Merge master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
authorLinus Torvalds <torvalds@woody.linux-foundation.org>
Mon, 26 Feb 2007 20:23:08 +0000 (12:23 -0800)
committerLinus Torvalds <torvalds@woody.linux-foundation.org>
Mon, 26 Feb 2007 20:23:08 +0000 (12:23 -0800)
* master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6: (25 commits)
  [XFRM]: Fix oops in xfrm4_dst_destroy()
  [XFRM_TUNNEL]: Reload header pointer after pskb_may_pull/pskb_expand_head
  [IPV4]: Use random32() in net/ipv4/multipath
  [BRIDGE]: eliminate workqueue for carrier check
  [BRIDGE]: get rid of miscdevice include
  [IPV6]: Fix __ipv6_addr_type() export in correct place.
  [IPV4] devinet: Register inetdev earlier.
  [IPV6] ADDRCONF: Register inet6_dev earlier.
  [IPV6] ADDRCONF: Manage prefix route corresponding to address manually added.
  [IPV6] IP6TUNNEL: Use update_pmtu() of dst on xmit.
  [IPV6] ADDRCONF: Statically link __ipv6_addr_type() for sunrpc subsystem.
  [IPV4]: Correct links in net/ipv4/Kconfig
  [SCTP]: Strike the transport before updating rto.
  [SCTP]: Fix connection hang/slowdown with PR-SCTP
  [TCP]: Fix MD5 signature pool locking.
  [TG3]: TSO workaround fixes.
  [AF_PACKET]: Remove unnecessary casts.
  [IPV6]: Adjust inet6_exit() cleanup sequence against inet6_init()
  [IPSEC]: More fix is needed for __xfrm6_bundle_create().
  [IRDA] net/irda/: proper prototypes
  ...

158 files changed:
Documentation/kernel-parameters.txt
Documentation/magic-number.txt
MAINTAINERS
arch/mips/Kconfig
arch/mips/Makefile
arch/mips/cobalt/mtd.c
arch/mips/configs/atlas_defconfig
arch/mips/configs/bigsur_defconfig
arch/mips/configs/capcella_defconfig
arch/mips/configs/cobalt_defconfig
arch/mips/configs/db1000_defconfig
arch/mips/configs/db1100_defconfig
arch/mips/configs/db1200_defconfig
arch/mips/configs/db1500_defconfig
arch/mips/configs/db1550_defconfig
arch/mips/configs/ddb5477_defconfig
arch/mips/configs/decstation_defconfig
arch/mips/configs/e55_defconfig
arch/mips/configs/emma2rh_defconfig
arch/mips/configs/ev64120_defconfig
arch/mips/configs/excite_defconfig
arch/mips/configs/ip22_defconfig
arch/mips/configs/ip27_defconfig
arch/mips/configs/ip32_defconfig
arch/mips/configs/jaguar-atx_defconfig
arch/mips/configs/jazz_defconfig
arch/mips/configs/jmr3927_defconfig
arch/mips/configs/lasat200_defconfig
arch/mips/configs/malta_defconfig
arch/mips/configs/mipssim_defconfig
arch/mips/configs/mpc30x_defconfig
arch/mips/configs/ocelot_3_defconfig
arch/mips/configs/ocelot_c_defconfig
arch/mips/configs/ocelot_defconfig
arch/mips/configs/ocelot_g_defconfig
arch/mips/configs/pb1100_defconfig
arch/mips/configs/pb1500_defconfig
arch/mips/configs/pb1550_defconfig
arch/mips/configs/pnx8550-jbs_defconfig
arch/mips/configs/pnx8550-stb810_defconfig
arch/mips/configs/pnx8550-v2pci_defconfig
arch/mips/configs/qemu_defconfig
arch/mips/configs/rbhma4500_defconfig
arch/mips/configs/rm200_defconfig
arch/mips/configs/sb1250-swarm_defconfig
arch/mips/configs/sead_defconfig
arch/mips/configs/tb0226_defconfig
arch/mips/configs/tb0229_defconfig
arch/mips/configs/tb0287_defconfig
arch/mips/configs/workpad_defconfig
arch/mips/configs/wrppmc_defconfig
arch/mips/configs/yosemite_defconfig
arch/mips/defconfig
arch/mips/kernel/asm-offsets.c
arch/mips/kernel/ptrace.c
arch/mips/kernel/signal.c
arch/mips/kernel/smp.c
arch/mips/kernel/traps.c
arch/mips/mm/ioremap.c
arch/mips/momentum/jaguar_atx/platform.c
arch/mips/momentum/ocelot_3/platform.c
arch/mips/momentum/ocelot_c/platform.c
arch/sparc64/defconfig
arch/sparc64/kernel/irq.c
arch/sparc64/kernel/pci.c
drivers/base/class.c
drivers/base/core.c
drivers/char/agp/Makefile
drivers/char/agp/agp.h
drivers/char/agp/ali-agp.c
drivers/char/agp/amd-k7-agp.c
drivers/char/agp/amd64-agp.c
drivers/char/agp/ati-agp.c
drivers/char/agp/efficeon-agp.c
drivers/char/agp/generic.c
drivers/char/agp/hp-agp.c
drivers/char/agp/i460-agp.c
drivers/char/agp/intel-agp.c
drivers/char/agp/nvidia-agp.c
drivers/char/agp/parisc-agp.c
drivers/char/agp/sgi-agp.c
drivers/char/agp/sis-agp.c
drivers/char/agp/sworks-agp.c
drivers/char/agp/uninorth-agp.c
drivers/char/agp/via-agp.c
drivers/leds/Kconfig
drivers/leds/Makefile
drivers/leds/leds-cobalt.c [new file with mode: 0644]
drivers/leds/leds-h1940.c [new file with mode: 0644]
drivers/pcmcia/hd64465_ss.c
drivers/pcmcia/m32r_cfc.c
drivers/pcmcia/m8xx_pcmcia.c
drivers/pcmcia/omap_cf.c
drivers/pcmcia/rsrc_mgr.c
drivers/pcmcia/vrc4171_card.c
drivers/sbus/char/Kconfig
drivers/sbus/char/Makefile
drivers/sbus/char/aurora.c [deleted file]
drivers/sbus/char/aurora.h [deleted file]
drivers/sbus/char/bbc_i2c.c
drivers/sbus/char/cd180.h [deleted file]
drivers/sbus/char/uctrl.c
drivers/serial/serial_txx9.c
drivers/usb/core/Makefile
drivers/usb/core/driver.c
drivers/usb/core/hub.c
drivers/usb/core/message.c
drivers/usb/core/quirks.c [new file with mode: 0644]
drivers/usb/core/sysfs.c
drivers/usb/core/usb.c
drivers/usb/core/usb.h
drivers/usb/gadget/inode.c
drivers/usb/host/uhci-debug.c
drivers/usb/host/uhci-hcd.c
drivers/usb/host/uhci-hcd.h
drivers/usb/host/uhci-q.c
drivers/usb/input/usbkbd.c
drivers/usb/input/usbmouse.c
drivers/usb/input/wacom_wac.c
drivers/usb/input/wacom_wac.h
drivers/usb/misc/Kconfig
drivers/usb/misc/Makefile
drivers/usb/misc/iowarrior.c [new file with mode: 0644]
drivers/usb/mon/mon_bin.c
drivers/usb/mon/mon_text.c
drivers/usb/mon/usb_mon.h
drivers/usb/net/Kconfig
drivers/usb/net/Makefile
drivers/usb/net/asix.c
drivers/usb/net/dm9601.c [new file with mode: 0644]
drivers/usb/serial/ftdi_sio.c
drivers/usb/serial/ftdi_sio.h
drivers/usb/serial/option.c
fs/jfs/jfs_txnmgr.c
fs/sysfs/file.c
fs/sysfs/sysfs.h
include/asm-mips/ptrace.h
include/asm-mips/sigcontext.h
include/asm-mips/stackframe.h
include/linux/device.h
include/linux/kmod.h
include/linux/pm.h
include/linux/sysfs.h
include/linux/usb.h
include/linux/usb/ch9.h
include/linux/usb/iowarrior.h [new file with mode: 0644]
include/linux/usb/quirks.h [new file with mode: 0644]
kernel/kmod.c
kernel/module.c
kernel/params.c
kernel/power/main.c
kernel/time/tick-common.c
kernel/time/tick-sched.c
security/selinux/hooks.c
security/selinux/ss/avtab.c
security/selinux/ss/policydb.c
security/selinux/ss/services.c
security/selinux/ss/sidtab.c

index c479d30..03eb5ed 100644 (file)
@@ -1758,6 +1758,13 @@ and is between 256 and 4096 characters. It is defined in the file
                        Note that genuine overcurrent events won't be
                        reported either.
 
+       usbcore.autosuspend=
+                       [USB] The autosuspend time delay (in seconds) used
+                       for newly-detected USB devices (default 2).  This
+                       is the time required before an idle device will be
+                       autosuspended.  Devices for which the delay is set
+                       to 0 won't be autosuspended at all.
+
        usbhid.mousepoll=
                        [USBHID] The interval which mice are to be polled at.
 
index af67fac..0e740c8 100644 (file)
@@ -65,7 +65,6 @@ CMAGIC                0x0111      user              include/linux/a.out.h
 MKISS_DRIVER_MAGIC    0x04bf      mkiss_channel     drivers/net/mkiss.h
 RISCOM8_MAGIC         0x0907      riscom_port       drivers/char/riscom8.h
 SPECIALIX_MAGIC       0x0907      specialix_port    drivers/char/specialix_io8.h
-AURORA_MAGIC          0x0A18      Aurora_port       drivers/sbus/char/aurora.h
 HDLC_MAGIC            0x239e      n_hdlc            drivers/char/n_hdlc.c
 APM_BIOS_MAGIC        0x4101      apm_user          arch/i386/kernel/apm.c
 CYCLADES_MAGIC        0x4359      cyclades_port     include/linux/cyclades.h
index c268b51..a9c1319 100644 (file)
@@ -3392,6 +3392,13 @@ L:       linux-usb-devel@lists.sourceforge.net
 S:     Maintained
 W:     http://www.kroah.com/linux-usb/
 
+USB DAVICOM DM9601 DRIVER
+P:     Peter Korsgaard
+M:     jacmet@sunsite.dk
+L:     linux-usb-devel@lists.sourceforge.net
+W:     http://www.linux-usb.org/usbnet
+S:     Maintained
+
 USB EHCI DRIVER
 P:     David Brownell
 M:     dbrownell@users.sourceforge.net
index c6f74f1..58e9788 100644 (file)
@@ -274,6 +274,7 @@ config MIPS_ATLAS
        select SYS_SUPPORTS_BIG_ENDIAN
        select SYS_SUPPORTS_LITTLE_ENDIAN
        select SYS_SUPPORTS_MULTITHREADING if EXPERIMENTAL
+       select SYS_SUPPORTS_SMARTMIPS
        select GENERIC_HARDIRQS_NO__DO_IRQ
        help
          This enables support for the MIPS Technologies Atlas evaluation
@@ -305,6 +306,7 @@ config MIPS_MALTA
        select SYS_SUPPORTS_BIG_ENDIAN
        select SYS_SUPPORTS_LITTLE_ENDIAN
        select SYS_SUPPORTS_MULTITHREADING
+       select SYS_SUPPORTS_SMARTMIPS
        help
          This enables support for the MIPS Technologies Malta evaluation
          board.
@@ -322,6 +324,7 @@ config MIPS_SEAD
        select SYS_SUPPORTS_64BIT_KERNEL if EXPERIMENTAL
        select SYS_SUPPORTS_BIG_ENDIAN
        select SYS_SUPPORTS_LITTLE_ENDIAN
+       select SYS_SUPPORTS_SMARTMIPS
        help
          This enables support for the MIPS Technologies SEAD evaluation
          board.
@@ -1641,6 +1644,18 @@ config 64BIT_PHYS_ADDR
 config CPU_HAS_LLSC
        bool
 
+config CPU_HAS_SMARTMIPS
+       depends on SYS_SUPPORTS_SMARTMIPS
+       bool "Support for the SmartMIPS ASE"
+       help
+         SmartMIPS is a extension of the MIPS32 architecture aimed at
+         increased security at both hardware and software level for
+         smartcards.  Enabling this option will allow proper use of the
+         SmartMIPS instructions by Linux applications.  However a kernel with
+         this option will not work on a MIPS core without SmartMIPS core.  If
+         you don't know you probably don't have SmartMIPS and should say N
+         here.
+
 config CPU_HAS_WB
        bool
 
@@ -1704,6 +1719,9 @@ config CPU_SUPPORTS_HIGHMEM
 config SYS_SUPPORTS_HIGHMEM
        bool
 
+config SYS_SUPPORTS_SMARTMIPS
+       bool
+
 config ARCH_FLATMEM_ENABLE
        def_bool y
        depends on !NUMA
index c68b5d3..92bca6a 100644 (file)
@@ -103,6 +103,8 @@ predef-le += -DMIPSEL -D_MIPSEL -D__MIPSEL -D__MIPSEL__
 cflags-$(CONFIG_CPU_BIG_ENDIAN)                += $(shell $(CC) -dumpmachine |grep -q 'mips.*el-.*' && echo -EB $(undef-all) $(predef-be))
 cflags-$(CONFIG_CPU_LITTLE_ENDIAN)     += $(shell $(CC) -dumpmachine |grep -q 'mips.*el-.*' || echo -EL $(undef-all) $(predef-le))
 
+cflags-$(CONFIG_CPU_HAS_SMARTMIPS)     += $(call cc-option,-msmartmips)
+
 cflags-$(CONFIG_SB1XXX_CORELIS)        += $(call cc-option,-mno-sched-prolog) \
                                   -fno-omit-frame-pointer
 
index 01d8ec7..2b088ef 100644 (file)
@@ -24,7 +24,7 @@
 
 static struct mtd_partition cobalt_mtd_partitions[] = {
        {
-               .name   = "Colo",
+               .name   = "firmware",
                .offset = 0x0,
                .size   = 0x80000,
        },
index 45874d1..4588949 100644 (file)
@@ -139,10 +139,12 @@ CONFIG_MIPS_MT_DISABLED=y
 CONFIG_SYS_SUPPORTS_MULTITHREADING=y
 # CONFIG_64BIT_PHYS_ADDR is not set
 CONFIG_CPU_HAS_LLSC=y
+# CONFIG_CPU_HAS_SMARTMIPS is not set
 CONFIG_CPU_HAS_SYNC=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_CPU_SUPPORTS_HIGHMEM=y
+CONFIG_SYS_SUPPORTS_SMARTMIPS=y
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_SELECT_MEMORY_MODEL=y
 CONFIG_FLATMEM_MANUAL=y
index b4cdd3e..aa05e29 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.20
-# Sun Feb 18 21:27:35 2007
+# Tue Feb 20 21:47:22 2007
 #
 CONFIG_MIPS=y
 
@@ -417,6 +417,7 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
 #
 # Plug and Play support
 #
+# CONFIG_PNPACPI is not set
 
 #
 # Block devices
@@ -589,6 +590,7 @@ CONFIG_NET_SB1250_MAC=y
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
 # CONFIG_QLA3XXX is not set
+# CONFIG_ATL1 is not set
 
 #
 # Ethernet (10000 Mbit)
@@ -1025,7 +1027,6 @@ CONFIG_FORCED_INLINING=y
 CONFIG_CROSSCOMPILE=y
 CONFIG_CMDLINE=""
 # CONFIG_DEBUG_STACK_USAGE is not set
-# CONFIG_KGDB is not set
 # CONFIG_SB1XXX_CORELIS is not set
 # CONFIG_RUNTIME_DEBUG is not set
 
index b05469e..b2594fa 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.20
-# Sun Feb 18 21:27:36 2007
+# Tue Feb 20 21:47:22 2007
 #
 CONFIG_MIPS=y
 
@@ -388,6 +388,7 @@ CONFIG_CONNECTOR=m
 #
 # Plug and Play support
 #
+# CONFIG_PNPACPI is not set
 
 #
 # Block devices
index f88c40f..9090a7a 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.20
-# Mon Feb 19 14:51:58 2007
+# Tue Feb 20 21:47:24 2007
 #
 CONFIG_MIPS=y
 
@@ -425,7 +425,7 @@ CONFIG_MTD_CFI_UTIL=y
 # CONFIG_MTD_COMPLEX_MAPPINGS is not set
 CONFIG_MTD_PHYSMAP=y
 CONFIG_MTD_PHYSMAP_START=0x0
-CONFIG_MTD_PHYSMAP_LEN=0
+CONFIG_MTD_PHYSMAP_LEN=0x0
 CONFIG_MTD_PHYSMAP_BANKWIDTH=0
 # CONFIG_MTD_PLATRAM is not set
 
@@ -449,7 +449,6 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=0
 # NAND Flash Device Drivers
 #
 # CONFIG_MTD_NAND is not set
-# CONFIG_MTD_NAND_CAFE is not set
 
 #
 # OneNAND Flash Device Drivers
@@ -464,6 +463,7 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=0
 #
 # Plug and Play support
 #
+# CONFIG_PNPACPI is not set
 
 #
 # Block devices
@@ -658,6 +658,7 @@ CONFIG_TULIP=y
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
 CONFIG_QLA3XXX=y
+# CONFIG_ATL1 is not set
 
 #
 # Ethernet (10000 Mbit)
index 1db19f1..4cb8cf4 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.20
-# Sun Feb 18 21:27:39 2007
+# Tue Feb 20 21:47:24 2007
 #
 CONFIG_MIPS=y
 
@@ -548,6 +548,7 @@ CONFIG_MTD_ALCHEMY=y
 #
 # Plug and Play support
 #
+# CONFIG_PNPACPI is not set
 
 #
 # Block devices
@@ -1103,6 +1104,7 @@ CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_CROSSCOMPILE=y
 CONFIG_CMDLINE=""
+CONFIG_SYS_SUPPORTS_KGDB=y
 
 #
 # Security options
index 529e6eb..d86dedf 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.20
-# Sun Feb 18 21:27:39 2007
+# Tue Feb 20 21:47:24 2007
 #
 CONFIG_MIPS=y
 
@@ -537,6 +537,7 @@ CONFIG_MTD_ALCHEMY=y
 #
 # Plug and Play support
 #
+# CONFIG_PNPACPI is not set
 
 #
 # Block devices
@@ -1103,6 +1104,7 @@ CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_CROSSCOMPILE=y
 CONFIG_CMDLINE=""
+CONFIG_SYS_SUPPORTS_KGDB=y
 
 #
 # Security options
index 9e86dcd..c24b600 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.20
-# Sun Feb 18 21:27:40 2007
+# Tue Feb 20 21:47:25 2007
 #
 CONFIG_MIPS=y
 
@@ -541,6 +541,7 @@ CONFIG_MTD_NAND_IDS=y
 #
 # Plug and Play support
 #
+# CONFIG_PNPACPI is not set
 
 #
 # Block devices
@@ -1185,6 +1186,7 @@ CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_CROSSCOMPILE=y
 CONFIG_CMDLINE="mem=48M"
+CONFIG_SYS_SUPPORTS_KGDB=y
 
 #
 # Security options
index 9c94461..baad2c5 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.20
-# Sun Feb 18 21:27:41 2007
+# Tue Feb 20 21:47:26 2007
 #
 CONFIG_MIPS=y
 
@@ -542,7 +542,6 @@ CONFIG_MTD_ALCHEMY=y
 # NAND Flash Device Drivers
 #
 # CONFIG_MTD_NAND is not set
-# CONFIG_MTD_NAND_CAFE is not set
 
 #
 # OneNAND Flash Device Drivers
@@ -557,6 +556,7 @@ CONFIG_MTD_ALCHEMY=y
 #
 # Plug and Play support
 #
+# CONFIG_PNPACPI is not set
 
 #
 # Block devices
@@ -715,6 +715,7 @@ CONFIG_MIPS_AU1X00_ENET=y
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
 CONFIG_QLA3XXX=m
+# CONFIG_ATL1 is not set
 
 #
 # Ethernet (10000 Mbit)
@@ -1145,6 +1146,7 @@ CONFIG_USB_MON=y
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
 # CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
 # CONFIG_USB_LED is not set
 # CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
@@ -1402,6 +1404,7 @@ CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_CROSSCOMPILE=y
 CONFIG_CMDLINE=""
+CONFIG_SYS_SUPPORTS_KGDB=y
 
 #
 # Security options
index 5b18d5d..c29fdab 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.20
-# Sun Feb 18 21:27:42 2007
+# Tue Feb 20 21:47:27 2007
 #
 CONFIG_MIPS=y
 
@@ -562,6 +562,7 @@ CONFIG_MTD_NAND_AU1550=m
 #
 # Plug and Play support
 #
+# CONFIG_PNPACPI is not set
 
 #
 # Block devices
@@ -751,6 +752,7 @@ CONFIG_MIPS_AU1X00_ENET=y
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
 CONFIG_QLA3XXX=m
+# CONFIG_ATL1 is not set
 
 #
 # Ethernet (10000 Mbit)
@@ -1219,6 +1221,7 @@ CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_CROSSCOMPILE=y
 CONFIG_CMDLINE=""
+CONFIG_SYS_SUPPORTS_KGDB=y
 
 #
 # Security options
index 1210188..f4b316d 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.20
-# Sun Feb 18 21:27:43 2007
+# Tue Feb 20 21:47:28 2007
 #
 CONFIG_MIPS=y
 
@@ -386,6 +386,7 @@ CONFIG_PROC_EVENTS=y
 #
 # Plug and Play support
 #
+# CONFIG_PNPACPI is not set
 
 #
 # Block devices
@@ -925,6 +926,7 @@ CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_CROSSCOMPILE=y
 CONFIG_CMDLINE="ip=any"
+CONFIG_SYS_SUPPORTS_KGDB=y
 
 #
 # Security options
index 2d71745..9c38e5c 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.20
-# Sun Feb 18 21:27:44 2007
+# Tue Feb 20 21:47:28 2007
 #
 CONFIG_MIPS=y
 
@@ -398,6 +398,7 @@ CONFIG_CONNECTOR=m
 #
 # Plug and Play support
 #
+# CONFIG_PNPACPI is not set
 
 #
 # Block devices
index 0ee2fbb..922af37 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.20
-# Sun Feb 18 21:27:44 2007
+# Tue Feb 20 21:47:28 2007
 #
 CONFIG_MIPS=y
 
@@ -294,6 +294,7 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
 # Plug and Play support
 #
 # CONFIG_PNP is not set
+# CONFIG_PNPACPI is not set
 
 #
 # Block devices
index 218fe6e..c0db8f1 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.20
-# Sun Feb 18 21:27:46 2007
+# Tue Feb 20 21:47:29 2007
 #
 CONFIG_MIPS=y
 
@@ -611,7 +611,6 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=2
 # NAND Flash Device Drivers
 #
 # CONFIG_MTD_NAND is not set
-# CONFIG_MTD_NAND_CAFE is not set
 
 #
 # OneNAND Flash Device Drivers
@@ -626,6 +625,7 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=2
 #
 # Plug and Play support
 #
+# CONFIG_PNPACPI is not set
 
 #
 # Block devices
@@ -1039,6 +1039,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_ADM1021 is not set
 # CONFIG_SENSORS_ADM1025 is not set
 # CONFIG_SENSORS_ADM1026 is not set
+# CONFIG_SENSORS_ADM1029 is not set
 # CONFIG_SENSORS_ADM1031 is not set
 # CONFIG_SENSORS_ADM9240 is not set
 # CONFIG_SENSORS_ASB100 is not set
index 5ad4870..ce088b3 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.20
-# Sun Feb 18 21:27:46 2007
+# Tue Feb 20 21:47:30 2007
 #
 CONFIG_MIPS=y
 
@@ -391,6 +391,7 @@ CONFIG_CONNECTOR=m
 #
 # Plug and Play support
 #
+# CONFIG_PNPACPI is not set
 
 #
 # Block devices
@@ -520,6 +521,7 @@ CONFIG_NET_ETHERNET=y
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
 CONFIG_QLA3XXX=m
+# CONFIG_ATL1 is not set
 
 #
 # Ethernet (10000 Mbit)
@@ -914,6 +916,7 @@ CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_CROSSCOMPILE=y
 CONFIG_CMDLINE="console=ttyS0,115200 root=/dev/nfs rw nfsroot=192.168.1.1:/mnt/disk2/fs.gal ip=192.168.1.211:192.168.1.1:::gt::"
+CONFIG_SYS_SUPPORTS_KGDB=y
 
 #
 # Security options
index 5e179fe..82f204d 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.20
-# Sun Feb 18 21:27:47 2007
+# Tue Feb 20 21:47:31 2007
 #
 CONFIG_MIPS=y
 
@@ -451,6 +451,7 @@ CONFIG_MTD_NAND_VERIFY_WRITE=y
 # CONFIG_MTD_NAND_ECC_SMC is not set
 CONFIG_MTD_NAND_IDS=y
 # CONFIG_MTD_NAND_DISKONCHIP is not set
+# CONFIG_MTD_NAND_BASLER_EXCITE is not set
 # CONFIG_MTD_NAND_CAFE is not set
 # CONFIG_MTD_NAND_NANDSIM is not set
 
@@ -467,6 +468,7 @@ CONFIG_MTD_NAND_IDS=y
 #
 # Plug and Play support
 #
+# CONFIG_PNPACPI is not set
 
 #
 # Block devices
@@ -638,6 +640,7 @@ CONFIG_NETDEVICES=y
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
 CONFIG_QLA3XXX=m
+# CONFIG_ATL1 is not set
 
 #
 # Ethernet (10000 Mbit)
@@ -1008,6 +1011,7 @@ CONFIG_USB_HID=m
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
 # CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
 # CONFIG_USB_LED is not set
 # CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
@@ -1277,6 +1281,7 @@ CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_CROSSCOMPILE=y
 CONFIG_CMDLINE=""
+CONFIG_SYS_SUPPORTS_KGDB=y
 
 #
 # Security options
index 864de21..cb81f13 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.20
-# Sun Feb 18 21:27:48 2007
+# Tue Feb 20 21:47:32 2007
 #
 CONFIG_MIPS=y
 
@@ -620,6 +620,7 @@ CONFIG_CONNECTOR=m
 #
 # Plug and Play support
 #
+# CONFIG_PNPACPI is not set
 
 #
 # Block devices
index 7b2f5f8..46f6ac4 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.20
-# Sun Feb 18 21:27:49 2007
+# Tue Feb 20 21:47:32 2007
 #
 CONFIG_MIPS=y
 
@@ -456,6 +456,7 @@ CONFIG_CONNECTOR=m
 #
 # Plug and Play support
 #
+# CONFIG_PNPACPI is not set
 
 #
 # Block devices
@@ -672,6 +673,7 @@ CONFIG_SGI_IOC3_ETH=y
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
 CONFIG_QLA3XXX=m
+# CONFIG_ATL1 is not set
 
 #
 # Ethernet (10000 Mbit)
@@ -1060,6 +1062,7 @@ CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_LOG_BUF_SHIFT=15
 CONFIG_CROSSCOMPILE=y
 CONFIG_CMDLINE=""
+CONFIG_SYS_SUPPORTS_KGDB=y
 
 #
 # Security options
index 14398e8..d9e5000 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.20
-# Sun Feb 18 21:27:50 2007
+# Tue Feb 20 21:47:33 2007
 #
 CONFIG_MIPS=y
 
@@ -396,6 +396,7 @@ CONFIG_PROC_EVENTS=y
 #
 # Plug and Play support
 #
+# CONFIG_PNPACPI is not set
 
 #
 # Block devices
@@ -600,6 +601,7 @@ CONFIG_SGI_O2MACE_ETH=y
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
 CONFIG_QLA3XXX=y
+# CONFIG_ATL1 is not set
 
 #
 # Ethernet (10000 Mbit)
index b389787..57ef0c4 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.20
-# Sun Feb 18 21:27:51 2007
+# Tue Feb 20 21:47:33 2007
 #
 CONFIG_MIPS=y
 
@@ -375,6 +375,7 @@ CONFIG_CONNECTOR=m
 #
 # Plug and Play support
 #
+# CONFIG_PNPACPI is not set
 
 #
 # Block devices
@@ -518,9 +519,6 @@ CONFIG_EEPRO100=y
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
 CONFIG_MV643XX_ETH=y
-CONFIG_MV643XX_ETH_0=y
-CONFIG_MV643XX_ETH_1=y
-CONFIG_MV643XX_ETH_2=y
 CONFIG_QLA3XXX=m
 
 #
@@ -833,6 +831,7 @@ CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_CROSSCOMPILE=y
 CONFIG_CMDLINE=""
+CONFIG_SYS_SUPPORTS_KGDB=y
 
 #
 # Security options
index dacf0a6..21d979f 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.20
-# Sun Feb 18 21:27:52 2007
+# Tue Feb 20 21:47:33 2007
 #
 CONFIG_MIPS=y
 
@@ -646,6 +646,7 @@ CONFIG_PARPORT_1284=y
 # Plug and Play support
 #
 # CONFIG_PNP is not set
+# CONFIG_PNPACPI is not set
 
 #
 # Block devices
index 29ed772..9ebb522 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.20
-# Sun Feb 18 21:27:53 2007
+# Tue Feb 20 21:47:34 2007
 #
 CONFIG_MIPS=y
 
@@ -384,6 +384,7 @@ CONFIG_PROC_EVENTS=y
 #
 # Plug and Play support
 #
+# CONFIG_PNPACPI is not set
 
 #
 # Block devices
@@ -513,6 +514,7 @@ CONFIG_NET_ETHERNET=y
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
 CONFIG_QLA3XXX=y
+# CONFIG_ATL1 is not set
 
 #
 # Ethernet (10000 Mbit)
index a1437b3..b3f767f 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.20
-# Sun Feb 18 21:27:54 2007
+# Tue Feb 20 21:47:34 2007
 #
 CONFIG_MIPS=y
 
@@ -454,7 +454,6 @@ CONFIG_MTD_LASAT=y
 # NAND Flash Device Drivers
 #
 # CONFIG_MTD_NAND is not set
-# CONFIG_MTD_NAND_CAFE is not set
 
 #
 # OneNAND Flash Device Drivers
@@ -469,6 +468,7 @@ CONFIG_MTD_LASAT=y
 #
 # Plug and Play support
 #
+# CONFIG_PNPACPI is not set
 
 #
 # Block devices
@@ -654,6 +654,7 @@ CONFIG_NET_ETHERNET=y
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
 CONFIG_QLA3XXX=m
+# CONFIG_ATL1 is not set
 
 #
 # Ethernet (10000 Mbit)
index 8d21bb9..a5f379d 100644 (file)
@@ -145,6 +145,7 @@ CONFIG_SYS_SUPPORTS_MULTITHREADING=y
 CONFIG_MIPS_MT_FPAFF=y
 # CONFIG_64BIT_PHYS_ADDR is not set
 CONFIG_CPU_HAS_LLSC=y
+# CONFIG_CPU_HAS_SMARTMIPS is not set
 CONFIG_CPU_MIPSR2_IRQ_VI=y
 CONFIG_CPU_MIPSR2_SRS=y
 CONFIG_CPU_HAS_SYNC=y
@@ -152,6 +153,7 @@ CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_IRQ_PER_CPU=y
 CONFIG_CPU_SUPPORTS_HIGHMEM=y
+CONFIG_SYS_SUPPORTS_SMARTMIPS=y
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_SELECT_MEMORY_MODEL=y
 CONFIG_FLATMEM_MANUAL=y
index 2acb99b..5ff53e1 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.20
-# Sun Feb 18 21:27:56 2007
+# Tue Feb 20 21:47:35 2007
 #
 CONFIG_MIPS=y
 
@@ -436,6 +436,7 @@ CONFIG_FIB_RULES=y
 #
 # Plug and Play support
 #
+# CONFIG_PNPACPI is not set
 
 #
 # Block devices
@@ -878,7 +879,6 @@ CONFIG_FORCED_INLINING=y
 CONFIG_CROSSCOMPILE=y
 CONFIG_CMDLINE="nfsroot=192.168.192.169:/u1/mipsel,timeo=20 ip=dhcp"
 # CONFIG_DEBUG_STACK_USAGE is not set
-# CONFIG_KGDB is not set
 # CONFIG_RUNTIME_DEBUG is not set
 # CONFIG_MIPS_UNCACHED is not set
 
index d52a5a4..750e644 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.20
-# Sun Feb 18 21:27:56 2007
+# Tue Feb 20 21:47:35 2007
 #
 CONFIG_MIPS=y
 
@@ -405,6 +405,7 @@ CONFIG_CONNECTOR=m
 #
 # Plug and Play support
 #
+# CONFIG_PNPACPI is not set
 
 #
 # Block devices
@@ -531,6 +532,7 @@ CONFIG_MII=m
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
 CONFIG_QLA3XXX=m
+# CONFIG_ATL1 is not set
 
 #
 # Ethernet (10000 Mbit)
@@ -883,6 +885,7 @@ CONFIG_USB_PEGASUS=m
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
 # CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
 # CONFIG_USB_LED is not set
 # CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
index 746106b..2febd0a 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.20
-# Sun Feb 18 21:27:58 2007
+# Tue Feb 20 21:47:35 2007
 #
 CONFIG_MIPS=y
 
@@ -496,6 +496,7 @@ CONFIG_CONNECTOR=m
 #
 # Plug and Play support
 #
+# CONFIG_PNPACPI is not set
 
 #
 # Block devices
@@ -713,9 +714,6 @@ CONFIG_E100=y
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
 CONFIG_MV643XX_ETH=y
-CONFIG_MV643XX_ETH_0=y
-CONFIG_MV643XX_ETH_1=y
-CONFIG_MV643XX_ETH_2=y
 CONFIG_QLA3XXX=m
 # CONFIG_ATL1 is not set
 
index 4b32b27..b8f4573 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.20
-# Sun Feb 18 21:27:58 2007
+# Tue Feb 20 21:47:36 2007
 #
 CONFIG_MIPS=y
 
@@ -393,6 +393,7 @@ CONFIG_PROC_EVENTS=y
 #
 # Plug and Play support
 #
+# CONFIG_PNPACPI is not set
 
 #
 # Block devices
@@ -523,6 +524,7 @@ CONFIG_NET_ETHERNET=y
 # CONFIG_BNX2 is not set
 # CONFIG_MV643XX_ETH is not set
 CONFIG_QLA3XXX=y
+# CONFIG_ATL1 is not set
 
 #
 # Ethernet (10000 Mbit)
index 674631b..8ade072 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.20
-# Sun Feb 18 21:27:59 2007
+# Tue Feb 20 21:47:36 2007
 #
 CONFIG_MIPS=y
 
@@ -390,6 +390,7 @@ CONFIG_PROC_EVENTS=y
 #
 # Plug and Play support
 #
+# CONFIG_PNPACPI is not set
 
 #
 # Block devices
@@ -854,6 +855,7 @@ CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_CROSSCOMPILE=y
 CONFIG_CMDLINE=""
+CONFIG_SYS_SUPPORTS_KGDB=y
 
 #
 # Security options
index 2600263..d20a221 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.20
-# Sun Feb 18 21:28:00 2007
+# Tue Feb 20 21:47:36 2007
 #
 CONFIG_MIPS=y
 
@@ -392,6 +392,7 @@ CONFIG_PROC_EVENTS=y
 #
 # Plug and Play support
 #
+# CONFIG_PNPACPI is not set
 
 #
 # Block devices
@@ -522,6 +523,7 @@ CONFIG_GALILEO_64240_ETH=y
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
 CONFIG_QLA3XXX=y
+# CONFIG_ATL1 is not set
 
 #
 # Ethernet (10000 Mbit)
index 05a33a2..33fcc81 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.20
-# Sun Feb 18 21:28:01 2007
+# Tue Feb 20 21:47:37 2007
 #
 CONFIG_MIPS=y
 
@@ -549,6 +549,7 @@ CONFIG_MTD_ALCHEMY=y
 #
 # Plug and Play support
 #
+# CONFIG_PNPACPI is not set
 
 #
 # Block devices
@@ -1096,6 +1097,7 @@ CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_CROSSCOMPILE=y
 CONFIG_CMDLINE=""
+CONFIG_SYS_SUPPORTS_KGDB=y
 
 #
 # Security options
index 34a6bee..e07c55d 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.20
-# Sun Feb 18 21:28:02 2007
+# Tue Feb 20 21:47:37 2007
 #
 CONFIG_MIPS=y
 
@@ -541,7 +541,6 @@ CONFIG_MTD_ALCHEMY=y
 # NAND Flash Device Drivers
 #
 # CONFIG_MTD_NAND is not set
-# CONFIG_MTD_NAND_CAFE is not set
 
 #
 # OneNAND Flash Device Drivers
@@ -556,6 +555,7 @@ CONFIG_MTD_ALCHEMY=y
 #
 # Plug and Play support
 #
+# CONFIG_PNPACPI is not set
 
 #
 # Block devices
@@ -745,6 +745,7 @@ CONFIG_MIPS_AU1X00_ENET=y
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
 CONFIG_QLA3XXX=m
+# CONFIG_ATL1 is not set
 
 #
 # Ethernet (10000 Mbit)
@@ -1213,6 +1214,7 @@ CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_CROSSCOMPILE=y
 CONFIG_CMDLINE=""
+CONFIG_SYS_SUPPORTS_KGDB=y
 
 #
 # Security options
index e3bff46..df210dd 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.20
-# Sun Feb 18 21:28:03 2007
+# Tue Feb 20 21:47:37 2007
 #
 CONFIG_MIPS=y
 
@@ -542,7 +542,6 @@ CONFIG_MTD_ALCHEMY=y
 # NAND Flash Device Drivers
 #
 # CONFIG_MTD_NAND is not set
-# CONFIG_MTD_NAND_CAFE is not set
 
 #
 # OneNAND Flash Device Drivers
@@ -557,6 +556,7 @@ CONFIG_MTD_ALCHEMY=y
 #
 # Plug and Play support
 #
+# CONFIG_PNPACPI is not set
 
 #
 # Block devices
@@ -746,6 +746,7 @@ CONFIG_MIPS_AU1X00_ENET=y
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
 CONFIG_QLA3XXX=m
+# CONFIG_ATL1 is not set
 
 #
 # Ethernet (10000 Mbit)
@@ -1206,6 +1207,7 @@ CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_CROSSCOMPILE=y
 CONFIG_CMDLINE=""
+CONFIG_SYS_SUPPORTS_KGDB=y
 
 #
 # Security options
index 009b3f8..106a164 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.20
-# Sun Feb 18 21:28:04 2007
+# Tue Feb 20 21:47:38 2007
 #
 CONFIG_MIPS=y
 
@@ -389,6 +389,7 @@ CONFIG_FW_LOADER=y
 #
 # Plug and Play support
 #
+# CONFIG_PNPACPI is not set
 
 #
 # Block devices
@@ -962,6 +963,7 @@ CONFIG_USB_MON=y
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
 # CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
 # CONFIG_USB_LED is not set
 # CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
@@ -1229,6 +1231,7 @@ CONFIG_CROSSCOMPILE=y
 CONFIG_CMDLINE="console=ttyS1,38400n8 kgdb=ttyS0 root=/dev/nfs ip=bootp"
 # CONFIG_DEBUG_STACK_USAGE is not set
 # CONFIG_KGDB is not set
+CONFIG_SYS_SUPPORTS_KGDB=y
 # CONFIG_RUNTIME_DEBUG is not set
 # CONFIG_MIPS_UNCACHED is not set
 
index 5bd377b..8caa2cd 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.20
-# Sun Feb 18 21:28:04 2007
+# Tue Feb 20 21:47:38 2007
 #
 CONFIG_MIPS=y
 
@@ -386,6 +386,7 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
 #
 # Plug and Play support
 #
+# CONFIG_PNPACPI is not set
 
 #
 # Block devices
@@ -952,6 +953,7 @@ CONFIG_USB_MON=y
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
 # CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
 # CONFIG_USB_LED is not set
 # CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
@@ -1219,6 +1221,7 @@ CONFIG_CROSSCOMPILE=y
 CONFIG_CMDLINE="console=ttyS1,38400n8 kgdb=ttyS0 root=/dev/nfs ip=bootp"
 # CONFIG_DEBUG_STACK_USAGE is not set
 # CONFIG_KGDB is not set
+CONFIG_SYS_SUPPORTS_KGDB=y
 # CONFIG_RUNTIME_DEBUG is not set
 # CONFIG_MIPS_UNCACHED is not set
 
index cc69470..43f1bec 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.20
-# Sun Feb 18 21:28:06 2007
+# Tue Feb 20 21:47:39 2007
 #
 CONFIG_MIPS=y
 
@@ -474,6 +474,7 @@ CONFIG_FW_LOADER=y
 #
 # Plug and Play support
 #
+# CONFIG_PNPACPI is not set
 
 #
 # Block devices
@@ -987,6 +988,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_ADM1021 is not set
 # CONFIG_SENSORS_ADM1025 is not set
 # CONFIG_SENSORS_ADM1026 is not set
+# CONFIG_SENSORS_ADM1029 is not set
 # CONFIG_SENSORS_ADM1031 is not set
 # CONFIG_SENSORS_ADM9240 is not set
 # CONFIG_SENSORS_ASB100 is not set
@@ -1209,6 +1211,7 @@ CONFIG_USB_MON=y
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
 # CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
 # CONFIG_USB_LED is not set
 # CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
@@ -1466,6 +1469,7 @@ CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_CROSSCOMPILE=y
 CONFIG_CMDLINE=""
+CONFIG_SYS_SUPPORTS_KGDB=y
 
 #
 # Security options
index c18c5e7..f68396d 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.20
-# Sun Feb 18 21:28:06 2007
+# Tue Feb 20 21:47:39 2007
 #
 CONFIG_MIPS=y
 
@@ -348,6 +348,7 @@ CONFIG_PROC_EVENTS=y
 # Plug and Play support
 #
 # CONFIG_PNP is not set
+# CONFIG_PNPACPI is not set
 
 #
 # Block devices
index 678f232..a6a824f 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.20
-# Sun Feb 18 21:28:07 2007
+# Tue Feb 20 21:47:39 2007
 #
 CONFIG_MIPS=y
 
@@ -560,7 +560,6 @@ CONFIG_MTD_CFI_UTIL=y
 # NAND Flash Device Drivers
 #
 # CONFIG_MTD_NAND is not set
-# CONFIG_MTD_NAND_CAFE is not set
 
 #
 # OneNAND Flash Device Drivers
@@ -576,6 +575,7 @@ CONFIG_MTD_CFI_UTIL=y
 # Plug and Play support
 #
 # CONFIG_PNP is not set
+# CONFIG_PNPACPI is not set
 
 #
 # Block devices
@@ -1191,6 +1191,7 @@ CONFIG_USB_MON=y
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
 # CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
 # CONFIG_USB_LED is not set
 # CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
@@ -1462,6 +1463,7 @@ CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_CROSSCOMPILE=y
 CONFIG_CMDLINE=""
+CONFIG_SYS_SUPPORTS_KGDB=y
 
 #
 # Security options
index 0417e86..bee3702 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.20
-# Sun Feb 18 21:28:09 2007
+# Tue Feb 20 21:47:40 2007
 #
 CONFIG_MIPS=y
 
@@ -661,6 +661,7 @@ CONFIG_PARPORT_NOT_PC=y
 # Plug and Play support
 #
 # CONFIG_PNP is not set
+# CONFIG_PNPACPI is not set
 
 #
 # Block devices
@@ -1397,6 +1398,7 @@ CONFIG_USB_AUERSWALD=m
 CONFIG_USB_RIO500=m
 CONFIG_USB_LEGOTOWER=m
 CONFIG_USB_LCD=m
+# CONFIG_USB_BERRY_CHARGE is not set
 CONFIG_USB_LED=m
 # CONFIG_USB_CYPRESS_CY7C63 is not set
 CONFIG_USB_CYTHERM=m
index 533df6f..3c891ed 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.20
-# Sun Feb 18 21:28:09 2007
+# Tue Feb 20 21:47:40 2007
 #
 CONFIG_MIPS=y
 
@@ -424,6 +424,7 @@ CONFIG_CONNECTOR=m
 #
 # Plug and Play support
 #
+# CONFIG_PNPACPI is not set
 
 #
 # Block devices
@@ -581,6 +582,7 @@ CONFIG_NET_SB1250_MAC=y
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
 CONFIG_QLA3XXX=m
+# CONFIG_ATL1 is not set
 
 #
 # Ethernet (10000 Mbit)
@@ -945,6 +947,7 @@ CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_LOG_BUF_SHIFT=15
 CONFIG_CROSSCOMPILE=y
 CONFIG_CMDLINE=""
+CONFIG_SYS_SUPPORTS_KGDB=y
 # CONFIG_SB1XXX_CORELIS is not set
 
 #
index 38816fe..e31d964 100644 (file)
@@ -129,10 +129,12 @@ CONFIG_MIPS_MT_DISABLED=y
 # CONFIG_MIPS_VPE_LOADER is not set
 # CONFIG_64BIT_PHYS_ADDR is not set
 CONFIG_CPU_HAS_LLSC=y
+# CONFIG_CPU_HAS_SMARTMIPS is not set
 CONFIG_CPU_HAS_SYNC=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_CPU_SUPPORTS_HIGHMEM=y
+CONFIG_SYS_SUPPORTS_SMARTMIPS=y
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_SELECT_MEMORY_MODEL=y
 CONFIG_FLATMEM_MANUAL=y
index c2f7c8c..5771c1a 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.20
-# Sun Feb 18 21:28:11 2007
+# Tue Feb 20 21:47:41 2007
 #
 CONFIG_MIPS=y
 
@@ -396,6 +396,7 @@ CONFIG_CONNECTOR=m
 #
 # Plug and Play support
 #
+# CONFIG_PNPACPI is not set
 
 #
 # Block devices
@@ -920,6 +921,7 @@ CONFIG_USB_STORAGE=y
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
 # CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
 # CONFIG_USB_LED is not set
 # CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
index 33b7880..a8eb4b1 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.20
-# Sun Feb 18 21:28:12 2007
+# Tue Feb 20 21:47:41 2007
 #
 CONFIG_MIPS=y
 
@@ -397,6 +397,7 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
 #
 # Plug and Play support
 #
+# CONFIG_PNPACPI is not set
 
 #
 # Block devices
@@ -530,6 +531,7 @@ CONFIG_R8169=y
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
 CONFIG_QLA3XXX=m
+# CONFIG_ATL1 is not set
 
 #
 # Ethernet (10000 Mbit)
@@ -819,6 +821,7 @@ CONFIG_USB_MON=y
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
 # CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
 # CONFIG_USB_LED is not set
 # CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
index d180586..69b8730 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.20
-# Sun Feb 18 21:28:13 2007
+# Tue Feb 20 21:47:41 2007
 #
 CONFIG_MIPS=y
 
@@ -409,6 +409,7 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
 #
 # Plug and Play support
 #
+# CONFIG_PNPACPI is not set
 
 #
 # Block devices
@@ -675,6 +676,7 @@ CONFIG_R8169=y
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
 # CONFIG_QLA3XXX is not set
+# CONFIG_ATL1 is not set
 
 #
 # Ethernet (10000 Mbit)
@@ -1016,6 +1018,7 @@ CONFIG_USB_MON=y
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
 # CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
 # CONFIG_USB_LED is not set
 # CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
index 570f0c1..2abbd68 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.20
-# Sun Feb 18 21:28:13 2007
+# Tue Feb 20 21:47:42 2007
 #
 CONFIG_MIPS=y
 
@@ -396,6 +396,7 @@ CONFIG_CONNECTOR=m
 # Plug and Play support
 #
 # CONFIG_PNP is not set
+# CONFIG_PNPACPI is not set
 
 #
 # Block devices
index 08f3190..44b6b7c 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.20
-# Sun Feb 18 21:28:14 2007
+# Tue Feb 20 21:47:42 2007
 #
 CONFIG_MIPS=y
 
@@ -400,6 +400,7 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
 #
 # Plug and Play support
 #
+# CONFIG_PNPACPI is not set
 
 #
 # Block devices
index aa69fee..f24e1c6 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.20
-# Sun Feb 18 21:28:15 2007
+# Tue Feb 20 21:47:42 2007
 #
 CONFIG_MIPS=y
 
@@ -381,6 +381,7 @@ CONFIG_CONNECTOR=m
 #
 # Plug and Play support
 #
+# CONFIG_PNPACPI is not set
 
 #
 # Block devices
@@ -841,6 +842,7 @@ CONFIG_CROSSCOMPILE=y
 CONFIG_CMDLINE=""
 # CONFIG_DEBUG_STACK_USAGE is not set
 # CONFIG_KGDB is not set
+CONFIG_SYS_SUPPORTS_KGDB=y
 # CONFIG_RUNTIME_DEBUG is not set
 
 #
index 6c2a233..8cb8f59 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.20
-# Sun Feb 18 21:27:34 2007
+# Tue Feb 20 21:47:14 2007
 #
 CONFIG_MIPS=y
 
@@ -620,6 +620,7 @@ CONFIG_CONNECTOR=m
 #
 # Plug and Play support
 #
+# CONFIG_PNPACPI is not set
 
 #
 # Block devices
index c0b089d..222de46 100644 (file)
@@ -64,6 +64,9 @@ void output_ptreg_defines(void)
        offset("#define PT_R31    ", struct pt_regs, regs[31]);
        offset("#define PT_LO     ", struct pt_regs, lo);
        offset("#define PT_HI     ", struct pt_regs, hi);
+#ifdef CONFIG_CPU_HAS_SMARTMIPS
+       offset("#define PT_ACX    ", struct pt_regs, acx);
+#endif
        offset("#define PT_EPC    ", struct pt_regs, cp0_epc);
        offset("#define PT_BVADDR ", struct pt_regs, cp0_badvaddr);
        offset("#define PT_STATUS ", struct pt_regs, cp0_status);
@@ -246,6 +249,7 @@ void output_sc_defines(void)
        text("/* Linux sigcontext offsets. */");
        offset("#define SC_REGS       ", struct sigcontext, sc_regs);
        offset("#define SC_FPREGS     ", struct sigcontext, sc_fpregs);
+       offset("#define SC_ACX        ", struct sigcontext, sc_acx);
        offset("#define SC_MDHI       ", struct sigcontext, sc_mdhi);
        offset("#define SC_MDLO       ", struct sigcontext, sc_mdlo);
        offset("#define SC_PC         ", struct sigcontext, sc_pc);
index 258d74f..201ae19 100644 (file)
@@ -236,6 +236,11 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
                case MMLO:
                        tmp = regs->lo;
                        break;
+#ifdef CONFIG_CPU_HAS_SMARTMIPS
+               case ACX:
+                       tmp = regs->acx;
+                       break;
+#endif
                case FPC_CSR:
                        tmp = child->thread.fpu.fcr31;
                        break;
@@ -362,6 +367,11 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
                case MMLO:
                        regs->lo = data;
                        break;
+#ifdef CONFIG_CPU_HAS_SMARTMIPS
+               case ACX:
+                       regs->acx = data;
+                       break;
+#endif
                case FPC_CSR:
                        child->thread.fpu.fcr31 = data;
                        break;
index adbfb95..f091786 100644 (file)
@@ -89,6 +89,9 @@ int setup_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc)
        for (i = 1; i < 32; i++)
                err |= __put_user(regs->regs[i], &sc->sc_regs[i]);
 
+#ifdef CONFIG_CPU_HAS_SMARTMIPS
+       err |= __put_user(regs->acx, &sc->sc_acx);
+#endif
        err |= __put_user(regs->hi, &sc->sc_mdhi);
        err |= __put_user(regs->lo, &sc->sc_mdlo);
        if (cpu_has_dsp) {
@@ -132,6 +135,10 @@ int restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc)
        current_thread_info()->restart_block.fn = do_no_restart_syscall;
 
        err |= __get_user(regs->cp0_epc, &sc->sc_pc);
+
+#ifdef CONFIG_CPU_HAS_SMARTMIPS
+       err |= __get_user(regs->acx, &sc->sc_acx);
+#endif
        err |= __get_user(regs->hi, &sc->sc_mdhi);
        err |= __get_user(regs->lo, &sc->sc_mdlo);
        if (cpu_has_dsp) {
index 0555fc5..c46e479 100644 (file)
@@ -51,31 +51,14 @@ int __cpu_logical_map[NR_CPUS];             /* Map logical to physical */
 EXPORT_SYMBOL(phys_cpu_present_map);
 EXPORT_SYMBOL(cpu_online_map);
 
+/* This happens early in bootup, can't really do it better */
 static void smp_tune_scheduling (void)
 {
        struct cache_desc *cd = &current_cpu_data.scache;
-       unsigned long cachesize;       /* kB   */
-       unsigned long cpu_khz;
+       unsigned long cachesize = cd->linesz * cd->sets * cd->ways;
 
-       /*
-        * Crude estimate until we actually meassure ...
-        */
-       cpu_khz = loops_per_jiffy * 2 * HZ / 1000;
-
-       /*
-        * Rough estimation for SMP scheduling, this is the number of
-        * cycles it takes for a fully memory-limited process to flush
-        * the SMP-local cache.
-        *
-        * (For a P5 this pretty much means we will choose another idle
-        *  CPU almost always at wakeup time (this is due to the small
-        *  L1 cache), on PIIs it's around 50-100 usecs, depending on
-        *  the cache size)
-        */
-       if (!cpu_khz)
-               return;
-
-       cachesize = cd->linesz * cd->sets * cd->ways;
+       if (cachesize > max_cache_size)
+               max_cache_size = cachesize;
 }
 
 extern void __init calibrate_delay(void);
index 2aa208b..18f56a9 100644 (file)
@@ -229,6 +229,9 @@ void show_regs(struct pt_regs *regs)
                        printk("\n");
        }
 
+#ifdef CONFIG_CPU_HAS_SMARTMIPS
+       printk("Acx    : %0*lx\n", field, regs->acx);
+#endif
        printk("Hi    : %0*lx\n", field, regs->hi);
        printk("Lo    : %0*lx\n", field, regs->lo);
 
index fc2c96f..cea7d0e 100644 (file)
@@ -6,13 +6,98 @@
  * (C) Copyright 1995 1996 Linus Torvalds
  * (C) Copyright 2001, 2002 Ralf Baechle
  */
-#include <linux/mm.h>
 #include <linux/module.h>
 #include <asm/addrspace.h>
 #include <asm/byteorder.h>
 
 #include <linux/vmalloc.h>
-#include <linux/io.h>
+#include <asm/cacheflush.h>
+#include <asm/io.h>
+#include <asm/tlbflush.h>
+
+static inline void remap_area_pte(pte_t * pte, unsigned long address,
+       phys_t size, phys_t phys_addr, unsigned long flags)
+{
+       phys_t end;
+       unsigned long pfn;
+       pgprot_t pgprot = __pgprot(_PAGE_GLOBAL | _PAGE_PRESENT | __READABLE
+                                  | __WRITEABLE | flags);
+
+       address &= ~PMD_MASK;
+       end = address + size;
+       if (end > PMD_SIZE)
+               end = PMD_SIZE;
+       if (address >= end)
+               BUG();
+       pfn = phys_addr >> PAGE_SHIFT;
+       do {
+               if (!pte_none(*pte)) {
+                       printk("remap_area_pte: page already exists\n");
+                       BUG();
+               }
+               set_pte(pte, pfn_pte(pfn, pgprot));
+               address += PAGE_SIZE;
+               pfn++;
+               pte++;
+       } while (address && (address < end));
+}
+
+static inline int remap_area_pmd(pmd_t * pmd, unsigned long address,
+       phys_t size, phys_t phys_addr, unsigned long flags)
+{
+       phys_t end;
+
+       address &= ~PGDIR_MASK;
+       end = address + size;
+       if (end > PGDIR_SIZE)
+               end = PGDIR_SIZE;
+       phys_addr -= address;
+       if (address >= end)
+               BUG();
+       do {
+               pte_t * pte = pte_alloc_kernel(pmd, address);
+               if (!pte)
+                       return -ENOMEM;
+               remap_area_pte(pte, address, end - address, address + phys_addr, flags);
+               address = (address + PMD_SIZE) & PMD_MASK;
+               pmd++;
+       } while (address && (address < end));
+       return 0;
+}
+
+static int remap_area_pages(unsigned long address, phys_t phys_addr,
+       phys_t size, unsigned long flags)
+{
+       int error;
+       pgd_t * dir;
+       unsigned long end = address + size;
+
+       phys_addr -= address;
+       dir = pgd_offset(&init_mm, address);
+       flush_cache_all();
+       if (address >= end)
+               BUG();
+       do {
+               pud_t *pud;
+               pmd_t *pmd;
+
+               error = -ENOMEM;
+               pud = pud_alloc(&init_mm, dir, address);
+               if (!pud)
+                       break;
+               pmd = pmd_alloc(&init_mm, pud, address);
+               if (!pmd)
+                       break;
+               if (remap_area_pmd(pmd, address, end - address,
+                                        phys_addr + address, flags))
+                       break;
+               error = 0;
+               address = (address + PGDIR_SIZE) & PGDIR_MASK;
+               dir++;
+       } while (address && (address < end));
+       flush_tlb_all();
+       return error;
+}
 
 /*
  * Generic mapping function (not visible outside):
@@ -36,7 +121,6 @@ void __iomem * __ioremap(phys_t phys_addr, phys_t size, unsigned long flags)
        unsigned long offset;
        phys_t last_addr;
        void * addr;
-       pgprot_t pgprot;
 
        phys_addr = fixup_bigphys_addr(phys_addr, size);
 
@@ -68,9 +152,6 @@ void __iomem * __ioremap(phys_t phys_addr, phys_t size, unsigned long flags)
                                return NULL;
        }
 
-       pgprot = __pgprot(_PAGE_GLOBAL | _PAGE_PRESENT | __READABLE
-                         | __WRITEABLE | flags);
-
        /*
         * Mappings have to be page-aligned
         */
@@ -85,8 +166,7 @@ void __iomem * __ioremap(phys_t phys_addr, phys_t size, unsigned long flags)
        if (!area)
                return NULL;
        addr = area->addr;
-       if (ioremap_page_range((unsigned long)addr, (unsigned long)addr + size,
-                              phys_addr, pgprot)) {
+       if (remap_area_pages((unsigned long) addr, phys_addr, size, flags)) {
                vunmap(addr);
                return NULL;
        }
index c78ba30..3df36ed 100644 (file)
@@ -200,7 +200,7 @@ static int __init mv643xx_eth_add_pds(void)
        int ret;
 
        get_mac(mac);
-       eth_mac_add(eth1_mac_addr, mac, 0);
+       eth_mac_add(eth0_mac_addr, mac, 0);
        eth_mac_add(eth1_mac_addr, mac, 1);
        eth_mac_add(eth2_mac_addr, mac, 2);
        ret = platform_add_devices(mv643xx_eth_pd_devs,
index 0ab8d23..024aef2 100644 (file)
@@ -200,7 +200,7 @@ static int __init mv643xx_eth_add_pds(void)
        int ret;
 
        get_mac(mac);
-       eth_mac_add(eth1_mac_addr, mac, 0);
+       eth_mac_add(eth0_mac_addr, mac, 0);
        eth_mac_add(eth1_mac_addr, mac, 1);
        eth_mac_add(eth2_mac_addr, mac, 2);
        ret = platform_add_devices(mv643xx_eth_pd_devs,
index 8e381d4..fac8b24 100644 (file)
@@ -174,7 +174,7 @@ static int __init mv643xx_eth_add_pds(void)
        int ret;
 
        get_mac(mac);
-       eth_mac_add(eth1_mac_addr, mac, 0);
+       eth_mac_add(eth0_mac_addr, mac, 0);
        eth_mac_add(eth1_mac_addr, mac, 1);
        ret = platform_add_devices(mv643xx_eth_pd_devs,
                        ARRAY_SIZE(mv643xx_eth_pd_devs));
index 0f44a6a..59eef40 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.20
-# Sun Feb 11 23:47:40 2007
+# Linux kernel version: 2.6.21-rc1
+# Mon Feb 26 10:45:21 2007
 #
 CONFIG_SPARC=y
 CONFIG_SPARC64=y
@@ -41,6 +41,7 @@ CONFIG_LOCALVERSION=""
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 # CONFIG_IPC_NS is not set
+CONFIG_SYSVIPC_SYSCTL=y
 CONFIG_POSIX_MQUEUE=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
@@ -322,6 +323,7 @@ CONFIG_CONNECTOR=m
 #
 # Plug and Play support
 #
+# CONFIG_PNPACPI is not set
 
 #
 # Block devices
@@ -787,6 +789,7 @@ CONFIG_I2C_ALGOBIT=y
 # CONFIG_I2C_NFORCE2 is not set
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_PASEMI is not set
 # CONFIG_I2C_PROSAVAGE is not set
 # CONFIG_I2C_SAVAGE4 is not set
 # CONFIG_I2C_SIS5595 is not set
@@ -833,6 +836,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_ADM1021 is not set
 # CONFIG_SENSORS_ADM1025 is not set
 # CONFIG_SENSORS_ADM1026 is not set
+# CONFIG_SENSORS_ADM1029 is not set
 # CONFIG_SENSORS_ADM1031 is not set
 # CONFIG_SENSORS_ADM9240 is not set
 # CONFIG_SENSORS_ASB100 is not set
@@ -873,6 +877,11 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_W83627EHF is not set
 # CONFIG_HWMON_DEBUG_CHIP is not set
 
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_SM501 is not set
+
 #
 # Multimedia devices
 #
@@ -887,16 +896,22 @@ CONFIG_HWMON=y
 #
 # Graphics support
 #
-# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 CONFIG_FB=y
+# CONFIG_FIRMWARE_EDID is not set
 CONFIG_FB_DDC=y
 CONFIG_FB_CFB_FILLRECT=y
 CONFIG_FB_CFB_COPYAREA=y
 CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_SVGALIB is not set
 # CONFIG_FB_MACMODES is not set
 # CONFIG_FB_BACKLIGHT is not set
 CONFIG_FB_MODE_HELPERS=y
 CONFIG_FB_TILEBLITTING=y
+
+#
+# Frambuffer hardware drivers
+#
 # CONFIG_FB_CIRRUS is not set
 # CONFIG_FB_PM2 is not set
 # CONFIG_FB_ASILIANT is not set
@@ -908,9 +923,11 @@ CONFIG_FB_TILEBLITTING=y
 # CONFIG_FB_MATROX is not set
 CONFIG_FB_RADEON=y
 CONFIG_FB_RADEON_I2C=y
+# CONFIG_FB_RADEON_BACKLIGHT is not set
 # CONFIG_FB_RADEON_DEBUG is not set
 # CONFIG_FB_ATY128 is not set
 # CONFIG_FB_ATY is not set
+# CONFIG_FB_S3 is not set
 # CONFIG_FB_SAVAGE is not set
 # CONFIG_FB_SIS is not set
 # CONFIG_FB_NEOMAGIC is not set
@@ -947,7 +964,6 @@ CONFIG_LOGO=y
 # CONFIG_LOGO_LINUX_VGA16 is not set
 # CONFIG_LOGO_LINUX_CLUT224 is not set
 CONFIG_LOGO_SUN_CLUT224=y
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -1192,6 +1208,7 @@ CONFIG_USB_HIDDEV=y
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
 # CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
 # CONFIG_USB_LED is not set
 # CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
@@ -1445,9 +1462,11 @@ CONFIG_MAGIC_SYSRQ=y
 CONFIG_DEBUG_FS=y
 # CONFIG_HEADERS_CHECK is not set
 CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
 CONFIG_LOG_BUF_SHIFT=18
 CONFIG_DETECT_SOFTLOCKUP=y
 CONFIG_SCHEDSTATS=y
+# CONFIG_TIMER_STATS is not set
 # CONFIG_DEBUG_SLAB is not set
 # CONFIG_DEBUG_RT_MUTEXES is not set
 # CONFIG_RT_MUTEX_TESTER is not set
@@ -1465,6 +1484,7 @@ CONFIG_DEBUG_BUGVERBOSE=y
 CONFIG_FORCED_INLINING=y
 # CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_LKDTM is not set
+# CONFIG_FAULT_INJECTION is not set
 # CONFIG_DEBUG_STACK_USAGE is not set
 # CONFIG_DEBUG_DCFLUSH is not set
 # CONFIG_STACK_DEBUG is not set
index b5ff3ee..c443db1 100644 (file)
@@ -109,6 +109,7 @@ static unsigned char virt_irq_alloc(unsigned int real_irq)
        return ent;
 }
 
+#ifdef CONFIG_PCI_MSI
 static void virt_irq_free(unsigned int virt_irq)
 {
        unsigned int real_irq;
@@ -121,6 +122,7 @@ static void virt_irq_free(unsigned int virt_irq)
 
        __bucket(real_irq)->virt_irq = 0;
 }
+#endif
 
 static unsigned int virt_to_real_irq(unsigned char virt_irq)
 {
index 6b740eb..6fedfb9 100644 (file)
@@ -668,7 +668,7 @@ int arch_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc)
 
 void arch_teardown_msi_irq(unsigned int virt_irq)
 {
-       struct msi_desc *entry = get_irq_data(virt_irq);
+       struct msi_desc *entry = get_irq_msi(virt_irq);
        struct pci_dev *pdev = entry->dev;
        struct pcidev_cookie *pcp = pdev->sysdata;
        struct pci_pbm_info *pbm = pcp->pbm;
index 1417e5c..d596812 100644 (file)
@@ -840,48 +840,6 @@ void class_device_destroy(struct class *cls, dev_t devt)
                class_device_unregister(class_dev);
 }
 
-int class_device_rename(struct class_device *class_dev, char *new_name)
-{
-       int error = 0;
-       char *old_class_name = NULL, *new_class_name = NULL;
-
-       class_dev = class_device_get(class_dev);
-       if (!class_dev)
-               return -EINVAL;
-
-       pr_debug("CLASS: renaming '%s' to '%s'\n", class_dev->class_id,
-                new_name);
-
-#ifdef CONFIG_SYSFS_DEPRECATED
-       if (class_dev->dev)
-               old_class_name = make_class_name(class_dev->class->name,
-                                                &class_dev->kobj);
-#endif
-
-       strlcpy(class_dev->class_id, new_name, KOBJ_NAME_LEN);
-
-       error = kobject_rename(&class_dev->kobj, new_name);
-
-#ifdef CONFIG_SYSFS_DEPRECATED
-       if (class_dev->dev) {
-               new_class_name = make_class_name(class_dev->class->name,
-                                                &class_dev->kobj);
-               if (new_class_name)
-                       sysfs_create_link(&class_dev->dev->kobj,
-                                         &class_dev->kobj, new_class_name);
-               if (old_class_name)
-                       sysfs_remove_link(&class_dev->dev->kobj,
-                                               old_class_name);
-       }
-#endif
-       class_device_put(class_dev);
-
-       kfree(old_class_name);
-       kfree(new_class_name);
-
-       return error;
-}
-
 struct class_device * class_device_get(struct class_device *class_dev)
 {
        if (class_dev)
index d04fd33..cf2a398 100644 (file)
@@ -637,12 +637,41 @@ int device_add(struct device *dev)
                                             BUS_NOTIFY_DEL_DEVICE, dev);
        device_remove_groups(dev);
  GroupError:
-       device_remove_attrs(dev);
+       device_remove_attrs(dev);
  AttrsError:
        if (dev->devt_attr) {
                device_remove_file(dev, dev->devt_attr);
                kfree(dev->devt_attr);
        }
+
+       if (dev->class) {
+               sysfs_remove_link(&dev->kobj, "subsystem");
+               /* If this is not a "fake" compatible device, remove the
+                * symlink from the class to the device. */
+               if (dev->kobj.parent != &dev->class->subsys.kset.kobj)
+                       sysfs_remove_link(&dev->class->subsys.kset.kobj,
+                                         dev->bus_id);
+#ifdef CONFIG_SYSFS_DEPRECATED
+               if (parent) {
+                       char *class_name = make_class_name(dev->class->name,
+                                                          &dev->kobj);
+                       if (class_name)
+                               sysfs_remove_link(&dev->parent->kobj,
+                                                 class_name);
+                       kfree(class_name);
+                       sysfs_remove_link(&dev->kobj, "device");
+               }
+#endif
+
+               down(&dev->class->sem);
+               /* notify any interfaces that the device is now gone */
+               list_for_each_entry(class_intf, &dev->class->interfaces, node)
+                       if (class_intf->remove_dev)
+                               class_intf->remove_dev(dev, class_intf);
+               /* remove the device from the class list */
+               list_del_init(&dev->node);
+               up(&dev->class->sem);
+       }
  ueventattrError:
        device_remove_file(dev, &dev->uevent_attr);
  attrError:
index a0d04a2..627f542 100644 (file)
@@ -1,7 +1,8 @@
 agpgart-y := backend.o frontend.o generic.o isoch.o
 
+agpgart-$(CONFIG_COMPAT)       += compat_ioctl.o
+
 obj-$(CONFIG_AGP)              += agpgart.o
-obj-$(CONFIG_COMPAT)           += compat_ioctl.o
 obj-$(CONFIG_AGP_ALI)          += ali-agp.o
 obj-$(CONFIG_AGP_ATI)          += ati-agp.o
 obj-$(CONFIG_AGP_AMD)          += amd-k7-agp.o
index 9bd68d9..fdbca25 100644 (file)
@@ -93,12 +93,12 @@ struct aper_size_info_fixed {
 
 struct agp_bridge_driver {
        struct module *owner;
-       void *aperture_sizes;
+       const void *aperture_sizes;
        int num_aperture_sizes;
        enum aper_size_type size_type;
        int cant_use_aperture;
        int needs_scratch_page;
-       struct gatt_mask *masks;
+       const struct gatt_mask *masks;
        int (*fetch_size)(void);
        int (*configure)(void);
        void (*agp_enable)(struct agp_bridge_data *, u32);
@@ -119,7 +119,7 @@ struct agp_bridge_driver {
 
 struct agp_bridge_data {
        const struct agp_version *version;
-       struct agp_bridge_driver *driver;
+       const struct agp_bridge_driver *driver;
        struct vm_operations_struct *vm_ops;
        void *previous_size;
        void *current_size;
@@ -290,7 +290,7 @@ void agp3_generic_cleanup(void);
 
 /* aperture sizes have been standardised since v3 */
 #define AGP_GENERIC_SIZES_ENTRIES 11
-extern struct aper_size_info_16 agp3_generic_sizes[];
+extern const struct aper_size_info_16 agp3_generic_sizes[];
 
 #define virt_to_gart(x) (phys_to_gart(virt_to_phys(x)))
 #define gart_to_virt(x) (phys_to_virt(gart_to_phys(x)))
index 98177a9..5b684fd 100644 (file)
@@ -182,7 +182,7 @@ static void m1541_destroy_page(void * addr)
 
 /* Setup function */
 
-static struct aper_size_info_32 ali_generic_sizes[7] =
+static const struct aper_size_info_32 ali_generic_sizes[7] =
 {
        {256, 65536, 6, 10},
        {128, 32768, 5, 9},
@@ -193,7 +193,7 @@ static struct aper_size_info_32 ali_generic_sizes[7] =
        {4, 1024, 0, 3}
 };
 
-static struct agp_bridge_driver ali_generic_bridge = {
+static const struct agp_bridge_driver ali_generic_bridge = {
        .owner                  = THIS_MODULE,
        .aperture_sizes         = ali_generic_sizes,
        .size_type              = U32_APER_SIZE,
@@ -217,7 +217,7 @@ static struct agp_bridge_driver ali_generic_bridge = {
        .agp_type_to_mask_type  = agp_generic_type_to_mask_type,
 };
 
-static struct agp_bridge_driver ali_m1541_bridge = {
+static const struct agp_bridge_driver ali_m1541_bridge = {
        .owner                  = THIS_MODULE,
        .aperture_sizes         = ali_generic_sizes,
        .size_type              = U32_APER_SIZE,
index 3d8d448..e6c534e 100644 (file)
@@ -344,7 +344,7 @@ static int amd_remove_memory(struct agp_memory *mem, off_t pg_start, int type)
        return 0;
 }
 
-static struct aper_size_info_lvl2 amd_irongate_sizes[7] =
+static const struct aper_size_info_lvl2 amd_irongate_sizes[7] =
 {
        {2048, 524288, 0x0000000c},
        {1024, 262144, 0x0000000a},
@@ -355,12 +355,12 @@ static struct aper_size_info_lvl2 amd_irongate_sizes[7] =
        {32, 8192, 0x00000000}
 };
 
-static struct gatt_mask amd_irongate_masks[] =
+static const struct gatt_mask amd_irongate_masks[] =
 {
        {.mask = 1, .type = 0}
 };
 
-static struct agp_bridge_driver amd_irongate_driver = {
+static const struct agp_bridge_driver amd_irongate_driver = {
        .owner                  = THIS_MODULE,
        .aperture_sizes         = amd_irongate_sizes,
        .size_type              = LVL2_APER_SIZE,
index 636d984..4857204 100644 (file)
@@ -192,7 +192,7 @@ static u64 amd64_configure (struct pci_dev *hammer, u64 gatt_table)
 }
 
 
-static struct aper_size_info_32 amd_8151_sizes[7] =
+static const struct aper_size_info_32 amd_8151_sizes[7] =
 {
        {2048, 524288, 9, 0x00000000 }, /* 0 0 0 0 0 0 */
        {1024, 262144, 8, 0x00000400 }, /* 1 0 0 0 0 0 */
@@ -232,7 +232,7 @@ static void amd64_cleanup(void)
 }
 
 
-static struct agp_bridge_driver amd_8151_driver = {
+static const struct agp_bridge_driver amd_8151_driver = {
        .owner                  = THIS_MODULE,
        .aperture_sizes         = amd_8151_sizes,
        .size_type              = U32_APER_SIZE,
index 77c9ad6..780e59e 100644 (file)
@@ -24,7 +24,7 @@
 #define ATI_GART_CACHE_ENTRY_CNTRL     0x10
 
 
-static struct aper_size_info_lvl2 ati_generic_sizes[7] =
+static const struct aper_size_info_lvl2 ati_generic_sizes[7] =
 {
        {2048, 524288, 0x0000000c},
        {1024, 262144, 0x0000000a},
@@ -410,7 +410,7 @@ static int ati_free_gatt_table(struct agp_bridge_data *bridge)
        return 0;
 }
 
-static struct agp_bridge_driver ati_generic_bridge = {
+static const struct agp_bridge_driver ati_generic_bridge = {
        .owner                  = THIS_MODULE,
        .aperture_sizes         = ati_generic_sizes,
        .size_type              = LVL2_APER_SIZE,
index 658cb1a..df8da72 100644 (file)
@@ -59,7 +59,7 @@ static struct _efficeon_private {
        unsigned long l1_table[EFFICEON_L1_SIZE];
 } efficeon_private;
 
-static struct gatt_mask efficeon_generic_masks[] =
+static const struct gatt_mask efficeon_generic_masks[] =
 {
        {.mask = 0x00000001, .type = 0}
 };
@@ -70,7 +70,7 @@ static inline unsigned long efficeon_mask_memory(unsigned long addr)
        return addr | 0x00000001;
 }
 
-static struct aper_size_info_lvl2 efficeon_generic_sizes[4] =
+static const struct aper_size_info_lvl2 efficeon_generic_sizes[4] =
 {
        {256, 65536, 0},
        {128, 32768, 32},
@@ -309,7 +309,7 @@ static int efficeon_remove_memory(struct agp_memory * mem, off_t pg_start, int t
 }
 
 
-static struct agp_bridge_driver efficeon_driver = {
+static const struct agp_bridge_driver efficeon_driver = {
        .owner                  = THIS_MODULE,
        .aperture_sizes         = efficeon_generic_sizes,
        .size_type              = LVL2_APER_SIZE,
index 7923337..f902d71 100644 (file)
@@ -1340,7 +1340,7 @@ void agp3_generic_cleanup(void)
 }
 EXPORT_SYMBOL(agp3_generic_cleanup);
 
-struct aper_size_info_16 agp3_generic_sizes[AGP_GENERIC_SIZES_ENTRIES] =
+const struct aper_size_info_16 agp3_generic_sizes[AGP_GENERIC_SIZES_ENTRIES] =
 {
        {4096, 1048576, 10,0x000},
        {2048,  524288, 9, 0x800},
index 847deab..79f7c01 100644 (file)
@@ -419,7 +419,7 @@ hp_zx1_enable (struct agp_bridge_data *bridge, u32 mode)
        agp_device_command(command, (mode & AGP8X_MODE) != 0);
 }
 
-struct agp_bridge_driver hp_zx1_driver = {
+struct const agp_bridge_driver hp_zx1_driver = {
        .owner                  = THIS_MODULE,
        .size_type              = FIXED_APER_SIZE,
        .configure              = hp_zx1_configure,
index 3e76186..1cde376 100644 (file)
@@ -78,7 +78,7 @@ static struct {
        } *lp_desc;
 } i460;
 
-static struct aper_size_info_8 i460_sizes[3] =
+static const struct aper_size_info_8 i460_sizes[3] =
 {
        /*
         * The 32GB aperture is only available with a 4M GART page size.  Due to the
@@ -550,7 +550,7 @@ static unsigned long i460_mask_memory (struct agp_bridge_data *bridge,
                | (((addr & ~((1 << I460_IO_PAGE_SHIFT) - 1)) & 0xfffff000) >> 12);
 }
 
-struct agp_bridge_driver intel_i460_driver = {
+struct const agp_bridge_driver intel_i460_driver = {
        .owner                  = THIS_MODULE,
        .aperture_sizes         = i460_sizes,
        .size_type              = U8_APER_SIZE,
index 06b0bb6..e542a62 100644 (file)
@@ -63,7 +63,7 @@ extern int agp_memory_reserved;
 #define INTEL_I7505_AGPCTRL    0x70
 #define INTEL_I7505_MCHCFG     0x50
 
-static struct aper_size_info_fixed intel_i810_sizes[] =
+static const struct aper_size_info_fixed intel_i810_sizes[] =
 {
        {64, 16384, 4},
        /* The 32M mode still requires a 64k gatt */
@@ -1365,18 +1365,18 @@ static int intel_7505_configure(void)
 }
 
 /* Setup function */
-static struct gatt_mask intel_generic_masks[] =
+static const struct gatt_mask intel_generic_masks[] =
 {
        {.mask = 0x00000017, .type = 0}
 };
 
-static struct aper_size_info_8 intel_815_sizes[2] =
+static const struct aper_size_info_8 intel_815_sizes[2] =
 {
        {64, 16384, 4, 0},
        {32, 8192, 3, 8},
 };
 
-static struct aper_size_info_8 intel_8xx_sizes[7] =
+static const struct aper_size_info_8 intel_8xx_sizes[7] =
 {
        {256, 65536, 6, 0},
        {128, 32768, 5, 32},
@@ -1387,7 +1387,7 @@ static struct aper_size_info_8 intel_8xx_sizes[7] =
        {4, 1024, 0, 63}
 };
 
-static struct aper_size_info_16 intel_generic_sizes[7] =
+static const struct aper_size_info_16 intel_generic_sizes[7] =
 {
        {256, 65536, 6, 0},
        {128, 32768, 5, 32},
@@ -1398,7 +1398,7 @@ static struct aper_size_info_16 intel_generic_sizes[7] =
        {4, 1024, 0, 63}
 };
 
-static struct aper_size_info_8 intel_830mp_sizes[4] =
+static const struct aper_size_info_8 intel_830mp_sizes[4] =
 {
        {256, 65536, 6, 0},
        {128, 32768, 5, 32},
@@ -1406,7 +1406,7 @@ static struct aper_size_info_8 intel_830mp_sizes[4] =
        {32, 8192, 3, 56}
 };
 
-static struct agp_bridge_driver intel_generic_driver = {
+static const struct agp_bridge_driver intel_generic_driver = {
        .owner                  = THIS_MODULE,
        .aperture_sizes         = intel_generic_sizes,
        .size_type              = U16_APER_SIZE,
@@ -1430,7 +1430,7 @@ static struct agp_bridge_driver intel_generic_driver = {
        .agp_type_to_mask_type  = agp_generic_type_to_mask_type,
 };
 
-static struct agp_bridge_driver intel_810_driver = {
+static const struct agp_bridge_driver intel_810_driver = {
        .owner                  = THIS_MODULE,
        .aperture_sizes         = intel_i810_sizes,
        .size_type              = FIXED_APER_SIZE,
@@ -1455,7 +1455,7 @@ static struct agp_bridge_driver intel_810_driver = {
        .agp_type_to_mask_type  = agp_generic_type_to_mask_type,
 };
 
-static struct agp_bridge_driver intel_815_driver = {
+static const struct agp_bridge_driver intel_815_driver = {
        .owner                  = THIS_MODULE,
        .aperture_sizes         = intel_815_sizes,
        .size_type              = U8_APER_SIZE,
@@ -1479,7 +1479,7 @@ static struct agp_bridge_driver intel_815_driver = {
        .agp_type_to_mask_type  = agp_generic_type_to_mask_type,
 };
 
-static struct agp_bridge_driver intel_830_driver = {
+static const struct agp_bridge_driver intel_830_driver = {
        .owner                  = THIS_MODULE,
        .aperture_sizes         = intel_i830_sizes,
        .size_type              = FIXED_APER_SIZE,
@@ -1504,7 +1504,7 @@ static struct agp_bridge_driver intel_830_driver = {
        .agp_type_to_mask_type  = intel_i830_type_to_mask_type,
 };
 
-static struct agp_bridge_driver intel_820_driver = {
+static const struct agp_bridge_driver intel_820_driver = {
        .owner                  = THIS_MODULE,
        .aperture_sizes         = intel_8xx_sizes,
        .size_type              = U8_APER_SIZE,
@@ -1528,7 +1528,7 @@ static struct agp_bridge_driver intel_820_driver = {
        .agp_type_to_mask_type  = agp_generic_type_to_mask_type,
 };
 
-static struct agp_bridge_driver intel_830mp_driver = {
+static const struct agp_bridge_driver intel_830mp_driver = {
        .owner                  = THIS_MODULE,
        .aperture_sizes         = intel_830mp_sizes,
        .size_type              = U8_APER_SIZE,
@@ -1552,7 +1552,7 @@ static struct agp_bridge_driver intel_830mp_driver = {
        .agp_type_to_mask_type  = agp_generic_type_to_mask_type,
 };
 
-static struct agp_bridge_driver intel_840_driver = {
+static const struct agp_bridge_driver intel_840_driver = {
        .owner                  = THIS_MODULE,
        .aperture_sizes         = intel_8xx_sizes,
        .size_type              = U8_APER_SIZE,
@@ -1576,7 +1576,7 @@ static struct agp_bridge_driver intel_840_driver = {
        .agp_type_to_mask_type  = agp_generic_type_to_mask_type,
 };
 
-static struct agp_bridge_driver intel_845_driver = {
+static const struct agp_bridge_driver intel_845_driver = {
        .owner                  = THIS_MODULE,
        .aperture_sizes         = intel_8xx_sizes,
        .size_type              = U8_APER_SIZE,
@@ -1600,7 +1600,7 @@ static struct agp_bridge_driver intel_845_driver = {
        .agp_type_to_mask_type  = agp_generic_type_to_mask_type,
 };
 
-static struct agp_bridge_driver intel_850_driver = {
+static const struct agp_bridge_driver intel_850_driver = {
        .owner                  = THIS_MODULE,
        .aperture_sizes         = intel_8xx_sizes,
        .size_type              = U8_APER_SIZE,
@@ -1624,7 +1624,7 @@ static struct agp_bridge_driver intel_850_driver = {
        .agp_type_to_mask_type  = agp_generic_type_to_mask_type,
 };
 
-static struct agp_bridge_driver intel_860_driver = {
+static const struct agp_bridge_driver intel_860_driver = {
        .owner                  = THIS_MODULE,
        .aperture_sizes         = intel_8xx_sizes,
        .size_type              = U8_APER_SIZE,
@@ -1648,7 +1648,7 @@ static struct agp_bridge_driver intel_860_driver = {
        .agp_type_to_mask_type  = agp_generic_type_to_mask_type,
 };
 
-static struct agp_bridge_driver intel_915_driver = {
+static const struct agp_bridge_driver intel_915_driver = {
        .owner                  = THIS_MODULE,
        .aperture_sizes         = intel_i830_sizes,
        .size_type              = FIXED_APER_SIZE,
@@ -1673,7 +1673,7 @@ static struct agp_bridge_driver intel_915_driver = {
        .agp_type_to_mask_type  = intel_i830_type_to_mask_type,
 };
 
-static struct agp_bridge_driver intel_i965_driver = {
+static const struct agp_bridge_driver intel_i965_driver = {
        .owner                  = THIS_MODULE,
        .aperture_sizes         = intel_i830_sizes,
        .size_type              = FIXED_APER_SIZE,
@@ -1698,7 +1698,7 @@ static struct agp_bridge_driver intel_i965_driver = {
        .agp_type_to_mask_type  = intel_i830_type_to_mask_type,
 };
 
-static struct agp_bridge_driver intel_7505_driver = {
+static const struct agp_bridge_driver intel_7505_driver = {
        .owner                  = THIS_MODULE,
        .aperture_sizes         = intel_8xx_sizes,
        .size_type              = U8_APER_SIZE,
index 2563286..0c9dab5 100644 (file)
@@ -272,7 +272,7 @@ static void nvidia_tlbflush(struct agp_memory *mem)
 }
 
 
-static struct aper_size_info_8 nvidia_generic_sizes[5] =
+static const struct aper_size_info_8 nvidia_generic_sizes[5] =
 {
        {512, 131072, 7, 0},
        {256, 65536, 6, 8},
@@ -283,13 +283,13 @@ static struct aper_size_info_8 nvidia_generic_sizes[5] =
 };
 
 
-static struct gatt_mask nvidia_generic_masks[] =
+static const struct gatt_mask nvidia_generic_masks[] =
 {
        { .mask = 1, .type = 0}
 };
 
 
-static struct agp_bridge_driver nvidia_driver = {
+static const struct agp_bridge_driver nvidia_driver = {
        .owner                  = THIS_MODULE,
        .aperture_sizes         = nvidia_generic_sizes,
        .size_type              = U8_APER_SIZE,
index b7b4590..36d07e3 100644 (file)
@@ -210,7 +210,7 @@ parisc_agp_enable(struct agp_bridge_data *bridge, u32 mode)
        agp_device_command(command, (mode & AGP8X_MODE) != 0);
 }
 
-struct agp_bridge_driver parisc_agp_driver = {
+struct const agp_bridge_driver parisc_agp_driver = {
        .owner                  = THIS_MODULE,
        .size_type              = FIXED_APER_SIZE,
        .configure              = parisc_agp_configure,
index 92d1dc4..e12773a 100644 (file)
@@ -247,7 +247,7 @@ static struct agp_bridge_data *sgi_tioca_find_bridge(struct pci_dev *pdev)
        return bridge;
 }
 
-struct agp_bridge_driver sgi_tioca_driver = {
+struct const agp_bridge_driver sgi_tioca_driver = {
        .owner = THIS_MODULE,
        .size_type = U16_APER_SIZE,
        .configure = sgi_tioca_configure,
index 60342b7..125f428 100644 (file)
@@ -108,7 +108,7 @@ static void sis_delayed_enable(struct agp_bridge_data *bridge, u32 mode)
        }
 }
 
-static struct aper_size_info_8 sis_generic_sizes[7] =
+static const struct aper_size_info_8 sis_generic_sizes[7] =
 {
        {256, 65536, 6, 99},
        {128, 32768, 5, 83},
index 9f5ae77..55212a3 100644 (file)
@@ -385,12 +385,12 @@ static int serverworks_remove_memory(struct agp_memory *mem, off_t pg_start,
        return 0;
 }
 
-static struct gatt_mask serverworks_masks[] =
+static const struct gatt_mask serverworks_masks[] =
 {
        {.mask = 1, .type = 0}
 };
 
-static struct aper_size_info_lvl2 serverworks_sizes[7] =
+static const struct aper_size_info_lvl2 serverworks_sizes[7] =
 {
        {2048, 524288, 0x80000000},
        {1024, 262144, 0xc0000000},
@@ -423,7 +423,7 @@ static void serverworks_agp_enable(struct agp_bridge_data *bridge, u32 mode)
        agp_device_command(command, 0);
 }
 
-static struct agp_bridge_driver sworks_driver = {
+static const struct agp_bridge_driver sworks_driver = {
        .owner                  = THIS_MODULE,
        .aperture_sizes         = serverworks_sizes,
        .size_type              = LVL2_APER_SIZE,
index 6c45702..292b4ad 100644 (file)
@@ -460,7 +460,7 @@ void null_cache_flush(void)
 
 /* Setup function */
 
-static struct aper_size_info_32 uninorth_sizes[7] =
+static const struct aper_size_info_32 uninorth_sizes[7] =
 {
 #if 0 /* Not sure uninorth supports that high aperture sizes */
        {256, 65536, 6, 64},
@@ -477,7 +477,7 @@ static struct aper_size_info_32 uninorth_sizes[7] =
  * Not sure that u3 supports that high aperture sizes but it
  * would strange if it did not :)
  */
-static struct aper_size_info_32 u3_sizes[8] =
+static const struct aper_size_info_32 u3_sizes[8] =
 {
        {512, 131072, 7, 128},
        {256, 65536, 6, 64},
@@ -489,7 +489,7 @@ static struct aper_size_info_32 u3_sizes[8] =
        {4, 1024, 0, 1}
 };
 
-struct agp_bridge_driver uninorth_agp_driver = {
+struct const agp_bridge_driver uninorth_agp_driver = {
        .owner                  = THIS_MODULE,
        .aperture_sizes         = (void *)uninorth_sizes,
        .size_type              = U32_APER_SIZE,
@@ -514,7 +514,7 @@ struct agp_bridge_driver uninorth_agp_driver = {
        .cant_use_aperture      = 1,
 };
 
-struct agp_bridge_driver u3_agp_driver = {
+struct const agp_bridge_driver u3_agp_driver = {
        .owner                  = THIS_MODULE,
        .aperture_sizes         = (void *)u3_sizes,
        .size_type              = U32_APER_SIZE,
index 2e7c043..a2bb4ec 100644 (file)
@@ -89,7 +89,7 @@ static void via_tlbflush(struct agp_memory *mem)
 }
 
 
-static struct aper_size_info_8 via_generic_sizes[9] =
+static const struct aper_size_info_8 via_generic_sizes[9] =
 {
        {256, 65536, 6, 0},
        {128, 32768, 5, 128},
@@ -170,7 +170,7 @@ static void via_tlbflush_agp3(struct agp_memory *mem)
 }
 
 
-static struct agp_bridge_driver via_agp3_driver = {
+static const struct agp_bridge_driver via_agp3_driver = {
        .owner                  = THIS_MODULE,
        .aperture_sizes         = agp3_generic_sizes,
        .size_type              = U8_APER_SIZE,
@@ -194,7 +194,7 @@ static struct agp_bridge_driver via_agp3_driver = {
        .agp_type_to_mask_type  = agp_generic_type_to_mask_type,
 };
 
-static struct agp_bridge_driver via_driver = {
+static const struct agp_bridge_driver via_driver = {
        .owner                  = THIS_MODULE,
        .aperture_sizes         = via_generic_sizes,
        .size_type              = U8_APER_SIZE,
index 7399ba7..80acd08 100644 (file)
@@ -82,6 +82,18 @@ config LEDS_WRAP
        help
          This option enables support for the PCEngines WRAP programmable LEDs.
 
+config LEDS_H1940
+       tristate "LED Support for iPAQ H1940 device"
+       depends LEDS_CLASS && ARCH_H1940
+       help
+         This option enables support for the LEDs on the h1940.
+
+config LEDS_COBALT
+       tristate "LED Support for Cobalt Server front LED"
+       depends on LEDS_CLASS && MIPS_COBALT
+       help
+         This option enables support for the front LED on Cobalt Server
+
 comment "LED Triggers"
 
 config LEDS_TRIGGERS
index 500de3d..aa2c18e 100644 (file)
@@ -14,6 +14,8 @@ obj-$(CONFIG_LEDS_S3C24XX)            += leds-s3c24xx.o
 obj-$(CONFIG_LEDS_AMS_DELTA)           += leds-ams-delta.o
 obj-$(CONFIG_LEDS_NET48XX)             += leds-net48xx.o
 obj-$(CONFIG_LEDS_WRAP)                        += leds-wrap.o
+obj-$(CONFIG_LEDS_H1940)               += leds-h1940.o
+obj-$(CONFIG_LEDS_COBALT)              += leds-cobalt.o
 
 # LED Triggers
 obj-$(CONFIG_LEDS_TRIGGER_TIMER)       += ledtrig-timer.o
diff --git a/drivers/leds/leds-cobalt.c b/drivers/leds/leds-cobalt.c
new file mode 100644 (file)
index 0000000..d16439c
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2006 - Florian Fainelli <florian@openwrt.org>
+ *
+ * Control the Cobalt Qube/RaQ front LED
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/leds.h>
+#include <asm/mach-cobalt/cobalt.h>
+
+static void cobalt_led_set(struct led_classdev *led_cdev, enum led_brightness brightness)
+{
+       if (brightness)
+               COBALT_LED_PORT = COBALT_LED_BAR_LEFT | COBALT_LED_BAR_RIGHT;
+       else
+               COBALT_LED_PORT = 0;
+}
+
+static struct led_classdev cobalt_led = {
+       .name = "cobalt-front-led",
+       .brightness_set = cobalt_led_set,
+       .default_trigger = "ide-disk",
+};
+
+static int __init cobalt_led_init(void)
+{
+       return led_classdev_register(NULL, &cobalt_led);
+}
+
+static void __exit cobalt_led_exit(void)
+{
+       led_classdev_unregister(&cobalt_led);
+}
+
+module_init(cobalt_led_init);
+module_exit(cobalt_led_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Front LED support for Cobalt Server");
+MODULE_AUTHOR("Florian Fainelli <florian@openwrt.org>");
diff --git a/drivers/leds/leds-h1940.c b/drivers/leds/leds-h1940.c
new file mode 100644 (file)
index 0000000..1d49d2a
--- /dev/null
@@ -0,0 +1,163 @@
+/*
+ * drivers/leds/h1940-leds.c
+ * Copyright (c) Arnaud Patard <arnaud.patard@rtp-net.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive for
+ * more details.
+ *
+ * H1940 leds driver
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/string.h>
+#include <linux/ctype.h>
+#include <linux/leds.h>
+#include <asm/arch/regs-gpio.h>
+#include <asm/hardware.h>
+#include <asm/arch/h1940-latch.h>
+
+/*
+ * Green led.
+ */
+void h1940_greenled_set(struct led_classdev *led_dev, enum led_brightness value)
+{
+       switch (value) {
+               case LED_HALF:
+                       h1940_latch_control(0,H1940_LATCH_LED_FLASH);
+                       s3c2410_gpio_setpin(S3C2410_GPA7,1);
+                       break;
+               case LED_FULL:
+                       h1940_latch_control(0,H1940_LATCH_LED_GREEN);
+                       s3c2410_gpio_setpin(S3C2410_GPA7,1);
+                       break;
+               default:
+               case LED_OFF:
+                       h1940_latch_control(H1940_LATCH_LED_FLASH,0);
+                       h1940_latch_control(H1940_LATCH_LED_GREEN,0);
+                       s3c2410_gpio_setpin(S3C2410_GPA7,0);
+                       break;
+       }
+}
+
+static struct led_classdev h1940_greenled = {
+       .name                   = "h1940:green",
+       .brightness_set         = h1940_greenled_set,
+       .default_trigger        = "h1940-charger",
+};
+
+/*
+ * Red led.
+ */
+void h1940_redled_set(struct led_classdev *led_dev, enum led_brightness value)
+{
+       switch (value) {
+               case LED_HALF:
+                       h1940_latch_control(0,H1940_LATCH_LED_FLASH);
+                       s3c2410_gpio_setpin(S3C2410_GPA1,1);
+                       break;
+               case LED_FULL:
+                       h1940_latch_control(0,H1940_LATCH_LED_RED);
+                       s3c2410_gpio_setpin(S3C2410_GPA1,1);
+                       break;
+               default:
+               case LED_OFF:
+                       h1940_latch_control(H1940_LATCH_LED_FLASH,0);
+                       h1940_latch_control(H1940_LATCH_LED_RED,0);
+                       s3c2410_gpio_setpin(S3C2410_GPA1,0);
+                       break;
+       }
+}
+
+static struct led_classdev h1940_redled = {
+       .name                   = "h1940:red",
+       .brightness_set         = h1940_redled_set,
+       .default_trigger        = "h1940-charger",
+};
+
+/*
+ * Blue led.
+ * (it can only be blue flashing led)
+ */
+void h1940_blueled_set(struct led_classdev *led_dev, enum led_brightness value)
+{
+       if (value) {
+               /* flashing Blue */
+               h1940_latch_control(0,H1940_LATCH_LED_FLASH);
+               s3c2410_gpio_setpin(S3C2410_GPA3,1);
+       } else {
+               h1940_latch_control(H1940_LATCH_LED_FLASH,0);
+               s3c2410_gpio_setpin(S3C2410_GPA3,0);
+       }
+
+}
+
+static struct led_classdev h1940_blueled = {
+       .name                   = "h1940:blue",
+       .brightness_set         = h1940_blueled_set,
+       .default_trigger        = "h1940-bluetooth",
+};
+
+static int __init h1940leds_probe(struct platform_device *pdev)
+{
+       int ret;
+
+       ret = led_classdev_register(&pdev->dev, &h1940_greenled);
+       if (ret)
+               goto err_green;
+
+       ret = led_classdev_register(&pdev->dev, &h1940_redled);
+       if (ret)
+               goto err_red;
+
+       ret = led_classdev_register(&pdev->dev, &h1940_blueled);
+       if (ret)
+               goto err_blue;
+
+       return 0;
+
+err_blue:
+       led_classdev_unregister(&h1940_redled);
+err_red:
+       led_classdev_unregister(&h1940_greenled);
+err_green:
+       return ret;
+}
+
+static int h1940leds_remove(struct platform_device *pdev)
+{
+       led_classdev_unregister(&h1940_greenled);
+       led_classdev_unregister(&h1940_redled);
+       led_classdev_unregister(&h1940_blueled);
+       return 0;
+}
+
+
+static struct platform_driver h1940leds_driver = {
+       .driver         = {
+               .name   = "h1940-leds",
+       },
+       .probe          = h1940leds_probe,
+       .remove         = h1940leds_remove,
+};
+
+
+static int __init h1940leds_init(void)
+{
+       return platform_driver_register(&h1940leds_driver);
+}
+
+static void __exit h1940leds_exit(void)
+{
+       platform_driver_unregister(&h1940leds_driver);
+}
+
+module_init(h1940leds_init);
+module_exit(h1940leds_exit);
+
+MODULE_AUTHOR("Arnaud Patard <arnaud.patard@rtp-net.org>");
+MODULE_DESCRIPTION("LED driver for the iPAQ H1940");
+MODULE_LICENSE("GPL");
index caca0dc..f2e810f 100644 (file)
@@ -907,7 +907,7 @@ static int __init init_hs(void)
 
        for (i=0; i<HS_MAX_SOCKETS; i++) {
                unsigned int ret;
-               hs_sockets[i].socket.dev.dev = &hd64465_device.dev;             
+               hs_sockets[i].socket.dev.parent = &hd64465_device.dev;
                hs_sockets[i].number = i;
                ret = pcmcia_register_socket(&hs_sockets[i].socket);
                if (ret && i)
index e4a9410..91da15b 100644 (file)
@@ -760,7 +760,7 @@ static int __init init_m32r_pcc(void)
        /* Set up interrupt handler(s) */
 
        for (i = 0 ; i < pcc_sockets ; i++) {
-               socket[i].socket.dev.dev = &pcc_device.dev;
+               socket[i].socket.dev.parent = &pcc_device.dev;
                socket[i].socket.ops = &pcc_operations;
                socket[i].socket.resource_ops = &pccard_nonstatic_ops;
                socket[i].socket.owner = THIS_MODULE;
index d059c91..9721ed7 100644 (file)
@@ -1321,7 +1321,7 @@ static int __init m8xx_init(void)
                socket[i].socket.ops = &m8xx_services;
                socket[i].socket.resource_ops = &pccard_iodyn_ops;
                socket[i].socket.cb_dev = NULL;
-               socket[i].socket.dev.dev = &m8xx_device.dev;
+               socket[i].socket.dev.parent = &m8xx_device.dev;
        }
 
        for (i = 0; i < PCMCIA_SOCKETS_NO; i++)
index 76f7cbc..d77f751 100644 (file)
@@ -291,7 +291,7 @@ static int __devinit omap_cf_probe(struct device *dev)
                omap_cf_present() ? "present" : "(not present)");
 
        cf->socket.owner = THIS_MODULE;
-       cf->socket.dev.dev = dev;
+       cf->socket.dev.parent = dev;
        cf->socket.ops = &omap_cf_ops;
        cf->socket.resource_ops = &pccard_static_ops;
        cf->socket.features = SS_CAP_PCCARD | SS_CAP_STATIC_MAP
index 81dfc2c..ce22262 100644 (file)
@@ -232,7 +232,7 @@ static struct resource *iodyn_find_io_region(unsigned long base, int num,
                unsigned long align, struct pcmcia_socket *s)
 {
        struct resource *res = make_resource(0, num, IORESOURCE_IO,
-                                            s->dev.class_id);
+                                            s->dev.bus_id);
        struct pcmcia_align_data data;
        unsigned long min = base;
        int ret;
index 206e26c..eee2f1c 100644 (file)
@@ -596,7 +596,7 @@ static int __devinit vrc4171_add_sockets(void)
                }
 
                sprintf(socket->name, "NEC VRC4171 Card Slot %1c", 'A' + slot);
-               socket->pcmcia_socket.dev.dev = &vrc4171_card_device.dev;
+               socket->pcmcia_socket.dev.parent = &vrc4171_card_device.dev;
                socket->pcmcia_socket.ops = &vrc4171_pccard_operations;
                socket->pcmcia_socket.owner = THIS_MODULE;
 
index 3a81529..35a7316 100644 (file)
@@ -46,13 +46,6 @@ config SUN_VIDEOPIX
          based on the Phillips SAA9051, can handle NTSC and PAL/SECAM and
          SVIDEO signals.
 
-config SUN_AURORA
-       tristate "Aurora Multiboard 1600se (EXPERIMENTAL)"
-       depends on EXPERIMENTAL && BROKEN
-       help
-         The Aurora Multiboard is a multi-port high-speed serial controller.
-         If you have one of these, say Y.
-
 config TADPOLE_TS102_UCTRL
        tristate "Tadpole TS102 Microcontroller support (EXPERIMENTAL)"
        depends on EXPERIMENTAL && SPARC32
index 3a5ea1d..7ab060e 100644 (file)
@@ -19,7 +19,6 @@ obj-$(CONFIG_SUN_OPENPROMIO)          += openprom.o
 obj-$(CONFIG_SUN_MOSTEK_RTC)           += rtc.o
 obj-$(CONFIG_SUN_BPP)                  += bpp.o
 obj-$(CONFIG_SUN_VIDEOPIX)             += vfc.o
-obj-$(CONFIG_SUN_AURORA)               += aurora.o
 obj-$(CONFIG_TADPOLE_TS102_UCTRL)      += uctrl.o
 obj-$(CONFIG_SUN_JSFLASH)              += jsflash.o
 obj-$(CONFIG_BBC_I2C)                  += bbc.o
diff --git a/drivers/sbus/char/aurora.c b/drivers/sbus/char/aurora.c
deleted file mode 100644 (file)
index a54b4ac..0000000
+++ /dev/null
@@ -1,2364 +0,0 @@
-/*     $Id: aurora.c,v 1.19 2002/01/08 16:00:16 davem Exp $
- *     linux/drivers/sbus/char/aurora.c -- Aurora multiport driver
- *
- *     Copyright (c) 1999 by Oliver Aldulea (oli at bv dot ro)
- *
- *     This code is based on the RISCom/8 multiport serial driver written
- *     by Dmitry Gorodchanin (pgmdsg@ibi.com), based on the Linux serial
- *     driver, written by Linus Torvalds, Theodore T'so and others.
- *     The Aurora multiport programming info was obtained mainly from the
- *     Cirrus Logic CD180 documentation (available on the web), and by
- *     doing heavy tests on the board. Many thanks to Eddie C. Dost for the
- *     help on the sbus interface.
- *
- *     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.
- *
- *     Revision 1.0
- *
- *     This is the first public release.
- *
- *     Most of the information you need is in the aurora.h file. Please
- *     read that file before reading this one.
- *
- *     Several parts of the code do not have comments yet.
- * 
- * n.b.  The board can support 115.2 bit rates, but only on a few
- * ports. The total badwidth of one chip (ports 0-7 or 8-15) is equal
- * to OSC_FREQ div 16. In case of my board, each chip can take 6
- * channels of 115.2 kbaud.  This information is not well-tested.
- * 
- * Fixed to use tty_get_baud_rate().
- *   Theodore Ts'o <tytso@mit.edu>, 2001-Oct-12
- */
-
-#include <linux/module.h>
-
-#include <linux/errno.h>
-#include <linux/sched.h>
-#ifdef AURORA_INT_DEBUG
-#include <linux/timer.h>
-#endif
-#include <linux/interrupt.h>
-#include <linux/tty.h>
-#include <linux/tty_flip.h>
-#include <linux/major.h>
-#include <linux/string.h>
-#include <linux/fcntl.h>
-#include <linux/mm.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/bitops.h>
-
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/oplib.h>
-#include <asm/system.h>
-#include <asm/kdebug.h>
-#include <asm/sbus.h>
-#include <asm/uaccess.h>
-
-#include "aurora.h"
-#include "cd180.h"
-
-unsigned char irqs[4] = {
-       0, 0, 0, 0
-};
-
-#ifdef AURORA_INT_DEBUG
-int irqhit=0;
-#endif
-
-static struct tty_driver *aurora_driver;
-static struct Aurora_board aurora_board[AURORA_NBOARD] = {
-       {0,},
-};
-
-static struct Aurora_port aurora_port[AURORA_TNPORTS] =  {
-       { 0, },
-};
-
-/* no longer used. static struct Aurora_board * IRQ_to_board[16] = { NULL, } ;*/
-static unsigned char * tmp_buf = NULL;
-
-DECLARE_TASK_QUEUE(tq_aurora);
-
-static inline int aurora_paranoia_check(struct Aurora_port const * port,
-                                   char *name, const char *routine)
-{
-#ifdef AURORA_PARANOIA_CHECK
-       static const char *badmagic =
-               KERN_DEBUG "aurora: Warning: bad aurora port magic number for device %s in %s\n";
-       static const char *badinfo =
-               KERN_DEBUG "aurora: Warning: null aurora port for device %s in %s\n";
-
-       if (!port) {
-               printk(badinfo, name, routine);
-               return 1;
-       }
-       if (port->magic != AURORA_MAGIC) {
-               printk(badmagic, name, routine);
-               return 1;
-       }
-#endif
-       return 0;
-}
-
-/*
- * 
- *  Service functions for aurora driver.
- * 
- */
-
-/* Get board number from pointer */
-static inline int board_No (struct Aurora_board const * bp)
-{
-       return bp - aurora_board;
-}
-
-/* Get port number from pointer */
-static inline int port_No (struct Aurora_port const * port)
-{
-       return AURORA_PORT(port - aurora_port); 
-}
-
-/* Get pointer to board from pointer to port */
-static inline struct Aurora_board * port_Board(struct Aurora_port const * port)
-{
-       return &aurora_board[AURORA_BOARD(port - aurora_port)];
-}
-
-/* Wait for Channel Command Register ready */
-static inline void aurora_wait_CCR(struct aurora_reg128 * r)
-{
-       unsigned long delay;
-
-#ifdef AURORA_DEBUG
-printk("aurora_wait_CCR\n");
-#endif
-       /* FIXME: need something more descriptive than 100000 :) */
-       for (delay = 100000; delay; delay--) 
-               if (!sbus_readb(&r->r[CD180_CCR]))
-                       return;
-       printk(KERN_DEBUG "aurora: Timeout waiting for CCR.\n");
-}
-
-/*
- *  aurora probe functions.
- */
-
-/* Must be called with enabled interrupts */
-static inline void aurora_long_delay(unsigned long delay)
-{
-       unsigned long i;
-
-#ifdef AURORA_DEBUG
-       printk("aurora_long_delay: start\n");
-#endif
-       for (i = jiffies + delay; time_before(jiffies, i); ) ;
-#ifdef AURORA_DEBUG
-       printk("aurora_long_delay: end\n");
-#endif
-}
-
-/* Reset and setup CD180 chip */
-static int aurora_init_CD180(struct Aurora_board * bp, int chip)
-{
-       unsigned long flags;
-       int id;
-       
-#ifdef AURORA_DEBUG
-       printk("aurora_init_CD180: start %d:%d\n",
-              board_No(bp), chip);
-#endif
-       save_flags(flags); cli();
-       sbus_writeb(0, &bp->r[chip]->r[CD180_CAR]);
-       sbus_writeb(0, &bp->r[chip]->r[CD180_GSVR]);
-
-       /* Wait for CCR ready        */
-       aurora_wait_CCR(bp->r[chip]);
-
-       /* Reset CD180 chip          */
-       sbus_writeb(CCR_HARDRESET, &bp->r[chip]->r[CD180_CCR]);
-       udelay(1);
-       sti();
-       id=1000;
-       while((--id) &&
-             (sbus_readb(&bp->r[chip]->r[CD180_GSVR])!=0xff))udelay(100);
-       if(!id) {
-               printk(KERN_ERR "aurora%d: Chip %d failed init.\n",
-                      board_No(bp), chip);
-               restore_flags(flags);
-               return(-1);
-       }
-       cli();
-       sbus_writeb((board_No(bp)<<5)|((chip+1)<<3),
-                   &bp->r[chip]->r[CD180_GSVR]); /* Set ID for this chip      */
-       sbus_writeb(0x80|bp->ACK_MINT,
-                   &bp->r[chip]->r[CD180_MSMR]); /* Prio for modem intr       */
-       sbus_writeb(0x80|bp->ACK_TINT,
-                   &bp->r[chip]->r[CD180_TSMR]); /* Prio for transmitter intr */
-       sbus_writeb(0x80|bp->ACK_RINT,
-                   &bp->r[chip]->r[CD180_RSMR]); /* Prio for receiver intr    */
-       /* Setting up prescaler. We need 4 tick per 1 ms */
-       sbus_writeb((bp->oscfreq/(1000000/AURORA_TPS)) >> 8,
-                   &bp->r[chip]->r[CD180_PPRH]);
-       sbus_writeb((bp->oscfreq/(1000000/AURORA_TPS)) & 0xff,
-                   &bp->r[chip]->r[CD180_PPRL]);
-
-       sbus_writeb(SRCR_AUTOPRI|SRCR_GLOBPRI,
-                   &bp->r[chip]->r[CD180_SRCR]);
-
-       id = sbus_readb(&bp->r[chip]->r[CD180_GFRCR]);
-       printk(KERN_INFO "aurora%d: Chip %d id %02x: ",
-              board_No(bp), chip,id);
-       if(sbus_readb(&bp->r[chip]->r[CD180_SRCR]) & 128) {
-               switch (id) {
-                       case 0x82:printk("CL-CD1864 rev A\n");break;
-                       case 0x83:printk("CL-CD1865 rev A\n");break;
-                       case 0x84:printk("CL-CD1865 rev B\n");break;
-                       case 0x85:printk("CL-CD1865 rev C\n");break;
-                       default:printk("Unknown.\n");
-               };
-       } else {
-               switch (id) {
-                       case 0x81:printk("CL-CD180 rev B\n");break;
-                       case 0x82:printk("CL-CD180 rev C\n");break;
-                       default:printk("Unknown.\n");
-               };
-       }
-       restore_flags(flags);
-#ifdef AURORA_DEBUG
-       printk("aurora_init_CD180: end\n");
-#endif
-       return 0;
-}
-
-static int valid_irq(unsigned char irq)
-{
-int i;
-for(i=0;i<TYPE_1_IRQS;i++)
-       if (type_1_irq[i]==irq) return 1;
-return 0;
-}
-
-static irqreturn_t aurora_interrupt(int irq, void * dev_id);
-
-/* Main probing routine, also sets irq. */
-static int aurora_probe(void)
-{
-       struct sbus_bus *sbus;
-       struct sbus_dev *sdev;
-       int grrr;
-       char buf[30];
-       int bn = 0;
-       struct Aurora_board *bp;
-
-       for_each_sbus(sbus) {
-               for_each_sbusdev(sdev, sbus) {
-/*                     printk("Try: %x %s\n",sdev,sdev->prom_name);*/
-                       if (!strcmp(sdev->prom_name, "sio16")) {
-#ifdef AURORA_DEBUG
-                               printk(KERN_INFO "aurora: sio16 at %p\n",sdev);
-#endif
-                               if((sdev->reg_addrs[0].reg_size!=1) &&
-                                  (sdev->reg_addrs[1].reg_size!=128) &&
-                                  (sdev->reg_addrs[2].reg_size!=128) &&
-                                  (sdev->reg_addrs[3].reg_size!=4)) {
-                                       printk(KERN_ERR "aurora%d: registers' sizes "
-                                              "do not match.\n", bn);
-                                       break;
-                               }
-                               bp = &aurora_board[bn];
-                               bp->r0 = (struct aurora_reg1 *)
-                                       sbus_ioremap(&sdev->resource[0], 0,
-                                                    sdev->reg_addrs[0].reg_size,
-                                                    "sio16");
-                               if (bp->r0 == NULL) {
-                                       printk(KERN_ERR "aurora%d: can't map "
-                                              "reg_addrs[0]\n", bn);
-                                       break;
-                               }
-#ifdef AURORA_DEBUG
-                               printk("Map reg 0: %p\n", bp->r0);
-#endif
-                               bp->r[0] = (struct aurora_reg128 *)
-                                       sbus_ioremap(&sdev->resource[1], 0,
-                                                    sdev->reg_addrs[1].reg_size,
-                                                    "sio16");
-                               if (bp->r[0] == NULL) {
-                                       printk(KERN_ERR "aurora%d: can't map "
-                                              "reg_addrs[1]\n", bn);
-                                       break;
-                               }
-#ifdef AURORA_DEBUG
-                               printk("Map reg 1: %p\n", bp->r[0]);
-#endif
-                               bp->r[1] = (struct aurora_reg128 *)
-                                       sbus_ioremap(&sdev->resource[2], 0,
-                                                    sdev->reg_addrs[2].reg_size,
-                                                    "sio16");
-                               if (bp->r[1] == NULL) {
-                                       printk(KERN_ERR "aurora%d: can't map "
-                                              "reg_addrs[2]\n", bn);
-                                       break;
-                               }
-#ifdef AURORA_DEBUG
-                               printk("Map reg 2: %p\n", bp->r[1]);
-#endif
-                               bp->r3 = (struct aurora_reg4 *)
-                                       sbus_ioremap(&sdev->resource[3], 0,
-                                                    sdev->reg_addrs[3].reg_size,
-                                                    "sio16");
-                               if (bp->r3 == NULL) {
-                                       printk(KERN_ERR "aurora%d: can't map "
-                                              "reg_addrs[3]\n", bn);
-                                       break;
-                               }
-#ifdef AURORA_DEBUG
-                               printk("Map reg 3: %p\n", bp->r3);
-#endif
-                               /* Variables setup */
-                               bp->flags = 0;
-#ifdef AURORA_DEBUG
-                               grrr=prom_getint(sdev->prom_node,"intr");
-                               printk("intr pri %d\n", grrr);
-#endif
-                               if ((bp->irq=irqs[bn]) && valid_irq(bp->irq) &&
-                                   !request_irq(bp->irq|0x30, aurora_interrupt, IRQF_SHARED, "sio16", bp)) {
-                                       free_irq(bp->irq|0x30, bp);
-                               } else
-                               if ((bp->irq=prom_getint(sdev->prom_node, "bintr")) && valid_irq(bp->irq) &&
-                                   !request_irq(bp->irq|0x30, aurora_interrupt, IRQF_SHARED, "sio16", bp)) {
-                                       free_irq(bp->irq|0x30, bp);
-                               } else
-                               if ((bp->irq=prom_getint(sdev->prom_node, "intr")) && valid_irq(bp->irq) &&
-                                   !request_irq(bp->irq|0x30, aurora_interrupt, IRQF_SHARED, "sio16", bp)) {
-                                       free_irq(bp->irq|0x30, bp);
-                               } else
-                               for(grrr=0;grrr<TYPE_1_IRQS;grrr++) {
-                                       if ((bp->irq=type_1_irq[grrr])&&!request_irq(bp->irq|0x30, aurora_interrupt, IRQF_SHARED, "sio16", bp)) {
-                                               free_irq(bp->irq|0x30, bp);
-                                               break;
-                                       } else {
-                                       printk(KERN_ERR "aurora%d: Could not get an irq for this board !!!\n",bn);
-                                       bp->flags=0xff;
-                                       }
-                               }
-                               if(bp->flags==0xff)break;
-                               printk(KERN_INFO "aurora%d: irq %d\n",bn,bp->irq&0x0f);
-                               buf[0]=0;
-                               grrr=prom_getproperty(sdev->prom_node,"dtr_rts",buf,sizeof(buf));
-                               if(!strcmp(buf,"swapped")){
-                                       printk(KERN_INFO "aurora%d: Swapped DTR and RTS\n",bn);
-                                       bp->DTR=MSVR_RTS;
-                                       bp->RTS=MSVR_DTR;
-                                       bp->MSVDTR=CD180_MSVRTS;
-                                       bp->MSVRTS=CD180_MSVDTR;
-                                       bp->flags|=AURORA_BOARD_DTR_FLOW_OK;
-                                       }else{
-                                       #ifdef AURORA_FORCE_DTR_FLOW
-                                       printk(KERN_INFO "aurora%d: Forcing swapped DTR-RTS\n",bn);
-                                       bp->DTR=MSVR_RTS;
-                                       bp->RTS=MSVR_DTR;
-                                       bp->MSVDTR=CD180_MSVRTS;
-                                       bp->MSVRTS=CD180_MSVDTR;
-                                       bp->flags|=AURORA_BOARD_DTR_FLOW_OK;
-                                       #else
-                                       printk(KERN_INFO "aurora%d: Normal DTR and RTS\n",bn);
-                                       bp->DTR=MSVR_DTR;
-                                       bp->RTS=MSVR_RTS;
-                                       bp->MSVDTR=CD180_MSVDTR;
-                                       bp->MSVRTS=CD180_MSVRTS;
-                                       #endif
-                               }
-                               bp->oscfreq=prom_getint(sdev->prom_node,"clk")*100;
-                               printk(KERN_INFO "aurora%d: Oscillator: %d Hz\n",bn,bp->oscfreq);
-                               grrr=prom_getproperty(sdev->prom_node,"chip",buf,sizeof(buf));
-                               printk(KERN_INFO "aurora%d: Chips: %s\n",bn,buf);
-                               grrr=prom_getproperty(sdev->prom_node,"manu",buf,sizeof(buf));
-                               printk(KERN_INFO "aurora%d: Manufacturer: %s\n",bn,buf);
-                               grrr=prom_getproperty(sdev->prom_node,"model",buf,sizeof(buf));
-                               printk(KERN_INFO "aurora%d: Model: %s\n",bn,buf);
-                               grrr=prom_getproperty(sdev->prom_node,"rev",buf,sizeof(buf));
-                               printk(KERN_INFO "aurora%d: Revision: %s\n",bn,buf);
-                               grrr=prom_getproperty(sdev->prom_node,"mode",buf,sizeof(buf));
-                               printk(KERN_INFO "aurora%d: Mode: %s\n",bn,buf);
-                               #ifdef MODULE
-                               bp->count=0;
-                               #endif
-                               bp->flags = AURORA_BOARD_PRESENT;
-                               /* hardware ack */
-                               bp->ACK_MINT=1;
-                               bp->ACK_TINT=2;
-                               bp->ACK_RINT=3;
-                               bn++;
-                       }
-               }
-       }
-       return bn;
-}
-
-static void aurora_release_io_range(struct Aurora_board *bp)
-{
-       sbus_iounmap((unsigned long)bp->r0, 1);
-       sbus_iounmap((unsigned long)bp->r[0], 128);
-       sbus_iounmap((unsigned long)bp->r[1], 128);
-       sbus_iounmap((unsigned long)bp->r3, 4);
-}
-
-static inline void aurora_mark_event(struct Aurora_port * port, int event)
-{
-#ifdef AURORA_DEBUG
-       printk("aurora_mark_event: start\n");
-#endif
-       set_bit(event, &port->event);
-       queue_task(&port->tqueue, &tq_aurora);
-       mark_bh(AURORA_BH);
-#ifdef AURORA_DEBUG
-       printk("aurora_mark_event: end\n");
-#endif
-}
-
-static __inline__ struct Aurora_port * aurora_get_port(struct Aurora_board const * bp,
-                                                      int chip,
-                                                      unsigned char const *what)
-{
-       unsigned char channel;
-       struct Aurora_port * port;
-
-       channel = ((chip << 3) |
-                  ((sbus_readb(&bp->r[chip]->r[CD180_GSCR]) & GSCR_CHAN) >> GSCR_CHAN_OFF));
-       port = &aurora_port[board_No(bp) * AURORA_NPORT * AURORA_NCD180 + channel];
-       if (port->flags & ASYNC_INITIALIZED)
-               return port;
-
-       printk(KERN_DEBUG "aurora%d: %s interrupt from invalid port %d\n",
-              board_No(bp), what, channel);
-       return NULL;
-}
-
-static void aurora_receive_exc(struct Aurora_board const * bp, int chip)
-{
-       struct Aurora_port *port;
-       struct tty_struct *tty;
-       unsigned char status;
-       unsigned char ch;
-       
-       if (!(port = aurora_get_port(bp, chip, "Receive_x")))
-               return;
-
-       tty = port->tty;
-       if (tty->flip.count >= TTY_FLIPBUF_SIZE)  {
-#ifdef AURORA_INTNORM
-               printk("aurora%d: port %d: Working around flip buffer overflow.\n",
-                      board_No(bp), port_No(port));
-#endif
-               return;
-       }
-       
-#ifdef AURORA_REPORT_OVERRUN   
-       status = sbus_readb(&bp->r[chip]->r[CD180_RCSR]);
-       if (status & RCSR_OE)  {
-               port->overrun++;
-#if 1
-               printk("aurora%d: port %d: Overrun. Total %ld overruns.\n",
-                      board_No(bp), port_No(port), port->overrun);
-#endif         
-       }
-       status &= port->mark_mask;
-#else  
-       status = sbus_readb(&bp->r[chip]->r[CD180_RCSR]) & port->mark_mask;
-#endif 
-       ch = sbus_readb(&bp->r[chip]->r[CD180_RDR]);
-       if (!status)
-               return;
-
-       if (status & RCSR_TOUT)  {
-/*             printk("aurora%d: port %d: Receiver timeout. Hardware problems ?\n",
-                      board_No(bp), port_No(port));*/
-               return;
-               
-       } else if (status & RCSR_BREAK)  {
-               printk(KERN_DEBUG "aurora%d: port %d: Handling break...\n",
-                      board_No(bp), port_No(port));
-               *tty->flip.flag_buf_ptr++ = TTY_BREAK;
-               if (port->flags & ASYNC_SAK)
-                       do_SAK(tty);
-               
-       } else if (status & RCSR_PE) 
-               *tty->flip.flag_buf_ptr++ = TTY_PARITY;
-       
-       else if (status & RCSR_FE) 
-               *tty->flip.flag_buf_ptr++ = TTY_FRAME;
-       
-        else if (status & RCSR_OE)
-               *tty->flip.flag_buf_ptr++ = TTY_OVERRUN;
-       
-       else
-               *tty->flip.flag_buf_ptr++ = 0;
-       
-       *tty->flip.char_buf_ptr++ = ch;
-       tty->flip.count++;
-       queue_task(&tty->flip.tqueue, &tq_timer);
-}
-
-static void aurora_receive(struct Aurora_board const * bp, int chip)
-{
-       struct Aurora_port *port;
-       struct tty_struct *tty;
-       unsigned char count,cnt;
-
-       if (!(port = aurora_get_port(bp, chip, "Receive")))
-               return;
-       
-       tty = port->tty;
-       
-       count = sbus_readb(&bp->r[chip]->r[CD180_RDCR]);
-
-#ifdef AURORA_REPORT_FIFO
-       port->hits[count > 8 ? 9 : count]++;
-#endif
-
-       while (count--)  {
-               if (tty->flip.count >= TTY_FLIPBUF_SIZE)  {
-#ifdef AURORA_INTNORM
-                       printk("aurora%d: port %d: Working around flip buffer overflow.\n",
-                              board_No(bp), port_No(port));
-#endif
-                       break;
-               }
-               cnt = sbus_readb(&bp->r[chip]->r[CD180_RDR]);
-               *tty->flip.char_buf_ptr++ = cnt;
-               *tty->flip.flag_buf_ptr++ = 0;
-               tty->flip.count++;
-       }
-       queue_task(&tty->flip.tqueue, &tq_timer);
-}
-
-static void aurora_transmit(struct Aurora_board const * bp, int chip)
-{
-       struct Aurora_port *port;
-       struct tty_struct *tty;
-       unsigned char count;
-       
-       if (!(port = aurora_get_port(bp, chip, "Transmit")))
-               return;
-               
-       tty = port->tty;
-       
-       if (port->SRER & SRER_TXEMPTY)  {
-               /* FIFO drained */
-               sbus_writeb(port_No(port) & 7,
-                           &bp->r[chip]->r[CD180_CAR]);
-               udelay(1);
-               port->SRER &= ~SRER_TXEMPTY;
-               sbus_writeb(port->SRER, &bp->r[chip]->r[CD180_SRER]);
-               return;
-       }
-       
-       if ((port->xmit_cnt <= 0 && !port->break_length)
-           || tty->stopped || tty->hw_stopped)  {
-               sbus_writeb(port_No(port) & 7,
-                           &bp->r[chip]->r[CD180_CAR]);
-               udelay(1);
-               port->SRER &= ~SRER_TXRDY;
-               sbus_writeb(port->SRER,
-                           &bp->r[chip]->r[CD180_SRER]);
-               return;
-       }
-       
-       if (port->break_length)  {
-               if (port->break_length > 0)  {
-                       if (port->COR2 & COR2_ETC)  {
-                               sbus_writeb(CD180_C_ESC,
-                                           &bp->r[chip]->r[CD180_TDR]);
-                               sbus_writeb(CD180_C_SBRK,
-                                           &bp->r[chip]->r[CD180_TDR]);
-                               port->COR2 &= ~COR2_ETC;
-                       }
-                       count = min(port->break_length, 0xff);
-                       sbus_writeb(CD180_C_ESC,
-                                   &bp->r[chip]->r[CD180_TDR]);
-                       sbus_writeb(CD180_C_DELAY,
-                                   &bp->r[chip]->r[CD180_TDR]);
-                       sbus_writeb(count,
-                                   &bp->r[chip]->r[CD180_TDR]);
-                       if (!(port->break_length -= count))
-                               port->break_length--;
-               } else  {
-                       sbus_writeb(CD180_C_ESC,
-                                   &bp->r[chip]->r[CD180_TDR]);
-                       sbus_writeb(CD180_C_EBRK,
-                                   &bp->r[chip]->r[CD180_TDR]);
-                       sbus_writeb(port->COR2,
-                                   &bp->r[chip]->r[CD180_COR2]);
-                       aurora_wait_CCR(bp->r[chip]);
-                       sbus_writeb(CCR_CORCHG2,
-                                   &bp->r[chip]->r[CD180_CCR]);
-                       port->break_length = 0;
-               }
-               return;
-       }
-       
-       count = CD180_NFIFO;
-       do {
-               u8 byte = port->xmit_buf[port->xmit_tail++];
-
-               sbus_writeb(byte, &bp->r[chip]->r[CD180_TDR]);
-               port->xmit_tail = port->xmit_tail & (SERIAL_XMIT_SIZE-1);
-               if (--port->xmit_cnt <= 0)
-                       break;
-       } while (--count > 0);
-       
-       if (port->xmit_cnt <= 0)  {
-               sbus_writeb(port_No(port) & 7,
-                           &bp->r[chip]->r[CD180_CAR]);
-               udelay(1);
-               port->SRER &= ~SRER_TXRDY;
-               sbus_writeb(port->SRER,
-                           &bp->r[chip]->r[CD180_SRER]);
-       }
-       if (port->xmit_cnt <= port->wakeup_chars)
-               aurora_mark_event(port, RS_EVENT_WRITE_WAKEUP);
-}
-
-static void aurora_check_modem(struct Aurora_board const * bp, int chip)
-{
-       struct Aurora_port *port;
-       struct tty_struct *tty;
-       unsigned char mcr;
-       
-       if (!(port = aurora_get_port(bp, chip, "Modem")))
-               return;
-               
-       tty = port->tty;
-       
-       mcr = sbus_readb(&bp->r[chip]->r[CD180_MCR]);
-       if (mcr & MCR_CDCHG)  {
-               if (sbus_readb(&bp->r[chip]->r[CD180_MSVR]) & MSVR_CD) 
-                       wake_up_interruptible(&port->open_wait);
-               else
-                       schedule_task(&port->tqueue_hangup);
-       }
-       
-/* We don't have such things yet. My aurora board has DTR and RTS swapped, but that doesn't count in this driver. Let's hope
- * Aurora didn't made any boards with CTS or DSR broken...
- */
-/* #ifdef AURORA_BRAIN_DAMAGED_CTS
-       if (mcr & MCR_CTSCHG)  {
-               if (aurora_in(bp, CD180_MSVR) & MSVR_CTS)  {
-                       tty->hw_stopped = 0;
-                       port->SRER |= SRER_TXRDY;
-                       if (port->xmit_cnt <= port->wakeup_chars)
-                               aurora_mark_event(port, RS_EVENT_WRITE_WAKEUP);
-               } else  {
-                       tty->hw_stopped = 1;
-                       port->SRER &= ~SRER_TXRDY;
-               }
-               sbus_writeb(port->SRER, &bp->r[chip]->r[CD180_SRER]);
-       }
-       if (mcr & MCR_DSRCHG)  {
-               if (aurora_in(bp, CD180_MSVR) & MSVR_DSR)  {
-                       tty->hw_stopped = 0;
-                       port->SRER |= SRER_TXRDY;
-                       if (port->xmit_cnt <= port->wakeup_chars)
-                               aurora_mark_event(port, RS_EVENT_WRITE_WAKEUP);
-               } else  {
-                       tty->hw_stopped = 1;
-                       port->SRER &= ~SRER_TXRDY;
-               }
-               sbus_writeb(port->SRER, &bp->r[chip]->r[CD180_SRER]);
-       }
-#endif AURORA_BRAIN_DAMAGED_CTS */
-       
-       /* Clear change bits */
-       sbus_writeb(0, &bp->r[chip]->r[CD180_MCR]);
-}
-
-/* The main interrupt processing routine */
-static irqreturn_t aurora_interrupt(int irq, void * dev_id)
-{
-       unsigned char status;
-       unsigned char ack,chip/*,chip_id*/;
-       struct Aurora_board * bp = (struct Aurora_board *) dev_id;
-       unsigned long loop = 0;
-
-#ifdef AURORA_INT_DEBUG
-       printk("IRQ%d %d\n",irq,++irqhit);
-#ifdef AURORA_FLOODPRO
-       if (irqhit>=AURORA_FLOODPRO)
-               sbus_writeb(8, &bp->r0->r);
-#endif
-#endif
-       
-/* old bp = IRQ_to_board[irq&0x0f];*/
-       
-       if (!bp || !(bp->flags & AURORA_BOARD_ACTIVE))
-               return IRQ_NONE;
-
-/*     The while() below takes care of this.
-       status = sbus_readb(&bp->r[0]->r[CD180_SRSR]);
-#ifdef AURORA_INT_DEBUG
-       printk("mumu: %02x\n", status);
-#endif
-       if (!(status&SRSR_ANYINT))
-               return IRQ_NONE; * Nobody has anything to say, so exit *
-*/
-       while ((loop++ < 48) &&
-              (status = sbus_readb(&bp->r[0]->r[CD180_SRSR]) & SRSR_ANYINT)){
-#ifdef AURORA_INT_DEBUG
-               printk("SRSR: %02x\n", status);
-#endif
-               if (status & SRSR_REXT) {
-                       ack = sbus_readb(&bp->r3->r[bp->ACK_RINT]);
-#ifdef AURORA_INT_DEBUG
-                       printk("R-ACK %02x\n", ack);
-#endif
-                       if ((ack >> 5) == board_No(bp)) {
-                               if ((chip=((ack>>3)&3)-1) < AURORA_NCD180) {
-                                       if ((ack&GSVR_ITMASK)==GSVR_IT_RGD) {
-                                               aurora_receive(bp,chip);
-                                               sbus_writeb(0,
-                                                        &bp->r[chip]->r[CD180_EOSRR]);
-                                       } else if ((ack & GSVR_ITMASK) == GSVR_IT_REXC) {
-                                               aurora_receive_exc(bp,chip);
-                                               sbus_writeb(0,
-                                                        &bp->r[chip]->r[CD180_EOSRR]);
-                                       }
-                               }
-                       }
-               } else if (status & SRSR_TEXT) {
-                       ack = sbus_readb(&bp->r3->r[bp->ACK_TINT]);
-#ifdef AURORA_INT_DEBUG
-                       printk("T-ACK %02x\n", ack);
-#endif
-                       if ((ack >> 5) == board_No(bp)) {
-                               if ((chip=((ack>>3)&3)-1) < AURORA_NCD180) {
-                                       if ((ack&GSVR_ITMASK)==GSVR_IT_TX) {
-                                               aurora_transmit(bp,chip);
-                                               sbus_writeb(0,
-                                                        &bp->r[chip]->r[CD180_EOSRR]);
-                                       }
-                               }
-                       }
-               } else if (status & SRSR_MEXT) {
-                       ack = sbus_readb(&bp->r3->r[bp->ACK_MINT]);
-#ifdef AURORA_INT_DEBUG
-                       printk("M-ACK %02x\n", ack);
-#endif
-                       if ((ack >> 5) == board_No(bp)) {
-                               if ((chip = ((ack>>3)&3)-1) < AURORA_NCD180) {
-                                       if ((ack&GSVR_ITMASK)==GSVR_IT_MDM) {
-                                               aurora_check_modem(bp,chip);
-                                               sbus_writeb(0,
-                                                        &bp->r[chip]->r[CD180_EOSRR]);
-                                       }
-                               }
-                       }
-               }
-       }
-/* I guess this faster code can be used with CD1865, using AUROPRI and GLOBPRI. */
-#if 0
-       while ((loop++ < 48)&&(status=bp->r[0]->r[CD180_SRSR]&SRSR_ANYINT)){
-#ifdef AURORA_INT_DEBUG
-               printk("SRSR: %02x\n",status);
-#endif
-               ack = sbus_readb(&bp->r3->r[0]);
-#ifdef AURORA_INT_DEBUG
-               printk("ACK: %02x\n",ack);
-#endif
-               if ((ack>>5)==board_No(bp)) {
-                       if ((chip=((ack>>3)&3)-1) < AURORA_NCD180) {
-                               ack&=GSVR_ITMASK;
-                               if (ack==GSVR_IT_RGD) {
-                                       aurora_receive(bp,chip);
-                                       sbus_writeb(0,
-                                                   &bp->r[chip]->r[CD180_EOSRR]);
-                               } else if (ack==GSVR_IT_REXC) {
-                                       aurora_receive_exc(bp,chip);
-                                       sbus_writeb(0,
-                                                   &bp->r[chip]->r[CD180_EOSRR]);
-                               } else if (ack==GSVR_IT_TX) {
-                                       aurora_transmit(bp,chip);
-                                       sbus_writeb(0,
-                                                   &bp->r[chip]->r[CD180_EOSRR]);
-                               } else if (ack==GSVR_IT_MDM) {
-                                       aurora_check_modem(bp,chip);
-                                       sbus_writeb(0,
-                                                   &bp->r[chip]->r[CD180_EOSRR]);
-                               }
-                       }
-               }
-       }
-#endif
-
-/* This is the old handling routine, used in riscom8 for only one CD180. I keep it here for reference. */
-#if 0
-       for(chip=0;chip<AURORA_NCD180;chip++){
-               chip_id=(board_No(bp)<<5)|((chip+1)<<3);
-               loop=0;
-               while ((loop++ < 1) &&
-                      ((status = sbus_readb(&bp->r[chip]->r[CD180_SRSR])) &
-                       (SRSR_TEXT | SRSR_MEXT | SRSR_REXT))) {
-
-                       if (status & SRSR_REXT) {
-                               ack = sbus_readb(&bp->r3->r[bp->ACK_RINT]);
-                               if (ack == (chip_id | GSVR_IT_RGD)) {
-#ifdef AURORA_INTMSG
-                                       printk("RX ACK\n");
-#endif
-                                       aurora_receive(bp,chip);
-                               } else if (ack == (chip_id | GSVR_IT_REXC)) {
-#ifdef AURORA_INTMSG
-                                       printk("RXC ACK\n");
-#endif
-                                       aurora_receive_exc(bp,chip);
-                               } else {
-#ifdef AURORA_INTNORM
-                                       printk("aurora%d-%d: Bad receive ack 0x%02x.\n",
-                                              board_No(bp), chip, ack);
-#endif
-                               }
-                       } else if (status & SRSR_TEXT) {
-                               ack = sbus_readb(&bp->r3->r[bp->ACK_TINT]);
-                               if (ack == (chip_id | GSVR_IT_TX)){
-#ifdef AURORA_INTMSG
-                                       printk("TX ACK\n");
-#endif
-                                       aurora_transmit(bp,chip);
-                               } else {
-#ifdef AURORA_INTNORM
-                                       printk("aurora%d-%d: Bad transmit ack 0x%02x.\n",
-                                              board_No(bp), chip, ack);
-#endif
-                               }
-                       } else  if (status & SRSR_MEXT)  {
-                               ack = sbus_readb(&bp->r3->r[bp->ACK_MINT]);
-                               if (ack == (chip_id | GSVR_IT_MDM)){
-#ifdef AURORA_INTMSG
-                                       printk("MDM ACK\n");
-#endif
-                                       aurora_check_modem(bp,chip);
-                               } else {
-#ifdef AURORA_INTNORM
-                                       printk("aurora%d-%d: Bad modem ack 0x%02x.\n",
-                                              board_No(bp), chip, ack);
-#endif
-                               }
-                       }
-                       sbus_writeb(0, &bp->r[chip]->r[CD180_EOSRR]);
-               }
-       }
-#endif
-
-       return IRQ_HANDLED;
-}
-
-#ifdef AURORA_INT_DEBUG
-static void aurora_timer (unsigned long ignored);
-
-static DEFINE_TIMER(aurora_poll_timer, aurora_timer, 0, 0);
-
-static void
-aurora_timer (unsigned long ignored)
-{
-       unsigned long flags;
-       int i;
-
-       save_flags(flags); cli();
-
-       printk("SRSR: %02x,%02x - ",
-              sbus_readb(&aurora_board[0].r[0]->r[CD180_SRSR]),
-              sbus_readb(&aurora_board[0].r[1]->r[CD180_SRSR]));
-       for (i = 0; i < 4; i++) {
-               udelay(1);
-               printk("%02x ",
-                      sbus_readb(&aurora_board[0].r3->r[i]));
-       }
-       printk("\n");
-
-       aurora_poll_timer.expires = jiffies + 300;
-       add_timer (&aurora_poll_timer);
-
-       restore_flags(flags);
-}
-#endif
-
-/*
- *  Routines for open & close processing.
- */
-
-/* Called with disabled interrupts */
-static int aurora_setup_board(struct Aurora_board * bp)
-{
-       int error;
-       
-#ifdef AURORA_ALLIRQ
-       int i;
-       for (i = 0; i < AURORA_ALLIRQ; i++) {
-               error = request_irq(allirq[i]|0x30, aurora_interrupt, IRQF_SHARED,
-                                   "sio16", bp);
-               if (error)
-                       printk(KERN_ERR "IRQ%d request error %d\n",
-                              allirq[i], error);
-       }
-#else
-       error = request_irq(bp->irq|0x30, aurora_interrupt, IRQF_SHARED,
-                           "sio16", bp);
-       if (error) {
-               printk(KERN_ERR "IRQ request error %d\n", error);
-               return error;
-       }
-#endif
-       /* Board reset */
-       sbus_writeb(0, &bp->r0->r);
-       udelay(1);
-       if (bp->flags & AURORA_BOARD_TYPE_2) {
-               /* unknown yet */
-       } else {
-               sbus_writeb((AURORA_CFG_ENABLE_IO | AURORA_CFG_ENABLE_IRQ |
-                            (((bp->irq)&0x0f)>>2)),
-                           &bp->r0->r);
-       }
-       udelay(10000);
-
-       if (aurora_init_CD180(bp,0))error=1;error=0;
-       if (aurora_init_CD180(bp,1))error++;
-       if (error == AURORA_NCD180) {
-               printk(KERN_ERR "Both chips failed initialisation.\n");
-               return -EIO;
-       }
-
-#ifdef AURORA_INT_DEBUG
-       aurora_poll_timer.expires= jiffies + 1;
-       add_timer(&aurora_poll_timer);
-#endif
-#ifdef AURORA_DEBUG
-       printk("aurora_setup_board: end\n");
-#endif
-       return 0;
-}
-
-/* Called with disabled interrupts */
-static void aurora_shutdown_board(struct Aurora_board *bp)
-{
-       int i;
-
-#ifdef AURORA_DEBUG
-       printk("aurora_shutdown_board: start\n");
-#endif
-
-#ifdef AURORA_INT_DEBUG
-       del_timer(&aurora_poll_timer);
-#endif
-
-#ifdef AURORA_ALLIRQ
-       for(i=0;i<AURORA_ALLIRQ;i++){
-               free_irq(allirq[i]|0x30, bp);
-/*             IRQ_to_board[allirq[i]&0xf] = NULL;*/
-       }
-#else
-       free_irq(bp->irq|0x30, bp);
-/*     IRQ_to_board[bp->irq&0xf] = NULL;*/
-#endif 
-       /* Drop all DTR's */
-       for(i=0;i<16;i++){
-               sbus_writeb(i & 7, &bp->r[i>>3]->r[CD180_CAR]);
-               udelay(1);
-               sbus_writeb(0, &bp->r[i>>3]->r[CD180_MSVR]);
-               udelay(1);
-       }
-       /* Board shutdown */
-       sbus_writeb(0, &bp->r0->r);
-
-#ifdef AURORA_DEBUG
-       printk("aurora_shutdown_board: end\n");
-#endif
-}
-
-/* Setting up port characteristics. 
- * Must be called with disabled interrupts
- */
-static void aurora_change_speed(struct Aurora_board *bp, struct Aurora_port *port)
-{
-       struct tty_struct *tty;
-       unsigned long baud;
-       long tmp;
-       unsigned char cor1 = 0, cor3 = 0;
-       unsigned char mcor1 = 0, mcor2 = 0,chip;
-       
-#ifdef AURORA_DEBUG
-       printk("aurora_change_speed: start\n");
-#endif
-       if (!(tty = port->tty) || !tty->termios)
-               return;
-               
-       chip = AURORA_CD180(port_No(port));
-
-       port->SRER  = 0;
-       port->COR2 = 0;
-       port->MSVR = MSVR_RTS|MSVR_DTR;
-       
-       baud = tty_get_baud_rate(tty);
-       
-       /* Select port on the board */
-       sbus_writeb(port_No(port) & 7,
-                   &bp->r[chip]->r[CD180_CAR]);
-       udelay(1);
-       
-       if (!baud)  {
-               /* Drop DTR & exit */
-               port->MSVR &= ~(bp->DTR|bp->RTS);
-               sbus_writeb(port->MSVR,
-                           &bp->r[chip]->r[CD180_MSVR]);
-               return;
-       } else  {
-               /* Set DTR on */
-               port->MSVR |= bp->DTR;
-               sbus_writeb(port->MSVR,
-                           &bp->r[chip]->r[CD180_MSVR]);
-       }
-       
-       /* Now we must calculate some speed dependent things. */
-       
-       /* Set baud rate for port. */
-       tmp = (((bp->oscfreq + baud/2) / baud +
-               CD180_TPC/2) / CD180_TPC);
-
-/*     tmp = (bp->oscfreq/7)/baud;
-       if((tmp%10)>4)tmp=tmp/10+1;else tmp=tmp/10;*/
-/*     printk("Prescaler period: %d\n",tmp);*/
-
-       sbus_writeb((tmp >> 8) & 0xff,
-                   &bp->r[chip]->r[CD180_RBPRH]);
-       sbus_writeb((tmp >> 8) & 0xff,
-                   &bp->r[chip]->r[CD180_TBPRH]);
-       sbus_writeb(tmp & 0xff, &bp->r[chip]->r[CD180_RBPRL]);
-       sbus_writeb(tmp & 0xff, &bp->r[chip]->r[CD180_TBPRL]);
-       
-       baud = (baud + 5) / 10;   /* Estimated CPS */
-       
-       /* Two timer ticks seems enough to wakeup something like SLIP driver */
-       tmp = ((baud + HZ/2) / HZ) * 2 - CD180_NFIFO;           
-       port->wakeup_chars = (tmp < 0) ? 0 : ((tmp >= SERIAL_XMIT_SIZE) ?
-                                             SERIAL_XMIT_SIZE - 1 : tmp);
-       
-       /* Receiver timeout will be transmission time for 1.5 chars */
-       tmp = (AURORA_TPS + AURORA_TPS/2 + baud/2) / baud;
-       tmp = (tmp > 0xff) ? 0xff : tmp;
-       sbus_writeb(tmp, &bp->r[chip]->r[CD180_RTPR]);
-       
-       switch (C_CSIZE(tty))  {
-        case CS5:
-               cor1 |= COR1_5BITS;
-               break;
-        case CS6:
-               cor1 |= COR1_6BITS;
-               break;
-        case CS7:
-               cor1 |= COR1_7BITS;
-               break;
-        case CS8:
-               cor1 |= COR1_8BITS;
-               break;
-       }
-       
-       if (C_CSTOPB(tty)) 
-               cor1 |= COR1_2SB;
-       
-       cor1 |= COR1_IGNORE;
-       if (C_PARENB(tty))  {
-               cor1 |= COR1_NORMPAR;
-               if (C_PARODD(tty)) 
-                       cor1 |= COR1_ODDP;
-               if (I_INPCK(tty)) 
-                       cor1 &= ~COR1_IGNORE;
-       }
-       /* Set marking of some errors */
-       port->mark_mask = RCSR_OE | RCSR_TOUT;
-       if (I_INPCK(tty)) 
-               port->mark_mask |= RCSR_FE | RCSR_PE;
-       if (I_BRKINT(tty) || I_PARMRK(tty)) 
-               port->mark_mask |= RCSR_BREAK;
-       if (I_IGNPAR(tty)) 
-               port->mark_mask &= ~(RCSR_FE | RCSR_PE);
-       if (I_IGNBRK(tty))  {
-               port->mark_mask &= ~RCSR_BREAK;
-               if (I_IGNPAR(tty)) 
-                       /* Real raw mode. Ignore all */
-                       port->mark_mask &= ~RCSR_OE;
-       }
-       /* Enable Hardware Flow Control */
-       if (C_CRTSCTS(tty))  {
-/*#ifdef AURORA_BRAIN_DAMAGED_CTS
-               port->SRER |= SRER_DSR | SRER_CTS;
-               mcor1 |= MCOR1_DSRZD | MCOR1_CTSZD;
-               mcor2 |= MCOR2_DSROD | MCOR2_CTSOD;
-               tty->hw_stopped = !(aurora_in(bp, CD180_MSVR) & (MSVR_CTS|MSVR_DSR));
-#else*/
-               port->COR2 |= COR2_CTSAE;
-/*#endif*/
-               if (bp->flags&AURORA_BOARD_DTR_FLOW_OK) {
-                       mcor1 |= AURORA_RXTH;
-               }
-       }
-       /* Enable Software Flow Control. FIXME: I'm not sure about this */
-       /* Some people reported that it works, but I still doubt */
-       if (I_IXON(tty))  {
-               port->COR2 |= COR2_TXIBE;
-               cor3 |= (COR3_FCT | COR3_SCDE);
-               if (I_IXANY(tty))
-                       port->COR2 |= COR2_IXM;
-               sbus_writeb(START_CHAR(tty),
-                           &bp->r[chip]->r[CD180_SCHR1]);
-               sbus_writeb(STOP_CHAR(tty),
-                           &bp->r[chip]->r[CD180_SCHR2]);
-               sbus_writeb(START_CHAR(tty),
-                           &bp->r[chip]->r[CD180_SCHR3]);
-               sbus_writeb(STOP_CHAR(tty),
-                           &bp->r[chip]->r[CD180_SCHR4]);
-       }
-       if (!C_CLOCAL(tty))  {
-               /* Enable CD check */
-               port->SRER |= SRER_CD;
-               mcor1 |= MCOR1_CDZD;
-               mcor2 |= MCOR2_CDOD;
-       }
-       
-       if (C_CREAD(tty)) 
-               /* Enable receiver */
-               port->SRER |= SRER_RXD;
-       
-       /* Set input FIFO size (1-8 bytes) */
-       cor3 |= AURORA_RXFIFO; 
-       /* Setting up CD180 channel registers */
-       sbus_writeb(cor1, &bp->r[chip]->r[CD180_COR1]);
-       sbus_writeb(port->COR2, &bp->r[chip]->r[CD180_COR2]);
-       sbus_writeb(cor3, &bp->r[chip]->r[CD180_COR3]);
-       /* Make CD180 know about registers change */
-       aurora_wait_CCR(bp->r[chip]);
-       sbus_writeb(CCR_CORCHG1 | CCR_CORCHG2 | CCR_CORCHG3,
-                   &bp->r[chip]->r[CD180_CCR]);
-       /* Setting up modem option registers */
-       sbus_writeb(mcor1, &bp->r[chip]->r[CD180_MCOR1]);
-       sbus_writeb(mcor2, &bp->r[chip]->r[CD180_MCOR2]);
-       /* Enable CD180 transmitter & receiver */
-       aurora_wait_CCR(bp->r[chip]);
-       sbus_writeb(CCR_TXEN | CCR_RXEN, &bp->r[chip]->r[CD180_CCR]);
-       /* Enable interrupts */
-       sbus_writeb(port->SRER, &bp->r[chip]->r[CD180_SRER]);
-       /* And finally set RTS on */
-       sbus_writeb(port->MSVR, &bp->r[chip]->r[CD180_MSVR]);
-#ifdef AURORA_DEBUG
-       printk("aurora_change_speed: end\n");
-#endif
-}
-
-/* Must be called with interrupts enabled */
-static int aurora_setup_port(struct Aurora_board *bp, struct Aurora_port *port)
-{
-       unsigned long flags;
-       
-#ifdef AURORA_DEBUG
-       printk("aurora_setup_port: start %d\n",port_No(port));
-#endif
-       if (port->flags & ASYNC_INITIALIZED)
-               return 0;
-               
-       if (!port->xmit_buf) {
-               /* We may sleep in get_zeroed_page() */
-               unsigned long tmp;
-               
-               if (!(tmp = get_zeroed_page(GFP_KERNEL)))
-                       return -ENOMEM;
-                   
-               if (port->xmit_buf) {
-                       free_page(tmp);
-                       return -ERESTARTSYS;
-               }
-               port->xmit_buf = (unsigned char *) tmp;
-       }
-               
-       save_flags(flags); cli();
-               
-       if (port->tty) 
-               clear_bit(TTY_IO_ERROR, &port->tty->flags);
-               
-#ifdef MODULE
-       if ((port->count == 1) && ((++bp->count) == 1))
-                       bp->flags |= AURORA_BOARD_ACTIVE;
-#endif
-
-       port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
-       aurora_change_speed(bp, port);
-       port->flags |= ASYNC_INITIALIZED;
-               
-       restore_flags(flags);
-#ifdef AURORA_DEBUG
-       printk("aurora_setup_port: end\n");
-#endif
-       return 0;
-}
-
-/* Must be called with interrupts disabled */
-static void aurora_shutdown_port(struct Aurora_board *bp, struct Aurora_port *port)
-{
-       struct tty_struct *tty;
-       unsigned char chip;
-
-#ifdef AURORA_DEBUG
-       printk("aurora_shutdown_port: start\n");
-#endif
-       if (!(port->flags & ASYNC_INITIALIZED)) 
-               return;
-       
-       chip = AURORA_CD180(port_No(port));
-       
-#ifdef AURORA_REPORT_OVERRUN
-       printk("aurora%d: port %d: Total %ld overruns were detected.\n",
-              board_No(bp), port_No(port), port->overrun);
-#endif 
-#ifdef AURORA_REPORT_FIFO
-       {
-               int i;
-               
-               printk("aurora%d: port %d: FIFO hits [ ",
-                      board_No(bp), port_No(port));
-               for (i = 0; i < 10; i++)  {
-                       printk("%ld ", port->hits[i]);
-               }
-               printk("].\n");
-       }
-#endif 
-       if (port->xmit_buf)  {
-               free_page((unsigned long) port->xmit_buf);
-               port->xmit_buf = NULL;
-       }
-
-       if (!(tty = port->tty) || C_HUPCL(tty))  {
-               /* Drop DTR */
-               port->MSVR &= ~(bp->DTR|bp->RTS);
-               sbus_writeb(port->MSVR,
-                           &bp->r[chip]->r[CD180_MSVR]);
-       }
-       
-        /* Select port */
-       sbus_writeb(port_No(port) & 7,
-                   &bp->r[chip]->r[CD180_CAR]);
-       udelay(1);
-
-       /* Reset port */
-       aurora_wait_CCR(bp->r[chip]);
-       sbus_writeb(CCR_SOFTRESET, &bp->r[chip]->r[CD180_CCR]);
-
-       /* Disable all interrupts from this port */
-       port->SRER = 0;
-       sbus_writeb(port->SRER, &bp->r[chip]->r[CD180_SRER]);
-       
-       if (tty)  
-               set_bit(TTY_IO_ERROR, &tty->flags);
-       port->flags &= ~ASYNC_INITIALIZED;
-
-#ifdef MODULE
-       if (--bp->count < 0)  {
-               printk(KERN_DEBUG "aurora%d: aurora_shutdown_port: "
-                      "bad board count: %d\n",
-                      board_No(bp), bp->count);
-               bp->count = 0;
-       }
-       
-       if (!bp->count)
-               bp->flags &= ~AURORA_BOARD_ACTIVE;
-#endif
-
-#ifdef AURORA_DEBUG
-       printk("aurora_shutdown_port: end\n");
-#endif
-}
-
-       
-static int block_til_ready(struct tty_struct *tty, struct file * filp,
-                          struct Aurora_port *port)
-{
-       DECLARE_WAITQUEUE(wait, current);
-       struct Aurora_board *bp = port_Board(port);
-       int    retval;
-       int    do_clocal = 0;
-       int    CD;
-       unsigned char chip;
-       
-#ifdef AURORA_DEBUG
-       printk("block_til_ready: start\n");
-#endif
-       chip = AURORA_CD180(port_No(port));
-
-       /* 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) || port->flags & ASYNC_CLOSING) {
-               interruptible_sleep_on(&port->close_wait);
-               if (port->flags & ASYNC_HUP_NOTIFY)
-                       return -EAGAIN;
-               else
-                       return -ERESTARTSYS;
-       }
-
-       /* If non-blocking mode is set, or the port is not enabled,
-        * then make the check up front and then exit.
-        */
-       if ((filp->f_flags & O_NONBLOCK) ||
-           (tty->flags & (1 << TTY_IO_ERROR))) {
-               port->flags |= ASYNC_NORMAL_ACTIVE;
-               return 0;
-       }
-
-       if (C_CLOCAL(tty))  
-               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, info->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;
-       add_wait_queue(&port->open_wait, &wait);
-       cli();
-       if (!tty_hung_up_p(filp))
-               port->count--;
-       sti();
-       port->blocked_open++;
-       while (1) {
-               cli();
-               sbus_writeb(port_No(port) & 7,
-                           &bp->r[chip]->r[CD180_CAR]);
-               udelay(1);
-               CD = sbus_readb(&bp->r[chip]->r[CD180_MSVR]) & MSVR_CD;
-               port->MSVR=bp->RTS;
-
-               /* auto drops DTR */
-               sbus_writeb(port->MSVR, &bp->r[chip]->r[CD180_MSVR]);
-               sti();
-               set_current_state(TASK_INTERRUPTIBLE);
-               if (tty_hung_up_p(filp) ||
-                   !(port->flags & ASYNC_INITIALIZED)) {
-                       if (port->flags & ASYNC_HUP_NOTIFY)
-                               retval = -EAGAIN;
-                       else
-                               retval = -ERESTARTSYS;  
-                       break;
-               }
-               if (!(port->flags & ASYNC_CLOSING) &&
-                   (do_clocal || CD))
-                       break;
-               if (signal_pending(current)) {
-                       retval = -ERESTARTSYS;
-                       break;
-               }
-               schedule();
-       }
-       current->state = TASK_RUNNING;
-       remove_wait_queue(&port->open_wait, &wait);
-       if (!tty_hung_up_p(filp))
-               port->count++;
-       port->blocked_open--;
-       if (retval)
-               return retval;
-       
-       port->flags |= ASYNC_NORMAL_ACTIVE;
-#ifdef AURORA_DEBUG
-       printk("block_til_ready: end\n");
-#endif
-       return 0;
-}      
-
-static int aurora_open(struct tty_struct * tty, struct file * filp)
-{
-       int board;
-       int error;
-       struct Aurora_port * port;
-       struct Aurora_board * bp;
-       unsigned long flags;
-       
-#ifdef AURORA_DEBUG
-       printk("aurora_open: start\n");
-#endif
-       
-       board = AURORA_BOARD(tty->index);
-       if (board > AURORA_NBOARD ||
-           !(aurora_board[board].flags & AURORA_BOARD_PRESENT)) {
-#ifdef AURORA_DEBUG
-               printk("aurora_open: error board %d present %d\n",
-                      board, aurora_board[board].flags & AURORA_BOARD_PRESENT);
-#endif
-               return -ENODEV;
-       }
-       
-       bp = &aurora_board[board];
-       port = aurora_port + board * AURORA_NPORT * AURORA_NCD180 + AURORA_PORT(tty->index);
-       if ((aurora_paranoia_check(port, tty->name, "aurora_open")) {
-#ifdef AURORA_DEBUG
-               printk("aurora_open: error paranoia check\n");
-#endif
-               return -ENODEV;
-       }
-       
-       port->count++;
-       tty->driver_data = port;
-       port->tty = tty;
-       
-       if ((error = aurora_setup_port(bp, port))) {
-#ifdef AURORA_DEBUG
-               printk("aurora_open: error aurora_setup_port ret %d\n",error);
-#endif
-               return error;
-       }
-
-       if ((error = block_til_ready(tty, filp, port))) {
-#ifdef AURORA_DEBUG
-               printk("aurora_open: error block_til_ready ret %d\n",error);
-#endif
-               return error;
-       }
-       
-#ifdef AURORA_DEBUG
-       printk("aurora_open: end\n");
-#endif
-       return 0;
-}
-
-static void aurora_close(struct tty_struct * tty, struct file * filp)
-{
-       struct Aurora_port *port = (struct Aurora_port *) tty->driver_data;
-       struct Aurora_board *bp;
-       unsigned long flags;
-       unsigned long timeout;
-       unsigned char chip;
-       
-#ifdef AURORA_DEBUG
-       printk("aurora_close: start\n");
-#endif
-       
-       if (!port || (aurora_paranoia_check(port, tty->name, "close"))
-               return;
-       
-       chip = AURORA_CD180(port_No(port));
-
-       save_flags(flags); cli();
-       if (tty_hung_up_p(filp))  {
-               restore_flags(flags);
-               return;
-       }
-       
-       bp = port_Board(port);
-       if ((tty->count == 1) && (port->count != 1))  {
-               printk(KERN_DEBUG "aurora%d: aurora_close: bad port count; "
-                      "tty->count is 1, port count is %d\n",
-                      board_No(bp), port->count);
-               port->count = 1;
-       }
-       if (--port->count < 0)  {
-               printk(KERN_DEBUG "aurora%d: aurora_close: bad port "
-                      "count for tty%d: %d\n",
-                      board_No(bp), port_No(port), port->count);
-               port->count = 0;
-       }
-       if (port->count)  {
-               restore_flags(flags);
-               return;
-       }
-       port->flags |= ASYNC_CLOSING;
-
-       /* 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 (port->closing_wait != ASYNC_CLOSING_WAIT_NONE){
-#ifdef AURORA_DEBUG
-               printk("aurora_close: waiting to flush...\n");
-#endif
-               tty_wait_until_sent(tty, port->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.
-        */
-       port->SRER &= ~SRER_RXD;
-       if (port->flags & ASYNC_INITIALIZED) {
-               port->SRER &= ~SRER_TXRDY;
-               port->SRER |= SRER_TXEMPTY;
-               sbus_writeb(port_No(port) & 7,
-                           &bp->r[chip]->r[CD180_CAR]);
-               udelay(1);
-               sbus_writeb(port->SRER, &bp->r[chip]->r[CD180_SRER]);
-               /*
-                * Before we drop DTR, make sure the UART transmitter
-                * has completely drained; this is especially
-                * important if there is a transmit FIFO!
-                */
-               timeout = jiffies+HZ;
-               while(port->SRER & SRER_TXEMPTY)  {
-                       msleep_interruptible(jiffies_to_msecs(port->timeout));
-                       if (time_after(jiffies, timeout))
-                               break;
-               }
-       }
-#ifdef AURORA_DEBUG
-       printk("aurora_close: shutdown_port\n");
-#endif
-       aurora_shutdown_port(bp, port);
-       if (tty->driver->flush_buffer)
-               tty->driver->flush_buffer(tty);
-       tty_ldisc_flush(tty);
-       tty->closing = 0;
-       port->event = 0;
-       port->tty = 0;
-       if (port->blocked_open) {
-               if (port->close_delay) {
-                       msleep_interruptible(jiffies_to_msecs(port->close_delay));
-               }
-               wake_up_interruptible(&port->open_wait);
-       }
-       port->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
-       wake_up_interruptible(&port->close_wait);
-       restore_flags(flags);
-#ifdef AURORA_DEBUG
-       printk("aurora_close: end\n");
-#endif
-}
-
-static int aurora_write(struct tty_struct * tty, 
-                       const unsigned char *buf, int count)
-{
-       struct Aurora_port *port = (struct Aurora_port *) tty->driver_data;
-       struct Aurora_board *bp;
-       int c, total = 0;
-       unsigned long flags;
-       unsigned char chip;
-
-#ifdef AURORA_DEBUG
-       printk("aurora_write: start %d\n",count);
-#endif
-       if ((aurora_paranoia_check(port, tty->name, "aurora_write"))
-               return 0;
-               
-       chip = AURORA_CD180(port_No(port));
-       
-       bp = port_Board(port);
-
-       if (!tty || !port->xmit_buf || !tmp_buf)
-               return 0;
-
-       save_flags(flags);
-       while (1) {
-               cli();
-               c = min(count, min(SERIAL_XMIT_SIZE - port->xmit_cnt - 1,
-                                  SERIAL_XMIT_SIZE - port->xmit_head));
-               if (c <= 0) {
-                       restore_flags(flags);
-                       break;
-               }
-               memcpy(port->xmit_buf + port->xmit_head, buf, c);
-               port->xmit_head = (port->xmit_head + c) & (SERIAL_XMIT_SIZE-1);
-               port->xmit_cnt += c;
-               restore_flags(flags);
-
-               buf += c;
-               count -= c;
-               total += c;
-       }
-
-       cli();
-       if (port->xmit_cnt && !tty->stopped && !tty->hw_stopped &&
-           !(port->SRER & SRER_TXRDY)) {
-               port->SRER |= SRER_TXRDY;
-               sbus_writeb(port_No(port) & 7,
-                           &bp->r[chip]->r[CD180_CAR]);
-               udelay(1);
-               sbus_writeb(port->SRER, &bp->r[chip]->r[CD180_SRER]);
-       }
-       restore_flags(flags);
-#ifdef AURORA_DEBUG
-       printk("aurora_write: end %d\n",total);
-#endif
-       return total;
-}
-
-static void aurora_put_char(struct tty_struct * tty, unsigned char ch)
-{
-       struct Aurora_port *port = (struct Aurora_port *) tty->driver_data;
-       unsigned long flags;
-
-#ifdef AURORA_DEBUG
-       printk("aurora_put_char: start %c\n",ch);
-#endif
-       if ((aurora_paranoia_check(port, tty->name, "aurora_put_char"))
-               return;
-
-       if (!tty || !port->xmit_buf)
-               return;
-
-       save_flags(flags); cli();
-       
-       if (port->xmit_cnt >= SERIAL_XMIT_SIZE - 1) {
-               restore_flags(flags);
-               return;
-       }
-
-       port->xmit_buf[port->xmit_head++] = ch;
-       port->xmit_head &= SERIAL_XMIT_SIZE - 1;
-       port->xmit_cnt++;
-       restore_flags(flags);
-#ifdef AURORA_DEBUG
-       printk("aurora_put_char: end\n");
-#endif
-}
-
-static void aurora_flush_chars(struct tty_struct * tty)
-{
-       struct Aurora_port *port = (struct Aurora_port *) tty->driver_data;
-       unsigned long flags;
-       unsigned char chip;
-
-/*#ifdef AURORA_DEBUG
-       printk("aurora_flush_chars: start\n");
-#endif*/
-       if ((aurora_paranoia_check(port, tty->name, "aurora_flush_chars"))
-               return;
-               
-       chip = AURORA_CD180(port_No(port));
-       
-       if (port->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped ||
-           !port->xmit_buf)
-               return;
-
-       save_flags(flags); cli();
-       port->SRER |= SRER_TXRDY;
-       sbus_writeb(port_No(port) & 7,
-                   &port_Board(port)->r[chip]->r[CD180_CAR]);
-       udelay(1);
-       sbus_writeb(port->SRER,
-                   &port_Board(port)->r[chip]->r[CD180_SRER]);
-       restore_flags(flags);
-/*#ifdef AURORA_DEBUG
-       printk("aurora_flush_chars: end\n");
-#endif*/
-}
-
-static int aurora_write_room(struct tty_struct * tty)
-{
-       struct Aurora_port *port = (struct Aurora_port *) tty->driver_data;
-       int     ret;
-
-#ifdef AURORA_DEBUG
-       printk("aurora_write_room: start\n");
-#endif
-       if ((aurora_paranoia_check(port, tty->name, "aurora_write_room"))
-               return 0;
-
-       ret = SERIAL_XMIT_SIZE - port->xmit_cnt - 1;
-       if (ret < 0)
-               ret = 0;
-#ifdef AURORA_DEBUG
-       printk("aurora_write_room: end\n");
-#endif
-       return ret;
-}
-
-static int aurora_chars_in_buffer(struct tty_struct *tty)
-{
-       struct Aurora_port *port = (struct Aurora_port *) tty->driver_data;
-                               
-       if ((aurora_paranoia_check(port, tty->name, "aurora_chars_in_buffer"))
-               return 0;
-       
-       return port->xmit_cnt;
-}
-
-static void aurora_flush_buffer(struct tty_struct *tty)
-{
-       struct Aurora_port *port = (struct Aurora_port *) tty->driver_data;
-       unsigned long flags;
-
-#ifdef AURORA_DEBUG
-       printk("aurora_flush_buffer: start\n");
-#endif
-       if ((aurora_paranoia_check(port, tty->name, "aurora_flush_buffer"))
-               return;
-
-       save_flags(flags); cli();
-       port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
-       restore_flags(flags);
-       
-       tty_wakeup(tty);
-#ifdef AURORA_DEBUG
-       printk("aurora_flush_buffer: end\n");
-#endif
-}
-
-static int aurora_tiocmget(struct tty_struct *tty, struct file *file)
-{
-       struct Aurora_port *port = (struct Aurora_port *) tty->driver_data;
-       struct Aurora_board * bp;
-       unsigned char status,chip;
-       unsigned int result;
-       unsigned long flags;
-
-#ifdef AURORA_DEBUG
-       printk("aurora_get_modem_info: start\n");
-#endif
-       if ((aurora_paranoia_check(port, tty->name, __FUNCTION__))
-               return -ENODEV;
-
-       chip = AURORA_CD180(port_No(port));
-
-       bp = port_Board(port);
-
-       save_flags(flags); cli();
-
-       sbus_writeb(port_No(port) & 7, &bp->r[chip]->r[CD180_CAR]);
-       udelay(1);
-
-       status = sbus_readb(&bp->r[chip]->r[CD180_MSVR]);
-       result = 0/*bp->r[chip]->r[AURORA_RI] & (1u << port_No(port)) ? 0 : TIOCM_RNG*/;
-
-       restore_flags(flags);
-
-       result |= ((status & bp->RTS) ? TIOCM_RTS : 0)
-               | ((status & bp->DTR) ? TIOCM_DTR : 0)
-               | ((status & MSVR_CD)  ? TIOCM_CAR : 0)
-               | ((status & MSVR_DSR) ? TIOCM_DSR : 0)
-               | ((status & MSVR_CTS) ? TIOCM_CTS : 0);
-
-#ifdef AURORA_DEBUG
-       printk("aurora_get_modem_info: end\n");
-#endif
-       return result;
-}
-
-static int aurora_tiocmset(struct tty_struct *tty, struct file *file,
-                          unsigned int set, unsigned int clear)
-{
-       struct Aurora_port *port = (struct Aurora_port *) tty->driver_data;
-       unsigned int arg;
-       unsigned long flags;
-       struct Aurora_board *bp = port_Board(port);
-       unsigned char chip;
-
-#ifdef AURORA_DEBUG
-       printk("aurora_set_modem_info: start\n");
-#endif
-       if ((aurora_paranoia_check(port, tty->name, __FUNCTION__))
-               return -ENODEV;
-
-       chip = AURORA_CD180(port_No(port));
-
-       save_flags(flags); cli();
-       if (set & TIOCM_RTS)
-               port->MSVR |= bp->RTS;
-       if (set & TIOCM_DTR)
-               port->MSVR |= bp->DTR;
-       if (clear & TIOCM_RTS)
-               port->MSVR &= ~bp->RTS;
-       if (clear & TIOCM_DTR)
-               port->MSVR &= ~bp->DTR;
-
-       sbus_writeb(port_No(port) & 7, &bp->r[chip]->r[CD180_CAR]);
-       udelay(1);
-
-       sbus_writeb(port->MSVR, &bp->r[chip]->r[CD180_MSVR]);
-
-       restore_flags(flags);
-#ifdef AURORA_DEBUG
-       printk("aurora_set_modem_info: end\n");
-#endif
-       return 0;
-}
-
-static void aurora_send_break(struct Aurora_port * port, unsigned long length)
-{
-       struct Aurora_board *bp = port_Board(port);
-       unsigned long flags;
-       unsigned char chip;
-       
-#ifdef AURORA_DEBUG
-       printk("aurora_send_break: start\n");
-#endif
-       chip = AURORA_CD180(port_No(port));
-       
-       save_flags(flags); cli();
-
-       port->break_length = AURORA_TPS / HZ * length;
-       port->COR2 |= COR2_ETC;
-       port->SRER  |= SRER_TXRDY;
-       sbus_writeb(port_No(port) & 7, &bp->r[chip]->r[CD180_CAR]);
-       udelay(1);
-
-       sbus_writeb(port->COR2, &bp->r[chip]->r[CD180_COR2]);
-       sbus_writeb(port->SRER, &bp->r[chip]->r[CD180_SRER]);
-       aurora_wait_CCR(bp->r[chip]);
-
-       sbus_writeb(CCR_CORCHG2, &bp->r[chip]->r[CD180_CCR]);
-       aurora_wait_CCR(bp->r[chip]);
-
-       restore_flags(flags);
-#ifdef AURORA_DEBUG
-       printk("aurora_send_break: end\n");
-#endif
-}
-
-static int aurora_set_serial_info(struct Aurora_port * port,
-                                 struct serial_struct * newinfo)
-{
-       struct serial_struct tmp;
-       struct Aurora_board *bp = port_Board(port);
-       int change_speed;
-       unsigned long flags;
-
-#ifdef AURORA_DEBUG
-       printk("aurora_set_serial_info: start\n");
-#endif
-       if (copy_from_user(&tmp, newinfo, sizeof(tmp)))
-               return -EFAULT;
-#if 0  
-       if ((tmp.irq != bp->irq) ||
-           (tmp.port != bp->base) ||
-           (tmp.type != PORT_CIRRUS) ||
-           (tmp.baud_base != (bp->oscfreq + CD180_TPC/2) / CD180_TPC) ||
-           (tmp.custom_divisor != 0) ||
-           (tmp.xmit_fifo_size != CD180_NFIFO) ||
-           (tmp.flags & ~AURORA_LEGAL_FLAGS))
-               return -EINVAL;
-#endif 
-       
-       change_speed = ((port->flags & ASYNC_SPD_MASK) !=
-                       (tmp.flags & ASYNC_SPD_MASK));
-       
-       if (!capable(CAP_SYS_ADMIN)) {
-               if ((tmp.close_delay != port->close_delay) ||
-                   (tmp.closing_wait != port->closing_wait) ||
-                   ((tmp.flags & ~ASYNC_USR_MASK) !=
-                    (port->flags & ~ASYNC_USR_MASK)))  
-                       return -EPERM;
-               port->flags = ((port->flags & ~ASYNC_USR_MASK) |
-                              (tmp.flags & ASYNC_USR_MASK));
-       } else  {
-               port->flags = ((port->flags & ~ASYNC_FLAGS) |
-                              (tmp.flags & ASYNC_FLAGS));
-               port->close_delay = tmp.close_delay;
-               port->closing_wait = tmp.closing_wait;
-       }
-       if (change_speed)  {
-               save_flags(flags); cli();
-               aurora_change_speed(bp, port);
-               restore_flags(flags);
-       }
-#ifdef AURORA_DEBUG
-       printk("aurora_set_serial_info: end\n");
-#endif
-       return 0;
-}
-
-extern int aurora_get_serial_info(struct Aurora_port * port,
-                                 struct serial_struct * retinfo)
-{
-       struct serial_struct tmp;
-       struct Aurora_board *bp = port_Board(port);
-       
-#ifdef AURORA_DEBUG
-       printk("aurora_get_serial_info: start\n");
-#endif
-       if (!access_ok(VERIFY_WRITE, (void *) retinfo, sizeof(tmp)))
-               return -EFAULT;
-       
-       memset(&tmp, 0, sizeof(tmp));
-       tmp.type = PORT_CIRRUS;
-       tmp.line = port - aurora_port;
-       tmp.port = 0;
-       tmp.irq  = bp->irq;
-       tmp.flags = port->flags;
-       tmp.baud_base = (bp->oscfreq + CD180_TPC/2) / CD180_TPC;
-       tmp.close_delay = port->close_delay * HZ/100;
-       tmp.closing_wait = port->closing_wait * HZ/100;
-       tmp.xmit_fifo_size = CD180_NFIFO;
-       copy_to_user(retinfo, &tmp, sizeof(tmp));
-#ifdef AURORA_DEBUG
-printk("aurora_get_serial_info: end\n");
-#endif
-       return 0;
-}
-
-static int aurora_ioctl(struct tty_struct * tty, struct file * filp, 
-                   unsigned int cmd, unsigned long arg)
-                   
-{
-       struct Aurora_port *port = (struct Aurora_port *) tty->driver_data;
-       int retval;
-
-#ifdef AURORA_DEBUG
-       printk("aurora_ioctl: start\n");
-#endif
-       if ((aurora_paranoia_check(port, tty->name, "aurora_ioctl"))
-               return -ENODEV;
-       
-       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 (!arg)
-                       aurora_send_break(port, HZ/4);  /* 1/4 second */
-               return 0;
-       case TCSBRKP:   /* support for POSIX tcsendbreak() */
-               retval = tty_check_change(tty);
-               if (retval)
-                       return retval;
-               tty_wait_until_sent(tty, 0);
-               aurora_send_break(port, arg ? arg*(HZ/10) : HZ/4);
-               return 0;
-       case TIOCGSOFTCAR:
-               return put_user(C_CLOCAL(tty) ? 1 : 0, (unsigned long *)arg);
-       case TIOCSSOFTCAR:
-               if (get_user(arg,(unsigned long *)arg))
-                       return -EFAULT;
-               tty->termios->c_cflag =
-                       ((tty->termios->c_cflag & ~CLOCAL) |
-                        (arg ? CLOCAL : 0));
-               return 0;
-       case TIOCGSERIAL:       
-               return aurora_get_serial_info(port, (struct serial_struct *) arg);
-       case TIOCSSERIAL:       
-               return aurora_set_serial_info(port, (struct serial_struct *) arg);
-       default:
-               return -ENOIOCTLCMD;
-       };
-#ifdef AURORA_DEBUG
-       printk("aurora_ioctl: end\n");
-#endif
-       return 0;
-}
-
-static void aurora_throttle(struct tty_struct * tty)
-{
-       struct Aurora_port *port = (struct Aurora_port *) tty->driver_data;
-       struct Aurora_board *bp;
-       unsigned long flags;
-       unsigned char chip;
-
-#ifdef AURORA_DEBUG
-       printk("aurora_throttle: start\n");
-#endif
-       if ((aurora_paranoia_check(port, tty->name, "aurora_throttle"))
-               return;
-       
-       bp = port_Board(port);
-       chip = AURORA_CD180(port_No(port));
-       
-       save_flags(flags); cli();
-       port->MSVR &= ~bp->RTS;
-       sbus_writeb(port_No(port) & 7, &bp->r[chip]->r[CD180_CAR]);
-       udelay(1);
-       if (I_IXOFF(tty))  {
-               aurora_wait_CCR(bp->r[chip]);
-               sbus_writeb(CCR_SSCH2, &bp->r[chip]->r[CD180_CCR]);
-               aurora_wait_CCR(bp->r[chip]);
-       }
-       sbus_writeb(port->MSVR, &bp->r[chip]->r[CD180_MSVR]);
-       restore_flags(flags);
-#ifdef AURORA_DEBUG
-       printk("aurora_throttle: end\n");
-#endif
-}
-
-static void aurora_unthrottle(struct tty_struct * tty)
-{
-       struct Aurora_port *port = (struct Aurora_port *) tty->driver_data;
-       struct Aurora_board *bp;
-       unsigned long flags;
-       unsigned char chip;
-
-#ifdef AURORA_DEBUG
-       printk("aurora_unthrottle: start\n");
-#endif
-       if ((aurora_paranoia_check(port, tty->name, "aurora_unthrottle"))
-               return;
-       
-       bp = port_Board(port);
-       
-       chip = AURORA_CD180(port_No(port));
-       
-       save_flags(flags); cli();
-       port->MSVR |= bp->RTS;
-       sbus_writeb(port_No(port) & 7,
-                   &bp->r[chip]->r[CD180_CAR]);
-       udelay(1);
-       if (I_IXOFF(tty))  {
-               aurora_wait_CCR(bp->r[chip]);
-               sbus_writeb(CCR_SSCH1,
-                           &bp->r[chip]->r[CD180_CCR]);
-               aurora_wait_CCR(bp->r[chip]);
-       }
-       sbus_writeb(port->MSVR, &bp->r[chip]->r[CD180_MSVR]);
-       restore_flags(flags);
-#ifdef AURORA_DEBUG
-       printk("aurora_unthrottle: end\n");
-#endif
-}
-
-static void aurora_stop(struct tty_struct * tty)
-{
-       struct Aurora_port *port = (struct Aurora_port *) tty->driver_data;
-       struct Aurora_board *bp;
-       unsigned long flags;
-       unsigned char chip;
-
-#ifdef AURORA_DEBUG
-       printk("aurora_stop: start\n");
-#endif
-       if ((aurora_paranoia_check(port, tty->name, "aurora_stop"))
-               return;
-       
-       bp = port_Board(port);
-       
-       chip = AURORA_CD180(port_No(port));
-       
-       save_flags(flags); cli();
-       port->SRER &= ~SRER_TXRDY;
-       sbus_writeb(port_No(port) & 7,
-                   &bp->r[chip]->r[CD180_CAR]);
-       udelay(1);
-       sbus_writeb(port->SRER,
-                   &bp->r[chip]->r[CD180_SRER]);
-       restore_flags(flags);
-#ifdef AURORA_DEBUG
-       printk("aurora_stop: end\n");
-#endif
-}
-
-static void aurora_start(struct tty_struct * tty)
-{
-       struct Aurora_port *port = (struct Aurora_port *) tty->driver_data;
-       struct Aurora_board *bp;
-       unsigned long flags;
-       unsigned char chip;
-
-#ifdef AURORA_DEBUG
-       printk("aurora_start: start\n");
-#endif
-       if ((aurora_paranoia_check(port, tty->name, "aurora_start"))
-               return;
-       
-       bp = port_Board(port);
-       
-       chip = AURORA_CD180(port_No(port));
-       
-       save_flags(flags); cli();
-       if (port->xmit_cnt && port->xmit_buf && !(port->SRER & SRER_TXRDY))  {
-               port->SRER |= SRER_TXRDY;
-               sbus_writeb(port_No(port) & 7,
-                           &bp->r[chip]->r[CD180_CAR]);
-               udelay(1);
-               sbus_writeb(port->SRER,
-                           &bp->r[chip]->r[CD180_SRER]);
-       }
-       restore_flags(flags);
-#ifdef AURORA_DEBUG
-       printk("aurora_start: end\n");
-#endif
-}
-
-/*
- * 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_aurora_hangup() -> tty->hangup() -> aurora_hangup()
- * 
- */
-static void do_aurora_hangup(void *private_)
-{
-       struct Aurora_port      *port = (struct Aurora_port *) private_;
-       struct tty_struct       *tty;
-
-#ifdef AURORA_DEBUG
-       printk("do_aurora_hangup: start\n");
-#endif
-       tty = port->tty;
-       if (tty != NULL) {
-               tty_hangup(tty);        /* FIXME: module removal race - AKPM */
-#ifdef AURORA_DEBUG
-               printk("do_aurora_hangup: end\n");
-#endif
-       }
-}
-
-static void aurora_hangup(struct tty_struct * tty)
-{
-       struct Aurora_port *port = (struct Aurora_port *) tty->driver_data;
-       struct Aurora_board *bp;
-                               
-#ifdef AURORA_DEBUG
-       printk("aurora_hangup: start\n");
-#endif
-       if ((aurora_paranoia_check(port, tty->name, "aurora_hangup"))
-               return;
-       
-       bp = port_Board(port);
-       
-       aurora_shutdown_port(bp, port);
-       port->event = 0;
-       port->count = 0;
-       port->flags &= ~ASYNC_NORMAL_ACTIVE;
-       port->tty = 0;
-       wake_up_interruptible(&port->open_wait);
-#ifdef AURORA_DEBUG
-       printk("aurora_hangup: end\n");
-#endif
-}
-
-static void aurora_set_termios(struct tty_struct * tty, struct termios * old_termios)
-{
-       struct Aurora_port *port = (struct Aurora_port *) tty->driver_data;
-       unsigned long flags;
-
-#ifdef AURORA_DEBUG
-       printk("aurora_set_termios: start\n");
-#endif
-       if ((aurora_paranoia_check(port, tty->name, "aurora_set_termios"))
-               return;
-       
-       if (tty->termios->c_cflag == old_termios->c_cflag &&
-           tty->termios->c_iflag == old_termios->c_iflag)
-               return;
-
-       save_flags(flags); cli();
-       aurora_change_speed(port_Board(port), port);
-       restore_flags(flags);
-
-       if ((old_termios->c_cflag & CRTSCTS) &&
-           !(tty->termios->c_cflag & CRTSCTS)) {
-               tty->hw_stopped = 0;
-               aurora_start(tty);
-       }
-#ifdef AURORA_DEBUG
-       printk("aurora_set_termios: end\n");
-#endif
-}
-
-static void do_aurora_bh(void)
-{
-        run_task_queue(&tq_aurora);
-}
-
-static void do_softint(void *private_)
-{
-       struct Aurora_port      *port = (struct Aurora_port *) private_;
-       struct tty_struct       *tty;
-
-#ifdef AURORA_DEBUG
-       printk("do_softint: start\n");
-#endif
-       tty = port->tty;
-       if (tty == NULL)
-               return;
-
-       if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &port->event)) {
-               tty_wakeup(tty);
-       }
-#ifdef AURORA_DEBUG
-       printk("do_softint: end\n");
-#endif
-}
-
-static const struct tty_operations aurora_ops = {
-       .open  = aurora_open,
-       .close = aurora_close,
-       .write = aurora_write,
-       .put_char = aurora_put_char,
-       .flush_chars = aurora_flush_chars,
-       .write_room = aurora_write_room,
-       .chars_in_buffer = aurora_chars_in_buffer,
-       .flush_buffer = aurora_flush_buffer,
-       .ioctl = aurora_ioctl,
-       .throttle = aurora_throttle,
-       .unthrottle = aurora_unthrottle,
-       .set_termios = aurora_set_termios,
-       .stop = aurora_stop,
-       .start = aurora_start,
-       .hangup = aurora_hangup,
-       .tiocmget = aurora_tiocmget,
-       .tiocmset = aurora_tiocmset,
-};
-
-static int aurora_init_drivers(void)
-{
-       int error;
-       int i;
-
-#ifdef AURORA_DEBUG
-       printk("aurora_init_drivers: start\n");
-#endif
-       tmp_buf = (unsigned char *) get_zeroed_page(GFP_KERNEL);
-       if (tmp_buf == NULL) {
-               printk(KERN_ERR "aurora: Couldn't get free page.\n");
-               return 1;
-       }
-       init_bh(AURORA_BH, do_aurora_bh);
-       aurora_driver = alloc_tty_driver(AURORA_INPORTS);
-       if (!aurora_driver) {
-               printk(KERN_ERR "aurora: Couldn't allocate tty driver.\n");
-               free_page((unsigned long) tmp_buf);
-               return 1;
-       }
-       aurora_driver->owner = THIS_MODULE;
-       aurora_driver->name = "ttyA";
-       aurora_driver->major = AURORA_MAJOR;
-       aurora_driver->type = TTY_DRIVER_TYPE_SERIAL;
-       aurora_driver->subtype = SERIAL_TYPE_NORMAL;
-       aurora_driver->init_termios = tty_std_termios;
-       aurora_driver->init_termios.c_cflag =
-               B9600 | CS8 | CREAD | HUPCL | CLOCAL;
-       aurora_driver->flags = TTY_DRIVER_REAL_RAW;
-       tty_set_operations(aurora_driver, &aurora_ops);
-       error = tty_register_driver(aurora_driver);
-       if (error) {
-               put_tty_driver(aurora_driver);
-               free_page((unsigned long) tmp_buf);
-               printk(KERN_ERR "aurora: Couldn't register aurora driver, error = %d\n",
-                      error);
-               return 1;
-       }
-       
-       memset(aurora_port, 0, sizeof(aurora_port));
-       for (i = 0; i < AURORA_TNPORTS; i++)  {
-               aurora_port[i].magic = AURORA_MAGIC;
-               aurora_port[i].tqueue.routine = do_softint;
-               aurora_port[i].tqueue.data = &aurora_port[i];
-               aurora_port[i].tqueue_hangup.routine = do_aurora_hangup;
-               aurora_port[i].tqueue_hangup.data = &aurora_port[i];
-               aurora_port[i].close_delay = 50 * HZ/100;
-               aurora_port[i].closing_wait = 3000 * HZ/100;
-               init_waitqueue_head(&aurora_port[i].open_wait);
-               init_waitqueue_head(&aurora_port[i].close_wait);
-       }
-#ifdef AURORA_DEBUG
-       printk("aurora_init_drivers: end\n");
-#endif
-       return 0;
-}
-
-static void aurora_release_drivers(void)
-{
-#ifdef AURORA_DEBUG
-       printk("aurora_release_drivers: start\n");
-#endif
-       free_page((unsigned long)tmp_buf);
-       tty_unregister_driver(aurora_driver);
-       put_tty_driver(aurora_driver);
-#ifdef AURORA_DEBUG
-       printk("aurora_release_drivers: end\n");
-#endif
-}
-
-/*
- * Called at boot time.
- *
- * You can specify IO base for up to RC_NBOARD cards,
- * using line "riscom8=0xiobase1,0xiobase2,.." at LILO prompt.
- * Note that there will be no probing at default
- * addresses in this case.
- *
- */
-void __init aurora_setup(char *str, int *ints)
-{
-       int i;
-
-       for(i=0;(i<ints[0])&&(i<4);i++) {
-               if (ints[i+1]) irqs[i]=ints[i+1];
-               }
-}
-
-static int __init aurora_real_init(void)
-{
-       int found;
-       int i;
-
-       printk(KERN_INFO "aurora: Driver starting.\n");
-       if(aurora_init_drivers())
-               return -EIO;
-       found = aurora_probe();
-       if(!found) {
-               aurora_release_drivers();
-               printk(KERN_INFO "aurora: No Aurora Multiport boards detected.\n");
-               return -EIO;
-       } else {
-               printk(KERN_INFO "aurora: %d boards found.\n", found);
-       }
-       for (i = 0; i < found; i++) {
-               int ret = aurora_setup_board(&aurora_board[i]);
-
-               if (ret) {
-#ifdef AURORA_DEBUG
-                       printk(KERN_ERR "aurora_init: error aurora_setup_board ret %d\n",
-                              ret);
-#endif
-                       return ret;
-               }
-       }
-       return 0;
-}
-
-int irq  = 0;
-int irq1 = 0;
-int irq2 = 0;
-int irq3 = 0;
-module_param(irq , int, 0);
-module_param(irq1, int, 0);
-module_param(irq2, int, 0);
-module_param(irq3, int, 0);
-
-static int __init aurora_init(void) 
-{
-       if (irq ) irqs[0]=irq ;
-       if (irq1) irqs[1]=irq1;
-       if (irq2) irqs[2]=irq2;
-       if (irq3) irqs[3]=irq3;
-       return aurora_real_init();
-}
-       
-static void __exit aurora_cleanup(void)
-{
-       int i;
-       
-#ifdef AURORA_DEBUG
-printk("cleanup_module: aurora_release_drivers\n");
-#endif
-
-       aurora_release_drivers();
-       for (i = 0; i < AURORA_NBOARD; i++)
-               if (aurora_board[i].flags & AURORA_BOARD_PRESENT) {
-                       aurora_shutdown_board(&aurora_board[i]);
-                       aurora_release_io_range(&aurora_board[i]);
-               }
-}
-
-module_init(aurora_init);
-module_exit(aurora_cleanup);
-MODULE_LICENSE("GPL");
diff --git a/drivers/sbus/char/aurora.h b/drivers/sbus/char/aurora.h
deleted file mode 100644 (file)
index b8b5476..0000000
+++ /dev/null
@@ -1,276 +0,0 @@
-/*     $Id: aurora.h,v 1.6 2001/06/05 12:23:38 davem Exp $
- *     linux/drivers/sbus/char/aurora.h -- Aurora multiport driver
- *
- *     Copyright (c) 1999 by Oliver Aldulea (oli@bv.ro)
- *
- *     This code is based on the RISCom/8 multiport serial driver written
- *     by Dmitry Gorodchanin (pgmdsg@ibi.com), based on the Linux serial
- *     driver, written by Linus Torvalds, Theodore T'so and others.
- *     The Aurora multiport programming info was obtained mainly from the
- *     Cirrus Logic CD180 documentation (available on the web), and by
- *     doing heavy tests on the board. Many thanks to Eddie C. Dost for the
- *     help on the sbus interface.
- *
- *     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.
- *
- *     Revision 1.0
- *
- *     This is the first public release.
- *
- *     This version needs a lot of feedback. This is the version that works
- *     with _my_ board. My board is model 1600se, revision '@(#)1600se.fth
- *     1.2 3/28/95 1'. The driver might work with your board, but I do not
- *     guarantee it. If you have _any_ type of board, I need to know if the
- *     driver works or not, I need to know exactly your board parameters
- *     (get them with 'cd /proc/openprom/iommu/sbus/sio16/; ls *; cat *')
- *     Also, I need your board revision code, which is written on the board.
- *     Send me the output of my driver too (it outputs through klogd).
- *
- *     If the driver does not work, you can try enabling the debug options
- *     to see what's wrong or what should be done.
- *
- *     I'm sorry about the alignment of the code. It was written in a
- *     128x48 environment.
- *
- *     I must say that I do not like Aurora Technologies' policy. I asked
- *     them to help me do this driver faster, but they ended by something
- *     like "don't call us, we'll call you", and I never heard anything
- *     from them. They told me "knowing the way the board works, I don't
- *     doubt you and others on the net will make the driver."
- *     The truth about this board is that it has nothing intelligent on it.
- *     If you want to say to somebody what kind of board you have, say that
- *     it uses Cirrus Logic processors (CD180). The power of the board is
- *     in those two chips. The rest of the board is the interface to the
- *     sbus and to the peripherals. Still, they did something smart: they
- *     reversed DTR and RTS to make on-board automatic hardware flow
- *     control usable.
- *     Thanks to Aurora Technologies for wasting my time, nerves and money.
- */
-
-#ifndef __LINUX_AURORA_H
-#define __LINUX_AURORA_H
-
-#include <linux/serial.h>
-#include <linux/serialP.h>
-
-#ifdef __KERNEL__
-
-/* This is the number of boards to support. I've only tested this driver with
- * one board, so it might not work.
- */
-#define AURORA_NBOARD 1
-
-/* Useful ? Yes. But you can safely comment the warnings if they annoy you
- * (let me say that again: the warnings in the code, not this define). 
- */
-#define AURORA_PARANOIA_CHECK
-
-/* Well, after many lost nights, I found that the IRQ for this board is
- * selected from four built-in values by writing some bits in the
- * configuration register. This causes a little problem to occur: which
- * IRQ to select ? Which one is the best for the user ? Well, I finally
- * decided for the following algorithm: if the "bintr" value is not acceptable
- * (not within type_1_irq[], then test the "intr" value, if that fails too,
- * try each value from type_1_irq until succeded. Hope it's ok.
- * You can safely reorder the irq's.
- */
-#define TYPE_1_IRQS 4
-unsigned char type_1_irq[TYPE_1_IRQS] = {
-       3, 5, 9, 13
-};
-/* I know something about another method of interrupt setting, but not enough.
- * Also, this is for another type of board, so I first have to learn how to
- * detect it.
-#define TYPE_2_IRQS 3
-unsigned char type_2_irq[TYPE_2_IRQS] = {
-       0, 0, 0 ** could anyone find these for me ? (see AURORA_ALLIRQ below) **
-       };
-unsigned char type_2_mask[TYPE_2_IRQS] = {
-       32, 64, 128
-       };
-*/
-
-/* The following section should only be modified by those who know what
- * they're doing (or don't, but want to help with some feedback). Modifying
- * anything raises a _big_ probability for your system to hang, but the
- * sacrifice worths. (I sacrificed my ext2fs many, many times...)
- */
-
-/* This one tries to dump to console the name of almost every function called,
- * and many other debugging info.
- */
-#undef AURORA_DEBUG
-
-/* These are the most dangerous and useful defines. They do printk() during
- * the interrupt processing routine(s), so if you manage to get "flooded" by
- * irq's, start thinking about the "Power off/on" button...
- */
-#undef AURORA_INTNORM  /* This one enables the "normal" messages, but some
-                        * of them cause flood, so I preffered putting
-                        * them under a define */
-#undef AURORA_INT_DEBUG /* This one is really bad. */
-
-/* Here's something helpful: after n irq's, the board will be disabled. This
- * prevents irq flooding during debug (no need to think about power
- * off/on anymore...)
- */
-#define AURORA_FLOODPRO        10
-
-/* This one helps finding which irq the board calls, in case of a strange/
- * unsupported board. AURORA_INT_DEBUG should be enabled, because I don't
- * think /proc/interrupts or any command will be available in case of an irq
- * flood... "allirq" is the list of all free irq's.
- */
-/*
-#define AURORA_ALLIRQ 6
-int allirq[AURORA_ALLIRQ]={
-       2,3,5,7,9,13
-       };
-*/
-
-/* These must not be modified. These values are assumed during the code for
- * performance optimisations.
- */
-#define AURORA_NCD180 2 /* two chips per board */
-#define AURORA_NPORT 8  /* 8 ports per chip */
-
-/* several utilities */
-#define AURORA_BOARD(line)     (((line) >> 4) & 0x01)
-#define AURORA_CD180(line)     (((line) >> 3) & 0x01)
-#define AURORA_PORT(line)      ((line) & 15)
-
-#define AURORA_TNPORTS (AURORA_NBOARD*AURORA_NCD180*AURORA_NPORT)
-
-/* Ticks per sec. Used for setting receiver timeout and break length */
-#define AURORA_TPS             4000
-
-#define AURORA_MAGIC   0x0A18
-
-/* Yeah, after heavy testing I decided it must be 6.
- * Sure, You can change it if needed.
- */
-#define AURORA_RXFIFO          6       /* Max. receiver FIFO size (1-8) */
-
-#define AURORA_RXTH            7
-
-struct aurora_reg1 {
-       __volatile__ unsigned char r;
-};
-
-struct aurora_reg128 {
-       __volatile__ unsigned char r[128];
-};
-       
-struct aurora_reg4 {
-       __volatile__ unsigned char r[4];
-};
-
-struct Aurora_board {
-       unsigned long           flags;
-       struct aurora_reg1      * r0;   /* This is the board configuration
-                                        * register (write-only). */
-       struct aurora_reg128    * r[2]; /* These are the registers for the
-                                        * two chips. */
-       struct aurora_reg4      * r3;   /* These are used for hardware-based
-                                        * acknowledge. Software-based ack is
-                                        * not supported by CD180. */
-       unsigned int            oscfreq; /* The on-board oscillator
-                                         * frequency, in Hz. */
-       unsigned char           irq;
-#ifdef MODULE
-       signed char             count;  /* counts the use of the board */
-#endif
-       /* Values for the dtr_rts swapped mode. */
-       unsigned char           DTR;
-       unsigned char           RTS;
-       unsigned char           MSVDTR;
-       unsigned char           MSVRTS;
-       /* Values for hardware acknowledge. */
-       unsigned char           ACK_MINT, ACK_TINT, ACK_RINT;
-};
-
-/* Board configuration register */
-#define AURORA_CFG_ENABLE_IO   8
-#define AURORA_CFG_ENABLE_IRQ  4
-
-/* Board flags */
-#define AURORA_BOARD_PRESENT           0x00000001
-#define AURORA_BOARD_ACTIVE            0x00000002
-#define AURORA_BOARD_TYPE_2            0x00000004      /* don't know how to
-                                                        * detect this yet */
-#define AURORA_BOARD_DTR_FLOW_OK       0x00000008
-
-/* The story goes like this: Cirrus programmed the CD-180 chip to do automatic
- * hardware flow control, and do it using CTS and DTR. CTS is ok, but, if you
- * have a modem and the chip drops DTR, then the modem will drop the carrier
- * (ain't that cute...). Luckily, the guys at Aurora decided to swap DTR and
- * RTS, which makes the flow control usable. I hope that all the boards made
- * by Aurora have these two signals swapped. If your's doesn't but you have a
- * breakout box, you can try to reverse them yourself, then set the following
- * flag.
- */
-#undef AURORA_FORCE_DTR_FLOW
-
-/* In fact, a few more words have to be said about hardware flow control.
- * This driver handles "output" flow control through the on-board facility
- * CTS Auto Enable. For the "input" flow control there are two cases when
- * the flow should be controlled. The first case is when the kernel is so
- * busy that it cannot process IRQ's in time; this flow control can only be
- * activated by the on-board chip, and if the board has RTS and DTR swapped,
- * this facility is usable. The second case is when the application is so
- * busy that it cannot receive bytes from the kernel, and this flow must be
- * activated by software. This second case is not yet implemented in this
- * driver. Unfortunately, I estimate that the second case is the one that
- * occurs the most.
- */
-
-
-struct Aurora_port {
-       int                     magic;
-       int                     baud_base;
-       int                     flags;
-       struct tty_struct       * tty;
-       int                     count;
-       int                     blocked_open;
-       long                    event;
-       int                     timeout;
-       int                     close_delay;
-       unsigned char           * xmit_buf;
-       int                     custom_divisor;
-       int                     xmit_head;
-       int                     xmit_tail;
-       int                     xmit_cnt;
-       wait_queue_head_t       open_wait;
-       wait_queue_head_t       close_wait;
-       struct tq_struct        tqueue;
-       struct tq_struct        tqueue_hangup;
-       short                   wakeup_chars;
-       short                   break_length;
-       unsigned short          closing_wait;
-       unsigned char           mark_mask;
-       unsigned char           SRER;
-       unsigned char           MSVR;
-       unsigned char           COR2;
-#ifdef AURORA_REPORT_OVERRUN
-       unsigned long           overrun;
-#endif 
-#ifdef AURORA_REPORT_FIFO
-       unsigned long           hits[10];
-#endif
-};
-
-#endif
-#endif /*__LINUX_AURORA_H*/
-
index 22631f8..8410587 100644 (file)
@@ -187,19 +187,20 @@ static int wait_for_pin(struct bbc_i2c_bus *bp, u8 *status)
        bp->waiting = 1;
        add_wait_queue(&bp->wq, &wait);
        while (limit-- > 0) {
-               u8 val;
-
-               set_current_state(TASK_INTERRUPTIBLE);
-               *status = val = readb(bp->i2c_control_regs + 0);
-               if ((val & I2C_PCF_PIN) == 0) {
+               unsigned long val;
+
+               val = wait_event_interruptible_timeout(
+                               bp->wq,
+                               (((*status = readb(bp->i2c_control_regs + 0))
+                                 & I2C_PCF_PIN) == 0),
+                               msecs_to_jiffies(250));
+               if (val > 0) {
                        ret = 0;
                        break;
                }
-               msleep_interruptible(250);
        }
        remove_wait_queue(&bp->wq, &wait);
        bp->waiting = 0;
-       current->state = TASK_RUNNING;
 
        return ret;
 }
@@ -340,7 +341,7 @@ static irqreturn_t bbc_i2c_interrupt(int irq, void *dev_id)
         */
        if (bp->waiting &&
            !(readb(bp->i2c_control_regs + 0x0) & I2C_PCF_PIN))
-               wake_up(&bp->wq);
+               wake_up_interruptible(&bp->wq);
 
        return IRQ_HANDLED;
 }
diff --git a/drivers/sbus/char/cd180.h b/drivers/sbus/char/cd180.h
deleted file mode 100644 (file)
index 445b86c..0000000
+++ /dev/null
@@ -1,240 +0,0 @@
-
-/* Definitions for Cirrus Logic CL-CD180 8-port async mux chip */
-#define CD180_NCH       8       /* Total number of channels                */
-#define CD180_TPC       16      /* Ticks per character                     */
-#define CD180_NFIFO    8       /* TX FIFO size                            */
-
-/* Global registers */
-#define CD180_GFRCR    0x6b    /* Global Firmware Revision Code Register  */
-#define CD180_SRCR     0x66    /* Service Request Configuration Register  */
-#define CD180_PPRH     0x70    /* Prescaler Period Register High          */
-#define CD180_PPRL     0x71    /* Prescaler Period Register Low           */
-#define CD180_MSMR     0x61    /* Modem Service Match Register            */
-#define CD180_TSMR     0x62    /* Transmit Service Match Register         */
-#define CD180_RSMR     0x63    /* Receive Service Match Register          */
-#define CD180_GSVR     0x40    /* Global Service Vector Register          */
-#define CD180_SRSR     0x65    /* Service Request Status Register         */
-#define CD180_GSCR     0x41    /* Global Service Channel Register         */
-#define CD180_CAR      0x64    /* Channel Access Register                 */
-
-/* Indexed registers */
-#define CD180_RDCR     0x07    /* Receive Data Count Register             */
-#define CD180_RDR      0x78    /* Receiver Data Register                  */
-#define CD180_RCSR     0x7a    /* Receiver Character Status Register      */
-#define CD180_TDR      0x7b    /* Transmit Data Register                  */
-#define CD180_EOSRR    0x7f    /* End of Service Request Register         */
-
-/* Channel Registers */
-#define CD180_SRER      0x02    /* Service Request Enable Register         */
-#define CD180_CCR       0x01    /* Channel Command Register                */
-#define CD180_COR1      0x03    /* Channel Option Register 1               */
-#define CD180_COR2      0x04    /* Channel Option Register 2               */
-#define CD180_COR3      0x05    /* Channel Option Register 3               */
-#define CD180_CCSR      0x06    /* Channel Control Status Register         */
-#define CD180_RTPR      0x18    /* Receive Timeout Period Register         */
-#define CD180_RBPRH     0x31    /* Receive Bit Rate Period Register High  */
-#define CD180_RBPRL     0x32    /* Receive Bit Rate Period Register Low   */
-#define CD180_TBPRH     0x39    /* Transmit Bit Rate Period Register High */
-#define CD180_TBPRL     0x3a    /* Transmit Bit Rate Period Register Low  */
-#define CD180_SCHR1     0x09    /* Special Character Register 1            */
-#define CD180_SCHR2     0x0a    /* Special Character Register 2            */
-#define CD180_SCHR3     0x0b    /* Special Character Register 3            */
-#define CD180_SCHR4     0x0c    /* Special Character Register 4            */
-#define CD180_MCR       0x12    /* Modem Change Register                   */
-#define CD180_MCOR1     0x10    /* Modem Change Option 1 Register          */
-#define CD180_MCOR2     0x11    /* Modem Change Option 2 Register          */
-#define CD180_MSVR      0x28    /* Modem Signal Value Register             */
-#define CD180_MSVRTS    0x29    /* Modem Signal Value RTS                  */
-#define CD180_MSVDTR    0x2a    /* Modem Signal Value DTR                  */
-
-/* Global Interrupt Vector Register (R/W) */
-
-#define GSVR_ITMASK     0x07     /* Interrupt type mask                     */
-#define  GSVR_IT_MDM     0x01    /* Modem Signal Change Interrupt           */
-#define  GSVR_IT_TX      0x02    /* Transmit Data Interrupt                 */
-#define  GSVR_IT_RGD     0x03    /* Receive Good Data Interrupt             */
-#define  GSVR_IT_REXC    0x07    /* Receive Exception Interrupt             */
-
-
-/* Global Interrupt Channel Register (R/W) */
-#define GSCR_CHAN       0x1c    /* Channel Number Mask                     */
-#define GSCR_CHAN_OFF   2       /* Channel Number Offset                   */
-
-
-/* Channel Address Register (R/W) */
-
-#define CAR_CHAN        0x07    /* Channel Number Mask                     */
-
-
-/* Receive Character Status Register (R/O) */
-
-#define RCSR_TOUT       0x80    /* Rx Timeout                              */
-#define RCSR_SCDET      0x70    /* Special Character Detected Mask         */
-#define  RCSR_NO_SC      0x00   /* No Special Characters Detected          */
-#define  RCSR_SC_1       0x10   /* Special Char 1 (or 1 & 3) Detected      */
-#define  RCSR_SC_2       0x20   /* Special Char 2 (or 2 & 4) Detected      */
-#define  RCSR_SC_3       0x30   /* Special Char 3 Detected                 */
-#define  RCSR_SC_4       0x40   /* Special Char 4 Detected                 */
-#define RCSR_BREAK      0x08    /* Break has been detected                 */
-#define RCSR_PE         0x04    /* Parity Error                            */
-#define RCSR_FE         0x02    /* Frame Error                             */
-#define RCSR_OE         0x01    /* Overrun Error                           */
-
-
-/* Channel Command Register (R/W) (commands in groups can be OR-ed) */
-
-#define CCR_HARDRESET   0x81    /* Reset the chip                          */
-
-#define CCR_SOFTRESET   0x80    /* Soft Channel Reset                      */
-
-#define CCR_CORCHG1     0x42    /* Channel Option Register 1 Changed       */
-#define CCR_CORCHG2     0x44    /* Channel Option Register 2 Changed       */
-#define CCR_CORCHG3     0x48    /* Channel Option Register 3 Changed       */
-
-#define CCR_SSCH1       0x21    /* Send Special Character 1                */
-
-#define CCR_SSCH2       0x22    /* Send Special Character 2                */
-
-#define CCR_SSCH3       0x23    /* Send Special Character 3                */
-
-#define CCR_SSCH4       0x24    /* Send Special Character 4                */
-
-#define CCR_TXEN        0x18    /* Enable Transmitter                      */
-#define CCR_RXEN        0x12    /* Enable Receiver                         */
-
-#define CCR_TXDIS       0x14    /* Disable Transmitter                     */
-#define CCR_RXDIS       0x11    /* Disable Receiver                        */
-
-
-/* Service Request Enable Register (R/W) */
-
-#define SRER_DSR         0x80    /* Enable interrupt on DSR change          */
-#define SRER_CD          0x40    /* Enable interrupt on CD change           */
-#define SRER_CTS         0x20    /* Enable interrupt on CTS change          */
-#define SRER_RXD         0x10    /* Enable interrupt on Receive Data        */
-#define SRER_RXSC        0x08    /* Enable interrupt on Receive Spec. Char  */
-#define SRER_TXRDY       0x04    /* Enable interrupt on TX FIFO empty       */
-#define SRER_TXEMPTY     0x02    /* Enable interrupt on TX completely empty */
-#define SRER_RET         0x01    /* Enable interrupt on RX Exc. Timeout     */
-
-
-/* Channel Option Register 1 (R/W) */
-
-#define COR1_ODDP       0x80    /* Odd Parity                              */
-#define COR1_PARMODE    0x60    /* Parity Mode mask                        */
-#define  COR1_NOPAR      0x00   /* No Parity                               */
-#define  COR1_FORCEPAR   0x20   /* Force Parity                            */
-#define  COR1_NORMPAR    0x40   /* Normal Parity                           */
-#define COR1_IGNORE     0x10    /* Ignore Parity on RX                     */
-#define COR1_STOPBITS   0x0c    /* Number of Stop Bits                     */
-#define  COR1_1SB        0x00   /* 1 Stop Bit                              */
-#define  COR1_15SB       0x04   /* 1.5 Stop Bits                           */
-#define  COR1_2SB        0x08   /* 2 Stop Bits                             */
-#define COR1_CHARLEN    0x03    /* Character Length                        */
-#define  COR1_5BITS      0x00   /* 5 bits                                  */
-#define  COR1_6BITS      0x01   /* 6 bits                                  */
-#define  COR1_7BITS      0x02   /* 7 bits                                  */
-#define  COR1_8BITS      0x03   /* 8 bits                                  */
-
-
-/* Channel Option Register 2 (R/W) */
-
-#define COR2_IXM        0x80    /* Implied XON mode                        */
-#define COR2_TXIBE      0x40    /* Enable In-Band (XON/XOFF) Flow Control  */
-#define COR2_ETC        0x20    /* Embedded Tx Commands Enable             */
-#define COR2_LLM        0x10    /* Local Loopback Mode                     */
-#define COR2_RLM        0x08    /* Remote Loopback Mode                    */
-#define COR2_RTSAO      0x04    /* RTS Automatic Output Enable             */
-#define COR2_CTSAE      0x02    /* CTS Automatic Enable                    */
-#define COR2_DSRAE      0x01    /* DSR Automatic Enable                    */
-
-
-/* Channel Option Register 3 (R/W) */
-
-#define COR3_XONCH      0x80    /* XON is a pair of characters (1 & 3)     */
-#define COR3_XOFFCH     0x40    /* XOFF is a pair of characters (2 & 4)    */
-#define COR3_FCT        0x20    /* Flow-Control Transparency Mode          */
-#define COR3_SCDE       0x10    /* Special Character Detection Enable      */
-#define COR3_RXTH       0x0f    /* RX FIFO Threshold value (1-8)           */
-
-
-/* Channel Control Status Register (R/O) */
-
-#define CCSR_RXEN       0x80    /* Receiver Enabled                        */
-#define CCSR_RXFLOFF    0x40    /* Receive Flow Off (XOFF was sent)        */
-#define CCSR_RXFLON     0x20    /* Receive Flow On (XON was sent)          */
-#define CCSR_TXEN       0x08    /* Transmitter Enabled                     */
-#define CCSR_TXFLOFF    0x04    /* Transmit Flow Off (got XOFF)            */
-#define CCSR_TXFLON     0x02    /* Transmit Flow On (got XON)              */
-
-
-/* Modem Change Option Register 1 (R/W) */
-
-#define MCOR1_DSRZD     0x80    /* Detect 0->1 transition of DSR           */
-#define MCOR1_CDZD      0x40    /* Detect 0->1 transition of CD            */
-#define MCOR1_CTSZD     0x20    /* Detect 0->1 transition of CTS           */
-#define MCOR1_DTRTH     0x0f    /* Auto DTR flow control Threshold (1-8)   */
-#define  MCOR1_NODTRFC   0x0     /* Automatic DTR flow control disabled     */
-
-
-/* Modem Change Option Register 2 (R/W) */
-
-#define MCOR2_DSROD     0x80    /* Detect 1->0 transition of DSR           */
-#define MCOR2_CDOD      0x40    /* Detect 1->0 transition of CD            */
-#define MCOR2_CTSOD     0x20    /* Detect 1->0 transition of CTS           */
-
-
-/* Modem Change Register (R/W) */
-
-#define MCR_DSRCHG      0x80    /* DSR Changed                             */
-#define MCR_CDCHG       0x40    /* CD Changed                              */
-#define MCR_CTSCHG      0x20    /* CTS Changed                             */
-
-
-/* Modem Signal Value Register (R/W) */
-
-#define MSVR_DSR        0x80    /* Current state of DSR input              */
-#define MSVR_CD         0x40    /* Current state of CD input               */
-#define MSVR_CTS        0x20    /* Current state of CTS input              */
-#define MSVR_DTR        0x02    /* Current state of DTR output             */
-#define MSVR_RTS        0x01    /* Current state of RTS output             */
-
-
-/* Service Request Status Register */
-
-#define SRSR_CMASK     0xC0    /* Current Service Context Mask            */
-#define  SRSR_CNONE    0x00    /* Not in a service context                */
-#define  SRSR_CRX      0x40    /* Rx Context                              */
-#define  SRSR_CTX      0x80    /* Tx Context                              */
-#define  SRSR_CMDM     0xC0    /* Modem Context                           */
-#define SRSR_ANYINT    0x6F    /* Any interrupt flag                      */
-#define SRSR_RINT      0x10    /* Receive Interrupt                       */
-#define SRSR_TINT      0x04    /* Transmit Interrupt                      */
-#define SRSR_MINT      0x01    /* Modem Interrupt                         */
-#define SRSR_REXT      0x20    /* Receive External Interrupt              */
-#define SRSR_TEXT      0x08    /* Transmit External Interrupt             */
-#define SRSR_MEXT      0x02    /* Modem External Interrupt                */
-
-
-/* Service Request Configuration Register */
-
-#define SRCR_PKGTYPE    0x80
-#define SRCR_REGACKEN   0x40
-#define SRCR_DAISYEN    0x20
-#define SRCR_GLOBPRI    0x10
-#define SRCR_UNFAIR     0x08
-#define SRCR_AUTOPRI    0x02
-#define SRCR_PRISEL     0x01
-
-/* Values for register-based Interrupt ACKs */
-#define CD180_ACK_MINT 0x75    /* goes to MSMR                            */
-#define CD180_ACK_TINT 0x76    /* goes to TSMR                            */
-#define CD180_ACK_RINT 0x77    /* goes to RSMR                            */
-
-/* Escape characters */
-
-#define CD180_C_ESC     0x00    /* Escape character                        */
-#define CD180_C_SBRK    0x81    /* Start sending BREAK                     */
-#define CD180_C_DELAY   0x82    /* Delay output                            */
-#define CD180_C_EBRK    0x83    /* Stop sending BREAK                      */
index 45cf5bc..44d2ef9 100644 (file)
@@ -364,6 +364,7 @@ static int __init ts102_uctrl_init(void)
        struct linux_prom_irqs tmp_irq[2];
         unsigned int vaddr[2] = { 0, 0 };
        int tmpnode, uctrlnode = prom_getchild(prom_root_node);
+       int err;
 
        tmpnode = prom_searchsiblings(uctrlnode, "obio");
 
@@ -389,7 +390,12 @@ static int __init ts102_uctrl_init(void)
        if(!driver->irq) 
                driver->irq = tmp_irq[0].pri;
 
-       request_irq(driver->irq, uctrl_interrupt, 0, "uctrl", driver);
+       err = request_irq(driver->irq, uctrl_interrupt, 0, "uctrl", driver);
+       if (err) {
+               printk("%s: unable to register irq %d\n",
+                      __FUNCTION__, driver->irq);
+               return err;
+       }
 
        if (misc_register(&uctrl_dev)) {
                printk("%s: unable to get misc minor %d\n",
index f4440d3..509ace7 100644 (file)
@@ -38,6 +38,8 @@
  *             Fix some spin_locks.
  *             Do not call uart_add_one_port for absent ports.
  *     1.07    Use CONFIG_SERIAL_TXX9_NR_UARTS.  Cleanup.
+ *     1.08    Use platform_device.
+ *             Fix and cleanup suspend/resume/initialization codes.
  */
 
 #if defined(CONFIG_SERIAL_TXX9_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
@@ -50,7 +52,7 @@
 #include <linux/console.h>
 #include <linux/sysrq.h>
 #include <linux/delay.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 #include <linux/pci.h>
 #include <linux/tty.h>
 #include <linux/tty_flip.h>
@@ -60,7 +62,7 @@
 
 #include <asm/io.h>
 
-static char *serial_version = "1.07";
+static char *serial_version = "1.08";
 static char *serial_name = "TX39/49 Serial driver";
 
 #define PASS_LIMIT     256
@@ -94,12 +96,7 @@ static char *serial_name = "TX39/49 Serial driver";
 
 struct uart_txx9_port {
        struct uart_port        port;
-
-       /*
-        * We provide a per-port pm hook.
-        */
-       void                    (*pm)(struct uart_port *port,
-                                     unsigned int state, unsigned int old);
+       /* No additional info for now */
 };
 
 #define TXX9_REGION_SIZE       0x24
@@ -277,6 +274,31 @@ static void serial_txx9_enable_ms(struct uart_port *port)
        /* TXX9-SIO can not control DTR... */
 }
 
+static void serial_txx9_initialize(struct uart_port *port)
+{
+       struct uart_txx9_port *up = (struct uart_txx9_port *)port;
+       unsigned int tmout = 10000;
+
+       sio_out(up, TXX9_SIFCR, TXX9_SIFCR_SWRST);
+       /* TX4925 BUG WORKAROUND.  Accessing SIOC register
+        * immediately after soft reset causes bus error. */
+       mmiowb();
+       udelay(1);
+       while ((sio_in(up, TXX9_SIFCR) & TXX9_SIFCR_SWRST) && --tmout)
+               udelay(1);
+       /* TX Int by FIFO Empty, RX Int by Receiving 1 char. */
+       sio_set(up, TXX9_SIFCR,
+               TXX9_SIFCR_TDIL_MAX | TXX9_SIFCR_RDIL_1);
+       /* initial settings */
+       sio_out(up, TXX9_SILCR,
+               TXX9_SILCR_UMODE_8BIT | TXX9_SILCR_USBL_1BIT |
+               ((up->port.flags & UPF_TXX9_USE_SCLK) ?
+                TXX9_SILCR_SCS_SCLK_BG : TXX9_SILCR_SCS_IMCLK_BG));
+       sio_quot_set(up, uart_get_divisor(port, 9600));
+       sio_out(up, TXX9_SIFLCR, TXX9_SIFLCR_RTSTL_MAX /* 15 */);
+       sio_out(up, TXX9_SIDICR, 0);
+}
+
 static inline void
 receive_chars(struct uart_txx9_port *up, unsigned int *status)
 {
@@ -657,9 +679,8 @@ static void
 serial_txx9_pm(struct uart_port *port, unsigned int state,
              unsigned int oldstate)
 {
-       struct uart_txx9_port *up = (struct uart_txx9_port *)port;
-       if (up->pm)
-               up->pm(port, state, oldstate);
+       if (state == 0)
+               serial_txx9_initialize(port);
 }
 
 static int serial_txx9_request_resource(struct uart_txx9_port *up)
@@ -732,7 +753,6 @@ static int serial_txx9_request_port(struct uart_port *port)
 static void serial_txx9_config_port(struct uart_port *port, int uflags)
 {
        struct uart_txx9_port *up = (struct uart_txx9_port *)port;
-       unsigned long flags;
        int ret;
 
        /*
@@ -749,30 +769,7 @@ static void serial_txx9_config_port(struct uart_port *port, int uflags)
        if (up->port.line == up->port.cons->index)
                return;
 #endif
-       spin_lock_irqsave(&up->port.lock, flags);
-       /*
-        * Reset the UART.
-        */
-       sio_out(up, TXX9_SIFCR, TXX9_SIFCR_SWRST);
-#ifdef CONFIG_CPU_TX49XX
-       /* TX4925 BUG WORKAROUND.  Accessing SIOC register
-        * immediately after soft reset causes bus error. */
-       iob();
-       udelay(1);
-#endif
-       while (sio_in(up, TXX9_SIFCR) & TXX9_SIFCR_SWRST)
-               ;
-       /* TX Int by FIFO Empty, RX Int by Receiving 1 char. */
-       sio_set(up, TXX9_SIFCR,
-               TXX9_SIFCR_TDIL_MAX | TXX9_SIFCR_RDIL_1);
-       /* initial settings */
-       sio_out(up, TXX9_SILCR,
-               TXX9_SILCR_UMODE_8BIT | TXX9_SILCR_USBL_1BIT |
-               ((up->port.flags & UPF_TXX9_USE_SCLK) ?
-                TXX9_SILCR_SCS_SCLK_BG : TXX9_SILCR_SCS_IMCLK_BG));
-       sio_quot_set(up, uart_get_divisor(port, 9600));
-       sio_out(up, TXX9_SIFLCR, TXX9_SIFLCR_RTSTL_MAX /* 15 */);
-       spin_unlock_irqrestore(&up->port.lock, flags);
+       serial_txx9_initialize(port);
 }
 
 static int
@@ -818,7 +815,8 @@ static struct uart_ops serial_txx9_pops = {
 
 static struct uart_txx9_port serial_txx9_ports[UART_NR];
 
-static void __init serial_txx9_register_ports(struct uart_driver *drv)
+static void __init serial_txx9_register_ports(struct uart_driver *drv,
+                                             struct device *dev)
 {
        int i;
 
@@ -827,6 +825,7 @@ static void __init serial_txx9_register_ports(struct uart_driver *drv)
 
                up->port.line = i;
                up->port.ops = &serial_txx9_pops;
+               up->port.dev = dev;
                if (up->port.iobase || up->port.mapbase)
                        uart_add_one_port(drv, &up->port);
        }
@@ -898,7 +897,7 @@ serial_txx9_console_write(struct console *co, const char *s, unsigned int count)
        sio_out(up, TXX9_SIDICR, ier);
 }
 
-static int serial_txx9_console_setup(struct console *co, char *options)
+static int __init serial_txx9_console_setup(struct console *co, char *options)
 {
        struct uart_port *port;
        struct uart_txx9_port *up;
@@ -919,17 +918,7 @@ static int serial_txx9_console_setup(struct console *co, char *options)
        if (!port->ops)
                return -ENODEV;
 
-       /*
-        *      Disable UART interrupts, set DTR and RTS high
-        *      and set speed.
-        */
-       sio_out(up, TXX9_SIDICR, 0);
-       /* initial settings */
-       sio_out(up, TXX9_SILCR,
-               TXX9_SILCR_UMODE_8BIT | TXX9_SILCR_USBL_1BIT |
-               ((port->flags & UPF_TXX9_USE_SCLK) ?
-                TXX9_SILCR_SCS_SCLK_BG : TXX9_SILCR_SCS_IMCLK_BG));
-       sio_out(up, TXX9_SIFLCR, TXX9_SIFLCR_RTSTL_MAX /* 15 */);
+       serial_txx9_initialize(&up->port);
 
        if (options)
                uart_parse_options(options, &baud, &parity, &bits, &flow);
@@ -981,31 +970,6 @@ int __init early_serial_txx9_setup(struct uart_port *port)
        return 0;
 }
 
-#ifdef ENABLE_SERIAL_TXX9_PCI
-#ifdef CONFIG_PM
-/**
- *     serial_txx9_suspend_port - suspend one serial port
- *     @line:  serial line number
- *
- *     Suspend one serial port.
- */
-static void serial_txx9_suspend_port(int line)
-{
-       uart_suspend_port(&serial_txx9_reg, &serial_txx9_ports[line].port);
-}
-
-/**
- *     serial_txx9_resume_port - resume one serial port
- *     @line:  serial line number
- *
- *     Resume one serial port.
- */
-static void serial_txx9_resume_port(int line)
-{
-       uart_resume_port(&serial_txx9_reg, &serial_txx9_ports[line].port);
-}
-#endif
-
 static DEFINE_MUTEX(serial_txx9_mutex);
 
 /**
@@ -1028,8 +992,18 @@ static int __devinit serial_txx9_register_port(struct uart_port *port)
        mutex_lock(&serial_txx9_mutex);
        for (i = 0; i < UART_NR; i++) {
                uart = &serial_txx9_ports[i];
-               if (!(uart->port.iobase || uart->port.mapbase))
+               if (uart_match_port(&uart->port, port)) {
+                       uart_remove_one_port(&serial_txx9_reg, &uart->port);
                        break;
+               }
+       }
+       if (i == UART_NR) {
+               /* Find unused port */
+               for (i = 0; i < UART_NR; i++) {
+                       uart = &serial_txx9_ports[i];
+                       if (!(uart->port.iobase || uart->port.mapbase))
+                               break;
+               }
        }
        if (i < UART_NR) {
                uart->port.iobase = port->iobase;
@@ -1071,6 +1045,95 @@ static void __devexit serial_txx9_unregister_port(int line)
        mutex_unlock(&serial_txx9_mutex);
 }
 
+/*
+ * Register a set of serial devices attached to a platform device.
+ */
+static int __devinit serial_txx9_probe(struct platform_device *dev)
+{
+       struct uart_port *p = dev->dev.platform_data;
+       struct uart_port port;
+       int ret, i;
+
+       memset(&port, 0, sizeof(struct uart_port));
+       for (i = 0; p && p->uartclk != 0; p++, i++) {
+               port.iobase     = p->iobase;
+               port.membase    = p->membase;
+               port.irq        = p->irq;
+               port.uartclk    = p->uartclk;
+               port.iotype     = p->iotype;
+               port.flags      = p->flags;
+               port.mapbase    = p->mapbase;
+               port.dev        = &dev->dev;
+               ret = serial_txx9_register_port(&port);
+               if (ret < 0) {
+                       dev_err(&dev->dev, "unable to register port at index %d "
+                               "(IO%x MEM%lx IRQ%d): %d\n", i,
+                               p->iobase, p->mapbase, p->irq, ret);
+               }
+       }
+       return 0;
+}
+
+/*
+ * Remove serial ports registered against a platform device.
+ */
+static int __devexit serial_txx9_remove(struct platform_device *dev)
+{
+       int i;
+
+       for (i = 0; i < UART_NR; i++) {
+               struct uart_txx9_port *up = &serial_txx9_ports[i];
+
+               if (up->port.dev == &dev->dev)
+                       serial_txx9_unregister_port(i);
+       }
+       return 0;
+}
+
+#ifdef CONFIG_PM
+static int serial_txx9_suspend(struct platform_device *dev, pm_message_t state)
+{
+       int i;
+
+       for (i = 0; i < UART_NR; i++) {
+               struct uart_txx9_port *up = &serial_txx9_ports[i];
+
+               if (up->port.type != PORT_UNKNOWN && up->port.dev == &dev->dev)
+                       uart_suspend_port(&serial_txx9_reg, &up->port);
+       }
+
+       return 0;
+}
+
+static int serial_txx9_resume(struct platform_device *dev)
+{
+       int i;
+
+       for (i = 0; i < UART_NR; i++) {
+               struct uart_txx9_port *up = &serial_txx9_ports[i];
+
+               if (up->port.type != PORT_UNKNOWN && up->port.dev == &dev->dev)
+                       uart_resume_port(&serial_txx9_reg, &up->port);
+       }
+
+       return 0;
+}
+#endif
+
+static struct platform_driver serial_txx9_plat_driver = {
+       .probe          = serial_txx9_probe,
+       .remove         = __devexit_p(serial_txx9_remove),
+#ifdef CONFIG_PM
+       .suspend        = serial_txx9_suspend,
+       .resume         = serial_txx9_resume,
+#endif
+       .driver         = {
+               .name   = "serial_txx9",
+               .owner  = THIS_MODULE,
+       },
+};
+
+#ifdef ENABLE_SERIAL_TXX9_PCI
 /*
  * Probe one serial board.  Unfortunately, there is no rhyme nor reason
  * to the arrangement of serial ports on a PCI card.
@@ -1097,20 +1160,22 @@ pciserial_txx9_init_one(struct pci_dev *dev, const struct pci_device_id *ent)
        line = serial_txx9_register_port(&port);
        if (line < 0) {
                printk(KERN_WARNING "Couldn't register serial port %s: %d\n", pci_name(dev), line);
+               pci_disable_device(dev);
+               return line;
        }
-       pci_set_drvdata(dev, (void *)(long)line);
+       pci_set_drvdata(dev, &serial_txx9_ports[line]);
 
        return 0;
 }
 
 static void __devexit pciserial_txx9_remove_one(struct pci_dev *dev)
 {
-       int line = (int)(long)pci_get_drvdata(dev);
+       struct uart_txx9_port *up = pci_get_drvdata(dev);
 
        pci_set_drvdata(dev, NULL);
 
-       if (line) {
-               serial_txx9_unregister_port(line);
+       if (up) {
+               serial_txx9_unregister_port(up->port.line);
                pci_disable_device(dev);
        }
 }
@@ -1118,10 +1183,10 @@ static void __devexit pciserial_txx9_remove_one(struct pci_dev *dev)
 #ifdef CONFIG_PM
 static int pciserial_txx9_suspend_one(struct pci_dev *dev, pm_message_t state)
 {
-       int line = (int)(long)pci_get_drvdata(dev);
+       struct uart_txx9_port *up = pci_get_drvdata(dev);
 
-       if (line)
-               serial_txx9_suspend_port(line);
+       if (up)
+               uart_suspend_port(&serial_txx9_reg, &up->port);
        pci_save_state(dev);
        pci_set_power_state(dev, pci_choose_state(dev, state));
        return 0;
@@ -1129,15 +1194,12 @@ static int pciserial_txx9_suspend_one(struct pci_dev *dev, pm_message_t state)
 
 static int pciserial_txx9_resume_one(struct pci_dev *dev)
 {
-       int line = (int)(long)pci_get_drvdata(dev);
+       struct uart_txx9_port *up = pci_get_drvdata(dev);
 
        pci_set_power_state(dev, PCI_D0);
        pci_restore_state(dev);
-
-       if (line) {
-               pci_enable_device(dev);
-               serial_txx9_resume_port(line);
-       }
+       if (up)
+               uart_resume_port(&serial_txx9_reg, &up->port);
        return 0;
 }
 #endif
@@ -1161,6 +1223,8 @@ static struct pci_driver serial_txx9_pci_driver = {
 MODULE_DEVICE_TABLE(pci, serial_txx9_pci_tbl);
 #endif /* ENABLE_SERIAL_TXX9_PCI */
 
+static struct platform_device *serial_txx9_plat_devs;
+
 static int __init serial_txx9_init(void)
 {
        int ret;
@@ -1168,13 +1232,39 @@ static int __init serial_txx9_init(void)
        printk(KERN_INFO "%s version %s\n", serial_name, serial_version);
 
        ret = uart_register_driver(&serial_txx9_reg);
-       if (ret >= 0) {
-               serial_txx9_register_ports(&serial_txx9_reg);
+       if (ret)
+               goto out;
+
+       serial_txx9_plat_devs = platform_device_alloc("serial_txx9", -1);
+       if (!serial_txx9_plat_devs) {
+               ret = -ENOMEM;
+               goto unreg_uart_drv;
+       }
+
+       ret = platform_device_add(serial_txx9_plat_devs);
+       if (ret)
+               goto put_dev;
+
+       serial_txx9_register_ports(&serial_txx9_reg,
+                                  &serial_txx9_plat_devs->dev);
+
+       ret = platform_driver_register(&serial_txx9_plat_driver);
+       if (ret)
+               goto del_dev;
 
 #ifdef ENABLE_SERIAL_TXX9_PCI
-               ret = pci_register_driver(&serial_txx9_pci_driver);
+       ret = pci_register_driver(&serial_txx9_pci_driver);
 #endif
-       }
+       if (ret == 0)
+               goto out;
+
+ del_dev:
+       platform_device_del(serial_txx9_plat_devs);
+ put_dev:
+       platform_device_put(serial_txx9_plat_devs);
+ unreg_uart_drv:
+       uart_unregister_driver(&serial_txx9_reg);
+ out:
        return ret;
 }
 
@@ -1185,6 +1275,8 @@ static void __exit serial_txx9_exit(void)
 #ifdef ENABLE_SERIAL_TXX9_PCI
        pci_unregister_driver(&serial_txx9_pci_driver);
 #endif
+       platform_driver_unregister(&serial_txx9_plat_driver);
+       platform_device_unregister(serial_txx9_plat_devs);
        for (i = 0; i < UART_NR; i++) {
                struct uart_txx9_port *up = &serial_txx9_ports[i];
                if (up->port.iobase || up->port.mapbase)
index 34e9bac..b607870 100644 (file)
@@ -4,7 +4,7 @@
 
 usbcore-objs   := usb.o hub.o hcd.o urb.o message.o driver.o \
                        config.o file.o buffer.o sysfs.o endpoint.o \
-                       devio.o notify.o generic.o
+                       devio.o notify.o generic.o quirks.o
 
 ifeq ($(CONFIG_PCI),y)
        usbcore-objs    += hcd-pci.o
index 2aded26..9e3e943 100644 (file)
@@ -366,19 +366,8 @@ void usb_driver_release_interface(struct usb_driver *driver,
 EXPORT_SYMBOL(usb_driver_release_interface);
 
 /* returns 0 if no match, 1 if match */
-int usb_match_one_id(struct usb_interface *interface,
-                    const struct usb_device_id *id)
+int usb_match_device(struct usb_device *dev, const struct usb_device_id *id)
 {
-       struct usb_host_interface *intf;
-       struct usb_device *dev;
-
-       /* proc_connectinfo in devio.c may call us with id == NULL. */
-       if (id == NULL)
-               return 0;
-
-       intf = interface->cur_altsetting;
-       dev = interface_to_usbdev(interface);
-
        if ((id->match_flags & USB_DEVICE_ID_MATCH_VENDOR) &&
            id->idVendor != le16_to_cpu(dev->descriptor.idVendor))
                return 0;
@@ -409,6 +398,26 @@ int usb_match_one_id(struct usb_interface *interface,
            (id->bDeviceProtocol != dev->descriptor.bDeviceProtocol))
                return 0;
 
+       return 1;
+}
+
+/* returns 0 if no match, 1 if match */
+int usb_match_one_id(struct usb_interface *interface,
+                    const struct usb_device_id *id)
+{
+       struct usb_host_interface *intf;
+       struct usb_device *dev;
+
+       /* proc_connectinfo in devio.c may call us with id == NULL. */
+       if (id == NULL)
+               return 0;
+
+       intf = interface->cur_altsetting;
+       dev = interface_to_usbdev(interface);
+
+       if (!usb_match_device(dev, id))
+               return 0;
+
        /* The interface class, subclass, and protocol should never be
         * checked for a match if the device class is Vendor Specific,
         * unless the match record specifies the Vendor ID. */
@@ -954,12 +963,16 @@ static int autosuspend_check(struct usb_device *udev)
        int                     i;
        struct usb_interface    *intf;
 
-       /* For autosuspend, fail fast if anything is in use.
-        * Also fail if any interfaces require remote wakeup but it
-        * isn't available. */
+       /* For autosuspend, fail fast if anything is in use or autosuspend
+        * is disabled.  Also fail if any interfaces require remote wakeup
+        * but it isn't available.
+        */
        udev->do_remote_wakeup = device_may_wakeup(&udev->dev);
        if (udev->pm_usage_cnt > 0)
                return -EBUSY;
+       if (!udev->autosuspend_delay)
+               return -EPERM;
+
        if (udev->actconfig) {
                for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++) {
                        intf = udev->actconfig->interface[i];
@@ -982,7 +995,7 @@ static int autosuspend_check(struct usb_device *udev)
 
 #define autosuspend_check(udev)                0
 
-#endif
+#endif /* CONFIG_USB_SUSPEND */
 
 /**
  * usb_suspend_both - suspend a USB device and its interfaces
@@ -1177,7 +1190,7 @@ static int usb_autopm_do_device(struct usb_device *udev, int inc_usage_cnt)
                        udev->pm_usage_cnt -= inc_usage_cnt;
        } else if (inc_usage_cnt <= 0 && autosuspend_check(udev) == 0)
                queue_delayed_work(ksuspend_usb_wq, &udev->autosuspend,
-                               USB_AUTOSUSPEND_DELAY);
+                               udev->autosuspend_delay);
        usb_pm_unlock(udev);
        return status;
 }
@@ -1211,6 +1224,26 @@ void usb_autosuspend_device(struct usb_device *udev)
        //              __FUNCTION__, udev->pm_usage_cnt);
 }
 
+/**
+ * usb_try_autosuspend_device - attempt an autosuspend of a USB device and its interfaces
+ * @udev: the usb_device to autosuspend
+ *
+ * This routine should be called when a core subsystem thinks @udev may
+ * be ready to autosuspend.
+ *
+ * @udev's usage counter left unchanged.  If it or any of the usage counters
+ * for an active interface is greater than 0, or autosuspend is not allowed
+ * for any other reason, no autosuspend request will be queued.
+ *
+ * This routine can run only in process context.
+ */
+void usb_try_autosuspend_device(struct usb_device *udev)
+{
+       usb_autopm_do_device(udev, 0);
+       // dev_dbg(&udev->dev, "%s: cnt %d\n",
+       //              __FUNCTION__, udev->pm_usage_cnt);
+}
+
 /**
  * usb_autoresume_device - immediately autoresume a USB device and its interfaces
  * @udev: the usb_device to autoresume
@@ -1261,7 +1294,7 @@ static int usb_autopm_do_interface(struct usb_interface *intf,
                                intf->pm_usage_cnt -= inc_usage_cnt;
                } else if (inc_usage_cnt <= 0 && autosuspend_check(udev) == 0)
                        queue_delayed_work(ksuspend_usb_wq, &udev->autosuspend,
-                                       USB_AUTOSUSPEND_DELAY);
+                                       udev->autosuspend_delay);
        }
        usb_pm_unlock(udev);
        return status;
index 50c0db1..4140074 100644 (file)
@@ -1287,6 +1287,9 @@ int usb_new_device(struct usb_device *udev)
        if (!try_module_get(THIS_MODULE))
                return -EINVAL;
 
+       /* Determine quirks */
+       usb_detect_quirks(udev);
+
        err = usb_get_configuration(udev);
        if (err < 0) {
                dev_err(&udev->dev, "can't read configurations, error %d\n",
index 74edaea..2f17468 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/timer.h>
 #include <linux/ctype.h>
 #include <linux/device.h>
+#include <linux/usb/quirks.h>
 #include <asm/byteorder.h>
 #include <asm/scatterlist.h>
 
@@ -685,7 +686,10 @@ static int usb_string_sub(struct usb_device *dev, unsigned int langid,
 
        /* Try to read the string descriptor by asking for the maximum
         * possible number of bytes */
-       rc = usb_get_string(dev, langid, index, buf, 255);
+       if (dev->quirks & USB_QUIRK_STRING_FETCH_255)
+               rc = -EIO;
+       else
+               rc = usb_get_string(dev, langid, index, buf, 255);
 
        /* If that failed try to read the descriptor length, then
         * ask for just that many bytes */
diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c
new file mode 100644 (file)
index 0000000..0e5c646
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * USB device quirk handling logic and table
+ *
+ * Copyright (c) 2007 Oliver Neukum
+ * Copyright (c) 2007 Greg Kroah-Hartman <gregkh@suse.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation, version 2.
+ *
+ *
+ */
+
+#include <linux/usb.h>
+#include <linux/usb/quirks.h>
+#include "usb.h"
+
+/* List of quirky USB devices.  Please keep this list ordered by:
+ *     1) Vendor ID
+ *     2) Product ID
+ *     3) Class ID
+ *
+ * as we want specific devices to be overridden first, and only after that, any
+ * class specific quirks.
+ *
+ * Right now the logic aborts if it finds a valid device in the table, we might
+ * want to change that in the future if it turns out that a whole class of
+ * devices is broken...
+ */
+static const struct usb_device_id usb_quirk_list[] = {
+       /* HP 5300/5370C scanner */
+       { USB_DEVICE(0x03f0, 0x0701), .driver_info = USB_QUIRK_STRING_FETCH_255 },
+
+       /* Elsa MicroLink 56k (V.250) */
+       { USB_DEVICE(0x05cc, 0x2267), .driver_info = USB_QUIRK_NO_AUTOSUSPEND },
+
+       { }  /* terminating entry must be last */
+};
+
+static void usb_autosuspend_quirk(struct usb_device *udev)
+{
+#ifdef CONFIG_USB_SUSPEND
+       /* disable autosuspend, but allow the user to re-enable it via sysfs */
+       udev->autosuspend_delay = 0;
+#endif
+}
+
+static const struct usb_device_id *find_id(struct usb_device *udev)
+{
+       const struct usb_device_id *id = usb_quirk_list;
+
+       for (; id->idVendor || id->bDeviceClass || id->bInterfaceClass ||
+                       id->driver_info; id++) {
+               if (usb_match_device(udev, id))
+                       return id;
+       }
+       return NULL;
+}
+
+/*
+ * Detect any quirks the device has, and do any housekeeping for it if needed.
+ */
+void usb_detect_quirks(struct usb_device *udev)
+{
+       const struct usb_device_id *id = usb_quirk_list;
+
+       id = find_id(udev);
+       if (id)
+               udev->quirks = (u32)(id->driver_info);
+       if (udev->quirks)
+               dev_dbg(&udev->dev, "USB quirks for this device: %x\n",
+                               udev->quirks);
+
+       /* do any special quirk handling here if needed */
+       if (udev->quirks & USB_QUIRK_NO_AUTOSUSPEND)
+               usb_autosuspend_quirk(udev);
+}
index 0edfbaf..311d5df 100644 (file)
@@ -148,6 +148,75 @@ show_maxchild(struct device *dev, struct device_attribute *attr, char *buf)
 }
 static DEVICE_ATTR(maxchild, S_IRUGO, show_maxchild, NULL);
 
+static ssize_t
+show_quirks(struct device *dev, struct device_attribute *attr, char *buf)
+{
+       struct usb_device *udev;
+
+       udev = to_usb_device(dev);
+       return sprintf(buf, "0x%x\n", udev->quirks);
+}
+static DEVICE_ATTR(quirks, S_IRUGO, show_quirks, NULL);
+
+#ifdef CONFIG_USB_SUSPEND
+
+static ssize_t
+show_autosuspend(struct device *dev, struct device_attribute *attr, char *buf)
+{
+       struct usb_device *udev = to_usb_device(dev);
+
+       return sprintf(buf, "%u\n", udev->autosuspend_delay / HZ);
+}
+
+static ssize_t
+set_autosuspend(struct device *dev, struct device_attribute *attr,
+               const char *buf, size_t count)
+{
+       struct usb_device *udev = to_usb_device(dev);
+       unsigned value, old;
+
+       if (sscanf(buf, "%u", &value) != 1 || value >= INT_MAX/HZ)
+               return -EINVAL;
+       value *= HZ;
+
+       old = udev->autosuspend_delay;
+       udev->autosuspend_delay = value;
+       if (value > 0 && old == 0)
+               usb_try_autosuspend_device(udev);
+
+       return count;
+}
+
+static DEVICE_ATTR(autosuspend, S_IRUGO | S_IWUSR,
+               show_autosuspend, set_autosuspend);
+
+static char power_group[] = "power";
+
+static int add_power_attributes(struct device *dev)
+{
+       int rc = 0;
+
+       if (is_usb_device(dev))
+               rc = sysfs_add_file_to_group(&dev->kobj,
+                               &dev_attr_autosuspend.attr,
+                               power_group);
+       return rc;
+}
+
+static void remove_power_attributes(struct device *dev)
+{
+       sysfs_remove_file_from_group(&dev->kobj,
+                       &dev_attr_autosuspend.attr,
+                       power_group);
+}
+
+#else
+
+#define add_power_attributes(dev)      0
+#define remove_power_attributes(dev)   do {} while (0)
+
+#endif /* CONFIG_USB_SUSPEND */
+
 /* Descriptor fields */
 #define usb_descriptor_attr_le16(field, format_string)                 \
 static ssize_t                                                         \
@@ -204,6 +273,7 @@ static struct attribute *dev_attrs[] = {
        &dev_attr_devnum.attr,
        &dev_attr_version.attr,
        &dev_attr_maxchild.attr,
+       &dev_attr_quirks.attr,
        NULL,
 };
 static struct attribute_group dev_attr_grp = {
@@ -219,6 +289,10 @@ int usb_create_sysfs_dev_files(struct usb_device *udev)
        if (retval)
                return retval;
 
+       retval = add_power_attributes(dev);
+       if (retval)
+               goto error;
+
        if (udev->manufacturer) {
                retval = device_create_file(dev, &dev_attr_manufacturer);
                if (retval)
@@ -239,10 +313,7 @@ int usb_create_sysfs_dev_files(struct usb_device *udev)
                goto error;
        return 0;
 error:
-       usb_remove_ep_files(&udev->ep0);
-       device_remove_file(dev, &dev_attr_manufacturer);
-       device_remove_file(dev, &dev_attr_product);
-       device_remove_file(dev, &dev_attr_serial);
+       usb_remove_sysfs_dev_files(udev);
        return retval;
 }
 
@@ -251,14 +322,11 @@ void usb_remove_sysfs_dev_files(struct usb_device *udev)
        struct device *dev = &udev->dev;
 
        usb_remove_ep_files(&udev->ep0);
+       device_remove_file(dev, &dev_attr_manufacturer);
+       device_remove_file(dev, &dev_attr_product);
+       device_remove_file(dev, &dev_attr_serial);
+       remove_power_attributes(dev);
        sysfs_remove_group(&dev->kobj, &dev_attr_grp);
-
-       if (udev->manufacturer)
-               device_remove_file(dev, &dev_attr_manufacturer);
-       if (udev->product)
-               device_remove_file(dev, &dev_attr_product);
-       if (udev->serial)
-               device_remove_file(dev, &dev_attr_serial);
 }
 
 /* Interface fields */
@@ -362,33 +430,28 @@ static inline void usb_remove_intf_ep_files(struct usb_interface *intf)
 
 int usb_create_sysfs_intf_files(struct usb_interface *intf)
 {
+       struct device *dev = &intf->dev;
        struct usb_device *udev = interface_to_usbdev(intf);
        struct usb_host_interface *alt = intf->cur_altsetting;
        int retval;
 
-       retval = sysfs_create_group(&intf->dev.kobj, &intf_attr_grp);
+       retval = sysfs_create_group(&dev->kobj, &intf_attr_grp);
        if (retval)
-               goto error;
+               return retval;
 
        if (alt->string == NULL)
                alt->string = usb_cache_string(udev, alt->desc.iInterface);
        if (alt->string)
-               retval = device_create_file(&intf->dev, &dev_attr_interface);
+               retval = device_create_file(dev, &dev_attr_interface);
        usb_create_intf_ep_files(intf, udev);
        return 0;
-error:
-       if (alt->string)
-               device_remove_file(&intf->dev, &dev_attr_interface);
-       sysfs_remove_group(&intf->dev.kobj, &intf_attr_grp);
-       usb_remove_intf_ep_files(intf);
-       return retval;
 }
 
 void usb_remove_sysfs_intf_files(struct usb_interface *intf)
 {
-       usb_remove_intf_ep_files(intf);
-       sysfs_remove_group(&intf->dev.kobj, &intf_attr_grp);
+       struct device *dev = &intf->dev;
 
-       if (intf->cur_altsetting->string)
-               device_remove_file(&intf->dev, &dev_attr_interface);
+       usb_remove_intf_ep_files(intf);
+       device_remove_file(dev, &dev_attr_interface);
+       sysfs_remove_group(&dev->kobj, &intf_attr_grp);
 }
index 3db721c..54b42ce 100644 (file)
@@ -22,6 +22,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/moduleparam.h>
 #include <linux/string.h>
 #include <linux/bitops.h>
 #include <linux/slab.h>
@@ -50,6 +51,16 @@ static int nousb;    /* Disable USB when built into kernel image */
 
 struct workqueue_struct *ksuspend_usb_wq;      /* For autosuspend */
 
+#ifdef CONFIG_USB_SUSPEND
+static int usb_autosuspend_delay = 2;          /* Default delay value,
+                                                * in seconds */
+module_param_named(autosuspend, usb_autosuspend_delay, uint, 0644);
+MODULE_PARM_DESC(autosuspend, "default autosuspend delay");
+
+#else
+#define usb_autosuspend_delay          0
+#endif
+
 
 /**
  * usb_ifnum_to_if - get the interface object with a given interface number
@@ -306,6 +317,7 @@ usb_alloc_dev(struct usb_device *parent, struct usb_bus *bus, unsigned port1)
 #ifdef CONFIG_PM
        mutex_init(&dev->pm_mutex);
        INIT_DELAYED_WORK(&dev->autosuspend, usb_autosuspend_work);
+       dev->autosuspend_delay = usb_autosuspend_delay * HZ;
 #endif
        return dev;
 }
index 17830a8..08b5a04 100644 (file)
@@ -13,6 +13,7 @@ extern void usb_disable_interface (struct usb_device *dev,
                struct usb_interface *intf);
 extern void usb_release_interface_cache(struct kref *ref);
 extern void usb_disable_device (struct usb_device *dev, int skip_ep0);
+extern void usb_detect_quirks(struct usb_device *udev);
 
 extern int usb_get_device_descriptor(struct usb_device *dev,
                unsigned int size);
@@ -21,6 +22,8 @@ extern int usb_set_configuration(struct usb_device *dev, int configuration);
 
 extern void usb_kick_khubd(struct usb_device *dev);
 extern void usb_resume_root_hub(struct usb_device *dev);
+extern int usb_match_device(struct usb_device *dev,
+                           const struct usb_device_id *id);
 
 extern int  usb_hub_init(void);
 extern void usb_hub_cleanup(void);
@@ -62,14 +65,14 @@ static inline void usb_pm_unlock(struct usb_device *udev) {}
 
 #ifdef CONFIG_USB_SUSPEND
 
-#define USB_AUTOSUSPEND_DELAY  (HZ*2)
-
 extern void usb_autosuspend_device(struct usb_device *udev);
+extern void usb_try_autosuspend_device(struct usb_device *udev);
 extern int usb_autoresume_device(struct usb_device *udev);
 
 #else
 
-#define usb_autosuspend_device(udev)   do {} while (0)
+#define usb_autosuspend_device(udev)           do {} while (0)
+#define usb_try_autosuspend_device(udev)       do {} while (0)
 static inline int usb_autoresume_device(struct usb_device *udev)
 {
        return 0;
index 34296e7..188c74a 100644 (file)
@@ -553,6 +553,7 @@ static ssize_t ep_aio_read_retry(struct kiocb *iocb)
 {
        struct kiocb_priv       *priv = iocb->private;
        ssize_t                 len, total;
+       void                    *to_copy;
        int                     i;
 
        /* we "retry" to get the right mm context for this: */
@@ -560,10 +561,11 @@ static ssize_t ep_aio_read_retry(struct kiocb *iocb)
        /* copy stuff into user buffers */
        total = priv->actual;
        len = 0;
+       to_copy = priv->buf;
        for (i=0; i < priv->nr_segs; i++) {
                ssize_t this = min((ssize_t)(priv->iv[i].iov_len), total);
 
-               if (copy_to_user(priv->iv[i].iov_base, priv->buf, this)) {
+               if (copy_to_user(priv->iv[i].iov_base, to_copy, this)) {
                        if (len == 0)
                                len = -EFAULT;
                        break;
@@ -571,6 +573,7 @@ static ssize_t ep_aio_read_retry(struct kiocb *iocb)
 
                total -= this;
                len += this;
+               to_copy += this;
                if (total == 0)
                        break;
        }
index 5d6c06b..8d24d3d 100644 (file)
@@ -196,7 +196,7 @@ static int uhci_show_qh(struct uhci_qh *qh, char *buf, int len, int space)
                struct uhci_td *td = list_entry(urbp->td_list.next,
                                struct uhci_td, list);
 
-               if (cpu_to_le32(td->dma_handle) != (element & ~UHCI_PTR_BITS))
+               if (element != LINK_TO_TD(td))
                        out += sprintf(out, "%*s Element != First TD\n",
                                        space, "");
                i = nurbs = 0;
@@ -220,16 +220,6 @@ static int uhci_show_qh(struct uhci_qh *qh, char *buf, int len, int space)
        return out - buf;
 }
 
-static const char * const qh_names[] = {
-  "skel_unlink_qh", "skel_iso_qh",
-  "skel_int128_qh", "skel_int64_qh",
-  "skel_int32_qh", "skel_int16_qh",
-  "skel_int8_qh", "skel_int4_qh",
-  "skel_int2_qh", "skel_int1_qh",
-  "skel_ls_control_qh", "skel_fs_control_qh",
-  "skel_bulk_qh", "skel_term_qh"
-};
-
 static int uhci_show_sc(int port, unsigned short status, char *buf, int len)
 {
        char *out = buf;
@@ -352,6 +342,12 @@ static int uhci_sprint_schedule(struct uhci_hcd *uhci, char *buf, int len)
        struct uhci_td *td;
        struct list_head *tmp, *head;
        int nframes, nerrs;
+       __le32 link;
+
+       static const char * const qh_names[] = {
+               "unlink", "iso", "int128", "int64", "int32", "int16",
+               "int8", "int4", "int2", "async", "term"
+       };
 
        out += uhci_show_root_hub_state(uhci, out, len - (out - buf));
        out += sprintf(out, "HC status\n");
@@ -374,7 +370,7 @@ static int uhci_sprint_schedule(struct uhci_hcd *uhci, char *buf, int len)
        nframes = 10;
        nerrs = 0;
        for (i = 0; i < UHCI_NUMFRAMES; ++i) {
-               __le32 link, qh_dma;
+               __le32 qh_dma;
 
                j = 0;
                td = uhci->frame_cpu[i];
@@ -393,7 +389,7 @@ static int uhci_sprint_schedule(struct uhci_hcd *uhci, char *buf, int len)
                do {
                        td = list_entry(tmp, struct uhci_td, fl_list);
                        tmp = tmp->next;
-                       if (cpu_to_le32(td->dma_handle) != link) {
+                       if (link != LINK_TO_TD(td)) {
                                if (nframes > 0)
                                        out += sprintf(out, "    link does "
                                                "not match list entry!\n");
@@ -430,23 +426,21 @@ check_link:
 
        for (i = 0; i < UHCI_NUM_SKELQH; ++i) {
                int cnt = 0;
+               __le32 fsbr_link = 0;
 
                qh = uhci->skelqh[i];
-               out += sprintf(out, "- %s\n", qh_names[i]); \
+               out += sprintf(out, "- skel_%s_qh\n", qh_names[i]); \
                out += uhci_show_qh(qh, out, len - (out - buf), 4);
 
                /* Last QH is the Terminating QH, it's different */
-               if (i == UHCI_NUM_SKELQH - 1) {
-                       if (qh->link != UHCI_PTR_TERM)
-                               out += sprintf(out, "    bandwidth reclamation on!\n");
-
-                       if (qh_element(qh) != cpu_to_le32(uhci->term_td->dma_handle))
+               if (i == SKEL_TERM) {
+                       if (qh_element(qh) != LINK_TO_TD(uhci->term_td))
                                out += sprintf(out, "    skel_term_qh element is not set to term_td!\n");
-
+                       if (link == LINK_TO_QH(uhci->skel_term_qh))
+                               goto check_qh_link;
                        continue;
                }
 
-               j = (i < 9) ? 9 : i+1;          /* Next skeleton */
                head = &qh->node;
                tmp = head->next;
 
@@ -456,15 +450,26 @@ check_link:
                        if (++cnt <= 10)
                                out += uhci_show_qh(qh, out,
                                                len - (out - buf), 4);
+                       if (!fsbr_link && qh->skel >= SKEL_FSBR)
+                               fsbr_link = LINK_TO_QH(qh);
                }
                if ((cnt -= 10) > 0)
                        out += sprintf(out, "    Skipped %d QHs\n", cnt);
 
-               if (i > 1 && i < UHCI_NUM_SKELQH - 1) {
-                       if (qh->link !=
-                           (cpu_to_le32(uhci->skelqh[j]->dma_handle) | UHCI_PTR_QH))
-                               out += sprintf(out, "    last QH not linked to next skeleton!\n");
-               }
+               link = UHCI_PTR_TERM;
+               if (i <= SKEL_ISO)
+                       ;
+               else if (i < SKEL_ASYNC)
+                       link = LINK_TO_QH(uhci->skel_async_qh);
+               else if (!uhci->fsbr_is_on)
+                       ;
+               else if (fsbr_link)
+                       link = fsbr_link;
+               else
+                       link = LINK_TO_QH(uhci->skel_term_qh);
+check_qh_link:
+               if (qh->link != link)
+                       out += sprintf(out, "    last QH not linked to next skeleton!\n");
        }
 
        return out - buf;
index ded4df3..44da433 100644 (file)
@@ -13,7 +13,7 @@
  * (C) Copyright 2000 Yggdrasil Computing, Inc. (port of new PCI interface
  *               support from usb-ohci.c by Adam Richter, adam@yggdrasil.com).
  * (C) Copyright 1999 Gregory P. Smith (from usb-ohci.c)
- * (C) Copyright 2004-2006 Alan Stern, stern@rowland.harvard.edu
+ * (C) Copyright 2004-2007 Alan Stern, stern@rowland.harvard.edu
  *
  * Intel documents this fairly well, and as far as I know there
  * are no royalties or anything like that, but even so there are
@@ -107,16 +107,16 @@ static __le32 uhci_frame_skel_link(struct uhci_hcd *uhci, int frame)
         * interrupt QHs, which will help spread out bandwidth utilization.
         *
         * ffs (Find First bit Set) does exactly what we need:
-        * 1,3,5,...  => ffs = 0 => use skel_int2_qh = skelqh[8],
-        * 2,6,10,... => ffs = 1 => use skel_int4_qh = skelqh[7], etc.
+        * 1,3,5,...  => ffs = 0 => use period-2 QH = skelqh[8],
+        * 2,6,10,... => ffs = 1 => use period-4 QH = skelqh[7], etc.
         * ffs >= 7 => not on any high-period queue, so use
-        *      skel_int1_qh = skelqh[9].
+        *      period-1 QH = skelqh[9].
         * Add in UHCI_NUMFRAMES to insure at least one bit is set.
         */
        skelnum = 8 - (int) __ffs(frame | UHCI_NUMFRAMES);
        if (skelnum <= 1)
                skelnum = 9;
-       return UHCI_PTR_QH | cpu_to_le32(uhci->skelqh[skelnum]->dma_handle);
+       return LINK_TO_QH(uhci->skelqh[skelnum]);
 }
 
 #include "uhci-debug.c"
@@ -540,16 +540,18 @@ static void uhci_shutdown(struct pci_dev *pdev)
  *
  * The hardware doesn't really know any difference
  * in the queues, but the order does matter for the
- * protocols higher up. The order is:
+ * protocols higher up.  The order in which the queues
+ * are encountered by the hardware is:
  *
- *  - any isochronous events handled before any
+ *  - All isochronous events are handled before any
  *    of the queues. We don't do that here, because
  *    we'll create the actual TD entries on demand.
- *  - The first queue is the interrupt queue.
- *  - The second queue is the control queue, split into low- and full-speed
- *  - The third queue is bulk queue.
- *  - The fourth queue is the bandwidth reclamation queue, which loops back
- *    to the full-speed control queue.
+ *  - The first queue is the high-period interrupt queue.
+ *  - The second queue is the period-1 interrupt and async
+ *    (low-speed control, full-speed control, then bulk) queue.
+ *  - The third queue is the terminating bandwidth reclamation queue,
+ *    which contains no members, loops back to itself, and is present
+ *    only when FSBR is on and there are no full-speed control or bulk QHs.
  */
 static int uhci_start(struct usb_hcd *hcd)
 {
@@ -626,34 +628,18 @@ static int uhci_start(struct usb_hcd *hcd)
        }
 
        /*
-        * 8 Interrupt queues; link all higher int queues to int1,
-        * then link int1 to control and control to bulk
+        * 8 Interrupt queues; link all higher int queues to int1 = async
         */
-       uhci->skel_int128_qh->link =
-                       uhci->skel_int64_qh->link =
-                       uhci->skel_int32_qh->link =
-                       uhci->skel_int16_qh->link =
-                       uhci->skel_int8_qh->link =
-                       uhci->skel_int4_qh->link =
-                       uhci->skel_int2_qh->link = UHCI_PTR_QH |
-                       cpu_to_le32(uhci->skel_int1_qh->dma_handle);
-
-       uhci->skel_int1_qh->link = UHCI_PTR_QH |
-                       cpu_to_le32(uhci->skel_ls_control_qh->dma_handle);
-       uhci->skel_ls_control_qh->link = UHCI_PTR_QH |
-                       cpu_to_le32(uhci->skel_fs_control_qh->dma_handle);
-       uhci->skel_fs_control_qh->link = UHCI_PTR_QH |
-                       cpu_to_le32(uhci->skel_bulk_qh->dma_handle);
-       uhci->skel_bulk_qh->link = UHCI_PTR_QH |
-                       cpu_to_le32(uhci->skel_term_qh->dma_handle);
+       for (i = SKEL_ISO + 1; i < SKEL_ASYNC; ++i)
+               uhci->skelqh[i]->link = LINK_TO_QH(uhci->skel_async_qh);
+       uhci->skel_async_qh->link = uhci->skel_term_qh->link = UHCI_PTR_TERM;
 
        /* This dummy TD is to work around a bug in Intel PIIX controllers */
        uhci_fill_td(uhci->term_td, 0, uhci_explen(0) |
-               (0x7f << TD_TOKEN_DEVADDR_SHIFT) | USB_PID_IN, 0);
-       uhci->term_td->link = cpu_to_le32(uhci->term_td->dma_handle);
-
-       uhci->skel_term_qh->link = UHCI_PTR_TERM;
-       uhci->skel_term_qh->element = cpu_to_le32(uhci->term_td->dma_handle);
+                       (0x7f << TD_TOKEN_DEVADDR_SHIFT) | USB_PID_IN, 0);
+       uhci->term_td->link = UHCI_PTR_TERM;
+       uhci->skel_async_qh->element = uhci->skel_term_qh->element =
+                       LINK_TO_TD(uhci->term_td);
 
        /*
         * Fill the frame list: make all entries point to the proper
index 74469b5..1b3d234 100644 (file)
@@ -129,11 +129,12 @@ struct uhci_qh {
        __le32 element;                 /* Queue element (TD) pointer */
 
        /* Software fields */
+       dma_addr_t dma_handle;
+
        struct list_head node;          /* Node in the list of QHs */
        struct usb_host_endpoint *hep;  /* Endpoint information */
        struct usb_device *udev;
        struct list_head queue;         /* Queue of urbps for this QH */
-       struct uhci_qh *skel;           /* Skeleton for this QH */
        struct uhci_td *dummy_td;       /* Dummy TD to end the queue */
        struct uhci_td *post_td;        /* Last TD completed */
 
@@ -149,8 +150,7 @@ struct uhci_qh {
 
        int state;                      /* QH_STATE_xxx; see above */
        int type;                       /* Queue type (control, bulk, etc) */
-
-       dma_addr_t dma_handle;
+       int skel;                       /* Skeleton queue number */
 
        unsigned int initial_toggle:1;  /* Endpoint's current toggle value */
        unsigned int needs_fixup:1;     /* Must fix the TD toggle values */
@@ -171,6 +171,8 @@ static inline __le32 qh_element(struct uhci_qh *qh) {
        return element;
 }
 
+#define LINK_TO_QH(qh)         (UHCI_PTR_QH | cpu_to_le32((qh)->dma_handle))
+
 
 /*
  *     Transfer Descriptors
@@ -264,6 +266,8 @@ static inline u32 td_status(struct uhci_td *td) {
        return le32_to_cpu(status);
 }
 
+#define LINK_TO_TD(td)         (cpu_to_le32((td)->dma_handle))
+
 
 /*
  *     Skeleton Queue Headers
@@ -272,12 +276,13 @@ static inline u32 td_status(struct uhci_td *td) {
 /*
  * The UHCI driver uses QHs with Interrupt, Control and Bulk URBs for
  * automatic queuing. To make it easy to insert entries into the schedule,
- * we have a skeleton of QHs for each predefined Interrupt latency,
- * low-speed control, full-speed control, bulk, and terminating QH
- * (see explanation for the terminating QH below).
+ * we have a skeleton of QHs for each predefined Interrupt latency.
+ * Asynchronous QHs (low-speed control, full-speed control, and bulk)
+ * go onto the period-1 interrupt list, since they all get accessed on
+ * every frame.
  *
- * When we want to add a new QH, we add it to the end of the list for the
- * skeleton QH.  For instance, the schedule list can look like this:
+ * When we want to add a new QH, we add it to the list starting from the
+ * appropriate skeleton QH.  For instance, the schedule can look like this:
  *
  * skel int128 QH
  * dev 1 interrupt QH
@@ -285,50 +290,47 @@ static inline u32 td_status(struct uhci_td *td) {
  * skel int64 QH
  * skel int32 QH
  * ...
- * skel int1 QH
- * skel low-speed control QH
- * dev 5 control QH
- * skel full-speed control QH
- * skel bulk QH
+ * skel int1 + async QH
+ * dev 5 low-speed control QH
  * dev 1 bulk QH
  * dev 2 bulk QH
- * skel terminating QH
  *
- * The terminating QH is used for 2 reasons:
- * - To place a terminating TD which is used to workaround a PIIX bug
- *   (see Intel errata for explanation), and
- * - To loop back to the full-speed control queue for full-speed bandwidth
- *   reclamation.
+ * There is a special terminating QH used to keep full-speed bandwidth
+ * reclamation active when no full-speed control or bulk QHs are linked
+ * into the schedule.  It has an inactive TD (to work around a PIIX bug,
+ * see the Intel errata) and it points back to itself.
  *
- * There's a special skeleton QH for Isochronous QHs.  It never appears
- * on the schedule, and Isochronous TDs go on the schedule before the
+ * There's a special skeleton QH for Isochronous QHs which never appears
+ * on the schedule Isochronous TDs go on the schedule before the
  * the skeleton QHs.  The hardware accesses them directly rather than
  * through their QH, which is used only for bookkeeping purposes.
  * While the UHCI spec doesn't forbid the use of QHs for Isochronous,
  * it doesn't use them either.  And the spec says that queues never
  * advance on an error completion status, which makes them totally
  * unsuitable for Isochronous transfers.
+ *
+ * There's also a special skeleton QH used for QHs which are in the process
+ * of unlinking and so may still be in use by the hardware.  It too never
+ * appears on the schedule.
  */
 
-#define UHCI_NUM_SKELQH                14
-#define skel_unlink_qh         skelqh[0]
-#define skel_iso_qh            skelqh[1]
-#define skel_int128_qh         skelqh[2]
-#define skel_int64_qh          skelqh[3]
-#define skel_int32_qh          skelqh[4]
-#define skel_int16_qh          skelqh[5]
-#define skel_int8_qh           skelqh[6]
-#define skel_int4_qh           skelqh[7]
-#define skel_int2_qh           skelqh[8]
-#define skel_int1_qh           skelqh[9]
-#define skel_ls_control_qh     skelqh[10]
-#define skel_fs_control_qh     skelqh[11]
-#define skel_bulk_qh           skelqh[12]
-#define skel_term_qh           skelqh[13]
-
-/* Find the skelqh entry corresponding to an interval exponent */
-#define UHCI_SKEL_INDEX(exponent)      (9 - exponent)
-
+#define UHCI_NUM_SKELQH                11
+#define SKEL_UNLINK            0
+#define skel_unlink_qh         skelqh[SKEL_UNLINK]
+#define SKEL_ISO               1
+#define skel_iso_qh            skelqh[SKEL_ISO]
+       /* int128, int64, ..., int1 = 2, 3, ..., 9 */
+#define SKEL_INDEX(exponent)   (9 - exponent)
+#define SKEL_ASYNC             9
+#define skel_async_qh          skelqh[SKEL_ASYNC]
+#define SKEL_TERM              10
+#define skel_term_qh           skelqh[SKEL_TERM]
+
+/* The following entries refer to sublists of skel_async_qh */
+#define SKEL_LS_CONTROL                20
+#define SKEL_FS_CONTROL                21
+#define SKEL_FSBR              SKEL_FS_CONTROL
+#define SKEL_BULK              22
 
 /*
  *     The UHCI controller and root hub
index 68e66b3..f4ebdb3 100644 (file)
@@ -13,7 +13,7 @@
  * (C) Copyright 2000 Yggdrasil Computing, Inc. (port of new PCI interface
  *               support from usb-ohci.c by Adam Richter, adam@yggdrasil.com).
  * (C) Copyright 1999 Gregory P. Smith (from usb-ohci.c)
- * (C) Copyright 2004-2006 Alan Stern, stern@rowland.harvard.edu
+ * (C) Copyright 2004-2007 Alan Stern, stern@rowland.harvard.edu
  */
 
 
@@ -45,15 +45,43 @@ static inline void uhci_clear_next_interrupt(struct uhci_hcd *uhci)
  */
 static void uhci_fsbr_on(struct uhci_hcd *uhci)
 {
+       struct uhci_qh *fsbr_qh, *lqh, *tqh;
+
        uhci->fsbr_is_on = 1;
-       uhci->skel_term_qh->link = cpu_to_le32(
-                       uhci->skel_fs_control_qh->dma_handle) | UHCI_PTR_QH;
+       lqh = list_entry(uhci->skel_async_qh->node.prev,
+                       struct uhci_qh, node);
+
+       /* Find the first FSBR QH.  Linear search through the list is
+        * acceptable because normally FSBR gets turned on as soon as
+        * one QH needs it. */
+       fsbr_qh = NULL;
+       list_for_each_entry_reverse(tqh, &uhci->skel_async_qh->node, node) {
+               if (tqh->skel < SKEL_FSBR)
+                       break;
+               fsbr_qh = tqh;
+       }
+
+       /* No FSBR QH means we must insert the terminating skeleton QH */
+       if (!fsbr_qh) {
+               uhci->skel_term_qh->link = LINK_TO_QH(uhci->skel_term_qh);
+               wmb();
+               lqh->link = uhci->skel_term_qh->link;
+
+       /* Otherwise loop the last QH to the first FSBR QH */
+       } else
+               lqh->link = LINK_TO_QH(fsbr_qh);
 }
 
 static void uhci_fsbr_off(struct uhci_hcd *uhci)
 {
+       struct uhci_qh *lqh;
+
        uhci->fsbr_is_on = 0;
-       uhci->skel_term_qh->link = UHCI_PTR_TERM;
+       lqh = list_entry(uhci->skel_async_qh->node.prev,
+                       struct uhci_qh, node);
+
+       /* End the async list normally and unlink the terminating QH */
+       lqh->link = uhci->skel_term_qh->link = UHCI_PTR_TERM;
 }
 
 static void uhci_add_fsbr(struct uhci_hcd *uhci, struct urb *urb)
@@ -158,11 +186,11 @@ static inline void uhci_insert_td_in_frame_list(struct uhci_hcd *uhci,
 
                td->link = ltd->link;
                wmb();
-               ltd->link = cpu_to_le32(td->dma_handle);
+               ltd->link = LINK_TO_TD(td);
        } else {
                td->link = uhci->frame[framenum];
                wmb();
-               uhci->frame[framenum] = cpu_to_le32(td->dma_handle);
+               uhci->frame[framenum] = LINK_TO_TD(td);
                uhci->frame_cpu[framenum] = td;
        }
 }
@@ -184,7 +212,7 @@ static inline void uhci_remove_td_from_frame_list(struct uhci_hcd *uhci,
                        struct uhci_td *ntd;
 
                        ntd = list_entry(td->fl_list.next, struct uhci_td, fl_list);
-                       uhci->frame[td->frame] = cpu_to_le32(ntd->dma_handle);
+                       uhci->frame[td->frame] = LINK_TO_TD(ntd);
                        uhci->frame_cpu[td->frame] = ntd;
                }
        } else {
@@ -405,12 +433,81 @@ static void uhci_fixup_toggles(struct uhci_qh *qh, int skip_first)
 }
 
 /*
- * Put a QH on the schedule in both hardware and software
+ * Link an Isochronous QH into its skeleton's list
  */
-static void uhci_activate_qh(struct uhci_hcd *uhci, struct uhci_qh *qh)
+static inline void link_iso(struct uhci_hcd *uhci, struct uhci_qh *qh)
+{
+       list_add_tail(&qh->node, &uhci->skel_iso_qh->node);
+
+       /* Isochronous QHs aren't linked by the hardware */
+}
+
+/*
+ * Link a high-period interrupt QH into the schedule at the end of its
+ * skeleton's list
+ */
+static void link_interrupt(struct uhci_hcd *uhci, struct uhci_qh *qh)
 {
        struct uhci_qh *pqh;
 
+       list_add_tail(&qh->node, &uhci->skelqh[qh->skel]->node);
+
+       pqh = list_entry(qh->node.prev, struct uhci_qh, node);
+       qh->link = pqh->link;
+       wmb();
+       pqh->link = LINK_TO_QH(qh);
+}
+
+/*
+ * Link a period-1 interrupt or async QH into the schedule at the
+ * correct spot in the async skeleton's list, and update the FSBR link
+ */
+static void link_async(struct uhci_hcd *uhci, struct uhci_qh *qh)
+{
+       struct uhci_qh *pqh, *lqh;
+       __le32 link_to_new_qh;
+       __le32 *extra_link = &link_to_new_qh;
+
+       /* Find the predecessor QH for our new one and insert it in the list.
+        * The list of QHs is expected to be short, so linear search won't
+        * take too long. */
+       list_for_each_entry_reverse(pqh, &uhci->skel_async_qh->node, node) {
+               if (pqh->skel <= qh->skel)
+                       break;
+       }
+       list_add(&qh->node, &pqh->node);
+       qh->link = pqh->link;
+
+       link_to_new_qh = LINK_TO_QH(qh);
+
+       /* If this is now the first FSBR QH, take special action */
+       if (uhci->fsbr_is_on && pqh->skel < SKEL_FSBR &&
+                       qh->skel >= SKEL_FSBR) {
+               lqh = list_entry(uhci->skel_async_qh->node.prev,
+                               struct uhci_qh, node);
+
+               /* If the new QH is also the last one, we must unlink
+                * the terminating skeleton QH and make the new QH point
+                * back to itself. */
+               if (qh == lqh) {
+                       qh->link = link_to_new_qh;
+                       extra_link = &uhci->skel_term_qh->link;
+
+               /* Otherwise the last QH must point to the new QH */
+               } else
+                       extra_link = &lqh->link;
+       }
+
+       /* Link it into the schedule */
+       wmb();
+       *extra_link = pqh->link = link_to_new_qh;
+}
+
+/*
+ * Put a QH on the schedule in both hardware and software
+ */
+static void uhci_activate_qh(struct uhci_hcd *uhci, struct uhci_qh *qh)
+{
        WARN_ON(list_empty(&qh->queue));
 
        /* Set the element pointer if it isn't set already.
@@ -421,7 +518,7 @@ static void uhci_activate_qh(struct uhci_hcd *uhci, struct uhci_qh *qh)
                struct uhci_td *td = list_entry(urbp->td_list.next,
                                struct uhci_td, list);
 
-               qh->element = cpu_to_le32(td->dma_handle);
+               qh->element = LINK_TO_TD(td);
        }
 
        /* Treat the queue as if it has just advanced */
@@ -432,18 +529,64 @@ static void uhci_activate_qh(struct uhci_hcd *uhci, struct uhci_qh *qh)
                return;
        qh->state = QH_STATE_ACTIVE;
 
-       /* Move the QH from its old list to the end of the appropriate
+       /* Move the QH from its old list to the correct spot in the appropriate
         * skeleton's list */
        if (qh == uhci->next_qh)
                uhci->next_qh = list_entry(qh->node.next, struct uhci_qh,
                                node);
-       list_move_tail(&qh->node, &qh->skel->node);
+       list_del(&qh->node);
+
+       if (qh->skel == SKEL_ISO)
+               link_iso(uhci, qh);
+       else if (qh->skel < SKEL_ASYNC)
+               link_interrupt(uhci, qh);
+       else
+               link_async(uhci, qh);
+}
+
+/*
+ * Unlink a high-period interrupt QH from the schedule
+ */
+static void unlink_interrupt(struct uhci_hcd *uhci, struct uhci_qh *qh)
+{
+       struct uhci_qh *pqh;
 
-       /* Link it into the schedule */
        pqh = list_entry(qh->node.prev, struct uhci_qh, node);
-       qh->link = pqh->link;
-       wmb();
-       pqh->link = UHCI_PTR_QH | cpu_to_le32(qh->dma_handle);
+       pqh->link = qh->link;
+       mb();
+}
+
+/*
+ * Unlink a period-1 interrupt or async QH from the schedule
+ */
+static void unlink_async(struct uhci_hcd *uhci, struct uhci_qh *qh)
+{
+       struct uhci_qh *pqh, *lqh;
+       __le32 link_to_next_qh = qh->link;
+
+       pqh = list_entry(qh->node.prev, struct uhci_qh, node);
+
+       /* If this is the first FSBQ QH, take special action */
+       if (uhci->fsbr_is_on && pqh->skel < SKEL_FSBR &&
+                       qh->skel >= SKEL_FSBR) {
+               lqh = list_entry(uhci->skel_async_qh->node.prev,
+                               struct uhci_qh, node);
+
+               /* If this QH is also the last one, we must link in
+                * the terminating skeleton QH. */
+               if (qh == lqh) {
+                       link_to_next_qh = LINK_TO_QH(uhci->skel_term_qh);
+                       uhci->skel_term_qh->link = link_to_next_qh;
+                       wmb();
+                       qh->link = link_to_next_qh;
+
+               /* Otherwise the last QH must point to the new first FSBR QH */
+               } else
+                       lqh->link = link_to_next_qh;
+       }
+
+       pqh->link = link_to_next_qh;
+       mb();
 }
 
 /*
@@ -451,17 +594,18 @@ static void uhci_activate_qh(struct uhci_hcd *uhci, struct uhci_qh *qh)
  */
 static void uhci_unlink_qh(struct uhci_hcd *uhci, struct uhci_qh *qh)
 {
-       struct uhci_qh *pqh;
-
        if (qh->state == QH_STATE_UNLINKING)
                return;
        WARN_ON(qh->state != QH_STATE_ACTIVE || !qh->udev);
        qh->state = QH_STATE_UNLINKING;
 
        /* Unlink the QH from the schedule and record when we did it */
-       pqh = list_entry(qh->node.prev, struct uhci_qh, node);
-       pqh->link = qh->link;
-       mb();
+       if (qh->skel == SKEL_ISO)
+               ;
+       else if (qh->skel < SKEL_ASYNC)
+               unlink_interrupt(uhci, qh);
+       else
+               unlink_async(uhci, qh);
 
        uhci_get_current_frame_number(uhci);
        qh->unlink_frame = uhci->frame_number;
@@ -697,6 +841,7 @@ static int uhci_submit_control(struct uhci_hcd *uhci, struct urb *urb,
        dma_addr_t data = urb->transfer_dma;
        __le32 *plink;
        struct urb_priv *urbp = urb->hcpriv;
+       int skel;
 
        /* The "pipe" thing contains the destination in bits 8--18 */
        destination = (urb->pipe & PIPE_DEVEP_MASK) | USB_PID_SETUP;
@@ -737,7 +882,7 @@ static int uhci_submit_control(struct uhci_hcd *uhci, struct urb *urb,
                td = uhci_alloc_td(uhci);
                if (!td)
                        goto nomem;
-               *plink = cpu_to_le32(td->dma_handle);
+               *plink = LINK_TO_TD(td);
 
                /* Alternate Data0/1 (start with Data1) */
                destination ^= TD_TOKEN_TOGGLE;
@@ -757,7 +902,7 @@ static int uhci_submit_control(struct uhci_hcd *uhci, struct urb *urb,
        td = uhci_alloc_td(uhci);
        if (!td)
                goto nomem;
-       *plink = cpu_to_le32(td->dma_handle);
+       *plink = LINK_TO_TD(td);
 
        /*
         * It's IN if the pipe is an output pipe or we're not expecting
@@ -784,7 +929,7 @@ static int uhci_submit_control(struct uhci_hcd *uhci, struct urb *urb,
        td = uhci_alloc_td(uhci);
        if (!td)
                goto nomem;
-       *plink = cpu_to_le32(td->dma_handle);
+       *plink = LINK_TO_TD(td);
 
        uhci_fill_td(td, 0, USB_PID_OUT | uhci_explen(0), 0);
        wmb();
@@ -797,11 +942,13 @@ static int uhci_submit_control(struct uhci_hcd *uhci, struct urb *urb,
         * isn't in the CONFIGURED state. */
        if (urb->dev->speed == USB_SPEED_LOW ||
                        urb->dev->state != USB_STATE_CONFIGURED)
-               qh->skel = uhci->skel_ls_control_qh;
+               skel = SKEL_LS_CONTROL;
        else {
-               qh->skel = uhci->skel_fs_control_qh;
+               skel = SKEL_FS_CONTROL;
                uhci_add_fsbr(uhci, urb);
        }
+       if (qh->state != QH_STATE_ACTIVE)
+               qh->skel = skel;
 
        urb->actual_length = -8;        /* Account for the SETUP packet */
        return 0;
@@ -860,7 +1007,7 @@ static int uhci_submit_common(struct uhci_hcd *uhci, struct urb *urb,
                        td = uhci_alloc_td(uhci);
                        if (!td)
                                goto nomem;
-                       *plink = cpu_to_le32(td->dma_handle);
+                       *plink = LINK_TO_TD(td);
                }
                uhci_add_td_to_urbp(td, urbp);
                uhci_fill_td(td, status,
@@ -888,7 +1035,7 @@ static int uhci_submit_common(struct uhci_hcd *uhci, struct urb *urb,
                td = uhci_alloc_td(uhci);
                if (!td)
                        goto nomem;
-               *plink = cpu_to_le32(td->dma_handle);
+               *plink = LINK_TO_TD(td);
 
                uhci_add_td_to_urbp(td, urbp);
                uhci_fill_td(td, status,
@@ -914,7 +1061,7 @@ static int uhci_submit_common(struct uhci_hcd *uhci, struct urb *urb,
        td = uhci_alloc_td(uhci);
        if (!td)
                goto nomem;
-       *plink = cpu_to_le32(td->dma_handle);
+       *plink = LINK_TO_TD(td);
 
        uhci_fill_td(td, 0, USB_PID_OUT | uhci_explen(0), 0);
        wmb();
@@ -931,7 +1078,7 @@ nomem:
        return -ENOMEM;
 }
 
-static inline int uhci_submit_bulk(struct uhci_hcd *uhci, struct urb *urb,
+static int uhci_submit_bulk(struct uhci_hcd *uhci, struct urb *urb,
                struct uhci_qh *qh)
 {
        int ret;
@@ -940,7 +1087,8 @@ static inline int uhci_submit_bulk(struct uhci_hcd *uhci, struct urb *urb,
        if (urb->dev->speed == USB_SPEED_LOW)
                return -EINVAL;
 
-       qh->skel = uhci->skel_bulk_qh;
+       if (qh->state != QH_STATE_ACTIVE)
+               qh->skel = SKEL_BULK;
        ret = uhci_submit_common(uhci, urb, qh);
        if (ret == 0)
                uhci_add_fsbr(uhci, urb);
@@ -968,7 +1116,7 @@ static int uhci_submit_interrupt(struct uhci_hcd *uhci, struct urb *urb,
                if (exponent < 0)
                        return -EINVAL;
                qh->period = 1 << exponent;
-               qh->skel = uhci->skelqh[UHCI_SKEL_INDEX(exponent)];
+               qh->skel = SKEL_INDEX(exponent);
 
                /* For now, interrupt phase is fixed by the layout
                 * of the QH lists. */
@@ -1005,7 +1153,7 @@ static int uhci_fixup_short_transfer(struct uhci_hcd *uhci,
                 * the queue at the status stage transaction, which is
                 * the last TD. */
                WARN_ON(list_empty(&urbp->td_list));
-               qh->element = cpu_to_le32(td->dma_handle);
+               qh->element = LINK_TO_TD(td);
                tmp = td->list.prev;
                ret = -EINPROGRESS;
 
@@ -1216,7 +1364,7 @@ static int uhci_submit_isochronous(struct uhci_hcd *uhci, struct urb *urb,
                qh->iso_status = 0;
        }
 
-       qh->skel = uhci->skel_iso_qh;
+       qh->skel = SKEL_ISO;
        if (!qh->bandwidth_reserved)
                uhci_reserve_bandwidth(uhci, qh);
        return 0;
@@ -1566,8 +1714,7 @@ static int uhci_advance_check(struct uhci_hcd *uhci, struct uhci_qh *qh)
        if (time_after(jiffies, qh->advance_jiffies + QH_WAIT_TIMEOUT)) {
 
                /* Detect the Intel bug and work around it */
-               if (qh->post_td && qh_element(qh) ==
-                               cpu_to_le32(qh->post_td->dma_handle)) {
+               if (qh->post_td && qh_element(qh) == LINK_TO_TD(qh->post_td)) {
                        qh->element = qh->post_td->link;
                        qh->advance_jiffies = jiffies;
                        ret = 1;
index 8505824..3749f4a 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/usb/input.h>
+#include <linux/hid.h>
 
 /*
  * Version Information
@@ -330,7 +331,8 @@ static void usb_kbd_disconnect(struct usb_interface *intf)
 }
 
 static struct usb_device_id usb_kbd_id_table [] = {
-       { USB_INTERFACE_INFO(3, 1, 1) },
+       { USB_INTERFACE_INFO(USB_INTERFACE_CLASS_HID, USB_INTERFACE_SUBCLASS_BOOT,
+               USB_INTERFACE_PROTOCOL_KEYBOARD) },
        { }                                             /* Terminating entry */
 };
 
index 64a33e4..692fd60 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/usb/input.h>
+#include <linux/hid.h>
 
 /*
  * Version Information
@@ -213,7 +214,8 @@ static void usb_mouse_disconnect(struct usb_interface *intf)
 }
 
 static struct usb_device_id usb_mouse_id_table [] = {
-       { USB_INTERFACE_INFO(3, 1, 2) },
+       { USB_INTERFACE_INFO(USB_INTERFACE_CLASS_HID, USB_INTERFACE_SUBCLASS_BOOT,
+               USB_INTERFACE_PROTOCOL_MOUSE) },
        { }     /* Terminating entry */
 };
 
index 4142e36..4f3e9bc 100644 (file)
@@ -163,7 +163,7 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo)
        }
 
        id = STYLUS_DEVICE_ID;
-       if (data[1] & 0x10) { /* in prox */
+       if (data[1] & 0x80) { /* in prox */
 
                switch ((data[1] >> 5) & 3) {
 
@@ -196,9 +196,6 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo)
                                        wacom_report_abs(wcombo, ABS_DISTANCE, data[7] & 0x3f);
                                break;
                }
-       }
-
-       if (data[1] & 0x90) {
                x = wacom_le16_to_cpu(&data[2]);
                y = wacom_le16_to_cpu(&data[4]);
                wacom_report_abs(wcombo, ABS_X, x);
@@ -210,19 +207,28 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo)
                        wacom_report_key(wcombo, BTN_STYLUS2, data[1] & 0x04);
                }
                wacom_report_abs(wcombo, ABS_MISC, id); /* report tool id */
-       }
-       else
-               wacom_report_abs(wcombo, ABS_MISC, 0); /* reset tool id */
-
-       if (data[1] & 0x10)  /* only report prox-in when in area */
                wacom_report_key(wcombo, wacom->tool[0], 1);
-       if (!(data[1] & 0x90))  /* report prox-out when physically out */
+       } else if (!(data[1] & 0x90)) {
+               wacom_report_abs(wcombo, ABS_X, 0);
+               wacom_report_abs(wcombo, ABS_Y, 0);
+               if (wacom->tool[0] == BTN_TOOL_MOUSE) {
+                       wacom_report_key(wcombo, BTN_LEFT, 0);
+                       wacom_report_key(wcombo, BTN_RIGHT, 0);
+                       wacom_report_abs(wcombo, ABS_DISTANCE, 0);
+               } else {
+                       wacom_report_abs(wcombo, ABS_PRESSURE, 0);
+                       wacom_report_key(wcombo, BTN_TOUCH, 0);
+                       wacom_report_key(wcombo, BTN_STYLUS, 0);
+                       wacom_report_key(wcombo, BTN_STYLUS2, 0);
+               }
+               wacom_report_abs(wcombo, ABS_MISC, 0); /* reset tool id */
                wacom_report_key(wcombo, wacom->tool[0], 0);
-       wacom_input_sync(wcombo);
+       }
 
        /* send pad data */
        if (wacom->features->type == WACOM_G4) {
-               if ( (wacom->serial[1] & 0xc0) != (data[7] & 0xf8) ) {
+               if (data[7] & 0xf8) {
+                       wacom_input_sync(wcombo); /* sync last event */
                        wacom->id[1] = 1;
                        wacom->serial[1] = (data[7] & 0xf8);
                        wacom_report_key(wcombo, BTN_0, (data[7] & 0x40));
@@ -230,10 +236,15 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo)
                        rw = ((data[7] & 0x18) >> 3) - ((data[7] & 0x20) >> 3);
                        wacom_report_rel(wcombo, REL_WHEEL, rw);
                        wacom_report_key(wcombo, BTN_TOOL_FINGER, 0xf0);
+                       wacom_report_abs(wcombo, ABS_MISC, PAD_DEVICE_ID);
                        wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0);
                } else if (wacom->id[1]) {
+                       wacom_input_sync(wcombo); /* sync last event */
                        wacom->id[1] = 0;
+                       wacom_report_key(wcombo, BTN_0, (data[7] & 0x40));
+                       wacom_report_key(wcombo, BTN_4, (data[7] & 0x80));
                        wacom_report_key(wcombo, BTN_TOOL_FINGER, 0);
+                       wacom_report_abs(wcombo, ABS_MISC, 0);
                        wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0);
                }
        }
@@ -304,28 +315,35 @@ static int wacom_intuos_inout(struct wacom_wac *wacom, void *wcombo)
                        default: /* Unknown tool */
                                wacom->tool[idx] = BTN_TOOL_PEN;
                }
-               /* only large I3 support Lens Cursor */
-               if(!((wacom->tool[idx] == BTN_TOOL_LENS)
-                                && ((wacom->features->type == INTUOS3)
-                                || (wacom->features->type == INTUOS3S)))) {
-                       wacom_report_abs(wcombo, ABS_MISC, wacom->id[idx]); /* report tool id */
-                       wacom_report_key(wcombo, wacom->tool[idx], 1);
-                       wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, wacom->serial[idx]);
-                       return 2;
-               }
                return 1;
        }
 
        /* Exit report */
        if ((data[1] & 0xfe) == 0x80) {
-               if(!((wacom->tool[idx] == BTN_TOOL_LENS)
-                                && ((wacom->features->type == INTUOS3)
-                                || (wacom->features->type == INTUOS3S)))) {
-                       wacom_report_key(wcombo, wacom->tool[idx], 0);
-                       wacom_report_abs(wcombo, ABS_MISC, 0); /* reset tool id */
-                       wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, wacom->serial[idx]);
-                       return 2;
+               wacom_report_abs(wcombo, ABS_X, 0);
+               wacom_report_abs(wcombo, ABS_Y, 0);
+               wacom_report_abs(wcombo, ABS_DISTANCE, 0);
+               if (wacom->tool[idx] >= BTN_TOOL_MOUSE) {
+                       wacom_report_key(wcombo, BTN_LEFT, 0);
+                       wacom_report_key(wcombo, BTN_MIDDLE, 0);
+                       wacom_report_key(wcombo, BTN_RIGHT, 0);
+                       wacom_report_key(wcombo, BTN_SIDE, 0);
+                       wacom_report_key(wcombo, BTN_EXTRA, 0);
+                       wacom_report_abs(wcombo, ABS_THROTTLE, 0);
+                       wacom_report_abs(wcombo, ABS_RZ, 0);
+               } else {
+                       wacom_report_abs(wcombo, ABS_PRESSURE, 0);
+                       wacom_report_abs(wcombo, ABS_TILT_X, 0);
+                       wacom_report_abs(wcombo, ABS_TILT_Y, 0);
+                       wacom_report_key(wcombo, BTN_STYLUS, 0);
+                       wacom_report_key(wcombo, BTN_STYLUS2, 0);
+                       wacom_report_key(wcombo, BTN_TOUCH, 0);
+                       wacom_report_abs(wcombo, ABS_WHEEL, 0);
                }
+               wacom_report_key(wcombo, wacom->tool[idx], 0);
+               wacom_report_abs(wcombo, ABS_MISC, 0); /* reset tool id */
+               wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, wacom->serial[idx]);
+               return 2;
        }
        return 0;
 }
@@ -394,6 +412,7 @@ static int wacom_intuos_irq(struct wacom_wac *wacom, void *wcombo)
                        wacom_report_key(wcombo, wacom->tool[1], 1);
                else
                        wacom_report_key(wcombo, wacom->tool[1], 0);
+               wacom_report_abs(wcombo, ABS_MISC, PAD_DEVICE_ID);
                wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xffffffff);
                 return 1;
        }
@@ -403,6 +422,12 @@ static int wacom_intuos_irq(struct wacom_wac *wacom, void *wcombo)
        if (result)
                 return result-1;
 
+       /* Only large I3 and I1 & I2 support Lense Cursor */
+       if((wacom->tool[idx] == BTN_TOOL_LENS)
+                       && ((wacom->features->type == INTUOS3)
+                       || (wacom->features->type == INTUOS3S)))
+               return 0;
+
        /* Cintiq doesn't send data when RDY bit isn't set */
        if ((wacom->features->type == CINTIQ) && !(data[1] & 0x40))
                  return 0;
@@ -554,11 +579,11 @@ static struct wacom_features wacom_features[] = {
        { "Wacom Volito2 4x5",   8,   5104,  3712,  511, 63, GRAPHIRE },
        { "Wacom Volito2 2x3",   8,   3248,  2320,  511, 63, GRAPHIRE },
        { "Wacom PenPartner2",   8,   3250,  2320,  255, 63, GRAPHIRE },
-       { "Wacom Intuos 4x5",   10,  12700, 10600, 1023, 63, INTUOS },
-       { "Wacom Intuos 6x8",   10,  20320, 16240, 1023, 63, INTUOS },
-       { "Wacom Intuos 9x12",  10,  30480, 24060, 1023, 63, INTUOS },
-       { "Wacom Intuos 12x12", 10,  30480, 31680, 1023, 63, INTUOS },
-       { "Wacom Intuos 12x18", 10,  45720, 31680, 1023, 63, INTUOS },
+       { "Wacom Intuos 4x5",   10,  12700, 10600, 1023, 31, INTUOS },
+       { "Wacom Intuos 6x8",   10,  20320, 16240, 1023, 31, INTUOS },
+       { "Wacom Intuos 9x12",  10,  30480, 24060, 1023, 31, INTUOS },
+       { "Wacom Intuos 12x12", 10,  30480, 31680, 1023, 31, INTUOS },
+       { "Wacom Intuos 12x18", 10,  45720, 31680, 1023, 31, INTUOS },
        { "Wacom PL400",         8,   5408,  4056,  255,  0, PL },
        { "Wacom PL500",         8,   6144,  4608,  255,  0, PL },
        { "Wacom PL600",         8,   6126,  4604,  255,  0, PL },
@@ -571,11 +596,11 @@ static struct wacom_features wacom_features[] = {
        { "Wacom DTF521",        8,   6282,  4762,  511,  0, PL },
        { "Wacom DTF720",        8,   6858,  5506,  511,  0, PL },
        { "Wacom Cintiq Partner",8,  20480, 15360,  511,  0, PTU },
-       { "Wacom Intuos2 4x5",   10, 12700, 10600, 1023, 63, INTUOS },
-       { "Wacom Intuos2 6x8",   10, 20320, 16240, 1023, 63, INTUOS },
-       { "Wacom Intuos2 9x12",  10, 30480, 24060, 1023, 63, INTUOS },
-       { "Wacom Intuos2 12x12", 10, 30480, 31680, 1023, 63, INTUOS },
-       { "Wacom Intuos2 12x18", 10, 45720, 31680, 1023, 63, INTUOS },
+       { "Wacom Intuos2 4x5",   10, 12700, 10600, 1023, 31, INTUOS },
+       { "Wacom Intuos2 6x8",   10, 20320, 16240, 1023, 31, INTUOS },
+       { "Wacom Intuos2 9x12",  10, 30480, 24060, 1023, 31, INTUOS },
+       { "Wacom Intuos2 12x12", 10, 30480, 31680, 1023, 31, INTUOS },
+       { "Wacom Intuos2 12x18", 10, 45720, 31680, 1023, 31, INTUOS },
        { "Wacom Intuos3 4x5",   10, 25400, 20320, 1023, 63, INTUOS3S },
        { "Wacom Intuos3 6x8",   10, 40640, 30480, 1023, 63, INTUOS3 },
        { "Wacom Intuos3 9x12",  10, 60960, 45720, 1023, 63, INTUOS3 },
@@ -584,7 +609,7 @@ static struct wacom_features wacom_features[] = {
        { "Wacom Intuos3 6x11",  10, 54204, 31750, 1023, 63, INTUOS3 },
        { "Wacom Intuos3 4x6",   10, 31496, 19685, 1023, 63, INTUOS3S },
        { "Wacom Cintiq 21UX",   10, 87200, 65600, 1023, 63, CINTIQ },
-       { "Wacom Intuos2 6x8",   10, 20320, 16240, 1023, 63, INTUOS },
+       { "Wacom Intuos2 6x8",   10, 20320, 16240, 1023, 31, INTUOS },
        { }
 };
 
index a1d9ce0..a230222 100644 (file)
@@ -12,6 +12,7 @@
 #define STYLUS_DEVICE_ID       0x02
 #define CURSOR_DEVICE_ID       0x06
 #define ERASER_DEVICE_ID       0x0A
+#define PAD_DEVICE_ID          0x0F
 
 enum {
        PENPARTNER = 0,
index 4907e8b..9c7eb61 100644 (file)
@@ -244,6 +244,20 @@ config USB_TRANCEVIBRATOR
          To compile this driver as a module, choose M here: the
          module will be called trancevibrator.
 
+config USB_IOWARRIOR
+       tristate "IO Warrior driver support"
+       depends on USB
+       help
+         Say Y here if you want to support the IO Warrior devices from Code
+         Mercenaries.  This includes support for the following devices:
+               IO Warrior 40
+               IO Warrior 24
+               IO Warrior 56
+               IO Warrior 24 Power Vampire
+
+         To compile this driver as a module, choose M here: the
+         module will be called iowarrior.
+
 config USB_TEST
        tristate "USB testing driver (DEVELOPMENT)"
        depends on USB && USB_DEVICEFS && EXPERIMENTAL
index dac2d5b..b68e6b7 100644 (file)
@@ -13,6 +13,7 @@ obj-$(CONFIG_USB_EMI26)               += emi26.o
 obj-$(CONFIG_USB_EMI62)                += emi62.o
 obj-$(CONFIG_USB_FTDI_ELAN)    += ftdi-elan.o
 obj-$(CONFIG_USB_IDMOUSE)      += idmouse.o
+obj-$(CONFIG_USB_IOWARRIOR)    += iowarrior.o
 obj-$(CONFIG_USB_LCD)          += usblcd.o
 obj-$(CONFIG_USB_LD)           += ldusb.o
 obj-$(CONFIG_USB_LED)          += usbled.o
diff --git a/drivers/usb/misc/iowarrior.c b/drivers/usb/misc/iowarrior.c
new file mode 100644 (file)
index 0000000..d69665c
--- /dev/null
@@ -0,0 +1,925 @@
+/*
+ *  Native support for the I/O-Warrior USB devices
+ *
+ *  Copyright (c) 2003-2005  Code Mercenaries GmbH
+ *  written by Christian Lucht <lucht@codemercs.com>
+ *
+ *  based on
+
+ *  usb-skeleton.c by Greg Kroah-Hartman  <greg@kroah.com>
+ *  brlvger.c by Stephane Dalton  <sdalton@videotron.ca>
+ *           and St�hane Doyon   <s.doyon@videotron.ca>
+ *
+ *  Released under the GPLv2.
+ */
+
+#include <linux/module.h>
+#include <linux/usb.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/sched.h>
+#include <linux/poll.h>
+#include <linux/version.h>
+#include <linux/usb/iowarrior.h>
+
+/* Version Information */
+#define DRIVER_VERSION "v0.4.0"
+#define DRIVER_AUTHOR "Christian Lucht <lucht@codemercs.com>"
+#define DRIVER_DESC "USB IO-Warrior driver (Linux 2.6.x)"
+
+#define USB_VENDOR_ID_CODEMERCS                1984
+/* low speed iowarrior */
+#define USB_DEVICE_ID_CODEMERCS_IOW40  0x1500
+#define USB_DEVICE_ID_CODEMERCS_IOW24  0x1501
+#define USB_DEVICE_ID_CODEMERCS_IOWPV1 0x1511
+#define USB_DEVICE_ID_CODEMERCS_IOWPV2 0x1512
+/* full speed iowarrior */
+#define USB_DEVICE_ID_CODEMERCS_IOW56  0x1503
+
+/* Get a minor range for your devices from the usb maintainer */
+#ifdef CONFIG_USB_DYNAMIC_MINORS
+#define IOWARRIOR_MINOR_BASE   0
+#else
+#define IOWARRIOR_MINOR_BASE   208     // SKELETON_MINOR_BASE 192 + 16, not offical yet
+#endif
+
+/* interrupt input queue size */
+#define MAX_INTERRUPT_BUFFER 16
+/*
+   maximum number of urbs that are submitted for writes at the same time,
+   this applies to the IOWarrior56 only!
+   IOWarrior24 and IOWarrior40 use synchronous usb_control_msg calls.
+*/
+#define MAX_WRITES_IN_FLIGHT 4
+
+/* Use our own dbg macro */
+#undef dbg
+#define dbg( format, arg... ) do { if( debug ) printk( KERN_DEBUG __FILE__ ": " format "\n" , ## arg ); } while ( 0 )
+
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
+
+/* Module parameters */
+static int debug = 0;
+module_param(debug, bool, 0644);
+MODULE_PARM_DESC(debug, "debug=1 enables debugging messages");
+
+static struct usb_driver iowarrior_driver;
+
+/*--------------*/
+/*     data     */
+/*--------------*/
+
+/* Structure to hold all of our device specific stuff */
+struct iowarrior {
+       struct mutex mutex;                     /* locks this structure */
+       struct usb_device *udev;                /* save off the usb device pointer */
+       struct usb_interface *interface;        /* the interface for this device */
+       unsigned char minor;                    /* the starting minor number for this device */
+       struct usb_endpoint_descriptor *int_out_endpoint;       /* endpoint for reading (needed for IOW56 only) */
+       struct usb_endpoint_descriptor *int_in_endpoint;        /* endpoint for reading */
+       struct urb *int_in_urb;         /* the urb for reading data */
+       unsigned char *int_in_buffer;   /* buffer for data to be read */
+       unsigned char serial_number;    /* to detect lost packages */
+       unsigned char *read_queue;      /* size is MAX_INTERRUPT_BUFFER * packet size */
+       wait_queue_head_t read_wait;
+       wait_queue_head_t write_wait;   /* wait-queue for writing to the device */
+       atomic_t write_busy;            /* number of write-urbs submitted */
+       atomic_t read_idx;
+       atomic_t intr_idx;
+       spinlock_t intr_idx_lock;       /* protects intr_idx */
+       atomic_t overflow_flag;         /* signals an index 'rollover' */
+       int present;                    /* this is 1 as long as the device is connected */
+       int opened;                     /* this is 1 if the device is currently open */
+       char chip_serial[9];            /* the serial number string of the chip connected */
+       int report_size;                /* number of bytes in a report */
+       u16 product_id;
+};
+
+/*--------------*/
+/*    globals   */
+/*--------------*/
+/* prevent races between open() and disconnect() */
+static DECLARE_MUTEX(disconnect_sem);
+
+/*
+ *  USB spec identifies 5 second timeouts.
+ */
+#define GET_TIMEOUT 5
+#define USB_REQ_GET_REPORT  0x01
+//#if 0
+static int usb_get_report(struct usb_device *dev,
+                         struct usb_host_interface *inter, unsigned char type,
+                         unsigned char id, void *buf, int size)
+{
+       return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
+                              USB_REQ_GET_REPORT,
+                              USB_DIR_IN | USB_TYPE_CLASS |
+                              USB_RECIP_INTERFACE, (type << 8) + id,
+                              inter->desc.bInterfaceNumber, buf, size,
+                              GET_TIMEOUT);
+}
+//#endif
+
+#define USB_REQ_SET_REPORT 0x09
+
+static int usb_set_report(struct usb_interface *intf, unsigned char type,
+                         unsigned char id, void *buf, int size)
+{
+       return usb_control_msg(interface_to_usbdev(intf),
+                              usb_sndctrlpipe(interface_to_usbdev(intf), 0),
+                              USB_REQ_SET_REPORT,
+                              USB_TYPE_CLASS | USB_RECIP_INTERFACE,
+                              (type << 8) + id,
+                              intf->cur_altsetting->desc.bInterfaceNumber, buf,
+                              size, 1);
+}
+
+/*---------------------*/
+/* driver registration */
+/*---------------------*/
+/* table of devices that work with this driver */
+static struct usb_device_id iowarrior_ids[] = {
+       {USB_DEVICE(USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW40)},
+       {USB_DEVICE(USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW24)},
+       {USB_DEVICE(USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOWPV1)},
+       {USB_DEVICE(USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOWPV2)},
+       {USB_DEVICE(USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW56)},
+       {}                      /* Terminating entry */
+};
+MODULE_DEVICE_TABLE(usb, iowarrior_ids);
+
+/*
+ * USB callback handler for reading data
+ */
+static void iowarrior_callback(struct urb *urb)
+{
+       struct iowarrior *dev = (struct iowarrior *)urb->context;
+       int intr_idx;
+       int read_idx;
+       int aux_idx;
+       int offset;
+       int status;
+
+       switch (urb->status) {
+       case 0:
+               /* success */
+               break;
+       case -ECONNRESET:
+       case -ENOENT:
+       case -ESHUTDOWN:
+               return;
+       default:
+               goto exit;
+       }
+
+       spin_lock(&dev->intr_idx_lock);
+       intr_idx = atomic_read(&dev->intr_idx);
+       /* aux_idx become previous intr_idx */
+       aux_idx = (intr_idx == 0) ? (MAX_INTERRUPT_BUFFER - 1) : (intr_idx - 1);
+       read_idx = atomic_read(&dev->read_idx);
+
+       /* queue is not empty and it's interface 0 */
+       if ((intr_idx != read_idx)
+           && (dev->interface->cur_altsetting->desc.bInterfaceNumber == 0)) {
+               /* + 1 for serial number */
+               offset = aux_idx * (dev->report_size + 1);
+               if (!memcmp
+                   (dev->read_queue + offset, urb->transfer_buffer,
+                    dev->report_size)) {
+                       /* equal values on interface 0 will be ignored */
+                       spin_unlock(&dev->intr_idx_lock);
+                       goto exit;
+               }
+       }
+
+       /* aux_idx become next intr_idx */
+       aux_idx = (intr_idx == (MAX_INTERRUPT_BUFFER - 1)) ? 0 : (intr_idx + 1);
+       if (read_idx == aux_idx) {
+               /* queue full, dropping oldest input */
+               read_idx = (++read_idx == MAX_INTERRUPT_BUFFER) ? 0 : read_idx;
+               atomic_set(&dev->read_idx, read_idx);
+               atomic_set(&dev->overflow_flag, 1);
+       }
+
+       /* +1 for serial number */
+       offset = intr_idx * (dev->report_size + 1);
+       memcpy(dev->read_queue + offset, urb->transfer_buffer,
+              dev->report_size);
+       *(dev->read_queue + offset + (dev->report_size)) = dev->serial_number++;
+
+       atomic_set(&dev->intr_idx, aux_idx);
+       spin_unlock(&dev->intr_idx_lock);
+       /* tell the blocking read about the new data */
+       wake_up_interruptible(&dev->read_wait);
+
+exit:
+       status = usb_submit_urb(urb, GFP_ATOMIC);
+       if (status)
+               dev_err(&dev->interface->dev, "%s - usb_submit_urb failed with result %d",
+                       __FUNCTION__, status);
+
+}
+
+/*
+ * USB Callback handler for write-ops
+ */
+static void iowarrior_write_callback(struct urb *urb)
+{
+       struct iowarrior *dev;
+       dev = (struct iowarrior *)urb->context;
+       /* sync/async unlink faults aren't errors */
+       if (urb->status &&
+           !(urb->status == -ENOENT ||
+             urb->status == -ECONNRESET || urb->status == -ESHUTDOWN)) {
+               dbg("%s - nonzero write bulk status received: %d",
+                   __func__, urb->status);
+       }
+       /* free up our allocated buffer */
+       usb_buffer_free(urb->dev, urb->transfer_buffer_length,
+                       urb->transfer_buffer, urb->transfer_dma);
+       /* tell a waiting writer the interrupt-out-pipe is available again */
+       atomic_dec(&dev->write_busy);
+       wake_up_interruptible(&dev->write_wait);
+}
+
+/**
+ *     iowarrior_delete
+ */
+static inline void iowarrior_delete(struct iowarrior *dev)
+{
+       dbg("%s - minor %d", __func__, dev->minor);
+       kfree(dev->int_in_buffer);
+       usb_free_urb(dev->int_in_urb);
+       kfree(dev->read_queue);
+       kfree(dev);
+}
+
+/*---------------------*/
+/* fops implementation */
+/*---------------------*/
+
+static int read_index(struct iowarrior *dev)
+{
+       int intr_idx, read_idx;
+
+       read_idx = atomic_read(&dev->read_idx);
+       intr_idx = atomic_read(&dev->intr_idx);
+
+       return (read_idx == intr_idx ? -1 : read_idx);
+}
+
+/**
+ *  iowarrior_read
+ */
+static ssize_t iowarrior_read(struct file *file, char __user *buffer,
+                             size_t count, loff_t *ppos)
+{
+       struct iowarrior *dev;
+       int read_idx;
+       int offset;
+
+       dev = (struct iowarrior *)file->private_data;
+
+       /* verify that the device wasn't unplugged */
+       if (dev == NULL || !dev->present)
+               return -ENODEV;
+
+       dbg("%s - minor %d, count = %zd", __func__, dev->minor, count);
+
+       /* read count must be packet size (+ time stamp) */
+       if ((count != dev->report_size)
+           && (count != (dev->report_size + 1)))
+               return -EINVAL;
+
+       /* repeat until no buffer overrun in callback handler occur */
+       do {
+               atomic_set(&dev->overflow_flag, 0);
+               if ((read_idx = read_index(dev)) == -1) {
+                       /* queue emty */
+                       if (file->f_flags & O_NONBLOCK)
+                               return -EAGAIN;
+                       else {
+                               //next line will return when there is either new data, or the device is unplugged
+                               int r = wait_event_interruptible(dev->read_wait,
+                                                                (!dev->present
+                                                                 || (read_idx =
+                                                                     read_index
+                                                                     (dev)) !=
+                                                                 -1));
+                               if (r) {
+                                       //we were interrupted by a signal
+                                       return -ERESTART;
+                               }
+                               if (!dev->present) {
+                                       //The device was unplugged
+                                       return -ENODEV;
+                               }
+                               if (read_idx == -1) {
+                                       // Can this happen ???
+                                       return 0;
+                               }
+                       }
+               }
+
+               offset = read_idx * (dev->report_size + 1);
+               if (copy_to_user(buffer, dev->read_queue + offset, count)) {
+                       return -EFAULT;
+               }
+       } while (atomic_read(&dev->overflow_flag));
+
+       read_idx = ++read_idx == MAX_INTERRUPT_BUFFER ? 0 : read_idx;
+       atomic_set(&dev->read_idx, read_idx);
+       return count;
+}
+
+/*
+ * iowarrior_write
+ */
+static ssize_t iowarrior_write(struct file *file,
+                              const char __user *user_buffer,
+                              size_t count, loff_t *ppos)
+{
+       struct iowarrior *dev;
+       int retval = 0;
+       char *buf = NULL;       /* for IOW24 and IOW56 we need a buffer */
+       struct urb *int_out_urb = NULL;
+
+       dev = (struct iowarrior *)file->private_data;
+
+       mutex_lock(&dev->mutex);
+       /* verify that the device wasn't unplugged */
+       if (dev == NULL || !dev->present) {
+               retval = -ENODEV;
+               goto exit;
+       }
+       dbg("%s - minor %d, count = %zd", __func__, dev->minor, count);
+       /* if count is 0 we're already done */
+       if (count == 0) {
+               retval = 0;
+               goto exit;
+       }
+       /* We only accept full reports */
+       if (count != dev->report_size) {
+               retval = -EINVAL;
+               goto exit;
+       }
+       switch (dev->product_id) {
+       case USB_DEVICE_ID_CODEMERCS_IOW24:
+       case USB_DEVICE_ID_CODEMERCS_IOWPV1:
+       case USB_DEVICE_ID_CODEMERCS_IOWPV2:
+       case USB_DEVICE_ID_CODEMERCS_IOW40:
+               /* IOW24 and IOW40 use a synchronous call */
+               buf = kmalloc(8, GFP_KERNEL);   /* 8 bytes are enough for both products */
+               if (!buf) {
+                       retval = -ENOMEM;
+                       goto exit;
+               }
+               if (copy_from_user(buf, user_buffer, count)) {
+                       retval = -EFAULT;
+                       kfree(buf);
+                       goto exit;
+               }
+               retval = usb_set_report(dev->interface, 2, 0, buf, count);
+               kfree(buf);
+               goto exit;
+               break;
+       case USB_DEVICE_ID_CODEMERCS_IOW56:
+               /* The IOW56 uses asynchronous IO and more urbs */
+               if (atomic_read(&dev->write_busy) == MAX_WRITES_IN_FLIGHT) {
+                       /* Wait until we are below the limit for submitted urbs */
+                       if (file->f_flags & O_NONBLOCK) {
+                               retval = -EAGAIN;
+                               goto exit;
+                       } else {
+                               retval = wait_event_interruptible(dev->write_wait,
+                                                                 (!dev->present || (atomic_read (&dev-> write_busy) < MAX_WRITES_IN_FLIGHT)));
+                               if (retval) {
+                                       /* we were interrupted by a signal */
+                                       retval = -ERESTART;
+                                       goto exit;
+                               }
+                               if (!dev->present) {
+                                       /* The device was unplugged */
+                                       retval = -ENODEV;
+                                       goto exit;
+                               }
+                               if (!dev->opened) {
+                                       /* We were closed while waiting for an URB */
+                                       retval = -ENODEV;
+                                       goto exit;
+                               }
+                       }
+               }
+               atomic_inc(&dev->write_busy);
+               int_out_urb = usb_alloc_urb(0, GFP_KERNEL);
+               if (!int_out_urb) {
+                       retval = -ENOMEM;
+                       dbg("%s Unable to allocate urb ", __func__);
+                       goto error;
+               }
+               buf = usb_buffer_alloc(dev->udev, dev->report_size,
+                                      GFP_KERNEL, &int_out_urb->transfer_dma);
+               if (!buf) {
+                       retval = -ENOMEM;
+                       dbg("%s Unable to allocate buffer ", __func__);
+                       goto error;
+               }
+               usb_fill_int_urb(int_out_urb, dev->udev,
+                                usb_sndintpipe(dev->udev,
+                                               dev->int_out_endpoint->bEndpointAddress),
+                                buf, dev->report_size,
+                                iowarrior_write_callback, dev,
+                                dev->int_out_endpoint->bInterval);
+               int_out_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+               if (copy_from_user(buf, user_buffer, count)) {
+                       retval = -EFAULT;
+                       goto error;
+               }
+               retval = usb_submit_urb(int_out_urb, GFP_KERNEL);
+               if (retval) {
+                       dbg("%s submit error %d for urb nr.%d", __func__,
+                           retval, atomic_read(&dev->write_busy));
+                       goto error;
+               }
+               /* submit was ok */
+               retval = count;
+               usb_free_urb(int_out_urb);
+               goto exit;
+               break;
+       default:
+               /* what do we have here ? An unsupported Product-ID ? */
+               dev_err(&dev->interface->dev, "%s - not supported for product=0x%x",
+                       __FUNCTION__, dev->product_id);
+               retval = -EFAULT;
+               goto exit;
+               break;
+       }
+error:
+       usb_buffer_free(dev->udev, dev->report_size, buf,
+                       int_out_urb->transfer_dma);
+       usb_free_urb(int_out_urb);
+       atomic_dec(&dev->write_busy);
+       wake_up_interruptible(&dev->write_wait);
+exit:
+       mutex_unlock(&dev->mutex);
+       return retval;
+}
+
+/**
+ *     iowarrior_ioctl
+ */
+static int iowarrior_ioctl(struct inode *inode, struct file *file,
+                          unsigned int cmd, unsigned long arg)
+{
+       struct iowarrior *dev = NULL;
+       __u8 *buffer;
+       __u8 __user *user_buffer;
+       int retval;
+       int io_res;             /* checks for bytes read/written and copy_to/from_user results */
+
+       dev = (struct iowarrior *)file->private_data;
+       if (dev == NULL) {
+               return -ENODEV;
+       }
+
+       buffer = kzalloc(dev->report_size, GFP_KERNEL);
+       if (!buffer)
+               return -ENOMEM;
+
+       /* lock this object */
+       mutex_lock(&dev->mutex);
+
+       /* verify that the device wasn't unplugged */
+       if (!dev->present) {
+               mutex_unlock(&dev->mutex);
+               return -ENODEV;
+       }
+
+       dbg("%s - minor %d, cmd 0x%.4x, arg %ld", __func__, dev->minor, cmd,
+           arg);
+
+       retval = 0;
+       io_res = 0;
+       switch (cmd) {
+       case IOW_WRITE:
+               if (dev->product_id == USB_DEVICE_ID_CODEMERCS_IOW24 ||
+                   dev->product_id == USB_DEVICE_ID_CODEMERCS_IOWPV1 ||
+                   dev->product_id == USB_DEVICE_ID_CODEMERCS_IOWPV2 ||
+                   dev->product_id == USB_DEVICE_ID_CODEMERCS_IOW40) {
+                       user_buffer = (__u8 __user *)arg;
+                       io_res = copy_from_user(buffer, user_buffer,
+                                               dev->report_size);
+                       if (io_res) {
+                               retval = -EFAULT;
+                       } else {
+                               io_res = usb_set_report(dev->interface, 2, 0,
+                                                       buffer,
+                                                       dev->report_size);
+                               if (io_res < 0)
+                                       retval = io_res;
+                       }
+               } else {
+                       retval = -EINVAL;
+                       dev_err(&dev->interface->dev,
+                               "ioctl 'IOW_WRITE' is not supported for product=0x%x.",
+                               dev->product_id);
+               }
+               break;
+       case IOW_READ:
+               user_buffer = (__u8 __user *)arg;
+               io_res = usb_get_report(dev->udev,
+                                       dev->interface->cur_altsetting, 1, 0,
+                                       buffer, dev->report_size);
+               if (io_res < 0)
+                       retval = io_res;
+               else {
+                       io_res = copy_to_user(user_buffer, buffer, dev->report_size);
+                       if (io_res < 0)
+                               retval = -EFAULT;
+               }
+               break;
+       case IOW_GETINFO:
+               {
+                       /* Report available information for the device */
+                       struct iowarrior_info info;
+                       /* needed for power consumption */
+                       struct usb_config_descriptor *cfg_descriptor = &dev->udev->actconfig->desc;
+
+                       /* directly from the descriptor */
+                       info.vendor = le16_to_cpu(dev->udev->descriptor.idVendor);
+                       info.product = dev->product_id;
+                       info.revision = le16_to_cpu(dev->udev->descriptor.bcdDevice);
+
+                       /* 0==UNKNOWN, 1==LOW(usb1.1) ,2=FULL(usb1.1), 3=HIGH(usb2.0) */
+                       info.speed = le16_to_cpu(dev->udev->speed);
+                       info.if_num = dev->interface->cur_altsetting->desc.bInterfaceNumber;
+                       info.report_size = dev->report_size;
+
+                       /* serial number string has been read earlier 8 chars or empty string */
+                       memcpy(info.serial, dev->chip_serial,
+                              sizeof(dev->chip_serial));
+                       if (cfg_descriptor == NULL) {
+                               info.power = -1;        /* no information available */
+                       } else {
+                               /* the MaxPower is stored in units of 2mA to make it fit into a byte-value */
+                               info.power = cfg_descriptor->bMaxPower * 2;
+                       }
+                       io_res = copy_to_user((struct iowarrior_info __user *)arg, &info,
+                                        sizeof(struct iowarrior_info));
+                       if (io_res < 0)
+                               retval = -EFAULT;
+                       break;
+               }
+       default:
+               /* return that we did not understand this ioctl call */
+               retval = -ENOTTY;
+               break;
+       }
+
+       /* unlock the device */
+       mutex_unlock(&dev->mutex);
+       return retval;
+}
+
+/**
+ *     iowarrior_open
+ */
+static int iowarrior_open(struct inode *inode, struct file *file)
+{
+       struct iowarrior *dev = NULL;
+       struct usb_interface *interface;
+       int subminor;
+       int retval = 0;
+
+       dbg("%s", __func__);
+
+       subminor = iminor(inode);
+
+       /* prevent disconnects */
+       down(&disconnect_sem);
+
+       interface = usb_find_interface(&iowarrior_driver, subminor);
+       if (!interface) {
+               err("%s - error, can't find device for minor %d", __FUNCTION__,
+                   subminor);
+               retval = -ENODEV;
+               goto out;
+       }
+
+       dev = usb_get_intfdata(interface);
+       if (!dev) {
+               retval = -ENODEV;
+               goto out;
+       }
+
+       /* Only one process can open each device, no sharing. */
+       if (dev->opened) {
+               retval = -EBUSY;
+               goto out;
+       }
+
+       /* setup interrupt handler for receiving values */
+       if ((retval = usb_submit_urb(dev->int_in_urb, GFP_KERNEL)) < 0) {
+               dev_err(&interface->dev, "Error %d while submitting URB\n", retval);
+               retval = -EFAULT;
+               goto out;
+       }
+       /* increment our usage count for the driver */
+       ++dev->opened;
+       /* save our object in the file's private structure */
+       file->private_data = dev;
+       retval = 0;
+
+out:
+       up(&disconnect_sem);
+       return retval;
+}
+
+/**
+ *     iowarrior_release
+ */
+static int iowarrior_release(struct inode *inode, struct file *file)
+{
+       struct iowarrior *dev;
+       int retval = 0;
+
+       dev = (struct iowarrior *)file->private_data;
+       if (dev == NULL) {
+               return -ENODEV;
+       }
+
+       dbg("%s - minor %d", __func__, dev->minor);
+
+       /* lock our device */
+       mutex_lock(&dev->mutex);
+
+       if (dev->opened <= 0) {
+               retval = -ENODEV;       /* close called more than once */
+               mutex_unlock(&dev->mutex);
+       } else {
+               dev->opened = 0;        /* we're closeing now */
+               retval = 0;
+               if (dev->present) {
+                       /*
+                          The device is still connected so we only shutdown
+                          pending read-/write-ops.
+                        */
+                       usb_kill_urb(dev->int_in_urb);
+                       wake_up_interruptible(&dev->read_wait);
+                       wake_up_interruptible(&dev->write_wait);
+                       mutex_unlock(&dev->mutex);
+               } else {
+                       /* The device was unplugged, cleanup resources */
+                       mutex_unlock(&dev->mutex);
+                       iowarrior_delete(dev);
+               }
+       }
+       return retval;
+}
+
+static unsigned iowarrior_poll(struct file *file, poll_table * wait)
+{
+       struct iowarrior *dev = file->private_data;
+       unsigned int mask = 0;
+
+       if (!dev->present)
+               return POLLERR | POLLHUP;
+
+       poll_wait(file, &dev->read_wait, wait);
+       poll_wait(file, &dev->write_wait, wait);
+
+       if (!dev->present)
+               return POLLERR | POLLHUP;
+
+       if (read_index(dev) != -1)
+               mask |= POLLIN | POLLRDNORM;
+
+       if (atomic_read(&dev->write_busy) < MAX_WRITES_IN_FLIGHT)
+               mask |= POLLOUT | POLLWRNORM;
+       return mask;
+}
+
+/*
+ * File operations needed when we register this driver.
+ * This assumes that this driver NEEDS file operations,
+ * of course, which means that the driver is expected
+ * to have a node in the /dev directory. If the USB
+ * device were for a network interface then the driver
+ * would use "struct net_driver" instead, and a serial
+ * device would use "struct tty_driver".
+ */
+static struct file_operations iowarrior_fops = {
+       .owner = THIS_MODULE,
+       .write = iowarrior_write,
+       .read = iowarrior_read,
+       .ioctl = iowarrior_ioctl,
+       .open = iowarrior_open,
+       .release = iowarrior_release,
+       .poll = iowarrior_poll,
+};
+
+/*
+ * usb class driver info in order to get a minor number from the usb core,
+ * and to have the device registered with devfs and the driver core
+ */
+static struct usb_class_driver iowarrior_class = {
+       .name = "iowarrior%d",
+       .fops = &iowarrior_fops,
+       .minor_base = IOWARRIOR_MINOR_BASE,
+};
+
+/*---------------------------------*/
+/*  probe and disconnect functions */
+/*---------------------------------*/
+/**
+ *     iowarrior_probe
+ *
+ *     Called by the usb core when a new device is connected that it thinks
+ *     this driver might be interested in.
+ */
+static int iowarrior_probe(struct usb_interface *interface,
+                          const struct usb_device_id *id)
+{
+       struct usb_device *udev = interface_to_usbdev(interface);
+       struct iowarrior *dev = NULL;
+       struct usb_host_interface *iface_desc;
+       struct usb_endpoint_descriptor *endpoint;
+       int i;
+       int retval = -ENOMEM;
+       int idele = 0;
+
+       /* allocate memory for our device state and intialize it */
+       dev = kzalloc(sizeof(struct iowarrior), GFP_KERNEL);
+       if (dev == NULL) {
+               dev_err(&interface->dev, "Out of memory");
+               return retval;
+       }
+
+       mutex_init(&dev->mutex);
+
+       atomic_set(&dev->intr_idx, 0);
+       atomic_set(&dev->read_idx, 0);
+       spin_lock_init(&dev->intr_idx_lock);
+       atomic_set(&dev->overflow_flag, 0);
+       init_waitqueue_head(&dev->read_wait);
+       atomic_set(&dev->write_busy, 0);
+       init_waitqueue_head(&dev->write_wait);
+
+       dev->udev = udev;
+       dev->interface = interface;
+
+       iface_desc = interface->cur_altsetting;
+       dev->product_id = le16_to_cpu(udev->descriptor.idProduct);
+
+       /* set up the endpoint information */
+       for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
+               endpoint = &iface_desc->endpoint[i].desc;
+
+               if (usb_endpoint_is_int_in(endpoint))
+                       dev->int_in_endpoint = endpoint;
+               if (usb_endpoint_is_int_out(endpoint))
+                       /* this one will match for the IOWarrior56 only */
+                       dev->int_out_endpoint = endpoint;
+       }
+       /* we have to check the report_size often, so remember it in the endianess suitable for our machine */
+       dev->report_size = le16_to_cpu(dev->int_in_endpoint->wMaxPacketSize);
+       if ((dev->interface->cur_altsetting->desc.bInterfaceNumber == 0) &&
+           (dev->product_id == USB_DEVICE_ID_CODEMERCS_IOW56))
+               /* IOWarrior56 has wMaxPacketSize different from report size */
+               dev->report_size = 7;
+
+       /* create the urb and buffer for reading */
+       dev->int_in_urb = usb_alloc_urb(0, GFP_KERNEL);
+       if (!dev->int_in_urb) {
+               dev_err(&interface->dev, "Couldn't allocate interrupt_in_urb\n");
+               goto error;
+       }
+       dev->int_in_buffer = kmalloc(dev->report_size, GFP_KERNEL);
+       if (!dev->int_in_buffer) {
+               dev_err(&interface->dev, "Couldn't allocate int_in_buffer\n");
+               goto error;
+       }
+       usb_fill_int_urb(dev->int_in_urb, dev->udev,
+                        usb_rcvintpipe(dev->udev,
+                                       dev->int_in_endpoint->bEndpointAddress),
+                        dev->int_in_buffer, dev->report_size,
+                        iowarrior_callback, dev,
+                        dev->int_in_endpoint->bInterval);
+       /* create an internal buffer for interrupt data from the device */
+       dev->read_queue =
+           kmalloc(((dev->report_size + 1) * MAX_INTERRUPT_BUFFER),
+                   GFP_KERNEL);
+       if (!dev->read_queue) {
+               dev_err(&interface->dev, "Couldn't allocate read_queue\n");
+               goto error;
+       }
+       /* Get the serial-number of the chip */
+       memset(dev->chip_serial, 0x00, sizeof(dev->chip_serial));
+       usb_string(udev, udev->descriptor.iSerialNumber, dev->chip_serial,
+                  sizeof(dev->chip_serial));
+       if (strlen(dev->chip_serial) != 8)
+               memset(dev->chip_serial, 0x00, sizeof(dev->chip_serial));
+
+       /* Set the idle timeout to 0, if this is interface 0 */
+       if (dev->interface->cur_altsetting->desc.bInterfaceNumber == 0) {
+               idele = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
+                                       0x0A,
+                                       USB_TYPE_CLASS | USB_RECIP_INTERFACE, 0,
+                                       0, NULL, 0, USB_CTRL_SET_TIMEOUT);
+               dbg("idele = %d", idele);
+       }
+       /* allow device read and ioctl */
+       dev->present = 1;
+
+       /* we can register the device now, as it is ready */
+       usb_set_intfdata(interface, dev);
+
+       retval = usb_register_dev(interface, &iowarrior_class);
+       if (retval) {
+               /* something prevented us from registering this driver */
+               dev_err(&interface->dev, "Not able to get a minor for this device.\n");
+               usb_set_intfdata(interface, NULL);
+               goto error;
+       }
+
+       dev->minor = interface->minor;
+
+       /* let the user know what node this device is now attached to */
+       dev_info(&interface->dev, "IOWarrior product=0x%x, serial=%s interface=%d "
+                "now attached to iowarrior%d\n", dev->product_id, dev->chip_serial,
+                iface_desc->desc.bInterfaceNumber, dev->minor - IOWARRIOR_MINOR_BASE);
+       return retval;
+
+error:
+       iowarrior_delete(dev);
+       return retval;
+}
+
+/**
+ *     iowarrior_disconnect
+ *
+ *     Called by the usb core when the device is removed from the system.
+ */
+static void iowarrior_disconnect(struct usb_interface *interface)
+{
+       struct iowarrior *dev;
+       int minor;
+
+       /* prevent races with open() */
+       down(&disconnect_sem);
+
+       dev = usb_get_intfdata(interface);
+       usb_set_intfdata(interface, NULL);
+
+       mutex_lock(&dev->mutex);
+
+       minor = dev->minor;
+
+       /* give back our minor */
+       usb_deregister_dev(interface, &iowarrior_class);
+
+       /* prevent device read, write and ioctl */
+       dev->present = 0;
+
+       mutex_unlock(&dev->mutex);
+
+       if (dev->opened) {
+               /* There is a process that holds a filedescriptor to the device ,
+                  so we only shutdown read-/write-ops going on.
+                  Deleting the device is postponed until close() was called.
+                */
+               usb_kill_urb(dev->int_in_urb);
+               wake_up_interruptible(&dev->read_wait);
+               wake_up_interruptible(&dev->write_wait);
+       } else {
+               /* no process is using the device, cleanup now */
+               iowarrior_delete(dev);
+       }
+       up(&disconnect_sem);
+
+       dev_info(&interface->dev, "I/O-Warror #%d now disconnected\n",
+                minor - IOWARRIOR_MINOR_BASE);
+}
+
+/* usb specific object needed to register this driver with the usb subsystem */
+static struct usb_driver iowarrior_driver = {
+       .name = "iowarrior",
+       .probe = iowarrior_probe,
+       .disconnect = iowarrior_disconnect,
+       .id_table = iowarrior_ids,
+};
+
+static int __init iowarrior_init(void)
+{
+       return usb_register(&iowarrior_driver);
+}
+
+static void __exit iowarrior_exit(void)
+{
+       usb_deregister(&iowarrior_driver);
+}
+
+module_init(iowarrior_init);
+module_exit(iowarrior_exit);
index c01dfe6..b2bedd9 100644 (file)
@@ -1165,7 +1165,7 @@ err_dev:
        return rc;
 }
 
-void __exit mon_bin_exit(void)
+void mon_bin_exit(void)
 {
        cdev_del(&mon_bin_cdev);
        unregister_chrdev_region(mon_bin_dev0, MON_BIN_MAX_MINOR);
index d38a127..494ee3b 100644 (file)
@@ -520,7 +520,7 @@ int __init mon_text_init(void)
        return 0;
 }
 
-void __exit mon_text_exit(void)
+void mon_text_exit(void)
 {
        debugfs_remove(mon_dir);
 }
index 4f949ce..efdfd89 100644 (file)
@@ -57,9 +57,9 @@ void mon_text_del(struct mon_bus *mbus);
 // void mon_bin_add(struct mon_bus *);
 
 int __init mon_text_init(void);
-void __exit mon_text_exit(void);
+void mon_text_exit(void);
 int __init mon_bin_init(void);
-void __exit mon_bin_exit(void);
+void mon_bin_exit(void);
 
 /*
  * DMA interface.
index 0f3d7db..3de564b 100644 (file)
@@ -186,6 +186,15 @@ config USB_NET_CDCETHER
          IEEE 802 "local assignment" bit is set in the address, a "usbX"
          name is used instead.
 
+config USB_NET_DM9601
+       tristate "Davicom DM9601 based USB 1.1 10/100 ethernet devices"
+       depends on USB_USBNET
+       select CRC32
+       select USB_USBNET_MII
+       help
+         This option adds support for Davicom DM9601 based USB 1.1
+         10/100 Ethernet adapters.
+
 config USB_NET_GL620A
        tristate "GeneSys GL620USB-A based cables"
        depends on USB_USBNET
index 7b51964..595a539 100644 (file)
@@ -8,6 +8,7 @@ obj-$(CONFIG_USB_PEGASUS)       += pegasus.o
 obj-$(CONFIG_USB_RTL8150)      += rtl8150.o
 obj-$(CONFIG_USB_NET_AX8817X)  += asix.o
 obj-$(CONFIG_USB_NET_CDCETHER) += cdc_ether.o
+obj-$(CONFIG_USB_NET_DM9601)   += dm9601.o
 obj-$(CONFIG_USB_NET_GL620A)   += gl620a.o
 obj-$(CONFIG_USB_NET_NET1080)  += net1080.o
 obj-$(CONFIG_USB_NET_PLUSB)    += plusb.o
index 7ef2e4b..5808ea0 100644 (file)
@@ -1395,9 +1395,9 @@ static const struct usb_device_id products [] = {
        USB_DEVICE (0x07b8, 0x420a),
        .driver_info =  (unsigned long) &hawking_uf200_info,
 }, {
-        // Billionton Systems, USB2AR
-        USB_DEVICE (0x08dd, 0x90ff),
-        .driver_info =  (unsigned long) &ax8817x_info,
+       // Billionton Systems, USB2AR
+       USB_DEVICE (0x08dd, 0x90ff),
+       .driver_info =  (unsigned long) &ax8817x_info,
 }, {
        // ATEN UC210T
        USB_DEVICE (0x0557, 0x2009),
@@ -1422,10 +1422,14 @@ static const struct usb_device_id       products [] = {
        // goodway corp usb gwusb2e
        USB_DEVICE (0x1631, 0x6200),
        .driver_info = (unsigned long) &ax8817x_info,
+}, {
+       // JVC MP-PRX1 Port Replicator
+       USB_DEVICE (0x04f1, 0x3008),
+       .driver_info = (unsigned long) &ax8817x_info,
 }, {
        // ASIX AX88772 10/100
-        USB_DEVICE (0x0b95, 0x7720),
-        .driver_info = (unsigned long) &ax88772_info,
+       USB_DEVICE (0x0b95, 0x7720),
+       .driver_info = (unsigned long) &ax88772_info,
 }, {
        // ASIX AX88178 10/100/1000
        USB_DEVICE (0x0b95, 0x1780),
diff --git a/drivers/usb/net/dm9601.c b/drivers/usb/net/dm9601.c
new file mode 100644 (file)
index 0000000..4a932e1
--- /dev/null
@@ -0,0 +1,606 @@
+/*
+ * Davicom DM9601 USB 1.1 10/100Mbps ethernet devices
+ *
+ * Peter Korsgaard <jacmet@sunsite.dk>
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2.  This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+//#define DEBUG
+
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+#include <linux/mii.h>
+#include <linux/usb.h>
+#include <linux/crc32.h>
+
+#include "usbnet.h"
+
+/* datasheet:
+ http://www.davicom.com.tw/big5/download/Data%20Sheet/DM9601-DS-P01-930914.pdf
+*/
+
+/* control requests */
+#define DM_READ_REGS   0x00
+#define DM_WRITE_REGS  0x01
+#define DM_READ_MEMS   0x02
+#define DM_WRITE_REG   0x03
+#define DM_WRITE_MEMS  0x05
+#define DM_WRITE_MEM   0x07
+
+/* registers */
+#define DM_NET_CTRL    0x00
+#define DM_RX_CTRL     0x05
+#define DM_SHARED_CTRL 0x0b
+#define DM_SHARED_ADDR 0x0c
+#define DM_SHARED_DATA 0x0d    /* low + high */
+#define DM_PHY_ADDR    0x10    /* 6 bytes */
+#define DM_MCAST_ADDR  0x16    /* 8 bytes */
+#define DM_GPR_CTRL    0x1e
+#define DM_GPR_DATA    0x1f
+
+#define DM_MAX_MCAST   64
+#define DM_MCAST_SIZE  8
+#define DM_EEPROM_LEN  256
+#define DM_TX_OVERHEAD 2       /* 2 byte header */
+#define DM_RX_OVERHEAD 7       /* 3 byte header + 4 byte crc tail */
+#define DM_TIMEOUT     1000
+
+
+static int dm_read(struct usbnet *dev, u8 reg, u16 length, void *data)
+{
+       devdbg(dev, "dm_read() reg=0x%02x length=%d", reg, length);
+       return usb_control_msg(dev->udev,
+                              usb_rcvctrlpipe(dev->udev, 0),
+                              DM_READ_REGS,
+                              USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+                              0, reg, data, length, USB_CTRL_SET_TIMEOUT);
+}
+
+static int dm_read_reg(struct usbnet *dev, u8 reg, u8 *value)
+{
+       return dm_read(dev, reg, 1, value);
+}
+
+static int dm_write(struct usbnet *dev, u8 reg, u16 length, void *data)
+{
+       devdbg(dev, "dm_write() reg=0x%02x, length=%d", reg, length);
+       return usb_control_msg(dev->udev,
+                              usb_sndctrlpipe(dev->udev, 0),
+                              DM_WRITE_REGS,
+                              USB_DIR_OUT | USB_TYPE_VENDOR |USB_RECIP_DEVICE,
+                              0, reg, data, length, USB_CTRL_SET_TIMEOUT);
+}
+
+static int dm_write_reg(struct usbnet *dev, u8 reg, u8 value)
+{
+       devdbg(dev, "dm_write_reg() reg=0x%02x, value=0x%02x", reg, value);
+       return usb_control_msg(dev->udev,
+                              usb_sndctrlpipe(dev->udev, 0),
+                              DM_WRITE_REG,
+                              USB_DIR_OUT | USB_TYPE_VENDOR |USB_RECIP_DEVICE,
+                              value, reg, 0, 0, USB_CTRL_SET_TIMEOUT);
+}
+
+static void dm_write_async_callback(struct urb *urb)
+{
+       struct usb_ctrlrequest *req = (struct usb_ctrlrequest *)urb->context;
+
+       if (urb->status < 0)
+               printk(KERN_DEBUG "dm_write_async_callback() failed with %d",
+                      urb->status);
+
+       kfree(req);
+       usb_free_urb(urb);
+}
+
+static void dm_write_async(struct usbnet *dev, u8 reg, u16 length, void *data)
+{
+       struct usb_ctrlrequest *req;
+       struct urb *urb;
+       int status;
+
+       devdbg(dev, "dm_write_async() reg=0x%02x length=%d", reg, length);
+
+       urb = usb_alloc_urb(0, GFP_ATOMIC);
+       if (!urb) {
+               deverr(dev, "Error allocating URB in dm_write_async!");
+               return;
+       }
+
+       req = kmalloc(sizeof(struct usb_ctrlrequest), GFP_ATOMIC);
+       if (!req) {
+               deverr(dev, "Failed to allocate memory for control request");
+               usb_free_urb(urb);
+               return;
+       }
+
+       req->bRequestType = USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE;
+       req->bRequest = DM_WRITE_REGS;
+       req->wValue = 0;
+       req->wIndex = cpu_to_le16(reg);
+       req->wLength = cpu_to_le16(length);
+
+       usb_fill_control_urb(urb, dev->udev,
+                            usb_sndctrlpipe(dev->udev, 0),
+                            (void *)req, data, length,
+                            dm_write_async_callback, req);
+
+       status = usb_submit_urb(urb, GFP_ATOMIC);
+       if (status < 0) {
+               deverr(dev, "Error submitting the control message: status=%d",
+                      status);
+               kfree(req);
+               usb_free_urb(urb);
+       }
+}
+
+static void dm_write_reg_async(struct usbnet *dev, u8 reg, u8 value)
+{
+       struct usb_ctrlrequest *req;
+       struct urb *urb;
+       int status;
+
+       devdbg(dev, "dm_write_reg_async() reg=0x%02x value=0x%02x",
+              reg, value);
+
+       urb = usb_alloc_urb(0, GFP_ATOMIC);
+       if (!urb) {
+               deverr(dev, "Error allocating URB in dm_write_async!");
+               return;
+       }
+
+       req = kmalloc(sizeof(struct usb_ctrlrequest), GFP_ATOMIC);
+       if (!req) {
+               deverr(dev, "Failed to allocate memory for control request");
+               usb_free_urb(urb);
+               return;
+       }
+
+       req->bRequestType = USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE;
+       req->bRequest = DM_WRITE_REG;
+       req->wValue = cpu_to_le16(value);
+       req->wIndex = cpu_to_le16(reg);
+       req->wLength = 0;
+
+       usb_fill_control_urb(urb, dev->udev,
+                            usb_sndctrlpipe(dev->udev, 0),
+                            (void *)req, 0, 0, dm_write_async_callback, req);
+
+       status = usb_submit_urb(urb, GFP_ATOMIC);
+       if (status < 0) {
+               deverr(dev, "Error submitting the control message: status=%d",
+                      status);
+               kfree(req);
+               usb_free_urb(urb);
+       }
+}
+
+static int dm_read_shared_word(struct usbnet *dev, int phy, u8 reg, u16 *value)
+{
+       int ret, i;
+
+       mutex_lock(&dev->phy_mutex);
+
+       dm_write_reg(dev, DM_SHARED_ADDR, phy ? (reg | 0x40) : reg);
+       dm_write_reg(dev, DM_SHARED_CTRL, phy ? 0xc : 0x4);
+
+       for (i = 0; i < DM_TIMEOUT; i++) {
+               u8 tmp;
+
+               udelay(1);
+               ret = dm_read_reg(dev, DM_SHARED_CTRL, &tmp);
+               if (ret < 0)
+                       goto out;
+
+               /* ready */
+               if ((tmp & 1) == 0)
+                       break;
+       }
+
+       if (i == DM_TIMEOUT) {
+               deverr(dev, "%s read timed out!", phy ? "phy" : "eeprom");
+               ret = -EIO;
+               goto out;
+       }
+
+       dm_write_reg(dev, DM_SHARED_CTRL, 0x0);
+       ret = dm_read(dev, DM_SHARED_DATA, 2, value);
+
+       devdbg(dev, "read shared %d 0x%02x returned 0x%04x, %d",
+              phy, reg, *value, ret);
+
+ out:
+       mutex_unlock(&dev->phy_mutex);
+       return ret;
+}
+
+static int dm_write_shared_word(struct usbnet *dev, int phy, u8 reg, u16 value)
+{
+       int ret, i;
+
+       mutex_lock(&dev->phy_mutex);
+
+       ret = dm_write(dev, DM_SHARED_DATA, 2, &value);
+       if (ret < 0)
+               goto out;
+
+       dm_write_reg(dev, DM_SHARED_ADDR, phy ? (reg | 0x40) : reg);
+       dm_write_reg(dev, DM_SHARED_CTRL, phy ? 0x1c : 0x14);
+
+       for (i = 0; i < DM_TIMEOUT; i++) {
+               u8 tmp;
+
+               udelay(1);
+               ret = dm_read_reg(dev, DM_SHARED_CTRL, &tmp);
+               if (ret < 0)
+                       goto out;
+
+               /* ready */
+               if ((tmp & 1) == 0)
+                       break;
+       }
+
+       if (i == DM_TIMEOUT) {
+               deverr(dev, "%s write timed out!", phy ? "phy" : "eeprom");
+               ret = -EIO;
+               goto out;
+       }
+
+       dm_write_reg(dev, DM_SHARED_CTRL, 0x0);
+
+out:
+       mutex_unlock(&dev->phy_mutex);
+       return ret;
+}
+
+static int dm_read_eeprom_word(struct usbnet *dev, u8 offset, void *value)
+{
+       return dm_read_shared_word(dev, 0, offset, value);
+}
+
+
+
+static int dm9601_get_eeprom_len(struct net_device *dev)
+{
+       return DM_EEPROM_LEN;
+}
+
+static int dm9601_get_eeprom(struct net_device *net,
+                            struct ethtool_eeprom *eeprom, u8 * data)
+{
+       struct usbnet *dev = netdev_priv(net);
+       u16 *ebuf = (u16 *) data;
+       int i;
+
+       /* access is 16bit */
+       if ((eeprom->offset % 2) || (eeprom->len % 2))
+               return -EINVAL;
+
+       for (i = 0; i < eeprom->len / 2; i++) {
+               if (dm_read_eeprom_word(dev, eeprom->offset / 2 + i,
+                                       &ebuf[i]) < 0)
+                       return -EINVAL;
+       }
+       return 0;
+}
+
+static int dm9601_mdio_read(struct net_device *netdev, int phy_id, int loc)
+{
+       struct usbnet *dev = netdev_priv(netdev);
+
+       u16 res;
+
+       if (phy_id) {
+               devdbg(dev, "Only internal phy supported");
+               return 0;
+       }
+
+       dm_read_shared_word(dev, 1, loc, &res);
+
+       devdbg(dev,
+              "dm9601_mdio_read() phy_id=0x%02x, loc=0x%02x, returns=0x%04x",
+              phy_id, loc, le16_to_cpu(res));
+
+       return le16_to_cpu(res);
+}
+
+static void dm9601_mdio_write(struct net_device *netdev, int phy_id, int loc,
+                             int val)
+{
+       struct usbnet *dev = netdev_priv(netdev);
+       u16 res = cpu_to_le16(val);
+
+       if (phy_id) {
+               devdbg(dev, "Only internal phy supported");
+               return;
+       }
+
+       devdbg(dev,"dm9601_mdio_write() phy_id=0x%02x, loc=0x%02x, val=0x%04x",
+              phy_id, loc, val);
+
+       dm_write_shared_word(dev, 1, loc, res);
+}
+
+static void dm9601_get_drvinfo(struct net_device *net,
+                              struct ethtool_drvinfo *info)
+{
+       /* Inherit standard device info */
+       usbnet_get_drvinfo(net, info);
+       info->eedump_len = DM_EEPROM_LEN;
+}
+
+static u32 dm9601_get_link(struct net_device *net)
+{
+       struct usbnet *dev = netdev_priv(net);
+
+       return mii_link_ok(&dev->mii);
+}
+
+static int dm9601_ioctl(struct net_device *net, struct ifreq *rq, int cmd)
+{
+       struct usbnet *dev = netdev_priv(net);
+
+       return generic_mii_ioctl(&dev->mii, if_mii(rq), cmd, NULL);
+}
+
+static struct ethtool_ops dm9601_ethtool_ops = {
+       .get_drvinfo    = dm9601_get_drvinfo,
+       .get_link       = dm9601_get_link,
+       .get_msglevel   = usbnet_get_msglevel,
+       .set_msglevel   = usbnet_set_msglevel,
+       .get_eeprom_len = dm9601_get_eeprom_len,
+       .get_eeprom     = dm9601_get_eeprom,
+       .get_settings   = usbnet_get_settings,
+       .set_settings   = usbnet_set_settings,
+       .nway_reset     = usbnet_nway_reset,
+};
+
+static void dm9601_set_multicast(struct net_device *net)
+{
+       struct usbnet *dev = netdev_priv(net);
+       /* We use the 20 byte dev->data for our 8 byte filter buffer
+        * to avoid allocating memory that is tricky to free later */
+       u8 *hashes = (u8 *) & dev->data;
+       u8 rx_ctl = 0x01;
+
+       memset(hashes, 0x00, DM_MCAST_SIZE);
+       hashes[DM_MCAST_SIZE - 1] |= 0x80;      /* broadcast address */
+
+       if (net->flags & IFF_PROMISC) {
+               rx_ctl |= 0x02;
+       } else if (net->flags & IFF_ALLMULTI || net->mc_count > DM_MAX_MCAST) {
+               rx_ctl |= 0x04;
+       } else if (net->mc_count) {
+               struct dev_mc_list *mc_list = net->mc_list;
+               int i;
+
+               for (i = 0; i < net->mc_count; i++) {
+                       u32 crc = ether_crc(ETH_ALEN, mc_list->dmi_addr) >> 26;
+                       hashes[crc >> 3] |= 1 << (crc & 0x7);
+               }
+       }
+
+       dm_write_async(dev, DM_MCAST_ADDR, DM_MCAST_SIZE, hashes);
+       dm_write_reg_async(dev, DM_RX_CTRL, rx_ctl);
+}
+
+static int dm9601_bind(struct usbnet *dev, struct usb_interface *intf)
+{
+       int ret;
+
+       ret = usbnet_get_endpoints(dev, intf);
+       if (ret)
+               goto out;
+
+       dev->net->do_ioctl = dm9601_ioctl;
+       dev->net->set_multicast_list = dm9601_set_multicast;
+       dev->net->ethtool_ops = &dm9601_ethtool_ops;
+       dev->net->hard_header_len += DM_TX_OVERHEAD;
+       dev->hard_mtu = dev->net->mtu + dev->net->hard_header_len;
+       dev->rx_urb_size = dev->net->mtu + DM_RX_OVERHEAD;
+
+       dev->mii.dev = dev->net;
+       dev->mii.mdio_read = dm9601_mdio_read;
+       dev->mii.mdio_write = dm9601_mdio_write;
+       dev->mii.phy_id_mask = 0x1f;
+       dev->mii.reg_num_mask = 0x1f;
+
+       /* reset */
+       ret = dm_write_reg(dev, DM_NET_CTRL, 1);
+       udelay(20);
+
+       /* read MAC */
+       ret = dm_read(dev, DM_PHY_ADDR, ETH_ALEN, dev->net->dev_addr);
+       if (ret < 0) {
+               printk(KERN_ERR "Error reading MAC address\n");
+               ret = -ENODEV;
+               goto out;
+       }
+
+
+       /* power up phy */
+       dm_write_reg(dev, DM_GPR_CTRL, 1);
+       dm_write_reg(dev, DM_GPR_DATA, 0);
+
+       /* receive broadcast packets */
+       dm9601_set_multicast(dev->net);
+
+       dm9601_mdio_write(dev->net, dev->mii.phy_id, MII_BMCR, BMCR_RESET);
+       dm9601_mdio_write(dev->net, dev->mii.phy_id, MII_ADVERTISE,
+                         ADVERTISE_ALL | ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP);
+       mii_nway_restart(&dev->mii);
+
+out:
+       return ret;
+}
+
+static int dm9601_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
+{
+       u8 status;
+       int len;
+
+       /* format:
+          b0: rx status
+          b1: packet length (incl crc) low
+          b2: packet length (incl crc) high
+          b3..n-4: packet data
+          bn-3..bn: ethernet crc
+        */
+
+       if (unlikely(skb->len < DM_RX_OVERHEAD)) {
+               dev_err(&dev->udev->dev, "unexpected tiny rx frame\n");
+               return 0;
+       }
+
+       status = skb->data[0];
+       len = (skb->data[1] | (skb->data[2] << 8)) - 4;
+
+       if (unlikely(status & 0xbf)) {
+               if (status & 0x01) dev->stats.rx_fifo_errors++;
+               if (status & 0x02) dev->stats.rx_crc_errors++;
+               if (status & 0x04) dev->stats.rx_frame_errors++;
+               if (status & 0x20) dev->stats.rx_missed_errors++;
+               if (status & 0x90) dev->stats.rx_length_errors++;
+               return 0;
+       }
+
+       skb_pull(skb, 3);
+       skb_trim(skb, len);
+
+       return 1;
+}
+
+static struct sk_buff *dm9601_tx_fixup(struct usbnet *dev, struct sk_buff *skb,
+                                      gfp_t flags)
+{
+       int len;
+
+       /* format:
+          b0: packet length low
+          b1: packet length high
+          b3..n: packet data
+       */
+
+       if (skb_headroom(skb) < DM_TX_OVERHEAD) {
+               struct sk_buff *skb2;
+
+               skb2 = skb_copy_expand(skb, DM_TX_OVERHEAD, 0, flags);
+               dev_kfree_skb_any(skb);
+               skb = skb2;
+               if (!skb)
+                       return NULL;
+       }
+
+       __skb_push(skb, DM_TX_OVERHEAD);
+
+       len = skb->len;
+       /* usbnet adds padding if length is a multiple of packet size
+          if so, adjust length value in header */
+       if ((len % dev->maxpacket) == 0)
+               len++;
+
+       skb->data[0] = len;
+       skb->data[1] = len >> 8;
+
+       return skb;
+}
+
+static void dm9601_status(struct usbnet *dev, struct urb *urb)
+{
+       int link;
+       u8 *buf;
+
+       /* format:
+          b0: net status
+          b1: tx status 1
+          b2: tx status 2
+          b3: rx status
+          b4: rx overflow
+          b5: rx count
+          b6: tx count
+          b7: gpr
+       */
+
+       if (urb->actual_length < 8)
+               return;
+
+       buf = urb->transfer_buffer;
+
+       link = !!(buf[0] & 0x40);
+       if (netif_carrier_ok(dev->net) != link) {
+               if (link) {
+                       netif_carrier_on(dev->net);
+                       usbnet_defer_kevent (dev, EVENT_LINK_RESET);
+               }
+               else
+                       netif_carrier_off(dev->net);
+               devdbg(dev, "Link Status is: %d", link);
+       }
+}
+
+static int dm9601_link_reset(struct usbnet *dev)
+{
+       struct ethtool_cmd ecmd;
+
+       mii_check_media(&dev->mii, 1, 1);
+       mii_ethtool_gset(&dev->mii, &ecmd);
+
+       devdbg(dev, "link_reset() speed: %d duplex: %d",
+              ecmd.speed, ecmd.duplex);
+
+       return 0;
+}
+
+static const struct driver_info dm9601_info = {
+       .description    = "Davicom DM9601 USB Ethernet",
+       .flags          = FLAG_ETHER,
+       .bind           = dm9601_bind,
+       .rx_fixup       = dm9601_rx_fixup,
+       .tx_fixup       = dm9601_tx_fixup,
+       .status         = dm9601_status,
+       .link_reset     = dm9601_link_reset,
+       .reset          = dm9601_link_reset,
+};
+
+static const struct usb_device_id products[] = {
+       {
+        USB_DEVICE(0x0a46, 0x9601),    /* Davicom USB-100 */
+        .driver_info = (unsigned long)&dm9601_info,
+        },
+       {},                     // END
+};
+
+MODULE_DEVICE_TABLE(usb, products);
+
+static struct usb_driver dm9601_driver = {
+       .name = "dm9601",
+       .id_table = products,
+       .probe = usbnet_probe,
+       .disconnect = usbnet_disconnect,
+       .suspend = usbnet_suspend,
+       .resume = usbnet_resume,
+};
+
+static int __init dm9601_init(void)
+{
+       return usb_register(&dm9601_driver);
+}
+
+static void __exit dm9601_exit(void)
+{
+       usb_deregister(&dm9601_driver);
+}
+
+module_init(dm9601_init);
+module_exit(dm9601_exit);
+
+MODULE_AUTHOR("Peter Korsgaard <jacmet@sunsite.dk>");
+MODULE_DESCRIPTION("Davicom DM9601 USB 1.1 ethernet devices");
+MODULE_LICENSE("GPL");
index 4695952..c525b42 100644 (file)
@@ -513,6 +513,7 @@ static struct usb_device_id id_table_combined [] = {
        { USB_DEVICE(FTDI_VID, FTDI_TACTRIX_OPENPORT_13S_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_TACTRIX_OPENPORT_13U_PID) },
        { USB_DEVICE(ELEKTOR_VID, ELEKTOR_FT323R_PID) },
+       { USB_DEVICE(TELLDUS_VID, TELLDUS_TELLSTICK_PID) },
        { },                                    /* Optional parameter entry */
        { }                                     /* Terminating entry */
 };
index 7eff1c0..1bdda93 100644 (file)
 #define FTDI_TACTRIX_OPENPORT_13S_PID  0xCC49  /* OpenPort 1.3 Subaru */
 #define FTDI_TACTRIX_OPENPORT_13U_PID  0xCC4A  /* OpenPort 1.3 Universal */
 
+/*
+ * Telldus Technologies
+ */
+#define TELLDUS_VID                    0x1781  /* Vendor ID */
+#define TELLDUS_TELLSTICK_PID          0x0C30  /* RF control dongle 433 MHz using FT232RL */
+
 /* Commands */
 #define FTDI_SIO_RESET                 0 /* Reset the port */
 #define FTDI_SIO_MODEM_CTRL    1 /* Set the modem control register */
index 9963a8b..db92a7f 100644 (file)
@@ -67,50 +67,95 @@ static int  option_tiocmset(struct usb_serial_port *port, struct file *file,
 static int  option_send_setup(struct usb_serial_port *port);
 
 /* Vendor and product IDs */
-#define OPTION_VENDOR_ID                0x0AF0
-#define HUAWEI_VENDOR_ID                0x12D1
-#define NOVATELWIRELESS_VENDOR_ID       0x1410
-#define ANYDATA_VENDOR_ID               0x16d5
-
-#define OPTION_PRODUCT_OLD              0x5000
-#define OPTION_PRODUCT_FUSION           0x6000
-#define OPTION_PRODUCT_FUSION2          0x6300
-#define OPTION_PRODUCT_COBRA            0x6500
-#define OPTION_PRODUCT_COBRA2           0x6600
-#define OPTION_PRODUCT_GTMAX36          0x6701
-#define HUAWEI_PRODUCT_E600             0x1001
-#define HUAWEI_PRODUCT_E220             0x1003
-#define NOVATELWIRELESS_PRODUCT_U740    0x1400
-#define ANYDATA_PRODUCT_ID              0x6501
+#define OPTION_VENDOR_ID                       0x0AF0
+#define OPTION_PRODUCT_COLT                    0x5000
+#define OPTION_PRODUCT_RICOLA                  0x6000
+#define OPTION_PRODUCT_RICOLA_LIGHT            0x6100
+#define OPTION_PRODUCT_RICOLA_QUAD             0x6200
+#define OPTION_PRODUCT_RICOLA_QUAD_LIGHT       0x6300
+#define OPTION_PRODUCT_RICOLA_NDIS             0x6050
+#define OPTION_PRODUCT_RICOLA_NDIS_LIGHT       0x6150
+#define OPTION_PRODUCT_RICOLA_NDIS_QUAD                0x6250
+#define OPTION_PRODUCT_RICOLA_NDIS_QUAD_LIGHT  0x6350
+#define OPTION_PRODUCT_COBRA                   0x6500
+#define OPTION_PRODUCT_COBRA_BUS               0x6501
+#define OPTION_PRODUCT_VIPER                   0x6600
+#define OPTION_PRODUCT_VIPER_BUS               0x6601
+#define OPTION_PRODUCT_GT_MAX_READY            0x6701
+#define OPTION_PRODUCT_GT_MAX                  0x6711
+#define OPTION_PRODUCT_FUJI_MODEM_LIGHT                0x6721
+#define OPTION_PRODUCT_FUJI_MODEM_GT           0x6741
+#define OPTION_PRODUCT_FUJI_MODEM_EX           0x6761
+#define OPTION_PRODUCT_FUJI_NETWORK_LIGHT      0x6731
+#define OPTION_PRODUCT_FUJI_NETWORK_GT         0x6751
+#define OPTION_PRODUCT_FUJI_NETWORK_EX         0x6771
+#define OPTION_PRODUCT_KOI_MODEM               0x6800
+#define OPTION_PRODUCT_KOI_NETWORK             0x6811
+#define OPTION_PRODUCT_SCORPION_MODEM          0x6901
+#define OPTION_PRODUCT_SCORPION_NETWORK                0x6911
+#define OPTION_PRODUCT_ETNA_MODEM              0x7001
+#define OPTION_PRODUCT_ETNA_NETWORK            0x7011
+#define OPTION_PRODUCT_ETNA_MODEM_LITE         0x7021
+#define OPTION_PRODUCT_ETNA_MODEM_GT           0x7041
+#define OPTION_PRODUCT_ETNA_MODEM_EX           0x7061
+#define OPTION_PRODUCT_ETNA_NETWORK_LITE       0x7031
+#define OPTION_PRODUCT_ETNA_NETWORK_GT         0x7051
+#define OPTION_PRODUCT_ETNA_NETWORK_EX         0x7071
+#define OPTION_PRODUCT_ETNA_KOI_MODEM          0x7100
+#define OPTION_PRODUCT_ETNA_KOI_NETWORK                0x7111
+
+#define HUAWEI_VENDOR_ID                       0x12D1
+#define HUAWEI_PRODUCT_E600                    0x1001
+#define HUAWEI_PRODUCT_E220                    0x1003
+
+#define NOVATELWIRELESS_VENDOR_ID              0x1410
+#define NOVATELWIRELESS_PRODUCT_U740           0x1400
+
+#define ANYDATA_VENDOR_ID                      0x16d5
+#define ANYDATA_PRODUCT_ID                     0x6501
 
 static struct usb_device_id option_ids[] = {
-       { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_OLD) },
-       { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUSION) },
-       { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUSION2) },
+       { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) },
+       { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) },
+       { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA_LIGHT) },
+       { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA_QUAD) },
+       { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA_QUAD_LIGHT) },
+       { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA_NDIS) },
+       { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA_NDIS_LIGHT) },
+       { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA_NDIS_QUAD) },
+       { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA_NDIS_QUAD_LIGHT) },
        { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COBRA) },
-       { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COBRA2) },
-       { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_GTMAX36) },
+       { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COBRA_BUS) },
+       { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_VIPER) },
+       { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_VIPER_BUS) },
+       { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_GT_MAX_READY) },
+       { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_GT_MAX) },
+       { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUJI_MODEM_LIGHT) },
+       { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUJI_MODEM_GT) },
+       { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUJI_MODEM_EX) },
+       { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUJI_NETWORK_LIGHT) },
+       { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUJI_NETWORK_GT) },
+       { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUJI_NETWORK_EX) },
+       { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_KOI_MODEM) },
+       { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_KOI_NETWORK) },
+       { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_SCORPION_MODEM) },
+       { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_SCORPION_NETWORK) },
+       { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_ETNA_MODEM) },
+       { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_ETNA_NETWORK) },
+       { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_ETNA_MODEM_LITE) },
+       { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_ETNA_MODEM_GT) },
+       { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_ETNA_MODEM_EX) },
+       { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_ETNA_NETWORK_LITE) },
+       { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_ETNA_NETWORK_GT) },
+       { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_ETNA_NETWORK_EX) },
+       { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_ETNA_KOI_MODEM) },
+       { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_ETNA_KOI_NETWORK) },
        { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E600) },
        { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E220) },
        { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID,NOVATELWIRELESS_PRODUCT_U740) },
        { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ID) },
        { } /* Terminating entry */
 };
-
-static struct usb_device_id option_ids1[] = {
-       { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_OLD) },
-       { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUSION) },
-       { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUSION2) },
-       { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COBRA) },
-       { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COBRA2) },
-       { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_GTMAX36) },
-       { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E600) },
-       { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E220) },
-       { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID,NOVATELWIRELESS_PRODUCT_U740) },
-       { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ID) },
-       { } /* Terminating entry */
-};
-
 MODULE_DEVICE_TABLE(usb, option_ids);
 
 static struct usb_driver option_driver = {
@@ -132,7 +177,7 @@ static struct usb_serial_driver option_1port_device = {
        },
        .description       = "GSM modem (1-port)",
        .usb_driver        = &option_driver,
-       .id_table          = option_ids1,
+       .id_table          = option_ids,
        .num_interrupt_in  = NUM_DONT_CARE,
        .num_bulk_in       = NUM_DONT_CARE,
        .num_bulk_out      = NUM_DONT_CARE,
index 6988a10..03893ac 100644 (file)
@@ -1919,7 +1919,8 @@ static void xtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
         * header ?
         */
        if (tlck->type & tlckTRUNCATE) {
-               pxd_t pxd;      /* truncated extent of xad */
+               /* This odd declaration suppresses a bogus gcc warning */
+               pxd_t pxd = pxd;        /* truncated extent of xad */
                int twm;
 
                /*
index 98b0910..8d4d839 100644 (file)
@@ -501,6 +501,30 @@ int sysfs_create_file(struct kobject * kobj, const struct attribute * attr)
 }
 
 
+/**
+ * sysfs_add_file_to_group - add an attribute file to a pre-existing group.
+ * @kobj: object we're acting for.
+ * @attr: attribute descriptor.
+ * @group: group name.
+ */
+int sysfs_add_file_to_group(struct kobject *kobj,
+               const struct attribute *attr, const char *group)
+{
+       struct dentry *dir;
+       int error;
+
+       dir = lookup_one_len(group, kobj->dentry, strlen(group));
+       if (IS_ERR(dir))
+               error = PTR_ERR(dir);
+       else {
+               error = sysfs_add_file(dir, attr, SYSFS_KOBJ_ATTR);
+               dput(dir);
+       }
+       return error;
+}
+EXPORT_SYMBOL_GPL(sysfs_add_file_to_group);
+
+
 /**
  * sysfs_update_file - update the modified timestamp on an object attribute.
  * @kobj: object we're acting for.
@@ -586,6 +610,26 @@ void sysfs_remove_file(struct kobject * kobj, const struct attribute * attr)
 }
 
 
+/**
+ * sysfs_remove_file_from_group - remove an attribute file from a group.
+ * @kobj: object we're acting for.
+ * @attr: attribute descriptor.
+ * @group: group name.
+ */
+void sysfs_remove_file_from_group(struct kobject *kobj,
+               const struct attribute *attr, const char *group)
+{
+       struct dentry *dir;
+
+       dir = lookup_one_len(group, kobj->dentry, strlen(group));
+       if (!IS_ERR(dir)) {
+               sysfs_hash_and_remove(dir, attr->name);
+               dput(dir);
+       }
+}
+EXPORT_SYMBOL_GPL(sysfs_remove_file_from_group);
+
+
 EXPORT_SYMBOL_GPL(sysfs_create_file);
 EXPORT_SYMBOL_GPL(sysfs_remove_file);
 EXPORT_SYMBOL_GPL(sysfs_update_file);
index d976b00..a77c57e 100644 (file)
@@ -1,3 +1,14 @@
+struct sysfs_dirent {
+       atomic_t                s_count;
+       struct list_head        s_sibling;
+       struct list_head        s_children;
+       void                    * s_element;
+       int                     s_type;
+       umode_t                 s_mode;
+       struct dentry           * s_dentry;
+       struct iattr            * s_iattr;
+       atomic_t                s_event;
+};
 
 extern struct vfsmount * sysfs_mount;
 extern struct kmem_cache *sysfs_dir_cachep;
index 8a1f2b6..1906938 100644 (file)
@@ -21,6 +21,7 @@
 #define FPC_EIR                70
 #define DSP_BASE       71              /* 3 more hi / lo register pairs */
 #define DSP_CONTROL    77
+#define ACX            78
 
 /*
  * This struct defines the way the registers are stored on the stack during a
@@ -39,6 +40,9 @@ struct pt_regs {
        unsigned long cp0_status;
        unsigned long hi;
        unsigned long lo;
+#ifdef CONFIG_CPU_HAS_SMARTMIPS
+       unsigned long acx;
+#endif
        unsigned long cp0_badvaddr;
        unsigned long cp0_cause;
        unsigned long cp0_epc;
index 9729474..9ce0607 100644 (file)
@@ -23,7 +23,7 @@ struct sigcontext {
        unsigned long long      sc_pc;
        unsigned long long      sc_regs[32];
        unsigned long long      sc_fpregs[32];
-       unsigned int            sc_ownedfp;     /* Unused */
+       unsigned int            sc_acx;         /* Was sc_ownedfp */
        unsigned int            sc_fpc_csr;
        unsigned int            sc_fpc_eir;     /* Unused */
        unsigned int            sc_used_math;
@@ -79,7 +79,7 @@ struct sigcontext32 {
        __u64           sc_pc;
        __u64           sc_regs[32];
        __u64           sc_fpregs[32];
-       __u32           sc_ownedfp;     /* Unused */
+       __u32           sc_acx;         /* Only MIPS32; was sc_ownedfp */
        __u32           sc_fpc_csr;
        __u32           sc_fpc_eir;     /* Unused */
        __u32           sc_used_math;
index 1fae5dc..7afa1fd 100644 (file)
                .endm
 
                .macro  SAVE_TEMP
+#ifdef CONFIG_CPU_HAS_SMARTMIPS
+               mflhxu  v1
+               LONG_S  v1, PT_LO(sp)
+               mflhxu  v1
+               LONG_S  v1, PT_HI(sp)
+               mflhxu  v1
+               LONG_S  v1, PT_ACX(sp)
+#else
                mfhi    v1
+               LONG_S  v1, PT_HI(sp)
+               mflo    v1
+               LONG_S  v1, PT_LO(sp)
+#endif
 #ifdef CONFIG_32BIT
                LONG_S  $8, PT_R8(sp)
                LONG_S  $9, PT_R9(sp)
 #endif
-               LONG_S  v1, PT_HI(sp)
-               mflo    v1
                LONG_S  $10, PT_R10(sp)
                LONG_S  $11, PT_R11(sp)
-               LONG_S  v1,  PT_LO(sp)
                LONG_S  $12, PT_R12(sp)
                LONG_S  $13, PT_R13(sp)
                LONG_S  $14, PT_R14(sp)
                .endm
 
                .macro  RESTORE_TEMP
+#ifdef CONFIG_CPU_HAS_SMARTMIPS
+               LONG_L  $24, PT_ACX(sp)
+               mtlhx   $24
+               LONG_L  $24, PT_HI(sp)
+               mtlhx   $24
                LONG_L  $24, PT_LO(sp)
+               mtlhx   $24
+#else
+               LONG_L  $24, PT_LO(sp)
+               mtlo    $24
+               LONG_L  $24, PT_HI(sp)
+               mthi    $24
+#endif
 #ifdef CONFIG_32BIT
                LONG_L  $8, PT_R8(sp)
                LONG_L  $9, PT_R9(sp)
 #endif
-               mtlo    $24
-               LONG_L  $24, PT_HI(sp)
                LONG_L  $10, PT_R10(sp)
                LONG_L  $11, PT_R11(sp)
-               mthi    $24
                LONG_L  $12, PT_R12(sp)
                LONG_L  $13, PT_R13(sp)
                LONG_L  $14, PT_R14(sp)
index d1a3a27..39a3199 100644 (file)
@@ -294,8 +294,6 @@ extern void class_device_initialize(struct class_device *);
 extern int __must_check class_device_add(struct class_device *);
 extern void class_device_del(struct class_device *);
 
-extern int class_device_rename(struct class_device *, char *);
-
 extern struct class_device * class_device_get(struct class_device *);
 extern void class_device_put(struct class_device *);
 
index cc8e674..10f505c 100644 (file)
 #ifdef CONFIG_KMOD
 /* modprobe exit status on success, -ve on error.  Return value
  * usually useless though. */
-extern void kmod_sysfs_init(void);
 extern int request_module(const char * name, ...) __attribute__ ((format (printf, 1, 2)));
 #else
-static inline void kmod_sysfs_init(void) {};
 static inline int request_module(const char * name, ...) { return -ENOSYS; }
 #endif
 
index 070394e..21db05a 100644 (file)
@@ -120,15 +120,48 @@ typedef int __bitwise suspend_disk_method_t;
 #define        PM_DISK_TESTPROC        ((__force suspend_disk_method_t) 6)
 #define        PM_DISK_MAX             ((__force suspend_disk_method_t) 7)
 
+/**
+ * struct pm_ops - Callbacks for managing platform dependent suspend states.
+ * @valid: Callback to determine whether the given state can be entered.
+ *     If %CONFIG_SOFTWARE_SUSPEND is set then %PM_SUSPEND_DISK is
+ *     always valid and never passed to this call.
+ *     If not assigned, all suspend states are advertised as valid
+ *     in /sys/power/state (but can still be rejected by prepare or enter.)
+ *
+ * @prepare: Prepare the platform for the given suspend state. Can return a
+ *     negative error code if necessary.
+ *
+ * @enter: Enter the given suspend state, must be assigned. Can return a
+ *     negative error code if necessary.
+ *
+ * @finish: Called when the system has left the given state and all devices
+ *     are resumed. The return value is ignored.
+ *
+ * @pm_disk_mode: Set to the disk method that the user should be able to
+ *     configure for suspend-to-disk. Since %PM_DISK_SHUTDOWN,
+ *     %PM_DISK_REBOOT, %PM_DISK_TEST and %PM_DISK_TESTPROC
+ *     are always allowed, currently only %PM_DISK_PLATFORM
+ *     makes sense. If the user then choses %PM_DISK_PLATFORM,
+ *     the @prepare call will be called before suspending to disk
+ *     (if present), the @enter call should be present and will
+ *     be called after all state has been saved and the machine
+ *     is ready to be shut down/suspended/..., and the @finish
+ *     callback is called after state has been restored. All
+ *     these calls are called with %PM_SUSPEND_DISK as the state.
+ */
 struct pm_ops {
-       suspend_disk_method_t pm_disk_mode;
        int (*valid)(suspend_state_t state);
        int (*prepare)(suspend_state_t state);
        int (*enter)(suspend_state_t state);
        int (*finish)(suspend_state_t state);
+       suspend_disk_method_t pm_disk_mode;
 };
 
-extern void pm_set_ops(struct pm_ops *);
+/**
+ * pm_set_ops - set platform dependent power management ops
+ * @pm_ops: The new power management operations to set.
+ */
+extern void pm_set_ops(struct pm_ops *pm_ops);
 extern struct pm_ops *pm_ops;
 extern int pm_suspend(suspend_state_t state);
 
index 192de3a..21805b5 100644 (file)
@@ -17,6 +17,7 @@
 struct kobject;
 struct module;
 struct nameidata;
+struct dentry;
 
 struct attribute {
        const char              * name;
@@ -68,18 +69,6 @@ struct sysfs_ops {
        ssize_t (*store)(struct kobject *,struct attribute *,const char *, size_t);
 };
 
-struct sysfs_dirent {
-       atomic_t                s_count;
-       struct list_head        s_sibling;
-       struct list_head        s_children;
-       void                    * s_element;
-       int                     s_type;
-       umode_t                 s_mode;
-       struct dentry           * s_dentry;
-       struct iattr            * s_iattr;
-       atomic_t                s_event;
-};
-
 #define SYSFS_ROOT             0x0001
 #define SYSFS_DIR              0x0002
 #define SYSFS_KOBJ_ATTR        0x0004
@@ -126,6 +115,11 @@ void sysfs_remove_bin_file(struct kobject *kobj, struct bin_attribute *attr);
 int __must_check sysfs_create_group(struct kobject *,
                                        const struct attribute_group *);
 void sysfs_remove_group(struct kobject *, const struct attribute_group *);
+int sysfs_add_file_to_group(struct kobject *kobj,
+               const struct attribute *attr, const char *group);
+void sysfs_remove_file_from_group(struct kobject *kobj,
+               const struct attribute *attr, const char *group);
+
 void sysfs_notify(struct kobject * k, char *dir, char *attr);
 
 
@@ -210,6 +204,18 @@ static inline void sysfs_remove_group(struct kobject * k, const struct attribute
        ;
 }
 
+static inline int sysfs_add_file_to_group(struct kobject *kobj,
+               const struct attribute *attr, const char *group)
+{
+       return 0;
+}
+
+static inline void sysfs_remove_file_from_group(struct kobject *kobj,
+               const struct attribute *attr, const char *group);
+{
+       ;
+}
+
 static inline void sysfs_notify(struct kobject * k, char *dir, char *attr)
 {
 }
index a8e8d1e..87dc75a 100644 (file)
@@ -388,10 +388,14 @@ struct usb_device {
        struct usb_device *children[USB_MAXCHILDREN];
 
        int pm_usage_cnt;               /* usage counter for autosuspend */
+       u32 quirks;                     /* quirks of the whole device */
+
 #ifdef CONFIG_PM
        struct delayed_work autosuspend; /* for delayed autosuspends */
        struct mutex pm_mutex;          /* protects PM operations */
 
+       unsigned autosuspend_delay;     /* in jiffies */
+
        unsigned auto_pm:1;             /* autosuspend/resume in progress */
        unsigned do_remote_wakeup:1;    /* remote wakeup should be enabled */
 #endif
index 245c725..1122a6c 100644 (file)
@@ -1,8 +1,9 @@
 /*
- * This file holds USB constants and structures that are needed for USB
- * device APIs.  These are used by the USB device model, which is defined
- * in chapter 9 of the USB 2.0 specification.  Linux has several APIs in C
- * that need these:
+ * This file holds USB constants and structures that are needed for
+ * USB device APIs.  These are used by the USB device model, which is
+ * defined in chapter 9 of the USB 2.0 specification and in the
+ * Wireless USB 1.0 (spread around).  Linux has several APIs in C that
+ * need these:
  *
  * - the master/host side Linux-USB kernel driver API;
  * - the "usbfs" user space API; and
  *
  * There's also "Wireless USB", using low power short range radios for
  * peripheral interconnection but otherwise building on the USB framework.
+ *
+ * Note all descriptors are declared '__attribute__((packed))' so that:
+ *
+ * [a] they never get padded, either internally (USB spec writers
+ *     probably handled that) or externally;
+ *
+ * [b] so that accessing bigger-than-a-bytes fields will never
+ *     generate bus errors on any platform, even when the location of
+ *     its descriptor inside a bundle isn't "naturally aligned", and
+ *
+ * [c] for consistency, removing all doubt even when it appears to
+ *     someone that the two other points are non-issues for that
+ *     particular descriptor type.
  */
 
 #ifndef __LINUX_USB_CH9_H
diff --git a/include/linux/usb/iowarrior.h b/include/linux/usb/iowarrior.h
new file mode 100644 (file)
index 0000000..cbbe020
--- /dev/null
@@ -0,0 +1,33 @@
+#ifndef _IOWARRIOR_H_
+#define _IOWARRIOR_H_
+
+#define CODEMERCS_MAGIC_NUMBER 0xC0    /* like COde Mercenaries */
+
+/* Define the ioctl commands for reading and writing data */
+#define IOW_WRITE      _IOW(CODEMERCS_MAGIC_NUMBER, 1, __u8 *)
+#define IOW_READ       _IOW(CODEMERCS_MAGIC_NUMBER, 2, __u8 *)
+
+/*
+   A struct for available device info which is read
+   with the ioctl IOW_GETINFO.
+   To be compatible with 2.4 userspace which didn't have an easy way to get
+   this information.
+*/
+struct iowarrior_info {
+       __u32 vendor;           /* vendor id : supposed to be USB_VENDOR_ID_CODEMERCS in all cases */
+       __u32 product;          /* product id : depends on type of chip (USB_DEVICE_ID_CODEMERCS_XXXXX) */
+       __u8 serial[9];         /* the serial number of our chip (if a serial-number is not available this is empty string) */
+       __u32 revision;         /* revision number of the chip */
+       __u32 speed;            /* USB-speed of the device (0=UNKNOWN, 1=LOW, 2=FULL 3=HIGH) */
+       __u32 power;            /* power consumption of the device in mA */
+       __u32 if_num;           /* the number of the endpoint */
+       __u32 report_size;      /* size of the data-packets on this interface */
+};
+
+/*
+  Get some device-information (product-id , serial-number etc.)
+  in order to identify a chip.
+*/
+#define IOW_GETINFO _IOR(CODEMERCS_MAGIC_NUMBER, 3, struct iowarrior_info)
+
+#endif  /* _IOWARRIOR_H_ */
diff --git a/include/linux/usb/quirks.h b/include/linux/usb/quirks.h
new file mode 100644 (file)
index 0000000..6bac8fa
--- /dev/null
@@ -0,0 +1,11 @@
+/*
+ * This file holds the definitions of quirks found in USB devices.
+ * Only quirks that affect the whole device, not an interface,
+ * belong here.
+ */
+
+/* device must not be autosuspended */
+#define USB_QUIRK_NO_AUTOSUSPEND       0x00000001
+
+/* string descriptors must not be fetched using a 255-byte read */
+#define USB_QUIRK_STRING_FETCH_255     0x00000002
index 9f923f8..7962761 100644 (file)
@@ -36,8 +36,6 @@
 #include <linux/resource.h>
 #include <asm/uaccess.h>
 
-extern int delete_module(const char *name, unsigned int flags);
-
 extern int max_threads;
 
 static struct workqueue_struct *khelper_wq;
@@ -48,7 +46,6 @@ static struct workqueue_struct *khelper_wq;
        modprobe_path is set via /proc/sys.
 */
 char modprobe_path[KMOD_PATH_LEN] = "/sbin/modprobe";
-struct module_kobject kmod_mk;
 
 /**
  * request_module - try to load a kernel module
@@ -78,11 +75,6 @@ int request_module(const char *fmt, ...)
        static atomic_t kmod_concurrent = ATOMIC_INIT(0);
 #define MAX_KMOD_CONCURRENT 50 /* Completely arbitrary value - KAO */
        static int kmod_loop_msg;
-       char modalias[16 + MODULE_NAME_LEN] = "MODALIAS=";
-       char *uevent_envp[2] = {
-               modalias,
-               NULL
-       };
 
        va_start(args, fmt);
        ret = vsnprintf(module_name, MODULE_NAME_LEN, fmt, args);
@@ -90,12 +82,6 @@ int request_module(const char *fmt, ...)
        if (ret >= MODULE_NAME_LEN)
                return -ENAMETOOLONG;
 
-       strcpy(&modalias[strlen("MODALIAS=")], module_name);
-       kobject_uevent_env(&kmod_mk.kobj, KOBJ_CHANGE, uevent_envp);
-
-       if (modprobe_path[0] == '\0')
-               goto out;
-
        /* If modprobe needs a service that is in a module, we get a recursive
         * loop.  Limit the number of running kmod threads to max_threads/2 or
         * MAX_KMOD_CONCURRENT, whichever is the smaller.  A cleaner method
@@ -122,115 +108,9 @@ int request_module(const char *fmt, ...)
 
        ret = call_usermodehelper(modprobe_path, argv, envp, 1);
        atomic_dec(&kmod_concurrent);
-out:
        return ret;
 }
 EXPORT_SYMBOL(request_module);
-
-static ssize_t store_mod_request(struct module_attribute *mattr,
-                                struct module *mod,
-                             const char *buffer, size_t count)
-{
-       char name[MODULE_NAME_LEN];
-       int ret;
-
-       if (count < 1 || count+1 > MODULE_NAME_LEN)
-               return -EINVAL;
-       memcpy(name, buffer, count);
-       name[count] = '\0';
-       if (name[count-1] == '\n')
-               name[count-1] = '\0';
-
-       ret = request_module(name);
-       if (ret < 0)
-               return ret;
-       return count;
-}
-
-static struct module_attribute mod_request = {
-       .attr = { .name = "mod_request", .mode = S_IWUSR, .owner = THIS_MODULE },
-       .store = store_mod_request,
-};
-
-#ifdef CONFIG_MODULE_UNLOAD
-static ssize_t store_mod_unload(struct module_attribute *mattr,
-                           struct module *mod,
-                           const char *buffer, size_t count)
-{
-       char name[MODULE_NAME_LEN];
-       int ret;
-
-       if (count < 1 || count+1 > MODULE_NAME_LEN)
-               return -EINVAL;
-       memcpy(name, buffer, count);
-       name[count] = '\0';
-       if (name[count-1] == '\n')
-               name[count-1] = '\0';
-
-       ret = delete_module(name, O_NONBLOCK);
-       if (ret < 0)
-               return ret;
-       return count;
-}
-
-static struct module_attribute mod_unload = {
-       .attr = { .name = "mod_unload", .mode = S_IWUSR, .owner = THIS_MODULE },
-       .store = store_mod_unload,
-};
-#endif
-
-static ssize_t show_mod_request_helper(struct module_attribute *mattr,
-                                      struct module *mod,
-                                      char *buffer)
-{
-       return sprintf(buffer, "%s\n", modprobe_path);
-}
-
-static ssize_t store_mod_request_helper(struct module_attribute *mattr,
-                                       struct module *mod,
-                                       const char *buffer, size_t count)
-{
-       if (count < 1 || count+1 > KMOD_PATH_LEN)
-               return -EINVAL;
-       memcpy(modprobe_path, buffer, count);
-       modprobe_path[count] = '\0';
-       if (modprobe_path[count-1] == '\n')
-               modprobe_path[count-1] = '\0';
-       return count;
-}
-
-static struct module_attribute mod_request_helper = {
-       .attr = {
-               .name = "mod_request_helper",
-               .mode = S_IWUSR | S_IRUGO,
-               .owner = THIS_MODULE
-       },
-       .show = show_mod_request_helper,
-       .store = store_mod_request_helper,
-};
-
-void __init kmod_sysfs_init(void)
-{
-       int ret;
-
-       kmod_mk.mod = THIS_MODULE;
-       kobj_set_kset_s(&kmod_mk, module_subsys);
-       kobject_set_name(&kmod_mk.kobj, "kmod");
-       kobject_init(&kmod_mk.kobj);
-       ret = kobject_add(&kmod_mk.kobj);
-       if (ret < 0)
-               goto out;
-
-       ret = sysfs_create_file(&kmod_mk.kobj, &mod_request_helper.attr);
-       ret = sysfs_create_file(&kmod_mk.kobj, &mod_request.attr);
-#ifdef CONFIG_MODULE_UNLOAD
-       ret = sysfs_create_file(&kmod_mk.kobj, &mod_unload.attr);
-#endif
-
-       kobject_uevent(&kmod_mk.kobj, KOBJ_ADD);
-out:
-       return;
-}
 #endif /* CONFIG_KMOD */
 
 struct subprocess_info {
index 8c25b1a..f77e893 100644 (file)
@@ -653,11 +653,20 @@ static void wait_for_zero_refcount(struct module *mod)
        mutex_lock(&module_mutex);
 }
 
-int delete_module(const char *name, unsigned int flags)
+asmlinkage long
+sys_delete_module(const char __user *name_user, unsigned int flags)
 {
        struct module *mod;
+       char name[MODULE_NAME_LEN];
        int ret, forced = 0;
 
+       if (!capable(CAP_SYS_MODULE))
+               return -EPERM;
+
+       if (strncpy_from_user(name, name_user, MODULE_NAME_LEN-1) < 0)
+               return -EFAULT;
+       name[MODULE_NAME_LEN-1] = '\0';
+
        if (mutex_lock_interruptible(&module_mutex) != 0)
                return -EINTR;
 
@@ -718,21 +727,6 @@ int delete_module(const char *name, unsigned int flags)
        return ret;
 }
 
-asmlinkage long
-sys_delete_module(const char __user *name_user, unsigned int flags)
-{
-       char name[MODULE_NAME_LEN];
-
-       if (!capable(CAP_SYS_MODULE))
-               return -EPERM;
-
-       if (strncpy_from_user(name, name_user, MODULE_NAME_LEN-1) < 0)
-               return -EFAULT;
-       name[MODULE_NAME_LEN-1] = '\0';
-
-       return delete_module(name, flags);
-}
-
 static void print_unload_info(struct seq_file *m, struct module *mod)
 {
        struct module_use *use;
@@ -2425,6 +2419,12 @@ void module_remove_driver(struct device_driver *drv)
                        kfree(driver_name);
                }
        }
+       /*
+        * Undo the additional reference we added in module_add_driver()
+        * via kset_find_obj()
+        */
+       if (drv->mod_name)
+               kobject_put(&drv->kobj);
 }
 EXPORT_SYMBOL(module_remove_driver);
 #endif
index 7a75157..e265b13 100644 (file)
@@ -707,7 +707,6 @@ static int __init param_sysfs_init(void)
        }
 
        param_sysfs_builtin();
-       kmod_sysfs_init();
 
        return 0;
 }
index e1c4131..a064dfd 100644 (file)
@@ -167,7 +167,10 @@ static inline int valid_state(suspend_state_t state)
        if (state == PM_SUSPEND_DISK)
                return 1;
 
-       if (pm_ops && pm_ops->valid && !pm_ops->valid(state))
+       /* all other states need lowlevel support and need to be
+        * valid to the lowlevel implementation, no valid callback
+        * implies that all are valid. */
+       if (!pm_ops || (pm_ops->valid && !pm_ops->valid(state)))
                return 0;
        return 1;
 }
index 4500e34..0986a2b 100644 (file)
@@ -77,6 +77,7 @@ static void tick_periodic(int cpu)
 void tick_handle_periodic(struct clock_event_device *dev)
 {
        int cpu = smp_processor_id();
+       ktime_t next;
 
        tick_periodic(cpu);
 
@@ -86,12 +87,12 @@ void tick_handle_periodic(struct clock_event_device *dev)
         * Setup the next period for devices, which do not have
         * periodic mode:
         */
+       next = ktime_add(dev->next_event, tick_period);
        for (;;) {
-               ktime_t next = ktime_add(dev->next_event, tick_period);
-
                if (!clockevents_program_event(dev, next, ktime_get()))
                        return;
                tick_periodic(cpu);
+               next = ktime_add(next, tick_period);
        }
 }
 
index 512a4a9..51556b9 100644 (file)
@@ -21,6 +21,8 @@
 #include <linux/sched.h>
 #include <linux/tick.h>
 
+#include <asm/irq_regs.h>
+
 #include "tick-internal.h"
 
 /*
index b1ac22d..19a385e 100644 (file)
@@ -653,11 +653,11 @@ static int superblock_doinit(struct super_block *sb, void *data)
        sbsec->initialized = 1;
 
        if (sbsec->behavior > ARRAY_SIZE(labeling_behaviors)) {
-               printk(KERN_INFO "SELinux: initialized (dev %s, type %s), unknown behavior\n",
+               printk(KERN_ERR "SELinux: initialized (dev %s, type %s), unknown behavior\n",
                       sb->s_id, sb->s_type->name);
        }
        else {
-               printk(KERN_INFO "SELinux: initialized (dev %s, type %s), %s\n",
+               printk(KERN_DEBUG "SELinux: initialized (dev %s, type %s), %s\n",
                       sb->s_id, sb->s_type->name,
                       labeling_behaviors[sbsec->behavior-1]);
        }
@@ -4434,7 +4434,7 @@ static int selinux_ipc_permission(struct kern_ipc_perm *ipcp, short flag)
 static int selinux_register_security (const char *name, struct security_operations *ops)
 {
        if (secondary_ops != original_ops) {
-               printk(KERN_INFO "%s:  There is already a secondary security "
+               printk(KERN_ERR "%s:  There is already a secondary security "
                       "module registered.\n", __FUNCTION__);
                return -EINVAL;
        }
@@ -4451,7 +4451,7 @@ static int selinux_register_security (const char *name, struct security_operatio
 static int selinux_unregister_security (const char *name, struct security_operations *ops)
 {
        if (ops != secondary_ops) {
-               printk (KERN_INFO "%s:  trying to unregister a security module "
+               printk(KERN_ERR "%s:  trying to unregister a security module "
                        "that is not registered.\n", __FUNCTION__);
                return -EINVAL;
        }
@@ -4889,9 +4889,9 @@ static __init int selinux_init(void)
                panic("SELinux: Unable to register with kernel.\n");
 
        if (selinux_enforcing) {
-               printk(KERN_INFO "SELinux:  Starting in enforcing mode\n");
+               printk(KERN_DEBUG "SELinux:  Starting in enforcing mode\n");
        } else {
-               printk(KERN_INFO "SELinux:  Starting in permissive mode\n");
+               printk(KERN_DEBUG "SELinux:  Starting in permissive mode\n");
        }
 
 #ifdef CONFIG_KEYS
@@ -4907,10 +4907,10 @@ static __init int selinux_init(void)
 
 void selinux_complete_init(void)
 {
-       printk(KERN_INFO "SELinux:  Completing initialization.\n");
+       printk(KERN_DEBUG "SELinux:  Completing initialization.\n");
 
        /* Set up any superblocks initialized prior to the policy load. */
-       printk(KERN_INFO "SELinux:  Setting up existing superblocks.\n");
+       printk(KERN_DEBUG "SELinux:  Setting up existing superblocks.\n");
        spin_lock(&sb_lock);
        spin_lock(&sb_security_lock);
 next_sb:
@@ -4968,9 +4968,9 @@ static int __init selinux_nf_ip_init(void)
 
        if (!selinux_enabled)
                goto out;
-               
-       printk(KERN_INFO "SELinux:  Registering netfilter hooks\n");
-       
+
+       printk(KERN_DEBUG "SELinux:  Registering netfilter hooks\n");
+
        err = nf_register_hook(&selinux_ipv4_op);
        if (err)
                panic("SELinux: nf_register_hook for IPv4: error %d\n", err);
@@ -4992,7 +4992,7 @@ __initcall(selinux_nf_ip_init);
 #ifdef CONFIG_SECURITY_SELINUX_DISABLE
 static void selinux_nf_ip_exit(void)
 {
-       printk(KERN_INFO "SELinux:  Unregistering netfilter hooks\n");
+       printk(KERN_DEBUG "SELinux:  Unregistering netfilter hooks\n");
 
        nf_unregister_hook(&selinux_ipv4_op);
 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
index 9142073..3122908 100644 (file)
@@ -277,7 +277,7 @@ void avtab_hash_eval(struct avtab *h, char *tag)
                }
        }
 
-       printk(KERN_INFO "%s:  %d entries and %d/%d buckets used, longest "
+       printk(KERN_DEBUG "%s:  %d entries and %d/%d buckets used, longest "
               "chain length %d\n", tag, h->nel, slots_used, AVTAB_SIZE,
               max_chain_len);
 }
index cd79c63..0ac1021 100644 (file)
@@ -374,7 +374,7 @@ static void symtab_hash_eval(struct symtab *s)
                struct hashtab_info info;
 
                hashtab_stat(h, &info);
-               printk(KERN_INFO "%s:  %d entries and %d/%d buckets used, "
+               printk(KERN_DEBUG "%s:  %d entries and %d/%d buckets used, "
                       "longest chain length %d\n", symtab_name[i], h->nel,
                       info.slots_used, h->size, info.max_chain_len);
        }
@@ -391,14 +391,14 @@ static int policydb_index_others(struct policydb *p)
 {
        int i, rc = 0;
 
-       printk(KERN_INFO "security:  %d users, %d roles, %d types, %d bools",
+       printk(KERN_DEBUG "security:  %d users, %d roles, %d types, %d bools",
               p->p_users.nprim, p->p_roles.nprim, p->p_types.nprim, p->p_bools.nprim);
        if (selinux_mls_enabled)
                printk(", %d sens, %d cats", p->p_levels.nprim,
                       p->p_cats.nprim);
        printk("\n");
 
-       printk(KERN_INFO "security:  %d classes, %d rules\n",
+       printk(KERN_DEBUG "security:  %d classes, %d rules\n",
               p->p_classes.nprim, p->te_avtab.nel);
 
 #ifdef DEBUG_HASHES
index ca9154d..1e52356 100644 (file)
@@ -609,6 +609,9 @@ int security_sid_to_context(u32 sid, char **scontext, u32 *scontext_len)
        struct context *context;
        int rc = 0;
 
+       *scontext = NULL;
+       *scontext_len  = 0;
+
        if (!ss_initialized) {
                if (sid <= SECINITSID_NUM) {
                        char *scontextp;
index d78f9ff..53a54a7 100644 (file)
@@ -253,7 +253,7 @@ void sidtab_hash_eval(struct sidtab *h, char *tag)
                }
        }
 
-       printk(KERN_INFO "%s:  %d entries and %d/%d buckets used, longest "
+       printk(KERN_DEBUG "%s:  %d entries and %d/%d buckets used, longest "
               "chain length %d\n", tag, h->nel, slots_used, SIDTAB_SIZE,
               max_chain_len);
 }