]> git.neil.brown.name Git - history.git/commitdiff
Import 2.3.99pre7-2 2.3.99pre7-2
authorLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:34:20 +0000 (15:34 -0500)
committerLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:34:20 +0000 (15:34 -0500)
236 files changed:
Documentation/Changes
Documentation/Configure.help
Documentation/filesystems/ntfs.txt
Documentation/networking/vortex.txt
Documentation/usb/scanner-hp-sane.txt
Documentation/usb/scanner.txt
MAINTAINERS
arch/i386/kernel/pci-i386.c
arch/i386/kernel/pci-i386.h
arch/i386/kernel/pci-irq.c
arch/i386/kernel/pci-pc.c
arch/i386/kernel/setup.c
arch/i386/mm/fault.c
arch/ppc/8260_io/Config.in [new file with mode: 0644]
arch/ppc/8260_io/Makefile [new file with mode: 0644]
arch/ppc/8260_io/commproc.c [new file with mode: 0644]
arch/ppc/8260_io/enet.c [new file with mode: 0644]
arch/ppc/8260_io/uart.c [new file with mode: 0644]
arch/ppc/8xx_io/enet.c
arch/ppc/8xx_io/uart.c
arch/ppc/Makefile
arch/ppc/config.in
arch/ppc/configs/chrp_defconfig [deleted file]
arch/ppc/configs/common_defconfig
arch/ppc/configs/pmac_defconfig [deleted file]
arch/ppc/configs/prep_defconfig [deleted file]
arch/ppc/defconfig
arch/ppc/kernel/Makefile
arch/ppc/kernel/align.c
arch/ppc/kernel/feature.c
arch/ppc/kernel/gemini_pci.c
arch/ppc/kernel/gemini_setup.c
arch/ppc/kernel/head.S
arch/ppc/kernel/head_8xx.S
arch/ppc/kernel/irq.c
arch/ppc/kernel/m8260_setup.c [new file with mode: 0644]
arch/ppc/kernel/m8xx_setup.c
arch/ppc/kernel/misc.S
arch/ppc/kernel/pmac_nvram.c
arch/ppc/kernel/pmac_pci.c
arch/ppc/kernel/pmac_pic.c
arch/ppc/kernel/pmac_setup.c
arch/ppc/kernel/ppc-stub.c
arch/ppc/kernel/ppc8260_pic.c [new file with mode: 0644]
arch/ppc/kernel/ppc8260_pic.h [new file with mode: 0644]
arch/ppc/kernel/ppc8xx_pic.c
arch/ppc/kernel/ppc_htab.c
arch/ppc/kernel/ppc_ksyms.c
arch/ppc/kernel/process.c
arch/ppc/kernel/prom.c
arch/ppc/kernel/qspan_pci.c
arch/ppc/kernel/setup.c
arch/ppc/kernel/totalmp.c [deleted file]
arch/ppc/kernel/traps.c
arch/ppc/mbxboot/Makefile
arch/ppc/mbxboot/embed_config.c
arch/ppc/mbxboot/head_8260.S [new file with mode: 0644]
arch/ppc/mbxboot/iic.c
arch/ppc/mbxboot/m8260_tty.c [new file with mode: 0644]
arch/ppc/mbxboot/misc.c
arch/ppc/mbxboot/pci.c
arch/ppc/mbxboot/qspan_pci.c
arch/ppc/mm/fault.c
arch/ppc/mm/init.c
arch/ppc/xmon/Makefile
arch/ppc/xmon/privinst.h
arch/ppc/xmon/start.c
arch/ppc/xmon/start_8xx.c [new file with mode: 0644]
arch/ppc/xmon/xmon.c
drivers/block/floppy.c
drivers/block/loop.c
drivers/char/rtc.c
drivers/char/specialix.c
drivers/char/vt.c
drivers/ide/ide.c
drivers/net/3c501.c
drivers/net/3c503.c
drivers/net/3c505.c
drivers/net/3c507.c
drivers/net/3c515.c
drivers/net/3c523.c
drivers/net/3c527.c
drivers/net/3c59x.c
drivers/net/82596.c
drivers/net/ac3200.c
drivers/net/appletalk/cops.c
drivers/net/appletalk/ltpc.c
drivers/net/arcnet/arc-rimi.c
drivers/net/arcnet/arcnet.c
drivers/net/arcnet/com20020-isa.c
drivers/net/arcnet/com20020-pci.c
drivers/net/arcnet/com20020.c
drivers/net/arcnet/com90io.c
drivers/net/arcnet/com90xx.c
drivers/net/arcnet/rfc1201.c
drivers/net/at1700.c
drivers/net/atp.c
drivers/net/bonding.c
drivers/net/cs89x0.c
drivers/net/de4x5.c
drivers/net/de600.c
drivers/net/de620.c
drivers/net/depca.c
drivers/net/dgrs.c
drivers/net/dummy.c
drivers/net/e2100.c
drivers/net/eepro.c
drivers/net/eexpress.c
drivers/net/eth16i.c
drivers/net/hp-plus.c
drivers/net/hp.c
drivers/net/hp100.c
drivers/net/lance.c
drivers/net/lne390.c
drivers/net/ne.c
drivers/net/ne2.c
drivers/net/ne3210.c
drivers/net/net_init.c
drivers/net/ni5010.c
drivers/net/ni52.c
drivers/net/ni65.c
drivers/net/pcmcia/Config.in
drivers/net/pcmcia/com20020_cs.c
drivers/net/pcmcia/pcnet_cs.c
drivers/net/pcmcia/ray_cs.c
drivers/net/plip.c
drivers/net/ppp_generic.c
drivers/net/rcpci45.c
drivers/net/sb1000.c
drivers/net/shaper.c
drivers/net/sk_mca.c
drivers/net/skfp/skfddi.c
drivers/net/slip.c
drivers/net/smc-mca.c
drivers/net/smc-ultra.c
drivers/net/smc-ultra32.c
drivers/net/strip.c
drivers/net/tulip/tulip_core.c
drivers/net/wan/comx.c
drivers/net/wan/cosa.c
drivers/net/wan/dlci.c
drivers/net/wan/hostess_sv11.c
drivers/net/wan/sealevel.c
drivers/net/wavelan.c
drivers/net/wd.c
drivers/pci/pci.ids
drivers/pci/proc.c
drivers/pcmcia/bulkmem.c
drivers/pcmcia/ds.c
drivers/pcmcia/tcic.c
drivers/sound/trident.c
drivers/sound/trident.h
drivers/usb/hub.c
drivers/usb/keybdev.c
drivers/usb/mousedev.c
drivers/usb/scanner.c
drivers/usb/scanner.h
drivers/usb/uhci.c
drivers/usb/usb-ohci.c
drivers/usb/usb-storage.c
drivers/usb/usb-storage.h
drivers/video/Makefile
drivers/video/aty128fb.c
drivers/video/macmodes.c
fs/autofs/autofs_i.h
fs/autofs/dirhash.c
fs/autofs/root.c
fs/buffer.c
fs/dcache.c
fs/inode.c
fs/isofs/dir.c
fs/nfs/read.c
fs/nfsd/vfs.c
fs/ntfs/Makefile
fs/ntfs/fs.c
fs/ntfs/struct.h
fs/ntfs/super.c
fs/ntfs/util.c
fs/pipe.c
fs/proc/base.c
fs/super.c
include/asm-ppc/atomic.h
include/asm-ppc/bitops.h
include/asm-ppc/cache.h
include/asm-ppc/cpm_8260.h [new file with mode: 0644]
include/asm-ppc/est8260.h [new file with mode: 0644]
include/asm-ppc/feature.h
include/asm-ppc/gemini_serial.h
include/asm-ppc/heathrow.h
include/asm-ppc/ide.h
include/asm-ppc/immap_8260.h [new file with mode: 0644]
include/asm-ppc/io.h
include/asm-ppc/irq.h
include/asm-ppc/mpc8260.h [new file with mode: 0644]
include/asm-ppc/nvram.h
include/asm-ppc/pgtable.h
include/asm-ppc/posix_types.h
include/asm-ppc/processor.h
include/asm-ppc/resource.h
include/asm-ppc/rpxclassic.h
include/asm-ppc/semaphore.h
include/asm-ppc/system.h
include/asm-ppc/termbits.h
include/linux/arcdevice.h
include/linux/coda_linux.h
include/linux/com20020.h
include/linux/fs.h
include/linux/mm.h
include/linux/netdevice.h
include/linux/ntfs_fs_sb.h
include/linux/pci_ids.h
include/linux/sched.h
include/linux/swap.h
include/linux/timer.h
include/net/atmclip.h
include/net/tcp.h
ipc/shm.c
kernel/fork.c
kernel/sched.c
kernel/timer.c
mm/memory.c
mm/page_io.c
mm/swap_state.c
mm/swapfile.c
mm/vmscan.c
net/atm/clip.c
net/core/dev.c
net/core/dst.c
net/ipv4/inetpeer.c
net/ipv4/ipconfig.c
net/ipv4/raw.c
net/ipv4/tcp_ipv4.c
net/ipv4/tcp_timer.c
net/ipv4/udp.c
net/sched/sch_generic.c
net/socket.c

index f5c4d516f4101e125117bbea550e32560d6ec552..586a6de07d2cd77773ea5b63ea0b16c6fbb955bc 100644 (file)
@@ -787,9 +787,9 @@ ftp://metalab.unc.edu/pub/Linux/hardware/pciutils-2.1.5.tar.gz
 Powertweak
 ==========
 
-The 0.1.2 release:
-http://linux.powertweak.com/files/powertweak-0.1.2.tgz
-ftp://atrey.karlin.mff.cuni.cz/pub/linux/pci/powertweak/powertweak-0.1.2.tgz
+The 0.1.13 release:
+http://linux.powertweak.com/files/powertweak-0.1.13.tgz
+ftp://atrey.karlin.mff.cuni.cz/pub/linux/pci/powertweak/powertweak-0.1.13.tgz
 
 Xosview
 =======
index 1397a81024464d09375a63dd6966b40b978ca6c4..222d003fb33df3b4a1f9021d756d32b67f133868 100644 (file)
@@ -9850,7 +9850,7 @@ CONFIG_USB_MDC800
   Say Y here if you want to connect this type of still camera to
   your computer's USB port. This driver can be used with gphoto 0.4.3
   and higher (look at http://www.gphoto.org ).
-  To use it create a device node with "mknod /dev/mustek c 10 171" and
+  To use it create a device node with "mknod /dev/mustek c 180 32" and
   configure it in your software.
 
   This code is also available as a module ( = code which can be
@@ -10444,6 +10444,8 @@ CONFIG_NTFS_RW
   damaged. Also, make sure to run chkdsk from within Microsoft
   Windows NT after having performed any writes to a NTFS partition
   from Linux to detect any problems as early as possible.
+  Please note that write support is limited to Windows NT4 and
+  earlier versions.
 
   If unsure, say N.
 
index 8e7505bd490f4e84f22c994c0c864f171f44644b..7f8794cf6fd2678c1c21c5453d63e75fe57c2c15 100644 (file)
@@ -12,6 +12,9 @@ volume sets on top of the md driver, although mirror and stripe
 sets should work as well - if the md driver can be talked into 
 using the same layout as Windows NT.
 
+Please note that the experimental write support is limited to
+Windows NT4 and earlier versions.
+
 The ntfs driver supports the following mount options:
 iocharset=name      Character set to use when returning file names.
                     Unlike VFAT, NTFS suppresses names that contain
index 1eebbfef5b5a9a94a0fc3901ed51172fba5adf00..850ce4838d544677f0569f1daa3120f931266cc1 100644 (file)
@@ -1,5 +1,10 @@
+Documentation/networking/vortex.txt
+Andrew Morton <andrewm@uow.edu.au>
+30 April 2000
+
+
 This document describes the usage and errata of the 3Com "Vortex" device
-driver for Linux.
+driver for Linux, 3c59x.c.
 
 The driver was written by Donald Becker <becker@cesdis.gsfc.nasa.gov>
 
@@ -8,7 +13,14 @@ Please report problems to one or more of:
 
   Andrew Morton <andrewm@uow.edu.au>
   Netdev mailing list <netdev@oss.sgi.com>
+  Linux kernel mailing list <linux-kernel@vger.rutgers.edu>
+
+Please note the 'Reporting and Diagnosing Problems' section at the end
+of this file.
+
 
+Since kernel 2.3.99-pre6, this driver incorporates the support for the
+3c575-series Cardbus cards which used to be handled by 3c575_cb.c.
 
 This driver supports the following hardware:
 
@@ -42,55 +54,133 @@ This driver supports the following hardware:
    3c450 Cyclone/unknown
    3Com Boomerang (unknown version)
 
-When loaded as a module the following variables may be set:
- name   type   description
- debug  int    The debug message level, 0 (no messages) to 6 (wordy).
- options int[] The media type override and card operation settings
-               (See list below.)
 
-An example of loading the vortex module is
-       insmod 3c59x.o debug=1 options=0,,12
-This sets the debug message level to minimal messages, sets the first card to
-the 10baseT transceiver, the second to the EEPROM-set transceiver, and the
-third card to operate in full-duplex mode using its 100baseTx transceiver.
-(Note: card ordering is set by the PCI BIOS.)
+Module parameters
+=================
+
+There are several parameters which may be provided to the driver when
+its module is loaded.  These are usually placed in /etc/modules.conf
+(used to be conf.modules).  Example:
+
+options 3c59x debug=3 rx_copybreak=300
+
+If you are using the PCMCIA tools (cardmgr) then theoptions may be
+placed in /etc/pcmcia/config.opts:
+
+module "3c59x" opts "debug=3 extra_reset=1"
+
+
+The supported parameters are:
+
+debug=N
+
+  Where N is a number from 0 to 7.  Anything above 3 produces a lot
+  of output in your system logs.  debug=1 is default.
+
+options=N1,N2,N3,...
+
+  Each number in the list provides an option to the corresponding
+  network card.  So if you have two 3c905's and you wish to provide
+  them with option 0x204 you would use:
 
-Possible media type settings
+    options=0x204,0x204
+
+  The individual options are composed of a number of bitfields which
+  have the following meanings:
+
+  ssible media type settings
        0       10baseT
        1       10Mbs AUI
        2       undefined
        3       10base2 (BNC)
        4       100base-TX
        5       100base-FX
-       6       MII (not yet available)
-       7       <Use default setting>
-       
-       8       Full-duplex bit
-               8 10baseT full-duplex
-               12 100baseTx full-duplex 
-       16      Bus-master enable bit (experimental use only!)
+       6       MII (Media Independent Interface)
+       7       Use default setting from EEPROM
+       8       Autonegotiate
+       9       External MII
+       10      Use default setting from EEPROM
 
-Details of the device driver implementation are at the top of the source file.
+  When generating a value for the 'options' setting, the above media
+  selection values may be OR'ed (or added to) the following:
 
-Additional documentation is available at Don Becker's Linux Drivers site:
+  512 (0x200)  Force full-duplex
+  16  (0x10)   Bus-master enable bit (Old Vortex cards only)
+
+  For example:
+
+    insmod 3c59x options=0x204
+
+  will force full-duplex 100base-TX, rather than allowing the usual
+  autonegotiation.
+
+full_duplex=N1,N2,N3...
+
+  Similar to bit 9 of 'options'.  Forces the corresponding card into
+  full-duplex mode.
+
+rx_copybreak=M
+
+  The driver preallocates 32 full-sized (1536 byte) network buffers
+  for receiving.  When a packet arrives, the driver has to decide
+  whether to leave the packet in its full-sized buffer, or to allocate
+  a smaller buffer and copy the packet across into it.
+
+  This is a speed/space tradeoff.
+
+  The value of rx_copybreak is used to decide when to make the copy. 
+  If the packet size is less than rx_copybreak, the packet is copied. 
+  The default value for rx_copybreak is 200 bytes.
+
+max_interrupt_work=N
+
+  The driver's interrupt service routine can handle many receive and
+  transmit packets in a single invokation.  It does this in a loop. 
+  The value of max_interrupt_work governs how mnay times the interrupt
+  service routine will loop.  The default value is 32 loops.  If this
+  is exceeded the interrupt service routine gives up and generates a
+  warning message "eth0: Too much work in interrupt".
+
+extra_reset=N
+
+  Where N is 0 or 1 (default 0).
+
+  Some network cards (notably 3CCFE575CT Cardbus) do not initialise
+  correctly and need an extra transmitter reset.  If you find that the
+  card comes up receiving but not transmitting, try giving the module
+  the 'extra_reset=1' option.
+
+compaq_ioaddr=N
+compaq_irq=N
+compaq_device_id=N
+
+  "Variables to work-around the Compaq PCI BIOS32 problem"....
 
-  http://cesdis.gsfc.nasa.gov/linux/drivers/vortex.html
 
 
 Additional resources
 --------------------
 
+Details of the device driver implementation are at the top of the source file.
+
+Additional documentation is available at Don Becker's Linux Drivers site:
+
+  http://cesdis.gsfc.nasa.gov/linux/drivers/vortex.html
+
 Donald Becker's driver development site:
 
+     http://www.scyld.com
      http://cesdis.gsfc.nasa.gov/linux/
 
 Don's vortex-diag program is useful for inspecting the NIC's state:
 
+     http://www.scyld.com/diag/#pci-diags
      http://cesdis.gsfc.nasa.gov/linux/diag/vortex-diag.c
 
 Don's mii-diag program may be used for inspecting and manipulating the
 NIC's Media Independent Interface subsystem:
 
+     http://www.scyld.com/diag/#mii-diag
      http://cesdis.gsfc.nasa.gov/linux/diag/#mii-diag
 
 3Com's documentation for many NICs, including the ones supported by
@@ -104,8 +194,16 @@ series kernel is available at
      http://www.uow.edu.au/~andrewm/linux/#3c59x-2.3
 
 
+Autonegotiation notes
+---------------------
+
+  The driver uses a one-minute heartbeat for adapting to changes in
+  the external LAN environment.  This means that when, for example, a
+  machine is unplugged from a hubbed 10baseT LAN plugged into a
+  switched 100baseT LAN, the throughput will be quite dreadful for up
+  to sixty seconds.  Be patient.
 
-Cisco interoperability note from Walter Wong <wcw+@CMU.EDU>:
+  Cisco interoperability note from Walter Wong <wcw+@CMU.EDU>:
 
   On a side note, adding HAS_NWAY seems to share a problem with the
   Cisco 6509 switch.  Specifically, you need to change the spanning
@@ -114,3 +212,32 @@ Cisco interoperability note from Walter Wong <wcw+@CMU.EDU>:
   we've noticed for a while but haven't had the time to track down.
 
 
+Reporting and diagnosing problems
+---------------------------------
+
+If the driver plays up, there are a number of things you can do analyse
+the problem and to help others do this:
+
+- Turn on debugging in the driver
+       Add 'debug=7' to /etc/modules.conf (/etc/conf.modules)
+       Change 'vortex_debug' to 7 in the source code.
+
+- Send all kernel logs, starting with the first probe of the card.
+
+- Run 'mii-diag -v' to show the state of the Media Independent
+  Interface.  If the card sometimes works and sometimes doesn't, run
+  'mii-diag -v' in both states.
+
+- Please run 'vortex-diag -aaee' in both good and bad states.  This
+  show the NIC's registers and EEPROM contents.
+
+- Describe your setup: 10baseT, 100baseT, full/half duplex, etc.
+
+- Note any additional module insertion commands you're using.
+
+- Try different media type settings (see above).
+
+- Try inserting the module with 'extra_reset=1' (or compile this into
+  the driver).
+
+
index c47491765123569e5d97c20a5b2d6632265b4d6f..25c36b7fe796a940039a51831acb69fdfacfa510 100644 (file)
@@ -1,13 +1,12 @@
 Copyright (C) 1999, 2000 David E. Nelson
 
-Mar. 23, 2000
+April 26, 2000
 
 CHANGES
 
-- Amended for Linux-2.3.40
+- Amended for Linux-2.3.99-pre6-3
 - Updated for multiple scanner support
 
-
 INTRODUCTION
 
 This document will hopefully provide enough info on how to get SANE
@@ -15,9 +14,12 @@ working with a Hewlett Packard USB capable scanner using the USB
 interface.  The majority of HP Scanners support the Scanner Control
 Language (SCL) which is both published by HP and supported by SANE.
 The only HP Scanners that I'm aware of that do not support SCL are the
-4200C and the 3300C.  All other HP scanners with USB interfaces should
-work (4100C, 5200C, 6200C, and 6300C).  Of course as HP releases new
-scanners this information may change.
+4200C ,3300C, and the PhotoSmart S20.  All other HP scanners with USB
+interfaces should work (4100C, 5200C, 6200C, and 6300C) as do models
+that are derived from the models above. ie the 6350C which is a 6300C
+with a transparency adaptor included with the scanner at time of
+purchase.  Of course as HP releases new scanners this information may
+change.
 
 
 REQUIREMENTS
@@ -37,9 +39,9 @@ At the time of this writing, version 0.83 was available.
 
 OK, I'VE INSTALLED SANE. SO WHAT DO I DO NOW?
 
-NOTE: $INSTALL_DIR is the location where SANE is installed.  It may
-be /usr/local, /usr, /opt or somewhere else.  If you don't know, ask
-your system administrator.
+NOTE: $INSTALL_DIR is the location where SANE is installed.  It may be
+/usr/local, /usr, /opt or somewhere else.  If you don't know, ask your
+system administrator.
 
 1) Make sure that you have the libsane-hp.* libraries under the
 $INSTALL_DIR/lib/sane/ directory.  If you don't, then the HP backend
@@ -56,17 +58,18 @@ files: dll.conf, hp.conf.
     option connect-device
 
 NOTE: If you are using multiple scanners, make sure to have the correct
-devince, ie /dev/usbscanner0.  See scanner.txt for more info.
+device, ie /dev/usbscanner0.  See scanner.txt for more info.
 
 3) You should now be able to use SANE (xscanimage or scanimage).
 
 Don't forget to read any relevant man pages regarding the usage of
-SANE.  If you have other entries uncommented in dll.conf, you may have
-to specify the device to (x)scanimage.  Again, `man` is your friend.
-The xscanimage (1) man page has info on how to get 'The Gimp' to work
-with xscanimage.  Note that Gimp support must be compiled into SANE
-for it work.  If you are dealing with a RedHat system, this means that
-you'll also need to install the gimp-devel rpm package.
+SANE.  If you have other entries uncommented in 'dll.conf', you may
+have to specify the device to (x)scanimage.  Again, `man` is your
+friend.  The xscanimage (1) man page has info on how to get 'The Gimp'
+to work with xscanimage.  Note that Gimp support must be compiled into
+SANE for it to work.  If you are dealing with a RedHat system, this
+means that you'll also need to install the gimp-devel rpm package
+prior to compiling SANE.
 
 NOTE: The issues regarding core dumping by (x)scanimage have (or seem
 to be thus far) been resolved with version 0.2+ of the USB scanner
index a750e191d0b35028ab2ddf5882d004c53e5b3cd1..e800b37e5f7dbbe12c895fa0588391c5969e303b 100644 (file)
@@ -1,25 +1,26 @@
 Copyright (C) 1999, 2000 David E. Nelson
 
-Mar. 23, 2000
+April 26, 2000
 
 CHANGES
 
-- Amended for linux-2.3.40
+- Amended for linux-2.3.99-pre6-3
 - Appended hp_scan.c to end of this README
 - Removed most references to HP
 - Updated uhci/ohci host controller info
 - Updated support for multiple scanner support
 - Updated supported scanners list
-
+- Updated usbdevfs info
+- Spellcheck
 
 OVERVIEW
 
-This README will address issues regarding how to configure the kernel
+This README addresses issues regarding how to configure the kernel
 to access a USB scanner.  Although the driver was originally conceived
 for USB HP scanners, it's general enough so that it can be used with
 other scanners.  Also, one can now pass the USB Vendor and Product
 ID's using module parameters for unknown scanners.  Refer to the
-document scanner_hp_sane.txt for guidance on how to configure SANE to
+document scanner-hp-sane.txt for guidance on how to configure SANE to
 use a USB HP Scanner.
 
 
@@ -41,11 +42,11 @@ more information on accomplishing this.
 A Linux kernel with USB Scanner support enabled.
 
 'lspci' which is only needed to determine the type of USB hardware
-available in your machine.
+available/installed in your machine.
 
 CONFIGURATION
 
-Using `lspci -v`, determine the type of USB hardware available.
+Using `lspci -v`, determine the type of USB hardware available/installed.
 
   If you see something like:
 
@@ -68,7 +69,10 @@ kernel, select 'Support for USB', 'OHCI/UHCI' depending on your
 hardware (determined from the steps above), 'USB Scanner support', and
 'Preliminary USB device filesystem'.  Compile and install the modules
 (you may need to execute `depmod -a` to update the module
-dependencies).  Testing was performed only as modules, YMMV.
+dependencies). If any of the USB sections were compiled into the
+kernel, a reboot is necessary. NOTE: Updating the boot disk with
+'lilo' may also be required. Testing was performed only as modules,
+YMMV.
 
 Beginning with version 0.4 of the driver, up to 16 scanners can be
 connected/used simultaneously.  If you intend to use more than
@@ -82,14 +86,15 @@ one scanner at a time:
        `mknod /dev/usb/scanner15 180 63`
 
 
-If you forsee using only one scanner:
+If you foresee using only one scanner it is best to:
        `mknod /dev/usbscanner0 c 180 48`
        `ln -s /dev/usbscanner0 /dev/usbscanner`
 
 
 Set appropriate permissions for /dev/usbscanner[0-15] (don't forget
 about group and world permissions).  Both read and write permissions
-are required for proper operation.
+are required for proper operation. For example:
+       `chmod 666 /dev/usbscanner0`
 
 Load the appropriate modules (if compiled as modules):
 
@@ -108,12 +113,23 @@ be used to test the scanner device if it's an HP scanner that supports
 SCL (Scanner Control Language).  Known HP scanner that support SCL are
 the 4100, 5200, 6200, the 6300 -- note that the 4200 is *not*
 supported since it does not understand SCL; it's also strongly
-suspected that the 3300 is not SCL compliant.  Hp_scan.c's purpose is
-to test the driver without having to retrieve/configure SANE.
-Hp_scan.c will scan the entire bed and put the output into a file
-called 'out.dat' in the current directory.  The data in the file is
-raw data so it's not very useful for imaging.
-
+suspected that the 3300 and the PhotoSmart S20 are not SCL compliant.
+Hp_scan.c's purpose is to test the driver without having to
+retrieve/configure SANE.  Hp_scan.c will scan the entire bed and put
+the output into a file called 'out.dat' in the current directory.  The
+data in the file is raw data so it's not very useful for imaging.
+
+MESSAGES
+
+On occassion the message 'usb_control/bulk_msg: timeout' or something
+similar will appear in '/var/adm/messages' or on the console or both,
+depending on how your system is configured.  This is a side effect
+that scanners are sometimes very slow at warming up and/or
+initialiazing.  In most cases, however, only several of these messages
+should appear and is generally considered to be normal.  If you see
+a message of the type 'excessive NAK's received' then this should
+be considered abnormal and generally indicates that the USB system is
+unable to communicate with the scanner for some particular reason.
 
 SUPPORTED SCANNERS
 
@@ -125,72 +141,97 @@ support the listed USB products.
 At the time of this writing, the following scanners were supported by
 scanner.c:
 
-  Acer
-
-    Prisa AcerScan 620U
-
-  Agfa
-
-    SnapScan 1212U, SnapScan Touch
-
-  Genius
-
-    ColorPage Vivid Pro
-
-  Hewlett Packard
-
-    3300, 4100, 4200, 5200, 6200, 6300, PhotoSmart S20
-
-  Microtek
-
-    ScanMaker X6-X6U, Phantom 336CX - C3, Phantom C6, ScanMaker V6USL,
-    ScanMaker V6UL - SpicyU
-
-  Mustek
+ Acer
+        Prisa Acerscan 620U & 640U (!)
+        Prisa AcerScan 620U (!)
+ Agfa
+        SnapScan 1212U
+        Another SnapScan 1212U (?)
+        SnapScan Touch
+ Colorado -- See Primax/Colorado below
+ Epson -- See Seiko/Epson below
+ Genius
+         ColorPage-Vivid Pro
+ Hewlett Packard
+        3300C
+        4100C
+        4200C
+        PhotoSmart S20
+        5200C
+        6200C
+        6300C
+ Microtek
+        ScanMaker X6 - X6U
+        Phantom 336CX - C3
+        Phantom 336CX - C3 #2
+        Phantom C6
+        ScanMaker V6USL
+        ScanMaker V6USL #2
+        ScanMaker V6UL - SpicyU
+ Mustek
+        1200 CU
+ Primax/Colorado
+        G2-300 #1
+        G2-600 #1
+        G2E-300 #1
+        ReadyScan 636i
+        G2-300 #2
+        G2-600 #2
+        G2E-300 #2
+        G2E-600
+        Colorado USB 9600
+        Colorado USB 19200
+        Colorado 600u
+        Colorado 1200u
+ Seiko/Epson Corp.
+        Perfection 636U and 636Photo
+        Perfection 610
+        Perfection 1200U and 1200Photo
+ Umax
+        Astra 1220U
+        Astra 1236U
+        Astra 2000U
+        Astra 2200U
+ Visioneer
+        OneTouch 5300
+        OneTouch 7600 duplicate ID (!)
+        6100
 
-    1200 CU
 
-  Primax/Colorado
-
-    G2-300, G2-600, G2E-300, G2E-600, ReadyScan 636i, Colorado USB
-    19200, Colorado 600u, Colorado 1200u
-
-  Seiko/Epson
-
-    Perfection Perfection 610, Perfection 636U/636Photo, Perfection
-    1200U/1200Photo
-
-  Umax
+MODULE PARAMETERS
 
-    Astra 1220U, 1236U, 2000U
+If you have a device that you wish to experiment with or try using
+this driver with, but the Vendor and Product ID's are not coded in,
+don't despair.  If the driver was compiled as a module, you can pass
+options to the driver.  Simply add 
 
-  Visioneer
+  options scanner vendor=0x#### product=0x****
 
-    OneTouch 5300, OneTouch 7600, 6100,
+to the /etc/modules.conf file replacing the #'s and the *'s with the
+correct ID's.  The ID's can be retrieved from the messages file or
+using `cat /proc/bus/usb/devices`. Note that USB /proc support must be
+enabled during kernel configuration.  If the 'scanner' module is
+already loaded into memory, it must be reloaded for the module
+parameters to take effect.  In essence, `rmmod scanner; modprobe
+scanner` must be performed.
 
+**NOTE**: In later kernels (2.3.38+), a new filesystem was introduced,
+usbdevfs.  To mount the filesystem, issue the command (as root):
 
-  User Specified.  See MODULE PARAMETERS for details.
+  mount -t usbdevfs /proc/bus/usb /proc/bus/usb
 
+An alternative and more permanent method would be to add
 
-MODULE PARAMETERS
+  none  /proc/bus/usb  usbdevfs  defaults  0  0
 
-If you have a device that you wish to experiment with or try using
-this driver with, but the Vendor and Product ID's are not coded in,
-don't despair.  If the driver was compiled as a module, you can pass
-options to the driver.  Simply add 'options scanner vendor=0x####
-product=0x****' to the conf.modules/modules.conf file replacing the
-#'s and the *'s with the correct ID's.  The ID's can be retrieved from
-the messages file or using `cat /proc/bus/usb/devices` if USB /proc
-support was selected during kernel configuration.  **NOTE**:In later
-kernels (2.3.38+), a new filesystem was introduced, usbdevfs.  To
-mount the filesystem, issue the command `mount -t usbdevfs
-/proc/bus/usb /proc/bus/usb`.  You can then issue ` cat
-/proc/bus/usb/devices` to extract USB device information.
+to /etc/fstab.  This will mount usbdevfs at each reboot.  You can then
+issue `cat /proc/bus/usb/devices` to extract USB device information.
 
 
 BUGS
 
-If you encounter any problems feel free to drop me an email.
+Just look at the list of fixes in the source files.  So, if you
+encounter any problems feel free to drop me an email.
 
 David /\/elson
 dnelson@jump.net
index ab5318154d9bbc8cbc8731fbdbd01044b5b3d646..30a265bde7edfce32b3180158c9c7d5d7bedeeab 100644 (file)
@@ -863,7 +863,7 @@ S:  Maintained
 RAGE128 FRAMEBUFFER DISPLAY DRIVER
 P:     Brad Douglas
 M:     brad@neruo.com
-L:     linux-fbdev@vuser.vc.union.edu
+L:     linux-fbdev@vuser.vu.union.edu
 S:     Maintained
 
 RAYLINK/WEBGEAR 802.11 WIRELESS LAN DRIVER
index cc3f8e1dafc631ee37c1b283117542fac4e08210..afb90ab125acac4b52cbda1beb9b7bbfda613955 100644 (file)
@@ -330,12 +330,18 @@ int pcibios_enable_resources(struct pci_dev *dev)
  *  If we set up a device for bus mastering, we need to check the latency
  *  timer as certain crappy BIOSes forget to set it properly.
  */
+unsigned int pcibios_max_latency = 255;
+
 void pcibios_set_master(struct pci_dev *dev)
 {
        u8 lat;
        pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat);
-       if (lat < 16) {
-               printk("PCI: Increasing latency timer of device %s to 64\n", dev->slot_name);
-               pci_write_config_byte(dev, PCI_LATENCY_TIMER, 64);
-       }
+       if (lat < 16)
+               lat = (64 <= pcibios_max_latency) ? 64 : pcibios_max_latency;
+       else if (lat > pcibios_max_latency)
+               lat = pcibios_max_latency;
+       else
+               return;
+       printk("PCI: Setting latency timer of device %s to %d\n", dev->slot_name, lat);
+       pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat);
 }
index 5af43f6619f560f87afdbb03a1f7bcd8da5fd4b2..f4f808e4c78424d03258072595ddba06a4c181d7 100644 (file)
@@ -25,6 +25,8 @@ extern unsigned int pci_probe;
 
 /* pci-i386.c */
 
+extern unsigned int pcibios_max_latency;
+
 void pcibios_resource_survey(void);
 int pcibios_enable_resources(struct pci_dev *);
 
@@ -64,5 +66,6 @@ struct irq_routing_table {
 
 extern unsigned int pcibios_irq_mask;
 
+void pcibios_irq_init(void);
 void pcibios_fixup_irqs(void);
 int pcibios_lookup_irq(struct pci_dev *dev, int assign);
index 4695abdf47a65d3d3e78a63600b9a461595b2c79..fa3f70e4159cecf769435f4dd349044407c273dc 100644 (file)
@@ -125,11 +125,22 @@ static void eisa_set_level_irq(unsigned int irq)
        }
 }
 
+static int pirq_ali_get(struct pci_dev *router, struct pci_dev *dev, int pirq)
+{
+       static unsigned char irqmap[16] = { 0, 9, 3, 10, 4, 5, 7, 6, 1, 11, 0, 12, 0, 14, 0, 15 };
+       pirq--;
+       if (pirq < 8) {
+               u8 x;
+               unsigned reg = 0x48 + (pirq >> 1);
+               pci_read_config_byte(router, reg, &x);
+               return irqmap[(pirq & 1) ? (x >> 4) : (x & 0x0f)];
+       }
+       return 0;
+}
+
 static int pirq_ali_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq)
 {
-       static unsigned char irqmap[16] = {
-               0, 8, 0, 2, 4, 5, 7, 6, 0, 1, 3, 9, 11, 0, 13, 15
-       };
+       static unsigned char irqmap[16] = { 0, 8, 0, 2, 4, 5, 7, 6, 0, 1, 3, 9, 11, 0, 13, 15 };
        unsigned int val = irqmap[irq];
        pirq--;
        if (val && pirq < 8) {
@@ -211,7 +222,7 @@ static struct irq_router pirq_routers[] = {
        { "PIIX", PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371FB_0, pirq_piix_get, pirq_piix_set },
        { "PIIX", PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371SB_0, pirq_piix_get, pirq_piix_set },
        { "PIIX", PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_0, pirq_piix_get, pirq_piix_set },
-       { "ALI", PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, NULL, pirq_ali_set },
+       { "ALI", PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, pirq_ali_get, pirq_ali_set },
        { "VIA", PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_0, pirq_via_get, pirq_via_set },
        { "VIA", PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C596, pirq_via_get, pirq_via_set },
        { "VIA", PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686, pirq_via_get, pirq_via_set },
@@ -236,7 +247,9 @@ static void __init pirq_find_router(void)
        }
 #endif
        if (!(pirq_router_dev = pci_find_slot(rt->rtr_bus, rt->rtr_devfn))) {
-               DBG("PCI: Interrupt router not found\n");
+               DBG("PCI: Interrupt router not found at %02x:%02x\n", rt->rtr_bus, rt->rtr_devfn);
+               /* fall back to default router */
+               pirq_router = pirq_routers + sizeof(pirq_routers) / sizeof(pirq_routers[0]) - 1;
                return;
        }
        if (rt->rtr_vendor) {
@@ -354,12 +367,9 @@ int pcibios_lookup_irq(struct pci_dev *dev, int assign)
        return 1;
 }
 
-void __init pcibios_fixup_irqs(void)
+void __init pcibios_irq_init(void)
 {
-       struct pci_dev *dev;
-       u8 pin;
-
-       DBG("PCI: IRQ fixup\n");
+       DBG("PCI: IRQ init\n");
        pirq_table = pirq_find_routing_table();
 #ifdef CONFIG_PCI_BIOS
        if (!pirq_table && (pci_probe & PCI_BIOS_IRQ_SCAN))
@@ -369,7 +379,14 @@ void __init pcibios_fixup_irqs(void)
                pirq_peer_trick();
                pirq_find_router();
        }
+}
+
+void __init pcibios_fixup_irqs(void)
+{
+       struct pci_dev *dev;
+       u8 pin;
 
+       DBG("PCI: IRQ fixup\n");
        pci_for_each_dev(dev) {
                /*
                 * If the BIOS has set an out of range IRQ number, just ignore it.
index 6dbac9abd044224430be7f1616f3dfce0ac03434..d1f41ff0df1f4c23d0d6b785a6ac58f422b65ce1 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/sched.h>
 #include <linux/pci.h>
 #include <linux/init.h>
+#include <linux/ioport.h>
 
 #include <asm/segment.h>
 #include <asm/io.h>
@@ -208,6 +209,7 @@ static struct pci_ops * __init pci_check_direct(void)
                        outl (tmp, 0xCF8);
                        __restore_flags(flags);
                        printk("PCI: Using configuration type 1\n");
+                       request_region(0xCF8, 8, "PCI conf1");
                        return &pci_direct_conf1;
                }
                outl (tmp, 0xCF8);
@@ -224,6 +226,7 @@ static struct pci_ops * __init pci_check_direct(void)
                    pci_sanity_check(&pci_direct_conf2)) {
                        __restore_flags(flags);
                        printk("PCI: Using configuration type 2\n");
+                       request_region(0xCF8, 4, "PCI conf2");
                        return &pci_direct_conf2;
                }
        }
@@ -912,6 +915,16 @@ static void __init pci_fixup_ide_trash(struct pci_dev *d)
                d->resource[i].start = d->resource[i].end = d->resource[i].flags = 0;
 }
 
+static void __init pci_fixup_latency(struct pci_dev *d)
+{
+       /*
+        *  SiS 5597 and 5598 chipsets require latency timer set to
+        *  at most 32 to avoid lockups.
+        */
+       DBG("PCI: Setting max latency to 32\n");
+       pcibios_max_latency = 32;
+}
+
 struct pci_fixup pcibios_fixups[] = {
        { PCI_FIXUP_HEADER,     PCI_VENDOR_ID_INTEL,    PCI_DEVICE_ID_INTEL_82451NX,    pci_fixup_i450nx },
        { PCI_FIXUP_HEADER,     PCI_VENDOR_ID_INTEL,    PCI_DEVICE_ID_INTEL_82454GX,    pci_fixup_i450gx },
@@ -921,6 +934,8 @@ struct pci_fixup pcibios_fixups[] = {
        { PCI_FIXUP_HEADER,     PCI_VENDOR_ID_UMC,      PCI_DEVICE_ID_UMC_UM8886BF,     pci_fixup_umc_ide },
        { PCI_FIXUP_HEADER,     PCI_VENDOR_ID_SI,       PCI_DEVICE_ID_SI_5513,          pci_fixup_ide_trash },
        { PCI_FIXUP_HEADER,     PCI_ANY_ID,             PCI_ANY_ID,                     pci_fixup_ide_bases },
+       { PCI_FIXUP_HEADER,     PCI_VENDOR_ID_SI,       PCI_DEVICE_ID_SI_5597,          pci_fixup_latency },
+       { PCI_FIXUP_HEADER,     PCI_VENDOR_ID_SI,       PCI_DEVICE_ID_SI_5598,          pci_fixup_latency },
        { 0 }
 };
 
@@ -969,8 +984,9 @@ void __init pcibios_init(void)
        printk("PCI: Probing PCI hardware\n");
        pci_root_bus = pci_scan_bus(0, pci_root_ops, NULL);
 
-       pcibios_fixup_irqs();
+       pcibios_irq_init();
        pcibios_fixup_peer_bridges();
+       pcibios_fixup_irqs();
        pcibios_resource_survey();
 
 #ifdef CONFIG_PCI_BIOS
index ac088253fe3d54667456ac1ea16800cc24688088..455170f5d7439226b9685f664baa5697b0cf7b06 100644 (file)
  *     Added proper L2 cache detection for Coppermine
  *     Dragan Stancevic <visitor@valinux.com>, October 1999
  *
- *  Added the origninal array for capability flags but forgot to credit 
+ *  Added the original array for capability flags but forgot to credit 
  *  myself :) (~1998) Fixed/cleaned up some cpu_model_info and other stuff
  *     Jauder Ho <jauderho@carumba.com>, January 2000
+ *
+ *  Detection for Celeron coppermine, identify_cpu() overhauled,
+ *  and a few other clean ups.
+ *  Dave Jones <dave@powertweak.com>, April 2000
  *     
  */
 
@@ -794,7 +798,7 @@ void __init setup_arch(char **cmdline_p)
 
 static int __init get_model_name(struct cpuinfo_x86 *c)
 {
-       unsigned int n, dummy, *v, ecx, edx;
+       unsigned int n, dummy, *v;
 
        /* Actually we must have cpuid or we could never have
         * figured out that this was AMD/Cyrix from the vendor info :-).
@@ -809,29 +813,6 @@ static int __init get_model_name(struct cpuinfo_x86 *c)
        cpuid(0x80000003, &v[4], &v[5], &v[6], &v[7]);
        cpuid(0x80000004, &v[8], &v[9], &v[10], &v[11]);
        c->x86_model_id[48] = 0;
-       /*  Set MTRR capability flag if appropriate  */
-       
-       if(c->x86_vendor==X86_VENDOR_AMD)
-       {
-               if(boot_cpu_data.x86 == 5) {
-                       if((boot_cpu_data.x86_model == 9) ||
-                          ((boot_cpu_data.x86_model == 8) && 
-                           (boot_cpu_data.x86_mask >= 8)))
-                               c->x86_capability |= X86_FEATURE_MTRR;
-               }
-       
-               if (n >= 0x80000005){
-                       cpuid(0x80000005, &dummy, &dummy, &ecx, &edx);
-                       printk("CPU: L1 I Cache: %dK  L1 D Cache: %dK\n",
-                               ecx>>24, edx>>24);
-                       c->x86_cache_size=(ecx>>24)+(edx>>24);  
-               }
-               if (n >= 0x80000006){
-                       cpuid(0x80000006, &dummy, &dummy, &ecx, &edx);
-                       printk("CPU: L2 Cache: %dK\n", ecx>>16);
-                       c->x86_cache_size=(ecx>>16);
-               }
-       }
        return 1;
 }
 
@@ -839,14 +820,24 @@ static int __init amd_model(struct cpuinfo_x86 *c)
 {
        u32 l, h;
        unsigned long flags;
+       unsigned int n, dummy, ecx, edx;
        int mbytes = max_mapnr >> (20-PAGE_SHIFT);
-       
+
        int r=get_model_name(c);
-       
+
        /*
-        *      Now do the cache operations. 
+        * Set MTRR capability flag if appropriate
+        */
+       if(boot_cpu_data.x86 == 5) {
+               if((boot_cpu_data.x86_model == 9) ||
+                  ((boot_cpu_data.x86_model == 8) && 
+                   (boot_cpu_data.x86_mask >= 8)))
+                       c->x86_capability |= X86_FEATURE_MTRR;
+       }
+
+       /*
+        * Now do the cache operations. 
         */
-        
        switch(c->x86)
        {
                case 5:
@@ -903,6 +894,20 @@ static int __init amd_model(struct cpuinfo_x86 *c)
                case 6: /* An Athlon. We can trust the BIOS probably */
                        break;          
        }
+
+       cpuid(0x80000000, &n, &dummy, &dummy, &dummy);
+       if (n >= 0x80000005) {
+               cpuid(0x80000005, &dummy, &dummy, &ecx, &edx);
+               printk("CPU: L1 I Cache: %dK  L1 D Cache: %dK\n",
+                       ecx>>24, edx>>24);
+               c->x86_cache_size=(ecx>>24)+(edx>>24);  
+       }
+       if (n >= 0x80000006) {
+               cpuid(0x80000006, &dummy, &dummy, &ecx, &edx);
+               printk("CPU: L2 Cache: %dK\n", ecx>>16);
+               c->x86_cache_size=(ecx>>16);
+       }
+
        return r;
 }
                        
@@ -1029,13 +1034,13 @@ static void __init cyrix_model(struct cpuinfo_x86 *c)
                /* It isnt really a PCI quirk directly, but the cure is the
                   same. The MediaGX has deep magic SMM stuff that handles the
                   SB emulation. It thows away the fifo on disable_dma() which
-                   is wrong and ruins the audio. 
+                  is wrong and ruins the audio. 
                    
-                   Bug2: VSA1 has a wrap bug so that using maximum sized DMA 
-                   causes bad things. According to NatSemi VSA2 has another
-                   bug to do with 'hlt'. I've not seen any boards using VSA2
-                   and X doesn't seem to support it either so who cares 8).
-                   VSA1 we work around however.
+                  Bug2: VSA1 has a wrap bug so that using maximum sized DMA 
+                  causes bad things. According to NatSemi VSA2 has another
+                  bug to do with 'hlt'. I've not seen any boards using VSA2
+                  and X doesn't seem to support it either so who cares 8).
+                  VSA1 we work around however.
                    
                */
                
@@ -1043,7 +1048,7 @@ static void __init cyrix_model(struct cpuinfo_x86 *c)
                isa_dma_bridge_buggy = 2;
 #endif         
                c->x86_cache_size=16;   /* Yep 16K integrated cache thats it */
-               
+
                /* GXm supports extended cpuid levels 'ala' AMD */
                if (c->cpuid_level == 2) {
                        get_model_name(c);  /* get CPU marketing name */
@@ -1256,7 +1261,7 @@ static struct cpu_model_info cpu_models[] __initdata = {
 
 void __init identify_cpu(struct cpuinfo_x86 *c)
 {
-       int i;
+       int i=0;
        char *p = NULL;
 
        c->loops_per_sec = loops_per_sec;
@@ -1264,100 +1269,118 @@ void __init identify_cpu(struct cpuinfo_x86 *c)
 
        get_cpu_vendor(c);
 
-       if (c->x86_vendor == X86_VENDOR_UNKNOWN &&
-           c->cpuid_level < 0)
-               return;
+       switch (c->x86_vendor) {
 
-       if (c->x86_vendor == X86_VENDOR_CYRIX) {
-               cyrix_model(c);
-               return;
-       }
+               case X86_VENDOR_UNKNOWN:
+                       if (c->cpuid_level < 0)
+                               return;
+                       break;
 
-       if (c->x86_vendor == X86_VENDOR_AMD && amd_model(c))
-               return;
+               case X86_VENDOR_CYRIX:
+                       cyrix_model(c);
+                       return;
 
-       if (c->x86_vendor == X86_VENDOR_CENTAUR) {
-               centaur_model(c);
-               return;
-       }
-               
-       if (c->cpuid_level > 0 && c->x86_vendor == X86_VENDOR_INTEL)
-       {
-               if(c->x86_capability&(1<<18))
-               {
-                       /* Disable processor serial number on Intel Pentium III 
-                          from code by Phil Karn */
-                       unsigned long lo,hi;
-                       rdmsr(0x119,lo,hi);
-                       lo |= 0x200000;
-                       wrmsr(0x119,lo,hi);
-                       printk(KERN_INFO "Pentium-III serial number disabled.\n");
-               }
-       }
+               case X86_VENDOR_AMD:
+                       if (amd_model(c))
+                               return;
+                       break;
 
-       if (c->cpuid_level > 1) {
-               /* supports eax=2  call */
-               int edx, dummy;
+               case X86_VENDOR_CENTAUR:
+                       centaur_model(c);
+                       return;
 
-               cpuid(2, &dummy, &dummy, &dummy, &edx);
+               case X86_VENDOR_INTEL:
+                       if(c->x86_capability&(1<<18)) {
+                               /* Disable processor serial number on Intel Pentium III 
+                                  from code by Phil Karn */
+                               unsigned long lo,hi;
+                               rdmsr(0x119,lo,hi);
+                               lo |= 0x200000;
+                               wrmsr(0x119,lo,hi);
+                               printk(KERN_INFO "Pentium-III serial number disabled.\n");
+                       }
 
-               /* We need only the LSB */
-               edx &= 0xff;
+                       if (c->cpuid_level > 1) {
+                               /* supports eax=2  call */
+                               int edx, dummy;
 
-               switch (edx) {
-                       case 0x40:
-                               c->x86_cache_size = 0;
-                               break;
+                               cpuid(2, &dummy, &dummy, &dummy, &edx);
 
-                       case 0x41:
-                               c->x86_cache_size = 128;
-                               break;
+                               /* We need only the LSB */
+                               edx &= 0xff;
 
-                       case 0x42:
-                       case 0x82: /*Detect 256-Kbyte cache on Coppermine*/
-                               c->x86_cache_size = 256;
-                               break;
+                               switch (edx) {
+                               case 0x40:
+                                       c->x86_cache_size = 0;
+                                       break;
 
-                       case 0x43:
-                               c->x86_cache_size = 512;
-                               break;
+                               case 0x41:
+                                       c->x86_cache_size = 128;
+                                       break;
 
-                       case 0x44:
-                               c->x86_cache_size = 1024;
-                               break;
+                               case 0x42:
+                               case 0x82: /*Detect 256-Kbyte cache on Coppermine*/
+                                       c->x86_cache_size = 256;
+                                       break;
 
-                       case 0x45:
-                               c->x86_cache_size = 2048;
-                               break;
+                               case 0x43:
+                                       c->x86_cache_size = 512;
+                                       break;
 
-                       default:
-                               c->x86_cache_size = 0;
-                               break;
-               }
-       }
+                               case 0x44:
+                                       c->x86_cache_size = 1024;
+                                       break;
+
+                               case 0x45:
+                                       c->x86_cache_size = 2048;
+                                       break;
 
+                               default:
+                                       c->x86_cache_size = 0;
+                                       break;
+                               }
+                       }
+
+                       /* Names for the Pentium II/Celeron processors 
+                          detectable only by also checking the cache size.
+                          Dixon is NOT a Celeron. */
+                       if (cpu_models[i].x86 == 6) {
+                               switch (c->x86_model) {
+                                       case 5:
+                                               if (c->x86_cache_size == 0)
+                                                       p = "Celeron (Covington)";
+                                               if (c->x86_cache_size == 256)
+                                                       p = "Mobile Pentium II (Dixon)";
+                                               break;
+
+                                       case 6:
+                                               if (c->x86_cache_size == 128)
+                                                       p = "Celeron (Mendocino)";
+                                               break;
+
+                                       case 8:
+                                               if (c->x86_cache_size == 128)
+                                                       p = "Celeron (Coppermine)";
+                                               break;
+                               }
+                       }
+                       if (p!=NULL)
+                               goto name_decoded;
+
+                       break;
+       }
+       
+       
        for (i = 0; i < sizeof(cpu_models)/sizeof(struct cpu_model_info); i++) {
                if (cpu_models[i].vendor == c->x86_vendor &&
                    cpu_models[i].x86 == c->x86) {
                        if (c->x86_model <= 16)
                                p = cpu_models[i].model_names[c->x86_model];
-
-                       /* Names for the Pentium II/Celeron processors 
-                           detectable only by also checking the cache size.
-                          Dixon is NOT a Celeron. */
-                       if ((cpu_models[i].vendor == X86_VENDOR_INTEL)
-                           && (cpu_models[i].x86 == 6))
-                       {
-                               if(c->x86_model == 5 &&  c->x86_cache_size == 0)
-                                       p = "Celeron (Covington)";                                              
-                               else if(c->x86_model == 6 && c->x86_cache_size == 128)
-                                       p = "Celeron (Mendocino)"; 
-                               else if(c->x86_model == 5 && c->x86_cache_size == 256)
-                                       p = "Mobile Pentium II (Dixon)";
-                       }
                }
        }
 
+name_decoded:
+
        if (p) {
                strcpy(c->x86_model_id, p);
                return;
@@ -1373,11 +1396,10 @@ void __init identify_cpu(struct cpuinfo_x86 *c)
 void __init dodgy_tsc(void)
 {
        get_cpu_vendor(&boot_cpu_data);
-       
+
        if(boot_cpu_data.x86_vendor != X86_VENDOR_CYRIX)
-       {
                return;
-       }
+
        cyrix_model(&boot_cpu_data);
 }
        
@@ -1442,15 +1464,15 @@ int get_cpuinfo(char * buffer)
                        continue;
 #endif
                p += sprintf(p,"processor\t: %d\n"
-                              "vendor_id\t: %s\n"
-                              "cpu family\t: %c\n"
-                              "model\t\t: %d\n"
-                              "model name\t: %s\n",
-                              n,
-                              c->x86_vendor_id[0] ? c->x86_vendor_id : "unknown",
-                              c->x86 + '0',
-                              c->x86_model,
-                              c->x86_model_id[0] ? c->x86_model_id : "unknown");
+                       "vendor_id\t: %s\n"
+                       "cpu family\t: %c\n"
+                       "model\t\t: %d\n"
+                       "model name\t: %s\n",
+                       n,
+                       c->x86_vendor_id[0] ? c->x86_vendor_id : "unknown",
+                       c->x86 + '0',
+                       c->x86_model,
+                       c->x86_model_id[0] ? c->x86_model_id : "unknown");
 
                if (c->x86_mask || c->cpuid_level >= 0)
                        p += sprintf(p, "stepping\t: %d\n", c->x86_mask);
@@ -1470,32 +1492,32 @@ int get_cpuinfo(char * buffer)
                switch (c->x86_vendor) {
 
                    case X86_VENDOR_CYRIX:
-                       x86_cap_flags[24] = "cxmmx";
-                       break;
+                               x86_cap_flags[24] = "cxmmx";
+                               break;
 
                    case X86_VENDOR_AMD:
-                       if (c->x86 == 5 && c->x86_model == 6)
-                               x86_cap_flags[10] = "sep";
-                       if (c->x86 < 6)
-                               x86_cap_flags[16] = "fcmov";
-                       x86_cap_flags[22] = "mmxext";
-                       x86_cap_flags[30] = "3dnowext";
-                       x86_cap_flags[31] = "3dnow";
-                       break;
+                               if (c->x86 == 5 && c->x86_model == 6)
+                                       x86_cap_flags[10] = "sep";
+                               if (c->x86 < 6)
+                                       x86_cap_flags[16] = "fcmov";
+                               x86_cap_flags[22] = "mmxext";
+                               x86_cap_flags[30] = "3dnowext";
+                               x86_cap_flags[31] = "3dnow";
+                               break;
 
                    case X86_VENDOR_INTEL:
-                       x86_cap_flags[16] = "pat";
-                       x86_cap_flags[24] = "fxsr";
-                       break;
+                               x86_cap_flags[16] = "pat";
+                               x86_cap_flags[24] = "fxsr";
+                               break;
 
                    case X86_VENDOR_CENTAUR:
-                       if (c->x86_model >=8)   /* Only Winchip2 and above */
-                           x86_cap_flags[31] = "3dnow";
-                       break;
+                               if (c->x86_model >=8)   /* Only Winchip2 and above */
+                                   x86_cap_flags[31] = "3dnow";
+                               break;
 
                    default:
-                       /* Unknown CPU manufacturer. Transmeta ? :-) */
-                       break;
+                               /* Unknown CPU manufacturer. Transmeta ? :-) */
+                               break;
                }
 
                sep_bug = c->x86_vendor == X86_VENDOR_INTEL &&
@@ -1528,9 +1550,10 @@ int get_cpuinfo(char * buffer)
                for ( i = 0 ; i < 32 ; i++ )
                        if ( c->x86_capability & (1 << i) )
                                p += sprintf(p, " %s", x86_cap_flags[i]);
+
                p += sprintf(p, "\nbogomips\t: %lu.%02lu\n\n",
-                            (c->loops_per_sec+2500)/500000,
-                            ((c->loops_per_sec+2500)/5000) % 100);
+                       (c->loops_per_sec+2500)/500000,
+                       ((c->loops_per_sec+2500)/5000) % 100);
        }
        return p - buffer;
 }
index 2f030f3062ce646341632424e29b8fb5ca9a4750..697645988e11c8c6867eefc184c14dd8c1322b49 100644 (file)
@@ -192,12 +192,17 @@ good_area:
         * make sure we exit gracefully rather than endlessly redo
         * the fault.
         */
-       {
-               int fault = handle_mm_fault(mm, vma, address, write);
-               if (fault < 0)
-                       goto out_of_memory;
-               if (!fault)
-                       goto do_sigbus;
+       switch (handle_mm_fault(mm, vma, address, write)) {
+       case 1:
+               tsk->min_flt++;
+               break;
+       case 2:
+               tsk->maj_flt++;
+               break;
+       case 0:
+               goto do_sigbus;
+       default:
+               goto out_of_memory;
        }
 
        /*
diff --git a/arch/ppc/8260_io/Config.in b/arch/ppc/8260_io/Config.in
new file mode 100644 (file)
index 0000000..8cdd8c6
--- /dev/null
@@ -0,0 +1,22 @@
+#
+# MPC8260 Communication options
+#
+if [ "$CONFIG_NET_ETHERNET" = "y" ]; then
+  mainmenu_option next_comment
+  comment 'MPC8260 Communication Options'
+  bool 'CPM SCC Ethernet' CONFIG_SCC_ENET
+  if [ "$CONFIG_SCC_ENET" = "y" ]; then
+  bool 'Ethernet on SCC1' CONFIG_SCC1_ENET
+    if [ "$CONFIG_SCC1_ENET" != "y" ]; then
+      bool 'Ethernet on SCC2' CONFIG_SCC2_ENET
+    fi
+  fi
+  bool 'FCC Ethernet' CONFIG_FCC_ENET
+  if [ "$CONFIG_FCC_ENET" = "y" ]; then
+  bool 'Ethernet on FCC1' CONFIG_FCC1_ENET
+    if [ "$CONFIG_FCC1_ENET" != "y" ]; then
+      bool 'Ethernet on FCC2' CONFIG_FCC2_ENET
+    fi
+  fi
+  endmenu
+fi
diff --git a/arch/ppc/8260_io/Makefile b/arch/ppc/8260_io/Makefile
new file mode 100644 (file)
index 0000000..240a856
--- /dev/null
@@ -0,0 +1,20 @@
+#
+# Makefile for the linux MPC8xx ppc-specific parts of comm processor
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+# Note 2! The CFLAGS definition is now in the main makefile...
+
+O_TARGET := 8260_io.a
+O_OBJS = commproc.o uart.o
+
+ifdef CONFIG_FCC_ENET
+O_OBJS += fcc.o
+endif
+ifdef CONFIG_SCC_ENET
+O_OBJS += enet.o
+endif
+
+include $(TOPDIR)/Rules.make
diff --git a/arch/ppc/8260_io/commproc.c b/arch/ppc/8260_io/commproc.c
new file mode 100644 (file)
index 0000000..63165f0
--- /dev/null
@@ -0,0 +1,163 @@
+
+/*
+ * General Purpose functions for the global management of the
+ * 8260 Communication Processor Module.
+ * Copyright (c) 1999 Dan Malek (dmalek@jlc.net)
+ * Copyright (c) 2000 MontaVista Software, Inc (source@mvista.com)
+ *     2.3.99 Updates
+ *
+ * In addition to the individual control of the communication
+ * channels, there are a few functions that globally affect the
+ * communication processor.
+ *
+ * Buffer descriptors must be allocated from the dual ported memory
+ * space.  The allocator for that is here.  When the communication
+ * process is reset, we reclaim the memory available.  There is
+ * currently no deallocator for this memory.
+ */
+#include <linux/config.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/param.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/interrupt.h>
+#include <linux/bootmem.h>
+#include <asm/irq.h>
+#include <asm/mpc8260.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/immap_8260.h>
+#include <asm/cpm_8260.h>
+
+static uint    dp_alloc_base;  /* Starting offset in DP ram */
+static uint    dp_alloc_top;   /* Max offset + 1 */
+static uint    host_buffer;    /* One page of host buffer */
+static uint    host_end;       /* end + 1 */
+cpm8260_t      *cpmp;          /* Pointer to comm processor space */
+
+/* We allocate this here because it is used almost exclusively for
+ * the communication processor devices.
+ */
+immap_t                *immr;
+
+void
+m8260_cpm_reset(void)
+{
+       volatile immap_t         *imp;
+       volatile cpm8260_t      *commproc;
+       uint                    vpgaddr;
+
+       immr = imp = (volatile immap_t *)IMAP_ADDR;
+       commproc = &imp->im_cpm;
+
+       /* Reclaim the DP memory for our use.
+       */
+       dp_alloc_base = CPM_DATAONLY_BASE;
+       dp_alloc_top = dp_alloc_base + CPM_DATAONLY_SIZE;
+
+       /* Set the host page for allocation.
+       */
+       host_buffer =
+               (uint) alloc_bootmem_pages(PAGE_SIZE * NUM_CPM_HOST_PAGES);
+       host_end = host_buffer + (PAGE_SIZE * NUM_CPM_HOST_PAGES);
+
+       vpgaddr = host_buffer;
+
+       /* Tell everyone where the comm processor resides.
+       */
+       cpmp = (cpm8260_t *)commproc;
+}
+
+/* Allocate some memory from the dual ported ram.  We may want to
+ * enforce alignment restrictions, but right now everyone is a good
+ * citizen.
+ */
+uint
+m8260_cpm_dpalloc(uint size)
+{
+       uint    retloc;
+
+       if ((dp_alloc_base + size) >= dp_alloc_top)
+               return(CPM_DP_NOSPACE);
+
+       retloc = dp_alloc_base;
+       dp_alloc_base += size;
+
+       return(retloc);
+}
+
+/* We also own one page of host buffer space for the allocation of
+ * UART "fifos" and the like.
+ */
+uint
+m8260_cpm_hostalloc(uint size)
+{
+       uint    retloc;
+
+       if ((host_buffer + size) >= host_end)
+               return(0);
+
+       retloc = host_buffer;
+       host_buffer += size;
+
+       return(retloc);
+}
+
+/* Set a baud rate generator.  This needs lots of work.  There are
+ * eight BRGs, which can be connected to the CPM channels or output
+ * as clocks.  The BRGs are in two different block of internal
+ * memory mapped space.
+ * The baud rate clock is the system clock divided by something.
+ * It was set up long ago during the initial boot phase and is
+ * is given to us.
+ * Baud rate clocks are zero-based in the driver code (as that maps
+ * to port numbers).  Documentation uses 1-based numbering.
+ */
+#define BRG_INT_CLK    (((bd_t *)__res)->bi_brgfreq * 1000000)
+#define BRG_UART_CLK   (BRG_INT_CLK/16)
+
+/* This function is used by UARTS, or anything else that uses a 16x
+ * oversampled clock.
+ */
+void
+m8260_cpm_setbrg(uint brg, uint rate)
+{
+       volatile uint   *bp;
+
+       /* This is good enough to get SMCs running.....
+       */
+       if (brg < 4) {
+               bp = (uint *)&immr->im_brgc1;
+       }
+       else {
+               bp = (uint *)&immr->im_brgc5;
+               brg -= 4;
+       }
+       bp += brg;
+       *bp = ((BRG_UART_CLK / rate) << 1) | CPM_BRG_EN;
+}
+
+/* This function is used to set high speed synchronous baud rate
+ * clocks.
+ */
+void
+m8260_cpm_fastbrg(uint brg, uint rate, int div16)
+{
+       volatile uint   *bp;
+
+       /* This is good enough to get SMCs running.....
+       */
+       if (brg < 4) {
+               bp = (uint *)&immr->im_brgc1;
+       }
+       else {
+               bp = (uint *)&immr->im_brgc5;
+               brg -= 4;
+       }
+       bp += brg;
+       *bp = ((BRG_INT_CLK / rate) << 1) | CPM_BRG_EN;
+       if (div16)
+               *bp |= CPM_BRG_DIV16;
+}
diff --git a/arch/ppc/8260_io/enet.c b/arch/ppc/8260_io/enet.c
new file mode 100644 (file)
index 0000000..d2009fa
--- /dev/null
@@ -0,0 +1,857 @@
+/*
+ * Ethernet driver for Motorola MPC8260.
+ * Copyright (c) 1999 Dan Malek (dmalek@jlc.net)
+ * Copyright (c) 2000 MontaVista Software Inc. (source@mvista.com)
+ *     2.3.99 Updates
+ *
+ * I copied this from the 8xx CPM Ethernet driver, so follow the
+ * credits back through that.
+ *
+ * This version of the driver is somewhat selectable for the different
+ * processor/board combinations.  It works for the boards I know about
+ * now, and should be easily modified to include others.  Some of the
+ * configuration information is contained in "commproc.h" and the
+ * remainder is here.
+ *
+ * Buffer descriptors are kept in the CPM dual port RAM, and the frame
+ * buffers are in the host memory.
+ *
+ * Right now, I am very watseful with the buffers.  I allocate memory
+ * pages and then divide them into 2K frame buffers.  This way I know I
+ * have buffers large enough to hold one frame within one buffer descriptor.
+ * Once I get this working, I will use 64 or 128 byte CPM buffers, which
+ * will be much more memory efficient and will easily handle lots of
+ * small packets.
+ *
+ */
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/string.h>
+#include <linux/ptrace.h>
+#include <linux/errno.h>
+#include <linux/ioport.h>
+#include <linux/malloc.h>
+#include <linux/interrupt.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/spinlock.h>
+
+#include <asm/immap_8260.h>
+#include <asm/pgtable.h>
+#include <asm/mpc8260.h>
+#include <asm/bitops.h>
+#include <asm/uaccess.h>
+#include <asm/cpm_8260.h>
+#include <asm/irq.h>
+
+/*
+ *                             Theory of Operation
+ *
+ * The MPC8260 CPM performs the Ethernet processing on an SCC.  It can use
+ * an aribtrary number of buffers on byte boundaries, but must have at
+ * least two receive buffers to prevent constant overrun conditions.
+ *
+ * The buffer descriptors are allocated from the CPM dual port memory
+ * with the data buffers allocated from host memory, just like all other
+ * serial communication protocols.  The host memory buffers are allocated
+ * from the free page pool, and then divided into smaller receive and
+ * transmit buffers.  The size of the buffers should be a power of two,
+ * since that nicely divides the page.  This creates a ring buffer
+ * structure similar to the LANCE and other controllers.
+ *
+ * Like the LANCE driver:
+ * The driver runs as two independent, single-threaded flows of control.  One
+ * is the send-packet routine, which enforces single-threaded use by the
+ * cep->tx_busy flag.  The other thread is the interrupt handler, which is
+ * single threaded by the hardware and other software.
+ */
+
+/* The transmitter timeout
+ */
+#define TX_TIMEOUT     (2*HZ)
+
+/* The number of Tx and Rx buffers.  These are allocated from the page
+ * pool.  The code may assume these are power of two, so it is best
+ * to keep them that size.
+ * We don't need to allocate pages for the transmitter.  We just use
+ * the skbuffer directly.
+ */
+#define CPM_ENET_RX_PAGES      4
+#define CPM_ENET_RX_FRSIZE     2048
+#define CPM_ENET_RX_FRPPG      (PAGE_SIZE / CPM_ENET_RX_FRSIZE)
+#define RX_RING_SIZE           (CPM_ENET_RX_FRPPG * CPM_ENET_RX_PAGES)
+#define TX_RING_SIZE           8       /* Must be power of two */
+#define TX_RING_MOD_MASK       7       /*   for this to work */
+
+/* The CPM stores dest/src/type, data, and checksum for receive packets.
+ */
+#define PKT_MAXBUF_SIZE                1518
+#define PKT_MINBUF_SIZE                64
+#define PKT_MAXBLR_SIZE                1520
+
+/* The CPM buffer descriptors track the ring buffers.  The rx_bd_base and
+ * tx_bd_base always point to the base of the buffer descriptors.  The
+ * cur_rx and cur_tx point to the currently available buffer.
+ * The dirty_tx tracks the current buffer that is being sent by the
+ * controller.  The cur_tx and dirty_tx are equal under both completely
+ * empty and completely full conditions.  The empty/ready indicator in
+ * the buffer descriptor determines the actual condition.
+ */
+struct scc_enet_private {
+       /* The saved address of a sent-in-place packet/buffer, for skfree(). */
+       struct  sk_buff* tx_skbuff[TX_RING_SIZE];
+       ushort  skb_cur;
+       ushort  skb_dirty;
+
+       /* CPM dual port RAM relative addresses.
+       */
+       cbd_t   *rx_bd_base;            /* Address of Rx and Tx buffers. */
+       cbd_t   *tx_bd_base;
+       cbd_t   *cur_rx, *cur_tx;               /* The next free ring entry */
+       cbd_t   *dirty_tx;      /* The ring entries to be free()ed. */
+       scc_t   *sccp;
+       struct  net_device_stats stats;
+       uint    tx_full;
+       spinlock_t lock;
+};
+
+static int scc_enet_open(struct net_device *dev);
+static int scc_enet_start_xmit(struct sk_buff *skb, struct net_device *dev);
+static int scc_enet_rx(struct net_device *dev);
+static void scc_enet_interrupt(int irq, void * dev_id, struct pt_regs * regs);
+static int scc_enet_close(struct net_device *dev);
+static struct net_device_stats *scc_enet_get_stats(struct net_device *dev);
+static void set_multicast_list(struct net_device *dev);
+
+/* These will be configurable for the SCC choice.
+*/
+#define CPM_ENET_BLOCK CPM_CR_SCC1_SBLOCK
+#define CPM_ENET_PAGE  CPM_CR_SCC1_PAGE
+#define PROFF_ENET     PROFF_SCC1
+#define SCC_ENET       0
+#define SIU_INT_ENET   SIU_INT_SCC1
+
+/* These are both board and SCC dependent....
+*/
+#define PD_ENET_RXD    ((uint)0x00000001)
+#define PD_ENET_TXD    ((uint)0x00000002)
+#define PD_ENET_TENA   ((uint)0x00000004)
+#define PC_ENET_RENA   ((uint)0x00020000)
+#define PC_ENET_CLSN   ((uint)0x00000004)
+#define PC_ENET_TXCLK  ((uint)0x00000800)
+#define PC_ENET_RXCLK  ((uint)0x00000400)
+#define CMX_CLK_ROUTE  ((uint)0x25000000)
+#define CMX_CLK_MASK   ((uint)0xff000000)
+
+/* Specific to a board.
+*/
+#define PC_EST8260_ENET_LOOPBACK       ((uint)0x80000000)
+#define PC_EST8260_ENET_SQE            ((uint)0x40000000)
+#define PC_EST8260_ENET_NOTFD          ((uint)0x20000000)
+
+static int
+scc_enet_open(struct net_device *dev)
+{
+
+       /* I should reset the ring buffers here, but I don't yet know
+        * a simple way to do that.
+        */
+       netif_start_queue(dev);
+       return 0;                                       /* Always succeed */
+}
+
+static int
+scc_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+       struct scc_enet_private *cep = (struct scc_enet_private *)dev->priv;
+       volatile cbd_t  *bdp;
+
+
+       /* Fill in a Tx ring entry */
+       bdp = cep->cur_tx;
+
+#ifndef final_version
+       if (bdp->cbd_sc & BD_ENET_TX_READY) {
+               /* Ooops.  All transmit buffers are full.  Bail out.
+                * This should not happen, since cep->tx_busy should be set.
+                */
+               printk("%s: tx queue full!.\n", dev->name);
+               return 1;
+       }
+#endif
+
+       /* Clear all of the status flags.
+        */
+       bdp->cbd_sc &= ~BD_ENET_TX_STATS;
+
+       /* If the frame is short, tell CPM to pad it.
+       */
+       if (skb->len <= ETH_ZLEN)
+               bdp->cbd_sc |= BD_ENET_TX_PAD;
+       else
+               bdp->cbd_sc &= ~BD_ENET_TX_PAD;
+
+       /* Set buffer length and buffer pointer.
+       */
+       bdp->cbd_datlen = skb->len;
+       bdp->cbd_bufaddr = __pa(skb->data);
+
+       /* Save skb pointer.
+       */
+       cep->tx_skbuff[cep->skb_cur] = skb;
+
+       cep->stats.tx_bytes += skb->len;
+       cep->skb_cur = (cep->skb_cur+1) & TX_RING_MOD_MASK;
+       
+       /* Push the data cache so the CPM does not get stale memory
+        * data.
+        */
+       flush_dcache_range((unsigned long)(skb->data),
+                                       (unsigned long)(skb->data + skb->len));
+
+       spin_lock_irq(&cep->lock);
+
+       /* Send it on its way.  Tell CPM its ready, interrupt when done,
+        * its the last BD of the frame, and to put the CRC on the end.
+        */
+       bdp->cbd_sc |= (BD_ENET_TX_READY | BD_ENET_TX_INTR | BD_ENET_TX_LAST | BD_ENET_TX_TC);
+
+       dev->trans_start = jiffies;
+
+       /* If this was the last BD in the ring, start at the beginning again.
+       */
+       if (bdp->cbd_sc & BD_ENET_TX_WRAP)
+               bdp = cep->tx_bd_base;
+       else
+               bdp++;
+
+       if (bdp->cbd_sc & BD_ENET_TX_READY)
+               netif_stop_queue(dev);
+
+       cep->cur_tx = (cbd_t *)bdp;
+
+       spin_unlock_irq(&cep->lock);
+
+       return 0;
+}
+
+static void
+scc_enet_timeout(struct net_device *dev)
+{
+       struct scc_enet_private *cep = (struct scc_enet_private *)dev->priv;
+
+       printk("%s: transmit timed out.\n", dev->name);
+       cep->stats.tx_errors++;
+#ifndef final_version
+       {
+               int     i;
+               cbd_t   *bdp;
+               printk(" Ring data dump: cur_tx %p%s cur_rx %p.\n",
+                      cep->cur_tx, cep->tx_full ? " (full)" : "",
+                      cep->cur_rx);
+               bdp = cep->tx_bd_base;
+               for (i = 0 ; i < TX_RING_SIZE; i++, bdp++)
+                       printk("%04x %04x %08x\n",
+                              bdp->cbd_sc,
+                              bdp->cbd_datlen,
+                              bdp->cbd_bufaddr);
+               bdp = cep->rx_bd_base;
+               for (i = 0 ; i < RX_RING_SIZE; i++, bdp++)
+                       printk("%04x %04x %08x\n",
+                              bdp->cbd_sc,
+                              bdp->cbd_datlen,
+                              bdp->cbd_bufaddr);
+       }
+#endif
+       if (!cep->tx_full)
+               netif_wake_queue(dev);
+}
+
+/* The interrupt handler.
+ * This is called from the CPM handler, not the MPC core interrupt.
+ */
+static void
+scc_enet_interrupt(int irq, void * dev_id, struct pt_regs * regs)
+{
+       struct  net_device *dev = dev_id;
+       volatile struct scc_enet_private *cep;
+       volatile cbd_t  *bdp;
+       ushort  int_events;
+       int     must_restart;
+
+       cep = (struct scc_enet_private *)dev->priv;
+
+       /* Get the interrupt events that caused us to be here.
+       */
+       int_events = cep->sccp->scc_scce;
+       cep->sccp->scc_scce = int_events;
+       must_restart = 0;
+
+       /* Handle receive event in its own function.
+       */
+       if (int_events & SCCE_ENET_RXF)
+               scc_enet_rx(dev_id);
+
+       /* Check for a transmit error.  The manual is a little unclear
+        * about this, so the debug code until I get it figured out.  It
+        * appears that if TXE is set, then TXB is not set.  However,
+        * if carrier sense is lost during frame transmission, the TXE
+        * bit is set, "and continues the buffer transmission normally."
+        * I don't know if "normally" implies TXB is set when the buffer
+        * descriptor is closed.....trial and error :-).
+        */
+
+       /* Transmit OK, or non-fatal error.  Update the buffer descriptors.
+       */
+       if (int_events & (SCCE_ENET_TXE | SCCE_ENET_TXB)) {
+           spin_lock(&cep->lock);
+           bdp = cep->dirty_tx;
+           while ((bdp->cbd_sc&BD_ENET_TX_READY)==0) {
+               if ((bdp==cep->cur_tx) && (cep->tx_full == 0))
+                   break;
+
+               if (bdp->cbd_sc & BD_ENET_TX_HB)        /* No heartbeat */
+                       cep->stats.tx_heartbeat_errors++;
+               if (bdp->cbd_sc & BD_ENET_TX_LC)        /* Late collision */
+                       cep->stats.tx_window_errors++;
+               if (bdp->cbd_sc & BD_ENET_TX_RL)        /* Retrans limit */
+                       cep->stats.tx_aborted_errors++;
+               if (bdp->cbd_sc & BD_ENET_TX_UN)        /* Underrun */
+                       cep->stats.tx_fifo_errors++;
+               if (bdp->cbd_sc & BD_ENET_TX_CSL)       /* Carrier lost */
+                       cep->stats.tx_carrier_errors++;
+
+
+               /* No heartbeat or Lost carrier are not really bad errors.
+                * The others require a restart transmit command.
+                */
+               if (bdp->cbd_sc &
+                   (BD_ENET_TX_LC | BD_ENET_TX_RL | BD_ENET_TX_UN)) {
+                       must_restart = 1;
+                       cep->stats.tx_errors++;
+               }
+
+               cep->stats.tx_packets++;
+
+               /* Deferred means some collisions occurred during transmit,
+                * but we eventually sent the packet OK.
+                */
+               if (bdp->cbd_sc & BD_ENET_TX_DEF)
+                       cep->stats.collisions++;
+
+               /* Free the sk buffer associated with this last transmit.
+               */
+               dev_kfree_skb_irq(cep->tx_skbuff[cep->skb_dirty]);
+               cep->skb_dirty = (cep->skb_dirty + 1) & TX_RING_MOD_MASK;
+
+               /* Update pointer to next buffer descriptor to be transmitted.
+               */
+               if (bdp->cbd_sc & BD_ENET_TX_WRAP)
+                       bdp = cep->tx_bd_base;
+               else
+                       bdp++;
+
+               /* I don't know if we can be held off from processing these
+                * interrupts for more than one frame time.  I really hope
+                * not.  In such a case, we would now want to check the
+                * currently available BD (cur_tx) and determine if any
+                * buffers between the dirty_tx and cur_tx have also been
+                * sent.  We would want to process anything in between that
+                * does not have BD_ENET_TX_READY set.
+                */
+
+               /* Since we have freed up a buffer, the ring is no longer
+                * full.
+                */
+               if (cep->tx_full) {
+                       if (netif_queue_stopped(dev)) {
+                               netif_wake_queue(dev);
+                       }
+               }
+
+               cep->dirty_tx = (cbd_t *)bdp;
+           }
+
+           if (must_restart) {
+               volatile cpm8260_t *cp;
+
+               /* Some transmit errors cause the transmitter to shut
+                * down.  We now issue a restart transmit.  Since the
+                * errors close the BD and update the pointers, the restart
+                * _should_ pick up without having to reset any of our
+                * pointers either.
+                */
+               cp = cpmp;
+               cp->cp_cpcr =
+                   mk_cr_cmd(CPM_ENET_PAGE, CPM_ENET_BLOCK, 0,
+                                       CPM_CR_RESTART_TX) | CPM_CR_FLG;
+               while (cp->cp_cpcr & CPM_CR_FLG);
+           }
+           spin_unlock(&cep->lock);
+       }
+
+       /* Check for receive busy, i.e. packets coming but no place to
+        * put them.  This "can't happen" because the receive interrupt
+        * is tossing previous frames.
+        */
+       if (int_events & SCCE_ENET_BSY) {
+               cep->stats.rx_dropped++;
+               printk("SCC ENET: BSY can't happen.\n");
+       }
+
+       return;
+}
+
+/* During a receive, the cur_rx points to the current incoming buffer.
+ * When we update through the ring, if the next incoming buffer has
+ * not been given to the system, we just set the empty indicator,
+ * effectively tossing the packet.
+ */
+static int
+scc_enet_rx(struct net_device *dev)
+{
+       struct  scc_enet_private *cep;
+       volatile cbd_t  *bdp;
+       struct  sk_buff *skb;
+       ushort  pkt_len;
+
+       cep = (struct scc_enet_private *)dev->priv;
+
+       /* First, grab all of the stats for the incoming packet.
+        * These get messed up if we get called due to a busy condition.
+        */
+       bdp = cep->cur_rx;
+
+for (;;) {
+       if (bdp->cbd_sc & BD_ENET_RX_EMPTY)
+               break;
+               
+#ifndef final_version
+       /* Since we have allocated space to hold a complete frame, both
+        * the first and last indicators should be set.
+        */
+       if ((bdp->cbd_sc & (BD_ENET_RX_FIRST | BD_ENET_RX_LAST)) !=
+               (BD_ENET_RX_FIRST | BD_ENET_RX_LAST))
+                       printk("CPM ENET: rcv is not first+last\n");
+#endif
+
+       /* Frame too long or too short.
+       */
+       if (bdp->cbd_sc & (BD_ENET_RX_LG | BD_ENET_RX_SH))
+               cep->stats.rx_length_errors++;
+       if (bdp->cbd_sc & BD_ENET_RX_NO)        /* Frame alignment */
+               cep->stats.rx_frame_errors++;
+       if (bdp->cbd_sc & BD_ENET_RX_CR)        /* CRC Error */
+               cep->stats.rx_crc_errors++;
+       if (bdp->cbd_sc & BD_ENET_RX_OV)        /* FIFO overrun */
+               cep->stats.rx_crc_errors++;
+
+       /* Report late collisions as a frame error.
+        * On this error, the BD is closed, but we don't know what we
+        * have in the buffer.  So, just drop this frame on the floor.
+        */
+       if (bdp->cbd_sc & BD_ENET_RX_CL) {
+               cep->stats.rx_frame_errors++;
+       }
+       else {
+
+               /* Process the incoming frame.
+               */
+               cep->stats.rx_packets++;
+               pkt_len = bdp->cbd_datlen;
+               cep->stats.rx_bytes += pkt_len;
+
+               /* This does 16 byte alignment, much more than we need.
+               */
+               skb = dev_alloc_skb(pkt_len);
+
+               if (skb == NULL) {
+                       printk("%s: Memory squeeze, dropping packet.\n", dev->name);
+                       cep->stats.rx_dropped++;
+               }
+               else {
+                       skb->dev = dev;
+                       skb_put(skb,pkt_len);   /* Make room */
+                       eth_copy_and_sum(skb,
+                               (unsigned char *)__va(bdp->cbd_bufaddr),
+                               pkt_len, 0);
+                       skb->protocol=eth_type_trans(skb,dev);
+                       netif_rx(skb);
+               }
+       }
+
+       /* Clear the status flags for this buffer.
+       */
+       bdp->cbd_sc &= ~BD_ENET_RX_STATS;
+
+       /* Mark the buffer empty.
+       */
+       bdp->cbd_sc |= BD_ENET_RX_EMPTY;
+
+       /* Update BD pointer to next entry.
+       */
+       if (bdp->cbd_sc & BD_ENET_RX_WRAP)
+               bdp = cep->rx_bd_base;
+       else
+               bdp++;
+
+   }
+       cep->cur_rx = (cbd_t *)bdp;
+
+       return 0;
+}
+
+static int
+scc_enet_close(struct net_device *dev)
+{
+       /* Don't know what to do yet.
+       */
+       netif_stop_queue(dev);
+
+       return 0;
+}
+
+static struct net_device_stats *scc_enet_get_stats(struct net_device *dev)
+{
+       struct scc_enet_private *cep = (struct scc_enet_private *)dev->priv;
+
+       return &cep->stats;
+}
+
+/* Set or clear the multicast filter for this adaptor.
+ * Skeleton taken from sunlance driver.
+ * The CPM Ethernet implementation allows Multicast as well as individual
+ * MAC address filtering.  Some of the drivers check to make sure it is
+ * a group multicast address, and discard those that are not.  I guess I
+ * will do the same for now, but just remove the test if you want
+ * individual filtering as well (do the upper net layers want or support
+ * this kind of feature?).
+ */
+
+static void set_multicast_list(struct net_device *dev)
+{
+       struct  scc_enet_private *cep;
+       struct  dev_mc_list *dmi;
+       u_char  *mcptr, *tdptr;
+       volatile scc_enet_t *ep;
+       int     i, j;
+       cep = (struct scc_enet_private *)dev->priv;
+
+       /* Get pointer to SCC area in parameter RAM.
+       */
+       ep = (scc_enet_t *)dev->base_addr;
+
+       if (dev->flags&IFF_PROMISC) {
+         
+               /* Log any net taps. */
+               printk("%s: Promiscuous mode enabled.\n", dev->name);
+               cep->sccp->scc_pmsr |= SCC_PMSR_PRO;
+       } else {
+
+               cep->sccp->scc_pmsr &= ~SCC_PMSR_PRO;
+
+               if (dev->flags & IFF_ALLMULTI) {
+                       /* Catch all multicast addresses, so set the
+                        * filter to all 1's.
+                        */
+                       ep->sen_gaddr1 = 0xffff;
+                       ep->sen_gaddr2 = 0xffff;
+                       ep->sen_gaddr3 = 0xffff;
+                       ep->sen_gaddr4 = 0xffff;
+               }
+               else {
+                       /* Clear filter and add the addresses in the list.
+                       */
+                       ep->sen_gaddr1 = 0;
+                       ep->sen_gaddr2 = 0;
+                       ep->sen_gaddr3 = 0;
+                       ep->sen_gaddr4 = 0;
+
+                       dmi = dev->mc_list;
+
+                       for (i=0; i<dev->mc_count; i++) {
+                               
+                               /* Only support group multicast for now.
+                               */
+                               if (!(dmi->dmi_addr[0] & 1))
+                                       continue;
+
+                               /* The address in dmi_addr is LSB first,
+                                * and taddr is MSB first.  We have to
+                                * copy bytes MSB first from dmi_addr.
+                                */
+                               mcptr = (u_char *)dmi->dmi_addr + 5;
+                               tdptr = (u_char *)&ep->sen_taddrh;
+                               for (j=0; j<6; j++)
+                                       *tdptr++ = *mcptr--;
+
+                               /* Ask CPM to run CRC and set bit in
+                                * filter mask.
+                                */
+                               cpmp->cp_cpcr = mk_cr_cmd(CPM_ENET_PAGE,
+                                               CPM_ENET_BLOCK, 0,
+                                               CPM_CR_SET_GADDR) | CPM_CR_FLG;
+                               /* this delay is necessary here -- Cort */
+                               udelay(10);
+                               while (cpmp->cp_cpcr & CPM_CR_FLG);
+                       }
+               }
+       }
+}
+
+/* Initialize the CPM Ethernet on SCC.
+ */
+int __init scc_enet_init(void)
+{
+       struct net_device *dev;
+       struct scc_enet_private *cep;
+       int i, j;
+       unsigned char   *eap;
+       unsigned long   mem_addr;
+       bd_t            *bd;
+       volatile        cbd_t           *bdp;
+       volatile        cpm8260_t       *cp;
+       volatile        scc_t           *sccp;
+       volatile        scc_enet_t      *ep;
+       volatile        immap_t         *immap;
+       volatile        iop8260_t       *io;
+
+       cp = cpmp;      /* Get pointer to Communication Processor */
+
+       immap = (immap_t *)IMAP_ADDR;   /* and to internal registers */
+       io = &immap->im_ioport;
+
+       bd = (bd_t *)__res;
+
+       /* Allocate some private information.
+       */
+       cep = (struct scc_enet_private *)kmalloc(sizeof(*cep), GFP_KERNEL);
+       __clear_user(cep,sizeof(*cep));
+       spin_lock_init(&cep->lock);
+
+       /* Create an Ethernet device instance.
+       */
+       dev = init_etherdev(0, 0);
+
+       /* Get pointer to SCC area in parameter RAM.
+       */
+       ep = (scc_enet_t *)(&immap->im_dprambase[PROFF_ENET]);
+
+       /* And another to the SCC register area.
+       */
+       sccp = (volatile scc_t *)(&immap->im_scc[SCC_ENET]);
+       cep->sccp = (scc_t *)sccp;              /* Keep the pointer handy */
+
+       /* Disable receive and transmit in case someone left it running.
+       */
+       sccp->scc_gsmrl &= ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT);
+
+       /* Configure port C and D pins for SCC Ethernet.  This
+        * won't work for all SCC possibilities....it will be
+        * board/port specific.
+        */
+       io->iop_pparc |=
+               (PC_ENET_RENA | PC_ENET_CLSN | PC_ENET_TXCLK | PC_ENET_RXCLK);
+       io->iop_pdirc &=
+               ~(PC_ENET_RENA | PC_ENET_CLSN | PC_ENET_TXCLK | PC_ENET_RXCLK);
+       io->iop_psorc &= 
+               ~(PC_ENET_RENA | PC_ENET_TXCLK | PC_ENET_RXCLK);
+       io->iop_psorc |= PC_ENET_CLSN;
+
+       io->iop_ppard |= (PD_ENET_RXD | PD_ENET_TXD | PD_ENET_TENA);
+       io->iop_pdird |= (PD_ENET_TXD | PD_ENET_TENA);
+       io->iop_pdird &= ~PD_ENET_RXD;
+       io->iop_psord |= PD_ENET_TXD;
+       io->iop_psord &= ~(PD_ENET_RXD | PD_ENET_TENA);
+
+       /* Configure Serial Interface clock routing.
+        * First, clear all SCC bits to zero, then set the ones we want.
+        */
+       immap->im_cpmux.cmx_scr &= ~CMX_CLK_MASK;
+       immap->im_cpmux.cmx_scr |= CMX_CLK_ROUTE;
+
+       /* Allocate space for the buffer descriptors in the DP ram.
+        * These are relative offsets in the DP ram address space.
+        * Initialize base addresses for the buffer descriptors.
+        */
+       i = m8260_cpm_dpalloc(sizeof(cbd_t) * RX_RING_SIZE);
+       ep->sen_genscc.scc_rbase = i;
+       cep->rx_bd_base = (cbd_t *)&immap->im_dprambase[i];
+
+       i = m8260_cpm_dpalloc(sizeof(cbd_t) * TX_RING_SIZE);
+       ep->sen_genscc.scc_tbase = i;
+       cep->tx_bd_base = (cbd_t *)&immap->im_dprambase[i];
+
+       cep->dirty_tx = cep->cur_tx = cep->tx_bd_base;
+       cep->cur_rx = cep->rx_bd_base;
+
+       ep->sen_genscc.scc_rfcr = SCC_EB;
+       ep->sen_genscc.scc_tfcr = SCC_EB;
+
+       /* Set maximum bytes per receive buffer.
+        * This appears to be an Ethernet frame size, not the buffer
+        * fragment size.  It must be a multiple of four.
+        */
+       ep->sen_genscc.scc_mrblr = PKT_MAXBLR_SIZE;
+
+       /* Set CRC preset and mask.
+       */
+       ep->sen_cpres = 0xffffffff;
+       ep->sen_cmask = 0xdebb20e3;
+
+       ep->sen_crcec = 0;      /* CRC Error counter */
+       ep->sen_alec = 0;       /* alignment error counter */
+       ep->sen_disfc = 0;      /* discard frame counter */
+
+       ep->sen_pads = 0x8888;  /* Tx short frame pad character */
+       ep->sen_retlim = 15;    /* Retry limit threshold */
+
+       ep->sen_maxflr = PKT_MAXBUF_SIZE;   /* maximum frame length register */
+       ep->sen_minflr = PKT_MINBUF_SIZE;  /* minimum frame length register */
+
+       ep->sen_maxd1 = PKT_MAXBLR_SIZE;        /* maximum DMA1 length */
+       ep->sen_maxd2 = PKT_MAXBLR_SIZE;        /* maximum DMA2 length */
+
+       /* Clear hash tables.
+       */
+       ep->sen_gaddr1 = 0;
+       ep->sen_gaddr2 = 0;
+       ep->sen_gaddr3 = 0;
+       ep->sen_gaddr4 = 0;
+       ep->sen_iaddr1 = 0;
+       ep->sen_iaddr2 = 0;
+       ep->sen_iaddr3 = 0;
+       ep->sen_iaddr4 = 0;
+
+       /* Set Ethernet station address.
+        *
+        * This is supplied in the board information structure, so we
+        * copy that into the controller.
+        */
+       eap = (unsigned char *)&(ep->sen_paddrh);
+       for (i=5; i>=0; i--)
+               *eap++ = dev->dev_addr[i] = bd->bi_enetaddr[i];
+
+       ep->sen_pper = 0;       /* 'cause the book says so */
+       ep->sen_taddrl = 0;     /* temp address (LSB) */
+       ep->sen_taddrm = 0;
+       ep->sen_taddrh = 0;     /* temp address (MSB) */
+
+       /* Now allocate the host memory pages and initialize the
+        * buffer descriptors.
+        */
+       bdp = cep->tx_bd_base;
+       for (i=0; i<TX_RING_SIZE; i++) {
+
+               /* Initialize the BD for every fragment in the page.
+               */
+               bdp->cbd_sc = 0;
+               bdp->cbd_bufaddr = 0;
+               bdp++;
+       }
+
+       /* Set the last buffer to wrap.
+       */
+       bdp--;
+       bdp->cbd_sc |= BD_SC_WRAP;
+
+       bdp = cep->rx_bd_base;
+       for (i=0; i<CPM_ENET_RX_PAGES; i++) {
+
+               /* Allocate a page.
+               */
+               mem_addr = __get_free_page(GFP_KERNEL);
+
+               /* Initialize the BD for every fragment in the page.
+               */
+               for (j=0; j<CPM_ENET_RX_FRPPG; j++) {
+                       bdp->cbd_sc = BD_ENET_RX_EMPTY | BD_ENET_RX_INTR;
+                       bdp->cbd_bufaddr = __pa(mem_addr);
+                       mem_addr += CPM_ENET_RX_FRSIZE;
+                       bdp++;
+               }
+       }
+
+       /* Set the last buffer to wrap.
+       */
+       bdp--;
+       bdp->cbd_sc |= BD_SC_WRAP;
+
+       /* Let's re-initialize the channel now.  We have to do it later
+        * than the manual describes because we have just now finished
+        * the BD initialization.
+        */
+       cpmp->cp_cpcr = mk_cr_cmd(CPM_ENET_PAGE, CPM_ENET_BLOCK, 0,
+                       CPM_CR_INIT_TRX) | CPM_CR_FLG;
+       while (cp->cp_cpcr & CPM_CR_FLG);
+
+       cep->skb_cur = cep->skb_dirty = 0;
+
+       sccp->scc_scce = 0xffff;        /* Clear any pending events */
+
+       /* Enable interrupts for transmit error, complete frame
+        * received, and any transmit buffer we have also set the
+        * interrupt flag.
+        */
+       sccp->scc_sccm = (SCCE_ENET_TXE | SCCE_ENET_RXF | SCCE_ENET_TXB);
+
+       /* Install our interrupt handler.
+       */
+       request_8xxirq(SIU_INT_ENET, scc_enet_interrupt, 0, "enet", dev);
+
+       /* Set GSMR_H to enable all normal operating modes.
+        * Set GSMR_L to enable Ethernet to MC68160.
+        */
+       sccp->scc_gsmrh = 0;
+       sccp->scc_gsmrl = (SCC_GSMRL_TCI | SCC_GSMRL_TPL_48 | SCC_GSMRL_TPP_10 | SCC_GSMRL_MODE_ENET);
+
+       /* Set sync/delimiters.
+       */
+       sccp->scc_dsr = 0xd555;
+
+       /* Set processing mode.  Use Ethernet CRC, catch broadcast, and
+        * start frame search 22 bit times after RENA.
+        */
+       sccp->scc_pmsr = (SCC_PMSR_ENCRC | SCC_PMSR_NIB22);
+
+       /* It is now OK to enable the Ethernet transmitter.
+        * Unfortunately, there are board implementation differences here.
+        */
+       io->iop_pparc &= ~(PC_EST8260_ENET_LOOPBACK |
+                               PC_EST8260_ENET_SQE | PC_EST8260_ENET_NOTFD);
+       io->iop_psorc &= ~(PC_EST8260_ENET_LOOPBACK |
+                               PC_EST8260_ENET_SQE | PC_EST8260_ENET_NOTFD);
+       io->iop_pdirc |= (PC_EST8260_ENET_LOOPBACK |
+                               PC_EST8260_ENET_SQE | PC_EST8260_ENET_NOTFD);
+       io->iop_pdatc &= ~(PC_EST8260_ENET_LOOPBACK | PC_EST8260_ENET_SQE);
+       io->iop_pdatc |= PC_EST8260_ENET_NOTFD;
+
+       dev->base_addr = (unsigned long)ep;
+       dev->priv = cep;
+
+       /* The CPM Ethernet specific entries in the device structure. */
+       dev->open = scc_enet_open;
+       dev->hard_start_xmit = scc_enet_start_xmit;
+       dev->tx_timeout = scc_enet_timeout;
+       dev->watchdog_timeo = TX_TIMEOUT;
+       dev->stop = scc_enet_close;
+       dev->get_stats = scc_enet_get_stats;
+       dev->set_multicast_list = set_multicast_list;
+
+       /* And last, enable the transmit and receive processing.
+       */
+       sccp->scc_gsmrl |= (SCC_GSMRL_ENR | SCC_GSMRL_ENT);
+
+       printk("%s: SCC ENET Version 0.1, ", dev->name);
+       for (i=0; i<5; i++)
+               printk("%02x:", dev->dev_addr[i]);
+       printk("%02x\n", dev->dev_addr[5]);
+
+       return 0;
+}
+
diff --git a/arch/ppc/8260_io/uart.c b/arch/ppc/8260_io/uart.c
new file mode 100644 (file)
index 0000000..9e93bcd
--- /dev/null
@@ -0,0 +1,2772 @@
+/*
+ *  UART driver for MPC8260 CPM SCC or SMC
+ *  Copyright (c) 1999 Dan Malek (dmalek@jlc.net)
+ *  Copyright (c) 2000 MontaVista Software, Inc. (source@mvista.com)
+ *     2.3.99 updates
+ *
+ * I used the 8xx uart.c driver as the framework for this driver.
+ * The original code was written for the EST8260 board.  I tried to make
+ * it generic, but there may be some assumptions in the structures that
+ * have to be fixed later.
+ *
+ * The 8xx and 8260 are similar, but not identical.  Over time we
+ * could probably merge these two drivers.
+ * To save porting time, I did not bother to change any object names
+ * that are not accessed outside of this file.
+ * It still needs lots of work........When it was easy, I included code
+ * to support the SCCs.
+ * Only the SCCs support modem control, so that is not complete either.
+ *
+ * This module exports the following rs232 io functions:
+ *
+ *     int rs_8xx_init(void);
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/timer.h>
+#include <linux/interrupt.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+#include <linux/serial.h>
+#include <linux/serialP.h>
+#include <linux/major.h>
+#include <linux/string.h>
+#include <linux/fcntl.h>
+#include <linux/ptrace.h>
+#include <linux/mm.h>
+#include <linux/malloc.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <asm/uaccess.h>
+#include <asm/immap_8260.h>
+#include <asm/mpc8260.h>
+#include <asm/cpm_8260.h>
+#include <asm/irq.h>
+
+#ifdef CONFIG_SERIAL_CONSOLE
+#include <linux/console.h>
+
+/* this defines the index into rs_table for the port to use
+*/
+#ifndef CONFIG_SERIAL_CONSOLE_PORT
+#define CONFIG_SERIAL_CONSOLE_PORT     0
+#endif
+#endif
+
+#define TX_WAKEUP      ASYNC_SHARE_IRQ
+
+static char *serial_name = "CPM UART driver";
+static char *serial_version = "0.01";
+
+static DECLARE_TASK_QUEUE(tq_serial);
+
+static struct tty_driver serial_driver, callout_driver;
+static int serial_refcount;
+static int serial_console_setup(struct console *co, char *options);
+
+/*
+ * Serial driver configuration section.  Here are the various options:
+ */
+#define SERIAL_PARANOIA_CHECK
+#define CONFIG_SERIAL_NOPAUSE_IO
+#define SERIAL_DO_RESTART
+
+/* Set of debugging defines */
+
+#undef SERIAL_DEBUG_INTR
+#undef SERIAL_DEBUG_OPEN
+#undef SERIAL_DEBUG_FLOW
+#undef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
+
+#define _INLINE_ inline
+  
+#define DBG_CNT(s)
+
+/* We overload some of the items in the data structure to meet our
+ * needs.  For example, the port address is the CPM parameter ram
+ * offset for the SCC or SMC.  The maximum number of ports is 4 SCCs and
+ * 2 SMCs.  The "hub6" field is used to indicate the channel number, with
+ * 0 and 1 indicating the SMCs and 2, 3, 4, and 5 are the SCCs.
+ * Since these ports are so versatile, I don't yet have a strategy for
+ * their management.  For example, SCC1 is used for Ethernet.  Right
+ * now, just don't put them in the table.  Of course, right now I just
+ * want the SMC to work as a uart :-)..
+ * The "type" field is currently set to 0, for PORT_UNKNOWN.  It is
+ * not currently used.  I should probably use it to indicate the port
+ * type of CMS or SCC.
+ * The SMCs do not support any modem control signals.
+ */
+#define smc_scc_num    hub6
+
+/* SMC2 is sometimes used for low performance TDM interfaces.  Define
+ * this as 1 if you want SMC2 as a serial port UART managed by this driver.
+ * Define this as 0 if you wish to use SMC2 for something else.
+ */
+#define USE_SMC2 1
+
+/* Define SCC to ttySx mapping.
+*/
+#define SCC_NUM_BASE   (USE_SMC2 + 1)  /* SCC base tty "number" */
+
+/* Define which SCC is the first one to use for a serial port.  These
+ * are 0-based numbers, i.e. this assumes the first SCC (SCC1) is used
+ * for Ethernet, and the first available SCC for serial UART is SCC2.
+ * NOTE:  IF YOU CHANGE THIS, you have to change the PROFF_xxx and
+ * interrupt vectors in the table below to match.
+ */
+#define SCC_IDX_BASE   1       /* table index */
+
+static struct serial_state rs_table[] = {
+       /* UART CLK   PORT          IRQ      FLAGS  NUM   */
+       { 0,     0, PROFF_SMC1, SIU_INT_SMC1,   0,    0 },    /* SMC1 ttyS0 */
+#if USE_SMC2
+       { 0,     0, PROFF_SMC2, SIU_INT_SMC2,   0,    1 },    /* SMC2 ttyS1 */
+#endif
+       { 0,     0, PROFF_SCC2, SIU_INT_SCC2,   0, SCC_NUM_BASE},    /* SCC2 ttyS2 */
+       { 0,     0, PROFF_SCC3, SIU_INT_SCC3,   0, SCC_NUM_BASE + 1},    /* SCC3 ttyS3 */
+};
+
+#define NR_PORTS       (sizeof(rs_table)/sizeof(struct serial_state))
+
+static struct tty_struct *serial_table[NR_PORTS];
+static struct termios *serial_termios[NR_PORTS];
+static struct termios *serial_termios_locked[NR_PORTS];
+
+/* The number of buffer descriptors and their sizes.
+*/
+#define RX_NUM_FIFO    4
+#define RX_BUF_SIZE    32
+#define TX_NUM_FIFO    4
+#define TX_BUF_SIZE    32
+
+#ifndef MIN
+#define MIN(a,b)       ((a) < (b) ? (a) : (b))
+#endif
+
+/* The async_struct in serial.h does not really give us what we
+ * need, so define our own here.
+ */
+typedef struct serial_info {
+       int                     magic;
+       int                     flags;
+       struct serial_state     *state;
+       struct tty_struct       *tty;
+       int                     read_status_mask;
+       int                     ignore_status_mask;
+       int                     timeout;
+       int                     line;
+       int                     x_char; /* xon/xoff character */
+       int                     close_delay;
+       unsigned short          closing_wait;
+       unsigned short          closing_wait2;
+       unsigned long           event;
+       unsigned long           last_active;
+       int                     blocked_open; /* # of blocked opens */
+       long                    session; /* Session of opening process */
+       long                    pgrp; /* pgrp of opening process */
+       struct tq_struct        tqueue;
+       struct tq_struct        tqueue_hangup;
+       wait_queue_head_t       open_wait;
+       wait_queue_head_t       close_wait;
+
+       /* CPM Buffer Descriptor pointers.
+       */
+       cbd_t                   *rx_bd_base;
+       cbd_t                   *rx_cur;
+       cbd_t                   *tx_bd_base;
+       cbd_t                   *tx_cur;
+} ser_info_t;
+
+static void change_speed(ser_info_t *info);
+static void rs_8xx_wait_until_sent(struct tty_struct *tty, int timeout);
+
+static inline int serial_paranoia_check(ser_info_t *info,
+                                       kdev_t device, const char *routine)
+{
+#ifdef SERIAL_PARANOIA_CHECK
+       static const char *badmagic =
+               "Warning: bad magic number for serial struct (%s) in %s\n";
+       static const char *badinfo =
+               "Warning: null async_struct for (%s) in %s\n";
+
+       if (!info) {
+               printk(badinfo, kdevname(device), routine);
+               return 1;
+       }
+       if (info->magic != SERIAL_MAGIC) {
+               printk(badmagic, kdevname(device), routine);
+               return 1;
+       }
+#endif
+       return 0;
+}
+
+/*
+ * This is used to figure out the divisor speeds and the timeouts,
+ * indexed by the termio value.  The generic CPM functions are responsible
+ * for setting and assigning baud rate generators for us.
+ */
+static int baud_table[] = {
+       0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,
+       9600, 19200, 38400, 57600, 115200, 230400, 460800, 0 };
+
+
+/*
+ * ------------------------------------------------------------
+ * rs_stop() and rs_start()
+ *
+ * This routines are called before setting or resetting tty->stopped.
+ * They enable or disable transmitter interrupts, as necessary.
+ * ------------------------------------------------------------
+ */
+static void rs_8xx_stop(struct tty_struct *tty)
+{
+       ser_info_t *info = (ser_info_t *)tty->driver_data;
+       int     idx;
+       unsigned long flags;
+       volatile scc_t  *sccp;
+       volatile smc_t  *smcp;
+
+       if (serial_paranoia_check(info, tty->device, "rs_stop"))
+               return;
+       
+       save_flags(flags); cli();
+       if ((idx = info->state->smc_scc_num) < SCC_NUM_BASE) {
+               smcp = &immr->im_smc[idx];
+               smcp->smc_smcm &= ~SMCM_TX;
+       }
+       else {
+               sccp = &immr->im_scc[idx - SCC_IDX_BASE];
+               sccp->scc_sccm &= ~UART_SCCM_TX;
+       }
+       restore_flags(flags);
+}
+
+static void rs_8xx_start(struct tty_struct *tty)
+{
+       ser_info_t *info = (ser_info_t *)tty->driver_data;
+       int     idx;
+       unsigned long flags;
+       volatile scc_t  *sccp;
+       volatile smc_t  *smcp;
+
+       if (serial_paranoia_check(info, tty->device, "rs_stop"))
+               return;
+       
+       save_flags(flags); cli();
+       if ((idx = info->state->smc_scc_num) < SCC_NUM_BASE) {
+               smcp = &immr->im_smc[idx];
+               smcp->smc_smcm |= SMCM_TX;
+       }
+       else {
+               sccp = &immr->im_scc[idx - SCC_IDX_BASE];
+               sccp->scc_sccm |= UART_SCCM_TX;
+       }
+       restore_flags(flags);
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * Here starts the interrupt handling routines.  All of the following
+ * subroutines are declared as inline and are folded into
+ * rs_interrupt().  They were separated out for readability's sake.
+ *
+ * Note: rs_interrupt() is a "fast" interrupt, which means that it
+ * runs with interrupts turned off.  People who may want to modify
+ * rs_interrupt() should try to keep the interrupt handler as fast as
+ * possible.  After you are done making modifications, it is not a bad
+ * idea to do:
+ * 
+ * gcc -S -DKERNEL -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer serial.c
+ *
+ * and look at the resulting assemble code in serial.s.
+ *
+ *                             - Ted Ts'o (tytso@mit.edu), 7-Mar-93
+ * -----------------------------------------------------------------------
+ */
+
+/*
+ * This routine is used by the interrupt handler to schedule
+ * processing in the software interrupt portion of the driver.
+ */
+static _INLINE_ void rs_sched_event(ser_info_t *info,
+                                 int event)
+{
+       info->event |= 1 << event;
+       queue_task(&info->tqueue, &tq_serial);
+       mark_bh(SERIAL_BH);
+}
+
+static _INLINE_ void receive_chars(ser_info_t *info)
+{
+       struct tty_struct *tty = info->tty;
+       unsigned char ch, *cp;
+       /*int   ignored = 0;*/
+       int     i;
+       ushort  status;
+       struct  async_icount *icount;
+       volatile cbd_t  *bdp;
+
+       icount = &info->state->icount;
+
+       /* Just loop through the closed BDs and copy the characters into
+        * the buffer.
+        */
+       bdp = info->rx_cur;
+       for (;;) {
+               if (bdp->cbd_sc & BD_SC_EMPTY)  /* If this one is empty */
+                       break;                  /*   we are all done */
+
+               /* The read status mask tell us what we should do with
+                * incoming characters, especially if errors occur.
+                * One special case is the use of BD_SC_EMPTY.  If
+                * this is not set, we are supposed to be ignoring
+                * inputs.  In this case, just mark the buffer empty and
+                * continue.
+               if (!(info->read_status_mask & BD_SC_EMPTY)) {
+                       bdp->cbd_sc |= BD_SC_EMPTY;
+                       bdp->cbd_sc &=
+                               ~(BD_SC_BR | BD_SC_FR | BD_SC_PR | BD_SC_OV);
+
+                       if (bdp->cbd_sc & BD_SC_WRAP)
+                               bdp = info->rx_bd_base;
+                       else
+                               bdp++;
+                       continue;
+               }
+                */
+
+               /* Get the number of characters and the buffer pointer.
+               */
+               i = bdp->cbd_datlen;
+               cp = (unsigned char *)__va(bdp->cbd_bufaddr);
+               status = bdp->cbd_sc;
+
+               /* Check to see if there is room in the tty buffer for
+                * the characters in our BD buffer.  If not, we exit
+                * now, leaving the BD with the characters.  We'll pick
+                * them up again on the next receive interrupt (which could
+                * be a timeout).
+                */
+               if ((tty->flip.count + i) >= TTY_FLIPBUF_SIZE)
+                       break;
+
+               while (i-- > 0) {
+                       ch = *cp++;
+                       *tty->flip.char_buf_ptr = ch;
+                       icount->rx++;
+
+#ifdef SERIAL_DEBUG_INTR
+                       printk("DR%02x:%02x...", ch, *status);
+#endif
+                       *tty->flip.flag_buf_ptr = 0;
+                       if (status & (BD_SC_BR | BD_SC_FR |
+                                      BD_SC_PR | BD_SC_OV)) {
+                               /*
+                                * For statistics only
+                                */
+                               if (status & BD_SC_BR)
+                                       icount->brk++;
+                               else if (status & BD_SC_PR)
+                                       icount->parity++;
+                               else if (status & BD_SC_FR)
+                                       icount->frame++;
+                               if (status & BD_SC_OV)
+                                       icount->overrun++;
+
+                               /*
+                                * Now check to see if character should be
+                                * ignored, and mask off conditions which
+                                * should be ignored.
+                               if (status & info->ignore_status_mask) {
+                                       if (++ignored > 100)
+                                               break;
+                                       continue;
+                               }
+                                */
+                               status &= info->read_status_mask;
+               
+                               if (status & (BD_SC_BR)) {
+#ifdef SERIAL_DEBUG_INTR
+                                       printk("handling break....");
+#endif
+                                       *tty->flip.flag_buf_ptr = TTY_BREAK;
+                                       if (info->flags & ASYNC_SAK)
+                                               do_SAK(tty);
+                               } else if (status & BD_SC_PR)
+                                       *tty->flip.flag_buf_ptr = TTY_PARITY;
+                               else if (status & BD_SC_FR)
+                                       *tty->flip.flag_buf_ptr = TTY_FRAME;
+                               if (status & BD_SC_OV) {
+                                       /*
+                                        * Overrun is special, since it's
+                                        * reported immediately, and doesn't
+                                        * affect the current character
+                                        */
+                                       if (tty->flip.count < TTY_FLIPBUF_SIZE) {
+                                               tty->flip.count++;
+                                               tty->flip.flag_buf_ptr++;
+                                               tty->flip.char_buf_ptr++;
+                                               *tty->flip.flag_buf_ptr =
+                                                               TTY_OVERRUN;
+                                       }
+                               }
+                       }
+                       if (tty->flip.count >= TTY_FLIPBUF_SIZE)
+                               break;
+
+                       tty->flip.flag_buf_ptr++;
+                       tty->flip.char_buf_ptr++;
+                       tty->flip.count++;
+               }
+
+               /* This BD is ready to be used again.  Clear status.
+                * Get next BD.
+                */
+               bdp->cbd_sc |= BD_SC_EMPTY;
+               bdp->cbd_sc &= ~(BD_SC_BR | BD_SC_FR | BD_SC_PR | BD_SC_OV);
+
+               if (bdp->cbd_sc & BD_SC_WRAP)
+                       bdp = info->rx_bd_base;
+               else
+                       bdp++;
+       }
+
+       info->rx_cur = (cbd_t *)bdp;
+
+       queue_task(&tty->flip.tqueue, &tq_timer);
+}
+
+static _INLINE_ void transmit_chars(ser_info_t *info)
+{
+       
+       if (info->flags & TX_WAKEUP) {
+               rs_sched_event(info, RS_EVENT_WRITE_WAKEUP);
+       }
+
+#ifdef SERIAL_DEBUG_INTR
+       printk("THRE...");
+#endif
+}
+
+#ifdef notdef
+       /* I need to do this for the SCCs, so it is left as a reminder.
+       */
+static _INLINE_ void check_modem_status(struct async_struct *info)
+{
+       int     status;
+       struct  async_icount *icount;
+       
+       status = serial_in(info, UART_MSR);
+
+       if (status & UART_MSR_ANY_DELTA) {
+               icount = &info->state->icount;
+               /* update input line counters */
+               if (status & UART_MSR_TERI)
+                       icount->rng++;
+               if (status & UART_MSR_DDSR)
+                       icount->dsr++;
+               if (status & UART_MSR_DDCD) {
+                       icount->dcd++;
+#ifdef CONFIG_HARD_PPS
+                       if ((info->flags & ASYNC_HARDPPS_CD) &&
+                           (status & UART_MSR_DCD))
+                               hardpps();
+#endif
+               }
+               if (status & UART_MSR_DCTS)
+                       icount->cts++;
+               wake_up_interruptible(&info->delta_msr_wait);
+       }
+
+       if ((info->flags & ASYNC_CHECK_CD) && (status & UART_MSR_DDCD)) {
+#if (defined(SERIAL_DEBUG_OPEN) || defined(SERIAL_DEBUG_INTR))
+               printk("ttys%d CD now %s...", info->line,
+                      (status & UART_MSR_DCD) ? "on" : "off");
+#endif         
+               if (status & UART_MSR_DCD)
+                       wake_up_interruptible(&info->open_wait);
+               else if (!((info->flags & ASYNC_CALLOUT_ACTIVE) &&
+                          (info->flags & ASYNC_CALLOUT_NOHUP))) {
+#ifdef SERIAL_DEBUG_OPEN
+                       printk("scheduling hangup...");
+#endif
+                       queue_task(&info->tqueue_hangup,
+                                          &tq_scheduler);
+               }
+       }
+       if (info->flags & ASYNC_CTS_FLOW) {
+               if (info->tty->hw_stopped) {
+                       if (status & UART_MSR_CTS) {
+#if (defined(SERIAL_DEBUG_INTR) || defined(SERIAL_DEBUG_FLOW))
+                               printk("CTS tx start...");
+#endif
+                               info->tty->hw_stopped = 0;
+                               info->IER |= UART_IER_THRI;
+                               serial_out(info, UART_IER, info->IER);
+                               rs_sched_event(info, RS_EVENT_WRITE_WAKEUP);
+                               return;
+                       }
+               } else {
+                       if (!(status & UART_MSR_CTS)) {
+#if (defined(SERIAL_DEBUG_INTR) || defined(SERIAL_DEBUG_FLOW))
+                               printk("CTS tx stop...");
+#endif
+                               info->tty->hw_stopped = 1;
+                               info->IER &= ~UART_IER_THRI;
+                               serial_out(info, UART_IER, info->IER);
+                       }
+               }
+       }
+}
+#endif
+
+/*
+ * This is the serial driver's interrupt routine for a single port
+ */
+static void rs_8xx_interrupt(int irq, void * dev_id, struct pt_regs * regs)
+{
+       u_char  events;
+       int     idx;
+       ser_info_t *info;
+       volatile smc_t  *smcp;
+       volatile scc_t  *sccp;
+       
+       info = (ser_info_t *)dev_id;
+
+       if ((idx = info->state->smc_scc_num) < SCC_NUM_BASE) {
+               smcp = &immr->im_smc[idx];
+               events = smcp->smc_smce;
+               if (events & SMCM_RX)
+                       receive_chars(info);
+               if (events & SMCM_TX)
+                       transmit_chars(info);
+               smcp->smc_smce = events;
+       }
+       else {
+               sccp = &immr->im_scc[idx - SCC_IDX_BASE];
+               events = sccp->scc_scce;
+               if (events & SCCM_RX)
+                       receive_chars(info);
+               if (events & SCCM_TX)
+                       transmit_chars(info);
+               sccp->scc_scce = events;
+       }
+       
+#ifdef SERIAL_DEBUG_INTR
+       printk("rs_interrupt_single(%d, %x)...",
+                                       info->state->smc_scc_num, events);
+#endif
+#ifdef modem_control
+       check_modem_status(info);
+#endif
+       info->last_active = jiffies;
+#ifdef SERIAL_DEBUG_INTR
+       printk("end.\n");
+#endif
+}
+
+
+/*
+ * -------------------------------------------------------------------
+ * Here ends the serial interrupt routines.
+ * -------------------------------------------------------------------
+ */
+
+/*
+ * This routine is used to handle the "bottom half" processing for the
+ * serial driver, known also the "software interrupt" processing.
+ * This processing is done at the kernel interrupt level, after the
+ * rs_interrupt() has returned, BUT WITH INTERRUPTS TURNED ON.  This
+ * is where time-consuming activities which can not be done in the
+ * interrupt driver proper are done; the interrupt driver schedules
+ * them using rs_sched_event(), and they get done here.
+ */
+static void do_serial_bh(void)
+{
+       run_task_queue(&tq_serial);
+}
+
+static void do_softint(void *private_)
+{
+       ser_info_t      *info = (ser_info_t *) private_;
+       struct tty_struct       *tty;
+       
+       tty = info->tty;
+       if (!tty)
+               return;
+
+       if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &info->event)) {
+               if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
+                   tty->ldisc.write_wakeup)
+                       (tty->ldisc.write_wakeup)(tty);
+               wake_up_interruptible(&tty->write_wait);
+       }
+}
+
+/*
+ * This routine is called from the scheduler tqueue when the interrupt
+ * routine has signalled that a hangup has occurred.  The path of
+ * hangup processing is:
+ *
+ *     serial interrupt routine -> (scheduler tqueue) ->
+ *     do_serial_hangup() -> tty->hangup() -> rs_hangup()
+ * 
+ */
+static void do_serial_hangup(void *private_)
+{
+       struct async_struct     *info = (struct async_struct *) private_;
+       struct tty_struct       *tty;
+       
+       tty = info->tty;
+       if (!tty)
+               return;
+
+       tty_hangup(tty);
+}
+
+/*static void rs_8xx_timer(void)
+{
+       printk("rs_8xx_timer\n");
+}*/
+
+
+static int startup(ser_info_t *info)
+{
+       unsigned long flags;
+       int     retval=0;
+       int     idx;
+       struct serial_state *state= info->state;
+       volatile smc_t          *smcp;
+       volatile scc_t          *sccp;
+       volatile smc_uart_t     *up;
+       volatile scc_uart_t     *scup;
+
+
+       save_flags(flags); cli();
+
+       if (info->flags & ASYNC_INITIALIZED) {
+               goto errout;
+       }
+
+#ifdef maybe
+       if (!state->port || !state->type) {
+               if (info->tty)
+                       set_bit(TTY_IO_ERROR, &info->tty->flags);
+               goto errout;
+       }
+#endif
+
+#ifdef SERIAL_DEBUG_OPEN
+       printk("starting up ttys%d (irq %d)...", info->line, state->irq);
+#endif
+
+
+#ifdef modem_control
+       info->MCR = 0;
+       if (info->tty->termios->c_cflag & CBAUD)
+               info->MCR = UART_MCR_DTR | UART_MCR_RTS;
+#endif
+       
+       if (info->tty)
+               clear_bit(TTY_IO_ERROR, &info->tty->flags);
+
+       /*
+        * and set the speed of the serial port
+        */
+       change_speed(info);
+       
+       if ((idx = info->state->smc_scc_num) < SCC_NUM_BASE) {
+               smcp = &immr->im_smc[idx];
+
+               /* Enable interrupts and I/O.
+               */
+               smcp->smc_smcm |= (SMCM_RX | SMCM_TX);
+               smcp->smc_smcmr |= (SMCMR_REN | SMCMR_TEN);
+
+               /* We can tune the buffer length and idle characters
+                * to take advantage of the entire incoming buffer size.
+                * If mrblr is something other than 1, maxidl has to be
+                * non-zero or we never get an interrupt.  The maxidl
+                * is the number of character times we wait after reception
+                * of the last character before we decide no more characters
+                * are coming.
+                */
+               up = (smc_uart_t *)&immr->im_dprambase[state->port];
+#if 0
+               up->smc_mrblr = 1;      /* receive buffer length */
+               up->smc_maxidl = 0;     /* wait forever for next char */
+#else
+               up->smc_mrblr = RX_BUF_SIZE;
+               up->smc_maxidl = RX_BUF_SIZE;
+#endif
+               up->smc_brkcr = 1;      /* number of break chars */
+       }
+       else {
+               sccp = &immr->im_scc[idx - SCC_IDX_BASE];
+               scup = (scc_uart_t *)&immr->im_dprambase[state->port];
+#if 0
+               scup->scc_genscc.scc_mrblr = 1; /* receive buffer length */
+               scup->scc_maxidl = 0;   /* wait forever for next char */
+#else
+               scup->scc_genscc.scc_mrblr = RX_BUF_SIZE;
+               scup->scc_maxidl = RX_BUF_SIZE;
+#endif
+
+               sccp->scc_sccm |= (UART_SCCM_TX | UART_SCCM_RX);
+               sccp->scc_gsmrl |= (SCC_GSMRL_ENR | SCC_GSMRL_ENT);
+       }
+
+       info->flags |= ASYNC_INITIALIZED;
+       restore_flags(flags);
+       return 0;
+       
+errout:
+       restore_flags(flags);
+       return retval;
+}
+
+/*
+ * This routine will shutdown a serial port; interrupts are disabled, and
+ * DTR is dropped if the hangup on close termio flag is on.
+ */
+static void shutdown(ser_info_t * info)
+{
+       unsigned long   flags;
+       struct serial_state *state;
+       int             idx;
+       volatile smc_t  *smcp;
+       volatile scc_t  *sccp;
+
+       if (!(info->flags & ASYNC_INITIALIZED))
+               return;
+
+       state = info->state;
+
+#ifdef SERIAL_DEBUG_OPEN
+       printk("Shutting down serial port %d (irq %d)....", info->line,
+              state->irq);
+#endif
+       
+       save_flags(flags); cli(); /* Disable interrupts */
+
+       if ((idx = info->state->smc_scc_num) < SCC_NUM_BASE) {
+               smcp = &immr->im_smc[idx];
+
+               /* Disable interrupts and I/O.
+               */
+               smcp->smc_smcm &= ~(SMCM_RX | SMCM_TX);
+#ifdef CONFIG_SERIAL_CONSOLE
+               /* We can't disable the transmitter if this is the
+                * system console.
+                */
+               if (idx != CONFIG_SERIAL_CONSOLE_PORT)
+#endif
+                       smcp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN);
+       }
+       else {
+               sccp = &immr->im_scc[idx - SCC_IDX_BASE];
+               sccp->scc_sccm &= ~(UART_SCCM_TX | UART_SCCM_RX);
+               sccp->scc_gsmrl &= ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT);
+       }
+       
+       if (info->tty)
+               set_bit(TTY_IO_ERROR, &info->tty->flags);
+
+       info->flags &= ~ASYNC_INITIALIZED;
+       restore_flags(flags);
+}
+
+/*
+ * This routine is called to set the UART divisor registers to match
+ * the specified baud rate for a serial port.
+ */
+static void change_speed(ser_info_t *info)
+{
+       int     baud_rate;
+       unsigned cflag, cval, scval, prev_mode;
+       int     i, bits, sbits, idx;
+       unsigned long   flags;
+       volatile smc_t  *smcp;
+       volatile scc_t  *sccp;
+
+       if (!info->tty || !info->tty->termios)
+               return;
+       cflag = info->tty->termios->c_cflag;
+
+       /* Character length programmed into the mode register is the
+        * sum of: 1 start bit, number of data bits, 0 or 1 parity bit,
+        * 1 or 2 stop bits, minus 1.
+        * The value 'bits' counts this for us.
+        */
+       cval = 0;
+       scval = 0;
+
+       /* byte size and parity */
+       switch (cflag & CSIZE) {
+             case CS5: bits = 5; break;
+             case CS6: bits = 6; break;
+             case CS7: bits = 7; break;
+             case CS8: bits = 8; break;
+             /* Never happens, but GCC is too dumb to figure it out */
+             default:  bits = 8; break;
+       }
+       sbits = bits - 5;
+
+       if (cflag & CSTOPB) {
+               cval |= SMCMR_SL;       /* Two stops */
+               scval |= SCU_PMSR_SL;
+               bits++;
+       }
+       if (cflag & PARENB) {
+               cval |= SMCMR_PEN;
+               scval |= SCU_PMSR_PEN;
+               bits++;
+       }
+       if (!(cflag & PARODD)) {
+               cval |= SMCMR_PM_EVEN;
+               scval |= (SCU_PMSR_REVP | SCU_PMSR_TEVP);
+       }
+
+       /* Determine divisor based on baud rate */
+       i = cflag & CBAUD;
+       if (i >= (sizeof(baud_table)/sizeof(int)))
+               baud_rate = 9600;
+       else
+               baud_rate = baud_table[i];
+
+       info->timeout = (TX_BUF_SIZE*HZ*bits);
+       info->timeout += HZ/50;         /* Add .02 seconds of slop */
+
+#ifdef modem_control
+       /* CTS flow control flag and modem status interrupts */
+       info->IER &= ~UART_IER_MSI;
+       if (info->flags & ASYNC_HARDPPS_CD)
+               info->IER |= UART_IER_MSI;
+       if (cflag & CRTSCTS) {
+               info->flags |= ASYNC_CTS_FLOW;
+               info->IER |= UART_IER_MSI;
+       } else
+               info->flags &= ~ASYNC_CTS_FLOW;
+       if (cflag & CLOCAL)
+               info->flags &= ~ASYNC_CHECK_CD;
+       else {
+               info->flags |= ASYNC_CHECK_CD;
+               info->IER |= UART_IER_MSI;
+       }
+       serial_out(info, UART_IER, info->IER);
+#endif
+
+       /*
+        * Set up parity check flag
+        */
+#define RELEVANT_IFLAG(iflag) (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK))
+
+       info->read_status_mask = (BD_SC_EMPTY | BD_SC_OV);
+       if (I_INPCK(info->tty))
+               info->read_status_mask |= BD_SC_FR | BD_SC_PR;
+       if (I_BRKINT(info->tty) || I_PARMRK(info->tty))
+               info->read_status_mask |= BD_SC_BR;
+       
+       /*
+        * Characters to ignore
+        */
+       info->ignore_status_mask = 0;
+       if (I_IGNPAR(info->tty))
+               info->ignore_status_mask |= BD_SC_PR | BD_SC_FR;
+       if (I_IGNBRK(info->tty)) {
+               info->ignore_status_mask |= BD_SC_BR;
+               /*
+                * If we're ignore parity and break indicators, ignore 
+                * overruns too.  (For real raw support).
+                */
+               if (I_IGNPAR(info->tty))
+                       info->ignore_status_mask |= BD_SC_OV;
+       }
+       /*
+        * !!! ignore all characters if CREAD is not set
+        */
+       if ((cflag & CREAD) == 0)
+               info->read_status_mask &= ~BD_SC_EMPTY;
+       save_flags(flags); cli();
+
+       /* Start bit has not been added (so don't, because we would just
+        * subtract it later), and we need to add one for the number of
+        * stops bits (there is always at least one).
+        */
+       bits++;
+       if ((idx = info->state->smc_scc_num) < SCC_NUM_BASE) {
+               smcp = &immr->im_smc[idx];
+
+               /* Set the mode register.  We want to keep a copy of the
+                * enables, because we want to put them back if they were
+                * present.
+                */
+               prev_mode = smcp->smc_smcmr;
+               smcp->smc_smcmr = smcr_mk_clen(bits) | cval |  SMCMR_SM_UART;
+               smcp->smc_smcmr |= (prev_mode & (SMCMR_REN | SMCMR_TEN));
+       }
+       else {
+               sccp = &immr->im_scc[idx - SCC_IDX_BASE];
+               sccp->scc_pmsr = (sbits << 12) | scval;
+       }
+
+       m8260_cpm_setbrg(info->state->smc_scc_num, baud_rate);
+
+       restore_flags(flags);
+}
+
+static void rs_8xx_put_char(struct tty_struct *tty, unsigned char ch)
+{
+       ser_info_t *info = (ser_info_t *)tty->driver_data;
+       volatile cbd_t  *bdp;
+
+       if (serial_paranoia_check(info, tty->device, "rs_put_char"))
+               return;
+
+       if (!tty)
+               return;
+
+       bdp = info->tx_cur;
+       while (bdp->cbd_sc & BD_SC_READY);
+
+       *((char *)__va(bdp->cbd_bufaddr)) = ch;
+       bdp->cbd_datlen = 1;
+       bdp->cbd_sc |= BD_SC_READY;
+
+       /* Get next BD.
+       */
+       if (bdp->cbd_sc & BD_SC_WRAP)
+               bdp = info->tx_bd_base;
+       else
+               bdp++;
+
+       info->tx_cur = (cbd_t *)bdp;
+
+}
+
+static int rs_8xx_write(struct tty_struct * tty, int from_user,
+                   const unsigned char *buf, int count)
+{
+       int     c, ret = 0;
+       ser_info_t *info = (ser_info_t *)tty->driver_data;
+       volatile cbd_t *bdp;
+
+       if (serial_paranoia_check(info, tty->device, "rs_write"))
+               return 0;
+
+       if (!tty) 
+               return 0;
+
+       bdp = info->tx_cur;
+
+       while (1) {
+               c = MIN(count, TX_BUF_SIZE);
+
+               if (c <= 0)
+                       break;
+
+               if (bdp->cbd_sc & BD_SC_READY) {
+                       info->flags |= TX_WAKEUP;
+                       break;
+               }
+
+               if (from_user) {
+                       if (c !=
+                           copy_from_user(__va(bdp->cbd_bufaddr), buf, c)) {
+                               if (!ret)
+                                       ret = -EFAULT;
+                               break;
+                       }
+               } else {
+                       memcpy(__va(bdp->cbd_bufaddr), buf, c);
+               }
+
+               bdp->cbd_datlen = c;
+               bdp->cbd_sc |= BD_SC_READY;
+
+               buf += c;
+               count -= c;
+               ret += c;
+
+               /* Get next BD.
+               */
+               if (bdp->cbd_sc & BD_SC_WRAP)
+                       bdp = info->tx_bd_base;
+               else
+                       bdp++;
+               info->tx_cur = (cbd_t *)bdp;
+       }
+       return ret;
+}
+
+static int rs_8xx_write_room(struct tty_struct *tty)
+{
+       ser_info_t *info = (ser_info_t *)tty->driver_data;
+       int     ret;
+
+       if (serial_paranoia_check(info, tty->device, "rs_write_room"))
+               return 0;
+
+       if ((info->tx_cur->cbd_sc & BD_SC_READY) == 0) {
+               info->flags &= ~TX_WAKEUP;
+               ret = TX_BUF_SIZE;
+       }
+       else {
+               info->flags |= TX_WAKEUP;
+               ret = 0;
+       }
+       return ret;
+}
+
+/* I could track this with transmit counters....maybe later.
+*/
+static int rs_8xx_chars_in_buffer(struct tty_struct *tty)
+{
+       ser_info_t *info = (ser_info_t *)tty->driver_data;
+                               
+       if (serial_paranoia_check(info, tty->device, "rs_chars_in_buffer"))
+               return 0;
+       return 0;
+}
+
+static void rs_8xx_flush_buffer(struct tty_struct *tty)
+{
+       ser_info_t *info = (ser_info_t *)tty->driver_data;
+                               
+       if (serial_paranoia_check(info, tty->device, "rs_flush_buffer"))
+               return;
+
+       /* There is nothing to "flush", whatever we gave the CPM
+        * is on its way out.
+        */
+       wake_up_interruptible(&tty->write_wait);
+       if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
+           tty->ldisc.write_wakeup)
+               (tty->ldisc.write_wakeup)(tty);
+       info->flags &= ~TX_WAKEUP;
+}
+
+/*
+ * This function is used to send a high-priority XON/XOFF character to
+ * the device
+ */
+static void rs_8xx_send_xchar(struct tty_struct *tty, char ch)
+{
+       volatile cbd_t  *bdp;
+
+       ser_info_t *info = (ser_info_t *)tty->driver_data;
+
+       if (serial_paranoia_check(info, tty->device, "rs_send_char"))
+               return;
+
+       bdp = info->tx_cur;
+       while (bdp->cbd_sc & BD_SC_READY);
+
+       *((char *)__va(bdp->cbd_bufaddr)) = ch;
+       bdp->cbd_datlen = 1;
+       bdp->cbd_sc |= BD_SC_READY;
+
+       /* Get next BD.
+       */
+       if (bdp->cbd_sc & BD_SC_WRAP)
+               bdp = info->tx_bd_base;
+       else
+               bdp++;
+
+       info->tx_cur = (cbd_t *)bdp;
+}
+
+/*
+ * ------------------------------------------------------------
+ * rs_throttle()
+ * 
+ * This routine is called by the upper-layer tty layer to signal that
+ * incoming characters should be throttled.
+ * ------------------------------------------------------------
+ */
+static void rs_8xx_throttle(struct tty_struct * tty)
+{
+       ser_info_t *info = (ser_info_t *)tty->driver_data;
+#ifdef SERIAL_DEBUG_THROTTLE
+       char    buf[64];
+       
+       printk("throttle %s: %d....\n", _tty_name(tty, buf),
+              tty->ldisc.chars_in_buffer(tty));
+#endif
+
+       if (serial_paranoia_check(info, tty->device, "rs_throttle"))
+               return;
+       
+       if (I_IXOFF(tty))
+               rs_8xx_send_xchar(tty, STOP_CHAR(tty));
+
+#ifdef modem_control
+       if (tty->termios->c_cflag & CRTSCTS)
+               info->MCR &= ~UART_MCR_RTS;
+
+       cli();
+       serial_out(info, UART_MCR, info->MCR);
+       sti();
+#endif
+}
+
+static void rs_8xx_unthrottle(struct tty_struct * tty)
+{
+       ser_info_t *info = (ser_info_t *)tty->driver_data;
+#ifdef SERIAL_DEBUG_THROTTLE
+       char    buf[64];
+       
+       printk("unthrottle %s: %d....\n", _tty_name(tty, buf),
+              tty->ldisc.chars_in_buffer(tty));
+#endif
+
+       if (serial_paranoia_check(info, tty->device, "rs_unthrottle"))
+               return;
+       
+       if (I_IXOFF(tty)) {
+               if (info->x_char)
+                       info->x_char = 0;
+               else
+                       rs_8xx_send_xchar(tty, START_CHAR(tty));
+       }
+#ifdef modem_control
+       if (tty->termios->c_cflag & CRTSCTS)
+               info->MCR |= UART_MCR_RTS;
+       cli();
+       serial_out(info, UART_MCR, info->MCR);
+       sti();
+#endif
+}
+
+/*
+ * ------------------------------------------------------------
+ * rs_ioctl() and friends
+ * ------------------------------------------------------------
+ */
+
+#ifdef maybe
+/*
+ * get_lsr_info - get line status register info
+ *
+ * Purpose: Let user call ioctl() to get info when the UART physically
+ *         is emptied.  On bus types like RS485, the transmitter must
+ *         release the bus after transmitting. This must be done when
+ *         the transmit shift register is empty, not be done when the
+ *         transmit holding register is empty.  This functionality
+ *         allows an RS485 driver to be written in user space. 
+ */
+static int get_lsr_info(struct async_struct * info, unsigned int *value)
+{
+       unsigned char status;
+       unsigned int result;
+
+       cli();
+       status = serial_in(info, UART_LSR);
+       sti();
+       result = ((status & UART_LSR_TEMT) ? TIOCSER_TEMT : 0);
+       return put_user(result,value);
+}
+#endif
+
+static int get_modem_info(ser_info_t *info, unsigned int *value)
+{
+       unsigned int result = 0;
+#ifdef modem_control
+       unsigned char control, status;
+
+       control = info->MCR;
+       cli();
+       status = serial_in(info, UART_MSR);
+       sti();
+       result =  ((control & UART_MCR_RTS) ? TIOCM_RTS : 0)
+               | ((control & UART_MCR_DTR) ? TIOCM_DTR : 0)
+#ifdef TIOCM_OUT1
+               | ((control & UART_MCR_OUT1) ? TIOCM_OUT1 : 0)
+               | ((control & UART_MCR_OUT2) ? TIOCM_OUT2 : 0)
+#endif
+               | ((status  & UART_MSR_DCD) ? TIOCM_CAR : 0)
+               | ((status  & UART_MSR_RI) ? TIOCM_RNG : 0)
+               | ((status  & UART_MSR_DSR) ? TIOCM_DSR : 0)
+               | ((status  & UART_MSR_CTS) ? TIOCM_CTS : 0);
+#endif
+       return put_user(result,value);
+}
+
+static int set_modem_info(ser_info_t *info, unsigned int cmd,
+                         unsigned int *value)
+{
+       int error;
+       unsigned int arg;
+
+       error = get_user(arg, value);
+       if (error)
+               return error;
+#ifdef modem_control
+       switch (cmd) {
+       case TIOCMBIS: 
+               if (arg & TIOCM_RTS)
+                       info->MCR |= UART_MCR_RTS;
+               if (arg & TIOCM_DTR)
+                       info->MCR |= UART_MCR_DTR;
+#ifdef TIOCM_OUT1
+               if (arg & TIOCM_OUT1)
+                       info->MCR |= UART_MCR_OUT1;
+               if (arg & TIOCM_OUT2)
+                       info->MCR |= UART_MCR_OUT2;
+#endif
+               break;
+       case TIOCMBIC:
+               if (arg & TIOCM_RTS)
+                       info->MCR &= ~UART_MCR_RTS;
+               if (arg & TIOCM_DTR)
+                       info->MCR &= ~UART_MCR_DTR;
+#ifdef TIOCM_OUT1
+               if (arg & TIOCM_OUT1)
+                       info->MCR &= ~UART_MCR_OUT1;
+               if (arg & TIOCM_OUT2)
+                       info->MCR &= ~UART_MCR_OUT2;
+#endif
+               break;
+       case TIOCMSET:
+               info->MCR = ((info->MCR & ~(UART_MCR_RTS |
+#ifdef TIOCM_OUT1
+                                           UART_MCR_OUT1 |
+                                           UART_MCR_OUT2 |
+#endif
+                                           UART_MCR_DTR))
+                            | ((arg & TIOCM_RTS) ? UART_MCR_RTS : 0)
+#ifdef TIOCM_OUT1
+                            | ((arg & TIOCM_OUT1) ? UART_MCR_OUT1 : 0)
+                            | ((arg & TIOCM_OUT2) ? UART_MCR_OUT2 : 0)
+#endif
+                            | ((arg & TIOCM_DTR) ? UART_MCR_DTR : 0));
+               break;
+       default:
+               return -EINVAL;
+       }
+       cli();
+       serial_out(info, UART_MCR, info->MCR);
+       sti();
+#endif
+       return 0;
+}
+
+/* Sending a break is a two step process on the SMC/SCC.  It is accomplished
+ * by sending a STOP TRANSMIT command followed by a RESTART TRANSMIT
+ * command.  We take advantage of the begin/end functions to make this
+ * happen.
+ */
+static void begin_break(ser_info_t *info)
+{
+       volatile cpm8260_t *cp;
+       uint    page, sblock;
+       ushort  num;
+
+       cp = cpmp;
+
+       if ((num = info->state->smc_scc_num) < SCC_NUM_BASE) {
+               if (num == 0) {
+                       page = CPM_CR_SMC1_PAGE;
+                       sblock = CPM_CR_SMC1_SBLOCK;
+               }
+               else {
+                       page = CPM_CR_SMC2_PAGE;
+                       sblock = CPM_CR_SMC2_SBLOCK;
+               }
+       }
+       else {
+               num -= SCC_NUM_BASE;
+               switch (num) {
+               case 0:
+                       page = CPM_CR_SCC1_PAGE;
+                       sblock = CPM_CR_SCC1_SBLOCK;
+                       break;
+               case 1:
+                       page = CPM_CR_SCC2_PAGE;
+                       sblock = CPM_CR_SCC2_SBLOCK;
+                       break;
+               case 2:
+                       page = CPM_CR_SCC3_PAGE;
+                       sblock = CPM_CR_SCC3_SBLOCK;
+                       break;
+               case 3:
+                       page = CPM_CR_SCC4_PAGE;
+                       sblock = CPM_CR_SCC4_SBLOCK;
+                       break;
+               default: return;
+               }
+       }
+       cp->cp_cpcr = mk_cr_cmd(page, sblock, 0, CPM_CR_STOP_TX) | CPM_CR_FLG;
+       while (cp->cp_cpcr & CPM_CR_FLG);
+}
+
+static void end_break(ser_info_t *info)
+{
+       volatile cpm8260_t *cp;
+       uint    page, sblock;
+       ushort  num;
+
+       cp = cpmp;
+
+       if ((num = info->state->smc_scc_num) < SCC_NUM_BASE) {
+               if (num == 0) {
+                       page = CPM_CR_SMC1_PAGE;
+                       sblock = CPM_CR_SMC1_SBLOCK;
+               }
+               else {
+                       page = CPM_CR_SMC2_PAGE;
+                       sblock = CPM_CR_SMC2_SBLOCK;
+               }
+       }
+       else {
+               num -= SCC_NUM_BASE;
+               switch (num) {
+               case 0:
+                       page = CPM_CR_SCC1_PAGE;
+                       sblock = CPM_CR_SCC1_SBLOCK;
+                       break;
+               case 1:
+                       page = CPM_CR_SCC2_PAGE;
+                       sblock = CPM_CR_SCC2_SBLOCK;
+                       break;
+               case 2:
+                       page = CPM_CR_SCC3_PAGE;
+                       sblock = CPM_CR_SCC3_SBLOCK;
+                       break;
+               case 3:
+                       page = CPM_CR_SCC4_PAGE;
+                       sblock = CPM_CR_SCC4_SBLOCK;
+                       break;
+               default: return;
+               }
+       }
+       cp->cp_cpcr = mk_cr_cmd(page, sblock, 0, CPM_CR_RESTART_TX) | CPM_CR_FLG;
+       while (cp->cp_cpcr & CPM_CR_FLG);
+}
+
+/*
+ * This routine sends a break character out the serial port.
+ */
+static void send_break(ser_info_t *info, int duration)
+{
+       current->state = TASK_INTERRUPTIBLE;
+#ifdef SERIAL_DEBUG_SEND_BREAK
+       printk("rs_send_break(%d) jiff=%lu...", duration, jiffies);
+#endif
+       begin_break(info);
+       schedule_timeout(duration);
+       end_break(info);
+#ifdef SERIAL_DEBUG_SEND_BREAK
+       printk("done jiffies=%lu\n", jiffies);
+#endif
+}
+
+
+static int rs_8xx_ioctl(struct tty_struct *tty, struct file * file,
+                   unsigned int cmd, unsigned long arg)
+{
+       int error;
+       ser_info_t *info = (ser_info_t *)tty->driver_data;
+       int retval;
+       struct async_icount cnow;       /* kernel counter temps */
+       struct serial_icounter_struct *p_cuser; /* user space */
+
+       if (serial_paranoia_check(info, tty->device, "rs_ioctl"))
+               return -ENODEV;
+
+       if ((cmd != TIOCMIWAIT) && (cmd != TIOCGICOUNT)) {
+               if (tty->flags & (1 << TTY_IO_ERROR))
+                   return -EIO;
+       }
+       
+       switch (cmd) {
+               case TCSBRK:    /* SVID version: non-zero arg --> no break */
+                       retval = tty_check_change(tty);
+                       if (retval)
+                               return retval;
+                       tty_wait_until_sent(tty, 0);
+                       if (signal_pending(current))
+                               return -EINTR;
+                       if (!arg) {
+                               send_break(info, HZ/4); /* 1/4 second */
+                               if (signal_pending(current))
+                                       return -EINTR;
+                       }
+                       return 0;
+               case TCSBRKP:   /* support for POSIX tcsendbreak() */
+                       retval = tty_check_change(tty);
+                       if (retval)
+                               return retval;
+                       tty_wait_until_sent(tty, 0);
+                       if (signal_pending(current))
+                               return -EINTR;
+                       send_break(info, arg ? arg*(HZ/10) : HZ/4);
+                       if (signal_pending(current))
+                               return -EINTR;
+                       return 0;
+               case TIOCSBRK:
+                       retval = tty_check_change(tty);
+                       if (retval)
+                               return retval;
+                       tty_wait_until_sent(tty, 0);
+                       begin_break(info);
+                       return 0;
+               case TIOCCBRK:
+                       retval = tty_check_change(tty);
+                       if (retval)
+                               return retval;
+                       end_break(info);
+                       return 0;
+               case TIOCGSOFTCAR:
+                       return put_user(C_CLOCAL(tty) ? 1 : 0, (int *) arg);
+               case TIOCSSOFTCAR:
+                       error = get_user(arg, (unsigned int *) arg);
+                       if (error)
+                               return error;
+                       tty->termios->c_cflag =
+                               ((tty->termios->c_cflag & ~CLOCAL) |
+                                (arg ? CLOCAL : 0));
+                       return 0;
+               case TIOCMGET:
+                       return get_modem_info(info, (unsigned int *) arg);
+               case TIOCMBIS:
+               case TIOCMBIC:
+               case TIOCMSET:
+                       return set_modem_info(info, cmd, (unsigned int *) arg);
+#ifdef maybe
+               case TIOCSERGETLSR: /* Get line status register */
+                       return get_lsr_info(info, (unsigned int *) arg);
+#endif
+               /*
+                * Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change
+                * - mask passed in arg for lines of interest
+                *   (use |'ed TIOCM_RNG/DSR/CD/CTS for masking)
+                * Caller should use TIOCGICOUNT to see which one it was
+                */
+                case TIOCMIWAIT:
+#ifdef modem_control
+                       cli();
+                       /* note the counters on entry */
+                       cprev = info->state->icount;
+                       sti();
+                       while (1) {
+                               interruptible_sleep_on(&info->delta_msr_wait);
+                               /* see if a signal did it */
+                               if (signal_pending(current))
+                                       return -ERESTARTSYS;
+                               cli();
+                               cnow = info->state->icount; /* atomic copy */
+                               sti();
+                               if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr && 
+                                   cnow.dcd == cprev.dcd && cnow.cts == cprev.cts)
+                                       return -EIO; /* no change => error */
+                               if ( ((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) ||
+                                    ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) ||
+                                    ((arg & TIOCM_CD)  && (cnow.dcd != cprev.dcd)) ||
+                                    ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts)) ) {
+                                       return 0;
+                               }
+                               cprev = cnow;
+                       }
+                       /* NOTREACHED */
+#else
+                       return 0;
+#endif
+
+               /* 
+                * Get counter of input serial line interrupts (DCD,RI,DSR,CTS)
+                * Return: write counters to the user passed counter struct
+                * NB: both 1->0 and 0->1 transitions are counted except for
+                *     RI where only 0->1 is counted.
+                */
+               case TIOCGICOUNT:
+                       cli();
+                       cnow = info->state->icount;
+                       sti();
+                       p_cuser = (struct serial_icounter_struct *) arg;
+                       error = put_user(cnow.cts, &p_cuser->cts);
+                       if (error) return error;
+                       error = put_user(cnow.dsr, &p_cuser->dsr);
+                       if (error) return error;
+                       error = put_user(cnow.rng, &p_cuser->rng);
+                       if (error) return error;
+                       error = put_user(cnow.dcd, &p_cuser->dcd);
+                       if (error) return error;
+                       return 0;
+
+               default:
+                       return -ENOIOCTLCMD;
+               }
+       return 0;
+}
+
+/* FIX UP modem control here someday......
+*/
+static void rs_8xx_set_termios(struct tty_struct *tty, struct termios *old_termios)
+{
+       ser_info_t *info = (ser_info_t *)tty->driver_data;
+
+       if (   (tty->termios->c_cflag == old_termios->c_cflag)
+           && (   RELEVANT_IFLAG(tty->termios->c_iflag) 
+               == RELEVANT_IFLAG(old_termios->c_iflag)))
+         return;
+
+       change_speed(info);
+
+#ifdef modem_control
+       /* Handle transition to B0 status */
+       if ((old_termios->c_cflag & CBAUD) &&
+           !(tty->termios->c_cflag & CBAUD)) {
+               info->MCR &= ~(UART_MCR_DTR|UART_MCR_RTS);
+               cli();
+               serial_out(info, UART_MCR, info->MCR);
+               sti();
+       }
+       
+       /* Handle transition away from B0 status */
+       if (!(old_termios->c_cflag & CBAUD) &&
+           (tty->termios->c_cflag & CBAUD)) {
+               info->MCR |= UART_MCR_DTR;
+               if (!tty->hw_stopped ||
+                   !(tty->termios->c_cflag & CRTSCTS)) {
+                       info->MCR |= UART_MCR_RTS;
+               }
+               cli();
+               serial_out(info, UART_MCR, info->MCR);
+               sti();
+       }
+       
+       /* Handle turning off CRTSCTS */
+       if ((old_termios->c_cflag & CRTSCTS) &&
+           !(tty->termios->c_cflag & CRTSCTS)) {
+               tty->hw_stopped = 0;
+               rs_8xx_start(tty);
+       }
+#endif
+
+#if 0
+       /*
+        * No need to wake up processes in open wait, since they
+        * sample the CLOCAL flag once, and don't recheck it.
+        * XXX  It's not clear whether the current behavior is correct
+        * or not.  Hence, this may change.....
+        */
+       if (!(old_termios->c_cflag & CLOCAL) &&
+           (tty->termios->c_cflag & CLOCAL))
+               wake_up_interruptible(&info->open_wait);
+#endif
+}
+
+/*
+ * ------------------------------------------------------------
+ * rs_close()
+ * 
+ * This routine is called when the serial port gets closed.  First, we
+ * wait for the last remaining data to be sent.  Then, we unlink its
+ * async structure from the interrupt chain if necessary, and we free
+ * that IRQ if nothing is left in the chain.
+ * ------------------------------------------------------------
+ */
+static void rs_8xx_close(struct tty_struct *tty, struct file * filp)
+{
+       ser_info_t *info = (ser_info_t *)tty->driver_data;
+       struct serial_state *state;
+       unsigned long   flags;
+       int             idx;
+       volatile smc_t  *smcp;
+       volatile scc_t  *sccp;
+
+       if (!info || serial_paranoia_check(info, tty->device, "rs_close"))
+               return;
+
+       state = info->state;
+       
+       save_flags(flags); cli();
+       
+       if (tty_hung_up_p(filp)) {
+               DBG_CNT("before DEC-hung");
+               MOD_DEC_USE_COUNT;
+               restore_flags(flags);
+               return;
+       }
+       
+#ifdef SERIAL_DEBUG_OPEN
+       printk("rs_close ttys%d, count = %d\n", info->line, state->count);
+#endif
+       if ((tty->count == 1) && (state->count != 1)) {
+               /*
+                * Uh, oh.  tty->count is 1, which means that the tty
+                * structure will be freed.  state->count should always
+                * be one in these conditions.  If it's greater than
+                * one, we've got real problems, since it means the
+                * serial port won't be shutdown.
+                */
+               printk("rs_close: bad serial port count; tty->count is 1, "
+                      "state->count is %d\n", state->count);
+               state->count = 1;
+       }
+       if (--state->count < 0) {
+               printk("rs_close: bad serial port count for ttys%d: %d\n",
+                      info->line, state->count);
+               state->count = 0;
+       }
+       if (state->count) {
+               DBG_CNT("before DEC-2");
+               MOD_DEC_USE_COUNT;
+               restore_flags(flags);
+               return;
+       }
+       info->flags |= ASYNC_CLOSING;
+       /*
+        * Save the termios structure, since this port may have
+        * separate termios for callout and dialin.
+        */
+       if (info->flags & ASYNC_NORMAL_ACTIVE)
+               info->state->normal_termios = *tty->termios;
+       if (info->flags & ASYNC_CALLOUT_ACTIVE)
+               info->state->callout_termios = *tty->termios;
+       /*
+        * Now we wait for the transmit buffer to clear; and we notify 
+        * the line discipline to only process XON/XOFF characters.
+        */
+       tty->closing = 1;
+       if (info->closing_wait != ASYNC_CLOSING_WAIT_NONE)
+               tty_wait_until_sent(tty, info->closing_wait);
+       /*
+        * At this point we stop accepting input.  To do this, we
+        * disable the receive line status interrupts, and tell the
+        * interrupt driver to stop checking the data ready bit in the
+        * line status register.
+        */
+       info->read_status_mask &= ~BD_SC_EMPTY;
+       if (info->flags & ASYNC_INITIALIZED) {
+               if ((idx = info->state->smc_scc_num) < SCC_NUM_BASE) {
+                       smcp = &immr->im_smc[idx];
+                       smcp->smc_smcm &= ~SMCM_RX;
+                       smcp->smc_smcmr &= ~SMCMR_REN;
+               }
+               else {
+                       sccp = &immr->im_scc[idx - SCC_IDX_BASE];
+                       sccp->scc_sccm &= ~UART_SCCM_RX;
+                       sccp->scc_gsmrl &= ~SCC_GSMRL_ENR;
+               }
+               /*
+                * Before we drop DTR, make sure the UART transmitter
+                * has completely drained; this is especially
+                * important if there is a transmit FIFO!
+                */
+               rs_8xx_wait_until_sent(tty, info->timeout);
+       }
+       shutdown(info);
+       if (tty->driver.flush_buffer)
+               tty->driver.flush_buffer(tty);
+       if (tty->ldisc.flush_buffer)
+               tty->ldisc.flush_buffer(tty);
+       tty->closing = 0;
+       info->event = 0;
+       info->tty = 0;
+       if (info->blocked_open) {
+               if (info->close_delay) {
+                       current->state = TASK_INTERRUPTIBLE;
+                       schedule_timeout(info->close_delay);
+               }
+               wake_up_interruptible(&info->open_wait);
+       }
+       info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE|
+                        ASYNC_CLOSING);
+       wake_up_interruptible(&info->close_wait);
+       MOD_DEC_USE_COUNT;
+       restore_flags(flags);
+}
+
+/*
+ * rs_wait_until_sent() --- wait until the transmitter is empty
+ */
+static void rs_8xx_wait_until_sent(struct tty_struct *tty, int timeout)
+{
+       ser_info_t *info = (ser_info_t *)tty->driver_data;
+       unsigned long orig_jiffies, char_time;
+       /*int lsr;*/
+       volatile cbd_t *bdp;
+       
+       if (serial_paranoia_check(info, tty->device, "rs_wait_until_sent"))
+               return;
+
+#ifdef maybe
+       if (info->state->type == PORT_UNKNOWN)
+               return;
+#endif
+
+       orig_jiffies = jiffies;
+       /*
+        * Set the check interval to be 1/5 of the estimated time to
+        * send a single character, and make it at least 1.  The check
+        * interval should also be less than the timeout.
+        * 
+        * Note: we have to use pretty tight timings here to satisfy
+        * the NIST-PCTS.
+        */
+       char_time = 1;
+       if (timeout)
+               char_time = MIN(char_time, timeout);
+#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
+       printk("In rs_wait_until_sent(%d) check=%lu...", timeout, char_time);
+       printk("jiff=%lu...", jiffies);
+#endif
+
+       /* We go through the loop at least once because we can't tell
+        * exactly when the last character exits the shifter.  There can
+        * be at least two characters waiting to be sent after the buffers
+        * are empty.
+        */
+       do {
+#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
+               printk("lsr = %d (jiff=%lu)...", lsr, jiffies);
+#endif
+               current->state = TASK_INTERRUPTIBLE;
+/*             current->counter = 0;    make us low-priority */
+               schedule_timeout(char_time);
+               if (signal_pending(current))
+                       break;
+               if (timeout && ((orig_jiffies + timeout) < jiffies))
+                       break;
+               bdp = info->tx_cur;
+       } while (bdp->cbd_sc & BD_SC_READY);
+       current->state = TASK_RUNNING;
+#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
+       printk("lsr = %d (jiff=%lu)...done\n", lsr, jiffies);
+#endif
+}
+
+/*
+ * rs_hangup() --- called by tty_hangup() when a hangup is signaled.
+ */
+static void rs_8xx_hangup(struct tty_struct *tty)
+{
+       ser_info_t *info = (ser_info_t *)tty->driver_data;
+       struct serial_state *state = info->state;
+       
+       if (serial_paranoia_check(info, tty->device, "rs_hangup"))
+               return;
+
+       state = info->state;
+       
+       rs_8xx_flush_buffer(tty);
+       shutdown(info);
+       info->event = 0;
+       state->count = 0;
+       info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE);
+       info->tty = 0;
+       wake_up_interruptible(&info->open_wait);
+}
+
+/*
+ * ------------------------------------------------------------
+ * rs_open() and friends
+ * ------------------------------------------------------------
+ */
+static int block_til_ready(struct tty_struct *tty, struct file * filp,
+                          ser_info_t *info)
+{
+#ifdef DO_THIS_LATER
+       DECLARE_WAITQUEUE(wait, current);
+#endif
+       struct serial_state *state = info->state;
+       int             retval;
+       int             do_clocal = 0;
+
+       /*
+        * If the device is in the middle of being closed, then block
+        * until it's done, and then try again.
+        */
+       if (tty_hung_up_p(filp) ||
+           (info->flags & ASYNC_CLOSING)) {
+               if (info->flags & ASYNC_CLOSING)
+                       interruptible_sleep_on(&info->close_wait);
+#ifdef SERIAL_DO_RESTART
+               if (info->flags & ASYNC_HUP_NOTIFY)
+                       return -EAGAIN;
+               else
+                       return -ERESTARTSYS;
+#else
+               return -EAGAIN;
+#endif
+       }
+
+       /*
+        * If this is a callout device, then just make sure the normal
+        * device isn't being used.
+        */
+       if (tty->driver.subtype == SERIAL_TYPE_CALLOUT) {
+               if (info->flags & ASYNC_NORMAL_ACTIVE)
+                       return -EBUSY;
+               if ((info->flags & ASYNC_CALLOUT_ACTIVE) &&
+                   (info->flags & ASYNC_SESSION_LOCKOUT) &&
+                   (info->session != current->session))
+                   return -EBUSY;
+               if ((info->flags & ASYNC_CALLOUT_ACTIVE) &&
+                   (info->flags & ASYNC_PGRP_LOCKOUT) &&
+                   (info->pgrp != current->pgrp))
+                   return -EBUSY;
+               info->flags |= ASYNC_CALLOUT_ACTIVE;
+               return 0;
+       }
+       
+       /*
+        * If non-blocking mode is set, or the port is not enabled,
+        * then make the check up front and then exit.
+        * If this is an SMC port, we don't have modem control to wait
+        * for, so just get out here.
+        */
+       if ((filp->f_flags & O_NONBLOCK) ||
+           (tty->flags & (1 << TTY_IO_ERROR)) ||
+           (info->state->smc_scc_num < SCC_NUM_BASE)) {
+               if (info->flags & ASYNC_CALLOUT_ACTIVE)
+                       return -EBUSY;
+               info->flags |= ASYNC_NORMAL_ACTIVE;
+               return 0;
+       }
+
+       if (info->flags & ASYNC_CALLOUT_ACTIVE) {
+               if (state->normal_termios.c_cflag & CLOCAL)
+                       do_clocal = 1;
+       } else {
+               if (tty->termios->c_cflag & CLOCAL)
+                       do_clocal = 1;
+       }
+       
+       /*
+        * Block waiting for the carrier detect and the line to become
+        * free (i.e., not in use by the callout).  While we are in
+        * this loop, state->count is dropped by one, so that
+        * rs_close() knows when to free things.  We restore it upon
+        * exit, either normal or abnormal.
+        */
+       retval = 0;
+#ifdef DO_THIS_LATER
+       add_wait_queue(&info->open_wait, &wait);
+#ifdef SERIAL_DEBUG_OPEN
+       printk("block_til_ready before block: ttys%d, count = %d\n",
+              state->line, state->count);
+#endif
+       cli();
+       if (!tty_hung_up_p(filp)) 
+               state->count--;
+       sti();
+       info->blocked_open++;
+       while (1) {
+               cli();
+               if (!(info->flags & ASYNC_CALLOUT_ACTIVE) &&
+                   (tty->termios->c_cflag & CBAUD))
+                       serial_out(info, UART_MCR,
+                                  serial_inp(info, UART_MCR) |
+                                  (UART_MCR_DTR | UART_MCR_RTS));
+               sti();
+               set_current_state(TASK_INTERRUPTIBLE);
+               if (tty_hung_up_p(filp) ||
+                   !(info->flags & ASYNC_INITIALIZED)) {
+#ifdef SERIAL_DO_RESTART
+                       if (info->flags & ASYNC_HUP_NOTIFY)
+                               retval = -EAGAIN;
+                       else
+                               retval = -ERESTARTSYS;  
+#else
+                       retval = -EAGAIN;
+#endif
+                       break;
+               }
+               if (!(info->flags & ASYNC_CALLOUT_ACTIVE) &&
+                   !(info->flags & ASYNC_CLOSING) &&
+                   (do_clocal || (serial_in(info, UART_MSR) &
+                                  UART_MSR_DCD)))
+                       break;
+               if (signal_pending(current)) {
+                       retval = -ERESTARTSYS;
+                       break;
+               }
+#ifdef SERIAL_DEBUG_OPEN
+               printk("block_til_ready blocking: ttys%d, count = %d\n",
+                      info->line, state->count);
+#endif
+               schedule();
+       }
+       current->state = TASK_RUNNING;
+       remove_wait_queue(&info->open_wait, &wait);
+       if (!tty_hung_up_p(filp))
+               state->count++;
+       info->blocked_open--;
+#ifdef SERIAL_DEBUG_OPEN
+       printk("block_til_ready after blocking: ttys%d, count = %d\n",
+              info->line, state->count);
+#endif
+#endif /* DO_THIS_LATER */
+       if (retval)
+               return retval;
+       info->flags |= ASYNC_NORMAL_ACTIVE;
+       return 0;
+}
+
+static int get_async_struct(int line, ser_info_t **ret_info)
+{
+       struct serial_state *sstate;
+
+       sstate = rs_table + line;
+       if (sstate->info) {
+               sstate->count++;
+               *ret_info = (ser_info_t *)sstate->info;
+               return 0;
+       }
+       else {
+               return -ENOMEM;
+       }
+}
+
+/*
+ * This routine is called whenever a serial port is opened.  It
+ * enables interrupts for a serial port, linking in its async structure into
+ * the IRQ chain.   It also performs the serial-specific
+ * initialization for the tty structure.
+ */
+static int rs_8xx_open(struct tty_struct *tty, struct file * filp)
+{
+       ser_info_t      *info;
+       int             retval, line;
+
+       line = MINOR(tty->device) - tty->driver.minor_start;
+       if ((line < 0) || (line >= NR_PORTS))
+               return -ENODEV;
+       retval = get_async_struct(line, &info);
+       if (retval)
+               return retval;
+       if (serial_paranoia_check(info, tty->device, "rs_open"))
+               return -ENODEV;
+
+#ifdef SERIAL_DEBUG_OPEN
+       printk("rs_open %s%d, count = %d\n", tty->driver.name, info->line,
+              info->state->count);
+#endif
+       tty->driver_data = info;
+       info->tty = tty;
+
+       /*
+        * Start up serial port
+        */
+       retval = startup(info);
+       if (retval)
+               return retval;
+
+       MOD_INC_USE_COUNT;
+       retval = block_til_ready(tty, filp, info);
+       if (retval) {
+#ifdef SERIAL_DEBUG_OPEN
+               printk("rs_open returning after block_til_ready with %d\n",
+                      retval);
+#endif
+               return retval;
+       }
+
+       if ((info->state->count == 1) &&
+           (info->flags & ASYNC_SPLIT_TERMIOS)) {
+               if (tty->driver.subtype == SERIAL_TYPE_NORMAL)
+                       *tty->termios = info->state->normal_termios;
+               else 
+                       *tty->termios = info->state->callout_termios;
+               change_speed(info);
+       }
+
+       info->session = current->session;
+       info->pgrp = current->pgrp;
+
+#ifdef SERIAL_DEBUG_OPEN
+       printk("rs_open ttys%d successful...", info->line);
+#endif
+       return 0;
+}
+
+/*
+ * /proc fs routines....
+ */
+
+static int inline line_info(char *buf, struct serial_state *state)
+{
+#ifdef notdef
+       struct async_struct *info = state->info, scr_info;
+       char    stat_buf[30], control, status;
+#endif
+       int     ret;
+
+       ret = sprintf(buf, "%d: uart:%s port:%X irq:%d",
+                     state->line,
+                     (state->smc_scc_num < SCC_NUM_BASE) ? "SMC" : "SCC",
+                     state->port, state->irq);
+
+       if (!state->port || (state->type == PORT_UNKNOWN)) {
+               ret += sprintf(buf+ret, "\n");
+               return ret;
+       }
+
+#ifdef notdef
+       /*
+        * Figure out the current RS-232 lines
+        */
+       if (!info) {
+               info = &scr_info;       /* This is just for serial_{in,out} */
+
+               info->magic = SERIAL_MAGIC;
+               info->port = state->port;
+               info->flags = state->flags;
+               info->quot = 0;
+               info->tty = 0;
+       }
+       cli();
+       status = serial_in(info, UART_MSR);
+       control = info ? info->MCR : serial_in(info, UART_MCR);
+       sti();
+       
+       stat_buf[0] = 0;
+       stat_buf[1] = 0;
+       if (control & UART_MCR_RTS)
+               strcat(stat_buf, "|RTS");
+       if (status & UART_MSR_CTS)
+               strcat(stat_buf, "|CTS");
+       if (control & UART_MCR_DTR)
+               strcat(stat_buf, "|DTR");
+       if (status & UART_MSR_DSR)
+               strcat(stat_buf, "|DSR");
+       if (status & UART_MSR_DCD)
+               strcat(stat_buf, "|CD");
+       if (status & UART_MSR_RI)
+               strcat(stat_buf, "|RI");
+
+       if (info->quot) {
+               ret += sprintf(buf+ret, " baud:%d",
+                              state->baud_base / info->quot);
+       }
+
+       ret += sprintf(buf+ret, " tx:%d rx:%d",
+                     state->icount.tx, state->icount.rx);
+
+       if (state->icount.frame)
+               ret += sprintf(buf+ret, " fe:%d", state->icount.frame);
+       
+       if (state->icount.parity)
+               ret += sprintf(buf+ret, " pe:%d", state->icount.parity);
+       
+       if (state->icount.brk)
+               ret += sprintf(buf+ret, " brk:%d", state->icount.brk);  
+
+       if (state->icount.overrun)
+               ret += sprintf(buf+ret, " oe:%d", state->icount.overrun);
+
+       /*
+        * Last thing is the RS-232 status lines
+        */
+       ret += sprintf(buf+ret, " %s\n", stat_buf+1);
+#endif
+       return ret;
+}
+
+int rs_8xx_read_proc(char *page, char **start, off_t off, int count,
+                int *eof, void *data)
+{
+       int i, len = 0;
+       off_t   begin = 0;
+
+       len += sprintf(page, "serinfo:1.0 driver:%s\n", serial_version);
+       for (i = 0; i < NR_PORTS && len < 4000; i++) {
+               len += line_info(page + len, &rs_table[i]);
+               if (len+begin > off+count)
+                       goto done;
+               if (len+begin < off) {
+                       begin += len;
+                       len = 0;
+               }
+       }
+       *eof = 1;
+done:
+       if (off >= len+begin)
+               return 0;
+       *start = page + (begin-off);
+       return ((count < begin+len-off) ? count : begin+len-off);
+}
+
+/*
+ * ---------------------------------------------------------------------
+ * rs_init() and friends
+ *
+ * rs_init() is called at boot-time to initialize the serial driver.
+ * ---------------------------------------------------------------------
+ */
+
+/*
+ * This routine prints out the appropriate serial driver version
+ * number, and identifies which options were configured into this
+ * driver.
+ */
+static _INLINE_ void show_serial_version(void)
+{
+       printk(KERN_INFO "%s version %s\n", serial_name, serial_version);
+}
+
+
+/*
+ * The serial console driver used during boot.  Note that these names
+ * clash with those found in "serial.c", so we currently can't support
+ * the 16xxx uarts and these at the same time.  I will fix this to become
+ * an indirect function call from tty_io.c (or something).
+ */
+
+#ifdef CONFIG_SERIAL_CONSOLE
+
+/*
+ * Print a string to the serial port trying not to disturb any possible
+ * real use of the port...
+ */
+static void serial_console_write(struct console *c, const char *s,
+                               unsigned count)
+{
+       struct          serial_state    *ser;
+       ser_info_t                      *info;
+       unsigned                        i;
+       volatile        cbd_t           *bdp, *bdbase;
+       volatile        smc_uart_t      *up;
+       volatile        u_char          *cp;
+
+       ser = rs_table + c->index;
+
+       /* If the port has been initialized for general use, we have
+        * to use the buffer descriptors allocated there.  Otherwise,
+        * we simply use the single buffer allocated.
+        */
+       if ((info = (ser_info_t *)ser->info) != NULL) {
+               bdp = info->tx_cur;
+               bdbase = info->tx_bd_base;
+       }
+       else {
+               /* Pointer to UART in parameter ram.
+               */
+               up = (smc_uart_t *)&immr->im_dprambase[ser->port];
+
+               /* Get the address of the host memory buffer.
+                */
+               bdp = bdbase = (cbd_t *)&immr->im_dprambase[up->smc_tbase];
+       }
+
+       /*
+        * We need to gracefully shut down the transmitter, disable
+        * interrupts, then send our bytes out.
+        */
+
+       /*
+        * Now, do each character.  This is not as bad as it looks
+        * since this is a holding FIFO and not a transmitting FIFO.
+        * We could add the complexity of filling the entire transmit
+        * buffer, but we would just wait longer between accesses......
+        */
+       for (i = 0; i < count; i++, s++) {
+               /* Wait for transmitter fifo to empty.
+                * Ready indicates output is ready, and xmt is doing
+                * that, not that it is ready for us to send.
+                */
+               while (bdp->cbd_sc & BD_SC_READY);
+               /* Send the character out. */
+               cp = __va(bdp->cbd_bufaddr);
+               *cp = *s;
+               
+               bdp->cbd_datlen = 1;
+               bdp->cbd_sc |= BD_SC_READY;
+
+               if (bdp->cbd_sc & BD_SC_WRAP)
+                       bdp = bdbase;
+               else
+                       bdp++;
+
+               /* if a LF, also do CR... */
+               if (*s == 10) {
+                       while (bdp->cbd_sc & BD_SC_READY);
+                       cp = __va(bdp->cbd_bufaddr);
+                       *cp = 13;
+                       bdp->cbd_datlen = 1;
+                       bdp->cbd_sc |= BD_SC_READY;
+
+                       if (bdp->cbd_sc & BD_SC_WRAP) {
+                               bdp = bdbase;
+                       }
+                       else {
+                               bdp++;
+                       }
+               }
+       }
+
+       /*
+        * Finally, Wait for transmitter & holding register to empty
+        *  and restore the IER
+        */
+       while (bdp->cbd_sc & BD_SC_READY);
+
+       if (info)
+               info->tx_cur = (cbd_t *)bdp;
+}
+
+/*
+ * Receive character from the serial port.  This only works well
+ * before the port is initialize for real use.
+ */
+static int serial_console_wait_key(struct console *co)
+{
+       struct serial_state             *ser;
+       u_char                          c, *cp;
+       ser_info_t                      *info;
+       volatile        cbd_t           *bdp;
+       volatile        smc_uart_t      *up;
+
+       ser = rs_table + co->index;
+
+       /* Pointer to UART in parameter ram.
+       */
+       up = (smc_uart_t *)&immr->im_dprambase[ser->port];
+
+       /* Get the address of the host memory buffer.
+        * If the port has been initialized for general use, we must
+        * use information from the port structure.
+        */
+       if ((info = (ser_info_t *)ser->info))
+               bdp = info->rx_cur;
+       else
+               bdp = (cbd_t *)&immr->im_dprambase[up->smc_rbase];
+
+       /*
+        * We need to gracefully shut down the receiver, disable
+        * interrupts, then read the input.
+        */
+       while (bdp->cbd_sc & BD_SC_EMPTY);      /* Wait for a character */
+       cp = __va(bdp->cbd_bufaddr);
+
+       if (info) {
+               if (bdp->cbd_sc & BD_SC_WRAP) {
+                       bdp = info->rx_bd_base;
+               }
+               else {
+                       bdp++;
+               }
+               info->rx_cur = (cbd_t *)bdp;
+       }
+
+       c = *cp;
+       return((int)c);
+}
+
+static kdev_t serial_console_device(struct console *c)
+{
+       return MKDEV(TTYAUX_MAJOR, 64 + c->index);
+}
+
+
+static struct console sercons = {
+       "ttyS",
+       serial_console_write,
+       NULL,
+       serial_console_device,
+       serial_console_wait_key,
+       NULL,
+       serial_console_setup,
+       CON_PRINTBUFFER,
+       CONFIG_SERIAL_CONSOLE_PORT,
+       0,
+       NULL
+};
+
+/*
+ *     Register console.
+ */
+long __init console_8xx_init(long kmem_start, long kmem_end)
+{
+       register_console(&sercons);
+       return kmem_start;
+}
+
+#endif
+
+/* Default console baud rate as determined by the board information
+ * structure.
+ */
+static int     baud_idx;
+
+/*
+ * The serial driver boot-time initialization code!
+ */
+int __init rs_8xx_init(void)
+{
+       struct serial_state * state;
+       ser_info_t      *info;
+       uint            mem_addr, dp_addr;
+       int             i, j, idx;
+       uint            page, sblock;
+       volatile        cbd_t           *bdp;
+       volatile        cpm8260_t       *cp;
+       volatile        smc_t           *sp;
+       volatile        smc_uart_t      *up;
+       volatile        scc_t           *scp;
+       volatile        scc_uart_t      *sup;
+       volatile        immap_t         *immap;
+       volatile        iop8260_t       *io;
+       
+       init_bh(SERIAL_BH, do_serial_bh);
+#if 0
+       timer_table[RS_TIMER].fn = rs_8xx_timer;
+       timer_table[RS_TIMER].expires = 0;
+#endif
+
+       show_serial_version();
+
+       /* Initialize the tty_driver structure */
+       
+       /*memset(&serial_driver, 0, sizeof(struct tty_driver));*/
+       __clear_user(&serial_driver,sizeof(struct tty_driver));
+       serial_driver.magic = TTY_DRIVER_MAGIC;
+       serial_driver.driver_name = "serial";
+       serial_driver.name = "ttyS";
+       serial_driver.major = TTY_MAJOR;
+       serial_driver.minor_start = 64;
+       serial_driver.num = NR_PORTS;
+       serial_driver.type = TTY_DRIVER_TYPE_SERIAL;
+       serial_driver.subtype = SERIAL_TYPE_NORMAL;
+       serial_driver.init_termios = tty_std_termios;
+       serial_driver.init_termios.c_cflag =
+               baud_idx | CS8 | CREAD | HUPCL | CLOCAL;
+       serial_driver.flags = TTY_DRIVER_REAL_RAW;
+       serial_driver.refcount = &serial_refcount;
+       serial_driver.table = serial_table;
+       serial_driver.termios = serial_termios;
+       serial_driver.termios_locked = serial_termios_locked;
+
+       serial_driver.open = rs_8xx_open;
+       serial_driver.close = rs_8xx_close;
+       serial_driver.write = rs_8xx_write;
+       serial_driver.put_char = rs_8xx_put_char;
+       serial_driver.write_room = rs_8xx_write_room;
+       serial_driver.chars_in_buffer = rs_8xx_chars_in_buffer;
+       serial_driver.flush_buffer = rs_8xx_flush_buffer;
+       serial_driver.ioctl = rs_8xx_ioctl;
+       serial_driver.throttle = rs_8xx_throttle;
+       serial_driver.unthrottle = rs_8xx_unthrottle;
+       serial_driver.send_xchar = rs_8xx_send_xchar;
+       serial_driver.set_termios = rs_8xx_set_termios;
+       serial_driver.stop = rs_8xx_stop;
+       serial_driver.start = rs_8xx_start;
+       serial_driver.hangup = rs_8xx_hangup;
+       serial_driver.wait_until_sent = rs_8xx_wait_until_sent;
+       serial_driver.read_proc = rs_8xx_read_proc;
+       
+       /*
+        * The callout device is just like normal device except for
+        * major number and the subtype code.
+        */
+       callout_driver = serial_driver;
+       callout_driver.name = "cua";
+       callout_driver.major = TTYAUX_MAJOR;
+       callout_driver.subtype = SERIAL_TYPE_CALLOUT;
+       callout_driver.read_proc = 0;
+       callout_driver.proc_entry = 0;
+
+       if (tty_register_driver(&serial_driver))
+               panic("Couldn't register serial driver\n");
+       if (tty_register_driver(&callout_driver))
+               panic("Couldn't register callout driver\n");
+       
+       immap = immr;
+       cp = &immap->im_cpm;
+       io = &immap->im_ioport;
+
+       /* This should have been done long ago by the early boot code,
+        * but do it again to make sure.
+        */
+       *(ushort *)(&immap->im_dprambase[PROFF_SMC1_BASE]) = PROFF_SMC1;
+       *(ushort *)(&immap->im_dprambase[PROFF_SMC2_BASE]) = PROFF_SMC2;
+
+       /* Geeze, here we go....Picking I/O port bits....Lots of
+        * choices.  If you don't like mine, pick your own.
+        * Configure SMCs Tx/Rx.  SMC1 is only on Port D, SMC2 is
+        * only on Port A.  You either pick 'em, or not.
+        */
+       io->iop_ppard |= 0x00c00000;
+       io->iop_pdird |= 0x00400000;
+       io->iop_pdird &= ~0x00800000;
+       io->iop_psord &= ~0x00c00000;
+#if USE_SMC2
+       io->iop_ppara |= 0x01800000;
+       io->iop_pdira |= 0x00800000;
+       io->iop_pdira &= ~0x01000000;
+       io->iop_psora &= ~0x01800000;
+#endif
+
+       /* Configure SCC2 and SCC3.  Be careful about the fine print.
+        * Secondary options are only available when you take away
+        * the primary option.  Unless the pins are used for something
+        * else, SCC2 and SCC3 are on Port B.
+        *      Port B,  8 - SCC3 TxD
+        *      Port B, 12 - SCC2 TxD
+        *      Port B, 14 - SCC3 RxD
+        *      Port B, 15 - SCC2 RxD
+        */
+       io->iop_pparb |= 0x008b0000;
+       io->iop_pdirb |= 0x00880000;
+       io->iop_psorb |= 0x00880000;
+       io->iop_pdirb &= ~0x00030000;
+       io->iop_psorb &= ~0x00030000;
+
+       /* Wire BRG1 to SMC1 and BRG2 to SMC2.
+       */
+       immap->im_cpmux.cmx_smr = 0;
+
+       /* Connect SCC2 and SCC3 to NMSI.  Connect BRG3 to SCC2 and
+        * BRG4 to SCC3.
+        */
+       immap->im_cpmux.cmx_scr &= ~0x00ffff00;
+       immap->im_cpmux.cmx_scr |= 0x00121b00;
+
+       for (i = 0, state = rs_table; i < NR_PORTS; i++,state++) {
+               state->magic = SSTATE_MAGIC;
+               state->line = i;
+               state->type = PORT_UNKNOWN;
+               state->custom_divisor = 0;
+               state->close_delay = 5*HZ/10;
+               state->closing_wait = 30*HZ;
+               state->callout_termios = callout_driver.init_termios;
+               state->normal_termios = serial_driver.init_termios;
+               state->icount.cts = state->icount.dsr = 
+                       state->icount.rng = state->icount.dcd = 0;
+               state->icount.rx = state->icount.tx = 0;
+               state->icount.frame = state->icount.parity = 0;
+               state->icount.overrun = state->icount.brk = 0;
+               printk(KERN_INFO "ttyS%02d at 0x%04x is a %s\n",
+                      i, state->port,
+                      (state->smc_scc_num < SCC_NUM_BASE) ? "SMC" : "SCC");
+#ifdef CONFIG_SERIAL_CONSOLE
+               /* If we just printed the message on the console port, and
+                * we are about to initialize it for general use, we have
+                * to wait a couple of character times for the CR/NL to
+                * make it out of the transmit buffer.
+                */
+               if (i == CONFIG_SERIAL_CONSOLE_PORT)
+                       mdelay(2);
+#endif
+               info = kmalloc(sizeof(ser_info_t), GFP_KERNEL);
+               if (info) {
+                       /*memset(info, 0, sizeof(ser_info_t));*/
+                       __clear_user(info,sizeof(ser_info_t));
+                       info->magic = SERIAL_MAGIC;
+                       info->flags = state->flags;
+                       info->tqueue.routine = do_softint;
+                       info->tqueue.data = info;
+                       info->tqueue_hangup.routine = do_serial_hangup;
+                       info->tqueue_hangup.data = info;
+                       info->line = i;
+                       info->state = state;
+                       state->info = (struct async_struct *)info;
+
+                       /* We need to allocate a transmit and receive buffer
+                        * descriptors from dual port ram, and a character
+                        * buffer area from host mem.
+                        */
+                       dp_addr = m8260_cpm_dpalloc(sizeof(cbd_t) * RX_NUM_FIFO);
+
+                       /* Allocate space for FIFOs in the host memory.
+                       */
+                       mem_addr = m8260_cpm_hostalloc(RX_NUM_FIFO * RX_BUF_SIZE);
+
+                       /* Set the physical address of the host memory
+                        * buffers in the buffer descriptors, and the
+                        * virtual address for us to work with.
+                        */
+                       bdp = (cbd_t *)&immap->im_dprambase[dp_addr];
+                       info->rx_cur = info->rx_bd_base = (cbd_t *)bdp;
+
+                       for (j=0; j<(RX_NUM_FIFO-1); j++) {
+                               bdp->cbd_bufaddr = __pa(mem_addr);
+                               bdp->cbd_sc = BD_SC_EMPTY | BD_SC_INTRPT;
+                               mem_addr += RX_BUF_SIZE;
+                               bdp++;
+                       }
+                       bdp->cbd_bufaddr = __pa(mem_addr);
+                       bdp->cbd_sc = BD_SC_WRAP | BD_SC_EMPTY | BD_SC_INTRPT;
+
+                       if ((idx = state->smc_scc_num) < SCC_NUM_BASE) {
+                               sp = &immap->im_smc[idx];
+                               up = (smc_uart_t *)&immap->im_dprambase[state->port];
+                               up->smc_rbase = dp_addr;
+                       }
+                       else {
+                               scp = &immap->im_scc[idx - SCC_IDX_BASE];
+                               sup = (scc_uart_t *)&immap->im_dprambase[state->port];
+                               sup->scc_genscc.scc_rbase = dp_addr;
+                       }
+
+                       dp_addr = m8260_cpm_dpalloc(sizeof(cbd_t) * TX_NUM_FIFO);
+
+                       /* Allocate space for FIFOs in the host memory.
+                       */
+                       mem_addr = m8260_cpm_hostalloc(TX_NUM_FIFO * TX_BUF_SIZE);
+
+                       /* Set the physical address of the host memory
+                        * buffers in the buffer descriptors, and the
+                        * virtual address for us to work with.
+                        */
+                       bdp = (cbd_t *)&immap->im_dprambase[dp_addr];
+                       info->tx_cur = info->tx_bd_base = (cbd_t *)bdp;
+
+                       for (j=0; j<(TX_NUM_FIFO-1); j++) {
+                               bdp->cbd_bufaddr = __pa(mem_addr);
+                               bdp->cbd_sc = BD_SC_INTRPT;
+                               mem_addr += TX_BUF_SIZE;
+                               bdp++;
+                       }
+                       bdp->cbd_bufaddr = __pa(mem_addr);
+                       bdp->cbd_sc = (BD_SC_WRAP | BD_SC_INTRPT);
+
+                       if (idx < SCC_NUM_BASE) {
+                               up->smc_tbase = dp_addr;
+
+                               /* Set up the uart parameters in the
+                                * parameter ram.
+                                */
+                               up->smc_rfcr = SMC_EB;
+                               up->smc_tfcr = SMC_EB;
+
+                               /* Set this to 1 for now, so we get single
+                                * character interrupts.  Using idle charater
+                                * time requires some additional tuning.
+                                */
+                               up->smc_mrblr = 1;
+                               up->smc_maxidl = 0;
+                               up->smc_brkcr = 1;
+
+                               /* Send the CPM an initialize command.
+                               */
+                               if (state->smc_scc_num == 0) {
+                                       page = CPM_CR_SMC1_PAGE;
+                                       sblock = CPM_CR_SMC1_SBLOCK;
+                               }
+                               else {
+                                       page = CPM_CR_SMC2_PAGE;
+                                       sblock = CPM_CR_SMC2_SBLOCK;
+                               }
+
+                               cp->cp_cpcr = mk_cr_cmd(page, sblock, 0,
+                                               CPM_CR_INIT_TRX) | CPM_CR_FLG;
+                               while (cp->cp_cpcr & CPM_CR_FLG);
+
+                               /* Set UART mode, 8 bit, no parity, one stop.
+                                * Enable receive and transmit.
+                                */
+                               sp->smc_smcmr = smcr_mk_clen(9) | SMCMR_SM_UART;
+
+                               /* Disable all interrupts and clear all pending
+                                * events.
+                                */
+                               sp->smc_smcm = 0;
+                               sp->smc_smce = 0xff;
+                       }
+                       else {
+                               sup->scc_genscc.scc_tbase = dp_addr;
+
+                               /* Set up the uart parameters in the
+                                * parameter ram.
+                                */
+                               sup->scc_genscc.scc_rfcr = SMC_EB;
+                               sup->scc_genscc.scc_tfcr = SMC_EB;
+
+                               /* Set this to 1 for now, so we get single
+                                * character interrupts.  Using idle charater
+                                * time requires some additional tuning.
+                                */
+                               sup->scc_genscc.scc_mrblr = 1;
+                               sup->scc_maxidl = 0;
+                               sup->scc_brkcr = 1;
+                               sup->scc_parec = 0;
+                               sup->scc_frmec = 0;
+                               sup->scc_nosec = 0;
+                               sup->scc_brkec = 0;
+                               sup->scc_uaddr1 = 0;
+                               sup->scc_uaddr2 = 0;
+                               sup->scc_toseq = 0;
+                               sup->scc_char1 = 0x8000;
+                               sup->scc_char2 = 0x8000;
+                               sup->scc_char3 = 0x8000;
+                               sup->scc_char4 = 0x8000;
+                               sup->scc_char5 = 0x8000;
+                               sup->scc_char6 = 0x8000;
+                               sup->scc_char7 = 0x8000;
+                               sup->scc_char8 = 0x8000;
+                               sup->scc_rccm = 0xc0ff;
+
+                               /* Send the CPM an initialize command.
+                               */
+                               if (state->smc_scc_num == 2) {
+                                       page = CPM_CR_SCC2_PAGE;
+                                       sblock = CPM_CR_SCC2_SBLOCK;
+                               }
+                               else {
+                                       page = CPM_CR_SCC3_PAGE;
+                                       sblock = CPM_CR_SCC3_SBLOCK;
+                               }
+
+                               cp->cp_cpcr = mk_cr_cmd(page, sblock, 0,
+                                               CPM_CR_INIT_TRX) | CPM_CR_FLG;
+                               while (cp->cp_cpcr & CPM_CR_FLG);
+
+                               /* Set UART mode, 8 bit, no parity, one stop.
+                                * Enable receive and transmit.
+                                */
+                               scp->scc_gsmrh = 0;
+                               scp->scc_gsmrl = 
+                                       (SCC_GSMRL_MODE_UART | SCC_GSMRL_TDCR_16 | SCC_GSMRL_RDCR_16);
+
+                               /* Disable all interrupts and clear all pending
+                                * events.
+                                */
+                               scp->scc_sccm = 0;
+                               scp->scc_scce = 0xffff;
+                               scp->scc_dsr = 0x7e7e;
+                               scp->scc_pmsr = 0x3000;
+                       }
+
+                       /* Install interrupt handler.
+                       */
+                       request_8xxirq(state->irq, rs_8xx_interrupt, 0, "uart", info);
+
+                       /* Set up the baud rate generator.
+                       */
+                       m8260_cpm_setbrg(state->smc_scc_num,
+                                                       baud_table[baud_idx]);
+
+                       /* If the port is the console, enable Rx and Tx.
+                       */
+#ifdef CONFIG_SERIAL_CONSOLE
+                       if (i == CONFIG_SERIAL_CONSOLE_PORT)
+                               sp->smc_smcmr |= SMCMR_REN | SMCMR_TEN;
+#endif
+               }
+       }
+       return 0;
+}
+
+/* This must always be called before the rs_8xx_init() function, otherwise
+ * it blows away the port control information.
+*/
+static int __init serial_console_setup(struct console *co, char *options)
+{
+       struct          serial_state *ser;
+       uint            mem_addr, dp_addr, bidx;
+       volatile        cbd_t           *bdp;
+       volatile        cpm8260_t       *cp;
+       volatile        immap_t         *immap;
+       volatile        smc_t           *sp;
+       volatile        smc_uart_t      *up;
+       volatile        iop8260_t       *io;
+       bd_t                            *bd;
+
+       bd = (bd_t *)__res;
+
+       for (bidx = 0; bidx < (sizeof(baud_table) / sizeof(int)); bidx++)
+               if (bd->bi_baudrate == baud_table[bidx])
+                       break;
+
+       co->cflag = CREAD|CLOCAL|bidx|CS8;
+       baud_idx = bidx;
+
+       ser = rs_table + co->index;
+
+       
+       immap = immr;
+       cp = &immap->im_cpm;
+       io = &immap->im_ioport;
+
+       /* This should have been done long ago by the early boot code,
+        * but do it again to make sure.
+        */
+       *(ushort *)(&immap->im_dprambase[PROFF_SMC1_BASE]) = PROFF_SMC1;
+       *(ushort *)(&immap->im_dprambase[PROFF_SMC2_BASE]) = PROFF_SMC2;
+
+       /* Right now, assume we are using SMCs.
+       */
+       sp = &immap->im_smc[ser->smc_scc_num];
+
+       /* When we get here, the CPM has been reset, so we need
+        * to configure the port.
+        * We need to allocate a transmit and receive buffer descriptor
+        * from dual port ram, and a character buffer area from host mem.
+        */
+       up = (smc_uart_t *)&immap->im_dprambase[ser->port];
+
+       /* Disable transmitter/receiver.
+       */
+       sp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN);
+
+       /* Use Port D for SMC1 instead of other functions.
+       */
+       io->iop_ppard |= 0x00c00000;
+       io->iop_pdird |= 0x00400000;
+       io->iop_pdird &= ~0x00800000;
+       io->iop_psord &= ~0x00c00000;
+
+       /* Allocate space for two buffer descriptors in the DP ram.
+       */
+       dp_addr = m8260_cpm_dpalloc(sizeof(cbd_t) * 2);
+
+       /* Allocate space for two 2 byte FIFOs in the host memory.
+       */
+       mem_addr = m8260_cpm_hostalloc(4);
+
+       /* Set the physical address of the host memory buffers in
+        * the buffer descriptors.
+        */
+       bdp = (cbd_t *)&immap->im_dprambase[dp_addr];
+       bdp->cbd_bufaddr = __pa(mem_addr);
+       (bdp+1)->cbd_bufaddr = __pa(mem_addr+2);
+
+       /* For the receive, set empty and wrap.
+        * For transmit, set wrap.
+        */
+       bdp->cbd_sc = BD_SC_EMPTY | BD_SC_WRAP;
+       (bdp+1)->cbd_sc = BD_SC_WRAP;
+
+       /* Set up the uart parameters in the parameter ram.
+       */
+       up->smc_rbase = dp_addr;        /* Base of receive buffer desc. */
+       up->smc_tbase = dp_addr+sizeof(cbd_t);  /* Base of xmt buffer desc. */
+       up->smc_rfcr = SMC_EB;
+       up->smc_tfcr = SMC_EB;
+
+       /* Set this to 1 for now, so we get single character interrupts.
+       */
+       up->smc_mrblr = 1;              /* receive buffer length */
+       up->smc_maxidl = 0;             /* wait forever for next char */
+
+       /* Send the CPM an initialize command.
+       */
+       cp->cp_cpcr = mk_cr_cmd(CPM_CR_SMC1_PAGE, CPM_CR_SMC1_SBLOCK, 0,
+                       CPM_CR_INIT_TRX) | CPM_CR_FLG;
+       while (cp->cp_cpcr & CPM_CR_FLG);
+
+       /* Set UART mode, 8 bit, no parity, one stop.
+        * Enable receive and transmit.
+        */
+       sp->smc_smcmr = smcr_mk_clen(9) |  SMCMR_SM_UART;
+
+       /* Set up the baud rate generator.
+       */
+       m8260_cpm_setbrg(ser->smc_scc_num, bd->bi_baudrate);
+
+       /* And finally, enable Rx and Tx.
+       */
+       sp->smc_smcmr |= SMCMR_REN | SMCMR_TEN;
+
+       return 0;
+}
index f6b37dcb4fb435d2897963316156836c8422825a..00a0d776fb32ded8227ea9a754804905f351bacb 100644 (file)
@@ -37,6 +37,7 @@
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
+#include <linux/spinlock.h>
 
 #include <asm/8xx_immap.h>
 #include <asm/pgtable.h>
  *     Port C,  9 (CTS2) - SCC Ethernet Collision
  */
 
+/* The transmitter timeout
+ */
+#define TX_TIMEOUT     (2*HZ)
+
 /* The number of Tx and Rx buffers.  These are allocated from the page
  * pool.  The code may assume these are power of two, so it is best
  * to keep them that size.
  * empty and completely full conditions.  The empty/ready indicator in
  * the buffer descriptor determines the actual condition.
  */
-struct cpm_enet_private {
+struct scc_enet_private {
        /* The saved address of a sent-in-place packet/buffer, for skfree(). */
        struct  sk_buff* tx_skbuff[TX_RING_SIZE];
        ushort  skb_cur;
@@ -150,17 +155,15 @@ struct cpm_enet_private {
        scc_t   *sccp;
        struct  net_device_stats stats;
        uint    tx_full;
-       uint    tx_busy;
-       unsigned long lock;
-       int     interrupt;
+       spinlock_t lock;
 };
 
-static int cpm_enet_open(struct net_device *dev);
-static int cpm_enet_start_xmit(struct sk_buff *skb, struct net_device *dev);
-static int cpm_enet_rx(struct net_device *dev);
-static void cpm_enet_interrupt(void *dev_id);
-static int cpm_enet_close(struct net_device *dev);
-static struct net_device_stats *cpm_enet_get_stats(struct net_device *dev);
+static int scc_enet_open(struct net_device *dev);
+static int scc_enet_start_xmit(struct sk_buff *skb, struct net_device *dev);
+static int scc_enet_rx(struct net_device *dev);
+static void scc_enet_interrupt(void *dev_id);
+static int scc_enet_close(struct net_device *dev);
+static struct net_device_stats *scc_enet_get_stats(struct net_device *dev);
 static void set_multicast_list(struct net_device *dev);
 
 /* Get this from various configuration locations (depends on board).
@@ -185,7 +188,7 @@ static void set_multicast_list(struct net_device *dev);
 #endif
 
 static int
-cpm_enet_open(struct net_device *dev)
+scc_enet_open(struct net_device *dev)
 {
 
        /* I should reset the ring buffers here, but I don't yet know
@@ -197,60 +200,10 @@ cpm_enet_open(struct net_device *dev)
 }
 
 static int
-cpm_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
+scc_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
-       struct cpm_enet_private *cep = (struct cpm_enet_private *)dev->priv;
+       struct scc_enet_private *cep = (struct scc_enet_private *)dev->priv;
        volatile cbd_t  *bdp;
-       unsigned long flags;
-
-       /* Transmitter timeout, serious problems. */
-       if (cep->tx_busy) {
-               int tickssofar = jiffies - dev->trans_start;
-               if (tickssofar < 200)
-                       return 1;
-               printk("%s: transmit timed out.\n", dev->name);
-               cep->stats.tx_errors++;
-#ifndef final_version
-               {
-                       int     i;
-                       cbd_t   *bdp;
-                       printk(" Ring data dump: cur_tx %p%s cur_rx %p.\n",
-                                  cep->cur_tx, cep->tx_full ? " (full)" : "",
-                                  cep->cur_rx);
-                       bdp = cep->tx_bd_base;
-                       for (i = 0 ; i < TX_RING_SIZE; i++, bdp++)
-                               printk("%04x %04x %08x\n",
-                                       bdp->cbd_sc,
-                                       bdp->cbd_datlen,
-                                       bdp->cbd_bufaddr);
-                       bdp = cep->rx_bd_base;
-                       for (i = 0 ; i < RX_RING_SIZE; i++, bdp++)
-                               printk("%04x %04x %08x\n",
-                                       bdp->cbd_sc,
-                                       bdp->cbd_datlen,
-                                       bdp->cbd_bufaddr);
-               }
-#endif
-
-               cep->tx_busy=0;
-               dev->trans_start = jiffies;
-
-               return 0;
-       }
-
-       /* Block a timer-based transmit from overlapping.  This could better be
-        * done with atomic_swap(1, cep->tx_busy), but set_bit() works as well.
-        */
-       if (test_and_set_bit(0, (void*)&cep->tx_busy) != 0) {
-               printk("%s: Transmitter access conflict.\n", dev->name);
-               return 1;
-       }
-
-       if (test_and_set_bit(0, (void*)&cep->lock) != 0) {
-               printk("%s: tx queue lock!.\n", dev->name);
-               /* don't clear cep->tx_busy flag. */
-               return 1;
-       }
 
        /* Fill in a Tx ring entry */
        bdp = cep->cur_tx;
@@ -261,7 +214,6 @@ cpm_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
                 * This should not happen, since cep->tx_busy should be set.
                 */
                printk("%s: tx queue full!.\n", dev->name);
-               cep->lock = 0;
                return 1;
        }
 #endif
@@ -292,7 +244,10 @@ cpm_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
        /* Push the data cache so the CPM does not get stale memory
         * data.
         */
-       flush_dcache_range(skb->data, skb->data + skb->len);
+       flush_dcache_range((unsigned long)(skb->data),
+                                       (unsigned long)(skb->data + skb->len));
+
+       spin_lock_irq(&cep->lock);
 
        /* Send it on its way.  Tell CPM its ready, interrupt when done,
         * its the last BD of the frame, and to put the CRC on the end.
@@ -308,37 +263,61 @@ cpm_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
        else
                bdp++;
 
-       save_flags(flags);
-       cli();
-       cep->lock = 0;
        if (bdp->cbd_sc & BD_ENET_TX_READY)
-               cep->tx_full = 1;
-       else
-               cep->tx_busy=0;
-       restore_flags(flags);
+               netif_stop_queue(dev);
 
        cep->cur_tx = (cbd_t *)bdp;
 
+       spin_unlock_irq(&cep->lock);
+
        return 0;
 }
 
+static void
+scc_enet_timeout(struct net_device *dev)
+{
+       struct scc_enet_private *cep = (struct scc_enet_private *)dev->priv;
+
+       printk("%s: transmit timed out.\n", dev->name);
+       cep->stats.tx_errors++;
+#ifndef final_version
+       {
+               int     i;
+               cbd_t   *bdp;
+               printk(" Ring data dump: cur_tx %p%s cur_rx %p.\n",
+                      cep->cur_tx, cep->tx_full ? " (full)" : "",
+                      cep->cur_rx);
+               bdp = cep->tx_bd_base;
+               for (i = 0 ; i < TX_RING_SIZE; i++, bdp++)
+                       printk("%04x %04x %08x\n",
+                              bdp->cbd_sc,
+                              bdp->cbd_datlen,
+                              bdp->cbd_bufaddr);
+               bdp = cep->rx_bd_base;
+               for (i = 0 ; i < RX_RING_SIZE; i++, bdp++)
+                       printk("%04x %04x %08x\n",
+                              bdp->cbd_sc,
+                              bdp->cbd_datlen,
+                              bdp->cbd_bufaddr);
+       }
+#endif
+       if (!cep->tx_full)
+               netif_wake_queue(dev);
+}
+
 /* The interrupt handler.
  * This is called from the CPM handler, not the MPC core interrupt.
  */
 static void
-cpm_enet_interrupt(void *dev_id)
+scc_enet_interrupt(void *dev_id)
 {
        struct  net_device *dev = dev_id;
-       volatile struct cpm_enet_private *cep;
+       volatile struct scc_enet_private *cep;
        volatile cbd_t  *bdp;
        ushort  int_events;
        int     must_restart;
 
-       cep = (struct cpm_enet_private *)dev->priv;
-       if (cep->interrupt)
-               printk("%s: Re-entering the interrupt handler.\n", dev->name);
-
-       cep->interrupt = 1;
+       cep = (struct scc_enet_private *)dev->priv;
 
        /* Get the interrupt events that caused us to be here.
        */
@@ -349,7 +328,7 @@ cpm_enet_interrupt(void *dev_id)
        /* Handle receive event in its own function.
        */
        if (int_events & SCCE_ENET_RXF)
-               cpm_enet_rx(dev_id);
+               scc_enet_rx(dev_id);
 
        /* Check for a transmit error.  The manual is a little unclear
         * about this, so the debug code until I get it figured out.  It
@@ -363,6 +342,7 @@ cpm_enet_interrupt(void *dev_id)
        /* Transmit OK, or non-fatal error.  Update the buffer descriptors.
        */
        if (int_events & (SCCE_ENET_TXE | SCCE_ENET_TXB)) {
+           spin_lock(&cep->lock);
            bdp = cep->dirty_tx;
            while ((bdp->cbd_sc&BD_ENET_TX_READY)==0) {
                if ((bdp==cep->cur_tx) && (cep->tx_full == 0))
@@ -421,10 +401,9 @@ cpm_enet_interrupt(void *dev_id)
                /* Since we have freed up a buffer, the ring is no longer
                 * full.
                 */
-               if (cep->tx_full && cep->tx_busy) {
-                       cep->tx_full = 0;
-                       cep->tx_busy = 0;
-                       netif_wake_queue(dev);
+               if (cep->tx_full) {
+                       if (netif_queue_stopped(dev))
+                               netif_wake_queue(dev);
                }
 
                cep->dirty_tx = (cbd_t *)bdp;
@@ -444,6 +423,7 @@ cpm_enet_interrupt(void *dev_id)
                    mk_cr_cmd(CPM_CR_ENET, CPM_CR_RESTART_TX) | CPM_CR_FLG;
                while (cp->cp_cpcr & CPM_CR_FLG);
            }
+           spin_unlock(&cep->lock);
        }
 
        /* Check for receive busy, i.e. packets coming but no place to
@@ -455,8 +435,6 @@ cpm_enet_interrupt(void *dev_id)
                printk("CPM ENET: BSY can't happen.\n");
        }
 
-       cep->interrupt = 0;
-
        return;
 }
 
@@ -466,14 +444,14 @@ cpm_enet_interrupt(void *dev_id)
  * effectively tossing the packet.
  */
 static int
-cpm_enet_rx(struct net_device *dev)
+scc_enet_rx(struct net_device *dev)
 {
-       struct  cpm_enet_private *cep;
+       struct  scc_enet_private *cep;
        volatile cbd_t  *bdp;
        struct  sk_buff *skb;
        ushort  pkt_len;
 
-       cep = (struct cpm_enet_private *)dev->priv;
+       cep = (struct scc_enet_private *)dev->priv;
 
        /* First, grab all of the stats for the incoming packet.
         * These get messed up if we get called due to a busy condition.
@@ -560,7 +538,7 @@ for (;;) {
 }
 
 static int
-cpm_enet_close(struct net_device *dev)
+scc_enet_close(struct net_device *dev)
 {
        /* Don't know what to do yet.
        */
@@ -569,9 +547,9 @@ cpm_enet_close(struct net_device *dev)
        return 0;
 }
 
-static struct net_device_stats *cpm_enet_get_stats(struct net_device *dev)
+static struct net_device_stats *scc_enet_get_stats(struct net_device *dev)
 {
-       struct cpm_enet_private *cep = (struct cpm_enet_private *)dev->priv;
+       struct scc_enet_private *cep = (struct scc_enet_private *)dev->priv;
 
        return &cep->stats;
 }
@@ -588,12 +566,12 @@ static struct net_device_stats *cpm_enet_get_stats(struct net_device *dev)
 
 static void set_multicast_list(struct net_device *dev)
 {
-       struct  cpm_enet_private *cep;
+       struct  scc_enet_private *cep;
        struct  dev_mc_list *dmi;
        u_char  *mcptr, *tdptr;
        volatile scc_enet_t *ep;
        int     i, j;
-       cep = (struct cpm_enet_private *)dev->priv;
+       cep = (struct scc_enet_private *)dev->priv;
 
        /* Get pointer to SCC area in parameter RAM.
        */
@@ -661,10 +639,10 @@ static void set_multicast_list(struct net_device *dev)
  * transmit and receive to make sure we don't catch the CPM with some
  * inconsistent control information.
  */
-int __init cpm_enet_init(void)
+int __init scc_enet_init(void)
 {
        struct net_device *dev;
-       struct cpm_enet_private *cep;
+       struct scc_enet_private *cep;
        int i, j;
        unsigned char   *eap;
        unsigned long   mem_addr;
@@ -684,9 +662,10 @@ int __init cpm_enet_init(void)
 
        /* Allocate some private information.
        */
-       cep = (struct cpm_enet_private *)kmalloc(sizeof(*cep), GFP_KERNEL);
+       cep = (struct scc_enet_private *)kmalloc(sizeof(*cep), GFP_KERNEL);
        /*memset(cep, 0, sizeof(*cep));*/
        __clear_user(cep,sizeof(*cep));
+       spin_lock_init(&cep->lock);
 
        /* Create an Ethernet device instance.
        */
@@ -858,7 +837,7 @@ int __init cpm_enet_init(void)
                */
                pte = find_pte(&init_mm, mem_addr);
                pte_val(*pte) |= _PAGE_NO_CACHE;
-               flush_tlb_page(current->mm->mmap, mem_addr);
+               flush_tlb_page(init_mm.mmap, mem_addr);
 
                /* Initialize the BD for every fragment in the page.
                */
@@ -894,7 +873,7 @@ int __init cpm_enet_init(void)
 
        /* Install our interrupt handler.
        */
-       cpm_install_handler(CPMVEC_ENET, cpm_enet_interrupt, dev);
+       cpm_install_handler(CPMVEC_ENET, scc_enet_interrupt, dev);
 
        /* Set GSMR_H to enable all normal operating modes.
         * Set GSMR_L to enable Ethernet to MC68160.
@@ -953,10 +932,12 @@ int __init cpm_enet_init(void)
 #endif
 
        /* The CPM Ethernet specific entries in the device structure. */
-       dev->open = cpm_enet_open;
-       dev->hard_start_xmit = cpm_enet_start_xmit;
-       dev->stop = cpm_enet_close;
-       dev->get_stats = cpm_enet_get_stats;
+       dev->open = scc_enet_open;
+       dev->hard_start_xmit = scc_enet_start_xmit;
+       dev->tx_timeout = scc_enet_timeout;
+       dev->watchdog_timeo = TX_TIMEOUT;
+       dev->stop = scc_enet_close;
+       dev->get_stats = scc_enet_get_stats;
        dev->set_multicast_list = set_multicast_list;
 
        /* And last, enable the transmit and receive processing.
index f5088b9e4955287248bf9248b58d3d22070612e3..2ae320e7a5f70b1bbb1aca228d3cc00b9356dd4b 100644 (file)
 #include <asm/8xx_immap.h>
 #include <asm/mpc8xx.h>
 #include "commproc.h"
+#ifdef CONFIG_KGDB
+extern int  kgdb_output_string (const char* s, unsigned int count);
+#endif
 
 #ifdef CONFIG_SERIAL_CONSOLE
 #include <linux/console.h>
@@ -700,25 +704,18 @@ static int startup(ser_info_t *info)
                 * are coming.
                 */
                up = (smc_uart_t *)&cpmp->cp_dparam[state->port];
-#if 0
-               up->smc_mrblr = 1;      /* receive buffer length */
-               up->smc_maxidl = 0;     /* wait forever for next char */
-#else
+
                up->smc_mrblr = RX_BUF_SIZE;
                up->smc_maxidl = RX_BUF_SIZE;
-#endif
+
                up->smc_brkcr = 1;      /* number of break chars */
        }
        else {
                sccp = &cpmp->cp_scc[idx - SCC_IDX_BASE];
                scup = (scc_uart_t *)&cpmp->cp_dparam[state->port];
-#if 0
-               scup->scc_genscc.scc_mrblr = 1; /* receive buffer length */
-               scup->scc_maxidl = 0;   /* wait forever for next char */
-#else
+
                scup->scc_genscc.scc_mrblr = RX_BUF_SIZE;
                scup->scc_maxidl = RX_BUF_SIZE;
-#endif
 
                sccp->scc_sccm |= (UART_SCCM_TX | UART_SCCM_RX);
                sccp->scc_gsmrl |= (SCC_GSMRL_ENR | SCC_GSMRL_ENT);
@@ -959,6 +956,12 @@ static int rs_8xx_write(struct tty_struct * tty, int from_user,
        ser_info_t *info = (ser_info_t *)tty->driver_data;
        volatile cbd_t *bdp;
 
+#ifdef CONFIG_KGDB
+       /* Try to let stub handle output. Returns true if it did. */ 
+       if (kgdb_output_string(buf, count))
+               return ret;
+#endif
+
        if (serial_paranoia_check(info, tty->device, "rs_write"))
                return 0;
 
@@ -979,8 +982,8 @@ static int rs_8xx_write(struct tty_struct * tty, int from_user,
                }
 
                if (from_user) {
-                       if (c !=
-                           copy_from_user(__va(bdp->cbd_bufaddr), buf, c)) {
+                       c -= copy_from_user(__va(bdp->cbd_bufaddr), buf, c);
+                       if (!c) {
                                if (!ret)
                                        ret = -EFAULT;
                                break;
@@ -2099,7 +2102,7 @@ static _INLINE_ void show_serial_version(void)
  * Print a string to the serial port trying not to disturb any possible
  * real use of the port...
  */
-static void serial_console_write(struct console *c, const char *s,
+static void my_console_write(int idx, const char *s,
                                unsigned count)
 {
        struct          serial_state    *ser;
@@ -2109,7 +2112,7 @@ static void serial_console_write(struct console *c, const char *s,
        volatile        smc_uart_t      *up;
        volatile        u_char          *cp;
 
-       ser = rs_table + c->index;
+       ser = rs_table + idx;
 
        /* If the port has been initialized for general use, we have
         * to use the buffer descriptors allocated there.  Otherwise,
@@ -2146,8 +2149,15 @@ static void serial_console_write(struct console *c, const char *s,
                 * that, not that it is ready for us to send.
                 */
                while (bdp->cbd_sc & BD_SC_READY);
-               /* Send the character out. */
-               cp = __va(bdp->cbd_bufaddr);
+
+               /* Send the character out.
+                * If the buffer address is in the CPM DPRAM, don't
+                * convert it.
+                */
+               if ((uint)(bdp->cbd_bufaddr) > (uint)IMAP_ADDR)
+                       cp = (u_char *)(bdp->cbd_bufaddr);
+               else
+                       cp = __va(bdp->cbd_bufaddr);
                *cp = *s;
                
                bdp->cbd_datlen = 1;
@@ -2185,19 +2195,48 @@ static void serial_console_write(struct console *c, const char *s,
                info->tx_cur = (cbd_t *)bdp;
 }
 
+static void serial_console_write(struct console *c, const char *s,
+                               unsigned count)
+{
+#ifdef CONFIG_KGDB
+       /* Try to let stub handle output. Returns true if it did. */ 
+       if (kgdb_output_string(s, count))
+               return;
+#endif
+       my_console_write(c->index, s, count);
+}
+
+#ifdef CONFIG_XMON
+int
+xmon_8xx_write(const char *s, unsigned count)
+{
+       my_console_write(0, s, count);
+       return(count);
+}
+#endif
+
+#ifdef CONFIG_KGDB
+void
+putDebugChar(char ch)
+{
+       my_console_write(0, &ch, 1);
+}
+#endif
+
 /*
  * Receive character from the serial port.  This only works well
  * before the port is initialize for real use.
  */
-static int serial_console_wait_key(struct console *co)
+static int my_console_wait_key(int idx, int xmon, char *obuf)
 {
        struct serial_state             *ser;
        u_char                          c, *cp;
        ser_info_t                      *info;
        volatile        cbd_t           *bdp;
        volatile        smc_uart_t      *up;
+       int                             i;
 
-       ser = rs_table + co->index;
+       ser = rs_table + idx;
 
        /* Pointer to UART in parameter ram.
        */
@@ -2215,9 +2254,34 @@ static int serial_console_wait_key(struct console *co)
        /*
         * We need to gracefully shut down the receiver, disable
         * interrupts, then read the input.
+        * XMON just wants a poll.  If no character, return -1, else
+        * return the character.
+        */
+       if (!xmon) {
+               while (bdp->cbd_sc & BD_SC_EMPTY);
+       }
+       else {
+               if (bdp->cbd_sc & BD_SC_EMPTY)
+                       return -1;
+       }
+
+       /* If the buffer address is in the CPM DPRAM, don't
+        * convert it.
         */
-       while (bdp->cbd_sc & BD_SC_EMPTY);      /* Wait for a character */
-       cp = __va(bdp->cbd_bufaddr);
+       if ((uint)(bdp->cbd_bufaddr) > (uint)IMAP_ADDR)
+               cp = (u_char *)(bdp->cbd_bufaddr);
+       else
+               cp = __va(bdp->cbd_bufaddr);
+
+       if (obuf) {
+               i = c = bdp->cbd_datlen;
+               while (i-- > 0)
+                       *obuf++ = *cp++;
+       }
+       else {
+               c = *cp;
+       }
+       bdp->cbd_sc |= BD_SC_EMPTY;
 
        if (info) {
                if (bdp->cbd_sc & BD_SC_WRAP) {
@@ -2229,10 +2293,89 @@ static int serial_console_wait_key(struct console *co)
                info->rx_cur = (cbd_t *)bdp;
        }
 
-       c = *cp;
        return((int)c);
 }
 
+static int serial_console_wait_key(struct console *co)
+{
+       return(my_console_wait_key(co->index, 0, NULL));
+}
+
+#ifdef CONFIG_XMON
+int
+xmon_8xx_read_poll(void)
+{
+       return(my_console_wait_key(0, 1, NULL));
+}
+
+int
+xmon_8xx_read_char(void)
+{
+       return(my_console_wait_key(0, 0, NULL));
+}
+#endif
+
+#ifdef CONFIG_KGDB
+static char kgdb_buf[RX_BUF_SIZE], *kgdp;
+static int kgdb_chars;
+
+unsigned char
+getDebugChar(void)
+{
+       if (kgdb_chars <= 0) {
+               kgdb_chars = my_console_wait_key(0, 0, kgdb_buf);
+               kgdp = kgdb_buf;
+       }
+       kgdb_chars--;
+
+       return(*kgdp++);
+}
+
+void kgdb_interruptible(int state)
+{
+}
+void kgdb_map_scc(void)
+{
+       struct          serial_state *ser;
+       uint            mem_addr;
+       volatile        cbd_t           *bdp;
+       volatile        smc_uart_t      *up;
+
+       cpmp = (cpm8xx_t *)&(((immap_t *)IMAP_ADDR)->im_cpm);
+
+       /* To avoid data cache CPM DMA coherency problems, allocate a
+        * buffer in the CPM DPRAM.  This will work until the CPM and
+        * serial ports are initialized.  At that time a memory buffer
+        * will be allcoated.
+        * The port is already initialized from the boot procedure, all
+        * we do here is give it a different buffer and make it a FIFO.
+        */
+
+       ser = rs_table;
+
+       /* Right now, assume we are using SMCs.
+       */
+       up = (smc_uart_t *)&cpmp->cp_dparam[ser->port];
+
+       /* Allocate space for an input FIFO, plus a few bytes for output.
+        * Allocate bytes to maintain word alignment.
+        */
+       mem_addr = (uint)(&cpmp->cp_dpmem[0x1000]);
+
+       /* Set the physical address of the host memory buffers in
+        * the buffer descriptors.
+        */
+       bdp = (cbd_t *)&cpmp->cp_dpmem[up->smc_rbase];
+       bdp->cbd_bufaddr = mem_addr;
+
+       bdp = (cbd_t *)&cpmp->cp_dpmem[up->smc_tbase];
+       bdp->cbd_bufaddr = mem_addr+RX_BUF_SIZE;
+
+       up->smc_mrblr = RX_BUF_SIZE;            /* receive buffer length */
+       up->smc_maxidl = RX_BUF_SIZE;
+}
+#endif
+
 static kdev_t serial_console_device(struct console *c)
 {
        return MKDEV(TTYAUX_MAJOR, 64 + c->index);
@@ -2522,8 +2665,8 @@ int __init rs_8xx_init(void)
                                 * character interrupts.  Using idle charater
                                 * time requires some additional tuning.
                                 */
-                               up->smc_mrblr = 1;
-                               up->smc_maxidl = 0;
+                               up->smc_mrblr = RX_BUF_SIZE;
+                               up->smc_maxidl = RX_BUF_SIZE;
                                up->smc_brkcr = 1;
 
                                /* Send the CPM an initialize command.
@@ -2557,12 +2700,8 @@ int __init rs_8xx_init(void)
                                sup->scc_genscc.scc_rfcr = SMC_EB;
                                sup->scc_genscc.scc_tfcr = SMC_EB;
 
-                               /* Set this to 1 for now, so we get single
-                                * character interrupts.  Using idle charater
-                                * time requires some additional tuning.
-                                */
-                               sup->scc_genscc.scc_mrblr = 1;
-                               sup->scc_maxidl = 0;
+                               sup->scc_genscc.scc_mrblr = RX_BUF_SIZE;
+                               sup->scc_maxidl = RX_BUF_SIZE;
                                sup->scc_brkcr = 1;
                                sup->scc_parec = 0;
                                sup->scc_frmec = 0;
@@ -2629,6 +2768,7 @@ int __init rs_8xx_init(void)
 #endif
                }
        }
+
        return 0;
 }
 
@@ -2678,16 +2818,17 @@ static int __init serial_console_setup(struct console *co, char *options)
        */
        dp_addr = m8xx_cpm_dpalloc(sizeof(cbd_t) * 2);
 
-       /* Allocate space for two 2 byte FIFOs in the host memory.
-       */
-       mem_addr = m8xx_cpm_hostalloc(4);
+       /* Allocate space for an input FIFO, plus a few bytes for output.
+        * Allocate bytes to maintain word alignment.
+        */
+       mem_addr = m8xx_cpm_hostalloc(RX_BUF_SIZE + 4);
 
        /* Set the physical address of the host memory buffers in
         * the buffer descriptors.
         */
        bdp = (cbd_t *)&cp->cp_dpmem[dp_addr];
        bdp->cbd_bufaddr = __pa(mem_addr);
-       (bdp+1)->cbd_bufaddr = __pa(mem_addr+2);
+       (bdp+1)->cbd_bufaddr = __pa(mem_addr+RX_BUF_SIZE);
 
        /* For the receive, set empty and wrap.
         * For transmit, set wrap.
@@ -2702,10 +2843,8 @@ static int __init serial_console_setup(struct console *co, char *options)
        up->smc_rfcr = SMC_EB;
        up->smc_tfcr = SMC_EB;
 
-       /* Set this to 1 for now, so we get single character interrupts.
-       */
-       up->smc_mrblr = 1;              /* receive buffer length */
-       up->smc_maxidl = 0;             /* wait forever for next char */
+       up->smc_mrblr = RX_BUF_SIZE;            /* receive buffer length */
+       up->smc_maxidl = RX_BUF_SIZE;
 
        /* Send the CPM an initialize command.
        */
index 4b578da455a7104d1bbf7ab7f2b0bb8604beaefd..6acdc9a65ef861ea2427d55996d917584a027fc6 100644 (file)
@@ -22,7 +22,7 @@ ASFLAGS               =
 LINKFLAGS      = -T arch/ppc/vmlinux.lds -Ttext $(KERNELLOAD) -Bstatic
 CPPFLAGS       := $(CPPFLAGS) -D__powerpc__
 CFLAGS         := $(CFLAGS) -D__powerpc__ -fsigned-char \
-               -msoft-float -pipe -fno-builtin -ffixed-r2 -Wno-uninitialized \
+               -msoft-float -pipe -ffixed-r2 -Wno-uninitialized \
                -mmultiple -mstring
 CPP            = $(CC) -E $(CFLAGS)
 
@@ -75,6 +75,11 @@ SUBDIRS += arch/ppc/8xx_io
 DRIVERS += arch/ppc/8xx_io/8xx_io.a
 endif
 
+ifdef CONFIG_8260
+SUBDIRS += arch/ppc/8260_io
+DRIVERS += arch/ppc/8260_io/8260_io.a
+endif
+
 ifdef CONFIG_APUS
 SUBDIRS += arch/ppc/amiga
 ARCHIVES += arch/ppc/amiga/amiga.o
@@ -98,6 +103,7 @@ $(BOOT_TARGETS): $(CHECKS) vmlinux
 endif
 
 ifdef CONFIG_6xx
+ifndef CONFIG_8260
 $(BOOT_TARGETS): $(CHECKS) vmlinux
        @$(MAKECOFFBOOT) $@
        @$(MAKEBOOT) $@
@@ -114,6 +120,12 @@ endif
        @$(MAKECOFFBOOT) $@
        @$(MAKEBOOT) $@
        @$(MAKECHRPBOOT) $@
+else
+# 8260 is custom 6xx
+$(BOOT_TARGETS): $(CHECKS) vmlinux
+       @$(MAKECOFFBOOT) $@
+       @$(MAKEMBXBOOT) $@
+endif
 endif
 
 ifdef CONFIG_PPC64
index e9499fbc9cfb2b46c9aedd6b3f2ef00cc8aee0b9..7e2c47c0b18d173c540d35b6774b6eec6388c282 100644 (file)
@@ -18,9 +18,14 @@ choice 'Processor Type'      \
        "6xx/7xx/7400           CONFIG_6xx      \
         4xx                    CONFIG_4xx      \
         630/Power3(64-Bit)     CONFIG_PPC64    \
-        82xx                   CONFIG_82xx     \
+        8260                   CONFIG_8260     \
         8xx                    CONFIG_8xx"     6xx
 
+if [ "$CONFIG_8260" = "y" ]; then
+  define_bool CONFIG_6xx y
+  define_bool CONFIG_SERIAL_CONSOLE y
+fi
+
 if [ "$CONFIG_4xx" = "y" ]; then
     choice 'Machine Type'                      \
        "Oak                    CONFIG_OAK      \
@@ -49,6 +54,7 @@ if [ "$CONFIG_6xx" = "y" ]; then
   choice 'Machine Type'                \
        "PowerMac/PReP/MTX/CHRP CONFIG_ALL_PPC  \
         Gemini         CONFIG_GEMINI           \
+        EST8260        CONFIG_EST8260          \
         APUS           CONFIG_APUS"            PowerMac/PReP/MTX/CHRP
 fi
 
@@ -56,6 +62,10 @@ if [ "$CONFIG_PPC64" = "y" ]; then
   define_bool CONFIG_ALL_PPC y
 fi
 
+if [ "$CONFIG_8xx" = "y" -o "$CONFIG_8260" = "y" ]; then
+  define_bool CONFIG_ALL_PPC n
+fi
+
 bool 'Symmetric multi-processing support' CONFIG_SMP
 if [ "$CONFIG_6xx" = "y" ];then
   bool 'AltiVec Support' CONFIG_ALTIVEC
@@ -86,7 +96,7 @@ define_bool CONFIG_ISA n
 define_bool CONFIG_SBUS n
 
 if [ "$CONFIG_APUS" = "y" -o "$CONFIG_4xx" = "y" -o \
-     "$CONFIG_82xx" = "y" ]; then
+     "$CONFIG_8260" = "y" ]; then
    define_bool CONFIG_PCI n
 else
    if [ "$CONFIG_6xx" = "y" -o "$CONFIG_PPC64" = "y" ]; then
@@ -144,7 +154,6 @@ if [ "$CONFIG_4xx" != "y" -a "$CONFIG_8xx" != "y" ]; then
      bool 'Support for ADB mouse' CONFIG_ADBMOUSE
   fi
   bool 'Support for Open Firmware device tree in /proc' CONFIG_PROC_DEVICETREE
-  bool 'Support for TotalImpact TotalMP' CONFIG_TOTALMP
   bool 'Support for early boot text console (BootX only)' CONFIG_BOOTX_TEXT
   bool 'Support for Motorola Hot Swap' CONFIG_MOTOROLA_HOTSWAP
 fi
@@ -226,6 +235,8 @@ fi
 
 source net/ax25/Config.in
 
+source net/irda/Config.in
+
 mainmenu_option next_comment
 comment 'ISDN subsystem'
 
@@ -266,6 +277,10 @@ if [ "$CONFIG_8xx" = "y" ]; then
 source arch/ppc/8xx_io/Config.in
 fi
 
+if [ "$CONFIG_8260" = "y" ]; then
+source arch/ppc/8260_io/Config.in
+fi
+
 source drivers/usb/Config.in
 
 mainmenu_option next_comment
diff --git a/arch/ppc/configs/chrp_defconfig b/arch/ppc/configs/chrp_defconfig
deleted file mode 100644 (file)
index 48e305f..0000000
+++ /dev/null
@@ -1,319 +0,0 @@
-#
-# Automatically generated by make menuconfig: don't edit
-#
-
-#
-# Platform support
-#
-CONFIG_PPC=y
-CONFIG_6xx=y
-# CONFIG_8xx is not set
-# CONFIG_PMAC is not set
-# CONFIG_PREP is not set
-CONFIG_CHRP=y
-# CONFIG_ALL_PPC is not set
-# CONFIG_APUS is not set
-# CONFIG_MBX is not set
-# CONFIG_SMP is not set
-CONFIG_MACH_SPECIFIC=y
-
-#
-# General setup
-#
-CONFIG_EXPERIMENTAL=y
-CONFIG_MODULES=y
-# CONFIG_MODVERSIONS is not set
-# CONFIG_KMOD is not set
-CONFIG_PCI=y
-# CONFIG_PCI_QUIRKS is not set
-CONFIG_PCI_OLD_PROC=y
-CONFIG_NET=y
-CONFIG_SYSCTL=y
-CONFIG_SYSVIPC=y
-# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_BINFMT_ELF=y
-CONFIG_KERNEL_ELF=y
-# CONFIG_BINFMT_MISC is not set
-# CONFIG_BINFMT_JAVA is not set
-# CONFIG_PARPORT is not set
-CONFIG_FB=y
-CONFIG_FB_COMPAT_XPMAC=y
-# CONFIG_PMAC_PBOOK is not set
-CONFIG_MAC_KEYBOARD=y
-# CONFIG_MAC_FLOPPY is not set
-# CONFIG_MAC_SERIAL is not set
-# CONFIG_ADBMOUSE is not set
-CONFIG_PROC_DEVICETREE=y
-# CONFIG_KGDB is not set
-# CONFIG_XMON is not set
-# CONFIG_TOTALMP is not set
-
-#
-# Plug and Play support
-#
-# CONFIG_PNP is not set
-
-#
-# Block devices
-#
-CONFIG_BLK_DEV_FD=y
-CONFIG_BLK_DEV_IDE=y
-# CONFIG_BLK_DEV_HD_IDE is not set
-CONFIG_BLK_DEV_IDEDISK=y
-CONFIG_BLK_DEV_IDECD=y
-# CONFIG_BLK_DEV_IDETAPE is not set
-# CONFIG_BLK_DEV_IDEFLOPPY is not set
-# CONFIG_BLK_DEV_IDESCSI is not set
-# CONFIG_BLK_DEV_CMD640 is not set
-# CONFIG_BLK_DEV_RZ1000 is not set
-# CONFIG_BLK_DEV_IDEPCI is not set
-CONFIG_BLK_DEV_SL82C105=y
-# CONFIG_IDE_CHIPSETS is not set
-CONFIG_BLK_DEV_LOOP=y
-# CONFIG_BLK_DEV_NBD is not set
-# CONFIG_BLK_DEV_MD is not set
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_INITRD=y
-# CONFIG_BLK_DEV_XD is not set
-CONFIG_PARIDE_PARPORT=y
-# CONFIG_PARIDE is not set
-# CONFIG_BLK_DEV_HD is not set
-
-#
-# Networking options
-#
-# CONFIG_PACKET is not set
-# CONFIG_NETLINK is not set
-# CONFIG_FIREWALL is not set
-# CONFIG_FILTER is not set
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-# CONFIG_IP_ADVANCED_ROUTER is not set
-# CONFIG_IP_PNP is not set
-# CONFIG_IP_ROUTER is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_IP_MROUTE is not set
-CONFIG_IP_ALIAS=y
-# CONFIG_SYN_COOKIES is not set
-CONFIG_INET_RARP=y
-CONFIG_IP_NOSR=y
-CONFIG_SKB_LARGE=y
-# CONFIG_IPV6 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_LLC is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
-# CONFIG_NET_HW_FLOWCONTROL is not set
-# CONFIG_CPU_IS_SLOW is not set
-# CONFIG_NET_SCHED is not set
-
-#
-# SCSI support
-#
-CONFIG_SCSI=y
-CONFIG_BLK_DEV_SD=y
-CONFIG_CHR_DEV_ST=y
-CONFIG_BLK_DEV_SR=y
-CONFIG_BLK_DEV_SR_VENDOR=y
-CONFIG_CHR_DEV_SG=y
-# CONFIG_SCSI_MULTI_LUN is not set
-CONFIG_SCSI_CONSTANTS=y
-# CONFIG_SCSI_LOGGING is not set
-
-#
-# SCSI low-level drivers
-#
-# CONFIG_SCSI_7000FASST is not set
-# CONFIG_SCSI_AHA152X is not set
-# CONFIG_SCSI_AHA1542 is not set
-# CONFIG_SCSI_AHA1740 is not set
-# CONFIG_SCSI_AIC7XXX is not set
-# CONFIG_SCSI_ADVANSYS is not set
-# CONFIG_SCSI_IN2000 is not set
-# CONFIG_SCSI_AM53C974 is not set
-# CONFIG_SCSI_BUSLOGIC is not set
-# CONFIG_SCSI_DTC3280 is not set
-# CONFIG_SCSI_EATA_DMA is not set
-# CONFIG_SCSI_EATA_PIO is not set
-# CONFIG_SCSI_EATA is not set
-# CONFIG_SCSI_FUTURE_DOMAIN is not set
-# CONFIG_SCSI_GDTH is not set
-# CONFIG_SCSI_GENERIC_NCR5380 is not set
-# CONFIG_SCSI_NCR53C406A is not set
-# CONFIG_SCSI_NCR53C7xx is not set
-CONFIG_SCSI_NCR53C8XX=y
-CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS=8
-CONFIG_SCSI_NCR53C8XX_MAX_TAGS=4
-CONFIG_SCSI_NCR53C8XX_SYNC=5
-# CONFIG_SCSI_NCR53C8XX_PROFILE is not set
-# CONFIG_SCSI_NCR53C8XX_IOMAPPED is not set
-# CONFIG_SCSI_NCR53C8XX_SYMBIOS_COMPAT is not set
-# CONFIG_SCSI_PAS16 is not set
-# CONFIG_SCSI_PCI2000 is not set
-# CONFIG_SCSI_PCI2220I is not set
-# CONFIG_SCSI_PSI240I is not set
-# CONFIG_SCSI_QLOGIC_FAS is not set
-# CONFIG_SCSI_QLOGIC_ISP is not set
-# CONFIG_SCSI_SEAGATE is not set
-# CONFIG_SCSI_DC390T is not set
-# CONFIG_SCSI_T128 is not set
-# CONFIG_SCSI_U14_34F is not set
-# CONFIG_SCSI_ULTRASTOR is not set
-# CONFIG_SCSI_DEBUG is not set
-CONFIG_SCSI_MESH=y
-CONFIG_SCSI_MESH_SYNC_RATE=10
-CONFIG_SCSI_MAC53C94=y
-
-#
-# Network device support
-#
-CONFIG_NETDEVICES=y
-# CONFIG_ARCNET is not set
-# CONFIG_DUMMY is not set
-# CONFIG_EQUALIZER is not set
-CONFIG_NET_ETHERNET=y
-# CONFIG_MACE is not set
-# CONFIG_BMAC is not set
-# CONFIG_NET_VENDOR_3COM is not set
-# CONFIG_LANCE is not set
-# CONFIG_NET_VENDOR_SMC is not set
-# CONFIG_NET_VENDOR_RACAL is not set
-# CONFIG_RTL8139 is not set
-# CONFIG_YELLOWFIN is not set
-# CONFIG_NET_ISA is not set
-CONFIG_NET_EISA=y
-# CONFIG_PCNET32 is not set
-# CONFIG_AC3200 is not set
-# CONFIG_APRICOT is not set
-# CONFIG_CS89x0 is not set
-# CONFIG_DE4X5 is not set
-CONFIG_DEC_ELCP=y
-# CONFIG_DGRS is not set
-# CONFIG_EEXPRESS_PRO100 is not set
-# CONFIG_LNE390 is not set
-# CONFIG_NE2K_PCI is not set
-# CONFIG_TLAN is not set
-# CONFIG_ES3210 is not set
-# CONFIG_EPIC100 is not set
-# CONFIG_ZNET is not set
-# CONFIG_NET_POCKET is not set
-# CONFIG_FDDI is not set
-# CONFIG_DLCI is not set
-# CONFIG_PPP is not set
-# CONFIG_SLIP is not set
-# CONFIG_NET_RADIO is not set
-# CONFIG_TR is not set
-# CONFIG_SHAPER is not set
-
-#
-# Amateur Radio support
-#
-# CONFIG_HAMRADIO is not set
-
-#
-# ISDN subsystem
-#
-# CONFIG_ISDN is not set
-
-#
-# CD-ROM drivers (not for SCSI or IDE/ATAPI drives)
-#
-# CONFIG_CD_NO_IDESCSI is not set
-
-#
-# Console drivers
-#
-CONFIG_DUMMY_CONSOLE=y
-CONFIG_FB_OF=y
-# CONFIG_FB_CONTROL is not set
-# CONFIG_FB_PLATINUM is not set
-# CONFIG_FB_VALKYRIE is not set
-CONFIG_FB_ATY=y
-CONFIG_FB_IMSTT=y
-# CONFIG_FB_CT65550 is not set
-# CONFIG_FB_S3TRIO is not set
-CONFIG_FB_VGA=y
-# CONFIG_FB_VIRTUAL is not set
-# CONFIG_FBCON_ADVANCED is not set
-CONFIG_FBCON_CFB8=y
-CONFIG_FBCON_CFB16=y
-CONFIG_FBCON_CFB24=y
-CONFIG_FBCON_CFB32=y
-CONFIG_FBCON_VGA=y
-# CONFIG_FBCON_FONTWIDTH8_ONLY is not set
-# CONFIG_FBCON_FONTS is not set
-CONFIG_FONT_8x8=y
-CONFIG_FONT_8x16=y
-
-#
-# Character devices
-#
-CONFIG_VT=y
-CONFIG_VT_CONSOLE=y
-CONFIG_SERIAL=y
-# CONFIG_SERIAL_CONSOLE is not set
-# CONFIG_SERIAL_EXTENDED is not set
-# CONFIG_SERIAL_NONSTANDARD is not set
-# CONFIG_UNIX98_PTYS is not set
-# CONFIG_MOUSE is not set
-# CONFIG_UMISC is not set
-# CONFIG_QIC02_TAPE is not set
-# CONFIG_WATCHDOG is not set
-# CONFIG_RTC is not set
-# CONFIG_VIDEO_DEV is not set
-CONFIG_NVRAM=y
-# CONFIG_JOYSTICK is not set
-
-#
-# Ftape, the floppy tape device driver
-#
-# CONFIG_FTAPE is not set
-
-#
-# Filesystems
-#
-# CONFIG_QUOTA is not set
-# CONFIG_MINIX_FS is not set
-CONFIG_EXT2_FS=y
-CONFIG_ISO9660_FS=y
-# CONFIG_JOLIET is not set
-# CONFIG_FAT_FS is not set
-# CONFIG_MSDOS_FS is not set
-# CONFIG_UMSDOS_FS is not set
-# CONFIG_VFAT_FS is not set
-CONFIG_PROC_FS=y
-CONFIG_NFS_FS=y
-# CONFIG_NFSD is not set
-CONFIG_SUNRPC=y
-CONFIG_LOCKD=y
-# CONFIG_CODA_FS is not set
-# CONFIG_SMB_FS is not set
-# CONFIG_HPFS_FS is not set
-# CONFIG_NTFS_FS is not set
-# CONFIG_SYSV_FS is not set
-# CONFIG_AFFS_FS is not set
-CONFIG_HFS_FS=y
-# CONFIG_ROMFS_FS is not set
-# CONFIG_AUTOFS_FS is not set
-# CONFIG_UFS_FS is not set
-# CONFIG_ADFS_FS is not set
-CONFIG_MAC_PARTITION=y
-# CONFIG_NLS is not set
-
-#
-# Sound
-#
-CONFIG_SOUND=y
-# CONFIG_SOUND_ES1370 is not set
-# CONFIG_SOUND_ES1371 is not set
-# CONFIG_SOUND_SONICVIBES is not set
-# CONFIG_SOUND_MSNDCLAS is not set
-# CONFIG_SOUND_MSNDPIN is not set
-# CONFIG_SOUND_OSS is not set
index 72d8f66ee7f04c7134bd1f8e5de46513802f987b..caf15d27d93d8f4da7ccb0ee41addf25da81c3b5 100644 (file)
@@ -1,5 +1,5 @@
 #
-# Automatically generated make config: don't edit
+# Automatically generated by make menuconfig: don't edit
 #
 # CONFIG_UID16 is not set
 
@@ -33,8 +33,8 @@ CONFIG_KMOD=y
 #
 # General setup
 #
-# CONFIG_PCI is not set
-CONFIG_PCI=y
+# CONFIG_ISA is not set
+# CONFIG_SBUS is not set
 CONFIG_PCI=y
 CONFIG_NET=y
 CONFIG_SYSCTL=y
@@ -46,6 +46,7 @@ CONFIG_KERNEL_ELF=y
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_PCI_NAMES is not set
 # CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
 
 #
 # Parallel port support
@@ -57,6 +58,7 @@ CONFIG_FB_COMPAT_XPMAC=y
 CONFIG_PMAC_PBOOK=y
 CONFIG_MAC_FLOPPY=y
 CONFIG_MAC_SERIAL=y
+# CONFIG_SERIAL_CONSOLE is not set
 CONFIG_ADB=y
 CONFIG_ADB_CUDA=y
 CONFIG_ADB_MACIO=y
@@ -64,7 +66,6 @@ CONFIG_ADB_PMU=y
 CONFIG_ADB_KEYBOARD=y
 CONFIG_ADBMOUSE=y
 CONFIG_PROC_DEVICETREE=y
-# CONFIG_TOTALMP is not set
 CONFIG_BOOTX_TEXT=y
 # CONFIG_MOTOROLA_HOTSWAP is not set
 # CONFIG_CMDLINE_BOOL is not set
@@ -73,21 +74,22 @@ CONFIG_BOOTX_TEXT=y
 # Plug and Play configuration
 #
 # CONFIG_PNP is not set
+# CONFIG_ISAPNP is not set
 
 #
 # Block devices
 #
 # CONFIG_BLK_DEV_FD is not set
 # CONFIG_BLK_DEV_XD is not set
+# CONFIG_PARIDE is not set
 # CONFIG_BLK_CPQ_DA is not set
 # CONFIG_BLK_DEV_DAC960 is not set
-
-#
-# Additional Block Devices
-#
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_LVM is not set
 # CONFIG_BLK_DEV_MD is not set
+# CONFIG_MD_LINEAR is not set
+# CONFIG_MD_STRIPED is not set
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_INITRD=y
 
@@ -112,18 +114,10 @@ CONFIG_IP_MULTICAST=y
 # CONFIG_IP_MROUTE is not set
 CONFIG_IP_ALIAS=y
 CONFIG_SYN_COOKIES=y
-
-#
-# (it is safe to leave these untouched)
-#
 CONFIG_SKB_LARGE=y
 # CONFIG_IPV6 is not set
 # CONFIG_KHTTPD is not set
 # CONFIG_ATM is not set
-
-#
-#  
-#
 # CONFIG_IPX is not set
 CONFIG_ATALK=m
 # CONFIG_DECNET is not set
@@ -150,35 +144,52 @@ CONFIG_IDE=y
 # IDE, ATA and ATAPI Block devices
 #
 CONFIG_BLK_DEV_IDE=y
-
-#
-# Please see Documentation/ide.txt for help/info on IDE drives
-#
 # CONFIG_BLK_DEV_HD_IDE is not set
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_BLK_DEV_IDEDISK=y
 # CONFIG_IDEDISK_MULTI_MODE is not set
+# CONFIG_BLK_DEV_IDECS is not set
 CONFIG_BLK_DEV_IDECD=y
 # CONFIG_BLK_DEV_IDETAPE is not set
 # CONFIG_BLK_DEV_IDEFLOPPY is not set
 CONFIG_BLK_DEV_IDESCSI=y
-
-#
-# IDE chipset support/bugfixes
-#
 # CONFIG_BLK_DEV_CMD640 is not set
+# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
+# CONFIG_BLK_DEV_ISAPNP is not set
 # CONFIG_BLK_DEV_RZ1000 is not set
 CONFIG_BLK_DEV_IDEPCI=y
 # CONFIG_IDEPCI_SHARE_IRQ is not set
 # CONFIG_BLK_DEV_IDEDMA_PCI is not set
 # CONFIG_BLK_DEV_OFFBOARD is not set
+# CONFIG_IDEDMA_PCI_AUTO is not set
 # CONFIG_BLK_DEV_IDEDMA is not set
 CONFIG_IDEDMA_PCI_EXPERIMENTAL=y
+# CONFIG_IDEDMA_PCI_WIP is not set
+# CONFIG_IDEDMA_NEW_DRIVE_LISTINGS is not set
+# CONFIG_BLK_DEV_AEC62XX is not set
+# CONFIG_AEC62XX_TUNING is not set
+# CONFIG_BLK_DEV_ALI15X3 is not set
+# CONFIG_WDC_ALI15X3 is not set
+# CONFIG_BLK_DEV_AMD7409 is not set
+# CONFIG_AMD7409_OVERRIDE is not set
+# CONFIG_BLK_DEV_CMD64X is not set
+# CONFIG_CMD64X_RAID is not set
 # CONFIG_BLK_DEV_CY82C693 is not set
+# CONFIG_BLK_DEV_CS5530 is not set
+# CONFIG_BLK_DEV_HPT34X is not set
+# CONFIG_HPT34X_AUTODMA is not set
+# CONFIG_BLK_DEV_HPT366 is not set
+# CONFIG_HPT366_FIP is not set
+# CONFIG_HPT366_MODE3 is not set
 # CONFIG_BLK_DEV_NS87415 is not set
 # CONFIG_BLK_DEV_OPTI621 is not set
+# CONFIG_BLK_DEV_PDC202XX is not set
+# CONFIG_PDC202XX_BURST is not set
+# CONFIG_PDC202XX_MASTER is not set
+# CONFIG_BLK_DEV_SIS5513 is not set
 # CONFIG_BLK_DEV_TRM290 is not set
 # CONFIG_BLK_DEV_VIA82CXXX is not set
+# CONFIG_VIA82CXXX_TUNING is not set
 # CONFIG_BLK_DEV_SL82C105 is not set
 CONFIG_BLK_DEV_IDE_PMAC=y
 CONFIG_BLK_DEV_IDEDMA_PMAC=y
@@ -192,10 +203,6 @@ CONFIG_BLK_DEV_IDE_MODES=y
 # SCSI support
 #
 CONFIG_SCSI=y
-
-#
-# SCSI support type (disk, tape, CD-ROM)
-#
 CONFIG_BLK_DEV_SD=y
 CONFIG_SD_EXTRA_DEVS=40
 CONFIG_CHR_DEV_ST=y
@@ -203,10 +210,6 @@ CONFIG_BLK_DEV_SR=y
 CONFIG_BLK_DEV_SR_VENDOR=y
 CONFIG_SR_EXTRA_DEVS=2
 CONFIG_CHR_DEV_SG=y
-
-#
-# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
-#
 # CONFIG_SCSI_DEBUG_QUEUES is not set
 # CONFIG_SCSI_MULTI_LUN is not set
 CONFIG_SCSI_CONSTANTS=y
@@ -226,12 +229,12 @@ CONFIG_SCSI_AIC7XXX=y
 CONFIG_AIC7XXX_CMDS_PER_DEVICE=8
 CONFIG_AIC7XXX_PROC_STATS=y
 CONFIG_AIC7XXX_RESET_DELAY=15
-# CONFIG_SCSI_IPS is not set
 # CONFIG_SCSI_ADVANSYS is not set
 # CONFIG_SCSI_IN2000 is not set
 # CONFIG_SCSI_AM53C974 is not set
 # CONFIG_SCSI_MEGARAID is not set
 # CONFIG_SCSI_BUSLOGIC is not set
+# CONFIG_SCSI_DMX3191D is not set
 # CONFIG_SCSI_DTC3280 is not set
 # CONFIG_SCSI_EATA is not set
 # CONFIG_SCSI_EATA_DMA is not set
@@ -262,11 +265,9 @@ CONFIG_SCSI_NCR53C8XX_SYNC=20
 # CONFIG_SCSI_QLOGIC_ISP is not set
 # CONFIG_SCSI_QLOGIC_FC is not set
 # CONFIG_SCSI_QLOGIC_1280 is not set
-# CONFIG_SCSI_SEAGATE is not set
 # CONFIG_SCSI_DC390T is not set
 # CONFIG_SCSI_T128 is not set
 # CONFIG_SCSI_U14_34F is not set
-# CONFIG_SCSI_ULTRASTOR is not set
 # CONFIG_SCSI_DEBUG is not set
 CONFIG_SCSI_MESH=y
 CONFIG_SCSI_MESH_SYNC_RATE=5
@@ -345,6 +346,7 @@ CONFIG_DE4X5=y
 # CONFIG_FDDI is not set
 # CONFIG_HIPPI is not set
 CONFIG_PPP=y
+# CONFIG_PPP_MULTILINK is not set
 # CONFIG_PPP_ASYNC is not set
 # CONFIG_PPP_SYNC_TTY is not set
 # CONFIG_PPP_DEFLATE is not set
@@ -483,59 +485,9 @@ CONFIG_NVRAM=y
 #
 # CONFIG_FTAPE is not set
 # CONFIG_DRM is not set
+# CONFIG_DRM_TDFX is not set
 # CONFIG_AGP is not set
 
-#
-# USB support
-#
-CONFIG_USB=y
-
-#
-# USB Controllers
-#
-# CONFIG_USB_UHCI is not set
-# CONFIG_USB_UHCI_ALT is not set
-CONFIG_USB_OHCI=y
-
-#
-# Miscellaneous USB options
-#
-# CONFIG_USB_DEVICEFS is not set
-
-#
-# USB Devices
-#
-# CONFIG_USB_PRINTER is not set
-# CONFIG_USB_SCANNER is not set
-# CONFIG_USB_AUDIO is not set
-# CONFIG_USB_ACM is not set
-# CONFIG_USB_SERIAL is not set
-# CONFIG_USB_CPIA is not set
-# CONFIG_USB_IBMCAM is not set
-# CONFIG_USB_OV511 is not set
-# CONFIG_USB_DC2XX is not set
-# CONFIG_USB_STORAGE is not set
-# CONFIG_USB_DABUSB is not set
-# CONFIG_USB_PLUSB is not set
-# CONFIG_USB_PEGASUS is not set
-# CONFIG_USB_RIO500 is not set
-# CONFIG_USB_DSBR is not set
-
-#
-# USB HID
-#
-# CONFIG_USB_HID is not set
-CONFIG_USB_KBD=y
-CONFIG_USB_MOUSE=y
-# CONFIG_USB_WACOM is not set
-# CONFIG_USB_WMFORCE is not set
-CONFIG_INPUT_KEYBDEV=y
-CONFIG_INPUT_MOUSEDEV=y
-# CONFIG_INPUT_MOUSEDEV_MIX is not set
-# CONFIG_INPUT_MOUSEDEV_DIGITIZER is not set
-# CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_EVDEV is not set
-
 #
 # File systems
 #
@@ -543,6 +495,7 @@ CONFIG_INPUT_MOUSEDEV=y
 CONFIG_AUTOFS_FS=y
 # CONFIG_AUTOFS4_FS is not set
 # CONFIG_ADFS_FS is not set
+# CONFIG_ADFS_FS_RW is not set
 # CONFIG_AFFS_FS is not set
 CONFIG_HFS_FS=y
 # CONFIG_BFS_FS is not set
@@ -552,32 +505,51 @@ CONFIG_MSDOS_FS=y
 CONFIG_VFAT_FS=y
 # CONFIG_EFS_FS is not set
 # CONFIG_CRAMFS is not set
+# CONFIG_RAMFS is not set
 CONFIG_ISO9660_FS=y
 # CONFIG_JOLIET is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_NTFS_FS is not set
+# CONFIG_NTFS_RW is not set
 # CONFIG_HPFS_FS is not set
 CONFIG_PROC_FS=y
 # CONFIG_DEVFS_FS is not set
+# CONFIG_DEVFS_DEBUG is not set
 CONFIG_DEVPTS_FS=y
 # CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX4FS_RW is not set
 # CONFIG_ROMFS_FS is not set
 CONFIG_EXT2_FS=y
 # CONFIG_SYSV_FS is not set
+# CONFIG_SYSV_FS_WRITE is not set
 # CONFIG_UDF_FS is not set
+# CONFIG_UDF_RW is not set
 # CONFIG_UFS_FS is not set
+# CONFIG_UFS_FS_WRITE is not set
 
 #
 # Network File Systems
 #
 # CONFIG_CODA_FS is not set
 CONFIG_NFS_FS=y
+# CONFIG_NFS_V3 is not set
+# CONFIG_ROOT_NFS is not set
 CONFIG_NFSD=y
 # CONFIG_NFSD_V3 is not set
 CONFIG_SUNRPC=y
 CONFIG_LOCKD=y
 # CONFIG_SMB_FS is not set
 # CONFIG_NCP_FS is not set
+# CONFIG_NCPFS_PACKET_SIGNING is not set
+# CONFIG_NCPFS_IOCTL_LOCKING is not set
+# CONFIG_NCPFS_STRONG is not set
+# CONFIG_NCPFS_NFS_NS is not set
+# CONFIG_NCPFS_OS2_NS is not set
+# CONFIG_NCPFS_SMALLDOS is not set
+# CONFIG_NCPFS_MOUNT_SUBDIR is not set
+# CONFIG_NCPFS_NDS_DOMAINS is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_NCPFS_EXTRAS is not set
 
 #
 # Partition Types
@@ -632,6 +604,7 @@ CONFIG_NLS=y
 # Sound
 #
 CONFIG_SOUND=y
+CONFIG_DMASOUND_AWACS=y
 CONFIG_DMASOUND=y
 # CONFIG_SOUND_CMPCI is not set
 # CONFIG_SOUND_ES1370 is not set
@@ -652,6 +625,7 @@ CONFIG_SOUND_OSS=y
 CONFIG_SOUND_CS4232=m
 # CONFIG_SOUND_SSCAPE is not set
 # CONFIG_SOUND_GUS is not set
+# CONFIG_SOUND_ICH is not set
 # CONFIG_SOUND_VMIDI is not set
 # CONFIG_SOUND_TRIX is not set
 # CONFIG_SOUND_MSS is not set
@@ -659,6 +633,7 @@ CONFIG_SOUND_CS4232=m
 # CONFIG_SOUND_NM256 is not set
 # CONFIG_SOUND_MAD16 is not set
 # CONFIG_SOUND_PAS is not set
+# CONFIG_PAS_JOYSTICK is not set
 # CONFIG_SOUND_PSS is not set
 # CONFIG_SOUND_SOFTOSS is not set
 # CONFIG_SOUND_SB is not set
@@ -672,6 +647,41 @@ CONFIG_SOUND_CS4232=m
 # CONFIG_SOUND_UART6850 is not set
 # CONFIG_SOUND_AEDSP16 is not set
 
+#
+# USB support
+#
+CONFIG_USB=y
+CONFIG_USB_DEBUG=y
+# CONFIG_USB_DEVICEFS is not set
+# CONFIG_USB_UHCI is not set
+# CONFIG_USB_UHCI_ALT is not set
+CONFIG_USB_OHCI=y
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_SCANNER is not set
+# CONFIG_USB_AUDIO is not set
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_SERIAL is not set
+# CONFIG_USB_IBMCAM is not set
+# CONFIG_USB_OV511 is not set
+# CONFIG_USB_DC2XX is not set
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_STORAGE is not set
+# CONFIG_USB_USS720 is not set
+# CONFIG_USB_DABUSB is not set
+# CONFIG_USB_PLUSB is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_DSBR is not set
+CONFIG_USB_HID=y
+# CONFIG_USB_WACOM is not set
+# CONFIG_USB_WMFORCE is not set
+CONFIG_INPUT_KEYBDEV=y
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+
 #
 # Kernel hacking
 #
diff --git a/arch/ppc/configs/pmac_defconfig b/arch/ppc/configs/pmac_defconfig
deleted file mode 100644 (file)
index e2b7c31..0000000
+++ /dev/null
@@ -1,550 +0,0 @@
-#
-# Automatically generated make config: don't edit
-#
-
-#
-# Platform support
-#
-CONFIG_PPC=y
-CONFIG_6xx=y
-# CONFIG_PPC64 is not set
-# CONFIG_82xx is not set
-# CONFIG_8xx is not set
-CONFIG_PMAC=y
-# CONFIG_PREP is not set
-# CONFIG_CHRP is not set
-# CONFIG_ALL_PPC is not set
-# CONFIG_GEMINI is not set
-# CONFIG_APUS is not set
-# CONFIG_SMP is not set
-CONFIG_MACH_SPECIFIC=y
-CONFIG_6xx=y
-
-#
-# General setup
-#
-CONFIG_EXPERIMENTAL=y
-CONFIG_MODULES=y
-# CONFIG_MODVERSIONS is not set
-CONFIG_KMOD=y
-CONFIG_PCI=y
-CONFIG_NET=y
-CONFIG_SYSCTL=y
-CONFIG_SYSVIPC=y
-# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_BINFMT_ELF=y
-CONFIG_KERNEL_ELF=y
-CONFIG_BINFMT_MISC=m
-CONFIG_HOTPLUG=y
-
-#
-# PCMCIA/Cardbus support
-#
-CONFIG_PCMCIA=m
-CONFIG_CARDBUS=y
-# CONFIG_PARPORT is not set
-# CONFIG_VGA_CONSOLE is not set
-CONFIG_FB=y
-CONFIG_FB_COMPAT_XPMAC=y
-CONFIG_PMAC_PBOOK=y
-CONFIG_MAC_FLOPPY=y
-CONFIG_MAC_SERIAL=y
-# CONFIG_SERIAL_CONSOLE is not set
-CONFIG_ADB=y
-CONFIG_ADB_CUDA=y
-CONFIG_ADB_MACIO=y
-CONFIG_ADB_PMU=y
-CONFIG_ADB_KEYBOARD=y
-CONFIG_PROC_DEVICETREE=y
-# CONFIG_TOTALMP is not set
-CONFIG_BOOTX_TEXT=y
-# CONFIG_MOTOROLA_HOTSWAP is not set
-
-#
-# Plug and Play configuration
-#
-# CONFIG_PNP is not set
-# CONFIG_ISAPNP is not set
-
-#
-# Block devices
-#
-# CONFIG_BLK_DEV_FD is not set
-CONFIG_BLK_DEV_IDE=y
-
-#
-# Please see Documentation/ide.txt for help/info on IDE drives
-#
-# CONFIG_BLK_DEV_HD_IDE is not set
-CONFIG_BLK_DEV_IDEDISK=y
-# CONFIG_IDEDISK_MULTI_MODE is not set
-CONFIG_BLK_DEV_IDECD=y
-# CONFIG_BLK_DEV_IDETAPE is not set
-CONFIG_BLK_DEV_IDEFLOPPY=y
-# CONFIG_BLK_DEV_IDESCSI is not set
-
-#
-# IDE chipset support/bugfixes
-#
-# CONFIG_BLK_DEV_CMD640 is not set
-# CONFIG_BLK_DEV_RZ1000 is not set
-CONFIG_BLK_DEV_IDEPCI=y
-CONFIG_BLK_DEV_IDEDMA_PCI=y
-CONFIG_IDEDMA_PCI_AUTO=y
-CONFIG_IDEDMA_NEW_DRIVE_LISTINGS=y
-CONFIG_IDEDMA_PCI_EXPERIMENTAL=y
-# CONFIG_BLK_DEV_OFFBOARD is not set
-# CONFIG_BLK_DEV_AEC6210 is not set
-CONFIG_BLK_DEV_CMD646=y
-# CONFIG_BLK_DEV_CY82C693 is not set
-# CONFIG_BLK_DEV_HPT34X is not set
-# CONFIG_BLK_DEV_HPT366 is not set
-# CONFIG_BLK_DEV_NS87415 is not set
-# CONFIG_BLK_DEV_OPTI621 is not set
-# CONFIG_BLK_DEV_PDC202XX is not set
-# CONFIG_BLK_DEV_TRM290 is not set
-# CONFIG_BLK_DEV_SL82C105 is not set
-CONFIG_BLK_DEV_IDE_PMAC=y
-CONFIG_BLK_DEV_IDEDMA_PMAC=y
-CONFIG_IDEDMA_PMAC_AUTO=y
-CONFIG_BLK_DEV_IDEDMA=y
-CONFIG_IDEDMA_AUTO=y
-# CONFIG_IDE_CHIPSETS is not set
-# CONFIG_BLK_CPQ_DA is not set
-
-#
-# Additional Block Devices
-#
-CONFIG_BLK_DEV_LOOP=y
-# CONFIG_BLK_DEV_NBD is not set
-# CONFIG_BLK_DEV_MD is not set
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_INITRD=y
-# CONFIG_BLK_DEV_XD is not set
-CONFIG_PARIDE_PARPORT=y
-# CONFIG_PARIDE is not set
-CONFIG_BLK_DEV_IDE_MODES=y
-# CONFIG_BLK_DEV_HD is not set
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
-CONFIG_NETLINK=y
-# CONFIG_RTNETLINK is not set
-# CONFIG_NETLINK_DEV is not set
-CONFIG_NETFILTER=y
-# CONFIG_NETFILTER_DEBUG is not set
-# CONFIG_FILTER is not set
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-# CONFIG_IP_ADVANCED_ROUTER is not set
-# CONFIG_IP_PNP is not set
-# CONFIG_IP_ROUTER is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_IP_MROUTE is not set
-CONFIG_IP_ALIAS=y
-# CONFIG_SYN_COOKIES is not set
-
-#
-# (it is safe to leave these untouched)
-#
-CONFIG_SKB_LARGE=y
-# CONFIG_IPV6 is not set
-# CONFIG_KHTTPD is not set
-# CONFIG_ATM is not set
-
-#
-#  
-#
-# CONFIG_IPX is not set
-CONFIG_ATALK=m
-# CONFIG_DECNET is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_LLC is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
-# CONFIG_NET_HW_FLOWCONTROL is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-
-#
-# SCSI support
-#
-CONFIG_SCSI=y
-
-#
-# SCSI support type (disk, tape, CD-ROM)
-#
-CONFIG_BLK_DEV_SD=y
-CONFIG_CHR_DEV_ST=y
-CONFIG_BLK_DEV_SR=y
-CONFIG_BLK_DEV_SR_VENDOR=y
-# CONFIG_CHR_DEV_SG is not set
-
-#
-# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
-#
-# CONFIG_SCSI_MULTI_LUN is not set
-CONFIG_SCSI_CONSTANTS=y
-# CONFIG_SCSI_LOGGING is not set
-
-#
-# SCSI low-level drivers
-#
-# CONFIG_SCSI_7000FASST is not set
-# CONFIG_SCSI_ACARD is not set
-# CONFIG_SCSI_AHA152X is not set
-# CONFIG_SCSI_AHA1542 is not set
-# CONFIG_SCSI_AHA1740 is not set
-CONFIG_SCSI_AIC7XXX=y
-# CONFIG_AIC7XXX_TCQ_ON_BY_DEFAULT is not set
-CONFIG_AIC7XXX_CMDS_PER_DEVICE=8
-CONFIG_AIC7XXX_PROC_STATS=y
-CONFIG_AIC7XXX_RESET_DELAY=15
-# CONFIG_SCSI_IPS is not set
-# CONFIG_SCSI_ADVANSYS is not set
-# CONFIG_SCSI_IN2000 is not set
-# CONFIG_SCSI_AM53C974 is not set
-# CONFIG_SCSI_MEGARAID is not set
-# CONFIG_SCSI_BUSLOGIC is not set
-# CONFIG_SCSI_DTC3280 is not set
-# CONFIG_SCSI_EATA is not set
-# CONFIG_SCSI_EATA_DMA is not set
-# CONFIG_SCSI_EATA_PIO is not set
-# CONFIG_SCSI_FUTURE_DOMAIN is not set
-# CONFIG_SCSI_GDTH is not set
-# CONFIG_SCSI_GENERIC_NCR5380 is not set
-# CONFIG_SCSI_INITIO is not set
-# CONFIG_SCSI_INIA100 is not set
-# CONFIG_SCSI_NCR53C406A is not set
-# CONFIG_SCSI_SYM53C416 is not set
-# CONFIG_SCSI_NCR53C7xx is not set
-# CONFIG_SCSI_NCR53C8XX is not set
-# CONFIG_SCSI_SYM53C8XX is not set
-# CONFIG_SCSI_PAS16 is not set
-# CONFIG_SCSI_PCI2000 is not set
-# CONFIG_SCSI_PCI2220I is not set
-# CONFIG_SCSI_PSI240I is not set
-# CONFIG_SCSI_QLOGIC_FAS is not set
-# CONFIG_SCSI_QLOGIC_ISP is not set
-# CONFIG_SCSI_QLOGIC_FC is not set
-# CONFIG_SCSI_SEAGATE is not set
-# CONFIG_SCSI_DC390T is not set
-# CONFIG_SCSI_T128 is not set
-# CONFIG_SCSI_U14_34F is not set
-# CONFIG_SCSI_ULTRASTOR is not set
-# CONFIG_SCSI_DEBUG is not set
-CONFIG_SCSI_MESH=y
-CONFIG_SCSI_MESH_SYNC_RATE=5
-CONFIG_SCSI_MAC53C94=y
-
-#
-# Network device support
-#
-CONFIG_NETDEVICES=y
-
-#
-# ARCnet devices
-#
-# CONFIG_ARCNET is not set
-# CONFIG_DUMMY is not set
-# CONFIG_EQUALIZER is not set
-# CONFIG_ETHERTAP is not set
-# CONFIG_NET_SB1000 is not set
-
-#
-# Ethernet (10 or 100Mbit)
-#
-CONFIG_NET_ETHERNET=y
-CONFIG_MACE=y
-CONFIG_BMAC=y
-# CONFIG_NET_VENDOR_3COM is not set
-# CONFIG_LANCE is not set
-# CONFIG_NET_VENDOR_SMC is not set
-# CONFIG_NET_VENDOR_RACAL is not set
-# CONFIG_YELLOWFIN is not set
-# CONFIG_RTL8139 is not set
-# CONFIG_SIS900 is not set
-# CONFIG_DM9102 is not set
-# CONFIG_AT1700 is not set
-# CONFIG_DEPCA is not set
-# CONFIG_NET_ISA is not set
-CONFIG_NET_EISA=y
-# CONFIG_PCNET32 is not set
-# CONFIG_ACENIC is not set
-# CONFIG_AC3200 is not set
-# CONFIG_APRICOT is not set
-# CONFIG_CS89x0 is not set
-CONFIG_DE4X5=y
-# CONFIG_DEC_ELCP is not set
-# CONFIG_DGRS is not set
-# CONFIG_EEXPRESS_PRO100 is not set
-# CONFIG_LNE390 is not set
-# CONFIG_NE3210 is not set
-# CONFIG_NE2K_PCI is not set
-# CONFIG_TLAN is not set
-# CONFIG_VIA_RHINE is not set
-# CONFIG_ES3210 is not set
-# CONFIG_EPIC100 is not set
-# CONFIG_ZNET is not set
-# CONFIG_NET_POCKET is not set
-# CONFIG_FDDI is not set
-# CONFIG_HIPPI is not set
-
-#
-# Appletalk devices
-#
-# CONFIG_LTPC is not set
-# CONFIG_COPS is not set
-# CONFIG_IPDDP is not set
-CONFIG_PPP=y
-CONFIG_PPP_ASYNC=y
-CONFIG_PPP_DEFLATE=y
-CONFIG_PPP_BSDCOMP=m
-# CONFIG_SLIP is not set
-
-#
-# Wireless LAN (non-hamradio)
-#
-# CONFIG_NET_RADIO is not set
-
-#
-# Token Ring driver support
-#
-# CONFIG_TR is not set
-# CONFIG_NET_FC is not set
-# CONFIG_RCPCI is not set
-# CONFIG_SHAPER is not set
-
-#
-# Wan interfaces
-#
-# CONFIG_WAN is not set
-
-#
-# PCMCIA network devices
-#
-# CONFIG_PCMCIA_PCNET is not set
-# CONFIG_PCMCIA_3C589 is not set
-# CONFIG_PCMCIA_RAYCS is not set
-
-#
-# Amateur Radio support
-#
-# CONFIG_HAMRADIO is not set
-
-#
-# ISDN subsystem
-#
-# CONFIG_ISDN is not set
-
-#
-# Old CD-ROM drivers (not SCSI, not IDE)
-#
-# CONFIG_CD_NO_IDESCSI is not set
-
-#
-# Console drivers
-#
-
-#
-# Frame-buffer support
-#
-CONFIG_FB=y
-CONFIG_DUMMY_CONSOLE=y
-# CONFIG_FB_CLGEN is not set
-# CONFIG_FB_PM2 is not set
-CONFIG_FB_OF=y
-CONFIG_FB_CONTROL=y
-CONFIG_FB_PLATINUM=y
-CONFIG_FB_VALKYRIE=y
-CONFIG_FB_IMSTT=y
-CONFIG_FB_CT65550=y
-# CONFIG_FB_S3TRIO is not set
-# CONFIG_FB_VGA16 is not set
-# CONFIG_FB_MATROX is not set
-CONFIG_FB_ATY=y
-# CONFIG_FB_3DFX is not set
-# CONFIG_FB_VIRTUAL is not set
-# CONFIG_FBCON_ADVANCED is not set
-CONFIG_FBCON_CFB8=y
-CONFIG_FBCON_CFB16=y
-CONFIG_FBCON_CFB24=y
-CONFIG_FBCON_CFB32=y
-# CONFIG_FBCON_FONTWIDTH8_ONLY is not set
-CONFIG_FBCON_FONTS=y
-# CONFIG_FONT_8x8 is not set
-CONFIG_FONT_8x16=y
-CONFIG_FONT_SUN8x16=y
-CONFIG_FONT_SUN12x22=y
-# CONFIG_FONT_6x11 is not set
-# CONFIG_FONT_PEARL_8x8 is not set
-# CONFIG_FONT_ACORN_8x8 is not set
-
-#
-# Character devices
-#
-CONFIG_VT=y
-CONFIG_VT_CONSOLE=y
-CONFIG_SERIAL=m
-# CONFIG_SERIAL_EXTENDED is not set
-# CONFIG_SERIAL_NONSTANDARD is not set
-CONFIG_UNIX98_PTYS=y
-CONFIG_UNIX98_PTY_COUNT=256
-
-#
-# Mice
-#
-CONFIG_BUSMOUSE=y
-# CONFIG_ATIXL_BUSMOUSE is not set
-# CONFIG_LOGIBUSMOUSE is not set
-# CONFIG_MS_BUSMOUSE is not set
-CONFIG_ADBMOUSE=y
-# CONFIG_MOUSE is not set
-# CONFIG_QIC02_TAPE is not set
-# CONFIG_WATCHDOG is not set
-CONFIG_NVRAM=y
-# CONFIG_RTC is not set
-
-#
-# Video For Linux
-#
-# CONFIG_VIDEO_DEV is not set
-
-#
-# Joystick support
-#
-# CONFIG_JOYSTICK is not set
-# CONFIG_DTLK is not set
-# CONFIG_R3964 is not set
-# CONFIG_APPLICOM is not set
-
-#
-# Ftape, the floppy tape device driver
-#
-# CONFIG_FTAPE is not set
-# CONFIG_DRM is not set
-
-#
-# USB drivers - not for the faint of heart
-#
-CONFIG_USB=y
-
-#
-# USB Controllers
-#
-# CONFIG_USB_UHCI is not set
-CONFIG_USB_OHCI=y
-CONFIG_USB_OHCI_DEBUG=y
-# CONFIG_USB_OHCI_HCD is not set
-
-#
-# Miscellaneous USB options
-#
-CONFIG_USB_DEBUG_ISOC=y
-CONFIG_USB_PROC=y
-# CONFIG_USB_EZUSB is not set
-
-#
-# USB Devices
-#
-CONFIG_USB_HUB=y
-CONFIG_USB_MOUSE=y
-CONFIG_USB_HP_SCANNER=m
-CONFIG_USB_KBD=y
-# CONFIG_USB_AUDIO is not set
-# CONFIG_USB_ACM is not set
-# CONFIG_USB_PRINTER is not set
-# CONFIG_USB_SERIAL is not set
-# CONFIG_USB_CPIA is not set
-CONFIG_USB_SCSI=m
-CONFIG_USB_SCSI_DEBUG=y
-# CONFIG_USB_USS720 is not set
-
-#
-# Filesystems
-#
-# CONFIG_QUOTA is not set
-CONFIG_AUTOFS_FS=y
-# CONFIG_ADFS_FS is not set
-# CONFIG_AFFS_FS is not set
-# CONFIG_HFS_FS is not set
-# CONFIG_FAT_FS is not set
-# CONFIG_MSDOS_FS is not set
-# CONFIG_UMSDOS_FS is not set
-# CONFIG_VFAT_FS is not set
-# CONFIG_EFS_FS is not set
-CONFIG_ISO9660_FS=y
-# CONFIG_JOLIET is not set
-# CONFIG_UDF_FS is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_NTFS_FS is not set
-# CONFIG_HPFS_FS is not set
-CONFIG_PROC_FS=y
-CONFIG_DEVPTS_FS=y
-# CONFIG_QNX4FS_FS is not set
-# CONFIG_ROMFS_FS is not set
-CONFIG_EXT2_FS=y
-# CONFIG_SYSV_FS is not set
-# CONFIG_UFS_FS is not set
-
-#
-# Network File Systems
-#
-# CONFIG_CODA_FS is not set
-CONFIG_NFS_FS=y
-CONFIG_NFSD=y
-# CONFIG_NFSD_SUN is not set
-CONFIG_SUNRPC=y
-CONFIG_LOCKD=y
-# CONFIG_SMB_FS is not set
-# CONFIG_NCP_FS is not set
-
-#
-# Partition Types
-#
-CONFIG_PARTITION_ADVANCED=y
-# CONFIG_OSF_PARTITION is not set
-CONFIG_MAC_PARTITION=y
-CONFIG_MSDOS_PARTITION=y
-# CONFIG_BSD_DISKLABEL is not set
-# CONFIG_SOLARIS_X86_PARTITION is not set
-# CONFIG_UNIXWARE_DISKLABEL is not set
-# CONFIG_SGI_PARTITION is not set
-# CONFIG_SUN_PARTITION is not set
-# CONFIG_AMIGA_PARTITION is not set
-# CONFIG_ATARI_PARTITION is not set
-# CONFIG_ACORN_PARTITION is not set
-# CONFIG_NLS is not set
-
-#
-# Sound
-#
-CONFIG_SOUND=y
-CONFIG_DMASOUND=y
-# CONFIG_SOUND_CMPCI is not set
-# CONFIG_SOUND_ES1370 is not set
-# CONFIG_SOUND_ES1371 is not set
-# CONFIG_SOUND_ESSSOLO1 is not set
-# CONFIG_SOUND_MAESTRO is not set
-# CONFIG_SOUND_SONICVIBES is not set
-# CONFIG_SOUND_MSNDCLAS is not set
-# CONFIG_SOUND_MSNDPIN is not set
-# CONFIG_SOUND_OSS is not set
-
-#
-# Kernel hacking
-#
-CONFIG_MAGIC_SYSRQ=y
-# CONFIG_KGDB is not set
-# CONFIG_XMON is not set
diff --git a/arch/ppc/configs/prep_defconfig b/arch/ppc/configs/prep_defconfig
deleted file mode 100644 (file)
index 01c314c..0000000
+++ /dev/null
@@ -1,361 +0,0 @@
-#
-# Automatically generated by make menuconfig: don't edit
-#
-
-#
-# Platform support
-#
-CONFIG_PPC=y
-CONFIG_6xx=y
-# CONFIG_8xx is not set
-# CONFIG_PMAC is not set
-CONFIG_PREP=y
-# CONFIG_CHRP is not set
-# CONFIG_ALL_PPC is not set
-# CONFIG_APUS is not set
-# CONFIG_MBX is not set
-# CONFIG_SMP is not set
-CONFIG_MACH_SPECIFIC=y
-
-#
-# General setup
-#
-CONFIG_EXPERIMENTAL=y
-CONFIG_MODULES=y
-CONFIG_MODVERSIONS=y
-CONFIG_KMOD=y
-CONFIG_PCI=y
-# CONFIG_PCI_QUIRKS is not set
-CONFIG_PCI_OLD_PROC=y
-CONFIG_NET=y
-CONFIG_SYSCTL=y
-CONFIG_SYSVIPC=y
-# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_BINFMT_ELF=y
-CONFIG_KERNEL_ELF=y
-# CONFIG_BINFMT_MISC is not set
-# CONFIG_BINFMT_JAVA is not set
-# CONFIG_PARPORT is not set
-# CONFIG_FB is not set
-CONFIG_VGA_CONSOLE=y
-# CONFIG_PMAC_PBOOK is not set
-# CONFIG_MAC_KEYBOARD is not set
-# CONFIG_MAC_FLOPPY is not set
-# CONFIG_MAC_SERIAL is not set
-# CONFIG_ADBMOUSE is not set
-# CONFIG_PROC_DEVICETREE is not set
-# CONFIG_KGDB is not set
-# CONFIG_XMON is not set
-
-#
-# Plug and Play support
-#
-# CONFIG_PNP is not set
-
-#
-# Block devices
-#
-CONFIG_BLK_DEV_FD=y
-CONFIG_BLK_DEV_IDE=y
-# CONFIG_BLK_DEV_HD_IDE is not set
-CONFIG_BLK_DEV_IDEDISK=y
-CONFIG_BLK_DEV_IDECD=y
-# CONFIG_BLK_DEV_IDETAPE is not set
-# CONFIG_BLK_DEV_IDEFLOPPY is not set
-# CONFIG_BLK_DEV_IDESCSI is not set
-# CONFIG_BLK_DEV_CMD640 is not set
-# CONFIG_BLK_DEV_RZ1000 is not set
-# CONFIG_BLK_DEV_IDEPCI is not set
-# CONFIG_BLK_DEV_SL82C105 is not set
-# CONFIG_IDE_CHIPSETS is not set
-CONFIG_BLK_DEV_LOOP=y
-# CONFIG_BLK_DEV_NBD is not set
-# CONFIG_BLK_DEV_MD is not set
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_INITRD=y
-# CONFIG_BLK_DEV_XD is not set
-CONFIG_PARIDE_PARPORT=y
-# CONFIG_PARIDE is not set
-# CONFIG_BLK_DEV_HD is not set
-
-#
-# Networking options
-#
-# CONFIG_PACKET is not set
-# CONFIG_NETLINK is not set
-# CONFIG_FIREWALL is not set
-# CONFIG_FILTER is not set
-CONFIG_UNIX=y
-CONFIG_INET=y
-# CONFIG_IP_MULTICAST is not set
-# CONFIG_IP_ADVANCED_ROUTER is not set
-# CONFIG_IP_PNP is not set
-# CONFIG_IP_ROUTER is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_IP_ALIAS is not set
-CONFIG_SYN_COOKIES=y
-# CONFIG_INET_RARP is not set
-# CONFIG_IP_NOSR is not set
-CONFIG_SKB_LARGE=y
-# CONFIG_IPV6 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_LLC is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
-# CONFIG_NET_HW_FLOWCONTROL is not set
-# CONFIG_CPU_IS_SLOW is not set
-# CONFIG_NET_SCHED is not set
-
-#
-# SCSI support
-#
-CONFIG_SCSI=y
-CONFIG_BLK_DEV_SD=y
-CONFIG_CHR_DEV_ST=y
-CONFIG_BLK_DEV_SR=y
-CONFIG_BLK_DEV_SR_VENDOR=y
-# CONFIG_CHR_DEV_SG is not set
-# CONFIG_SCSI_MULTI_LUN is not set
-# CONFIG_SCSI_CONSTANTS is not set
-# CONFIG_SCSI_LOGGING is not set
-
-#
-# SCSI low-level drivers
-#
-# CONFIG_SCSI_7000FASST is not set
-# CONFIG_SCSI_AHA152X is not set
-# CONFIG_SCSI_AHA1542 is not set
-# CONFIG_SCSI_AHA1740 is not set
-# CONFIG_SCSI_AIC7XXX is not set
-# CONFIG_SCSI_ADVANSYS is not set
-# CONFIG_SCSI_IN2000 is not set
-# CONFIG_SCSI_AM53C974 is not set
-# CONFIG_SCSI_BUSLOGIC is not set
-# CONFIG_SCSI_DTC3280 is not set
-# CONFIG_SCSI_EATA_DMA is not set
-# CONFIG_SCSI_EATA_PIO is not set
-# CONFIG_SCSI_EATA is not set
-# CONFIG_SCSI_FUTURE_DOMAIN is not set
-# CONFIG_SCSI_GDTH is not set
-# CONFIG_SCSI_GENERIC_NCR5380 is not set
-# CONFIG_SCSI_NCR53C406A is not set
-# CONFIG_SCSI_NCR53C7xx is not set
-CONFIG_SCSI_NCR53C8XX=y
-CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS=8
-CONFIG_SCSI_NCR53C8XX_MAX_TAGS=4
-CONFIG_SCSI_NCR53C8XX_SYNC=5
-# CONFIG_SCSI_NCR53C8XX_PROFILE is not set
-CONFIG_SCSI_NCR53C8XX_IOMAPPED=y
-# CONFIG_SCSI_NCR53C8XX_SYMBIOS_COMPAT is not set
-# CONFIG_SCSI_PAS16 is not set
-# CONFIG_SCSI_PCI2000 is not set
-# CONFIG_SCSI_PCI2220I is not set
-# CONFIG_SCSI_PSI240I is not set
-# CONFIG_SCSI_QLOGIC_FAS is not set
-# CONFIG_SCSI_QLOGIC_ISP is not set
-# CONFIG_SCSI_SEAGATE is not set
-# CONFIG_SCSI_DC390T is not set
-# CONFIG_SCSI_T128 is not set
-# CONFIG_SCSI_U14_34F is not set
-# CONFIG_SCSI_ULTRASTOR is not set
-# CONFIG_SCSI_DEBUG is not set
-# CONFIG_SCSI_MESH is not set
-# CONFIG_SCSI_MAC53C94 is not set
-
-#
-# Network device support
-#
-CONFIG_NETDEVICES=y
-# CONFIG_ARCNET is not set
-# CONFIG_DUMMY is not set
-# CONFIG_EQUALIZER is not set
-CONFIG_NET_ETHERNET=y
-# CONFIG_MACE is not set
-# CONFIG_BMAC is not set
-# CONFIG_NET_VENDOR_3COM is not set
-CONFIG_LANCE=y
-# CONFIG_NET_VENDOR_SMC is not set
-# CONFIG_NET_VENDOR_RACAL is not set
-# CONFIG_RTL8139 is not set
-# CONFIG_YELLOWFIN is not set
-# CONFIG_NET_ISA is not set
-CONFIG_NET_EISA=y
-CONFIG_PCNET32=y
-# CONFIG_AC3200 is not set
-# CONFIG_APRICOT is not set
-# CONFIG_CS89x0 is not set
-CONFIG_DE4X5=y
-# CONFIG_DEC_ELCP is not set
-# CONFIG_DGRS is not set
-# CONFIG_EEXPRESS_PRO100 is not set
-# CONFIG_LNE390 is not set
-# CONFIG_NE2K_PCI is not set
-# CONFIG_TLAN is not set
-# CONFIG_ES3210 is not set
-# CONFIG_EPIC100 is not set
-# CONFIG_ZNET is not set
-# CONFIG_NET_POCKET is not set
-# CONFIG_FDDI is not set
-# CONFIG_DLCI is not set
-CONFIG_PPP=m
-# CONFIG_SLIP is not set
-# CONFIG_NET_RADIO is not set
-# CONFIG_TR is not set
-# CONFIG_SHAPER is not set
-
-#
-# Amateur Radio support
-#
-# CONFIG_HAMRADIO is not set
-
-#
-# ISDN subsystem
-#
-# CONFIG_ISDN is not set
-
-#
-# CD-ROM drivers (not for SCSI or IDE/ATAPI drives)
-#
-# CONFIG_CD_NO_IDESCSI is not set
-
-#
-# Console drivers
-#
-
-#
-# Character devices
-#
-CONFIG_VT=y
-CONFIG_VT_CONSOLE=y
-CONFIG_SERIAL=y
-CONFIG_SERIAL_CONSOLE=y
-# CONFIG_SERIAL_EXTENDED is not set
-# CONFIG_SERIAL_NONSTANDARD is not set
-CONFIG_MOUSE=y
-# CONFIG_ATIXL_BUSMOUSE is not set
-# CONFIG_BUSMOUSE is not set
-# CONFIG_MS_BUSMOUSE is not set
-CONFIG_PSMOUSE=y
-# CONFIG_82C710_MOUSE is not set
-# CONFIG_PC110_PAD is not set
-# CONFIG_UMISC is not set
-# CONFIG_QIC02_TAPE is not set
-# CONFIG_WATCHDOG is not set
-# CONFIG_RTC is not set
-# CONFIG_VIDEO_DEV is not set
-# CONFIG_NVRAM is not set
-# CONFIG_JOYSTICK is not set
-
-#
-# Ftape, the floppy tape device driver
-#
-# CONFIG_FTAPE is not set
-
-#
-# Filesystems
-#
-# CONFIG_QUOTA is not set
-# CONFIG_MINIX_FS is not set
-CONFIG_EXT2_FS=y
-CONFIG_ISO9660_FS=y
-# CONFIG_JOLIET is not set
-CONFIG_FAT_FS=m
-CONFIG_MSDOS_FS=m
-# CONFIG_UMSDOS_FS is not set
-# CONFIG_VFAT_FS is not set
-CONFIG_PROC_FS=y
-CONFIG_NFS_FS=y
-# CONFIG_NFSD is not set
-CONFIG_SUNRPC=y
-CONFIG_LOCKD=y
-# CONFIG_CODA_FS is not set
-# CONFIG_SMB_FS is not set
-# CONFIG_HPFS_FS is not set
-# CONFIG_NTFS_FS is not set
-# CONFIG_SYSV_FS is not set
-# CONFIG_AFFS_FS is not set
-# CONFIG_HFS_FS is not set
-# CONFIG_ROMFS_FS is not set
-# CONFIG_AUTOFS_FS is not set
-# CONFIG_UFS_FS is not set
-# CONFIG_ADFS_FS is not set
-# CONFIG_DEVPTS_FS is not set
-# CONFIG_MAC_PARTITION is not set
-CONFIG_NLS=y
-
-#
-# Native Language Support
-#
-# CONFIG_NLS_CODEPAGE_437 is not set
-# CONFIG_NLS_CODEPAGE_737 is not set
-# CONFIG_NLS_CODEPAGE_775 is not set
-# CONFIG_NLS_CODEPAGE_850 is not set
-# CONFIG_NLS_CODEPAGE_852 is not set
-# CONFIG_NLS_CODEPAGE_855 is not set
-# CONFIG_NLS_CODEPAGE_857 is not set
-# CONFIG_NLS_CODEPAGE_860 is not set
-# CONFIG_NLS_CODEPAGE_861 is not set
-# CONFIG_NLS_CODEPAGE_862 is not set
-# CONFIG_NLS_CODEPAGE_863 is not set
-# CONFIG_NLS_CODEPAGE_864 is not set
-# CONFIG_NLS_CODEPAGE_865 is not set
-# CONFIG_NLS_CODEPAGE_866 is not set
-# CONFIG_NLS_CODEPAGE_869 is not set
-# CONFIG_NLS_CODEPAGE_874 is not set
-# CONFIG_NLS_ISO8859_1 is not set
-# CONFIG_NLS_ISO8859_2 is not set
-# CONFIG_NLS_ISO8859_3 is not set
-# CONFIG_NLS_ISO8859_4 is not set
-# CONFIG_NLS_ISO8859_5 is not set
-# CONFIG_NLS_ISO8859_6 is not set
-# CONFIG_NLS_ISO8859_7 is not set
-# CONFIG_NLS_ISO8859_8 is not set
-# CONFIG_NLS_ISO8859_9 is not set
-# CONFIG_NLS_KOI8_R is not set
-
-#
-# Sound
-#
-CONFIG_SOUND=y
-# CONFIG_SOUND_ES1370 is not set
-# CONFIG_SOUND_ES1371 is not set
-# CONFIG_SOUND_SONICVIBES is not set
-# CONFIG_SOUND_MSNDCLAS is not set
-# CONFIG_SOUND_MSNDPIN is not set
-CONFIG_SOUND_OSS=y
-# CONFIG_SOUND_PAS is not set
-# CONFIG_SOUND_SB is not set
-# CONFIG_SOUND_ADLIB is not set
-# CONFIG_SOUND_GUS is not set
-# CONFIG_SOUND_MPU401 is not set
-# CONFIG_SOUND_PSS is not set
-# CONFIG_SOUND_MSS is not set
-# CONFIG_SOUND_SSCAPE is not set
-# CONFIG_SOUND_TRIX is not set
-# CONFIG_SOUND_MAD16 is not set
-# CONFIG_SOUND_WAVEFRONT is not set
-CONFIG_SOUND_CS4232=y
-CONFIG_CS4232_BASE=530
-CONFIG_CS4232_IRQ=11
-CONFIG_CS4232_DMA=0
-CONFIG_CS4232_DMA2=3
-CONFIG_CS4232_MPU_BASE=330
-CONFIG_CS4232_MPU_IRQ=9
-# CONFIG_SOUND_MAUI is not set
-# CONFIG_SOUND_SGALAXY is not set
-# CONFIG_SOUND_OPL3SA1 is not set
-# CONFIG_SOUND_SOFTOSS is not set
-# CONFIG_SOUND_YM3812 is not set
-# CONFIG_SOUND_VMIDI is not set
-# CONFIG_SOUND_UART6850 is not set
-
-#
-# Additional low level sound drivers
-#
-# CONFIG_LOWLEVEL_SOUND is not set
index 229768b9bdc0ac0da08e809810ff54a609326081..caf15d27d93d8f4da7ccb0ee41addf25da81c3b5 100644 (file)
@@ -1,5 +1,5 @@
 #
-# Automatically generated make config: don't edit
+# Automatically generated by make menuconfig: don't edit
 #
 # CONFIG_UID16 is not set
 
@@ -66,7 +66,6 @@ CONFIG_ADB_PMU=y
 CONFIG_ADB_KEYBOARD=y
 CONFIG_ADBMOUSE=y
 CONFIG_PROC_DEVICETREE=y
-# CONFIG_TOTALMP is not set
 CONFIG_BOOTX_TEXT=y
 # CONFIG_MOTOROLA_HOTSWAP is not set
 # CONFIG_CMDLINE_BOOL is not set
@@ -85,13 +84,12 @@ CONFIG_BOOTX_TEXT=y
 # CONFIG_PARIDE is not set
 # CONFIG_BLK_CPQ_DA is not set
 # CONFIG_BLK_DEV_DAC960 is not set
-
-#
-# Additional Block Devices
-#
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_LVM is not set
 # CONFIG_BLK_DEV_MD is not set
+# CONFIG_MD_LINEAR is not set
+# CONFIG_MD_STRIPED is not set
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_INITRD=y
 
@@ -116,18 +114,10 @@ CONFIG_IP_MULTICAST=y
 # CONFIG_IP_MROUTE is not set
 CONFIG_IP_ALIAS=y
 CONFIG_SYN_COOKIES=y
-
-#
-# (it is safe to leave these untouched)
-#
 CONFIG_SKB_LARGE=y
 # CONFIG_IPV6 is not set
 # CONFIG_KHTTPD is not set
 # CONFIG_ATM is not set
-
-#
-#  
-#
 # CONFIG_IPX is not set
 CONFIG_ATALK=m
 # CONFIG_DECNET is not set
@@ -154,10 +144,6 @@ CONFIG_IDE=y
 # IDE, ATA and ATAPI Block devices
 #
 CONFIG_BLK_DEV_IDE=y
-
-#
-# Please see Documentation/ide.txt for help/info on IDE drives
-#
 # CONFIG_BLK_DEV_HD_IDE is not set
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_BLK_DEV_IDEDISK=y
@@ -167,10 +153,6 @@ CONFIG_BLK_DEV_IDECD=y
 # CONFIG_BLK_DEV_IDETAPE is not set
 # CONFIG_BLK_DEV_IDEFLOPPY is not set
 CONFIG_BLK_DEV_IDESCSI=y
-
-#
-# IDE chipset support/bugfixes
-#
 # CONFIG_BLK_DEV_CMD640 is not set
 # CONFIG_BLK_DEV_CMD640_ENHANCED is not set
 # CONFIG_BLK_DEV_ISAPNP is not set
@@ -207,6 +189,7 @@ CONFIG_IDEDMA_PCI_EXPERIMENTAL=y
 # CONFIG_BLK_DEV_SIS5513 is not set
 # CONFIG_BLK_DEV_TRM290 is not set
 # CONFIG_BLK_DEV_VIA82CXXX is not set
+# CONFIG_VIA82CXXX_TUNING is not set
 # CONFIG_BLK_DEV_SL82C105 is not set
 CONFIG_BLK_DEV_IDE_PMAC=y
 CONFIG_BLK_DEV_IDEDMA_PMAC=y
@@ -220,10 +203,6 @@ CONFIG_BLK_DEV_IDE_MODES=y
 # SCSI support
 #
 CONFIG_SCSI=y
-
-#
-# SCSI support type (disk, tape, CD-ROM)
-#
 CONFIG_BLK_DEV_SD=y
 CONFIG_SD_EXTRA_DEVS=40
 CONFIG_CHR_DEV_ST=y
@@ -231,10 +210,6 @@ CONFIG_BLK_DEV_SR=y
 CONFIG_BLK_DEV_SR_VENDOR=y
 CONFIG_SR_EXTRA_DEVS=2
 CONFIG_CHR_DEV_SG=y
-
-#
-# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
-#
 # CONFIG_SCSI_DEBUG_QUEUES is not set
 # CONFIG_SCSI_MULTI_LUN is not set
 CONFIG_SCSI_CONSTANTS=y
@@ -254,12 +229,12 @@ CONFIG_SCSI_AIC7XXX=y
 CONFIG_AIC7XXX_CMDS_PER_DEVICE=8
 CONFIG_AIC7XXX_PROC_STATS=y
 CONFIG_AIC7XXX_RESET_DELAY=15
-# CONFIG_SCSI_IPS is not set
 # CONFIG_SCSI_ADVANSYS is not set
 # CONFIG_SCSI_IN2000 is not set
 # CONFIG_SCSI_AM53C974 is not set
 # CONFIG_SCSI_MEGARAID is not set
 # CONFIG_SCSI_BUSLOGIC is not set
+# CONFIG_SCSI_DMX3191D is not set
 # CONFIG_SCSI_DTC3280 is not set
 # CONFIG_SCSI_EATA is not set
 # CONFIG_SCSI_EATA_DMA is not set
@@ -290,11 +265,9 @@ CONFIG_SCSI_NCR53C8XX_SYNC=20
 # CONFIG_SCSI_QLOGIC_ISP is not set
 # CONFIG_SCSI_QLOGIC_FC is not set
 # CONFIG_SCSI_QLOGIC_1280 is not set
-# CONFIG_SCSI_SEAGATE is not set
 # CONFIG_SCSI_DC390T is not set
 # CONFIG_SCSI_T128 is not set
 # CONFIG_SCSI_U14_34F is not set
-# CONFIG_SCSI_ULTRASTOR is not set
 # CONFIG_SCSI_DEBUG is not set
 CONFIG_SCSI_MESH=y
 CONFIG_SCSI_MESH_SYNC_RATE=5
@@ -373,6 +346,7 @@ CONFIG_DE4X5=y
 # CONFIG_FDDI is not set
 # CONFIG_HIPPI is not set
 CONFIG_PPP=y
+# CONFIG_PPP_MULTILINK is not set
 # CONFIG_PPP_ASYNC is not set
 # CONFIG_PPP_SYNC_TTY is not set
 # CONFIG_PPP_DEFLATE is not set
@@ -514,59 +488,6 @@ CONFIG_NVRAM=y
 # CONFIG_DRM_TDFX is not set
 # CONFIG_AGP is not set
 
-#
-# USB support
-#
-CONFIG_USB=y
-
-#
-# USB Controllers
-#
-# CONFIG_USB_UHCI is not set
-# CONFIG_USB_UHCI_ALT is not set
-CONFIG_USB_OHCI=y
-
-#
-# Miscellaneous USB options
-#
-# CONFIG_USB_DEVICEFS is not set
-
-#
-# USB Devices
-#
-# CONFIG_USB_PRINTER is not set
-# CONFIG_USB_SCANNER is not set
-# CONFIG_USB_AUDIO is not set
-# CONFIG_USB_ACM is not set
-# CONFIG_USB_SERIAL is not set
-# CONFIG_USB_CPIA is not set
-# CONFIG_USB_IBMCAM is not set
-# CONFIG_USB_OV511 is not set
-# CONFIG_USB_DC2XX is not set
-# CONFIG_USB_MDC800 is not set
-# CONFIG_USB_STORAGE is not set
-# CONFIG_USB_USS720 is not set
-# CONFIG_USB_DABUSB is not set
-# CONFIG_USB_PLUSB is not set
-# CONFIG_USB_PEGASUS is not set
-# CONFIG_USB_RIO500 is not set
-# CONFIG_USB_DSBR is not set
-
-#
-# USB HID
-#
-# CONFIG_USB_HID is not set
-CONFIG_USB_KBD=y
-CONFIG_USB_MOUSE=y
-# CONFIG_USB_WACOM is not set
-# CONFIG_USB_WMFORCE is not set
-CONFIG_INPUT_KEYBDEV=y
-CONFIG_INPUT_MOUSEDEV=y
-# CONFIG_INPUT_MOUSEDEV_MIX is not set
-# CONFIG_INPUT_MOUSEDEV_DIGITIZER is not set
-# CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_EVDEV is not set
-
 #
 # File systems
 #
@@ -574,6 +495,7 @@ CONFIG_INPUT_MOUSEDEV=y
 CONFIG_AUTOFS_FS=y
 # CONFIG_AUTOFS4_FS is not set
 # CONFIG_ADFS_FS is not set
+# CONFIG_ADFS_FS_RW is not set
 # CONFIG_AFFS_FS is not set
 CONFIG_HFS_FS=y
 # CONFIG_BFS_FS is not set
@@ -583,27 +505,34 @@ CONFIG_MSDOS_FS=y
 CONFIG_VFAT_FS=y
 # CONFIG_EFS_FS is not set
 # CONFIG_CRAMFS is not set
+# CONFIG_RAMFS is not set
 CONFIG_ISO9660_FS=y
 # CONFIG_JOLIET is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_NTFS_FS is not set
+# CONFIG_NTFS_RW is not set
 # CONFIG_HPFS_FS is not set
 CONFIG_PROC_FS=y
 # CONFIG_DEVFS_FS is not set
 # CONFIG_DEVFS_DEBUG is not set
 CONFIG_DEVPTS_FS=y
 # CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX4FS_RW is not set
 # CONFIG_ROMFS_FS is not set
 CONFIG_EXT2_FS=y
 # CONFIG_SYSV_FS is not set
+# CONFIG_SYSV_FS_WRITE is not set
 # CONFIG_UDF_FS is not set
+# CONFIG_UDF_RW is not set
 # CONFIG_UFS_FS is not set
+# CONFIG_UFS_FS_WRITE is not set
 
 #
 # Network File Systems
 #
 # CONFIG_CODA_FS is not set
 CONFIG_NFS_FS=y
+# CONFIG_NFS_V3 is not set
 # CONFIG_ROOT_NFS is not set
 CONFIG_NFSD=y
 # CONFIG_NFSD_V3 is not set
@@ -611,6 +540,16 @@ CONFIG_SUNRPC=y
 CONFIG_LOCKD=y
 # CONFIG_SMB_FS is not set
 # CONFIG_NCP_FS is not set
+# CONFIG_NCPFS_PACKET_SIGNING is not set
+# CONFIG_NCPFS_IOCTL_LOCKING is not set
+# CONFIG_NCPFS_STRONG is not set
+# CONFIG_NCPFS_NFS_NS is not set
+# CONFIG_NCPFS_OS2_NS is not set
+# CONFIG_NCPFS_SMALLDOS is not set
+# CONFIG_NCPFS_MOUNT_SUBDIR is not set
+# CONFIG_NCPFS_NDS_DOMAINS is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_NCPFS_EXTRAS is not set
 
 #
 # Partition Types
@@ -665,6 +604,7 @@ CONFIG_NLS=y
 # Sound
 #
 CONFIG_SOUND=y
+CONFIG_DMASOUND_AWACS=y
 CONFIG_DMASOUND=y
 # CONFIG_SOUND_CMPCI is not set
 # CONFIG_SOUND_ES1370 is not set
@@ -685,6 +625,7 @@ CONFIG_SOUND_OSS=y
 CONFIG_SOUND_CS4232=m
 # CONFIG_SOUND_SSCAPE is not set
 # CONFIG_SOUND_GUS is not set
+# CONFIG_SOUND_ICH is not set
 # CONFIG_SOUND_VMIDI is not set
 # CONFIG_SOUND_TRIX is not set
 # CONFIG_SOUND_MSS is not set
@@ -706,6 +647,41 @@ CONFIG_SOUND_CS4232=m
 # CONFIG_SOUND_UART6850 is not set
 # CONFIG_SOUND_AEDSP16 is not set
 
+#
+# USB support
+#
+CONFIG_USB=y
+CONFIG_USB_DEBUG=y
+# CONFIG_USB_DEVICEFS is not set
+# CONFIG_USB_UHCI is not set
+# CONFIG_USB_UHCI_ALT is not set
+CONFIG_USB_OHCI=y
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_SCANNER is not set
+# CONFIG_USB_AUDIO is not set
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_SERIAL is not set
+# CONFIG_USB_IBMCAM is not set
+# CONFIG_USB_OV511 is not set
+# CONFIG_USB_DC2XX is not set
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_STORAGE is not set
+# CONFIG_USB_USS720 is not set
+# CONFIG_USB_DABUSB is not set
+# CONFIG_USB_PLUSB is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_DSBR is not set
+CONFIG_USB_HID=y
+# CONFIG_USB_WACOM is not set
+# CONFIG_USB_WMFORCE is not set
+CONFIG_INPUT_KEYBDEV=y
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+
 #
 # Kernel hacking
 #
index 73db2269e9d732b93ab462f5e288ebd7aeefd3fb..ed16da557d183056812a8d992ea8745bc49fece7 100644 (file)
@@ -31,7 +31,7 @@ CONFIG_CHRP=y
 endif
 
 O_OBJS := entry.o traps.o irq.o idle.o time.o process.o signal.o syscalls.o \
-         misc.o bitops.o ptrace.o align.o ppc_htab.o semaphore.o
+         misc.o ptrace.o align.o ppc_htab.o semaphore.o bitops.o
 
 ifndef CONFIG_8xx
 O_OBJS += hashtable.o
@@ -45,10 +45,6 @@ ifdef CONFIG_KGDB
 O_OBJS += ppc-stub.o
 endif
 
-ifdef CONFIG_TOTALMP
-O_OBJS += totalmp.o
-endif
-
 ifdef CONFIG_PMAC_PBOOK
 O_OBJS += sleep.o
 endif
@@ -100,6 +96,9 @@ endif
 ifeq ($(CONFIG_GEMINI),y)
   O_OBJS += gemini_prom.o gemini_pci.o gemini_setup.o open_pic.o
 endif
+ifeq ($(CONFIG_8260),y)
+  O_OBJS += m8260_setup.o ppc8260_pic.o
+endif
 
 all: $(KHEAD) kernel.o
 
index 7f6340261f3984f575f55f18b680cfb7b7de101b..5b7366adccd03a8d0166316f434f89ac8514738d 100644 (file)
@@ -14,6 +14,7 @@
 #include <asm/processor.h>
 #include <asm/uaccess.h>
 #include <asm/system.h>
+#include <asm/cache.h>
 
 struct aligninfo {
        unsigned char len;
@@ -38,6 +39,8 @@ struct aligninfo {
 #define S      0x40    /* single-precision fp, or byte-swap value */
 #define HARD   0x80    /* string, stwcx. */
 
+#define DCBZ   0x5f    /* 8xx/82xx dcbz faults when cache not enabled */
+
 /*
  * The PowerPC stores certain bits of the instruction that caused the
  * alignment exception in the DSISR register.  This array maps those
@@ -220,9 +223,27 @@ fix_alignment(struct pt_regs *regs)
        areg = regs->dsisr & 0x1f;              /* register to update */
        instr = (regs->dsisr >> 10) & 0x7f;
 #endif
+
        nb = aligninfo[instr].len;
-       if (nb == 0)
-               return 0;       /* too hard or invalid instruction bits */
+       if (nb == 0) {
+               long *p;
+               int i;
+
+               if (instr != DCBZ)
+                       return 0;       /* too hard or invalid instruction */
+               /*
+                * The dcbz (data cache block zero) instruction
+                * gives an alignment fault if used on non-cacheable
+                * memory.  We handle the fault mainly for the
+                * case when we are running with the cache disabled
+                * for debugging.
+                */
+               p = (long *) (regs->dar & -L1_CACHE_BYTES);
+               for (i = 0; i < L1_CACHE_BYTES / sizeof(long); ++i)
+                       p[i] = 0;
+               return 1;
+       }
+
        flags = aligninfo[instr].flags;
 
        /* For the 4xx-family processors, the 'dar' field of the
index d5baa3747096fd07d80abe1d5c4e3164f6e6c1be..e47befdd331c22fb8847b47398ea676ad6f968d6 100644 (file)
@@ -57,8 +57,8 @@ static fbit feature_bits_ohare_pbook[] = {
        {0x38,1,OH_BAY_RESET_N},        /* FEATURE_Mediabay_reset */
        {0x38,1,OH_BAY_POWER_N},        /* FEATURE_Mediabay_power */
        {0x38,0,OH_BAY_PCI_ENABLE},     /* FEATURE_Mediabay_PCI_enable */
-       {0x38,0,OH_BAY_IDE_ENABLE},     /* FEATURE_Mediabay_IDE_enable */
-       {0x38,1,OH_IDE1_RESET_N},       /* FEATURE_Mediabay_IDE_reset */
+       {0x38,0,OH_BAY_IDE_ENABLE},     /* FEATURE_IDE1_enable */
+       {0x38,1,OH_IDE1_RESET_N},       /* FEATURE_IDE1_reset */
        {0x38,0,OH_BAY_FLOPPY_ENABLE},  /* FEATURE_Mediabay_floppy_enable */
        {0x38,0,0},                     /* FEATURE_BMac_reset */
        {0x38,0,0},                     /* FEATURE_BMac_IO_enable */
@@ -68,6 +68,8 @@ static fbit feature_bits_ohare_pbook[] = {
        {0x38,0,0},                     /* FEATURE_Sound_CLK_Enable */
        {0x38,0,0},                     /* FEATURE_IDE2_enable */
        {0x38,0,0},                     /* FEATURE_IDE2_reset */
+       {0x38,0,0},                     /* FEATURE_Mediabay_IDE_switch */
+       {0x38,0,0},                     /* FEATURE_Mediabay_content */
 };
 
 /* Those bits are from a PowerBook. It's possible that desktop machines
@@ -87,8 +89,8 @@ static fbit feature_bits_heathrow[] = {
        {0x38,1,HRW_BAY_RESET_N},       /* FEATURE_Mediabay_reset */
        {0x38,1,HRW_BAY_POWER_N},       /* FEATURE_Mediabay_power */
        {0x38,0,HRW_BAY_PCI_ENABLE},    /* FEATURE_Mediabay_PCI_enable */
-       {0x38,0,HRW_BAY_IDE_ENABLE},    /* FEATURE_Mediabay_IDE_enable */
-       {0x38,1,HRW_IDE1_RESET_N},      /* FEATURE_Mediabay_IDE_reset */
+       {0x38,0,HRW_BAY_IDE_ENABLE},    /* FEATURE_IDE1_enable */
+       {0x38,1,HRW_IDE1_RESET_N},      /* FEATURE_IDE1_reset */
        {0x38,0,HRW_BAY_FLOPPY_ENABLE}, /* FEATURE_Mediabay_floppy_enable */
        {0x38,0,HRW_BMAC_RESET},        /* FEATURE_BMac_reset */
        {0x38,0,HRW_BMAC_IO_ENABLE},    /* FEATURE_BMac_IO_enable */
@@ -98,9 +100,44 @@ static fbit feature_bits_heathrow[] = {
        {0x38,0,HRW_SOUND_CLK_ENABLE},  /* FEATURE_Sound_CLK_Enable */
        {0x38,0,0},                     /* FEATURE_IDE2_enable */
        {0x38,0,0},                     /* FEATURE_IDE2_reset */
+       {0x38,0,0},                     /* FEATURE_Mediabay_IDE_switch */
+       {0x38,0,0},                     /* FEATURE_Mediabay_content */
 };
 
-/* Those bits are from an iBook.
+/*
+ * Those bits are from a 1999 G3 PowerBook, with a paddington chip.
+ * Mostly the same as the heathrow.
+ */
+static fbit feature_bits_paddington[] = {
+       {0x38,0,0},                     /* FEATURE_null */
+       {0x38,0,0},                     /* FEATURE_Serial_reset */
+       {0x38,0,HRW_SCC_ENABLE},        /* FEATURE_Serial_enable */
+       {0x38,0,HRW_SCCA_IO},           /* FEATURE_Serial_IO_A */
+       {0x38,0,HRW_SCCB_IO},           /* FEATURE_Serial_IO_B */
+       {0x38,0,HRW_SWIM_ENABLE},       /* FEATURE_SWIM3_enable */
+       {0x38,0,HRW_MESH_ENABLE},       /* FEATURE_MESH_enable */
+       {0x38,0,HRW_IDE0_ENABLE},       /* FEATURE_IDE0_enable */
+       {0x38,1,HRW_IDE0_RESET_N},      /* FEATURE_IDE0_reset */
+       {0x38,0,HRW_IOBUS_ENABLE},      /* FEATURE_IOBUS_enable */
+       {0x38,1,HRW_BAY_RESET_N},       /* FEATURE_Mediabay_reset */
+       {0x38,1,HRW_BAY_POWER_N},       /* FEATURE_Mediabay_power */
+       {0x38,0,HRW_BAY_PCI_ENABLE},    /* FEATURE_Mediabay_PCI_enable */
+       {0x38,0,HRW_BAY_IDE_ENABLE},    /* FEATURE_IDE1_enable */
+       {0x38,1,HRW_IDE1_RESET_N},      /* FEATURE_IDE1_reset */
+       {0x38,0,HRW_BAY_FLOPPY_ENABLE}, /* FEATURE_Mediabay_floppy_enable */
+       {0x38,0,HRW_BMAC_RESET},        /* FEATURE_BMac_reset */
+       {0x38,0,HRW_BMAC_IO_ENABLE},    /* FEATURE_BMac_IO_enable */
+       {0x38,1,PADD_MODEM_POWER_N},    /* FEATURE_Modem_power */
+       {0x38,0,HRW_SLOW_SCC_PCLK},     /* FEATURE_Slow_SCC_PCLK */
+       {0x38,1,HRW_SOUND_POWER_N},     /* FEATURE_Sound_Power */
+       {0x38,0,HRW_SOUND_CLK_ENABLE},  /* FEATURE_Sound_CLK_Enable */
+       {0x38,0,0},                     /* FEATURE_IDE2_enable */
+       {0x38,0,0},                     /* FEATURE_IDE2_reset */
+       {0x38,0,0},                     /* FEATURE_Mediabay_IDE_switch */
+       {0x38,0,0},                     /* FEATURE_Mediabay_content */
+};
+
+/* Those bits are for Core99 machines (iBook,G4,iMacSL/DV,Pismo,...).
  */
 static fbit feature_bits_keylargo[] = {
        {0x38,0,0},                     /* FEATURE_null */
@@ -110,14 +147,14 @@ static fbit feature_bits_keylargo[] = {
        {0x38,0,0},                     /* FEATURE_Serial_IO_B */
        {0x38,0,0},                     /* FEATURE_SWIM3_enable */
        {0x38,0,0},                     /* FEATURE_MESH_enable */
-       {0x38,0,0},                     /* FEATURE_IDE0_enable */
-       {0x3c,1,0x01000000},            /* FEATURE_IDE0_reset */
+       {0x3c,0,0},                     /* FEATURE_IDE0_enable */
+       {0x3c,1,0x01000000},            /* FEATURE_IDE0_reset */
        {0x38,0,0},                     /* FEATURE_IOBUS_enable */
-       {0x38,0,0},                     /* FEATURE_Mediabay_reset */
-       {0x38,0,0},                     /* FEATURE_Mediabay_power */
+       {0x34,1,0x00000200},            /* FEATURE_Mediabay_reset */
+       {0x34,1,0x00000400},            /* FEATURE_Mediabay_power */
        {0x38,0,0},                     /* FEATURE_Mediabay_PCI_enable */
-       {0x38,0,0},                     /* FEATURE_Mediabay_IDE_enable */
-       {0x3c,1,0x08000000},            /* FEATURE_Mediabay_IDE_reset */
+       {0x3c,0,0x0},                   /* FEATURE_IDE1_enable */
+       {0x3c,1,0x08000000},            /* FEATURE_IDE1_reset */
        {0x38,0,0},                     /* FEATURE_Mediabay_floppy_enable */
        {0x38,0,0},                     /* FEATURE_BMac_reset */
        {0x38,0,0},                     /* FEATURE_BMac_IO_enable */
@@ -127,6 +164,8 @@ static fbit feature_bits_keylargo[] = {
        {0x38,0,0},                     /* FEATURE_Sound_CLK_Enable */
        {0x38,0,0},                     /* FEATURE_IDE2_enable */
        {0x3c,1,0x40000000},            /* FEATURE_IDE2_reset */
+       {0x34,0,0x00001000},            /* FEATURE_Mediabay_IDE_switch */
+       {0x34,0,0x00000100},            /* FEATURE_Mediabay_content */
 };
 
 /* definition of a feature controller object */
@@ -164,6 +203,8 @@ feature_init(void)
                 */
                if (device_is_compatible(np, "Keylargo")) {
                        feature_add_controller(np, feature_bits_keylargo);
+               } else if (device_is_compatible(np, "paddington")) {
+                       feature_add_controller(np, feature_bits_paddington);
                } else {
                        feature_add_controller(np, feature_bits_heathrow);
                }
@@ -268,6 +309,8 @@ feature_set(struct device_node* device, enum system_feature f)
        if (!controller)
                return -ENODEV;
        bit = &controller->bits[f];
+       if (!bit->mask)
+               return -EINVAL;
        
 #ifdef DEBUG_FEATURE
        printk("feature: <%s> setting feature %d in controller @0x%x\n",
@@ -299,6 +342,8 @@ feature_clear(struct device_node* device, enum system_feature f)
        if (!controller)
                return -ENODEV;
        bit = &controller->bits[f];
+       if (!bit->mask)
+               return -EINVAL;
        
 #ifdef DEBUG_FEATURE
        printk("feature: <%s> clearing feature %d in controller @0x%x\n",
@@ -329,6 +374,8 @@ feature_test(struct device_node* device, enum system_feature f)
        if (!controller)
                return -ENODEV;
        bit = &controller->bits[f];
+       if (!bit->mask)
+               return -EINVAL;
        
 #ifdef DEBUG_FEATURE
        printk("feature: <%s> clearing feature %d in controller @0x%x\n",
index fb80dc4937a79134d9b6ea6d4009891ee11aa6f1..1ac83d1c88feea506d48c08dc1318e326de423ec 100644 (file)
@@ -77,178 +77,19 @@ gemini_pcibios_write_config_dword(unsigned char bus, unsigned char dev,
        return PCIBIOS_SUCCESSFUL;
 }
 
-struct gemini_device {
-       unsigned short vendor, device;
-       unsigned char irq;
-       unsigned short cmd;
-       unsigned char cache_line, latency;
-       void (*init)(struct pci_dev *dev);
-};
-
-static struct gemini_device gemini_map[] = {
-       { PCI_VENDOR_ID_NCR, PCI_DEVICE_ID_NCR_53C885, 11, 0x15, 32, 248, NULL },
-       { PCI_VENDOR_ID_NCR, 0x701, 10, 0, 0, 0, NULL },
-       { PCI_VENDOR_ID_TUNDRA, PCI_DEVICE_ID_TUNDRA_CA91C042, 3, 0, 0, 0, NULL },
-       { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_MPIC, 0xff, 0, 0, 0, NULL },
-       { PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_CMD_670, 0xff, 0, 0, 0, NULL },
-       { PCI_VENDOR_ID_MOTOROLA, PCI_DEVICE_ID_MOTOROLA_MPC106, 0xff, 0, 0, 0, NULL },
-};
-
-static int gemini_map_count = (sizeof( gemini_map ) /
-                               sizeof( gemini_map[0] ));
-
-
-/*  This just sets up the known devices on the board. */
-static void __init mapin_device( struct pci_dev *dev )
-{
-       struct gemini_device *p;
-       unsigned short cmd;
-       int i;
-  
-
-       for( i=0; i < gemini_map_count; i++ ) {
-               p = &(gemini_map[i]);
-    
-               if ( p->vendor == dev->vendor && 
-                    p->device == dev->device ) {
-     
-                       if (p->irq != 0xff) {
-                               pci_write_config_byte( dev, PCI_INTERRUPT_LINE, p->irq );
-                               dev->irq = p->irq;
-                       }
-
-                       if (p->cmd) {
-                               pci_read_config_word( dev, PCI_COMMAND, &cmd );
-                               pci_write_config_word( dev, PCI_COMMAND, (p->cmd|cmd));
-                       }
-
-                       if (p->cache_line)
-                               pci_write_config_byte( dev, PCI_CACHE_LINE_SIZE, p->cache_line );
-                       if (p->latency)
-                               pci_write_config_byte( dev, PCI_LATENCY_TIMER, p->latency );
-               }
-       }
-}
-
-#define KB 1024
-#define MB (KB*KB)
-
-#define ALIGN(val,align) (((val) + ((align) -1))&(~((align) -1)))
-#define MAX(a,b)   (((a) > (b)) ? (a) : (b))
-
-#define FIRST_IO_ADDR 0x10000
-#define FIRST_MEM_ADDR 0x02000000
-
-#define GEMINI_PCI_MEM_BASE (0xf0000000)
-#define GEMINI_PCI_IO_BASE  (0xfe800000)
-
-static unsigned long pci_mem_base = GEMINI_PCI_MEM_BASE;
-static unsigned long pci_io_base = GEMINI_PCI_IO_BASE;
-
-static unsigned int io_base = FIRST_IO_ADDR;
-static unsigned int mem_base = FIRST_MEM_ADDR;
-
-
-
-__init void layout_dev( struct pci_dev *dev )
+void __init gemini_pcibios_fixup(void)
 {
        int i;
-       struct pci_bus *bus;
-       unsigned short cmd;
-       unsigned int reg, base, mask, size, alignto, type;
-
-       bus = dev->bus;
-
-       /* make any known settings happen */
-       mapin_device( dev );
-
-       gemini_pcibios_read_config_word( bus->number, dev->devfn, PCI_COMMAND, &cmd );
-
-       for( reg = PCI_BASE_ADDRESS_0, i=0; reg <= PCI_BASE_ADDRESS_5; reg += 4, i++ ) {
-    
-               /* MPIC already done */
-               if (dev->vendor == PCI_VENDOR_ID_IBM &&
-                   dev->device == PCI_DEVICE_ID_IBM_MPIC)
-                       return;
-
-               gemini_pcibios_write_config_dword( bus->number, dev->devfn, reg, 0xffffffff );
-               gemini_pcibios_read_config_dword( bus->number, dev->devfn, reg, &base );
-               if (!base) {
-                       dev->resource[i].start = 0;
-                       continue;
-               }
-
-               if (base & PCI_BASE_ADDRESS_SPACE_IO) {
-                       cmd |= PCI_COMMAND_IO;
-                       base &= PCI_BASE_ADDRESS_IO_MASK;
-                       mask = (~base << 1) | 0x1;
-                       size = (mask & base) & 0xffffffff;
-                       alignto = MAX(0x400, size);
-                       base = ALIGN(io_base, alignto);
-                       io_base = base + size;
-                       gemini_pcibios_write_config_dword( bus->number, dev->devfn, reg, 
-                                                          ((pci_io_base + base) & 0x00ffffff) | 0x1);
-                       dev->resource[i].start = (pci_io_base + base) | 0x1;
-               }
-
-               else {
-                       cmd |= PCI_COMMAND_MEMORY;
-                       type = base & PCI_BASE_ADDRESS_MEM_TYPE_MASK;
-                       mask = (~base << 1) | 0x1;
-                       size = (mask & base) & 0xffffffff;
-                       switch( type ) {
-
-                       case PCI_BASE_ADDRESS_MEM_TYPE_32:
-                               break;
-                       case PCI_BASE_ADDRESS_MEM_TYPE_64:
-                               printk("Warning: Ignoring 64-bit device; slot %d, function %d.\n",
-                                      PCI_SLOT( dev->devfn ), PCI_FUNC( dev->devfn ));
-                               reg += 4;
-                               continue;
+       struct pci_dev *dev;
+       
+       pci_for_each_dev(dev) {
+               for(i = 0; i < 6; i++) {
+                       if (dev->resource[i].flags & IORESOURCE_IO) {
+                               dev->resource[i].start |= (0xfe << 24);
+                               dev->resource[i].end |= (0xfe << 24);
                        }
-
-                       alignto = MAX(0x1000, size);
-                       base = ALIGN(mem_base, alignto);
-                       mem_base = base + size;
-                       gemini_pcibios_write_config_dword( bus->number, dev->devfn,
-                                                          reg, (pci_mem_base + base));
-                       dev->resource[i].start = pci_mem_base + base;
                }
        }
-
-       if ((dev->class >> 8) == PCI_CLASS_DISPLAY_VGA)
-               cmd |= PCI_COMMAND_IO;
-
-       gemini_pcibios_write_config_word( bus->number, dev->devfn, PCI_COMMAND,
-                                         (cmd|PCI_COMMAND_MASTER));
-}
-
-__init void layout_bus( struct pci_bus *bus )
-{
-       struct pci_dev *dev;
-
-       io_base = ALIGN(io_base, 4*KB);
-       mem_base = ALIGN(mem_base, 4*KB);
-
-       pci_for_each_dev(dev)
-       {
-               if (((dev->class >> 16) != PCI_BASE_CLASS_BRIDGE) ||
-                   ((dev->class >> 8) == PCI_CLASS_BRIDGE_OTHER))
-                       layout_dev( dev );
-       }
-}
-
-void __init gemini_pcibios_fixup(void)
-{
-       unsigned long orig_mem_base, orig_io_base;
-       
-       orig_mem_base = pci_mem_base;
-       orig_io_base = pci_io_base;
-
-       pci_mem_base = orig_mem_base;
-       pci_io_base = orig_io_base;
 }
 
 decl_config_access_method(gemini);
index ae9a0bd5cc90a709f6b8c2716270954517cdb818..e069baf5b5d15f08d59cd79fe1fc943c4206b2fb 100644 (file)
 #include "open_pic.h"
 
 void gemini_setup_pci_ptrs(void);
+static int gemini_get_clock_speed(void);
+extern void gemini_pcibios_fixup(void);
 
-static unsigned char gemini_switch_map = 0;
 static char *gemini_board_families[] = {
-       "VGM", "VSS", "KGM", "VGR", "KSS"
-};
-
-static char *gemini_memtypes[] = {
-       "EDO DRAM, 60nS", "SDRAM, 15nS, CL=2", "SDRAM, 15nS, CL=2 with ECC"
+  "VGM", "VSS", "KGM", "VGR", "VCM", "VCS", "KCM", "VCR"
 };
+static int gemini_board_count = sizeof(gemini_board_families) /
+                                 sizeof(gemini_board_families[0]);
 
 static unsigned int cpu_7xx[16] = {
        0, 15, 14, 0, 0, 13, 5, 9, 6, 11, 8, 10, 16, 12, 7, 0
@@ -66,14 +65,14 @@ static inline unsigned long _get_HID1(void)
 int
 gemini_get_cpuinfo(char *buffer)
 {
-       int i, len;
+       int len;
        unsigned char reg, rev;
        char *family;
        unsigned int type;
 
        reg = readb(GEMINI_FEAT);
        family = gemini_board_families[((reg>>4) & 0xf)];
-       if (((reg>>4) & 0xf) > 2)
+       if (((reg>>4) & 0xf) > gemini_board_count)
                printk(KERN_ERR "cpuinfo(): unable to determine board family\n");
 
        reg = readb(GEMINI_BREV);
@@ -85,18 +84,17 @@ gemini_get_cpuinfo(char *buffer)
        len = sprintf( buffer, "machine\t\t: Gemini %s%d, rev %c, eco %d\n", 
                       family, type, (rev + 'A'), (reg & 0xf));
 
-       len += sprintf( buffer+len, "vendor\t\t: %s\n", 
-                       (_get_PVR() & (1<<15)) ? "IBM" : "Motorola");
+       len = sprintf(buffer, "board\t\t: Gemini %s", family);
+       if (type > 9)
+               len += sprintf(buffer+len, "%c", (type - 10) + 'A');
+       else
+               len += sprintf(buffer+len, "%d", type);
 
-       reg = readb(GEMINI_MEMCFG);
-       len += sprintf( buffer+len, "memory type\t: %s\n", 
-                       gemini_memtypes[(reg & 0xc0)>>6]);
-       len += sprintf( buffer+len, "switches on\t: ");
-       for( i=0; i < 8; i++ ) {
-               if ( gemini_switch_map & (1<<i))
-                       len += sprintf(buffer+len, "%d ", i);
-       }
-       len += sprintf(buffer+len, "\n");
+       len += sprintf(buffer+len, ", rev %c, eco %d\n",
+                      (rev + 'A'), (reg & 0xf));
+
+       len += sprintf(buffer+len, "clock\t\t: %dMhz\n", 
+                      gemini_get_clock_speed());
 
        return len;
 }
@@ -116,11 +114,16 @@ static u_char gemini_openpic_initsenses[] = {
 
 void __init gemini_openpic_init(void)
 {
+
+       OpenPIC = (volatile struct OpenPIC *)
+               grackle_read(0x80005800 + 0x10);
+#if 0  
        grackle_write(GEMINI_MPIC_PCI_CFG + PCI_BASE_ADDRESS_0, 
                      GEMINI_MPIC_ADDR);
        grackle_write(GEMINI_MPIC_PCI_CFG + PCI_COMMAND, PCI_COMMAND_MEMORY);
 
        OpenPIC = (volatile struct OpenPIC *) GEMINI_MPIC_ADDR;
+#endif
        OpenPIC_InitSenses = gemini_openpic_initsenses;
        OpenPIC_NumInitSenses = sizeof( gemini_openpic_initsenses );
 
@@ -148,7 +151,6 @@ gemini_heartbeat(void)
 
 void __init gemini_setup_arch(void)
 {
-       unsigned int cpu;
        extern char cmd_line[];
 
 
@@ -165,29 +167,8 @@ void __init gemini_setup_arch(void)
        /* nothing but serial consoles... */  
        sprintf(cmd_line, "%s console=ttyS0", cmd_line);
 
-
-       /* The user switches on the front panel can be used as follows:
-
-          Switch 0 - adds "debug" to the command line for verbose boot info,
-          Switch 7 - boots in single-user mode 
-
-       */
-
-       gemini_switch_map = readb( GEMINI_USWITCH );
-  
-       if ( gemini_switch_map & (1<<GEMINI_SWITCH_VERBOSE))
-               sprintf(cmd_line, "%s debug", cmd_line);
-
-       if ( gemini_switch_map & (1<<GEMINI_SWITCH_SINGLE_USER))
-               sprintf(cmd_line, "%s single", cmd_line);
-
        printk("Boot arguments: %s\n", cmd_line);
 
-       /* mutter some kind words about who made the CPU */
-       cpu = _get_PVR();
-       printk("CPU manufacturer: %s [rev=%04x]\n", (cpu & (1<<15)) ? "IBM" :
-              "Motorola", (cpu & 0xffff));
-
        ppc_md.heartbeat = gemini_heartbeat;
        ppc_md.heartbeat_reset = HZ/8;
        ppc_md.heartbeat_count = 1;
@@ -202,19 +183,17 @@ void __init gemini_setup_arch(void)
 int
 gemini_get_clock_speed(void)
 {
-       unsigned long hid1;
+       unsigned long hid1, pvr = _get_PVR();
        int clock;
-       unsigned char reg;
-  
-       hid1 = _get_HID1();
-       if ((_get_PVR()>>16) == 8)
+
+       hid1 = (_get_HID1() >> 28) & 0xf;
+       if (PVR_VER(pvr) == 8 ||
+           PVR_VER(pvr) == 12)
                hid1 = cpu_7xx[hid1];
        else
                hid1 = cpu_6xx[hid1];
 
-       reg = readb(GEMINI_BSTAT) & 0xc0;
-
-       switch( reg >> 2 ) {
+       switch((readb(GEMINI_BSTAT) & 0xc) >> 2) {
 
        case 0:
        default:
@@ -226,7 +205,7 @@ gemini_get_clock_speed(void)
                break;
   
        case 2:
-               clock = (hid1*50)/3;
+               clock = (hid1*50);
                break;
        }
 
@@ -242,83 +221,72 @@ gemini_get_clock_speed(void)
 
 void __init gemini_init_l2(void)
 {
-       unsigned char reg;
-       unsigned long cache;
-       int speed;
-
-       reg = readb(GEMINI_L2CFG);
-
-       /* 750's L2 initializes differently from a 604's.  Also note that a Grackle
-          bug will hang a dual-604 board, so make sure that doesn't happen by not
-          turning on the L2 */
-       if ( _get_PVR() >> 16 != 8 ) {
-     
-               /* check for dual cpus and cry sadly about the loss of an L2... */
-               if ((( readb(GEMINI_CPUSTAT) & 0x0c ) >> 2) != 1) 
-                       printk("Sorry. Your dual-604 does not allow the L2 to be enabled due "
-                              "to a Grackle bug.\n");
-               else if ( reg & GEMINI_L2_SIZE_MASK ) {
-                       printk("Enabling 604 L2 cache: %dKb\n", 
-                              (128<<((reg & GEMINI_L2_SIZE_MASK)>>6)));
-                       writeb( 1, GEMINI_L2CFG );
-               }
-       }
+        unsigned char reg, brev, fam, creg;
+        unsigned long cache;
+        unsigned long pvr = _get_PVR();
+
+        reg = readb(GEMINI_L2CFG);
+        brev = readb(GEMINI_BREV);
+        fam = readb(GEMINI_FEAT);
+
+        switch(PVR_VER(pvr)) {
+
+        case 8:
+                if (reg & 0xc0)
+                        cache = (((reg >> 6) & 0x3) << 28);
+                else
+                        cache = 0x3 << 28;
 
-       /* do a 750 */
-       else {
-               /* Synergy's first round of 750 boards had the L2 size stuff into the
-                  board register above.  If it's there, it's used; if not, the
-                  standard default is 1Mb.  The L2 type, I'm told, is "most likely
-                  probably always going to be late-write".  --Dan */
-
-               if (reg & 0xc0) {
-                       printk("Enabling 750 L2 cache: %dKb\n", 
-                              (128 << ((reg & 0xc0)>>6)));
-                       /* take the size given */
-                       cache = (((reg>>6) & 0x3)<<28);
-               }
-               else
-               {
-                       printk("Enabling 750 L2 cache: 1M\n");
-                       /* default of 1Mb */
-                       cache = 0x3<<28;
-               }
-               reg &= 0x3;
-
-               /* a cache ratio of 1:1 and CPU clock speeds in excess of 300Mhz are bad
-                  things.  If found, tune it down to 1:1.5.  -- Dan */
-               if (!reg) {
-
-printk("3\n");
-                       speed = gemini_get_clock_speed();
-   
-                       if (speed >= 300) {
-                               printk("Warning:  L2 ratio is 1:1 on a %dMhz processor.  Dropping to 1:1.5.\n",
-                                      speed );
-                               printk("Contact Synergy Microsystems for an ECO to fix this problem\n");
-                               reg = 0x1;
-                       }
-               }
-
-               /* standard stuff */
-               cache |= ((1<<reg)<<25);
 #ifdef CONFIG_SMP
-               /* A couple errata for the 750's (both IBM and Motorola silicon)
-                  note that you can get missed cache lines on MP implementations.
-                  The workaround - if you call it that - is to make the L2
-                  write-through.  This is fixed in IBM's 3.1 rev (I'm told), but
-                  for now, always make 2.x versions use L2 write-through. --Dan */
-               if (((_get_PVR()>>8) & 0xf) <= 2)
-               {
-                       cache |= L2CR_L2WT;
-                       printk("L2 cache: Enabling Write-Through due to 750 Errata.\n");
-               }
-#endif
-               cache |= L2CR_PIPE_LATEWR|L2CR_L2CTL|L2CR_INST_DISABLE;
-               _set_L2CR(0);
-               _set_L2CR(cache|L2CR_L2I|L2CR_L2E);
+                /* Pre-3.0 processor revs had snooping errata.  Leave
+                   their L2's disabled with SMP. -- Dan */
+                if (PVR_CFG(pvr) < 3) {
+                        printk("Pre-3.0 750; L2 left disabled!\n");
+                        return;
+                }
+#endif /* CONFIG_SMP */
+
+                /* Special case: VGM5-B's came before L2 ratios were set on
+                   the board.  Processor speed shouldn't be too high, so
+                   set L2 ratio to 1:1.5.  */
+                if ((brev == 0x51) && ((fam & 0xa0) >> 4) == 0)
+                        reg |= 1;
+
+                /* determine best cache ratio based upon what the board
+                   tells us (which sometimes _may_ not be true) and
+                   the processor speed. */
+                else {
+                        if (gemini_get_clock_speed() > 250)
+                                reg = 2;
+                }
+                break;
+        case 12:
+       {
+               static unsigned long l2_size_val = 0;
+               
+               if (!l2_size_val)
+                       l2_size_val = _get_L2CR();
+               cache = l2_size_val;
+                break;
        }
+        case 4:
+        case 9:
+                creg = readb(GEMINI_CPUSTAT);
+                if (((creg & 0xc) >> 2) != 1)
+                        printk("Dual-604 boards don't support the use of L2\n");
+                else
+                        writeb(1, GEMINI_L2CFG);
+                return;
+        default:
+                printk("Unknown processor; L2 left disabled\n");
+                return;
+        }
+
+        cache |= ((1<<reg) << 25);
+        cache |= (L2CR_PIPE_LATEWR|L2CR_L2CTL|L2CR_INST_DISABLE);
+        _set_L2CR(0);
+        _set_L2CR(cache | L2CR_L2I | L2CR_L2E);
+
 }
 
 void
@@ -540,8 +508,11 @@ void gemini_post_irq(struct pt_regs* regs, int irq)
 void __init gemini_init(unsigned long r3, unsigned long r4, unsigned long r5,
                        unsigned long r6, unsigned long r7)
 {
+       int i;
        int chrp_get_irq( struct pt_regs * );
-       void layout_bus( struct pci_bus * );
+
+       for(i = 0; i < GEMINI_LEDS; i++)
+               gemini_led_off(i);
  
        gemini_setup_pci_ptrs();
 
@@ -585,5 +556,5 @@ void __init gemini_init(unsigned long r3, unsigned long r4, unsigned long r5,
 #ifdef CONFIG_MAGIC_SYSRQ
        ppc_md.ppc_kbd_sysrq_xlate = NULL;
 #endif
-       ppc_md.pcibios_fixup_bus = layout_bus;
+       ppc_md.pcibios_fixup_bus = gemini_pcibios_fixup;
 }
index 218bb4ebbdf4ebcf9ef0f5c4aa7acf37468f03f8..6700806bd15950e70535ba68bfd96775525e52f1 100644 (file)
@@ -1274,6 +1274,7 @@ __secondary_start:
        ori     r3,r3,start_secondary@l
        mtspr   SRR0,r3
        mtspr   SRR1,r4
+       SYNC
        rfi
 #endif /* CONFIG_SMP */
 
@@ -1436,7 +1437,7 @@ start_here:
        tlbsync                 /* ... on all CPUs */
        sync
 #endif
-       
+
        bl      load_up_mmu
 
 /* Set up for using our exception vectors */
@@ -1544,6 +1545,28 @@ setup_screen_bat:
        mtspr   IBAT1U,r3
        blr
 #endif
+
+#ifdef CONFIG_8260
+/* Jump into the system reset for the rom.
+ * We first disable the MMU, and then jump to the ROM reset address.
+ *
+ * r3 is the board info structure, r4 is the location for starting.
+ * I use this for building a small kernel that can load other kernels,
+ * rather than trying to write or rely on a rom monitor that can tftp load.
+ */
+       .globl  m8260_gorom
+m8260_gorom:
+       li      r5,MSR_KERNEL & ~(MSR_IR|MSR_DR)
+       lis     r6,2f@h
+       addis   r6,r6,-KERNELBASE@h
+       ori     r6,r6,2f@l
+       mtspr   SRR0,r6
+       mtspr   SRR1,r5
+       rfi
+2:
+       mtlr    r4
+       blr
+#endif
        
 /*
  * We put a few things here that have to be page-aligned.
index 83f276585d90bf3277ef792d823ce8eaaf5a15d5..59b8a49c69496c06c62e4bd730f6e8a30288b5cc 100644 (file)
@@ -136,7 +136,7 @@ __start:
        mtspr   DC_CST, r8
        lis     r8, IDC_ENABLE@h
        mtspr   IC_CST, r8
-#if 0
+#ifdef CONFIG_8xx_COPYBACK
        mtspr   DC_CST, r8
 #else
        /* For a debug option, I left this here to easily enable
@@ -356,15 +356,26 @@ SystemCall:
  * only perform the attribute functions.
  */
 InstructionTLBMiss:
+#ifdef CONFIG_8xx_CPU6
+       stw     r3, 8(r0)
+       li      r3, 0x3f80
+       stw     r3, 12(r0)
+       lwz     r3, 12(r0)
+#endif
        mtspr   M_TW, r20       /* Save a couple of working registers */
        mfcr    r20
        stw     r20, 0(r0)
        stw     r21, 4(r0)
        mfspr   r20, SRR0       /* Get effective address of fault */
+#ifdef CONFIG_8xx_CPU6
+       li      r3, 0x3780
+       stw     r3, 12(r0)
+       lwz     r3, 12(r0)
+#endif
        mtspr   MD_EPN, r20     /* Have to use MD_EPN for walk, MI_EPN can't */
        mfspr   r20, M_TWB      /* Get level 1 table entry address */
        lwz     r21, 0(r20)     /* Get the level 1 entry */
-       rlwinm. r20, r21,0,0,20 /* Extract page descriptor page address */
+       rlwinm. r20, r21,0,0,19 /* Extract page descriptor page address */
        beq     2f              /* If zero, don't try to find a pte */
 
        /* We have a pte table, so load the MI_TWC with the attributes
@@ -372,88 +383,131 @@ InstructionTLBMiss:
         */
        tophys(r21,r21)
        ori     r21,r21,1               /* Set valid bit */
+#ifdef CONFIG_8xx_CPU6
+       li      r3, 0x2b80
+       stw     r3, 12(r0)
+       lwz     r3, 12(r0)
+#endif
        mtspr   MI_TWC, r21     /* Set page attributes */
+#ifdef CONFIG_8xx_CPU6
+       li      r3, 0x3b80
+       stw     r3, 12(r0)
+       lwz     r3, 12(r0)
+#endif
        mtspr   MD_TWC, r21     /* Load pte table base address */
        mfspr   r21, MD_TWC     /* ....and get the pte address */
-       lwz     r21, 0(r21)     /* Get the pte */
+       lwz     r20, 0(r21)     /* Get the pte */
+#if 0
+       ori     r20, r20, _PAGE_ACCESSED
+       stw     r20, 0(r21)
+#endif
 
        /* Set four subpage valid bits (24, 25, 26, and 27).
-        * Since we currently run MI_CTR.PPCS = 0, the manual says,
-        *      "If the page size is larger than 4k byte, then all the
-        *       4 bits should have the same value."
-        * I don't really know what to do if the page size is 4k Bytes,
-        * but I know setting them all to 0 does not work, and setting them
-        * all to 1 does, so that is the way it is right now.
-        * BTW, these four bits map to the software only bits in the
-        * linux page table.  I used to turn them all of, but now just
-        * set them all for the hardware.
-       li      r20, 0x00f0
-       andc    r20, r21, r20
-       ori     r20, r20, 0x0080
+        * Clear bit 28 (which should be in the PTE, but we do this anyway).
         */
-       ori     r20, r21, 0x00f0
-
+       li      r21, 0x00f0
+       rlwimi  r20, r21, 0, 24, 28
+#ifdef CONFIG_8xx_CPU6
+       li      r3, 0x2d80
+       stw     r3, 12(r0)
+       lwz     r3, 12(r0)
+#endif
        mtspr   MI_RPN, r20     /* Update TLB entry */
 
        mfspr   r20, M_TW       /* Restore registers */
        lwz     r21, 0(r0)
        mtcr    r21
        lwz     r21, 4(r0)
+#ifdef CONFIG_8xx_CPU6
+       lwz     r3, 8(r0)
+#endif
        rfi
 
 2:     mfspr   r20, M_TW       /* Restore registers */
        lwz     r21, 0(r0)
        mtcr    r21
        lwz     r21, 4(r0)
+#ifdef CONFIG_8xx_CPU6
+       lwz     r3, 8(r0)
+#endif
        b       InstructionAccess
 
        . = 0x1200
 DataStoreTLBMiss:
+#ifdef CONFIG_8xx_CPU6
+       stw     r3, 8(r0)
+       li      r3, 0x3f80
+       stw     r3, 12(r0)
+       lwz     r3, 12(r0)
+#endif
        mtspr   M_TW, r20       /* Save a couple of working registers */
        mfcr    r20
        stw     r20, 0(r0)
        stw     r21, 4(r0)
        mfspr   r20, M_TWB      /* Get level 1 table entry address */
        lwz     r21, 0(r20)     /* Get the level 1 entry */
-       rlwinm. r20, r21,0,0,20 /* Extract page descriptor page address */
+       rlwinm. r20, r21,0,0,19 /* Extract page descriptor page address */
        beq     2f              /* If zero, don't try to find a pte */
 
        /* We have a pte table, so load fetch the pte from the table.
         */
        tophys(r21, r21)
        ori     r21, r21, 1     /* Set valid bit in physical L2 page */
+#ifdef CONFIG_8xx_CPU6
+       li      r3, 0x3b80
+       stw     r3, 12(r0)
+       lwz     r3, 12(r0)
+#endif
        mtspr   MD_TWC, r21     /* Load pte table base address */
-       mfspr   r21, MD_TWC     /* ....and get the pte address */
-       lwz     r21, 0(r21)     /* Get the pte */
+       mfspr   r20, MD_TWC     /* ....and get the pte address */
+       lwz     r20, 0(r20)     /* Get the pte */
+
+       /* Insert the Guarded flag into the TWC from the Linux PTE.
+        * It is bit 27 of both the Linux PTE and the TWC (at least
+        * I got that right :-).  It will be better when we can put
+        * this into the Linux pgd/pmd and load it in the operation
+        * above.
+        */
+       rlwimi  r21, r20, 0, 27, 27
+#ifdef CONFIG_8xx_CPU6
+       li      r3, 0x3b80
+       stw     r3, 12(r0)
+       lwz     r3, 12(r0)
+#endif
+       mtspr   MD_TWC, r21
 
        /* Set four subpage valid bits (24, 25, 26, and 27).
-        * Since we currently run MD_CTR.PPCS = 0, the manual says,
-        *      "If the page size is larger than 4k byte, then all the
-        *       4 bits should have the same value."
-        * I don't really know what to do if the page size is 4k Bytes,
-        * but I know setting them all to 0 does not work, and setting them
-        * all to 1 does, so that is the way it is right now.
-        * BTW, these four bits map to the software only bits in the
-        * linux page table.  I used to turn them all of, but now just
-        * set them all for the hardware.
-       li      r20, 0x00f0
-       andc    r20, r21, r20
-       ori     r20, r20, 0x0080
+        * Clear bit 28 (which should be in the PTE, but we do this anyway).
         */
-       ori     r20, r21, 0x00f0
-
+#if 0
+       ori     r20, r20, 0x00f0
+#else
+       li      r21, 0x00f0
+       rlwimi  r20, r21, 0, 24, 28
+#endif
+#ifdef CONFIG_8xx_CPU6
+       li      r3, 0x3d80
+       stw     r3, 12(r0)
+       lwz     r3, 12(r0)
+#endif
        mtspr   MD_RPN, r20     /* Update TLB entry */
 
        mfspr   r20, M_TW       /* Restore registers */
        lwz     r21, 0(r0)
        mtcr    r21
        lwz     r21, 4(r0)
+#ifdef CONFIG_8xx_CPU6
+       lwz     r3, 8(r0)
+#endif
        rfi
 
 2:     mfspr   r20, M_TW       /* Restore registers */
        lwz     r21, 0(r0)
        mtcr    r21
        lwz     r21, 4(r0)
+#ifdef CONFIG_8xx_CPU6
+       lwz     r3, 8(r0)
+#endif
        b       DataAccess
 
 /* This is an instruction TLB error on the MPC8xx.  This could be due
@@ -474,6 +528,12 @@ InstructionTLBError:
  */
        . = 0x1400
 DataTLBError:
+#ifdef CONFIG_8xx_CPU6
+       stw     r3, 8(r0)
+       li      r3, 0x3f80
+       stw     r3, 12(r0)
+       lwz     r3, 12(r0)
+#endif
        mtspr   M_TW, r20       /* Save a couple of working registers */
        mfcr    r20
        stw     r20, 0(r0)
@@ -487,52 +547,59 @@ DataTLBError:
 
        mfspr   r20, M_TWB      /* Get level 1 table entry address */
        lwz     r21, 0(r20)     /* Get the level 1 entry */
-       rlwinm. r20, r21,0,0,20 /* Extract page descriptor page address */
+       rlwinm. r20, r21,0,0,19 /* Extract page descriptor page address */
        beq     2f              /* If zero, bail */
 
        /* We have a pte table, so fetch the pte from the table.
         */
        tophys(r21, r21)
        ori     r21, r21, 1             /* Set valid bit in physical L2 page */
+#ifdef CONFIG_8xx_CPU6
+       li      r3, 0x3b80
+       stw     r3, 12(r0)
+       lwz     r3, 12(r0)
+#endif
        mtspr   MD_TWC, r21             /* Load pte table base address */
        mfspr   r21, MD_TWC             /* ....and get the pte address */
-       lwz     r21, 0(r21)             /* Get the pte */
+       lwz     r20, 0(r21)             /* Get the pte */
 
-       andi.   r20, r21, _PAGE_RW      /* Is it writeable? */
+       andi.   r21, r20, _PAGE_RW      /* Is it writeable? */
        beq     2f                      /* Bail out if not */
 
-       ori     r21, r21, _PAGE_DIRTY   /* Update changed bit */
-       mfspr   r20, MD_TWC             /* Get pte address again */
-       stw     r21, 0(r20)             /* and update pte in table */
+       /* Update 'changed', among others.
+       */
+       ori     r20, r20, _PAGE_DIRTY|_PAGE_HWWRITE|_PAGE_ACCESSED
+       mfspr   r21, MD_TWC             /* Get pte address again */
+       stw     r20, 0(r21)             /* and update pte in table */
 
        /* Set four subpage valid bits (24, 25, 26, and 27).
-        * Since we currently run MD_CTR.PPCS = 0, the manual says,
-        *      "If the page size is larger than 4k byte, then all the
-        *       4 bits should have the same value."
-        * I don't really know what to do if the page size is 4k Bytes,
-        * but I know setting them all to 0 does not work, and setting them
-        * all to 1 does, so that is the way it is right now.
-        * BTW, these four bits map to the software only bits in the
-        * linux page table.  I used to turn them all of, but now just
-        * set them all for the hardware.
-       li      r20, 0x00f0
-       andc    r20, r21, r20
-       ori     r20, r20, 0x0080
+        * Clear bit 28 (which should be in the PTE, but we do this anyway).
         */
-       ori     r20, r21, 0x00f0
-
+       li      r21, 0x00f0
+       rlwimi  r20, r21, 0, 24, 28
+#ifdef CONFIG_8xx_CPU6
+       li      r3, 0x3d80
+       stw     r3, 12(r0)
+       lwz     r3, 12(r0)
+#endif
        mtspr   MD_RPN, r20     /* Update TLB entry */
 
        mfspr   r20, M_TW       /* Restore registers */
        lwz     r21, 0(r0)
        mtcr    r21
        lwz     r21, 4(r0)
+#ifdef CONFIG_8xx_CPU6
+       lwz     r3, 8(r0)
+#endif
        rfi
 2:
        mfspr   r20, M_TW       /* Restore registers */
        lwz     r21, 0(r0)
        mtcr    r21
        lwz     r21, 4(r0)
+#ifdef CONFIG_8xx_CPU6
+       lwz     r3, 8(r0)
+#endif
        b       DataAccess
 
        STD_EXCEPTION(0x1500, Trap_15, UnknownException)
@@ -542,6 +609,7 @@ DataTLBError:
        STD_EXCEPTION(0x1900, Trap_19, UnknownException)
        STD_EXCEPTION(0x1a00, Trap_1a, UnknownException)
        STD_EXCEPTION(0x1b00, Trap_1b, UnknownException)
+
 /* On the MPC8xx, these next four traps are used for development
  * support of breakpoints and such.  Someday I will get around to
  * using them.
index c0cc492adb6b1ad43509dc0f3065eaa75c43c866..28be8bf46c97225263c708b2a6c43b434b635334 100644 (file)
@@ -117,9 +117,9 @@ void irq_kfree(void *ptr)
        kfree(ptr);
 }
 
-#ifdef CONFIG_8xx
+#if (defined(CONFIG_8xx) || defined(CONFIG_8260))
 /* Name change so we can catch standard drivers that potentially mess up
- * the internal interrupt controller on 8xx and 82xx.  Just bear with me,
+ * the internal interrupt controller on 8xx and 8260.  Just bear with me,
  * I don't like this either and I am searching a better solution.  For
  * now, this is what I need. -- Dan
  */
@@ -194,10 +194,10 @@ void sys_free_irq(unsigned int irq, void *dev_id)
 #else
 void free_irq(unsigned int irq, void *dev_id)
 {
-#ifndef CONFIG_8xx
-       request_irq(irq, NULL, 0, NULL, dev_id);
-#else
+#if (defined(CONFIG_8xx) || defined(CONFIG_8260))
        request_8xxirq(irq, NULL, 0, NULL, dev_id);
+#else
+       request_irq(irq, NULL, 0, NULL, dev_id);
 #endif
 }
 #endif
diff --git a/arch/ppc/kernel/m8260_setup.c b/arch/ppc/kernel/m8260_setup.c
new file mode 100644 (file)
index 0000000..65ea973
--- /dev/null
@@ -0,0 +1,303 @@
+/*
+ * $Id: m8xx_setup.c,v 1.4 1999/09/18 18:40:36 dmalek Exp $
+ *
+ *  linux/arch/ppc/kernel/setup.c
+ *
+ *  Copyright (C) 1995  Linus Torvalds
+ *  Adapted from 'alpha' version by Gary Thomas
+ *  Modified by Cort Dougan (cort@cs.nmt.edu)
+ *  Modified for MBX using prep/chrp/pmac functions by Dan (dmalek@jlc.net)
+ *  Further modified for generic 8xx and 8260 by Dan.
+ */
+
+/*
+ * bootup setup stuff..
+ */
+
+#include <linux/config.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/stddef.h>
+#include <linux/unistd.h>
+#include <linux/ptrace.h>
+#include <linux/malloc.h>
+#include <linux/user.h>
+#include <linux/a.out.h>
+#include <linux/tty.h>
+#include <linux/major.h>
+#include <linux/interrupt.h>
+#include <linux/reboot.h>
+#include <linux/init.h>
+#include <linux/blk.h>
+#include <linux/ioport.h>
+#include <linux/ide.h>
+
+#include <asm/mmu.h>
+#include <asm/processor.h>
+#include <asm/residual.h>
+#include <asm/io.h>
+#include <asm/pgtable.h>
+#include <asm/ide.h>
+#include <asm/mpc8260.h>
+#include <asm/immap_8260.h>
+#include <asm/machdep.h>
+
+#include "time.h"
+#include "ppc8260_pic.h"
+
+static int m8260_set_rtc_time(unsigned long time);
+unsigned long m8260_get_rtc_time(void);
+void m8260_calibrate_decr(void);
+
+#if 0
+extern int mackbd_setkeycode(unsigned int scancode, unsigned int keycode);
+extern int mackbd_getkeycode(unsigned int scancode);
+extern int mackbd_pretranslate(unsigned char scancode, char raw_mode);
+extern int mackbd_translate(unsigned char scancode, unsigned char *keycode,
+                          char raw_mode);
+extern char mackbd_unexpected_up(unsigned char keycode);
+extern void mackbd_leds(unsigned char leds);
+extern void mackbd_init_hw(void);
+#endif
+
+extern unsigned long loops_per_sec;
+
+unsigned char __res[sizeof(bd_t)];
+unsigned long empty_zero_page[1024];
+
+#ifdef CONFIG_BLK_DEV_RAM
+extern int rd_doload;          /* 1 = load ramdisk, 0 = don't load */
+extern int rd_prompt;          /* 1 = prompt for ramdisk, 0 = don't prompt */
+extern int rd_image_start;     /* starting block # of image */
+#endif
+
+extern char saved_command_line[256];
+
+extern unsigned long find_available_memory(void);
+extern void m8260_cpm_reset(void);
+
+void __init adbdev_init(void)
+{
+}
+
+void __init
+m8260_setup_arch(void)
+{
+       extern char cmd_line[];
+       
+       printk("Boot arguments: %s\n", cmd_line);
+
+       /* Reset the Communication Processor Module.
+       */
+       m8260_cpm_reset();
+}
+
+void
+abort(void)
+{
+#ifdef CONFIG_XMON
+       extern void xmon(void *);
+       xmon(0);
+#endif
+       machine_restart(NULL);
+}
+
+/* The decrementer counts at the system (internal) clock frequency
+ * divided by four.
+ */
+void __init m8260_calibrate_decr(void)
+{
+       bd_t    *binfo = (bd_t *)__res;
+       int freq, divisor;
+
+       freq = (binfo->bi_intfreq * 1000000);
+        divisor = 16;
+        decrementer_count = freq / HZ / divisor;
+        count_period_num = divisor;
+        count_period_den = freq / 1000000;
+}
+
+/* The 8260 has an internal 1-second timer update register that
+ * we should use for this purpose.
+ */
+static uint    rtc_time;
+static int
+m8260_set_rtc_time(unsigned long time)
+{
+       rtc_time = time;
+       return(0);
+}
+
+unsigned long __init
+m8260_get_rtc_time(void)
+{
+
+       /* Get time from the RTC.
+       */
+       return((unsigned long)rtc_time);
+}
+
+void
+m8260_restart(char *cmd)
+{
+       extern void m8260_gorom(bd_t *bi, uint addr);
+
+       m8260_gorom(NULL, 0xff000100);
+}
+
+void
+m8260_power_off(void)
+{
+   m8260_restart(NULL);
+}
+
+void
+m8260_halt(void)
+{
+   m8260_restart(NULL);
+}
+
+
+int m8260_setup_residual(char *buffer)
+{
+        int     len = 0;
+       bd_t    *bp;
+
+       bp = (bd_t *)__res;
+                       
+       len += sprintf(len+buffer,"clock\t\t: %dMHz\n"
+                      "bus clock\t: %dMHz\n",
+                      bp->bi_intfreq /*/ 1000000*/,
+                      bp->bi_busfreq /*/ 1000000*/);
+
+       return len;
+}
+
+/* Initialize the internal interrupt controller.  The number of
+ * interrupts supported can vary with the processor type, and the
+ * 8260 family can have up to 64.
+ * External interrupts can be either edge or level triggered, and
+ * need to be initialized by the appropriate driver.
+ */
+void __init
+m8260_init_IRQ(void)
+{
+       int i;
+       void cpm_interrupt_init(void);
+
+#if 0
+        ppc8260_pic.irq_offset = 0;
+#endif
+        for ( i = 0 ; i < NR_SIU_INTS ; i++ )
+                irq_desc[i].handler = &ppc8260_pic;
+       
+       /* Initialize the default interrupt mapping priorities,
+        * in case the boot rom changed something on us.
+        */
+       immr->im_intctl.ic_sicr = 0;
+       immr->im_intctl.ic_siprr = 0x05309770;
+       immr->im_intctl.ic_scprrh = 0x05309770;
+       immr->im_intctl.ic_scprrl = 0x05309770;
+
+}
+
+
+void __init
+m8260_init(unsigned long r3, unsigned long r4, unsigned long r5,
+        unsigned long r6, unsigned long r7)
+{
+
+       if ( r3 )
+               memcpy( (void *)__res,(void *)(r3+KERNELBASE), sizeof(bd_t) );
+       
+#ifdef CONFIG_BLK_DEV_INITRD
+       /* take care of initrd if we have one */
+       if ( r4 )
+       {
+               initrd_start = r4 + KERNELBASE;
+               initrd_end = r5 + KERNELBASE;
+       }
+#endif /* CONFIG_BLK_DEV_INITRD */
+       /* take care of cmd line */
+       if ( r6 )
+       {
+               
+               *(char *)(r7+KERNELBASE) = 0;
+               strcpy(cmd_line, (char *)(r6+KERNELBASE));
+       }
+
+       ppc_md.setup_arch     = m8260_setup_arch;
+       ppc_md.setup_residual = m8260_setup_residual;
+       ppc_md.get_cpuinfo    = NULL;
+       ppc_md.irq_cannonicalize = NULL;
+       ppc_md.init_IRQ       = m8260_init_IRQ;
+       ppc_md.get_irq        = m8260_get_irq;
+       ppc_md.init           = NULL;
+
+       ppc_md.restart        = m8260_restart;
+       ppc_md.power_off      = m8260_power_off;
+       ppc_md.halt           = m8260_halt;
+
+       ppc_md.time_init      = NULL;
+       ppc_md.set_rtc_time   = m8260_set_rtc_time;
+       ppc_md.get_rtc_time   = m8260_get_rtc_time;
+       ppc_md.calibrate_decr = m8260_calibrate_decr;
+
+#if 0
+       ppc_md.kbd_setkeycode    = pckbd_setkeycode;
+       ppc_md.kbd_getkeycode    = pckbd_getkeycode;
+       ppc_md.kbd_pretranslate  = pckbd_pretranslate;
+       ppc_md.kbd_translate     = pckbd_translate;
+       ppc_md.kbd_unexpected_up = pckbd_unexpected_up;
+       ppc_md.kbd_leds          = pckbd_leds;
+       ppc_md.kbd_init_hw       = pckbd_init_hw;
+#ifdef CONFIG_MAGIC_SYSRQ
+       ppc_md.kbd_sysrq_xlate   = pckbd_sysrq_xlate;
+#endif
+#else
+       ppc_md.kbd_setkeycode    = NULL;
+       ppc_md.kbd_getkeycode    = NULL;
+       ppc_md.kbd_translate     = NULL;
+       ppc_md.kbd_unexpected_up = NULL;
+       ppc_md.kbd_leds          = NULL;
+       ppc_md.kbd_init_hw       = NULL;
+#ifdef CONFIG_MAGIC_SYSRQ
+       ppc_md.kbd_sysrq_xlate   = NULL;
+#endif
+#endif
+
+#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
+        ppc_ide_md.insw = m8xx_ide_insw;
+        ppc_ide_md.outsw = m8xx_ide_outsw;
+        ppc_ide_md.default_irq = m8xx_ide_default_irq;
+        ppc_ide_md.default_io_base = m8xx_ide_default_io_base;
+        ppc_ide_md.check_region = m8xx_ide_check_region;
+        ppc_ide_md.request_region = m8xx_ide_request_region;
+        ppc_ide_md.release_region = m8xx_ide_release_region;
+        ppc_ide_md.fix_driveid = m8xx_ide_fix_driveid;
+        ppc_ide_md.ide_init_hwif = m8xx_ide_init_hwif_ports;
+        ppc_ide_md.ide_request_irq = m8xx_ide_request_irq;
+
+        ppc_ide_md.io_base = _IO_BASE;
+#endif         
+}
+
+void
+prom_init(uint r3, uint r4, uint r5, uint r6)
+{
+       /* Nothing to do now, but we are called immediatedly upon
+        * kernel start up with MMU disabled, so if there is
+        * anything we need to do......
+        */
+}
+
+/* Mainly for ksyms.
+*/
+int
+request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *),
+                      unsigned long flag, const char *naem, void *dev)
+{
+       panic("request IRQ\n");
+}
index a417bed2eb7b71ee78daf4013cea32b8f9c6b7a8..9f0a517e3a9d9b8c7f57580a99c6ccb16692d218 100644 (file)
@@ -130,7 +130,6 @@ void
 abort(void)
 {
 #ifdef CONFIG_XMON
-       extern void xmon(void *);
        xmon(0);
 #endif
        machine_restart(NULL);
index e4fbefbc337c9c33f3038c3f8ee03f3f7768a0ef..96adb96cd402294aa82d87202804c54fff8564ed 100644 (file)
@@ -18,6 +18,7 @@
 #include <asm/errno.h>
 #include <asm/processor.h>
 #include <asm/page.h>
+#include <asm/cache.h>
 #include "ppc_asm.h"
 
 #if defined(CONFIG_4xx) || defined(CONFIG_8xx)
@@ -165,6 +166,11 @@ _GLOBAL(_tlbie)
  * This is a no-op on the 601.
  */
 _GLOBAL(flush_instruction_cache)
+#ifdef CONFIG_8xx
+       isync
+       lis     r5, IDC_INVALL@h
+       mtspr   IC_CST, r5
+#else
        mfspr   r3,PVR
        rlwinm  r3,r3,16,16,31
        cmpi    0,r3,1
@@ -173,6 +179,7 @@ _GLOBAL(flush_instruction_cache)
        mfspr   r3,HID0
        ori     r3,r3,HID0_ICFI
        mtspr   HID0,r3
+#endif /* CONFIG_8xx */
        SYNC
        blr
 
@@ -241,8 +248,7 @@ _GLOBAL(__flush_page_to_ram)
        rlwinm  r5,r5,16,16,31
        cmpi    0,r5,1
        beqlr                           /* for 601, do nothing */
-       li      r4,0x0FFF
-       andc    r3,r3,r4                /* Get page base address */
+       rlwinm  r3,r3,0,0,19            /* Get page base address */
        li      r4,4096/CACHE_LINE_SIZE /* Number of lines in a page */
        mtctr   r4
        mr      r6,r3
@@ -373,6 +379,7 @@ _GLOBAL(__spin_trylock)
  * void atomic_clear_mask(atomic_t mask, atomic_t *addr)
  * void atomic_set_mask(atomic_t mask, atomic_t *addr);
  */
+#if 0 /* now inline - paulus */
 _GLOBAL(atomic_add)
 10:    lwarx   r5,0,r4         /* Fetch old value & reserve */
        add     r5,r5,r3        /* Perform 'add' operation */
@@ -423,11 +430,10 @@ _GLOBAL(atomic_dec_and_test)
        subi    r5,r5,1         /* Perform 'add' operation */
        stwcx.  r5,0,r3         /* Update with new value */
        bne-    10b             /* Retry if "reservation" (i.e. lock) lost */
-       cmpi    0,r5,0          /* Return 'true' IFF 0 */
-       li      r3,1
-       beqlr
-       li      r3,0
+       cntlzw  r3,r5
+       srwi    r3,r3,5         
        blr
+#endif /* 0 */
 _GLOBAL(atomic_clear_mask)
 10:    lwarx   r5,0,r4
        andc    r5,r5,r3
index a3a9bae709e85f80813cbe88dc7ec2bf6595e0ed..db0632238fb1f1009952320165dda9453c7656ff 100644 (file)
@@ -7,14 +7,18 @@
 #include <linux/nvram.h>
 #include <linux/init.h>
 #include <linux/slab.h>
+#include <linux/delay.h>
 #include <asm/init.h>
 #include <asm/io.h>
 #include <asm/system.h>
 #include <asm/prom.h>
 #include <asm/machdep.h>
+#include <asm/nvram.h>
 #include <linux/adb.h>
 #include <linux/pmu.h>
 
+#undef DEBUG
+
 /*
  * Read and write the non-volatile RAM on PowerMacs and CHRP machines.
  */
@@ -23,9 +27,191 @@ static volatile unsigned char *nvram_addr;
 static volatile unsigned char *nvram_data;
 static int nvram_mult, is_core_99;
 static char* nvram_image;
+static int core99_bank = 0;
+
+extern int pmac_newworld;
  
 #define NVRAM_SIZE             0x2000  /* 8kB of non-volatile RAM */
  
+#define CORE99_SIGNATURE       0x5a
+#define CORE99_ADLER_START     0x14
+
+/* Core99 nvram is a flash */
+#define CORE99_FLASH_STATUS_DONE       0x80
+#define CORE99_FLASH_STATUS_ERR                0x38
+#define CORE99_FLASH_CMD_ERASE_CONFIRM 0xd0
+#define CORE99_FLASH_CMD_ERASE_SETUP   0x20
+#define CORE99_FLASH_CMD_RESET         0xff
+#define CORE99_FLASH_CMD_WRITE_SETUP   0x40
+
+/* CHRP NVRAM header */
+struct chrp_header {
+  u8           signature;
+  u8           cksum;
+  u16          len;
+  char          name[12];
+  u8           data[0];
+};
+
+struct core99_header {
+  struct chrp_header   hdr;
+  u32                  adler;
+  u32                  generation;
+  u32                  reserved[2];
+};
+
+static int nvram_partitions[3];
+
+static u8
+chrp_checksum(struct chrp_header* hdr)
+{
+       u8 *ptr;
+       u16 sum = hdr->signature;
+       for (ptr = (u8 *)&hdr->len; ptr < hdr->data; ptr++)
+               sum += *ptr;
+       while (sum > 0xFF)
+               sum = (sum & 0xFF) + (sum>>8);
+       return sum;
+}
+
+static u32
+core99_calc_adler(u8 *buffer)
+{
+       int cnt;
+       u32 low, high;
+
+       buffer += CORE99_ADLER_START;
+       low = 1;
+       high = 0;
+       for (cnt=0; cnt<(NVRAM_SIZE-CORE99_ADLER_START); cnt++) {
+               if ((cnt % 5000) == 0) {
+                       high  %= 65521UL;
+                       high %= 65521UL;
+               }
+               low += buffer[cnt];
+               high += low;
+       }
+       low  %= 65521UL;
+       high %= 65521UL;
+  
+       return (high << 16) | low;
+}
+
+static u32
+core99_check(u8* datas)
+{
+       struct core99_header* hdr99 = (struct core99_header*)datas;
+
+       if (hdr99->hdr.signature != CORE99_SIGNATURE) {
+#ifdef DEBUG
+               printk("Invalid signature\n");
+#endif         
+               return 0;
+       }
+       if (hdr99->hdr.cksum != chrp_checksum(&hdr99->hdr)) {
+#ifdef DEBUG
+               printk("Invalid checksum\n");
+#endif
+               return 0;
+       }
+       if (hdr99->adler != core99_calc_adler(datas)) {
+#ifdef DEBUG
+               printk("Invalid adler\n");
+#endif
+               return 0;
+       }
+       return hdr99->generation;
+}
+
+static int
+core99_erase_bank(int bank)
+{
+       int stat, i;
+       
+       u8* base = (u8 *)nvram_data + core99_bank*NVRAM_SIZE;
+       
+       out_8(base, CORE99_FLASH_CMD_ERASE_SETUP);
+       out_8(base, CORE99_FLASH_CMD_ERASE_CONFIRM);
+       do { stat = in_8(base); }
+       while(!(stat & CORE99_FLASH_STATUS_DONE));
+       out_8(base, CORE99_FLASH_CMD_RESET);
+       if (stat & CORE99_FLASH_STATUS_ERR) {
+               printk("nvram: flash error 0x%02x on erase !\n", stat);
+               return -ENXIO;
+       }
+       for (i=0; i<NVRAM_SIZE; i++)
+               if (base[i] != 0xff) {
+                       printk("nvram: flash erase failed !\n");
+                       return -ENXIO;
+               }
+       return 0;
+}
+
+static int
+core99_write_bank(int bank, u8* datas)
+{
+       int i, stat = 0;
+       
+       u8* base = (u8 *)nvram_data + core99_bank*NVRAM_SIZE;
+       
+       for (i=0; i<NVRAM_SIZE; i++) {
+               out_8(base+i, CORE99_FLASH_CMD_WRITE_SETUP);
+               out_8(base+i, datas[i]);
+               do { stat = in_8(base); }
+               while(!(stat & CORE99_FLASH_STATUS_DONE));
+               if (stat & CORE99_FLASH_STATUS_ERR)
+                       break;
+       }
+       out_8(base, CORE99_FLASH_CMD_RESET);
+       if (stat & CORE99_FLASH_STATUS_ERR) {
+               printk("nvram: flash error 0x%02x on write !\n", stat);
+               return -ENXIO;
+       }
+       for (i=0; i<NVRAM_SIZE; i++)
+               if (base[i] != datas[i]) {
+                       printk("nvram: flash write failed !\n");
+                       return -ENXIO;
+               }
+       return 0;       
+}
+
+static void
+lookup_partitions(void)
+{
+       u8 buffer[17];
+       int i, offset;
+       struct chrp_header* hdr;
+
+       if (pmac_newworld) {
+               nvram_partitions[pmac_nvram_OF] = -1;
+               nvram_partitions[pmac_nvram_XPRAM] = -1;
+               nvram_partitions[pmac_nvram_NR] = -1;
+               hdr = (struct chrp_header *)buffer;
+       
+               offset = 0;
+               do {
+                       for (i=0;i<16;i++)
+                               buffer[i] = nvram_read_byte(offset+i);
+                       if (!strcmp(hdr->name, "common"))
+                               nvram_partitions[pmac_nvram_OF] = offset + 0x10;
+                       if (!strcmp(hdr->name, "APL,MacOS75")) {
+                               nvram_partitions[pmac_nvram_XPRAM] = offset + 0x10;
+                               nvram_partitions[pmac_nvram_NR] = offset + 0x110;
+                       }
+                       offset += (hdr->len * 0x10);
+               } while(offset < NVRAM_SIZE);
+       } else {
+               nvram_partitions[pmac_nvram_OF] = 0x1800;
+               nvram_partitions[pmac_nvram_XPRAM] = 0x1300;
+               nvram_partitions[pmac_nvram_NR] = 0x1400;
+       }       
+#ifdef DEBUG
+       printk("nvram: OF partition at 0x%x\n", nvram_partitions[pmac_nvram_OF]);
+       printk("nvram: XP partition at 0x%x\n", nvram_partitions[pmac_nvram_XPRAM]);
+       printk("nvram: NR partition at 0x%x\n", nvram_partitions[pmac_nvram_NR]);
+#endif 
+}
+
 __init
 void pmac_nvram_init(void)
 {
@@ -40,17 +226,32 @@ void pmac_nvram_init(void)
        }
        nvram_naddrs = dp->n_addrs;
        is_core_99 = device_is_compatible(dp, "nvram,flash");
-       if (is_core_99)
-       {
+       if (is_core_99) {
                int i;
-               if (nvram_naddrs < 1)
+               u32 gen_bank0, gen_bank1;
+               
+               if (nvram_naddrs < 1) {
+                       printk(KERN_ERR "nvram: no address\n");
                        return;
-               nvram_image = kmalloc(dp->addrs[0].size, GFP_KERNEL);
-               if (!nvram_image)
+               }
+               nvram_image = kmalloc(NVRAM_SIZE, GFP_KERNEL);
+               if (!nvram_image) {
+                       printk(KERN_ERR "nvram: can't allocate image\n");
                        return;
-               nvram_data = ioremap(dp->addrs[0].address, dp->addrs[0].size);
-               for (i=0; i<dp->addrs[0].size; i++)
-                       nvram_image[i] = in_8(nvram_data + i);
+               }
+               nvram_data = ioremap(dp->addrs[0].address, NVRAM_SIZE*2);
+#ifdef DEBUG
+               printk("nvram: Checking bank 0...\n");
+#endif
+               gen_bank0 = core99_check((u8 *)nvram_data);
+               gen_bank1 = core99_check((u8 *)nvram_data + NVRAM_SIZE);
+               core99_bank = (gen_bank0 < gen_bank1) ? 1 : 0;
+#ifdef DEBUG
+               printk("nvram: gen0=%d, gen1=%d\n", gen_bank0, gen_bank1);
+               printk("nvram: Active bank is: %d\n", core99_bank);
+#endif
+               for (i=0; i<NVRAM_SIZE; i++)
+                       nvram_image[i] = nvram_data[i + core99_bank*NVRAM_SIZE];
        } else if (_machine == _MACH_chrp && nvram_naddrs == 1) {
                nvram_data = ioremap(dp->addrs[0].address, dp->addrs[0].size);
                nvram_mult = 1;
@@ -68,6 +269,33 @@ void pmac_nvram_init(void)
        }
 }
 
+void
+pmac_nvram_update(void)
+{
+       struct core99_header* hdr99;
+       
+       if (!is_core_99 || !nvram_data || !nvram_image)
+               return;
+       if (!memcmp(nvram_image, (u8*)nvram_data + core99_bank*NVRAM_SIZE,
+               NVRAM_SIZE))
+               return;
+#ifdef DEBUG
+       printk("Updating nvram...\n");
+#endif
+       hdr99 = (struct core99_header*)nvram_image;
+       hdr99->generation++;
+       hdr99->hdr.signature = CORE99_SIGNATURE;
+       hdr99->hdr.cksum = chrp_checksum(&hdr99->hdr);
+       hdr99->adler = core99_calc_adler(nvram_image);
+       core99_bank = core99_bank ? 0 : 1;
+       if (core99_erase_bank(core99_bank)) {
+               printk("nvram: Error erasing bank %d\n", core99_bank);
+               return;
+       }
+       if (core99_write_bank(core99_bank, nvram_image))
+               printk("nvram: Error writing bank %d\n", core99_bank);
+}
+
 __openfirmware
 unsigned char nvram_read_byte(int addr)
 {
@@ -125,3 +353,33 @@ void nvram_write_byte(unsigned char val, int addr)
        }
        eieio();
 }
+
+int
+pmac_get_partition(int partition)
+{
+       return nvram_partitions[partition];
+}
+
+u8
+pmac_xpram_read(int xpaddr)
+{
+       int offset = nvram_partitions[pmac_nvram_XPRAM];
+       
+       if (offset < 0)
+               return 0;
+               
+       return nvram_read_byte(xpaddr + offset);
+}
+
+void
+pmac_xpram_write(int xpaddr, u8 data)
+{
+       int offset = nvram_partitions[pmac_nvram_XPRAM];
+       
+       if (offset < 0)
+               return;
+               
+       nvram_write_byte(xpaddr + offset, data);
+}
+
+
index b57d5aa281f1ee59d42a24cc1e6286bffefde84e..ee54ba37d19129af64bbf6cd5884182a4cbe9510 100644 (file)
@@ -525,7 +525,8 @@ static void __init init_bandit(struct bridge_data *bp)
               bp->io_base);
 }
 
-#define GRACKLE_STG_ENABLE 0x00000040
+#define GRACKLE_PICR1_STG              0x00000040
+#define GRACKLE_PICR1_LOOPSNOOP                0x00000010
 
 /* N.B. this is called before bridges is initialized, so we can't
    use grackle_pcibios_{read,write}_config_dword. */
@@ -535,11 +536,25 @@ static inline void grackle_set_stg(struct bridge_data *bp, int enable)
 
        out_be32(bp->cfg_addr, GRACKLE_CFA(0, 0, 0xa8));
        val = in_le32((volatile unsigned int *)bp->cfg_data);
-       val = enable? (val | GRACKLE_STG_ENABLE): (val & ~GRACKLE_STG_ENABLE);
+       val = enable? (val | GRACKLE_PICR1_STG) :
+               (val & ~GRACKLE_PICR1_STG);
        out_be32(bp->cfg_addr, GRACKLE_CFA(0, 0, 0xa8));
        out_le32((volatile unsigned int *)bp->cfg_data, val);
 }
 
+static inline void grackle_set_loop_snoop(struct bridge_data *bp, int enable)
+{
+       unsigned int val;
+
+       out_be32(bp->cfg_addr, GRACKLE_CFA(0, 0, 0xa8));
+       val = in_le32((volatile unsigned int *)bp->cfg_data);
+       val = enable? (val | GRACKLE_PICR1_LOOPSNOOP) :
+               (val & ~GRACKLE_PICR1_LOOPSNOOP);
+       out_be32(bp->cfg_addr, GRACKLE_CFA(0, 0, 0xa8));
+       out_le32((volatile unsigned int *)bp->cfg_data, val);
+}
+
+
 void __init pmac_find_bridges(void)
 {
        int bus;
@@ -620,7 +635,9 @@ static void __init add_bridges(struct device_node *dev)
                        bp->cfg_data = (volatile unsigned char *)
                                ioremap(0xfee00000, 0x1000);
                         bp->io_base = (void *) ioremap(0xfe000000, 0x20000);
-#if 0 /* Disabled for now, HW problems */
+                        if (machine_is_compatible("AAPL,PowerBook1998"))
+                               grackle_set_loop_snoop(bp, 1);
+#if 0                  /* Disabled for now, HW problems ??? */
                        grackle_set_stg(bp, 1);
 #endif
                } else {
index b58d69fc948ffcd7fa897648f7197e08b95a77e8..ab2fdbc15661da0bf008112fc418e04384101a5f 100644 (file)
@@ -158,13 +158,13 @@ static void gatwick_action(int cpl, void *dev_id, struct pt_regs *regs)
 {
        int irq, bits;
        
-       for (irq = max_irqs - 1; irq > max_real_irqs; irq -= 32) {
+       for (irq = max_irqs; (irq -= 32) >= max_real_irqs; ) {
                int i = irq >> 5;
                bits = ld_le32(&pmac_irq_hw[i]->flag)
                        | ppc_lost_interrupts[i];
                if (bits == 0)
                        continue;
-               irq -= cntlzw(bits);
+               irq += __ilog2(bits);
                break;
        }
        /* The previous version of this code allowed for this case, we
@@ -213,13 +213,13 @@ pmac_get_irq(struct pt_regs *regs)
        }
        else
        {
-               for (irq = max_real_irqs - 1; irq > 0; irq -= 32) {
+               for (irq = max_real_irqs; (irq -= 32) >= 0; ) {
                        int i = irq >> 5;
                        bits = ld_le32(&pmac_irq_hw[i]->flag)
                                | ppc_lost_interrupts[i];
                        if (bits == 0)
                                continue;
-                       irq -= cntlzw(bits);
+                       irq += __ilog2(bits);
                        break;
                }
        }
@@ -489,11 +489,9 @@ sleep_save_intrs(int viaint)
        if (max_real_irqs > 32)
                out_le32(&pmac_irq_hw[1]->enable, ppc_cached_irq_mask[1]);
        (void)in_le32(&pmac_irq_hw[0]->flag);
-        do {
-                /* make sure mask gets to controller before we
-                   return to user */
-                mb();
-        } while(in_le32(&pmac_irq_hw[0]->enable) != ppc_cached_irq_mask[0]);
+       /* make sure mask gets to controller before we return to caller */
+       mb();
+        (void)in_le32(&pmac_irq_hw[0]->enable);
 }
 
 void
index c2c4cbbf496f4bc0e333e5c1ae9877eeb28cfd83..35aa7a76d408e1ded915bdbf142e4039483765e5 100644 (file)
@@ -100,6 +100,8 @@ int has_l2cache = 0;
 
 extern char saved_command_line[];
 
+extern int pmac_newworld;
+
 #define DEFAULT_ROOT_DEVICE 0x0801     /* sda1 - slightly silly choice */
 
 extern void zs_kgdb_hook(int tty_num);
@@ -198,6 +200,11 @@ pmac_get_cpuinfo(char *buffer)
                }
        }
        
+       /* Indicate newworld/oldworld */
+       len += sprintf(buffer+len, "pmac-generation\t: %s\n",
+               pmac_newworld ? "NewWorld" : "OldWorld");               
+       
+
        return len;
 }
 
@@ -499,6 +506,8 @@ pmac_restart(char *cmd)
        struct adb_request req;
 #endif /* CONFIG_ADB_CUDA */
 
+       pmac_nvram_update();
+       
        switch (sys_ctrler) {
 #ifdef CONFIG_ADB_CUDA
        case SYS_CTRLER_CUDA:
@@ -524,6 +533,8 @@ pmac_power_off(void)
        struct adb_request req;
 #endif /* CONFIG_ADB_CUDA */
 
+       pmac_nvram_update();
+       
        switch (sys_ctrler) {
 #ifdef CONFIG_ADB_CUDA
        case SYS_CTRLER_CUDA:
index 42ca7eadcea6132da509d88a2ad580e79ce91de6..5014af189ad5ca0ed04d182d0308ac54e90ffe75 100644 (file)
@@ -123,6 +123,7 @@ static char remcomOutBuffer[BUFMAX];
 
 static int initialized = 0;
 static int kgdb_active = 0;
+static int kgdb_started = 0;
 static u_int fault_jmp_buf[100];
 static int kdebug;
 
@@ -342,7 +343,7 @@ static void kgdb_flush_cache_all(void)
        flush_instruction_cache();
 }
 
-static inline int get_msr()
+static inline int get_msr(void)
 {
        int msr;
        asm volatile("mfmsr %0" : "=r" (msr):);
@@ -460,6 +461,9 @@ static int computeSignal(unsigned int tt)
        return SIGHUP;         /* default for things we don't know about */
 }
 
+#define PC_REGNUM 64
+#define SP_REGNUM 1
+
 /*
  * This function does all command processing for interfacing to gdb.
  */
@@ -481,6 +485,7 @@ handle_exception (struct pt_regs *regs)
                return;
        }
        kgdb_active = 1;
+       kgdb_started = 1;
 
 #ifdef KGDB_DEBUG
        printk("kgdb: entering handle_exception; trap [0x%x]\n",
@@ -501,9 +506,25 @@ handle_exception (struct pt_regs *regs)
        sigval = computeSignal(regs->trap);
        ptr = remcomOutBuffer;
 
+#if 0
        *ptr++ = 'S';
        *ptr++ = hexchars[sigval >> 4];
        *ptr++ = hexchars[sigval & 0xf];
+#else
+       *ptr++ = 'T';
+       *ptr++ = hexchars[sigval >> 4];
+       *ptr++ = hexchars[sigval & 0xf];
+       *ptr++ = hexchars[PC_REGNUM >> 4];
+       *ptr++ = hexchars[PC_REGNUM & 0xf];
+       *ptr++ = ':';
+       ptr = mem2hex((char *)&regs->nip, ptr, 4);
+       *ptr++ = ';';
+       *ptr++ = hexchars[SP_REGNUM >> 4];
+       *ptr++ = hexchars[SP_REGNUM & 0xf];
+       *ptr++ = ':';
+       ptr = mem2hex(((char *)&regs) + SP_REGNUM*4, ptr, 4);
+       *ptr++ = ';';
+#endif
 
        *ptr++ = 0;
 
@@ -639,6 +660,7 @@ handle_exception (struct pt_regs *regs)
                                } else {
                                        strcpy(remcomOutBuffer, "E03");
                                }
+                               flush_icache_range(addr, addr+length);
                        } else {
                                strcpy(remcomOutBuffer, "E02");
                        }
@@ -668,7 +690,9 @@ handle_exception (struct pt_regs *regs)
                case 's':
                        kgdb_flush_cache_all();
                        regs->msr |= MSR_SE;
+#if 0
                        set_msr(msr | MSR_SE);
+#endif
                        unlock_kernel();
                        kgdb_active = 0;
                        return;
@@ -700,6 +724,37 @@ breakpoint(void)
        }
 
        asm("   .globl breakinst
-            breakinst: trap
+            breakinst: .long 0x7d821008
             ");
 }
+
+/* Output string in GDB O-packet format if GDB has connected. If nothing
+   output, returns 0 (caller must then handle output). */
+int
+kgdb_output_string (const char* s, unsigned int count)
+{
+       char buffer[512];
+
+        if (!kgdb_started)
+            return 0;
+
+       count = (count <= (sizeof(buffer) / 2 - 2)) 
+               ? count : (sizeof(buffer) / 2 - 2);
+
+       buffer[0] = 'O';
+       mem2hex (s, &buffer[1], count);
+       putpacket(buffer);
+
+        return 1;
+ }
+
+#ifndef CONFIG_8xx
+
+/* I don't know why other platforms don't need this.  The function for
+ * the 8xx is found in arch/ppc/8xx_io/uart.c.  -- Dan
+ */
+void
+kgdb_map_scc(void)
+{
+}
+#endif
diff --git a/arch/ppc/kernel/ppc8260_pic.c b/arch/ppc/kernel/ppc8260_pic.c
new file mode 100644 (file)
index 0000000..21cfde0
--- /dev/null
@@ -0,0 +1,111 @@
+
+#include <linux/stddef.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/signal.h>
+#include <asm/irq.h>
+#include <asm/immap_8260.h>
+#include <asm/mpc8260.h>
+#include "ppc8260_pic.h"
+
+/* The 8260 internal interrupt controller.  It is usually
+ * the only interrupt controller.
+ * There are two 32-bit registers (high/low) for up to 64
+ * possible interrupts.
+ *
+ * Now, the fun starts.....Interrupt Numbers DO NOT MAP
+ * in a simple arithmetic fashion to mask or pending registers.
+ * That is, interrupt 4 does not map to bit position 4.
+ * We create two tables, indexed by vector number, to indicate
+ * which register to use and which bit in the register to use.
+ */
+static u_char  irq_to_siureg[] = {
+       1, 1, 1, 1, 1, 1, 1, 1,
+       1, 1, 1, 1, 1, 1, 1, 1,
+       0, 0, 0, 0, 0, 0, 0, 0,
+       0, 0, 0, 0, 0, 0, 0, 0,
+       1, 1, 1, 1, 1, 1, 1, 1,
+       1, 1, 1, 1, 1, 1, 1, 1,
+       0, 0, 0, 0, 0, 0, 0, 0,
+       0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static u_char  irq_to_siubit[] = {
+       31, 16, 17, 18, 19, 20, 21, 22,
+       23, 24, 25, 26, 27, 28, 29, 30,
+       29, 30, 16, 17, 18, 19, 20, 21,
+       22, 23, 24, 25, 26, 27, 28, 31,
+        0,  1,  2,  3,  4,  5,  6,  7,
+        8,  9, 10, 11, 12, 13, 14, 15,
+       15, 14, 13, 12, 11, 10,  9,  8,
+        7,  6,  5,  4,  3,  2,  1,  0
+};
+
+static void m8260_mask_irq(unsigned int irq_nr)
+{
+       int     bit, word;
+       volatile uint   *simr;
+
+       bit = irq_to_siubit[irq_nr];
+       word = irq_to_siureg[irq_nr];
+
+       simr = &(immr->im_intctl.ic_simrh);
+       ppc_cached_irq_mask[word] &= ~(1 << (31 - bit));
+       simr[word] = ppc_cached_irq_mask[word];
+}
+
+static void m8260_unmask_irq(unsigned int irq_nr)
+{
+       int     bit, word;
+       volatile uint   *simr;
+
+       bit = irq_to_siubit[irq_nr];
+       word = irq_to_siureg[irq_nr];
+
+       simr = &(immr->im_intctl.ic_simrh);
+       ppc_cached_irq_mask[word] |= (1 << (31 - bit));
+       simr[word] = ppc_cached_irq_mask[word];
+}
+
+static void m8260_mask_and_ack(unsigned int irq_nr)
+{
+       int     bit, word;
+       volatile uint   *simr, *sipnr;
+
+       bit = irq_to_siubit[irq_nr];
+       word = irq_to_siureg[irq_nr];
+
+       simr = &(immr->im_intctl.ic_simrh);
+       sipnr = &(immr->im_intctl.ic_sipnrh);
+       ppc_cached_irq_mask[word] &= ~(1 << (31 - bit));
+       simr[word] = ppc_cached_irq_mask[word];
+       sipnr[word] = 1 << bit;
+}
+
+struct hw_interrupt_type ppc8260_pic = {
+       " 8260 SIU  ",
+       NULL,
+       NULL,
+       m8260_unmask_irq,
+       m8260_mask_irq,
+       m8260_mask_and_ack,
+       0
+};
+
+
+int
+m8260_get_irq(struct pt_regs *regs)
+{
+       int irq;
+        unsigned long bits;
+
+        /* For MPC8260, read the SIVEC register and shift the bits down
+         * to get the irq number.         */
+        bits = immr->im_intctl.ic_sivec;
+        irq = bits >> 26;
+#if 0
+        irq += ppc8260_pic.irq_offset;
+#endif
+       return irq;
+}
+
diff --git a/arch/ppc/kernel/ppc8260_pic.h b/arch/ppc/kernel/ppc8260_pic.h
new file mode 100644 (file)
index 0000000..b073dbe
--- /dev/null
@@ -0,0 +1,15 @@
+
+#ifndef _PPC_KERNEL_PPC8260_H
+#define _PPC_KERNEL_PPC8260_H
+
+#include "local_irq.h"
+
+extern struct hw_interrupt_type ppc8260_pic;
+
+void m8260_pic_init(void);
+void m8260_do_IRQ(struct pt_regs *regs,
+                 int            cpu,
+                 int            isfake);
+int m8260_get_irq(struct pt_regs *regs);
+
+#endif /* _PPC_KERNEL_PPC8260_H */
index afcda088b81ca56a22420c87f911e8df73d5c990..e2db1e34d6097fb9bda3a27754884e687ebab1b7 100644 (file)
@@ -8,7 +8,7 @@
 #include <asm/mpc8xx.h>
 #include "ppc8xx_pic.h"
 
-/* The 8xx or 82xx internal interrupt controller.  It is usually
+/* The 8xx internal interrupt controller.  It is usually
  * the only interrupt controller.  Some boards, like the MBX and
  * Sandpoint have the 8259 as a secondary controller.  Depending
  * upon the processor type, the internal controller can have as
@@ -25,13 +25,8 @@ static void m8xx_mask_irq(unsigned int irq_nr)
        word = irq_nr >> 5;
 
        ppc_cached_irq_mask[word] &= ~(1 << (31-bit));
-#ifdef CONFIG_82xx
-       ((immap_t *)IMAP_ADDR)->im_siu_conf.sc_simask[word] =
-                                               ppc_cached_irq_mask[word];
-#else
        ((immap_t *)IMAP_ADDR)->im_siu_conf.sc_simask =
                                                ppc_cached_irq_mask[word];
-#endif
 }
 
 static void m8xx_unmask_irq(unsigned int irq_nr)
@@ -42,13 +37,8 @@ static void m8xx_unmask_irq(unsigned int irq_nr)
        word = irq_nr >> 5;
 
        ppc_cached_irq_mask[word] |= (1 << (31-bit));
-#ifdef CONFIG_82xx
-       ((immap_t *)IMAP_ADDR)->im_siu_conf.sc_simask[word] =
-                                               ppc_cached_irq_mask[word];
-#else
        ((immap_t *)IMAP_ADDR)->im_siu_conf.sc_simask =
                                                ppc_cached_irq_mask[word];
-#endif
 }
 
 static void m8xx_mask_and_ack(unsigned int irq_nr)
@@ -59,15 +49,9 @@ static void m8xx_mask_and_ack(unsigned int irq_nr)
        word = irq_nr >> 5;
 
        ppc_cached_irq_mask[word] &= ~(1 << (31-bit));
-#ifdef CONFIG_82xx
-       ((immap_t *)IMAP_ADDR)->im_siu_conf.sc_simask[word] =
-                                               ppc_cached_irq_mask[word];
-       ((immap_t *)IMAP_ADDR)->im_siu_conf.sc_sipend[word] = 1 << (31-bit);
-#else
        ((immap_t *)IMAP_ADDR)->im_siu_conf.sc_simask =
                                                ppc_cached_irq_mask[word];
        ((immap_t *)IMAP_ADDR)->im_siu_conf.sc_sipend = 1 << (31-bit);
-#endif
 }
 
 struct hw_interrupt_type ppc8xx_pic = {
@@ -129,7 +113,7 @@ m8xx_get_irq(struct pt_regs *regs)
 
 /* The MBX is the only 8xx board that uses the 8259.
 */
-#ifdef CONFIG_MBX
+#if defined(CONFIG_MBX) && defined(CONFIG_PCI)
 void mbx_i8259_action(int cpl, void *dev_id, struct pt_regs *regs)
 {
        int bits, irq;
@@ -165,7 +149,7 @@ int request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *)
        unsigned long irqflags, const char * devname, void *dev_id)
 {
 
-#ifdef CONFIG_MBX
+#if defined(CONFIG_MBX) && defined(CONFIG_PCI)
        irq += i8259_pic.irq_offset;
        return (request_8xxirq(irq, handler, irqflags, devname, dev_id));
 #else
index 441310e687c7700e8387f3ff0d0aae14292eb0cf..655eb4390f95a1d7fb0e6009076601c2650e391b 100644 (file)
@@ -502,7 +502,7 @@ int proc_dol2crvec(ctl_table *table, int write, struct file *filp,
        #define TMPBUFLEN 256
        char buf[TMPBUFLEN], *p;
        static const char *sizestrings[4] = {
-               "unknown size", "256KB", "512KB", "1MB"
+               "2MB", "256KB", "512KB", "1MB"
        };
        static const char *clockstrings[8] = {
                "clock disabled", "+1 clock", "+1.5 clock", "reserved(3)",
index 7d4c038ecb8bfe70f8fedc402cbfa263792bdebc..9b7d2be314834a97591731699167b252efd8a0d4 100644 (file)
@@ -54,9 +54,10 @@ extern int sys_sigreturn(struct pt_regs *regs);
 extern void do_lost_interrupts(unsigned long);
 extern int do_signal(sigset_t *, struct pt_regs *);
 
-asmlinkage long long __ashrdi3(long long, int);
-asmlinkage long long __lshrdi3(long long, int);
-asmlinkage int abs(int);
+long long __ashrdi3(long long, int);
+long long __ashldi3(long long, int);
+long long __lshrdi3(long long, int);
+int abs(int);
 
 EXPORT_SYMBOL(clear_page);
 EXPORT_SYMBOL(do_signal);
@@ -95,25 +96,12 @@ EXPORT_SYMBOL(ucSystemType);
 #endif
 #endif
 
-EXPORT_SYMBOL(atomic_add);
-EXPORT_SYMBOL(atomic_sub);
-EXPORT_SYMBOL(atomic_inc);
-EXPORT_SYMBOL(atomic_inc_return);
-EXPORT_SYMBOL(atomic_dec);
-EXPORT_SYMBOL(atomic_dec_return);
-EXPORT_SYMBOL(atomic_dec_and_test);
-
 EXPORT_SYMBOL(set_bit);
 EXPORT_SYMBOL(clear_bit);
 EXPORT_SYMBOL(change_bit);
 EXPORT_SYMBOL(test_and_set_bit);
 EXPORT_SYMBOL(test_and_clear_bit);
 EXPORT_SYMBOL(test_and_change_bit);
-#if 0
-EXPORT_SYMBOL(ffz);
-EXPORT_SYMBOL(find_first_zero_bit);
-EXPORT_SYMBOL(find_next_zero_bit);
-#endif
 
 EXPORT_SYMBOL(strcpy);
 EXPORT_SYMBOL(strncpy);
@@ -254,6 +242,7 @@ EXPORT_SYMBOL(nvram_write_byte);
 #endif /* CONFIG_NVRAM */
 
 EXPORT_SYMBOL_NOVERS(__ashrdi3);
+EXPORT_SYMBOL_NOVERS(__ashldi3);
 EXPORT_SYMBOL_NOVERS(__lshrdi3);
 EXPORT_SYMBOL_NOVERS(memcpy);
 EXPORT_SYMBOL_NOVERS(memset);
@@ -281,3 +270,17 @@ EXPORT_SYMBOL(console_drivers);
 EXPORT_SYMBOL(xmon);
 #endif
 EXPORT_SYMBOL(down_read_failed);
+
+extern void (*debugger)(struct pt_regs *regs);
+extern int (*debugger_bpt)(struct pt_regs *regs);
+extern int (*debugger_sstep)(struct pt_regs *regs);
+extern int (*debugger_iabr_match)(struct pt_regs *regs);
+extern int (*debugger_dabr_match)(struct pt_regs *regs);
+extern void (*debugger_fault_handler)(struct pt_regs *regs);
+
+EXPORT_SYMBOL(debugger);
+EXPORT_SYMBOL(debugger_bpt);
+EXPORT_SYMBOL(debugger_sstep);
+EXPORT_SYMBOL(debugger_iabr_match);
+EXPORT_SYMBOL(debugger_dabr_match);
+EXPORT_SYMBOL(debugger_fault_handler);
index ce8e039c0e268e1497fbae293729e3a7446b4ab7..e1f1b49831108793237d66c8e0d871b3961c1c21 100644 (file)
@@ -489,7 +489,7 @@ asmlinkage int sys_execve(unsigned long a0, unsigned long a1, unsigned long a2,
 {
        int error;
        char * filename;
-       lock_kernel();
+
        filename = getname((char *) a0);
        error = PTR_ERR(filename);
        if (IS_ERR(filename))
@@ -503,8 +503,6 @@ asmlinkage int sys_execve(unsigned long a0, unsigned long a1, unsigned long a2,
        error = do_execve(filename, (char **) a1, (char **) a2, regs);
        putname(filename);
 out:
-       unlock_kernel();
-
        return error;
 }
 
index a987b8fd6980b017136eb94bf9c3406424182da0..31fc850683fec85b8f4d753095a0185c3127b2cf 100644 (file)
@@ -106,7 +106,10 @@ unsigned int rtas_entry = 0;  /* physical pointer */
 unsigned int rtas_size = 0;
 unsigned int old_rtas = 0;
 
+/* Set for a newworld machine */
 int use_of_interrupt_tree = 0;
+int pmac_newworld = 0;
+
 static struct device_node *allnodes = 0;
 
 #ifdef CONFIG_BOOTX_TEXT
@@ -802,7 +805,6 @@ __init
 static void
 setup_disp_fake_bi(ihandle dp)
 {
-       unsigned int len;
        int width = 640, height = 480, depth = 8, pitch;
        unsigned address;
        boot_infos_t* bi;
@@ -982,15 +984,17 @@ void
 finish_device_tree(void)
 {
        unsigned long mem = (unsigned long) klimit;
-       char* model;
-       
-       /* Here, we decide if we'll use the interrupt-tree (new Core99 code) or not.
-        * This code was only tested with Core99 machines so far, but should be easily
-        * adapted to older newworld machines (iMac, B&W G3, Lombard).
-        */
-       model = get_property(allnodes, "model", 0);
-       if ((boot_infos == 0) && model && (strcmp(model, "PowerBook2,1") == 0
-           || strcmp(model, "PowerMac2,1") == 0 || strcmp(model, "PowerMac3,1") == 0))
+
+       /* All newworld machines now use the interrupt tree */
+       struct device_node *np = allnodes;
+       while(np) {
+               if (get_property(np, "interrupt-parent", 0)) {
+                       pmac_newworld = 1;
+                       break;
+               }
+               np = np->allnext;
+       }
+       if (boot_infos == 0 && pmac_newworld)
                use_of_interrupt_tree = 1;
 
        mem = finish_node(allnodes, mem, NULL);
@@ -1827,7 +1831,8 @@ abort()
 #ifdef CONFIG_XMON
        xmon(NULL);
 #endif
-       prom_exit();
+       for (;;)
+               prom_exit();
 }
 
 #ifdef CONFIG_BOOTX_TEXT
index 860f4f0cc6426aa86217245d3129010f2a202838..c31dd9399871bd558deb0ae8737baf3caaf9f299 100644 (file)
@@ -84,7 +84,7 @@
                "       .align 2\n"                     \
                "       .long 1b,3b\n"                  \
                ".text"                                 \
-               : "=r"(x) : "r"(addr))
+               : "=r"(x) : "r"(addr) : " %0")
 
 #define QS_CONFIG_ADDR ((volatile uint *)(PCI_CSR_ADDR + 0x500))
 #define QS_CONFIG_DATA ((volatile uint *)(PCI_CSR_ADDR + 0x504))
index 2b771ef143b4b36743d18cf725af999d60f62712..49a8da139370d7bdb612c2b0c89e3a2b2b55302e 100644 (file)
 #include <asm/mpc8xx.h>
 #include <asm/8xx_immap.h>
 #endif
+#ifdef CONFIG_8260
+#include <asm/mpc8260.h>
+#include <asm/immap_8260.h>
+#endif
 #include <asm/bootx.h>
 #include <asm/machdep.h>
 #include <asm/feature.h>
@@ -109,8 +113,10 @@ struct machdep_calls ppc_md;
  * on pmac as well so we don't need the ifdef's.
  * Until we get multiple-console support in here
  * that is.  -- Cort
+ * Maybe tie it to serial consoles, since this is really what
+ * these processors use on existing boards.  -- Dan
  */ 
-#if !defined(CONFIG_4xx) && !defined(CONFIG_8xx)
+#if !defined(CONFIG_4xx) && !defined(CONFIG_8xx) && !defined(CONFIG_8260)
 struct screen_info screen_info = {
        0, 25,                  /* orig-x, orig-y */
        0,                      /* unused */
@@ -283,10 +289,10 @@ int get_cpuinfo(char *buffer)
                        }
                        break;
                case 0x0050:
-                       len += sprintf(len+buffer, "821\n");
+                       len += sprintf(len+buffer, "8xx\n");
                        break;
                case 0x0081:
-                       len += sprintf(len+buffer, "8240\n");
+                       len += sprintf(len+buffer, "82xx\n");
                        break;
                case 0x4011:
                        len += sprintf(len+buffer, "405GP\n");
@@ -300,7 +306,7 @@ int get_cpuinfo(char *buffer)
                 * Assume here that all clock rates are the same in a
                 * smp system.  -- Cort
                 */
-#if !defined(CONFIG_4xx) && !defined(CONFIG_8xx)
+#if !defined(CONFIG_4xx) && !defined(CONFIG_8xx) && !defined(CONFIG_8260)
                if ( have_of )
                {
                        struct device_node *cpu_node;
@@ -418,10 +424,10 @@ identify_machine(unsigned long r3, unsigned long r4, unsigned long r5,
                 unsigned long r6, unsigned long r7)
 {
        parse_bootinfo();
-       
+
        if ( ppc_md.progress ) ppc_md.progress("id mach(): start", 0x100);
        
-#if !defined(CONFIG_4xx) && !defined(CONFIG_8xx)
+#if !defined(CONFIG_4xx) && !defined(CONFIG_8xx) && !defined(CONFIG_8260)
 #ifndef CONFIG_MACH_SPECIFIC
        /* if we didn't get any bootinfo telling us what we are... */
        if ( _machine == 0 )
@@ -540,6 +546,8 @@ identify_machine(unsigned long r3, unsigned long r4, unsigned long r5,
        oak_init(r3, r4, r5, r6, r7);
 #elif defined(CONFIG_8xx)
         m8xx_init(r3, r4, r5, r6, r7);
+#elif defined(CONFIG_8260)
+        m8260_init(r3, r4, r5, r6, r7);
 #else
 #error "No board type has been defined for identify_machine()!"
 #endif /* CONFIG_4xx */
@@ -659,13 +667,19 @@ void __init setup_arch(char **cmdline_p)
        map_bootx_text();
 #endif
 
+#ifdef CONFIG_ALL_PPC
+       feature_init();
+#endif
+
 #ifdef CONFIG_XMON
        xmon_map_scc();
        if (strstr(cmd_line, "xmon"))
                xmon(0);
 #endif /* CONFIG_XMON */
        if ( ppc_md.progress ) ppc_md.progress("setup_arch: enter", 0x3eab);
+
 #if defined(CONFIG_KGDB)
+       kgdb_map_scc();
        set_debug_traps();
        breakpoint();
 #endif
@@ -688,6 +702,7 @@ void __init setup_arch(char **cmdline_p)
 
        ppc_md.setup_arch();
        if ( ppc_md.progress ) ppc_md.progress("arch: exit", 0x3eab);
+
        paging_init();
 }
 
@@ -696,7 +711,6 @@ void ppc_generic_ide_fix_driveid(struct hd_driveid *id)
         int i;
        unsigned short *stringcast;
 
-
        id->config         = __le16_to_cpu(id->config);
        id->cyls           = __le16_to_cpu(id->cyls);
        id->reserved2      = __le16_to_cpu(id->reserved2);
@@ -708,16 +722,16 @@ void ppc_generic_ide_fix_driveid(struct hd_driveid *id)
        id->vendor1        = __le16_to_cpu(id->vendor1);
        id->vendor2        = __le16_to_cpu(id->vendor2);
        stringcast = (unsigned short *)&id->serial_no[0];
-       for (i=0; i<(20/2); i++)
+       for (i = 0; i < (20/2); i++)
                stringcast[i] = __le16_to_cpu(stringcast[i]);
        id->buf_type       = __le16_to_cpu(id->buf_type);
        id->buf_size       = __le16_to_cpu(id->buf_size);
        id->ecc_bytes      = __le16_to_cpu(id->ecc_bytes);
        stringcast = (unsigned short *)&id->fw_rev[0];
-       for (i=0; i<(8/2); i++)
+       for (i = 0; i < (8/2); i++)
                stringcast[i] = __le16_to_cpu(stringcast[i]);
        stringcast = (unsigned short *)&id->model[0];
-       for (i=0; i<(40/2); i++)
+       for (i = 0; i < (40/2); i++)
                stringcast[i] = __le16_to_cpu(stringcast[i]);
        id->dword_io       = __le16_to_cpu(id->dword_io);
        id->reserved50     = __le16_to_cpu(id->reserved50);
@@ -735,12 +749,12 @@ void ppc_generic_ide_fix_driveid(struct hd_driveid *id)
        id->eide_dma_time  = __le16_to_cpu(id->eide_dma_time);
        id->eide_pio       = __le16_to_cpu(id->eide_pio);
        id->eide_pio_iordy = __le16_to_cpu(id->eide_pio_iordy);
-       for (i=0; i<2; i++)
+       for (i = 0; i < 2; i++)
                id->words69_70[i] = __le16_to_cpu(id->words69_70[i]);
-        for (i=0; i<4; i++)
+        for (i = 0; i < 4; i++)
                 id->words71_74[i] = __le16_to_cpu(id->words71_74[i]);
        id->queue_depth    = __le16_to_cpu(id->queue_depth);
-       for (i=0; i<4; i++)
+       for (i = 0; i < 4; i++)
                id->words76_79[i] = __le16_to_cpu(id->words76_79[i]);
        id->major_rev_num  = __le16_to_cpu(id->major_rev_num);
        id->minor_rev_num  = __le16_to_cpu(id->minor_rev_num);
@@ -756,14 +770,14 @@ void ppc_generic_ide_fix_driveid(struct hd_driveid *id)
        id->CurAPMvalues   = __le16_to_cpu(id->CurAPMvalues);
        id->word92         = __le16_to_cpu(id->word92);
        id->hw_config      = __le16_to_cpu(id->hw_config);
-       for (i=0; i<32; i++)
+       for (i = 0; i < 32; i++)
                id->words94_125[i]  = __le16_to_cpu(id->words94_125[i]);
        id->last_lun       = __le16_to_cpu(id->last_lun);
        id->word127        = __le16_to_cpu(id->word127);
        id->dlf            = __le16_to_cpu(id->dlf);
        id->csfo           = __le16_to_cpu(id->csfo);
-       for (i=0; i<31; i++)
+       for (i = 0; i < 30; i++)
                id->words130_159[i] = __le16_to_cpu(id->words130_159[i]);
-       for (i=0; i<97; i++)
+       for (i = 0; i < 96; i++)
                id->words160_255[i] = __le16_to_cpu(id->words160_255[i]);
 }
diff --git a/arch/ppc/kernel/totalmp.c b/arch/ppc/kernel/totalmp.c
deleted file mode 100644 (file)
index ecbc04b..0000000
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * $Id: totalmp.c,v 1.6 1999/08/31 06:54:10 davem Exp $
- *
- * Support for Total Impact's TotalMP PowerPC accelerator board.
- *
- * Written by Cort Dougan (cort@cs.nmt.edu)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-
-#include <linux/pci.h>
-#include <linux/init.h>
-#include <linux/openpic.h>
-#include <linux/errno.h>
-#include <linux/kernel.h>
-#include <linux/delay.h>
-#include <linux/mm.h>
-
-#include <asm/io.h>
-
-extern void totalmp_init(void);
-
-extern inline void openpic_writefield(volatile u_int *addr, u_int mask,
-                                     u_int field);
-void __init totalmp_init(void)
-{
-       struct pci_dev *dev;
-       u32 val;
-       unsigned long ctl_area, ctl_area_phys;
-
-       /* it's a pci card */
-       if ( !pci_present() ) return;
-
-       /* search for a MPIC.  For now, we assume
-        * only one TotalMP card installed. -- Cort
-        */
-       for(dev=pci_devices; dev; dev=dev->next)
-       {
-               if ( (dev->vendor == PCI_VENDOR_ID_IBM)
-                    && ((dev->device == PCI_DEVICE_ID_IBM_MPIC)
-                        || (dev->device==PCI_DEVICE_ID_IBM_MPIC_2)) )
-               {
-                       break;
-               }
-       }
-
-       if ( !dev ) return;
-
-       OpenPIC = (struct OpenPIC *)bus_to_virt(dev->base_address[0]);
-#if 0  
-       if ( (ulong)OpenPIC > 0x10000000 )
-       {
-               printk("TotalMP: relocating base %lx -> %lx\n",
-                      (ulong)OpenPIC, ((ulong)OpenPIC & 0x00FFFFFF) | 0x01000000);
-               OpenPIC = (struct OpenPIC *)(((ulong)OpenPIC & 0x00FFFFFF) | 0x01000000);
-               pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, (ulong)OpenPIC);
-       }*/
-#endif 
-       OpenPIC = (struct OpenPIC *)((ulong)OpenPIC + _IO_BASE);
-
-       openpic_init(0);
-
-       /* put openpic in 8259-cascade mode */
-       openpic_writefield(&OpenPIC->Global.Global_Configuration0, 0, 0x20000000);
-       /* set ipi to highest priority */
-       openpic_writefield(&OpenPIC->Global._IPI_Vector_Priority[0].Reg, 0, 0x000f0000);
-
-       /* allocate and remap the control area to be no-cache */
-       ctl_area = __get_free_pages(GFP_ATOMIC, 3);
-       ctl_area_phys = (unsigned long) virt_to_phys((void *)ctl_area);
-       ctl_area = (unsigned long)ioremap(ctl_area, 0x8000);
-       
-       /* soft reset cpu 0 */
-       pci_read_config_dword(dev, PCI_BASE_ADDRESS_0, &val);
-       openpic_writefield(&OpenPIC->Global._Processor_Initialization.Reg, 0, 0x1);
-
-       /* wait for base address reg to change, signaling that cpu 0 is done */
-#define wait_for(where) {                                      \
-       udelay(100);                                            \
-       pci_read_config_dword(dev, PCI_BASE_ADDRESS_0, &val);   \
-       if ( val != 0x77700000 )                                \
-       {                                                       \
-               printk("TotalMP: CPU0 did not respond: val %x %d\n", val, where); \
-               /*free_pages((ulong)phys_to_virt(ctl_area_phys),1);*/ \
-               return;                                         \
-       } }
-       
-       /* tell cpu0 where the control area is */
-       pci_write_config_dword(dev, PCI_BASE_ADDRESS_0,(~val) >> 16);
-       wait_for(0);
-       pci_write_config_dword(dev, PCI_BASE_ADDRESS_0,
-                              ((ulong)ctl_area & 0xff000000)>>20);
-       wait_for(1);
-       pci_write_config_dword(dev, PCI_BASE_ADDRESS_0,
-                              ((ulong)ctl_area & 0x00ff0000)>>12);
-       wait_for(2);
-       pci_write_config_dword(dev, PCI_BASE_ADDRESS_0,
-                              ((ulong)ctl_area & 0x0000ff00)>>4);
-       wait_for(3);
-       pci_write_config_dword(dev, PCI_BASE_ADDRESS_0,
-                              ((ulong)ctl_area & 0x000000ff)<<4);
-       wait_for(4);
-#undef wait_for
-       /* wait for cpu0 to "sign-on" */
-}
-
index ac7f47602d77081ff3071ed4e9e93f3dc03ed48f..28a5a5035e7d88599a4d00dda414482154d4b23d 100644 (file)
@@ -119,10 +119,10 @@ MachineCheckException(struct pt_regs *regs)
                        printk("Unknown values in msr\n");
                }
                show_regs(regs);
-               print_backtrace((unsigned long *)regs->gpr[1]);
 #if defined(CONFIG_XMON) || defined(CONFIG_KGDB)
                debugger(regs);
 #endif
+               print_backtrace((unsigned long *)regs->gpr[1]);
                panic("machine check");
        }
        _exception(SIGSEGV, regs);      
index 6f9fd0135be259c696ad92575847ff42540729d9..9dd5d64f36cd5aca38f2898f434ff9553996317f 100644 (file)
@@ -25,11 +25,20 @@ ZSZ = 0
 IOFF = 0
 ISZ = 0
 
-TFTPIMAGE=/tftpboot/zImage.mbx
-ZLINKFLAGS = -T ../vmlinux.lds -Ttext 0x00180000
+TFTPIMAGE=/tftpboot/zImage.embedded
 
+ifdef CONFIG_8xx
+ZLINKFLAGS = -T ../vmlinux.lds -Ttext 0x00180000
 OBJECTS := head.o misc.o ../coffboot/zlib.o m8xx_tty.o
 CFLAGS = $(CPPFLAGS) -O2 -DSTDC_HEADERS -fno-builtin -DCONFIG_8xx
+endif
+
+ifdef CONFIG_8260
+ZLINKFLAGS = -T ../vmlinux.lds -Ttext 0x00400000
+OBJECTS := head_8260.o misc.o ../coffboot/zlib.o m8260_tty.o embed_config.o
+CFLAGS = $(CPPFLAGS) -O2 -DSTDC_HEADERS -fno-builtin -DCONFIG_8260
+endif
+
 OBJCOPY_ARGS = -O elf32-powerpc
 
 ifeq ($(CONFIG_MBX),y)
index 009d0b4bcb0349792247ade1e16214020dc86dcb..4477d9639fcc34a42ba77712f24e0926491be859 100644 (file)
@@ -3,7 +3,13 @@
  * not have boot monitor support for board information.
  */
 #include <sys/types.h>
-#include "asm/mpc8xx.h"
+#include <linux/autoconf.h>
+#ifdef CONFIG_8xx
+#include <asm/mpc8xx.h>
+#endif
+#ifdef CONFIG_8260
+#include <asm/mpc8260.h>
+#endif
 
 
 /* IIC functions.
 extern void    iic_read(uint devaddr, u_char *buf, uint offset, uint count);
 extern u_char  aschex_to_byte(u_char *cp);
 
+/* Supply a default Ethernet address for those eval boards that don't
+ * ship with one.  This is an address from the MBX board I have, so
+ * it is unlikely you will find it on your network.
+ */
+static ushort  def_enet_addr[] = { 0x0800, 0x3e26, 0x1559 };
+
+#if defined(CONFIG_RPXLITE) || defined(CONFIG_RPXCLASSIC)
+
 static void    rpx_eth(bd_t *bd, u_char *cp);
 static void    rpx_brate(bd_t *bd, u_char *cp);
 static void    rpx_memsize(bd_t *bd, u_char *cp);
@@ -89,8 +103,10 @@ rpx_cfg(bd_t *bd)
        bd->bi_memstart = 0;
 
 #else
+       /* For boards without initialized EEPROM.
+       */
        bd->bi_memstart = 0;
-       bd->bi_memsize = (4 * 1024 * 1024);
+       bd->bi_memsize = (8 * 1024 * 1024);
        bd->bi_intfreq = 48;
        bd->bi_busfreq = 48;
        bd->bi_baudrate = 9600;
@@ -174,7 +190,9 @@ rpx_cpuspeed(bd_t *bd, u_char *cp)
        if (num > 50)
                bd->bi_busfreq /= 2;
 }
+#endif /* RPXLITE || RPXCLASSIC */
 
+#ifdef CONFIG_BSEIP
 /* Build a board information structure for the BSE ip-Engine.
  * There is more to come since we will add some environment
  * variables and a function to read them.
@@ -204,4 +222,31 @@ bseip_cfg(bd_t *bd)
        bd->bi_intfreq = 48;
        bd->bi_busfreq = 48;
 }
+#endif /* BSEIP */
 
+#ifdef CONFIG_EST8260
+void
+embed_config(bd_t *bd)
+{
+       u_char  *cp;
+       int     i;
+
+#if 1
+       /* This is actually provided by my boot rom.  I have it
+        * here for those people that may load the kernel with
+        * a JTAG/COP tool and not the rom monitor.
+        */
+       bd->bi_baudrate = 115200;
+       bd->bi_intfreq = 200;
+       bd->bi_busfreq = 66;
+       bd->bi_cpmfreq = 66;
+       bd->bi_brgfreq = 33;
+       bd->bi_memsize = 16 * 1024 * 1024;
+#endif
+
+       cp = (u_char *)def_enet_addr;
+       for (i=0; i<6; i++) {
+               bd->bi_enetaddr[i] = *cp++;
+       }
+}
+#endif /* EST8260 */
diff --git a/arch/ppc/mbxboot/head_8260.S b/arch/ppc/mbxboot/head_8260.S
new file mode 100644 (file)
index 0000000..79377a2
--- /dev/null
@@ -0,0 +1,246 @@
+#include "../kernel/ppc_defs.h"
+#include "../kernel/ppc_asm.tmpl"
+#include <asm/processor.h>
+#include <asm/cache.h>
+
+       .text
+
+/*
+ * $Id: head.S,v 1.33 1999/09/08 01:06:58 cort Exp $
+ *     
+ * Boot loader philosophy:
+ *      ROM loads us to some arbitrary location
+ *      Move the boot code to the link address (8M)
+ *      Call decompress_kernel()
+ *         Relocate the initrd, zimage and residual data to 8M
+ *         Decompress the kernel to 0
+ *      Jump to the kernel entry
+ *            -- Cort
+ */
+       .globl  start
+start:
+       bl      start_
+start_:
+       mr      r11,r3          /* Save pointer to residual/board data */
+       mr      r25,r5          /* Save OFW pointer */
+       li      r3,MSR_IP       /* Establish default MSR value */
+       mtmsr   r3
+
+/* check if we need to relocate ourselves to the link addr or were we
+   loaded there to begin with -- Cort */
+       lis     r4,start@h
+       ori     r4,r4,start@l
+       mflr    r3
+       subi    r3,r3,4         /* we get the nip, not the ip of the branch */
+       mr      r8,r3
+       cmp     0,r3,r4
+       bne     1010f
+/* compute size of whole image in words.  this should be moved to
+ * start_ldr() -- Cort
+ */
+       lis     r4,start@h
+       ori     r4,r4,start@l
+       lis     r5,end@h
+       ori     r5,r5,end@l
+       addi    r5,r5,3         /* round up */
+       sub     r5,r5,r4
+       srwi    r5,r5,2
+       mr      r7,r5
+       b       start_ldr
+1010:
+/* 
+ * no matter where we're loaded, move ourselves to -Ttext address
+ */
+relocate:
+       mflr    r3              /* Compute code bias */
+       subi    r3,r3,4
+       mr      r8,r3
+       lis     r4,start@h
+       ori     r4,r4,start@l
+       lis     r5,end@h
+       ori     r5,r5,end@l
+       addi    r5,r5,3                 /* Round up - just in case */
+       sub     r5,r5,r4                /* Compute # longwords to move */
+       srwi    r5,r5,2
+       mtctr   r5
+       mr      r7,r5
+       li      r6,0
+       subi    r3,r3,4                 /* Set up for loop */
+       subi    r4,r4,4
+00:    lwzu    r5,4(r3)
+       stwu    r5,4(r4)
+       xor     r6,r6,r5
+       bdnz    00b
+       lis     r3,start_ldr@h
+       ori     r3,r3,start_ldr@l
+       mtlr    r3                      /* Easiest way to do an absolute jump */
+       blr
+start_ldr:
+/* Clear all of BSS */
+       lis     r3,edata@h
+       ori     r3,r3,edata@l
+       lis     r4,end@h
+       ori     r4,r4,end@l
+       subi    r3,r3,4
+       subi    r4,r4,4
+       li      r0,0
+50:    stwu    r0,4(r3)
+       cmp     0,r3,r4
+       bne     50b
+90:    mr      r9,r1                   /* Save old stack pointer (in case it matters) */
+       lis     r1,.stack@h
+       ori     r1,r1,.stack@l
+       addi    r1,r1,4096*2
+       subi    r1,r1,256
+       li      r2,0x000F               /* Mask pointer to 16-byte boundary */
+       andc    r1,r1,r2
+/* Run loader */
+       mr      r3,r8                   /* Load point */
+       mr      r4,r7                   /* Program length */
+       mr      r5,r6                   /* Checksum */
+       mr      r6,r11                  /* Residual data */
+       mr      r7,r25                  /* OFW interfaces */
+       bl      decompress_kernel
+       
+       /* changed to use r3 (as firmware does) for kernel
+          as ptr to residual -- Cort*/
+       lis     r6,cmd_line@h
+       ori     r6,r6,cmd_line@l
+       lwz     r6, 0(r6)
+       subi    r7,r6,1
+00:    lbzu    r2,1(r7)
+       cmpi    0,r2,0
+       bne     00b
+
+       /* r4,r5 have initrd_start, size */
+       lis     r2,initrd_start@h
+       ori     r2,r2,initrd_start@l
+       lwz     r4,0(r2)
+       lis     r2,initrd_end@h
+       ori     r2,r2,initrd_end@l
+       lwz     r5,0(r2)
+       
+       /* tell kernel we're prep */
+       /* 
+        * get start address of kernel code which is stored as a coff
+        * entry.  see boot/head.S -- Cort 
+        */
+       li      r9,0x4
+       mtlr    r9
+       lis     r10,0xdeadc0de@h
+       ori     r10,r10,0xdeadc0de@l
+       li      r9,0
+       stw     r10,0(r9)
+/*
+ * The Radstone firmware maps PCI memory at 0xc0000000 using BAT2
+ * so disable BATs before setting this to avoid a clash
+ */
+       li      r8,0
+       mtspr   DBAT0U,r8
+       mtspr   DBAT1U,r8
+       mtspr   DBAT2U,r8
+       mtspr   DBAT3U,r8
+       mtspr   IBAT0U,r8
+       mtspr   IBAT1U,r8
+       mtspr   IBAT2U,r8
+       mtspr   IBAT3U,r8
+
+       blr
+hang:
+       b       hang    
+
+/*
+ * Delay for a number of microseconds
+ * -- Use the BUS timer (assumes 66MHz)
+ */
+       .globl  udelay
+udelay:                
+       mfspr   r4,PVR
+       srwi    r4,r4,16
+       cmpi    0,r4,1          /* 601 ? */
+       bne     .udelay_not_601
+00:    li      r0,86   /* Instructions / microsecond? */
+       mtctr   r0
+10:    addi    r0,r0,0 /* NOP */
+       bdnz    10b
+       subic.  r3,r3,1
+       bne     00b
+       blr
+
+.udelay_not_601:               
+       mulli   r4,r3,1000      /* nanoseconds */
+       addi    r4,r4,59
+       li      r5,60
+       divw    r4,r4,r5        /* BUS ticks */
+1:     mftbu   r5
+       mftb    r6
+       mftbu   r7
+       cmp     0,r5,r7
+       bne     1b              /* Get [synced] base time */
+       addc    r9,r6,r4        /* Compute end time */
+       addze   r8,r5
+2:     mftbu   r5
+       cmp     0,r5,r8
+       blt     2b
+       bgt     3f
+       mftb    r6
+       cmp     0,r6,r9
+       blt     2b
+3:     blr             
+
+.globl _get_HID0
+_get_HID0:             
+       mfspr   r3,HID0
+       blr
+
+.globl _put_HID0
+_put_HID0:             
+       mtspr   HID0,r3
+       blr
+               
+.globl _get_MSR
+_get_MSR:              
+       mfmsr   r3
+       blr
+       
+.globl _put_MSR
+_put_MSR:              
+       mtmsr   r3
+       blr
+
+/*
+ * Flush instruction cache
+ * *** I'm really paranoid here!
+ */
+_GLOBAL(flush_instruction_cache)
+       mflr    r5
+       bl      flush_data_cache
+       mfspr   r3,HID0 /* Caches are controlled by this register */
+       li      r4,0
+       ori     r4,r4,(HID0_ICE|HID0_ICFI)
+       or      r3,r3,r4        /* Need to enable+invalidate to clear */
+       mtspr   HID0,r3
+       andc    r3,r3,r4
+       ori     r3,r3,HID0_ICE  /* Enable cache */
+       mtspr   HID0,r3
+       mtlr    r5
+       blr
+       
+#define NUM_CACHE_LINES 128*8
+#define CACHE_LINE_SIZE 32 
+#define cache_flush_buffer 0x1000
+
+/*
+ * Flush data cache
+ * *** I'm really paranoid here!
+ */
+_GLOBAL(flush_data_cache)
+       lis     r3,cache_flush_buffer@h
+       ori     r3,r3,cache_flush_buffer@l
+       li      r4,NUM_CACHE_LINES
+       mtctr   r4
+00:    lwz     r4,0(r3)
+       addi    r3,r3,CACHE_LINE_SIZE   /* Next line, please */
+       bdnz    00b     
+10:    blr
+       .comm   .stack,4096*2,4
index 7775350d50024eee2777701a89a448fc19f6b44d..27de804a63b39cef3348517ba38a71577fdbe629 100644 (file)
@@ -43,6 +43,15 @@ iic_init()
        */
        while (cp->cp_cpcr & (CPM_CR_RST | CPM_CR_FLG));
 
+       /* Remove any microcode patches.  We will install our own
+        * later.
+        */
+       cp->cp_cpmcr1 = 0;
+       cp->cp_cpmcr2 = 0;
+       cp->cp_cpmcr3 = 0;
+       cp->cp_cpmcr4 = 0;
+       cp->cp_rccr = 0;
+
        iip = (iic_t *)&cp->cp_dparam[PROFF_IIC];
        i2c = (i2c8xx_t *)&(immap->im_i2c);
 
diff --git a/arch/ppc/mbxboot/m8260_tty.c b/arch/ppc/mbxboot/m8260_tty.c
new file mode 100644 (file)
index 0000000..9135473
--- /dev/null
@@ -0,0 +1,202 @@
+
+
+/* Minimal serial functions needed to send messages out the serial
+ * port on SMC1.
+ */
+#include <linux/types.h>
+#include <linux/autoconf.h>
+#include "asm/mpc8260.h"
+#include "asm/cpm_8260.h"
+
+uint   no_print;
+extern char    *params[];
+extern int     nparams;
+static         u_char  cons_hold[128], *sgptr;
+static         int     cons_hold_cnt;
+
+void
+serial_init(bd_t *bd)
+{
+       volatile smc_t          *sp;
+       volatile smc_uart_t     *up;
+       volatile cbd_t  *tbdf, *rbdf;
+       volatile immap_t        *ip;
+       volatile iop8260_t      *io;
+       volatile cpm8260_t      *cp;
+       uint    dpaddr, memaddr;
+
+       ip = (immap_t *)IMAP_ADDR;
+
+       sp = (smc_t*)&(ip->im_smc[0]);
+       *(ushort *)(&ip->im_dprambase[PROFF_SMC1_BASE]) = PROFF_SMC1;
+       up = (smc_uart_t *)&ip->im_dprambase[PROFF_SMC1];
+
+       cp = &ip->im_cpm;
+       io = &ip->im_ioport;
+
+       /* Disable transmitter/receiver.
+       */
+       sp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN);
+
+       /* Use Port D for SMC1 instead of other functions.
+       */
+       io->iop_ppard |= 0x00c00000;
+       io->iop_pdird |= 0x00400000;
+       io->iop_pdird &= ~0x00800000;
+       io->iop_psord &= ~0x00c00000;
+
+       /* Allocate space for two buffer descriptors in the DP ram.
+        * For now, this address seems OK, but it may have to
+        * change with newer versions of the firmware.
+        */
+       dpaddr = 0x0800;
+
+       /* Grab a few bytes from the top of memory.
+        */
+#if 1
+       memaddr = (bd->bi_memsize - 256) & ~15;
+#else
+       memaddr = 0x0f002c00;
+#endif
+
+       /* Set the physical address of the host memory buffers in
+        * the buffer descriptors.
+        */
+       rbdf = (cbd_t *)&ip->im_dprambase[dpaddr];
+       rbdf->cbd_bufaddr = memaddr;
+       rbdf->cbd_sc = 0;
+       tbdf = rbdf + 1;
+       tbdf->cbd_bufaddr = memaddr+128;
+       tbdf->cbd_sc = 0;
+
+       /* Set up the uart parameters in the parameter ram.
+       */
+       up->smc_rbase = dpaddr;
+       up->smc_tbase = dpaddr+sizeof(cbd_t);
+       up->smc_rfcr = SMC_EB;
+       up->smc_tfcr = SMC_EB;
+       up->smc_brklen = 0;
+       up->smc_brkec = 0;
+       up->smc_brkcr = 0;
+
+       /* Set UART mode, 8 bit, no parity, one stop.
+        * Enable receive and transmit.
+        */
+       sp->smc_smcmr = smcr_mk_clen(9) |  SMCMR_SM_UART;
+
+       /* Mask all interrupts and remove anything pending.
+       */
+       sp->smc_smcm = 0;
+       sp->smc_smce = 0xff;
+
+       /* Set up the baud rate generator.
+        */
+       ip->im_clkrst.car_sccr = 0;     /* DIV 4 BRG */
+       ip->im_cpmux.cmx_smr = 0;
+       ip->im_brgc1 =
+               ((((bd->bi_brgfreq * 1000000)/16) / bd->bi_baudrate) << 1) |
+                                                               CPM_BRG_EN;
+
+       /* Make the first buffer the only buffer.
+       */
+       tbdf->cbd_sc |= BD_SC_WRAP;
+       rbdf->cbd_sc |= BD_SC_EMPTY | BD_SC_WRAP;
+
+#if 0
+       /* Single character receive.
+       */
+       up->smc_mrblr = 1;
+       up->smc_maxidl = 0;
+#else
+       up->smc_mrblr = 128;
+       up->smc_maxidl = 8;
+#endif
+
+       /* Initialize Tx/Rx parameters.
+       */
+       cp->cp_cpcr = mk_cr_cmd(CPM_CR_SMC1_PAGE, CPM_CR_SMC1_SBLOCK, 0, CPM_CR_INIT_TRX) | CPM_CR_FLG;
+       while (cp->cp_cpcr & CPM_CR_FLG);
+
+       /* Enable transmitter/receiver.
+       */
+       sp->smc_smcmr |= SMCMR_REN | SMCMR_TEN;
+}
+
+void
+serial_putchar(const char c)
+{
+       volatile cbd_t          *tbdf;
+       volatile char           *buf;
+       volatile smc_uart_t     *up;
+       volatile immap_t        *ip;
+       extern bd_t             *board_info;
+
+       ip = (immap_t *)IMAP_ADDR;
+       up = (smc_uart_t *)&(ip->im_dprambase[PROFF_SMC1]);
+       tbdf = (cbd_t *)&ip->im_dprambase[up->smc_tbase];
+
+       /* Wait for last character to go.
+       */
+       buf = (char *)tbdf->cbd_bufaddr;
+       while (tbdf->cbd_sc & BD_SC_READY);
+
+       *buf = c;
+       tbdf->cbd_datlen = 1;
+       tbdf->cbd_sc |= BD_SC_READY;
+}
+
+char
+serial_getc()
+{
+       char    c;
+
+       if (cons_hold_cnt <= 0) {
+               cons_hold_cnt = serial_readbuf(cons_hold);
+               sgptr = cons_hold;
+       }
+       c = *sgptr++;
+       cons_hold_cnt--;
+
+       return(c);
+}
+
+int
+serial_readbuf(u_char *cbuf)
+{
+       volatile cbd_t          *rbdf;
+       volatile char           *buf;
+       volatile smc_uart_t     *up;
+       volatile immap_t        *ip;
+       int     i, nc;
+
+       ip = (immap_t *)IMAP_ADDR;
+
+       up = (smc_uart_t *)&(ip->im_dprambase[PROFF_SMC1]);
+       rbdf = (cbd_t *)&ip->im_dprambase[up->smc_rbase];
+
+       /* Wait for character to show up.
+       */
+       buf = (char *)rbdf->cbd_bufaddr;
+       while (rbdf->cbd_sc & BD_SC_EMPTY);
+       nc = rbdf->cbd_datlen;
+       for (i=0; i<nc; i++)
+               *cbuf++ = *buf++;
+       rbdf->cbd_sc |= BD_SC_EMPTY;
+
+       return(nc);
+}
+
+int
+serial_tstc()
+{
+       volatile cbd_t          *rbdf;
+       volatile smc_uart_t     *up;
+       volatile immap_t        *ip;
+
+       ip = (immap_t *)IMAP_ADDR;
+       up = (smc_uart_t *)&(ip->im_dprambase[PROFF_SMC1]);
+       rbdf = (cbd_t *)&ip->im_dprambase[up->smc_rbase];
+
+       return(!(rbdf->cbd_sc & BD_SC_EMPTY));
+}
+
index 7ecf18512bb5b11ec2a1a926e59a64299fa15d3e..683f53491011651e41e23aa00db30b9b7d643180 100644 (file)
@@ -20,6 +20,9 @@
 #ifdef CONFIG_8xx
 #include <asm/mpc8xx.h>
 #endif
+#ifdef CONFIG_8260
+#include <asm/mpc8260.h>
+#endif
 
 /*
  * Please send me load/board info and such data for hardware not
@@ -231,6 +234,13 @@ decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum, b
        unsigned long i;
        char    *dp;
 
+#ifdef CONFIG_8260
+       /* I don't know why I didn't do it this way on the 8xx.......
+       */
+       embed_config(bp);
+       serial_init(bp);
+#endif
+
        /* These values must be variables.  If not, the compiler optimizer
         * will remove some code, causing the size of the code to vary
         * when these values are zero.  This is bad because we first
index 72a8aa0e7c45d8274d9b49d1bd3c07824d6773d5..4c3332ef8998477bf5fb5beaf0778839caeadd3c 100644 (file)
@@ -1,6 +1,7 @@
 /* Stand alone funtions for QSpan Tundra support.
  */
-#include <sys/types.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
 #include <linux/pci.h>
 #include <asm/mpc8xx.h>
 
index b4f332a9b7fa08c586c4f9b7fdcfcb4bac05e765..f94105b2a4f753b50099f5f55c39819a90d4de35 100644 (file)
@@ -9,7 +9,8 @@
  * I don't know what to do about interrupts (yet).
  */
 
-#include <sys/types.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
 #include <linux/pci.h>
 #include <asm/mpc8xx.h>
 
index 562ce02954a01f0125fa45be3c9e4697b3bec5ce..076ee56e57f1ca638f12bee68d95fcd1e9948c83 100644 (file)
@@ -216,7 +216,7 @@ unsigned long va_to_phys(unsigned long address)
        
        pte = find_pte(current->mm, address);
        if (pte)
-               return((unsigned long)(pte_page(*pte)) | (address & ~(PAGE_MASK-1)));
+               return(((unsigned long)(pte_val(*pte)) & PAGE_MASK) | (address & ~(PAGE_MASK-1)));
        return (0);
 }
 
@@ -237,7 +237,7 @@ print_8xx_pte(struct mm_struct *mm, unsigned long addr)
                                 printk(" (0x%08lx)->(0x%08lx)->0x%08lx\n",
                                         (long)pgd, (long)pte, (long)pte_val(*pte));
 #define pp ((long)pte_val(*pte))                               
-                               printk(" RPN: %05x PP: %x SPS: %x SH: %lx "
+                               printk(" RPN: %05lx PP: %lx SPS: %lx SH: %lx "
                                       "CI: %lx v: %lx\n",
                                       pp>>12,    /* rpn */
                                       (pp>>10)&3, /* pp */
index c92abef90ab8f39c422a1f82b993847dd3d61afc..80fb7575e7ca8f65e502c6d89f2256be323507f5 100644 (file)
 #include <asm/mmu.h>
 #include <asm/residual.h>
 #include <asm/uaccess.h>
+#ifdef CONFIG_8xx
 #include <asm/8xx_immap.h>
 #include <asm/mpc8xx.h>
+#endif
+#ifdef CONFIG_8260
+#include <asm/immap_8260.h>
+#include <asm/mpc8260.h>
+#endif
 #include <asm/smp.h>
 #include <asm/bootx.h>
 #include <asm/machdep.h>
@@ -104,6 +110,9 @@ unsigned long *m8xx_find_end_of_memory(void);
 #ifdef CONFIG_4xx
 unsigned long *oak_find_end_of_memory(void);
 #endif
+#ifdef CONFIG_8260
+unsigned long *m8260_find_end_of_memory(void);
+#endif /* CONFIG_8260 */
 static void mapin_ram(void);
 void map_page(unsigned long va, unsigned long pa, int flags);
 extern void die_if_kernel(char *,struct pt_regs *,long);
@@ -725,7 +734,7 @@ static void __init mapin_ram(void)
                          * don't get ASID compares on kernel space.
                          */
                        f = _PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_SHARED;
-#ifdef CONFIG_KGDB
+#if defined(CONFIG_KGDB) || defined(CONFIG_XMON)
                        /* Allows stub to set breakpoints everywhere */
                        f |= _PAGE_RW | _PAGE_DIRTY | _PAGE_HWWRITE;
 #else
@@ -896,6 +905,9 @@ MMU_init(void)
         mtspr(SPRN_ICCR, 0x80000000);  /* 128 MB of instr. space at 0x0. */
 }
 #else
+       /* How about ppc_md.md_find_end_of_memory instead of these
+        * ifdefs?  -- Dan.
+        */
 void __init MMU_init(void)
 {
        if ( ppc_md.progress ) ppc_md.progress("MMU:enter", 0x111);
@@ -910,8 +922,13 @@ void __init MMU_init(void)
        else if ( _machine == _MACH_gemini )
                end_of_DRAM = gemini_find_end_of_memory();
 #endif /* CONFIG_GEMINI        */
+#if defined(CONFIG_8260)
+       else
+               end_of_DRAM = m8260_find_end_of_memory();
+#else
        else /* prep */
                end_of_DRAM = prep_find_end_of_memory();
+#endif
 
        if ( ppc_md.progress ) ppc_md.progress("MMU:hash init", 0x300);
         hash_init();
@@ -960,11 +977,6 @@ void __init MMU_init(void)
                        setbat(0, base, base, 0x100000, IO_PAGE);
                }
 #endif
-#if 0
-// This is bogus, BAT must be aligned.
-//             setbat(0, disp_bi->dispDeviceBase, disp_bi->dispDeviceBase, 0x100000, IO_PAGE);
-//             disp_bi->logicalDisplayBase = disp_bi->dispDeviceBase;
-#endif         
                ioremap_base = 0xf0000000;
                break;
        case _MACH_apus:
@@ -977,6 +989,16 @@ void __init MMU_init(void)
                setbat(0, 0xf0000000, 0xf0000000, 0x10000000, IO_PAGE);
                setbat(1, 0x80000000, 0x80000000, 0x10000000, IO_PAGE);
                break;
+       case _MACH_8260:
+               /* Map the IMMR, plus anything else we can cover
+                * in that upper space according to the memory controller
+                * chip select mapping.  Grab another bunch of space
+                * below that for stuff we can't cover in the upper.
+                */
+               setbat(0, 0xf0000000, 0xf0000000, 0x10000000, IO_PAGE);
+               setbat(1, 0xe0000000, 0xe0000000, 0x10000000, IO_PAGE);
+               ioremap_base = 0xe0000000;
+               break;
        }
        ioremap_bot = ioremap_base;
 #else /* CONFIG_8xx */
@@ -1295,6 +1317,28 @@ unsigned long __init *gemini_find_end_of_memory(void)
 }
 #endif /* defined(CONFIG_GEMINI) */
 
+#ifdef CONFIG_8260
+/*
+ * Same hack as 8xx.
+ */
+unsigned long __init *m8260_find_end_of_memory(void)
+{
+       bd_t    *binfo;
+       unsigned long *ret;
+       extern unsigned char __res[];
+       
+       binfo = (bd_t *)__res;
+
+       phys_mem.regions[0].address = 0;
+       phys_mem.regions[0].size = binfo->bi_memsize;   
+       phys_mem.n_regions = 1;
+       
+       ret = __va(phys_mem.regions[0].size);
+       set_phys_avail(&phys_mem);
+       return ret;
+}
+#endif /* CONFIG_8260 */
+
 #ifdef CONFIG_APUS
 #define HARDWARE_MAPPED_SIZE (512*1024)
 unsigned long __init *apus_find_end_of_memory(void)
@@ -1396,6 +1440,7 @@ static void __init hash_init(void)
        case 3: /* 603 */
        case 6: /* 603e */
        case 7: /* 603ev */
+       case 0x0081: /* 82xx */
                Hash_size = 0;
                Hash_mask = 0;
                break;
index ba501cf35f3b57e1c9eb93c5e397d0ce8e7af035..614f3b7ebe097e6613ede9554bf105cb56a4be3e 100644 (file)
@@ -1,6 +1,10 @@
 # Makefile for xmon
 
 O_TARGET = x.o
+ifeq ($(CONFIG_8xx),y)
+O_OBJS = start_8xx.o xmon.o ppc-dis.o ppc-opc.o subr_prf.o setjmp.o
+else
 O_OBJS = start.o xmon.o ppc-dis.o ppc-opc.o subr_prf.o setjmp.o
+endif
 
 include $(TOPDIR)/Rules.make
index ec281a154eba34e2838c93b38651baba60491792..c492a35687bda0ff9edb5757b2668f187ba24f06 100644 (file)
@@ -38,6 +38,7 @@ GSETSPR(274, sprg2)
 GSETSPR(275, sprg3)
 GSETSPR(282, ear)
 GSETSPR(287, pvr)
+#ifndef CONFIG_8xx
 GSETSPR(528, bat0u)
 GSETSPR(529, bat0l)
 GSETSPR(530, bat1u)
@@ -51,6 +52,13 @@ GSETSPR(1009, hid1)
 GSETSPR(1010, iabr)
 GSETSPR(1013, dabr)
 GSETSPR(1023, pir)
+#else
+GSETSPR(144, cmpa)
+GSETSPR(145, cmpb)
+GSETSPR(146, cmpc)
+GSETSPR(147, cmpd)
+GSETSPR(158, ictrl)
+#endif
 
 static inline int get_sr(int n)
 {
index 95b19ba475fb2b44c8be027390e6413df3f80b8c..77b6f3548d418735d8acb53a95bc62f10c3ae56e 100644 (file)
@@ -43,6 +43,8 @@ void buf_access(void)
                sccd[3] &= ~0x80;       /* reset DLAB */
 }
 
+extern int adb_init(void);
+
 void
 xmon_map_scc(void)
 {
@@ -59,12 +61,13 @@ xmon_map_scc(void)
 
                /* needs to be hacked if xmon_printk is to be used
                   from within find_via_pmu() */
+#ifdef CONFIG_ADB_PMU
                if (!via_modem && disp_bi && find_via_pmu()) {
                        prom_drawstring("xmon uses screen and keyboard\n");
                        use_screen = 1;
-                       return;
                }
 #endif
+#endif
 
 #ifdef CHRP_ESCC
                addr = 0xc1013020;
@@ -77,18 +80,11 @@ xmon_map_scc(void)
                np = find_devices("mac-io");
                if (np && np->n_addrs) {
                        macio_node = np;
-                       addr = np->addrs[0].address + 0x13000;
-                       /* use the B channel on the iMac */
-                       if (!xmon_use_sccb)
-                               addr += 0x20; /* use A channel */
+                       addr = np->addrs[0].address + 0x13020;
                }
                base = (volatile unsigned char *) ioremap(addr & PAGE_MASK, PAGE_SIZE);
                sccc = base + (addr & ~PAGE_MASK);
-#ifdef CHRP_ESCC
-               sccd = sccc + (0xc1013030 - 0xc1013020);
-#else
-               sccd = sccc + (0xf3013030 - 0xf3013020);
-#endif
+               sccd = sccc + 0x10;
        }
        else if ( _machine & _MACH_gemini )
        {
@@ -133,10 +129,10 @@ xmon_write(void *handle, void *ptr, int nb)
        ct = 0;
        for (i = 0; i < nb; ++i) {
                while ((*sccc & TXRDY) == 0) {
-#ifdef CONFIG_ADB          
+#ifdef CONFIG_ADB_PMU
                        if (sys_ctrler == SYS_CTRLER_PMU)
                                pmu_poll();
-#endif /* CONFIG_ADB */
+#endif /* CONFIG_ADB_PMU */
                }
                c = p[i];
                if (c == '\n' && !ct) {
@@ -144,7 +140,6 @@ xmon_write(void *handle, void *ptr, int nb)
                        ct = 1;
                        --i;
                } else {
-                       prom_drawchar(c);
                        if (console)
                                printk("%c", c);
                        ct = 0;
@@ -156,10 +151,10 @@ xmon_write(void *handle, void *ptr, int nb)
 }
 
 int xmon_wants_key;
-int xmon_pmu_keycode;
+int xmon_adb_keycode;
 
 #ifdef CONFIG_BOOTX_TEXT
-static int xmon_pmu_shiftstate;
+static int xmon_adb_shiftstate;
 
 static unsigned char xmon_keytab[128] =
        "asdfhgzxcv\000bqwer"                           /* 0x00 - 0x0f */
@@ -178,13 +173,13 @@ static unsigned char xmon_shift_keytab[128] =
        "\0\0000123456789\0\0\0";                       /* 0x50 - 0x5f */
 
 static int
-xmon_get_pmu_key(void)
+xmon_get_adb_key(void)
 {
        int k, t, on;
 
        xmon_wants_key = 1;
        for (;;) {
-               xmon_pmu_keycode = -1;
+               xmon_adb_keycode = -1;
                t = 0;
                on = 0;
                do {
@@ -194,20 +189,22 @@ xmon_get_pmu_key(void)
                                prom_drawchar('\b');
                                t = 200000;
                        }
+#ifdef CONFIG_ADB_PMU
                        pmu_poll();
-               } while (xmon_pmu_keycode == -1);
-               k = xmon_pmu_keycode;
+#endif /* CONFIG_ADB_PMU */
+               } while (xmon_adb_keycode == -1);
+               k = xmon_adb_keycode;
                if (on)
                        prom_drawstring(" \b");
 
                /* test for shift keys */
                if ((k & 0x7f) == 0x38 || (k & 0x7f) == 0x7b) {
-                       xmon_pmu_shiftstate = (k & 0x80) == 0;
+                       xmon_adb_shiftstate = (k & 0x80) == 0;
                        continue;
                }
                if (k >= 0x80)
                        continue;       /* ignore up transitions */
-               k = (xmon_pmu_shiftstate? xmon_shift_keytab: xmon_keytab)[k];
+               k = (xmon_adb_shiftstate? xmon_shift_keytab: xmon_keytab)[k];
                if (k != 0)
                        break;
        }
@@ -225,7 +222,7 @@ xmon_read(void *handle, void *ptr, int nb)
 #ifdef CONFIG_BOOTX_TEXT
     if (use_screen) {
        for (i = 0; i < nb; ++i)
-           *p++ = xmon_get_pmu_key();
+           *p++ = xmon_get_adb_key();
        return i;
     }
 #endif
@@ -233,12 +230,12 @@ xmon_read(void *handle, void *ptr, int nb)
        xmon_init_scc();
     for (i = 0; i < nb; ++i) {
        while ((*sccc & RXRDY) == 0)
-#ifdef CONFIG_ADB          
+#ifdef CONFIG_ADB_PMU
            if (sys_ctrler == SYS_CTRLER_PMU)
                pmu_poll();
 #else
                ;
-#endif /* CONFIG_ADB */
+#endif /* CONFIG_ADB_PMU */
        buf_access();
                *p++ = *sccd;
     }
@@ -249,12 +246,10 @@ int
 xmon_read_poll(void)
 {
        if ((*sccc & RXRDY) == 0) {
-#ifdef CONFIG_ADB          
+#ifdef CONFIG_ADB_PMU
                if (sys_ctrler == SYS_CTRLER_PMU)
                        pmu_poll();
-#else
-                       ;
-#endif                 
+#endif /* CONFIG_ADB_PMU */
                return -1;
        }
        buf_access();
@@ -297,6 +292,12 @@ xmon_init_scc()
                        while (readtb() - t0 < 3*TB_SPEED)
                                eieio();
                }
+               /* use the B channel if requested */
+               if (xmon_use_sccb) {
+                       sccc = (volatile unsigned char *)
+                               ((unsigned long)sccc & ~0x20);
+                       sccd = sccc + 0x10;
+               }
                for (i = 20000; i != 0; --i) {
                        x = *sccc; eieio();
                }
diff --git a/arch/ppc/xmon/start_8xx.c b/arch/ppc/xmon/start_8xx.c
new file mode 100644 (file)
index 0000000..64bd431
--- /dev/null
@@ -0,0 +1,289 @@
+/*
+ * Copyright (C) 1996 Paul Mackerras.
+ * Copyright (C) 2000 Dan Malek.
+ * Quick hack of Paul's code to make XMON work on 8xx processors.  Lots
+ * of assumptions, like the SMC1 is used, it has been initialized by the
+ * loader at some point, and we can just stuff and suck bytes.
+ * We rely upon the 8xx uart driver to support us, as the interface
+ * changes between boot up and operational phases of the kernel.
+ */
+#include <linux/config.h>
+#include <linux/string.h>
+#include <asm/machdep.h>
+#include <asm/io.h>
+#include <asm/page.h>
+#include <linux/kernel.h>
+#include <asm/processor.h>
+#include <asm/8xx_immap.h>
+#include <asm/mpc8xx.h>
+#include "commproc.h"
+
+extern void xmon_printf(const char *fmt, ...);
+extern int xmon_8xx_write(char *str, int nb);
+extern int xmon_8xx_read_poll(void);
+extern int xmon_8xx_read_char(void);
+void prom_drawhex(uint);
+void prom_drawstring(const char *str);
+
+static int use_screen = 1; /* default */
+
+#define TB_SPEED       25000000
+
+static inline unsigned int readtb(void)
+{
+       unsigned int ret;
+
+       asm volatile("mftb %0" : "=r" (ret) :);
+       return ret;
+}
+
+void buf_access(void)
+{
+}
+
+void
+xmon_map_scc(void)
+{
+
+       cpmp = (cpm8xx_t *)&(((immap_t *)IMAP_ADDR)->im_cpm);
+       use_screen = 0;
+       
+       prom_drawstring("xmon uses serial port\n");
+}
+
+static int scc_initialized = 0;
+
+void xmon_init_scc(void);
+
+int
+xmon_write(void *handle, void *ptr, int nb)
+{
+       char *p = ptr;
+       int i, c, ct;
+
+       if (!scc_initialized)
+               xmon_init_scc();
+
+       return(xmon_8xx_write(ptr, nb));
+}
+
+int xmon_wants_key;
+
+int
+xmon_read(void *handle, void *ptr, int nb)
+{
+       char *p = ptr;
+       int i;
+
+       if (!scc_initialized)
+               xmon_init_scc();
+
+       for (i = 0; i < nb; ++i) {
+               *p++ = xmon_8xx_read_char();
+       }
+       return i;
+}
+
+int
+xmon_read_poll(void)
+{
+       return(xmon_8xx_read_poll());
+}
+
+void
+xmon_init_scc()
+{
+       scc_initialized = 1;
+}
+
+#if 0
+extern int (*prom_entry)(void *);
+
+int
+xmon_exit(void)
+{
+    struct prom_args {
+       char *service;
+    } args;
+
+    for (;;) {
+       args.service = "exit";
+       (*prom_entry)(&args);
+    }
+}
+#endif
+
+void *xmon_stdin;
+void *xmon_stdout;
+void *xmon_stderr;
+
+void
+xmon_init(void)
+{
+}
+
+int
+xmon_putc(int c, void *f)
+{
+    char ch = c;
+
+    if (c == '\n')
+       xmon_putc('\r', f);
+    return xmon_write(f, &ch, 1) == 1? c: -1;
+}
+
+int
+xmon_putchar(int c)
+{
+    return xmon_putc(c, xmon_stdout);
+}
+
+int
+xmon_fputs(char *str, void *f)
+{
+    int n = strlen(str);
+
+    return xmon_write(f, str, n) == n? 0: -1;
+}
+
+int
+xmon_readchar(void)
+{
+    char ch;
+
+    for (;;) {
+       switch (xmon_read(xmon_stdin, &ch, 1)) {
+       case 1:
+           return ch;
+       case -1:
+           xmon_printf("read(stdin) returned -1\r\n", 0, 0);
+           return -1;
+       }
+    }
+}
+
+static char line[256];
+static char *lineptr;
+static int lineleft;
+
+#if 0
+int xmon_expect(const char *str, unsigned int timeout)
+{
+       int c;
+       unsigned int t0;
+
+       timeout *= TB_SPEED;
+       t0 = readtb();
+       do {
+               lineptr = line;
+               for (;;) {
+                       c = xmon_read_poll();
+                       if (c == -1) {
+                               if (readtb() - t0 > timeout)
+                                       return 0;
+                               continue;
+                       }
+                       if (c == '\n')
+                               break;
+                       if (c != '\r' && lineptr < &line[sizeof(line) - 1])
+                               *lineptr++ = c;
+               }
+               *lineptr = 0;
+       } while (strstr(line, str) == NULL);
+       return 1;
+}
+#endif
+
+int
+xmon_getchar(void)
+{
+    int c;
+
+    if (lineleft == 0) {
+       lineptr = line;
+       for (;;) {
+           c = xmon_readchar();
+           if (c == -1 || c == 4)
+               break;
+           if (c == '\r' || c == '\n') {
+               *lineptr++ = '\n';
+               xmon_putchar('\n');
+               break;
+           }
+           switch (c) {
+           case 0177:
+           case '\b':
+               if (lineptr > line) {
+                   xmon_putchar('\b');
+                   xmon_putchar(' ');
+                   xmon_putchar('\b');
+                   --lineptr;
+               }
+               break;
+           case 'U' & 0x1F:
+               while (lineptr > line) {
+                   xmon_putchar('\b');
+                   xmon_putchar(' ');
+                   xmon_putchar('\b');
+                   --lineptr;
+               }
+               break;
+           default:
+               if (lineptr >= &line[sizeof(line) - 1])
+                   xmon_putchar('\a');
+               else {
+                   xmon_putchar(c);
+                   *lineptr++ = c;
+               }
+           }
+       }
+       lineleft = lineptr - line;
+       lineptr = line;
+    }
+    if (lineleft == 0)
+       return -1;
+    --lineleft;
+    return *lineptr++;
+}
+
+char *
+xmon_fgets(char *str, int nb, void *f)
+{
+    char *p;
+    int c;
+
+    for (p = str; p < str + nb - 1; ) {
+       c = xmon_getchar();
+       if (c == -1) {
+           if (p == str)
+               return 0;
+           break;
+       }
+       *p++ = c;
+       if (c == '\n')
+           break;
+    }
+    *p = 0;
+    return str;
+}
+
+void
+prom_drawhex(uint val)
+{
+       unsigned char buf[10];
+
+       int i;
+       for (i = 7;  i >= 0;  i--)
+       {
+               buf[i] = "0123456789abcdef"[val & 0x0f];
+               val >>= 4;
+       }
+       buf[8] = '\0';
+       xmon_fputs(buf, xmon_stdout);
+}
+
+void
+prom_drawstring(const char *str)
+{
+       xmon_fputs(str, xmon_stdout);
+}
index b81e21890c2072f941bb6d9790402dae05e4cf2c..17975cb44376d008f05939545e3eb0c88918953d 100644 (file)
@@ -120,8 +120,7 @@ void
 xmon(struct pt_regs *excp)
 {
        struct pt_regs regs;
-       int msr, cmd, i;
-       unsigned *sp;
+       int msr, cmd;
 
        if (excp == NULL) {
                asm volatile ("stw      0,0(%0)\n\
@@ -137,29 +136,6 @@ xmon(struct pt_regs *excp)
                excp = &regs;
        }
 
-       prom_drawstring("xmon pc="); prom_drawhex(excp->nip);
-       prom_drawstring(" lr="); prom_drawhex(excp->link);
-       prom_drawstring(" msr="); prom_drawhex(excp->msr);
-       prom_drawstring(" trap="); prom_drawhex(excp->trap);
-       prom_drawstring(" sp="); prom_drawhex(excp->gpr[1]);
-       sp = (unsigned *)&excp->gpr[0];
-       for (i = 0; i < 32; ++i) {
-               if ((i & 7) == 0)
-                       prom_drawstring("\n");
-               prom_drawstring(" ");
-               prom_drawhex(sp[i]);
-       }
-       sp = (unsigned *) excp->gpr[1];
-       for (i = 0; i < 64; ++i) {
-               if ((i & 7) == 0) {
-                       prom_drawstring("\n");
-                       prom_drawhex(sp);
-                       prom_drawstring(" ");
-               }
-               prom_drawstring(" ");
-               prom_drawhex(sp[i]);
-       }
-       prom_drawstring("\n");
        msr = get_msr();
        set_msr(msr & ~0x8000); /* disable interrupts */
        remove_bpts();
@@ -284,10 +260,12 @@ insert_bpts()
                        bp->enabled = 0;
                }
        }
+#ifndef CONFIG_8xx
        if (dabr.enabled)
                set_dabr(dabr.address);
        if (iabr.enabled)
                set_iabr(iabr.address);
+#endif
 }
 
 static void
@@ -297,8 +275,10 @@ remove_bpts()
        struct bpt *bp;
        unsigned instr;
 
+#ifndef CONFIG_8xx
        set_dabr(0);
        set_iabr(0);
+#endif
        bp = bpts;
        for (i = 0; i < NBPTS; ++i, ++bp) {
                if (!bp->enabled)
@@ -412,6 +392,7 @@ bpt_cmds(void)
 
        cmd = inchar();
        switch (cmd) {
+#ifndef CONFIG_8xx
        case 'd':
                mode = 7;
                cmd = inchar();
@@ -436,6 +417,7 @@ bpt_cmds(void)
                        iabr.address |= 3;
                scanhex(&iabr.count);
                break;
+#endif
        case 'c':
                if (!scanhex(&a)) {
                        /* clear all breakpoints */
@@ -1406,6 +1388,7 @@ static char *lookup_name(unsigned long addr)
 return NULL;   
 #if 0
        cmp = simple_strtoul(c, &c, 8);
+       /* XXX crap, we don't want the whole of the rest of the map - paulus */
        strcpy( last, strsep( &c, "\n"));
        while ( c < (sysmap+sysmap_size) )
        {
@@ -1414,7 +1397,7 @@ return NULL;
                        break;
                strcpy( last, strsep( &c, "\n"));
        }
-       return NULLlast;
+       return last;
 #endif 
 }
 
index c4b9500df7f4316da71afc74b1187176dba470d3..8254d0a7aa8ca72abe62295df0f5226dc31a1d62 100644 (file)
@@ -583,8 +583,7 @@ static inline void debugt(const char *message)
 }
 
 typedef void (*timeout_fn)(unsigned long);
-static struct timer_list fd_timeout ={ NULL, NULL, 0, 0,
-                                      (timeout_fn) floppy_shutdown };
+static struct timer_list fd_timeout ={ function: (timeout_fn) floppy_shutdown };
 
 static const char *timeout_message;
 
@@ -592,7 +591,7 @@ static const char *timeout_message;
 static void is_alive(const char *message)
 {
        /* this routine checks whether the floppy driver is "alive" */
-       if (fdc_busy && command_status < 2 && !fd_timeout.prev){
+       if (fdc_busy && command_status < 2 && !timer_pending(&fd_timeout)){
                DPRINT("timeout handler died: %s\n",message);
        }
 }
@@ -903,14 +902,14 @@ static void motor_off_callback(unsigned long nr)
 }
 
 static struct timer_list motor_off_timer[N_DRIVE] = {
-       { NULL, NULL, 0, 0, motor_off_callback },
-       { NULL, NULL, 0, 1, motor_off_callback },
-       { NULL, NULL, 0, 2, motor_off_callback },
-       { NULL, NULL, 0, 3, motor_off_callback },
-       { NULL, NULL, 0, 4, motor_off_callback },
-       { NULL, NULL, 0, 5, motor_off_callback },
-       { NULL, NULL, 0, 6, motor_off_callback },
-       { NULL, NULL, 0, 7, motor_off_callback }
+       { data: 0, function: motor_off_callback },
+       { data: 1, function: motor_off_callback },
+       { data: 2, function: motor_off_callback },
+       { data: 3, function: motor_off_callback },
+       { data: 4, function: motor_off_callback },
+       { data: 5, function: motor_off_callback },
+       { data: 6, function: motor_off_callback },
+       { data: 7, function: motor_off_callback }
 };
 
 /* schedules motor off */
@@ -976,7 +975,7 @@ static void schedule_bh( void (*handler)(void*) )
        mark_bh(IMMEDIATE_BH);
 }
 
-static struct timer_list fd_timer ={ NULL, NULL, 0, 0, 0 };
+static struct timer_list fd_timer;
 
 static void cancel_activity(void)
 {
@@ -1852,9 +1851,9 @@ static void show_floppy(void)
                printk("DEVICE_INTR=%p\n", DEVICE_INTR);
        if (floppy_tq.sync)
                printk("floppy_tq.routine=%p\n", floppy_tq.routine);
-       if (fd_timer.prev)
+       if (timer_pending(&fd_timer))
                printk("fd_timer.function=%p\n", fd_timer.function);
-       if (fd_timeout.prev){
+       if (timer_pending(&fd_timeout)){
                printk("timer_table=%p\n",fd_timeout.function);
                printk("expires=%lu\n",fd_timeout.expires-jiffies);
                printk("now=%lu\n",jiffies);
@@ -4334,13 +4333,13 @@ static void floppy_release_irq_and_dma(void)
 #ifdef FLOPPY_SANITY_CHECK
 #ifndef __sparc__
        for (drive=0; drive < N_FDC * 4; drive++)
-               if (motor_off_timer[drive].next)
+               if (timer_pending(motor_off_timer + drive))
                        printk("motor off timer %d still active\n", drive);
 #endif
 
-       if (fd_timeout.next)
+       if (timer_pending(&fd_timeout))
                printk("floppy timer still active:%s\n", timeout_message);
-       if (fd_timer.next)
+       if (timer_pending(&fd_timer))
                printk("auxiliary floppy timer still active\n");
        if (floppy_tq.sync)
                printk("task queue still active\n");
index 668cb5096fdc2d336976c62e1a9f097cdf99dca5..bacb62fba9a8af56820bce829c60ae9a00fc2e66 100644 (file)
@@ -443,6 +443,7 @@ static int loop_set_fd(struct loop_device *lo, kdev_t dev, unsigned int arg)
                        lo->lo_backing_file->f_flags = file->f_flags;
                        lo->lo_backing_file->f_owner = file->f_owner;
                        lo->lo_backing_file->f_dentry = file->f_dentry;
+                       lo->lo_backing_file->f_vfsmnt = file->f_vfsmnt;
                        lo->lo_backing_file->f_op = file->f_op;
                        lo->lo_backing_file->private_data = file->private_data;
                        file_moveto(lo->lo_backing_file, file);
index cf51995ec1da78a8db997e9867b630e110d04851..87b1d56d13c29a80dab5514df418e604365a4a13 100644 (file)
  *     1.10    Paul Barton-Davis: add support for async I/O
  *     1.10a   Andrea Arcangeli: Alpha updates
  *     1.10b   Andrew Morton: SMP lock fix
+ *     1.10c   Cesar Barros: SMP locking fixes and cleanup
  */
 
-#define RTC_VERSION            "1.10b"
+#define RTC_VERSION            "1.10c"
 
 #define RTC_IRQ        8       /* Can't see this changing soon.        */
 #define RTC_IO_EXTENT  0x10    /* Only really two ports, but...        */
@@ -124,7 +125,14 @@ static int rtc_read_proc(char *page, char **start, off_t off,
 #define RTC_IS_OPEN            0x01    /* means /dev/rtc is in use     */
 #define RTC_TIMER_ON           0x02    /* missed irq timer active      */
 
-static atomic_t rtc_status = ATOMIC_INIT(0); /* bitmapped status byte. */
+/*
+ * rtc_status is never changed by rtc_interrupt, and ioctl/open/close is
+ * protected by the big kernel lock. However, ioctl can still disable the timer
+ * in rtc_status and then with del_timer after the interrupt has read
+ * rtc_status but before mod_timer is called, which would then reenable the
+ * timer (but you would need to have an awful timing before you'd trip on it)
+ */
+static unsigned long rtc_status = 0;   /* bitmapped status byte.       */
 static unsigned long rtc_freq = 0;     /* Current periodic IRQ rate    */
 static unsigned long rtc_irq_data = 0; /* our output to the world      */
 
@@ -162,15 +170,17 @@ static void rtc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
        rtc_irq_data += 0x100;
        rtc_irq_data &= ~0xff;
        rtc_irq_data |= (CMOS_READ(RTC_INTR_FLAGS) & 0xF0);
+
+       if (rtc_status & RTC_TIMER_ON)
+               mod_timer(&rtc_irq_timer, jiffies + HZ/rtc_freq + 2*HZ/100);
+
        spin_unlock (&rtc_lock);
 
+       /* Now do the rest of the actions */
        wake_up_interruptible(&rtc_wait);       
 
        if (rtc_async_queue)
                kill_fasync (rtc_async_queue, SIGIO, POLL_IN);
-
-       if (atomic_read(&rtc_status) & RTC_TIMER_ON)
-               mod_timer(&rtc_irq_timer, jiffies + HZ/rtc_freq + 2*HZ/100);
 }
 #endif
 
@@ -200,7 +210,18 @@ static ssize_t rtc_read(struct file *file, char *buf,
 
        current->state = TASK_INTERRUPTIBLE;
                
-       while ((data = xchg(&rtc_irq_data, 0)) == 0) {
+       do {
+               /* First make it right. Then make it fast. Putting this whole
+                * block within the parentheses of a while would be too
+                * confusing. And no, xchg() is not the answer. */
+               spin_lock_irq (&rtc_lock);
+               data = rtc_irq_data;
+               rtc_irq_data = 0;
+               spin_unlock_irq (&rtc_lock);
+
+               if (data != 0)
+                       break;
+
                if (file->f_flags & O_NONBLOCK) {
                        retval = -EAGAIN;
                        goto out;
@@ -210,7 +231,7 @@ static ssize_t rtc_read(struct file *file, char *buf,
                        goto out;
                }
                schedule();
-       }
+       } while (1);
 
        retval = put_user(data, (unsigned long *)buf); 
        if (!retval)
@@ -226,8 +247,6 @@ static ssize_t rtc_read(struct file *file, char *buf,
 static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
                     unsigned long arg)
 {
-
-       unsigned long flags;
        struct rtc_time wtime; 
 
        switch (cmd) {
@@ -245,10 +264,11 @@ static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
        case RTC_PIE_OFF:       /* Mask periodic int. enab. bit */
        {
                mask_rtc_irq_bit(RTC_PIE);
-               if (atomic_read(&rtc_status) & RTC_TIMER_ON) {
+               if (rtc_status & RTC_TIMER_ON) {
+                       spin_lock_irq (&rtc_lock);
+                       rtc_status &= ~RTC_TIMER_ON;
                        del_timer(&rtc_irq_timer);
-                       atomic_set(&rtc_status,
-                                  atomic_read(&rtc_status) & ~RTC_TIMER_ON);
+                       spin_unlock_irq (&rtc_lock);
                }
                return 0;
        }
@@ -262,11 +282,12 @@ static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
                if ((rtc_freq > 64) && (!capable(CAP_SYS_RESOURCE)))
                        return -EACCES;
 
-               if (!(atomic_read(&rtc_status) & RTC_TIMER_ON)) {
-                       atomic_set(&rtc_status,
-                                  atomic_read(&rtc_status) | RTC_TIMER_ON);
+               if (!(rtc_status & RTC_TIMER_ON)) {
+                       spin_lock_irq (&rtc_lock);
                        rtc_irq_timer.expires = jiffies + HZ/rtc_freq + 2*HZ/100;
                        add_timer(&rtc_irq_timer);
+                       rtc_status |= RTC_TIMER_ON;
+                       spin_unlock_irq (&rtc_lock);
                }
                set_rtc_irq_bit(RTC_PIE);
                return 0;
@@ -320,7 +341,7 @@ static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
                if (sec >= 60)
                        sec = 0xff;
 
-               spin_lock_irqsave(&rtc_lock, flags);
+               spin_lock_irq(&rtc_lock);
                if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) ||
                    RTC_ALWAYS_BCD)
                {
@@ -331,7 +352,7 @@ static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
                CMOS_WRITE(hrs, RTC_HOURS_ALARM);
                CMOS_WRITE(min, RTC_MINUTES_ALARM);
                CMOS_WRITE(sec, RTC_SECONDS_ALARM);
-               spin_unlock_irqrestore(&rtc_lock, flags);
+               spin_unlock_irq(&rtc_lock);
 
                return 0;
        }
@@ -346,8 +367,7 @@ static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
                unsigned char mon, day, hrs, min, sec, leap_yr;
                unsigned char save_control, save_freq_select;
                unsigned int yrs;
-               unsigned long flags;
-                       
+
                if (!capable(CAP_SYS_TIME))
                        return -EACCES;
 
@@ -379,11 +399,11 @@ static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
                if ((yrs -= epoch) > 255)    /* They are unsigned */
                        return -EINVAL;
 
-               spin_lock_irqsave(&rtc_lock, flags);
+               spin_lock_irq(&rtc_lock);
                if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY)
                    || RTC_ALWAYS_BCD) {
                        if (yrs > 169) {
-                               spin_unlock_irqrestore(&rtc_lock, flags);
+                               spin_unlock_irq(&rtc_lock);
                                return -EINVAL;
                        }
                        if (yrs >= 100)
@@ -412,7 +432,7 @@ static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
                CMOS_WRITE(save_control, RTC_CONTROL);
                CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT);
 
-               spin_unlock_irqrestore(&rtc_lock, flags);
+               spin_unlock_irq(&rtc_lock);
                return 0;
        }
 #ifndef __alpha__
@@ -446,13 +466,13 @@ static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
                if (arg != (1<<tmp))
                        return -EINVAL;
 
+               spin_lock_irq(&rtc_lock);
                rtc_freq = arg;
 
-               spin_lock_irqsave(&rtc_lock, flags);
                val = CMOS_READ(RTC_FREQ_SELECT) & 0xf0;
                val |= (16 - tmp);
                CMOS_WRITE(val, RTC_FREQ_SELECT);
-               spin_unlock_irqrestore(&rtc_lock, flags);
+               spin_unlock_irq(&rtc_lock);
                return 0;
        }
 #else
@@ -489,18 +509,18 @@ static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
 
 static int rtc_open(struct inode *inode, struct file *file)
 {
-       unsigned long flags;
-
-       if(atomic_read(&rtc_status) & RTC_IS_OPEN)
+       /* If someday somebody decides to remove the kernel_lock on open and
+        * close and ioctl this is gonna get open to races */
+       if(rtc_status & RTC_IS_OPEN)
                return -EBUSY;
 
        MOD_INC_USE_COUNT;
 
-       atomic_set(&rtc_status, atomic_read(&rtc_status) | RTC_IS_OPEN);
+       rtc_status |= RTC_IS_OPEN;
 
-       spin_lock_irqsave (&rtc_lock, flags);
+       spin_lock_irq (&rtc_lock);
        rtc_irq_data = 0;
-       spin_unlock_irqrestore (&rtc_lock, flags);
+       spin_unlock_irq (&rtc_lock);
        return 0;
 }
 
@@ -512,7 +532,6 @@ static int rtc_fasync (int fd, struct file *filp, int on)
 
 static int rtc_release(struct inode *inode, struct file *file)
 {
-       unsigned long flags;
 #ifndef __alpha__
        /*
         * Turn off all interrupts once the device is no longer
@@ -521,19 +540,19 @@ static int rtc_release(struct inode *inode, struct file *file)
 
        unsigned char tmp;
 
-       spin_lock_irqsave(&rtc_lock, flags);
+       spin_lock_irq(&rtc_lock);
        tmp = CMOS_READ(RTC_CONTROL);
        tmp &=  ~RTC_PIE;
        tmp &=  ~RTC_AIE;
        tmp &=  ~RTC_UIE;
        CMOS_WRITE(tmp, RTC_CONTROL);
        CMOS_READ(RTC_INTR_FLAGS);
-       spin_unlock_irqrestore(&rtc_lock, flags);
 
-       if (atomic_read(&rtc_status) & RTC_TIMER_ON) {
-               atomic_set(&rtc_status, atomic_read(&rtc_status) & ~RTC_TIMER_ON);
+       if (rtc_status & RTC_TIMER_ON) {
+               rtc_status &= ~RTC_TIMER_ON;
                del_timer(&rtc_irq_timer);
        }
+       spin_unlock_irq(&rtc_lock);
 
        if (file->f_flags & FASYNC) {
                rtc_fasync (-1, file, 0);
@@ -542,10 +561,10 @@ static int rtc_release(struct inode *inode, struct file *file)
 #endif
        MOD_DEC_USE_COUNT;
 
-       spin_lock_irqsave (&rtc_lock, flags);
+       spin_lock_irq (&rtc_lock);
        rtc_irq_data = 0;
-       spin_unlock_irqrestore (&rtc_lock, flags);
-       atomic_set(&rtc_status, atomic_read(&rtc_status) & ~RTC_IS_OPEN);
+       spin_unlock_irq (&rtc_lock);
+       rtc_status = rtc_status & ~RTC_IS_OPEN;
        return 0;
 }
 
@@ -553,13 +572,13 @@ static int rtc_release(struct inode *inode, struct file *file)
 /* Called without the kernel lock - fine */
 static unsigned int rtc_poll(struct file *file, poll_table *wait)
 {
-       unsigned long l, flags;
+       unsigned long l;
 
        poll_wait(file, &rtc_wait, wait);
 
-       spin_lock_irqsave (&rtc_lock, flags);
+       spin_lock_irq (&rtc_lock);
        l = rtc_irq_data;
-       spin_unlock_irqrestore (&rtc_lock, flags);
+       spin_unlock_irq (&rtc_lock);
 
        if (l != 0)
                return POLLIN | POLLRDNORM;
@@ -592,7 +611,6 @@ static struct miscdevice rtc_dev=
 
 static int __init rtc_init(void)
 {
-       unsigned long flags;
 #ifdef __alpha__
        unsigned int year, ctrl;
        unsigned long uip_watchdog;
@@ -663,10 +681,10 @@ found:
                while (jiffies - uip_watchdog < 2*HZ/100)
                        barrier();
        
-       spin_lock_irqsave(&rtc_lock, flags);
+       spin_lock_irq(&rtc_lock);
        year = CMOS_READ(RTC_YEAR);
        ctrl = CMOS_READ(RTC_CONTROL);
-       spin_unlock_irqrestore(&rtc_lock, flags);
+       spin_unlock_irq(&rtc_lock);
        
        if (!(ctrl & RTC_DM_BINARY) || RTC_ALWAYS_BCD)
                BCD_TO_BIN(year);       /* This should never happen... */
@@ -684,12 +702,12 @@ found:
 #ifndef __alpha__
        init_timer(&rtc_irq_timer);
        rtc_irq_timer.function = rtc_dropped_irq;
-       spin_lock_irqsave(&rtc_lock, flags);
+       spin_lock_irq(&rtc_lock);
        /* Initialize periodic freq. to CMOS reset default, which is 1024Hz */
        CMOS_WRITE(((CMOS_READ(RTC_FREQ_SELECT) & 0xF0) | 0x06), RTC_FREQ_SELECT);
-       spin_unlock_irqrestore(&rtc_lock, flags);
-#endif
+       spin_unlock_irq(&rtc_lock);
        rtc_freq = 1024;
+#endif
 
        printk(KERN_INFO "Real Time Clock Driver v" RTC_VERSION "\n");
 
@@ -699,9 +717,16 @@ found:
 static void __exit rtc_exit (void)
 {
        /* interrupts and maybe timer disabled at this point by rtc_release */
+       /* FIXME: Maybe??? */
 
-       if (atomic_read(&rtc_status) & RTC_TIMER_ON)
+       if (rtc_status & RTC_TIMER_ON) {
+               spin_lock_irq (&rtc_lock);
+               rtc_status &= ~RTC_TIMER_ON;
                del_timer(&rtc_irq_timer);
+               spin_unlock_irq (&rtc_lock);
+
+               printk(KERN_WARNING "rtc_exit(), and timer still running.\n");
+       }
 
        remove_proc_entry ("driver/rtc", NULL);
        misc_deregister(&rtc_dev);
@@ -735,16 +760,24 @@ EXPORT_NO_SYMBOLS;
 
 static void rtc_dropped_irq(unsigned long data)
 {
-       unsigned long flags;
-
        printk(KERN_INFO "rtc: lost some interrupts at %ldHz.\n", rtc_freq);
-       mod_timer(&rtc_irq_timer, jiffies + HZ/rtc_freq + 2*HZ/100);
 
-       spin_lock_irqsave(&rtc_lock, flags);
+       spin_lock_irq (&rtc_lock);
+
+       /* Just in case someone disabled the timer from behind our back... */
+       if (rtc_status & RTC_TIMER_ON)
+               mod_timer(&rtc_irq_timer, jiffies + HZ/rtc_freq + 2*HZ/100);
+
        rtc_irq_data += ((rtc_freq/HZ)<<8);
        rtc_irq_data &= ~0xff;
        rtc_irq_data |= (CMOS_READ(RTC_INTR_FLAGS) & 0xF0);     /* restart */
-       spin_unlock_irqrestore(&rtc_lock, flags);
+       spin_unlock_irq(&rtc_lock);
+
+       /* Now we have new data */
+       wake_up_interruptible(&rtc_wait);
+
+       if (rtc_async_queue)
+               kill_fasync (rtc_async_queue, SIGIO, POLL_IN);
 }
 #endif
 
@@ -759,12 +792,13 @@ static int rtc_proc_output (char *buf)
        char *p;
        struct rtc_time tm;
        unsigned char batt, ctrl;
-       unsigned long flags;
+       unsigned long freq;
 
-       spin_lock_irqsave(&rtc_lock, flags);
+       spin_lock_irq(&rtc_lock);
        batt = CMOS_READ(RTC_VALID) & RTC_VRT;
        ctrl = CMOS_READ(RTC_CONTROL);
-       spin_unlock_irqrestore(&rtc_lock, flags);
+       freq = rtc_freq;
+       spin_unlock_irq(&rtc_lock);
 
        p = buf;
 
@@ -821,7 +855,7 @@ static int rtc_proc_output (char *buf)
                     YN(RTC_AIE),
                     YN(RTC_UIE),
                     YN(RTC_PIE),
-                    rtc_freq,
+                    freq,
                     batt ? "okay" : "dead");
 
        return  p - buf;
@@ -844,21 +878,20 @@ static int rtc_read_proc(char *page, char **start, off_t off,
 /*
  * Returns true if a clock update is in progress
  */
+/* FIXME shouldn't this be above rtc_init to make it fully inlined? */
 static inline unsigned char rtc_is_updating(void)
 {
-       unsigned long flags;
        unsigned char uip;
 
-       spin_lock_irqsave(&rtc_lock, flags);
+       spin_lock_irq(&rtc_lock);
        uip = (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP);
-       spin_unlock_irqrestore(&rtc_lock, flags);
+       spin_unlock_irq(&rtc_lock);
        return uip;
 }
 
 static void get_rtc_time(struct rtc_time *rtc_tm)
 {
-
-       unsigned long flags, uip_watchdog = jiffies;
+       unsigned long uip_watchdog = jiffies;
        unsigned char ctrl;
 
        /*
@@ -881,7 +914,7 @@ static void get_rtc_time(struct rtc_time *rtc_tm)
         * RTC has RTC_DAY_OF_WEEK, we ignore it, as it is only updated
         * by the RTC when initially set to a non-zero value.
         */
-       spin_lock_irqsave(&rtc_lock, flags);
+       spin_lock_irq(&rtc_lock);
        rtc_tm->tm_sec = CMOS_READ(RTC_SECONDS);
        rtc_tm->tm_min = CMOS_READ(RTC_MINUTES);
        rtc_tm->tm_hour = CMOS_READ(RTC_HOURS);
@@ -889,7 +922,7 @@ static void get_rtc_time(struct rtc_time *rtc_tm)
        rtc_tm->tm_mon = CMOS_READ(RTC_MONTH);
        rtc_tm->tm_year = CMOS_READ(RTC_YEAR);
        ctrl = CMOS_READ(RTC_CONTROL);
-       spin_unlock_irqrestore(&rtc_lock, flags);
+       spin_unlock_irq(&rtc_lock);
 
        if (!(ctrl & RTC_DM_BINARY) || RTC_ALWAYS_BCD)
        {
@@ -913,19 +946,18 @@ static void get_rtc_time(struct rtc_time *rtc_tm)
 
 static void get_rtc_alm_time(struct rtc_time *alm_tm)
 {
-       unsigned long flags;
        unsigned char ctrl;
 
        /*
         * Only the values that we read from the RTC are set. That
         * means only tm_hour, tm_min, and tm_sec.
         */
-       spin_lock_irqsave(&rtc_lock, flags);
+       spin_lock_irq(&rtc_lock);
        alm_tm->tm_sec = CMOS_READ(RTC_SECONDS_ALARM);
        alm_tm->tm_min = CMOS_READ(RTC_MINUTES_ALARM);
        alm_tm->tm_hour = CMOS_READ(RTC_HOURS_ALARM);
        ctrl = CMOS_READ(RTC_CONTROL);
-       spin_unlock_irqrestore(&rtc_lock, flags);
+       spin_unlock_irq(&rtc_lock);
 
        if (!(ctrl & RTC_DM_BINARY) || RTC_ALWAYS_BCD)
        {
@@ -949,28 +981,28 @@ static void get_rtc_alm_time(struct rtc_time *alm_tm)
 static void mask_rtc_irq_bit(unsigned char bit)
 {
        unsigned char val;
-       unsigned long flags;
 
-       spin_lock_irqsave(&rtc_lock, flags);
+       spin_lock_irq(&rtc_lock);
        val = CMOS_READ(RTC_CONTROL);
        val &=  ~bit;
        CMOS_WRITE(val, RTC_CONTROL);
        CMOS_READ(RTC_INTR_FLAGS);
+
        rtc_irq_data = 0;
-       spin_unlock_irqrestore(&rtc_lock, flags);
+       spin_unlock_irq(&rtc_lock);
 }
 
 static void set_rtc_irq_bit(unsigned char bit)
 {
        unsigned char val;
-       unsigned long flags;
 
-       spin_lock_irqsave(&rtc_lock, flags);
+       spin_lock_irq(&rtc_lock);
        val = CMOS_READ(RTC_CONTROL);
        val |= bit;
        CMOS_WRITE(val, RTC_CONTROL);
        CMOS_READ(RTC_INTR_FLAGS);
+
        rtc_irq_data = 0;
-       spin_unlock_irqrestore(&rtc_lock, flags);
+       spin_unlock_irq(&rtc_lock);
 }
 #endif
index 5c66649e85bcbc106eb1b7430a672bbd515a370f..0776b5d6b70aca7602fe4ef98960c4ba5363b598 100644 (file)
@@ -2351,10 +2351,8 @@ int specialix_init(void)
                                                pdev);
                        if (!pdev) break;
 
-                       if (pci_enable_device(pdev)) {
-                               i++;
+                       if (pci_enable_device(pdev))
                                continue;
-                       }
 
                        sx_board[i].irq = pdev->irq;
 
index 9d0cae4ffd797dd25e9647338130bac0f2969609..7ba9779243efe3a037d2a650696510ee36649cd9 100644 (file)
@@ -104,8 +104,7 @@ kd_nosound(unsigned long ignored)
 void
 _kd_mksound(unsigned int hz, unsigned int ticks)
 {
-       static struct timer_list sound_timer = { NULL, NULL, 0, 0,
-                                                kd_nosound };
+       static struct timer_list sound_timer = { function: kd_nosound };
        unsigned int count = 0;
        unsigned long flags;
 
index 712ec750225299aea1aee509ad55ce7d12134941..039c0bfd9fbfa7d34e39d288b97aa085c41b8fcc 100644 (file)
@@ -1256,7 +1256,7 @@ static void ide_do_request (ide_hwgroup_t *hwgroup, int masked_irq)
                                if (0 < (signed long)(jiffies + WAIT_MIN_SLEEP - sleep)) 
                                        sleep = jiffies + WAIT_MIN_SLEEP;
 #if 1
-                               if (hwgroup->timer.next || hwgroup->timer.prev)
+                               if (timer_pending(&hwgroup->timer))
                                        printk("ide_set_handler: timer already active\n");
 #endif
                                hwgroup->sleeping = 1;  /* so that ide_timer_expiry knows what to do */
index 0334b7fe2f12db6eede5de895d38bd561b13cdf6..f6703d089f6732265b23987e9aea6289f94c6c7b 100644 (file)
@@ -917,11 +917,9 @@ static void set_multicast_list(struct net_device *dev)
 
 #ifdef MODULE
 
-static char devicename[9] = { 0, };
-
 static struct net_device dev_3c501 =
 {
-       devicename, /* device name is inserted by linux/drivers/net/net_init.c */
+       "", /* device name is inserted by linux/drivers/net/net_init.c */
        0, 0, 0, 0,
        0x280, 5,
        0, 0, 0, NULL, el1_probe
index a859f9ddc0858fc52f4b1fc62d07e2948c86744c..55de6fd6c737cdbbb9d31bdc49a97257cc55da51 100644 (file)
@@ -621,12 +621,10 @@ el2_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring
 }
 #ifdef MODULE
 #define MAX_EL2_CARDS  4       /* Max number of EL2 cards per module */
-#define NAMELEN        8       /* #of chars for storing dev->name */
 
-static char namelist[NAMELEN * MAX_EL2_CARDS] = { 0, };
 static struct net_device dev_el2[MAX_EL2_CARDS] = {
        {
-               NULL,           /* assign a chunk of namelist[] below */
+               "",
                0, 0, 0, 0,
                0, 0,
                0, 0, 0, NULL, NULL
@@ -649,7 +647,6 @@ init_module(void)
 
        for (this_dev = 0; this_dev < MAX_EL2_CARDS; this_dev++) {
                struct net_device *dev = &dev_el2[this_dev];
-               dev->name = namelist+(NAMELEN*this_dev);
                dev->irq = irq[this_dev];
                dev->base_addr = io[this_dev];
                dev->mem_end = xcvr[this_dev];  /* low 4bits = xcvr sel. */
index b333ad08c6c0e3b173dd5016d9c6019a66d7c2e7..e4b6ed4a099f76228654dbe66582b8160480cc7d 100644 (file)
@@ -1607,11 +1607,9 @@ int __init elplus_probe(struct net_device *dev)
 }
 
 #ifdef MODULE
-#define NAMELEN 9
-static char devicename[ELP_MAX_CARDS][NAMELEN] = {{0,}};
 static struct net_device dev_3c505[ELP_MAX_CARDS] =
 {
-       { NULL,         /* device name is inserted by net_init.c */
+       { "",           /* device name is inserted by net_init.c */
        0, 0, 0, 0,
        0, 0,
        0, 0, 0, NULL, elplus_probe},
@@ -1630,7 +1628,6 @@ int init_module(void)
 
        for (this_dev = 0; this_dev < ELP_MAX_CARDS; this_dev++) {
                struct net_device *dev = &dev_3c505[this_dev];
-               dev->name = devicename[this_dev];
                dev->irq = irq[this_dev];
                dev->base_addr = io[this_dev];
                if (dma[this_dev]) {
index faecb72add96c5de82db074b04fae988200a2c2b..a59d69f5a3dc7633c36c9a72d23b3278ad60ecf7 100644 (file)
@@ -860,9 +860,8 @@ static void el16_rx(struct net_device *dev)
        lp->rx_tail = rx_tail;
 }
 #ifdef MODULE
-static char devicename[9] = { 0, };
 static struct net_device dev_3c507 = {
-       devicename, /* device name is inserted by linux/drivers/net/net_init.c */
+       "", /* device name is inserted by linux/drivers/net/net_init.c */
        0, 0, 0, 0,
        0, 0,
        0, 0, 0, NULL, el16_probe
index f5c8ef1b057434b0260ad3a7bbc6d90015718020..e52d1d4ee9d9a9d56fb7269018a7e521865de04f 100644 (file)
@@ -300,7 +300,6 @@ struct boom_tx_desc {
 };
 
 struct corkscrew_private {
-       char devname[8];        /* "ethN" string, also for kernel debug. */
        const char *product_name;
        struct net_device *next_module;
        /* The Rx and Tx rings are here to keep them quad-word-aligned. */
@@ -564,7 +563,6 @@ static struct net_device *corkscrew_found_device(struct net_device *dev,
        dev->priv =
            (void *) (((long) dev + sizeof(struct net_device) + 15) & ~15);
        vp = (struct corkscrew_private *) dev->priv;
-       dev->name = vp->devname;        /* An empty string. */
        dev->base_addr = ioaddr;
        dev->irq = irq;
        dev->dma =
index 7a14db1ce427aa91ea5745cf042d495495de948b..d22b847a82bf531f5e8fb1eaf27f468bc4b8408e 100644 (file)
@@ -1207,15 +1207,11 @@ static void set_multicast_list(struct net_device *dev)
 
 /* Increase if needed ;) */
 #define MAX_3C523_CARDS 4
-/* I'm not sure where this magic 9 comes from */
-#define NAMELEN 9
-
-static char devicenames[NAMELEN * MAX_3C523_CARDS] = {0,};
 
 static struct net_device dev_elmc[MAX_3C523_CARDS] =
 {      
        {
-       NULL /*"3c523" */ , 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL
+       "", 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL
        },
 };
 
@@ -1232,7 +1228,6 @@ int init_module(void)
        for(this_dev=0; this_dev<MAX_3C523_CARDS; this_dev++) 
                {
                struct net_device *dev = &dev_elmc[this_dev];
-               dev->name=devicenames+(NAMELEN*this_dev);
                dev->irq=irq[this_dev];
                dev->base_addr=io[this_dev];
                dev->init=elmc_probe;
index a44153e311c36256d9a8dd453f017a86b5bdf592..6e391017269414519cc34516e8d46550acbb2bb1 100644 (file)
@@ -1457,9 +1457,8 @@ static void mc32_reset_multicast_list(struct net_device *dev)
 
 #ifdef MODULE
 
-static char devicename[9] = { 0, };
 static struct net_device this_device = {
-       devicename, /* will be inserted by linux/drivers/net/mc32_init.c */
+       "", /* will be inserted by linux/drivers/net/mc32_init.c */
        0, 0, 0, 0,
        0, 0,  /* I/O address, IRQ */
        0, 0, 0, NULL, mc32_probe };
index 6e7842c20383d50679e735ca9c833426977249ef..45603a0c10ce6cbcd2d7484fa4beab0999ca2079 100644 (file)
 
        Linux Kernel Additions:
        
+       0.99H+lk0.9 - David S. Miller - softnet, PCI DMA updates
+       0.99H+lk1.0 - Jeff Garzik <jgarzik@mandrakesoft.com>
+               Remove compatibility defines for kernel versions < 2.2.x.
+               Update for new 2.3.x module interface
        LK1.1.2 (March 19, 2000)
        * New PCI interface (jgarzik)
 
-*/
-
-/*
-    22Apr00, Andrew Morton <andrewm@uow.edu.au>
+    LK1.1.3 25 April 2000, Andrew Morton <andrewm@uow.edu.au>
     - Merged with 3c575_cb.c
     - Don't set RxComplete in boomerang interrupt enable reg
     - spinlock in vortex_timer to protect mdio functions
     - Handle resource allocation failures.
     - Fix 3CCFE575CT LED polarity
     - Make tx_interrupt_mitigation the default
+
+    LK1.1.4 25 April 2000, Andrew Morton <andrewm@uow.edu.au>    
     - Add extra TxReset to vortex_up() to fix 575_cb hotplug initialisation probs.
+    - Put vortex_info_tbl into __devinitdata
+    - In the vortex_error StatsFull HACK, disable stats in vp->intr_enable as well
+      as in the hardware.
+    - Increased the loop counter in wait_for_completion from 2,000 to 4,000.
+
+    LK1.1.5 28 April 2000, andrewm
+    - Added powerpc defines
+    - Some extra diagnostics
+    - In vortex_error(), reset the Tx on maxCollisions.  Otherwise most
+      chips usually get a Tx timeout.
+    - Added extra_reset module parm
+    - Replaced some inline timer manip with mod_timer
+      (Franois romieu <Francois.Romieu@nic.fr>)
+    - In vortex_up(), don't make Wn3_config initialisation dependent upon has_nway
+      (this came across from 3c575_cb).
+
     - See http://www.uow.edu.au/~andrewm/linux/#3c59x-2.3 for more details.
 */
 
@@ -56,9 +75,6 @@
  * elimination of all the tests and reduced cache footprint.
  */
 
-static char *version =
-"3c59x.c:v0.99L+LK1.1.2+AKPM  24 Apr 2000  Donald Becker and others  http://cesdis.gsfc.nasa.gov/linux/drivers/vortex.html\n";
-
 /* "Knobs" that adjust features and parameters. */
 /* Set the copy breakpoint for the copy-only-tiny-frames scheme.
    Setting to > 1512 effectively disables this feature. */
@@ -67,10 +83,15 @@ static const int rx_copybreak = 200;
 static const int mtu = 1500;
 /* Maximum events (Rx packets, etc.) to handle at each interrupt. */
 static int max_interrupt_work = 32;
+/* Give the NIC an extra reset at the end of vortex_up() */
+static int extra_reset = 0;
 
 /* Allow aggregation of Tx interrupts.  Saves CPU load at the cost
  * of possible Tx stalls if the system is blocking interrupts
  * somewhere else.  Undefine this to disable.
+ * AKPM 26 April 2000: enabling this still gets vestigial Tx timeouts
+ * in a heavily loaded (collision-prone) 10BaseT LAN.  Should be OK with
+ * switched Ethernet.
  */
 #define tx_interrupt_mitigation 1
 
@@ -96,8 +117,8 @@ static int rx_nocopy = 0, rx_copy = 0, queued_packet = 0, rx_csumhits;
 #define PKT_BUF_SZ             1536                    /* Size of each temporary Rx buffer.*/
 
 #ifndef __OPTIMIZE__
-#warning  You must compile this file with the correct options!
-#warning  See the last lines of the source file.
+#error You must compile this file with the correct options!
+#error See the last lines of the source file.
 #error You must compile this driver with "-O".
 #endif
 
@@ -120,6 +141,12 @@ static int rx_nocopy = 0, rx_copy = 0, queued_packet = 0, rx_csumhits;
 #include <asm/bitops.h>
 #include <asm/io.h>
 
+/* John Daniel <jdaniel@etresoft.com> said these work... */
+#ifdef __powerpc__
+#define outsl outsl_ns
+#define insl insl_ns
+#endif
+
 /* Kernel compatibility defines, some common to David Hinds' PCMCIA package.
    This is only in the support-all-kernels source code. */
 
@@ -127,6 +154,9 @@ static int rx_nocopy = 0, rx_copy = 0, queued_packet = 0, rx_csumhits;
 
 #include <linux/delay.h>
 
+static char *version __devinitdata =
+"3c59x.c:v0.99L+LK1.1.5  30 Apr 2000  Donald Becker and others  http://cesdis.gsfc.nasa.gov/linux/drivers/vortex.html " "$Revision: 1.78 $\n";
+
 MODULE_AUTHOR("Donald Becker <becker@cesdis.gsfc.nasa.gov>");
 MODULE_DESCRIPTION("3Com 3c59x/3c90x/3c575 series Vortex/Boomerang/Cyclone driver");
 MODULE_PARM(debug, "i");
@@ -134,6 +164,7 @@ MODULE_PARM(options, "1-" __MODULE_STRING(8) "i");
 MODULE_PARM(full_duplex, "1-" __MODULE_STRING(8) "i");
 MODULE_PARM(rx_copybreak, "i");
 MODULE_PARM(max_interrupt_work, "i");
+MODULE_PARM(extra_reset, "i");
 MODULE_PARM(compaq_ioaddr, "i");
 MODULE_PARM(compaq_irq, "i");
 MODULE_PARM(compaq_device_id, "i");
@@ -291,7 +322,7 @@ static struct vortex_chip_info {
        int flags;
        int drv_flags;
        int io_size;
-} vortex_info_tbl[] = {
+} vortex_info_tbl[] __devinitdata = {
        {"3c590 Vortex 10Mbps",
         PCI_USES_IO|PCI_USES_MASTER, IS_VORTEX, 32, },
        {"3c592 EISA 10mbps Demon/Vortex",                                      /* AKPM: from Don's 3c59x_cb.c 0.49H */
@@ -551,8 +582,7 @@ struct vortex_private {
 
        /* PCI configuration space information. */
        struct pci_dev *pdev;
-       char *cb_fn_base;                       /* CardBus function status addr space. */
-       int chip_id;
+       char *cb_fn_base;                                       /* CardBus function status addr space. */
 
        /* The remainder are related to chip state, mostly media selection. */
        struct timer_list timer;                        /* Media selection timer. */
@@ -564,7 +594,9 @@ struct vortex_private {
                full_bus_master_tx:1, full_bus_master_rx:2, /* Boomerang  */
                hw_csums:1,                                             /* Has hardware checksums. */
                tx_full:1,
+               has_nway:1,
                open:1;
+       int tx_reset_resume;                            /* Flag to retart timer after vortex_error handling */
        u16 status_enable;
        u16 intr_enable;
        u16 available_media;                            /* From Wn3_Options. */
@@ -573,6 +605,7 @@ struct vortex_private {
        unsigned char phys[2];                          /* MII device addresses. */
        u16 deferred;                                           /* Resend these interrupts when we
                                                                                 * bale from the ISR */
+       u16 io_size;                                            /* Size of PCI region (for release_region) */
        spinlock_t lock;
 };
 
@@ -620,6 +653,7 @@ static int boomerang_rx(struct net_device *dev);
 static void vortex_interrupt(int irq, void *dev_id, struct pt_regs *regs);
 static void boomerang_interrupt(int irq, void *dev_id, struct pt_regs *regs);
 static int vortex_close(struct net_device *dev);
+static void dump_tx_ring(struct net_device *dev);
 static void update_stats(long ioaddr, struct net_device *dev);
 static struct net_device_stats *vortex_get_stats(struct net_device *dev);
 static void set_rx_mode(struct net_device *dev);
@@ -775,13 +809,15 @@ static int __devinit vortex_probe1(struct pci_dev *pdev,
        dev->base_addr = ioaddr;
        dev->irq = irq;
        dev->mtu = mtu;
+       vp->has_nway = (vortex_info_tbl[chip_idx].drv_flags & HAS_NWAY) ? 1 : 0;
+       vp->io_size = vortex_info_tbl[chip_idx].io_size;
 
        /* module list only for EISA devices */
        if (pdev == NULL) {
                vp->next_module = root_vortex_eisa_dev;
                root_vortex_eisa_dev = dev;
        }
-       
+
        /* PCI-only startup logic */
        if (pdev) {
                /* EISA resources already marked, so only PCI needs to do this here */
@@ -794,9 +830,8 @@ static int __devinit vortex_probe1(struct pci_dev *pdev,
                }
 
                /* wake up and enable device */         
-               if (pci_enable_device (pdev)) {
+               if ((retval = pci_enable_device(pdev))) {
                        printk (KERN_ERR "%s: Cannot enable device, aborting\n", dev->name);
-                       retval = -EIO;
                        goto free_region;
                }
 
@@ -806,7 +841,6 @@ static int __devinit vortex_probe1(struct pci_dev *pdev,
        }
 
        vp->lock = SPIN_LOCK_UNLOCKED;
-       vp->chip_id = chip_idx;
        vp->pdev = pdev;
 
        /* Makes sure rings are at least 16 byte aligned. */
@@ -898,15 +932,15 @@ static int __devinit vortex_probe1(struct pci_dev *pdev,
                           dev->irq);
 #endif
 
-       if (pdev && vortex_info_tbl[vp->chip_id].drv_flags & HAS_CB_FNS) {
+       if (pdev && vortex_info_tbl[chip_idx].drv_flags & HAS_CB_FNS) {
                u32 fn_st_addr;                 /* Cardbus function status space */
                fn_st_addr = pci_resource_start (pdev, 2);
                if (fn_st_addr)
                        vp->cb_fn_base = ioremap(fn_st_addr, 128);
                printk(KERN_INFO "%s: CardBus functions mapped %8.8x->%p\n",
                           dev->name, fn_st_addr, vp->cb_fn_base);
-#if 0 /* AKPM */
-               if (vortex_pci_tbl[vp->chip_id].device != 0x5257) {
+#if 1 /* AKPM: the 575_cb and 905B LEDs seem OK without this */
+               if (vortex_pci_tbl[chip_idx].device != 0x5257) {
                        EL3WINDOW(2);
                        outw(0x10 | inw(ioaddr + Wn2_ResetOptions), ioaddr + Wn2_ResetOptions);
                }
@@ -925,7 +959,7 @@ static int __devinit vortex_probe1(struct pci_dev *pdev,
        }
 
        {
-               static char *ram_split[] = {"5:3", "3:1", "1:1", "3:5"};
+               static const char * ram_split[] = {"5:3", "3:1", "1:1", "3:5"};
                union wn3_config config;
                EL3WINDOW(3);
                vp->available_media = inw(ioaddr + Wn3_Options);
@@ -1010,6 +1044,7 @@ static int __devinit vortex_probe1(struct pci_dev *pdev,
 free_region:
        release_region (ioaddr, vortex_info_tbl[chip_idx].io_size);
 free_dev:
+       unregister_netdev(dev);
        kfree (dev);
        printk(KERN_ERR PFX "vortex_probe1 fails.  Returns %d\n", retval);
 out:
@@ -1018,7 +1053,7 @@ out:
 
 static void wait_for_completion(struct net_device *dev, int cmd)
 {
-       int i = 2000;
+       int i = 4000;
 
        outw(cmd, dev->base_addr + EL3_CMD);
        while (--i > 0)
@@ -1054,7 +1089,7 @@ vortex_up(struct net_device *dev)
                                   media_tbl[vp->media_override].name);
                dev->if_port = vp->media_override;
        } else if (vp->autoselect) {
-               if (vortex_info_tbl[vp->chip_id].drv_flags & HAS_NWAY) {
+               if (vp->has_nway) {
                        printk(KERN_INFO "%s: using NWAY autonegotiation\n", dev->name);
                        dev->if_port = XCVR_NWAY;
                } else {
@@ -1062,7 +1097,7 @@ vortex_up(struct net_device *dev)
                        dev->if_port = XCVR_100baseTx;
                        while (! (vp->available_media & media_tbl[dev->if_port].mask))
                                dev->if_port = media_tbl[dev->if_port].next;
-                       printk(KERN_INFO "%s: first avaialble mdeia type: %s\n",
+                       printk(KERN_INFO "%s: first available media type: %s\n",
                                        dev->name,
                                        media_tbl[dev->if_port].name);
                }
@@ -1084,7 +1119,7 @@ vortex_up(struct net_device *dev)
 
        vp->full_duplex = vp->force_fd;
        config.u.xcvr = dev->if_port;
-       if ( ! (vortex_info_tbl[vp->chip_id].drv_flags & HAS_NWAY))
+//AKPM if (!vp->has_nway)
        {
                if (vortex_debug > 6)
                        printk(KERN_DEBUG "vortex_up(): writing 0x%x to InternalConfig\n",
@@ -1136,6 +1171,7 @@ vortex_up(struct net_device *dev)
                outb(dev->dev_addr[i], ioaddr + i);
        for (; i < 12; i+=2)
                outw(0, ioaddr + i);
+
        if (vp->cb_fn_base) {
                u_short n = inw(ioaddr + Wn2_ResetOptions);
 #if 0  /* AKPM: This is done in vortex_probe1, and seems to be wrong anyway... */
@@ -1180,7 +1216,7 @@ vortex_up(struct net_device *dev)
                /* Initialize the RxEarly register as recommended. */
                outw(SetRxThreshold + (1536>>2), ioaddr + EL3_CMD);
                outl(0x0020, ioaddr + PktStatus);
-               outl(virt_to_bus(&vp->rx_ring[0]), ioaddr + UpListPtr);
+               outl(vp->rx_ring_dma, ioaddr + UpListPtr);
        }
        if (vp->full_bus_master_tx) {           /* Boomerang bus master Tx. */
                dev->hard_start_xmit = &boomerang_start_xmit;
@@ -1218,9 +1254,16 @@ vortex_up(struct net_device *dev)
        if (vp->cb_fn_base)                     /* The PCMCIA people are idiots.  */
                writel(0x8000, vp->cb_fn_base + 4);
 
-       /* AKPM: unjam the 3CCFE575CT */
-       wait_for_completion(dev, TxReset);
-       outw(TxEnable, ioaddr + EL3_CMD);
+       if (extra_reset)
+       {
+               /* AKPM: unjam the 3CCFE575CT */
+               wait_for_completion(dev, TxReset);
+               if (vp->full_bus_master_tx) {
+                       outb(PKT_BUF_SZ>>8, ioaddr + TxFreeThreshold);
+                       outw(DownUnstall, ioaddr + EL3_CMD);
+               }
+               outw(TxEnable, ioaddr + EL3_CMD);
+       }
 }
 
 static int
@@ -1244,7 +1287,7 @@ vortex_open(struct net_device *dev)
                        printk(KERN_DEBUG "%s:  Filling in the Rx ring.\n", dev->name);
                for (i = 0; i < RX_RING_SIZE; i++) {
                        struct sk_buff *skb;
-                       vp->rx_ring[i].next = cpu_to_le32(virt_to_bus(&vp->rx_ring[i+1]));
+                       vp->rx_ring[i].next = cpu_to_le32(vp->rx_ring_dma + sizeof(struct boom_rx_desc) * (i+1));
                        vp->rx_ring[i].status = 0;      /* Clear complete bit. */
                        vp->rx_ring[i].length = cpu_to_le32(PKT_BUF_SZ | LAST_FRAG);
                        skb = dev_alloc_skb(PKT_BUF_SZ);
@@ -1253,10 +1296,10 @@ vortex_open(struct net_device *dev)
                                break;                  /* Bad news!  */
                        skb->dev = dev;                 /* Mark as being used by this device. */
                        skb_reserve(skb, 2);    /* Align IP on 16 byte boundaries */
-                       vp->rx_ring[i].addr = cpu_to_le32(virt_to_bus(skb->tail));
+                       vp->rx_ring[i].addr = cpu_to_le32(pci_map_single(vp->pdev, skb->tail, PKT_BUF_SZ, PCI_DMA_FROMDEVICE));
                }
                /* Wrap the ring. */
-               vp->rx_ring[i-1].next = cpu_to_le32(virt_to_bus(&vp->rx_ring[0]));
+               vp->rx_ring[i-1].next = cpu_to_le32(vp->rx_ring_dma);
        }
 
        vortex_up(dev);
@@ -1294,7 +1337,7 @@ static void vortex_timer(unsigned long data)
                                printk(KERN_DEBUG "%s: Media %s has link beat, %x.\n",
                                           dev->name, media_tbl[dev->if_port].name, media_status);
                } else if (vortex_debug > 1)
-                       printk(KERN_DEBUG "%s: Media %s is has no link beat, %x.\n",
+                       printk(KERN_DEBUG "%s: Media %s has no link beat, %x.\n",
                                   dev->name, media_tbl[dev->if_port].name, media_status);
                break;
        case XCVR_MII: case XCVR_NWAY:
@@ -1323,6 +1366,9 @@ static void vortex_timer(unsigned long data)
                                                outb((vp->full_duplex ? 0x20 : 0) |
                                                        (dev->mtu > 1500 ? 0x40 : 0),
                                                        ioaddr + Wn3_MAC_Ctrl);
+                                               if (vortex_debug > 1)
+                                                       printk(KERN_DEBUG "Setting duplex in Wn3_MAC_Ctrl\n");
+                                               /* AKPM: bug: should reset Tx and Rx after setting Duplex.  Page 180 */
                                        }
                                        next_tick = 60*HZ;
                                }
@@ -1365,6 +1411,9 @@ static void vortex_timer(unsigned long data)
 
                outw(dev->if_port == XCVR_10base2 ? StartCoax : StopCoax,
                         ioaddr + EL3_CMD);
+               if (vortex_debug > 1)
+                       printk(KERN_DEBUG "wrote 0x%08x to Wn3_Config\n", config.i);
+               /* AKPM: FIXME: Should reset Rx & Tx here.  P60 of 3c90xc.pdf */
        }
        EL3WINDOW(old_window);
        enable_irq(dev->irq);
@@ -1411,23 +1460,8 @@ static void vortex_tx_timeout(struct net_device *dev)
                }
        }
 
-       if (vortex_debug > 0) {
-               if (vp->full_bus_master_tx) {
-                       int i;
-                       printk(KERN_DEBUG "  Flags; bus-master %d, full %d; dirty %d "
-                                  "current %d.\n",
-                                  vp->full_bus_master_tx, vp->tx_full, vp->dirty_tx, vp->cur_tx);
-                       printk(KERN_DEBUG "  Transmit list %8.8x vs. %p.\n",
-                                  inl(ioaddr + DownListPtr),
-                                  &vp->tx_ring[vp->dirty_tx % TX_RING_SIZE]);
-                       for (i = 0; i < TX_RING_SIZE; i++) {
-                               printk(KERN_DEBUG "  %d: @%p  length %8.8x status %8.8x\n", i,
-                                          &vp->tx_ring[i],
-                                          le32_to_cpu(vp->tx_ring[i].length),
-                                          le32_to_cpu(vp->tx_ring[i].status));
-                       }
-               }
-       }
+       if (vortex_debug > 1)
+               dump_tx_ring(dev);
 
        wait_for_completion(dev, TxReset);
 
@@ -1441,7 +1475,7 @@ static void vortex_tx_timeout(struct net_device *dev)
                                 ioaddr + DownListPtr);
                if (vp->tx_full && (vp->cur_tx - vp->dirty_tx <= TX_RING_SIZE - 1)) {
                        vp->tx_full = 0;
-                       netif_start_queue (dev);
+                       netif_wake_queue (dev);
                }
                if (vp->tx_full)
                        netif_stop_queue (dev);
@@ -1468,25 +1502,30 @@ vortex_error(struct net_device *dev, int status)
        struct vortex_private *vp = (struct vortex_private *)dev->priv;
        long ioaddr = dev->base_addr;
        int do_tx_reset = 0;
+       unsigned char tx_status = 0;
 
-       if (vortex_debug > 2)
+       if (vortex_debug > 2) {
                printk(KERN_DEBUG "%s: vortex_error(), status=0x%x\n", dev->name, status);
+       }
 
        if (status & TxComplete) {                      /* Really "TxError" for us. */
-               unsigned char tx_status = inb(ioaddr + TxStatus);
+               tx_status = inb(ioaddr + TxStatus);
                /* Presumably a tx-timeout. We must merely re-enable. */
                if (vortex_debug > 2
-                       || (tx_status != 0x88 && vortex_debug > 0))
+                       || (tx_status != 0x88 && vortex_debug > 0)) {
                        printk(KERN_DEBUG"%s: Transmit error, Tx status register %2.2x.\n",
                                   dev->name, tx_status);
+                       dump_tx_ring(dev);
+               }
                if (tx_status & 0x14)  vp->stats.tx_fifo_errors++;
                if (tx_status & 0x38)  vp->stats.tx_aborted_errors++;
                outb(0, ioaddr + TxStatus);
-               if (tx_status & 0x30)
+               if (tx_status & 0x38)   /* AKPM: tx reset after 16 collisions, despite what the manual says */
                        do_tx_reset = 1;
                else                                    /* Merely re-enable the transmitter. */
                        outw(TxEnable, ioaddr + EL3_CMD);
        }
+
        if (status & RxEarly) {                         /* Rx early is unused. */
                vortex_rx(dev);
                outw(AckIntr | RxEarly, ioaddr + EL3_CMD);
@@ -1504,6 +1543,7 @@ vortex_error(struct net_device *dev, int status)
                                   "stats as an interrupt source.\n", dev->name);
                        EL3WINDOW(5);
                        outw(SetIntrEnb | (inw(ioaddr + 10) & ~StatsFull), ioaddr + EL3_CMD);
+                       vp->intr_enable &= ~StatsFull;
                        EL3WINDOW(7);
                        DoneDidThat++;
                }
@@ -1534,11 +1574,41 @@ vortex_error(struct net_device *dev, int status)
                        outw(AckIntr | HostError, ioaddr + EL3_CMD);
                }
        }
+
+       /*
+        * Black magic.  If we're resetting the transmitter,  remember the current downlist
+        * pointer and restore it afterwards.  We can't usr cur_tx because that could
+        * lag the actual hardware index.
+        */
        if (do_tx_reset) {
-               wait_for_completion(dev, TxReset);
-               outw(TxEnable, ioaddr + EL3_CMD);
-       }
+               if (vp->full_bus_master_tx) {
+                       unsigned long old_down_list_ptr;
+
+                       wait_for_completion(dev, DownStall);
+                       old_down_list_ptr = inl(ioaddr + DownListPtr);
+                       wait_for_completion(dev, TxReset);
+                       outw(TxEnable, ioaddr + EL3_CMD);
+
+                       /* Restart DMA if necessary */
+                       outl(old_down_list_ptr, ioaddr + DownListPtr);
+                       if (vortex_debug > 2)
+                                       printk(KERN_DEBUG "reset DMA to 0x%08x\n", inl(ioaddr + DownListPtr));
+                       outw(DownUnstall, ioaddr + EL3_CMD);
 
+                       /*
+                        * Here we make a single attempt to prevent a timeout by
+                        * restarting the timer if we think that the ISR has a good
+                        * chance of unjamming things.
+                        */
+                       if (vp->tx_reset_resume == 0 && vp->tx_full) {
+                               vp->tx_reset_resume = 1;
+                               dev->trans_start = jiffies;
+                       }
+               } else {
+                       wait_for_completion(dev, TxReset);
+                       outw(TxEnable, ioaddr + EL3_CMD);
+               }
+       }
 }
 
 static int
@@ -1547,8 +1617,6 @@ vortex_start_xmit(struct sk_buff *skb, struct net_device *dev)
        struct vortex_private *vp = (struct vortex_private *)dev->priv;
        long ioaddr = dev->base_addr;
 
-       netif_stop_queue (dev);
-       
        /* Put out the doubleword header... */
        outl(skb->len, ioaddr + TX_FIFO);
        if (vp->bus_master) {
@@ -1559,16 +1627,18 @@ vortex_start_xmit(struct sk_buff *skb, struct net_device *dev)
                outw(len, ioaddr + Wn7_MasterLen);
                vp->tx_skb = skb;
                outw(StartDMADown, ioaddr + EL3_CMD);
-               /* dev->tbusy will be cleared at the DMADone interrupt. */
+               /* netif_wake_queue() will be called at the DMADone interrupt. */
        } else {
                /* ... and the packet rounded to a doubleword. */
                outsl(ioaddr + TX_FIFO, skb->data, (skb->len + 3) >> 2);
                dev_kfree_skb (skb);
                if (inw(ioaddr + TxFree) > 1536) {
-                       netif_start_queue (dev);
-               } else
+                       netif_start_queue (dev);        /* AKPM: redundant? */
+               } else {
                        /* Interrupt us when the FIFO has room for max-sized packet. */
+                       netif_stop_queue(dev);
                        outw(SetTxThreshold + (1536>>2), ioaddr + EL3_CMD);
+               }
        }
 
        dev->trans_start = jiffies;
@@ -1601,57 +1671,53 @@ boomerang_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
        struct vortex_private *vp = (struct vortex_private *)dev->priv;
        long ioaddr = dev->base_addr;
+       /* Calculate the next Tx descriptor entry. */
+       int entry = vp->cur_tx % TX_RING_SIZE;
+       struct boom_tx_desc *prev_entry = &vp->tx_ring[(vp->cur_tx-1) % TX_RING_SIZE];
+       unsigned long flags;
 
        if (vortex_debug > 6)
                printk(KERN_DEBUG "boomerang_start_xmit()\n");
 
-       netif_stop_queue (dev);
-       {
-               /* Calculate the next Tx descriptor entry. */
-               int entry = vp->cur_tx % TX_RING_SIZE;
-               struct boom_tx_desc *prev_entry =
-                       &vp->tx_ring[(vp->cur_tx-1) % TX_RING_SIZE];
-               unsigned long flags;
-
-               if (vortex_debug > 3)
-                       printk(KERN_DEBUG "%s: Trying to send a packet, Tx index %d.\n",
-                                  dev->name, vp->cur_tx);
-               if (vp->tx_full) {
-                       if (vortex_debug > 0)
-                               printk(KERN_WARNING "%s: Tx Ring full, refusing to send buffer.\n",
-                                          dev->name);
-                       return 1;
-               }
-               vp->tx_skbuff[entry] = skb;
-               vp->tx_ring[entry].next = 0;
-               vp->tx_ring[entry].addr = cpu_to_le32(pci_map_single(vp->pdev, skb->data, skb->len, PCI_DMA_TODEVICE));
-               vp->tx_ring[entry].length = cpu_to_le32(skb->len | LAST_FRAG);
-               vp->tx_ring[entry].status = cpu_to_le32(skb->len | TxIntrUploaded);
-
-               spin_lock_irqsave(&vp->lock, flags);
-               /* Wait for the stall to complete. */
-               wait_for_completion(dev, DownStall);
-               prev_entry->next = cpu_to_le32(vp->tx_ring_dma + entry * sizeof(struct boom_tx_desc));
-               if (inl(ioaddr + DownListPtr) == 0) {
-                       outl(vp->tx_ring_dma + entry * sizeof(struct boom_tx_desc), ioaddr + DownListPtr);
-                       queued_packet++;
-               }
+       if (vortex_debug > 3)
+               printk(KERN_DEBUG "%s: Trying to send a packet, Tx index %d.\n",
+                          dev->name, vp->cur_tx);
+       if (vp->tx_full) {
+               if (vortex_debug > 0)
+                       printk(KERN_WARNING "%s: Tx Ring full, refusing to send buffer.\n",
+                                  dev->name);
+               return 1;
+       }
+       vp->tx_skbuff[entry] = skb;
+       vp->tx_ring[entry].next = 0;
+       vp->tx_ring[entry].addr = cpu_to_le32(pci_map_single(vp->pdev, skb->data, skb->len, PCI_DMA_TODEVICE));
+       vp->tx_ring[entry].length = cpu_to_le32(skb->len | LAST_FRAG);
+       vp->tx_ring[entry].status = cpu_to_le32(skb->len | TxIntrUploaded);
 
-               vp->cur_tx++;
-               if (vp->cur_tx - vp->dirty_tx > TX_RING_SIZE - 1) {
-                       vp->tx_full = 1;
-                       netif_stop_queue (dev);
-               } else {                                        /* Clear previous interrupt enable. */
+       spin_lock_irqsave(&vp->lock, flags);
+       /* Wait for the stall to complete. */
+       wait_for_completion(dev, DownStall);
+       prev_entry->next = cpu_to_le32(vp->tx_ring_dma + entry * sizeof(struct boom_tx_desc));
+       if (inl(ioaddr + DownListPtr) == 0) {
+               outl(vp->tx_ring_dma + entry * sizeof(struct boom_tx_desc), ioaddr + DownListPtr);
+               queued_packet++;
+       }
+
+       vp->cur_tx++;
+       if (vp->cur_tx - vp->dirty_tx > TX_RING_SIZE - 1) {
+               vp->tx_full = 1;
+               netif_stop_queue (dev);
+       } else {                                        /* Clear previous interrupt enable. */
 #if defined(tx_interrupt_mitigation)
-                       prev_entry->status &= cpu_to_le32(~TxIntrUploaded);
+               prev_entry->status &= cpu_to_le32(~TxIntrUploaded);
 #endif
-                       netif_start_queue (dev);
-               }
-               outw(DownUnstall, ioaddr + EL3_CMD);
-               spin_unlock_irqrestore(&vp->lock, flags);
-               dev->trans_start = jiffies;
-               return 0;
+               /* netif_start_queue (dev); */          /* AKPM: redundant? */
        }
+       outw(DownUnstall, ioaddr + EL3_CMD);
+       vp->tx_reset_resume = 0;
+       spin_unlock_irqrestore(&vp->lock, flags);
+       dev->trans_start = jiffies;
+       return 0;
 }
 
 /* The interrupt handler does all of the Rx thread work and cleans up
@@ -1667,17 +1733,16 @@ static void vortex_interrupt(int irq, void *dev_id, struct pt_regs *regs)
        struct net_device *dev = dev_id;
        struct vortex_private *vp = (struct vortex_private *)dev->priv;
        long ioaddr;
-       int latency, status;
+       int status;
        int work_done = max_interrupt_work;
 
        spin_lock(&vp->lock);
        
        ioaddr = dev->base_addr;
-       latency = inb(ioaddr + Timer);
        status = inw(ioaddr + EL3_STATUS);
 
        if (vortex_debug > 6)
-               printk("AKPM: vortex_interrupt. status=0x%4x\n", status);
+               printk("vortex_interrupt(). status=0x%4x\n", status);
 
        if (status & IntReq) {
                status |= vp->deferred;
@@ -1689,7 +1754,7 @@ static void vortex_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 
        if (vortex_debug > 4)
                printk(KERN_DEBUG "%s: interrupt, status %4.4x, latency %d ticks.\n",
-                          dev->name, status, latency);
+                          dev->name, status, inb(ioaddr + Timer));
        do {
                if (vortex_debug > 5)
                                printk(KERN_DEBUG "%s: In interrupt loop, status %4.4x.\n",
@@ -1709,12 +1774,17 @@ static void vortex_interrupt(int irq, void *dev_id, struct pt_regs *regs)
                        if (inw(ioaddr + Wn7_MasterStatus) & 0x1000) {
                                outw(0x1000, ioaddr + Wn7_MasterStatus); /* Ack the event. */
                                pci_unmap_single(vp->pdev, vp->tx_skb_dma, (vp->tx_skb->len + 3) & ~3, PCI_DMA_TODEVICE);
-                               dev_kfree_skb_irq(vp->tx_skb); /* Release the transfered buffer */
+                               dev_kfree_skb_irq(vp->tx_skb); /* Release the transferred buffer */
                                if (inw(ioaddr + TxFree) > 1536) {
-                                       netif_wake_queue (dev);
+                                       /*
+                                        * AKPM: FIXME: I don't think we need this.  If the queue was stopped due to
+                                        * insufficient FIFO room, the TxAvailable test will succeed and call
+                                        * netif_wake_queue()
+                                        */
+                                       netif_wake_queue(dev);
                                } else { /* Interrupt when FIFO has room for max-sized packet. */
                                        outw(SetTxThreshold + (1536>>2), ioaddr + EL3_CMD);
-                                       netif_stop_queue (dev);         /* AKPM: This is new */
+                                       netif_stop_queue(dev);          /* AKPM: This is new */
                                }
                        }
                }
@@ -1736,7 +1806,7 @@ static void vortex_interrupt(int irq, void *dev_id, struct pt_regs *regs)
                                outw(AckIntr | (vp->deferred & 0x7ff), ioaddr + EL3_CMD);
                        } while ((status = inw(ioaddr + EL3_CMD)) & IntLatch);
                        /* The timer will reenable interrupts. */
-                       mod_timer(&vp->timer, jiffies+1*HZ);
+                       mod_timer(&vp->timer, jiffies + 1*HZ);
                        break;
                }
                /* Acknowledge the IRQ. */
@@ -1763,33 +1833,31 @@ static void boomerang_interrupt(int irq, void *dev_id, struct pt_regs *regs)
        struct net_device *dev = dev_id;
        struct vortex_private *vp = (struct vortex_private *)dev->priv;
        long ioaddr;
-       int latency, status;
+       int status;
        int work_done = max_interrupt_work;
 
        spin_lock(&vp->lock);
        
        ioaddr = dev->base_addr;
-       latency = inb(ioaddr + Timer);
        status = inw(ioaddr + EL3_STATUS);
 
        if (vortex_debug > 6)
                printk(KERN_DEBUG "boomerang_interrupt. status=0x%4x\n", status);
 
-       if (status & IntReq) {
-               status |= vp->deferred;
-               vp->deferred = 0;
-       }
-
-       if (status == 0xffff)           /* AKPM: h/w no longer present (hotplug)? */
-       {
+       if (status == 0xffff) {         /* AKPM: h/w no longer present (hotplug)? */
                if (vortex_debug > 1)
                        printk(KERN_DEBUG "boomerang_interrupt(1): status = 0xffff\n");
                goto handler_exit;
        }
 
+       if (status & IntReq) {
+               status |= vp->deferred;
+               vp->deferred = 0;
+       }
+
        if (vortex_debug > 4)
                printk(KERN_DEBUG "%s: interrupt, status %4.4x, latency %d ticks.\n",
-                          dev->name, status, latency);
+                          dev->name, status, inb(ioaddr + Timer));
        do {
                if (vortex_debug > 5)
                                printk(KERN_DEBUG "%s: In interrupt loop, status %4.4x.\n",
@@ -1835,11 +1903,8 @@ static void boomerang_interrupt(int irq, void *dev_id, struct pt_regs *regs)
                        netif_stop_queue (dev);
 
                /* Check for all uncommon interrupts at once. */
-               if (status & (HostError | RxEarly | StatsFull | TxComplete | IntReq)) {
-                       if (status == 0xffff)
-                               break;
+               if (status & (HostError | RxEarly | StatsFull | TxComplete | IntReq))
                        vortex_error(dev, status);
-               }
 
                if (--work_done < 0) {
                        printk(KERN_WARNING "%s: Too much work in interrupt, status "
@@ -1852,7 +1917,7 @@ static void boomerang_interrupt(int irq, void *dev_id, struct pt_regs *regs)
                                outw(AckIntr | (vp->deferred & 0x7ff), ioaddr + EL3_CMD);
                        } while ((status = inw(ioaddr + EL3_CMD)) & IntLatch);
                        /* The timer will reenable interrupts. */
-                       mod_timer(&vp->timer, jiffies+1*HZ);
+                       mod_timer(&vp->timer, jiffies + 1*HZ);
                        break;
                }
                /* Acknowledge the IRQ. */
@@ -1948,9 +2013,8 @@ boomerang_rx(struct net_device *dev)
        int rx_work_limit = vp->dirty_rx + RX_RING_SIZE - vp->cur_rx;
 
        if (vortex_debug > 5)
-               printk(KERN_DEBUG "boomerang_rx(): status %4.4x, rx_status "
-                          "%4.4x.\n",
-                          inw(ioaddr+EL3_STATUS), inw(ioaddr+RxStatus));
+               printk(KERN_DEBUG "boomerang_rx(): status %4.4x\n", inw(ioaddr+EL3_STATUS));
+
        while ((rx_status = le32_to_cpu(vp->rx_ring[entry].status)) & RxDComplete){
                if (--rx_work_limit < 0)
                        break;
@@ -2108,6 +2172,38 @@ vortex_close(struct net_device *dev)
        return 0;
 }
 
+static void
+dump_tx_ring(struct net_device *dev)
+{
+       if (vortex_debug > 0) {
+               struct vortex_private *vp = (struct vortex_private *)dev->priv;
+               long ioaddr = dev->base_addr;
+               
+               if (vp->full_bus_master_tx) {
+                       int i;
+                       int stalled = inl(ioaddr + PktStatus) & 0x04;   /* Possible racy. But it's only debug stuff */
+
+                       wait_for_completion(dev, DownStall);
+                       printk(KERN_DEBUG "  Flags; bus-master %d, full %d; dirty %d(%d) "
+                                       "current %d(%d).\n",
+                                       vp->full_bus_master_tx, vp->tx_full,
+                                       vp->dirty_tx, vp->dirty_tx % TX_RING_SIZE,
+                                       vp->cur_tx, vp->cur_tx % TX_RING_SIZE);
+                       printk(KERN_DEBUG "  Transmit list %8.8x vs. %p.\n",
+                                  inl(ioaddr + DownListPtr),
+                                  &vp->tx_ring[vp->dirty_tx % TX_RING_SIZE]);
+                       for (i = 0; i < TX_RING_SIZE; i++) {
+                               printk(KERN_DEBUG "  %d: @%p  length %8.8x status %8.8x\n", i,
+                                          &vp->tx_ring[i],
+                                          le32_to_cpu(vp->tx_ring[i].length),
+                                          le32_to_cpu(vp->tx_ring[i].status));
+                       }
+                       if (!stalled)
+                               outw(DownUnstall, ioaddr + EL3_CMD);
+               }
+       }
+}
+
 static struct net_device_stats *vortex_get_stats(struct net_device *dev)
 {
        struct vortex_private *vp = (struct vortex_private *)dev->priv;
@@ -2344,15 +2440,21 @@ static void __devexit vortex_remove_one (struct pci_dev *pdev)
        struct net_device *dev = pdev->driver_data;
        struct vortex_private *vp;
 
-       if (!dev)
-               return;
+       if (!dev) {
+               printk("vortex_remove_one called for EISA device!\n");
+               BUG();
+       }
 
        vp = (void *)(dev->priv);
 
        /* No need to check MOD_IN_USE, as sys_delete_module() checks. */
+       /* AKPM: FIXME: we should have
+        *      if (vp->cb_fn_base) iounmap(vp->cb_fn_base);
+        * here
+        */
        unregister_netdev(dev);
        outw(TotalReset, dev->base_addr + EL3_CMD);
-       release_region(dev->base_addr, vortex_info_tbl[vp->chip_id].io_size);
+       release_region(dev->base_addr, vp->io_size);
        kfree(dev);
 }
 
index 44c6726a8d95c7433cf81efb4ebcc616ceff4f9c..7fa0bb8e19c350aa5988f008b03075d071bc4a22 100644 (file)
@@ -1494,11 +1494,9 @@ struct netdev_entry i596_drv =
 #endif
 
 #ifdef MODULE
-static char devicename[9] =
-{0,};
 static struct net_device dev_82596 =
 {
-       devicename,     /* device name inserted by drivers/net/net_init.c */
+       "",     /* device name inserted by drivers/net/net_init.c */
        0, 0, 0, 0,
        0, 0,           /* base, irq */
        0, 0, 0, NULL, i82596_probe};
index c20ee80a1fc30f9656e5d38c6005783f72bf6300..e86be3824f2e1fe21af4accc4ebc20d414d4d030 100644 (file)
@@ -344,11 +344,9 @@ static int ac_close_card(struct net_device *dev)
 
 #ifdef MODULE
 #define MAX_AC32_CARDS 4       /* Max number of AC32 cards per module */
-#define NAMELEN                8       /* # of chars for storing dev->name */
-static char namelist[NAMELEN * MAX_AC32_CARDS] = { 0, };
 static struct net_device dev_ac32[MAX_AC32_CARDS] = {
        {
-               NULL,           /* assign a chunk of namelist[] below */
+               "",
                0, 0, 0, 0,
                0, 0,
                0, 0, 0, NULL, NULL
@@ -369,7 +367,6 @@ init_module(void)
 
        for (this_dev = 0; this_dev < MAX_AC32_CARDS; this_dev++) {
                struct net_device *dev = &dev_ac32[this_dev];
-               dev->name = namelist+(NAMELEN*this_dev);
                dev->irq = irq[this_dev];
                dev->base_addr = io[this_dev];
                dev->mem_start = mem[this_dev];         /* Currently ignored by driver */
index 466705f9edac1bc61c16e20a92c51d3cc9376490..76cbf0f896602d4e016e38b6d3524c7e5a6a0e2e 100644 (file)
@@ -1008,11 +1008,9 @@ static struct net_device_stats *cops_get_stats(struct net_device *dev)
 }
 
 #ifdef MODULE
-static char lt_name[16];
-
 static struct net_device cops0_dev =
 {
-       lt_name,        /* device name */
+       "",     /* device name */
         0, 0, 0, 0,
         0x0, 0,  /* I/O address, IRQ */
         0, 0, 0, NULL, cops_probe
index da5afb2ad38306cfd4298cf7a4ef1e8a8fdf34a2..ee1c90c0270b41eaac3332688e022db92e4495e4 100644 (file)
@@ -1272,10 +1272,8 @@ __setup("ltpc=", ltpc_setup);
 
 #ifdef MODULE
 
-static char dev_name[8];
-
 static struct net_device dev_ltpc = {
-               dev_name
+               ""
                0, 0, 0, 0,
                0x0, 0,
                0, 0, 0, NULL, ltpc_probe };
index 0829bd82ef56da1039e7e2f677703dff9d25bd28..02331da249719b4893cb0c46acfbf7844bf869e2 100644 (file)
@@ -163,6 +163,7 @@ static int __init arcrimi_found(struct net_device *dev)
                BUGMSG(D_NORMAL, "Can't allocate device data!\n");
                goto err_free_irq;
        }
+       lp->card_name = "RIM I";
        lp->hw.command = arcrimi_command;
        lp->hw.status = arcrimi_status;
        lp->hw.intmask = arcrimi_setmask;
index 789123124363b428993905a1afe3ca38057411dd..5bfa64f956f1aa9bb9c1ce6d99802bbd757e00d2 100644 (file)
@@ -41,7 +41,7 @@
  *     <jojo@repas.de>
  */
 
-#define VERSION "arcnet: v3.92 BETA 2000/02/13 - by Avery Pennarun et al.\n"
+#define VERSION "arcnet: v3.93 BETA 2000/04/29 - by Avery Pennarun et al.\n"
 
 #include <linux/module.h>
 #include <linux/config.h>
@@ -584,6 +584,8 @@ static int arcnet_send_packet(struct sk_buff *skb, struct net_device *dev)
        soft = &pkt->soft.rfc1201;
        proto = arc_proto_map[soft->proto];
 
+       BUGMSG(D_SKB_SIZE, "skb: transmitting %d bytes to %02X\n",
+               skb->len, pkt->hard.dest);
        BUGLVL(D_SKB) arcnet_dump_skb(dev, skb, "tx");
 
        /* fits in one packet? */
index 7bd06e2e48c7a6319e2e50f592dc3b6082eaac72..7f8a022bf6268d1e17ef2acd50f0f22d47e5b185 100644 (file)
@@ -52,6 +52,7 @@ static int __init com20020isa_probe(struct net_device *dev)
 {
        int ioaddr;
        unsigned long airqmask;
+       struct arcnet_local *lp = dev->priv;
 
 #ifndef MODULE
        arcnet_init();
@@ -103,6 +104,8 @@ static int __init com20020isa_probe(struct net_device *dev)
                        }
                }
        }
+
+       lp->card_name = "ISA COM20020";
        return com20020_found(dev, 0);
 }
 
@@ -119,7 +122,8 @@ static int irq = 0;         /* or use the insmod io= irq= shmem= options */
 static char *device;           /* use eg. device="arc1" to change name */
 static int timeout = 3;
 static int backplane = 0;
-static int clock = 0;
+static int clockp = 0;
+static int clockm = 0;
 
 MODULE_PARM(node, "i");
 MODULE_PARM(io, "i");
@@ -127,7 +131,8 @@ MODULE_PARM(irq, "i");
 MODULE_PARM(device, "s");
 MODULE_PARM(timeout, "i");
 MODULE_PARM(backplane, "i");
-MODULE_PARM(clock, "i");
+MODULE_PARM(clockp, "i");
+MODULE_PARM(clockm, "i");
 
 static void com20020isa_open_close(struct net_device *dev, bool open)
 {
@@ -155,7 +160,8 @@ int init_module(void)
                dev->dev_addr[0] = node;
 
        lp->backplane = backplane;
-       lp->clock = clock & 7;
+       lp->clockp = clockp & 7;
+       lp->clockm = clockm & 3;
        lp->timeout = timeout & 3;
        lp->hw.open_close_ll = com20020isa_open_close;
 
@@ -174,13 +180,7 @@ int init_module(void)
 
 void cleanup_module(void)
 {
-       struct net_device *dev = my_dev;
-
-       unregister_netdev(dev);
-       free_irq(dev->irq, dev);
-       release_region(dev->base_addr, ARCNET_TOTAL_SIZE);
-       kfree(dev->priv);
-       kfree(dev);
+       com20020_remove(my_dev);
 }
 
 #else
index b88203f543b1d53564dc7b40a833d093e901c639..f468f38292e39ae83c00d84b59a3d765eb04798b 100644 (file)
 
 #define VERSION "arcnet: COM20020 PCI support\n"
 
-#ifdef MODULE
-#define MAX_CARDS      16
-static struct net_device *cards[MAX_CARDS];
-static int numcards;
-#endif
+/* Module parameters */
+
+static int node = 0;
+static char *device;           /* use eg. device="arc1" to change name */
+static int timeout = 3;
+static int backplane = 0;
+static int clockp = 0;
+static int clockm = 0;
+
+MODULE_PARM(node, "i");
+MODULE_PARM(device, "s");
+MODULE_PARM(timeout, "i");
+MODULE_PARM(backplane, "i");
+MODULE_PARM(clockp, "i");
+MODULE_PARM(clockm, "i");
 
 static void com20020pci_open_close(struct net_device *dev, bool open)
 {
@@ -56,111 +66,99 @@ static void com20020pci_open_close(struct net_device *dev, bool open)
                MOD_DEC_USE_COUNT;
 }
 
-/*
- * No need to probe for PCI cards - just ask the PCI layer and launch all the
- * ones we find.
- */
-static int __init com20020pci_probe(char *name_template, int node, int backplane, int clock, int timeout)
+static int __devinit com20020pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 {
        struct net_device *dev;
        struct arcnet_local *lp;
-       struct pci_dev *pdev = NULL;
-       int ioaddr, gotone = 0, err;
-
-       BUGLVL(D_NORMAL) printk(VERSION);
-
-       while ((pdev = pci_find_device(0x1571, 0xa004, pdev))) {
-               if (pci_enable_device(pdev))
-                       continue;
-               dev = dev_alloc(name_template ? : "arc%d", &err);
-               if (!dev)
-                       return err;
-               lp = dev->priv = kmalloc(sizeof(struct arcnet_local), GFP_KERNEL);
-               if (!lp)
-                       return -ENOMEM;
-               memset(lp, 0, sizeof(struct arcnet_local));
-
-               ioaddr = pdev->resource[2].start;
-               dev->base_addr = ioaddr;
-               dev->irq = pdev->irq;
-               dev->dev_addr[0] = node;
-               lp->backplane = backplane;
-               lp->clock = clock;
-               lp->timeout = timeout;
-               lp->hw.open_close_ll = com20020pci_open_close;
-
-               BUGMSG(D_INIT, "PCI BIOS reports a device at %Xh, IRQ %d\n",
-                      ioaddr, dev->irq);
-
-               if (check_region(ioaddr, ARCNET_TOTAL_SIZE)) {
-                       BUGMSG(D_INIT, "IO region %xh-%xh already allocated.\n",
-                              ioaddr, ioaddr + ARCNET_TOTAL_SIZE - 1);
-                       continue;
-               }
-               if (ASTATUS() == 0xFF) {
-                       BUGMSG(D_NORMAL, "IO address %Xh was reported by PCI BIOS, "
-                              "but seems empty!\n", ioaddr);
-                       continue;
-               }
-               if (com20020_check(dev))
-                       continue;
-
-               if (!com20020_found(dev, SA_SHIRQ)) {
-#ifdef MODULE
-                       if(numcards==MAX_CARDS)
-                               printk(KERN_WARNING "com20020pci: Too many cards. Ignoring.\n");
-                       else
-                               cards[numcards++] = dev;
-#endif
-                       gotone++;
-               }
+       int ioaddr, err;
+
+       if (pci_enable_device(pdev))
+               return -EIO;
+       dev = dev_alloc(device ? : "arc%d", &err);
+       if (!dev)
+               return err;
+       lp = dev->priv = kmalloc(sizeof(struct arcnet_local), GFP_KERNEL);
+       if (!lp)
+               return -ENOMEM;
+       memset(lp, 0, sizeof(struct arcnet_local));
+       pdev->driver_data = dev;
+
+       ioaddr = pci_resource_start(pdev, 2);
+       dev->base_addr = ioaddr;
+       dev->irq = pdev->irq;
+       dev->dev_addr[0] = node;
+       lp->card_name = pdev->name;
+       lp->card_flags = id->driver_data;
+       lp->backplane = backplane;
+       lp->clockp = clockp & 7;
+       lp->clockm = clockm & 3;
+       lp->timeout = timeout;
+       lp->hw.open_close_ll = com20020pci_open_close;
+
+       if (check_region(ioaddr, ARCNET_TOTAL_SIZE)) {
+               BUGMSG(D_INIT, "IO region %xh-%xh already allocated.\n",
+                      ioaddr, ioaddr + ARCNET_TOTAL_SIZE - 1);
+               return -EBUSY;
+       }
+       if (ASTATUS() == 0xFF) {
+               BUGMSG(D_NORMAL, "IO address %Xh was reported by PCI BIOS, "
+                      "but seems empty!\n", ioaddr);
+               return -EIO;
        }
+       if (com20020_check(dev))
+               return -EIO;
 
-       return gotone ? 0 : -ENODEV;
+       return com20020_found(dev, SA_SHIRQ);
 }
 
-
-#ifdef MODULE
-
-/* Module parameters */
-
-static int node = 0;
-static char *device;           /* use eg. device="arc1" to change name */
-static int timeout = 3;
-static int backplane = 0;
-static int clock = 0;
-
-MODULE_PARM(node, "i");
-MODULE_PARM(device, "s");
-MODULE_PARM(timeout, "i");
-MODULE_PARM(backplane, "i");
-MODULE_PARM(clock, "i");
-
-int init_module(void)
+static void __devexit com20020pci_remove(struct pci_dev *pdev)
 {
-       return com20020pci_probe(device, node, backplane, clock & 7, timeout & 3);
+       com20020_remove(pdev->driver_data);
 }
 
-void cleanup_module(void)
+static struct pci_device_id com20020pci_id_table[] __devinitdata = {
+       { 0x1571, 0xa001, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
+       { 0x1571, 0xa002, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
+       { 0x1571, 0xa003, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
+       { 0x1571, 0xa004, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
+       { 0x1571, 0xa005, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
+       { 0x1571, 0xa006, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
+       { 0x1571, 0xa007, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
+       { 0x1571, 0xa008, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
+       { 0x1571, 0xa009, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ARC_IS_5MBIT },
+       { 0x1571, 0xa00a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ARC_IS_5MBIT },
+       { 0x1571, 0xa00b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ARC_IS_5MBIT },
+       { 0x1571, 0xa00c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ARC_IS_5MBIT },
+       { 0x1571, 0xa00d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ARC_IS_5MBIT },
+       { 0x1571, 0xa201, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ARC_CAN_10MBIT },
+       { 0x1571, 0xa202, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ARC_CAN_10MBIT },
+       { 0x1571, 0xa203, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ARC_CAN_10MBIT },
+       { 0x1571, 0xa204, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ARC_CAN_10MBIT },
+       { 0x1571, 0xa205, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ARC_CAN_10MBIT },
+       { 0x1571, 0xa206, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ARC_CAN_10MBIT },
+       {0,}
+};
+
+static struct pci_driver com20020pci_driver __devinitdata = {
+       name:           "com20020",
+       id_table:       com20020pci_id_table,
+       probe:          com20020pci_probe,
+       remove:         com20020pci_remove
+};
+
+int com20020pci_init(void)
 {
-       struct net_device *dev;
-       int count;
-
-       for (count = 0; count < numcards; count++) {
-               dev = cards[count];
-               unregister_netdev(dev);
-               free_irq(dev->irq, dev);
-               release_region(dev->base_addr, ARCNET_TOTAL_SIZE);
-               kfree(dev->priv);
-               kfree(dev);
-       }
+       BUGLVL(D_NORMAL) printk(VERSION);
+#ifndef MODULE
+       arcnet_init();
+#endif
+       return pci_module_init(&com20020pci_driver);
 }
 
-#else
-
-void __init com20020pci_probe_all(void)
+void com20020pci_cleanup(void)
 {
-       com20020pci_probe(NULL, 0, 0, 0, 3);
+       pci_unregister_driver(&com20020pci_driver);
 }
 
-#endif                         /* MODULE */
+module_init(com20020pci_init)
+module_exit(com20020pci_cleanup)
index 768313e12b627b17eba37b51e451c6899debcf4d..aa5abc7d275ee8096a0aeabfb8288d2b80e4a277 100644 (file)
@@ -42,9 +42,9 @@
 #define VERSION "arcnet: COM20020 chipset support (by David Woodhouse et al.)\n"
 
 static char *clockrates[] =
-{"2.5 Mb/s", "1.25Mb/s", "625 Kb/s", "312.5 Kb/s",
- "156.25 Kb/s", "Reserved", "Reserved",
- "Reserved"};
+{"10 Mb/s", "Reserved", "5 Mb/s",
+ "2.5 Mb/s", "1.25Mb/s", "625 Kb/s", "312.5 Kb/s",
+ "156.25 Kb/s", "Reserved", "Reserved", "Reserved"};
 
 static void com20020_command(struct net_device *dev, int command);
 static int com20020_status(struct net_device *dev);
@@ -87,7 +87,7 @@ static void com20020_copy_to_card(struct net_device *dev, int bufnum,
 
 
 /* Reset the card and check some basic stuff during the detection stage. */
-int __init com20020_check(struct net_device *dev)
+int __devinit com20020_check(struct net_device *dev)
 {
        int ioaddr = dev->base_addr, status;
        struct arcnet_local *lp = dev->priv;
@@ -95,15 +95,25 @@ int __init com20020_check(struct net_device *dev)
        ARCRESET0;
        mdelay(RESETtime);
 
-       lp->setup = lp->clock << 1;
+       lp->setup = lp->clockm ? 0 : (lp->clockp << 1);
+       lp->setup2 = (lp->clockm << 4) | 8;
 
-       REGSETUP;
-       SETCONF(lp->config);
-       outb(lp->setup, ioaddr + 7);
+       SET_SUBADR(SUB_SETUP1);
+       outb(lp->setup, _XREG);
+
+       if (lp->card_flags & ARC_CAN_10MBIT)
+       {
+               SET_SUBADR(SUB_SETUP2);
+               outb(lp->setup2, _XREG);
+       
+               /* must now write the magic "restart operation" command */
+               mdelay(1);
+               outb(0x18, _COMMAND);
+       }
 
        lp->config = 0x21 | (lp->timeout << 3) | (lp->backplane << 2);
        /* set node ID to 0x42 (but transmitter is disabled, so it's okay) */
-       SETCONF(lp->config);
+       SETCONF;
        outb(0x42, ioaddr + 7);
 
        status = ASTATUS();
@@ -139,7 +149,7 @@ int __init com20020_check(struct net_device *dev)
 /* Set up the struct net_device associated with this card.  Called after
  * probing succeeds.
  */
-int __init com20020_found(struct net_device *dev, int shared)
+int __devinit com20020_found(struct net_device *dev, int shared)
 {
        struct arcnet_local *lp;
        int ioaddr = dev->base_addr;
@@ -166,16 +176,24 @@ int __init com20020_found(struct net_device *dev, int shared)
        if (!dev->dev_addr[0])
                dev->dev_addr[0] = inb(ioaddr + 8);     /* FIXME: do this some other way! */
 
-       lp->setup = lp->clock << 1;
+       SET_SUBADR(SUB_SETUP1);
+       outb(lp->setup, _XREG);
+
+       if (lp->card_flags & ARC_CAN_10MBIT)
+       {
+               SET_SUBADR(SUB_SETUP2);
+               outb(lp->setup2, _XREG);
+       
+               /* must now write the magic "restart operation" command */
+               mdelay(1);
+               outb(0x18, _COMMAND);
+       }
 
-       REGSETUP;
-       SETCONF(lp->config);
-       outb(lp->setup, ioaddr + 7);
 
        lp->config = 0x20 | (lp->timeout << 3) | (lp->backplane << 2) | 1;
        /* Default 0x38 + register: Node ID */
-       SETCONF(lp->config);
-       outb(dev->dev_addr[0], ioaddr + 7);
+       SETCONF;
+       outb(dev->dev_addr[0], _XREG);
 
        /* reserve the irq */
        if (request_irq(dev->irq, &arcnet_interrupt, shared,
@@ -183,22 +201,26 @@ int __init com20020_found(struct net_device *dev, int shared)
                BUGMSG(D_NORMAL, "Can't get IRQ %d!\n", dev->irq);
                return -ENODEV;
        }
-       /* reserve the I/O region - guaranteed to work by check_region */
-       request_region(ioaddr, ARCNET_TOTAL_SIZE, "arcnet (COM20020)");
+       /* reserve the I/O region */
+       if (request_region(ioaddr, ARCNET_TOTAL_SIZE, "arcnet (COM20020)")) {
+               free_irq(dev->irq, dev);
+               return -EBUSY;
+       }
        dev->base_addr = ioaddr;
 
-       BUGMSG(D_NORMAL, "COM20020: station %02Xh found at %03lXh, IRQ %d.\n",
-              dev->dev_addr[0], dev->base_addr, dev->irq);
+       BUGMSG(D_NORMAL, "%s: station %02Xh found at %03lXh, IRQ %d.\n",
+              lp->card_name, dev->dev_addr[0], dev->base_addr, dev->irq);
 
        if (lp->backplane)
                BUGMSG(D_NORMAL, "Using backplane mode.\n");
 
        if (lp->timeout != 3)
                BUGMSG(D_NORMAL, "Using extended timeout value of %d.\n", lp->timeout);
-       if (lp->setup) {
-               BUGMSG(D_NORMAL, "Using CKP %d - data rate %s.\n",
-                      lp->setup >> 1, clockrates[lp->setup >> 1]);
-       }
+
+       BUGMSG(D_NORMAL, "Using CKP %d - data rate %s.\n",
+              lp->setup >> 1, 
+              clockrates[3 - ((lp->setup2 & 0xF0) >> 4) + ((lp->setup & 0x0F) >> 1)]);
+
        if (!dev->init && register_netdev(dev)) {
                free_irq(dev->irq, dev);
                release_region(ioaddr, ARCNET_TOTAL_SIZE);
@@ -227,7 +249,7 @@ static int com20020_reset(struct net_device *dev, int really_reset)
 
        lp->config = TXENcfg | (lp->timeout << 3) | (lp->backplane << 2);
        /* power-up defaults */
-       SETCONF(lp->config);
+       SETCONF;
 
        if (really_reset) {
                /* reset the card */
@@ -283,7 +305,7 @@ static void com20020_openclose(struct net_device *dev, bool open)
        else {
                /* disable transmitter */
                lp->config &= ~TXENcfg;
-               SETCONF(lp->config);
+               SETCONF;
                MOD_DEC_USE_COUNT;
        }
        lp->hw.open_close_ll(dev, open);
@@ -305,39 +327,34 @@ static void com20020_set_mc_list(struct net_device *dev)
        if ((dev->flags & IFF_PROMISC) && (dev->flags & IFF_UP)) {      /* Enable promiscuous mode */
                if (!(lp->setup & PROMISCset))
                        BUGMSG(D_NORMAL, "Setting promiscuous flag...\n");
-               REGSETUP;
-               SETCONF(lp->config);
+               SET_SUBADR(SUB_SETUP1);
                lp->setup |= PROMISCset;
-               outb(lp->setup, _SETUP);
+               outb(lp->setup, _XREG);
        } else
                /* Disable promiscuous mode, use normal mode */
        {
                if ((lp->setup & PROMISCset))
                        BUGMSG(D_NORMAL, "Resetting promiscuous flag...\n");
-               REGSETUP;
-               SETCONF(lp->config);
+               SET_SUBADR(SUB_SETUP1);
                lp->setup &= ~PROMISCset;
-               outb(lp->setup, _SETUP);
+               outb(lp->setup, _XREG);
        }
 }
 
-
-/*
- * FIXME: put this somewhere!
- * 
- if ((dstatus = inb(_DIAGSTAT)) & NEWNXTIDflag)
- {
- REGNXTID;
- SETCONF(lp->config);
- BUGMSG(D_EXTRA, "New NextID detected: %X\n", inb(ioaddr + 7));
- }
- */
-
+void __devexit com20020_remove(struct net_device *dev)
+{
+       unregister_netdev(dev);
+       free_irq(dev->irq, dev);
+       release_region(dev->base_addr, ARCNET_TOTAL_SIZE);
+       kfree(dev->priv);
+       kfree(dev);
+}
 
 #ifdef MODULE
 
 EXPORT_SYMBOL(com20020_check);
 EXPORT_SYMBOL(com20020_found);
+EXPORT_SYMBOL(com20020_remove);
 
 int init_module(void)
 {
index e7db72e15a35c57fcad0f491c7cf944df052a10c..aca9635aef8a42c921912ebe2bcf464f3247c44c 100644 (file)
@@ -253,6 +253,7 @@ static int __init com90io_found(struct net_device *dev)
        memset(dev->priv, 0, sizeof(struct arcnet_local));
 
        lp = (struct arcnet_local *) (dev->priv);
+       lp->card_name = "COM90xx I/O";
        lp->hw.command = com90io_command;
        lp->hw.status = com90io_status;
        lp->hw.intmask = com90io_setmask;
index ac8790ef0139c0200971cbf8fdfeef43f04c23d9..7293a16f89ba3352567d335215f085380860ee95 100644 (file)
@@ -452,6 +452,7 @@ static int __init com90xx_found(struct net_device *dev0, int ioaddr, int airq,
 
        /* Initialize the rest of the device structure. */
        memset(lp, 0, sizeof(struct arcnet_local));
+       lp->card_name = "COM90xx";
        lp->hw.command = com90xx_command;
        lp->hw.status = com90xx_status;
        lp->hw.intmask = com90xx_setmask;
index 92d026ec807325b3fc267fdaea329321fefe8648..8aedd16b9bcd14d719eceaaa7c1bd856ffa4a3b1 100644 (file)
@@ -280,6 +280,7 @@ static void rx(struct net_device *dev, int bufnum,
                        if (in->numpackets > 16) {
                                BUGMSG(D_EXTRA, "incoming packet more than 16 segments; dropping. (splitflag=%d)\n",
                                       soft->split_flag);
+                               lp->rfc1201.aborted_seq = soft->sequence;
                                lp->stats.rx_errors++;
                                lp->stats.rx_length_errors++;
                                return;
@@ -288,6 +289,7 @@ static void rx(struct net_device *dev, int bufnum,
                                                  GFP_ATOMIC);
                        if (skb == NULL) {
                                BUGMSG(D_NORMAL, "(split) memory squeeze, dropping packet.\n");
+                               lp->rfc1201.aborted_seq = soft->sequence;
                                lp->stats.rx_dropped++;
                                return;
                        }
@@ -355,6 +357,10 @@ static void rx(struct net_device *dev, int bufnum,
                        in->skb = NULL;
                        in->lastpacket = in->numpackets = 0;
 
+           BUGMSG(D_SKB_SIZE, "skb: received %d bytes from %02X (unsplit)\n",
+               skb->len, pkt->hard.source);
+           BUGMSG(D_SKB_SIZE, "skb: received %d bytes from %02X (split)\n",
+               skb->len, pkt->hard.source);
                        BUGLVL(D_SKB) arcnet_dump_skb(dev, skb, "rx");
 
                        skb->protocol = type_trans(skb, dev);
@@ -442,8 +448,11 @@ static void load_pkt(struct net_device *dev, struct arc_hardware *hard,
                hard->offset[0] = 0;
                hard->offset[1] = ofs = 512 - softlen;
        } else if (softlen > MTU) {     /* exception packet - add an extra header */
-               struct arc_rfc1201 excsoft =
-               {soft->proto, 0xFF, 0xFFFF};
+               struct arc_rfc1201 excsoft;
+
+               excsoft.proto = soft->proto;
+               excsoft.split_flag = 0xff;
+               excsoft.sequence = 0xffff;
 
                hard->offset[0] = 0;
                ofs = 512 - softlen;
index 4c8723efaf417cec75923a7c68010f9ad84b4d24..b59131a62707e666136f51338e14dbc6b55ef1a2 100644 (file)
@@ -877,9 +877,8 @@ set_rx_mode(struct net_device *dev)
 }
 
 #ifdef MODULE
-static char devicename[9] = { 0, };
 static struct net_device dev_at1700 = {
-       devicename, /* device name is inserted by linux/drivers/net/net_init.c */
+       "", /* device name is inserted by linux/drivers/net/net_init.c */
        0, 0, 0, 0,
        0, 0,
        0, 0, 0, NULL, at1700_probe };
index 3ebfe9bcc21e087da3a0166d77ed6ef23204d8aa..53f0b2b6500774511868e678e542102ff195bc59 100644 (file)
@@ -750,9 +750,8 @@ static void set_multicast_list(struct net_device *dev)
 #ifdef MODULE
 
 static int io = 0;
-static char nullname[8] = "";
 static struct net_device atp_dev = {
-       nullname, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, atp_probe };
+       "", 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, atp_probe };
        
 MODULE_PARM(io, "I/O port of the pocket adapter");
 
index f1a4526d44d3cad90e1dbb80d4f1cfc96f6a9077..b1234af8d3fa25987d08eef8cb30304a6f6b8aef 100644 (file)
@@ -309,10 +309,8 @@ static struct net_device_stats *bond_get_stats(struct net_device *dev)
 
 #ifdef MODULE
 
-static char bond_name[16];
-
 static struct net_device dev_bond = {
-               bond_name,      /* Needs to be writeable */
+               "",
                0, 0, 0, 0,
                0x0, 0,
                0, 0, 0, NULL, bond_init };
index 9fd9a275ee2a94da6cf9a593fbf15be1ac609925..3153a692ea99bc9064983eb8ca3248df8dc34527 100644 (file)
@@ -1491,9 +1491,8 @@ static int set_mac_address(struct net_device *dev, void *addr)
 
 #ifdef MODULE
 
-static char namespace[16] = "";
 static struct net_device dev_cs89x0 = {
-        NULL,
+        "",
         0, 0, 0, 0,
         0, 0,
         0, 0, 0, NULL, NULL };
@@ -1560,7 +1559,6 @@ init_module(void)
 #if DEBUGGING
        net_debug = debug;
 #endif
-        dev_cs89x0.name = namespace;
        dev_cs89x0.irq = irq;
        dev_cs89x0.base_addr = io;
 
index 4d738e579a603c1d52d5de658ae2b1376044c5c0..8ae5d07ed434548bcf4c4c027218a34b25bc8a8c 100644 (file)
@@ -5904,13 +5904,12 @@ insert_device(struct net_device *dev, u_long iobase, int (*init)(struct net_devi
 {
     struct net_device *new;
 
-    new = (struct net_device *)kmalloc(sizeof(struct net_device)+8, GFP_KERNEL);
+    new = (struct net_device *)kmalloc(sizeof(struct net_device), GFP_KERNEL);
     if (new == NULL) {
        printk("de4x5.c: Device not initialised, insufficient memory\n");
        return NULL;
     } else {
-       memset((char *)new, 0, sizeof(struct net_device)+8);
-       new->name = (char *)(new + 1);
+       memset((char *)new, 0, sizeof(struct net_device));
        new->base_addr = iobase;       /* assign the io address */
        new->init = init;              /* initialisation routine */
     }
index 075f19cb80e7683ee3773669594dcf7aa7ee44fd..9e9abe7041e1a2653785c3f5db600eb644dd168e 100644 (file)
@@ -819,9 +819,8 @@ de600_rspace(struct sock *sk)
 #endif
 \f
 #ifdef MODULE
-static char nullname[8];
 static struct net_device de600_dev = {
-       nullname, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, de600_probe };
+       "", 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, de600_probe };
 
 int
 init_module(void)
index 440ac99515c6ed08c9bbe634b287025428c999b8..43541521226d9cebc30f703725b955d71b413ae0 100644 (file)
@@ -985,9 +985,8 @@ static int __init read_eeprom(struct net_device *dev)
  *
  */
 #ifdef MODULE
-static char nullname[8] = "";
 static struct net_device de620_dev = {
-       nullname, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, de620_probe };
+       "", 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, de620_probe };
 
 int init_module(void)
 {
index 06d9e61717df6278d0b4d67a90a5214c68c74c95..b62dc591a610b5751a3ca52520b8f503bcd772a2 100644 (file)
@@ -1524,7 +1524,7 @@ insert_device(struct net_device *dev, u_long iobase, int (*init)(struct net_devi
 {
     struct net_device *new;
 
-    new = (struct net_device *)kmalloc(sizeof(struct net_device)+8, GFP_KERNEL);
+    new = (struct net_device *)kmalloc(sizeof(struct net_device), GFP_KERNEL);
     if (new == NULL) {
        printk("eth%d: Device not initialised, insufficient memory\n",num_eth);
        return NULL;
@@ -1532,7 +1532,6 @@ insert_device(struct net_device *dev, u_long iobase, int (*init)(struct net_devi
        new->next = dev->next;
        dev->next = new;
        dev = dev->next;               /* point to the new device */
-       dev->name = (char *)(dev + 1);
        if (num_eth > 9999) {
            sprintf(dev->name,"eth????");/* New device name */
        } else {
@@ -2002,9 +2001,8 @@ static int depca_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 }
 
 #ifdef MODULE
-static char devicename[9] = {0,};
 static struct net_device thisDepca = {
-  devicename,  /* device name is inserted by /linux/drivers/net/net_init.c */
+  "",  /* device name is inserted by /linux/drivers/net/net_init.c */
   0, 0, 0, 0,
   0x200, 7,    /* I/O address, IRQ */
   0, 0, 0, NULL, depca_probe
index 5a5f3cc62cf1707e1240696551cc79afb0666319..e605e4023fb65f74c81515885a5a3811890bc3ea 100644 (file)
@@ -192,7 +192,6 @@ typedef struct
        /*
         *      Stuff for generic ethercard I/F
         */
-       char                    devname[8];     /* "ethN" string */
        struct net_device               *next_dev;
        struct net_device_stats stats;
 
@@ -1256,7 +1255,6 @@ dgrs_found_device(
        dev->priv = ((void *)dev) + sizeof(struct net_device);
        priv = (DGRS_PRIV *)dev->priv;
 
-       dev->name = priv->devname; /* An empty string. */
        dev->base_addr = io;
        dev->mem_start = mem;
        dev->mem_end = mem + 2048 * 1024 - 1;
@@ -1294,9 +1292,6 @@ dgrs_found_device(
                memcpy(devN, dev, dev_size);
                devN->priv = ((void *)devN) + sizeof(struct net_device);
                privN = (DGRS_PRIV *)devN->priv;
-                       /* ... but seset devname to a NULL string */
-               privN->devname[0] = 0;
-               devN->name = privN->devname;
                        /* ... and zero out VM areas */
                privN->vmem = 0;
                privN->vplxdma = 0;
index dae428320ee7ef357f37966da92b0fca79351976..bec5eb631fe21252f99c4056f6c55fadd24797cf 100644 (file)
@@ -133,10 +133,8 @@ static int __init dummy_probe(struct net_device *dev)
        return 0;
 }
 
-static char dummy_name[16];
-
 static struct net_device dev_dummy = {
-               dummy_name,     /* Needs to be writeable */
+               "",
                0, 0, 0, 0,
                0x0, 0,
                0, 0, 0, NULL, dummy_probe };
index 4ea0e6b71b496af348426af6a5c66d4821df602e..d31aac565658df1614f3944821411496ed259dc9 100644 (file)
@@ -384,11 +384,9 @@ struct netdev_entry e21_drv =
 \f
 #ifdef MODULE
 #define MAX_E21_CARDS  4       /* Max number of E21 cards per module */
-#define NAMELEN                8       /* # of chars for storing dev->name */
-static char namelist[NAMELEN * MAX_E21_CARDS] = { 0, };
 static struct net_device dev_e21[MAX_E21_CARDS] = {
        {
-               NULL,           /* assign a chunk of namelist[] below */
+               "",
                0, 0, 0, 0,
                0, 0,
                0, 0, 0, NULL, NULL
@@ -414,7 +412,6 @@ init_module(void)
 
        for (this_dev = 0; this_dev < MAX_E21_CARDS; this_dev++) {
                struct net_device *dev = &dev_e21[this_dev];
-               dev->name = namelist+(NAMELEN*this_dev);
                dev->irq = irq[this_dev];
                dev->base_addr = io[this_dev];
                dev->mem_start = mem[this_dev];
index 6549f10c76d77679606c7f255eb5d7cb0b3c6ff9..ebbe5742ee31e5e60d1c7475e6e34e9b2ca30d93 100644 (file)
@@ -1572,7 +1572,6 @@ eepro_transmit_interrupt(struct net_device *dev)
 }
 
 #define MAX_EEPRO 8
-static char devicename[MAX_EEPRO][9];
 static struct net_device dev_eepro[MAX_EEPRO];
 
 static int io[MAX_EEPRO] = {
@@ -1606,7 +1605,6 @@ init_module(void)
 
        while (n_eepro < MAX_EEPRO && io[n_eepro] >= 0) {
                struct net_device *d = &dev_eepro[n_eepro];
-               d->name         = devicename[n_eepro]; /* inserted by drivers/net/net_init.c */
                d->mem_end      = mem[n_eepro];
                d->base_addr    = io[n_eepro];
                d->irq          = irq[n_eepro];
index d5230dddaea09b7881f999aef768c360bf171556..b96da10ddf1e2daf5694979c1e796e5a2e3b7fd9 100644 (file)
@@ -1623,13 +1623,10 @@ eexp_set_multicast(struct net_device *dev)
 #ifdef MODULE
 
 #define EEXP_MAX_CARDS     4    /* max number of cards to support */
-#define NAMELEN            8    /* max length of dev->name (inc null) */
-
-static char namelist[NAMELEN * EEXP_MAX_CARDS] = { 0, };
 
 static struct net_device dev_eexp[EEXP_MAX_CARDS] =
 {
-        { NULL,         /* will allocate dynamically */
+        { "",
          0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, express_probe },
 };
 
@@ -1649,7 +1646,6 @@ int init_module(void)
 
        for (this_dev = 0; this_dev < EEXP_MAX_CARDS; this_dev++) {
                struct net_device *dev = &dev_eexp[this_dev];
-               dev->name = namelist + (NAMELEN*this_dev);
                dev->irq = irq[this_dev];
                dev->base_addr = io[this_dev];
                if (io[this_dev] == 0) {
index 502936cab184c48a50569b1f41c6ee4257c5e175..56f2600d0fa7e7c84d7c5240e97ee1326519b9b6 100644 (file)
@@ -1390,12 +1390,10 @@ static ushort eth16i_parse_mediatype(const char* s)
 }
 
 #define MAX_ETH16I_CARDS 4  /* Max number of Eth16i cards per module */
-#define NAMELEN          8  /* number of chars for storing dev->name */
 
-static char namelist[NAMELEN * MAX_ETH16I_CARDS] = { 0, };
 static struct net_device dev_eth16i[MAX_ETH16I_CARDS] = {
        {
-               NULL,
+               "",
                0, 0, 0, 0,
                0, 0,
                0, 0, 0, NULL, NULL
@@ -1436,7 +1434,6 @@ int init_module(void)
        {
                struct net_device *dev = &dev_eth16i[this_dev];
        
-               dev->name = namelist + (NAMELEN*this_dev);
                dev->irq = 0; /* irq[this_dev]; */
                dev->base_addr = io[this_dev];
                dev->init = eth16i_probe;
index 2bf83d866115d34337914cd66230555df5e78938..7afe9bf4462041871cf9cbf3fa86f8e579e409e7 100644 (file)
@@ -414,11 +414,9 @@ hpp_mem_block_output(struct net_device *dev, int count,
 \f
 #ifdef MODULE
 #define MAX_HPP_CARDS  4       /* Max number of HPP cards per module */
-#define NAMELEN                8       /* # of chars for storing dev->name */
-static char namelist[NAMELEN * MAX_HPP_CARDS] = { 0, };
 static struct net_device dev_hpp[MAX_HPP_CARDS] = {
        {
-               NULL,           /* assign a chunk of namelist[] below */
+               "",
                0, 0, 0, 0,
                0, 0,
                0, 0, 0, NULL, NULL
@@ -440,7 +438,6 @@ init_module(void)
 
        for (this_dev = 0; this_dev < MAX_HPP_CARDS; this_dev++) {
                struct net_device *dev = &dev_hpp[this_dev];
-               dev->name = namelist+(NAMELEN*this_dev);
                dev->irq = irq[this_dev];
                dev->base_addr = io[this_dev];
                dev->init = hp_plus_probe;
index 24b3e9d83c06c2aee17d6ed9057441492a34b72c..2300e6a7a197ee53582db131bd2ca49721538d6d 100644 (file)
@@ -385,11 +385,9 @@ hp_init_card(struct net_device *dev)
 
 #ifdef MODULE
 #define MAX_HP_CARDS   4       /* Max number of HP cards per module */
-#define NAMELEN                8       /* # of chars for storing dev->name */
-static char namelist[NAMELEN * MAX_HP_CARDS] = { 0, };
 static struct net_device dev_hp[MAX_HP_CARDS] = {
        {
-               NULL,           /* assign a chunk of namelist[] below */
+               "",
                0, 0, 0, 0,
                0, 0,
                0, 0, 0, NULL, NULL
@@ -411,7 +409,6 @@ init_module(void)
 
        for (this_dev = 0; this_dev < MAX_HP_CARDS; this_dev++) {
                struct net_device *dev = &dev_hp[this_dev];
-               dev->name = namelist+(NAMELEN*this_dev);
                dev->irq = irq[this_dev];
                dev->base_addr = io[this_dev];
                dev->init = hp_probe;
index a0cb270451ff9126c4d81d03643c36f60d3d2ab4..39625e4814fa7f0532e86f8329cfa54171468dbe 100644 (file)
@@ -3123,10 +3123,7 @@ int hp100_port[5] = { 0, -1, -1, -1, -1 };
 MODULE_PARM(hp100_port, "1-5i");
 #endif
 
-#ifdef LINUX_2_1
-char hp100_name[5][IFNAMSIZ] = { "", "", "", "", "" };
-MODULE_PARM(hp100_name, "1-5c" __MODULE_STRING(IFNAMSIZ));
-#else
+#ifndef LINUX_2_1
 static char devname[5][IFNAMSIZ] = { "", "", "", "", "" };
 static char *hp100_name[5] = { devname[0], devname[1],
                                devname[2], devname[3],
@@ -3162,7 +3159,9 @@ int init_module( void )
       /* Create device and set basics args */
       hp100_devlist[i] = kmalloc(sizeof(struct net_device), GFP_KERNEL);
       memset(hp100_devlist[i], 0x00, sizeof(struct net_device));
+#ifndef LINUX_2_1
       hp100_devlist[i]->name = hp100_name[i];
+#endif
       hp100_devlist[i]->base_addr = hp100_port[i];
       hp100_devlist[i]->init = &hp100_probe;
 
index ce94c3139db50a1ef2bd0ee5283f435a58aefd87..51f6ebaf61aaed61fa65ec061047e01b978a311f 100644 (file)
@@ -290,7 +290,6 @@ static void lance_tx_timeout (struct net_device *dev);
 
 #ifdef MODULE
 #define MAX_CARDS              8       /* Max number of interfaces (cards) per module */
-#define IF_NAMELEN             8       /* # of chars for storing dev->name */
 
 static int io[MAX_CARDS] = { 0, };
 static int dma[MAX_CARDS] = { 0, };
@@ -300,10 +299,9 @@ MODULE_PARM(io, "1-" __MODULE_STRING(MAX_CARDS) "i");
 MODULE_PARM(dma, "1-" __MODULE_STRING(MAX_CARDS) "i");
 MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_CARDS) "i");
 
-static char ifnames[MAX_CARDS][IF_NAMELEN] = { {0, }, };
 static struct net_device dev_lance[MAX_CARDS] =
 {{
-    0, /* device name is inserted by linux/drivers/net/net_init.c */
+    "", /* device name is inserted by linux/drivers/net/net_init.c */
        0, 0, 0, 0,
        0, 0,
        0, 0, 0, NULL, NULL}};
@@ -314,7 +312,6 @@ int init_module(void)
 
        for (this_dev = 0; this_dev < MAX_CARDS; this_dev++) {
                struct net_device *dev = &dev_lance[this_dev];
-               dev->name = ifnames[this_dev];
                dev->irq = irq[this_dev];
                dev->base_addr = io[this_dev];
                dev->dma = dma[this_dev];
index 2700129c29f73cfbdb7216214e7431868c2def39..bc6ab00059a82a369bfc463ad608d73916734e08 100644 (file)
@@ -372,11 +372,9 @@ static int lne390_close(struct net_device *dev)
 
 #ifdef MODULE
 #define MAX_LNE_CARDS  4       /* Max number of LNE390 cards per module */
-#define NAMELEN                8       /* # of chars for storing dev->name */
-static char namelist[NAMELEN * MAX_LNE_CARDS] = { 0, };
 static struct net_device dev_lne[MAX_LNE_CARDS] = {
        {
-               NULL,           /* assign a chunk of namelist[] below */
+               "",
                0, 0, 0, 0,
                0, 0,
                0, 0, 0, NULL, NULL
@@ -397,7 +395,6 @@ int init_module(void)
 
        for (this_dev = 0; this_dev < MAX_LNE_CARDS; this_dev++) {
                struct net_device *dev = &dev_lne[this_dev];
-               dev->name = namelist+(NAMELEN*this_dev);
                dev->irq = irq[this_dev];
                dev->base_addr = io[this_dev];
                dev->mem_start = mem[this_dev];
index 477db0958039613709044da2f676aa2239311d0b..9e651fb8f2f99c78ed98d985845b72c60a365ae9 100644 (file)
@@ -807,10 +807,9 @@ retry:
 #ifdef MODULE
 #define MAX_NE_CARDS   4       /* Max number of NE cards per module */
 #define NAMELEN                8       /* # of chars for storing dev->name */
-static char namelist[NAMELEN * MAX_NE_CARDS] = { 0, };
 static struct net_device dev_ne[MAX_NE_CARDS] = {
        {
-               NULL,           /* assign a chunk of namelist[] below */
+               "",
                0, 0, 0, 0,
                0, 0,
                0, 0, 0, NULL, NULL
@@ -840,7 +839,6 @@ int init_module(void)
 
        for (this_dev = 0; this_dev < MAX_NE_CARDS; this_dev++) {
                struct net_device *dev = &dev_ne[this_dev];
-               dev->name = namelist+(NAMELEN*this_dev);
                dev->irq = irq[this_dev];
                dev->mem_end = bad[this_dev];
                dev->base_addr = io[this_dev];
index 269300c0dcec7f1fd614365035e2bfbc27902739..c48ad24ce28f0deaf3473e84446d188f01b9f166 100644 (file)
@@ -619,11 +619,9 @@ retry:
 
 #ifdef MODULE
 #define MAX_NE_CARDS   4       /* Max number of NE cards per module */
-#define NAMELEN                8       /* # of chars for storing dev->name */
-static char namelist[NAMELEN * MAX_NE_CARDS] = { 0, };
 static struct net_device dev_ne[MAX_NE_CARDS] = {
        {
-               NULL,           /* assign a chunk of namelist[] below */
+               "",
                0, 0, 0, 0,
                0, 0,
                0, 0, 0, NULL, NULL
@@ -648,7 +646,6 @@ int init_module(void)
 
        for (this_dev = 0; this_dev < MAX_NE_CARDS; this_dev++) {
                struct net_device *dev = &dev_ne[this_dev];
-               dev->name = namelist+(NAMELEN*this_dev);
                dev->irq = irq[this_dev];
                dev->mem_end = bad[this_dev];
                dev->base_addr = io[this_dev];
index 9a70ecee1386ffed7aa09d29f0cccfc9dbc63cb7..ad39dd40b52862f8c7151b3b40fe3531b84cad25 100644 (file)
@@ -363,11 +363,9 @@ static int ne3210_close(struct net_device *dev)
 
 #ifdef MODULE
 #define MAX_NE3210_CARDS       4       /* Max number of NE3210 cards per module */
-#define NAMELEN                        8       /* # of chars for storing dev->name */
-static char namelist[NAMELEN * MAX_NE3210_CARDS] = { 0, };
 static struct net_device dev_ne3210[MAX_NE3210_CARDS] = {
        {
-               NULL,           /* assign a chunk of namelist[] below */
+               "",
                0, 0, 0, 0,
                0, 0,
                0, 0, 0, NULL, NULL
@@ -388,7 +386,6 @@ int init_module(void)
 
        for (this_dev = 0; this_dev < MAX_NE3210_CARDS; this_dev++) {
                struct net_device *dev = &dev_ne3210[this_dev];
-               dev->name = namelist+(NAMELEN*this_dev);
                dev->irq = irq[this_dev];
                dev->base_addr = io[this_dev];
                dev->mem_start = mem[this_dev];
index 214341b5315463318fdbe23058617af6f8215a52..9630e895a3ca8b1596f3581f4eca909a5224d2dc 100644 (file)
@@ -74,7 +74,7 @@ static struct net_device *init_alloc_dev(int sizeof_priv)
        int alloc_size;
 
        /* ensure 32-byte alignment of the private area */
-       alloc_size = sizeof (*dev) + IFNAMSIZ + sizeof_priv + 31;
+       alloc_size = sizeof (*dev) + sizeof_priv + 31;
 
        dev = (struct net_device *) kmalloc (alloc_size, GFP_KERNEL);
        if (dev == NULL)
@@ -88,7 +88,6 @@ static struct net_device *init_alloc_dev(int sizeof_priv)
        if (sizeof_priv)
                dev->priv = (void *) (((long)(dev + 1) + 31) & ~31);
 
-       dev->name = sizeof_priv + 31 + (char *)(dev + 1);
        return dev;
 }
 
index 8e5bca56a3ffb7e5ea1eaf8a604f759d44e08807..c9e8c1ff7aad91114c0c8b0e9244678aa2aabde7 100644 (file)
@@ -741,9 +741,8 @@ static void show_registers(struct net_device *dev)
 }
 
 #ifdef MODULE
-static char devicename[9] = { 0, };
 static struct net_device dev_ni5010 = {
-        devicename,
+        "",
         0, 0, 0, 0,
         0, 0,
         0, 0, 0, NULL, ni5010_probe };
index 6d1d0e71480a046c133cbb924819f04e00c91a5e..3ffdfabd4927f8d69ea625737cd41662f3892089 100644 (file)
@@ -1277,9 +1277,8 @@ static void set_multicast_list(struct net_device *dev)
 }
 
 #ifdef MODULE
-static char devicename[9] = { 0, };
 static struct net_device dev_ni52 = {
-       devicename,     /* "ni5210": device name inserted by net_init.c */
+       "",     /* device name inserted by net_init.c */
        0, 0, 0, 0,
        0x300, 9,        /* I/O address, IRQ */
        0, 0, 0, NULL, ni52_probe };
index 2e82ceca52d4d4b03e44a9cc771ea69ec45aebd2..0b5c8589873f1db5da589599ba7ec9db4d543aae 100644 (file)
@@ -1173,10 +1173,8 @@ static void set_multicast_list(struct net_device *dev)
 }
 
 #ifdef MODULE
-static char devicename[9] = { 0, };
-
 static struct net_device dev_ni65 = {
-       devicename,     /* "ni6510": device name inserted by net_init.c */
+       "",     /* "ni6510": device name inserted by net_init.c */
        0, 0, 0, 0,
        0x360, 9,        /* I/O address, IRQ */
        0, 0, 0, NULL, ni65_probe };
index 5a83c521c26d9cf7634d681e8d1c709be950ae7c..b6035305ca0e565625f261220b5b8e70d085323c 100644 (file)
@@ -18,7 +18,6 @@ if [ "$CONFIG_NET_PCMCIA" = "y" ]; then
    dep_tristate '  IBM PCMCIA tokenring adapter support' CONFIG_PCMCIA_IBMTR $CONFIG_PCMCIA_IBMTR $CONFIG_TR $CONFIG_PCMCIA
 
    if [ "$CONFIG_CARDBUS" = "y" ]; then
-      comment '  3Com 3c575 moved to Ethernet 10/100 menu'
       tristate '  Xircom Tulip-like CardBus support' CONFIG_PCMCIA_XIRTULIP
    fi
 
index 6853cc4039cdd50cda06e4b32a9fcb626e03c842..85d5c86ebab858e6b5db3c74b372d5e1e696990c 100644 (file)
@@ -102,12 +102,14 @@ static inline void regdump(struct net_device *dev) { }
 static int node = 0;
 static int timeout = 3;
 static int backplane = 0;
-static int clock = 0;
+static int clockp = 0;
+static int clockm = 0;
 
 MODULE_PARM(node, "i");
 MODULE_PARM(timeout, "i");
 MODULE_PARM(backplane, "i");
-MODULE_PARM(clock, "i");
+MODULE_PARM(clockp, "i");
+MODULE_PARM(clockm, "i");
 
 /* Bit map of interrupts to choose from */
 static u_int irq_mask = 0xdeb8;
@@ -231,7 +233,8 @@ static dev_link_t *com20020_attach(void)
     dev->dev_addr[0] = node;
     lp->timeout = timeout;
     lp->backplane = backplane;
-    lp->clock = clock;
+    lp->clockp = clockp;
+    lp->clockm = clockm & 3;
     lp->hw.open_close_ll = com20020cs_open_close;
 
     link->irq.Instance = info->dev = dev;
@@ -350,6 +353,7 @@ while ((last_ret=CardServices(last_fn=(fn), args))!=0) goto cs_failed
 
 static void com20020_config(dev_link_t *link)
 {
+    struct arcnet_local *lp;
     client_handle_t handle;
     tuple_t tuple;
     cisparse_t parse;
@@ -426,6 +430,11 @@ static void com20020_config(dev_link_t *link)
     }
     
     MOD_INC_USE_COUNT;
+
+    lp = dev->priv;
+    lp->card_name = "PCMCIA COM20020";
+    lp->card_flags = ARC_CAN_10MBIT; /* pretend all of them can 10Mbit */
+
     i = com20020_found(dev, 0);
     
     if (i != 0) {
index 185644307bdf34aa7b3bb6a30c6bfc6e7c2ccefc..b3788db9bf2ddc9aaef727ca4b802bb8662e21e6 100644 (file)
@@ -310,7 +310,7 @@ static dev_link_t *pcnet_attach(void)
     link->conf.IntType = INT_MEMORY_AND_IO;
 
     ethdev_init(dev);
-    dev->name = info->node.dev_name;
+    strcpy(dev->name, info->node.dev_name);
     dev->init = &pcnet_init;
     dev->open = &pcnet_open;
     dev->stop = &pcnet_close;
index ba58883c2cebabbd1ac586c05bdd5180f95a0965..452b9e7eda9b0f4e9328debe290c2dd7076d6a86 100644 (file)
@@ -385,7 +385,7 @@ static dev_link_t *ray_attach(void)
 
     DEBUG(2,"ray_cs ray_attach calling ether_setup.)\n");
     ether_setup(dev);
-    dev->name = local->node.dev_name;
+    strcpy(dev->name, local->node.dev_name);
     dev->init = &ray_dev_init;
     dev->open = &ray_open;
     dev->stop = &ray_dev_close;
index 877407590661b3a0f17cb7156290f87fe1257783..d8a2259b2d8230f6d93ee5c6bb4a2bc841109993 100644 (file)
@@ -1395,14 +1395,6 @@ static int __init plip_init (void)
                                break;
                        }
                        memset(dev_plip[i], 0, sizeof(struct net_device));
-                       dev_plip[i]->name = 
-                               kmalloc(strlen("plipXXX"), GFP_KERNEL);
-                       if (!dev_plip[i]->name) {
-                               printk(KERN_ERR "plip: memory squeeze.\n");
-                               kfree(dev_plip[i]);
-                               dev_plip[i] = NULL;
-                               break;
-                       }
                        sprintf(dev_plip[i]->name, "plip%d", i);
                        dev_plip[i]->priv = pb;
                        if (plip_init_dev(dev_plip[i],pb) || register_netdev(dev_plip[i])) {
index 4a7454d3fdaa148e080039b9fbf0cc60bc230b64..be2162f87ad432a0a2ae5b8070f1da54eacf547f 100644 (file)
@@ -92,7 +92,6 @@ struct ppp_file {
  */
 struct ppp {
        struct ppp_file file;           /* stuff for read/write/poll */
-       char            name[16];       /* unit name */
        struct list_head channels;      /* list of attached channels */
        int             n_channels;     /* how many channels are attached */
        spinlock_t      rlock;          /* lock for receive side */
@@ -2190,7 +2189,6 @@ ppp_create_interface(int unit, int *retp)
        memset(dev, 0, sizeof(struct net_device));
 
        ppp->file.index = unit;
-       sprintf(ppp->name, "ppp%d", unit);
        ppp->mru = PPP_MRU;
        init_ppp_file(&ppp->file, INTERFACE);
        for (i = 0; i < NUM_NP; ++i)
@@ -2205,7 +2203,7 @@ ppp_create_interface(int unit, int *retp)
 
        ppp->dev = dev;
        dev->init = ppp_net_init;
-       dev->name = ppp->name;
+       sprintf(dev->name, "ppp%d", unit);
        dev->priv = ppp;
        dev->new_style = 1;
 
index 36d734a73787e50c426e914c5ea61f82f7b5c043..96df996dea609d44e8e5fd26e15262a0b1c7e562 100644 (file)
@@ -117,7 +117,6 @@ typedef struct
      */
     struct net_device *dev;            
      
-    char devname[8];                /* "ethN" string */
     U8     id;                        /* the AdapterID */
     U32    pci_addr;               /* the pci address of the adapter */
     U32    bus;
@@ -276,8 +275,6 @@ RCfound_device(int memaddr, int irq,
 #endif
 
     pDpa = dev->priv;
-    if (!dev->name)
-        dev->name = pDpa->devname;
 
     pDpa->dev = dev;            /* this is just for easy reference */
     pDpa->function = function;
index bcf6e7e5b3b007ef2140443ac9cd0c7773467e01..a34deb630a9d7d76154cdc7be8d5ec98674d2272 100644 (file)
@@ -1205,9 +1205,8 @@ MODULE_DESCRIPTION("General Instruments SB1000 driver");
 MODULE_PARM(io, "1-2i");
 MODULE_PARM(irq, "i");
 
-static char devname[8] = {0, };
 static struct net_device dev_sb1000 = {
-        devname,
+        "",
         0, 0, 0, 0,
         0, 0,
         0, 0, 0, NULL, sb1000_probe };
@@ -1220,8 +1219,8 @@ init_module(void)
 {
        int i;
        for (i = 0; i < 100; i++) {
-               sprintf(devname, "cm%d", i);
-               if (dev_get(devname) == 0) break;
+               sprintf(dev_sb1000.name, "cm%d", i);
+               if (dev_get(dev_sb1000.name) == 0) break;
        }
        if (i == 100) {
                printk(KERN_ERR "sb1000: can't register any device cm<n>\n");
index 1334836145de5c8348c045f1320ad056d3ab9d4f..acc1fcd464cea6886f6948f80b3104ef1d2c934b 100644 (file)
@@ -688,11 +688,9 @@ int __init shaper_probe(struct net_device *dev)
  
 #ifdef MODULE
 
-static char devicename[9];
-
 static struct net_device dev_shape = 
 {
-       devicename,
+       "",
        0, 0, 0, 0,
        0, 0,
        0, 0, 0, NULL, shaper_probe 
index 088b89388fed6914560a1eae51445954e7ce22b2..27379bfdb93af1a797f1a8b390ad15ee446cceab 100644 (file)
@@ -1068,13 +1068,12 @@ int skmca_probe(struct net_device *dev)
 
 #define DEVMAX 5
 
-static char NameSpace[8 * DEVMAX];
 static struct net_device moddevs[DEVMAX] =
-    { {NameSpace + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, skmca_probe},
-{NameSpace + 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, skmca_probe},
-{NameSpace + 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, skmca_probe},
-{NameSpace + 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, skmca_probe},
-{NameSpace + 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, skmca_probe}
+    { {"", 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, skmca_probe},
+{"", 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, skmca_probe},
+{"", 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, skmca_probe},
+{"", 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, skmca_probe},
+{"", 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, skmca_probe}
 };
 
 int irq = 0;
index b6b112318932f8a11bf36814903b54b9a3e8a04e..1bbd5f0688b593116bce08c51890ea198c7cbd79 100644 (file)
@@ -551,7 +551,7 @@ static struct net_device *insert_device(struct net_device *dev,
        int len;
 
        PRINTK(KERN_INFO "entering insert_device\n");
-       len = sizeof(struct net_device) + 8 + sizeof(struct s_smc);
+       len = sizeof(struct net_device) + sizeof(struct s_smc);
        new = (struct net_device *) kmalloc(len, GFP_KERNEL);
        if (new == NULL) {
                printk("fddi%d: Device not initialised, insufficient memory\n",
@@ -559,8 +559,7 @@ static struct net_device *insert_device(struct net_device *dev,
                return NULL;
        } else {
                memset((char *) new, 0, len);
-               new->name = (char *) (new + 1);
-               new->priv = (struct s_smc *) (new->name + 8);
+               new->priv = (struct s_smc *) (new + 1);
                new->init = init;       /* initialisation routine */
                if (!loading_module) {
                        new->next = dev->next;
index 620b1cc464e051ac36565e79869955cddc1ed32b..9e395d36116822e4e482be0e4b8a4ed43ac6d2af 100644 (file)
@@ -89,7 +89,6 @@
 
 
 typedef struct slip_ctrl {
-       char            if_name[16];    /* "sl0\0" .. "sl99999\0"       */
        struct slip     ctrl;           /* SLIP things                  */
        struct net_device       dev;            /* the device                   */
 } slip_ctrl_t;
@@ -805,8 +804,7 @@ sl_alloc(kdev_t line)
        sl->dev         = &slp->dev;
        spin_lock_init(&sl->lock);
        sl->mode        = SL_MODE_DEFAULT;
-       sprintf(slp->if_name, "sl%d", i);
-       slp->dev.name         = slp->if_name;
+       sprintf(slp->dev.name, "sl%d", i);
        slp->dev.base_addr    = i;
        slp->dev.priv         = (void*)sl;
        slp->dev.init         = sl_init;
index ab1664fecd0f8f1d494ba7a00647e6ec846c2990..03c624a9dfe29ae56a266749333d372ef0b88b11 100644 (file)
@@ -437,14 +437,11 @@ static int ultramca_close_card(struct net_device *dev)
 #undef MODULE        /* don't want to bother now! */
 
 #define MAX_ULTRAMCA_CARDS 4   /* Max number of Ultra cards per module */
-#define NAMELEN 8              /* # of chars for storing dev->name */
-
-static char namelist[NAMELEN * MAX_ULTRAMCA_CARDS] = { 0, };
 
 static struct net_device dev_ultra[MAX_ULTRAMCA_CARDS] =
 {
        {
-               NULL,       /* assign a chunk of namelist[] below */
+               "",
                0, 0, 0, 0,
                0, 0,
                0, 0, 0, NULL, NULL
@@ -463,7 +460,6 @@ int init_module(void)
 
        for (this_dev = 0; this_dev < MAX_ULTRAMCA_CARDS; this_dev++) {
                struct net_device *dev = &dev_ultra[this_dev];
-               dev->name = namelist + (NAMELEN * this_dev);
                dev->irq = irq[this_dev];
                dev->base_addr = io[this_dev];
                dev->init = ultramca_probe;
index 217159ea77e9babcd91ed6bb78782f6eec431142..7477bcb50d860d134bcfd4975e597d6da8fc5094 100644 (file)
@@ -424,11 +424,9 @@ ultra_close_card(struct net_device *dev)
 \f
 #ifdef MODULE
 #define MAX_ULTRA_CARDS        4       /* Max number of Ultra cards per module */
-#define NAMELEN                8       /* # of chars for storing dev->name */
-static char namelist[NAMELEN * MAX_ULTRA_CARDS] = { 0, };
 static struct net_device dev_ultra[MAX_ULTRA_CARDS] = {
        {
-               NULL,           /* assign a chunk of namelist[] below */
+               "",             /* assign a chunk of namelist[] below */
                0, 0, 0, 0,
                0, 0,
                0, 0, 0, NULL, NULL
@@ -452,7 +450,6 @@ init_module(void)
 
        for (this_dev = 0; this_dev < MAX_ULTRA_CARDS; this_dev++) {
                struct net_device *dev = &dev_ultra[this_dev];
-               dev->name = namelist+(NAMELEN*this_dev);
                dev->irq = irq[this_dev];
                dev->base_addr = io[this_dev];
                dev->init = ultra_probe;
index 22fdc650551aaf9e782ffa81abf143a525cbebb4..a7ba60dfa70ad788bbbc8984ad02f047cee40acb 100644 (file)
@@ -368,11 +368,9 @@ static void ultra32_block_output(struct net_device *dev,
 \f
 #ifdef MODULE
 #define MAX_ULTRA32_CARDS   4  /* Max number of Ultra cards per module */
-#define NAMELEN                    8   /* # of chars for storing dev->name */
-static char namelist[NAMELEN * MAX_ULTRA32_CARDS] = { 0, };
 static struct net_device dev_ultra[MAX_ULTRA32_CARDS] = {
        {
-               NULL,           /* assign a chunk of namelist[] below */
+               "",
                0, 0, 0, 0,
                0, 0,
                0, 0, 0, NULL, NULL
@@ -385,7 +383,6 @@ int init_module(void)
 
        for (this_dev = 0; this_dev < MAX_ULTRA32_CARDS; this_dev++) {
                struct net_device *dev = &dev_ultra[this_dev];
-               dev->name = namelist+(NAMELEN*this_dev);
                dev->init = ultra32_probe;
                if (register_netdev(dev) != 0) {
                        if (found > 0) { /* Got at least one. */
index 0d754ed310078961e8de2905f730292151ad0ae2..b37b86df054314c86b46e7b3eac4102f091f85b4 100644 (file)
@@ -311,7 +311,6 @@ struct strip
      */
 
     struct tty_struct *tty;                    /* ptr to TTY structure         */
-    char8              if_name;                        /* Dynamically generated name   */
     struct net_device      dev;                        /* Our device structure         */
 
     /*
@@ -1180,7 +1179,7 @@ sprintf_status_info(char *buffer, struct strip *strip_info)
     FirmwareVersion    firmware_version    = strip_info->firmware_version;
     SerialNumber       serial_number       = strip_info->serial_number;
     BatteryVoltage     battery_voltage     = strip_info->battery_voltage;
-    char8              if_name             = strip_info->if_name;
+    char*              if_name             = strip_info->dev.name;
     MetricomAddress    true_dev_addr       = strip_info->true_dev_addr;
     MetricomAddress    dev_dev_addr        = *(MetricomAddress*)strip_info->dev.dev_addr;
     int                manual_dev_addr     = strip_info->manual_dev_addr;
@@ -1196,7 +1195,7 @@ sprintf_status_info(char *buffer, struct strip *strip_info)
 #endif
     RestoreInterrupts(intstat);
 
-    p += sprintf(p, "\nInterface name\t\t%s\n", if_name.c);
+    p += sprintf(p, "\nInterface name\t\t%s\n", if_name);
     p += sprintf(p, " Radio working:\t\t%s\n", working ? "Yes" : "No");
     radio_address_to_string(&true_dev_addr, &addr_string);
     p += sprintf(p, " Radio address:\t\t%s\n", addr_string.c);
@@ -2664,8 +2663,7 @@ static struct strip *strip_alloc(void)
     strip_info->idle_timer.function = strip_IdleTask;
 
     /* Note: strip_info->if_name is currently 8 characters long */
-    sprintf(strip_info->if_name.c, "st%d", channel_id);
-    strip_info->dev.name         = strip_info->if_name.c;
+    sprintf(strip_info->dev.name, "st%d", channel_id);
     strip_info->dev.base_addr    = channel_id;
     strip_info->dev.priv         = (void*)strip_info;
     strip_info->dev.next         = NULL;
@@ -2736,7 +2734,7 @@ static int strip_open(struct tty_struct *tty)
     MOD_INC_USE_COUNT;
 #endif
 
-    printk(KERN_INFO "STRIP: device \"%s\" activated\n", strip_info->if_name.c);
+    printk(KERN_INFO "STRIP: device \"%s\" activated\n", strip_info->dev.name);
 
     /*
      * Done.  We have linked the TTY line to a channel.
@@ -2767,7 +2765,7 @@ static void strip_close(struct tty_struct *tty)
 
     tty->disc_data = 0;
     strip_info->tty = NULL;
-    printk(KERN_INFO "STRIP: device \"%s\" closed down\n", strip_info->if_name.c);
+    printk(KERN_INFO "STRIP: device \"%s\" closed down\n", strip_info->dev.name);
     strip_free(strip_info);
     tty->disc_data = NULL;
 #ifdef MODULE
index 6e7cd9a63c25c939572f762369e2620462afe834..bc4dec29cb3ea8cc52466b619f53b5fa63cc6bb5 100644 (file)
@@ -1348,11 +1348,11 @@ static void tulip_suspend (struct pci_dev *pdev)
                netif_device_detach (dev);
                tulip_down (dev);
        }
-       pci_set_power_state(pdev, 3);
+//     pci_set_power_state(pdev, 3);
 }
 
 
-static void tulip_resume (struct pci_dev *pdev)
+static void tulip_resume(struct pci_dev *pdev)
 {
        struct net_device *dev = pdev->driver_data;
 
index 65a8108891081148cd5334067ade3b44b10b6f48..4190e2ed481e626b34546d1f32b7be2b2e2258db 100644 (file)
@@ -877,7 +877,7 @@ static int comx_mkdir(struct inode *dir, struct dentry *dentry, int mode)
                return -ENOMEM;
        }
        memset(dev, 0, sizeof(struct net_device));
-       dev->name = (char *)new_dir->name;
+       strcpy(dev->name, (char *)new_dir->name);
        dev->init = comx_init_dev;
 
        if (register_netdevice(dev)) {
index 8e0c5d37dc18c67a25828bf5257c456b3091b3fa..6d3f6a8a919d3266f5fc144d98edf91fe8e3c421 100644 (file)
@@ -588,7 +588,7 @@ static void sppp_channel_init(struct channel_data *chan)
        memset(chan->pppdev.dev, 0, sizeof(struct net_device));
        sppp_attach(&chan->pppdev);
        d=chan->pppdev.dev;
-       d->name = chan->name;
+       strcpy(d->name, chan->name);
        d->base_addr = chan->cosa->datareg;
        d->irq = chan->cosa->irq;
        d->dma = chan->cosa->dma;
index 362e7a36eed6312b971ffad0bfb535c4f05715c1..af905fc09979313f84562b22885f45face2701dc 100644 (file)
@@ -441,13 +441,6 @@ int dlci_add(struct dlci_add *dlci)
                return(-ENOMEM);
 
        memset(master, 0, sizeof(*master));
-       master->name = kmalloc(strlen(buf) + 1, GFP_KERNEL);
-
-       if (!master->name)
-       {
-               kfree(master);
-               return(-ENOMEM);
-       }
 
        strcpy(master->name, buf);
        master->init = dlci_init;
@@ -456,7 +449,6 @@ int dlci_add(struct dlci_add *dlci)
        err = register_netdev(master);
        if (err < 0)
        {
-               kfree(master->name);
                kfree(master);
                return(err);
        }
@@ -472,7 +464,6 @@ int dlci_add(struct dlci_add *dlci)
        {
                unregister_netdev(master);
                kfree(master->priv);
-               kfree(master->name);
                kfree(master);
                return(err);
        }
@@ -516,7 +507,6 @@ int dlci_del(struct dlci_add *dlci)
                open_dev[i] = NULL;
 
        kfree(master->priv);
-       kfree(master->name);
        kfree(master);
 
        MOD_DEC_USE_COUNT;
index 6220d7fdd498f5cf6b2c1ca9e22747a92aefe064..a4d038f055223d392be7adc476594b09c7738097 100644 (file)
@@ -44,7 +44,6 @@ struct sv11_device
        void *if_ptr;   /* General purpose pointer (used by SPPP) */
        struct z8530_dev sync;
        struct ppp_device netdev;
-       char name[16];
 };
 
 /*
@@ -279,7 +278,6 @@ static struct sv11_device *sv11_init(int iobase, int irq)
        dev->chanA.netdevice=sv->netdev.dev;
        dev->chanA.dev=dev;
        dev->chanB.dev=dev;
-       dev->name=sv->name;
        
        if(dma)
        {
@@ -323,55 +321,48 @@ static struct sv11_device *sv11_init(int iobase, int irq)
        /*
         *      Now we can take the IRQ
         */
-       
-       for(i=0;i<999;i++)
+       if(dev_alloc_name(dev->chanA.netdevice,"hdlc%d")>=0)
        {
-               sprintf(sv->name,"hdlc%d", i);
-               if(dev_get(sv->name)==0)
-               {
-                       struct net_device *d=dev->chanA.netdevice;
-       
-                       /* 
-                        *      Initialise the PPP components
-                        */
-                       sppp_attach(&sv->netdev);
-                       
-                       /*
-                        *      Local fields
-                        */     
-                       sprintf(sv->name,"hdlc%d", i);
-                       
-                       d->name = sv->name;
-                       d->base_addr = iobase;
-                       d->irq = irq;
-                       d->priv = sv;
-                       d->init = NULL;
-                       
-                       d->open = hostess_open;
-                       d->stop = hostess_close;
-                       d->hard_start_xmit = hostess_queue_xmit;
-                       d->get_stats = hostess_get_stats;
-                       d->set_multicast_list = NULL;
-                       d->do_ioctl = hostess_ioctl;
+               struct net_device *d=dev->chanA.netdevice;
+
+               /* 
+                *      Initialise the PPP components
+                */
+               sppp_attach(&sv->netdev);
+               
+               /*
+                *      Local fields
+                */     
+               
+               d->base_addr = iobase;
+               d->irq = irq;
+               d->priv = sv;
+               d->init = NULL;
+               
+               d->open = hostess_open;
+               d->stop = hostess_close;
+               d->hard_start_xmit = hostess_queue_xmit;
+               d->get_stats = hostess_get_stats;
+               d->set_multicast_list = NULL;
+               d->do_ioctl = hostess_ioctl;
 #ifdef LINUX_21                        
-                       d->neigh_setup = hostess_neigh_setup_dev;
-                       dev_init_buffers(d);
+               d->neigh_setup = hostess_neigh_setup_dev;
+               dev_init_buffers(d);
 #else
-                       d->init = return_0;
+               d->init = return_0;
 #endif
-                       d->set_mac_address = NULL;
-                       
-                       if(register_netdev(d)==-1)
-                       {
-                               printk(KERN_ERR "%s: unable to register device.\n",
-                                       sv->name);
-                               goto fail;
-                       }                               
-
-                       z8530_describe(dev, "I/O", iobase);
-                       dev->active=1;
-                       return sv;      
-               }
+               d->set_mac_address = NULL;
+               
+               if(register_netdev(d)==-1)
+               {
+                       printk(KERN_ERR "%s: unable to register device.\n",
+                               d->name);
+                       goto fail;
+               }                               
+
+               z8530_describe(dev, "I/O", iobase);
+               dev->active=1;
+               return sv;      
        }
 dmafail2:
        if(dma==1)
index 8fd2ff10577ed30e370e1d6a5acd74c2b0ae90c1..68b31868882050fcb7ae579f1e9841f5ab89e27d 100644 (file)
@@ -35,7 +35,6 @@ struct slvl_device
        void *if_ptr;   /* General purpose pointer (used by SPPP) */
        struct z8530_channel *chan;
        struct ppp_device netdev;
-       char name[16];
        int channel;
 };
 
@@ -223,7 +222,6 @@ static struct slvl_board *slvl_init(int iobase, int irq, int txdma, int rxdma, i
        struct slvl_device *sv;
        struct slvl_board *b;
        
-       int i;
        unsigned long flags;
        int u;
        
@@ -306,7 +304,6 @@ static struct slvl_board *slvl_init(int iobase, int irq, int txdma, int rxdma, i
        dev->chanB.netdevice=b->dev[1].netdev.dev;
        dev->chanA.dev=dev;
        dev->chanB.dev=dev;
-       dev->name=b->dev[0].name;
 
        dev->chanA.txdma=3;
        dev->chanA.rxdma=1;
@@ -350,52 +347,46 @@ static struct slvl_board *slvl_init(int iobase, int irq, int txdma, int rxdma, i
                sv=&b->dev[u];
                sv->channel = u;
        
-               for(i=0;i<999;i++)
+               if(dev_alloc_name(sv->chan->netdevice,"hdlc%d")>=0)
                {
-                       sprintf(sv->name,"hdlc%d", i);
-                       if(dev_get(sv->name)==0)
-                       {
-                               struct net_device *d=sv->chan->netdevice;
-       
-                               /* 
-                                *      Initialise the PPP components
-                                */
-                               sppp_attach(&sv->netdev);
-                       
-                               /*
-                                *      Local fields
-                                */     
-                               sprintf(sv->name,"hdlc%d", i);
-                               
-                               d->name = sv->name;
-                               d->base_addr = iobase;
-                               d->irq = irq;
-                               d->priv = sv;
-                               d->init = NULL;
+                       struct net_device *d=sv->chan->netdevice;
+
+                       /* 
+                        *      Initialise the PPP components
+                        */
+                       sppp_attach(&sv->netdev);
+               
+                       /*
+                        *      Local fields
+                        */     
                        
-                               d->open = sealevel_open;
-                               d->stop = sealevel_close;
-                               d->hard_start_xmit = sealevel_queue_xmit;
-                               d->get_stats = sealevel_get_stats;
-                               d->set_multicast_list = NULL;
-                               d->do_ioctl = sealevel_ioctl;
+                       d->base_addr = iobase;
+                       d->irq = irq;
+                       d->priv = sv;
+                       d->init = NULL;
+               
+                       d->open = sealevel_open;
+                       d->stop = sealevel_close;
+                       d->hard_start_xmit = sealevel_queue_xmit;
+                       d->get_stats = sealevel_get_stats;
+                       d->set_multicast_list = NULL;
+                       d->do_ioctl = sealevel_ioctl;
 #ifdef LINUX_21                        
-                               d->neigh_setup = sealevel_neigh_setup_dev;
-                               dev_init_buffers(d);
+                       d->neigh_setup = sealevel_neigh_setup_dev;
+                       dev_init_buffers(d);
 #else
-                               d->init = return_0;
+                       d->init = return_0;
 #endif
-                               d->set_mac_address = NULL;
-                       
-                               if(register_netdev(d)==-1)
-                               {
-                                       printk(KERN_ERR "%s: unable to register device.\n",
-                                               sv->name);
-                                       goto fail_unit;
-                               }                               
+                       d->set_mac_address = NULL;
+               
+                       if(register_netdev(d)==-1)
+                       {
+                               printk(KERN_ERR "%s: unable to register device.\n",
+                                       d->name);
+                               goto fail_unit;
+                       }                               
 
-                               break;
-                       }
+                       break;
                }
        }
        z8530_describe(dev, "I/O", iobase);
index 2162d5ff00f13ac827e42d5322e610a8df91249f..b6be90321d60456313a8c8c090b2c91f1c91f93e 100644 (file)
@@ -4211,7 +4211,6 @@ int init_module(void)
                                break;
                        }
                        memset(dev, 0x00, sizeof(struct net_device));
-                       dev->name = name[i];
                        dev->base_addr = io[i];
                        dev->irq = irq[i];
                        dev->init = &wavelan_config;
index 9507ba615815ce73191b23ce7558edab94620338..1792b1852cfcbe74b40b1fb4800062fb168033e9 100644 (file)
@@ -442,11 +442,9 @@ wd_close(struct net_device *dev)
 \f
 #ifdef MODULE
 #define MAX_WD_CARDS   4       /* Max number of wd cards per module */
-#define NAMELEN                8       /* # of chars for storing dev->name */
-static char namelist[NAMELEN * MAX_WD_CARDS] = { 0, };
 static struct net_device dev_wd[MAX_WD_CARDS] = {
        {
-               NULL,           /* assign a chunk of namelist[] below */
+               "",             /* assign a chunk of namelist[] below */
                0, 0, 0, 0,
                0, 0,
                0, 0, 0, NULL, NULL
@@ -472,7 +470,6 @@ init_module(void)
 
        for (this_dev = 0; this_dev < MAX_WD_CARDS; this_dev++) {
                struct net_device *dev = &dev_wd[this_dev];
-               dev->name = namelist+(NAMELEN*this_dev);
                dev->irq = irq[this_dev];
                dev->base_addr = io[this_dev];
                dev->mem_start = mem[this_dev];
index 2d9788a3178f091734544b59f7b0465113bbf264..15fff1fa86e208cc50b48fb0ceeb1f03bc09caf1 100644 (file)
@@ -4,7 +4,7 @@
 #      Maintained by Martin Mares <pci-ids@ucw.cz>
 #      If you have any new entries, send them to the maintainer.
 #
-#      $Id: pci.ids,v 1.56 2000/04/17 16:11:58 mj Exp $
+#      $Id: pci.ids,v 1.60 2000/05/01 19:53:05 mj Exp $
 #
 
 # Vendors, devices and subsystems. Please keep sorted.
        0046  DECchip 21554
                9005 1364  Dell PowerEdge RAID Controller 2
                9005 1365  Dell PowerEdge RAID Controller 2
-       1065  RAID Controller
+       1065  StrongARM DC21285
+               1069 0020  DAC960P
 1012  Micronics Computers Inc
 1013  Cirrus Logic
        0038  GD 7548
        002d  Python
        002e  ServeRAID controller
        0036  Miami
+       003a  CPU to PCI Bridge
        003e  16/4 Token ring UTP/STP controller
                1014 003e  Token-Ring Adapter
                1014 00cd  Token-Ring Adapter + Wake-On-LAN
                1014 00cf  16/4 Token-Ring Adapter Special
                1014 00e4  High-Speed 100/16/4 Token-Ring Adapter
                1014 00e5  16/4 Token-Ring Adapter 2 + Wake-On-LAN
+       0045  SSA Adapter
        0046  MPIC interrupt controller
        0047  PCI to PCI Bridge
        0048  PCI to PCI Bridge
+       004e  ATM Controller (14104e00)
+       004f  ATM Controller (14104f00)
+       0050  ATM Controller (14105000)
        0053  25 MBit ATM Controller
        0057  MPEG PCI Bridge
        005c  i82557B 10/100
+       007c  ATM Controller (14107c00)
        007d  3780IDSP [MWave]
+       0090  GXT 3000P
+               1014 008E  GXT-3000P
        0095  20H2999 PCI Docking Bridge
+       00a5  ATM Controller (1410a500)
+       00a6  ATM 155MBPS MM Controller (1410a600)
        00b7  256-bit Graphics Rasterizer [Fire GL1]
                1902 00b8  Fire GL1
+       00be  ATM 622MBPS Controller (1410be00)
+       0142  Yotta Video Compositor Input
+               1014 0143 Yotta Input Controller (ytin)
+       0144  Yotta Video Compositor Output
+               1014 0145 Yotta Output Controller (ytout)
        ffff  MPIC-2 interrupt controller
 1015  LSI Logic Corp of Canada
 1016  ICL Personal Systems
        1077  VScom 400 4 port serial adaptor
        9036  9036
        9050  PCI <-> IOBus Bridge
+               10b5 2273  SH-ARC SoHard ARCnet card
                d84d 4006  EX-4006 1P
                d84d 4008  EX-4008 1P EPP/ECP
                d84d 4014  EX-4014 2P
 11ae  Aztech System Ltd
 11af  Avid Technology Inc.
 11b0  V3 Semiconductor Inc.
+       0002  V300PSC
        0292  V292PBC [Am29030/40 Bridge]
        0960  V96xPBC
        c960  V96DPC
        0458  LT WinModem
        0459  LT WinModem
        045a  LT WinModem
-       0480  Venus WinModem (V90, 56KFlex)
+       0480  Venus Modem (V90, 56KFlex)
 11c2  Sand Microelectronics
 11c3  NEC Corp
 11c4  Document Technologies, Inc
                139c 0017  Raven
                14af 0002  Maxi Gamer Phoenix
                3030 3030  Skywell Magic TwinPower
-       0004  Voodoo Banshee
+       0004  Voodoo Banshee [Velocity 100]
        0005  Voodoo 3
                121a 0004  Voodoo3 AGP
                121a 0030  Voodoo3 AGP
 12ad  Multidata GmbH
 12ae  Alteon Networks Inc.
        0001  AceNIC Gigabit Ethernet
+               1410 0104  Gigabit Ethernet-SX PCI Adapter (14100401)
 12af  TDK USA Corp
 12b0  Jorge Scientific Corp
 12b1  GammaLink
 156f  M-Systems Flash Disk Pioneers Ltd
 1570  Lecroy Corp
 1571  Contemporary Controls
+       a001  CCSI PCI20-485 ARCnet
+       a002  CCSI PCI20-485D ARCnet
+       a003  CCSI PCI20-485X ARCnet
+       a004  CCSI PCI20-CXB ARCnet
+       a005  CCSI PCI20-CXS ARCnet
+       a006  CCSI PCI20-FOG-SMA ARCnet
+       a007  CCSI PCI20-FOG-ST ARCnet
+       a008  CCSI PCI20-TB5 ARCnet
+       a009  CCSI PCI20-5-485 5Mbit ARCnet
+       a00a  CCSI PCI20-5-485D 5Mbit ARCnet
+       a00b  CCSI PCI20-5-485X 5Mbit ARCnet
+       a00c  CCSI PCI20-5-FOG-ST 5Mbit ARCnet
+       a00d  CCSI PCI20-5-FOG-SMA 5Mbit ARCnet
+       a201  CCSI PCI22-485 10Mbit ARCnet
+       a202  CCSI PCI22-485D 10Mbit ARCnet
+       a203  CCSI PCI22-485X 10Mbit ARCnet
+       a204  CCSI PCI22-CHB 10Mbit ARCnet
+       a205  CCSI PCI22-FOG_ST 10Mbit ARCnet
+       a206  CCSI PCI22-THB 10Mbit ARCnet
 1572  Otis Elevator Company
 1573  Lattice - Vantis
 1574  Fairchild Semiconductor
 45fb  Baldor Electric Company
 4680  Umax Computer Corp
 4843  Hercules Computer Technology Inc
+4916  RedCreek Communications Inc
+       1960  RedCreek PCI adapter
 4943  Growth Networks
 4978  Axil Computer Inc
 4a14  NetVin
@@ -4728,6 +4768,7 @@ C 02  Network controller
        01  Token ring network controller
        02  FDDI network controller
        03  ATM network controller
+       04  ISDN controller
        80  Network controller
 C 03  Display controller
        00  VGA compatible controller
@@ -4759,6 +4800,10 @@ C 06  Bridge
        08  RACEway bridge
                00  Transparent mode
                01  Endpoint mode
+       09  Semi-transparent PCI-to-PCI bridge
+               40  Primary bus towards host CPU
+               80  Secondary bus towards host CPU
+       0a  InfiniBand to PCI host bridge
        80  Bridge
 C 07  Communication controller
        00  Serial controller
@@ -4836,6 +4881,7 @@ C 0c  Serial bus controller
                Fe  USB Device
        04  Fiber Channel
        05  SMBus
+       06  InfiniBand
 C 0d  Wireless controller
        00  IRDA controller
        01  Consumer IR controller
@@ -4850,8 +4896,10 @@ C 0f  Satellite communications controller
        04  Satellite data communication controller
 C 10  Encryption controller
        00  Network and computing encryption device
-       01  Entertainment encryption device
+       10  Entertainment encryption device
        80  Encryption controller
 C 11  Signal processing controller
        00  DPIO module
+       01  Performance counters
+       10  Communication synchronizer
        80  Signal processing controller
index 067e25647fbbeba49f5bd6c86de01b4cb4a04842..703b8c138f52ac653d8cf018c48997c6da0395f7 100644 (file)
@@ -389,7 +389,7 @@ static int pci_read_proc(char *buf, char **start, off_t off,
 
        *eof = 1;
        pci_for_each_dev(dev) {
-               nprinted = sprint_dev_config(dev, buf + len, count - len);
+               nprinted = sprint_dev_config(dev, buf + len, PAGE_SIZE - len);
                if (nprinted < 0) {
                        *eof = 0;
                        break;
index 33a6ce1b92350619a3f2fee6a808e9ee1a612fa9..43e47c75b21f5e707e24a01429720b9e5e245396 100644 (file)
@@ -231,7 +231,7 @@ static void setup_erase_request(client_handle_t handle, eraseq_entry_t *erase)
            busy = kmalloc(sizeof(erase_busy_t), GFP_KERNEL);
            busy->erase = erase;
            busy->client = handle;
-           busy->timeout.prev = busy->timeout.next = NULL;
+           init_timer(&busy->timeout);
            busy->timeout.data = (u_long)busy;
            busy->timeout.function = &handle_erase_timeout;
            busy->prev = busy->next = NULL;
index c536f22c668a6a470c4056f6eb2ff8a600c32d63..11e4330c512bc33ffa51ecbad0cffc3b79f81a32 100644 (file)
@@ -897,7 +897,7 @@ int __init init_pcmcia_ds(void)
        init_waitqueue_head(&s->queue);
        init_waitqueue_head(&s->request);
        s->handle = NULL;
-       s->removal.prev = s->removal.next = NULL;
+       init_timer(&s->removal);
        s->removal.data = i;
        s->removal.function = &handle_removal;
        s->bind = NULL;
index 8939ea9f6652bd3a377eb333915547852e3ed961..67abc32e6bb305b5854884090d1cafd0da5751fa 100644 (file)
@@ -450,7 +450,7 @@ static int __init init_tcic(void)
     /* Set up polling */
     poll_timer.function = &tcic_timer;
     poll_timer.data = 0;
-    poll_timer.prev = poll_timer.next = NULL;
+    init_timer(&poll_timer);
 
     /* Build interrupt mask */
     printk(", %d sockets\n" KERN_INFO "  irq list (", sockets);
index 6f5a383cd3382fe62de8eb0116afbd1595be9c7c..75b78a8b91614be7c29f94a4b5b7583b00a4844b 100644 (file)
@@ -284,7 +284,7 @@ struct trident_card {
        /* Function support */
        struct trident_channel *(*alloc_pcm_channel)(struct trident_card *);
        struct trident_channel *(*alloc_rec_pcm_channel)(struct trident_card *);
-       void (*free_pcm_channel)(struct trident_card *, int chan);
+       void (*free_pcm_channel)(struct trident_card *, unsigned int chan);
        void (*address_interrupt)(struct trident_card *);
 };
 
@@ -434,13 +434,19 @@ static void trident_stop_voice(struct trident_card * card, unsigned int channel)
 #endif
 }
 
-static int trident_check_channel_interrupt(struct trident_card * card, int channel)
+static u32 trident_get_interrupt_mask (struct trident_card * card,
+                                      unsigned int b)
 {
-       unsigned int mask = 1 << (channel & 0x1f);
-       struct trident_pcm_bank *bank = &card->banks[channel >> 5];
-       u32 reg, addr = bank->addresses->aint;
+       struct trident_pcm_bank *bank = &card->banks[b];
+       u32 addr = bank->addresses->aint;
+       return inl(TRID_REG(card, addr));
+}
 
-       reg = inl(TRID_REG(card, addr));
+static int trident_check_channel_interrupt(struct trident_card * card,
+                                          unsigned int channel)
+{
+       unsigned int mask = 1 << (channel & 0x1f);
+       u32 reg = trident_get_interrupt_mask (card, channel >> 5);
 
 #ifdef DEBUG
        if (reg & mask)
@@ -450,7 +456,8 @@ static int trident_check_channel_interrupt(struct trident_card * card, int chann
        return (reg & mask) ? TRUE : FALSE;
 }
 
-static void trident_ack_channel_interrupt(struct trident_card * card, int channel)
+static void trident_ack_channel_interrupt(struct trident_card * card,
+                                         unsigned int channel)
 {
        unsigned int mask = 1 << (channel & 0x1f);
        struct trident_pcm_bank *bank = &card->banks[channel >> 5];
@@ -473,11 +480,7 @@ static struct trident_channel * trident_alloc_pcm_channel(struct trident_card *c
        int idx;
 
        bank = &card->banks[BANK_B];
-       if (bank->bitmap == ~0UL) {
-               /* no more free channels avaliable */
-               printk(KERN_ERR "trident: no more channels available on Bank B.\n");
-               return NULL;
-       }
+
        for (idx = 31; idx >= 0; idx--) {
                if (!(bank->bitmap & (1 << idx))) {
                        struct trident_channel *channel = &bank->channels[idx];
@@ -486,6 +489,9 @@ static struct trident_channel * trident_alloc_pcm_channel(struct trident_card *c
                        return channel;
                }
        }
+
+       /* no more free channels avaliable */
+       printk(KERN_ERR "trident: no more channels available on Bank B.\n");
        return NULL;
 }
 
@@ -496,12 +502,7 @@ static struct trident_channel *ali_alloc_pcm_channel(struct trident_card *card)
 
        bank = &card->banks[BANK_A];
 
-       if (bank->bitmap == ~0UL) {
-               /* no more free channels avaliable */
-               printk(KERN_ERR "trident: no more channels available on Bank B.\n");
-               return NULL;
-       }
-       for (idx = 0; idx <= 31; idx++) {
+       for (idx = ALI_PCM_OUT_CHANNEL_FIRST; idx <= ALI_PCM_OUT_CHANNEL_LAST ; idx++) {
                if (!(bank->bitmap & (1 << idx))) {
                        struct trident_channel *channel = &bank->channels[idx];
                        bank->bitmap |= 1 << idx;
@@ -509,6 +510,9 @@ static struct trident_channel *ali_alloc_pcm_channel(struct trident_card *card)
                        return channel;
                }
        }
+
+       /* no more free channels avaliable */
+       printk(KERN_ERR "trident: no more channels available on Bank B.\n");
        return NULL;
 }
 
@@ -529,7 +533,8 @@ static struct trident_channel *ali_alloc_rec_pcm_channel(struct trident_card *ca
 }
 
 
-static void trident_free_pcm_channel(struct trident_card *card, int channel)
+static void trident_free_pcm_channel(struct trident_card *card,
+                                    unsigned int channel)
 {
        int bank;
 
@@ -539,12 +544,10 @@ static void trident_free_pcm_channel(struct trident_card *card, int channel)
        bank = channel >> 5;
        channel = channel & 0x1f;
 
-       if (card->banks[bank].bitmap & (1 << (channel))) {
-               card->banks[bank].bitmap &= ~(1 << (channel));
-       }
+       card->banks[bank].bitmap &= ~(1 << (channel));
 }
 
-static void ali_free_pcm_channel(struct trident_card *card, int channel)
+static void ali_free_pcm_channel(struct trident_card *card, unsigned int channel)
 {
        int bank;
 
@@ -554,9 +557,7 @@ static void ali_free_pcm_channel(struct trident_card *card, int channel)
        bank = channel >> 5;
        channel = channel & 0x1f;
 
-       if (card->banks[bank].bitmap & (1 << (channel))) {
-               card->banks[bank].bitmap &= ~(1 << (channel));
-       }
+       card->banks[bank].bitmap &= ~(1 << (channel));
 }
 
 
@@ -569,14 +570,16 @@ static int trident_load_channel_registers(struct trident_card *card, u32 *data,
        if (channel > 63)
                return FALSE;
 
-       /* select hardware channel to write */
+       /* select hardware channel to write */
        outb(channel, TRID_REG(card, T4D_LFO_GC_CIR));
-       /* output the channel registers */
+
+       /* Output the channel registers, but don't write register
+          three to an ALI chip. */
+
        for (i = 0; i < CHANNEL_REGS; i++) {
+               if (i == 3 && card->pci_id == PCI_DEVICE_ID_ALI_5451)
+                       continue;
                outl(data[i], TRID_REG(card, CHANNEL_START + 4*i));
-               if (i == 2)
-                       if (card->pci_id == PCI_DEVICE_ID_ALI_5451)
-                               i++;    //skip i=3
        }
 
        return TRUE;
@@ -1229,21 +1232,50 @@ static void trident_address_interrupt(struct trident_card *card)
 static void ali_address_interrupt(struct trident_card *card)
 {
        int i;
-       struct trident_state *state;
-       
+       u32 mask = trident_get_interrupt_mask (card, BANK_A);
+
+#ifdef DEBUG
+       /* Sanity check to make sure that every state has a channel
+          and vice versa. */
+       u32 done = 0;
+       unsigned ns = 0;
+       unsigned nc = 0;
        for (i = 0; i < NR_HW_CH; i++) {
-               if (trident_check_channel_interrupt(card, i)) {
-                       trident_ack_channel_interrupt(card, i);
-                       if ((state = card->states[i]) != NULL) {
-                               state->dmabuf.update_flag |= ALI_ADDRESS_INT_UPDATE;
-                               trident_update_ptr(state);
-                       } else {
+               if (card->banks[BANK_A].bitmap & (1<<i))
+                       nc ++;
+
+               if (card->states[i]) {
+                       u32 bit = 1 << card->states[i]->dmabuf.channel->num;
+                       if (bit & done) 
+                               printk (KERN_ERR "trident: channel allocated to two states\n");
+                       ns++;
+
+                       done |= bit;
+               }
+       }
+       if (ns != nc) 
+               printk (KERN_ERR "trident: number of states != number of channels\n");
+#endif
+
+       for (i = 0; mask && i < NR_HW_CH; i++) {                        
+               struct trident_state *state = card->states[i];
+               if (!state)
+                       continue;
+
+               trident_ack_channel_interrupt(card, state->dmabuf.channel->num);
+               mask &= ~ (1<<state->dmabuf.channel->num);
+               state->dmabuf.update_flag |= ALI_ADDRESS_INT_UPDATE;
+               trident_update_ptr(state);
+       }
+
+       if (mask) 
+               for (i = 0; i < NR_HW_CH; i++)
+                       if (mask & (1<<i)) {
                                printk("ali: spurious channel irq %d.\n", i);
                                trident_stop_voice(card, i);
                                trident_disable_voice_irq(card, i);
                        }
-               }
-       }
+
 }
 
 static void trident_interrupt(int irq, void *dev_id, struct pt_regs *regs)
@@ -1897,7 +1929,7 @@ static int trident_open(struct inode *inode, struct file *file)
                
        if (dmabuf->channel == NULL) {
                kfree (card->states[i]);
-               card->states[i] = NULL;;
+               card->states[i] = NULL;
                return -ENODEV;
        }
 
@@ -1954,6 +1986,11 @@ static int trident_open(struct inode *inode, struct file *file)
        state->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
        up(&state->open_sem);
 
+#ifdef DEBUG
+       printk(KERN_ERR "trident: open virtual channel %d, hard channel %d\n", 
+              state->virt,
+              dmabuf->channel->num);
+#endif
        MOD_INC_USE_COUNT;
        return 0;
 }
index dc8239b0efa9843b693e4791f47cf889a5cf4d2d..a35563622a22e9109a0a80fea64a7dda8bcfc801 100644 (file)
@@ -103,6 +103,11 @@ enum ali_pcm_in_channel_num {
        ALI_PCM_IN_CHANNEL      = 31
 };
 
+enum ali_pcm_out_channel_num {
+       ALI_PCM_OUT_CHANNEL_FIRST = 1,
+       ALI_PCM_OUT_CHANNEL_LAST = 30
+};
+
 enum ali_ac97_power_control_bit {
        ALI_EAPD_POWER_DOWN     = 0x8000
 };
index 821dedb4aecb9859a5db9d22531c0cc71f9411f2..534325986c1bdeb25177b5d8d206f045d170eb93 100644 (file)
@@ -406,6 +406,7 @@ static void usb_hub_port_connect_change(struct usb_device *hub, int port)
 
        /* Run it through the hoops (find a driver, etc) */
        if (usb_new_device(usb)) {
+               usb_disconnect(&hub->children[port]);
                /* Woops, disable the port */
                dbg("hub: disabling port %d", port + 1);
                usb_clear_port_feature(hub, port + 1, USB_PORT_FEAT_ENABLE);
index 233f7943b266b317b7bf4f8e8da497bb5bb62e87..5ba9869e93e3c44899c1ceff497e27480d249a61 100644 (file)
@@ -46,7 +46,7 @@ static unsigned short x86_keycodes[256] =
         32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
         48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
         64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
-        80, 81, 82, 83, 89, 85, 86, 87, 88,115,119,120,121,375,123, 90,
+        80, 81, 82, 83, 43, 85, 86, 87, 88,115,119,120,121,375,123, 90,
        284,285,309,298,312, 91,327,328,329,331,333,335,336,337,338,339,
        367,294,293,286,350, 92,334,512,116,377,109,111,373,347,348,349,
        360, 93, 94, 95, 98,376,100,101,357,316,354,304,289,102,351,355,
index 26db93b4f5b3a664c9bcc31e44ca8bf1511c097c..d80385bad75f00a7c10d1c064626fdaa3675984e 100644 (file)
@@ -418,10 +418,8 @@ static struct input_handle *mousedev_connect(struct input_handler *handler, stru
 
        mousedev->devfs = input_register_minor("mouse%d", minor, MOUSEDEV_MINOR_BASE);
 
-       if (mousedev_mix.open) {
+       if (mousedev_mix.open)
                input_open_device(&mousedev->handle);
-               mousedev_mix.open++;
-       }
 
        printk("mouse%d: PS/2 mouse device for input%d\n", minor, dev->number);
 
@@ -432,10 +430,8 @@ static void mousedev_disconnect(struct input_handle *handle)
 {
        struct mousedev *mousedev = handle->private;
 
-       if (mousedev->open || mousedev_mix.open) {
+       if (mousedev->open || mousedev_mix.open)
                input_close_device(handle);
-               mousedev_mix.open--;
-       }
 
        if (!--mousedev->used) {
                input_unregister_minor(mousedev->devfs);
index 666752f764dd6bff2fd9bb315e99f7f8a99e09f6..38021887eca9f8ae3def2fd333a3e2851f1f0327 100644 (file)
@@ -1,7 +1,7 @@
 /* -*- linux-c -*- */
 
 /* 
- * Driver for USB Scanners (linux-2.3.99-pre3-7)
+ * Driver for USB Scanners (linux-2.3.99-pre6-3)
  *
  * Copyright (C) 1999, 2000 David E. Nelson
  *
@@ -54,7 +54,7 @@
  *    - Removed unnessesary #include's
  *    - Scanner model now reported via syslog INFO after being detected 
  *      *and* configured.
- *    - Added user specified verdor:product USB ID's which can be passed 
+ *    - Added user specified vendor:product USB ID's which can be passed 
  *      as module parameters.
  *
  *
  *      -EINTR.
  *
  *
+ * 0.4.3  4/30/2000
+ *
+ *    - Added Umax Astra 2200 ID.  Thanks to Flynn Marquardt 
+ *      <flynn@isr.uni-stuttgart.de>.
+ *    - Added iVina 1200U ID. Thanks to Dyson Lin <dyson@avision.com.tw>.
+ *    - Added access time update for the device file courtesy of Paul
+ *      Mackerras <paulus@linuxcare.com>.  This allows a user space daemon
+ *      to turn the lamp off for a Umax 1220U scanner after a prescribed
+ *      time.
+ *    - Fixed HP S20 ID's.  Thanks to Ruud Linders <rlinders@xs4all.nl>.
+ *    - Added Acer ScanPrisa 620U ID. Thanks to Oliver
+ *      Schwartz <Oliver.Schwartz@gmx.de> via sane-devel mail list.
+ *    - Fixed bug in read_scanner for copy_to_user() function.  The returned
+ *      value should be 'partial' not 'this_read'.
+ *    - Fixed bug in read_scanner. 'count' should be decremented 
+ *      by 'this_read' and not by 'partial'.  This resulted in twice as many
+ *      calls to read_scanner() for small amounts of data and possibly
+ *      unexpected returns of '0'.  Thanks to Karl Heinz 
+ *      Kremer <khk@khk.net> and Alain Knaff <Alain.Knaff@ltnb.lu>
+ *      for discovering this.
+ *    - Integrated Randy Dunlap's <randy.dunlap@intel.com> patch for a
+ *      scanner lookup/ident table. Thanks Randy.
+ *    - Documentation updates.
+ *    - Added wait queues to read_scanner().
+ *
+ *
  *  TODO
  *
  *    - Performance
  *    - Johannes Erdfelt for the loaning of a USB analyzer for tracking an
  *      issue with HP-4100 and uhci.
  *    - Adolfo Montero for his assistance.
- *    - And anybody else who chimed in with reports and suggestions.
+ *    - All the folks who chimed in with reports and suggestions.
+ *    - All the developers that are working on USB SANE backends or other
+ *      applications to use USB scanners.
  *
  *  Performance:
  *
  *       8 Bit Gray  ~ 17 secs - 4.2 Mbit/sec
  */
 
+/* 
+ * Scanner definitions, macros, module info, 
+ * debug/ioctl/data_dump enable, and other constants.
+ */ 
 #include "scanner.h"
 
-
 static void
 irq_scanner(struct urb *urb)
 {
 
 /*
  * For the meantime, this is just a placeholder until I figure out what
- * all I want to do with it.
+ * all I want to do with it -- or somebody else for that matter.
  */
 
        struct scn_usb_data *scn = urb->context;
@@ -234,7 +265,7 @@ open_scanner(struct inode * inode, struct file * file)
        dbg("open_scanner: scn_minor:%d", scn_minor);
 
        if (!p_scn_table[scn_minor]) {
-               err("open_scanner(%d): invalid scn_minor", scn_minor);
+               err("open_scanner(%d): Unable to access minor data", scn_minor);
                return -ENODEV;
        }
 
@@ -243,17 +274,22 @@ open_scanner(struct inode * inode, struct file * file)
        dev = scn->scn_dev;
 
        if (!dev) {
+               err("open_scanner(%d): Scanner device not present", scn_minor);
                return -ENODEV;
        }
 
        if (!scn->present) {
+               err("open_scanner(%d): Scanner is not present", scn_minor);
                return -ENODEV;
        }
 
        if (scn->isopen) {
+               err("open_scanner(%d): Scanner device is already open", scn_minor);
                return -EBUSY;
        }
 
+       init_waitqueue_head(&scn->rd_wait_q);
+
        scn->isopen = 1;
 
        file->private_data = scn; /* Used by the read and write metheds */
@@ -316,6 +352,8 @@ write_scanner(struct file * file, const char * buffer,
 
        dev = scn->scn_dev;
 
+       file->f_dentry->d_inode->i_atime = CURRENT_TIME;
+
        while (count > 0) {
 
                if (signal_pending(current)) {
@@ -365,7 +403,6 @@ write_scanner(struct file * file, const char * buffer,
                        bytes_written += partial;
                } else { /* No data written */
                        ret = 0;
-                       bytes_written = 0;
                        break;
                }
        }
@@ -388,6 +425,7 @@ read_scanner(struct file * file, char * buffer,
        int partial;            /* Number of bytes successfully read */
        int this_read;          /* Max number of bytes to read */
        int result;
+       int rd_expire = RD_EXPIRE;
 
        char *ibuf;
 
@@ -402,7 +440,12 @@ read_scanner(struct file * file, char * buffer,
        bytes_read = 0;
        ret = 0;
 
-       while (count) {
+       file->f_dentry->d_inode->i_atime = CURRENT_TIME; /* Update the
+                                                            atime of
+                                                            the device
+                                                            node */
+
+       while (count > 0) {
                if (signal_pending(current)) {
                        ret = -EINTR;
                        break;
@@ -410,13 +453,34 @@ read_scanner(struct file * file, char * buffer,
 
                this_read = (count >= IBUF_SIZE) ? IBUF_SIZE : count;
                
-               result = usb_bulk_msg(dev, usb_rcvbulkpipe(dev, scn->bulk_in_ep), ibuf, this_read, &partial, 120*HZ);
-               dbg("read stats(%d): result:%d this_read:%d partial:%d", scn_minor, result, this_read, partial);
+               result = usb_bulk_msg(dev, usb_rcvbulkpipe(dev, scn->bulk_in_ep), ibuf, this_read, &partial, RD_NAK_TIMEOUT);
+               dbg("read stats(%d): result:%d this_read:%d partial:%d count:%d", scn_minor, result, this_read, partial, count);
 
-               if (result == USB_ST_TIMEOUT) { /* NAK -- shouldn't happen */
-                       warn("read_scanner(%d): NAK received", scn_minor);
-                       ret = -ETIME;
-                       break;
+/* 
+ * Scanners are sometimes inheriently slow since they are mechanical
+ * in nature.  USB bulk reads tend to timeout while the scanner is
+ * positioning, resetting, warming up the lamp, etc if the timeout is
+ * set too low.  A very long timeout parameter for bulk reads was used
+ * to overcome this limitation, but this sometimes resulted in folks
+ * having to wait for the timeout to expire after pressing Ctrl-C from
+ * an application. The user was sometimes left with the impression
+ * that something had hung or crashed when in fact the USB read was
+ * just waiting on data.  So, the below code retains the same long
+ * timeout period, but splits it up into smaller parts so that
+ * Ctrl-C's are acted upon in a reasonable amount of time. 
+ */
+
+               if (result == USB_ST_TIMEOUT && !partial) { /* Timeout
+                                                               and no
+                                                               data */
+                       if (--rd_expire <= 0) {
+                               warn("read_scanner(%d): excessive NAK's received", scn_minor);
+                               ret = -ETIME;
+                               break;
+                       } else {
+                               interruptible_sleep_on_timeout(&scn->rd_wait_q, RD_NAK_TIMEOUT);
+                               continue;
+                       }
                } else if ((result < 0) && (result != USB_ST_DATAUNDERRUN)) {
                        warn("read_scanner(%d): funky result:%d. Please notify the maintainer.", scn_minor, (int)result);
                        ret = -EIO;
@@ -436,19 +500,17 @@ read_scanner(struct file * file, char * buffer,
 #endif
 
                if (partial) { /* Data returned */
-                       if (copy_to_user(buffer, ibuf, this_read)) {
+                       if (copy_to_user(buffer, ibuf, partial)) {
                                ret = -EFAULT;
                                break;
                        }
-                       count -= partial;
-                       bytes_read += partial;
+                       count -= this_read; /* Compensate for short reads */
+                       bytes_read += partial; /* Keep tally of what actually was read */
                        buffer += partial;
-                       
                } else {
                        ret = 0;
                        break;
                }
-               
        }
        
        return ret ? ret : bytes_read;
@@ -462,6 +524,7 @@ probe_scanner(struct usb_device *dev, unsigned int ifnum)
        struct usb_endpoint_descriptor *endpoint;
        
        int ep_cnt;
+       int ix;
 
        kdev_t scn_minor;
 
@@ -497,120 +560,20 @@ probe_scanner(struct usb_device *dev, unsigned int ifnum)
  * Until we detect a device which is pleasing, we silently punt.
  */
 
-       do {
-               if (dev->descriptor.idVendor == 0x03f0) {          /* Hewlett Packard */
-                       if (dev->descriptor.idProduct == 0x0205 || /* 3300C */
-                           dev->descriptor.idProduct == 0x0101 || /* 4100C */
-                           dev->descriptor.idProduct == 0x0105 || /* 4200C */
-                           dev->descriptor.idProduct == 0x0202 || /* PhotoSmart S20 */
-                           dev->descriptor.idProduct == 0x0401 || /* 5200C */
-                           dev->descriptor.idProduct == 0x0201 || /* 6200C */
-                           dev->descriptor.idProduct == 0x0601) { /* 6300C */
-                               valid_device = 1;
-                               break;
-                       }
-               }
-               
-               if (dev->descriptor.idVendor == 0x06bd) {          /* Agfa */
-                       if (dev->descriptor.idProduct == 0x0001 || /* SnapScan 1212U */
-                           dev->descriptor.idProduct == 0x2061 || /* Another SnapScan 1212U (?) */
-                           dev->descriptor.idProduct == 0x0100) { /* SnapScan Touch */
-                               valid_device = 1;
-                               break;
-                       }
-               }
-               
-               if (dev->descriptor.idVendor == 0x1606) {          /* Umax */
-                       if (dev->descriptor.idProduct == 0x0010 || /* Astra 1220U */
-                           dev->descriptor.idProduct == 0x0030 || /* Astra 2000U */
-                           dev->descriptor.idProduct == 0x0002) { /* Astra 1236U */
-                               valid_device = 1;
-                               break;
-                       }
-               }
-               
-               if (dev->descriptor.idVendor == 0x04b8) {          /* Seiko/Epson Corp. */
-                       if (dev->descriptor.idProduct == 0x0101 || /* Perfection 636U and 636Photo */
-                           dev->descriptor.idProduct == 0x0103 || /* Perfection 610 */
-                           dev->descriptor.idProduct == 0x0104) { /* Perfection 1200U and 1200Photo */
-                               valid_device = 1;
-                               break;
-                       }
-               }
-
-               if (dev->descriptor.idVendor == 0x055f) {          /* Mustek */
-                       if (dev->descriptor.idProduct == 0x0001) { /* 1200 CU */
-                               valid_device = 1;
-                               break;
-                       }
-               }
-
-               if (dev->descriptor.idVendor == 0x05da) {          /* Microtek */
-                       if (dev->descriptor.idProduct == 0x0099 || /* ScanMaker X6 - X6U */
-                           dev->descriptor.idProduct == 0x0094 || /* Phantom 336CX - C3 */
-                           dev->descriptor.idProduct == 0x00a0 || /* Phantom 336CX - C3 #2 */
-                           dev->descriptor.idProduct == 0x009a || /* Phantom C6 */
-                           dev->descriptor.idProduct == 0x00a3 || /* ScanMaker V6USL */
-                           dev->descriptor.idProduct == 0x80a3 || /* ScanMaker V6USL #2 */
-                           dev->descriptor.idProduct == 0x80ac) { /* ScanMaker V6UL - SpicyU */
-                               valid_device = 1;
-                               break;
-                       }
-               }
-
-               if (dev->descriptor.idVendor == 0x0461) {          /* Primax/Colorado */
-                       if (dev->descriptor.idProduct == 0x0300 || /* G2-300 #1 */
-                           dev->descriptor.idProduct == 0x0380 || /* G2-600 #1 */
-                           dev->descriptor.idProduct == 0x0301 || /* G2E-300 */
-                           dev->descriptor.idProduct == 0x0381 || /* ReadyScan 636i */
-                           dev->descriptor.idProduct == 0x0302 || /* G2-300 #2 */
-                           dev->descriptor.idProduct == 0x0382 || /* G2-600 #2 */
-                           dev->descriptor.idProduct == 0x0303 || /* G2E-300 */
-                           dev->descriptor.idProduct == 0x0383 || /* G2E-600 */
-                           dev->descriptor.idProduct == 0x0340 || /* Colorado USB 9600 */
-                           dev->descriptor.idProduct == 0x0360 || /* Colorado USB 19200 */
-                           dev->descriptor.idProduct == 0x0341 || /* Colorado 600u */
-                           dev->descriptor.idProduct == 0x0361) { /* Colorado 1200u */
-                               valid_device = 1;
-                               break;
-                       }
-               }
-               
-               if (dev->descriptor.idVendor == 0x04a7) {          /* Visioneer */
-                       if (dev->descriptor.idProduct == 0x0221 || /* OneTouch 5300 */
-                           dev->descriptor.idProduct == 0x0221 || /* OneTouch 7600 */
-                           dev->descriptor.idProduct == 0x0231) { /* 6100 */
-                               valid_device = 1;
-                               break;
-                       }
-               }
-               
-               if (dev->descriptor.idVendor == 0x0458) {          /* Genius */
-                       if(dev->descriptor.idProduct == 0x2001) { /* ColorPage-Vivid Pro */
-                               valid_device = 1;
-                               break;
-                       }
-               }
-               
-               if (dev->descriptor.idVendor == 0x04a5) {          /* Acer */
-                       if(dev->descriptor.idProduct == 0x2060) { /* Prisa Acerscan 620U */
-                               valid_device = 1;
-                               break;
-                       }
-               }
-               
-               if (dev->descriptor.idVendor == vendor &&   /* User specified */
-                   dev->descriptor.idProduct == product) { /* User specified */
+       for (ix = 0; ix < sizeof (scanner_device_ids) / sizeof (struct scanner_device); ix++) {
+               if ((dev->descriptor.idVendor == scanner_device_ids [ix].idVendor) &&
+                   (dev->descriptor.idProduct == scanner_device_ids [ix].idProduct)) {
                        valid_device = 1;
                        break;
-               }
-               
-               
-       } while (0);
+                }
+       }
+       if (dev->descriptor.idVendor == vendor &&   /* User specified */
+           dev->descriptor.idProduct == product) { /* User specified */
+               valid_device = 1;
+       }
        
-       if (!valid_device)      
-               return NULL;    /* We didn't find anything pleasing */
-
+        if (!valid_device)
+                return NULL;    /* We didn't find anything pleasing */
 
 /*
  * After this point we can be a little noisy about what we are trying to
index d4dd607b7313eb78f5f7271acc59e5f011a6d292..f8a4d2163645dc220f0b6ca56eb1218df65ba27a 100644 (file)
@@ -1,3 +1,26 @@
+/*
+ * Driver for USB Scanners (linux-2.3.99-pre6-3)
+ *
+ * Copyright (C) 1999, 2000 David E. Nelson
+ *
+ * David E. Nelson (dnelson@jump.net)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */ 
+
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/malloc.h>
 #include <linux/delay.h>
 #include <linux/ioctl.h>
+#include <linux/sched.h>
 
 // #define DEBUG
 
+#include <linux/usb.h>
+
+static __s32 vendor=-1, product=-1;
+
+MODULE_AUTHOR("David E. Nelson, dnelson@jump.net, http://www.jump.net/~dnelson");
+MODULE_DESCRIPTION("USB Scanner Driver");
+
+MODULE_PARM(vendor, "i");
+MODULE_PARM_DESC(vendor, "User specified USB idVendor");
+
+MODULE_PARM(product, "i");
+MODULE_PARM_DESC(product, "User specified USB idProduct");
+
+
 /* Enable to activate the ioctl interface.  This is mainly meant for */
 /* development purposes until an ioctl number is officially registered */
 // #define SCN_IOCTL
 
-#include <linux/usb.h>
-// #include "usb.h"
-
 /* WARNING: These DATA_DUMP's can produce a lot of data. Caveat Emptor. */
 // #define RD_DATA_DUMP /* Enable to dump data - limited to 24 bytes */
 // #define WR_DATA_DUMP /* DEBUG does not have to be defined. */
 #define IBUF_SIZE 32768
 #define OBUF_SIZE 4096
 
+/* read_scanner timeouts -- RD_NAK_TIMEOUT * RD_EXPIRE = Number of seconds */
+#define RD_NAK_TIMEOUT (10*HZ) /* Number of X seconds to wait */
+#define RD_EXPIRE 12           /* Number of attempts to wait X seconds */
 
-/* FIXME: These are NOT registered ioctls()'s */
 
+/* FIXME: These are NOT registered ioctls()'s */
 #define PV8630_IOCTL_INREQUEST 69
 #define PV8630_IOCTL_OUTREQUEST 70
 
@@ -55,19 +93,74 @@ struct scn_usb_data {
        char present;           /* Not zero if device is present */
        char *obuf, *ibuf;      /* transfer buffers */
        char bulk_in_ep, bulk_out_ep, intr_ep; /* Endpoint assignments */
+       wait_queue_head_t rd_wait_q; /* read timeouts */
 };
 
 static struct scn_usb_data *p_scn_table[SCN_MAX_MNR] = { NULL, /* ... */};
 
-MODULE_AUTHOR("David E. Nelson, dnelson@jump.net, http://www.jump.net/~dnelson");
-MODULE_DESCRIPTION("USB Scanner Driver");
-
-static __s32 vendor=-1, product=-1;
-MODULE_PARM(vendor, "i");
-MODULE_PARM_DESC(vendor, "User specified USB idVendor");
-
-MODULE_PARM(product, "i");
-MODULE_PARM_DESC(product, "User specified USB idProduct");
+/* table of scanners that may work with this driver */
+static const struct scanner_device {
+       __u16           idVendor;
+       __u16           idProduct;
+} scanner_device_ids [] = {
+       /* Acer */
+               { 0x04a5, 0x2060 },     /* Prisa Acerscan 620U & 640U (!) */
+               { 0x04a5, 0x2040 },     /* Prisa AcerScan 620U (!) */
+       /* Agfa */
+               { 0x06bd, 0x0001 },     /* SnapScan 1212U */
+               { 0x06bd, 0x2061 },     /* Another SnapScan 1212U (?) */
+               { 0x06bd, 0x0100 },     /* SnapScan Touch */
+       /* Colorado -- See Primax/Colorado below */
+       /* Epson -- See Seiko/Epson below */
+       /* Genius */
+               { 0x0458, 0x2001 },     /* ColorPage-Vivid Pro */
+       /* Hewlett Packard */
+               { 0x03f0, 0x0205 },     /* 3300C */
+               { 0x03f0, 0x0101 },     /* 4100C */
+               { 0x03f0, 0x0105 },     /* 4200C */
+               { 0x03f0, 0x0202 },     /* PhotoSmart S20 */
+               { 0x03f0, 0x0401 },     /* 5200C */
+               { 0x03f0, 0x0201 },     /* 6200C */
+               { 0x03f0, 0x0601 },     /* 6300C */
+       /* iVina */
+               { 0x0638, 0x0268 },     /* 1200U */
+       /* Microtek */
+               { 0x05da, 0x0099 },     /* ScanMaker X6 - X6U */
+               { 0x05da, 0x0094 },     /* Phantom 336CX - C3 */
+               { 0x05da, 0x00a0 },     /* Phantom 336CX - C3 #2 */
+               { 0x05da, 0x009a },     /* Phantom C6 */
+               { 0x05da, 0x00a3 },     /* ScanMaker V6USL */
+               { 0x05da, 0x80a3 },     /* ScanMaker V6USL #2 */
+               { 0x05da, 0x80ac },     /* ScanMaker V6UL - SpicyU */
+       /* Mustek */
+               { 0x055f, 0x0001 },     /* 1200 CU */
+       /* Primax/Colorado */
+               { 0x0461, 0x0300 },     /* G2-300 #1 */
+               { 0x0461, 0x0380 },     /* G2-600 #1 */
+               { 0x0461, 0x0301 },     /* G2E-300 #1 */
+               { 0x0461, 0x0381 },     /* ReadyScan 636i */
+               { 0x0461, 0x0302 },     /* G2-300 #2 */
+               { 0x0461, 0x0382 },     /* G2-600 #2 */
+               { 0x0461, 0x0303 },     /* G2E-300 #2 */
+               { 0x0461, 0x0383 },     /* G2E-600 */
+               { 0x0461, 0x0340 },     /* Colorado USB 9600 */
+               { 0x0461, 0x0360 },     /* Colorado USB 19200 */
+               { 0x0461, 0x0341 },     /* Colorado 600u */
+               { 0x0461, 0x0361 },     /* Colorado 1200u */
+       /* Seiko/Epson Corp. */
+               { 0x04b8, 0x0101 },     /* Perfection 636U and 636Photo */
+               { 0x04b8, 0x0103 },     /* Perfection 610 */
+               { 0x04b8, 0x0104 },     /* Perfection 1200U and 1200Photo */
+       /* Umax */
+               { 0x1606, 0x0010 },     /* Astra 1220U */
+               { 0x1606, 0x0002 },     /* Astra 1236U */
+               { 0x1606, 0x0030 },     /* Astra 2000U */
+               { 0x1606, 0x0230 },     /* Astra 2200U */
+       /* Visioneer */
+               { 0x04a7, 0x0221 },     /* OneTouch 5300 */
+               { 0x04a7, 0x0221 },     /* OneTouch 7600 duplicate ID (!) */
+               { 0x04a7, 0x0231 },     /* 6100 */
+};
 
 /* Forward declarations */
 static struct usb_driver scanner_driver;
index d64672049dfc9840144355948c1a600252cd772a..563151dbe193927a6080704b9bef059e65915001 100644 (file)
@@ -1929,9 +1929,10 @@ static int rh_unlink_urb(struct urb *urb)
 {
        struct uhci *uhci = (struct uhci *)urb->dev->bus->hcpriv;
 
-       uhci->rh.send = 0;
-       del_timer(&uhci->rh.rh_int_timer);
-
+       if (uhci->rh.urb == urb) {
+               uhci->rh.send = 0;
+               del_timer(&uhci->rh.rh_int_timer);
+       }
        return 0;
 }
 /*-------------------------------------------------------------------*/
@@ -2182,7 +2183,7 @@ static struct uhci *alloc_uhci(unsigned int io_addr, unsigned int io_size)
         * us a reasonable dynamic range for irq latencies.
         */
        for (i = 0; i < 1024; i++) {
-               struct uhci_td *irq = &uhci->skel_int2_td;
+               struct uhci_td *irq = &uhci->skel_int1_td;
 
                if (i & 1) {
                        irq++;
index e6f3a55c789d9c30ca0897dcf980569ec86ba8e9..50388dccf9d7ff1c8f02ed11a1346b4de24b5856 100644 (file)
@@ -520,6 +520,9 @@ static int sohci_unlink_urb (urb_t * urb)
        if (!urb) /* just to be sure */ 
                return -EINVAL;
                
+       if (!urb->dev || !urb->dev->bus)
+               return -ENODEV;
+
        ohci = (ohci_t *) urb->dev->bus->hcpriv; 
 
 #ifdef DEBUG
@@ -530,12 +533,14 @@ static int sohci_unlink_urb (urb_t * urb)
                return rh_unlink_urb (urb); /* a request to the virtual root hub */
        
        if (urb->hcpriv) { 
-               if (urb->status == USB_ST_URB_PENDING) { /* URB active? */
+               /* URB active? */
+               if (urb->status == USB_ST_URB_PENDING && !ohci->disabled) {
                        urb_priv_t  * urb_priv = urb->hcpriv;
                        urb_priv->state = URB_DEL; 
 
                        /* we want to delete the TDs of an URB from an ed 
-                        * request the deletion, it will be handled at the next USB-frame */
+                        * request the deletion, it will be handled at the
+                        * next USB-frame */
                        
                        spin_lock_irqsave (&usb_ed_lock, flags);
                        ep_rm_ed (urb->dev, urb_priv->ed);
@@ -549,6 +554,10 @@ static int sohci_unlink_urb (urb_t * urb)
                        remove_wait_queue (&op_wakeup, &wait); 
                } else 
                        urb_rm_priv (urb);
+
+               urb->status = -ENOENT;  // mark urb as killed           
+               if (urb->complete)
+                       urb->complete ((struct urb *) urb);
                usb_dec_dev_use (urb->dev);             
        }       
        return 0;
@@ -1274,7 +1283,7 @@ static __u8 root_hub_dev_des[] =
 {
        0x12,       /*  __u8  bLength; */
        0x01,       /*  __u8  bDescriptorType; Device */
-       0x00,       /*  __u16 bcdUSB; v1.0 */
+       0x10,       /*  __u16 bcdUSB; v1.1 */
        0x01,
        0x09,       /*  __u8  bDeviceClass; HUB_CLASSCODE */
        0x00,       /*  __u8  bDeviceSubClass; */
@@ -1323,7 +1332,7 @@ static __u8 root_hub_config_des[] =
        0x05,       /*  __u8  ep_bDescriptorType; Endpoint */
        0x81,       /*  __u8  ep_bEndpointAddress; IN Endpoint 1 */
        0x03,       /*  __u8  ep_bmAttributes; Interrupt */
-       0x08,       /*  __u16 ep_wMaxPacketSize; 8 Bytes */
+       0x02,       /*  __u16 ep_wMaxPacketSize; ((MAX_ROOT_PORTS + 1) / 8 */
        0x00,
        0xff        /*  __u8  ep_bInterval; 255 ms */
 };
@@ -1622,8 +1631,10 @@ static int rh_unlink_urb (urb_t * urb)
 {
        ohci_t * ohci = urb->dev->bus->hcpriv;
  
-       ohci->rh.send = 0;
-       del_timer (&ohci->rh.rh_int_timer);
+       if (ohci->rh.urb == urb) {
+               ohci->rh.send = 0;
+               del_timer (&ohci->rh.rh_int_timer);
+       }
        return 0;
 }
  
@@ -1782,11 +1793,29 @@ static void hc_interrupt (int irq, void * __ohci, struct pt_regs * r)
 
 /*-------------------------------------------------------------------------*/
 
+/* reinitialize after controller reset */
+
+static void hc_reinit_ohci (ohci_t *ohci)
+{
+       int i;
+
+       /* for load balancing of the interrupt branches */
+       for (i = 0; i < NUM_INTS; i++) ohci->ohci_int_load[i] = 0;
+       for (i = 0; i < NUM_INTS; i++) ohci->hcca.int_table[i] = 0;
+       
+       ohci->ed_rm_list [0] = NULL;
+       ohci->ed_rm_list [1] = NULL;
+
+       /* end of control and bulk lists */      
+       ohci->ed_isotail     = NULL;
+       ohci->ed_controltail = NULL;
+       ohci->ed_bulktail    = NULL;
+} 
+
 /* allocate OHCI */
 
 static ohci_t * hc_alloc_ohci (void * mem_base)
 {
-       int i;
        ohci_t * ohci;
        struct usb_bus * bus;
 
@@ -1799,15 +1828,6 @@ static ohci_t * hc_alloc_ohci (void * mem_base)
        ohci->irq = -1;
        ohci->regs = mem_base;   
 
-       /* for load ballancing of the interrupt branches */
-       for (i = 0; i < NUM_INTS; i++) ohci->ohci_int_load[i] = 0;
-       for (i = 0; i < NUM_INTS; i++) ohci->hcca.int_table[i] = 0;
-       
-       /* end of control and bulk lists */      
-       ohci->ed_isotail     = NULL;
-       ohci->ed_controltail = NULL;
-       ohci->ed_bulktail    = NULL;
-
        bus = usb_alloc_bus (&sohci_device_operations);
        if (!bus) {
                free_pages ((unsigned long) ohci, 1);
@@ -1820,6 +1840,7 @@ static ohci_t * hc_alloc_ohci (void * mem_base)
        return ohci;
 } 
 
+
 /*-------------------------------------------------------------------------*/
 
 /* De-allocate all resources.. */
@@ -1977,15 +1998,47 @@ static int handle_pm_event (struct pm_dev *dev, pm_request_t rqst, void *data)
        if (ohci) {
                switch (rqst) {
                case PM_SUSPEND:
-                       dbg("USB-Bus suspend: %p", ohci);
-                       writel (ohci->hc_control = 0xFF, &ohci->regs->control);
+                       /* act as if usb suspend can always be used */
+                       dbg("USB suspend: %p", ohci->regs);
+                       ohci->hc_control = OHCI_USB_SUSPEND;
+                       writel (ohci->hc_control, &ohci->regs->control);
                        wait_ms (10);
                        break;
+
                case PM_RESUME:
-                       dbg("USB-Bus resume: %p", ohci);
-                       writel (ohci->hc_control = 0x7F, &ohci->regs->control);
-                       wait_ms (20);
-                       writel (ohci->hc_control = 0xBF, &ohci->regs->control);
+                       /* did we suspend, or were we powered off? */
+                       ohci->hc_control = readl (&ohci->regs->control);
+                       temp = ohci->hc_control & OHCI_CTRL_HCFS;
+                       switch (temp) {
+
+                       case OHCI_USB_RESET:    // lost power
+                               dbg("USB reset: %p", ohci->regs);
+                               ohci->disabled = 1;
+                               if (ohci->bus->root_hub)
+                                       usb_disconnect (&ohci->bus->root_hub);
+                               hc_reinit_ohci (ohci);
+                               if ((temp = hc_reset (ohci)) < 0
+                                       || (temp = hc_start (ohci)) < 0) {
+                                       ohci->disabled = 1;
+                                       err ("can't restart, %d", temp);
+                               }
+                               dbg ("reset done");
+                               break;
+
+                       case OHCI_USB_SUSPEND:  // host wakeup
+                       case OHCI_USB_RESUME:   // remote wakeup
+                               dbg("USB resume: %p", ohci->regs);
+                               ohci->hc_control = OHCI_USB_RESUME;
+                               writel (ohci->hc_control, &ohci->regs->control);
+                               wait_ms (20);
+
+                               ohci->hc_control = OHCI_CONTROL_INIT | OHCI_USB_OPER;
+                               writel (ohci->hc_control, &ohci->regs->control);
+                               break;
+
+                       default:
+                               warn ("odd PM_RESUME");
+                       }
                        break;
                }
        }
index 6ef0a97c4e9427eee7c5fd69f8663766dbe2e42a..42157dbabd220894ff7924bb8800ccfdda551ba8 100644 (file)
@@ -66,59 +66,59 @@ typedef void (*proto_cmnd)(Scsi_Cmnd*, struct us_data*);
 
 /* we allocate one of these for every device that we remember */
 struct us_data {
-       struct us_data          *next;           /* next device */
+       struct us_data          *next;           /* next device */
 
        /* the device we're working with */
-       struct semaphore        dev_semaphore;   /* protect pusb_dev */
-       struct usb_device       *pusb_dev;       /* this usb_device */
+       struct semaphore        dev_semaphore;   /* protect pusb_dev */
+       struct usb_device       *pusb_dev;       /* this usb_device */
 
        unsigned int            flags;           /* from filter initially */
 
        /* information about the device -- always good */
-       char                    vendor[32];
-       char                    product[32];
-       char                    serial[32];
-       char                    *transport_name;
-       char                    *protocol_name;
-       __u8                    subclass;
-       __u8                    protocol;
+       char                    vendor[USB_STOR_STRING_LEN];
+       char                    product[USB_STOR_STRING_LEN];
+       char                    serial[USB_STOR_STRING_LEN];
+       char                    *transport_name;
+       char                    *protocol_name;
+       u8                      subclass;
+       u8                      protocol;
 
        /* information about the device -- only good if device is attached */
-       __u8                    ifnum;           /* interface number   */
-       __u8                    ep_in;           /* bulk in endpoint   */
-       __u8                    ep_out;          /* bulk out endpoint  */
-       __u8                    ep_int;          /* interrupt endpoint */
-       __u8                    ep_interval;     /* interrupt interval */
+       u8                      ifnum;           /* interface number   */
+       u8                      ep_in;           /* bulk in endpoint   */
+       u8                      ep_out;          /* bulk out endpoint  */
+       struct usb_endpoint_descriptor *ep_int;  /* interrupt endpoint */ 
 
        /* function pointers for this device */
-       trans_cmnd              transport;       /* transport function     */
-       trans_reset             transport_reset; /* transport device reset */
-       proto_cmnd              proto_handler;   /* protocol handler       */
+       trans_cmnd              transport;       /* transport function     */
+       trans_reset             transport_reset; /* transport device reset */
+       proto_cmnd              proto_handler;   /* protocol handler       */
 
        /* SCSI interfaces */
-       GUID(guid);                              /* unique dev id       */
+       GUID(guid);                              /* unique dev id       */
        struct Scsi_Host        *host;           /* our dummy host data */
-       Scsi_Host_Template      htmplt;          /* own host template   */
-       int                     host_number;     /* to find us          */
-       int                     host_no;         /* allocated by scsi   */
-       Scsi_Cmnd               *srb;            /* current srb         */
+       Scsi_Host_Template      htmplt;          /* own host template   */
+       int                     host_number;     /* to find us          */
+       int                     host_no;         /* allocated by scsi   */
+       Scsi_Cmnd               *srb;            /* current srb         */
        
        /* thread information */
        Scsi_Cmnd               *queue_srb;      /* the single queue slot */
-       int                     action;          /* what to do            */
-       int                     pid;             /* control thread        */
+       int                     action;          /* what to do            */
+       int                     pid;             /* control thread        */
 
        /* interrupt info for CBI devices -- only good if attached */
-       struct semaphore        ip_waitq;        /* for CBI interrupts   */
-       __u16                   ip_data;         /* interrupt data       */
-       int                     ip_wanted;       /* is an IRQ expected?  */
-       void                    *irq_handle;     /* for USB int requests */
-       unsigned int            irqpipe;         /* pipe for release_irq */
+       struct semaphore        ip_waitq;        /* for CBI interrupts   */
+       int                     ip_wanted;       /* is an IRQ expected?  */
+
+       struct semaphore        irq_urb_sem;     /* to protect irq_urb   */
+       struct urb              *irq_urb;        /* for USB int requests */
+       unsigned char           irqbuf[2];       /* buffer for USB IRQ   */
 
        /* mutual exclusion structures */
-       struct semaphore        notify;          /* thread begin/end        */
-       struct semaphore        sleeper;         /* to sleep the thread on  */
-       struct semaphore        queue_exclusion; /* to protect data structs */
+       struct semaphore        notify;          /* thread begin/end        */
+       struct semaphore        sleeper;         /* to sleep the thread on  */
+       struct semaphore        queue_exclusion; /* to protect data structs */
 };
 
 /*
@@ -151,7 +151,7 @@ static struct usb_driver storage_driver = {
  * Transfer one SCSI scatter-gather buffer via bulk transfer
  *
  * Note that this function is necessary because we want the ability to
- * use scatter-gather memory.  Good performance is achived by a combination
+ * use scatter-gather memory.  Good performance is achieved by a combination
  * of scatter-gather and clustering (which makes each chunk bigger).
  *
  * Note that the lower layer will always retry when a NAK occurs, up to the
@@ -166,7 +166,7 @@ static int us_transfer_partial(struct us_data *us, int pipe,
 
        /* transfer the data */
        US_DEBUGP("Bulk xfer 0x%x(%d)\n", (unsigned int)buf, length);
-       result = usb_bulk_msg(us->pusb_dev, pipe, buf, length, &partial, HZ);
+       result = usb_bulk_msg(us->pusb_dev, pipe, buf, length, &partial, 5*HZ);
        US_DEBUGP("bulk_msg returned %d xferred %d/%d\n",
                  result, partial, length);
        
@@ -226,7 +226,7 @@ static void us_transfer(Scsi_Cmnd *srb, int dir_in)
                 */
                sg = (struct scatterlist *) srb->request_buffer;
                for (i = 0; i < srb->use_sg; i++) {
-                       result = us_transfer_partial(us, pipe, sg[i].address,
+                       result = us_transfer_partial(us, pipe, sg[i].address, 
                                                     sg[i].length);
                        if (result)
                                break;
@@ -234,7 +234,7 @@ static void us_transfer(Scsi_Cmnd *srb, int dir_in)
        }
        else
                /* no scatter-gather, just make the request */
-               result = us_transfer_partial(us, pipe, srb->request_buffer,
+               result = us_transfer_partial(us, pipe, srb->request_buffer, 
                                             srb->request_bufflen);
 
        /* return the result in the data structure itself */
@@ -251,7 +251,7 @@ static unsigned int us_transfer_length(Scsi_Cmnd *srb, struct us_data *us)
        struct scatterlist *sg;
 
        /* support those devices which need the length calculated
-        * differently
+        * differently 
         */
        if (us->flags & US_FL_ALT_LENGTH) {
                if (srb->cmnd[0] == INQUIRY) {
@@ -374,18 +374,18 @@ static void invoke_transport(Scsi_Cmnd *srb, struct us_data *us)
                srb->cmnd[3] = 0;
                srb->cmnd[4] = 18;
                srb->cmnd[5] = 0;
-    
+
                /* set the buffer length for transfer */
                old_request_buffer = srb->request_buffer;
                old_request_bufflen = srb->request_bufflen;
-               old_sg = srb->use_sg;
+               old_sg = srb->use_sg;
                srb->use_sg = 0;
                srb->request_bufflen = 18;
                srb->request_buffer = srb->sense_buffer;
 
                /* issue the auto-sense command */
                temp_result = us->transport(us->srb, us);
-               if (temp_result == USB_STOR_TRANSPORT_ERROR) {
+               if (temp_result != USB_STOR_TRANSPORT_GOOD) {
                        /* FIXME: we need to invoke a transport reset here */
                        US_DEBUGP("-- auto-sense failure\n");
                        srb->result = DID_ERROR << 16;
@@ -433,20 +433,22 @@ static void invoke_transport(Scsi_Cmnd *srb, struct us_data *us)
 /*
  * Control/Bulk/Interrupt transport
  */
-static int CBI_irq(int state, void *buffer, int len, void *dev_id)
+static void CBI_irq(struct urb *urb)
 {
-       struct us_data *us = (struct us_data *)dev_id;
+       struct us_data *us = (struct us_data *)urb->context;
 
        US_DEBUGP("USB IRQ recieved for device on host %d\n", us->host_no);
-       US_DEBUGP("-- IRQ data length is %d\n", len);
-       US_DEBUGP("-- IRQ state is %d\n", state);
+       US_DEBUGP("-- IRQ data length is %d\n", urb->actual_length);
+       US_DEBUGP("-- IRQ state is %d\n", urb->status);
 
        /* is the device removed? */
-       if (state != -ENOENT) {
+       if (urb->status != -ENOENT) {
                /* save the data for interpretation later */
-               us->ip_data = le16_to_cpup((__u16 *)buffer);
-               US_DEBUGP("-- Interrupt Status 0x%x\n", us->ip_data);
-  
+               US_DEBUGP("-- Interrupt Status (0x%x, 0x%x)\n",
+                         ((unsigned char*)urb->transfer_buffer)[0], 
+                         ((unsigned char*)urb->transfer_buffer)[1]);
+
+
                /* was this a wanted interrupt? */
                if (us->ip_wanted) {
                        us->ip_wanted = 0;
@@ -455,12 +457,6 @@ static int CBI_irq(int state, void *buffer, int len, void *dev_id)
                        US_DEBUGP("ERROR: Unwanted interrupt received!\n");
        } else
                US_DEBUGP("-- device has been removed\n");
-
-       /* This return code is truly meaningless -- and I mean truly.  It gets
-        * ignored by other layers.  It used to indicate if we wanted to get
-        * another interrupt or disable the interrupt callback
-        */
-       return 0;
 }
 
 static int CBI_transport(Scsi_Cmnd *srb, struct us_data *us)
@@ -480,7 +476,7 @@ static int CBI_transport(Scsi_Cmnd *srb, struct us_data *us)
                /* STALL must be cleared when they are detected */
                if (result == -EPIPE) {
                        US_DEBUGP("-- Stall on control pipe. Clearing\n");
-                       result = usb_clear_halt(us->pusb_dev,   
+                       result = usb_clear_halt(us->pusb_dev,   
                                                usb_sndctrlpipe(us->pusb_dev,
                                                                0));
                        US_DEBUGP("-- usb_clear_halt() returns %d\n", result);
@@ -513,7 +509,9 @@ static int CBI_transport(Scsi_Cmnd *srb, struct us_data *us)
                return USB_STOR_TRANSPORT_ERROR;
        }
        
-       US_DEBUGP("Got interrupt data 0x%x\n", us->ip_data);
+       US_DEBUGP("Got interrupt data (0x%x, 0x%x)\n", 
+                 ((unsigned char*)us->irq_urb->transfer_buffer)[0],
+                 ((unsigned char*)us->irq_urb->transfer_buffer)[1]);
        
        /* UFI gives us ASC and ASCQ, like a request sense
         *
@@ -527,7 +525,7 @@ static int CBI_transport(Scsi_Cmnd *srb, struct us_data *us)
                    srb->cmnd[0] == INQUIRY)
                        return USB_STOR_TRANSPORT_GOOD;
                else
-                       if (us->ip_data)
+                       if (((unsigned char*)us->irq_urb->transfer_buffer)[0])
                                return USB_STOR_TRANSPORT_FAILED;
                        else
                                return USB_STOR_TRANSPORT_GOOD;
@@ -537,10 +535,14 @@ static int CBI_transport(Scsi_Cmnd *srb, struct us_data *us)
         * The first byte should always be a 0x0
         * The second byte & 0x0F should be 0x0 for good, otherwise error 
         */
-       switch ((us->ip_data & 0xFF0F)) {
-       case 0x0000: 
+       if (((unsigned char*)us->irq_urb->transfer_buffer)[0]) {
+               US_DEBUGP("CBI IRQ data showed reserved bType\n");
+               return USB_STOR_TRANSPORT_ERROR;
+       }
+       switch (((unsigned char*)us->irq_urb->transfer_buffer)[1] & 0x0F) {
+       case 0x00: 
                return USB_STOR_TRANSPORT_GOOD;
-       case 0x0001: 
+       case 0x01: 
                return USB_STOR_TRANSPORT_FAILED;
        default: 
                return USB_STOR_TRANSPORT_ERROR;
@@ -609,8 +611,8 @@ static int Bulk_transport(Scsi_Cmnd *srb, struct us_data *us)
        int partial;
        
        /* set up the command wrapper */
-       bcb.Signature = US_BULK_CB_SIGN;
-       bcb.DataTransferLength = us_transfer_length(srb, us);
+       bcb.Signature = cpu_to_le32(US_BULK_CB_SIGN);
+       bcb.DataTransferLength = cpu_to_le32(us_transfer_length(srb, us));
        bcb.Flags = US_DIRECTION(srb->cmnd[0]) << 7;
        bcb.Tag = srb->serial_number;
        bcb.Lun = srb->cmnd[1] >> 5;
@@ -625,8 +627,8 @@ static int Bulk_transport(Scsi_Cmnd *srb, struct us_data *us)
        
        /* send it to out endpoint */
        US_DEBUGP("Bulk command S 0x%x T 0x%x LUN %d L %d F %d CL %d\n",
-                 bcb.Signature, bcb.Tag, bcb.Lun, bcb.DataTransferLength,
-                 bcb.Flags, bcb.Length);
+                 le32_to_cpu(bcb.Signature), bcb.Tag, bcb.Lun, 
+                 bcb.DataTransferLength, bcb.Flags, bcb.Length);
        result = usb_bulk_msg(us->pusb_dev, pipe, &bcb,
                              US_BULK_CB_WRAP_LEN, &partial, HZ*5);
        US_DEBUGP("Bulk command transfer result=%d\n", result);
@@ -657,17 +659,17 @@ static int Bulk_transport(Scsi_Cmnd *srb, struct us_data *us)
        /* get CSW for device status */
        US_DEBUGP("Attempting to get CSW...\n");
        result = usb_bulk_msg(us->pusb_dev, pipe, &bcs,
-                             US_BULK_CS_WRAP_LEN, &partial, HZ);
+                             US_BULK_CS_WRAP_LEN, &partial, HZ*2);
        
        /* did the attempt to read the CSW fail? */
        if (result == -EPIPE) {
                US_DEBUGP("clearing endpoint halt for pipe 0x%x\n", pipe);
                usb_clear_halt(us->pusb_dev, pipe);
-
+              
                /* get the status again */
                US_DEBUGP("Attempting to get CSW (2nd try)...\n");
                result = usb_bulk_msg(us->pusb_dev, pipe, &bcs,
-                                     US_BULK_CS_WRAP_LEN, &partial, HZ);
+                                     US_BULK_CS_WRAP_LEN, &partial, HZ*2);
                
                /* if it fails again, we need a reset and return an error*/
                if (result == -EPIPE) {
@@ -685,8 +687,10 @@ static int Bulk_transport(Scsi_Cmnd *srb, struct us_data *us)
        
        /* check bulk status */
        US_DEBUGP("Bulk status S 0x%x T 0x%x R %d V 0x%x\n",
-                 bcs.Signature, bcs.Tag, bcs.Residue, bcs.Status);
-       if (bcs.Signature != US_BULK_CS_SIGN || bcs.Tag != bcb.Tag ||
+                 le32_to_cpu(bcs.Signature), bcs.Tag, 
+                 bcs.Residue, bcs.Status);
+       if (bcs.Signature != cpu_to_le32(US_BULK_CS_SIGN) || 
+           bcs.Tag != bcb.Tag || 
            bcs.Status > US_BULK_STAT_PHASE || partial != 13) {
                US_DEBUGP("Bulk logical error\n");
                return USB_STOR_TRANSPORT_ERROR;
@@ -718,7 +722,7 @@ static int Bulk_transport(Scsi_Cmnd *srb, struct us_data *us)
 static void ATAPI_command(Scsi_Cmnd *srb, struct us_data *us)
 {
        int old_cmnd = 0;
-  
+
        /* Fix some commands -- this is a form of mode translation
         * ATAPI devices only accept 12 byte long commands 
         *
@@ -770,10 +774,10 @@ static void ATAPI_command(Scsi_Cmnd *srb, struct us_data *us)
                srb->cmnd[0] = srb->cmnd[0] | 0x20;
                break;
        } /* end switch on cmnd[0] */
-  
+
        /* send the command to the transport layer */
        invoke_transport(srb, us);
-  
+
        /* Fix the MODE_SENSE data if we translated the command
         */
        if (old_cmnd == MODE_SENSE) {
@@ -802,7 +806,7 @@ static void ATAPI_command(Scsi_Cmnd *srb, struct us_data *us)
 static void ufi_command(Scsi_Cmnd *srb, struct us_data *us)
 {
        int old_cmnd = 0;
-  
+
        /* fix some commands -- this is a form of mode translation
         * UFI devices only accept 12 byte long commands 
         *
@@ -831,7 +835,7 @@ static void ufi_command(Scsi_Cmnd *srb, struct us_data *us)
                srb->cmnd[10] = 0;
                srb->cmnd[9] = 0;
 
-               /* if we're sending data, we send all.  If getting data, 
+               /* if we're sending data, we send all.  If getting data, 
                 * get the minimum */
                if (srb->cmnd[0] == MODE_SELECT)
                        srb->cmnd[8] = srb->cmnd[4];
@@ -853,7 +857,7 @@ static void ufi_command(Scsi_Cmnd *srb, struct us_data *us)
                srb->cmnd[7] = 0;
                srb->cmnd[8] = 8;
                break;
+
                /* for REQUEST_SENSE, UFI devices only ever return 18 bytes */
        case REQUEST_SENSE:
                srb->cmnd[4] = 18;
@@ -912,48 +916,48 @@ static void transparent_scsi_command(Scsi_Cmnd *srb, struct us_data *us)
         * so some devices do not support them
         */
        if (us->flags & US_FL_MODE_XLATE) {
-    
+
                /* translate READ_6 to READ_10 */
                if (srb->cmnd[0] == 0x08) {
-      
+
                        /* get the control */
                        srb->cmnd[9] = us->srb->cmnd[5];
-      
+
                        /* get the length */
                        srb->cmnd[8] = us->srb->cmnd[6];
                        srb->cmnd[7] = 0;
-      
+
                        /* set the reserved area to 0 */
                        srb->cmnd[6] = 0;           
-      
+
                        /* get LBA */
                        srb->cmnd[5] = us->srb->cmnd[3];
                        srb->cmnd[4] = us->srb->cmnd[2];
                        srb->cmnd[3] = 0;
                        srb->cmnd[2] = 0;
-      
+
                        /* LUN and other info in cmnd[1] can stay */
-      
+
                        /* fix command code */
                        srb->cmnd[0] = 0x28;
-      
+
                        US_DEBUGP("Changing READ_6 to READ_10\n");
                        US_DEBUG(us_show_command(srb));
                }
-    
+
                /* translate WRITE_6 to WRITE_10 */
                if (srb->cmnd[0] == 0x0A) {
-      
+
                        /* get the control */
                        srb->cmnd[9] = us->srb->cmnd[5];
-      
+
                        /* get the length */
                        srb->cmnd[8] = us->srb->cmnd[4];
                        srb->cmnd[7] = 0;
-      
+
                        /* set the reserved area to 0 */
                        srb->cmnd[6] = 0;           
-      
+
                        /* get LBA */
                        srb->cmnd[5] = us->srb->cmnd[3];
                        srb->cmnd[4] = us->srb->cmnd[2];
@@ -961,7 +965,7 @@ static void transparent_scsi_command(Scsi_Cmnd *srb, struct us_data *us)
                        srb->cmnd[2] = 0;
            
                        /* LUN and other info in cmnd[1] can stay */
-      
+
                        /* fix command code */
                        srb->cmnd[0] = 0x2A;
 
@@ -1226,7 +1230,7 @@ int usb_stor_proc_info (char *buffer, char **start, off_t offset,
        SPRINTF("   Host scsi%d: usb-storage\n", hostno);
 
        /* print product, vendor, and serial number strings */
-       SPRINTF("       Vendor: %s\n", us->vendor);
+       SPRINTF("       Vendor: %s\n", us->vendor);
        SPRINTF("      Product: %s\n", us->product);
        SPRINTF("Serial Number: %s\n", us->serial);
 
@@ -1235,7 +1239,7 @@ int usb_stor_proc_info (char *buffer, char **start, off_t offset,
        SPRINTF("    Transport: %s\n", us->transport_name);
 
        /* show the GUID of the device */
-       SPRINTF("         GUID: " GUID_FORMAT "\n", GUID_ARGS(us->guid));
+       SPRINTF("         GUID: " GUID_FORMAT "\n", GUID_ARGS(us->guid));
 
        /* release our lock on the data structures */
        up(&us_list_semaphore);
@@ -1334,7 +1338,7 @@ static int usb_stor_control_thread(void * __us)
                action = us->action;
                us->action = 0;
                us->srb = us->queue_srb;
-       
+       
                /* release the queue lock as fast as possible */
                up(&(us->queue_exclusion));
 
@@ -1380,8 +1384,8 @@ static int usb_stor_control_thread(void * __us)
                                               sizeof(sense_notready));
                                        us->srb->result = GOOD;
                                } else {
-                                       memcpy(us->srb->sense_buffer,
-                                              sense_notready,
+                                       memcpy(us->srb->sense_buffer, 
+                                              sense_notready, 
                                               sizeof(sense_notready));
                                        us->srb->result = CHECK_CONDITION;
                                }
@@ -1395,7 +1399,7 @@ static int usb_stor_control_thread(void * __us)
                        up(&(us->dev_semaphore));
 
                        /* indicate that the command is done */
-                       US_DEBUGP("scsi cmd done, result=0x%x\n",
+                       US_DEBUGP("scsi cmd done, result=0x%x\n", 
                                  us->srb->result);
                        us->srb->scsi_done(us->srb);
                        us->srb = NULL;
@@ -1428,15 +1432,22 @@ static int usb_stor_control_thread(void * __us)
 static struct us_unusual_dev us_unusual_dev_list[] = {
        { 0x057b, 0x0000, 0x0114,
          "Y-E Data Flashbuster-U", US_SC_UFI, US_PR_CB, US_FL_SINGLE_LUN },
+       { 0x059b, 0x0030, 0x0100,
+         "Iomega Zip 250", US_SC_SCSI, US_PR_BULK, US_FL_SINGLE_LUN },
        { 0x0781, 0x0001, 0x0200,
-         "Sandisk ImageMate", US_SC_SCSI, US_PR_CB, 
+         "Sandisk ImageMate (w/eject button)", US_SC_SCSI, US_PR_CB, 
          US_FL_SINGLE_LUN | US_FL_START_STOP },
        { 0x0781, 0x0002, 0x0009,
-         "** SECRET DEVICE **", US_SC_SCSI, US_PR_BULK, US_FL_SINGLE_LUN },
-       { 0x04e6, 0x0002, 0x0100,
-         "Microtech USB-SCSI-HD50", US_SC_SCSI, US_PR_BULK, US_FL_ALT_LENGTH},
+         "** SECRET DEVICE **", US_SC_SCSI, US_PR_BULK, 
+         US_FL_SINGLE_LUN | US_FL_IGNORE_SER },
        { 0x07af, 0x0005, 0x0100,
-         "Shuttle eUSCSI Bridge", US_SC_SCSI, US_PR_BULK, US_FL_ALT_LENGTH},
+         "Microtech USB-SCSI-HD50", US_SC_SCSI, US_PR_BULK, US_FL_ALT_LENGTH}, 
+       { 0x04e6, 0x0002, 0x0100,
+         "Shuttle eUSCSI Bridge", US_SC_SCSI, US_PR_BULK, US_FL_ALT_LENGTH}, 
+       { 0x04e6, 0x0006, 0x0100,
+         "Shuttle eUSB MMC Adapter", US_SC_SCSI, US_PR_CB, US_FL_SINGLE_LUN}, 
+       { 0x03f0, 0x0107, 0x0200,
+         "HP USB CD-Writer Plus", US_SC_8070, US_PR_CB, 0}, 
        { 0x0000, 0x0000, 0x0,
          "", 0, 0, 0}
 };
@@ -1446,8 +1457,8 @@ static struct us_unusual_dev us_unusual_dev_list[] = {
  * defining how we should support this device, or NULL if it's not in the
  * list
  */
-static struct us_unusual_dev* us_find_dev(__u16 idVendor, __u16 idProduct, 
-                                         __u16 bcdDevice)
+static struct us_unusual_dev* us_find_dev(u16 idVendor, u16 idProduct, 
+                                         u16 bcdDevice)
 {
        struct us_unusual_dev* ptr;
 
@@ -1472,14 +1483,64 @@ static struct us_unusual_dev* us_find_dev(__u16 idVendor, __u16 idProduct,
        return ptr;
 }
 
+/* Set up the IRQ pipe and handler
+ * Note that this function assumes that all the data in the us_data
+ * strucuture is current.  This includes the ep_int field, which gives us
+ * the endpoint for the interrupt.
+ * Returns non-zero on failure, zero on success
+ */ 
+static int usb_stor_allocate_irq(struct us_data *ss)
+{
+       unsigned int pipe;
+       int maxp;
+       int result;
+
+       US_DEBUGP("Allocating IRQ for CBI transport\n");
+       
+       /* lock access to the data structure */
+       down(&(ss->irq_urb_sem));
+
+       /* allocate the URB */
+       ss->irq_urb = usb_alloc_urb(0);
+       if (!ss->irq_urb) {
+               up(&(ss->irq_urb_sem));
+               US_DEBUGP("couldn't allocate interrupt URB");
+               return 1;
+       }
+       
+       /* calculate the pipe and max packet size */
+       pipe = usb_rcvintpipe(ss->pusb_dev, ss->ep_int->bEndpointAddress & 
+                             USB_ENDPOINT_NUMBER_MASK);
+       maxp = usb_maxpacket(ss->pusb_dev, pipe, usb_pipeout(pipe));
+       if (maxp > sizeof(ss->irqbuf))
+               maxp = sizeof(ss->irqbuf);
+       
+       /* fill in the URB with our data */
+       FILL_INT_URB(ss->irq_urb, ss->pusb_dev, pipe, ss->irqbuf, maxp, 
+                    CBI_irq, ss, ss->ep_int->bInterval); 
+       
+       /* submit the URB for processing */
+       result = usb_submit_urb(ss->irq_urb);
+       US_DEBUGP("usb_submit_urb() returns %d\n", result);
+       if (result) {
+               usb_free_urb(ss->irq_urb);
+               up(&(ss->irq_urb_sem));
+               return 2;
+       }
+
+       /* unlock the data structure and return success */
+       up(&(ss->irq_urb_sem));
+       return 0;
+}
+
 /* Probe to see if a new device is actually a SCSI device */
 static void * storage_probe(struct usb_device *dev, unsigned int ifnum)
 {
        int i;
        char mf[USB_STOR_STRING_LEN];                /* manufacturer */
        char prod[USB_STOR_STRING_LEN];              /* product */
-       char serial[USB_STOR_STRING_LEN];            /* serial number */
-       GUID(guid);                        /* Global Unique Identifier */
+       char serial[USB_STOR_STRING_LEN];            /* serial number */
+       GUID(guid);                        /* Global Unique Identifier */
        unsigned int flags;
        struct us_unusual_dev *unusual_dev;
        struct us_data *ss = NULL;
@@ -1488,12 +1549,11 @@ static void * storage_probe(struct usb_device *dev, unsigned int ifnum)
        /* these are temporary copies -- we test on these, then put them
         * in the us-data structure 
         */
-       __u8 ep_in = 0;
-       __u8 ep_out = 0;
-       __u8 ep_int = 0;
-       __u8 ep_interval = 0;
-       __u8 subclass = 0;
-       __u8 protocol = 0;
+       struct usb_endpoint_descriptor *ep_in = NULL;
+       struct usb_endpoint_descriptor *ep_out = NULL;
+       struct usb_endpoint_descriptor *ep_int = NULL;
+       u8 subclass = 0;
+       u8 protocol = 0;
 
        /* the altsettting 0 on the interface we're probing */
        struct usb_interface_descriptor *altsetting = 
@@ -1550,23 +1610,19 @@ static void * storage_probe(struct usb_device *dev, unsigned int ifnum)
                        /* BULK in or out? */
                        if (altsetting->endpoint[i].bEndpointAddress & 
                            USB_DIR_IN)
-                               ep_in = altsetting->endpoint[i].bEndpointAddress &
-                                       USB_ENDPOINT_NUMBER_MASK;
+                               ep_in = &altsetting->endpoint[i];
                        else
-                               ep_out = altsetting->endpoint[i].bEndpointAddress &
-                                       USB_ENDPOINT_NUMBER_MASK;
+                               ep_out = &altsetting->endpoint[i];
                }
 
                /* is it an interrupt endpoint? */
                if ((altsetting->endpoint[i].bmAttributes & 
                     USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT) {
-                       ep_int = altsetting->endpoint[i].bEndpointAddress &
-                               USB_ENDPOINT_NUMBER_MASK;
-                       ep_interval = altsetting->endpoint[i].bInterval;
+                       ep_int = &altsetting->endpoint[i];
                }
        }
-       US_DEBUGP("Endpoints: In %d Out %d Int %d (Period %d)\n",
-                 ep_in, ep_out, ep_int, ep_interval);
+       US_DEBUGP("Endpoints: In: 0x%p Out: 0x%p Int: 0x%p (Period %d)\n",
+                 ep_in, ep_out, ep_int, ep_int ? ep_int->bInterval : 0);
 
        /* set the interface -- STALL is an acceptable response here */
        result = usb_set_interface(dev, altsetting->bInterfaceNumber, 0);
@@ -1582,7 +1638,7 @@ static void * storage_probe(struct usb_device *dev, unsigned int ifnum)
 
        /* Do some basic sanity checks, and bail if we find a problem */
        if (!ep_in || !ep_out || (protocol == US_PR_CBI && !ep_int)) {
-               US_DEBUGP("Sanity check failed.  Rejecting device.\n");
+               US_DEBUGP("Sanity check failed.  Rejecting device.\n");
                return NULL;
        }
 
@@ -1591,14 +1647,14 @@ static void * storage_probe(struct usb_device *dev, unsigned int ifnum)
        /* clear the GUID and fetch the strings */
        GUID_CLEAR(guid);
        if (dev->descriptor.iManufacturer)
-               usb_string(dev, dev->descriptor.iManufacturer, mf, 
-                          sizeof(mf));
+               usb_string(dev, dev->descriptor.iManufacturer, 
+                          mf, sizeof(mf));
        if (dev->descriptor.iProduct)
-               usb_string(dev, dev->descriptor.iProduct, prod, 
-                          sizeof(prod));
-       if (dev->descriptor.iSerialNumber)
-               usb_string(dev, dev->descriptor.iSerialNumber, serial, 
-                          sizeof(serial));
+               usb_string(dev, dev->descriptor.iProduct, 
+                          prod, sizeof(prod));
+       if (dev->descriptor.iSerialNumber && !(flags & US_FL_IGNORE_SER))
+               usb_string(dev, dev->descriptor.iSerialNumber, 
+                          serial, sizeof(serial));
        
        /* Create a GUID for this device */
        if (dev->descriptor.iSerialNumber && serial[0]) {
@@ -1633,22 +1689,20 @@ static void * storage_probe(struct usb_device *dev, unsigned int ifnum)
                ss->ifnum = ifnum;
                ss->pusb_dev = dev;
        
-               /* hook up the IRQ handler again */
-               if (ss->protocol == US_PR_CBI) {
-                       /* set up so we'll wait for notification */
-                       init_MUTEX_LOCKED(&(ss->ip_waitq));
-                       
-                       /* set up the IRQ pipe and handler */
-                       US_DEBUGP("Allocating IRQ for CBI transport\n");
-                       ss->irqpipe = usb_rcvintpipe(ss->pusb_dev, ss->ep_int);
-                       result = usb_request_irq(ss->pusb_dev, ss->irqpipe, 
-                                                CBI_irq, ss->ep_interval,
-                                                (void *)ss,
-                                                &(ss->irq_handle));
-                       US_DEBUGP("-- usb_request_irq returned %d\n", result);
-               }
+               /* copy over the endpoint data */
+               if (ep_in)
+                       ss->ep_in = ep_in->bEndpointAddress & 
+                               USB_ENDPOINT_NUMBER_MASK;
+               if (ep_out)
+                       ss->ep_out = ep_out->bEndpointAddress & 
+                               USB_ENDPOINT_NUMBER_MASK;
+               ss->ep_int = ep_int;
+
+               /* allocate an IRQ callback if one is needed */
+               if ((ss->protocol == US_PR_CBI) && usb_stor_allocate_irq(ss))
+                       return NULL;
        } else { 
-               /* New device -- Allocate memory and initialize */
+               /* New device -- allocate memory and initialize */
                US_DEBUGP("New GUID " GUID_FORMAT "\n", GUID_ARGS(guid));
        
                if ((ss = (struct us_data *)kmalloc(sizeof(struct us_data), 
@@ -1662,7 +1716,9 @@ static void * storage_probe(struct usb_device *dev, unsigned int ifnum)
                /* Initialize the mutexes only when the struct is new */
                init_MUTEX_LOCKED(&(ss->sleeper));
                init_MUTEX_LOCKED(&(ss->notify));
+               init_MUTEX_LOCKED(&(ss->ip_waitq));
                init_MUTEX(&(ss->queue_exclusion));
+               init_MUTEX(&(ss->irq_urb_sem));
                init_MUTEX(&(ss->dev_semaphore));
 
                /* copy over the subclass and protocol data */
@@ -1671,10 +1727,13 @@ static void * storage_probe(struct usb_device *dev, unsigned int ifnum)
                ss->flags = flags;
 
                /* copy over the endpoint data */
-               ss->ep_in = ep_in;
-               ss->ep_out = ep_out;
+               if (ep_in)
+                       ss->ep_in = ep_in->bEndpointAddress & 
+                               USB_ENDPOINT_NUMBER_MASK;
+               if (ep_out)
+                       ss->ep_out = ep_out->bEndpointAddress & 
+                               USB_ENDPOINT_NUMBER_MASK;
                ss->ep_int = ep_int;
-               ss->ep_interval = ep_interval;
 
                /* establish the connection to the new device */
                ss->ifnum = ifnum;
@@ -1739,7 +1798,7 @@ static void * storage_probe(struct usb_device *dev, unsigned int ifnum)
 
                case US_SC_QIC:
                        ss->protocol_name = "QIC-157";
-                       US_DEBUGP("Sorry, device not supported.  Please\n");
+                       US_DEBUGP("Sorry, device not supported.  Please\n");
                        US_DEBUGP("contact mdharm-usb@one-eyed-alien.net\n");
                        US_DEBUGP("if you see this message.\n");
                        up(&us_list_semaphore);
@@ -1771,19 +1830,9 @@ static void * storage_probe(struct usb_device *dev, unsigned int ifnum)
                }
                US_DEBUGP("Protocol: %s\n", ss->protocol_name);
 
-               if (ss->protocol == US_PR_CBI) {
-                       /* set up so we'll wait for notification */
-                       init_MUTEX_LOCKED(&(ss->ip_waitq));
-                       
-                       /* set up the IRQ pipe and handler */
-                       US_DEBUGP("Allocating IRQ for CBI transport\n");
-                       ss->irqpipe = usb_rcvintpipe(ss->pusb_dev, ss->ep_int);
-                       result = usb_request_irq(ss->pusb_dev, ss->irqpipe, 
-                                                CBI_irq, ss->ep_interval,
-                                                (void *)ss,
-                                                &(ss->irq_handle));
-                       US_DEBUGP("-- usb_request_irq returned %d\n", result);
-               }
+               /* allocate an IRQ callback if one is needed */
+               if ((ss->protocol == US_PR_CBI) && usb_stor_allocate_irq(ss))
+                       return NULL;
                
                /*
                 * Since this is a new device, we need to generate a scsi 
@@ -1803,7 +1852,7 @@ static void * storage_probe(struct usb_device *dev, unsigned int ifnum)
                 */
                (struct us_data *)ss->htmplt.proc_dir = ss; 
                
-               /* start up our thread */
+               /* start up our control thread */
                ss->pid = kernel_thread(usb_stor_control_thread, ss,
                                        CLONE_FS | CLONE_FILES |
                                        CLONE_SIGHAND);
@@ -1814,10 +1863,10 @@ static void * storage_probe(struct usb_device *dev, unsigned int ifnum)
                        return NULL;
                }
                
-               /* wait for it to start */
+               /* wait for the thread to start */
                down(&(ss->notify));
                        
-               /* now register - our detect function will be called */
+               /* now register  - our detect function will be called */
                ss->htmplt.module = THIS_MODULE;
                scsi_register_module(MODULE_SCSI_HA, &(ss->htmplt));
                
@@ -1845,7 +1894,7 @@ static void storage_disconnect(struct usb_device *dev, void *ptr)
        int result;
 
        US_DEBUGP("storage_disconnect() called\n");
+
        /* this is the odd case -- we disconnected but weren't using it */
        if (!ss) {
                US_DEBUGP("-- device was not in use\n");
@@ -1856,13 +1905,15 @@ static void storage_disconnect(struct usb_device *dev, void *ptr)
        down(&(ss->dev_semaphore));
 
        /* release the IRQ, if we have one */
-       if (ss->irq_handle) {
+       down(&(ss->irq_urb_sem));
+       if (ss->irq_urb) {
                US_DEBUGP("-- releasing irq handle\n");
-               result = usb_release_irq(ss->pusb_dev, ss->irq_handle, 
-                                        ss->irqpipe);
-               US_DEBUGP("-- usb_release_irq() returned %d\n", result);
-               ss->irq_handle = NULL;
+               result = usb_unlink_urb(ss->irq_urb);
+               ss->irq_urb = NULL;
+               US_DEBUGP("-- usb_unlink_urb() returned %d\n", result);
+               usb_free_urb(ss->irq_urb);
        }
+       up(&(ss->irq_urb_sem));
 
        /* mark the device as gone */
        ss->pusb_dev = NULL;
index c867bbe0df6f9210a2b546151a2fa2fec383f686..0d5152e367e4999d7c2b69afb682f60b48a1c823 100644 (file)
@@ -27,23 +27,23 @@ extern unsigned char us_direction[256/8];
 
 /* Sub Classes */
 
-#define US_SC_RBC      1               /* Typically, flash devices */
-#define US_SC_8020     2               /* CD-ROM */
-#define US_SC_QIC      3               /* QIC-157 Tapes */
-#define US_SC_UFI      4               /* Floppy */
-#define US_SC_8070     5               /* Removable media */
-#define US_SC_SCSI     6               /* Transparent */
+#define US_SC_RBC      0x01            /* Typically, flash devices */
+#define US_SC_8020     0x02            /* CD-ROM */
+#define US_SC_QIC      0x03            /* QIC-157 Tapes */
+#define US_SC_UFI      0x04            /* Floppy */
+#define US_SC_8070     0x05            /* Removable media */
+#define US_SC_SCSI     0x06            /* Transparent */
 #define US_SC_MIN      US_SC_RBC
 #define US_SC_MAX      US_SC_SCSI
 
 /* Protocols */
 
-#define US_PR_CB       1               /* Control/Bulk w/o interrupt */
-#define US_PR_CBI      0               /* Control/Bulk/Interrupt */
+#define US_PR_CBI      0x00            /* Control/Bulk/Interrupt */
+#define US_PR_CB       0x01            /* Control/Bulk w/o interrupt */
 #define US_PR_BULK     0x50            /* bulk only */
 
 /*
- * Bulk only data structures (Zip 100, for example)
+ * Bulk only data structures
  */
 
 /* command block wrapper */
@@ -57,8 +57,8 @@ struct bulk_cb_wrap {
        __u8    CDB[16];                /* max command */
 };
 
-#define US_BULK_CB_WRAP_LEN    31
-#define US_BULK_CB_SIGN                0x43425355
+#define US_BULK_CB_WRAP_LEN    31
+#define US_BULK_CB_SIGN                0x43425355      /*spells out USBC */
 #define US_BULK_FLAG_IN                1
 #define US_BULK_FLAG_OUT       0
 
@@ -72,7 +72,7 @@ struct bulk_cs_wrap {
 };
 
 #define US_BULK_CS_WRAP_LEN    13
-#define US_BULK_CS_SIGN                0x53425355
+#define US_BULK_CS_SIGN                0x53425355      /* spells out 'USBS' */
 #define US_BULK_STAT_OK                0
 #define US_BULK_STAT_FAIL      1
 #define US_BULK_STAT_PHASE     2
@@ -84,15 +84,15 @@ struct bulk_cs_wrap {
 /*
  * us_bulk_transfer() return codes
  */
-#define US_BULK_TRANSFER_GOOD   0
-#define US_BULK_TRANSFER_SHORT  1
+#define US_BULK_TRANSFER_GOOD  0
+#define US_BULK_TRANSFER_SHORT 1
 #define US_BULK_TRANSFER_FAILED 2
 
 /*
  * Transport return codes
  */
 
-#define USB_STOR_TRANSPORT_GOOD    0   /* Transport good, command good     */
+#define USB_STOR_TRANSPORT_GOOD           0   /* Transport good, command good     */
 #define USB_STOR_TRANSPORT_FAILED  1   /* Transport good, command failed   */
 #define USB_STOR_TRANSPORT_ERROR   2   /* Transport bad (i.e. device dead) */
 
@@ -147,9 +147,11 @@ struct us_unusual_dev {
 };
 
 /* Flag definitions */
-#define US_FL_SINGLE_LUN      0x00000001 /* allow access to only LUN 0 */
+#define US_FL_SINGLE_LUN      0x00000001 /* allow access to only LUN 0     */
 #define US_FL_MODE_XLATE      0x00000002 /* translate _6 to _10 comands for
-                                                   Win/MacOS compatibility */
-#define US_FL_START_STOP      0x00000004 /* ignore START_STOP commands */
+                                                   Win/MacOS compatibility */
+#define US_FL_START_STOP      0x00000004 /* ignore START_STOP commands     */
 #define US_FL_ALT_LENGTH      0x00000008 /* use the alternate algorithm for
-                                                    us_transfer_length() */
+                                                   us_transfer_length()    */
+#define US_FL_IGNORE_SER      0x00000010 /* Ignore the serial number given  */
+
index 2cebdad61c3e7c635513255a086fa3c88d3ff1a4..244ff5872ef29f7b56de76f9b1f95ba9f6b59058 100644 (file)
@@ -48,7 +48,7 @@ obj-$(CONFIG_FONT_ACORN_8x8)      += font_acorn_8x8.o
 
 # Add fbmon.o back into obj-$(CONFIG_FB) in 2.5.x
 obj-$(CONFIG_FB)                  += fbmem.o fbcmap.o modedb.o fbcon.o fonts.o
-obj-$(CONFIG_FB_COMPAT_XPMAC)     += macmodes.o
+obj-$(CONFIG_PPC)                 += macmodes.o
 
 obj-$(CONFIG_FB_ACORN)            += acornfb.o
 obj-$(CONFIG_FB_AMIGA)            += amifb.o
index 0952d068935ef086f5c1f0710ae302ccbeb92b35..e38afe23d3ead45c0e45d9d045e0a20622b13e6a 100644 (file)
  *             - monitor sensing (DDC)
  *              - virtual display
  *             - other platform support (only ppc/x86 supported)
- *             - PPLL_REF_DIV & XTALIN calculation    -done for x86
- *             - determine MCLK from previous setting -done for x86            
- *              - calculate XCLK, rather than probe BIOS
  *             - hardware cursor support
  *             - ioctl()'s
+ *
+ *    Please cc: your patches to brad@neruo.com.
  */
 
 /*
@@ -82,7 +81,7 @@
 #endif
 
 /* default mode */
-static struct fb_var_screeninfo default_var = {
+static struct fb_var_screeninfo default_var __initdata = {
     /* 640x480, 60 Hz, Non-Interlaced (25.175 MHz dotclock) */
     640, 480, 640, 480, 0, 0, 8, 0,
     {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
@@ -118,6 +117,7 @@ static const struct aty128_chip_info aty128_pci_probe_list[] __initdata =
 };
 
 /* packed BIOS settings */
+#ifndef CONFIG_PPC
 #pragma pack(1)
 typedef struct {
     u8 clock_chip_type;
@@ -144,6 +144,7 @@ typedef struct {
     u32 XCLK_max_freq;
 } PLL_BLOCK;
 #pragma pack()
+#endif /* !CONFIG_PPC */
 
 /* onboard memory information */
 struct aty128_meminfo {
@@ -1772,8 +1773,9 @@ aty128_init(struct fb_info_aty128 *info, const char *name)
         info->palette[j].blue = default_blu[k];
     }
 
+    /* setup the DAC the way we like it */
     dac = aty_ld_le32(DAC_CNTL);
-    dac |= (DAC_8BIT_EN | DAC_RANGE_CNTL | DAC_BLANKING);
+    dac |= (DAC_8BIT_EN | DAC_RANGE_CNTL);
     dac |= DAC_MASK;
     aty_st_le32(DAC_CNTL, dac);
 
index 98bcf32d86e6e99c4d6df4cb63b71903f039eaf0..9030fd0c6a66dd4969057c52541c6fc3c8653dc5 100644 (file)
@@ -188,8 +188,10 @@ static const struct monitor_map {
     { -1,    VMODE_640_480_60 },       /* catch-all, must be last */
 };
 
+#ifdef CONFIG_FB_COMPAT_XPMAC
 struct fb_info *console_fb_info = NULL;
 struct vc_mode display_info;
+
 static u16 palette_red[16];
 static u16 palette_green[16];
 static u16 palette_blue[16];
@@ -198,20 +200,12 @@ static struct fb_cmap palette_cmap = {
 };
 
 
-int console_getmode(struct vc_mode *);
-int console_setmode(struct vc_mode *, int);
-int console_setcmap(int, unsigned char *, unsigned char *, unsigned char *);
-int console_powermode(int);
-int mac_var_to_vmode(const struct fb_var_screeninfo *, int *, int *);
-
-
 int console_getmode(struct vc_mode *mode)
 {
     *mode = display_info;
     return 0;
 }
 
-
 int console_setmode(struct vc_mode *mode, int doit)
 {
     struct fb_var_screeninfo var;
@@ -258,7 +252,6 @@ int console_setmode(struct vc_mode *mode, int doit)
     return 0;
 }
 
-
 int console_setcmap(int n_entries, unsigned char *red, unsigned char *green,
                     unsigned char *blue)
 {
@@ -289,6 +282,17 @@ int console_setcmap(int n_entries, unsigned char *red, unsigned char *green,
     return 0;
 }
 
+int console_powermode(int mode)
+{
+    if (mode == VC_POWERMODE_INQUIRY)
+        return 0;
+    if (mode < VESA_NO_BLANKING || mode > VESA_POWERDOWN)
+        return -EINVAL;
+    /* Not Supported */
+    return -ENXIO;
+}
+#endif /* CONFIG_FB_COMPAT_XPMAC */
+
 
     /*
      *  Convert a MacOS vmode/cmode pair to a frame buffer video mode structure
@@ -363,17 +367,6 @@ int mac_vmode_to_var(int vmode, int cmode, struct fb_var_screeninfo *var)
 }
 
 
-int console_powermode(int mode)
-{
-    if (mode == VC_POWERMODE_INQUIRY)
-        return 0;
-    if (mode < VESA_NO_BLANKING || mode > VESA_POWERDOWN)
-        return -EINVAL;
-    /* Not Supported */
-    return -ENXIO;
-}
-
-
     /*
      *  Convert a frame buffer video mode structure to a MacOS vmode/cmode pair
      */
index cfd74c9d57dc5e4307afa667c63c9b5d7320a687..9dc40922a441a8e8b541aad17108f03e1b7cd7b3 100644 (file)
@@ -132,7 +132,7 @@ void autofs_hash_nuke(struct autofs_dirhash *);
 /* Expiration-handling functions */
 
 void autofs_update_usage(struct autofs_dirhash *,struct autofs_dir_ent *);
-struct autofs_dir_ent *autofs_expire(struct super_block *,struct autofs_sb_info *);
+struct autofs_dir_ent *autofs_expire(struct super_block *,struct autofs_sb_info *, struct vfsmount *mnt);
 
 /* Operations structures */
 
index 44c761901a1057ef7f3a501983cc86daaae9e9bd..168d7861b7b60cb219f572e77d9641413b21a320 100644 (file)
@@ -34,7 +34,8 @@ void autofs_update_usage(struct autofs_dirhash *dh,
 }
 
 struct autofs_dir_ent *autofs_expire(struct super_block *sb,
-                                    struct autofs_sb_info *sbi)
+                                    struct autofs_sb_info *sbi,
+                                    struct vfsmount *mnt)
 {
        struct autofs_dirhash *dh = &sbi->dirhash;
        struct autofs_dir_ent *ent;
@@ -79,12 +80,25 @@ struct autofs_dir_ent *autofs_expire(struct super_block *sb,
                        DPRINTK(("autofs: not expirable (not a mounted directory): %s\n", ent->name));
                        continue;
                }
+               mntget(mnt);
+               dget(dentry);
+               if (!follow_down(&mnt, &dentry)) {
+                       dput(dentry);
+                       mntput(mnt);
+                       DPRINTK(("autofs: not expirable (not a mounted directory): %s\n", ent->name));
+                       continue;
+               }
+               while (d_mountpoint(dentry) && follow_down(&mnt, &dentry))
+                       ;
+               dput(dentry);
 
-               if ( may_umount(dentry->d_mounts->d_sb) == 0 ) {
+               if ( may_umount(mnt) == 0 ) {
+                       mntput(mnt);
                        DPRINTK(("autofs: signaling expire on %s\n", ent->name));
                        return ent; /* Expirable! */
                }
                DPRINTK(("autofs: didn't expire due to may_umount: %s\n", ent->name));
+               mntput(mnt);
        }
        return NULL;            /* No expirable entries */
 }
index baa8cd6bfa8b046befdf1ca6bac91cb168e242d0..63ac3db2aca51838241ac367c0d7b84040dfd531 100644 (file)
@@ -432,6 +432,7 @@ static inline int autofs_get_protover(int *p)
 /* Perform an expiry operation */
 static inline int autofs_expire_run(struct super_block *sb,
                                    struct autofs_sb_info *sbi,
+                                   struct vfsmount *mnt,
                                    struct autofs_packet_expire *pkt_p)
 {
        struct autofs_dir_ent *ent;
@@ -443,7 +444,7 @@ static inline int autofs_expire_run(struct super_block *sb,
        pkt.hdr.type = autofs_ptype_expire;
 
        if ( !sbi->exp_timeout ||
-            !(ent = autofs_expire(sb,sbi)) )
+            !(ent = autofs_expire(sb,sbi,mnt)) )
                return -EAGAIN;
 
        pkt.len = ent->len;
@@ -487,7 +488,7 @@ static int autofs_root_ioctl(struct inode *inode, struct file *filp,
        case AUTOFS_IOC_SETTIMEOUT:
                return autofs_get_set_timeout(sbi,(unsigned long *)arg);
        case AUTOFS_IOC_EXPIRE:
-               return autofs_expire_run(inode->i_sb,sbi,
+               return autofs_expire_run(inode->i_sb, sbi, filp->f_vfsmnt,
                                         (struct autofs_packet_expire *)arg);
        default:
                return -ENOSYS;
index 4e9fa90150b26cc897919e922ff32f3e6e812224..bf030e2a11e1af781ac1d4f6d5f9b0ec403d8905 100644 (file)
@@ -1578,7 +1578,6 @@ int block_read_full_page(struct page *page, get_block_t *get_block)
                nr++;
        } while (i++, iblock++, (bh = bh->b_this_page) != head);
 
-       ++current->maj_flt;
        if (nr) {
                if (Page_Uptodate(page))
                        BUG();
@@ -2002,8 +2001,6 @@ int brw_page(int rw, struct page *page, kdev_t dev, int b[], int size)
                }
                bh = bh->b_this_page;
        } while (bh != head);
-       if (rw == READ)
-               ++current->maj_flt;
        if ((rw == READ) && nr) {
                if (Page_Uptodate(page))
                        BUG();
@@ -2277,7 +2274,7 @@ void __init buffer_init(unsigned long mempages)
                    __get_free_pages(GFP_ATOMIC, order);
        } while (hash_table == NULL && --order > 0);
        printk("Buffer-cache hash table entries: %d (order: %d, %ld bytes)\n",
-              nr_hash, order, (1UL<<order) * PAGE_SIZE);
+              nr_hash, order, (PAGE_SIZE << order));
 
        if (!hash_table)
                panic("Failed to allocate buffer hash table\n");
index 001b1024d2b57021bf9f1289f226cf059f351dd9..5db85157bd8113107fb4328c460cfaee7d46114d 100644 (file)
@@ -1098,11 +1098,12 @@ void __init dcache_init(unsigned long mempages)
                        __get_free_pages(GFP_ATOMIC, order);
        } while (dentry_hashtable == NULL && --order >= 0);
 
+       printk("Dentry-cache hash table entries: %d (order: %ld, %ld bytes)\n",
+                       nr_hash, order, (PAGE_SIZE << order));
+
        if (!dentry_hashtable)
                panic("Failed to allocate dcache hash table\n");
 
-       printk("VFS: DCACHE hash table configured to %d entries\n", nr_hash);
-
        d = dentry_hashtable;
        i = nr_hash;
        do {
index 9068498c2c9cfe34a1c463a2cd7fa10d68454920..58de74881f33f8cd66bf74b12075cbca688dadb8 100644 (file)
@@ -876,11 +876,12 @@ void __init inode_init(unsigned long mempages)
                        __get_free_pages(GFP_ATOMIC, order);
        } while (inode_hashtable == NULL && --order >= 0);
 
+       printk("Inode-cache hash table entries: %d (order: %ld, %ld bytes)\n",
+                       nr_hash, order, (PAGE_SIZE << order));
+
        if (!inode_hashtable)
                panic("Failed to allocate inode hash table\n");
 
-       printk("VFS: INODE hash table configured to %d entries\n", nr_hash);
-
        head = inode_hashtable;
        i = nr_hash;
        do {
index cbb2136683c47a756138f015b2117aeac572ce24..1b99acb1995ce3d7344bf03fe3410a57635c1cd1 100644 (file)
@@ -133,12 +133,28 @@ static int do_isofs_readdir(struct inode *inode, struct file *filp,
                       block, offset, filp->f_pos);
                printk("inode->i_size = %x\n",inode->i_size);
 #endif
+               /* Next directory_record on next CDROM sector */
+               if (offset >= bufsize) {
+#ifdef DEBUG
+                       printk("offset >= bufsize\n");
+#endif
+                       brelse(bh);
+                       offset = 0;
+                       block = isofs_bmap(inode, (filp->f_pos) >> bufbits);
+                       if (!block)
+                               return 0;
+                       bh = breada(inode->i_dev, block, bufsize, filp->f_pos, inode->i_size);
+                       if (!bh)
+                               return 0;
+                       continue;
+               }
+
                de = (struct iso_directory_record *) (bh->b_data + offset);
                if(first_de) inode_number = (block << bufbits) + (offset & (bufsize - 1));
 
                de_len = *(unsigned char *) de;
 #ifdef DEBUG
-               printk("de_len = %ld\n", de_len);
+               printk("de_len = %d\n", de_len);
 #endif
            
 
@@ -146,16 +162,11 @@ static int do_isofs_readdir(struct inode *inode, struct file *filp,
                   CDROM sector.  If we are at the end of the directory, we
                   kick out of the while loop. */
 
-               if ((de_len == 0) || (offset >= bufsize) ) {
+               if (de_len == 0) {
                        brelse(bh);
-                       if (de_len == 0) {
-                               filp->f_pos = ((filp->f_pos & ~(ISOFS_BLOCK_SIZE - 1))
-                                              + ISOFS_BLOCK_SIZE);
-                               offset = 0;
-                       } else {
-                               offset -= bufsize;
-                               filp->f_pos += offset;
-                       }
+                       filp->f_pos = ((filp->f_pos & ~(ISOFS_BLOCK_SIZE - 1))
+                                      + ISOFS_BLOCK_SIZE);
+                       offset = 0;
 
                        if (filp->f_pos >= inode->i_size)
                                return 0;
index aa01a2b6432b8991c56966054303a3ff6479e2cd..871e8ef01975ddd0f8b2aba159d9d9aeed5ed331 100644 (file)
@@ -15,6 +15,7 @@
  * within the RPC code when root squashing is suspected.
  */
 
+#include <linux/config.h>
 #include <linux/sched.h>
 #include <linux/kernel.h>
 #include <linux/errno.h>
index a664046a435dc930248d9b07d32c2161da4be055..874775013afa29c792e6e28e8a3ace21fef0c097 100644 (file)
@@ -141,7 +141,7 @@ nfsd_lookup(struct svc_rqst *rqstp, struct svc_fh *fhp, const char *name,
        } else {
                dentry = lookup_one(name, dparent);
                err = PTR_ERR(dentry);
-               if (err)
+               if (IS_ERR(dentry))
                        goto out_nfserr;
                /*
                 * check if we have crossed a mount point ...
@@ -955,7 +955,7 @@ nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp,
         */
        dchild = lookup_one(fname, dentry);
        err = PTR_ERR(dchild);
-       if(IS_ERR(dchild))
+       if (IS_ERR(dchild))
                goto out_nfserr;
 
        err = fh_compose(resfhp, fhp->fh_export, dchild);
index 6ec49bfd701a26c719012456c772733895176367..6f0e188d136f7aa82a61585e3dd00edc1b373fea 100644 (file)
@@ -3,7 +3,7 @@
 O_TARGET := ntfs.o
 O_OBJS   := fs.o sysctl.o support.o util.o inode.o dir.o super.o attr.o
 M_OBJS   := $(O_TARGET)
-EXTRA_CFLAGS = -DNTFS_IN_LINUX_KERNEL -DNTFS_VERSION=\"000410\"
+EXTRA_CFLAGS = -DNTFS_IN_LINUX_KERNEL -DNTFS_VERSION=\"000502\"
 
 include $(TOPDIR)/Rules.make
 
index 238e5c61b01e78ecf79ebc2b4ba3929a4d9ed6d9..b1ad8189589558d940e75f47d6c0ce56aa7a3c59 100644 (file)
@@ -2,10 +2,10 @@
  *  fs.c
  *  NTFS driver for Linux 2.3.x
  *
- *  Copyright (C) 2000, Anton Altaparmakov
  *  Copyright (C) 1995-1997, 1999 Martin von Löwis
  *  Copyright (C) 1996 Richard Russon
  *  Copyright (C) 1996-1997 Régis Duchesne
+ *  Copyright (C) 2000, Anton Altaparmakov
  */
 
 #ifdef HAVE_CONFIG_H
@@ -937,7 +937,7 @@ static int __init init_ntfs_fs(void)
        return register_filesystem(&ntfs_fs_type);
 }
 
-static __exit void exit_ntfs_fs(void)
+static void __exit exit_ntfs_fs(void)
 {
        SYSCTL(0);
        ntfs_debug(DEBUG_OTHER, "unregistering %s\n",ntfs_fs_type.name);
index 2b032d7444b25844bb918aaaf5f614cf40a7c089..6e757e830a7171e4a608801a14a9b4850695b1ea 100644 (file)
@@ -3,6 +3,7 @@
  * Structure definitions
  *
  *  Copyright (C) 1997 Régis Duchesne
+ *  Copyright (C) 2000 Anton Altaparmakov
  */
 
 /* Necessary forward definition */
@@ -42,7 +43,10 @@ typedef struct _ntfs_volume{
        ntfs_u32 at_standard_information;
        ntfs_u32 at_attribute_list;
        ntfs_u32 at_file_name;
+       ntfs_u32 at_volume_version;
        ntfs_u32 at_security_descriptor;
+       ntfs_u32 at_volume_name;
+       ntfs_u32 at_volume_information;
        ntfs_u32 at_data;
        ntfs_u32 at_index_root;
        ntfs_u32 at_index_allocation;
index d7dcb127fa2a33f08c11b485d4ec1fbded8b82f3..7f2a7fe8674b011fbca381cd4e1d80411ab2b3c9 100644 (file)
@@ -4,6 +4,7 @@
  *  Copyright (C) 1995-1997, 1999 Martin von Löwis
  *  Copyright (C) 1996-1997 Régis Duchesne
  *  Copyright (C) 1999 Steve Dodd
+ *  Copyright (C) 2000 Anton Altparmakov
  */
 
 #include "ntfstypes.h"
@@ -62,7 +63,10 @@ int ntfs_init_volume(ntfs_volume *vol,char *boot)
        vol->at_standard_information=0x10;
        vol->at_attribute_list=0x20;
        vol->at_file_name=0x30;
+       vol->at_volume_version=0x40;
        vol->at_security_descriptor=0x50;
+       vol->at_volume_name=0x60;
+       vol->at_volume_information=0x70;
        vol->at_data=0x80;
        vol->at_index_root=0x90;
        vol->at_index_allocation=0xA0;
@@ -141,8 +145,18 @@ process_attrdef(ntfs_inode* attrdef,ntfs_u8* def)
        }else if(ntfs_ua_strncmp(name,"$FILE_NAME",64)==0){
                vol->at_file_name=type;
                check_type=0x30;
+       }else if(ntfs_ua_strncmp(name,"$VOLUME_VERSION",64)==0){
+               vol->at_volume_version=type;
+               check_type=0x40;
        }else if(ntfs_ua_strncmp(name,"$SECURITY_DESCRIPTOR",64)==0){
-               vol->at_file_name=type;
+               vol->at_security_descriptor=type;
+               check_type=0x50;
+       }else if(ntfs_ua_strncmp(name,"$VOLUME_NAME",64)==0){
+               vol->at_volume_name=type;
+               check_type=0x60;
+       }else if(ntfs_ua_strncmp(name,"$VOLUME_INFORMATION",64)==0){
+               vol->at_volume_information=type;
+               check_type=0x70;
        }else if(ntfs_ua_strncmp(name,"$DATA",64)==0){
                vol->at_data=type;
                check_type=0x80;
@@ -158,6 +172,7 @@ process_attrdef(ntfs_inode* attrdef,ntfs_u8* def)
        }else if(ntfs_ua_strncmp(name,"$SYMBOLIC_LINK",64)==0 ||
                 ntfs_ua_strncmp(name,"$REPARSE_POINT",64)==0){
                vol->at_symlink=type;
+               check_type=0xC0;
        }
        if(check_type && check_type!=type){
                ntfs_error("Unexpected type %x for %x\n",type,check_type);
@@ -196,10 +211,32 @@ ntfs_init_attrdef(ntfs_inode* attrdef)
        return error;
 }
 
+/* ntfs_get_version will determine the NTFS version of the 
+   volume and will return the version in a BCD format, with
+   the MSB being the major version number and the LSB the
+   minor one. Otherwise return <0 on error. 
+   Example: version 3.1 will be returned as 0x0301.
+   This has the obvious limitation of not coping with version
+   numbers above 0x80 but that shouldn't be a problem... */
+int ntfs_get_version(ntfs_inode* volume)
+{
+       ntfs_attribute *volinfo;
+       int i;
+
+       volinfo = ntfs_find_attr(volume, volume->vol->at_volume_information, 0);
+       if (!volinfo) 
+               return -EINVAL;
+       if (!volinfo->resident) {
+               ntfs_error("Volume information attribute is not resident!\n");
+               return -EINVAL;
+       }
+       return ((ntfs_u8*)volinfo->d.data)[8] << 8 | ((ntfs_u8*)volinfo->d.data)[9];
+}
+
 int ntfs_load_special_files(ntfs_volume *vol)
 {
        int error;
-       ntfs_inode upcase,attrdef;
+       ntfs_inode upcase, attrdef, volume;
 
        vol->mft_ino=(ntfs_inode*)ntfs_calloc(3*sizeof(ntfs_inode));
        error=ENOMEM;
@@ -232,6 +269,21 @@ int ntfs_load_special_files(ntfs_volume *vol)
        error=ntfs_init_attrdef(&attrdef);
        ntfs_clear_inode(&attrdef);
        if(error)return error;
+
+       /* Check for NTFS version and if Win2k version (ie. 3.0+)
+          do not allow write access since the driver write support
+          is broken, especially for Win2k. */
+       ntfs_debug(DEBUG_BSD,"Going to load VOLUME\n");
+       error = ntfs_init_inode(&volume,vol,FILE_VOLUME);
+       if (error) return error;
+       if ((error = ntfs_get_version(&volume)) >= 0x0300) {
+               NTFS_SB(vol)->s_flags |= MS_RDONLY;
+               ntfs_error("Warning! NTFS volume version is Win2k+: Mounting read-only\n");
+       }
+       ntfs_clear_inode(&volume);
+       if (error < 0) return error;
+       ntfs_debug(DEBUG_BSD, "NTFS volume is version %d.%d\n", error >> 8, error & 0xff);
+
        return 0;
 }
 
index e0f9b236299f8708046d1b8a6300ab813bf7ecac..8f4fc6ca8bd49eb0c447ce3740475667ca9683f1 100644 (file)
@@ -267,6 +267,8 @@ int ntfs_uni_strncmp(short int* a,short int *b,int n)
                        return -1;
                if(b[i]<a[i])
                        return 1;
+               if (a[i] == 0)
+                       return 0;
        }
        return 0;
 }
@@ -282,6 +284,8 @@ int ntfs_ua_strncmp(short int* a,char* b,int n)
                        return -1;
                if(b[i]<NTFS_GETU16(a+i))
                        return 1;
+               if (b[i] == 0)
+                       return 0;
        }
        return 0;
 }
index d4583efc6fb02640340ad658b986693dc3460350..8999d72ffc9b4bdb2f394975dc7674ac8b0d00b4 100644 (file)
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -527,6 +527,8 @@ int do_pipe(int *fd)
 
        error = -ENOMEM;
        f1->f_dentry = f2->f_dentry = dget(d_alloc_root(inode));
+       /* MOUNT_REWRITE: set to pipefs internal vfsmnt */
+       f1->f_vfsmnt = f2->f_vfsmnt = NULL;
        if (!f1->f_dentry)
                goto close_f12_inode_i_j;
 
index ae3c361227e089f286d06cb968aaf4966eb5422d..39111ef9738a8c40874ec9a04d6efea5bf8ecd72 100644 (file)
@@ -40,12 +40,18 @@ int proc_pid_statm(struct task_struct*,char*);
 int proc_pid_cpu(struct task_struct*,char*);
 
 /* MOUNT_REWRITE: make all files have non-NULL ->f_vfsmnt (pipefs, sockfs) */
+/* Until then... */
+#define NULL_VFSMNT    /* remove as soon as pipefs and sockfs will be there */
+
 static int proc_fd_link(struct inode *inode, struct dentry **dentry, struct vfsmount **mnt)
 {
        if (inode->u.proc_i.file) {
-               if (inode->u.proc_i.file->f_vfsmnt) {
-                       *mnt = mntget(inode->u.proc_i.file->f_vfsmnt);
-               }
+#ifdef NULL_VFSMNT
+               if (!inode->u.proc_i.file->f_vfsmnt)
+                       mntget(*mnt);
+               else
+#endif
+               *mnt = mntget(inode->u.proc_i.file->f_vfsmnt);
                *dentry = dget(inode->u.proc_i.file->f_dentry);
                return 0;
        }
@@ -174,7 +180,6 @@ static int standard_permission(struct inode *inode, int mask)
 static int proc_permission(struct inode *inode, int mask)
 {
        struct dentry *de, *base, *root;
-       struct super_block *our_sb, *sb, *below;
        struct vfsmount *our_vfsmnt, *vfsmnt, *mnt;
 
        if (standard_permission(inode, mask) != 0)
@@ -187,14 +192,12 @@ static int proc_permission(struct inode *inode, int mask)
 
        de = root;
        mnt = vfsmnt;
-       our_sb = base->d_inode->i_sb;
-       sb = de->d_inode->i_sb;
-       while (sb != our_sb) {
-               de = sb->s_root->d_covers;
-               below = de->d_inode->i_sb;
-               if (sb == below)
+
+       while (vfsmnt != our_vfsmnt) {
+               if (vfsmnt == vfsmnt->mnt_parent)
                        goto out;
-               sb = below;
+               de = vfsmnt->mnt_mountpoint;
+               vfsmnt = vfsmnt->mnt_parent;
        }
 
        if (!is_subdir(de, base))
@@ -368,6 +371,9 @@ static int proc_pid_follow_link(struct dentry *dentry, struct nameidata *nd)
 {
        struct inode *inode = dentry->d_inode;
        int error;
+#ifdef NULL_VFSMNT
+       struct vfsmount *dummy = mntget(nd->mnt);
+#endif
 
        /* We don't need a base pointer in the /proc filesystem */
        dput(nd->dentry);
@@ -379,6 +385,9 @@ static int proc_pid_follow_link(struct dentry *dentry, struct nameidata *nd)
 
        error = inode->u.proc_i.op.proc_get_link(inode, &nd->dentry, &nd->mnt);
 out:
+#ifdef NULL_VFSMNT
+       mntput(dummy);
+#endif
        return error;
 }
 
index 7c8596822dff6c1b6ec18629bb6bf14819dd5217..a6670c47470bd5fcf08aeefaf7b67277c6fc6b44 100644 (file)
@@ -74,7 +74,7 @@ LIST_HEAD(super_blocks);
  */
 
 static struct file_system_type *file_systems = NULL;
-static spinlock_t file_systems_lock = SPIN_LOCK_UNLOCKED;
+static rwlock_t file_systems_lock = RW_LOCK_UNLOCKED;
 
 /* WARNING: This can be used only if we _already_ own a reference */
 static void get_filesystem(struct file_system_type *fs)
@@ -120,13 +120,13 @@ int register_filesystem(struct file_system_type * fs)
                return -EINVAL;
        if (fs->next)
                return -EBUSY;
-       spin_lock(&file_systems_lock);
+       write_lock(&file_systems_lock);
        p = find_filesystem(fs->name);
        if (*p)
                res = -EBUSY;
        else
                *p = fs;
-       spin_unlock(&file_systems_lock);
+       write_unlock(&file_systems_lock);
        return res;
 }
 
@@ -146,18 +146,18 @@ int unregister_filesystem(struct file_system_type * fs)
 {
        struct file_system_type ** tmp;
 
-       spin_lock(&file_systems_lock);
+       write_lock(&file_systems_lock);
        tmp = &file_systems;
        while (*tmp) {
                if (fs == *tmp) {
                        *tmp = fs->next;
                        fs->next = NULL;
-                       spin_unlock(&file_systems_lock);
+                       write_unlock(&file_systems_lock);
                        return 0;
                }
                tmp = &(*tmp)->next;
        }
-       spin_unlock(&file_systems_lock);
+       write_unlock(&file_systems_lock);
        return -EINVAL;
 }
 
@@ -173,14 +173,14 @@ static int fs_index(const char * __name)
                return err;
 
        err = -EINVAL;
-       spin_lock(&file_systems_lock);
+       read_lock(&file_systems_lock);
        for (tmp=file_systems, index=0 ; tmp ; tmp=tmp->next, index++) {
                if (strcmp(tmp->name,name) == 0) {
                        err = index;
                        break;
                }
        }
-       spin_unlock(&file_systems_lock);
+       read_unlock(&file_systems_lock);
        putname(name);
        return err;
 }
@@ -190,11 +190,11 @@ static int fs_name(unsigned int index, char * buf)
        struct file_system_type * tmp;
        int len, res;
 
-       spin_lock(&file_systems_lock);
+       read_lock(&file_systems_lock);
        for (tmp = file_systems; tmp; tmp = tmp->next, index--)
                if (index <= 0 && try_inc_mod_count(tmp->owner))
                                break;
-       spin_unlock(&file_systems_lock);
+       read_unlock(&file_systems_lock);
        if (!tmp)
                return -EINVAL;
 
@@ -210,10 +210,10 @@ static int fs_maxindex(void)
        struct file_system_type * tmp;
        int index;
 
-       spin_lock(&file_systems_lock);
+       read_lock(&file_systems_lock);
        for (tmp = file_systems, index = 0 ; tmp ; tmp = tmp->next, index++)
                ;
-       spin_unlock(&file_systems_lock);
+       read_unlock(&file_systems_lock);
        return index;
 }
 
@@ -245,7 +245,7 @@ int get_filesystem_list(char * buf)
        int len = 0;
        struct file_system_type * tmp;
 
-       spin_lock(&file_systems_lock);
+       read_lock(&file_systems_lock);
        tmp = file_systems;
        while (tmp && len < PAGE_SIZE - 80) {
                len += sprintf(buf+len, "%s\t%s\n",
@@ -253,7 +253,7 @@ int get_filesystem_list(char * buf)
                        tmp->name);
                tmp = tmp->next;
        }
-       spin_unlock(&file_systems_lock);
+       read_unlock(&file_systems_lock);
        return len;
 }
 
@@ -261,17 +261,17 @@ static struct file_system_type *get_fs_type(const char *name)
 {
        struct file_system_type *fs;
        
-       spin_lock(&file_systems_lock);
+       read_lock(&file_systems_lock);
        fs = *(find_filesystem(name));
        if (fs && !try_inc_mod_count(fs->owner))
                fs = NULL;
-       spin_unlock(&file_systems_lock);
+       read_unlock(&file_systems_lock);
        if (!fs && (request_module(name) == 0)) {
-               spin_lock(&file_systems_lock);
+               read_lock(&file_systems_lock);
                fs = *(find_filesystem(name));
                if (fs && !try_inc_mod_count(fs->owner))
                        fs = NULL;
-               spin_unlock(&file_systems_lock);
+               read_unlock(&file_systems_lock);
        }
        return fs;
 }
@@ -872,16 +872,30 @@ static int do_remount_sb(struct super_block *sb, int flags, char *data)
  * give false negatives. The main reason why it's here is that we need
  * a non-destructive way to look for easily umountable filesystems.
  */
- /* MOUNT_REWRITE: it should take vfsmount, not superblock */
-int may_umount(struct super_block *sb)
+int may_umount(struct vfsmount *mnt)
 {
+       struct super_block * sb = mnt->mnt_sb;
        struct dentry * root;
        int count;
 
+       if (atomic_read(&mnt->mnt_count) > 2)
+               return -EBUSY;
+
+       if (mnt->mnt_instances.next != mnt->mnt_instances.prev)
+               return 0;
+
+       /*
+        * OK, at that point we have only one instance. We should have
+        * one active reference from ->s_root, one active reference
+        * from ->mnt_root (which may be different) and possibly one
+        * active reference from ->mnt_mountpoint (if mnt->mnt_parent == mnt).
+        * Anything above that means that tree is busy.
+        */
+
        root = sb->s_root;
 
        count = d_active_refs(root);
-       if (root->d_covers == root)
+       if (mnt->mnt_parent == mnt)
                count--;
        if (count != 2)
                return -EBUSY;
@@ -1369,22 +1383,21 @@ skip_nfs:
                goto mount_it;
        }
 
-       spin_lock(&file_systems_lock);
+       read_lock(&file_systems_lock);
        for (fs_type = file_systems ; fs_type ; fs_type = fs_type->next) {
                if (!(fs_type->fs_flags & FS_REQUIRES_DEV))
                        continue;
                if (!try_inc_mod_count(fs_type->owner))
                        continue;
-               spin_unlock(&file_systems_lock);
+               read_unlock(&file_systems_lock);
                sb = read_super(ROOT_DEV,bdev,fs_type,root_mountflags,NULL,1);
                if (sb) 
                        goto mount_it;
-               spin_lock(&file_systems_lock);
+               read_lock(&file_systems_lock);
                put_filesystem(fs_type);
        }
-       spin_unlock(&file_systems_lock);
-       panic("VFS: Unable to mount root fs on %s",
-               kdevname(ROOT_DEV));
+       read_unlock(&file_systems_lock);
+       panic("VFS: Unable to mount root fs on %s", kdevname(ROOT_DEV));
 
 mount_it:
        printk ("VFS: Mounted root (%s filesystem)%s.\n",
@@ -1564,7 +1577,8 @@ int __init change_root(kdev_t new_root_dev,const char *put_old)
        mount_root();
 #if 1
        shrink_dcache();
-       printk("change_root: old root has d_count=%d\n", old_root->d_count);
+       printk("change_root: old root has d_count=%d\n", 
+              old_rootmnt->mnt_root->d_count);
 #endif
        mount_devfs_fs ();
        /*
index c9103a39308098b0311ff3cf08ae1963b4023c34..c3c5133d67abfad7af8494dba77c021e3bd918f7 100644 (file)
@@ -18,94 +18,60 @@ typedef struct { int counter; } atomic_t;
 #define atomic_read(v)         ((v)->counter)
 #define atomic_set(v,i)                (((v)->counter) = (i))
 
-extern void atomic_add(int a, atomic_t *v);
-extern int  atomic_add_return(int a, atomic_t *v);
-extern void atomic_sub(int a, atomic_t *v);
-extern void atomic_inc(atomic_t *v);
-extern int  atomic_inc_return(atomic_t *v);
-extern void atomic_dec(atomic_t *v);
-extern int  atomic_dec_return(atomic_t *v);
-extern int  atomic_dec_and_test(atomic_t *v);
-
 extern void atomic_clear_mask(unsigned long mask, unsigned long *addr);
 extern void atomic_set_mask(unsigned long mask, unsigned long *addr);
 
-#if 0  /* for now */
-extern __inline__ void atomic_add(atomic_t a, atomic_t *v)
+extern __inline__ int atomic_add_return(int a, atomic_t *v)
 {
-       atomic_t t;
+       int t;
 
        __asm__ __volatile__("\n\
 1:     lwarx   %0,0,%3\n\
        add     %0,%2,%0\n\
        stwcx.  %0,0,%3\n\
-       bne     1b"
+       bne-    1b"
        : "=&r" (t), "=m" (*v)
-       : "r" (a), "r" (v)
+       : "r" (a), "r" (v), "m" (*v)
        : "cc");
-}
 
-extern __inline__ void atomic_sub(atomic_t a, atomic_t *v)
-{
-       atomic_t t;
-
-       __asm__ __volatile__("\n\
-1:     lwarx   %0,0,%3\n\
-       subf    %0,%2,%0\n\
-       stwcx.  %0,0,%3\n\
-       bne     1b"
-       : "=&r" (t), "=m" (*v)
-       : "r" (a), "r" (v)
-       : "cc");
+       return t;
 }
 
-extern __inline__ int atomic_sub_and_test(atomic_t a, atomic_t *v)
+extern __inline__ int atomic_sub_return(int a, atomic_t *v)
 {
-       atomic_t t;
+       int t;
 
        __asm__ __volatile__("\n\
 1:     lwarx   %0,0,%3\n\
        subf    %0,%2,%0\n\
        stwcx.  %0,0,%3\n\
-       bne     1b"
+       bne-    1b"
        : "=&r" (t), "=m" (*v)
-       : "r" (a), "r" (v)
+       : "r" (a), "r" (v), "m" (*v)
        : "cc");
 
-       return t == 0;
+       return t;
 }
 
-extern __inline__ void atomic_inc(atomic_t *v)
+extern __inline__ int atomic_inc_return(atomic_t *v)
 {
-       atomic_t t;
+       int t;
 
        __asm__ __volatile__("\n\
 1:     lwarx   %0,0,%2\n\
        addic   %0,%0,1\n\
        stwcx.  %0,0,%2\n\
-       bne     1b"
+       bne-    1b"
        : "=&r" (t), "=m" (*v)
-       : "r" (v)
+       : "r" (v), "m" (*v)
        : "cc");
-}
-
-extern __inline__ void atomic_dec(atomic_t *v)
-{
-       atomic_t t;
 
-       __asm__ __volatile__("\n\
-1:     lwarx   %0,0,%2\n\
-       addic   %0,%0,-1\n\
-       stwcx.  %0,0,%2\n\
-       bne     1b"
-       : "=&r" (t), "=m" (*v)
-       : "r" (v)
-       : "cc");
+       return t;
 }
 
-extern __inline__ int atomic_dec_and_test(atomic_t *v)
+extern __inline__ int atomic_dec_return(atomic_t *v)
 {
-       atomic_t t;
+       int t;
 
        __asm__ __volatile__("\n\
 1:     lwarx   %0,0,%2\n\
@@ -113,11 +79,17 @@ extern __inline__ int atomic_dec_and_test(atomic_t *v)
        stwcx.  %0,0,%2\n\
        bne     1b"
        : "=&r" (t), "=m" (*v)
-       : "r" (v)
+       : "r" (v), "m" (*v)
        : "cc");
 
-       return t == 0;
+       return t;
 }
-#endif /* 0 */
+
+#define atomic_add(a, v)               ((void) atomic_add_return((a), (v)))
+#define atomic_sub(a, v)               ((void) atomic_sub_return((a), (v)))
+#define atomic_sub_and_test(a, v)      (atomic_sub_return((a), (v)) == 0)
+#define atomic_inc(v)                  ((void) atomic_inc_return((v)))
+#define atomic_dec(v)                  ((void) atomic_dec_return((v)))
+#define atomic_dec_and_test(v)         (atomic_dec_return((v)) == 0)
 
 #endif /* _ASM_PPC_ATOMIC_H_ */
index c981d5fa01b109db79c51a21a390fb35a598f06c..3c89fcf8a363381f2c4a912ab28820b368cdbff7 100644 (file)
@@ -16,15 +16,18 @@ extern int test_and_set_bit(int nr, volatile void *addr);
 extern int test_and_clear_bit(int nr, volatile void *addr);
 extern int test_and_change_bit(int nr, volatile void *addr);
 
-
-/* Returns the number of 0's to the left of the most significant 1 bit */
-extern __inline__  int cntlzw(int bits)
-{
-       int lz;
-
-       asm ("cntlzw %0,%1" : "=r" (lz) : "r" (bits));
-       return lz;
-}
+/*
+ * Arguably these bit operations don't imply any memory barrier or
+ * SMP ordering, but in fact a lot of drivers expect them to imply
+ * both, since they do on x86 cpus.
+ */
+#ifdef CONFIG_SMP
+#define SMP_WMB                "eieio\n"
+#define SMP_MB         "\nsync"
+#else
+#define SMP_WMB
+#define SMP_MB
+#endif /* CONFIG_SMP */
 
 /*
  * These are if'd out here because using : "cc" as a constraint
@@ -95,15 +98,20 @@ extern __inline__ int test_bit(int nr, __const__ volatile void *addr)
        return ((p[nr >> 5] >> (nr & 0x1f)) & 1) != 0;
 }
 
-extern __inline__ int ffz(unsigned int x)
+/* Return the bit position of the most significant 1 bit in a word */
+extern __inline__ int __ilog2(unsigned int x)
 {
-       int n;
+       int lz;
+
+       asm ("cntlzw %0,%1" : "=r" (lz) : "r" (x));
+       return 31 - lz;
+}
 
-       if (x == ~0)
+extern __inline__ int ffz(unsigned int x)
+{
+       if ((x = ~x) == 0)
                return 32;
-       x = ~x & (x+1);         /* set LS zero to 1, other bits to 0 */
-       __asm__ ("cntlzw %0,%1" : "=r" (n) : "r" (x));
-       return 31 - n;
+       return __ilog2(x & -x);
 }
 
 #ifdef __KERNEL__
@@ -113,19 +121,10 @@ extern __inline__ int ffz(unsigned int x)
  * the libc and compiler builtin ffs routines, therefore
  * differs in spirit from the above ffz (man ffs).
  */
-
-#define ffs(x) generic_ffs(x)
-
-#if 0
-/* untested, someone with PPC knowledge? */
-/* From Alexander Kjeldaas <astor@guardian.no> */
 extern __inline__ int ffs(int x)
 {
-        int result;
-        asm ("cntlzw %0,%1" : "=r" (result) : "r" (x));
-        return 32 - result; /* IBM backwards ordering of bits */
+       return __ilog2(x & -x) + 1;
 }
-#endif
 
 /*
  * hweightN: returns the hamming weight (i.e. the number
index 0a7f7968951267efc43538c4b3278b4aa375c5bb..069ad9707bccfcac11804a95f0615d376b20021d 100644 (file)
@@ -8,11 +8,16 @@
 #include <asm/processor.h>
 
 /* bytes per L1 cache line */
-#define        L1_CACHE_BYTES  32      
-#define        L1_CACHE_ALIGN(x)       (((x)+(L1_CACHE_BYTES-1))&~(L1_CACHE_BYTES-1))
-#define L1_CACHE_PAGES         8
+#if !defined(CONFIG_8xx) || defined(CONFIG_8260)
+#define        L1_CACHE_BYTES  32
+#else
+#define        L1_CACHE_BYTES  16
+#endif /* !8xx || 8260 */
+
+#define        L1_CACHE_ALIGN(x)       (((x)+(L1_CACHE_BYTES-1))&~(L1_CACHE_BYTES-1))
+#define        L1_CACHE_PAGES          8
 
-#define        SMP_CACHE_BYTES L1_CACHE_BYTES
+#define        SMP_CACHE_BYTES L1_CACHE_BYTES
 
 #ifdef MODULE
 #define __cacheline_aligned __attribute__((__aligned__(L1_CACHE_BYTES)))
diff --git a/include/asm-ppc/cpm_8260.h b/include/asm-ppc/cpm_8260.h
new file mode 100644 (file)
index 0000000..c479f87
--- /dev/null
@@ -0,0 +1,551 @@
+
+/*
+ * MPC8260 Communication Processor Module.
+ * Copyright (c) 1999 Dan Malek (dmalek@jlc.net)
+ *
+ * This file contains structures and information for the communication
+ * processor channels found in the dual port RAM or parameter RAM.
+ * All CPM control and status is available through the MPC8260 internal
+ * memory map.  See immap.h for details.
+ */
+#ifndef __CPM_82XX__
+#define __CPM_82XX__
+
+#include <asm/immap_8260.h>
+
+/* CPM Command register.
+*/
+#define CPM_CR_RST     ((uint)0x80000000)
+#define CPM_CR_PAGE    ((uint)0x7c000000)
+#define CPM_CR_SBLOCK  ((uint)0x03e00000)
+#define CPM_CR_FLG     ((uint)0x00010000)
+#define CPM_CR_MCN     ((uint)0x00003fc0)
+#define CPM_CR_OPCODE  ((uint)0x0000000f)
+
+/* Device sub-block and page codes.
+*/
+#define CPM_CR_SCC1_SBLOCK     (0x04)
+#define CPM_CR_SCC2_SBLOCK     (0x05)
+#define CPM_CR_SCC3_SBLOCK     (0x06)
+#define CPM_CR_SCC4_SBLOCK     (0x07)
+#define CPM_CR_SMC1_SBLOCK     (0x08)
+#define CPM_CR_SMC2_SBLOCK     (0x09)
+#define CPM_CR_SPI_SBLOCK      (0x0a)
+#define CPM_CR_I2C_SBLOCK      (0x0b)
+#define CPM_CR_TIMER_SBLOCK    (0x0f)
+#define CPM_CR_RAND_SBLOCK     (0x0e)
+#define CPM_CR_FCC1_SBLOCK     (0x10)
+#define CPM_CR_FCC2_SBLOCK     (0x11)
+#define CPM_CR_FCC3_SBLOCK     (0x12)
+#define CPM_CR_IDMA1_SBLOCK    (0x14)
+#define CPM_CR_IDMA2_SBLOCK    (0x15)
+#define CPM_CR_IDMA3_SBLOCK    (0x16)
+#define CPM_CR_IDMA4_SBLOCK    (0x17)
+#define CPM_CR_MCC1_SBLOCK     (0x1c)
+
+#define CPM_CR_SCC1_PAGE       (0x00)
+#define CPM_CR_SCC2_PAGE       (0x01)
+#define CPM_CR_SCC3_PAGE       (0x02)
+#define CPM_CR_SCC4_PAGE       (0x03)
+#define CPM_CR_SMC1_PAGE       (0x07)
+#define CPM_CR_SMC2_PAGE       (0x08)
+#define CPM_CR_SPI_PAGE                (0x09)
+#define CPM_CR_I2C_PAGE                (0x0a)
+#define CPM_CR_TIMER_PAGE      (0x0a)
+#define CPM_CR_RAND_PAGE       (0x0a)
+#define CPM_CR_FCC1_PAGE       (0x04)
+#define CPM_CR_FCC2_PAGE       (0x05)
+#define CPM_CR_FCC3_PAGE       (0x06)
+#define CPM_CR_IDMA1_PAGE      (0x07)
+#define CPM_CR_IDMA2_PAGE      (0x08)
+#define CPM_CR_IDMA3_PAGE      (0x09)
+#define CPM_CR_IDMA4_PAGE      (0x0a)
+#define CPM_CR_MCC1_PAGE       (0x07)
+#define CPM_CR_MCC2_PAGE       (0x08)
+
+/* Some opcodes (there are more...later)
+*/
+#define CPM_CR_INIT_TRX                ((ushort)0x0000)
+#define CPM_CR_INIT_RX         ((ushort)0x0001)
+#define CPM_CR_INIT_TX         ((ushort)0x0002)
+#define CPM_CR_HUNT_MODE       ((ushort)0x0003)
+#define CPM_CR_STOP_TX         ((ushort)0x0004)
+#define CPM_CR_RESTART_TX      ((ushort)0x0006)
+#define CPM_CR_SET_GADDR       ((ushort)0x0008)
+
+#define mk_cr_cmd(PG, SBC, MCN, OP) \
+       ((PG << 26) | (SBC << 21) | (MCN << 6) | OP)
+
+/* Dual Port RAM addresses.  The first 16K is available for almost
+ * any CPM use, so we put the BDs there.  The first 128 bytes are
+ * used for SMC1 and SMC2 parameter RAM, so we start allocating
+ * BDs above that.  All of this must change when we start
+ * downloading RAM microcode.
+ */
+#define CPM_DATAONLY_BASE      ((uint)128)
+#define CPM_DATAONLY_SIZE      ((uint)(16 * 1024) - CPM_DATAONLY_BASE)
+#define CPM_DP_NOSPACE         ((uint)0x7fffffff)
+
+/* The number of pages of host memory we allocate for CPM.  This is
+ * done early in kernel initialization to get physically contiguous
+ * pages.
+ */
+#define NUM_CPM_HOST_PAGES     2
+
+
+/* Export the base address of the communication processor registers
+ * and dual port ram.
+ */
+extern cpm8260_t       *cpmp;          /* Pointer to comm processor */
+uint           m8260_cpm_dpalloc(uint size);
+uint           m8260_cpm_hostalloc(uint size);
+void           m8260_cpm_setbrg(uint brg, uint rate);
+void           m8260_cpm_fastbrg(uint brg, uint rate, int div16);
+
+/* Buffer descriptors used by many of the CPM protocols.
+*/
+typedef struct cpm_buf_desc {
+       ushort  cbd_sc;         /* Status and Control */
+       ushort  cbd_datlen;     /* Data length in buffer */
+       uint    cbd_bufaddr;    /* Buffer address in host memory */
+} cbd_t;
+
+#define BD_SC_EMPTY    ((ushort)0x8000)        /* Recieve is empty */
+#define BD_SC_READY    ((ushort)0x8000)        /* Transmit is ready */
+#define BD_SC_WRAP     ((ushort)0x2000)        /* Last buffer descriptor */
+#define BD_SC_INTRPT   ((ushort)0x1000)        /* Interrupt on change */
+#define BD_SC_LAST     ((ushort)0x0800)        /* Last buffer in frame */
+#define BD_SC_CM       ((ushort)0x0200)        /* Continous mode */
+#define BD_SC_ID       ((ushort)0x0100)        /* Rec'd too many idles */
+#define BD_SC_P                ((ushort)0x0100)        /* xmt preamble */
+#define BD_SC_BR       ((ushort)0x0020)        /* Break received */
+#define BD_SC_FR       ((ushort)0x0010)        /* Framing error */
+#define BD_SC_PR       ((ushort)0x0008)        /* Parity error */
+#define BD_SC_OV       ((ushort)0x0002)        /* Overrun */
+#define BD_SC_CD       ((ushort)0x0001)        /* ?? */
+
+/* Parameter RAM offsets from the base.
+*/
+#define PROFF_SCC1             ((uint)0x8000)
+#define PROFF_SCC2             ((uint)0x8100)
+#define PROFF_SCC3             ((uint)0x8200)
+#define PROFF_SCC4             ((uint)0x8300)
+#define PROFF_FCC1             ((uint)0x8400)
+#define PROFF_FCC2             ((uint)0x8500)
+#define PROFF_FCC3             ((uint)0x8600)
+#define PROFF_MCC1             ((uint)0x8700)
+#define PROFF_SMC1_BASE                ((uint)0x87fc)
+#define PROFF_IDMA1_BASE       ((uint)0x87fe)
+#define PROFF_MCC2             ((uint)0x8800)
+#define PROFF_SMC2_BASE                ((uint)0x88fc)
+#define PROFF_IDMA2_BASE       ((uint)0x88fe)
+#define PROFF_SPI_BASE         ((uint)0x89fc)
+#define PROFF_IDMA3_BASE       ((uint)0x89fe)
+#define PROFF_TIMERS           ((uint)0x8ae0)
+#define PROFF_REVNUM           ((uint)0x8af0)
+#define PROFF_RAND             ((uint)0x8af8)
+#define PROFF_I2C_BASE         ((uint)0x8afc)
+#define PROFF_IDMA4_BASE       ((uint)0x89fe)
+
+/* The SMCs are relocated to any of the first eight DPRAM pages.
+ * We will fix these at the first locations of DPRAM, until we
+ * get some microcode patches :-).
+ * The parameter ram space for the SMCs is fifty-some bytes, and
+ * they are required to start on a 64 byte boundary.
+ */
+#define PROFF_SMC1     (0)
+#define PROFF_SMC2     (64)
+
+
+/* Define enough so I can at least use the serial port as a UART.
+ */
+typedef struct smc_uart {
+       ushort  smc_rbase;      /* Rx Buffer descriptor base address */
+       ushort  smc_tbase;      /* Tx Buffer descriptor base address */
+       u_char  smc_rfcr;       /* Rx function code */
+       u_char  smc_tfcr;       /* Tx function code */
+       ushort  smc_mrblr;      /* Max receive buffer length */
+       uint    smc_rstate;     /* Internal */
+       uint    smc_idp;        /* Internal */
+       ushort  smc_rbptr;      /* Internal */
+       ushort  smc_ibc;        /* Internal */
+       uint    smc_rxtmp;      /* Internal */
+       uint    smc_tstate;     /* Internal */
+       uint    smc_tdp;        /* Internal */
+       ushort  smc_tbptr;      /* Internal */
+       ushort  smc_tbc;        /* Internal */
+       uint    smc_txtmp;      /* Internal */
+       ushort  smc_maxidl;     /* Maximum idle characters */
+       ushort  smc_tmpidl;     /* Temporary idle counter */
+       ushort  smc_brklen;     /* Last received break length */
+       ushort  smc_brkec;      /* rcv'd break condition counter */
+       ushort  smc_brkcr;      /* xmt break count register */
+       ushort  smc_rmask;      /* Temporary bit mask */
+       uint    smc_stmp;       /* SDMA Temp */
+} smc_uart_t;
+
+/* Function code bits.
+*/
+#define SMC_GBL        ((u_char)0x20)  /* Set memory snooping */
+#define SMC_EB ((u_char)0x10)  /* Set big endian byte order */
+#define SMC_TC2        ((u_char)0x04)  /* Transfer code 2 value */
+#define SMC_DTB        ((u_char)0x02)  /* Use local bus when set */
+
+/* SMC uart mode register (Internal memory map).
+*/
+#define        SMCMR_REN       ((ushort)0x0001)
+#define SMCMR_TEN      ((ushort)0x0002)
+#define SMCMR_DM       ((ushort)0x000c)
+#define SMCMR_SM_GCI   ((ushort)0x0000)
+#define SMCMR_SM_UART  ((ushort)0x0020)
+#define SMCMR_SM_TRANS ((ushort)0x0030)
+#define SMCMR_SM_MASK  ((ushort)0x0030)
+#define SMCMR_PM_EVEN  ((ushort)0x0100)        /* Even parity, else odd */
+#define SMCMR_REVD     SMCMR_PM_EVEN
+#define SMCMR_PEN      ((ushort)0x0200)        /* Parity enable */
+#define SMCMR_BS       SMCMR_PEN
+#define SMCMR_SL       ((ushort)0x0400)        /* Two stops, else one */
+#define SMCR_CLEN_MASK ((ushort)0x7800)        /* Character length */
+#define smcr_mk_clen(C)        (((C) << 11) & SMCR_CLEN_MASK)
+
+/* SMC Event and Mask register.
+*/
+#define        SMCM_TXE        ((unsigned char)0x10)
+#define        SMCM_BSY        ((unsigned char)0x04)
+#define        SMCM_TX         ((unsigned char)0x02)
+#define        SMCM_RX         ((unsigned char)0x01)
+
+/* Baud rate generators.
+*/
+#define CPM_BRG_RST            ((uint)0x00020000)
+#define CPM_BRG_EN             ((uint)0x00010000)
+#define CPM_BRG_EXTC_INT       ((uint)0x00000000)
+#define CPM_BRG_EXTC_CLK3_9    ((uint)0x00004000)
+#define CPM_BRG_EXTC_CLK5_15   ((uint)0x00008000)
+#define CPM_BRG_ATB            ((uint)0x00002000)
+#define CPM_BRG_CD_MASK                ((uint)0x00001ffe)
+#define CPM_BRG_DIV16          ((uint)0x00000001)
+
+/* SCCs.
+*/
+#define SCC_GSMRH_IRP          ((uint)0x00040000)
+#define SCC_GSMRH_GDE          ((uint)0x00010000)
+#define SCC_GSMRH_TCRC_CCITT   ((uint)0x00008000)
+#define SCC_GSMRH_TCRC_BISYNC  ((uint)0x00004000)
+#define SCC_GSMRH_TCRC_HDLC    ((uint)0x00000000)
+#define SCC_GSMRH_REVD         ((uint)0x00002000)
+#define SCC_GSMRH_TRX          ((uint)0x00001000)
+#define SCC_GSMRH_TTX          ((uint)0x00000800)
+#define SCC_GSMRH_CDP          ((uint)0x00000400)
+#define SCC_GSMRH_CTSP         ((uint)0x00000200)
+#define SCC_GSMRH_CDS          ((uint)0x00000100)
+#define SCC_GSMRH_CTSS         ((uint)0x00000080)
+#define SCC_GSMRH_TFL          ((uint)0x00000040)
+#define SCC_GSMRH_RFW          ((uint)0x00000020)
+#define SCC_GSMRH_TXSY         ((uint)0x00000010)
+#define SCC_GSMRH_SYNL16       ((uint)0x0000000c)
+#define SCC_GSMRH_SYNL8                ((uint)0x00000008)
+#define SCC_GSMRH_SYNL4                ((uint)0x00000004)
+#define SCC_GSMRH_RTSM         ((uint)0x00000002)
+#define SCC_GSMRH_RSYN         ((uint)0x00000001)
+
+#define SCC_GSMRL_SIR          ((uint)0x80000000)      /* SCC2 only */
+#define SCC_GSMRL_EDGE_NONE    ((uint)0x60000000)
+#define SCC_GSMRL_EDGE_NEG     ((uint)0x40000000)
+#define SCC_GSMRL_EDGE_POS     ((uint)0x20000000)
+#define SCC_GSMRL_EDGE_BOTH    ((uint)0x00000000)
+#define SCC_GSMRL_TCI          ((uint)0x10000000)
+#define SCC_GSMRL_TSNC_3       ((uint)0x0c000000)
+#define SCC_GSMRL_TSNC_4       ((uint)0x08000000)
+#define SCC_GSMRL_TSNC_14      ((uint)0x04000000)
+#define SCC_GSMRL_TSNC_INF     ((uint)0x00000000)
+#define SCC_GSMRL_RINV         ((uint)0x02000000)
+#define SCC_GSMRL_TINV         ((uint)0x01000000)
+#define SCC_GSMRL_TPL_128      ((uint)0x00c00000)
+#define SCC_GSMRL_TPL_64       ((uint)0x00a00000)
+#define SCC_GSMRL_TPL_48       ((uint)0x00800000)
+#define SCC_GSMRL_TPL_32       ((uint)0x00600000)
+#define SCC_GSMRL_TPL_16       ((uint)0x00400000)
+#define SCC_GSMRL_TPL_8                ((uint)0x00200000)
+#define SCC_GSMRL_TPL_NONE     ((uint)0x00000000)
+#define SCC_GSMRL_TPP_ALL1     ((uint)0x00180000)
+#define SCC_GSMRL_TPP_01       ((uint)0x00100000)
+#define SCC_GSMRL_TPP_10       ((uint)0x00080000)
+#define SCC_GSMRL_TPP_ZEROS    ((uint)0x00000000)
+#define SCC_GSMRL_TEND         ((uint)0x00040000)
+#define SCC_GSMRL_TDCR_32      ((uint)0x00030000)
+#define SCC_GSMRL_TDCR_16      ((uint)0x00020000)
+#define SCC_GSMRL_TDCR_8       ((uint)0x00010000)
+#define SCC_GSMRL_TDCR_1       ((uint)0x00000000)
+#define SCC_GSMRL_RDCR_32      ((uint)0x0000c000)
+#define SCC_GSMRL_RDCR_16      ((uint)0x00008000)
+#define SCC_GSMRL_RDCR_8       ((uint)0x00004000)
+#define SCC_GSMRL_RDCR_1       ((uint)0x00000000)
+#define SCC_GSMRL_RENC_DFMAN   ((uint)0x00003000)
+#define SCC_GSMRL_RENC_MANCH   ((uint)0x00002000)
+#define SCC_GSMRL_RENC_FM0     ((uint)0x00001000)
+#define SCC_GSMRL_RENC_NRZI    ((uint)0x00000800)
+#define SCC_GSMRL_RENC_NRZ     ((uint)0x00000000)
+#define SCC_GSMRL_TENC_DFMAN   ((uint)0x00000600)
+#define SCC_GSMRL_TENC_MANCH   ((uint)0x00000400)
+#define SCC_GSMRL_TENC_FM0     ((uint)0x00000200)
+#define SCC_GSMRL_TENC_NRZI    ((uint)0x00000100)
+#define SCC_GSMRL_TENC_NRZ     ((uint)0x00000000)
+#define SCC_GSMRL_DIAG_LE      ((uint)0x000000c0)      /* Loop and echo */
+#define SCC_GSMRL_DIAG_ECHO    ((uint)0x00000080)
+#define SCC_GSMRL_DIAG_LOOP    ((uint)0x00000040)
+#define SCC_GSMRL_DIAG_NORM    ((uint)0x00000000)
+#define SCC_GSMRL_ENR          ((uint)0x00000020)
+#define SCC_GSMRL_ENT          ((uint)0x00000010)
+#define SCC_GSMRL_MODE_ENET    ((uint)0x0000000c)
+#define SCC_GSMRL_MODE_DDCMP   ((uint)0x00000009)
+#define SCC_GSMRL_MODE_BISYNC  ((uint)0x00000008)
+#define SCC_GSMRL_MODE_V14     ((uint)0x00000007)
+#define SCC_GSMRL_MODE_AHDLC   ((uint)0x00000006)
+#define SCC_GSMRL_MODE_PROFIBUS        ((uint)0x00000005)
+#define SCC_GSMRL_MODE_UART    ((uint)0x00000004)
+#define SCC_GSMRL_MODE_SS7     ((uint)0x00000003)
+#define SCC_GSMRL_MODE_ATALK   ((uint)0x00000002)
+#define SCC_GSMRL_MODE_HDLC    ((uint)0x00000000)
+
+#define SCC_TODR_TOD           ((ushort)0x8000)
+
+/* SCC Event and Mask register.
+*/
+#define        SCCM_TXE        ((unsigned char)0x10)
+#define        SCCM_BSY        ((unsigned char)0x04)
+#define        SCCM_TX         ((unsigned char)0x02)
+#define        SCCM_RX         ((unsigned char)0x01)
+
+typedef struct scc_param {
+       ushort  scc_rbase;      /* Rx Buffer descriptor base address */
+       ushort  scc_tbase;      /* Tx Buffer descriptor base address */
+       u_char  scc_rfcr;       /* Rx function code */
+       u_char  scc_tfcr;       /* Tx function code */
+       ushort  scc_mrblr;      /* Max receive buffer length */
+       uint    scc_rstate;     /* Internal */
+       uint    scc_idp;        /* Internal */
+       ushort  scc_rbptr;      /* Internal */
+       ushort  scc_ibc;        /* Internal */
+       uint    scc_rxtmp;      /* Internal */
+       uint    scc_tstate;     /* Internal */
+       uint    scc_tdp;        /* Internal */
+       ushort  scc_tbptr;      /* Internal */
+       ushort  scc_tbc;        /* Internal */
+       uint    scc_txtmp;      /* Internal */
+       uint    scc_rcrc;       /* Internal */
+       uint    scc_tcrc;       /* Internal */
+} sccp_t;
+
+/* Function code bits.
+*/
+#define SCC_EB ((u_char)0x10)  /* Set big endian byte order */
+
+/* CPM Ethernet through SCC1.
+ */
+typedef struct scc_enet {
+       sccp_t  sen_genscc;
+       uint    sen_cpres;      /* Preset CRC */
+       uint    sen_cmask;      /* Constant mask for CRC */
+       uint    sen_crcec;      /* CRC Error counter */
+       uint    sen_alec;       /* alignment error counter */
+       uint    sen_disfc;      /* discard frame counter */
+       ushort  sen_pads;       /* Tx short frame pad character */
+       ushort  sen_retlim;     /* Retry limit threshold */
+       ushort  sen_retcnt;     /* Retry limit counter */
+       ushort  sen_maxflr;     /* maximum frame length register */
+       ushort  sen_minflr;     /* minimum frame length register */
+       ushort  sen_maxd1;      /* maximum DMA1 length */
+       ushort  sen_maxd2;      /* maximum DMA2 length */
+       ushort  sen_maxd;       /* Rx max DMA */
+       ushort  sen_dmacnt;     /* Rx DMA counter */
+       ushort  sen_maxb;       /* Max BD byte count */
+       ushort  sen_gaddr1;     /* Group address filter */
+       ushort  sen_gaddr2;
+       ushort  sen_gaddr3;
+       ushort  sen_gaddr4;
+       uint    sen_tbuf0data0; /* Save area 0 - current frame */
+       uint    sen_tbuf0data1; /* Save area 1 - current frame */
+       uint    sen_tbuf0rba;   /* Internal */
+       uint    sen_tbuf0crc;   /* Internal */
+       ushort  sen_tbuf0bcnt;  /* Internal */
+       ushort  sen_paddrh;     /* physical address (MSB) */
+       ushort  sen_paddrm;
+       ushort  sen_paddrl;     /* physical address (LSB) */
+       ushort  sen_pper;       /* persistence */
+       ushort  sen_rfbdptr;    /* Rx first BD pointer */
+       ushort  sen_tfbdptr;    /* Tx first BD pointer */
+       ushort  sen_tlbdptr;    /* Tx last BD pointer */
+       uint    sen_tbuf1data0; /* Save area 0 - current frame */
+       uint    sen_tbuf1data1; /* Save area 1 - current frame */
+       uint    sen_tbuf1rba;   /* Internal */
+       uint    sen_tbuf1crc;   /* Internal */
+       ushort  sen_tbuf1bcnt;  /* Internal */
+       ushort  sen_txlen;      /* Tx Frame length counter */
+       ushort  sen_iaddr1;     /* Individual address filter */
+       ushort  sen_iaddr2;
+       ushort  sen_iaddr3;
+       ushort  sen_iaddr4;
+       ushort  sen_boffcnt;    /* Backoff counter */
+
+       /* NOTE: Some versions of the manual have the following items
+        * incorrectly documented.  Below is the proper order.
+        */
+       ushort  sen_taddrh;     /* temp address (MSB) */
+       ushort  sen_taddrm;
+       ushort  sen_taddrl;     /* temp address (LSB) */
+} scc_enet_t;
+
+
+/* SCC Event register as used by Ethernet.
+*/
+#define SCCE_ENET_GRA  ((ushort)0x0080)        /* Graceful stop complete */
+#define SCCE_ENET_TXE  ((ushort)0x0010)        /* Transmit Error */
+#define SCCE_ENET_RXF  ((ushort)0x0008)        /* Full frame received */
+#define SCCE_ENET_BSY  ((ushort)0x0004)        /* All incoming buffers full */
+#define SCCE_ENET_TXB  ((ushort)0x0002)        /* A buffer was transmitted */
+#define SCCE_ENET_RXB  ((ushort)0x0001)        /* A buffer was received */
+
+/* SCC Mode Register (PMSR) as used by Ethernet.
+*/
+#define SCC_PMSR_HBC   ((ushort)0x8000)        /* Enable heartbeat */
+#define SCC_PMSR_FC    ((ushort)0x4000)        /* Force collision */
+#define SCC_PMSR_RSH   ((ushort)0x2000)        /* Receive short frames */
+#define SCC_PMSR_IAM   ((ushort)0x1000)        /* Check individual hash */
+#define SCC_PMSR_ENCRC ((ushort)0x0800)        /* Ethernet CRC mode */
+#define SCC_PMSR_PRO   ((ushort)0x0200)        /* Promiscuous mode */
+#define SCC_PMSR_BRO   ((ushort)0x0100)        /* Catch broadcast pkts */
+#define SCC_PMSR_SBT   ((ushort)0x0080)        /* Special backoff timer */
+#define SCC_PMSR_LPB   ((ushort)0x0040)        /* Set Loopback mode */
+#define SCC_PMSR_SIP   ((ushort)0x0020)        /* Sample Input Pins */
+#define SCC_PMSR_LCW   ((ushort)0x0010)        /* Late collision window */
+#define SCC_PMSR_NIB22 ((ushort)0x000a)        /* Start frame search */
+#define SCC_PMSR_FDE   ((ushort)0x0001)        /* Full duplex enable */
+
+/* Buffer descriptor control/status used by Ethernet receive.
+*/
+#define BD_ENET_RX_EMPTY       ((ushort)0x8000)
+#define BD_ENET_RX_WRAP                ((ushort)0x2000)
+#define BD_ENET_RX_INTR                ((ushort)0x1000)
+#define BD_ENET_RX_LAST                ((ushort)0x0800)
+#define BD_ENET_RX_FIRST       ((ushort)0x0400)
+#define BD_ENET_RX_MISS                ((ushort)0x0100)
+#define BD_ENET_RX_LG          ((ushort)0x0020)
+#define BD_ENET_RX_NO          ((ushort)0x0010)
+#define BD_ENET_RX_SH          ((ushort)0x0008)
+#define BD_ENET_RX_CR          ((ushort)0x0004)
+#define BD_ENET_RX_OV          ((ushort)0x0002)
+#define BD_ENET_RX_CL          ((ushort)0x0001)
+#define BD_ENET_RX_STATS       ((ushort)0x013f)        /* All status bits */
+
+/* Buffer descriptor control/status used by Ethernet transmit.
+*/
+#define BD_ENET_TX_READY       ((ushort)0x8000)
+#define BD_ENET_TX_PAD         ((ushort)0x4000)
+#define BD_ENET_TX_WRAP                ((ushort)0x2000)
+#define BD_ENET_TX_INTR                ((ushort)0x1000)
+#define BD_ENET_TX_LAST                ((ushort)0x0800)
+#define BD_ENET_TX_TC          ((ushort)0x0400)
+#define BD_ENET_TX_DEF         ((ushort)0x0200)
+#define BD_ENET_TX_HB          ((ushort)0x0100)
+#define BD_ENET_TX_LC          ((ushort)0x0080)
+#define BD_ENET_TX_RL          ((ushort)0x0040)
+#define BD_ENET_TX_RCMASK      ((ushort)0x003c)
+#define BD_ENET_TX_UN          ((ushort)0x0002)
+#define BD_ENET_TX_CSL         ((ushort)0x0001)
+#define BD_ENET_TX_STATS       ((ushort)0x03ff)        /* All status bits */
+
+/* SCC as UART
+*/
+typedef struct scc_uart {
+       sccp_t  scc_genscc;
+       uint    scc_res1;       /* Reserved */
+       uint    scc_res2;       /* Reserved */
+       ushort  scc_maxidl;     /* Maximum idle chars */
+       ushort  scc_idlc;       /* temp idle counter */
+       ushort  scc_brkcr;      /* Break count register */
+       ushort  scc_parec;      /* receive parity error counter */
+       ushort  scc_frmec;      /* receive framing error counter */
+       ushort  scc_nosec;      /* receive noise counter */
+       ushort  scc_brkec;      /* receive break condition counter */
+       ushort  scc_brkln;      /* last received break length */
+       ushort  scc_uaddr1;     /* UART address character 1 */
+       ushort  scc_uaddr2;     /* UART address character 2 */
+       ushort  scc_rtemp;      /* Temp storage */
+       ushort  scc_toseq;      /* Transmit out of sequence char */
+       ushort  scc_char1;      /* control character 1 */
+       ushort  scc_char2;      /* control character 2 */
+       ushort  scc_char3;      /* control character 3 */
+       ushort  scc_char4;      /* control character 4 */
+       ushort  scc_char5;      /* control character 5 */
+       ushort  scc_char6;      /* control character 6 */
+       ushort  scc_char7;      /* control character 7 */
+       ushort  scc_char8;      /* control character 8 */
+       ushort  scc_rccm;       /* receive control character mask */
+       ushort  scc_rccr;       /* receive control character register */
+       ushort  scc_rlbc;       /* receive last break character */
+} scc_uart_t;
+
+/* SCC Event and Mask registers when it is used as a UART.
+*/
+#define UART_SCCM_GLR          ((ushort)0x1000)
+#define UART_SCCM_GLT          ((ushort)0x0800)
+#define UART_SCCM_AB           ((ushort)0x0200)
+#define UART_SCCM_IDL          ((ushort)0x0100)
+#define UART_SCCM_GRA          ((ushort)0x0080)
+#define UART_SCCM_BRKE         ((ushort)0x0040)
+#define UART_SCCM_BRKS         ((ushort)0x0020)
+#define UART_SCCM_CCR          ((ushort)0x0008)
+#define UART_SCCM_BSY          ((ushort)0x0004)
+#define UART_SCCM_TX           ((ushort)0x0002)
+#define UART_SCCM_RX           ((ushort)0x0001)
+
+/* The SCC PMSR when used as a UART.
+*/
+#define SCU_PMSR_FLC           ((ushort)0x8000)
+#define SCU_PMSR_SL            ((ushort)0x4000)
+#define SCU_PMSR_CL            ((ushort)0x3000)
+#define SCU_PMSR_UM            ((ushort)0x0c00)
+#define SCU_PMSR_FRZ           ((ushort)0x0200)
+#define SCU_PMSR_RZS           ((ushort)0x0100)
+#define SCU_PMSR_SYN           ((ushort)0x0080)
+#define SCU_PMSR_DRT           ((ushort)0x0040)
+#define SCU_PMSR_PEN           ((ushort)0x0010)
+#define SCU_PMSR_RPM           ((ushort)0x000c)
+#define SCU_PMSR_REVP          ((ushort)0x0008)
+#define SCU_PMSR_TPM           ((ushort)0x0003)
+#define SCU_PMSR_TEVP          ((ushort)0x0003)
+
+/* CPM Transparent mode SCC.
+ */
+typedef struct scc_trans {
+       sccp_t  st_genscc;
+       uint    st_cpres;       /* Preset CRC */
+       uint    st_cmask;       /* Constant mask for CRC */
+} scc_trans_t;
+
+#define BD_SCC_TX_LAST         ((ushort)0x0800)
+
+/* IIC parameter RAM.
+*/
+typedef struct iic {
+       ushort  iic_rbase;      /* Rx Buffer descriptor base address */
+       ushort  iic_tbase;      /* Tx Buffer descriptor base address */
+       u_char  iic_rfcr;       /* Rx function code */
+       u_char  iic_tfcr;       /* Tx function code */
+       ushort  iic_mrblr;      /* Max receive buffer length */
+       uint    iic_rstate;     /* Internal */
+       uint    iic_rdp;        /* Internal */
+       ushort  iic_rbptr;      /* Internal */
+       ushort  iic_rbc;        /* Internal */
+       uint    iic_rxtmp;      /* Internal */
+       uint    iic_tstate;     /* Internal */
+       uint    iic_tdp;        /* Internal */
+       ushort  iic_tbptr;      /* Internal */
+       ushort  iic_tbc;        /* Internal */
+       uint    iic_txtmp;      /* Internal */
+} iic_t;
+
+#define BD_IIC_START           ((ushort)0x0400)
+
+#endif /* __CPM_82XX__ */
diff --git a/include/asm-ppc/est8260.h b/include/asm-ppc/est8260.h
new file mode 100644 (file)
index 0000000..201286a
--- /dev/null
@@ -0,0 +1,20 @@
+
+#define IMAP_ADDR      ((uint)0xf0000000)
+
+
+/* A Board Information structure that is given to a program when
+ * prom starts it up.
+ */
+typedef struct bd_info {
+       unsigned int    bi_memstart;    /* Memory start address */
+       unsigned int    bi_memsize;     /* Memory (end) size in bytes */
+       unsigned int    bi_intfreq;     /* Internal Freq, in Hz */
+       unsigned int    bi_busfreq;     /* Bus Freq, in MHz */
+       unsigned int    bi_cpmfreq;     /* CPM Freq, in MHz */
+       unsigned int    bi_brgfreq;     /* BRG Freq, in MHz */
+       unsigned char   bi_enetaddr[6];
+       unsigned int    bi_baudrate;
+} bd_t;
+
+extern bd_t m8xx_board_info;
+
index 318150dab09be5c570c326d63a099d6c9455091a..78d73b5327bdccd56e4adb934465c32a85c03c98 100644 (file)
@@ -32,8 +32,8 @@ enum system_feature {
        FEATURE_Mediabay_reset,
        FEATURE_Mediabay_power,
        FEATURE_Mediabay_PCI_enable,
-       FEATURE_Mediabay_IDE_enable,    /* Also IDE 1 */
-       FEATURE_Mediabay_IDE_reset,     /* Also IDE 1 */
+       FEATURE_IDE1_enable,            /* MediaBay IDE */
+       FEATURE_IDE1_reset,             /* MediaBay IDE */
        FEATURE_Mediabay_floppy_enable,
        FEATURE_BMac_reset,
        FEATURE_BMac_IO_enable,
@@ -43,6 +43,8 @@ enum system_feature {
        FEATURE_Sound_CLK_enable,
        FEATURE_IDE2_enable,
        FEATURE_IDE2_reset,
+       FEATURE_Mediabay_IDE_switch,    /* MB IDE bus switch */
+       FEATURE_Mediabay_content,       /* MB content indicator enable */
        FEATURE_last,
 };
 
index 745c24a3978d44c1d81c6f942b3eec8765f77691..089a0ce6002d9d91e2fb070a9241fc01d7305e8f 100644 (file)
 #define BASE_BAUD  (24576000 / 16)
 
 #ifdef CONFIG_SERIAL_DETECT_IRQ
-#define STD_COM_FLAGS (/*ASYNC_BOOT_AUTOCONF|*/ASYNC_SKIP_TEST|ASYNC_AUTO_IRQ)
+#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF|ASYNC_SKIP_TEST|ASYNC_AUTO_IRQ)
 #define STD_COM4_FLAGS (ASYNC_BOOT_AUTOCONF|ASYNC_AUTO_IRQ)
 #else
-#define STD_COM_FLAGS (/*ASYNC_BOOT_AUTOCONF|*/ASYNC_SKIP_TEST)
+#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF|ASYNC_SKIP_TEST)
 #define STD_COM4_FLAGS (ASYNC_BOOT_AUTOCONF)
 #endif
 
index 4081e123735e751702ad6dcef7f6abc5d8f0656f..84a86267049780406645fa78d5e111cba0d2d819 100644 (file)
@@ -13,7 +13,7 @@
  * Bits in feature control register.
  * Bits postfixed with a _N are in inverse logic
  */
-#define HRW_RESET_SCC          1               /* Named in_use_led in OF ??? */
+#define HRW_MODEM_POWER_N      1               /* turns off modem power */
 #define HRW_BAY_POWER_N                2
 #define HRW_BAY_PCI_ENABLE     4
 #define HRW_BAY_IDE_ENABLE     8
 #define HRW_ARB_BYPASS         0x400000        /* ??? (0 on main, 1 on gatwick) */
 #define HRW_IDE1_RESET_N       0x800000        /* Media bay */
 #define HRW_SLOW_SCC_PCLK      0x1000000       /* ??? (0) */
-#define HRW_MODEM_POWER_N      0x2000000       /* Used by internal modem on wallstreet */
+#define HRW_RESET_SCC          0x2000000       /* perhaps? */
 #define HRW_MFDC_CELL_ENABLE   0x4000000       /* ??? (0) */
 #define HRW_USE_MFDC           0x8000000       /* ??? (0) */
 #define HRW_BMAC_IO_ENABLE     0x60000000      /* two bits, not documented in OF */
 #define HRW_BMAC_RESET         0x80000000      /* not documented in OF */
+
+
+#define PADD_MODEM_POWER_N     0x00000001      /* modem power on paddington */
index 8b50f862b243d343f92d52df5ddba9a3a03fe2b2..198132fa43a758409966f1c9763547027e19c95c 100644 (file)
@@ -63,6 +63,7 @@ void ide_insw(ide_ioreg_t port, void *buf, int ns);
 void ide_outsw(ide_ioreg_t port, void *buf, int ns);
 void ppc_generic_ide_fix_driveid(struct hd_driveid *id);
 
+#if 0
 #undef insw
 #define insw(port, buf, ns)    do {                            \
        ppc_ide_md.insw((port), (buf), (ns));                   \
@@ -72,6 +73,7 @@ void ppc_generic_ide_fix_driveid(struct hd_driveid *id);
 #define outsw(port, buf, ns)   do {                            \
        ppc_ide_md.outsw((port), (buf), (ns));                  \
 } while (0)
+#endif
 
 #undef SUPPORT_SLOW_DATA_PORTS
 #define        SUPPORT_SLOW_DATA_PORTS 0
diff --git a/include/asm-ppc/immap_8260.h b/include/asm-ppc/immap_8260.h
new file mode 100644 (file)
index 0000000..407cbf0
--- /dev/null
@@ -0,0 +1,433 @@
+
+/*
+ * MPC8260 Internal Memory Map
+ * Copyright (c) 1999 Dan Malek (dmalek@jlc.net)
+ *
+ * The Internal Memory Map of the 8260.  I don't know how generic
+ * this will be, as I don't have any knowledge of the subsequent
+ * parts at this time.  I copied this from the 8xx_immap.h.
+ */
+#ifndef __IMMAP_82XX__
+#define __IMMAP_82XX__
+
+/* System configuration registers.
+*/
+typedef        struct sys_conf {
+       uint    sc_siumcr;
+       uint    sc_sypcr;
+       char    res1[6];
+       ushort  sc_swsr;
+       char    res2[20];
+       uint    sc_bcr;
+       u_char  sc_ppc_acr;
+       char    res3[3];
+       uint    sc_ppc_alrh;
+       uint    sc_ppc_alrl;
+       u_char  sc_lcl_acr;
+       char    res4[3];
+       uint    sc_lcl_alrh;
+       uint    sc_lcl_alrl;
+       uint    sc_tescr1;
+       uint    sc_tescr2;
+       uint    sc_ltescr1;
+       uint    sc_ltescr2;
+       uint    sc_pdtea;
+       u_char  sc_pdtem;
+       char    res5[3];
+       uint    sc_ldtea;
+       u_char  sc_ldtem;
+       char    res6[163];
+} sysconf8260_t;
+
+
+/* Memory controller registers.
+*/
+typedef struct mem_ctlr {
+       uint    memc_br0;
+       uint    memc_or0;
+       uint    memc_br1;
+       uint    memc_or1;
+       uint    memc_br2;
+       uint    memc_or2;
+       uint    memc_br3;
+       uint    memc_or3;
+       uint    memc_br4;
+       uint    memc_or4;
+       uint    memc_br5;
+       uint    memc_or5;
+       uint    memc_br6;
+       uint    memc_or6;
+       uint    memc_br7;
+       uint    memc_or7;
+       uint    memc_br8;
+       uint    memc_or8;
+       uint    memc_br9;
+       uint    memc_or9;
+       uint    memc_br10;
+       uint    memc_or10;
+       uint    memc_br11;
+       uint    memc_or11;
+       char    res1[8];
+       uint    memc_mar;
+       char    res2[4];
+       uint    memc_mamr;
+       uint    memc_mbmr;
+       uint    memc_mcmr;
+       char    res3[8];
+       ushort  memc_mptpr;
+       char    res4[2];
+       uint    memc_mdr;
+       char    res5[4];
+       uint    memc_psdmr;
+       uint    memc_lsdmr;
+       u_char  memc_purt;
+       char    res6[3];
+       u_char  memc_psrt;
+       char    res7[3];
+       u_char  memc_lurt;
+       char    res8[3];
+       u_char  memc_lsrt;
+       char    res9[3];
+       uint    memc_immr;
+       char    res10[84];
+} memctl8260_t;
+
+/* System Integration Timers.
+*/
+typedef struct sys_int_timers {
+       char    res1[32];
+       ushort  sit_tmcntsc;
+       char    res2[2];
+       uint    sit_tmcnt;
+       char    res3[4];
+       uint    sit_tmcntal;
+       char    res4[16];
+       ushort  sit_piscr;
+       char    res5[2];
+       uint    sit_pitc;
+       uint    sit_pitr;
+       char    res6[94];
+       char    res7[2390];
+} sit8260_t;
+
+#define PISCR_PIRQ_MASK                ((ushort)0xff00)
+#define PISCR_PS               ((ushort)0x0080)
+#define PISCR_PIE              ((ushort)0x0004)
+#define PISCR_PTF              ((ushort)0x0002)
+#define PISCR_PTE              ((ushort)0x0001)
+
+/* Interrupt Controller.
+*/
+typedef struct interrupt_controller {
+       ushort  ic_sicr;
+       char    res1[2];
+       uint    ic_sivec;
+       uint    ic_sipnrh;
+       uint    ic_sipnrl;
+       uint    ic_siprr;
+       uint    ic_scprrh;
+       uint    ic_scprrl;
+       uint    ic_simrh;
+       uint    ic_simrl;
+       uint    ic_siexr;
+       char    res2[88];
+} intctl8260_t;
+
+/* Clocks and Reset.
+*/
+typedef struct clk_and_reset {
+       uint    car_sccr;
+       char    res1[4];
+       uint    car_scmr;
+       char    res2[4];
+       uint    car_rsr;
+       uint    car_rmr;
+       char    res[104];
+} car8260_t;
+
+/* Input/Output Port control/status registers.
+ * Names consistent with processor manual, although they are different
+ * from the original 8xx names.......
+ */
+typedef struct io_port {
+       uint    iop_pdira;
+       uint    iop_ppara;
+       uint    iop_psora;
+       uint    iop_podra;
+       uint    iop_pdata;
+       char    res1[12];
+       uint    iop_pdirb;
+       uint    iop_pparb;
+       uint    iop_psorb;
+       uint    iop_podrb;
+       uint    iop_pdatb;
+       char    res2[12];
+       uint    iop_pdirc;
+       uint    iop_pparc;
+       uint    iop_psorc;
+       uint    iop_podrc;
+       uint    iop_pdatc;
+       char    res3[12];
+       uint    iop_pdird;
+       uint    iop_ppard;
+       uint    iop_psord;
+       uint    iop_podrd;
+       uint    iop_pdatd;
+       char    res4[12];
+} iop8260_t;
+
+/* Communication Processor Module Timers
+*/
+typedef struct cpm_timers {
+       u_char  cpmt_tgcr1;
+       char    res1[3];
+       u_char  cpmt_tgcr2;
+       char    res2[11];
+       ushort  cpmt_tmr1;
+       ushort  cpmt_tmr2;
+       ushort  cpmt_trr1;
+       ushort  cpmt_trr2;
+       ushort  cpmt_tcr1;
+       ushort  cpmt_tcr2;
+       ushort  cpmt_tcn1;
+       ushort  cpmt_tcn2;
+       ushort  cpmt_tmr3;
+       ushort  cpmt_tmr4;
+       ushort  cpmt_trr3;
+       ushort  cpmt_trr4;
+       ushort  cpmt_tcr3;
+       ushort  cpmt_tcr4;
+       ushort  cpmt_tcn3;
+       ushort  cpmt_tcn4;
+       ushort  cpmt_ter1;
+       ushort  cpmt_ter2;
+       ushort  cpmt_ter3;
+       ushort  cpmt_ter4;
+       char    res3[584];
+} cpmtimer8260_t;
+
+/* DMA control/status registers.
+*/
+typedef struct sdma_csr {
+       char    res0[24];
+       u_char  sdma_sdsr;
+       char    res1[3];
+       u_char  sdma_sdmr;
+       char    res2[3];
+       u_char  sdma_idsr1;
+       char    res3[3];
+       u_char  sdma_idmr1;
+       char    res4[3];
+       u_char  sdma_idsr2;
+       char    res5[3];
+       u_char  sdma_idmr2;
+       char    res6[3];
+       u_char  sdma_idsr3;
+       char    res7[3];
+       u_char  sdma_idmr3;
+       char    res8[3];
+       u_char  sdma_idsr4;
+       char    res9[3];
+       u_char  sdma_idmr4;
+       char    res10[707];
+} sdma8260_t;
+
+/* Fast controllers
+*/
+typedef struct fcc {
+       uint    fcc_gfmr;
+       uint    fcc_fpsmr;
+       ushort  fcc_ftodr;
+       char    res1[2];
+       ushort  fcc_fdsr;
+       char    res2[2];
+       uint    fcc_fcce;
+       uint    fcc_fccm;
+       u_char  fcc_fccs;
+       char    res3[3];
+       u_char  fcc_ftirr_phy[4];
+} fcc_t;
+
+/* I2C
+*/
+typedef struct i2c {
+       u_char  i2c_i2mod;
+       char    res1[3];
+       u_char  i2c_i2add;
+       char    res2[3];
+       u_char  i2c_i2brg;
+       char    res3[3];
+       u_char  i2c_i2com;
+       char    res4[3];
+       u_char  i2c_i2cer;
+       char    res5[3];
+       u_char  i2c_i2cmr;
+       char    res6[331];
+} i2c8260_t;
+
+typedef struct scc {           /* Serial communication channels */
+       uint    scc_gsmrl;
+       uint    scc_gsmrh;
+       ushort  scc_pmsr;
+       char    res1[2];
+       ushort  scc_todr;
+       ushort  scc_dsr;
+       ushort  scc_scce;
+       char    res2[2];
+       ushort  scc_sccm;
+       char    res3;
+       u_char  scc_sccs;
+       char    res4[8];
+} scc_t;
+
+typedef struct smc {           /* Serial management channels */
+       char    res1[2];
+       ushort  smc_smcmr;
+       char    res2[2];
+       u_char  smc_smce;
+       char    res3[3];
+       u_char  smc_smcm;
+       char    res4[5];
+} smc_t;
+
+/* Serial Peripheral Interface.
+*/
+typedef struct spi {
+       ushort  spi_spmode;
+       char    res1[4];
+       u_char  spi_spie;
+       char    res2[3];
+       u_char  spi_spim;
+       char    res3[2];
+       u_char  spi_spcom;
+       char    res4[82];
+} spi_t;
+
+/* CPM Mux.
+*/
+typedef struct cpmux {
+       u_char  cmx_si1cr;
+       char    res1;
+       u_char  cmx_si2cr;
+       char    res2;
+       uint    cmx_fcr;
+       uint    cmx_scr;
+       u_char  cmx_smr;
+       char    res3;
+       ushort  cmx_uar;
+       char    res4[16];
+} cpmux_t;
+
+/* SIRAM control
+*/
+typedef struct siram {
+       ushort  si_amr;
+       ushort  si_bmr;
+       ushort  si_cmr;
+       ushort  si_dmr;
+       u_char  si_gmr;
+       char    res1;
+       u_char  si_cmdr;
+       char    res2;
+       u_char  si_str;
+       char    res3;
+       ushort  si_rsr;
+} siramctl_t;
+
+typedef struct mcc {
+       ushort  mcc_mcce;
+       char    res1[2];
+       ushort  mcc_mccm;
+       char    res2[2];
+       u_char  mcc_mccf;
+       char    res3[7];
+} mcc_t;
+
+typedef struct comm_proc {
+       uint    cp_cpcr;
+       uint    cp_rccr;
+       char    res1[14];
+       ushort  cp_rter;
+       char    res2[2];
+       ushort  cp_rtmr;
+       ushort  cp_rtscr;
+       char    res3[2];
+       uint    cp_rtsr;
+       char    res4[12];
+} cpm8260_t;
+
+/* ...and the whole thing wrapped up....
+*/
+typedef struct immap {
+       /* Some references are into the unique and known dpram spaces,
+        * others are from the generic base.
+        */
+#define im_dprambase   im_dpram1
+       u_char          im_dpram1[16*1024];
+       char            res1[16*1024];
+       u_char          im_dpram2[4*1024];
+       char            res2[8*1024];
+       u_char          im_dpram3[4*1024];
+       char            res3[16*1024];
+
+       sysconf8260_t   im_siu_conf;    /* SIU Configuration */
+       memctl8260_t    im_memctl;      /* Memory Controller */
+       sit8260_t       im_sit;         /* System Integration Timers */
+       intctl8260_t    im_intctl;      /* Interrupt Controller */
+       car8260_t       im_clkrst;      /* Clocks and reset */
+       iop8260_t       im_ioport;      /* IO Port control/status */
+       cpmtimer8260_t  im_cpmtimer;    /* CPM timers */
+       sdma8260_t      im_sdma;        /* SDMA control/status */
+
+       fcc_t           im_fcc[3];      /* Three FCCs */
+
+       char            res4[159];
+
+       /* First set of baud rate generators.
+       */
+       char            res4a[496];
+       uint            im_brgc5;
+       uint            im_brgc6;
+       uint            im_brgc7;
+       uint            im_brgc8;
+
+       char            res5[608];
+
+       i2c8260_t       im_i2c;         /* I2C control/status */
+       cpm8260_t       im_cpm;         /* Communication processor */
+
+       /* Second set of baud rate generators.
+       */
+       uint            im_brgc1;
+       uint            im_brgc2;
+       uint            im_brgc3;
+       uint            im_brgc4;
+
+       scc_t           im_scc[4];      /* Four SCCs */
+       smc_t           im_smc[2];      /* Couple of SMCs */
+       spi_t           im_spi;         /* A SPI */
+       cpmux_t         im_cpmux;       /* CPM clock route mux */
+       siramctl_t      im_siramctl1;   /* First SI RAM Control */
+       mcc_t           im_mcc1;        /* First MCC */
+       siramctl_t      im_siramctl2;   /* Second SI RAM Control */
+       mcc_t           im_mcc2;        /* Second MCC */
+
+       char            res6[1184];
+
+       ushort          im_si1txram[256];
+       char            res7[512];
+       ushort          im_si1rxram[256];
+       char            res8[512];
+       ushort          im_si2txram[256];
+       char            res9[512];
+       ushort          im_si2rxram[256];
+       char            res10[512];
+       char            res11[4096];
+} immap_t;
+
+/* The 8260 relies heavily on the IMMR, so we keep it around as a
+ * kernel global symbol now.  Should have done this for the 8xx......
+ */
+immap_t        *immr;
+
+#endif /* __IMMAP_82XX__ */
index 7bb3d901d0bbb1b2573417c1e7fa5f0fa8e3b6fd..a4be6b7e29624612672f84c816496ba384e8a4b5 100644 (file)
@@ -23,6 +23,8 @@
 #include <asm/board.h>
 #elif defined(CONFIG_8xx)
 #include <asm/mpc8xx.h>
+#elif defined(CONFIG_8260)
+#include <asm/mpc8260.h>
 #else
 #ifdef CONFIG_APUS
 #define _IO_BASE 0
@@ -52,12 +54,18 @@ extern unsigned long pci_dram_offset;
 #define writel(b,addr) out_le32((volatile u32 *)(addr),(b))
 #endif
 
+/*
+ * The insw/outsw/insl/outsl macros don't do byte-swapping.
+ * They are only used in practice for transferring buffers which
+ * are arrays of bytes, and byte-swapping is not appropriate in
+ * that case.  - paulus
+ */
 #define insb(port, buf, ns)    _insb((u8 *)((port)+_IO_BASE), (buf), (ns))
 #define outsb(port, buf, ns)   _outsb((u8 *)((port)+_IO_BASE), (buf), (ns))
-#define insw(port, buf, ns)    _insw((u16 *)((port)+_IO_BASE), (buf), (ns))
-#define outsw(port, buf, ns)   _outsw((u16 *)((port)+_IO_BASE), (buf), (ns))
-#define insl(port, buf, nl)    _insl((u32 *)((port)+_IO_BASE), (buf), (nl))
-#define outsl(port, buf, nl)   _outsl((u32 *)((port)+_IO_BASE), (buf), (nl))
+#define insw(port, buf, ns)    _insw_ns((u16 *)((port)+_IO_BASE), (buf), (ns))
+#define outsw(port, buf, ns)   _outsw_ns((u16 *)((port)+_IO_BASE), (buf), (ns))
+#define insl(port, buf, nl)    _insl_ns((u32 *)((port)+_IO_BASE), (buf), (nl))
+#define outsl(port, buf, nl)   _outsl_ns((u32 *)((port)+_IO_BASE), (buf), (nl))
 
 #define inb(port)              in_8((u8 *)((port)+_IO_BASE))
 #define outb(val, port)                out_8((u8 *)((port)+_IO_BASE), (val))
@@ -86,19 +94,21 @@ extern void _insw(volatile u16 *port, void *buf, int ns);
 extern void _outsw(volatile u16 *port, const void *buf, int ns);
 extern void _insl(volatile u32 *port, void *buf, int nl);
 extern void _outsl(volatile u32 *port, const void *buf, int nl);
+extern void _insw_ns(volatile u16 *port, void *buf, int ns);
+extern void _outsw_ns(volatile u16 *port, const void *buf, int ns);
+extern void _insl_ns(volatile u32 *port, void *buf, int nl);
+extern void _outsl_ns(volatile u32 *port, const void *buf, int nl);
 
 /*
  * The *_ns versions below don't do byte-swapping.
+ * Neither do the standard versions now, these are just here
+ * for older code.
  */
 #define insw_ns(port, buf, ns) _insw_ns((u16 *)((port)+_IO_BASE), (buf), (ns))
 #define outsw_ns(port, buf, ns)        _outsw_ns((u16 *)((port)+_IO_BASE), (buf), (ns))
 #define insl_ns(port, buf, nl) _insl_ns((u32 *)((port)+_IO_BASE), (buf), (nl))
 #define outsl_ns(port, buf, nl)        _outsl_ns((u32 *)((port)+_IO_BASE), (buf), (nl))
 
-extern void _insw_ns(volatile u16 *port, void *buf, int ns);
-extern void _outsw_ns(volatile u16 *port, const void *buf, int ns);
-extern void _insl_ns(volatile u32 *port, void *buf, int nl);
-extern void _outsl_ns(volatile u32 *port, const void *buf, int nl);
 
 #define IO_SPACE_LIMIT ~0
 
index 867dd0bab5162d95eb495b39dd5259d5d6795a05..0f1972ddf9bcd45b413d536831fd18b464d2533a 100644 (file)
@@ -57,21 +57,15 @@ irq_cannonicalize(int irq)
  * There are eight external interrupts (IRQs) that can be configured
  * as either level or edge sensitive. 
  *
- * The 82xx can have up to 64 interrupts on the internal controller.
- *
  * On some implementations, there is also the possibility of an 8259
  * through the PCI and PCI-ISA bridges.
  */
-#ifdef CONFIG_82xx
-#define NR_SIU_INTS    64
-#else
 #define NR_SIU_INTS    16
-#endif
 
 #define NR_IRQS        (NR_SIU_INTS + NR_8259_INTS)
 
 /* These values must be zero-based and map 1:1 with the SIU configuration.
- * They are used throughout the 8xx/82xx I/O subsystem to generate
+ * They are used throughout the 8xx I/O subsystem to generate
  * interrupt masks, flags, and other control patterns.  This is why the
  * current kernel assumption of the 8259 as the base controller is such
  * a pain in the butt.
@@ -166,11 +160,37 @@ extern irq_node_t *new_irq_node(void);
  */
 #define NR_IRQS                        256
 
+#ifndef CONFIG_8260
+
 #define NUM_8259_INTERRUPTS    16
 #define IRQ_8259_CASCADE       16
 #define openpic_to_irq(n)      ((n)+NUM_8259_INTERRUPTS)
 #define irq_to_openpic(n)      ((n)-NUM_8259_INTERRUPTS)
 
+#else /* CONFIG_8260 */
+
+/* The 8260 has an internal interrupt controller with a maximum of
+ * 64 IRQs.  We will use NR_IRQs from above since it is large enough.
+ * Don't be confused by the 8260 documentation where they list an
+ * "interrupt number" and "interrupt vector".  We are only interested
+ * in the interrupt vector.  There are "reserved" holes where the
+ * vector number increases, but the interrupt number in the table does not.
+ * (Document errata updates have fixed this...make sure you have up to
+ * date processor documentation -- Dan).
+ */
+#define NR_SIU_INTS    64
+
+/* There are many more than these, we will add them as we need them.
+*/
+#define        SIU_INT_SMC1            ((uint)0x04)
+#define        SIU_INT_SMC2            ((uint)0x05)
+#define        SIU_INT_SCC1            ((uint)0x28)
+#define        SIU_INT_SCC2            ((uint)0x29)
+#define        SIU_INT_SCC3            ((uint)0x2a)
+#define        SIU_INT_SCC4            ((uint)0x2b)
+
+#endif /* CONFIG_8260 */
+
 /*
  * This gets called from serial.c, which is now used on
  * powermacs as well as prep/chrp boxes.
diff --git a/include/asm-ppc/mpc8260.h b/include/asm-ppc/mpc8260.h
new file mode 100644 (file)
index 0000000..1ce80da
--- /dev/null
@@ -0,0 +1,40 @@
+
+/* This is the single file included by all MPC8260 build options.
+ * Since there are many different boards and no standard configuration,
+ * we have a unique include file for each.  Rather than change every
+ * file that has to include MPC8260 configuration, they all include
+ * this one and the configuration switching is done here.
+ */
+#ifndef __CONFIG_8260_DEFS
+#define __CONFIG_8260_DEFS
+
+#ifdef CONFIG_8260
+
+#ifdef CONFIG_EST8260
+#include <asm/est8260.h>
+#endif
+
+/* I don't yet have the ISA or PCI stuff done....no 8260 with
+ * such thing.....
+ */
+#define _IO_BASE        0
+#define _ISA_MEM_BASE   0
+#define PCI_DRAM_OFFSET 0
+
+/* The "residual" data board information structure the boot loader
+ * hands to us.
+ */
+extern unsigned char __res[];
+
+/* I need this to get pt_regs.......
+*/
+#include <asm/ptrace.h>
+
+extern int request_8xxirq(unsigned int irq,
+                      void (*handler)(int, void *, struct pt_regs *),
+                      unsigned long flags, 
+                      const char *device,
+                      void *dev_id);
+
+#endif /* CONFIG_8260 */
+#endif
index ea7bf19146f681f54f3c5d55b39ba733e2d7d433..985d2a321c50080c2df3a9f041ce2afeb7c8e9af 100644 (file)
 #define BIN_TO_BCD(val) ((val)=(((val)/10)<<4) + (val)%10)
 #endif
 
+/* PowerMac specific nvram stuffs */
+
+enum {
+       pmac_nvram_OF,          /* Open Firmware partition */
+       pmac_nvram_XPRAM,       /* MacOS XPRAM partition */
+       pmac_nvram_NR           /* MacOS Name Registry partition */
+};
+
+/* Return partition offset in nvram */
+extern int     pmac_get_partition(int partition);
+
+/* Direct access to XPRAM */
+extern u8      pmac_xpram_read(int xpaddr);
+extern void    pmac_xpram_write(int xpaddr, u8 data);
+
+/* Some offsets in XPRAM */
+#define PMAC_XPRAM_MACHINE_LOC 0xe4
+#define PMAC_XPRAM_SOUND_VOLUME        0x08
+
+/* Machine location structure in XPRAM */
+struct pmac_machine_location {
+       u32     latitude;       /* 2+30 bit Fractional number */
+       u32     longitude;      /* 2+30 bit Fractional number */
+       u32     delta;          /* mix of GMT delta and DLS */
+};
+
 #endif
index 9218c665b9ce0a9c8381d3b82f284f6504e131d7..5c4e39902a5e81b0495d66da07ee393c8c73a568 100644 (file)
@@ -65,12 +65,11 @@ extern inline void flush_tlb_pgtables(struct mm_struct *mm,
 #define flush_cache_mm(mm)             do { } while (0)
 #define flush_cache_range(mm, a, b)    do { } while (0)
 #define flush_cache_page(vma, p)       do { } while (0)
+#define flush_icache_page(vma, page)   do { } while (0)
 
 extern void flush_icache_range(unsigned long, unsigned long);
 extern void __flush_page_to_ram(unsigned long page_va);
 #define flush_page_to_ram(page)        __flush_page_to_ram(page_address(page))
-extern void __flush_icache_page(unsigned long page_va);
-#define flush_icache_page(vma, page) __flush_icache_page(page_address(page))
 
 extern unsigned long va_to_phys(unsigned long address);
 extern pte_t *va_to_pte(struct task_struct *tsk, unsigned long address);
@@ -197,22 +196,18 @@ extern unsigned long ioremap_bot, ioremap_base;
 #define _PAGE_NO_CACHE 0x0002  /* I: cache inhibit */
 #define _PAGE_SHARED   0x0004  /* No ASID (context) compare */
 
-/* These four software bits must be masked out when the entry is loaded
+/* These five software bits must be masked out when the entry is loaded
  * into the TLB.
  */
+#define _PAGE_DIRTY    0x0008  /* software: page changed */
 #define _PAGE_GUARDED  0x0010  /* software: guarded access */
 #define _PAGE_WRITETHRU 0x0020 /* software: use writethrough cache */
 #define _PAGE_RW       0x0040  /* software: user write access allowed */
 #define _PAGE_ACCESSED 0x0080  /* software: page referenced */
 
-#define _PAGE_DIRTY    0x0100  /* C: page changed (write protect) */
+#define _PAGE_HWWRITE  0x0100  /* C: page changed (write protect) */
 #define _PAGE_USER     0x0800  /* One of the PP bits, the other must be 0 */
 
-/* This is used to enable or disable the actual hardware write
- * protection.
- */
-#define _PAGE_HWWRITE  _PAGE_DIRTY
-
 #else /* CONFIG_6xx */
 /* Definitions for 60x, 740/750, etc. */
 #define _PAGE_PRESENT  0x001   /* software: pte contains a translation */
@@ -432,6 +427,7 @@ extern inline pte_t * pte_offset(pmd_t * dir, unsigned long address)
 }
 
 extern pgd_t swapper_pg_dir[1024];
+extern void paging_init(void);
 
 /*
  * Page tables may have changed.  We don't need to do anything here
index 04c59a5b3db18c114f70153bc9efae3f2327577f..47539d3a70ad24f972b83acd32932fc8149f2a07 100644 (file)
@@ -1,6 +1,8 @@
 #ifndef _PPC_POSIX_TYPES_H
 #define _PPC_POSIX_TYPES_H
 
+#include <linux/config.h>      /* for CONFIG_PPC64 */
+
 /*
  * This file is generally used by user-level software, so you need to
  * be a little careful about namespace pollution etc.  Also, we cannot
@@ -15,8 +17,17 @@ typedef long         __kernel_off_t;
 typedef int            __kernel_pid_t;
 typedef unsigned int   __kernel_uid_t;
 typedef unsigned int   __kernel_gid_t;
+
+/* Grrr... gcc thinks size_t is unsigned int, so we either
+   have to have this nonsense or use -fno-builtin. - paulus */
+#ifdef CONFIG_PPC64
 typedef unsigned long  __kernel_size_t;
 typedef long           __kernel_ssize_t;
+#else
+typedef unsigned int   __kernel_size_t;
+typedef int            __kernel_ssize_t;
+#endif /* CONFIG_PPC64 */
+
 typedef long           __kernel_ptrdiff_t;
 typedef long           __kernel_time_t;
 typedef long           __kernel_suseconds_t;
index 5212c5b71e11bb917a7be1a4645223b24dc3fd28..3088dd279e174184b3d4494a094fa7128fb2b523 100644 (file)
 #define        PVR_8260        PVR_8240
 
 
+/* I am just adding a single entry for 8260 boards.  I think we may be
+ * able to combine mbx, fads, rpxlite, bseip, and classic into a single
+ * generic 8xx as well.  The boards containing these processors are either
+ * identical at the processor level (due to the high integration) or so
+ * wildly different that testing _machine at run time is best replaced by
+ * conditional compilation by board type (found in their respective .h file).
+ *     -- Dan
+ */
 #define _MACH_prep     0x00000001
 #define _MACH_Pmac     0x00000002      /* pmac or pmac clone (non-chrp) */
 #define _MACH_chrp     0x00000004      /* chrp machine */
 #define _MACH_classic  0x00000400      /* RPCG RPX-Classic 8xx board */
 #define _MACH_oak      0x00000800      /* IBM "Oak" 403 eval. board */
 #define _MACH_walnut   0x00001000      /* IBM "Walnut" 405GP eval. board */
+#define _MACH_8260     0x00002000      /* Generic 8260 */
 
 
 /* see residual.h for these */
@@ -707,6 +716,9 @@ void _nmask_and_or_msr(unsigned long nmask, unsigned long or_val);
 #elif defined(CONFIG_GEMINI)
 #define _machine _MACH_gemini
 #define have_of 0
+#elif defined(CONFIG_8260)
+#define _machine _MACH_8260
+#define have_of 0
 #else
 #error "Machine not defined correctly"
 #endif
index c27aa85910c3319b6d9812890cdb4dfb3142e8f4..d31976a3d651af4a86c6c5ac4b5483c7a004b3d0 100644 (file)
@@ -14,6 +14,8 @@
 
 #define RLIM_NLIMITS   10
 
+#ifdef __KERNEL__
+
 /*
  * SuS says limits have to be unsigned.
  * Which makes a ton more sense anyway.
@@ -21,8 +23,6 @@
 #define RLIM_INFINITY  (~0UL)
 
 
-#ifdef __KERNEL__
-
 #define INIT_RLIMITS                                                   \
 {                                                                      \
        { RLIM_INFINITY, RLIM_INFINITY },               \
index fd733b38ebc4cda61c7c1c2d6f206c16295f6558..74be5608530157d2b43eebf9b3b4162194c777a9 100644 (file)
@@ -62,6 +62,6 @@ extern bd_t m8xx_board_info;
 
 /* Machine type
 */
-#define _MACH_8xx (_MACH_rpxclassic)
+#define _MACH_8xx (_MACH_classic)
 
 #endif
index 461ac03605cb3e65cb6fbdd1cb1cebbff11499ac..92063a8689ca47b01f1311fe6985676ede6fe7f2 100644 (file)
@@ -12,6 +12,7 @@
 #ifdef __KERNEL__
 
 #include <asm/atomic.h>
+#include <asm/system.h>
 #include <linux/wait.h>
 
 struct semaphore {
index 162a09a1d181dd9d247f4d9acfa93f884bac3166..fa9bc9944ee48379e8330c274506f60a56e0b708 100644 (file)
@@ -8,6 +8,7 @@
 
 #include <linux/config.h>
 #include <linux/kdev_t.h>
+#include <linux/bitops.h>
 
 #include <asm/processor.h>
 #include <asm/atomic.h>
index 11b4c513a5dc4f2fc917f32603f6ebbb116dfeaf..324b626000618fd75aa85f728a7c4e9db7ba13c7 100644 (file)
@@ -57,12 +57,9 @@ struct termios {
 #define ICRNL  0000400
 #define IXON   0001000
 #define IXOFF  0002000
-#if defined(__KERNEL__) || defined(__USE_BSD)
-  /* POSIX.1 doesn't want these... */
-# define IXANY         0004000
-# define IUCLC         0010000
-# define IMAXBEL       0020000
-#endif
+#define IXANY          0004000
+#define IUCLC          0010000
+#define IMAXBEL        0020000
 
 /* c_oflag bits */
 #define OPOST  0000001
index 777f5f8eefb7af6196da0ea9388112f2feda6f2e..b5a9999a5570d7fbc080edf4dcaf769f8af76aee 100644 (file)
@@ -72,7 +72,8 @@
 #define D_TX           256     /* show tx packets                        */
 #define D_RX           512     /* show rx packets                        */
 #define D_SKB          1024    /* show skb's                             */
-#define D_TIMING       2048    /* show time needed to copy buffers to card */
+#define D_SKB_SIZE     2048    /* show skb sizes                         */
+#define D_TIMING       4096    /* show time needed to copy buffers to card */
 
 #ifndef ARCNET_DEBUG_MAX
 #define ARCNET_DEBUG_MAX (~0)  /* enable ALL debug messages       */
@@ -174,6 +175,13 @@ extern int arcnet_debug;
 #define NORMALconf      0x00   /* 1-249 byte packets */
 #define EXTconf         0x08   /* 250-504 byte packets */
 
+/* card feature flags, set during auto-detection.
+ * (currently only used by com20020pci)
+ */
+#define ARC_IS_5MBIT    1   /* card default speed is 5MBit */
+#define ARC_CAN_10MBIT  2   /* card uses COM20022, supporting 10MBit,
+                                but default is 2.5MBit. */
+
 
 /* information needed to define an encapsulation driver */
 struct ArcProto {
@@ -227,8 +235,10 @@ struct arcnet_local {
        uint8_t config,         /* current value of CONFIG register */
                timeout,        /* Extended timeout for COM20020 */
                backplane,      /* Backplane flag for COM20020 */
-               clock,          /* COM20020 clock speed flag */
-               setup,          /* Contents of setup register */
+               clockp,         /* COM20020 clock divider */
+               clockm,         /* COM20020 clock multiplier flag */
+               setup,          /* Contents of setup1 register */
+               setup2,         /* Contents of setup2 register */
                intmask;        /* current value of INTMASK register */
        uint8_t default_proto[256];     /* default encap to use for each host */
        int cur_tx,             /* buffer used by current transmit, or -1 */
@@ -236,7 +246,8 @@ struct arcnet_local {
                cur_rx;         /* current receive buffer */
        int lastload_dest,      /* can last loaded packet be acked? */
                lasttrans_dest; /* can last TX'd packet be acked? */
-       int basename_len;       /* name length without suffix ('arc0e' -> 4) */
+       char *card_name;        /* card ident string */
+       int card_flags;         /* special card features */
 
        /*
         * Buffer management: an ARCnet card has 4 x 512-byte buffers, each of
index 21f5bad13a5fc51adce6731b18dc1b2217322dde..08ccef4c45b28eff9847828347ee3ac7755dd3a3 100644 (file)
@@ -102,7 +102,7 @@ void coda_sysctl_clean(void);
   if (coda_debug & mask) {                                        \
     printk("(%s,l. %d): ",  __FUNCTION__, __LINE__);              \
     printk(format, ## a); }                                       \
-} while (0) ;                            
+} while (0)
 
 #define ENTRY    \
     if(coda_print_entry) printk("Process %d entered %s\n",current->pid,__FUNCTION__)
index b386bf34d19a1076d3671704e8441ba6c28adafc..89cefc2baee1c96fab31f1a0c1931d104bea801a 100644 (file)
@@ -29,6 +29,7 @@
 
 int com20020_check(struct net_device *dev);
 int com20020_found(struct net_device *dev, int shared);
+void com20020_remove(struct net_device *dev);
 
 /* The number of low I/O ports used by the card. */
 #define ARCNET_TOTAL_SIZE 9
@@ -41,8 +42,10 @@ int com20020_found(struct net_device *dev, int shared);
 #define _ADDR_HI  (ioaddr+2)   /* control registers for IO-mapped memory */
 #define _ADDR_LO  (ioaddr+3)
 #define _MEMDATA  (ioaddr+4)   /* data port for IO-mapped memory */
+#define _SUBADR   (ioaddr+5)   /* the extended port _XREG refers to */
 #define _CONFIG   (ioaddr+6)   /* configuration register */
-#define _SETUP    (ioaddr+7)   /* setup register */
+#define _XREG     (ioaddr+7)   /* extra registers (indexed by _CONFIG 
+                                       or _SUBADR) */
 
 /* in the ADDR_HI register */
 #define RDDATAflag     0x80    /* next access is a read (not a write) */
@@ -57,10 +60,28 @@ int com20020_found(struct net_device *dev, int shared);
 /* in SETUP register */
 #define PROMISCset     0x10    /* enable RCV_ALL */
 
-#define REGTENTID (lp->config &= ~3);
-#define REGNID (lp->config = (lp->config&~2)|1);
-#define REGSETUP (lp->config = (lp->config&~1)|2);
-#define REGNXTID (lp->config |= 3);
+/* COM2002x */
+#define SUB_TENTATIVE  0       /* tentative node ID */
+#define SUB_NODE       1       /* node ID */
+#define SUB_SETUP1     2       /* various options */
+#define SUB_TEST       3       /* test/diag register */
+
+/* COM20022 only */
+#define SUB_SETUP2     4       /* sundry options */
+#define SUB_BUSCTL     5       /* bus control options */
+#define SUB_DMACOUNT   6       /* DMA count options */
+
+#define SET_SUBADR(x) do { \
+       if ((x) < 4) \
+       { \
+               lp->config = (lp->config & ~0x03) | (x); \
+               SETCONF; \
+       } \
+       else \
+       { \
+               outb(x, _SUBADR); \
+       } \
+} while (0)
 
 #undef ARCRESET
 #undef ASTATUS
@@ -80,6 +101,6 @@ int com20020_found(struct net_device *dev, int shared);
 #define ACOMMAND(cmd)  outb((cmd),_COMMAND)
 #define AINTMASK(msk)  outb((msk),_INTMASK)
 
-#define SETCONF(cfg)   outb(cfg, _CONFIG)
+#define SETCONF                outb(lp->config, _CONFIG)
 
 #endif /* __COM20020_H */
index 46d8c0fbced1037c3e74b5601f2e135a9ac675fb..0b0e06a22216f0c280b2ee5df85feeb4677ae399 100644 (file)
@@ -786,7 +786,7 @@ struct file_system_type var = { \
 
 extern int register_filesystem(struct file_system_type *);
 extern int unregister_filesystem(struct file_system_type *);
-extern int may_umount(struct super_block *);
+extern int may_umount(struct vfsmount *);
 
 static inline int vfs_statfs(struct super_block *sb, struct statfs *buf)
 {
index ff34ee99f971e4735fb7869c11106907085651c9..a7a11d69e7fce045e9bf272c0263009da9e2d4ab 100644 (file)
@@ -173,7 +173,7 @@ typedef struct page {
 #define PG_slab                         8
 #define PG_swap_cache           9
 #define PG_skip                        10
-#define PG_swap_entry          11
+#define PG_unused_03           11
 #define PG_highmem             12
                                /* bits 21-30 unused */
 #define PG_reserved            31
@@ -210,9 +210,6 @@ typedef struct page {
 #define PageClearSwapCache(page)       clear_bit(PG_swap_cache, &(page)->flags)
 
 #define PageTestandClearSwapCache(page)        test_and_clear_bit(PG_swap_cache, &(page)->flags)
-#define PageSwapEntry(page)            test_bit(PG_swap_entry, &(page)->flags)
-#define SetPageSwapEntry(page)         set_bit(PG_swap_entry, &(page)->flags)
-#define ClearPageSwapEntry(page)       clear_bit(PG_swap_entry, &(page)->flags)
 
 #ifdef CONFIG_HIGHMEM
 #define PageHighMem(page)              test_bit(PG_highmem, &(page)->flags)
index bb19b0807c193b25298ff977cfe282d74a24e64f..b2e1ac568dbe4fc72878eb7c5d1d11397552eb4f 100644 (file)
@@ -210,7 +210,7 @@ struct net_device
         * (i.e. as seen by users in the "Space.c" file).  It is the name
         * the interface.
         */
-       char                    *name;
+       char                    name[IFNAMSIZ];
 
        /*
         *      I/O specific fields
index 898ef7105af69caae3cf6d2ea69d9bcf111e5d46..4b958337ffb71c89cc4f6150872a7a9046f428a4 100644 (file)
@@ -15,7 +15,10 @@ struct ntfs_sb_info{
        ntfs_u32 at_standard_information;
        ntfs_u32 at_attribute_list;
        ntfs_u32 at_file_name;
+       ntfs_u32 at_volume_version;
        ntfs_u32 at_security_descriptor;
+       ntfs_u32 at_volume_name;
+       ntfs_u32 at_volume_information;
        ntfs_u32 at_data;
        ntfs_u32 at_index_root;
        ntfs_u32 at_index_allocation;
index 4377b14cd24a93474a172288b9dedeee8cfe701e..b65681331c9b999a71632ef2db63cc8e1191ddfb 100644 (file)
 #define PCI_DEVICE_ID_SI_5571          0x5571
 #define PCI_DEVICE_ID_SI_5591          0x5591
 #define PCI_DEVICE_ID_SI_5597          0x5597
+#define PCI_DEVICE_ID_SI_5598          0x5598
 #define PCI_DEVICE_ID_SI_5600          0x5600
 #define PCI_DEVICE_ID_SI_6306          0x6306
 #define PCI_DEVICE_ID_SI_6326          0x6326
index d6b4813127a329431d4264484e2c6a2e3f9a4231..07d7f0d4bac072496781f1ca25fdcac1ef283709 100644 (file)
@@ -203,7 +203,7 @@ struct mm_struct {
        unsigned long start_code, end_code, start_data, end_data;
        unsigned long start_brk, brk, start_stack;
        unsigned long arg_start, arg_end, env_start, env_end;
-       unsigned long min_flt, maj_flt, rss, total_vm, locked_vm;
+       unsigned long rss, total_vm, locked_vm;
        unsigned long def_flags;
        unsigned long cpu_vm_mask;
        unsigned long swap_cnt; /* number of pages to swap on next pass */
@@ -225,7 +225,7 @@ struct mm_struct {
                0, 0, 0, 0,                             \
                0, 0, 0,                                \
                0, 0, 0, 0,                             \
-               0, 0, 0, 0, 0,                          \
+               0, 0, 0,                                \
                0, 0, 0, 0, NULL }
 
 struct signal_struct {
index 5d5f97cdb24cebdf16ef77e6fda2c1059e842ff6..75da055a6bc8cb5f682af7468e17a61c3ec46e7d 100644 (file)
@@ -121,7 +121,6 @@ extern void get_swaphandle_info(swp_entry_t, unsigned long *, kdev_t *,
                                        struct inode **);
 extern int swap_duplicate(swp_entry_t);
 extern int swap_count(struct page *);
-extern swp_entry_t acquire_swap_entry(struct page *page);
 extern int valid_swaphandles(swp_entry_t, unsigned long *);
 #define get_swap_page() __get_swap_page(1)
 extern void __swap_free(swp_entry_t, unsigned short);
index e6eb00da0aa5a460f5bbbc09141b9e93aa60837a..5b1490553cd2ccd5a6d483e484b24b09208e9659 100644 (file)
@@ -2,6 +2,7 @@
 #define _LINUX_TIMER_H
 
 #include <linux/config.h>
+#include <linux/list.h>
 
 /*
  * Old-style timers. Please don't use for any new code.
@@ -47,8 +48,7 @@ extern struct timer_struct timer_table[32];
  * to distinguish between the different invocations.
  */
 struct timer_list {
-       struct timer_list *next; /* MUST be first element */
-       struct timer_list *prev;
+       struct list_head list;
        unsigned long expires;
        unsigned long data;
        void (*function)(unsigned long);
@@ -56,7 +56,7 @@ struct timer_list {
 };
 
 extern void add_timer(struct timer_list * timer);
-extern int  del_timer(struct timer_list * timer);
+extern int del_timer(struct timer_list * timer);
 
 /*
  * mod_timer is a more efficient way to update the expire field of an
@@ -69,16 +69,15 @@ extern void it_real_fn(unsigned long);
 
 extern inline void init_timer(struct timer_list * timer)
 {
-       timer->next = NULL;
-       timer->prev = NULL;
+       timer->list.next = timer->list.prev = NULL;
 #ifdef CONFIG_SMP
        timer->running = 0;
 #endif
 }
 
-extern inline int timer_pending(const struct timer_list * timer)
+extern inline int timer_pending (const struct timer_list * timer)
 {
-       return timer->prev != NULL;
+       return timer->list.next != NULL;
 }
 
 #ifdef CONFIG_SMP
index a568dd753eaed92be2dc07f3d0380a5e1a480d21..28d0584c423f28bb3e3778c0aaeb3dbab84ae468 100644 (file)
@@ -48,7 +48,6 @@ struct atmarp_entry {
 
 
 struct clip_priv {
-       char name[8];                   /* interface name */
        int number;                     /* for convenience ... */
        spinlock_t xoff_lock;           /* ensures that pop is atomic (SMP) */
        struct net_device_stats stats;
index aeae815017a8803112e763458765fbddafec5eb0..65fb19289600090a2f3a0656a5798b9c4b21f69c 100644 (file)
@@ -1079,7 +1079,7 @@ static __inline__ int tcp_snd_test(struct tcp_opt *tp, struct sk_buff *skb,
 
 static __inline__ void tcp_check_probe_timer(struct sock *sk, struct tcp_opt *tp)
 {
-       if (!tp->packets_out && !tp->probe_timer.prev)
+       if (!tp->packets_out && !timer_pending(&tp->probe_timer))
                tcp_reset_xmit_timer(sk, TCP_TIME_PROBE0, tp->rto);
 }
 
@@ -1505,13 +1505,13 @@ static inline int tcp_timer_is_set(struct sock *sk, int what)
 
        switch (what) {
        case TCP_TIME_RETRANS:
-               ret = tp->retransmit_timer.prev != NULL;
+               ret = timer_pending(&tp->retransmit_timer);
                break;
        case TCP_TIME_DACK:
-               ret = tp->delack_timer.prev != NULL;
+               ret = timer_pending(&tp->delack_timer);
                break;
        case TCP_TIME_PROBE0:
-               ret = tp->probe_timer.prev != NULL;
+               ret = timer_pending(&tp->probe_timer);
                break;  
        default:
                ret = 0;
index eca8db4c7073dc8e64048d80d9bec3fd7a3af210..17ebedb828276f1bdf758bee6ec7af391d4f8633 100644 (file)
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -1394,12 +1394,10 @@ static struct page * shm_nopage_core(struct shmid_kernel *shp, unsigned int idx,
                (*rss)++;
                pte = pte_mkdirty(mk_pte(page, PAGE_SHARED));
                SHM_ENTRY(shp, idx) = pte;
-       } else
-               --current->maj_flt;  /* was incremented in do_no_page */
+       }
 
        /* pte_val(pte) == SHM_ENTRY (shp, idx) */
        get_page(pte_page(pte));
-       current->min_flt++;
        return pte_page(pte);
 
 oom:
index fa63452e124b5801631838d7e36ecfee0fbf02d8..febda79097c2f86e04cb2fd3bf1184145bb8ae5e 100644 (file)
@@ -6,9 +6,9 @@
 
 /*
  *  'fork.c' contains the help-routines for the 'fork' system call
- * (see also system_call.s).
+ * (see also entry.S and others).
  * Fork is rather simple, once you get the hang of it, but the memory
- * management can be a bitch. See 'mm/mm.c': 'copy_page_tables()'
+ * management can be a bitch. See 'mm/memory.c': 'copy_page_tables()'
  */
 
 #include <linux/config.h>
index c846e4160eb6f99b1dee729489fa6871df96d22b..c42402e9546c15ed770fd92010c27548e7f15693 100644 (file)
@@ -1157,6 +1157,8 @@ void __init init_idle(void)
        sched_data->last_schedule = get_cycles();
 }
 
+extern void init_timervecs (void);
+
 void __init sched_init(void)
 {
        /*
@@ -1171,6 +1173,8 @@ void __init sched_init(void)
        for(nr = 0; nr < PIDHASH_SZ; nr++)
                pidhash[nr] = NULL;
 
+       init_timervecs();
+
        init_bh(TIMER_BH, timer_bh);
        init_bh(TQUEUE_BH, tqueue_bh);
        init_bh(IMMEDIATE_BH, immediate_bh);
index b28c69123f8ad50cd9943af8482313b2d29d05a9..1f2698dc306262d65a69ed83704174a3af009e02 100644 (file)
@@ -83,13 +83,13 @@ unsigned long prof_shift = 0;
 #define TVR_MASK (TVR_SIZE - 1)
 
 struct timer_vec {
-        int index;
-        struct timer_list *vec[TVN_SIZE];
+       int index;
+       struct list_head vec[TVN_SIZE];
 };
 
 struct timer_vec_root {
-        int index;
-        struct timer_list *vec[TVR_SIZE];
+       int index;
+       struct list_head vec[TVR_SIZE];
 };
 
 static struct timer_vec tv5 = { 0 };
@@ -104,19 +104,22 @@ static struct timer_vec * const tvecs[] = {
 
 #define NOOF_TVECS (sizeof(tvecs) / sizeof(tvecs[0]))
 
-static unsigned long timer_jiffies = 0;
-
-static inline void insert_timer(struct timer_list *timer, struct timer_list **vec)
+void init_timervecs (void)
 {
-       struct timer_list *next = *vec;
+       int i;
 
-       timer->next = next;
-       if (next)
-               next->prev = timer;
-       *vec = timer;
-       timer->prev = (struct timer_list *)vec;
+       for (i = 0; i < TVN_SIZE; i++) {
+               INIT_LIST_HEAD(tv5.vec + i);
+               INIT_LIST_HEAD(tv4.vec + i);
+               INIT_LIST_HEAD(tv3.vec + i);
+               INIT_LIST_HEAD(tv2.vec + i);
+       }
+       for (i = 0; i < TVR_SIZE; i++)
+               INIT_LIST_HEAD(tv1.vec + i);
 }
 
+static unsigned long timer_jiffies = 0;
+
 static inline void internal_add_timer(struct timer_list *timer)
 {
        /*
@@ -124,7 +127,7 @@ static inline void internal_add_timer(struct timer_list *timer)
         */
        unsigned long expires = timer->expires;
        unsigned long idx = expires - timer_jiffies;
-       struct timer_list ** vec;
+       struct list_head * vec;
 
        if (idx < TVR_SIZE) {
                int i = expires & TVR_MASK;
@@ -148,10 +151,13 @@ static inline void internal_add_timer(struct timer_list *timer)
                vec = tv5.vec + i;
        } else {
                /* Can only get here on architectures with 64-bit jiffies */
-               timer->next = timer->prev = timer;
+               INIT_LIST_HEAD(&timer->list);
                return;
        }
-       insert_timer(timer, vec);
+       /*
+        * Timers are FIFO!
+        */
+       list_add(&timer->list, vec->prev);
 }
 
 spinlock_t timerlist_lock = SPIN_LOCK_UNLOCKED;
@@ -161,7 +167,7 @@ void add_timer(struct timer_list *timer)
        unsigned long flags;
 
        spin_lock_irqsave(&timerlist_lock, flags);
-       if (timer->prev)
+       if (timer->list.next)
                goto bug;
        internal_add_timer(timer);
 out:
@@ -174,17 +180,12 @@ bug:
        goto out;
 }
 
-static inline int detach_timer(struct timer_list *timer)
+static inline int detach_timer (struct timer_list *timer)
 {
-       struct timer_list *prev = timer->prev;
-       if (prev) {
-               struct timer_list *next = timer->next;
-               prev->next = next;
-               if (next)
-                       next->prev = prev;
-               return 1;
-       }
-       return 0;
+       if (!timer_pending(timer))
+               return 0;
+       list_del(&timer->list);
+       return 1;
 }
 
 int mod_timer(struct timer_list *timer, unsigned long expires)
@@ -207,7 +208,7 @@ int del_timer(struct timer_list * timer)
 
        spin_lock_irqsave(&timerlist_lock, flags);
        ret = detach_timer(timer);
-       timer->next = timer->prev = 0;
+       timer->list.next = timer->list.prev = NULL;
        spin_unlock_irqrestore(&timerlist_lock, flags);
        return ret;
 }
@@ -231,7 +232,7 @@ int del_timer_sync(struct timer_list * timer)
 
                spin_lock_irqsave(&timerlist_lock, flags);
                ret += detach_timer(timer);
-               timer->next = timer->prev = 0;
+               timer->list.next = timer->list.prev = 0;
                running = timer->running;
                spin_unlock_irqrestore(&timerlist_lock, flags);
 
@@ -247,42 +248,58 @@ int del_timer_sync(struct timer_list * timer)
 
 static inline void cascade_timers(struct timer_vec *tv)
 {
-        /* cascade all the timers from tv up one level */
-        struct timer_list *timer;
-        timer = tv->vec[tv->index];
-        /*
-         * We are removing _all_ timers from the list, so we don't  have to
-         * detach them individually, just clear the list afterwards.
-         */
-        while (timer) {
-                struct timer_list *tmp = timer;
-                timer = timer->next;
-                internal_add_timer(tmp);
-        }
-        tv->vec[tv->index] = NULL;
-        tv->index = (tv->index + 1) & TVN_MASK;
+       /* cascade all the timers from tv up one level */
+       struct list_head *head, *curr, *next;
+
+       head = tv->vec + tv->index;
+       curr = head->next;
+       /*
+        * We are removing _all_ timers from the list, so we don't  have to
+        * detach them individually, just clear the list afterwards.
+        */
+       while (curr != head) {
+               struct timer_list *tmp;
+
+               tmp = list_entry(curr, struct timer_list, list);
+               next = curr->next;
+               list_del(curr); // not needed
+               internal_add_timer(tmp);
+               curr = next;
+       }
+       INIT_LIST_HEAD(head);
+       tv->index = (tv->index + 1) & TVN_MASK;
 }
 
 static inline void run_timer_list(void)
 {
        spin_lock_irq(&timerlist_lock);
        while ((long)(jiffies - timer_jiffies) >= 0) {
-               struct timer_list *timer;
+               struct list_head *head, *curr;
                if (!tv1.index) {
                        int n = 1;
                        do {
                                cascade_timers(tvecs[n]);
                        } while (tvecs[n]->index == 1 && ++n < NOOF_TVECS);
                }
-               while ((timer = tv1.vec[tv1.index])) {
-                       void (*fn)(unsigned long) = timer->function;
-                       unsigned long data = timer->data;
+repeat:
+               head = tv1.vec + tv1.index;
+               curr = head->next;
+               if (curr != head) {
+                       struct timer_list *timer;
+                       void (*fn)(unsigned long);
+                       unsigned long data;
+
+                       timer = list_entry(curr, struct timer_list, list);
+                       fn = timer->function;
+                       data= timer->data;
+
                        detach_timer(timer);
-                       timer->next = timer->prev = NULL;
+                       timer->list.next = timer->list.prev = NULL;
                        timer_set_running(timer);
                        spin_unlock_irq(&timerlist_lock);
                        fn(data);
                        spin_lock_irq(&timerlist_lock);
+                       goto repeat;
                }
                ++timer_jiffies; 
                tv1.index = (tv1.index + 1) & TVR_MASK;
@@ -340,7 +357,7 @@ static void second_overflow(void)
     /* Bump the maxerror field */
     time_maxerror += time_tolerance >> SHIFT_USEC;
     if ( time_maxerror > NTP_PHASE_LIMIT ) {
-        time_maxerror = NTP_PHASE_LIMIT;
+       time_maxerror = NTP_PHASE_LIMIT;
        time_status |= STA_UNSYNC;
     }
 
index 84ecb57b5e7b87a619a81a7d4087d638a307d4dc..f0baed69f8a280a16d25733071f8f4017a23fa8b 100644 (file)
@@ -824,7 +824,6 @@ static int do_wp_page(struct mm_struct *mm, struct vm_area_struct * vma,
        map_nr = pte_pagenr(pte);
        if (map_nr >= max_mapnr)
                goto bad_wp_page;
-       mm->min_flt++;
        old_page = mem_map + map_nr;
        
        /*
@@ -855,7 +854,7 @@ static int do_wp_page(struct mm_struct *mm, struct vm_area_struct * vma,
                flush_cache_page(vma, address);
                establish_pte(vma, address, page_table, pte_mkyoung(pte_mkdirty(pte_mkwrite(pte))));
                spin_unlock(&mm->page_table_lock);
-               return 1;
+               return 1;       /* Minor fault */
        }
 
        /*
@@ -880,7 +879,7 @@ static int do_wp_page(struct mm_struct *mm, struct vm_area_struct * vma,
        }
        spin_unlock(&mm->page_table_lock);
        __free_page(new_page);
-       return 1;
+       return 1;       /* Minor fault */
 
 bad_wp_page:
        spin_unlock(&mm->page_table_lock);
@@ -1049,12 +1048,9 @@ static int do_swap_page(struct mm_struct * mm,
        }
 
        mm->rss++;
-       mm->min_flt++;
 
        pte = mk_pte(page, vma->vm_page_prot);
 
-       SetPageSwapEntry(page);
-
        /*
         * Freeze the "shared"ness of the page, ie page_count + swap_count.
         * Must lock page before transferring our swap count to already
@@ -1074,7 +1070,7 @@ static int do_swap_page(struct mm_struct * mm,
        set_pte(page_table, pte);
        /* No need to invalidate - it was non-present before */
        update_mmu_cache(vma, address, pte);
-       return 1;
+       return 1;       /* Minor fault */
 }
 
 /*
@@ -1094,13 +1090,12 @@ static int do_anonymous_page(struct mm_struct * mm, struct vm_area_struct * vma,
                clear_user_highpage(page, addr);
                entry = pte_mkwrite(pte_mkdirty(mk_pte(page, vma->vm_page_prot)));
                mm->rss++;
-               mm->min_flt++;
                flush_page_to_ram(page);
        }
        set_pte(page_table, entry);
        /* No need to invalidate - it was non-present before */
        update_mmu_cache(vma, addr, entry);
-       return 1;
+       return 1;       /* Minor fault */
 }
 
 /*
@@ -1133,7 +1128,6 @@ static int do_no_page(struct mm_struct * mm, struct vm_area_struct * vma,
                return 0;
        if (new_page == NOPAGE_OOM)
                return -1;
-       ++mm->maj_flt;
        ++mm->rss;
        /*
         * This silly early PAGE_DIRTY setting removes a race
@@ -1156,7 +1150,7 @@ static int do_no_page(struct mm_struct * mm, struct vm_area_struct * vma,
        set_pte(page_table, entry);
        /* no need to invalidate: a not-present page shouldn't be cached */
        update_mmu_cache(vma, address, entry);
-       return 1;
+       return 2;       /* Major fault */
 }
 
 /*
index 23acf5af4272be8c58dab7433d7d9da0dd92ca30..76c47d212a2fe7a771ed97c86e98fa56ee08ff8f 100644 (file)
@@ -132,6 +132,11 @@ void rw_swap_page_nolock(int rw, swp_entry_t entry, char *buf, int wait)
                PAGE_BUG(page);
        if (PageSwapCache(page))
                PAGE_BUG(page);
+       if (page->mapping)
+               PAGE_BUG(page);
+       /* needs sync_page to wait I/O completation */
+       page->mapping = &swapper_space;
        if (!rw_swap_page_base(rw, entry, page, wait))
                UnlockPage(page);
+       page->mapping = NULL;
 }
index 29ba0d78b9307b81519270f5ec09c169e82489b9..26dcf6feaaa0cf9c215f4a73ca330817efa1e5a8 100644 (file)
@@ -130,9 +130,6 @@ void free_page_and_swap_cache(struct page *page)
                }
                UnlockPage(page);
        }
-
-       ClearPageSwapEntry(page);
-
        __free_page(page);
 }
 
index da2dd9147eab6de9736d3ce4a235f218f8d18835..b948de34a65973dd350ef00e8faa49020dced25e 100644 (file)
@@ -200,49 +200,6 @@ bad_count:
        goto out;
 }
 
-/* needs the big kernel lock */
-swp_entry_t acquire_swap_entry(struct page *page)
-{
-       struct swap_info_struct * p;
-       unsigned long offset, type;
-       swp_entry_t entry;
-
-       if (!PageSwapEntry(page))
-               goto new_swap_entry;
-
-       /* We have the old entry in the page offset still */
-       if (!page->index)
-               goto new_swap_entry;
-       entry.val = page->index;
-       type = SWP_TYPE(entry);
-       if (type >= nr_swapfiles)
-               goto new_swap_entry;
-       p = type + swap_info;
-       if ((p->flags & SWP_WRITEOK) != SWP_WRITEOK)
-               goto new_swap_entry;
-       offset = SWP_OFFSET(entry);
-       if (offset >= p->max)
-               goto new_swap_entry;
-       /* Has it been re-used for something else? */
-       swap_list_lock();
-       swap_device_lock(p);
-       if (p->swap_map[offset])
-               goto unlock_new_swap_entry;
-
-       /* We're cool, we can just use the old one */
-       p->swap_map[offset] = 1;
-       swap_device_unlock(p);
-       nr_swap_pages--;
-       swap_list_unlock();
-       return entry;
-
-unlock_new_swap_entry:
-       swap_device_unlock(p);
-       swap_list_unlock();
-new_swap_entry:
-       return get_swap_page();
-}
-
 /*
  * The swap entry has been read in advance, and we return 1 to indicate
  * that the page has been used or is no longer needed.
index 644ff1cdec26ff522bf60a379239ce56c3ce8fd1..06ad20249896a0339a460df74d9a88ff8c01768c 100644 (file)
@@ -151,7 +151,7 @@ drop_pte:
         * we have the swap cache set up to associate the
         * page with that swap entry.
         */
-       entry = acquire_swap_entry(page);
+       entry = get_swap_page();
        if (!entry.val)
                goto out_failed; /* No swap space left */
                
@@ -387,8 +387,8 @@ int swap_out(unsigned int priority, int gfp_mask)
                                if (!p->swappable || !mm || mm->rss <= 0)
                                        continue;
                                /* small processes are swapped out less */
-                               while ((mm->swap_cnt << 2 * (i + 1) < max_cnt)
-                                               && i++ < 10)
+                               while ((mm->swap_cnt << 2 * (i + 1) < max_cnt) && i++ < 10)
+                                       /* nothing */;
                                mm->swap_cnt >>= i;
                                mm->swap_cnt += i; /* if swap_cnt reaches 0 */
                                /* we're big -> hog treatment */
index f1bd99b94d7d28e04595b18c5fabf4140e3b47c7..c2b6788c905e93041cf955a34a1d7f7a06d3a0e4 100644 (file)
@@ -594,7 +594,6 @@ int clip_create(int number)
        if (!dev) return -ENOMEM;
        memset(dev,0,sizeof(struct net_device)+sizeof(struct clip_priv));
        clip_priv = PRIV(dev);
-       dev->name = clip_priv->name;
        sprintf(dev->name,"atm%d",number);
        dev->init = clip_init;
        spin_lock_init(&clip_priv->xoff_lock);
index cb6b75d9fe65d1b4e223678b43713a99496fa0c4..0e9454579ac74c240335df754d52f2ec0407f829 100644 (file)
@@ -453,13 +453,12 @@ int dev_alloc_name(struct net_device *dev, const char *name)
 
 struct net_device *dev_alloc(const char *name, int *err)
 {
-       struct net_device *dev=kmalloc(sizeof(struct net_device)+16, GFP_KERNEL);
+       struct net_device *dev=kmalloc(sizeof(struct net_device), GFP_KERNEL);
        if (dev == NULL) {
                *err = -ENOBUFS;
                return NULL;
        }
        memset(dev, 0, sizeof(struct net_device));
-       dev->name = (char *)(dev + 1);  /* Name string space */
        *err = dev_alloc_name(dev, name);
        if (*err < 0) {
                kfree(dev);
index 50b160a4c45c2aa403a288c1550025f5bae6f83b..2b17d37820f25ac4db9e10d3a2854da2c6452d36 100644 (file)
@@ -37,7 +37,7 @@ static unsigned long dst_gc_timer_inc = DST_GC_MAX;
 static void dst_run_gc(unsigned long);
 
 static struct timer_list dst_gc_timer =
-       { NULL, NULL, DST_GC_MIN, 0L, dst_run_gc };
+       { data: DST_GC_MIN, function: dst_run_gc };
 
 
 static void dst_run_gc(unsigned long dummy)
index a20273d7d9385f89767fad90445800f8dc5d80f0..1ce3860cbefcb73bcec81fb67dbd10a3809e3275 100644 (file)
@@ -94,7 +94,7 @@ spinlock_t inet_peer_unused_lock = SPIN_LOCK_UNLOCKED;
 
 static void peer_check_expire(unsigned long dummy);
 static struct timer_list peer_periodic_timer =
-       { NULL, NULL, 0, 0, &peer_check_expire };
+       { { NULL, NULL }, 0, 0, &peer_check_expire };
 int inet_peer_gc_mintime = 10 * HZ,
     inet_peer_gc_maxtime = 120 * HZ;
 
index cd51bcef3a2d318d8365ca548da797b12a6de4a9..94cfa649db6d712260a04ef76af5d5e589fd7f56 100644 (file)
@@ -227,20 +227,17 @@ static int __init ic_setup_if(void)
        strcpy(ir.ifr_ifrn.ifrn_name, ic_dev->name);
        set_sockaddr(sin, ic_myaddr, 0);
        if ((err = ic_dev_ioctl(SIOCSIFADDR, &ir)) < 0) {
-               printk(KERN_ERR "IP-Config: Unable to set interface address (%u.%u.%u.%u).\n",
-                       NIPQUAD(err));
+               printk(KERN_ERR "IP-Config: Unable to set interface address (%d).\n", err);
                return -1;
        }
        set_sockaddr(sin, ic_netmask, 0);
        if ((err = ic_dev_ioctl(SIOCSIFNETMASK, &ir)) < 0) {
-               printk(KERN_ERR "IP-Config: Unable to set interface netmask (%u.%u.%u.%u).\n",
-                       NIPQUAD(err));
+               printk(KERN_ERR "IP-Config: Unable to set interface netmask (%d).\n", err);
                return -1;
        }
        set_sockaddr(sin, ic_myaddr | ~ic_netmask, 0);
        if ((err = ic_dev_ioctl(SIOCSIFBRDADDR, &ir)) < 0) {
-               printk(KERN_ERR "IP-Config: Unable to set interface broadcast address (%u.%u.%u.%u).\n",
-                       NIPQUAD(err));
+               printk(KERN_ERR "IP-Config: Unable to set interface broadcast address (%d).\n", err);
                return -1;
        }
        return 0;
@@ -264,8 +261,7 @@ static int __init ic_setup_routes(void)
                set_sockaddr((struct sockaddr_in *) &rm.rt_gateway, ic_gateway, 0);
                rm.rt_flags = RTF_UP | RTF_GATEWAY;
                if ((err = ic_route_ioctl(SIOCADDRT, &rm)) < 0) {
-                       printk(KERN_ERR "IP-Config: Cannot add default route (%u.%u.%u.%u).\n",
-                               NIPQUAD(err));
+                       printk(KERN_ERR "IP-Config: Cannot add default route (%d).\n", err);
                        return -1;
                }
        }
index a7555b6b5de19bc5a011e53decc40b5f9d34c0e6..2c96b967aec26b0a293deb1af4ca06119dc588d7 100644 (file)
@@ -591,7 +591,7 @@ static void get_raw_sock(struct sock *sp, char *tmpbuf, int i)
        src   = sp->rcv_saddr;
        destp = 0;
        srcp  = sp->num;
-       timer_active = (sp->timer.prev != NULL) ? 2 : 0;
+       timer_active = (timer_pending(&sp->timer)) ? 2 : 0;
        timer_expires = (timer_active == 2 ? sp->timer.expires : jiffies);
        sprintf(tmpbuf, "%4d: %08X:%04X %08X:%04X"
                " %02X %08X:%08X %02X:%08lX %08X %5d %8d %ld %d %p",
index 5facec2c853cdcfcc5848213d10df597bb5ac73a..278157e88fc9a8f7cdebe0da0b9eb9e83b6282d6 100644 (file)
@@ -2002,14 +2002,14 @@ static void get_tcp_sock(struct sock *sp, char *tmpbuf, int i)
        srcp  = ntohs(sp->sport);
        timer_active    = 0;
        timer_expires   = (unsigned) -1;
-       if (tp->retransmit_timer.prev != NULL && tp->retransmit_timer.expires < timer_expires) {
+       if (timer_pending(&tp->retransmit_timer) && tp->retransmit_timer.expires < timer_expires) {
                timer_active    = 1;
                timer_expires   = tp->retransmit_timer.expires;
-       } else if (tp->probe_timer.prev != NULL && tp->probe_timer.expires < timer_expires) {
+       } else if (timer_pending(&tp->probe_timer) && tp->probe_timer.expires < timer_expires) {
                timer_active    = 4;
                timer_expires   = tp->probe_timer.expires;
        }
-       if (sp->timer.prev != NULL && sp->timer.expires < timer_expires) {
+       if (timer_pending(&sp->timer) && sp->timer.expires < timer_expires) {
                timer_active    = 2;
                timer_expires   = sp->timer.expires;
        }
index 9e98877074923f741034a2861fd09318669f1681..bbc155e2d7afdd6003be1e2a3f93cd22a9d338f0 100644 (file)
@@ -378,7 +378,7 @@ void tcp_tw_deschedule(struct tcp_tw_bucket *tw)
 static int tcp_twcal_hand = -1;
 static int tcp_twcal_jiffie;
 static void tcp_twcal_tick(unsigned long);
-static struct timer_list tcp_twcal_timer = {NULL, NULL, 0, 0, tcp_twcal_tick,};
+static struct timer_list tcp_twcal_timer = {function: tcp_twcal_tick};
 static struct tcp_tw_bucket *tcp_twcal_row[TCP_TW_RECYCLE_SLOTS];
 
 void tcp_tw_schedule(struct tcp_tw_bucket *tw, int timeo)
index 570e1de2bb8d788b8abece918abf11dd9aebb984..a4cd08b53f26490791316d51d4d7021365742a04 100644 (file)
@@ -988,7 +988,7 @@ static void get_udp_sock(struct sock *sp, char *tmpbuf, int i)
        src   = sp->rcv_saddr;
        destp = ntohs(sp->dport);
        srcp  = ntohs(sp->sport);
-       timer_active = (sp->timer.prev != NULL) ? 2 : 0;
+       timer_active = timer_pending(&sp->timer) ? 2 : 0;
        timer_expires = (timer_active == 2 ? sp->timer.expires : jiffies);
        sprintf(tmpbuf, "%4d: %08X:%04X %08X:%04X"
                " %02X %08X:%08X %02X:%08lX %08X %5d %8d %ld %d %p",
index d0c0539aa6c8c6b0bc11a6c10f9ec6d77fa875bd..7fa9ed97527df90c3e17837ce9602a94978a40ce 100644 (file)
@@ -513,7 +513,7 @@ void dev_shutdown(struct net_device *dev)
         }
 #endif
        BUG_TRAP(dev->qdisc_list == NULL);
-       BUG_TRAP(dev->watchdog_timer.prev == NULL);
+       BUG_TRAP(!timer_pending(&dev->watchdog_timer));
        dev->qdisc_list = NULL;
        spin_unlock_bh(&dev->queue_lock);
        write_unlock(&qdisc_tree_lock);
index 309f76bc470f183ce6b8367e65e6726cda5f1316..a29ad21f54df97d4e6d5bec9eca1300585bf08a3 100644 (file)
@@ -269,6 +269,8 @@ static int sock_map_fd(struct socket *sock)
                }
 
                file->f_dentry = d_alloc_root(sock->inode);
+               /* MOUNT_REWRITE: set to sockfs internal vfsmnt */
+               file->f_vfsmnt = NULL;
                if (!file->f_dentry) {
                        put_filp(file);
                        put_unused_fd(fd);