]> git.neil.brown.name Git - history.git/commitdiff
- Peter Anvin: more P4 configuration parsing 2.4.0-test12pre2
authorLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:40:20 +0000 (15:40 -0500)
committerLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:40:20 +0000 (15:40 -0500)
- Stephen Tweedie: O_SYNC patches. Make O_SYNC/fsync/fdatasync
  do the right thing.
- Keith Owens: make mdule loading use the right struct module size
- Boszormenyi Zoltan: get MTRR's right for the >32-bit case
- Alan Cox: various random documentation etc
- Dario Ballabio: EATA and u14-34f update
- Ivan Kokshaysky: unbreak alpha ruffian
- Richard Henderson: PCI bridge initialization on alpha
- Zach Brown: correct locking in Maestro driver
- Geert Uytterhoeven: more m68k updates
- Andrey Savochkin: eepro100 update
- Dag Brattli: irda update
- Johannes Erdfelt: USB update

135 files changed:
CREDITS
Documentation/Configure.help
Documentation/DocBook/kernel-hacking.tmpl
Documentation/filesystems/proc.txt
Documentation/networking/irda.txt
Documentation/usb/usb-serial.txt
MAINTAINERS
arch/alpha/kernel/core_cia.c
arch/alpha/kernel/pci.c
arch/alpha/kernel/sys_ruffian.c
arch/arm/kernel/bios32.c
arch/i386/kernel/mtrr.c
arch/i386/kernel/setup.c
arch/m68k/amiga/amiga_ksyms.c
arch/m68k/amiga/amiints.c
arch/m68k/amiga/amisound.c
arch/m68k/amiga/chipram.c
arch/m68k/amiga/cia.c
arch/m68k/amiga/config.c
arch/m68k/atari/atakeyb.c
arch/m68k/atari/config.c
arch/m68k/atari/stram.c
arch/m68k/kernel/entry.S
arch/m68k/kernel/m68k_defs.c
arch/m68k/kernel/ptrace.c
arch/m68k/kernel/setup.c
arch/m68k/kernel/signal.c
arch/m68k/kernel/traps.c
arch/m68k/mac/config.c
arch/m68k/q40/config.c
arch/mips/ddb5074/pci.c
arch/ppc/amiga/config.c
drivers/block/acsi.c
drivers/block/ataflop.c
drivers/char/amikeyb.c
drivers/char/q40_keyb.c
drivers/char/serial.c
drivers/ide/buddha.c
drivers/ide/gayle.c
drivers/ide/ide.c
drivers/ide/q40ide.c
drivers/media/radio/radio-aimslab.c
drivers/media/radio/radio-aztech.c
drivers/media/radio/radio-cadet.c
drivers/media/radio/radio-gemtek.c
drivers/media/radio/radio-rtrack2.c
drivers/media/radio/radio-sf16fmi.c
drivers/media/radio/radio-terratec.c
drivers/media/radio/radio-trust.c
drivers/media/radio/radio-typhoon.c
drivers/media/radio/radio-zoltrix.c
drivers/media/video/bw-qcam.c
drivers/media/video/c-qcam.c
drivers/net/eepro100.c
drivers/net/irda/irtty.c
drivers/net/irda/nsc-ircc.c
drivers/net/tokenring/tms380tr_microcode.h
drivers/pci/setup-bus.c
drivers/pci/setup-res.c
drivers/pnp/isapnp.c
drivers/scsi/Makefile
drivers/scsi/a2091.c
drivers/scsi/a2091.h
drivers/scsi/a3000.c
drivers/scsi/a3000.h
drivers/scsi/atari_scsi.c
drivers/scsi/eata.c
drivers/scsi/eata.h
drivers/scsi/gvp11.c
drivers/scsi/ide-scsi.c
drivers/scsi/mvme147.c [new file with mode: 0644]
drivers/scsi/mvme147.h [new file with mode: 0644]
drivers/scsi/u14-34f.c
drivers/scsi/u14-34f.h
drivers/scsi/wd33c93.h
drivers/sound/cs46xx.c
drivers/sound/dmasound/dmasound_atari.c
drivers/sound/dmasound/dmasound_paula.c
drivers/sound/maestro.c
drivers/usb/Config.in
drivers/usb/serial/Config.in [new file with mode: 0644]
drivers/usb/serial/Makefile
drivers/usb/serial/empeg.c [new file with mode: 0644]
drivers/usb/serial/visor.c
drivers/usb/uhci.c
drivers/usb/usb.c
drivers/usb/wacom.c
drivers/video/amifb.c
drivers/video/atafb.c
fs/buffer.c
fs/ext2/fsync.c
fs/ext2/inode.c
fs/ext2/namei.c
fs/inode.c
include/asm-generic/bitops.h
include/asm-i386/mtrr.h
include/asm-m68k/amigahw.h
include/asm-m68k/amigaints.h
include/asm-m68k/amipcmcia.h
include/asm-m68k/atari_stram.h
include/asm-m68k/atarihw.h
include/asm-m68k/bitops.h
include/asm-m68k/entry.h
include/asm-m68k/fcntl.h
include/asm-m68k/keyboard.h
include/asm-m68k/machdep.h
include/asm-m68k/motorola_pgalloc.h [new file with mode: 0644]
include/asm-m68k/motorola_pgtable.h [new file with mode: 0644]
include/asm-m68k/page.h
include/asm-m68k/param.h
include/asm-m68k/pgalloc.h
include/asm-m68k/pgtable.h
include/asm-m68k/q40_keyboard.h
include/asm-m68k/softirq.h
include/asm-m68k/spinlock.h
include/asm-m68k/stat.h
include/asm-m68k/sun3_pgalloc.h [new file with mode: 0644]
include/asm-m68k/sun3_pgtable.h [new file with mode: 0644]
include/asm-m68k/system.h
include/asm-m68k/types.h
include/linux/ext2_fs.h
include/linux/fs.h
include/linux/ioport.h
include/linux/kernel.h
include/linux/pci.h
include/linux/pci_ids.h
include/linux/sched.h
kernel/module.c
lib/vsprintf.c
mm/filemap.c
mm/vmscan.c
net/irda/ircomm/ircomm_core.c
net/irda/ircomm/ircomm_tty.c
net/irda/irlan/irlan_client_event.c
net/irda/irlap_event.c

diff --git a/CREDITS b/CREDITS
index 7f8a8c70c4c032aeca9557c75addd0fb961069b3..1a013c565b308a64893e6fc0d4926a5d1e941ee7 100644 (file)
--- a/CREDITS
+++ b/CREDITS
@@ -152,10 +152,12 @@ E: balasub@cis.ohio-state.edu
 D: Wrote SYS V IPC (part of standard kernel since 0.99.10)
 
 N: Dario Ballabio
-E: dario@milano.europe.dg.com
+E: ballabio_dario@emc.com
+E: dario.ballabio@tiscalinet.it
+E: dario.ballabio@inwind.it
 D: Author and maintainer of the Ultrastor 14F/34F SCSI driver
 D: Author and maintainer of the EATA ISA/EISA/PCI SCSI driver
-S: Data General Corporation
+S: EMC Corporation
 S: Milano
 S: Italy
 
index 4fd971b88fc57416ccbe76c1978eaf56352b8a94..eef5afa3da8a3823cd7779d15ba1dd7bec4650f8 100644 (file)
@@ -10286,6 +10286,17 @@ CONFIG_USB_SERIAL_VISOR
   The module will be called visor.o. If you want to compile it as a
   module, say M here and read Documentation/modules.txt.
 
+USB Belkin and Paracom Single Port Serial Driver
+CONFIG_USB_SERIAL_BELKIN
+  Say Y here if you want to use a Belkin USB Serial single port
+  adaptor (F5U103 is one of the model numbers) or the Peracom single
+  port USB to serial adapter.
+
+  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 belkin_sa.o.  If you want to compile it as
+  a module, say M here and read Documentation/modules.txt.
+
 USB FTDI Single Port Serial Driver
 CONFIG_USB_SERIAL_FTDI_SIO
   Say Y here if you want to use a FTDI SIO single port USB to serial
@@ -10366,6 +10377,16 @@ CONFIG_USB_SERIAL_DIGI_ACCELEPORT
   The module will be called digi_acceleport.o. If you want to compile 
   it as a module, say M here and read Documentation/modules.txt.
 
+USB Empeg empeg-car Mark I/II Driver
+CONFIG_USB_SERIAL_EMPEG
+  Say Y here if you want to connect to your Empeg empeg-car Mark I/II
+  mp3 player via USB.
+
+  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 empeg.o. If you want to compile it as a
+  module, say M here and read Documentation/modules.txt.
+
 USB Serial Converter verbose debug
 CONFIG_USB_SERIAL_DEBUG
   Say Y here if you want verbose debug messages from the USB Serial
@@ -13395,6 +13416,17 @@ CONFIG_MIXCOMWD
   module, say M here and read Documentation/modules.txt. Most people
   will say N.
 
+Toshiba Laptop support
+CONFIG_TOSHIBA
+  If you intend to run this the kernel on a Toshiba portable say yes
+  here. This adds a driver to safely access the System Management
+  Mode of the CPU on Toshiba portables. The System Management Mode
+  is used to set the BIOS and power saving options on Toshiba portables.
+
+  For information on utilities to make use of this driver see the
+  Toshiba Linux utilities website at:
+  http://www.buzzard.org.uk/toshiba/
+
 /dev/cpu/microcode - Intel P6 CPU microcode support
 CONFIG_MICROCODE
   If you say Y here and also to "/dev file system support" in the
index 8d87787ad673e4efab0c02b1ec375fef9d61880b..47fbe077ed2dcedebdb5cf45c7899aa96979488f 100644 (file)
@@ -846,7 +846,7 @@ foo_open (...)
    first class of operations work on <type>atomic_t</type>
 
    <filename class=headerfile>include/asm/atomic.h</filename>; this
-   contains a signed integer (at least 32 bits long), and you must use
+   contains a signed integer (at least 24 bits long), and you must use
    these functions to manipulate or read atomic_t variables.
    <function>atomic_read()</function> and
    <function>atomic_set()</function> get and set the counter,
@@ -870,8 +870,8 @@ foo_open (...)
   </para>
 
   <para>
-   The second class of atomic operations is atomic bit operations,
-   defined in
+   The second class of atomic operations is atomic bit operations on a
+   <type>long</type>, defined in
 
    <filename class=headerfile>include/asm/bitops.h</filename>.  These
    operations generally take a pointer to the bit pattern, and a bit
@@ -887,9 +887,15 @@ foo_open (...)
   
   <para>
    It is possible to call these operations with bit indices greater
-   than 31.  The resulting behavior is strange on big-endian
+   than BITS_PER_LONG.  The resulting behavior is strange on big-endian
    platforms though so it is a good idea not to do this.
   </para>
+
+  <para>
+   Note that the order of bits depends on the architecture, and in
+   particular, the bitfield passed to these operations must be at
+   least as large as a <type>long</type>.
+  </para>
  </chapter>
 
  <chapter id="symbols">
index 5dcf02cfe9e3161af742754dc698b20167c0b4e9..ea8d32afbb135e0b7ae853a7f496ebd6460b4371 100644 (file)
@@ -3,8 +3,11 @@
 ------------------------------------------------------------------------------
 /proc/sys         Terrehon Bowden <terrehon@pacbell.net>        October 7 1999
                   Bodo Bauer <bb@ricochet.net>
+
+2.4.x update     Jorge Nerin <comandante@zaralinux.com>      November 14 2000
 ------------------------------------------------------------------------------
-Version 1.2                                              Kernel version 2.2.12
+Version 1.3                                              Kernel version 2.2.12
+                                             Kernel version 2.4.0-test11-pre4
 ------------------------------------------------------------------------------
 
 Table of Contents
@@ -42,17 +45,18 @@ Preface
 0.1 Introduction/Credits
 ------------------------
 
-This documentation  is  part  of a soon (or so we hope) to be released book on
-the SuSE  Linux  distribution.  As  there is no complete documentation for the
-/proc file  system and we've used many freely available sources to write these
-chapters, it  seems  only  fair  to give the work back to the Linux community.
-This work is based on the 2.2.* kernel version. I'm afraid it's still far from
-complete, but  we  hope  it will be useful. As far as we know, it is the first
-'all-in-one' document  about the /proc file system. It is focused on the Intel
-x86 hardware,  so if you are looking for PPC, ARM, SPARC, APX, etc., features,
-you probably  won't  find  what  you are looking for. It also only covers IPv4
-networking, not  IPv6  nor  other protocols - sorry. But additions and patches
-are welcome and will be added to this document if you mail them to Bodo.
+This documentation is  part of a soon (or  so we hope) to be  released book on
+the SuSE  Linux distribution. As  there is  no complete documentation  for the
+/proc file system and we've used  many freely available sources to write these
+chapters, it  seems only fair  to give the work  back to the  Linux community.
+This work is  based on the 2.2.*  kernel version and the  upcomming 2.4.*. I'm
+afraid it's still far from complete, but we  hope it will be useful. As far as
+we know, it is the first 'all-in-one' document about the /proc file system. It
+is focused  on the Intel  x86 hardware,  so if you  are looking for  PPC, ARM,
+SPARC, APX, etc., features, you probably  won't find what you are looking for.
+It also only covers IPv4 networking, not IPv6 nor other protocols - sorry. But
+additions and patches  are welcome and will  be added to this  document if you
+mail them to Bodo.
 
 We'd like  to  thank Alan Cox, Rik van Riel, and Alexey Kuznetsov and a lot of
 other people for help compiling this documentation. We'd also like to extend a
@@ -65,9 +69,13 @@ If you  have  any comments, corrections or additions, please don't hesitate to
 contact Bodo  Bauer  at  bb@ricochet.net.  We'll  be happy to add them to this
 document.
 
-The latest  version  of  this  document  is  available  online  at
+The   latest   version    of   this   document   is    available   online   at
 http://skaro.nightcrawler.com/~bb/Docs/Proc as HTML version.
 
+If  the above  direction does  not works  for you,  ypu could  try the  kernel
+mailing  list  at  linux-kernel@vger.kernel.org  and/or try  to  reach  me  at
+comandante@zaralinux.com.
+
 0.2 Legal Stuff
 ---------------
 
@@ -92,7 +100,7 @@ In This Chapter
 
 The proc  file  system acts as an interface to internal data structures in the
 kernel. It  can  be  used to obtain information about the system and to change
-certain kernel parameters at runtime.
+certain kernel parameters at runtime (sysctl).
 
 First, we'll  take  a  look  at the read-only parts of /proc. In Chapter 2, we
 show you how you can use /proc/sys to change settings.
@@ -111,16 +119,17 @@ Table 1-1: Process specific entries in /proc
 ..............................................................................
  File    Content                                        
  cmdline Command line arguments                         
- environ Values of environment variables                
+ cpu    Current and last cpu in wich it was executed           (2.4)(smp)
+ cwd    Link to the current working directory
+ environ Values of environment variables      
+ exe    Link to the executable of this process
  fd      Directory, which contains all file descriptors 
+ maps   Memory maps to executables and library files           (2.4)
  mem     Memory held by this process                    
+ root   Link to the root directory of this process
  stat    Process status                                 
- status  Process status in human readable form          
- cwd     Link to the current working directory          
- exe     Link to the executable of this process         
- maps    Memory maps                                    
- root    Link to the root directory of this process     
  statm   Process memory status information              
+ status  Process status in human readable form          
 ..............................................................................
 
 For example, to get the status information of a process, all you have to do is
@@ -131,6 +140,7 @@ read the file /proc/PID/status:
   State:  R (running) 
   Pid:    5452 
   PPid:   743 
+  TracerPid:      0                                            (2.4)
   Uid:    501     501     501     501 
   Gid:    100     100     100     100 
   Groups: 100 14 16 
@@ -187,13 +197,20 @@ Table 1-3: Kernel info in /proc
  devices     Available devices (block and character)           
  dma         Used DMS channels                                 
  filesystems Supported filesystems                             
+ driver             Various drivers grouped here, currently rtc        (2.4)
+ execdomains Execdomains, related to security                  (2.4)
+ fb         Frame Buffer devices                               (2.4)
+ fs         File system parameters, currently nfs/exports      (2.4)
  ide         Directory containing info about the IDE subsystem 
  interrupts  Interrupt usage                                   
+ iomem      Memory map                                         (2.4)
  ioports     I/O port usage                                    
- kcore       Kernel core image (can be ELF or A.OUT)           
+ irq        Masks for irq to cpu affinity                      (2.4)(smp?)
+ isapnp             ISA PnP (Plug&Play) Info                           (2.4)
+ kcore       Kernel core image (can be ELF or A.OUT(deprecated in 2.4))   
  kmsg        Kernel messages                                   
  ksyms       Kernel symbol table                               
- loadavg     Load average                                      
+ loadavg     Load average of last 1, 5 & 15 minutes                
  locks       Kernel locks                                      
  meminfo     Memory info                                       
  misc        Miscellaneous                                     
@@ -201,14 +218,19 @@ Table 1-3: Kernel info in /proc
  mounts      Mounted filesystems                               
  net         Networking info (see text)                        
  partitions  Table of partitions known to the system           
+ pci        Depreciated info of PCI bus (new way -> /proc/bus/pci/, 
+             decoupled by lspci                                        (2.4)
  rtc         Real time clock                                   
  scsi        SCSI info (see text)                              
  slabinfo    Slab pool info                                    
  stat        Overall statistics                                
  swaps       Swap space utilization                            
  sys         See chapter 2                                     
+ sysvipc     Info of SysVIPC Resources (msg, sem, shm)         (2.4)
+ tty        Info of tty drivers
  uptime      System uptime                                     
  version     Kernel version                                    
+ video      bttv info of video resources                       (2.4)
 ..............................................................................
 
 You can,  for  example,  check  which interrupts are currently in use and what
@@ -230,6 +252,68 @@ they are used for by looking in the file /proc/interrupts:
    15:          7          XT-PIC  ide1 
   NMI:          0 
 
+In 2.4.* a couple of lines where added to this file LOC & ERR (this time is the
+output of a SMP machine):
+
+  > cat /proc/interrupts 
+
+             CPU0       CPU1       
+    0:    1243498    1214548    IO-APIC-edge  timer
+    1:       8949       8958    IO-APIC-edge  keyboard
+    2:          0          0          XT-PIC  cascade
+    5:      11286      10161    IO-APIC-edge  soundblaster
+    8:          1          0    IO-APIC-edge  rtc
+    9:      27422      27407    IO-APIC-edge  3c503
+   12:     113645     113873    IO-APIC-edge  PS/2 Mouse
+   13:          0          0          XT-PIC  fpu
+   14:      22491      24012    IO-APIC-edge  ide0
+   15:       2183       2415    IO-APIC-edge  ide1
+   17:      30564      30414   IO-APIC-level  eth0
+   18:        177        164   IO-APIC-level  bttv
+  NMI:    2457961    2457959 
+  LOC:    2457882    2457881 
+  ERR:       2155
+
+NMI is incremented in this case because every timer interrupt generates a NMI
+(Non Maskable Interrupt) which is used by the NMI Watchdog to detect lookups.
+
+LOC is the local interrupt counter of the internal APIC of every CPU.
+
+ERR is incremented in the case of errors in the IO-APIC bus (the bus that
+connects the CPUs in a SMP system. This means that an error has been detected,
+the IO-APIC automatically retry the transmision, so it should not be a big
+problem, but you should read the SMP-FAQ.
+
+In this context it could be interesting to note the new irq directory in 2.4.
+It could be used to set IRQ to CPU affinity, this means that you can "hook" an
+IRQ to only one CPU, or to exclude a CPU of handling IRQs. The contents of the
+irq subdir is one subdir for each IRQ, and one file; prof_cpu_mask
+
+For example 
+  > ls /proc/irq/
+  0  10  12  14  16  18  2  4  6  8  prof_cpu_mask
+  1  11  13  15  17  19  3  5  7  9
+  > ls /proc/irq/0/
+  smp_affinity
+
+The contents of the prof_cpu_mask file and each smp_affinity file for each IRQ
+is the same by default:
+
+  > cat /proc/irq/0/smp_affinity 
+  ffffffff
+
+It's a bitmask, in wich you can specify wich CPUs can handle the IRQ, you can
+set it by doing:
+
+  > echo 1 > /proc/irq/prof_cpu_mask
+
+This means that only the first CPU will handle the IRQ, but you can also echo 5
+wich means that only the first and fourth CPU can handle the IRQ.
+
+The way IRQs are routed is handled by the IO-APIC, and it's Round Robin
+between all the CPUs which are allowed to handle it. As usual the kernel has
+more info than you and does a better job than you, so the defaults are the
+best choice for almost everyone.
 
 There are  three  more  important subdirectories in /proc: net, scsi, and sys.
 The general  rule  is  that  the  contents,  or  even  the  existence of these
@@ -1307,6 +1391,15 @@ Time in seconds to keep an IP fragment in memory.
 TCP settings
 ------------
 
+tcp_ecn
+-------
+
+This file controls the use of the ECN bit in the IPv4 headers, this is a new
+feature about Explicit Congestion Notification, but some routers and firewalls
+block trafic that has this bit set, so it could be necessary to echo 0 to
+/proc/sys/net/ipv4/tcp_ecn, if you want to talk to this sites. For more info
+you could read RFC2481.
+
 tcp_retrans_collapse
 --------------------
 
index fa455100ee4f6d56ce636da62e3cbd1b66ef13f9..a4b5a110db782aa87cc0b12cea7cb9c1faa071a6 100644 (file)
@@ -1,10 +1,10 @@
 To use the IrDA protocols within Linux you will need to get a suitable copy
 of the IrDA Utilities. More detailed information about these and associated
-programs can be found on http://www.cs.uit.no/linux-irda/
+programs can be found on http://irda.sourceforge.net/
 
 For more information about how to use the IrDA protocol stack, see the
-IR-HOWTO (http://www.snafu.de/~wehe/IR-HOWTO.html) written by Werner Heuser
-<wehe@snafu.de>
+IR-HOWTO (http://www.mobilix.org/Infrared-HOWTO/Infrared-HOWTO.html) written by Werner Heuser
+<wehe@mobilix.org>
 
 There is an active mailing list for discussing Linux-IrDA matters called
 linux-irda. To subscribe to it, visit:
index a6efeefa57d14d890ca3eb0bae2687d85506f175..00ce3dfd444927a8508637b4c9a228f4a03ab9dc 100644 (file)
@@ -182,6 +182,15 @@ TO DO List:
   -- Add everything else that is missing :)
 
 
+Empeg empeg-car Mark I/II Driver (empeg.c)
+
+  This is an experimental driver to provide connectivity support for the
+  client synchronization tools for an Empeg empeg-car mp3 player.
+
+  The driver is still pretty new, so some testing 'in the wild' would be
+  helpful. :)
+
+
 Generic Serial driver
 
   If your device is not one of the above listed devices, compatible with
index 072d1da5d3dc3fc05549dadc04021a0857945395..c42849b99e450bba42a2a50d5f1f11cfb9a6bd8d 100644 (file)
@@ -393,7 +393,7 @@ S:  Maintained
 
 EATA ISA/EISA/PCI SCSI DRIVER
 P:     Dario Ballabio
-M:     dario@milano.europe.dg.com
+M:     ballabio_dario@emc.com
 L:     linux-scsi@vger.kernel.org
 S:     Maintained
 
@@ -651,9 +651,9 @@ S:  Maintained
 
 IRDA SUBSYSTEM
 P:      Dag Brattli
-M:      Dag Brattli <dagb@cs.uit.no>
+M:      Dag Brattli <dag@brattli.net>
 L:      linux-irda@pasta.cs.uit.no
-W:      http://www.cs.uit.no/linux-irda/
+W:      http://irda.sourceforge.net/
 S:      Maintained
 
 ISAPNP
@@ -1223,7 +1223,7 @@ S:        Maintained
 
 U14-34F SCSI DRIVER
 P:     Dario Ballabio
-M:     dario@milano.europe.dg.com
+M:     ballabio_dario@emc.com
 L:     linux-scsi@vger.kernel.org
 S:     Maintained
 
index 1b1f4686746900d057ac14d8f259ec88a830ee0f..b736f9516ce898af2eb6a0561b763e5b0aa1aeab 100644 (file)
@@ -119,6 +119,7 @@ conf_read(unsigned long addr, unsigned char type1)
        stat0 = *(vip)CIA_IOC_CIA_ERR;
        *(vip)CIA_IOC_CIA_ERR = stat0;
        mb();
+       *(vip)CIA_IOC_CIA_ERR; /* re-read to force write */
 
        /* If Type1 access, must set CIA CFG. */
        if (type1) {
@@ -128,6 +129,7 @@ conf_read(unsigned long addr, unsigned char type1)
                *(vip)CIA_IOC_CFG;
        }
 
+       mb();
        draina();
        mcheck_expected(0) = 1;
        mcheck_taken(0) = 0;
@@ -171,6 +173,7 @@ conf_write(unsigned long addr, unsigned int value, unsigned char type1)
        stat0 = *(vip)CIA_IOC_CIA_ERR;
        *(vip)CIA_IOC_CIA_ERR = stat0;
        mb();
+       *(vip)CIA_IOC_CIA_ERR; /* re-read to force write */
 
        /* If Type1 access, must set CIA CFG.  */
        if (type1) {
@@ -180,6 +183,7 @@ conf_write(unsigned long addr, unsigned int value, unsigned char type1)
                *(vip)CIA_IOC_CFG;
        }
 
+       mb();
        draina();
        mcheck_expected(0) = 1;
        mcheck_taken(0) = 0;
@@ -188,7 +192,7 @@ conf_write(unsigned long addr, unsigned int value, unsigned char type1)
        /* Access configuration space.  */
        *(vip)addr = value;
        mb();
-       mb();  /* magic */
+       *(vip)addr; /* read back to force the write */
 
        mcheck_expected(0) = 0;
        mb();
@@ -606,7 +610,8 @@ do_init_arch(int is_pyxis)
        *(vip)CIA_IOC_ERR_MASK = temp;
 
        /* Clear all currently pending errors.  */
-       *(vip)CIA_IOC_CIA_ERR = 0;
+       temp = *(vip)CIA_IOC_CIA_ERR;
+       *(vip)CIA_IOC_CIA_ERR = temp;
 
        /* Turn on mchecks.  */
        temp = *(vip)CIA_IOC_CIA_CTRL;
index 1b83bdfb97953f7941eb784e016b02a3a546cb09..b06c6bd806827159d790e227d09e1bf7973b26f1 100644 (file)
@@ -8,6 +8,11 @@
 
 /* 2.3.x PCI/resources, 1999 Andrea Arcangeli <andrea@suse.de> */
 
+/*
+ * Nov 2000, Ivan Kokshaysky <ink@jurassic.park.msu.ru>
+ *          PCI-PCI bridges cleanup
+ */
+
 #include <linux/string.h>
 #include <linux/pci.h>
 #include <linux/init.h>
@@ -71,6 +76,26 @@ quirk_ali_ide_ports(struct pci_dev *dev)
                dev->resource[3].end = dev->resource[3].start + 7;
 }
 
+/*
+ * Notorious Cy82C693 chip. One of its numerous bugs: although
+ * Cypress IDE controller doesn't support native mode, it has
+ * programmable addresses of IDE command/control registers.
+ * This violates PCI specifications, confuses IDE subsystem
+ * and causes resource conflict between primary HD_CMD register
+ * and floppy controller. Ugh.
+ * Fix that.
+ */
+static void __init
+quirk_cypress_ide_ports(struct pci_dev *dev)
+{
+       if (dev->class >> 8 != PCI_CLASS_STORAGE_IDE)
+               return;
+       dev->resource[1].start |= 2;
+       dev->resource[1].end = dev->resource[1].start;
+       pci_claim_resource(dev, 0);
+       pci_claim_resource(dev, 1);
+}
+
 static void __init
 quirk_vga_enable_rom(struct pci_dev *dev)
 {
@@ -78,7 +103,6 @@ quirk_vga_enable_rom(struct pci_dev *dev)
           But if its a Cirrus 543x/544x DISABLE it, since
           enabling ROM disables the memory... */
        if ((dev->class >> 8) == PCI_CLASS_DISPLAY_VGA &&
-           /* But if its a Cirrus 543x/544x DISABLE it */
            (dev->vendor != PCI_VENDOR_ID_CIRRUS ||
             (dev->device < 0x00a0) || (dev->device > 0x00ac)))
        {
@@ -98,6 +122,8 @@ struct pci_fixup pcibios_fixups[] __initdata = {
          quirk_isa_bridge },
        { PCI_FIXUP_HEADER, PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M5229,
          quirk_ali_ide_ports },
+       { PCI_FIXUP_HEADER, PCI_VENDOR_ID_CONTAQ, PCI_DEVICE_ID_CONTAQ_82C693,
+         quirk_cypress_ide_ports },
        { PCI_FIXUP_FINAL, PCI_ANY_ID, PCI_ANY_ID, quirk_vga_enable_rom },
        { 0 }
 };
@@ -122,18 +148,12 @@ pcibios_align_resource(void *data, struct resource *res, unsigned long size)
                        start = PCIBIOS_MIN_IO + hose->io_space->start;
 
                /*
-                * Aligning to 0x800 rather than the minimum base of
-                * 0x400 is an attempt to avoid having devices in 
-                * any 0x?C?? range, which is where the de4x5 driver
-                * probes for EISA cards.
-                *
-                * Adaptecs, especially, resent such intrusions.
-                *
-                * The de4x5 driver has the eisa probe conditionalized
-                * out for Alpha, so lower the minimum base back to 0x400.
+                * Put everything into 0x00-0xff region modulo 0x400
                 */
-               alignto = MAX(0x400, size);
-               start = ALIGN(start, alignto);
+               if (start & 0x300) {
+                       start = (start + 0x3ff) & ~0x3ff;
+                       res->start = start;
+               }
        }
        else if (res->flags & IORESOURCE_MEM) {
                /* Make sure we start at our min on all hoses */
@@ -181,44 +201,6 @@ pcibios_align_resource(void *data, struct resource *res, unsigned long size)
 #undef MB
 #undef GB
 
-/* 
- * Pre-layout host-independant device initialization.
- */
-
-static void __init
-pcibios_assign_special(struct pci_dev * dev)
-{
-       int i;
-
-       /* The first three resources of an IDE controler are often magic, 
-          so leave them unchanged.  This is true, for instance, of the
-          Contaq 82C693 as seen on SX164 and DP264.  */
-
-       if (dev->class >> 8 == PCI_CLASS_STORAGE_IDE) {
-               /* Resource 1 of IDE controller is the address of HD_CMD
-                  register which actually occupies a single byte (0x3f6
-                  for ide0) in reported 0x3f4-3f7 range. We have to fix
-                  that to avoid resource conflict with AT-style floppy
-                  controller. */
-               dev->resource[1].start += 2;
-               dev->resource[1].end = dev->resource[1].start;
-               for (i = 0; i < PCI_NUM_RESOURCES; i++)
-                       if (dev->resource[i].flags && dev->resource[i].start)
-                               pci_claim_resource(dev, i);
-       }
-       /*
-        * We don't have code that will init the CYPRESS bridge correctly
-        * so we do the next best thing, and depend on the previous
-        * console code to do the right thing, and ignore it here... :-\
-        */
-       else if (dev->vendor == PCI_VENDOR_ID_CONTAQ &&
-                dev->device == PCI_DEVICE_ID_CONTAQ_82C693)
-               for (i = 0; i < PCI_NUM_RESOURCES; i++)
-                       if (dev->resource[i].flags && dev->resource[i].start)
-                               pci_claim_resource(dev, i);
-}
-
-
 void __init
 pcibios_init(void)
 {
@@ -257,7 +239,6 @@ pcibios_fixup_device_resources(struct pci_dev *dev, struct pci_bus *bus)
                        pcibios_fixup_resource(&dev->resource[i],
                                               hose->mem_space);
        }
-       pcibios_assign_special(dev);
 }
 
 void __init
@@ -265,17 +246,33 @@ pcibios_fixup_bus(struct pci_bus *bus)
 {
        /* Propogate hose info into the subordinate devices.  */
 
-       struct pci_controler *hose = (struct pci_controler *) bus->sysdata;
+       struct pci_controler *hose = bus->sysdata;
        struct list_head *ln;
+       struct pci_dev *dev = bus->self;
 
-       /* ???? */
-       bus->resource[0] = hose->io_space;
-       bus->resource[1] = hose->mem_space;
+       if (!dev) {
+               /* Root bus */
+               bus->resource[0] = hose->io_space;
+               bus->resource[1] = hose->mem_space;
+       } else {
+               /* This is a bridge. Do not care how it's initialized,
+                  just link its resources to the bus ones */
+               int i;
 
-       /* If this is a bridge, get the current bases */
-       if (bus->self) {
-               pci_read_bridge_bases(bus);
-               pcibios_fixup_device_resources(bus->self, bus->parent);
+               for(i=0; i<3; i++) {
+                       bus->resource[i] =
+                               &dev->resource[PCI_BRIDGE_RESOURCES+i];
+                       bus->resource[i]->name = bus->name;
+               }
+               bus->resource[0]->flags |= pci_bridge_check_io(dev);
+               bus->resource[1]->flags |= IORESOURCE_MEM;
+               /* For now, propogate hose limits to the bus;
+                  we'll adjust them later. */
+               bus->resource[0]->end = hose->io_space->end;
+               bus->resource[1]->end = hose->mem_space->end;
+               /* Turn off downstream PF memory address range by default */
+               bus->resource[2]->start = 1024*1024;
+               bus->resource[2]->end = bus->resource[2]->start - 1;
        }
 
        for (ln = bus->devices.next; ln != &bus->devices; ln = ln->next) {
@@ -385,99 +382,6 @@ pcibios_set_master(struct pci_dev *dev)
        pci_write_config_byte(dev, PCI_LATENCY_TIMER, 64);
 }
 
-#define ROUND_UP(x, a)         (((x) + (a) - 1) & ~((a) - 1))
-
-static void __init
-pcibios_size_bridge(struct pci_bus *bus, struct pbus_set_ranges_data *outer)
-{
-       struct pbus_set_ranges_data inner;
-       struct pci_dev *dev;
-       struct pci_dev *bridge = bus->self;
-       struct pci_controler *hose = bus->sysdata;
-       struct list_head *ln;
-
-       if (!bridge)
-               return; /* host bridge, nothing to do */
-
-       /* set reasonable default locations for pcibios_align_resource */
-       inner.io_start = hose->io_space->start + PCIBIOS_MIN_IO;
-       inner.mem_start = hose->mem_space->start + PCIBIOS_MIN_MEM;
-       inner.io_end = inner.io_start;
-       inner.mem_end = inner.mem_start;
-
-       /* Collect information about how our direct children are layed out. */
-       for (ln=bus->devices.next; ln != &bus->devices; ln=ln->next) {
-               int i;
-               dev = pci_dev_b(ln);
-
-               /* Skip bridges for now */
-               if (dev->class >> 8 == PCI_CLASS_BRIDGE_PCI)
-                       continue;
-
-               for (i = 0; i < PCI_NUM_RESOURCES; i++) {
-                       struct resource res;
-                       unsigned long size;
-
-                       memcpy(&res, &dev->resource[i], sizeof(res));
-                       size = res.end - res.start + 1;
-
-                       if (res.flags & IORESOURCE_IO) {
-                               res.start = inner.io_end;
-                               pcibios_align_resource(dev, &res, size);
-                               inner.io_end = res.start + size;
-                       } else if (res.flags & IORESOURCE_MEM) {
-                               res.start = inner.mem_end;
-                               pcibios_align_resource(dev, &res, size);
-                               inner.mem_end = res.start + size;
-                       }
-               }
-       }
-
-       /* And for all of the subordinate busses. */
-       for (ln=bus->children.next; ln != &bus->children; ln=ln->next)
-               pcibios_size_bridge(pci_bus_b(ln), &inner);
-
-       /* turn the ending locations into sizes (subtract start) */
-       inner.io_end -= inner.io_start;
-       inner.mem_end -= inner.mem_start;
-
-       /* Align the sizes up by bridge rules */
-       inner.io_end = ROUND_UP(inner.io_end, 4*1024) - 1;
-       inner.mem_end = ROUND_UP(inner.mem_end, 1*1024*1024) - 1;
-
-       /* Adjust the bridge's allocation requirements */
-       bridge->resource[0].end = bridge->resource[0].start + inner.io_end;
-       bridge->resource[1].end = bridge->resource[1].start + inner.mem_end;
-
-       bridge->resource[PCI_BRIDGE_RESOURCES].end =
-           bridge->resource[PCI_BRIDGE_RESOURCES].start + inner.io_end;
-       bridge->resource[PCI_BRIDGE_RESOURCES+1].end =
-           bridge->resource[PCI_BRIDGE_RESOURCES+1].start + inner.mem_end;
-
-       /* adjust parent's resource requirements */
-       if (outer) {
-               outer->io_end = ROUND_UP(outer->io_end, 4*1024);
-               outer->io_end += inner.io_end;
-
-               outer->mem_end = ROUND_UP(outer->mem_end, 1*1024*1024);
-               outer->mem_end += inner.mem_end;
-       }
-}
-
-#undef ROUND_UP
-
-static void __init 
-pcibios_size_bridges(void)
-{
-       struct list_head *ln1, *ln2;
-
-       for(ln1=pci_root_buses.next; ln1 != &pci_root_buses; ln1=ln1->next)
-               for(ln2 = pci_bus_b(ln1)->children.next; 
-                   ln2 != &pci_bus_b(ln1)->children;
-                   ln2 = ln2->next)
-                       pcibios_size_bridge(pci_bus_b(ln2), NULL);
-}
-
 void __init
 common_init_pci(void)
 {
@@ -495,10 +399,8 @@ common_init_pci(void)
                next_busno += 1;
        }
 
-       pcibios_size_bridges();
        pci_assign_unassigned_resources();
        pci_fixup_irqs(alpha_mv.pci_swizzle, alpha_mv.pci_map_irq);
-       pci_set_bus_ranges();
 }
 
 
index 54fc933870732a5d96cf2c996b8a241725d15097..c9a2e79a4b7f30f6558e20902e03307db446b1de 100644 (file)
@@ -56,9 +56,9 @@ ruffian_init_irq(void)
        
        init_i8259a_irqs();
 
-       /* Not interested in the bogus interrupts (0,3,4,6), 
+       /* Not interested in the bogus interrupts (0,3,6),
           NMI (1), HALT (2), flash (5), or 21142 (8).  */
-       init_pyxis_irqs(0x17f0000);
+       init_pyxis_irqs(0x16f0000);
 
        common_init_isa_dma();
 }
index 3ee0d0381e63d7b385c1a6dc66b7acb32747085a..868fbd4a71c6f61746c741e47be730baa7b9a455 100644 (file)
@@ -451,7 +451,6 @@ void __init pcibios_init(void)
         */
        pci_assign_unassigned_resources();
        pci_fixup_irqs(hw_pci->swizzle, hw_pci->map_irq);
-       pci_set_bus_ranges();
 }
 
 char * __init pcibios_setup(char *str)
index 47c83f58ed9f1d86790c996523109e71f9cf7f56..71cbea695b37a251bc0b0e9dc14f7d03b9eea61e 100644 (file)
@@ -480,12 +480,14 @@ static int have_wrcomb (void)
     }
 }   /*  End Function have_wrcomb  */
 
+static u32 size_or_mask, size_and_mask;
+
 static void intel_get_mtrr (unsigned int reg, unsigned long *base,
                            unsigned long *size, mtrr_type *type)
 {
-    unsigned long dummy, mask_lo, base_lo;
+    unsigned long mask_lo, mask_hi, base_lo, base_hi;
 
-    rdmsr (MTRRphysMask_MSR(reg), mask_lo, dummy);
+    rdmsr (MTRRphysMask_MSR(reg), mask_lo, mask_hi);
     if ( (mask_lo & 0x800) == 0 )
     {
        /*  Invalid (i.e. free) range  */
@@ -495,20 +497,17 @@ static void intel_get_mtrr (unsigned int reg, unsigned long *base,
        return;
     }
 
-    rdmsr(MTRRphysBase_MSR(reg), base_lo, dummy);
+    rdmsr(MTRRphysBase_MSR(reg), base_lo, base_hi);
 
-    /* We ignore the extra address bits (32-35). If someone wants to
-       run x86 Linux on a machine with >4GB memory, this will be the
-       least of their problems. */
+    /* Work out the shifted address mask. */
+    mask_lo = size_or_mask | mask_hi << (32 - PAGE_SHIFT)
+               | mask_lo >> PAGE_SHIFT;
 
-    /* Clean up mask_lo so it gives the real address mask. */
-    mask_lo = (mask_lo & 0xfffff000UL);
     /* This works correctly if size is a power of two, i.e. a
        contiguous range. */
-    *size = ~(mask_lo - 1);
-
-    *base = (base_lo & 0xfffff000UL);
-    *type = (base_lo & 0xff);
+     *size = -mask_lo;
+     *base = base_hi << (32 - PAGE_SHIFT) | base_lo >> PAGE_SHIFT;
+     *type = base_lo & 0xff;
 }   /*  End Function intel_get_mtrr  */
 
 static void cyrix_get_arr (unsigned int reg, unsigned long *base,
@@ -533,13 +532,13 @@ static void cyrix_get_arr (unsigned int reg, unsigned long *base,
     /* Enable interrupts if it was enabled previously */
     __restore_flags (flags);
     shift = ((unsigned char *) base)[1] & 0x0f;
-    *base &= 0xfffff000UL;
+    *base >>= PAGE_SHIFT;
 
     /* Power of two, at least 4K on ARR0-ARR6, 256K on ARR7
      * Note: shift==0xf means 4G, this is unsupported.
      */
     if (shift)
-      *size = (reg < 7 ? 0x800UL : 0x20000UL) << shift;
+      *size = (reg < 7 ? 0x1UL : 0x40UL) << shift;
     else
       *size = 0;
 
@@ -576,7 +575,7 @@ static void amd_get_mtrr (unsigned int reg, unsigned long *base,
     /*  Upper dword is region 1, lower is region 0  */
     if (reg == 1) low = high;
     /*  The base masks off on the right alignment  */
-    *base = low & 0xFFFE0000;
+    *base = (low & 0xFFFE0000) >> PAGE_SHIFT;
     *type = 0;
     if (low & 1) *type = MTRR_TYPE_UNCACHABLE;
     if (low & 2) *type = MTRR_TYPE_WRCOMB;
@@ -601,7 +600,7 @@ static void amd_get_mtrr (unsigned int reg, unsigned long *base,
      * *128K   ...
      */
     low = (~low) & 0x1FFFC;
-    *size = (low + 4) << 15;
+    *size = (low + 4) << (15 - PAGE_SHIFT);
     return;
 }   /*  End Function amd_get_mtrr  */
 
@@ -614,8 +613,8 @@ static struct
 static void centaur_get_mcr (unsigned int reg, unsigned long *base,
                             unsigned long *size, mtrr_type *type)
 {
-    *base = centaur_mcr[reg].high & 0xfffff000;
-    *size = (~(centaur_mcr[reg].low & 0xfffff000))+1;
+    *base = centaur_mcr[reg].high >> PAGE_SHIFT;
+    *size = -(centaur_mcr[reg].low & 0xfffff000) >> PAGE_SHIFT;
     *type = MTRR_TYPE_WRCOMB;  /*  If it is there, it is write-combining  */
 }   /*  End Function centaur_get_mcr  */
 
@@ -645,8 +644,10 @@ static void intel_set_mtrr_up (unsigned int reg, unsigned long base,
     }
     else
     {
-       wrmsr (MTRRphysBase_MSR (reg), base | type, 0);
-       wrmsr (MTRRphysMask_MSR (reg), ~(size - 1) | 0x800, 0);
+       wrmsr (MTRRphysBase_MSR (reg), base << PAGE_SHIFT | type,
+               (base & size_and_mask) >> (32 - PAGE_SHIFT));
+       wrmsr (MTRRphysMask_MSR (reg), -size << PAGE_SHIFT | 0x800,
+               (-size & size_and_mask) >> (32 - PAGE_SHIFT));
     }
     if (do_safe) set_mtrr_done (&ctxt);
 }   /*  End Function intel_set_mtrr_up  */
@@ -660,7 +661,9 @@ static void cyrix_set_arr_up (unsigned int reg, unsigned long base,
     arr = CX86_ARR_BASE + (reg << 1) + reg; /* avoid multiplication by 3 */
 
     /* count down from 32M (ARR0-ARR6) or from 2G (ARR7) */
-    size >>= (reg < 7 ? 12 : 18);
+    if (reg >= 7)
+       size >>= 6;
+
     size &= 0x7fff; /* make sure arr_size <= 14 */
     for(arr_size = 0; size; arr_size++, size >>= 1);
 
@@ -685,6 +688,7 @@ static void cyrix_set_arr_up (unsigned int reg, unsigned long base,
     }
 
     if (do_safe) set_mtrr_prepare (&ctxt);
+    base <<= PAGE_SHIFT;
     setCx86(arr,    ((unsigned char *) &base)[3]);
     setCx86(arr+1,  ((unsigned char *) &base)[2]);
     setCx86(arr+2, (((unsigned char *) &base)[1]) | arr_size);
@@ -704,34 +708,36 @@ static void amd_set_mtrr_up (unsigned int reg, unsigned long base,
     [RETURNS] Nothing.
 */
 {
-    u32 low, high;
+    u32 regs[2];
     struct set_mtrr_context ctxt;
 
     if (do_safe) set_mtrr_prepare (&ctxt);
     /*
      * Low is MTRR0 , High MTRR 1
      */
-    rdmsr (0xC0000085, low, high);
+    rdmsr (0xC0000085, regs[0], regs[1]);
     /*
      * Blank to disable
      */
     if (size == 0)
-       *(reg ? &high : &low) = 0;
+       regs[reg] = 0;
     else
-       /* Set the register to the base (already shifted for us), the
-          type (off by one) and an inverted bitmask of the size
-          The size is the only odd bit. We are fed say 512K
-          We invert this and we get 111 1111 1111 1011 but
-          if you subtract one and invert you get the desired
-          111 1111 1111 1100 mask
-          */
-       *(reg ? &high : &low)=(((~(size-1))>>15)&0x0001FFFC)|base|(type+1);
+       /* Set the register to the base, the type (off by one) and an
+          inverted bitmask of the size The size is the only odd
+          bit. We are fed say 512K We invert this and we get 111 1111
+          1111 1011 but if you subtract one and invert you get the   
+          desired 111 1111 1111 1100 mask
+
+          But ~(x - 1) == ~x + 1 == -x. Two's complement rocks!  */
+       regs[reg] = (-size>>(15-PAGE_SHIFT) & 0x0001FFFC)
+                               | (base<<PAGE_SHIFT) | (type+1);
+
     /*
      * 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, low, high);
+    wrmsr (0xC0000085, regs[0], regs[1]);
     if (do_safe) set_mtrr_done (&ctxt);
 }   /*  End Function amd_set_mtrr_up  */
 
@@ -751,9 +757,8 @@ static void centaur_set_mcr_up (unsigned int reg, unsigned long base,
     }
     else
     {
-        high = base & 0xfffff000; /* base works on 4K pages... */
-        low = ((~(size-1))&0xfffff000);
-        low |= 0x1f;             /* only support write-combining... */
+       high = base << PAGE_SHIFT;
+       low = -size << PAGE_SHIFT | 0x1f; /* only support write-combining... */
     }
     centaur_mcr[reg].high = high;
     centaur_mcr[reg].low = low;
@@ -1058,7 +1063,7 @@ static int generic_get_free_region (unsigned long base, unsigned long size)
     for (i = 0; i < max; ++i)
     {
        (*get_mtrr) (i, &lbase, &lsize, &ltype);
-       if (lsize < 1) return i;
+       if (lsize == 0) return i;
     }
     return -ENOSPC;
 }   /*  End Function generic_get_free_region  */
@@ -1075,10 +1080,10 @@ static int cyrix_get_free_region (unsigned long base, unsigned long size)
     unsigned long lbase, lsize;
 
     /* If we are to set up a region >32M then look at ARR7 immediately */
-    if (size > 0x2000000UL)
+    if (size > 0x2000)
     {
        cyrix_get_arr (7, &lbase, &lsize, &ltype);
-       if (lsize < 1) return 7;
+       if (lsize == 1) return 7;
        /*  Else try ARR0-ARR6 first  */
     }
     else
@@ -1087,11 +1092,11 @@ static int cyrix_get_free_region (unsigned long base, unsigned long size)
        {
            cyrix_get_arr (i, &lbase, &lsize, &ltype);
            if ((i == 3) && arr3_protected) continue;
-           if (lsize < 1) return i;
+           if (lsize == 0) return i;
        }
        /* ARR0-ARR6 isn't free, try ARR7 but its size must be at least 256K */
        cyrix_get_arr (i, &lbase, &lsize, &ltype);
-       if ((lsize < 1) && (size >= 0x40000)) return i;
+       if ((lsize == 0) && (size >= 0x40)) return i;
     }
     return -ENOSPC;
 }   /*  End Function cyrix_get_free_region  */
@@ -1100,9 +1105,9 @@ static int (*get_free_region) (unsigned long base,
                               unsigned long size) = generic_get_free_region;
 
 /**
- *     mtrr_add - Add a memory type region
- *     @base: Physical base address of region
- *     @size: Physical size of region
+ *     mtrr_add_page - Add a memory type region
+ *     @base: Physical base address of region in pages (4 KB)
+ *     @size: Physical size of region in pages (4 KB)
  *     @type: Type of MTRR desired
  *     @increment: If this is true do usage counting on the region
  *
@@ -1135,11 +1140,11 @@ static int (*get_free_region) (unsigned long base,
  *     failures and do not wish system log messages to be sent.
  */
 
-int mtrr_add(unsigned long base, unsigned long size, unsigned int type, char increment)
+int mtrr_add_page(unsigned long base, unsigned long size, unsigned int type, char increment)
 {
 /*  [SUMMARY] Add an MTRR entry.
-    <base> The starting (base) address of the region.
-    <size> The size (in bytes) of the region.
+    <base> The starting (base, in pages) address of the region.
+    <size> The size of the region. (in pages)
     <type> The type of the new region.
     <increment> If true and the region already exists, the usage count will be
     incremented.
@@ -1164,7 +1169,7 @@ int mtrr_add(unsigned long base, unsigned long size, unsigned int type, char inc
           o Power of 2 block
           o base suitably aligned to the power
        */
-       if ( type > MTRR_TYPE_WRCOMB || size < (1 << 17) ||
+       if ( type > MTRR_TYPE_WRCOMB || size < (1 << (17-PAGE_SHIFT)) ||
             (size & ~(size-1))-size || ( base & (size-1) ) )
            return -EINVAL;
        break;
@@ -1176,9 +1181,9 @@ int mtrr_add(unsigned long base, unsigned long size, unsigned int type, char inc
             boot_cpu_data.x86_model == 1 &&
             boot_cpu_data.x86_mask <= 7 )
        {
-           if ( base & ((1 << 22)-1) )
+           if ( base & ((1 << (22-PAGE_SHIFT))-1) )
            {
-               printk (KERN_WARNING "mtrr: base(0x%lx) is not 4 MiB aligned\n", base);
+               printk (KERN_WARNING "mtrr: base(0x%lx000) is not 4 MiB aligned\n", base);
                return -EINVAL;
            }
        }
@@ -1186,12 +1191,6 @@ int mtrr_add(unsigned long base, unsigned long size, unsigned int type, char inc
        
     case MTRR_IF_CYRIX_ARR:
     case MTRR_IF_CENTAUR_MCR:
-       if ( (base & 0xfff) || (size & 0xfff) )
-       {
-           printk ("mtrr: size and base must be multiples of 4 kiB\n");
-           printk ("mtrr: size: %lx  base: %lx\n", size, base);
-           return -EINVAL;
-       }
         if ( mtrr_if == MTRR_IF_CENTAUR_MCR )
        {
            if (type != MTRR_TYPE_WRCOMB)
@@ -1200,9 +1199,9 @@ int mtrr_add(unsigned long base, unsigned long size, unsigned int type, char inc
                return -EINVAL;
            }
        }
-       else if (base + size < 0x100000)
+       else if (base + size < 0x100)
        {
-           printk (KERN_WARNING "mtrr: cannot set region below 1 MiB (0x%lx,0x%lx)\n",
+           printk (KERN_WARNING "mtrr: cannot set region below 1 MiB (0x%lx000,0x%lx000)\n",
                    base, size);
            return -EINVAL;
        }
@@ -1213,7 +1212,7 @@ int mtrr_add(unsigned long base, unsigned long size, unsigned int type, char inc
             lbase = lbase >> 1, last = last >> 1);
        if (lbase != last)
        {
-           printk (KERN_WARNING "mtrr: base(0x%lx) is not aligned on a size(0x%lx) boundary\n",
+           printk (KERN_WARNING "mtrr: base(0x%lx000) is not aligned on a size(0x%lx000) boundary\n",
                    base, size);
            return -EINVAL;
        }
@@ -1228,12 +1227,20 @@ int mtrr_add(unsigned long base, unsigned long size, unsigned int type, char inc
        printk ("mtrr: type: %u illegal\n", type);
        return -EINVAL;
     }
+
     /*  If the type is WC, check that this processor supports it  */
     if ( (type == MTRR_TYPE_WRCOMB) && !have_wrcomb () )
     {
         printk (KERN_WARNING "mtrr: your processor doesn't support write-combining\n");
         return -ENOSYS;
     }
+
+    if ( base & size_or_mask || size  & size_or_mask )
+    {
+       printk ("mtrr: base or size exceeds the MTRR width\n");
+       return -EINVAL;
+    }
+
     increment = increment ? 1 : 0;
     max = get_num_var_ranges ();
     /*  Search for existing MTRR  */
@@ -1247,7 +1254,8 @@ int mtrr_add(unsigned long base, unsigned long size, unsigned int type, char inc
        if ( (base < lbase) || (base + size > lbase + lsize) )
        {
            up(&main_lock);
-           printk (KERN_WARNING "mtrr: 0x%lx,0x%lx overlaps existing 0x%lx,0x%lx\n",
+           printk (KERN_WARNING "mtrr: 0x%lx000,0x%lx000 overlaps existing"
+                   " 0x%lx000,0x%lx000\n",
                    base, size, lbase, lsize);
            return -EINVAL;
        }
@@ -1256,7 +1264,7 @@ int mtrr_add(unsigned long base, unsigned long size, unsigned int type, char inc
        {
            if (type == MTRR_TYPE_UNCACHABLE) continue;
            up(&main_lock);
-           printk ( "mtrr: type mismatch for %lx,%lx old: %s new: %s\n",
+           printk ( "mtrr: type mismatch for %lx000,%lx000 old: %s new: %s\n",
                     base, size, attrib_to_str (ltype), attrib_to_str (type) );
            return -EINVAL;
        }
@@ -1278,10 +1286,67 @@ int mtrr_add(unsigned long base, unsigned long size, unsigned int type, char inc
     compute_ascii ();
     up(&main_lock);
     return i;
+}   /*  End Function mtrr_add_page  */
+
+/**
+ *     mtrr_add - Add a memory type region
+ *     @base: Physical base address of region
+ *     @size: Physical size of region
+ *     @type: Type of MTRR desired
+ *     @increment: If this is true do usage counting on the region
+ *
+ *     Memory type region registers control the caching on newer Intel and
+ *     non Intel processors. This function allows drivers to request an
+ *     MTRR is added. The details and hardware specifics of each processor's
+ *     implementation are hidden from the caller, but nevertheless the 
+ *     caller should expect to need to provide a power of two size on an
+ *     equivalent power of two boundary.
+ *
+ *     If the region cannot be added either because all regions are in use
+ *     or the CPU cannot support it a negative value is returned. On success
+ *     the register number for this entry is returned, but should be treated
+ *     as a cookie only.
+ *
+ *     On a multiprocessor machine the changes are made to all processors.
+ *     This is required on x86 by the Intel processors.
+ *
+ *     The available types are
+ *
+ *     %MTRR_TYPE_UNCACHEABLE  -       No caching
+ *
+ *     %MTRR_TYPE_WRITEBACK    -       Write data back in bursts whenever
+ *
+ *     %MTRR_TYPE_WRCOMB       -       Write data back soon but allow bursts
+ *
+ *     %MTRR_TYPE_WRTHROUGH    -       Cache reads but not writes
+ *
+ *     BUGS: Needs a quiet flag for the cases where drivers do not mind
+ *     failures and do not wish system log messages to be sent.
+ */
+
+int mtrr_add(unsigned long base, unsigned long size, unsigned int type, char increment)
+{
+/*  [SUMMARY] Add an MTRR entry.
+    <base> The starting (base) address of the region.
+    <size> The size (in bytes) of the region.
+    <type> The type of the new region.
+    <increment> If true and the region already exists, the usage count will be
+    incremented.
+    [RETURNS] The MTRR register on success, else a negative number indicating
+    the error code.
+*/
+
+    if ( (base & (PAGE_SIZE - 1)) || (size & (PAGE_SIZE - 1)) )
+    {
+       printk ("mtrr: size and base must be multiples of 4 kiB\n");
+       printk ("mtrr: size: 0x%lx  base: 0x%lx\n", size, base);
+       return -EINVAL;
+    }
+    return mtrr_add_page(base >> PAGE_SHIFT, size >> PAGE_SHIFT, type, increment);
 }   /*  End Function mtrr_add  */
 
 /**
- *     mtrr_del - delete a memory type region
+ *     mtrr_del_page - delete a memory type region
  *     @reg: Register returned by mtrr_add
  *     @base: Physical base address
  *     @size: Size of region
@@ -1295,7 +1360,7 @@ int mtrr_add(unsigned long base, unsigned long size, unsigned int type, char inc
  *     code.
  */
  
-int mtrr_del (int reg, unsigned long base, unsigned long size)
+int mtrr_del_page (int reg, unsigned long base, unsigned long size)
 /*  [SUMMARY] Delete MTRR/decrement usage count.
     <reg> The register. If this is less than 0 then <<base>> and <<size>> must
     be supplied.
@@ -1320,7 +1385,7 @@ int mtrr_del (int reg, unsigned long base, unsigned long size)
        for (i = 0; i < max; ++i)
        {
            (*get_mtrr) (i, &lbase, &lsize, &ltype);
-           if ( (lbase == base) && (lsize == size) )
+           if (lbase == base && lsize == size)
            {
                reg = i;
                break;
@@ -1329,7 +1394,7 @@ int mtrr_del (int reg, unsigned long base, unsigned long size)
        if (reg < 0)
        {
            up(&main_lock);
-           printk ("mtrr: no MTRR for %lx,%lx found\n", base, size);
+           printk ("mtrr: no MTRR for %lx000,%lx000 found\n", base, size);
            return -EINVAL;
        }
     }
@@ -1365,12 +1430,46 @@ int mtrr_del (int reg, unsigned long base, unsigned long size)
     compute_ascii ();
     up (&main_lock);
     return reg;
-}   /*  End Function mtrr_del  */
+}   /*  End Function mtrr_del_page  */
+
+/**
+ *     mtrr_del - delete a memory type region
+ *     @reg: Register returned by mtrr_add
+ *     @base: Physical base address
+ *     @size: Size of region
+ *
+ *     If register is supplied then base and size are ignored. This is
+ *     how drivers should call it.
+ *
+ *     Releases an MTRR region. If the usage count drops to zero the 
+ *     register is freed and the region returns to default state.
+ *     On success the register is returned, on failure a negative error
+ *     code.
+ */
+int mtrr_del (int reg, unsigned long base, unsigned long size)
+/*  [SUMMARY] Delete MTRR/decrement usage count.
+    <reg> The register. If this is less than 0 then <<base>> and <<size>> must
+    be supplied.
+    <base> The base address of the region. This is ignored if <<reg>> is >= 0.
+    <size> The size of the region. This is ignored if <<reg>> is >= 0.
+    [RETURNS] The register on success, else a negative number indicating
+    the error code.
+*/
+{
+    if ( (base & (PAGE_SIZE - 1)) || (size & (PAGE_SIZE - 1)) )
+    {
+       printk ("mtrr: size and base must be multiples of 4 kiB\n");
+       printk ("mtrr: size: 0x%lx  base: 0x%lx\n", size, base);
+       return -EINVAL;
+    }
+    return mtrr_del_page(reg, base >> PAGE_SHIFT, size >> PAGE_SHIFT);
+}
 
 #ifdef USERSPACE_INTERFACE
 
 static int mtrr_file_add (unsigned long base, unsigned long size,
-                         unsigned int type, char increment, struct file *file)
+                         unsigned int type, char increment, struct file *file, int page)
 {
     int reg, max;
     unsigned int *fcount = file->private_data;
@@ -1386,18 +1485,38 @@ static int mtrr_file_add (unsigned long base, unsigned long size,
        memset (fcount, 0, max * sizeof *fcount);
        file->private_data = fcount;
     }
-    reg = mtrr_add (base, size, type, 1);
+    if (!page) {
+       if ( (base & (PAGE_SIZE - 1)) || (size & (PAGE_SIZE - 1)) )
+       {
+           printk ("mtrr: size and base must be multiples of 4 kiB\n");
+           printk ("mtrr: size: 0x%lx  base: 0x%lx\n", size, base);
+           return -EINVAL;
+       }
+       base >>= PAGE_SHIFT;
+       size >>= PAGE_SHIFT;
+    }
+    reg = mtrr_add_page (base, size, type, 1);
     if (reg >= 0) ++fcount[reg];
     return reg;
 }   /*  End Function mtrr_file_add  */
 
 static int mtrr_file_del (unsigned long base, unsigned long size,
-                         struct file *file)
+                         struct file *file, int page)
 {
     int reg;
     unsigned int *fcount = file->private_data;
 
-    reg = mtrr_del (-1, base, size);
+    if (!page) {
+       if ( (base & (PAGE_SIZE - 1)) || (size & (PAGE_SIZE - 1)) )
+       {
+           printk ("mtrr: size and base must be multiples of 4 kiB\n");
+           printk ("mtrr: size: 0x%lx  base: 0x%lx\n", size, base);
+           return -EINVAL;
+       }
+       base >>= PAGE_SHIFT;
+       size >>= PAGE_SHIFT;
+    }
+    reg = mtrr_del_page (-1, base, size);
     if (reg < 0) return reg;
     if (fcount == NULL) return reg;
     if (fcount[reg] < 1) return -EINVAL;
@@ -1418,12 +1537,13 @@ static ssize_t mtrr_read (struct file *file, char *buf, size_t len,
 static ssize_t mtrr_write (struct file *file, const char *buf, size_t len,
                           loff_t *ppos)
 /*  Format of control line:
-    "base=%lx size=%lx type=%s"     OR:
+    "base=%Lx size=%Lx type=%s"     OR:
     "disable=%d"
 */
 {
     int i, err;
-    unsigned long reg, base, size;
+    unsigned long reg;
+    unsigned long long base, size;
     char *ptr;
     char line[LINE_SIZE];
 
@@ -1438,7 +1558,7 @@ static ssize_t mtrr_write (struct file *file, const char *buf, size_t len,
     if ( !strncmp (line, "disable=", 8) )
     {
        reg = simple_strtoul (line + 8, &ptr, 0);
-       err = mtrr_del (reg, 0, 0);
+       err = mtrr_del_page (reg, 0, 0);
        if (err < 0) return err;
        return len;
     }
@@ -1447,14 +1567,20 @@ static ssize_t mtrr_write (struct file *file, const char *buf, size_t len,
        printk ("mtrr: no \"base=\" in line: \"%s\"\n", line);
        return -EINVAL;
     }
-    base = simple_strtoul (line + 5, &ptr, 0);
+    base = simple_strtoull (line + 5, &ptr, 0);
     for (; isspace (*ptr); ++ptr);
     if ( strncmp (ptr, "size=", 5) )
     {
        printk ("mtrr: no \"size=\" in line: \"%s\"\n", line);
        return -EINVAL;
     }
-    size = simple_strtoul (ptr + 5, &ptr, 0);
+    size = simple_strtoull (ptr + 5, &ptr, 0);
+    if ( (base & 0xfff) || (size & 0xfff) )
+    {
+       printk ("mtrr: size and base must be multiples of 4 kiB\n");
+       printk ("mtrr: size: 0x%Lx  base: 0x%Lx\n", size, base);
+       return -EINVAL;
+    }
     for (; isspace (*ptr); ++ptr);
     if ( strncmp (ptr, "type=", 5) )
     {
@@ -1466,7 +1592,9 @@ static ssize_t mtrr_write (struct file *file, const char *buf, size_t len,
     for (i = 0; i < MTRR_NUM_TYPES; ++i)
     {
        if ( strcmp (ptr, mtrr_strings[i]) ) continue;
-       err = mtrr_add (base, size, i, 1);
+       base >>= PAGE_SHIFT;
+       size >>= PAGE_SHIFT;
+       err = mtrr_add_page ((unsigned long)base, (unsigned long)size, i, 1);
        if (err < 0) return err;
        return len;
     }
@@ -1490,7 +1618,7 @@ static int mtrr_ioctl (struct inode *inode, struct file *file,
        if ( !suser () ) return -EPERM;
        if ( copy_from_user (&sentry, (void *) arg, sizeof sentry) )
            return -EFAULT;
-       err = mtrr_file_add (sentry.base, sentry.size, sentry.type, 1, file);
+       err = mtrr_file_add (sentry.base, sentry.size, sentry.type, 1, file, 0);
        if (err < 0) return err;
        break;
       case MTRRIOC_SET_ENTRY:
@@ -1504,7 +1632,7 @@ static int mtrr_ioctl (struct inode *inode, struct file *file,
        if ( !suser () ) return -EPERM;
        if ( copy_from_user (&sentry, (void *) arg, sizeof sentry) )
            return -EFAULT;
-       err = mtrr_file_del (sentry.base, sentry.size, file);
+       err = mtrr_file_del (sentry.base, sentry.size, file, 0);
        if (err < 0) return err;
        break;
       case MTRRIOC_KILL_ENTRY:
@@ -1519,7 +1647,54 @@ static int mtrr_ioctl (struct inode *inode, struct file *file,
            return -EFAULT;
        if ( gentry.regnum >= get_num_var_ranges () ) return -EINVAL;
        (*get_mtrr) (gentry.regnum, &gentry.base, &gentry.size, &type);
+
+       /* Hide entries that go above 4GB */
+       if (gentry.base + gentry.size > 0x100000 || gentry.size == 0x100000)
+           gentry.base = gentry.size = gentry.type = 0;
+       else {
+           gentry.base <<= PAGE_SHIFT;
+           gentry.size <<= PAGE_SHIFT;
+           gentry.type = type;
+       }
+
+       if ( copy_to_user ( (void *) arg, &gentry, sizeof gentry) )
+            return -EFAULT;
+       break;
+      case MTRRIOC_ADD_PAGE_ENTRY:
+       if ( !suser () ) return -EPERM;
+       if ( copy_from_user (&sentry, (void *) arg, sizeof sentry) )
+           return -EFAULT;
+       err = mtrr_file_add (sentry.base, sentry.size, sentry.type, 1, file, 1);
+       if (err < 0) return err;
+       break;
+      case MTRRIOC_SET_PAGE_ENTRY:
+       if ( !suser () ) return -EPERM;
+       if ( copy_from_user (&sentry, (void *) arg, sizeof sentry) )
+           return -EFAULT;
+       err = mtrr_add_page (sentry.base, sentry.size, sentry.type, 0);
+       if (err < 0) return err;
+       break;
+      case MTRRIOC_DEL_PAGE_ENTRY:
+       if ( !suser () ) return -EPERM;
+       if ( copy_from_user (&sentry, (void *) arg, sizeof sentry) )
+           return -EFAULT;
+       err = mtrr_file_del (sentry.base, sentry.size, file, 1);
+       if (err < 0) return err;
+       break;
+      case MTRRIOC_KILL_PAGE_ENTRY:
+       if ( !suser () ) return -EPERM;
+       if ( copy_from_user (&sentry, (void *) arg, sizeof sentry) )
+           return -EFAULT;
+       err = mtrr_del_page (-1, sentry.base, sentry.size);
+       if (err < 0) return err;
+       break;
+      case MTRRIOC_GET_PAGE_ENTRY:
+       if ( copy_from_user (&gentry, (void *) arg, sizeof gentry) )
+           return -EFAULT;
+       if ( gentry.regnum >= get_num_var_ranges () ) return -EINVAL;
+       (*get_mtrr) (gentry.regnum, &gentry.base, &gentry.size, &type);
        gentry.type = type;
+
        if ( copy_to_user ( (void *) arg, &gentry, sizeof gentry) )
             return -EFAULT;
        break;
@@ -1578,24 +1753,24 @@ static void compute_ascii (void)
     for (i = 0; i < max; i++)
     {
        (*get_mtrr) (i, &base, &size, &type);
-       if (size < 1) usage_table[i] = 0;
+       if (size == 0) usage_table[i] = 0;
        else
        {
-           if (size < 0x100000)
+           if (size < (0x100000 >> PAGE_SHIFT))
            {
-               /* 1MB */
-               factor = 'k';
-               size >>= 10;
+               /* less than 1MB */
+               factor = 'K';
+               size <<= PAGE_SHIFT - 10;
            }
            else
            {
                factor = 'M';
-               size >>= 20;
+               size >>= 20 - PAGE_SHIFT;
            }
            sprintf
                (ascii_buffer + ascii_buf_bytes,
-                "reg%02i: base=0x%08lx (%4liMB), size=%4li%cB: %s, count=%d\n",
-                i, base, base>>20, size, factor,
+                "reg%02i: base=0x%05lx000 (%4liMB), size=%4li%cB: %s, count=%d\n",
+                i, base, base >> (20 - PAGE_SHIFT), size, factor,
                 attrib_to_str (type), usage_table[i]);
            ascii_buf_bytes += strlen (ascii_buffer + ascii_buf_bytes);
        }
@@ -1762,11 +1937,38 @@ static int __init mtrr_setup(void)
        mtrr_if = MTRR_IF_INTEL;
        get_mtrr = intel_get_mtrr;
        set_mtrr_up = intel_set_mtrr_up;
+       switch (boot_cpu_data.x86_vendor) {
+       case X86_VENDOR_AMD:
+               /* The original Athlon docs said that
+                  total addressable memory is 44 bits wide.
+                  It was not really clear whether its MTRRs
+                  follow this or not. (Read: 44 or 36 bits).
+                  However, "x86-64_overview.pdf" explicitly
+                  states that "previous implementations support
+                  36 bit MTRRs" and also provides a way to
+                  query the width (in bits) of the physical
+                  addressable memory on the Hammer family.
+                */
+               if (boot_cpu_data.x86 == 7 && (cpuid_eax(0x80000000) >= 0x80000008)) {
+                       u32     phys_addr;
+                       phys_addr = cpuid_eax(0x80000008) & 0xff ;
+                       size_or_mask = ~((1 << (phys_addr - PAGE_SHIFT)) - 1);
+                       size_and_mask = ~size_or_mask & 0xfff00000;
+                       break;
+               }
+       default:
+               /* Intel, etc. */
+               size_or_mask  = 0xff000000; /* 36 bits */
+               size_and_mask = 0x00f00000;
+               break;
+       }
     } else if ( test_bit(X86_FEATURE_K6_MTRR, &boot_cpu_data.x86_capability) ) {
        /* Pre-Athlon (K6) AMD CPU MTRRs */
        mtrr_if = MTRR_IF_AMD_K6;
        get_mtrr = amd_get_mtrr;
        set_mtrr_up = amd_set_mtrr_up;
+       size_or_mask  = 0xfff00000; /* 32 bits */
+       size_and_mask = 0;
     } else if ( test_bit(X86_FEATURE_CYRIX_ARR, &boot_cpu_data.x86_capability) ) {
        /* Cyrix ARRs */
        mtrr_if = MTRR_IF_CYRIX_ARR;
@@ -1774,12 +1976,16 @@ static int __init mtrr_setup(void)
        set_mtrr_up = cyrix_set_arr_up;
        get_free_region = cyrix_get_free_region;
        cyrix_arr_init();
+       size_or_mask  = 0xfff00000; /* 32 bits */
+       size_and_mask = 0;
     } else if ( test_bit(X86_FEATURE_CENTAUR_MCR, &boot_cpu_data.x86_capability) ) {
        /* Centaur MCRs */
        mtrr_if = MTRR_IF_CENTAUR_MCR;
        get_mtrr = centaur_get_mcr;
        set_mtrr_up = centaur_set_mcr_up;
        centaur_mcr_init();
+       size_or_mask  = 0xfff00000; /* 32 bits */
+       size_and_mask = 0;
     } else {
        /* No supported MTRR interface */
        mtrr_if = MTRR_IF_NONE;
index 7c9dc14fdd4572eeb20eb42c30ddf91a8f140a77..4871aa2ae39e12dfe8a7158db2fa21072055059b 100644 (file)
@@ -1531,8 +1531,32 @@ static void __init init_intel(struct cpuinfo_x86 *c)
                                dh = des >> 4;
                                dl = des & 0x0F;
 
+                               /* Black magic... */
+
                                switch ( dh )
                                {
+                               case 0:
+                                       switch ( dl ) {
+                                       case 6:
+                                               /* L1 I cache */
+                                               l1i += 8;
+                                               break;
+                                       case 8:
+                                               /* L1 I cache */
+                                               l1i += 16;
+                                               break;
+                                       case 10:
+                                               /* L1 D cache */
+                                               l1d += 8;
+                                               break;
+                                       case 12:
+                                               /* L1 D cache */
+                                               l1d += 16;
+                                               break;
+                                       default:
+                                               /* TLB, or unknown */
+                                       }
+                                       break;
                                case 2:
                                        if ( dl ) {
                                                /* L3 cache */
@@ -1541,6 +1565,16 @@ static void __init init_intel(struct cpuinfo_x86 *c)
                                        }
                                        break;
                                case 4:
+                                       if ( c->x86 > 6 && dl ) {
+                                               /* P4 family */
+                                               if ( dl ) {
+                                                       /* L3 cache */
+                                                       cs = 128 << (dl-1);
+                                                       l3 += cs;
+                                                       break;
+                                               }
+                                       }
+                                       /* else same as 8 - fall through */
                                case 8:
                                        if ( dl ) {
                                                /* L2 cache */
@@ -1556,9 +1590,16 @@ static void __init init_intel(struct cpuinfo_x86 *c)
                                        }
                                        break;
                                case 7:
-                                       /* L1 I cache */
-                                       cs = dl ? (16 << (dl-1)) : 12;
-                                       l1i += cs;
+                                       if ( dl >= 8 ) 
+                                       {
+                                               /* L2 cache */
+                                               cs = 64<<(dl-8);
+                                               l2 += cs;
+                                       } else {
+                                               /* L0 I cache, count as L1 */
+                                               cs = dl ? (16 << (dl-1)) : 12;
+                                               l1i += cs;
+                                       }
                                        break;
                                default:
                                        /* TLB, or something else we don't know about */
@@ -2066,8 +2107,8 @@ int get_cpuinfo(char * buffer)
                /* Intel-defined */
                "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce",
                "cx8", "apic", NULL, "sep", "mtrr", "pge", "mca", "cmov",
-               "pat", "pse36", "pn", "clflsh", NULL, "dtes", "acpi", "mmx",
-               "fxsr", "sse", "sse2", "selfsnoop", NULL, "acc", "ia64", NULL,
+               "pat", "pse36", "pn", "clflush", NULL, "dts", "acpi", "mmx",
+               "fxsr", "sse", "sse2", "ss", NULL, "tm", "ia64", NULL,
 
                /* AMD-defined */
                NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
index e9fee546e080818bfa27282807721b9a4f0b78aa..b7bd84c73ea7b49dd86655d80b5dd5d5487fa774 100644 (file)
@@ -25,7 +25,6 @@ EXPORT_SYMBOL(amiga_audio_period);
 EXPORT_SYMBOL(amiga_audio_min_period);
 EXPORT_SYMBOL(amiga_do_irq);
 EXPORT_SYMBOL(amiga_do_irq_list);
-EXPORT_SYMBOL(amiga_intena_vals);
 
 #ifdef CONFIG_AMIGA_PCMCIA
   EXPORT_SYMBOL(pcmcia_reset);
index 58759ba3601a552dbf933c12159cb5d9fafaac30..0902518f9bad9014eacbeb384f4e0658155be050 100644 (file)
@@ -58,7 +58,7 @@ extern int cia_get_irq_list(struct ciabase *base, char *buf);
 /* irq node variables for amiga interrupt sources */
 static irq_node_t *ami_irq_list[AMI_STD_IRQS];
 
-unsigned short amiga_intena_vals[AMI_STD_IRQS] = {
+static unsigned short amiga_intena_vals[AMI_STD_IRQS] = {
        IF_VERTB, IF_COPER, IF_AUD0, IF_AUD1, IF_AUD2, IF_AUD3, IF_BLIT,
        IF_DSKSYN, IF_DSKBLK, IF_RBF, IF_TBE, IF_SOFT, IF_PORTS, IF_EXTER
 };
@@ -106,7 +106,7 @@ void __init amiga_init_IRQ(void)
 
        /* turn off PCMCIA interrupts */
        if (AMIGAHW_PRESENT(PCMCIA))
-               pcmcia_disable_irq();
+               gayle.inten = GAYLE_IRQ_IDE;
 
        /* turn off all interrupts and enable the master interrupt bit */
        custom.intena = 0x7fff;
@@ -352,67 +352,16 @@ inline void amiga_do_irq(int irq, struct pt_regs *fp)
        ami_irq_list[irq]->handler(irq, ami_irq_list[irq]->dev_id, fp);
 }
 
-void amiga_do_irq_list(int irq, struct pt_regs *fp, struct irq_server *server)
+void amiga_do_irq_list(int irq, struct pt_regs *fp)
 {
-       irq_node_t *node, *slow_nodes;
-       unsigned short flags, intena;
+       irq_node_t *node;
 
        kstat.irqs[0][SYS_IRQS + irq]++;
-       if (server->count++)
-               server->reentrance = 1;
-
-       intena = amiga_intena_vals[irq];
-       custom.intreq = intena;
-
-       /* serve fast handler if present - there can only be one of these */
-       node = ami_irq_list[irq];
 
-       /*
-        * Timer interrupts show up like this
-        */
-       if (!node) {
-               server->count--;
-               return;
-       }
+       custom.intreq = amiga_intena_vals[irq];
 
-       if (node && (node->flags & SA_INTERRUPT)) {
-               save_flags(flags);
-               cli();
+       for (node = ami_irq_list[irq]; node; node = node->next)
                node->handler(irq, node->dev_id, fp);
-               restore_flags(flags);
-
-               server->count--;
-               return;
-       }
-
-       /*
-        * Disable the interrupt source in question and reenable all
-        * other interrupts. No interrupt handler should ever touch
-        * the intena flags directly!
-        */
-       custom.intena = intena;
-       save_flags(flags);
-#if 0 /* def CPU_M68060_ONLY */
-       sti();
-#else
-       restore_flags((flags & ~0x0700) | (fp->sr & 0x0700));
-#endif
-
-       slow_nodes = node;
-       for (;;) {
-               for (; node; node = node->next)
-                       node->handler(irq, node->dev_id, fp);
-
-               if (!server->reentrance) {
-                       server->count--;
-                       restore_flags(flags);
-                       custom.intena = IF_SETCLR | intena;
-                       return;
-               }
-
-               server->reentrance = 0;
-               node = slow_nodes;
-       }
 }
 
 /*
@@ -445,7 +394,6 @@ static void ami_int1(int irq, void *dev_id, struct pt_regs *fp)
 static void ami_int3(int irq, void *dev_id, struct pt_regs *fp)
 {
        unsigned short ints = custom.intreqr & custom.intenar;
-       static struct irq_server server = {0, 0};
 
        /* if a blitter interrupt */
        if (ints & IF_BLIT) {
@@ -461,7 +409,7 @@ static void ami_int3(int irq, void *dev_id, struct pt_regs *fp)
 
        /* if a vertical blank interrupt */
        if (ints & IF_VERTB)
-               amiga_do_irq_list(IRQ_AMIGA_VERTB, fp, &server);
+               amiga_do_irq_list(IRQ_AMIGA_VERTB, fp);
 }
 
 static void ami_int4(int irq, void *dev_id, struct pt_regs *fp)
index 2210d05d6603d0cf8bd3d255247e2fc2a183ddea..4c94f786239682fcfe110aa7812bc282dd3cc4f2 100644 (file)
@@ -8,6 +8,7 @@
  * for more details.
  */
 
+#include <linux/config.h>
 #include <linux/sched.h>
 #include <linux/timer.h>
 #include <linux/init.h>
@@ -42,7 +43,9 @@ static u_long clock_constant;
 
 void __init amiga_init_sound(void)
 {
-       snd_data = amiga_chip_alloc(sizeof(sine_data), "Beep");
+       static struct resource beep_res = { "Beep" };
+
+       snd_data = amiga_chip_alloc_res(sizeof(sine_data), &beep_res);
        if (!snd_data) {
                printk (KERN_CRIT "amiga init_sound: failed to allocate chipmem\n");
                return;
@@ -51,6 +54,11 @@ void __init amiga_init_sound(void)
 
        /* setup divisor */
        clock_constant = (amiga_colorclock+DATA_SIZE/2)/DATA_SIZE;
+
+       /* without amifb, turn video off and enable high quality sound */
+#ifndef CONFIG_FB_AMIGA
+       amifb_video_off();
+#endif
 }
 
 static void nosound( unsigned long ignored );
index b7f9f0508c7f6608e3d39d56dd5aea8c8c332bd4..dfae2b43fd3e604377c40f02d72ef387cffbdb79 100644 (file)
 **
 **      Modified 03-May-94 by Geert Uytterhoeven <geert@linux-m68k.org>
 **          - 64-bit aligned allocations for full AGA compatibility
+**
+**     Rewritten 15/9/2000 by Geert to use resource management
 */
 
+#include <linux/config.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/ioport.h>
+#include <linux/slab.h>
 #include <asm/amigahw.h>
 
-struct chip_desc {
-       unsigned first   :  1;
-       unsigned last    :  1;
-       unsigned alloced :  1;
-       unsigned length  : 24;
-       long pad;                                       /* We suppose this makes this struct 64 bits long!! */
-};
-
-#define DP(ptr) ((struct chip_desc *)(ptr))
+unsigned long amiga_chip_size;
 
-u_long amiga_chip_size;
+static struct resource chipram_res = { "Chip RAM", CHIP_PHYSADDR };
 static unsigned long chipavail;
 
-static struct resource chipram = { "Chip RAM", 0 };
 
-unsigned long amiga_chip_avail( void )
+void __init amiga_chip_init(void)
 {
-#ifdef DEBUG
-       printk("chip_avail : %ld bytes\n",chipavail);
+    if (!AMIGAHW_PRESENT(CHIP_RAM))
+       return;
+
+#ifndef CONFIG_APUS_FAST_EXCEPT
+    /*
+     *  Remove the first 4 pages where PPC exception handlers will be located
+     */
+    amiga_chip_size -= 0x4000;
 #endif
-       return chipavail;
-}
+    chipram_res.end = amiga_chip_size-1;
+    request_resource(&iomem_resource, &chipram_res);
 
+    chipavail = amiga_chip_size;
+}
 
-void __init amiga_chip_init (void)
+    
+void *amiga_chip_alloc(unsigned long size, const char *name)
 {
-  struct chip_desc *dp;
-
-  if (!AMIGAHW_PRESENT(CHIP_RAM))
-    return;
+    struct resource *res;
 
-  chipram.end = amiga_chip_size-1;
-  request_resource(&iomem_resource, &chipram);
-
-  /* initialize start boundary */
-
-  dp = DP(chipaddr);
-  dp->first = 1;
-
-  dp->alloced = 0;
-  dp->length = amiga_chip_size - 2*sizeof(*dp);
-
-  /* initialize end boundary */
-  dp = DP(chipaddr + amiga_chip_size) - 1;
-  dp->last = 1;
-  
-  dp->alloced = 0;
-  dp->length = amiga_chip_size - 2*sizeof(*dp);
-  chipavail = dp->length;  /*MILAN*/
+    /* round up */
+    size = PAGE_ALIGN(size);
 
 #ifdef DEBUG
-  printk ("chipram end boundary is %p, length is %d\n", dp,
-         dp->length);
+    printk("amiga_chip_alloc: allocate %ld bytes\n", size);
 #endif
+    res = kmalloc(sizeof(struct resource), GFP_KERNEL);
+    if (!res)
+       return NULL;
+    memset(res, 0, sizeof(struct resource));
+    res->name = name;
+
+    if (allocate_resource(&chipram_res, res, size, 0, UINT_MAX, PAGE_SIZE, NULL, NULL) < 0) {
+       kfree(res);
+       return NULL;
+    }
+    chipavail -= size;
+#ifdef DEBUG
+    printk("amiga_chip_alloc: returning %lx\n", res->start);
+#endif
+    return (void *)ZTWO_VADDR(res->start);
 }
 
-void *amiga_chip_alloc(long size, const char *name)
-{
-       /* last chunk */
-       struct chip_desc *dp;
-       void *ptr;
 
-       /* round off */
-       size = (size + 7) & ~7;
+    /*
+     *  Warning:
+     *  amiga_chip_alloc_res is meant only for drivers that need to allocate
+     *  Chip RAM before kmalloc() is functional. As a consequence, those
+     *  drivers must not free that Chip RAM afterwards.
+     */
 
-#ifdef DEBUG
-   printk("amiga_chip_alloc: allocate %ld bytes\n", size);
-#endif
+void * __init amiga_chip_alloc_res(unsigned long size, struct resource *res)
+{
+    unsigned long start;
+
+    /* round up */
+    size = PAGE_ALIGN(size);
+    /* dmesg into chipmem prefers memory at the safe end */
+    start = CHIP_PHYSADDR + chipavail - size;
 
-       /*
-        * get pointer to descriptor for last chunk by 
-        * going backwards from end chunk
-        */
-       dp = DP(chipaddr + amiga_chip_size) - 1;
-       dp = DP((unsigned long)dp - dp->length) - 1;
-       
-       while ((dp->alloced || dp->length < size)
-              && !dp->first)
-               dp = DP ((unsigned long)dp - dp[-1].length) - 2;
-
-       if (dp->alloced || dp->length < size) {
-               printk ("no chipmem available for %ld allocation\n", size);
-               return NULL;
-       }
-
-       if (dp->length < (size + 2*sizeof(*dp))) {
-               /* length too small to split; allocate the whole thing */
-               dp->alloced = 1;
-               ptr = (void *)(dp+1);
-               dp = DP((unsigned long)ptr + dp->length);
-               dp->alloced = 1;
 #ifdef DEBUG
-               printk ("amiga_chip_alloc: no split\n");
+    printk("amiga_chip_alloc_res: allocate %ld bytes\n", size);
 #endif
-       } else {
-               /* split the extent; use the end part */
-               long newsize = dp->length - (2*sizeof(*dp) + size);
-
+    if (allocate_resource(&chipram_res, res, size, start, UINT_MAX, PAGE_SIZE, NULL, NULL) < 0) {
+       printk("amiga_chip_alloc_res: first alloc failed!\n");
+       if (allocate_resource(&chipram_res, res, size, 0, UINT_MAX, PAGE_SIZE, NULL, NULL) < 0)
+           return NULL;
+    }
+    chipavail -= size;
 #ifdef DEBUG
-               printk ("amiga_chip_alloc: splitting %d to %ld\n", dp->length,
-                       newsize);
+    printk("amiga_chip_alloc_res: returning %lx\n", res->start);
 #endif
-               dp->length = newsize;
-               dp = DP((unsigned long)(dp+1) + newsize);
-               dp->first = dp->last = 0;
-               dp->alloced = 0;
-               dp->length = newsize;
-               dp++;
-               dp->first = dp->last = 0;
-               dp->alloced = 1;
-               dp->length = size;
-               ptr = (void *)(dp+1);
-               dp = DP((unsigned long)ptr + size);
-               dp->alloced = 1;
-               dp->length = size;
-       }
+    return (void *)ZTWO_VADDR(res->start);
+}
 
+void amiga_chip_free(void *ptr)
+{
+    unsigned long start = ZTWO_PADDR(ptr);
+    struct resource **p, *res;
+    unsigned long size;
+
+    for (p = &chipram_res.child; (res = *p); p = &res->sibling) {
+       if (res->start != start)
+           continue;
+       *p = res->sibling;
+       size = res->end-start;
 #ifdef DEBUG
-       printk ("amiga_chip_alloc: returning %p\n", ptr);
+       printk("amiga_chip_free: free %ld bytes at %p\n", size, ptr);
 #endif
-
-       if ((unsigned long)ptr & 7)
-               panic("amiga_chip_alloc: alignment violation\n");
-
-    chipavail -= size + (2*sizeof(*dp)); /*MILAN*/
-
-    if (!request_mem_region(ZTWO_PADDR(ptr), size, name))
-       printk(KERN_WARNING "amiga_chip_alloc: region of size %ld at 0x%08lx "
-              "is busy\n", size, ZTWO_PADDR(ptr));
-
-    return ptr;
+       chipavail += size;
+       kfree(res);
+       return;
+    }
+    printk("amiga_chip_free: trying to free nonexistent region at %p\n", ptr);
 }
 
-void amiga_chip_free (void *ptr)
-{
-       struct chip_desc *sdp = DP(ptr) - 1, *dp2;
-       struct chip_desc *edp = DP((unsigned long)ptr + sdp->length);
 
-    chipavail += sdp->length + (2* sizeof(sdp)); /*MILAN*/
+unsigned long amiga_chip_avail(void)
+{
 #ifdef DEBUG
-   printk("chip_free: free %ld bytes at %p\n",sdp->length,ptr);
+       printk("amiga_chip_avail : %ld bytes\n", chipavail);
 #endif
-       /* deallocate the chunk */
-       sdp->alloced = edp->alloced = 0;
-       release_mem_region(ZTWO_PADDR(ptr), sdp->length);
-
-       /* check if we should merge with the previous chunk */
-       if (!sdp->first && !sdp[-1].alloced) {
-               dp2 = DP((unsigned long)sdp - sdp[-1].length) - 2;
-               dp2->length += sdp->length + 2*sizeof(*sdp);
-               edp->length = dp2->length;
-               sdp = dp2;
-       }
-
-       /* check if we should merge with the following chunk */
-       if (!edp->last && !edp[1].alloced) {
-               dp2 = DP((unsigned long)edp + edp[1].length) + 2;
-               dp2->length += edp->length + 2*sizeof(*sdp);
-               sdp->length = dp2->length;
-               edp = dp2;
-       }
+       return chipavail;
 }
index cda8986994aaea823a7064ca2cb7e92719256cd6..d72d8af9ff14d861fc945dc076fa67763c141577 100644 (file)
@@ -27,18 +27,17 @@ struct ciabase {
        u_short int_mask;
        int handler_irq, cia_irq, server_irq;
        char *name;
-       struct irq_server server;
        irq_handler_t irq_list[CIA_IRQS];
 } ciaa_base = {
        &ciaa, 0, 0, IF_PORTS,
        IRQ_AMIGA_AUTO_2, IRQ_AMIGA_CIAA,
        IRQ_AMIGA_PORTS,
-       "CIAA handler", {0, 0}
+       "CIAA handler"
 }, ciab_base = {
        &ciab, 0, 0, IF_EXTER,
        IRQ_AMIGA_AUTO_6, IRQ_AMIGA_CIAB,
        IRQ_AMIGA_EXTER,
-       "CIAB handler", {0, 0}
+       "CIAB handler"
 };
 
 /*
@@ -136,7 +135,7 @@ static void cia_handler(int irq, void *dev_id, struct pt_regs *fp)
                }
                ints >>= 1;
        }
-       amiga_do_irq_list(base->server_irq, fp, &base->server);
+       amiga_do_irq_list(base->server_irq, fp);
 }
 
 void __init cia_init_IRQ(struct ciabase *base)
index f139fd89a7c3699e4b62bbf0221b3341aec3edce..618d9a61830eebba23f24042fefa560c5093ea54 100644 (file)
@@ -31,6 +31,7 @@
 #include <asm/amigahw.h>
 #include <asm/amigaints.h>
 #include <asm/irq.h>
+#include <asm/keyboard.h>
 #include <asm/machdep.h>
 #include <asm/io.h>
 
@@ -71,6 +72,8 @@ static void amiga_sched_init(void (*handler)(int, void *, struct pt_regs *));
 /* amiga specific keyboard functions */
 extern int amiga_keyb_init(void);
 extern int amiga_kbdrate (struct kbd_repeat *);
+extern int amiga_kbd_translate(unsigned char keycode, unsigned char *keycodep,
+                              char raw_mode);
 /* amiga specific irq functions */
 extern void amiga_init_IRQ (void);
 extern void (*amiga_default_handler[]) (int, void *, struct pt_regs *);
@@ -388,6 +391,8 @@ void __init config_amiga(void)
   mach_sched_init      = amiga_sched_init;
   mach_keyb_init       = amiga_keyb_init;
   mach_kbdrate         = amiga_kbdrate;
+  mach_kbd_translate   = amiga_kbd_translate;
+  SYSRQ_KEY            = 0xff;
   mach_init_IRQ        = amiga_init_IRQ;
   mach_default_handler = &amiga_default_handler;
   mach_request_irq     = amiga_request_irq;
@@ -862,7 +867,9 @@ static void amiga_mem_console_write(struct console *co, const char *s,
 
 static void amiga_savekmsg_init(void)
 {
-    savekmsg = (struct savekmsg *)amiga_chip_alloc(SAVEKMSG_MAXMEM, "Debug");
+    static struct resource debug_res = { "Debug" };
+
+    savekmsg = amiga_chip_alloc_res(SAVEKMSG_MAXMEM, &debug_res);
     savekmsg->magic1 = SAVEKMSG_MAGIC1;
     savekmsg->magic2 = SAVEKMSG_MAGIC2;
     savekmsg->magicptr = virt_to_phys(savekmsg);
index d7a64faea53eed57472c1384964b0bb39866eb5d..36d88a6eddc9d550c0801c33f612d2da93fc921c 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/random.h>
 #include <linux/init.h>
 #include <linux/kbd_ll.h>
+#include <linux/kbd_kern.h>
 
 #include <asm/atariints.h>
 #include <asm/atarihw.h>
@@ -362,7 +363,7 @@ static void keyboard_interrupt(int irq, void *dummy, struct pt_regs *fp)
     if (acia_stat & ACIA_RDRF) /* received a character */
     {
        scancode = acia.key_data;       /* get it or reset the ACIA, I'll get it! */
-       mark_bh(KEYBOARD_BH);
+       tasklet_schedule(&keyboard_tasklet);
       interpret_scancode:
        switch (kb_state.state)
        {
@@ -860,3 +861,16 @@ int atari_kbdrate( struct kbd_repeat *k )
        
        return( 0 );
 }
+
+int atari_kbd_translate(unsigned char keycode, unsigned char *keycodep, char raw_mode)
+{
+#ifdef CONFIG_MAGIC_SYSRQ
+        /* ALT+HELP pressed? */
+        if ((keycode == 98) && ((shift_state & 0xff) == 8))
+                *keycodep = 0xff;
+        else
+#endif
+                *keycodep = keycode;
+        return 1;
+}
+
index 3acfeff7a2c280a2265598b1ba72e248de3ab7a4..70a32fb65108766291db9adf97cfee116865fdc6 100644 (file)
@@ -60,6 +60,8 @@ static int atari_get_hardware_list(char *buffer);
 /* atari specific keyboard functions */
 extern int atari_keyb_init(void);
 extern int atari_kbdrate (struct kbd_repeat *);
+extern int atari_kbd_translate(unsigned char keycode, unsigned char *keycodep,
+                              char raw_mode);
 extern void atari_kbd_leds (unsigned int);
 /* atari specific irq functions */
 extern void atari_init_IRQ (void);
@@ -253,6 +255,8 @@ void __init config_atari(void)
     mach_sched_init      = atari_sched_init;
     mach_keyb_init       = atari_keyb_init;
     mach_kbdrate         = atari_kbdrate;
+    mach_kbd_translate   = atari_kbd_translate;
+    SYSRQ_KEY            = 0xff;
     mach_kbd_leds        = atari_kbd_leds;
     mach_init_IRQ        = atari_init_IRQ;
     mach_request_irq     = atari_request_irq;
index d0acdaaaea3277bacc9563beea2cdaa7e2e60f37..b4a797f2e58c664227de70f802a5dbe145c1c777 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/vmalloc.h>
 #include <linux/pagemap.h>
 #include <linux/shm.h>
+#include <linux/bootmem.h>
 
 #include <asm/setup.h>
 #include <asm/machdep.h>
@@ -33,6 +34,7 @@
 
 #ifdef CONFIG_STRAM_SWAP
 #define MAJOR_NR    Z2RAM_MAJOR
+#define do_z2_request do_stram_request
 #include <linux/blk.h>
 #undef DEVICE_NAME
 #define DEVICE_NAME    "stram"
    unswap_by_move disabled because it does not handle swapped shm pages.
 */
 
+/* 2000-05-01: ++andreas
+   Integrated with bootmem.  Remove all traces of unswap_by_move.
+*/
+
 #ifdef CONFIG_STRAM_SWAP
 #define ALIGN_IF_SWAP(x)       PAGE_ALIGN(x)
 #else
 #endif
 
 /* get index of swap page at address 'addr' */
-#define SWAP_NR(addr)          (((unsigned long)(addr)-swap_start) >> PAGE_SHIFT)
+#define SWAP_NR(addr)          (((addr) - swap_start) >> PAGE_SHIFT)
 
 /* get address of swap page #'nr' */
-#define SWAP_ADDR(nr)          ((void *)(swap_start + ((nr)<<PAGE_SHIFT)))
+#define SWAP_ADDR(nr)          (swap_start + ((nr) << PAGE_SHIFT))
 
 /* get number of pages for 'n' bytes (already page-aligned) */
 #define N_PAGES(n)                     ((n) >> PAGE_SHIFT)
 #define MAX_STRAM_FRACTION_NOM         1
 #define MAX_STRAM_FRACTION_DENOM       3
 
-/* Start and end of the (pre-mem_init) reserved ST-RAM region */
-static unsigned long rsvd_stram_beg, rsvd_stram_end;
-
 /* Start and end (virtual) of ST-RAM */
-static unsigned long stram_start, stram_end;
+static void *stram_start, *stram_end;
 
 /* set after memory_init() executed and allocations via start_mem aren't
  * possible anymore */
@@ -159,7 +162,7 @@ static int kernel_in_stram;
 
 typedef struct stram_block {
        struct stram_block *next;
-       unsigned long start;
+       void *start;
        unsigned long size;
        unsigned flags;
        const char *owner;
@@ -168,7 +171,6 @@ typedef struct stram_block {
 /* values for flags field */
 #define BLOCK_FREE             0x01    /* free structure in the BLOCKs pool */
 #define BLOCK_KMALLOCED        0x02    /* structure allocated by kmalloc() */
-#define BLOCK_STATIC   0x04    /* pre-mem_init() allocated block */
 #define BLOCK_GFP              0x08    /* block allocated with __get_dma_pages() */
 #define BLOCK_INSWAP   0x10    /* block allocated in swap space */
 
@@ -191,7 +193,7 @@ static BLOCK static_blocks[N_STATIC_BLOCKS];
 static int max_swap_size = -1;
 
 /* start and end of swapping area */
-static unsigned long swap_start, swap_end;
+static void *swap_start, *swap_end;
 
 /* The ST-RAM's swap info structure */
 static struct swap_info_struct *stram_swap_info;
@@ -215,7 +217,6 @@ static DECLARE_MUTEX(stram_swap_sem);
 #ifdef DO_PROC
 static unsigned stat_swap_read = 0;
 static unsigned stat_swap_write = 0;
-static unsigned stat_swap_move = 0;
 static unsigned stat_swap_force = 0;
 #endif /* DO_PROC */
 
@@ -224,21 +225,19 @@ static unsigned stat_swap_force = 0;
 /***************************** Prototypes *****************************/
 
 #ifdef CONFIG_STRAM_SWAP
-static int swap_init( unsigned long start_mem, unsigned long swap_data );
+static int swap_init(void *start_mem, void *swap_data);
 static void *get_stram_region( unsigned long n_pages );
 static void free_stram_region( unsigned long offset, unsigned long n_pages
                               );
-static int in_some_region( unsigned long addr );
+static int in_some_region(void *addr);
 static unsigned long find_free_region( unsigned long n_pages, unsigned long
                                       *total_free, unsigned long
                                       *region_free );
-static void do_stram_request( void );
+static void do_stram_request(request_queue_t *);
 static int stram_open( struct inode *inode, struct file *filp );
 static int stram_release( struct inode *inode, struct file *filp );
-static void do_z2_request( void );
 #endif
-static int get_gfp_order( unsigned long size );
-static void reserve_region( unsigned long addr, unsigned long end );
+static void reserve_region(void *start, void *end);
 static BLOCK *add_region( void *addr, unsigned long size );
 static BLOCK *find_region( void *addr );
 static int remove_region( BLOCK *block );
@@ -264,14 +263,12 @@ void __init atari_stram_init(void)
 
        /* determine whether kernel code resides in ST-RAM (then ST-RAM is the
         * first memory block at virtual 0x0) */
-       stram_start = (unsigned long)phys_to_virt(0);
+       stram_start = phys_to_virt(0);
        kernel_in_stram = (stram_start == 0);
 
        for( i = 0; i < m68k_num_memory; ++i ) {
                if (m68k_memory[i].addr == 0) {
                        /* skip first 2kB or page (supervisor-only!) */
-                       rsvd_stram_beg = stram_start + ALIGN_IF_SWAP(0x800);
-                       rsvd_stram_end = rsvd_stram_beg;
                        stram_end = stram_start + m68k_memory[i].size;
                        return;
                }
@@ -282,10 +279,10 @@ void __init atari_stram_init(void)
 
 
 /*
- * This function is called from mem_init() to reserve the pages needed for
+ * This function is called from setup_arch() to reserve the pages needed for
  * ST-RAM management.
  */
-void __init atari_stram_reserve_pages(unsigned long start_mem)
+void __init atari_stram_reserve_pages(void *start_mem)
 {
 #ifdef CONFIG_STRAM_SWAP
        /* if max_swap_size is negative (i.e. no stram_swap= option given),
@@ -299,42 +296,24 @@ void __init atari_stram_reserve_pages(unsigned long start_mem)
                max_swap_size =
                        (!MACH_IS_HADES &&
                         (N_PAGES(stram_end-stram_start)*MAX_STRAM_FRACTION_DENOM <=
-                         max_mapnr*MAX_STRAM_FRACTION_NOM)) ? 16*1024*1024 : 0;
+                         (high_memory>>PAGE_SHIFT)*MAX_STRAM_FRACTION_NOM)) ? 16*1024*1024 : 0;
        DPRINTK( "atari_stram_reserve_pages: max_swap_size = %d\n", max_swap_size );
 #endif
 
        /* always reserve first page of ST-RAM, the first 2 kB are
         * supervisor-only! */
-       set_bit( PG_reserved, &virt_to_page(stram_start)->flags );
+       if (!kernel_in_stram)
+               reserve_bootmem (0, PAGE_SIZE);
 
 #ifdef CONFIG_STRAM_SWAP
-       if (!max_swap_size) {
-         fallback:
-#endif
-               DPRINTK( "atari_stram_reserve_pages: swapping disabled\n" );
-               if (!kernel_in_stram) {
-                       /* Reserve all pages that have been marked by pre-mem_init
-                        * stram_alloc() (e.g. for the screen memory). */
-                       reserve_region( rsvd_stram_beg, rsvd_stram_end );
-                       DPRINTK( "atari_stram_reserve_pages: reseverved %08lx-%08lx\n",
-                                        rsvd_stram_beg, rsvd_stram_end );
-               }
-               /* else (kernel in ST-RAM): nothing to do, ST-RAM buffers are
-                * kernel data */
-#ifdef CONFIG_STRAM_SWAP
-       }
-       else {
-               unsigned long swap_data;
-               BLOCK *p;
-
-               /* determine first page to use as swap:
-                * if the kernel is in TT-RAM, this is the first page of (usable)
-                * ST-RAM; else if there were already some allocations (probable...),
-                * use the lowest address of these (the list is sorted by address!);
-                * otherwise just use the end of kernel data (= start_mem) */
-               swap_start = !kernel_in_stram ? stram_start + PAGE_SIZE :
-                                        alloc_list ? alloc_list->start :
-                                        start_mem;
+       {
+               void *swap_data;
+
+               start_mem = (void *) PAGE_ALIGN ((unsigned long) start_mem);
+               /* determine first page to use as swap: if the kernel is
+                  in TT-RAM, this is the first page of (usable) ST-RAM;
+                  otherwise just use the end of kernel data (= start_mem) */
+               swap_start = !kernel_in_stram ? stram_start + PAGE_SIZE : start_mem;
                /* decrement by one page, rest of kernel assumes that first swap page
                 * is always reserved and maybe doesn't handle SWP_ENTRY == 0
                 * correctly */
@@ -343,7 +322,7 @@ void __init atari_stram_reserve_pages(unsigned long start_mem)
                if (swap_end-swap_start > max_swap_size)
                        swap_end =  swap_start + max_swap_size;
                DPRINTK( "atari_stram_reserve_pages: swapping enabled; "
-                                "swap=%08lx-%08lx\n", swap_start, swap_end );
+                                "swap=%p-%p\n", swap_start, swap_end);
                
                /* reserve some amount of memory for maintainance of
                 * swapping itself: one page for each 2048 (PAGE_SIZE/2)
@@ -352,24 +331,18 @@ void __init atari_stram_reserve_pages(unsigned long start_mem)
                start_mem += ((SWAP_NR(swap_end) + PAGE_SIZE/2 - 1)
                              >> (PAGE_SHIFT-1)) << PAGE_SHIFT;
                /* correct swap_start if necessary */
-               if (swap_start == swap_data)
-                       swap_start = start_mem;
+               if (swap_start + PAGE_SIZE == swap_data)
+                       swap_start = start_mem - PAGE_SIZE;
                
                if (!swap_init( start_mem, swap_data )) {
                        printk( KERN_ERR "ST-RAM swap space initialization failed\n" );
                        max_swap_size = 0;
-                       goto fallback;
+                       return;
                }
                /* reserve region for swapping meta-data */
-               reserve_region( swap_data, start_mem );
+               reserve_region(swap_data, start_mem);
                /* reserve swapping area itself */
-               reserve_region( swap_start+PAGE_SIZE, swap_end );
-
-               /* Formerly static areas have been included in the swap area. */
-               for( p = alloc_list; p; p = p->next ) {
-                       if (p->flags & BLOCK_STATIC)
-                               p->flags = (p->flags & ~BLOCK_STATIC) | BLOCK_INSWAP;
-               }
+               reserve_region(swap_start + PAGE_SIZE, swap_end);
 
                /*
                 * If the whole ST-RAM is used for swapping, there are no allocatable
@@ -387,15 +360,12 @@ void __init atari_stram_reserve_pages(unsigned long start_mem)
                 * You just will get non-DMA-able memory...
                 */
                mach_max_dma_address = 0xffffffff;
-
-               /*
-                * Ok, num_physpages needs not be really exact, but it's better to
-                * subtract the pages set aside for swapping.
-                */
-               num_physpages -= SWAP_NR(swap_end)-1;
        }
 #endif
-       
+}
+
+void atari_stram_mem_init_hook (void)
+{
        mem_init_done = 1;
 }
 
@@ -420,68 +390,33 @@ void __init atari_stram_reserve_pages(unsigned long start_mem)
  *    likely to fail :-(
  * 
  */
-void *atari_stram_alloc( long size, unsigned long *start_mem,
-                                                const char *owner )
+void *atari_stram_alloc(long size, const char *owner)
 {
        void *addr = NULL;
        BLOCK *block;
        int flags;
 
-       DPRINTK( "atari_stram_alloc(size=%08lx,*start_mem=%08lx,owner=%s)\n",
-                        size, start_mem ? *start_mem : 0xffffffff, owner );
-       
-       if (start_mem && mem_init_done) {
-               printk( KERN_ERR "atari_stram_alloc called with start_mem!=NULL "
-                               "after mem_init() from %p\n", __builtin_return_address(0) );
-               return( NULL );
-       }
-       if (!start_mem && !mem_init_done) {
-               printk( KERN_ERR "atari_stram_alloc called with start_mem==NULL "
-                               "before mem_init() from %p\n", __builtin_return_address(0) );
-               return( NULL );
-       }
+       DPRINTK("atari_stram_alloc(size=%08lx,owner=%s)\n", size, owner);
 
        size = ALIGN_IF_SWAP(size);
        DPRINTK( "atari_stram_alloc: rounded size = %08lx\n", size );
-       if (!mem_init_done) {
-               /* before mem_init(): allocate "statically", i.e. either in the kernel
-                * data space (current end in *start_mem), or at the end of currently
-                * reserved ST-RAM. */
-               if (kernel_in_stram) {
-                       /* Get memory from kernel data space */
-                       *start_mem = ALIGN_IF_SWAP(*start_mem);
-                       addr = (void *)*start_mem;
-                       *start_mem += size;
-                       DPRINTK( "atari_stram_alloc: pre-mem_init and k/ST: "
-                                        "shifted start_mem to %08lx, addr=%p\n",
-                                        *start_mem, addr );
-               }
-               else {
-                       /* Get memory from rsvd_stram_beg */
-                       if (rsvd_stram_end + size < stram_end) {
-                               addr = (void *) rsvd_stram_end;
-                               rsvd_stram_end += size;
-                               DPRINTK( "atari_stram_alloc: pre-mem_init and k/TT: "
-                                                "shifted rsvd_stram_end to %08lx, addr=%p\n",
-                                                rsvd_stram_end, addr );
-                       }
-               }
-               flags = BLOCK_STATIC;
-       }
 #ifdef CONFIG_STRAM_SWAP
-       else if (max_swap_size) {
-               /* If swapping is active (can only be the case after mem_init()!):
-                * make some free space in the swap "device". */
+       if (max_swap_size) {
+               /* If swapping is active: make some free space in the swap
+                  "device". */
                DPRINTK( "atari_stram_alloc: after mem_init, swapping ok, "
                                 "calling get_region\n" );
                addr = get_stram_region( N_PAGES(size) );
                flags = BLOCK_INSWAP;
        }
+       else
 #endif
+       if (!mem_init_done)
+               return alloc_bootmem_low(size);
        else {
                /* After mem_init() and no swapping: can only resort to
                 * __get_dma_pages() */
-               addr = (void *)__get_dma_pages(GFP_KERNEL, get_gfp_order(size));
+               addr = (void *)__get_dma_pages(GFP_KERNEL, get_order(size));
                flags = BLOCK_GFP;
                DPRINTK( "atari_stram_alloc: after mem_init, swapping off, "
                                 "get_pages=%p\n", addr );
@@ -492,14 +427,12 @@ void *atari_stram_alloc( long size, unsigned long *start_mem,
                        /* out of memory for BLOCK structure :-( */
                        DPRINTK( "atari_stram_alloc: out of mem for BLOCK -- "
                                         "freeing again\n" );
-                       if (flags == BLOCK_STATIC)
-                               rsvd_stram_end -= size;
 #ifdef CONFIG_STRAM_SWAP
-                       else if (flags == BLOCK_INSWAP)
+                       if (flags == BLOCK_INSWAP)
                                free_stram_region( SWAP_NR(addr), N_PAGES(size) );
-#endif
                        else
-                               free_pages( (unsigned long)addr, get_gfp_order(size));
+#endif
+                               free_pages((unsigned long)addr, get_order(size));
                        return( NULL );
                }
                block->owner = owner;
@@ -527,15 +460,15 @@ void atari_stram_free( void *addr )
        if (!max_swap_size) {
 #endif
                if (block->flags & BLOCK_GFP) {
-                       DPRINTK( "atari_stram_free: is kmalloced, order_size=%d\n",
-                                        get_gfp_order(block->size) );
-                       free_pages( (unsigned long)addr, get_gfp_order(block->size) );
+                       DPRINTK("atari_stram_free: is kmalloced, order_size=%d\n",
+                               get_order(block->size));
+                       free_pages((unsigned long)addr, get_order(block->size));
                }
                else
                        goto fail;
 #ifdef CONFIG_STRAM_SWAP
        }
-       else if (block->flags & (BLOCK_INSWAP|BLOCK_STATIC)) {
+       else if (block->flags & BLOCK_INSWAP) {
                DPRINTK( "atari_stram_free: is swap-alloced\n" );
                free_stram_region( SWAP_NR(block->start), N_PAGES(block->size) );
        }
@@ -563,17 +496,18 @@ void atari_stram_free( void *addr )
  * Initialize ST-RAM swap device
  * (lots copied and modified from sys_swapon() in mm/swapfile.c)
  */
-static int __init swap_init(unsigned long start_mem, unsigned long swap_data)
+static int __init swap_init(void *start_mem, void *swap_data)
 {
-       static struct dentry fake_dentry[3];
+       static struct dentry fake_dentry;
+       static struct vfsmount fake_vfsmnt;
        struct swap_info_struct *p;
        struct inode swap_inode;
        unsigned int type;
-       unsigned long addr;
+       void *addr;
        int i, j, k, prev;
 
-       DPRINTK( "swap_init(start_mem=%08lx, swap_data=%08lx)\n",
-                        start_mem, swap_data );
+       DPRINTK("swap_init(start_mem=%p, swap_data=%p)\n",
+               start_mem, swap_data);
        
        /* need at least one page for swapping to (and this also isn't very
         * much... :-) */
@@ -598,18 +532,16 @@ static int __init swap_init(unsigned long start_mem, unsigned long swap_data)
        stram_swap_type = type;
 
        /* fake some dir cache entries to give us some name in /dev/swaps */
-       fake_dentry[0].d_covers = &fake_dentry[1];
-       fake_dentry[0].d_parent = &fake_dentry[0];
-       fake_dentry[1].d_parent = &fake_dentry[2];
-       fake_dentry[1].d_name.name = "stram (internal)";
-       fake_dentry[1].d_name.len = 16;
-       fake_dentry[2].d_covers = &fake_dentry[2];
-       fake_dentry[2].d_parent = &fake_dentry[2];
+       fake_dentry.d_parent = &fake_dentry;
+       fake_dentry.d_name.name = "stram (internal)";
+       fake_dentry.d_name.len = 16;
+       fake_vfsmnt.mnt_parent = &fake_vfsmnt;
        
        p->flags        = SWP_USED;
-       p->swap_file    = &fake_dentry[0];
+       p->swap_file    = &fake_dentry;
+       p->swap_vfsmnt  = &fake_vfsmnt;
        p->swap_device  = 0;
-       p->swap_map     = (unsigned short *)swap_data;
+       p->swap_map     = swap_data;
        p->cluster_nr   = 0;
        p->next         = -1;
        p->prio         = 0x7ff0;       /* a rather high priority, but not the higest
@@ -628,7 +560,7 @@ static int __init swap_init(unsigned long start_mem, unsigned long swap_data)
        k = 0; /* # of already allocated pages (from pre-mem_init stram_alloc()) */
        p->lowest_bit = 0;
        p->highest_bit = 0;
-       for( i = 1, addr = (unsigned long)SWAP_ADDR(1); i < p->max;
+       for( i = 1, addr = SWAP_ADDR(1); i < p->max;
                 i++, addr += PAGE_SIZE ) {
                if (in_some_region( addr )) {
                        p->swap_map[i] = SWAP_MAP_BAD;
@@ -685,8 +617,8 @@ static int __init swap_init(unsigned long start_mem, unsigned long swap_data)
  * what to do if a write is requested later.
  */
 static inline void unswap_pte(struct vm_area_struct * vma, unsigned long
-                             address, pte_t *dir, unsigned long entry,
-                             unsigned long page /*, int isswap */)
+                             address, pte_t *dir, swp_entry_t entry,
+                             struct page *page)
 {
        pte_t pte = *dir;
 
@@ -698,34 +630,25 @@ static inline void unswap_pte(struct vm_area_struct * vma, unsigned long
                    memory */
                if (pte_page(pte) != page)
                        return;
-               if (0 /* isswap */)
-                       virt_to_page(pte_page(pte))->offset = page;
-               else
-                       /* We will be removing the swap cache in a moment, so... */
-                       set_pte(dir, pte_mkdirty(pte));
+               /* We will be removing the swap cache in a moment, so... */
+               set_pte(dir, pte_mkdirty(pte));
                return;
        }
-       if (pte_val(pte) != entry)
+       if (pte_val(pte) != entry.val)
                return;
 
-       if (0 /* isswap */) {
-               DPRINTK( "unswap_pte: replacing entry %08lx by %08lx", entry, page );
-               set_pte(dir, __pte(page));
-       }
-       else {
-               DPRINTK( "unswap_pte: replacing entry %08lx by new page %08lx",
-                                entry, page );
-               set_pte(dir, pte_mkdirty(__mk_pte(page,vma->vm_page_prot)));
-               atomic_inc(&virt_to_page(page)->count);
-               ++vma->vm_mm->rss;
-       }
+       DPRINTK("unswap_pte: replacing entry %08lx by new page %p",
+               entry.val, page);
+       set_pte(dir, pte_mkdirty(mk_pte(page, vma->vm_page_prot)));
        swap_free(entry);
+       get_page(page);
+       ++vma->vm_mm->rss;
 }
 
 static inline void unswap_pmd(struct vm_area_struct * vma, pmd_t *dir,
                              unsigned long address, unsigned long size,
-                             unsigned long offset, unsigned long entry,
-                             unsigned long page /* , int isswap */)
+                             unsigned long offset, swp_entry_t entry,
+                             struct page *page)
 {
        pte_t * pte;
        unsigned long end;
@@ -733,7 +656,7 @@ static inline void unswap_pmd(struct vm_area_struct * vma, pmd_t *dir,
        if (pmd_none(*dir))
                return;
        if (pmd_bad(*dir)) {
-               printk("unswap_pmd: bad pmd (%08lx)\n", pmd_val(*dir));
+               pmd_ERROR(*dir);
                pmd_clear(dir);
                return;
        }
@@ -744,8 +667,7 @@ static inline void unswap_pmd(struct vm_area_struct * vma, pmd_t *dir,
        if (end > PMD_SIZE)
                end = PMD_SIZE;
        do {
-               unswap_pte(vma, offset+address-vma->vm_start, pte, entry,
-                          page /* , isswap */);
+               unswap_pte(vma, offset+address-vma->vm_start, pte, entry, page);
                address += PAGE_SIZE;
                pte++;
        } while (address < end);
@@ -753,8 +675,7 @@ static inline void unswap_pmd(struct vm_area_struct * vma, pmd_t *dir,
 
 static inline void unswap_pgd(struct vm_area_struct * vma, pgd_t *dir,
                              unsigned long address, unsigned long size,
-                             unsigned long entry, unsigned long page
-                             /* , int isswap */)
+                             swp_entry_t entry, struct page *page)
 {
        pmd_t * pmd;
        unsigned long offset, end;
@@ -762,7 +683,7 @@ static inline void unswap_pgd(struct vm_area_struct * vma, pgd_t *dir,
        if (pgd_none(*dir))
                return;
        if (pgd_bad(*dir)) {
-               printk("unswap_pgd: bad pgd (%08lx)\n", pgd_val(*dir));
+               pgd_ERROR(*dir);
                pgd_clear(dir);
                return;
        }
@@ -774,28 +695,26 @@ static inline void unswap_pgd(struct vm_area_struct * vma, pgd_t *dir,
                end = PGDIR_SIZE;
        do {
                unswap_pmd(vma, pmd, address, end - address, offset, entry,
-                          page /* , isswap */);
+                          page);
                address = (address + PMD_SIZE) & PMD_MASK;
                pmd++;
        } while (address < end);
 }
 
 static void unswap_vma(struct vm_area_struct * vma, pgd_t *pgdir,
-                      unsigned long entry, unsigned long page
-                      /* , int isswap */)
+                      swp_entry_t entry, struct page *page)
 {
        unsigned long start = vma->vm_start, end = vma->vm_end;
 
-       while (start < end) {
-               unswap_pgd(vma, pgdir, start, end - start, entry, page
-                          /* , isswap */);
+       do {
+               unswap_pgd(vma, pgdir, start, end - start, entry, page);
                start = (start + PGDIR_SIZE) & PGDIR_MASK;
                pgdir++;
-       }
+       } while (start < end);
 }
 
-static void unswap_process(struct mm_struct * mm, unsigned long entry, 
-                          unsigned long page /* , int isswap */)
+static void unswap_process(struct mm_struct * mm, swp_entry_t entry, 
+                          struct page *page)
 {
        struct vm_area_struct* vma;
 
@@ -806,110 +725,18 @@ static void unswap_process(struct mm_struct * mm, unsigned long entry,
                return;
        for (vma = mm->mmap; vma; vma = vma->vm_next) {
                pgd_t * pgd = pgd_offset(mm, vma->vm_start);
-               unswap_vma(vma, pgd, entry, page /* , isswap */);
+               unswap_vma(vma, pgd, entry, page);
        }
 }
 
 
-#if 0
-static int unswap_by_move(unsigned short *map, unsigned long max,
-                         unsigned long start, unsigned long n_pages)
-{
-       struct task_struct *p;
-       unsigned long entry, rover = (start == 1) ? n_pages+1 : 1;
-       unsigned long i, j;
-
-       DPRINTK( "unswapping %lu..%lu by moving in swap\n",
-                        start, start+n_pages-1 );
-       
-       /* can free the allocated pages by moving them to other swap pages */
-       for( i = start; i < start+n_pages; ++i ) {
-               if (!map[i]) {
-                       map[i] = SWAP_MAP_BAD;
-                       DPRINTK( "unswap: page %lu was free\n", i );
-                       continue;
-               }
-               else if (map[i] == SWAP_MAP_BAD) {
-                       printk( KERN_ERR "get_stram_region: page %lu already "
-                                       "reserved??\n", i );
-               }
-               DPRINTK( "unswap: page %lu is alloced, count=%u\n", i, map[i] );
-
-               /* find a free page not in our region */
-               for( j = rover; j != rover-1; j = (j == max-1) ? 1 : j+1 ) {
-                       if (j >= start && j < start+n_pages)
-                               continue;
-                       if (!map[j]) {
-                               rover = j+1;
-                               break;
-                       }
-               }
-               if (j == rover-1) {
-                       printk( KERN_ERR "get_stram_region: not enough free swap "
-                                       "pages now??\n" );
-                       return( -ENOMEM );
-               }
-               DPRINTK( "unswap: map[i=%lu]=%u map[j=%lu]=%u nr_swap=%u\n",
-                                i, map[i], j, map[j], nr_swap_pages );
-               
-               --nr_swap_pages;
-               entry = SWP_ENTRY( stram_swap_type, j );
-               if (stram_swap_info->lowest_bit == j)
-                       stram_swap_info->lowest_bit++;
-               if (stram_swap_info->highest_bit == j)
-                       stram_swap_info->highest_bit--;
-               
-               memcpy( SWAP_ADDR(j), SWAP_ADDR(i), PAGE_SIZE );
-#ifdef DO_PROC
-               stat_swap_move++;
-#endif
-
-               while( map[i] ) {
-                       read_lock(&tasklist_lock);
-                       for_each_task(p) {
-                               if (unswap_process( p->mm, SWP_ENTRY( stram_swap_type, i ),
-                                                                       entry, 1 )) {
-                                       read_unlock(&tasklist_lock);
-                                       map[j]++;
-                                       goto repeat;
-                               }
-                       }
-                       read_unlock(&tasklist_lock);
-                       if (map[i] && map[i] != SWAP_MAP_MAX) {
-                               printk( KERN_ERR "get_stram_region: ST-RAM swap page %lu "
-                                               "not used by any process\n", i );
-                               /* quit while loop and overwrite bad map entry */
-                               break;
-                       }
-                       else if (!map[i]) {
-                               /* somebody else must have swapped in that page, so free the
-                                * new one (we're moving to) */
-                               DPRINTK( "unswap: map[i] became 0, also clearing map[j]\n" );
-                               map[j] = 0;
-                       }
-                 repeat:
-               }
-
-               DPRINTK( "unswap: map[i=%lu]=%u map[j=%lu]=%u nr_swap=%u\n",
-                                i, map[i], j, map[j], nr_swap_pages );
-               map[i] = SWAP_MAP_BAD;
-               if (stram_swap_info->lowest_bit == i)
-                       stram_swap_info->lowest_bit++;
-               if (stram_swap_info->highest_bit == i)
-                       stram_swap_info->highest_bit--;
-               --nr_swap_pages;
-       }
-       return( 0 );
-}
-#endif
-
 static int unswap_by_read(unsigned short *map, unsigned long max,
                          unsigned long start, unsigned long n_pages)
 {
        struct task_struct *p;
-       unsigned long entry, page;
+       struct page *page;
+       swp_entry_t entry;
        unsigned long i;
-       struct page *page_map;
 
        DPRINTK( "unswapping %lu..%lu by reading in\n",
                         start, start+n_pages-1 );
@@ -932,28 +759,24 @@ static int unswap_by_read(unsigned short *map, unsigned long max,
                        /* Get a page for the entry, using the existing
                           swap cache page if there is one.  Otherwise,
                           get a clean page and read the swap into it. */
-                       page_map = read_swap_cache(entry);
-                       if (page_map) {
-                               page = (unsigned long) page_address(page_map);
-                               read_lock(&tasklist_lock);
-                               for_each_task(p)
-                                       unswap_process(p->mm, entry, page
-                                                      /* , 0 */);
-                               read_unlock(&tasklist_lock);
-                               shm_unuse(entry, page);
-                               /* Now get rid of the extra reference to
-                                  the temporary page we've been using. */
-                               if (PageSwapCache(page_map))
-                                       delete_from_swap_cache(page_map);
-                               __free_page(page_map);
-       #ifdef DO_PROC
-                               stat_swap_force++;
-       #endif
-                       }
-                       else {
+                       page = read_swap_cache(entry);
+                       if (!page) {
                                swap_free(entry);
                                return -ENOMEM;
                        }
+                       read_lock(&tasklist_lock);
+                       for_each_task(p)
+                               unswap_process(p->mm, entry, page);
+                       read_unlock(&tasklist_lock);
+                       shm_unuse(entry, page);
+                       /* Now get rid of the extra reference to the
+                          temporary page we've been using. */
+                       if (PageSwapCache(page))
+                               delete_from_swap_cache(page);
+                       __free_page(page);
+       #ifdef DO_PROC
+                       stat_swap_force++;
+       #endif
                }
 
                DPRINTK( "unswap: map[i=%lu]=%u nr_swap=%u\n",
@@ -998,14 +821,7 @@ static void *get_stram_region( unsigned long n_pages )
        DPRINTK( "get_stram_region: region starts at %lu, has %lu free pages\n",
                         start, region_free );
 
-#if 0
-       err = ((total_free-region_free >= n_pages-region_free) ?
-                  unswap_by_move( map, max, start, n_pages ) :
-                  unswap_by_read( map, max, start, n_pages ));
-#else
        err = unswap_by_read(map, max, start, n_pages);
-#endif
-
        if (err)
                goto end;
 
@@ -1062,7 +878,7 @@ static void free_stram_region( unsigned long offset, unsigned long n_pages )
 
 
 /* is addr in some of the allocated regions? */
-static int in_some_region( unsigned long addr )
+static int in_some_region(void *addr)
 {
        BLOCK *p;
        
@@ -1164,17 +980,13 @@ static int stram_sizes[14] = {
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
 static int refcnt = 0;
 
-static void do_stram_request( void )
+static void do_stram_request(request_queue_t *q)
 {
-       unsigned long start, len;
-
-       while( !QUEUE_EMPTY ) {
-               if (MAJOR(CURRENT->rq_dev) != MAJOR_NR)
-                       panic("stram: request list destroyed");
-               if (CURRENT->bh) {
-                       if (!buffer_locked(CURRENT->bh))
-                               panic("stram: block not locked");
-               }
+       void *start;
+       unsigned long len;
+
+       while (1) {
+               INIT_REQUEST;
                
                start = swap_start + (CURRENT->sector << 9);
                len   = CURRENT->current_nr_sectors << 9;
@@ -1188,13 +1000,13 @@ static void do_stram_request( void )
                }
 
                if (CURRENT->cmd == READ) {
-                       memcpy( CURRENT->buffer, (char *)start, len );
+                       memcpy(CURRENT->buffer, start, len);
 #ifdef DO_PROC
                        stat_swap_read += N_PAGES(len);
 #endif
                }
                else {
-                       memcpy( (char *)start, CURRENT->buffer, len );
+                       memcpy(start, CURRENT->buffer, len);
 #ifdef DO_PROC
                        stat_swap_write += N_PAGES(len);
 #endif
@@ -1251,19 +1063,15 @@ int __init stram_device_init(void)
        return( -ENXIO );
     }
 
-    blk_dev[STRAM_MAJOR].request_fn = do_stram_request;
+    blk_init_queue(BLK_DEFAULT_QUEUE(STRAM_MAJOR), do_stram_request);
     blksize_size[STRAM_MAJOR] = stram_blocksizes;
        stram_sizes[STRAM_MINOR] = (swap_end - swap_start)/1024;
     blk_size[STRAM_MAJOR] = stram_sizes;
        register_disk(NULL, MKDEV(STRAM_MAJOR, STRAM_MINOR), 1, &stram_fops,
                        (swap_end-swap_start)>>9);
-       do_z2_request(); /* to avoid warning */
        return( 0 );
 }
 
-/* to avoid warning */
-static void do_z2_request( void ) { }
-
 #endif /* CONFIG_STRAM_SWAP */
 
 \f
@@ -1271,30 +1079,10 @@ static void do_z2_request( void ) { }
 /*                                                     Misc Utility Functions                                                  */
 /* ------------------------------------------------------------------------ */
 
-
-/* return log2 of #pages for size */
-static int get_gfp_order( unsigned long size )
+/* reserve a range of pages */
+static void reserve_region(void *start, void *end)
 {
-       int order;
-
-       size = N_PAGES( size + PAGE_SIZE -1 );
-       order = -1;
-       do {
-               size >>= 1;
-               order++;
-       } while (size);
-
-       return( order );
-}
-
-
-/* reserve a range of pages in mem_map[] */
-static void reserve_region( unsigned long addr, unsigned long end )
-{
-       mem_map_t *mapp = virt_to_page(addr);
-
-       for( ; addr < end; addr += PAGE_SIZE, ++mapp )
-               set_bit( PG_reserved, &mapp->flags );
+       reserve_bootmem (virt_to_phys(start), end - start);
 }
 
 
@@ -1328,11 +1116,11 @@ static BLOCK *add_region( void *addr, unsigned long size )
                printk( KERN_ERR "Out of memory for ST-RAM descriptor blocks\n" );
                return( NULL );
        }
-       n->start = (unsigned long)addr;
+       n->start = addr;
        n->size  = size;
 
        for( p = &alloc_list; *p; p = &((*p)->next) )
-               if ((*p)->start > (unsigned long)addr) break;
+               if ((*p)->start > addr) break;
        n->next = *p;
        *p = n;
 
@@ -1346,9 +1134,9 @@ static BLOCK *find_region( void *addr )
        BLOCK *p;
        
        for( p = alloc_list; p; p = p->next ) {
-               if (p->start == (unsigned long)addr)
+               if (p->start == addr)
                        return( p );
-               if (p->start > (unsigned long)addr)
+               if (p->start > addr)
                        break;
        }
        return( NULL );
@@ -1405,14 +1193,13 @@ int get_stram_list( char *buf )
                                ++used;
                }
                PRINT_PROC(
-                       "Total ST-RAM:      %8lu kB\n"
+                       "Total ST-RAM:      %8u kB\n"
                        "Total ST-RAM swap: %8lu kB\n"
                        "Free swap:         %8u kB\n"
                        "Used swap:         %8u kB\n"
                        "Allocated swap:    %8u kB\n"
                        "Swap Reads:        %8u\n"
                        "Swap Writes:       %8u\n"
-                       "Swap Moves:        %8u\n"
                        "Swap Forced Reads: %8u\n",
                        (stram_end - stram_start) >> 10,
                        (max-1) << (PAGE_SHIFT-10),
@@ -1421,17 +1208,13 @@ int get_stram_list( char *buf )
                        rsvd << (PAGE_SHIFT-10),
                        stat_swap_read,
                        stat_swap_write,
-                       stat_swap_move,
                        stat_swap_force );
        }
        else {
 #endif
                PRINT_PROC( "ST-RAM swapping disabled\n" );
-               PRINT_PROC(
-                       "Total ST-RAM:      %8lu kB\n"
-                       "Reserved ST-RAM:   %8lu kB\n",
-                       (stram_end - stram_start) >> 10,
-                       (rsvd_stram_end - rsvd_stram_beg) >> 10 );
+               PRINT_PROC("Total ST-RAM:      %8u kB\n",
+                          (stram_end - stram_start) >> 10);
 #ifdef CONFIG_STRAM_SWAP
        }
 #endif
@@ -1441,12 +1224,10 @@ int get_stram_list( char *buf )
                if (len + 50 >= PAGE_SIZE)
                        break;
                PRINT_PROC("0x%08lx-0x%08lx: %s (",
-                          virt_to_phys((void *)p->start),
-                          virt_to_phys((void *)p->start+p->size-1),
+                          virt_to_phys(p->start),
+                          virt_to_phys(p->start+p->size-1),
                           p->owner);
-               if (p->flags & BLOCK_STATIC)
-                       PRINT_PROC( "static)\n" );
-               else if (p->flags & BLOCK_GFP)
+               if (p->flags & BLOCK_GFP)
                        PRINT_PROC( "page-alloced)\n" );
                else if (p->flags & BLOCK_INSWAP)
                        PRINT_PROC( "in swap)\n" );
index 20bb8e1293669e001c9c7561c3b50b5cd9dce1f2..3e62e6fe17ba7c991b3b1387d3d7d31b9f86f675 100644 (file)
@@ -128,7 +128,7 @@ ENTRY(system_call)
        | save top of frame
        movel   %sp,%curptr@(TASK_THREAD+THREAD_ESP0)
 
-       btst    #PF_TRACESYS_BIT,%curptr@(TASK_FLAGS+PF_TRACESYS_OFF)
+       btst    #PT_TRACESYS_BIT,%curptr@(TASK_PTRACE+PT_TRACESYS_OFF)
        jne     do_trace
        cmpl    #NR_syscalls,%d0
        jcc     badsys
@@ -149,7 +149,7 @@ SYMBOL_NAME_LABEL(ret_from_exception)
        jeq     2f
 #endif
                                        | check for delayed trace
-       bclr    #PF_DTRACE_BIT,%curptr@(TASK_FLAGS+PF_DTRACE_OFF)
+       bclr    #PT_DTRACE_BIT,%curptr@(TASK_PTRACE+PT_DTRACE_OFF)
        jne     do_delayed_trace
 5:
        tstl    %curptr@(TASK_STATE)    | state
index 47cffcfa91979dbdfe1365b72428cfc441304129..817583a7d4c814112eb53eff09582e5012de124a 100644 (file)
@@ -24,6 +24,7 @@ int main(void)
        /* offsets into the task struct */
        DEFINE(TASK_STATE, offsetof(struct task_struct, state));
        DEFINE(TASK_FLAGS, offsetof(struct task_struct, flags));
+       DEFINE(TASK_PTRACE, offsetof(struct task_struct, ptrace));
        DEFINE(TASK_SIGPENDING, offsetof(struct task_struct, sigpending));
        DEFINE(TASK_NEEDRESCHED, offsetof(struct task_struct, need_resched));
        DEFINE(TASK_THREAD, offsetof(struct task_struct, thread));
index 0dd5870f2454632e835eacc77d3588bf31cf7a89..6b1f5f38621bb92f5f9c4cf6a5e317ce08690ed9 100644 (file)
@@ -97,10 +97,10 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
        ret = -EPERM;
        if (request == PTRACE_TRACEME) {
                /* are we already being traced? */
-               if (current->flags & PF_PTRACED)
+               if (current->ptrace & PT_PTRACED)
                        goto out;
                /* set the ptrace bit in the process flags. */
-               current->flags |= PF_PTRACED;
+               current->ptrace |= PT_PTRACED;
                ret = 0;
                goto out;
        }
@@ -126,9 +126,9 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
                    (current->gid != child->gid)) && !capable(CAP_SYS_PTRACE))
                        goto out;
                /* the same process cannot be attached many times */
-               if (child->flags & PF_PTRACED)
+               if (child->ptrace & PT_PTRACED)
                        goto out;
-               child->flags |= PF_PTRACED;
+               child->ptrace |= PT_PTRACED;
 
                write_lock_irqsave(&tasklist_lock, flags);
                if (child->p_pptr != current) {
@@ -143,7 +143,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
                goto out;
        }
        ret = -ESRCH;
-       if (!(child->flags & PF_PTRACED))
+       if (!(child->ptrace & PT_PTRACED))
                goto out;
        if (child->state != TASK_STOPPED) {
                if (request != PTRACE_KILL)
@@ -250,9 +250,9 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
                        if ((unsigned long) data > _NSIG)
                                goto out;
                        if (request == PTRACE_SYSCALL)
-                               child->flags |= PF_TRACESYS;
+                               child->ptrace |= PT_TRACESYS;
                        else
-                               child->flags &= ~PF_TRACESYS;
+                               child->ptrace &= ~PT_TRACESYS;
                        child->exit_code = data;
                        /* make sure the single step bit is not set. */
                        tmp = get_reg(child, PT_SR) & ~(TRACE_BITS << 16);
@@ -287,7 +287,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
                        ret = -EIO;
                        if ((unsigned long) data > _NSIG)
                                goto out;
-                       child->flags &= ~PF_TRACESYS;
+                       child->ptrace &= ~PT_TRACESYS;
                        tmp = get_reg(child, PT_SR) | (TRACE_BITS << 16);
                        put_reg(child, PT_SR, tmp);
 
@@ -304,7 +304,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
                        ret = -EIO;
                        if ((unsigned long) data > _NSIG)
                                goto out;
-                       child->flags &= ~(PF_PTRACED|PF_TRACESYS);
+                       child->ptrace &= ~(PT_PTRACED|PT_TRACESYS);
                        child->exit_code = data;
                        write_lock_irqsave(&tasklist_lock, flags);
                        REMOVE_LINKS(child);
@@ -384,8 +384,8 @@ out:
 asmlinkage void syscall_trace(void)
 {
        lock_kernel();
-       if ((current->flags & (PF_PTRACED|PF_TRACESYS))
-                       != (PF_PTRACED|PF_TRACESYS))
+       if ((current->ptrace & (PT_PTRACED|PT_TRACESYS))
+                       != (PT_PTRACED|PT_TRACESYS))
                goto out;
        current->exit_code = SIGTRAP;
        current->state = TASK_STOPPED;
index a2e3f47f1a3ec91215d38cf2b9e0107f1977096a..040f96d97e636e41f32c76eefe9629a2a5b86c82 100644 (file)
@@ -73,6 +73,8 @@ void (*mach_sched_init) (void (*handler)(int, void *, struct pt_regs *)) __initd
 int (*mach_keyb_init) (void) __initdata = NULL;
 int (*mach_kbdrate) (struct kbd_repeat *) = NULL;
 void (*mach_kbd_leds) (unsigned int) = NULL;
+int (*mach_kbd_translate)(unsigned char scancode, unsigned char *keycode, char raw_mode) = NULL;
+unsigned int SYSRQ_KEY;
 /* machine dependent irq functions */
 void (*mach_init_IRQ) (void) __initdata = NULL;
 void (*(*mach_default_handler)[]) (int, void *, struct pt_regs *) = NULL;
index fa13dc39037d04edd2d24a4c5451280c5b16a0f0..9d754f9b8e2be86354257ba7da8c62b346fb5f7a 100644 (file)
@@ -1043,7 +1043,7 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs)
                if (!signr)
                        break;
 
-               if ((current->flags & PF_PTRACED) && signr != SIGKILL) {
+               if ((current->ptrace & PT_PTRACED) && signr != SIGKILL) {
                        current->exit_code = signr;
                        current->state = TASK_STOPPED;
                        regs->sr &= ~PS_T;
index a4c0cea5588e43e215aeaf710d3f603babdb34d6..d5d6753cb1e4582efb0632d69975842a19984ee4 100644 (file)
@@ -35,7 +35,7 @@
 #include <asm/system.h>
 #include <asm/uaccess.h>
 #include <asm/traps.h>
-#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
 #include <asm/machdep.h>
 #include <asm/siginfo.h>
 
@@ -947,7 +947,7 @@ asmlinkage void trap_c(struct frame *fp)
        if (fp->ptregs.sr & PS_S) {
                if ((fp->ptregs.vector >> 2) == VEC_TRACE) {
                        /* traced a trapping instruction */
-                       current->flags |= PF_DTRACE;
+                       current->ptrace |= PT_DTRACE;
                } else
                        bad_super_trap(fp);
                return;
index a0486cf953248c6e9656f2c008758bf4046a494e..ef02d9bb98b91fa80776edb9388c2cfc9d524247 100644 (file)
@@ -61,10 +61,6 @@ void *mac_env;               /* Loaded by the boot asm */
 /* The phys. video addr. - might be bogus on some machines */
 unsigned long mac_orig_videoaddr;
 
-/* Mac specific keyboard functions */
-extern int mackbd_init_hw(void);
-extern void mackbd_leds(unsigned int leds);
-
 /* Mac specific timer functions */
 extern void mac_gettod (int *, int *, int *, int *, int *, int *);
 extern unsigned long mac_gettimeoffset (void);
@@ -91,20 +87,21 @@ extern void nubus_sweep_video(void);
 extern void mac_debug_init(void);
 extern void mac_debugging_long(int, long);
 
-#ifdef CONFIG_MAGIC_SYSRQ
-static char mac_sysrq_xlate[128] =
-       "\000sdfghzxcv\000bqwer"                                /* 0x00 - 0x0f */
-       "yt123465=97-80)o"                                      /* 0x10 - 0x1f */
-       "u(ip\rlj'k;\\,/nm."                                    /* 0x20 - 0x2f */
-       "\t `\000\033\000\000\000\000\000\000\000\000\000\000\000"      /* 0x30 - 0x3f */
-       "\000.\000*\000+\000\000\000\000\000/\r\000-\000"       /* 0x40 - 0x4f */
-       "\000\00001234567a89\000\000\000"                       /* 0x50 - 0x5f */
-       "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"  /* 0x60 - 0x6f */
-       "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"; /* 0x70 - 0x7f */
-#endif
-
 extern void (*kd_mksound)(unsigned int, unsigned int);
 
+extern int mackbd_init_hw(void);
+extern void mackbd_leds(unsigned int leds);
+extern int mackbd_translate(unsigned char keycode, unsigned char *keycodep, char raw_mode);
+
+extern void mac_hid_init_hw(void);
+extern int mac_hid_kbd_translate(unsigned char scancode, unsigned char *keycode, char raw_mode);
+
+#ifdef CONFIG_MAGIC_SYSRQ
+extern unsigned char mac_hid_kbd_sysrq_xlate[128];
+extern unsigned char pckbd_sysrq_xlate[128];
+extern unsigned char mackbd_sysrq_xlate[128];
+#endif /* CONFIG_MAGIC_SYSRQ */
+
 static void mac_get_model(char *str);
 
 void mac_bang(int irq, void *vector, struct pt_regs *p)
@@ -213,76 +210,93 @@ static void mac_cache_card_flush(int writeback)
 
 void __init config_mac(void)
 {
-
-    if (!MACH_IS_MAC) {
-      printk("ERROR: no Mac, but config_mac() called!! \n");
-    }
-    
-    mach_sched_init      = mac_sched_init;
-    mach_keyb_init       = mackbd_init_hw;
-    mach_kbd_leds        = mackbd_leds;
-    mach_init_IRQ        = mac_init_IRQ;
-    mach_request_irq     = mac_request_irq;
-    mach_free_irq        = mac_free_irq;
-    enable_irq           = mac_enable_irq;
-    disable_irq          = mac_disable_irq;
-    mach_get_model      = mac_get_model;
-    mach_default_handler = &mac_handlers;
-    mach_get_irq_list    = mac_get_irq_list;
-    mach_gettimeoffset   = mac_gettimeoffset;
-    mach_gettod          = mac_gettod;
-    mach_hwclk           = mac_hwclk;
-    mach_set_clock_mmss         = mac_set_clock_mmss;
+       if (!MACH_IS_MAC) {
+         printk("ERROR: no Mac, but config_mac() called!! \n");
+       }
+       
+#ifdef CONFIG_VT
+#ifdef CONFIG_INPUT_ADBHID
+       mach_keyb_init       = mac_hid_init_hw;
+       mach_kbd_translate   = mac_hid_kbd_translate;
+#ifdef CONFIG_MAGIC_SYSRQ
+#ifdef CONFIG_MAC_ADBKEYCODES
+       if (!keyboard_sends_linux_keycodes) {
+               mach_sysrq_xlate = mac_hid_kbd_sysrq_xlate;
+               SYSRQ_KEY = 0x69;
+       } else
+#endif /* CONFIG_MAC_ADBKEYCODES */
+       {
+               mach_sysrq_xlate = pckbd_sysrq_xlate;
+               SYSRQ_KEY = 0x54;
+       }
+#endif /* CONFIG_MAGIC_SYSRQ */
+#elif defined(CONFIG_ADB_KEYBOARD)
+       mach_keyb_init       = mackbd_init_hw;
+       mach_kbd_leds        = mackbd_leds;
+       mach_kbd_translate   = mackbd_translate;
+       mach_sysrq_xlate     = mackbd_sysrq_xlate;
+       SYSRQ_KEY = 0x69;
+#endif /* CONFIG_INPUT_ADBHID */
+#endif /* CONFIG_VT */
+
+       mach_sched_init      = mac_sched_init;
+       mach_init_IRQ        = mac_init_IRQ;
+       mach_request_irq     = mac_request_irq;
+       mach_free_irq        = mac_free_irq;
+       enable_irq           = mac_enable_irq;
+       disable_irq          = mac_disable_irq;
+       mach_get_model   = mac_get_model;
+       mach_default_handler = &mac_handlers;
+       mach_get_irq_list    = mac_get_irq_list;
+       mach_gettimeoffset   = mac_gettimeoffset;
+       mach_gettod          = mac_gettod;
+       mach_hwclk           = mac_hwclk;
+       mach_set_clock_mmss      = mac_set_clock_mmss;
 #if 0
-    mach_mksound         = mac_mksound;
+       mach_mksound         = mac_mksound;
 #endif
-    mach_reset           = mac_reset;
-    mach_halt            = mac_poweroff;
-    mach_power_off       = mac_poweroff;
-    conswitchp          = &dummy_con;
-    mach_max_dma_address = 0xffffffff;
+       mach_reset           = mac_reset;
+       mach_halt            = mac_poweroff;
+       mach_power_off       = mac_poweroff;
+       conswitchp               = &dummy_con;
+       mach_max_dma_address = 0xffffffff;
 #if 0
-    mach_debug_init     = mac_debug_init;
-#endif
-    kd_mksound          = mac_mksound;
-#ifdef CONFIG_MAGIC_SYSRQ
-    mach_sysrq_key = 114;         /* HELP */
-    mach_sysrq_shift_state = 8;   /* Alt */
-    mach_sysrq_shift_mask = 0xff; /* all modifiers except CapsLock */
-    mach_sysrq_xlate = mac_sysrq_xlate;
+       mach_debug_init  = mac_debug_init;
 #endif
+       kd_mksound               = mac_mksound;
 #ifdef CONFIG_HEARTBEAT
 #if 0
-    mach_heartbeat = mac_heartbeat;
-    mach_heartbeat_irq = IRQ_MAC_TIMER;
+       mach_heartbeat = mac_heartbeat;
+       mach_heartbeat_irq = IRQ_MAC_TIMER;
 #endif
 #endif
 
-    /*
-     * Determine hardware present
-     */
+       /*
+        * Determine hardware present
+        */
      
-    mac_identify();
-    mac_report_hardware();
+       mac_identify();
+       mac_report_hardware();
     
-    /* AFAIK only the IIci takes a cache card.  The IIfx has onboard
-       cache ... someone needs to figure out how to tell if it's on or
-       not. */
-    if (macintosh_config->ident == MAC_MODEL_IICI
-       || macintosh_config->ident == MAC_MODEL_IIFX) {
-       mach_l2_flush = mac_cache_card_flush;
-    }
+       /* AFAIK only the IIci takes a cache card.  The IIfx has onboard
+          cache ... someone needs to figure out how to tell if it's on or
+          not. */
+
+       if (macintosh_config->ident == MAC_MODEL_IICI
+           || macintosh_config->ident == MAC_MODEL_IIFX) {
+               mach_l2_flush = mac_cache_card_flush;
+       }
 #ifdef MAC_DEBUG_SOUND
-    /* goes on forever if timers broken */
-    mac_mksound(1000,10);
+       /* goes on forever if timers broken */
+       mac_mksound(1000,10);
 #endif
 
-    /*
-     * Check for machine specific fixups.
-     */
+       /*
+        * Check for machine specific fixups.
+        */
 
 #ifdef OLD_NUBUS_CODE
-    nubus_sweep_video();
+        nubus_sweep_video();
 #endif
 }      
 
index 3b70dfcc3457bbf481e3ddb2c60f91834170ca93..294765dd261cdade5d288fafae7db1fbed96d5eb 100644 (file)
@@ -90,6 +90,12 @@ static struct console q40_console_driver = {
 extern char *q40_mem_cptr; /*=(char *)0xff020000;*/
 static int _cpleft;
 
+int q40_kbd_translate(unsigned char keycode, unsigned char *keycodep, char raw_mode)
+{
+        *keycodep = keycode;
+        return 1;
+}
+
 static void q40_mem_console_write(struct console *co, const char *s,
                                  unsigned int count)
 {
@@ -199,6 +205,7 @@ void __init config_q40(void)
     mach_sched_init      = q40_sched_init;           /* ok */
     /*mach_kbdrate         = q40_kbdrate;*/          /* unneeded ?*/
     mach_keyb_init       = q40_keyb_init;            /* OK */
+    mach_kbd_translate   = q40_kbd_translate;
     mach_init_IRQ        = q40_init_IRQ;   
     mach_gettimeoffset   = q40_gettimeoffset; 
     mach_gettod         = q40_gettod;
index 1201b0ff489ec1e516114a586e4be5c3cb50a7fa..d92d79e01180b2c0949b1eacb2b38daa708a225e 100644 (file)
@@ -286,7 +286,6 @@ void __init pcibios_init(void)
     pci_scan_bus(0, &nile4_pci_ops, NULL);
     ddb5074_pci_fixup();
     pci_assign_unassigned_resources();
-    pci_set_bus_ranges();
     pcibios_fixup_irqs();
 }
 
index c2c0eb90fd4062cb5eb3cafa1d7f7ebcd0a092af..4586d8abe462d9676b320f8b2ea2c1815242b794 100644 (file)
@@ -796,7 +796,7 @@ static void amiga_mem_console_write(struct console *co, const char *s,
 
 static void amiga_savekmsg_init(void)
 {
-    savekmsg = (struct savekmsg *)amiga_chip_alloc(SAVEKMSG_MAXMEM);
+    savekmsg = (struct savekmsg *)amiga_chip_alloc(SAVEKMSG_MAXMEM, "Debug");
     savekmsg->magic1 = SAVEKMSG_MAGIC1;
     savekmsg->magic2 = SAVEKMSG_MAGIC2;
     savekmsg->magicptr = virt_to_phys(savekmsg);
index f2a102cf2412fb3eb39be01392210c8a6a699d19..53261f815866761cc3c3b219c0a2ff0ab5e51d18 100644 (file)
@@ -1785,7 +1785,7 @@ int acsi_init( void )
                return -EBUSY;
        }
        if (!(acsi_buffer =
-                 (char *)atari_stram_alloc( ACSI_BUFFER_SIZE, NULL, "acsi" ))) {
+                 (char *)atari_stram_alloc(ACSI_BUFFER_SIZE, "acsi"))) {
                printk( KERN_ERR "Unable to get ACSI ST-Ram buffer.\n" );
                devfs_unregister_blkdev( MAJOR_NR, "ad" );
                return -ENOMEM;
index 33dd5b8969b525e59c1b1d096c4844cc736b2891..96c5df3870291a24cab1482773c033dbc04a6a08 100644 (file)
@@ -1990,7 +1990,7 @@ int __init atari_floppy_init (void)
        SelectedDrive = -1;
        BufferDrive = -1;
 
-       DMABuffer = atari_stram_alloc( BUFFER_SIZE+512, NULL, "ataflop" );
+       DMABuffer = atari_stram_alloc(BUFFER_SIZE+512, "ataflop");
        if (!DMABuffer) {
                printk(KERN_ERR "atari_floppy_init: cannot get dma buffer\n");
                unregister_blkdev(MAJOR_NR, "fd");
index 73b8fecd21dec6be13174f87c28e29180c4f92d6..a81a4c0b34d2cc3f92a194e8df90caced28701ec 100644 (file)
@@ -12,6 +12,7 @@
  * Amiga support by Hamish Macdonald
  */
 
+#include <linux/config.h>
 #include <linux/types.h>
 #include <linux/sched.h>
 #include <linux/interrupt.h>
@@ -23,6 +24,7 @@
 #include <linux/timer.h>
 #include <linux/random.h>
 #include <linux/kernel.h>
+#include <linux/ioport.h>
 #include <linux/init.h>
 #include <linux/kbd_kern.h>
 
@@ -186,7 +188,6 @@ static void amikeyb_rep(unsigned long ignore)
 
     kbd_pt_regs = NULL;
 
-    init_timer(&amikeyb_rep_timer);
     amikeyb_rep_timer.expires = jiffies + key_repeat_rate;
     add_timer(&amikeyb_rep_timer);
     handle_scancode(rep_scancode, 1);
@@ -254,7 +255,6 @@ static void keyboard_interrupt(int irq, void *dummy, struct pt_regs *fp)
        } else {
            del_timer(&amikeyb_rep_timer);
            rep_scancode = keycode;
-           init_timer(&amikeyb_rep_timer);
            amikeyb_rep_timer.expires = jiffies + key_repeat_delay;
            add_timer(&amikeyb_rep_timer);
        }
@@ -300,6 +300,8 @@ int __init amiga_keyb_init(void)
 {
     if (!AMIGAHW_PRESENT(AMI_KEYBOARD))
         return -EIO;
+    if (!request_mem_region(CIAA_PHYSADDR-1+0xb00, 0x100, "amikeyb"))
+       return -EBUSY;
 
     /* setup key map */
     memcpy(key_maps[0], amiplain_map, sizeof(plain_map));
@@ -342,3 +344,16 @@ int amiga_kbdrate( struct kbd_repeat *k )
     
     return( 0 );
 }
+
+int amiga_kbd_translate(unsigned char keycode, unsigned char *keycodep, char raw_mode)
+{
+#ifdef CONFIG_MAGIC_SYSRQ
+        /* SHIFT+ALTGR+HELP pressed? */
+        if ((keycode == 0x5f) && ((shift_state & 0xff) == 3))
+                *keycodep = 0xff;
+        else
+#endif
+                *keycodep = keycode;
+        return 1;
+}
+
index a0e41b189130a0882f011c04d11d4e43d44c45d8..22c981b79aa1438ed826d3895830888be6dd39be 100644 (file)
 #include <linux/interrupt.h>
 #include <linux/tty.h>
 #include <linux/mm.h>
+#include <linux/keyboard.h>
 #include <linux/signal.h>
 #include <linux/ioport.h>
 #include <linux/init.h>
 #include <linux/kbd_ll.h>
+#include <linux/kbd_kern.h>
 #include <linux/delay.h>
 #include <linux/sysrq.h>
 #include <linux/random.h>
@@ -342,7 +344,6 @@ static void keyboard_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
        unsigned char status;
 
-       disable_keyboard();
        spin_lock(&kbd_controller_lock);
        kbd_pt_regs = regs;
 
@@ -378,8 +379,7 @@ static void keyboard_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 
                handle_scancode(scancode, ! keyup );
                keyup=0;
-               mark_bh(KEYBOARD_BH);
-
+               tasklet_schedule(&keyboard_tasklet);
              }
            else
              keyup=1;
@@ -387,20 +387,7 @@ static void keyboard_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 exit:
        spin_unlock(&kbd_controller_lock);
        master_outb(-1,KEYBOARD_UNLOCK_REG); /* keyb ints reenabled herewith */
-       enable_keyboard();
-}
-
-
-
-
-#ifdef CONFIG_MAGIC_SYSRQ
-int kbd_is_sysrq(unsigned char keycode)
-{
-       return( keycode == SYSRQ_KEY );
 }
-#endif /* CONFIG_MAGIC_SYSRQ */
-
-
 
 
 #define KBD_NO_DATA    (-1)    /* No data */
index 85da92470d621fb449b93c1e4b47d6a77911fe99..a4e34cb1f730c71c81d357551610bfa49e60be75 100644 (file)
@@ -3990,7 +3990,7 @@ pci_plx9050_fn(struct pci_dev *dev, struct pci_board *board, int enable)
        if (dev->vendor == PCI_VENDOR_ID_PANACOM)
                irq_config = 0x43;
        if ((dev->vendor == PCI_VENDOR_ID_PLX) &&
-           (dev->device == PCI_VENDOR_ID_PLX_ROMULUS)) {
+           (dev->device == PCI_DEVICE_ID_PLX_ROMULUS)) {
                /*
                 * As the megawolf cards have the int pins active
                 * high, and have 2 UART chips, both ints must be
@@ -4324,7 +4324,7 @@ static struct pci_board pci_boards[] __devinitdata = {
                SPCI_FL_BASE2, 8, 460800 },
        /* Megawolf Romulus PCI Serial Card, from Mike Hudson */
        /* (Exoray@isys.ca) */
-       {       PCI_VENDOR_ID_PLX, PCI_VENDOR_ID_PLX_ROMULUS,
+       {       PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_ROMULUS,
                0x10b5, 0x106a,
                SPCI_FL_BASE2, 4, 921600,
                0x20, 2, pci_plx9050_fn, 0x03 },
index 7ef6f645a2286e27c6cc16b08c5a28267f345492..4de01ad9c3010146e79390d6e006139986089459 100644 (file)
@@ -43,7 +43,7 @@
 #define BUDDHA_BASE2   0xa00
 #define BUDDHA_BASE3   0xc00
 
-static const u_int __init buddha_bases[CATWEASEL_NUM_HWIFS] = {
+static const u_int buddha_bases[CATWEASEL_NUM_HWIFS] __initdata = {
     BUDDHA_BASE1, BUDDHA_BASE2, BUDDHA_BASE3
 };
 
@@ -62,7 +62,7 @@ static const u_int __init buddha_bases[CATWEASEL_NUM_HWIFS] = {
 #define BUDDHA_STATUS  0x1e            /* see status-bits */
 #define BUDDHA_CONTROL 0x11a
 
-static int __init buddha_offsets[IDE_NR_PORTS] = {
+static int buddha_offsets[IDE_NR_PORTS] __initdata = {
     BUDDHA_DATA, BUDDHA_ERROR, BUDDHA_NSECTOR, BUDDHA_SECTOR, BUDDHA_LCYL,
     BUDDHA_HCYL, BUDDHA_SELECT, BUDDHA_STATUS, BUDDHA_CONTROL
 };
@@ -76,7 +76,7 @@ static int __init buddha_offsets[IDE_NR_PORTS] = {
 #define BUDDHA_IRQ2    0xf40           /* interrupt */
 #define BUDDHA_IRQ3    0xf80
 
-static const int __init buddha_irqports[CATWEASEL_NUM_HWIFS] = {
+static const int buddha_irqports[CATWEASEL_NUM_HWIFS] __initdata = {
     BUDDHA_IRQ1, BUDDHA_IRQ2, BUDDHA_IRQ3
 };
 
index 2011b6a266ff340a7939d9d165104d09b8e85519..5a5e8c04dc3f956420af27109f3c72c3ed373c7f 100644 (file)
 #include <linux/ide.h>
 #include <linux/init.h>
 
+#include <asm/setup.h>
 #include <asm/amigahw.h>
 #include <asm/amigaints.h>
+#include <asm/amigayle.h>
 
 
     /*
@@ -42,7 +44,7 @@
 #define GAYLE_STATUS   0x1e            /* see status-bits */
 #define GAYLE_CONTROL  0x101a
 
-static int __init gayle_offsets[IDE_NR_PORTS] = {
+static int gayle_offsets[IDE_NR_PORTS] __initdata = {
     GAYLE_DATA, GAYLE_ERROR, GAYLE_NSECTOR, GAYLE_SECTOR, GAYLE_LCYL,
     GAYLE_HCYL, GAYLE_SELECT, GAYLE_STATUS, -1, -1
 };
@@ -87,7 +89,7 @@ static int gayle_ack_intr_a4000(ide_hwif_t *hwif)
     unsigned char ch;
 
     ch = inb(hwif->io_ports[IDE_IRQ_OFFSET]);
-    if (!(ch & 0x80))
+    if (!(ch & GAYLE_IRQ_IDE))
        return 0;
     return 1;
 }
@@ -97,10 +99,10 @@ static int gayle_ack_intr_a1200(ide_hwif_t *hwif)
     unsigned char ch;
 
     ch = inb(hwif->io_ports[IDE_IRQ_OFFSET]);
-    if (!(ch & 0x80))
+    if (!(ch & GAYLE_IRQ_IDE))
        return 0;
     (void)inb(hwif->io_ports[IDE_STATUS_OFFSET]);
-    outb(0x7c | (ch & 0x03), hwif->io_ports[IDE_IRQ_OFFSET]);
+    outb(0x7c, hwif->io_ports[IDE_IRQ_OFFSET]);
     return 1;
 }
 
index 32205ccccf3fa31b044220f646a426edc7d4ad57..ece650b5d0f42cb29297ebe7e59464b9257f0987 100644 (file)
@@ -3241,6 +3241,12 @@ static void __init probe_for_hwifs (void)
                macide_init();
        }
 #endif /* CONFIG_BLK_DEV_MAC_IDE */
+#ifdef CONFIG_BLK_DEV_Q40IDE
+       {
+               extern void q40ide_init(void);
+               q40ide_init();
+       }
+#endif /* CONFIG_BLK_DEV_Q40IDE */
 #ifdef CONFIG_BLK_DEV_BUDDHA
        {
                extern void buddha_init(void);
index 41d4277d22bbd74e9cf776730e475e5e4121ef7a..4582d45563e0210211bf0330bedf1841713af571 100644 (file)
@@ -1,21 +1,16 @@
 /*
  *  linux/drivers/ide/q40ide.c -- Q40 I/O port IDE Driver
  *
- *     original file created 12 Jul 1997 by Geert Uytterhoeven
+ *     (c) Richard Zidlicky
  *
  *  This file is subject to the terms and conditions of the GNU General Public
  *  License.  See the file COPYING in the main directory of this archive for
  *  more details.
  *
- * RZ:
- *  almost identical with pcide.c, maybe we can merge it later. 
- *  Differences:
- *       max 2 HWIFS for now
- *       translate portaddresses to q40 native addresses (not yet...) instead rely on in/out[bw]
- *         address translation
  *
  */
 
+#include <linux/config.h>
 #include <linux/types.h>
 #include <linux/mm.h>
 #include <linux/interrupt.h>
@@ -28,7 +23,7 @@
      *  Bases of the IDE interfaces
      */
 
-#define PCIDE_NUM_HWIFS        2
+#define Q40IDE_NUM_HWIFS       2
 
 #define PCIDE_BASE1    0x1f0
 #define PCIDE_BASE2    0x170
@@ -37,7 +32,7 @@
 #define PCIDE_BASE5    0x1e0
 #define PCIDE_BASE6    0x160
 
-static const q40ide_ioreg_t pcide_bases[PCIDE_NUM_HWIFS] = {
+static const q40ide_ioreg_t pcide_bases[Q40IDE_NUM_HWIFS] = {
     PCIDE_BASE1, PCIDE_BASE2, /* PCIDE_BASE3, PCIDE_BASE4  , PCIDE_BASE5,
     PCIDE_BASE6 */
 };
@@ -58,7 +53,7 @@ static const int pcide_offsets[IDE_NR_PORTS] = {
     PCIDE_REG(CMD)
 };
 
-int q40ide_default_irq(q40ide_ioreg_t base)
+static int q40ide_default_irq(q40ide_ioreg_t base)
 {
            switch (base) { 
                    case 0x1f0: return 14;
@@ -69,41 +64,26 @@ int q40ide_default_irq(q40ide_ioreg_t base)
           }
 }
 
-void q40_ide_init_hwif_ports (q40ide_ioreg_t *p, q40ide_ioreg_t base, int *irq)
-{
-       q40ide_ioreg_t port = base;
-       int i = 8;
-
-       while (i--)
-               *p++ = port++;
-       *p++ = base + 0x206;
-       if (irq != NULL)
-               *irq = 0;
-}
 
 
     /*
-     *  Probe for PC IDE interfaces
+     *  Probe for Q40 IDE interfaces
      */
 
-int q40ide_probe_hwif(int index, ide_hwif_t *hwif)
+void q40ide_init(void)
 {
-    static int pcide_index[PCIDE_NUM_HWIFS] = { 0, };
     int i;
 
     if (!MACH_IS_Q40)
-      return 0;
-
-    for (i = 0; i < PCIDE_NUM_HWIFS; i++) {
-       if (!pcide_index[i]) {
-         /*printk("ide%d: Q40 IDE interface\n", index);*/
-           pcide_index[i] = index+1;
-       }
-       if (pcide_index[i] == index+1) {
-           ide_setup_ports(hwif,(ide_ioreg_t) pcide_bases[i], pcide_offsets, 0, /*q40_ack_intr???*/ NULL);
-           hwif->irq = ide_default_irq((ide_ioreg_t)pcide_bases[i]); /*q40_ide_irq[i];  */ /* 14 */
-           return 1;
-       }
+      return ;
+
+    for (i = 0; i < Q40IDE_NUM_HWIFS; i++) {
+       hw_regs_t hw;
+
+       ide_setup_ports(&hw,(ide_ioreg_t) pcide_bases[i], (int *)pcide_offsets, 
+                       pcide_bases[i]+0x206, 
+                       0, NULL, q40ide_default_irq(pcide_bases[i]));
+       ide_register_hw(&hw, NULL);
     }
-    return 0;
 }
+
index b01c1562f6e27176703168f82630e0c7f06d6121..64bfad320dc150bcf9eb1971cfa7bd8eb0f63769 100644 (file)
@@ -338,7 +338,7 @@ static int __init rtrack_init(void)
                return -EINVAL;
        }
 
-       if (check_region(io, 2)) 
+       if (request_region(io, 2, "rtrack")) 
        {
                printk(KERN_ERR "rtrack: port 0x%x already in use\n", io);
                return -EBUSY;
@@ -347,9 +347,10 @@ static int __init rtrack_init(void)
        rtrack_radio.priv=&rtrack_unit;
        
        if(video_register_device(&rtrack_radio, VFL_TYPE_RADIO)==-1)
+       {
+               release_region(io, 2);
                return -EINVAL;
-               
-       request_region(io, 2, "rtrack");
+       }
        printk(KERN_INFO "AIMSlab RadioTrack/RadioReveal card driver.\n");
 
        /* Set up the I/O locking */
index 06999d8065048e8aeac284be4cfa2738a7a1d14d..971b62fe17597d44a2c61a1135892c1ad2e45d11 100644 (file)
@@ -289,7 +289,7 @@ static int __init aztech_init(void)
                return -EINVAL;
        }
 
-       if (check_region(io, 2)) 
+       if (request_region(io, 2, "aztech")) 
        {
                printk(KERN_ERR "aztech: port 0x%x already in use\n", io);
                return -EBUSY;
@@ -299,9 +299,11 @@ static int __init aztech_init(void)
        aztech_radio.priv=&aztech_unit;
        
        if(video_register_device(&aztech_radio, VFL_TYPE_RADIO)==-1)
+       {
+               release_region(io,2);
                return -EINVAL;
+       }
                
-       request_region(io, 2, "aztech");
        printk(KERN_INFO "Aztech radio card driver v1.00/19990224 rkroll@exploits.org\n");
        /* mute card - prevents noisy bootups */
        outb (0, io);
index 15ec8515a76e0bd7e995fd26016bfc567039eb89..8ffe83a88f655492ddb44abac137c8f95818cb7a 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/videodev.h>    /* kernel radio structs         */
 #include <linux/config.h>      /* CONFIG_RADIO_CADET_PORT      */
 #include <linux/param.h>
+#include <linux/isapnp.h>
 
 #ifndef CONFIG_RADIO_CADET_PORT
 #define CONFIG_RADIO_CADET_PORT 0x330
@@ -44,16 +45,9 @@ static __u8 rdsin=0,rdsout=0,rdsstat=0;
 static unsigned char rdsbuf[RDS_BUFFER];
 static int cadet_lock=0;
 
-#ifndef MODULE
 static int cadet_probe(void);
-#endif
-
-#ifdef CONFIG_ISAPNP
-#include <linux/isapnp.h>
-
-struct pci_dev *dev;
+static struct pci_dev *dev;
 static int isapnp_cadet_probe(void);
-#endif
 
 /*
  * Signal Strength Threshold Values
@@ -551,7 +545,6 @@ static struct video_device cadet_radio=
        ioctl:          cadet_ioctl,
 };
 
-#ifdef CONFIG_ISAPNP
 static int isapnp_cadet_probe(void)
 {
        dev = isapnp_find_dev (NULL, ISAPNP_VENDOR('M','S','M'),
@@ -574,9 +567,7 @@ static int isapnp_cadet_probe(void)
 
        return io;
 }
-#endif         /* CONFIG_ISAPNP */
 
-#ifdef MODULE
 static int cadet_probe(void)
 {
         static int iovals[8]={0x330,0x332,0x334,0x336,0x338,0x33a,0x33c,0x33e};
@@ -584,30 +575,35 @@ static int cadet_probe(void)
 
        for(i=0;i<8;i++) {
                io=iovals[i];
-               if(check_region(io,2)>=0) {
+               if(request_region(io,2, "cadet-probe")>=0) {
                        cadet_setfreq(1410);
                        if(cadet_getfreq()==1410) {
+                               release_region(io, 2);
                                return io;
                        }
+                       release_region(io, 2);
                }
        }
        return -1;
 }
-#endif         /* MODULE */
 
 static int __init cadet_init(void)
 {
-#ifdef CONFIG_ISAPNP
-       io = isapnp_cadet_probe();
-
+       /*
+        *      If a probe was requested then probe ISAPnP first (safest)
+        */
        if (io < 0)
-               return (io);
-#else
-#ifndef MODULE         /* only probe on non-ISAPnP monolithic compiles */
-       io = cadet_probe ();
-#endif /* MODULE */
-#endif /* CONFIG_ISAPNP */
+               io = isapnp_cadet_probe();
+       /*
+        *      If that fails then probe unsafely if probe is requested
+        */
+       if(io < 0)
+               io = cadet_probe ();
 
+       /*
+        *      Else we bail out
+        */
+        
         if(io < 0) {
 #ifdef MODULE        
                printk(KERN_ERR "You must set an I/O address with io=0x???\n");
@@ -638,10 +634,8 @@ static void __exit cadet_cleanup_module(void)
        video_unregister_device(&cadet_radio);
        release_region(io,2);
 
-#ifdef CONFIG_ISAPNP
        if (dev)
                dev->deactivate(dev);
-#endif
 }
 
 module_init(cadet_init);
index 4bac8dcfe038ea1fc9f0d6aa6d9dd067346588f2..32351f653b8693af85fb05160f21470106cf3c19 100644 (file)
@@ -265,7 +265,7 @@ static int __init gemtek_init(void)
                return -EINVAL;
        }
 
-       if (check_region(io, 4)) 
+       if (request_region(io, 4, "gemtek")) 
        {
                printk(KERN_ERR "gemtek: port 0x%x already in use\n", io);
                return -EBUSY;
@@ -274,9 +274,10 @@ static int __init gemtek_init(void)
        gemtek_radio.priv=&gemtek_unit;
        
        if(video_register_device(&gemtek_radio, VFL_TYPE_RADIO)==-1)
+       {
+               release_region(io, 4);
                return -EINVAL;
-               
-       request_region(io, 4, "gemtek");
+       }
        printk(KERN_INFO "GemTek Radio Card driver.\n");
 
        spin_lock_init(&lock);
index ad479af3224b56d7918009f181ececa32dc6f0c3..d34315b2bd155c8545fb6e6025f73c8b647fff84 100644 (file)
@@ -230,7 +230,7 @@ static int __init rtrack2_init(void)
                printk(KERN_ERR "You must set an I/O address with io=0x20c or io=0x30c\n");
                return -EINVAL;
        }
-       if (check_region(io, 4)) 
+       if (request_region(io, 4, "rtrack2")) 
        {
                printk(KERN_ERR "rtrack2: port 0x%x already in use\n", io);
                return -EBUSY;
@@ -240,9 +240,11 @@ static int __init rtrack2_init(void)
 
        spin_lock_init(&lock);  
        if(video_register_device(&rtrack2_radio, VFL_TYPE_RADIO)==-1)
+       {
+               release_region(io, 4);
                return -EINVAL;
+       }
                
-       request_region(io, 4, "rtrack2");
        printk(KERN_INFO "AIMSlab Radiotrack II card driver.\n");
 
        /* mute card - prevents noisy bootups */
index 13a155316b372ba6b5ee46825950e1ba18dfa57d..e2fa902ff1110f28ee753368871a4653f7497677 100644 (file)
@@ -291,7 +291,7 @@ static int __init fmi_init(void)
                printk(KERN_ERR "You must set an I/O address with io=0x???\n");
                return -EINVAL;
        }
-       if (check_region(io, 2)) 
+       if (request_region(io, 2, "fmi")) 
        {
                printk(KERN_ERR "fmi: port 0x%x already in use\n", io);
                return -EBUSY;
@@ -306,9 +306,11 @@ static int __init fmi_init(void)
        init_MUTEX(&lock);
        
        if(video_register_device(&fmi_radio, VFL_TYPE_RADIO)==-1)
+       {
+               release_region(io, 2);
                return -EINVAL;
+       }
                
-       request_region(io, 2, "fmi");
        printk(KERN_INFO "SF16FMx radio card driver at 0x%x.\n", io);
        printk(KERN_INFO "(c) 1998 Petr Vandrovec, vandrove@vc.cvut.cz.\n");
        /* mute card - prevents noisy bootups */
index 28094e3cdeab34d335c3d269d4ca3edc886621d9..6f2ff8ee680dc47a80e280558188043364e7d5dd 100644 (file)
@@ -309,7 +309,7 @@ static int __init terratec_init(void)
                printk(KERN_ERR "You must set an I/O address with io=0x???\n");
                return -EINVAL;
        }
-       if (check_region(io, 2)) 
+       if (request_region(io, 2, "terratec")) 
        {
                printk(KERN_ERR "TerraTec: port 0x%x already in use\n", io);
                return -EBUSY;
@@ -320,9 +320,11 @@ static int __init terratec_init(void)
        spin_lock_init(&lock);
        
        if(video_register_device(&terratec_radio, VFL_TYPE_RADIO)==-1)
+       {
+               release_region(io,2);
                return -EINVAL;
+       }
                
-       request_region(io, 2, "terratec");
        printk(KERN_INFO "TERRATEC ActivRadio Standalone card driver.\n");
 
        /* mute card - prevents noisy bootups */
index 2fb6ed26d09574e4f72bc4ecb5cc8cf0b21341f2..cf4aa8b0013cf71a8d30b75f4289b9f761e87f3e 100644 (file)
@@ -300,14 +300,15 @@ static int __init trust_init(void)
                printk(KERN_ERR "You must set an I/O address with io=0x???\n");
                return -EINVAL;
        }
-       if(check_region(io, 2)) {
+       if(request_region(io, 2, "Trust FM Radio")) {
                printk(KERN_ERR "trust: port 0x%x already in use\n", io);
                return -EBUSY;
        }
        if(video_register_device(&trust_radio, VFL_TYPE_RADIO)==-1)
+       {
+               release_region(io, 2);
                return -EINVAL;
-               
-       request_region(io, 2, "Trust FM Radio");
+       }
 
        printk(KERN_INFO "Trust FM Radio card driver v1.0.\n");
 
index c550fd45ca7be8c3fbaf0ff854ec633442e3d921..d02d7f1bedffa897620d381e7d588b8fc4adc555 100644 (file)
@@ -350,7 +350,7 @@ static int __init typhoon_init(void)
 
        printk(KERN_INFO BANNER);
        io = typhoon_unit.iobase;
-       if (check_region(io, 8)) {
+       if (request_region(io, 8, "typhoon")) {
                printk(KERN_ERR "radio-typhoon: port 0x%x already in use\n",
                       typhoon_unit.iobase);
                return -EBUSY;
@@ -358,9 +358,10 @@ static int __init typhoon_init(void)
 
        typhoon_radio.priv = &typhoon_unit;
        if (video_register_device(&typhoon_radio, VFL_TYPE_RADIO) == -1)
+       {
+               release_region(io, 8);
                return -EINVAL;
-
-       request_region(typhoon_unit.iobase, 8, "typhoon");
+       }
        printk(KERN_INFO "radio-typhoon: port 0x%x.\n", typhoon_unit.iobase);
        printk(KERN_INFO "radio-typhoon: mute frequency is %lu kHz.\n",
               typhoon_unit.mutefreq);
index 940447bb90c6e129f2b6b9697c8b41aa0f6135f1..e9adaef7aa134a3fba9040dece33279df8b127a9 100644 (file)
@@ -355,20 +355,22 @@ static int __init zoltrix_init(void)
                printk(KERN_ERR "You must set an I/O address with io=0x???\n");
                return -EINVAL;
        }
-       if (check_region(io, 2)) {
-               printk(KERN_ERR "zoltrix: port 0x%x already in use\n", io);
-               return -EBUSY;
-       }
        if ((io != 0x20c) && (io != 0x30c)) {
                printk(KERN_ERR "zoltrix: invalid port, try 0x20c or 0x30c\n");
                return -ENXIO;
        }
+
        zoltrix_radio.priv = &zoltrix_unit;
+       if (request_region(io, 2, "zoltrix")) {
+               printk(KERN_ERR "zoltrix: port 0x%x already in use\n", io);
+               return -EBUSY;
+       }
 
        if (video_register_device(&zoltrix_radio, VFL_TYPE_RADIO) == -1)
+       {
+               release_region(io, 2);
                return -EINVAL;
-
-       request_region(io, 2, "zoltrix");
+       }
        printk(KERN_INFO "Zoltrix Radio Plus card driver.\n");
 
        init_MUTEX(&zoltrix_unit.lock);
index 92d71ba59003996ef73fdd856b26d5cd965fe49d..602adb7d568db8fe3381e562027ff87761f7e935 100644 (file)
@@ -865,12 +865,9 @@ static int qcam_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
                case VIDIOCGWIN:
                {
                        struct video_window vw;
-                       vw.x=0;
-                       vw.y=0;
+                       memset(&vw, 0, sizeof(vw));
                        vw.width=qcam->width/qcam->transfer_scale;
                        vw.height=qcam->height/qcam->transfer_scale;
-                       vw.chromakey=0;
-                       vw.flags=0;
                        if(copy_to_user(arg, &vw, sizeof(vw)))
                                return -EFAULT;
                        return 0;
index 2b0444582923db7d17d4604f6b228b87242ee1aa..642049de9d040b335042b2f15ed92aefd3cddcb7 100644 (file)
@@ -679,12 +679,9 @@ static int qcam_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
                case VIDIOCGWIN:
                {
                        struct video_window vw;
-                       vw.x=0;
-                       vw.y=0;
+                       memset(&vw, 0, sizeof(vw));
                        vw.width=qcam->width;
                        vw.height=qcam->height;
-                       vw.chromakey=0;
-                       vw.flags=0;
                        if(copy_to_user(arg, &vw, sizeof(vw)))
                                return -EFAULT;
                        return 0;
index 6ba26b3b91814e4143df0079141c4b2b25ac4ddc..298a317e2297310844bb9a548fa5af28f0ff4e21 100644 (file)
 
 static const char *version =
 "eepro100.c:v1.09j-t 9/29/99 Donald Becker http://cesdis.gsfc.nasa.gov/linux/drivers/eepro100.html\n"
-"eepro100.c: $Revision: 1.33 $ 2000/05/24 Modified by Andrey V. Savochkin <saw@saw.sw.com.sg> and others\n";
+"eepro100.c: $Revision: 1.35 $ 2000/11/17 Modified by Andrey V. Savochkin <saw@saw.sw.com.sg> and others\n";
 
 /* A few user-configurable values that apply to all boards.
    First set is undocumented and spelled per Intel recommendations. */
 
-static int congenb;            /* Enable congestion control in the DP83840. */
+static int congenb /* = 0 */; /* Enable congestion control in the DP83840. */
 static int txfifo = 8;         /* Tx FIFO threshold in 4 byte units, 0-15 */
 static int rxfifo = 8;         /* Rx FIFO threshold, default 32 bytes. */
 /* Tx/Rx DMA burst length, 0-127, 0 == no preemption, tx==128 -> disabled. */
 static int txdmacount = 128;
-static int rxdmacount;
+static int rxdmacount /* = 0 */;
 
 /* Set the copy breakpoint for the copy-only-tiny-buffer Rx method.
    Lower values use more memory, but are faster. */
+#if defined(__alpha__) || defined(__sparc__)
+static int rx_copybreak = 1518;
+#else
 static int rx_copybreak = 200;
+#endif
 
 /* Maximum events (Rx packets, etc.) to handle at each interrupt. */
 static int max_interrupt_work = 20;
@@ -136,26 +140,6 @@ static inline int null_set_power_state(struct pci_dev *dev, int state)
 }
 #endif /* CONFIG_EEPRO100_PM */
 
-#ifndef pci_resource_start
-#define pci_resource_start(p, n) (p)->resource[n].start
-#define pci_resource_len(p, n) ((p)->resource[n].end - (p)->resource[n].start)
-#endif
-
-/* Because of changes in this area the driver may not compile for kernels
-   2.3.43 - 2.3.47.  --SAW */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,43)
-#define netif_wake_queue(dev)  do { \
-                                                                       clear_bit(0, (void*)&dev->tbusy); \
-                                                                       mark_bh(NET_BH); \
-                                                               } while(0)
-#define netif_start_queue(dev) clear_bit(0, (void*)&dev->tbusy)
-#define netif_stop_queue(dev)  set_bit(0, (void*)&dev->tbusy)
-#define netif_running(dev)             dev->start
-#define netdevice_start(dev)   dev->start = 1
-#define netdevice_stop(dev)            dev->start = 0
-#define netif_set_tx_timeout(dev, tf, tm)
-#define dev_kfree_skb_irq(x)   dev_kfree_skb(x)
-#else
 #define netdevice_start(dev)
 #define netdevice_stop(dev)
 #define netif_set_tx_timeout(dev, tf, tm) \
@@ -163,51 +147,8 @@ static inline int null_set_power_state(struct pci_dev *dev, int state)
                                                                        (dev)->tx_timeout = (tf); \
                                                                        (dev)->watchdog_timeo = (tm); \
                                                                } while(0)
-#endif
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,47)
 #define netif_device_attach(dev) netif_start_queue(dev)
 #define netif_device_detach(dev) netif_stop_queue(dev)
-#endif
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,43)
-typedef u32 dma_addr_t;
-static void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size,
-                                                                 dma_addr_t *dma_handle)
-{
-       void *ret;
-       ret = kmalloc(size, GFP_ATOMIC);
-       if (ret != NULL) {
-               *dma_handle = virt_to_bus(ret);
-       }
-       return ret;
-}
-
-void pci_free_consistent(struct pci_dev *hwdev, size_t size,
-                                                void *vaddr, dma_addr_t dma_handle)
-{
-       kfree(vaddr);
-}
-
-#define PCI_DMA_FROMDEVICE 0
-#define PCI_DMA_TODEVICE 0
-
-extern inline dma_addr_t pci_map_single(struct pci_dev *hwdev, void *ptr,
-                                                                               size_t size, int direction)
-{
-       return virt_to_bus(ptr);
-}
-
-extern inline void pci_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr,
-                                                                       size_t size, int direction)
-{
-}
-
-extern inline void pci_dma_sync_single(struct pci_dev *hwdev,
-                                      dma_addr_t dma_handle,
-                                      size_t size, int direction)
-{
-}
-#endif
 
 #ifndef PCI_DEVICE_ID_INTEL_ID1029
 #define PCI_DEVICE_ID_INTEL_ID1029 0x1029
@@ -450,6 +391,7 @@ enum RxFD_bits {
        TxUnderrun=0x1000,  StatusComplete=0x8000,
 };
 
+#define CONFIG_DATA_SIZE 22
 struct TxFD {                                  /* Transmit frame descriptor set. */
        s32 status;
        u32 link;                                       /* void * */
@@ -461,6 +403,8 @@ struct TxFD {                                       /* Transmit frame descriptor set. */
        s32 tx_buf_size0;                       /* Length of Tx frame. */
        u32 tx_buf_addr1;                       /* void *, frame to be transmitted.  */
        s32 tx_buf_size1;                       /* Length of Tx frame. */
+       /* the structure must have space for at least CONFIG_DATA_SIZE starting
+        * from tx_desc_addr field */
 };
 
 /* Multicast filter setting block.  --SAW */
@@ -546,12 +490,12 @@ struct speedo_private {
 /* The parameters for a CmdConfigure operation.
    There are so many options that it would be difficult to document each bit.
    We mostly use the default or recommended settings. */
-const char i82557_config_cmd[22] = {
+const char i82557_config_cmd[CONFIG_DATA_SIZE] = {
        22, 0x08, 0, 0,  0, 0, 0x32, 0x03,  1, /* 1=Use MII  0=Use AUI */
        0, 0x2E, 0,  0x60, 0,
        0xf2, 0x48,   0, 0x40, 0xf2, 0x80,              /* 0x40=Force full-duplex */
        0x3f, 0x05, };
-const char i82558_config_cmd[22] = {
+const char i82558_config_cmd[CONFIG_DATA_SIZE] = {
        22, 0x08, 0, 1,  0, 0, 0x22, 0x03,  1, /* 1=Use MII  0=Use AUI */
        0, 0x2E, 0,  0x60, 0x08, 0x88,
        0x68, 0, 0x40, 0xf2, 0x84,              /* Disable FC */
@@ -571,11 +515,10 @@ static const char is_mii[] = { 0, 1, 1, 0, 1, 1, 0, 1 };
 static int eepro100_init_one(struct pci_dev *pdev,
                const struct pci_device_id *ent);
 static void eepro100_remove_one (struct pci_dev *pdev);
-
 #ifdef CONFIG_EEPRO100_PM
 static void eepro100_suspend (struct pci_dev *pdev);
 static void eepro100_resume (struct pci_dev *pdev);
-#endif /* CONFIG_EEPRO100_PM */
+#endif
 
 static int do_eeprom_cmd(long ioaddr, int cmd, int cmd_len);
 static int mdio_read(long ioaddr, int phy_id, int location);
@@ -611,9 +554,9 @@ static int __devinit eepro100_init_one (struct pci_dev *pdev,
        unsigned long ioaddr;
        int irq;
        int acpi_idle_state = 0, pm;
-       static int cards_found;
+       static int cards_found /* = 0 */;
 
-       static int did_version;                 /* Already printed version info. */
+       static int did_version /* = 0 */;               /* Already printed version info. */
        if (speedo_debug > 0  &&  did_version++ == 0)
                printk(version);
 
@@ -755,6 +698,7 @@ static int speedo_found1(struct pci_dev *pdev,
           This takes less than 10usec and will easily finish before the next
           action. */
        outl(PortReset, ioaddr + SCBPort);
+       udelay(10);
 
        if (eeprom[3] & 0x0100)
                product = "OEM i82557/i82558 10/100 Ethernet";
@@ -841,6 +785,7 @@ static int speedo_found1(struct pci_dev *pdev,
 #endif  /* kernel_bloat */
 
        outl(PortReset, ioaddr + SCBPort);
+       udelay(10);
 
        /* Return the chip to its original power state. */
        pci_set_power_state(pdev, acpi_idle_state);
@@ -856,7 +801,8 @@ static int speedo_found1(struct pci_dev *pdev,
        sp->tx_ring = tx_ring_space;
        sp->tx_ring_dma = tx_ring_dma;
        sp->lstats = (struct speedo_stats *)(sp->tx_ring + TX_RING_SIZE);
-       sp->lstats_dma = TX_RING_ELEM_DMA(sp, TX_RING_SIZE);
+       sp->lstats_dma = cpu_to_le32(TX_RING_ELEM_DMA(sp, TX_RING_SIZE));
+       init_timer(&sp->timer); /* used in ioctl() */
 
        sp->full_duplex = option >= 0 && (option & 0x10) ? 1 : 0;
        if (card_idx >= 0) {
@@ -921,7 +867,7 @@ static int do_eeprom_cmd(long ioaddr, int cmd, int cmd_len)
        io_outw(EE_ENB, ee_addr); udelay(2);
 
        /* Terminate the EEPROM access. */
-       io_outw(EE_ENB & ~EE_CS, ee_addr); udelay(4);
+       io_outw(EE_ENB & ~EE_CS, ee_addr);
        return retval;
 }
 
@@ -960,6 +906,7 @@ speedo_open(struct net_device *dev)
 {
        struct speedo_private *sp = (struct speedo_private *)dev->priv;
        long ioaddr = dev->base_addr;
+       int retval;
 
        if (speedo_debug > 1)
                printk(KERN_DEBUG "%s: speedo_open() irq %d.\n", dev->name, dev->irq);
@@ -977,9 +924,10 @@ speedo_open(struct net_device *dev)
        sp->in_interrupt = 0;
 
        /* .. we can safely take handler calls during init. */
-       if (request_irq(dev->irq, &speedo_interrupt, SA_SHIRQ, dev->name, dev)) {
+       retval = request_irq(dev->irq, &speedo_interrupt, SA_SHIRQ, dev->name, dev);
+       if (retval) {
                MOD_DEC_USE_COUNT;
-               return -EBUSY;
+               return retval;
        }
 
        dev->if_port = sp->default_port;
@@ -1030,7 +978,6 @@ speedo_open(struct net_device *dev)
           to an alternate media type
           2) to monitor Rx activity, and restart the Rx process if the receiver
           hangs. */
-       init_timer(&sp->timer);
        sp->timer.expires = RUN_AT((24*HZ)/10);                         /* 2.4 sec. */
        sp->timer.data = (unsigned long)dev;
        sp->timer.function = &speedo_timer;                                     /* timer handler */
@@ -1055,29 +1002,32 @@ static void speedo_resume(struct net_device *dev)
        /* Set the segment registers to '0'. */
        wait_for_cmd_done(ioaddr + SCBCmd);
        outl(0, ioaddr + SCBPointer);
+       inl(ioaddr + SCBPointer); /* XXX */
        outb(RxAddrLoad, ioaddr + SCBCmd);
        wait_for_cmd_done(ioaddr + SCBCmd);
        outb(CUCmdBase, ioaddr + SCBCmd);
-       wait_for_cmd_done(ioaddr + SCBCmd);
 
        /* Load the statistics block and rx ring addresses. */
+       wait_for_cmd_done(ioaddr + SCBCmd);
        outl(sp->lstats_dma, ioaddr + SCBPointer);
+       inl(ioaddr + SCBPointer); /* XXX */
        outb(CUStatsAddr, ioaddr + SCBCmd);
        sp->lstats->done_marker = 0;
-       wait_for_cmd_done(ioaddr + SCBCmd);
 
        if (sp->rx_ringp[sp->cur_rx % RX_RING_SIZE] == NULL) {
                if (speedo_debug > 2)
                        printk(KERN_DEBUG "%s: NULL cur_rx in speedo_resume().\n",
                                        dev->name);
        } else {
+               wait_for_cmd_done(ioaddr + SCBCmd);
                outl(sp->rx_ring_dma[sp->cur_rx % RX_RING_SIZE],
                         ioaddr + SCBPointer);
                outb(RxStart, ioaddr + SCBCmd);
-               wait_for_cmd_done(ioaddr + SCBCmd);
        }
 
+       wait_for_cmd_done(ioaddr + SCBCmd);
        outb(CUDumpStats, ioaddr + SCBCmd);
+       udelay(30);
 
        /* Fill the first command with our physical address. */
        {
@@ -1143,14 +1093,19 @@ static void speedo_timer(unsigned long data)
                /* We haven't received a packet in a Long Time.  We might have been
                   bitten by the receiver hang bug.  This can be cleared by sending
                   a set multicast list command. */
-               if (speedo_debug > 2)
+               if (speedo_debug > 3)
                        printk(KERN_DEBUG "%s: Sending a multicast list set command"
-                                  " from a timer routine.\n", dev->name);
+                                  " from a timer routine,"
+                                  " m=%d, j=%ld, l=%ld.\n",
+                                  dev->name, sp->rx_mode, jiffies, sp->last_rx_time);
                set_rx_mode(dev);
        }
        /* We must continue to monitor the media. */
        sp->timer.expires = RUN_AT(2*HZ);                       /* 2.0 sec. */
        add_timer(&sp->timer);
+#if defined(timer_exit)
+       timer_exit(&sp->timer);
+#endif
 }
 
 static void speedo_show_state(struct net_device *dev)
@@ -1182,13 +1137,15 @@ static void speedo_show_state(struct net_device *dev)
                                           (unsigned)sp->rx_ringp[i]->status : 0);
 
 #if 0
-       long ioaddr = dev->base_addr;
-       int phy_num = sp->phy[0] & 0x1f;
-       for (i = 0; i < 16; i++) {
-               /* FIXME: what does it mean?  --SAW */
-               if (i == 6) i = 21;
-               printk(KERN_DEBUG "%s:  PHY index %d register %d is %4.4x.\n",
-                          dev->name, phy_num, i, mdio_read(ioaddr, phy_num, i));
+       {
+               long ioaddr = dev->base_addr;
+               int phy_num = sp->phy[0] & 0x1f;
+               for (i = 0; i < 16; i++) {
+                       /* FIXME: what does it mean?  --SAW */
+                       if (i == 6) i = 21;
+                       printk(KERN_DEBUG "%s:  PHY index %d register %d is %4.4x.\n",
+                                  dev->name, phy_num, i, mdio_read(ioaddr, phy_num, i));
+               }
        }
 #endif
 
@@ -1200,6 +1157,7 @@ speedo_init_rx_ring(struct net_device *dev)
 {
        struct speedo_private *sp = (struct speedo_private *)dev->priv;
        struct RxFD *rxf, *last_rxf = NULL;
+       dma_addr_t last_rxf_dma = 0 /* to shut up the compiler */;
        int i;
 
        sp->cur_rx = 0;
@@ -1214,26 +1172,31 @@ speedo_init_rx_ring(struct net_device *dev)
                rxf = (struct RxFD *)skb->tail;
                sp->rx_ringp[i] = rxf;
                sp->rx_ring_dma[i] =
-                       pci_map_single(sp->pdev, rxf, PKT_BUF_SZ + sizeof(struct RxFD), PCI_DMA_FROMDEVICE);
+                       pci_map_single(sp->pdev, rxf,
+                                       PKT_BUF_SZ + sizeof(struct RxFD), PCI_DMA_BIDIRECTIONAL);
                skb_reserve(skb, sizeof(struct RxFD));
                if (last_rxf) {
                        last_rxf->link = cpu_to_le32(sp->rx_ring_dma[i]);
-                       pci_dma_sync_single(sp->pdev, sp->rx_ring_dma[i-1], sizeof(struct RxFD), PCI_DMA_TODEVICE);
+                       pci_dma_sync_single(sp->pdev, last_rxf_dma,
+                                       sizeof(struct RxFD), PCI_DMA_TODEVICE);
                }
                last_rxf = rxf;
+               last_rxf_dma = sp->rx_ring_dma[i];
                rxf->status = cpu_to_le32(0x00000001);  /* '1' is flag value only. */
                rxf->link = 0;                                          /* None yet. */
                /* This field unused by i82557. */
                rxf->rx_buf_addr = 0xffffffff;
                rxf->count = cpu_to_le32(PKT_BUF_SZ << 16);
-               pci_dma_sync_single(sp->pdev, sp->rx_ring_dma[i], sizeof(struct RxFD), PCI_DMA_TODEVICE);
+               pci_dma_sync_single(sp->pdev, sp->rx_ring_dma[i],
+                               sizeof(struct RxFD), PCI_DMA_TODEVICE);
        }
        sp->dirty_rx = (unsigned int)(i - RX_RING_SIZE);
        /* Mark the last entry as end-of-list. */
        last_rxf->status = cpu_to_le32(0xC0000002);     /* '2' is flag value only. */
-       pci_dma_sync_single(sp->pdev, sp->rx_ring_dma[RX_RING_SIZE-1], sizeof(struct RxFD), PCI_DMA_TODEVICE);
+       pci_dma_sync_single(sp->pdev, sp->rx_ring_dma[RX_RING_SIZE-1],
+                       sizeof(struct RxFD), PCI_DMA_TODEVICE);
        sp->last_rxf = last_rxf;
-       sp->last_rxf_dma = sp->rx_ring_dma[RX_RING_SIZE-1];
+       sp->last_rxf_dma = last_rxf_dma;
 }
 
 static void speedo_purge_tx(struct net_device *dev)
@@ -1304,9 +1267,6 @@ static void speedo_tx_timeout(struct net_device *dev)
                   sp->dirty_tx, sp->cur_tx,
                   sp->tx_ring[sp->dirty_tx % TX_RING_SIZE].status);
 
-       /* Trigger a stats dump to give time before the reset. */
-       speedo_get_stats(dev);
-
        speedo_show_state(dev);
 #if 0
        if ((status & 0x00C0) != 0x0080
@@ -1322,14 +1282,7 @@ static void speedo_tx_timeout(struct net_device *dev)
 #else
        {
 #endif
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,43)
-               start_bh_atomic();
-               /* Ensure that timer routine doesn't run! */
-               del_timer(&sp->timer);
-               end_bh_atomic();
-#else /* LINUX_VERSION_CODE */
                del_timer_sync(&sp->timer);
-#endif /* LINUX_VERSION_CODE */
                /* Reset the Tx and Rx units. */
                outl(PortReset, ioaddr + SCBPort);
                /* We may get spurious interrupts here.  But I don't think that they
@@ -1367,25 +1320,6 @@ speedo_start_xmit(struct sk_buff *skb, struct net_device *dev)
        long ioaddr = dev->base_addr;
        int entry;
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,43)
-       if (test_bit(0, (void*)&dev->tbusy) != 0) {
-               int tickssofar = jiffies - dev->trans_start;
-               if (tickssofar < TX_TIMEOUT - 2)
-                       return 1;
-               if (tickssofar < TX_TIMEOUT) {
-                       /* Reap sent packets from the full Tx queue. */
-                       unsigned long flags;
-                       spin_lock_irqsave(&sp->lock, flags);
-                       wait_for_cmd_done(ioaddr + SCBCmd);
-                       outw(SCBTriggerIntr, ioaddr + SCBCmd);
-                       spin_unlock_irqrestore(&sp->lock, flags);
-                       return 1;
-               }
-               speedo_tx_timeout(dev);
-               return 1;
-       }
-#endif
-
        {       /* Prevent interrupts from changing the Tx ring from underneath us. */
                unsigned long flags;
 
@@ -1636,7 +1570,7 @@ static void speedo_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
                        /* Clear all interrupt sources. */
                        /* Will change from 0xfc00 to 0xff00 when we start handling
                           FCP and ER interrupts --Dragan */
-                       outl(0xfc00, ioaddr + SCBStatus);
+                       outw(0xfc00, ioaddr + SCBStatus);
                        break;
                }
        } while (1);
@@ -1668,7 +1602,8 @@ static inline struct RxFD *speedo_rx_alloc(struct net_device *dev, int entry)
        skb->dev = dev;
        skb_reserve(skb, sizeof(struct RxFD));
        rxf->rx_buf_addr = 0xffffffff;
-       pci_dma_sync_single(sp->pdev, sp->rx_ring_dma[entry], sizeof(struct RxFD), PCI_DMA_TODEVICE);
+       pci_dma_sync_single(sp->pdev, sp->rx_ring_dma[entry],
+                       sizeof(struct RxFD), PCI_DMA_TODEVICE);
        return rxf;
 }
 
@@ -1681,7 +1616,8 @@ static inline void speedo_rx_link(struct net_device *dev, int entry,
        rxf->count = cpu_to_le32(PKT_BUF_SZ << 16);
        sp->last_rxf->link = cpu_to_le32(rxf_dma);
        sp->last_rxf->status &= cpu_to_le32(~0xC0000000);
-       pci_dma_sync_single(sp->pdev, sp->last_rxf_dma, sizeof(struct RxFD), PCI_DMA_TODEVICE);
+       pci_dma_sync_single(sp->pdev, sp->last_rxf_dma,
+                       sizeof(struct RxFD), PCI_DMA_TODEVICE);
        sp->last_rxf = rxf;
        sp->last_rxf_dma = rxf_dma;
 }
@@ -1742,7 +1678,6 @@ speedo_rx(struct net_device *dev)
 {
        struct speedo_private *sp = (struct speedo_private *)dev->priv;
        int entry = sp->cur_rx % RX_RING_SIZE;
-       int status;
        int rx_work_limit = sp->dirty_rx + RX_RING_SIZE - sp->cur_rx;
        int alloc_ok = 1;
 
@@ -1750,16 +1685,16 @@ speedo_rx(struct net_device *dev)
                printk(KERN_DEBUG " In speedo_rx().\n");
        /* If we own the next entry, it's a new packet. Send it up. */
        while (sp->rx_ringp[entry] != NULL) {
+               int status;
                int pkt_len;
 
                pci_dma_sync_single(sp->pdev, sp->rx_ring_dma[entry],
                        sizeof(struct RxFD), PCI_DMA_FROMDEVICE);
+               status = le32_to_cpu(sp->rx_ringp[entry]->status);
+               pkt_len = le32_to_cpu(sp->rx_ringp[entry]->count) & 0x3fff;
 
-               if(!((status = le32_to_cpu(sp->rx_ringp[entry]->status)) & RxComplete)) {
+               if (!(status & RxComplete))
                        break;
-               }
-
-               pkt_len = le32_to_cpu(sp->rx_ringp[entry]->count) & 0x3fff;
 
                if (--rx_work_limit < 0)
                        break;
@@ -1812,7 +1747,6 @@ speedo_rx(struct net_device *dev)
                                           pkt_len);
 #endif
                        } else {
-                               void *temp;
                                /* Pass up the already-filled skbuff. */
                                skb = sp->rx_skbuff[entry];
                                if (skb == NULL) {
@@ -1821,7 +1755,7 @@ speedo_rx(struct net_device *dev)
                                        break;
                                }
                                sp->rx_skbuff[entry] = NULL;
-                               temp = skb_put(skb, pkt_len);
+                               skb_put(skb, pkt_len);
                                sp->rx_ringp[entry] = NULL;
                                pci_unmap_single(sp->pdev, sp->rx_ring_dma[entry],
                                                PKT_BUF_SZ + sizeof(struct RxFD), PCI_DMA_FROMDEVICE);
@@ -1862,7 +1796,7 @@ speedo_close(struct net_device *dev)
                           dev->name, inw(ioaddr + SCBStatus));
 
        /* Shut off the media monitoring timer. */
-       del_timer(&sp->timer);
+       del_timer_sync(&sp->timer);
 
        /* Shutting down the chip nicely fails to disable flow control. So.. */
        outl(PortPartialReset, ioaddr + SCBPort);
@@ -1922,10 +1856,6 @@ speedo_close(struct net_device *dev)
    update the stats with the previous dump results, and then trigger a
    new dump.
 
-   These problems are mitigated by the current /proc implementation, which
-   calls this routine first to judge the output length, and then to emit the
-   output.
-
    Oh, and incoming frames are dropped while executing dump-stats!
    */
 static struct net_device_stats *
@@ -1968,6 +1898,7 @@ static int speedo_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
        u16 *data = (u16 *)&rq->ifr_data;
        int phy = sp->phy[0] & 0x1f;
        int saved_acpi;
+       int t;
 
     switch(cmd) {
        case SIOCDEVPRIVATE:            /* Get the address of the PHY in use. */
@@ -1978,30 +1909,20 @@ static int speedo_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
                   They are currently serialized only with MDIO access from the
                   timer routine.  2000/05/09 SAW */
                saved_acpi = pci_set_power_state(sp->pdev, 0);
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,43)
-               start_bh_atomic();
+               t = del_timer_sync(&sp->timer);
                data[3] = mdio_read(ioaddr, data[0], data[1]);
-               end_bh_atomic();
-#else /* LINUX_VERSION_CODE */
-               del_timer_sync(&sp->timer);
-               data[3] = mdio_read(ioaddr, data[0], data[1]);
-               add_timer(&sp->timer); /* may be set to the past  --SAW */
-#endif /* LINUX_VERSION_CODE */
+               if (t)
+                       add_timer(&sp->timer); /* may be set to the past  --SAW */
                pci_set_power_state(sp->pdev, saved_acpi);
                return 0;
        case SIOCDEVPRIVATE+2:          /* Write the specified MII register */
                if (!capable(CAP_NET_ADMIN))
                        return -EPERM;
                saved_acpi = pci_set_power_state(sp->pdev, 0);
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,43)
-               start_bh_atomic();
-               mdio_write(ioaddr, data[0], data[1], data[2]);
-               end_bh_atomic();
-#else /* LINUX_VERSION_CODE */
-               del_timer_sync(&sp->timer);
+               t = del_timer_sync(&sp->timer);
                mdio_write(ioaddr, data[0], data[1], data[2]);
-               add_timer(&sp->timer); /* may be set to the past  --SAW */
-#endif /* LINUX_VERSION_CODE */
+               if (t)
+                       add_timer(&sp->timer); /* may be set to the past  --SAW */
                pci_set_power_state(sp->pdev, saved_acpi);
                return 0;
        default:
@@ -2060,7 +1981,7 @@ static void set_rx_mode(struct net_device *dev)
                        cpu_to_le32(TX_RING_ELEM_DMA(sp, (entry + 1) % TX_RING_SIZE));
                config_cmd_data = (void *)&sp->tx_ring[entry].tx_desc_addr;
                /* Construct a full CmdConfig frame. */
-               memcpy(config_cmd_data, i82558_config_cmd, sizeof(i82558_config_cmd));
+               memcpy(config_cmd_data, i82558_config_cmd, CONFIG_DATA_SIZE);
                config_cmd_data[1] = (txfifo << 4) | rxfifo;
                config_cmd_data[4] = rxdmacount;
                config_cmd_data[5] = txdmacount + 0x80;
@@ -2186,7 +2107,8 @@ static void set_rx_mode(struct net_device *dev)
                mc_setup_frm->link =
                        cpu_to_le32(TX_RING_ELEM_DMA(sp, (entry + 1) % TX_RING_SIZE));
 
-               pci_dma_sync_single(sp->pdev, mc_blk->frame_dma, mc_blk->len, PCI_DMA_TODEVICE);
+               pci_dma_sync_single(sp->pdev, mc_blk->frame_dma,
+                               mc_blk->len, PCI_DMA_TODEVICE);
 
                wait_for_cmd_done(ioaddr + SCBCmd);
                clear_suspend(last_cmd);
@@ -2207,9 +2129,7 @@ static void set_rx_mode(struct net_device *dev)
        sp->rx_mode = new_rx_mode;
 }
 \f
-
 #ifdef CONFIG_EEPRO100_PM
-
 static void eepro100_suspend(struct pci_dev *pdev)
 {
        struct net_device *dev = pdev->driver_data;
@@ -2241,7 +2161,6 @@ static void eepro100_resume(struct pci_dev *pdev)
        sp->flow_ctrl = sp->partner = 0;
        set_rx_mode(dev);
 }
-
 #endif /* CONFIG_EEPRO100_PM */
 
 static void __devexit eepro100_remove_one (struct pci_dev *pdev)
@@ -2284,7 +2203,6 @@ static struct pci_driver eepro100_driver = {
        id_table:       eepro100_pci_tbl,
        probe:          eepro100_init_one,
        remove:         eepro100_remove_one,
-
 #ifdef CONFIG_EEPRO100_PM
        suspend:        eepro100_suspend,
        resume:         eepro100_resume,
index 614c5e20073d4b603dd4d2e021bd83b04740e622..a2e6147cb577009129dd6c1f133743d17fea4299 100644 (file)
@@ -960,7 +960,7 @@ static int irtty_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
        ASSERT(self != NULL, return -1;);
        ASSERT(self->magic == IRTTY_MAGIC, return -1;);
 
-       IRDA_DEBUG(2, __FUNCTION__ "(), %s, (cmd=0x%X)\n", dev->name, cmd);
+       IRDA_DEBUG(3, __FUNCTION__ "(), %s, (cmd=0x%X)\n", dev->name, cmd);
        
        /* Disable interrupts & save flags */
        save_flags(flags);
index 245442ff2adf004d28be89c422853e3b96198779..a63e865b78a3c93b9c99017676147803d17b0ed5 100644 (file)
@@ -708,9 +708,12 @@ static int nsc_ircc_setup(chipio_t *info)
        switch_bank(iobase, BANK0);
        
        /* Set FIFO threshold to TX17, RX16, reset and enable FIFO's */
-       switch_bank(iobase, BANK0);     
+       switch_bank(iobase, BANK0);
        outb(FCR_RXTH|FCR_TXTH|FCR_TXSR|FCR_RXSR|FCR_FIFO_EN, iobase+FCR);
-       
+
+       outb(0x03, iobase+LCR);         /* 8 bit word length */
+       outb(MCR_SIR, iobase+MCR);      /* Start at SIR-mode, also clears LSR*/
+
        /* Set FIFO size to 32 */
        switch_bank(iobase, BANK2);
        outb(EXCR2_RFSIZ|EXCR2_TFSIZ, iobase+EXCR2);
@@ -723,7 +726,7 @@ static int nsc_ircc_setup(chipio_t *info)
        switch_bank(iobase, BANK6);
        outb(0x20, iobase+0); /* Set 32 bits FIR CRC */
        outb(0x0a, iobase+1); /* Set MIR pulse width */
-       outb(0x0d, iobase+2); /* Set SIR pulse width */
+       outb(0x0d, iobase+2); /* Set SIR pulse width to 1.6us */
        outb(0x2a, iobase+4); /* Set beginning frag, and preamble length */
 
        MESSAGE("%s, driver loaded (Dag Brattli)\n", driver_name);
@@ -804,8 +807,6 @@ static void nsc_ircc_init_dongle_interface (int iobase, int dongle_id)
                           dongle_types[dongle_id]); 
                break;
        case 0x04: /* Sharp RY5HD01 */
-               IRDA_DEBUG(0, __FUNCTION__ "(), %s not supported yet\n",
-                          dongle_types[dongle_id]); 
                break;
        case 0x05: /* Reserved, but this is what the Thinkpad reports */
                IRDA_DEBUG(0, __FUNCTION__ "(), %s not defined by irda yet\n",
@@ -892,8 +893,7 @@ static void nsc_ircc_change_dongle_speed(int iobase, int speed, int dongle_id)
                           dongle_types[dongle_id]); 
                break;
        case 0x04: /* Sharp RY5HD01 */
-               IRDA_DEBUG(0, __FUNCTION__ "(), %s not supported yet\n",
-                          dongle_types[dongle_id]); 
+               break;
        case 0x05: /* Reserved */
                IRDA_DEBUG(0, __FUNCTION__ "(), %s not defined by irda yet\n",
                           dongle_types[dongle_id]); 
index 3c03f1f6f85677b163fdacc999a27d1d7a319316..c05adebc15b492cb95360f1024cef21e9505d64f 100644 (file)
@@ -27,7 +27,7 @@
 
 #if defined(CONFIG_TMS380TR) || defined(CONFIG_TMS380TR_MODULE)
 
-unsigned char tms380tr_code[] = {
+static unsigned char tms380tr_code[] = {
        0x00, 0x00, 0x00, 0xA0, 0x00, 0x20, 0x68, 0x54,
        0x73, 0x69, 0x63, 0x20, 0x64, 0x6F, 0x20, 0x65,
        0x73, 0x69, 0x72, 0x20, 0x6C, 0x65, 0x61, 0x65,
index 401185890b2f7776fca2b1f9206aa2be4123273c..d9d8ae97d4abf1b5551c0259a867a023bb29f5af 100644 (file)
  * Support routines for initializing a PCI subsystem.
  */
 
+/*
+ * Nov 2000, Ivan Kokshaysky <ink@jurassic.park.msu.ru>
+ *          PCI-PCI bridges cleanup, sorted resource allocation
+ */
+
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/pci.h>
 #include <linux/errno.h>
 #include <linux/ioport.h>
 #include <linux/cache.h>
+#include <linux/slab.h>
 
 
-#define DEBUG_CONFIG 0
+#define DEBUG_CONFIG 1
 #if DEBUG_CONFIG
 # define DBGC(args)     printk args
 #else
 # define DBGC(args)
 #endif
 
-
 #define ROUND_UP(x, a)         (((x) + (a) - 1) & ~((a) - 1))
-#define ROUND_DOWN(x, a)       ((x) & ~((a) - 1))
 
-static void __init
-pbus_set_ranges(struct pci_bus *bus, struct pbus_set_ranges_data *outer)
+static int __init
+pbus_assign_resources_sorted(struct pci_bus *bus,
+                            struct pbus_set_ranges_data *ranges)
 {
-       struct pbus_set_ranges_data inner;
-       struct pci_dev *dev;
        struct list_head *ln;
+       struct resource *res;
+       struct resource_list head_io, head_mem, *list, *tmp;
+       unsigned long io_reserved = 0, mem_reserved = 0;
+       int idx, found_vga = 0;
 
-       inner.found_vga = 0;
-       inner.mem_start = inner.io_start = ~0UL;
-       inner.mem_end = inner.io_end = 0;
-
-       /* Collect information about how our direct children are layed out. */
+       head_io.next = head_mem.next = NULL;
        for (ln=bus->devices.next; ln != &bus->devices; ln=ln->next) {
-               int i;
-               dev = pci_dev_b(ln);
-               for (i = 0; i < PCI_NUM_RESOURCES; i++) {
-                       struct resource *res = &dev->resource[i];
-                       if (res->flags & IORESOURCE_IO) {
-                               if (res->start < inner.io_start)
-                                       inner.io_start = res->start;
-                               if (res->end > inner.io_end)
-                                       inner.io_end = res->end;
-                       } else if (res->flags & IORESOURCE_MEM) {
-                               if (res->start < inner.mem_start)
-                                       inner.mem_start = res->start;
-                               if (res->end > inner.mem_end)
-                                       inner.mem_end = res->end;
-                       }
+               struct pci_dev *dev = pci_dev_b(ln);
+               u16 cmd;
+
+               /* First, disable the device to avoid side
+                  effects of possibly overlapping I/O and
+                  memory ranges.
+                  Except the VGA - for obvious reason. :-)  */
+               if (dev->class >> 8 == PCI_CLASS_DISPLAY_VGA)
+                       found_vga = 1;
+               else {
+                       pci_read_config_word(dev, PCI_COMMAND, &cmd);
+                       cmd &= ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY
+                                               | PCI_COMMAND_MASTER);
+                       pci_write_config_word(dev, PCI_COMMAND, cmd);
+               }
+               /* Reserve some resources for CardBus.
+                  Are these values reasonable? */
+               if (dev->class >> 8 == PCI_CLASS_BRIDGE_CARDBUS) {
+                       io_reserved += 8*1024;
+                       mem_reserved += 32*1024*1024;
+                       continue;
                }
-                if ((dev->class >> 8) == PCI_CLASS_DISPLAY_VGA)
-                        inner.found_vga = 1;
+
+               pdev_sort_resources(dev, &head_io, IORESOURCE_IO);
+               pdev_sort_resources(dev, &head_mem, IORESOURCE_MEM);
        }
 
-       /* And for all of the sub-busses.  */
-       for (ln=bus->children.next; ln != &bus->children; ln=ln->next)
-               pbus_set_ranges(pci_bus_b(ln), &inner);
-
-       /* Align the values.  */
-       inner.io_start = ROUND_DOWN(inner.io_start, 4*1024);
-       inner.io_end = ROUND_UP(inner.io_end, 4*1024);
-
-       inner.mem_start = ROUND_DOWN(inner.mem_start, 1*1024*1024);
-       inner.mem_end = ROUND_UP(inner.mem_end, 1*1024*1024);
-
-       pcibios_fixup_pbus_ranges(bus, &inner);
-
-       /* Configure the bridge, if possible.  */
-       if (bus->self) {
-               struct pci_dev *bridge = bus->self;
-               u32 l;
-
-                /* Set up the top and bottom of the PCI I/O segment
-                   for this bus.  */
-                pci_read_config_dword(bridge, PCI_IO_BASE, &l);
-                l &= 0xffff0000;
-                l |= (inner.io_start >> 8) & 0x00f0;
-               l |= (inner.io_end - 1) & 0xf000;
-                pci_write_config_dword(bridge, PCI_IO_BASE, l);
-
-                /*
-                 * Clear out the upper 16 bits of IO base/limit.
-                 * Clear out the upper 32 bits of PREF base/limit.
-                 */
-                pci_write_config_dword(bridge, PCI_IO_BASE_UPPER16, 0);
-                pci_write_config_dword(bridge, PCI_PREF_BASE_UPPER32, 0);
-                pci_write_config_dword(bridge, PCI_PREF_LIMIT_UPPER32, 0);
-
-                /* Set up the top and bottom of the PCI Memory segment
-                   for this bus.  */
-                l = (inner.mem_start & 0xfff00000) >> 16;
-               l |= (inner.mem_end - 1) & 0xfff00000;
-                pci_write_config_dword(bridge, PCI_MEMORY_BASE, l);
-
-                /*
-                 * Turn off downstream PF memory address range, unless
-                 * there is a VGA behind this bridge, in which case, we
-                 * enable the PREFETCH range to include BIOS ROM at C0000.
-                 *
-                 * NOTE: this is a bit of a hack, done with PREFETCH for
-                 * simplicity, rather than having to add it into the above
-                 * non-PREFETCH range, which could then be bigger than we want.
-                 * We might assume that we could relocate the BIOS ROM, but
-                 * that would depend on having it found by those who need it
-                 * (the DEC BIOS emulator would find it, but I do not know
-                 * about the Xservers). So, we do it this way for now... ;-)
-                 */
-                l = (inner.found_vga) ? 0 : 0x0000ffff;
-                pci_write_config_dword(bridge, PCI_PREF_MEMORY_BASE, l);
-
-                /*
-                 * Tell bridge that there is an ISA bus in the system,
-                 * and (possibly) a VGA as well.
-                 */
-                l = (inner.found_vga) ? 0x0c : 0x04;
-                pci_write_config_byte(bridge, PCI_BRIDGE_CONTROL, l);
-
-                /*
-                 * Clear status bits,
-                 * turn on I/O    enable (for downstream I/O),
-                 * turn on memory enable (for downstream memory),
-                 * turn on master enable (for upstream memory and I/O).
-                 */
-                pci_write_config_dword(bridge, PCI_COMMAND, 0xffff0007);
+       for (list = head_io.next; list;) {
+               res = list->res;
+               idx = res - &list->dev->resource[0];
+               if (pci_assign_resource(list->dev, idx) == 0
+                   && ranges->io_end < res->end)
+                       ranges->io_end = res->end;
+               tmp = list;
+               list = list->next;
+               kfree(tmp);
+       }
+       for (list = head_mem.next; list;) {
+               res = list->res;
+               idx = res - &list->dev->resource[0];
+               if (pci_assign_resource(list->dev, idx) == 0
+                   && ranges->mem_end < res->end)
+                       ranges->mem_end = res->end;
+               tmp = list;
+               list = list->next;
+               kfree(tmp);
        }
 
-       if (outer) {
-               outer->found_vga |= inner.found_vga;
-               if (inner.io_start < outer->io_start)
-                       outer->io_start = inner.io_start;
-               if (inner.io_end > outer->io_end)
-                       outer->io_end = inner.io_end;
-               if (inner.mem_start < outer->mem_start)
-                       outer->mem_start = inner.mem_start;
-               if (inner.mem_end > outer->mem_end)
-                       outer->mem_end = inner.mem_end;
+       ranges->io_end += io_reserved;
+       ranges->mem_end += mem_reserved;
+
+       /* PCI-to-PCI Bridge Architecture Specification rev. 1.1 (1998)
+          requires that if there is no I/O ports or memory behind the
+          bridge, corresponding range must be turned off by writing base
+          value greater than limit to the bridge's base/limit registers.  */
+#if 1
+       /* But assuming that some hardware designed before 1998 might
+          not support this (very unlikely - at least all DEC bridges
+          are ok and I believe that was standard de-facto. -ink), we
+          must allow for at least one unit.  */
+       if (ranges->io_end == ranges->io_start)
+               ranges->io_end += 1;
+       if (ranges->mem_end == ranges->mem_start)
+               ranges->mem_end += 1;
+#endif
+       ranges->io_end = ROUND_UP(ranges->io_end, 4*1024);
+       ranges->mem_end = ROUND_UP(ranges->mem_end, 1024*1024);
+
+       return found_vga;
+}
+
+/* Initialize bridges with base/limit values we have collected */
+static void __init
+pci_setup_bridge(struct pci_bus *bus)
+{
+       struct pbus_set_ranges_data ranges;
+       struct pci_dev *bridge = bus->self;
+       u32 l;
+
+       if (!bridge || (bridge->class >> 8) != PCI_CLASS_BRIDGE_PCI)
+               return;
+       ranges.io_start = bus->resource[0]->start;
+       ranges.io_end = bus->resource[0]->end;
+       ranges.mem_start = bus->resource[1]->start;
+       ranges.mem_end = bus->resource[1]->end;
+       pcibios_fixup_pbus_ranges(bus, &ranges);
+
+       DBGC(("PCI: Bus %d, bridge: %s\n", bus->number, bridge->name));
+       DBGC(("  IO window: %04lx-%04lx\n", ranges.io_start, ranges.io_end));
+       DBGC(("  MEM window: %08lx-%08lx\n", ranges.mem_start, ranges.mem_end));
+
+       /* Set up the top and bottom of the PCI I/O segment for this bus. */
+       pci_read_config_dword(bridge, PCI_IO_BASE, &l);
+       l &= 0xffff0000;
+       l |= (ranges.io_start >> 8) & 0x00f0;
+       l |= ranges.io_end & 0xf000;
+       pci_write_config_dword(bridge, PCI_IO_BASE, l);
+
+       /* Clear upper 16 bits of I/O base/limit. */
+       pci_write_config_dword(bridge, PCI_IO_BASE_UPPER16, 0);
+
+       /* Clear out the upper 32 bits of PREF base/limit. */
+       pci_write_config_dword(bridge, PCI_PREF_BASE_UPPER32, 0);
+       pci_write_config_dword(bridge, PCI_PREF_LIMIT_UPPER32, 0);
+
+       /* Set up the top and bottom of the PCI Memory segment
+          for this bus. */
+       l = (ranges.mem_start >> 16) & 0xfff0;
+       l |= ranges.mem_end & 0xfff00000;
+       pci_write_config_dword(bridge, PCI_MEMORY_BASE, l);
+
+       /* Set up PREF base/limit. */
+       l = (bus->resource[2]->start >> 16) & 0xfff0;
+       l |= bus->resource[2]->end & 0xfff00000;
+       pci_write_config_dword(bridge, PCI_PREF_MEMORY_BASE, l);
+
+       /* Check if we have VGA behind the bridge.
+          Enable ISA in either case. */
+       l = (bus->resource[0]->flags & IORESOURCE_BUS_HAS_VGA) ? 0x0c : 0x04;
+       pci_write_config_word(bridge, PCI_BRIDGE_CONTROL, l);
+}
+
+static void __init
+pbus_assign_resources(struct pci_bus *bus, struct pbus_set_ranges_data *ranges)
+{
+       struct list_head *ln;
+       int found_vga = pbus_assign_resources_sorted(bus, ranges);
+
+       if (!ranges->found_vga && found_vga) {
+               struct pci_bus *b;
+
+               ranges->found_vga = 1;
+               /* Propogate presence of the VGA to upstream bridges */
+               for (b = bus; b->parent; b = b->parent) {
+#if 0
+                       /* ? Do we actually need to enable PF memory? */
+                       b->resource[2]->start = 0;
+#endif
+                       b->resource[0]->flags |= IORESOURCE_BUS_HAS_VGA;
+               }
+       }
+       for (ln=bus->children.next; ln != &bus->children; ln=ln->next) {
+               struct pci_bus *b = pci_bus_b(ln);
+
+               b->resource[0]->start = ranges->io_start = ranges->io_end;
+               b->resource[1]->start = ranges->mem_start = ranges->mem_end;
+
+               pbus_assign_resources(b, ranges);
+
+               b->resource[0]->end = ranges->io_end - 1;
+               b->resource[1]->end = ranges->mem_end - 1;
+
+               pci_setup_bridge(b);
        }
 }
 
-void __init
-pci_set_bus_ranges(void)
+void __init 
+pci_assign_unassigned_resources(void)
 {
+       struct pbus_set_ranges_data ranges;
        struct list_head *ln;
+       struct pci_dev *dev;
+
+       for(ln=pci_root_buses.next; ln != &pci_root_buses; ln=ln->next) {
+               struct pci_bus *b = pci_bus_b(ln);
 
-       for(ln=pci_root_buses.next; ln != &pci_root_buses; ln=ln->next)
-               pbus_set_ranges(pci_bus_b(ln), NULL);
+               ranges.io_start = b->resource[0]->start;
+               ranges.mem_start = b->resource[1]->start;
+               ranges.io_end = ranges.io_start;
+               ranges.mem_end = ranges.mem_start;
+               ranges.found_vga = 0;
+               pbus_assign_resources(b, &ranges);
+       }
+       pci_for_each_dev(dev) {
+               pdev_enable_device(dev);
+       }
+}
+
+/* Check whether the bridge supports I/O forwarding.
+   If not, its I/O base/limit register must be
+   read-only and read as 0. */
+unsigned long __init
+pci_bridge_check_io(struct pci_dev *bridge)
+{
+       u16 io;
+
+       pci_read_config_word(bridge, PCI_IO_BASE, &io);
+       if (!io) {
+               pci_write_config_word(bridge, PCI_IO_BASE, 0xf0f0);
+               pci_read_config_word(bridge, PCI_IO_BASE, &io);
+               pci_write_config_word(bridge, PCI_IO_BASE, 0x0);
+       }
+       if (io)
+               return IORESOURCE_IO;
+       printk(KERN_WARNING "PCI: bridge %s does not support I/O forwarding!\n",
+                               bridge->name);
+       return 0;
 }
index 1a95544d8f31dfb9c1fc8084954b951176539a31..a2e83d751477cf315f98aa7fbf42b71d8ec598e1 100644 (file)
 
 /* fixed for multiple pci buses, 1999 Andrea Arcangeli <andrea@suse.de> */
 
+/*
+ * Nov 2000, Ivan Kokshaysky <ink@jurassic.park.msu.ru>
+ *          Resource sorting
+ */
+
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/pci.h>
 #include <linux/errno.h>
 #include <linux/ioport.h>
 #include <linux/cache.h>
+#include <linux/slab.h>
 
 
-#define DEBUG_CONFIG 0
+#define DEBUG_CONFIG 1
 #if DEBUG_CONFIG
 # define DBGC(args)     printk args
 #else
@@ -114,19 +120,58 @@ pci_assign_resource(struct pci_dev *dev, int i)
                }
        }
 
-       DBGC(("  got res[%lx:%lx] for resource %d\n", res->start, res->end, i));
+       DBGC(("  got res[%lx:%lx] for resource %d of %s\n", res->start,
+                                               res->end, i, dev->name));
 
        return 0;
 }
 
-void
-pdev_assign_unassigned_resources(struct pci_dev *dev)
+/* Sort resources of a given type by alignment */
+void __init
+pdev_sort_resources(struct pci_dev *dev,
+                   struct resource_list *head, u32 type_mask)
+{
+       int i;
+
+       for (i = 0; i < PCI_NUM_RESOURCES; i++) {
+               struct resource *r;
+               struct resource_list *list, *tmp;
+
+               /* PCI-PCI bridges may have I/O ports or
+                  memory on the primary bus */
+               if (dev->class >> 8 == PCI_CLASS_BRIDGE_PCI &&
+                                               i >= PCI_BRIDGE_RESOURCES)
+                       continue;
+
+               r = &dev->resource[i];
+               if (!(r->flags & type_mask) || r->parent)
+                       continue;
+               for (list = head; ; list = list->next) {
+                       unsigned long size = 0;
+                       struct resource_list *ln = list->next;
+
+                       if (ln)
+                               size = ln->res->end - ln->res->start;
+                       if (r->end - r->start > size) {
+                               tmp = kmalloc(sizeof(*tmp), GFP_KERNEL);
+                               tmp->next = ln;
+                               tmp->res = r;
+                               tmp->dev = dev;
+                               list->next = tmp;
+                               break;
+                       }
+               }
+       }
+}
+
+void __init
+pdev_enable_device(struct pci_dev *dev)
 {
        u32 reg;
        u16 cmd;
        int i;
 
-       DBGC(("PCI assign unassigned: (%s)\n", dev->name));
+       DBGC(("PCI enable device: (%s)\n", dev->name));
 
        pci_read_config_word(dev, PCI_COMMAND, &cmd);
 
@@ -137,13 +182,6 @@ pdev_assign_unassigned_resources(struct pci_dev *dev)
                        cmd |= PCI_COMMAND_IO;
                else if (res->flags & IORESOURCE_MEM)
                        cmd |= PCI_COMMAND_MEMORY;
-
-               /* If it is already assigned or the resource does
-                  not exist, there is nothing to do.  */
-               if (res->parent != NULL || res->flags == 0)
-                       continue;
-
-               pci_assign_resource(dev, i);
        }
 
        /* Special case, disable the ROM.  Several devices act funny
@@ -171,24 +209,12 @@ pdev_assign_unassigned_resources(struct pci_dev *dev)
           it, the bit will go into the bucket. */
        cmd |= PCI_COMMAND_MASTER;
 
+       /* Set the cache line and default latency (32).  */
+       pci_write_config_word(dev, PCI_CACHE_LINE_SIZE,
+                       (32 << 8) | (L1_CACHE_BYTES / sizeof(u32)));
+
        /* Enable the appropriate bits in the PCI command register.  */
        pci_write_config_word(dev, PCI_COMMAND, cmd);
 
        DBGC(("  cmd reg 0x%x\n", cmd));
-
-       /* If this is a PCI bridge, set the cache line correctly.  */
-       if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) {
-               pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE,
-                                     (L1_CACHE_BYTES / sizeof(u32)));
-       }
-}
-
-void __init
-pci_assign_unassigned_resources(void)
-{
-       struct pci_dev *dev;
-
-       pci_for_each_dev(dev) {
-               pdev_assign_unassigned_resources(dev);
-       }
 }
index 7d7b705c7810596bab3c6c9392d025e612523162..b8f3664d5b6ce7c212cf76630d5e68585e80146c 100644 (file)
@@ -270,17 +270,16 @@ static int isapnp_next_rdp(void)
 {
        int rdp = isapnp_rdp;
        while (rdp <= 0x3ff) {
-               if (!check_region(rdp, 1)) {
-                       isapnp_rdp = rdp;
-                       return 0;
-               }
-               rdp += RDP_STEP;
                /*
                 *      We cannot use NE2000 probe spaces for ISAPnP or we
                 *      will lock up machines.
                 */
-               if(rdp >= 0x280 && rdp <= 0x380)
-                       continue;
+               if ((rdp < 0x280 || rdp >  0x380) && !check_region(rdp, 1)) 
+               {
+                       isapnp_rdp = rdp;
+                       return 0;
+               }
+               rdp += RDP_STEP;
        }
        return -1;
 }
index 7d07453dfec48219a51e0a6d401ffe2323f51859..c2627d106e1db9beaeb9aad8deca74de6d29bf5d 100644 (file)
@@ -39,6 +39,7 @@ obj-$(CONFIG_WARPENGINE_SCSI) += amiga7xx.o   53c7xx.o
 obj-$(CONFIG_A3000_SCSI)       += a3000.o      wd33c93.o
 obj-$(CONFIG_A2091_SCSI)       += a2091.o      wd33c93.o
 obj-$(CONFIG_GVP11_SCSI)       += gvp11.o      wd33c93.o
+obj-$(CONFIG_MVME147_SCSI)     += mvme147.o    wd33c93.o
 obj-$(CONFIG_CYBERSTORM_SCSI)  += NCR53C9x.o   cyberstorm.o
 obj-$(CONFIG_CYBERSTORMII_SCSI)        += NCR53C9x.o   cyberstormII.o
 obj-$(CONFIG_BLZ2060_SCSI)     += NCR53C9x.o   blz2060.o
index 5c657b2e5d06032afdafcdba6b7f8f7fc3abf102..64da3a50743d61dea4018300265263390880afdd 100644 (file)
@@ -231,8 +231,6 @@ int __init a2091_detect(Scsi_Host_Template *tpnt)
 
 #define HOSTS_C
 
-#include "a2091.h"
-
 static Scsi_Host_Template driver_template = A2091_SCSI;
 
 #include "scsi_module.c"
index 97beba1465bb23d23bfa14d818873cf54a706315..b0bcaa4b11873508fbaba1f01da8f292351a1dde 100644 (file)
@@ -1,4 +1,5 @@
 #ifndef A2091_H
+#define A2091_H
 
 /* $Id: a2091.h,v 1.4 1997/01/19 23:07:09 davem Exp $
  *
index c9a4253f0a8a6b6963be2850f0986e3f018bb9fa..ddb65b250618fd89e8db41f0a61e469753c481f8 100644 (file)
@@ -3,6 +3,7 @@
 #include <linux/blk.h>
 #include <linux/sched.h>
 #include <linux/version.h>
+#include <linux/ioport.h>
 #include <linux/init.h>
 #include <linux/spinlock.h>
 
@@ -100,7 +101,9 @@ static int dma_setup (Scsi_Cmnd *cmd, int dir_in)
        cache_push (addr, cmd->SCp.this_residual);
 
     /* start DMA */
+    mb();                      /* make sure setup is completed */
     DMA(a3000_host)->ST_DMA = 1;
+    mb();                      /* make sure DMA has started before next IO */
 
     /* return success */
     return 0;
@@ -116,12 +119,15 @@ static void dma_stop (struct Scsi_Host *instance, Scsi_Cmnd *SCpnt,
        cntr |= CNTR_DDIR;
 
     DMA(instance)->CNTR = cntr;
+    mb();                      /* make sure CNTR is updated before next IO */
 
     /* flush if we were reading */
     if (HDATA(instance)->dma_dir) {
        DMA(instance)->FLUSH = 1;
+       mb();                   /* don't allow prefetch */
        while (!(DMA(instance)->ISTR & ISTR_FE_FLG))
-           ;
+           barrier();
+       mb();                   /* no IO until FLUSH is done */
     }
 
     /* clear a possible interrupt */
@@ -132,9 +138,11 @@ static void dma_stop (struct Scsi_Host *instance, Scsi_Cmnd *SCpnt,
 
     /* stop DMA */
     DMA(instance)->SP_DMA = 1;
+    mb();                      /* make sure DMA is stopped before next IO */
 
     /* restore the CONTROL bits (minus the direction flag) */
     DMA(instance)->CNTR = CNTR_PDMD | CNTR_INTEN;
+    mb();                      /* make sure CNTR is updated before next IO */
 
     /* copy from a bounce buffer, if necessary */
     if (status && HDATA(instance)->dma_bounce_buffer) {
@@ -170,13 +178,17 @@ int __init a3000_detect(Scsi_Host_Template *tpnt)
 
     if  (!MACH_IS_AMIGA || !AMIGAHW_PRESENT(A3000_SCSI))
        return 0;
+    if (!request_mem_region(0xDD0000, 256, "wd33c93"))
+       return -EBUSY;
 
     tpnt->proc_name = "A3000";
     tpnt->proc_info = &wd33c93_proc_info;
 
     a3000_host = scsi_register (tpnt, sizeof(struct WD33C93_hostdata));
-    if(a3000_host == NULL)
+    if (a3000_host == NULL) {
+       release_mem_region(0xDD0000, 256);
        return 0;
+    }
     a3000_host->base = ZTWO_VADDR(0xDD0000);
     a3000_host->irq = IRQ_AMIGA_PORTS;
     DMA(a3000_host)->DAWR = DAWR_A3000;
@@ -192,9 +204,7 @@ int __init a3000_detect(Scsi_Host_Template *tpnt)
 
 #define HOSTS_C
 
-#include "a3000.h"
-
-static Scsi_Host_Template driver_template = A3000_SCSI;
+static Scsi_Host_Template driver_template = _A3000_SCSI;
 
 #include "scsi_module.c"
 
@@ -203,6 +213,7 @@ int a3000_release(struct Scsi_Host *instance)
 #ifdef MODULE
     wd33c93_release();
     DMA(instance)->CNTR = 0;
+    release_mem_region(0xDD0000, 256);
     free_irq(IRQ_AMIGA_PORTS, a3000_intr);
 #endif
     return 1;
index 478c3d39abf9c84ac23c8375b003faf3d7c76fbe..78f51c8e0cdcff0de862861abb17e659146e64c8 100644 (file)
@@ -1,4 +1,5 @@
 #ifndef A3000_H
+#define A3000_H
 
 /* $Id: a3000.h,v 1.4 1997/01/19 23:07:10 davem Exp $
  *
@@ -29,7 +30,7 @@ int wd33c93_reset(Scsi_Cmnd *, unsigned int);
 #define CAN_QUEUE 16
 #endif
 
-#define A3000_SCSI {  proc_name:          "A3000",                     \
+#define _A3000_SCSI { proc_name:          "A3000",                     \
                      proc_info:           NULL,                        \
                      name:                "Amiga 3000 built-in SCSI",  \
                      detect:              a3000_detect,                \
index 77feb1cbc3a262587f6e44a3daee357835196481..449b74013178e7927387826cd979d695354beca7 100644 (file)
@@ -656,7 +656,7 @@ int atari_scsi_detect (Scsi_Host_Template *host)
         */
        if (MACH_IS_ATARI && ATARIHW_PRESENT(ST_SCSI) &&
            !ATARIHW_PRESENT(EXTD_DMA) && m68k_num_memory > 1) {
-               atari_dma_buffer = atari_stram_alloc( STRAM_BUFFER_SIZE, NULL, "SCSI" );
+               atari_dma_buffer = atari_stram_alloc(STRAM_BUFFER_SIZE, "SCSI");
                if (!atari_dma_buffer) {
                        printk( KERN_ERR "atari_scsi_detect: can't allocate ST-RAM "
                                        "double buffer\n" );
index a1f277e8d19bca41a2d76eb1a0d0c7f9ff4919dc..9436e6a6519adbe247a4d3f6b80c6fd72f985fb1 100644 (file)
@@ -1,12 +1,26 @@
 /*
  *      eata.c - Low-level driver for EATA/DMA SCSI host adapters.
  *
+ *      22 Nov 2000 Rev. 6.02 for linux 2.4.0-test11
+ *        + Return code checked when calling pci_enable_device.
+ *        + Removed old scsi error handling support.
+ *        + The obsolete boot option flag eh:n is silently ignored.
+ *        + Removed error messages while a disk drive is powered up at
+ *          boot time.
+ *        + Improved boot messages: all tagged capable device are
+ *          indicated as "tagged" or "soft-tagged" :
+ *          - "soft-tagged"  means that the driver is trying to do its 
+ *            own tagging (i.e. the tc:y option is in effect);
+ *          - "tagged" means that the device supports tagged commands,
+ *            but the driver lets the HBA be responsible for tagging
+ *            support.
+ *
  *      16 Sep 1999 Rev. 5.11 for linux 2.2.12 and 2.3.18
  *        + Updated to the new __setup interface for boot command line options.
  *        + When loaded as a module, accepts the new parameter boot_options
  *          which value is a string with the same format of the kernel boot
  *          command line options. A valid example is:
- *          modprobe eata 'boot_options=\"0x7410,0x230,lc:y,tc:n,mq:4\"'
+ *          modprobe eata boot_options=\"0x7410,0x230,lc:y,tc:n,mq:4\"
  *
  *       9 Sep 1999 Rev. 5.10 for linux 2.2.12 and 2.3.17
  *        + 64bit cleanup for Linux/Alpha platform support
  *          This driver is based on the CAM (Common Access Method Committee)
  *          EATA (Enhanced AT Bus Attachment) rev. 2.0A, using DMA protocol.
  *
- *  Copyright (C) 1994-1999 Dario Ballabio (dario@milano.europe.dg.com)
+ *  Copyright (C) 1994-2000 Dario Ballabio (ballabio_dario@emc.com)
+ *
+ *  Alternate email: dario.ballabio@inwind.it, dario.ballabio@tiscalinet.it
  *
  *  Redistribution and use in source and binary forms, with or without
  *  modification, are permitted provided that redistributions of source
  *  After the optional list of detection probes, other possible command line
  *  options are:
  *
- *  eh:y  use new scsi code;
- *  eh:n  use old scsi code;
  *  et:y  force use of extended translation (255 heads, 63 sectors);
  *  et:n  use disk geometry detected by scsicam_bios_param;
  *  rs:y  reverse scan order while detecting PCI boards;
  *
  *  The default value is: "eata=lc:n,tc:n,mq:16,tm:0,et:n,rs:n".
  *  An example using the list of detection probes could be:
- *  "eata=0x7410,0x230,lc:y,tc:n,mq:4,eh:n,et:n".
+ *  "eata=0x7410,0x230,lc:y,tc:n,mq:4,et:n".
  *
  *  When loading as a module, parameters can be specified as well.
  *  The above example would be (use 1 in place of y and 0 in place of n):
  *
  *  modprobe eata io_port=0x7410,0x230 linked_comm=1 tagged_comm=0 \
- *                max_queue_depth=4 tag_mode=0 use_new_eh_code=0 \
+ *                max_queue_depth=4 tag_mode=0 \
  *                ext_tran=0 rev_scan=1
  *
  *  ----------------------------------------------------------------------------
 
 #include <linux/version.h>
 
+#ifndef LinuxVersionCode
 #define LinuxVersionCode(v, p, s) (((v)<<16)+((p)<<8)+(s))
+#endif
+
 #define MAX_INT_PARAM 10
 
 #if defined(MODULE)
@@ -382,7 +399,6 @@ MODULE_PARM(tagged_comm, "i");
 MODULE_PARM(link_statistics, "i");
 MODULE_PARM(max_queue_depth, "i");
 MODULE_PARM(tag_mode, "i");
-MODULE_PARM(use_new_eh_code, "i");
 MODULE_PARM(ext_tran, "i");
 MODULE_PARM(rev_scan, "i");
 MODULE_AUTHOR("Dario Ballabio");
@@ -410,12 +426,7 @@ MODULE_AUTHOR("Dario Ballabio");
 #include <linux/pci.h>
 #include <linux/init.h>
 #include <linux/ctype.h>
-
-#if LINUX_VERSION_CODE < LinuxVersionCode(2,3,18)
-#include <asm/spinlock.h>
-#else
 #include <linux/spinlock.h>
-#endif
 
 #define SPIN_FLAGS unsigned long spin_flags;
 #define SPIN_LOCK spin_lock_irq(&io_request_lock);
@@ -501,10 +512,6 @@ MODULE_AUTHOR("Dario Ballabio");
 #define ASOK              0x00
 #define ASST              0x01
 
-#if LINUX_VERSION_CODE < LinuxVersionCode(2,3,18)
-#define ARRAY_SIZE(x) (sizeof (x) / sizeof((x)[0]))
-#endif
-
 #define YESNO(a) ((a) ? 'y' : 'n')
 #define TLDEV(type) ((type) == TYPE_DISK || (type) == TYPE_ROM)
 
@@ -693,7 +700,6 @@ static int link_statistics;
 static int tag_mode = TAG_MIXED;
 static int ext_tran = FALSE;
 static int rev_scan = TRUE;
-static int use_new_eh_code = TRUE;
 static char *boot_options;
 
 #if defined(CONFIG_SCSI_EATA_TAGGED_QUEUE)
@@ -761,9 +767,9 @@ static void select_queue_depths(struct Scsi_Host *host, Scsi_Device *devlist) {
          }
 
       if (dev->tagged_supported && TLDEV(dev->type) && dev->tagged_queue)
-         tag_suffix = ", tagged";
+         tag_suffix = ", soft-tagged";
       else if (dev->tagged_supported && TLDEV(dev->type))
-         tag_suffix = ", untagged";
+         tag_suffix = ", tagged";
 
       printk("%s: scsi%d, channel %d, id %d, lun %d, cmds/lun %d%s%s.\n",
              BN(j), host->host_no, dev->channel, dev->id, dev->lun,
@@ -831,7 +837,7 @@ static inline void tune_pci_port(unsigned long port_base) {
 
       addr = pci_resource_start (dev, 0);
 
-      pci_enable_device (dev); /* XXX handle error */
+      if (pci_enable_device (dev)) continue;
 
 #if defined(DEBUG_PCI_DETECT)
       printk("%s: tune_pci_port, bus %d, devfn 0x%x, addr 0x%x.\n",
@@ -1122,13 +1128,11 @@ static inline int port_detect \
       }
    else                                 tag_type = 'n';
 
-   sh[j]->hostt->use_new_eh_code = use_new_eh_code;
-
    if (j == 0) {
-      printk("EATA/DMA 2.0x: Copyright (C) 1994-1999 Dario Ballabio.\n");
-      printk("%s config options -> tc:%c, lc:%c, mq:%d, eh:%c, rs:%c, et:%c.\n",
+      printk("EATA/DMA 2.0x: Copyright (C) 1994-2000 Dario Ballabio.\n");
+      printk("%s config options -> tc:%c, lc:%c, mq:%d, rs:%c, et:%c.\n",
              driver_name, tag_type, YESNO(linked_comm), max_queue_depth,
-             YESNO(use_new_eh_code), YESNO(rev_scan), YESNO(ext_tran));
+             YESNO(rev_scan), YESNO(ext_tran));
       }
 
    printk("%s: 2.0%c, %s 0x%03lx, IRQ %u, %s, SG %d, MB %d.\n",
@@ -1191,7 +1195,6 @@ static void internal_setup(char *str, int *ints) {
       else if (!strncmp(cur, "tm:", 3)) tag_mode = val;
       else if (!strncmp(cur, "mq:", 3))  max_queue_depth = val;
       else if (!strncmp(cur, "ls:", 3))  link_statistics = val;
-      else if (!strncmp(cur, "eh:", 3))  use_new_eh_code = val;
       else if (!strncmp(cur, "et:", 3))  ext_tran = val;
       else if (!strncmp(cur, "rs:", 3))  rev_scan = val;
 
@@ -1439,79 +1442,6 @@ int eata2x_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) {
    return rtn;
 }
 
-static inline int do_old_abort(Scsi_Cmnd *SCarg) {
-   unsigned int i, j;
-
-   j = ((struct hostdata *) SCarg->host->hostdata)->board_number;
-
-   if (SCarg->host_scribble == NULL ||
-       (SCarg->serial_number_at_timeout &&
-       (SCarg->serial_number != SCarg->serial_number_at_timeout))) {
-      printk("%s: abort, target %d.%d:%d, pid %ld inactive.\n",
-             BN(j), SCarg->channel, SCarg->target, SCarg->lun, SCarg->pid);
-      return SCSI_ABORT_NOT_RUNNING;
-      }
-
-   i = *(unsigned int *)SCarg->host_scribble;
-   printk("%s: abort, mbox %d, target %d.%d:%d, pid %ld.\n",
-          BN(j), i, SCarg->channel, SCarg->target, SCarg->lun, SCarg->pid);
-
-   if (i >= sh[j]->can_queue)
-      panic("%s: abort, invalid SCarg->host_scribble.\n", BN(j));
-
-   if (wait_on_busy(sh[j]->io_port, MAXLOOP)) {
-      printk("%s: abort, timeout error.\n", BN(j));
-      return SCSI_ABORT_ERROR;
-      }
-
-   if (HD(j)->cp_stat[i] == FREE) {
-      printk("%s: abort, mbox %d is free.\n", BN(j), i);
-      return SCSI_ABORT_NOT_RUNNING;
-      }
-
-   if (HD(j)->cp_stat[i] == IN_USE) {
-      printk("%s: abort, mbox %d is in use.\n", BN(j), i);
-
-      if (SCarg != HD(j)->cp[i].SCpnt)
-         panic("%s: abort, mbox %d, SCarg %p, cp SCpnt %p.\n",
-               BN(j), i, SCarg, HD(j)->cp[i].SCpnt);
-
-      if (inb(sh[j]->io_port + REG_AUX_STATUS) & IRQ_ASSERTED)
-         printk("%s: abort, mbox %d, interrupt pending.\n", BN(j), i);
-
-      return SCSI_ABORT_SNOOZE;
-      }
-
-   if (HD(j)->cp_stat[i] == IN_RESET) {
-      printk("%s: abort, mbox %d is in reset.\n", BN(j), i);
-      return SCSI_ABORT_ERROR;
-      }
-
-   if (HD(j)->cp_stat[i] == LOCKED) {
-      printk("%s: abort, mbox %d is locked.\n", BN(j), i);
-      return SCSI_ABORT_NOT_RUNNING;
-      }
-
-   if (HD(j)->cp_stat[i] == READY || HD(j)->cp_stat[i] == ABORTING) {
-      SCarg->result = DID_ABORT << 16;
-      SCarg->host_scribble = NULL;
-      HD(j)->cp_stat[i] = FREE;
-      printk("%s, abort, mbox %d ready, DID_ABORT, pid %ld done.\n",
-             BN(j), i, SCarg->pid);
-      SCarg->scsi_done(SCarg);
-      return SCSI_ABORT_SUCCESS;
-      }
-
-   panic("%s: abort, mbox %d, invalid cp_stat.\n", BN(j), i);
-}
-
-int eata2x_old_abort(Scsi_Cmnd *SCarg) {
-   int rtn;
-
-   rtn = do_old_abort(SCarg);
-   return rtn;
-}
-
 static inline int do_abort(Scsi_Cmnd *SCarg) {
    unsigned int i, j;
 
@@ -1589,151 +1519,6 @@ int eata2x_abort(Scsi_Cmnd *SCarg) {
    return do_abort(SCarg);
 }
 
-static inline int do_old_reset(Scsi_Cmnd *SCarg) {
-   unsigned int i, j, time, k, c, limit = 0;
-   int arg_done = FALSE;
-   Scsi_Cmnd *SCpnt;
-
-   j = ((struct hostdata *) SCarg->host->hostdata)->board_number;
-   printk("%s: reset, enter, target %d.%d:%d, pid %ld.\n",
-          BN(j), SCarg->channel, SCarg->target, SCarg->lun, SCarg->pid);
-
-   if (SCarg->host_scribble == NULL)
-      printk("%s: reset, pid %ld inactive.\n", BN(j), SCarg->pid);
-
-   if (SCarg->serial_number_at_timeout &&
-       (SCarg->serial_number != SCarg->serial_number_at_timeout)) {
-      printk("%s: reset, pid %ld, reset not running.\n", BN(j), SCarg->pid);
-      return SCSI_RESET_NOT_RUNNING;
-      }
-
-   if (HD(j)->in_reset) {
-      printk("%s: reset, exit, already in reset.\n", BN(j));
-      return SCSI_RESET_ERROR;
-      }
-
-   if (wait_on_busy(sh[j]->io_port, MAXLOOP)) {
-      printk("%s: reset, exit, timeout error.\n", BN(j));
-      return SCSI_RESET_ERROR;
-      }
-
-   HD(j)->retries = 0;
-
-   for (c = 0; c <= sh[j]->max_channel; c++)
-      for (k = 0; k < sh[j]->max_id; k++) {
-         HD(j)->target_redo[k][c] = TRUE;
-         HD(j)->target_to[k][c] = 0;
-         }
-
-   for (i = 0; i < sh[j]->can_queue; i++) {
-
-      if (HD(j)->cp_stat[i] == FREE) continue;
-
-      if (HD(j)->cp_stat[i] == LOCKED) {
-         HD(j)->cp_stat[i] = FREE;
-         printk("%s: reset, locked mbox %d forced free.\n", BN(j), i);
-         continue;
-         }
-
-      if (!(SCpnt = HD(j)->cp[i].SCpnt))
-         panic("%s: reset, mbox %d, SCpnt == NULL.\n", BN(j), i);
-
-      if (HD(j)->cp_stat[i] == READY || HD(j)->cp_stat[i] == ABORTING) {
-         HD(j)->cp_stat[i] = ABORTING;
-         printk("%s: reset, mbox %d aborting, pid %ld.\n",
-                BN(j), i, SCpnt->pid);
-         }
-
-      else {
-         HD(j)->cp_stat[i] = IN_RESET;
-         printk("%s: reset, mbox %d in reset, pid %ld.\n",
-                BN(j), i, SCpnt->pid);
-         }
-
-      if (SCpnt->host_scribble == NULL)
-         panic("%s: reset, mbox %d, garbled SCpnt.\n", BN(j), i);
-
-      if (*(unsigned int *)SCpnt->host_scribble != i)
-         panic("%s: reset, mbox %d, index mismatch.\n", BN(j), i);
-
-      if (SCpnt->scsi_done == NULL)
-         panic("%s: reset, mbox %d, SCpnt->scsi_done == NULL.\n", BN(j), i);
-
-      if (SCpnt == SCarg) arg_done = TRUE;
-      }
-
-   if (do_dma(sh[j]->io_port, 0, RESET_PIO)) {
-      printk("%s: reset, cannot reset, timeout error.\n", BN(j));
-      return SCSI_RESET_ERROR;
-      }
-
-   printk("%s: reset, board reset done, enabling interrupts.\n", BN(j));
-
-#if defined(DEBUG_RESET)
-   do_trace = TRUE;
-#endif
-
-   HD(j)->in_reset = TRUE;
-   SPIN_UNLOCK
-   time = jiffies;
-   while ((jiffies - time) < (10 * HZ) && limit++ < 200000) udelay(100L);
-   SPIN_LOCK
-   printk("%s: reset, interrupts disabled, loops %d.\n", BN(j), limit);
-
-   for (i = 0; i < sh[j]->can_queue; i++) {
-
-      if (HD(j)->cp_stat[i] == IN_RESET) {
-         SCpnt = HD(j)->cp[i].SCpnt;
-         SCpnt->result = DID_RESET << 16;
-         SCpnt->host_scribble = NULL;
-
-         /* This mailbox is still waiting for its interrupt */
-         HD(j)->cp_stat[i] = LOCKED;
-
-         printk("%s, reset, mbox %d locked, DID_RESET, pid %ld done.\n",
-                BN(j), i, SCpnt->pid);
-         }
-
-      else if (HD(j)->cp_stat[i] == ABORTING) {
-         SCpnt = HD(j)->cp[i].SCpnt;
-         SCpnt->result = DID_RESET << 16;
-         SCpnt->host_scribble = NULL;
-
-         /* This mailbox was never queued to the adapter */
-         HD(j)->cp_stat[i] = FREE;
-
-         printk("%s, reset, mbox %d aborting, DID_RESET, pid %ld done.\n",
-                BN(j), i, SCpnt->pid);
-         }
-
-      else
-
-         /* Any other mailbox has already been set free by interrupt */
-         continue;
-
-      SCpnt->scsi_done(SCpnt);
-      }
-
-   HD(j)->in_reset = FALSE;
-   do_trace = FALSE;
-
-   if (arg_done) {
-      printk("%s: reset, exit, success.\n", BN(j));
-      return SCSI_RESET_SUCCESS;
-      }
-   else {
-      printk("%s: reset, exit, wakeup.\n", BN(j));
-      return SCSI_RESET_PUNT;
-      }
-}
-
-int eata2x_old_reset(Scsi_Cmnd *SCarg, unsigned int reset_flags) {
-   int rtn;
-
-   rtn = do_old_reset(SCarg);
-   return rtn;
-}
-
 static inline int do_reset(Scsi_Cmnd *SCarg) {
    unsigned int i, j, time, k, c, limit = 0;
    int arg_done = FALSE;
@@ -1983,7 +1768,7 @@ static inline int reorder(unsigned int j, unsigned long cursec,
 
    if (link_statistics) {
       if (cursec > sl[0]) iseek = cursec - sl[0]; else iseek = sl[0] - cursec;
-      batchcount++; readycount += n_ready, seeknosort += seek / 1024;
+      batchcount++; readycount += n_ready; seeknosort += seek / 1024;
       if (input_only) inputcount++;
       if (overlap) { ovlcount++; seeksorted += iseek / 1024; }
       else seeksorted += (iseek + maxsec - minsec) / 1024;
@@ -2169,7 +1954,9 @@ static inline void ihdlr(int irq, unsigned int j) {
          if (tstatus == GOOD)
             HD(j)->target_redo[SCpnt->target][SCpnt->channel] = FALSE;
 
-         if (spp->target_status && SCpnt->device->type == TYPE_DISK)
+         if (spp->target_status && SCpnt->device->type == TYPE_DISK &&
+             (!(tstatus == CHECK_CONDITION && HD(j)->iocount <= 1000 &&
+               (SCpnt->sense_buffer[2] & 0xf) == NOT_READY)))
             printk("%s: ihdlr, target %d.%d:%d, pid %ld, "\
                    "target_status 0x%x, sense key 0x%x.\n", BN(j),
                    SCpnt->channel, SCpnt->target, SCpnt->lun,
@@ -2297,13 +2084,5 @@ static Scsi_Host_Template driver_template = EATA;
 #include "scsi_module.c"
 
 #ifndef MODULE
-
-#if LINUX_VERSION_CODE < LinuxVersionCode(2,3,18)
-void eata2x_setup(char *str, int *ints) {
-   internal_setup(str, ints);
-}
-#else
 __setup("eata=", option_setup);
-#endif
-
 #endif /* end MODULE */
index 6c00ca0a2b4d2efe2a9a5e01e57e8737c2d9c5fe..5b3216e602bc5a443578f987ae09ab6078752b7d 100644 (file)
@@ -5,28 +5,23 @@
 #define _EATA_H
 
 #include <scsi/scsicam.h>
-#include <linux/version.h>
 
 int eata2x_detect(Scsi_Host_Template *);
 int eata2x_release(struct Scsi_Host *);
 int eata2x_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
 int eata2x_abort(Scsi_Cmnd *);
-int eata2x_old_abort(Scsi_Cmnd *);
 int eata2x_reset(Scsi_Cmnd *);
-int eata2x_old_reset(Scsi_Cmnd *, unsigned int);
 int eata2x_biosparam(Disk *, kdev_t, int *);
 
-#define EATA_VERSION "5.11.00"
-
-#define LinuxVersionCode(v, p, s) (((v)<<16)+((p)<<8)+(s))
+#define EATA_VERSION "6.02.00"
 
 #define EATA {                                                               \
                 name:              "EATA/DMA 2.0x rev. " EATA_VERSION " ",   \
                 detect:                  eata2x_detect,                      \
                 release:                 eata2x_release,                     \
                 queuecommand:            eata2x_queuecommand,                \
-                abort:                   eata2x_old_abort,                   \
-                reset:                   eata2x_old_reset,                   \
+                abort:                   NULL,                               \
+                reset:                   NULL,                               \
                 eh_abort_handler:        eata2x_abort,                       \
                 eh_device_reset_handler: NULL,                               \
                 eh_bus_reset_handler:    NULL,                               \
index e6d5b29421d264354a0b180682285480c69b1f8c..116ddbb58d58ed891626c5ab69e7f4f56c5c0285 100644 (file)
@@ -346,7 +346,7 @@ int __init gvp11_detect(Scsi_Host_Template *tpnt)
        continue;
 
 release:
-       release_mem_region(ZTWO_PADDR(instance->base), 256);
+       release_mem_region(address, 256);
     }
 
     return num_gvp11;
index 2b51924cf77170e68875729b9854dc4e7f2554bc..5d403105525d29761439fff33298a9f4ad88849d 100644 (file)
@@ -840,7 +840,7 @@ static void __exit exit_idescsi_module(void)
                failed = 0;
                while ((drive = ide_scan_devices (media[i], idescsi_driver.name, &idescsi_driver, failed)) != NULL)
                        if (idescsi_cleanup (drive)) {
-                               printk ("%s: cleanup_module() called while still busy\n", drive->name);
+                               printk ("%s: exit_idescsi_module() called while still busy\n", drive->name);
                                failed++;
                        }
        }
diff --git a/drivers/scsi/mvme147.c b/drivers/scsi/mvme147.c
new file mode 100644 (file)
index 0000000..26e3a27
--- /dev/null
@@ -0,0 +1,116 @@
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/blk.h>
+#include <linux/sched.h>
+#include <linux/version.h>
+
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/mvme147hw.h>
+#include <asm/irq.h>
+
+#include "scsi.h"
+#include "hosts.h"
+#include "wd33c93.h"
+#include "mvme147.h"
+
+#include<linux/stat.h>
+
+#define HDATA(ptr) ((struct WD33C93_hostdata *)((ptr)->hostdata))
+
+static struct Scsi_Host *mvme147_host = NULL;
+
+static void mvme147_intr (int irq, void *dummy, struct pt_regs *fp)
+{
+    if (irq == MVME147_IRQ_SCSI_PORT)
+       wd33c93_intr (mvme147_host);
+    else
+       m147_pcc->dma_intr = 0x89;      /* Ack and enable ints */
+}
+
+static int dma_setup (Scsi_Cmnd *cmd, int dir_in)
+{
+    unsigned char flags = 0x01;
+    unsigned long addr = virt_to_bus(cmd->SCp.ptr);
+
+    /* setup dma direction */
+    if (!dir_in)
+       flags |= 0x04;
+
+    /* remember direction */
+    HDATA(mvme147_host)->dma_dir = dir_in;
+
+    if (dir_in)
+       /* invalidate any cache */
+       cache_clear (addr, cmd->SCp.this_residual);
+    else
+       /* push any dirty cache */
+       cache_push (addr, cmd->SCp.this_residual);
+
+    /* start DMA */
+    m147_pcc->dma_bcr   = cmd->SCp.this_residual | (1<<24);
+    m147_pcc->dma_dadr  = addr;
+    m147_pcc->dma_cntrl = flags;
+
+    /* return success */
+    return 0;
+}
+
+static void dma_stop (struct Scsi_Host *instance, Scsi_Cmnd *SCpnt,
+                     int status)
+{
+    m147_pcc->dma_cntrl = 0;
+}
+
+int mvme147_detect(Scsi_Host_Template *tpnt)
+{
+    static unsigned char called = 0;
+
+    if (!MACH_IS_MVME147 || called)
+       return 0;
+    called++;
+
+    tpnt->proc_name = "MVME147";
+    tpnt->proc_info = &wd33c93_proc_info;
+
+    mvme147_host = scsi_register (tpnt, sizeof(struct WD33C93_hostdata));
+    mvme147_host->base = 0xfffe4000;
+    mvme147_host->irq = MVME147_IRQ_SCSI_PORT;
+    wd33c93_init(mvme147_host, (wd33c93_regs *)0xfffe4000,
+                dma_setup, dma_stop, WD33C93_FS_8_10);
+
+    request_irq(MVME147_IRQ_SCSI_PORT, mvme147_intr, 0, "MVME147 SCSI PORT", mvme147_intr);
+    request_irq(MVME147_IRQ_SCSI_DMA, mvme147_intr, 0, "MVME147 SCSI DMA", mvme147_intr);
+#if 0  /* Disabled; causes problems booting */
+    m147_pcc->scsi_interrupt = 0x10;   /* Assert SCSI bus reset */
+    udelay(100);
+    m147_pcc->scsi_interrupt = 0x00;   /* Negate SCSI bus reset */
+    udelay(2000);
+    m147_pcc->scsi_interrupt = 0x40;   /* Clear bus reset interrupt */
+#endif
+    m147_pcc->scsi_interrupt = 0x09;   /* Enable interrupt */
+
+    m147_pcc->dma_cntrl = 0x00;                /* ensure DMA is stopped */
+    m147_pcc->dma_intr = 0x89;         /* Ack and enable ints */
+
+    return 1;
+}
+
+#define HOSTS_C
+
+#include "mvme147.h"
+
+static Scsi_Host_Template driver_template = MVME147_SCSI;
+
+#include "scsi_module.c"
+
+int mvme147_release(struct Scsi_Host *instance)
+{
+#ifdef MODULE
+    /* XXX Make sure DMA is stopped! */
+    wd33c93_release();
+    free_irq(MVME147_IRQ_SCSI_PORT, mvme147_intr);
+    free_irq(MVME147_IRQ_SCSI_DMA, mvme147_intr);
+#endif
+    return 1;
+}
diff --git a/drivers/scsi/mvme147.h b/drivers/scsi/mvme147.h
new file mode 100644 (file)
index 0000000..dabde1b
--- /dev/null
@@ -0,0 +1,50 @@
+#ifndef MVME147_H
+
+/* $Id: mvme147.h,v 1.4 1997/01/19 23:07:10 davem Exp $
+ *
+ * Header file for the MVME147 built-in SCSI controller for Linux
+ *
+ * Written and (C) 1993, Hamish Macdonald, see mvme147.c for more info
+ *
+ */
+
+#include <linux/types.h>
+
+int mvme147_detect(Scsi_Host_Template *);
+int mvme147_release(struct Scsi_Host *);
+const char *wd33c93_info(void);
+int wd33c93_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
+int wd33c93_abort(Scsi_Cmnd *);
+int wd33c93_reset(Scsi_Cmnd *, unsigned int);
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+#ifndef CMD_PER_LUN
+#define CMD_PER_LUN 2
+#endif
+
+#ifndef CAN_QUEUE
+#define CAN_QUEUE 16
+#endif
+
+#ifdef HOSTS_C
+
+#define MVME147_SCSI {proc_name:          "MVME147",                   \
+                     proc_info:           NULL,                        \
+                     name:                "MVME147 built-in SCSI",     \
+                     detect:              mvme147_detect,              \
+                     release:             mvme147_release,             \
+                     queuecommand:        wd33c93_queuecommand,        \
+                     abort:               wd33c93_abort,               \
+                     reset:               wd33c93_reset,               \
+                     can_queue:           CAN_QUEUE,                   \
+                     this_id:             7,                           \
+                     sg_tablesize:        SG_ALL,                      \
+                     cmd_per_lun:         CMD_PER_LUN,                 \
+                     use_clustering:      ENABLE_CLUSTERING }
+
+#endif /* else def HOSTS_C */
+
+#endif /* MVME147_H */
index c9985393570bcdfe1fef12e1a77998c754e530a7..0aa6220024c2ab6e834a880281551ba858224553 100644 (file)
@@ -1,12 +1,20 @@
 /*
  *      u14-34f.c - Low-level driver for UltraStor 14F/34F SCSI host adapters.
  *
+ *      01 Nov 2000 Rev. 6.02 for linux 2.4.0-test11
+ *        + Removed old scsi error handling support.
+ *        + The obsolete boot option flag eh:n is silently ignored.
+ *        + Removed error messages while a disk drive is powered up at
+ *          boot time.
+ *        + Improved boot messages: all tagged capable device are
+ *          indicated as "tagged".
+ *
  *      16 Sep 1999 Rev. 5.11 for linux 2.2.12 and 2.3.18
  *        + Updated to the new __setup interface for boot command line options.
  *        + When loaded as a module, accepts the new parameter boot_options
  *          which value is a string with the same format of the kernel boot
  *          command line options. A valid example is:
- *          modprobe u14-34f 'boot_options=\"0x230,0x340,lc:y,mq:4\"'
+ *          modprobe u14-34f boot_options=\"0x230,0x340,lc:y,mq:4\"
  *
  *      22 Jul 1999 Rev. 5.00 for linux 2.2.10 and 2.3.11
  *        + Removed pre-2.2 source code compatibility.
  *
  *          Multiple U14F and/or U34F host adapters are supported.
  *
- *  Copyright (C) 1994-1999 Dario Ballabio (dario@milano.europe.dg.com)
+ *  Copyright (C) 1994-2000 Dario Ballabio (ballabio_dario@emc.com)
+ *
+ *  Alternate email: dario.ballabio@inwind.it, dario.ballabio@tiscalinet.it
  *
  *  Redistribution and use in source and binary forms, with or without
  *  modification, are permitted provided that redistributions of source
  *  After the optional list of detection probes, other possible command line
  *  options are:
  *
- *  eh:y  use new scsi code;
- *  eh:n  use old scsi code;
  *  et:y  use disk geometry returned by scsicam_bios_param;
  *  et:n  use disk geometry jumpered on the board;
  *  lc:y  enables linked commands;
  *
  *  The default value is: "u14-34f=lc:n,of:n,mq:8,et:n".
  *  An example using the list of detection probes could be:
- *  "u14-34f=0x230,0x340,lc:y,of:n,mq:4,eh:n,et:n".
+ *  "u14-34f=0x230,0x340,lc:y,of:n,mq:4,et:n".
  *
  *  When loading as a module, parameters can be specified as well.
  *  The above example would be (use 1 in place of y and 0 in place of n):
  *
  *  modprobe u14-34f io_port=0x230,0x340 linked_comm=1 have_old_firmware=0 \
- *                max_queue_depth=4 use_new_eh_code=0 ext_tran=0
+ *                max_queue_depth=4 ext_tran=0
  *
  *  ----------------------------------------------------------------------------
  *  In this implementation, linked commands are designed to work with any DISK
 
 #include <linux/version.h>
 
+#ifndef LinuxVersionCode
 #define LinuxVersionCode(v, p, s) (((v)<<16)+((p)<<8)+(s))
+#endif
+
 #define MAX_INT_PARAM 10
 
 #if defined(MODULE)
@@ -334,7 +345,6 @@ MODULE_PARM(linked_comm, "i");
 MODULE_PARM(have_old_firmware, "i");
 MODULE_PARM(link_statistics, "i");
 MODULE_PARM(max_queue_depth, "i");
-MODULE_PARM(use_new_eh_code, "i");
 MODULE_PARM(ext_tran, "i");
 MODULE_AUTHOR("Dario Ballabio");
 
@@ -360,12 +370,7 @@ MODULE_AUTHOR("Dario Ballabio");
 #include <linux/config.h>
 #include <linux/init.h>
 #include <linux/ctype.h>
-
-#if LINUX_VERSION_CODE < LinuxVersionCode(2,3,18)
-#include <asm/spinlock.h>
-#else
 #include <linux/spinlock.h>
-#endif
 
 #define SPIN_FLAGS unsigned long spin_flags;
 #define SPIN_LOCK spin_lock_irq(&io_request_lock);
@@ -450,10 +455,6 @@ MODULE_AUTHOR("Dario Ballabio");
 #define ASOK              0x00
 #define ASST              0x91
 
-#if LINUX_VERSION_CODE < LinuxVersionCode(2,3,18)
-#define ARRAY_SIZE(x) (sizeof (x) / sizeof((x)[0]))
-#endif
-
 #define YESNO(a) ((a) ? 'y' : 'n')
 #define TLDEV(type) ((type) == TYPE_DISK || (type) == TYPE_ROM)
 
@@ -554,10 +555,9 @@ static void do_interrupt_handler(int, void *, struct pt_regs *);
 static void flush_dev(Scsi_Device *, unsigned long, unsigned int, unsigned int);
 static int do_trace = FALSE;
 static int setup_done = FALSE;
-static int link_statistics = 0;
+static int link_statistics;
 static int ext_tran = FALSE;
-static int use_new_eh_code = TRUE;
-static char *boot_options = NULL;
+static char *boot_options;
 
 #if defined(HAVE_OLD_UX4F_FIRMWARE)
 static int have_old_firmware = TRUE;
@@ -619,9 +619,9 @@ static void select_queue_depths(struct Scsi_Host *host, Scsi_Device *devlist) {
          }
 
       if (dev->tagged_supported && TLDEV(dev->type) && dev->tagged_queue)
-         tag_suffix = ", tagged";
+         tag_suffix = ", soft-tagged";
       else if (dev->tagged_supported && TLDEV(dev->type))
-         tag_suffix = ", untagged";
+         tag_suffix = ", tagged";
 
       printk("%s: scsi%d, channel %d, id %d, lun %d, cmds/lun %d%s%s.\n",
              BN(j), host->host_no, dev->channel, dev->id, dev->lun,
@@ -766,8 +766,6 @@ static inline int port_detect \
 
    if (have_old_firmware) tpnt->use_clustering = DISABLE_CLUSTERING;
 
-   tpnt->use_new_eh_code = use_new_eh_code;
-
    sh[j] = scsi_register(tpnt, sizeof(struct hostdata));
 
    if (sh[j] == NULL) {
@@ -875,10 +873,10 @@ static inline int port_detect \
    if (max_queue_depth < MAX_CMD_PER_LUN) max_queue_depth = MAX_CMD_PER_LUN;
 
    if (j == 0) {
-      printk("UltraStor 14F/34F: Copyright (C) 1994-1999 Dario Ballabio.\n");
-      printk("%s config options -> of:%c, lc:%c, mq:%d, eh:%c, et:%c.\n",
+      printk("UltraStor 14F/34F: Copyright (C) 1994-2000 Dario Ballabio.\n");
+      printk("%s config options -> of:%c, lc:%c, mq:%d, et:%c.\n",
              driver_name, YESNO(have_old_firmware), YESNO(linked_comm),
-             max_queue_depth, YESNO(use_new_eh_code), YESNO(ext_tran));
+             max_queue_depth, YESNO(ext_tran));
       }
 
    printk("%s: %s 0x%03lx, BIOS 0x%05x, IRQ %u, %s, SG %d, MB %d.\n",
@@ -921,7 +919,6 @@ static void internal_setup(char *str, int *ints) {
       else if (!strncmp(cur, "of:", 3)) have_old_firmware = val;
       else if (!strncmp(cur, "mq:", 3))  max_queue_depth = val;
       else if (!strncmp(cur, "ls:", 3))  link_statistics = val;
-      else if (!strncmp(cur, "eh:", 3))  use_new_eh_code = val;
       else if (!strncmp(cur, "et:", 3))  ext_tran = val;
 
       if ((cur = strchr(cur, ','))) ++cur;
@@ -1112,79 +1109,6 @@ int u14_34f_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) {
    return rtn;
 }
 
-static inline int do_old_abort(Scsi_Cmnd *SCarg) {
-   unsigned int i, j;
-
-   j = ((struct hostdata *) SCarg->host->hostdata)->board_number;
-
-   if (SCarg->host_scribble == NULL ||
-       (SCarg->serial_number_at_timeout &&
-       (SCarg->serial_number != SCarg->serial_number_at_timeout))) {
-      printk("%s: abort, target %d.%d:%d, pid %ld inactive.\n",
-             BN(j), SCarg->channel, SCarg->target, SCarg->lun, SCarg->pid);
-      return SCSI_ABORT_NOT_RUNNING;
-      }
-
-   i = *(unsigned int *)SCarg->host_scribble;
-   printk("%s: abort, mbox %d, target %d.%d:%d, pid %ld.\n",
-          BN(j), i, SCarg->channel, SCarg->target, SCarg->lun, SCarg->pid);
-
-   if (i >= sh[j]->can_queue)
-      panic("%s: abort, invalid SCarg->host_scribble.\n", BN(j));
-
-   if (wait_on_busy(sh[j]->io_port, MAXLOOP)) {
-      printk("%s: abort, timeout error.\n", BN(j));
-      return SCSI_ABORT_ERROR;
-      }
-
-   if (HD(j)->cp_stat[i] == FREE) {
-      printk("%s: abort, mbox %d is free.\n", BN(j), i);
-      return SCSI_ABORT_NOT_RUNNING;
-      }
-
-   if (HD(j)->cp_stat[i] == IN_USE) {
-      printk("%s: abort, mbox %d is in use.\n", BN(j), i);
-
-      if (SCarg != HD(j)->cp[i].SCpnt)
-         panic("%s: abort, mbox %d, SCarg %p, cp SCpnt %p.\n",
-               BN(j), i, SCarg, HD(j)->cp[i].SCpnt);
-
-      if (inb(sh[j]->io_port + REG_SYS_INTR) & IRQ_ASSERTED)
-         printk("%s: abort, mbox %d, interrupt pending.\n", BN(j), i);
-
-      return SCSI_ABORT_SNOOZE;
-      }
-
-   if (HD(j)->cp_stat[i] == IN_RESET) {
-      printk("%s: abort, mbox %d is in reset.\n", BN(j), i);
-      return SCSI_ABORT_ERROR;
-      }
-
-   if (HD(j)->cp_stat[i] == LOCKED) {
-      printk("%s: abort, mbox %d is locked.\n", BN(j), i);
-      return SCSI_ABORT_NOT_RUNNING;
-      }
-
-   if (HD(j)->cp_stat[i] == READY || HD(j)->cp_stat[i] == ABORTING) {
-      SCarg->result = DID_ABORT << 16;
-      SCarg->host_scribble = NULL;
-      HD(j)->cp_stat[i] = FREE;
-      printk("%s, abort, mbox %d ready, DID_ABORT, pid %ld done.\n",
-             BN(j), i, SCarg->pid);
-      SCarg->scsi_done(SCarg);
-      return SCSI_ABORT_SUCCESS;
-      }
-
-   panic("%s: abort, mbox %d, invalid cp_stat.\n", BN(j), i);
-}
-
-int u14_34f_old_abort(Scsi_Cmnd *SCarg) {
-   int rtn;
-
-   rtn = do_old_abort(SCarg);
-   return rtn;
-}
-
 static inline int do_abort(Scsi_Cmnd *SCarg) {
    unsigned int i, j;
 
@@ -1262,152 +1186,6 @@ int u14_34f_abort(Scsi_Cmnd *SCarg) {
    return do_abort(SCarg);
 }
 
-static inline int do_old_reset(Scsi_Cmnd *SCarg) {
-   unsigned int i, j, time, k, c, limit = 0;
-   int arg_done = FALSE;
-   Scsi_Cmnd *SCpnt;
-
-   j = ((struct hostdata *) SCarg->host->hostdata)->board_number;
-   printk("%s: reset, enter, target %d.%d:%d, pid %ld.\n",
-          BN(j), SCarg->channel, SCarg->target, SCarg->lun, SCarg->pid);
-
-   if (SCarg->host_scribble == NULL)
-      printk("%s: reset, pid %ld inactive.\n", BN(j), SCarg->pid);
-
-   if (SCarg->serial_number_at_timeout &&
-       (SCarg->serial_number != SCarg->serial_number_at_timeout)) {
-      printk("%s: reset, pid %ld, reset not running.\n", BN(j), SCarg->pid);
-      return SCSI_RESET_NOT_RUNNING;
-      }
-
-   if (HD(j)->in_reset) {
-      printk("%s: reset, exit, already in reset.\n", BN(j));
-      return SCSI_RESET_ERROR;
-      }
-
-   if (wait_on_busy(sh[j]->io_port, MAXLOOP)) {
-      printk("%s: reset, exit, timeout error.\n", BN(j));
-      return SCSI_RESET_ERROR;
-      }
-
-   HD(j)->retries = 0;
-
-   for (c = 0; c <= sh[j]->max_channel; c++)
-      for (k = 0; k < sh[j]->max_id; k++) {
-         HD(j)->target_redo[k][c] = TRUE;
-         HD(j)->target_to[k][c] = 0;
-         }
-
-   for (i = 0; i < sh[j]->can_queue; i++) {
-
-      if (HD(j)->cp_stat[i] == FREE) continue;
-
-      if (HD(j)->cp_stat[i] == LOCKED) {
-         HD(j)->cp_stat[i] = FREE;
-         printk("%s: reset, locked mbox %d forced free.\n", BN(j), i);
-         continue;
-         }
-
-      if (!(SCpnt = HD(j)->cp[i].SCpnt))
-         panic("%s: reset, mbox %d, SCpnt == NULL.\n", BN(j), i);
-
-      if (HD(j)->cp_stat[i] == READY || HD(j)->cp_stat[i] == ABORTING) {
-         HD(j)->cp_stat[i] = ABORTING;
-         printk("%s: reset, mbox %d aborting, pid %ld.\n",
-                BN(j), i, SCpnt->pid);
-         }
-
-      else {
-         HD(j)->cp_stat[i] = IN_RESET;
-         printk("%s: reset, mbox %d in reset, pid %ld.\n",
-                BN(j), i, SCpnt->pid);
-         }
-
-      if (SCpnt->host_scribble == NULL)
-         panic("%s: reset, mbox %d, garbled SCpnt.\n", BN(j), i);
-
-      if (*(unsigned int *)SCpnt->host_scribble != i)
-         panic("%s: reset, mbox %d, index mismatch.\n", BN(j), i);
-
-      if (SCpnt->scsi_done == NULL)
-         panic("%s: reset, mbox %d, SCpnt->scsi_done == NULL.\n", BN(j), i);
-
-      if (SCpnt == SCarg) arg_done = TRUE;
-      }
-
-   if (wait_on_busy(sh[j]->io_port, MAXLOOP)) {
-      printk("%s: reset, cannot reset, timeout error.\n", BN(j));
-      return SCSI_RESET_ERROR;
-      }
-
-   outb(CMD_RESET, sh[j]->io_port + REG_LCL_INTR);
-   printk("%s: reset, board reset done, enabling interrupts.\n", BN(j));
-
-#if defined(DEBUG_RESET)
-   do_trace = TRUE;
-#endif
-
-   HD(j)->in_reset = TRUE;
-   SPIN_UNLOCK
-   time = jiffies;
-   while ((jiffies - time) < (10 * HZ) && limit++ < 200000) udelay(100L);
-   SPIN_LOCK
-   printk("%s: reset, interrupts disabled, loops %d.\n", BN(j), limit);
-
-   for (i = 0; i < sh[j]->can_queue; i++) {
-
-      if (HD(j)->cp_stat[i] == IN_RESET) {
-         SCpnt = HD(j)->cp[i].SCpnt;
-         SCpnt->result = DID_RESET << 16;
-         SCpnt->host_scribble = NULL;
-
-         /* This mailbox is still waiting for its interrupt */
-         HD(j)->cp_stat[i] = LOCKED;
-
-         printk("%s, reset, mbox %d locked, DID_RESET, pid %ld done.\n",
-                BN(j), i, SCpnt->pid);
-         }
-
-      else if (HD(j)->cp_stat[i] == ABORTING) {
-         SCpnt = HD(j)->cp[i].SCpnt;
-         SCpnt->result = DID_RESET << 16;
-         SCpnt->host_scribble = NULL;
-
-         /* This mailbox was never queued to the adapter */
-         HD(j)->cp_stat[i] = FREE;
-
-         printk("%s, reset, mbox %d aborting, DID_RESET, pid %ld done.\n",
-                BN(j), i, SCpnt->pid);
-         }
-
-      else
-
-         /* Any other mailbox has already been set free by interrupt */
-         continue;
-
-      SCpnt->scsi_done(SCpnt);
-      }
-
-   HD(j)->in_reset = FALSE;
-   do_trace = FALSE;
-
-   if (arg_done) {
-      printk("%s: reset, exit, success.\n", BN(j));
-      return SCSI_RESET_SUCCESS;
-      }
-   else {
-      printk("%s: reset, exit, wakeup.\n", BN(j));
-      return SCSI_RESET_PUNT;
-      }
-}
-
-int u14_34f_old_reset(Scsi_Cmnd *SCarg, unsigned int reset_flags) {
-   int rtn;
-
-   rtn = do_old_reset(SCarg);
-   return rtn;
-}
-
 static inline int do_reset(Scsi_Cmnd *SCarg) {
    unsigned int i, j, time, k, c, limit = 0;
    int arg_done = FALSE;
@@ -1663,7 +1441,7 @@ static inline int reorder(unsigned int j, unsigned long cursec,
 
    if (link_statistics) {
       if (cursec > sl[0]) iseek = cursec - sl[0]; else iseek = sl[0] - cursec;
-      batchcount++; readycount += n_ready, seeknosort += seek / 1024;
+      batchcount++; readycount += n_ready; seeknosort += seek / 1024;
       if (input_only) inputcount++;
       if (overlap) { ovlcount++; seeksorted += iseek / 1024; }
       else seeksorted += (iseek + maxsec - minsec) / 1024;
@@ -1837,7 +1615,9 @@ static inline void ihdlr(int irq, unsigned int j) {
          if (tstatus == GOOD)
             HD(j)->target_redo[SCpnt->target][SCpnt->channel] = FALSE;
 
-         if (spp->target_status && SCpnt->device->type == TYPE_DISK)
+         if (spp->target_status && SCpnt->device->type == TYPE_DISK &&
+             (!(tstatus == CHECK_CONDITION && HD(j)->iocount <= 1000 &&
+               (SCpnt->sense_buffer[2] & 0xf) == NOT_READY)))
             printk("%s: ihdlr, target %d.%d:%d, pid %ld, "\
                    "target_status 0x%x, sense key 0x%x.\n", BN(j),
                    SCpnt->channel, SCpnt->target, SCpnt->lun,
@@ -1969,13 +1749,5 @@ static Scsi_Host_Template driver_template = ULTRASTOR_14_34F;
 #include "scsi_module.c"
 
 #ifndef MODULE
-
-#if LINUX_VERSION_CODE < LinuxVersionCode(2,3,18)
-void u14_34f_setup(char *str, int *ints) {
-   internal_setup(str, ints);
-}
-#else
 __setup("u14-34f=", option_setup);
-#endif
-
 #endif /* end MODULE */
index ff49b56ead8d9231d7e95efe3e6d557544a63844..5e481ea403a9c569f392ae2d8c258b42b9e4e0b4 100644 (file)
@@ -5,30 +5,23 @@
 #define _U14_34F_H
 
 #include <scsi/scsicam.h>
-#include <linux/version.h>
 
 int u14_34f_detect(Scsi_Host_Template *);
 int u14_34f_release(struct Scsi_Host *);
 int u14_34f_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
 int u14_34f_abort(Scsi_Cmnd *);
-int u14_34f_old_abort(Scsi_Cmnd *);
 int u14_34f_reset(Scsi_Cmnd *);
-int u14_34f_old_reset(Scsi_Cmnd *, unsigned int);
 int u14_34f_biosparam(Disk *, kdev_t, int *);
 
-#define U14_34F_VERSION "5.11.00"
-
-#ifndef LinuxVersionCode
-#define LinuxVersionCode(v, p, s) (((v)<<16)+((p)<<8)+(s))
-#endif
+#define U14_34F_VERSION "6.02.00"
 
 #define ULTRASTOR_14_34F {                                                   \
                 name:         "UltraStor 14F/34F rev. " U14_34F_VERSION " ", \
                 detect:                  u14_34f_detect,                     \
                 release:                 u14_34f_release,                    \
                 queuecommand:            u14_34f_queuecommand,               \
-                abort:                   u14_34f_old_abort,                  \
-                reset:                   u14_34f_old_reset,                  \
+                abort:                   NULL,                               \
+                reset:                   NULL,                               \
                 eh_abort_handler:        u14_34f_abort,                      \
                 eh_device_reset_handler: NULL,                               \
                 eh_bus_reset_handler:    NULL,                               \
index 203c7d98038cae44bdbcaf443b5776063f6d5903..83e1319186be51cc9dbb332aa5f4c084e9949a53 100644 (file)
    /* This is what the 3393 chip looks like to us */
 typedef struct {
    volatile unsigned char   SASR;
+#if !defined(CONFIG_MVME147_SCSI)
    char                     pad;
+#endif
 #ifdef CONFIG_SGI_IP22
    char                     pad2,pad3;
 #endif
@@ -341,5 +343,6 @@ int wd33c93_queuecommand (Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *));
 void wd33c93_intr (struct Scsi_Host *instance);
 int wd33c93_proc_info(char *, char **, off_t, int, int, int);
 int wd33c93_reset (Scsi_Cmnd *, unsigned int);
+void wd33c93_release(void);
 
 #endif /* WD33C93_H */
index a10f9d2c2f2fe40af96f78e9a80cd137559ff1a8..5a4632a6bcc2a315f54d897586522e7552e8c3dc 100644 (file)
  * Changes:
  *     20000815        Updated driver to kernel 2.4, some cleanups/fixes
  *                     Nils Faerber <nils@kernelconcepts.de>
+ *
+ *     20000909        Changed cs_read, cs_write and drain_dac
+ *                     Nils Faerber <nils@kernelconcepts.de>
+ *
  *     20001110        Added __initdata to BA1Struct in cs461x_image.h
  *                     and three more __init here
  *                     Bartlomiej Zolnierkiewicz <bkz@linux-ide.org>
+ *
+ *     20001023        Ported to Linux 2.4 PCI interface, some cleanups
+ *                     Christoph Hellwig <hch@caldera.de>
+ *
  */
  
 #include <linux/module.h>
 
 #define GOF_PER_SEC    200
 
-/*
- * Define this to enable recording,
- * this is curently broken and using it will cause data corruption
- * in kernel- and user-space!
- */
-/* #define CS46XX_ENABLE_RECORD */
-
 static int external_amp = 0;
 static int thinkpad = 0;
 
 
-/* an instance of the 4610 channel */
+/* An instance of the 4610 channel */
 
 struct cs_channel 
 {
@@ -92,7 +93,7 @@ struct cs_channel
        void *state;
 };
 
-#define DRIVER_VERSION "0.09"
+#define DRIVER_VERSION "0.14"
 
 /* magic numbers to protect our data structures */
 #define CS_CARD_MAGIC          0x46524F4D /* "FROM" */
@@ -169,7 +170,7 @@ struct cs_card {
        unsigned int magic;
 
        /* We keep cs461x cards in a linked list */
-       struct cs_card *next;
+       struct list_head devs;
 
        /* The cs461x has a certain amount of cross channel interaction
           so we use a single per card lock */
@@ -220,7 +221,7 @@ struct cs_card {
        void (*free_pcm_channel)(struct cs_card *, int chan);
 };
 
-static struct cs_card *devs = NULL;
+static LIST_HEAD(devs);
 
 static int cs_open_mixdev(struct inode *inode, struct file *file);
 static int cs_release_mixdev(struct inode *inode, struct file *file);
@@ -787,7 +788,7 @@ static int drain_dac(struct cs_state *state, int nonblock)
 
                tmo = (dmabuf->dmasize * HZ) / dmabuf->rate;
                tmo >>= sample_shift[dmabuf->fmt];
-               tmo += (4096*HZ)/dmabuf->rate;
+               tmo += (2048*HZ)/dmabuf->rate;
 
                if (!schedule_timeout(tmo ? tmo : 1) && tmo){
                        printk(KERN_ERR "cs461x: drain_dac, dma timeout? %d\n", count);
@@ -844,8 +845,9 @@ static void cs_update_ptr(struct cs_state *state)
                                        memset (dmabuf->rawbuf + swptr, silence, clear_cnt);
                                        dmabuf->endcleared = 1;
                                }
-                       }                       
-                       wake_up(&dmabuf->wait);
+                       }
+                       if (dmabuf->count < (signed)dmabuf->dmasize/2)
+                               wake_up(&dmabuf->wait);
                }
        }
        /* error handling and process wake up for DAC */
@@ -864,7 +866,8 @@ static void cs_update_ptr(struct cs_state *state)
                                __stop_dac(state);
                                dmabuf->error++;
                        }
-                       wake_up(&dmabuf->wait);
+                       if (dmabuf->count < (signed)dmabuf->dmasize/2)
+                               wake_up(&dmabuf->wait);
                }
        }
 }
@@ -874,7 +877,7 @@ static void cs_record_interrupt(struct cs_state *state)
        memcpy(state->dmabuf.rawbuf + (2048*state->dmabuf.pringbuf++),
                state->dmabuf.pbuf+2048*state->dmabuf.ppingbuf++, 2048);
        state->dmabuf.ppingbuf&=1;
-       if(state->dmabuf.pringbuf > (PAGE_SIZE<<state->dmabuf.buforder)/2048)
+       if(state->dmabuf.pringbuf >= (PAGE_SIZE<<state->dmabuf.buforder)/2048)
                state->dmabuf.pringbuf=0;
        cs_update_ptr(state);
 }
@@ -929,6 +932,7 @@ static ssize_t cs_read(struct file *file, char *buffer, size_t count, loff_t *pp
 {
        struct cs_state *state = (struct cs_state *)file->private_data;
        struct dmabuf *dmabuf = &state->dmabuf;
+       DECLARE_WAITQUEUE(wait, current);
        ssize_t ret;
        unsigned long flags;
        unsigned swptr;
@@ -948,6 +952,7 @@ static ssize_t cs_read(struct file *file, char *buffer, size_t count, loff_t *pp
                return -EFAULT;
        ret = 0;
 
+       add_wait_queue(&state->dmabuf.wait, &wait);
        while (count > 0) {
                spin_lock_irqsave(&state->card->lock, flags);
                if (dmabuf->count > (signed) dmabuf->dmasize) {
@@ -960,49 +965,34 @@ static ssize_t cs_read(struct file *file, char *buffer, size_t count, loff_t *pp
                cnt = dmabuf->dmasize - swptr;
                if (dmabuf->count < cnt)
                        cnt = dmabuf->count;
+               if (cnt <= 0)
+                       __set_current_state(TASK_INTERRUPTIBLE);
                spin_unlock_irqrestore(&state->card->lock, flags);
 
                if (cnt > count)
                        cnt = count;
                if (cnt <= 0) {
-                       unsigned long tmo;
                        /* buffer is empty, start the dma machine and wait for data to be
                           recorded */
                        start_adc(state);
                        if (file->f_flags & O_NONBLOCK) {
-                               if (!ret) ret = -EAGAIN;
-                               return ret;
-                       }
-                       /* This isnt strictly right for the 810  but it'll do */
-                       tmo = (dmabuf->dmasize * HZ) / (dmabuf->rate * 2);
-                       tmo >>= sample_shift[dmabuf->fmt];
-                       /* There are two situations when sleep_on_timeout returns, one is when
-                          the interrupt is serviced correctly and the process is waked up by
-                          ISR ON TIME. Another is when timeout is expired, which means that
-                          either interrupt is NOT serviced correctly (pending interrupt) or it
-                          is TOO LATE for the process to be scheduled to run (scheduler latency)
-                          which results in a (potential) buffer overrun. And worse, there is
-                          NOTHING we can do to prevent it. */
-                       if (!interruptible_sleep_on_timeout(&dmabuf->wait, tmo)) {
-#ifdef DEBUG
-                               printk(KERN_ERR "cs461x: recording schedule timeout, "
-                                      "dmasz %u fragsz %u count %i hwptr %u swptr %u\n",
-                                      dmabuf->dmasize, dmabuf->fragsize, dmabuf->count,
-                                      dmabuf->hwptr, dmabuf->swptr);
-#endif
-                               /* a buffer overrun, we delay the recovery untill next time the
-                                  while loop begin and we REALLY have space to record */
+                               if (!ret)
+                                       ret = -EAGAIN;
+                               remove_wait_queue(&state->dmabuf.wait, &wait);
+                               break;
                        }
+                       schedule();
                        if (signal_pending(current)) {
                                ret = ret ? ret : -ERESTARTSYS;
-                               return ret;
+                               break;
                        }
                        continue;
                }
 
                if (copy_to_user(buffer, dmabuf->rawbuf + swptr, cnt)) {
-                       if (!ret) ret = -EFAULT;
-                       return ret;
+                       if (!ret)
+                               ret = -EFAULT;
+                       break;
                }
 
                swptr = (swptr + cnt) % dmabuf->dmasize;
@@ -1017,6 +1007,8 @@ static ssize_t cs_read(struct file *file, char *buffer, size_t count, loff_t *pp
                ret += cnt;
                start_adc(state);
        }
+       remove_wait_queue(&state->dmabuf.wait, &wait);
+       set_current_state(TASK_RUNNING);
        return ret;
 }
 
@@ -1026,7 +1018,8 @@ static ssize_t cs_write(struct file *file, const char *buffer, size_t count, lof
 {
        struct cs_state *state = (struct cs_state *)file->private_data;
        struct dmabuf *dmabuf = &state->dmabuf;
-       ssize_t ret;
+       DECLARE_WAITQUEUE(wait, current);
+       ssize_t ret = 0;
        unsigned long flags;
        unsigned swptr;
        int cnt;
@@ -1043,8 +1036,8 @@ static ssize_t cs_write(struct file *file, const char *buffer, size_t count, lof
                return ret;
        if (!access_ok(VERIFY_READ, buffer, count))
                return -EFAULT;
-       ret = 0;
 
+       add_wait_queue(&state->dmabuf.wait, &wait);
        while (count > 0) {
                spin_lock_irqsave(&state->card->lock, flags);
                if (dmabuf->count < 0) {
@@ -1057,48 +1050,34 @@ static ssize_t cs_write(struct file *file, const char *buffer, size_t count, lof
                cnt = dmabuf->dmasize - swptr;
                if (dmabuf->count + cnt > dmabuf->dmasize)
                        cnt = dmabuf->dmasize - dmabuf->count;
+               if (cnt <= 0)
+                       __set_current_state(TASK_INTERRUPTIBLE);
                spin_unlock_irqrestore(&state->card->lock, flags);
 
                if (cnt > count)
                        cnt = count;
                if (cnt <= 0) {
-                       unsigned long tmo;
                        /* buffer is full, start the dma machine and wait for data to be
                           played */
                        start_dac(state);
                        if (file->f_flags & O_NONBLOCK) {
-                               if (!ret) ret = -EAGAIN;
-                               return ret;
-                       }
-                       /* Not strictly correct but works */
-                       tmo = (dmabuf->dmasize * HZ) / (dmabuf->rate * 2);
-                       tmo >>= sample_shift[dmabuf->fmt];
-                       /* There are two situations when sleep_on_timeout returns, one is when
-                          the interrupt is serviced correctly and the process is waked up by
-                          ISR ON TIME. Another is when timeout is expired, which means that
-                          either interrupt is NOT serviced correctly (pending interrupt) or it
-                          is TOO LATE for the process to be scheduled to run (scheduler latency)
-                          which results in a (potential) buffer underrun. And worse, there is
-                          NOTHING we can do to prevent it. */
-                       if (!interruptible_sleep_on_timeout(&dmabuf->wait, tmo)) {
-#ifdef DEBUG
-                               printk(KERN_ERR "cs461x: playback schedule timeout, "
-                                      "dmasz %u fragsz %u count %i hwptr %u swptr %u\n",
-                                      dmabuf->dmasize, dmabuf->fragsize, dmabuf->count,
-                                      dmabuf->hwptr, dmabuf->swptr);
-#endif
-                               /* a buffer underrun, we delay the recovery untill next time the
-                                  while loop begin and we REALLY have data to play */
+                               if (!ret)
+                                       ret = -EAGAIN;
+                               remove_wait_queue(&state->dmabuf.wait, &wait);
+                               break;
                        }
+                       schedule();
                        if (signal_pending(current)) {
-                               if (!ret) ret = -ERESTARTSYS;
-                               return ret;
+                               if (!ret)
+                                       ret = -ERESTARTSYS;
+                               break;
                        }
                        continue;
                }
                if (copy_from_user(dmabuf->rawbuf + swptr, buffer, cnt)) {
-                       if (!ret) ret = -EFAULT;
-                       return ret;
+                       if (!ret)
+                               ret = -EFAULT;
+                       break;
                }
 
                swptr = (swptr + cnt) % dmabuf->dmasize;
@@ -1149,10 +1128,17 @@ static unsigned int cs_poll(struct file *file, struct poll_table_struct *wait)
        return mask;
 }
 
+
+/*
+ * We let users mmap the ring buffer. Its not the real DMA buffer but
+ * that side of the code is hidden in the IRQ handling. We do a software
+ * emulation of DMA from a 64K or so buffer into a 2K FIFO.
+ * (the hardware probably deserves a moan here but Crystal send me nice
+ * toys ;)).
+ */
+
 static int cs_mmap(struct file *file, struct vm_area_struct *vma)
 {
-       return -EINVAL;
-#if 0  
        struct cs_state *state = (struct cs_state *)file->private_data;
        struct dmabuf *dmabuf = &state->dmabuf;
        int ret;
@@ -1168,7 +1154,7 @@ static int cs_mmap(struct file *file, struct vm_area_struct *vma)
        } else 
                return -EINVAL;
 
-       if (vma->vm_offset != 0)
+       if (vma->vm_pgoff != 0)
                return -EINVAL;
        size = vma->vm_end - vma->vm_start;
        if (size > (PAGE_SIZE << dmabuf->buforder))
@@ -1179,7 +1165,6 @@ static int cs_mmap(struct file *file, struct vm_area_struct *vma)
        dmabuf->mapped = 1;
 
        return 0;
-#endif 
 }
 
 static int cs_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
@@ -1503,7 +1488,7 @@ static void amp_none(struct cs_card *card, int change)
 
 static void amp_voyetra(struct cs_card *card, int change)
 {
-       /* Manage the EAPD bit on the Crystal 4297 */
+       /* Manage the EAPD bit on the Crystal 4297 and the Analog AD1885 */
        int old=card->amplifier;
 
        card->amplifier+=change;
@@ -1524,7 +1509,6 @@ static void amp_voyetra(struct cs_card *card, int change)
 }
 
 
-
 /*
  *     Untested
  */
@@ -1532,7 +1516,6 @@ static void amp_voyetra(struct cs_card *card, int change)
 static void amp_voyetra_4294(struct cs_card *card, int change)
 {
        struct ac97_codec *c=card->ac97_codec[0];
-       int old = card->amplifier;
 
        card->amplifier+=change;
 
@@ -1593,17 +1576,20 @@ static void clkrun_hack(struct cs_card *card, int change)
 static int cs_open(struct inode *inode, struct file *file)
 {
        int i = 0;
-       struct cs_card *card = devs;
+       struct cs_card *card;
        struct cs_state *state = NULL;
        struct dmabuf *dmabuf = NULL;
+       struct list_head *list;
 
 #ifndef CS46XX_ENABLE_RECORD
        if (file->f_mode & FMODE_READ)
                return -ENODEV;
 #endif
 
-       /* find an avaiable virtual channel (instance of /dev/dsp) */
-       while (card != NULL) {
+       for (list = devs.next; ; list = list->next) {
+               if (list == &devs)
+                       return -ENODEV;
+               card = list_entry(list, struct cs_card, devs);
                for (i = 0; i < NR_HW_CH; i++) {
                        if (card->states[i] == NULL) {
                                state = card->states[i] = (struct cs_state *)
@@ -1622,7 +1608,6 @@ static int cs_open(struct inode *inode, struct file *file)
                                goto found_virt;
                        }
                }
-               card = card->next;
        }
        /* no more virtual channel avaiable */
        if (!state)
@@ -1841,7 +1826,11 @@ static void cs_ac97_set(struct ac97_codec *dev, u8 reg, u16 val)
 {
        struct cs_card *card = dev->private_data;
        int count;
+       int val2;
        
+       if (reg == AC97_CD_VOL)
+               val2 = cs_ac97_get(dev, AC97_CD_VOL);
+
        /*
         *  1. Write ACCAD = Command Address Register = 46Ch for AC97 register address
         *  2. Write ACCDA = Command Data Register = 470h    for data to write to AC97
@@ -1883,6 +1872,44 @@ static void cs_ac97_set(struct ac97_codec *dev, u8 reg, u16 val)
         */
        if (cs461x_peekBA0(card, BA0_ACCTL) & ACCTL_DCV)
                printk(KERN_WARNING "cs461x: AC'97 write problem, reg = 0x%x, val = 0x%x\n", reg, val);
+
+       /*
+        *      Adjust power if the mixer is selected/deselected according
+        *      to the CD.
+        *
+        *      IF the CD is a valid input source (mixer or direct) AND
+        *              the CD is not muted THEN power is needed
+        *
+        *      We do two things. When record select changes the input to
+        *      add/remove the CD we adjust the power count if the CD is
+        *      unmuted.
+        *
+        *      When the CD mute changes we adjust the power level if the
+        *      CD was a valid input.
+        *
+        *      We also check for CD volume != 0, as the CD mute isn't
+        *      normally tweaked from userspace.
+        */
+
+       /* CD mute change ? */
+       if (reg == AC97_CD_VOL) {
+               /* Mute bit change ? */
+               if ((val2^val) & 0x8000 || ((val2 == 0x1f1f || val == 0x1f1f) && val2 != val)) {
+                       /* This is a hack but its cleaner than the alternatives.
+                          Right now card->ac97_codec[0] might be NULL as we are
+                          still doing codec setup. This does an early assignment
+                          to avoid the problem if it occurs */
+
+                       if (card->ac97_codec[0] == NULL)
+                               card->ac97_codec[0] = dev;
+
+                       /* Mute on */
+                       if(val & 0x8000 || val == 0x1f1f)
+                               card->amplifier_ctrl(card, -1);
+                       else /* Mute off power on */
+                               card->amplifier_ctrl(card, 1);
+               }
+       }
 }
 
 
@@ -1892,13 +1919,19 @@ static int cs_open_mixdev(struct inode *inode, struct file *file)
 {
        int i;
        int minor = MINOR(inode->i_rdev);
-       struct cs_card *card = devs;
+       struct cs_card *card;
+       struct list_head *list;
 
-       for (card = devs; card != NULL; card = card->next)
+       for (list = devs.next; ; list = list->next) {
+               if (list == &devs)
+                       return -ENODEV;
+               card = list_entry(list, struct cs_card, devs);
                for (i = 0; i < NR_AC97; i++)
                        if (card->ac97_codec[i] != NULL &&
                            card->ac97_codec[i]->dev_mixer == minor)
                                goto match;
+       }
+
 
        if (!card)
                return -ENODEV;
@@ -1907,28 +1940,31 @@ static int cs_open_mixdev(struct inode *inode, struct file *file)
        file->private_data = card->ac97_codec[i];
 
        card->active_ctrl(card,1);
-       MOD_INC_USE_COUNT;
        return 0;
 }
 
 static int cs_release_mixdev(struct inode *inode, struct file *file)
 {
        int minor = MINOR(inode->i_rdev);
-       struct cs_card *card = devs;
+       struct cs_card *card;
+       struct list_head *list;
        int i;
-
-       for (card = devs; card != NULL; card = card->next)
+       
+       for (list = devs.next; ; list = list->next) {
+               if (list == &devs)
+                       return -ENODEV;
+               card = list_entry(list, struct cs_card, devs);
                for (i = 0; i < NR_AC97; i++)
                        if (card->ac97_codec[i] != NULL &&
                            card->ac97_codec[i]->dev_mixer == minor)
                                goto match;
+       }
 
        if (!card)
                return -ENODEV;
 match:
        card->active_ctrl(card, -1);
 
-       MOD_DEC_USE_COUNT;
        return 0;
 }
 
@@ -2269,7 +2305,7 @@ static int __init cs_hardware_init(struct cs_card *card)
          *  for a reset.
          */
         cs461x_pokeBA0(card, BA0_ACCTL, 0);
-        udelay(500);
+        udelay(50);
         cs461x_pokeBA0(card, BA0_ACCTL, ACCTL_RSTN);
 
        /*
@@ -2284,7 +2320,7 @@ static int __init cs_hardware_init(struct cs_card *card)
         *  generating bit clock (so we don't try to start the PLL without an
         *  input clock).
         */
-       mdelay(10);             /* 1 should be enough ?? */
+       mdelay(5);              /* 1 should be enough ?? */
 
        /*
         *  Set the serial port timing configuration, so that
@@ -2309,7 +2345,7 @@ static int __init cs_hardware_init(struct cs_card *card)
        /*
          *  Wait until the PLL has stabilized.
         */
-       mdelay(100);            /* Again 1 should be enough ?? */
+       mdelay(5);              /* Again 1 should be enough ?? */
 
        /*
         *  Turn on clocking of the core so that we can setup the serial ports.
@@ -2472,8 +2508,7 @@ static int __init cs_hardware_init(struct cs_card *card)
  *     Card subid table
  */
 
-struct cs_card_type
-{
+struct cs_card_type {
        u16 vendor;
        u16 id;
        char *name;
@@ -2481,7 +2516,7 @@ struct cs_card_type
        void (*active)(struct cs_card *, int);
 };
 
-static struct cs_card_type __initdata cards[]={
+static struct cs_card_type __devinitdata cards[]={
        {0x1489, 0x7001, "Genius Soundmaker 128 value", amp_none, NULL},
        {0x5053, 0x3357, "Voyetra", amp_voyetra, NULL},
        /* MI6020/21 use the same chipset as the Thinkpads, maybe needed */
@@ -2490,18 +2525,14 @@ static struct cs_card_type __initdata cards[]={
        {PCI_VENDOR_ID_IBM, 0x0132, "Thinkpad 570", amp_none, clkrun_hack},
        {PCI_VENDOR_ID_IBM, 0x0153, "Thinkpad 600X/A20/T20", amp_none, clkrun_hack},
        {PCI_VENDOR_ID_IBM, 0x1010, "Thinkpad 600E (unsupported)", NULL, NULL},
+       {0, 0, "Card without SSID set", NULL, NULL },
        {0, 0, NULL, NULL, NULL}
 };
 
-static int __init cs_install(struct pci_dev *pci_dev)
+static int __devinit cs_probe(struct pci_dev * pci_dev, const struct pci_device_id * id)
 {
        struct cs_card *card;
        struct cs_card_type *cp = &cards[0];
-       u16 ss_card, ss_vendor;
-
-
-       pci_read_config_word(pci_dev, PCI_SUBSYSTEM_VENDOR_ID, &ss_vendor);
-       pci_read_config_word(pci_dev, PCI_SUBSYSTEM_ID, &ss_card);
 
        if ((card = kmalloc(sizeof(struct cs_card), GFP_KERNEL)) == NULL) {
                printk(KERN_ERR "cs461x: out of memory\n");
@@ -2509,8 +2540,8 @@ static int __init cs_install(struct pci_dev *pci_dev)
        }
        memset(card, 0, sizeof(*card));
 
-       card->ba0_addr = pci_dev->resource[0].start&PCI_BASE_ADDRESS_MEM_MASK;
-       card->ba1_addr = pci_dev->resource[1].start&PCI_BASE_ADDRESS_MEM_MASK;
+       card->ba0_addr = pci_resource_start(pci_dev, 0);
+       card->ba1_addr = pci_resource_start(pci_dev, 1);
        card->pci_dev = pci_dev;
        card->irq = pci_dev->irq;
        card->magic = CS_CARD_MAGIC;
@@ -2529,7 +2560,7 @@ static int __init cs_install(struct pci_dev *pci_dev)
 
        while(cp->name)
        {
-               if(cp->vendor == ss_vendor && cp->id == ss_card)
+               if(cp->vendor == id->subvendor && cp->id == id->subdevice)
                {
                        card->amplifier_ctrl = cp->amp;
                        if(cp->active)
@@ -2541,7 +2572,7 @@ static int __init cs_install(struct pci_dev *pci_dev)
        if(cp->name==NULL)
        {
        printk(KERN_INFO "cs461x: Unknown card (%04X:%04X) at 0x%08lx/0x%08lx, IRQ %d\n",
-               ss_vendor, ss_card, card->ba0_addr, card->ba1_addr,  card->irq);
+               id->subvendor, id->subdevice, card->ba0_addr, card->ba1_addr,  card->irq);
        }
        else
        {
@@ -2598,9 +2629,11 @@ static int __init cs_install(struct pci_dev *pci_dev)
                unregister_sound_dsp(card->dev_audio);
                goto fail;
        }
-       card->next = devs;
-       devs = card;
-       
+
+       pci_set_drvdata (pci_dev, card);
+
+       list_add_tail(&card->devs, &devs);
+
        card->active_ctrl(card, -1);
        return 0;
        
@@ -2622,11 +2655,13 @@ fail2:
 
 }
 
-static void cs_remove(struct cs_card *card)
+static void __devexit cs_remove(struct pci_dev * pci_dev)
 {
+       struct cs_card * card = pci_get_drvdata (pci_dev);
        int i;
        unsigned int tmp;
-       
+
+       list_del(&card->devs);
        card->active_ctrl(card,1);
 
        tmp = cs461x_peek(card, BA1_PFIE);
@@ -2698,57 +2733,39 @@ static void cs_remove(struct cs_card *card)
 
 MODULE_AUTHOR("Alan Cox <alan@redhat.com>, Jaroslav Kysela");
 MODULE_DESCRIPTION("Crystal SoundFusion Audio Support");
+MODULE_PARM(external_amp, "i");
+MODULE_PARM(thinkpad, "i");
+
+static struct pci_device_id cs_pci_tbl[] __devinitdata = {
+       { PCI_VENDOR_ID_CIRRUS, 0x6001, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
+       { PCI_VENDOR_ID_CIRRUS, 0x6003, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
+       { PCI_VENDOR_ID_CIRRUS, 0x6004, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
+       { 0, }
+};
+MODULE_DEVICE_TABLE (pci, cs_pci_tbl);
+
+static struct pci_driver cs_pci_driver = {
+       name:           "cs46xx",
+       id_table:       cs_pci_tbl,
+       probe:          cs_probe,
+       remove:         cs_remove,
+};
 
-int __init cs_probe(void)
+static int __init cs_init(void)
 {
-       struct pci_dev *pcidev = NULL;
        int foundone=0;
        
-       if (!pci_present())   /* No PCI bus in this machine! */
-               return -ENODEV;
-               
        printk(KERN_INFO "Crystal 4280/461x + AC97 Audio, version "
               DRIVER_VERSION ", " __TIME__ " " __DATE__ "\n");
 
-       while( (pcidev = pci_find_device(PCI_VENDOR_ID_CIRRUS, 0x6001 , pcidev))!=NULL ) {
-               if (cs_install(pcidev)==0)
-                       foundone++;
-       }
-       while( (pcidev = pci_find_device(PCI_VENDOR_ID_CIRRUS, 0x6003 , pcidev))!=NULL ) {
-               if (cs_install(pcidev)==0)
-                       foundone++;
-       }
-       while( (pcidev = pci_find_device(PCI_VENDOR_ID_CIRRUS, 0x6004 , pcidev))!=NULL ) {
-               if (cs_install(pcidev)==0)
-                       foundone++;
-       }
-
-       printk(KERN_INFO "cs461x: Found %d audio device(s).\n",
-               foundone);
-       return foundone;
+       return pci_module_init(&cs_pci_driver);
 }
 
-#ifdef MODULE
-
-int init_module(void)
+static void __exit cs_exit(void)
 {
-       if(cs_probe()==0)
-               printk(KERN_ERR "cs461x: No devices found.\n");
-       return 0;
+       pci_unregister_driver(&cs_pci_driver);
 }
 
-void cleanup_module (void)
-{
-       struct cs_card *next;
-       while(devs)
-       {
-               next=devs->next;
-               cs_remove(devs);
-               devs=next;
-       }
-}
+module_init(cs_init);
+module_exit(cs_exit);
 
-MODULE_PARM(external_amp, "i");
-MODULE_PARM(thinkpad, "i");
-
-#endif
index faf00d79868b4e60728a6692740e65abb5de3858..0845ecd522ba3dcc60cea3d4249267f6642664cc 100644 (file)
@@ -816,7 +816,7 @@ static void AtaRelease(void)
 
 static void *AtaAlloc(unsigned int size, int flags)
 {
-       return atari_stram_alloc( size, NULL, "dmasound" );
+       return atari_stram_alloc(size, "dmasound");
 }
 
 static void AtaFree(void *obj, unsigned int size)
index 18f6be2d031d5862b480bfd1ceb7353700360141..d76c079371d23fad509fd26626a75f3b0d3a2339 100644 (file)
@@ -27,8 +27,6 @@
    /*
     *  The minimum period for audio depends on htotal (for OCS/ECS/AGA)
     *  (Imported from arch/m68k/amiga/amisound.c)
-    *
-    *  FIXME: if amifb is not used, there should be a method to change htotal
     */
 
 extern volatile u_short amiga_audio_min_period;
index ca96b7f995cc4397d6b7c0eab16edab229d5f0a2..6013b2ec23c5b9d4694875a36b6986cd3ec2e5fb 100644 (file)
@@ -1958,6 +1958,7 @@ mixer_push_state(struct ess_card *card)
 static int mixer_ioctl(struct ess_card *card, unsigned int cmd, unsigned long arg)
 {
        int i, val=0;
+       unsigned long flags;
 
        VALIDATE_CARD(card);
         if (cmd == SOUND_MIXER_INFO) {
@@ -1990,9 +1991,9 @@ static int mixer_ioctl(struct ess_card *card, unsigned int cmd, unsigned long ar
                        if(!card->mix.recmask_io) {
                                val = 0;
                        } else {
-                               spin_lock(&card->lock);
+                               spin_lock_irqsave(&card->lock, flags);
                                val = card->mix.recmask_io(card,1,0);
-                               spin_unlock(&card->lock);
+                               spin_unlock_irqrestore(&card->lock, flags);
                        }
                        break;
                        
@@ -2019,9 +2020,9 @@ static int mixer_ioctl(struct ess_card *card, unsigned int cmd, unsigned long ar
                                return -EINVAL;
 
                        /* do we ever want to touch the hardware? */
-/*                     spin_lock(&card->lock);
+/*                     spin_lock_irqsave(&card->lock, flags);
                        val = card->mix.read_mixer(card,i);
-                       spin_unlock(&card->lock);*/
+                       spin_unlock_irqrestore(&card->lock, flags);*/
 
                        val = card->mix.mixer_state[i];
 /*                     M_printk("returned 0x%x for mixer %d\n",val,i);*/
@@ -2046,9 +2047,9 @@ static int mixer_ioctl(struct ess_card *card, unsigned int cmd, unsigned long ar
                if(!val) return 0;
                if(! (val &= card->mix.record_sources)) return -EINVAL;
 
-               spin_lock(&card->lock);
+               spin_lock_irqsave(&card->lock, flags);
                card->mix.recmask_io(card,0,val);
-               spin_unlock(&card->lock);
+               spin_unlock_irqrestore(&card->lock, flags);
                return 0;
 
        default:
@@ -2057,9 +2058,9 @@ static int mixer_ioctl(struct ess_card *card, unsigned int cmd, unsigned long ar
                if ( ! supported_mixer(card,i)) 
                        return -EINVAL;
 
-               spin_lock(&card->lock);
+               spin_lock_irqsave(&card->lock, flags);
                set_mixer(card,i,val);
-               spin_unlock(&card->lock);
+               spin_unlock_irqrestore(&card->lock, flags);
 
                return 0;
        }
@@ -3392,6 +3393,19 @@ maestro_install(struct pci_dev *pcidev, int card_type)
        
        ess = &card->channels[0];
 
+       if (pci_enable_device(pcidev)) {
+               printk (KERN_ERR "maestro: pci_enable_device() failed\n");
+               for (i = 0; i < NR_DSPS; i++) {
+                       struct ess_state *s = &card->channels[i];
+                       if (s->dev_audio != -1)
+                               unregister_sound_dsp(s->dev_audio);
+               }
+               release_region(card->iobase, 256);
+               unregister_reboot_notifier(&maestro_nb);
+               kfree(card);
+               return 0;
+       }
+
        /*
         *      Ok card ready. Begin setup proper
         */
index d4feefa211e772af039f4fb7a72d65235caecd83..e263e6a6d239a24f03d569870af6af261f310463 100644 (file)
@@ -25,56 +25,16 @@ comment 'USB Controllers'
    fi
    dep_tristate '  OHCI (Compaq, iMacs, OPTi, SiS, ALi, ...) support' CONFIG_USB_OHCI $CONFIG_USB
 
-comment 'USB Devices'
-   dep_tristate '  USB Printer support' CONFIG_USB_PRINTER $CONFIG_USB
-   dep_tristate '  USB Scanner support' CONFIG_USB_SCANNER $CONFIG_USB
-   if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-      dep_tristate '  Microtek X6USB scanner support (EXPERIMENTAL)' CONFIG_USB_MICROTEK $CONFIG_USB $CONFIG_SCSI
-   fi
+   comment 'USB Device Class drivers'
    dep_tristate '  USB Audio support' CONFIG_USB_AUDIO $CONFIG_USB $CONFIG_SOUND
-   dep_tristate '  USB Modem (CDC ACM) support' CONFIG_USB_ACM $CONFIG_USB
-   dep_tristate '  USB Serial Converter support' CONFIG_USB_SERIAL $CONFIG_USB
-   if [ "$CONFIG_USB_SERIAL" != "n" ]; then
-      bool '    USB Generic Serial Driver' CONFIG_USB_SERIAL_GENERIC
-      dep_tristate '    USB Handspring Visor Driver' CONFIG_USB_SERIAL_VISOR $CONFIG_USB_SERIAL
-      dep_tristate '    USB Digi International AccelePort USB Serial Driver' CONFIG_USB_SERIAL_DIGI_ACCELEPORT $CONFIG_USB_SERIAL
-      if [ "$CONFIG_EXPERIMENTAL" != "n" ]; then
-         dep_tristate '    USB ConnectTech WhiteHEAT Serial Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_WHITEHEAT $CONFIG_USB_SERIAL
-         dep_tristate '    USB FTDI Single Port Serial Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_FTDI_SIO $CONFIG_USB_SERIAL
-         dep_tristate '    USB Keyspan PDA Single Port Serial Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_KEYSPAN_PDA $CONFIG_USB_SERIAL
-         dep_tristate '    USB Keyspan USA-xxx Serial Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_KEYSPAN $CONFIG_USB_SERIAL
-         if [ "$CONFIG_USB_SERIAL_KEYSPAN" != "n" ]; then
-            bool '      USB Keyspan USA-28 Firmware' CONFIG_USB_SERIAL_KEYSPAN_USA28
-            bool '      USB Keyspan USA-28X Firmware' CONFIG_USB_SERIAL_KEYSPAN_USA28X
-            bool '      USB Keyspan USA-19 Firmware' CONFIG_USB_SERIAL_KEYSPAN_USA19
-            bool '      USB Keyspan USA-18X Firmware' CONFIG_USB_SERIAL_KEYSPAN_USA18X
-            bool '      USB Keyspan USA-19W Firmware' CONFIG_USB_SERIAL_KEYSPAN_USA19W
-         fi
-         dep_tristate '    USB ZyXEL omni.net LCD Plus Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_OMNINET $CONFIG_USB_SERIAL
-         dep_tristate '    USB Belkin and Peracom Single Port Serial Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_BELKIN $CONFIG_USB_SERIAL
-      fi
-      bool '    USB Serial Converter verbose debug' CONFIG_USB_SERIAL_DEBUG
-   fi
-   dep_tristate '  USB IBM (Xirlink) C-it Camera support' CONFIG_USB_IBMCAM $CONFIG_USB $CONFIG_VIDEO_DEV
-   dep_tristate '  USB OV511 Camera support' CONFIG_USB_OV511 $CONFIG_USB $CONFIG_VIDEO_DEV
-   dep_tristate '  USB Kodak DC-2xx Camera support' CONFIG_USB_DC2XX $CONFIG_USB
-   if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-          dep_tristate '  USB Mustek MDC800 Digital Camera support (EXPERIMENTAL)' CONFIG_USB_MDC800 $CONFIG_USB
-   fi
+   dep_tristate '  USB Bluetooth support (EXPERIMENTAL)' CONFIG_USB_BLUETOOTH $CONFIG_USB $CONFIG_EXPERIMENTAL
    dep_tristate '  USB Mass Storage support' CONFIG_USB_STORAGE $CONFIG_USB $CONFIG_SCSI
    if [ "$CONFIG_USB_STORAGE" != "n" ]; then
       bool '    USB Mass Storage verbose debug' CONFIG_USB_STORAGE_DEBUG
+      bool '    Freecom USB/ATAPI Bridge support' CONFIG_USB_STORAGE_FREECOM
    fi
-   dep_tristate '  USS720 parport driver' CONFIG_USB_USS720 $CONFIG_USB $CONFIG_PARPORT
-   dep_tristate '  DABUSB driver' CONFIG_USB_DABUSB $CONFIG_USB
-   if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-      dep_tristate '  PLUSB Prolific USB-Network driver (EXPERIMENTAL)' CONFIG_USB_PLUSB $CONFIG_USB $CONFIG_NET
-      dep_tristate '  USB ADMtek Pegasus-based ethernet device support (EXPERIMENTAL)' CONFIG_USB_PEGASUS $CONFIG_USB $CONFIG_NET
-      dep_tristate '  USB Diamond Rio500 support (EXPERIMENTAL)' CONFIG_USB_RIO500 $CONFIG_USB
-      dep_tristate '  D-Link USB FM radio support (EXPERIMENTAL)' CONFIG_USB_DSBR $CONFIG_USB $CONFIG_VIDEO_DEV
-      dep_tristate '  USB Bluetooth support (EXPERIMENTAL)' CONFIG_USB_BLUETOOTH $CONFIG_USB
-      dep_tristate '  NetChip 1080-based USB Host-to-Host Link (EXPERIMENTAL)' CONFIG_USB_NET1080 $CONFIG_USB $CONFIG_NET
-   fi
+   dep_tristate '  USB Modem (CDC ACM) support' CONFIG_USB_ACM $CONFIG_USB
+   dep_tristate '  USB Printer support' CONFIG_USB_PRINTER $CONFIG_USB
 
    comment 'USB Human Interface Devices (HID)'
    if [ "$CONFIG_INPUT" = "n" ]; then
@@ -87,6 +47,30 @@ comment 'USB Devices'
       fi
       dep_tristate '  Wacom Intuos/Graphire tablet support' CONFIG_USB_WACOM $CONFIG_USB $CONFIG_INPUT
    fi
+
+   comment 'USB Imaging devices'
+   dep_tristate '  USB Kodak DC-2xx Camera support' CONFIG_USB_DC2XX $CONFIG_USB
+   dep_tristate '  USB Mustek MDC800 Digital Camera support (EXPERIMENTAL)' CONFIG_USB_MDC800 $CONFIG_USB $CONFIG_EXPERIMENTAL
+   dep_tristate '  USB Scanner support' CONFIG_USB_SCANNER $CONFIG_USB
+   dep_tristate '  Microtek X6USB scanner support (EXPERIMENTAL)' CONFIG_USB_MICROTEK $CONFIG_USB $CONFIG_SCSI $CONFIG_EXPERIMENTAL
+
+   comment 'USB Multimedia devices'
+   dep_tristate '  USB IBM (Xirlink) C-it Camera support' CONFIG_USB_IBMCAM $CONFIG_USB $CONFIG_VIDEO_DEV
+   dep_tristate '  USB OV511 Camera support' CONFIG_USB_OV511 $CONFIG_USB $CONFIG_VIDEO_DEV
+   dep_tristate '  D-Link USB FM radio support (EXPERIMENTAL)' CONFIG_USB_DSBR $CONFIG_USB $CONFIG_VIDEO_DEV $CONFIG_EXPERIMENTAL
+   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 '  NetChip 1080-based USB Host-to-Host Link (EXPERIMENTAL)' CONFIG_USB_NET1080 $CONFIG_USB $CONFIG_NET $CONFIG_EXPERIMENTAL
+
+   comment 'USB port drivers'
+   dep_tristate '  USS720 parport driver' CONFIG_USB_USS720 $CONFIG_USB $CONFIG_PARPORT
+   source drivers/usb/serial/Config.in
+
+   comment 'USB misc drivers'
+   dep_tristate '  USB Diamond Rio500 support (EXPERIMENTAL)' CONFIG_USB_RIO500 $CONFIG_USB $CONFIG_EXPERIMENTAL
 fi
 
 endmenu
diff --git a/drivers/usb/serial/Config.in b/drivers/usb/serial/Config.in
new file mode 100644 (file)
index 0000000..db77957
--- /dev/null
@@ -0,0 +1,29 @@
+#
+# USB Serial device configuration
+#
+mainmenu_option next_comment
+comment 'USB Serial Converter support'
+
+tristate 'USB Serial Converter support' CONFIG_USB_SERIAL $CONFIG_USB
+if [ "$CONFIG_USB_SERIAL" != "n" ]; then
+  bool '  USB Serial Converter verbose debug' CONFIG_USB_SERIAL_DEBUG
+  bool '  USB Generic Serial Driver' CONFIG_USB_SERIAL_GENERIC
+  dep_tristate '  USB Belkin and Peracom Single Port Serial Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_BELKIN $CONFIG_USB_SERIAL $CONFIG_EXPERIMENTAL
+  dep_tristate '  USB ConnectTech WhiteHEAT Serial Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_WHITEHEAT $CONFIG_USB_SERIAL $CONFIG_EXPERIMENTAL
+  dep_tristate '  USB Digi International AccelePort USB Serial Driver' CONFIG_USB_SERIAL_DIGI_ACCELEPORT $CONFIG_USB_SERIAL
+  dep_tristate '  USB Empeg empeg-car Mark I/II Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_EMPEG $CONFIG_USB_SERIAL $CONFIG_EXPERIMENTAL
+  dep_tristate '  USB FTDI Single Port Serial Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_FTDI_SIO $CONFIG_USB_SERIAL $CONFIG_EXPERIMENTAL
+  dep_tristate '  USB Handspring Visor Driver' CONFIG_USB_SERIAL_VISOR $CONFIG_USB_SERIAL
+  dep_tristate '  USB Keyspan PDA Single Port Serial Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_KEYSPAN_PDA $CONFIG_USB_SERIAL $CONFIG_EXPERIMENTAL
+  dep_tristate '  USB Keyspan USA-xxx Serial Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_KEYSPAN $CONFIG_USB_SERIAL $CONFIG_EXPERIMENTAL
+  if [ "$CONFIG_USB_SERIAL_KEYSPAN" != "n" ]; then
+     bool '    USB Keyspan USA-28 Firmware' CONFIG_USB_SERIAL_KEYSPAN_USA28
+     bool '    USB Keyspan USA-28X Firmware' CONFIG_USB_SERIAL_KEYSPAN_USA28X
+     bool '    USB Keyspan USA-19 Firmware' CONFIG_USB_SERIAL_KEYSPAN_USA19
+     bool '    USB Keyspan USA-18X Firmware' CONFIG_USB_SERIAL_KEYSPAN_USA18X
+     bool '    USB Keyspan USA-19W Firmware' CONFIG_USB_SERIAL_KEYSPAN_USA19W
+  fi
+  dep_tristate '  USB ZyXEL omni.net LCD Plus Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_OMNINET $CONFIG_USB_SERIAL $CONFIG_EXPERIMENTAL
+fi
+
+endmenu
index b90d4f52dcb0b5139915b0d7ac0c994319b097bb..0fc7143045e9b494121fb08d7485c6eea9b7d355 100644 (file)
@@ -22,6 +22,7 @@ obj-$(CONFIG_USB_SERIAL_KEYSPAN)              += keyspan.o
 obj-$(CONFIG_USB_SERIAL_OMNINET)               += omninet.o
 obj-$(CONFIG_USB_SERIAL_DIGI_ACCELEPORT)       += digi_acceleport.o
 obj-$(CONFIG_USB_SERIAL_BELKIN)                        += belkin_sa.o
+obj-$(CONFIG_USB_SERIAL_EMPEG)                 += empeg.o
  
 # Objects that export symbols.
 export-objs    := usbserial.o
diff --git a/drivers/usb/serial/empeg.c b/drivers/usb/serial/empeg.c
new file mode 100644 (file)
index 0000000..a22694d
--- /dev/null
@@ -0,0 +1,635 @@
+/*
+ * USB Empeg empeg-car player driver
+ *
+ *     Copyright (C) 2000
+ *         Gary Brubaker (xavyer@ix.netcom.com)
+ *
+ *     Copyright (C) 1999, 2000
+ *         Greg Kroah-Hartman (greg@kroah.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, version 2.
+ *
+ * See Documentation/usb/usb-serial.txt for more information on using this driver
+ * 
+ * (11/13/2000) gb
+ *     Moved tty->low_latency = 1 from empeg_read_bulk_callback() to empeg_open()
+ *     (It only needs to be set once - Doh!)
+ * 
+ * (11/11/2000) gb
+ *     Updated to work with id_table structure.
+ * 
+ * (11/04/2000) gb
+ *     Forked this from visor.c, and hacked it up to work with an
+ *     Empeg ltd. empeg-car player.  Constructive criticism welcomed.
+ *     I would like to say, 'Thank You' to Greg Kroah-Hartman for the
+ *     use of his code, and for his guidance, advice and patience. :)
+ *     A 'Thank You' is in order for John Ripley of Empeg ltd for his
+ *     advice, and patience too.
+ * 
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/signal.h>
+#include <linux/errno.h>
+#include <linux/poll.h>
+#include <linux/init.h>
+#include <linux/malloc.h>
+#include <linux/fcntl.h>
+#include <linux/tty_driver.h>
+#include <linux/tty_flip.h>
+#include <linux/tty.h>
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#ifdef CONFIG_USB_SERIAL_DEBUG
+       #define DEBUG
+#else
+       #undef DEBUG
+#endif
+#include <linux/usb.h>
+
+#include "usb-serial.h"
+
+#define EMPEG_VENDOR_ID                 0x084f
+#define EMPEG_PRODUCT_ID                0x0001
+
+#define MIN(a,b)               (((a)<(b))?(a):(b))
+
+/* function prototypes for an empeg-car player */
+static int  empeg_open         (struct usb_serial_port *port, struct file *filp);
+static void empeg_close                (struct usb_serial_port *port, struct file *filp);
+static int  empeg_write                (struct usb_serial_port *port, int from_user, const unsigned char *buf, int count);
+static void empeg_throttle     (struct usb_serial_port *port);
+static void empeg_unthrottle   (struct usb_serial_port *port);
+static int  empeg_startup      (struct usb_serial *serial);
+static void empeg_shutdown     (struct usb_serial *serial);
+static int  empeg_ioctl                (struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg);
+static void empeg_set_termios  (struct usb_serial_port *port, struct termios *old_termios);
+static void empeg_write_bulk_callback  (struct urb *urb);
+static void empeg_read_bulk_callback   (struct urb *urb);
+
+static __devinitdata struct usb_device_id id_table [] = {
+        { idVendor: EMPEG_VENDOR_ID, idProduct: EMPEG_PRODUCT_ID },
+        { }                                     /* Terminating entry */
+};
+
+MODULE_DEVICE_TABLE (usb, id_table);
+
+struct usb_serial_device_type empeg_device = {
+       name:                   "Empeg",
+       id_table:               id_table,
+       needs_interrupt_in:     MUST_HAVE_NOT,  /* must not have an interrupt in endpoint */
+       needs_bulk_in:          MUST_HAVE,      /* must have a bulk in endpoint */
+       needs_bulk_out:         MUST_HAVE,      /* must have a bulk out endpoint */
+       num_interrupt_in:       0,
+       num_bulk_in:            1,
+       num_bulk_out:           1,
+       num_ports:              1,
+       open:                   empeg_open,
+       close:                  empeg_close,
+       throttle:               empeg_throttle,
+       unthrottle:             empeg_unthrottle,
+       startup:                empeg_startup,
+       shutdown:               empeg_shutdown,
+       ioctl:                  empeg_ioctl,
+       set_termios:            empeg_set_termios,
+       write:                  empeg_write,
+       write_bulk_callback:    empeg_write_bulk_callback,
+       read_bulk_callback:     empeg_read_bulk_callback,
+};
+
+#define NUM_URBS                       16
+#define URB_TRANSFER_BUFFER_SIZE       4096
+
+static struct urb      *write_urb_pool[NUM_URBS];
+static spinlock_t      write_urb_pool_lock;
+static int             bytes_in;
+static int             bytes_out;
+
+/******************************************************************************
+ * Empeg specific driver functions
+ ******************************************************************************/
+static int empeg_open (struct usb_serial_port *port, struct file *filp)
+{
+       struct usb_serial *serial = port->serial;
+       unsigned long flags;
+       int result;
+
+       if (port_paranoia_check (port, __FUNCTION__))
+               return -ENODEV;
+
+       dbg(__FUNCTION__ " - port %d", port->number);
+
+       spin_lock_irqsave (&port->port_lock, flags);
+
+       ++port->open_count;
+       MOD_INC_USE_COUNT;
+
+       /* gb - 2000/11/05
+        *
+        * personally, I think these termios should be set in
+        * empeg_startup(), but it appears doing so leads to one
+        * of those chicken/egg problems. :)
+        *
+        */
+       port->tty->termios->c_iflag
+               &= ~(IGNBRK
+               | BRKINT
+               | PARMRK
+               | ISTRIP
+               | INLCR
+               | IGNCR
+               | ICRNL
+               | IXON);
+
+       port->tty->termios->c_oflag
+               &= ~OPOST;
+
+       port->tty->termios->c_lflag
+               &= ~(ECHO
+               | ECHONL
+               | ICANON
+               | ISIG
+               | IEXTEN);
+
+       port->tty->termios->c_cflag
+               &= ~(CSIZE
+               | PARENB);
+
+       port->tty->termios->c_cflag
+               |= CS8;
+
+       /* gb - 2000/11/05
+        *
+        * force low_latency on
+        *
+        * The tty_flip_buffer_push()'s in empeg_read_bulk_callback() will actually
+        * force the data through if low_latency is set.  Otherwise the pushes are
+        * scheduled; this is bad as it opens up the possibility of dropping bytes
+        * on the floor.  We are trying to sustain high data transfer rates; and
+        * don't want to drop bytes on the floor.
+        * Moral: use low_latency - drop no bytes - life is good. :)
+        *
+        */
+       port->tty->low_latency = 1;
+
+       if (!port->active) {
+               port->active = 1;
+               bytes_in = 0;
+               bytes_out = 0;
+
+               /* Start reading from the device */
+               FILL_BULK_URB(
+                       port->read_urb,
+                       serial->dev, 
+                       usb_rcvbulkpipe(serial->dev,
+                               port->bulk_in_endpointAddress),
+                       port->read_urb->transfer_buffer,
+                       port->read_urb->transfer_buffer_length,
+                       empeg_read_bulk_callback,
+                       port);
+
+               port->read_urb->transfer_flags |= USB_QUEUE_BULK;
+
+               result = usb_submit_urb(port->read_urb);
+
+               if (result)
+                       err(__FUNCTION__ " - failed submitting read urb, error %d", result);
+
+       }
+
+       spin_unlock_irqrestore (&port->port_lock, flags);
+
+       return 0;
+}
+
+
+static void empeg_close (struct usb_serial_port *port, struct file * filp)
+{
+       struct usb_serial *serial;
+       unsigned char *transfer_buffer;
+       unsigned long flags;
+
+       if (port_paranoia_check (port, __FUNCTION__))
+               return;
+
+       dbg(__FUNCTION__ " - port %d", port->number);
+
+       serial = get_usb_serial (port, __FUNCTION__);
+       if (!serial)
+               return;
+
+       spin_lock_irqsave (&port->port_lock, flags);
+
+       --port->open_count;
+       MOD_DEC_USE_COUNT;
+
+       if (port->open_count <= 0) {
+               transfer_buffer =  kmalloc (0x12, GFP_KERNEL);
+
+               if (!transfer_buffer) {
+                       err(__FUNCTION__ " - kmalloc(%d) failed.", 0x12);
+               } else {
+                       kfree (transfer_buffer);
+               }
+
+               /* shutdown our bulk read */
+               usb_unlink_urb (port->read_urb);
+               port->active = 0;
+               port->open_count = 0;
+       }
+
+       spin_unlock_irqrestore (&port->port_lock, flags);
+
+       /* Uncomment the following line if you want to see some statistics in your syslog */
+       /* info ("Bytes In = %d  Bytes Out = %d", bytes_in, bytes_out); */
+
+}
+
+
+static int empeg_write (struct usb_serial_port *port, int from_user, const unsigned char *buf, int count)
+{
+       struct usb_serial *serial = port->serial;
+       struct urb *urb;
+       const unsigned char *current_position = buf;
+       unsigned long flags;
+       int status;
+       int i;
+       int bytes_sent = 0;
+       int transfer_size;
+
+       dbg(__FUNCTION__ " - port %d", port->number);
+
+       usb_serial_debug_data (__FILE__, __FUNCTION__, count, buf);
+
+       while (count > 0) {
+
+               /* try to find a free urb in our list of them */
+               urb = NULL;
+
+               spin_lock_irqsave (&write_urb_pool_lock, flags);
+
+               for (i = 0; i < NUM_URBS; ++i) {
+                       if (write_urb_pool[i]->status != -EINPROGRESS) {
+                               urb = write_urb_pool[i];
+                               break;
+                       }
+               }
+
+               spin_unlock_irqrestore (&write_urb_pool_lock, flags);
+
+               if (urb == NULL) {
+                       dbg (__FUNCTION__ " - no more free urbs");
+                       goto exit;
+               }
+
+               if (urb->transfer_buffer == NULL) {
+                       urb->transfer_buffer = kmalloc (URB_TRANSFER_BUFFER_SIZE, GFP_KERNEL);
+                       if (urb->transfer_buffer == NULL) {
+                               err(__FUNCTION__" no more kernel memory...");
+                               goto exit;
+                       }
+               }
+
+               transfer_size = MIN (count, URB_TRANSFER_BUFFER_SIZE);
+
+               if (from_user) {
+                       copy_from_user (urb->transfer_buffer, current_position, transfer_size);
+               } else {
+                       memcpy (urb->transfer_buffer, current_position, transfer_size);
+               }
+
+               count = (count > port->bulk_out_size) ? port->bulk_out_size : count;
+
+               /* build up our urb */
+               FILL_BULK_URB (
+                       urb,
+                       serial->dev,
+                       usb_sndbulkpipe(serial->dev,
+                               port->bulk_out_endpointAddress), 
+                       urb->transfer_buffer,
+                       transfer_size,
+                       empeg_write_bulk_callback,
+                       port);
+
+               urb->transfer_flags |= USB_QUEUE_BULK;
+
+               /* send it down the pipe */
+               status = usb_submit_urb(urb);
+               if (status)
+                       dbg(__FUNCTION__ " - usb_submit_urb(write bulk) failed with status = %d", status);
+
+               current_position += transfer_size;
+               bytes_sent += transfer_size;
+               count -= transfer_size;
+               bytes_out += transfer_size;
+
+       }
+
+exit:
+       return bytes_sent;
+
+} 
+
+
+static void empeg_write_bulk_callback (struct urb *urb)
+{
+       struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
+
+       if (port_paranoia_check (port, __FUNCTION__))
+               return;
+
+       dbg(__FUNCTION__ " - port %d", port->number);
+
+       if (urb->status) {
+               dbg(__FUNCTION__ " - nonzero write bulk status received: %d", urb->status);
+               return;
+       }
+
+       queue_task(&port->tqueue, &tq_immediate);
+       mark_bh(IMMEDIATE_BH);
+
+       return;
+
+}
+
+
+static void empeg_read_bulk_callback (struct urb *urb)
+{
+       struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
+       struct usb_serial *serial = get_usb_serial (port, __FUNCTION__);
+       struct tty_struct *tty;
+       unsigned char *data = urb->transfer_buffer;
+       int i;
+       int result;
+
+       if (port_paranoia_check (port, __FUNCTION__))
+               return;
+
+       dbg(__FUNCTION__ " - port %d", port->number);
+
+       if (!serial) {
+               dbg(__FUNCTION__ " - bad serial pointer, exiting");
+               return;
+       }
+
+       if (urb->status) {
+               dbg(__FUNCTION__ " - nonzero read bulk status received: %d", urb->status);
+               return;
+       }
+
+       usb_serial_debug_data (__FILE__, __FUNCTION__, urb->actual_length, data);
+
+       tty = port->tty;
+
+       if (urb->actual_length) {
+               for (i = 0; i < urb->actual_length ; ++i) {
+                       /* gb - 2000/11/13
+                        * If we insert too many characters we'll overflow the buffer.
+                        * This means we'll lose bytes - Decidedly bad.
+                        */
+                       if(tty->flip.count >= TTY_FLIPBUF_SIZE) {
+                               tty_flip_buffer_push(tty);
+                               }
+                       /* gb - 2000/11/13
+                        * This doesn't push the data through unless tty->low_latency is set.
+                        */
+                       tty_insert_flip_char(tty, data[i], 0);
+               }
+               /* gb - 2000/11/13
+                * Goes straight through instead of scheduling - if tty->low_latency is set.
+                */
+               tty_flip_buffer_push(tty);
+               bytes_in += urb->actual_length;
+       }
+
+       /* Continue trying to always read  */
+       FILL_BULK_URB(
+               port->read_urb,
+               serial->dev, 
+               usb_rcvbulkpipe(serial->dev,
+                       port->bulk_in_endpointAddress),
+               port->read_urb->transfer_buffer,
+               port->read_urb->transfer_buffer_length,
+               empeg_read_bulk_callback,
+               port);
+
+       port->read_urb->transfer_flags |= USB_QUEUE_BULK;
+
+       result = usb_submit_urb(port->read_urb);
+
+       if (result)
+               err(__FUNCTION__ " - failed resubmitting read urb, error %d", result);
+
+       return;
+
+}
+
+
+static void empeg_throttle (struct usb_serial_port *port)
+{
+       unsigned long flags;
+
+       dbg(__FUNCTION__ " - port %d", port->number);
+
+       spin_lock_irqsave (&port->port_lock, flags);
+
+       usb_unlink_urb (port->read_urb);
+
+       spin_unlock_irqrestore (&port->port_lock, flags);
+
+       return;
+
+}
+
+
+static void empeg_unthrottle (struct usb_serial_port *port)
+{
+       unsigned long flags;
+       int result;
+
+       dbg(__FUNCTION__ " - port %d", port->number);
+
+       spin_lock_irqsave (&port->port_lock, flags);
+
+       port->read_urb->dev = port->serial->dev;
+
+       result = usb_submit_urb(port->read_urb);
+
+       if (result)
+               err(__FUNCTION__ " - failed submitting read urb, error %d", result);
+
+       spin_unlock_irqrestore (&port->port_lock, flags);
+
+       return;
+
+}
+
+
+static int  empeg_startup (struct usb_serial *serial)
+{
+
+       dbg(__FUNCTION__);
+
+       dbg(__FUNCTION__ " - Set config to 1");
+       usb_set_configuration (serial->dev, 1);
+
+       /* continue on with initialization */
+       return 0;
+
+}
+
+
+static void empeg_shutdown (struct usb_serial *serial)
+{
+       int i;
+
+       dbg (__FUNCTION__);
+
+       /* stop reads and writes on all ports */
+       for (i=0; i < serial->num_ports; ++i) {
+               while (serial->port[i].open_count > 0) {
+                       empeg_close (&serial->port[i], NULL);
+               }
+       }
+
+}
+
+
+static int empeg_ioctl (struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg)
+{
+       dbg(__FUNCTION__ " - port %d, cmd 0x%.4x", port->number, cmd);
+
+       return -ENOIOCTLCMD;
+}
+
+
+/* This function is all nice and good, but we don't change anything based on it :) */
+static void empeg_set_termios (struct usb_serial_port *port, struct termios *old_termios)
+{
+       unsigned int cflag = port->tty->termios->c_cflag;
+
+       dbg(__FUNCTION__ " - port %d", port->number);
+
+       /* check that they really want us to change something */
+       if (old_termios) {
+               if ((cflag == old_termios->c_cflag) &&
+                   (RELEVANT_IFLAG(port->tty->termios->c_iflag) == RELEVANT_IFLAG(old_termios->c_iflag))) {
+                       dbg(__FUNCTION__ " - nothing to change...");
+                       return;
+               }
+       }
+
+       if ((!port->tty) || (!port->tty->termios)) {
+               dbg(__FUNCTION__" - no tty structures");
+               return;
+       }
+
+       /* get the byte size */
+       switch (cflag & CSIZE) {
+               case CS5:       dbg(__FUNCTION__ " - data bits = 5");   break;
+               case CS6:       dbg(__FUNCTION__ " - data bits = 6");   break;
+               case CS7:       dbg(__FUNCTION__ " - data bits = 7");   break;
+               default:
+               case CS8:       dbg(__FUNCTION__ " - data bits = 8");   break;
+       }
+
+       /* determine the parity */
+       if (cflag & PARENB)
+               if (cflag & PARODD)
+                       dbg(__FUNCTION__ " - parity = odd");
+               else
+                       dbg(__FUNCTION__ " - parity = even");
+       else
+               dbg(__FUNCTION__ " - parity = none");
+
+       /* figure out the stop bits requested */
+       if (cflag & CSTOPB)
+               dbg(__FUNCTION__ " - stop bits = 2");
+       else
+               dbg(__FUNCTION__ " - stop bits = 1");
+
+       /* figure out the flow control settings */
+       if (cflag & CRTSCTS)
+               dbg(__FUNCTION__ " - RTS/CTS is enabled");
+       else
+               dbg(__FUNCTION__ " - RTS/CTS is disabled");
+
+       /* determine software flow control */
+       if (I_IXOFF(port->tty))
+               dbg(__FUNCTION__ " - XON/XOFF is enabled, XON = %2x, XOFF = %2x", START_CHAR(port->tty), STOP_CHAR(port->tty));
+       else
+               dbg(__FUNCTION__ " - XON/XOFF is disabled");
+
+       /* get the baud rate wanted */
+       dbg(__FUNCTION__ " - baud rate = %d", tty_get_baud_rate(port->tty));
+
+       return;
+
+}
+
+
+static int __init empeg_init (void)
+{
+       struct urb *urb;
+       int i;
+
+       usb_serial_register (&empeg_device);
+
+       /* create our write urb pool and transfer buffers */ 
+       spin_lock_init (&write_urb_pool_lock);
+       for (i = 0; i < NUM_URBS; ++i) {
+               urb = usb_alloc_urb(0);
+               write_urb_pool[i] = urb;
+               if (urb == NULL) {
+                       err("No more urbs???");
+                       continue;
+               }
+
+               urb->transfer_buffer = NULL;
+               urb->transfer_buffer = kmalloc (URB_TRANSFER_BUFFER_SIZE, GFP_KERNEL);
+               if (!urb->transfer_buffer) {
+                       err (__FUNCTION__ " - out of memory for urb buffers.");
+                       continue;
+               }
+       }
+
+       return 0;
+
+}
+
+
+static void __exit empeg_exit (void)
+{
+       int i;
+       unsigned long flags;
+
+       usb_serial_deregister (&empeg_device);
+
+       spin_lock_irqsave (&write_urb_pool_lock, flags);
+
+       for (i = 0; i < NUM_URBS; ++i) {
+               if (write_urb_pool[i]) {
+                       /* FIXME - uncomment the following usb_unlink_urb call when
+                        * the host controllers get fixed to set urb->dev = NULL after
+                        * the urb is finished.  Otherwise this call oopses. */
+                       /* usb_unlink_urb(write_urb_pool[i]); */
+                       if (write_urb_pool[i]->transfer_buffer)
+                               kfree(write_urb_pool[i]->transfer_buffer);
+                       usb_free_urb (write_urb_pool[i]);
+               }
+       }
+
+       spin_unlock_irqrestore (&write_urb_pool_lock, flags);
+
+}
+
+
+module_init(empeg_init);
+module_exit(empeg_exit);
+
+MODULE_AUTHOR("Gary Brubaker <xavyer@ix.netcom.com>");
+MODULE_DESCRIPTION("USB Empeg Mark I/II Driver");
index c078704f0d88884ca7125c917c4ef517d9bf084c..ee1b73893ded53c092b037cc5e1e91a9dabc5a6d 100644 (file)
  *
  * See Documentation/usb/usb-serial.txt for more information on using this driver
  * 
+ * (11/12/2000) gkh
+ *     Fixed bug with data being dropped on the floor by forcing tty->low_latency
+ *     to be on.  Hopefully this fixes the OHCI issue!
+ *
  * (11/01/2000) Adam J. Richter
  *     usb_device_id table support
  * 
@@ -171,6 +175,11 @@ static int visor_open (struct usb_serial_port *port, struct file *filp)
                bytes_in = 0;
                bytes_out = 0;
 
+               /* force low_latency on so that our tty_push actually forces the data through, 
+                  otherwise it is scheduled, and with high data rates (like with OHCI) data
+                  can get lost. */
+               port->tty->low_latency = 1;
+               
                /* Start reading from the device */
                FILL_BULK_URB(port->read_urb, serial->dev, 
                              usb_rcvbulkpipe(serial->dev, port->bulk_in_endpointAddress),
@@ -348,6 +357,11 @@ static void visor_read_bulk_callback (struct urb *urb)
        tty = port->tty;
        if (urb->actual_length) {
                for (i = 0; i < urb->actual_length ; ++i) {
+                       /* if we insert more than TTY_FLIPBUF_SIZE characters, we drop them. */
+                       if(tty->flip.count >= TTY_FLIPBUF_SIZE) {
+                               tty_flip_buffer_push(tty);
+                       }
+                       /* this doesn't actually push the data through unless tty->low_latency is set */
                        tty_insert_flip_char(tty, data[i], 0);
                }
                tty_flip_buffer_push(tty);
index 0a0d32f690f1ee53bd403ed6853209a75114af28..e671ee3e491edaa24c59f6432546fccb4c59d1a2 100644 (file)
@@ -8,6 +8,10 @@
  * (C) Copyright 1999 Deti Fliegl, deti@fliegl.de
  * (C) Copyright 1999 Thomas Sailer, sailer@ife.ee.ethz.ch
  * (C) Copyright 1999 Roman Weissgaerber, weissg@vienna.at
+ * (C) Copyright 2000 Yggdrasil Computing, Inc. (port of new PCI interface
+ *               support from usb-ohci.c by Adam Richter, adam@yggdrasil.com).
+ * (C) Copyright 1999 Gregory P. Smith (from usb-ohci.c)
+ *
  *
  * Intel documents this fairly well, and as far as I know there
  * are no royalties or anything like that, but even so there are
@@ -46,7 +50,6 @@
 #include "uhci-debug.h"
 
 #include <linux/pm.h>
-static int handle_pm_event(struct pm_dev *dev, pm_request_t rqst, void *data);
 
 static int debug = 1;
 MODULE_PARM(debug, "i");
@@ -56,8 +59,6 @@ static kmem_cache_t *uhci_td_cachep;
 static kmem_cache_t *uhci_qh_cachep;
 static kmem_cache_t *uhci_up_cachep;   /* urb_priv */
 
-static LIST_HEAD(uhci_list);
-
 static int rh_submit_urb(struct urb *urb);
 static int rh_unlink_urb(struct urb *urb);
 static int uhci_get_current_frame_number(struct usb_device *dev);
@@ -2343,9 +2344,7 @@ static int setup_uhci(struct pci_dev *dev, int irq, unsigned int io_addr, unsign
        uhci = alloc_uhci(io_addr, io_size);
        if (!uhci)
                return -ENOMEM;
-
-       INIT_LIST_HEAD(&uhci->uhci_list);
-       list_add(&uhci->uhci_list, &uhci_list);
+       dev->driver_data = uhci;
 
        request_region(uhci->io_addr, io_size, "usb-uhci");
 
@@ -2358,21 +2357,11 @@ static int setup_uhci(struct pci_dev *dev, int irq, unsigned int io_addr, unsign
        if (request_irq(irq, uhci_interrupt, SA_SHIRQ, "usb-uhci", uhci) == 0) {
                uhci->irq = irq;
 
-               if (!uhci_start_root_hub(uhci)) {
-                       struct pm_dev *pmdev;
-
-                       pmdev = pm_register(PM_PCI_DEV,
-                                           PM_PCI_ID(dev),
-                                           handle_pm_event);
-                       if (pmdev)
-                               pmdev->data = uhci;
+               if (!uhci_start_root_hub(uhci))
                        return 0;
-               }
        }
 
        /* Couldn't allocate IRQ if we got here */
-       list_del(&uhci->uhci_list);
-       INIT_LIST_HEAD(&uhci->uhci_list);
 
        reset_hc(uhci);
        release_region(uhci->io_addr, uhci->io_size);
@@ -2381,7 +2370,8 @@ static int setup_uhci(struct pci_dev *dev, int irq, unsigned int io_addr, unsign
        return retval;
 }
 
-static int found_uhci(struct pci_dev *dev)
+static int __devinit
+uhci_pci_probe (struct pci_dev *dev, const struct pci_device_id *id)
 {
        int i;
 
@@ -2389,11 +2379,11 @@ static int found_uhci(struct pci_dev *dev)
        pci_write_config_word(dev, USBLEGSUP, USBLEGSUP_DEFAULT);
 
        if (pci_enable_device(dev) < 0)
-               return -1;
+               return -ENODEV;
 
        if (!dev->irq) {
                err("found UHCI device with no IRQ assigned. check BIOS settings!");
-               return -1;
+               return -ENODEV;
        }
 
        /* Search for the IO base address.. */
@@ -2412,29 +2402,76 @@ static int found_uhci(struct pci_dev *dev)
                return setup_uhci(dev, dev->irq, io_addr, io_size);
        }
 
-       return -1;
+       return -ENODEV;
 }
 
-static int handle_pm_event(struct pm_dev *dev, pm_request_t rqst, void *data)
+static void __devexit
+uhci_pci_remove (struct pci_dev *dev)
 {
-       struct uhci *uhci = dev->data;
-       switch (rqst) {
-       case PM_SUSPEND:
-               reset_hc(uhci);
-               break;
-       case PM_RESUME:
-               reset_hc(uhci);
-               start_hc(uhci);
-               break;
-       }
-       return 0;
+       struct uhci *uhci = dev->driver_data;
+
+       if (uhci->bus->root_hub)
+               usb_disconnect(&uhci->bus->root_hub);
+
+       usb_deregister_bus(uhci->bus);
+
+       reset_hc(uhci);
+       release_region(uhci->io_addr, uhci->io_size);
+
+       uhci_free_pending_qhs(uhci);
+
+       release_uhci(uhci);
+}
+
+static void
+uhci_pci_suspend (struct pci_dev *dev)
+{
+       reset_hc((struct uhci *) dev->driver_data);
 }
 
-static int __init uhci_init(void)
+static void
+uhci_pci_resume (struct pci_dev *dev)
+{
+       reset_hc((struct uhci *) dev->driver_data);
+       start_hc((struct uhci *) dev->driver_data);
+}
+
+/*-------------------------------------------------------------------------*/
+
+static const struct pci_device_id __devinitdata uhci_pci_ids [] = { {
+
+       /* handle any USB UHCI controller */
+       class:          ((PCI_CLASS_SERIAL_USB << 8) | 0x00),
+       class_mask:     ~0,
+
+       /* no matter who makes it */
+       vendor:         PCI_ANY_ID,
+       device:         PCI_ANY_ID,
+       subvendor:      PCI_ANY_ID,
+       subdevice:      PCI_ANY_ID,
+
+       }, { /* end: all zeroes */ }
+};
+
+MODULE_DEVICE_TABLE (pci, uhci_pci_ids);
+
+static struct pci_driver uhci_pci_driver = {
+       name:           "usb-uhci",
+       id_table:       &uhci_pci_ids [0],
+
+       probe:          uhci_pci_probe,
+       remove:         uhci_pci_remove,
+
+#ifdef CONFIG_PM
+       suspend:        uhci_pci_suspend,
+       resume:         uhci_pci_resume,
+#endif /* PM */
+};
+
+static int __init uhci_hcd_init(void)
 {
        int retval;
-       struct pci_dev *dev;
-       u8 type;
 
        retval = -ENOMEM;
 
@@ -2461,25 +2498,8 @@ static int __init uhci_init(void)
        if (!uhci_up_cachep)
                goto up_failed;
 
-       retval = -ENODEV;
-       dev = NULL;
-       for (;;) {
-               dev = pci_find_class(PCI_CLASS_SERIAL_USB << 8, dev);
-               if (!dev)
-                       break;
-
-               /* Is it the UHCI programming interface? */
-               pci_read_config_byte(dev, PCI_CLASS_PROG, &type);
-               if (type != 0)
-                       continue;
-
-               /* Ok set it up */
-               retval = found_uhci(dev);
-       }
-
-       /* We only want to return an error code if ther was an error */
-       /*  and we didn't find a UHCI controller */
-       if (retval && list_empty(&uhci_list))
+       retval = pci_module_init (&uhci_pci_driver);
+       if (retval)
                goto init_failed;
 
        return 0;
@@ -2500,32 +2520,10 @@ td_failed:
        return retval;
 }
 
-void uhci_cleanup(void)
+static void __exit uhci_hcd_cleanup (void) 
 {
-       struct list_head *tmp, *head = &uhci_list;
-
-       tmp = head->next;
-       while (tmp != head) {
-               struct uhci *uhci = list_entry(tmp, struct uhci, uhci_list);
-
-               tmp = tmp->next;
-
-               list_del(&uhci->uhci_list);
-               INIT_LIST_HEAD(&uhci->uhci_list);
-
-               if (uhci->bus->root_hub)
-                       usb_disconnect(&uhci->bus->root_hub);
-
-               usb_deregister_bus(uhci->bus);
-
-               reset_hc(uhci);
-               release_region(uhci->io_addr, uhci->io_size);
-
-               uhci_free_pending_qhs(uhci);
-
-               release_uhci(uhci);
-       }
-
+       pci_unregister_driver (&uhci_pci_driver);
+       
        if (kmem_cache_destroy(uhci_up_cachep))
                printk(KERN_INFO "uhci: not all urb_priv's were freed\n");
 
@@ -2536,14 +2534,8 @@ void uhci_cleanup(void)
                printk(KERN_INFO "uhci: not all TD's were freed\n");
 }
 
-static void __exit uhci_exit(void)
-{
-       pm_unregister_all(handle_pm_event);
-       uhci_cleanup();
-}
-
-module_init(uhci_init);
-module_exit(uhci_exit);
+module_init(uhci_hcd_init);
+module_exit(uhci_hcd_cleanup);
 
 MODULE_AUTHOR("Linus Torvalds, Johannes Erdfelt, Randy Dunlap, Georg Acher, Deti Fliegl, Thomas Sailer, Roman Weissgaerber");
 MODULE_DESCRIPTION("USB Universal Host Controller Interface driver");
index 5b1b76003c5827ff204ed1ea59ff478a3031fd13..1b41717dbc3f39a33700e4128ac38587c8f18523 100644 (file)
@@ -296,11 +296,13 @@ void usb_claim_bandwidth (struct usb_device *dev, struct urb *urb, int bustime,
        else
                dev->bus->bandwidth_int_reqs++;
        urb->bandwidth = bustime;
-       
+
+#ifdef USB_BANDWIDTH_MESSAGES
        dbg("bandwidth alloc increased by %d to %d for %d requesters",
                bustime,
                dev->bus->bandwidth_allocated,
                dev->bus->bandwidth_int_reqs + dev->bus->bandwidth_isoc_reqs);
+#endif
 }
 
 /*
@@ -316,10 +318,12 @@ void usb_release_bandwidth(struct usb_device *dev, struct urb *urb, int isoc)
        else
                dev->bus->bandwidth_int_reqs--;
 
+#ifdef USB_BANDWIDTH_MESSAGES
        dbg("bandwidth alloc reduced by %d to %d for %d requesters",
                urb->bandwidth,
                dev->bus->bandwidth_allocated,
                dev->bus->bandwidth_int_reqs + dev->bus->bandwidth_isoc_reqs);
+#endif
        urb->bandwidth = 0;
 }
 
index af813ceab430d9bc85bb21e15bc33754b65f46bc..ac6e08ae959182d887bdb6e243196d2a28fa7f53 100644 (file)
@@ -316,7 +316,7 @@ static void wacom_close(struct input_dev *dev)
                usb_unlink_urb(&wacom->irq);
 }
 
-static void *wacom_probe(struct usb_device *dev, unsigned int ifnum)
+static void *wacom_probe(struct usb_device *dev, unsigned int ifnum, const struct usb_device_id *id)
 {
        struct usb_endpoint_descriptor *endpoint;
        struct wacom *wacom;
index e6ad28fcff1c609d7ada620fd6b2a7506c9b3558..44f6fc8c5f824e6faaf39c07f9e24977b4f3fc57 100644 (file)
@@ -749,13 +749,6 @@ static struct display disp;
 static struct fb_info fb_info;
 
 
-       /*
-        * The minimum period for audio depends on htotal (for OCS/ECS/AGA)
-        * (Imported from arch/m68k/amiga/amisound.c)
-        */
-
-extern volatile u_short amiga_audio_min_period;
-
        /*
         * Since we can't read the palette on OCS/ECS, and since reading one
         * single color palette entry requires 5 expensive custom chip bus accesses
@@ -1206,6 +1199,8 @@ int __init amifb_setup(char *options)
                if (!strcmp(this_opt, "inverse")) {
                        amifb_inverse = 1;
                        fb_invert_cmaps();
+               } else if (!strcmp(this_opt, "off")) {
+                       amifb_video_off();
                } else if (!strcmp(this_opt, "ilbm"))
                        amifb_ilbm = 1;
                else if (!strncmp(this_opt, "monitorcap:", 11))
@@ -1771,7 +1766,7 @@ default_chipset:
         * access the videomem with writethrough cache
         */
        videomemory_phys = (u_long)ZTWO_PADDR(videomemory);
-       videomemory = (u_long)ioremap_writethrough(videomemory_phys, videomemorysize);
+       //videomemory = (u_long)ioremap_writethrough(videomemory_phys, videomemorysize);
        if (!videomemory) {
                printk("amifb: WARNING! unable to map videomem cached writethrough\n");
                videomemory = ZTWO_VADDR(videomemory_phys);
@@ -1792,15 +1787,11 @@ default_chipset:
 
        ami_init_copper();
 
-       if (request_irq(IRQ_AMIGA_AUTO_3, amifb_interrupt, 0,
-                       "fb vertb handler", NULL)) {
+       if (request_irq(IRQ_AMIGA_VERTB, amifb_interrupt, 0,
+                       "fb vertb handler", &currentpar)) {
                err = -EBUSY;
                goto amifb_error;
        }
-       amiga_intena_vals[IRQ_AMIGA_VERTB] = IF_COPER;
-       amiga_intena_vals[IRQ_AMIGA_COPPER] = 0;
-       custom.intena = IF_VERTB;
-       custom.intena = IF_SETCLR | IF_COPER;
 
        amifb_set_var(&var, -1, &fb_info);
 
@@ -1895,57 +1886,33 @@ static int flash_cursor(void)
 
 static void amifb_interrupt(int irq, void *dev_id, struct pt_regs *fp)
 {
-       u_short ints = custom.intreqr & custom.intenar;
-       static struct irq_server server = {0, 0};
-       unsigned long flags;
-
-       if (ints & IF_BLIT) {
-               custom.intreq = IF_BLIT;
-               amiga_do_irq(IRQ_AMIGA_BLIT, fp);
-       }
-
-       if (ints & IF_COPER) {
-               custom.intreq = IF_COPER;
-               if (do_vmode_pan || do_vmode_full)
-                       ami_update_display();
-
-               if (do_vmode_full)
-                       ami_init_display();
-
-               if (do_vmode_pan) {
-                       flash_cursor();
-                       ami_rebuild_copper();
-                       do_cursor = do_vmode_pan = 0;
-               } else if (do_cursor) {
-                       flash_cursor();
+       if (do_vmode_pan || do_vmode_full)
+               ami_update_display();
+
+       if (do_vmode_full)
+               ami_init_display();
+
+       if (do_vmode_pan) {
+               flash_cursor();
+               ami_rebuild_copper();
+               do_cursor = do_vmode_pan = 0;
+       } else if (do_cursor) {
+               flash_cursor();
+               ami_set_sprite();
+               do_cursor = 0;
+       } else {
+               if (flash_cursor())
                        ami_set_sprite();
-                       do_cursor = 0;
-               } else {
-                       if (flash_cursor())
-                               ami_set_sprite();
-               }
-
-               save_flags(flags);
-               cli();
-               if (get_vbpos() < down2(currentpar.diwstrt_v - 6))
-                       custom.copjmp2 = 0;
-               restore_flags(flags);
-
-               if (do_blank) {
-                       ami_do_blank();
-                       do_blank = 0;
-               }
+       }
 
-               if (do_vmode_full) {
-                       ami_reinit_copper();
-                       do_vmode_full = 0;
-               }
-               amiga_do_irq_list(IRQ_AMIGA_VERTB, fp, &server);
+       if (do_blank) {
+               ami_do_blank();
+               do_blank = 0;
        }
 
-       if (ints & IF_VERTB) {
-               printk("%s: Warning: IF_VERTB was enabled\n", __FUNCTION__);
-               custom.intena = IF_VERTB;
+       if (do_vmode_full) {
+               ami_reinit_copper();
+               do_vmode_full = 0;
        }
 }
 
@@ -3379,5 +3346,6 @@ void cleanup_module(void)
 {
        unregister_framebuffer(&fb_info);
        amifb_deinit();
+       amifb_video_off();
 }
 #endif /* MODULE */
index c09a691a864a036257ba7c96f20f17e00527122e..e305027a7ac6d0bcf1a776fccb31bb352d40010f 100644 (file)
@@ -2424,6 +2424,21 @@ do_install_cmap(int con, struct fb_info *info)
                                            1, fbhw->setcolreg, info);          
 }
 
+static int
+atafb_get_fix(struct fb_fix_screeninfo *fix, int con, struct fb_info *info)
+{
+       struct atafb_par par;
+       if (con == -1)
+               atafb_get_par(&par);
+       else {
+         int err;
+               if ((err=fbhw->decode_var(&fb_display[con].var,&par)))
+                 return err;
+       }
+       memset(fix, 0, sizeof(struct fb_fix_screeninfo));
+       return fbhw->encode_fix(fix, &par);
+}
+       
 static int
 atafb_get_var(struct fb_var_screeninfo *var, int con, struct fb_info *info)
 {
@@ -2776,7 +2791,7 @@ int __init atafb_init(void)
 #endif /* ATAFB_EXT */
                mem_req = default_mem_req + ovsc_offset + ovsc_addlen;
                mem_req = PAGE_ALIGN(mem_req) + PAGE_SIZE;
-               screen_base = atari_stram_alloc(mem_req, NULL, "atafb");
+               screen_base = atari_stram_alloc(mem_req, "atafb");
                if (!screen_base)
                        panic("Cannot allocate screen memory");
                memset(screen_base, 0, mem_req);
index 9f9fbbfbd8300e4a6da95689e99a7bae8a9c5de0..0f5e6c4dcd55c3739e34b716952c09be6de48c6c 100644 (file)
@@ -69,6 +69,8 @@ static char buffersize_index[65] =
  *     lru_list_lock > hash_table_lock > free_list_lock > unused_list_lock
  */
 
+#define BH_ENTRY(list) list_entry((list), struct buffer_head, b_inode_buffers)
+
 /*
  * Hash table gook..
  */
@@ -567,6 +569,42 @@ unsigned int get_hardblocksize(kdev_t dev)
        return 0;
 }
 
+void buffer_insert_inode_queue(struct buffer_head *bh, struct inode *inode)
+{
+       spin_lock(&lru_list_lock);
+       if (bh->b_inode)
+               list_del(&bh->b_inode_buffers);
+       bh->b_inode = inode;
+       list_add(&bh->b_inode_buffers, &inode->i_dirty_buffers);
+       spin_unlock(&lru_list_lock);
+}
+
+/* The caller must have the lru_list lock before calling the 
+   remove_inode_queue functions.  */
+static void __remove_inode_queue(struct buffer_head *bh)
+{
+       bh->b_inode = NULL;
+       list_del(&bh->b_inode_buffers);
+}
+
+static inline void remove_inode_queue(struct buffer_head *bh)
+{
+       if (bh->b_inode)
+               __remove_inode_queue(bh);
+}
+
+int inode_has_buffers(struct inode *inode)
+{
+       int ret;
+       
+       spin_lock(&lru_list_lock);
+       ret = !list_empty(&inode->i_dirty_buffers);
+       spin_unlock(&lru_list_lock);
+       
+       return ret;
+}
+
+
 /* If invalidate_buffers() will trash dirty buffers, it means some kind
    of fs corruption is going on. Trashing dirty data always imply losing
    information that was supposed to be just stored on the physical layer
@@ -615,6 +653,7 @@ void __invalidate_buffers(kdev_t dev, int destroy_dirty_buffers)
                        write_lock(&hash_table_lock);
                        if (!atomic_read(&bh->b_count) &&
                            (destroy_dirty_buffers || !buffer_dirty(bh))) {
+                               remove_inode_queue(bh);
                                __remove_from_queues(bh);
                                put_last_free(bh);
                        }
@@ -679,6 +718,7 @@ void set_blocksize(kdev_t dev, int size)
                                        printk(KERN_WARNING
                                               "set_blocksize: dev %s buffer_dirty %lu size %hu\n",
                                               kdevname(dev), bh->b_blocknr, bh->b_size);
+                               remove_inode_queue(bh);
                                __remove_from_queues(bh);
                                put_last_free(bh);
                        } else {
@@ -793,6 +833,136 @@ still_busy:
        return;
 }
 
+/*
+ * Synchronise all the inode's dirty buffers to the disk.
+ *
+ * We have conflicting pressures: we want to make sure that all
+ * initially dirty buffers get waited on, but that any subsequently
+ * dirtied buffers don't.  After all, we don't want fsync to last
+ * forever if somebody is actively writing to the file.
+ *
+ * Do this in two main stages: first we copy dirty buffers to a
+ * temporary inode list, queueing the writes as we go.  Then we clean
+ * up, waiting for those writes to complete.
+ * 
+ * During this second stage, any subsequent updates to the file may end
+ * up refiling the buffer on the original inode's dirty list again, so
+ * there is a chance we will end up with a buffer queued for write but
+ * not yet completed on that list.  So, as a final cleanup we go through
+ * the osync code to catch these locked, dirty buffers without requeuing
+ * any newly dirty buffers for write.
+ */
+
+int fsync_inode_buffers(struct inode *inode)
+{
+       struct buffer_head *bh;
+       struct inode tmp;
+       int err = 0, err2;
+       
+       INIT_LIST_HEAD(&tmp.i_dirty_buffers);
+       
+       spin_lock(&lru_list_lock);
+
+       while (!list_empty(&inode->i_dirty_buffers)) {
+               bh = BH_ENTRY(inode->i_dirty_buffers.next);
+               list_del(&bh->b_inode_buffers);
+               if (!buffer_dirty(bh) && !buffer_locked(bh))
+                       bh->b_inode = NULL;
+               else {
+                       bh->b_inode = &tmp;
+                       list_add(&bh->b_inode_buffers, &tmp.i_dirty_buffers);
+                       atomic_inc(&bh->b_count);
+                       if (buffer_dirty(bh)) {
+                               spin_unlock(&lru_list_lock);
+                               ll_rw_block(WRITE, 1, &bh);
+                               spin_lock(&lru_list_lock);
+                       }
+               }
+       }
+
+       while (!list_empty(&tmp.i_dirty_buffers)) {
+               bh = BH_ENTRY(tmp.i_dirty_buffers.prev);
+               remove_inode_queue(bh);
+               spin_unlock(&lru_list_lock);
+               wait_on_buffer(bh);
+               if (!buffer_uptodate(bh))
+                       err = -EIO;
+               brelse(bh);
+               spin_lock(&lru_list_lock);
+       }
+       
+       spin_unlock(&lru_list_lock);
+       err2 = osync_inode_buffers(inode);
+
+       if (err)
+               return err;
+       else
+               return err2;
+}
+
+
+/*
+ * osync is designed to support O_SYNC io.  It waits synchronously for
+ * all already-submitted IO to complete, but does not queue any new
+ * writes to the disk.
+ *
+ * To do O_SYNC writes, just queue the buffer writes with ll_rw_block as
+ * you dirty the buffers, and then use osync_inode_buffers to wait for
+ * completion.  Any other dirty buffers which are not yet queued for
+ * write will not be flushed to disk by the osync.
+ */
+
+int osync_inode_buffers(struct inode *inode)
+{
+       struct buffer_head *bh;
+       struct list_head *list;
+       int err = 0;
+
+       spin_lock(&lru_list_lock);
+       
+ repeat:
+       
+       for (list = inode->i_dirty_buffers.prev; 
+            bh = BH_ENTRY(list), list != &inode->i_dirty_buffers;
+            list = bh->b_inode_buffers.prev) {
+               if (buffer_locked(bh)) {
+                       atomic_inc(&bh->b_count);
+                       spin_unlock(&lru_list_lock);
+                       wait_on_buffer(bh);
+                       brelse(bh);
+                       if (!buffer_uptodate(bh))
+                               err = -EIO;
+                       spin_lock(&lru_list_lock);
+                       goto repeat;
+               }
+       }
+
+       spin_unlock(&lru_list_lock);
+       return err;
+}
+
+
+/*
+ * Invalidate any and all dirty buffers on a given inode.  We are
+ * probably unmounting the fs, but that doesn't mean we have already
+ * done a sync().  Just drop the buffers from the inode list.
+ */
+
+void invalidate_inode_buffers(struct inode *inode)
+{
+       struct list_head *list, *next;
+       
+       spin_lock(&lru_list_lock);
+       list = inode->i_dirty_buffers.next; 
+       while (list != &inode->i_dirty_buffers) {
+               next = list->next;
+               remove_inode_queue(BH_ENTRY(list));
+               list = next;
+       }
+       spin_unlock(&lru_list_lock);
+}
+
+
 /*
  * Ok, this is getblk, and it isn't very clear, again to hinder
  * race-conditions. Most of the code is seldom used, (ie repeating),
@@ -941,6 +1111,8 @@ static void __refile_buffer(struct buffer_head *bh)
        if (dispose != bh->b_list) {
                __remove_from_lru_list(bh, bh->b_list);
                bh->b_list = dispose;
+               if (dispose == BUF_CLEAN)
+                       remove_inode_queue(bh);
                __insert_into_lru_list(bh, dispose);
        }
 }
@@ -978,6 +1150,7 @@ void __bforget(struct buffer_head * buf)
        if (!atomic_dec_and_test(&buf->b_count) || buffer_locked(buf))
                goto in_use;
        __hash_unlink(buf);
+       remove_inode_queue(buf);
        write_unlock(&hash_table_lock);
        __remove_from_lru_list(buf, buf->b_list);
        spin_unlock(&lru_list_lock);
@@ -1074,6 +1247,8 @@ struct buffer_head * breada(kdev_t dev, int block, int bufsize,
  */
 static __inline__ void __put_unused_buffer_head(struct buffer_head * bh)
 {
+       if (bh->b_inode)
+               BUG();
        if (nr_unused_buffer_heads >= MAX_UNUSED_BUFFERS) {
                kmem_cache_free(bh_cachep, bh);
        } else {
@@ -1441,6 +1616,7 @@ static int __block_write_full_page(struct inode *inode, struct page *page, get_b
                }
                set_bit(BH_Uptodate, &bh->b_state);
                if (!atomic_set_buffer_dirty(bh)) {
+                       buffer_insert_inode_queue(bh, inode);
                        __mark_dirty(bh);
                        need_balance_dirty = 1;
                }
@@ -1551,6 +1727,7 @@ static int __block_commit_write(struct inode *inode, struct page *page,
                        set_bit(BH_Uptodate, &bh->b_state);
                        if (!atomic_set_buffer_dirty(bh)) {
                                __mark_dirty(bh);
+                               buffer_insert_inode_queue(bh, inode);
                                need_balance_dirty = 1;
                        }
                }
@@ -2313,9 +2490,10 @@ cleaned_buffers_try_again:
                /* The buffer can be either on the regular
                 * queues or on the free list..
                 */
-               if (p->b_dev != B_FREE)
+               if (p->b_dev != B_FREE) {
+                       remove_inode_queue(p);
                        __remove_from_queues(p);
-               else
+               else
                        __remove_from_free_list(p, index);
                __put_unused_buffer_head(p);
        } while (tmp != bh);
index 42ce44c65eb5e28d5ba856fbd2136dc67dc16b84..8b2ecab4181beb9dc604a09c6f2778cfb71d3a9b 100644 (file)
 #include <linux/smp_lock.h>
 
 
-#define blocksize      (EXT2_BLOCK_SIZE(inode->i_sb))
-#define addr_per_block (EXT2_ADDR_PER_BLOCK(inode->i_sb))
-
-static int sync_indirect(struct inode * inode, u32 * block, int wait)
-{
-       struct buffer_head * bh;
-       
-       if (!*block)
-               return 0;
-       bh = get_hash_table(inode->i_dev, le32_to_cpu(*block), blocksize);
-       if (!bh)
-               return 0;
-       if (wait && buffer_req(bh) && !buffer_uptodate(bh)) {
-               /* There can be a parallell read(2) that started read-I/O
-                  on the buffer so we can't assume that there's been
-                  an I/O error without first waiting I/O completation. */
-               wait_on_buffer(bh);
-               if (!buffer_uptodate(bh))
-               {
-                       brelse (bh);
-                       return -1;
-               }
-       }
-       if (wait || !buffer_uptodate(bh) || !buffer_dirty(bh)) {
-               if (wait)
-                       /* when we return from fsync all the blocks
-                          must be _just_ stored on disk */
-                       wait_on_buffer(bh);
-               brelse(bh);
-               return 0;
-       }
-       ll_rw_block(WRITE, 1, &bh);
-       atomic_dec(&bh->b_count);
-       return 0;
-}
-
-static int sync_iblock(struct inode * inode, u32 * iblock, 
-                       struct buffer_head ** bh, int wait) 
-{
-       int rc, tmp;
-       
-       *bh = NULL;
-       tmp = le32_to_cpu(*iblock);
-       if (!tmp)
-               return 0;
-       rc = sync_indirect(inode, iblock, wait);
-       if (rc)
-               return rc;
-       *bh = bread(inode->i_dev, tmp, blocksize);
-       if (!*bh)
-               return -1;
-       return 0;
-}
-
-static int sync_dindirect(struct inode * inode, u32 * diblock, int wait)
-{
-       int i;
-       struct buffer_head * dind_bh;
-       int rc, err = 0;
-
-       rc = sync_iblock(inode, diblock, &dind_bh, wait);
-       if (rc || !dind_bh)
-               return rc;
-       
-       for (i = 0; i < addr_per_block; i++) {
-               rc = sync_indirect(inode, ((u32 *) dind_bh->b_data) + i, wait);
-               if (rc)
-                       err = rc;
-       }
-       brelse(dind_bh);
-       return err;
-}
-
-static int sync_tindirect(struct inode * inode, u32 * tiblock, int wait)
-{
-       int i;
-       struct buffer_head * tind_bh;
-       int rc, err = 0;
-
-       rc = sync_iblock(inode, tiblock, &tind_bh, wait);
-       if (rc || !tind_bh)
-               return rc;
-       
-       for (i = 0; i < addr_per_block; i++) {
-               rc = sync_dindirect(inode, ((u32 *) tind_bh->b_data) + i, wait);
-               if (rc)
-                       err = rc;
-       }
-       brelse(tind_bh);
-       return err;
-}
-
 /*
  *     File may be NULL when we are called. Perhaps we shouldn't
  *     even pass file to fsync ?
@@ -127,32 +35,20 @@ static int sync_tindirect(struct inode * inode, u32 * tiblock, int wait)
 
 int ext2_sync_file(struct file * file, struct dentry *dentry, int datasync)
 {
-       int wait, err = 0;
        struct inode *inode = dentry->d_inode;
+       return ext2_fsync_inode(inode, datasync);
+}
 
-       lock_kernel();
-       if (S_ISLNK(inode->i_mode) && !(inode->i_blocks))
-               /*
-                * Don't sync fast links!
-                */
-               goto skip;
-
-       err = generic_buffer_fdatasync(inode, 0, ~0UL);
-
-       for (wait=0; wait<=1; wait++)
-       {
-               err |= sync_indirect(inode,
-                                    inode->u.ext2_i.i_data+EXT2_IND_BLOCK,
-                                    wait);
-               err |= sync_dindirect(inode,
-                                     inode->u.ext2_i.i_data+EXT2_DIND_BLOCK, 
-                                     wait);
-               err |= sync_tindirect(inode, 
-                                     inode->u.ext2_i.i_data+EXT2_TIND_BLOCK, 
-                                     wait);
-       }
-skip:
-       err |= ext2_sync_inode (inode);
-       unlock_kernel();
+int ext2_fsync_inode(struct inode *inode, int datasync)
+{
+       int err;
+       
+       err  = fsync_inode_buffers(inode);
+       if (!(inode->i_state & I_DIRTY))
+               return err;
+       if (datasync && !(inode->i_state & I_DIRTY_DATASYNC))
+               return err;
+       
+       err |= ext2_sync_inode(inode);
        return err ? -EIO : 0;
 }
index 5852cef4c6723320771b107ca2e58e466625d825..168a5503fcc5827874aab919b5741f9c04a471d9 100644 (file)
@@ -404,7 +404,7 @@ static int ext2_alloc_branch(struct inode *inode,
                branch[n].p = (u32*) bh->b_data + offsets[n];
                *branch[n].p = branch[n].key;
                mark_buffer_uptodate(bh, 1);
-               mark_buffer_dirty(bh);
+               mark_buffer_dirty_inode(bh, inode);
                if (IS_SYNC(inode) || inode->u.ext2_i.i_osync) {
                        ll_rw_block (WRITE, 1, &bh);
                        wait_on_buffer (bh);
@@ -469,7 +469,7 @@ static inline int ext2_splice_branch(struct inode *inode,
 
        /* had we spliced it onto indirect block? */
        if (where->bh) {
-               mark_buffer_dirty(where->bh);
+               mark_buffer_dirty_inode(where->bh, inode);
                if (IS_SYNC(inode) || inode->u.ext2_i.i_osync) {
                        ll_rw_block (WRITE, 1, &where->bh);
                        wait_on_buffer(where->bh);
@@ -591,7 +591,7 @@ struct buffer_head * ext2_getblk(struct inode * inode, long block, int create, i
                                wait_on_buffer(bh);
                        memset(bh->b_data, 0, inode->i_sb->s_blocksize);
                        mark_buffer_uptodate(bh, 1);
-                       mark_buffer_dirty(bh);
+                       mark_buffer_dirty_inode(bh, inode);
                }
                return bh;
        }
@@ -907,7 +907,7 @@ void ext2_truncate (struct inode * inode)
                if (partial == chain)
                        mark_inode_dirty(inode);
                else
-                       mark_buffer_dirty(partial->bh);
+                       mark_buffer_dirty_inode(partial->bh, inode);
                ext2_free_branches(inode, &nr, &nr+1, (chain+n-1) - partial);
        }
        /* Clear the ends of indirect blocks on the shared branch */
@@ -916,7 +916,7 @@ void ext2_truncate (struct inode * inode)
                                   partial->p + 1,
                                   (u32*)partial->bh->b_data + addr_per_block,
                                   (chain+n-1) - partial);
-               mark_buffer_dirty(partial->bh);
+               mark_buffer_dirty_inode(partial->bh, inode);
                if (IS_SYNC(inode)) {
                        ll_rw_block (WRITE, 1, &partial->bh);
                        wait_on_buffer (partial->bh);
@@ -1208,7 +1208,7 @@ static int ext2_update_inode(struct inode * inode, int do_sync)
                raw_inode->i_block[0] = cpu_to_le32(kdev_t_to_nr(inode->i_rdev));
        else for (block = 0; block < EXT2_N_BLOCKS; block++)
                raw_inode->i_block[block] = inode->u.ext2_i.i_data[block];
-       mark_buffer_dirty(bh);
+       mark_buffer_dirty_inode(bh, inode);
        if (do_sync) {
                ll_rw_block (WRITE, 1, &bh);
                wait_on_buffer (bh);
index 3c981f75c5f9f8ae45df72be249b07c727a6b26b..1eaaac4072738b32e88bc6e61dcc99853ff6fe0c 100644 (file)
@@ -296,7 +296,7 @@ int ext2_add_entry (struct inode * dir, const char * name, int namelen,
                        dir->u.ext2_i.i_flags &= ~EXT2_BTREE_FL;
                        mark_inode_dirty(dir);
                        dir->i_version = ++event;
-                       mark_buffer_dirty(bh);
+                       mark_buffer_dirty_inode(bh, dir);
                        if (IS_SYNC(dir)) {
                                ll_rw_block (WRITE, 1, &bh);
                                wait_on_buffer (bh);
@@ -337,7 +337,7 @@ static int ext2_delete_entry (struct inode * dir,
                        else
                                de->inode = 0;
                        dir->i_version = ++event;
-                       mark_buffer_dirty(bh);
+                       mark_buffer_dirty_inode(bh, dir);
                        if (IS_SYNC(dir)) {
                                ll_rw_block (WRITE, 1, &bh);
                                wait_on_buffer (bh);
@@ -449,7 +449,7 @@ static int ext2_mkdir(struct inode * dir, struct dentry * dentry, int mode)
        strcpy (de->name, "..");
        ext2_set_de_type(dir->i_sb, de, S_IFDIR);
        inode->i_nlink = 2;
-       mark_buffer_dirty(dir_block);
+       mark_buffer_dirty_inode(dir_block, dir);
        brelse (dir_block);
        inode->i_mode = S_IFDIR | mode;
        if (dir->i_mode & S_ISGID)
@@ -755,7 +755,7 @@ static int ext2_rename (struct inode * old_dir, struct dentry *old_dentry,
                                              EXT2_FEATURE_INCOMPAT_FILETYPE))
                        new_de->file_type = old_de->file_type;
                new_dir->i_version = ++event;
-               mark_buffer_dirty(new_bh);
+               mark_buffer_dirty_inode(new_bh, new_dir);
                if (IS_SYNC(new_dir)) {
                        ll_rw_block (WRITE, 1, &new_bh);
                        wait_on_buffer (new_bh);
@@ -786,7 +786,7 @@ static int ext2_rename (struct inode * old_dir, struct dentry *old_dentry,
        mark_inode_dirty(old_dir);
        if (dir_bh) {
                PARENT_INO(dir_bh->b_data) = le32_to_cpu(new_dir->i_ino);
-               mark_buffer_dirty(dir_bh);
+               mark_buffer_dirty_inode(dir_bh, old_inode);
                old_dir->i_nlink--;
                mark_inode_dirty(old_dir);
                if (new_inode) {
index 96e3664e55ebfd8ff5620f1fbe2b04562c68a2ee..24016206dfec3ca6447cb983fe946959e0642571 100644 (file)
@@ -96,6 +96,7 @@ static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags)
                INIT_LIST_HEAD(&inode->i_hash);
                INIT_LIST_HEAD(&inode->i_data.pages);
                INIT_LIST_HEAD(&inode->i_dentry);
+               INIT_LIST_HEAD(&inode->i_dirty_buffers);
                sema_init(&inode->i_sem, 1);
                sema_init(&inode->i_zombie, 1);
                spin_lock_init(&inode->i_data.i_shared_lock);
@@ -122,14 +123,14 @@ static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags)
  *     Mark an inode as dirty. Callers should use mark_inode_dirty.
  */
  
-void __mark_inode_dirty(struct inode *inode)
+void __mark_inode_dirty(struct inode *inode, int flags)
 {
        struct super_block * sb = inode->i_sb;
 
        if (sb) {
                spin_lock(&inode_lock);
-               if (!(inode->i_state & I_DIRTY)) {
-                       inode->i_state |= I_DIRTY;
+               if ((inode->i_state & flags) != flags) {
+                       inode->i_state |= flags;
                        /* Only add valid (ie hashed) inodes to the dirty list */
                        if (!list_empty(&inode->i_hash)) {
                                list_del(&inode->i_list);
@@ -196,7 +197,8 @@ static inline void sync_one(struct inode *inode, int sync)
                                                        ? &inode_in_use
                                                        : &inode_unused);
                /* Set I_LOCK, reset I_DIRTY */
-               inode->i_state ^= I_DIRTY | I_LOCK;
+               inode->i_state |= I_LOCK;
+               inode->i_state &= ~I_DIRTY;
                spin_unlock(&inode_lock);
 
                write_inode(inode, sync);
@@ -281,6 +283,60 @@ void write_inode_now(struct inode *inode, int sync)
                printk("write_inode_now: no super block\n");
 }
 
+/**
+ * generic_osync_inode - flush all dirty data for a given inode to disk
+ * @inode: inode to write
+ * @datasync: if set, don't bother flushing timestamps
+ *
+ * This can be called by file_write functions for files which have the
+ * O_SYNC flag set, to flush dirty writes to disk.  
+ */
+
+int generic_osync_inode(struct inode *inode, int datasync)
+{
+       int err;
+       
+       /* 
+        * WARNING
+        *
+        * Currently, the filesystem write path does not pass the
+        * filp down to the low-level write functions.  Therefore it
+        * is impossible for (say) __block_commit_write to know if
+        * the operation is O_SYNC or not.
+        *
+        * Ideally, O_SYNC writes would have the filesystem call
+        * ll_rw_block as it went to kick-start the writes, and we
+        * could call osync_inode_buffers() here to wait only for
+        * those IOs which have already been submitted to the device
+        * driver layer.  As it stands, if we did this we'd not write
+        * anything to disk since our writes have not been queued by
+        * this point: they are still on the dirty LRU.
+        * 
+        * So, currently we will call fsync_inode_buffers() instead,
+        * to flush _all_ dirty buffers for this inode to disk on 
+        * every O_SYNC write, not just the synchronous I/Os.  --sct
+        */
+
+#ifdef WRITERS_QUEUE_IO
+       err = osync_inode_buffers(inode);
+#else
+       err = fsync_inode_buffers(inode);
+#endif
+
+       spin_lock(&inode_lock);
+       if (!(inode->i_state & I_DIRTY))
+               goto out;
+       if (datasync && !(inode->i_state & I_DIRTY_DATASYNC))
+               goto out;
+       spin_unlock(&inode_lock);
+       write_inode_now(inode, 1);
+       return err;
+
+ out:
+       spin_unlock(&inode_lock);
+       return err;
+}
+
 /**
  * clear_inode - clear an inode
  * @inode: inode to clear
@@ -412,7 +468,8 @@ int invalidate_inodes(struct super_block * sb)
  *      dispose_list.
  */
 #define CAN_UNUSE(inode) \
-       (((inode)->i_state | (inode)->i_data.nrpages) == 0)
+       ((((inode)->i_state | (inode)->i_data.nrpages) == 0)  && \
+        !inode_has_buffers(inode))
 #define INODE(entry)   (list_entry(entry, struct inode, i_list))
 
 void prune_icache(int goal)
@@ -911,7 +968,7 @@ void update_atime (struct inode *inode)
        if ( IS_NODIRATIME (inode) && S_ISDIR (inode->i_mode) ) return;
        if ( IS_RDONLY (inode) ) return;
        inode->i_atime = CURRENT_TIME;
-       mark_inode_dirty (inode);
+       mark_inode_dirty_sync (inode);
 }   /*  End Function update_atime  */
 
 
index 0ae1086536ddef578233b8a97db98bc1a4d2e12f..1428fd95b987e42772eebdd15c88e09501479a39 100644 (file)
@@ -9,14 +9,14 @@
  * disable interrupts while they operate.  (You have to provide inline
  * routines to cli() and sti().)
  *
- * Also note, these routines assume that you have 32 bit integers.
+ * Also note, these routines assume that you have 32 bit longs.
  * You will have to change this if you are trying to port Linux to the
  * Alpha architecture or to a Cray.  :-)
  * 
  * C language equivalents written by Theodore Ts'o, 9/26/92
  */
 
-extern __inline__ int set_bit(int nr,int * addr)
+extern __inline__ int set_bit(int nr,long * addr)
 {
        int     mask, retval;
 
@@ -29,7 +29,7 @@ extern __inline__ int set_bit(int nr,int * addr)
        return retval;
 }
 
-extern __inline__ int clear_bit(int nr, int * addr)
+extern __inline__ int clear_bit(int nr, long * addr)
 {
        int     mask, retval;
 
@@ -42,7 +42,7 @@ extern __inline__ int clear_bit(int nr, int * addr)
        return retval;
 }
 
-extern __inline__ int test_bit(int nr, int * addr)
+extern __inline__ int test_bit(int nr, long * addr)
 {
        int     mask;
 
index cc28a42c74962966a2ac2dd64b79580e5a30f2e3..488208e7045842478a0487d5cb43bc5f80ddbd57 100644 (file)
@@ -49,6 +49,11 @@ struct mtrr_gentry
 #define MTRRIOC_DEL_ENTRY        _IOW(MTRR_IOCTL_BASE,  2, struct mtrr_sentry)
 #define MTRRIOC_GET_ENTRY        _IOWR(MTRR_IOCTL_BASE, 3, struct mtrr_gentry)
 #define MTRRIOC_KILL_ENTRY       _IOW(MTRR_IOCTL_BASE,  4, struct mtrr_sentry)
+#define MTRRIOC_ADD_PAGE_ENTRY   _IOW(MTRR_IOCTL_BASE,  5, struct mtrr_sentry)
+#define MTRRIOC_SET_PAGE_ENTRY   _IOW(MTRR_IOCTL_BASE,  6, struct mtrr_sentry)
+#define MTRRIOC_DEL_PAGE_ENTRY   _IOW(MTRR_IOCTL_BASE,  7, struct mtrr_sentry)
+#define MTRRIOC_GET_PAGE_ENTRY   _IOWR(MTRR_IOCTL_BASE, 8, struct mtrr_gentry)
+#define MTRRIOC_KILL_PAGE_ENTRY  _IOW(MTRR_IOCTL_BASE,  9, struct mtrr_sentry)
 
 /*  These are the region types  */
 #define MTRR_TYPE_UNCACHABLE 0
@@ -79,18 +84,31 @@ static char *mtrr_strings[MTRR_NUM_TYPES] =
 # ifdef CONFIG_MTRR
 extern int mtrr_add (unsigned long base, unsigned long size,
                     unsigned int type, char increment);
+extern int mtrr_add_page (unsigned long base, unsigned long size,
+                    unsigned int type, char increment);
 extern int mtrr_del (int reg, unsigned long base, unsigned long size);
+extern int mtrr_del_page (int reg, unsigned long base, unsigned long size);
 #  else
 static __inline__ int mtrr_add (unsigned long base, unsigned long size,
                                unsigned int type, char increment)
 {
     return -ENODEV;
 }
+static __inline__ int mtrr_add_page (unsigned long base, unsigned long size,
+                               unsigned int type, char increment)
+{
+    return -ENODEV;
+}
 static __inline__ int mtrr_del (int reg, unsigned long base,
                                unsigned long size)
 {
     return -ENODEV;
 }
+static __inline__ int mtrr_del_page (int reg, unsigned long base,
+                               unsigned long size)
+{
+    return -ENODEV;
+}
 #  endif
 
 /*  The following functions are for initialisation: don't use them!  */
index d63ceca32c46baed9cb3381609515a499045715e..3e5a2770cbac6b22a482e97fe61663600c42ff4f 100644 (file)
@@ -16,6 +16,8 @@
 #ifndef _M68K_AMIGAHW_H
 #define _M68K_AMIGAHW_H
 
+#include <linux/ioport.h>
+
     /*
      *  Different Amiga models
      */
@@ -279,11 +281,27 @@ struct CIA {
 #define ciab   ((*(volatile struct CIA *)(zTwoBase + CIAB_PHYSADDR)))
 
 #define CHIP_PHYSADDR      (0x000000)
-#define chipaddr ((unsigned long)(zTwoBase + CHIP_PHYSADDR))
+
 void amiga_chip_init (void);
-void *amiga_chip_alloc (long size, const char *name);
-void amiga_chip_free (void *);
+void *amiga_chip_alloc(unsigned long size, const char *name);
+void *amiga_chip_alloc_res(unsigned long size, struct resource *res);
+void amiga_chip_free(void *ptr);
 unsigned long amiga_chip_avail( void ); /*MILAN*/
+extern volatile unsigned short amiga_audio_min_period;
+
+static inline void amifb_video_off(void)
+{
+       if (amiga_chipset == CS_ECS || amiga_chipset == CS_AGA) {
+               /* program Denise/Lisa for a higher maximum play rate */
+               custom.htotal = 113;        /* 31 kHz */
+               custom.vtotal = 223;        /* 70 Hz */
+               custom.beamcon0 = 0x4390;   /* HARDDIS, VAR{BEAM,VSY,HSY,CSY}EN */
+               /* suspend the monitor */
+               custom.hsstrt = custom.hsstop = 116;
+               custom.vsstrt = custom.vsstop = 226;
+               amiga_audio_min_period = 57;
+       }
+}
 
 struct tod3000 {
   unsigned int  :28, second2:4;        /* lower digit */
index 35bc3e18ed63a4931e14c1269aefb38ab9d0fdf3..2aff4cfbf7b3837013f4f3b94a177f52a41f2028 100644 (file)
 #define IF_DSKBLK   0x0002     /* diskblock DMA finished */
 #define IF_TBE     0x0001      /* serial transmit buffer empty interrupt */
 
-struct irq_server {
-       unsigned short count, reentrance;
-};
-
 extern void amiga_do_irq(int irq, struct pt_regs *fp);
-extern void amiga_do_irq_list(int irq, struct pt_regs *fp, struct irq_server *server);
+extern void amiga_do_irq_list(int irq, struct pt_regs *fp);
 
 extern unsigned short amiga_intena_vals[];
 
index 78ffce6aa6ea882a8a09266dc4cc43dab0a6b8c4..6f1ec1887d82c3d5f66713ec15ddf363e8410cc0 100644 (file)
@@ -36,17 +36,17 @@ static inline u_char pcmcia_get_intreq(void)
 
 static inline void pcmcia_ack_int(u_char intreq)
 {
-       gayle.intreq = ((intreq & 0x2c) ^ 0x2c) | 0xc0;
+       gayle.intreq = 0xf8;
 }
 
 static inline void pcmcia_enable_irq(void)
 {
-       gayle.inten = GAYLE_IRQ_IDE|GAYLE_IRQ_IRQ;
+       gayle.inten |= GAYLE_IRQ_IRQ;
 }
 
 static inline void pcmcia_disable_irq(void)
 {
-       gayle.inten = GAYLE_IRQ_IDE;
+       gayle.inten &= ~GAYLE_IRQ_IRQ;
 }
 
 #define PCMCIA_INSERTED        (gayle.cardstatus & GAYLE_CS_CCDET)
index 31d620b67d0ec0f93739a7c78154ef76e6b1f4c9..7546d13963be046b525ae056f862670d7bbf3535 100644 (file)
@@ -6,12 +6,12 @@
  */
 
 /* public interface */
-void *atari_stram_alloc( long size, unsigned long *start_mem,
-                                                const char *owner );
-void atari_stram_free( void *);
+void *atari_stram_alloc(long size, const char *owner);
+void atari_stram_free(void *);
 
 /* functions called internally by other parts of the kernel */
-void atari_stram_init( void);
-void atari_stram_reserve_pages( unsigned long start_mem );
+void atari_stram_init(void);
+void atari_stram_reserve_pages(void *start_mem);
+void atari_stram_mem_init_hook (void);
 
 #endif /*_M68K_ATARI_STRAM_H */
index 8937fc2d19e84e14d12c574a37eb6e27459a74a9..e27147ae8468687f244202363972d65509f9786d 100644 (file)
@@ -123,7 +123,7 @@ extern struct atari_hw_present atari_hw_present;
  */
 
 #include <linux/mm.h>
-#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
 
 static inline void dma_cache_maintenance( unsigned long paddr,
                                          unsigned long len,
index ff1c8b9fa93ae8dfd61e40c537a83a3dec318a23..7d91887d73d694d5da4fd989ee7962d1b8ecc28f 100644 (file)
@@ -83,6 +83,12 @@ extern __inline__ int __generic_test_and_clear_bit(int nr, void * vaddr)
        return retval;
 }
 
+/*
+ * clear_bit() doesn't provide any barrier for the compiler.
+ */
+#define smp_mb__before_clear_bit()     barrier()
+#define smp_mb__after_clear_bit()      barrier()
+
 #define clear_bit(nr,vaddr) \
   (__builtin_constant_p(nr) ? \
    __constant_clear_bit(nr, vaddr) : \
index 444d5ba3598b20410b85bfb479e0facb31f4c913..d5eae1ee1f04432fdbf559d71687081f3c8b9352 100644 (file)
 LFLUSH_I_AND_D = 0x00000808
 LSIGTRAP = 5
 
-/* process bits for task_struct.flags */
-PF_TRACESYS_OFF = 3
-PF_TRACESYS_BIT = 5
-PF_PTRACED_OFF = 3
-PF_PTRACED_BIT = 4
-PF_DTRACE_OFF = 1
-PF_DTRACE_BIT = 5
+/* process bits for task_struct.ptrace */
+PT_TRACESYS_OFF = 3
+PT_TRACESYS_BIT = 1
+PT_PTRACED_OFF = 3
+PT_PTRACED_BIT = 0
+PT_DTRACE_OFF = 3
+PT_DTRACE_BIT = 2
 
 #define SAVE_ALL_INT save_all_int
 #define SAVE_ALL_SYS save_all_sys
index 9738061b764a973ee59b86db5d6e096b8b5a6765..c0b273f68f055bedc32ea30b5b6b4fddc2076088 100644 (file)
 #define F_SETSIG       10      /*  for sockets. */
 #define F_GETSIG       11      /*  for sockets. */
 
+#define F_GETLK64      12      /*  using 'struct flock64' */
+#define F_SETLK64      13
+#define F_SETLKW64     14
+
 /* for F_[GET|SET]FL */
 #define FD_CLOEXEC     1       /* actually anything with low bit set goes */
 
@@ -70,5 +74,13 @@ struct flock {
        pid_t l_pid;
 };
 
+struct flock64 {
+       short  l_type;
+       short  l_whence;
+       loff_t l_start;
+       loff_t l_len;
+       pid_t  l_pid;
+};
+
 #define F_LINUX_SPECIFIC_BASE  1024
 #endif /* _M68K_FCNTL_H */
index 555ef68ec6fda2d2dc25bd74c6081a7595b69919..ce0fdd07515564efce1b8f10c243415fb81e9648 100644 (file)
@@ -8,7 +8,6 @@
  *  This file contains the m68k architecture specific keyboard definitions
  */
 
-#include <linux/config.h> /* CONFIG_MAGIC_SYSRQ */
 #ifndef __M68K_KEYBOARD_H
 #define __M68K_KEYBOARD_H
 
@@ -39,17 +38,6 @@ static __inline__ int kbd_getkeycode(unsigned int scancode)
     return scancode > 127 ? -EINVAL : scancode;
 }
 
-static __inline__ int kbd_translate(unsigned char scancode,
-                                   unsigned char *keycode, char raw_mode)
-{
-#ifdef CONFIG_Q40
-    if (MACH_IS_Q40)
-        return q40kbd_translate(scancode,keycode,raw_mode);
-#endif
-    *keycode = scancode;
-    return 1;
-}
-
 static __inline__ char kbd_unexpected_up(unsigned char keycode)
 {
 #ifdef CONFIG_Q40
@@ -65,15 +53,16 @@ static __inline__ void kbd_leds(unsigned char leds)
        mach_kbd_leds(leds);
 }
 
-#ifdef CONFIG_MAGIC_SYSRQ
-#define kbd_is_sysrq(keycode)  ((keycode) == mach_sysrq_key && \
-                                (up_flag || \
-                                 (shift_state & mach_sysrq_shift_mask) == \
-                                 mach_sysrq_shift_state))
-#define kbd_sysrq_xlate                        mach_sysrq_xlate
-#endif
+#define kbd_init_hw            mach_keyb_init
+#define kbd_translate          mach_kbd_translate
+
+#define kbd_sysrq_xlate                mach_sysrq_xlate
+
+/* resource allocation */
+#define kbd_request_region()
+#define kbd_request_irq(handler)
 
-#define kbd_init_hw    mach_keyb_init
+extern unsigned int SYSRQ_KEY;
 
 #endif /* __KERNEL__ */
 
index 864f09ecd6f9fb4cef5f55084aaebf62df332b19..269d90b9d462c02a9702d9438b2ed7320a867224 100644 (file)
@@ -13,6 +13,7 @@ extern void (*mach_sched_init) (void (*handler)(int, void *, struct pt_regs *));
 extern int (*mach_keyb_init) (void);
 extern int (*mach_kbdrate) (struct kbd_repeat *);
 extern void (*mach_kbd_leds) (unsigned int);
+extern int (*mach_kbd_translate)(unsigned char scancode, unsigned char *keycode, char raw_mode);
 /* machine dependent irq functions */
 extern void (*mach_init_IRQ) (void);
 extern void (*(*mach_default_handler)[]) (int, void *, struct pt_regs *);
diff --git a/include/asm-m68k/motorola_pgalloc.h b/include/asm-m68k/motorola_pgalloc.h
new file mode 100644 (file)
index 0000000..9257aeb
--- /dev/null
@@ -0,0 +1,260 @@
+#ifndef _MOTOROLA_PGALLOC_H
+#define _MOTOROLA_PGALLOC_H
+
+extern struct pgtable_cache_struct {
+       unsigned long *pmd_cache;
+       unsigned long *pte_cache;
+/* This counts in units of pointer tables, of which can be eight per page. */
+       unsigned long pgtable_cache_sz;
+} quicklists;
+
+#define pgd_quicklist ((unsigned long *)0)
+#define pmd_quicklist (quicklists.pmd_cache)
+#define pte_quicklist (quicklists.pte_cache)
+/* This isn't accurate because of fragmentation of allocated pages for
+   pointer tables, but that should not be a problem. */
+#define pgtable_cache_size ((quicklists.pgtable_cache_sz+7)/8)
+
+extern pte_t *get_pte_slow(pmd_t *pmd, unsigned long offset);
+extern pmd_t *get_pmd_slow(pgd_t *pgd, unsigned long offset);
+
+extern pmd_t *get_pointer_table(void);
+extern int free_pointer_table(pmd_t *);
+
+extern inline pte_t *get_pte_fast(void)
+{
+       unsigned long *ret;
+
+       ret = pte_quicklist;
+       if (ret) {
+               pte_quicklist = (unsigned long *)*ret;
+               ret[0] = 0;
+               quicklists.pgtable_cache_sz -= 8;
+       }
+       return (pte_t *)ret;
+}
+
+extern inline void free_pte_fast(pte_t *pte)
+{
+       *(unsigned long *)pte = (unsigned long)pte_quicklist;
+       pte_quicklist = (unsigned long *)pte;
+       quicklists.pgtable_cache_sz += 8;
+}
+
+extern inline void free_pte_slow(pte_t *pte)
+{
+       cache_page((unsigned long)pte);
+       free_page((unsigned long) pte);
+}
+
+extern inline pmd_t *get_pmd_fast(void)
+{
+       unsigned long *ret;
+
+       ret = pmd_quicklist;
+       if (ret) {
+               pmd_quicklist = (unsigned long *)*ret;
+               ret[0] = 0;
+               quicklists.pgtable_cache_sz--;
+       }
+       return (pmd_t *)ret;
+}
+
+extern inline void free_pmd_fast(pmd_t *pmd)
+{
+       *(unsigned long *)pmd = (unsigned long)pmd_quicklist;
+       pmd_quicklist = (unsigned long *) pmd;
+       quicklists.pgtable_cache_sz++;
+}
+
+extern inline int free_pmd_slow(pmd_t *pmd)
+{
+       return free_pointer_table(pmd);
+}
+
+/* The pgd cache is folded into the pmd cache, so these are dummy routines. */
+extern inline pgd_t *get_pgd_fast(void)
+{
+       return (pgd_t *)0;
+}
+
+extern inline void free_pgd_fast(pgd_t *pgd)
+{
+}
+
+extern inline void free_pgd_slow(pgd_t *pgd)
+{
+}
+
+extern void __bad_pte(pmd_t *pmd);
+extern void __bad_pmd(pgd_t *pgd);
+
+extern inline void pte_free(pte_t *pte)
+{
+       free_pte_fast(pte);
+}
+
+extern inline pte_t *pte_alloc(pmd_t *pmd, unsigned long address)
+{
+       address = (address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1);
+       if (pmd_none(*pmd)) {
+               pte_t *page = get_pte_fast();
+
+               if (!page)
+                       return get_pte_slow(pmd, address);
+               pmd_set(pmd,page);
+               return page + address;
+       }
+       if (pmd_bad(*pmd)) {
+               __bad_pte(pmd);
+               return NULL;
+       }
+       return (pte_t *)__pmd_page(*pmd) + address;
+}
+
+extern inline void pmd_free(pmd_t *pmd)
+{
+       free_pmd_fast(pmd);
+}
+
+extern inline pmd_t *pmd_alloc(pgd_t *pgd, unsigned long address)
+{
+       address = (address >> PMD_SHIFT) & (PTRS_PER_PMD - 1);
+       if (pgd_none(*pgd)) {
+               pmd_t *page = get_pmd_fast();
+
+               if (!page)
+                       return get_pmd_slow(pgd, address);
+               pgd_set(pgd, page);
+               return page + address;
+       }
+       if (pgd_bad(*pgd)) {
+               __bad_pmd(pgd);
+               return NULL;
+       }
+       return (pmd_t *)__pgd_page(*pgd) + address;
+}
+
+extern inline void pte_free_kernel(pte_t *pte)
+{
+       free_pte_fast(pte);
+}
+
+extern inline pte_t *pte_alloc_kernel(pmd_t *pmd, unsigned long address)
+{
+       return pte_alloc(pmd, address);
+}
+
+extern inline void pmd_free_kernel(pmd_t *pmd)
+{
+       free_pmd_fast(pmd);
+}
+
+extern inline pmd_t *pmd_alloc_kernel(pgd_t *pgd, unsigned long address)
+{
+       return pmd_alloc(pgd, address);
+}
+
+extern inline void pgd_free(pgd_t *pgd)
+{
+       free_pmd_fast((pmd_t *)pgd);
+}
+
+extern inline pgd_t *pgd_alloc(void)
+{
+       pgd_t *pgd = (pgd_t *)get_pmd_fast();
+       if (!pgd)
+               pgd = (pgd_t *)get_pointer_table();
+       return pgd;
+}
+
+extern int do_check_pgt_cache(int, int);
+
+extern inline void set_pgdir(unsigned long address, pgd_t entry)
+{
+}
+
+
+/*
+ * flush all user-space atc entries.
+ */
+static inline void __flush_tlb(void)
+{
+       if (CPU_IS_040_OR_060)
+               __asm__ __volatile__(".chip 68040\n\t"
+                                    "pflushan\n\t"
+                                    ".chip 68k");
+       else
+               __asm__ __volatile__("pflush #0,#4");
+}
+
+static inline void __flush_tlb040_one(unsigned long addr)
+{
+       __asm__ __volatile__(".chip 68040\n\t"
+                            "pflush (%0)\n\t"
+                            ".chip 68k"
+                            : : "a" (addr));
+}
+
+static inline void __flush_tlb_one(unsigned long addr)
+{
+       if (CPU_IS_040_OR_060)
+               __flush_tlb040_one(addr);
+       else
+               __asm__ __volatile__("pflush #0,#4,(%0)" : : "a" (addr));
+}
+
+#define flush_tlb() __flush_tlb()
+
+/*
+ * flush all atc entries (both kernel and user-space entries).
+ */
+static inline void flush_tlb_all(void)
+{
+       if (CPU_IS_040_OR_060)
+               __asm__ __volatile__(".chip 68040\n\t"
+                                    "pflusha\n\t"
+                                    ".chip 68k");
+       else
+               __asm__ __volatile__("pflusha");
+}
+
+static inline void flush_tlb_mm(struct mm_struct *mm)
+{
+       if (mm == current->mm)
+               __flush_tlb();
+}
+
+static inline void flush_tlb_page(struct vm_area_struct *vma, unsigned long addr)
+{
+       if (vma->vm_mm == current->mm)
+               __flush_tlb_one(addr);
+}
+
+static inline void flush_tlb_range(struct mm_struct *mm,
+                                  unsigned long start, unsigned long end)
+{
+       if (mm == current->mm)
+               __flush_tlb();
+}
+
+extern inline void flush_tlb_kernel_page(unsigned long addr)
+{
+       if (CPU_IS_040_OR_060) {
+               mm_segment_t old_fs = get_fs();
+               set_fs(KERNEL_DS);
+               __asm__ __volatile__(".chip 68040\n\t"
+                                    "pflush (%0)\n\t"
+                                    ".chip 68k"
+                                    : : "a" (addr));
+               set_fs(old_fs);
+       } else
+               __asm__ __volatile__("pflush #4,#4,(%0)" : : "a" (addr));
+}
+
+extern inline void flush_tlb_pgtables(struct mm_struct *mm,
+                                     unsigned long start, unsigned long end)
+{
+}
+
+#endif /* _MOTOROLA_PGALLOC_H */
diff --git a/include/asm-m68k/motorola_pgtable.h b/include/asm-m68k/motorola_pgtable.h
new file mode 100644 (file)
index 0000000..190f6bd
--- /dev/null
@@ -0,0 +1,264 @@
+#ifndef _MOTOROLA_PGTABLE_H
+#define _MOTOROLA_PGTABLE_H
+
+/*
+ * Definitions for MMU descriptors
+ */
+#define _PAGE_PRESENT  0x001
+#define _PAGE_SHORT    0x002
+#define _PAGE_RONLY    0x004
+#define _PAGE_ACCESSED 0x008
+#define _PAGE_DIRTY    0x010
+#define _PAGE_SUPER    0x080   /* 68040 supervisor only */
+#define _PAGE_FAKE_SUPER 0x200 /* fake supervisor only on 680[23]0 */
+#define _PAGE_GLOBAL040        0x400   /* 68040 global bit, used for kva descs */
+#define _PAGE_COW      0x800   /* implemented in software */
+#define _PAGE_NOCACHE030 0x040 /* 68030 no-cache mode */
+#define _PAGE_NOCACHE  0x060   /* 68040 cache mode, non-serialized */
+#define _PAGE_NOCACHE_S        0x040   /* 68040 no-cache mode, serialized */
+#define _PAGE_CACHE040 0x020   /* 68040 cache mode, cachable, copyback */
+#define _PAGE_CACHE040W        0x000   /* 68040 cache mode, cachable, write-through */
+
+#define _DESCTYPE_MASK 0x003
+
+#define _CACHEMASK040  (~0x060)
+#define _TABLE_MASK    (0xfffffe00)
+
+#define _PAGE_TABLE    (_PAGE_SHORT)
+#define _PAGE_CHG_MASK  (PAGE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_NOCACHE)
+
+#ifndef __ASSEMBLY__
+
+/* This is the cache mode to be used for pages containing page descriptors for
+ * processors >= '040. It is in pte_mknocache(), and the variable is defined
+ * and initialized in head.S */
+extern int m68k_pgtable_cachemode;
+
+/* This is the cache mode for normal pages, for supervisor access on
+ * processors >= '040. It is used in pte_mkcache(), and the variable is
+ * defined and initialized in head.S */
+
+#if defined(CONFIG_060_WRITETHROUGH)
+extern int m68k_supervisor_cachemode;
+#else
+#define m68k_supervisor_cachemode _PAGE_CACHE040
+#endif
+
+#if defined(CPU_M68040_OR_M68060_ONLY)
+#define mm_cachebits _PAGE_CACHE040
+#elif defined(CPU_M68020_OR_M68030_ONLY)
+#define mm_cachebits 0
+#else
+extern unsigned long mm_cachebits;
+#endif
+
+#define PAGE_NONE      __pgprot(_PAGE_PRESENT | _PAGE_RONLY | _PAGE_ACCESSED | mm_cachebits)
+#define PAGE_SHARED    __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED | mm_cachebits)
+#define PAGE_COPY      __pgprot(_PAGE_PRESENT | _PAGE_RONLY | _PAGE_ACCESSED | mm_cachebits)
+#define PAGE_READONLY  __pgprot(_PAGE_PRESENT | _PAGE_RONLY | _PAGE_ACCESSED | mm_cachebits)
+#define PAGE_KERNEL    __pgprot(_PAGE_PRESENT | _PAGE_DIRTY | _PAGE_ACCESSED | mm_cachebits)
+
+/* Alternate definitions that are compile time constants, for
+   initializing protection_map.  The cachebits are fixed later.  */
+#define PAGE_NONE_C    __pgprot(_PAGE_PRESENT | _PAGE_RONLY | _PAGE_ACCESSED)
+#define PAGE_SHARED_C  __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED)
+#define PAGE_COPY_C    __pgprot(_PAGE_PRESENT | _PAGE_RONLY | _PAGE_ACCESSED)
+#define PAGE_READONLY_C        __pgprot(_PAGE_PRESENT | _PAGE_RONLY | _PAGE_ACCESSED)
+
+/*
+ * The m68k can't do page protection for execute, and considers that the same are read.
+ * Also, write permissions imply read permissions. This is the closest we can get..
+ */
+#define __P000 PAGE_NONE_C
+#define __P001 PAGE_READONLY_C
+#define __P010 PAGE_COPY_C
+#define __P011 PAGE_COPY_C
+#define __P100 PAGE_READONLY_C
+#define __P101 PAGE_READONLY_C
+#define __P110 PAGE_COPY_C
+#define __P111 PAGE_COPY_C
+
+#define __S000 PAGE_NONE_C
+#define __S001 PAGE_READONLY_C
+#define __S010 PAGE_SHARED_C
+#define __S011 PAGE_SHARED_C
+#define __S100 PAGE_READONLY_C
+#define __S101 PAGE_READONLY_C
+#define __S110 PAGE_SHARED_C
+#define __S111 PAGE_SHARED_C
+
+/*
+ * Conversion functions: convert a page and protection to a page entry,
+ * and a page entry and page directory to the page they refer to.
+ */
+#define __mk_pte(page, pgprot) \
+({                                                                     \
+       pte_t __pte;                                                    \
+                                                                       \
+       pte_val(__pte) = __pa(page) + pgprot_val(pgprot);               \
+       __pte;                                                          \
+})
+#define mk_pte(page, pgprot) __mk_pte(page_address(page), (pgprot))
+#define mk_pte_phys(physpage, pgprot) \
+({                                                                     \
+       pte_t __pte;                                                    \
+                                                                       \
+       pte_val(__pte) = (physpage) + pgprot_val(pgprot);               \
+       __pte;                                                          \
+})
+
+extern inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
+{ pte_val(pte) = (pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot); return pte; }
+
+extern inline void pmd_set(pmd_t * pmdp, pte_t * ptep)
+{
+       unsigned long ptbl = virt_to_phys(ptep) | _PAGE_TABLE | _PAGE_ACCESSED;
+       unsigned long *ptr = pmdp->pmd;
+       short i = 16;
+       while (--i >= 0) {
+               *ptr++ = ptbl;
+               ptbl += (sizeof(pte_t)*PTRS_PER_PTE/16);
+       }
+}
+
+extern inline void pgd_set(pgd_t * pgdp, pmd_t * pmdp)
+{ pgd_val(*pgdp) = _PAGE_TABLE | _PAGE_ACCESSED | __pa(pmdp); }
+
+#define __pte_page(pte) ((unsigned long)__va(pte_val(pte) & PAGE_MASK))
+#define __pmd_page(pmd) ((unsigned long)__va(pmd_val(pmd) & _TABLE_MASK))
+#define __pgd_page(pgd) ((unsigned long)__va(pgd_val(pgd) & _TABLE_MASK))
+
+
+#define pte_none(pte)          (!pte_val(pte))
+#define pte_present(pte)       (pte_val(pte) & (_PAGE_PRESENT | _PAGE_FAKE_SUPER))
+#define pte_clear(ptep)                ({ pte_val(*(ptep)) = 0; })
+#define pte_pagenr(pte)                ((__pte_page(pte) - PAGE_OFFSET) >> PAGE_SHIFT)
+
+#define pmd_none(pmd)          (!pmd_val(pmd))
+#define pmd_bad(pmd)           ((pmd_val(pmd) & _DESCTYPE_MASK) != _PAGE_TABLE)
+#define pmd_present(pmd)       (pmd_val(pmd) & _PAGE_TABLE)
+#define pmd_clear(pmdp) ({                     \
+       unsigned long *__ptr = pmdp->pmd;       \
+       short __i = 16;                         \
+       while (--__i >= 0)                      \
+               *__ptr++ = 0;                   \
+})
+
+
+#define pgd_none(pgd)          (!pgd_val(pgd))
+#define pgd_bad(pgd)           ((pgd_val(pgd) & _DESCTYPE_MASK) != _PAGE_TABLE)
+#define pgd_present(pgd)       (pgd_val(pgd) & _PAGE_TABLE)
+#define pgd_clear(pgdp)                ({ pgd_val(*pgdp) = 0; })
+/* Permanent address of a page. */
+#define page_address(page)     ({ if (!(page)->virtual) BUG(); (page)->virtual; })
+#define __page_address(page)   (PAGE_OFFSET + (((page) - mem_map) << PAGE_SHIFT))
+#define pte_page(pte)          (mem_map+pte_pagenr(pte))
+
+#define pte_ERROR(e) \
+       printk("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, pte_val(e))
+#define pmd_ERROR(e) \
+       printk("%s:%d: bad pmd %08lx.\n", __FILE__, __LINE__, pmd_val(e))
+#define pgd_ERROR(e) \
+       printk("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pgd_val(e))
+
+
+/*
+ * The following only work if pte_present() is true.
+ * Undefined behaviour if not..
+ */
+extern inline int pte_read(pte_t pte)          { return 1; }
+extern inline int pte_write(pte_t pte)         { return !(pte_val(pte) & _PAGE_RONLY); }
+extern inline int pte_exec(pte_t pte)          { return 1; }
+extern inline int pte_dirty(pte_t pte)         { return pte_val(pte) & _PAGE_DIRTY; }
+extern inline int pte_young(pte_t pte)         { return pte_val(pte) & _PAGE_ACCESSED; }
+
+extern inline pte_t pte_wrprotect(pte_t pte)   { pte_val(pte) |= _PAGE_RONLY; return pte; }
+extern inline pte_t pte_rdprotect(pte_t pte)   { return pte; }
+extern inline pte_t pte_exprotect(pte_t pte)   { return pte; }
+extern inline pte_t pte_mkclean(pte_t pte)     { pte_val(pte) &= ~_PAGE_DIRTY; return pte; }
+extern inline pte_t pte_mkold(pte_t pte)       { pte_val(pte) &= ~_PAGE_ACCESSED; return pte; }
+extern inline pte_t pte_mkwrite(pte_t pte)     { pte_val(pte) &= ~_PAGE_RONLY; return pte; }
+extern inline pte_t pte_mkread(pte_t pte)      { return pte; }
+extern inline pte_t pte_mkexec(pte_t pte)      { return pte; }
+extern inline pte_t pte_mkdirty(pte_t pte)     { pte_val(pte) |= _PAGE_DIRTY; return pte; }
+extern inline pte_t pte_mkyoung(pte_t pte)     { pte_val(pte) |= _PAGE_ACCESSED; return pte; }
+extern inline pte_t pte_mknocache(pte_t pte)
+{
+       pte_val(pte) = (pte_val(pte) & _CACHEMASK040) | m68k_pgtable_cachemode;
+       return pte;
+}
+extern inline pte_t pte_mkcache(pte_t pte)     { pte_val(pte) = (pte_val(pte) & _CACHEMASK040) | m68k_supervisor_cachemode; return pte; }
+
+#define PAGE_DIR_OFFSET(tsk,address) pgd_offset((tsk),(address))
+
+#define pgd_index(address)     ((address) >> PGDIR_SHIFT)
+
+/* to find an entry in a page-table-directory */
+extern inline pgd_t * pgd_offset(struct mm_struct * mm, unsigned long address)
+{
+       return mm->pgd + pgd_index(address);
+}
+
+#define swapper_pg_dir kernel_pg_dir
+extern pgd_t kernel_pg_dir[128];
+
+extern inline pgd_t * pgd_offset_k(unsigned long address)
+{
+       return kernel_pg_dir + (address >> PGDIR_SHIFT);
+}
+
+
+/* Find an entry in the second-level page table.. */
+extern inline pmd_t * pmd_offset(pgd_t * dir, unsigned long address)
+{
+       return (pmd_t *)__pgd_page(*dir) + ((address >> PMD_SHIFT) & (PTRS_PER_PMD-1));
+}
+
+/* Find an entry in the third-level page table.. */ 
+extern inline pte_t * pte_offset(pmd_t * pmdp, unsigned long address)
+{
+       return (pte_t *)__pmd_page(*pmdp) + ((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1));
+}
+
+
+/*
+ * Allocate and free page tables. The xxx_kernel() versions are
+ * used to allocate a kernel page table - this turns on ASN bits
+ * if any.
+ */
+
+/* Prior to calling these routines, the page should have been flushed
+ * from both the cache and ATC, or the CPU might not notice that the
+ * cache setting for the page has been changed. -jskov
+ */
+static inline void nocache_page (unsigned long vaddr)
+{
+       if (CPU_IS_040_OR_060) {
+               pgd_t *dir;
+               pmd_t *pmdp;
+               pte_t *ptep;
+
+               dir = pgd_offset_k(vaddr);
+               pmdp = pmd_offset(dir,vaddr);
+               ptep = pte_offset(pmdp,vaddr);
+               *ptep = pte_mknocache(*ptep);
+       }
+}
+
+static inline void cache_page (unsigned long vaddr)
+{
+       if (CPU_IS_040_OR_060) {
+               pgd_t *dir;
+               pmd_t *pmdp;
+               pte_t *ptep;
+
+               dir = pgd_offset_k(vaddr);
+               pmdp = pmd_offset(dir,vaddr);
+               ptep = pte_offset(pmdp,vaddr);
+               *ptep = pte_mkcache(*ptep);
+       }
+}
+
+
+#endif /* !__ASSEMBLY__ */
+#endif /* _MOTOROLA_PGTABLE_H */
index 80e5269a2448e6ca9158a6779c206c999e632f0a..40915d41c8ec9f80d82f06f481be510187e9d19f 100644 (file)
@@ -160,7 +160,7 @@ static inline void *__va(unsigned long x)
 #endif /* CONFIG_SUN3 */
 
 #define MAP_NR(addr)           (((unsigned long)(addr)-PAGE_OFFSET) >> PAGE_SHIFT)
-#define virt_to_page(kaddr)    (mem_map + (((unsigned long)(addr)-PAGE_OFFSET) >> PAGE_SHIFT))
+#define virt_to_page(kaddr)    (mem_map + (((unsigned long)(kaddr)-PAGE_OFFSET) >> PAGE_SHIFT))
 #define VALID_PAGE(page)       ((page - mem_map) < max_mapnr)
 
 #ifndef CONFIG_SUN3
index 2207a1eb236708566c91bd30f6da9047fecfbd42..7f608ec38d3a2fda353668e9978bc9f4fb9298b8 100644 (file)
@@ -23,4 +23,8 @@
 
 #define MAXHOSTNAMELEN 64      /* max length of hostname */
 
+#ifdef __KERNEL__
+# define CLOCKS_PER_SEC        HZ      /* frequency at which times() counts */
+#endif
+
 #endif /* _M68K_PARAM_H */
index 028b7c40ea1bb9ad6fd5c33c6f2bb4ab6ec74955..8778ec6d5d94f3128816818eecf8c6eba722c9fe 100644 (file)
-#ifndef _M68K_PGALLOC_H
-#define _M68K_PGALLOC_H
+
+#ifndef M68K_PGALLOC_H
+#define M68K_PGALLOC_H
 
 #include <asm/setup.h>
 #include <asm/virtconvert.h>
 
-extern struct pgtable_cache_struct {
-       unsigned long *pmd_cache;
-       unsigned long *pte_cache;
-/* This counts in units of pointer tables, of which can be eight per page. */
-       unsigned long pgtable_cache_sz;
-} quicklists;
-
-#define pgd_quicklist ((unsigned long *)0)
-#define pmd_quicklist (quicklists.pmd_cache)
-#define pte_quicklist (quicklists.pte_cache)
-/* This isn't accurate because of fragmentation of allocated pages for
-   pointer tables, but that should not be a problem. */
-#define pgtable_cache_size ((quicklists.pgtable_cache_sz+7)/8)
-
-extern pte_t *get_pte_slow(pmd_t *pmd, unsigned long offset);
-extern pmd_t *get_pmd_slow(pgd_t *pgd, unsigned long offset);
-
-extern pmd_t *get_pointer_table(void);
-extern int free_pointer_table(pmd_t *);
-
-extern inline pte_t *get_pte_fast(void)
-{
-       unsigned long *ret;
-
-       ret = pte_quicklist;
-       if (ret) {
-               pte_quicklist = (unsigned long *)*ret;
-               ret[0] = 0;
-               quicklists.pgtable_cache_sz -= 8;
-       }
-       return (pte_t *)ret;
-}
-
-extern inline void free_pte_fast(pte_t *pte)
-{
-       *(unsigned long *)pte = (unsigned long)pte_quicklist;
-       pte_quicklist = (unsigned long *)pte;
-       quicklists.pgtable_cache_sz += 8;
-}
-
-extern inline void free_pte_slow(pte_t *pte)
-{
-       cache_page((unsigned long)pte);
-       free_page((unsigned long) pte);
-}
-
-extern inline pmd_t *get_pmd_fast(void)
-{
-       unsigned long *ret;
-
-       ret = pmd_quicklist;
-       if (ret) {
-               pmd_quicklist = (unsigned long *)*ret;
-               ret[0] = 0;
-               quicklists.pgtable_cache_sz--;
-       }
-       return (pmd_t *)ret;
-}
-
-extern inline void free_pmd_fast(pmd_t *pmd)
-{
-       *(unsigned long *)pmd = (unsigned long)pmd_quicklist;
-       pmd_quicklist = (unsigned long *) pmd;
-       quicklists.pgtable_cache_sz++;
-}
-
-extern inline int free_pmd_slow(pmd_t *pmd)
-{
-       return free_pointer_table(pmd);
-}
-
-/* The pgd cache is folded into the pmd cache, so these are dummy routines. */
-extern inline pgd_t *get_pgd_fast(void)
-{
-       return (pgd_t *)0;
-}
-
-extern inline void free_pgd_fast(pgd_t *pgd)
-{
-}
-
-extern inline void free_pgd_slow(pgd_t *pgd)
-{
-}
-
-extern void __bad_pte(pmd_t *pmd);
-extern void __bad_pmd(pgd_t *pgd);
-
-extern inline void pte_free(pte_t *pte)
-{
-       free_pte_fast(pte);
-}
-
-extern inline pte_t *pte_alloc(pmd_t *pmd, unsigned long address)
-{
-       address = (address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1);
-       if (pmd_none(*pmd)) {
-               pte_t *page = get_pte_fast();
-
-               if (!page)
-                       return get_pte_slow(pmd, address);
-               pmd_set(pmd,page);
-               return page + address;
-       }
-       if (pmd_bad(*pmd)) {
-               __bad_pte(pmd);
-               return NULL;
-       }
-       return (pte_t *)__pmd_page(*pmd) + address;
-}
-
-extern inline void pmd_free(pmd_t *pmd)
-{
-       free_pmd_fast(pmd);
-}
-
-extern inline pmd_t *pmd_alloc(pgd_t *pgd, unsigned long address)
-{
-       address = (address >> PMD_SHIFT) & (PTRS_PER_PMD - 1);
-       if (pgd_none(*pgd)) {
-               pmd_t *page = get_pmd_fast();
-
-               if (!page)
-                       return get_pmd_slow(pgd, address);
-               pgd_set(pgd, page);
-               return page + address;
-       }
-       if (pgd_bad(*pgd)) {
-               __bad_pmd(pgd);
-               return NULL;
-       }
-       return (pmd_t *)__pgd_page(*pgd) + address;
-}
-
-extern inline void pte_free_kernel(pte_t *pte)
-{
-       free_pte_fast(pte);
-}
-
-extern inline pte_t *pte_alloc_kernel(pmd_t *pmd, unsigned long address)
-{
-       return pte_alloc(pmd, address);
-}
-
-extern inline void pmd_free_kernel(pmd_t *pmd)
-{
-       free_pmd_fast(pmd);
-}
-
-extern inline pmd_t *pmd_alloc_kernel(pgd_t *pgd, unsigned long address)
-{
-       return pmd_alloc(pgd, address);
-}
-
-extern inline void pgd_free(pgd_t *pgd)
-{
-       free_pmd_fast((pmd_t *)pgd);
-}
-
-extern inline pgd_t *pgd_alloc(void)
-{
-       pgd_t *pgd = (pgd_t *)get_pmd_fast();
-       if (!pgd)
-               pgd = (pgd_t *)get_pointer_table();
-       return pgd;
-}
-
-extern int do_check_pgt_cache(int, int);
-
-extern inline void set_pgdir(unsigned long address, pgd_t entry)
-{
-}
-
-
 /*
  * Cache handling functions
  */
@@ -325,82 +152,13 @@ extern inline void flush_icache_range (unsigned long address,
        }
 }
 
+#define flush_icache_page(vma,pg)              do { } while (0)
 
-/*
- * flush all user-space atc entries.
- */
-static inline void __flush_tlb(void)
-{
-       if (CPU_IS_040_OR_060)
-               __asm__ __volatile__(".chip 68040\n\t"
-                                    "pflushan\n\t"
-                                    ".chip 68k");
-       else
-               __asm__ __volatile__("pflush #0,#4");
-}
-
-static inline void __flush_tlb_one(unsigned long addr)
-{
-       if (CPU_IS_040_OR_060) {
-               __asm__ __volatile__(".chip 68040\n\t"
-                                    "pflush (%0)\n\t"
-                                    ".chip 68k"
-                                    : : "a" (addr));
-       } else
-               __asm__ __volatile__("pflush #0,#4,(%0)" : : "a" (addr));
-}
-
-#define flush_tlb() __flush_tlb()
-
-/*
- * flush all atc entries (both kernel and user-space entries).
- */
-static inline void flush_tlb_all(void)
-{
-       if (CPU_IS_040_OR_060)
-               __asm__ __volatile__(".chip 68040\n\t"
-                                    "pflusha\n\t"
-                                    ".chip 68k");
-       else
-               __asm__ __volatile__("pflusha");
-}
-
-static inline void flush_tlb_mm(struct mm_struct *mm)
-{
-       if (mm == current->mm)
-               __flush_tlb();
-}
-
-static inline void flush_tlb_page(struct vm_area_struct *vma, unsigned long addr)
-{
-       if (vma->vm_mm == current->mm)
-               __flush_tlb_one(addr);
-}
-
-static inline void flush_tlb_range(struct mm_struct *mm,
-                                  unsigned long start, unsigned long end)
-{
-       if (mm == current->mm)
-               __flush_tlb();
-}
 
-extern inline void flush_tlb_kernel_page(unsigned long addr)
-{
-       if (CPU_IS_040_OR_060) {
-               mm_segment_t old_fs = get_fs();
-               set_fs(KERNEL_DS);
-               __asm__ __volatile__(".chip 68040\n\t"
-                                    "pflush (%0)\n\t"
-                                    ".chip 68k"
-                                    : : "a" (addr));
-               set_fs(old_fs);
-       } else
-               __asm__ __volatile__("pflush #4,#4,(%0)" : : "a" (addr));
-}
-
-extern inline void flush_tlb_pgtables(struct mm_struct *mm,
-                                     unsigned long start, unsigned long end)
-{
-}
+#ifdef CONFIG_SUN3
+#include <asm/sun3_pgalloc.h>
+#else
+#include <asm/motorola_pgalloc.h>
+#endif
 
-#endif /* _M68K_PGALLOC_H */
+#endif /* M68K_PGALLOC_H */
index 655d604d24c2dfe469977d68abf656fd35af6450..71fd0ae750ea6426b3422b78601c8c0ea06438ee 100644 (file)
 
 
 /* PMD_SHIFT determines the size of the area a second-level page table can map */
+#ifdef CONFIG_SUN3
+#define PMD_SHIFT       17
+#else
 #define PMD_SHIFT      22
+#endif
 #define PMD_SIZE       (1UL << PMD_SHIFT)
 #define PMD_MASK       (~(PMD_SIZE-1))
 
 /* PGDIR_SHIFT determines what a third-level page table entry can map */
+#ifdef CONFIG_SUN3
+#define PGDIR_SHIFT     17
+#else
 #define PGDIR_SHIFT    25
+#endif
 #define PGDIR_SIZE     (1UL << PGDIR_SHIFT)
 #define PGDIR_MASK     (~(PGDIR_SIZE-1))
 
  * entries per page directory level: the m68k is configured as three-level,
  * so we do have PMD level physically.
  */
+#ifdef CONFIG_SUN3
+#define PTRS_PER_PTE   16
+#define PTRS_PER_PMD   1
+#define PTRS_PER_PGD   2048
+#else
 #define PTRS_PER_PTE   1024
 #define PTRS_PER_PMD   8
 #define PTRS_PER_PGD   128
+#endif
 #define USER_PTRS_PER_PGD      (TASK_SIZE/PGDIR_SIZE)
 #define FIRST_USER_PGD_NR      0
 
 /* Virtual address region for use by kernel_map() */
+#ifdef CONFIG_SUN3
+#define KMAP_START     0x0DC00000
+#define KMAP_END       0x0E000000
+#else
 #define        KMAP_START      0xd0000000
 #define        KMAP_END        0xf0000000
+#endif
 
+#ifndef CONFIG_SUN3
 /* Just any arbitrary offset to the start of the vmalloc VM area: the
  * current 8MB value just means that there will be a 8MB "hole" after the
  * physical memory until the kernel virtual memory starts.  That means that
 #define VMALLOC_START (((unsigned long) high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
 #define VMALLOC_VMADDR(x) ((unsigned long)(x))
 #define VMALLOC_END KMAP_START
-
-#endif /* __ASSEMBLY__ */
-
-/*
- * Definitions for MMU descriptors
- */
-#define _PAGE_PRESENT  0x001
-#define _PAGE_SHORT    0x002
-#define _PAGE_RONLY    0x004
-#define _PAGE_ACCESSED 0x008
-#define _PAGE_DIRTY    0x010
-#define _PAGE_SUPER    0x080   /* 68040 supervisor only */
-#define _PAGE_FAKE_SUPER 0x200 /* fake supervisor only on 680[23]0 */
-#define _PAGE_GLOBAL040        0x400   /* 68040 global bit, used for kva descs */
-#define _PAGE_COW      0x800   /* implemented in software */
-#define _PAGE_NOCACHE030 0x040 /* 68030 no-cache mode */
-#define _PAGE_NOCACHE  0x060   /* 68040 cache mode, non-serialized */
-#define _PAGE_NOCACHE_S        0x040   /* 68040 no-cache mode, serialized */
-#define _PAGE_CACHE040 0x020   /* 68040 cache mode, cachable, copyback */
-#define _PAGE_CACHE040W        0x000   /* 68040 cache mode, cachable, write-through */
-
-/* Page protection values within PTE. */
-#define SUN3_PAGE_VALID     (0x80000000)
-#define SUN3_PAGE_WRITEABLE (0x40000000)
-#define SUN3_PAGE_SYSTEM    (0x20000000)
-#define SUN3_PAGE_NOCACHE   (0x10000000)
-#define SUN3_PAGE_ACCESSED  (0x02000000)
-#define SUN3_PAGE_MODIFIED  (0x01000000)
-
-#define _DESCTYPE_MASK 0x003
-
-#define _CACHEMASK040  (~0x060)
-#define _TABLE_MASK    (0xfffffe00)
-
-#define _PAGE_TABLE    (_PAGE_SHORT)
-#define _PAGE_CHG_MASK  (PAGE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_NOCACHE)
-
-#ifndef __ASSEMBLY__
-
-/* This is the cache mode to be used for pages containing page descriptors for
- * processors >= '040. It is in pte_mknocache(), and the variable is defined
- * and initialized in head.S */
-extern int m68k_pgtable_cachemode;
-
-/* This is the cache mode for normal pages, for supervisor access on
- * processors >= '040. It is used in pte_mkcache(), and the variable is
- * defined and initialized in head.S */
-
-#if defined(CONFIG_060_WRITETHROUGH)
-extern int m68k_supervisor_cachemode;
-#else
-#define m68k_supervisor_cachemode _PAGE_CACHE040
-#endif
-
-#if defined(CPU_M68040_OR_M68060_ONLY)
-#define mm_cachebits _PAGE_CACHE040
-#elif defined(CPU_M68020_OR_M68030_ONLY)
-#define mm_cachebits 0
 #else
-extern unsigned long mm_cachebits;
-#endif
-
-#define PAGE_NONE      __pgprot(_PAGE_PRESENT | _PAGE_RONLY | _PAGE_ACCESSED | mm_cachebits)
-#define PAGE_SHARED    __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED | mm_cachebits)
-#define PAGE_COPY      __pgprot(_PAGE_PRESENT | _PAGE_RONLY | _PAGE_ACCESSED | mm_cachebits)
-#define PAGE_READONLY  __pgprot(_PAGE_PRESENT | _PAGE_RONLY | _PAGE_ACCESSED | mm_cachebits)
-#define PAGE_KERNEL    __pgprot(_PAGE_PRESENT | _PAGE_DIRTY | _PAGE_ACCESSED | mm_cachebits)
-
-/* Alternate definitions that are compile time constants, for
-   initializing protection_map.  The cachebits are fixed later.  */
-#define PAGE_NONE_C    __pgprot(_PAGE_PRESENT | _PAGE_RONLY | _PAGE_ACCESSED)
-#define PAGE_SHARED_C  __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED)
-#define PAGE_COPY_C    __pgprot(_PAGE_PRESENT | _PAGE_RONLY | _PAGE_ACCESSED)
-#define PAGE_READONLY_C        __pgprot(_PAGE_PRESENT | _PAGE_RONLY | _PAGE_ACCESSED)
-
-/*
- * The m68k can't do page protection for execute, and considers that the same are read.
- * Also, write permissions imply read permissions. This is the closest we can get..
- */
-#define __P000 PAGE_NONE_C
-#define __P001 PAGE_READONLY_C
-#define __P010 PAGE_COPY_C
-#define __P011 PAGE_COPY_C
-#define __P100 PAGE_READONLY_C
-#define __P101 PAGE_READONLY_C
-#define __P110 PAGE_COPY_C
-#define __P111 PAGE_COPY_C
-
-#define __S000 PAGE_NONE_C
-#define __S001 PAGE_READONLY_C
-#define __S010 PAGE_SHARED_C
-#define __S011 PAGE_SHARED_C
-#define __S100 PAGE_READONLY_C
-#define __S101 PAGE_READONLY_C
-#define __S110 PAGE_SHARED_C
-#define __S111 PAGE_SHARED_C
+extern unsigned long vmalloc_end;
+#define VMALLOC_START 0x0f800000
+#define VMALLOC_VMADDR(x) ((unsigned long)(x))
+#define VMALLOC_END vmalloc_end
+#endif /* CONFIG_SUN3 */
 
 /* zero page used for uninitialized stuff */
 extern unsigned long empty_zero_page;
@@ -182,176 +112,7 @@ extern pte_t * __bad_pagetable(void);
 
 /* sizeof(void*)==1<<SIZEOF_PTR_LOG2 */
 /* 64-bit machines, beware!  SRB. */
-#define SIZEOF_PTR_LOG2                        2
-
-/*
- * Conversion functions: convert a page and protection to a page entry,
- * and a page entry and page directory to the page they refer to.
- */
-#define __mk_pte(page, pgprot) \
-({                                                                     \
-       pte_t __pte;                                                    \
-                                                                       \
-       pte_val(__pte) = __pa((page) + pgprot_val(pgprot);              \
-       __pte;                                                          \
-})
-#define mk_pte(page, pgprot) __mk_pte(page_address(page), (pgprot))
-#define mk_pte_phys(physpage, pgprot) \
-({                                                                     \
-       pte_t __pte;                                                    \
-                                                                       \
-       pte_val(__pte) = (physpage) + pgprot_val(pgprot);               \
-       __pte;                                                          \
-})
-
-extern inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
-{ pte_val(pte) = (pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot); return pte; }
-
-extern inline void pmd_set(pmd_t * pmdp, pte_t * ptep)
-{
-       unsigned long ptbl = virt_to_phys(ptep) | _PAGE_TABLE | _PAGE_ACCESSED;
-       unsigned long *ptr = pmdp->pmd;
-       short i = 16;
-       while (--i >= 0) {
-               *ptr++ = ptbl;
-               ptbl += (sizeof(pte_t)*PTRS_PER_PTE/16);
-       }
-}
-
-extern inline void pgd_set(pgd_t * pgdp, pmd_t * pmdp)
-{ pgd_val(*pgdp) = _PAGE_TABLE | _PAGE_ACCESSED | __pa(pmdp); }
-
-#define __pte_page(pte) ((unsigned long)__va(pte_val(pte) & PAGE_MASK))
-#define __pmd_page(pmd) ((unsigned long)__va(pmd_val(pmd) & _TABLE_MASK))
-#define __pgd_page(pgd) ((unsigned long)__va(pgd_val(pgd) & _TABLE_MASK))
-
-#define pte_none(pte)          (!pte_val(pte))
-#define pte_present(pte)       (pte_val(pte) & (_PAGE_PRESENT | _PAGE_FAKE_SUPER))
-#define pte_clear(ptep)                ({ pte_val(*(ptep)) = 0; })
-
-#define pmd_none(pmd)          (!pmd_val(pmd))
-#define pmd_bad(pmd)           ((pmd_val(pmd) & _DESCTYPE_MASK) != _PAGE_TABLE)
-#define pmd_present(pmd)       (pmd_val(pmd) & _PAGE_TABLE)
-#define pmd_clear(pmdp) ({                     \
-       unsigned long *__ptr = pmdp->pmd;       \
-       short __i = 16;                         \
-       while (--__i >= 0)                      \
-               *__ptr++ = 0;                   \
-})
-
-#define pgd_none(pgd)          (!pgd_val(pgd))
-#define pgd_bad(pgd)           ((pgd_val(pgd) & _DESCTYPE_MASK) != _PAGE_TABLE)
-#define pgd_present(pgd)       (pgd_val(pgd) & _PAGE_TABLE)
-#define pgd_clear(pgdp)                ({ pgd_val(*pgdp) = 0; })
-
-/* Permanent address of a page. */
-#define page_address(page)     ((page)->virtual)
-#define __page_address(page)   (PAGE_OFFSET + (((page) - mem_map) << PAGE_SHIFT))
-#define pte_page(pte)          (mem_map+((__pte_page(pte) - PAGE_OFFSET) >> PAGE_SHIFT))
-
-#define pte_ERROR(e) \
-       printk("%s:%d: bad pte %p(%08lx).\n", __FILE__, __LINE__, &(e), pte_val(e))
-#define pmd_ERROR(e) \
-       printk("%s:%d: bad pmd %p(%08lx).\n", __FILE__, __LINE__, &(e), pmd_val(e))
-#define pgd_ERROR(e) \
-       printk("%s:%d: bad pgd %p(%08lx).\n", __FILE__, __LINE__, &(e), pgd_val(e))
-
-/*
- * The following only work if pte_present() is true.
- * Undefined behaviour if not..
- */
-extern inline int pte_read(pte_t pte)          { return 1; }
-extern inline int pte_write(pte_t pte)         { return !(pte_val(pte) & _PAGE_RONLY); }
-extern inline int pte_exec(pte_t pte)          { return 1; }
-extern inline int pte_dirty(pte_t pte)         { return pte_val(pte) & _PAGE_DIRTY; }
-extern inline int pte_young(pte_t pte)         { return pte_val(pte) & _PAGE_ACCESSED; }
-
-extern inline pte_t pte_wrprotect(pte_t pte)   { pte_val(pte) |= _PAGE_RONLY; return pte; }
-extern inline pte_t pte_rdprotect(pte_t pte)   { return pte; }
-extern inline pte_t pte_exprotect(pte_t pte)   { return pte; }
-extern inline pte_t pte_mkclean(pte_t pte)     { pte_val(pte) &= ~_PAGE_DIRTY; return pte; }
-extern inline pte_t pte_mkold(pte_t pte)       { pte_val(pte) &= ~_PAGE_ACCESSED; return pte; }
-extern inline pte_t pte_mkwrite(pte_t pte)     { pte_val(pte) &= ~_PAGE_RONLY; return pte; }
-extern inline pte_t pte_mkread(pte_t pte)      { return pte; }
-extern inline pte_t pte_mkexec(pte_t pte)      { return pte; }
-extern inline pte_t pte_mkdirty(pte_t pte)     { pte_val(pte) |= _PAGE_DIRTY; return pte; }
-extern inline pte_t pte_mkyoung(pte_t pte)     { pte_val(pte) |= _PAGE_ACCESSED; return pte; }
-extern inline pte_t pte_mknocache(pte_t pte)
-{
-       pte_val(pte) = (pte_val(pte) & _CACHEMASK040) | m68k_pgtable_cachemode;
-       return pte;
-}
-extern inline pte_t pte_mkcache(pte_t pte)     { pte_val(pte) = (pte_val(pte) & _CACHEMASK040) | m68k_supervisor_cachemode; return pte; }
-
-#define PAGE_DIR_OFFSET(tsk,address) pgd_offset((tsk),(address))
-
-#define pgd_index(address)     ((address) >> PGDIR_SHIFT)
-
-/* to find an entry in a page-table-directory */
-extern inline pgd_t * pgd_offset(struct mm_struct * mm, unsigned long address)
-{
-       return mm->pgd + pgd_index(address);
-}
-
-#define swapper_pg_dir kernel_pg_dir
-extern pgd_t kernel_pg_dir[128];
-
-extern inline pgd_t * pgd_offset_k(unsigned long address)
-{
-       return kernel_pg_dir + (address >> PGDIR_SHIFT);
-}
-
-
-/* Find an entry in the second-level page table.. */
-extern inline pmd_t * pmd_offset(pgd_t * dir, unsigned long address)
-{
-       return (pmd_t *)__pgd_page(*dir) + ((address >> PMD_SHIFT) & (PTRS_PER_PMD-1));
-}
-
-/* Find an entry in the third-level page table.. */ 
-extern inline pte_t * pte_offset(pmd_t * pmdp, unsigned long address)
-{
-       return (pte_t *)__pmd_page(*pmdp) + ((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1));
-}
-
-/*
- * Allocate and free page tables. The xxx_kernel() versions are
- * used to allocate a kernel page table - this turns on ASN bits
- * if any.
- */
-
-/* Prior to calling these routines, the page should have been flushed
- * from both the cache and ATC, or the CPU might not notice that the
- * cache setting for the page has been changed. -jskov
- */
-static inline void nocache_page (unsigned long vaddr)
-{
-       if (CPU_IS_040_OR_060) {
-               pgd_t *dir;
-               pmd_t *pmdp;
-               pte_t *ptep;
-
-               dir = pgd_offset_k(vaddr);
-               pmdp = pmd_offset(dir,vaddr);
-               ptep = pte_offset(pmdp,vaddr);
-               *ptep = pte_mknocache(*ptep);
-       }
-}
-
-static inline void cache_page (unsigned long vaddr)
-{
-       if (CPU_IS_040_OR_060) {
-               pgd_t *dir;
-               pmd_t *pmdp;
-               pte_t *ptep;
-
-               dir = pgd_offset_k(vaddr);
-               pmdp = pmd_offset(dir,vaddr);
-               ptep = pte_offset(pmdp,vaddr);
-               *ptep = pte_mkcache(*ptep);
-       }
-}
-
+#define SIZEOF_PTR_LOG2                               2
 
 /*
  * Check if the addr/len goes up to the end of a physical
@@ -374,13 +135,24 @@ extern void kernel_set_cachemode(void *addr, unsigned long size, int cmode);
 
 /*
  * The m68k doesn't have any external MMU info: the kernel page
- * tables contain all the necessary information.
+ * tables contain all the necessary information.  The Sun3 does, but
+ * they are updated on demand.
  */
 extern inline void update_mmu_cache(struct vm_area_struct * vma,
        unsigned long address, pte_t pte)
 {
 }
 
+#ifdef CONFIG_SUN3
+/* Macros to (de)construct the fake PTEs representing swap pages. */
+#define SWP_TYPE(x)                ((x).val & 0x7F)
+#define SWP_OFFSET(x)      (((x).val) >> 7)
+#define SWP_ENTRY(type,offset) ((swp_entry_t) { ((type) | ((offset) << 7)) })
+#define pte_to_swp_entry(pte)          ((swp_entry_t) { pte_val(pte) })
+#define swp_entry_to_pte(x)            ((pte_t) { (x).val })
+
+#else
+
 /* Encode and de-code a swap entry (must be !pte_none(e) && !pte_present(e)) */
 #define SWP_TYPE(x)                    (((x).val >> 1) & 0xff)
 #define SWP_OFFSET(x)                  ((x).val >> 10)
@@ -388,7 +160,9 @@ extern inline void update_mmu_cache(struct vm_area_struct * vma,
 #define pte_to_swp_entry(pte)          ((swp_entry_t) { pte_val(pte) })
 #define swp_entry_to_pte(x)            ((pte_t) { (x).val })
 
-#endif /* __ASSEMBLY__ */
+#endif CONFIG_SUN3
+
+#endif /* !__ASSEMBLY__ */
 
 /* Needs to be defined here and not in linux/mm.h, as it is arch dependent */
 #define PageSkip(page)         (0)
@@ -396,6 +170,16 @@ extern inline void update_mmu_cache(struct vm_area_struct * vma,
 
 #define io_remap_page_range remap_page_range
 
+/* MMU-specific headers */
+
+#ifdef CONFIG_SUN3
+#include <asm/sun3_pgtable.h>
+#else
+#include <asm/motorola_pgtable.h>
+#endif
+
+#ifndef __ASSEMBLY__
 #include <asm-generic/pgtable.h>
+#endif /* !__ASSEMBLY__ */
 
 #endif /* _M68K_PGTABLE_H */
index 9083bc1ec21510366621e1aaebe3e6fad4917f50..88993462d2c3b4dd1eb542b14e1a983d08451390 100644 (file)
@@ -23,7 +23,6 @@ extern int q40kbd_translate(unsigned char scancode, unsigned char *keycode,
                           char raw_mode);
 extern char q40kbd_unexpected_up(unsigned char keycode);
 extern void q40kbd_leds(unsigned char leds);
-extern int q40kbd_is_sysrq(unsigned char keycode);
 extern void q40kbd_init_hw(void);
 extern unsigned char q40kbd_sysrq_xlate[128];
 
@@ -36,7 +35,6 @@ extern unsigned char q40kbd_sysrq_xlate[128];
 #define kbd_unexpected_up      q40kbd_unexpected_up
 #define kbd_leds               q40kbd_leds
 #define kbd_init_hw            q40kbd_init_hw
-#define kbd_is_sysrq           q40kbd_is_sysrq
 #define kbd_sysrq_xlate                q40kbd_sysrq_xlate
 
 
index 89a3e3971cbd9142ee71d6fc97be1514ddc3fbc3..3a346780bef41e1d9600a2c9373de4b4073344d6 100644 (file)
@@ -7,14 +7,12 @@
 
 #include <asm/atomic.h>
 
-#define local_bh_disable()     (local_bh_count(smp_processor_id())++)
-#define local_bh_enable()      (local_bh_count(smp_processor_id())--)
+#define cpu_bh_disable(cpu)    do { local_bh_count(cpu)++; barrier(); } while (0)
+#define cpu_bh_enable(cpu)     do { barrier(); local_bh_count(cpu)--; } while (0)
 
-#define in_softirq() (local_bh_count != 0)
+#define local_bh_disable()     cpu_bh_disable(smp_processor_id())
+#define local_bh_enable()      cpu_bh_enable(smp_processor_id())
 
-/* These are for the irq's testing the lock */
-#define softirq_trylock(cpu)  (local_bh_count(cpu) ? 0 : (local_bh_count(cpu)=1))
-#define softirq_endlock(cpu)  (local_bh_count(cpu) = 0)
-#define synchronize_bh()       barrier()
+#define in_softirq() (local_bh_count(smp_processor_id()) != 0)
 
 #endif
index fec1481758b55d1e124cfba752d6dd61cf0f02f4..20f46e27b5340d962185c332f87b27e48399e0e2 100644 (file)
@@ -1,6 +1,6 @@
 #ifndef __M68K_SPINLOCK_H
 #define __M68K_SPINLOCK_H
 
-#error "m68k doesn't do SMP"
+#error "m68k doesn't do SMP yet"
 
 #endif
index 1d5b008e09d7d40e914c9a4295b0a18b34cdd62d..81b225ef4ac1b6be374850da927bfa603e3ea25b 100644 (file)
@@ -44,8 +44,10 @@ struct stat {
 struct stat64 {
        unsigned char   __pad0[6];
        unsigned short  st_dev;
+       unsigned char   __pad1[4];
 
-       unsigned long long      st_ino;
+#define STAT64_HAS_BROKEN_ST_INO       1
+       unsigned long   __st_ino;
 
        unsigned int    st_mode;
        unsigned int    st_nlink;
@@ -53,14 +55,15 @@ struct stat64 {
        unsigned long   st_uid;
        unsigned long   st_gid;
 
+       unsigned char   __pad2[6];
        unsigned short  st_rdev;
-       unsigned char   __pad3[10];
+       unsigned char   __pad3[4];
 
        long long       st_size;
        unsigned long   st_blksize;
 
-       unsigned long   st_blocks;      /* Number 512-byte blocks allocated. */
        unsigned long   __pad4;         /* future possible st_blocks high bits */
+       unsigned long   st_blocks;      /* Number 512-byte blocks allocated. */
 
        unsigned long   st_atime;
        unsigned long   __pad5;
@@ -71,8 +74,7 @@ struct stat64 {
        unsigned long   st_ctime;
        unsigned long   __pad7;         /* will be high 32 bits of ctime someday */
 
-       unsigned long   __unused1;
-       unsigned long   __unused2;
+       unsigned long long      st_ino;
 };
 
 #endif /* _M68K_STAT_H */
diff --git a/include/asm-m68k/sun3_pgalloc.h b/include/asm-m68k/sun3_pgalloc.h
new file mode 100644 (file)
index 0000000..32a810a
--- /dev/null
@@ -0,0 +1,274 @@
+/* sun3_pgalloc.h --
+ * reorganization around 2.3.39, routines moved from sun3_pgtable.h 
+ *
+ * moved 1/26/2000 Sam Creasey
+ */
+
+#ifndef _SUN3_PGALLOC_H
+#define _SUN3_PGALLOC_H
+
+/* Pagetable caches. */
+//todo: should implement for at least ptes. --m
+#define pgd_quicklist ((unsigned long *) 0)
+#define pmd_quicklist ((unsigned long *) 0)
+#define pte_quicklist ((unsigned long *) 0)
+#define pgtable_cache_size (0L)
+
+/* Allocation and deallocation of various flavours of pagetables. */
+extern inline int free_pmd_fast (pmd_t *pmdp) { return 0; }
+extern inline int free_pmd_slow (pmd_t *pmdp) { return 0; }
+extern inline pmd_t *get_pmd_fast (void) { return (pmd_t *) 0; }
+
+//todo: implement the following properly.
+#define get_pte_fast() ((pte_t *) 0)
+#define get_pte_slow pte_alloc
+#define free_pte_fast(pte)
+#define free_pte_slow pte_free
+
+/* FIXME - when we get this compiling */
+/* erm, now that it's compiling, what do we do with it? */
+#define _KERNPG_TABLE 0
+
+extern inline void pte_free_kernel(pte_t * pte)
+{
+        free_page((unsigned long) pte);
+}
+
+extern const char bad_pmd_string[];
+
+extern inline pte_t * pte_alloc_kernel(pmd_t * pmd, unsigned long address)
+{
+        address = (address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1);
+        if (pmd_none(*pmd)) {
+                pte_t * page = (pte_t *) get_free_page(GFP_KERNEL);
+                if (pmd_none(*pmd)) {
+                        if (page) {
+                                pmd_val(*pmd) = _KERNPG_TABLE + __pa(page);
+                                return page + address;
+                        }
+                        pmd_val(*pmd) = _KERNPG_TABLE + __pa((unsigned long)BAD_PAGETABLE);
+                        return NULL;
+                }
+                free_page((unsigned long) page);
+        }
+        if (pmd_bad(*pmd)) {
+                printk(bad_pmd_string, pmd_val(*pmd));
+               printk("at kernel pgd off %08x\n", (unsigned int)pmd);
+                pmd_val(*pmd) = _KERNPG_TABLE + __pa((unsigned long)BAD_PAGETABLE);
+                return NULL;
+        }
+        return (pte_t *) __pmd_page(*pmd) + address;
+}
+
+/*
+ * allocating and freeing a pmd is trivial: the 1-entry pmd is
+ * inside the pgd, so has no extra memory associated with it.
+ */
+extern inline void pmd_free_kernel(pmd_t * pmd)
+{
+//        pmd_val(*pmd) = 0;
+}
+
+extern inline pmd_t * pmd_alloc_kernel(pgd_t * pgd, unsigned long address)
+{
+        return (pmd_t *) pgd;
+}
+
+extern inline void pte_free(pte_t * pte)
+{
+        free_page((unsigned long) pte);
+}
+
+extern inline pte_t * pte_alloc(pmd_t * pmd, unsigned long address)
+{
+       address = (address >> (PAGE_SHIFT-2)) & 4*(PTRS_PER_PTE - 1);
+
+repeat:
+       if (pmd_none(*pmd))
+               goto getnew;
+       if (pmd_bad(*pmd))
+               goto fix;
+       return (pte_t *) (__pmd_page(*pmd) + address);
+
+getnew:
+{
+       unsigned long page = __get_free_page(GFP_KERNEL);
+       if (!pmd_none(*pmd))
+               goto freenew;
+       if (!page)
+               goto oom;
+       memset((void *)page, 0, PAGE_SIZE);
+//     pmd_val(*pmd) = SUN3_PMD_MAGIC + __pa(page);
+       pmd_val(*pmd) = __pa(page);
+       return (pte_t *) (page + address);
+freenew:
+       free_page(page);
+       goto repeat;
+}
+
+fix:
+       printk(bad_pmd_string, pmd_val(*pmd));
+       printk("in normal pgd offset %08x\n", (unsigned int)pmd);
+oom:
+//     pmd_val(*pmd) = SUN3_PMD_MAGIC + __pa(BAD_PAGETABLE);
+       pmd_val(*pmd) = __pa(BAD_PAGETABLE);
+       return NULL;
+}
+
+/*
+ * allocating and freeing a pmd is trivial: the 1-entry pmd is
+ * inside the pgd, so has no extra memory associated with it.
+ */
+extern inline void pmd_free(pmd_t * pmd)
+{
+        pmd_val(*pmd) = 0;
+}
+
+extern inline pmd_t * pmd_alloc(pgd_t * pgd, unsigned long address)
+{
+        return (pmd_t *) pgd;
+}
+
+extern inline void pgd_free(pgd_t * pgd)
+{
+        free_page((unsigned long) pgd);
+}
+
+extern inline pgd_t * pgd_alloc(void)
+{
+     pgd_t *new_pgd;
+
+     new_pgd = (pgd_t *)get_free_page(GFP_KERNEL);
+     memcpy(new_pgd, swapper_pg_dir, PAGE_SIZE);
+     memset(new_pgd, 0, (PAGE_OFFSET >> PGDIR_SHIFT));
+     return new_pgd;
+}
+
+/* FIXME: the sun3 doesn't have a page table cache! 
+   (but the motorola routine should just return 0) */
+
+extern int do_check_pgt_cache(int, int);
+
+extern inline void set_pgdir(unsigned long address, pgd_t entry)
+{
+}
+
+/* Reserved PMEGs. */
+extern char sun3_reserved_pmeg[SUN3_PMEGS_NUM];
+extern unsigned long pmeg_vaddr[SUN3_PMEGS_NUM];
+extern unsigned char pmeg_alloc[SUN3_PMEGS_NUM];
+extern unsigned char pmeg_ctx[SUN3_PMEGS_NUM];
+
+/* Flush all userspace mappings one by one...  (why no flush command,
+   sun?) */
+static inline void flush_tlb_all(void)
+{
+       unsigned long addr;
+       unsigned char ctx, oldctx;
+
+       oldctx = sun3_get_context();
+       for(addr = 0x00000000; addr < TASK_SIZE; addr += SUN3_PMEG_SIZE) {
+              for(ctx = 0; ctx < 8; ctx++) {
+                      sun3_put_context(ctx);
+                      sun3_put_segmap(addr, SUN3_INVALID_PMEG);
+              }
+       }
+
+       sun3_put_context(oldctx);
+       /* erase all of the userspace pmeg maps, we've clobbered them
+         all anyway */
+       for(addr = 0; addr < SUN3_INVALID_PMEG; addr++) {
+              if(pmeg_alloc[addr] == 1) {
+                      pmeg_alloc[addr] = 0;
+                      pmeg_ctx[addr] = 0;
+                      pmeg_vaddr[addr] = 0;
+              }
+       }
+
+}
+
+/* Clear user TLB entries within the context named in mm */
+static inline void flush_tlb_mm (struct mm_struct *mm)
+{
+     unsigned char oldctx;
+     unsigned char seg;
+     unsigned long i;
+
+     oldctx = sun3_get_context();
+     sun3_put_context(mm->context);
+
+     for(i = 0; i < TASK_SIZE; i += SUN3_PMEG_SIZE) {
+            seg = sun3_get_segmap(i);
+            if(seg == SUN3_INVALID_PMEG)
+                    continue;
+            
+            sun3_put_segmap(i, SUN3_INVALID_PMEG);
+            pmeg_alloc[seg] = 0;
+            pmeg_ctx[seg] = 0;
+            pmeg_vaddr[seg] = 0;
+     }
+
+     sun3_put_context(oldctx);
+                    
+}
+
+/* Flush a single TLB page. In this case, we're limited to flushing a
+   single PMEG */
+static inline void flush_tlb_page (struct vm_area_struct *vma,
+                                  unsigned long addr)
+{
+       unsigned char oldctx;
+       unsigned char i;
+
+       oldctx = sun3_get_context();
+       sun3_put_context(vma->vm_mm->context);
+       addr &= ~SUN3_PMEG_MASK;
+       if((i = sun3_get_segmap(addr)) != SUN3_INVALID_PMEG)
+       {
+               pmeg_alloc[i] = 0;
+               pmeg_ctx[i] = 0;
+               pmeg_vaddr[i] = 0;
+               sun3_put_segmap (addr,  SUN3_INVALID_PMEG);     
+       }
+       sun3_put_context(oldctx);
+
+}
+/* Flush a range of pages from TLB. */
+
+static inline void flush_tlb_range (struct mm_struct *mm,
+                     unsigned long start, unsigned long end)
+{
+       unsigned char seg, oldctx;
+       
+       start &= ~SUN3_PMEG_MASK;
+
+       oldctx = sun3_get_context();
+       sun3_put_context(mm->context);
+
+       while(start < end)
+       {
+               if((seg = sun3_get_segmap(start)) == SUN3_INVALID_PMEG) 
+                    goto next;
+               if(pmeg_ctx[seg] == mm->context) {
+                       pmeg_alloc[seg] = 0;
+                       pmeg_ctx[seg] = 0;
+                       pmeg_vaddr[seg] = 0;
+               }
+               sun3_put_segmap(start, SUN3_INVALID_PMEG);
+       next:
+               start += SUN3_PMEG_SIZE;
+       }
+}
+
+/* Flush kernel page from TLB. */
+static inline void flush_tlb_kernel_page (unsigned long addr)
+{
+       sun3_put_segmap (addr & ~(SUN3_PMEG_SIZE - 1), SUN3_INVALID_PMEG);
+}
+
+extern inline void flush_tlb_pgtables(struct mm_struct *mm,
+                                     unsigned long start, unsigned long end)
+{
+}
+
+#endif /* SUN3_PGALLOC_H */
diff --git a/include/asm-m68k/sun3_pgtable.h b/include/asm-m68k/sun3_pgtable.h
new file mode 100644 (file)
index 0000000..ce9e09a
--- /dev/null
@@ -0,0 +1,219 @@
+#ifndef _SUN3_PGTABLE_H
+#define _SUN3_PGTABLE_H
+
+#include <asm/sun3mmu.h>
+
+#ifndef __ASSEMBLY__
+#include <asm/virtconvert.h>
+#include <linux/linkage.h>
+
+/*
+ * This file contains all the things which change drastically for the sun3
+ * pagetable stuff, to avoid making too much of a mess of the generic m68k
+ * `pgtable.h'; this should only be included from the generic file. --m
+ */
+
+/* For virtual address to physical address conversion */
+#define VTOP(addr)     __pa(addr)
+#define PTOV(addr)     __va(addr)
+
+
+#endif /* !__ASSEMBLY__ */
+
+/* These need to be defined for compatibility although the sun3 doesn't use them */
+#define _PAGE_NOCACHE030 0x040
+#define _CACHEMASK040   (~0x060)
+#define _PAGE_NOCACHE_S 0x040
+
+/* Page protection values within PTE. */
+#define SUN3_PAGE_VALID     (0x80000000)
+#define SUN3_PAGE_WRITEABLE (0x40000000)
+#define SUN3_PAGE_SYSTEM    (0x20000000)
+#define SUN3_PAGE_NOCACHE   (0x10000000)
+#define SUN3_PAGE_ACCESSED  (0x02000000)
+#define SUN3_PAGE_MODIFIED  (0x01000000)
+
+
+/* Externally used page protection values. */
+#define _PAGE_PRESENT  (SUN3_PAGE_VALID)
+#define _PAGE_ACCESSED (SUN3_PAGE_ACCESSED)
+
+/* Compound page protection values. */
+//todo: work out which ones *should* have SUN3_PAGE_NOCACHE and fix...
+// is it just PAGE_KERNEL and PAGE_SHARED?
+#define PAGE_NONE      __pgprot(SUN3_PAGE_VALID \
+                                | SUN3_PAGE_ACCESSED \
+                                | SUN3_PAGE_NOCACHE)
+#define PAGE_SHARED    __pgprot(SUN3_PAGE_VALID \
+                                | SUN3_PAGE_WRITEABLE \
+                                | SUN3_PAGE_ACCESSED \
+                                | SUN3_PAGE_NOCACHE)
+#define PAGE_COPY      __pgprot(SUN3_PAGE_VALID \
+                                | SUN3_PAGE_ACCESSED \
+                                | SUN3_PAGE_NOCACHE)
+#define PAGE_READONLY  __pgprot(SUN3_PAGE_VALID \
+                                | SUN3_PAGE_ACCESSED \
+                                | SUN3_PAGE_NOCACHE)
+#define PAGE_KERNEL    __pgprot(SUN3_PAGE_VALID \
+                                | SUN3_PAGE_WRITEABLE \
+                                | SUN3_PAGE_SYSTEM \
+                                | SUN3_PAGE_NOCACHE \
+                                | SUN3_PAGE_ACCESSED \
+                                | SUN3_PAGE_MODIFIED)
+#define PAGE_INIT      __pgprot(SUN3_PAGE_VALID \
+                                | SUN3_PAGE_WRITEABLE \
+                                | SUN3_PAGE_SYSTEM \
+                                | SUN3_PAGE_NOCACHE)
+
+/*
+ * Page protections for initialising protection_map. The sun3 has only two
+ * protection settings, valid (implying read and execute) and writeable. These
+ * are as close as we can get...
+ */
+#define __P000 PAGE_NONE
+#define __P001 PAGE_READONLY
+#define __P010 PAGE_COPY
+#define __P011 PAGE_COPY
+#define __P100 PAGE_READONLY
+#define __P101 PAGE_READONLY
+#define __P110 PAGE_COPY
+#define __P111 PAGE_COPY
+
+#define __S000 PAGE_NONE
+#define __S001 PAGE_READONLY
+#define __S010 PAGE_SHARED
+#define __S011 PAGE_SHARED
+#define __S100 PAGE_READONLY
+#define __S101 PAGE_READONLY
+#define __S110 PAGE_SHARED
+#define __S111 PAGE_SHARED
+
+/* Use these fake page-protections on PMDs. */
+#define SUN3_PMD_VALID (0x00000001)
+#define SUN3_PMD_MASK  (0x0000003F)
+#define SUN3_PMD_MAGIC (0x0000002B)
+
+#ifndef __ASSEMBLY__
+
+/*
+ * Conversion functions: convert a page and protection to a page entry,
+ * and a page entry and page directory to the page they refer to.
+ */
+#define __mk_pte(page, pgprot) \
+({ pte_t __pte; pte_val(__pte) = (__pa(page) >> PAGE_SHIFT) | pgprot_val(pgprot); __pte; })
+#define mk_pte(page, pgprot) __mk_pte(page_address(page), (pgprot))
+#define mk_pte_phys(physpage, pgprot) \
+({ pte_t __pte; pte_val(__pte) = ((physpage) >> PAGE_SHIFT) | pgprot_val(pgprot); __pte; })
+extern inline pte_t pte_modify (pte_t pte, pgprot_t newprot)
+{ pte_val(pte) = (pte_val(pte) & SUN3_PAGE_CHG_MASK) | pgprot_val(newprot); return pte; }
+
+#define pmd_set(pmdp,ptep) do {} while (0)
+
+extern inline void pgd_set(pgd_t * pgdp, pmd_t * pmdp)
+{ pgd_val(*pgdp) = virt_to_phys(pmdp); }
+
+#define __pte_page(pte) \
+((unsigned long) __va ((pte_val (pte) & SUN3_PAGE_PGNUM_MASK) << PAGE_SHIFT))
+#define __pmd_page(pmd) \
+((unsigned long) __va (pmd_val (pmd) & PAGE_MASK))
+
+extern inline int pte_none (pte_t pte) { return !pte_val (pte); }
+extern inline int pte_present (pte_t pte) { return pte_val (pte) & SUN3_PAGE_VALID; }
+extern inline void pte_clear (pte_t *ptep) { pte_val (*ptep) = 0; }
+
+/* FIXME: this is only a guess */
+#define pte_pagenr(pte)                ((__pte_page(pte) - PAGE_OFFSET) >> PAGE_SHIFT)
+/* Permanent address of a page. */
+#define page_address(page)     ({ if (!(page)->virtual) BUG(); (page)->virtual; })
+#define __page_address(page)   (PAGE_OFFSET + (((page) - mem_map) << PAGE_SHIFT))
+#define pte_page(pte)          (mem_map+pte_pagenr(pte))
+
+
+extern inline int pmd_none2 (pmd_t *pmd) { return !pmd_val (*pmd); }
+#define pmd_none(pmd) pmd_none2(&(pmd))
+//extern inline int pmd_bad (pmd_t pmd) { return (pmd_val (pmd) & SUN3_PMD_MASK) != SUN3_PMD_MAGIC; }
+extern inline int pmd_bad2 (pmd_t *pmd) { return 0; }
+#define pmd_bad(pmd) pmd_bad2(&(pmd))
+extern inline int pmd_present2 (pmd_t *pmd) { return pmd_val (*pmd) & SUN3_PMD_VALID; }
+#define pmd_present(pmd) pmd_present2(&(pmd))
+extern inline void pmd_clear (pmd_t *pmdp) { pmd_val (*pmdp) = 0; }
+
+extern inline int pgd_none (pgd_t pgd) { return 0; }
+extern inline int pgd_bad (pgd_t pgd) { return 0; }
+extern inline int pgd_present (pgd_t pgd) { return 0; }
+extern inline void pgd_clear (pgd_t *pgdp) {}
+
+
+#define pte_ERROR(e) \
+       printk("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, pte_val(e))
+#define pmd_ERROR(e) \
+       printk("%s:%d: bad pmd %08lx.\n", __FILE__, __LINE__, pmd_val(e))
+#define pgd_ERROR(e) \
+       printk("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pgd_val(e))
+
+
+/*
+ * The following only work if pte_present() is true.
+ * Undefined behaviour if not...
+ * [we have the full set here even if they don't change from m68k]
+ */
+extern inline int pte_read(pte_t pte)          { return 1; }
+extern inline int pte_write(pte_t pte)         { return pte_val(pte) & SUN3_PAGE_WRITEABLE; }
+extern inline int pte_exec(pte_t pte)          { return 1; }
+extern inline int pte_dirty(pte_t pte)         { return pte_val(pte) & SUN3_PAGE_MODIFIED; }
+extern inline int pte_young(pte_t pte)         { return pte_val(pte) & SUN3_PAGE_ACCESSED; }
+
+extern inline pte_t pte_wrprotect(pte_t pte)   { pte_val(pte) &= ~SUN3_PAGE_WRITEABLE; return pte; }
+extern inline pte_t pte_rdprotect(pte_t pte)   { return pte; }
+extern inline pte_t pte_exprotect(pte_t pte)   { return pte; }
+extern inline pte_t pte_mkclean(pte_t pte)     { pte_val(pte) &= ~SUN3_PAGE_MODIFIED; return pte; }
+extern inline pte_t pte_mkold(pte_t pte)       { pte_val(pte) &= ~SUN3_PAGE_ACCESSED; return pte; }
+extern inline pte_t pte_mkwrite(pte_t pte)     { pte_val(pte) |= SUN3_PAGE_WRITEABLE; return pte; }
+extern inline pte_t pte_mkread(pte_t pte)      { return pte; }
+extern inline pte_t pte_mkexec(pte_t pte)      { return pte; }
+extern inline pte_t pte_mkdirty(pte_t pte)     { pte_val(pte) |= SUN3_PAGE_MODIFIED; return pte; }
+extern inline pte_t pte_mkyoung(pte_t pte)     { pte_val(pte) |= SUN3_PAGE_ACCESSED; return pte; }
+extern inline pte_t pte_mknocache(pte_t pte)   { pte_val(pte) |= SUN3_PAGE_NOCACHE; return pte; }
+// use this version when caches work...
+//extern inline pte_t pte_mkcache(pte_t pte)   { pte_val(pte) &= SUN3_PAGE_NOCACHE; return pte; }
+// until then, use:
+extern inline pte_t pte_mkcache(pte_t pte)     { return pte; }
+
+extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
+extern pgd_t kernel_pg_dir[PTRS_PER_PGD];
+
+/* Find an entry in a pagetable directory. */
+#define pgd_index(address)     ((address) >> PGDIR_SHIFT)
+
+#define pgd_offset(mm, address) \
+((mm)->pgd + pgd_index(address))
+
+/* Find an entry in a kernel pagetable directory. */
+#define pgd_offset_k(address) pgd_offset(&init_mm, address)
+
+/* Find an entry in the second-level pagetable. */
+extern inline pmd_t *pmd_offset (pgd_t *pgd, unsigned long address)
+{
+       return (pmd_t *) pgd;
+}
+
+/* Find an entry in the third-level pagetable. */
+#define pte_offset(pmd, address) \
+((pte_t *) __pmd_page (*pmd) + ((address >> PAGE_SHIFT) & (PTRS_PER_PTE-1)))
+
+/* Disable caching for page at given kernel virtual address. */
+static inline void nocache_page (unsigned long vaddr)
+{
+       /* Don't think this is required on sun3. --m */
+}
+
+/* Enable caching for page at given kernel virtual address. */
+static inline void cache_page (unsigned long vaddr)
+{
+       /* Don't think this is required on sun3. --m */
+}
+
+
+
+#endif /* !__ASSEMBLY__ */
+#endif /* !_SUN3_PGTABLE_H */
index a33bb7c14406941ae62b8e3bf20c30331310b933..3da1d58d74d8b11f0f7792f303d5e8bf626837ac 100644 (file)
@@ -3,6 +3,7 @@
 
 #include <linux/config.h> /* get configuration macros */
 #include <linux/linkage.h>
+#include <linux/kernel.h>
 #include <asm/segment.h>
 #include <asm/entry.h>
 
@@ -70,19 +71,23 @@ asmlinkage void resume(void);
 #define sti()                  __sti()
 #define save_flags(x)          __save_flags(x)
 #define restore_flags(x)       __restore_flags(x)
-
+#define save_and_cli(flags)   do { save_flags(flags); cli(); } while(0)
 
 /*
  * Force strict CPU ordering.
  * Not really required on m68k...
  */
-#define nop()  asm volatile ("nop"::)
-#define mb()   asm volatile (""   : : :"memory")
-#define rmb()  asm volatile (""   : : :"memory")
-#define wmb()  asm volatile (""   : : :"memory")
+#define nop()          do { asm volatile ("nop"); barrier(); } while (0)
+#define mb()           barrier()
+#define rmb()          barrier()
+#define wmb()          barrier()
 #define set_mb(var, value)    do { xchg(&var, value); } while (0)
 #define set_wmb(var, value)    do { var = value; wmb(); } while (0)
 
+#define smp_mb()       barrier()
+#define smp_rmb()      barrier()
+#define smp_wmb()      barrier()
+
 
 #define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
 #define tas(ptr) (xchg((ptr),1))
index b0ece7bda893c766b5c2f159c4688a736c45127e..45d1588f28e3f121bcfc69556be23bf71d280d4b 100644 (file)
@@ -49,6 +49,10 @@ typedef unsigned long long u64;
 
 #define BITS_PER_LONG 32
 
+/* DMA addresses are 32-bits wide */
+
+typedef u32 dma_addr_t;
+
 #endif /* __KERNEL__ */
 
 #endif /* _M68K_TYPES_H */
index af962e94f38e0237c82d9252d1be59799d3ac96c..847ae567ed1e8d9d0688d1883416d8269c1bdde3 100644 (file)
@@ -549,6 +549,7 @@ extern int ext2_write (struct inode *, struct file *, char *, int);
 
 /* fsync.c */
 extern int ext2_sync_file (struct file *, struct dentry *, int);
+extern int ext2_fsync_inode (struct inode *, int);
 
 /* ialloc.c */
 extern struct inode * ext2_new_inode (const struct inode *, int, int *);
index 4701868040c745525326a605d39ffe799f4801b3..ff0098c64d08576e305bef1df66d90f166fc5874 100644 (file)
@@ -243,6 +243,9 @@ struct buffer_head {
 
        unsigned long b_rsector;        /* Real buffer location on disk */
        wait_queue_head_t b_wait;
+
+       struct inode *       b_inode;
+       struct list_head     b_inode_buffers;   /* doubly linked list of inode dirty buffers */
 };
 
 typedef void (bh_end_io_t)(struct buffer_head *bh, int uptodate);
@@ -382,6 +385,8 @@ struct inode {
        struct list_head        i_hash;
        struct list_head        i_list;
        struct list_head        i_dentry;
+       
+       struct list_head        i_dirty_buffers;
 
        unsigned long           i_ino;
        atomic_t                i_count;
@@ -452,16 +457,25 @@ struct inode {
 };
 
 /* Inode state bits.. */
-#define I_DIRTY                1
-#define I_LOCK         2
-#define I_FREEING      4
-#define I_CLEAR                8
+#define I_DIRTY_SYNC           1 /* Not dirty enough for O_DATASYNC */
+#define I_DIRTY_DATASYNC       2 /* Data-related inode changes pending */
+#define I_LOCK                 4
+#define I_FREEING              8
+#define I_CLEAR                        16
+
+#define I_DIRTY (I_DIRTY_SYNC | I_DIRTY_DATASYNC)
 
-extern void __mark_inode_dirty(struct inode *);
+extern void __mark_inode_dirty(struct inode *, int);
 static inline void mark_inode_dirty(struct inode *inode)
 {
-       if (!(inode->i_state & I_DIRTY))
-               __mark_inode_dirty(inode);
+       if ((inode->i_state & I_DIRTY) != I_DIRTY)
+               __mark_inode_dirty(inode, I_DIRTY);
+}
+
+static inline void mark_inode_dirty_sync(struct inode *inode)
+{
+       if (!(inode->i_state & I_DIRTY_SYNC))
+               __mark_inode_dirty(inode, I_DIRTY_SYNC);
 }
 
 struct fown_struct {
@@ -1025,10 +1039,18 @@ static inline void buffer_IO_error(struct buffer_head * bh)
        bh->b_end_io(bh, 0);
 }
 
+extern void buffer_insert_inode_queue(struct buffer_head *, struct inode *);
+static inline void mark_buffer_dirty_inode(struct buffer_head *bh, struct inode *inode)
+{
+       mark_buffer_dirty(bh);
+       buffer_insert_inode_queue(bh, inode);
+}
+
 extern void balance_dirty(kdev_t);
 extern int check_disk_change(kdev_t);
 extern int invalidate_inodes(struct super_block *);
 extern void invalidate_inode_pages(struct inode *);
+extern void invalidate_inode_buffers(struct inode *);
 #define invalidate_buffers(dev)        __invalidate_buffers((dev), 0)
 #define destroy_buffers(dev)   __invalidate_buffers((dev), 1)
 extern void __invalidate_buffers(kdev_t dev, int);
@@ -1036,6 +1058,9 @@ extern void sync_inodes(kdev_t);
 extern void write_inode_now(struct inode *, int);
 extern void sync_dev(kdev_t);
 extern int fsync_dev(kdev_t);
+extern int fsync_inode_buffers(struct inode *);
+extern int osync_inode_buffers(struct inode *);
+extern int inode_has_buffers(struct inode *);
 extern void sync_supers(kdev_t);
 extern int bmap(struct inode *, int);
 extern int notify_change(struct dentry *, struct iattr *);
@@ -1249,6 +1274,7 @@ extern ssize_t block_write(struct file *, const char *, size_t, loff_t *);
 
 extern int file_fsync(struct file *, struct dentry *, int);
 extern int generic_buffer_fdatasync(struct inode *inode, unsigned long start_idx, unsigned long end_idx);
+extern int generic_osync_inode(struct inode *, int);
 
 extern int inode_change_ok(struct inode *, struct iattr *);
 extern void inode_setattr(struct inode *, struct iattr *);
index a24e7770abb048b19a67e571abbece79155f2c7f..7c3569949684240c958069f8e70f42ad22212c5f 100644 (file)
@@ -19,6 +19,12 @@ struct resource {
        struct resource *parent, *sibling, *child;
 };
 
+struct resource_list {
+       struct resource_list *next;
+       struct resource *res;
+       struct pci_dev *dev;
+};
+
 /*
  * IO resources have these defined flags.
  */
@@ -34,6 +40,7 @@ struct resource {
 #define IORESOURCE_CACHEABLE   0x00004000
 #define IORESOURCE_RANGELENGTH 0x00008000
 #define IORESOURCE_SHADOWABLE  0x00010000
+#define IORESOURCE_BUS_HAS_VGA 0x00080000
 
 #define IORESOURCE_UNSET       0x20000000
 #define IORESOURCE_AUTO                0x40000000
index beb41bfa3c1b8e2799825fa2fee6c01835410c54..4e1b281be11e14e4b8d2050905ae02f3c6cb8efb 100644 (file)
@@ -56,6 +56,8 @@ NORET_TYPE void up_and_exit(struct semaphore *, long)
        ATTRIB_NORET;
 extern unsigned long simple_strtoul(const char *,char **,unsigned int);
 extern long simple_strtol(const char *,char **,unsigned int);
+extern unsigned long long simple_strtoull(const char *,char **,unsigned int);
+extern long long simple_strtoll(const char *,char **,unsigned int);
 extern int sprintf(char * buf, const char * fmt, ...);
 extern int vsprintf(char *buf, const char *, va_list);
 extern int get_option(char **str, int *pint);
index 0c2dc46aeaf5662ce8c4bac7fdff8d70fef079d8..d98a3a01a4daeb05afe5ad0c5fdea4385a3f6483 100644 (file)
@@ -530,12 +530,13 @@ void pci_set_master(struct pci_dev *dev);
 int pci_set_power_state(struct pci_dev *dev, int state);
 int pci_assign_resource(struct pci_dev *dev, int i);
 
-/* Helper functions for low-level code (drivers/pci/setup.c) */
+/* Helper functions for low-level code (drivers/pci/setup-[bus,res].c) */
 
 int pci_claim_resource(struct pci_dev *, int);
 void pci_assign_unassigned_resources(void);
-void pdev_assign_unassigned_resources(struct pci_dev *dev);
-void pci_set_bus_ranges(void);
+void pdev_enable_device(struct pci_dev *);
+void pdev_sort_resources(struct pci_dev *, struct resource_list *, u32);
+unsigned long pci_bridge_check_io(struct pci_dev *);
 void pci_fixup_irqs(u8 (*)(struct pci_dev *, u8 *),
                    int (*)(struct pci_dev *, u8, u8));
 
index d3957292ce12bdfb0b2ea619f75f100265339cfb..a13ff5e064a8615b3cdfa35fbcbfe3f787039c72 100644 (file)
 
 /* Vendors and devices.  Sort key: vendor first, device next. */
 
+/* Should be Dynalink - same company? */
+#define PCI_VENDOR_ID_ASUSCOM          0x0675
+#define PCI_DEVICE_ID_ASUSCOM_TA1      0x1702
+
 #define PCI_VENDOR_ID_COMPAQ           0x0e11
 #define PCI_DEVICE_ID_COMPAQ_TOKENRING 0x0508
 #define PCI_DEVICE_ID_COMPAQ_1280      0x3033
 
 #define PCI_VENDOR_ID_NS               0x100b
 #define PCI_DEVICE_ID_NS_87415         0x0002
-#define PCI_DEVICE_ID_NS_87560_LIO      0x000e
-#define PCI_DEVICE_ID_NS_87560_USB      0x0012
+#define PCI_DEVICE_ID_NS_87560_LIO     0x000e
+#define PCI_DEVICE_ID_NS_87560_USB     0x0012
 #define PCI_DEVICE_ID_NS_87410         0xd001
 
 #define PCI_VENDOR_ID_TSENG            0x100c
 #define        PCI_DEVICE_ID_IBM_405GP         0x0156
 #define PCI_DEVICE_ID_IBM_MPIC_2       0xffff
 
+#define PCI_VENDOR_ID_COMPEX2          0x101a // pci.ids says "AT&T GIS (NCR)"
+#define PCI_DEVICE_ID_COMPEX2_100VG    0x0005
+
 #define PCI_VENDOR_ID_WD               0x101c
 #define PCI_DEVICE_ID_WD_7197          0x3296
 
+#define PCI_VENDOR_ID_AMI              0x101e
+#define PCI_DEVICE_ID_AMI_MEGARAID3    0x1960
+#define PCI_DEVICE_ID_AMI_MEGARAID     0x9010
+#define PCI_DEVICE_ID_AMI_MEGARAID2    0x9060
+
 #define PCI_VENDOR_ID_AMD              0x1022
 #define PCI_DEVICE_ID_AMD_LANCE                0x2000
 #define PCI_DEVICE_ID_AMD_LANCE_HOME   0x2001
 #define PCI_DEVICE_ID_AMD_VIPER_740C   0x740C
 
 #define PCI_VENDOR_ID_TRIDENT          0x1023
+#define PCI_DEVICE_ID_TRIDENT_4DWAVE_DX        0x2000
+#define PCI_DEVICE_ID_TRIDENT_4DWAVE_NX        0x2001
 #define PCI_DEVICE_ID_TRIDENT_9320     0x9320
 #define PCI_DEVICE_ID_TRIDENT_9388     0x9388
 #define PCI_DEVICE_ID_TRIDENT_9397     0x9397
 #define PCI_DEVICE_ID_MATROX_MIL_2     0x051b
 #define PCI_DEVICE_ID_MATROX_MIL_2_AGP 0x051f
 #define PCI_DEVICE_ID_MATROX_MGA_IMP   0x0d10
-#define PCI_DEVICE_ID_MATROX_G100_MM    0x1000
-#define PCI_DEVICE_ID_MATROX_G100_AGP   0x1001
-#define PCI_DEVICE_ID_MATROX_G200_PCI   0x0520
-#define PCI_DEVICE_ID_MATROX_G200_AGP   0x0521
+#define PCI_DEVICE_ID_MATROX_G100_MM   0x1000
+#define PCI_DEVICE_ID_MATROX_G100_AGP  0x1001
+#define PCI_DEVICE_ID_MATROX_G200_PCI  0x0520
+#define PCI_DEVICE_ID_MATROX_G200_AGP  0x0521
 #define        PCI_DEVICE_ID_MATROX_G400       0x0525
 #define PCI_DEVICE_ID_MATROX_VIA       0x4536
 
 #define PCI_DEVICE_ID_PCTECH_SAMURAI_1 0x3010
 #define PCI_DEVICE_ID_PCTECH_SAMURAI_IDE 0x3020
 
-#define PCI_VENDOR_ID_DPT               0x1044   
-#define PCI_DEVICE_ID_DPT               0xa400  
+#define PCI_VENDOR_ID_DPT              0x1044
+#define PCI_DEVICE_ID_DPT              0xa400
 
 #define PCI_VENDOR_ID_OPTI             0x1045
 #define PCI_DEVICE_ID_OPTI_92C178      0xc178
 #define PCI_DEVICE_ID_OPTI_82C861      0xc861
 #define PCI_DEVICE_ID_OPTI_82C825      0xd568
 
+#define PCI_VENDOR_ID_ELSA             0x1048
+#define PCI_DEVICE_ID_ELSA_MICROLINK   0x1000
+#define PCI_DEVICE_ID_ELSA_QS3000      0x3000
+
 #define PCI_VENDOR_ID_SGS              0x104a
 #define PCI_DEVICE_ID_SGS_2000         0x0008
 #define PCI_DEVICE_ID_SGS_1764         0x0009
 #define PCI_DEVICE_ID_TI_1251B         0xac1f
 #define PCI_DEVICE_ID_TI_1420          0xac51
 
+#define PCI_VENDOR_ID_SONY             0x104d
+#define PCI_DEVICE_ID_SONY_CXD3222     0x8039
 
 #define PCI_VENDOR_ID_OAK              0x104e
 #define PCI_DEVICE_ID_OAK_OTI107       0x0107
 #define PCI_VENDOR_ID_WINBOND2         0x1050
 #define PCI_DEVICE_ID_WINBOND2_89C940  0x0940
 #define PCI_DEVICE_ID_WINBOND2_89C940F 0x5a5a
+#define PCI_DEVICE_ID_WINBOND2_6692    0x6692
 
 #define PCI_VENDOR_ID_EFAR             0x1055
 #define PCI_DEVICE_ID_EFAR_SLC90E66_1  0x9130
 #define PCI_VENDOR_ID_LEADTEK          0x107d
 #define PCI_DEVICE_ID_LEADTEK_805      0x0000
 
-#define PCI_VENDOR_ID_INTERPHASE               0x107e
+#define PCI_VENDOR_ID_INTERPHASE       0x107e
 #define PCI_DEVICE_ID_INTERPHASE_5526  0x0004
 #define PCI_DEVICE_ID_INTERPHASE_55x6  0x0005
+#define PCI_DEVICE_ID_INTERPHASE_5575  0x0008
 
 #define PCI_VENDOR_ID_CONTAQ           0x1080
 #define PCI_DEVICE_ID_CONTAQ_82C599    0x0600
 #define PCI_VENDOR_ID_BROOKTREE                0x109e
 #define PCI_DEVICE_ID_BROOKTREE_848    0x0350
 #define PCI_DEVICE_ID_BROOKTREE_849A   0x0351
-#define PCI_DEVICE_ID_BROOKTREE_878_1   0x036e
-#define PCI_DEVICE_ID_BROOKTREE_878     0x0878
+#define PCI_DEVICE_ID_BROOKTREE_878_1  0x036e
+#define PCI_DEVICE_ID_BROOKTREE_878    0x0878
 #define PCI_DEVICE_ID_BROOKTREE_8474   0x8474
 
 #define PCI_VENDOR_ID_SIERRA           0x10a8
 #define PCI_DEVICE_ID_DATABOOK_87144   0xb106
 
 #define PCI_VENDOR_ID_PLX              0x10b5
-#define PCI_VENDOR_ID_PLX_ROMULUS      0x106a
+#define PCI_DEVICE_ID_PLX_R685         0x1030
+#define PCI_DEVICE_ID_PLX_ROMULUS      0x106a
 #define PCI_DEVICE_ID_PLX_SPCOM800     0x1076
 #define PCI_DEVICE_ID_PLX_1077         0x1077
 #define PCI_DEVICE_ID_PLX_SPCOM200     0x1103
+#define PCI_DEVICE_ID_PLX_DJINN_ITOO   0x1151
+#define PCI_DEVICE_ID_PLX_R753         0x1152
 #define PCI_DEVICE_ID_PLX_9050         0x9050
 #define PCI_DEVICE_ID_PLX_9060         0x9060
 #define PCI_DEVICE_ID_PLX_9060ES       0x906E
 #define PCI_DEVICE_ID_AL_M5229         0x5229
 #define PCI_DEVICE_ID_AL_M5237         0x5237
 #define PCI_DEVICE_ID_AL_M5243         0x5243
+#define PCI_DEVICE_ID_AL_M5451         0x5451
 #define PCI_DEVICE_ID_AL_M7101         0x7101
 
 #define PCI_VENDOR_ID_MITSUBISHI       0x10ba
 #define PCI_VENDOR_ID_SURECOM          0x10bd
 #define PCI_DEVICE_ID_SURECOM_NE34     0x0e34
 
-#define PCI_VENDOR_ID_NEOMAGIC          0x10c8
+#define PCI_VENDOR_ID_NEOMAGIC         0x10c8
 #define PCI_DEVICE_ID_NEOMAGIC_MAGICGRAPH_NM2070 0x0001
 #define PCI_DEVICE_ID_NEOMAGIC_MAGICGRAPH_128V 0x0002
 #define PCI_DEVICE_ID_NEOMAGIC_MAGICGRAPH_128ZV 0x0003
 #define PCI_DEVICE_ID_INIT_320P                0x9100
 #define PCI_DEVICE_ID_INIT_360P                0x9500
 
+#define PCI_VENDOR_ID_CREATIVE         0x1102 // duplicate: ECTIVA
+#define PCI_DEVICE_ID_CREATIVE_EMU10K1 0x0002
+
+#define PCI_VENDOR_ID_ECTIVA           0x1102 // duplicate: CREATIVE
+#define PCI_DEVICE_ID_ECTIVA_EV1938    0x8938
+
 #define PCI_VENDOR_ID_TTI              0x1103
 #define PCI_DEVICE_ID_TTI_HPT343       0x0003
 #define PCI_DEVICE_ID_TTI_HPT366       0x0004
 #define PCI_DEVICE_ID_VIA_8633_1       0xB091
 #define PCI_DEVICE_ID_VIA_8367_1       0xB099
 
-#define PCI_VENDOR_ID_SMC2             0x1113
-#define PCI_DEVICE_ID_SMC2_1211TX      0x1211
+#define PCI_VENDOR_ID_SMC2             0x1113
+#define PCI_DEVICE_ID_SMC2_1211TX      0x1211
 
 #define PCI_VENDOR_ID_VORTEX           0x1119
 #define PCI_DEVICE_ID_VORTEX_GDT60x0   0x0000
 #define PCI_DEVICE_ID_EF_ATM_FPGA      0x0000
 #define PCI_DEVICE_ID_EF_ATM_ASIC      0x0002
 
+#define PCI_VENDOR_ID_IDT              0x111d
+#define PCI_DEVICE_ID_IDT_IDT77201     0x0001
+
 #define PCI_VENDOR_ID_FORE             0x1127
 #define PCI_DEVICE_ID_FORE_PCA200PC    0x0210
 #define PCI_DEVICE_ID_FORE_PCA200E     0x0300
 #define PCI_DEVICE_ID_PHILIPS_SAA7145  0x7145
 #define PCI_DEVICE_ID_PHILIPS_SAA7146  0x7146
 
+#define PCI_VENDOR_ID_EICON            0x1133
+#define PCI_DEVICE_ID_EICON_DIVA20PRO  0xe001
+#define PCI_DEVICE_ID_EICON_DIVA20     0xe002
+#define PCI_DEVICE_ID_EICON_DIVA20PRO_U        0xe003
+#define PCI_DEVICE_ID_EICON_DIVA20_U   0xe004
+#define PCI_DEVICE_ID_EICON_DIVA201    0xe005
+#define PCI_DEVICE_ID_EICON_MAESTRA    0xe010
+#define PCI_DEVICE_ID_EICON_MAESTRAQ   0xe012
+#define PCI_DEVICE_ID_EICON_MAESTRAQ_U 0xe013
+#define PCI_DEVICE_ID_EICON_MAESTRAP   0xe014
 #define PCI_VENDOR_ID_CYCLONE          0x113c
 #define PCI_DEVICE_ID_CYCLONE_SDK      0x0001
 
 #define PCI_DEVICE_ID_SERVERWORKS_LE   0x0009
 #define PCI_DEVICE_ID_SERVERWORKS_CIOB30   0x0010
 #define PCI_DEVICE_ID_SERVERWORKS_CMIC_HE  0x0011
-#define PCI_DEVICE_ID_SERVERWORKS_CSB5     0x0201
-#define PCI_DEVICE_ID_SERVERWORKS_OSB4  0x0200
+#define PCI_DEVICE_ID_SERVERWORKS_CSB5    0x0201
+#define PCI_DEVICE_ID_SERVERWORKS_OSB4 0x0200
 #define PCI_DEVICE_ID_SERVERWORKS_OSB4IDE 0x0211
 #define PCI_DEVICE_ID_SERVERWORKS_OSB4USB 0x0220
 
 #define PCI_DEVICE_ID_ARTOP_ATP850UF   0x0005
 #define PCI_DEVICE_ID_ARTOP_ATP860     0x0006
 #define PCI_DEVICE_ID_ARTOP_ATP860R    0x0007
+#define PCI_DEVICE_ID_ARTOP_AEC7610    0x8002
+#define PCI_DEVICE_ID_ARTOP_AEC7612UW  0x8010
+#define PCI_DEVICE_ID_ARTOP_AEC7612U   0x8020
+#define PCI_DEVICE_ID_ARTOP_AEC7612S   0x8030
+#define PCI_DEVICE_ID_ARTOP_AEC7612D   0x8040
+#define PCI_DEVICE_ID_ARTOP_AEC7612SUW 0x8050
+#define PCI_DEVICE_ID_ARTOP_8060       0x8060
 
 #define PCI_VENDOR_ID_ZEITNET          0x1193
 #define PCI_DEVICE_ID_ZEITNET_1221     0x0001
 #define PCI_DEVICE_ID_COMPEX_ENET100VG4        0x0112
 #define PCI_DEVICE_ID_COMPEX_RL2000    0x1401
 
-#define PCI_VENDOR_ID_RP               0x11fe
-#define PCI_DEVICE_ID_RP32INTF         0x0001
-#define PCI_DEVICE_ID_RP8INTF          0x0002
-#define PCI_DEVICE_ID_RP16INTF         0x0003
-#define PCI_DEVICE_ID_RP4QUAD         0x0004
-#define PCI_DEVICE_ID_RP8OCTA          0x0005
-#define PCI_DEVICE_ID_RP8J            0x0006
-#define PCI_DEVICE_ID_RPP4            0x000A
-#define PCI_DEVICE_ID_RPP8            0x000B
-#define PCI_DEVICE_ID_RP8M            0x000C
+#define PCI_VENDOR_ID_RP               0x11fe
+#define PCI_DEVICE_ID_RP32INTF         0x0001
+#define PCI_DEVICE_ID_RP8INTF          0x0002
+#define PCI_DEVICE_ID_RP16INTF         0x0003
+#define PCI_DEVICE_ID_RP4QUAD          0x0004
+#define PCI_DEVICE_ID_RP8OCTA          0x0005
+#define PCI_DEVICE_ID_RP8J             0x0006
+#define PCI_DEVICE_ID_RPP4             0x000A
+#define PCI_DEVICE_ID_RPP8             0x000B
+#define PCI_DEVICE_ID_RP8M             0x000C
 
 #define PCI_VENDOR_ID_CYCLADES         0x120e
 #define PCI_DEVICE_ID_CYCLOM_Y_Lo      0x0100
 #define PCI_VENDOR_ID_3DFX             0x121a
 #define PCI_DEVICE_ID_3DFX_VOODOO      0x0001
 #define PCI_DEVICE_ID_3DFX_VOODOO2     0x0002
-#define PCI_DEVICE_ID_3DFX_BANSHEE      0x0003
+#define PCI_DEVICE_ID_3DFX_BANSHEE     0x0003
 #define PCI_DEVICE_ID_3DFX_VOODOO3     0x0005
 
 #define PCI_VENDOR_ID_SIGMADES         0x1236
 #define PCI_VENDOR_ID_CCUBE            0x123f
 
 #define PCI_VENDOR_ID_AVM              0x1244
+#define PCI_DEVICE_ID_AVM_B1           0x0700
+#define PCI_DEVICE_ID_AVM_C4           0x0800
 #define PCI_DEVICE_ID_AVM_A1           0x0a00
+#define PCI_DEVICE_ID_AVM_T1           0x1200
 
 #define PCI_VENDOR_ID_DIPIX            0x1246
 
 #define PCI_DEVICE_ID_OPTIBASE_VQUEST  0x2130
 
 #define PCI_VENDOR_ID_ESS              0x125d
+#define PCI_DEVICE_ID_ESS_ESS1968      0x1968
 #define PCI_DEVICE_ID_ESS_AUDIOPCI     0x1969
+#define PCI_DEVICE_ID_ESS_ESS1978      0x1978
 
 #define PCI_VENDOR_ID_SATSAGEM         0x1267
+#define PCI_DEVICE_ID_SATSAGEM_NICCY   0x1016
 #define PCI_DEVICE_ID_SATSAGEM_PCR2101 0x5352
 #define PCI_DEVICE_ID_SATSAGEM_TELSATTURBO 0x5a4b
 
 
 #define PCI_VENDOR_ID_ENSONIQ          0x1274
 #define PCI_DEVICE_ID_ENSONIQ_AUDIOPCI 0x5000
-#define PCI_DEVICE_ID_ENSONIQ_ES1371    0x1371
+#define PCI_DEVICE_ID_ENSONIQ_ES1371   0x1371
 
 #define PCI_VENDOR_ID_ROCKWELL         0x127A
 
+/* formerly Platform Tech */
+#define PCI_VENDOR_ID_ESS_OLD          0x1285
+#define PCI_DEVICE_ID_ESS_ESS0100      0x0100
+
 #define PCI_VENDOR_ID_ALTEON           0x12ae
 #define PCI_DEVICE_ID_ALTEON_ACENIC    0x0001
 
 #define PCI_SUBDEVICE_ID_CHASE_PCIRAS4         0xF001
 #define PCI_SUBDEVICE_ID_CHASE_PCIRAS8         0xF010
 
+#define PCI_VENDOR_ID_AUREAL           0x12eb
+#define PCI_DEVICE_ID_AUREAL_VORTEX_1  0x0001
+#define PCI_DEVICE_ID_AUREAL_VORTEX_2  0x0002
+
 #define PCI_VENDOR_ID_CBOARDS          0x1307
 #define PCI_DEVICE_ID_CBOARDS_DAS1602_16 0x0001
 
 #define PCI_DEVICE_ID_SIIG_2S1P_20x_650        0x2061
 #define PCI_DEVICE_ID_SIIG_2S1P_20x_850        0x2062
 
+#define PCI_VENDOR_ID_DOMEX            0x134a
+#define PCI_DEVICE_ID_DOMEX_DMX3191D   0x0001
+
 #define PCI_VENDOR_ID_QUATECH          0x135C
 #define PCI_DEVICE_ID_QUATECH_QSC100   0x0010
 #define PCI_DEVICE_ID_QUATECH_DSC100   0x0020
 #define PCI_DEVICE_ID_SEALEVEL_COMM4   0x7401
 #define PCI_DEVICE_ID_SEALEVEL_COMM8   0x7801
 
+#define PCI_VENDOR_ID_HYPERCOPE                0x1365
+#define PCI_DEVICE_ID_HYPERCOPE_PLX    0x9050
+
+#define PCI_VENDOR_ID_LMC              0x1376
+#define PCI_DEVICE_ID_LMC_HSSI         0x0003
+#define PCI_DEVICE_ID_LMC_DS3          0x0004
+#define PCI_DEVICE_ID_LMC_SSI          0x0005
+#define PCI_DEVICE_ID_LMC_T1           0x0006
+
 #define PCI_VENDOR_ID_NETGEAR          0x1385
 #define PCI_DEVICE_ID_NETGEAR_GA620    0x620a
 
+#define PCI_VENDOR_ID_APPLICOM         0x1389
+#define PCI_DEVICE_ID_APPLICOM_PCIGENERIC 0x0001
+#define PCI_DEVICE_ID_APPLICOM_PCI2000IBS_CAN 0x0002
+#define PCI_DEVICE_ID_APPLICOM_PCI2000PFB 0x0003
+
+#define PCI_VENDOR_ID_MOXA             0x1393
+#define PCI_DEVICE_ID_MOXA_C104                0x1040
+#define PCI_DEVICE_ID_MOXA_C168                0x1680
+#define PCI_DEVICE_ID_MOXA_CP204J      0x2040
+#define PCI_DEVICE_ID_MOXA_C218                0x2180
+#define PCI_DEVICE_ID_MOXA_C320                0x3200
+
 #define PCI_VENDOR_ID_3WARE            0x13C1
 #define PCI_DEVICE_ID_3WARE_1000       0x1000
 
+#define PCI_VENDOR_ID_CMEDIA           0x13f6
+#define PCI_DEVICE_ID_CMEDIA_CM8338A   0x0100
+#define PCI_DEVICE_ID_CMEDIA_CM8338B   0x0101
+#define PCI_DEVICE_ID_CMEDIA_CM8738    0x0111
+#define PCI_DEVICE_ID_CMEDIA_CM8738B   0x0112
+
 #define PCI_VENDOR_ID_LAVA             0x1407
 #define PCI_DEVICE_ID_LAVA_DSERIAL     0x0100 /* 2x 16550 */
 #define PCI_DEVICE_ID_LAVA_QUATRO_A    0x0101 /* 2x 16550, half of 4 port */
 #define PCI_VENDOR_ID_TIMEDIA          0x1409
 #define PCI_DEVICE_ID_TIMEDIA_1889     0x7168
 
-#define PCI_VENDOR_ID_OXSEMI            0x1415
-#define PCI_DEVICE_ID_OXSEMI_16PCI954   0x9501
+#define PCI_VENDOR_ID_OXSEMI           0x1415
+#define PCI_DEVICE_ID_OXSEMI_16PCI954  0x9501
 #define PCI_DEVICE_ID_OXSEMI_16PCI952  0x950A
 #define PCI_DEVICE_ID_OXSEMI_16PCI95N  0x9511
 
+#define PCI_VENDOR_ID_AIRONET          0x14b9
+#define PCI_DEVICE_ID_AIRONET_4800_1   0x0001
+#define PCI_DEVICE_ID_AIRONET_4800     0x4500 // values switched?  see
+#define PCI_DEVICE_ID_AIRONET_4500     0x4800 // drivers/net/aironet4500_card.c
+
 #define PCI_VENDOR_ID_TITAN            0x14D2
 #define PCI_DEVICE_ID_TITAN_100                0xA001
 #define PCI_DEVICE_ID_TITAN_200                0xA005
 #define PCI_DEVICE_ID_INTEL_82441      0x1237
 #define PCI_DEVICE_ID_INTEL_82380FB    0x124b
 #define PCI_DEVICE_ID_INTEL_82439      0x1250
+#define PCI_DEVICE_ID_INTEL_80960_RP   0x1960
 #define PCI_DEVICE_ID_INTEL_82371SB_0  0x7000
 #define PCI_DEVICE_ID_INTEL_82371SB_1  0x7010
 #define PCI_DEVICE_ID_INTEL_82371SB_2  0x7020
 
 #define PCI_VENDOR_ID_TIGERJET         0xe159
 #define PCI_DEVICE_ID_TIGERJET_300     0x0001
+#define PCI_DEVICE_ID_TIGERJET_100     0x0002
 
 #define PCI_VENDOR_ID_ARK              0xedd8
 #define PCI_DEVICE_ID_ARK_STING                0xa091
index a24292180b64b320cafafe89626f464db6cbb1ff..44bee2c1720635119c01f41a22c862d95947de06 100644 (file)
@@ -174,18 +174,19 @@ struct files_struct {
        struct file * fd_array[NR_OPEN_DEFAULT];
 };
 
-#define INIT_FILES { \
-       ATOMIC_INIT(1), \
-       RW_LOCK_UNLOCKED, \
-       NR_OPEN_DEFAULT, \
-       __FD_SETSIZE, \
-       0, \
-       &init_files.fd_array[0], \
-       &init_files.close_on_exec_init, \
-       &init_files.open_fds_init, \
-       { { 0, } }, \
-       { { 0, } }, \
-       { NULL, } \
+#define INIT_FILES \
+{                                                      \
+       count:          ATOMIC_INIT(1),                 \
+       file_lock:      RW_LOCK_UNLOCKED,               \
+       max_fds:        NR_OPEN_DEFAULT,                \
+       max_fdset:      __FD_SETSIZE,                   \
+       next_fd:        0,                              \
+       fd:             &init_files.fd_array[0],        \
+       close_on_exec:  &init_files.close_on_exec_init, \
+       open_fds:       &init_files.open_fds_init,      \
+       close_on_exec_init: { { 0, } },                 \
+       open_fds_init:  { { 0, } },                     \
+       fd_array:       { NULL, }                       \
 }
 
 /* Maximum number of active map areas.. This is a random (large) number */
@@ -220,18 +221,19 @@ struct mm_struct {
        void * segments;
 };
 
-#define INIT_MM(name) {                                        \
-               &init_mmap, NULL, NULL,                 \
-               swapper_pg_dir,                         \
-               ATOMIC_INIT(2), ATOMIC_INIT(1), 1,      \
-               __MUTEX_INITIALIZER(name.mmap_sem),     \
-               SPIN_LOCK_UNLOCKED,                     \
-               0,                                      \
-               0, 0, 0, 0,                             \
-               0, 0, 0,                                \
-               0, 0, 0, 0,                             \
-               0, 0, 0,                                \
-               0, 0, 0, 0, NULL }
+#define INIT_MM(name) \
+{                                                      \
+       mmap:           &init_mmap,                     \
+       mmap_avl:       NULL,                           \
+       mmap_cache:     NULL,                           \
+       pgd:            swapper_pg_dir,                 \
+       mm_users:       ATOMIC_INIT(2),                 \
+       mm_count:       ATOMIC_INIT(1),                 \
+       map_count:      1,                              \
+       mmap_sem:       __MUTEX_INITIALIZER(name.mmap_sem), \
+       page_table_lock: SPIN_LOCK_UNLOCKED,            \
+       segments:       NULL                            \
+}
 
 struct signal_struct {
        atomic_t                count;
@@ -240,10 +242,11 @@ struct signal_struct {
 };
 
 
-#define INIT_SIGNALS { \
-               ATOMIC_INIT(1), \
-               { {{0,}}, }, \
-               SPIN_LOCK_UNLOCKED }
+#define INIT_SIGNALS { \
+       count:          ATOMIC_INIT(1),                 \
+       action:         { {{0,}}, },                    \
+       siglock:        SPIN_LOCK_UNLOCKED              \
+}
 
 /*
  * Some day this will be a full-fledged user tracking system..
index 889025caf6c2ac2ef8c9a99d8b7ea7f52a5b2ed1..dd02b40cd89105a3922edcf01c10867b4dc87940 100644 (file)
@@ -483,7 +483,9 @@ sys_init_module(const char *name_user, struct module *mod_user)
 
        /* Ok, that's about all the sanity we can stomach; copy the rest.  */
 
-       if (copy_from_user(mod+1, mod_user+1, mod->size-sizeof(*mod))) {
+       if (copy_from_user((char *)mod+mod_user_size,
+                          (char *)mod_user+mod_user_size,
+                          mod->size-mod_user_size)) {
                error = -EFAULT;
                goto err3;
        }
index 3367fc3e191ad5d1643ad76027641d49dc464f32..0c3a295363bb0a328de262f0b33b6dc5bf5519a6 100644 (file)
@@ -48,6 +48,38 @@ long simple_strtol(const char *cp,char **endp,unsigned int base)
        return simple_strtoul(cp,endp,base);
 }
 
+unsigned long long simple_strtoull(const char *cp,char **endp,unsigned int base)
+{
+       unsigned long long result = 0,value;
+
+       if (!base) {
+               base = 10;
+               if (*cp == '0') {
+                       base = 8;
+                       cp++;
+                       if ((*cp == 'x') && isxdigit(cp[1])) {
+                               cp++;
+                               base = 16;
+                       }
+               }
+       }
+       while (isxdigit(*cp) && (value = isdigit(*cp) ? *cp-'0' : (islower(*cp)
+           ? toupper(*cp) : *cp)-'A'+10) < base) {
+               result = result*base + value;
+               cp++;
+       }
+       if (endp)
+               *endp = (char *)cp;
+       return result;
+}
+
+long long simple_strtoll(const char *cp,char **endp,unsigned int base)
+{
+       if(*cp=='-')
+               return -simple_strtoull(cp+1,endp,base);
+       return simple_strtoull(cp,endp,base);
+}
+
 static int skip_atoi(const char **s)
 {
        int i=0;
index a191cc2f4ae29725d891f1162f15d38a5435cd6d..651dbd1c90a8d3866f357f9969f94bcdc33e6fe8 100644 (file)
@@ -2462,7 +2462,7 @@ generic_file_write(struct file *file,const char *buf,size_t count,loff_t *ppos)
        if (count) {
                remove_suid(inode);
                inode->i_ctime = inode->i_mtime = CURRENT_TIME;
-               mark_inode_dirty(inode);
+               mark_inode_dirty_sync(inode);
        }
 
        while (count) {
@@ -2521,8 +2521,14 @@ unlock:
        if (cached_page)
                page_cache_free(cached_page);
 
+       /* For now, when the user asks for O_SYNC, we'll actually
+        * provide O_DSYNC. */
+       if ((status >= 0) && (file->f_flags & O_SYNC))
+               status = generic_osync_inode(inode, 1); /* 1 means datasync */
+       
        err = written ? written : status;
 out:
+
        up(&inode->i_sem);
        return err;
 fail_write:
index c5b2d289d312045136c06a5f95141781c47b49d2..862a5bc1eea66491fe957f4979edc0b53ffccdff 100644 (file)
@@ -195,8 +195,6 @@ out_failed:
 out_free_success:
        page_cache_release(page);
        return 1;
-out_failed:
-       return 0;
 out_unlock_restore:
        set_pte(page_table, pte);
        UnlockPage(page);
index ae626e08b5df11876be10c8976838e69096d4216..7ae03b0a623e55b59190f02101f0b32767ae60c4 100644 (file)
@@ -512,7 +512,7 @@ int ircomm_proc_read(char *buf, char **start, off_t offset, int len)
 #endif /* CONFIG_PROC_FS */
 
 #ifdef MODULE
-MODULE_AUTHOR("Dag Brattli <dagb@cs.uit.no>");
+MODULE_AUTHOR("Dag Brattli <dag@brattli.net>");
 MODULE_DESCRIPTION("IrCOMM protocol");
 
 int init_module(void) 
index 67925c5b5542e6b2851d9dba820c202c1b20a207..b88cc3d53b5935c7ff721722a53df9b7dd8593d1 100644 (file)
@@ -100,7 +100,11 @@ int __init ircomm_tty_init(void)
        memset(&driver, 0, sizeof(struct tty_driver));
        driver.magic           = TTY_DRIVER_MAGIC;
        driver.driver_name     = "ircomm";
+#ifdef CONFIG_DEVFS_FS
+       driver.name            = "ircomm%d";
+#else
        driver.name            = "ircomm";
+#endif
        driver.major           = IRCOMM_TTY_MAJOR;
        driver.minor_start     = IRCOMM_TTY_MINOR;
        driver.num             = IRCOMM_TTY_PORTS;
index a06b18582677dcdbc9f32cd23c77f1935df41202..56c3604f66a95a1bb8ec2edd01c59c5e34d68dd1 100644 (file)
@@ -108,11 +108,10 @@ static int irlan_client_state_idle(struct irlan_cb *self, IRLAN_EVENT event,
                self->client.iriap = iriap_open(LSAP_ANY, IAS_CLIENT, self,
                                                irlan_client_get_value_confirm);
                /* Get some values from peer IAS */
+               irlan_next_client_state(self, IRLAN_QUERY);
                iriap_getvaluebyclass_request(self->client.iriap,
                                              self->saddr, self->daddr,
                                              "IrLAN", "IrDA:TinyTP:LsapSel");
-               
-               irlan_next_client_state(self, IRLAN_QUERY);
                break;
        case IRLAN_WATCHDOG_TIMEOUT:
                IRDA_DEBUG(2, __FUNCTION__ "(), IRLAN_WATCHDOG_TIMEOUT\n");
index ec5f6611c00b9a389d3635680fcad542ecedfe35..e5454d3a4f5985a41f9deeebe0c0e896f5dd897a 100644 (file)
@@ -4,10 +4,10 @@
  * Version:       0.9
  * Description:   IrLAP state machine implementation
  * Status:        Experimental.
- * Author:        Dag Brattli <dagb@cs.uit.no>
+ * Author:        Dag Brattli <dag@brattli.net>
  * Created at:    Sat Aug 16 00:59:29 1997
  * Modified at:   Sat Dec 25 21:07:57 1999
- * Modified by:   Dag Brattli <dagb@cs.uit.no>
+ * Modified by:   Dag Brattli <dag@brattli.net>
  * 
  *     Copyright (c) 1998-2000 Dag Brattli <dag@brattli.net>,
  *     Copyright (c) 1998      Thomas Davis <ratbert@radiks.net>
@@ -551,13 +551,15 @@ static int irlap_state_query(struct irlap_cb *self, IRLAP_EVENT event,
                 * since we want to work even with devices that violate the
                 * timing requirements.
                 */
-               if (irda_device_is_receiving(self->netdev)) {
-                       IRDA_DEBUG(1, __FUNCTION__ 
+               if (irda_device_is_receiving(self->netdev) && !self->add_wait) {
+                       IRDA_DEBUG(2, __FUNCTION__ 
                                   "(), device is slow to answer, "
                                   "waiting some more!\n");
                        irlap_start_slot_timer(self, MSECS_TO_JIFFIES(10));
+                       self->add_wait = TRUE;
                        return ret;
                }
+               self->add_wait = FALSE;
 
                if (self->s < self->S) {
                        irlap_send_discovery_xid_frame(self, self->S, 
@@ -1324,9 +1326,7 @@ static int irlap_state_nrm_p(struct irlap_cb *self, IRLAP_EVENT event,
                 *  of receiving a frame (page 45, IrLAP). Check that
                 *  we only do this once for each frame.
                 */
-               if (irda_device_is_receiving(self->netdev) && 
-                   !self->add_wait) 
-               {
+               if (irda_device_is_receiving(self->netdev) && !self->add_wait) {
                        IRDA_DEBUG(1, "FINAL_TIMER_EXPIRED when receiving a "
                              "frame! Waiting a little bit more!\n");
                        irlap_start_final_timer(self, MSECS_TO_JIFFIES(300));