summary refs log tree commit diff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/Kconfig2
-rw-r--r--drivers/Makefile1
-rw-r--r--drivers/atm/Kconfig1
-rw-r--r--drivers/atm/ambassador.c17
-rw-r--r--drivers/block/Kconfig14
-rw-r--r--drivers/block/acsi_slm.c4
-rw-r--r--drivers/block/cciss.c2
-rw-r--r--drivers/block/loop.c4
-rw-r--r--drivers/block/nbd.c2
-rw-r--r--drivers/block/pktcdvd.c547
-rw-r--r--drivers/char/Kconfig15
-rw-r--r--drivers/char/Makefile1
-rw-r--r--drivers/char/amiserial.c6
-rw-r--r--drivers/char/cs5535_gpio.c4
-rw-r--r--drivers/char/cyclades.c7769
-rw-r--r--drivers/char/drm/drm_ioc32.c56
-rw-r--r--drivers/char/drm/i915_ioc32.c12
-rw-r--r--drivers/char/drm/mga_ioc32.c8
-rw-r--r--drivers/char/drm/r128_ioc32.c10
-rw-r--r--drivers/char/drm/radeon_ioc32.c20
-rw-r--r--drivers/char/dsp56k.c6
-rw-r--r--drivers/char/dtlk.c4
-rw-r--r--drivers/char/epca.c16
-rw-r--r--drivers/char/esp.c2
-rw-r--r--drivers/char/generic_serial.c4
-rw-r--r--drivers/char/hvcs.c6
-rw-r--r--drivers/char/hvsi.c2
-rw-r--r--drivers/char/ip2/ip2main.c12
-rw-r--r--drivers/char/ipmi/ipmi_devintf.c4
-rw-r--r--drivers/char/isicom.c296
-rw-r--r--drivers/char/istallion.c1164
-rw-r--r--drivers/char/lp.c4
-rw-r--r--drivers/char/mem.c4
-rw-r--r--drivers/char/moxa.c18
-rw-r--r--drivers/char/mxser.c32
-rw-r--r--drivers/char/mxser_new.c2804
-rw-r--r--drivers/char/mxser_new.h450
-rw-r--r--drivers/char/n_r3964.c4
-rw-r--r--drivers/char/n_tty.c2
-rw-r--r--drivers/char/nsc_gpio.c4
-rw-r--r--drivers/char/pcmcia/synclink_cs.c2
-rw-r--r--drivers/char/ppdev.c4
-rw-r--r--drivers/char/pty.c10
-rw-r--r--drivers/char/random.c2
-rw-r--r--drivers/char/raw.c2
-rw-r--r--drivers/char/riscom8.c4
-rw-r--r--drivers/char/rocket.c10
-rw-r--r--drivers/char/ser_a2232.c2
-rw-r--r--drivers/char/serial167.c2
-rw-r--r--drivers/char/sonypi.c2
-rw-r--r--drivers/char/specialix.c9
-rw-r--r--drivers/char/stallion.c2148
-rw-r--r--drivers/char/sx.c2232
-rw-r--r--drivers/char/sx.h1
-rw-r--r--drivers/char/synclink.c4
-rw-r--r--drivers/char/synclink_gt.c6
-rw-r--r--drivers/char/synclinkmp.c6
-rw-r--r--drivers/char/tb0219.c4
-rw-r--r--drivers/char/tipar.c4
-rw-r--r--drivers/char/tty_io.c396
-rw-r--r--drivers/char/tty_ioctl.c264
-rw-r--r--drivers/char/vc_screen.c6
-rw-r--r--drivers/char/viotape.c10
-rw-r--r--drivers/char/vme_scc.c2
-rw-r--r--drivers/char/vr41xx_giu.c4
-rw-r--r--drivers/clocksource/acpi_pm.c36
-rw-r--r--drivers/hid/Kconfig18
-rw-r--r--drivers/hid/Makefile15
-rw-r--r--drivers/hid/hid-core.c1003
-rw-r--r--drivers/hid/hid-input.c (renamed from drivers/usb/input/hid-input.c)151
-rw-r--r--drivers/i2c/i2c-dev.c4
-rw-r--r--drivers/ide/pci/alim15x3.c16
-rw-r--r--drivers/ide/pci/pdc202xx_new.c22
-rw-r--r--drivers/ide/pci/sis5513.c3
-rw-r--r--drivers/ide/pci/sl82c105.c31
-rw-r--r--drivers/ieee1394/ieee1394_core.h2
-rw-r--r--drivers/infiniband/core/uverbs_main.c6
-rw-r--r--drivers/infiniband/hw/ipath/ipath_file_ops.c4
-rw-r--r--drivers/infiniband/hw/ipath/ipath_fs.c10
-rw-r--r--drivers/infiniband/hw/mthca/mthca_provider.c4
-rw-r--r--drivers/infiniband/hw/mthca/mthca_qp.c4
-rw-r--r--drivers/infiniband/hw/mthca/mthca_srq.c4
-rw-r--r--drivers/infiniband/ulp/iser/iser_memory.c4
-rw-r--r--drivers/input/Makefile1
-rw-r--r--drivers/isdn/act2000/module.c3
-rw-r--r--drivers/isdn/capi/capi.c13
-rw-r--r--drivers/isdn/capi/capidrv.c9
-rw-r--r--drivers/isdn/gigaset/Kconfig1
-rw-r--r--drivers/isdn/gigaset/asyncdata.c5
-rw-r--r--drivers/isdn/gigaset/common.c37
-rw-r--r--drivers/isdn/gigaset/gigaset.h4
-rw-r--r--drivers/isdn/gigaset/interface.c4
-rw-r--r--drivers/isdn/gigaset/isocdata.c5
-rw-r--r--drivers/isdn/hardware/avm/avm_cs.c3
-rw-r--r--drivers/isdn/hardware/avm/b1.c10
-rw-r--r--drivers/isdn/hardware/avm/t1isa.c1
-rw-r--r--drivers/isdn/hardware/eicon/debug.c4
-rw-r--r--drivers/isdn/hardware/eicon/di.c8
-rw-r--r--drivers/isdn/hardware/eicon/divasmain.c2
-rw-r--r--drivers/isdn/hardware/eicon/io.c2
-rw-r--r--drivers/isdn/hardware/eicon/istream.c4
-rw-r--r--drivers/isdn/hardware/eicon/platform.h8
-rw-r--r--drivers/isdn/hisax/Kconfig8
-rw-r--r--drivers/isdn/hisax/avma1_cs.c3
-rw-r--r--drivers/isdn/hisax/config.c21
-rw-r--r--drivers/isdn/hisax/diva.c4
-rw-r--r--drivers/isdn/hisax/elsa_cs.c3
-rw-r--r--drivers/isdn/hisax/fsm.c4
-rw-r--r--drivers/isdn/hisax/hfc4s8s_l1.c3
-rw-r--r--drivers/isdn/hisax/hfc_pci.c10
-rw-r--r--drivers/isdn/hisax/hfc_usb.c3
-rw-r--r--drivers/isdn/hisax/hisax.h6
-rw-r--r--drivers/isdn/hisax/hisax_fcpcipnp.c4
-rw-r--r--drivers/isdn/hisax/hisax_isac.c2
-rw-r--r--drivers/isdn/hisax/isdnhdlc.c25
-rw-r--r--drivers/isdn/hisax/isdnhdlc.h2
-rw-r--r--drivers/isdn/hisax/sedlbauer.c4
-rw-r--r--drivers/isdn/hisax/sedlbauer_cs.c3
-rw-r--r--drivers/isdn/hisax/st5481_b.c3
-rw-r--r--drivers/isdn/hisax/st5481_d.c4
-rw-r--r--drivers/isdn/hisax/st5481_init.c4
-rw-r--r--drivers/isdn/hisax/teles_cs.c3
-rw-r--r--drivers/isdn/hysdn/hycapi.c3
-rw-r--r--drivers/isdn/hysdn/hysdn_boot.c3
-rw-r--r--drivers/isdn/hysdn/hysdn_init.c3
-rw-r--r--drivers/isdn/hysdn/hysdn_net.c3
-rw-r--r--drivers/isdn/hysdn/hysdn_proclog.c7
-rw-r--r--drivers/isdn/i4l/isdn_bsdcomp.c4
-rw-r--r--drivers/isdn/i4l/isdn_common.c15
-rw-r--r--drivers/isdn/i4l/isdn_net.c6
-rw-r--r--drivers/isdn/i4l/isdn_ppp.c21
-rw-r--r--drivers/isdn/i4l/isdn_tty.c2
-rw-r--r--drivers/isdn/i4l/isdn_v110.c3
-rw-r--r--drivers/isdn/icn/icn.c3
-rw-r--r--drivers/isdn/isdnloop/isdnloop.c3
-rw-r--r--drivers/isdn/pcbit/drv.c9
-rw-r--r--drivers/isdn/pcbit/layer2.c3
-rw-r--r--drivers/isdn/sc/init.c9
-rw-r--r--drivers/md/bitmap.c8
-rw-r--r--drivers/md/dm-bio-list.h14
-rw-r--r--drivers/md/dm-crypt.c4
-rw-r--r--drivers/md/dm-emc.c10
-rw-r--r--drivers/md/dm-hw-handler.h2
-rw-r--r--drivers/md/dm-io.c15
-rw-r--r--drivers/md/dm-ioctl.c16
-rw-r--r--drivers/md/dm-linear.c4
-rw-r--r--drivers/md/dm-log.c24
-rw-r--r--drivers/md/dm-log.h10
-rw-r--r--drivers/md/dm-mpath.c52
-rw-r--r--drivers/md/dm-mpath.h4
-rw-r--r--drivers/md/dm-path-selector.h12
-rw-r--r--drivers/md/dm-raid1.c25
-rw-r--r--drivers/md/dm-round-robin.c12
-rw-r--r--drivers/md/dm-snap.c33
-rw-r--r--drivers/md/dm-stripe.c2
-rw-r--r--drivers/md/dm-zero.c2
-rw-r--r--drivers/md/dm.c130
-rw-r--r--drivers/md/dm.h19
-rw-r--r--drivers/md/md.c12
-rw-r--r--drivers/media/video/compat_ioctl32.c2
-rw-r--r--drivers/media/video/videodev.c2
-rw-r--r--drivers/media/video/zoran_procfs.c4
-rw-r--r--drivers/mmc/au1xmmc.c2
-rw-r--r--drivers/mmc/pxamci.c4
-rw-r--r--drivers/mmc/tifm_sd.c2
-rw-r--r--drivers/net/irda/irtty-sir.c4
-rw-r--r--drivers/net/via-velocity.c2
-rw-r--r--drivers/net/wan/cosa.c4
-rw-r--r--drivers/net/wireless/strip.c2
-rw-r--r--drivers/oprofile/buffer_sync.c8
-rw-r--r--drivers/pci/proc.c8
-rw-r--r--drivers/pcmcia/pcmcia_ioctl.c6
-rw-r--r--drivers/pnp/isapnp/proc.c2
-rw-r--r--drivers/s390/block/dasd_ioctl.c2
-rw-r--r--drivers/s390/char/fs3270.c16
-rw-r--r--drivers/s390/char/sclp_tty.c2
-rw-r--r--drivers/s390/char/tape_char.c8
-rw-r--r--drivers/s390/char/tty3270.c2
-rw-r--r--drivers/sbus/char/bpp.c4
-rw-r--r--drivers/sbus/char/cpwatchdog.c2
-rw-r--r--drivers/sbus/char/display7seg.c2
-rw-r--r--drivers/sbus/char/openprom.c2
-rw-r--r--drivers/sbus/char/vfc_dev.c2
-rw-r--r--drivers/scsi/sd.c2
-rw-r--r--drivers/scsi/st.c2
-rw-r--r--drivers/serial/21285.c4
-rw-r--r--drivers/serial/68328serial.c2
-rw-r--r--drivers/serial/68360serial.c2
-rw-r--r--drivers/serial/8250.c4
-rw-r--r--drivers/serial/amba-pl010.c4
-rw-r--r--drivers/serial/amba-pl011.c4
-rw-r--r--drivers/serial/atmel_serial.c2
-rw-r--r--drivers/serial/clps711x.c4
-rw-r--r--drivers/serial/crisv10.c8
-rw-r--r--drivers/serial/crisv10.h4
-rw-r--r--drivers/serial/dz.c4
-rw-r--r--drivers/serial/icom.c4
-rw-r--r--drivers/serial/imx.c4
-rw-r--r--drivers/serial/ioc3_serial.c4
-rw-r--r--drivers/serial/ioc4_serial.c6
-rw-r--r--drivers/serial/ip22zilog.c4
-rw-r--r--drivers/serial/jsm/jsm_tty.c10
-rw-r--r--drivers/serial/m32r_sio.c2
-rw-r--r--drivers/serial/mcfserial.c2
-rw-r--r--drivers/serial/mpc52xx_uart.c4
-rw-r--r--drivers/serial/mpsc.c4
-rw-r--r--drivers/serial/mux.c4
-rw-r--r--drivers/serial/netx-serial.c4
-rw-r--r--drivers/serial/pmac_zilog.c10
-rw-r--r--drivers/serial/pmac_zilog.h2
-rw-r--r--drivers/serial/pxa.c4
-rw-r--r--drivers/serial/s3c2410.c4
-rw-r--r--drivers/serial/sa1100.c4
-rw-r--r--drivers/serial/serial_core.c21
-rw-r--r--drivers/serial/serial_lh7a40x.c4
-rw-r--r--drivers/serial/serial_txx9.c4
-rw-r--r--drivers/serial/sh-sci.c4
-rw-r--r--drivers/serial/sn_console.c4
-rw-r--r--drivers/serial/sunhv.c4
-rw-r--r--drivers/serial/sunsab.c4
-rw-r--r--drivers/serial/sunsu.c4
-rw-r--r--drivers/serial/sunzilog.c4
-rw-r--r--drivers/serial/uartlite.c4
-rw-r--r--drivers/serial/v850e_uart.c4
-rw-r--r--drivers/serial/vr41xx_siu.c4
-rw-r--r--drivers/tc/zs.c2
-rw-r--r--drivers/telephony/ixj.c10
-rw-r--r--drivers/usb/class/cdc-acm.c4
-rw-r--r--drivers/usb/core/inode.c4
-rw-r--r--drivers/usb/gadget/file_storage.c16
-rw-r--r--drivers/usb/gadget/serial.c4
-rw-r--r--drivers/usb/input/Kconfig21
-rw-r--r--drivers/usb/input/Makefile3
-rw-r--r--drivers/usb/input/hid-core.c1415
-rw-r--r--drivers/usb/input/hid-debug.h757
-rw-r--r--drivers/usb/input/hid-ff.c8
-rw-r--r--drivers/usb/input/hid-lgff.c7
-rw-r--r--drivers/usb/input/hid-pidff.c58
-rw-r--r--drivers/usb/input/hid-tmff.c5
-rw-r--r--drivers/usb/input/hid-zpff.c7
-rw-r--r--drivers/usb/input/hid.h540
-rw-r--r--drivers/usb/input/hiddev.c37
-rw-r--r--drivers/usb/input/usbhid.h84
-rw-r--r--drivers/usb/misc/sisusbvga/sisusb.c2
-rw-r--r--drivers/usb/serial/ark3116.c4
-rw-r--r--drivers/usb/serial/belkin_sa.c4
-rw-r--r--drivers/usb/serial/console.c2
-rw-r--r--drivers/usb/serial/cp2101.c4
-rw-r--r--drivers/usb/serial/cypress_m8.c10
-rw-r--r--drivers/usb/serial/digi_acceleport.c6
-rw-r--r--drivers/usb/serial/empeg.c4
-rw-r--r--drivers/usb/serial/ftdi_sio.c4
-rw-r--r--drivers/usb/serial/io_edgeport.c8
-rw-r--r--drivers/usb/serial/io_ti.c6
-rw-r--r--drivers/usb/serial/ir-usb.c4
-rw-r--r--drivers/usb/serial/keyspan.c2
-rw-r--r--drivers/usb/serial/keyspan.h2
-rw-r--r--drivers/usb/serial/keyspan_pda.c2
-rw-r--r--drivers/usb/serial/kl5kusb105.c6
-rw-r--r--drivers/usb/serial/kobil_sct.c10
-rw-r--r--drivers/usb/serial/mct_u232.c4
-rw-r--r--drivers/usb/serial/mos7720.c4
-rw-r--r--drivers/usb/serial/mos7840.c4
-rw-r--r--drivers/usb/serial/option.c4
-rw-r--r--drivers/usb/serial/pl2303.c4
-rw-r--r--drivers/usb/serial/sierra.c2
-rw-r--r--drivers/usb/serial/ti_usb_3410_5052.c4
-rw-r--r--drivers/usb/serial/usb-serial.c2
-rw-r--r--drivers/usb/serial/visor.c4
-rw-r--r--drivers/usb/serial/whiteheat.c6
-rw-r--r--drivers/video/Kconfig4
-rw-r--r--drivers/video/S3triofb.c7
-rw-r--r--drivers/video/amifb.c8
-rw-r--r--drivers/video/arcfb.c2
-rw-r--r--drivers/video/atafb.c13
-rw-r--r--drivers/video/aty/aty128fb.c5
-rw-r--r--drivers/video/aty/atyfb.h9
-rw-r--r--drivers/video/aty/atyfb_base.c193
-rw-r--r--drivers/video/aty/mach64_ct.c47
-rw-r--r--drivers/video/aty/radeon_monitor.c3
-rw-r--r--drivers/video/au1100fb.h2
-rw-r--r--drivers/video/backlight/backlight.c95
-rw-r--r--drivers/video/backlight/corgi_bl.c4
-rw-r--r--drivers/video/backlight/hp680_bl.c4
-rw-r--r--drivers/video/backlight/lcd.c80
-rw-r--r--drivers/video/backlight/locomolcd.c4
-rw-r--r--drivers/video/cfbimgblt.c8
-rw-r--r--drivers/video/cirrusfb.c15
-rw-r--r--drivers/video/console/softcursor.c26
-rw-r--r--drivers/video/console/sticon.c2
-rw-r--r--drivers/video/console/vgacon.c30
-rw-r--r--drivers/video/cyberfb.c4
-rw-r--r--drivers/video/epson1355fb.c4
-rw-r--r--drivers/video/fbcmap.c55
-rw-r--r--drivers/video/fbcvt.c2
-rw-r--r--drivers/video/fbmem.c22
-rw-r--r--drivers/video/fbmon.c2
-rw-r--r--drivers/video/ffb.c4
-rw-r--r--drivers/video/fm2fb.c1
-rw-r--r--drivers/video/geode/Kconfig20
-rw-r--r--drivers/video/geode/display_gx.c23
-rw-r--r--drivers/video/geode/display_gx.h7
-rw-r--r--drivers/video/geode/gxfb_core.c53
-rw-r--r--drivers/video/geode/video_gx.c107
-rw-r--r--drivers/video/geode/video_gx.h25
-rw-r--r--drivers/video/hpfb.c2
-rw-r--r--drivers/video/i810/i810-i2c.c4
-rw-r--r--drivers/video/igafb.c6
-rw-r--r--drivers/video/intelfb/intelfbdrv.c3
-rw-r--r--drivers/video/macfb.c20
-rw-r--r--drivers/video/mbx/mbxdebugfs.c188
-rw-r--r--drivers/video/mbx/mbxfb.c359
-rw-r--r--drivers/video/mbx/reg_bits.h114
-rw-r--r--drivers/video/mbx/regs.h2
-rw-r--r--drivers/video/modedb.c6
-rw-r--r--drivers/video/neofb.c2
-rw-r--r--drivers/video/nvidia/nv_accel.c35
-rw-r--r--drivers/video/nvidia/nv_i2c.c7
-rw-r--r--drivers/video/nvidia/nv_local.h11
-rw-r--r--drivers/video/nvidia/nv_of.c3
-rw-r--r--drivers/video/nvidia/nv_proto.h1
-rw-r--r--drivers/video/offb.c3
-rw-r--r--drivers/video/platinumfb.c3
-rw-r--r--drivers/video/pmagb-b-fb.c2
-rw-r--r--drivers/video/pvr2fb.c18
-rw-r--r--drivers/video/retz3fb.c4
-rw-r--r--drivers/video/riva/fbdev.c66
-rw-r--r--drivers/video/riva/riva_hw.c10
-rw-r--r--drivers/video/riva/riva_hw.h17
-rw-r--r--drivers/video/s3c2410fb.c213
-rw-r--r--drivers/video/savage/savagefb-i2c.c7
-rw-r--r--drivers/video/sis/init301.c7
-rw-r--r--drivers/video/stifb.c3
-rw-r--r--drivers/video/tgafb.c58
-rw-r--r--drivers/video/tridentfb.c22
-rw-r--r--drivers/video/vesafb.c24
-rw-r--r--drivers/video/vga16fb.c28
-rw-r--r--drivers/video/virgefb.c17
-rw-r--r--drivers/zorro/proc.c2
339 files changed, 14928 insertions, 11166 deletions
diff --git a/drivers/Kconfig b/drivers/Kconfig
index f39463418904..4929e923b5c6 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -64,6 +64,8 @@ source "drivers/video/Kconfig"
 
 source "sound/Kconfig"
 
+source "drivers/hid/Kconfig"
+
 source "drivers/usb/Kconfig"
 
 source "drivers/mmc/Kconfig"
diff --git a/drivers/Makefile b/drivers/Makefile
index 67711770b1d9..50f76da598c9 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -77,4 +77,5 @@ obj-$(CONFIG_CRYPTO)		+= crypto/
 obj-$(CONFIG_SUPERH)		+= sh/
 obj-$(CONFIG_GENERIC_TIME)	+= clocksource/
 obj-$(CONFIG_DMA_ENGINE)	+= dma/
+obj-$(CONFIG_HID)		+= hid/
 obj-$(CONFIG_PPC_PS3)		+= ps3/
diff --git a/drivers/atm/Kconfig b/drivers/atm/Kconfig
index cfa5af883e13..2ddd76fdbc43 100644
--- a/drivers/atm/Kconfig
+++ b/drivers/atm/Kconfig
@@ -242,6 +242,7 @@ config ATM_IDT77252_USE_SUNI
 config ATM_AMBASSADOR
 	tristate "Madge Ambassador (Collage PCI 155 Server)"
 	depends on PCI && ATM
+	select BITREVERSE
 	help
 	  This is a driver for ATMizer based ATM card produced by Madge
 	  Networks Ltd. Say Y (or M to compile as a module named ambassador)
diff --git a/drivers/atm/ambassador.c b/drivers/atm/ambassador.c
index afa7d750a593..3c372e08f77d 100644
--- a/drivers/atm/ambassador.c
+++ b/drivers/atm/ambassador.c
@@ -32,6 +32,7 @@
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/poison.h>
+#include <linux/bitrev.h>
 
 #include <asm/atomic.h>
 #include <asm/io.h>
@@ -2068,18 +2069,6 @@ static void __devinit amb_ucode_version (amb_dev * dev) {
   PRINTK (KERN_INFO, "microcode version is %u.%u", major, minor);
 }
   
-// swap bits within byte to get Ethernet ordering
-static u8 bit_swap (u8 byte)
-{
-    const u8 swap[] = {
-      0x0, 0x8, 0x4, 0xc,
-      0x2, 0xa, 0x6, 0xe,
-      0x1, 0x9, 0x5, 0xd,
-      0x3, 0xb, 0x7, 0xf
-    };
-    return ((swap[byte & 0xf]<<4) | swap[byte>>4]);
-}
-
 // get end station address
 static void __devinit amb_esi (amb_dev * dev, u8 * esi) {
   u32 lower4;
@@ -2101,9 +2090,9 @@ static void __devinit amb_esi (amb_dev * dev, u8 * esi) {
     PRINTDB (DBG_INIT, "ESI:");
     for (i = 0; i < ESI_LEN; ++i) {
       if (i < 4)
-	  esi[i] = bit_swap (lower4>>(8*i));
+	  esi[i] = bitrev8(lower4>>(8*i));
       else
-	  esi[i] = bit_swap (upper2>>(8*(i-4)));
+	  esi[i] = bitrev8(upper2>>(8*(i-4)));
       PRINTDM (DBG_INIT, " %02x", esi[i]);
     }
     
diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig
index 85072446d772..ce9cfcb6071c 100644
--- a/drivers/block/Kconfig
+++ b/drivers/block/Kconfig
@@ -431,14 +431,18 @@ config CDROM_PKTCDVD
 	tristate "Packet writing on CD/DVD media"
 	depends on !UML
 	help
-	  If you have a CDROM drive that supports packet writing, say Y to
-	  include preliminary support. It should work with any MMC/Mt Fuji
-	  compliant ATAPI or SCSI drive, which is just about any newer CD
-	  writer.
+	  If you have a CDROM/DVD drive that supports packet writing, say
+	  Y to include support. It should work with any MMC/Mt Fuji
+	  compliant ATAPI or SCSI drive, which is just about any newer
+	  DVD/CD writer.
 
-	  Currently only writing to CD-RW, DVD-RW and DVD+RW discs is possible.
+	  Currently only writing to CD-RW, DVD-RW, DVD+RW and DVDRAM discs
+	  is possible.
 	  DVD-RW disks must be in restricted overwrite mode.
 
+	  See the file <file:Documentation/cdrom/packet-writing.txt>
+	  for further information on the use of this driver.
+
 	  To compile this driver as a module, choose M here: the
 	  module will be called pktcdvd.
 
diff --git a/drivers/block/acsi_slm.c b/drivers/block/acsi_slm.c
index 8e41c87b026e..e04be94d195c 100644
--- a/drivers/block/acsi_slm.c
+++ b/drivers/block/acsi_slm.c
@@ -363,7 +363,7 @@ static ssize_t slm_read( struct file *file, char *buf, size_t count,
 						 loff_t *ppos )
 
 {
-	struct inode *node = file->f_dentry->d_inode;
+	struct inode *node = file->f_path.dentry->d_inode;
 	unsigned long page;
 	int length;
 	int end;
@@ -618,7 +618,7 @@ static ssize_t slm_write( struct file *file, const char *buf, size_t count,
 						  loff_t *ppos )
 
 {
-	struct inode *node = file->f_dentry->d_inode;
+	struct inode *node = file->f_path.dentry->d_inode;
 	int		device = iminor(node);
 	int		n, filled, w, h;
 
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c
index 892e092afe9a..ee159edb6b88 100644
--- a/drivers/block/cciss.c
+++ b/drivers/block/cciss.c
@@ -535,7 +535,7 @@ static int do_ioctl(struct file *f, unsigned cmd, unsigned long arg)
 {
 	int ret;
 	lock_kernel();
-	ret = cciss_ioctl(f->f_dentry->d_inode, f, cmd, arg);
+	ret = cciss_ioctl(f->f_path.dentry->d_inode, f, cmd, arg);
 	unlock_kernel();
 	return ret;
 }
diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index beab6d2643cb..6b5b64207407 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -1000,7 +1000,7 @@ loop_get_status(struct loop_device *lo, struct loop_info64 *info)
 
 	if (lo->lo_state != Lo_bound)
 		return -ENXIO;
-	error = vfs_getattr(file->f_vfsmnt, file->f_dentry, &stat);
+	error = vfs_getattr(file->f_path.mnt, file->f_path.dentry, &stat);
 	if (error)
 		return error;
 	memset(info, 0, sizeof(*info));
@@ -1287,7 +1287,7 @@ loop_get_status_compat(struct loop_device *lo,
 
 static long lo_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 {
-	struct inode *inode = file->f_dentry->d_inode;
+	struct inode *inode = file->f_path.dentry->d_inode;
 	struct loop_device *lo = inode->i_bdev->bd_disk->private_data;
 	int err;
 
diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c
index 7bf2cfbd6285..090796bef78f 100644
--- a/drivers/block/nbd.c
+++ b/drivers/block/nbd.c
@@ -537,7 +537,7 @@ static int nbd_ioctl(struct inode *inode, struct file *file,
 		error = -EINVAL;
 		file = fget(arg);
 		if (file) {
-			inode = file->f_dentry->d_inode;
+			inode = file->f_path.dentry->d_inode;
 			if (S_ISSOCK(inode->i_mode)) {
 				lo->file = file;
 				lo->sock = SOCKET_I(inode);
diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c
index e45eaa264119..7c95c762950f 100644
--- a/drivers/block/pktcdvd.c
+++ b/drivers/block/pktcdvd.c
@@ -1,6 +1,7 @@
 /*
  * Copyright (C) 2000 Jens Axboe <axboe@suse.de>
  * Copyright (C) 2001-2004 Peter Osterlund <petero2@telia.com>
+ * Copyright (C) 2006 Thomas Maier <balagi@justmail.de>
  *
  * May be copied or modified under the terms of the GNU General Public
  * License.  See linux/COPYING for more information.
@@ -59,6 +60,8 @@
 #include <scsi/scsi_cmnd.h>
 #include <scsi/scsi_ioctl.h>
 #include <scsi/scsi.h>
+#include <linux/debugfs.h>
+#include <linux/device.h>
 
 #include <asm/uaccess.h>
 
@@ -83,9 +86,424 @@
 static struct pktcdvd_device *pkt_devs[MAX_WRITERS];
 static struct proc_dir_entry *pkt_proc;
 static int pktdev_major;
+static int write_congestion_on  = PKT_WRITE_CONGESTION_ON;
+static int write_congestion_off = PKT_WRITE_CONGESTION_OFF;
 static struct mutex ctl_mutex;	/* Serialize open/close/setup/teardown */
 static mempool_t *psd_pool;
 
+static struct class	*class_pktcdvd = NULL;    /* /sys/class/pktcdvd */
+static struct dentry	*pkt_debugfs_root = NULL; /* /debug/pktcdvd */
+
+/* forward declaration */
+static int pkt_setup_dev(dev_t dev, dev_t* pkt_dev);
+static int pkt_remove_dev(dev_t pkt_dev);
+static int pkt_seq_show(struct seq_file *m, void *p);
+
+
+
+/*
+ * create and register a pktcdvd kernel object.
+ */
+static struct pktcdvd_kobj* pkt_kobj_create(struct pktcdvd_device *pd,
+					const char* name,
+					struct kobject* parent,
+					struct kobj_type* ktype)
+{
+	struct pktcdvd_kobj *p;
+	p = kzalloc(sizeof(*p), GFP_KERNEL);
+	if (!p)
+		return NULL;
+	kobject_set_name(&p->kobj, "%s", name);
+	p->kobj.parent = parent;
+	p->kobj.ktype = ktype;
+	p->pd = pd;
+	if (kobject_register(&p->kobj) != 0)
+		return NULL;
+	return p;
+}
+/*
+ * remove a pktcdvd kernel object.
+ */
+static void pkt_kobj_remove(struct pktcdvd_kobj *p)
+{
+	if (p)
+		kobject_unregister(&p->kobj);
+}
+/*
+ * default release function for pktcdvd kernel objects.
+ */
+static void pkt_kobj_release(struct kobject *kobj)
+{
+	kfree(to_pktcdvdkobj(kobj));
+}
+
+
+/**********************************************************
+ *
+ * sysfs interface for pktcdvd
+ * by (C) 2006  Thomas Maier <balagi@justmail.de>
+ *
+ **********************************************************/
+
+#define DEF_ATTR(_obj,_name,_mode) \
+	static struct attribute _obj = { \
+		.name = _name, .owner = THIS_MODULE, .mode = _mode }
+
+/**********************************************************
+  /sys/class/pktcdvd/pktcdvd[0-7]/
+                     stat/reset
+                     stat/packets_started
+                     stat/packets_finished
+                     stat/kb_written
+                     stat/kb_read
+                     stat/kb_read_gather
+                     write_queue/size
+                     write_queue/congestion_off
+                     write_queue/congestion_on
+ **********************************************************/
+
+DEF_ATTR(kobj_pkt_attr_st1, "reset", 0200);
+DEF_ATTR(kobj_pkt_attr_st2, "packets_started", 0444);
+DEF_ATTR(kobj_pkt_attr_st3, "packets_finished", 0444);
+DEF_ATTR(kobj_pkt_attr_st4, "kb_written", 0444);
+DEF_ATTR(kobj_pkt_attr_st5, "kb_read", 0444);
+DEF_ATTR(kobj_pkt_attr_st6, "kb_read_gather", 0444);
+
+static struct attribute *kobj_pkt_attrs_stat[] = {
+	&kobj_pkt_attr_st1,
+	&kobj_pkt_attr_st2,
+	&kobj_pkt_attr_st3,
+	&kobj_pkt_attr_st4,
+	&kobj_pkt_attr_st5,
+	&kobj_pkt_attr_st6,
+	NULL
+};
+
+DEF_ATTR(kobj_pkt_attr_wq1, "size", 0444);
+DEF_ATTR(kobj_pkt_attr_wq2, "congestion_off", 0644);
+DEF_ATTR(kobj_pkt_attr_wq3, "congestion_on",  0644);
+
+static struct attribute *kobj_pkt_attrs_wqueue[] = {
+	&kobj_pkt_attr_wq1,
+	&kobj_pkt_attr_wq2,
+	&kobj_pkt_attr_wq3,
+	NULL
+};
+
+/* declares a char buffer[64] _dbuf, copies data from
+ * _b with length _l into it and ensures that _dbuf ends
+ * with a \0 character.
+ */
+#define DECLARE_BUF_AS_STRING(_dbuf, _b, _l) \
+	char _dbuf[64]; int dlen = (_l) < 0 ? 0 : (_l); \
+	if (dlen >= sizeof(_dbuf)) dlen = sizeof(_dbuf)-1; \
+	memcpy(_dbuf, _b, dlen); _dbuf[dlen] = 0
+
+static ssize_t kobj_pkt_show(struct kobject *kobj,
+			struct attribute *attr, char *data)
+{
+	struct pktcdvd_device *pd = to_pktcdvdkobj(kobj)->pd;
+	int n = 0;
+	int v;
+	if (strcmp(attr->name, "packets_started") == 0) {
+		n = sprintf(data, "%lu\n", pd->stats.pkt_started);
+
+	} else if (strcmp(attr->name, "packets_finished") == 0) {
+		n = sprintf(data, "%lu\n", pd->stats.pkt_ended);
+
+	} else if (strcmp(attr->name, "kb_written") == 0) {
+		n = sprintf(data, "%lu\n", pd->stats.secs_w >> 1);
+
+	} else if (strcmp(attr->name, "kb_read") == 0) {
+		n = sprintf(data, "%lu\n", pd->stats.secs_r >> 1);
+
+	} else if (strcmp(attr->name, "kb_read_gather") == 0) {
+		n = sprintf(data, "%lu\n", pd->stats.secs_rg >> 1);
+
+	} else if (strcmp(attr->name, "size") == 0) {
+		spin_lock(&pd->lock);
+		v = pd->bio_queue_size;
+		spin_unlock(&pd->lock);
+		n = sprintf(data, "%d\n", v);
+
+	} else if (strcmp(attr->name, "congestion_off") == 0) {
+		spin_lock(&pd->lock);
+		v = pd->write_congestion_off;
+		spin_unlock(&pd->lock);
+		n = sprintf(data, "%d\n", v);
+
+	} else if (strcmp(attr->name, "congestion_on") == 0) {
+		spin_lock(&pd->lock);
+		v = pd->write_congestion_on;
+		spin_unlock(&pd->lock);
+		n = sprintf(data, "%d\n", v);
+	}
+	return n;
+}
+
+static void init_write_congestion_marks(int* lo, int* hi)
+{
+	if (*hi > 0) {
+		*hi = max(*hi, 500);
+		*hi = min(*hi, 1000000);
+		if (*lo <= 0)
+			*lo = *hi - 100;
+		else {
+			*lo = min(*lo, *hi - 100);
+			*lo = max(*lo, 100);
+		}
+	} else {
+		*hi = -1;
+		*lo = -1;
+	}
+}
+
+static ssize_t kobj_pkt_store(struct kobject *kobj,
+			struct attribute *attr,
+			const char *data, size_t len)
+{
+	struct pktcdvd_device *pd = to_pktcdvdkobj(kobj)->pd;
+	int val;
+	DECLARE_BUF_AS_STRING(dbuf, data, len); /* ensure sscanf scans a string */
+
+	if (strcmp(attr->name, "reset") == 0 && dlen > 0) {
+		pd->stats.pkt_started = 0;
+		pd->stats.pkt_ended = 0;
+		pd->stats.secs_w = 0;
+		pd->stats.secs_rg = 0;
+		pd->stats.secs_r = 0;
+
+	} else if (strcmp(attr->name, "congestion_off") == 0
+		   && sscanf(dbuf, "%d", &val) == 1) {
+		spin_lock(&pd->lock);
+		pd->write_congestion_off = val;
+		init_write_congestion_marks(&pd->write_congestion_off,
+					&pd->write_congestion_on);
+		spin_unlock(&pd->lock);
+
+	} else if (strcmp(attr->name, "congestion_on") == 0
+		   && sscanf(dbuf, "%d", &val) == 1) {
+		spin_lock(&pd->lock);
+		pd->write_congestion_on = val;
+		init_write_congestion_marks(&pd->write_congestion_off,
+					&pd->write_congestion_on);
+		spin_unlock(&pd->lock);
+	}
+	return len;
+}
+
+static struct sysfs_ops kobj_pkt_ops = {
+	.show = kobj_pkt_show,
+	.store = kobj_pkt_store
+};
+static struct kobj_type kobj_pkt_type_stat = {
+	.release = pkt_kobj_release,
+	.sysfs_ops = &kobj_pkt_ops,
+	.default_attrs = kobj_pkt_attrs_stat
+};
+static struct kobj_type kobj_pkt_type_wqueue = {
+	.release = pkt_kobj_release,
+	.sysfs_ops = &kobj_pkt_ops,
+	.default_attrs = kobj_pkt_attrs_wqueue
+};
+
+static void pkt_sysfs_dev_new(struct pktcdvd_device *pd)
+{
+	if (class_pktcdvd) {
+		pd->clsdev = class_device_create(class_pktcdvd,
+					NULL, pd->pkt_dev,
+					NULL, "%s", pd->name);
+		if (IS_ERR(pd->clsdev))
+			pd->clsdev = NULL;
+	}
+	if (pd->clsdev) {
+		pd->kobj_stat = pkt_kobj_create(pd, "stat",
+					&pd->clsdev->kobj,
+					&kobj_pkt_type_stat);
+		pd->kobj_wqueue = pkt_kobj_create(pd, "write_queue",
+					&pd->clsdev->kobj,
+					&kobj_pkt_type_wqueue);
+	}
+}
+
+static void pkt_sysfs_dev_remove(struct pktcdvd_device *pd)
+{
+	pkt_kobj_remove(pd->kobj_stat);
+	pkt_kobj_remove(pd->kobj_wqueue);
+	if (class_pktcdvd)
+		class_device_destroy(class_pktcdvd, pd->pkt_dev);
+}
+
+
+/********************************************************************
+  /sys/class/pktcdvd/
+                     add            map block device
+                     remove         unmap packet dev
+                     device_map     show mappings
+ *******************************************************************/
+
+static void class_pktcdvd_release(struct class *cls)
+{
+	kfree(cls);
+}
+static ssize_t class_pktcdvd_show_map(struct class *c, char *data)
+{
+	int n = 0;
+	int idx;
+	mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING);
+	for (idx = 0; idx < MAX_WRITERS; idx++) {
+		struct pktcdvd_device *pd = pkt_devs[idx];
+		if (!pd)
+			continue;
+		n += sprintf(data+n, "%s %u:%u %u:%u\n",
+			pd->name,
+			MAJOR(pd->pkt_dev), MINOR(pd->pkt_dev),
+			MAJOR(pd->bdev->bd_dev),
+			MINOR(pd->bdev->bd_dev));
+	}
+	mutex_unlock(&ctl_mutex);
+	return n;
+}
+
+static ssize_t class_pktcdvd_store_add(struct class *c, const char *buf,
+					size_t count)
+{
+	unsigned int major, minor;
+	DECLARE_BUF_AS_STRING(dbuf, buf, count);
+	if (sscanf(dbuf, "%u:%u", &major, &minor) == 2) {
+		pkt_setup_dev(MKDEV(major, minor), NULL);
+		return count;
+	}
+	return -EINVAL;
+}
+
+static ssize_t class_pktcdvd_store_remove(struct class *c, const char *buf,
+					size_t count)
+{
+	unsigned int major, minor;
+	DECLARE_BUF_AS_STRING(dbuf, buf, count);
+	if (sscanf(dbuf, "%u:%u", &major, &minor) == 2) {
+		pkt_remove_dev(MKDEV(major, minor));
+		return count;
+	}
+	return -EINVAL;
+}
+
+static struct class_attribute class_pktcdvd_attrs[] = {
+ __ATTR(add,            0200, NULL, class_pktcdvd_store_add),
+ __ATTR(remove,         0200, NULL, class_pktcdvd_store_remove),
+ __ATTR(device_map,     0444, class_pktcdvd_show_map, NULL),
+ __ATTR_NULL
+};
+
+
+static int pkt_sysfs_init(void)
+{
+	int ret = 0;
+
+	/*
+	 * create control files in sysfs
+	 * /sys/class/pktcdvd/...
+	 */
+	class_pktcdvd = kzalloc(sizeof(*class_pktcdvd), GFP_KERNEL);
+	if (!class_pktcdvd)
+		return -ENOMEM;
+	class_pktcdvd->name = DRIVER_NAME;
+	class_pktcdvd->owner = THIS_MODULE;
+	class_pktcdvd->class_release = class_pktcdvd_release;
+	class_pktcdvd->class_attrs = class_pktcdvd_attrs;
+	ret = class_register(class_pktcdvd);
+	if (ret) {
+		kfree(class_pktcdvd);
+		class_pktcdvd = NULL;
+		printk(DRIVER_NAME": failed to create class pktcdvd\n");
+		return ret;
+	}
+	return 0;
+}
+
+static void pkt_sysfs_cleanup(void)
+{
+	if (class_pktcdvd)
+		class_destroy(class_pktcdvd);
+	class_pktcdvd = NULL;
+}
+
+/********************************************************************
+  entries in debugfs
+
+  /debugfs/pktcdvd[0-7]/
+			info
+
+ *******************************************************************/
+
+static int pkt_debugfs_seq_show(struct seq_file *m, void *p)
+{
+	return pkt_seq_show(m, p);
+}
+
+static int pkt_debugfs_fops_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, pkt_debugfs_seq_show, inode->i_private);
+}
+
+static struct file_operations debug_fops = {
+	.open		= pkt_debugfs_fops_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+	.owner		= THIS_MODULE,
+};
+
+static void pkt_debugfs_dev_new(struct pktcdvd_device *pd)
+{
+	if (!pkt_debugfs_root)
+		return;
+	pd->dfs_f_info = NULL;
+	pd->dfs_d_root = debugfs_create_dir(pd->name, pkt_debugfs_root);
+	if (IS_ERR(pd->dfs_d_root)) {
+		pd->dfs_d_root = NULL;
+		return;
+	}
+	pd->dfs_f_info = debugfs_create_file("info", S_IRUGO,
+				pd->dfs_d_root, pd, &debug_fops);
+	if (IS_ERR(pd->dfs_f_info)) {
+		pd->dfs_f_info = NULL;
+		return;
+	}
+}
+
+static void pkt_debugfs_dev_remove(struct pktcdvd_device *pd)
+{
+	if (!pkt_debugfs_root)
+		return;
+	if (pd->dfs_f_info)
+		debugfs_remove(pd->dfs_f_info);
+	pd->dfs_f_info = NULL;
+	if (pd->dfs_d_root)
+		debugfs_remove(pd->dfs_d_root);
+	pd->dfs_d_root = NULL;
+}
+
+static void pkt_debugfs_init(void)
+{
+	pkt_debugfs_root = debugfs_create_dir(DRIVER_NAME, NULL);
+	if (IS_ERR(pkt_debugfs_root)) {
+		pkt_debugfs_root = NULL;
+		return;
+	}
+}
+
+static void pkt_debugfs_cleanup(void)
+{
+	if (!pkt_debugfs_root)
+		return;
+	debugfs_remove(pkt_debugfs_root);
+	pkt_debugfs_root = NULL;
+}
+
+/* ----------------------------------------------------------*/
+
 
 static void pkt_bio_finished(struct pktcdvd_device *pd)
 {
@@ -893,6 +1311,7 @@ static int pkt_handle_queue(struct pktcdvd_device *pd)
 	sector_t zone = 0; /* Suppress gcc warning */
 	struct pkt_rb_node *node, *first_node;
 	struct rb_node *n;
+	int wakeup;
 
 	VPRINTK("handle_queue\n");
 
@@ -965,7 +1384,13 @@ try_next_bio:
 		pkt->write_size += bio->bi_size / CD_FRAMESIZE;
 		spin_unlock(&pkt->lock);
 	}
+	/* check write congestion marks, and if bio_queue_size is
+	   below, wake up any waiters */
+	wakeup = (pd->write_congestion_on > 0
+	 		&& pd->bio_queue_size <= pd->write_congestion_off);
 	spin_unlock(&pd->lock);
+	if (wakeup)
+		blk_clear_queue_congested(pd->disk->queue, WRITE);
 
 	pkt->sleep_time = max(PACKET_WAIT_TIME, 1);
 	pkt_set_state(pkt, PACKET_WAITING_STATE);
@@ -2178,6 +2603,23 @@ static int pkt_make_request(request_queue_t *q, struct bio *bio)
 	}
 	spin_unlock(&pd->cdrw.active_list_lock);
 
+ 	/*
+	 * Test if there is enough room left in the bio work queue
+	 * (queue size >= congestion on mark).
+	 * If not, wait till the work queue size is below the congestion off mark.
+	 */
+	spin_lock(&pd->lock);
+	if (pd->write_congestion_on > 0
+	    && pd->bio_queue_size >= pd->write_congestion_on) {
+		blk_set_queue_congested(q, WRITE);
+		do {
+			spin_unlock(&pd->lock);
+			congestion_wait(WRITE, HZ);
+			spin_lock(&pd->lock);
+		} while(pd->bio_queue_size > pd->write_congestion_off);
+	}
+	spin_unlock(&pd->lock);
+
 	/*
 	 * No matching packet found. Store the bio in the work queue.
 	 */
@@ -2297,6 +2739,9 @@ static int pkt_seq_show(struct seq_file *m, void *p)
 	seq_printf(m, "\tstate:\t\t\ti:%d ow:%d rw:%d ww:%d rec:%d fin:%d\n",
 		   states[0], states[1], states[2], states[3], states[4], states[5]);
 
+	seq_printf(m, "\twrite congestion marks:\toff=%d on=%d\n",
+			pd->write_congestion_off,
+			pd->write_congestion_on);
 	return 0;
 }
 
@@ -2436,36 +2881,33 @@ static struct block_device_operations pktcdvd_ops = {
 /*
  * Set up mapping from pktcdvd device to CD-ROM device.
  */
-static int pkt_setup_dev(struct pkt_ctrl_command *ctrl_cmd)
+static int pkt_setup_dev(dev_t dev, dev_t* pkt_dev)
 {
 	int idx;
 	int ret = -ENOMEM;
 	struct pktcdvd_device *pd;
 	struct gendisk *disk;
-	dev_t dev = new_decode_dev(ctrl_cmd->dev);
+
+	mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING);
 
 	for (idx = 0; idx < MAX_WRITERS; idx++)
 		if (!pkt_devs[idx])
 			break;
 	if (idx == MAX_WRITERS) {
 		printk(DRIVER_NAME": max %d writers supported\n", MAX_WRITERS);
-		return -EBUSY;
+		ret = -EBUSY;
+		goto out_mutex;
 	}
 
 	pd = kzalloc(sizeof(struct pktcdvd_device), GFP_KERNEL);
 	if (!pd)
-		return ret;
+		goto out_mutex;
 
 	pd->rb_pool = mempool_create_kmalloc_pool(PKT_RB_POOL_SIZE,
 						  sizeof(struct pkt_rb_node));
 	if (!pd->rb_pool)
 		goto out_mem;
 
-	disk = alloc_disk(1);
-	if (!disk)
-		goto out_mem;
-	pd->disk = disk;
-
 	INIT_LIST_HEAD(&pd->cdrw.pkt_free_list);
 	INIT_LIST_HEAD(&pd->cdrw.pkt_active_list);
 	spin_lock_init(&pd->cdrw.active_list_lock);
@@ -2476,11 +2918,18 @@ static int pkt_setup_dev(struct pkt_ctrl_command *ctrl_cmd)
 	init_waitqueue_head(&pd->wqueue);
 	pd->bio_queue = RB_ROOT;
 
+	pd->write_congestion_on  = write_congestion_on;
+	pd->write_congestion_off = write_congestion_off;
+
+	disk = alloc_disk(1);
+	if (!disk)
+		goto out_mem;
+	pd->disk = disk;
 	disk->major = pktdev_major;
 	disk->first_minor = idx;
 	disk->fops = &pktcdvd_ops;
 	disk->flags = GENHD_FL_REMOVABLE;
-	sprintf(disk->disk_name, DRIVER_NAME"%d", idx);
+	strcpy(disk->disk_name, pd->name);
 	disk->private_data = pd;
 	disk->queue = blk_alloc_queue(GFP_KERNEL);
 	if (!disk->queue)
@@ -2492,8 +2941,15 @@ static int pkt_setup_dev(struct pkt_ctrl_command *ctrl_cmd)
 		goto out_new_dev;
 
 	add_disk(disk);
+
+	pkt_sysfs_dev_new(pd);
+	pkt_debugfs_dev_new(pd);
+
 	pkt_devs[idx] = pd;
-	ctrl_cmd->pkt_dev = new_encode_dev(pd->pkt_dev);
+	if (pkt_dev)
+		*pkt_dev = pd->pkt_dev;
+
+	mutex_unlock(&ctl_mutex);
 	return 0;
 
 out_new_dev:
@@ -2504,17 +2960,22 @@ out_mem:
 	if (pd->rb_pool)
 		mempool_destroy(pd->rb_pool);
 	kfree(pd);
+out_mutex:
+	mutex_unlock(&ctl_mutex);
+	printk(DRIVER_NAME": setup of pktcdvd device failed\n");
 	return ret;
 }
 
 /*
  * Tear down mapping from pktcdvd device to CD-ROM device.
  */
-static int pkt_remove_dev(struct pkt_ctrl_command *ctrl_cmd)
+static int pkt_remove_dev(dev_t pkt_dev)
 {
 	struct pktcdvd_device *pd;
 	int idx;
-	dev_t pkt_dev = new_decode_dev(ctrl_cmd->pkt_dev);
+	int ret = 0;
+
+	mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING);
 
 	for (idx = 0; idx < MAX_WRITERS; idx++) {
 		pd = pkt_devs[idx];
@@ -2523,15 +2984,22 @@ static int pkt_remove_dev(struct pkt_ctrl_command *ctrl_cmd)
 	}
 	if (idx == MAX_WRITERS) {
 		DPRINTK(DRIVER_NAME": dev not setup\n");
-		return -ENXIO;
+		ret = -ENXIO;
+		goto out;
 	}
 
-	if (pd->refcnt > 0)
-		return -EBUSY;
-
+	if (pd->refcnt > 0) {
+		ret = -EBUSY;
+		goto out;
+	}
 	if (!IS_ERR(pd->cdrw.thread))
 		kthread_stop(pd->cdrw.thread);
 
+	pkt_devs[idx] = NULL;
+
+	pkt_debugfs_dev_remove(pd);
+	pkt_sysfs_dev_remove(pd);
+
 	blkdev_put(pd->bdev);
 
 	remove_proc_entry(pd->name, pkt_proc);
@@ -2541,18 +3009,24 @@ static int pkt_remove_dev(struct pkt_ctrl_command *ctrl_cmd)
 	blk_cleanup_queue(pd->disk->queue);
 	put_disk(pd->disk);
 
-	pkt_devs[idx] = NULL;
 	mempool_destroy(pd->rb_pool);
 	kfree(pd);
 
 	/* This is safe: open() is still holding a reference. */
 	module_put(THIS_MODULE);
-	return 0;
+
+out:
+	mutex_unlock(&ctl_mutex);
+	return ret;
 }
 
 static void pkt_get_status(struct pkt_ctrl_command *ctrl_cmd)
 {
-	struct pktcdvd_device *pd = pkt_find_dev_from_minor(ctrl_cmd->dev_index);
+	struct pktcdvd_device *pd;
+
+	mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING);
+
+	pd = pkt_find_dev_from_minor(ctrl_cmd->dev_index);
 	if (pd) {
 		ctrl_cmd->dev = new_encode_dev(pd->bdev->bd_dev);
 		ctrl_cmd->pkt_dev = new_encode_dev(pd->pkt_dev);
@@ -2561,6 +3035,8 @@ static void pkt_get_status(struct pkt_ctrl_command *ctrl_cmd)
 		ctrl_cmd->pkt_dev = 0;
 	}
 	ctrl_cmd->num_devices = MAX_WRITERS;
+
+	mutex_unlock(&ctl_mutex);
 }
 
 static int pkt_ctl_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
@@ -2568,6 +3044,7 @@ static int pkt_ctl_ioctl(struct inode *inode, struct file *file, unsigned int cm
 	void __user *argp = (void __user *)arg;
 	struct pkt_ctrl_command ctrl_cmd;
 	int ret = 0;
+	dev_t pkt_dev = 0;
 
 	if (cmd != PACKET_CTRL_CMD)
 		return -ENOTTY;
@@ -2579,21 +3056,16 @@ static int pkt_ctl_ioctl(struct inode *inode, struct file *file, unsigned int cm
 	case PKT_CTRL_CMD_SETUP:
 		if (!capable(CAP_SYS_ADMIN))
 			return -EPERM;
-		mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING);
-		ret = pkt_setup_dev(&ctrl_cmd);
-		mutex_unlock(&ctl_mutex);
+		ret = pkt_setup_dev(new_decode_dev(ctrl_cmd.dev), &pkt_dev);
+		ctrl_cmd.pkt_dev = new_encode_dev(pkt_dev);
 		break;
 	case PKT_CTRL_CMD_TEARDOWN:
 		if (!capable(CAP_SYS_ADMIN))
 			return -EPERM;
-		mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING);
-		ret = pkt_remove_dev(&ctrl_cmd);
-		mutex_unlock(&ctl_mutex);
+		ret = pkt_remove_dev(new_decode_dev(ctrl_cmd.pkt_dev));
 		break;
 	case PKT_CTRL_CMD_STATUS:
-		mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING);
 		pkt_get_status(&ctrl_cmd);
-		mutex_unlock(&ctl_mutex);
 		break;
 	default:
 		return -ENOTTY;
@@ -2620,6 +3092,8 @@ static int __init pkt_init(void)
 {
 	int ret;
 
+	mutex_init(&ctl_mutex);
+
 	psd_pool = mempool_create_kmalloc_pool(PSD_POOL_SIZE,
 					sizeof(struct packet_stacked_data));
 	if (!psd_pool)
@@ -2633,18 +3107,25 @@ static int __init pkt_init(void)
 	if (!pktdev_major)
 		pktdev_major = ret;
 
+	ret = pkt_sysfs_init();
+	if (ret)
+		goto out;
+
+	pkt_debugfs_init();
+
 	ret = misc_register(&pkt_misc);
 	if (ret) {
 		printk(DRIVER_NAME": Unable to register misc device\n");
-		goto out;
+		goto out_misc;
 	}
 
-	mutex_init(&ctl_mutex);
-
 	pkt_proc = proc_mkdir(DRIVER_NAME, proc_root_driver);
 
 	return 0;
 
+out_misc:
+	pkt_debugfs_cleanup();
+	pkt_sysfs_cleanup();
 out:
 	unregister_blkdev(pktdev_major, DRIVER_NAME);
 out2:
@@ -2656,6 +3137,10 @@ static void __exit pkt_exit(void)
 {
 	remove_proc_entry(DRIVER_NAME, proc_root_driver);
 	misc_deregister(&pkt_misc);
+
+	pkt_debugfs_cleanup();
+	pkt_sysfs_cleanup();
+
 	unregister_blkdev(pktdev_major, DRIVER_NAME);
 	mempool_destroy(psd_pool);
 }
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index 24f922f12783..b10f4d8fdc7f 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -201,6 +201,21 @@ config MOXA_SMARTIO
 	  The module will be called mxser. If you want to do that, say M
 	  here.
 
+config MOXA_SMARTIO_NEW
+	tristate "Moxa SmartIO support v. 2.0 (EXPERIMENTAL)"
+	depends on SERIAL_NONSTANDARD
+	help
+	  Say Y here if you have a Moxa SmartIO multiport serial card and/or
+	  want to help develop a new version of this driver.
+
+	  This is upgraded (1.9.1) driver from original Moxa drivers with
+	  changes finally resulting in PCI probing.
+
+	  Use at your own risk.
+
+	  This driver can also be built as a module. The module will be called
+	  mxser_new. If you want to do that, say M here.
+
 config ISI
 	tristate "Multi-Tech multiport card support (EXPERIMENTAL)"
 	depends on SERIAL_NONSTANDARD
diff --git a/drivers/char/Makefile b/drivers/char/Makefile
index b1fcdab90947..fc110637ced6 100644
--- a/drivers/char/Makefile
+++ b/drivers/char/Makefile
@@ -31,6 +31,7 @@ obj-$(CONFIG_MOXA_INTELLIO)	+= moxa.o
 obj-$(CONFIG_A2232)		+= ser_a2232.o generic_serial.o
 obj-$(CONFIG_ATARI_DSP56K)	+= dsp56k.o
 obj-$(CONFIG_MOXA_SMARTIO)	+= mxser.o
+obj-$(CONFIG_MOXA_SMARTIO_NEW)	+= mxser_new.o
 obj-$(CONFIG_COMPUTONE)		+= ip2/
 obj-$(CONFIG_RISCOM8)		+= riscom8.o
 obj-$(CONFIG_ISI)		+= isicom.o
diff --git a/drivers/char/amiserial.c b/drivers/char/amiserial.c
index 66086fa2d59a..feb4ac802a0d 100644
--- a/drivers/char/amiserial.c
+++ b/drivers/char/amiserial.c
@@ -104,7 +104,7 @@ static struct async_struct *IRQ_ports;
 
 static unsigned char current_ctl_bits;
 
-static void change_speed(struct async_struct *info, struct termios *old);
+static void change_speed(struct async_struct *info, struct ktermios *old);
 static void rs_wait_until_sent(struct tty_struct *tty, int timeout);
 
 
@@ -694,7 +694,7 @@ static void shutdown(struct async_struct * info)
  * the specified baud rate for a serial port.
  */
 static void change_speed(struct async_struct *info,
-			 struct termios *old_termios)
+			 struct ktermios *old_termios)
 {
 	int	quot = 0, baud_base, baud;
 	unsigned cflag, cval = 0;
@@ -1365,7 +1365,7 @@ static int rs_ioctl(struct tty_struct *tty, struct file * file,
 	return 0;
 }
 
-static void rs_set_termios(struct tty_struct *tty, struct termios *old_termios)
+static void rs_set_termios(struct tty_struct *tty, struct ktermios *old_termios)
 {
 	struct async_struct *info = (struct async_struct *)tty->driver_data;
 	unsigned long flags;
diff --git a/drivers/char/cs5535_gpio.c b/drivers/char/cs5535_gpio.c
index 8ce3f34cfc22..c02d9e99e050 100644
--- a/drivers/char/cs5535_gpio.c
+++ b/drivers/char/cs5535_gpio.c
@@ -82,7 +82,7 @@ static inline u32 cs5535_lowhigh_base(int reg)
 static ssize_t cs5535_gpio_write(struct file *file, const char __user *data,
 				 size_t len, loff_t *ppos)
 {
-	u32	m = iminor(file->f_dentry->d_inode);
+	u32	m = iminor(file->f_path.dentry->d_inode);
 	int	i, j;
 	u32	base = gpio_base + cs5535_lowhigh_base(m);
 	u32	m0, m1;
@@ -117,7 +117,7 @@ static ssize_t cs5535_gpio_write(struct file *file, const char __user *data,
 static ssize_t cs5535_gpio_read(struct file *file, char __user *buf,
 				size_t len, loff_t *ppos)
 {
-	u32	m = iminor(file->f_dentry->d_inode);
+	u32	m = iminor(file->f_path.dentry->d_inode);
 	u32	base = gpio_base + cs5535_lowhigh_base(m);
 	int	rd_bit = 1 << (m & 0x0f);
 	int	i;
diff --git a/drivers/char/cyclades.c b/drivers/char/cyclades.c
index acb2de5e3a98..3ffa0807754c 100644
--- a/drivers/char/cyclades.c
+++ b/drivers/char/cyclades.c
@@ -1,8 +1,6 @@
 #undef	BLOCKMOVE
 #define	Z_WAKE
 #undef	Z_EXT_CHARS_IN_BUFFER
-static char rcsid[] =
-"$Revision: 2.3.2.20 $$Date: 2004/02/25 18:14:16 $";
 
 /*
  *  linux/drivers/char/cyclades.c
@@ -593,18 +591,20 @@ static char rcsid[] =
  *
  */
 
+#define CY_VERSION	"2.4"
+
 /* If you need to install more boards than NR_CARDS, change the constant
    in the definition below. No other change is necessary to support up to
    eight boards. Beyond that you'll have to extend cy_isa_addresses. */
 
-#define NR_CARDS        4
+#define NR_CARDS	4
 
 /*
    If the total number of ports is larger than NR_PORTS, change this
    constant in the definition below. No other change is necessary to
    support more boards/ports. */
 
-#define NR_PORTS        256
+#define NR_PORTS	256
 
 #define ZE_V1_NPORTS	64
 #define ZO_V1	0
@@ -625,9 +625,9 @@ static char rcsid[] =
 #undef	CY_PCI_DEBUG
 
 #if 0
-#define PAUSE __asm__("nop");
+#define PAUSE __asm__("nop")
 #else
-#define PAUSE ;
+#define PAUSE do {} while (0)
 #endif
 
 /*
@@ -663,7 +663,7 @@ static char rcsid[] =
 		do {						\
 		spin_lock_irqsave(&cy_card[info->card].card_lock, flags); \
 		} while (0)
-		
+
 #define	CY_UNLOCK(info,flags)					\
 		do {						\
 		spin_unlock_irqrestore(&cy_card[info->card].card_lock, flags); \
@@ -676,14 +676,14 @@ static char rcsid[] =
 #include <linux/stat.h>
 #include <linux/proc_fs.h>
 
-static void cy_throttle (struct tty_struct *tty);
-static void cy_send_xchar (struct tty_struct *tty, char ch);
+static void cy_throttle(struct tty_struct *tty);
+static void cy_send_xchar(struct tty_struct *tty, char ch);
 
 #define IS_CYC_Z(card) ((card).num_chips == -1)
 
 #define Z_FPGA_CHECK(card) \
-    ((cy_readl(&((struct RUNTIME_9060 __iomem *) \
-		 ((card).ctl_addr))->init_ctrl) & (1<<17)) != 0)
+	((cy_readl(&((struct RUNTIME_9060 __iomem *) \
+		((card).ctl_addr))->init_ctrl) & (1<<17)) != 0)
 
 #define ISZLOADED(card)	(((ZO_V1==cy_readl(&((struct RUNTIME_9060 __iomem *) \
 			((card).ctl_addr))->mail_box_0)) || \
@@ -698,8 +698,6 @@ static void cy_send_xchar (struct tty_struct *tty, char ch);
 
 #define STD_COM_FLAGS (0)
 
-#define	JIFFIES_DIFF(n, j)	((j) - (n))
-
 static struct tty_driver *cy_serial_driver;
 
 #ifdef CONFIG_ISA
@@ -713,27 +711,28 @@ static struct tty_driver *cy_serial_driver;
 */
 
 static unsigned int cy_isa_addresses[] = {
-        0xD0000,
-        0xD2000,
-        0xD4000,
-        0xD6000,
-        0xD8000,
-        0xDA000,
-        0xDC000,
-        0xDE000,
-        0,0,0,0,0,0,0,0
+	0xD0000,
+	0xD2000,
+	0xD4000,
+	0xD6000,
+	0xD8000,
+	0xDA000,
+	0xDC000,
+	0xDE000,
+	0, 0, 0, 0, 0, 0, 0, 0
 };
+
 #define NR_ISA_ADDRS ARRAY_SIZE(cy_isa_addresses)
 
 #ifdef MODULE
 static long maddr[NR_CARDS] = { 0, };
-static int irq[NR_CARDS]  = { 0, };
+static int irq[NR_CARDS] = { 0, };
 
 module_param_array(maddr, long, NULL, 0);
 module_param_array(irq, int, NULL, 0);
 #endif
 
-#endif /* CONFIG_ISA */
+#endif				/* CONFIG_ISA */
 
 /* This is the per-card data structure containing address, irq, number of
    channels, etc. This driver supports a maximum of NR_CARDS cards.
@@ -745,7 +744,7 @@ static struct cyclades_card cy_card[NR_CARDS];
 */
 static struct cyclades_port cy_port[NR_PORTS];
 
-static int cy_next_channel; /* next minor available */
+static int cy_next_channel;	/* next minor available */
 
 /*
  * This is used to look up the divisor speeds and the timeouts
@@ -757,36 +756,42 @@ static int cy_next_channel; /* next minor available */
  *     20
  */
 static int baud_table[] = {
-       0,    50,    75,   110,   134,   150,   200,   300,   600,  1200,
-    1800,  2400,  4800,  9600, 19200, 38400, 57600, 76800,115200,150000,
-  230400,     0};
-
-static char baud_co_25[] = {  /* 25 MHz clock option table */
-    /* value =>    00    01   02    03    04 */
-    /* divide by    8    32   128   512  2048 */
-    0x00,  0x04,  0x04,  0x04,  0x04,  0x04,  0x03,  0x03,  0x03,  0x02,
-    0x02,  0x02,  0x01,  0x01,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00};
-
-static char baud_bpr_25[] = {  /* 25 MHz baud rate period table */
-    0x00,  0xf5,  0xa3,  0x6f,  0x5c,  0x51,  0xf5,  0xa3,  0x51,  0xa3,
-    0x6d,  0x51,  0xa3,  0x51,  0xa3,  0x51,  0x36,  0x29,  0x1b,  0x15};
-
-static char baud_co_60[] = {  /* 60 MHz clock option table (CD1400 J) */
-    /* value =>    00    01   02    03    04 */
-    /* divide by    8    32   128   512  2048 */
-    0x00,  0x00,  0x00,  0x04,  0x04,  0x04,  0x04,  0x04,  0x03,  0x03,
-    0x03,  0x02,  0x02,  0x01,  0x01,  0x00,  0x00,  0x00,  0x00,  0x00,
-    0x00};
-
-static char baud_bpr_60[] = {  /* 60 MHz baud rate period table (CD1400 J) */
-    0x00,  0x82,  0x21,  0xff,  0xdb,  0xc3,  0x92,  0x62,  0xc3,  0x62,
-    0x41,  0xc3,  0x62,  0xc3,  0x62,  0xc3,  0x82,  0x62,  0x41,  0x32,
-    0x21};
-
-static char baud_cor3[] = {  /* receive threshold */
-    0x0a,  0x0a,  0x0a,  0x0a,  0x0a,  0x0a,  0x0a,  0x0a,  0x0a,  0x0a,
-    0x0a,  0x0a,  0x0a,  0x09,  0x09,  0x08,  0x08,  0x08,  0x08,  0x07,
-    0x07};
+	0, 50, 75, 110, 134, 150, 200, 300, 600, 1200,
+	1800, 2400, 4800, 9600, 19200, 38400, 57600, 76800, 115200, 150000,
+	230400, 0
+};
+
+static char baud_co_25[] = {	/* 25 MHz clock option table */
+	/* value =>    00    01   02    03    04 */
+	/* divide by    8    32   128   512  2048 */
+	0x00, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x02,
+	0x02, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+static char baud_bpr_25[] = {	/* 25 MHz baud rate period table */
+	0x00, 0xf5, 0xa3, 0x6f, 0x5c, 0x51, 0xf5, 0xa3, 0x51, 0xa3,
+	0x6d, 0x51, 0xa3, 0x51, 0xa3, 0x51, 0x36, 0x29, 0x1b, 0x15
+};
+
+static char baud_co_60[] = {	/* 60 MHz clock option table (CD1400 J) */
+	/* value =>    00    01   02    03    04 */
+	/* divide by    8    32   128   512  2048 */
+	0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, 0x03,
+	0x03, 0x02, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00
+};
+
+static char baud_bpr_60[] = {	/* 60 MHz baud rate period table (CD1400 J) */
+	0x00, 0x82, 0x21, 0xff, 0xdb, 0xc3, 0x92, 0x62, 0xc3, 0x62,
+	0x41, 0xc3, 0x62, 0xc3, 0x62, 0xc3, 0x82, 0x62, 0x41, 0x32,
+	0x21
+};
+
+static char baud_cor3[] = {	/* receive threshold */
+	0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
+	0x0a, 0x0a, 0x0a, 0x09, 0x09, 0x08, 0x08, 0x08, 0x08, 0x07,
+	0x07
+};
 
 /*
  * The Cyclades driver implements HW flow control as any serial driver.
@@ -799,42 +804,42 @@ static char baud_cor3[] = {  /* receive threshold */
  * cables.
  */
 
-static char rflow_thr[] = {  /* rflow threshold */
-    0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
-    0x00,  0x00,  0x00,  0x0a,  0x0a,  0x0a,  0x0a,  0x0a,  0x0a,  0x0a,
-    0x0a};
+static char rflow_thr[] = {	/* rflow threshold */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
+	0x0a
+};
 
 /*  The Cyclom-Ye has placed the sequential chips in non-sequential
  *  address order.  This look-up table overcomes that problem.
  */
-static int cy_chip_offset [] =
-    { 0x0000,
-      0x0400,
-      0x0800,
-      0x0C00,
-      0x0200,
-      0x0600,
-      0x0A00,
-      0x0E00
-    };
+static int cy_chip_offset[] = { 0x0000,
+	0x0400,
+	0x0800,
+	0x0C00,
+	0x0200,
+	0x0600,
+	0x0A00,
+	0x0E00
+};
 
 /* PCI related definitions */
 
-static unsigned short	cy_pci_nboard;
-static unsigned short	cy_isa_nboard;
-static unsigned short	cy_nboard;
+static unsigned short cy_pci_nboard;
+static unsigned short cy_isa_nboard;
+static unsigned short cy_nboard;
 #ifdef CONFIG_PCI
-static unsigned short	cy_pci_dev_id[] = {
-			    PCI_DEVICE_ID_CYCLOM_Y_Lo,	/* PCI < 1Mb */
-			    PCI_DEVICE_ID_CYCLOM_Y_Hi,	/* PCI > 1Mb */
-			    PCI_DEVICE_ID_CYCLOM_4Y_Lo,	/* 4Y PCI < 1Mb */
-			    PCI_DEVICE_ID_CYCLOM_4Y_Hi,	/* 4Y PCI > 1Mb */
-			    PCI_DEVICE_ID_CYCLOM_8Y_Lo,	/* 8Y PCI < 1Mb */
-			    PCI_DEVICE_ID_CYCLOM_8Y_Hi,	/* 8Y PCI > 1Mb */
-			    PCI_DEVICE_ID_CYCLOM_Z_Lo,	/* Z PCI < 1Mb */
-			    PCI_DEVICE_ID_CYCLOM_Z_Hi,	/* Z PCI > 1Mb */
-			    0				/* end of table */
-			};
+static unsigned short cy_pci_dev_id[] = {
+	PCI_DEVICE_ID_CYCLOM_Y_Lo,	/* PCI < 1Mb */
+	PCI_DEVICE_ID_CYCLOM_Y_Hi,	/* PCI > 1Mb */
+	PCI_DEVICE_ID_CYCLOM_4Y_Lo,	/* 4Y PCI < 1Mb */
+	PCI_DEVICE_ID_CYCLOM_4Y_Hi,	/* 4Y PCI > 1Mb */
+	PCI_DEVICE_ID_CYCLOM_8Y_Lo,	/* 8Y PCI < 1Mb */
+	PCI_DEVICE_ID_CYCLOM_8Y_Hi,	/* 8Y PCI > 1Mb */
+	PCI_DEVICE_ID_CYCLOM_Z_Lo,	/* Z PCI < 1Mb */
+	PCI_DEVICE_ID_CYCLOM_Z_Hi,	/* Z PCI > 1Mb */
+	0			/* end of table */
+};
 #endif
 
 static void cy_start(struct tty_struct *);
@@ -842,9 +847,9 @@ static void set_line_char(struct cyclades_port *);
 static int cyz_issue_cmd(struct cyclades_card *, uclong, ucchar, uclong);
 #ifdef CONFIG_ISA
 static unsigned detect_isa_irq(void __iomem *);
-#endif /* CONFIG_ISA */
+#endif				/* CONFIG_ISA */
 
-static int cyclades_get_proc_info(char *, char **, off_t , int , int *, void *);
+static int cyclades_get_proc_info(char *, char **, off_t, int, int *, void *);
 
 #ifndef CONFIG_CYZ_INTR
 static void cyz_poll(unsigned long);
@@ -855,41 +860,36 @@ static long cyz_polling_cycle = CZ_DEF_POLL;
 static int cyz_timeron = 0;
 static DEFINE_TIMER(cyz_timerlist, cyz_poll, 0, 0);
 
-#else /* CONFIG_CYZ_INTR */
+#else				/* CONFIG_CYZ_INTR */
 static void cyz_rx_restart(unsigned long);
 static struct timer_list cyz_rx_full_timer[NR_PORTS];
-#endif /* CONFIG_CYZ_INTR */
+#endif				/* CONFIG_CYZ_INTR */
 
-static inline int
-serial_paranoia_check(struct cyclades_port *info,
-                        char *name, const char *routine)
+static inline int serial_paranoia_check(struct cyclades_port *info,
+		char *name, const char *routine)
 {
 #ifdef SERIAL_PARANOIA_CHECK
-    static const char *badmagic =
-        "cyc Warning: bad magic number for serial struct (%s) in %s\n";
-    static const char *badinfo =
-        "cyc Warning: null cyclades_port for (%s) in %s\n";
-    static const char *badrange =
-        "cyc Warning: cyclades_port out of range for (%s) in %s\n";
-
-    if (!info) {
-        printk(badinfo, name, routine);
-        return 1;
-    }
-
-    if( (long)info < (long)(&cy_port[0])
-    || (long)(&cy_port[NR_PORTS]) < (long)info ){
-        printk(badrange, name, routine);
-        return 1;
-    }
-
-    if (info->magic != CYCLADES_MAGIC) {
-        printk(badmagic, name, routine);
-        return 1;
-    }
+	if (!info) {
+		printk("cyc Warning: null cyclades_port for (%s) in %s\n",
+				name, routine);
+		return 1;
+	}
+
+	if ((long)info < (long)(&cy_port[0]) ||
+			(long)(&cy_port[NR_PORTS]) < (long)info) {
+		printk("cyc Warning: cyclades_port out of range for (%s) in "
+				"%s\n", name, routine);
+		return 1;
+	}
+
+	if (info->magic != CYCLADES_MAGIC) {
+		printk("cyc Warning: bad magic number for serial struct (%s) "
+				"in %s\n", name, routine);
+		return 1;
+	}
 #endif
-        return 0;
-} /* serial_paranoia_check */
+	return 0;
+}				/* serial_paranoia_check */
 
 /*
  * This routine is used by the interrupt handler to schedule
@@ -897,13 +897,11 @@ serial_paranoia_check(struct cyclades_port *info,
  * (also known as the "bottom half").  This can be called any
  * number of times for any channel without harm.
  */
-static inline void
-cy_sched_event(struct cyclades_port *info, int event)
+static inline void cy_sched_event(struct cyclades_port *info, int event)
 {
-    info->event |= 1 << event; /* remember what kind of event and who */
-    schedule_work(&info->tqueue);
-} /* cy_sched_event */
-
+	info->event |= 1 << event; /* remember what kind of event and who */
+	schedule_work(&info->tqueue);
+}				/* cy_sched_event */
 
 /*
  * This routine is used to handle the "bottom half" processing for the
@@ -930,41 +928,36 @@ do_softint(struct work_struct *work)
 {
 	struct cyclades_port *info =
 		container_of(work, struct cyclades_port, tqueue);
-  struct tty_struct    *tty;
-
-    tty = info->tty;
-    if (!tty)
-        return;
-
-    if (test_and_clear_bit(Cy_EVENT_HANGUP, &info->event)) {
-        tty_hangup(info->tty);
-        wake_up_interruptible(&info->open_wait);
-        info->flags &= ~ASYNC_NORMAL_ACTIVE;
-    }
-    if (test_and_clear_bit(Cy_EVENT_OPEN_WAKEUP, &info->event)) {
-        wake_up_interruptible(&info->open_wait);
-    }
+	struct tty_struct    *tty;
+
+	tty = info->tty;
+	if (!tty)
+		return;
+
+	if (test_and_clear_bit(Cy_EVENT_HANGUP, &info->event)) {
+		tty_hangup(info->tty);
+		wake_up_interruptible(&info->open_wait);
+		        info->flags &= ~ASYNC_NORMAL_ACTIVE;
+	}
+	if (test_and_clear_bit(Cy_EVENT_OPEN_WAKEUP, &info->event))
+		wake_up_interruptible(&info->open_wait);
 #ifdef CONFIG_CYZ_INTR
-    if (test_and_clear_bit(Cy_EVENT_Z_RX_FULL, &info->event)) {
-	if (cyz_rx_full_timer[info->line].function == NULL) {
-	    cyz_rx_full_timer[info->line].expires = jiffies + 1;
-	    cyz_rx_full_timer[info->line].function = cyz_rx_restart;
-	    cyz_rx_full_timer[info->line].data = (unsigned long)info;
-	    add_timer(&cyz_rx_full_timer[info->line]);
+	if (test_and_clear_bit(Cy_EVENT_Z_RX_FULL, &info->event)) {
+		if (cyz_rx_full_timer[info->line].function == NULL) {
+			cyz_rx_full_timer[info->line].expires = jiffies + 1;
+			cyz_rx_full_timer[info->line].function = cyz_rx_restart;
+			cyz_rx_full_timer[info->line].data =
+						(unsigned long)info;
+			add_timer(&cyz_rx_full_timer[info->line]);
+		}
 	}
-    }
 #endif
-    if (test_and_clear_bit(Cy_EVENT_DELTA_WAKEUP, &info->event)) {
-	wake_up_interruptible(&info->delta_msr_wait);
-    }
-    if (test_and_clear_bit(Cy_EVENT_WRITE_WAKEUP, &info->event)) {
-        tty_wakeup(tty);
-        wake_up_interruptible(&tty->write_wait);
-    }
+	if (test_and_clear_bit(Cy_EVENT_DELTA_WAKEUP, &info->event))
+		wake_up_interruptible(&info->delta_msr_wait);
+	tty_wakeup(tty);
 #ifdef Z_WAKE
-    if (test_and_clear_bit(Cy_EVENT_SHUTDOWN_WAKEUP, &info->event)) {
-        wake_up_interruptible(&info->shutdown_wait);
-    }
+	if (test_and_clear_bit(Cy_EVENT_SHUTDOWN_WAKEUP, &info->event))
+		wake_up_interruptible(&info->shutdown_wait);
 #endif
 } /* do_softint */
 
@@ -979,341 +972,339 @@ do_softint(struct work_struct *work)
 
    This function is only called from inside spinlock-protected code.
  */
-static int
-cyy_issue_cmd(void __iomem *base_addr, u_char cmd, int index)
+static int cyy_issue_cmd(void __iomem * base_addr, u_char cmd, int index)
 {
-  volatile int  i;
+	volatile int i;
 
-    /* Check to see that the previous command has completed */
-    for(i = 0 ; i < 100 ; i++){
-	if (cy_readb(base_addr+(CyCCR<<index)) == 0){
-	    break;
+	/* Check to see that the previous command has completed */
+	for (i = 0; i < 100; i++) {
+		if (cy_readb(base_addr + (CyCCR << index)) == 0) {
+			break;
+		}
+		udelay(10L);
 	}
-	udelay(10L);
-    }
-    /* if the CCR never cleared, the previous command
-       didn't finish within the "reasonable time" */
-    if (i == 100)	return (-1);
+	/* if the CCR never cleared, the previous command
+	   didn't finish within the "reasonable time" */
+	if (i == 100)
+		return -1;
 
-    /* Issue the new command */
-    cy_writeb(base_addr+(CyCCR<<index), cmd);
+	/* Issue the new command */
+	cy_writeb(base_addr + (CyCCR << index), cmd);
 
-    return(0);
-} /* cyy_issue_cmd */
+	return 0;
+}				/* cyy_issue_cmd */
 
 #ifdef CONFIG_ISA
 /* ISA interrupt detection code */
-static unsigned 
-detect_isa_irq(void __iomem *address)
+static unsigned detect_isa_irq(void __iomem * address)
 {
-  int irq;
-  unsigned long irqs, flags;
-  int save_xir, save_car;
-  int index = 0; /* IRQ probing is only for ISA */
-
-    /* forget possible initially masked and pending IRQ */
-    irq = probe_irq_off(probe_irq_on());
-
-    /* Clear interrupts on the board first */
-    cy_writeb(address + (Cy_ClrIntr<<index), 0);
-			      /* Cy_ClrIntr is 0x1800 */
-
-    irqs = probe_irq_on();
-    /* Wait ... */
-    udelay(5000L);
-
-    /* Enable the Tx interrupts on the CD1400 */
-    local_irq_save(flags);
-	cy_writeb(address + (CyCAR<<index), 0);
-	cyy_issue_cmd(address, CyCHAN_CTL|CyENB_XMTR, index);
-
-	cy_writeb(address + (CyCAR<<index), 0);
-	cy_writeb(address + (CySRER<<index), 
-		cy_readb(address + (CySRER<<index)) | CyTxRdy);
-    local_irq_restore(flags);
-
-    /* Wait ... */
-    udelay(5000L);
-
-    /* Check which interrupt is in use */
-    irq = probe_irq_off(irqs);
-
-    /* Clean up */
-    save_xir = (u_char) cy_readb(address + (CyTIR<<index));
-    save_car = cy_readb(address + (CyCAR<<index));
-    cy_writeb(address + (CyCAR<<index), (save_xir & 0x3));
-    cy_writeb(address + (CySRER<<index),
-	cy_readb(address + (CySRER<<index)) & ~CyTxRdy);
-    cy_writeb(address + (CyTIR<<index), (save_xir & 0x3f));
-    cy_writeb(address + (CyCAR<<index), (save_car));
-    cy_writeb(address + (Cy_ClrIntr<<index), 0);
-			      /* Cy_ClrIntr is 0x1800 */
-
-    return (irq > 0)? irq : 0;
+	int irq;
+	unsigned long irqs, flags;
+	int save_xir, save_car;
+	int index = 0;		/* IRQ probing is only for ISA */
+
+	/* forget possible initially masked and pending IRQ */
+	irq = probe_irq_off(probe_irq_on());
+
+	/* Clear interrupts on the board first */
+	cy_writeb(address + (Cy_ClrIntr << index), 0);
+	/* Cy_ClrIntr is 0x1800 */
+
+	irqs = probe_irq_on();
+	/* Wait ... */
+	udelay(5000L);
+
+	/* Enable the Tx interrupts on the CD1400 */
+	local_irq_save(flags);
+	cy_writeb(address + (CyCAR << index), 0);
+	cyy_issue_cmd(address, CyCHAN_CTL | CyENB_XMTR, index);
+
+	cy_writeb(address + (CyCAR << index), 0);
+	cy_writeb(address + (CySRER << index),
+		  cy_readb(address + (CySRER << index)) | CyTxRdy);
+	local_irq_restore(flags);
+
+	/* Wait ... */
+	udelay(5000L);
+
+	/* Check which interrupt is in use */
+	irq = probe_irq_off(irqs);
+
+	/* Clean up */
+	save_xir = (u_char) cy_readb(address + (CyTIR << index));
+	save_car = cy_readb(address + (CyCAR << index));
+	cy_writeb(address + (CyCAR << index), (save_xir & 0x3));
+	cy_writeb(address + (CySRER << index),
+		  cy_readb(address + (CySRER << index)) & ~CyTxRdy);
+	cy_writeb(address + (CyTIR << index), (save_xir & 0x3f));
+	cy_writeb(address + (CyCAR << index), (save_car));
+	cy_writeb(address + (Cy_ClrIntr << index), 0);
+	/* Cy_ClrIntr is 0x1800 */
+
+	return (irq > 0) ? irq : 0;
 }
-#endif /* CONFIG_ISA */
+#endif				/* CONFIG_ISA */
 
-/* The real interrupt service routine is called
-   whenever the card wants its hand held--chars
-   received, out buffer empty, modem change, etc.
- */
-static irqreturn_t
-cyy_interrupt(int irq, void *dev_id)
+static void cyy_intr_chip(struct cyclades_card *cinfo, int chip,
+			void __iomem * base_addr, int status, int index)
 {
-  struct tty_struct *tty;
-  int status;
-  struct cyclades_card *cinfo;
-  struct cyclades_port *info;
-  void __iomem *base_addr, *card_base_addr;
-  int chip;
-  int save_xir, channel, save_car;
-  char data;
-  volatile int char_count;
-  int outch;
-  int i,j,index;
-  int too_many;
-  int had_work;
-  int mdm_change;
-  int mdm_status;
-  int len;
-    if((cinfo = (struct cyclades_card *)dev_id) == 0){
-#ifdef CY_DEBUG_INTERRUPTS
-	printk("cyy_interrupt: spurious interrupt %d\n\r", irq);
-#endif
-        return IRQ_NONE; /* spurious interrupt */
-    }
-
-    card_base_addr = cinfo->base_addr;
-    index = cinfo->bus_index;
-
-
-    /* This loop checks all chips in the card.  Make a note whenever
-       _any_ chip had some work to do, as this is considered an
-       indication that there will be more to do.  Only when no chip
-       has any work does this outermost loop exit.
-     */
-    do{
-        had_work = 0;
-        for ( chip = 0 ; chip < cinfo->num_chips ; chip ++) {
-            base_addr = cinfo->base_addr + (cy_chip_offset[chip]<<index);
-            too_many = 0;
-            while ( (status = cy_readb(base_addr+(CySVRR<<index))) != 0x00) {
-                had_work++;
-                /* The purpose of the following test is to ensure that
-                   no chip can monopolize the driver.  This forces the
-                   chips to be checked in a round-robin fashion (after
-                   draining each of a bunch (1000) of characters).
-                 */
-                if(1000<too_many++){
-                    break;
-                }
-                if (status & CySRReceive) { /* reception interrupt */
+	struct cyclades_port *info;
+	struct tty_struct *tty;
+	volatile int char_count;
+	int i, j, len, mdm_change, mdm_status, outch;
+	int save_xir, channel, save_car;
+	char data;
+
+	if (status & CySRReceive) {	/* reception interrupt */
 #ifdef CY_DEBUG_INTERRUPTS
-		    printk("cyy_interrupt: rcvd intr, chip %d\n\r", chip);
+		printk("cyy_interrupt: rcvd intr, chip %d\n\r", chip);
 #endif
-                    /* determine the channel & change to that context */
-		    spin_lock(&cinfo->card_lock);
-                    save_xir = (u_char) cy_readb(base_addr+(CyRIR<<index));
-                    channel = (u_short ) (save_xir & CyIRChannel);
-                    i = channel + chip * 4 + cinfo->first_line;
-                    info = &cy_port[i];
-                    info->last_active = jiffies;
-                    save_car = cy_readb(base_addr+(CyCAR<<index));
-                    cy_writeb(base_addr+(CyCAR<<index), save_xir);
-
-                    /* if there is nowhere to put the data, discard it */
-                    if(info->tty == 0){
-                        j = (cy_readb(base_addr+(CyRIVR<<index)) & CyIVRMask);
-                        if ( j == CyIVRRxEx ) { /* exception */
-                            data = cy_readb(base_addr+(CyRDSR<<index));
-                        } else { /* normal character reception */
-                            char_count = cy_readb(base_addr+(CyRDCR<<index));
-                            while(char_count--){
-                                data = cy_readb(base_addr+(CyRDSR<<index));
-                            }
-                        }
-                    }else{ /* there is an open port for this data */
-                        tty = info->tty;
-                        j = (cy_readb(base_addr+(CyRIVR<<index)) & CyIVRMask);
-                        if ( j == CyIVRRxEx ) { /* exception */
-                            data = cy_readb(base_addr+(CyRDSR<<index));
-
-			    /* For statistics only */
-			    if (data & CyBREAK)
-				info->icount.brk++;
-			    else if(data & CyFRAME)
-				info->icount.frame++;
-			    else if(data & CyPARITY)
-				info->icount.parity++;
-			    else if(data & CyOVERRUN)
-				info->icount.overrun++;
-
-                            if(data & info->ignore_status_mask){
-				info->icount.rx++;
-                                continue;
-                            }
-                            if (tty_buffer_request_room(tty, 1)) {
-                                if (data & info->read_status_mask){
-                                    if(data & CyBREAK){
-                                        tty_insert_flip_char(tty, cy_readb(base_addr+(CyRDSR<<index)), TTY_BREAK);
-					info->icount.rx++;
-                                        if (info->flags & ASYNC_SAK){
-                                            do_SAK(tty);
-                                        }
-                                    }else if(data & CyFRAME){
-                                        tty_insert_flip_char(tty, cy_readb(base_addr+(CyRDSR<<index)), TTY_FRAME);
-					info->icount.rx++;
-					info->idle_stats.frame_errs++;
-                                    }else if(data & CyPARITY){
-					/* Pieces of seven... */
-                                        tty_insert_flip_char(tty, cy_readb(base_addr+(CyRDSR<<index)), TTY_PARITY);
-					info->icount.rx++;
-					info->idle_stats.parity_errs++;
-                                    }else if(data & CyOVERRUN){
-                                        tty_insert_flip_char(tty, 0, TTY_OVERRUN);
+		/* determine the channel & change to that context */
+		spin_lock(&cinfo->card_lock);
+		save_xir = (u_char) cy_readb(base_addr + (CyRIR << index));
+		channel = (u_short) (save_xir & CyIRChannel);
+		i = channel + chip * 4 + cinfo->first_line;
+		info = &cy_port[i];
+		info->last_active = jiffies;
+		save_car = cy_readb(base_addr + (CyCAR << index));
+		cy_writeb(base_addr + (CyCAR << index), save_xir);
+
+		/* if there is nowhere to put the data, discard it */
+		if (info->tty == 0) {
+			j = (cy_readb(base_addr + (CyRIVR << index)) &
+				CyIVRMask);
+			if (j == CyIVRRxEx) {	/* exception */
+				data = cy_readb(base_addr + (CyRDSR << index));
+			} else {	/* normal character reception */
+				char_count = cy_readb(base_addr +
+						(CyRDCR << index));
+				while (char_count--) {
+					data = cy_readb(base_addr +
+						(CyRDSR << index));
+				}
+			}
+		} else {	/* there is an open port for this data */
+			tty = info->tty;
+			j = (cy_readb(base_addr + (CyRIVR << index)) &
+					CyIVRMask);
+			if (j == CyIVRRxEx) {	/* exception */
+				data = cy_readb(base_addr + (CyRDSR << index));
+
+				/* For statistics only */
+				if (data & CyBREAK)
+					info->icount.brk++;
+				else if (data & CyFRAME)
+					info->icount.frame++;
+				else if (data & CyPARITY)
+					info->icount.parity++;
+				else if (data & CyOVERRUN)
+					info->icount.overrun++;
+
+				if (data & info->ignore_status_mask) {
 					info->icount.rx++;
-                                        /* If the flip buffer itself is
-                                           overflowing, we still lose
-                                           the next incoming character.
-                                         */
-                                        tty_insert_flip_char(tty, cy_readb(base_addr+(CyRDSR<<index)), TTY_FRAME);
-				        info->icount.rx++;
+					return;
+				}
+				if (tty_buffer_request_room(tty, 1)) {
+					if (data & info->read_status_mask) {
+						if (data & CyBREAK) {
+							tty_insert_flip_char(
+								tty,
+								cy_readb(
+								base_addr +
+								(CyRDSR <<
+									index)),
+								TTY_BREAK);
+							info->icount.rx++;
+							if (info->flags &
+							    ASYNC_SAK) {
+								do_SAK(tty);
+							}
+						} else if (data & CyFRAME) {
+							tty_insert_flip_char(
+								tty,
+								cy_readb(
+								base_addr +
+								(CyRDSR <<
+									index)),
+								TTY_FRAME);
+							info->icount.rx++;
+							info->idle_stats.
+								frame_errs++;
+						} else if (data & CyPARITY) {
+							/* Pieces of seven... */
+							tty_insert_flip_char(
+								tty,
+								cy_readb(
+								base_addr +
+								(CyRDSR <<
+									index)),
+								TTY_PARITY);
+							info->icount.rx++;
+							info->idle_stats.
+								parity_errs++;
+						} else if (data & CyOVERRUN) {
+							tty_insert_flip_char(
+								tty, 0,
+								TTY_OVERRUN);
+							info->icount.rx++;
+						/* If the flip buffer itself is
+						   overflowing, we still lose
+						   the next incoming character.
+						 */
+							tty_insert_flip_char(
+								tty,
+								cy_readb(
+								base_addr +
+								(CyRDSR <<
+									index)),
+								TTY_FRAME);
+							info->icount.rx++;
+							info->idle_stats.
+								overruns++;
+					/* These two conditions may imply */
+					/* a normal read should be done. */
+					/* }else if(data & CyTIMEOUT){ */
+					/* }else if(data & CySPECHAR){ */
+						} else {
+							tty_insert_flip_char(
+								tty, 0,
+								TTY_NORMAL);
+							info->icount.rx++;
+						}
+					} else {
+						tty_insert_flip_char(tty, 0,
+								TTY_NORMAL);
+						info->icount.rx++;
+					}
+				} else {
+					/* there was a software buffer
+					   overrun and nothing could be
+					   done about it!!! */
+					info->icount.buf_overrun++;
 					info->idle_stats.overruns++;
-                                    /* These two conditions may imply */
-                                    /* a normal read should be done. */
-                                    /* }else if(data & CyTIMEOUT){ */
-                                    /* }else if(data & CySPECHAR){ */
-                                    }else {
-					tty_insert_flip_char(tty, 0, TTY_NORMAL);
-				        info->icount.rx++;
-                                    }
-                                }else{
-				    tty_insert_flip_char(tty, 0, TTY_NORMAL);
-				    info->icount.rx++;
-                                }
-                            }else{
-                                /* there was a software buffer
-				   overrun and nothing could be
-				   done about it!!! */
-				info->icount.buf_overrun++;
-				info->idle_stats.overruns++;
-                            }
-                        } else { /* normal character reception */
-                            /* load # chars available from the chip */
-                            char_count = cy_readb(base_addr+(CyRDCR<<index));
+				}
+			} else {	/* normal character reception */
+				/* load # chars available from the chip */
+				char_count = cy_readb(base_addr +
+						(CyRDCR << index));
 
 #ifdef CY_ENABLE_MONITORING
-                            ++info->mon.int_count;
-                            info->mon.char_count += char_count;
-                            if (char_count > info->mon.char_max)
-                               info->mon.char_max = char_count;
-                            info->mon.char_last = char_count;
+				++info->mon.int_count;
+				info->mon.char_count += char_count;
+				if (char_count > info->mon.char_max)
+					info->mon.char_max = char_count;
+				info->mon.char_last = char_count;
 #endif
-			    len = tty_buffer_request_room(tty, char_count);
-                            while(len--){
-                                data = cy_readb(base_addr+(CyRDSR<<index));
-				tty_insert_flip_char(tty, data, TTY_NORMAL);
-				info->idle_stats.recv_bytes++;
-				info->icount.rx++;
+				len = tty_buffer_request_room(tty, char_count);
+				while (len--) {
+					data = cy_readb(base_addr +
+							(CyRDSR << index));
+					tty_insert_flip_char(tty, data,
+							TTY_NORMAL);
+					info->idle_stats.recv_bytes++;
+					info->icount.rx++;
 #ifdef CY_16Y_HACK
-                                udelay(10L);
+					udelay(10L);
 #endif
-                            }
-                             info->idle_stats.recv_idle = jiffies;
-                        }
+				}
+				info->idle_stats.recv_idle = jiffies;
+			}
 			tty_schedule_flip(tty);
-                    }
-                    /* end of service */
-                    cy_writeb(base_addr+(CyRIR<<index), (save_xir & 0x3f));
-                    cy_writeb(base_addr+(CyCAR<<index), (save_car));
-		    spin_unlock(&cinfo->card_lock);
-                }
-
-
-                if (status & CySRTransmit) { /* transmission interrupt */
-                    /* Since we only get here when the transmit buffer
-                       is empty, we know we can always stuff a dozen
-                       characters. */
+		}
+		/* end of service */
+		cy_writeb(base_addr + (CyRIR << index), (save_xir & 0x3f));
+		cy_writeb(base_addr + (CyCAR << index), (save_car));
+		spin_unlock(&cinfo->card_lock);
+	}
+
+	if (status & CySRTransmit) {	/* transmission interrupt */
+		/* Since we only get here when the transmit buffer
+		   is empty, we know we can always stuff a dozen
+		   characters. */
 #ifdef CY_DEBUG_INTERRUPTS
-		    printk("cyy_interrupt: xmit intr, chip %d\n\r", chip);
+		printk("cyy_interrupt: xmit intr, chip %d\n\r", chip);
 #endif
 
-                    /* determine the channel & change to that context */
-		    spin_lock(&cinfo->card_lock);
-                    save_xir = (u_char) cy_readb(base_addr+(CyTIR<<index));
-                    channel = (u_short ) (save_xir & CyIRChannel);
-                    i = channel + chip * 4 + cinfo->first_line;
-                    save_car = cy_readb(base_addr+(CyCAR<<index));
-                    cy_writeb(base_addr+(CyCAR<<index), save_xir);
-
-                    /* validate the port# (as configured and open) */
-                    if( (i < 0) || (NR_PORTS <= i) ){
-                        cy_writeb(base_addr+(CySRER<<index),
-                             cy_readb(base_addr+(CySRER<<index)) & ~CyTxRdy);
-                        goto txend;
-                    }
-                    info = &cy_port[i];
-                    info->last_active = jiffies;
-                    if(info->tty == 0){
-                        cy_writeb(base_addr+(CySRER<<index),
-                             cy_readb(base_addr+(CySRER<<index)) & ~CyTxRdy);
-                        goto txdone;
-                    }
-
-                    /* load the on-chip space for outbound data */
-                    char_count = info->xmit_fifo_size;
-
-                    if(info->x_char) { /* send special char */
-                        outch = info->x_char;
-                        cy_writeb(base_addr+(CyTDR<<index), outch);
-                        char_count--;
+		/* determine the channel & change to that context */
+		spin_lock(&cinfo->card_lock);
+		save_xir = (u_char) cy_readb(base_addr + (CyTIR << index));
+		channel = (u_short) (save_xir & CyIRChannel);
+		i = channel + chip * 4 + cinfo->first_line;
+		save_car = cy_readb(base_addr + (CyCAR << index));
+		cy_writeb(base_addr + (CyCAR << index), save_xir);
+
+		/* validate the port# (as configured and open) */
+		if ((i < 0) || (NR_PORTS <= i)) {
+			cy_writeb(base_addr + (CySRER << index),
+				  cy_readb(base_addr + (CySRER << index)) &
+				  ~CyTxRdy);
+			goto txend;
+		}
+		info = &cy_port[i];
+		info->last_active = jiffies;
+		if (info->tty == 0) {
+			cy_writeb(base_addr + (CySRER << index),
+				  cy_readb(base_addr + (CySRER << index)) &
+				  ~CyTxRdy);
+			goto txdone;
+		}
+
+		/* load the on-chip space for outbound data */
+		char_count = info->xmit_fifo_size;
+
+		if (info->x_char) {	/* send special char */
+			outch = info->x_char;
+			cy_writeb(base_addr + (CyTDR << index), outch);
+			char_count--;
 			info->icount.tx++;
-                        info->x_char = 0;
-                    }
+			info->x_char = 0;
+		}
 
-                    if (info->breakon || info->breakoff) {
+		if (info->breakon || info->breakoff) {
 			if (info->breakon) {
-			    cy_writeb(base_addr + (CyTDR<<index), 0); 
-			    cy_writeb(base_addr + (CyTDR<<index), 0x81);
-			    info->breakon = 0;
-                            char_count -= 2;
+				cy_writeb(base_addr + (CyTDR << index), 0);
+				cy_writeb(base_addr + (CyTDR << index), 0x81);
+				info->breakon = 0;
+				char_count -= 2;
 			}
 			if (info->breakoff) {
-			    cy_writeb(base_addr + (CyTDR<<index), 0); 
-			    cy_writeb(base_addr + (CyTDR<<index), 0x83);
-			    info->breakoff = 0;
-                            char_count -= 2;
+				cy_writeb(base_addr + (CyTDR << index), 0);
+				cy_writeb(base_addr + (CyTDR << index), 0x83);
+				info->breakoff = 0;
+				char_count -= 2;
 			}
-                    }
-
-                    while (char_count-- > 0){
-			if (!info->xmit_cnt){
-			    if (cy_readb(base_addr+(CySRER<<index))&CyTxMpty) {
-				cy_writeb(base_addr+(CySRER<<index),
-					  cy_readb(base_addr+(CySRER<<index)) &
-					  ~CyTxMpty);
-			    } else {
-				cy_writeb(base_addr+(CySRER<<index),
-					  ((cy_readb(base_addr+(CySRER<<index))
-					    & ~CyTxRdy)
-					   | CyTxMpty));
-			    }
-			    goto txdone;
+		}
+
+		while (char_count-- > 0) {
+			if (!info->xmit_cnt) {
+				if (cy_readb(base_addr + (CySRER << index)) &
+						CyTxMpty) {
+					cy_writeb(base_addr + (CySRER << index),
+						cy_readb(base_addr +
+							(CySRER << index)) &
+						~CyTxMpty);
+				} else {
+					cy_writeb(base_addr + (CySRER << index),
+						(cy_readb(base_addr +
+						  	(CySRER << index)) &
+						~CyTxRdy) | CyTxMpty);
+				}
+				goto txdone;
 			}
-			if (info->xmit_buf == 0){
-                            cy_writeb(base_addr+(CySRER<<index),
-				cy_readb(base_addr+(CySRER<<index)) & 
+			if (info->xmit_buf == 0) {
+				cy_writeb(base_addr + (CySRER << index),
+					cy_readb(base_addr + (CySRER << index))&
 					~CyTxRdy);
-                            goto txdone;
+				goto txdone;
 			}
-			if (info->tty->stopped || info->tty->hw_stopped){
-                            cy_writeb(base_addr+(CySRER<<index),
-				cy_readb(base_addr+(CySRER<<index)) & 
+			if (info->tty->stopped || info->tty->hw_stopped) {
+				cy_writeb(base_addr + (CySRER << index),
+					cy_readb(base_addr + (CySRER << index))&
 					~CyTxRdy);
-                            goto txdone;
+				goto txdone;
 			}
-                        /* Because the Embedded Transmit Commands have
-                           been enabled, we must check to see if the
+			/* Because the Embedded Transmit Commands have
+			   been enabled, we must check to see if the
 			   escape character, NULL, is being sent.  If it
 			   is, we must ensure that there is room for it
 			   to be doubled in the output stream.  Therefore
@@ -1322,125 +1313,182 @@ cyy_interrupt(int irq, void *dev_id)
 			   after the check for a NULL output character.
 			   This is necessary because there may not be
 			   room for the two chars needed to send a NULL.)
-                         */
-                        outch = info->xmit_buf[info->xmit_tail];
-                        if( outch ){
-                            info->xmit_cnt--;
-                            info->xmit_tail = (info->xmit_tail + 1)
-                                                      & (SERIAL_XMIT_SIZE - 1);
-                            cy_writeb(base_addr+(CyTDR<<index), outch);
-			    info->icount.tx++;
-                        }else{
-                            if(char_count > 1){
-                                info->xmit_cnt--;
-                                info->xmit_tail = (info->xmit_tail + 1)
-						      & (SERIAL_XMIT_SIZE - 1);
-                                cy_writeb(base_addr+(CyTDR<<index), 
-					  outch);
-                                cy_writeb(base_addr+(CyTDR<<index), 0);
+			 */
+			outch = info->xmit_buf[info->xmit_tail];
+			if (outch) {
+				info->xmit_cnt--;
+				info->xmit_tail = (info->xmit_tail + 1) &
+						(SERIAL_XMIT_SIZE - 1);
+				cy_writeb(base_addr + (CyTDR << index), outch);
 				info->icount.tx++;
-                                char_count--;
-                            }else{
-                            }
-                        }
-                    }
-
-        txdone:
-                    if (info->xmit_cnt < WAKEUP_CHARS) {
-                        cy_sched_event(info, Cy_EVENT_WRITE_WAKEUP);
-                    }
-        txend:
-                    /* end of service */
-                    cy_writeb(base_addr+(CyTIR<<index), 
-			      (save_xir & 0x3f));
-                    cy_writeb(base_addr+(CyCAR<<index), (save_car));
-		    spin_unlock(&cinfo->card_lock);
-                }
-
-                if (status & CySRModem) {        /* modem interrupt */
-
-                    /* determine the channel & change to that context */
-		    spin_lock(&cinfo->card_lock);
-                    save_xir = (u_char) cy_readb(base_addr+(CyMIR<<index));
-                    channel = (u_short ) (save_xir & CyIRChannel);
-                    info = &cy_port[channel + chip * 4
-		                           + cinfo->first_line];
-                    info->last_active = jiffies;
-                    save_car = cy_readb(base_addr+(CyCAR<<index));
-                    cy_writeb(base_addr+(CyCAR<<index), save_xir);
-
-                    mdm_change = cy_readb(base_addr+(CyMISR<<index));
-                    mdm_status = cy_readb(base_addr+(CyMSVR1<<index));
-
-                    if(info->tty == 0){/* no place for data, ignore it*/
-                        ;
-                    }else{
+			} else {
+				if (char_count > 1) {
+					info->xmit_cnt--;
+					info->xmit_tail = (info->xmit_tail + 1)&
+						(SERIAL_XMIT_SIZE - 1);
+					cy_writeb(base_addr + (CyTDR << index),
+						outch);
+					cy_writeb(base_addr + (CyTDR << index),
+						0);
+					info->icount.tx++;
+					char_count--;
+				} else {
+				}
+			}
+		}
+
+txdone:
+		if (info->xmit_cnt < WAKEUP_CHARS) {
+			cy_sched_event(info, Cy_EVENT_WRITE_WAKEUP);
+		}
+txend:
+		/* end of service */
+		cy_writeb(base_addr + (CyTIR << index), (save_xir & 0x3f));
+		cy_writeb(base_addr + (CyCAR << index), (save_car));
+		spin_unlock(&cinfo->card_lock);
+	}
+
+	if (status & CySRModem) {	/* modem interrupt */
+
+		/* determine the channel & change to that context */
+		spin_lock(&cinfo->card_lock);
+		save_xir = (u_char) cy_readb(base_addr + (CyMIR << index));
+		channel = (u_short) (save_xir & CyIRChannel);
+		info = &cy_port[channel + chip * 4 + cinfo->first_line];
+		info->last_active = jiffies;
+		save_car = cy_readb(base_addr + (CyCAR << index));
+		cy_writeb(base_addr + (CyCAR << index), save_xir);
+
+		mdm_change = cy_readb(base_addr + (CyMISR << index));
+		mdm_status = cy_readb(base_addr + (CyMSVR1 << index));
+
+		if (info->tty == 0) {	/* no place for data, ignore it */
+			;
+		} else {
 			if (mdm_change & CyANY_DELTA) {
-			    /* For statistics only */
-			    if (mdm_change & CyDCD)	info->icount.dcd++;
-			    if (mdm_change & CyCTS)	info->icount.cts++;
-			    if (mdm_change & CyDSR)	info->icount.dsr++;
-			    if (mdm_change & CyRI)	info->icount.rng++;
+				/* For statistics only */
+				if (mdm_change & CyDCD)
+					info->icount.dcd++;
+				if (mdm_change & CyCTS)
+					info->icount.cts++;
+				if (mdm_change & CyDSR)
+					info->icount.dsr++;
+				if (mdm_change & CyRI)
+					info->icount.rng++;
+
+				cy_sched_event(info, Cy_EVENT_DELTA_WAKEUP);
+			}
+
+			if ((mdm_change & CyDCD) &&
+					(info->flags & ASYNC_CHECK_CD)) {
+				if (mdm_status & CyDCD) {
+					cy_sched_event(info,
+							Cy_EVENT_OPEN_WAKEUP);
+				} else {
+					cy_sched_event(info, Cy_EVENT_HANGUP);
+				}
+			}
+			if ((mdm_change & CyCTS) &&
+					(info->flags & ASYNC_CTS_FLOW)) {
+				if (info->tty->hw_stopped) {
+					if (mdm_status & CyCTS) {
+						/* cy_start isn't used
+						   because... !!! */
+						info->tty->hw_stopped = 0;
+						cy_writeb(base_addr +
+							(CySRER << index),
+							cy_readb(base_addr +
+								(CySRER <<
+									index))|
+							CyTxRdy);
+						cy_sched_event(info,
+							Cy_EVENT_WRITE_WAKEUP);
+					}
+				} else {
+					if (!(mdm_status & CyCTS)) {
+						/* cy_stop isn't used
+						   because ... !!! */
+						info->tty->hw_stopped = 1;
+						cy_writeb(base_addr +
+							(CySRER << index),
+							cy_readb(base_addr +
+								(CySRER <<
+								index)) &
+							~CyTxRdy);
+					}
+				}
+			}
+			if (mdm_change & CyDSR) {
+			}
+			if (mdm_change & CyRI) {
+			}
+		}
+		/* end of service */
+		cy_writeb(base_addr + (CyMIR << index), (save_xir & 0x3f));
+		cy_writeb(base_addr + (CyCAR << index), save_car);
+		spin_unlock(&cinfo->card_lock);
+	}
+}
+
+/* The real interrupt service routine is called
+   whenever the card wants its hand held--chars
+   received, out buffer empty, modem change, etc.
+ */
+static irqreturn_t cyy_interrupt(int irq, void *dev_id)
+{
+	int status;
+	struct cyclades_card *cinfo;
+	void __iomem *base_addr, *card_base_addr;
+	int chip;
+	int index;
+	int too_many;
+	int had_work;
+
+	if ((cinfo = (struct cyclades_card *)dev_id) == 0) {
+#ifdef CY_DEBUG_INTERRUPTS
+		printk("cyy_interrupt: spurious interrupt %d\n\r", irq);
+#endif
+		return IRQ_NONE;	/* spurious interrupt */
+	}
+
+	card_base_addr = cinfo->base_addr;
+	index = cinfo->bus_index;
 
-			    cy_sched_event(info, Cy_EVENT_DELTA_WAKEUP);
+	/* This loop checks all chips in the card.  Make a note whenever
+	   _any_ chip had some work to do, as this is considered an
+	   indication that there will be more to do.  Only when no chip
+	   has any work does this outermost loop exit.
+	 */
+	do {
+		had_work = 0;
+		for (chip = 0; chip < cinfo->num_chips; chip++) {
+			base_addr = cinfo->base_addr +
+					(cy_chip_offset[chip] << index);
+			too_many = 0;
+			while ((status = cy_readb(base_addr +
+						(CySVRR << index))) != 0x00) {
+				had_work++;
+			/* The purpose of the following test is to ensure that
+			   no chip can monopolize the driver.  This forces the
+			   chips to be checked in a round-robin fashion (after
+			   draining each of a bunch (1000) of characters).
+			 */
+				if (1000 < too_many++) {
+					break;
+				}
+				cyy_intr_chip(cinfo, chip, base_addr, status,
+						index);
 			}
+		}
+	} while (had_work);
 
-                        if((mdm_change & CyDCD)
-                        && (info->flags & ASYNC_CHECK_CD)){
-                            if(mdm_status & CyDCD){
-                                cy_sched_event(info,
-				    Cy_EVENT_OPEN_WAKEUP);
-                            }else{
-                                cy_sched_event(info,
-				    Cy_EVENT_HANGUP);
-                            }
-                        }
-                        if((mdm_change & CyCTS)
-                        && (info->flags & ASYNC_CTS_FLOW)){
-                            if(info->tty->hw_stopped){
-                                if(mdm_status & CyCTS){
-                                    /* cy_start isn't used
-				         because... !!! */
-                                    info->tty->hw_stopped = 0;
-                                  cy_writeb(base_addr+(CySRER<<index),
-                                       cy_readb(base_addr+(CySRER<<index)) | 
-                                       CyTxRdy);
-                                    cy_sched_event(info,
-				        Cy_EVENT_WRITE_WAKEUP);
-                                }
-                            }else{
-                                if(!(mdm_status & CyCTS)){
-                                    /* cy_stop isn't used
-				         because ... !!! */
-                                    info->tty->hw_stopped = 1;
-                                  cy_writeb(base_addr+(CySRER<<index),
-                                       cy_readb(base_addr+(CySRER<<index)) & 
-                                       ~CyTxRdy);
-                                }
-                            }
-                        }
-                        if(mdm_change & CyDSR){
-                        }
-                        if(mdm_change & CyRI){
-                        }
-                    }
-                    /* end of service */
-                    cy_writeb(base_addr+(CyMIR<<index), 
-			      (save_xir & 0x3f));
-                    cy_writeb(base_addr+(CyCAR<<index), save_car);
-		    spin_unlock(&cinfo->card_lock);
-                }
-            }          /* end while status != 0 */
-        }            /* end loop for chips... */
-    } while(had_work);
-
-   /* clear interrupts */
-   spin_lock(&cinfo->card_lock);
-   cy_writeb(card_base_addr + (Cy_ClrIntr<<index), 0);
-                                /* Cy_ClrIntr is 0x1800 */
-   spin_unlock(&cinfo->card_lock);
-   return IRQ_HANDLED;
-} /* cyy_interrupt */
+	/* clear interrupts */
+	spin_lock(&cinfo->card_lock);
+	cy_writeb(card_base_addr + (Cy_ClrIntr << index), 0);
+	/* Cy_ClrIntr is 0x1800 */
+	spin_unlock(&cinfo->card_lock);
+	return IRQ_HANDLED;
+}				/* cyy_interrupt */
 
 /***********************************************************/
 /********* End of block of Cyclom-Y specific code **********/
@@ -1448,643 +1496,655 @@ cyy_interrupt(int irq, void *dev_id)
 /***********************************************************/
 
 static int
-cyz_fetch_msg( struct cyclades_card *cinfo,
-	    uclong *channel, ucchar *cmd, uclong *param)
+cyz_fetch_msg(struct cyclades_card *cinfo,
+		uclong * channel, ucchar * cmd, uclong * param)
 {
-  struct FIRM_ID __iomem *firm_id;
-  struct ZFW_CTRL __iomem *zfw_ctrl;
-  struct BOARD_CTRL __iomem *board_ctrl;
-  unsigned long loc_doorbell;
-
-    firm_id = cinfo->base_addr + ID_ADDRESS;
-    if (!ISZLOADED(*cinfo)){
-	return (-1);
-    }
-    zfw_ctrl = cinfo->base_addr + (cy_readl(&firm_id->zfwctrl_addr) & 0xfffff);
-    board_ctrl = &zfw_ctrl->board_ctrl;
-
-    loc_doorbell = cy_readl(&((struct RUNTIME_9060 __iomem *)
-                     (cinfo->ctl_addr))->loc_doorbell);
-    if (loc_doorbell){
-	*cmd = (char)(0xff & loc_doorbell);
-	*channel = cy_readl(&board_ctrl->fwcmd_channel);
-	*param = (uclong)cy_readl(&board_ctrl->fwcmd_param);
-	cy_writel(&((struct RUNTIME_9060 __iomem *)(cinfo->ctl_addr))->loc_doorbell, 
-                 0xffffffff);
-	return 1;
-    }
-    return 0;
-} /* cyz_fetch_msg */
+	struct FIRM_ID __iomem *firm_id;
+	struct ZFW_CTRL __iomem *zfw_ctrl;
+	struct BOARD_CTRL __iomem *board_ctrl;
+	unsigned long loc_doorbell;
+
+	firm_id = cinfo->base_addr + ID_ADDRESS;
+	if (!ISZLOADED(*cinfo)) {
+		return -1;
+	}
+	zfw_ctrl = cinfo->base_addr + (cy_readl(&firm_id->zfwctrl_addr) &
+			0xfffff);
+	board_ctrl = &zfw_ctrl->board_ctrl;
+
+	loc_doorbell = cy_readl(&((struct RUNTIME_9060 __iomem *)
+				  (cinfo->ctl_addr))->loc_doorbell);
+	if (loc_doorbell) {
+		*cmd = (char)(0xff & loc_doorbell);
+		*channel = cy_readl(&board_ctrl->fwcmd_channel);
+		*param = (uclong) cy_readl(&board_ctrl->fwcmd_param);
+		cy_writel(&((struct RUNTIME_9060 __iomem *)(cinfo->ctl_addr))->
+			  loc_doorbell, 0xffffffff);
+		return 1;
+	}
+	return 0;
+}				/* cyz_fetch_msg */
 
 static int
-cyz_issue_cmd( struct cyclades_card *cinfo,
-	    uclong channel, ucchar cmd, uclong param)
+cyz_issue_cmd(struct cyclades_card *cinfo,
+		uclong channel, ucchar cmd, uclong param)
 {
-  struct FIRM_ID __iomem *firm_id;
-  struct ZFW_CTRL __iomem *zfw_ctrl;
-  struct BOARD_CTRL __iomem *board_ctrl;
-  unsigned long __iomem *pci_doorbell;
-  int index;
-
-    firm_id = cinfo->base_addr + ID_ADDRESS;
-    if (!ISZLOADED(*cinfo)){
-	return (-1);
-    }
-    zfw_ctrl = cinfo->base_addr + (cy_readl(&firm_id->zfwctrl_addr) & 0xfffff);
-    board_ctrl = &zfw_ctrl->board_ctrl;
-
-    index = 0;
-    pci_doorbell = &((struct RUNTIME_9060 __iomem *) (cinfo->ctl_addr))->pci_doorbell;
-    while( (cy_readl(pci_doorbell) & 0xff) != 0){
-        if (index++ == 1000){
-	    return((int)(cy_readl(pci_doorbell) & 0xff));
-        }
-	udelay(50L);
-    }
-    cy_writel(&board_ctrl->hcmd_channel, channel);
-    cy_writel(&board_ctrl->hcmd_param , param);
-    cy_writel(pci_doorbell, (long)cmd);
-
-    return(0);
-} /* cyz_issue_cmd */
+	struct FIRM_ID __iomem *firm_id;
+	struct ZFW_CTRL __iomem *zfw_ctrl;
+	struct BOARD_CTRL __iomem *board_ctrl;
+	unsigned long __iomem *pci_doorbell;
+	int index;
+
+	firm_id = cinfo->base_addr + ID_ADDRESS;
+	if (!ISZLOADED(*cinfo)) {
+		return -1;
+	}
+	zfw_ctrl = cinfo->base_addr + (cy_readl(&firm_id->zfwctrl_addr) &
+			0xfffff);
+	board_ctrl = &zfw_ctrl->board_ctrl;
+
+	index = 0;
+	pci_doorbell =
+	    &((struct RUNTIME_9060 __iomem *)(cinfo->ctl_addr))->pci_doorbell;
+	while ((cy_readl(pci_doorbell) & 0xff) != 0) {
+		if (index++ == 1000) {
+			return (int)(cy_readl(pci_doorbell) & 0xff);
+		}
+		udelay(50L);
+	}
+	cy_writel(&board_ctrl->hcmd_channel, channel);
+	cy_writel(&board_ctrl->hcmd_param, param);
+	cy_writel(pci_doorbell, (long)cmd);
+
+	return 0;
+}				/* cyz_issue_cmd */
 
 static void
 cyz_handle_rx(struct cyclades_port *info,
-	      volatile struct CH_CTRL __iomem *ch_ctrl,
-	      volatile struct BUF_CTRL __iomem *buf_ctrl)
+		volatile struct CH_CTRL __iomem * ch_ctrl,
+		volatile struct BUF_CTRL __iomem * buf_ctrl)
 {
-  struct cyclades_card *cinfo = &cy_card[info->card];
-  struct tty_struct *tty = info->tty;
-  volatile int char_count;
-  int len;
+	struct cyclades_card *cinfo = &cy_card[info->card];
+	struct tty_struct *tty = info->tty;
+	volatile int char_count;
+	int len;
 #ifdef BLOCKMOVE
-  int small_count;
+	int small_count;
 #else
-  char data;
+	char data;
 #endif
-  volatile uclong rx_put, rx_get, new_rx_get, rx_bufsize, rx_bufaddr;
+	volatile uclong rx_put, rx_get, new_rx_get, rx_bufsize, rx_bufaddr;
 
-    rx_get = new_rx_get = cy_readl(&buf_ctrl->rx_get);
-    rx_put = cy_readl(&buf_ctrl->rx_put);
-    rx_bufsize = cy_readl(&buf_ctrl->rx_bufsize);
-    rx_bufaddr = cy_readl(&buf_ctrl->rx_bufaddr);
-    if (rx_put >= rx_get)
-	char_count = rx_put - rx_get;
-    else
-	char_count = rx_put - rx_get + rx_bufsize;
+	rx_get = new_rx_get = cy_readl(&buf_ctrl->rx_get);
+	rx_put = cy_readl(&buf_ctrl->rx_put);
+	rx_bufsize = cy_readl(&buf_ctrl->rx_bufsize);
+	rx_bufaddr = cy_readl(&buf_ctrl->rx_bufaddr);
+	if (rx_put >= rx_get)
+		char_count = rx_put - rx_get;
+	else
+		char_count = rx_put - rx_get + rx_bufsize;
 
-    if ( char_count ) {
-	info->last_active = jiffies;
-	info->jiffies[1] = jiffies;
+	if (char_count) {
+		info->last_active = jiffies;
+		info->jiffies[1] = jiffies;
 
 #ifdef CY_ENABLE_MONITORING
-	info->mon.int_count++;
-	info->mon.char_count += char_count;
-	if (char_count > info->mon.char_max)
-	    info->mon.char_max = char_count;
-	info->mon.char_last = char_count;
+		info->mon.int_count++;
+		info->mon.char_count += char_count;
+		if (char_count > info->mon.char_max)
+			info->mon.char_max = char_count;
+		info->mon.char_last = char_count;
 #endif
-	if(tty == 0){
-	    /* flush received characters */
-	    new_rx_get = (new_rx_get + char_count) & (rx_bufsize - 1);
-	    info->rflush_count++;
-	}else{
+		if (tty == 0) {
+			/* flush received characters */
+			new_rx_get = (new_rx_get + char_count) &
+					(rx_bufsize - 1);
+			info->rflush_count++;
+		} else {
 #ifdef BLOCKMOVE
-	    /* we'd like to use memcpy(t, f, n) and memset(s, c, count)
-	       for performance, but because of buffer boundaries, there
-	       may be several steps to the operation */
-	    while(0 < (small_count = 
-		       min_t(unsigned int, (rx_bufsize - new_rx_get),
-		       min_t(unsigned int, (TTY_FLIPBUF_SIZE - tty->flip.count), char_count))
-		 )) {
-		memcpy_fromio(tty->flip.char_buf_ptr,
-			      (char *)(cinfo->base_addr
-				       + rx_bufaddr + new_rx_get),
-			      small_count);
-
-		tty->flip.char_buf_ptr += small_count;
-		memset(tty->flip.flag_buf_ptr, TTY_NORMAL, small_count);
-		tty->flip.flag_buf_ptr += small_count;
-		new_rx_get = (new_rx_get + small_count) & (rx_bufsize - 1);
-		char_count -= small_count;
-		info->icount.rx += small_count;
-		info->idle_stats.recv_bytes += small_count;
-		tty->flip.count += small_count;
-	    }
+		/* we'd like to use memcpy(t, f, n) and memset(s, c, count)
+		   for performance, but because of buffer boundaries, there
+		   may be several steps to the operation */
+			while (0 < (small_count = min_t(unsigned int,
+					rx_bufsize - new_rx_get,
+					min_t(unsigned int, TTY_FLIPBUF_SIZE -
+						tty->flip.count, char_count)))){
+				memcpy_fromio(tty->flip.char_buf_ptr,
+					(char *)(cinfo->base_addr + rx_bufaddr +
+						new_rx_get),
+					small_count);
+
+				tty->flip.char_buf_ptr += small_count;
+				memset(tty->flip.flag_buf_ptr, TTY_NORMAL,
+					small_count);
+				tty->flip.flag_buf_ptr += small_count;
+				new_rx_get = (new_rx_get + small_count) &
+						(rx_bufsize - 1);
+				char_count -= small_count;
+				info->icount.rx += small_count;
+				info->idle_stats.recv_bytes += small_count;
+				tty->flip.count += small_count;
+			}
 #else
-	    len = tty_buffer_request_room(tty, char_count);
-	    while(len--){
-		data = cy_readb(cinfo->base_addr + rx_bufaddr + new_rx_get);
-		new_rx_get = (new_rx_get + 1) & (rx_bufsize - 1);
-		tty_insert_flip_char(tty, data, TTY_NORMAL);
-		info->idle_stats.recv_bytes++;
-		info->icount.rx++;
-	    }
+			len = tty_buffer_request_room(tty, char_count);
+			while (len--) {
+				data = cy_readb(cinfo->base_addr + rx_bufaddr +
+						new_rx_get);
+				new_rx_get = (new_rx_get + 1)& (rx_bufsize - 1);
+				tty_insert_flip_char(tty, data, TTY_NORMAL);
+				info->idle_stats.recv_bytes++;
+				info->icount.rx++;
+			}
 #endif
 #ifdef CONFIG_CYZ_INTR
-	    /* Recalculate the number of chars in the RX buffer and issue
-	       a cmd in case it's higher than the RX high water mark */
-	    rx_put = cy_readl(&buf_ctrl->rx_put);
-	    if (rx_put >= rx_get)
-		char_count = rx_put - rx_get;
-	    else
-		char_count = rx_put - rx_get + rx_bufsize;
-	    if(char_count >= cy_readl(&buf_ctrl->rx_threshold)) {
-		cy_sched_event(info, Cy_EVENT_Z_RX_FULL);
-	    }
+		/* Recalculate the number of chars in the RX buffer and issue
+		   a cmd in case it's higher than the RX high water mark */
+			rx_put = cy_readl(&buf_ctrl->rx_put);
+			if (rx_put >= rx_get)
+				char_count = rx_put - rx_get;
+			else
+				char_count = rx_put - rx_get + rx_bufsize;
+			if (char_count >= (int)cy_readl(&buf_ctrl->
+					rx_threshold)) {
+				cy_sched_event(info, Cy_EVENT_Z_RX_FULL);
+			}
 #endif
-	    info->idle_stats.recv_idle = jiffies;
-	    tty_schedule_flip(tty);
+			info->idle_stats.recv_idle = jiffies;
+			tty_schedule_flip(tty);
+		}
+		/* Update rx_get */
+		cy_writel(&buf_ctrl->rx_get, new_rx_get);
 	}
-	/* Update rx_get */
-	cy_writel(&buf_ctrl->rx_get, new_rx_get);
-    }
 }
 
 static void
 cyz_handle_tx(struct cyclades_port *info,
-	      volatile struct CH_CTRL __iomem *ch_ctrl,
-	      volatile struct BUF_CTRL __iomem *buf_ctrl)
+		volatile struct CH_CTRL __iomem * ch_ctrl,
+		volatile struct BUF_CTRL __iomem * buf_ctrl)
 {
-  struct cyclades_card *cinfo = &cy_card[info->card];
-  struct tty_struct *tty = info->tty;
-  char data;
-  volatile int char_count;
+	struct cyclades_card *cinfo = &cy_card[info->card];
+	struct tty_struct *tty = info->tty;
+	char data;
+	volatile int char_count;
 #ifdef BLOCKMOVE
-  int small_count;
+	int small_count;
 #endif
-  volatile uclong tx_put, tx_get, tx_bufsize, tx_bufaddr;
+	volatile uclong tx_put, tx_get, tx_bufsize, tx_bufaddr;
 
-    if (info->xmit_cnt <= 0)	/* Nothing to transmit */
-	return;
+	if (info->xmit_cnt <= 0)	/* Nothing to transmit */
+		return;
 
-    tx_get = cy_readl(&buf_ctrl->tx_get);
-    tx_put = cy_readl(&buf_ctrl->tx_put);
-    tx_bufsize = cy_readl(&buf_ctrl->tx_bufsize);
-    tx_bufaddr = cy_readl(&buf_ctrl->tx_bufaddr);
-    if (tx_put >= tx_get)
-	char_count = tx_get - tx_put - 1 + tx_bufsize;
-    else
-	char_count = tx_get - tx_put - 1;
+	tx_get = cy_readl(&buf_ctrl->tx_get);
+	tx_put = cy_readl(&buf_ctrl->tx_put);
+	tx_bufsize = cy_readl(&buf_ctrl->tx_bufsize);
+	tx_bufaddr = cy_readl(&buf_ctrl->tx_bufaddr);
+	if (tx_put >= tx_get)
+		char_count = tx_get - tx_put - 1 + tx_bufsize;
+	else
+		char_count = tx_get - tx_put - 1;
 
-    if ( char_count ) {
+	if (char_count) {
 
-	if( tty == 0 ){
-	    goto ztxdone;
-	}
+		if (tty == 0) {
+			goto ztxdone;
+		}
 
-	if(info->x_char) { /* send special char */
-	    data = info->x_char;
+		if (info->x_char) {	/* send special char */
+			data = info->x_char;
 
-	    cy_writeb((cinfo->base_addr + tx_bufaddr + tx_put), data);
-	    tx_put = (tx_put + 1) & (tx_bufsize - 1);
-	    info->x_char = 0;
-	    char_count--;
-	    info->icount.tx++;
-	    info->last_active = jiffies;
-	    info->jiffies[2] = jiffies;
-	}
+			cy_writeb(cinfo->base_addr + tx_bufaddr + tx_put, data);
+			tx_put = (tx_put + 1) & (tx_bufsize - 1);
+			info->x_char = 0;
+			char_count--;
+			info->icount.tx++;
+			info->last_active = jiffies;
+			info->jiffies[2] = jiffies;
+		}
 #ifdef BLOCKMOVE
-	while(0 < (small_count = 
-		   min_t(unsigned int, (tx_bufsize - tx_put),
-		       min_t(unsigned int, (SERIAL_XMIT_SIZE - info->xmit_tail),
-			   min_t(unsigned int, info->xmit_cnt, char_count))))) {
-
-	    memcpy_toio((char *)(cinfo->base_addr + tx_bufaddr + tx_put),
-			&info->xmit_buf[info->xmit_tail],
-			small_count);
-
-	    tx_put = (tx_put + small_count) & (tx_bufsize - 1);
-	    char_count -= small_count;
-	    info->icount.tx += small_count;
-	    info->xmit_cnt -= small_count;
-	    info->xmit_tail = 
-		(info->xmit_tail + small_count) & (SERIAL_XMIT_SIZE - 1);
-	    info->last_active = jiffies;
-	    info->jiffies[2] = jiffies;
-	}
+		while (0 < (small_count = min_t(unsigned int,
+				tx_bufsize - tx_put, min_t(unsigned int,
+					(SERIAL_XMIT_SIZE - info->xmit_tail),
+					min_t(unsigned int, info->xmit_cnt,
+						char_count))))) {
+
+			memcpy_toio((char *)(cinfo->base_addr + tx_bufaddr +
+					tx_put),
+					&info->xmit_buf[info->xmit_tail],
+					small_count);
+
+			tx_put = (tx_put + small_count) & (tx_bufsize - 1);
+			char_count -= small_count;
+			info->icount.tx += small_count;
+			info->xmit_cnt -= small_count;
+			info->xmit_tail = (info->xmit_tail + small_count) &
+					(SERIAL_XMIT_SIZE - 1);
+			info->last_active = jiffies;
+			info->jiffies[2] = jiffies;
+		}
 #else
-	while (info->xmit_cnt && char_count){
-	    data = info->xmit_buf[info->xmit_tail];
-	    info->xmit_cnt--;
-	    info->xmit_tail = (info->xmit_tail + 1) & (SERIAL_XMIT_SIZE - 1);
-
-	    cy_writeb(cinfo->base_addr + tx_bufaddr + tx_put, data);
-	    tx_put = (tx_put + 1) & (tx_bufsize - 1);
-	    char_count--;
-	    info->icount.tx++;
-	    info->last_active = jiffies;
-	    info->jiffies[2] = jiffies;
-	}
+		while (info->xmit_cnt && char_count) {
+			data = info->xmit_buf[info->xmit_tail];
+			info->xmit_cnt--;
+			info->xmit_tail = (info->xmit_tail + 1) &
+					(SERIAL_XMIT_SIZE - 1);
+
+			cy_writeb(cinfo->base_addr + tx_bufaddr + tx_put, data);
+			tx_put = (tx_put + 1) & (tx_bufsize - 1);
+			char_count--;
+			info->icount.tx++;
+			info->last_active = jiffies;
+			info->jiffies[2] = jiffies;
+		}
 #endif
-    ztxdone:
-	if (info->xmit_cnt < WAKEUP_CHARS) {
-	    cy_sched_event(info, Cy_EVENT_WRITE_WAKEUP);
+ztxdone:
+		if (info->xmit_cnt < WAKEUP_CHARS) {
+			cy_sched_event(info, Cy_EVENT_WRITE_WAKEUP);
+		}
+		/* Update tx_put */
+		cy_writel(&buf_ctrl->tx_put, tx_put);
 	}
-	/* Update tx_put */
-	cy_writel(&buf_ctrl->tx_put, tx_put);
-    }
 }
 
-static void
-cyz_handle_cmd(struct cyclades_card *cinfo)
+static void cyz_handle_cmd(struct cyclades_card *cinfo)
 {
-  struct tty_struct *tty;
-  struct cyclades_port *info;
-  static volatile struct FIRM_ID __iomem *firm_id;
-  static volatile struct ZFW_CTRL __iomem *zfw_ctrl;
-  static volatile struct BOARD_CTRL __iomem *board_ctrl;
-  static volatile struct CH_CTRL __iomem *ch_ctrl;
-  static volatile struct BUF_CTRL __iomem *buf_ctrl;
-  uclong channel;
-  ucchar cmd;
-  uclong param;
-  uclong hw_ver, fw_ver;
-  int special_count;
-  int delta_count;
-
-    firm_id = cinfo->base_addr + ID_ADDRESS;
-    zfw_ctrl = cinfo->base_addr + (cy_readl(&firm_id->zfwctrl_addr) & 0xfffff);
-    board_ctrl = &zfw_ctrl->board_ctrl;
-    fw_ver = cy_readl(&board_ctrl->fw_version);
-    hw_ver = cy_readl(&((struct RUNTIME_9060 __iomem *)(cinfo->ctl_addr))->mail_box_0);
-
-
-    while(cyz_fetch_msg(cinfo, &channel, &cmd, &param) == 1) {
-	special_count = 0;
-	delta_count = 0;
-	info = &cy_port[channel + cinfo->first_line];
-	if((tty = info->tty) == 0) {
-	    continue;
-	}
-	ch_ctrl = &(zfw_ctrl->ch_ctrl[channel]);
-	buf_ctrl = &(zfw_ctrl->buf_ctrl[channel]);
-
-	switch(cmd) {
-	    case C_CM_PR_ERROR:
-		tty_insert_flip_char(tty, 0, TTY_PARITY);
-		info->icount.rx++;
-		special_count++;
-		break;
-	    case C_CM_FR_ERROR:
-		tty_insert_flip_char(tty, 0, TTY_FRAME);
-		info->icount.rx++;
-		special_count++;
-		break;
-	    case C_CM_RXBRK:
-		tty_insert_flip_char(tty, 0, TTY_BREAK);
-		info->icount.rx++;
-		special_count++;
-		break;
-	    case C_CM_MDCD:
-		info->icount.dcd++;
-		delta_count++;
-		if (info->flags & ASYNC_CHECK_CD){
-		    if ((fw_ver > 241 ? 
-			  ((u_long)param) : 
-			  cy_readl(&ch_ctrl->rs_status)) & C_RS_DCD) {
-			cy_sched_event(info, Cy_EVENT_OPEN_WAKEUP);
-		    }else{
-			cy_sched_event(info, Cy_EVENT_HANGUP);
-		    }
+	struct tty_struct *tty;
+	struct cyclades_port *info;
+	static volatile struct FIRM_ID __iomem *firm_id;
+	static volatile struct ZFW_CTRL __iomem *zfw_ctrl;
+	static volatile struct BOARD_CTRL __iomem *board_ctrl;
+	static volatile struct CH_CTRL __iomem *ch_ctrl;
+	static volatile struct BUF_CTRL __iomem *buf_ctrl;
+	uclong channel;
+	ucchar cmd;
+	uclong param;
+	uclong hw_ver, fw_ver;
+	int special_count;
+	int delta_count;
+
+	firm_id = cinfo->base_addr + ID_ADDRESS;
+	zfw_ctrl = cinfo->base_addr + (cy_readl(&firm_id->zfwctrl_addr) &
+			0xfffff);
+	board_ctrl = &zfw_ctrl->board_ctrl;
+	fw_ver = cy_readl(&board_ctrl->fw_version);
+	hw_ver = cy_readl(&((struct RUNTIME_9060 __iomem *)(cinfo->ctl_addr))->
+			mail_box_0);
+
+	while (cyz_fetch_msg(cinfo, &channel, &cmd, &param) == 1) {
+		special_count = 0;
+		delta_count = 0;
+		info = &cy_port[channel + cinfo->first_line];
+		if ((tty = info->tty) == 0) {
+			continue;
 		}
-		break;
-	    case C_CM_MCTS:
-		info->icount.cts++;
-		delta_count++;
-		break;
-	    case C_CM_MRI:
-		info->icount.rng++;
-		delta_count++;
-		break;
-	    case C_CM_MDSR:
-		info->icount.dsr++;
-		delta_count++;
-		break;
+		ch_ctrl = &(zfw_ctrl->ch_ctrl[channel]);
+		buf_ctrl = &(zfw_ctrl->buf_ctrl[channel]);
+
+		switch (cmd) {
+		case C_CM_PR_ERROR:
+			tty_insert_flip_char(tty, 0, TTY_PARITY);
+			info->icount.rx++;
+			special_count++;
+			break;
+		case C_CM_FR_ERROR:
+			tty_insert_flip_char(tty, 0, TTY_FRAME);
+			info->icount.rx++;
+			special_count++;
+			break;
+		case C_CM_RXBRK:
+			tty_insert_flip_char(tty, 0, TTY_BREAK);
+			info->icount.rx++;
+			special_count++;
+			break;
+		case C_CM_MDCD:
+			info->icount.dcd++;
+			delta_count++;
+			if (info->flags & ASYNC_CHECK_CD) {
+				if ((fw_ver > 241 ? ((u_long) param) :
+						cy_readl(&ch_ctrl->rs_status)) &
+						C_RS_DCD) {
+					cy_sched_event(info,
+						 	Cy_EVENT_OPEN_WAKEUP);
+				} else {
+					cy_sched_event(info, Cy_EVENT_HANGUP);
+				}
+			}
+			break;
+		case C_CM_MCTS:
+			info->icount.cts++;
+			delta_count++;
+			break;
+		case C_CM_MRI:
+			info->icount.rng++;
+			delta_count++;
+			break;
+		case C_CM_MDSR:
+			info->icount.dsr++;
+			delta_count++;
+			break;
 #ifdef Z_WAKE
-	    case C_CM_IOCTLW:
-		cy_sched_event(info, Cy_EVENT_SHUTDOWN_WAKEUP);
-		break;
+		case C_CM_IOCTLW:
+			cy_sched_event(info, Cy_EVENT_SHUTDOWN_WAKEUP);
+			break;
 #endif
 #ifdef CONFIG_CYZ_INTR
-	    case C_CM_RXHIWM:
-	    case C_CM_RXNNDT:
-	    case C_CM_INTBACK2:
-		/* Reception Interrupt */
+		case C_CM_RXHIWM:
+		case C_CM_RXNNDT:
+		case C_CM_INTBACK2:
+			/* Reception Interrupt */
 #ifdef CY_DEBUG_INTERRUPTS
-		printk("cyz_interrupt: rcvd intr, card %d, port %ld\n\r", 
-			info->card, channel);
+			printk("cyz_interrupt: rcvd intr, card %d, "
+					"port %ld\n\r", info->card, channel);
 #endif
-		cyz_handle_rx(info, ch_ctrl, buf_ctrl);
-		break;
-	    case C_CM_TXBEMPTY:
-	    case C_CM_TXLOWWM:
-	    case C_CM_INTBACK:
-		/* Transmission Interrupt */
+			cyz_handle_rx(info, ch_ctrl, buf_ctrl);
+			break;
+		case C_CM_TXBEMPTY:
+		case C_CM_TXLOWWM:
+		case C_CM_INTBACK:
+			/* Transmission Interrupt */
 #ifdef CY_DEBUG_INTERRUPTS
-		printk("cyz_interrupt: xmit intr, card %d, port %ld\n\r", 
-			info->card, channel);
+			printk("cyz_interrupt: xmit intr, card %d, "
+					"port %ld\n\r", info->card, channel);
 #endif
-		cyz_handle_tx(info, ch_ctrl, buf_ctrl);
-		break;
-#endif /* CONFIG_CYZ_INTR */
-	    case C_CM_FATAL:
-		/* should do something with this !!! */
-		break;
-	    default:
-		break;
+			cyz_handle_tx(info, ch_ctrl, buf_ctrl);
+			break;
+#endif				/* CONFIG_CYZ_INTR */
+		case C_CM_FATAL:
+			/* should do something with this !!! */
+			break;
+		default:
+			break;
+		}
+		if (delta_count)
+			cy_sched_event(info, Cy_EVENT_DELTA_WAKEUP);
+		if (special_count)
+			tty_schedule_flip(tty);
 	}
-	if(delta_count)
-	    cy_sched_event(info, Cy_EVENT_DELTA_WAKEUP);
-	if(special_count)
-	    tty_schedule_flip(tty);
-    }
 }
 
 #ifdef CONFIG_CYZ_INTR
-static irqreturn_t
-cyz_interrupt(int irq, void *dev_id)
+static irqreturn_t cyz_interrupt(int irq, void *dev_id)
 {
-  struct cyclades_card *cinfo;
+	struct cyclades_card *cinfo;
 
-    if((cinfo = (struct cyclades_card *)dev_id) == 0){
+	if ((cinfo = (struct cyclades_card *)dev_id) == 0) {
 #ifdef CY_DEBUG_INTERRUPTS
-	printk("cyz_interrupt: spurious interrupt %d\n\r", irq);
+		printk("cyz_interrupt: spurious interrupt %d\n\r", irq);
 #endif
-        return IRQ_NONE; /* spurious interrupt */
-    }
+		return IRQ_NONE;	/* spurious interrupt */
+	}
 
-    if (!ISZLOADED(*cinfo)) {
+	if (!ISZLOADED(*cinfo)) {
 #ifdef CY_DEBUG_INTERRUPTS
-	printk("cyz_interrupt: board not yet loaded (IRQ%d).\n\r", irq);
+		printk("cyz_interrupt: board not yet loaded (IRQ%d).\n\r", irq);
 #endif
-	return IRQ_NONE;
-    }
+		return IRQ_NONE;
+	}
 
-    /* Handle the interrupts */
-    cyz_handle_cmd(cinfo);
+	/* Handle the interrupts */
+	cyz_handle_cmd(cinfo);
 
-    return IRQ_HANDLED;
-} /* cyz_interrupt */
+	return IRQ_HANDLED;
+}				/* cyz_interrupt */
 
-static void
-cyz_rx_restart(unsigned long arg)
+static void cyz_rx_restart(unsigned long arg)
 {
-    struct cyclades_port *info = (struct cyclades_port *)arg;
-    int retval;
-    int card = info->card;
-    uclong channel = (info->line) - (cy_card[card].first_line);
-    unsigned long flags;
-
-    CY_LOCK(info, flags);
-    retval = cyz_issue_cmd(&cy_card[card], channel, C_CM_INTBACK2, 0L);
-    if (retval != 0){
-	printk("cyc:cyz_rx_restart retval on ttyC%d was %x\n", 
-	       info->line, retval);
-    }
-    cyz_rx_full_timer[info->line].function = NULL;
-    CY_UNLOCK(info, flags);
+	struct cyclades_port *info = (struct cyclades_port *)arg;
+	int retval;
+	int card = info->card;
+	uclong channel = (info->line) - (cy_card[card].first_line);
+	unsigned long flags;
+
+	CY_LOCK(info, flags);
+	retval = cyz_issue_cmd(&cy_card[card], channel, C_CM_INTBACK2, 0L);
+	if (retval != 0) {
+		printk("cyc:cyz_rx_restart retval on ttyC%d was %x\n",
+			info->line, retval);
+	}
+	cyz_rx_full_timer[info->line].function = NULL;
+	CY_UNLOCK(info, flags);
 }
 
-#else /* CONFIG_CYZ_INTR */
+#else				/* CONFIG_CYZ_INTR */
 
-static void
-cyz_poll(unsigned long arg)
+static void cyz_poll(unsigned long arg)
 {
-  struct cyclades_card *cinfo;
-  struct cyclades_port *info;
-  struct tty_struct *tty;
-  static volatile struct FIRM_ID *firm_id;
-  static volatile struct ZFW_CTRL *zfw_ctrl;
-  static volatile struct BOARD_CTRL *board_ctrl;
-  static volatile struct CH_CTRL *ch_ctrl;
-  static volatile struct BUF_CTRL *buf_ctrl;
-  int card, port;
-
-    cyz_timerlist.expires = jiffies + (HZ);
-    for (card = 0 ; card < NR_CARDS ; card++){
-	cinfo = &cy_card[card];
-
-	if (!IS_CYC_Z(*cinfo)) continue;
-	if (!ISZLOADED(*cinfo)) continue;
+	struct cyclades_card *cinfo;
+	struct cyclades_port *info;
+	struct tty_struct *tty;
+	static volatile struct FIRM_ID *firm_id;
+	static volatile struct ZFW_CTRL *zfw_ctrl;
+	static volatile struct BOARD_CTRL *board_ctrl;
+	static volatile struct CH_CTRL *ch_ctrl;
+	static volatile struct BUF_CTRL *buf_ctrl;
+	int card, port;
 
-	firm_id = cinfo->base_addr + ID_ADDRESS;
-	zfw_ctrl = cinfo->base_addr + (cy_readl(&firm_id->zfwctrl_addr) & 0xfffff);
-	board_ctrl = &(zfw_ctrl->board_ctrl);
+	cyz_timerlist.expires = jiffies + (HZ);
+	for (card = 0; card < NR_CARDS; card++) {
+		cinfo = &cy_card[card];
+
+		if (!IS_CYC_Z(*cinfo))
+			continue;
+		if (!ISZLOADED(*cinfo))
+			continue;
+
+		firm_id = cinfo->base_addr + ID_ADDRESS;
+		zfw_ctrl = cinfo->base_addr +
+				(cy_readl(&firm_id->zfwctrl_addr) & 0xfffff);
+		board_ctrl = &(zfw_ctrl->board_ctrl);
 
 	/* Skip first polling cycle to avoid racing conditions with the FW */
-	if (!cinfo->intr_enabled) {
-	    cinfo->nports = (int) cy_readl(&board_ctrl->n_channel);
-	    cinfo->intr_enabled = 1;
-	    continue;
-	}
+		if (!cinfo->intr_enabled) {
+			cinfo->nports = (int)cy_readl(&board_ctrl->n_channel);
+			cinfo->intr_enabled = 1;
+			continue;
+		}
 
-	cyz_handle_cmd(cinfo);
+		cyz_handle_cmd(cinfo);
 
-	for (port = 0 ; port < cinfo->nports ; port++) {
-	    info = &cy_port[ port + cinfo->first_line ];
-            tty = info->tty;
-	    ch_ctrl = &(zfw_ctrl->ch_ctrl[port]);
-	    buf_ctrl = &(zfw_ctrl->buf_ctrl[port]);
+		for (port = 0; port < cinfo->nports; port++) {
+			info = &cy_port[port + cinfo->first_line];
+			tty = info->tty;
+			ch_ctrl = &(zfw_ctrl->ch_ctrl[port]);
+			buf_ctrl = &(zfw_ctrl->buf_ctrl[port]);
 
-	    if (!info->throttle)
-	        cyz_handle_rx(info, ch_ctrl, buf_ctrl);
-	    cyz_handle_tx(info, ch_ctrl, buf_ctrl);
+			if (!info->throttle)
+				cyz_handle_rx(info, ch_ctrl, buf_ctrl);
+			cyz_handle_tx(info, ch_ctrl, buf_ctrl);
+		}
+		/* poll every 'cyz_polling_cycle' period */
+		cyz_timerlist.expires = jiffies + cyz_polling_cycle;
 	}
-	/* poll every 'cyz_polling_cycle' period */
-	cyz_timerlist.expires = jiffies + cyz_polling_cycle;
-    }
-    add_timer(&cyz_timerlist);
+	add_timer(&cyz_timerlist);
+}				/* cyz_poll */
 
-    return;
-} /* cyz_poll */
-
-#endif /* CONFIG_CYZ_INTR */
+#endif				/* CONFIG_CYZ_INTR */
 
 /********** End of block of Cyclades-Z specific code *********/
 /***********************************************************/
 
-
 /* This is called whenever a port becomes active;
    interrupts are enabled and DTR & RTS are turned on.
  */
-static int
-startup(struct cyclades_port * info)
+static int startup(struct cyclades_port *info)
 {
-  unsigned long flags;
-  int retval = 0;
-  void __iomem *base_addr;
-  int card,chip,channel,index;
-  unsigned long page;
+	unsigned long flags;
+	int retval = 0;
+	void __iomem *base_addr;
+	int card, chip, channel, index;
+	unsigned long page;
 
-    card = info->card;
-    channel = (info->line) - (cy_card[card].first_line);
+	card = info->card;
+	channel = (info->line) - (cy_card[card].first_line);
 
-    page = get_zeroed_page(GFP_KERNEL);
-    if (!page)
-	return -ENOMEM;
+	page = get_zeroed_page(GFP_KERNEL);
+	if (!page)
+		return -ENOMEM;
 
-    CY_LOCK(info, flags);
+	CY_LOCK(info, flags);
 
-    if (info->flags & ASYNC_INITIALIZED){
-	free_page(page);
-	goto errout;
-    }
+	if (info->flags & ASYNC_INITIALIZED) {
+		free_page(page);
+		goto errout;
+	}
 
-    if (!info->type){
-        if (info->tty){
-            set_bit(TTY_IO_ERROR, &info->tty->flags);
-        }
-	free_page(page);
-	goto errout;
-    }
+	if (!info->type) {
+		if (info->tty) {
+			set_bit(TTY_IO_ERROR, &info->tty->flags);
+		}
+		free_page(page);
+		goto errout;
+	}
 
-    if (info->xmit_buf)
-	free_page(page);
-    else
-	info->xmit_buf = (unsigned char *) page;
+	if (info->xmit_buf)
+		free_page(page);
+	else
+		info->xmit_buf = (unsigned char *)page;
 
-    CY_UNLOCK(info, flags);
+	CY_UNLOCK(info, flags);
 
-    set_line_char(info);
+	set_line_char(info);
 
-    if (!IS_CYC_Z(cy_card[card])) {
-	chip = channel>>2;
-	channel &= 0x03;
-	index = cy_card[card].bus_index;
-	base_addr = cy_card[card].base_addr + (cy_chip_offset[chip]<<index);
+	if (!IS_CYC_Z(cy_card[card])) {
+		chip = channel >> 2;
+		channel &= 0x03;
+		index = cy_card[card].bus_index;
+		base_addr = cy_card[card].base_addr +
+				(cy_chip_offset[chip] << index);
 
 #ifdef CY_DEBUG_OPEN
-	printk("cyc startup card %d, chip %d, channel %d, base_addr %lx\n",
-	     card, chip, channel, (long)base_addr);/**/
+		printk("cyc startup card %d, chip %d, channel %d, "
+				"base_addr %lx\n",
+				card, chip, channel, (long)base_addr);
+		/**/
 #endif
+		CY_LOCK(info, flags);
 
-	CY_LOCK(info, flags);
-
-	cy_writeb(base_addr+(CyCAR<<index), (u_char)channel);
+		cy_writeb(base_addr + (CyCAR << index), (u_char) channel);
 
-	cy_writeb(base_addr+(CyRTPR<<index), (info->default_timeout
-		 ? info->default_timeout : 0x02)); /* 10ms rx timeout */
+		cy_writeb(base_addr + (CyRTPR << index),
+			(info->default_timeout ? info->default_timeout : 0x02));
+		/* 10ms rx timeout */
 
-	cyy_issue_cmd(base_addr,CyCHAN_CTL|CyENB_RCVR|CyENB_XMTR,index);
+		cyy_issue_cmd(base_addr, CyCHAN_CTL | CyENB_RCVR | CyENB_XMTR,
+				index);
 
-	cy_writeb(base_addr+(CyCAR<<index), (u_char)channel);
-	cy_writeb(base_addr+(CyMSVR1<<index), CyRTS);
-	cy_writeb(base_addr+(CyMSVR2<<index), CyDTR);
+		cy_writeb(base_addr + (CyCAR << index), (u_char) channel);
+		cy_writeb(base_addr + (CyMSVR1 << index), CyRTS);
+		cy_writeb(base_addr + (CyMSVR2 << index), CyDTR);
 
 #ifdef CY_DEBUG_DTR
-	printk("cyc:startup raising DTR\n");
-	printk("     status: 0x%x, 0x%x\n",
-		cy_readb(base_addr+(CyMSVR1<<index)), 
-                cy_readb(base_addr+(CyMSVR2<<index)));
+		printk("cyc:startup raising DTR\n");
+		printk("     status: 0x%x, 0x%x\n",
+			cy_readb(base_addr + (CyMSVR1 << index)),
+			cy_readb(base_addr + (CyMSVR2 << index)));
 #endif
 
-	cy_writeb(base_addr+(CySRER<<index),
-		cy_readb(base_addr+(CySRER<<index)) | CyRxData);
-	info->flags |= ASYNC_INITIALIZED;
+		cy_writeb(base_addr + (CySRER << index),
+			cy_readb(base_addr + (CySRER << index)) | CyRxData);
+		info->flags |= ASYNC_INITIALIZED;
 
-	if (info->tty){
-	    clear_bit(TTY_IO_ERROR, &info->tty->flags);
-	}
-	info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
-	info->breakon = info->breakoff = 0;
-	memset((char *)&info->idle_stats, 0, sizeof(info->idle_stats));
-	info->idle_stats.in_use    =
-	info->idle_stats.recv_idle =
-	info->idle_stats.xmit_idle = jiffies;
+		if (info->tty) {
+			clear_bit(TTY_IO_ERROR, &info->tty->flags);
+		}
+		info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
+		info->breakon = info->breakoff = 0;
+		memset((char *)&info->idle_stats, 0, sizeof(info->idle_stats));
+		info->idle_stats.in_use =
+		info->idle_stats.recv_idle =
+		info->idle_stats.xmit_idle = jiffies;
 
-	CY_UNLOCK(info, flags);
+		CY_UNLOCK(info, flags);
 
-    } else {
-      struct FIRM_ID __iomem *firm_id;
-      struct ZFW_CTRL __iomem *zfw_ctrl;
-      struct BOARD_CTRL __iomem *board_ctrl;
-      struct CH_CTRL __iomem *ch_ctrl;
-      int retval;
+	} else {
+		struct FIRM_ID __iomem *firm_id;
+		struct ZFW_CTRL __iomem *zfw_ctrl;
+		struct BOARD_CTRL __iomem *board_ctrl;
+		struct CH_CTRL __iomem *ch_ctrl;
+		int retval;
 
-	base_addr = cy_card[card].base_addr;
+		base_addr = cy_card[card].base_addr;
 
-        firm_id = base_addr + ID_ADDRESS;
-        if (!ISZLOADED(cy_card[card])){
-	    return -ENODEV;
-	}
+		firm_id = base_addr + ID_ADDRESS;
+		if (!ISZLOADED(cy_card[card])) {
+			return -ENODEV;
+		}
 
-	zfw_ctrl = cy_card[card].base_addr + (cy_readl(&firm_id->zfwctrl_addr) & 0xfffff);
-	board_ctrl = &zfw_ctrl->board_ctrl;
-	ch_ctrl = zfw_ctrl->ch_ctrl;
+		zfw_ctrl = cy_card[card].base_addr +
+				(cy_readl(&firm_id->zfwctrl_addr) & 0xfffff);
+		board_ctrl = &zfw_ctrl->board_ctrl;
+		ch_ctrl = zfw_ctrl->ch_ctrl;
 
 #ifdef CY_DEBUG_OPEN
-	printk("cyc startup Z card %d, channel %d, base_addr %lx\n",
-	     card, channel, (long)base_addr);/**/
+		printk("cyc startup Z card %d, channel %d, base_addr %lx\n",
+			card, channel, (long)base_addr);
+		/**/
 #endif
+		CY_LOCK(info, flags);
 
-	CY_LOCK(info, flags);
-
-	cy_writel(&ch_ctrl[channel].op_mode, C_CH_ENABLE);
+		cy_writel(&ch_ctrl[channel].op_mode, C_CH_ENABLE);
 #ifdef Z_WAKE
 #ifdef CONFIG_CYZ_INTR
-	cy_writel(&ch_ctrl[channel].intr_enable, 
-		  C_IN_TXBEMPTY|C_IN_TXLOWWM|C_IN_RXHIWM|C_IN_RXNNDT|
-		  C_IN_IOCTLW|
-		  C_IN_MDCD);
+		cy_writel(&ch_ctrl[channel].intr_enable,
+			  C_IN_TXBEMPTY | C_IN_TXLOWWM | C_IN_RXHIWM |
+			  C_IN_RXNNDT | C_IN_IOCTLW | C_IN_MDCD);
 #else
-	cy_writel(&ch_ctrl[channel].intr_enable, 
-		  C_IN_IOCTLW|
-		  C_IN_MDCD);
-#endif /* CONFIG_CYZ_INTR */
+		cy_writel(&ch_ctrl[channel].intr_enable,
+			  C_IN_IOCTLW | C_IN_MDCD);
+#endif				/* CONFIG_CYZ_INTR */
 #else
 #ifdef CONFIG_CYZ_INTR
-	cy_writel(&ch_ctrl[channel].intr_enable, 
-		  C_IN_TXBEMPTY|C_IN_TXLOWWM|C_IN_RXHIWM|C_IN_RXNNDT|
-		  C_IN_MDCD);
+		cy_writel(&ch_ctrl[channel].intr_enable,
+			  C_IN_TXBEMPTY | C_IN_TXLOWWM | C_IN_RXHIWM |
+			  C_IN_RXNNDT | C_IN_MDCD);
 #else
-	cy_writel(&ch_ctrl[channel].intr_enable, 
-		  C_IN_MDCD);
-#endif /* CONFIG_CYZ_INTR */
-#endif /* Z_WAKE */
-
-	retval = cyz_issue_cmd(&cy_card[card], channel, C_CM_IOCTL, 0L);
-	if (retval != 0){
-	    printk("cyc:startup(1) retval on ttyC%d was %x\n",
-		   info->line, retval);
-	}
+		cy_writel(&ch_ctrl[channel].intr_enable, C_IN_MDCD);
+#endif				/* CONFIG_CYZ_INTR */
+#endif				/* Z_WAKE */
+
+		retval = cyz_issue_cmd(&cy_card[card], channel, C_CM_IOCTL, 0L);
+		if (retval != 0) {
+			printk("cyc:startup(1) retval on ttyC%d was %x\n",
+				info->line, retval);
+		}
 
-	/* Flush RX buffers before raising DTR and RTS */
-	retval = cyz_issue_cmd(&cy_card[card], channel, C_CM_FLUSH_RX, 0L);
-	if (retval != 0){
-	    printk("cyc:startup(2) retval on ttyC%d was %x\n",
-		   info->line, retval);
-	}
+		/* Flush RX buffers before raising DTR and RTS */
+		retval = cyz_issue_cmd(&cy_card[card], channel, C_CM_FLUSH_RX,
+				0L);
+		if (retval != 0) {
+			printk("cyc:startup(2) retval on ttyC%d was %x\n",
+				info->line, retval);
+		}
 
-	/* set timeout !!! */
-	/* set RTS and DTR !!! */
-	cy_writel(&ch_ctrl[channel].rs_control,
-             cy_readl(&ch_ctrl[channel].rs_control) | C_RS_RTS | C_RS_DTR) ;
-	retval = cyz_issue_cmd(&cy_card[info->card],
-	    channel, C_CM_IOCTLM, 0L);
-	if (retval != 0){
-	    printk("cyc:startup(3) retval on ttyC%d was %x\n",
-		   info->line, retval);
-	}
+		/* set timeout !!! */
+		/* set RTS and DTR !!! */
+		cy_writel(&ch_ctrl[channel].rs_control,
+			cy_readl(&ch_ctrl[channel].rs_control) | C_RS_RTS |
+			C_RS_DTR);
+		retval = cyz_issue_cmd(&cy_card[info->card], channel,
+				C_CM_IOCTLM, 0L);
+		if (retval != 0) {
+			printk("cyc:startup(3) retval on ttyC%d was %x\n",
+				info->line, retval);
+		}
 #ifdef CY_DEBUG_DTR
-	    printk("cyc:startup raising Z DTR\n");
+		printk("cyc:startup raising Z DTR\n");
 #endif
 
-	/* enable send, recv, modem !!! */
+		/* enable send, recv, modem !!! */
 
-	info->flags |= ASYNC_INITIALIZED;
-	if (info->tty){
-	    clear_bit(TTY_IO_ERROR, &info->tty->flags);
-	}
-	info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
-	info->breakon = info->breakoff = 0;
-	memset((char *)&info->idle_stats, 0, sizeof(info->idle_stats));
-	info->idle_stats.in_use    =
-	info->idle_stats.recv_idle =
-	info->idle_stats.xmit_idle = jiffies;
+		info->flags |= ASYNC_INITIALIZED;
+		if (info->tty) {
+			clear_bit(TTY_IO_ERROR, &info->tty->flags);
+		}
+		info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
+		info->breakon = info->breakoff = 0;
+		memset((char *)&info->idle_stats, 0, sizeof(info->idle_stats));
+		info->idle_stats.in_use =
+		info->idle_stats.recv_idle =
+		info->idle_stats.xmit_idle = jiffies;
 
-	CY_UNLOCK(info, flags);
-    }
+		CY_UNLOCK(info, flags);
+	}
 
 #ifdef CY_DEBUG_OPEN
 	printk(" cyc startup done\n");
@@ -2094,165 +2154,165 @@ startup(struct cyclades_port * info)
 errout:
 	CY_UNLOCK(info, flags);
 	return retval;
-} /* startup */
-
+}				/* startup */
 
-static void
-start_xmit( struct cyclades_port *info )
+static void start_xmit(struct cyclades_port *info)
 {
-  unsigned long flags;
-  void __iomem *base_addr;
-  int card,chip,channel,index;
-
-    card = info->card;
-    channel = (info->line) - (cy_card[card].first_line);
-    if (!IS_CYC_Z(cy_card[card])) {
-	chip = channel>>2;
-	channel &= 0x03;
-	index = cy_card[card].bus_index;
-	base_addr = cy_card[card].base_addr + (cy_chip_offset[chip]<<index);
+	unsigned long flags;
+	void __iomem *base_addr;
+	int card, chip, channel, index;
 
-	CY_LOCK(info, flags);
-	    cy_writeb(base_addr+(CyCAR<<index), channel);
-	    cy_writeb(base_addr+(CySRER<<index), 
-               cy_readb(base_addr+(CySRER<<index)) | CyTxRdy);
-	CY_UNLOCK(info, flags);
-    } else {
+	card = info->card;
+	channel = (info->line) - (cy_card[card].first_line);
+	if (!IS_CYC_Z(cy_card[card])) {
+		chip = channel >> 2;
+		channel &= 0x03;
+		index = cy_card[card].bus_index;
+		base_addr = cy_card[card].base_addr +
+				(cy_chip_offset[chip] << index);
+
+		CY_LOCK(info, flags);
+		cy_writeb(base_addr + (CyCAR << index), channel);
+		cy_writeb(base_addr + (CySRER << index),
+			cy_readb(base_addr + (CySRER << index)) | CyTxRdy);
+		CY_UNLOCK(info, flags);
+	} else {
 #ifdef CONFIG_CYZ_INTR
-      int retval;
+		int retval;
 
-	CY_LOCK(info, flags);
-	    retval = cyz_issue_cmd(&cy_card[card], channel, C_CM_INTBACK, 0L);
-	    if (retval != 0){
-		printk("cyc:start_xmit retval on ttyC%d was %x\n",
-		       info->line, retval);
-	    }
-	CY_UNLOCK(info, flags);
-#else /* CONFIG_CYZ_INTR */
-	/* Don't have to do anything at this time */
-#endif /* CONFIG_CYZ_INTR */
-    }
-} /* start_xmit */
+		CY_LOCK(info, flags);
+		retval = cyz_issue_cmd(&cy_card[card], channel, C_CM_INTBACK,
+				0L);
+		if (retval != 0) {
+			printk("cyc:start_xmit retval on ttyC%d was %x\n",
+				info->line, retval);
+		}
+		CY_UNLOCK(info, flags);
+#else				/* CONFIG_CYZ_INTR */
+		/* Don't have to do anything at this time */
+#endif				/* CONFIG_CYZ_INTR */
+	}
+}				/* start_xmit */
 
 /*
  * This routine shuts down a serial port; interrupts are disabled,
  * and DTR is dropped if the hangup on close termio flag is on.
  */
-static void
-shutdown(struct cyclades_port * info)
+static void shutdown(struct cyclades_port *info)
 {
-  unsigned long flags;
-  void __iomem *base_addr;
-  int card,chip,channel,index;
-
-    if (!(info->flags & ASYNC_INITIALIZED)){
-        return;
-    }
-
-    card = info->card;
-    channel = info->line - cy_card[card].first_line;
-    if (!IS_CYC_Z(cy_card[card])) {
-	chip = channel>>2;
-	channel &= 0x03;
-	index = cy_card[card].bus_index;
-	base_addr = cy_card[card].base_addr + (cy_chip_offset[chip]<<index);
+	unsigned long flags;
+	void __iomem *base_addr;
+	int card, chip, channel, index;
+
+	if (!(info->flags & ASYNC_INITIALIZED)) {
+		return;
+	}
+
+	card = info->card;
+	channel = info->line - cy_card[card].first_line;
+	if (!IS_CYC_Z(cy_card[card])) {
+		chip = channel >> 2;
+		channel &= 0x03;
+		index = cy_card[card].bus_index;
+		base_addr = cy_card[card].base_addr +
+				(cy_chip_offset[chip] << index);
 
 #ifdef CY_DEBUG_OPEN
-    printk("cyc shutdown Y card %d, chip %d, channel %d, base_addr %lx\n",
-		card, chip, channel, (long)base_addr);
+		printk("cyc shutdown Y card %d, chip %d, channel %d, "
+				"base_addr %lx\n",
+				card, chip, channel, (long)base_addr);
 #endif
 
-	CY_LOCK(info, flags);
+		CY_LOCK(info, flags);
 
-	    /* Clear delta_msr_wait queue to avoid mem leaks. */
-	    wake_up_interruptible(&info->delta_msr_wait);
-
-	    if (info->xmit_buf){
-		unsigned char * temp;
-		temp = info->xmit_buf;
-		info->xmit_buf = NULL;
-		free_page((unsigned long) temp);
-	    }
-	    cy_writeb(base_addr+(CyCAR<<index), (u_char)channel);
-	    if (!info->tty || (info->tty->termios->c_cflag & HUPCL)) {
-		cy_writeb(base_addr+(CyMSVR1<<index), ~CyRTS);
-		cy_writeb(base_addr+(CyMSVR2<<index), ~CyDTR);
+		/* Clear delta_msr_wait queue to avoid mem leaks. */
+		wake_up_interruptible(&info->delta_msr_wait);
+
+		if (info->xmit_buf) {
+			unsigned char *temp;
+			temp = info->xmit_buf;
+			info->xmit_buf = NULL;
+			free_page((unsigned long)temp);
+		}
+		cy_writeb(base_addr + (CyCAR << index), (u_char) channel);
+		if (!info->tty || (info->tty->termios->c_cflag & HUPCL)) {
+			cy_writeb(base_addr + (CyMSVR1 << index), ~CyRTS);
+			cy_writeb(base_addr + (CyMSVR2 << index), ~CyDTR);
 #ifdef CY_DEBUG_DTR
-		printk("cyc shutdown dropping DTR\n");
-		printk("     status: 0x%x, 0x%x\n",
-		    cy_readb(base_addr+(CyMSVR1<<index)), 
-                    cy_readb(base_addr+(CyMSVR2<<index)));
+			printk("cyc shutdown dropping DTR\n");
+			printk("     status: 0x%x, 0x%x\n",
+				cy_readb(base_addr + (CyMSVR1 << index)),
+				cy_readb(base_addr + (CyMSVR2 << index)));
 #endif
-	    }
-	    cyy_issue_cmd(base_addr,CyCHAN_CTL|CyDIS_RCVR,index);
-	     /* it may be appropriate to clear _XMIT at
-	       some later date (after testing)!!! */
-
-	    if (info->tty){
-		set_bit(TTY_IO_ERROR, &info->tty->flags);
-	    }
-	    info->flags &= ~ASYNC_INITIALIZED;
-	CY_UNLOCK(info, flags);
-    } else {
-      struct FIRM_ID __iomem *firm_id;
-      struct ZFW_CTRL __iomem *zfw_ctrl;
-      struct BOARD_CTRL __iomem *board_ctrl;
-      struct CH_CTRL __iomem *ch_ctrl;
-      int retval;
-
-	base_addr = cy_card[card].base_addr;
+		}
+		cyy_issue_cmd(base_addr, CyCHAN_CTL | CyDIS_RCVR, index);
+		/* it may be appropriate to clear _XMIT at
+		   some later date (after testing)!!! */
+
+		if (info->tty) {
+			set_bit(TTY_IO_ERROR, &info->tty->flags);
+		}
+		info->flags &= ~ASYNC_INITIALIZED;
+		CY_UNLOCK(info, flags);
+	} else {
+		struct FIRM_ID __iomem *firm_id;
+		struct ZFW_CTRL __iomem *zfw_ctrl;
+		struct BOARD_CTRL __iomem *board_ctrl;
+		struct CH_CTRL __iomem *ch_ctrl;
+		int retval;
+
+		base_addr = cy_card[card].base_addr;
 #ifdef CY_DEBUG_OPEN
-    printk("cyc shutdown Z card %d, channel %d, base_addr %lx\n",
-		card, channel, (long)base_addr);
+		printk("cyc shutdown Z card %d, channel %d, base_addr %lx\n",
+			card, channel, (long)base_addr);
 #endif
 
-        firm_id = base_addr + ID_ADDRESS;
-        if (!ISZLOADED(cy_card[card])) {
-	    return;
-	}
+		firm_id = base_addr + ID_ADDRESS;
+		if (!ISZLOADED(cy_card[card])) {
+			return;
+		}
 
-	zfw_ctrl = cy_card[card].base_addr + (cy_readl(&firm_id->zfwctrl_addr) & 0xfffff);
-	board_ctrl = &zfw_ctrl->board_ctrl;
-	ch_ctrl = zfw_ctrl->ch_ctrl;
+		zfw_ctrl = cy_card[card].base_addr +
+				(cy_readl(&firm_id->zfwctrl_addr) & 0xfffff);
+		board_ctrl = &zfw_ctrl->board_ctrl;
+		ch_ctrl = zfw_ctrl->ch_ctrl;
 
-	CY_LOCK(info, flags);
+		CY_LOCK(info, flags);
 
-	    if (info->xmit_buf){
-		unsigned char * temp;
-		temp = info->xmit_buf;
-		info->xmit_buf = NULL;
-		free_page((unsigned long) temp);
-	    }
-	    
-	    if (!info->tty || (info->tty->termios->c_cflag & HUPCL)) {
-		cy_writel(&ch_ctrl[channel].rs_control,
-                   (uclong)(cy_readl(&ch_ctrl[channel].rs_control) & 
-                   ~(C_RS_RTS | C_RS_DTR)));
-		retval = cyz_issue_cmd(&cy_card[info->card],
-			channel, C_CM_IOCTLM, 0L);
-		if (retval != 0){
-		    printk("cyc:shutdown retval on ttyC%d was %x\n",
-			   info->line, retval);
+		if (info->xmit_buf) {
+			unsigned char *temp;
+			temp = info->xmit_buf;
+			info->xmit_buf = NULL;
+			free_page((unsigned long)temp);
 		}
+
+		if (!info->tty || (info->tty->termios->c_cflag & HUPCL)) {
+			cy_writel(&ch_ctrl[channel].rs_control,
+				(uclong)(cy_readl(&ch_ctrl[channel].rs_control)&
+					~(C_RS_RTS | C_RS_DTR)));
+			retval = cyz_issue_cmd(&cy_card[info->card], channel,
+					C_CM_IOCTLM, 0L);
+			if (retval != 0) {
+				printk("cyc:shutdown retval on ttyC%d was %x\n",
+					info->line, retval);
+			}
 #ifdef CY_DEBUG_DTR
-		printk("cyc:shutdown dropping Z DTR\n");
+			printk("cyc:shutdown dropping Z DTR\n");
 #endif
-	    }
-	    
-	    if (info->tty){
-		set_bit(TTY_IO_ERROR, &info->tty->flags);
-	    }
-	    info->flags &= ~ASYNC_INITIALIZED;
+		}
 
-	CY_UNLOCK(info, flags);
-    }
+		if (info->tty) {
+			set_bit(TTY_IO_ERROR, &info->tty->flags);
+		}
+		info->flags &= ~ASYNC_INITIALIZED;
+
+		CY_UNLOCK(info, flags);
+	}
 
 #ifdef CY_DEBUG_OPEN
-    printk(" cyc shutdown done\n");
+	printk(" cyc shutdown done\n");
 #endif
-    return;
-} /* shutdown */
-
+}				/* shutdown */
 
 /*
  * ------------------------------------------------------------
@@ -2261,527 +2321,546 @@ shutdown(struct cyclades_port * info)
  */
 
 static int
-block_til_ready(struct tty_struct *tty, struct file * filp,
-                           struct cyclades_port *info)
+block_til_ready(struct tty_struct *tty, struct file *filp,
+		struct cyclades_port *info)
 {
-  DECLARE_WAITQUEUE(wait, current);
-  struct cyclades_card *cinfo;
-  unsigned long flags;
-  int chip, channel,index;
-  int retval;
-  void __iomem *base_addr;
-
-    cinfo = &cy_card[info->card];
-    channel = info->line - cinfo->first_line;
-
-    /*
-     * If the device is in the middle of being closed, then block
-     * until it's done, and then try again.
-     */
-    if (tty_hung_up_p(filp) || (info->flags & ASYNC_CLOSING)) {
-	if (info->flags & ASYNC_CLOSING) {
-            interruptible_sleep_on(&info->close_wait);
+	DECLARE_WAITQUEUE(wait, current);
+	struct cyclades_card *cinfo;
+	unsigned long flags;
+	int chip, channel, index;
+	int retval;
+	void __iomem *base_addr;
+
+	cinfo = &cy_card[info->card];
+	channel = info->line - cinfo->first_line;
+
+	/*
+	 * If the device is in the middle of being closed, then block
+	 * until it's done, and then try again.
+	 */
+	if (tty_hung_up_p(filp) || (info->flags & ASYNC_CLOSING)) {
+		if (info->flags & ASYNC_CLOSING) {
+			interruptible_sleep_on(&info->close_wait);
+		}
+		return (info->flags & ASYNC_HUP_NOTIFY) ? -EAGAIN: -ERESTARTSYS;
+	}
+
+	/*
+	 * If non-blocking mode is set, then make the check up front
+	 * and then exit.
+	 */
+	if ((filp->f_flags & O_NONBLOCK) || (tty->flags & (1 << TTY_IO_ERROR))) {
+		info->flags |= ASYNC_NORMAL_ACTIVE;
+		return 0;
 	}
-        return ((info->flags & ASYNC_HUP_NOTIFY) ? -EAGAIN : -ERESTARTSYS);
-    }
-
-    /*
-     * If non-blocking mode is set, then make the check up front
-     * and then exit.
-     */
-    if ((filp->f_flags & O_NONBLOCK) ||
-	(tty->flags & (1 << TTY_IO_ERROR))) {
-        info->flags |= ASYNC_NORMAL_ACTIVE;
-        return 0;
-    }
-
-    /*
-     * 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
-     * cy_close() knows when to free things.  We restore it upon
-     * exit, either normal or abnormal.
-     */
-    retval = 0;
-    add_wait_queue(&info->open_wait, &wait);
+
+	/*
+	 * 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
+	 * cy_close() knows when to free things.  We restore it upon
+	 * exit, either normal or abnormal.
+	 */
+	retval = 0;
+	add_wait_queue(&info->open_wait, &wait);
 #ifdef CY_DEBUG_OPEN
-    printk("cyc block_til_ready before block: ttyC%d, count = %d\n",
-           info->line, info->count);/**/
+	printk("cyc block_til_ready before block: ttyC%d, count = %d\n",
+		info->line, info->count);
+	/**/
 #endif
-    CY_LOCK(info, flags);
-    if (!tty_hung_up_p(filp))
-	info->count--;
-    CY_UNLOCK(info, flags);
+	CY_LOCK(info, flags);
+	if (!tty_hung_up_p(filp))
+		info->count--;
+	CY_UNLOCK(info, flags);
 #ifdef CY_DEBUG_COUNT
-    printk("cyc block_til_ready: (%d): decrementing count to %d\n",
-        current->pid, info->count);
+	printk("cyc block_til_ready: (%d): decrementing count to %d\n",
+		current->pid, info->count);
 #endif
-    info->blocked_open++;
-
-    if (!IS_CYC_Z(*cinfo)) {
-	chip = channel>>2;
-	channel &= 0x03;
-	index = cinfo->bus_index;
-	base_addr = cinfo->base_addr + (cy_chip_offset[chip]<<index);
-
-	while (1) {
-	    CY_LOCK(info, flags);
-		if ((tty->termios->c_cflag & CBAUD)){
-		    cy_writeb(base_addr+(CyCAR<<index), (u_char)channel);
-		    cy_writeb(base_addr+(CyMSVR1<<index), CyRTS);
-		    cy_writeb(base_addr+(CyMSVR2<<index), CyDTR);
+	info->blocked_open++;
+
+	if (!IS_CYC_Z(*cinfo)) {
+		chip = channel >> 2;
+		channel &= 0x03;
+		index = cinfo->bus_index;
+		base_addr = cinfo->base_addr + (cy_chip_offset[chip] << index);
+
+		while (1) {
+			CY_LOCK(info, flags);
+			if ((tty->termios->c_cflag & CBAUD)) {
+				cy_writeb(base_addr + (CyCAR << index),
+					  (u_char) channel);
+				cy_writeb(base_addr + (CyMSVR1 << index),
+					  CyRTS);
+				cy_writeb(base_addr + (CyMSVR2 << index),
+					  CyDTR);
 #ifdef CY_DEBUG_DTR
-		    printk("cyc:block_til_ready raising DTR\n");
-		    printk("     status: 0x%x, 0x%x\n",
-			cy_readb(base_addr+(CyMSVR1<<index)), 
-                        cy_readb(base_addr+(CyMSVR2<<index)));
+				printk("cyc:block_til_ready raising DTR\n");
+				printk("     status: 0x%x, 0x%x\n",
+					cy_readb(base_addr +
+						(CyMSVR1 << index)),
+					cy_readb(base_addr +
+						(CyMSVR2 << index)));
 #endif
-		}
-	    CY_UNLOCK(info, flags);
+			}
+			CY_UNLOCK(info, flags);
 
-	    set_current_state(TASK_INTERRUPTIBLE);
-	    if (tty_hung_up_p(filp)
-	    || !(info->flags & ASYNC_INITIALIZED) ){
-		retval = ((info->flags & ASYNC_HUP_NOTIFY) ? 
-		    -EAGAIN : -ERESTARTSYS);
-		break;
-	    }
+			set_current_state(TASK_INTERRUPTIBLE);
+			if (tty_hung_up_p(filp) ||
+					!(info->flags & ASYNC_INITIALIZED)) {
+				retval = ((info->flags & ASYNC_HUP_NOTIFY) ?
+					  -EAGAIN : -ERESTARTSYS);
+				break;
+			}
 
-	    CY_LOCK(info, flags);
-		cy_writeb(base_addr+(CyCAR<<index), (u_char)channel);
-		if (!(info->flags & ASYNC_CLOSING)
-		&& (C_CLOCAL(tty)
-		    || (cy_readb(base_addr+(CyMSVR1<<index)) & CyDCD))) {
+			CY_LOCK(info, flags);
+			cy_writeb(base_addr + (CyCAR << index),
+				  (u_char) channel);
+			if (!(info->flags & ASYNC_CLOSING) && (C_CLOCAL(tty) ||
+					(cy_readb(base_addr +
+						(CyMSVR1 << index)) & CyDCD))) {
+				CY_UNLOCK(info, flags);
+				break;
+			}
 			CY_UNLOCK(info, flags);
-			break;
-		}
-	    CY_UNLOCK(info, flags);
 
-	    if (signal_pending(current)) {
-		retval = -ERESTARTSYS;
-		break;
-	    }
+			if (signal_pending(current)) {
+				retval = -ERESTARTSYS;
+				break;
+			}
 #ifdef CY_DEBUG_OPEN
-	    printk("cyc block_til_ready blocking: ttyC%d, count = %d\n",
-		   info->line, info->count);/**/
+			printk("cyc block_til_ready blocking: ttyC%d, "
+					"count = %d\n",
+					info->line, info->count);
+			/**/
 #endif
-	    schedule();
-	}
-    } else {
-      struct FIRM_ID __iomem *firm_id;
-      struct ZFW_CTRL __iomem *zfw_ctrl;
-      struct BOARD_CTRL __iomem *board_ctrl;
-      struct CH_CTRL __iomem *ch_ctrl;
-      int retval;
-
-	base_addr = cinfo->base_addr;
-	firm_id = base_addr + ID_ADDRESS;
-        if (!ISZLOADED(*cinfo)){
-            current->state = TASK_RUNNING;
-	    remove_wait_queue(&info->open_wait, &wait);
-	    return -EINVAL;
-	}
-
-	zfw_ctrl = base_addr + (cy_readl(&firm_id->zfwctrl_addr) & 0xfffff);
-	board_ctrl = &zfw_ctrl->board_ctrl;
-	ch_ctrl = zfw_ctrl->ch_ctrl;
-
-	while (1) {
-	    if ((tty->termios->c_cflag & CBAUD)){
-		cy_writel(&ch_ctrl[channel].rs_control,
-			cy_readl(&ch_ctrl[channel].rs_control) |
-			(C_RS_RTS | C_RS_DTR));
-		retval = cyz_issue_cmd(&cy_card[info->card],
-				       channel, C_CM_IOCTLM, 0L);
-		if (retval != 0){
-		    printk("cyc:block_til_ready retval on ttyC%d was %x\n",
-			   info->line, retval);
+			schedule();
+		}
+	} else {
+		struct FIRM_ID __iomem *firm_id;
+		struct ZFW_CTRL __iomem *zfw_ctrl;
+		struct BOARD_CTRL __iomem *board_ctrl;
+		struct CH_CTRL __iomem *ch_ctrl;
+		int retval;
+
+		base_addr = cinfo->base_addr;
+		firm_id = base_addr + ID_ADDRESS;
+		if (!ISZLOADED(*cinfo)) {
+			current->state = TASK_RUNNING;
+			remove_wait_queue(&info->open_wait, &wait);
+			return -EINVAL;
 		}
+
+		zfw_ctrl = base_addr + (cy_readl(&firm_id->zfwctrl_addr) &
+				0xfffff);
+		board_ctrl = &zfw_ctrl->board_ctrl;
+		ch_ctrl = zfw_ctrl->ch_ctrl;
+
+		while (1) {
+			if ((tty->termios->c_cflag & CBAUD)) {
+				cy_writel(&ch_ctrl[channel].rs_control,
+					  cy_readl(&ch_ctrl[channel].
+						   rs_control) | (C_RS_RTS |
+								  C_RS_DTR));
+				retval = cyz_issue_cmd(&cy_card[info->card],
+						channel, C_CM_IOCTLM, 0L);
+				if (retval != 0) {
+					printk("cyc:block_til_ready retval on "
+						"ttyC%d was %x\n",
+						info->line, retval);
+				}
 #ifdef CY_DEBUG_DTR
-		printk("cyc:block_til_ready raising Z DTR\n");
+				printk("cyc:block_til_ready raising Z DTR\n");
 #endif
-	    }
+			}
 
-	    set_current_state(TASK_INTERRUPTIBLE);
-	    if (tty_hung_up_p(filp)
-	    || !(info->flags & ASYNC_INITIALIZED) ){
-		retval = ((info->flags & ASYNC_HUP_NOTIFY) ?
-		    -EAGAIN : -ERESTARTSYS);
-		break;
-	    }
-	    if (!(info->flags & ASYNC_CLOSING)
-	    && (C_CLOCAL(tty)
-	      || (cy_readl(&ch_ctrl[channel].rs_status) & C_RS_DCD))) {
-		break;
-	    }
-	    if (signal_pending(current)) {
-		retval = -ERESTARTSYS;
-		break;
-	    }
+			set_current_state(TASK_INTERRUPTIBLE);
+			if (tty_hung_up_p(filp) ||
+					!(info->flags & ASYNC_INITIALIZED)) {
+				retval = ((info->flags & ASYNC_HUP_NOTIFY) ?
+					  -EAGAIN : -ERESTARTSYS);
+				break;
+			}
+			if (!(info->flags & ASYNC_CLOSING) && (C_CLOCAL(tty) ||
+					(cy_readl(&ch_ctrl[channel].rs_status) &
+						C_RS_DCD))) {
+				break;
+			}
+			if (signal_pending(current)) {
+				retval = -ERESTARTSYS;
+				break;
+			}
 #ifdef CY_DEBUG_OPEN
-	    printk("cyc block_til_ready blocking: ttyC%d, count = %d\n",
-		   info->line, info->count);/**/
+			printk("cyc block_til_ready blocking: ttyC%d, "
+					"count = %d\n",
+					info->line, info->count);
+			/**/
 #endif
-	    schedule();
+			schedule();
+		}
 	}
-    }
-    current->state = TASK_RUNNING;
-    remove_wait_queue(&info->open_wait, &wait);
-    if (!tty_hung_up_p(filp)){
-	info->count++;
+	current->state = TASK_RUNNING;
+	remove_wait_queue(&info->open_wait, &wait);
+	if (!tty_hung_up_p(filp)) {
+		info->count++;
 #ifdef CY_DEBUG_COUNT
-	printk("cyc:block_til_ready (%d): incrementing count to %d\n",
-	    current->pid, info->count);
+		printk("cyc:block_til_ready (%d): incrementing count to %d\n",
+			current->pid, info->count);
 #endif
-    }
-    info->blocked_open--;
+	}
+	info->blocked_open--;
 #ifdef CY_DEBUG_OPEN
-    printk("cyc:block_til_ready after blocking: ttyC%d, count = %d\n",
-	   info->line, info->count);/**/
+	printk("cyc:block_til_ready after blocking: ttyC%d, count = %d\n",
+		info->line, info->count);
+	/**/
 #endif
-    if (retval)
-	return retval;
-    info->flags |= ASYNC_NORMAL_ACTIVE;
-    return 0;
-} /* block_til_ready */
-
+	if (retval)
+		return retval;
+	info->flags |= ASYNC_NORMAL_ACTIVE;
+	return 0;
+}				/* block_til_ready */
 
 /*
  * This routine is called whenever a serial port is opened.  It
  * performs the serial-specific initialization for the tty structure.
  */
-static int
-cy_open(struct tty_struct *tty, struct file * filp)
+static int cy_open(struct tty_struct *tty, struct file *filp)
 {
-  struct cyclades_port  *info;
-  int retval, line;
-
-    line = tty->index;
-    if ((line < 0) || (NR_PORTS <= line)){
-        return -ENODEV;
-    }
-    info = &cy_port[line];
-    if (info->line < 0){
-        return -ENODEV;
-    }
-    
-    /* If the card's firmware hasn't been loaded,
-       treat it as absent from the system.  This
-       will make the user pay attention.
-    */
-    if (IS_CYC_Z(cy_card[info->card])) {
-	struct cyclades_card *cinfo = &cy_card[info->card];
-	struct FIRM_ID __iomem *firm_id = cinfo->base_addr + ID_ADDRESS;
-
-        if (!ISZLOADED(*cinfo)) {
-	    if (((ZE_V1 ==cy_readl(&((struct RUNTIME_9060 __iomem *)
-		(cinfo->ctl_addr))->mail_box_0)) &&
-		Z_FPGA_CHECK (*cinfo)) &&
-		(ZFIRM_HLT == cy_readl (&firm_id->signature)))
-	    {
-		printk ("cyc:Cyclades-Z Error: you need an external power supply for this number of ports.\n\rFirmware halted.\r\n");
-	    } else {
-		printk("cyc:Cyclades-Z firmware not yet loaded\n");
-	    }
-	    return -ENODEV;
-	}
-#ifdef CONFIG_CYZ_INTR
-	else {
-	    /* In case this Z board is operating in interrupt mode, its 
-	       interrupts should be enabled as soon as the first open happens 
-	       to one of its ports. */
-            if (!cinfo->intr_enabled) {
-		struct ZFW_CTRL __iomem *zfw_ctrl;
-		struct BOARD_CTRL __iomem *board_ctrl;
-
-		zfw_ctrl = cinfo->base_addr + (cy_readl (&firm_id->zfwctrl_addr) & 0xfffff);
+	struct cyclades_port *info;
+	int retval, line;
 
-		board_ctrl = &zfw_ctrl->board_ctrl;
+	line = tty->index;
+	if ((line < 0) || (NR_PORTS <= line)) {
+		return -ENODEV;
+	}
+	info = &cy_port[line];
+	if (info->line < 0) {
+		return -ENODEV;
+	}
 
-		/* Enable interrupts on the PLX chip */
-		cy_writew(cinfo->ctl_addr+0x68,
-			cy_readw(cinfo->ctl_addr+0x68)|0x0900);
-		/* Enable interrupts on the FW */
-		retval = cyz_issue_cmd(cinfo,
-					0, C_CM_IRQ_ENBL, 0L);
-		if (retval != 0){
-		    printk("cyc:IRQ enable retval was %x\n", retval);
+	/* If the card's firmware hasn't been loaded,
+	   treat it as absent from the system.  This
+	   will make the user pay attention.
+	 */
+	if (IS_CYC_Z(cy_card[info->card])) {
+		struct cyclades_card *cinfo = &cy_card[info->card];
+		struct FIRM_ID __iomem *firm_id = cinfo->base_addr + ID_ADDRESS;
+
+		if (!ISZLOADED(*cinfo)) {
+			if (((ZE_V1 == cy_readl(
+					&((struct RUNTIME_9060 __iomem *)
+					 (cinfo->ctl_addr))->mail_box_0)) &&
+					Z_FPGA_CHECK(*cinfo)) &&
+					(ZFIRM_HLT == cy_readl(
+						&firm_id->signature))) {
+				printk("cyc:Cyclades-Z Error: you need an "
+					"external power supply for this number "
+					"of ports.\n\rFirmware halted.\r\n");
+			} else {
+				printk("cyc:Cyclades-Z firmware not yet "
+					"loaded\n");
+			}
+			return -ENODEV;
 		}
-		cinfo->nports = (int) cy_readl (&board_ctrl->n_channel);
-		cinfo->intr_enabled = 1;
-	    }
+#ifdef CONFIG_CYZ_INTR
+		else {
+		/* In case this Z board is operating in interrupt mode, its
+		   interrupts should be enabled as soon as the first open
+		   happens to one of its ports. */
+			if (!cinfo->intr_enabled) {
+				struct ZFW_CTRL __iomem *zfw_ctrl;
+				struct BOARD_CTRL __iomem *board_ctrl;
+
+				zfw_ctrl = cinfo->base_addr +
+					(cy_readl(&firm_id->zfwctrl_addr) &
+						0xfffff);
+
+				board_ctrl = &zfw_ctrl->board_ctrl;
+
+				/* Enable interrupts on the PLX chip */
+				cy_writew(cinfo->ctl_addr + 0x68,
+					  cy_readw(cinfo->ctl_addr +
+						   0x68) | 0x0900);
+				/* Enable interrupts on the FW */
+				retval = cyz_issue_cmd(cinfo, 0,
+						C_CM_IRQ_ENBL, 0L);
+				if (retval != 0) {
+					printk("cyc:IRQ enable retval was %x\n",
+						retval);
+				}
+				cinfo->nports =
+					(int)cy_readl(&board_ctrl->n_channel);
+				cinfo->intr_enabled = 1;
+			}
+		}
+#endif				/* CONFIG_CYZ_INTR */
+		/* Make sure this Z port really exists in hardware */
+		if (info->line > (cinfo->first_line + cinfo->nports - 1))
+			return -ENODEV;
 	}
-#endif /* CONFIG_CYZ_INTR */
-	/* Make sure this Z port really exists in hardware */
-	if (info->line > (cinfo->first_line + cinfo->nports - 1))
-		return -ENODEV;
-    }
 #ifdef CY_DEBUG_OTHER
-    printk("cyc:cy_open ttyC%d\n", info->line); /* */
+	printk("cyc:cy_open ttyC%d\n", info->line);	/* */
 #endif
-    tty->driver_data = info;
-    info->tty = tty;
-    if (serial_paranoia_check(info, tty->name, "cy_open")){
-        return -ENODEV;
-    }
+	tty->driver_data = info;
+	info->tty = tty;
+	if (serial_paranoia_check(info, tty->name, "cy_open")) {
+		return -ENODEV;
+	}
 #ifdef CY_DEBUG_OPEN
-    printk("cyc:cy_open ttyC%d, count = %d\n",
-        info->line, info->count);/**/
+	printk("cyc:cy_open ttyC%d, count = %d\n", info->line, info->count);
+	/**/
 #endif
-    info->count++;
+	info->count++;
 #ifdef CY_DEBUG_COUNT
-    printk("cyc:cy_open (%d): incrementing count to %d\n",
-        current->pid, info->count);
+	printk("cyc:cy_open (%d): incrementing count to %d\n",
+		current->pid, info->count);
 #endif
 
-    /*
-     * If the port is the middle of closing, bail out now
-     */
-    if (tty_hung_up_p(filp) || (info->flags & ASYNC_CLOSING)) {
-	if (info->flags & ASYNC_CLOSING)
-	    interruptible_sleep_on(&info->close_wait);
-	return ((info->flags & ASYNC_HUP_NOTIFY) ? -EAGAIN : -ERESTARTSYS);
-    }
-
-    /*
-     * Start up serial port
-     */
-    retval = startup(info);
-    if (retval){
-        return retval;
-    }
-
-    retval = block_til_ready(tty, filp, info);
-    if (retval) {
-#ifdef CY_DEBUG_OPEN
-        printk("cyc:cy_open returning after block_til_ready with %d\n",
-               retval);
-#endif
-        return retval;
-    }
+	/*
+	 * If the port is the middle of closing, bail out now
+	 */
+	if (tty_hung_up_p(filp) || (info->flags & ASYNC_CLOSING)) {
+		if (info->flags & ASYNC_CLOSING)
+			interruptible_sleep_on(&info->close_wait);
+		return (info->flags & ASYNC_HUP_NOTIFY) ? -EAGAIN: -ERESTARTSYS;
+	}
 
-    info->throttle = 0;
+	/*
+	 * Start up serial port
+	 */
+	retval = startup(info);
+	if (retval) {
+		return retval;
+	}
 
+	retval = block_til_ready(tty, filp, info);
+	if (retval) {
 #ifdef CY_DEBUG_OPEN
-    printk(" cyc:cy_open done\n");/**/
+		printk("cyc:cy_open returning after block_til_ready with %d\n",
+			retval);
 #endif
+		return retval;
+	}
 
-    return 0;
-} /* cy_open */
+	info->throttle = 0;
 
+#ifdef CY_DEBUG_OPEN
+	printk(" cyc:cy_open done\n");
+	/**/
+#endif
+	return 0;
+}				/* cy_open */
 
 /*
  * cy_wait_until_sent() --- wait until the transmitter is empty
  */
-static void 
-cy_wait_until_sent(struct tty_struct *tty, int timeout)
+static void cy_wait_until_sent(struct tty_struct *tty, int timeout)
 {
-  struct cyclades_port * info = (struct cyclades_port *)tty->driver_data;
-  void __iomem *base_addr;
-  int card,chip,channel,index;
-  unsigned long orig_jiffies;
-  int char_time;
-	
-    if (serial_paranoia_check(info, tty->name, "cy_wait_until_sent"))
-	return;
-
-    if (info->xmit_fifo_size == 0)
-	return; /* Just in case.... */
-
-
-    orig_jiffies = jiffies;
-    /*
-     * Set the check interval to be 1/5 of the estimated time to
-     * send a single character, and make it at least 1.  The check
-     * interval should also be less than the timeout.
-     * 
-     * Note: we have to use pretty tight timings here to satisfy
-     * the NIST-PCTS.
-     */
-    char_time = (info->timeout - HZ/50) / info->xmit_fifo_size;
-    char_time = char_time / 5;
-    if (char_time <= 0)
-	char_time = 1;
-    if (timeout < 0)
-	timeout = 0;
-    if (timeout)
-	char_time = min(char_time, timeout);
-    /*
-     * If the transmitter hasn't cleared in twice the approximate
-     * amount of time to send the entire FIFO, it probably won't
-     * ever clear.  This assumes the UART isn't doing flow
-     * control, which is currently the case.  Hence, if it ever
-     * takes longer than info->timeout, this is probably due to a
-     * UART bug of some kind.  So, we clamp the timeout parameter at
-     * 2*info->timeout.
-     */
-    if (!timeout || timeout > 2*info->timeout)
-	timeout = 2*info->timeout;
+	struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
+	void __iomem *base_addr;
+	int card, chip, channel, index;
+	unsigned long orig_jiffies;
+	int char_time;
+
+	if (serial_paranoia_check(info, tty->name, "cy_wait_until_sent"))
+		return;
+
+	if (info->xmit_fifo_size == 0)
+		return;		/* Just in case.... */
+
+	orig_jiffies = jiffies;
+	/*
+	 * Set the check interval to be 1/5 of the estimated time to
+	 * send a single character, and make it at least 1.  The check
+	 * interval should also be less than the timeout.
+	 *
+	 * Note: we have to use pretty tight timings here to satisfy
+	 * the NIST-PCTS.
+	 */
+	char_time = (info->timeout - HZ / 50) / info->xmit_fifo_size;
+	char_time = char_time / 5;
+	if (char_time <= 0)
+		char_time = 1;
+	if (timeout < 0)
+		timeout = 0;
+	if (timeout)
+		char_time = min(char_time, timeout);
+	/*
+	 * If the transmitter hasn't cleared in twice the approximate
+	 * amount of time to send the entire FIFO, it probably won't
+	 * ever clear.  This assumes the UART isn't doing flow
+	 * control, which is currently the case.  Hence, if it ever
+	 * takes longer than info->timeout, this is probably due to a
+	 * UART bug of some kind.  So, we clamp the timeout parameter at
+	 * 2*info->timeout.
+	 */
+	if (!timeout || timeout > 2 * info->timeout)
+		timeout = 2 * info->timeout;
 #ifdef CY_DEBUG_WAIT_UNTIL_SENT
-    printk("In cy_wait_until_sent(%d) check=%lu...", timeout, char_time);
-    printk("jiff=%lu...", jiffies);
+	printk("In cy_wait_until_sent(%d) check=%lu...", timeout, char_time);
+	printk("jiff=%lu...", jiffies);
 #endif
-    card = info->card;
-    channel = (info->line) - (cy_card[card].first_line);
-    if (!IS_CYC_Z(cy_card[card])) {
-	chip = channel>>2;
-	channel &= 0x03;
-	index = cy_card[card].bus_index;
-	base_addr = cy_card[card].base_addr + (cy_chip_offset[chip]<<index);
-	while (cy_readb(base_addr+(CySRER<<index)) & CyTxRdy) {
+	card = info->card;
+	channel = (info->line) - (cy_card[card].first_line);
+	if (!IS_CYC_Z(cy_card[card])) {
+		chip = channel >> 2;
+		channel &= 0x03;
+		index = cy_card[card].bus_index;
+		base_addr =
+		    cy_card[card].base_addr + (cy_chip_offset[chip] << index);
+		while (cy_readb(base_addr + (CySRER << index)) & CyTxRdy) {
 #ifdef CY_DEBUG_WAIT_UNTIL_SENT
-	    printk("Not clean (jiff=%lu)...", jiffies);
+			printk("Not clean (jiff=%lu)...", jiffies);
 #endif
-	    if (msleep_interruptible(jiffies_to_msecs(char_time)))
-		break;
-	    if (timeout && time_after(jiffies, orig_jiffies + timeout))
-		break;
+			if (msleep_interruptible(jiffies_to_msecs(char_time)))
+				break;
+			if (timeout && time_after(jiffies, orig_jiffies +
+					timeout))
+				break;
+		}
+	} else {
+		/* Nothing to do! */
 	}
-    } else {
-	// Nothing to do!
-    }
-    /* Run one more char cycle */
-    msleep_interruptible(jiffies_to_msecs(char_time * 5));
+	/* Run one more char cycle */
+	msleep_interruptible(jiffies_to_msecs(char_time * 5));
 #ifdef CY_DEBUG_WAIT_UNTIL_SENT
-    printk("Clean (jiff=%lu)...done\n", jiffies);
+	printk("Clean (jiff=%lu)...done\n", jiffies);
 #endif
 }
 
 /*
  * This routine is called when a particular tty device is closed.
  */
-static void
-cy_close(struct tty_struct *tty, struct file *filp)
+static void cy_close(struct tty_struct *tty, struct file *filp)
 {
-  struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
-  unsigned long flags;
+	struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
+	unsigned long flags;
 
 #ifdef CY_DEBUG_OTHER
-    printk("cyc:cy_close ttyC%d\n", info->line);
+	printk("cyc:cy_close ttyC%d\n", info->line);
 #endif
 
-    if (!info || serial_paranoia_check(info, tty->name, "cy_close")){
-        return;
-    }
+	if (!info || serial_paranoia_check(info, tty->name, "cy_close")) {
+		return;
+	}
 
-    CY_LOCK(info, flags);
-    /* If the TTY is being hung up, nothing to do */
-    if (tty_hung_up_p(filp)) {
-	CY_UNLOCK(info, flags);
-        return;
-    }
-        
+	CY_LOCK(info, flags);
+	/* If the TTY is being hung up, nothing to do */
+	if (tty_hung_up_p(filp)) {
+		CY_UNLOCK(info, flags);
+		return;
+	}
 #ifdef CY_DEBUG_OPEN
-    printk("cyc:cy_close ttyC%d, count = %d\n", info->line, info->count);
+	printk("cyc:cy_close ttyC%d, count = %d\n", info->line, info->count);
 #endif
-    if ((tty->count == 1) && (info->count != 1)) {
-        /*
-         * Uh, oh.  tty->count is 1, which means that the tty
-         * structure will be freed.  Info->count should always
-         * be one in these conditions.  If it's greater than
-         * one, we've got real problems, since it means the
-         * serial port won't be shutdown.
-         */
-        printk("cyc:cy_close: bad serial port count; tty->count is 1, "
-           "info->count is %d\n", info->count);
-        info->count = 1;
-    }
+	if ((tty->count == 1) && (info->count != 1)) {
+		/*
+		 * Uh, oh.  tty->count is 1, which means that the tty
+		 * structure will be freed.  Info->count should always
+		 * be one in these conditions.  If it's greater than
+		 * one, we've got real problems, since it means the
+		 * serial port won't be shutdown.
+		 */
+		printk("cyc:cy_close: bad serial port count; tty->count is 1, "
+			"info->count is %d\n", info->count);
+		info->count = 1;
+	}
 #ifdef CY_DEBUG_COUNT
-    printk("cyc:cy_close at (%d): decrementing count to %d\n",
-        current->pid, info->count - 1);
+	printk("cyc:cy_close at (%d): decrementing count to %d\n",
+		current->pid, info->count - 1);
 #endif
-    if (--info->count < 0) {
+	if (--info->count < 0) {
 #ifdef CY_DEBUG_COUNT
-    printk("cyc:cyc_close setting count to 0\n");
+		printk("cyc:cyc_close setting count to 0\n");
 #endif
-        info->count = 0;
-    }
-    if (info->count) {
-	CY_UNLOCK(info, flags);
-        return;
-    }
-    info->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;
-    CY_UNLOCK(info, flags);
-    if (info->closing_wait != CY_CLOSING_WAIT_NONE) {
-	tty_wait_until_sent(tty, info->closing_wait);
-    }
-    CY_LOCK(info, flags);
-
-    if (!IS_CYC_Z(cy_card[info->card])) {
-	int channel = info->line - cy_card[info->card].first_line;
-	int index = cy_card[info->card].bus_index;
-	void __iomem *base_addr = cy_card[info->card].base_addr + (cy_chip_offset[channel>>2] << index);
-	/* Stop accepting input */
-	channel &= 0x03;
-	cy_writeb(base_addr+(CyCAR<<index), (u_char)channel);
-	cy_writeb(base_addr+(CySRER<<index),
-			cy_readb(base_addr+(CySRER<<index)) & ~CyRxData);
-	if (info->flags & ASYNC_INITIALIZED) {
-	    /* Waiting for on-board buffers to be empty before closing 
-	       the port */
-	    CY_UNLOCK(info, flags);
-	    cy_wait_until_sent(tty, info->timeout);
-	    CY_LOCK(info, flags);
+		info->count = 0;
 	}
-    } else {
-#ifdef Z_WAKE
-	/* Waiting for on-board buffers to be empty before closing the port */
-	void __iomem *base_addr = cy_card[info->card].base_addr;
-	struct FIRM_ID __iomem *firm_id = base_addr + ID_ADDRESS;
-	struct ZFW_CTRL __iomem *zfw_ctrl = base_addr + (cy_readl(&firm_id->zfwctrl_addr) & 0xfffff);
-	struct CH_CTRL __iomem *ch_ctrl = zfw_ctrl->ch_ctrl;
-	int channel = info->line - cy_card[info->card].first_line;
-	int retval;
+	if (info->count) {
+		CY_UNLOCK(info, flags);
+		return;
+	}
+	info->flags |= ASYNC_CLOSING;
 
-	if (cy_readl(&ch_ctrl[channel].flow_status) != C_FS_TXIDLE) {
-	    retval = cyz_issue_cmd(&cy_card[info->card], channel, 
-				   C_CM_IOCTLW, 0L);
-	    if (retval != 0){
-		printk("cyc:cy_close retval on ttyC%d was %x\n",
-		       info->line, retval);
-	    }
-	    CY_UNLOCK(info, flags);
-	    interruptible_sleep_on(&info->shutdown_wait);
-	    CY_LOCK(info, flags);
+	/*
+	 * Now we wait for the transmit buffer to clear; and we notify
+	 * the line discipline to only process XON/XOFF characters.
+	 */
+	tty->closing = 1;
+	CY_UNLOCK(info, flags);
+	if (info->closing_wait != CY_CLOSING_WAIT_NONE) {
+		tty_wait_until_sent(tty, info->closing_wait);
 	}
+	CY_LOCK(info, flags);
+
+	if (!IS_CYC_Z(cy_card[info->card])) {
+		int channel = info->line - cy_card[info->card].first_line;
+		int index = cy_card[info->card].bus_index;
+		void __iomem *base_addr = cy_card[info->card].base_addr +
+			(cy_chip_offset[channel >> 2] << index);
+		/* Stop accepting input */
+		channel &= 0x03;
+		cy_writeb(base_addr + (CyCAR << index), (u_char) channel);
+		cy_writeb(base_addr + (CySRER << index),
+			  cy_readb(base_addr + (CySRER << index)) & ~CyRxData);
+		if (info->flags & ASYNC_INITIALIZED) {
+			/* Waiting for on-board buffers to be empty before closing
+			   the port */
+			CY_UNLOCK(info, flags);
+			cy_wait_until_sent(tty, info->timeout);
+			CY_LOCK(info, flags);
+		}
+	} else {
+#ifdef Z_WAKE
+		/* Waiting for on-board buffers to be empty before closing the port */
+		void __iomem *base_addr = cy_card[info->card].base_addr;
+		struct FIRM_ID __iomem *firm_id = base_addr + ID_ADDRESS;
+		struct ZFW_CTRL __iomem *zfw_ctrl =
+		    base_addr + (cy_readl(&firm_id->zfwctrl_addr) & 0xfffff);
+		struct CH_CTRL __iomem *ch_ctrl = zfw_ctrl->ch_ctrl;
+		int channel = info->line - cy_card[info->card].first_line;
+		int retval;
+
+		if (cy_readl(&ch_ctrl[channel].flow_status) != C_FS_TXIDLE) {
+			retval = cyz_issue_cmd(&cy_card[info->card], channel,
+						C_CM_IOCTLW, 0L);
+			if (retval != 0) {
+				printk("cyc:cy_close retval on ttyC%d was %x\n",
+					info->line, retval);
+			}
+			CY_UNLOCK(info, flags);
+			interruptible_sleep_on(&info->shutdown_wait);
+			CY_LOCK(info, flags);
+		}
 #endif
-    }
-
-    CY_UNLOCK(info, flags);
-    shutdown(info);
-    if (tty->driver->flush_buffer)
-        tty->driver->flush_buffer(tty);
-    tty_ldisc_flush(tty);        
-    CY_LOCK(info, flags);
-
-    tty->closing = 0;
-    info->event = 0;
-    info->tty = NULL;
-    if (info->blocked_open) {
+	}
+
 	CY_UNLOCK(info, flags);
-        if (info->close_delay) {
-            msleep_interruptible(jiffies_to_msecs(info->close_delay));
-        }
-        wake_up_interruptible(&info->open_wait);
+	shutdown(info);
+	if (tty->driver->flush_buffer)
+		tty->driver->flush_buffer(tty);
+	tty_ldisc_flush(tty);
 	CY_LOCK(info, flags);
-    }
-    info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
-    wake_up_interruptible(&info->close_wait);
+
+	tty->closing = 0;
+	info->event = 0;
+	info->tty = NULL;
+	if (info->blocked_open) {
+		CY_UNLOCK(info, flags);
+		if (info->close_delay) {
+			msleep_interruptible(jiffies_to_msecs
+						(info->close_delay));
+		}
+		wake_up_interruptible(&info->open_wait);
+		CY_LOCK(info, flags);
+	}
+	info->flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING);
+	wake_up_interruptible(&info->close_wait);
 
 #ifdef CY_DEBUG_OTHER
-    printk(" cyc:cy_close done\n");
+	printk(" cyc:cy_close done\n");
 #endif
 
-    CY_UNLOCK(info, flags);
-    return;
-} /* cy_close */
-
+	CY_UNLOCK(info, flags);
+}				/* cy_close */
 
 /* This routine gets called when tty_write has put something into
  * the write_queue.  The characters may come from user space or
@@ -2796,50 +2875,49 @@ cy_close(struct tty_struct *tty, struct file *filp)
  * If the port is already active, there is no need to kick it.
  *
  */
-static int
-cy_write(struct tty_struct * tty, const unsigned char *buf, int count)
+static int cy_write(struct tty_struct *tty, const unsigned char *buf, int count)
 {
-  struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
-  unsigned long flags;
-  int c, ret = 0;
+	struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
+	unsigned long flags;
+	int c, ret = 0;
 
 #ifdef CY_DEBUG_IO
-    printk("cyc:cy_write ttyC%d\n", info->line); /* */
+	printk("cyc:cy_write ttyC%d\n", info->line);	/* */
 #endif
 
-    if (serial_paranoia_check(info, tty->name, "cy_write")){
-        return 0;
-    }
-        
-    if (!info->xmit_buf)
-	return 0;
+	if (serial_paranoia_check(info, tty->name, "cy_write")) {
+		return 0;
+	}
 
-    CY_LOCK(info, flags);
-    while (1) {
-	c = min(count, min((int)(SERIAL_XMIT_SIZE - info->xmit_cnt - 1),
-			(int)(SERIAL_XMIT_SIZE - info->xmit_head)));
-	        
-	if (c <= 0)
-	    break;
-
-	memcpy(info->xmit_buf + info->xmit_head, buf, c);
-	info->xmit_head = (info->xmit_head + c) & (SERIAL_XMIT_SIZE-1);
-	info->xmit_cnt += c;
-	buf += c;
-	count -= c;
-	ret += c;
-    }
-    CY_UNLOCK(info, flags);
-
-    info->idle_stats.xmit_bytes += ret;
-    info->idle_stats.xmit_idle   = jiffies;
-
-    if (info->xmit_cnt && !tty->stopped && !tty->hw_stopped) {
-        start_xmit(info);
-    }
-    return ret;
-} /* cy_write */
+	if (!info->xmit_buf)
+		return 0;
 
+	CY_LOCK(info, flags);
+	while (1) {
+		c = min(count, min((int)(SERIAL_XMIT_SIZE - info->xmit_cnt - 1),
+				   (int)(SERIAL_XMIT_SIZE - info->xmit_head)));
+
+		if (c <= 0)
+			break;
+
+		memcpy(info->xmit_buf + info->xmit_head, buf, c);
+		info->xmit_head = (info->xmit_head + c) &
+			(SERIAL_XMIT_SIZE - 1);
+		info->xmit_cnt += c;
+		buf += c;
+		count -= c;
+		ret += c;
+	}
+	CY_UNLOCK(info, flags);
+
+	info->idle_stats.xmit_bytes += ret;
+	info->idle_stats.xmit_idle = jiffies;
+
+	if (info->xmit_cnt && !tty->stopped && !tty->hw_stopped) {
+		start_xmit(info);
+	}
+	return ret;
+}				/* cy_write */
 
 /*
  * This routine is called by the kernel to write a single
@@ -2848,60 +2926,56 @@ cy_write(struct tty_struct * tty, const unsigned char *buf, int count)
  * done stuffing characters into the driver.  If there is no room
  * in the queue, the character is ignored.
  */
-static void
-cy_put_char(struct tty_struct *tty, unsigned char ch)
+static void cy_put_char(struct tty_struct *tty, unsigned char ch)
 {
-  struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
-  unsigned long flags;
+	struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
+	unsigned long flags;
 
 #ifdef CY_DEBUG_IO
-    printk("cyc:cy_put_char ttyC%d\n", info->line);
+	printk("cyc:cy_put_char ttyC%d\n", info->line);
 #endif
 
-    if (serial_paranoia_check(info, tty->name, "cy_put_char"))
-        return;
+	if (serial_paranoia_check(info, tty->name, "cy_put_char"))
+		return;
 
-    if (!info->xmit_buf)
-        return;
+	if (!info->xmit_buf)
+		return;
 
-    CY_LOCK(info, flags);
-        if (info->xmit_cnt >= SERIAL_XMIT_SIZE - 1) {
-	    CY_UNLOCK(info, flags);
-            return;
-        }
+	CY_LOCK(info, flags);
+	if (info->xmit_cnt >= (int)(SERIAL_XMIT_SIZE - 1)) {
+		CY_UNLOCK(info, flags);
+		return;
+	}
 
-        info->xmit_buf[info->xmit_head++] = ch;
-        info->xmit_head &= SERIAL_XMIT_SIZE - 1;
-        info->xmit_cnt++;
+	info->xmit_buf[info->xmit_head++] = ch;
+	info->xmit_head &= SERIAL_XMIT_SIZE - 1;
+	info->xmit_cnt++;
 	info->idle_stats.xmit_bytes++;
 	info->idle_stats.xmit_idle = jiffies;
-    CY_UNLOCK(info, flags);
-} /* cy_put_char */
-
+	CY_UNLOCK(info, flags);
+}				/* cy_put_char */
 
 /*
  * This routine is called by the kernel after it has written a
  * series of characters to the tty device using put_char().  
  */
-static void
-cy_flush_chars(struct tty_struct *tty)
+static void cy_flush_chars(struct tty_struct *tty)
 {
-  struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
-                                
+	struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
+
 #ifdef CY_DEBUG_IO
-    printk("cyc:cy_flush_chars ttyC%d\n", info->line); /* */
+	printk("cyc:cy_flush_chars ttyC%d\n", info->line);	/* */
 #endif
 
-    if (serial_paranoia_check(info, tty->name, "cy_flush_chars"))
-        return;
-
-    if (info->xmit_cnt <= 0 || tty->stopped
-    || tty->hw_stopped || !info->xmit_buf)
-        return;
+	if (serial_paranoia_check(info, tty->name, "cy_flush_chars"))
+		return;
 
-    start_xmit(info);
-} /* cy_flush_chars */
+	if (info->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped ||
+			!info->xmit_buf)
+		return;
 
+	start_xmit(info);
+}				/* cy_flush_chars */
 
 /*
  * This routine returns the numbers of characters the tty driver
@@ -2909,75 +2983,70 @@ cy_flush_chars(struct tty_struct *tty)
  * to change as output buffers get emptied, or if the output flow
  * control is activated.
  */
-static int
-cy_write_room(struct tty_struct *tty)
+static int cy_write_room(struct tty_struct *tty)
 {
-  struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
-  int   ret;
-                                
+	struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
+	int ret;
+
 #ifdef CY_DEBUG_IO
-    printk("cyc:cy_write_room ttyC%d\n", info->line); /* */
+	printk("cyc:cy_write_room ttyC%d\n", info->line);	/* */
 #endif
 
-    if (serial_paranoia_check(info, tty->name, "cy_write_room"))
-        return 0;
-    ret = SERIAL_XMIT_SIZE - info->xmit_cnt - 1;
-    if (ret < 0)
-        ret = 0;
-    return ret;
-} /* cy_write_room */
-
+	if (serial_paranoia_check(info, tty->name, "cy_write_room"))
+		return 0;
+	ret = SERIAL_XMIT_SIZE - info->xmit_cnt - 1;
+	if (ret < 0)
+		ret = 0;
+	return ret;
+}				/* cy_write_room */
 
-static int
-cy_chars_in_buffer(struct tty_struct *tty)
+static int cy_chars_in_buffer(struct tty_struct *tty)
 {
-  struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
-  int card, channel;
-                                
-    if (serial_paranoia_check(info, tty->name, "cy_chars_in_buffer"))
-        return 0;
+	struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
+	int card, channel;
+
+	if (serial_paranoia_check(info, tty->name, "cy_chars_in_buffer"))
+		return 0;
 
-    card = info->card;
-    channel = (info->line) - (cy_card[card].first_line);
+	card = info->card;
+	channel = (info->line) - (cy_card[card].first_line);
 
 #ifdef Z_EXT_CHARS_IN_BUFFER
-    if (!IS_CYC_Z(cy_card[card])) {
-#endif /* Z_EXT_CHARS_IN_BUFFER */
+	if (!IS_CYC_Z(cy_card[card])) {
+#endif				/* Z_EXT_CHARS_IN_BUFFER */
 #ifdef CY_DEBUG_IO
-	printk("cyc:cy_chars_in_buffer ttyC%d %d\n",
-		info->line, info->xmit_cnt); /* */
+		printk("cyc:cy_chars_in_buffer ttyC%d %d\n", info->line, info->xmit_cnt);	/* */
 #endif
-	return info->xmit_cnt;
+		return info->xmit_cnt;
 #ifdef Z_EXT_CHARS_IN_BUFFER
-    } else {
-	static volatile struct FIRM_ID *firm_id;
-	static volatile struct ZFW_CTRL *zfw_ctrl;
-	static volatile struct CH_CTRL *ch_ctrl;
-	static volatile struct BUF_CTRL *buf_ctrl;
-	int char_count;
-	volatile uclong tx_put, tx_get, tx_bufsize;
-
-	firm_id = cy_card[card].base_addr + ID_ADDRESS;
-	zfw_ctrl = cy_card[card].base_addr + (cy_readl(&firm_id->zfwctrl_addr) & 0xfffff);
-	ch_ctrl = &(zfw_ctrl->ch_ctrl[channel]);
-	buf_ctrl = &(zfw_ctrl->buf_ctrl[channel]);
-
-	tx_get = cy_readl(&buf_ctrl->tx_get);
-	tx_put = cy_readl(&buf_ctrl->tx_put);
-	tx_bufsize = cy_readl(&buf_ctrl->tx_bufsize);
-	if (tx_put >= tx_get)
-	    char_count = tx_put - tx_get;
-	else
-	    char_count = tx_put - tx_get + tx_bufsize;
+	} else {
+		static volatile struct FIRM_ID *firm_id;
+		static volatile struct ZFW_CTRL *zfw_ctrl;
+		static volatile struct CH_CTRL *ch_ctrl;
+		static volatile struct BUF_CTRL *buf_ctrl;
+		int char_count;
+		volatile uclong tx_put, tx_get, tx_bufsize;
+
+		firm_id = cy_card[card].base_addr + ID_ADDRESS;
+		zfw_ctrl = cy_card[card].base_addr +
+			(cy_readl(&firm_id->zfwctrl_addr) & 0xfffff);
+		ch_ctrl = &(zfw_ctrl->ch_ctrl[channel]);
+		buf_ctrl = &(zfw_ctrl->buf_ctrl[channel]);
+
+		tx_get = cy_readl(&buf_ctrl->tx_get);
+		tx_put = cy_readl(&buf_ctrl->tx_put);
+		tx_bufsize = cy_readl(&buf_ctrl->tx_bufsize);
+		if (tx_put >= tx_get)
+			char_count = tx_put - tx_get;
+		else
+			char_count = tx_put - tx_get + tx_bufsize;
 #ifdef CY_DEBUG_IO
-	printk("cyc:cy_chars_in_buffer ttyC%d %d\n",
-		info->line, info->xmit_cnt + char_count); /* */
+		printk("cyc:cy_chars_in_buffer ttyC%d %d\n", info->line, info->xmit_cnt + char_count);	/* */
 #endif
-	return (info->xmit_cnt + char_count);
-    }
-#endif /* Z_EXT_CHARS_IN_BUFFER */
-} /* cy_chars_in_buffer */
-
+		return info->xmit_cnt + char_count;
+	}
+#endif				/* Z_EXT_CHARS_IN_BUFFER */
+}				/* cy_chars_in_buffer */
 
 /*
  * ------------------------------------------------------------
@@ -2985,178 +3054,179 @@ cy_chars_in_buffer(struct tty_struct *tty)
  * ------------------------------------------------------------
  */
 
-static void
-cyy_baud_calc(struct cyclades_port *info, uclong baud)
+static void cyy_baud_calc(struct cyclades_port *info, uclong baud)
 {
-    int co, co_val, bpr;
-    uclong cy_clock = ((info->chip_rev >= CD1400_REV_J) ? 60000000 : 25000000);
-
-    if (baud == 0) {
-	info->tbpr = info->tco = info->rbpr = info->rco = 0;
-	return;
-    }
-
-    /* determine which prescaler to use */
-    for (co = 4, co_val = 2048; co; co--, co_val >>= 2) {
-	if (cy_clock / co_val / baud > 63)
-	    break;
-    }
-
-    bpr = (cy_clock / co_val * 2 / baud + 1) / 2;
-    if (bpr > 255)
-	bpr = 255;
-
-    info->tbpr = info->rbpr = bpr;
-    info->tco = info->rco = co;
+	int co, co_val, bpr;
+	uclong cy_clock = ((info->chip_rev >= CD1400_REV_J) ? 60000000 :
+			25000000);
+
+	if (baud == 0) {
+		info->tbpr = info->tco = info->rbpr = info->rco = 0;
+		return;
+	}
+
+	/* determine which prescaler to use */
+	for (co = 4, co_val = 2048; co; co--, co_val >>= 2) {
+		if (cy_clock / co_val / baud > 63)
+			break;
+	}
+
+	bpr = (cy_clock / co_val * 2 / baud + 1) / 2;
+	if (bpr > 255)
+		bpr = 255;
+
+	info->tbpr = info->rbpr = bpr;
+	info->tco = info->rco = co;
 }
 
 /*
  * This routine finds or computes the various line characteristics.
  * It used to be called config_setup
  */
-static void
-set_line_char(struct cyclades_port * info)
+static void set_line_char(struct cyclades_port *info)
 {
-  unsigned long flags;
-  void __iomem *base_addr;
-  int card,chip,channel,index;
-  unsigned cflag, iflag;
-  unsigned short chip_number;
-  int baud, baud_rate = 0;
-  int   i;
-
-
-    if (!info->tty || !info->tty->termios){
-        return;
-    }
-    if (info->line == -1){
-        return;
-    }
-    cflag = info->tty->termios->c_cflag;
-    iflag = info->tty->termios->c_iflag;
-
-    /*
-     * Set up the tty->alt_speed kludge
-     */
-    if (info->tty) {
-	if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
-	    info->tty->alt_speed = 57600;
-	if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
-	    info->tty->alt_speed = 115200;
-	if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
-	    info->tty->alt_speed = 230400;
-	if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
-	    info->tty->alt_speed = 460800;
-    }
-
-    card = info->card;
-    channel = (info->line) - (cy_card[card].first_line);
-    chip_number = channel / 4;
-
-    if (!IS_CYC_Z(cy_card[card])) {
-
-	index = cy_card[card].bus_index;
-
-	/* baud rate */
-	baud = tty_get_baud_rate(info->tty);
-	if ((baud == 38400) &&
-	    ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)) {
-	    if (info->custom_divisor)
-		baud_rate = info->baud / info->custom_divisor;
-	    else
-		baud_rate = info->baud;
-	} else if (baud > CD1400_MAX_SPEED) {
-	    baud = CD1400_MAX_SPEED;
+	unsigned long flags;
+	void __iomem *base_addr;
+	int card, chip, channel, index;
+	unsigned cflag, iflag;
+	unsigned short chip_number;
+	int baud, baud_rate = 0;
+	int i;
+
+	if (!info->tty || !info->tty->termios) {
+		return;
 	}
-	/* find the baud index */
-	for (i = 0; i < 20; i++) {
-	    if (baud == baud_table[i]) {
-		break;
-	    }
+	if (info->line == -1) {
+		return;
 	}
-	if (i == 20) {
-	    i = 19; /* CD1400_MAX_SPEED */
-	} 
+	cflag = info->tty->termios->c_cflag;
+	iflag = info->tty->termios->c_iflag;
 
-	if ((baud == 38400) &&
-	    ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)) {
-	    cyy_baud_calc(info, baud_rate);
-	} else {
-	    if(info->chip_rev >= CD1400_REV_J) {
-		/* It is a CD1400 rev. J or later */
-		info->tbpr = baud_bpr_60[i]; /* Tx BPR */
-		info->tco = baud_co_60[i]; /* Tx CO */
-		info->rbpr = baud_bpr_60[i]; /* Rx BPR */
-		info->rco = baud_co_60[i]; /* Rx CO */
-	    } else {
-		info->tbpr = baud_bpr_25[i]; /* Tx BPR */
-		info->tco = baud_co_25[i]; /* Tx CO */
-		info->rbpr = baud_bpr_25[i]; /* Rx BPR */
-		info->rco = baud_co_25[i]; /* Rx CO */
-	    }
-	}
-	if (baud_table[i] == 134) {
-	    /* get it right for 134.5 baud */
-	    info->timeout = (info->xmit_fifo_size*HZ*30/269) + 2;
-	} else if ((baud == 38400) &&
-		   ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)) {
-	    info->timeout = (info->xmit_fifo_size*HZ*15/baud_rate) + 2;
-	} else if (baud_table[i]) {
-	    info->timeout = (info->xmit_fifo_size*HZ*15/baud_table[i]) + 2;
-	    /* this needs to be propagated into the card info */
-	} else {
-	    info->timeout = 0;
-	}
-	/* By tradition (is it a standard?) a baud rate of zero
-	   implies the line should be/has been closed.  A bit
-	   later in this routine such a test is performed. */
-
-	/* byte size and parity */
-	info->cor5 = 0;
-	info->cor4 = 0;
-	info->cor3 = (info->default_threshold
-		      ? info->default_threshold
-		      : baud_cor3[i]); /* receive threshold */
-	info->cor2 = CyETC;
-	switch(cflag & CSIZE){
-	case CS5:
-	    info->cor1 = Cy_5_BITS;
-	    break;
-	case CS6:
-	    info->cor1 = Cy_6_BITS;
-	    break;
-	case CS7:
-	    info->cor1 = Cy_7_BITS;
-	    break;
-	case CS8:
-	    info->cor1 = Cy_8_BITS;
-	    break;
-	}
-	if(cflag & CSTOPB){
-	    info->cor1 |= Cy_2_STOP;
-	}
-	if (cflag & PARENB){
-	    if (cflag & PARODD){
-		info->cor1 |= CyPARITY_O;
-	    }else{
-		info->cor1 |= CyPARITY_E;
-	    }
-	}else{
-	    info->cor1 |= CyPARITY_NONE;
-	}
-	    
-	/* CTS flow control flag */
-	if (cflag & CRTSCTS){
-	    info->flags |= ASYNC_CTS_FLOW;
-	    info->cor2 |= CyCtsAE;
-	}else{
-	    info->flags &= ~ASYNC_CTS_FLOW;
-	    info->cor2 &= ~CyCtsAE;
+	/*
+	 * Set up the tty->alt_speed kludge
+	 */
+	if (info->tty) {
+		if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
+			info->tty->alt_speed = 57600;
+		if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
+			info->tty->alt_speed = 115200;
+		if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
+			info->tty->alt_speed = 230400;
+		if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
+			info->tty->alt_speed = 460800;
 	}
-	if (cflag & CLOCAL)
-	    info->flags &= ~ASYNC_CHECK_CD;
-	else
-	    info->flags |= ASYNC_CHECK_CD;
+
+	card = info->card;
+	channel = (info->line) - (cy_card[card].first_line);
+	chip_number = channel / 4;
+
+	if (!IS_CYC_Z(cy_card[card])) {
+
+		index = cy_card[card].bus_index;
+
+		/* baud rate */
+		baud = tty_get_baud_rate(info->tty);
+		if (baud == 38400 && (info->flags & ASYNC_SPD_MASK) ==
+				ASYNC_SPD_CUST) {
+			if (info->custom_divisor)
+				baud_rate = info->baud / info->custom_divisor;
+			else
+				baud_rate = info->baud;
+		} else if (baud > CD1400_MAX_SPEED) {
+			baud = CD1400_MAX_SPEED;
+		}
+		/* find the baud index */
+		for (i = 0; i < 20; i++) {
+			if (baud == baud_table[i]) {
+				break;
+			}
+		}
+		if (i == 20) {
+			i = 19;	/* CD1400_MAX_SPEED */
+		}
+
+		if (baud == 38400 && (info->flags & ASYNC_SPD_MASK) ==
+				ASYNC_SPD_CUST) {
+			cyy_baud_calc(info, baud_rate);
+		} else {
+			if (info->chip_rev >= CD1400_REV_J) {
+				/* It is a CD1400 rev. J or later */
+				info->tbpr = baud_bpr_60[i];	/* Tx BPR */
+				info->tco = baud_co_60[i];	/* Tx CO */
+				info->rbpr = baud_bpr_60[i];	/* Rx BPR */
+				info->rco = baud_co_60[i];	/* Rx CO */
+			} else {
+				info->tbpr = baud_bpr_25[i];	/* Tx BPR */
+				info->tco = baud_co_25[i];	/* Tx CO */
+				info->rbpr = baud_bpr_25[i];	/* Rx BPR */
+				info->rco = baud_co_25[i];	/* Rx CO */
+			}
+		}
+		if (baud_table[i] == 134) {
+			/* get it right for 134.5 baud */
+			info->timeout = (info->xmit_fifo_size * HZ * 30 / 269) +
+					2;
+		} else if (baud == 38400 && (info->flags & ASYNC_SPD_MASK) ==
+				ASYNC_SPD_CUST) {
+			info->timeout = (info->xmit_fifo_size * HZ * 15 /
+					baud_rate) + 2;
+		} else if (baud_table[i]) {
+			info->timeout = (info->xmit_fifo_size * HZ * 15 /
+					baud_table[i]) + 2;
+			/* this needs to be propagated into the card info */
+		} else {
+			info->timeout = 0;
+		}
+		/* By tradition (is it a standard?) a baud rate of zero
+		   implies the line should be/has been closed.  A bit
+		   later in this routine such a test is performed. */
+
+		/* byte size and parity */
+		info->cor5 = 0;
+		info->cor4 = 0;
+		/* receive threshold */
+		info->cor3 = (info->default_threshold ?
+				info->default_threshold : baud_cor3[i]);
+		info->cor2 = CyETC;
+		switch (cflag & CSIZE) {
+		case CS5:
+			info->cor1 = Cy_5_BITS;
+			break;
+		case CS6:
+			info->cor1 = Cy_6_BITS;
+			break;
+		case CS7:
+			info->cor1 = Cy_7_BITS;
+			break;
+		case CS8:
+			info->cor1 = Cy_8_BITS;
+			break;
+		}
+		if (cflag & CSTOPB) {
+			info->cor1 |= Cy_2_STOP;
+		}
+		if (cflag & PARENB) {
+			if (cflag & PARODD) {
+				info->cor1 |= CyPARITY_O;
+			} else {
+				info->cor1 |= CyPARITY_E;
+			}
+		} else {
+			info->cor1 |= CyPARITY_NONE;
+		}
+
+		/* CTS flow control flag */
+		if (cflag & CRTSCTS) {
+			info->flags |= ASYNC_CTS_FLOW;
+			info->cor2 |= CyCtsAE;
+		} else {
+			info->flags &= ~ASYNC_CTS_FLOW;
+			info->cor2 &= ~CyCtsAE;
+		}
+		if (cflag & CLOCAL)
+			info->flags &= ~ASYNC_CHECK_CD;
+		else
+			info->flags |= ASYNC_CHECK_CD;
 
 	 /***********************************************
 	    The hardware option, CyRtsAO, presents RTS when
@@ -3168,300 +3238,319 @@ set_line_char(struct cyclades_port * info)
 	    cable.  Contact Marcio Saito for details.
 	 ***********************************************/
 
-	chip = channel>>2;
-	channel &= 0x03;
-	base_addr = cy_card[card].base_addr + (cy_chip_offset[chip]<<index);
+		chip = channel >> 2;
+		channel &= 0x03;
+		base_addr = cy_card[card].base_addr +
+			(cy_chip_offset[chip] << index);
 
-	CY_LOCK(info, flags);
-	    cy_writeb(base_addr+(CyCAR<<index), (u_char)channel);
-
-	   /* tx and rx baud rate */
-
-	    cy_writeb(base_addr+(CyTCOR<<index), info->tco);
-	    cy_writeb(base_addr+(CyTBPR<<index), info->tbpr);
-	    cy_writeb(base_addr+(CyRCOR<<index), info->rco);
-	    cy_writeb(base_addr+(CyRBPR<<index), info->rbpr);
-
-	    /* set line characteristics  according configuration */
-
-	    cy_writeb(base_addr+(CySCHR1<<index), 
-		      START_CHAR(info->tty));
-	    cy_writeb(base_addr+(CySCHR2<<index), 
-		      STOP_CHAR(info->tty));
-	    cy_writeb(base_addr+(CyCOR1<<index), info->cor1);
-	    cy_writeb(base_addr+(CyCOR2<<index), info->cor2);
-	    cy_writeb(base_addr+(CyCOR3<<index), info->cor3);
-	    cy_writeb(base_addr+(CyCOR4<<index), info->cor4);
-	    cy_writeb(base_addr+(CyCOR5<<index), info->cor5);
-
-	    cyy_issue_cmd(base_addr,
-		     CyCOR_CHANGE|CyCOR1ch|CyCOR2ch|CyCOR3ch,index);
-
-	    cy_writeb(base_addr+(CyCAR<<index), 
-		      (u_char)channel); /* !!! Is this needed? */
-	    cy_writeb(base_addr+(CyRTPR<<index), (info->default_timeout
-					         ? info->default_timeout
-					         : 0x02)); /* 10ms rx timeout */
-
-	    if (C_CLOCAL(info->tty)) {
-		/* without modem intr */
-		cy_writeb(base_addr+(CySRER<<index),
-                   cy_readb(base_addr+(CySRER<<index)) | CyMdmCh); 
-					/* act on 1->0 modem transitions */
-                if ((cflag & CRTSCTS) && info->rflow) {
-                        cy_writeb(base_addr+(CyMCOR1<<index), 
-                                  (CyCTS|rflow_thr[i]));
-                } else {
-                        cy_writeb(base_addr+(CyMCOR1<<index), CyCTS);
-                }
-					/* act on 0->1 modem transitions */
-		cy_writeb(base_addr+(CyMCOR2<<index), CyCTS);
-	    } else {
-		/* without modem intr */
-		cy_writeb(base_addr+(CySRER<<index),
-                   cy_readb(base_addr+(CySRER<<index)) | CyMdmCh); 
-					/* act on 1->0 modem transitions */
-                if ((cflag & CRTSCTS) && info->rflow) {
-			cy_writeb(base_addr+(CyMCOR1<<index), 
-        	                  (CyDSR|CyCTS|CyRI|CyDCD|rflow_thr[i]));
-                } else {
-			cy_writeb(base_addr+(CyMCOR1<<index), 
-                                  CyDSR|CyCTS|CyRI|CyDCD);
-                }
-					/* act on 0->1 modem transitions */
-		cy_writeb(base_addr+(CyMCOR2<<index), 
-			  CyDSR|CyCTS|CyRI|CyDCD);
-	    }
-
-	    if(i == 0){ /* baud rate is zero, turn off line */
-	        if (info->rtsdtr_inv) {
-			cy_writeb(base_addr+(CyMSVR1<<index), ~CyRTS);
+		CY_LOCK(info, flags);
+		cy_writeb(base_addr + (CyCAR << index), (u_char) channel);
+
+		/* tx and rx baud rate */
+
+		cy_writeb(base_addr + (CyTCOR << index), info->tco);
+		cy_writeb(base_addr + (CyTBPR << index), info->tbpr);
+		cy_writeb(base_addr + (CyRCOR << index), info->rco);
+		cy_writeb(base_addr + (CyRBPR << index), info->rbpr);
+
+		/* set line characteristics  according configuration */
+
+		cy_writeb(base_addr + (CySCHR1 << index),
+			  START_CHAR(info->tty));
+		cy_writeb(base_addr + (CySCHR2 << index), STOP_CHAR(info->tty));
+		cy_writeb(base_addr + (CyCOR1 << index), info->cor1);
+		cy_writeb(base_addr + (CyCOR2 << index), info->cor2);
+		cy_writeb(base_addr + (CyCOR3 << index), info->cor3);
+		cy_writeb(base_addr + (CyCOR4 << index), info->cor4);
+		cy_writeb(base_addr + (CyCOR5 << index), info->cor5);
+
+		cyy_issue_cmd(base_addr, CyCOR_CHANGE | CyCOR1ch | CyCOR2ch |
+				CyCOR3ch, index);
+
+		cy_writeb(base_addr + (CyCAR << index), (u_char) channel);	/* !!! Is this needed? */
+		cy_writeb(base_addr + (CyRTPR << index),
+			(info->default_timeout ? info->default_timeout : 0x02));
+		/* 10ms rx timeout */
+
+		if (C_CLOCAL(info->tty)) {
+			/* without modem intr */
+			cy_writeb(base_addr + (CySRER << index),
+				  cy_readb(base_addr +
+					   (CySRER << index)) | CyMdmCh);
+			/* act on 1->0 modem transitions */
+			if ((cflag & CRTSCTS) && info->rflow) {
+				cy_writeb(base_addr + (CyMCOR1 << index),
+					  (CyCTS | rflow_thr[i]));
+			} else {
+				cy_writeb(base_addr + (CyMCOR1 << index),
+					  CyCTS);
+			}
+			/* act on 0->1 modem transitions */
+			cy_writeb(base_addr + (CyMCOR2 << index), CyCTS);
 		} else {
-                        cy_writeb(base_addr+(CyMSVR2<<index), ~CyDTR);
+			/* without modem intr */
+			cy_writeb(base_addr + (CySRER << index),
+				  cy_readb(base_addr +
+					   (CySRER << index)) | CyMdmCh);
+			/* act on 1->0 modem transitions */
+			if ((cflag & CRTSCTS) && info->rflow) {
+				cy_writeb(base_addr + (CyMCOR1 << index),
+					  (CyDSR | CyCTS | CyRI | CyDCD |
+					   rflow_thr[i]));
+			} else {
+				cy_writeb(base_addr + (CyMCOR1 << index),
+					  CyDSR | CyCTS | CyRI | CyDCD);
+			}
+			/* act on 0->1 modem transitions */
+			cy_writeb(base_addr + (CyMCOR2 << index),
+				  CyDSR | CyCTS | CyRI | CyDCD);
 		}
+
+		if (i == 0) {	/* baud rate is zero, turn off line */
+			if (info->rtsdtr_inv) {
+				cy_writeb(base_addr + (CyMSVR1 << index),
+					  ~CyRTS);
+			} else {
+				cy_writeb(base_addr + (CyMSVR2 << index),
+					  ~CyDTR);
+			}
 #ifdef CY_DEBUG_DTR
-		printk("cyc:set_line_char dropping DTR\n");
-		printk("     status: 0x%x, 0x%x\n", 
-		    cy_readb(base_addr+(CyMSVR1<<index)),
-		    cy_readb(base_addr+(CyMSVR2<<index)));
+			printk("cyc:set_line_char dropping DTR\n");
+			printk("     status: 0x%x, 0x%x\n",
+				cy_readb(base_addr + (CyMSVR1 << index)),
+				cy_readb(base_addr + (CyMSVR2 << index)));
 #endif
-	    }else{
-                if (info->rtsdtr_inv) {
-			cy_writeb(base_addr+(CyMSVR1<<index), CyRTS);
-                } else {
-			cy_writeb(base_addr+(CyMSVR2<<index), CyDTR);
-                }
+		} else {
+			if (info->rtsdtr_inv) {
+				cy_writeb(base_addr + (CyMSVR1 << index),
+					  CyRTS);
+			} else {
+				cy_writeb(base_addr + (CyMSVR2 << index),
+					  CyDTR);
+			}
 #ifdef CY_DEBUG_DTR
-		printk("cyc:set_line_char raising DTR\n");
-		printk("     status: 0x%x, 0x%x\n",
-		    cy_readb(base_addr+(CyMSVR1<<index)),
-		    cy_readb(base_addr+(CyMSVR2<<index)));
+			printk("cyc:set_line_char raising DTR\n");
+			printk("     status: 0x%x, 0x%x\n",
+				cy_readb(base_addr + (CyMSVR1 << index)),
+				cy_readb(base_addr + (CyMSVR2 << index)));
 #endif
-	    }
-
-	    if (info->tty){
-		clear_bit(TTY_IO_ERROR, &info->tty->flags);
-	    }
-	CY_UNLOCK(info, flags);
+		}
 
-    } else {
-      struct FIRM_ID __iomem *firm_id;
-      struct ZFW_CTRL __iomem *zfw_ctrl;
-      struct BOARD_CTRL __iomem *board_ctrl;
-      struct CH_CTRL __iomem *ch_ctrl;
-      struct BUF_CTRL __iomem *buf_ctrl;
-      uclong sw_flow;
-      int retval;
-
-        firm_id = cy_card[card].base_addr + ID_ADDRESS;
-        if (!ISZLOADED(cy_card[card])) {
-	    return;
-	}
+		if (info->tty) {
+			clear_bit(TTY_IO_ERROR, &info->tty->flags);
+		}
+		CY_UNLOCK(info, flags);
 
-	zfw_ctrl = cy_card[card].base_addr + (cy_readl(&firm_id->zfwctrl_addr) & 0xfffff);
-	board_ctrl = &zfw_ctrl->board_ctrl;
-	ch_ctrl = &(zfw_ctrl->ch_ctrl[channel]);
-	buf_ctrl = &zfw_ctrl->buf_ctrl[channel];
-
-	/* baud rate */
-	baud = tty_get_baud_rate(info->tty);
-	if ((baud == 38400) &&
-	    ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)) {
-	    if (info->custom_divisor)
-		baud_rate = info->baud / info->custom_divisor;
-	    else
-		baud_rate = info->baud;
-	} else if (baud > CYZ_MAX_SPEED) {
-	    baud = CYZ_MAX_SPEED;
-	}
-	cy_writel(&ch_ctrl->comm_baud , baud);
-
-	if (baud == 134) {
-	    /* get it right for 134.5 baud */
-	    info->timeout = (info->xmit_fifo_size*HZ*30/269) + 2;
-	} else if ((baud == 38400) &&
-		   ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)) {
-	    info->timeout = (info->xmit_fifo_size*HZ*15/baud_rate) + 2;
-	} else if (baud) {
-	    info->timeout = (info->xmit_fifo_size*HZ*15/baud) + 2;
-	    /* this needs to be propagated into the card info */
 	} else {
-	    info->timeout = 0;
-	}
+		struct FIRM_ID __iomem *firm_id;
+		struct ZFW_CTRL __iomem *zfw_ctrl;
+		struct BOARD_CTRL __iomem *board_ctrl;
+		struct CH_CTRL __iomem *ch_ctrl;
+		struct BUF_CTRL __iomem *buf_ctrl;
+		uclong sw_flow;
+		int retval;
+
+		firm_id = cy_card[card].base_addr + ID_ADDRESS;
+		if (!ISZLOADED(cy_card[card])) {
+			return;
+		}
 
-	/* byte size and parity */
-	switch(cflag & CSIZE){
-	case CS5: cy_writel(&ch_ctrl->comm_data_l , C_DL_CS5); break;
-	case CS6: cy_writel(&ch_ctrl->comm_data_l , C_DL_CS6); break;
-	case CS7: cy_writel(&ch_ctrl->comm_data_l , C_DL_CS7); break;
-	case CS8: cy_writel(&ch_ctrl->comm_data_l , C_DL_CS8); break;
-	}
-	if(cflag & CSTOPB){
-	    cy_writel(&ch_ctrl->comm_data_l,
-               cy_readl(&ch_ctrl->comm_data_l) | C_DL_2STOP);
-	}else{
-	    cy_writel(&ch_ctrl->comm_data_l,
-               cy_readl(&ch_ctrl->comm_data_l) | C_DL_1STOP);
-	}
-	if (cflag & PARENB){
-	    if (cflag & PARODD){
-		cy_writel(&ch_ctrl->comm_parity , C_PR_ODD);
-	    }else{
-		cy_writel(&ch_ctrl->comm_parity , C_PR_EVEN);
-	    }
-	}else{
-	    cy_writel(&ch_ctrl->comm_parity , C_PR_NONE);
-	}
+		zfw_ctrl = cy_card[card].base_addr +
+			(cy_readl(&firm_id->zfwctrl_addr) & 0xfffff);
+		board_ctrl = &zfw_ctrl->board_ctrl;
+		ch_ctrl = &(zfw_ctrl->ch_ctrl[channel]);
+		buf_ctrl = &zfw_ctrl->buf_ctrl[channel];
+
+		/* baud rate */
+		baud = tty_get_baud_rate(info->tty);
+		if (baud == 38400 && (info->flags & ASYNC_SPD_MASK) ==
+				ASYNC_SPD_CUST) {
+			if (info->custom_divisor)
+				baud_rate = info->baud / info->custom_divisor;
+			else
+				baud_rate = info->baud;
+		} else if (baud > CYZ_MAX_SPEED) {
+			baud = CYZ_MAX_SPEED;
+		}
+		cy_writel(&ch_ctrl->comm_baud, baud);
+
+		if (baud == 134) {
+			/* get it right for 134.5 baud */
+			info->timeout = (info->xmit_fifo_size * HZ * 30 / 269) +
+					2;
+		} else if (baud == 38400 && (info->flags & ASYNC_SPD_MASK) ==
+				ASYNC_SPD_CUST) {
+			info->timeout = (info->xmit_fifo_size * HZ * 15 /
+					baud_rate) + 2;
+		} else if (baud) {
+			info->timeout = (info->xmit_fifo_size * HZ * 15 /
+					baud) + 2;
+			/* this needs to be propagated into the card info */
+		} else {
+			info->timeout = 0;
+		}
 
-	/* CTS flow control flag */
-	if (cflag & CRTSCTS){
-	    cy_writel(&ch_ctrl->hw_flow,
-               cy_readl(&ch_ctrl->hw_flow) | C_RS_CTS | C_RS_RTS);
-	}else{
-	    cy_writel(&ch_ctrl->hw_flow,
-               cy_readl(&ch_ctrl->hw_flow) & ~(C_RS_CTS | C_RS_RTS));
-	}
-	/* As the HW flow control is done in firmware, the driver doesn't
-	   need to care about it */
-	info->flags &= ~ASYNC_CTS_FLOW;
-
-	/* XON/XOFF/XANY flow control flags */
-	sw_flow = 0;
-	if (iflag & IXON){
-	    sw_flow |= C_FL_OXX;
-	    if (iflag & IXANY)
-		sw_flow |= C_FL_OIXANY;
-	}
-	cy_writel(&ch_ctrl->sw_flow, sw_flow);
+		/* byte size and parity */
+		switch (cflag & CSIZE) {
+		case CS5:
+			cy_writel(&ch_ctrl->comm_data_l, C_DL_CS5);
+			break;
+		case CS6:
+			cy_writel(&ch_ctrl->comm_data_l, C_DL_CS6);
+			break;
+		case CS7:
+			cy_writel(&ch_ctrl->comm_data_l, C_DL_CS7);
+			break;
+		case CS8:
+			cy_writel(&ch_ctrl->comm_data_l, C_DL_CS8);
+			break;
+		}
+		if (cflag & CSTOPB) {
+			cy_writel(&ch_ctrl->comm_data_l,
+				  cy_readl(&ch_ctrl->comm_data_l) | C_DL_2STOP);
+		} else {
+			cy_writel(&ch_ctrl->comm_data_l,
+				  cy_readl(&ch_ctrl->comm_data_l) | C_DL_1STOP);
+		}
+		if (cflag & PARENB) {
+			if (cflag & PARODD) {
+				cy_writel(&ch_ctrl->comm_parity, C_PR_ODD);
+			} else {
+				cy_writel(&ch_ctrl->comm_parity, C_PR_EVEN);
+			}
+		} else {
+			cy_writel(&ch_ctrl->comm_parity, C_PR_NONE);
+		}
 
-	retval = cyz_issue_cmd(&cy_card[card], channel, C_CM_IOCTL, 0L);
-	if (retval != 0){
-	    printk("cyc:set_line_char retval on ttyC%d was %x\n",
-		   info->line, retval);
-	}
+		/* CTS flow control flag */
+		if (cflag & CRTSCTS) {
+			cy_writel(&ch_ctrl->hw_flow,
+				  cy_readl(&ch_ctrl->
+					   hw_flow) | C_RS_CTS | C_RS_RTS);
+		} else {
+			cy_writel(&ch_ctrl->hw_flow,
+				  cy_readl(&ch_ctrl->
+					   hw_flow) & ~(C_RS_CTS | C_RS_RTS));
+		}
+		/* As the HW flow control is done in firmware, the driver
+		   doesn't need to care about it */
+		info->flags &= ~ASYNC_CTS_FLOW;
+
+		/* XON/XOFF/XANY flow control flags */
+		sw_flow = 0;
+		if (iflag & IXON) {
+			sw_flow |= C_FL_OXX;
+			if (iflag & IXANY)
+				sw_flow |= C_FL_OIXANY;
+		}
+		cy_writel(&ch_ctrl->sw_flow, sw_flow);
 
-	/* CD sensitivity */
-	if (cflag & CLOCAL){
-	    info->flags &= ~ASYNC_CHECK_CD;
-	}else{
-	    info->flags |= ASYNC_CHECK_CD;
-	}
+		retval = cyz_issue_cmd(&cy_card[card], channel, C_CM_IOCTL, 0L);
+		if (retval != 0) {
+			printk("cyc:set_line_char retval on ttyC%d was %x\n",
+				info->line, retval);
+		}
+
+		/* CD sensitivity */
+		if (cflag & CLOCAL) {
+			info->flags &= ~ASYNC_CHECK_CD;
+		} else {
+			info->flags |= ASYNC_CHECK_CD;
+		}
 
-	if(baud == 0){ /* baud rate is zero, turn off line */
-	    cy_writel(&ch_ctrl->rs_control,
-               cy_readl(&ch_ctrl->rs_control) & ~C_RS_DTR);
+		if (baud == 0) {	/* baud rate is zero, turn off line */
+			cy_writel(&ch_ctrl->rs_control,
+				  cy_readl(&ch_ctrl->rs_control) & ~C_RS_DTR);
 #ifdef CY_DEBUG_DTR
-	    printk("cyc:set_line_char dropping Z DTR\n");
+			printk("cyc:set_line_char dropping Z DTR\n");
 #endif
-	}else{
-	    cy_writel(&ch_ctrl->rs_control,
-               cy_readl(&ch_ctrl->rs_control) | C_RS_DTR);
+		} else {
+			cy_writel(&ch_ctrl->rs_control,
+				  cy_readl(&ch_ctrl->rs_control) | C_RS_DTR);
 #ifdef CY_DEBUG_DTR
-	    printk("cyc:set_line_char raising Z DTR\n");
+			printk("cyc:set_line_char raising Z DTR\n");
 #endif
-	}
+		}
 
-	retval = cyz_issue_cmd( &cy_card[card], channel, C_CM_IOCTLM, 0L);
-	if (retval != 0){
-	    printk("cyc:set_line_char(2) retval on ttyC%d was %x\n",
-		   info->line, retval);
-	}
+		retval = cyz_issue_cmd(&cy_card[card], channel, C_CM_IOCTLM,0L);
+		if (retval != 0) {
+			printk("cyc:set_line_char(2) retval on ttyC%d was %x\n",
+				info->line, retval);
+		}
 
-	if (info->tty){
-	    clear_bit(TTY_IO_ERROR, &info->tty->flags);
+		if (info->tty) {
+			clear_bit(TTY_IO_ERROR, &info->tty->flags);
+		}
 	}
-    }
-} /* set_line_char */
-
+}				/* set_line_char */
 
 static int
-get_serial_info(struct cyclades_port * info,
-                           struct serial_struct __user * retinfo)
+get_serial_info(struct cyclades_port *info,
+		struct serial_struct __user * retinfo)
 {
-  struct serial_struct tmp;
-  struct cyclades_card *cinfo = &cy_card[info->card];
-
-    if (!retinfo)
-            return -EFAULT;
-    memset(&tmp, 0, sizeof(tmp));
-    tmp.type = info->type;
-    tmp.line = info->line;
-    tmp.port = info->card * 0x100 + info->line - cinfo->first_line;
-    tmp.irq = cinfo->irq;
-    tmp.flags = info->flags;
-    tmp.close_delay = info->close_delay;
-    tmp.baud_base = info->baud;
-    tmp.custom_divisor = info->custom_divisor;
-    tmp.hub6 = 0;               /*!!!*/
-    return copy_to_user(retinfo,&tmp,sizeof(*retinfo))?-EFAULT:0;
-} /* get_serial_info */
+	struct serial_struct tmp;
+	struct cyclades_card *cinfo = &cy_card[info->card];
 
+	if (!retinfo)
+		return -EFAULT;
+	memset(&tmp, 0, sizeof(tmp));
+	tmp.type = info->type;
+	tmp.line = info->line;
+	tmp.port = info->card * 0x100 + info->line - cinfo->first_line;
+	tmp.irq = cinfo->irq;
+	tmp.flags = info->flags;
+	tmp.close_delay = info->close_delay;
+	tmp.baud_base = info->baud;
+	tmp.custom_divisor = info->custom_divisor;
+	tmp.hub6 = 0;		/*!!! */
+	return copy_to_user(retinfo, &tmp, sizeof(*retinfo)) ? -EFAULT : 0;
+}				/* get_serial_info */
 
 static int
-set_serial_info(struct cyclades_port * info,
-                           struct serial_struct __user * new_info)
+set_serial_info(struct cyclades_port *info,
+		struct serial_struct __user * new_info)
 {
-  struct serial_struct new_serial;
-  struct cyclades_port old_info;
-
-    if (copy_from_user(&new_serial,new_info,sizeof(new_serial)))
-	return -EFAULT;
-    old_info = *info;
-
-    if (!capable(CAP_SYS_ADMIN)) {
-            if ((new_serial.close_delay != info->close_delay) ||
-		(new_serial.baud_base != info->baud) ||
-		((new_serial.flags & ASYNC_FLAGS & ~ASYNC_USR_MASK) !=
-		 (info->flags & ASYNC_FLAGS & ~ASYNC_USR_MASK)))
-                    return -EPERM;
-            info->flags = ((info->flags & ~ASYNC_USR_MASK) |
-                           (new_serial.flags & ASYNC_USR_MASK));
-            info->baud = new_serial.baud_base;
-	    info->custom_divisor = new_serial.custom_divisor;
-            goto check_and_exit;
-    }
-
-
-    /*
-     * OK, past this point, all the error checking has been done.
-     * At this point, we start making changes.....
-     */
-
-    info->baud = new_serial.baud_base;
-    info->custom_divisor = new_serial.custom_divisor;
-    info->flags = ((info->flags & ~ASYNC_FLAGS) |
-                    (new_serial.flags & ASYNC_FLAGS));
-    info->close_delay = new_serial.close_delay * HZ/100;
-    info->closing_wait = new_serial.closing_wait * HZ/100;
+	struct serial_struct new_serial;
+	struct cyclades_port old_info;
+
+	if (copy_from_user(&new_serial, new_info, sizeof(new_serial)))
+		return -EFAULT;
+	old_info = *info;
+
+	if (!capable(CAP_SYS_ADMIN)) {
+		if (new_serial.close_delay != info->close_delay ||
+				new_serial.baud_base != info->baud ||
+				(new_serial.flags & ASYNC_FLAGS &
+					~ASYNC_USR_MASK) !=
+				(info->flags & ASYNC_FLAGS & ~ASYNC_USR_MASK))
+			return -EPERM;
+		info->flags = (info->flags & ~ASYNC_USR_MASK) |
+				(new_serial.flags & ASYNC_USR_MASK);
+		info->baud = new_serial.baud_base;
+		info->custom_divisor = new_serial.custom_divisor;
+		goto check_and_exit;
+	}
+
+	/*
+	 * OK, past this point, all the error checking has been done.
+	 * At this point, we start making changes.....
+	 */
+
+	info->baud = new_serial.baud_base;
+	info->custom_divisor = new_serial.custom_divisor;
+	info->flags = (info->flags & ~ASYNC_FLAGS) |
+			(new_serial.flags & ASYNC_FLAGS);
+	info->close_delay = new_serial.close_delay * HZ / 100;
+	info->closing_wait = new_serial.closing_wait * HZ / 100;
 
 check_and_exit:
-    if (info->flags & ASYNC_INITIALIZED){
-        set_line_char(info);
-        return 0;
-    }else{
-        return startup(info);
-    }
-} /* set_serial_info */
+	if (info->flags & ASYNC_INITIALIZED) {
+		set_line_char(info);
+		return 0;
+	} else {
+		return startup(info);
+	}
+}				/* set_serial_info */
 
 /*
  * get_lsr_info - get line status register info
@@ -3473,441 +3562,452 @@ check_and_exit:
  *	    transmit holding register is empty.  This functionality
  *	    allows an RS485 driver to be written in user space.
  */
-static int get_lsr_info(struct cyclades_port *info, unsigned int __user *value)
+static int get_lsr_info(struct cyclades_port *info, unsigned int __user * value)
 {
-    int card, chip, channel, index;
-    unsigned char status;
-    unsigned int result;
-    unsigned long flags;
-    void __iomem *base_addr;
-
-    card = info->card;
-    channel = (info->line) - (cy_card[card].first_line);
-    if (!IS_CYC_Z(cy_card[card])) {
-	chip = channel>>2;
-	channel &= 0x03;
-	index = cy_card[card].bus_index;
-	base_addr = cy_card[card].base_addr + (cy_chip_offset[chip]<<index);
+	int card, chip, channel, index;
+	unsigned char status;
+	unsigned int result;
+	unsigned long flags;
+	void __iomem *base_addr;
 
-	CY_LOCK(info, flags);
-	status = cy_readb(base_addr+(CySRER<<index)) & (CyTxRdy|CyTxMpty);
-	CY_UNLOCK(info, flags);
-	result = (status ? 0 : TIOCSER_TEMT);
-    } else {
-	/* Not supported yet */
-	return -EINVAL;
-    }
-    return put_user(result, (unsigned long __user *) value);
+	card = info->card;
+	channel = (info->line) - (cy_card[card].first_line);
+	if (!IS_CYC_Z(cy_card[card])) {
+		chip = channel >> 2;
+		channel &= 0x03;
+		index = cy_card[card].bus_index;
+		base_addr =
+		    cy_card[card].base_addr + (cy_chip_offset[chip] << index);
+
+		CY_LOCK(info, flags);
+		status = cy_readb(base_addr + (CySRER << index)) &
+				(CyTxRdy | CyTxMpty);
+		CY_UNLOCK(info, flags);
+		result = (status ? 0 : TIOCSER_TEMT);
+	} else {
+		/* Not supported yet */
+		return -EINVAL;
+	}
+	return put_user(result, (unsigned long __user *)value);
 }
 
-static int
-cy_tiocmget(struct tty_struct *tty, struct file *file)
+static int cy_tiocmget(struct tty_struct *tty, struct file *file)
 {
-  struct cyclades_port * info = (struct cyclades_port *)tty->driver_data;
-  int card,chip,channel,index;
-  void __iomem *base_addr;
-  unsigned long flags;
-  unsigned char status;
-  unsigned long lstatus;
-  unsigned int result;
-  struct FIRM_ID __iomem *firm_id;
-  struct ZFW_CTRL __iomem *zfw_ctrl;
-  struct BOARD_CTRL __iomem *board_ctrl;
-  struct CH_CTRL __iomem *ch_ctrl;
-
-    if (serial_paranoia_check(info, tty->name, __FUNCTION__))
-	return -ENODEV;
-
-    card = info->card;
-    channel = (info->line) - (cy_card[card].first_line);
-    if (!IS_CYC_Z(cy_card[card])) {
-	chip = channel>>2;
-	channel &= 0x03;
-	index = cy_card[card].bus_index;
-	base_addr = cy_card[card].base_addr + (cy_chip_offset[chip]<<index);
+	struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
+	int card, chip, channel, index;
+	void __iomem *base_addr;
+	unsigned long flags;
+	unsigned char status;
+	unsigned long lstatus;
+	unsigned int result;
+	struct FIRM_ID __iomem *firm_id;
+	struct ZFW_CTRL __iomem *zfw_ctrl;
+	struct BOARD_CTRL __iomem *board_ctrl;
+	struct CH_CTRL __iomem *ch_ctrl;
+
+	if (serial_paranoia_check(info, tty->name, __FUNCTION__))
+		return -ENODEV;
 
-	CY_LOCK(info, flags);
-	    cy_writeb(base_addr+(CyCAR<<index), (u_char)channel);
-	    status = cy_readb(base_addr+(CyMSVR1<<index));
-	    status |= cy_readb(base_addr+(CyMSVR2<<index));
-	CY_UNLOCK(info, flags);
+	card = info->card;
+	channel = (info->line) - (cy_card[card].first_line);
+	if (!IS_CYC_Z(cy_card[card])) {
+		chip = channel >> 2;
+		channel &= 0x03;
+		index = cy_card[card].bus_index;
+		base_addr =
+		    cy_card[card].base_addr + (cy_chip_offset[chip] << index);
 
-        if (info->rtsdtr_inv) {
-	    result =  ((status  & CyRTS) ? TIOCM_DTR : 0)
-		    | ((status  & CyDTR) ? TIOCM_RTS : 0);
+		CY_LOCK(info, flags);
+		cy_writeb(base_addr + (CyCAR << index), (u_char) channel);
+		status = cy_readb(base_addr + (CyMSVR1 << index));
+		status |= cy_readb(base_addr + (CyMSVR2 << index));
+		CY_UNLOCK(info, flags);
+
+		if (info->rtsdtr_inv) {
+			result = ((status & CyRTS) ? TIOCM_DTR : 0) |
+				((status & CyDTR) ? TIOCM_RTS : 0);
+		} else {
+			result = ((status & CyRTS) ? TIOCM_RTS : 0) |
+				((status & CyDTR) ? TIOCM_DTR : 0);
+		}
+		result |= ((status & CyDCD) ? TIOCM_CAR : 0) |
+			((status & CyRI) ? TIOCM_RNG : 0) |
+			((status & CyDSR) ? TIOCM_DSR : 0) |
+			((status & CyCTS) ? TIOCM_CTS : 0);
 	} else {
-	    result =  ((status  & CyRTS) ? TIOCM_RTS : 0)
-		    | ((status  & CyDTR) ? TIOCM_DTR : 0);
-	}
-	result |=  ((status  & CyDCD) ? TIOCM_CAR : 0)
-		 | ((status  & CyRI) ? TIOCM_RNG : 0)
-		 | ((status  & CyDSR) ? TIOCM_DSR : 0)
-		 | ((status  & CyCTS) ? TIOCM_CTS : 0);
-    } else {
-	base_addr = cy_card[card].base_addr;
-
-        if (cy_card[card].num_chips != -1){
-	    return -EINVAL;
-	}
+		base_addr = cy_card[card].base_addr;
 
-	firm_id = cy_card[card].base_addr + ID_ADDRESS;
-        if (ISZLOADED(cy_card[card])) {
-	    zfw_ctrl = cy_card[card].base_addr + (cy_readl(&firm_id->zfwctrl_addr) & 0xfffff);
-	    board_ctrl = &zfw_ctrl->board_ctrl;
-	    ch_ctrl = zfw_ctrl->ch_ctrl;
-	    lstatus = cy_readl(&ch_ctrl[channel].rs_status);
-	    result =  ((lstatus  & C_RS_RTS) ? TIOCM_RTS : 0)
-		    | ((lstatus  & C_RS_DTR) ? TIOCM_DTR : 0)
-	            | ((lstatus  & C_RS_DCD) ? TIOCM_CAR : 0)
-		    | ((lstatus  & C_RS_RI) ? TIOCM_RNG : 0)
-		    | ((lstatus  & C_RS_DSR) ? TIOCM_DSR : 0)
-		    | ((lstatus  & C_RS_CTS) ? TIOCM_CTS : 0);
-	}else{
-	    result = 0;
-	    return -ENODEV;
-	}
+		if (cy_card[card].num_chips != -1) {
+			return -EINVAL;
+		}
 
-    }
-    return result;
-} /* cy_tiomget */
+		firm_id = cy_card[card].base_addr + ID_ADDRESS;
+		if (ISZLOADED(cy_card[card])) {
+			zfw_ctrl = cy_card[card].base_addr +
+				(cy_readl(&firm_id->zfwctrl_addr) & 0xfffff);
+			board_ctrl = &zfw_ctrl->board_ctrl;
+			ch_ctrl = zfw_ctrl->ch_ctrl;
+			lstatus = cy_readl(&ch_ctrl[channel].rs_status);
+			result = ((lstatus & C_RS_RTS) ? TIOCM_RTS : 0) |
+				((lstatus & C_RS_DTR) ? TIOCM_DTR : 0) |
+				((lstatus & C_RS_DCD) ? TIOCM_CAR : 0) |
+				((lstatus & C_RS_RI) ? TIOCM_RNG : 0) |
+				((lstatus & C_RS_DSR) ? TIOCM_DSR : 0) |
+				((lstatus & C_RS_CTS) ? TIOCM_CTS : 0);
+		} else {
+			result = 0;
+			return -ENODEV;
+		}
 
+	}
+	return result;
+}				/* cy_tiomget */
 
 static int
 cy_tiocmset(struct tty_struct *tty, struct file *file,
-            unsigned int set, unsigned int clear)
+		unsigned int set, unsigned int clear)
 {
-  struct cyclades_port * info = (struct cyclades_port *)tty->driver_data;
-  int card,chip,channel,index;
-  void __iomem *base_addr;
-  unsigned long flags;
-  struct FIRM_ID __iomem *firm_id;
-  struct ZFW_CTRL __iomem *zfw_ctrl;
-  struct BOARD_CTRL __iomem *board_ctrl;
-  struct CH_CTRL __iomem *ch_ctrl;
-  int retval;
-
-    if (serial_paranoia_check(info, tty->name, __FUNCTION__))
-	return -ENODEV;
-
-    card = info->card;
-    channel = (info->line) - (cy_card[card].first_line);
-    if (!IS_CYC_Z(cy_card[card])) {
-	chip = channel>>2;
-	channel &= 0x03;
-	index = cy_card[card].bus_index;
-	base_addr = cy_card[card].base_addr + (cy_chip_offset[chip]<<index);
-
-	if (set & TIOCM_RTS){
-		CY_LOCK(info, flags);
-	        cy_writeb(base_addr+(CyCAR<<index), (u_char)channel);
-                if (info->rtsdtr_inv) {
-			cy_writeb(base_addr+(CyMSVR2<<index), CyDTR);
-                } else {
-			cy_writeb(base_addr+(CyMSVR1<<index), CyRTS);
-                }
-		CY_UNLOCK(info, flags);
-	}
-	if (clear & TIOCM_RTS) {
-		CY_LOCK(info, flags);
-		cy_writeb(base_addr+(CyCAR<<index), (u_char)channel);
-                if (info->rtsdtr_inv) {
-			cy_writeb(base_addr+(CyMSVR2<<index), ~CyDTR);
-                } else {
-			cy_writeb(base_addr+(CyMSVR1<<index), ~CyRTS);
-                }
-		CY_UNLOCK(info, flags);
-	}
-	if (set & TIOCM_DTR){
-		CY_LOCK(info, flags);
-		cy_writeb(base_addr+(CyCAR<<index), (u_char)channel);
-                if (info->rtsdtr_inv) {
-			cy_writeb(base_addr+(CyMSVR1<<index), CyRTS);
-                } else {
-			cy_writeb(base_addr+(CyMSVR2<<index), CyDTR);
-                }
+	struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
+	int card, chip, channel, index;
+	void __iomem *base_addr;
+	unsigned long flags;
+	struct FIRM_ID __iomem *firm_id;
+	struct ZFW_CTRL __iomem *zfw_ctrl;
+	struct BOARD_CTRL __iomem *board_ctrl;
+	struct CH_CTRL __iomem *ch_ctrl;
+	int retval;
+
+	if (serial_paranoia_check(info, tty->name, __FUNCTION__))
+		return -ENODEV;
+
+	card = info->card;
+	channel = (info->line) - (cy_card[card].first_line);
+	if (!IS_CYC_Z(cy_card[card])) {
+		chip = channel >> 2;
+		channel &= 0x03;
+		index = cy_card[card].bus_index;
+		base_addr =
+		    cy_card[card].base_addr + (cy_chip_offset[chip] << index);
+
+		if (set & TIOCM_RTS) {
+			CY_LOCK(info, flags);
+			cy_writeb(base_addr + (CyCAR << index),
+				  (u_char) channel);
+			if (info->rtsdtr_inv) {
+				cy_writeb(base_addr + (CyMSVR2 << index),
+					  CyDTR);
+			} else {
+				cy_writeb(base_addr + (CyMSVR1 << index),
+					  CyRTS);
+			}
+			CY_UNLOCK(info, flags);
+		}
+		if (clear & TIOCM_RTS) {
+			CY_LOCK(info, flags);
+			cy_writeb(base_addr + (CyCAR << index),
+				  (u_char) channel);
+			if (info->rtsdtr_inv) {
+				cy_writeb(base_addr + (CyMSVR2 << index),
+					  ~CyDTR);
+			} else {
+				cy_writeb(base_addr + (CyMSVR1 << index),
+					  ~CyRTS);
+			}
+			CY_UNLOCK(info, flags);
+		}
+		if (set & TIOCM_DTR) {
+			CY_LOCK(info, flags);
+			cy_writeb(base_addr + (CyCAR << index),
+				  (u_char) channel);
+			if (info->rtsdtr_inv) {
+				cy_writeb(base_addr + (CyMSVR1 << index),
+					  CyRTS);
+			} else {
+				cy_writeb(base_addr + (CyMSVR2 << index),
+					  CyDTR);
+			}
 #ifdef CY_DEBUG_DTR
-		printk("cyc:set_modem_info raising DTR\n");
-		printk("     status: 0x%x, 0x%x\n",
-		    cy_readb(base_addr+(CyMSVR1<<index)), 
-                    cy_readb(base_addr+(CyMSVR2<<index)));
+			printk("cyc:set_modem_info raising DTR\n");
+			printk("     status: 0x%x, 0x%x\n",
+				cy_readb(base_addr + (CyMSVR1 << index)),
+				cy_readb(base_addr + (CyMSVR2 << index)));
 #endif
-		CY_UNLOCK(info, flags);
-	}
-	if (clear & TIOCM_DTR) {
-		CY_LOCK(info, flags);
-		cy_writeb(base_addr+(CyCAR<<index), (u_char)channel);
-                if (info->rtsdtr_inv) {
-			cy_writeb(base_addr+(CyMSVR1<<index), ~CyRTS);
-                } else {
-			cy_writeb(base_addr+(CyMSVR2<<index), ~CyDTR);
-                }
+			CY_UNLOCK(info, flags);
+		}
+		if (clear & TIOCM_DTR) {
+			CY_LOCK(info, flags);
+			cy_writeb(base_addr + (CyCAR << index),
+				  (u_char) channel);
+			if (info->rtsdtr_inv) {
+				cy_writeb(base_addr + (CyMSVR1 << index),
+					  ~CyRTS);
+			} else {
+				cy_writeb(base_addr + (CyMSVR2 << index),
+					  ~CyDTR);
+			}
 
 #ifdef CY_DEBUG_DTR
-		printk("cyc:set_modem_info dropping DTR\n");
-		printk("     status: 0x%x, 0x%x\n",
-		    cy_readb(base_addr+(CyMSVR1<<index)), 
-                    cy_readb(base_addr+(CyMSVR2<<index)));
+			printk("cyc:set_modem_info dropping DTR\n");
+			printk("     status: 0x%x, 0x%x\n",
+				cy_readb(base_addr + (CyMSVR1 << index)),
+				cy_readb(base_addr + (CyMSVR2 << index)));
 #endif
-		CY_UNLOCK(info, flags);
-	}
-    } else {
-	base_addr = cy_card[card].base_addr;
-
-	firm_id = cy_card[card].base_addr + ID_ADDRESS;
-        if (ISZLOADED(cy_card[card])) {
-	    zfw_ctrl = cy_card[card].base_addr + (cy_readl(&firm_id->zfwctrl_addr) & 0xfffff);
-	    board_ctrl = &zfw_ctrl->board_ctrl;
-	    ch_ctrl = zfw_ctrl->ch_ctrl;
-
-	    if (set & TIOCM_RTS){
-		    CY_LOCK(info, flags);
-		    cy_writel(&ch_ctrl[channel].rs_control,
-                       cy_readl(&ch_ctrl[channel].rs_control) | C_RS_RTS);
-		    CY_UNLOCK(info, flags);
-	    }
-	    if (clear & TIOCM_RTS) {
-		    CY_LOCK(info, flags);
-		    cy_writel(&ch_ctrl[channel].rs_control,
-                       cy_readl(&ch_ctrl[channel].rs_control) & ~C_RS_RTS);
-		    CY_UNLOCK(info, flags);
-	    }
-	    if (set & TIOCM_DTR){
-		    CY_LOCK(info, flags);
-		    cy_writel(&ch_ctrl[channel].rs_control,
-                       cy_readl(&ch_ctrl[channel].rs_control) | C_RS_DTR);
+			CY_UNLOCK(info, flags);
+		}
+	} else {
+		base_addr = cy_card[card].base_addr;
+
+		firm_id = cy_card[card].base_addr + ID_ADDRESS;
+		if (ISZLOADED(cy_card[card])) {
+			zfw_ctrl = cy_card[card].base_addr +
+				(cy_readl(&firm_id->zfwctrl_addr) & 0xfffff);
+			board_ctrl = &zfw_ctrl->board_ctrl;
+			ch_ctrl = zfw_ctrl->ch_ctrl;
+
+			if (set & TIOCM_RTS) {
+				CY_LOCK(info, flags);
+				cy_writel(&ch_ctrl[channel].rs_control,
+					  cy_readl(&ch_ctrl[channel].
+						   rs_control) | C_RS_RTS);
+				CY_UNLOCK(info, flags);
+			}
+			if (clear & TIOCM_RTS) {
+				CY_LOCK(info, flags);
+				cy_writel(&ch_ctrl[channel].rs_control,
+					  cy_readl(&ch_ctrl[channel].
+						   rs_control) & ~C_RS_RTS);
+				CY_UNLOCK(info, flags);
+			}
+			if (set & TIOCM_DTR) {
+				CY_LOCK(info, flags);
+				cy_writel(&ch_ctrl[channel].rs_control,
+					  cy_readl(&ch_ctrl[channel].
+						   rs_control) | C_RS_DTR);
 #ifdef CY_DEBUG_DTR
-		    printk("cyc:set_modem_info raising Z DTR\n");
+				printk("cyc:set_modem_info raising Z DTR\n");
 #endif
-		    CY_UNLOCK(info, flags);
-	    }
-	    if (clear & TIOCM_DTR) {
-		    CY_LOCK(info, flags);
-		    cy_writel(&ch_ctrl[channel].rs_control,
-                       cy_readl(&ch_ctrl[channel].rs_control) & ~C_RS_DTR);
+				CY_UNLOCK(info, flags);
+			}
+			if (clear & TIOCM_DTR) {
+				CY_LOCK(info, flags);
+				cy_writel(&ch_ctrl[channel].rs_control,
+					  cy_readl(&ch_ctrl[channel].
+						   rs_control) & ~C_RS_DTR);
 #ifdef CY_DEBUG_DTR
-		    printk("cyc:set_modem_info clearing Z DTR\n");
+				printk("cyc:set_modem_info clearing Z DTR\n");
 #endif
-		    CY_UNLOCK(info, flags);
-	    }
-	}else{
-	    return -ENODEV;
-	}
-	CY_LOCK(info, flags);
-        retval = cyz_issue_cmd(&cy_card[info->card],
-				    channel, C_CM_IOCTLM,0L);
-	if (retval != 0){
-	    printk("cyc:set_modem_info retval on ttyC%d was %x\n",
-		   info->line, retval);
+				CY_UNLOCK(info, flags);
+			}
+		} else {
+			return -ENODEV;
+		}
+		CY_LOCK(info, flags);
+		retval = cyz_issue_cmd(&cy_card[info->card],
+					channel, C_CM_IOCTLM, 0L);
+		if (retval != 0) {
+			printk("cyc:set_modem_info retval on ttyC%d was %x\n",
+				info->line, retval);
+		}
+		CY_UNLOCK(info, flags);
 	}
-	CY_UNLOCK(info, flags);
-    }
-    return 0;
-} /* cy_tiocmset */
+	return 0;
+}				/* cy_tiocmset */
 
 /*
  * cy_break() --- routine which turns the break handling on or off
  */
-static void
-cy_break(struct tty_struct *tty, int break_state)
+static void cy_break(struct tty_struct *tty, int break_state)
 {
-    struct cyclades_port * info = (struct cyclades_port *)tty->driver_data;
-    unsigned long flags;
-
-    if (serial_paranoia_check(info, tty->name, "cy_break"))
-	return;
-
-    CY_LOCK(info, flags);
-    if (!IS_CYC_Z(cy_card[info->card])) {
-        /* Let the transmit ISR take care of this (since it
-	   requires stuffing characters into the output stream).
-        */
-	if (break_state == -1) {
-	    if (!info->breakon) {
-		info->breakon = 1;
-		if (!info->xmit_cnt) {
-		    CY_UNLOCK(info, flags);
-		    start_xmit(info);
-		    CY_LOCK(info, flags);
+	struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
+	unsigned long flags;
+
+	if (serial_paranoia_check(info, tty->name, "cy_break"))
+		return;
+
+	CY_LOCK(info, flags);
+	if (!IS_CYC_Z(cy_card[info->card])) {
+		/* Let the transmit ISR take care of this (since it
+		   requires stuffing characters into the output stream).
+		 */
+		if (break_state == -1) {
+			if (!info->breakon) {
+				info->breakon = 1;
+				if (!info->xmit_cnt) {
+					CY_UNLOCK(info, flags);
+					start_xmit(info);
+					CY_LOCK(info, flags);
+				}
+			}
+		} else {
+			if (!info->breakoff) {
+				info->breakoff = 1;
+				if (!info->xmit_cnt) {
+					CY_UNLOCK(info, flags);
+					start_xmit(info);
+					CY_LOCK(info, flags);
+				}
+			}
 		}
-	    }
 	} else {
-	    if (!info->breakoff) {
-		info->breakoff = 1;
-		if (!info->xmit_cnt) {
-		    CY_UNLOCK(info, flags);
-		    start_xmit(info);
-		    CY_LOCK(info, flags);
+		int retval;
+
+		if (break_state == -1) {
+			retval = cyz_issue_cmd(&cy_card[info->card],
+				info->line - cy_card[info->card].first_line,
+				C_CM_SET_BREAK, 0L);
+			if (retval != 0) {
+				printk("cyc:cy_break (set) retval on ttyC%d "
+					"was %x\n", info->line, retval);
+			}
+		} else {
+			retval = cyz_issue_cmd(&cy_card[info->card],
+				info->line - cy_card[info->card].first_line,
+				C_CM_CLR_BREAK, 0L);
+			if (retval != 0) {
+				printk("cyc:cy_break (clr) retval on ttyC%d "
+					"was %x\n", info->line, retval);
+			}
 		}
-	    }
-	}
-    } else {
-	int retval;
-
-	if (break_state == -1) {
-	    retval = cyz_issue_cmd(&cy_card[info->card],
-		(info->line) - (cy_card[info->card].first_line),
-		C_CM_SET_BREAK, 0L);
-	    if (retval != 0) {
-		printk("cyc:cy_break (set) retval on ttyC%d was %x\n",
-		       info->line, retval);
-	    }
-	} else {
-	    retval = cyz_issue_cmd(&cy_card[info->card],
-		(info->line) - (cy_card[info->card].first_line),
-		C_CM_CLR_BREAK, 0L);
-	    if (retval != 0) {
-		printk("cyc:cy_break (clr) retval on ttyC%d was %x\n",
-		       info->line, retval);
-	    }
 	}
-    }
-    CY_UNLOCK(info, flags);
-} /* cy_break */
+	CY_UNLOCK(info, flags);
+}				/* cy_break */
 
 static int
-get_mon_info(struct cyclades_port * info, struct cyclades_monitor __user * mon)
+get_mon_info(struct cyclades_port *info, struct cyclades_monitor __user * mon)
 {
 
-    if(copy_to_user(mon, &info->mon, sizeof(struct cyclades_monitor)))
-    	return -EFAULT;
-    info->mon.int_count  = 0;
-    info->mon.char_count = 0;
-    info->mon.char_max   = 0;
-    info->mon.char_last  = 0;
-    return 0;
-}/* get_mon_info */
-
+	if (copy_to_user(mon, &info->mon, sizeof(struct cyclades_monitor)))
+		return -EFAULT;
+	info->mon.int_count = 0;
+	info->mon.char_count = 0;
+	info->mon.char_max = 0;
+	info->mon.char_last = 0;
+	return 0;
+}				/* get_mon_info */
 
-static int
-set_threshold(struct cyclades_port * info, unsigned long value)
+static int set_threshold(struct cyclades_port *info, unsigned long value)
 {
-  void __iomem *base_addr;
-  int card,channel,chip,index;
-  unsigned long flags;
-   
-    card = info->card;
-    channel = info->line - cy_card[card].first_line;
-    if (!IS_CYC_Z(cy_card[card])) {
-	chip = channel>>2;
-	channel &= 0x03;
-	index = cy_card[card].bus_index;
-	base_addr = cy_card[card].base_addr + (cy_chip_offset[chip]<<index);
-
-	info->cor3 &= ~CyREC_FIFO;
-	info->cor3 |= value & CyREC_FIFO;
+	void __iomem *base_addr;
+	int card, channel, chip, index;
+	unsigned long flags;
 
-	CY_LOCK(info, flags);
-	    cy_writeb(base_addr+(CyCOR3<<index), info->cor3);
-	    cyy_issue_cmd(base_addr,CyCOR_CHANGE|CyCOR3ch,index);
-	CY_UNLOCK(info, flags);
-    } else {
-	// Nothing to do!
-    }
-    return 0;
-}/* set_threshold */
+	card = info->card;
+	channel = info->line - cy_card[card].first_line;
+	if (!IS_CYC_Z(cy_card[card])) {
+		chip = channel >> 2;
+		channel &= 0x03;
+		index = cy_card[card].bus_index;
+		base_addr =
+		    cy_card[card].base_addr + (cy_chip_offset[chip] << index);
 
+		info->cor3 &= ~CyREC_FIFO;
+		info->cor3 |= value & CyREC_FIFO;
 
-static int
-get_threshold(struct cyclades_port * info, unsigned long __user *value)
-{
-  void __iomem *base_addr;
-  int card,channel,chip,index;
-  unsigned long tmp;
-   
-    card = info->card;
-    channel = info->line - cy_card[card].first_line;
-    if (!IS_CYC_Z(cy_card[card])) {
-	chip = channel>>2;
-	channel &= 0x03;
-	index = cy_card[card].bus_index;
-	base_addr = cy_card[card].base_addr + (cy_chip_offset[chip]<<index);
-
-	tmp = cy_readb(base_addr+(CyCOR3<<index)) & CyREC_FIFO;
-	return put_user(tmp,value);
-    } else {
-	// Nothing to do!
+		CY_LOCK(info, flags);
+		cy_writeb(base_addr + (CyCOR3 << index), info->cor3);
+		cyy_issue_cmd(base_addr, CyCOR_CHANGE | CyCOR3ch, index);
+		CY_UNLOCK(info, flags);
+	} else {
+		/* Nothing to do! */
+	}
 	return 0;
-    }
-}/* get_threshold */
-
+}				/* set_threshold */
 
 static int
-set_default_threshold(struct cyclades_port * info, unsigned long value)
+get_threshold(struct cyclades_port *info, unsigned long __user * value)
 {
-    info->default_threshold = value & 0x0f;
-    return 0;
-}/* set_default_threshold */
+	void __iomem *base_addr;
+	int card, channel, chip, index;
+	unsigned long tmp;
 
+	card = info->card;
+	channel = info->line - cy_card[card].first_line;
+	if (!IS_CYC_Z(cy_card[card])) {
+		chip = channel >> 2;
+		channel &= 0x03;
+		index = cy_card[card].bus_index;
+		base_addr =
+		    cy_card[card].base_addr + (cy_chip_offset[chip] << index);
+
+		tmp = cy_readb(base_addr + (CyCOR3 << index)) & CyREC_FIFO;
+		return put_user(tmp, value);
+	} else {
+		/* Nothing to do! */
+		return 0;
+	}
+}				/* get_threshold */
 
 static int
-get_default_threshold(struct cyclades_port * info, unsigned long __user *value)
+set_default_threshold(struct cyclades_port *info, unsigned long value)
 {
-    return put_user(info->default_threshold,value);
-}/* get_default_threshold */
-
+	info->default_threshold = value & 0x0f;
+	return 0;
+}				/* set_default_threshold */
 
 static int
-set_timeout(struct cyclades_port * info, unsigned long value)
+get_default_threshold(struct cyclades_port *info, unsigned long __user * value)
 {
-  void __iomem *base_addr;
-  int card,channel,chip,index;
-  unsigned long flags;
-   
-    card = info->card;
-    channel = info->line - cy_card[card].first_line;
-    if (!IS_CYC_Z(cy_card[card])) {
-	chip = channel>>2;
-	channel &= 0x03;
-	index = cy_card[card].bus_index;
-	base_addr = cy_card[card].base_addr + (cy_chip_offset[chip]<<index);
+	return put_user(info->default_threshold, value);
+}				/* get_default_threshold */
 
-	CY_LOCK(info, flags);
-	    cy_writeb(base_addr+(CyRTPR<<index), value & 0xff);
-	CY_UNLOCK(info, flags);
-    } else {
-	// Nothing to do!
-    }
-    return 0;
-}/* set_timeout */
+static int set_timeout(struct cyclades_port *info, unsigned long value)
+{
+	void __iomem *base_addr;
+	int card, channel, chip, index;
+	unsigned long flags;
 
+	card = info->card;
+	channel = info->line - cy_card[card].first_line;
+	if (!IS_CYC_Z(cy_card[card])) {
+		chip = channel >> 2;
+		channel &= 0x03;
+		index = cy_card[card].bus_index;
+		base_addr =
+		    cy_card[card].base_addr + (cy_chip_offset[chip] << index);
 
-static int
-get_timeout(struct cyclades_port * info, unsigned long __user *value)
-{
-  void __iomem *base_addr;
-  int card,channel,chip,index;
-  unsigned long tmp;
-   
-    card = info->card;
-    channel = info->line - cy_card[card].first_line;
-    if (!IS_CYC_Z(cy_card[card])) {
-	chip = channel>>2;
-	channel &= 0x03;
-	index = cy_card[card].bus_index;
-	base_addr = cy_card[card].base_addr + (cy_chip_offset[chip]<<index);
-
-	tmp = cy_readb(base_addr+(CyRTPR<<index));
-	return put_user(tmp,value);
-    } else {
-	// Nothing to do!
+		CY_LOCK(info, flags);
+		cy_writeb(base_addr + (CyRTPR << index), value & 0xff);
+		CY_UNLOCK(info, flags);
+	} else {
+		/* Nothing to do! */
+	}
 	return 0;
-    }
-}/* get_timeout */
-
+}				/* set_timeout */
 
-static int
-set_default_timeout(struct cyclades_port * info, unsigned long value)
+static int get_timeout(struct cyclades_port *info, unsigned long __user * value)
 {
-    info->default_timeout = value & 0xff;
-    return 0;
-}/* set_default_timeout */
+	void __iomem *base_addr;
+	int card, channel, chip, index;
+	unsigned long tmp;
 
+	card = info->card;
+	channel = info->line - cy_card[card].first_line;
+	if (!IS_CYC_Z(cy_card[card])) {
+		chip = channel >> 2;
+		channel &= 0x03;
+		index = cy_card[card].bus_index;
+		base_addr =
+		    cy_card[card].base_addr + (cy_chip_offset[chip] << index);
+
+		tmp = cy_readb(base_addr + (CyRTPR << index));
+		return put_user(tmp, value);
+	} else {
+		/* Nothing to do! */
+		return 0;
+	}
+}				/* get_timeout */
+
+static int set_default_timeout(struct cyclades_port *info, unsigned long value)
+{
+	info->default_timeout = value & 0xff;
+	return 0;
+}				/* set_default_timeout */
 
 static int
-get_default_timeout(struct cyclades_port * info, unsigned long __user *value)
+get_default_timeout(struct cyclades_port *info, unsigned long __user * value)
 {
-    return put_user(info->default_timeout,value);
-}/* get_default_timeout */
+	return put_user(info->default_timeout, value);
+}				/* get_default_timeout */
 
 /*
  * This routine allows the tty driver to implement device-
@@ -3915,184 +4015,193 @@ get_default_timeout(struct cyclades_port * info, unsigned long __user *value)
  * not recognized by the driver, it should return ENOIOCTLCMD.
  */
 static int
-cy_ioctl(struct tty_struct *tty, struct file * file,
-            unsigned int cmd, unsigned long arg)
+cy_ioctl(struct tty_struct *tty, struct file *file,
+	 unsigned int cmd, unsigned long arg)
 {
-  struct cyclades_port * info = (struct cyclades_port *)tty->driver_data;
-  struct cyclades_icount cprev, cnow;		/* kernel counter temps */
-  struct serial_icounter_struct __user *p_cuser;	/* user space */
-  int ret_val = 0;
-  unsigned long flags;
-  void __user *argp = (void __user *)arg;
-
-    if (serial_paranoia_check(info, tty->name, "cy_ioctl"))
-	return -ENODEV;
+	struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
+	struct cyclades_icount cprev, cnow;	/* kernel counter temps */
+	struct serial_icounter_struct __user *p_cuser;	/* user space */
+	int ret_val = 0;
+	unsigned long flags;
+	void __user *argp = (void __user *)arg;
+
+	if (serial_paranoia_check(info, tty->name, "cy_ioctl"))
+		return -ENODEV;
 
 #ifdef CY_DEBUG_OTHER
-    printk("cyc:cy_ioctl ttyC%d, cmd = %x arg = %lx\n",
-        info->line, cmd, arg); /* */
+	printk("cyc:cy_ioctl ttyC%d, cmd = %x arg = %lx\n", info->line, cmd, arg);	/* */
 #endif
 
-    switch (cmd) {
-        case CYGETMON:
-            ret_val = get_mon_info(info, argp);
-            break;
-        case CYGETTHRESH:
-            ret_val = get_threshold(info, argp);
-            break;
-        case CYSETTHRESH:
-            ret_val = set_threshold(info, arg);
-            break;
-        case CYGETDEFTHRESH:
-            ret_val = get_default_threshold(info, argp);
-            break;
-        case CYSETDEFTHRESH:
-            ret_val = set_default_threshold(info, arg);
-            break;
-        case CYGETTIMEOUT:
-            ret_val = get_timeout(info, argp);
-            break;
-        case CYSETTIMEOUT:
-            ret_val = set_timeout(info, arg);
-            break;
-        case CYGETDEFTIMEOUT:
-            ret_val = get_default_timeout(info, argp);
-            break;
-        case CYSETDEFTIMEOUT:
-            ret_val = set_default_timeout(info, arg);
-            break;
+	switch (cmd) {
+	case CYGETMON:
+		ret_val = get_mon_info(info, argp);
+		break;
+	case CYGETTHRESH:
+		ret_val = get_threshold(info, argp);
+		break;
+	case CYSETTHRESH:
+		ret_val = set_threshold(info, arg);
+		break;
+	case CYGETDEFTHRESH:
+		ret_val = get_default_threshold(info, argp);
+		break;
+	case CYSETDEFTHRESH:
+		ret_val = set_default_threshold(info, arg);
+		break;
+	case CYGETTIMEOUT:
+		ret_val = get_timeout(info, argp);
+		break;
+	case CYSETTIMEOUT:
+		ret_val = set_timeout(info, arg);
+		break;
+	case CYGETDEFTIMEOUT:
+		ret_val = get_default_timeout(info, argp);
+		break;
+	case CYSETDEFTIMEOUT:
+		ret_val = set_default_timeout(info, arg);
+		break;
 	case CYSETRFLOW:
-    	    info->rflow = (int)arg;
-	    ret_val = 0;
-	    break;
+		info->rflow = (int)arg;
+		ret_val = 0;
+		break;
 	case CYGETRFLOW:
-	    ret_val = info->rflow;
-	    break;
+		ret_val = info->rflow;
+		break;
 	case CYSETRTSDTR_INV:
-    	    info->rtsdtr_inv = (int)arg;
-	    ret_val = 0;
-	    break;
+		info->rtsdtr_inv = (int)arg;
+		ret_val = 0;
+		break;
 	case CYGETRTSDTR_INV:
-	    ret_val = info->rtsdtr_inv;
-	    break;
+		ret_val = info->rtsdtr_inv;
+		break;
 	case CYGETCARDINFO:
-            if (copy_to_user(argp, &cy_card[info->card], 
-			sizeof (struct cyclades_card))) {
-		ret_val = -EFAULT;
+		if (copy_to_user(argp, &cy_card[info->card],
+				 sizeof(struct cyclades_card))) {
+			ret_val = -EFAULT;
+			break;
+		}
+		ret_val = 0;
 		break;
-	    }
-	    ret_val = 0;
-            break;
 	case CYGETCD1400VER:
-	    ret_val = info->chip_rev;
-	    break;
+		ret_val = info->chip_rev;
+		break;
 #ifndef CONFIG_CYZ_INTR
 	case CYZSETPOLLCYCLE:
-            cyz_polling_cycle = (arg * HZ) / 1000;
-	    ret_val = 0;
-	    break;
+		cyz_polling_cycle = (arg * HZ) / 1000;
+		ret_val = 0;
+		break;
 	case CYZGETPOLLCYCLE:
-            ret_val = (cyz_polling_cycle * 1000) / HZ;
-	    break;
-#endif /* CONFIG_CYZ_INTR */
+		ret_val = (cyz_polling_cycle * 1000) / HZ;
+		break;
+#endif				/* CONFIG_CYZ_INTR */
 	case CYSETWAIT:
-    	    info->closing_wait = (unsigned short)arg * HZ/100;
-	    ret_val = 0;
-	    break;
+		info->closing_wait = (unsigned short)arg *HZ / 100;
+		ret_val = 0;
+		break;
 	case CYGETWAIT:
-	    ret_val = info->closing_wait / (HZ/100);
-	    break;
-        case TIOCGSERIAL:
-            ret_val = get_serial_info(info, argp);
-            break;
-        case TIOCSSERIAL:
-            ret_val = set_serial_info(info, argp);
-            break;
-	case TIOCSERGETLSR: /* Get line status register */
-	    ret_val = get_lsr_info(info, argp);
-	    break;
-	/*
-	 * Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change 
-	 * - mask passed in arg for lines of interest
-	 *   (use |'ed TIOCM_RNG/DSR/CD/CTS for masking)
-	 * Caller should use TIOCGICOUNT to see which one it was
-	 */
+		ret_val = info->closing_wait / (HZ / 100);
+		break;
+	case TIOCGSERIAL:
+		ret_val = get_serial_info(info, argp);
+		break;
+	case TIOCSSERIAL:
+		ret_val = set_serial_info(info, argp);
+		break;
+	case TIOCSERGETLSR:	/* Get line status register */
+		ret_val = get_lsr_info(info, argp);
+		break;
+		/*
+		 * Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change
+		 * - mask passed in arg for lines of interest
+		 *   (use |'ed TIOCM_RNG/DSR/CD/CTS for masking)
+		 * Caller should use TIOCGICOUNT to see which one it was
+		 */
 	case TIOCMIWAIT:
-	    CY_LOCK(info, flags);
-	    /* note the counters on entry */
-	    cprev = info->icount;
-	    CY_UNLOCK(info, flags);
-	    while (1) {
-		interruptible_sleep_on(&info->delta_msr_wait);
-		/* see if a signal did it */
-		if (signal_pending(current)) {
-		    return -ERESTARTSYS;
-		}
-
 		CY_LOCK(info, flags);
-		cnow = info->icount; /* atomic copy */
+		/* note the counters on entry */
+		cprev = info->icount;
 		CY_UNLOCK(info, flags);
+		while (1) {
+			interruptible_sleep_on(&info->delta_msr_wait);
+			/* see if a signal did it */
+			if (signal_pending(current)) {
+				return -ERESTARTSYS;
+			}
 
-		if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr && 
-		    cnow.dcd == cprev.dcd && cnow.cts == cprev.cts) {
-		    return -EIO; /* no change => error */
-		}
-		if ( ((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) || 
-		     ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) || 
-		     ((arg & TIOCM_CD)  && (cnow.dcd != cprev.dcd)) || 
-		     ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts)) ) {
-		    return 0;
-		}
-		cprev = cnow;
-	    }
-	    /* NOTREACHED */
+			CY_LOCK(info, flags);
+			cnow = info->icount;	/* atomic copy */
+			CY_UNLOCK(info, flags);
 
-	/*
-	 * Get counter of input serial line interrupts (DCD,RI,DSR,CTS)
-	 * Return: write counters to the user passed counter struct
-	 * NB: both 1->0 and 0->1 transitions are counted except for
-	 *     RI where only 0->1 is counted.
-	 */
+			if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr &&
+			    cnow.dcd == cprev.dcd && cnow.cts == cprev.cts) {
+				return -EIO;	/* no change => error */
+			}
+			if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) ||
+			    ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) ||
+			    ((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd)) ||
+			    ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts))) {
+				return 0;
+			}
+			cprev = cnow;
+		}
+		/* NOTREACHED */
+
+		/*
+		 * Get counter of input serial line interrupts (DCD,RI,DSR,CTS)
+		 * Return: write counters to the user passed counter struct
+		 * NB: both 1->0 and 0->1 transitions are counted except for
+		 *     RI where only 0->1 is counted.
+		 */
 	case TIOCGICOUNT:
-	    CY_LOCK(info, flags);
-	    cnow = info->icount;
-	    CY_UNLOCK(info, flags);
-	    p_cuser = argp;
-	    ret_val = put_user(cnow.cts, &p_cuser->cts);
-	    if (ret_val) return ret_val;
-	    ret_val = put_user(cnow.dsr, &p_cuser->dsr);
-	    if (ret_val) return ret_val;
-	    ret_val = put_user(cnow.rng, &p_cuser->rng);
-	    if (ret_val) return ret_val;
-	    ret_val = put_user(cnow.dcd, &p_cuser->dcd);
-	    if (ret_val) return ret_val;
-	    ret_val = put_user(cnow.rx, &p_cuser->rx);
-	    if (ret_val) return ret_val;
-	    ret_val = put_user(cnow.tx, &p_cuser->tx);
-	    if (ret_val) return ret_val;
-	    ret_val = put_user(cnow.frame, &p_cuser->frame);
-	    if (ret_val) return ret_val;
-	    ret_val = put_user(cnow.overrun, &p_cuser->overrun);
-	    if (ret_val) return ret_val;
-	    ret_val = put_user(cnow.parity, &p_cuser->parity);
-	    if (ret_val) return ret_val;
-	    ret_val = put_user(cnow.brk, &p_cuser->brk);
-	    if (ret_val) return ret_val;
-	    ret_val = put_user(cnow.buf_overrun, &p_cuser->buf_overrun);
-	    if (ret_val) return ret_val;
-	    ret_val = 0;
-	    break;
-        default:
-            ret_val = -ENOIOCTLCMD;
-    }
+		CY_LOCK(info, flags);
+		cnow = info->icount;
+		CY_UNLOCK(info, flags);
+		p_cuser = argp;
+		ret_val = put_user(cnow.cts, &p_cuser->cts);
+		if (ret_val)
+			return ret_val;
+		ret_val = put_user(cnow.dsr, &p_cuser->dsr);
+		if (ret_val)
+			return ret_val;
+		ret_val = put_user(cnow.rng, &p_cuser->rng);
+		if (ret_val)
+			return ret_val;
+		ret_val = put_user(cnow.dcd, &p_cuser->dcd);
+		if (ret_val)
+			return ret_val;
+		ret_val = put_user(cnow.rx, &p_cuser->rx);
+		if (ret_val)
+			return ret_val;
+		ret_val = put_user(cnow.tx, &p_cuser->tx);
+		if (ret_val)
+			return ret_val;
+		ret_val = put_user(cnow.frame, &p_cuser->frame);
+		if (ret_val)
+			return ret_val;
+		ret_val = put_user(cnow.overrun, &p_cuser->overrun);
+		if (ret_val)
+			return ret_val;
+		ret_val = put_user(cnow.parity, &p_cuser->parity);
+		if (ret_val)
+			return ret_val;
+		ret_val = put_user(cnow.brk, &p_cuser->brk);
+		if (ret_val)
+			return ret_val;
+		ret_val = put_user(cnow.buf_overrun, &p_cuser->buf_overrun);
+		if (ret_val)
+			return ret_val;
+		ret_val = 0;
+		break;
+	default:
+		ret_val = -ENOIOCTLCMD;
+	}
 
 #ifdef CY_DEBUG_OTHER
-    printk(" cyc:cy_ioctl done\n");
+	printk(" cyc:cy_ioctl done\n");
 #endif
 
-    return ret_val;
-} /* cy_ioctl */
-
+	return ret_val;
+}				/* cy_ioctl */
 
 /*
  * This routine allows the tty driver to be notified when
@@ -4100,66 +4209,64 @@ cy_ioctl(struct tty_struct *tty, struct file * file,
  * well-designed tty driver should be prepared to accept the case
  * where old == NULL, and try to do something rational.
  */
-static void
-cy_set_termios(struct tty_struct *tty, struct termios * old_termios)
+static void cy_set_termios(struct tty_struct *tty, struct ktermios *old_termios)
 {
-  struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
+	struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
 
 #ifdef CY_DEBUG_OTHER
-    printk("cyc:cy_set_termios ttyC%d\n", info->line);
+	printk("cyc:cy_set_termios ttyC%d\n", info->line);
 #endif
 
-    if ((tty->termios->c_cflag == old_termios->c_cflag) &&
-	((tty->termios->c_iflag & (IXON|IXANY)) == 
-	 (old_termios->c_iflag & (IXON|IXANY))))
-        return;
-    set_line_char(info);
-
-    if ((old_termios->c_cflag & CRTSCTS) &&
-        !(tty->termios->c_cflag & CRTSCTS)) {
-            tty->hw_stopped = 0;
-            cy_start(tty);
-    }
+	if (tty->termios->c_cflag == old_termios->c_cflag &&
+			(tty->termios->c_iflag & (IXON | IXANY)) ==
+			(old_termios->c_iflag & (IXON | IXANY)))
+		return;
+	set_line_char(info);
+
+	if ((old_termios->c_cflag & CRTSCTS) &&
+			!(tty->termios->c_cflag & CRTSCTS)) {
+		tty->hw_stopped = 0;
+		cy_start(tty);
+	}
 #if 0
-    /*
-     * No need to wake up processes in open wait, since they
-     * sample the CLOCAL flag once, and don't recheck it.
-     * XXX  It's not clear whether the current behavior is correct
-     * or not.  Hence, this may change.....
-     */
-    if (!(old_termios->c_cflag & CLOCAL) &&
-        (tty->termios->c_cflag & CLOCAL))
-            wake_up_interruptible(&info->open_wait);
+	/*
+	 * No need to wake up processes in open wait, since they
+	 * sample the CLOCAL flag once, and don't recheck it.
+	 * XXX  It's not clear whether the current behavior is correct
+	 * or not.  Hence, this may change.....
+	 */
+	if (!(old_termios->c_cflag & CLOCAL) &&
+	    (tty->termios->c_cflag & CLOCAL))
+		wake_up_interruptible(&info->open_wait);
 #endif
-
-    return;
-} /* cy_set_termios */
+}				/* cy_set_termios */
 
 /* This function is used to send a high-priority XON/XOFF character to
    the device.
 */
-static void
-cy_send_xchar (struct tty_struct *tty, char ch)
+static void cy_send_xchar(struct tty_struct *tty, char ch)
 {
-	struct cyclades_port *info = (struct cyclades_port *) tty->driver_data;
+	struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
 	int card, channel;
 
-	if (serial_paranoia_check (info, tty->name, "cy_send_xchar"))
+	if (serial_paranoia_check(info, tty->name, "cy_send_xchar"))
 		return;
 
-  	info->x_char = ch;
+	info->x_char = ch;
 
 	if (ch)
-		cy_start (tty);
+		cy_start(tty);
 
 	card = info->card;
 	channel = info->line - cy_card[card].first_line;
 
-	if (IS_CYC_Z (cy_card[card])) {
-		if (ch == STOP_CHAR (tty))
-	  		cyz_issue_cmd (&cy_card[card], channel, C_CM_SENDXOFF, 0L);
-		else if (ch == START_CHAR (tty))
-			cyz_issue_cmd (&cy_card[card], channel, C_CM_SENDXON, 0L);
+	if (IS_CYC_Z(cy_card[card])) {
+		if (ch == STOP_CHAR(tty))
+			cyz_issue_cmd(&cy_card[card], channel, C_CM_SENDXOFF,
+					0L);
+		else if (ch == START_CHAR(tty))
+			cyz_issue_cmd(&cy_card[card], channel, C_CM_SENDXON,
+					0L);
 	}
 }
 
@@ -4167,260 +4274,248 @@ cy_send_xchar (struct tty_struct *tty, char ch)
    that incoming characters should be throttled because the input
    buffers are close to full.
  */
-static void
-cy_throttle(struct tty_struct * tty)
+static void cy_throttle(struct tty_struct *tty)
 {
-  struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
-  unsigned long flags;
-  void __iomem *base_addr;
-  int card,chip,channel,index;
+	struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
+	unsigned long flags;
+	void __iomem *base_addr;
+	int card, chip, channel, index;
 
 #ifdef CY_DEBUG_THROTTLE
-  char buf[64];
+	char buf[64];
 
-    printk("cyc:throttle %s: %d....ttyC%d\n", 
-	   tty_name(tty, buf),
-           tty->ldisc.chars_in_buffer(tty), info->line);
+	printk("cyc:throttle %s: %d....ttyC%d\n", tty_name(tty, buf),
+			tty->ldisc.chars_in_buffer(tty), info->line);
 #endif
 
-    if (serial_paranoia_check(info, tty->name, "cy_throttle")){
-            return;
-    }
-
-    card = info->card;
-
-    if (I_IXOFF(tty)) {
-        if (!IS_CYC_Z (cy_card[card]))
-            cy_send_xchar (tty, STOP_CHAR (tty));
-        else
-            info->throttle = 1;
-    }
-
-    if (tty->termios->c_cflag & CRTSCTS) {
-        channel = info->line - cy_card[card].first_line;
-        if (!IS_CYC_Z(cy_card[card])) {
-            chip = channel>>2;
-            channel &= 0x03;
-            index = cy_card[card].bus_index;
-            base_addr = cy_card[card].base_addr + (cy_chip_offset[chip]<<index);
-
-            CY_LOCK(info, flags);
-            cy_writeb(base_addr+(CyCAR<<index), (u_char)channel);
-            if (info->rtsdtr_inv) {
-                cy_writeb(base_addr+(CyMSVR2<<index), ~CyDTR);
-             } else {
-                cy_writeb(base_addr+(CyMSVR1<<index), ~CyRTS);
-	     }
-	    CY_UNLOCK(info, flags);
-	} else {
-	    info->throttle = 1;
-        }
-    }
+	if (serial_paranoia_check(info, tty->name, "cy_throttle")) {
+		return;
+	}
 
-    return;
-} /* cy_throttle */
+	card = info->card;
+
+	if (I_IXOFF(tty)) {
+		if (!IS_CYC_Z(cy_card[card]))
+			cy_send_xchar(tty, STOP_CHAR(tty));
+		else
+			info->throttle = 1;
+	}
 
+	if (tty->termios->c_cflag & CRTSCTS) {
+		channel = info->line - cy_card[card].first_line;
+		if (!IS_CYC_Z(cy_card[card])) {
+			chip = channel >> 2;
+			channel &= 0x03;
+			index = cy_card[card].bus_index;
+			base_addr = cy_card[card].base_addr +
+				(cy_chip_offset[chip] << index);
+
+			CY_LOCK(info, flags);
+			cy_writeb(base_addr + (CyCAR << index),
+				  (u_char) channel);
+			if (info->rtsdtr_inv) {
+				cy_writeb(base_addr + (CyMSVR2 << index),
+					  ~CyDTR);
+			} else {
+				cy_writeb(base_addr + (CyMSVR1 << index),
+					  ~CyRTS);
+			}
+			CY_UNLOCK(info, flags);
+		} else {
+			info->throttle = 1;
+		}
+	}
+}				/* cy_throttle */
 
 /*
  * This routine notifies the tty driver that it should signal
  * that characters can now be sent to the tty without fear of
  * overrunning the input buffers of the line disciplines.
  */
-static void
-cy_unthrottle(struct tty_struct * tty)
+static void cy_unthrottle(struct tty_struct *tty)
 {
-  struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
-  unsigned long flags;
-  void __iomem *base_addr;
-  int card,chip,channel,index;
+	struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
+	unsigned long flags;
+	void __iomem *base_addr;
+	int card, chip, channel, index;
 
 #ifdef CY_DEBUG_THROTTLE
-  char buf[64];
-        
-    printk("cyc:unthrottle %s: %d....ttyC%d\n", 
-	   tty_name(tty, buf),
-           tty->ldisc.chars_in_buffer(tty), info->line);
-#endif
+	char buf[64];
 
-    if (serial_paranoia_check(info, tty->name, "cy_unthrottle")){
-            return;
-    }
+	printk("cyc:unthrottle %s: %d....ttyC%d\n", tty_name(tty, buf),
+		tty->ldisc.chars_in_buffer(tty), info->line);
+#endif
 
-    if (I_IXOFF(tty)) {
-	if (info->x_char)
-	    info->x_char = 0;
-	else
-	    cy_send_xchar (tty, START_CHAR (tty));
-    }
-
-    if (tty->termios->c_cflag & CRTSCTS) {
-        card = info->card;
-        channel = info->line - cy_card[card].first_line;
-        if (!IS_CYC_Z(cy_card[card])) {
-	    chip = channel>>2;
-	    channel &= 0x03;
-	    index = cy_card[card].bus_index;
-	    base_addr = cy_card[card].base_addr + (cy_chip_offset[chip]<<index);
-
-	    CY_LOCK(info, flags);
-	    cy_writeb(base_addr+(CyCAR<<index), (u_char)channel);
-	    if (info->rtsdtr_inv) {
-		    cy_writeb(base_addr+(CyMSVR2<<index), CyDTR);
-	    } else {
-		    cy_writeb(base_addr+(CyMSVR1<<index), CyRTS);
-	    }
-	    CY_UNLOCK(info, flags);
-        } else {
-	    info->throttle = 0;
+	if (serial_paranoia_check(info, tty->name, "cy_unthrottle")) {
+		return;
 	}
-    }
 
-    return;
-} /* cy_unthrottle */
+	if (I_IXOFF(tty)) {
+		if (info->x_char)
+			info->x_char = 0;
+		else
+			cy_send_xchar(tty, START_CHAR(tty));
+	}
 
+	if (tty->termios->c_cflag & CRTSCTS) {
+		card = info->card;
+		channel = info->line - cy_card[card].first_line;
+		if (!IS_CYC_Z(cy_card[card])) {
+			chip = channel >> 2;
+			channel &= 0x03;
+			index = cy_card[card].bus_index;
+			base_addr = cy_card[card].base_addr +
+				(cy_chip_offset[chip] << index);
+
+			CY_LOCK(info, flags);
+			cy_writeb(base_addr + (CyCAR << index),
+				  (u_char) channel);
+			if (info->rtsdtr_inv) {
+				cy_writeb(base_addr + (CyMSVR2 << index),
+					  CyDTR);
+			} else {
+				cy_writeb(base_addr + (CyMSVR1 << index),
+					  CyRTS);
+			}
+			CY_UNLOCK(info, flags);
+		} else {
+			info->throttle = 0;
+		}
+	}
+}				/* cy_unthrottle */
 
 /* cy_start and cy_stop provide software output flow control as a
    function of XON/XOFF, software CTS, and other such stuff.
 */
-static void
-cy_stop(struct tty_struct *tty)
+static void cy_stop(struct tty_struct *tty)
 {
-  struct cyclades_card *cinfo;
-  struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
-  void __iomem *base_addr;
-  int chip,channel,index;
-  unsigned long flags;
+	struct cyclades_card *cinfo;
+	struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
+	void __iomem *base_addr;
+	int chip, channel, index;
+	unsigned long flags;
 
 #ifdef CY_DEBUG_OTHER
-    printk("cyc:cy_stop ttyC%d\n", info->line); /* */
+	printk("cyc:cy_stop ttyC%d\n", info->line);	/* */
 #endif
 
-    if (serial_paranoia_check(info, tty->name, "cy_stop"))
-        return;
-        
-    cinfo = &cy_card[info->card];
-    channel = info->line - cinfo->first_line;
-    if (!IS_CYC_Z(*cinfo)) {
-        index = cinfo->bus_index;
-        chip = channel>>2;
-        channel &= 0x03;
-        base_addr = cy_card[info->card].base_addr + (cy_chip_offset[chip]<<index);
-
-	CY_LOCK(info, flags);
-            cy_writeb(base_addr+(CyCAR<<index),
-	       (u_char)(channel & 0x0003)); /* index channel */
-            cy_writeb(base_addr+(CySRER<<index), 
-               cy_readb(base_addr+(CySRER<<index)) & ~CyTxRdy);
-	CY_UNLOCK(info, flags);
-    } else {
-	// Nothing to do!
-    }
+	if (serial_paranoia_check(info, tty->name, "cy_stop"))
+		return;
 
-    return;
-} /* cy_stop */
+	cinfo = &cy_card[info->card];
+	channel = info->line - cinfo->first_line;
+	if (!IS_CYC_Z(*cinfo)) {
+		index = cinfo->bus_index;
+		chip = channel >> 2;
+		channel &= 0x03;
+		base_addr = cy_card[info->card].base_addr +
+			(cy_chip_offset[chip] << index);
 
+		CY_LOCK(info, flags);
+		cy_writeb(base_addr + (CyCAR << index),
+			(u_char)(channel & 0x0003)); /* index channel */
+		cy_writeb(base_addr + (CySRER << index),
+			  cy_readb(base_addr + (CySRER << index)) & ~CyTxRdy);
+		CY_UNLOCK(info, flags);
+	} else {
+		/* Nothing to do! */
+	}
+}				/* cy_stop */
 
-static void
-cy_start(struct tty_struct *tty)
+static void cy_start(struct tty_struct *tty)
 {
-  struct cyclades_card *cinfo;
-  struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
-  void __iomem *base_addr;
-  int chip,channel,index;
-  unsigned long flags;
+	struct cyclades_card *cinfo;
+	struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
+	void __iomem *base_addr;
+	int chip, channel, index;
+	unsigned long flags;
 
 #ifdef CY_DEBUG_OTHER
-    printk("cyc:cy_start ttyC%d\n", info->line); /* */
+	printk("cyc:cy_start ttyC%d\n", info->line);	/* */
 #endif
 
-    if (serial_paranoia_check(info, tty->name, "cy_start"))
-        return;
-        
-    cinfo = &cy_card[info->card];
-    channel = info->line - cinfo->first_line;
-    index = cinfo->bus_index;
-    if (!IS_CYC_Z(*cinfo)) {
-        chip = channel>>2;
-        channel &= 0x03;
-        base_addr = cy_card[info->card].base_addr + (cy_chip_offset[chip]<<index);
-
-	CY_LOCK(info, flags);
-            cy_writeb(base_addr+(CyCAR<<index),
-	       (u_char)(channel & 0x0003)); /* index channel */
-            cy_writeb(base_addr+(CySRER<<index), 
-               cy_readb(base_addr+(CySRER<<index)) | CyTxRdy);
-	CY_UNLOCK(info, flags);
-    } else {
-	// Nothing to do!
-    }
+	if (serial_paranoia_check(info, tty->name, "cy_start"))
+		return;
 
-    return;
-} /* cy_start */
+	cinfo = &cy_card[info->card];
+	channel = info->line - cinfo->first_line;
+	index = cinfo->bus_index;
+	if (!IS_CYC_Z(*cinfo)) {
+		chip = channel >> 2;
+		channel &= 0x03;
+		base_addr = cy_card[info->card].base_addr +
+			(cy_chip_offset[chip] << index);
 
+		CY_LOCK(info, flags);
+		cy_writeb(base_addr + (CyCAR << index), (u_char) (channel & 0x0003));	/* index channel */
+		cy_writeb(base_addr + (CySRER << index),
+			  cy_readb(base_addr + (CySRER << index)) | CyTxRdy);
+		CY_UNLOCK(info, flags);
+	} else {
+		/* Nothing to do! */
+	}
+}				/* cy_start */
 
-static void
-cy_flush_buffer(struct tty_struct *tty)
+static void cy_flush_buffer(struct tty_struct *tty)
 {
-  struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
-  int card, channel, retval;
-  unsigned long flags;
-                                
+	struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
+	int card, channel, retval;
+	unsigned long flags;
+
 #ifdef CY_DEBUG_IO
-    printk("cyc:cy_flush_buffer ttyC%d\n", info->line); /* */
+	printk("cyc:cy_flush_buffer ttyC%d\n", info->line);	/* */
 #endif
 
-    if (serial_paranoia_check(info, tty->name, "cy_flush_buffer"))
-        return;
-
-    card = info->card;
-    channel = (info->line) - (cy_card[card].first_line);
+	if (serial_paranoia_check(info, tty->name, "cy_flush_buffer"))
+		return;
 
-    CY_LOCK(info, flags);
-    info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
-    CY_UNLOCK(info, flags);
+	card = info->card;
+	channel = (info->line) - (cy_card[card].first_line);
 
-    if (IS_CYC_Z(cy_card[card])) { /* If it is a Z card, flush the on-board 
-				      buffers as well */
 	CY_LOCK(info, flags);
-	retval = cyz_issue_cmd(&cy_card[card], channel, C_CM_FLUSH_TX, 0L);
-	if (retval != 0) {
-	    printk("cyc: flush_buffer retval on ttyC%d was %x\n",
-		   info->line, retval);
-	}
+	info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
 	CY_UNLOCK(info, flags);
-    }
-    tty_wakeup(tty);
-    wake_up_interruptible(&tty->write_wait);
-} /* cy_flush_buffer */
 
+	if (IS_CYC_Z(cy_card[card])) {	/* If it is a Z card, flush the on-board
+					   buffers as well */
+		CY_LOCK(info, flags);
+		retval =
+		    cyz_issue_cmd(&cy_card[card], channel, C_CM_FLUSH_TX, 0L);
+		if (retval != 0) {
+			printk("cyc: flush_buffer retval on ttyC%d was %x\n",
+				info->line, retval);
+		}
+		CY_UNLOCK(info, flags);
+	}
+	tty_wakeup(tty);
+	wake_up_interruptible(&tty->write_wait);
+}				/* cy_flush_buffer */
 
 /*
  * cy_hangup() --- called by tty_hangup() when a hangup is signaled.
  */
-static void
-cy_hangup(struct tty_struct *tty)
+static void cy_hangup(struct tty_struct *tty)
 {
-  struct cyclades_port * info = (struct cyclades_port *)tty->driver_data;
-        
+	struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
+
 #ifdef CY_DEBUG_OTHER
-    printk("cyc:cy_hangup ttyC%d\n", info->line); /* */
+	printk("cyc:cy_hangup ttyC%d\n", info->line);	/* */
 #endif
 
-    if (serial_paranoia_check(info, tty->name, "cy_hangup"))
-        return;
+	if (serial_paranoia_check(info, tty->name, "cy_hangup"))
+		return;
 
-    cy_flush_buffer(tty);
-    shutdown(info);
-    info->event = 0;
-    info->count = 0;
+	cy_flush_buffer(tty);
+	shutdown(info);
+	info->event = 0;
+	info->count = 0;
 #ifdef CY_DEBUG_COUNT
-    printk("cyc:cy_hangup (%d): setting count to 0\n", current->pid);
+	printk("cyc:cy_hangup (%d): setting count to 0\n", current->pid);
 #endif
-    info->tty = NULL;
-    info->flags &= ~ASYNC_NORMAL_ACTIVE;
-    wake_up_interruptible(&info->open_wait);
-} /* cy_hangup */
-
+	info->tty = NULL;
+	info->flags &= ~ASYNC_NORMAL_ACTIVE;
+	wake_up_interruptible(&info->open_wait);
+}				/* cy_hangup */
 
 /*
  * ---------------------------------------------------------------------
@@ -4433,82 +4528,84 @@ cy_hangup(struct tty_struct *tty)
 /* initialize chips on Cyclom-Y card -- return number of valid
    chips (which is number of ports/4) */
 static unsigned short __init
-cyy_init_card(void __iomem *true_base_addr,int index)
+cyy_init_card(void __iomem * true_base_addr, int index)
 {
-  unsigned int chip_number;
-  void __iomem *base_addr;
-
-    cy_writeb(true_base_addr+(Cy_HwReset<<index), 0); 
-						/* Cy_HwReset is 0x1400 */
-    cy_writeb(true_base_addr+(Cy_ClrIntr<<index), 0); 
-						/* Cy_ClrIntr is 0x1800 */
-    udelay(500L);
-
-    for(chip_number=0; chip_number<CyMAX_CHIPS_PER_CARD; chip_number++){
-        base_addr = true_base_addr + (cy_chip_offset[chip_number]<<index);
-        mdelay(1);
-        if(cy_readb(base_addr+(CyCCR<<index)) != 0x00){
-            /*************
-            printk(" chip #%d at %#6lx is never idle (CCR != 0)\n",
-               chip_number, (unsigned long)base_addr);
-            *************/
-            return chip_number;
-        }
-
-        cy_writeb(base_addr+(CyGFRCR<<index), 0);
-        udelay(10L);
-
-        /* The Cyclom-16Y does not decode address bit 9 and therefore
-           cannot distinguish between references to chip 0 and a non-
-           existent chip 4.  If the preceding clearing of the supposed
-           chip 4 GFRCR register appears at chip 0, there is no chip 4
-           and this must be a Cyclom-16Y, not a Cyclom-32Ye.
-        */
-        if (chip_number == 4
-        && cy_readb(true_base_addr
-	    + (cy_chip_offset[0]<<index)
-	    + (CyGFRCR<<index)) == 0){
-            return chip_number;
-        }
-
-        cy_writeb(base_addr+(CyCCR<<index), CyCHIP_RESET);
-        mdelay(1);
-
-        if(cy_readb(base_addr+(CyGFRCR<<index)) == 0x00){
-            /*
-            printk(" chip #%d at %#6lx is not responding ",
-               chip_number, (unsigned long)base_addr);
-            printk("(GFRCR stayed 0)\n",
-            */
-            return chip_number;
-        }
-        if((0xf0 & (cy_readb(base_addr+(CyGFRCR<<index)))) != 0x40){
-            /*
-            printk(" chip #%d at %#6lx is not valid (GFRCR == %#2x)\n",
-               chip_number, (unsigned long)base_addr,
-	       base_addr[CyGFRCR<<index]);
-            */
-            return chip_number;
-        }
-        cy_writeb(base_addr+(CyGCR<<index), CyCH0_SERIAL);
-        if (cy_readb(base_addr+(CyGFRCR<<index)) >= CD1400_REV_J){
-	    /* It is a CD1400 rev. J or later */
-	    /* Impossible to reach 5ms with this chip. 
-	       Changed to 2ms instead (f = 500 Hz). */
-	    cy_writeb(base_addr+(CyPPR<<index), CyCLOCK_60_2MS);
-	} else {
-	    /* f = 200 Hz */
-	    cy_writeb(base_addr+(CyPPR<<index), CyCLOCK_25_5MS);
-	}
+	unsigned int chip_number;
+	void __iomem *base_addr;
+
+	cy_writeb(true_base_addr + (Cy_HwReset << index), 0);
+	/* Cy_HwReset is 0x1400 */
+	cy_writeb(true_base_addr + (Cy_ClrIntr << index), 0);
+	/* Cy_ClrIntr is 0x1800 */
+	udelay(500L);
+
+	for (chip_number = 0; chip_number < CyMAX_CHIPS_PER_CARD; chip_number++) {
+		base_addr =
+		    true_base_addr + (cy_chip_offset[chip_number] << index);
+		mdelay(1);
+		if (cy_readb(base_addr + (CyCCR << index)) != 0x00) {
+			/*************
+			printk(" chip #%d at %#6lx is never idle (CCR != 0)\n",
+			chip_number, (unsigned long)base_addr);
+			*************/
+			return chip_number;
+		}
+
+		cy_writeb(base_addr + (CyGFRCR << index), 0);
+		udelay(10L);
+
+		/* The Cyclom-16Y does not decode address bit 9 and therefore
+		   cannot distinguish between references to chip 0 and a non-
+		   existent chip 4.  If the preceding clearing of the supposed
+		   chip 4 GFRCR register appears at chip 0, there is no chip 4
+		   and this must be a Cyclom-16Y, not a Cyclom-32Ye.
+		 */
+		if (chip_number == 4 && cy_readb(true_base_addr +
+				(cy_chip_offset[0] << index) +
+				(CyGFRCR << index)) == 0) {
+			return chip_number;
+		}
+
+		cy_writeb(base_addr + (CyCCR << index), CyCHIP_RESET);
+		mdelay(1);
+
+		if (cy_readb(base_addr + (CyGFRCR << index)) == 0x00) {
+			/*
+			   printk(" chip #%d at %#6lx is not responding ",
+			   chip_number, (unsigned long)base_addr);
+			   printk("(GFRCR stayed 0)\n",
+			 */
+			return chip_number;
+		}
+		if ((0xf0 & (cy_readb(base_addr + (CyGFRCR << index)))) !=
+				0x40) {
+			/*
+			printk(" chip #%d at %#6lx is not valid (GFRCR == "
+					"%#2x)\n",
+					chip_number, (unsigned long)base_addr,
+					base_addr[CyGFRCR<<index]);
+			 */
+			return chip_number;
+		}
+		cy_writeb(base_addr + (CyGCR << index), CyCH0_SERIAL);
+		if (cy_readb(base_addr + (CyGFRCR << index)) >= CD1400_REV_J) {
+			/* It is a CD1400 rev. J or later */
+			/* Impossible to reach 5ms with this chip.
+			   Changed to 2ms instead (f = 500 Hz). */
+			cy_writeb(base_addr + (CyPPR << index), CyCLOCK_60_2MS);
+		} else {
+			/* f = 200 Hz */
+			cy_writeb(base_addr + (CyPPR << index), CyCLOCK_25_5MS);
+		}
 
-    /*
-        printk(" chip #%d at %#6lx is rev 0x%2x\n",
-               chip_number, (unsigned long)base_addr,
-	       cy_readb(base_addr+(CyGFRCR<<index)));
-    */
-    }
-    return chip_number;
-} /* cyy_init_card */
+		/*
+		   printk(" chip #%d at %#6lx is rev 0x%2x\n",
+		   chip_number, (unsigned long)base_addr,
+		   cy_readb(base_addr+(CyGFRCR<<index)));
+		 */
+	}
+	return chip_number;
+}				/* cyy_init_card */
 
 /*
  * ---------------------------------------------------------------------
@@ -4516,126 +4613,124 @@ cyy_init_card(void __iomem *true_base_addr,int index)
  * sets global variables and return the number of ISA boards found.
  * ---------------------------------------------------------------------
  */
-static int __init
-cy_detect_isa(void)
+static int __init cy_detect_isa(void)
 {
 #ifdef CONFIG_ISA
-  unsigned short	cy_isa_irq,nboard;
-  void __iomem		*cy_isa_address;
-  unsigned short	i,j,cy_isa_nchan;
+	unsigned short cy_isa_irq, nboard;
+	void __iomem *cy_isa_address;
+	unsigned short i, j, cy_isa_nchan;
 #ifdef MODULE
-  int isparam = 0;
+	int isparam = 0;
 #endif
 
-        nboard = 0;
+	nboard = 0;
 
 #ifdef MODULE
 	/* Check for module parameters */
-	for(i = 0 ; i < NR_CARDS; i++) {
-	    if (maddr[i] || i) {
-		isparam = 1;
-		cy_isa_addresses[i] = maddr[i];
-	    }
-	    if (!maddr[i])
-		break;
+	for (i = 0; i < NR_CARDS; i++) {
+		if (maddr[i] || i) {
+			isparam = 1;
+			cy_isa_addresses[i] = maddr[i];
+		}
+		if (!maddr[i])
+			break;
 	}
 #endif
 
-        /* scan the address table probing for Cyclom-Y/ISA boards */
-        for (i = 0 ; i < NR_ISA_ADDRS ; i++) {
-        	unsigned int isa_address = cy_isa_addresses[i];
-                if (isa_address  == 0x0000) {
-                        return(nboard);
-                }
+	/* scan the address table probing for Cyclom-Y/ISA boards */
+	for (i = 0; i < NR_ISA_ADDRS; i++) {
+		unsigned int isa_address = cy_isa_addresses[i];
+		if (isa_address == 0x0000) {
+			return nboard;
+		}
 
-                /* probe for CD1400... */
+		/* probe for CD1400... */
 		cy_isa_address = ioremap(isa_address, CyISA_Ywin);
-                cy_isa_nchan = CyPORTS_PER_CHIP * 
-                     cyy_init_card(cy_isa_address,0);
-                if (cy_isa_nchan == 0) {
-                        continue;
-                }
-
+		cy_isa_nchan = CyPORTS_PER_CHIP *
+			cyy_init_card(cy_isa_address, 0);
+		if (cy_isa_nchan == 0) {
+			continue;
+		}
 #ifdef MODULE
 		if (isparam && irq[i])
-		    cy_isa_irq = irq[i];
+			cy_isa_irq = irq[i];
 		else
 #endif
-                /* find out the board's irq by probing */
-                cy_isa_irq = detect_isa_irq(cy_isa_address);
-                if (cy_isa_irq == 0) {
-                        printk("Cyclom-Y/ISA found at 0x%lx ",
-                                (unsigned long) cy_isa_address);
-                        printk("but the IRQ could not be detected.\n");
-                        continue;
-                }
-
-                if((cy_next_channel+cy_isa_nchan) > NR_PORTS) {
-                        printk("Cyclom-Y/ISA found at 0x%lx ",
-                                (unsigned long) cy_isa_address);
-                        printk("but no more channels are available.\n");
-                        printk("Change NR_PORTS in cyclades.c and recompile kernel.\n");
-                        return(nboard);
-                }
-                /* fill the next cy_card structure available */
-                for (j = 0 ; j < NR_CARDS ; j++) {
-                        if (cy_card[j].base_addr == 0)  break;
-                }
-                if (j == NR_CARDS) {    /* no more cy_cards available */
-                        printk("Cyclom-Y/ISA found at 0x%lx ",
-                                (unsigned long) cy_isa_address);
-                        printk("but no more cards can be used .\n");
-                        printk("Change NR_CARDS in cyclades.c and recompile kernel.\n");
-                        return(nboard);
-                }
-
-                /* allocate IRQ */
-                if(request_irq(cy_isa_irq, cyy_interrupt,
-				   IRQF_DISABLED, "Cyclom-Y", &cy_card[j]))
-                {
-                        printk("Cyclom-Y/ISA found at 0x%lx ",
-                                (unsigned long) cy_isa_address);
-                        printk("but could not allocate IRQ#%d.\n",
-                                cy_isa_irq);
-                        return(nboard);
-                }
-
-                /* set cy_card */
-                cy_card[j].base_addr = cy_isa_address;
-                cy_card[j].ctl_addr = NULL;
-                cy_card[j].irq = (int) cy_isa_irq;
-                cy_card[j].bus_index = 0;
-                cy_card[j].first_line = cy_next_channel;
-                cy_card[j].num_chips = cy_isa_nchan/4;
-                nboard++;
-                        
-                /* print message */
-                printk("Cyclom-Y/ISA #%d: 0x%lx-0x%lx, IRQ%d, ",
-                    j+1, (unsigned long) cy_isa_address,
-                    (unsigned long)(cy_isa_address + (CyISA_Ywin - 1)),
-		    cy_isa_irq);
-                printk("%d channels starting from port %d.\n",
-                        cy_isa_nchan, cy_next_channel);
-                cy_next_channel += cy_isa_nchan;
-        }
-        return(nboard);
+			/* find out the board's irq by probing */
+			cy_isa_irq = detect_isa_irq(cy_isa_address);
+		if (cy_isa_irq == 0) {
+			printk("Cyclom-Y/ISA found at 0x%lx ",
+				(unsigned long)cy_isa_address);
+			printk("but the IRQ could not be detected.\n");
+			continue;
+		}
+
+		if ((cy_next_channel + cy_isa_nchan) > NR_PORTS) {
+			printk("Cyclom-Y/ISA found at 0x%lx ",
+				(unsigned long)cy_isa_address);
+			printk("but no more channels are available.\n");
+			printk("Change NR_PORTS in cyclades.c and recompile "
+					"kernel.\n");
+			return nboard;
+		}
+		/* fill the next cy_card structure available */
+		for (j = 0; j < NR_CARDS; j++) {
+			if (cy_card[j].base_addr == 0)
+				break;
+		}
+		if (j == NR_CARDS) {	/* no more cy_cards available */
+			printk("Cyclom-Y/ISA found at 0x%lx ",
+				(unsigned long)cy_isa_address);
+			printk("but no more cards can be used .\n");
+			printk("Change NR_CARDS in cyclades.c and recompile "
+					"kernel.\n");
+			return nboard;
+		}
+
+		/* allocate IRQ */
+		if (request_irq(cy_isa_irq, cyy_interrupt,
+				IRQF_DISABLED, "Cyclom-Y", &cy_card[j])) {
+			printk("Cyclom-Y/ISA found at 0x%lx ",
+				(unsigned long)cy_isa_address);
+			printk("but could not allocate IRQ#%d.\n", cy_isa_irq);
+			return nboard;
+		}
+
+		/* set cy_card */
+		cy_card[j].base_addr = cy_isa_address;
+		cy_card[j].ctl_addr = NULL;
+		cy_card[j].irq = (int)cy_isa_irq;
+		cy_card[j].bus_index = 0;
+		cy_card[j].first_line = cy_next_channel;
+		cy_card[j].num_chips = cy_isa_nchan / 4;
+		nboard++;
+
+		/* print message */
+		printk("Cyclom-Y/ISA #%d: 0x%lx-0x%lx, IRQ%d, ",
+			j + 1, (unsigned long)cy_isa_address,
+			(unsigned long)(cy_isa_address + (CyISA_Ywin - 1)),
+			cy_isa_irq);
+		printk("%d channels starting from port %d.\n",
+			cy_isa_nchan, cy_next_channel);
+		cy_next_channel += cy_isa_nchan;
+	}
+	return nboard;
 #else
-        return(0);
-#endif /* CONFIG_ISA */
-} /* cy_detect_isa */
+	return 0;
+#endif				/* CONFIG_ISA */
+}				/* cy_detect_isa */
 
-static void 
-plx_init(void __iomem *addr, uclong initctl)
+static void plx_init(void __iomem * addr, uclong initctl)
 {
-    /* Reset PLX */
-    cy_writel(addr + initctl, cy_readl(addr + initctl) | 0x40000000);
-    udelay(100L);
-    cy_writel(addr + initctl, cy_readl(addr + initctl) & ~0x40000000);
-
-    /* Reload Config. Registers from EEPROM */
-    cy_writel(addr + initctl, cy_readl(addr + initctl) | 0x20000000);
-    udelay(100L);
-    cy_writel(addr + initctl, cy_readl(addr + initctl) & ~0x20000000);
+	/* Reset PLX */
+	cy_writel(addr + initctl, cy_readl(addr + initctl) | 0x40000000);
+	udelay(100L);
+	cy_writel(addr + initctl, cy_readl(addr + initctl) & ~0x40000000);
+
+	/* Reload Config. Registers from EEPROM */
+	cy_writel(addr + initctl, cy_readl(addr + initctl) | 0x20000000);
+	udelay(100L);
+	cy_writel(addr + initctl, cy_readl(addr + initctl) & ~0x20000000);
 }
 
 /*
@@ -4644,43 +4739,42 @@ plx_init(void __iomem *addr, uclong initctl)
  * sets global variables and return the number of PCI boards found.
  * ---------------------------------------------------------------------
  */
-static int __init
-cy_detect_pci(void)
+static int __init cy_detect_pci(void)
 {
 #ifdef CONFIG_PCI
 
-  struct pci_dev	*pdev = NULL;
-  unsigned char		cyy_rev_id;
-  unsigned char		cy_pci_irq = 0;
-  uclong		cy_pci_phys0, cy_pci_phys2;
-  void __iomem		*cy_pci_addr0, *cy_pci_addr2;
-  unsigned short	i,j,cy_pci_nchan, plx_ver;
-  unsigned short	device_id,dev_index = 0;
-  uclong		mailbox;
-  uclong		ZeIndex = 0;
-  void __iomem		*Ze_addr0[NR_CARDS], *Ze_addr2[NR_CARDS];
-  uclong		Ze_phys0[NR_CARDS], Ze_phys2[NR_CARDS];
-  unsigned char		Ze_irq[NR_CARDS];
-  struct pci_dev	*Ze_pdev[NR_CARDS];
-
-        for (i = 0; i < NR_CARDS; i++) {
-                /* look for a Cyclades card by vendor and device id */
-                while((device_id = cy_pci_dev_id[dev_index]) != 0) {
-                        if((pdev = pci_get_device(PCI_VENDOR_ID_CYCLADES,
-                                        device_id, pdev)) == NULL) {
-                                dev_index++;    /* try next device id */
-                        } else {
-                                break;          /* found a board */
-                        }
-                }
+	struct pci_dev *pdev = NULL;
+	unsigned char cyy_rev_id;
+	unsigned char cy_pci_irq = 0;
+	uclong cy_pci_phys0, cy_pci_phys2;
+	void __iomem *cy_pci_addr0, *cy_pci_addr2;
+	unsigned short i, j, cy_pci_nchan, plx_ver;
+	unsigned short device_id, dev_index = 0;
+	uclong mailbox;
+	uclong ZeIndex = 0;
+	void __iomem *Ze_addr0[NR_CARDS], *Ze_addr2[NR_CARDS];
+	uclong Ze_phys0[NR_CARDS], Ze_phys2[NR_CARDS];
+	unsigned char Ze_irq[NR_CARDS];
+	struct pci_dev *Ze_pdev[NR_CARDS];
+
+	for (i = 0; i < NR_CARDS; i++) {
+		/* look for a Cyclades card by vendor and device id */
+		while ((device_id = cy_pci_dev_id[dev_index]) != 0) {
+			if ((pdev = pci_get_device(PCI_VENDOR_ID_CYCLADES,
+						   device_id, pdev)) == NULL) {
+				dev_index++;	/* try next device id */
+			} else {
+				break;	/* found a board */
+			}
+		}
 
 		if (device_id == 0)
-		    break;
+			break;
 
 		if (pci_enable_device(pdev))
-		    continue;
+			continue;
 
-                /* read PCI configuration area */
+		/* read PCI configuration area */
 		cy_pci_irq = pdev->irq;
 		cy_pci_phys0 = pci_resource_start(pdev, 0);
 		cy_pci_phys2 = pci_resource_start(pdev, 2);
@@ -4688,482 +4782,497 @@ cy_detect_pci(void)
 
 		device_id &= ~PCI_DEVICE_ID_MASK;
 
-    if ((device_id == PCI_DEVICE_ID_CYCLOM_Y_Lo)
-	   || (device_id == PCI_DEVICE_ID_CYCLOM_Y_Hi)){
+		if (device_id == PCI_DEVICE_ID_CYCLOM_Y_Lo ||
+				device_id == PCI_DEVICE_ID_CYCLOM_Y_Hi) {
 #ifdef CY_PCI_DEBUG
-            printk("Cyclom-Y/PCI (bus=0x0%x, pci_id=0x%x, ",
-		pdev->bus->number, pdev->devfn);
-            printk("rev_id=%d) IRQ%d\n",
-		cyy_rev_id, (int)cy_pci_irq);
-            printk("Cyclom-Y/PCI:found  winaddr=0x%lx ctladdr=0x%lx\n",
-		(ulong)cy_pci_phys2, (ulong)cy_pci_phys0);
+			printk("Cyclom-Y/PCI (bus=0x0%x, pci_id=0x%x, ",
+				pdev->bus->number, pdev->devfn);
+			printk("rev_id=%d) IRQ%d\n",
+				cyy_rev_id, (int)cy_pci_irq);
+			printk("Cyclom-Y/PCI:found  winaddr=0x%lx "
+				"ctladdr=0x%lx\n",
+				(ulong)cy_pci_phys2, (ulong)cy_pci_phys0);
 #endif
 
-		if (pci_resource_flags(pdev, 2) & IORESOURCE_IO) {
-		    printk("  Warning: PCI I/O bit incorrectly set. "
-			   "Ignoring it...\n");
-		    pdev->resource[2].flags &= ~IORESOURCE_IO;
-		}
-
-		/* Although we don't use this I/O region, we should
-		   request it from the kernel anyway, to avoid problems
-		   with other drivers accessing it. */
-		if (pci_request_regions(pdev, "Cyclom-Y") != 0) {
-			printk(KERN_ERR "cyclades: failed to reserve PCI resources\n");
-			continue;
-		}
+			if (pci_resource_flags(pdev, 2) & IORESOURCE_IO) {
+				printk("  Warning: PCI I/O bit incorrectly "
+					"set. Ignoring it...\n");
+				pdev->resource[2].flags &= ~IORESOURCE_IO;
+			}
 
+			/* Although we don't use this I/O region, we should
+			   request it from the kernel anyway, to avoid problems
+			   with other drivers accessing it. */
+			if (pci_request_regions(pdev, "Cyclom-Y") != 0) {
+				printk(KERN_ERR "cyclades: failed to reserve "
+						"PCI resources\n");
+				continue;
+			}
 #if defined(__alpha__)
-                if (device_id  == PCI_DEVICE_ID_CYCLOM_Y_Lo) { /* below 1M? */
-		    printk("Cyclom-Y/PCI (bus=0x0%x, pci_id=0x%x, ",
-			pdev->bus->number, pdev->devfn);
-		    printk("rev_id=%d) IRQ%d\n",
-		        cyy_rev_id, (int)cy_pci_irq);
-                    printk("Cyclom-Y/PCI:found  winaddr=0x%lx ctladdr=0x%lx\n",
-		        (ulong)cy_pci_phys2, (ulong)cy_pci_phys0);
-	            printk("Cyclom-Y/PCI not supported for low addresses in "
-                           "Alpha systems.\n");
-		    i--;
-	            continue;
-                }
+			if (device_id == PCI_DEVICE_ID_CYCLOM_Y_Lo) {	/* below 1M? */
+				printk("Cyclom-Y/PCI (bus=0x0%x, pci_id=0x%x, ",
+					pdev->bus->number, pdev->devfn);
+				printk("rev_id=%d) IRQ%d\n",
+					cyy_rev_id, (int)cy_pci_irq);
+				printk("Cyclom-Y/PCI:found  winaddr=0x%lx "
+					"ctladdr=0x%lx\n",
+					(ulong)cy_pci_phys2,
+					(ulong)cy_pci_phys0);
+				printk("Cyclom-Y/PCI not supported for low "
+					"addresses in Alpha systems.\n");
+				i--;
+				continue;
+			}
 #endif
-		cy_pci_addr0 = ioremap(cy_pci_phys0, CyPCI_Yctl);
-		cy_pci_addr2 = ioremap(cy_pci_phys2, CyPCI_Ywin);
+			cy_pci_addr0 = ioremap(cy_pci_phys0, CyPCI_Yctl);
+			cy_pci_addr2 = ioremap(cy_pci_phys2, CyPCI_Ywin);
 
 #ifdef CY_PCI_DEBUG
-            printk("Cyclom-Y/PCI: relocate winaddr=0x%lx ctladdr=0x%lx\n",
-		(u_long)cy_pci_addr2, (u_long)cy_pci_addr0);
+			printk("Cyclom-Y/PCI: relocate winaddr=0x%lx "
+				"ctladdr=0x%lx\n",
+				(u_long)cy_pci_addr2, (u_long)cy_pci_addr0);
 #endif
-                cy_pci_nchan = (unsigned short)(CyPORTS_PER_CHIP * 
-                       cyy_init_card(cy_pci_addr2, 1));
-                if(cy_pci_nchan == 0) {
-                        printk("Cyclom-Y PCI host card with ");
-                        printk("no Serial-Modules at 0x%lx.\n",
-			    (ulong) cy_pci_phys2);
-                        i--;
-                        continue;
-                }
-                if((cy_next_channel+cy_pci_nchan) > NR_PORTS) {
-                        printk("Cyclom-Y/PCI found at 0x%lx ",
-			    (ulong) cy_pci_phys2);
-                        printk("but no channels are available.\n");
-                        printk("Change NR_PORTS in cyclades.c and recompile kernel.\n");
-                        return(i);
-                }
-                /* fill the next cy_card structure available */
-                for (j = 0 ; j < NR_CARDS ; j++) {
-                        if (cy_card[j].base_addr == 0)  break;
-                }
-                if (j == NR_CARDS) {    /* no more cy_cards available */
-                        printk("Cyclom-Y/PCI found at 0x%lx ",
-			    (ulong) cy_pci_phys2);
-                        printk("but no more cards can be used.\n");
-                        printk("Change NR_CARDS in cyclades.c and recompile kernel.\n");
-                        return(i);
-                }
-
-                /* allocate IRQ */
-                if(request_irq(cy_pci_irq, cyy_interrupt,
-		        IRQF_SHARED, "Cyclom-Y", &cy_card[j]))
-                {
-                        printk("Cyclom-Y/PCI found at 0x%lx ",
-			    (ulong) cy_pci_phys2);
-                        printk("but could not allocate IRQ%d.\n",
-			    cy_pci_irq);
-                        return(i);
-                }
-
-                /* set cy_card */
-                cy_card[j].base_phys = (ulong)cy_pci_phys2;
-                cy_card[j].ctl_phys = (ulong)cy_pci_phys0;
-                cy_card[j].base_addr = cy_pci_addr2;
-                cy_card[j].ctl_addr = cy_pci_addr0;
-                cy_card[j].irq = (int) cy_pci_irq;
-                cy_card[j].bus_index = 1;
-                cy_card[j].first_line = cy_next_channel;
-                cy_card[j].num_chips = cy_pci_nchan/4;
-		cy_card[j].pdev = pdev;
-	
-                /* enable interrupts in the PCI interface */
-		plx_ver = cy_readb(cy_pci_addr2 + CyPLX_VER) & 0x0f;
-		switch (plx_ver) {
-		    case PLX_9050:
-
-		    cy_writeb(cy_pci_addr0+0x4c, 0x43);
-		    break;
-
-		    case PLX_9060:
-		    case PLX_9080:
-		    default: /* Old boards, use PLX_9060 */
-
-		    plx_init(cy_pci_addr0, 0x6c);
-		    /* For some yet unknown reason, once the PLX9060 reloads
-		       the EEPROM, the IRQ is lost and, thus, we have to
-		       re-write it to the PCI config. registers.
-		       This will remain here until we find a permanent fix. */
-		    pci_write_config_byte(pdev, PCI_INTERRUPT_LINE, cy_pci_irq);
-
-		    cy_writew(cy_pci_addr0+0x68, 
-			cy_readw(cy_pci_addr0+0x68)|0x0900);
-		    break;
-		}
+			cy_pci_nchan = (unsigned short)(CyPORTS_PER_CHIP *
+					cyy_init_card(cy_pci_addr2, 1));
+			if (cy_pci_nchan == 0) {
+				printk("Cyclom-Y PCI host card with ");
+				printk("no Serial-Modules at 0x%lx.\n",
+					(ulong) cy_pci_phys2);
+				i--;
+				continue;
+			}
+			if ((cy_next_channel + cy_pci_nchan) > NR_PORTS) {
+				printk("Cyclom-Y/PCI found at 0x%lx ",
+					(ulong) cy_pci_phys2);
+				printk("but no channels are available.\n");
+				printk("Change NR_PORTS in cyclades.c and "
+						"recompile kernel.\n");
+				return i;
+			}
+			/* fill the next cy_card structure available */
+			for (j = 0; j < NR_CARDS; j++) {
+				if (cy_card[j].base_addr == 0)
+					break;
+			}
+			if (j == NR_CARDS) {	/* no more cy_cards available */
+				printk("Cyclom-Y/PCI found at 0x%lx ",
+					(ulong) cy_pci_phys2);
+				printk("but no more cards can be used.\n");
+				printk("Change NR_CARDS in cyclades.c and "
+						"recompile kernel.\n");
+				return i;
+			}
+
+			/* allocate IRQ */
+			if (request_irq(cy_pci_irq, cyy_interrupt,
+					IRQF_SHARED, "Cyclom-Y", &cy_card[j])) {
+				printk("Cyclom-Y/PCI found at 0x%lx ",
+					(ulong) cy_pci_phys2);
+				printk("but could not allocate IRQ%d.\n",
+					cy_pci_irq);
+				return i;
+			}
 
-                /* print message */
-                printk("Cyclom-Y/PCI #%d: 0x%lx-0x%lx, IRQ%d, ",
-		       j+1, 
-		       (ulong)cy_pci_phys2, 
-		       (ulong)(cy_pci_phys2 + CyPCI_Ywin - 1),
-		       (int)cy_pci_irq);
-                printk("%d channels starting from port %d.\n",
-		    cy_pci_nchan, cy_next_channel);
-
-                cy_next_channel += cy_pci_nchan;
-    }else if (device_id == PCI_DEVICE_ID_CYCLOM_Z_Lo){
-	    /* print message */
-		printk("Cyclades-Z/PCI (bus=0x0%x, pci_id=0x%x, ",
-		    pdev->bus->number, pdev->devfn);
-		printk("rev_id=%d) IRQ%d\n",
-		    cyy_rev_id, (int)cy_pci_irq);
-		printk("Cyclades-Z/PCI: found winaddr=0x%lx ctladdr=0x%lx\n",
-		    (ulong)cy_pci_phys2, (ulong)cy_pci_phys0);
-	    printk("Cyclades-Z/PCI not supported for low addresses\n");
-	    break;
-    }else if (device_id == PCI_DEVICE_ID_CYCLOM_Z_Hi){
+			/* set cy_card */
+			cy_card[j].base_phys = (ulong) cy_pci_phys2;
+			cy_card[j].ctl_phys = (ulong) cy_pci_phys0;
+			cy_card[j].base_addr = cy_pci_addr2;
+			cy_card[j].ctl_addr = cy_pci_addr0;
+			cy_card[j].irq = (int)cy_pci_irq;
+			cy_card[j].bus_index = 1;
+			cy_card[j].first_line = cy_next_channel;
+			cy_card[j].num_chips = cy_pci_nchan / 4;
+			cy_card[j].pdev = pdev;
+
+			/* enable interrupts in the PCI interface */
+			plx_ver = cy_readb(cy_pci_addr2 + CyPLX_VER) & 0x0f;
+			switch (plx_ver) {
+			case PLX_9050:
+
+				cy_writeb(cy_pci_addr0 + 0x4c, 0x43);
+				break;
+
+			case PLX_9060:
+			case PLX_9080:
+			default:	/* Old boards, use PLX_9060 */
+
+				plx_init(cy_pci_addr0, 0x6c);
+			/* For some yet unknown reason, once the PLX9060 reloads
+			   the EEPROM, the IRQ is lost and, thus, we have to
+			   re-write it to the PCI config. registers.
+			   This will remain here until we find a permanent
+			   fix. */
+				pci_write_config_byte(pdev, PCI_INTERRUPT_LINE,
+						cy_pci_irq);
+
+				cy_writew(cy_pci_addr0 + 0x68,
+					  cy_readw(cy_pci_addr0 +
+						   0x68) | 0x0900);
+				break;
+			}
+
+			/* print message */
+			printk("Cyclom-Y/PCI #%d: 0x%lx-0x%lx, IRQ%d, ",
+				j + 1, (ulong)cy_pci_phys2,
+				(ulong) (cy_pci_phys2 + CyPCI_Ywin - 1),
+				(int)cy_pci_irq);
+			printk("%d channels starting from port %d.\n",
+				cy_pci_nchan, cy_next_channel);
+
+			cy_next_channel += cy_pci_nchan;
+		} else if (device_id == PCI_DEVICE_ID_CYCLOM_Z_Lo) {
+			/* print message */
+			printk("Cyclades-Z/PCI (bus=0x0%x, pci_id=0x%x, ",
+				pdev->bus->number, pdev->devfn);
+			printk("rev_id=%d) IRQ%d\n",
+				cyy_rev_id, (int)cy_pci_irq);
+			printk("Cyclades-Z/PCI: found winaddr=0x%lx "
+				"ctladdr=0x%lx\n",
+				(ulong)cy_pci_phys2, (ulong)cy_pci_phys0);
+			printk("Cyclades-Z/PCI not supported for low "
+				"addresses\n");
+			break;
+		} else if (device_id == PCI_DEVICE_ID_CYCLOM_Z_Hi) {
 #ifdef CY_PCI_DEBUG
-            printk("Cyclades-Z/PCI (bus=0x0%x, pci_id=0x%x, ",
-	        pdev->bus->number, pdev->devfn);
-            printk("rev_id=%d) IRQ%d\n",
-		cyy_rev_id, (int)cy_pci_irq);
-            printk("Cyclades-Z/PCI: found winaddr=0x%lx ctladdr=0x%lx\n",
-                (ulong)cy_pci_phys2, (ulong)cy_pci_phys0);
+			printk("Cyclades-Z/PCI (bus=0x0%x, pci_id=0x%x, ",
+				pdev->bus->number, pdev->devfn);
+			printk("rev_id=%d) IRQ%d\n",
+				cyy_rev_id, (int)cy_pci_irq);
+			printk("Cyclades-Z/PCI: found winaddr=0x%lx "
+				"ctladdr=0x%lx\n",
+				(ulong) cy_pci_phys2, (ulong) cy_pci_phys0);
 #endif
-		cy_pci_addr0 = ioremap(cy_pci_phys0, CyPCI_Zctl);
-
-		/* Disable interrupts on the PLX before resetting it */
-		cy_writew(cy_pci_addr0+0x68,
-			cy_readw(cy_pci_addr0+0x68) & ~0x0900);
-
-		plx_init(cy_pci_addr0, 0x6c);
-		/* For some yet unknown reason, once the PLX9060 reloads
-		   the EEPROM, the IRQ is lost and, thus, we have to
-		   re-write it to the PCI config. registers.
-		   This will remain here until we find a permanent fix. */
-		pci_write_config_byte(pdev, PCI_INTERRUPT_LINE, cy_pci_irq);
-
-		mailbox = (uclong)cy_readl(&((struct RUNTIME_9060 __iomem *) 
-			   cy_pci_addr0)->mail_box_0);
-
-		if (pci_resource_flags(pdev, 2) & IORESOURCE_IO) {
-		    printk("  Warning: PCI I/O bit incorrectly set. "
-			   "Ignoring it...\n");
-		    pdev->resource[2].flags &= ~IORESOURCE_IO;
-		}
+			cy_pci_addr0 = ioremap(cy_pci_phys0, CyPCI_Zctl);
+
+			/* Disable interrupts on the PLX before resetting it */
+			cy_writew(cy_pci_addr0 + 0x68,
+				cy_readw(cy_pci_addr0 + 0x68) & ~0x0900);
+
+			plx_init(cy_pci_addr0, 0x6c);
+			/* For some yet unknown reason, once the PLX9060 reloads
+			   the EEPROM, the IRQ is lost and, thus, we have to
+			   re-write it to the PCI config. registers.
+			   This will remain here until we find a permanent
+			   fix. */
+			pci_write_config_byte(pdev, PCI_INTERRUPT_LINE,
+						cy_pci_irq);
+
+			mailbox =
+			    (uclong)cy_readl(&((struct RUNTIME_9060 __iomem *)
+						cy_pci_addr0)->mail_box_0);
+
+			if (pci_resource_flags(pdev, 2) & IORESOURCE_IO) {
+				printk("  Warning: PCI I/O bit incorrectly "
+					"set. Ignoring it...\n");
+				pdev->resource[2].flags &= ~IORESOURCE_IO;
+			}
 
-		/* Although we don't use this I/O region, we should
-		   request it from the kernel anyway, to avoid problems
-		   with other drivers accessing it. */
-		if (pci_request_regions(pdev, "Cyclades-Z") != 0) {
-			printk(KERN_ERR "cyclades: failed to reserve PCI resources\n");
-			continue;
-		}
-	
-		if (mailbox == ZE_V1) {
-		    cy_pci_addr2 = ioremap(cy_pci_phys2, CyPCI_Ze_win);
-		    if (ZeIndex == NR_CARDS) {
-			printk("Cyclades-Ze/PCI found at 0x%lx ",
-				(ulong)cy_pci_phys2);
-			printk("but no more cards can be used.\n");
-                        printk("Change NR_CARDS in cyclades.c and recompile kernel.\n");
-		    } else {
-			Ze_phys0[ZeIndex] = cy_pci_phys0;
-			Ze_phys2[ZeIndex] = cy_pci_phys2;
-			Ze_addr0[ZeIndex] = cy_pci_addr0;
-			Ze_addr2[ZeIndex] = cy_pci_addr2;
-			Ze_irq[ZeIndex] = cy_pci_irq;
-			Ze_pdev[ZeIndex] = pdev;
-			ZeIndex++;
-		    }
-		    i--;
-		    continue;
-		} else {
-		    cy_pci_addr2 = ioremap(cy_pci_phys2, CyPCI_Zwin);
-		}
+			/* Although we don't use this I/O region, we should
+			   request it from the kernel anyway, to avoid problems
+			   with other drivers accessing it. */
+			if (pci_request_regions(pdev, "Cyclades-Z") != 0) {
+				printk(KERN_ERR "cyclades: failed to reserve "
+					"PCI resources\n");
+				continue;
+			}
+
+			if (mailbox == ZE_V1) {
+				cy_pci_addr2 = ioremap(cy_pci_phys2,
+						CyPCI_Ze_win);
+				if (ZeIndex == NR_CARDS) {
+					printk("Cyclades-Ze/PCI found at "
+						"0x%lx but no more cards can "
+						"be used.\nChange NR_CARDS in "
+						"cyclades.c and recompile "
+						"kernel.\n",
+						(ulong)cy_pci_phys2);
+				} else {
+					Ze_phys0[ZeIndex] = cy_pci_phys0;
+					Ze_phys2[ZeIndex] = cy_pci_phys2;
+					Ze_addr0[ZeIndex] = cy_pci_addr0;
+					Ze_addr2[ZeIndex] = cy_pci_addr2;
+					Ze_irq[ZeIndex] = cy_pci_irq;
+					Ze_pdev[ZeIndex] = pdev;
+					ZeIndex++;
+				}
+				i--;
+				continue;
+			} else {
+				cy_pci_addr2 = ioremap(cy_pci_phys2,CyPCI_Zwin);
+			}
 
 #ifdef CY_PCI_DEBUG
-            printk("Cyclades-Z/PCI: relocate winaddr=0x%lx ctladdr=0x%lx\n",
-                (ulong)cy_pci_addr2, (ulong)cy_pci_addr0);
-	    if (mailbox == ZO_V1) {
-		cy_writel(&((struct RUNTIME_9060 *)
-			  (cy_pci_addr0))->loc_addr_base, WIN_CREG);
-		PAUSE
-		printk("Cyclades-8Zo/PCI: FPGA id %lx, ver %lx\n",
-		       (ulong)(0xff & cy_readl(&((struct CUSTOM_REG *)
-		        (cy_pci_addr2))->fpga_id)),
-		       (ulong)(0xff & cy_readl(&((struct CUSTOM_REG *)
-		        (cy_pci_addr2))->fpga_version)));
-		cy_writel(&((struct RUNTIME_9060 *)
-			  (cy_pci_addr0))->loc_addr_base, WIN_RAM);
-	    } else {
-		printk("Cyclades-Z/PCI: New Cyclades-Z board.  FPGA not loaded\n");
-	    }
+			printk("Cyclades-Z/PCI: relocate winaddr=0x%lx "
+				"ctladdr=0x%lx\n",
+				(ulong) cy_pci_addr2, (ulong) cy_pci_addr0);
+			if (mailbox == ZO_V1) {
+				cy_writel(&((struct RUNTIME_9060 *)
+					(cy_pci_addr0))->loc_addr_base,
+					WIN_CREG);
+				PAUSE;
+				printk("Cyclades-8Zo/PCI: FPGA id %lx, ver "
+					"%lx\n", (ulong) (0xff &
+					cy_readl(&((struct CUSTOM_REG *)
+						(cy_pci_addr2))->fpga_id)),
+					(ulong)(0xff &
+					cy_readl(&((struct CUSTOM_REG *)
+						(cy_pci_addr2))->
+							fpga_version)));
+				cy_writel(&((struct RUNTIME_9060 *)
+					(cy_pci_addr0))->loc_addr_base,
+					WIN_RAM);
+			} else {
+				printk("Cyclades-Z/PCI: New Cyclades-Z board.  "
+						"FPGA not loaded\n");
+			}
 #endif
-	    /* The following clears the firmware id word.  This ensures
-	       that the driver will not attempt to talk to the board
-	       until it has been properly initialized.
-	     */
-		PAUSE
-		if ((mailbox == ZO_V1) || (mailbox == ZO_V2))
-		    cy_writel(cy_pci_addr2 + ID_ADDRESS, 0L);
-
-                /* This must be a Cyclades-8Zo/PCI.  The extendable
-                   version will have a different device_id and will
-                   be allocated its maximum number of ports. */
-                cy_pci_nchan = 8;
-
-                if((cy_next_channel+cy_pci_nchan) > NR_PORTS) {
-                        printk("Cyclades-8Zo/PCI found at 0x%lx ",
-			    (ulong)cy_pci_phys2);
-                        printk("but no channels are available.\n");
-                        printk("Change NR_PORTS in cyclades.c and recompile kernel.\n");
-                        return(i);
-                }
-
-                /* fill the next cy_card structure available */
-                for (j = 0 ; j < NR_CARDS ; j++) {
-                        if (cy_card[j].base_addr == 0)  break;
-                }
-                if (j == NR_CARDS) {    /* no more cy_cards available */
-		    printk("Cyclades-8Zo/PCI found at 0x%lx ",
-			(ulong)cy_pci_phys2);
-		    printk("but no more cards can be used.\n");
-                    printk("Change NR_CARDS in cyclades.c and recompile kernel.\n");
-		    return(i);
-                }
+			/* The following clears the firmware id word.  This
+			   ensures that the driver will not attempt to talk to
+			   the board until it has been properly initialized.
+			 */
+			PAUSE;
+			if ((mailbox == ZO_V1) || (mailbox == ZO_V2))
+				cy_writel(cy_pci_addr2 + ID_ADDRESS, 0L);
+
+			/* This must be a Cyclades-8Zo/PCI.  The extendable
+			   version will have a different device_id and will
+			   be allocated its maximum number of ports. */
+			cy_pci_nchan = 8;
+
+			if ((cy_next_channel + cy_pci_nchan) > NR_PORTS) {
+				printk("Cyclades-8Zo/PCI found at 0x%lx but"
+					"no channels are available.\nChange "
+					"NR_PORTS in cyclades.c and recompile "
+					"kernel.\n", (ulong)cy_pci_phys2);
+				return i;
+			}
 
+			/* fill the next cy_card structure available */
+			for (j = 0; j < NR_CARDS; j++) {
+				if (cy_card[j].base_addr == 0)
+					break;
+			}
+			if (j == NR_CARDS) {	/* no more cy_cards available */
+				printk("Cyclades-8Zo/PCI found at 0x%lx but"
+					"no more cards can be used.\nChange "
+					"NR_CARDS in cyclades.c and recompile "
+					"kernel.\n", (ulong)cy_pci_phys2);
+				return i;
+			}
+#ifdef CONFIG_CYZ_INTR
+			/* allocate IRQ only if board has an IRQ */
+			if ((cy_pci_irq != 0) && (cy_pci_irq != 255)) {
+				if (request_irq(cy_pci_irq, cyz_interrupt,
+						IRQF_SHARED, "Cyclades-Z",
+						&cy_card[j])) {
+					printk("Cyclom-8Zo/PCI found at 0x%lx "
+						"but could not allocate "
+						"IRQ%d.\n", (ulong)cy_pci_phys2,
+						cy_pci_irq);
+					return i;
+				}
+			}
+#endif				/* CONFIG_CYZ_INTR */
+
+			/* set cy_card */
+			cy_card[j].base_phys = cy_pci_phys2;
+			cy_card[j].ctl_phys = cy_pci_phys0;
+			cy_card[j].base_addr = cy_pci_addr2;
+			cy_card[j].ctl_addr = cy_pci_addr0;
+			cy_card[j].irq = (int)cy_pci_irq;
+			cy_card[j].bus_index = 1;
+			cy_card[j].first_line = cy_next_channel;
+			cy_card[j].num_chips = -1;
+			cy_card[j].pdev = pdev;
+
+			/* print message */
 #ifdef CONFIG_CYZ_INTR
-                /* allocate IRQ only if board has an IRQ */
-		if( (cy_pci_irq != 0) && (cy_pci_irq != 255) ) {
-		    if(request_irq(cy_pci_irq, cyz_interrupt,
-			IRQF_SHARED, "Cyclades-Z", &cy_card[j]))
-		    {
-                        printk("Cyclom-8Zo/PCI found at 0x%lx ",
-			    (ulong) cy_pci_phys2);
-                        printk("but could not allocate IRQ%d.\n",
-			    cy_pci_irq);
-			return(i);
-		    }
+			/* don't report IRQ if board is no IRQ */
+			if ((cy_pci_irq != 0) && (cy_pci_irq != 255))
+				printk("Cyclades-8Zo/PCI #%d: 0x%lx-0x%lx, "
+					"IRQ%d, ", j + 1, (ulong)cy_pci_phys2,
+					(ulong) (cy_pci_phys2 + CyPCI_Zwin - 1),
+					(int)cy_pci_irq);
+			else
+#endif				/* CONFIG_CYZ_INTR */
+				printk("Cyclades-8Zo/PCI #%d: 0x%lx-0x%lx, ",
+					j + 1, (ulong)cy_pci_phys2,
+					(ulong)(cy_pci_phys2 + CyPCI_Zwin - 1));
+
+			printk("%d channels starting from port %d.\n",
+					cy_pci_nchan, cy_next_channel);
+			cy_next_channel += cy_pci_nchan;
 		}
-#endif /* CONFIG_CYZ_INTR */
-
-
-                /* set cy_card */
-                cy_card[j].base_phys = cy_pci_phys2;
-                cy_card[j].ctl_phys = cy_pci_phys0;
-                cy_card[j].base_addr = cy_pci_addr2;
-                cy_card[j].ctl_addr = cy_pci_addr0;
-                cy_card[j].irq = (int) cy_pci_irq;
-                cy_card[j].bus_index = 1;
-                cy_card[j].first_line = cy_next_channel;
-                cy_card[j].num_chips = -1;
-		cy_card[j].pdev = pdev;
+	}
 
-                /* print message */
-#ifdef CONFIG_CYZ_INTR
-		/* don't report IRQ if board is no IRQ */
-		if( (cy_pci_irq != 0) && (cy_pci_irq != 255) )
-		    printk("Cyclades-8Zo/PCI #%d: 0x%lx-0x%lx, IRQ%d, ",
-			j+1,(ulong)cy_pci_phys2,
-			(ulong)(cy_pci_phys2 + CyPCI_Zwin - 1),
-			(int)cy_pci_irq);
-		else
-#endif /* CONFIG_CYZ_INTR */
-		    printk("Cyclades-8Zo/PCI #%d: 0x%lx-0x%lx, ",
-			j+1,(ulong)cy_pci_phys2,
-			(ulong)(cy_pci_phys2 + CyPCI_Zwin - 1));
-
-                printk("%d channels starting from port %d.\n",
-		    cy_pci_nchan,cy_next_channel);
-                cy_next_channel += cy_pci_nchan;
-	    }
-        }
-
-        for (; ZeIndex != 0 && i < NR_CARDS; i++) {
-	    cy_pci_phys0 = Ze_phys0[0];
-	    cy_pci_phys2 = Ze_phys2[0];
-	    cy_pci_addr0 = Ze_addr0[0];
-	    cy_pci_addr2 = Ze_addr2[0];
-	    cy_pci_irq = Ze_irq[0];
-	    pdev = Ze_pdev[0];
-	    for (j = 0 ; j < ZeIndex-1 ; j++) {
-		Ze_phys0[j] = Ze_phys0[j+1];
-		Ze_phys2[j] = Ze_phys2[j+1];
-		Ze_addr0[j] = Ze_addr0[j+1];
-		Ze_addr2[j] = Ze_addr2[j+1];
-		Ze_irq[j] = Ze_irq[j+1];
-		Ze_pdev[j] = Ze_pdev[j+1];
-	    }
-	    ZeIndex--;
-		mailbox = (uclong)cy_readl(&((struct RUNTIME_9060 __iomem *) 
-					   cy_pci_addr0)->mail_box_0);
+	for (; ZeIndex != 0 && i < NR_CARDS; i++) {
+		cy_pci_phys0 = Ze_phys0[0];
+		cy_pci_phys2 = Ze_phys2[0];
+		cy_pci_addr0 = Ze_addr0[0];
+		cy_pci_addr2 = Ze_addr2[0];
+		cy_pci_irq = Ze_irq[0];
+		pdev = Ze_pdev[0];
+		for (j = 0; j < ZeIndex - 1; j++) {
+			Ze_phys0[j] = Ze_phys0[j + 1];
+			Ze_phys2[j] = Ze_phys2[j + 1];
+			Ze_addr0[j] = Ze_addr0[j + 1];
+			Ze_addr2[j] = Ze_addr2[j + 1];
+			Ze_irq[j] = Ze_irq[j + 1];
+			Ze_pdev[j] = Ze_pdev[j + 1];
+		}
+		ZeIndex--;
+		mailbox = (uclong)cy_readl(&((struct RUNTIME_9060 __iomem *)
+						cy_pci_addr0)->mail_box_0);
 #ifdef CY_PCI_DEBUG
-            printk("Cyclades-Z/PCI: relocate winaddr=0x%lx ctladdr=0x%lx\n",
-                (ulong)cy_pci_addr2, (ulong)cy_pci_addr0);
-	    printk("Cyclades-Z/PCI: New Cyclades-Z board.  FPGA not loaded\n");
+		printk("Cyclades-Z/PCI: relocate winaddr=0x%lx ctladdr=0x%lx\n",
+			(ulong)cy_pci_addr2, (ulong)cy_pci_addr0);
+		printk("Cyclades-Z/PCI: New Cyclades-Z board.  FPGA not "
+				"loaded\n");
 #endif
-		PAUSE
-                /* This must be the new Cyclades-Ze/PCI. */
-                cy_pci_nchan = ZE_V1_NPORTS;
-
-                if((cy_next_channel+cy_pci_nchan) > NR_PORTS) {
-                        printk("Cyclades-Ze/PCI found at 0x%lx ",
-			    (ulong)cy_pci_phys2);
-                        printk("but no channels are available.\n");
-                        printk("Change NR_PORTS in cyclades.c and recompile kernel.\n");
-                        return(i);
-                }
-
-                /* fill the next cy_card structure available */
-                for (j = 0 ; j < NR_CARDS ; j++) {
-                        if (cy_card[j].base_addr == 0)  break;
-                }
-                if (j == NR_CARDS) {    /* no more cy_cards available */
-		    printk("Cyclades-Ze/PCI found at 0x%lx ",
-			(ulong)cy_pci_phys2);
-		    printk("but no more cards can be used.\n");
-                    printk("Change NR_CARDS in cyclades.c and recompile kernel.\n");
-		    return(i);
-                }
+		PAUSE;
+		/* This must be the new Cyclades-Ze/PCI. */
+		cy_pci_nchan = ZE_V1_NPORTS;
+
+		if ((cy_next_channel + cy_pci_nchan) > NR_PORTS) {
+			printk("Cyclades-Ze/PCI found at 0x%lx but no channels "
+				"are available.\nChange NR_PORTS in cyclades.c "
+				"and recompile kernel.\n",
+				(ulong) cy_pci_phys2);
+			return i;
+		}
 
+		/* fill the next cy_card structure available */
+		for (j = 0; j < NR_CARDS; j++) {
+			if (cy_card[j].base_addr == 0)
+				break;
+		}
+		if (j == NR_CARDS) {	/* no more cy_cards available */
+			printk("Cyclades-Ze/PCI found at 0x%lx but no more "
+				"cards can be used.\nChange NR_CARDS in "
+				"cyclades.c and recompile kernel.\n",
+				(ulong) cy_pci_phys2);
+			return i;
+		}
 #ifdef CONFIG_CYZ_INTR
-                /* allocate IRQ only if board has an IRQ */
-		if( (cy_pci_irq != 0) && (cy_pci_irq != 255) ) {
-		    if(request_irq(cy_pci_irq, cyz_interrupt,
-			IRQF_SHARED, "Cyclades-Z", &cy_card[j]))
-		    {
-                        printk("Cyclom-Ze/PCI found at 0x%lx ",
-			    (ulong) cy_pci_phys2);
-                        printk("but could not allocate IRQ%d.\n",
-			    cy_pci_irq);
-			return(i);
-		    }
+		/* allocate IRQ only if board has an IRQ */
+		if ((cy_pci_irq != 0) && (cy_pci_irq != 255)) {
+			if (request_irq(cy_pci_irq, cyz_interrupt,
+					IRQF_SHARED, "Cyclades-Z",
+					&cy_card[j])) {
+				printk("Cyclom-Ze/PCI found at 0x%lx ",
+					(ulong) cy_pci_phys2);
+				printk("but could not allocate IRQ%d.\n",
+					cy_pci_irq);
+				return i;
+			}
 		}
-#endif /* CONFIG_CYZ_INTR */
-
-                /* set cy_card */
-                cy_card[j].base_phys = cy_pci_phys2;
-                cy_card[j].ctl_phys = cy_pci_phys0;
-                cy_card[j].base_addr = cy_pci_addr2;
-                cy_card[j].ctl_addr = cy_pci_addr0;
-                cy_card[j].irq = (int) cy_pci_irq;
-                cy_card[j].bus_index = 1;
-                cy_card[j].first_line = cy_next_channel;
-                cy_card[j].num_chips = -1;
+#endif				/* CONFIG_CYZ_INTR */
+
+		/* set cy_card */
+		cy_card[j].base_phys = cy_pci_phys2;
+		cy_card[j].ctl_phys = cy_pci_phys0;
+		cy_card[j].base_addr = cy_pci_addr2;
+		cy_card[j].ctl_addr = cy_pci_addr0;
+		cy_card[j].irq = (int)cy_pci_irq;
+		cy_card[j].bus_index = 1;
+		cy_card[j].first_line = cy_next_channel;
+		cy_card[j].num_chips = -1;
 		cy_card[j].pdev = pdev;
 
-                /* print message */
+		/* print message */
 #ifdef CONFIG_CYZ_INTR
 		/* don't report IRQ if board is no IRQ */
-		if( (cy_pci_irq != 0) && (cy_pci_irq != 255) )
-		    printk("Cyclades-Ze/PCI #%d: 0x%lx-0x%lx, IRQ%d, ",
-			j+1,(ulong)cy_pci_phys2,
-			(ulong)(cy_pci_phys2 + CyPCI_Ze_win - 1),
-			(int)cy_pci_irq);
+		if ((cy_pci_irq != 0) && (cy_pci_irq != 255))
+			printk("Cyclades-Ze/PCI #%d: 0x%lx-0x%lx, IRQ%d, ",
+				j + 1, (ulong) cy_pci_phys2,
+				(ulong) (cy_pci_phys2 + CyPCI_Ze_win - 1),
+				(int)cy_pci_irq);
 		else
-#endif /* CONFIG_CYZ_INTR */
-		    printk("Cyclades-Ze/PCI #%d: 0x%lx-0x%lx, ",
-			j+1,(ulong)cy_pci_phys2,
-			(ulong)(cy_pci_phys2 + CyPCI_Ze_win - 1));
-
-                printk("%d channels starting from port %d.\n",
-		    cy_pci_nchan,cy_next_channel);
-                cy_next_channel += cy_pci_nchan;
-        }
+#endif				/* CONFIG_CYZ_INTR */
+			printk("Cyclades-Ze/PCI #%d: 0x%lx-0x%lx, ",
+				j + 1, (ulong) cy_pci_phys2,
+				(ulong) (cy_pci_phys2 + CyPCI_Ze_win - 1));
+
+		printk("%d channels starting from port %d.\n",
+			cy_pci_nchan, cy_next_channel);
+		cy_next_channel += cy_pci_nchan;
+	}
 	if (ZeIndex != 0) {
-	    printk("Cyclades-Ze/PCI found at 0x%x ",
-		(unsigned int) Ze_phys2[0]);
-	    printk("but no more cards can be used.\n");
-            printk("Change NR_CARDS in cyclades.c and recompile kernel.\n");
+		printk("Cyclades-Ze/PCI found at 0x%x but no more cards can be "
+			"used.\nChange NR_CARDS in cyclades.c and recompile "
+			"kernel.\n", (unsigned int)Ze_phys2[0]);
 	}
-        return(i);
+	return i;
 #else
-        return(0);
-#endif /* ifdef CONFIG_PCI */
-} /* cy_detect_pci */
-
+	return 0;
+#endif				/* ifdef CONFIG_PCI */
+}				/* cy_detect_pci */
 
 /*
  * This routine prints out the appropriate serial driver version number
  * and identifies which options were configured into this driver.
  */
-static inline void
-show_version(void)
+static inline void show_version(void)
 {
-  char *rcsvers, *rcsdate, *tmp;
-    rcsvers = strchr(rcsid, ' '); rcsvers++;
-    tmp = strchr(rcsvers, ' '); *tmp++ = '\0';
-    rcsdate = strchr(tmp, ' '); rcsdate++;
-    tmp = strrchr(rcsdate, ' '); *tmp = '\0';
-    printk("Cyclades driver %s %s\n",
-        rcsvers, rcsdate);
-    printk("        built %s %s\n",
-	__DATE__, __TIME__);
-} /* show_version */
-
-static int 
+	printk("Cyclades driver " CY_VERSION "\n");
+	printk("        built %s %s\n", __DATE__, __TIME__);
+}				/* show_version */
+
+static int
 cyclades_get_proc_info(char *buf, char **start, off_t offset, int length,
-		       int *eof, void *data)
+		int *eof, void *data)
 {
-    struct cyclades_port  *info;
-    int i;
-    int len=0;
-    off_t begin=0;
-    off_t pos=0;
-    int size;
-    __u32 cur_jifs = jiffies;
-
-    size = sprintf(buf, "Dev TimeOpen   BytesOut  IdleOut    BytesIn   IdleIn  Overruns  Ldisc\n");
-
-    pos += size;
-    len += size;
-
-    /* Output one line for each known port */
-    for (i = 0; i < NR_PORTS && cy_port[i].line >= 0; i++) {
-	info = &cy_port[i];
-
-	if (info->count)
-	    size = sprintf(buf+len,
-			"%3d %8lu %10lu %8lu %10lu %8lu %9lu %6ld\n",
-			info->line,
-			JIFFIES_DIFF(info->idle_stats.in_use, cur_jifs) / HZ,
-			info->idle_stats.xmit_bytes,
-			JIFFIES_DIFF(info->idle_stats.xmit_idle, cur_jifs) / HZ,
-			info->idle_stats.recv_bytes,
-			JIFFIES_DIFF(info->idle_stats.recv_idle, cur_jifs) / HZ,
-			info->idle_stats.overruns,
-			(long) info->tty->ldisc.num);
-	else
-	    size = sprintf(buf+len,
-			"%3d %8lu %10lu %8lu %10lu %8lu %9lu %6ld\n",
-			info->line, 0L, 0L, 0L, 0L, 0L, 0L, 0L);
+	struct cyclades_port *info;
+	int i;
+	int len = 0;
+	off_t begin = 0;
+	off_t pos = 0;
+	int size;
+	__u32 cur_jifs = jiffies;
+
+	size = sprintf(buf, "Dev TimeOpen   BytesOut  IdleOut    BytesIn   "
+			"IdleIn  Overruns  Ldisc\n");
+
+	pos += size;
 	len += size;
-	pos = begin + len;
 
-	if (pos < offset) {
-	    len   = 0;
-	    begin = pos;
+	/* Output one line for each known port */
+	for (i = 0; i < NR_PORTS && cy_port[i].line >= 0; i++) {
+		info = &cy_port[i];
+
+		if (info->count)
+			size = sprintf(buf + len, "%3d %8lu %10lu %8lu %10lu "
+				"%8lu %9lu %6ld\n", info->line,
+				(cur_jifs - info->idle_stats.in_use) / HZ,
+				info->idle_stats.xmit_bytes,
+				(cur_jifs - info->idle_stats.xmit_idle) / HZ,
+				info->idle_stats.recv_bytes,
+				(cur_jifs - info->idle_stats.recv_idle) / HZ,
+				info->idle_stats.overruns,
+				(long)info->tty->ldisc.num);
+		else
+			size = sprintf(buf + len, "%3d %8lu %10lu %8lu %10lu "
+				"%8lu %9lu %6ld\n",
+				info->line, 0L, 0L, 0L, 0L, 0L, 0L, 0L);
+		len += size;
+		pos = begin + len;
+
+		if (pos < offset) {
+			len = 0;
+			begin = pos;
+		}
+		if (pos > offset + length)
+			goto done;
 	}
-	if (pos > offset + length)
-	    goto done;
-    }
-    *eof = 1;
+	*eof = 1;
 done:
-    *start = buf + (offset - begin);	/* Start of wanted data */
-    len -= (offset - begin);		/* Start slop */
-    if (len > length)
-	len = length;			/* Ending slop */
-    if (len < 0)
-	len = 0;
-    return len;
+	*start = buf + (offset - begin);	/* Start of wanted data */
+	len -= (offset - begin);	/* Start slop */
+	if (len > length)
+		len = length;	/* Ending slop */
+	if (len < 0)
+		len = 0;
+	return len;
 }
 
 /* The serial driver boot-time initialization code!
@@ -5185,290 +5294,288 @@ done:
  */
 
 static const struct tty_operations cy_ops = {
-    .open = cy_open,
-    .close = cy_close,
-    .write = cy_write,
-    .put_char = cy_put_char,
-    .flush_chars = cy_flush_chars,
-    .write_room = cy_write_room,
-    .chars_in_buffer = cy_chars_in_buffer,
-    .flush_buffer = cy_flush_buffer,
-    .ioctl = cy_ioctl,
-    .throttle = cy_throttle,
-    .unthrottle = cy_unthrottle,
-    .set_termios = cy_set_termios,
-    .stop = cy_stop,
-    .start = cy_start,
-    .hangup = cy_hangup,
-    .break_ctl = cy_break,
-    .wait_until_sent = cy_wait_until_sent,
-    .read_proc = cyclades_get_proc_info,
-    .tiocmget = cy_tiocmget,
-    .tiocmset = cy_tiocmset,
+	.open = cy_open,
+	.close = cy_close,
+	.write = cy_write,
+	.put_char = cy_put_char,
+	.flush_chars = cy_flush_chars,
+	.write_room = cy_write_room,
+	.chars_in_buffer = cy_chars_in_buffer,
+	.flush_buffer = cy_flush_buffer,
+	.ioctl = cy_ioctl,
+	.throttle = cy_throttle,
+	.unthrottle = cy_unthrottle,
+	.set_termios = cy_set_termios,
+	.stop = cy_stop,
+	.start = cy_start,
+	.hangup = cy_hangup,
+	.break_ctl = cy_break,
+	.wait_until_sent = cy_wait_until_sent,
+	.read_proc = cyclades_get_proc_info,
+	.tiocmget = cy_tiocmget,
+	.tiocmset = cy_tiocmset,
 };
 
-static int __init
-cy_init(void)
+static int __init cy_init(void)
 {
-  struct cyclades_port  *info;
-  struct cyclades_card *cinfo;
-  int number_z_boards = 0;
-  int board,port,i,index;
-  unsigned long mailbox;
-  unsigned short chip_number;
-  int nports;
-
-    cy_serial_driver = alloc_tty_driver(NR_PORTS);
-    if (!cy_serial_driver)
-	return -ENOMEM;
-    show_version();
-
-    /* Initialize the tty_driver structure */
-    
-    cy_serial_driver->owner = THIS_MODULE;
-    cy_serial_driver->driver_name = "cyclades";
-    cy_serial_driver->name = "ttyC";
-    cy_serial_driver->major = CYCLADES_MAJOR;
-    cy_serial_driver->minor_start = 0;
-    cy_serial_driver->type = TTY_DRIVER_TYPE_SERIAL;
-    cy_serial_driver->subtype = SERIAL_TYPE_NORMAL;
-    cy_serial_driver->init_termios = tty_std_termios;
-    cy_serial_driver->init_termios.c_cflag =
-            B9600 | CS8 | CREAD | HUPCL | CLOCAL;
-    cy_serial_driver->flags = TTY_DRIVER_REAL_RAW;
-    tty_set_operations(cy_serial_driver, &cy_ops);
-
-    if (tty_register_driver(cy_serial_driver))
-            panic("Couldn't register Cyclades serial driver\n");
-
-    for (i = 0; i < NR_CARDS; i++) {
-            /* base_addr=0 indicates board not found */
-            cy_card[i].base_addr = NULL;
-    }
-
-    /* the code below is responsible to find the boards. Each different
-       type of board has its own detection routine. If a board is found,
-       the next cy_card structure available is set by the detection
-       routine. These functions are responsible for checking the
-       availability of cy_card and cy_port data structures and updating
-       the cy_next_channel. */
-
-    /* look for isa boards */
-    cy_isa_nboard = cy_detect_isa();
-
-    /* look for pci boards */
-    cy_pci_nboard = cy_detect_pci();
-
-    cy_nboard = cy_isa_nboard + cy_pci_nboard;
-
-    /* invalidate remaining cy_card structures */
-    for (i = 0 ; i < NR_CARDS ; i++) {
-        if (cy_card[i].base_addr == 0) {
-                cy_card[i].first_line = -1;
-                cy_card[i].ctl_addr = NULL;
-                cy_card[i].irq = 0;
-                cy_card[i].bus_index = 0;
-                cy_card[i].first_line = 0;
-                cy_card[i].num_chips = 0;
-        }
-    }
-    /* invalidate remaining cy_port structures */
-    for (i = cy_next_channel ; i < NR_PORTS ; i++) {
-        cy_port[i].line = -1;
-        cy_port[i].magic = -1;
-    }
-
-    /* initialize per-port data structures for each valid board found */
-    for (board = 0 ; board < cy_nboard ; board++) {
-            cinfo = &cy_card[board];
-            if (cinfo->num_chips == -1) { /* Cyclades-Z */
-		number_z_boards++;
-		mailbox = cy_readl(&((struct RUNTIME_9060 __iomem *)
-			     cy_card[board].ctl_addr)->mail_box_0);
-		nports = (mailbox == ZE_V1) ? ZE_V1_NPORTS : 8;
-		cinfo->intr_enabled = 0;
-		cinfo->nports = 0; /* Will be correctly set later, after 
-				      Z FW is loaded */
-		spin_lock_init(&cinfo->card_lock);
-                for (port = cinfo->first_line ;
-                     port < cinfo->first_line + nports;
-                     port++)
-                {
-                    info = &cy_port[port];
-                    info->magic = CYCLADES_MAGIC;
-                    info->type = PORT_STARTECH;
-                    info->card = board;
-                    info->line = port;
-		    info->chip_rev = 0;
-                    info->flags = STD_COM_FLAGS;
-                    info->tty = NULL;
-		    if (mailbox == ZO_V1)
-			info->xmit_fifo_size = CYZ_FIFO_SIZE;
-		    else
-			info->xmit_fifo_size = 4 * CYZ_FIFO_SIZE;
-                    info->cor1 = 0;
-                    info->cor2 = 0;
-                    info->cor3 = 0;
-                    info->cor4 = 0;
-                    info->cor5 = 0;
-                    info->tbpr = 0;
-                    info->tco = 0;
-                    info->rbpr = 0;
-                    info->rco = 0;
-		    info->custom_divisor = 0;
-                    info->close_delay = 5*HZ/10;
-		    info->closing_wait = CLOSING_WAIT_DELAY;
-		    info->icount.cts = info->icount.dsr = 
-			info->icount.rng = info->icount.dcd = 0;
-		    info->icount.rx = info->icount.tx = 0;
-		    info->icount.frame = info->icount.parity = 0;
-		    info->icount.overrun = info->icount.brk = 0;
-                    info->x_char = 0;
-                    info->event = 0;
-                    info->count = 0;
-                    info->blocked_open = 0;
-                    info->default_threshold = 0;
-                    info->default_timeout = 0;
-		    INIT_WORK(&info->tqueue, do_softint);
-		    init_waitqueue_head(&info->open_wait);
-		    init_waitqueue_head(&info->close_wait);
-		    init_waitqueue_head(&info->shutdown_wait);
-		    init_waitqueue_head(&info->delta_msr_wait);
-                    /* info->session */
-                    /* info->pgrp */
-                    info->read_status_mask = 0;
-                    /* info->timeout */
-		    /* Bentson's vars */
-                    info->jiffies[0] = 0;
-                    info->jiffies[1] = 0;
-                    info->jiffies[2] = 0;
-                    info->rflush_count = 0;
+	struct cyclades_port *info;
+	struct cyclades_card *cinfo;
+	int number_z_boards = 0;
+	int board, port, i, index;
+	unsigned long mailbox;
+	unsigned short chip_number;
+	int nports;
+
+	cy_serial_driver = alloc_tty_driver(NR_PORTS);
+	if (!cy_serial_driver)
+		return -ENOMEM;
+	show_version();
+
+	/* Initialize the tty_driver structure */
+
+	cy_serial_driver->owner = THIS_MODULE;
+	cy_serial_driver->driver_name = "cyclades";
+	cy_serial_driver->name = "ttyC";
+	cy_serial_driver->major = CYCLADES_MAJOR;
+	cy_serial_driver->minor_start = 0;
+	cy_serial_driver->type = TTY_DRIVER_TYPE_SERIAL;
+	cy_serial_driver->subtype = SERIAL_TYPE_NORMAL;
+	cy_serial_driver->init_termios = tty_std_termios;
+	cy_serial_driver->init_termios.c_cflag =
+	    B9600 | CS8 | CREAD | HUPCL | CLOCAL;
+	cy_serial_driver->flags = TTY_DRIVER_REAL_RAW;
+	tty_set_operations(cy_serial_driver, &cy_ops);
+
+	if (tty_register_driver(cy_serial_driver))
+		panic("Couldn't register Cyclades serial driver\n");
+
+	for (i = 0; i < NR_CARDS; i++) {
+		/* base_addr=0 indicates board not found */
+		cy_card[i].base_addr = NULL;
+	}
+
+	/* the code below is responsible to find the boards. Each different
+	   type of board has its own detection routine. If a board is found,
+	   the next cy_card structure available is set by the detection
+	   routine. These functions are responsible for checking the
+	   availability of cy_card and cy_port data structures and updating
+	   the cy_next_channel. */
+
+	/* look for isa boards */
+	cy_isa_nboard = cy_detect_isa();
+
+	/* look for pci boards */
+	cy_pci_nboard = cy_detect_pci();
+
+	cy_nboard = cy_isa_nboard + cy_pci_nboard;
+
+	/* invalidate remaining cy_card structures */
+	for (i = 0; i < NR_CARDS; i++) {
+		if (cy_card[i].base_addr == 0) {
+			cy_card[i].first_line = -1;
+			cy_card[i].ctl_addr = NULL;
+			cy_card[i].irq = 0;
+			cy_card[i].bus_index = 0;
+			cy_card[i].first_line = 0;
+			cy_card[i].num_chips = 0;
+		}
+	}
+	/* invalidate remaining cy_port structures */
+	for (i = cy_next_channel; i < NR_PORTS; i++) {
+		cy_port[i].line = -1;
+		cy_port[i].magic = -1;
+	}
+
+	/* initialize per-port data structures for each valid board found */
+	for (board = 0; board < cy_nboard; board++) {
+		cinfo = &cy_card[board];
+		if (cinfo->num_chips == -1) {	/* Cyclades-Z */
+			number_z_boards++;
+			mailbox = cy_readl(&((struct RUNTIME_9060 __iomem *)
+					     cy_card[board].ctl_addr)->
+					   mail_box_0);
+			nports = (mailbox == ZE_V1) ? ZE_V1_NPORTS : 8;
+			cinfo->intr_enabled = 0;
+			cinfo->nports = 0;	/* Will be correctly set later, after 
+						   Z FW is loaded */
+			spin_lock_init(&cinfo->card_lock);
+			for (port = cinfo->first_line;
+			     port < cinfo->first_line + nports; port++) {
+				info = &cy_port[port];
+				info->magic = CYCLADES_MAGIC;
+				info->type = PORT_STARTECH;
+				info->card = board;
+				info->line = port;
+				info->chip_rev = 0;
+				info->flags = STD_COM_FLAGS;
+				info->tty = NULL;
+				if (mailbox == ZO_V1)
+					info->xmit_fifo_size = CYZ_FIFO_SIZE;
+				else
+					info->xmit_fifo_size =
+					    4 * CYZ_FIFO_SIZE;
+				info->cor1 = 0;
+				info->cor2 = 0;
+				info->cor3 = 0;
+				info->cor4 = 0;
+				info->cor5 = 0;
+				info->tbpr = 0;
+				info->tco = 0;
+				info->rbpr = 0;
+				info->rco = 0;
+				info->custom_divisor = 0;
+				info->close_delay = 5 * HZ / 10;
+				info->closing_wait = CLOSING_WAIT_DELAY;
+				info->icount.cts = info->icount.dsr =
+				    info->icount.rng = info->icount.dcd = 0;
+				info->icount.rx = info->icount.tx = 0;
+				info->icount.frame = info->icount.parity = 0;
+				info->icount.overrun = info->icount.brk = 0;
+				info->x_char = 0;
+				info->event = 0;
+				info->count = 0;
+				info->blocked_open = 0;
+				info->default_threshold = 0;
+				info->default_timeout = 0;
+				INIT_WORK(&info->tqueue, do_softint);
+				init_waitqueue_head(&info->open_wait);
+				init_waitqueue_head(&info->close_wait);
+				init_waitqueue_head(&info->shutdown_wait);
+				init_waitqueue_head(&info->delta_msr_wait);
+				/* info->session */
+				/* info->pgrp */
+				info->read_status_mask = 0;
+				/* info->timeout */
+				/* Bentson's vars */
+				info->jiffies[0] = 0;
+				info->jiffies[1] = 0;
+				info->jiffies[2] = 0;
+				info->rflush_count = 0;
 #ifdef CONFIG_CYZ_INTR
-		    init_timer(&cyz_rx_full_timer[port]);
-		    cyz_rx_full_timer[port].function = NULL;
+				init_timer(&cyz_rx_full_timer[port]);
+				cyz_rx_full_timer[port].function = NULL;
 #endif
-                }
-                continue;
-            }else{ /* Cyclom-Y of some kind*/
-                index = cinfo->bus_index;
-		spin_lock_init(&cinfo->card_lock);
-		cinfo->nports = CyPORTS_PER_CHIP * cinfo->num_chips;
-                for (port = cinfo->first_line ;
-                     port < cinfo->first_line + cinfo->nports ;
-                     port++)
-                {
-                    info = &cy_port[port];
-                    info->magic = CYCLADES_MAGIC;
-                    info->type = PORT_CIRRUS;
-                    info->card = board;
-                    info->line = port;
-                    info->flags = STD_COM_FLAGS;
-                    info->tty = NULL;
-                    info->xmit_fifo_size = CyMAX_CHAR_FIFO;
-                    info->cor1 = CyPARITY_NONE|Cy_1_STOP|Cy_8_BITS;
-                    info->cor2 = CyETC;
-                    info->cor3 = 0x08; /* _very_ small rcv threshold */
-                    info->cor4 = 0;
-                    info->cor5 = 0;
-		    info->custom_divisor = 0;
-                    info->close_delay = 5*HZ/10;
-		    info->closing_wait = CLOSING_WAIT_DELAY;
-		    info->icount.cts = info->icount.dsr = 
-			info->icount.rng = info->icount.dcd = 0;
-		    info->icount.rx = info->icount.tx = 0;
-		    info->icount.frame = info->icount.parity = 0;
-		    info->icount.overrun = info->icount.brk = 0;
-		    chip_number = (port - cinfo->first_line) / 4;
-		    if ((info->chip_rev =
-			 cy_readb(cinfo->base_addr +
-				  (cy_chip_offset[chip_number]<<index) +
-				  (CyGFRCR<<index))) >= CD1400_REV_J) {
-                        /* It is a CD1400 rev. J or later */
-                        info->tbpr = baud_bpr_60[13]; /* Tx BPR */
-                        info->tco = baud_co_60[13]; /* Tx CO */
-                        info->rbpr = baud_bpr_60[13]; /* Rx BPR */
-                        info->rco = baud_co_60[13]; /* Rx CO */
-                        info->rflow = 0;
-                        info->rtsdtr_inv = 1;
-                    } else {
-                        info->tbpr = baud_bpr_25[13]; /* Tx BPR */
-                        info->tco = baud_co_25[13]; /* Tx CO */
-                        info->rbpr = baud_bpr_25[13]; /* Rx BPR */
-                        info->rco = baud_co_25[13]; /* Rx CO */
-                        info->rflow = 0;
-                        info->rtsdtr_inv = 0;
-                    }
-                    info->x_char = 0;
-                    info->event = 0;
-                    info->count = 0;
-                    info->blocked_open = 0;
-                    info->default_threshold = 0;
-                    info->default_timeout = 0;
-		    INIT_WORK(&info->tqueue, do_softint);
-		    init_waitqueue_head(&info->open_wait);
-		    init_waitqueue_head(&info->close_wait);
-		    init_waitqueue_head(&info->shutdown_wait);
-		    init_waitqueue_head(&info->delta_msr_wait);
-                    /* info->session */
-                    /* info->pgrp */
-                    info->read_status_mask =
-		                  CyTIMEOUT| CySPECHAR| CyBREAK
-                                  | CyPARITY| CyFRAME| CyOVERRUN;
-                    /* info->timeout */
-                }
-            }
-    }
+			}
+			continue;
+		} else {	/* Cyclom-Y of some kind */
+			index = cinfo->bus_index;
+			spin_lock_init(&cinfo->card_lock);
+			cinfo->nports = CyPORTS_PER_CHIP * cinfo->num_chips;
+			for (port = cinfo->first_line;
+			     port < cinfo->first_line + cinfo->nports; port++) {
+				info = &cy_port[port];
+				info->magic = CYCLADES_MAGIC;
+				info->type = PORT_CIRRUS;
+				info->card = board;
+				info->line = port;
+				info->flags = STD_COM_FLAGS;
+				info->tty = NULL;
+				info->xmit_fifo_size = CyMAX_CHAR_FIFO;
+				info->cor1 =
+				    CyPARITY_NONE | Cy_1_STOP | Cy_8_BITS;
+				info->cor2 = CyETC;
+				info->cor3 = 0x08;	/* _very_ small rcv threshold */
+				info->cor4 = 0;
+				info->cor5 = 0;
+				info->custom_divisor = 0;
+				info->close_delay = 5 * HZ / 10;
+				info->closing_wait = CLOSING_WAIT_DELAY;
+				info->icount.cts = info->icount.dsr =
+				    info->icount.rng = info->icount.dcd = 0;
+				info->icount.rx = info->icount.tx = 0;
+				info->icount.frame = info->icount.parity = 0;
+				info->icount.overrun = info->icount.brk = 0;
+				chip_number = (port - cinfo->first_line) / 4;
+				if ((info->chip_rev =
+				     cy_readb(cinfo->base_addr +
+					      (cy_chip_offset[chip_number] <<
+					       index) + (CyGFRCR << index))) >=
+				    CD1400_REV_J) {
+					/* It is a CD1400 rev. J or later */
+					info->tbpr = baud_bpr_60[13];	/* Tx BPR */
+					info->tco = baud_co_60[13];	/* Tx CO */
+					info->rbpr = baud_bpr_60[13];	/* Rx BPR */
+					info->rco = baud_co_60[13];	/* Rx CO */
+					info->rflow = 0;
+					info->rtsdtr_inv = 1;
+				} else {
+					info->tbpr = baud_bpr_25[13];	/* Tx BPR */
+					info->tco = baud_co_25[13];	/* Tx CO */
+					info->rbpr = baud_bpr_25[13];	/* Rx BPR */
+					info->rco = baud_co_25[13];	/* Rx CO */
+					info->rflow = 0;
+					info->rtsdtr_inv = 0;
+				}
+				info->x_char = 0;
+				info->event = 0;
+				info->count = 0;
+				info->blocked_open = 0;
+				info->default_threshold = 0;
+				info->default_timeout = 0;
+				INIT_WORK(&info->tqueue, do_softint);
+				init_waitqueue_head(&info->open_wait);
+				init_waitqueue_head(&info->close_wait);
+				init_waitqueue_head(&info->shutdown_wait);
+				init_waitqueue_head(&info->delta_msr_wait);
+				/* info->session */
+				/* info->pgrp */
+				info->read_status_mask =
+				    CyTIMEOUT | CySPECHAR | CyBREAK
+				    | CyPARITY | CyFRAME | CyOVERRUN;
+				/* info->timeout */
+			}
+		}
+	}
 
 #ifndef CONFIG_CYZ_INTR
-    if (number_z_boards && !cyz_timeron){
-	cyz_timeron++;
-	cyz_timerlist.expires = jiffies + 1;
-	add_timer(&cyz_timerlist);
+	if (number_z_boards && !cyz_timeron) {
+		cyz_timeron++;
+		cyz_timerlist.expires = jiffies + 1;
+		add_timer(&cyz_timerlist);
 #ifdef CY_PCI_DEBUG
-	printk("Cyclades-Z polling initialized\n");
+		printk("Cyclades-Z polling initialized\n");
 #endif
-    }
-#endif /* CONFIG_CYZ_INTR */
+	}
+#endif				/* CONFIG_CYZ_INTR */
+
+	return 0;
 
-    return 0;
-    
-} /* cy_init */
+}				/* cy_init */
 
-static void __exit
-cy_cleanup_module(void)
+static void __exit cy_cleanup_module(void)
 {
-    int i, e1;
+	int i, e1;
 
 #ifndef CONFIG_CYZ_INTR
-    if (cyz_timeron){
-	cyz_timeron = 0;
-	del_timer(&cyz_timerlist);
-    }
+	if (cyz_timeron){
+		cyz_timeron = 0;
+		del_timer(&cyz_timerlist);
+	}
 #endif /* CONFIG_CYZ_INTR */
 
-    if ((e1 = tty_unregister_driver(cy_serial_driver)))
-            printk("cyc: failed to unregister Cyclades serial driver(%d)\n",
-		e1);
+	if ((e1 = tty_unregister_driver(cy_serial_driver)))
+		printk("cyc: failed to unregister Cyclades serial driver(%d)\n",
+			e1);
 
-    put_tty_driver(cy_serial_driver);
+	put_tty_driver(cy_serial_driver);
 
-    for (i = 0; i < NR_CARDS; i++) {
-        if (cy_card[i].base_addr) {
-	    iounmap(cy_card[i].base_addr);
-	    if (cy_card[i].ctl_addr)
-		iounmap(cy_card[i].ctl_addr);
-	    if (cy_card[i].irq
+	for (i = 0; i < NR_CARDS; i++) {
+		if (cy_card[i].base_addr) {
+			iounmap(cy_card[i].base_addr);
+			if (cy_card[i].ctl_addr)
+				iounmap(cy_card[i].ctl_addr);
+			if (cy_card[i].irq
 #ifndef CONFIG_CYZ_INTR
-		&& cy_card[i].num_chips != -1 /* not a Z card */
+				&& cy_card[i].num_chips != -1 /* not a Z card */
 #endif /* CONFIG_CYZ_INTR */
-	    )
-		free_irq(cy_card[i].irq, &cy_card[i]);
+				)
+				free_irq(cy_card[i].irq, &cy_card[i]);
 #ifdef CONFIG_PCI
-		if (cy_card[i].pdev)
-			pci_release_regions(cy_card[i].pdev);
+			if (cy_card[i].pdev)
+				pci_release_regions(cy_card[i].pdev);
 #endif
-        }
-    }
+		}
+	}
 } /* cy_cleanup_module */
 
 module_init(cy_init);
diff --git a/drivers/char/drm/drm_ioc32.c b/drivers/char/drm/drm_ioc32.c
index d4f874520082..fafeb34f89d5 100644
--- a/drivers/char/drm/drm_ioc32.c
+++ b/drivers/char/drm/drm_ioc32.c
@@ -102,7 +102,7 @@ static int compat_drm_version(struct file *file, unsigned int cmd,
 			  &version->desc))
 		return -EFAULT;
 
-	err = drm_ioctl(file->f_dentry->d_inode, file,
+	err = drm_ioctl(file->f_path.dentry->d_inode, file,
 			DRM_IOCTL_VERSION, (unsigned long)version);
 	if (err)
 		return err;
@@ -143,7 +143,7 @@ static int compat_drm_getunique(struct file *file, unsigned int cmd,
 			  &u->unique))
 		return -EFAULT;
 
-	err = drm_ioctl(file->f_dentry->d_inode, file,
+	err = drm_ioctl(file->f_path.dentry->d_inode, file,
 			DRM_IOCTL_GET_UNIQUE, (unsigned long)u);
 	if (err)
 		return err;
@@ -172,7 +172,7 @@ static int compat_drm_setunique(struct file *file, unsigned int cmd,
 			  &u->unique))
 		return -EFAULT;
 
-	return drm_ioctl(file->f_dentry->d_inode, file,
+	return drm_ioctl(file->f_path.dentry->d_inode, file,
 			 DRM_IOCTL_SET_UNIQUE, (unsigned long)u);
 }
 
@@ -203,7 +203,7 @@ static int compat_drm_getmap(struct file *file, unsigned int cmd,
 	if (__put_user(idx, &map->offset))
 		return -EFAULT;
 
-	err = drm_ioctl(file->f_dentry->d_inode, file,
+	err = drm_ioctl(file->f_path.dentry->d_inode, file,
 			DRM_IOCTL_GET_MAP, (unsigned long)map);
 	if (err)
 		return err;
@@ -244,7 +244,7 @@ static int compat_drm_addmap(struct file *file, unsigned int cmd,
 	    || __put_user(m32.flags, &map->flags))
 		return -EFAULT;
 
-	err = drm_ioctl(file->f_dentry->d_inode, file,
+	err = drm_ioctl(file->f_path.dentry->d_inode, file,
 			DRM_IOCTL_ADD_MAP, (unsigned long)map);
 	if (err)
 		return err;
@@ -282,7 +282,7 @@ static int compat_drm_rmmap(struct file *file, unsigned int cmd,
 	if (__put_user((void *)(unsigned long)handle, &map->handle))
 		return -EFAULT;
 
-	return drm_ioctl(file->f_dentry->d_inode, file,
+	return drm_ioctl(file->f_path.dentry->d_inode, file,
 			 DRM_IOCTL_RM_MAP, (unsigned long)map);
 }
 
@@ -312,7 +312,7 @@ static int compat_drm_getclient(struct file *file, unsigned int cmd,
 	if (__put_user(idx, &client->idx))
 		return -EFAULT;
 
-	err = drm_ioctl(file->f_dentry->d_inode, file,
+	err = drm_ioctl(file->f_path.dentry->d_inode, file,
 			DRM_IOCTL_GET_CLIENT, (unsigned long)client);
 	if (err)
 		return err;
@@ -349,7 +349,7 @@ static int compat_drm_getstats(struct file *file, unsigned int cmd,
 	if (!access_ok(VERIFY_WRITE, stats, sizeof(*stats)))
 		return -EFAULT;
 
-	err = drm_ioctl(file->f_dentry->d_inode, file,
+	err = drm_ioctl(file->f_path.dentry->d_inode, file,
 			DRM_IOCTL_GET_STATS, (unsigned long)stats);
 	if (err)
 		return err;
@@ -393,7 +393,7 @@ static int compat_drm_addbufs(struct file *file, unsigned int cmd,
 	    || __put_user(agp_start, &buf->agp_start))
 		return -EFAULT;
 
-	err = drm_ioctl(file->f_dentry->d_inode, file,
+	err = drm_ioctl(file->f_path.dentry->d_inode, file,
 			DRM_IOCTL_ADD_BUFS, (unsigned long)buf);
 	if (err)
 		return err;
@@ -425,7 +425,7 @@ static int compat_drm_markbufs(struct file *file, unsigned int cmd,
 	    || __put_user(b32.high_mark, &buf->high_mark))
 		return -EFAULT;
 
-	return drm_ioctl(file->f_dentry->d_inode, file,
+	return drm_ioctl(file->f_path.dentry->d_inode, file,
 			 DRM_IOCTL_MARK_BUFS, (unsigned long)buf);
 }
 
@@ -467,7 +467,7 @@ static int compat_drm_infobufs(struct file *file, unsigned int cmd,
 	    || __put_user(list, &request->list))
 		return -EFAULT;
 
-	err = drm_ioctl(file->f_dentry->d_inode, file,
+	err = drm_ioctl(file->f_path.dentry->d_inode, file,
 			DRM_IOCTL_INFO_BUFS, (unsigned long)request);
 	if (err)
 		return err;
@@ -529,7 +529,7 @@ static int compat_drm_mapbufs(struct file *file, unsigned int cmd,
 	    || __put_user(list, &request->list))
 		return -EFAULT;
 
-	err = drm_ioctl(file->f_dentry->d_inode, file,
+	err = drm_ioctl(file->f_path.dentry->d_inode, file,
 			DRM_IOCTL_MAP_BUFS, (unsigned long)request);
 	if (err)
 		return err;
@@ -576,7 +576,7 @@ static int compat_drm_freebufs(struct file *file, unsigned int cmd,
 			  &request->list))
 		return -EFAULT;
 
-	return drm_ioctl(file->f_dentry->d_inode, file,
+	return drm_ioctl(file->f_path.dentry->d_inode, file,
 			 DRM_IOCTL_FREE_BUFS, (unsigned long)request);
 }
 
@@ -603,7 +603,7 @@ static int compat_drm_setsareactx(struct file *file, unsigned int cmd,
 			  &request->handle))
 		return -EFAULT;
 
-	return drm_ioctl(file->f_dentry->d_inode, file,
+	return drm_ioctl(file->f_path.dentry->d_inode, file,
 			 DRM_IOCTL_SET_SAREA_CTX, (unsigned long)request);
 }
 
@@ -626,7 +626,7 @@ static int compat_drm_getsareactx(struct file *file, unsigned int cmd,
 	if (__put_user(ctx_id, &request->ctx_id))
 		return -EFAULT;
 
-	err = drm_ioctl(file->f_dentry->d_inode, file,
+	err = drm_ioctl(file->f_path.dentry->d_inode, file,
 			DRM_IOCTL_GET_SAREA_CTX, (unsigned long)request);
 	if (err)
 		return err;
@@ -662,7 +662,7 @@ static int compat_drm_resctx(struct file *file, unsigned int cmd,
 			  &res->contexts))
 		return -EFAULT;
 
-	err = drm_ioctl(file->f_dentry->d_inode, file,
+	err = drm_ioctl(file->f_path.dentry->d_inode, file,
 			DRM_IOCTL_RES_CTX, (unsigned long)res);
 	if (err)
 		return err;
@@ -716,7 +716,7 @@ static int compat_drm_dma(struct file *file, unsigned int cmd,
 			  &d->request_sizes))
 		return -EFAULT;
 
-	err = drm_ioctl(file->f_dentry->d_inode, file,
+	err = drm_ioctl(file->f_path.dentry->d_inode, file,
 			DRM_IOCTL_DMA, (unsigned long)d);
 	if (err)
 		return err;
@@ -749,7 +749,7 @@ static int compat_drm_agp_enable(struct file *file, unsigned int cmd,
 	if (put_user(m32.mode, &mode->mode))
 		return -EFAULT;
 
-	return drm_ioctl(file->f_dentry->d_inode, file,
+	return drm_ioctl(file->f_path.dentry->d_inode, file,
 			 DRM_IOCTL_AGP_ENABLE, (unsigned long)mode);
 }
 
@@ -779,7 +779,7 @@ static int compat_drm_agp_info(struct file *file, unsigned int cmd,
 	if (!access_ok(VERIFY_WRITE, info, sizeof(*info)))
 		return -EFAULT;
 
-	err = drm_ioctl(file->f_dentry->d_inode, file,
+	err = drm_ioctl(file->f_path.dentry->d_inode, file,
 			DRM_IOCTL_AGP_INFO, (unsigned long)info);
 	if (err)
 		return err;
@@ -825,7 +825,7 @@ static int compat_drm_agp_alloc(struct file *file, unsigned int cmd,
 	    || __put_user(req32.type, &request->type))
 		return -EFAULT;
 
-	err = drm_ioctl(file->f_dentry->d_inode, file,
+	err = drm_ioctl(file->f_path.dentry->d_inode, file,
 			DRM_IOCTL_AGP_ALLOC, (unsigned long)request);
 	if (err)
 		return err;
@@ -833,7 +833,7 @@ static int compat_drm_agp_alloc(struct file *file, unsigned int cmd,
 	if (__get_user(req32.handle, &request->handle)
 	    || __get_user(req32.physical, &request->physical)
 	    || copy_to_user(argp, &req32, sizeof(req32))) {
-		drm_ioctl(file->f_dentry->d_inode, file,
+		drm_ioctl(file->f_path.dentry->d_inode, file,
 			  DRM_IOCTL_AGP_FREE, (unsigned long)request);
 		return -EFAULT;
 	}
@@ -854,7 +854,7 @@ static int compat_drm_agp_free(struct file *file, unsigned int cmd,
 	    || __put_user(handle, &request->handle))
 		return -EFAULT;
 
-	return drm_ioctl(file->f_dentry->d_inode, file,
+	return drm_ioctl(file->f_path.dentry->d_inode, file,
 			 DRM_IOCTL_AGP_FREE, (unsigned long)request);
 }
 
@@ -879,7 +879,7 @@ static int compat_drm_agp_bind(struct file *file, unsigned int cmd,
 	    || __put_user(req32.offset, &request->offset))
 		return -EFAULT;
 
-	return drm_ioctl(file->f_dentry->d_inode, file,
+	return drm_ioctl(file->f_path.dentry->d_inode, file,
 			 DRM_IOCTL_AGP_BIND, (unsigned long)request);
 }
 
@@ -896,7 +896,7 @@ static int compat_drm_agp_unbind(struct file *file, unsigned int cmd,
 	    || __put_user(handle, &request->handle))
 		return -EFAULT;
 
-	return drm_ioctl(file->f_dentry->d_inode, file,
+	return drm_ioctl(file->f_path.dentry->d_inode, file,
 			 DRM_IOCTL_AGP_UNBIND, (unsigned long)request);
 }
 #endif				/* __OS_HAS_AGP */
@@ -921,7 +921,7 @@ static int compat_drm_sg_alloc(struct file *file, unsigned int cmd,
 	    || __put_user(x, &request->size))
 		return -EFAULT;
 
-	err = drm_ioctl(file->f_dentry->d_inode, file,
+	err = drm_ioctl(file->f_path.dentry->d_inode, file,
 			DRM_IOCTL_SG_ALLOC, (unsigned long)request);
 	if (err)
 		return err;
@@ -948,7 +948,7 @@ static int compat_drm_sg_free(struct file *file, unsigned int cmd,
 	    || __put_user(x << PAGE_SHIFT, &request->handle))
 		return -EFAULT;
 
-	return drm_ioctl(file->f_dentry->d_inode, file,
+	return drm_ioctl(file->f_path.dentry->d_inode, file,
 			 DRM_IOCTL_SG_FREE, (unsigned long)request);
 }
 
@@ -988,7 +988,7 @@ static int compat_drm_wait_vblank(struct file *file, unsigned int cmd,
 	    || __put_user(req32.request.signal, &request->request.signal))
 		return -EFAULT;
 
-	err = drm_ioctl(file->f_dentry->d_inode, file,
+	err = drm_ioctl(file->f_path.dentry->d_inode, file,
 			DRM_IOCTL_WAIT_VBLANK, (unsigned long)request);
 	if (err)
 		return err;
@@ -1060,7 +1060,7 @@ long drm_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
 	if (fn != NULL)
 		ret = (*fn) (filp, cmd, arg);
 	else
-		ret = drm_ioctl(filp->f_dentry->d_inode, filp, cmd, arg);
+		ret = drm_ioctl(filp->f_path.dentry->d_inode, filp, cmd, arg);
 	unlock_kernel();
 
 	return ret;
diff --git a/drivers/char/drm/i915_ioc32.c b/drivers/char/drm/i915_ioc32.c
index 296248cdc767..1fe68a251b75 100644
--- a/drivers/char/drm/i915_ioc32.c
+++ b/drivers/char/drm/i915_ioc32.c
@@ -66,7 +66,7 @@ static int compat_i915_batchbuffer(struct file *file, unsigned int cmd,
 			  &batchbuffer->cliprects))
 		return -EFAULT;
 
-	return drm_ioctl(file->f_dentry->d_inode, file,
+	return drm_ioctl(file->f_path.dentry->d_inode, file,
 			 DRM_IOCTL_I915_BATCHBUFFER,
 			 (unsigned long)batchbuffer);
 }
@@ -102,7 +102,7 @@ static int compat_i915_cmdbuffer(struct file *file, unsigned int cmd,
 			  &cmdbuffer->cliprects))
 		return -EFAULT;
 
-	return drm_ioctl(file->f_dentry->d_inode, file,
+	return drm_ioctl(file->f_path.dentry->d_inode, file,
 			 DRM_IOCTL_I915_CMDBUFFER, (unsigned long)cmdbuffer);
 }
 
@@ -125,7 +125,7 @@ static int compat_i915_irq_emit(struct file *file, unsigned int cmd,
 			  &request->irq_seq))
 		return -EFAULT;
 
-	return drm_ioctl(file->f_dentry->d_inode, file,
+	return drm_ioctl(file->f_path.dentry->d_inode, file,
 			 DRM_IOCTL_I915_IRQ_EMIT, (unsigned long)request);
 }
 typedef struct drm_i915_getparam32 {
@@ -149,7 +149,7 @@ static int compat_i915_getparam(struct file *file, unsigned int cmd,
 			  &request->value))
 		return -EFAULT;
 
-	return drm_ioctl(file->f_dentry->d_inode, file,
+	return drm_ioctl(file->f_path.dentry->d_inode, file,
 			 DRM_IOCTL_I915_GETPARAM, (unsigned long)request);
 }
 
@@ -178,7 +178,7 @@ static int compat_i915_alloc(struct file *file, unsigned int cmd,
 			  &request->region_offset))
 		return -EFAULT;
 
-	return drm_ioctl(file->f_dentry->d_inode, file,
+	return drm_ioctl(file->f_path.dentry->d_inode, file,
 			 DRM_IOCTL_I915_ALLOC, (unsigned long)request);
 }
 
@@ -215,7 +215,7 @@ long i915_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
 	if (fn != NULL)
 		ret = (*fn) (filp, cmd, arg);
 	else
-		ret = drm_ioctl(filp->f_dentry->d_inode, filp, cmd, arg);
+		ret = drm_ioctl(filp->f_path.dentry->d_inode, filp, cmd, arg);
 	unlock_kernel();
 
 	return ret;
diff --git a/drivers/char/drm/mga_ioc32.c b/drivers/char/drm/mga_ioc32.c
index 54a18eb2fc04..30d00478ddee 100644
--- a/drivers/char/drm/mga_ioc32.c
+++ b/drivers/char/drm/mga_ioc32.c
@@ -100,7 +100,7 @@ static int compat_mga_init(struct file *file, unsigned int cmd,
 	if (err)
 		return -EFAULT;
 
-	return drm_ioctl(file->f_dentry->d_inode, file,
+	return drm_ioctl(file->f_path.dentry->d_inode, file,
 			 DRM_IOCTL_MGA_INIT, (unsigned long)init);
 }
 
@@ -125,7 +125,7 @@ static int compat_mga_getparam(struct file *file, unsigned int cmd,
 			  &getparam->value))
 		return -EFAULT;
 
-	return drm_ioctl(file->f_dentry->d_inode, file,
+	return drm_ioctl(file->f_path.dentry->d_inode, file,
 			 DRM_IOCTL_MGA_GETPARAM, (unsigned long)getparam);
 }
 
@@ -166,7 +166,7 @@ static int compat_mga_dma_bootstrap(struct file *file, unsigned int cmd,
 	    || __put_user(dma_bootstrap32.agp_size, &dma_bootstrap->agp_size))
 		return -EFAULT;
 
-	err = drm_ioctl(file->f_dentry->d_inode, file,
+	err = drm_ioctl(file->f_path.dentry->d_inode, file,
 			DRM_IOCTL_MGA_DMA_BOOTSTRAP,
 			(unsigned long)dma_bootstrap);
 	if (err)
@@ -224,7 +224,7 @@ long mga_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
 	if (fn != NULL)
 		ret = (*fn) (filp, cmd, arg);
 	else
-		ret = drm_ioctl(filp->f_dentry->d_inode, filp, cmd, arg);
+		ret = drm_ioctl(filp->f_path.dentry->d_inode, filp, cmd, arg);
 	unlock_kernel();
 
 	return ret;
diff --git a/drivers/char/drm/r128_ioc32.c b/drivers/char/drm/r128_ioc32.c
index 9dd6d4116e47..d3cb676eee84 100644
--- a/drivers/char/drm/r128_ioc32.c
+++ b/drivers/char/drm/r128_ioc32.c
@@ -95,7 +95,7 @@ static int compat_r128_init(struct file *file, unsigned int cmd,
 			  &init->agp_textures_offset))
 		return -EFAULT;
 
-	return drm_ioctl(file->f_dentry->d_inode, file,
+	return drm_ioctl(file->f_path.dentry->d_inode, file,
 			 DRM_IOCTL_R128_INIT, (unsigned long)init);
 }
 
@@ -129,7 +129,7 @@ static int compat_r128_depth(struct file *file, unsigned int cmd,
 			  &depth->mask))
 		return -EFAULT;
 
-	return drm_ioctl(file->f_dentry->d_inode, file,
+	return drm_ioctl(file->f_path.dentry->d_inode, file,
 			 DRM_IOCTL_R128_DEPTH, (unsigned long)depth);
 
 }
@@ -153,7 +153,7 @@ static int compat_r128_stipple(struct file *file, unsigned int cmd,
 			  &stipple->mask))
 		return -EFAULT;
 
-	return drm_ioctl(file->f_dentry->d_inode, file,
+	return drm_ioctl(file->f_path.dentry->d_inode, file,
 			 DRM_IOCTL_R128_STIPPLE, (unsigned long)stipple);
 }
 
@@ -178,7 +178,7 @@ static int compat_r128_getparam(struct file *file, unsigned int cmd,
 			  &getparam->value))
 		return -EFAULT;
 
-	return drm_ioctl(file->f_dentry->d_inode, file,
+	return drm_ioctl(file->f_path.dentry->d_inode, file,
 			 DRM_IOCTL_R128_GETPARAM, (unsigned long)getparam);
 }
 
@@ -214,7 +214,7 @@ long r128_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
 	if (fn != NULL)
 		ret = (*fn) (filp, cmd, arg);
 	else
-		ret = drm_ioctl(filp->f_dentry->d_inode, filp, cmd, arg);
+		ret = drm_ioctl(filp->f_path.dentry->d_inode, filp, cmd, arg);
 	unlock_kernel();
 
 	return ret;
diff --git a/drivers/char/drm/radeon_ioc32.c b/drivers/char/drm/radeon_ioc32.c
index 0ccfd3618ff1..1f1f9cc055a4 100644
--- a/drivers/char/drm/radeon_ioc32.c
+++ b/drivers/char/drm/radeon_ioc32.c
@@ -92,7 +92,7 @@ static int compat_radeon_cp_init(struct file *file, unsigned int cmd,
 			  &init->gart_textures_offset))
 		return -EFAULT;
 
-	return drm_ioctl(file->f_dentry->d_inode, file,
+	return drm_ioctl(file->f_path.dentry->d_inode, file,
 			 DRM_IOCTL_RADEON_CP_INIT, (unsigned long)init);
 }
 
@@ -125,7 +125,7 @@ static int compat_radeon_cp_clear(struct file *file, unsigned int cmd,
 			  &clr->depth_boxes))
 		return -EFAULT;
 
-	return drm_ioctl(file->f_dentry->d_inode, file,
+	return drm_ioctl(file->f_path.dentry->d_inode, file,
 			 DRM_IOCTL_RADEON_CLEAR, (unsigned long)clr);
 }
 
@@ -149,7 +149,7 @@ static int compat_radeon_cp_stipple(struct file *file, unsigned int cmd,
 			  &request->mask))
 		return -EFAULT;
 
-	return drm_ioctl(file->f_dentry->d_inode, file,
+	return drm_ioctl(file->f_path.dentry->d_inode, file,
 			 DRM_IOCTL_RADEON_STIPPLE, (unsigned long)request);
 }
 
@@ -204,7 +204,7 @@ static int compat_radeon_cp_texture(struct file *file, unsigned int cmd,
 			  &image->data))
 		return -EFAULT;
 
-	return drm_ioctl(file->f_dentry->d_inode, file,
+	return drm_ioctl(file->f_path.dentry->d_inode, file,
 			 DRM_IOCTL_RADEON_TEXTURE, (unsigned long)request);
 }
 
@@ -238,7 +238,7 @@ static int compat_radeon_cp_vertex2(struct file *file, unsigned int cmd,
 			  &request->prim))
 		return -EFAULT;
 
-	return drm_ioctl(file->f_dentry->d_inode, file,
+	return drm_ioctl(file->f_path.dentry->d_inode, file,
 			 DRM_IOCTL_RADEON_VERTEX2, (unsigned long)request);
 }
 
@@ -268,7 +268,7 @@ static int compat_radeon_cp_cmdbuf(struct file *file, unsigned int cmd,
 			  &request->boxes))
 		return -EFAULT;
 
-	return drm_ioctl(file->f_dentry->d_inode, file,
+	return drm_ioctl(file->f_path.dentry->d_inode, file,
 			 DRM_IOCTL_RADEON_CMDBUF, (unsigned long)request);
 }
 
@@ -293,7 +293,7 @@ static int compat_radeon_cp_getparam(struct file *file, unsigned int cmd,
 			  &request->value))
 		return -EFAULT;
 
-	return drm_ioctl(file->f_dentry->d_inode, file,
+	return drm_ioctl(file->f_path.dentry->d_inode, file,
 			 DRM_IOCTL_RADEON_GETPARAM, (unsigned long)request);
 }
 
@@ -322,7 +322,7 @@ static int compat_radeon_mem_alloc(struct file *file, unsigned int cmd,
 			  &request->region_offset))
 		return -EFAULT;
 
-	return drm_ioctl(file->f_dentry->d_inode, file,
+	return drm_ioctl(file->f_path.dentry->d_inode, file,
 			 DRM_IOCTL_RADEON_ALLOC, (unsigned long)request);
 }
 
@@ -345,7 +345,7 @@ static int compat_radeon_irq_emit(struct file *file, unsigned int cmd,
 			  &request->irq_seq))
 		return -EFAULT;
 
-	return drm_ioctl(file->f_dentry->d_inode, file,
+	return drm_ioctl(file->f_path.dentry->d_inode, file,
 			 DRM_IOCTL_RADEON_IRQ_EMIT, (unsigned long)request);
 }
 
@@ -386,7 +386,7 @@ long radeon_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
 	if (fn != NULL)
 		ret = (*fn) (filp, cmd, arg);
 	else
-		ret = drm_ioctl(filp->f_dentry->d_inode, filp, cmd, arg);
+		ret = drm_ioctl(filp->f_path.dentry->d_inode, filp, cmd, arg);
 	unlock_kernel();
 
 	return ret;
diff --git a/drivers/char/dsp56k.c b/drivers/char/dsp56k.c
index 9b1bf60ffbe7..06f2dbf17710 100644
--- a/drivers/char/dsp56k.c
+++ b/drivers/char/dsp56k.c
@@ -201,7 +201,7 @@ static int dsp56k_upload(u_char __user *bin, int len)
 static ssize_t dsp56k_read(struct file *file, char __user *buf, size_t count,
 			   loff_t *ppos)
 {
-	struct inode *inode = file->f_dentry->d_inode;
+	struct inode *inode = file->f_path.dentry->d_inode;
 	int dev = iminor(inode) & 0x0f;
 
 	switch(dev)
@@ -264,7 +264,7 @@ static ssize_t dsp56k_read(struct file *file, char __user *buf, size_t count,
 static ssize_t dsp56k_write(struct file *file, const char __user *buf, size_t count,
 			    loff_t *ppos)
 {
-	struct inode *inode = file->f_dentry->d_inode;
+	struct inode *inode = file->f_path.dentry->d_inode;
 	int dev = iminor(inode) & 0x0f;
 
 	switch(dev)
@@ -420,7 +420,7 @@ static int dsp56k_ioctl(struct inode *inode, struct file *file,
 #if 0
 static unsigned int dsp56k_poll(struct file *file, poll_table *wait)
 {
-	int dev = iminor(file->f_dentry->d_inode) & 0x0f;
+	int dev = iminor(file->f_path.dentry->d_inode) & 0x0f;
 
 	switch(dev)
 	{
diff --git a/drivers/char/dtlk.c b/drivers/char/dtlk.c
index 5e82c3bad2e3..d4005e94fe5f 100644
--- a/drivers/char/dtlk.c
+++ b/drivers/char/dtlk.c
@@ -122,7 +122,7 @@ static void dtlk_timer_tick(unsigned long data);
 static ssize_t dtlk_read(struct file *file, char __user *buf,
 			 size_t count, loff_t * ppos)
 {
-	unsigned int minor = iminor(file->f_dentry->d_inode);
+	unsigned int minor = iminor(file->f_path.dentry->d_inode);
 	char ch;
 	int i = 0, retries;
 
@@ -174,7 +174,7 @@ static ssize_t dtlk_write(struct file *file, const char __user *buf,
 	}
 #endif
 
-	if (iminor(file->f_dentry->d_inode) != DTLK_MINOR)
+	if (iminor(file->f_path.dentry->d_inode) != DTLK_MINOR)
 		return -EINVAL;
 
 	while (1) {
diff --git a/drivers/char/epca.c b/drivers/char/epca.c
index 7c71eb779802..a0f822c9d74d 100644
--- a/drivers/char/epca.c
+++ b/drivers/char/epca.c
@@ -199,7 +199,7 @@ static int pc_ioctl(struct tty_struct *, struct file *,
                     unsigned int, unsigned long);
 static int info_ioctl(struct tty_struct *, struct file *,
                     unsigned int, unsigned long);
-static void pc_set_termios(struct tty_struct *, struct termios *);
+static void pc_set_termios(struct tty_struct *, struct ktermios *);
 static void do_softint(struct work_struct *work);
 static void pc_stop(struct tty_struct *);
 static void pc_start(struct tty_struct *);
@@ -1236,6 +1236,8 @@ static int __init pc_init(void)
 	pc_driver->init_termios.c_oflag = 0;
 	pc_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | CLOCAL | HUPCL;
 	pc_driver->init_termios.c_lflag = 0;
+	pc_driver->init_termios.c_ispeed = 9600;
+	pc_driver->init_termios.c_ospeed = 9600;
 	pc_driver->flags = TTY_DRIVER_REAL_RAW;
 	tty_set_operations(pc_driver, &pc_ops);
 
@@ -1250,6 +1252,8 @@ static int __init pc_init(void)
 	pc_info->init_termios.c_oflag = 0;
 	pc_info->init_termios.c_lflag = 0;
 	pc_info->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL;
+	pc_info->init_termios.c_ispeed = 9600;
+	pc_info->init_termios.c_ospeed = 9600;
 	pc_info->flags = TTY_DRIVER_REAL_RAW;
 	tty_set_operations(pc_info, &info_ops);
 
@@ -1999,7 +2003,7 @@ static void epcaparam(struct tty_struct *tty, struct channel *ch)
 { /* Begin epcaparam */
 
 	unsigned int cmdHead;
-	struct termios *ts;
+	struct ktermios *ts;
 	struct board_chan __iomem *bc;
 	unsigned mval, hflow, cflag, iflag;
 
@@ -2114,7 +2118,7 @@ static void receive_data(struct channel *ch)
 { /* Begin receive_data */
 
 	unchar *rptr;
-	struct termios *ts = NULL;
+	struct ktermios *ts = NULL;
 	struct tty_struct *tty;
 	struct board_chan __iomem *bc;
 	int dataToRead, wrapgap, bytesAvailable;
@@ -2362,12 +2366,14 @@ static int pc_ioctl(struct tty_struct *tty, struct file * file,
 	switch (cmd) 
 	{ /* Begin switch cmd */
 
+#if 0	/* Handled by calling layer properly */
 		case TCGETS:
-			if (copy_to_user(argp, tty->termios, sizeof(struct termios)))
+			if (copy_to_user(argp, tty->termios, sizeof(struct ktermios)))
 				return -EFAULT;
 			return 0;
 		case TCGETA:
 			return get_termio(tty, argp);
+#endif
 		case TCSBRK:	/* SVID version: non-zero arg --> no break */
 			retval = tty_check_change(tty);
 			if (retval)
@@ -2536,7 +2542,7 @@ static int pc_ioctl(struct tty_struct *tty, struct file * file,
 
 /* --------------------- Begin pc_set_termios  ----------------------- */
 
-static void pc_set_termios(struct tty_struct *tty, struct termios *old_termios)
+static void pc_set_termios(struct tty_struct *tty, struct ktermios *old_termios)
 { /* Begin pc_set_termios */
 
 	struct channel *ch;
diff --git a/drivers/char/esp.c b/drivers/char/esp.c
index 93b551962513..d1bfbaa2aa02 100644
--- a/drivers/char/esp.c
+++ b/drivers/char/esp.c
@@ -1915,7 +1915,7 @@ static int rs_ioctl(struct tty_struct *tty, struct file * file,
 	return 0;
 }
 
-static void rs_set_termios(struct tty_struct *tty, struct termios *old_termios)
+static void rs_set_termios(struct tty_struct *tty, struct ktermios *old_termios)
 {
 	struct esp_struct *info = (struct esp_struct *)tty->driver_data;
 	unsigned long flags;
diff --git a/drivers/char/generic_serial.c b/drivers/char/generic_serial.c
index 87127e49c0db..e769811e7417 100644
--- a/drivers/char/generic_serial.c
+++ b/drivers/char/generic_serial.c
@@ -718,11 +718,11 @@ static unsigned int     gs_baudrates[] = {
 
 
 void gs_set_termios (struct tty_struct * tty, 
-                     struct termios * old_termios)
+                     struct ktermios * old_termios)
 {
 	struct gs_port *port;
 	int baudrate, tmp, rv;
-	struct termios *tiosp;
+	struct ktermios *tiosp;
 
 	func_enter();
 
diff --git a/drivers/char/hvcs.c b/drivers/char/hvcs.c
index d090622f1dea..207f7343ba60 100644
--- a/drivers/char/hvcs.c
+++ b/drivers/char/hvcs.c
@@ -192,11 +192,13 @@ MODULE_VERSION(HVCS_DRIVER_VERSION);
  * that will cause echoing or we'll go into recursive loop echoing chars back
  * and forth with the console drivers.
  */
-static struct termios hvcs_tty_termios = {
+static struct ktermios hvcs_tty_termios = {
 	.c_iflag = IGNBRK | IGNPAR,
 	.c_oflag = OPOST,
 	.c_cflag = B38400 | CS8 | CREAD | HUPCL,
-	.c_cc = INIT_C_CC
+	.c_cc = INIT_C_CC,
+	.c_ispeed = 38400,
+	.c_ospeed = 38400
 };
 
 /*
diff --git a/drivers/char/hvsi.c b/drivers/char/hvsi.c
index 82a41d5b4ed0..d7806834fc17 100644
--- a/drivers/char/hvsi.c
+++ b/drivers/char/hvsi.c
@@ -1161,6 +1161,8 @@ static int __init hvsi_init(void)
 	hvsi_driver->type = TTY_DRIVER_TYPE_SYSTEM;
 	hvsi_driver->init_termios = tty_std_termios;
 	hvsi_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL;
+	hvsi_driver->init_termios.c_ispeed = 9600;
+	hvsi_driver->init_termios.c_ospeed = 9600;
 	hvsi_driver->flags = TTY_DRIVER_REAL_RAW;
 	tty_set_operations(hvsi_driver, &hvsi_ops);
 
diff --git a/drivers/char/ip2/ip2main.c b/drivers/char/ip2/ip2main.c
index cda2459c1d60..7c70310a49b5 100644
--- a/drivers/char/ip2/ip2main.c
+++ b/drivers/char/ip2/ip2main.c
@@ -177,7 +177,7 @@ static int  ip2_write_room(PTTY);
 static int  ip2_chars_in_buf(PTTY);
 static void ip2_flush_buffer(PTTY);
 static int  ip2_ioctl(PTTY, struct file *, UINT, ULONG);
-static void ip2_set_termios(PTTY, struct termios *);
+static void ip2_set_termios(PTTY, struct ktermios *);
 static void ip2_set_line_discipline(PTTY);
 static void ip2_throttle(PTTY);
 static void ip2_unthrottle(PTTY);
@@ -198,7 +198,7 @@ static void do_status(struct work_struct *);
 
 static void ip2_wait_until_sent(PTTY,int);
 
-static void set_params (i2ChanStrPtr, struct termios *);
+static void set_params (i2ChanStrPtr, struct ktermios *);
 static int get_serial_info(i2ChanStrPtr, struct serial_struct __user *);
 static int set_serial_info(i2ChanStrPtr, struct serial_struct __user *);
 
@@ -2398,7 +2398,7 @@ set_serial_info( i2ChanStrPtr pCh, struct serial_struct __user *new_info )
 /*                                                                            */
 /******************************************************************************/
 static void
-ip2_set_termios( PTTY tty, struct termios *old_termios )
+ip2_set_termios( PTTY tty, struct ktermios *old_termios )
 {
 	i2ChanStrPtr pCh = (i2ChanStrPtr)tty->driver_data;
 
@@ -2440,11 +2440,11 @@ ip2_set_line_discipline ( PTTY tty )
 /* change.                                                                    */
 /******************************************************************************/
 static void
-set_params( i2ChanStrPtr pCh, struct termios *o_tios )
+set_params( i2ChanStrPtr pCh, struct ktermios *o_tios )
 {
 	tcflag_t cflag, iflag, lflag;
 	char stop_char, start_char;
-	struct termios dummy;
+	struct ktermios dummy;
 
 	lflag = pCh->pTTY->termios->c_lflag;
 	cflag = pCh->pTTY->termios->c_cflag;
@@ -2700,7 +2700,7 @@ static
 ssize_t
 ip2_ipl_read(struct file *pFile, char __user *pData, size_t count, loff_t *off )
 {
-	unsigned int minor = iminor(pFile->f_dentry->d_inode);
+	unsigned int minor = iminor(pFile->f_path.dentry->d_inode);
 	int rc = 0;
 
 #ifdef IP2DEBUG_IPL
diff --git a/drivers/char/ipmi/ipmi_devintf.c b/drivers/char/ipmi/ipmi_devintf.c
index 375d3378eecd..e257835a9a73 100644
--- a/drivers/char/ipmi/ipmi_devintf.c
+++ b/drivers/char/ipmi/ipmi_devintf.c
@@ -798,7 +798,7 @@ static long compat_ipmi_ioctl(struct file *filep, unsigned int cmd,
 		if (copy_to_user(precv64, &recv64, sizeof(recv64)))
 			return -EFAULT;
 
-		rc = ipmi_ioctl(filep->f_dentry->d_inode, filep,
+		rc = ipmi_ioctl(filep->f_path.dentry->d_inode, filep,
 				((cmd == COMPAT_IPMICTL_RECEIVE_MSG)
 				 ? IPMICTL_RECEIVE_MSG
 				 : IPMICTL_RECEIVE_MSG_TRUNC),
@@ -815,7 +815,7 @@ static long compat_ipmi_ioctl(struct file *filep, unsigned int cmd,
 		return rc;
 	}
 	default:
-		return ipmi_ioctl(filep->f_dentry->d_inode, filep, cmd, arg);
+		return ipmi_ioctl(filep->f_path.dentry->d_inode, filep, cmd, arg);
 	}
 }
 #endif
diff --git a/drivers/char/isicom.c b/drivers/char/isicom.c
index 1637c1d9a4ba..5a747e685993 100644
--- a/drivers/char/isicom.c
+++ b/drivers/char/isicom.c
@@ -172,12 +172,14 @@ static struct pci_driver isicom_driver = {
 static int prev_card = 3;	/*	start servicing isi_card[0]	*/
 static struct tty_driver *isicom_normal;
 
-static struct timer_list tx;
+static DECLARE_COMPLETION(isi_timerdone);
 static char re_schedule = 1;
 
 static void isicom_tx(unsigned long _data);
 static void isicom_start(struct tty_struct *tty);
 
+static DEFINE_TIMER(tx, isicom_tx, 0, 0);
+
 /*   baud index mappings from linux defns to isi */
 
 static signed char linuxb_to_isib[] = {
@@ -193,9 +195,9 @@ struct	isi_board {
 	unsigned short		shift_count;
 	struct isi_port		* ports;
 	signed char		count;
-	unsigned char		isa;
 	spinlock_t		card_lock; /* Card wide lock 11/5/00 -sameer */
 	unsigned long		flags;
+	unsigned int		index;
 };
 
 struct	isi_port {
@@ -514,17 +516,11 @@ static void isicom_tx(unsigned long _data)
 	/*	schedule another tx for hopefully in about 10ms	*/
 sched_again:
 	if (!re_schedule) {
-		re_schedule = 2;
+		complete(&isi_timerdone);
  		return;
 	}
 
-	init_timer(&tx);
-	tx.expires = jiffies + HZ/100;
-	tx.data = 0;
-	tx.function = isicom_tx;
-	add_timer(&tx);
-
-	return;
+	mod_timer(&tx, jiffies + msecs_to_jiffies(10));
 }
 
 /* 	Interrupt handlers 	*/
@@ -562,14 +558,12 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id)
 	base = card->base;
 	spin_lock(&card->card_lock);
 
-	if (card->isa == NO) {
-		/*
-		 * disable any interrupts from the PCI card and lower the
-		 * interrupt line
-		 */
-		outw(0x8000, base+0x04);
-		ClearInterrupt(base);
-	}
+	/*
+	 * disable any interrupts from the PCI card and lower the
+	 * interrupt line
+	 */
+	outw(0x8000, base+0x04);
+	ClearInterrupt(base);
 
 	inw(base);		/* get the dummy word out */
 	header = inw(base);
@@ -579,19 +573,13 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id)
 	if (channel + 1 > card->port_count) {
 		printk(KERN_WARNING "ISICOM: isicom_interrupt(0x%lx): "
 			"%d(channel) > port_count.\n", base, channel+1);
-		if (card->isa)
-			ClearInterrupt(base);
-		else
-			outw(0x0000, base+0x04); /* enable interrupts */
+		outw(0x0000, base+0x04); /* enable interrupts */
 		spin_unlock(&card->card_lock);
 		return IRQ_HANDLED;
 	}
 	port = card->ports + channel;
 	if (!(port->flags & ASYNC_INITIALIZED)) {
-		if (card->isa)
-			ClearInterrupt(base);
-		else
-			outw(0x0000, base+0x04); /* enable interrupts */
+		outw(0x0000, base+0x04); /* enable interrupts */
 		return IRQ_HANDLED;
 	}
 
@@ -604,10 +592,7 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id)
 		}
 		if (byte_count & 0x01)
 			inw(base);
-		if (card->isa == YES)
-			ClearInterrupt(base);
-		else
-			outw(0x0000, base+0x04); /* enable interrupts */
+		outw(0x0000, base+0x04); /* enable interrupts */
 		spin_unlock(&card->card_lock);
 		return IRQ_HANDLED;
 	}
@@ -708,10 +693,7 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id)
 		}
 		tty_flip_buffer_push(tty);
 	}
-	if (card->isa == YES)
-		ClearInterrupt(base);
-	else
-		outw(0x0000, base+0x04); /* enable interrupts */
+	outw(0x0000, base+0x04); /* enable interrupts */
 
 	return IRQ_HANDLED;
 }
@@ -964,8 +946,8 @@ static int isicom_open(struct tty_struct *tty, struct file *filp)
 {
 	struct isi_port *port;
 	struct isi_board *card;
-	unsigned int line, board;
-	int error;
+	unsigned int board;
+	int error, line;
 
 	line = tty->index;
 	if (line < 0 || line > PORT_COUNT-1)
@@ -1399,7 +1381,7 @@ static int isicom_ioctl(struct tty_struct *tty, struct file *filp,
 
 /* set_termios et all */
 static void isicom_set_termios(struct tty_struct *tty,
-	struct termios *old_termios)
+	struct ktermios *old_termios)
 {
 	struct isi_port *port = tty->driver_data;
 
@@ -1520,37 +1502,6 @@ static void isicom_flush_buffer(struct tty_struct *tty)
  * Driver init and deinit functions
  */
 
-static int __devinit isicom_register_ioregion(struct pci_dev *pdev,
-	const unsigned int index)
-{
-	struct isi_board *board = pci_get_drvdata(pdev);
-
-	if (!board->base)
-		return -EINVAL;
-
-	if (!request_region(board->base, 16, ISICOM_NAME)) {
-		dev_dbg(&pdev->dev, "I/O Region 0x%lx-0x%lx is busy. Card%d "
-			"will be disabled.\n", board->base, board->base + 15,
-			index + 1);
-		return -EBUSY;
- 	}
-
-	return 0;
-}
-
-static void isicom_unregister_ioregion(struct pci_dev *pdev)
-{
-	struct isi_board *board = pci_get_drvdata(pdev);
-
-	if (!board->base)
-		return;
-
-	release_region(board->base, 16);
-	dev_dbg(&pdev->dev, "I/O Region 0x%lx-0x%lx released.\n",
-		board->base, board->base + 15);
-	board->base = 0;
-}
-
 static const struct tty_operations isicom_ops = {
 	.open			= isicom_open,
 	.close			= isicom_close,
@@ -1571,70 +1522,6 @@ static const struct tty_operations isicom_ops = {
 	.tiocmset		= isicom_tiocmset,
 };
 
-static int __devinit isicom_register_tty_driver(void)
-{
-	int error = -ENOMEM;
-
-	/* tty driver structure initialization */
-	isicom_normal = alloc_tty_driver(PORT_COUNT);
-	if (!isicom_normal)
-		goto end;
-
-	isicom_normal->owner			= THIS_MODULE;
-	isicom_normal->name 			= "ttyM";
-	isicom_normal->major			= ISICOM_NMAJOR;
-	isicom_normal->minor_start		= 0;
-	isicom_normal->type			= TTY_DRIVER_TYPE_SERIAL;
-	isicom_normal->subtype			= SERIAL_TYPE_NORMAL;
-	isicom_normal->init_termios		= tty_std_termios;
-	isicom_normal->init_termios.c_cflag	= B9600 | CS8 | CREAD | HUPCL |
-		CLOCAL;
-	isicom_normal->flags			= TTY_DRIVER_REAL_RAW;
-	tty_set_operations(isicom_normal, &isicom_ops);
-
-	if ((error = tty_register_driver(isicom_normal))) {
-		pr_dbg("Couldn't register the dialin driver, error=%d\n",
-			error);
-		put_tty_driver(isicom_normal);
-	}
-end:
-	return error;
-}
-
-static void isicom_unregister_tty_driver(void)
-{
-	int error;
-
-	if ((error = tty_unregister_driver(isicom_normal)))
-		pr_dbg("couldn't unregister normal driver, error=%d.\n", error);
-
-	put_tty_driver(isicom_normal);
-}
-
-static int __devinit isicom_register_isr(struct pci_dev *pdev,
-	const unsigned int index)
-{
-	struct isi_board *board = pci_get_drvdata(pdev);
-	unsigned long irqflags = IRQF_DISABLED;
-	int retval = -EINVAL;
-
-	if (!board->base)
-		goto end;
-
-	if (board->isa == NO)
-		irqflags |= IRQF_SHARED;
-
-	retval = request_irq(board->irq, isicom_interrupt, irqflags,
-		ISICOM_NAME, board);
-	if (retval < 0)
-		dev_warn(&pdev->dev, "Could not install handler at Irq %d. "
-			"Card%d will be disabled.\n", board->irq, index + 1);
- 	else
-		retval = 0;
-end:
-	return retval;
-}
-
 static int __devinit reset_card(struct pci_dev *pdev,
 	const unsigned int card, unsigned int *signature)
 {
@@ -1656,36 +1543,23 @@ static int __devinit reset_card(struct pci_dev *pdev,
 
 	*signature = inw(base + 0x4) & 0xff;
 
-	if (board->isa == YES) {
-		if (!(inw(base + 0xe) & 0x1) || (inw(base + 0x2))) {
-			dev_dbg(&pdev->dev, "base+0x2=0x%lx, base+0xe=0x%lx\n",
-				inw(base + 0x2), inw(base + 0xe));
-			dev_err(&pdev->dev, "ISILoad:ISA Card%d reset failure "
-				"(Possible bad I/O Port Address 0x%lx).\n",
-				card + 1, base);
-			retval = -EIO;
-			goto end;
-		}
-	} else {
-		portcount = inw(base + 0x2);
-		if (!(inw(base + 0xe) & 0x1) || ((portcount != 0) &&
-				(portcount != 4) && (portcount != 8))) {
-			dev_dbg(&pdev->dev, "base+0x2=0x%lx, base+0xe=0x%lx\n",
-				inw(base + 0x2), inw(base + 0xe));
-			dev_err(&pdev->dev, "ISILoad:PCI Card%d reset failure "
-				"(Possible bad I/O Port Address 0x%lx).\n",
-				card + 1, base);
-			retval = -EIO;
-			goto end;
-		}
+	portcount = inw(base + 0x2);
+	if (!(inw(base + 0xe) & 0x1) || ((portcount != 0) &&
+			(portcount != 4) && (portcount != 8))) {
+		dev_dbg(&pdev->dev, "base+0x2=0x%lx, base+0xe=0x%lx\n",
+			inw(base + 0x2), inw(base + 0xe));
+		dev_err(&pdev->dev, "ISILoad:PCI Card%d reset failure "
+			"(Possible bad I/O Port Address 0x%lx).\n",
+			card + 1, base);
+		retval = -EIO;
+		goto end;
 	}
 
 	switch (*signature) {
 	case 0xa5:
 	case 0xbb:
 	case 0xdd:
-		board->port_count = (board->isa == NO && portcount == 4) ? 4 :
-			8;
+		board->port_count = (portcount == 4) ? 4 : 8;
 		board->shift_count = 12;
 		break;
 	case 0xcc:
@@ -1831,6 +1705,11 @@ static int __devinit load_firmware(struct pci_dev *pdev,
 		}
 
 		data = kmalloc(word_count * 2, GFP_KERNEL);
+		if (data == NULL) {
+			dev_err(&pdev->dev, "Card%d, firmware upload "
+				"failed, not enough memory\n", index + 1);
+			goto errrelfw;
+		}
 		inw(base);
 		insw(base, data, word_count);
 		InterruptTheCard(base);
@@ -1879,8 +1758,6 @@ end:
 /*
  *	Insmod can set static symbols so keep these static
  */
-static int io[4];
-static int irq[4];
 static int card;
 
 static int __devinit isicom_probe(struct pci_dev *pdev,
@@ -1906,20 +1783,29 @@ static int __devinit isicom_probe(struct pci_dev *pdev,
 			break;
 		}
 
+	board->index = index;
 	board->base = ioaddr;
 	board->irq = pciirq;
-	board->isa = NO;
 	card++;
 
 	pci_set_drvdata(pdev, board);
 
-	retval = isicom_register_ioregion(pdev, index);
-	if (retval < 0)
+	retval = pci_request_region(pdev, 3, ISICOM_NAME);
+	if (retval) {
+		dev_err(&pdev->dev, "I/O Region 0x%lx-0x%lx is busy. Card%d "
+			"will be disabled.\n", board->base, board->base + 15,
+			index + 1);
+		retval = -EBUSY;
 		goto err;
+ 	}
 
-	retval = isicom_register_isr(pdev, index);
-	if (retval < 0)
+	retval = request_irq(board->irq, isicom_interrupt,
+			IRQF_SHARED | IRQF_DISABLED, ISICOM_NAME, board);
+	if (retval < 0) {
+		dev_err(&pdev->dev, "Could not install handler at Irq %d. "
+			"Card%d will be disabled.\n", board->irq, index + 1);
 		goto errunrr;
+	}
 
 	retval = reset_card(pdev, index, &signature);
 	if (retval < 0)
@@ -1929,12 +1815,16 @@ static int __devinit isicom_probe(struct pci_dev *pdev,
 	if (retval < 0)
 		goto errunri;
 
+	for (index = 0; index < board->port_count; index++)
+		tty_register_device(isicom_normal, board->index * 16 + index,
+				&pdev->dev);
+
 	return 0;
 
 errunri:
 	free_irq(board->irq, board);
 errunrr:
-	isicom_unregister_ioregion(pdev);
+	pci_release_region(pdev, 3);
 err:
 	board->base = 0;
 	return retval;
@@ -1943,18 +1833,21 @@ err:
 static void __devexit isicom_remove(struct pci_dev *pdev)
 {
 	struct isi_board *board = pci_get_drvdata(pdev);
+	unsigned int i;
+
+	for (i = 0; i < board->port_count; i++)
+		tty_unregister_device(isicom_normal, board->index * 16 + i);
 
 	free_irq(board->irq, board);
-	isicom_unregister_ioregion(pdev);
+	pci_release_region(pdev, 3);
 }
 
-static int __devinit isicom_setup(void)
+static int __init isicom_init(void)
 {
 	int retval, idx, channel;
 	struct isi_port *port;
 
 	card = 0;
-	memset(isi_ports, 0, sizeof(isi_ports));
 
 	for(idx = 0; idx < BOARD_COUNT; idx++) {
 		port = &isi_ports[idx * 16];
@@ -1975,66 +1868,65 @@ static int __devinit isicom_setup(void)
  		}
 		isi_card[idx].base = 0;
 		isi_card[idx].irq = 0;
-
-		if (!io[idx])
-			continue;
-
-		if (irq[idx] == 2 || irq[idx] == 3 || irq[idx] == 4	||
-				irq[idx] == 5	|| irq[idx] == 7	||
-				irq[idx] == 10	|| irq[idx] == 11	||
-				irq[idx] == 12	|| irq[idx] == 15) {
-			printk(KERN_ERR "ISICOM: ISA not supported yet.\n");
-			retval = -EINVAL;
-			goto error;
-		} else
-			printk(KERN_ERR "ISICOM: Irq %d unsupported. "
-				"Disabling Card%d...\n", irq[idx], idx + 1);
 	}
 
-	retval = isicom_register_tty_driver();
-	if (retval < 0)
+	/* tty driver structure initialization */
+	isicom_normal = alloc_tty_driver(PORT_COUNT);
+	if (!isicom_normal) {
+		retval = -ENOMEM;
 		goto error;
+	}
+
+	isicom_normal->owner			= THIS_MODULE;
+	isicom_normal->name 			= "ttyM";
+	isicom_normal->major			= ISICOM_NMAJOR;
+	isicom_normal->minor_start		= 0;
+	isicom_normal->type			= TTY_DRIVER_TYPE_SERIAL;
+	isicom_normal->subtype			= SERIAL_TYPE_NORMAL;
+	isicom_normal->init_termios		= tty_std_termios;
+	isicom_normal->init_termios.c_cflag	= B9600 | CS8 | CREAD | HUPCL |
+		CLOCAL;
+	isicom_normal->flags			= TTY_DRIVER_REAL_RAW |
+		TTY_DRIVER_DYNAMIC_DEV;
+	tty_set_operations(isicom_normal, &isicom_ops);
+
+	retval = tty_register_driver(isicom_normal);
+	if (retval) {
+		pr_dbg("Couldn't register the dialin driver\n");
+		goto err_puttty;
+	}
 
 	retval = pci_register_driver(&isicom_driver);
 	if (retval < 0) {
 		printk(KERN_ERR "ISICOM: Unable to register pci driver.\n");
-		goto errtty;
+		goto err_unrtty;
 	}
 
-	init_timer(&tx);
-	tx.expires = jiffies + 1;
-	tx.data = 0;
-	tx.function = isicom_tx;
-	re_schedule = 1;
-	add_timer(&tx);
+	mod_timer(&tx, jiffies + 1);
 
 	return 0;
-errtty:
-	isicom_unregister_tty_driver();
+err_unrtty:
+	tty_unregister_driver(isicom_normal);
+err_puttty:
+	put_tty_driver(isicom_normal);
 error:
 	return retval;
 }
 
 static void __exit isicom_exit(void)
 {
-	unsigned int index = 0;
-
 	re_schedule = 0;
 
-	while (re_schedule != 2 && index++ < 100)
-		msleep(10);
+	wait_for_completion_timeout(&isi_timerdone, HZ);
 
 	pci_unregister_driver(&isicom_driver);
-	isicom_unregister_tty_driver();
+	tty_unregister_driver(isicom_normal);
+	put_tty_driver(isicom_normal);
 }
 
-module_init(isicom_setup);
+module_init(isicom_init);
 module_exit(isicom_exit);
 
 MODULE_AUTHOR("MultiTech");
 MODULE_DESCRIPTION("Driver for the ISI series of cards by MultiTech");
 MODULE_LICENSE("GPL");
-module_param_array(io, int, NULL, 0);
-MODULE_PARM_DESC(io, "I/O ports for the cards");
-module_param_array(irq, int, NULL, 0);
-MODULE_PARM_DESC(irq, "Interrupts for the cards");
diff --git a/drivers/char/istallion.c b/drivers/char/istallion.c
index 8f591945ebd9..68645d351873 100644
--- a/drivers/char/istallion.c
+++ b/drivers/char/istallion.c
@@ -14,14 +14,6 @@
  *	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.
  */
 
 /*****************************************************************************/
@@ -41,6 +33,7 @@
 #include <linux/device.h>
 #include <linux/wait.h>
 #include <linux/eisa.h>
+#include <linux/ctype.h>
 
 #include <asm/io.h>
 #include <asm/uaccess.h>
@@ -61,21 +54,10 @@
 #define	BRD_BRUMBY4	2
 #define	BRD_ONBOARD2	3
 #define	BRD_ONBOARD	4
-#define	BRD_BRUMBY8	5
-#define	BRD_BRUMBY16	6
 #define	BRD_ONBOARDE	7
-#define	BRD_ONBOARD32	9
-#define	BRD_ONBOARD2_32	10
-#define	BRD_ONBOARDRS	11
-#define	BRD_EASYIO	20
-#define	BRD_ECH		21
-#define	BRD_ECHMC	22
 #define	BRD_ECP		23
 #define BRD_ECPE	24
 #define	BRD_ECPMC	25
-#define	BRD_ECHPCI	26
-#define	BRD_ECH64PCI	27
-#define	BRD_EASYIOPCI	28
 #define	BRD_ECPPCI	29
 
 #define	BRD_BRUMBY	BRD_BRUMBY4
@@ -119,20 +101,16 @@
  *	interrupt is required.
  */
 
-typedef struct {
+struct stlconf {
 	int		brdtype;
 	int		ioaddr1;
 	int		ioaddr2;
 	unsigned long	memaddr;
 	int		irq;
 	int		irqtype;
-} stlconf_t;
-
-static stlconf_t	stli_brdconf[] = {
-	/*{ BRD_ECP, 0x2a0, 0, 0xcc000, 0, 0 },*/
 };
 
-static int	stli_nrbrds = ARRAY_SIZE(stli_brdconf);
+static unsigned int stli_nrbrds;
 
 /* stli_lock must NOT be taken holding brd_lock */
 static spinlock_t stli_lock;	/* TTY logic lock */
@@ -194,9 +172,11 @@ static struct tty_struct	*stli_txcooktty;
  *	with this termios initially. Basically all it defines is a raw port
  *	at 9600 baud, 8 data bits, no parity, 1 stop bit.
  */
-static struct termios		stli_deftermios = {
+static struct ktermios		stli_deftermios = {
 	.c_cflag	= (B9600 | CS8 | CREAD | HUPCL | CLOCAL),
 	.c_cc		= INIT_C_CC,
+	.c_ispeed	= 9600,
+	.c_ospeed	= 9600,
 };
 
 /*
@@ -205,13 +185,12 @@ static struct termios		stli_deftermios = {
  */
 static comstats_t	stli_comstats;
 static combrd_t		stli_brdstats;
-static asystats_t	stli_cdkstats;
-static stlibrd_t	stli_dummybrd;
-static stliport_t	stli_dummyport;
+static struct asystats	stli_cdkstats;
 
 /*****************************************************************************/
 
-static stlibrd_t	*stli_brds[STL_MAXBRDS];
+static DEFINE_MUTEX(stli_brdslock);
+static struct stlibrd	*stli_brds[STL_MAXBRDS];
 
 static int		stli_shared;
 
@@ -223,6 +202,7 @@ static int		stli_shared;
  */
 #define	BST_FOUND	0x1
 #define	BST_STARTED	0x2
+#define	BST_PROBED	0x4
 
 /*
  *	Define the set of port state flags. These are marked for internal
@@ -255,18 +235,18 @@ static char	*stli_brdnames[] = {
 	"Brumby",
 	"Brumby",
 	"ONboard-EI",
-	(char *) NULL,
+	NULL,
 	"ONboard",
 	"ONboard-MC",
 	"ONboard-MC",
-	(char *) NULL,
-	(char *) NULL,
-	(char *) NULL,
-	(char *) NULL,
-	(char *) NULL,
-	(char *) NULL,
-	(char *) NULL,
-	(char *) NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
 	"EasyIO",
 	"EC8/32-AT",
 	"EC8/32-MC",
@@ -304,12 +284,10 @@ static char	**stli_brdsp[] = {
  *	parse any module arguments.
  */
 
-typedef struct stlibrdtype {
+static struct stlibrdtype {
 	char	*name;
 	int	type;
-} stlibrdtype_t;
-
-static stlibrdtype_t	stli_brdstr[] = {
+} stli_brdstr[] = {
 	{ "stallion", BRD_STALLION },
 	{ "1", BRD_STALLION },
 	{ "brumby", BRD_BRUMBY },
@@ -379,6 +357,7 @@ MODULE_PARM_DESC(board2, "Board 2 config -> name[,ioaddr[,memaddr]");
 module_param_array(board3, charp, NULL, 0);
 MODULE_PARM_DESC(board3, "Board 3 config -> name[,ioaddr[,memaddr]");
 
+#if STLI_EISAPROBE != 0
 /*
  *	Set up a default memory address table for EISA board probing.
  *	The default addresses are all bellow 1Mbyte, which has to be the
@@ -396,14 +375,11 @@ static unsigned long	stli_eisamemprobeaddrs[] = {
 };
 
 static int	stli_eisamempsize = ARRAY_SIZE(stli_eisamemprobeaddrs);
+#endif
 
 /*
  *	Define the Stallion PCI vendor and device IDs.
  */
-#ifdef CONFIG_PCI
-#ifndef	PCI_VENDOR_ID_STALLION
-#define	PCI_VENDOR_ID_STALLION		0x124d
-#endif
 #ifndef PCI_DEVICE_ID_ECRA
 #define	PCI_DEVICE_ID_ECRA		0x0004
 #endif
@@ -414,7 +390,7 @@ static struct pci_device_id istallion_pci_tbl[] = {
 };
 MODULE_DEVICE_TABLE(pci, istallion_pci_tbl);
 
-#endif /* CONFIG_PCI */
+static struct pci_driver stli_pcidriver;
 
 /*****************************************************************************/
 
@@ -615,22 +591,10 @@ MODULE_DEVICE_TABLE(pci, istallion_pci_tbl);
 /*****************************************************************************/
 
 /*
- *	Define some handy local macros...
- */
-#undef MIN
-#define	MIN(a,b)	(((a) <= (b)) ? (a) : (b))
-
-#undef	TOLOWER
-#define	TOLOWER(x)	((((x) >= 'A') && ((x) <= 'Z')) ? ((x) + 0x20) : (x))
-
-/*****************************************************************************/
-
-/*
  *	Prototype all functions in this driver!
  */
 
-static int	stli_parsebrd(stlconf_t *confp, char **argp);
-static int	stli_init(void);
+static int	stli_parsebrd(struct stlconf *confp, char **argp);
 static int	stli_open(struct tty_struct *tty, struct file *filp);
 static void	stli_close(struct tty_struct *tty, struct file *filp);
 static int	stli_write(struct tty_struct *tty, const unsigned char *buf, int count);
@@ -639,7 +603,7 @@ static void	stli_flushchars(struct tty_struct *tty);
 static int	stli_writeroom(struct tty_struct *tty);
 static int	stli_charsinbuffer(struct tty_struct *tty);
 static int	stli_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg);
-static void	stli_settermios(struct tty_struct *tty, struct termios *old);
+static void	stli_settermios(struct tty_struct *tty, struct ktermios *old);
 static void	stli_throttle(struct tty_struct *tty);
 static void	stli_unthrottle(struct tty_struct *tty);
 static void	stli_stop(struct tty_struct *tty);
@@ -649,86 +613,84 @@ static void	stli_breakctl(struct tty_struct *tty, int state);
 static void	stli_waituntilsent(struct tty_struct *tty, int timeout);
 static void	stli_sendxchar(struct tty_struct *tty, char ch);
 static void	stli_hangup(struct tty_struct *tty);
-static int	stli_portinfo(stlibrd_t *brdp, stliport_t *portp, int portnr, char *pos);
+static int	stli_portinfo(struct stlibrd *brdp, struct stliport *portp, int portnr, char *pos);
 
-static int	stli_brdinit(stlibrd_t *brdp);
-static int	stli_startbrd(stlibrd_t *brdp);
+static int	stli_brdinit(struct stlibrd *brdp);
+static int	stli_startbrd(struct stlibrd *brdp);
 static ssize_t	stli_memread(struct file *fp, char __user *buf, size_t count, loff_t *offp);
 static ssize_t	stli_memwrite(struct file *fp, const char __user *buf, size_t count, loff_t *offp);
 static int	stli_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, unsigned long arg);
-static void	stli_brdpoll(stlibrd_t *brdp, cdkhdr_t __iomem *hdrp);
+static void	stli_brdpoll(struct stlibrd *brdp, cdkhdr_t __iomem *hdrp);
 static void	stli_poll(unsigned long arg);
-static int	stli_hostcmd(stlibrd_t *brdp, stliport_t *portp);
-static int	stli_initopen(stlibrd_t *brdp, stliport_t *portp);
-static int	stli_rawopen(stlibrd_t *brdp, stliport_t *portp, unsigned long arg, int wait);
-static int	stli_rawclose(stlibrd_t *brdp, stliport_t *portp, unsigned long arg, int wait);
-static int	stli_waitcarrier(stlibrd_t *brdp, stliport_t *portp, struct file *filp);
+static int	stli_hostcmd(struct stlibrd *brdp, struct stliport *portp);
+static int	stli_initopen(struct stlibrd *brdp, struct stliport *portp);
+static int	stli_rawopen(struct stlibrd *brdp, struct stliport *portp, unsigned long arg, int wait);
+static int	stli_rawclose(struct stlibrd *brdp, struct stliport *portp, unsigned long arg, int wait);
+static int	stli_waitcarrier(struct stlibrd *brdp, struct stliport *portp, struct file *filp);
 static void	stli_dohangup(struct work_struct *);
-static int	stli_setport(stliport_t *portp);
-static int	stli_cmdwait(stlibrd_t *brdp, stliport_t *portp, unsigned long cmd, void *arg, int size, int copyback);
-static void	stli_sendcmd(stlibrd_t *brdp, stliport_t *portp, unsigned long cmd, void *arg, int size, int copyback);
-static void	__stli_sendcmd(stlibrd_t *brdp, stliport_t *portp, unsigned long cmd, void *arg, int size, int copyback);
-static void	stli_dodelaycmd(stliport_t *portp, cdkctrl_t __iomem *cp);
-static void	stli_mkasyport(stliport_t *portp, asyport_t *pp, struct termios *tiosp);
+static int	stli_setport(struct stliport *portp);
+static int	stli_cmdwait(struct stlibrd *brdp, struct stliport *portp, unsigned long cmd, void *arg, int size, int copyback);
+static void	stli_sendcmd(struct stlibrd *brdp, struct stliport *portp, unsigned long cmd, void *arg, int size, int copyback);
+static void	__stli_sendcmd(struct stlibrd *brdp, struct stliport *portp, unsigned long cmd, void *arg, int size, int copyback);
+static void	stli_dodelaycmd(struct stliport *portp, cdkctrl_t __iomem *cp);
+static void	stli_mkasyport(struct stliport *portp, asyport_t *pp, struct ktermios *tiosp);
 static void	stli_mkasysigs(asysigs_t *sp, int dtr, int rts);
 static long	stli_mktiocm(unsigned long sigvalue);
-static void	stli_read(stlibrd_t *brdp, stliport_t *portp);
-static int	stli_getserial(stliport_t *portp, struct serial_struct __user *sp);
-static int	stli_setserial(stliport_t *portp, struct serial_struct __user *sp);
+static void	stli_read(struct stlibrd *brdp, struct stliport *portp);
+static int	stli_getserial(struct stliport *portp, struct serial_struct __user *sp);
+static int	stli_setserial(struct stliport *portp, struct serial_struct __user *sp);
 static int	stli_getbrdstats(combrd_t __user *bp);
-static int	stli_getportstats(stliport_t *portp, comstats_t __user *cp);
-static int	stli_portcmdstats(stliport_t *portp);
-static int	stli_clrportstats(stliport_t *portp, comstats_t __user *cp);
-static int	stli_getportstruct(stliport_t __user *arg);
-static int	stli_getbrdstruct(stlibrd_t __user *arg);
-static stlibrd_t *stli_allocbrd(void);
-
-static void	stli_ecpinit(stlibrd_t *brdp);
-static void	stli_ecpenable(stlibrd_t *brdp);
-static void	stli_ecpdisable(stlibrd_t *brdp);
-static void __iomem *stli_ecpgetmemptr(stlibrd_t *brdp, unsigned long offset, int line);
-static void	stli_ecpreset(stlibrd_t *brdp);
-static void	stli_ecpintr(stlibrd_t *brdp);
-static void	stli_ecpeiinit(stlibrd_t *brdp);
-static void	stli_ecpeienable(stlibrd_t *brdp);
-static void	stli_ecpeidisable(stlibrd_t *brdp);
-static void __iomem *stli_ecpeigetmemptr(stlibrd_t *brdp, unsigned long offset, int line);
-static void	stli_ecpeireset(stlibrd_t *brdp);
-static void	stli_ecpmcenable(stlibrd_t *brdp);
-static void	stli_ecpmcdisable(stlibrd_t *brdp);
-static void __iomem *stli_ecpmcgetmemptr(stlibrd_t *brdp, unsigned long offset, int line);
-static void	stli_ecpmcreset(stlibrd_t *brdp);
-static void	stli_ecppciinit(stlibrd_t *brdp);
-static void __iomem *stli_ecppcigetmemptr(stlibrd_t *brdp, unsigned long offset, int line);
-static void	stli_ecppcireset(stlibrd_t *brdp);
-
-static void	stli_onbinit(stlibrd_t *brdp);
-static void	stli_onbenable(stlibrd_t *brdp);
-static void	stli_onbdisable(stlibrd_t *brdp);
-static void __iomem *stli_onbgetmemptr(stlibrd_t *brdp, unsigned long offset, int line);
-static void	stli_onbreset(stlibrd_t *brdp);
-static void	stli_onbeinit(stlibrd_t *brdp);
-static void	stli_onbeenable(stlibrd_t *brdp);
-static void	stli_onbedisable(stlibrd_t *brdp);
-static void __iomem *stli_onbegetmemptr(stlibrd_t *brdp, unsigned long offset, int line);
-static void	stli_onbereset(stlibrd_t *brdp);
-static void	stli_bbyinit(stlibrd_t *brdp);
-static void __iomem *stli_bbygetmemptr(stlibrd_t *brdp, unsigned long offset, int line);
-static void	stli_bbyreset(stlibrd_t *brdp);
-static void	stli_stalinit(stlibrd_t *brdp);
-static void __iomem *stli_stalgetmemptr(stlibrd_t *brdp, unsigned long offset, int line);
-static void	stli_stalreset(stlibrd_t *brdp);
-
-static stliport_t *stli_getport(int brdnr, int panelnr, int portnr);
-
-static int	stli_initecp(stlibrd_t *brdp);
-static int	stli_initonb(stlibrd_t *brdp);
-static int	stli_eisamemprobe(stlibrd_t *brdp);
-static int	stli_initports(stlibrd_t *brdp);
-
-#ifdef	CONFIG_PCI
-static int	stli_initpcibrd(int brdtype, struct pci_dev *devp);
+static int	stli_getportstats(struct stliport *portp, comstats_t __user *cp);
+static int	stli_portcmdstats(struct stliport *portp);
+static int	stli_clrportstats(struct stliport *portp, comstats_t __user *cp);
+static int	stli_getportstruct(struct stliport __user *arg);
+static int	stli_getbrdstruct(struct stlibrd __user *arg);
+static struct stlibrd *stli_allocbrd(void);
+
+static void	stli_ecpinit(struct stlibrd *brdp);
+static void	stli_ecpenable(struct stlibrd *brdp);
+static void	stli_ecpdisable(struct stlibrd *brdp);
+static void __iomem *stli_ecpgetmemptr(struct stlibrd *brdp, unsigned long offset, int line);
+static void	stli_ecpreset(struct stlibrd *brdp);
+static void	stli_ecpintr(struct stlibrd *brdp);
+static void	stli_ecpeiinit(struct stlibrd *brdp);
+static void	stli_ecpeienable(struct stlibrd *brdp);
+static void	stli_ecpeidisable(struct stlibrd *brdp);
+static void __iomem *stli_ecpeigetmemptr(struct stlibrd *brdp, unsigned long offset, int line);
+static void	stli_ecpeireset(struct stlibrd *brdp);
+static void	stli_ecpmcenable(struct stlibrd *brdp);
+static void	stli_ecpmcdisable(struct stlibrd *brdp);
+static void __iomem *stli_ecpmcgetmemptr(struct stlibrd *brdp, unsigned long offset, int line);
+static void	stli_ecpmcreset(struct stlibrd *brdp);
+static void	stli_ecppciinit(struct stlibrd *brdp);
+static void __iomem *stli_ecppcigetmemptr(struct stlibrd *brdp, unsigned long offset, int line);
+static void	stli_ecppcireset(struct stlibrd *brdp);
+
+static void	stli_onbinit(struct stlibrd *brdp);
+static void	stli_onbenable(struct stlibrd *brdp);
+static void	stli_onbdisable(struct stlibrd *brdp);
+static void __iomem *stli_onbgetmemptr(struct stlibrd *brdp, unsigned long offset, int line);
+static void	stli_onbreset(struct stlibrd *brdp);
+static void	stli_onbeinit(struct stlibrd *brdp);
+static void	stli_onbeenable(struct stlibrd *brdp);
+static void	stli_onbedisable(struct stlibrd *brdp);
+static void __iomem *stli_onbegetmemptr(struct stlibrd *brdp, unsigned long offset, int line);
+static void	stli_onbereset(struct stlibrd *brdp);
+static void	stli_bbyinit(struct stlibrd *brdp);
+static void __iomem *stli_bbygetmemptr(struct stlibrd *brdp, unsigned long offset, int line);
+static void	stli_bbyreset(struct stlibrd *brdp);
+static void	stli_stalinit(struct stlibrd *brdp);
+static void __iomem *stli_stalgetmemptr(struct stlibrd *brdp, unsigned long offset, int line);
+static void	stli_stalreset(struct stlibrd *brdp);
+
+static struct stliport *stli_getport(unsigned int brdnr, unsigned int panelnr, unsigned int portnr);
+
+static int	stli_initecp(struct stlibrd *brdp);
+static int	stli_initonb(struct stlibrd *brdp);
+#if STLI_EISAPROBE != 0
+static int	stli_eisamemprobe(struct stlibrd *brdp);
 #endif
+static int	stli_initports(struct stlibrd *brdp);
 
 /*****************************************************************************/
 
@@ -766,136 +728,19 @@ static int	stli_timeron;
 
 static struct class *istallion_class;
 
-/*
- *	Loadable module initialization stuff.
- */
-
-static int __init istallion_module_init(void)
-{
-	stli_init();
-	return 0;
-}
-
-/*****************************************************************************/
-
-static void __exit istallion_module_exit(void)
-{
-	stlibrd_t	*brdp;
-	stliport_t	*portp;
-	int		i, j;
-
-	printk(KERN_INFO "Unloading %s: version %s\n", stli_drvtitle,
-		stli_drvversion);
-
-	/*
-	 *	Free up all allocated resources used by the ports. This includes
-	 *	memory and interrupts.
-	 */
-	if (stli_timeron) {
-		stli_timeron = 0;
-		del_timer_sync(&stli_timerlist);
-	}
-
-	i = tty_unregister_driver(stli_serial);
-	if (i) {
-		printk("STALLION: failed to un-register tty driver, "
-			"errno=%d\n", -i);
-		return;
-	}
-	put_tty_driver(stli_serial);
-	for (i = 0; i < 4; i++)
-		class_device_destroy(istallion_class, MKDEV(STL_SIOMEMMAJOR, i));
-	class_destroy(istallion_class);
-	if ((i = unregister_chrdev(STL_SIOMEMMAJOR, "staliomem")))
-		printk("STALLION: failed to un-register serial memory device, "
-			"errno=%d\n", -i);
-
-	kfree(stli_txcookbuf);
-
-	for (i = 0; (i < stli_nrbrds); i++) {
-		if ((brdp = stli_brds[i]) == NULL)
-			continue;
-		for (j = 0; (j < STL_MAXPORTS); j++) {
-			portp = brdp->ports[j];
-			if (portp != NULL) {
-				if (portp->tty != NULL)
-					tty_hangup(portp->tty);
-				kfree(portp);
-			}
-		}
-
-		iounmap(brdp->membase);
-		if (brdp->iosize > 0)
-			release_region(brdp->iobase, brdp->iosize);
-		kfree(brdp);
-		stli_brds[i] = NULL;
-	}
-}
-
-module_init(istallion_module_init);
-module_exit(istallion_module_exit);
-
-/*****************************************************************************/
-
-/*
- *	Check for any arguments passed in on the module load command line.
- */
-
-static void stli_argbrds(void)
+static void stli_cleanup_ports(struct stlibrd *brdp)
 {
-	stlconf_t conf;
-	stlibrd_t *brdp;
-	int i;
-
-	for (i = stli_nrbrds; i < ARRAY_SIZE(stli_brdsp); i++) {
-		memset(&conf, 0, sizeof(conf));
-		if (stli_parsebrd(&conf, stli_brdsp[i]) == 0)
-			continue;
-		if ((brdp = stli_allocbrd()) == NULL)
-			continue;
-		stli_nrbrds = i + 1;
-		brdp->brdnr = i;
-		brdp->brdtype = conf.brdtype;
-		brdp->iobase = conf.ioaddr1;
-		brdp->memaddr = conf.memaddr;
-		stli_brdinit(brdp);
-	}
-}
-
-/*****************************************************************************/
-
-/*
- *	Convert an ascii string number into an unsigned long.
- */
-
-static unsigned long stli_atol(char *str)
-{
-	unsigned long val;
-	int base, c;
-	char *sp;
-
-	val = 0;
-	sp = str;
-	if ((*sp == '0') && (*(sp+1) == 'x')) {
-		base = 16;
-		sp += 2;
-	} else if (*sp == '0') {
-		base = 8;
-		sp++;
-	} else {
-		base = 10;
-	}
-
-	for (; (*sp != 0); sp++) {
-		c = (*sp > '9') ? (TOLOWER(*sp) - 'a' + 10) : (*sp - '0');
-		if ((c < 0) || (c >= base)) {
-			printk("STALLION: invalid argument %s\n", str);
-			val = 0;
-			break;
+	struct stliport *portp;
+	unsigned int j;
+
+	for (j = 0; j < STL_MAXPORTS; j++) {
+		portp = brdp->ports[j];
+		if (portp != NULL) {
+			if (portp->tty != NULL)
+				tty_hangup(portp->tty);
+			kfree(portp);
 		}
-		val = (val * base) + c;
 	}
-	return(val);
 }
 
 /*****************************************************************************/
@@ -904,16 +749,16 @@ static unsigned long stli_atol(char *str)
  *	Parse the supplied argument string, into the board conf struct.
  */
 
-static int stli_parsebrd(stlconf_t *confp, char **argp)
+static int stli_parsebrd(struct stlconf *confp, char **argp)
 {
+	unsigned int i;
 	char *sp;
-	int i;
 
 	if (argp[0] == NULL || *argp[0] == 0)
 		return 0;
 
 	for (sp = argp[0], i = 0; ((*sp != 0) && (i < 25)); sp++, i++)
-		*sp = TOLOWER(*sp);
+		*sp = tolower(*sp);
 
 	for (i = 0; i < ARRAY_SIZE(stli_brdstr); i++) {
 		if (strcmp(stli_brdstr[i].name, argp[0]) == 0)
@@ -926,9 +771,9 @@ static int stli_parsebrd(stlconf_t *confp, char **argp)
 
 	confp->brdtype = stli_brdstr[i].type;
 	if (argp[1] != NULL && *argp[1] != 0)
-		confp->ioaddr1 = stli_atol(argp[1]);
+		confp->ioaddr1 = simple_strtoul(argp[1], NULL, 0);
 	if (argp[2] !=  NULL && *argp[2] != 0)
-		confp->memaddr = stli_atol(argp[2]);
+		confp->memaddr = simple_strtoul(argp[2], NULL, 0);
 	return(1);
 }
 
@@ -936,10 +781,10 @@ static int stli_parsebrd(stlconf_t *confp, char **argp)
 
 static int stli_open(struct tty_struct *tty, struct file *filp)
 {
-	stlibrd_t *brdp;
-	stliport_t *portp;
-	unsigned int minordev;
-	int brdnr, portnr, rc;
+	struct stlibrd *brdp;
+	struct stliport *portp;
+	unsigned int minordev, brdnr, portnr;
+	int rc;
 
 	minordev = tty->index;
 	brdnr = MINOR2BRD(minordev);
@@ -951,7 +796,7 @@ static int stli_open(struct tty_struct *tty, struct file *filp)
 	if ((brdp->state & BST_STARTED) == 0)
 		return -ENODEV;
 	portnr = MINOR2PORT(minordev);
-	if ((portnr < 0) || (portnr > brdp->nrports))
+	if (portnr > brdp->nrports)
 		return -ENODEV;
 
 	portp = brdp->ports[portnr];
@@ -1031,8 +876,8 @@ static int stli_open(struct tty_struct *tty, struct file *filp)
 
 static void stli_close(struct tty_struct *tty, struct file *filp)
 {
-	stlibrd_t *brdp;
-	stliport_t *portp;
+	struct stlibrd *brdp;
+	struct stliport *portp;
 	unsigned long flags;
 
 	portp = tty->driver_data;
@@ -1109,7 +954,7 @@ static void stli_close(struct tty_struct *tty, struct file *filp)
  *	this still all happens pretty quickly.
  */
 
-static int stli_initopen(stlibrd_t *brdp, stliport_t *portp)
+static int stli_initopen(struct stlibrd *brdp, struct stliport *portp)
 {
 	struct tty_struct *tty;
 	asynotify_t nt;
@@ -1157,7 +1002,7 @@ static int stli_initopen(stlibrd_t *brdp, stliport_t *portp)
  *	to overlap.
  */
 
-static int stli_rawopen(stlibrd_t *brdp, stliport_t *portp, unsigned long arg, int wait)
+static int stli_rawopen(struct stlibrd *brdp, struct stliport *portp, unsigned long arg, int wait)
 {
 	cdkhdr_t __iomem *hdrp;
 	cdkctrl_t __iomem *cp;
@@ -1228,7 +1073,7 @@ static int stli_rawopen(stlibrd_t *brdp, stliport_t *portp, unsigned long arg, i
  *	wait is true then must have user context (to sleep).
  */
 
-static int stli_rawclose(stlibrd_t *brdp, stliport_t *portp, unsigned long arg, int wait)
+static int stli_rawclose(struct stlibrd *brdp, struct stliport *portp, unsigned long arg, int wait)
 {
 	cdkhdr_t __iomem *hdrp;
 	cdkctrl_t __iomem *cp;
@@ -1292,7 +1137,7 @@ static int stli_rawclose(stlibrd_t *brdp, stliport_t *portp, unsigned long arg,
  *	to complete (as opposed to initiating the command then returning).
  */
 
-static int stli_cmdwait(stlibrd_t *brdp, stliport_t *portp, unsigned long cmd, void *arg, int size, int copyback)
+static int stli_cmdwait(struct stlibrd *brdp, struct stliport *portp, unsigned long cmd, void *arg, int size, int copyback)
 {
 	wait_event_interruptible(portp->raw_wait,
 			!test_bit(ST_CMDING, &portp->state));
@@ -1318,16 +1163,16 @@ static int stli_cmdwait(stlibrd_t *brdp, stliport_t *portp, unsigned long cmd, v
  *	waiting for the command to complete - so must have user context.
  */
 
-static int stli_setport(stliport_t *portp)
+static int stli_setport(struct stliport *portp)
 {
-	stlibrd_t *brdp;
+	struct stlibrd *brdp;
 	asyport_t aport;
 
 	if (portp == NULL)
 		return -ENODEV;
 	if (portp->tty == NULL)
 		return -ENODEV;
-	if (portp->brdnr < 0 && portp->brdnr >= stli_nrbrds)
+	if (portp->brdnr >= stli_nrbrds)
 		return -ENODEV;
 	brdp = stli_brds[portp->brdnr];
 	if (brdp == NULL)
@@ -1344,7 +1189,7 @@ static int stli_setport(stliport_t *portp)
  *	maybe because if we are clocal then we don't need to wait...
  */
 
-static int stli_waitcarrier(stlibrd_t *brdp, stliport_t *portp, struct file *filp)
+static int stli_waitcarrier(struct stlibrd *brdp, struct stliport *portp, struct file *filp)
 {
 	unsigned long flags;
 	int rc, doclocal;
@@ -1409,8 +1254,8 @@ static int stli_write(struct tty_struct *tty, const unsigned char *buf, int coun
 	unsigned char __iomem *bits;
 	unsigned char __iomem *shbuf;
 	unsigned char *chbuf;
-	stliport_t *portp;
-	stlibrd_t *brdp;
+	struct stliport *portp;
+	struct stlibrd *brdp;
 	unsigned int len, stlen, head, tail, size;
 	unsigned long flags;
 
@@ -1419,7 +1264,7 @@ static int stli_write(struct tty_struct *tty, const unsigned char *buf, int coun
 	portp = tty->driver_data;
 	if (portp == NULL)
 		return 0;
-	if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds))
+	if (portp->brdnr >= stli_nrbrds)
 		return 0;
 	brdp = stli_brds[portp->brdnr];
 	if (brdp == NULL)
@@ -1445,12 +1290,12 @@ static int stli_write(struct tty_struct *tty, const unsigned char *buf, int coun
 		stlen = len;
 	}
 
-	len = MIN(len, count);
+	len = min(len, (unsigned int)count);
 	count = 0;
 	shbuf = (char __iomem *) EBRDGETMEMPTR(brdp, portp->txoffset);
 
 	while (len > 0) {
-		stlen = MIN(len, stlen);
+		stlen = min(len, stlen);
 		memcpy_toio(shbuf + head, chbuf, stlen);
 		chbuf += stlen;
 		len -= stlen;
@@ -1516,8 +1361,8 @@ static void stli_flushchars(struct tty_struct *tty)
 	unsigned char __iomem *bits;
 	cdkasy_t __iomem *ap;
 	struct tty_struct *cooktty;
-	stliport_t *portp;
-	stlibrd_t *brdp;
+	struct stliport *portp;
+	struct stlibrd *brdp;
 	unsigned int len, stlen, head, tail, size, count, cooksize;
 	unsigned char *buf;
 	unsigned char __iomem *shbuf;
@@ -1541,7 +1386,7 @@ static void stli_flushchars(struct tty_struct *tty)
 	portp = tty->driver_data;
 	if (portp == NULL)
 		return;
-	if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds))
+	if (portp->brdnr >= stli_nrbrds)
 		return;
 	brdp = stli_brds[portp->brdnr];
 	if (brdp == NULL)
@@ -1564,13 +1409,13 @@ static void stli_flushchars(struct tty_struct *tty)
 		stlen = len;
 	}
 
-	len = MIN(len, cooksize);
+	len = min(len, cooksize);
 	count = 0;
 	shbuf = EBRDGETMEMPTR(brdp, portp->txoffset);
 	buf = stli_txcookbuf;
 
 	while (len > 0) {
-		stlen = MIN(len, stlen);
+		stlen = min(len, stlen);
 		memcpy_toio(shbuf + head, buf, stlen);
 		buf += stlen;
 		len -= stlen;
@@ -1604,8 +1449,8 @@ static void stli_flushchars(struct tty_struct *tty)
 static int stli_writeroom(struct tty_struct *tty)
 {
 	cdkasyrq_t __iomem *rp;
-	stliport_t *portp;
-	stlibrd_t *brdp;
+	struct stliport *portp;
+	struct stlibrd *brdp;
 	unsigned int head, tail, len;
 	unsigned long flags;
 
@@ -1619,7 +1464,7 @@ static int stli_writeroom(struct tty_struct *tty)
 	portp = tty->driver_data;
 	if (portp == NULL)
 		return 0;
-	if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds))
+	if (portp->brdnr >= stli_nrbrds)
 		return 0;
 	brdp = stli_brds[portp->brdnr];
 	if (brdp == NULL)
@@ -1657,8 +1502,8 @@ static int stli_writeroom(struct tty_struct *tty)
 static int stli_charsinbuffer(struct tty_struct *tty)
 {
 	cdkasyrq_t __iomem *rp;
-	stliport_t *portp;
-	stlibrd_t *brdp;
+	struct stliport *portp;
+	struct stlibrd *brdp;
 	unsigned int head, tail, len;
 	unsigned long flags;
 
@@ -1667,7 +1512,7 @@ static int stli_charsinbuffer(struct tty_struct *tty)
 	portp = tty->driver_data;
 	if (portp == NULL)
 		return 0;
-	if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds))
+	if (portp->brdnr >= stli_nrbrds)
 		return 0;
 	brdp = stli_brds[portp->brdnr];
 	if (brdp == NULL)
@@ -1695,10 +1540,10 @@ static int stli_charsinbuffer(struct tty_struct *tty)
  *	Generate the serial struct info.
  */
 
-static int stli_getserial(stliport_t *portp, struct serial_struct __user *sp)
+static int stli_getserial(struct stliport *portp, struct serial_struct __user *sp)
 {
 	struct serial_struct sio;
-	stlibrd_t *brdp;
+	struct stlibrd *brdp;
 
 	memset(&sio, 0, sizeof(struct serial_struct));
 	sio.type = PORT_UNKNOWN;
@@ -1728,7 +1573,7 @@ static int stli_getserial(stliport_t *portp, struct serial_struct __user *sp)
  *	just quietly ignore any requests to change irq, etc.
  */
 
-static int stli_setserial(stliport_t *portp, struct serial_struct __user *sp)
+static int stli_setserial(struct stliport *portp, struct serial_struct __user *sp)
 {
 	struct serial_struct sio;
 	int rc;
@@ -1759,13 +1604,13 @@ static int stli_setserial(stliport_t *portp, struct serial_struct __user *sp)
 
 static int stli_tiocmget(struct tty_struct *tty, struct file *file)
 {
-	stliport_t *portp = tty->driver_data;
-	stlibrd_t *brdp;
+	struct stliport *portp = tty->driver_data;
+	struct stlibrd *brdp;
 	int rc;
 
 	if (portp == NULL)
 		return -ENODEV;
-	if (portp->brdnr < 0 || portp->brdnr >= stli_nrbrds)
+	if (portp->brdnr >= stli_nrbrds)
 		return 0;
 	brdp = stli_brds[portp->brdnr];
 	if (brdp == NULL)
@@ -1783,13 +1628,13 @@ static int stli_tiocmget(struct tty_struct *tty, struct file *file)
 static int stli_tiocmset(struct tty_struct *tty, struct file *file,
 			 unsigned int set, unsigned int clear)
 {
-	stliport_t *portp = tty->driver_data;
-	stlibrd_t *brdp;
+	struct stliport *portp = tty->driver_data;
+	struct stlibrd *brdp;
 	int rts = -1, dtr = -1;
 
 	if (portp == NULL)
 		return -ENODEV;
-	if (portp->brdnr < 0 || portp->brdnr >= stli_nrbrds)
+	if (portp->brdnr >= stli_nrbrds)
 		return 0;
 	brdp = stli_brds[portp->brdnr];
 	if (brdp == NULL)
@@ -1814,8 +1659,8 @@ static int stli_tiocmset(struct tty_struct *tty, struct file *file,
 
 static int stli_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg)
 {
-	stliport_t *portp;
-	stlibrd_t *brdp;
+	struct stliport *portp;
+	struct stlibrd *brdp;
 	unsigned int ival;
 	int rc;
 	void __user *argp = (void __user *)arg;
@@ -1823,7 +1668,7 @@ static int stli_ioctl(struct tty_struct *tty, struct file *file, unsigned int cm
 	portp = tty->driver_data;
 	if (portp == NULL)
 		return -ENODEV;
-	if (portp->brdnr < 0 || portp->brdnr >= stli_nrbrds)
+	if (portp->brdnr >= stli_nrbrds)
 		return 0;
 	brdp = stli_brds[portp->brdnr];
 	if (brdp == NULL)
@@ -1889,11 +1734,11 @@ static int stli_ioctl(struct tty_struct *tty, struct file *file, unsigned int cm
  *	Looks like it is true for the current ttys implementation..!!
  */
 
-static void stli_settermios(struct tty_struct *tty, struct termios *old)
+static void stli_settermios(struct tty_struct *tty, struct ktermios *old)
 {
-	stliport_t *portp;
-	stlibrd_t *brdp;
-	struct termios *tiosp;
+	struct stliport *portp;
+	struct stlibrd *brdp;
+	struct ktermios *tiosp;
 	asyport_t aport;
 
 	if (tty == NULL)
@@ -1901,7 +1746,7 @@ static void stli_settermios(struct tty_struct *tty, struct termios *old)
 	portp = tty->driver_data;
 	if (portp == NULL)
 		return;
-	if (portp->brdnr < 0 || portp->brdnr >= stli_nrbrds)
+	if (portp->brdnr >= stli_nrbrds)
 		return;
 	brdp = stli_brds[portp->brdnr];
 	if (brdp == NULL)
@@ -1937,7 +1782,7 @@ static void stli_settermios(struct tty_struct *tty, struct termios *old)
 
 static void stli_throttle(struct tty_struct *tty)
 {
-	stliport_t	*portp = tty->driver_data;
+	struct stliport	*portp = tty->driver_data;
 	if (portp == NULL)
 		return;
 	set_bit(ST_RXSTOP, &portp->state);
@@ -1953,7 +1798,7 @@ static void stli_throttle(struct tty_struct *tty)
 
 static void stli_unthrottle(struct tty_struct *tty)
 {
-	stliport_t	*portp = tty->driver_data;
+	struct stliport	*portp = tty->driver_data;
 	if (portp == NULL)
 		return;
 	clear_bit(ST_RXSTOP, &portp->state);
@@ -1992,7 +1837,7 @@ static void stli_start(struct tty_struct *tty)
 
 static void stli_dohangup(struct work_struct *ugly_api)
 {
-	stliport_t *portp = container_of(ugly_api, stliport_t, tqhangup);
+	struct stliport *portp = container_of(ugly_api, struct stliport, tqhangup);
 	if (portp->tty != NULL) {
 		tty_hangup(portp->tty);
 	}
@@ -2009,14 +1854,14 @@ static void stli_dohangup(struct work_struct *ugly_api)
 
 static void stli_hangup(struct tty_struct *tty)
 {
-	stliport_t *portp;
-	stlibrd_t *brdp;
+	struct stliport *portp;
+	struct stlibrd *brdp;
 	unsigned long flags;
 
 	portp = tty->driver_data;
 	if (portp == NULL)
 		return;
-	if (portp->brdnr < 0 || portp->brdnr >= stli_nrbrds)
+	if (portp->brdnr >= stli_nrbrds)
 		return;
 	brdp = stli_brds[portp->brdnr];
 	if (brdp == NULL)
@@ -2062,14 +1907,14 @@ static void stli_hangup(struct tty_struct *tty)
 
 static void stli_flushbuffer(struct tty_struct *tty)
 {
-	stliport_t *portp;
-	stlibrd_t *brdp;
+	struct stliport *portp;
+	struct stlibrd *brdp;
 	unsigned long ftype, flags;
 
 	portp = tty->driver_data;
 	if (portp == NULL)
 		return;
-	if (portp->brdnr < 0 || portp->brdnr >= stli_nrbrds)
+	if (portp->brdnr >= stli_nrbrds)
 		return;
 	brdp = stli_brds[portp->brdnr];
 	if (brdp == NULL)
@@ -2099,14 +1944,14 @@ static void stli_flushbuffer(struct tty_struct *tty)
 
 static void stli_breakctl(struct tty_struct *tty, int state)
 {
-	stlibrd_t	*brdp;
-	stliport_t	*portp;
+	struct stlibrd	*brdp;
+	struct stliport	*portp;
 	long		arg;
 
 	portp = tty->driver_data;
 	if (portp == NULL)
 		return;
-	if (portp->brdnr < 0 || portp->brdnr >= stli_nrbrds)
+	if (portp->brdnr >= stli_nrbrds)
 		return;
 	brdp = stli_brds[portp->brdnr];
 	if (brdp == NULL)
@@ -2120,7 +1965,7 @@ static void stli_breakctl(struct tty_struct *tty, int state)
 
 static void stli_waituntilsent(struct tty_struct *tty, int timeout)
 {
-	stliport_t *portp;
+	struct stliport *portp;
 	unsigned long tend;
 
 	if (tty == NULL)
@@ -2146,14 +1991,14 @@ static void stli_waituntilsent(struct tty_struct *tty, int timeout)
 
 static void stli_sendxchar(struct tty_struct *tty, char ch)
 {
-	stlibrd_t	*brdp;
-	stliport_t	*portp;
+	struct stlibrd	*brdp;
+	struct stliport	*portp;
 	asyctrl_t	actrl;
 
 	portp = tty->driver_data;
 	if (portp == NULL)
 		return;
-	if (portp->brdnr < 0 || portp->brdnr >= stli_nrbrds)
+	if (portp->brdnr >= stli_nrbrds)
 		return;
 	brdp = stli_brds[portp->brdnr];
 	if (brdp == NULL)
@@ -2181,7 +2026,7 @@ static void stli_sendxchar(struct tty_struct *tty, char ch)
  *	short then padded with spaces).
  */
 
-static int stli_portinfo(stlibrd_t *brdp, stliport_t *portp, int portnr, char *pos)
+static int stli_portinfo(struct stlibrd *brdp, struct stliport *portp, int portnr, char *pos)
 {
 	char *sp, *uart;
 	int rc, cnt;
@@ -2244,9 +2089,9 @@ static int stli_portinfo(stlibrd_t *brdp, stliport_t *portp, int portnr, char *p
 
 static int stli_readproc(char *page, char **start, off_t off, int count, int *eof, void *data)
 {
-	stlibrd_t *brdp;
-	stliport_t *portp;
-	int brdnr, portnr, totalport;
+	struct stlibrd *brdp;
+	struct stliport *portp;
+	unsigned int brdnr, portnr, totalport;
 	int curoff, maxoff;
 	char *pos;
 
@@ -2316,7 +2161,7 @@ stli_readdone:
  *	entry point)
  */
 
-static void __stli_sendcmd(stlibrd_t *brdp, stliport_t *portp, unsigned long cmd, void *arg, int size, int copyback)
+static void __stli_sendcmd(struct stlibrd *brdp, struct stliport *portp, unsigned long cmd, void *arg, int size, int copyback)
 {
 	cdkhdr_t __iomem *hdrp;
 	cdkctrl_t __iomem *cp;
@@ -2352,7 +2197,7 @@ static void __stli_sendcmd(stlibrd_t *brdp, stliport_t *portp, unsigned long cmd
 	spin_unlock_irqrestore(&brd_lock, flags);
 }
 
-static void stli_sendcmd(stlibrd_t *brdp, stliport_t *portp, unsigned long cmd, void *arg, int size, int copyback)
+static void stli_sendcmd(struct stlibrd *brdp, struct stliport *portp, unsigned long cmd, void *arg, int size, int copyback)
 {
 	unsigned long		flags;
 
@@ -2371,7 +2216,7 @@ static void stli_sendcmd(stlibrd_t *brdp, stliport_t *portp, unsigned long cmd,
  *	more chars to unload.
  */
 
-static void stli_read(stlibrd_t *brdp, stliport_t *portp)
+static void stli_read(struct stlibrd *brdp, struct stliport *portp)
 {
 	cdkasyrq_t __iomem *rp;
 	char __iomem *shbuf;
@@ -2406,7 +2251,7 @@ static void stli_read(stlibrd_t *brdp, stliport_t *portp)
 	while (len > 0) {
 		unsigned char *cptr;
 
-		stlen = MIN(len, stlen);
+		stlen = min(len, stlen);
 		tty_prepare_flip_string(tty, &cptr, stlen);
 		memcpy_fromio(cptr, shbuf + tail, stlen);
 		len -= stlen;
@@ -2433,7 +2278,7 @@ static void stli_read(stlibrd_t *brdp, stliport_t *portp)
  *	difficult to deal with them here.
  */
 
-static void stli_dodelaycmd(stliport_t *portp, cdkctrl_t __iomem *cp)
+static void stli_dodelaycmd(struct stliport *portp, cdkctrl_t __iomem *cp)
 {
 	int cmd;
 
@@ -2481,7 +2326,7 @@ static void stli_dodelaycmd(stliport_t *portp, cdkctrl_t __iomem *cp)
  *	then port is still busy, otherwise no longer busy.
  */
 
-static int stli_hostcmd(stlibrd_t *brdp, stliport_t *portp)
+static int stli_hostcmd(struct stlibrd *brdp, struct stliport *portp)
 {
 	cdkasy_t __iomem *ap;
 	cdkctrl_t __iomem *cp;
@@ -2628,9 +2473,9 @@ static int stli_hostcmd(stlibrd_t *brdp, stliport_t *portp)
  *	at the cdk header structure.
  */
 
-static void stli_brdpoll(stlibrd_t *brdp, cdkhdr_t __iomem *hdrp)
+static void stli_brdpoll(struct stlibrd *brdp, cdkhdr_t __iomem *hdrp)
 {
-	stliport_t *portp;
+	struct stliport *portp;
 	unsigned char hostbits[(STL_MAXCHANS / 8) + 1];
 	unsigned char slavebits[(STL_MAXCHANS / 8) + 1];
 	unsigned char __iomem *slavep;
@@ -2697,11 +2542,10 @@ static void stli_brdpoll(stlibrd_t *brdp, cdkhdr_t __iomem *hdrp)
 static void stli_poll(unsigned long arg)
 {
 	cdkhdr_t __iomem *hdrp;
-	stlibrd_t *brdp;
-	int brdnr;
+	struct stlibrd *brdp;
+	unsigned int brdnr;
 
-	stli_timerlist.expires = STLI_TIMEOUT;
-	add_timer(&stli_timerlist);
+	mod_timer(&stli_timerlist, STLI_TIMEOUT);
 
 /*
  *	Check each board and do any servicing required.
@@ -2730,7 +2574,7 @@ static void stli_poll(unsigned long arg)
  *	the slave.
  */
 
-static void stli_mkasyport(stliport_t *portp, asyport_t *pp, struct termios *tiosp)
+static void stli_mkasyport(struct stliport *portp, asyport_t *pp, struct ktermios *tiosp)
 {
 	memset(pp, 0, sizeof(asyport_t));
 
@@ -2879,13 +2723,13 @@ static long stli_mktiocm(unsigned long sigvalue)
  *	we need to do here is set up the appropriate per port data structures.
  */
 
-static int stli_initports(stlibrd_t *brdp)
+static int stli_initports(struct stlibrd *brdp)
 {
-	stliport_t	*portp;
-	int		i, panelnr, panelport;
+	struct stliport	*portp;
+	unsigned int i, panelnr, panelport;
 
 	for (i = 0, panelnr = 0, panelport = 0; (i < brdp->nrports); i++) {
-		portp = kzalloc(sizeof(stliport_t), GFP_KERNEL);
+		portp = kzalloc(sizeof(struct stliport), GFP_KERNEL);
 		if (!portp) {
 			printk("STALLION: failed to allocate port structure\n");
 			continue;
@@ -2919,7 +2763,7 @@ static int stli_initports(stlibrd_t *brdp)
  *	All the following routines are board specific hardware operations.
  */
 
-static void stli_ecpinit(stlibrd_t *brdp)
+static void stli_ecpinit(struct stlibrd *brdp)
 {
 	unsigned long	memconf;
 
@@ -2934,21 +2778,21 @@ static void stli_ecpinit(stlibrd_t *brdp)
 
 /*****************************************************************************/
 
-static void stli_ecpenable(stlibrd_t *brdp)
+static void stli_ecpenable(struct stlibrd *brdp)
 {	
 	outb(ECP_ATENABLE, (brdp->iobase + ECP_ATCONFR));
 }
 
 /*****************************************************************************/
 
-static void stli_ecpdisable(stlibrd_t *brdp)
+static void stli_ecpdisable(struct stlibrd *brdp)
 {	
 	outb(ECP_ATDISABLE, (brdp->iobase + ECP_ATCONFR));
 }
 
 /*****************************************************************************/
 
-static void __iomem *stli_ecpgetmemptr(stlibrd_t *brdp, unsigned long offset, int line)
+static void __iomem *stli_ecpgetmemptr(struct stlibrd *brdp, unsigned long offset, int line)
 {	
 	void __iomem *ptr;
 	unsigned char val;
@@ -2969,7 +2813,7 @@ static void __iomem *stli_ecpgetmemptr(stlibrd_t *brdp, unsigned long offset, in
 
 /*****************************************************************************/
 
-static void stli_ecpreset(stlibrd_t *brdp)
+static void stli_ecpreset(struct stlibrd *brdp)
 {	
 	outb(ECP_ATSTOP, (brdp->iobase + ECP_ATCONFR));
 	udelay(10);
@@ -2979,7 +2823,7 @@ static void stli_ecpreset(stlibrd_t *brdp)
 
 /*****************************************************************************/
 
-static void stli_ecpintr(stlibrd_t *brdp)
+static void stli_ecpintr(struct stlibrd *brdp)
 {	
 	outb(0x1, brdp->iobase);
 }
@@ -2990,7 +2834,7 @@ static void stli_ecpintr(stlibrd_t *brdp)
  *	The following set of functions act on ECP EISA boards.
  */
 
-static void stli_ecpeiinit(stlibrd_t *brdp)
+static void stli_ecpeiinit(struct stlibrd *brdp)
 {
 	unsigned long	memconf;
 
@@ -3008,21 +2852,21 @@ static void stli_ecpeiinit(stlibrd_t *brdp)
 
 /*****************************************************************************/
 
-static void stli_ecpeienable(stlibrd_t *brdp)
+static void stli_ecpeienable(struct stlibrd *brdp)
 {	
 	outb(ECP_EIENABLE, (brdp->iobase + ECP_EICONFR));
 }
 
 /*****************************************************************************/
 
-static void stli_ecpeidisable(stlibrd_t *brdp)
+static void stli_ecpeidisable(struct stlibrd *brdp)
 {	
 	outb(ECP_EIDISABLE, (brdp->iobase + ECP_EICONFR));
 }
 
 /*****************************************************************************/
 
-static void __iomem *stli_ecpeigetmemptr(stlibrd_t *brdp, unsigned long offset, int line)
+static void __iomem *stli_ecpeigetmemptr(struct stlibrd *brdp, unsigned long offset, int line)
 {	
 	void __iomem *ptr;
 	unsigned char	val;
@@ -3046,7 +2890,7 @@ static void __iomem *stli_ecpeigetmemptr(stlibrd_t *brdp, unsigned long offset,
 
 /*****************************************************************************/
 
-static void stli_ecpeireset(stlibrd_t *brdp)
+static void stli_ecpeireset(struct stlibrd *brdp)
 {	
 	outb(ECP_EISTOP, (brdp->iobase + ECP_EICONFR));
 	udelay(10);
@@ -3060,21 +2904,21 @@ static void stli_ecpeireset(stlibrd_t *brdp)
  *	The following set of functions act on ECP MCA boards.
  */
 
-static void stli_ecpmcenable(stlibrd_t *brdp)
+static void stli_ecpmcenable(struct stlibrd *brdp)
 {	
 	outb(ECP_MCENABLE, (brdp->iobase + ECP_MCCONFR));
 }
 
 /*****************************************************************************/
 
-static void stli_ecpmcdisable(stlibrd_t *brdp)
+static void stli_ecpmcdisable(struct stlibrd *brdp)
 {	
 	outb(ECP_MCDISABLE, (brdp->iobase + ECP_MCCONFR));
 }
 
 /*****************************************************************************/
 
-static void __iomem *stli_ecpmcgetmemptr(stlibrd_t *brdp, unsigned long offset, int line)
+static void __iomem *stli_ecpmcgetmemptr(struct stlibrd *brdp, unsigned long offset, int line)
 {	
 	void __iomem *ptr;
 	unsigned char val;
@@ -3095,7 +2939,7 @@ static void __iomem *stli_ecpmcgetmemptr(stlibrd_t *brdp, unsigned long offset,
 
 /*****************************************************************************/
 
-static void stli_ecpmcreset(stlibrd_t *brdp)
+static void stli_ecpmcreset(struct stlibrd *brdp)
 {	
 	outb(ECP_MCSTOP, (brdp->iobase + ECP_MCCONFR));
 	udelay(10);
@@ -3109,7 +2953,7 @@ static void stli_ecpmcreset(stlibrd_t *brdp)
  *	The following set of functions act on ECP PCI boards.
  */
 
-static void stli_ecppciinit(stlibrd_t *brdp)
+static void stli_ecppciinit(struct stlibrd *brdp)
 {
 	outb(ECP_PCISTOP, (brdp->iobase + ECP_PCICONFR));
 	udelay(10);
@@ -3119,7 +2963,7 @@ static void stli_ecppciinit(stlibrd_t *brdp)
 
 /*****************************************************************************/
 
-static void __iomem *stli_ecppcigetmemptr(stlibrd_t *brdp, unsigned long offset, int line)
+static void __iomem *stli_ecppcigetmemptr(struct stlibrd *brdp, unsigned long offset, int line)
 {	
 	void __iomem *ptr;
 	unsigned char	val;
@@ -3140,7 +2984,7 @@ static void __iomem *stli_ecppcigetmemptr(stlibrd_t *brdp, unsigned long offset,
 
 /*****************************************************************************/
 
-static void stli_ecppcireset(stlibrd_t *brdp)
+static void stli_ecppcireset(struct stlibrd *brdp)
 {	
 	outb(ECP_PCISTOP, (brdp->iobase + ECP_PCICONFR));
 	udelay(10);
@@ -3154,7 +2998,7 @@ static void stli_ecppcireset(stlibrd_t *brdp)
  *	The following routines act on ONboards.
  */
 
-static void stli_onbinit(stlibrd_t *brdp)
+static void stli_onbinit(struct stlibrd *brdp)
 {
 	unsigned long	memconf;
 
@@ -3171,21 +3015,21 @@ static void stli_onbinit(stlibrd_t *brdp)
 
 /*****************************************************************************/
 
-static void stli_onbenable(stlibrd_t *brdp)
+static void stli_onbenable(struct stlibrd *brdp)
 {	
 	outb((brdp->enabval | ONB_ATENABLE), (brdp->iobase + ONB_ATCONFR));
 }
 
 /*****************************************************************************/
 
-static void stli_onbdisable(stlibrd_t *brdp)
+static void stli_onbdisable(struct stlibrd *brdp)
 {	
 	outb((brdp->enabval | ONB_ATDISABLE), (brdp->iobase + ONB_ATCONFR));
 }
 
 /*****************************************************************************/
 
-static void __iomem *stli_onbgetmemptr(stlibrd_t *brdp, unsigned long offset, int line)
+static void __iomem *stli_onbgetmemptr(struct stlibrd *brdp, unsigned long offset, int line)
 {	
 	void __iomem *ptr;
 
@@ -3202,7 +3046,7 @@ static void __iomem *stli_onbgetmemptr(stlibrd_t *brdp, unsigned long offset, in
 
 /*****************************************************************************/
 
-static void stli_onbreset(stlibrd_t *brdp)
+static void stli_onbreset(struct stlibrd *brdp)
 {	
 	outb(ONB_ATSTOP, (brdp->iobase + ONB_ATCONFR));
 	udelay(10);
@@ -3216,7 +3060,7 @@ static void stli_onbreset(stlibrd_t *brdp)
  *	The following routines act on ONboard EISA.
  */
 
-static void stli_onbeinit(stlibrd_t *brdp)
+static void stli_onbeinit(struct stlibrd *brdp)
 {
 	unsigned long	memconf;
 
@@ -3236,21 +3080,21 @@ static void stli_onbeinit(stlibrd_t *brdp)
 
 /*****************************************************************************/
 
-static void stli_onbeenable(stlibrd_t *brdp)
+static void stli_onbeenable(struct stlibrd *brdp)
 {	
 	outb(ONB_EIENABLE, (brdp->iobase + ONB_EICONFR));
 }
 
 /*****************************************************************************/
 
-static void stli_onbedisable(stlibrd_t *brdp)
+static void stli_onbedisable(struct stlibrd *brdp)
 {	
 	outb(ONB_EIDISABLE, (brdp->iobase + ONB_EICONFR));
 }
 
 /*****************************************************************************/
 
-static void __iomem *stli_onbegetmemptr(stlibrd_t *brdp, unsigned long offset, int line)
+static void __iomem *stli_onbegetmemptr(struct stlibrd *brdp, unsigned long offset, int line)
 {	
 	void __iomem *ptr;
 	unsigned char val;
@@ -3274,7 +3118,7 @@ static void __iomem *stli_onbegetmemptr(stlibrd_t *brdp, unsigned long offset, i
 
 /*****************************************************************************/
 
-static void stli_onbereset(stlibrd_t *brdp)
+static void stli_onbereset(struct stlibrd *brdp)
 {	
 	outb(ONB_EISTOP, (brdp->iobase + ONB_EICONFR));
 	udelay(10);
@@ -3288,7 +3132,7 @@ static void stli_onbereset(stlibrd_t *brdp)
  *	The following routines act on Brumby boards.
  */
 
-static void stli_bbyinit(stlibrd_t *brdp)
+static void stli_bbyinit(struct stlibrd *brdp)
 {
 	outb(BBY_ATSTOP, (brdp->iobase + BBY_ATCONFR));
 	udelay(10);
@@ -3300,7 +3144,7 @@ static void stli_bbyinit(stlibrd_t *brdp)
 
 /*****************************************************************************/
 
-static void __iomem *stli_bbygetmemptr(stlibrd_t *brdp, unsigned long offset, int line)
+static void __iomem *stli_bbygetmemptr(struct stlibrd *brdp, unsigned long offset, int line)
 {	
 	void __iomem *ptr;
 	unsigned char val;
@@ -3315,7 +3159,7 @@ static void __iomem *stli_bbygetmemptr(stlibrd_t *brdp, unsigned long offset, in
 
 /*****************************************************************************/
 
-static void stli_bbyreset(stlibrd_t *brdp)
+static void stli_bbyreset(struct stlibrd *brdp)
 {	
 	outb(BBY_ATSTOP, (brdp->iobase + BBY_ATCONFR));
 	udelay(10);
@@ -3329,7 +3173,7 @@ static void stli_bbyreset(stlibrd_t *brdp)
  *	The following routines act on original old Stallion boards.
  */
 
-static void stli_stalinit(stlibrd_t *brdp)
+static void stli_stalinit(struct stlibrd *brdp)
 {
 	outb(0x1, brdp->iobase);
 	mdelay(1000);
@@ -3337,7 +3181,7 @@ static void stli_stalinit(stlibrd_t *brdp)
 
 /*****************************************************************************/
 
-static void __iomem *stli_stalgetmemptr(stlibrd_t *brdp, unsigned long offset, int line)
+static void __iomem *stli_stalgetmemptr(struct stlibrd *brdp, unsigned long offset, int line)
 {	
 	BUG_ON(offset > brdp->memsize);
 	return brdp->membase + (offset % STAL_PAGESIZE);
@@ -3345,7 +3189,7 @@ static void __iomem *stli_stalgetmemptr(stlibrd_t *brdp, unsigned long offset, i
 
 /*****************************************************************************/
 
-static void stli_stalreset(stlibrd_t *brdp)
+static void stli_stalreset(struct stlibrd *brdp)
 {	
 	u32 __iomem *vecp;
 
@@ -3362,21 +3206,22 @@ static void stli_stalreset(stlibrd_t *brdp)
  *	board types.
  */
 
-static int stli_initecp(stlibrd_t *brdp)
+static int stli_initecp(struct stlibrd *brdp)
 {
 	cdkecpsig_t sig;
 	cdkecpsig_t __iomem *sigsp;
 	unsigned int status, nxtid;
 	char *name;
-	int panelnr, nrports;
+	int retval, panelnr, nrports;
 
-	if (!request_region(brdp->iobase, brdp->iosize, "istallion"))
-		return -EIO;
-	
-	if ((brdp->iobase == 0) || (brdp->memaddr == 0))
-	{
-		release_region(brdp->iobase, brdp->iosize);
-		return -ENODEV;
+	if ((brdp->iobase == 0) || (brdp->memaddr == 0)) {
+		retval = -ENODEV;
+		goto err;
+	}
+
+	if (!request_region(brdp->iobase, brdp->iosize, "istallion")) {
+		retval = -EIO;
+		goto err;
 	}
 
 	brdp->iosize = ECP_IOSIZE;
@@ -3388,7 +3233,6 @@ static int stli_initecp(stlibrd_t *brdp)
  */
 	switch (brdp->brdtype) {
 	case BRD_ECP:
-		brdp->membase = (void *) brdp->memaddr;
 		brdp->memsize = ECP_MEMSIZE;
 		brdp->pagesize = ECP_ATPAGESIZE;
 		brdp->init = stli_ecpinit;
@@ -3402,7 +3246,6 @@ static int stli_initecp(stlibrd_t *brdp)
 		break;
 
 	case BRD_ECPE:
-		brdp->membase = (void *) brdp->memaddr;
 		brdp->memsize = ECP_MEMSIZE;
 		brdp->pagesize = ECP_EIPAGESIZE;
 		brdp->init = stli_ecpeiinit;
@@ -3416,7 +3259,6 @@ static int stli_initecp(stlibrd_t *brdp)
 		break;
 
 	case BRD_ECPMC:
-		brdp->membase = (void *) brdp->memaddr;
 		brdp->memsize = ECP_MEMSIZE;
 		brdp->pagesize = ECP_MCPAGESIZE;
 		brdp->init = NULL;
@@ -3430,7 +3272,6 @@ static int stli_initecp(stlibrd_t *brdp)
 		break;
 
 	case BRD_ECPPCI:
-		brdp->membase = (void *) brdp->memaddr;
 		brdp->memsize = ECP_PCIMEMSIZE;
 		brdp->pagesize = ECP_PCIPAGESIZE;
 		brdp->init = stli_ecppciinit;
@@ -3444,8 +3285,8 @@ static int stli_initecp(stlibrd_t *brdp)
 		break;
 
 	default:
-		release_region(brdp->iobase, brdp->iosize);
-		return -EINVAL;
+		retval = -EINVAL;
+		goto err_reg;
 	}
 
 /*
@@ -3457,10 +3298,9 @@ static int stli_initecp(stlibrd_t *brdp)
 	EBRDINIT(brdp);
 
 	brdp->membase = ioremap(brdp->memaddr, brdp->memsize);
-	if (brdp->membase == NULL)
-	{
-		release_region(brdp->iobase, brdp->iosize);
-		return -ENOMEM;
+	if (brdp->membase == NULL) {
+		retval = -ENOMEM;
+		goto err_reg;
 	}
 
 /*
@@ -3473,12 +3313,9 @@ static int stli_initecp(stlibrd_t *brdp)
 	memcpy_fromio(&sig, sigsp, sizeof(cdkecpsig_t));
 	EBRDDISABLE(brdp);
 
-	if (sig.magic != cpu_to_le32(ECP_MAGIC))
-	{
-		release_region(brdp->iobase, brdp->iosize);
-		iounmap(brdp->membase);
-		brdp->membase = NULL;
-		return -ENODEV;
+	if (sig.magic != cpu_to_le32(ECP_MAGIC)) {
+		retval = -ENODEV;
+		goto err_unmap;
 	}
 
 /*
@@ -3503,6 +3340,13 @@ static int stli_initecp(stlibrd_t *brdp)
 
 	brdp->state |= BST_FOUND;
 	return 0;
+err_unmap:
+	iounmap(brdp->membase);
+	brdp->membase = NULL;
+err_reg:
+	release_region(brdp->iobase, brdp->iosize);
+err:
+	return retval;
 }
 
 /*****************************************************************************/
@@ -3512,23 +3356,27 @@ static int stli_initecp(stlibrd_t *brdp)
  *	This handles only these board types.
  */
 
-static int stli_initonb(stlibrd_t *brdp)
+static int stli_initonb(struct stlibrd *brdp)
 {
 	cdkonbsig_t sig;
 	cdkonbsig_t __iomem *sigsp;
 	char *name;
-	int i;
+	int i, retval;
 
 /*
  *	Do a basic sanity check on the IO and memory addresses.
  */
-	if (brdp->iobase == 0 || brdp->memaddr == 0)
-		return -ENODEV;
+	if (brdp->iobase == 0 || brdp->memaddr == 0) {
+		retval = -ENODEV;
+		goto err;
+	}
 
 	brdp->iosize = ONB_IOSIZE;
 	
-	if (!request_region(brdp->iobase, brdp->iosize, "istallion"))
-		return -EIO;
+	if (!request_region(brdp->iobase, brdp->iosize, "istallion")) {
+		retval = -EIO;
+		goto err;
+	}
 
 /*
  *	Based on the specific board type setup the common vars to access
@@ -3537,10 +3385,7 @@ static int stli_initonb(stlibrd_t *brdp)
  */
 	switch (brdp->brdtype) {
 	case BRD_ONBOARD:
-	case BRD_ONBOARD32:
 	case BRD_ONBOARD2:
-	case BRD_ONBOARD2_32:
-	case BRD_ONBOARDRS:
 		brdp->memsize = ONB_MEMSIZE;
 		brdp->pagesize = ONB_ATPAGESIZE;
 		brdp->init = stli_onbinit;
@@ -3571,8 +3416,6 @@ static int stli_initonb(stlibrd_t *brdp)
 		break;
 
 	case BRD_BRUMBY4:
-	case BRD_BRUMBY8:
-	case BRD_BRUMBY16:
 		brdp->memsize = BBY_MEMSIZE;
 		brdp->pagesize = BBY_PAGESIZE;
 		brdp->init = stli_bbyinit;
@@ -3599,8 +3442,8 @@ static int stli_initonb(stlibrd_t *brdp)
 		break;
 
 	default:
-		release_region(brdp->iobase, brdp->iosize);
-		return -EINVAL;
+		retval = -EINVAL;
+		goto err_reg;
 	}
 
 /*
@@ -3612,10 +3455,9 @@ static int stli_initonb(stlibrd_t *brdp)
 	EBRDINIT(brdp);
 
 	brdp->membase = ioremap(brdp->memaddr, brdp->memsize);
-	if (brdp->membase == NULL)
-	{
-		release_region(brdp->iobase, brdp->iosize);
-		return -ENOMEM;
+	if (brdp->membase == NULL) {
+		retval = -ENOMEM;
+		goto err_reg;
 	}
 
 /*
@@ -3631,12 +3473,9 @@ static int stli_initonb(stlibrd_t *brdp)
 	if (sig.magic0 != cpu_to_le16(ONB_MAGIC0) ||
 	    sig.magic1 != cpu_to_le16(ONB_MAGIC1) ||
 	    sig.magic2 != cpu_to_le16(ONB_MAGIC2) ||
-	    sig.magic3 != cpu_to_le16(ONB_MAGIC3))
-	{
-		release_region(brdp->iobase, brdp->iosize);
-		iounmap(brdp->membase);
-		brdp->membase = NULL;
-		return -ENODEV;
+	    sig.magic3 != cpu_to_le16(ONB_MAGIC3)) {
+		retval = -ENODEV;
+		goto err_unmap;
 	}
 
 /*
@@ -3658,6 +3497,13 @@ static int stli_initonb(stlibrd_t *brdp)
 
 	brdp->state |= BST_FOUND;
 	return 0;
+err_unmap:
+	iounmap(brdp->membase);
+	brdp->membase = NULL;
+err_reg:
+	release_region(brdp->iobase, brdp->iosize);
+err:
+	return retval;
 }
 
 /*****************************************************************************/
@@ -3668,14 +3514,15 @@ static int stli_initonb(stlibrd_t *brdp)
  *	read in the memory map, and get the show on the road...
  */
 
-static int stli_startbrd(stlibrd_t *brdp)
+static int stli_startbrd(struct stlibrd *brdp)
 {
 	cdkhdr_t __iomem *hdrp;
 	cdkmem_t __iomem *memp;
 	cdkasy_t __iomem *ap;
 	unsigned long flags;
-	stliport_t *portp;
-	int portnr, nrdevs, i, rc = 0;
+	unsigned int portnr, nrdevs, i;
+	struct stliport *portp;
+	int rc = 0;
 	u32 memoff;
 
 	spin_lock_irqsave(&brd_lock, flags);
@@ -3762,8 +3609,7 @@ stli_donestartup:
 
 	if (! stli_timeron) {
 		stli_timeron++;
-		stli_timerlist.expires = STLI_TIMEOUT;
-		add_timer(&stli_timerlist);
+		mod_timer(&stli_timerlist, STLI_TIMEOUT);
 	}
 
 	return rc;
@@ -3775,49 +3621,32 @@ stli_donestartup:
  *	Probe and initialize the specified board.
  */
 
-static int __init stli_brdinit(stlibrd_t *brdp)
+static int __devinit stli_brdinit(struct stlibrd *brdp)
 {
-	stli_brds[brdp->brdnr] = brdp;
+	int retval;
 
 	switch (brdp->brdtype) {
 	case BRD_ECP:
 	case BRD_ECPE:
 	case BRD_ECPMC:
 	case BRD_ECPPCI:
-		stli_initecp(brdp);
+		retval = stli_initecp(brdp);
 		break;
 	case BRD_ONBOARD:
 	case BRD_ONBOARDE:
 	case BRD_ONBOARD2:
-	case BRD_ONBOARD32:
-	case BRD_ONBOARD2_32:
-	case BRD_ONBOARDRS:
 	case BRD_BRUMBY4:
-	case BRD_BRUMBY8:
-	case BRD_BRUMBY16:
 	case BRD_STALLION:
-		stli_initonb(brdp);
+		retval = stli_initonb(brdp);
 		break;
-	case BRD_EASYIO:
-	case BRD_ECH:
-	case BRD_ECHMC:
-	case BRD_ECHPCI:
-		printk(KERN_ERR "STALLION: %s board type not supported in "
-				"this driver\n", stli_brdnames[brdp->brdtype]);
-		return -ENODEV;
 	default:
 		printk(KERN_ERR "STALLION: board=%d is unknown board "
 				"type=%d\n", brdp->brdnr, brdp->brdtype);
-		return -ENODEV;
+		retval = -ENODEV;
 	}
 
-	if ((brdp->state & BST_FOUND) == 0) {
-		printk(KERN_ERR "STALLION: %s board not found, board=%d "
-				"io=%x mem=%x\n",
-			stli_brdnames[brdp->brdtype], brdp->brdnr,
-			brdp->iobase, (int) brdp->memaddr);
-		return -ENODEV;
-	}
+	if (retval)
+		return retval;
 
 	stli_initports(brdp);
 	printk(KERN_INFO "STALLION: %s found, board=%d io=%x mem=%x "
@@ -3827,6 +3656,7 @@ static int __init stli_brdinit(stlibrd_t *brdp)
 	return 0;
 }
 
+#if STLI_EISAPROBE != 0
 /*****************************************************************************/
 
 /*
@@ -3834,7 +3664,7 @@ static int __init stli_brdinit(stlibrd_t *brdp)
  *	might be. This is a bit if hack, but it is the best we can do.
  */
 
-static int stli_eisamemprobe(stlibrd_t *brdp)
+static int stli_eisamemprobe(struct stlibrd *brdp)
 {
 	cdkecpsig_t	ecpsig, __iomem *ecpsigp;
 	cdkonbsig_t	onbsig, __iomem *onbsigp;
@@ -3920,10 +3750,11 @@ static int stli_eisamemprobe(stlibrd_t *brdp)
 	}
 	return 0;
 }
+#endif
 
 static int stli_getbrdnr(void)
 {
-	int i;
+	unsigned int i;
 
 	for (i = 0; i < STL_MAXBRDS; i++) {
 		if (!stli_brds[i]) {
@@ -3935,6 +3766,7 @@ static int stli_getbrdnr(void)
 	return -1;
 }
 
+#if STLI_EISAPROBE != 0
 /*****************************************************************************/
 
 /*
@@ -3949,9 +3781,9 @@ static int stli_getbrdnr(void)
 
 static int stli_findeisabrds(void)
 {
-	stlibrd_t *brdp;
-	unsigned int iobase, eid;
-	int i;
+	struct stlibrd *brdp;
+	unsigned int iobase, eid, i;
+	int brdnr, found = 0;
 
 /*
  *	Firstly check if this is an EISA system.  If this is not an EISA system then
@@ -3989,9 +3821,11 @@ static int stli_findeisabrds(void)
  *		Allocate a board structure and initialize it.
  */
 		if ((brdp = stli_allocbrd()) == NULL)
-			return -ENOMEM;
-		if ((brdp->brdnr = stli_getbrdnr()) < 0)
-			return -ENOMEM;
+			return found ? : -ENOMEM;
+		brdnr = stli_getbrdnr();
+		if (brdnr < 0)
+			return found ? : -ENOMEM;
+		brdp->brdnr = (unsigned int)brdnr;
 		eid = inb(iobase + 0xc82);
 		if (eid == ECP_EISAID)
 			brdp->brdtype = BRD_ECPE;
@@ -4003,11 +3837,24 @@ static int stli_findeisabrds(void)
 		outb(0x1, (iobase + 0xc84));
 		if (stli_eisamemprobe(brdp))
 			outb(0, (iobase + 0xc84));
-		stli_brdinit(brdp);
+		if (stli_brdinit(brdp) < 0) {
+			kfree(brdp);
+			continue;
+		}
+
+		stli_brds[brdp->brdnr] = brdp;
+		found++;
+
+		for (i = 0; i < brdp->nrports; i++)
+			tty_register_device(stli_serial,
+					brdp->brdnr * STL_MAXPORTS + i, NULL);
 	}
 
-	return 0;
+	return found;
 }
+#else
+static inline int stli_findeisabrds(void) { return 0; }
+#endif
 
 /*****************************************************************************/
 
@@ -4017,72 +3864,104 @@ static int stli_findeisabrds(void)
 
 /*****************************************************************************/
 
-#ifdef	CONFIG_PCI
-
 /*
  *	We have a Stallion board. Allocate a board structure and
  *	initialize it. Read its IO and MEMORY resources from PCI
  *	configuration space.
  */
 
-static int stli_initpcibrd(int brdtype, struct pci_dev *devp)
+static int __devinit stli_pciprobe(struct pci_dev *pdev,
+		const struct pci_device_id *ent)
 {
-	stlibrd_t *brdp;
-
-	if (pci_enable_device(devp))
-		return -EIO;
-	if ((brdp = stli_allocbrd()) == NULL)
-		return -ENOMEM;
-	if ((brdp->brdnr = stli_getbrdnr()) < 0) {
+	struct stlibrd *brdp;
+	unsigned int i;
+	int brdnr, retval = -EIO;
+
+	retval = pci_enable_device(pdev);
+	if (retval)
+		goto err;
+	brdp = stli_allocbrd();
+	if (brdp == NULL) {
+		retval = -ENOMEM;
+		goto err;
+	}
+	mutex_lock(&stli_brdslock);
+	brdnr = stli_getbrdnr();
+	if (brdnr < 0) {
 		printk(KERN_INFO "STALLION: too many boards found, "
 			"maximum supported %d\n", STL_MAXBRDS);
-		return 0;
+		mutex_unlock(&stli_brdslock);
+		retval = -EIO;
+		goto err_fr;
 	}
-	brdp->brdtype = brdtype;
+	brdp->brdnr = (unsigned int)brdnr;
+	stli_brds[brdp->brdnr] = brdp;
+	mutex_unlock(&stli_brdslock);
+	brdp->brdtype = BRD_ECPPCI;
 /*
  *	We have all resources from the board, so lets setup the actual
  *	board structure now.
  */
-	brdp->iobase = pci_resource_start(devp, 3);
-	brdp->memaddr = pci_resource_start(devp, 2);
-	stli_brdinit(brdp);
+	brdp->iobase = pci_resource_start(pdev, 3);
+	brdp->memaddr = pci_resource_start(pdev, 2);
+	retval = stli_brdinit(brdp);
+	if (retval)
+		goto err_null;
+
+	brdp->state |= BST_PROBED;
+	pci_set_drvdata(pdev, brdp);
+
+	EBRDENABLE(brdp);
+	brdp->enable = NULL;
+	brdp->disable = NULL;
+
+	for (i = 0; i < brdp->nrports; i++)
+		tty_register_device(stli_serial, brdp->brdnr * STL_MAXPORTS + i,
+				&pdev->dev);
 
 	return 0;
+err_null:
+	stli_brds[brdp->brdnr] = NULL;
+err_fr:
+	kfree(brdp);
+err:
+	return retval;
 }
 
-/*****************************************************************************/
+static void stli_pciremove(struct pci_dev *pdev)
+{
+	struct stlibrd *brdp = pci_get_drvdata(pdev);
 
-/*
- *	Find all Stallion PCI boards that might be installed. Initialize each
- *	one as it is found.
- */
+	stli_cleanup_ports(brdp);
 
-static int stli_findpcibrds(void)
-{
-	struct pci_dev *dev = NULL;
+	iounmap(brdp->membase);
+	if (brdp->iosize > 0)
+		release_region(brdp->iobase, brdp->iosize);
 
-	while ((dev = pci_get_device(PCI_VENDOR_ID_STALLION, PCI_DEVICE_ID_ECRA, dev))) {
-		stli_initpcibrd(BRD_ECPPCI, dev);
-	}
-	return 0;
+	stli_brds[brdp->brdnr] = NULL;
+	kfree(brdp);
 }
 
-#endif
-
+static struct pci_driver stli_pcidriver = {
+	.name = "istallion",
+	.id_table = istallion_pci_tbl,
+	.probe = stli_pciprobe,
+	.remove = __devexit_p(stli_pciremove)
+};
 /*****************************************************************************/
 
 /*
  *	Allocate a new board structure. Fill out the basic info in it.
  */
 
-static stlibrd_t *stli_allocbrd(void)
+static struct stlibrd *stli_allocbrd(void)
 {
-	stlibrd_t *brdp;
+	struct stlibrd *brdp;
 
-	brdp = kzalloc(sizeof(stlibrd_t), GFP_KERNEL);
+	brdp = kzalloc(sizeof(struct stlibrd), GFP_KERNEL);
 	if (!brdp) {
 		printk(KERN_ERR "STALLION: failed to allocate memory "
-				"(size=%Zd)\n", sizeof(stlibrd_t));
+				"(size=%Zd)\n", sizeof(struct stlibrd));
 		return NULL;
 	}
 	brdp->magic = STLI_BOARDMAGIC;
@@ -4098,43 +3977,37 @@ static stlibrd_t *stli_allocbrd(void)
 
 static int stli_initbrds(void)
 {
-	stlibrd_t *brdp, *nxtbrdp;
-	stlconf_t *confp;
-	int i, j;
-
-	if (stli_nrbrds > STL_MAXBRDS) {
-		printk(KERN_INFO "STALLION: too many boards in configuration "
-			"table, truncating to %d\n", STL_MAXBRDS);
-		stli_nrbrds = STL_MAXBRDS;
-	}
+	struct stlibrd *brdp, *nxtbrdp;
+	struct stlconf conf;
+	unsigned int i, j, found = 0;
+	int retval;
 
-/*
- *	Firstly scan the list of static boards configured. Allocate
- *	resources and initialize the boards as found. If this is a
- *	module then let the module args override static configuration.
- */
-	for (i = 0; (i < stli_nrbrds); i++) {
-		confp = &stli_brdconf[i];
-		stli_parsebrd(confp, stli_brdsp[i]);
+	for (stli_nrbrds = 0; stli_nrbrds < ARRAY_SIZE(stli_brdsp);
+			stli_nrbrds++) {
+		memset(&conf, 0, sizeof(conf));
+		if (stli_parsebrd(&conf, stli_brdsp[stli_nrbrds]) == 0)
+			continue;
 		if ((brdp = stli_allocbrd()) == NULL)
-			return -ENOMEM;
-		brdp->brdnr = i;
-		brdp->brdtype = confp->brdtype;
-		brdp->iobase = confp->ioaddr1;
-		brdp->memaddr = confp->memaddr;
-		stli_brdinit(brdp);
+			continue;
+		brdp->brdnr = stli_nrbrds;
+		brdp->brdtype = conf.brdtype;
+		brdp->iobase = conf.ioaddr1;
+		brdp->memaddr = conf.memaddr;
+		if (stli_brdinit(brdp) < 0) {
+			kfree(brdp);
+			continue;
+		}
+		stli_brds[brdp->brdnr] = brdp;
+		found++;
+
+		for (i = 0; i < brdp->nrports; i++)
+			tty_register_device(stli_serial,
+					brdp->brdnr * STL_MAXPORTS + i, NULL);
 	}
 
-/*
- *	Static configuration table done, so now use dynamic methods to
- *	see if any more boards should be configured.
- */
-	stli_argbrds();
-	if (STLI_EISAPROBE)
-		stli_findeisabrds();
-#ifdef CONFIG_PCI
-	stli_findpcibrds();
-#endif
+	retval = stli_findeisabrds();
+	if (retval > 0)
+		found += retval;
 
 /*
  *	All found boards are initialized. Now for a little optimization, if
@@ -4174,7 +4047,16 @@ static int stli_initbrds(void)
 		}
 	}
 
+	retval = pci_register_driver(&stli_pcidriver);
+	if (retval && found == 0) {
+		printk(KERN_ERR "Neither isa nor eisa cards found nor pci "
+				"driver can be registered!\n");
+		goto err;
+	}
+
 	return 0;
+err:
+	return retval;
 }
 
 /*****************************************************************************/
@@ -4189,12 +4071,13 @@ static ssize_t stli_memread(struct file *fp, char __user *buf, size_t count, lof
 {
 	unsigned long flags;
 	void __iomem *memptr;
-	stlibrd_t *brdp;
-	int brdnr, size, n;
+	struct stlibrd *brdp;
+	unsigned int brdnr;
+	int size, n;
 	void *p;
 	loff_t off = *offp;
 
-	brdnr = iminor(fp->f_dentry->d_inode);
+	brdnr = iminor(fp->f_path.dentry->d_inode);
 	if (brdnr >= stli_nrbrds)
 		return -ENODEV;
 	brdp = stli_brds[brdnr];
@@ -4205,7 +4088,7 @@ static ssize_t stli_memread(struct file *fp, char __user *buf, size_t count, lof
 	if (off >= brdp->memsize || off + count < off)
 		return 0;
 
-	size = MIN(count, (brdp->memsize - off));
+	size = min(count, (size_t)(brdp->memsize - off));
 
 	/*
 	 *	Copy the data a page at a time
@@ -4219,8 +4102,8 @@ static ssize_t stli_memread(struct file *fp, char __user *buf, size_t count, lof
 		spin_lock_irqsave(&brd_lock, flags);
 		EBRDENABLE(brdp);
 		memptr = EBRDGETMEMPTR(brdp, off);
-		n = MIN(size, (brdp->pagesize - (((unsigned long) off) % brdp->pagesize)));
-		n = MIN(n, PAGE_SIZE);
+		n = min(size, (int)(brdp->pagesize - (((unsigned long) off) % brdp->pagesize)));
+		n = min(n, (int)PAGE_SIZE);
 		memcpy_fromio(p, memptr, n);
 		EBRDDISABLE(brdp);
 		spin_unlock_irqrestore(&brd_lock, flags);
@@ -4252,13 +4135,14 @@ static ssize_t stli_memwrite(struct file *fp, const char __user *buf, size_t cou
 {
 	unsigned long flags;
 	void __iomem *memptr;
-	stlibrd_t *brdp;
+	struct stlibrd *brdp;
 	char __user *chbuf;
-	int brdnr, size, n;
+	unsigned int brdnr;
+	int size, n;
 	void *p;
 	loff_t off = *offp;
 
-	brdnr = iminor(fp->f_dentry->d_inode);
+	brdnr = iminor(fp->f_path.dentry->d_inode);
 
 	if (brdnr >= stli_nrbrds)
 		return -ENODEV;
@@ -4271,7 +4155,7 @@ static ssize_t stli_memwrite(struct file *fp, const char __user *buf, size_t cou
 		return 0;
 
 	chbuf = (char __user *) buf;
-	size = MIN(count, (brdp->memsize - off));
+	size = min(count, (size_t)(brdp->memsize - off));
 
 	/*
 	 *	Copy the data a page at a time
@@ -4282,8 +4166,8 @@ static ssize_t stli_memwrite(struct file *fp, const char __user *buf, size_t cou
 		return -ENOMEM;
 
 	while (size > 0) {
-		n = MIN(size, (brdp->pagesize - (((unsigned long) off) % brdp->pagesize)));
-		n = MIN(n, PAGE_SIZE);
+		n = min(size, (int)(brdp->pagesize - (((unsigned long) off) % brdp->pagesize)));
+		n = min(n, (int)PAGE_SIZE);
 		if (copy_from_user(p, chbuf, n)) {
 			if (count == 0)
 				count = -EFAULT;
@@ -4313,8 +4197,8 @@ out:
 
 static int stli_getbrdstats(combrd_t __user *bp)
 {
-	stlibrd_t *brdp;
-	int i;
+	struct stlibrd *brdp;
+	unsigned int i;
 
 	if (copy_from_user(&stli_brdstats, bp, sizeof(combrd_t)))
 		return -EFAULT;
@@ -4350,19 +4234,20 @@ static int stli_getbrdstats(combrd_t __user *bp)
  *	Resolve the referenced port number into a port struct pointer.
  */
 
-static stliport_t *stli_getport(int brdnr, int panelnr, int portnr)
+static struct stliport *stli_getport(unsigned int brdnr, unsigned int panelnr,
+		unsigned int portnr)
 {
-	stlibrd_t *brdp;
-	int i;
+	struct stlibrd *brdp;
+	unsigned int i;
 
-	if (brdnr < 0 || brdnr >= STL_MAXBRDS)
+	if (brdnr >= STL_MAXBRDS)
 		return NULL;
 	brdp = stli_brds[brdnr];
 	if (brdp == NULL)
 		return NULL;
 	for (i = 0; (i < panelnr); i++)
 		portnr += brdp->panels[i];
-	if ((portnr < 0) || (portnr >= brdp->nrports))
+	if (portnr >= brdp->nrports)
 		return NULL;
 	return brdp->ports[portnr];
 }
@@ -4375,10 +4260,10 @@ static stliport_t *stli_getport(int brdnr, int panelnr, int portnr)
  *	what port to get stats for (used through board control device).
  */
 
-static int stli_portcmdstats(stliport_t *portp)
+static int stli_portcmdstats(struct stliport *portp)
 {
 	unsigned long	flags;
-	stlibrd_t	*brdp;
+	struct stlibrd	*brdp;
 	int		rc;
 
 	memset(&stli_comstats, 0, sizeof(comstats_t));
@@ -4449,9 +4334,9 @@ static int stli_portcmdstats(stliport_t *portp)
  *	what port to get stats for (used through board control device).
  */
 
-static int stli_getportstats(stliport_t *portp, comstats_t __user *cp)
+static int stli_getportstats(struct stliport *portp, comstats_t __user *cp)
 {
-	stlibrd_t *brdp;
+	struct stlibrd *brdp;
 	int rc;
 
 	if (!portp) {
@@ -4480,9 +4365,9 @@ static int stli_getportstats(stliport_t *portp, comstats_t __user *cp)
  *	Clear the port stats structure. We also return it zeroed out...
  */
 
-static int stli_clrportstats(stliport_t *portp, comstats_t __user *cp)
+static int stli_clrportstats(struct stliport *portp, comstats_t __user *cp)
 {
-	stlibrd_t *brdp;
+	struct stlibrd *brdp;
 	int rc;
 
 	if (!portp) {
@@ -4519,17 +4404,18 @@ static int stli_clrportstats(stliport_t *portp, comstats_t __user *cp)
  *	Return the entire driver ports structure to a user app.
  */
 
-static int stli_getportstruct(stliport_t __user *arg)
+static int stli_getportstruct(struct stliport __user *arg)
 {
-	stliport_t *portp;
+	struct stliport stli_dummyport;
+	struct stliport *portp;
 
-	if (copy_from_user(&stli_dummyport, arg, sizeof(stliport_t)))
+	if (copy_from_user(&stli_dummyport, arg, sizeof(struct stliport)))
 		return -EFAULT;
 	portp = stli_getport(stli_dummyport.brdnr, stli_dummyport.panelnr,
 		 stli_dummyport.portnr);
 	if (!portp)
 		return -ENODEV;
-	if (copy_to_user(arg, portp, sizeof(stliport_t)))
+	if (copy_to_user(arg, portp, sizeof(struct stliport)))
 		return -EFAULT;
 	return 0;
 }
@@ -4540,18 +4426,19 @@ static int stli_getportstruct(stliport_t __user *arg)
  *	Return the entire driver board structure to a user app.
  */
 
-static int stli_getbrdstruct(stlibrd_t __user *arg)
+static int stli_getbrdstruct(struct stlibrd __user *arg)
 {
-	stlibrd_t *brdp;
+	struct stlibrd stli_dummybrd;
+	struct stlibrd *brdp;
 
-	if (copy_from_user(&stli_dummybrd, arg, sizeof(stlibrd_t)))
+	if (copy_from_user(&stli_dummybrd, arg, sizeof(struct stlibrd)))
 		return -EFAULT;
-	if ((stli_dummybrd.brdnr < 0) || (stli_dummybrd.brdnr >= STL_MAXBRDS))
+	if (stli_dummybrd.brdnr >= STL_MAXBRDS)
 		return -ENODEV;
 	brdp = stli_brds[stli_dummybrd.brdnr];
 	if (!brdp)
 		return -ENODEV;
-	if (copy_to_user(arg, brdp, sizeof(stlibrd_t)))
+	if (copy_to_user(arg, brdp, sizeof(struct stlibrd)))
 		return -EFAULT;
 	return 0;
 }
@@ -4566,7 +4453,7 @@ static int stli_getbrdstruct(stlibrd_t __user *arg)
 
 static int stli_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, unsigned long arg)
 {
-	stlibrd_t *brdp;
+	struct stlibrd *brdp;
 	int brdnr, rc, done;
 	void __user *argp = (void __user *)arg;
 
@@ -4665,46 +4552,53 @@ static const struct tty_operations stli_ops = {
 };
 
 /*****************************************************************************/
+/*
+ *	Loadable module initialization stuff.
+ */
+
+static void istallion_cleanup_isa(void)
+{
+	struct stlibrd	*brdp;
+	unsigned int j;
+
+	for (j = 0; (j < stli_nrbrds); j++) {
+		if ((brdp = stli_brds[j]) == NULL || (brdp->state & BST_PROBED))
+			continue;
+
+		stli_cleanup_ports(brdp);
 
-static int __init stli_init(void)
+		iounmap(brdp->membase);
+		if (brdp->iosize > 0)
+			release_region(brdp->iobase, brdp->iosize);
+		kfree(brdp);
+		stli_brds[j] = NULL;
+	}
+}
+
+static int __init istallion_module_init(void)
 {
-	int i;
+	unsigned int i;
+	int retval;
+
 	printk(KERN_INFO "%s: version %s\n", stli_drvtitle, stli_drvversion);
 
 	spin_lock_init(&stli_lock);
 	spin_lock_init(&brd_lock);
 
-	stli_initbrds();
-
-	stli_serial = alloc_tty_driver(STL_MAXBRDS * STL_MAXPORTS);
-	if (!stli_serial)
-		return -ENOMEM;
-
-/*
- *	Allocate a temporary write buffer.
- */
 	stli_txcookbuf = kmalloc(STLI_TXBUFSIZE, GFP_KERNEL);
-	if (!stli_txcookbuf)
+	if (!stli_txcookbuf) {
 		printk(KERN_ERR "STALLION: failed to allocate memory "
 				"(size=%d)\n", STLI_TXBUFSIZE);
+		retval = -ENOMEM;
+		goto err;
+	}
 
-/*
- *	Set up a character driver for the shared memory region. We need this
- *	to down load the slave code image. Also it is a useful debugging tool.
- */
-	if (register_chrdev(STL_SIOMEMMAJOR, "staliomem", &stli_fsiomem))
-		printk(KERN_ERR "STALLION: failed to register serial memory "
-				"device\n");
-
-	istallion_class = class_create(THIS_MODULE, "staliomem");
-	for (i = 0; i < 4; i++)
-		class_device_create(istallion_class, NULL,
-				MKDEV(STL_SIOMEMMAJOR, i),
-				NULL, "staliomem%d", i);
+	stli_serial = alloc_tty_driver(STL_MAXBRDS * STL_MAXPORTS);
+	if (!stli_serial) {
+		retval = -ENOMEM;
+		goto err_free;
+	}
 
-/*
- *	Set up the tty driver structure and register us as a driver.
- */
 	stli_serial->owner = THIS_MODULE;
 	stli_serial->driver_name = stli_drvname;
 	stli_serial->name = stli_serialname;
@@ -4713,15 +4607,79 @@ static int __init stli_init(void)
 	stli_serial->type = TTY_DRIVER_TYPE_SERIAL;
 	stli_serial->subtype = SERIAL_TYPE_NORMAL;
 	stli_serial->init_termios = stli_deftermios;
-	stli_serial->flags = TTY_DRIVER_REAL_RAW;
+	stli_serial->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
 	tty_set_operations(stli_serial, &stli_ops);
 
-	if (tty_register_driver(stli_serial)) {
-		put_tty_driver(stli_serial);
+	retval = tty_register_driver(stli_serial);
+	if (retval) {
 		printk(KERN_ERR "STALLION: failed to register serial driver\n");
-		return -EBUSY;
+		goto err_ttyput;
 	}
+
+	retval = stli_initbrds();
+	if (retval)
+		goto err_ttyunr;
+
+/*
+ *	Set up a character driver for the shared memory region. We need this
+ *	to down load the slave code image. Also it is a useful debugging tool.
+ */
+	retval = register_chrdev(STL_SIOMEMMAJOR, "staliomem", &stli_fsiomem);
+	if (retval) {
+		printk(KERN_ERR "STALLION: failed to register serial memory "
+				"device\n");
+		goto err_deinit;
+	}
+
+	istallion_class = class_create(THIS_MODULE, "staliomem");
+	for (i = 0; i < 4; i++)
+		class_device_create(istallion_class, NULL,
+				MKDEV(STL_SIOMEMMAJOR, i),
+				NULL, "staliomem%d", i);
+
 	return 0;
+err_deinit:
+	pci_unregister_driver(&stli_pcidriver);
+	istallion_cleanup_isa();
+err_ttyunr:
+	tty_unregister_driver(stli_serial);
+err_ttyput:
+	put_tty_driver(stli_serial);
+err_free:
+	kfree(stli_txcookbuf);
+err:
+	return retval;
 }
 
 /*****************************************************************************/
+
+static void __exit istallion_module_exit(void)
+{
+	unsigned int j;
+
+	printk(KERN_INFO "Unloading %s: version %s\n", stli_drvtitle,
+		stli_drvversion);
+
+	if (stli_timeron) {
+		stli_timeron = 0;
+		del_timer_sync(&stli_timerlist);
+	}
+
+	unregister_chrdev(STL_SIOMEMMAJOR, "staliomem");
+
+	for (j = 0; j < 4; j++)
+		class_device_destroy(istallion_class, MKDEV(STL_SIOMEMMAJOR,
+					j));
+	class_destroy(istallion_class);
+
+	pci_unregister_driver(&stli_pcidriver);
+	istallion_cleanup_isa();
+
+	tty_unregister_driver(stli_serial);
+	put_tty_driver(stli_serial);
+
+	kfree(stli_txcookbuf);
+}
+
+module_init(istallion_module_init);
+module_exit(istallion_module_exit);
diff --git a/drivers/char/lp.c b/drivers/char/lp.c
index 1ecea7d448f1..b70b5388b5a8 100644
--- a/drivers/char/lp.c
+++ b/drivers/char/lp.c
@@ -296,7 +296,7 @@ static int lp_wait_ready(int minor, int nonblock)
 static ssize_t lp_write(struct file * file, const char __user * buf,
 		        size_t count, loff_t *ppos)
 {
-	unsigned int minor = iminor(file->f_dentry->d_inode);
+	unsigned int minor = iminor(file->f_path.dentry->d_inode);
 	struct parport *port = lp_table[minor].dev->port;
 	char *kbuf = lp_table[minor].lp_buffer;
 	ssize_t retv = 0;
@@ -415,7 +415,7 @@ static ssize_t lp_read(struct file * file, char __user * buf,
 		       size_t count, loff_t *ppos)
 {
 	DEFINE_WAIT(wait);
-	unsigned int minor=iminor(file->f_dentry->d_inode);
+	unsigned int minor=iminor(file->f_path.dentry->d_inode);
 	struct parport *port = lp_table[minor].dev->port;
 	ssize_t retval = 0;
 	char *kbuf = lp_table[minor].lp_buffer;
diff --git a/drivers/char/mem.c b/drivers/char/mem.c
index e67eef4867ba..089020e0ee5a 100644
--- a/drivers/char/mem.c
+++ b/drivers/char/mem.c
@@ -774,7 +774,7 @@ static loff_t memory_lseek(struct file * file, loff_t offset, int orig)
 {
 	loff_t ret;
 
-	mutex_lock(&file->f_dentry->d_inode->i_mutex);
+	mutex_lock(&file->f_path.dentry->d_inode->i_mutex);
 	switch (orig) {
 		case 0:
 			file->f_pos = offset;
@@ -789,7 +789,7 @@ static loff_t memory_lseek(struct file * file, loff_t offset, int orig)
 		default:
 			ret = -EINVAL;
 	}
-	mutex_unlock(&file->f_dentry->d_inode->i_mutex);
+	mutex_unlock(&file->f_path.dentry->d_inode->i_mutex);
 	return ret;
 }
 
diff --git a/drivers/char/moxa.c b/drivers/char/moxa.c
index 8b316953173d..f391a24a1b44 100644
--- a/drivers/char/moxa.c
+++ b/drivers/char/moxa.c
@@ -234,7 +234,7 @@ static void moxa_put_char(struct tty_struct *, unsigned char);
 static int moxa_ioctl(struct tty_struct *, struct file *, unsigned int, unsigned long);
 static void moxa_throttle(struct tty_struct *);
 static void moxa_unthrottle(struct tty_struct *);
-static void moxa_set_termios(struct tty_struct *, struct termios *);
+static void moxa_set_termios(struct tty_struct *, struct ktermios *);
 static void moxa_stop(struct tty_struct *);
 static void moxa_start(struct tty_struct *);
 static void moxa_hangup(struct tty_struct *);
@@ -261,7 +261,7 @@ static void MoxaPortEnable(int);
 static void MoxaPortDisable(int);
 static long MoxaPortGetMaxBaud(int);
 static long MoxaPortSetBaud(int, long);
-static int MoxaPortSetTermio(int, struct termios *, speed_t);
+static int MoxaPortSetTermio(int, struct ktermios *, speed_t);
 static int MoxaPortGetLineOut(int, int *, int *);
 static void MoxaPortLineCtrl(int, int, int);
 static void MoxaPortFlowCtrl(int, int, int, int, int, int);
@@ -355,6 +355,8 @@ static int __init moxa_init(void)
 	moxaDriver->init_termios.c_oflag = 0;
 	moxaDriver->init_termios.c_cflag = B9600 | CS8 | CREAD | CLOCAL | HUPCL;
 	moxaDriver->init_termios.c_lflag = 0;
+	moxaDriver->init_termios.c_ispeed = 9600;
+	moxaDriver->init_termios.c_ospeed = 9600;
 	moxaDriver->flags = TTY_DRIVER_REAL_RAW;
 	tty_set_operations(moxaDriver, &moxa_ops);
 
@@ -864,7 +866,7 @@ static void moxa_unthrottle(struct tty_struct *tty)
 }
 
 static void moxa_set_termios(struct tty_struct *tty,
-			     struct termios *old_termios)
+			     struct ktermios *old_termios)
 {
 	struct moxa_str *ch = (struct moxa_str *) tty->driver_data;
 
@@ -978,7 +980,7 @@ static void moxa_poll(unsigned long ignored)
 
 static void set_tty_param(struct tty_struct *tty)
 {
-	register struct termios *ts;
+	register struct ktermios *ts;
 	struct moxa_str *ch;
 	int rts, cts, txflow, rxflow, xany;
 
@@ -1149,7 +1151,7 @@ static void shut_down(struct moxa_str *ch)
 static void receive_data(struct moxa_str *ch)
 {
 	struct tty_struct *tp;
-	struct termios *ts;
+	struct ktermios *ts;
 	unsigned long flags;
 
 	ts = NULL;
@@ -1912,9 +1914,9 @@ int MoxaPortsOfCard(int cardno)
  *
  *      Function 12:    Configure the port.
  *      Syntax:
- *      int  MoxaPortSetTermio(int port, struct termios *termio, speed_t baud);
+ *      int  MoxaPortSetTermio(int port, struct ktermios *termio, speed_t baud);
  *           int port           : port number (0 - 127)
- *           struct termios * termio : termio structure pointer
+ *           struct ktermios * termio : termio structure pointer
  *	     speed_t baud	: baud rate
  *
  *           return:    -1      : this port is invalid or termio == NULL
@@ -2195,7 +2197,7 @@ long MoxaPortSetBaud(int port, long baud)
 	return (baud);
 }
 
-int MoxaPortSetTermio(int port, struct termios *termio, speed_t baud)
+int MoxaPortSetTermio(int port, struct ktermios *termio, speed_t baud)
 {
 	void __iomem *ofsAddr;
 	tcflag_t cflag;
diff --git a/drivers/char/mxser.c b/drivers/char/mxser.c
index 5ed2486b7581..c063359baf78 100644
--- a/drivers/char/mxser.c
+++ b/drivers/char/mxser.c
@@ -328,8 +328,8 @@ struct mxser_struct {
 	int xmit_tail;
 	int xmit_cnt;
 	struct work_struct tqueue;
-	struct termios normal_termios;
-	struct termios callout_termios;
+	struct ktermios normal_termios;
+	struct ktermios callout_termios;
 	wait_queue_head_t open_wait;
 	wait_queue_head_t close_wait;
 	wait_queue_head_t delta_msr_wait;
@@ -364,8 +364,8 @@ static int mxserBoardCAP[MXSER_BOARDS] = {
 static struct tty_driver *mxvar_sdriver;
 static struct mxser_struct mxvar_table[MXSER_PORTS];
 static struct tty_struct *mxvar_tty[MXSER_PORTS + 1];
-static struct termios *mxvar_termios[MXSER_PORTS + 1];
-static struct termios *mxvar_termios_locked[MXSER_PORTS + 1];
+static struct ktermios *mxvar_termios[MXSER_PORTS + 1];
+static struct ktermios *mxvar_termios_locked[MXSER_PORTS + 1];
 static struct mxser_log mxvar_log;
 static int mxvar_diagflag;
 static unsigned char mxser_msr[MXSER_PORTS + 1];
@@ -402,7 +402,7 @@ static int mxser_ioctl(struct tty_struct *, struct file *, uint, ulong);
 static int mxser_ioctl_special(unsigned int, void __user *);
 static void mxser_throttle(struct tty_struct *);
 static void mxser_unthrottle(struct tty_struct *);
-static void mxser_set_termios(struct tty_struct *, struct termios *);
+static void mxser_set_termios(struct tty_struct *, struct ktermios *);
 static void mxser_stop(struct tty_struct *);
 static void mxser_start(struct tty_struct *);
 static void mxser_hangup(struct tty_struct *);
@@ -414,7 +414,7 @@ static void mxser_check_modem_status(struct mxser_struct *, int);
 static int mxser_block_til_ready(struct tty_struct *, struct file *, struct mxser_struct *);
 static int mxser_startup(struct mxser_struct *);
 static void mxser_shutdown(struct mxser_struct *);
-static int mxser_change_speed(struct mxser_struct *, struct termios *old_termios);
+static int mxser_change_speed(struct mxser_struct *, struct ktermios *old_termios);
 static int mxser_get_serial_info(struct mxser_struct *, struct serial_struct __user *);
 static int mxser_set_serial_info(struct mxser_struct *, struct serial_struct __user *);
 static int mxser_get_lsr_info(struct mxser_struct *, unsigned int __user *);
@@ -515,6 +515,7 @@ static void __exit mxser_module_exit(void)
 			if (pdev != NULL) {	/* PCI */
 				release_region(pci_resource_start(pdev, 2), pci_resource_len(pdev, 2));
 				release_region(pci_resource_start(pdev, 3), pci_resource_len(pdev, 3));
+				pci_dev_put(pdev);
 			} else {
 				release_region(mxsercfg[i].ioaddr[0], 8 * mxsercfg[i].ports);
 				release_region(mxsercfg[i].vector, 1);
@@ -556,7 +557,7 @@ static int mxser_initbrd(int board, struct mxser_hwconf *hwconf)
 	n = board * MXSER_PORTS_PER_BOARD;
 	info = &mxvar_table[n];
 	/*if (verbose) */  {
-		printk(KERN_DEBUG "        ttyM%d - ttyM%d ",
+		printk(KERN_DEBUG "        ttyMI%d - ttyMI%d ",
 			n, n + hwconf->ports - 1);
 		printk(" max. baud rate = %d bps.\n",
 			hwconf->MaxCanSetBaudRate[0]);
@@ -717,7 +718,7 @@ static int mxser_init(void)
 	/* Initialize the tty_driver structure */
 	memset(mxvar_sdriver, 0, sizeof(struct tty_driver));
 	mxvar_sdriver->magic = TTY_DRIVER_MAGIC;
-	mxvar_sdriver->name = "ttyM";
+	mxvar_sdriver->name = "ttyMI";
 	mxvar_sdriver->major = ttymajor;
 	mxvar_sdriver->minor_start = 0;
 	mxvar_sdriver->num = MXSER_PORTS + 1;
@@ -725,6 +726,8 @@ static int mxser_init(void)
 	mxvar_sdriver->subtype = SERIAL_TYPE_NORMAL;
 	mxvar_sdriver->init_termios = tty_std_termios;
 	mxvar_sdriver->init_termios.c_cflag = B9600|CS8|CREAD|HUPCL|CLOCAL;
+	mxvar_sdriver->init_termios.c_ispeed = 9600;
+	mxvar_sdriver->init_termios.c_ospeed = 9600;
 	mxvar_sdriver->flags = TTY_DRIVER_REAL_RAW;
 	tty_set_operations(mxvar_sdriver, &mxser_ops);
 	mxvar_sdriver->ttys = mxvar_tty;
@@ -839,9 +842,9 @@ static int mxser_init(void)
 	index = 0;
 	b = 0;
 	while (b < n) {
-		pdev = pci_find_device(mxser_pcibrds[b].vendor,
+		pdev = pci_get_device(mxser_pcibrds[b].vendor,
 				mxser_pcibrds[b].device, pdev);
-			if (pdev == NULL) {
+		if (pdev == NULL) {
 			b++;
 			continue;
 		}
@@ -893,6 +896,9 @@ static int mxser_init(void)
 			if (mxser_initbrd(m, &hwconf) < 0)
 				continue;
 			m++;
+			/* Keep an extra reference if we succeeded. It will
+			   be returned at unload time */
+			pci_dev_get(pdev);
 		}
 	}
 #endif
@@ -994,7 +1000,7 @@ static int mxser_open(struct tty_struct *tty, struct file *filp)
 		mxser_change_speed(info, NULL);
 	}
 
-	info->session = current->signal->session;
+	info->session = process_session(current);
 	info->pgrp = process_group(current);
 
 	/*
@@ -1745,7 +1751,7 @@ static void mxser_unthrottle(struct tty_struct *tty)
 	/* MX_UNLOCK(&info->slock); */
 }
 
-static void mxser_set_termios(struct tty_struct *tty, struct termios *old_termios)
+static void mxser_set_termios(struct tty_struct *tty, struct ktermios *old_termios)
 {
 	struct mxser_struct *info = tty->driver_data;
 	unsigned long flags;
@@ -2537,7 +2543,7 @@ static void mxser_shutdown(struct mxser_struct *info)
  * This routine is called to set the UART divisor registers to match
  * the specified baud rate for a serial port.
  */
-static int mxser_change_speed(struct mxser_struct *info, struct termios *old_termios)
+static int mxser_change_speed(struct mxser_struct *info, struct ktermios *old_termios)
 {
 	unsigned cflag, cval, fcr;
 	int ret = 0;
diff --git a/drivers/char/mxser_new.c b/drivers/char/mxser_new.c
new file mode 100644
index 000000000000..efa8076c33e0
--- /dev/null
+++ b/drivers/char/mxser_new.c
@@ -0,0 +1,2804 @@
+/*
+ *          mxser.c  -- MOXA Smartio/Industio family multiport serial driver.
+ *
+ *      Copyright (C) 1999-2006  Moxa Technologies (support@moxa.com.tw).
+ *	Copyright (C) 2006       Jiri Slaby <jirislaby@gmail.com>
+ *
+ *      This code is loosely based on the 1.8 moxa driver which is based on
+ *	Linux serial driver, written by Linus Torvalds, Theodore T'so and
+ *	others.
+ *
+ *      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.
+ *
+ *	Fed through a cleanup, indent and remove of non 2.6 code by Alan Cox
+ *	<alan@redhat.com>. The original 1.8 code is available on www.moxa.com.
+ *	- Fixed x86_64 cleanness
+ *	- Fixed sleep with spinlock held in mxser_send_break
+ */
+
+#include <linux/module.h>
+#include <linux/autoconf.h>
+#include <linux/errno.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/timer.h>
+#include <linux/interrupt.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+#include <linux/serial.h>
+#include <linux/serial_reg.h>
+#include <linux/major.h>
+#include <linux/string.h>
+#include <linux/fcntl.h>
+#include <linux/ptrace.h>
+#include <linux/gfp.h>
+#include <linux/ioport.h>
+#include <linux/mm.h>
+#include <linux/smp_lock.h>
+#include <linux/delay.h>
+#include <linux/pci.h>
+
+#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/bitops.h>
+#include <asm/uaccess.h>
+
+#include "mxser_new.h"
+
+#define	MXSER_VERSION	"2.0"
+#define	MXSERMAJOR	 174
+#define	MXSERCUMAJOR	 175
+
+#define	MXSER_EVENT_TXLOW	1
+
+#define MXSER_BOARDS		4	/* Max. boards */
+#define MXSER_PORTS_PER_BOARD	8	/* Max. ports per board */
+#define MXSER_PORTS		(MXSER_BOARDS * MXSER_PORTS_PER_BOARD)
+#define MXSER_ISR_PASS_LIMIT	99999L
+
+#define	MXSER_ERR_IOADDR	-1
+#define	MXSER_ERR_IRQ		-2
+#define	MXSER_ERR_IRQ_CONFLIT	-3
+#define	MXSER_ERR_VECTOR	-4
+
+#define WAKEUP_CHARS		256
+
+#define UART_MCR_AFE		0x20
+#define UART_LSR_SPECIAL	0x1E
+
+#define RELEVANT_IFLAG(iflag)	(iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK|\
+					  IXON|IXOFF))
+
+#define C168_ASIC_ID    1
+#define C104_ASIC_ID    2
+#define C102_ASIC_ID	0xB
+#define CI132_ASIC_ID	4
+#define CI134_ASIC_ID	3
+#define CI104J_ASIC_ID  5
+
+#define MXSER_HIGHBAUD	1
+#define MXSER_HAS2	2
+
+/* This is only for PCI */
+static const struct {
+	int type;
+	int tx_fifo;
+	int rx_fifo;
+	int xmit_fifo_size;
+	int rx_high_water;
+	int rx_trigger;
+	int rx_low_water;
+	long max_baud;
+} Gpci_uart_info[] = {
+	{MOXA_OTHER_UART, 16, 16, 16, 14, 14, 1, 921600L},
+	{MOXA_MUST_MU150_HWID, 64, 64, 64, 48, 48, 16, 230400L},
+	{MOXA_MUST_MU860_HWID, 128, 128, 128, 96, 96, 32, 921600L}
+};
+#define UART_INFO_NUM	ARRAY_SIZE(Gpci_uart_info)
+
+struct mxser_cardinfo {
+	unsigned int nports;
+	char *name;
+	unsigned int flags;
+};
+
+static const struct mxser_cardinfo mxser_cards[] = {
+	{ 8, "C168 series", },			/* C168-ISA */
+	{ 4, "C104 series", },			/* C104-ISA */
+	{ 4, "CI-104J series", },		/* CI104J */
+	{ 8, "C168H/PCI series", },		/* C168-PCI */
+	{ 4, "C104H/PCI series", },		/* C104-PCI */
+	{ 4, "C102 series", MXSER_HAS2 },	/* C102-ISA */
+	{ 4, "CI-132 series", MXSER_HAS2 },	/* CI132 */
+	{ 4, "CI-134 series", },		/* CI134 */
+	{ 2, "CP-132 series", },		/* CP132 */
+	{ 4, "CP-114 series", },		/* CP114 */
+	{ 4, "CT-114 series", },		/* CT114 */
+	{ 2, "CP-102 series", MXSER_HIGHBAUD },	/* CP102 */
+	{ 4, "CP-104U series", },		/* CP104U */
+	{ 8, "CP-168U series", },		/* CP168U */
+	{ 2, "CP-132U series", },		/* CP132U */
+	{ 4, "CP-134U series", },		/* CP134U */
+	{ 4, "CP-104JU series", },		/* CP104JU */
+	{ 8, "Moxa UC7000 Serial", },		/* RC7000 */
+	{ 8, "CP-118U series", },		/* CP118U */
+	{ 2, "CP-102UL series", },		/* CP102UL */
+	{ 2, "CP-102U series", },		/* CP102U */
+	{ 8, "CP-118EL series", },		/* CP118EL */
+	{ 8, "CP-168EL series", },		/* CP168EL */
+	{ 4, "CP-104EL series", }		/* CP104EL */
+};
+
+/* driver_data correspond to the lines in the structure above
+   see also ISA probe function before you change something */
+static struct pci_device_id mxser_pcibrds[] = {
+	{ PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_C168),
+		.driver_data = 3 },
+	{ PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_C104),
+		.driver_data = 4 },
+	{ PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP132),
+		.driver_data = 8 },
+	{ PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP114),
+		.driver_data = 9 },
+	{ PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CT114),
+		.driver_data = 10 },
+	{ PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP102),
+		.driver_data = 11 },
+	{ PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP104U),
+		.driver_data = 12 },
+	{ PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP168U),
+		.driver_data = 13 },
+	{ PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP132U),
+		.driver_data = 14 },
+	{ PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP134U),
+		.driver_data = 15 },
+	{ PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP104JU),
+		.driver_data = 16 },
+	{ PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_RC7000),
+		.driver_data = 17 },
+	{ PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP118U),
+		.driver_data = 18 },
+	{ PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP102UL),
+		.driver_data = 19 },
+	{ PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP102U),
+		.driver_data = 20 },
+	{ PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP118EL),
+		.driver_data = 21 },
+	{ PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP168EL),
+		.driver_data = 22 },
+	{ PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP104EL),
+		.driver_data = 23 },
+	{ }
+};
+MODULE_DEVICE_TABLE(pci, mxser_pcibrds);
+
+static int ioaddr[MXSER_BOARDS] = { 0, 0, 0, 0 };
+static int ttymajor = MXSERMAJOR;
+static int calloutmajor = MXSERCUMAJOR;
+
+/* Variables for insmod */
+
+MODULE_AUTHOR("Casper Yang");
+MODULE_DESCRIPTION("MOXA Smartio/Industio Family Multiport Board Device Driver");
+module_param_array(ioaddr, int, NULL, 0);
+module_param(ttymajor, int, 0);
+MODULE_LICENSE("GPL");
+
+struct mxser_log {
+	int tick;
+	unsigned long rxcnt[MXSER_PORTS];
+	unsigned long txcnt[MXSER_PORTS];
+};
+
+
+struct mxser_mon {
+	unsigned long rxcnt;
+	unsigned long txcnt;
+	unsigned long up_rxcnt;
+	unsigned long up_txcnt;
+	int modem_status;
+	unsigned char hold_reason;
+};
+
+struct mxser_mon_ext {
+	unsigned long rx_cnt[32];
+	unsigned long tx_cnt[32];
+	unsigned long up_rxcnt[32];
+	unsigned long up_txcnt[32];
+	int modem_status[32];
+
+	long baudrate[32];
+	int databits[32];
+	int stopbits[32];
+	int parity[32];
+	int flowctrl[32];
+	int fifo[32];
+	int iftype[32];
+};
+
+struct mxser_board;
+
+struct mxser_port {
+	struct mxser_board *board;
+	struct tty_struct *tty;
+
+	unsigned long ioaddr;
+	unsigned long opmode_ioaddr;
+	int max_baud;
+
+	int rx_high_water;
+	int rx_trigger;		/* Rx fifo trigger level */
+	int rx_low_water;
+	int baud_base;		/* max. speed */
+	long realbaud;
+	int type;		/* UART type */
+	int flags;		/* defined in tty.h */
+	long session;		/* Session of opening process */
+	long pgrp;		/* pgrp of opening process */
+
+	int x_char;		/* xon/xoff character */
+	int IER;		/* Interrupt Enable Register */
+	int MCR;		/* Modem control register */
+
+	unsigned char stop_rx;
+	unsigned char ldisc_stop_rx;
+
+	int custom_divisor;
+	int close_delay;
+	unsigned short closing_wait;
+	unsigned char err_shadow;
+	unsigned long event;
+
+	int count;		/* # of fd on device */
+	int blocked_open;	/* # of blocked opens */
+	struct async_icount icount; /* kernel counters for 4 input interrupts */
+	int timeout;
+
+	int read_status_mask;
+	int ignore_status_mask;
+	int xmit_fifo_size;
+	unsigned char *xmit_buf;
+	int xmit_head;
+	int xmit_tail;
+	int xmit_cnt;
+
+	struct ktermios normal_termios;
+	struct ktermios callout_termios;
+
+	struct mxser_mon mon_data;
+
+	spinlock_t slock;
+	struct work_struct tqueue;
+	wait_queue_head_t open_wait;
+	wait_queue_head_t close_wait;
+	wait_queue_head_t delta_msr_wait;
+};
+
+struct mxser_board {
+	unsigned int idx;
+	int irq;
+	const struct mxser_cardinfo *info;
+	unsigned long vector;
+	unsigned long vector_mask;
+
+	int chip_flag;
+	int uart_type;
+
+	struct mxser_port ports[MXSER_PORTS_PER_BOARD];
+};
+
+struct mxser_mstatus {
+	tcflag_t cflag;
+	int cts;
+	int dsr;
+	int ri;
+	int dcd;
+};
+
+static struct mxser_mstatus GMStatus[MXSER_PORTS];
+
+static int mxserBoardCAP[MXSER_BOARDS] = {
+	0, 0, 0, 0
+	/*  0x180, 0x280, 0x200, 0x320 */
+};
+
+static struct mxser_board mxser_boards[MXSER_BOARDS];
+static struct tty_driver *mxvar_sdriver;
+static struct mxser_log mxvar_log;
+static int mxvar_diagflag;
+static unsigned char mxser_msr[MXSER_PORTS + 1];
+static struct mxser_mon_ext mon_data_ext;
+static int mxser_set_baud_method[MXSER_PORTS + 1];
+static spinlock_t gm_lock;
+
+static int CheckIsMoxaMust(int io)
+{
+	u8 oldmcr, hwid;
+	int i;
+
+	outb(0, io + UART_LCR);
+	DISABLE_MOXA_MUST_ENCHANCE_MODE(io);
+	oldmcr = inb(io + UART_MCR);
+	outb(0, io + UART_MCR);
+	SET_MOXA_MUST_XON1_VALUE(io, 0x11);
+	if ((hwid = inb(io + UART_MCR)) != 0) {
+		outb(oldmcr, io + UART_MCR);
+		return MOXA_OTHER_UART;
+	}
+
+	GET_MOXA_MUST_HARDWARE_ID(io, &hwid);
+	for (i = 1; i < UART_INFO_NUM; i++) { /* 0 = OTHER_UART */
+		if (hwid == Gpci_uart_info[i].type)
+			return (int)hwid;
+	}
+	return MOXA_OTHER_UART;
+}
+
+static void process_txrx_fifo(struct mxser_port *info)
+{
+	int i;
+
+	if ((info->type == PORT_16450) || (info->type == PORT_8250)) {
+		info->rx_trigger = 1;
+		info->rx_high_water = 1;
+		info->rx_low_water = 1;
+		info->xmit_fifo_size = 1;
+	} else
+		for (i = 0; i < UART_INFO_NUM; i++)
+			if (info->board->chip_flag == Gpci_uart_info[i].type) {
+				info->rx_trigger = Gpci_uart_info[i].rx_trigger;
+				info->rx_low_water = Gpci_uart_info[i].rx_low_water;
+				info->rx_high_water = Gpci_uart_info[i].rx_high_water;
+				info->xmit_fifo_size = Gpci_uart_info[i].xmit_fifo_size;
+				break;
+			}
+}
+
+static void mxser_do_softint(struct work_struct *work)
+{
+	struct mxser_port *info = container_of(work, struct mxser_port, tqueue);
+	struct tty_struct *tty = info->tty;
+
+	if (test_and_clear_bit(MXSER_EVENT_TXLOW, &info->event))
+		tty_wakeup(tty);
+}
+
+static unsigned char mxser_get_msr(int baseaddr, int mode, int port)
+{
+	unsigned char status = 0;
+
+	status = inb(baseaddr + UART_MSR);
+
+	mxser_msr[port] &= 0x0F;
+	mxser_msr[port] |= status;
+	status = mxser_msr[port];
+	if (mode)
+		mxser_msr[port] = 0;
+
+	return status;
+}
+
+static int mxser_block_til_ready(struct tty_struct *tty, struct file *filp,
+		struct mxser_port *port)
+{
+	DECLARE_WAITQUEUE(wait, current);
+	int retval;
+	int do_clocal = 0;
+	unsigned long flags;
+
+	/*
+	 * 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) ||
+			test_bit(TTY_IO_ERROR, &tty->flags)) {
+		port->flags |= ASYNC_NORMAL_ACTIVE;
+		return 0;
+	}
+
+	if (tty->termios->c_cflag & CLOCAL)
+		do_clocal = 1;
+
+	/*
+	 * Block waiting for the carrier detect and the line to become
+	 * free (i.e., not in use by the callout).  While we are in
+	 * this loop, port->count is dropped by one, so that
+	 * mxser_close() knows when to free things.  We restore it upon
+	 * exit, either normal or abnormal.
+	 */
+	retval = 0;
+	add_wait_queue(&port->open_wait, &wait);
+
+	spin_lock_irqsave(&port->slock, flags);
+	if (!tty_hung_up_p(filp))
+		port->count--;
+	spin_unlock_irqrestore(&port->slock, flags);
+	port->blocked_open++;
+	while (1) {
+		spin_lock_irqsave(&port->slock, flags);
+		outb(inb(port->ioaddr + UART_MCR) |
+			UART_MCR_DTR | UART_MCR_RTS, port->ioaddr + UART_MCR);
+		spin_unlock_irqrestore(&port->slock, flags);
+		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 ||
+				(inb(port->ioaddr + UART_MSR) & UART_MSR_DCD)))
+			break;
+		if (signal_pending(current)) {
+			retval = -ERESTARTSYS;
+			break;
+		}
+		schedule();
+	}
+	set_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;
+	return 0;
+}
+
+static int mxser_set_baud(struct mxser_port *info, long newspd)
+{
+	int quot = 0;
+	unsigned char cval;
+	int ret = 0;
+	unsigned long flags;
+
+	if (!info->tty || !info->tty->termios)
+		return ret;
+
+	if (!(info->ioaddr))
+		return ret;
+
+	if (newspd > info->max_baud)
+		return 0;
+
+	info->realbaud = newspd;
+	if (newspd == 134) {
+		quot = (2 * info->baud_base / 269);
+	} else if (newspd) {
+		quot = info->baud_base / newspd;
+		if (quot == 0)
+			quot = 1;
+	} else {
+		quot = 0;
+	}
+
+	info->timeout = ((info->xmit_fifo_size * HZ * 10 * quot) / info->baud_base);
+	info->timeout += HZ / 50;	/* Add .02 seconds of slop */
+
+	if (quot) {
+		spin_lock_irqsave(&info->slock, flags);
+		info->MCR |= UART_MCR_DTR;
+		outb(info->MCR, info->ioaddr + UART_MCR);
+		spin_unlock_irqrestore(&info->slock, flags);
+	} else {
+		spin_lock_irqsave(&info->slock, flags);
+		info->MCR &= ~UART_MCR_DTR;
+		outb(info->MCR, info->ioaddr + UART_MCR);
+		spin_unlock_irqrestore(&info->slock, flags);
+		return ret;
+	}
+
+	cval = inb(info->ioaddr + UART_LCR);
+
+	outb(cval | UART_LCR_DLAB, info->ioaddr + UART_LCR);	/* set DLAB */
+
+	outb(quot & 0xff, info->ioaddr + UART_DLL);	/* LS of divisor */
+	outb(quot >> 8, info->ioaddr + UART_DLM);	/* MS of divisor */
+	outb(cval, info->ioaddr + UART_LCR);	/* reset DLAB */
+
+
+	return ret;
+}
+
+/*
+ * This routine is called to set the UART divisor registers to match
+ * the specified baud rate for a serial port.
+ */
+static int mxser_change_speed(struct mxser_port *info,
+		struct ktermios *old_termios)
+{
+	unsigned cflag, cval, fcr;
+	int ret = 0;
+	unsigned char status;
+	long baud;
+	unsigned long flags;
+
+	if (!info->tty || !info->tty->termios)
+		return ret;
+	cflag = info->tty->termios->c_cflag;
+	if (!(info->ioaddr))
+		return ret;
+
+	if (mxser_set_baud_method[info->tty->index] == 0) {
+		baud = tty_get_baud_rate(info->tty);
+		mxser_set_baud(info, baud);
+	}
+
+	/* byte size and parity */
+	switch (cflag & CSIZE) {
+	case CS5:
+		cval = 0x00;
+		break;
+	case CS6:
+		cval = 0x01;
+		break;
+	case CS7:
+		cval = 0x02;
+		break;
+	case CS8:
+		cval = 0x03;
+		break;
+	default:
+		cval = 0x00;
+		break;		/* too keep GCC shut... */
+	}
+	if (cflag & CSTOPB)
+		cval |= 0x04;
+	if (cflag & PARENB)
+		cval |= UART_LCR_PARITY;
+	if (!(cflag & PARODD))
+		cval |= UART_LCR_EPAR;
+	if (cflag & CMSPAR)
+		cval |= UART_LCR_SPAR;
+
+	if ((info->type == PORT_8250) || (info->type == PORT_16450)) {
+		if (info->board->chip_flag) {
+			fcr = UART_FCR_ENABLE_FIFO;
+			fcr |= MOXA_MUST_FCR_GDA_MODE_ENABLE;
+			SET_MOXA_MUST_FIFO_VALUE(info);
+		} else
+			fcr = 0;
+	} else {
+		fcr = UART_FCR_ENABLE_FIFO;
+		if (info->board->chip_flag) {
+			fcr |= MOXA_MUST_FCR_GDA_MODE_ENABLE;
+			SET_MOXA_MUST_FIFO_VALUE(info);
+		} else {
+			switch (info->rx_trigger) {
+			case 1:
+				fcr |= UART_FCR_TRIGGER_1;
+				break;
+			case 4:
+				fcr |= UART_FCR_TRIGGER_4;
+				break;
+			case 8:
+				fcr |= UART_FCR_TRIGGER_8;
+				break;
+			default:
+				fcr |= UART_FCR_TRIGGER_14;
+				break;
+			}
+		}
+	}
+
+	/* CTS flow control flag and modem status interrupts */
+	info->IER &= ~UART_IER_MSI;
+	info->MCR &= ~UART_MCR_AFE;
+	if (cflag & CRTSCTS) {
+		info->flags |= ASYNC_CTS_FLOW;
+		info->IER |= UART_IER_MSI;
+		if ((info->type == PORT_16550A) || (info->board->chip_flag)) {
+			info->MCR |= UART_MCR_AFE;
+		} else {
+			status = inb(info->ioaddr + UART_MSR);
+			if (info->tty->hw_stopped) {
+				if (status & UART_MSR_CTS) {
+					info->tty->hw_stopped = 0;
+					if (info->type != PORT_16550A &&
+							!info->board->chip_flag) {
+						outb(info->IER & ~UART_IER_THRI,
+							info->ioaddr +
+							UART_IER);
+						info->IER |= UART_IER_THRI;
+						outb(info->IER, info->ioaddr +
+								UART_IER);
+					}
+					set_bit(MXSER_EVENT_TXLOW, &info->event);
+					schedule_work(&info->tqueue);				}
+			} else {
+				if (!(status & UART_MSR_CTS)) {
+					info->tty->hw_stopped = 1;
+					if ((info->type != PORT_16550A) &&
+							(!info->board->chip_flag)) {
+						info->IER &= ~UART_IER_THRI;
+						outb(info->IER, info->ioaddr +
+								UART_IER);
+					}
+				}
+			}
+		}
+	} else {
+		info->flags &= ~ASYNC_CTS_FLOW;
+	}
+	outb(info->MCR, info->ioaddr + UART_MCR);
+	if (cflag & CLOCAL) {
+		info->flags &= ~ASYNC_CHECK_CD;
+	} else {
+		info->flags |= ASYNC_CHECK_CD;
+		info->IER |= UART_IER_MSI;
+	}
+	outb(info->IER, info->ioaddr + UART_IER);
+
+	/*
+	 * Set up parity check flag
+	 */
+	info->read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR;
+	if (I_INPCK(info->tty))
+		info->read_status_mask |= UART_LSR_FE | UART_LSR_PE;
+	if (I_BRKINT(info->tty) || I_PARMRK(info->tty))
+		info->read_status_mask |= UART_LSR_BI;
+
+	info->ignore_status_mask = 0;
+
+	if (I_IGNBRK(info->tty)) {
+		info->ignore_status_mask |= UART_LSR_BI;
+		info->read_status_mask |= UART_LSR_BI;
+		/*
+		 * If we're ignore parity and break indicators, ignore
+		 * overruns too.  (For real raw support).
+		 */
+		if (I_IGNPAR(info->tty)) {
+			info->ignore_status_mask |=
+						UART_LSR_OE |
+						UART_LSR_PE |
+						UART_LSR_FE;
+			info->read_status_mask |=
+						UART_LSR_OE |
+						UART_LSR_PE |
+						UART_LSR_FE;
+		}
+	}
+	if (info->board->chip_flag) {
+		spin_lock_irqsave(&info->slock, flags);
+		SET_MOXA_MUST_XON1_VALUE(info->ioaddr, START_CHAR(info->tty));
+		SET_MOXA_MUST_XOFF1_VALUE(info->ioaddr, STOP_CHAR(info->tty));
+		if (I_IXON(info->tty)) {
+			ENABLE_MOXA_MUST_RX_SOFTWARE_FLOW_CONTROL(info->ioaddr);
+		} else {
+			DISABLE_MOXA_MUST_RX_SOFTWARE_FLOW_CONTROL(info->ioaddr);
+		}
+		if (I_IXOFF(info->tty)) {
+			ENABLE_MOXA_MUST_TX_SOFTWARE_FLOW_CONTROL(info->ioaddr);
+		} else {
+			DISABLE_MOXA_MUST_TX_SOFTWARE_FLOW_CONTROL(info->ioaddr);
+		}
+		spin_unlock_irqrestore(&info->slock, flags);
+	}
+
+
+	outb(fcr, info->ioaddr + UART_FCR);	/* set fcr */
+	outb(cval, info->ioaddr + UART_LCR);
+
+	return ret;
+}
+
+static void mxser_check_modem_status(struct mxser_port *port, int status)
+{
+	/* update input line counters */
+	if (status & UART_MSR_TERI)
+		port->icount.rng++;
+	if (status & UART_MSR_DDSR)
+		port->icount.dsr++;
+	if (status & UART_MSR_DDCD)
+		port->icount.dcd++;
+	if (status & UART_MSR_DCTS)
+		port->icount.cts++;
+	port->mon_data.modem_status = status;
+	wake_up_interruptible(&port->delta_msr_wait);
+
+	if ((port->flags & ASYNC_CHECK_CD) && (status & UART_MSR_DDCD)) {
+		if (status & UART_MSR_DCD)
+			wake_up_interruptible(&port->open_wait);
+		schedule_work(&port->tqueue);
+	}
+
+	if (port->flags & ASYNC_CTS_FLOW) {
+		if (port->tty->hw_stopped) {
+			if (status & UART_MSR_CTS) {
+				port->tty->hw_stopped = 0;
+
+				if ((port->type != PORT_16550A) &&
+						(!port->board->chip_flag)) {
+					outb(port->IER & ~UART_IER_THRI,
+						port->ioaddr + UART_IER);
+					port->IER |= UART_IER_THRI;
+					outb(port->IER, port->ioaddr +
+							UART_IER);
+				}
+				set_bit(MXSER_EVENT_TXLOW, &port->event);
+				schedule_work(&port->tqueue);
+			}
+		} else {
+			if (!(status & UART_MSR_CTS)) {
+				port->tty->hw_stopped = 1;
+				if (port->type != PORT_16550A &&
+						!port->board->chip_flag) {
+					port->IER &= ~UART_IER_THRI;
+					outb(port->IER, port->ioaddr +
+							UART_IER);
+				}
+			}
+		}
+	}
+}
+
+static int mxser_startup(struct mxser_port *info)
+{
+	unsigned long page;
+	unsigned long flags;
+
+	page = __get_free_page(GFP_KERNEL);
+	if (!page)
+		return -ENOMEM;
+
+	spin_lock_irqsave(&info->slock, flags);
+
+	if (info->flags & ASYNC_INITIALIZED) {
+		free_page(page);
+		spin_unlock_irqrestore(&info->slock, flags);
+		return 0;
+	}
+
+	if (!info->ioaddr || !info->type) {
+		if (info->tty)
+			set_bit(TTY_IO_ERROR, &info->tty->flags);
+		free_page(page);
+		spin_unlock_irqrestore(&info->slock, flags);
+		return 0;
+	}
+	if (info->xmit_buf)
+		free_page(page);
+	else
+		info->xmit_buf = (unsigned char *) page;
+
+	/*
+	 * Clear the FIFO buffers and disable them
+	 * (they will be reenabled in mxser_change_speed())
+	 */
+	if (info->board->chip_flag)
+		outb((UART_FCR_CLEAR_RCVR |
+			UART_FCR_CLEAR_XMIT |
+			MOXA_MUST_FCR_GDA_MODE_ENABLE), info->ioaddr + UART_FCR);
+	else
+		outb((UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT),
+			info->ioaddr + UART_FCR);
+
+	/*
+	 * At this point there's no way the LSR could still be 0xFF;
+	 * if it is, then bail out, because there's likely no UART
+	 * here.
+	 */
+	if (inb(info->ioaddr + UART_LSR) == 0xff) {
+		spin_unlock_irqrestore(&info->slock, flags);
+		if (capable(CAP_SYS_ADMIN)) {
+			if (info->tty)
+				set_bit(TTY_IO_ERROR, &info->tty->flags);
+			return 0;
+		} else
+			return -ENODEV;
+	}
+
+	/*
+	 * Clear the interrupt registers.
+	 */
+	(void) inb(info->ioaddr + UART_LSR);
+	(void) inb(info->ioaddr + UART_RX);
+	(void) inb(info->ioaddr + UART_IIR);
+	(void) inb(info->ioaddr + UART_MSR);
+
+	/*
+	 * Now, initialize the UART
+	 */
+	outb(UART_LCR_WLEN8, info->ioaddr + UART_LCR);	/* reset DLAB */
+	info->MCR = UART_MCR_DTR | UART_MCR_RTS;
+	outb(info->MCR, info->ioaddr + UART_MCR);
+
+	/*
+	 * Finally, enable interrupts
+	 */
+	info->IER = UART_IER_MSI | UART_IER_RLSI | UART_IER_RDI;
+
+	if (info->board->chip_flag)
+		info->IER |= MOXA_MUST_IER_EGDAI;
+	outb(info->IER, info->ioaddr + UART_IER);	/* enable interrupts */
+
+	/*
+	 * And clear the interrupt registers again for luck.
+	 */
+	(void) inb(info->ioaddr + UART_LSR);
+	(void) inb(info->ioaddr + UART_RX);
+	(void) inb(info->ioaddr + UART_IIR);
+	(void) inb(info->ioaddr + UART_MSR);
+
+	if (info->tty)
+		clear_bit(TTY_IO_ERROR, &info->tty->flags);
+	info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
+
+	/*
+	 * and set the speed of the serial port
+	 */
+	spin_unlock_irqrestore(&info->slock, flags);
+	mxser_change_speed(info, NULL);
+
+	info->flags |= ASYNC_INITIALIZED;
+	return 0;
+}
+
+/*
+ * This routine will shutdown a serial port; interrupts maybe disabled, and
+ * DTR is dropped if the hangup on close termio flag is on.
+ */
+static void mxser_shutdown(struct mxser_port *info)
+{
+	unsigned long flags;
+
+	if (!(info->flags & ASYNC_INITIALIZED))
+		return;
+
+	spin_lock_irqsave(&info->slock, flags);
+
+	/*
+	 * clear delta_msr_wait queue to avoid mem leaks: we may free the irq
+	 * here so the queue might never be waken up
+	 */
+	wake_up_interruptible(&info->delta_msr_wait);
+
+	/*
+	 * Free the IRQ, if necessary
+	 */
+	if (info->xmit_buf) {
+		free_page((unsigned long) info->xmit_buf);
+		info->xmit_buf = NULL;
+	}
+
+	info->IER = 0;
+	outb(0x00, info->ioaddr + UART_IER);
+
+	if (!info->tty || (info->tty->termios->c_cflag & HUPCL))
+		info->MCR &= ~(UART_MCR_DTR | UART_MCR_RTS);
+	outb(info->MCR, info->ioaddr + UART_MCR);
+
+	/* clear Rx/Tx FIFO's */
+	if (info->board->chip_flag)
+		outb(UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT |
+				MOXA_MUST_FCR_GDA_MODE_ENABLE,
+				info->ioaddr + UART_FCR);
+	else
+		outb(UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT,
+			info->ioaddr + UART_FCR);
+
+	/* read data port to reset things */
+	(void) inb(info->ioaddr + UART_RX);
+
+	if (info->tty)
+		set_bit(TTY_IO_ERROR, &info->tty->flags);
+
+	info->flags &= ~ASYNC_INITIALIZED;
+
+	if (info->board->chip_flag)
+		SET_MOXA_MUST_NO_SOFTWARE_FLOW_CONTROL(info->ioaddr);
+
+	spin_unlock_irqrestore(&info->slock, flags);
+}
+
+/*
+ * This routine is called whenever a serial port is opened.  It
+ * enables interrupts for a serial port, linking in its async structure into
+ * the IRQ chain.   It also performs the serial-specific
+ * initialization for the tty structure.
+ */
+static int mxser_open(struct tty_struct *tty, struct file *filp)
+{
+	struct mxser_port *info;
+	int retval, line;
+
+	/* initialize driver_data in case something fails */
+	tty->driver_data = NULL;
+
+	line = tty->index;
+	if (line == MXSER_PORTS)
+		return 0;
+	if (line < 0 || line > MXSER_PORTS)
+		return -ENODEV;
+	info = &mxser_boards[line / MXSER_PORTS_PER_BOARD].ports[line % MXSER_PORTS_PER_BOARD];
+	if (!info->ioaddr)
+		return -ENODEV;
+
+	tty->driver_data = info;
+	info->tty = tty;
+	/*
+	 * Start up serial port
+	 */
+	info->count++;
+	retval = mxser_startup(info);
+	if (retval)
+		return retval;
+
+	retval = mxser_block_til_ready(tty, filp, info);
+	if (retval)
+		return retval;
+
+	if ((info->count == 1) && (info->flags & ASYNC_SPLIT_TERMIOS)) {
+		if (tty->driver->subtype == SERIAL_TYPE_NORMAL)
+			*tty->termios = info->normal_termios;
+		else
+			*tty->termios = info->callout_termios;
+		mxser_change_speed(info, NULL);
+	}
+
+	info->session = process_session(current);
+	info->pgrp = process_group(current);
+
+	/* unmark here for very high baud rate (ex. 921600 bps) used */
+	tty->low_latency = 1;
+	return 0;
+}
+
+/*
+ * This routine is called when the serial port gets closed.  First, we
+ * wait for the last remaining data to be sent.  Then, we unlink its
+ * async structure from the interrupt chain if necessary, and we free
+ * that IRQ if nothing is left in the chain.
+ */
+static void mxser_close(struct tty_struct *tty, struct file *filp)
+{
+	struct mxser_port *info = tty->driver_data;
+
+	unsigned long timeout;
+	unsigned long flags;
+
+	if (tty->index == MXSER_PORTS)
+		return;
+	if (!info)
+		return;
+
+	spin_lock_irqsave(&info->slock, flags);
+
+	if (tty_hung_up_p(filp)) {
+		spin_unlock_irqrestore(&info->slock, flags);
+		return;
+	}
+	if ((tty->count == 1) && (info->count != 1)) {
+		/*
+		 * Uh, oh.  tty->count is 1, which means that the tty
+		 * structure will be freed.  Info->count should always
+		 * be one in these conditions.  If it's greater than
+		 * one, we've got real problems, since it means the
+		 * serial port won't be shutdown.
+		 */
+		printk(KERN_ERR "mxser_close: bad serial port count; "
+			"tty->count is 1, info->count is %d\n", info->count);
+		info->count = 1;
+	}
+	if (--info->count < 0) {
+		printk(KERN_ERR "mxser_close: bad serial port count for "
+			"ttys%d: %d\n", tty->index, info->count);
+		info->count = 0;
+	}
+	if (info->count) {
+		spin_unlock_irqrestore(&info->slock, flags);
+		return;
+	}
+	info->flags |= ASYNC_CLOSING;
+	spin_unlock_irqrestore(&info->slock, flags);
+	/*
+	 * Save the termios structure, since this port may have
+	 * separate termios for callout and dialin.
+	 */
+	if (info->flags & ASYNC_NORMAL_ACTIVE)
+		info->normal_termios = *tty->termios;
+	/*
+	 * Now we wait for the transmit buffer to clear; and we notify
+	 * the line discipline to only process XON/XOFF characters.
+	 */
+	tty->closing = 1;
+	if (info->closing_wait != ASYNC_CLOSING_WAIT_NONE)
+		tty_wait_until_sent(tty, info->closing_wait);
+	/*
+	 * At this point we stop accepting input.  To do this, we
+	 * disable the receive line status interrupts, and tell the
+	 * interrupt driver to stop checking the data ready bit in the
+	 * line status register.
+	 */
+	info->IER &= ~UART_IER_RLSI;
+	if (info->board->chip_flag)
+		info->IER &= ~MOXA_MUST_RECV_ISR;
+
+	if (info->flags & ASYNC_INITIALIZED) {
+		outb(info->IER, info->ioaddr + UART_IER);
+		/*
+		 * 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 (!(inb(info->ioaddr + UART_LSR) & UART_LSR_TEMT)) {
+			schedule_timeout_interruptible(5);
+			if (time_after(jiffies, timeout))
+				break;
+		}
+	}
+	mxser_shutdown(info);
+
+	if (tty->driver->flush_buffer)
+		tty->driver->flush_buffer(tty);
+
+	tty_ldisc_flush(tty);
+
+	tty->closing = 0;
+	info->event = 0;
+	info->tty = NULL;
+	if (info->blocked_open) {
+		if (info->close_delay)
+			schedule_timeout_interruptible(info->close_delay);
+		wake_up_interruptible(&info->open_wait);
+	}
+
+	info->flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING);
+	wake_up_interruptible(&info->close_wait);
+
+}
+
+static int mxser_write(struct tty_struct *tty, const unsigned char *buf, int count)
+{
+	int c, total = 0;
+	struct mxser_port *info = tty->driver_data;
+	unsigned long flags;
+
+	if (!info->xmit_buf)
+		return 0;
+
+	while (1) {
+		c = min_t(int, count, min(SERIAL_XMIT_SIZE - info->xmit_cnt - 1,
+					  SERIAL_XMIT_SIZE - info->xmit_head));
+		if (c <= 0)
+			break;
+
+		memcpy(info->xmit_buf + info->xmit_head, buf, c);
+		spin_lock_irqsave(&info->slock, flags);
+		info->xmit_head = (info->xmit_head + c) &
+				  (SERIAL_XMIT_SIZE - 1);
+		info->xmit_cnt += c;
+		spin_unlock_irqrestore(&info->slock, flags);
+
+		buf += c;
+		count -= c;
+		total += c;
+	}
+
+	if (info->xmit_cnt && !tty->stopped) {
+		if (!tty->hw_stopped ||
+				(info->type == PORT_16550A) ||
+				(info->board->chip_flag)) {
+			spin_lock_irqsave(&info->slock, flags);
+			outb(info->IER & ~UART_IER_THRI, info->ioaddr +
+					UART_IER);
+			info->IER |= UART_IER_THRI;
+			outb(info->IER, info->ioaddr + UART_IER);
+			spin_unlock_irqrestore(&info->slock, flags);
+		}
+	}
+	return total;
+}
+
+static void mxser_put_char(struct tty_struct *tty, unsigned char ch)
+{
+	struct mxser_port *info = tty->driver_data;
+	unsigned long flags;
+
+	if (!info->xmit_buf)
+		return;
+
+	if (info->xmit_cnt >= SERIAL_XMIT_SIZE - 1)
+		return;
+
+	spin_lock_irqsave(&info->slock, flags);
+	info->xmit_buf[info->xmit_head++] = ch;
+	info->xmit_head &= SERIAL_XMIT_SIZE - 1;
+	info->xmit_cnt++;
+	spin_unlock_irqrestore(&info->slock, flags);
+	if (!tty->stopped) {
+		if (!tty->hw_stopped ||
+				(info->type == PORT_16550A) ||
+				info->board->chip_flag) {
+			spin_lock_irqsave(&info->slock, flags);
+			outb(info->IER & ~UART_IER_THRI, info->ioaddr + UART_IER);
+			info->IER |= UART_IER_THRI;
+			outb(info->IER, info->ioaddr + UART_IER);
+			spin_unlock_irqrestore(&info->slock, flags);
+		}
+	}
+}
+
+
+static void mxser_flush_chars(struct tty_struct *tty)
+{
+	struct mxser_port *info = tty->driver_data;
+	unsigned long flags;
+
+	if (info->xmit_cnt <= 0 ||
+			tty->stopped ||
+			!info->xmit_buf ||
+			(tty->hw_stopped &&
+			 (info->type != PORT_16550A) &&
+			 (!info->board->chip_flag)
+			))
+		return;
+
+	spin_lock_irqsave(&info->slock, flags);
+
+	outb(info->IER & ~UART_IER_THRI, info->ioaddr + UART_IER);
+	info->IER |= UART_IER_THRI;
+	outb(info->IER, info->ioaddr + UART_IER);
+
+	spin_unlock_irqrestore(&info->slock, flags);
+}
+
+static int mxser_write_room(struct tty_struct *tty)
+{
+	struct mxser_port *info = tty->driver_data;
+	int ret;
+
+	ret = SERIAL_XMIT_SIZE - info->xmit_cnt - 1;
+	if (ret < 0)
+		ret = 0;
+	return ret;
+}
+
+static int mxser_chars_in_buffer(struct tty_struct *tty)
+{
+	struct mxser_port *info = tty->driver_data;
+	return info->xmit_cnt;
+}
+
+static void mxser_flush_buffer(struct tty_struct *tty)
+{
+	struct mxser_port *info = tty->driver_data;
+	char fcr;
+	unsigned long flags;
+
+
+	spin_lock_irqsave(&info->slock, flags);
+	info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
+
+	fcr = inb(info->ioaddr + UART_FCR);
+	outb((fcr | UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT),
+		info->ioaddr + UART_FCR);
+	outb(fcr, info->ioaddr + UART_FCR);
+
+	spin_unlock_irqrestore(&info->slock, flags);
+
+	tty_wakeup(tty);
+}
+
+/*
+ * ------------------------------------------------------------
+ * friends of mxser_ioctl()
+ * ------------------------------------------------------------
+ */
+static int mxser_get_serial_info(struct mxser_port *info,
+		struct serial_struct __user *retinfo)
+{
+	struct serial_struct tmp;
+
+	if (!retinfo)
+		return -EFAULT;
+	memset(&tmp, 0, sizeof(tmp));
+	tmp.type = info->type;
+	tmp.line = info->tty->index;
+	tmp.port = info->ioaddr;
+	tmp.irq = info->board->irq;
+	tmp.flags = info->flags;
+	tmp.baud_base = info->baud_base;
+	tmp.close_delay = info->close_delay;
+	tmp.closing_wait = info->closing_wait;
+	tmp.custom_divisor = info->custom_divisor;
+	tmp.hub6 = 0;
+	if (copy_to_user(retinfo, &tmp, sizeof(*retinfo)))
+		return -EFAULT;
+	return 0;
+}
+
+static int mxser_set_serial_info(struct mxser_port *info,
+		struct serial_struct __user *new_info)
+{
+	struct serial_struct new_serial;
+	unsigned int flags;
+	int retval = 0;
+
+	if (!new_info || !info->ioaddr)
+		return -EFAULT;
+	if (copy_from_user(&new_serial, new_info, sizeof(new_serial)))
+		return -EFAULT;
+
+	if ((new_serial.irq != info->board->irq) ||
+			(new_serial.port != info->ioaddr) ||
+			(new_serial.custom_divisor != info->custom_divisor) ||
+			(new_serial.baud_base != info->baud_base))
+		return -EPERM;
+
+	flags = info->flags & ASYNC_SPD_MASK;
+
+	if (!capable(CAP_SYS_ADMIN)) {
+		if ((new_serial.baud_base != info->baud_base) ||
+				(new_serial.close_delay != info->close_delay) ||
+				((new_serial.flags & ~ASYNC_USR_MASK) != (info->flags & ~ASYNC_USR_MASK)))
+			return -EPERM;
+		info->flags = ((info->flags & ~ASYNC_USR_MASK) |
+				(new_serial.flags & ASYNC_USR_MASK));
+	} else {
+		/*
+		 * OK, past this point, all the error checking has been done.
+		 * At this point, we start making changes.....
+		 */
+		info->flags = ((info->flags & ~ASYNC_FLAGS) |
+				(new_serial.flags & ASYNC_FLAGS));
+		info->close_delay = new_serial.close_delay * HZ / 100;
+		info->closing_wait = new_serial.closing_wait * HZ / 100;
+		info->tty->low_latency =
+				(info->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
+		info->tty->low_latency = 0;
+	}
+
+	info->type = new_serial.type;
+
+	process_txrx_fifo(info);
+
+	if (info->flags & ASYNC_INITIALIZED) {
+		if (flags != (info->flags & ASYNC_SPD_MASK))
+			mxser_change_speed(info, NULL);
+	} else
+		retval = mxser_startup(info);
+
+	return retval;
+}
+
+/*
+ * mxser_get_lsr_info - get line status register info
+ *
+ * Purpose: Let user call ioctl() to get info when the UART physically
+ *	    is emptied.  On bus types like RS485, the transmitter must
+ *	    release the bus after transmitting. This must be done when
+ *	    the transmit shift register is empty, not be done when the
+ *	    transmit holding register is empty.  This functionality
+ *	    allows an RS485 driver to be written in user space.
+ */
+static int mxser_get_lsr_info(struct mxser_port *info,
+		unsigned int __user *value)
+{
+	unsigned char status;
+	unsigned int result;
+	unsigned long flags;
+
+	spin_lock_irqsave(&info->slock, flags);
+	status = inb(info->ioaddr + UART_LSR);
+	spin_unlock_irqrestore(&info->slock, flags);
+	result = ((status & UART_LSR_TEMT) ? TIOCSER_TEMT : 0);
+	return put_user(result, value);
+}
+
+/*
+ * This routine sends a break character out the serial port.
+ */
+static void mxser_send_break(struct mxser_port *info, int duration)
+{
+	unsigned long flags;
+
+	if (!info->ioaddr)
+		return;
+	set_current_state(TASK_INTERRUPTIBLE);
+	spin_lock_irqsave(&info->slock, flags);
+	outb(inb(info->ioaddr + UART_LCR) | UART_LCR_SBC,
+		info->ioaddr + UART_LCR);
+	spin_unlock_irqrestore(&info->slock, flags);
+	schedule_timeout(duration);
+	spin_lock_irqsave(&info->slock, flags);
+	outb(inb(info->ioaddr + UART_LCR) & ~UART_LCR_SBC,
+		info->ioaddr + UART_LCR);
+	spin_unlock_irqrestore(&info->slock, flags);
+}
+
+static int mxser_tiocmget(struct tty_struct *tty, struct file *file)
+{
+	struct mxser_port *info = tty->driver_data;
+	unsigned char control, status;
+	unsigned long flags;
+
+
+	if (tty->index == MXSER_PORTS)
+		return -ENOIOCTLCMD;
+	if (test_bit(TTY_IO_ERROR, &tty->flags))
+		return -EIO;
+
+	control = info->MCR;
+
+	spin_lock_irqsave(&info->slock, flags);
+	status = inb(info->ioaddr + UART_MSR);
+	if (status & UART_MSR_ANY_DELTA)
+		mxser_check_modem_status(info, status);
+	spin_unlock_irqrestore(&info->slock, flags);
+	return ((control & UART_MCR_RTS) ? TIOCM_RTS : 0) |
+		    ((control & UART_MCR_DTR) ? TIOCM_DTR : 0) |
+		    ((status & UART_MSR_DCD) ? TIOCM_CAR : 0) |
+		    ((status & UART_MSR_RI) ? TIOCM_RNG : 0) |
+		    ((status & UART_MSR_DSR) ? TIOCM_DSR : 0) |
+		    ((status & UART_MSR_CTS) ? TIOCM_CTS : 0);
+}
+
+static int mxser_tiocmset(struct tty_struct *tty, struct file *file,
+		unsigned int set, unsigned int clear)
+{
+	struct mxser_port *info = tty->driver_data;
+	unsigned long flags;
+
+
+	if (tty->index == MXSER_PORTS)
+		return -ENOIOCTLCMD;
+	if (test_bit(TTY_IO_ERROR, &tty->flags))
+		return -EIO;
+
+	spin_lock_irqsave(&info->slock, flags);
+
+	if (set & TIOCM_RTS)
+		info->MCR |= UART_MCR_RTS;
+	if (set & TIOCM_DTR)
+		info->MCR |= UART_MCR_DTR;
+
+	if (clear & TIOCM_RTS)
+		info->MCR &= ~UART_MCR_RTS;
+	if (clear & TIOCM_DTR)
+		info->MCR &= ~UART_MCR_DTR;
+
+	outb(info->MCR, info->ioaddr + UART_MCR);
+	spin_unlock_irqrestore(&info->slock, flags);
+	return 0;
+}
+
+static int mxser_program_mode(int port)
+{
+	int id, i, j, n;
+
+	spin_lock(&gm_lock);
+	outb(0, port);
+	outb(0, port);
+	outb(0, port);
+	(void)inb(port);
+	(void)inb(port);
+	outb(0, port);
+	(void)inb(port);
+	spin_unlock(&gm_lock);
+
+	id = inb(port + 1) & 0x1F;
+	if ((id != C168_ASIC_ID) &&
+			(id != C104_ASIC_ID) &&
+			(id != C102_ASIC_ID) &&
+			(id != CI132_ASIC_ID) &&
+			(id != CI134_ASIC_ID) &&
+			(id != CI104J_ASIC_ID))
+		return -1;
+	for (i = 0, j = 0; i < 4; i++) {
+		n = inb(port + 2);
+		if (n == 'M') {
+			j = 1;
+		} else if ((j == 1) && (n == 1)) {
+			j = 2;
+			break;
+		} else
+			j = 0;
+	}
+	if (j != 2)
+		id = -2;
+	return id;
+}
+
+static void mxser_normal_mode(int port)
+{
+	int i, n;
+
+	outb(0xA5, port + 1);
+	outb(0x80, port + 3);
+	outb(12, port + 0);	/* 9600 bps */
+	outb(0, port + 1);
+	outb(0x03, port + 3);	/* 8 data bits */
+	outb(0x13, port + 4);	/* loop back mode */
+	for (i = 0; i < 16; i++) {
+		n = inb(port + 5);
+		if ((n & 0x61) == 0x60)
+			break;
+		if ((n & 1) == 1)
+			(void)inb(port);
+	}
+	outb(0x00, port + 4);
+}
+
+#define CHIP_SK 	0x01	/* Serial Data Clock  in Eprom */
+#define CHIP_DO 	0x02	/* Serial Data Output in Eprom */
+#define CHIP_CS 	0x04	/* Serial Chip Select in Eprom */
+#define CHIP_DI 	0x08	/* Serial Data Input  in Eprom */
+#define EN_CCMD 	0x000	/* Chip's command register     */
+#define EN0_RSARLO	0x008	/* Remote start address reg 0  */
+#define EN0_RSARHI	0x009	/* Remote start address reg 1  */
+#define EN0_RCNTLO	0x00A	/* Remote byte count reg WR    */
+#define EN0_RCNTHI	0x00B	/* Remote byte count reg WR    */
+#define EN0_DCFG	0x00E	/* Data configuration reg WR   */
+#define EN0_PORT	0x010	/* Rcv missed frame error counter RD */
+#define ENC_PAGE0	0x000	/* Select page 0 of chip registers   */
+#define ENC_PAGE3	0x0C0	/* Select page 3 of chip registers   */
+static int mxser_read_register(int port, unsigned short *regs)
+{
+	int i, k, value, id;
+	unsigned int j;
+
+	id = mxser_program_mode(port);
+	if (id < 0)
+		return id;
+	for (i = 0; i < 14; i++) {
+		k = (i & 0x3F) | 0x180;
+		for (j = 0x100; j > 0; j >>= 1) {
+			outb(CHIP_CS, port);
+			if (k & j) {
+				outb(CHIP_CS | CHIP_DO, port);
+				outb(CHIP_CS | CHIP_DO | CHIP_SK, port);	/* A? bit of read */
+			} else {
+				outb(CHIP_CS, port);
+				outb(CHIP_CS | CHIP_SK, port);	/* A? bit of read */
+			}
+		}
+		(void)inb(port);
+		value = 0;
+		for (k = 0, j = 0x8000; k < 16; k++, j >>= 1) {
+			outb(CHIP_CS, port);
+			outb(CHIP_CS | CHIP_SK, port);
+			if (inb(port) & CHIP_DI)
+				value |= j;
+		}
+		regs[i] = value;
+		outb(0, port);
+	}
+	mxser_normal_mode(port);
+	return id;
+}
+
+static int mxser_ioctl_special(unsigned int cmd, void __user *argp)
+{
+	struct mxser_port *port;
+	int result, status;
+	unsigned int i, j;
+
+	switch (cmd) {
+	case MOXA_GET_CONF:
+/*		if (copy_to_user(argp, mxsercfg,
+				sizeof(struct mxser_hwconf) * 4))
+			return -EFAULT;
+		return 0;*/
+		return -ENXIO;
+	case MOXA_GET_MAJOR:
+		if (copy_to_user(argp, &ttymajor, sizeof(int)))
+			return -EFAULT;
+		return 0;
+
+	case MOXA_GET_CUMAJOR:
+		if (copy_to_user(argp, &calloutmajor, sizeof(int)))
+			return -EFAULT;
+		return 0;
+
+	case MOXA_CHKPORTENABLE:
+		result = 0;
+
+		for (i = 0; i < MXSER_BOARDS; i++)
+			for (j = 0; j < MXSER_PORTS_PER_BOARD; j++)
+				if (mxser_boards[i].ports[j].ioaddr)
+					result |= (1 << i);
+
+		return put_user(result, (unsigned long __user *)argp);
+	case MOXA_GETDATACOUNT:
+		if (copy_to_user(argp, &mxvar_log, sizeof(mxvar_log)))
+			return -EFAULT;
+		return 0;
+	case MOXA_GETMSTATUS:
+		for (i = 0; i < MXSER_BOARDS; i++)
+			for (j = 0; j < MXSER_PORTS_PER_BOARD; j++) {
+				port = &mxser_boards[i].ports[j];
+
+				GMStatus[i].ri = 0;
+				if (!port->ioaddr) {
+					GMStatus[i].dcd = 0;
+					GMStatus[i].dsr = 0;
+					GMStatus[i].cts = 0;
+					continue;
+				}
+
+				if (!port->tty || !port->tty->termios)
+					GMStatus[i].cflag =
+						port->normal_termios.c_cflag;
+				else
+					GMStatus[i].cflag =
+						port->tty->termios->c_cflag;
+
+				status = inb(port->ioaddr + UART_MSR);
+				if (status & 0x80 /*UART_MSR_DCD */ )
+					GMStatus[i].dcd = 1;
+				else
+					GMStatus[i].dcd = 0;
+
+				if (status & 0x20 /*UART_MSR_DSR */ )
+					GMStatus[i].dsr = 1;
+				else
+					GMStatus[i].dsr = 0;
+
+
+				if (status & 0x10 /*UART_MSR_CTS */ )
+					GMStatus[i].cts = 1;
+				else
+					GMStatus[i].cts = 0;
+			}
+		if (copy_to_user(argp, GMStatus,
+				sizeof(struct mxser_mstatus) * MXSER_PORTS))
+			return -EFAULT;
+		return 0;
+	case MOXA_ASPP_MON_EXT: {
+		int status, p, shiftbit;
+		unsigned long opmode;
+		unsigned cflag, iflag;
+
+		for (i = 0; i < MXSER_BOARDS; i++)
+			for (j = 0; j < MXSER_PORTS_PER_BOARD; j++) {
+				port = &mxser_boards[i].ports[j];
+				if (!port->ioaddr)
+					continue;
+
+				status = mxser_get_msr(port->ioaddr, 0, i);
+
+				if (status & UART_MSR_TERI)
+					port->icount.rng++;
+				if (status & UART_MSR_DDSR)
+					port->icount.dsr++;
+				if (status & UART_MSR_DDCD)
+					port->icount.dcd++;
+				if (status & UART_MSR_DCTS)
+					port->icount.cts++;
+
+				port->mon_data.modem_status = status;
+				mon_data_ext.rx_cnt[i] = port->mon_data.rxcnt;
+				mon_data_ext.tx_cnt[i] = port->mon_data.txcnt;
+				mon_data_ext.up_rxcnt[i] =
+					port->mon_data.up_rxcnt;
+				mon_data_ext.up_txcnt[i] =
+					port->mon_data.up_txcnt;
+				mon_data_ext.modem_status[i] =
+					port->mon_data.modem_status;
+				mon_data_ext.baudrate[i] = port->realbaud;
+
+				if (!port->tty || !port->tty->termios) {
+					cflag = port->normal_termios.c_cflag;
+					iflag = port->normal_termios.c_iflag;
+				} else {
+					cflag = port->tty->termios->c_cflag;
+					iflag = port->tty->termios->c_iflag;
+				}
+
+				mon_data_ext.databits[i] = cflag & CSIZE;
+
+				mon_data_ext.stopbits[i] = cflag & CSTOPB;
+
+				mon_data_ext.parity[i] =
+					cflag & (PARENB | PARODD | CMSPAR);
+
+				mon_data_ext.flowctrl[i] = 0x00;
+
+				if (cflag & CRTSCTS)
+					mon_data_ext.flowctrl[i] |= 0x03;
+
+				if (iflag & (IXON | IXOFF))
+					mon_data_ext.flowctrl[i] |= 0x0C;
+
+				if (port->type == PORT_16550A)
+					mon_data_ext.fifo[i] = 1;
+				else
+					mon_data_ext.fifo[i] = 0;
+
+				p = i % 4;
+				shiftbit = p * 2;
+				opmode = inb(port->opmode_ioaddr) >> shiftbit;
+				opmode &= OP_MODE_MASK;
+
+				mon_data_ext.iftype[i] = opmode;
+
+			}
+			if (copy_to_user(argp, &mon_data_ext,
+						sizeof(mon_data_ext)))
+				return -EFAULT;
+
+			return 0;
+
+	} default:
+		return -ENOIOCTLCMD;
+	}
+	return 0;
+}
+
+static int mxser_ioctl(struct tty_struct *tty, struct file *file,
+		unsigned int cmd, unsigned long arg)
+{
+	struct mxser_port *info = tty->driver_data;
+	struct async_icount cprev, cnow;	/* kernel counter temps */
+	struct serial_icounter_struct __user *p_cuser;
+	unsigned long templ;
+	unsigned long flags;
+	void __user *argp = (void __user *)arg;
+	int retval;
+
+	if (tty->index == MXSER_PORTS)
+		return mxser_ioctl_special(cmd, argp);
+
+	if (cmd == MOXA_SET_OP_MODE || cmd == MOXA_GET_OP_MODE) {
+		int p;
+		unsigned long opmode;
+		static unsigned char ModeMask[] = { 0xfc, 0xf3, 0xcf, 0x3f };
+		int shiftbit;
+		unsigned char val, mask;
+
+		p = tty->index % 4;
+		if (cmd == MOXA_SET_OP_MODE) {
+			if (get_user(opmode, (int __user *) argp))
+				return -EFAULT;
+			if (opmode != RS232_MODE &&
+					opmode != RS485_2WIRE_MODE &&
+					opmode != RS422_MODE &&
+					opmode != RS485_4WIRE_MODE)
+				return -EFAULT;
+			mask = ModeMask[p];
+			shiftbit = p * 2;
+			val = inb(info->opmode_ioaddr);
+			val &= mask;
+			val |= (opmode << shiftbit);
+			outb(val, info->opmode_ioaddr);
+		} else {
+			shiftbit = p * 2;
+			opmode = inb(info->opmode_ioaddr) >> shiftbit;
+			opmode &= OP_MODE_MASK;
+			if (copy_to_user(argp, &opmode, sizeof(int)))
+				return -EFAULT;
+		}
+		return 0;
+	}
+
+	if (cmd != TIOCGSERIAL && cmd != TIOCMIWAIT && cmd != TIOCGICOUNT &&
+			test_bit(TTY_IO_ERROR, &tty->flags))
+		return -EIO;
+
+	switch (cmd) {
+	case TCSBRK:		/* SVID version: non-zero arg --> no break */
+		retval = tty_check_change(tty);
+		if (retval)
+			return retval;
+		tty_wait_until_sent(tty, 0);
+		if (!arg)
+			mxser_send_break(info, 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);
+		mxser_send_break(info, arg ? arg * (HZ / 10) : HZ / 4);
+		return 0;
+	case TIOCGSOFTCAR:
+		return put_user(C_CLOCAL(tty) ? 1 : 0, (unsigned long __user *)argp);
+	case TIOCSSOFTCAR:
+		if (get_user(templ, (unsigned long __user *) argp))
+			return -EFAULT;
+		arg = templ;
+		tty->termios->c_cflag = ((tty->termios->c_cflag & ~CLOCAL) | (arg ? CLOCAL : 0));
+		return 0;
+	case TIOCGSERIAL:
+		return mxser_get_serial_info(info, argp);
+	case TIOCSSERIAL:
+		return mxser_set_serial_info(info, argp);
+	case TIOCSERGETLSR:	/* Get line status register */
+		return mxser_get_lsr_info(info, argp);
+		/*
+		 * Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change
+		 * - mask passed in arg for lines of interest
+		 *   (use |'ed TIOCM_RNG/DSR/CD/CTS for masking)
+		 * Caller should use TIOCGICOUNT to see which one it was
+		 */
+	case TIOCMIWAIT: {
+		DECLARE_WAITQUEUE(wait, current);
+		int ret;
+		spin_lock_irqsave(&info->slock, flags);
+		cprev = info->icount;	/* note the counters on entry */
+		spin_unlock_irqrestore(&info->slock, flags);
+
+		add_wait_queue(&info->delta_msr_wait, &wait);
+		while (1) {
+			spin_lock_irqsave(&info->slock, flags);
+			cnow = info->icount;	/* atomic copy */
+			spin_unlock_irqrestore(&info->slock, flags);
+
+			set_current_state(TASK_INTERRUPTIBLE);
+			if (((arg & TIOCM_RNG) &&
+					(cnow.rng != cprev.rng)) ||
+					((arg & TIOCM_DSR) &&
+					(cnow.dsr != cprev.dsr)) ||
+					((arg & TIOCM_CD) &&
+					(cnow.dcd != cprev.dcd)) ||
+					((arg & TIOCM_CTS) &&
+					(cnow.cts != cprev.cts))) {
+				ret = 0;
+				break;
+			}
+			/* see if a signal did it */
+			if (signal_pending(current)) {
+				ret = -ERESTARTSYS;
+				break;
+			}
+			cprev = cnow;
+		}
+		current->state = TASK_RUNNING;
+		remove_wait_queue(&info->delta_msr_wait, &wait);
+		break;
+	}
+	/* NOTREACHED */
+	/*
+	 * Get counter of input serial line interrupts (DCD,RI,DSR,CTS)
+	 * Return: write counters to the user passed counter struct
+	 * NB: both 1->0 and 0->1 transitions are counted except for
+	 *     RI where only 0->1 is counted.
+	 */
+	case TIOCGICOUNT:
+		spin_lock_irqsave(&info->slock, flags);
+		cnow = info->icount;
+		spin_unlock_irqrestore(&info->slock, flags);
+		p_cuser = argp;
+		if (put_user(cnow.frame, &p_cuser->frame))
+			return -EFAULT;
+		if (put_user(cnow.brk, &p_cuser->brk))
+			return -EFAULT;
+		if (put_user(cnow.overrun, &p_cuser->overrun))
+			return -EFAULT;
+		if (put_user(cnow.buf_overrun, &p_cuser->buf_overrun))
+			return -EFAULT;
+		if (put_user(cnow.parity, &p_cuser->parity))
+			return -EFAULT;
+		if (put_user(cnow.rx, &p_cuser->rx))
+			return -EFAULT;
+		if (put_user(cnow.tx, &p_cuser->tx))
+			return -EFAULT;
+		put_user(cnow.cts, &p_cuser->cts);
+		put_user(cnow.dsr, &p_cuser->dsr);
+		put_user(cnow.rng, &p_cuser->rng);
+		put_user(cnow.dcd, &p_cuser->dcd);
+		return 0;
+	case MOXA_HighSpeedOn:
+		return put_user(info->baud_base != 115200 ? 1 : 0, (int __user *)argp);
+	case MOXA_SDS_RSTICOUNTER:
+		info->mon_data.rxcnt = 0;
+		info->mon_data.txcnt = 0;
+		return 0;
+	case MOXA_ASPP_SETBAUD:{
+		long baud;
+		if (get_user(baud, (long __user *)argp))
+			return -EFAULT;
+		mxser_set_baud(info, baud);
+		return 0;
+	}
+	case MOXA_ASPP_GETBAUD:
+		if (copy_to_user(argp, &info->realbaud, sizeof(long)))
+			return -EFAULT;
+
+		return 0;
+
+	case MOXA_ASPP_OQUEUE:{
+		int len, lsr;
+
+		len = mxser_chars_in_buffer(tty);
+
+		lsr = inb(info->ioaddr + UART_LSR) & UART_LSR_TEMT;
+
+		len += (lsr ? 0 : 1);
+
+		if (copy_to_user(argp, &len, sizeof(int)))
+			return -EFAULT;
+
+		return 0;
+	}
+	case MOXA_ASPP_MON: {
+		int mcr, status;
+
+		status = mxser_get_msr(info->ioaddr, 1, tty->index);
+		mxser_check_modem_status(info, status);
+
+		mcr = inb(info->ioaddr + UART_MCR);
+		if (mcr & MOXA_MUST_MCR_XON_FLAG)
+			info->mon_data.hold_reason &= ~NPPI_NOTIFY_XOFFHOLD;
+		else
+			info->mon_data.hold_reason |= NPPI_NOTIFY_XOFFHOLD;
+
+		if (mcr & MOXA_MUST_MCR_TX_XON)
+			info->mon_data.hold_reason &= ~NPPI_NOTIFY_XOFFXENT;
+		else
+			info->mon_data.hold_reason |= NPPI_NOTIFY_XOFFXENT;
+
+		if (info->tty->hw_stopped)
+			info->mon_data.hold_reason |= NPPI_NOTIFY_CTSHOLD;
+		else
+			info->mon_data.hold_reason &= ~NPPI_NOTIFY_CTSHOLD;
+
+		if (copy_to_user(argp, &info->mon_data,
+				sizeof(struct mxser_mon)))
+			return -EFAULT;
+
+		return 0;
+	}
+	case MOXA_ASPP_LSTATUS: {
+		if (copy_to_user(argp, &info->err_shadow,
+				sizeof(unsigned char)))
+			return -EFAULT;
+
+		info->err_shadow = 0;
+		return 0;
+	}
+	case MOXA_SET_BAUD_METHOD: {
+		int method;
+
+		if (get_user(method, (int __user *)argp))
+			return -EFAULT;
+		mxser_set_baud_method[tty->index] = method;
+		if (copy_to_user(argp, &method, sizeof(int)))
+			return -EFAULT;
+
+		return 0;
+	}
+	default:
+		return -ENOIOCTLCMD;
+	}
+	return 0;
+}
+
+static void mxser_stoprx(struct tty_struct *tty)
+{
+	struct mxser_port *info = tty->driver_data;
+
+	info->ldisc_stop_rx = 1;
+	if (I_IXOFF(tty)) {
+		if (info->board->chip_flag) {
+			info->IER &= ~MOXA_MUST_RECV_ISR;
+			outb(info->IER, info->ioaddr + UART_IER);
+		} else {
+			info->x_char = STOP_CHAR(tty);
+			outb(0, info->ioaddr + UART_IER);
+			info->IER |= UART_IER_THRI;
+			outb(info->IER, info->ioaddr + UART_IER);
+		}
+	}
+
+	if (info->tty->termios->c_cflag & CRTSCTS) {
+		info->MCR &= ~UART_MCR_RTS;
+		outb(info->MCR, info->ioaddr + UART_MCR);
+	}
+}
+
+/*
+ * This routine is called by the upper-layer tty layer to signal that
+ * incoming characters should be throttled.
+ */
+static void mxser_throttle(struct tty_struct *tty)
+{
+	mxser_stoprx(tty);
+}
+
+static void mxser_unthrottle(struct tty_struct *tty)
+{
+	struct mxser_port *info = tty->driver_data;
+
+	/* startrx */
+	info->ldisc_stop_rx = 0;
+	if (I_IXOFF(tty)) {
+		if (info->x_char)
+			info->x_char = 0;
+		else {
+			if (info->board->chip_flag) {
+				info->IER |= MOXA_MUST_RECV_ISR;
+				outb(info->IER, info->ioaddr + UART_IER);
+			} else {
+				info->x_char = START_CHAR(tty);
+				outb(0, info->ioaddr + UART_IER);
+				info->IER |= UART_IER_THRI;
+				outb(info->IER, info->ioaddr + UART_IER);
+			}
+		}
+	}
+
+	if (info->tty->termios->c_cflag & CRTSCTS) {
+		info->MCR |= UART_MCR_RTS;
+		outb(info->MCR, info->ioaddr + UART_MCR);
+	}
+}
+
+/*
+ * mxser_stop() and mxser_start()
+ *
+ * This routines are called before setting or resetting tty->stopped.
+ * They enable or disable transmitter interrupts, as necessary.
+ */
+static void mxser_stop(struct tty_struct *tty)
+{
+	struct mxser_port *info = tty->driver_data;
+	unsigned long flags;
+
+	spin_lock_irqsave(&info->slock, flags);
+	if (info->IER & UART_IER_THRI) {
+		info->IER &= ~UART_IER_THRI;
+		outb(info->IER, info->ioaddr + UART_IER);
+	}
+	spin_unlock_irqrestore(&info->slock, flags);
+}
+
+static void mxser_start(struct tty_struct *tty)
+{
+	struct mxser_port *info = tty->driver_data;
+	unsigned long flags;
+
+	spin_lock_irqsave(&info->slock, flags);
+	if (info->xmit_cnt && info->xmit_buf) {
+		outb(info->IER & ~UART_IER_THRI, info->ioaddr + UART_IER);
+		info->IER |= UART_IER_THRI;
+		outb(info->IER, info->ioaddr + UART_IER);
+	}
+	spin_unlock_irqrestore(&info->slock, flags);
+}
+
+static void mxser_set_termios(struct tty_struct *tty, struct ktermios *old_termios)
+{
+	struct mxser_port *info = tty->driver_data;
+	unsigned long flags;
+
+	if ((tty->termios->c_cflag != old_termios->c_cflag) ||
+			(RELEVANT_IFLAG(tty->termios->c_iflag) != RELEVANT_IFLAG(old_termios->c_iflag))) {
+
+		mxser_change_speed(info, old_termios);
+
+		if ((old_termios->c_cflag & CRTSCTS) &&
+				!(tty->termios->c_cflag & CRTSCTS)) {
+			tty->hw_stopped = 0;
+			mxser_start(tty);
+		}
+	}
+
+	/* Handle sw stopped */
+	if ((old_termios->c_iflag & IXON) &&
+			!(tty->termios->c_iflag & IXON)) {
+		tty->stopped = 0;
+
+		if (info->board->chip_flag) {
+			spin_lock_irqsave(&info->slock, flags);
+			DISABLE_MOXA_MUST_RX_SOFTWARE_FLOW_CONTROL(info->ioaddr);
+			spin_unlock_irqrestore(&info->slock, flags);
+		}
+
+		mxser_start(tty);
+	}
+}
+
+/*
+ * mxser_wait_until_sent() --- wait until the transmitter is empty
+ */
+static void mxser_wait_until_sent(struct tty_struct *tty, int timeout)
+{
+	struct mxser_port *info = tty->driver_data;
+	unsigned long orig_jiffies, char_time;
+	int lsr;
+
+	if (info->type == PORT_UNKNOWN)
+		return;
+
+	if (info->xmit_fifo_size == 0)
+		return;		/* Just in case.... */
+
+	orig_jiffies = jiffies;
+	/*
+	 * Set the check interval to be 1/5 of the estimated time to
+	 * send a single character, and make it at least 1.  The check
+	 * interval should also be less than the timeout.
+	 *
+	 * Note: we have to use pretty tight timings here to satisfy
+	 * the NIST-PCTS.
+	 */
+	char_time = (info->timeout - HZ / 50) / info->xmit_fifo_size;
+	char_time = char_time / 5;
+	if (char_time == 0)
+		char_time = 1;
+	if (timeout && timeout < char_time)
+		char_time = timeout;
+	/*
+	 * If the transmitter hasn't cleared in twice the approximate
+	 * amount of time to send the entire FIFO, it probably won't
+	 * ever clear.  This assumes the UART isn't doing flow
+	 * control, which is currently the case.  Hence, if it ever
+	 * takes longer than info->timeout, this is probably due to a
+	 * UART bug of some kind.  So, we clamp the timeout parameter at
+	 * 2*info->timeout.
+	 */
+	if (!timeout || timeout > 2 * info->timeout)
+		timeout = 2 * info->timeout;
+#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
+	printk(KERN_DEBUG "In rs_wait_until_sent(%d) check=%lu...",
+		timeout, char_time);
+	printk("jiff=%lu...", jiffies);
+#endif
+	while (!((lsr = inb(info->ioaddr + UART_LSR)) & UART_LSR_TEMT)) {
+#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
+		printk("lsr = %d (jiff=%lu)...", lsr, jiffies);
+#endif
+		schedule_timeout_interruptible(char_time);
+		if (signal_pending(current))
+			break;
+		if (timeout && time_after(jiffies, orig_jiffies + timeout))
+			break;
+	}
+	set_current_state(TASK_RUNNING);
+
+#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
+	printk("lsr = %d (jiff=%lu)...done\n", lsr, jiffies);
+#endif
+}
+
+/*
+ * This routine is called by tty_hangup() when a hangup is signaled.
+ */
+void mxser_hangup(struct tty_struct *tty)
+{
+	struct mxser_port *info = tty->driver_data;
+
+	mxser_flush_buffer(tty);
+	mxser_shutdown(info);
+	info->event = 0;
+	info->count = 0;
+	info->flags &= ~ASYNC_NORMAL_ACTIVE;
+	info->tty = NULL;
+	wake_up_interruptible(&info->open_wait);
+}
+
+/*
+ * mxser_rs_break() --- routine which turns the break handling on or off
+ */
+static void mxser_rs_break(struct tty_struct *tty, int break_state)
+{
+	struct mxser_port *info = tty->driver_data;
+	unsigned long flags;
+
+	spin_lock_irqsave(&info->slock, flags);
+	if (break_state == -1)
+		outb(inb(info->ioaddr + UART_LCR) | UART_LCR_SBC,
+			info->ioaddr + UART_LCR);
+	else
+		outb(inb(info->ioaddr + UART_LCR) & ~UART_LCR_SBC,
+			info->ioaddr + UART_LCR);
+	spin_unlock_irqrestore(&info->slock, flags);
+}
+
+static void mxser_receive_chars(struct mxser_port *port, int *status)
+{
+	struct tty_struct *tty = port->tty;
+	unsigned char ch, gdl;
+	int ignored = 0;
+	int cnt = 0;
+	int recv_room;
+	int max = 256;
+	unsigned long flags;
+
+	spin_lock_irqsave(&port->slock, flags);
+
+	recv_room = tty->receive_room;
+	if ((recv_room == 0) && (!port->ldisc_stop_rx))
+		mxser_stoprx(tty);
+
+	if (port->board->chip_flag != MOXA_OTHER_UART) {
+
+		if (*status & UART_LSR_SPECIAL)
+			goto intr_old;
+		if (port->board->chip_flag == MOXA_MUST_MU860_HWID &&
+				(*status & MOXA_MUST_LSR_RERR))
+			goto intr_old;
+		if (*status & MOXA_MUST_LSR_RERR)
+			goto intr_old;
+
+		gdl = inb(port->ioaddr + MOXA_MUST_GDL_REGISTER);
+
+		if (port->board->chip_flag == MOXA_MUST_MU150_HWID)
+			gdl &= MOXA_MUST_GDL_MASK;
+		if (gdl >= recv_room) {
+			if (!port->ldisc_stop_rx)
+				mxser_stoprx(tty);
+		}
+		while (gdl--) {
+			ch = inb(port->ioaddr + UART_RX);
+			tty_insert_flip_char(tty, ch, 0);
+			cnt++;
+		}
+		goto end_intr;
+	}
+intr_old:
+
+	do {
+		if (max-- < 0)
+			break;
+
+		ch = inb(port->ioaddr + UART_RX);
+		if (port->board->chip_flag && (*status & UART_LSR_OE))
+			outb(0x23, port->ioaddr + UART_FCR);
+		*status &= port->read_status_mask;
+		if (*status & port->ignore_status_mask) {
+			if (++ignored > 100)
+				break;
+		} else {
+			char flag = 0;
+			if (*status & UART_LSR_SPECIAL) {
+				if (*status & UART_LSR_BI) {
+					flag = TTY_BREAK;
+					port->icount.brk++;
+
+					if (port->flags & ASYNC_SAK)
+						do_SAK(tty);
+				} else if (*status & UART_LSR_PE) {
+					flag = TTY_PARITY;
+					port->icount.parity++;
+				} else if (*status & UART_LSR_FE) {
+					flag = TTY_FRAME;
+					port->icount.frame++;
+				} else if (*status & UART_LSR_OE) {
+					flag = TTY_OVERRUN;
+					port->icount.overrun++;
+				}
+			}
+			tty_insert_flip_char(tty, ch, flag);
+			cnt++;
+			if (cnt >= recv_room) {
+				if (!port->ldisc_stop_rx)
+					mxser_stoprx(tty);
+				break;
+			}
+
+		}
+
+		if (port->board->chip_flag)
+			break;
+
+		*status = inb(port->ioaddr + UART_LSR);
+	} while (*status & UART_LSR_DR);
+
+end_intr:
+	mxvar_log.rxcnt[port->tty->index] += cnt;
+	port->mon_data.rxcnt += cnt;
+	port->mon_data.up_rxcnt += cnt;
+	spin_unlock_irqrestore(&port->slock, flags);
+
+	tty_flip_buffer_push(tty);
+}
+
+static void mxser_transmit_chars(struct mxser_port *port)
+{
+	int count, cnt;
+	unsigned long flags;
+
+	spin_lock_irqsave(&port->slock, flags);
+
+	if (port->x_char) {
+		outb(port->x_char, port->ioaddr + UART_TX);
+		port->x_char = 0;
+		mxvar_log.txcnt[port->tty->index]++;
+		port->mon_data.txcnt++;
+		port->mon_data.up_txcnt++;
+		port->icount.tx++;
+		goto unlock;
+	}
+
+	if (port->xmit_buf == 0)
+		goto unlock;
+
+	if ((port->xmit_cnt <= 0) || port->tty->stopped ||
+			(port->tty->hw_stopped &&
+			(port->type != PORT_16550A) &&
+			(!port->board->chip_flag))) {
+		port->IER &= ~UART_IER_THRI;
+		outb(port->IER, port->ioaddr + UART_IER);
+		goto unlock;
+	}
+
+	cnt = port->xmit_cnt;
+	count = port->xmit_fifo_size;
+	do {
+		outb(port->xmit_buf[port->xmit_tail++],
+			port->ioaddr + UART_TX);
+		port->xmit_tail = port->xmit_tail & (SERIAL_XMIT_SIZE - 1);
+		if (--port->xmit_cnt <= 0)
+			break;
+	} while (--count > 0);
+	mxvar_log.txcnt[port->tty->index] += (cnt - port->xmit_cnt);
+
+	port->mon_data.txcnt += (cnt - port->xmit_cnt);
+	port->mon_data.up_txcnt += (cnt - port->xmit_cnt);
+	port->icount.tx += (cnt - port->xmit_cnt);
+
+	if (port->xmit_cnt < WAKEUP_CHARS) {
+		set_bit(MXSER_EVENT_TXLOW, &port->event);
+		schedule_work(&port->tqueue);
+	}
+	if (port->xmit_cnt <= 0) {
+		port->IER &= ~UART_IER_THRI;
+		outb(port->IER, port->ioaddr + UART_IER);
+	}
+unlock:
+	spin_unlock_irqrestore(&port->slock, flags);
+}
+
+/*
+ * This is the serial driver's generic interrupt routine
+ */
+static irqreturn_t mxser_interrupt(int irq, void *dev_id)
+{
+	int status, iir, i;
+	struct mxser_board *brd = NULL;
+	struct mxser_port *port;
+	int max, irqbits, bits, msr;
+	int pass_counter = 0;
+	unsigned int int_cnt;
+	int handled = IRQ_NONE;
+
+	for (i = 0; i < MXSER_BOARDS; i++)
+		if (dev_id == &mxser_boards[i]) {
+			brd = dev_id;
+			break;
+		}
+
+	if (i == MXSER_BOARDS)
+		goto irq_stop;
+	if (brd == NULL)
+		goto irq_stop;
+	max = brd->info->nports;
+	while (1) {
+		irqbits = inb(brd->vector) & brd->vector_mask;
+		if (irqbits == brd->vector_mask)
+			break;
+
+		handled = IRQ_HANDLED;
+		for (i = 0, bits = 1; i < max; i++, irqbits |= bits, bits <<= 1) {
+			if (irqbits == brd->vector_mask)
+				break;
+			if (bits & irqbits)
+				continue;
+			port = &brd->ports[i];
+
+			int_cnt = 0;
+			do {
+				iir = inb(port->ioaddr + UART_IIR);
+				if (iir & UART_IIR_NO_INT)
+					break;
+				iir &= MOXA_MUST_IIR_MASK;
+				if (!port->tty) {
+					status = inb(port->ioaddr + UART_LSR);
+					outb(0x27, port->ioaddr + UART_FCR);
+					inb(port->ioaddr + UART_MSR);
+					break;
+				}
+
+				status = inb(port->ioaddr + UART_LSR);
+
+				if (status & UART_LSR_PE)
+					port->err_shadow |= NPPI_NOTIFY_PARITY;
+				if (status & UART_LSR_FE)
+					port->err_shadow |= NPPI_NOTIFY_FRAMING;
+				if (status & UART_LSR_OE)
+					port->err_shadow |=
+						NPPI_NOTIFY_HW_OVERRUN;
+				if (status & UART_LSR_BI)
+					port->err_shadow |= NPPI_NOTIFY_BREAK;
+
+				if (port->board->chip_flag) {
+					if (iir == MOXA_MUST_IIR_GDA ||
+					    iir == MOXA_MUST_IIR_RDA ||
+					    iir == MOXA_MUST_IIR_RTO ||
+					    iir == MOXA_MUST_IIR_LSR)
+						mxser_receive_chars(port,
+								&status);
+
+				} else {
+					status &= port->read_status_mask;
+					if (status & UART_LSR_DR)
+						mxser_receive_chars(port,
+								&status);
+				}
+				msr = inb(port->ioaddr + UART_MSR);
+				if (msr & UART_MSR_ANY_DELTA)
+					mxser_check_modem_status(port, msr);
+
+				if (port->board->chip_flag) {
+					if (iir == 0x02 && (status &
+								UART_LSR_THRE))
+						mxser_transmit_chars(port);
+				} else {
+					if (status & UART_LSR_THRE)
+						mxser_transmit_chars(port);
+				}
+			} while (int_cnt++ < MXSER_ISR_PASS_LIMIT);
+		}
+		if (pass_counter++ > MXSER_ISR_PASS_LIMIT)
+			break;	/* Prevent infinite loops */
+	}
+
+irq_stop:
+	return handled;
+}
+
+static const struct tty_operations mxser_ops = {
+	.open = mxser_open,
+	.close = mxser_close,
+	.write = mxser_write,
+	.put_char = mxser_put_char,
+	.flush_chars = mxser_flush_chars,
+	.write_room = mxser_write_room,
+	.chars_in_buffer = mxser_chars_in_buffer,
+	.flush_buffer = mxser_flush_buffer,
+	.ioctl = mxser_ioctl,
+	.throttle = mxser_throttle,
+	.unthrottle = mxser_unthrottle,
+	.set_termios = mxser_set_termios,
+	.stop = mxser_stop,
+	.start = mxser_start,
+	.hangup = mxser_hangup,
+	.break_ctl = mxser_rs_break,
+	.wait_until_sent = mxser_wait_until_sent,
+	.tiocmget = mxser_tiocmget,
+	.tiocmset = mxser_tiocmset,
+};
+
+/*
+ * The MOXA Smartio/Industio serial driver boot-time initialization code!
+ */
+
+static void mxser_release_res(struct mxser_board *brd, struct pci_dev *pdev,
+		unsigned int irq)
+{
+	if (irq)
+		free_irq(brd->irq, brd);
+	if (pdev != NULL) {	/* PCI */
+		pci_release_region(pdev, 2);
+		pci_release_region(pdev, 3);
+		pci_dev_put(pdev);
+	} else {
+		release_region(brd->ports[0].ioaddr, 8 * brd->info->nports);
+		release_region(brd->vector, 1);
+	}
+}
+
+static int __devinit mxser_initbrd(struct mxser_board *brd,
+		struct pci_dev *pdev)
+{
+	struct mxser_port *info;
+	unsigned int i;
+	int retval;
+
+	printk(KERN_INFO "max. baud rate = %d bps.\n", brd->ports[0].max_baud);
+
+	for (i = 0; i < brd->info->nports; i++) {
+		info = &brd->ports[i];
+		info->board = brd;
+		info->stop_rx = 0;
+		info->ldisc_stop_rx = 0;
+
+		/* Enhance mode enabled here */
+		if (brd->chip_flag != MOXA_OTHER_UART)
+			ENABLE_MOXA_MUST_ENCHANCE_MODE(info->ioaddr);
+
+		info->flags = ASYNC_SHARE_IRQ;
+		info->type = brd->uart_type;
+
+		process_txrx_fifo(info);
+
+		info->custom_divisor = info->baud_base * 16;
+		info->close_delay = 5 * HZ / 10;
+		info->closing_wait = 30 * HZ;
+		INIT_WORK(&info->tqueue, mxser_do_softint);
+		info->normal_termios = mxvar_sdriver->init_termios;
+		init_waitqueue_head(&info->open_wait);
+		init_waitqueue_head(&info->close_wait);
+		init_waitqueue_head(&info->delta_msr_wait);
+		memset(&info->mon_data, 0, sizeof(struct mxser_mon));
+		info->err_shadow = 0;
+		spin_lock_init(&info->slock);
+
+		/* before set INT ISR, disable all int */
+		outb(inb(info->ioaddr + UART_IER) & 0xf0,
+			info->ioaddr + UART_IER);
+	}
+	/*
+	 * Allocate the IRQ if necessary
+	 */
+
+	retval = request_irq(brd->irq, mxser_interrupt,
+			(brd->ports[0].flags & ASYNC_SHARE_IRQ) ? IRQF_SHARED :
+			IRQF_DISABLED, "mxser", brd);
+	if (retval) {
+		printk(KERN_ERR "Board %s: Request irq failed, IRQ (%d) may "
+			"conflict with another device.\n",
+			brd->info->name, brd->irq);
+		/* We hold resources, we need to release them. */
+		mxser_release_res(brd, pdev, 0);
+		return retval;
+	}
+	return 0;
+}
+
+static int __init mxser_get_ISA_conf(int cap, struct mxser_board *brd)
+{
+	int id, i, bits;
+	unsigned short regs[16], irq;
+	unsigned char scratch, scratch2;
+
+	brd->chip_flag = MOXA_OTHER_UART;
+
+	id = mxser_read_register(cap, regs);
+	switch (id) {
+	case C168_ASIC_ID:
+		brd->info = &mxser_cards[0];
+		break;
+	case C104_ASIC_ID:
+		brd->info = &mxser_cards[1];
+		break;
+	case CI104J_ASIC_ID:
+		brd->info = &mxser_cards[2];
+		break;
+	case C102_ASIC_ID:
+		brd->info = &mxser_cards[5];
+		break;
+	case CI132_ASIC_ID:
+		brd->info = &mxser_cards[6];
+		break;
+	case CI134_ASIC_ID:
+		brd->info = &mxser_cards[7];
+		break;
+	default:
+		return 0;
+	}
+
+	irq = 0;
+	/* some ISA cards have 2 ports, but we want to see them as 4-port (why?)
+	   Flag-hack checks if configuration should be read as 2-port here. */
+	if (brd->info->nports == 2 || (brd->info->flags & MXSER_HAS2)) {
+		irq = regs[9] & 0xF000;
+		irq = irq | (irq >> 4);
+		if (irq != (regs[9] & 0xFF00))
+			return MXSER_ERR_IRQ_CONFLIT;
+	} else if (brd->info->nports == 4) {
+		irq = regs[9] & 0xF000;
+		irq = irq | (irq >> 4);
+		irq = irq | (irq >> 8);
+		if (irq != regs[9])
+			return MXSER_ERR_IRQ_CONFLIT;
+	} else if (brd->info->nports == 8) {
+		irq = regs[9] & 0xF000;
+		irq = irq | (irq >> 4);
+		irq = irq | (irq >> 8);
+		if ((irq != regs[9]) || (irq != regs[10]))
+			return MXSER_ERR_IRQ_CONFLIT;
+	}
+
+	if (!irq)
+		return MXSER_ERR_IRQ;
+	brd->irq = ((int)(irq & 0xF000) >> 12);
+	for (i = 0; i < 8; i++)
+		brd->ports[i].ioaddr = (int) regs[i + 1] & 0xFFF8;
+	if ((regs[12] & 0x80) == 0)
+		return MXSER_ERR_VECTOR;
+	brd->vector = (int)regs[11];	/* interrupt vector */
+	if (id == 1)
+		brd->vector_mask = 0x00FF;
+	else
+		brd->vector_mask = 0x000F;
+	for (i = 7, bits = 0x0100; i >= 0; i--, bits <<= 1) {
+		if (regs[12] & bits) {
+			brd->ports[i].baud_base = 921600;
+			brd->ports[i].max_baud = 921600;
+		} else {
+			brd->ports[i].baud_base = 115200;
+			brd->ports[i].max_baud = 115200;
+		}
+	}
+	scratch2 = inb(cap + UART_LCR) & (~UART_LCR_DLAB);
+	outb(scratch2 | UART_LCR_DLAB, cap + UART_LCR);
+	outb(0, cap + UART_EFR);	/* EFR is the same as FCR */
+	outb(scratch2, cap + UART_LCR);
+	outb(UART_FCR_ENABLE_FIFO, cap + UART_FCR);
+	scratch = inb(cap + UART_IIR);
+
+	if (scratch & 0xC0)
+		brd->uart_type = PORT_16550A;
+	else
+		brd->uart_type = PORT_16450;
+	if (!request_region(brd->ports[0].ioaddr, 8 * brd->info->nports,
+			"mxser(IO)"))
+		return MXSER_ERR_IOADDR;
+	if (!request_region(brd->vector, 1, "mxser(vector)")) {
+		release_region(brd->ports[0].ioaddr, 8 * brd->info->nports);
+		return MXSER_ERR_VECTOR;
+	}
+	return brd->info->nports;
+}
+
+static int __devinit mxser_probe(struct pci_dev *pdev,
+		const struct pci_device_id *ent)
+{
+	struct mxser_board *brd;
+	unsigned int i, j;
+	unsigned long ioaddress;
+	int retval = -EINVAL;
+
+	for (i = 0; i < MXSER_BOARDS; i++)
+		if (mxser_boards[i].info == NULL)
+			break;
+
+	if (i >= MXSER_BOARDS) {
+		printk(KERN_ERR "Too many Smartio/Industio family boards found "
+			"(maximum %d), board not configured\n", MXSER_BOARDS);
+		goto err;
+	}
+
+	brd = &mxser_boards[i];
+	brd->idx = i * MXSER_PORTS_PER_BOARD;
+	printk(KERN_INFO "Found MOXA %s board (BusNo=%d, DevNo=%d)\n",
+		mxser_cards[ent->driver_data].name,
+		pdev->bus->number, PCI_SLOT(pdev->devfn));
+
+	retval = pci_enable_device(pdev);
+	if (retval) {
+		printk(KERN_ERR "Moxa SmartI/O PCI enable fail !\n");
+		goto err;
+	}
+
+	/* io address */
+	ioaddress = pci_resource_start(pdev, 2);
+	retval = pci_request_region(pdev, 2, "mxser(IO)");
+	if (retval)
+		goto err;
+
+	brd->info = &mxser_cards[ent->driver_data];
+	for (i = 0; i < brd->info->nports; i++)
+		brd->ports[i].ioaddr = ioaddress + 8 * i;
+
+	/* vector */
+	ioaddress = pci_resource_start(pdev, 3);
+	retval = pci_request_region(pdev, 3, "mxser(vector)");
+	if (retval)
+		goto err_relio;
+	brd->vector = ioaddress;
+
+	/* irq */
+	brd->irq = pdev->irq;
+
+	brd->chip_flag = CheckIsMoxaMust(brd->ports[0].ioaddr);
+	brd->uart_type = PORT_16550A;
+	brd->vector_mask = 0;
+
+	for (i = 0; i < brd->info->nports; i++) {
+		for (j = 0; j < UART_INFO_NUM; j++) {
+			if (Gpci_uart_info[j].type == brd->chip_flag) {
+				brd->ports[i].max_baud =
+					Gpci_uart_info[j].max_baud;
+
+				/* exception....CP-102 */
+				if (brd->info->flags & MXSER_HIGHBAUD)
+					brd->ports[i].max_baud = 921600;
+				break;
+			}
+		}
+	}
+
+	if (brd->chip_flag == MOXA_MUST_MU860_HWID) {
+		for (i = 0; i < brd->info->nports; i++) {
+			if (i < 4)
+				brd->ports[i].opmode_ioaddr = ioaddress + 4;
+			else
+				brd->ports[i].opmode_ioaddr = ioaddress + 0x0c;
+		}
+		outb(0, ioaddress + 4);	/* default set to RS232 mode */
+		outb(0, ioaddress + 0x0c);	/* default set to RS232 mode */
+	}
+
+	for (i = 0; i < brd->info->nports; i++) {
+		brd->vector_mask |= (1 << i);
+		brd->ports[i].baud_base = 921600;
+	}
+
+	/* mxser_initbrd will hook ISR. */
+	if (mxser_initbrd(brd, pdev) < 0)
+		goto err_relvec;
+
+	for (i = 0; i < brd->info->nports; i++)
+		tty_register_device(mxvar_sdriver, brd->idx + i, &pdev->dev);
+
+	pci_set_drvdata(pdev, brd);
+
+	return 0;
+err_relvec:
+	pci_release_region(pdev, 3);
+err_relio:
+	pci_release_region(pdev, 2);
+	brd->info = NULL;
+err:
+	return retval;
+}
+
+static void __devexit mxser_remove(struct pci_dev *pdev)
+{
+	struct mxser_board *brd = pci_get_drvdata(pdev);
+	unsigned int i;
+
+	for (i = 0; i < brd->info->nports; i++)
+		tty_unregister_device(mxvar_sdriver, brd->idx + i);
+
+	mxser_release_res(brd, pdev, 1);
+}
+
+static struct pci_driver mxser_driver = {
+	.name = "mxser",
+	.id_table = mxser_pcibrds,
+	.probe = mxser_probe,
+	.remove = __devexit_p(mxser_remove)
+};
+
+static int __init mxser_module_init(void)
+{
+	struct mxser_board *brd;
+	unsigned long cap;
+	unsigned int i, m, isaloop;
+	int retval, b;
+
+	pr_debug("Loading module mxser ...\n");
+
+	mxvar_sdriver = alloc_tty_driver(MXSER_PORTS + 1);
+	if (!mxvar_sdriver)
+		return -ENOMEM;
+	spin_lock_init(&gm_lock);
+
+	printk(KERN_INFO "MOXA Smartio/Industio family driver version %s\n",
+		MXSER_VERSION);
+
+	/* Initialize the tty_driver structure */
+	mxvar_sdriver->magic = TTY_DRIVER_MAGIC;
+	mxvar_sdriver->name = "ttyMI";
+	mxvar_sdriver->major = ttymajor;
+	mxvar_sdriver->minor_start = 0;
+	mxvar_sdriver->num = MXSER_PORTS + 1;
+	mxvar_sdriver->type = TTY_DRIVER_TYPE_SERIAL;
+	mxvar_sdriver->subtype = SERIAL_TYPE_NORMAL;
+	mxvar_sdriver->init_termios = tty_std_termios;
+	mxvar_sdriver->init_termios.c_cflag = B9600|CS8|CREAD|HUPCL|CLOCAL;
+	mxvar_sdriver->flags = TTY_DRIVER_REAL_RAW|TTY_DRIVER_DYNAMIC_DEV;
+	tty_set_operations(mxvar_sdriver, &mxser_ops);
+
+	retval = tty_register_driver(mxvar_sdriver);
+	if (retval) {
+		printk(KERN_ERR "Couldn't install MOXA Smartio/Industio family "
+				"tty driver !\n");
+		goto err_put;
+	}
+
+	mxvar_diagflag = 0;
+
+	m = 0;
+	/* Start finding ISA boards here */
+	for (isaloop = 0; isaloop < 2; isaloop++)
+		for (b = 0; b < MXSER_BOARDS && m < MXSER_BOARDS; b++) {
+			if (!isaloop)
+				cap = mxserBoardCAP[b]; /* predefined */
+			else
+				cap = ioaddr[b]; /* module param */
+
+			if (!cap)
+				continue;
+
+			brd = &mxser_boards[m];
+			retval = mxser_get_ISA_conf(cap, brd);
+
+			if (retval != 0)
+				printk(KERN_INFO "Found MOXA %s board "
+					"(CAP=0x%x)\n",
+					brd->info->name, ioaddr[b]);
+
+			if (retval <= 0) {
+				if (retval == MXSER_ERR_IRQ)
+					printk(KERN_ERR "Invalid interrupt "
+						"number, board not "
+						"configured\n");
+				else if (retval == MXSER_ERR_IRQ_CONFLIT)
+					printk(KERN_ERR "Invalid interrupt "
+						"number, board not "
+						"configured\n");
+				else if (retval == MXSER_ERR_VECTOR)
+					printk(KERN_ERR "Invalid interrupt "
+						"vector, board not "
+						"configured\n");
+				else if (retval == MXSER_ERR_IOADDR)
+					printk(KERN_ERR "Invalid I/O address, "
+						"board not configured\n");
+
+				brd->info = NULL;
+				continue;
+			}
+
+			/* mxser_initbrd will hook ISR. */
+			if (mxser_initbrd(brd, NULL) < 0) {
+				brd->info = NULL;
+				continue;
+			}
+
+			brd->idx = m * MXSER_PORTS_PER_BOARD;
+			for (i = 0; i < brd->info->nports; i++)
+				tty_register_device(mxvar_sdriver, brd->idx + i,
+						NULL);
+
+			m++;
+		}
+
+	retval = pci_register_driver(&mxser_driver);
+	if (retval) {
+		printk(KERN_ERR "Can't register pci driver\n");
+		if (!m) {
+			retval = -ENODEV;
+			goto err_unr;
+		} /* else: we have some ISA cards under control */
+	}
+
+	pr_debug("Done.\n");
+
+	return 0;
+err_unr:
+	tty_unregister_driver(mxvar_sdriver);
+err_put:
+	put_tty_driver(mxvar_sdriver);
+	return retval;
+}
+
+static void __exit mxser_module_exit(void)
+{
+	unsigned int i, j;
+
+	pr_debug("Unloading module mxser ...\n");
+
+	pci_unregister_driver(&mxser_driver);
+
+	for (i = 0; i < MXSER_BOARDS; i++) /* ISA remains */
+		if (mxser_boards[i].info != NULL)
+			for (j = 0; j < mxser_boards[i].info->nports; j++)
+				tty_unregister_device(mxvar_sdriver,
+						mxser_boards[i].idx + j);
+	tty_unregister_driver(mxvar_sdriver);
+	put_tty_driver(mxvar_sdriver);
+
+	for (i = 0; i < MXSER_BOARDS; i++)
+		if (mxser_boards[i].info != NULL)
+			mxser_release_res(&mxser_boards[i], NULL, 1);
+
+	pr_debug("Done.\n");
+}
+
+module_init(mxser_module_init);
+module_exit(mxser_module_exit);
diff --git a/drivers/char/mxser_new.h b/drivers/char/mxser_new.h
new file mode 100644
index 000000000000..a08f0ecb09ba
--- /dev/null
+++ b/drivers/char/mxser_new.h
@@ -0,0 +1,450 @@
+#ifndef _MXSER_H
+#define _MXSER_H
+
+/*
+ *	Semi-public control interfaces
+ */
+
+/*
+ *	MOXA ioctls
+ */
+
+#define MOXA			0x400
+#define MOXA_GETDATACOUNT	(MOXA + 23)
+#define	MOXA_GET_CONF		(MOXA + 35)
+#define MOXA_DIAGNOSE		(MOXA + 50)
+#define MOXA_CHKPORTENABLE	(MOXA + 60)
+#define MOXA_HighSpeedOn	(MOXA + 61)
+#define MOXA_GET_MAJOR		(MOXA + 63)
+#define MOXA_GET_CUMAJOR	(MOXA + 64)
+#define MOXA_GETMSTATUS		(MOXA + 65)
+#define MOXA_SET_OP_MODE	(MOXA + 66)
+#define MOXA_GET_OP_MODE	(MOXA + 67)
+
+#define RS232_MODE		0
+#define RS485_2WIRE_MODE	1
+#define RS422_MODE		2
+#define RS485_4WIRE_MODE	3
+#define OP_MODE_MASK		3
+// above add by Victor Yu. 01-05-2004
+
+#define TTY_THRESHOLD_THROTTLE  128
+
+#define LO_WATER	 	(TTY_FLIPBUF_SIZE)
+#define HI_WATER		(TTY_FLIPBUF_SIZE*2*3/4)
+
+// added by James. 03-11-2004.
+#define MOXA_SDS_GETICOUNTER  	(MOXA + 68)
+#define MOXA_SDS_RSTICOUNTER  	(MOXA + 69)
+// (above) added by James.
+
+#define MOXA_ASPP_OQUEUE  	(MOXA + 70)
+#define MOXA_ASPP_SETBAUD 	(MOXA + 71)
+#define MOXA_ASPP_GETBAUD 	(MOXA + 72)
+#define MOXA_ASPP_MON     	(MOXA + 73)
+#define MOXA_ASPP_LSTATUS 	(MOXA + 74)
+#define MOXA_ASPP_MON_EXT 	(MOXA + 75)
+#define MOXA_SET_BAUD_METHOD	(MOXA + 76)
+
+
+/* --------------------------------------------------- */
+
+#define NPPI_NOTIFY_PARITY	0x01
+#define NPPI_NOTIFY_FRAMING	0x02
+#define NPPI_NOTIFY_HW_OVERRUN	0x04
+#define NPPI_NOTIFY_SW_OVERRUN	0x08
+#define NPPI_NOTIFY_BREAK	0x10
+
+#define NPPI_NOTIFY_CTSHOLD         0x01	// Tx hold by CTS low
+#define NPPI_NOTIFY_DSRHOLD         0x02	// Tx hold by DSR low
+#define NPPI_NOTIFY_XOFFHOLD        0x08	// Tx hold by Xoff received
+#define NPPI_NOTIFY_XOFFXENT        0x10	// Xoff Sent
+
+//CheckIsMoxaMust return value
+#define MOXA_OTHER_UART			0x00
+#define MOXA_MUST_MU150_HWID		0x01
+#define MOXA_MUST_MU860_HWID		0x02
+
+// follow just for Moxa Must chip define.
+//
+// when LCR register (offset 0x03) write following value,
+// the Must chip will enter enchance mode. And write value
+// on EFR (offset 0x02) bit 6,7 to change bank.
+#define MOXA_MUST_ENTER_ENCHANCE	0xBF
+
+// when enhance mode enable, access on general bank register
+#define MOXA_MUST_GDL_REGISTER		0x07
+#define MOXA_MUST_GDL_MASK		0x7F
+#define MOXA_MUST_GDL_HAS_BAD_DATA	0x80
+
+#define MOXA_MUST_LSR_RERR		0x80	// error in receive FIFO
+// enchance register bank select and enchance mode setting register
+// when LCR register equal to 0xBF
+#define MOXA_MUST_EFR_REGISTER		0x02
+// enchance mode enable
+#define MOXA_MUST_EFR_EFRB_ENABLE	0x10
+// enchance reister bank set 0, 1, 2
+#define MOXA_MUST_EFR_BANK0		0x00
+#define MOXA_MUST_EFR_BANK1		0x40
+#define MOXA_MUST_EFR_BANK2		0x80
+#define MOXA_MUST_EFR_BANK3		0xC0
+#define MOXA_MUST_EFR_BANK_MASK		0xC0
+
+// set XON1 value register, when LCR=0xBF and change to bank0
+#define MOXA_MUST_XON1_REGISTER		0x04
+
+// set XON2 value register, when LCR=0xBF and change to bank0
+#define MOXA_MUST_XON2_REGISTER		0x05
+
+// set XOFF1 value register, when LCR=0xBF and change to bank0
+#define MOXA_MUST_XOFF1_REGISTER	0x06
+
+// set XOFF2 value register, when LCR=0xBF and change to bank0
+#define MOXA_MUST_XOFF2_REGISTER	0x07
+
+#define MOXA_MUST_RBRTL_REGISTER	0x04
+#define MOXA_MUST_RBRTH_REGISTER	0x05
+#define MOXA_MUST_RBRTI_REGISTER	0x06
+#define MOXA_MUST_THRTL_REGISTER	0x07
+#define MOXA_MUST_ENUM_REGISTER		0x04
+#define MOXA_MUST_HWID_REGISTER		0x05
+#define MOXA_MUST_ECR_REGISTER		0x06
+#define MOXA_MUST_CSR_REGISTER		0x07
+
+// good data mode enable
+#define MOXA_MUST_FCR_GDA_MODE_ENABLE	0x20
+// only good data put into RxFIFO
+#define MOXA_MUST_FCR_GDA_ONLY_ENABLE	0x10
+
+// enable CTS interrupt
+#define MOXA_MUST_IER_ECTSI		0x80
+// enable RTS interrupt
+#define MOXA_MUST_IER_ERTSI		0x40
+// enable Xon/Xoff interrupt
+#define MOXA_MUST_IER_XINT		0x20
+// enable GDA interrupt
+#define MOXA_MUST_IER_EGDAI		0x10
+
+#define MOXA_MUST_RECV_ISR		(UART_IER_RDI | MOXA_MUST_IER_EGDAI)
+
+// GDA interrupt pending
+#define MOXA_MUST_IIR_GDA		0x1C
+#define MOXA_MUST_IIR_RDA		0x04
+#define MOXA_MUST_IIR_RTO		0x0C
+#define MOXA_MUST_IIR_LSR		0x06
+
+// recieved Xon/Xoff or specical interrupt pending
+#define MOXA_MUST_IIR_XSC		0x10
+
+// RTS/CTS change state interrupt pending
+#define MOXA_MUST_IIR_RTSCTS		0x20
+#define MOXA_MUST_IIR_MASK		0x3E
+
+#define MOXA_MUST_MCR_XON_FLAG		0x40
+#define MOXA_MUST_MCR_XON_ANY		0x80
+#define MOXA_MUST_MCR_TX_XON		0x08
+
+
+// software flow control on chip mask value
+#define MOXA_MUST_EFR_SF_MASK		0x0F
+// send Xon1/Xoff1
+#define MOXA_MUST_EFR_SF_TX1		0x08
+// send Xon2/Xoff2
+#define MOXA_MUST_EFR_SF_TX2		0x04
+// send Xon1,Xon2/Xoff1,Xoff2
+#define MOXA_MUST_EFR_SF_TX12		0x0C
+// don't send Xon/Xoff
+#define MOXA_MUST_EFR_SF_TX_NO		0x00
+// Tx software flow control mask
+#define MOXA_MUST_EFR_SF_TX_MASK	0x0C
+// don't receive Xon/Xoff
+#define MOXA_MUST_EFR_SF_RX_NO		0x00
+// receive Xon1/Xoff1
+#define MOXA_MUST_EFR_SF_RX1		0x02
+// receive Xon2/Xoff2
+#define MOXA_MUST_EFR_SF_RX2		0x01
+// receive Xon1,Xon2/Xoff1,Xoff2
+#define MOXA_MUST_EFR_SF_RX12		0x03
+// Rx software flow control mask
+#define MOXA_MUST_EFR_SF_RX_MASK	0x03
+
+//#define MOXA_MUST_MIN_XOFFLIMIT               66
+//#define MOXA_MUST_MIN_XONLIMIT                20
+//#define ID1_RX_TRIG                   120
+
+
+#define CHECK_MOXA_MUST_XOFFLIMIT(info) { 	\
+	if ( (info)->IsMoxaMustChipFlag && 	\
+	 (info)->HandFlow.XoffLimit < MOXA_MUST_MIN_XOFFLIMIT ) {	\
+		(info)->HandFlow.XoffLimit = MOXA_MUST_MIN_XOFFLIMIT;	\
+		(info)->HandFlow.XonLimit = MOXA_MUST_MIN_XONLIMIT;	\
+	}	\
+}
+
+#define ENABLE_MOXA_MUST_ENCHANCE_MODE(baseio) { \
+	u8	__oldlcr, __efr;	\
+	__oldlcr = inb((baseio)+UART_LCR);	\
+	outb(MOXA_MUST_ENTER_ENCHANCE, (baseio)+UART_LCR);	\
+	__efr = inb((baseio)+MOXA_MUST_EFR_REGISTER);	\
+	__efr |= MOXA_MUST_EFR_EFRB_ENABLE;	\
+	outb(__efr, (baseio)+MOXA_MUST_EFR_REGISTER);	\
+	outb(__oldlcr, (baseio)+UART_LCR);	\
+}
+
+#define DISABLE_MOXA_MUST_ENCHANCE_MODE(baseio) {	\
+	u8	__oldlcr, __efr;	\
+	__oldlcr = inb((baseio)+UART_LCR);	\
+	outb(MOXA_MUST_ENTER_ENCHANCE, (baseio)+UART_LCR);	\
+	__efr = inb((baseio)+MOXA_MUST_EFR_REGISTER);	\
+	__efr &= ~MOXA_MUST_EFR_EFRB_ENABLE;	\
+	outb(__efr, (baseio)+MOXA_MUST_EFR_REGISTER);	\
+	outb(__oldlcr, (baseio)+UART_LCR);	\
+}
+
+#define SET_MOXA_MUST_XON1_VALUE(baseio, Value) {	\
+	u8	__oldlcr, __efr;	\
+	__oldlcr = inb((baseio)+UART_LCR);	\
+	outb(MOXA_MUST_ENTER_ENCHANCE, (baseio)+UART_LCR);	\
+	__efr = inb((baseio)+MOXA_MUST_EFR_REGISTER);	\
+	__efr &= ~MOXA_MUST_EFR_BANK_MASK;	\
+	__efr |= MOXA_MUST_EFR_BANK0;	\
+	outb(__efr, (baseio)+MOXA_MUST_EFR_REGISTER);	\
+	outb((u8)(Value), (baseio)+MOXA_MUST_XON1_REGISTER);	\
+	outb(__oldlcr, (baseio)+UART_LCR);	\
+}
+
+#define SET_MOXA_MUST_XON2_VALUE(baseio, Value) {	\
+	u8	__oldlcr, __efr;	\
+	__oldlcr = inb((baseio)+UART_LCR);	\
+	outb(MOXA_MUST_ENTER_ENCHANCE, (baseio)+UART_LCR);	\
+	__efr = inb((baseio)+MOXA_MUST_EFR_REGISTER);	\
+	__efr &= ~MOXA_MUST_EFR_BANK_MASK;	\
+	__efr |= MOXA_MUST_EFR_BANK0;	\
+	outb(__efr, (baseio)+MOXA_MUST_EFR_REGISTER);	\
+	outb((u8)(Value), (baseio)+MOXA_MUST_XON2_REGISTER);	\
+	outb(__oldlcr, (baseio)+UART_LCR);	\
+}
+
+#define SET_MOXA_MUST_XOFF1_VALUE(baseio, Value) {	\
+	u8	__oldlcr, __efr;	\
+	__oldlcr = inb((baseio)+UART_LCR);	\
+	outb(MOXA_MUST_ENTER_ENCHANCE, (baseio)+UART_LCR);	\
+	__efr = inb((baseio)+MOXA_MUST_EFR_REGISTER);	\
+	__efr &= ~MOXA_MUST_EFR_BANK_MASK;	\
+	__efr |= MOXA_MUST_EFR_BANK0;	\
+	outb(__efr, (baseio)+MOXA_MUST_EFR_REGISTER);	\
+	outb((u8)(Value), (baseio)+MOXA_MUST_XOFF1_REGISTER);	\
+	outb(__oldlcr, (baseio)+UART_LCR);	\
+}
+
+#define SET_MOXA_MUST_XOFF2_VALUE(baseio, Value) {	\
+	u8	__oldlcr, __efr;	\
+	__oldlcr = inb((baseio)+UART_LCR);	\
+	outb(MOXA_MUST_ENTER_ENCHANCE, (baseio)+UART_LCR);	\
+	__efr = inb((baseio)+MOXA_MUST_EFR_REGISTER);	\
+	__efr &= ~MOXA_MUST_EFR_BANK_MASK;	\
+	__efr |= MOXA_MUST_EFR_BANK0;	\
+	outb(__efr, (baseio)+MOXA_MUST_EFR_REGISTER);	\
+	outb((u8)(Value), (baseio)+MOXA_MUST_XOFF2_REGISTER);	\
+	outb(__oldlcr, (baseio)+UART_LCR);	\
+}
+
+#define SET_MOXA_MUST_RBRTL_VALUE(baseio, Value) {	\
+	u8	__oldlcr, __efr;	\
+	__oldlcr = inb((baseio)+UART_LCR);	\
+	outb(MOXA_MUST_ENTER_ENCHANCE, (baseio)+UART_LCR);	\
+	__efr = inb((baseio)+MOXA_MUST_EFR_REGISTER);	\
+	__efr &= ~MOXA_MUST_EFR_BANK_MASK;	\
+	__efr |= MOXA_MUST_EFR_BANK1;	\
+	outb(__efr, (baseio)+MOXA_MUST_EFR_REGISTER);	\
+	outb((u8)(Value), (baseio)+MOXA_MUST_RBRTL_REGISTER);	\
+	outb(__oldlcr, (baseio)+UART_LCR);	\
+}
+
+#define SET_MOXA_MUST_RBRTH_VALUE(baseio, Value) {	\
+	u8	__oldlcr, __efr;	\
+	__oldlcr = inb((baseio)+UART_LCR);	\
+	outb(MOXA_MUST_ENTER_ENCHANCE, (baseio)+UART_LCR);	\
+	__efr = inb((baseio)+MOXA_MUST_EFR_REGISTER);	\
+	__efr &= ~MOXA_MUST_EFR_BANK_MASK;	\
+	__efr |= MOXA_MUST_EFR_BANK1;	\
+	outb(__efr, (baseio)+MOXA_MUST_EFR_REGISTER);	\
+	outb((u8)(Value), (baseio)+MOXA_MUST_RBRTH_REGISTER);	\
+	outb(__oldlcr, (baseio)+UART_LCR);	\
+}
+
+#define SET_MOXA_MUST_RBRTI_VALUE(baseio, Value) {	\
+	u8	__oldlcr, __efr;	\
+	__oldlcr = inb((baseio)+UART_LCR);	\
+	outb(MOXA_MUST_ENTER_ENCHANCE, (baseio)+UART_LCR);	\
+	__efr = inb((baseio)+MOXA_MUST_EFR_REGISTER);	\
+	__efr &= ~MOXA_MUST_EFR_BANK_MASK;	\
+	__efr |= MOXA_MUST_EFR_BANK1;	\
+	outb(__efr, (baseio)+MOXA_MUST_EFR_REGISTER);	\
+	outb((u8)(Value), (baseio)+MOXA_MUST_RBRTI_REGISTER);	\
+	outb(__oldlcr, (baseio)+UART_LCR);	\
+}
+
+#define SET_MOXA_MUST_THRTL_VALUE(baseio, Value) {	\
+	u8	__oldlcr, __efr;	\
+	__oldlcr = inb((baseio)+UART_LCR);	\
+	outb(MOXA_MUST_ENTER_ENCHANCE, (baseio)+UART_LCR);	\
+	__efr = inb((baseio)+MOXA_MUST_EFR_REGISTER);	\
+	__efr &= ~MOXA_MUST_EFR_BANK_MASK;	\
+	__efr |= MOXA_MUST_EFR_BANK1;	\
+	outb(__efr, (baseio)+MOXA_MUST_EFR_REGISTER);	\
+	outb((u8)(Value), (baseio)+MOXA_MUST_THRTL_REGISTER);	\
+	outb(__oldlcr, (baseio)+UART_LCR);	\
+}
+
+//#define MOXA_MUST_RBRL_VALUE  4
+#define SET_MOXA_MUST_FIFO_VALUE(info) {	\
+	u8	__oldlcr, __efr;	\
+	__oldlcr = inb((info)->ioaddr+UART_LCR);	\
+	outb(MOXA_MUST_ENTER_ENCHANCE, (info)->ioaddr+UART_LCR);	\
+	__efr = inb((info)->ioaddr+MOXA_MUST_EFR_REGISTER);	\
+	__efr &= ~MOXA_MUST_EFR_BANK_MASK;	\
+	__efr |= MOXA_MUST_EFR_BANK1;	\
+	outb(__efr, (info)->ioaddr+MOXA_MUST_EFR_REGISTER);	\
+	outb((u8)((info)->rx_high_water), (info)->ioaddr+MOXA_MUST_RBRTH_REGISTER);	\
+	outb((u8)((info)->rx_trigger), (info)->ioaddr+MOXA_MUST_RBRTI_REGISTER);	\
+	outb((u8)((info)->rx_low_water), (info)->ioaddr+MOXA_MUST_RBRTL_REGISTER);	\
+	outb(__oldlcr, (info)->ioaddr+UART_LCR);	\
+}
+
+
+
+#define SET_MOXA_MUST_ENUM_VALUE(baseio, Value) {	\
+	u8	__oldlcr, __efr;	\
+	__oldlcr = inb((baseio)+UART_LCR);	\
+	outb(MOXA_MUST_ENTER_ENCHANCE, (baseio)+UART_LCR);	\
+	__efr = inb((baseio)+MOXA_MUST_EFR_REGISTER);	\
+	__efr &= ~MOXA_MUST_EFR_BANK_MASK;	\
+	__efr |= MOXA_MUST_EFR_BANK2;	\
+	outb(__efr, (baseio)+MOXA_MUST_EFR_REGISTER);	\
+	outb((u8)(Value), (baseio)+MOXA_MUST_ENUM_REGISTER);	\
+	outb(__oldlcr, (baseio)+UART_LCR);	\
+}
+
+#define GET_MOXA_MUST_HARDWARE_ID(baseio, pId) {	\
+	u8	__oldlcr, __efr;	\
+	__oldlcr = inb((baseio)+UART_LCR);	\
+	outb(MOXA_MUST_ENTER_ENCHANCE, (baseio)+UART_LCR);	\
+	__efr = inb((baseio)+MOXA_MUST_EFR_REGISTER);	\
+	__efr &= ~MOXA_MUST_EFR_BANK_MASK;	\
+	__efr |= MOXA_MUST_EFR_BANK2;	\
+	outb(__efr, (baseio)+MOXA_MUST_EFR_REGISTER);	\
+	*pId = inb((baseio)+MOXA_MUST_HWID_REGISTER);	\
+	outb(__oldlcr, (baseio)+UART_LCR);	\
+}
+
+#define SET_MOXA_MUST_NO_SOFTWARE_FLOW_CONTROL(baseio) {	\
+	u8	__oldlcr, __efr;	\
+	__oldlcr = inb((baseio)+UART_LCR);	\
+	outb(MOXA_MUST_ENTER_ENCHANCE, (baseio)+UART_LCR);	\
+	__efr = inb((baseio)+MOXA_MUST_EFR_REGISTER);	\
+	__efr &= ~MOXA_MUST_EFR_SF_MASK;	\
+	outb(__efr, (baseio)+MOXA_MUST_EFR_REGISTER);	\
+	outb(__oldlcr, (baseio)+UART_LCR);	\
+}
+
+#define SET_MOXA_MUST_JUST_TX_SOFTWARE_FLOW_CONTROL(baseio) {	\
+	u8	__oldlcr, __efr;	\
+	__oldlcr = inb((baseio)+UART_LCR);	\
+	outb(MOXA_MUST_ENTER_ENCHANCE, (baseio)+UART_LCR);	\
+	__efr = inb((baseio)+MOXA_MUST_EFR_REGISTER);	\
+	__efr &= ~MOXA_MUST_EFR_SF_MASK;	\
+	__efr |= MOXA_MUST_EFR_SF_TX1;	\
+	outb(__efr, (baseio)+MOXA_MUST_EFR_REGISTER);	\
+	outb(__oldlcr, (baseio)+UART_LCR);	\
+}
+
+#define ENABLE_MOXA_MUST_TX_SOFTWARE_FLOW_CONTROL(baseio) {	\
+	u8	__oldlcr, __efr;	\
+	__oldlcr = inb((baseio)+UART_LCR);	\
+	outb(MOXA_MUST_ENTER_ENCHANCE, (baseio)+UART_LCR);	\
+	__efr = inb((baseio)+MOXA_MUST_EFR_REGISTER);	\
+	__efr &= ~MOXA_MUST_EFR_SF_TX_MASK;	\
+	__efr |= MOXA_MUST_EFR_SF_TX1;	\
+	outb(__efr, (baseio)+MOXA_MUST_EFR_REGISTER);	\
+	outb(__oldlcr, (baseio)+UART_LCR);	\
+}
+
+#define DISABLE_MOXA_MUST_TX_SOFTWARE_FLOW_CONTROL(baseio) {	\
+	u8	__oldlcr, __efr;	\
+	__oldlcr = inb((baseio)+UART_LCR);	\
+	outb(MOXA_MUST_ENTER_ENCHANCE, (baseio)+UART_LCR);	\
+	__efr = inb((baseio)+MOXA_MUST_EFR_REGISTER);	\
+	__efr &= ~MOXA_MUST_EFR_SF_TX_MASK;	\
+	outb(__efr, (baseio)+MOXA_MUST_EFR_REGISTER);	\
+	outb(__oldlcr, (baseio)+UART_LCR);	\
+}
+
+#define SET_MOXA_MUST_JUST_RX_SOFTWARE_FLOW_CONTROL(baseio) {	\
+	u8	__oldlcr, __efr;	\
+	__oldlcr = inb((baseio)+UART_LCR);	\
+	outb(MOXA_MUST_ENTER_ENCHANCE, (baseio)+UART_LCR);	\
+	__efr = inb((baseio)+MOXA_MUST_EFR_REGISTER);	\
+	__efr &= ~MOXA_MUST_EFR_SF_MASK;	\
+	__efr |= MOXA_MUST_EFR_SF_RX1;	\
+	outb(__efr, (baseio)+MOXA_MUST_EFR_REGISTER);	\
+	outb(__oldlcr, (baseio)+UART_LCR);	\
+}
+
+#define ENABLE_MOXA_MUST_RX_SOFTWARE_FLOW_CONTROL(baseio) {	\
+	u8	__oldlcr, __efr;	\
+	__oldlcr = inb((baseio)+UART_LCR);	\
+	outb(MOXA_MUST_ENTER_ENCHANCE, (baseio)+UART_LCR);	\
+	__efr = inb((baseio)+MOXA_MUST_EFR_REGISTER);	\
+	__efr &= ~MOXA_MUST_EFR_SF_RX_MASK;	\
+	__efr |= MOXA_MUST_EFR_SF_RX1;	\
+	outb(__efr, (baseio)+MOXA_MUST_EFR_REGISTER);	\
+	outb(__oldlcr, (baseio)+UART_LCR);	\
+}
+
+#define DISABLE_MOXA_MUST_RX_SOFTWARE_FLOW_CONTROL(baseio) {	\
+	u8	__oldlcr, __efr;	\
+	__oldlcr = inb((baseio)+UART_LCR);	\
+	outb(MOXA_MUST_ENTER_ENCHANCE, (baseio)+UART_LCR);	\
+	__efr = inb((baseio)+MOXA_MUST_EFR_REGISTER);	\
+	__efr &= ~MOXA_MUST_EFR_SF_RX_MASK;	\
+	outb(__efr, (baseio)+MOXA_MUST_EFR_REGISTER);	\
+	outb(__oldlcr, (baseio)+UART_LCR);	\
+}
+
+#define ENABLE_MOXA_MUST_TX_RX_SOFTWARE_FLOW_CONTROL(baseio) {	\
+	u8	__oldlcr, __efr;	\
+	__oldlcr = inb((baseio)+UART_LCR);	\
+	outb(MOXA_MUST_ENTER_ENCHANCE, (baseio)+UART_LCR);	\
+	__efr = inb((baseio)+MOXA_MUST_EFR_REGISTER);	\
+	__efr &= ~MOXA_MUST_EFR_SF_MASK;	\
+	__efr |= (MOXA_MUST_EFR_SF_RX1|MOXA_MUST_EFR_SF_TX1);	\
+	outb(__efr, (baseio)+MOXA_MUST_EFR_REGISTER);	\
+	outb(__oldlcr, (baseio)+UART_LCR);	\
+}
+
+#define ENABLE_MOXA_MUST_XON_ANY_FLOW_CONTROL(baseio) {	\
+	u8	__oldmcr;	\
+	__oldmcr = inb((baseio)+UART_MCR);	\
+	__oldmcr |= MOXA_MUST_MCR_XON_ANY;	\
+	outb(__oldmcr, (baseio)+UART_MCR);	\
+}
+
+#define DISABLE_MOXA_MUST_XON_ANY_FLOW_CONTROL(baseio) {	\
+	u8	__oldmcr;	\
+	__oldmcr = inb((baseio)+UART_MCR);	\
+	__oldmcr &= ~MOXA_MUST_MCR_XON_ANY;	\
+	outb(__oldmcr, (baseio)+UART_MCR);	\
+}
+
+#define READ_MOXA_MUST_GDL(baseio)	inb((baseio)+MOXA_MUST_GDL_REGISTER)
+
+
+#ifndef INIT_WORK
+#define INIT_WORK(_work, _func, _data){	\
+	_data->tqueue.routine = _func;\
+	_data->tqueue.data = _data;\
+	}
+#endif
+
+#endif
diff --git a/drivers/char/n_r3964.c b/drivers/char/n_r3964.c
index 203dc2b661d5..103d338f21e2 100644
--- a/drivers/char/n_r3964.c
+++ b/drivers/char/n_r3964.c
@@ -142,7 +142,7 @@ static ssize_t r3964_write(struct tty_struct * tty, struct file * file,
                       const unsigned char * buf, size_t nr);
 static int r3964_ioctl(struct tty_struct * tty, struct file * file,
                        unsigned int cmd, unsigned long arg);
-static void r3964_set_termios(struct tty_struct *tty, struct termios * old);
+static void r3964_set_termios(struct tty_struct *tty, struct ktermios * old);
 static unsigned int r3964_poll(struct tty_struct * tty, struct file * file,
 		      struct poll_table_struct  *wait);
 static void r3964_receive_buf(struct tty_struct *tty, const unsigned char *cp,
@@ -1347,7 +1347,7 @@ static int r3964_ioctl(struct tty_struct * tty, struct file * file,
    }
 }
 
-static void r3964_set_termios(struct tty_struct *tty, struct termios * old)
+static void r3964_set_termios(struct tty_struct *tty, struct ktermios * old)
 {
    TRACE_L("set_termios");
 }
diff --git a/drivers/char/n_tty.c b/drivers/char/n_tty.c
index 603b9ade5eb0..e96a00fe1389 100644
--- a/drivers/char/n_tty.c
+++ b/drivers/char/n_tty.c
@@ -994,7 +994,7 @@ int is_ignored(int sig)
  *	when the ldisc is closed.
  */
  
-static void n_tty_set_termios(struct tty_struct *tty, struct termios * old)
+static void n_tty_set_termios(struct tty_struct *tty, struct ktermios * old)
 {
 	if (!tty)
 		return;
diff --git a/drivers/char/nsc_gpio.c b/drivers/char/nsc_gpio.c
index 4d47d79bcea7..808d44e9a32a 100644
--- a/drivers/char/nsc_gpio.c
+++ b/drivers/char/nsc_gpio.c
@@ -41,7 +41,7 @@ void nsc_gpio_dump(struct nsc_gpio_ops *amp, unsigned index)
 ssize_t nsc_gpio_write(struct file *file, const char __user *data,
 		       size_t len, loff_t *ppos)
 {
-	unsigned m = iminor(file->f_dentry->d_inode);
+	unsigned m = iminor(file->f_path.dentry->d_inode);
 	struct nsc_gpio_ops *amp = file->private_data;
 	struct device *dev = amp->dev;
 	size_t i;
@@ -104,7 +104,7 @@ ssize_t nsc_gpio_write(struct file *file, const char __user *data,
 ssize_t nsc_gpio_read(struct file *file, char __user * buf,
 		      size_t len, loff_t * ppos)
 {
-	unsigned m = iminor(file->f_dentry->d_inode);
+	unsigned m = iminor(file->f_path.dentry->d_inode);
 	int value;
 	struct nsc_gpio_ops *amp = file->private_data;
 
diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c
index 74d21c1c104f..5152cedd8878 100644
--- a/drivers/char/pcmcia/synclink_cs.c
+++ b/drivers/char/pcmcia/synclink_cs.c
@@ -2375,7 +2375,7 @@ static int ioctl_common(MGSLPC_INFO *info, unsigned int cmd, unsigned long arg)
  * 	tty		pointer to tty structure
  * 	termios		pointer to buffer to hold returned old termios
  */
-static void mgslpc_set_termios(struct tty_struct *tty, struct termios *old_termios)
+static void mgslpc_set_termios(struct tty_struct *tty, struct ktermios *old_termios)
 {
 	MGSLPC_INFO *info = (MGSLPC_INFO *)tty->driver_data;
 	unsigned long flags;
diff --git a/drivers/char/ppdev.c b/drivers/char/ppdev.c
index c1e3dd837fc8..4abd1eff61d6 100644
--- a/drivers/char/ppdev.c
+++ b/drivers/char/ppdev.c
@@ -106,7 +106,7 @@ static inline void pp_enable_irq (struct pp_struct *pp)
 static ssize_t pp_read (struct file * file, char __user * buf, size_t count,
 			loff_t * ppos)
 {
-	unsigned int minor = iminor(file->f_dentry->d_inode);
+	unsigned int minor = iminor(file->f_path.dentry->d_inode);
 	struct pp_struct *pp = file->private_data;
 	char * kbuffer;
 	ssize_t bytes_read = 0;
@@ -189,7 +189,7 @@ static ssize_t pp_read (struct file * file, char __user * buf, size_t count,
 static ssize_t pp_write (struct file * file, const char __user * buf,
 			 size_t count, loff_t * ppos)
 {
-	unsigned int minor = iminor(file->f_dentry->d_inode);
+	unsigned int minor = iminor(file->f_path.dentry->d_inode);
 	struct pp_struct *pp = file->private_data;
 	char * kbuffer;
 	ssize_t bytes_written = 0;
diff --git a/drivers/char/pty.c b/drivers/char/pty.c
index 80d3eedd7f96..c07a1b5cd05d 100644
--- a/drivers/char/pty.c
+++ b/drivers/char/pty.c
@@ -218,7 +218,7 @@ out:
 	return retval;
 }
 
-static void pty_set_termios(struct tty_struct *tty, struct termios *old_termios)
+static void pty_set_termios(struct tty_struct *tty, struct ktermios *old_termios)
 {
         tty->termios->c_cflag &= ~(CSIZE | PARENB);
         tty->termios->c_cflag |= (CS8 | CREAD);
@@ -272,6 +272,8 @@ static void __init legacy_pty_init(void)
 	pty_driver->init_termios.c_oflag = 0;
 	pty_driver->init_termios.c_cflag = B38400 | CS8 | CREAD;
 	pty_driver->init_termios.c_lflag = 0;
+	pty_driver->init_termios.c_ispeed = 38400;
+	pty_driver->init_termios.c_ospeed = 38400;
 	pty_driver->flags = TTY_DRIVER_RESET_TERMIOS | TTY_DRIVER_REAL_RAW;
 	pty_driver->other = pty_slave_driver;
 	tty_set_operations(pty_driver, &pty_ops);
@@ -286,6 +288,8 @@ static void __init legacy_pty_init(void)
 	pty_slave_driver->subtype = PTY_TYPE_SLAVE;
 	pty_slave_driver->init_termios = tty_std_termios;
 	pty_slave_driver->init_termios.c_cflag = B38400 | CS8 | CREAD;
+	pty_slave_driver->init_termios.c_ispeed = 38400;
+	pty_slave_driver->init_termios.c_ospeed = 38400;
 	pty_slave_driver->flags = TTY_DRIVER_RESET_TERMIOS |
 					TTY_DRIVER_REAL_RAW;
 	pty_slave_driver->other = pty_driver;
@@ -366,6 +370,8 @@ static void __init unix98_pty_init(void)
 	ptm_driver->init_termios.c_oflag = 0;
 	ptm_driver->init_termios.c_cflag = B38400 | CS8 | CREAD;
 	ptm_driver->init_termios.c_lflag = 0;
+	ptm_driver->init_termios.c_ispeed = 38400;
+	ptm_driver->init_termios.c_ospeed = 38400;
 	ptm_driver->flags = TTY_DRIVER_RESET_TERMIOS | TTY_DRIVER_REAL_RAW |
 		TTY_DRIVER_DYNAMIC_DEV | TTY_DRIVER_DEVPTS_MEM;
 	ptm_driver->other = pts_driver;
@@ -381,6 +387,8 @@ static void __init unix98_pty_init(void)
 	pts_driver->subtype = PTY_TYPE_SLAVE;
 	pts_driver->init_termios = tty_std_termios;
 	pts_driver->init_termios.c_cflag = B38400 | CS8 | CREAD;
+	pts_driver->init_termios.c_ispeed = 38400;
+	pts_driver->init_termios.c_ospeed = 38400;
 	pts_driver->flags = TTY_DRIVER_RESET_TERMIOS | TTY_DRIVER_REAL_RAW |
 		TTY_DRIVER_DYNAMIC_DEV | TTY_DRIVER_DEVPTS_MEM;
 	pts_driver->other = ptm_driver;
diff --git a/drivers/char/random.c b/drivers/char/random.c
index 4c6782a1ecdb..092a01cc02da 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -1048,7 +1048,7 @@ random_write(struct file * file, const char __user * buffer,
 	if (p == buffer) {
 		return (ssize_t)ret;
 	} else {
-		struct inode *inode = file->f_dentry->d_inode;
+		struct inode *inode = file->f_path.dentry->d_inode;
 	        inode->i_mtime = current_fs_time(inode->i_sb);
 		mark_inode_dirty(inode);
 		return (ssize_t)(p - buffer);
diff --git a/drivers/char/raw.c b/drivers/char/raw.c
index 3b32313f6eb4..645e20a06ece 100644
--- a/drivers/char/raw.c
+++ b/drivers/char/raw.c
@@ -75,7 +75,7 @@ static int raw_open(struct inode *inode, struct file *filp)
 	filp->f_flags |= O_DIRECT;
 	filp->f_mapping = bdev->bd_inode->i_mapping;
 	if (++raw_devices[minor].inuse == 1)
-		filp->f_dentry->d_inode->i_mapping =
+		filp->f_path.dentry->d_inode->i_mapping =
 			bdev->bd_inode->i_mapping;
 	filp->private_data = bdev;
 	mutex_unlock(&raw_mutex);
diff --git a/drivers/char/riscom8.c b/drivers/char/riscom8.c
index 0a77bfcd5b5e..e2a94bfb2a43 100644
--- a/drivers/char/riscom8.c
+++ b/drivers/char/riscom8.c
@@ -1539,7 +1539,7 @@ static void rc_hangup(struct tty_struct * tty)
 	wake_up_interruptible(&port->open_wait);
 }
 
-static void rc_set_termios(struct tty_struct * tty, struct termios * old_termios)
+static void rc_set_termios(struct tty_struct * tty, struct ktermios * old_termios)
 {
 	struct riscom_port *port = (struct riscom_port *)tty->driver_data;
 	unsigned long flags;
@@ -1614,6 +1614,8 @@ static inline int rc_init_drivers(void)
 	riscom_driver->init_termios = tty_std_termios;
 	riscom_driver->init_termios.c_cflag =
 		B9600 | CS8 | CREAD | HUPCL | CLOCAL;
+	riscom_driver->init_termios.c_ispeed = 9600;
+	riscom_driver->init_termios.c_ospeed = 9600;
 	riscom_driver->flags = TTY_DRIVER_REAL_RAW;
 	tty_set_operations(riscom_driver, &riscom_ops);
 	if ((error = tty_register_driver(riscom_driver)))  {
diff --git a/drivers/char/rocket.c b/drivers/char/rocket.c
index bac80056f7e0..e94a62e30fc4 100644
--- a/drivers/char/rocket.c
+++ b/drivers/char/rocket.c
@@ -712,7 +712,7 @@ static void init_r_port(int board, int aiop, int chan, struct pci_dev *pci_dev)
  *  user mode into the driver (exception handler).  *info CD manipulation is spinlock protected.
  */
 static void configure_r_port(struct r_port *info,
-			     struct termios *old_termios)
+			     struct ktermios *old_termios)
 {
 	unsigned cflag;
 	unsigned long flags;
@@ -1017,7 +1017,7 @@ static int rp_open(struct tty_struct *tty, struct file *filp)
 	/*
 	 * Info->count is now 1; so it's safe to sleep now.
 	 */
-	info->session = current->signal->session;
+	info->session = process_session(current);
 	info->pgrp = process_group(current);
 
 	if ((info->flags & ROCKET_INITIALIZED) == 0) {
@@ -1194,7 +1194,7 @@ static void rp_close(struct tty_struct *tty, struct file *filp)
 }
 
 static void rp_set_termios(struct tty_struct *tty,
-			   struct termios *old_termios)
+			   struct ktermios *old_termios)
 {
 	struct r_port *info = (struct r_port *) tty->driver_data;
 	CHANNEL_t *cp;
@@ -2214,7 +2214,7 @@ static int __init init_PCI(int boards_found)
 	int count = 0;
 
 	/*  Work through the PCI device list, pulling out ours */
-	while ((dev = pci_find_device(PCI_VENDOR_ID_RP, PCI_ANY_ID, dev))) {
+	while ((dev = pci_get_device(PCI_VENDOR_ID_RP, PCI_ANY_ID, dev))) {
 		if (register_PCI(count + boards_found, dev))
 			count++;
 	}
@@ -2436,6 +2436,8 @@ static int __init rp_init(void)
 	rocket_driver->init_termios = tty_std_termios;
 	rocket_driver->init_termios.c_cflag =
 	    B9600 | CS8 | CREAD | HUPCL | CLOCAL;
+	rocket_driver->init_termios.c_ispeed = 9600;
+	rocket_driver->init_termios.c_ospeed = 9600;
 #ifdef ROCKET_SOFT_FLOW
 	rocket_driver->flags |= TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
 #endif
diff --git a/drivers/char/ser_a2232.c b/drivers/char/ser_a2232.c
index 4217d38caef9..75de5f66517a 100644
--- a/drivers/char/ser_a2232.c
+++ b/drivers/char/ser_a2232.c
@@ -695,6 +695,8 @@ static int a2232_init_drivers(void)
 	a2232_driver->init_termios = tty_std_termios;
 	a2232_driver->init_termios.c_cflag =
 		B9600 | CS8 | CREAD | HUPCL | CLOCAL;
+	a2232_driver->init_termios.c_ispeed = 9600;
+	a2232_driver->init_termios.c_ospeed = 9600;
 	a2232_driver->flags = TTY_DRIVER_REAL_RAW;
 	tty_set_operations(a2232_driver, &a2232_ops);
 	if ((error = tty_register_driver(a2232_driver))) {
diff --git a/drivers/char/serial167.c b/drivers/char/serial167.c
index 9ba13af234be..af50d32ae2c7 100644
--- a/drivers/char/serial167.c
+++ b/drivers/char/serial167.c
@@ -1695,7 +1695,7 @@ cy_ioctl(struct tty_struct *tty, struct file * file,
 
 
 static void
-cy_set_termios(struct tty_struct *tty, struct termios * old_termios)
+cy_set_termios(struct tty_struct *tty, struct ktermios * old_termios)
 {
   struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
 
diff --git a/drivers/char/sonypi.c b/drivers/char/sonypi.c
index fc87070f1866..17d54e1331b2 100644
--- a/drivers/char/sonypi.c
+++ b/drivers/char/sonypi.c
@@ -979,7 +979,7 @@ static ssize_t sonypi_misc_read(struct file *file, char __user *buf,
 	}
 
 	if (ret > 0) {
-		struct inode *inode = file->f_dentry->d_inode;
+		struct inode *inode = file->f_path.dentry->d_inode;
 		inode->i_atime = current_fs_time(inode->i_sb);
 	}
 
diff --git a/drivers/char/specialix.c b/drivers/char/specialix.c
index 99137ab66b62..20946f5127e0 100644
--- a/drivers/char/specialix.c
+++ b/drivers/char/specialix.c
@@ -2311,7 +2311,7 @@ static void sx_hangup(struct tty_struct * tty)
 }
 
 
-static void sx_set_termios(struct tty_struct * tty, struct termios * old_termios)
+static void sx_set_termios(struct tty_struct * tty, struct ktermios * old_termios)
 {
 	struct specialix_port *port = (struct specialix_port *)tty->driver_data;
 	unsigned long flags;
@@ -2400,6 +2400,8 @@ static int sx_init_drivers(void)
 	specialix_driver->init_termios = tty_std_termios;
 	specialix_driver->init_termios.c_cflag =
 		B9600 | CS8 | CREAD | HUPCL | CLOCAL;
+	specialix_driver->init_termios.c_ispeed = 9600;
+	specialix_driver->init_termios.c_ospeed = 9600;
 	specialix_driver->flags = TTY_DRIVER_REAL_RAW;
 	tty_set_operations(specialix_driver, &sx_ops);
 
@@ -2475,7 +2477,7 @@ static int __init specialix_init(void)
 				i++;
 				continue;
 			}
-			pdev = pci_find_device (PCI_VENDOR_ID_SPECIALIX,
+			pdev = pci_get_device (PCI_VENDOR_ID_SPECIALIX,
 			                        PCI_DEVICE_ID_SPECIALIX_IO8,
 			                        pdev);
 			if (!pdev) break;
@@ -2491,6 +2493,9 @@ static int __init specialix_init(void)
 			if (!sx_probe(&sx_board[i]))
 				found ++;
 		}
+		/* May exit pci_get sequence early with lots of boards */
+		if (pdev != NULL)
+			pci_dev_put(pdev);
 	}
 #endif
 
diff --git a/drivers/char/stallion.c b/drivers/char/stallion.c
index 5e2de62bce70..e45113a7a472 100644
--- a/drivers/char/stallion.c
+++ b/drivers/char/stallion.c
@@ -41,13 +41,12 @@
 #include <linux/smp_lock.h>
 #include <linux/device.h>
 #include <linux/delay.h>
+#include <linux/ctype.h>
 
 #include <asm/io.h>
 #include <asm/uaccess.h>
 
-#ifdef CONFIG_PCI
 #include <linux/pci.h>
-#endif
 
 /*****************************************************************************/
 
@@ -63,45 +62,16 @@
 #define	BRD_ECH64PCI	27
 #define	BRD_EASYIOPCI	28
 
-/*
- *	Define a configuration structure to hold the board configuration.
- *	Need to set this up in the code (for now) with the boards that are
- *	to be configured into the system. This is what needs to be modified
- *	when adding/removing/modifying boards. Each line entry in the
- *	stl_brdconf[] array is a board. Each line contains io/irq/memory
- *	ranges for that board (as well as what type of board it is).
- *	Some examples:
- *		{ BRD_EASYIO, 0x2a0, 0, 0, 10, 0 },
- *	This line would configure an EasyIO board (4 or 8, no difference),
- *	at io address 2a0 and irq 10.
- *	Another example:
- *		{ BRD_ECH, 0x2a8, 0x280, 0, 12, 0 },
- *	This line will configure an EasyConnection 8/32 board at primary io
- *	address 2a8, secondary io address 280 and irq 12.
- *	Enter as many lines into this array as you want (only the first 4
- *	will actually be used!). Any combination of EasyIO and EasyConnection
- *	boards can be specified. EasyConnection 8/32 boards can share their
- *	secondary io addresses between each other.
- *
- *	NOTE: there is no need to put any entries in this table for PCI
- *	boards. They will be found automatically by the driver - provided
- *	PCI BIOS32 support is compiled into the kernel.
- */
-
-typedef struct {
-	int		brdtype;
+struct stlconf {
+	unsigned int	brdtype;
 	int		ioaddr1;
 	int		ioaddr2;
 	unsigned long	memaddr;
 	int		irq;
 	int		irqtype;
-} stlconf_t;
-
-static stlconf_t	stl_brdconf[] = {
-	/*{ BRD_EASYIO, 0x2a0, 0, 0, 10, 0 },*/
 };
 
-static int	stl_nrbrds = ARRAY_SIZE(stl_brdconf);
+static unsigned int stl_nrbrds;
 
 /*****************************************************************************/
 
@@ -143,34 +113,30 @@ static struct tty_driver	*stl_serial;
  *	with this termios initially. Basically all it defines is a raw port
  *	at 9600, 8 data bits, 1 stop bit.
  */
-static struct termios		stl_deftermios = {
+static struct ktermios		stl_deftermios = {
 	.c_cflag	= (B9600 | CS8 | CREAD | HUPCL | CLOCAL),
 	.c_cc		= INIT_C_CC,
+	.c_ispeed	= 9600,
+	.c_ospeed	= 9600,
 };
 
 /*
- *	Define global stats structures. Not used often, and can be
- *	re-used for each stats call.
- */
-static comstats_t	stl_comstats;
-static combrd_t		stl_brdstats;
-static stlbrd_t		stl_dummybrd;
-static stlport_t	stl_dummyport;
-
-/*
  *	Define global place to put buffer overflow characters.
  */
 static char		stl_unwanted[SC26198_RXFIFOSIZE];
 
 /*****************************************************************************/
 
-static stlbrd_t		*stl_brds[STL_MAXBRDS];
+static DEFINE_MUTEX(stl_brdslock);
+static struct stlbrd		*stl_brds[STL_MAXBRDS];
 
 /*
  *	Per board state flags. Used with the state field of the board struct.
  *	Not really much here!
  */
 #define	BRD_FOUND	0x1
+#define STL_PROBED	0x2
+
 
 /*
  *	Define the port structure istate flags. These set of flags are
@@ -187,32 +153,32 @@ static stlbrd_t		*stl_brds[STL_MAXBRDS];
  *	referencing boards when printing trace and stuff.
  */
 static char	*stl_brdnames[] = {
-	(char *) NULL,
-	(char *) NULL,
-	(char *) NULL,
-	(char *) NULL,
-	(char *) NULL,
-	(char *) NULL,
-	(char *) NULL,
-	(char *) NULL,
-	(char *) NULL,
-	(char *) NULL,
-	(char *) NULL,
-	(char *) NULL,
-	(char *) NULL,
-	(char *) NULL,
-	(char *) NULL,
-	(char *) NULL,
-	(char *) NULL,
-	(char *) NULL,
-	(char *) NULL,
-	(char *) NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
 	"EasyIO",
 	"EC8/32-AT",
 	"EC8/32-MC",
-	(char *) NULL,
-	(char *) NULL,
-	(char *) NULL,
+	NULL,
+	NULL,
+	NULL,
 	"EC8/32-PCI",
 	"EC8/64-PCI",
 	"EasyIO-PCI",
@@ -225,7 +191,7 @@ static char	*stl_brdnames[] = {
  *	load line. These allow for easy board definitions, and easy
  *	modification of the io, memory and irq resoucres.
  */
-static int	stl_nargs = 0;
+static unsigned int stl_nargs;
 static char	*board0[4];
 static char	*board1[4];
 static char	*board2[4];
@@ -243,12 +209,10 @@ static char	**stl_brdsp[] = {
  *	parse any module arguments.
  */
 
-typedef struct stlbrdtype {
+static struct {
 	char	*name;
 	int	type;
-} stlbrdtype_t;
-
-static stlbrdtype_t	stl_brdstr[] = {
+} stl_brdstr[] = {
 	{ "easyio", BRD_EASYIO },
 	{ "eio", BRD_EASYIO },
 	{ "20", BRD_EASYIO },
@@ -282,9 +246,6 @@ static stlbrdtype_t	stl_brdstr[] = {
 /*
  *	Define the module agruments.
  */
-MODULE_AUTHOR("Greg Ungerer");
-MODULE_DESCRIPTION("Stallion Multiport Serial Driver");
-MODULE_LICENSE("GPL");
 
 module_param_array(board0, charp, &stl_nargs, 0);
 MODULE_PARM_DESC(board0, "Board 0 config -> name[,ioaddr[,ioaddr2][,irq]]");
@@ -386,8 +347,6 @@ static spinlock_t stallion_lock;	/* Guard the tty driver */
 
 /*****************************************************************************/
 
-#ifdef CONFIG_PCI
-
 /*
  *	Define the Stallion PCI vendor and device IDs.
  */
@@ -407,22 +366,19 @@ static spinlock_t stallion_lock;	/* Guard the tty driver */
 /*
  *	Define structure to hold all Stallion PCI boards.
  */
-typedef struct stlpcibrd {
-	unsigned short		vendid;
-	unsigned short		devid;
-	int			brdtype;
-} stlpcibrd_t;
-
-static stlpcibrd_t	stl_pcibrds[] = {
-	{ PCI_VENDOR_ID_STALLION, PCI_DEVICE_ID_ECHPCI864, BRD_ECH64PCI },
-	{ PCI_VENDOR_ID_STALLION, PCI_DEVICE_ID_EIOPCI, BRD_EASYIOPCI },
-	{ PCI_VENDOR_ID_STALLION, PCI_DEVICE_ID_ECHPCI832, BRD_ECHPCI },
-	{ PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_87410, BRD_ECHPCI },
-};
-
-static int	stl_nrpcibrds = ARRAY_SIZE(stl_pcibrds);
 
-#endif
+static struct pci_device_id stl_pcibrds[] = {
+	{ PCI_DEVICE(PCI_VENDOR_ID_STALLION, PCI_DEVICE_ID_ECHPCI864),
+		.driver_data = BRD_ECH64PCI },
+	{ PCI_DEVICE(PCI_VENDOR_ID_STALLION, PCI_DEVICE_ID_EIOPCI),
+		.driver_data = BRD_EASYIOPCI },
+	{ PCI_DEVICE(PCI_VENDOR_ID_STALLION, PCI_DEVICE_ID_ECHPCI832),
+		.driver_data = BRD_ECHPCI },
+	{ PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_87410),
+		.driver_data = BRD_ECHPCI },
+	{ }
+};
+MODULE_DEVICE_TABLE(pci, stl_pcibrds);
 
 /*****************************************************************************/
 
@@ -442,134 +398,74 @@ static unsigned int	stl_baudrates[] = {
 	9600, 19200, 38400, 57600, 115200, 230400, 460800, 921600
 };
 
-/*
- *	Define some handy local macros...
- */
-#undef	MIN
-#define	MIN(a,b)	(((a) <= (b)) ? (a) : (b))
-
-#undef	TOLOWER
-#define	TOLOWER(x)	((((x) >= 'A') && ((x) <= 'Z')) ? ((x) + 0x20) : (x))
-
 /*****************************************************************************/
 
 /*
  *	Declare all those functions in this driver!
  */
 
-static void	stl_argbrds(void);
-static int	stl_parsebrd(stlconf_t *confp, char **argp);
-
-static unsigned long stl_atol(char *str);
-
-static int	stl_init(void);
-static int	stl_open(struct tty_struct *tty, struct file *filp);
-static void	stl_close(struct tty_struct *tty, struct file *filp);
-static int	stl_write(struct tty_struct *tty, const unsigned char *buf, int count);
-static void	stl_putchar(struct tty_struct *tty, unsigned char ch);
-static void	stl_flushchars(struct tty_struct *tty);
-static int	stl_writeroom(struct tty_struct *tty);
-static int	stl_charsinbuffer(struct tty_struct *tty);
-static int	stl_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg);
-static void	stl_settermios(struct tty_struct *tty, struct termios *old);
-static void	stl_throttle(struct tty_struct *tty);
-static void	stl_unthrottle(struct tty_struct *tty);
-static void	stl_stop(struct tty_struct *tty);
-static void	stl_start(struct tty_struct *tty);
-static void	stl_flushbuffer(struct tty_struct *tty);
-static void	stl_breakctl(struct tty_struct *tty, int state);
-static void	stl_waituntilsent(struct tty_struct *tty, int timeout);
-static void	stl_sendxchar(struct tty_struct *tty, char ch);
-static void	stl_hangup(struct tty_struct *tty);
 static int	stl_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, unsigned long arg);
-static int	stl_portinfo(stlport_t *portp, int portnr, char *pos);
-static int	stl_readproc(char *page, char **start, off_t off, int count, int *eof, void *data);
-
-static int	stl_brdinit(stlbrd_t *brdp);
-static int	stl_initports(stlbrd_t *brdp, stlpanel_t *panelp);
-static int	stl_getserial(stlport_t *portp, struct serial_struct __user *sp);
-static int	stl_setserial(stlport_t *portp, struct serial_struct __user *sp);
-static int	stl_getbrdstats(combrd_t __user *bp);
-static int	stl_getportstats(stlport_t *portp, comstats_t __user *cp);
-static int	stl_clrportstats(stlport_t *portp, comstats_t __user *cp);
-static int	stl_getportstruct(stlport_t __user *arg);
-static int	stl_getbrdstruct(stlbrd_t __user *arg);
-static int	stl_waitcarrier(stlport_t *portp, struct file *filp);
-static int	stl_eiointr(stlbrd_t *brdp);
-static int	stl_echatintr(stlbrd_t *brdp);
-static int	stl_echmcaintr(stlbrd_t *brdp);
-static int	stl_echpciintr(stlbrd_t *brdp);
-static int	stl_echpci64intr(stlbrd_t *brdp);
-static void	stl_offintr(struct work_struct *);
-static stlbrd_t *stl_allocbrd(void);
-static stlport_t *stl_getport(int brdnr, int panelnr, int portnr);
-
-static inline int	stl_initbrds(void);
-static inline int	stl_initeio(stlbrd_t *brdp);
-static inline int	stl_initech(stlbrd_t *brdp);
-static inline int	stl_getbrdnr(void);
-
-#ifdef	CONFIG_PCI
-static inline int	stl_findpcibrds(void);
-static inline int	stl_initpcibrd(int brdtype, struct pci_dev *devp);
-#endif
+static int	stl_brdinit(struct stlbrd *brdp);
+static int	stl_getportstats(struct stlport *portp, comstats_t __user *cp);
+static int	stl_clrportstats(struct stlport *portp, comstats_t __user *cp);
+static int	stl_waitcarrier(struct stlport *portp, struct file *filp);
 
 /*
  *	CD1400 uart specific handling functions.
  */
-static void	stl_cd1400setreg(stlport_t *portp, int regnr, int value);
-static int	stl_cd1400getreg(stlport_t *portp, int regnr);
-static int	stl_cd1400updatereg(stlport_t *portp, int regnr, int value);
-static int	stl_cd1400panelinit(stlbrd_t *brdp, stlpanel_t *panelp);
-static void	stl_cd1400portinit(stlbrd_t *brdp, stlpanel_t *panelp, stlport_t *portp);
-static void	stl_cd1400setport(stlport_t *portp, struct termios *tiosp);
-static int	stl_cd1400getsignals(stlport_t *portp);
-static void	stl_cd1400setsignals(stlport_t *portp, int dtr, int rts);
-static void	stl_cd1400ccrwait(stlport_t *portp);
-static void	stl_cd1400enablerxtx(stlport_t *portp, int rx, int tx);
-static void	stl_cd1400startrxtx(stlport_t *portp, int rx, int tx);
-static void	stl_cd1400disableintrs(stlport_t *portp);
-static void	stl_cd1400sendbreak(stlport_t *portp, int len);
-static void	stl_cd1400flowctrl(stlport_t *portp, int state);
-static void	stl_cd1400sendflow(stlport_t *portp, int state);
-static void	stl_cd1400flush(stlport_t *portp);
-static int	stl_cd1400datastate(stlport_t *portp);
-static void	stl_cd1400eiointr(stlpanel_t *panelp, unsigned int iobase);
-static void	stl_cd1400echintr(stlpanel_t *panelp, unsigned int iobase);
-static void	stl_cd1400txisr(stlpanel_t *panelp, int ioaddr);
-static void	stl_cd1400rxisr(stlpanel_t *panelp, int ioaddr);
-static void	stl_cd1400mdmisr(stlpanel_t *panelp, int ioaddr);
-
-static inline int	stl_cd1400breakisr(stlport_t *portp, int ioaddr);
+static void	stl_cd1400setreg(struct stlport *portp, int regnr, int value);
+static int	stl_cd1400getreg(struct stlport *portp, int regnr);
+static int	stl_cd1400updatereg(struct stlport *portp, int regnr, int value);
+static int	stl_cd1400panelinit(struct stlbrd *brdp, struct stlpanel *panelp);
+static void	stl_cd1400portinit(struct stlbrd *brdp, struct stlpanel *panelp, struct stlport *portp);
+static void	stl_cd1400setport(struct stlport *portp, struct ktermios *tiosp);
+static int	stl_cd1400getsignals(struct stlport *portp);
+static void	stl_cd1400setsignals(struct stlport *portp, int dtr, int rts);
+static void	stl_cd1400ccrwait(struct stlport *portp);
+static void	stl_cd1400enablerxtx(struct stlport *portp, int rx, int tx);
+static void	stl_cd1400startrxtx(struct stlport *portp, int rx, int tx);
+static void	stl_cd1400disableintrs(struct stlport *portp);
+static void	stl_cd1400sendbreak(struct stlport *portp, int len);
+static void	stl_cd1400flowctrl(struct stlport *portp, int state);
+static void	stl_cd1400sendflow(struct stlport *portp, int state);
+static void	stl_cd1400flush(struct stlport *portp);
+static int	stl_cd1400datastate(struct stlport *portp);
+static void	stl_cd1400eiointr(struct stlpanel *panelp, unsigned int iobase);
+static void	stl_cd1400echintr(struct stlpanel *panelp, unsigned int iobase);
+static void	stl_cd1400txisr(struct stlpanel *panelp, int ioaddr);
+static void	stl_cd1400rxisr(struct stlpanel *panelp, int ioaddr);
+static void	stl_cd1400mdmisr(struct stlpanel *panelp, int ioaddr);
+
+static inline int	stl_cd1400breakisr(struct stlport *portp, int ioaddr);
 
 /*
  *	SC26198 uart specific handling functions.
  */
-static void	stl_sc26198setreg(stlport_t *portp, int regnr, int value);
-static int	stl_sc26198getreg(stlport_t *portp, int regnr);
-static int	stl_sc26198updatereg(stlport_t *portp, int regnr, int value);
-static int	stl_sc26198getglobreg(stlport_t *portp, int regnr);
-static int	stl_sc26198panelinit(stlbrd_t *brdp, stlpanel_t *panelp);
-static void	stl_sc26198portinit(stlbrd_t *brdp, stlpanel_t *panelp, stlport_t *portp);
-static void	stl_sc26198setport(stlport_t *portp, struct termios *tiosp);
-static int	stl_sc26198getsignals(stlport_t *portp);
-static void	stl_sc26198setsignals(stlport_t *portp, int dtr, int rts);
-static void	stl_sc26198enablerxtx(stlport_t *portp, int rx, int tx);
-static void	stl_sc26198startrxtx(stlport_t *portp, int rx, int tx);
-static void	stl_sc26198disableintrs(stlport_t *portp);
-static void	stl_sc26198sendbreak(stlport_t *portp, int len);
-static void	stl_sc26198flowctrl(stlport_t *portp, int state);
-static void	stl_sc26198sendflow(stlport_t *portp, int state);
-static void	stl_sc26198flush(stlport_t *portp);
-static int	stl_sc26198datastate(stlport_t *portp);
-static void	stl_sc26198wait(stlport_t *portp);
-static void	stl_sc26198txunflow(stlport_t *portp, struct tty_struct *tty);
-static void	stl_sc26198intr(stlpanel_t *panelp, unsigned int iobase);
-static void	stl_sc26198txisr(stlport_t *port);
-static void	stl_sc26198rxisr(stlport_t *port, unsigned int iack);
-static void	stl_sc26198rxbadch(stlport_t *portp, unsigned char status, char ch);
-static void	stl_sc26198rxbadchars(stlport_t *portp);
-static void	stl_sc26198otherisr(stlport_t *port, unsigned int iack);
+static void	stl_sc26198setreg(struct stlport *portp, int regnr, int value);
+static int	stl_sc26198getreg(struct stlport *portp, int regnr);
+static int	stl_sc26198updatereg(struct stlport *portp, int regnr, int value);
+static int	stl_sc26198getglobreg(struct stlport *portp, int regnr);
+static int	stl_sc26198panelinit(struct stlbrd *brdp, struct stlpanel *panelp);
+static void	stl_sc26198portinit(struct stlbrd *brdp, struct stlpanel *panelp, struct stlport *portp);
+static void	stl_sc26198setport(struct stlport *portp, struct ktermios *tiosp);
+static int	stl_sc26198getsignals(struct stlport *portp);
+static void	stl_sc26198setsignals(struct stlport *portp, int dtr, int rts);
+static void	stl_sc26198enablerxtx(struct stlport *portp, int rx, int tx);
+static void	stl_sc26198startrxtx(struct stlport *portp, int rx, int tx);
+static void	stl_sc26198disableintrs(struct stlport *portp);
+static void	stl_sc26198sendbreak(struct stlport *portp, int len);
+static void	stl_sc26198flowctrl(struct stlport *portp, int state);
+static void	stl_sc26198sendflow(struct stlport *portp, int state);
+static void	stl_sc26198flush(struct stlport *portp);
+static int	stl_sc26198datastate(struct stlport *portp);
+static void	stl_sc26198wait(struct stlport *portp);
+static void	stl_sc26198txunflow(struct stlport *portp, struct tty_struct *tty);
+static void	stl_sc26198intr(struct stlpanel *panelp, unsigned int iobase);
+static void	stl_sc26198txisr(struct stlport *port);
+static void	stl_sc26198rxisr(struct stlport *port, unsigned int iack);
+static void	stl_sc26198rxbadch(struct stlport *portp, unsigned char status, char ch);
+static void	stl_sc26198rxbadchars(struct stlport *portp);
+static void	stl_sc26198otherisr(struct stlport *port, unsigned int iack);
 
 /*****************************************************************************/
 
@@ -577,20 +473,20 @@ static void	stl_sc26198otherisr(stlport_t *port, unsigned int iack);
  *	Generic UART support structure.
  */
 typedef struct uart {
-	int	(*panelinit)(stlbrd_t *brdp, stlpanel_t *panelp);
-	void	(*portinit)(stlbrd_t *brdp, stlpanel_t *panelp, stlport_t *portp);
-	void	(*setport)(stlport_t *portp, struct termios *tiosp);
-	int	(*getsignals)(stlport_t *portp);
-	void	(*setsignals)(stlport_t *portp, int dtr, int rts);
-	void	(*enablerxtx)(stlport_t *portp, int rx, int tx);
-	void	(*startrxtx)(stlport_t *portp, int rx, int tx);
-	void	(*disableintrs)(stlport_t *portp);
-	void	(*sendbreak)(stlport_t *portp, int len);
-	void	(*flowctrl)(stlport_t *portp, int state);
-	void	(*sendflow)(stlport_t *portp, int state);
-	void	(*flush)(stlport_t *portp);
-	int	(*datastate)(stlport_t *portp);
-	void	(*intr)(stlpanel_t *panelp, unsigned int iobase);
+	int	(*panelinit)(struct stlbrd *brdp, struct stlpanel *panelp);
+	void	(*portinit)(struct stlbrd *brdp, struct stlpanel *panelp, struct stlport *portp);
+	void	(*setport)(struct stlport *portp, struct ktermios *tiosp);
+	int	(*getsignals)(struct stlport *portp);
+	void	(*setsignals)(struct stlport *portp, int dtr, int rts);
+	void	(*enablerxtx)(struct stlport *portp, int rx, int tx);
+	void	(*startrxtx)(struct stlport *portp, int rx, int tx);
+	void	(*disableintrs)(struct stlport *portp);
+	void	(*sendbreak)(struct stlport *portp, int len);
+	void	(*flowctrl)(struct stlport *portp, int state);
+	void	(*sendflow)(struct stlport *portp, int state);
+	void	(*flush)(struct stlport *portp);
+	int	(*datastate)(struct stlport *portp);
+	void	(*intr)(struct stlpanel *panelp, unsigned int iobase);
 } uart_t;
 
 /*
@@ -712,184 +608,35 @@ static const struct file_operations	stl_fsiomem = {
 	.ioctl		= stl_memioctl,
 };
 
-/*****************************************************************************/
-
 static struct class *stallion_class;
 
 /*
- *	Loadable module initialization stuff.
- */
-
-static int __init stallion_module_init(void)
-{
-	stl_init();
-	return 0;
-}
-
-/*****************************************************************************/
-
-static void __exit stallion_module_exit(void)
-{
-	stlbrd_t	*brdp;
-	stlpanel_t	*panelp;
-	stlport_t	*portp;
-	int		i, j, k;
-
-#ifdef DEBUG
-	printk("cleanup_module()\n");
-#endif
-
-	printk(KERN_INFO "Unloading %s: version %s\n", stl_drvtitle,
-		stl_drvversion);
-
-/*
- *	Free up all allocated resources used by the ports. This includes
- *	memory and interrupts. As part of this process we will also do
- *	a hangup on every open port - to try to flush out any processes
- *	hanging onto ports.
- */
-	i = tty_unregister_driver(stl_serial);
-	put_tty_driver(stl_serial);
-	if (i) {
-		printk("STALLION: failed to un-register tty driver, "
-			"errno=%d\n", -i);
-		return;
-	}
-	for (i = 0; i < 4; i++)
-		class_device_destroy(stallion_class, MKDEV(STL_SIOMEMMAJOR, i));
-	if ((i = unregister_chrdev(STL_SIOMEMMAJOR, "staliomem")))
-		printk("STALLION: failed to un-register serial memory device, "
-			"errno=%d\n", -i);
-	class_destroy(stallion_class);
-
-	for (i = 0; (i < stl_nrbrds); i++) {
-		if ((brdp = stl_brds[i]) == (stlbrd_t *) NULL)
-			continue;
-
-		free_irq(brdp->irq, brdp);
-
-		for (j = 0; (j < STL_MAXPANELS); j++) {
-			panelp = brdp->panels[j];
-			if (panelp == (stlpanel_t *) NULL)
-				continue;
-			for (k = 0; (k < STL_PORTSPERPANEL); k++) {
-				portp = panelp->ports[k];
-				if (portp == (stlport_t *) NULL)
-					continue;
-				if (portp->tty != (struct tty_struct *) NULL)
-					stl_hangup(portp->tty);
-				kfree(portp->tx.buf);
-				kfree(portp);
-			}
-			kfree(panelp);
-		}
-
-		release_region(brdp->ioaddr1, brdp->iosize1);
-		if (brdp->iosize2 > 0)
-			release_region(brdp->ioaddr2, brdp->iosize2);
-
-		kfree(brdp);
-		stl_brds[i] = (stlbrd_t *) NULL;
-	}
-}
-
-module_init(stallion_module_init);
-module_exit(stallion_module_exit);
-
-/*****************************************************************************/
-
-/*
  *	Check for any arguments passed in on the module load command line.
  */
 
-static void stl_argbrds(void)
-{
-	stlconf_t	conf;
-	stlbrd_t	*brdp;
-	int		i;
-
-#ifdef DEBUG
-	printk("stl_argbrds()\n");
-#endif
-
-	for (i = stl_nrbrds; (i < stl_nargs); i++) {
-		memset(&conf, 0, sizeof(conf));
-		if (stl_parsebrd(&conf, stl_brdsp[i]) == 0)
-			continue;
-		if ((brdp = stl_allocbrd()) == (stlbrd_t *) NULL)
-			continue;
-		stl_nrbrds = i + 1;
-		brdp->brdnr = i;
-		brdp->brdtype = conf.brdtype;
-		brdp->ioaddr1 = conf.ioaddr1;
-		brdp->ioaddr2 = conf.ioaddr2;
-		brdp->irq = conf.irq;
-		brdp->irqtype = conf.irqtype;
-		stl_brdinit(brdp);
-	}
-}
-
-/*****************************************************************************/
-
-/*
- *	Convert an ascii string number into an unsigned long.
- */
-
-static unsigned long stl_atol(char *str)
-{
-	unsigned long	val;
-	int		base, c;
-	char		*sp;
-
-	val = 0;
-	sp = str;
-	if ((*sp == '0') && (*(sp+1) == 'x')) {
-		base = 16;
-		sp += 2;
-	} else if (*sp == '0') {
-		base = 8;
-		sp++;
-	} else {
-		base = 10;
-	}
-
-	for (; (*sp != 0); sp++) {
-		c = (*sp > '9') ? (TOLOWER(*sp) - 'a' + 10) : (*sp - '0');
-		if ((c < 0) || (c >= base)) {
-			printk("STALLION: invalid argument %s\n", str);
-			val = 0;
-			break;
-		}
-		val = (val * base) + c;
-	}
-	return val;
-}
-
 /*****************************************************************************/
 
 /*
  *	Parse the supplied argument string, into the board conf struct.
  */
 
-static int stl_parsebrd(stlconf_t *confp, char **argp)
+static int __init stl_parsebrd(struct stlconf *confp, char **argp)
 {
 	char	*sp;
-	int	i;
+	unsigned int i;
 
-#ifdef DEBUG
-	printk("stl_parsebrd(confp=%x,argp=%x)\n", (int) confp, (int) argp);
-#endif
+	pr_debug("stl_parsebrd(confp=%p,argp=%p)\n", confp, argp);
 
-	if ((argp[0] == (char *) NULL) || (*argp[0] == 0))
+	if ((argp[0] == NULL) || (*argp[0] == 0))
 		return 0;
 
-	for (sp = argp[0], i = 0; ((*sp != 0) && (i < 25)); sp++, i++)
-		*sp = TOLOWER(*sp);
+	for (sp = argp[0], i = 0; (*sp != 0) && (i < 25); sp++, i++)
+		*sp = tolower(*sp);
 
-	for (i = 0; i < ARRAY_SIZE(stl_brdstr); i++) {
+	for (i = 0; i < ARRAY_SIZE(stl_brdstr); i++)
 		if (strcmp(stl_brdstr[i].name, argp[0]) == 0)
 			break;
-	}
+
 	if (i == ARRAY_SIZE(stl_brdstr)) {
 		printk("STALLION: unknown board name, %s?\n", argp[0]);
 		return 0;
@@ -898,16 +645,16 @@ static int stl_parsebrd(stlconf_t *confp, char **argp)
 	confp->brdtype = stl_brdstr[i].type;
 
 	i = 1;
-	if ((argp[i] != (char *) NULL) && (*argp[i] != 0))
-		confp->ioaddr1 = stl_atol(argp[i]);
+	if ((argp[i] != NULL) && (*argp[i] != 0))
+		confp->ioaddr1 = simple_strtoul(argp[i], NULL, 0);
 	i++;
 	if (confp->brdtype == BRD_ECH) {
-		if ((argp[i] != (char *) NULL) && (*argp[i] != 0))
-			confp->ioaddr2 = stl_atol(argp[i]);
+		if ((argp[i] != NULL) && (*argp[i] != 0))
+			confp->ioaddr2 = simple_strtoul(argp[i], NULL, 0);
 		i++;
 	}
-	if ((argp[i] != (char *) NULL) && (*argp[i] != 0))
-		confp->irq = stl_atol(argp[i]);
+	if ((argp[i] != NULL) && (*argp[i] != 0))
+		confp->irq = simple_strtoul(argp[i], NULL, 0);
 	return 1;
 }
 
@@ -917,14 +664,14 @@ static int stl_parsebrd(stlconf_t *confp, char **argp)
  *	Allocate a new board structure. Fill out the basic info in it.
  */
 
-static stlbrd_t *stl_allocbrd(void)
+static struct stlbrd *stl_allocbrd(void)
 {
-	stlbrd_t	*brdp;
+	struct stlbrd	*brdp;
 
-	brdp = kzalloc(sizeof(stlbrd_t), GFP_KERNEL);
+	brdp = kzalloc(sizeof(struct stlbrd), GFP_KERNEL);
 	if (!brdp) {
 		printk("STALLION: failed to allocate memory (size=%Zd)\n",
-			sizeof(stlbrd_t));
+			sizeof(struct stlbrd));
 		return NULL;
 	}
 
@@ -936,26 +683,23 @@ static stlbrd_t *stl_allocbrd(void)
 
 static int stl_open(struct tty_struct *tty, struct file *filp)
 {
-	stlport_t	*portp;
-	stlbrd_t	*brdp;
-	unsigned int	minordev;
-	int		brdnr, panelnr, portnr, rc;
-
-#ifdef DEBUG
-	printk("stl_open(tty=%x,filp=%x): device=%s\n", (int) tty,
-		(int) filp, tty->name);
-#endif
+	struct stlport	*portp;
+	struct stlbrd	*brdp;
+	unsigned int	minordev, brdnr, panelnr;
+	int		portnr, rc;
+
+	pr_debug("stl_open(tty=%p,filp=%p): device=%s\n", tty, filp, tty->name);
 
 	minordev = tty->index;
 	brdnr = MINOR2BRD(minordev);
 	if (brdnr >= stl_nrbrds)
 		return -ENODEV;
 	brdp = stl_brds[brdnr];
-	if (brdp == (stlbrd_t *) NULL)
+	if (brdp == NULL)
 		return -ENODEV;
 	minordev = MINOR2PORT(minordev);
-	for (portnr = -1, panelnr = 0; (panelnr < STL_MAXPANELS); panelnr++) {
-		if (brdp->panels[panelnr] == (stlpanel_t *) NULL)
+	for (portnr = -1, panelnr = 0; panelnr < STL_MAXPANELS; panelnr++) {
+		if (brdp->panels[panelnr] == NULL)
 			break;
 		if (minordev < brdp->panels[panelnr]->nrports) {
 			portnr = minordev;
@@ -967,7 +711,7 @@ static int stl_open(struct tty_struct *tty, struct file *filp)
 		return -ENODEV;
 
 	portp = brdp->panels[panelnr]->ports[portnr];
-	if (portp == (stlport_t *) NULL)
+	if (portp == NULL)
 		return -ENODEV;
 
 /*
@@ -1013,10 +757,10 @@ static int stl_open(struct tty_struct *tty, struct file *filp)
  *	previous opens still in effect. If we are a normal serial device
  *	then also we might have to wait for carrier.
  */
-	if (!(filp->f_flags & O_NONBLOCK)) {
+	if (!(filp->f_flags & O_NONBLOCK))
 		if ((rc = stl_waitcarrier(portp, filp)) != 0)
 			return rc;
-	}
+
 	portp->flags |= ASYNC_NORMAL_ACTIVE;
 
 	return 0;
@@ -1029,14 +773,12 @@ static int stl_open(struct tty_struct *tty, struct file *filp)
  *	maybe because if we are clocal then we don't need to wait...
  */
 
-static int stl_waitcarrier(stlport_t *portp, struct file *filp)
+static int stl_waitcarrier(struct stlport *portp, struct file *filp)
 {
 	unsigned long	flags;
 	int		rc, doclocal;
 
-#ifdef DEBUG
-	printk("stl_waitcarrier(portp=%x,filp=%x)\n", (int) portp, (int) filp);
-#endif
+	pr_debug("stl_waitcarrier(portp=%p,filp=%p)\n", portp, filp);
 
 	rc = 0;
 	doclocal = 0;
@@ -1062,9 +804,8 @@ static int stl_waitcarrier(stlport_t *portp, struct file *filp)
 			break;
 		}
 		if (((portp->flags & ASYNC_CLOSING) == 0) &&
-		    (doclocal || (portp->sigs & TIOCM_CD))) {
+		    (doclocal || (portp->sigs & TIOCM_CD)))
 			break;
-		}
 		if (signal_pending(current)) {
 			rc = -ERESTARTSYS;
 			break;
@@ -1083,17 +824,61 @@ static int stl_waitcarrier(stlport_t *portp, struct file *filp)
 
 /*****************************************************************************/
 
+static void stl_flushbuffer(struct tty_struct *tty)
+{
+	struct stlport	*portp;
+
+	pr_debug("stl_flushbuffer(tty=%p)\n", tty);
+
+	if (tty == NULL)
+		return;
+	portp = tty->driver_data;
+	if (portp == NULL)
+		return;
+
+	stl_flush(portp);
+	tty_wakeup(tty);
+}
+
+/*****************************************************************************/
+
+static void stl_waituntilsent(struct tty_struct *tty, int timeout)
+{
+	struct stlport	*portp;
+	unsigned long	tend;
+
+	pr_debug("stl_waituntilsent(tty=%p,timeout=%d)\n", tty, timeout);
+
+	if (tty == NULL)
+		return;
+	portp = tty->driver_data;
+	if (portp == NULL)
+		return;
+
+	if (timeout == 0)
+		timeout = HZ;
+	tend = jiffies + timeout;
+
+	while (stl_datastate(portp)) {
+		if (signal_pending(current))
+			break;
+		msleep_interruptible(20);
+		if (time_after_eq(jiffies, tend))
+			break;
+	}
+}
+
+/*****************************************************************************/
+
 static void stl_close(struct tty_struct *tty, struct file *filp)
 {
-	stlport_t	*portp;
+	struct stlport	*portp;
 	unsigned long	flags;
 
-#ifdef DEBUG
-	printk("stl_close(tty=%x,filp=%x)\n", (int) tty, (int) filp);
-#endif
+	pr_debug("stl_close(tty=%p,filp=%p)\n", tty, filp);
 
 	portp = tty->driver_data;
-	if (portp == (stlport_t *) NULL)
+	if (portp == NULL)
 		return;
 
 	spin_lock_irqsave(&stallion_lock, flags);
@@ -1136,17 +921,17 @@ static void stl_close(struct tty_struct *tty, struct file *filp)
 	stl_enablerxtx(portp, 0, 0);
 	stl_flushbuffer(tty);
 	portp->istate = 0;
-	if (portp->tx.buf != (char *) NULL) {
+	if (portp->tx.buf != NULL) {
 		kfree(portp->tx.buf);
-		portp->tx.buf = (char *) NULL;
-		portp->tx.head = (char *) NULL;
-		portp->tx.tail = (char *) NULL;
+		portp->tx.buf = NULL;
+		portp->tx.head = NULL;
+		portp->tx.tail = NULL;
 	}
 	set_bit(TTY_IO_ERROR, &tty->flags);
 	tty_ldisc_flush(tty);
 
 	tty->closing = 0;
-	portp->tty = (struct tty_struct *) NULL;
+	portp->tty = NULL;
 
 	if (portp->openwaitcnt) {
 		if (portp->close_delay)
@@ -1167,20 +952,17 @@ static void stl_close(struct tty_struct *tty, struct file *filp)
 
 static int stl_write(struct tty_struct *tty, const unsigned char *buf, int count)
 {
-	stlport_t	*portp;
+	struct stlport	*portp;
 	unsigned int	len, stlen;
 	unsigned char	*chbuf;
 	char		*head, *tail;
 
-#ifdef DEBUG
-	printk("stl_write(tty=%x,buf=%x,count=%d)\n",
-		(int) tty, (int) buf, count);
-#endif
+	pr_debug("stl_write(tty=%p,buf=%p,count=%d)\n", tty, buf, count);
 
 	portp = tty->driver_data;
-	if (portp == (stlport_t *) NULL)
+	if (portp == NULL)
 		return 0;
-	if (portp->tx.buf == (char *) NULL)
+	if (portp->tx.buf == NULL)
 		return 0;
 
 /*
@@ -1201,10 +983,10 @@ static int stl_write(struct tty_struct *tty, const unsigned char *buf, int count
 		stlen = len;
 	}
 
-	len = MIN(len, count);
+	len = min(len, (unsigned int)count);
 	count = 0;
 	while (len > 0) {
-		stlen = MIN(len, stlen);
+		stlen = min(len, stlen);
 		memcpy(head, chbuf, stlen);
 		len -= stlen;
 		chbuf += stlen;
@@ -1227,20 +1009,18 @@ static int stl_write(struct tty_struct *tty, const unsigned char *buf, int count
 
 static void stl_putchar(struct tty_struct *tty, unsigned char ch)
 {
-	stlport_t	*portp;
+	struct stlport	*portp;
 	unsigned int	len;
 	char		*head, *tail;
 
-#ifdef DEBUG
-	printk("stl_putchar(tty=%x,ch=%x)\n", (int) tty, (int) ch);
-#endif
+	pr_debug("stl_putchar(tty=%p,ch=%x)\n", tty, ch);
 
-	if (tty == (struct tty_struct *) NULL)
+	if (tty == NULL)
 		return;
 	portp = tty->driver_data;
-	if (portp == (stlport_t *) NULL)
+	if (portp == NULL)
 		return;
-	if (portp->tx.buf == (char *) NULL)
+	if (portp->tx.buf == NULL)
 		return;
 
 	head = portp->tx.head;
@@ -1267,18 +1047,16 @@ static void stl_putchar(struct tty_struct *tty, unsigned char ch)
 
 static void stl_flushchars(struct tty_struct *tty)
 {
-	stlport_t	*portp;
+	struct stlport	*portp;
 
-#ifdef DEBUG
-	printk("stl_flushchars(tty=%x)\n", (int) tty);
-#endif
+	pr_debug("stl_flushchars(tty=%p)\n", tty);
 
-	if (tty == (struct tty_struct *) NULL)
+	if (tty == NULL)
 		return;
 	portp = tty->driver_data;
-	if (portp == (stlport_t *) NULL)
+	if (portp == NULL)
 		return;
-	if (portp->tx.buf == (char *) NULL)
+	if (portp->tx.buf == NULL)
 		return;
 
 	stl_startrxtx(portp, -1, 1);
@@ -1288,24 +1066,22 @@ static void stl_flushchars(struct tty_struct *tty)
 
 static int stl_writeroom(struct tty_struct *tty)
 {
-	stlport_t	*portp;
+	struct stlport	*portp;
 	char		*head, *tail;
 
-#ifdef DEBUG
-	printk("stl_writeroom(tty=%x)\n", (int) tty);
-#endif
+	pr_debug("stl_writeroom(tty=%p)\n", tty);
 
-	if (tty == (struct tty_struct *) NULL)
+	if (tty == NULL)
 		return 0;
 	portp = tty->driver_data;
-	if (portp == (stlport_t *) NULL)
+	if (portp == NULL)
 		return 0;
-	if (portp->tx.buf == (char *) NULL)
+	if (portp->tx.buf == NULL)
 		return 0;
 
 	head = portp->tx.head;
 	tail = portp->tx.tail;
-	return ((head >= tail) ? (STL_TXBUFSIZE - (head - tail) - 1) : (tail - head - 1));
+	return (head >= tail) ? (STL_TXBUFSIZE - (head - tail) - 1) : (tail - head - 1);
 }
 
 /*****************************************************************************/
@@ -1321,20 +1097,18 @@ static int stl_writeroom(struct tty_struct *tty)
 
 static int stl_charsinbuffer(struct tty_struct *tty)
 {
-	stlport_t	*portp;
+	struct stlport	*portp;
 	unsigned int	size;
 	char		*head, *tail;
 
-#ifdef DEBUG
-	printk("stl_charsinbuffer(tty=%x)\n", (int) tty);
-#endif
+	pr_debug("stl_charsinbuffer(tty=%p)\n", tty);
 
-	if (tty == (struct tty_struct *) NULL)
+	if (tty == NULL)
 		return 0;
 	portp = tty->driver_data;
-	if (portp == (stlport_t *) NULL)
+	if (portp == NULL)
 		return 0;
-	if (portp->tx.buf == (char *) NULL)
+	if (portp->tx.buf == NULL)
 		return 0;
 
 	head = portp->tx.head;
@@ -1351,14 +1125,12 @@ static int stl_charsinbuffer(struct tty_struct *tty)
  *	Generate the serial struct info.
  */
 
-static int stl_getserial(stlport_t *portp, struct serial_struct __user *sp)
+static int stl_getserial(struct stlport *portp, struct serial_struct __user *sp)
 {
 	struct serial_struct	sio;
-	stlbrd_t		*brdp;
+	struct stlbrd		*brdp;
 
-#ifdef DEBUG
-	printk("stl_getserial(portp=%x,sp=%x)\n", (int) portp, (int) sp);
-#endif
+	pr_debug("stl_getserial(portp=%p,sp=%p)\n", portp, sp);
 
 	memset(&sio, 0, sizeof(struct serial_struct));
 	sio.line = portp->portnr;
@@ -1378,7 +1150,7 @@ static int stl_getserial(stlport_t *portp, struct serial_struct __user *sp)
 	}
 
 	brdp = stl_brds[portp->brdnr];
-	if (brdp != (stlbrd_t *) NULL)
+	if (brdp != NULL)
 		sio.irq = brdp->irq;
 
 	return copy_to_user(sp, &sio, sizeof(struct serial_struct)) ? -EFAULT : 0;
@@ -1392,13 +1164,11 @@ static int stl_getserial(stlport_t *portp, struct serial_struct __user *sp)
  *	just quietly ignore any requests to change irq, etc.
  */
 
-static int stl_setserial(stlport_t *portp, struct serial_struct __user *sp)
+static int stl_setserial(struct stlport *portp, struct serial_struct __user *sp)
 {
 	struct serial_struct	sio;
 
-#ifdef DEBUG
-	printk("stl_setserial(portp=%x,sp=%x)\n", (int) portp, (int) sp);
-#endif
+	pr_debug("stl_setserial(portp=%p,sp=%p)\n", portp, sp);
 
 	if (copy_from_user(&sio, sp, sizeof(struct serial_struct)))
 		return -EFAULT;
@@ -1424,12 +1194,12 @@ static int stl_setserial(stlport_t *portp, struct serial_struct __user *sp)
 
 static int stl_tiocmget(struct tty_struct *tty, struct file *file)
 {
-	stlport_t	*portp;
+	struct stlport	*portp;
 
-	if (tty == (struct tty_struct *) NULL)
+	if (tty == NULL)
 		return -ENODEV;
 	portp = tty->driver_data;
-	if (portp == (stlport_t *) NULL)
+	if (portp == NULL)
 		return -ENODEV;
 	if (tty->flags & (1 << TTY_IO_ERROR))
 		return -EIO;
@@ -1440,13 +1210,13 @@ static int stl_tiocmget(struct tty_struct *tty, struct file *file)
 static int stl_tiocmset(struct tty_struct *tty, struct file *file,
 			unsigned int set, unsigned int clear)
 {
-	stlport_t	*portp;
+	struct stlport	*portp;
 	int rts = -1, dtr = -1;
 
-	if (tty == (struct tty_struct *) NULL)
+	if (tty == NULL)
 		return -ENODEV;
 	portp = tty->driver_data;
-	if (portp == (stlport_t *) NULL)
+	if (portp == NULL)
 		return -ENODEV;
 	if (tty->flags & (1 << TTY_IO_ERROR))
 		return -EIO;
@@ -1466,27 +1236,24 @@ static int stl_tiocmset(struct tty_struct *tty, struct file *file,
 
 static int stl_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg)
 {
-	stlport_t	*portp;
+	struct stlport	*portp;
 	unsigned int	ival;
 	int		rc;
 	void __user *argp = (void __user *)arg;
 
-#ifdef DEBUG
-	printk("stl_ioctl(tty=%x,file=%x,cmd=%x,arg=%x)\n",
-		(int) tty, (int) file, cmd, (int) arg);
-#endif
+	pr_debug("stl_ioctl(tty=%p,file=%p,cmd=%x,arg=%lx)\n", tty, file, cmd,
+			arg);
 
-	if (tty == (struct tty_struct *) NULL)
+	if (tty == NULL)
 		return -ENODEV;
 	portp = tty->driver_data;
-	if (portp == (stlport_t *) NULL)
+	if (portp == NULL)
 		return -ENODEV;
 
 	if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) &&
- 	    (cmd != COM_GETPORTSTATS) && (cmd != COM_CLRPORTSTATS)) {
+ 	    (cmd != COM_GETPORTSTATS) && (cmd != COM_CLRPORTSTATS))
 		if (tty->flags & (1 << TTY_IO_ERROR))
 			return -EIO;
-	}
 
 	rc = 0;
 
@@ -1531,19 +1298,37 @@ static int stl_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd
 
 /*****************************************************************************/
 
-static void stl_settermios(struct tty_struct *tty, struct termios *old)
+/*
+ *	Start the transmitter again. Just turn TX interrupts back on.
+ */
+
+static void stl_start(struct tty_struct *tty)
 {
-	stlport_t	*portp;
-	struct termios	*tiosp;
+	struct stlport	*portp;
 
-#ifdef DEBUG
-	printk("stl_settermios(tty=%x,old=%x)\n", (int) tty, (int) old);
-#endif
+	pr_debug("stl_start(tty=%p)\n", tty);
 
-	if (tty == (struct tty_struct *) NULL)
+	if (tty == NULL)
 		return;
 	portp = tty->driver_data;
-	if (portp == (stlport_t *) NULL)
+	if (portp == NULL)
+		return;
+	stl_startrxtx(portp, -1, 1);
+}
+
+/*****************************************************************************/
+
+static void stl_settermios(struct tty_struct *tty, struct ktermios *old)
+{
+	struct stlport	*portp;
+	struct ktermios	*tiosp;
+
+	pr_debug("stl_settermios(tty=%p,old=%p)\n", tty, old);
+
+	if (tty == NULL)
+		return;
+	portp = tty->driver_data;
+	if (portp == NULL)
 		return;
 
 	tiosp = tty->termios;
@@ -1571,16 +1356,14 @@ static void stl_settermios(struct tty_struct *tty, struct termios *old)
 
 static void stl_throttle(struct tty_struct *tty)
 {
-	stlport_t	*portp;
+	struct stlport	*portp;
 
-#ifdef DEBUG
-	printk("stl_throttle(tty=%x)\n", (int) tty);
-#endif
+	pr_debug("stl_throttle(tty=%p)\n", tty);
 
-	if (tty == (struct tty_struct *) NULL)
+	if (tty == NULL)
 		return;
 	portp = tty->driver_data;
-	if (portp == (stlport_t *) NULL)
+	if (portp == NULL)
 		return;
 	stl_flowctrl(portp, 0);
 }
@@ -1593,16 +1376,14 @@ static void stl_throttle(struct tty_struct *tty)
 
 static void stl_unthrottle(struct tty_struct *tty)
 {
-	stlport_t	*portp;
+	struct stlport	*portp;
 
-#ifdef DEBUG
-	printk("stl_unthrottle(tty=%x)\n", (int) tty);
-#endif
+	pr_debug("stl_unthrottle(tty=%p)\n", tty);
 
-	if (tty == (struct tty_struct *) NULL)
+	if (tty == NULL)
 		return;
 	portp = tty->driver_data;
-	if (portp == (stlport_t *) NULL)
+	if (portp == NULL)
 		return;
 	stl_flowctrl(portp, 1);
 }
@@ -1616,16 +1397,14 @@ static void stl_unthrottle(struct tty_struct *tty)
 
 static void stl_stop(struct tty_struct *tty)
 {
-	stlport_t	*portp;
+	struct stlport	*portp;
 
-#ifdef DEBUG
-	printk("stl_stop(tty=%x)\n", (int) tty);
-#endif
+	pr_debug("stl_stop(tty=%p)\n", tty);
 
-	if (tty == (struct tty_struct *) NULL)
+	if (tty == NULL)
 		return;
 	portp = tty->driver_data;
-	if (portp == (stlport_t *) NULL)
+	if (portp == NULL)
 		return;
 	stl_startrxtx(portp, -1, 0);
 }
@@ -1633,28 +1412,6 @@ static void stl_stop(struct tty_struct *tty)
 /*****************************************************************************/
 
 /*
- *	Start the transmitter again. Just turn TX interrupts back on.
- */
-
-static void stl_start(struct tty_struct *tty)
-{
-	stlport_t	*portp;
-
-#ifdef DEBUG
-	printk("stl_start(tty=%x)\n", (int) tty);
-#endif
-
-	if (tty == (struct tty_struct *) NULL)
-		return;
-	portp = tty->driver_data;
-	if (portp == (stlport_t *) NULL)
-		return;
-	stl_startrxtx(portp, -1, 1);
-}
-
-/*****************************************************************************/
-
-/*
  *	Hangup this port. This is pretty much like closing the port, only
  *	a little more brutal. No waiting for data to drain. Shutdown the
  *	port and maybe drop signals.
@@ -1662,16 +1419,14 @@ static void stl_start(struct tty_struct *tty)
 
 static void stl_hangup(struct tty_struct *tty)
 {
-	stlport_t	*portp;
+	struct stlport	*portp;
 
-#ifdef DEBUG
-	printk("stl_hangup(tty=%x)\n", (int) tty);
-#endif
+	pr_debug("stl_hangup(tty=%p)\n", tty);
 
-	if (tty == (struct tty_struct *) NULL)
+	if (tty == NULL)
 		return;
 	portp = tty->driver_data;
-	if (portp == (stlport_t *) NULL)
+	if (portp == NULL)
 		return;
 
 	portp->flags &= ~ASYNC_INITIALIZED;
@@ -1682,13 +1437,13 @@ static void stl_hangup(struct tty_struct *tty)
 	stl_flushbuffer(tty);
 	portp->istate = 0;
 	set_bit(TTY_IO_ERROR, &tty->flags);
-	if (portp->tx.buf != (char *) NULL) {
+	if (portp->tx.buf != NULL) {
 		kfree(portp->tx.buf);
-		portp->tx.buf = (char *) NULL;
-		portp->tx.head = (char *) NULL;
-		portp->tx.tail = (char *) NULL;
+		portp->tx.buf = NULL;
+		portp->tx.head = NULL;
+		portp->tx.tail = NULL;
 	}
-	portp->tty = (struct tty_struct *) NULL;
+	portp->tty = NULL;
 	portp->flags &= ~ASYNC_NORMAL_ACTIVE;
 	portp->refcount = 0;
 	wake_up_interruptible(&portp->open_wait);
@@ -1696,38 +1451,16 @@ static void stl_hangup(struct tty_struct *tty)
 
 /*****************************************************************************/
 
-static void stl_flushbuffer(struct tty_struct *tty)
-{
-	stlport_t	*portp;
-
-#ifdef DEBUG
-	printk("stl_flushbuffer(tty=%x)\n", (int) tty);
-#endif
-
-	if (tty == (struct tty_struct *) NULL)
-		return;
-	portp = tty->driver_data;
-	if (portp == (stlport_t *) NULL)
-		return;
-
-	stl_flush(portp);
-	tty_wakeup(tty);
-}
-
-/*****************************************************************************/
-
 static void stl_breakctl(struct tty_struct *tty, int state)
 {
-	stlport_t	*portp;
+	struct stlport	*portp;
 
-#ifdef DEBUG
-	printk("stl_breakctl(tty=%x,state=%d)\n", (int) tty, state);
-#endif
+	pr_debug("stl_breakctl(tty=%p,state=%d)\n", tty, state);
 
-	if (tty == (struct tty_struct *) NULL)
+	if (tty == NULL)
 		return;
 	portp = tty->driver_data;
-	if (portp == (stlport_t *) NULL)
+	if (portp == NULL)
 		return;
 
 	stl_sendbreak(portp, ((state == -1) ? 1 : 2));
@@ -1735,48 +1468,16 @@ static void stl_breakctl(struct tty_struct *tty, int state)
 
 /*****************************************************************************/
 
-static void stl_waituntilsent(struct tty_struct *tty, int timeout)
-{
-	stlport_t	*portp;
-	unsigned long	tend;
-
-#ifdef DEBUG
-	printk("stl_waituntilsent(tty=%x,timeout=%d)\n", (int) tty, timeout);
-#endif
-
-	if (tty == (struct tty_struct *) NULL)
-		return;
-	portp = tty->driver_data;
-	if (portp == (stlport_t *) NULL)
-		return;
-
-	if (timeout == 0)
-		timeout = HZ;
-	tend = jiffies + timeout;
-
-	while (stl_datastate(portp)) {
-		if (signal_pending(current))
-			break;
-		msleep_interruptible(20);
-		if (time_after_eq(jiffies, tend))
-			break;
-	}
-}
-
-/*****************************************************************************/
-
 static void stl_sendxchar(struct tty_struct *tty, char ch)
 {
-	stlport_t	*portp;
+	struct stlport	*portp;
 
-#ifdef DEBUG
-	printk("stl_sendxchar(tty=%x,ch=%x)\n", (int) tty, ch);
-#endif
+	pr_debug("stl_sendxchar(tty=%p,ch=%x)\n", tty, ch);
 
-	if (tty == (struct tty_struct *) NULL)
+	if (tty == NULL)
 		return;
 	portp = tty->driver_data;
-	if (portp == (stlport_t *) NULL)
+	if (portp == NULL)
 		return;
 
 	if (ch == STOP_CHAR(tty))
@@ -1797,7 +1498,7 @@ static void stl_sendxchar(struct tty_struct *tty, char ch)
  *	short then padded with spaces).
  */
 
-static int stl_portinfo(stlport_t *portp, int portnr, char *pos)
+static int stl_portinfo(struct stlport *portp, int portnr, char *pos)
 {
 	char	*sp;
 	int	sigs, cnt;
@@ -1826,7 +1527,7 @@ static int stl_portinfo(stlport_t *portp, int portnr, char *pos)
 	*sp = ' ';
 	sp += cnt;
 
-	for (cnt = (sp - pos); (cnt < (MAXLINE - 1)); cnt++)
+	for (cnt = sp - pos; cnt < (MAXLINE - 1); cnt++)
 		*sp++ = ' ';
 	if (cnt >= MAXLINE)
 		pos[(MAXLINE - 2)] = '+';
@@ -1843,18 +1544,15 @@ static int stl_portinfo(stlport_t *portp, int portnr, char *pos)
 
 static int stl_readproc(char *page, char **start, off_t off, int count, int *eof, void *data)
 {
-	stlbrd_t	*brdp;
-	stlpanel_t	*panelp;
-	stlport_t	*portp;
-	int		brdnr, panelnr, portnr, totalport;
-	int		curoff, maxoff;
+	struct stlbrd	*brdp;
+	struct stlpanel	*panelp;
+	struct stlport	*portp;
+	unsigned int	brdnr, panelnr, portnr;
+	int		totalport, curoff, maxoff;
 	char		*pos;
 
-#ifdef DEBUG
-	printk("stl_readproc(page=%x,start=%x,off=%x,count=%d,eof=%x,"
-		"data=%x\n", (int) page, (int) start, (int) off, count,
-		(int) eof, (int) data);
-#endif
+	pr_debug("stl_readproc(page=%p,start=%p,off=%lx,count=%d,eof=%p,"
+		"data=%p\n", page, start, off, count, eof, data);
 
 	pos = page;
 	totalport = 0;
@@ -1873,9 +1571,9 @@ static int stl_readproc(char *page, char **start, off_t off, int count, int *eof
  *	We scan through for each board, panel and port. The offset is
  *	calculated on the fly, and irrelevant ports are skipped.
  */
-	for (brdnr = 0; (brdnr < stl_nrbrds); brdnr++) {
+	for (brdnr = 0; brdnr < stl_nrbrds; brdnr++) {
 		brdp = stl_brds[brdnr];
-		if (brdp == (stlbrd_t *) NULL)
+		if (brdp == NULL)
 			continue;
 		if (brdp->state == 0)
 			continue;
@@ -1887,9 +1585,9 @@ static int stl_readproc(char *page, char **start, off_t off, int count, int *eof
 		}
 
 		totalport = brdnr * STL_MAXPORTS;
-		for (panelnr = 0; (panelnr < brdp->nrpanels); panelnr++) {
+		for (panelnr = 0; panelnr < brdp->nrpanels; panelnr++) {
 			panelp = brdp->panels[panelnr];
-			if (panelp == (stlpanel_t *) NULL)
+			if (panelp == NULL)
 				continue;
 
 			maxoff = curoff + (panelp->nrports * MAXLINE);
@@ -1899,10 +1597,10 @@ static int stl_readproc(char *page, char **start, off_t off, int count, int *eof
 				continue;
 			}
 
-			for (portnr = 0; (portnr < panelp->nrports); portnr++,
+			for (portnr = 0; portnr < panelp->nrports; portnr++,
 			    totalport++) {
 				portp = panelp->ports[portnr];
-				if (portp == (stlport_t *) NULL)
+				if (portp == NULL)
 					continue;
 				if (off >= (curoff += MAXLINE))
 					continue;
@@ -1917,7 +1615,7 @@ static int stl_readproc(char *page, char **start, off_t off, int count, int *eof
 
 stl_readdone:
 	*start = page;
-	return (pos - page);
+	return pos - page;
 }
 
 /*****************************************************************************/
@@ -1929,11 +1627,9 @@ stl_readdone:
 
 static irqreturn_t stl_intr(int irq, void *dev_id)
 {
-	stlbrd_t	*brdp = (stlbrd_t *) dev_id;
+	struct stlbrd *brdp = dev_id;
 
-#ifdef DEBUG
-	printk("stl_intr(brdp=%x,irq=%d)\n", (int) brdp, irq);
-#endif
+	pr_debug("stl_intr(brdp=%p,irq=%d)\n", brdp, irq);
 
 	return IRQ_RETVAL((* brdp->isr)(brdp));
 }
@@ -1944,9 +1640,9 @@ static irqreturn_t stl_intr(int irq, void *dev_id)
  *	Interrupt service routine for EasyIO board types.
  */
 
-static int stl_eiointr(stlbrd_t *brdp)
+static int stl_eiointr(struct stlbrd *brdp)
 {
-	stlpanel_t	*panelp;
+	struct stlpanel	*panelp;
 	unsigned int	iobase;
 	int		handled = 0;
 
@@ -1967,18 +1663,17 @@ static int stl_eiointr(stlbrd_t *brdp)
  *	Interrupt service routine for ECH-AT board types.
  */
 
-static int stl_echatintr(stlbrd_t *brdp)
+static int stl_echatintr(struct stlbrd *brdp)
 {
-	stlpanel_t	*panelp;
-	unsigned int	ioaddr;
-	int		bnknr;
+	struct stlpanel	*panelp;
+	unsigned int	ioaddr, bnknr;
 	int		handled = 0;
 
 	outb((brdp->ioctrlval | ECH_BRDENABLE), brdp->ioctrl);
 
 	while (inb(brdp->iostatus) & ECH_INTRPEND) {
 		handled = 1;
-		for (bnknr = 0; (bnknr < brdp->nrbnks); bnknr++) {
+		for (bnknr = 0; bnknr < brdp->nrbnks; bnknr++) {
 			ioaddr = brdp->bnkstataddr[bnknr];
 			if (inb(ioaddr) & ECH_PNLINTRPEND) {
 				panelp = brdp->bnk2panel[bnknr];
@@ -1998,16 +1693,15 @@ static int stl_echatintr(stlbrd_t *brdp)
  *	Interrupt service routine for ECH-MCA board types.
  */
 
-static int stl_echmcaintr(stlbrd_t *brdp)
+static int stl_echmcaintr(struct stlbrd *brdp)
 {
-	stlpanel_t	*panelp;
-	unsigned int	ioaddr;
-	int		bnknr;
+	struct stlpanel	*panelp;
+	unsigned int	ioaddr, bnknr;
 	int		handled = 0;
 
 	while (inb(brdp->iostatus) & ECH_INTRPEND) {
 		handled = 1;
-		for (bnknr = 0; (bnknr < brdp->nrbnks); bnknr++) {
+		for (bnknr = 0; bnknr < brdp->nrbnks; bnknr++) {
 			ioaddr = brdp->bnkstataddr[bnknr];
 			if (inb(ioaddr) & ECH_PNLINTRPEND) {
 				panelp = brdp->bnk2panel[bnknr];
@@ -2024,16 +1718,15 @@ static int stl_echmcaintr(stlbrd_t *brdp)
  *	Interrupt service routine for ECH-PCI board types.
  */
 
-static int stl_echpciintr(stlbrd_t *brdp)
+static int stl_echpciintr(struct stlbrd *brdp)
 {
-	stlpanel_t	*panelp;
-	unsigned int	ioaddr;
-	int		bnknr, recheck;
+	struct stlpanel	*panelp;
+	unsigned int	ioaddr, bnknr, recheck;
 	int		handled = 0;
 
 	while (1) {
 		recheck = 0;
-		for (bnknr = 0; (bnknr < brdp->nrbnks); bnknr++) {
+		for (bnknr = 0; bnknr < brdp->nrbnks; bnknr++) {
 			outb(brdp->bnkpageaddr[bnknr], brdp->ioctrl);
 			ioaddr = brdp->bnkstataddr[bnknr];
 			if (inb(ioaddr) & ECH_PNLINTRPEND) {
@@ -2055,16 +1748,15 @@ static int stl_echpciintr(stlbrd_t *brdp)
  *	Interrupt service routine for ECH-8/64-PCI board types.
  */
 
-static int stl_echpci64intr(stlbrd_t *brdp)
+static int stl_echpci64intr(struct stlbrd *brdp)
 {
-	stlpanel_t	*panelp;
-	unsigned int	ioaddr;
-	int		bnknr;
+	struct stlpanel	*panelp;
+	unsigned int	ioaddr, bnknr;
 	int		handled = 0;
 
 	while (inb(brdp->ioctrl) & 0x1) {
 		handled = 1;
-		for (bnknr = 0; (bnknr < brdp->nrbnks); bnknr++) {
+		for (bnknr = 0; bnknr < brdp->nrbnks; bnknr++) {
 			ioaddr = brdp->bnkstataddr[bnknr];
 			if (inb(ioaddr) & ECH_PNLINTRPEND) {
 				panelp = brdp->bnk2panel[bnknr];
@@ -2083,35 +1775,32 @@ static int stl_echpci64intr(stlbrd_t *brdp)
  */
 static void stl_offintr(struct work_struct *work)
 {
-	stlport_t		*portp = container_of(work, stlport_t, tqueue);
+	struct stlport		*portp = container_of(work, struct stlport, tqueue);
 	struct tty_struct	*tty;
 	unsigned int		oldsigs;
 
-#ifdef DEBUG
-	printk("stl_offintr(portp=%x)\n", (int) portp);
-#endif
+	pr_debug("stl_offintr(portp=%p)\n", portp);
 
-	if (portp == (stlport_t *) NULL)
+	if (portp == NULL)
 		return;
 
 	tty = portp->tty;
-	if (tty == (struct tty_struct *) NULL)
+	if (tty == NULL)
 		return;
 
 	lock_kernel();
-	if (test_bit(ASYI_TXLOW, &portp->istate)) {
+	if (test_bit(ASYI_TXLOW, &portp->istate))
 		tty_wakeup(tty);
-	}
+
 	if (test_bit(ASYI_DCDCHANGE, &portp->istate)) {
 		clear_bit(ASYI_DCDCHANGE, &portp->istate);
 		oldsigs = portp->sigs;
 		portp->sigs = stl_getsignals(portp);
 		if ((portp->sigs & TIOCM_CD) && ((oldsigs & TIOCM_CD) == 0))
 			wake_up_interruptible(&portp->open_wait);
-		if ((oldsigs & TIOCM_CD) && ((portp->sigs & TIOCM_CD) == 0)) {
+		if ((oldsigs & TIOCM_CD) && ((portp->sigs & TIOCM_CD) == 0))
 			if (portp->flags & ASYNC_CHECK_CD)
 				tty_hangup(tty);	/* FIXME: module removal race here - AKPM */
-		}
 	}
 	unlock_kernel();
 }
@@ -2122,14 +1811,13 @@ static void stl_offintr(struct work_struct *work)
  *	Initialize all the ports on a panel.
  */
 
-static int __init stl_initports(stlbrd_t *brdp, stlpanel_t *panelp)
+static int __devinit stl_initports(struct stlbrd *brdp, struct stlpanel *panelp)
 {
-	stlport_t	*portp;
-	int		chipmask, i;
+	struct stlport *portp;
+	unsigned int i;
+	int chipmask;
 
-#ifdef DEBUG
-	printk("stl_initports(brdp=%x,panelp=%x)\n", (int) brdp, (int) panelp);
-#endif
+	pr_debug("stl_initports(brdp=%p,panelp=%p)\n", brdp, panelp);
 
 	chipmask = stl_panelinit(brdp, panelp);
 
@@ -2137,11 +1825,11 @@ static int __init stl_initports(stlbrd_t *brdp, stlpanel_t *panelp)
  *	All UART's are initialized (if found!). Now go through and setup
  *	each ports data structures.
  */
-	for (i = 0; (i < panelp->nrports); i++) {
-		portp = kzalloc(sizeof(stlport_t), GFP_KERNEL);
+	for (i = 0; i < panelp->nrports; i++) {
+		portp = kzalloc(sizeof(struct stlport), GFP_KERNEL);
 		if (!portp) {
 			printk("STALLION: failed to allocate memory "
-				"(size=%Zd)\n", sizeof(stlport_t));
+				"(size=%Zd)\n", sizeof(struct stlport));
 			break;
 		}
 
@@ -2164,7 +1852,30 @@ static int __init stl_initports(stlbrd_t *brdp, stlpanel_t *panelp)
 		stl_portinit(brdp, panelp, portp);
 	}
 
-	return(0);
+	return 0;
+}
+
+static void stl_cleanup_panels(struct stlbrd *brdp)
+{
+	struct stlpanel *panelp;
+	struct stlport *portp;
+	unsigned int j, k;
+
+	for (j = 0; j < STL_MAXPANELS; j++) {
+		panelp = brdp->panels[j];
+		if (panelp == NULL)
+			continue;
+		for (k = 0; k < STL_PORTSPERPANEL; k++) {
+			portp = panelp->ports[k];
+			if (portp == NULL)
+				continue;
+			if (portp->tty != NULL)
+				stl_hangup(portp->tty);
+			kfree(portp->tx.buf);
+			kfree(portp);
+		}
+		kfree(panelp);
+	}
 }
 
 /*****************************************************************************/
@@ -2173,16 +1884,14 @@ static int __init stl_initports(stlbrd_t *brdp, stlpanel_t *panelp)
  *	Try to find and initialize an EasyIO board.
  */
 
-static inline int stl_initeio(stlbrd_t *brdp)
+static int __devinit stl_initeio(struct stlbrd *brdp)
 {
-	stlpanel_t	*panelp;
+	struct stlpanel	*panelp;
 	unsigned int	status;
 	char		*name;
-	int		rc;
+	int		retval;
 
-#ifdef DEBUG
-	printk("stl_initeio(brdp=%x)\n", (int) brdp);
-#endif
+	pr_debug("stl_initeio(brdp=%p)\n", brdp);
 
 	brdp->ioctrl = brdp->ioaddr1 + 1;
 	brdp->iostatus = brdp->ioaddr1 + 2;
@@ -2207,18 +1916,20 @@ static inline int stl_initeio(stlbrd_t *brdp)
 		    (stl_vecmap[brdp->irq] == (unsigned char) 0xff)) {
 			printk("STALLION: invalid irq=%d for brd=%d\n",
 				brdp->irq, brdp->brdnr);
-			return(-EINVAL);
+			retval = -EINVAL;
+			goto err;
 		}
 		outb((stl_vecmap[brdp->irq] | EIO_0WS |
 			((brdp->irqtype) ? EIO_INTLEVEL : EIO_INTEDGE)),
 			brdp->ioctrl);
 	}
 
+	retval = -EBUSY;
 	if (!request_region(brdp->ioaddr1, brdp->iosize1, name)) {
 		printk(KERN_WARNING "STALLION: Warning, board %d I/O address "
 			"%x conflicts with another device\n", brdp->brdnr, 
 			brdp->ioaddr1);
-		return(-EBUSY);
+		goto err;
 	}
 	
 	if (brdp->iosize2 > 0)
@@ -2229,8 +1940,7 @@ static inline int stl_initeio(stlbrd_t *brdp)
 			printk(KERN_WARNING "STALLION: Warning, also "
 				"releasing board %d I/O address %x \n", 
 				brdp->brdnr, brdp->ioaddr1);
-			release_region(brdp->ioaddr1, brdp->iosize1);
-        		return(-EBUSY);
+			goto err_rel1;
 		}
 
 /*
@@ -2239,6 +1949,7 @@ static inline int stl_initeio(stlbrd_t *brdp)
 	brdp->clk = CD1400_CLK;
 	brdp->isr = stl_eiointr;
 
+	retval = -ENODEV;
 	switch (status & EIO_IDBITMASK) {
 	case EIO_8PORTM:
 		brdp->clk = CD1400_CLK8M;
@@ -2262,11 +1973,11 @@ static inline int stl_initeio(stlbrd_t *brdp)
 			brdp->nrports = 16;
 			break;
 		default:
-			return(-ENODEV);
+			goto err_rel2;
 		}
 		break;
 	default:
-		return(-ENODEV);
+		goto err_rel2;
 	}
 
 /*
@@ -2274,11 +1985,12 @@ static inline int stl_initeio(stlbrd_t *brdp)
  *	can complete the setup.
  */
 
-	panelp = kzalloc(sizeof(stlpanel_t), GFP_KERNEL);
+	panelp = kzalloc(sizeof(struct stlpanel), GFP_KERNEL);
 	if (!panelp) {
 		printk(KERN_WARNING "STALLION: failed to allocate memory "
-			"(size=%Zd)\n", sizeof(stlpanel_t));
-		return -ENOMEM;
+			"(size=%Zd)\n", sizeof(struct stlpanel));
+		retval = -ENOMEM;
+		goto err_rel2;
 	}
 
 	panelp->magic = STL_PANELMAGIC;
@@ -2288,10 +2000,10 @@ static inline int stl_initeio(stlbrd_t *brdp)
 	panelp->iobase = brdp->ioaddr1;
 	panelp->hwid = status;
 	if ((status & EIO_IDBITMASK) == EIO_MK3) {
-		panelp->uartp = (void *) &stl_sc26198uart;
+		panelp->uartp = &stl_sc26198uart;
 		panelp->isr = stl_sc26198intr;
 	} else {
-		panelp->uartp = (void *) &stl_cd1400uart;
+		panelp->uartp = &stl_cd1400uart;
 		panelp->isr = stl_cd1400eiointr;
 	}
 
@@ -2302,11 +2014,20 @@ static inline int stl_initeio(stlbrd_t *brdp)
 	if (request_irq(brdp->irq, stl_intr, IRQF_SHARED, name, brdp) != 0) {
 		printk("STALLION: failed to register interrupt "
 		    "routine for %s irq=%d\n", name, brdp->irq);
-		rc = -ENODEV;
-	} else {
-		rc = 0;
+		retval = -ENODEV;
+		goto err_fr;
 	}
-	return rc;
+
+	return 0;
+err_fr:
+	stl_cleanup_panels(brdp);
+err_rel2:
+	if (brdp->iosize2 > 0)
+		release_region(brdp->ioaddr2, brdp->iosize2);
+err_rel1:
+	release_region(brdp->ioaddr1, brdp->iosize1);
+err:
+	return retval;
 }
 
 /*****************************************************************************/
@@ -2316,16 +2037,14 @@ static inline int stl_initeio(stlbrd_t *brdp)
  *	dealing with all types of ECH board.
  */
 
-static inline int stl_initech(stlbrd_t *brdp)
+static int __devinit stl_initech(struct stlbrd *brdp)
 {
-	stlpanel_t	*panelp;
-	unsigned int	status, nxtid, ioaddr, conflict;
-	int		panelnr, banknr, i;
+	struct stlpanel	*panelp;
+	unsigned int	status, nxtid, ioaddr, conflict, panelnr, banknr, i;
+	int		retval;
 	char		*name;
 
-#ifdef DEBUG
-	printk("stl_initech(brdp=%x)\n", (int) brdp);
-#endif
+	pr_debug("stl_initech(brdp=%p)\n", brdp);
 
 	status = 0;
 	conflict = 0;
@@ -2342,20 +2061,23 @@ static inline int stl_initech(stlbrd_t *brdp)
 		brdp->ioctrl = brdp->ioaddr1 + 1;
 		brdp->iostatus = brdp->ioaddr1 + 1;
 		status = inb(brdp->iostatus);
-		if ((status & ECH_IDBITMASK) != ECH_ID)
-			return(-ENODEV);
+		if ((status & ECH_IDBITMASK) != ECH_ID) {
+			retval = -ENODEV;
+			goto err;
+		}
 		if ((brdp->irq < 0) || (brdp->irq > 15) ||
 		    (stl_vecmap[brdp->irq] == (unsigned char) 0xff)) {
 			printk("STALLION: invalid irq=%d for brd=%d\n",
 				brdp->irq, brdp->brdnr);
-			return(-EINVAL);
+			retval = -EINVAL;
+			goto err;
 		}
 		status = ((brdp->ioaddr2 & ECH_ADDR2MASK) >> 1);
 		status |= (stl_vecmap[brdp->irq] << 1);
 		outb((status | ECH_BRDRESET), brdp->ioaddr1);
 		brdp->ioctrlval = ECH_INTENABLE |
 			((brdp->irqtype) ? ECH_INTLEVEL : ECH_INTEDGE);
-		for (i = 0; (i < 10); i++)
+		for (i = 0; i < 10; i++)
 			outb((brdp->ioctrlval | ECH_BRDENABLE), brdp->ioctrl);
 		brdp->iosize1 = 2;
 		brdp->iosize2 = 32;
@@ -2368,13 +2090,16 @@ static inline int stl_initech(stlbrd_t *brdp)
 		brdp->ioctrl = brdp->ioaddr1 + 0x20;
 		brdp->iostatus = brdp->ioctrl;
 		status = inb(brdp->iostatus);
-		if ((status & ECH_IDBITMASK) != ECH_ID)
-			return(-ENODEV);
+		if ((status & ECH_IDBITMASK) != ECH_ID) {
+			retval = -ENODEV;
+			goto err;
+		}
 		if ((brdp->irq < 0) || (brdp->irq > 15) ||
 		    (stl_vecmap[brdp->irq] == (unsigned char) 0xff)) {
 			printk("STALLION: invalid irq=%d for brd=%d\n",
 				brdp->irq, brdp->brdnr);
-			return(-EINVAL);
+			retval = -EINVAL;
+			goto err;
 		}
 		outb(ECHMC_BRDRESET, brdp->ioctrl);
 		outb(ECHMC_INTENABLE, brdp->ioctrl);
@@ -2401,19 +2126,20 @@ static inline int stl_initech(stlbrd_t *brdp)
 
 	default:
 		printk("STALLION: unknown board type=%d\n", brdp->brdtype);
-		return(-EINVAL);
-		break;
+		retval = -EINVAL;
+		goto err;
 	}
 
 /*
  *	Check boards for possible IO address conflicts and return fail status 
  * 	if an IO conflict found.
  */
+	retval = -EBUSY;
 	if (!request_region(brdp->ioaddr1, brdp->iosize1, name)) {
 		printk(KERN_WARNING "STALLION: Warning, board %d I/O address "
 			"%x conflicts with another device\n", brdp->brdnr, 
 			brdp->ioaddr1);
-		return(-EBUSY);
+		goto err;
 	}
 	
 	if (brdp->iosize2 > 0)
@@ -2424,8 +2150,7 @@ static inline int stl_initech(stlbrd_t *brdp)
 			printk(KERN_WARNING "STALLION: Warning, also "
 				"releasing board %d I/O address %x \n", 
 				brdp->brdnr, brdp->ioaddr1);
-			release_region(brdp->ioaddr1, brdp->iosize1);
-			return(-EBUSY);
+			goto err_rel1;
 		}
 
 /*
@@ -2440,19 +2165,19 @@ static inline int stl_initech(stlbrd_t *brdp)
 	panelnr = 0;
 	nxtid = 0;
 
-	for (i = 0; (i < STL_MAXPANELS); i++) {
+	for (i = 0; i < STL_MAXPANELS; i++) {
 		if (brdp->brdtype == BRD_ECHPCI) {
 			outb(nxtid, brdp->ioctrl);
 			ioaddr = brdp->ioaddr2;
 		}
 		status = inb(ioaddr + ECH_PNLSTATUS);
 		if ((status & ECH_PNLIDMASK) != nxtid)
-			break;
-		panelp = kzalloc(sizeof(stlpanel_t), GFP_KERNEL);
+			goto err_fr;
+		panelp = kzalloc(sizeof(struct stlpanel), GFP_KERNEL);
 		if (!panelp) {
 			printk("STALLION: failed to allocate memory "
-				"(size=%Zd)\n", sizeof(stlpanel_t));
-			break;
+				"(size=%Zd)\n", sizeof(struct stlpanel));
+			goto err_fr;
 		}
 		panelp->magic = STL_PANELMAGIC;
 		panelp->brdnr = brdp->brdnr;
@@ -2465,7 +2190,7 @@ static inline int stl_initech(stlbrd_t *brdp)
 		brdp->bnkstataddr[banknr++] = ioaddr + ECH_PNLSTATUS;
 
 		if (status & ECH_PNLXPID) {
-			panelp->uartp = (void *) &stl_sc26198uart;
+			panelp->uartp = &stl_sc26198uart;
 			panelp->isr = stl_sc26198intr;
 			if (status & ECH_PNL16PORT) {
 				panelp->nrports = 16;
@@ -2473,11 +2198,10 @@ static inline int stl_initech(stlbrd_t *brdp)
 				brdp->bnkpageaddr[banknr] = nxtid;
 				brdp->bnkstataddr[banknr++] = ioaddr + 4 +
 					ECH_PNLSTATUS;
-			} else {
+			} else
 				panelp->nrports = 8;
-			}
 		} else {
-			panelp->uartp = (void *) &stl_cd1400uart;
+			panelp->uartp = &stl_cd1400uart;
 			panelp->isr = stl_cd1400echintr;
 			if (status & ECH_PNL16PORT) {
 				panelp->nrports = 16;
@@ -2500,7 +2224,7 @@ static inline int stl_initech(stlbrd_t *brdp)
 		brdp->panels[panelnr++] = panelp;
 		if ((brdp->brdtype != BRD_ECHPCI) &&
 		    (ioaddr >= (brdp->ioaddr2 + brdp->iosize2)))
-			break;
+			goto err_fr;
 	}
 
 	brdp->nrpanels = panelnr;
@@ -2512,12 +2236,19 @@ static inline int stl_initech(stlbrd_t *brdp)
 	if (request_irq(brdp->irq, stl_intr, IRQF_SHARED, name, brdp) != 0) {
 		printk("STALLION: failed to register interrupt "
 		    "routine for %s irq=%d\n", name, brdp->irq);
-		i = -ENODEV;
-	} else {
-		i = 0;
+		retval = -ENODEV;
+		goto err_fr;
 	}
 
-	return(i);
+	return 0;
+err_fr:
+	stl_cleanup_panels(brdp);
+	if (brdp->iosize2 > 0)
+		release_region(brdp->ioaddr2, brdp->iosize2);
+err_rel1:
+	release_region(brdp->ioaddr1, brdp->iosize1);
+err:
+	return retval;
 }
 
 /*****************************************************************************/
@@ -2529,48 +2260,61 @@ static inline int stl_initech(stlbrd_t *brdp)
  *	since the initial search and setup is very different.
  */
 
-static int __init stl_brdinit(stlbrd_t *brdp)
+static int __devinit stl_brdinit(struct stlbrd *brdp)
 {
-	int	i;
+	int i, retval;
 
-#ifdef DEBUG
-	printk("stl_brdinit(brdp=%x)\n", (int) brdp);
-#endif
+	pr_debug("stl_brdinit(brdp=%p)\n", brdp);
 
 	switch (brdp->brdtype) {
 	case BRD_EASYIO:
 	case BRD_EASYIOPCI:
-		stl_initeio(brdp);
+		retval = stl_initeio(brdp);
+		if (retval)
+			goto err;
 		break;
 	case BRD_ECH:
 	case BRD_ECHMC:
 	case BRD_ECHPCI:
 	case BRD_ECH64PCI:
-		stl_initech(brdp);
+		retval = stl_initech(brdp);
+		if (retval)
+			goto err;
 		break;
 	default:
 		printk("STALLION: board=%d is unknown board type=%d\n",
 			brdp->brdnr, brdp->brdtype);
-		return(ENODEV);
+		retval = -ENODEV;
+		goto err;
 	}
 
-	stl_brds[brdp->brdnr] = brdp;
 	if ((brdp->state & BRD_FOUND) == 0) {
 		printk("STALLION: %s board not found, board=%d io=%x irq=%d\n",
 			stl_brdnames[brdp->brdtype], brdp->brdnr,
 			brdp->ioaddr1, brdp->irq);
-		return(ENODEV);
+		goto err_free;
 	}
 
-	for (i = 0; (i < STL_MAXPANELS); i++)
-		if (brdp->panels[i] != (stlpanel_t *) NULL)
+	for (i = 0; i < STL_MAXPANELS; i++)
+		if (brdp->panels[i] != NULL)
 			stl_initports(brdp, brdp->panels[i]);
 
 	printk("STALLION: %s found, board=%d io=%x irq=%d "
 		"nrpanels=%d nrports=%d\n", stl_brdnames[brdp->brdtype],
 		brdp->brdnr, brdp->ioaddr1, brdp->irq, brdp->nrpanels,
 		brdp->nrports);
-	return(0);
+
+	return 0;
+err_free:
+	free_irq(brdp->irq, brdp);
+
+	stl_cleanup_panels(brdp);
+
+	release_region(brdp->ioaddr1, brdp->iosize1);
+	if (brdp->iosize2 > 0)
+		release_region(brdp->ioaddr2, brdp->iosize2);
+err:
+	return retval;
 }
 
 /*****************************************************************************/
@@ -2579,59 +2323,62 @@ static int __init stl_brdinit(stlbrd_t *brdp)
  *	Find the next available board number that is free.
  */
 
-static inline int stl_getbrdnr(void)
+static int __devinit stl_getbrdnr(void)
 {
-	int	i;
+	unsigned int i;
 
-	for (i = 0; (i < STL_MAXBRDS); i++) {
-		if (stl_brds[i] == (stlbrd_t *) NULL) {
+	for (i = 0; i < STL_MAXBRDS; i++)
+		if (stl_brds[i] == NULL) {
 			if (i >= stl_nrbrds)
 				stl_nrbrds = i + 1;
-			return(i);
+			return i;
 		}
-	}
-	return(-1);
+
+	return -1;
 }
 
 /*****************************************************************************/
-
-#ifdef	CONFIG_PCI
-
 /*
  *	We have a Stallion board. Allocate a board structure and
  *	initialize it. Read its IO and IRQ resources from PCI
  *	configuration space.
  */
 
-static inline int stl_initpcibrd(int brdtype, struct pci_dev *devp)
+static int __devinit stl_pciprobe(struct pci_dev *pdev,
+		const struct pci_device_id *ent)
 {
-	stlbrd_t	*brdp;
-
-#ifdef DEBUG
-	printk("stl_initpcibrd(brdtype=%d,busnr=%x,devnr=%x)\n", brdtype,
-		devp->bus->number, devp->devfn);
-#endif
-
-	if (pci_enable_device(devp))
-		return(-EIO);
-	if ((brdp = stl_allocbrd()) == (stlbrd_t *) NULL)
-		return(-ENOMEM);
-	if ((brdp->brdnr = stl_getbrdnr()) < 0) {
-		printk("STALLION: too many boards found, "
+	struct stlbrd *brdp;
+	unsigned int i, brdtype = ent->driver_data;
+	int brdnr, retval = -ENODEV;
+
+	if ((pdev->class >> 8) == PCI_CLASS_STORAGE_IDE)
+		goto err;
+
+	dev_info(&pdev->dev, "please, report this to LKML: %x/%x/%x\n",
+			pdev->vendor, pdev->device, pdev->class);
+
+	retval = pci_enable_device(pdev);
+	if (retval)
+		goto err;
+	brdp = stl_allocbrd();
+	if (brdp == NULL) {
+		retval = -ENOMEM;
+		goto err;
+	}
+	mutex_lock(&stl_brdslock);
+	brdnr = stl_getbrdnr();
+	if (brdnr < 0) {
+		dev_err(&pdev->dev, "too many boards found, "
 			"maximum supported %d\n", STL_MAXBRDS);
-		return(0);
+		mutex_unlock(&stl_brdslock);
+		goto err_fr;
 	}
-	brdp->brdtype = brdtype;
+	brdp->brdnr = (unsigned int)brdnr;
+	stl_brds[brdp->brdnr] = brdp;
+	mutex_unlock(&stl_brdslock);
 
-/*
- *	Different Stallion boards use the BAR registers in different ways,
- *	so set up io addresses based on board type.
- */
-#ifdef DEBUG
-	printk("%s(%d): BAR[]=%x,%x,%x,%x IRQ=%x\n", __FILE__, __LINE__,
-		pci_resource_start(devp, 0), pci_resource_start(devp, 1),
-		pci_resource_start(devp, 2), pci_resource_start(devp, 3), devp->irq);
-#endif
+	brdp->brdtype = brdtype;
+	brdp->state |= STL_PROBED;
 
 /*
  *	We have all resources from the board, so let's setup the actual
@@ -2639,120 +2386,70 @@ static inline int stl_initpcibrd(int brdtype, struct pci_dev *devp)
  */
 	switch (brdtype) {
 	case BRD_ECHPCI:
-		brdp->ioaddr2 = pci_resource_start(devp, 0);
-		brdp->ioaddr1 = pci_resource_start(devp, 1);
+		brdp->ioaddr2 = pci_resource_start(pdev, 0);
+		brdp->ioaddr1 = pci_resource_start(pdev, 1);
 		break;
 	case BRD_ECH64PCI:
-		brdp->ioaddr2 = pci_resource_start(devp, 2);
-		brdp->ioaddr1 = pci_resource_start(devp, 1);
+		brdp->ioaddr2 = pci_resource_start(pdev, 2);
+		brdp->ioaddr1 = pci_resource_start(pdev, 1);
 		break;
 	case BRD_EASYIOPCI:
-		brdp->ioaddr1 = pci_resource_start(devp, 2);
-		brdp->ioaddr2 = pci_resource_start(devp, 1);
+		brdp->ioaddr1 = pci_resource_start(pdev, 2);
+		brdp->ioaddr2 = pci_resource_start(pdev, 1);
 		break;
 	default:
-		printk("STALLION: unknown PCI board type=%d\n", brdtype);
+		dev_err(&pdev->dev, "unknown PCI board type=%u\n", brdtype);
 		break;
 	}
 
-	brdp->irq = devp->irq;
-	stl_brdinit(brdp);
-
-	return(0);
-}
-
-/*****************************************************************************/
-
-/*
- *	Find all Stallion PCI boards that might be installed. Initialize each
- *	one as it is found.
- */
-
+	brdp->irq = pdev->irq;
+	retval = stl_brdinit(brdp);
+	if (retval)
+		goto err_null;
 
-static inline int stl_findpcibrds(void)
-{
-	struct pci_dev	*dev = NULL;
-	int		i, rc;
-
-#ifdef DEBUG
-	printk("stl_findpcibrds()\n");
-#endif
+	pci_set_drvdata(pdev, brdp);
 
-	for (i = 0; (i < stl_nrpcibrds); i++)
-		while ((dev = pci_find_device(stl_pcibrds[i].vendid,
-		    stl_pcibrds[i].devid, dev))) {
-
-/*
- *			Found a device on the PCI bus that has our vendor and
- *			device ID. Need to check now that it is really us.
- */
-			if ((dev->class >> 8) == PCI_CLASS_STORAGE_IDE)
-				continue;
-
-			rc = stl_initpcibrd(stl_pcibrds[i].brdtype, dev);
-			if (rc)
-				return(rc);
-		}
+	for (i = 0; i < brdp->nrports; i++)
+		tty_register_device(stl_serial,
+				brdp->brdnr * STL_MAXPORTS + i, &pdev->dev);
 
-	return(0);
+	return 0;
+err_null:
+	stl_brds[brdp->brdnr] = NULL;
+err_fr:
+	kfree(brdp);
+err:
+	return retval;
 }
 
-#endif
-
-/*****************************************************************************/
-
-/*
- *	Scan through all the boards in the configuration and see what we
- *	can find. Handle EIO and the ECH boards a little differently here
- *	since the initial search and setup is too different.
- */
-
-static inline int stl_initbrds(void)
+static void __devexit stl_pciremove(struct pci_dev *pdev)
 {
-	stlbrd_t	*brdp;
-	stlconf_t	*confp;
-	int		i;
+	struct stlbrd *brdp = pci_get_drvdata(pdev);
+	unsigned int i;
 
-#ifdef DEBUG
-	printk("stl_initbrds()\n");
-#endif
+	free_irq(brdp->irq, brdp);
 
-	if (stl_nrbrds > STL_MAXBRDS) {
-		printk("STALLION: too many boards in configuration table, "
-			"truncating to %d\n", STL_MAXBRDS);
-		stl_nrbrds = STL_MAXBRDS;
-	}
+	stl_cleanup_panels(brdp);
 
-/*
- *	Firstly scan the list of static boards configured. Allocate
- *	resources and initialize the boards as found.
- */
-	for (i = 0; (i < stl_nrbrds); i++) {
-		confp = &stl_brdconf[i];
-		stl_parsebrd(confp, stl_brdsp[i]);
-		if ((brdp = stl_allocbrd()) == (stlbrd_t *) NULL)
-			return(-ENOMEM);
-		brdp->brdnr = i;
-		brdp->brdtype = confp->brdtype;
-		brdp->ioaddr1 = confp->ioaddr1;
-		brdp->ioaddr2 = confp->ioaddr2;
-		brdp->irq = confp->irq;
-		brdp->irqtype = confp->irqtype;
-		stl_brdinit(brdp);
-	}
+	release_region(brdp->ioaddr1, brdp->iosize1);
+	if (brdp->iosize2 > 0)
+		release_region(brdp->ioaddr2, brdp->iosize2);
 
-/*
- *	Find any dynamically supported boards. That is via module load
- *	line options or auto-detected on the PCI bus.
- */
-	stl_argbrds();
-#ifdef CONFIG_PCI
-	stl_findpcibrds();
-#endif
+	for (i = 0; i < brdp->nrports; i++)
+		tty_unregister_device(stl_serial,
+				brdp->brdnr * STL_MAXPORTS + i);
 
-	return(0);
+	stl_brds[brdp->brdnr] = NULL;
+	kfree(brdp);
 }
 
+static struct pci_driver stl_pcidriver = {
+	.name = "stallion",
+	.id_table = stl_pcibrds,
+	.probe = stl_pciprobe,
+	.remove = __devexit_p(stl_pciremove)
+};
+
 /*****************************************************************************/
 
 /*
@@ -2761,17 +2458,18 @@ static inline int stl_initbrds(void)
 
 static int stl_getbrdstats(combrd_t __user *bp)
 {
-	stlbrd_t	*brdp;
-	stlpanel_t	*panelp;
-	int		i;
+	combrd_t	stl_brdstats;
+	struct stlbrd	*brdp;
+	struct stlpanel	*panelp;
+	unsigned int i;
 
 	if (copy_from_user(&stl_brdstats, bp, sizeof(combrd_t)))
 		return -EFAULT;
 	if (stl_brdstats.brd >= STL_MAXBRDS)
-		return(-ENODEV);
+		return -ENODEV;
 	brdp = stl_brds[stl_brdstats.brd];
-	if (brdp == (stlbrd_t *) NULL)
-		return(-ENODEV);
+	if (brdp == NULL)
+		return -ENODEV;
 
 	memset(&stl_brdstats, 0, sizeof(combrd_t));
 	stl_brdstats.brd = brdp->brdnr;
@@ -2783,7 +2481,7 @@ static int stl_getbrdstats(combrd_t __user *bp)
 	stl_brdstats.irq = brdp->irq;
 	stl_brdstats.nrpanels = brdp->nrpanels;
 	stl_brdstats.nrports = brdp->nrports;
-	for (i = 0; (i < brdp->nrpanels); i++) {
+	for (i = 0; i < brdp->nrpanels; i++) {
 		panelp = brdp->panels[i];
 		stl_brdstats.panels[i].panel = i;
 		stl_brdstats.panels[i].hwid = panelp->hwid;
@@ -2799,24 +2497,24 @@ static int stl_getbrdstats(combrd_t __user *bp)
  *	Resolve the referenced port number into a port struct pointer.
  */
 
-static stlport_t *stl_getport(int brdnr, int panelnr, int portnr)
+static struct stlport *stl_getport(int brdnr, int panelnr, int portnr)
 {
-	stlbrd_t	*brdp;
-	stlpanel_t	*panelp;
+	struct stlbrd	*brdp;
+	struct stlpanel	*panelp;
 
-	if ((brdnr < 0) || (brdnr >= STL_MAXBRDS))
-		return((stlport_t *) NULL);
+	if (brdnr < 0 || brdnr >= STL_MAXBRDS)
+		return NULL;
 	brdp = stl_brds[brdnr];
-	if (brdp == (stlbrd_t *) NULL)
-		return((stlport_t *) NULL);
-	if ((panelnr < 0) || (panelnr >= brdp->nrpanels))
-		return((stlport_t *) NULL);
+	if (brdp == NULL)
+		return NULL;
+	if (panelnr < 0 || (unsigned int)panelnr >= brdp->nrpanels)
+		return NULL;
 	panelp = brdp->panels[panelnr];
-	if (panelp == (stlpanel_t *) NULL)
-		return((stlport_t *) NULL);
-	if ((portnr < 0) || (portnr >= panelp->nrports))
-		return((stlport_t *) NULL);
-	return(panelp->ports[portnr]);
+	if (panelp == NULL)
+		return NULL;
+	if (portnr < 0 || (unsigned int)portnr >= panelp->nrports)
+		return NULL;
+	return panelp->ports[portnr];
 }
 
 /*****************************************************************************/
@@ -2827,8 +2525,9 @@ static stlport_t *stl_getport(int brdnr, int panelnr, int portnr)
  *	what port to get stats for (used through board control device).
  */
 
-static int stl_getportstats(stlport_t *portp, comstats_t __user *cp)
+static int stl_getportstats(struct stlport *portp, comstats_t __user *cp)
 {
+	comstats_t	stl_comstats;
 	unsigned char	*head, *tail;
 	unsigned long	flags;
 
@@ -2837,8 +2536,8 @@ static int stl_getportstats(stlport_t *portp, comstats_t __user *cp)
 			return -EFAULT;
 		portp = stl_getport(stl_comstats.brd, stl_comstats.panel,
 			stl_comstats.port);
-		if (portp == (stlport_t *) NULL)
-			return(-ENODEV);
+		if (portp == NULL)
+			return -ENODEV;
 	}
 
 	portp->stats.state = portp->istate;
@@ -2853,25 +2552,24 @@ static int stl_getportstats(stlport_t *portp, comstats_t __user *cp)
 	portp->stats.rxbuffered = 0;
 
 	spin_lock_irqsave(&stallion_lock, flags);
-	if (portp->tty != (struct tty_struct *) NULL) {
+	if (portp->tty != NULL)
 		if (portp->tty->driver_data == portp) {
 			portp->stats.ttystate = portp->tty->flags;
 			/* No longer available as a statistic */
 			portp->stats.rxbuffered = 1; /*portp->tty->flip.count; */
-			if (portp->tty->termios != (struct termios *) NULL) {
+			if (portp->tty->termios != NULL) {
 				portp->stats.cflags = portp->tty->termios->c_cflag;
 				portp->stats.iflags = portp->tty->termios->c_iflag;
 				portp->stats.oflags = portp->tty->termios->c_oflag;
 				portp->stats.lflags = portp->tty->termios->c_lflag;
 			}
 		}
-	}
 	spin_unlock_irqrestore(&stallion_lock, flags);
 
 	head = portp->tx.head;
 	tail = portp->tx.tail;
-	portp->stats.txbuffered = ((head >= tail) ? (head - tail) :
-		(STL_TXBUFSIZE - (tail - head)));
+	portp->stats.txbuffered = (head >= tail) ? (head - tail) :
+		(STL_TXBUFSIZE - (tail - head));
 
 	portp->stats.signals = (unsigned long) stl_getsignals(portp);
 
@@ -2885,15 +2583,17 @@ static int stl_getportstats(stlport_t *portp, comstats_t __user *cp)
  *	Clear the port stats structure. We also return it zeroed out...
  */
 
-static int stl_clrportstats(stlport_t *portp, comstats_t __user *cp)
+static int stl_clrportstats(struct stlport *portp, comstats_t __user *cp)
 {
+	comstats_t	stl_comstats;
+
 	if (!portp) {
 		if (copy_from_user(&stl_comstats, cp, sizeof(comstats_t)))
 			return -EFAULT;
 		portp = stl_getport(stl_comstats.brd, stl_comstats.panel,
 			stl_comstats.port);
-		if (portp == (stlport_t *) NULL)
-			return(-ENODEV);
+		if (portp == NULL)
+			return -ENODEV;
 	}
 
 	memset(&portp->stats, 0, sizeof(comstats_t));
@@ -2910,17 +2610,18 @@ static int stl_clrportstats(stlport_t *portp, comstats_t __user *cp)
  *	Return the entire driver ports structure to a user app.
  */
 
-static int stl_getportstruct(stlport_t __user *arg)
+static int stl_getportstruct(struct stlport __user *arg)
 {
-	stlport_t	*portp;
+	struct stlport	stl_dummyport;
+	struct stlport	*portp;
 
-	if (copy_from_user(&stl_dummyport, arg, sizeof(stlport_t)))
+	if (copy_from_user(&stl_dummyport, arg, sizeof(struct stlport)))
 		return -EFAULT;
 	portp = stl_getport(stl_dummyport.brdnr, stl_dummyport.panelnr,
 		 stl_dummyport.portnr);
 	if (!portp)
 		return -ENODEV;
-	return copy_to_user(arg, portp, sizeof(stlport_t)) ? -EFAULT : 0;
+	return copy_to_user(arg, portp, sizeof(struct stlport)) ? -EFAULT : 0;
 }
 
 /*****************************************************************************/
@@ -2929,18 +2630,19 @@ static int stl_getportstruct(stlport_t __user *arg)
  *	Return the entire driver board structure to a user app.
  */
 
-static int stl_getbrdstruct(stlbrd_t __user *arg)
+static int stl_getbrdstruct(struct stlbrd __user *arg)
 {
-	stlbrd_t	*brdp;
+	struct stlbrd	stl_dummybrd;
+	struct stlbrd	*brdp;
 
-	if (copy_from_user(&stl_dummybrd, arg, sizeof(stlbrd_t)))
+	if (copy_from_user(&stl_dummybrd, arg, sizeof(struct stlbrd)))
 		return -EFAULT;
-	if ((stl_dummybrd.brdnr < 0) || (stl_dummybrd.brdnr >= STL_MAXBRDS))
+	if (stl_dummybrd.brdnr >= STL_MAXBRDS)
 		return -ENODEV;
 	brdp = stl_brds[stl_dummybrd.brdnr];
 	if (!brdp)
-		return(-ENODEV);
-	return copy_to_user(arg, brdp, sizeof(stlbrd_t)) ? -EFAULT : 0;
+		return -ENODEV;
+	return copy_to_user(arg, brdp, sizeof(struct stlbrd)) ? -EFAULT : 0;
 }
 
 /*****************************************************************************/
@@ -2956,14 +2658,11 @@ static int stl_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, uns
 	int	brdnr, rc;
 	void __user *argp = (void __user *)arg;
 
-#ifdef DEBUG
-	printk("stl_memioctl(ip=%x,fp=%x,cmd=%x,arg=%x)\n", (int) ip,
-		(int) fp, cmd, (int) arg);
-#endif
+	pr_debug("stl_memioctl(ip=%p,fp=%p,cmd=%x,arg=%lx)\n", ip, fp, cmd,arg);
 
 	brdnr = iminor(ip);
 	if (brdnr >= STL_MAXBRDS)
-		return(-ENODEV);
+		return -ENODEV;
 	rc = 0;
 
 	switch (cmd) {
@@ -2987,7 +2686,7 @@ static int stl_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, uns
 		break;
 	}
 
-	return(rc);
+	return rc;
 }
 
 static const struct tty_operations stl_ops = {
@@ -3015,55 +2714,6 @@ static const struct tty_operations stl_ops = {
 };
 
 /*****************************************************************************/
-
-static int __init stl_init(void)
-{
-	int i;
-	printk(KERN_INFO "%s: version %s\n", stl_drvtitle, stl_drvversion);
-
-	spin_lock_init(&stallion_lock);
-	spin_lock_init(&brd_lock);
-
-	stl_initbrds();
-
-	stl_serial = alloc_tty_driver(STL_MAXBRDS * STL_MAXPORTS);
-	if (!stl_serial)
-		return -1;
-
-/*
- *	Set up a character driver for per board stuff. This is mainly used
- *	to do stats ioctls on the ports.
- */
-	if (register_chrdev(STL_SIOMEMMAJOR, "staliomem", &stl_fsiomem))
-		printk("STALLION: failed to register serial board device\n");
-
-	stallion_class = class_create(THIS_MODULE, "staliomem");
-	for (i = 0; i < 4; i++)
-		class_device_create(stallion_class, NULL,
-				    MKDEV(STL_SIOMEMMAJOR, i), NULL,
-				    "staliomem%d", i);
-
-	stl_serial->owner = THIS_MODULE;
-	stl_serial->driver_name = stl_drvname;
-	stl_serial->name = "ttyE";
-	stl_serial->major = STL_SERIALMAJOR;
-	stl_serial->minor_start = 0;
-	stl_serial->type = TTY_DRIVER_TYPE_SERIAL;
-	stl_serial->subtype = SERIAL_TYPE_NORMAL;
-	stl_serial->init_termios = stl_deftermios;
-	stl_serial->flags = TTY_DRIVER_REAL_RAW;
-	tty_set_operations(stl_serial, &stl_ops);
-
-	if (tty_register_driver(stl_serial)) {
-		put_tty_driver(stl_serial);
-		printk("STALLION: failed to register serial driver\n");
-		return -1;
-	}
-
-	return 0;
-}
-
-/*****************************************************************************/
 /*                       CD1400 HARDWARE FUNCTIONS                           */
 /*****************************************************************************/
 
@@ -3073,21 +2723,21 @@ static int __init stl_init(void)
  *	(Maybe should make this inline...)
  */
 
-static int stl_cd1400getreg(stlport_t *portp, int regnr)
+static int stl_cd1400getreg(struct stlport *portp, int regnr)
 {
 	outb((regnr + portp->uartaddr), portp->ioaddr);
 	return inb(portp->ioaddr + EREG_DATA);
 }
 
-static void stl_cd1400setreg(stlport_t *portp, int regnr, int value)
+static void stl_cd1400setreg(struct stlport *portp, int regnr, int value)
 {
-	outb((regnr + portp->uartaddr), portp->ioaddr);
+	outb(regnr + portp->uartaddr, portp->ioaddr);
 	outb(value, portp->ioaddr + EREG_DATA);
 }
 
-static int stl_cd1400updatereg(stlport_t *portp, int regnr, int value)
+static int stl_cd1400updatereg(struct stlport *portp, int regnr, int value)
 {
-	outb((regnr + portp->uartaddr), portp->ioaddr);
+	outb(regnr + portp->uartaddr, portp->ioaddr);
 	if (inb(portp->ioaddr + EREG_DATA) != value) {
 		outb(value, portp->ioaddr + EREG_DATA);
 		return 1;
@@ -3103,16 +2753,14 @@ static int stl_cd1400updatereg(stlport_t *portp, int regnr, int value)
  *	identical when dealing with ports.
  */
 
-static int stl_cd1400panelinit(stlbrd_t *brdp, stlpanel_t *panelp)
+static int stl_cd1400panelinit(struct stlbrd *brdp, struct stlpanel *panelp)
 {
 	unsigned int	gfrcr;
 	int		chipmask, i, j;
 	int		nrchips, uartaddr, ioaddr;
 	unsigned long   flags;
 
-#ifdef DEBUG
-	printk("stl_panelinit(brdp=%x,panelp=%x)\n", (int) brdp, (int) panelp);
-#endif
+	pr_debug("stl_panelinit(brdp=%p,panelp=%p)\n", brdp, panelp);
 
 	spin_lock_irqsave(&brd_lock, flags);
 	BRDENABLE(panelp->brdnr, panelp->pagenr);
@@ -3122,13 +2770,12 @@ static int stl_cd1400panelinit(stlbrd_t *brdp, stlpanel_t *panelp)
  */
 	chipmask = 0;
 	nrchips = panelp->nrports / CD1400_PORTS;
-	for (i = 0; (i < nrchips); i++) {
+	for (i = 0; i < nrchips; i++) {
 		if (brdp->brdtype == BRD_ECHPCI) {
 			outb((panelp->pagenr + (i >> 1)), brdp->ioctrl);
 			ioaddr = panelp->iobase;
-		} else {
+		} else
 			ioaddr = panelp->iobase + (EREG_BANKSIZE * (i >> 1));
-		}
 		uartaddr = (i & 0x01) ? 0x080 : 0;
 		outb((GFRCR + uartaddr), ioaddr);
 		outb(0, (ioaddr + EREG_DATA));
@@ -3136,10 +2783,10 @@ static int stl_cd1400panelinit(stlbrd_t *brdp, stlpanel_t *panelp)
 		outb(CCR_RESETFULL, (ioaddr + EREG_DATA));
 		outb(CCR_RESETFULL, (ioaddr + EREG_DATA));
 		outb((GFRCR + uartaddr), ioaddr);
-		for (j = 0; (j < CCR_MAXWAIT); j++) {
+		for (j = 0; j < CCR_MAXWAIT; j++)
 			if ((gfrcr = inb(ioaddr + EREG_DATA)) != 0)
 				break;
-		}
+
 		if ((j >= CCR_MAXWAIT) || (gfrcr < 0x40) || (gfrcr > 0x60)) {
 			printk("STALLION: cd1400 not responding, "
 				"brd=%d panel=%d chip=%d\n",
@@ -3162,16 +2809,14 @@ static int stl_cd1400panelinit(stlbrd_t *brdp, stlpanel_t *panelp)
  *	Initialize hardware specific port registers.
  */
 
-static void stl_cd1400portinit(stlbrd_t *brdp, stlpanel_t *panelp, stlport_t *portp)
+static void stl_cd1400portinit(struct stlbrd *brdp, struct stlpanel *panelp, struct stlport *portp)
 {
 	unsigned long flags;
-#ifdef DEBUG
-	printk("stl_cd1400portinit(brdp=%x,panelp=%x,portp=%x)\n",
-		(int) brdp, (int) panelp, (int) portp);
-#endif
+	pr_debug("stl_cd1400portinit(brdp=%p,panelp=%p,portp=%p)\n", brdp,
+			panelp, portp);
 
-	if ((brdp == (stlbrd_t *) NULL) || (panelp == (stlpanel_t *) NULL) ||
-	    (portp == (stlport_t *) NULL))
+	if ((brdp == NULL) || (panelp == NULL) ||
+	    (portp == NULL))
 		return;
 
 	spin_lock_irqsave(&brd_lock, flags);
@@ -3195,15 +2840,13 @@ static void stl_cd1400portinit(stlbrd_t *brdp, stlpanel_t *panelp, stlport_t *po
  *	since it won't usually take too long to be ready.
  */
 
-static void stl_cd1400ccrwait(stlport_t *portp)
+static void stl_cd1400ccrwait(struct stlport *portp)
 {
 	int	i;
 
-	for (i = 0; (i < CCR_MAXWAIT); i++) {
-		if (stl_cd1400getreg(portp, CCR) == 0) {
+	for (i = 0; i < CCR_MAXWAIT; i++)
+		if (stl_cd1400getreg(portp, CCR) == 0)
 			return;
-		}
-	}
 
 	printk("STALLION: cd1400 not responding, port=%d panel=%d brd=%d\n",
 		portp->portnr, portp->panelnr, portp->brdnr);
@@ -3216,9 +2859,9 @@ static void stl_cd1400ccrwait(stlport_t *portp)
  *	settings.
  */
 
-static void stl_cd1400setport(stlport_t *portp, struct termios *tiosp)
+static void stl_cd1400setport(struct stlport *portp, struct ktermios *tiosp)
 {
-	stlbrd_t	*brdp;
+	struct stlbrd	*brdp;
 	unsigned long	flags;
 	unsigned int	clkdiv, baudrate;
 	unsigned char	cor1, cor2, cor3;
@@ -3242,7 +2885,7 @@ static void stl_cd1400setport(stlport_t *portp, struct termios *tiosp)
 	sreroff = 0;
 
 	brdp = stl_brds[portp->brdnr];
-	if (brdp == (stlbrd_t *) NULL)
+	if (brdp == NULL)
 		return;
 
 /*
@@ -3339,8 +2982,8 @@ static void stl_cd1400setport(stlport_t *portp, struct termios *tiosp)
 		baudrate = STL_CD1400MAXBAUD;
 
 	if (baudrate > 0) {
-		for (clk = 0; (clk < CD1400_NUMCLKS); clk++) {
-			clkdiv = ((portp->clk / stl_cd1400clkdivs[clk]) / baudrate);
+		for (clk = 0; clk < CD1400_NUMCLKS; clk++) {
+			clkdiv = (portp->clk / stl_cd1400clkdivs[clk]) / baudrate;
 			if (clkdiv < 0x100)
 				break;
 		}
@@ -3355,9 +2998,8 @@ static void stl_cd1400setport(stlport_t *portp, struct termios *tiosp)
 		mcor2 |= MCOR2_DCD;
 		sreron |= SRER_MODEM;
 		portp->flags |= ASYNC_CHECK_CD;
-	} else {
+	} else
 		portp->flags &= ~ASYNC_CHECK_CD;
-	}
 
 /*
  *	Setup cd1400 enhanced modes if we can. In particular we want to
@@ -3382,18 +3024,16 @@ static void stl_cd1400setport(stlport_t *portp, struct termios *tiosp)
  *	them all up.
  */
 
-#ifdef DEBUG
-	printk("SETPORT: portnr=%d panelnr=%d brdnr=%d\n",
+	pr_debug("SETPORT: portnr=%d panelnr=%d brdnr=%d\n",
 		portp->portnr, portp->panelnr, portp->brdnr);
-	printk("    cor1=%x cor2=%x cor3=%x cor4=%x cor5=%x\n",
+	pr_debug("    cor1=%x cor2=%x cor3=%x cor4=%x cor5=%x\n",
 		cor1, cor2, cor3, cor4, cor5);
-	printk("    mcor1=%x mcor2=%x rtpr=%x sreron=%x sreroff=%x\n",
+	pr_debug("    mcor1=%x mcor2=%x rtpr=%x sreron=%x sreroff=%x\n",
 		mcor1, mcor2, rtpr, sreron, sreroff);
-	printk("    tcor=%x tbpr=%x rcor=%x rbpr=%x\n", clk, div, clk, div);
-	printk("    schr1=%x schr2=%x schr3=%x schr4=%x\n",
+	pr_debug("    tcor=%x tbpr=%x rcor=%x rbpr=%x\n", clk, div, clk, div);
+	pr_debug("    schr1=%x schr2=%x schr3=%x schr4=%x\n",
 		tiosp->c_cc[VSTART], tiosp->c_cc[VSTOP],
 		tiosp->c_cc[VSTART], tiosp->c_cc[VSTOP]);
-#endif
 
 	spin_lock_irqsave(&brd_lock, flags);
 	BRDENABLE(portp->brdnr, portp->pagenr);
@@ -3441,15 +3081,13 @@ static void stl_cd1400setport(stlport_t *portp, struct termios *tiosp)
  *	Set the state of the DTR and RTS signals.
  */
 
-static void stl_cd1400setsignals(stlport_t *portp, int dtr, int rts)
+static void stl_cd1400setsignals(struct stlport *portp, int dtr, int rts)
 {
 	unsigned char	msvr1, msvr2;
 	unsigned long	flags;
 
-#ifdef DEBUG
-	printk("stl_cd1400setsignals(portp=%x,dtr=%d,rts=%d)\n",
-		(int) portp, dtr, rts);
-#endif
+	pr_debug("stl_cd1400setsignals(portp=%p,dtr=%d,rts=%d)\n",
+			portp, dtr, rts);
 
 	msvr1 = 0;
 	msvr2 = 0;
@@ -3475,15 +3113,13 @@ static void stl_cd1400setsignals(stlport_t *portp, int dtr, int rts)
  *	Return the state of the signals.
  */
 
-static int stl_cd1400getsignals(stlport_t *portp)
+static int stl_cd1400getsignals(struct stlport *portp)
 {
 	unsigned char	msvr1, msvr2;
 	unsigned long	flags;
 	int		sigs;
 
-#ifdef DEBUG
-	printk("stl_cd1400getsignals(portp=%x)\n", (int) portp);
-#endif
+	pr_debug("stl_cd1400getsignals(portp=%p)\n", portp);
 
 	spin_lock_irqsave(&brd_lock, flags);
 	BRDENABLE(portp->brdnr, portp->pagenr);
@@ -3513,15 +3149,13 @@ static int stl_cd1400getsignals(stlport_t *portp)
  *	Enable/Disable the Transmitter and/or Receiver.
  */
 
-static void stl_cd1400enablerxtx(stlport_t *portp, int rx, int tx)
+static void stl_cd1400enablerxtx(struct stlport *portp, int rx, int tx)
 {
 	unsigned char	ccr;
 	unsigned long	flags;
 
-#ifdef DEBUG
-	printk("stl_cd1400enablerxtx(portp=%x,rx=%d,tx=%d)\n",
-		(int) portp, rx, tx);
-#endif
+	pr_debug("stl_cd1400enablerxtx(portp=%p,rx=%d,tx=%d)\n", portp, rx, tx);
+
 	ccr = 0;
 
 	if (tx == 0)
@@ -3549,15 +3183,12 @@ static void stl_cd1400enablerxtx(stlport_t *portp, int rx, int tx)
  *	Start/stop the Transmitter and/or Receiver.
  */
 
-static void stl_cd1400startrxtx(stlport_t *portp, int rx, int tx)
+static void stl_cd1400startrxtx(struct stlport *portp, int rx, int tx)
 {
 	unsigned char	sreron, sreroff;
 	unsigned long	flags;
 
-#ifdef DEBUG
-	printk("stl_cd1400startrxtx(portp=%x,rx=%d,tx=%d)\n",
-		(int) portp, rx, tx);
-#endif
+	pr_debug("stl_cd1400startrxtx(portp=%p,rx=%d,tx=%d)\n", portp, rx, tx);
 
 	sreron = 0;
 	sreroff = 0;
@@ -3589,13 +3220,12 @@ static void stl_cd1400startrxtx(stlport_t *portp, int rx, int tx)
  *	Disable all interrupts from this port.
  */
 
-static void stl_cd1400disableintrs(stlport_t *portp)
+static void stl_cd1400disableintrs(struct stlport *portp)
 {
 	unsigned long	flags;
 
-#ifdef DEBUG
-	printk("stl_cd1400disableintrs(portp=%x)\n", (int) portp);
-#endif
+	pr_debug("stl_cd1400disableintrs(portp=%p)\n", portp);
+
 	spin_lock_irqsave(&brd_lock, flags);
 	BRDENABLE(portp->brdnr, portp->pagenr);
 	stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03));
@@ -3606,13 +3236,11 @@ static void stl_cd1400disableintrs(stlport_t *portp)
 
 /*****************************************************************************/
 
-static void stl_cd1400sendbreak(stlport_t *portp, int len)
+static void stl_cd1400sendbreak(struct stlport *portp, int len)
 {
 	unsigned long	flags;
 
-#ifdef DEBUG
-	printk("stl_cd1400sendbreak(portp=%x,len=%d)\n", (int) portp, len);
-#endif
+	pr_debug("stl_cd1400sendbreak(portp=%p,len=%d)\n", portp, len);
 
 	spin_lock_irqsave(&brd_lock, flags);
 	BRDENABLE(portp->brdnr, portp->pagenr);
@@ -3633,19 +3261,17 @@ static void stl_cd1400sendbreak(stlport_t *portp, int len)
  *	Take flow control actions...
  */
 
-static void stl_cd1400flowctrl(stlport_t *portp, int state)
+static void stl_cd1400flowctrl(struct stlport *portp, int state)
 {
 	struct tty_struct	*tty;
 	unsigned long		flags;
 
-#ifdef DEBUG
-	printk("stl_cd1400flowctrl(portp=%x,state=%x)\n", (int) portp, state);
-#endif
+	pr_debug("stl_cd1400flowctrl(portp=%p,state=%x)\n", portp, state);
 
-	if (portp == (stlport_t *) NULL)
+	if (portp == NULL)
 		return;
 	tty = portp->tty;
-	if (tty == (struct tty_struct *) NULL)
+	if (tty == NULL)
 		return;
 
 	spin_lock_irqsave(&brd_lock, flags);
@@ -3697,19 +3323,17 @@ static void stl_cd1400flowctrl(stlport_t *portp, int state)
  *	Send a flow control character...
  */
 
-static void stl_cd1400sendflow(stlport_t *portp, int state)
+static void stl_cd1400sendflow(struct stlport *portp, int state)
 {
 	struct tty_struct	*tty;
 	unsigned long		flags;
 
-#ifdef DEBUG
-	printk("stl_cd1400sendflow(portp=%x,state=%x)\n", (int) portp, state);
-#endif
+	pr_debug("stl_cd1400sendflow(portp=%p,state=%x)\n", portp, state);
 
-	if (portp == (stlport_t *) NULL)
+	if (portp == NULL)
 		return;
 	tty = portp->tty;
-	if (tty == (struct tty_struct *) NULL)
+	if (tty == NULL)
 		return;
 
 	spin_lock_irqsave(&brd_lock, flags);
@@ -3732,15 +3356,13 @@ static void stl_cd1400sendflow(stlport_t *portp, int state)
 
 /*****************************************************************************/
 
-static void stl_cd1400flush(stlport_t *portp)
+static void stl_cd1400flush(struct stlport *portp)
 {
 	unsigned long	flags;
 
-#ifdef DEBUG
-	printk("stl_cd1400flush(portp=%x)\n", (int) portp);
-#endif
+	pr_debug("stl_cd1400flush(portp=%p)\n", portp);
 
-	if (portp == (stlport_t *) NULL)
+	if (portp == NULL)
 		return;
 
 	spin_lock_irqsave(&brd_lock, flags);
@@ -3763,13 +3385,11 @@ static void stl_cd1400flush(stlport_t *portp)
  *	maintains the busy port flag.
  */
 
-static int stl_cd1400datastate(stlport_t *portp)
+static int stl_cd1400datastate(struct stlport *portp)
 {
-#ifdef DEBUG
-	printk("stl_cd1400datastate(portp=%x)\n", (int) portp);
-#endif
+	pr_debug("stl_cd1400datastate(portp=%p)\n", portp);
 
-	if (portp == (stlport_t *) NULL)
+	if (portp == NULL)
 		return 0;
 
 	return test_bit(ASYI_TXBUSY, &portp->istate) ? 1 : 0;
@@ -3781,14 +3401,11 @@ static int stl_cd1400datastate(stlport_t *portp)
  *	Interrupt service routine for cd1400 EasyIO boards.
  */
 
-static void stl_cd1400eiointr(stlpanel_t *panelp, unsigned int iobase)
+static void stl_cd1400eiointr(struct stlpanel *panelp, unsigned int iobase)
 {
 	unsigned char	svrtype;
 
-#ifdef DEBUG
-	printk("stl_cd1400eiointr(panelp=%x,iobase=%x)\n",
-		(int) panelp, iobase);
-#endif
+	pr_debug("stl_cd1400eiointr(panelp=%p,iobase=%x)\n", panelp, iobase);
 
 	spin_lock(&brd_lock);
 	outb(SVRR, iobase);
@@ -3814,14 +3431,11 @@ static void stl_cd1400eiointr(stlpanel_t *panelp, unsigned int iobase)
  *	Interrupt service routine for cd1400 panels.
  */
 
-static void stl_cd1400echintr(stlpanel_t *panelp, unsigned int iobase)
+static void stl_cd1400echintr(struct stlpanel *panelp, unsigned int iobase)
 {
 	unsigned char	svrtype;
 
-#ifdef DEBUG
-	printk("stl_cd1400echintr(panelp=%x,iobase=%x)\n", (int) panelp,
-		iobase);
-#endif
+	pr_debug("stl_cd1400echintr(panelp=%p,iobase=%x)\n", panelp, iobase);
 
 	outb(SVRR, iobase);
 	svrtype = inb(iobase + EREG_DATA);
@@ -3843,7 +3457,7 @@ static void stl_cd1400echintr(stlpanel_t *panelp, unsigned int iobase)
  *	this is the only way to generate them on the cd1400.
  */
 
-static inline int stl_cd1400breakisr(stlport_t *portp, int ioaddr)
+static int stl_cd1400breakisr(struct stlport *portp, int ioaddr)
 {
 	if (portp->brklen == 1) {
 		outb((COR2 + portp->uartaddr), ioaddr);
@@ -3885,16 +3499,14 @@ static inline int stl_cd1400breakisr(stlport_t *portp, int ioaddr)
  *	be NULL if the buffer has been freed.
  */
 
-static void stl_cd1400txisr(stlpanel_t *panelp, int ioaddr)
+static void stl_cd1400txisr(struct stlpanel *panelp, int ioaddr)
 {
-	stlport_t	*portp;
+	struct stlport	*portp;
 	int		len, stlen;
 	char		*head, *tail;
 	unsigned char	ioack, srer;
 
-#ifdef DEBUG
-	printk("stl_cd1400txisr(panelp=%x,ioaddr=%x)\n", (int) panelp, ioaddr);
-#endif
+	pr_debug("stl_cd1400txisr(panelp=%p,ioaddr=%x)\n", panelp, ioaddr);
 
 	ioack = inb(ioaddr + EREG_TXACK);
 	if (((ioack & panelp->ackmask) != 0) ||
@@ -3933,9 +3545,9 @@ static void stl_cd1400txisr(stlpanel_t *panelp, int ioaddr)
 		}
 		outb(srer, (ioaddr + EREG_DATA));
 	} else {
-		len = MIN(len, CD1400_TXFIFOSIZE);
+		len = min(len, CD1400_TXFIFOSIZE);
 		portp->stats.txtotal += len;
-		stlen = MIN(len, ((portp->tx.buf + STL_TXBUFSIZE) - tail));
+		stlen = min(len, ((portp->tx.buf + STL_TXBUFSIZE) - tail));
 		outb((TDR + portp->uartaddr), ioaddr);
 		outsb((ioaddr + EREG_DATA), tail, stlen);
 		len -= stlen;
@@ -3966,17 +3578,15 @@ stl_txalldone:
  *	shutdown a port not in user context. Need to handle this case.
  */
 
-static void stl_cd1400rxisr(stlpanel_t *panelp, int ioaddr)
+static void stl_cd1400rxisr(struct stlpanel *panelp, int ioaddr)
 {
-	stlport_t		*portp;
+	struct stlport		*portp;
 	struct tty_struct	*tty;
 	unsigned int		ioack, len, buflen;
 	unsigned char		status;
 	char			ch;
 
-#ifdef DEBUG
-	printk("stl_cd1400rxisr(panelp=%x,ioaddr=%x)\n", (int) panelp, ioaddr);
-#endif
+	pr_debug("stl_cd1400rxisr(panelp=%p,ioaddr=%x)\n", panelp, ioaddr);
 
 	ioack = inb(ioaddr + EREG_RXACK);
 	if ((ioack & panelp->ackmask) != 0) {
@@ -3990,13 +3600,13 @@ static void stl_cd1400rxisr(stlpanel_t *panelp, int ioaddr)
 		outb((RDCR + portp->uartaddr), ioaddr);
 		len = inb(ioaddr + EREG_DATA);
 		if (tty == NULL || (buflen = tty_buffer_request_room(tty, len)) == 0) {
-			len = MIN(len, sizeof(stl_unwanted));
+			len = min(len, sizeof(stl_unwanted));
 			outb((RDSR + portp->uartaddr), ioaddr);
 			insb((ioaddr + EREG_DATA), &stl_unwanted[0], len);
 			portp->stats.rxlost += len;
 			portp->stats.rxtotal += len;
 		} else {
-			len = MIN(len, buflen);
+			len = min(len, buflen);
 			if (len > 0) {
 				unsigned char *ptr;
 				outb((RDSR + portp->uartaddr), ioaddr);
@@ -4033,18 +3643,16 @@ static void stl_cd1400rxisr(stlpanel_t *panelp, int ioaddr)
 						do_SAK(tty);
 						BRDENABLE(portp->brdnr, portp->pagenr);
 					}
-				} else if (status & ST_PARITY) {
+				} else if (status & ST_PARITY)
 					status = TTY_PARITY;
-				} else if (status & ST_FRAMING) {
+				else if (status & ST_FRAMING)
 					status = TTY_FRAME;
-				} else if(status & ST_OVERRUN) {
+				else if(status & ST_OVERRUN)
 					status = TTY_OVERRUN;
-				} else {
+				else
 					status = 0;
-				}
-			} else {
+			} else
 				status = 0;
-			}
 			tty_insert_flip_char(tty, ch, status);
 			tty_schedule_flip(tty);
 		}
@@ -4066,15 +3674,13 @@ stl_rxalldone:
  *	processing routine.
  */
 
-static void stl_cd1400mdmisr(stlpanel_t *panelp, int ioaddr)
+static void stl_cd1400mdmisr(struct stlpanel *panelp, int ioaddr)
 {
-	stlport_t	*portp;
+	struct stlport	*portp;
 	unsigned int	ioack;
 	unsigned char	misr;
 
-#ifdef DEBUG
-	printk("stl_cd1400mdmisr(panelp=%x)\n", (int) panelp);
-#endif
+	pr_debug("stl_cd1400mdmisr(panelp=%p)\n", panelp);
 
 	ioack = inb(ioaddr + EREG_MDACK);
 	if (((ioack & panelp->ackmask) != 0) ||
@@ -4106,19 +3712,19 @@ static void stl_cd1400mdmisr(stlpanel_t *panelp, int ioaddr)
  *	(Maybe should make this inline...)
  */
 
-static int stl_sc26198getreg(stlport_t *portp, int regnr)
+static int stl_sc26198getreg(struct stlport *portp, int regnr)
 {
 	outb((regnr | portp->uartaddr), (portp->ioaddr + XP_ADDR));
 	return inb(portp->ioaddr + XP_DATA);
 }
 
-static void stl_sc26198setreg(stlport_t *portp, int regnr, int value)
+static void stl_sc26198setreg(struct stlport *portp, int regnr, int value)
 {
 	outb((regnr | portp->uartaddr), (portp->ioaddr + XP_ADDR));
 	outb(value, (portp->ioaddr + XP_DATA));
 }
 
-static int stl_sc26198updatereg(stlport_t *portp, int regnr, int value)
+static int stl_sc26198updatereg(struct stlport *portp, int regnr, int value)
 {
 	outb((regnr | portp->uartaddr), (portp->ioaddr + XP_ADDR));
 	if (inb(portp->ioaddr + XP_DATA) != value) {
@@ -4134,14 +3740,14 @@ static int stl_sc26198updatereg(stlport_t *portp, int regnr, int value)
  *	Functions to get and set the sc26198 global registers.
  */
 
-static int stl_sc26198getglobreg(stlport_t *portp, int regnr)
+static int stl_sc26198getglobreg(struct stlport *portp, int regnr)
 {
 	outb(regnr, (portp->ioaddr + XP_ADDR));
 	return inb(portp->ioaddr + XP_DATA);
 }
 
 #if 0
-static void stl_sc26198setglobreg(stlport_t *portp, int regnr, int value)
+static void stl_sc26198setglobreg(struct stlport *portp, int regnr, int value)
 {
 	outb(regnr, (portp->ioaddr + XP_ADDR));
 	outb(value, (portp->ioaddr + XP_DATA));
@@ -4156,15 +3762,12 @@ static void stl_sc26198setglobreg(stlport_t *portp, int regnr, int value)
  *	identical when dealing with ports.
  */
 
-static int stl_sc26198panelinit(stlbrd_t *brdp, stlpanel_t *panelp)
+static int stl_sc26198panelinit(struct stlbrd *brdp, struct stlpanel *panelp)
 {
 	int	chipmask, i;
 	int	nrchips, ioaddr;
 
-#ifdef DEBUG
-	printk("stl_sc26198panelinit(brdp=%x,panelp=%x)\n",
-		(int) brdp, (int) panelp);
-#endif
+	pr_debug("stl_sc26198panelinit(brdp=%p,panelp=%p)\n", brdp, panelp);
 
 	BRDENABLE(panelp->brdnr, panelp->pagenr);
 
@@ -4176,7 +3779,7 @@ static int stl_sc26198panelinit(stlbrd_t *brdp, stlpanel_t *panelp)
 	if (brdp->brdtype == BRD_ECHPCI)
 		outb(panelp->pagenr, brdp->ioctrl);
 
-	for (i = 0; (i < nrchips); i++) {
+	for (i = 0; i < nrchips; i++) {
 		ioaddr = panelp->iobase + (i * 4); 
 		outb(SCCR, (ioaddr + XP_ADDR));
 		outb(CR_RESETALL, (ioaddr + XP_DATA));
@@ -4204,15 +3807,13 @@ static int stl_sc26198panelinit(stlbrd_t *brdp, stlpanel_t *panelp)
  *	Initialize hardware specific port registers.
  */
 
-static void stl_sc26198portinit(stlbrd_t *brdp, stlpanel_t *panelp, stlport_t *portp)
+static void stl_sc26198portinit(struct stlbrd *brdp, struct stlpanel *panelp, struct stlport *portp)
 {
-#ifdef DEBUG
-	printk("stl_sc26198portinit(brdp=%x,panelp=%x,portp=%x)\n",
-		(int) brdp, (int) panelp, (int) portp);
-#endif
+	pr_debug("stl_sc26198portinit(brdp=%p,panelp=%p,portp=%p)\n", brdp,
+			panelp, portp);
 
-	if ((brdp == (stlbrd_t *) NULL) || (panelp == (stlpanel_t *) NULL) ||
-	    (portp == (stlport_t *) NULL))
+	if ((brdp == NULL) || (panelp == NULL) ||
+	    (portp == NULL))
 		return;
 
 	portp->ioaddr = panelp->iobase + ((portp->portnr < 8) ? 0 : 4);
@@ -4232,9 +3833,9 @@ static void stl_sc26198portinit(stlbrd_t *brdp, stlpanel_t *panelp, stlport_t *p
  *	settings.
  */
 
-static void stl_sc26198setport(stlport_t *portp, struct termios *tiosp)
+static void stl_sc26198setport(struct stlport *portp, struct ktermios *tiosp)
 {
-	stlbrd_t	*brdp;
+	struct stlbrd	*brdp;
 	unsigned long	flags;
 	unsigned int	baudrate;
 	unsigned char	mr0, mr1, mr2, clk;
@@ -4249,7 +3850,7 @@ static void stl_sc26198setport(stlport_t *portp, struct termios *tiosp)
 	imroff = 0;
 
 	brdp = stl_brds[portp->brdnr];
-	if (brdp == (stlbrd_t *) NULL)
+	if (brdp == NULL)
 		return;
 
 /*
@@ -4298,9 +3899,8 @@ static void stl_sc26198setport(stlport_t *portp, struct termios *tiosp)
 			mr1 |= (MR1_PARENB | MR1_PARODD);
 		else
 			mr1 |= (MR1_PARENB | MR1_PAREVEN);
-	} else {
+	} else
 		mr1 |= MR1_PARNONE;
-	}
 
 	mr1 |= MR1_ERRBLOCK;
 
@@ -4340,12 +3940,10 @@ static void stl_sc26198setport(stlport_t *portp, struct termios *tiosp)
 	if (baudrate > STL_SC26198MAXBAUD)
 		baudrate = STL_SC26198MAXBAUD;
 
-	if (baudrate > 0) {
-		for (clk = 0; (clk < SC26198_NRBAUDS); clk++) {
+	if (baudrate > 0)
+		for (clk = 0; clk < SC26198_NRBAUDS; clk++)
 			if (baudrate <= sc26198_baudtable[clk])
 				break;
-		}
-	}
 
 /*
  *	Check what form of modem signaling is required and set it up.
@@ -4367,9 +3965,9 @@ static void stl_sc26198setport(stlport_t *portp, struct termios *tiosp)
 	if (tiosp->c_iflag & IXON) {
 		mr0 |= MR0_SWFTX | MR0_SWFT;
 		imron |= IR_XONXOFF;
-	} else {
+	} else
 		imroff |= IR_XONXOFF;
-	}
+
 	if (tiosp->c_iflag & IXOFF)
 		mr0 |= MR0_SWFRX;
 
@@ -4383,15 +3981,13 @@ static void stl_sc26198setport(stlport_t *portp, struct termios *tiosp)
  *	them all up.
  */
 
-#ifdef DEBUG
-	printk("SETPORT: portnr=%d panelnr=%d brdnr=%d\n",
+	pr_debug("SETPORT: portnr=%d panelnr=%d brdnr=%d\n",
 		portp->portnr, portp->panelnr, portp->brdnr);
-	printk("    mr0=%x mr1=%x mr2=%x clk=%x\n", mr0, mr1, mr2, clk);
-	printk("    iopr=%x imron=%x imroff=%x\n", iopr, imron, imroff);
-	printk("    schr1=%x schr2=%x schr3=%x schr4=%x\n",
+	pr_debug("    mr0=%x mr1=%x mr2=%x clk=%x\n", mr0, mr1, mr2, clk);
+	pr_debug("    iopr=%x imron=%x imroff=%x\n", iopr, imron, imroff);
+	pr_debug("    schr1=%x schr2=%x schr3=%x schr4=%x\n",
 		tiosp->c_cc[VSTART], tiosp->c_cc[VSTOP],
 		tiosp->c_cc[VSTART], tiosp->c_cc[VSTOP]);
-#endif
 
 	spin_lock_irqsave(&brd_lock, flags);
 	BRDENABLE(portp->brdnr, portp->pagenr);
@@ -4429,15 +4025,13 @@ static void stl_sc26198setport(stlport_t *portp, struct termios *tiosp)
  *	Set the state of the DTR and RTS signals.
  */
 
-static void stl_sc26198setsignals(stlport_t *portp, int dtr, int rts)
+static void stl_sc26198setsignals(struct stlport *portp, int dtr, int rts)
 {
 	unsigned char	iopioron, iopioroff;
 	unsigned long	flags;
 
-#ifdef DEBUG
-	printk("stl_sc26198setsignals(portp=%x,dtr=%d,rts=%d)\n",
-		(int) portp, dtr, rts);
-#endif
+	pr_debug("stl_sc26198setsignals(portp=%p,dtr=%d,rts=%d)\n", portp,
+			dtr, rts);
 
 	iopioron = 0;
 	iopioroff = 0;
@@ -4464,15 +4058,13 @@ static void stl_sc26198setsignals(stlport_t *portp, int dtr, int rts)
  *	Return the state of the signals.
  */
 
-static int stl_sc26198getsignals(stlport_t *portp)
+static int stl_sc26198getsignals(struct stlport *portp)
 {
 	unsigned char	ipr;
 	unsigned long	flags;
 	int		sigs;
 
-#ifdef DEBUG
-	printk("stl_sc26198getsignals(portp=%x)\n", (int) portp);
-#endif
+	pr_debug("stl_sc26198getsignals(portp=%p)\n", portp);
 
 	spin_lock_irqsave(&brd_lock, flags);
 	BRDENABLE(portp->brdnr, portp->pagenr);
@@ -4495,15 +4087,12 @@ static int stl_sc26198getsignals(stlport_t *portp)
  *	Enable/Disable the Transmitter and/or Receiver.
  */
 
-static void stl_sc26198enablerxtx(stlport_t *portp, int rx, int tx)
+static void stl_sc26198enablerxtx(struct stlport *portp, int rx, int tx)
 {
 	unsigned char	ccr;
 	unsigned long	flags;
 
-#ifdef DEBUG
-	printk("stl_sc26198enablerxtx(portp=%x,rx=%d,tx=%d)\n",
-		(int) portp, rx, tx);
-#endif
+	pr_debug("stl_sc26198enablerxtx(portp=%p,rx=%d,tx=%d)\n", portp, rx,tx);
 
 	ccr = portp->crenable;
 	if (tx == 0)
@@ -4529,15 +4118,12 @@ static void stl_sc26198enablerxtx(stlport_t *portp, int rx, int tx)
  *	Start/stop the Transmitter and/or Receiver.
  */
 
-static void stl_sc26198startrxtx(stlport_t *portp, int rx, int tx)
+static void stl_sc26198startrxtx(struct stlport *portp, int rx, int tx)
 {
 	unsigned char	imr;
 	unsigned long	flags;
 
-#ifdef DEBUG
-	printk("stl_sc26198startrxtx(portp=%x,rx=%d,tx=%d)\n",
-		(int) portp, rx, tx);
-#endif
+	pr_debug("stl_sc26198startrxtx(portp=%p,rx=%d,tx=%d)\n", portp, rx, tx);
 
 	imr = portp->imr;
 	if (tx == 0)
@@ -4565,13 +4151,11 @@ static void stl_sc26198startrxtx(stlport_t *portp, int rx, int tx)
  *	Disable all interrupts from this port.
  */
 
-static void stl_sc26198disableintrs(stlport_t *portp)
+static void stl_sc26198disableintrs(struct stlport *portp)
 {
 	unsigned long	flags;
 
-#ifdef DEBUG
-	printk("stl_sc26198disableintrs(portp=%x)\n", (int) portp);
-#endif
+	pr_debug("stl_sc26198disableintrs(portp=%p)\n", portp);
 
 	spin_lock_irqsave(&brd_lock, flags);
 	BRDENABLE(portp->brdnr, portp->pagenr);
@@ -4583,22 +4167,20 @@ static void stl_sc26198disableintrs(stlport_t *portp)
 
 /*****************************************************************************/
 
-static void stl_sc26198sendbreak(stlport_t *portp, int len)
+static void stl_sc26198sendbreak(struct stlport *portp, int len)
 {
 	unsigned long	flags;
 
-#ifdef DEBUG
-	printk("stl_sc26198sendbreak(portp=%x,len=%d)\n", (int) portp, len);
-#endif
+	pr_debug("stl_sc26198sendbreak(portp=%p,len=%d)\n", portp, len);
 
 	spin_lock_irqsave(&brd_lock, flags);
 	BRDENABLE(portp->brdnr, portp->pagenr);
 	if (len == 1) {
 		stl_sc26198setreg(portp, SCCR, CR_TXSTARTBREAK);
 		portp->stats.txbreaks++;
-	} else {
+	} else
 		stl_sc26198setreg(portp, SCCR, CR_TXSTOPBREAK);
-	}
+
 	BRDDISABLE(portp->brdnr);
 	spin_unlock_irqrestore(&brd_lock, flags);
 }
@@ -4609,20 +4191,18 @@ static void stl_sc26198sendbreak(stlport_t *portp, int len)
  *	Take flow control actions...
  */
 
-static void stl_sc26198flowctrl(stlport_t *portp, int state)
+static void stl_sc26198flowctrl(struct stlport *portp, int state)
 {
 	struct tty_struct	*tty;
 	unsigned long		flags;
 	unsigned char		mr0;
 
-#ifdef DEBUG
-	printk("stl_sc26198flowctrl(portp=%x,state=%x)\n", (int) portp, state);
-#endif
+	pr_debug("stl_sc26198flowctrl(portp=%p,state=%x)\n", portp, state);
 
-	if (portp == (stlport_t *) NULL)
+	if (portp == NULL)
 		return;
 	tty = portp->tty;
-	if (tty == (struct tty_struct *) NULL)
+	if (tty == NULL)
 		return;
 
 	spin_lock_irqsave(&brd_lock, flags);
@@ -4680,20 +4260,18 @@ static void stl_sc26198flowctrl(stlport_t *portp, int state)
  *	Send a flow control character.
  */
 
-static void stl_sc26198sendflow(stlport_t *portp, int state)
+static void stl_sc26198sendflow(struct stlport *portp, int state)
 {
 	struct tty_struct	*tty;
 	unsigned long		flags;
 	unsigned char		mr0;
 
-#ifdef DEBUG
-	printk("stl_sc26198sendflow(portp=%x,state=%x)\n", (int) portp, state);
-#endif
+	pr_debug("stl_sc26198sendflow(portp=%p,state=%x)\n", portp, state);
 
-	if (portp == (stlport_t *) NULL)
+	if (portp == NULL)
 		return;
 	tty = portp->tty;
-	if (tty == (struct tty_struct *) NULL)
+	if (tty == NULL)
 		return;
 
 	spin_lock_irqsave(&brd_lock, flags);
@@ -4721,15 +4299,13 @@ static void stl_sc26198sendflow(stlport_t *portp, int state)
 
 /*****************************************************************************/
 
-static void stl_sc26198flush(stlport_t *portp)
+static void stl_sc26198flush(struct stlport *portp)
 {
 	unsigned long	flags;
 
-#ifdef DEBUG
-	printk("stl_sc26198flush(portp=%x)\n", (int) portp);
-#endif
+	pr_debug("stl_sc26198flush(portp=%p)\n", portp);
 
-	if (portp == (stlport_t *) NULL)
+	if (portp == NULL)
 		return;
 
 	spin_lock_irqsave(&brd_lock, flags);
@@ -4751,16 +4327,14 @@ static void stl_sc26198flush(stlport_t *portp)
  *	check the port statusy register to be sure.
  */
 
-static int stl_sc26198datastate(stlport_t *portp)
+static int stl_sc26198datastate(struct stlport *portp)
 {
 	unsigned long	flags;
 	unsigned char	sr;
 
-#ifdef DEBUG
-	printk("stl_sc26198datastate(portp=%x)\n", (int) portp);
-#endif
+	pr_debug("stl_sc26198datastate(portp=%p)\n", portp);
 
-	if (portp == (stlport_t *) NULL)
+	if (portp == NULL)
 		return 0;
 	if (test_bit(ASYI_TXBUSY, &portp->istate))
 		return 1;
@@ -4781,18 +4355,16 @@ static int stl_sc26198datastate(stlport_t *portp)
  *	to process a command...
  */
 
-static void stl_sc26198wait(stlport_t *portp)
+static void stl_sc26198wait(struct stlport *portp)
 {
 	int	i;
 
-#ifdef DEBUG
-	printk("stl_sc26198wait(portp=%x)\n", (int) portp);
-#endif
+	pr_debug("stl_sc26198wait(portp=%p)\n", portp);
 
-	if (portp == (stlport_t *) NULL)
+	if (portp == NULL)
 		return;
 
-	for (i = 0; (i < 20); i++)
+	for (i = 0; i < 20; i++)
 		stl_sc26198getglobreg(portp, TSTR);
 }
 
@@ -4804,7 +4376,7 @@ static void stl_sc26198wait(stlport_t *portp)
  *	automatic flow control modes of the sc26198.
  */
 
-static inline void stl_sc26198txunflow(stlport_t *portp, struct tty_struct *tty)
+static void stl_sc26198txunflow(struct stlport *portp, struct tty_struct *tty)
 {
 	unsigned char	mr0;
 
@@ -4822,9 +4394,9 @@ static inline void stl_sc26198txunflow(stlport_t *portp, struct tty_struct *tty)
  *	Interrupt service routine for sc26198 panels.
  */
 
-static void stl_sc26198intr(stlpanel_t *panelp, unsigned int iobase)
+static void stl_sc26198intr(struct stlpanel *panelp, unsigned int iobase)
 {
-	stlport_t	*portp;
+	struct stlport	*portp;
 	unsigned int	iack;
 
 	spin_lock(&brd_lock);
@@ -4860,16 +4432,14 @@ static void stl_sc26198intr(stlpanel_t *panelp, unsigned int iobase)
  *	be NULL if the buffer has been freed.
  */
 
-static void stl_sc26198txisr(stlport_t *portp)
+static void stl_sc26198txisr(struct stlport *portp)
 {
 	unsigned int	ioaddr;
 	unsigned char	mr0;
 	int		len, stlen;
 	char		*head, *tail;
 
-#ifdef DEBUG
-	printk("stl_sc26198txisr(portp=%x)\n", (int) portp);
-#endif
+	pr_debug("stl_sc26198txisr(portp=%p)\n", portp);
 
 	ioaddr = portp->ioaddr;
 	head = portp->tx.head;
@@ -4894,9 +4464,9 @@ static void stl_sc26198txisr(stlport_t *portp)
 			outb(mr0, (ioaddr + XP_DATA));
 		}
 	} else {
-		len = MIN(len, SC26198_TXFIFOSIZE);
+		len = min(len, SC26198_TXFIFOSIZE);
 		portp->stats.txtotal += len;
-		stlen = MIN(len, ((portp->tx.buf + STL_TXBUFSIZE) - tail));
+		stlen = min(len, ((portp->tx.buf + STL_TXBUFSIZE) - tail));
 		outb(GTXFIFO, (ioaddr + XP_ADDR));
 		outsb((ioaddr + XP_DATA), tail, stlen);
 		len -= stlen;
@@ -4923,14 +4493,12 @@ static void stl_sc26198txisr(stlport_t *portp)
  *	shutdown a port not in user context. Need to handle this case.
  */
 
-static void stl_sc26198rxisr(stlport_t *portp, unsigned int iack)
+static void stl_sc26198rxisr(struct stlport *portp, unsigned int iack)
 {
 	struct tty_struct	*tty;
 	unsigned int		len, buflen, ioaddr;
 
-#ifdef DEBUG
-	printk("stl_sc26198rxisr(portp=%x,iack=%x)\n", (int) portp, iack);
-#endif
+	pr_debug("stl_sc26198rxisr(portp=%p,iack=%x)\n", portp, iack);
 
 	tty = portp->tty;
 	ioaddr = portp->ioaddr;
@@ -4939,13 +4507,13 @@ static void stl_sc26198rxisr(stlport_t *portp, unsigned int iack)
 
 	if ((iack & IVR_TYPEMASK) == IVR_RXDATA) {
 		if (tty == NULL || (buflen = tty_buffer_request_room(tty, len)) == 0) {
-			len = MIN(len, sizeof(stl_unwanted));
+			len = min(len, sizeof(stl_unwanted));
 			outb(GRXFIFO, (ioaddr + XP_ADDR));
 			insb((ioaddr + XP_DATA), &stl_unwanted[0], len);
 			portp->stats.rxlost += len;
 			portp->stats.rxtotal += len;
 		} else {
-			len = MIN(len, buflen);
+			len = min(len, buflen);
 			if (len > 0) {
 				unsigned char *ptr;
 				outb(GRXFIFO, (ioaddr + XP_ADDR));
@@ -4965,8 +4533,8 @@ static void stl_sc26198rxisr(stlport_t *portp, unsigned int iack)
  *	flow control modes of the sc26198.
  */
 	if (test_bit(ASYI_TXFLOWED, &portp->istate)) {
-		if ((tty != (struct tty_struct *) NULL) &&
-		    (tty->termios != (struct termios *) NULL) &&
+		if ((tty != NULL) &&
+		    (tty->termios != NULL) &&
 		    (tty->termios->c_iflag & IXANY)) {
 			stl_sc26198txunflow(portp, tty);
 		}
@@ -4979,7 +4547,7 @@ static void stl_sc26198rxisr(stlport_t *portp, unsigned int iack)
  *	Process an RX bad character.
  */
 
-static inline void stl_sc26198rxbadch(stlport_t *portp, unsigned char status, char ch)
+static void stl_sc26198rxbadch(struct stlport *portp, unsigned char status, char ch)
 {
 	struct tty_struct	*tty;
 	unsigned int		ioaddr;
@@ -4996,7 +4564,7 @@ static inline void stl_sc26198rxbadch(stlport_t *portp, unsigned char status, ch
 	if (status & SR_RXBREAK)
 		portp->stats.rxbreaks++;
 
-	if ((tty != (struct tty_struct *) NULL) &&
+	if ((tty != NULL) &&
 	    ((portp->rxignoremsk & status) == 0)) {
 		if (portp->rxmarkmsk & status) {
 			if (status & SR_RXBREAK) {
@@ -5005,18 +4573,16 @@ static inline void stl_sc26198rxbadch(stlport_t *portp, unsigned char status, ch
 					do_SAK(tty);
 					BRDENABLE(portp->brdnr, portp->pagenr);
 				}
-			} else if (status & SR_RXPARITY) {
+			} else if (status & SR_RXPARITY)
 				status = TTY_PARITY;
-			} else if (status & SR_RXFRAMING) {
+			else if (status & SR_RXFRAMING)
 				status = TTY_FRAME;
-			} else if(status & SR_RXOVERRUN) {
+			else if(status & SR_RXOVERRUN)
 				status = TTY_OVERRUN;
-			} else {
+			else
 				status = 0;
-			}
-		} else {
+		} else
 			status = 0;
-		}
 
 		tty_insert_flip_char(tty, ch, status);
 		tty_schedule_flip(tty);
@@ -5037,7 +4603,7 @@ static inline void stl_sc26198rxbadch(stlport_t *portp, unsigned char status, ch
  *	the FIFO).
  */
 
-static void stl_sc26198rxbadchars(stlport_t *portp)
+static void stl_sc26198rxbadchars(struct stlport *portp)
 {
 	unsigned char	status, mr1;
 	char		ch;
@@ -5070,13 +4636,11 @@ static void stl_sc26198rxbadchars(stlport_t *portp)
  *	processing time.
  */
 
-static void stl_sc26198otherisr(stlport_t *portp, unsigned int iack)
+static void stl_sc26198otherisr(struct stlport *portp, unsigned int iack)
 {
 	unsigned char	cir, ipr, xisr;
 
-#ifdef DEBUG
-	printk("stl_sc26198otherisr(portp=%x,iack=%x)\n", (int) portp, iack);
-#endif
+	pr_debug("stl_sc26198otherisr(portp=%p,iack=%x)\n", portp, iack);
 
 	cir = stl_sc26198getglobreg(portp, CIR);
 
@@ -5109,4 +4673,172 @@ static void stl_sc26198otherisr(stlport_t *portp, unsigned int iack)
 	}
 }
 
-/*****************************************************************************/
+static void stl_free_isabrds(void)
+{
+	struct stlbrd *brdp;
+	unsigned int i;
+
+	for (i = 0; i < stl_nrbrds; i++) {
+		if ((brdp = stl_brds[i]) == NULL || (brdp->state & STL_PROBED))
+			continue;
+
+		free_irq(brdp->irq, brdp);
+
+		stl_cleanup_panels(brdp);
+
+		release_region(brdp->ioaddr1, brdp->iosize1);
+		if (brdp->iosize2 > 0)
+			release_region(brdp->ioaddr2, brdp->iosize2);
+
+		kfree(brdp);
+		stl_brds[i] = NULL;
+	}
+}
+
+/*
+ *	Loadable module initialization stuff.
+ */
+static int __init stallion_module_init(void)
+{
+	struct stlbrd	*brdp;
+	struct stlconf	conf;
+	unsigned int i, j;
+	int retval;
+
+	printk(KERN_INFO "%s: version %s\n", stl_drvtitle, stl_drvversion);
+
+	spin_lock_init(&stallion_lock);
+	spin_lock_init(&brd_lock);
+
+/*
+ *	Find any dynamically supported boards. That is via module load
+ *	line options.
+ */
+	for (i = stl_nrbrds; i < stl_nargs; i++) {
+		memset(&conf, 0, sizeof(conf));
+		if (stl_parsebrd(&conf, stl_brdsp[i]) == 0)
+			continue;
+		if ((brdp = stl_allocbrd()) == NULL)
+			continue;
+		brdp->brdnr = i;
+		brdp->brdtype = conf.brdtype;
+		brdp->ioaddr1 = conf.ioaddr1;
+		brdp->ioaddr2 = conf.ioaddr2;
+		brdp->irq = conf.irq;
+		brdp->irqtype = conf.irqtype;
+		if (stl_brdinit(brdp))
+			kfree(brdp);
+		else {
+			for (j = 0; j < brdp->nrports; j++)
+				tty_register_device(stl_serial,
+					brdp->brdnr * STL_MAXPORTS + j, NULL);
+			stl_brds[brdp->brdnr] = brdp;
+			stl_nrbrds = i + 1;
+		}
+	}
+
+	/* this has to be _after_ isa finding because of locking */
+	retval = pci_register_driver(&stl_pcidriver);
+	if (retval && stl_nrbrds == 0)
+		goto err;
+
+	stl_serial = alloc_tty_driver(STL_MAXBRDS * STL_MAXPORTS);
+	if (!stl_serial) {
+		retval = -ENOMEM;
+		goto err_pcidr;
+	}
+
+/*
+ *	Set up a character driver for per board stuff. This is mainly used
+ *	to do stats ioctls on the ports.
+ */
+	if (register_chrdev(STL_SIOMEMMAJOR, "staliomem", &stl_fsiomem))
+		printk("STALLION: failed to register serial board device\n");
+
+	stallion_class = class_create(THIS_MODULE, "staliomem");
+	if (IS_ERR(stallion_class)) {
+		retval = PTR_ERR(stallion_class);
+		goto err_reg;
+	}
+	for (i = 0; i < 4; i++)
+		class_device_create(stallion_class, NULL,
+				    MKDEV(STL_SIOMEMMAJOR, i), NULL,
+				    "staliomem%d", i);
+
+	stl_serial->owner = THIS_MODULE;
+	stl_serial->driver_name = stl_drvname;
+	stl_serial->name = "ttyE";
+	stl_serial->major = STL_SERIALMAJOR;
+	stl_serial->minor_start = 0;
+	stl_serial->type = TTY_DRIVER_TYPE_SERIAL;
+	stl_serial->subtype = SERIAL_TYPE_NORMAL;
+	stl_serial->init_termios = stl_deftermios;
+	stl_serial->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
+	tty_set_operations(stl_serial, &stl_ops);
+
+	retval = tty_register_driver(stl_serial);
+	if (retval) {
+		printk("STALLION: failed to register serial driver\n");
+		goto err_clsdev;
+	}
+
+	return 0;
+err_clsdev:
+	for (i = 0; i < 4; i++)
+		class_device_destroy(stallion_class, MKDEV(STL_SIOMEMMAJOR, i));
+	class_destroy(stallion_class);
+err_reg:
+	unregister_chrdev(STL_SIOMEMMAJOR, "staliomem");
+	put_tty_driver(stl_serial);
+err_pcidr:
+	pci_unregister_driver(&stl_pcidriver);
+	stl_free_isabrds();
+err:
+	return retval;
+}
+
+static void __exit stallion_module_exit(void)
+{
+	struct stlbrd *brdp;
+	unsigned int i, j;
+	int retval;
+
+	pr_debug("cleanup_module()\n");
+
+	printk(KERN_INFO "Unloading %s: version %s\n", stl_drvtitle,
+		stl_drvversion);
+
+/*
+ *	Free up all allocated resources used by the ports. This includes
+ *	memory and interrupts. As part of this process we will also do
+ *	a hangup on every open port - to try to flush out any processes
+ *	hanging onto ports.
+ */
+	for (i = 0; i < stl_nrbrds; i++) {
+		if ((brdp = stl_brds[i]) == NULL || (brdp->state & STL_PROBED))
+			continue;
+		for (j = 0; j < brdp->nrports; j++)
+			tty_unregister_device(stl_serial,
+				brdp->brdnr * STL_MAXPORTS + j);
+	}
+	tty_unregister_driver(stl_serial);
+	put_tty_driver(stl_serial);
+
+	for (i = 0; i < 4; i++)
+		class_device_destroy(stallion_class, MKDEV(STL_SIOMEMMAJOR, i));
+	if ((retval = unregister_chrdev(STL_SIOMEMMAJOR, "staliomem")))
+		printk("STALLION: failed to un-register serial memory device, "
+			"errno=%d\n", -retval);
+	class_destroy(stallion_class);
+
+	pci_unregister_driver(&stl_pcidriver);
+
+	stl_free_isabrds();
+}
+
+module_init(stallion_module_init);
+module_exit(stallion_module_exit);
+
+MODULE_AUTHOR("Greg Ungerer");
+MODULE_DESCRIPTION("Stallion Multiport Serial Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/char/sx.c b/drivers/char/sx.c
index cc10af08cb05..a3008ce13015 100644
--- a/drivers/char/sx.c
+++ b/drivers/char/sx.c
@@ -32,7 +32,6 @@
  *      USA.
  *
  * Revision history:
- * $Log: sx.c,v $
  * Revision 1.33  2000/03/09 10:00:00  pvdl,wolff
  * - Fixed module and port counting
  * - Fixed signal handling
@@ -199,9 +198,7 @@
  *
  * */
 
-
-#define RCS_ID "$Id: sx.c,v 1.33 2000/03/08 10:01:02 wolff, pvdl Exp $"
-#define RCS_REV "$Revision: 1.33 $"
+#define SX_VERSION	1.33
 
 #include <linux/module.h>
 #include <linux/kdev_t.h>
@@ -217,6 +214,7 @@
 #include <linux/fcntl.h>
 #include <linux/major.h>
 #include <linux/delay.h>
+#include <linux/eisa.h>
 #include <linux/pci.h>
 #include <linux/slab.h>
 #include <linux/init.h>
@@ -240,7 +238,6 @@
 #include <linux/generic_serial.h>
 #include "sx.h"
 
-
 /* I don't think that this driver can handle more than 256 ports on
    one machine. You'll have to increase the number of boards in sx.h
    if you want more than 4 boards.  */
@@ -249,21 +246,12 @@
 #define PCI_DEVICE_ID_SPECIALIX_SX_XIO_IO8 0x2000
 #endif
 
-#ifdef CONFIG_PCI
-static struct pci_device_id sx_pci_tbl[] = {
-	{ PCI_VENDOR_ID_SPECIALIX, PCI_DEVICE_ID_SPECIALIX_SX_XIO_IO8, PCI_ANY_ID, PCI_ANY_ID },
-	{ 0 }
-};
-MODULE_DEVICE_TABLE(pci, sx_pci_tbl);
-#endif /* CONFIG_PCI */
-
 /* Configurable options: 
    (Don't be too sure that it'll work if you toggle them) */
 
 /* Am I paranoid or not ? ;-) */
 #undef SX_PARANOIA_CHECK
 
-
 /* 20 -> 2000 per second. The card should rate-limit interrupts at 100
    Hz, but it is user configurable. I don't recommend going above 1000
    Hz. The interrupt ratelimit might trigger if the interrupt is
@@ -277,7 +265,6 @@ MODULE_DEVICE_TABLE(pci, sx_pci_tbl);
    interrupt. Use polling. */
 #undef IRQ_RATE_LIMIT
 
-
 #if 0
 /* Not implemented */
 /* 
@@ -286,35 +273,33 @@ MODULE_DEVICE_TABLE(pci, sx_pci_tbl);
  */
 #define SX_REPORT_FIFO
 #define SX_REPORT_OVERRUN
-#endif 
-
+#endif
 
 /* Function prototypes */
-static void sx_disable_tx_interrupts (void * ptr); 
-static void sx_enable_tx_interrupts (void * ptr); 
-static void sx_disable_rx_interrupts (void * ptr); 
-static void sx_enable_rx_interrupts (void * ptr); 
-static int  sx_get_CD (void * ptr); 
-static void sx_shutdown_port (void * ptr);
-static int  sx_set_real_termios (void  *ptr);
-static void sx_close (void  *ptr);
-static int sx_chars_in_buffer (void * ptr);
-static int sx_init_board (struct sx_board *board);
-static int sx_init_portstructs (int nboards, int nports);
-static int sx_fw_ioctl (struct inode *inode, struct file *filp,
-                        unsigned int cmd, unsigned long arg);
+static void sx_disable_tx_interrupts(void *ptr);
+static void sx_enable_tx_interrupts(void *ptr);
+static void sx_disable_rx_interrupts(void *ptr);
+static void sx_enable_rx_interrupts(void *ptr);
+static int sx_get_CD(void *ptr);
+static void sx_shutdown_port(void *ptr);
+static int sx_set_real_termios(void *ptr);
+static void sx_close(void *ptr);
+static int sx_chars_in_buffer(void *ptr);
+static int sx_init_board(struct sx_board *board);
+static int sx_init_portstructs(int nboards, int nports);
+static int sx_fw_ioctl(struct inode *inode, struct file *filp,
+		unsigned int cmd, unsigned long arg);
 static int sx_init_drivers(void);
 
-
 static struct tty_driver *sx_driver;
 
+static DEFINE_MUTEX(sx_boards_lock);
 static struct sx_board boards[SX_NBOARDS];
 static struct sx_port *sx_ports;
 static int sx_initialized;
 static int sx_nports;
 static int sx_debug;
 
-
 /* You can have the driver poll your card. 
     - Set sx_poll to 1 to poll every timer tick (10ms on Intel). 
       This is used when the card cannot use an interrupt for some reason.
@@ -333,27 +318,36 @@ static int sx_slowpoll;
 
 static int sx_maxints = 100;
 
+#ifdef CONFIG_ISA
+
 /* These are the only open spaces in my computer. Yours may have more
    or less.... -- REW 
    duh: Card at 0xa0000 is possible on HP Netserver?? -- pvdl
 */
-static int sx_probe_addrs[]= {0xc0000, 0xd0000, 0xe0000, 
-                              0xc8000, 0xd8000, 0xe8000};
-static int si_probe_addrs[]= {0xc0000, 0xd0000, 0xe0000, 
-                              0xc8000, 0xd8000, 0xe8000, 0xa0000};
-static int si1_probe_addrs[]= { 0xd0000};
+static int sx_probe_addrs[] = {
+	0xc0000, 0xd0000, 0xe0000,
+	0xc8000, 0xd8000, 0xe8000
+};
+static int si_probe_addrs[] = {
+	0xc0000, 0xd0000, 0xe0000,
+	0xc8000, 0xd8000, 0xe8000, 0xa0000
+};
+static int si1_probe_addrs[] = {
+	0xd0000
+};
 
 #define NR_SX_ADDRS ARRAY_SIZE(sx_probe_addrs)
 #define NR_SI_ADDRS ARRAY_SIZE(si_probe_addrs)
 #define NR_SI1_ADDRS ARRAY_SIZE(si1_probe_addrs)
 
+module_param_array(sx_probe_addrs, int, NULL, 0);
+module_param_array(si_probe_addrs, int, NULL, 0);
+#endif
 
 /* Set the mask to all-ones. This alas, only supports 32 interrupts. 
    Some architectures may need more. */
 static int sx_irqmask = -1;
 
-module_param_array(sx_probe_addrs, int, NULL, 0);
-module_param_array(si_probe_addrs, int, NULL, 0);
 module_param(sx_poll, int, 0);
 module_param(sx_slowpoll, int, 0);
 module_param(sx_maxints, int, 0);
@@ -368,13 +362,12 @@ static struct real_driver sx_real_driver = {
 	sx_disable_rx_interrupts,
 	sx_enable_rx_interrupts,
 	sx_get_CD,
-	sx_shutdown_port, 
-	sx_set_real_termios, 
+	sx_shutdown_port,
+	sx_set_real_termios,
 	sx_chars_in_buffer,
 	sx_close,
 };
 
-
 /* 
    This driver can spew a whole lot of debugging output at you. If you
    need maximum performance, you should disable the DEBUG define. To
@@ -385,23 +378,17 @@ static struct real_driver sx_real_driver = {
 */
 #define DEBUG
 
-
 #ifdef DEBUG
-#define sx_dprintk(f, str...) if (sx_debug & f) printk (str)
+#define sx_dprintk(f, str...)	if (sx_debug & f) printk (str)
 #else
-#define sx_dprintk(f, str...) /* nothing */
+#define sx_dprintk(f, str...)	/* nothing */
 #endif
 
+#define func_enter()	sx_dprintk(SX_DEBUG_FLOW, "sx: enter %s\n",__FUNCTION__)
+#define func_exit()	sx_dprintk(SX_DEBUG_FLOW, "sx: exit  %s\n",__FUNCTION__)
 
-
-#define func_enter() sx_dprintk (SX_DEBUG_FLOW, "sx: enter %s\n",__FUNCTION__)
-#define func_exit()  sx_dprintk (SX_DEBUG_FLOW, "sx: exit  %s\n", __FUNCTION__)
-
-#define func_enter2() sx_dprintk (SX_DEBUG_FLOW, "sx: enter %s (port %d)\n", \
-					__FUNCTION__, port->line)
-
-
-
+#define func_enter2()	sx_dprintk(SX_DEBUG_FLOW, "sx: enter %s (port %d)\n", \
+				__FUNCTION__, port->line)
 
 /* 
  *  Firmware loader driver specific routines
@@ -409,31 +396,26 @@ static struct real_driver sx_real_driver = {
  */
 
 static const struct file_operations sx_fw_fops = {
-	.owner		= THIS_MODULE,
-	.ioctl		= sx_fw_ioctl,
+	.owner = THIS_MODULE,
+	.ioctl = sx_fw_ioctl,
 };
 
 static struct miscdevice sx_fw_device = {
 	SXCTL_MISC_MINOR, "sxctl", &sx_fw_fops
 };
 
-
-
-
-
 #ifdef SX_PARANOIA_CHECK
 
 /* This doesn't work. Who's paranoid around here? Not me! */
 
-static inline int sx_paranoia_check(struct sx_port const * port,
+static inline int sx_paranoia_check(struct sx_port const *port,
 				    char *name, const char *routine)
 {
+	static const char *badmagic = KERN_ERR "sx: Warning: bad sx port magic "
+			"number for device %s in %s\n";
+	static const char *badinfo = KERN_ERR "sx: Warning: null sx port for "
+			"device %s in %s\n";
 
-	static const char *badmagic =
-	  KERN_ERR "sx: Warning: bad sx port magic number for device %s in %s\n";
-	static const char *badinfo =
-	  KERN_ERR "sx: Warning: null sx port for device %s in %s\n";
- 
 	if (!port) {
 		printk(badinfo, name, routine);
 		return 1;
@@ -456,23 +438,24 @@ static inline int sx_paranoia_check(struct sx_port const * port,
 #define TIMEOUT_1 30
 #define TIMEOUT_2 1000000
 
-
 #ifdef DEBUG
 static void my_hd_io(void __iomem *p, int len)
 {
 	int i, j, ch;
 	unsigned char __iomem *addr = p;
 
-	for (i=0;i<len;i+=16) {
-		printk ("%p ", addr+i);
-		for (j=0;j<16;j++) {
-			printk ("%02x %s", readb(addr+j+i), (j==7)?" ":"");
+	for (i = 0; i < len; i += 16) {
+		printk("%p ", addr + i);
+		for (j = 0; j < 16; j++) {
+			printk("%02x %s", readb(addr + j + i),
+					(j == 7) ? " " : "");
 		}
-		for (j=0;j<16;j++) {
-			ch = readb(addr+j+i);
-			printk ("%c", (ch < 0x20)?'.':((ch > 0x7f)?'.':ch));
+		for (j = 0; j < 16; j++) {
+			ch = readb(addr + j + i);
+			printk("%c", (ch < 0x20) ? '.' :
+					((ch > 0x7f) ? '.' : ch));
 		}
-		printk ("\n");
+		printk("\n");
 	}
 }
 static void my_hd(void *p, int len)
@@ -480,419 +463,468 @@ static void my_hd(void *p, int len)
 	int i, j, ch;
 	unsigned char *addr = p;
 
-	for (i=0;i<len;i+=16) {
-		printk ("%p ", addr+i);
-		for (j=0;j<16;j++) {
-			printk ("%02x %s", addr[j+i], (j==7)?" ":"");
+	for (i = 0; i < len; i += 16) {
+		printk("%p ", addr + i);
+		for (j = 0; j < 16; j++) {
+			printk("%02x %s", addr[j + i], (j == 7) ? " " : "");
 		}
-		for (j=0;j<16;j++) {
-			ch = addr[j+i];
-			printk ("%c", (ch < 0x20)?'.':((ch > 0x7f)?'.':ch));
+		for (j = 0; j < 16; j++) {
+			ch = addr[j + i];
+			printk("%c", (ch < 0x20) ? '.' :
+					((ch > 0x7f) ? '.' : ch));
 		}
-		printk ("\n");
+		printk("\n");
 	}
 }
 #endif
 
-
-
 /* This needs redoing for Alpha -- REW -- Done. */
 
-static inline void write_sx_byte (struct sx_board *board, int offset, u8 byte)
+static inline void write_sx_byte(struct sx_board *board, int offset, u8 byte)
 {
-	writeb (byte, board->base+offset);
+	writeb(byte, board->base + offset);
 }
 
-static inline u8 read_sx_byte (struct sx_board *board, int offset)
+static inline u8 read_sx_byte(struct sx_board *board, int offset)
 {
-	return readb (board->base+offset);
+	return readb(board->base + offset);
 }
 
-
-static inline void write_sx_word (struct sx_board *board, int offset, u16 word)
+static inline void write_sx_word(struct sx_board *board, int offset, u16 word)
 {
-	writew (word, board->base+offset);
+	writew(word, board->base + offset);
 }
 
-static inline u16 read_sx_word (struct sx_board *board, int offset)
+static inline u16 read_sx_word(struct sx_board *board, int offset)
 {
-	return readw (board->base + offset);
+	return readw(board->base + offset);
 }
 
-
-static int sx_busy_wait_eq (struct sx_board *board, 
-                     	    int offset, int mask, int correctval)
+static int sx_busy_wait_eq(struct sx_board *board,
+		int offset, int mask, int correctval)
 {
 	int i;
 
-	func_enter ();
+	func_enter();
 
-	for (i=0; i < TIMEOUT_1 ;i++)
-		if ((read_sx_byte (board, offset) & mask) == correctval) {
-			func_exit ();
+	for (i = 0; i < TIMEOUT_1; i++)
+		if ((read_sx_byte(board, offset) & mask) == correctval) {
+			func_exit();
 			return 1;
 		}
 
-	for (i=0; i < TIMEOUT_2 ;i++) {
-		if ((read_sx_byte (board, offset) & mask) == correctval) {
-			func_exit ();
+	for (i = 0; i < TIMEOUT_2; i++) {
+		if ((read_sx_byte(board, offset) & mask) == correctval) {
+			func_exit();
 			return 1;
 		}
-		udelay (1);
+		udelay(1);
 	}
 
-	func_exit ();
+	func_exit();
 	return 0;
 }
 
-
-static int sx_busy_wait_neq (struct sx_board *board, 
-                      	     int offset, int mask, int badval)
+static int sx_busy_wait_neq(struct sx_board *board,
+		int offset, int mask, int badval)
 {
 	int i;
 
-	func_enter ();
+	func_enter();
 
-	for (i=0; i < TIMEOUT_1 ;i++)
-		if ((read_sx_byte (board, offset) & mask) != badval) {
-			func_exit ();
+	for (i = 0; i < TIMEOUT_1; i++)
+		if ((read_sx_byte(board, offset) & mask) != badval) {
+			func_exit();
 			return 1;
 		}
 
-	for (i=0; i < TIMEOUT_2 ;i++) {
-		if ((read_sx_byte (board, offset) & mask) != badval) {
-			func_exit ();
+	for (i = 0; i < TIMEOUT_2; i++) {
+		if ((read_sx_byte(board, offset) & mask) != badval) {
+			func_exit();
 			return 1;
 		}
-		udelay (1);
+		udelay(1);
 	}
 
-	func_exit ();
+	func_exit();
 	return 0;
 }
 
-
-
 /* 5.6.4 of 6210028 r2.3 */
-static int sx_reset (struct sx_board *board)
+static int sx_reset(struct sx_board *board)
 {
-	func_enter ();
+	func_enter();
 
-	if (IS_SX_BOARD (board)) {
+	if (IS_SX_BOARD(board)) {
 
-		write_sx_byte (board, SX_CONFIG, 0);
-		write_sx_byte (board, SX_RESET, 1); /* Value doesn't matter */
+		write_sx_byte(board, SX_CONFIG, 0);
+		write_sx_byte(board, SX_RESET, 1); /* Value doesn't matter */
 
-		if (!sx_busy_wait_eq (board, SX_RESET_STATUS, 1, 0)) {
-			printk (KERN_INFO "sx: Card doesn't respond to reset....\n");
+		if (!sx_busy_wait_eq(board, SX_RESET_STATUS, 1, 0)) {
+			printk(KERN_INFO "sx: Card doesn't respond to "
+					"reset...\n");
 			return 0;
 		}
 	} else if (IS_EISA_BOARD(board)) {
-		outb(board->irq<<4, board->eisa_base+0xc02);
+		outb(board->irq << 4, board->eisa_base + 0xc02);
 	} else if (IS_SI1_BOARD(board)) {
-	        write_sx_byte (board, SI1_ISA_RESET,   0); // value does not matter
+		write_sx_byte(board, SI1_ISA_RESET, 0);	/*value doesn't matter*/
 	} else {
 		/* Gory details of the SI/ISA board */
-		write_sx_byte (board, SI2_ISA_RESET,    SI2_ISA_RESET_SET);
-		write_sx_byte (board, SI2_ISA_IRQ11,    SI2_ISA_IRQ11_CLEAR);
-		write_sx_byte (board, SI2_ISA_IRQ12,    SI2_ISA_IRQ12_CLEAR);
-		write_sx_byte (board, SI2_ISA_IRQ15,    SI2_ISA_IRQ15_CLEAR);
-		write_sx_byte (board, SI2_ISA_INTCLEAR, SI2_ISA_INTCLEAR_CLEAR);
-		write_sx_byte (board, SI2_ISA_IRQSET,   SI2_ISA_IRQSET_CLEAR);
+		write_sx_byte(board, SI2_ISA_RESET, SI2_ISA_RESET_SET);
+		write_sx_byte(board, SI2_ISA_IRQ11, SI2_ISA_IRQ11_CLEAR);
+		write_sx_byte(board, SI2_ISA_IRQ12, SI2_ISA_IRQ12_CLEAR);
+		write_sx_byte(board, SI2_ISA_IRQ15, SI2_ISA_IRQ15_CLEAR);
+		write_sx_byte(board, SI2_ISA_INTCLEAR, SI2_ISA_INTCLEAR_CLEAR);
+		write_sx_byte(board, SI2_ISA_IRQSET, SI2_ISA_IRQSET_CLEAR);
 	}
 
-	func_exit ();
+	func_exit();
 	return 1;
 }
 
-
 /* This doesn't work on machines where "NULL" isn't 0 */
 /* If you have one of those, someone will need to write 
    the equivalent of this, which will amount to about 3 lines. I don't
    want to complicate this right now. -- REW
    (See, I do write comments every now and then :-) */
-#define OFFSETOF(strct, elem) ((long)&(((struct strct *)NULL)->elem))
-
-
-#define CHAN_OFFSET(port,elem) (port->ch_base + OFFSETOF (_SXCHANNEL, elem))
-#define MODU_OFFSET(board,addr,elem)    (addr + OFFSETOF (_SXMODULE, elem))
-#define  BRD_OFFSET(board,elem)                (OFFSETOF (_SXCARD, elem))
+#define OFFSETOF(strct, elem)	((long)&(((struct strct *)NULL)->elem))
 
+#define CHAN_OFFSET(port,elem)	(port->ch_base + OFFSETOF (_SXCHANNEL, elem))
+#define MODU_OFFSET(board,addr,elem)	(addr + OFFSETOF (_SXMODULE, elem))
+#define  BRD_OFFSET(board,elem)	(OFFSETOF (_SXCARD, elem))
 
 #define sx_write_channel_byte(port, elem, val) \
-   write_sx_byte (port->board, CHAN_OFFSET (port, elem), val)
+	write_sx_byte (port->board, CHAN_OFFSET (port, elem), val)
 
 #define sx_read_channel_byte(port, elem) \
-   read_sx_byte (port->board, CHAN_OFFSET (port, elem))
+	read_sx_byte (port->board, CHAN_OFFSET (port, elem))
 
 #define sx_write_channel_word(port, elem, val) \
-   write_sx_word (port->board, CHAN_OFFSET (port, elem), val)
+	write_sx_word (port->board, CHAN_OFFSET (port, elem), val)
 
 #define sx_read_channel_word(port, elem) \
-   read_sx_word (port->board, CHAN_OFFSET (port, elem))
-
+	read_sx_word (port->board, CHAN_OFFSET (port, elem))
 
 #define sx_write_module_byte(board, addr, elem, val) \
-   write_sx_byte (board, MODU_OFFSET (board, addr, elem), val)
+	write_sx_byte (board, MODU_OFFSET (board, addr, elem), val)
 
 #define sx_read_module_byte(board, addr, elem) \
-   read_sx_byte (board, MODU_OFFSET (board, addr, elem))
+	read_sx_byte (board, MODU_OFFSET (board, addr, elem))
 
 #define sx_write_module_word(board, addr, elem, val) \
-   write_sx_word (board, MODU_OFFSET (board, addr, elem), val)
+	write_sx_word (board, MODU_OFFSET (board, addr, elem), val)
 
 #define sx_read_module_word(board, addr, elem) \
-   read_sx_word (board, MODU_OFFSET (board, addr, elem))
-
+	read_sx_word (board, MODU_OFFSET (board, addr, elem))
 
 #define sx_write_board_byte(board, elem, val) \
-   write_sx_byte (board, BRD_OFFSET (board, elem), val)
+	write_sx_byte (board, BRD_OFFSET (board, elem), val)
 
 #define sx_read_board_byte(board, elem) \
-   read_sx_byte (board, BRD_OFFSET (board, elem))
+	read_sx_byte (board, BRD_OFFSET (board, elem))
 
 #define sx_write_board_word(board, elem, val) \
-   write_sx_word (board, BRD_OFFSET (board, elem), val)
+	write_sx_word (board, BRD_OFFSET (board, elem), val)
 
 #define sx_read_board_word(board, elem) \
-   read_sx_word (board, BRD_OFFSET (board, elem))
-
+	read_sx_word (board, BRD_OFFSET (board, elem))
 
-static int sx_start_board (struct sx_board *board)
+static int sx_start_board(struct sx_board *board)
 {
-	if (IS_SX_BOARD (board)) {
-		write_sx_byte (board, SX_CONFIG, SX_CONF_BUSEN);
+	if (IS_SX_BOARD(board)) {
+		write_sx_byte(board, SX_CONFIG, SX_CONF_BUSEN);
 	} else if (IS_EISA_BOARD(board)) {
 		write_sx_byte(board, SI2_EISA_OFF, SI2_EISA_VAL);
-		outb((board->irq<<4)|4, board->eisa_base+0xc02);
+		outb((board->irq << 4) | 4, board->eisa_base + 0xc02);
 	} else if (IS_SI1_BOARD(board)) {
-		write_sx_byte (board, SI1_ISA_RESET_CLEAR, 0);
-		write_sx_byte (board, SI1_ISA_INTCL, 0);
+		write_sx_byte(board, SI1_ISA_RESET_CLEAR, 0);
+		write_sx_byte(board, SI1_ISA_INTCL, 0);
 	} else {
 		/* Don't bug me about the clear_set. 
 		   I haven't the foggiest idea what it's about -- REW */
-		write_sx_byte (board, SI2_ISA_RESET,    SI2_ISA_RESET_CLEAR);
-		write_sx_byte (board, SI2_ISA_INTCLEAR, SI2_ISA_INTCLEAR_SET);
+		write_sx_byte(board, SI2_ISA_RESET, SI2_ISA_RESET_CLEAR);
+		write_sx_byte(board, SI2_ISA_INTCLEAR, SI2_ISA_INTCLEAR_SET);
 	}
 	return 1;
 }
 
 #define SX_IRQ_REG_VAL(board) \
-        ((board->flags & SX_ISA_BOARD)?(board->irq << 4):0)
+	((board->flags & SX_ISA_BOARD) ? (board->irq << 4) : 0)
 
 /* Note. The SX register is write-only. Therefore, we have to enable the
    bus too. This is a no-op, if you don't mess with this driver... */
-static int sx_start_interrupts (struct sx_board *board)
+static int sx_start_interrupts(struct sx_board *board)
 {
 
 	/* Don't call this with board->irq == 0 */
 
 	if (IS_SX_BOARD(board)) {
-		write_sx_byte (board, SX_CONFIG, SX_IRQ_REG_VAL (board) | 
-		                                 SX_CONF_BUSEN | 
-		                                 SX_CONF_HOSTIRQ);
+		write_sx_byte(board, SX_CONFIG, SX_IRQ_REG_VAL(board) |
+				SX_CONF_BUSEN | SX_CONF_HOSTIRQ);
 	} else if (IS_EISA_BOARD(board)) {
-		inb(board->eisa_base+0xc03);  
+		inb(board->eisa_base + 0xc03);
 	} else if (IS_SI1_BOARD(board)) {
-	       write_sx_byte (board, SI1_ISA_INTCL,0);
-	       write_sx_byte (board, SI1_ISA_INTCL_CLEAR,0);
+		write_sx_byte(board, SI1_ISA_INTCL, 0);
+		write_sx_byte(board, SI1_ISA_INTCL_CLEAR, 0);
 	} else {
 		switch (board->irq) {
-		case 11:write_sx_byte (board, SI2_ISA_IRQ11, SI2_ISA_IRQ11_SET);break;
-		case 12:write_sx_byte (board, SI2_ISA_IRQ12, SI2_ISA_IRQ12_SET);break;
-		case 15:write_sx_byte (board, SI2_ISA_IRQ15, SI2_ISA_IRQ15_SET);break;
-		default:printk (KERN_INFO "sx: SI/XIO card doesn't support interrupt %d.\n", 
-		                board->irq);
-		return 0;
+		case 11:
+			write_sx_byte(board, SI2_ISA_IRQ11, SI2_ISA_IRQ11_SET);
+			break;
+		case 12:
+			write_sx_byte(board, SI2_ISA_IRQ12, SI2_ISA_IRQ12_SET);
+			break;
+		case 15:
+			write_sx_byte(board, SI2_ISA_IRQ15, SI2_ISA_IRQ15_SET);
+			break;
+		default:
+			printk(KERN_INFO "sx: SI/XIO card doesn't support "
+					"interrupt %d.\n", board->irq);
+			return 0;
 		}
-		write_sx_byte (board, SI2_ISA_INTCLEAR, SI2_ISA_INTCLEAR_SET);
+		write_sx_byte(board, SI2_ISA_INTCLEAR, SI2_ISA_INTCLEAR_SET);
 	}
 
 	return 1;
 }
 
-
-static int sx_send_command (struct sx_port *port, 
-                     	    int command, int mask, int newstat)
+static int sx_send_command(struct sx_port *port,
+		int command, int mask, int newstat)
 {
-	func_enter2 ();
-	write_sx_byte (port->board, CHAN_OFFSET (port, hi_hstat), command);
-	func_exit ();
-	return sx_busy_wait_eq (port->board, CHAN_OFFSET (port, hi_hstat), mask, newstat);
+	func_enter2();
+	write_sx_byte(port->board, CHAN_OFFSET(port, hi_hstat), command);
+	func_exit();
+	return sx_busy_wait_eq(port->board, CHAN_OFFSET(port, hi_hstat), mask,
+			newstat);
 }
 
-
-static char *mod_type_s (int module_type)
+static char *mod_type_s(int module_type)
 {
 	switch (module_type) {
-	case TA4:       return "TA4";
-	case TA8:       return "TA8";
-	case TA4_ASIC:  return "TA4_ASIC";
-	case TA8_ASIC:  return "TA8_ASIC";
-	case MTA_CD1400:return "MTA_CD1400";
-	case SXDC:      return "SXDC";
-	default:return "Unknown/invalid";
+	case TA4:
+		return "TA4";
+	case TA8:
+		return "TA8";
+	case TA4_ASIC:
+		return "TA4_ASIC";
+	case TA8_ASIC:
+		return "TA8_ASIC";
+	case MTA_CD1400:
+		return "MTA_CD1400";
+	case SXDC:
+		return "SXDC";
+	default:
+		return "Unknown/invalid";
 	}
 }
 
-
-static char *pan_type_s (int pan_type)
+static char *pan_type_s(int pan_type)
 {
 	switch (pan_type) {
-	case MOD_RS232DB25:     return "MOD_RS232DB25";
-	case MOD_RS232RJ45:     return "MOD_RS232RJ45";
-	case MOD_RS422DB25:     return "MOD_RS422DB25";
-	case MOD_PARALLEL:      return "MOD_PARALLEL";
-	case MOD_2_RS232DB25:   return "MOD_2_RS232DB25";
-	case MOD_2_RS232RJ45:   return "MOD_2_RS232RJ45";
-	case MOD_2_RS422DB25:   return "MOD_2_RS422DB25";
-	case MOD_RS232DB25MALE: return "MOD_RS232DB25MALE";
-	case MOD_2_PARALLEL:    return "MOD_2_PARALLEL";
-	case MOD_BLANK:         return "empty";
-	default:return "invalid";
+	case MOD_RS232DB25:
+		return "MOD_RS232DB25";
+	case MOD_RS232RJ45:
+		return "MOD_RS232RJ45";
+	case MOD_RS422DB25:
+		return "MOD_RS422DB25";
+	case MOD_PARALLEL:
+		return "MOD_PARALLEL";
+	case MOD_2_RS232DB25:
+		return "MOD_2_RS232DB25";
+	case MOD_2_RS232RJ45:
+		return "MOD_2_RS232RJ45";
+	case MOD_2_RS422DB25:
+		return "MOD_2_RS422DB25";
+	case MOD_RS232DB25MALE:
+		return "MOD_RS232DB25MALE";
+	case MOD_2_PARALLEL:
+		return "MOD_2_PARALLEL";
+	case MOD_BLANK:
+		return "empty";
+	default:
+		return "invalid";
 	}
 }
 
-
-static int mod_compat_type (int module_type)
+static int mod_compat_type(int module_type)
 {
 	return module_type >> 4;
 }
 
 static void sx_reconfigure_port(struct sx_port *port)
 {
-	if (sx_read_channel_byte (port, hi_hstat) == HS_IDLE_OPEN) {
-		if (sx_send_command (port, HS_CONFIG, -1, HS_IDLE_OPEN) != 1) {
-			printk (KERN_WARNING "sx: Sent reconfigure command, but card didn't react.\n");
+	if (sx_read_channel_byte(port, hi_hstat) == HS_IDLE_OPEN) {
+		if (sx_send_command(port, HS_CONFIG, -1, HS_IDLE_OPEN) != 1) {
+			printk(KERN_WARNING "sx: Sent reconfigure command, but "
+					"card didn't react.\n");
 		}
 	} else {
-		sx_dprintk (SX_DEBUG_TERMIOS, 
-		            "sx: Not sending reconfigure: port isn't open (%02x).\n", 
-		            sx_read_channel_byte (port, hi_hstat));
-	}	
+		sx_dprintk(SX_DEBUG_TERMIOS, "sx: Not sending reconfigure: "
+				"port isn't open (%02x).\n",
+				sx_read_channel_byte(port, hi_hstat));
+	}
 }
 
-static void sx_setsignals (struct sx_port *port, int dtr, int rts)
+static void sx_setsignals(struct sx_port *port, int dtr, int rts)
 {
 	int t;
-	func_enter2 ();
+	func_enter2();
 
-	t = sx_read_channel_byte (port, hi_op);
-	if (dtr >= 0) t = dtr? (t | OP_DTR): (t & ~OP_DTR);
-	if (rts >= 0) t = rts? (t | OP_RTS): (t & ~OP_RTS);
-	sx_write_channel_byte (port, hi_op, t);
-	sx_dprintk (SX_DEBUG_MODEMSIGNALS, "setsignals: %d/%d\n", dtr, rts);
+	t = sx_read_channel_byte(port, hi_op);
+	if (dtr >= 0)
+		t = dtr ? (t | OP_DTR) : (t & ~OP_DTR);
+	if (rts >= 0)
+		t = rts ? (t | OP_RTS) : (t & ~OP_RTS);
+	sx_write_channel_byte(port, hi_op, t);
+	sx_dprintk(SX_DEBUG_MODEMSIGNALS, "setsignals: %d/%d\n", dtr, rts);
 
-	func_exit ();
+	func_exit();
 }
 
-
-
-static int sx_getsignals (struct sx_port *port)
+static int sx_getsignals(struct sx_port *port)
 {
-	int i_stat,o_stat;
-
-	o_stat = sx_read_channel_byte (port, hi_op);
-	i_stat = sx_read_channel_byte (port, hi_ip);
-
-	sx_dprintk (SX_DEBUG_MODEMSIGNALS, "getsignals: %d/%d  (%d/%d) %02x/%02x\n",
-	            (o_stat & OP_DTR) != 0, (o_stat & OP_RTS) != 0,
-	            port->c_dcd, sx_get_CD (port),
-	            sx_read_channel_byte (port, hi_ip),
-	            sx_read_channel_byte (port, hi_state));
-
-	return (((o_stat & OP_DTR)?TIOCM_DTR:0) |
-	        ((o_stat & OP_RTS)?TIOCM_RTS:0) |
-	        ((i_stat & IP_CTS)?TIOCM_CTS:0) |
-	        ((i_stat & IP_DCD)?TIOCM_CAR:0) |
-	        ((i_stat & IP_DSR)?TIOCM_DSR:0) |
-	        ((i_stat & IP_RI)?TIOCM_RNG:0)
-	        );
+	int i_stat, o_stat;
+
+	o_stat = sx_read_channel_byte(port, hi_op);
+	i_stat = sx_read_channel_byte(port, hi_ip);
+
+	sx_dprintk(SX_DEBUG_MODEMSIGNALS, "getsignals: %d/%d  (%d/%d) "
+			"%02x/%02x\n",
+			(o_stat & OP_DTR) != 0, (o_stat & OP_RTS) != 0,
+			port->c_dcd, sx_get_CD(port),
+			sx_read_channel_byte(port, hi_ip),
+			sx_read_channel_byte(port, hi_state));
+
+	return (((o_stat & OP_DTR) ? TIOCM_DTR : 0) |
+		((o_stat & OP_RTS) ? TIOCM_RTS : 0) |
+		((i_stat & IP_CTS) ? TIOCM_CTS : 0) |
+		((i_stat & IP_DCD) ? TIOCM_CAR : 0) |
+		((i_stat & IP_DSR) ? TIOCM_DSR : 0) |
+		((i_stat & IP_RI) ? TIOCM_RNG : 0));
 }
 
-
-static void sx_set_baud (struct sx_port *port)
+static void sx_set_baud(struct sx_port *port)
 {
 	int t;
 
 	if (port->board->ta_type == MOD_SXDC) {
 		switch (port->gs.baud) {
-		  /* Save some typing work... */
-#define e(x) case x:t= BAUD_ ## x ; break
-			e(50);e(75);e(110);e(150);e(200);e(300);e(600);
-                        e(1200);e(1800);e(2000);e(2400);e(4800);e(7200);
-                        e(9600);e(14400);e(19200);e(28800);e(38400);
-                        e(56000);e(57600);e(64000);e(76800);e(115200);
-			e(128000);e(150000);e(230400);e(256000);e(460800);
-                        e(921600);
-		case 134    :t = BAUD_134_5;   break;
-		case 0      :t = -1;
-								 break;
+			/* Save some typing work... */
+#define e(x) case x: t = BAUD_ ## x; break
+			e(50);
+			e(75);
+			e(110);
+			e(150);
+			e(200);
+			e(300);
+			e(600);
+			e(1200);
+			e(1800);
+			e(2000);
+			e(2400);
+			e(4800);
+			e(7200);
+			e(9600);
+			e(14400);
+			e(19200);
+			e(28800);
+			e(38400);
+			e(56000);
+			e(57600);
+			e(64000);
+			e(76800);
+			e(115200);
+			e(128000);
+			e(150000);
+			e(230400);
+			e(256000);
+			e(460800);
+			e(921600);
+		case 134:
+			t = BAUD_134_5;
+			break;
+		case 0:
+			t = -1;
+			break;
 		default:
 			/* Can I return "invalid"? */
 			t = BAUD_9600;
-			printk (KERN_INFO "sx: unsupported baud rate: %d.\n", port->gs.baud);
+			printk(KERN_INFO "sx: unsupported baud rate: %d.\n",
+					port->gs.baud);
 			break;
 		}
 #undef e
 		if (t > 0) {
-			/* The baud rate is not set to 0, so we're enabeling DTR... -- REW */
-			sx_setsignals (port, 1, -1); 
+/* The baud rate is not set to 0, so we're enabeling DTR... -- REW */
+			sx_setsignals(port, 1, -1);
 			/* XXX This is not TA & MTA compatible */
-			sx_write_channel_byte (port, hi_csr, 0xff);
+			sx_write_channel_byte(port, hi_csr, 0xff);
 
-			sx_write_channel_byte (port, hi_txbaud, t);
-			sx_write_channel_byte (port, hi_rxbaud, t);
+			sx_write_channel_byte(port, hi_txbaud, t);
+			sx_write_channel_byte(port, hi_rxbaud, t);
 		} else {
-			sx_setsignals (port, 0, -1);
+			sx_setsignals(port, 0, -1);
 		}
 	} else {
 		switch (port->gs.baud) {
-#define e(x) case x:t= CSR_ ## x ; break
-			e(75);e(150);e(300);e(600);e(1200);e(2400);e(4800);
-                        e(1800);e(9600);
-			e(19200);e(57600);e(38400);
-			/* TA supports 110, but not 115200, MTA supports 115200, but not 110 */
-		case 110: 
+#define e(x) case x: t = CSR_ ## x; break
+			e(75);
+			e(150);
+			e(300);
+			e(600);
+			e(1200);
+			e(2400);
+			e(4800);
+			e(1800);
+			e(9600);
+			e(19200);
+			e(57600);
+			e(38400);
+/* TA supports 110, but not 115200, MTA supports 115200, but not 110 */
+		case 110:
 			if (port->board->ta_type == MOD_TA) {
 				t = CSR_110;
 				break;
 			} else {
 				t = CSR_9600;
-				printk (KERN_INFO "sx: Unsupported baud rate: %d.\n", port->gs.baud);
+				printk(KERN_INFO "sx: Unsupported baud rate: "
+						"%d.\n", port->gs.baud);
 				break;
 			}
-		case 115200: 
+		case 115200:
 			if (port->board->ta_type == MOD_TA) {
 				t = CSR_9600;
-				printk (KERN_INFO "sx: Unsupported baud rate: %d.\n", port->gs.baud);
+				printk(KERN_INFO "sx: Unsupported baud rate: "
+						"%d.\n", port->gs.baud);
 				break;
 			} else {
 				t = CSR_110;
 				break;
 			}
-		case 0      :t = -1;
-								 break;
+		case 0:
+			t = -1;
+			break;
 		default:
 			t = CSR_9600;
-			printk (KERN_INFO "sx: Unsupported baud rate: %d.\n", port->gs.baud);
+			printk(KERN_INFO "sx: Unsupported baud rate: %d.\n",
+					port->gs.baud);
 			break;
 		}
 #undef e
 		if (t >= 0) {
-			sx_setsignals (port, 1, -1);
-			sx_write_channel_byte (port, hi_csr, t * 0x11);
+			sx_setsignals(port, 1, -1);
+			sx_write_channel_byte(port, hi_csr, t * 0x11);
 		} else {
-			sx_setsignals (port, 0, -1);
+			sx_setsignals(port, 0, -1);
 		}
 	}
 }
 
-
 /* Simon Allen's version of this routine was 225 lines long. 85 is a lot
    better. -- REW */
 
-static int sx_set_real_termios (void *ptr)
+static int sx_set_real_termios(void *ptr)
 {
 	struct sx_port *port = ptr;
 
@@ -907,80 +939,83 @@ static int sx_set_real_termios (void *ptr)
 	   belongs (next to the drop dtr if baud == 0) -- REW */
 	/* sx_setsignals (port, 1, -1); */
 
-	sx_set_baud (port);
+	sx_set_baud(port);
 
 #define CFLAG port->gs.tty->termios->c_cflag
-	sx_write_channel_byte (port, hi_mr1,
-	                       (C_PARENB (port->gs.tty)? MR1_WITH:MR1_NONE) |
-	                       (C_PARODD (port->gs.tty)? MR1_ODD:MR1_EVEN) |
-	                       (C_CRTSCTS(port->gs.tty)? MR1_RTS_RXFLOW:0) |
-	                       (((CFLAG & CSIZE)==CS8) ? MR1_8_BITS:0) |
-	                       (((CFLAG & CSIZE)==CS7) ? MR1_7_BITS:0) |
-	                       (((CFLAG & CSIZE)==CS6) ? MR1_6_BITS:0) |
-	                       (((CFLAG & CSIZE)==CS5) ? MR1_5_BITS:0) );
-
-	sx_write_channel_byte (port, hi_mr2,
-	                       (C_CRTSCTS(port->gs.tty)?MR2_CTS_TXFLOW:0) |
-	                       (C_CSTOPB (port->gs.tty)?MR2_2_STOP:MR2_1_STOP));
+	sx_write_channel_byte(port, hi_mr1,
+			(C_PARENB(port->gs.tty) ? MR1_WITH : MR1_NONE) |
+			(C_PARODD(port->gs.tty) ? MR1_ODD : MR1_EVEN) |
+			(C_CRTSCTS(port->gs.tty) ? MR1_RTS_RXFLOW : 0) |
+			(((CFLAG & CSIZE) == CS8) ? MR1_8_BITS : 0) |
+			(((CFLAG & CSIZE) == CS7) ? MR1_7_BITS : 0) |
+			(((CFLAG & CSIZE) == CS6) ? MR1_6_BITS : 0) |
+			(((CFLAG & CSIZE) == CS5) ? MR1_5_BITS : 0));
+
+	sx_write_channel_byte(port, hi_mr2,
+			(C_CRTSCTS(port->gs.tty) ? MR2_CTS_TXFLOW : 0) |
+			(C_CSTOPB(port->gs.tty) ? MR2_2_STOP :
+			MR2_1_STOP));
 
 	switch (CFLAG & CSIZE) {
-	case CS8:sx_write_channel_byte (port, hi_mask, 0xff);break;
-	case CS7:sx_write_channel_byte (port, hi_mask, 0x7f);break;
-	case CS6:sx_write_channel_byte (port, hi_mask, 0x3f);break;
-	case CS5:sx_write_channel_byte (port, hi_mask, 0x1f);break;
+	case CS8:
+		sx_write_channel_byte(port, hi_mask, 0xff);
+		break;
+	case CS7:
+		sx_write_channel_byte(port, hi_mask, 0x7f);
+		break;
+	case CS6:
+		sx_write_channel_byte(port, hi_mask, 0x3f);
+		break;
+	case CS5:
+		sx_write_channel_byte(port, hi_mask, 0x1f);
+		break;
 	default:
-		printk (KERN_INFO "sx: Invalid wordsize: %u\n", CFLAG & CSIZE);
+		printk(KERN_INFO "sx: Invalid wordsize: %u\n", CFLAG & CSIZE);
 		break;
 	}
 
-	sx_write_channel_byte (port, hi_prtcl, 
-	                       (I_IXON   (port->gs.tty)?SP_TXEN:0) |
-	                       (I_IXOFF  (port->gs.tty)?SP_RXEN:0) |
-	                       (I_IXANY  (port->gs.tty)?SP_TANY:0) |
-	                       SP_DCEN);
+	sx_write_channel_byte(port, hi_prtcl,
+			(I_IXON(port->gs.tty) ? SP_TXEN : 0) |
+			(I_IXOFF(port->gs.tty) ? SP_RXEN : 0) |
+			(I_IXANY(port->gs.tty) ? SP_TANY : 0) | SP_DCEN);
 
-	sx_write_channel_byte (port, hi_break, 
-	                       (I_IGNBRK(port->gs.tty)?BR_IGN:0 |
-	                        I_BRKINT(port->gs.tty)?BR_INT:0));
+	sx_write_channel_byte(port, hi_break,
+			(I_IGNBRK(port->gs.tty) ? BR_IGN : 0 |
+			I_BRKINT(port->gs.tty) ? BR_INT : 0));
 
-	sx_write_channel_byte (port, hi_txon,  START_CHAR (port->gs.tty));
-	sx_write_channel_byte (port, hi_rxon,  START_CHAR (port->gs.tty));
-	sx_write_channel_byte (port, hi_txoff, STOP_CHAR  (port->gs.tty));
-	sx_write_channel_byte (port, hi_rxoff, STOP_CHAR  (port->gs.tty));
+	sx_write_channel_byte(port, hi_txon, START_CHAR(port->gs.tty));
+	sx_write_channel_byte(port, hi_rxon, START_CHAR(port->gs.tty));
+	sx_write_channel_byte(port, hi_txoff, STOP_CHAR(port->gs.tty));
+	sx_write_channel_byte(port, hi_rxoff, STOP_CHAR(port->gs.tty));
 
 	sx_reconfigure_port(port);
 
 	/* Tell line discipline whether we will do input cooking */
-	if(I_OTHER(port->gs.tty)) {
+	if (I_OTHER(port->gs.tty)) {
 		clear_bit(TTY_HW_COOK_IN, &port->gs.tty->flags);
 	} else {
 		set_bit(TTY_HW_COOK_IN, &port->gs.tty->flags);
 	}
-	sx_dprintk (SX_DEBUG_TERMIOS, "iflags: %x(%d) ",
-	            port->gs.tty->termios->c_iflag, 
-	            I_OTHER(port->gs.tty));
-
+	sx_dprintk(SX_DEBUG_TERMIOS, "iflags: %x(%d) ",
+			port->gs.tty->termios->c_iflag, I_OTHER(port->gs.tty));
 
 /* Tell line discipline whether we will do output cooking.
  * If OPOST is set and no other output flags are set then we can do output
  * processing.  Even if only *one* other flag in the O_OTHER group is set
  * we do cooking in software.
  */
-	if(O_OPOST(port->gs.tty) && !O_OTHER(port->gs.tty)) {
+	if (O_OPOST(port->gs.tty) && !O_OTHER(port->gs.tty)) {
 		set_bit(TTY_HW_COOK_OUT, &port->gs.tty->flags);
 	} else {
 		clear_bit(TTY_HW_COOK_OUT, &port->gs.tty->flags);
 	}
-	sx_dprintk (SX_DEBUG_TERMIOS, "oflags: %x(%d)\n",
-	            port->gs.tty->termios->c_oflag, 
-	            O_OTHER(port->gs.tty));
+	sx_dprintk(SX_DEBUG_TERMIOS, "oflags: %x(%d)\n",
+			port->gs.tty->termios->c_oflag, O_OTHER(port->gs.tty));
 	/* port->c_dcd = sx_get_CD (port); */
-	func_exit ();
+	func_exit();
 	return 0;
 }
 
-
-
 /* ********************************************************************** *
  *                   the interrupt related routines                       *
  * ********************************************************************** */
@@ -996,245 +1031,260 @@ static int sx_set_real_termios (void *ptr)
    know I'm dead against that, but I think it is required in this
    case.  */
 
-
-static void sx_transmit_chars (struct sx_port *port)
+static void sx_transmit_chars(struct sx_port *port)
 {
 	int c;
 	int tx_ip;
 	int txroom;
 
-	func_enter2 ();
-	sx_dprintk (SX_DEBUG_TRANSMIT, "Port %p: transmit %d chars\n", 
-	            port, port->gs.xmit_cnt);
+	func_enter2();
+	sx_dprintk(SX_DEBUG_TRANSMIT, "Port %p: transmit %d chars\n",
+			port, port->gs.xmit_cnt);
 
-	if (test_and_set_bit (SX_PORT_TRANSMIT_LOCK, &port->locks)) {
+	if (test_and_set_bit(SX_PORT_TRANSMIT_LOCK, &port->locks)) {
 		return;
 	}
 
 	while (1) {
 		c = port->gs.xmit_cnt;
 
-		sx_dprintk (SX_DEBUG_TRANSMIT, "Copying %d ", c);
-		tx_ip  = sx_read_channel_byte (port, hi_txipos);
+		sx_dprintk(SX_DEBUG_TRANSMIT, "Copying %d ", c);
+		tx_ip = sx_read_channel_byte(port, hi_txipos);
 
 		/* Took me 5 minutes to deduce this formula. 
 		   Luckily it is literally in the manual in section 6.5.4.3.5 */
-		txroom = (sx_read_channel_byte (port, hi_txopos) - tx_ip - 1) & 0xff;
+		txroom = (sx_read_channel_byte(port, hi_txopos) - tx_ip - 1) &
+				0xff;
 
 		/* Don't copy more bytes than there is room for in the buffer */
 		if (c > txroom)
 			c = txroom;
-		sx_dprintk (SX_DEBUG_TRANSMIT, " %d(%d) ", c, txroom );
+		sx_dprintk(SX_DEBUG_TRANSMIT, " %d(%d) ", c, txroom);
 
 		/* Don't copy past the end of the hardware transmit buffer */
-		if (c > 0x100 - tx_ip) 
+		if (c > 0x100 - tx_ip)
 			c = 0x100 - tx_ip;
 
-		sx_dprintk (SX_DEBUG_TRANSMIT, " %d(%d) ", c, 0x100-tx_ip );
+		sx_dprintk(SX_DEBUG_TRANSMIT, " %d(%d) ", c, 0x100 - tx_ip);
 
 		/* Don't copy pas the end of the source buffer */
-		if (c > SERIAL_XMIT_SIZE - port->gs.xmit_tail) 
+		if (c > SERIAL_XMIT_SIZE - port->gs.xmit_tail)
 			c = SERIAL_XMIT_SIZE - port->gs.xmit_tail;
 
-		sx_dprintk (SX_DEBUG_TRANSMIT, " %d(%ld) \n", 
-		            c, SERIAL_XMIT_SIZE- port->gs.xmit_tail);
-
-		/* If for one reason or another, we can't copy more data, we're done! */
-		if (c == 0) break;
+		sx_dprintk(SX_DEBUG_TRANSMIT, " %d(%ld) \n",
+				c, SERIAL_XMIT_SIZE - port->gs.xmit_tail);
 
+		/* If for one reason or another, we can't copy more data, we're
+		   done! */
+		if (c == 0)
+			break;
 
-		memcpy_toio (port->board->base + CHAN_OFFSET(port,hi_txbuf) + tx_ip, 
-		             port->gs.xmit_buf + port->gs.xmit_tail, c);
+		memcpy_toio(port->board->base + CHAN_OFFSET(port, hi_txbuf) +
+			tx_ip, port->gs.xmit_buf + port->gs.xmit_tail, c);
 
 		/* Update the pointer in the card */
-		sx_write_channel_byte (port, hi_txipos, (tx_ip+c) & 0xff);
+		sx_write_channel_byte(port, hi_txipos, (tx_ip + c) & 0xff);
 
 		/* Update the kernel buffer end */
-		port->gs.xmit_tail = (port->gs.xmit_tail + c) & (SERIAL_XMIT_SIZE-1);
+		port->gs.xmit_tail = (port->gs.xmit_tail + c) &
+				(SERIAL_XMIT_SIZE - 1);
 
 		/* This one last. (this is essential)
-		   It would allow others to start putting more data into the buffer! */
+		   It would allow others to start putting more data into the
+		   buffer! */
 		port->gs.xmit_cnt -= c;
 	}
 
 	if (port->gs.xmit_cnt == 0) {
-		sx_disable_tx_interrupts (port);
+		sx_disable_tx_interrupts(port);
 	}
 
 	if ((port->gs.xmit_cnt <= port->gs.wakeup_chars) && port->gs.tty) {
 		tty_wakeup(port->gs.tty);
-		sx_dprintk (SX_DEBUG_TRANSMIT, "Waking up.... ldisc (%d)....\n",
-		            port->gs.wakeup_chars); 
+		sx_dprintk(SX_DEBUG_TRANSMIT, "Waking up.... ldisc (%d)....\n",
+				port->gs.wakeup_chars);
 	}
 
-	clear_bit (SX_PORT_TRANSMIT_LOCK, &port->locks);
-	func_exit ();
+	clear_bit(SX_PORT_TRANSMIT_LOCK, &port->locks);
+	func_exit();
 }
 
-
 /* Note the symmetry between receiving chars and transmitting them!
    Note: The kernel should have implemented both a receive buffer and
    a transmit buffer. */
 
 /* Inlined: Called only once. Remove the inline when you add another call */
-static inline void sx_receive_chars (struct sx_port *port)
+static inline void sx_receive_chars(struct sx_port *port)
 {
 	int c;
 	int rx_op;
 	struct tty_struct *tty;
-	int copied=0;
+	int copied = 0;
 	unsigned char *rp;
 
-	func_enter2 ();
+	func_enter2();
 	tty = port->gs.tty;
 	while (1) {
-		rx_op = sx_read_channel_byte (port, hi_rxopos);
-		c = (sx_read_channel_byte (port, hi_rxipos) - rx_op) & 0xff;
+		rx_op = sx_read_channel_byte(port, hi_rxopos);
+		c = (sx_read_channel_byte(port, hi_rxipos) - rx_op) & 0xff;
 
-		sx_dprintk (SX_DEBUG_RECEIVE, "rxop=%d, c = %d.\n", rx_op, c); 
+		sx_dprintk(SX_DEBUG_RECEIVE, "rxop=%d, c = %d.\n", rx_op, c);
 
 		/* Don't copy past the end of the hardware receive buffer */
-		if (rx_op + c > 0x100) c = 0x100 - rx_op;
+		if (rx_op + c > 0x100)
+			c = 0x100 - rx_op;
 
-		sx_dprintk (SX_DEBUG_RECEIVE, "c = %d.\n", c);
+		sx_dprintk(SX_DEBUG_RECEIVE, "c = %d.\n", c);
 
 		/* Don't copy more bytes than there is room for in the buffer */
 
 		c = tty_prepare_flip_string(tty, &rp, c);
 
-		sx_dprintk (SX_DEBUG_RECEIVE, "c = %d.\n", c); 
+		sx_dprintk(SX_DEBUG_RECEIVE, "c = %d.\n", c);
 
 		/* If for one reason or another, we can't copy more data, we're done! */
-		if (c == 0) break;
+		if (c == 0)
+			break;
 
-		sx_dprintk (SX_DEBUG_RECEIVE , "Copying over %d chars. First is %d at %lx\n", c, 
-		            read_sx_byte (port->board, CHAN_OFFSET(port,hi_rxbuf) + rx_op),
-		            CHAN_OFFSET(port, hi_rxbuf)); 
-		memcpy_fromio (rp,
-		               port->board->base + CHAN_OFFSET(port,hi_rxbuf) + rx_op, c);
+		sx_dprintk(SX_DEBUG_RECEIVE, "Copying over %d chars. First is "
+				"%d at %lx\n", c, read_sx_byte(port->board,
+					CHAN_OFFSET(port, hi_rxbuf) + rx_op),
+				CHAN_OFFSET(port, hi_rxbuf));
+		memcpy_fromio(rp, port->board->base +
+				CHAN_OFFSET(port, hi_rxbuf) + rx_op, c);
 
 		/* This one last. ( Not essential.)
-		   It allows the card to start putting more data into the buffer! 
+		   It allows the card to start putting more data into the
+		   buffer!
 		   Update the pointer in the card */
-		sx_write_channel_byte (port, hi_rxopos, (rx_op + c) & 0xff);
+		sx_write_channel_byte(port, hi_rxopos, (rx_op + c) & 0xff);
 
 		copied += c;
 	}
 	if (copied) {
 		struct timeval tv;
 
-		do_gettimeofday (&tv);
-		sx_dprintk (SX_DEBUG_RECEIVE, 
-		            "pushing flipq port %d (%3d chars): %d.%06d  (%d/%d)\n", 
-		            port->line, copied, 
-		            (int) (tv.tv_sec % 60), (int)tv.tv_usec, tty->raw, tty->real_raw);
+		do_gettimeofday(&tv);
+		sx_dprintk(SX_DEBUG_RECEIVE, "pushing flipq port %d (%3d "
+				"chars): %d.%06d  (%d/%d)\n", port->line,
+				copied, (int)(tv.tv_sec % 60), (int)tv.tv_usec,
+				tty->raw, tty->real_raw);
 
-		/* Tell the rest of the system the news. Great news. New characters! */
-		tty_flip_buffer_push (tty);
+		/* Tell the rest of the system the news. Great news. New
+		   characters! */
+		tty_flip_buffer_push(tty);
 		/*    tty_schedule_flip (tty); */
 	}
 
-	func_exit ();
+	func_exit();
 }
 
 /* Inlined: it is called only once. Remove the inline if you add another 
    call */
-static inline void sx_check_modem_signals (struct sx_port *port)
+static inline void sx_check_modem_signals(struct sx_port *port)
 {
 	int hi_state;
 	int c_dcd;
 
-	hi_state = sx_read_channel_byte (port, hi_state);
-	sx_dprintk (SX_DEBUG_MODEMSIGNALS, "Checking modem signals (%d/%d)\n",
-	            port->c_dcd, sx_get_CD (port));
+	hi_state = sx_read_channel_byte(port, hi_state);
+	sx_dprintk(SX_DEBUG_MODEMSIGNALS, "Checking modem signals (%d/%d)\n",
+			port->c_dcd, sx_get_CD(port));
 
 	if (hi_state & ST_BREAK) {
 		hi_state &= ~ST_BREAK;
-		sx_dprintk (SX_DEBUG_MODEMSIGNALS, "got a break.\n");
-		sx_write_channel_byte (port, hi_state, hi_state);
-		gs_got_break (&port->gs);
+		sx_dprintk(SX_DEBUG_MODEMSIGNALS, "got a break.\n");
+		sx_write_channel_byte(port, hi_state, hi_state);
+		gs_got_break(&port->gs);
 	}
 	if (hi_state & ST_DCD) {
 		hi_state &= ~ST_DCD;
-		sx_dprintk (SX_DEBUG_MODEMSIGNALS, "got a DCD change.\n");
-		sx_write_channel_byte (port, hi_state, hi_state);
-		c_dcd = sx_get_CD (port);
-		sx_dprintk (SX_DEBUG_MODEMSIGNALS, "DCD is now %d\n", c_dcd);
+		sx_dprintk(SX_DEBUG_MODEMSIGNALS, "got a DCD change.\n");
+		sx_write_channel_byte(port, hi_state, hi_state);
+		c_dcd = sx_get_CD(port);
+		sx_dprintk(SX_DEBUG_MODEMSIGNALS, "DCD is now %d\n", c_dcd);
 		if (c_dcd != port->c_dcd) {
 			port->c_dcd = c_dcd;
-			if (sx_get_CD (port)) {
+			if (sx_get_CD(port)) {
 				/* DCD went UP */
-				if ((sx_read_channel_byte(port, hi_hstat) != HS_IDLE_CLOSED) &&
-						!(port->gs.tty->termios->c_cflag & CLOCAL) ) {
-					/* Are we blocking in open?*/
-					sx_dprintk (SX_DEBUG_MODEMSIGNALS, "DCD active, unblocking open\n");
-					wake_up_interruptible(&port->gs.open_wait);
+				if ((sx_read_channel_byte(port, hi_hstat) !=
+						HS_IDLE_CLOSED) &&
+						!(port->gs.tty->termios->
+							c_cflag & CLOCAL)) {
+					/* Are we blocking in open? */
+					sx_dprintk(SX_DEBUG_MODEMSIGNALS, "DCD "
+						"active, unblocking open\n");
+					wake_up_interruptible(&port->gs.
+							open_wait);
 				} else {
-					sx_dprintk (SX_DEBUG_MODEMSIGNALS, "DCD raised. Ignoring.\n");
+					sx_dprintk(SX_DEBUG_MODEMSIGNALS, "DCD "
+						"raised. Ignoring.\n");
 				}
 			} else {
 				/* DCD went down! */
-				if (!(port->gs.tty->termios->c_cflag & CLOCAL) ) {
-					sx_dprintk (SX_DEBUG_MODEMSIGNALS, "DCD dropped. hanging up....\n");
-					tty_hangup (port->gs.tty);
+				if (!(port->gs.tty->termios->c_cflag & CLOCAL)){
+					sx_dprintk(SX_DEBUG_MODEMSIGNALS, "DCD "
+						"dropped. hanging up....\n");
+					tty_hangup(port->gs.tty);
 				} else {
-					sx_dprintk (SX_DEBUG_MODEMSIGNALS, "DCD dropped. ignoring.\n");
+					sx_dprintk(SX_DEBUG_MODEMSIGNALS, "DCD "
+						"dropped. ignoring.\n");
 				}
 			}
 		} else {
-			sx_dprintk (SX_DEBUG_MODEMSIGNALS, "Hmmm. card told us DCD changed, but it didn't.\n");
+			sx_dprintk(SX_DEBUG_MODEMSIGNALS, "Hmmm. card told us "
+				"DCD changed, but it didn't.\n");
 		}
 	}
 }
 
-
 /* This is what an interrupt routine should look like. 
  * Small, elegant, clear.
  */
 
-static irqreturn_t sx_interrupt (int irq, void *ptr)
+static irqreturn_t sx_interrupt(int irq, void *ptr)
 {
 	struct sx_board *board = ptr;
 	struct sx_port *port;
 	int i;
 
-	func_enter ();
-	sx_dprintk (SX_DEBUG_FLOW, "sx: enter sx_interrupt (%d/%d)\n", irq, board->irq); 
+	func_enter();
+	sx_dprintk(SX_DEBUG_FLOW, "sx: enter sx_interrupt (%d/%d)\n", irq,
+			board->irq);
 
 	/* AAargh! The order in which to do these things is essential and
 	   not trivial. 
 
 	   - Rate limit goes before "recursive". Otherwise a series of
-	     recursive calls will hang the machine in the interrupt routine. 
+	   recursive calls will hang the machine in the interrupt routine.
 
 	   - hardware twiddling goes before "recursive". Otherwise when we
-	     poll the card, and a recursive interrupt happens, we won't
-	     ack the card, so it might keep on interrupting us. (especially
-	     level sensitive interrupt systems like PCI).
+	   poll the card, and a recursive interrupt happens, we won't
+	   ack the card, so it might keep on interrupting us. (especially
+	   level sensitive interrupt systems like PCI).
 
 	   - Rate limit goes before hardware twiddling. Otherwise we won't
-	     catch a card that has gone bonkers.
+	   catch a card that has gone bonkers.
 
 	   - The "initialized" test goes after the hardware twiddling. Otherwise
-	     the card will stick us in the interrupt routine again.
+	   the card will stick us in the interrupt routine again.
 
 	   - The initialized test goes before recursive. 
-	*/
-
-
+	 */
 
 #ifdef IRQ_RATE_LIMIT
 	/* Aaargh! I'm ashamed. This costs more lines-of-code than the
-	   actual interrupt routine!. (Well, used to when I wrote that comment) */
+	   actual interrupt routine!. (Well, used to when I wrote that
+	   comment) */
 	{
 		static int lastjif;
-		static int nintr=0;
+		static int nintr = 0;
 
 		if (lastjif == jiffies) {
 			if (++nintr > IRQ_RATE_LIMIT) {
-				free_irq (board->irq, board);
-				printk (KERN_ERR "sx: Too many interrupts. Turning off interrupt %d.\n", 
-					      board->irq);
+				free_irq(board->irq, board);
+				printk(KERN_ERR "sx: Too many interrupts. "
+						"Turning off interrupt %d.\n",
+						board->irq);
 			}
 		} else {
 			lastjif = jiffies;
@@ -1243,19 +1293,20 @@ static irqreturn_t sx_interrupt (int irq, void *ptr)
 	}
 #endif
 
-
 	if (board->irq == irq) {
 		/* Tell the card we've noticed the interrupt. */
 
-		sx_write_board_word (board, cc_int_pending, 0);
-		if (IS_SX_BOARD (board)) {
-			write_sx_byte (board, SX_RESET_IRQ, 1);
+		sx_write_board_word(board, cc_int_pending, 0);
+		if (IS_SX_BOARD(board)) {
+			write_sx_byte(board, SX_RESET_IRQ, 1);
 		} else if (IS_EISA_BOARD(board)) {
-			inb(board->eisa_base+0xc03);
-			write_sx_word(board, 8, 0); 
+			inb(board->eisa_base + 0xc03);
+			write_sx_word(board, 8, 0);
 		} else {
-			write_sx_byte (board, SI2_ISA_INTCLEAR, SI2_ISA_INTCLEAR_CLEAR);
-			write_sx_byte (board, SI2_ISA_INTCLEAR, SI2_ISA_INTCLEAR_SET);
+			write_sx_byte(board, SI2_ISA_INTCLEAR,
+					SI2_ISA_INTCLEAR_CLEAR);
+			write_sx_byte(board, SI2_ISA_INTCLEAR,
+					SI2_ISA_INTCLEAR_SET);
 		}
 	}
 
@@ -1264,53 +1315,48 @@ static irqreturn_t sx_interrupt (int irq, void *ptr)
 	if (!(board->flags & SX_BOARD_INITIALIZED))
 		return IRQ_HANDLED;
 
-	if (test_and_set_bit (SX_BOARD_INTR_LOCK, &board->locks)) {
-		printk (KERN_ERR "Recursive interrupt! (%d)\n", board->irq);
+	if (test_and_set_bit(SX_BOARD_INTR_LOCK, &board->locks)) {
+		printk(KERN_ERR "Recursive interrupt! (%d)\n", board->irq);
 		return IRQ_HANDLED;
 	}
 
-	 for (i=0;i<board->nports;i++) {
+	for (i = 0; i < board->nports; i++) {
 		port = &board->ports[i];
 		if (port->gs.flags & GS_ACTIVE) {
-			if (sx_read_channel_byte (port, hi_state)) {
-				sx_dprintk (SX_DEBUG_INTERRUPTS, 
-				            "Port %d: modem signal change?... \n", i);
-				sx_check_modem_signals (port); 
+			if (sx_read_channel_byte(port, hi_state)) {
+				sx_dprintk(SX_DEBUG_INTERRUPTS, "Port %d: "
+						"modem signal change?... \n",i);
+				sx_check_modem_signals(port);
 			}
 			if (port->gs.xmit_cnt) {
-				sx_transmit_chars (port);
+				sx_transmit_chars(port);
 			}
 			if (!(port->gs.flags & SX_RX_THROTTLE)) {
-				sx_receive_chars (port);
+				sx_receive_chars(port);
 			}
 		}
 	}
 
-	clear_bit (SX_BOARD_INTR_LOCK, &board->locks);
+	clear_bit(SX_BOARD_INTR_LOCK, &board->locks);
 
-	sx_dprintk (SX_DEBUG_FLOW, "sx: exit sx_interrupt (%d/%d)\n", irq, board->irq); 
-        func_exit ();
+	sx_dprintk(SX_DEBUG_FLOW, "sx: exit sx_interrupt (%d/%d)\n", irq,
+			board->irq);
+	func_exit();
 	return IRQ_HANDLED;
 }
 
-
-static void sx_pollfunc (unsigned long data)
+static void sx_pollfunc(unsigned long data)
 {
-	struct sx_board *board = (struct sx_board *) data;
-
-	func_enter ();
+	struct sx_board *board = (struct sx_board *)data;
 
-	sx_interrupt (0, board);
+	func_enter();
 
-	init_timer(&board->timer);
+	sx_interrupt(0, board);
 
-	board->timer.expires = jiffies + sx_poll;
-	add_timer (&board->timer);
-	func_exit ();
+	mod_timer(&board->timer, jiffies + sx_poll);
+	func_exit();
 }
 
-
-
 /* ********************************************************************** *
  *                Here are the routines that actually                     *
  *              interface with the generic_serial driver                  *
@@ -1319,9 +1365,9 @@ static void sx_pollfunc (unsigned long data)
 /* Ehhm. I don't know how to fiddle with interrupts on the SX card. --REW */
 /* Hmm. Ok I figured it out. You don't.  */
 
-static void sx_disable_tx_interrupts (void * ptr) 
+static void sx_disable_tx_interrupts(void *ptr)
 {
-	struct sx_port *port = ptr; 
+	struct sx_port *port = ptr;
 	func_enter2();
 
 	port->gs.flags &= ~GS_TX_INTEN;
@@ -1329,30 +1375,28 @@ static void sx_disable_tx_interrupts (void * ptr)
 	func_exit();
 }
 
-
-static void sx_enable_tx_interrupts (void * ptr) 
+static void sx_enable_tx_interrupts(void *ptr)
 {
-	struct sx_port *port = ptr; 
+	struct sx_port *port = ptr;
 	int data_in_buffer;
 	func_enter2();
 
 	/* First transmit the characters that we're supposed to */
-	sx_transmit_chars (port);
+	sx_transmit_chars(port);
 
 	/* The sx card will never interrupt us if we don't fill the buffer
 	   past 25%. So we keep considering interrupts off if that's the case. */
-	data_in_buffer = (sx_read_channel_byte (port, hi_txipos) - 
-	                  sx_read_channel_byte (port, hi_txopos)) & 0xff;
+	data_in_buffer = (sx_read_channel_byte(port, hi_txipos) -
+			  sx_read_channel_byte(port, hi_txopos)) & 0xff;
 
 	/* XXX Must be "HIGH_WATER" for SI card according to doc. */
-	if (data_in_buffer < LOW_WATER) 
+	if (data_in_buffer < LOW_WATER)
 		port->gs.flags &= ~GS_TX_INTEN;
 
 	func_exit();
 }
 
-
-static void sx_disable_rx_interrupts (void * ptr) 
+static void sx_disable_rx_interrupts(void *ptr)
 {
 	/*  struct sx_port *port = ptr; */
 	func_enter();
@@ -1360,7 +1404,7 @@ static void sx_disable_rx_interrupts (void * ptr)
 	func_exit();
 }
 
-static void sx_enable_rx_interrupts (void * ptr) 
+static void sx_enable_rx_interrupts(void *ptr)
 {
 	/*  struct sx_port *port = ptr; */
 	func_enter();
@@ -1368,55 +1412,48 @@ static void sx_enable_rx_interrupts (void * ptr)
 	func_exit();
 }
 
-
 /* Jeez. Isn't this simple? */
-static int sx_get_CD (void * ptr) 
+static int sx_get_CD(void *ptr)
 {
 	struct sx_port *port = ptr;
 	func_enter2();
 
 	func_exit();
-	return ((sx_read_channel_byte (port, hi_ip) & IP_DCD) != 0);
+	return ((sx_read_channel_byte(port, hi_ip) & IP_DCD) != 0);
 }
 
-
 /* Jeez. Isn't this simple? */
-static int sx_chars_in_buffer (void * ptr) 
+static int sx_chars_in_buffer(void *ptr)
 {
 	struct sx_port *port = ptr;
 	func_enter2();
 
 	func_exit();
-	return ((sx_read_channel_byte (port, hi_txipos) - 
-	         sx_read_channel_byte (port, hi_txopos)) & 0xff);
+	return ((sx_read_channel_byte(port, hi_txipos) -
+		 sx_read_channel_byte(port, hi_txopos)) & 0xff);
 }
 
-
-static void sx_shutdown_port (void * ptr) 
+static void sx_shutdown_port(void *ptr)
 {
-	struct sx_port *port = ptr; 
+	struct sx_port *port = ptr;
 
 	func_enter();
 
-	port->gs.flags &= ~ GS_ACTIVE;
+	port->gs.flags &= ~GS_ACTIVE;
 	if (port->gs.tty && (port->gs.tty->termios->c_cflag & HUPCL)) {
-		sx_setsignals (port, 0, 0);
+		sx_setsignals(port, 0, 0);
 		sx_reconfigure_port(port);
 	}
 
 	func_exit();
 }
 
-
-
-
-
 /* ********************************************************************** *
  *                Here are the routines that actually                     *
  *               interface with the rest of the system                    *
  * ********************************************************************** */
 
-static int sx_open  (struct tty_struct * tty, struct file * filp)
+static int sx_open(struct tty_struct *tty, struct file *filp)
 {
 	struct sx_port *port;
 	int retval, line;
@@ -1429,18 +1466,18 @@ static int sx_open  (struct tty_struct * tty, struct file * filp)
 	}
 
 	line = tty->index;
-	sx_dprintk (SX_DEBUG_OPEN, "%d: opening line %d. tty=%p ctty=%p, np=%d)\n", 
-	            current->pid, line, tty, current->signal->tty, sx_nports);
+	sx_dprintk(SX_DEBUG_OPEN, "%d: opening line %d. tty=%p ctty=%p, "
+			"np=%d)\n", current->pid, line, tty,
+			current->signal->tty, sx_nports);
 
 	if ((line < 0) || (line >= SX_NPORTS) || (line >= sx_nports))
 		return -ENODEV;
 
-	port = & sx_ports[line];
+	port = &sx_ports[line];
 	port->c_dcd = 0; /* Make sure that the first interrupt doesn't detect a
-	                    1 -> 0 transition. */
+			    1 -> 0 transition. */
 
-
-	sx_dprintk (SX_DEBUG_OPEN, "port = %p c_dcd = %d\n", port, port->c_dcd);
+	sx_dprintk(SX_DEBUG_OPEN, "port = %p c_dcd = %d\n", port, port->c_dcd);
 
 	spin_lock_irqsave(&port->gs.driver_lock, flags);
 
@@ -1449,13 +1486,13 @@ static int sx_open  (struct tty_struct * tty, struct file * filp)
 	port->gs.count++;
 	spin_unlock_irqrestore(&port->gs.driver_lock, flags);
 
-	sx_dprintk (SX_DEBUG_OPEN, "starting port\n");
+	sx_dprintk(SX_DEBUG_OPEN, "starting port\n");
 
 	/*
 	 * Start up serial port
 	 */
 	retval = gs_init_port(&port->gs);
-	sx_dprintk (SX_DEBUG_OPEN, "done gs_init\n");
+	sx_dprintk(SX_DEBUG_OPEN, "done gs_init\n");
 	if (retval) {
 		port->gs.count--;
 		return retval;
@@ -1463,19 +1500,20 @@ static int sx_open  (struct tty_struct * tty, struct file * filp)
 
 	port->gs.flags |= GS_ACTIVE;
 	if (port->gs.count <= 1)
-		sx_setsignals (port, 1,1);
+		sx_setsignals(port, 1, 1);
 
 #if 0
 	if (sx_debug & SX_DEBUG_OPEN)
-		my_hd (port, sizeof (*port));
+		my_hd(port, sizeof(*port));
 #else
 	if (sx_debug & SX_DEBUG_OPEN)
-		my_hd_io (port->board->base + port->ch_base, sizeof (*port));
+		my_hd_io(port->board->base + port->ch_base, sizeof(*port));
 #endif
 
 	if (port->gs.count <= 1) {
-		if (sx_send_command (port, HS_LOPEN, -1, HS_IDLE_OPEN) != 1) {
-			printk (KERN_ERR "sx: Card didn't respond to LOPEN command.\n");
+		if (sx_send_command(port, HS_LOPEN, -1, HS_IDLE_OPEN) != 1) {
+			printk(KERN_ERR "sx: Card didn't respond to LOPEN "
+					"command.\n");
 			spin_lock_irqsave(&port->gs.driver_lock, flags);
 			port->gs.count--;
 			spin_unlock_irqrestore(&port->gs.driver_lock, flags);
@@ -1484,75 +1522,76 @@ static int sx_open  (struct tty_struct * tty, struct file * filp)
 	}
 
 	retval = gs_block_til_ready(port, filp);
-	sx_dprintk (SX_DEBUG_OPEN, "Block til ready returned %d. Count=%d\n", 
-	            retval, port->gs.count);
+	sx_dprintk(SX_DEBUG_OPEN, "Block til ready returned %d. Count=%d\n",
+			retval, port->gs.count);
 
 	if (retval) {
-		/* 
-		 * Don't lower gs.count here because sx_close() will be called later
-		 */ 
+/*
+ * Don't lower gs.count here because sx_close() will be called later
+ */
 
 		return retval;
 	}
 	/* tty->low_latency = 1; */
 
-	port->c_dcd = sx_get_CD (port);
-	sx_dprintk (SX_DEBUG_OPEN, "at open: cd=%d\n", port->c_dcd);
+	port->c_dcd = sx_get_CD(port);
+	sx_dprintk(SX_DEBUG_OPEN, "at open: cd=%d\n", port->c_dcd);
 
 	func_exit();
 	return 0;
 
 }
 
-
-static void sx_close (void *ptr)
+static void sx_close(void *ptr)
 {
-	struct sx_port *port = ptr; 
+	struct sx_port *port = ptr;
 	/* Give the port 5 seconds to close down. */
-	int to = 5 * HZ; 
+	int to = 5 * HZ;
 
-	func_enter ();
+	func_enter();
 
-	sx_setsignals (port, 0, 0);
-	sx_reconfigure_port(port);	
-	sx_send_command (port, HS_CLOSE, 0, 0);
+	sx_setsignals(port, 0, 0);
+	sx_reconfigure_port(port);
+	sx_send_command(port, HS_CLOSE, 0, 0);
 
-	while (to-- && (sx_read_channel_byte (port, hi_hstat) != HS_IDLE_CLOSED))
+	while (to-- && (sx_read_channel_byte(port, hi_hstat) != HS_IDLE_CLOSED))
 		if (msleep_interruptible(10))
 			break;
-	if (sx_read_channel_byte (port, hi_hstat) != HS_IDLE_CLOSED) {
-		if (sx_send_command (port, HS_FORCE_CLOSED, -1, HS_IDLE_CLOSED) != 1) {
-			printk (KERN_ERR 
-			        "sx: sent the force_close command, but card didn't react\n");
+	if (sx_read_channel_byte(port, hi_hstat) != HS_IDLE_CLOSED) {
+		if (sx_send_command(port, HS_FORCE_CLOSED, -1, HS_IDLE_CLOSED)
+				!= 1) {
+			printk(KERN_ERR "sx: sent the force_close command, but "
+					"card didn't react\n");
 		} else
-			sx_dprintk (SX_DEBUG_CLOSE, "sent the force_close command.\n");
+			sx_dprintk(SX_DEBUG_CLOSE, "sent the force_close "
+					"command.\n");
 	}
 
-	sx_dprintk (SX_DEBUG_CLOSE, "waited %d jiffies for close. count=%d\n", 
-	            5 * HZ - to - 1, port->gs.count);
+	sx_dprintk(SX_DEBUG_CLOSE, "waited %d jiffies for close. count=%d\n",
+			5 * HZ - to - 1, port->gs.count);
 
-	if(port->gs.count) {
-		sx_dprintk(SX_DEBUG_CLOSE, "WARNING port count:%d\n", port->gs.count);
-		//printk ("%s SETTING port count to zero: %p count: %d\n", __FUNCTION__, port, port->gs.count);
-		//port->gs.count = 0;
+	if (port->gs.count) {
+		sx_dprintk(SX_DEBUG_CLOSE, "WARNING port count:%d\n",
+				port->gs.count);
+		/*printk("%s SETTING port count to zero: %p count: %d\n",
+				__FUNCTION__, port, port->gs.count);
+		port->gs.count = 0;*/
 	}
 
-	func_exit ();
+	func_exit();
 }
 
-
-
 /* This is relatively thorough. But then again it is only 20 lines. */
-#define MARCHUP    for (i=min;i<max;i++) 
-#define MARCHDOWN  for (i=max-1;i>=min;i--)
-#define W0         write_sx_byte (board, i, 0x55)
-#define W1         write_sx_byte (board, i, 0xaa)
-#define R0         if (read_sx_byte (board, i) != 0x55) return 1
-#define R1         if (read_sx_byte (board, i) != 0xaa) return 1
+#define MARCHUP		for (i = min; i < max; i++)
+#define MARCHDOWN	for (i = max - 1; i >= min; i--)
+#define W0		write_sx_byte(board, i, 0x55)
+#define W1		write_sx_byte(board, i, 0xaa)
+#define R0		if (read_sx_byte(board, i) != 0x55) return 1
+#define R1		if (read_sx_byte(board, i) != 0xaa) return 1
 
 /* This memtest takes a human-noticable time. You normally only do it
    once a boot, so I guess that it is worth it. */
-static int do_memtest (struct sx_board *board, int min, int max)
+static int do_memtest(struct sx_board *board, int min, int max)
 {
 	int i;
 
@@ -1561,16 +1600,37 @@ static int do_memtest (struct sx_board *board, int min, int max)
 	   intermittent errors. -- REW
 	   (For the theory behind memory testing see: 
 	   Testing Semiconductor Memories by A.J. van de Goor.) */
-	MARCHUP	 {W0;}
-	MARCHUP   {R0;W1;R1;W0;R0;W1;}
-	MARCHUP   {R1;W0;W1;}
-	MARCHDOWN {R1;W0;W1;W0;}
-	MARCHDOWN {R0;W1;W0;}
+	MARCHUP {
+		W0;
+	}
+	MARCHUP {
+		R0;
+		W1;
+		R1;
+		W0;
+		R0;
+		W1;
+	}
+	MARCHUP {
+		R1;
+		W0;
+		W1;
+	}
+	MARCHDOWN {
+		R1;
+		W0;
+		W1;
+		W0;
+	}
+	MARCHDOWN {
+		R0;
+		W1;
+		W0;
+	}
 
 	return 0;
 }
 
-
 #undef MARCHUP
 #undef MARCHDOWN
 #undef W0
@@ -1578,33 +1638,54 @@ static int do_memtest (struct sx_board *board, int min, int max)
 #undef R0
 #undef R1
 
-#define MARCHUP    for (i=min;i<max;i+=2) 
-#define MARCHDOWN  for (i=max-1;i>=min;i-=2)
-#define W0         write_sx_word (board, i, 0x55aa)
-#define W1         write_sx_word (board, i, 0xaa55)
-#define R0         if (read_sx_word (board, i) != 0x55aa) return 1
-#define R1         if (read_sx_word (board, i) != 0xaa55) return 1
+#define MARCHUP		for (i = min; i < max; i += 2)
+#define MARCHDOWN	for (i = max - 1; i >= min; i -= 2)
+#define W0		write_sx_word(board, i, 0x55aa)
+#define W1		write_sx_word(board, i, 0xaa55)
+#define R0		if (read_sx_word(board, i) != 0x55aa) return 1
+#define R1		if (read_sx_word(board, i) != 0xaa55) return 1
 
 #if 0
 /* This memtest takes a human-noticable time. You normally only do it
    once a boot, so I guess that it is worth it. */
-static int do_memtest_w (struct sx_board *board, int min, int max)
+static int do_memtest_w(struct sx_board *board, int min, int max)
 {
 	int i;
 
-	MARCHUP   {W0;}
-	MARCHUP   {R0;W1;R1;W0;R0;W1;}
-	MARCHUP   {R1;W0;W1;}
-	MARCHDOWN {R1;W0;W1;W0;}
-	MARCHDOWN {R0;W1;W0;}
+	MARCHUP {
+		W0;
+	}
+	MARCHUP {
+		R0;
+		W1;
+		R1;
+		W0;
+		R0;
+		W1;
+	}
+	MARCHUP {
+		R1;
+		W0;
+		W1;
+	}
+	MARCHDOWN {
+		R1;
+		W0;
+		W1;
+		W0;
+	}
+	MARCHDOWN {
+		R0;
+		W1;
+		W0;
+	}
 
 	return 0;
 }
 #endif
 
-
-static int sx_fw_ioctl (struct inode *inode, struct file *filp,
-                        unsigned int cmd, unsigned long arg)
+static int sx_fw_ioctl(struct inode *inode, struct file *filp,
+		unsigned int cmd, unsigned long arg)
 {
 	int rc = 0;
 	int __user *descr = (int __user *)arg;
@@ -1616,7 +1697,7 @@ static int sx_fw_ioctl (struct inode *inode, struct file *filp,
 
 	func_enter();
 
-#if 0 
+#if 0
 	/* Removed superuser check: Sysops can use the permissions on the device
 	   file to restrict access. Recommendation: Root only. (root.root 600) */
 	if (!capable(CAP_SYS_ADMIN)) {
@@ -1624,103 +1705,115 @@ static int sx_fw_ioctl (struct inode *inode, struct file *filp,
 	}
 #endif
 
-	sx_dprintk (SX_DEBUG_FIRMWARE, "IOCTL %x: %lx\n", cmd, arg);
+	sx_dprintk(SX_DEBUG_FIRMWARE, "IOCTL %x: %lx\n", cmd, arg);
 
-	if (!board) board = &boards[0];
+	if (!board)
+		board = &boards[0];
 	if (board->flags & SX_BOARD_PRESENT) {
-		sx_dprintk (SX_DEBUG_FIRMWARE, "Board present! (%x)\n", 
-		            board->flags);
+		sx_dprintk(SX_DEBUG_FIRMWARE, "Board present! (%x)\n",
+				board->flags);
 	} else {
-		sx_dprintk (SX_DEBUG_FIRMWARE, "Board not present! (%x) all:", 
-		            board->flags);
-		for (i=0;i< SX_NBOARDS;i++)
-			sx_dprintk (SX_DEBUG_FIRMWARE, "<%x> ", boards[i].flags);
-		sx_dprintk (SX_DEBUG_FIRMWARE, "\n");
+		sx_dprintk(SX_DEBUG_FIRMWARE, "Board not present! (%x) all:",
+				board->flags);
+		for (i = 0; i < SX_NBOARDS; i++)
+			sx_dprintk(SX_DEBUG_FIRMWARE, "<%x> ", boards[i].flags);
+		sx_dprintk(SX_DEBUG_FIRMWARE, "\n");
 		return -EIO;
 	}
 
 	switch (cmd) {
 	case SXIO_SET_BOARD:
-		sx_dprintk (SX_DEBUG_FIRMWARE, "set board to %ld\n", arg);
-		if (arg >= SX_NBOARDS) return -EIO;
-		sx_dprintk (SX_DEBUG_FIRMWARE, "not out of range\n");
-		if (!(boards[arg].flags	& SX_BOARD_PRESENT)) return -EIO;
-		sx_dprintk (SX_DEBUG_FIRMWARE, ".. and present!\n");
+		sx_dprintk(SX_DEBUG_FIRMWARE, "set board to %ld\n", arg);
+		if (arg >= SX_NBOARDS)
+			return -EIO;
+		sx_dprintk(SX_DEBUG_FIRMWARE, "not out of range\n");
+		if (!(boards[arg].flags & SX_BOARD_PRESENT))
+			return -EIO;
+		sx_dprintk(SX_DEBUG_FIRMWARE, ".. and present!\n");
 		board = &boards[arg];
 		break;
 	case SXIO_GET_TYPE:
-		rc = -ENOENT; /* If we manage to miss one, return error. */
-		if (IS_SX_BOARD (board)) rc = SX_TYPE_SX;
-		if (IS_CF_BOARD (board)) rc = SX_TYPE_CF;
-		if (IS_SI_BOARD (board)) rc = SX_TYPE_SI;
-		if (IS_SI1_BOARD (board)) rc = SX_TYPE_SI;
-		if (IS_EISA_BOARD (board)) rc = SX_TYPE_SI;
-		sx_dprintk (SX_DEBUG_FIRMWARE, "returning type= %d\n", rc);
+		rc = -ENOENT;	/* If we manage to miss one, return error. */
+		if (IS_SX_BOARD(board))
+			rc = SX_TYPE_SX;
+		if (IS_CF_BOARD(board))
+			rc = SX_TYPE_CF;
+		if (IS_SI_BOARD(board))
+			rc = SX_TYPE_SI;
+		if (IS_SI1_BOARD(board))
+			rc = SX_TYPE_SI;
+		if (IS_EISA_BOARD(board))
+			rc = SX_TYPE_SI;
+		sx_dprintk(SX_DEBUG_FIRMWARE, "returning type= %d\n", rc);
 		break;
 	case SXIO_DO_RAMTEST:
-		if (sx_initialized) /* Already initialized: better not ramtest the board.  */
+		if (sx_initialized)	/* Already initialized: better not ramtest the board.  */
 			return -EPERM;
-		if (IS_SX_BOARD (board)) {
-			rc          = do_memtest   (board, 0, 0x7000);
-			if (!rc) rc = do_memtest   (board, 0, 0x7000);
-			/*if (!rc) rc = do_memtest_w (board, 0, 0x7000);*/
+		if (IS_SX_BOARD(board)) {
+			rc = do_memtest(board, 0, 0x7000);
+			if (!rc)
+				rc = do_memtest(board, 0, 0x7000);
+			/*if (!rc) rc = do_memtest_w (board, 0, 0x7000); */
 		} else {
-			rc             = do_memtest   (board, 0, 0x7ff8);
+			rc = do_memtest(board, 0, 0x7ff8);
 			/* if (!rc) rc = do_memtest_w (board, 0, 0x7ff8); */
 		}
-		sx_dprintk (SX_DEBUG_FIRMWARE, "returning memtest result= %d\n", rc);
+		sx_dprintk(SX_DEBUG_FIRMWARE, "returning memtest result= %d\n",
+			   rc);
 		break;
 	case SXIO_DOWNLOAD:
-		if (sx_initialized) /* Already initialized */
+		if (sx_initialized)	/* Already initialized */
 			return -EEXIST;
-		if (!sx_reset (board)) 
+		if (!sx_reset(board))
 			return -EIO;
-		sx_dprintk (SX_DEBUG_INIT, "reset the board...\n");
-
-		tmp = kmalloc (SX_CHUNK_SIZE, GFP_USER);
-		if (!tmp) return -ENOMEM;
-		get_user (nbytes, descr++);
-		get_user (offset, descr++); 
-		get_user (data,	 descr++);
+		sx_dprintk(SX_DEBUG_INIT, "reset the board...\n");
+
+		tmp = kmalloc(SX_CHUNK_SIZE, GFP_USER);
+		if (!tmp)
+			return -ENOMEM;
+		get_user(nbytes, descr++);
+		get_user(offset, descr++);
+		get_user(data, descr++);
 		while (nbytes && data) {
-			for (i=0;i<nbytes;i += SX_CHUNK_SIZE) {
-				if (copy_from_user(tmp, (char __user *)data+i, 
-						   (i + SX_CHUNK_SIZE >
-						    nbytes) ? nbytes - i :
-						   	      SX_CHUNK_SIZE)) {
-					kfree (tmp);
+			for (i = 0; i < nbytes; i += SX_CHUNK_SIZE) {
+				if (copy_from_user(tmp, (char __user *)data + i,
+						(i + SX_CHUNK_SIZE > nbytes) ?
+						nbytes - i : SX_CHUNK_SIZE)) {
+					kfree(tmp);
 					return -EFAULT;
 				}
-				memcpy_toio(board->base2 + offset + i, tmp, 
-				                (i+SX_CHUNK_SIZE>nbytes)?nbytes-i:SX_CHUNK_SIZE);
+				memcpy_toio(board->base2 + offset + i, tmp,
+						(i + SX_CHUNK_SIZE > nbytes) ?
+						nbytes - i : SX_CHUNK_SIZE);
 			}
 
-			get_user (nbytes, descr++);
-			get_user (offset, descr++); 
-			get_user (data,   descr++);
+			get_user(nbytes, descr++);
+			get_user(offset, descr++);
+			get_user(data, descr++);
 		}
-		kfree (tmp);
-		sx_nports += sx_init_board (board);
+		kfree(tmp);
+		sx_nports += sx_init_board(board);
 		rc = sx_nports;
 		break;
 	case SXIO_INIT:
-		if (sx_initialized) /* Already initialized */
+		if (sx_initialized)	/* Already initialized */
 			return -EEXIST;
 		/* This is not allowed until all boards are initialized... */
-		for (i=0;i<SX_NBOARDS;i++) {
-			if ( (boards[i].flags & SX_BOARD_PRESENT) &&
-			     !(boards[i].flags & SX_BOARD_INITIALIZED))
+		for (i = 0; i < SX_NBOARDS; i++) {
+			if ((boards[i].flags & SX_BOARD_PRESENT) &&
+				!(boards[i].flags & SX_BOARD_INITIALIZED))
 				return -EIO;
 		}
-		for (i=0;i<SX_NBOARDS;i++)
-			if (!(boards[i].flags & SX_BOARD_PRESENT)) break;
-
-		sx_dprintk (SX_DEBUG_FIRMWARE, "initing portstructs, %d boards, "
-		            "%d channels, first board: %d ports\n", 
-		            i, sx_nports, boards[0].nports);
-		rc = sx_init_portstructs (i, sx_nports);
-		sx_init_drivers ();
-		if (rc >= 0) 
+		for (i = 0; i < SX_NBOARDS; i++)
+			if (!(boards[i].flags & SX_BOARD_PRESENT))
+				break;
+
+		sx_dprintk(SX_DEBUG_FIRMWARE, "initing portstructs, %d boards, "
+				"%d channels, first board: %d ports\n",
+				i, sx_nports, boards[0].nports);
+		rc = sx_init_portstructs(i, sx_nports);
+		sx_init_drivers();
+		if (rc >= 0)
 			sx_initialized++;
 		break;
 	case SXIO_SETDEBUG:
@@ -1737,32 +1830,32 @@ static int sx_fw_ioctl (struct inode *inode, struct file *filp,
 		rc = sx_nports;
 		break;
 	default:
-		printk (KERN_WARNING "Unknown ioctl on firmware device (%x).\n", cmd);
+		printk(KERN_WARNING "Unknown ioctl on firmware device (%x).\n",
+				cmd);
 		break;
 	}
-	func_exit ();
+	func_exit();
 	return rc;
 }
 
-
-static void sx_break (struct tty_struct * tty, int flag)
+static void sx_break(struct tty_struct *tty, int flag)
 {
 	struct sx_port *port = tty->driver_data;
 	int rv;
 
-	func_enter ();
+	func_enter();
 
-	if (flag) 
-		rv = sx_send_command (port, HS_START, -1, HS_IDLE_BREAK);
-	else 
-		rv = sx_send_command (port, HS_STOP, -1, HS_IDLE_OPEN);
-	if (rv != 1) printk (KERN_ERR "sx: couldn't send break (%x).\n",
-			read_sx_byte (port->board, CHAN_OFFSET (port, hi_hstat)));
+	if (flag)
+		rv = sx_send_command(port, HS_START, -1, HS_IDLE_BREAK);
+	else
+		rv = sx_send_command(port, HS_STOP, -1, HS_IDLE_OPEN);
+	if (rv != 1)
+		printk(KERN_ERR "sx: couldn't send break (%x).\n",
+			read_sx_byte(port->board, CHAN_OFFSET(port, hi_hstat)));
 
-	func_exit ();
+	func_exit();
 }
 
-
 static int sx_tiocmget(struct tty_struct *tty, struct file *file)
 {
 	struct sx_port *port = tty->driver_data;
@@ -1770,7 +1863,7 @@ static int sx_tiocmget(struct tty_struct *tty, struct file *file)
 }
 
 static int sx_tiocmset(struct tty_struct *tty, struct file *file,
-		       unsigned int set, unsigned int clear)
+		unsigned int set, unsigned int clear)
 {
 	struct sx_port *port = tty->driver_data;
 	int rts = -1, dtr = -1;
@@ -1789,8 +1882,8 @@ static int sx_tiocmset(struct tty_struct *tty, struct file *file,
 	return 0;
 }
 
-static int sx_ioctl (struct tty_struct * tty, struct file * filp, 
-                     unsigned int cmd, unsigned long arg)
+static int sx_ioctl(struct tty_struct *tty, struct file *filp,
+		unsigned int cmd, unsigned long arg)
 {
 	int rc;
 	struct sx_port *port = tty->driver_data;
@@ -1803,10 +1896,10 @@ static int sx_ioctl (struct tty_struct * tty, struct file * filp,
 	switch (cmd) {
 	case TIOCGSOFTCAR:
 		rc = put_user(((tty->termios->c_cflag & CLOCAL) ? 1 : 0),
-		              (unsigned __user *) argp);
+				(unsigned __user *)argp);
 		break;
 	case TIOCSSOFTCAR:
-		if ((rc = get_user(ival, (unsigned __user *) argp)) == 0) {
+		if ((rc = get_user(ival, (unsigned __user *)argp)) == 0) {
 			tty->termios->c_cflag =
 				(tty->termios->c_cflag & ~CLOCAL) |
 				(ival ? CLOCAL : 0);
@@ -1827,7 +1920,6 @@ static int sx_ioctl (struct tty_struct * tty, struct file * filp,
 	return rc;
 }
 
-
 /* The throttle/unthrottle scheme for the Specialix card is different
  * from other drivers and deserves some explanation. 
  * The Specialix hardware takes care of XON/XOFF
@@ -1844,7 +1936,7 @@ static int sx_ioctl (struct tty_struct * tty, struct file * filp,
  * flow control scheme is in use for that port. -- Simon Allen
  */
 
-static void sx_throttle (struct tty_struct * tty)
+static void sx_throttle(struct tty_struct *tty)
 {
 	struct sx_port *port = (struct sx_port *)tty->driver_data;
 
@@ -1852,14 +1944,13 @@ static void sx_throttle (struct tty_struct * tty)
 	/* If the port is using any type of input flow
 	 * control then throttle the port.
 	 */
-	if((tty->termios->c_cflag & CRTSCTS) || (I_IXOFF(tty)) ) {
+	if ((tty->termios->c_cflag & CRTSCTS) || (I_IXOFF(tty))) {
 		port->gs.flags |= SX_RX_THROTTLE;
 	}
 	func_exit();
 }
 
-
-static void sx_unthrottle (struct tty_struct * tty)
+static void sx_unthrottle(struct tty_struct *tty)
 {
 	struct sx_port *port = (struct sx_port *)tty->driver_data;
 
@@ -1873,15 +1964,11 @@ static void sx_unthrottle (struct tty_struct * tty)
 	return;
 }
 
-
 /* ********************************************************************** *
  *                    Here are the initialization routines.               *
  * ********************************************************************** */
 
-
-
-
-static int sx_init_board (struct sx_board *board)
+static int sx_init_board(struct sx_board *board)
 {
 	int addr;
 	int chans;
@@ -1893,36 +1980,38 @@ static int sx_init_board (struct sx_board *board)
 
 	board->flags |= SX_BOARD_INITIALIZED;
 
-	if (read_sx_byte (board, 0))
+	if (read_sx_byte(board, 0))
 		/* CF boards may need this. */
-		write_sx_byte(board,0, 0);
+		write_sx_byte(board, 0, 0);
 
 	/* This resets the processor again, to make sure it didn't do any
 	   foolish things while we were downloading the image */
-	if (!sx_reset (board))
+	if (!sx_reset(board))
 		return 0;
 
-	sx_start_board (board);
-	udelay (10);
-	if (!sx_busy_wait_neq (board, 0, 0xff, 0)) {
-		printk (KERN_ERR "sx: Ooops. Board won't initialize.\n");
+	sx_start_board(board);
+	udelay(10);
+	if (!sx_busy_wait_neq(board, 0, 0xff, 0)) {
+		printk(KERN_ERR "sx: Ooops. Board won't initialize.\n");
 		return 0;
 	}
 
 	/* Ok. So now the processor on the card is running. It gathered
 	   some info for us... */
-	sx_dprintk (SX_DEBUG_INIT, "The sxcard structure:\n");
-	if (sx_debug & SX_DEBUG_INIT) my_hd_io (board->base, 0x10);
-	sx_dprintk (SX_DEBUG_INIT, "the first sx_module structure:\n");
-	if (sx_debug & SX_DEBUG_INIT) my_hd_io (board->base + 0x80, 0x30);
-
-	sx_dprintk (SX_DEBUG_INIT, 
-	            "init_status: %x, %dk memory, firmware V%x.%02x,\n", 
-	            read_sx_byte (board, 0), read_sx_byte(board, 1), 
-	            read_sx_byte (board, 5), read_sx_byte(board, 4));
-
-	if (read_sx_byte (board, 0) == 0xff) {
-		printk (KERN_INFO "sx: No modules found. Sorry.\n");
+	sx_dprintk(SX_DEBUG_INIT, "The sxcard structure:\n");
+	if (sx_debug & SX_DEBUG_INIT)
+		my_hd_io(board->base, 0x10);
+	sx_dprintk(SX_DEBUG_INIT, "the first sx_module structure:\n");
+	if (sx_debug & SX_DEBUG_INIT)
+		my_hd_io(board->base + 0x80, 0x30);
+
+	sx_dprintk(SX_DEBUG_INIT, "init_status: %x, %dk memory, firmware "
+			"V%x.%02x,\n",
+			read_sx_byte(board, 0), read_sx_byte(board, 1),
+			read_sx_byte(board, 5), read_sx_byte(board, 4));
+
+	if (read_sx_byte(board, 0) == 0xff) {
+		printk(KERN_INFO "sx: No modules found. Sorry.\n");
 		board->nports = 0;
 		return 0;
 	}
@@ -1930,82 +2019,97 @@ static int sx_init_board (struct sx_board *board)
 	chans = 0;
 
 	if (IS_SX_BOARD(board)) {
-		sx_write_board_word (board, cc_int_count, sx_maxints);
+		sx_write_board_word(board, cc_int_count, sx_maxints);
 	} else {
 		if (sx_maxints)
-			sx_write_board_word (board, cc_int_count, SI_PROCESSOR_CLOCK/8/sx_maxints);
+			sx_write_board_word(board, cc_int_count,
+					SI_PROCESSOR_CLOCK / 8 / sx_maxints);
 	}
 
 	/* grab the first module type... */
-	/*  board->ta_type = mod_compat_type (read_sx_byte (board, 0x80 + 0x08)); */
-	board->ta_type = mod_compat_type (sx_read_module_byte (board, 0x80, mc_chip));
+	/* board->ta_type = mod_compat_type (read_sx_byte (board, 0x80 + 0x08)); */
+	board->ta_type = mod_compat_type(sx_read_module_byte(board, 0x80,
+				mc_chip));
 
 	/* XXX byteorder */
-	for (addr = 0x80;addr != 0;addr = read_sx_word (board, addr) & 0x7fff) {
-		type = sx_read_module_byte (board, addr, mc_chip);
-		sx_dprintk (SX_DEBUG_INIT, "Module at %x: %d channels\n", 
-		            addr, read_sx_byte (board, addr + 2));
-
-		chans += sx_read_module_byte (board, addr, mc_type);
-
-		sx_dprintk (SX_DEBUG_INIT, "module is an %s, which has %s/%s panels\n", 
-		            mod_type_s (type),
-		            pan_type_s (sx_read_module_byte (board, addr, mc_mods) & 0xf),
-		            pan_type_s (sx_read_module_byte (board, addr, mc_mods) >> 4));
-
-		sx_dprintk (SX_DEBUG_INIT, "CD1400 versions: %x/%x, ASIC version: %x\n", 
-		            sx_read_module_byte (board, addr, mc_rev1),
-		            sx_read_module_byte (board, addr, mc_rev2),
-		            sx_read_module_byte (board, addr, mc_mtaasic_rev));
+	for (addr = 0x80; addr != 0; addr = read_sx_word(board, addr) & 0x7fff){
+		type = sx_read_module_byte(board, addr, mc_chip);
+		sx_dprintk(SX_DEBUG_INIT, "Module at %x: %d channels\n",
+				addr, read_sx_byte(board, addr + 2));
+
+		chans += sx_read_module_byte(board, addr, mc_type);
+
+		sx_dprintk(SX_DEBUG_INIT, "module is an %s, which has %s/%s "
+				"panels\n",
+				mod_type_s(type),
+				pan_type_s(sx_read_module_byte(board, addr,
+						mc_mods) & 0xf),
+				pan_type_s(sx_read_module_byte(board, addr,
+						mc_mods) >> 4));
+
+		sx_dprintk(SX_DEBUG_INIT, "CD1400 versions: %x/%x, ASIC "
+			"version: %x\n",
+			sx_read_module_byte(board, addr, mc_rev1),
+			sx_read_module_byte(board, addr, mc_rev2),
+			sx_read_module_byte(board, addr, mc_mtaasic_rev));
 
 		/* The following combinations are illegal: It should theoretically
 		   work, but timing problems make the bus HANG. */
 
-		if (mod_compat_type (type) != board->ta_type) {
-			printk (KERN_ERR "sx: This is an invalid configuration.\n"
-			        "Don't mix TA/MTA/SXDC on the same hostadapter.\n");
-			chans=0;
+		if (mod_compat_type(type) != board->ta_type) {
+			printk(KERN_ERR "sx: This is an invalid "
+				"configuration.\nDon't mix TA/MTA/SXDC on the "
+				"same hostadapter.\n");
+			chans = 0;
 			break;
 		}
-		if ((IS_EISA_BOARD(board) || 
-		     IS_SI_BOARD(board)) && (mod_compat_type(type) == 4)) {
-			printk (KERN_ERR "sx: This is an invalid configuration.\n"
-			        "Don't use SXDCs on an SI/XIO adapter.\n");
-			chans=0;
+		if ((IS_EISA_BOARD(board) ||
+				IS_SI_BOARD(board)) &&
+				(mod_compat_type(type) == 4)) {
+			printk(KERN_ERR	"sx: This is an invalid "
+				"configuration.\nDon't use SXDCs on an SI/XIO "
+				"adapter.\n");
+			chans = 0;
 			break;
 		}
-#if 0 /* Problem fixed: firmware 3.05 */
+#if 0				/* Problem fixed: firmware 3.05 */
 		if (IS_SX_BOARD(board) && (type == TA8)) {
 			/* There are some issues with the firmware and the DCD/RTS
 			   lines. It might work if you tie them together or something.
-			   It might also work if you get a newer sx_firmware.	Therefore
+			   It might also work if you get a newer sx_firmware.   Therefore
 			   this is just a warning. */
-			printk (KERN_WARNING "sx: The SX host doesn't work too well "
-			        "with the TA8 adapters.\nSpecialix is working on it.\n");
+			printk(KERN_WARNING
+			       "sx: The SX host doesn't work too well "
+			       "with the TA8 adapters.\nSpecialix is working on it.\n");
 		}
 #endif
 	}
 
 	if (chans) {
-		/* board->flags |= SX_BOARD_PRESENT; */
-		if(board->irq > 0) {
+		if (board->irq > 0) {
 			/* fixed irq, probably PCI */
-			if(sx_irqmask & (1 << board->irq)) { /* may we use this irq? */
-				if(request_irq(board->irq, sx_interrupt, IRQF_SHARED | IRQF_DISABLED, "sx", board)) {
-					printk(KERN_ERR "sx: Cannot allocate irq %d.\n", board->irq);
+			if (sx_irqmask & (1 << board->irq)) {	/* may we use this irq? */
+				if (request_irq(board->irq, sx_interrupt,
+						IRQF_SHARED | IRQF_DISABLED,
+						"sx", board)) {
+					printk(KERN_ERR "sx: Cannot allocate "
+						"irq %d.\n", board->irq);
 					board->irq = 0;
 				}
 			} else
 				board->irq = 0;
-		} else if(board->irq < 0 && sx_irqmask) {
+		} else if (board->irq < 0 && sx_irqmask) {
 			/* auto-allocate irq */
 			int irqnr;
-			int irqmask = sx_irqmask & (IS_SX_BOARD(board) ? SX_ISA_IRQ_MASK : SI2_ISA_IRQ_MASK);
-			for(irqnr = 15; irqnr > 0; irqnr--)
-				if(irqmask & (1 << irqnr))
-					if(! request_irq(irqnr, sx_interrupt, IRQF_SHARED | IRQF_DISABLED, "sx", board))
+			int irqmask = sx_irqmask & (IS_SX_BOARD(board) ?
+					SX_ISA_IRQ_MASK : SI2_ISA_IRQ_MASK);
+			for (irqnr = 15; irqnr > 0; irqnr--)
+				if (irqmask & (1 << irqnr))
+					if (!request_irq(irqnr, sx_interrupt,
+						IRQF_SHARED | IRQF_DISABLED,
+						"sx", board))
 						break;
-			if(! irqnr)
+			if (!irqnr)
 				printk(KERN_ERR "sx: Cannot allocate IRQ.\n");
 			board->irq = irqnr;
 		} else
@@ -2013,52 +2117,48 @@ static int sx_init_board (struct sx_board *board)
 
 		if (board->irq) {
 			/* Found a valid interrupt, start up interrupts! */
-			sx_dprintk (SX_DEBUG_INIT, "Using irq %d.\n", board->irq);
-			sx_start_interrupts (board);
+			sx_dprintk(SX_DEBUG_INIT, "Using irq %d.\n",
+					board->irq);
+			sx_start_interrupts(board);
 			board->poll = sx_slowpoll;
 			board->flags |= SX_IRQ_ALLOCATED;
 		} else {
 			/* no irq: setup board for polled operation */
 			board->poll = sx_poll;
-			sx_dprintk (SX_DEBUG_INIT, "Using poll-interval %d.\n", board->poll);
+			sx_dprintk(SX_DEBUG_INIT, "Using poll-interval %d.\n",
+					board->poll);
 		}
 
-		/* The timer should be initialized anyway: That way we can safely
-			 del_timer it when the module is unloaded. */
-		init_timer (&board->timer);
+		/* The timer should be initialized anyway: That way we can
+		   safely del_timer it when the module is unloaded. */
+		setup_timer(&board->timer, sx_pollfunc, (unsigned long)board);
 
-		if (board->poll) {
-			board->timer.data = (unsigned long) board;
-			board->timer.function = sx_pollfunc;
-			board->timer.expires = jiffies + board->poll;
-			add_timer (&board->timer);
-		}
+		if (board->poll)
+			mod_timer(&board->timer, jiffies + board->poll);
 	} else {
 		board->irq = 0;
 	}
 
 	board->nports = chans;
-	sx_dprintk (SX_DEBUG_INIT, "returning %d ports.", board->nports);
+	sx_dprintk(SX_DEBUG_INIT, "returning %d ports.", board->nports);
 
 	func_exit();
 	return chans;
 }
 
-
-static void printheader(void)
+static void __devinit printheader(void)
 {
 	static int header_printed;
 
 	if (!header_printed) {
-		printk (KERN_INFO "Specialix SX driver "
-		        "(C) 1998/1999 R.E.Wolff@BitWizard.nl \n");
-		printk (KERN_INFO "sx: version %s\n", RCS_ID);
+		printk(KERN_INFO "Specialix SX driver "
+			"(C) 1998/1999 R.E.Wolff@BitWizard.nl\n");
+		printk(KERN_INFO "sx: version " __stringify(SX_VERSION) "\n");
 		header_printed = 1;
 	}
 }
 
-
-static int probe_sx (struct sx_board *board)
+static int __devinit probe_sx(struct sx_board *board)
 {
 	struct vpd_prom vpdp;
 	char *p;
@@ -2066,51 +2166,57 @@ static int probe_sx (struct sx_board *board)
 
 	func_enter();
 
-	if (!IS_CF_BOARD (board)) {    
-		sx_dprintk (SX_DEBUG_PROBE, "Going to verify vpd prom at %p.\n", 
-		            board->base + SX_VPD_ROM);
+	if (!IS_CF_BOARD(board)) {
+		sx_dprintk(SX_DEBUG_PROBE, "Going to verify vpd prom at %p.\n",
+				board->base + SX_VPD_ROM);
 
 		if (sx_debug & SX_DEBUG_PROBE)
 			my_hd_io(board->base + SX_VPD_ROM, 0x40);
 
-		p = (char *) &vpdp;
-		for (i=0;i< sizeof (struct vpd_prom);i++)
-			*p++ = read_sx_byte (board, SX_VPD_ROM + i*2);
+		p = (char *)&vpdp;
+		for (i = 0; i < sizeof(struct vpd_prom); i++)
+			*p++ = read_sx_byte(board, SX_VPD_ROM + i * 2);
 
 		if (sx_debug & SX_DEBUG_PROBE)
-			my_hd (&vpdp, 0x20);
+			my_hd(&vpdp, 0x20);
 
-		sx_dprintk (SX_DEBUG_PROBE, "checking identifier...\n");
+		sx_dprintk(SX_DEBUG_PROBE, "checking identifier...\n");
 
-		if (strncmp (vpdp.identifier, SX_VPD_IDENT_STRING, 16) != 0) {
-			sx_dprintk (SX_DEBUG_PROBE, "Got non-SX identifier: '%s'\n", 
-			            vpdp.identifier); 
+		if (strncmp(vpdp.identifier, SX_VPD_IDENT_STRING, 16) != 0) {
+			sx_dprintk(SX_DEBUG_PROBE, "Got non-SX identifier: "
+					"'%s'\n", vpdp.identifier);
 			return 0;
 		}
 	}
 
-	printheader ();
-
-	if (!IS_CF_BOARD (board)) {
-		printk (KERN_DEBUG "sx: Found an SX board at %lx\n", board->hw_base);
-		printk (KERN_DEBUG "sx: hw_rev: %d, assembly level: %d, uniq ID:%08x, ", 
-		        vpdp.hwrev, vpdp.hwass, vpdp.uniqid);
-		printk (           "Manufactured: %d/%d\n", 
-		        1970 + vpdp.myear, vpdp.mweek);
+	printheader();
 
+	if (!IS_CF_BOARD(board)) {
+		printk(KERN_DEBUG "sx: Found an SX board at %lx\n",
+			board->hw_base);
+		printk(KERN_DEBUG "sx: hw_rev: %d, assembly level: %d, "
+				"uniq ID:%08x, ",
+				vpdp.hwrev, vpdp.hwass, vpdp.uniqid);
+		printk("Manufactured: %d/%d\n", 1970 + vpdp.myear, vpdp.mweek);
 
-		if ((((vpdp.uniqid >> 24) & SX_UNIQUEID_MASK) != SX_PCI_UNIQUEID1) &&
-		    (((vpdp.uniqid >> 24) & SX_UNIQUEID_MASK) != SX_ISA_UNIQUEID1)) {
-			/* This might be a bit harsh. This was the primary reason the
-			   SX/ISA card didn't work at first... */
-			printk (KERN_ERR "sx: Hmm. Not an SX/PCI or SX/ISA card. Sorry: giving up.\n");
+		if ((((vpdp.uniqid >> 24) & SX_UNIQUEID_MASK) !=
+				SX_PCI_UNIQUEID1) && (((vpdp.uniqid >> 24) &
+				SX_UNIQUEID_MASK) != SX_ISA_UNIQUEID1)) {
+			/* This might be a bit harsh. This was the primary
+			   reason the SX/ISA card didn't work at first... */
+			printk(KERN_ERR "sx: Hmm. Not an SX/PCI or SX/ISA "
+					"card. Sorry: giving up.\n");
 			return (0);
 		}
 
-		if (((vpdp.uniqid >> 24) & SX_UNIQUEID_MASK) == SX_ISA_UNIQUEID1) {
+		if (((vpdp.uniqid >> 24) & SX_UNIQUEID_MASK) ==
+				SX_ISA_UNIQUEID1) {
 			if (((unsigned long)board->hw_base) & 0x8000) {
-				printk (KERN_WARNING "sx: Warning: There may be hardware problems with the card at %lx.\n", board->hw_base);
-				printk (KERN_WARNING "sx: Read sx.txt for more info.\n");
+				printk(KERN_WARNING "sx: Warning: There may be "
+					"hardware problems with the card at "
+					"%lx.\n", board->hw_base);
+				printk(KERN_WARNING "sx: Read sx.txt for more "
+						"info.\n");
 			}
 		}
 	}
@@ -2118,17 +2224,15 @@ static int probe_sx (struct sx_board *board)
 	board->nports = -1;
 
 	/* This resets the processor, and keeps it off the bus. */
-	if (!sx_reset (board)) 
+	if (!sx_reset(board))
 		return 0;
-	sx_dprintk (SX_DEBUG_INIT, "reset the board...\n");
-
-	board->flags |= SX_BOARD_PRESENT;
+	sx_dprintk(SX_DEBUG_INIT, "reset the board...\n");
 
 	func_exit();
 	return 1;
 }
 
-
+#if defined(CONFIG_ISA) || defined(CONFIG_EISA)
 
 /* Specialix probes for this card at 32k increments from 640k to 16M.
    I consider machines with less than 16M unlikely nowadays, so I'm
@@ -2136,28 +2240,27 @@ static int probe_sx (struct sx_board *board)
    card. 0xe0000 and 0xf0000 are taken by the BIOS. That only leaves 
    0xc0000, 0xc8000, 0xd0000 and 0xd8000 . */
 
-static int probe_si (struct sx_board *board)
+static int __devinit probe_si(struct sx_board *board)
 {
 	int i;
 
 	func_enter();
-	sx_dprintk (SX_DEBUG_PROBE, "Going to verify SI signature hw %lx at %p.\n", board->hw_base,
-	            board->base + SI2_ISA_ID_BASE);
+	sx_dprintk(SX_DEBUG_PROBE, "Going to verify SI signature hw %lx at "
+		"%p.\n", board->hw_base, board->base + SI2_ISA_ID_BASE);
 
 	if (sx_debug & SX_DEBUG_PROBE)
 		my_hd_io(board->base + SI2_ISA_ID_BASE, 0x8);
 
 	if (!IS_EISA_BOARD(board)) {
-	  if( IS_SI1_BOARD(board) ) 
-	    {
-		for (i=0;i<8;i++) {
-		  write_sx_byte (board, SI2_ISA_ID_BASE+7-i,i); 
-
+		if (IS_SI1_BOARD(board)) {
+			for (i = 0; i < 8; i++) {
+				write_sx_byte(board, SI2_ISA_ID_BASE + 7 - i,i);
+			}
 		}
-	    }
-		for (i=0;i<8;i++) {
-			if ((read_sx_byte (board, SI2_ISA_ID_BASE+7-i) & 7) != i) {
-				func_exit ();
+		for (i = 0; i < 8; i++) {
+			if ((read_sx_byte(board, SI2_ISA_ID_BASE + 7 - i) & 7)
+					!= i) {
+				func_exit();
 				return 0;
 			}
 		}
@@ -2167,20 +2270,20 @@ static int probe_si (struct sx_board *board)
 	   but to prevent trouble, we'd better double check that we don't
 	   have an SI1 board when we're probing for an SI2 board.... */
 
-	write_sx_byte (board, SI2_ISA_ID_BASE,0x10); 
-	if ( IS_SI1_BOARD(board)) {
+	write_sx_byte(board, SI2_ISA_ID_BASE, 0x10);
+	if (IS_SI1_BOARD(board)) {
 		/* This should be an SI1 board, which has this
 		   location writable... */
-		if (read_sx_byte (board, SI2_ISA_ID_BASE) != 0x10) {
-			func_exit ();
-			return 0; 
+		if (read_sx_byte(board, SI2_ISA_ID_BASE) != 0x10) {
+			func_exit();
+			return 0;
 		}
 	} else {
 		/* This should be an SI2 board, which has the bottom
 		   3 bits non-writable... */
-		if (read_sx_byte (board, SI2_ISA_ID_BASE) == 0x10) {
-			func_exit ();
-			return 0; 
+		if (read_sx_byte(board, SI2_ISA_ID_BASE) == 0x10) {
+			func_exit();
+			return 0;
 		}
 	}
 
@@ -2188,45 +2291,44 @@ static int probe_si (struct sx_board *board)
 	   but to prevent trouble, we'd better double check that we don't
 	   have an SI1 board when we're probing for an SI2 board.... */
 
-	write_sx_byte (board, SI2_ISA_ID_BASE,0x10); 
-	if ( IS_SI1_BOARD(board)) {
+	write_sx_byte(board, SI2_ISA_ID_BASE, 0x10);
+	if (IS_SI1_BOARD(board)) {
 		/* This should be an SI1 board, which has this
 		   location writable... */
-		if (read_sx_byte (board, SI2_ISA_ID_BASE) != 0x10) {
+		if (read_sx_byte(board, SI2_ISA_ID_BASE) != 0x10) {
 			func_exit();
-			return 0; 
+			return 0;
 		}
 	} else {
 		/* This should be an SI2 board, which has the bottom
 		   3 bits non-writable... */
-		if (read_sx_byte (board, SI2_ISA_ID_BASE) == 0x10) {
-			func_exit ();
-			return 0; 
+		if (read_sx_byte(board, SI2_ISA_ID_BASE) == 0x10) {
+			func_exit();
+			return 0;
 		}
 	}
 
-	printheader ();
+	printheader();
 
-	printk (KERN_DEBUG "sx: Found an SI board at %lx\n", board->hw_base);
+	printk(KERN_DEBUG "sx: Found an SI board at %lx\n", board->hw_base);
 	/* Compared to the SX boards, it is a complete guess as to what
-		 this card is up to... */
+	   this card is up to... */
 
 	board->nports = -1;
 
 	/* This resets the processor, and keeps it off the bus. */
-	if (!sx_reset (board)) 
+	if (!sx_reset(board))
 		return 0;
-	sx_dprintk (SX_DEBUG_INIT, "reset the board...\n");
-
-	board->flags |= SX_BOARD_PRESENT;
+	sx_dprintk(SX_DEBUG_INIT, "reset the board...\n");
 
 	func_exit();
 	return 1;
 }
+#endif
 
 static const struct tty_operations sx_ops = {
 	.break_ctl = sx_break,
-	.open	= sx_open,
+	.open = sx_open,
 	.close = gs_close,
 	.write = gs_write,
 	.put_char = gs_put_char,
@@ -2261,34 +2363,23 @@ static int sx_init_drivers(void)
 	sx_driver->type = TTY_DRIVER_TYPE_SERIAL;
 	sx_driver->subtype = SERIAL_TYPE_NORMAL;
 	sx_driver->init_termios = tty_std_termios;
-	sx_driver->init_termios.c_cflag =
-	  B9600 | CS8 | CREAD | HUPCL | CLOCAL;
+	sx_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
+	sx_driver->init_termios.c_ispeed = 9600;
+	sx_driver->init_termios.c_ospeed = 9600;
 	sx_driver->flags = TTY_DRIVER_REAL_RAW;
 	tty_set_operations(sx_driver, &sx_ops);
 
 	if ((error = tty_register_driver(sx_driver))) {
 		put_tty_driver(sx_driver);
 		printk(KERN_ERR "sx: Couldn't register sx driver, error = %d\n",
-		       error);
+			error);
 		return 1;
 	}
 	func_exit();
 	return 0;
 }
 
-
-static void * ckmalloc (int size)
-{
-	void *p;
-
-	p = kmalloc(size, GFP_KERNEL);
-	if (p) 
-		memset(p, 0, size);
-	return p;
-}
-
-
-static int sx_init_portstructs (int nboards, int nports)
+static int sx_init_portstructs(int nboards, int nports)
 {
 	struct sx_board *board;
 	struct sx_port *port;
@@ -2299,8 +2390,9 @@ static int sx_init_portstructs (int nboards, int nports)
 	func_enter();
 
 	/* Many drivers statically allocate the maximum number of ports
-	   There is no reason not to allocate them dynamically. Is there? -- REW */
-	sx_ports          = ckmalloc(nports * sizeof (struct sx_port));
+	   There is no reason not to allocate them dynamically.
+	   Is there? -- REW */
+	sx_ports = kcalloc(nports, sizeof(struct sx_port), GFP_KERNEL);
 	if (!sx_ports)
 		return -ENOMEM;
 
@@ -2308,10 +2400,10 @@ static int sx_init_portstructs (int nboards, int nports)
 	for (i = 0; i < nboards; i++) {
 		board = &boards[i];
 		board->ports = port;
-		for (j=0; j < boards[i].nports;j++) {
-			sx_dprintk (SX_DEBUG_INIT, "initing port %d\n", j);
+		for (j = 0; j < boards[i].nports; j++) {
+			sx_dprintk(SX_DEBUG_INIT, "initing port %d\n", j);
 			port->gs.magic = SX_MAGIC;
-			port->gs.close_delay = HZ/2;
+			port->gs.close_delay = HZ / 2;
 			port->gs.closing_wait = 30 * HZ;
 			port->board = board;
 			port->gs.rd = &sx_real_driver;
@@ -2323,8 +2415,8 @@ static int sx_init_portstructs (int nboards, int nports)
 			 * Initializing wait queue
 			 */
 			init_waitqueue_head(&port->gs.open_wait);
-			init_waitqueue_head(&port->gs.close_wait); 		
-			
+			init_waitqueue_head(&port->gs.close_wait);
+
 			port++;
 		}
 	}
@@ -2335,28 +2427,36 @@ static int sx_init_portstructs (int nboards, int nports)
 		board = &boards[i];
 		board->port_base = portno;
 		/* Possibly the configuration was rejected. */
-		sx_dprintk (SX_DEBUG_PROBE, "Board has %d channels\n", board->nports);
-		if (board->nports <= 0) continue;
+		sx_dprintk(SX_DEBUG_PROBE, "Board has %d channels\n",
+				board->nports);
+		if (board->nports <= 0)
+			continue;
 		/* XXX byteorder ?? */
-		for (addr = 0x80;addr != 0;addr = read_sx_word (board, addr) & 0x7fff) {
-			chans = sx_read_module_byte (board, addr, mc_type); 
-			sx_dprintk (SX_DEBUG_PROBE, "Module at %x: %d channels\n", addr, chans);
-			sx_dprintk (SX_DEBUG_PROBE, "Port at");
-			for (j=0;j<chans;j++) {
-				/* The "sx-way" is the way it SHOULD be done. That way in the 
-				   future, the firmware may for example pack the structures a bit
-				   more efficient. Neil tells me it isn't going to happen anytime
-				   soon though. */
+		for (addr = 0x80; addr != 0;
+				addr = read_sx_word(board, addr) & 0x7fff) {
+			chans = sx_read_module_byte(board, addr, mc_type);
+			sx_dprintk(SX_DEBUG_PROBE, "Module at %x: %d "
+					"channels\n", addr, chans);
+			sx_dprintk(SX_DEBUG_PROBE, "Port at");
+			for (j = 0; j < chans; j++) {
+				/* The "sx-way" is the way it SHOULD be done.
+				   That way in the future, the firmware may for
+				   example pack the structures a bit more
+				   efficient. Neil tells me it isn't going to
+				   happen anytime soon though. */
 				if (IS_SX_BOARD(board))
-					port->ch_base = sx_read_module_word (board, addr+j*2, mc_chan_pointer);
+					port->ch_base = sx_read_module_word(
+							board, addr + j * 2,
+							mc_chan_pointer);
 				else
-					port->ch_base = addr + 0x100 + 0x300*j;
+					port->ch_base = addr + 0x100 + 0x300 *j;
 
-				sx_dprintk (SX_DEBUG_PROBE, " %x", port->ch_base);
+				sx_dprintk(SX_DEBUG_PROBE, " %x",
+						port->ch_base);
 				port->line = portno++;
 				port++;
 			}
-			sx_dprintk (SX_DEBUG_PROBE, "\n");
+			sx_dprintk(SX_DEBUG_PROBE, "\n");
 		}
 		/* This has to be done earlier. */
 		/* board->flags |= SX_BOARD_INITIALIZED; */
@@ -2366,6 +2466,17 @@ static int sx_init_portstructs (int nboards, int nports)
 	return 0;
 }
 
+static unsigned int sx_find_free_board(void)
+{
+	unsigned int i;
+
+	for (i = 0; i < SX_NBOARDS; i++)
+		if (!(boards[i].flags & SX_BOARD_PRESENT))
+			break;
+
+	return i;
+}
+
 static void __exit sx_release_drivers(void)
 {
 	func_enter();
@@ -2374,7 +2485,122 @@ static void __exit sx_release_drivers(void)
 	func_exit();
 }
 
-#ifdef CONFIG_PCI
+static void __devexit sx_remove_card(struct sx_board *board,
+		struct pci_dev *pdev)
+{
+	if (board->flags & SX_BOARD_INITIALIZED) {
+		/* The board should stop messing with us. (actually I mean the
+		   interrupt) */
+		sx_reset(board);
+		if ((board->irq) && (board->flags & SX_IRQ_ALLOCATED))
+			free_irq(board->irq, board);
+
+		/* It is safe/allowed to del_timer a non-active timer */
+		del_timer(&board->timer);
+		if (pdev) {
+			pci_iounmap(pdev, board->base);
+			pci_release_region(pdev, IS_CF_BOARD(board) ? 3 : 2);
+		} else {
+			iounmap(board->base);
+			release_region(board->hw_base, board->hw_len);
+		}
+
+		board->flags &= ~(SX_BOARD_INITIALIZED | SX_BOARD_PRESENT);
+	}
+}
+
+#ifdef CONFIG_EISA
+
+static int __devinit sx_eisa_probe(struct device *dev)
+{
+	struct eisa_device *edev = to_eisa_device(dev);
+	struct sx_board *board;
+	unsigned long eisa_slot = edev->base_addr;
+	unsigned int i;
+	int retval = -EIO;
+
+	mutex_lock(&sx_boards_lock);
+	i = sx_find_free_board();
+	if (i == SX_NBOARDS) {
+		mutex_unlock(&sx_boards_lock);
+		goto err;
+	}
+	board = &boards[i];
+	board->flags |= SX_BOARD_PRESENT;
+	mutex_unlock(&sx_boards_lock);
+
+	dev_info(dev, "XIO : Signature found in EISA slot %lu, "
+		 "Product %d Rev %d (REPORT THIS TO LKLM)\n",
+		 eisa_slot >> 12,
+		 inb(eisa_slot + EISA_VENDOR_ID_OFFSET + 2),
+		 inb(eisa_slot + EISA_VENDOR_ID_OFFSET + 3));
+
+	board->eisa_base = eisa_slot;
+	board->flags &= ~SX_BOARD_TYPE;
+	board->flags |= SI_EISA_BOARD;
+
+	board->hw_base = ((inb(eisa_slot + 0xc01) << 8) +
+			  inb(eisa_slot + 0xc00)) << 16;
+	board->hw_len = SI2_EISA_WINDOW_LEN;
+	if (!request_region(board->hw_base, board->hw_len, "sx")) {
+		dev_err(dev, "can't request region\n");
+		goto err_flag;
+	}
+	board->base2 =
+	board->base = ioremap(board->hw_base, SI2_EISA_WINDOW_LEN);
+	if (!board->base) {
+		dev_err(dev, "can't remap memory\n");
+		goto err_reg;
+	}
+
+	sx_dprintk(SX_DEBUG_PROBE, "IO hw_base address: %lx\n", board->hw_base);
+	sx_dprintk(SX_DEBUG_PROBE, "base: %p\n", board->base);
+	board->irq = inb(eisa_slot + 0xc02) >> 4;
+	sx_dprintk(SX_DEBUG_PROBE, "IRQ: %d\n", board->irq);
+
+	if (!probe_si(board))
+		goto err_unmap;
+
+	dev_set_drvdata(dev, board);
+
+	return 0;
+err_unmap:
+	iounmap(board->base);
+err_reg:
+	release_region(board->hw_base, board->hw_len);
+err_flag:
+	board->flags &= ~SX_BOARD_PRESENT;
+err:
+	return retval;
+}
+
+static int __devexit sx_eisa_remove(struct device *dev)
+{
+	struct sx_board *board = dev_get_drvdata(dev);
+
+	sx_remove_card(board, NULL);
+
+	return 0;
+}
+
+static struct eisa_device_id sx_eisa_tbl[] = {
+	{ "SLX" },
+	{ "" }
+};
+
+MODULE_DEVICE_TABLE(eisa, sx_eisa_tbl);
+
+static struct eisa_driver sx_eisadriver = {
+	.id_table = sx_eisa_tbl,
+	.driver = {
+		.name = "sx",
+		.probe = sx_eisa_probe,
+		.remove = __devexit_p(sx_eisa_remove),
+	}
+};
+
+#endif
+
  /******************************************************** 
  * Setting bit 17 in the CNTRL register of the PLX 9050  * 
  * chip forces a retry on writes while a read is pending.*
@@ -2386,233 +2612,265 @@ static void __exit sx_release_drivers(void)
    EEprom.  As the bit is read/write for the CPU, we can fix it here,
    if we detect that it isn't set correctly. -- REW */
 
-static void fix_sx_pci (struct pci_dev *pdev, struct sx_board *board)
+static void __devinit fix_sx_pci(struct pci_dev *pdev, struct sx_board *board)
 {
 	unsigned int hwbase;
 	void __iomem *rebase;
 	unsigned int t;
 
-#define CNTRL_REG_OFFSET        0x50
-#define CNTRL_REG_GOODVALUE     0x18260000
+#define CNTRL_REG_OFFSET	0x50
+#define CNTRL_REG_GOODVALUE	0x18260000
 
 	pci_read_config_dword(pdev, PCI_BASE_ADDRESS_0, &hwbase);
 	hwbase &= PCI_BASE_ADDRESS_MEM_MASK;
 	rebase = ioremap(hwbase, 0x80);
-	t = readl (rebase + CNTRL_REG_OFFSET);
+	t = readl(rebase + CNTRL_REG_OFFSET);
 	if (t != CNTRL_REG_GOODVALUE) {
-		printk (KERN_DEBUG "sx: performing cntrl reg fix: %08x -> %08x\n", t, CNTRL_REG_GOODVALUE); 
-		writel (CNTRL_REG_GOODVALUE, rebase + CNTRL_REG_OFFSET);
+		printk(KERN_DEBUG "sx: performing cntrl reg fix: %08x -> "
+			"%08x\n", t, CNTRL_REG_GOODVALUE);
+		writel(CNTRL_REG_GOODVALUE, rebase + CNTRL_REG_OFFSET);
 	}
 	iounmap(rebase);
 }
-#endif
-
 
-static int __init sx_init(void) 
+static int __devinit sx_pci_probe(struct pci_dev *pdev,
+				  const struct pci_device_id *ent)
 {
-	int i;
-	int found = 0;
-	int eisa_slot;
 	struct sx_board *board;
+	unsigned int i, reg;
+	int retval = -EIO;
 
-#ifdef CONFIG_PCI
-	struct pci_dev *pdev = NULL;
-	unsigned int tint;
-	unsigned short tshort;
-#endif
+	mutex_lock(&sx_boards_lock);
+	i = sx_find_free_board();
+	if (i == SX_NBOARDS) {
+		mutex_unlock(&sx_boards_lock);
+		goto err;
+	}
+	board = &boards[i];
+	board->flags |= SX_BOARD_PRESENT;
+	mutex_unlock(&sx_boards_lock);
 
-	func_enter();
-	sx_dprintk (SX_DEBUG_INIT, "Initing sx module... (sx_debug=%d)\n", sx_debug);
-	if (abs ((long) (&sx_debug) - sx_debug) < 0x10000) {
-		printk (KERN_WARNING "sx: sx_debug is an address, instead of a value. "
-		        "Assuming -1.\n");
-		printk ("(%p)\n", &sx_debug);
-		sx_debug=-1;
+	retval = pci_enable_device(pdev);
+	if (retval)
+		goto err_flag;
+
+	board->flags &= ~SX_BOARD_TYPE;
+	board->flags |= (pdev->subsystem_vendor == 0x200) ? SX_PCI_BOARD :
+		SX_CFPCI_BOARD;
+
+	/* CF boards use base address 3.... */
+	reg = IS_CF_BOARD(board) ? 3 : 2;
+	retval = pci_request_region(pdev, reg, "sx");
+	if (retval) {
+		dev_err(&pdev->dev, "can't request region\n");
+		goto err_flag;
+	}
+	board->hw_base = pci_resource_start(pdev, reg);
+	board->base2 =
+	board->base = pci_iomap(pdev, reg, WINDOW_LEN(board));
+	if (!board->base) {
+		dev_err(&pdev->dev, "ioremap failed\n");
+		goto err_reg;
 	}
 
-	if (misc_register(&sx_fw_device) < 0) {
-		printk(KERN_ERR "SX: Unable to register firmware loader driver.\n");
-		return -EIO;
+	/* Most of the stuff on the CF board is offset by 0x18000 ....  */
+	if (IS_CF_BOARD(board))
+		board->base += 0x18000;
+
+	board->irq = pdev->irq;
+
+	dev_info(&pdev->dev, "Got a specialix card: %p(%d) %x.\n", board->base,
+		 board->irq, board->flags);
+
+	if (!probe_sx(board)) {
+		retval = -EIO;
+		goto err_unmap;
 	}
 
-#ifdef CONFIG_PCI
-	while ((pdev = pci_find_device (PCI_VENDOR_ID_SPECIALIX, 
-					PCI_DEVICE_ID_SPECIALIX_SX_XIO_IO8, 
-					      pdev))) {
-		if (pci_enable_device(pdev))
-			continue;
+	fix_sx_pci(pdev, board);
 
-		/* Specialix has a whole bunch of cards with
-		   0x2000 as the device ID. They say its because
-		   the standard requires it. Stupid standard. */
-		/* It seems that reading a word doesn't work reliably on 2.0.
-		   Also, reading a non-aligned dword doesn't work. So we read the
-		   whole dword at 0x2c and extract the word at 0x2e (SUBSYSTEM_ID)
-		   ourselves */
-		/* I don't know why the define doesn't work, constant 0x2c does --REW */ 
-		pci_read_config_dword (pdev, 0x2c, &tint);
-		tshort = (tint >> 16) & 0xffff;
-		sx_dprintk (SX_DEBUG_PROBE, "Got a specialix card: %x.\n", tint);
-		/* sx_dprintk (SX_DEBUG_PROBE, "pdev = %d/%d	(%x)\n", pdev, tint); */ 
-		if ((tshort != 0x0200) && (tshort != 0x0300)) {
-			sx_dprintk (SX_DEBUG_PROBE, "But it's not an SX card (%d)...\n", 
-				    tshort);
-			continue;
-		}
-		board = &boards[found];
+	pci_set_drvdata(pdev, board);
 
-		board->flags &= ~SX_BOARD_TYPE;
-		board->flags |= (tshort == 0x200)?SX_PCI_BOARD:
-						  SX_CFPCI_BOARD;
-
-		/* CF boards use base address 3.... */
-		if (IS_CF_BOARD (board))
-			board->hw_base = pci_resource_start (pdev, 3);
-		else
-			board->hw_base = pci_resource_start (pdev, 2);
-		board->base2 = 
-		board->base = ioremap(board->hw_base, WINDOW_LEN (board));
-		if (!board->base) {
-			printk(KERN_ERR "ioremap failed\n");
-			/* XXX handle error */
-		}
+	return 0;
+err_unmap:
+	pci_iounmap(pdev, board->base);
+err_reg:
+	pci_release_region(pdev, reg);
+err_flag:
+	board->flags &= ~SX_BOARD_PRESENT;
+err:
+	return retval;
+}
 
-		/* Most of the stuff on the CF board is offset by
-		   0x18000 ....  */
-		if (IS_CF_BOARD (board)) board->base += 0x18000;
+static void __devexit sx_pci_remove(struct pci_dev *pdev)
+{
+	struct sx_board *board = pci_get_drvdata(pdev);
 
-		board->irq = pdev->irq;
+	sx_remove_card(board, pdev);
+}
 
-		sx_dprintk (SX_DEBUG_PROBE, "Got a specialix card: %x/%p(%d) %x.\n", 
-			    tint, boards[found].base, board->irq, board->flags);
+/* Specialix has a whole bunch of cards with 0x2000 as the device ID. They say
+   its because the standard requires it. So check for SUBVENDOR_ID. */
+static struct pci_device_id sx_pci_tbl[] = {
+	{ PCI_VENDOR_ID_SPECIALIX, PCI_DEVICE_ID_SPECIALIX_SX_XIO_IO8,
+		.subvendor = 0x0200,.subdevice = PCI_ANY_ID },
+	{ PCI_VENDOR_ID_SPECIALIX, PCI_DEVICE_ID_SPECIALIX_SX_XIO_IO8,
+		.subvendor = 0x0300,.subdevice = PCI_ANY_ID },
+	{ 0 }
+};
 
-		if (probe_sx (board)) {
-			found++;
-			fix_sx_pci (pdev, board);
-		} else 
-			iounmap(board->base2);
-	}
+MODULE_DEVICE_TABLE(pci, sx_pci_tbl);
+
+static struct pci_driver sx_pcidriver = {
+	.name = "sx",
+	.id_table = sx_pci_tbl,
+	.probe = sx_pci_probe,
+	.remove = __devexit_p(sx_pci_remove)
+};
+
+static int __init sx_init(void)
+{
+#ifdef CONFIG_EISA
+	int retval1;
 #endif
+#ifdef CONFIG_ISA
+	struct sx_board *board;
+	unsigned int i;
+#endif
+	unsigned int found = 0;
+	int retval;
+
+	func_enter();
+	sx_dprintk(SX_DEBUG_INIT, "Initing sx module... (sx_debug=%d)\n",
+			sx_debug);
+	if (abs((long)(&sx_debug) - sx_debug) < 0x10000) {
+		printk(KERN_WARNING "sx: sx_debug is an address, instead of a "
+				"value. Assuming -1.\n(%p)\n", &sx_debug);
+		sx_debug = -1;
+	}
 
-	for (i=0;i<NR_SX_ADDRS;i++) {
+	if (misc_register(&sx_fw_device) < 0) {
+		printk(KERN_ERR "SX: Unable to register firmware loader "
+				"driver.\n");
+		return -EIO;
+	}
+#ifdef CONFIG_ISA
+	for (i = 0; i < NR_SX_ADDRS; i++) {
 		board = &boards[found];
 		board->hw_base = sx_probe_addrs[i];
+		board->hw_len = SX_WINDOW_LEN;
+		if (!request_region(board->hw_base, board->hw_len, "sx"))
+			continue;
 		board->base2 =
-		board->base = ioremap(board->hw_base, SX_WINDOW_LEN);
+		board->base = ioremap(board->hw_base, board->hw_len);
+		if (!board->base)
+			goto err_sx_reg;
 		board->flags &= ~SX_BOARD_TYPE;
-		board->flags |=	SX_ISA_BOARD;
-		board->irq = sx_irqmask?-1:0;
+		board->flags |= SX_ISA_BOARD;
+		board->irq = sx_irqmask ? -1 : 0;
 
-		if (probe_sx (board)) {
+		if (probe_sx(board)) {
+			board->flags |= SX_BOARD_PRESENT;
 			found++;
 		} else {
 			iounmap(board->base);
+err_sx_reg:
+			release_region(board->hw_base, board->hw_len);
 		}
 	}
 
-	for (i=0;i<NR_SI_ADDRS;i++) {
+	for (i = 0; i < NR_SI_ADDRS; i++) {
 		board = &boards[found];
 		board->hw_base = si_probe_addrs[i];
+		board->hw_len = SI2_ISA_WINDOW_LEN;
+		if (!request_region(board->hw_base, board->hw_len, "sx"))
+			continue;
 		board->base2 =
-		board->base = ioremap(board->hw_base, SI2_ISA_WINDOW_LEN);
+		board->base = ioremap(board->hw_base, board->hw_len);
+		if (!board->base)
+			goto err_si_reg;
 		board->flags &= ~SX_BOARD_TYPE;
-		board->flags |=  SI_ISA_BOARD;
-		board->irq = sx_irqmask ?-1:0;
+		board->flags |= SI_ISA_BOARD;
+		board->irq = sx_irqmask ? -1 : 0;
 
-		if (probe_si (board)) {
+		if (probe_si(board)) {
+			board->flags |= SX_BOARD_PRESENT;
 			found++;
 		} else {
-			iounmap (board->base);
+			iounmap(board->base);
+err_si_reg:
+			release_region(board->hw_base, board->hw_len);
 		}
 	}
-	for (i=0;i<NR_SI1_ADDRS;i++) {
+	for (i = 0; i < NR_SI1_ADDRS; i++) {
 		board = &boards[found];
 		board->hw_base = si1_probe_addrs[i];
+		board->hw_len = SI1_ISA_WINDOW_LEN;
+		if (!request_region(board->hw_base, board->hw_len, "sx"))
+			continue;
 		board->base2 =
-		board->base = ioremap(board->hw_base, SI1_ISA_WINDOW_LEN);
+		board->base = ioremap(board->hw_base, board->hw_len);
+		if (!board->base)
+			goto err_si1_reg;
 		board->flags &= ~SX_BOARD_TYPE;
-		board->flags |=  SI1_ISA_BOARD;
-		board->irq = sx_irqmask ?-1:0;
+		board->flags |= SI1_ISA_BOARD;
+		board->irq = sx_irqmask ? -1 : 0;
 
-		if (probe_si (board)) {
+		if (probe_si(board)) {
+			board->flags |= SX_BOARD_PRESENT;
 			found++;
 		} else {
-			iounmap (board->base);
+			iounmap(board->base);
+err_si1_reg:
+			release_region(board->hw_base, board->hw_len);
 		}
 	}
+#endif
+#ifdef CONFIG_EISA
+	retval1 = eisa_driver_register(&sx_eisadriver);
+#endif
+	retval = pci_register_driver(&sx_pcidriver);
 
-        sx_dprintk(SX_DEBUG_PROBE, "Probing for EISA cards\n");
-        for(eisa_slot=0x1000; eisa_slot<0x10000; eisa_slot+=0x1000)
-        {
-                if((inb(eisa_slot+0xc80)==0x4d) &&
-                   (inb(eisa_slot+0xc81)==0x98))
-                {
-			sx_dprintk(SX_DEBUG_PROBE, "%s : Signature found in EISA slot %d, Product %d Rev %d\n",
-			                        "XIO", (eisa_slot>>12), inb(eisa_slot+0xc82), inb(eisa_slot+0xc83));
-
-			board = &boards[found];
-			board->eisa_base = eisa_slot;
-			board->flags &= ~SX_BOARD_TYPE;
-			board->flags |= SI_EISA_BOARD;
-
-			board->hw_base = (((inb(0xc01+eisa_slot) << 8) + inb(0xc00+eisa_slot)) << 16);
-			board->base2 =
-			board->base = ioremap(board->hw_base, SI2_EISA_WINDOW_LEN);
-
-			sx_dprintk(SX_DEBUG_PROBE, "IO hw_base address: %lx\n", board->hw_base);
-			sx_dprintk(SX_DEBUG_PROBE, "base: %p\n", board->base);
-			board->irq = inb(board->eisa_base+0xc02)>>4; 
-			sx_dprintk(SX_DEBUG_PROBE, "IRQ: %d\n", board->irq);
-			
-			probe_si(board);
-
-			found++;
-		}
-	}
 	if (found) {
-		printk (KERN_INFO "sx: total of %d boards detected.\n", found);
-	} else {
-		misc_deregister(&sx_fw_device);
+		printk(KERN_INFO "sx: total of %d boards detected.\n", found);
+		retval = 0;
+	} else if (retval) {
+#ifdef CONFIG_EISA
+		retval = retval1;
+		if (retval1)
+#endif
+			misc_deregister(&sx_fw_device);
 	}
 
 	func_exit();
-	return found?0:-EIO;
+	return retval;
 }
 
-
-static void __exit sx_exit (void)
+static void __exit sx_exit(void)
 {
-	int i; 
-	struct sx_board *board;
+	int i;
 
 	func_enter();
-	for (i = 0; i < SX_NBOARDS; i++) {
-		board = &boards[i];
-		if (board->flags & SX_BOARD_INITIALIZED) {
-			sx_dprintk (SX_DEBUG_CLEANUP, "Cleaning up board at %p\n", board->base);
-			/* The board should stop messing with us.
-			   (actually I mean the interrupt) */
-			sx_reset (board);
-			if ((board->irq) && (board->flags & SX_IRQ_ALLOCATED))
-				free_irq (board->irq, board);
-
-			/* It is safe/allowed to del_timer a non-active timer */
-			del_timer (& board->timer);
-			iounmap(board->base);
-		}
-	}
+#ifdef CONFIG_EISA
+	eisa_driver_unregister(&sx_eisadriver);
+#endif
+	pci_unregister_driver(&sx_pcidriver);
+
+	for (i = 0; i < SX_NBOARDS; i++)
+		sx_remove_card(&boards[i], NULL);
+
 	if (misc_deregister(&sx_fw_device) < 0) {
-		printk (KERN_INFO "sx: couldn't deregister firmware loader device\n");
+		printk(KERN_INFO "sx: couldn't deregister firmware loader "
+				"device\n");
 	}
-	sx_dprintk (SX_DEBUG_CLEANUP, "Cleaning up drivers (%d)\n", sx_initialized);
+	sx_dprintk(SX_DEBUG_CLEANUP, "Cleaning up drivers (%d)\n",
+			sx_initialized);
 	if (sx_initialized)
-		sx_release_drivers ();
+		sx_release_drivers();
 
-	kfree (sx_ports);
+	kfree(sx_ports);
 	func_exit();
 }
 
 module_init(sx_init);
 module_exit(sx_exit);
-
-
diff --git a/drivers/char/sx.h b/drivers/char/sx.h
index e01f83cbe299..432aad0a2ddd 100644
--- a/drivers/char/sx.h
+++ b/drivers/char/sx.h
@@ -35,6 +35,7 @@ struct sx_board {
   void __iomem *base;
   void __iomem *base2;
   unsigned long hw_base;
+  resource_size_t hw_len;
   int eisa_base;
   int port_base; /* Number of the first port */
   struct sx_port *ports;
diff --git a/drivers/char/synclink.c b/drivers/char/synclink.c
index 645187b9141e..acc6fab601cc 100644
--- a/drivers/char/synclink.c
+++ b/drivers/char/synclink.c
@@ -3060,7 +3060,7 @@ static int mgsl_ioctl_common(struct mgsl_struct *info, unsigned int cmd, unsigne
  * 	
  * Return Value:		None
  */
-static void mgsl_set_termios(struct tty_struct *tty, struct termios *old_termios)
+static void mgsl_set_termios(struct tty_struct *tty, struct ktermios *old_termios)
 {
 	struct mgsl_struct *info = (struct mgsl_struct *)tty->driver_data;
 	unsigned long flags;
@@ -4405,6 +4405,8 @@ static int mgsl_init_tty(void)
 	serial_driver->init_termios = tty_std_termios;
 	serial_driver->init_termios.c_cflag =
 		B9600 | CS8 | CREAD | HUPCL | CLOCAL;
+	serial_driver->init_termios.c_ispeed = 9600;
+	serial_driver->init_termios.c_ospeed = 9600;
 	serial_driver->flags = TTY_DRIVER_REAL_RAW;
 	tty_set_operations(serial_driver, &mgsl_ops);
 	if ((rc = tty_register_driver(serial_driver)) < 0) {
diff --git a/drivers/char/synclink_gt.c b/drivers/char/synclink_gt.c
index e4730a7312b5..792c79c315e0 100644
--- a/drivers/char/synclink_gt.c
+++ b/drivers/char/synclink_gt.c
@@ -151,7 +151,7 @@ static struct tty_driver *serial_driver;
 static int  open(struct tty_struct *tty, struct file * filp);
 static void close(struct tty_struct *tty, struct file * filp);
 static void hangup(struct tty_struct *tty);
-static void set_termios(struct tty_struct *tty, struct termios *old_termios);
+static void set_termios(struct tty_struct *tty, struct ktermios *old_termios);
 
 static int  write(struct tty_struct *tty, const unsigned char *buf, int count);
 static void put_char(struct tty_struct *tty, unsigned char ch);
@@ -816,7 +816,7 @@ static void hangup(struct tty_struct *tty)
 	wake_up_interruptible(&info->open_wait);
 }
 
-static void set_termios(struct tty_struct *tty, struct termios *old_termios)
+static void set_termios(struct tty_struct *tty, struct ktermios *old_termios)
 {
 	struct slgt_info *info = tty->driver_data;
 	unsigned long flags;
@@ -3546,6 +3546,8 @@ static int __init slgt_init(void)
 	serial_driver->init_termios = tty_std_termios;
 	serial_driver->init_termios.c_cflag =
 		B9600 | CS8 | CREAD | HUPCL | CLOCAL;
+	serial_driver->init_termios.c_ispeed = 9600;
+	serial_driver->init_termios.c_ospeed = 9600;
 	serial_driver->flags = TTY_DRIVER_REAL_RAW;
 	tty_set_operations(serial_driver, &ops);
 	if ((rc = tty_register_driver(serial_driver)) < 0) {
diff --git a/drivers/char/synclinkmp.c b/drivers/char/synclinkmp.c
index 20a96ef250be..53e8ccf94fe3 100644
--- a/drivers/char/synclinkmp.c
+++ b/drivers/char/synclinkmp.c
@@ -519,7 +519,7 @@ static struct tty_driver *serial_driver;
 static int  open(struct tty_struct *tty, struct file * filp);
 static void close(struct tty_struct *tty, struct file * filp);
 static void hangup(struct tty_struct *tty);
-static void set_termios(struct tty_struct *tty, struct termios *old_termios);
+static void set_termios(struct tty_struct *tty, struct ktermios *old_termios);
 
 static int  write(struct tty_struct *tty, const unsigned char *buf, int count);
 static void put_char(struct tty_struct *tty, unsigned char ch);
@@ -918,7 +918,7 @@ static void hangup(struct tty_struct *tty)
 
 /* Set new termios settings
  */
-static void set_termios(struct tty_struct *tty, struct termios *old_termios)
+static void set_termios(struct tty_struct *tty, struct ktermios *old_termios)
 {
 	SLMP_INFO *info = (SLMP_INFO *)tty->driver_data;
 	unsigned long flags;
@@ -4034,6 +4034,8 @@ static int __init synclinkmp_init(void)
 	serial_driver->init_termios = tty_std_termios;
 	serial_driver->init_termios.c_cflag =
 		B9600 | CS8 | CREAD | HUPCL | CLOCAL;
+	serial_driver->init_termios.c_ispeed = 9600;
+	serial_driver->init_termios.c_ospeed = 9600;
 	serial_driver->flags = TTY_DRIVER_REAL_RAW;
 	tty_set_operations(serial_driver, &ops);
 	if ((rc = tty_register_driver(serial_driver)) < 0) {
diff --git a/drivers/char/tb0219.c b/drivers/char/tb0219.c
index bb1bad4c18f9..4c431cb7cf1b 100644
--- a/drivers/char/tb0219.c
+++ b/drivers/char/tb0219.c
@@ -164,7 +164,7 @@ static ssize_t tanbac_tb0219_read(struct file *file, char __user *buf, size_t le
 	unsigned int minor;
 	char value;
 
-	minor = iminor(file->f_dentry->d_inode);
+	minor = iminor(file->f_path.dentry->d_inode);
 	switch (minor) {
 	case 0:
 		value = get_led();
@@ -200,7 +200,7 @@ static ssize_t tanbac_tb0219_write(struct file *file, const char __user *data,
 	int retval = 0;
 	char c;
 
-	minor = iminor(file->f_dentry->d_inode);
+	minor = iminor(file->f_path.dentry->d_inode);
 	switch (minor) {
 	case 0:
 		type = TYPE_LED;
diff --git a/drivers/char/tipar.c b/drivers/char/tipar.c
index 9df0ca1be0e3..47fb20f69695 100644
--- a/drivers/char/tipar.c
+++ b/drivers/char/tipar.c
@@ -285,7 +285,7 @@ static ssize_t
 tipar_write (struct file *file, const char __user *buf, size_t count,
 		loff_t * ppos)
 {
-	unsigned int minor = iminor(file->f_dentry->d_inode) - TIPAR_MINOR;
+	unsigned int minor = iminor(file->f_path.dentry->d_inode) - TIPAR_MINOR;
 	ssize_t n;
 
 	parport_claim_or_block(table[minor].dev);
@@ -313,7 +313,7 @@ static ssize_t
 tipar_read(struct file *file, char __user *buf, size_t count, loff_t * ppos)
 {
 	int b = 0;
-	unsigned int minor = iminor(file->f_dentry->d_inode) - TIPAR_MINOR;
+	unsigned int minor = iminor(file->f_path.dentry->d_inode) - TIPAR_MINOR;
 	ssize_t retval = 0;
 	ssize_t n = 0;
 
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index b3cfc8bc613c..4044c864fdd4 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -109,13 +109,15 @@
 #define TTY_PARANOIA_CHECK 1
 #define CHECK_TTY_COUNT 1
 
-struct termios tty_std_termios = {	/* for the benefit of tty drivers  */
+struct ktermios tty_std_termios = {	/* for the benefit of tty drivers  */
 	.c_iflag = ICRNL | IXON,
 	.c_oflag = OPOST | ONLCR,
 	.c_cflag = B38400 | CS8 | CREAD | HUPCL,
 	.c_lflag = ISIG | ICANON | ECHO | ECHOE | ECHOK |
 		   ECHOCTL | ECHOKE | IEXTEN,
-	.c_cc = INIT_C_CC
+	.c_cc = INIT_C_CC,
+	.c_ispeed = 38400,
+	.c_ospeed = 38400
 };
 
 EXPORT_SYMBOL(tty_std_termios);
@@ -126,7 +128,7 @@ EXPORT_SYMBOL(tty_std_termios);
    
 LIST_HEAD(tty_drivers);			/* linked list of tty drivers */
 
-/* Semaphore to protect creating and releasing a tty. This is shared with
+/* Mutex to protect creating and releasing a tty. This is shared with
    vt.c for deeply disgusting hack reasons */
 DEFINE_MUTEX(tty_mutex);
 EXPORT_SYMBOL(tty_mutex);
@@ -250,7 +252,7 @@ static int check_tty_count(struct tty_struct *tty, const char *routine)
 				    "!= #fd's(%d) in %s\n",
 		       tty->name, tty->count, count, routine);
 		return count;
-       }	
+	}
 #endif
 	return 0;
 }
@@ -259,18 +261,6 @@ static int check_tty_count(struct tty_struct *tty, const char *routine)
  * Tty buffer allocation management
  */
 
-
-/**
- *	tty_buffer_free_all		-	free buffers used by a tty
- *	@tty: tty to free from
- *
- *	Remove all the buffers pending on a tty whether queued with data
- *	or in the free ring. Must be called when the tty is no longer in use
- *
- *	Locking: none
- */
-
-
 /**
  *	tty_buffer_free_all		-	free buffers used by a tty
  *	@tty: tty to free from
@@ -614,7 +604,7 @@ EXPORT_SYMBOL_GPL(tty_prepare_flip_string_flags);
  *	they are not on hot paths so a little discipline won't do 
  *	any harm.
  *
- *	Locking: takes termios_sem
+ *	Locking: takes termios_mutex
  */
  
 static void tty_set_termios_ldisc(struct tty_struct *tty, int num)
@@ -915,7 +905,7 @@ static void tty_ldisc_enable(struct tty_struct *tty)
  *	context.
  *
  *	Locking: takes tty_ldisc_lock.
- *		called functions take termios_sem
+ *		 called functions take termios_mutex
  */
  
 static int tty_set_ldisc(struct tty_struct *tty, int ldisc)
@@ -1251,6 +1241,22 @@ void tty_ldisc_flush(struct tty_struct *tty)
 }
 
 EXPORT_SYMBOL_GPL(tty_ldisc_flush);
+
+/**
+ *	tty_reset_termios	-	reset terminal state
+ *	@tty: tty to reset
+ *
+ *	Restore a terminal to the driver default state
+ */
+
+static void tty_reset_termios(struct tty_struct *tty)
+{
+	mutex_lock(&tty->termios_mutex);
+	*tty->termios = tty->driver->init_termios;
+	tty->termios->c_ispeed = tty_termios_input_baud_rate(tty->termios);
+	tty->termios->c_ospeed = tty_termios_baud_rate(tty->termios);
+	mutex_unlock(&tty->termios_mutex);
+}
 	
 /**
  *	do_tty_hangup		-	actual handler for hangup events
@@ -1267,12 +1273,12 @@ EXPORT_SYMBOL_GPL(tty_ldisc_flush);
  *
  *	Locking:
  *		BKL
- *		redirect lock for undoing redirection
- *		file list lock for manipulating list of ttys
- *		tty_ldisc_lock from called functions
- *		termios_sem resetting termios data
- *		tasklist_lock to walk task list for hangup event
- *
+ *		  redirect lock for undoing redirection
+ *		  file list lock for manipulating list of ttys
+ *		  tty_ldisc_lock from called functions
+ *		  termios_mutex resetting termios data
+ *		  tasklist_lock to walk task list for hangup event
+ *		    ->siglock to protect ->signal/->sighand
  */
 static void do_tty_hangup(struct work_struct *work)
 {
@@ -1339,11 +1345,7 @@ static void do_tty_hangup(struct work_struct *work)
 	 * N_TTY.
 	 */
 	if (tty->driver->flags & TTY_DRIVER_RESET_TERMIOS)
-	{
-		mutex_lock(&tty->termios_mutex);
-		*tty->termios = tty->driver->init_termios;
-		mutex_unlock(&tty->termios_mutex);
-	}
+		tty_reset_termios(tty);
 	
 	/* Defer ldisc switch */
 	/* tty_deferred_ldisc_switch(N_TTY);
@@ -1354,14 +1356,18 @@ static void do_tty_hangup(struct work_struct *work)
 	read_lock(&tasklist_lock);
 	if (tty->session > 0) {
 		do_each_task_pid(tty->session, PIDTYPE_SID, p) {
+			spin_lock_irq(&p->sighand->siglock);
 			if (p->signal->tty == tty)
 				p->signal->tty = NULL;
-			if (!p->signal->leader)
+			if (!p->signal->leader) {
+				spin_unlock_irq(&p->sighand->siglock);
 				continue;
-			group_send_sig_info(SIGHUP, SEND_SIG_PRIV, p);
-			group_send_sig_info(SIGCONT, SEND_SIG_PRIV, p);
+			}
+			__group_send_sig_info(SIGHUP, SEND_SIG_PRIV, p);
+			__group_send_sig_info(SIGCONT, SEND_SIG_PRIV, p);
 			if (tty->pgrp > 0)
 				p->signal->tty_old_pgrp = tty->pgrp;
+			spin_unlock_irq(&p->sighand->siglock);
 		} while_each_task_pid(tty->session, PIDTYPE_SID, p);
 	}
 	read_unlock(&tasklist_lock);
@@ -1453,6 +1459,14 @@ int tty_hung_up_p(struct file * filp)
 
 EXPORT_SYMBOL(tty_hung_up_p);
 
+static void session_clear_tty(pid_t session)
+{
+	struct task_struct *p;
+	do_each_task_pid(session, PIDTYPE_SID, p) {
+		proc_clear_tty(p);
+	} while_each_task_pid(session, PIDTYPE_SID, p);
+}
+
 /**
  *	disassociate_ctty	-	disconnect controlling tty
  *	@on_exit: true if exiting so need to "hang up" the session
@@ -1469,31 +1483,35 @@ EXPORT_SYMBOL(tty_hung_up_p);
  *	The argument on_exit is set to 1 if called when a process is
  *	exiting; it is 0 if called by the ioctl TIOCNOTTY.
  *
- *	Locking: tty_mutex is taken to protect current->signal->tty
+ *	Locking:
  *		BKL is taken for hysterical raisins
- *		Tasklist lock is taken (under tty_mutex) to walk process
- *		lists for the session.
+ *		  tty_mutex is taken to protect tty
+ *		  ->siglock is taken to protect ->signal/->sighand
+ *		  tasklist_lock is taken to walk process list for sessions
+ *		    ->siglock is taken to protect ->signal/->sighand
  */
 
 void disassociate_ctty(int on_exit)
 {
 	struct tty_struct *tty;
-	struct task_struct *p;
 	int tty_pgrp = -1;
+	int session;
 
 	lock_kernel();
 
 	mutex_lock(&tty_mutex);
-	tty = current->signal->tty;
+	tty = get_current_tty();
 	if (tty) {
 		tty_pgrp = tty->pgrp;
 		mutex_unlock(&tty_mutex);
+		/* XXX: here we race, there is nothing protecting tty */
 		if (on_exit && tty->driver->type != TTY_DRIVER_TYPE_PTY)
 			tty_vhangup(tty);
 	} else {
-		if (current->signal->tty_old_pgrp) {
-			kill_pg(current->signal->tty_old_pgrp, SIGHUP, on_exit);
-			kill_pg(current->signal->tty_old_pgrp, SIGCONT, on_exit);
+		pid_t old_pgrp = current->signal->tty_old_pgrp;
+		if (old_pgrp) {
+			kill_pg(old_pgrp, SIGHUP, on_exit);
+			kill_pg(old_pgrp, SIGCONT, on_exit);
 		}
 		mutex_unlock(&tty_mutex);
 		unlock_kernel();	
@@ -1505,19 +1523,29 @@ void disassociate_ctty(int on_exit)
 			kill_pg(tty_pgrp, SIGCONT, on_exit);
 	}
 
-	/* Must lock changes to tty_old_pgrp */
-	mutex_lock(&tty_mutex);
+	spin_lock_irq(&current->sighand->siglock);
 	current->signal->tty_old_pgrp = 0;
-	tty->session = 0;
-	tty->pgrp = -1;
+	session = process_session(current);
+	spin_unlock_irq(&current->sighand->siglock);
+
+	mutex_lock(&tty_mutex);
+	/* It is possible that do_tty_hangup has free'd this tty */
+	tty = get_current_tty();
+	if (tty) {
+		tty->session = 0;
+		tty->pgrp = 0;
+	} else {
+#ifdef TTY_DEBUG_HANGUP
+		printk(KERN_DEBUG "error attempted to write to tty [0x%p]"
+		       " = NULL", tty);
+#endif
+	}
+	mutex_unlock(&tty_mutex);
 
 	/* Now clear signal->tty under the lock */
 	read_lock(&tasklist_lock);
-	do_each_task_pid(current->signal->session, PIDTYPE_SID, p) {
-		p->signal->tty = NULL;
-	} while_each_task_pid(current->signal->session, PIDTYPE_SID, p);
+	session_clear_tty(session);
 	read_unlock(&tasklist_lock);
-	mutex_unlock(&tty_mutex);
 	unlock_kernel();
 }
 
@@ -1615,7 +1643,7 @@ static ssize_t tty_read(struct file * file, char __user * buf, size_t count,
 	struct tty_ldisc *ld;
 
 	tty = (struct tty_struct *)file->private_data;
-	inode = file->f_dentry->d_inode;
+	inode = file->f_path.dentry->d_inode;
 	if (tty_paranoia_check(tty, inode, "tty_read"))
 		return -EIO;
 	if (!tty || (test_bit(TTY_IO_ERROR, &tty->flags)))
@@ -1718,7 +1746,7 @@ static inline ssize_t do_tty_write(
 		cond_resched();
 	}
 	if (written) {
-		struct inode *inode = file->f_dentry->d_inode;
+		struct inode *inode = file->f_path.dentry->d_inode;
 		inode->i_mtime = current_fs_time(inode->i_sb);
 		ret = written;
 	}
@@ -1749,7 +1777,7 @@ static ssize_t tty_write(struct file * file, const char __user * buf, size_t cou
 			 loff_t *ppos)
 {
 	struct tty_struct * tty;
-	struct inode *inode = file->f_dentry->d_inode;
+	struct inode *inode = file->f_path.dentry->d_inode;
 	ssize_t ret;
 	struct tty_ldisc *ld;
 	
@@ -1856,8 +1884,8 @@ static int init_dev(struct tty_driver *driver, int idx,
 	struct tty_struct **ret_tty)
 {
 	struct tty_struct *tty, *o_tty;
-	struct termios *tp, **tp_loc, *o_tp, **o_tp_loc;
-	struct termios *ltp, **ltp_loc, *o_ltp, **o_ltp_loc;
+	struct ktermios *tp, **tp_loc, *o_tp, **o_tp_loc;
+	struct ktermios *ltp, **ltp_loc, *o_ltp, **o_ltp_loc;
 	int retval = 0;
 
 	/* check whether we're reopening an existing tty */
@@ -1904,7 +1932,7 @@ static int init_dev(struct tty_driver *driver, int idx,
 	}
 
 	if (!*tp_loc) {
-		tp = (struct termios *) kmalloc(sizeof(struct termios),
+		tp = (struct ktermios *) kmalloc(sizeof(struct ktermios),
 						GFP_KERNEL);
 		if (!tp)
 			goto free_mem_out;
@@ -1912,11 +1940,11 @@ static int init_dev(struct tty_driver *driver, int idx,
 	}
 
 	if (!*ltp_loc) {
-		ltp = (struct termios *) kmalloc(sizeof(struct termios),
+		ltp = (struct ktermios *) kmalloc(sizeof(struct ktermios),
 						 GFP_KERNEL);
 		if (!ltp)
 			goto free_mem_out;
-		memset(ltp, 0, sizeof(struct termios));
+		memset(ltp, 0, sizeof(struct ktermios));
 	}
 
 	if (driver->type == TTY_DRIVER_TYPE_PTY) {
@@ -1937,19 +1965,19 @@ static int init_dev(struct tty_driver *driver, int idx,
 		}
 
 		if (!*o_tp_loc) {
-			o_tp = (struct termios *)
-				kmalloc(sizeof(struct termios), GFP_KERNEL);
+			o_tp = (struct ktermios *)
+				kmalloc(sizeof(struct ktermios), GFP_KERNEL);
 			if (!o_tp)
 				goto free_mem_out;
 			*o_tp = driver->other->init_termios;
 		}
 
 		if (!*o_ltp_loc) {
-			o_ltp = (struct termios *)
-				kmalloc(sizeof(struct termios), GFP_KERNEL);
+			o_ltp = (struct ktermios *)
+				kmalloc(sizeof(struct ktermios), GFP_KERNEL);
 			if (!o_ltp)
 				goto free_mem_out;
-			memset(o_ltp, 0, sizeof(struct termios));
+			memset(o_ltp, 0, sizeof(struct ktermios));
 		}
 
 		/*
@@ -1988,6 +2016,9 @@ static int init_dev(struct tty_driver *driver, int idx,
 		*ltp_loc = ltp;
 	tty->termios = *tp_loc;
 	tty->termios_locked = *ltp_loc;
+	/* Compatibility until drivers always set this */
+	tty->termios->c_ispeed = tty_termios_input_baud_rate(tty->termios);
+	tty->termios->c_ospeed = tty_termios_baud_rate(tty->termios);
 	driver->refcount++;
 	tty->count++;
 
@@ -2090,7 +2121,7 @@ release_mem_out:
 static void release_mem(struct tty_struct *tty, int idx)
 {
 	struct tty_struct *o_tty;
-	struct termios *tp;
+	struct ktermios *tp;
 	int devpts = tty->driver->flags & TTY_DRIVER_DEVPTS_MEM;
 
 	if ((o_tty = tty->link) != NULL) {
@@ -2156,7 +2187,7 @@ static void release_dev(struct file * filp)
 	unsigned long flags;
 	
 	tty = (struct tty_struct *)filp->private_data;
-	if (tty_paranoia_check(tty, filp->f_dentry->d_inode, "release_dev"))
+	if (tty_paranoia_check(tty, filp->f_path.dentry->d_inode, "release_dev"))
 		return;
 
 	check_tty_count(tty, "release_dev");
@@ -2337,16 +2368,10 @@ static void release_dev(struct file * filp)
 	 * tty.
 	 */
 	if (tty_closing || o_tty_closing) {
-		struct task_struct *p;
-
 		read_lock(&tasklist_lock);
-		do_each_task_pid(tty->session, PIDTYPE_SID, p) {
-			p->signal->tty = NULL;
-		} while_each_task_pid(tty->session, PIDTYPE_SID, p);
+		session_clear_tty(tty->session);
 		if (o_tty)
-			do_each_task_pid(o_tty->session, PIDTYPE_SID, p) {
-				p->signal->tty = NULL;
-			} while_each_task_pid(o_tty->session, PIDTYPE_SID, p);
+			session_clear_tty(o_tty->session);
 		read_unlock(&tasklist_lock);
 	}
 
@@ -2443,9 +2468,9 @@ static void release_dev(struct file * filp)
  *	The termios state of a pty is reset on first open so that
  *	settings don't persist across reuse.
  *
- *	Locking: tty_mutex protects current->signal->tty, get_tty_driver and
- *		init_dev work. tty->count should protect the rest.
- *		task_lock is held to update task details for sessions
+ *	Locking: tty_mutex protects tty, get_tty_driver and init_dev work.
+ *		 tty->count should protect the rest.
+ *		 ->siglock protects ->signal/->sighand
  */
 
 static int tty_open(struct inode * inode, struct file * filp)
@@ -2467,12 +2492,13 @@ retry_open:
 	mutex_lock(&tty_mutex);
 
 	if (device == MKDEV(TTYAUX_MAJOR,0)) {
-		if (!current->signal->tty) {
+		tty = get_current_tty();
+		if (!tty) {
 			mutex_unlock(&tty_mutex);
 			return -ENXIO;
 		}
-		driver = current->signal->tty->driver;
-		index = current->signal->tty->index;
+		driver = tty->driver;
+		index = tty->index;
 		filp->f_flags |= O_NONBLOCK; /* Don't let /dev/tty block */
 		/* noctty = 1; */
 		goto got_driver;
@@ -2547,17 +2573,16 @@ got_driver:
 			filp->f_op = &tty_fops;
 		goto retry_open;
 	}
+
+	mutex_lock(&tty_mutex);
+	spin_lock_irq(&current->sighand->siglock);
 	if (!noctty &&
 	    current->signal->leader &&
 	    !current->signal->tty &&
-	    tty->session == 0) {
-	    	task_lock(current);
-		current->signal->tty = tty;
-		task_unlock(current);
-		current->signal->tty_old_pgrp = 0;
-		tty->session = current->signal->session;
-		tty->pgrp = process_group(current);
-	}
+	    tty->session == 0)
+		__proc_set_tty(current, tty);
+	spin_unlock_irq(&current->sighand->siglock);
+	mutex_unlock(&tty_mutex);
 	return 0;
 }
 
@@ -2672,7 +2697,7 @@ static unsigned int tty_poll(struct file * filp, poll_table * wait)
 	int ret = 0;
 
 	tty = (struct tty_struct *)filp->private_data;
-	if (tty_paranoia_check(tty, filp->f_dentry->d_inode, "tty_poll"))
+	if (tty_paranoia_check(tty, filp->f_path.dentry->d_inode, "tty_poll"))
 		return 0;
 		
 	ld = tty_ldisc_ref_wait(tty);
@@ -2688,7 +2713,7 @@ static int tty_fasync(int fd, struct file * filp, int on)
 	int retval;
 
 	tty = (struct tty_struct *)filp->private_data;
-	if (tty_paranoia_check(tty, filp->f_dentry->d_inode, "tty_fasync"))
+	if (tty_paranoia_check(tty, filp->f_path.dentry->d_inode, "tty_fasync"))
 		return 0;
 	
 	retval = fasync_helper(fd, filp, on, &tty->fasync);
@@ -2747,7 +2772,7 @@ static int tiocsti(struct tty_struct *tty, char __user *p)
  *
  *	Copies the kernel idea of the window size into the user buffer.
  *
- *	Locking: tty->termios_sem is taken to ensure the winsize data
+ *	Locking: tty->termios_mutex is taken to ensure the winsize data
  *		is consistent.
  */
 
@@ -2774,8 +2799,8 @@ static int tiocgwinsz(struct tty_struct *tty, struct winsize __user * arg)
  *	Locking:
  *		Called function use the console_sem is used to ensure we do
  *	not try and resize the console twice at once.
- *		The tty->termios_sem is used to ensure we don't double
- *	resize and get confused. Lock order - tty->termios.sem before
+ *		The tty->termios_mutex is used to ensure we don't double
+ *	resize and get confused. Lock order - tty->termios_mutex before
  *	console sem
  */
 
@@ -2880,25 +2905,28 @@ static int fionbio(struct file *file, int __user *p)
  *	leader to set this tty as the controlling tty for the session.
  *
  *	Locking:
- *		Takes tasklist lock internally to walk sessions
- *		Takes task_lock() when updating signal->tty
  *		Takes tty_mutex() to protect tty instance
- *
+ *		Takes tasklist_lock internally to walk sessions
+ *		Takes ->siglock() when updating signal->tty
  */
 
 static int tiocsctty(struct tty_struct *tty, int arg)
 {
-	struct task_struct *p;
-
+	int ret = 0;
 	if (current->signal->leader &&
-	    (current->signal->session == tty->session))
-		return 0;
+			(process_session(current) == tty->session))
+		return ret;
+
+	mutex_lock(&tty_mutex);
 	/*
 	 * The process must be a session leader and
 	 * not have a controlling tty already.
 	 */
-	if (!current->signal->leader || current->signal->tty)
-		return -EPERM;
+	if (!current->signal->leader || current->signal->tty) {
+		ret = -EPERM;
+		goto unlock;
+	}
+
 	if (tty->session > 0) {
 		/*
 		 * This tty is already the controlling
@@ -2908,24 +2936,18 @@ static int tiocsctty(struct tty_struct *tty, int arg)
 			/*
 			 * Steal it away
 			 */
-
 			read_lock(&tasklist_lock);
-			do_each_task_pid(tty->session, PIDTYPE_SID, p) {
-				p->signal->tty = NULL;
-			} while_each_task_pid(tty->session, PIDTYPE_SID, p);
+			session_clear_tty(tty->session);
 			read_unlock(&tasklist_lock);
-		} else
-			return -EPERM;
+		} else {
+			ret = -EPERM;
+			goto unlock;
+		}
 	}
-	mutex_lock(&tty_mutex);
-	task_lock(current);
-	current->signal->tty = tty;
-	task_unlock(current);
+	proc_set_tty(current, tty);
+unlock:
 	mutex_unlock(&tty_mutex);
-	current->signal->tty_old_pgrp = 0;
-	tty->session = current->signal->session;
-	tty->pgrp = process_group(current);
-	return 0;
+	return ret;
 }
 
 /**
@@ -2937,7 +2959,7 @@ static int tiocsctty(struct tty_struct *tty, int arg)
  *	Obtain the process group of the tty. If there is no process group
  *	return an error.
  *
- *	Locking: none. Reference to ->signal->tty is safe.
+ *	Locking: none. Reference to current->signal->tty is safe.
  */
 
 static int tiocgpgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t __user *p)
@@ -2974,13 +2996,13 @@ static int tiocspgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t
 		return retval;
 	if (!current->signal->tty ||
 	    (current->signal->tty != real_tty) ||
-	    (real_tty->session != current->signal->session))
+	    (real_tty->session != process_session(current)))
 		return -ENOTTY;
 	if (get_user(pgrp, p))
 		return -EFAULT;
 	if (pgrp < 0)
 		return -EINVAL;
-	if (session_of_pgrp(pgrp) != current->signal->session)
+	if (session_of_pgrp(pgrp) != process_session(current))
 		return -EPERM;
 	real_tty->pgrp = pgrp;
 	return 0;
@@ -2995,7 +3017,7 @@ static int tiocspgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t
  *	Obtain the session id of the tty. If there is no session
  *	return an error.
  *
- *	Locking: none. Reference to ->signal->tty is safe.
+ *	Locking: none. Reference to current->signal->tty is safe.
  */
 
 static int tiocgsid(struct tty_struct *tty, struct tty_struct *real_tty, pid_t __user *p)
@@ -3214,14 +3236,11 @@ int tty_ioctl(struct inode * inode, struct file * file,
 			clear_bit(TTY_EXCLUSIVE, &tty->flags);
 			return 0;
 		case TIOCNOTTY:
-			/* FIXME: taks lock or tty_mutex ? */
 			if (current->signal->tty != tty)
 				return -ENOTTY;
 			if (current->signal->leader)
 				disassociate_ctty(0);
-			task_lock(current);
-			current->signal->tty = NULL;
-			task_unlock(current);
+			proc_clear_tty(current);
 			return 0;
 		case TIOCSCTTY:
 			return tiocsctty(tty, arg);
@@ -3321,7 +3340,7 @@ static void __do_SAK(struct work_struct *work)
 	
 	if (!tty)
 		return;
-	session  = tty->session;
+	session = tty->session;
 	
 	/* We don't want an ldisc switch during this */
 	disc = tty_ldisc_ref(tty);
@@ -3336,7 +3355,7 @@ static void __do_SAK(struct work_struct *work)
 	/* Kill the entire session */
 	do_each_task_pid(session, PIDTYPE_SID, p) {
 		printk(KERN_NOTICE "SAK: killed process %d"
-			" (%s): p->signal->session==tty->session\n",
+			" (%s): process_session(p)==tty->session\n",
 			p->pid, p->comm);
 		send_sig(SIGKILL, p, 1);
 	} while_each_task_pid(session, PIDTYPE_SID, p);
@@ -3346,7 +3365,7 @@ static void __do_SAK(struct work_struct *work)
 	do_each_thread(g, p) {
 		if (p->signal->tty == tty) {
 			printk(KERN_NOTICE "SAK: killed process %d"
-			    " (%s): p->signal->session==tty->session\n",
+			    " (%s): process_session(p)==tty->session\n",
 			    p->pid, p->comm);
 			send_sig(SIGKILL, p, 1);
 			continue;
@@ -3456,84 +3475,6 @@ static void flush_to_ldisc(struct work_struct *work)
 	tty_ldisc_deref(disc);
 }
 
-/*
- * Routine which returns the baud rate of the tty
- *
- * Note that the baud_table needs to be kept in sync with the
- * include/asm/termbits.h file.
- */
-static int baud_table[] = {
-	0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,
-	9600, 19200, 38400, 57600, 115200, 230400, 460800,
-#ifdef __sparc__
-	76800, 153600, 307200, 614400, 921600
-#else
-	500000, 576000, 921600, 1000000, 1152000, 1500000, 2000000,
-	2500000, 3000000, 3500000, 4000000
-#endif
-};
-
-static int n_baud_table = ARRAY_SIZE(baud_table);
-
-/**
- *	tty_termios_baud_rate
- *	@termios: termios structure
- *
- *	Convert termios baud rate data into a speed. This should be called
- *	with the termios lock held if this termios is a terminal termios
- *	structure. May change the termios data.
- *
- *	Locking: none
- */
- 
-int tty_termios_baud_rate(struct termios *termios)
-{
-	unsigned int cbaud;
-	
-	cbaud = termios->c_cflag & CBAUD;
-
-	if (cbaud & CBAUDEX) {
-		cbaud &= ~CBAUDEX;
-
-		if (cbaud < 1 || cbaud + 15 > n_baud_table)
-			termios->c_cflag &= ~CBAUDEX;
-		else
-			cbaud += 15;
-	}
-	return baud_table[cbaud];
-}
-
-EXPORT_SYMBOL(tty_termios_baud_rate);
-
-/**
- *	tty_get_baud_rate	-	get tty bit rates
- *	@tty: tty to query
- *
- *	Returns the baud rate as an integer for this terminal. The
- *	termios lock must be held by the caller and the terminal bit
- *	flags may be updated.
- *
- *	Locking: none
- */
- 
-int tty_get_baud_rate(struct tty_struct *tty)
-{
-	int baud = tty_termios_baud_rate(tty->termios);
-
-	if (baud == 38400 && tty->alt_speed) {
-		if (!tty->warned) {
-			printk(KERN_WARNING "Use of setserial/setrocket to "
-					    "set SPD_* flags is deprecated\n");
-			tty->warned = 1;
-		}
-		baud = tty->alt_speed;
-	}
-	
-	return baud;
-}
-
-EXPORT_SYMBOL(tty_get_baud_rate);
-
 /**
  *	tty_flip_buffer_push	-	terminal
  *	@tty: tty to push
@@ -3756,8 +3697,8 @@ int tty_register_driver(struct tty_driver *driver)
 
 	if (p) {
 		driver->ttys = (struct tty_struct **)p;
-		driver->termios = (struct termios **)(p + driver->num);
-		driver->termios_locked = (struct termios **)(p + driver->num * 2);
+		driver->termios = (struct ktermios **)(p + driver->num);
+		driver->termios_locked = (struct ktermios **)(p + driver->num * 2);
 	} else {
 		driver->ttys = NULL;
 		driver->termios = NULL;
@@ -3796,7 +3737,7 @@ EXPORT_SYMBOL(tty_register_driver);
 int tty_unregister_driver(struct tty_driver *driver)
 {
 	int i;
-	struct termios *tp;
+	struct ktermios *tp;
 	void *p;
 
 	if (driver->refcount)
@@ -3834,9 +3775,52 @@ int tty_unregister_driver(struct tty_driver *driver)
 	cdev_del(&driver->cdev);
 	return 0;
 }
-
 EXPORT_SYMBOL(tty_unregister_driver);
 
+dev_t tty_devnum(struct tty_struct *tty)
+{
+	return MKDEV(tty->driver->major, tty->driver->minor_start) + tty->index;
+}
+EXPORT_SYMBOL(tty_devnum);
+
+void proc_clear_tty(struct task_struct *p)
+{
+	spin_lock_irq(&p->sighand->siglock);
+	p->signal->tty = NULL;
+	spin_unlock_irq(&p->sighand->siglock);
+}
+EXPORT_SYMBOL(proc_clear_tty);
+
+void __proc_set_tty(struct task_struct *tsk, struct tty_struct *tty)
+{
+	if (tty) {
+		tty->session = process_session(tsk);
+		tty->pgrp = process_group(tsk);
+	}
+	tsk->signal->tty = tty;
+	tsk->signal->tty_old_pgrp = 0;
+}
+
+void proc_set_tty(struct task_struct *tsk, struct tty_struct *tty)
+{
+	spin_lock_irq(&tsk->sighand->siglock);
+	__proc_set_tty(tsk, tty);
+	spin_unlock_irq(&tsk->sighand->siglock);
+}
+
+struct tty_struct *get_current_tty(void)
+{
+	struct tty_struct *tty;
+	WARN_ON_ONCE(!mutex_is_locked(&tty_mutex));
+	tty = current->signal->tty;
+	/*
+	 * session->tty can be changed/cleared from under us, make sure we
+	 * issue the load. The obtained pointer, when not NULL, is valid as
+	 * long as we hold tty_mutex.
+	 */
+	barrier();
+	return tty;
+}
 
 /*
  * Initialize the console device. This is called *early*, so
diff --git a/drivers/char/tty_ioctl.c b/drivers/char/tty_ioctl.c
index 3b6fa7b0be8b..dee47f40c6a3 100644
--- a/drivers/char/tty_ioctl.c
+++ b/drivers/char/tty_ioctl.c
@@ -36,6 +36,7 @@
 #define TERMIOS_FLUSH	1
 #define TERMIOS_WAIT	2
 #define TERMIOS_TERMIO	4
+#define TERMIOS_OLD	8
 
 
 /**
@@ -84,9 +85,9 @@ stop_waiting:
 
 EXPORT_SYMBOL(tty_wait_until_sent);
 
-static void unset_locked_termios(struct termios *termios,
-				 struct termios *old,
-				 struct termios *locked)
+static void unset_locked_termios(struct ktermios *termios,
+				 struct ktermios *old,
+				 struct ktermios *locked)
 {
 	int	i;
 	
@@ -105,8 +106,204 @@ static void unset_locked_termios(struct termios *termios,
 	for (i=0; i < NCCS; i++)
 		termios->c_cc[i] = locked->c_cc[i] ?
 			old->c_cc[i] : termios->c_cc[i];
+	/* FIXME: What should we do for i/ospeed */
 }
 
+/*
+ * Routine which returns the baud rate of the tty
+ *
+ * Note that the baud_table needs to be kept in sync with the
+ * include/asm/termbits.h file.
+ */
+static const speed_t baud_table[] = {
+	0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,
+	9600, 19200, 38400, 57600, 115200, 230400, 460800,
+#ifdef __sparc__
+	76800, 153600, 307200, 614400, 921600
+#else
+	500000, 576000, 921600, 1000000, 1152000, 1500000, 2000000,
+	2500000, 3000000, 3500000, 4000000
+#endif
+};
+
+#ifndef __sparc__
+static const tcflag_t baud_bits[] = {
+	B0, B50, B75, B110, B134, B150, B200, B300, B600,
+	B1200, B1800, B2400, B4800, B9600, B19200, B38400,
+	B57600, B115200, B230400, B460800, B500000, B576000,
+	B921600, B1000000, B1152000, B1500000, B2000000, B2500000,
+	B3000000, B3500000, B4000000
+};
+#else
+static const tcflag_t baud_bits[] = {
+	B0, B50, B75, B110, B134, B150, B200, B300, B600,
+	B1200, B1800, B2400, B4800, B9600, B19200, B38400,
+	B57600, B115200, B230400, B460800, B76800, B153600,
+	B307200, B614400, B921600
+};
+#endif
+
+static int n_baud_table = ARRAY_SIZE(baud_table);
+
+/**
+ *	tty_termios_baud_rate
+ *	@termios: termios structure
+ *
+ *	Convert termios baud rate data into a speed. This should be called
+ *	with the termios lock held if this termios is a terminal termios
+ *	structure. May change the termios data. Device drivers can call this
+ *	function but should use ->c_[io]speed directly as they are updated.
+ *
+ *	Locking: none
+ */
+
+speed_t tty_termios_baud_rate(struct ktermios *termios)
+{
+	unsigned int cbaud;
+
+	cbaud = termios->c_cflag & CBAUD;
+
+#ifdef BOTHER
+	/* Magic token for arbitary speed via c_ispeed/c_ospeed */
+	if (cbaud == BOTHER)
+		return termios->c_ospeed;
+#endif
+	if (cbaud & CBAUDEX) {
+		cbaud &= ~CBAUDEX;
+
+		if (cbaud < 1 || cbaud + 15 > n_baud_table)
+			termios->c_cflag &= ~CBAUDEX;
+		else
+			cbaud += 15;
+	}
+	return baud_table[cbaud];
+}
+
+EXPORT_SYMBOL(tty_termios_baud_rate);
+
+/**
+ *	tty_termios_input_baud_rate
+ *	@termios: termios structure
+ *
+ *	Convert termios baud rate data into a speed. This should be called
+ *	with the termios lock held if this termios is a terminal termios
+ *	structure. May change the termios data. Device drivers can call this
+ *	function but should use ->c_[io]speed directly as they are updated.
+ *
+ *	Locking: none
+ */
+
+speed_t tty_termios_input_baud_rate(struct ktermios *termios)
+{
+#ifdef IBSHIFT
+	unsigned int cbaud = (termios->c_cflag >> IBSHIFT) & CBAUD;
+
+	if (cbaud == B0)
+		return tty_termios_baud_rate(termios);
+
+	/* Magic token for arbitary speed via c_ispeed*/
+	if (cbaud == BOTHER)
+		return termios->c_ispeed;
+
+	if (cbaud & CBAUDEX) {
+		cbaud &= ~CBAUDEX;
+
+		if (cbaud < 1 || cbaud + 15 > n_baud_table)
+			termios->c_cflag &= ~(CBAUDEX << IBSHIFT);
+		else
+			cbaud += 15;
+	}
+	return baud_table[cbaud];
+#else
+	return tty_termios_baud_rate(termios);
+#endif
+}
+
+EXPORT_SYMBOL(tty_termios_input_baud_rate);
+
+#ifdef BOTHER
+
+/**
+ *	tty_termios_encode_baud_rate
+ *	@termios: termios structure
+ *	@ispeed: input speed
+ *	@ospeed: output speed
+ *
+ *	Encode the speeds set into the passed termios structure. This is
+ *	used as a library helper for drivers os that they can report back
+ *	the actual speed selected when it differs from the speed requested
+ *
+ *	For now input and output speed must agree.
+ *
+ *	Locking: Caller should hold termios lock. This is already held
+ *	when calling this function from the driver termios handler.
+ */
+
+void tty_termios_encode_baud_rate(struct ktermios *termios, speed_t ibaud, speed_t obaud)
+{
+	int i = 0;
+	int ifound = 0, ofound = 0;
+
+	termios->c_ispeed = ibaud;
+	termios->c_ospeed = obaud;
+
+	termios->c_cflag &= ~CBAUD;
+	/* Identical speed means no input encoding (ie B0 << IBSHIFT)*/
+	if (termios->c_ispeed == termios->c_ospeed)
+		ifound = 1;
+
+	do {
+		if (obaud == baud_table[i]) {
+			termios->c_cflag |= baud_bits[i];
+			ofound = 1;
+			/* So that if ibaud == obaud we don't set it */
+			continue;
+		}
+		if (ibaud == baud_table[i]) {
+			termios->c_cflag |= (baud_bits[i] << IBSHIFT);
+			ifound = 1;
+		}
+	}
+	while(++i < n_baud_table);
+	if (!ofound)
+		termios->c_cflag |= BOTHER;
+	if (!ifound)
+		termios->c_cflag |= (BOTHER << IBSHIFT);
+}
+
+EXPORT_SYMBOL_GPL(tty_termios_encode_baud_rate);
+
+#endif
+
+/**
+ *	tty_get_baud_rate	-	get tty bit rates
+ *	@tty: tty to query
+ *
+ *	Returns the baud rate as an integer for this terminal. The
+ *	termios lock must be held by the caller and the terminal bit
+ *	flags may be updated.
+ *
+ *	Locking: none
+ */
+
+speed_t tty_get_baud_rate(struct tty_struct *tty)
+{
+	speed_t baud = tty_termios_baud_rate(tty->termios);
+
+	if (baud == 38400 && tty->alt_speed) {
+		if (!tty->warned) {
+			printk(KERN_WARNING "Use of setserial/setrocket to "
+					    "set SPD_* flags is deprecated\n");
+			tty->warned = 1;
+		}
+		baud = tty->alt_speed;
+	}
+
+	return baud;
+}
+
+EXPORT_SYMBOL(tty_get_baud_rate);
+
 /**
  *	change_termios		-	update termios values
  *	@tty: tty to update
@@ -119,10 +316,10 @@ static void unset_locked_termios(struct termios *termios,
  *	Locking: termios_sem
  */
 
-static void change_termios(struct tty_struct * tty, struct termios * new_termios)
+static void change_termios(struct tty_struct * tty, struct ktermios * new_termios)
 {
 	int canon_change;
-	struct termios old_termios = *tty->termios;
+	struct ktermios old_termios = *tty->termios;
 	struct tty_ldisc *ld;
 	
 	/*
@@ -195,23 +392,39 @@ static void change_termios(struct tty_struct * tty, struct termios * new_termios
 
 static int set_termios(struct tty_struct * tty, void __user *arg, int opt)
 {
-	struct termios tmp_termios;
+	struct ktermios tmp_termios;
 	struct tty_ldisc *ld;
 	int retval = tty_check_change(tty);
 
 	if (retval)
 		return retval;
 
+	memcpy(&tmp_termios, tty->termios, sizeof(struct ktermios));
+
 	if (opt & TERMIOS_TERMIO) {
-		memcpy(&tmp_termios, tty->termios, sizeof(struct termios));
 		if (user_termio_to_kernel_termios(&tmp_termios,
 						(struct termio __user *)arg))
 			return -EFAULT;
+#ifdef TCGETS2
+	} else if (opt & TERMIOS_OLD) {
+		if (user_termios_to_kernel_termios_1(&tmp_termios,
+						(struct termios __user *)arg))
+			return -EFAULT;
 	} else {
 		if (user_termios_to_kernel_termios(&tmp_termios,
-						(struct termios __user *)arg))
+						(struct termios2 __user *)arg))
 			return -EFAULT;
 	}
+#else
+	} else if (user_termios_to_kernel_termios(&tmp_termios,
+					(struct termios __user *)arg))
+		return -EFAULT;
+#endif
+
+	/* If old style Bfoo values are used then load c_ispeed/c_ospeed with the real speed
+	   so its unconditionally usable */
+	tmp_termios.c_ispeed = tty_termios_input_baud_rate(&tmp_termios);
+	tmp_termios.c_ospeed = tty_termios_baud_rate(&tmp_termios);
 
 	ld = tty_ldisc_ref(tty);
 	
@@ -286,8 +499,8 @@ static int get_sgttyb(struct tty_struct * tty, struct sgttyb __user * sgttyb)
 	struct sgttyb tmp;
 
 	mutex_lock(&tty->termios_mutex);
-	tmp.sg_ispeed = 0;
-	tmp.sg_ospeed = 0;
+	tmp.sg_ispeed = tty->termios->c_ispeed;
+	tmp.sg_ospeed = tty->termios->c_ospeed;
 	tmp.sg_erase = tty->termios->c_cc[VERASE];
 	tmp.sg_kill = tty->termios->c_cc[VKILL];
 	tmp.sg_flags = get_sgflags(tty);
@@ -296,7 +509,7 @@ static int get_sgttyb(struct tty_struct * tty, struct sgttyb __user * sgttyb)
 	return copy_to_user(sgttyb, &tmp, sizeof(tmp)) ? -EFAULT : 0;
 }
 
-static void set_sgflags(struct termios * termios, int flags)
+static void set_sgflags(struct ktermios * termios, int flags)
 {
 	termios->c_iflag = ICRNL | IXON;
 	termios->c_oflag = 0;
@@ -337,7 +550,7 @@ static int set_sgttyb(struct tty_struct * tty, struct sgttyb __user * sgttyb)
 {
 	int retval;
 	struct sgttyb tmp;
-	struct termios termios;
+	struct ktermios termios;
 
 	retval = tty_check_change(tty);
 	if (retval)
@@ -351,6 +564,10 @@ static int set_sgttyb(struct tty_struct * tty, struct sgttyb __user * sgttyb)
 	termios.c_cc[VERASE] = tmp.sg_erase;
 	termios.c_cc[VKILL] = tmp.sg_kill;
 	set_sgflags(&termios, tmp.sg_flags);
+	/* Try and encode into Bfoo format */
+#ifdef BOTHER
+	tty_termios_encode_baud_rate(&termios, termios.c_ispeed, termios.c_ospeed);
+#endif
 	mutex_unlock(&tty->termios_mutex);
 	change_termios(tty, &termios);
 	return 0;
@@ -481,16 +698,33 @@ int n_tty_ioctl(struct tty_struct * tty, struct file * file,
 		case TIOCSLTC:
 			return set_ltchars(real_tty, p);
 #endif
+		case TCSETSF:
+			return set_termios(real_tty, p,  TERMIOS_FLUSH | TERMIOS_WAIT | TERMIOS_OLD);
+		case TCSETSW:
+			return set_termios(real_tty, p, TERMIOS_WAIT | TERMIOS_OLD);
+		case TCSETS:
+			return set_termios(real_tty, p, TERMIOS_OLD);
+#ifndef TCGETS2
 		case TCGETS:
 			if (kernel_termios_to_user_termios((struct termios __user *)arg, real_tty->termios))
 				return -EFAULT;
 			return 0;
-		case TCSETSF:
+#else
+		case TCGETS:
+			if (kernel_termios_to_user_termios_1((struct termios __user *)arg, real_tty->termios))
+				return -EFAULT;
+			return 0;
+		case TCGETS2:
+			if (kernel_termios_to_user_termios((struct termios2 __user *)arg, real_tty->termios))
+				return -EFAULT;
+			return 0;
+		case TCSETSF2:
 			return set_termios(real_tty, p,  TERMIOS_FLUSH | TERMIOS_WAIT);
-		case TCSETSW:
+		case TCSETSW2:
 			return set_termios(real_tty, p, TERMIOS_WAIT);
-		case TCSETS:
+		case TCSETS2:
 			return set_termios(real_tty, p, 0);
+#endif
 		case TCGETA:
 			return get_termio(real_tty, p);
 		case TCSETAF:
diff --git a/drivers/char/vc_screen.c b/drivers/char/vc_screen.c
index f442b574b44a..26776517f04c 100644
--- a/drivers/char/vc_screen.c
+++ b/drivers/char/vc_screen.c
@@ -72,7 +72,7 @@ static loff_t vcs_lseek(struct file *file, loff_t offset, int orig)
 	int size;
 
 	down(&con_buf_sem);
-	size = vcs_size(file->f_dentry->d_inode);
+	size = vcs_size(file->f_path.dentry->d_inode);
 	switch (orig) {
 		default:
 			up(&con_buf_sem);
@@ -98,7 +98,7 @@ static loff_t vcs_lseek(struct file *file, loff_t offset, int orig)
 static ssize_t
 vcs_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
 {
-	struct inode *inode = file->f_dentry->d_inode;
+	struct inode *inode = file->f_path.dentry->d_inode;
 	unsigned int currcons = iminor(inode);
 	struct vc_data *vc;
 	long pos;
@@ -271,7 +271,7 @@ unlock_out:
 static ssize_t
 vcs_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
 {
-	struct inode *inode = file->f_dentry->d_inode;
+	struct inode *inode = file->f_path.dentry->d_inode;
 	unsigned int currcons = iminor(inode);
 	struct vc_data *vc;
 	long pos;
diff --git a/drivers/char/viotape.c b/drivers/char/viotape.c
index 73c78bf75d7f..94d79cb8ce8d 100644
--- a/drivers/char/viotape.c
+++ b/drivers/char/viotape.c
@@ -442,7 +442,7 @@ static ssize_t viotap_write(struct file *file, const char *buf,
 	if (op == NULL)
 		return -ENOMEM;
 
-	get_dev_info(file->f_dentry->d_inode, &devi);
+	get_dev_info(file->f_path.dentry->d_inode, &devi);
 
 	/*
 	 * We need to make sure we can send a request.  We use
@@ -532,7 +532,7 @@ static ssize_t viotap_read(struct file *file, char *buf, size_t count,
 	if (op == NULL)
 		return -ENOMEM;
 
-	get_dev_info(file->f_dentry->d_inode, &devi);
+	get_dev_info(file->f_path.dentry->d_inode, &devi);
 
 	/*
 	 * We need to make sure we can send a request.  We use
@@ -612,7 +612,7 @@ static int viotap_ioctl(struct inode *inode, struct file *file,
 	if (op == NULL)
 		return -ENOMEM;
 
-	get_dev_info(file->f_dentry->d_inode, &devi);
+	get_dev_info(file->f_path.dentry->d_inode, &devi);
 
 	down(&reqSem);
 
@@ -777,7 +777,7 @@ static int viotap_open(struct inode *inode, struct file *file)
 	if (op == NULL)
 		return -ENOMEM;
 
-	get_dev_info(file->f_dentry->d_inode, &devi);
+	get_dev_info(file->f_path.dentry->d_inode, &devi);
 
 	/* Note: We currently only support one mode! */
 	if ((devi.devno >= viotape_numdev) || (devi.mode)) {
@@ -822,7 +822,7 @@ static int viotap_release(struct inode *inode, struct file *file)
 		return -ENOMEM;
 	init_completion(&op->com);
 
-	get_dev_info(file->f_dentry->d_inode, &devi);
+	get_dev_info(file->f_path.dentry->d_inode, &devi);
 
 	if (devi.devno >= viotape_numdev) {
 		ret = -ENODEV;
diff --git a/drivers/char/vme_scc.c b/drivers/char/vme_scc.c
index d0b94dd1af6d..e01317cb1a0e 100644
--- a/drivers/char/vme_scc.c
+++ b/drivers/char/vme_scc.c
@@ -153,6 +153,8 @@ static int scc_init_drivers(void)
 	scc_driver->init_termios = tty_std_termios;
 	scc_driver->init_termios.c_cflag =
 	  B9600 | CS8 | CREAD | HUPCL | CLOCAL;
+	scc_driver->init_termios.c_ispeed = 9600;
+	scc_driver->init_termios.c_ospeed = 9600;
 	scc_driver->flags = TTY_DRIVER_REAL_RAW;
 	tty_set_operations(scc_driver, &scc_ops);
 
diff --git a/drivers/char/vr41xx_giu.c b/drivers/char/vr41xx_giu.c
index 8e7949305171..a744dad9cf45 100644
--- a/drivers/char/vr41xx_giu.c
+++ b/drivers/char/vr41xx_giu.c
@@ -506,7 +506,7 @@ static ssize_t gpio_read(struct file *file, char __user *buf, size_t len,
 	unsigned int pin;
 	char value = '0';
 
-	pin = iminor(file->f_dentry->d_inode);
+	pin = iminor(file->f_path.dentry->d_inode);
 	if (pin >= giu_nr_pins)
 		return -EBADF;
 
@@ -530,7 +530,7 @@ static ssize_t gpio_write(struct file *file, const char __user *data,
 	char c;
 	int retval = 0;
 
-	pin = iminor(file->f_dentry->d_inode);
+	pin = iminor(file->f_path.dentry->d_inode);
 	if (pin >= giu_nr_pins)
 		return -EBADF;
 
diff --git a/drivers/clocksource/acpi_pm.c b/drivers/clocksource/acpi_pm.c
index 7fcb77a9d011..8ab61ef97b4c 100644
--- a/drivers/clocksource/acpi_pm.c
+++ b/drivers/clocksource/acpi_pm.c
@@ -142,6 +142,39 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_LE,
 			acpi_pm_check_graylist);
 #endif
 
+#ifndef CONFIG_X86_64
+#include "mach_timer.h"
+#define PMTMR_EXPECTED_RATE \
+  ((CALIBRATE_LATCH * (PMTMR_TICKS_PER_SEC >> 10)) / (CLOCK_TICK_RATE>>10))
+/*
+ * Some boards have the PMTMR running way too fast. We check
+ * the PMTMR rate against PIT channel 2 to catch these cases.
+ */
+static int verify_pmtmr_rate(void)
+{
+	u32 value1, value2;
+	unsigned long count, delta;
+
+	mach_prepare_counter();
+	value1 = read_pmtmr();
+	mach_countup(&count);
+	value2 = read_pmtmr();
+	delta = (value2 - value1) & ACPI_PM_MASK;
+
+	/* Check that the PMTMR delta is within 5% of what we expect */
+	if (delta < (PMTMR_EXPECTED_RATE * 19) / 20 ||
+	    delta > (PMTMR_EXPECTED_RATE * 21) / 20) {
+		printk(KERN_INFO "PM-Timer running at invalid rate: %lu%% "
+			"of normal - aborting.\n",
+			100UL * delta / PMTMR_EXPECTED_RATE);
+		return -1;
+	}
+
+	return 0;
+}
+#else
+#define verify_pmtmr_rate() (0)
+#endif
 
 static int __init init_acpi_pm_clocksource(void)
 {
@@ -173,6 +206,9 @@ static int __init init_acpi_pm_clocksource(void)
 	return -ENODEV;
 
 pm_good:
+	if (verify_pmtmr_rate() != 0)
+		return -ENODEV;
+
 	return clocksource_register(&clocksource_acpi_pm);
 }
 
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
new file mode 100644
index 000000000000..96d4a0bb2203
--- /dev/null
+++ b/drivers/hid/Kconfig
@@ -0,0 +1,18 @@
+#
+# HID driver configuration
+#
+menu "HID Devices"
+	depends on INPUT
+
+config HID
+	tristate "Generic HID support"
+	default y
+	---help---
+	  Say Y here if you want generic HID support to connect keyboards,
+	  mice, joysticks, graphic tablets, or any other HID based devices
+	  to your computer. You also need to select particular types of
+	  HID devices you want to compile support for, in the particular
+	  driver menu (USB, Bluetooth)
+
+endmenu
+
diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile
new file mode 100644
index 000000000000..6432392110bf
--- /dev/null
+++ b/drivers/hid/Makefile
@@ -0,0 +1,15 @@
+#
+# Makefile for the HID driver
+#
+
+# Multipart objects.
+hid-objs	:= hid-core.o hid-input.o
+
+# Optional parts of multipart objects.
+
+obj-$(CONFIG_HID)		+= hid.o
+
+ifeq ($(CONFIG_INPUT_DEBUG),y)
+EXTRA_CFLAGS += -DDEBUG
+endif
+
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
new file mode 100644
index 000000000000..18c2b3cf6bcc
--- /dev/null
+++ b/drivers/hid/hid-core.c
@@ -0,0 +1,1003 @@
+/*
+ *  HID support for Linux
+ *
+ *  Copyright (c) 1999 Andreas Gal
+ *  Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz>
+ *  Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc
+ *  Copyright (c) 2006 Jiri Kosina
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ */
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/list.h>
+#include <linux/mm.h>
+#include <linux/smp_lock.h>
+#include <linux/spinlock.h>
+#include <asm/unaligned.h>
+#include <asm/byteorder.h>
+#include <linux/input.h>
+#include <linux/wait.h>
+
+#undef DEBUG
+#undef DEBUG_DATA
+
+#include <linux/hid.h>
+#include <linux/hiddev.h>
+
+/*
+ * Version Information
+ */
+
+#define DRIVER_VERSION "v2.6"
+#define DRIVER_AUTHOR "Andreas Gal, Vojtech Pavlik"
+#define DRIVER_DESC "USB HID core driver"
+#define DRIVER_LICENSE "GPL"
+
+/*
+ * Module parameters.
+ */
+
+static unsigned int hid_mousepoll_interval;
+module_param_named(mousepoll, hid_mousepoll_interval, uint, 0644);
+MODULE_PARM_DESC(mousepoll, "Polling interval of mice");
+
+/*
+ * Register a new report for a device.
+ */
+
+static struct hid_report *hid_register_report(struct hid_device *device, unsigned type, unsigned id)
+{
+	struct hid_report_enum *report_enum = device->report_enum + type;
+	struct hid_report *report;
+
+	if (report_enum->report_id_hash[id])
+		return report_enum->report_id_hash[id];
+
+	if (!(report = kzalloc(sizeof(struct hid_report), GFP_KERNEL)))
+		return NULL;
+
+	if (id != 0)
+		report_enum->numbered = 1;
+
+	report->id = id;
+	report->type = type;
+	report->size = 0;
+	report->device = device;
+	report_enum->report_id_hash[id] = report;
+
+	list_add_tail(&report->list, &report_enum->report_list);
+
+	return report;
+}
+
+/*
+ * Register a new field for this report.
+ */
+
+static struct hid_field *hid_register_field(struct hid_report *report, unsigned usages, unsigned values)
+{
+	struct hid_field *field;
+
+	if (report->maxfield == HID_MAX_FIELDS) {
+		dbg("too many fields in report");
+		return NULL;
+	}
+
+	if (!(field = kzalloc(sizeof(struct hid_field) + usages * sizeof(struct hid_usage)
+		+ values * sizeof(unsigned), GFP_KERNEL))) return NULL;
+
+	field->index = report->maxfield++;
+	report->field[field->index] = field;
+	field->usage = (struct hid_usage *)(field + 1);
+	field->value = (unsigned *)(field->usage + usages);
+	field->report = report;
+
+	return field;
+}
+
+/*
+ * Open a collection. The type/usage is pushed on the stack.
+ */
+
+static int open_collection(struct hid_parser *parser, unsigned type)
+{
+	struct hid_collection *collection;
+	unsigned usage;
+
+	usage = parser->local.usage[0];
+
+	if (parser->collection_stack_ptr == HID_COLLECTION_STACK_SIZE) {
+		dbg("collection stack overflow");
+		return -1;
+	}
+
+	if (parser->device->maxcollection == parser->device->collection_size) {
+		collection = kmalloc(sizeof(struct hid_collection) *
+				parser->device->collection_size * 2, GFP_KERNEL);
+		if (collection == NULL) {
+			dbg("failed to reallocate collection array");
+			return -1;
+		}
+		memcpy(collection, parser->device->collection,
+			sizeof(struct hid_collection) *
+			parser->device->collection_size);
+		memset(collection + parser->device->collection_size, 0,
+			sizeof(struct hid_collection) *
+			parser->device->collection_size);
+		kfree(parser->device->collection);
+		parser->device->collection = collection;
+		parser->device->collection_size *= 2;
+	}
+
+	parser->collection_stack[parser->collection_stack_ptr++] =
+		parser->device->maxcollection;
+
+	collection = parser->device->collection +
+		parser->device->maxcollection++;
+	collection->type = type;
+	collection->usage = usage;
+	collection->level = parser->collection_stack_ptr - 1;
+
+	if (type == HID_COLLECTION_APPLICATION)
+		parser->device->maxapplication++;
+
+	return 0;
+}
+
+/*
+ * Close a collection.
+ */
+
+static int close_collection(struct hid_parser *parser)
+{
+	if (!parser->collection_stack_ptr) {
+		dbg("collection stack underflow");
+		return -1;
+	}
+	parser->collection_stack_ptr--;
+	return 0;
+}
+
+/*
+ * Climb up the stack, search for the specified collection type
+ * and return the usage.
+ */
+
+static unsigned hid_lookup_collection(struct hid_parser *parser, unsigned type)
+{
+	int n;
+	for (n = parser->collection_stack_ptr - 1; n >= 0; n--)
+		if (parser->device->collection[parser->collection_stack[n]].type == type)
+			return parser->device->collection[parser->collection_stack[n]].usage;
+	return 0; /* we know nothing about this usage type */
+}
+
+/*
+ * Add a usage to the temporary parser table.
+ */
+
+static int hid_add_usage(struct hid_parser *parser, unsigned usage)
+{
+	if (parser->local.usage_index >= HID_MAX_USAGES) {
+		dbg("usage index exceeded");
+		return -1;
+	}
+	parser->local.usage[parser->local.usage_index] = usage;
+	parser->local.collection_index[parser->local.usage_index] =
+		parser->collection_stack_ptr ?
+		parser->collection_stack[parser->collection_stack_ptr - 1] : 0;
+	parser->local.usage_index++;
+	return 0;
+}
+
+/*
+ * Register a new field for this report.
+ */
+
+static int hid_add_field(struct hid_parser *parser, unsigned report_type, unsigned flags)
+{
+	struct hid_report *report;
+	struct hid_field *field;
+	int usages;
+	unsigned offset;
+	int i;
+
+	if (!(report = hid_register_report(parser->device, report_type, parser->global.report_id))) {
+		dbg("hid_register_report failed");
+		return -1;
+	}
+
+	if (parser->global.logical_maximum < parser->global.logical_minimum) {
+		dbg("logical range invalid %d %d", parser->global.logical_minimum, parser->global.logical_maximum);
+		return -1;
+	}
+
+	offset = report->size;
+	report->size += parser->global.report_size * parser->global.report_count;
+
+	if (!parser->local.usage_index) /* Ignore padding fields */
+		return 0;
+
+	usages = max_t(int, parser->local.usage_index, parser->global.report_count);
+
+	if ((field = hid_register_field(report, usages, parser->global.report_count)) == NULL)
+		return 0;
+
+	field->physical = hid_lookup_collection(parser, HID_COLLECTION_PHYSICAL);
+	field->logical = hid_lookup_collection(parser, HID_COLLECTION_LOGICAL);
+	field->application = hid_lookup_collection(parser, HID_COLLECTION_APPLICATION);
+
+	for (i = 0; i < usages; i++) {
+		int j = i;
+		/* Duplicate the last usage we parsed if we have excess values */
+		if (i >= parser->local.usage_index)
+			j = parser->local.usage_index - 1;
+		field->usage[i].hid = parser->local.usage[j];
+		field->usage[i].collection_index =
+			parser->local.collection_index[j];
+	}
+
+	field->maxusage = usages;
+	field->flags = flags;
+	field->report_offset = offset;
+	field->report_type = report_type;
+	field->report_size = parser->global.report_size;
+	field->report_count = parser->global.report_count;
+	field->logical_minimum = parser->global.logical_minimum;
+	field->logical_maximum = parser->global.logical_maximum;
+	field->physical_minimum = parser->global.physical_minimum;
+	field->physical_maximum = parser->global.physical_maximum;
+	field->unit_exponent = parser->global.unit_exponent;
+	field->unit = parser->global.unit;
+
+	return 0;
+}
+
+/*
+ * Read data value from item.
+ */
+
+static u32 item_udata(struct hid_item *item)
+{
+	switch (item->size) {
+		case 1: return item->data.u8;
+		case 2: return item->data.u16;
+		case 4: return item->data.u32;
+	}
+	return 0;
+}
+
+static s32 item_sdata(struct hid_item *item)
+{
+	switch (item->size) {
+		case 1: return item->data.s8;
+		case 2: return item->data.s16;
+		case 4: return item->data.s32;
+	}
+	return 0;
+}
+
+/*
+ * Process a global item.
+ */
+
+static int hid_parser_global(struct hid_parser *parser, struct hid_item *item)
+{
+	switch (item->tag) {
+
+		case HID_GLOBAL_ITEM_TAG_PUSH:
+
+			if (parser->global_stack_ptr == HID_GLOBAL_STACK_SIZE) {
+				dbg("global enviroment stack overflow");
+				return -1;
+			}
+
+			memcpy(parser->global_stack + parser->global_stack_ptr++,
+				&parser->global, sizeof(struct hid_global));
+			return 0;
+
+		case HID_GLOBAL_ITEM_TAG_POP:
+
+			if (!parser->global_stack_ptr) {
+				dbg("global enviroment stack underflow");
+				return -1;
+			}
+
+			memcpy(&parser->global, parser->global_stack + --parser->global_stack_ptr,
+				sizeof(struct hid_global));
+			return 0;
+
+		case HID_GLOBAL_ITEM_TAG_USAGE_PAGE:
+			parser->global.usage_page = item_udata(item);
+			return 0;
+
+		case HID_GLOBAL_ITEM_TAG_LOGICAL_MINIMUM:
+			parser->global.logical_minimum = item_sdata(item);
+			return 0;
+
+		case HID_GLOBAL_ITEM_TAG_LOGICAL_MAXIMUM:
+			if (parser->global.logical_minimum < 0)
+				parser->global.logical_maximum = item_sdata(item);
+			else
+				parser->global.logical_maximum = item_udata(item);
+			return 0;
+
+		case HID_GLOBAL_ITEM_TAG_PHYSICAL_MINIMUM:
+			parser->global.physical_minimum = item_sdata(item);
+			return 0;
+
+		case HID_GLOBAL_ITEM_TAG_PHYSICAL_MAXIMUM:
+			if (parser->global.physical_minimum < 0)
+				parser->global.physical_maximum = item_sdata(item);
+			else
+				parser->global.physical_maximum = item_udata(item);
+			return 0;
+
+		case HID_GLOBAL_ITEM_TAG_UNIT_EXPONENT:
+			parser->global.unit_exponent = item_sdata(item);
+			return 0;
+
+		case HID_GLOBAL_ITEM_TAG_UNIT:
+			parser->global.unit = item_udata(item);
+			return 0;
+
+		case HID_GLOBAL_ITEM_TAG_REPORT_SIZE:
+			if ((parser->global.report_size = item_udata(item)) > 32) {
+				dbg("invalid report_size %d", parser->global.report_size);
+				return -1;
+			}
+			return 0;
+
+		case HID_GLOBAL_ITEM_TAG_REPORT_COUNT:
+			if ((parser->global.report_count = item_udata(item)) > HID_MAX_USAGES) {
+				dbg("invalid report_count %d", parser->global.report_count);
+				return -1;
+			}
+			return 0;
+
+		case HID_GLOBAL_ITEM_TAG_REPORT_ID:
+			if ((parser->global.report_id = item_udata(item)) == 0) {
+				dbg("report_id 0 is invalid");
+				return -1;
+			}
+			return 0;
+
+		default:
+			dbg("unknown global tag 0x%x", item->tag);
+			return -1;
+	}
+}
+
+/*
+ * Process a local item.
+ */
+
+static int hid_parser_local(struct hid_parser *parser, struct hid_item *item)
+{
+	__u32 data;
+	unsigned n;
+
+	if (item->size == 0) {
+		dbg("item data expected for local item");
+		return -1;
+	}
+
+	data = item_udata(item);
+
+	switch (item->tag) {
+
+		case HID_LOCAL_ITEM_TAG_DELIMITER:
+
+			if (data) {
+				/*
+				 * We treat items before the first delimiter
+				 * as global to all usage sets (branch 0).
+				 * In the moment we process only these global
+				 * items and the first delimiter set.
+				 */
+				if (parser->local.delimiter_depth != 0) {
+					dbg("nested delimiters");
+					return -1;
+				}
+				parser->local.delimiter_depth++;
+				parser->local.delimiter_branch++;
+			} else {
+				if (parser->local.delimiter_depth < 1) {
+					dbg("bogus close delimiter");
+					return -1;
+				}
+				parser->local.delimiter_depth--;
+			}
+			return 1;
+
+		case HID_LOCAL_ITEM_TAG_USAGE:
+
+			if (parser->local.delimiter_branch > 1) {
+				dbg("alternative usage ignored");
+				return 0;
+			}
+
+			if (item->size <= 2)
+				data = (parser->global.usage_page << 16) + data;
+
+			return hid_add_usage(parser, data);
+
+		case HID_LOCAL_ITEM_TAG_USAGE_MINIMUM:
+
+			if (parser->local.delimiter_branch > 1) {
+				dbg("alternative usage ignored");
+				return 0;
+			}
+
+			if (item->size <= 2)
+				data = (parser->global.usage_page << 16) + data;
+
+			parser->local.usage_minimum = data;
+			return 0;
+
+		case HID_LOCAL_ITEM_TAG_USAGE_MAXIMUM:
+
+			if (parser->local.delimiter_branch > 1) {
+				dbg("alternative usage ignored");
+				return 0;
+			}
+
+			if (item->size <= 2)
+				data = (parser->global.usage_page << 16) + data;
+
+			for (n = parser->local.usage_minimum; n <= data; n++)
+				if (hid_add_usage(parser, n)) {
+					dbg("hid_add_usage failed\n");
+					return -1;
+				}
+			return 0;
+
+		default:
+
+			dbg("unknown local item tag 0x%x", item->tag);
+			return 0;
+	}
+	return 0;
+}
+
+/*
+ * Process a main item.
+ */
+
+static int hid_parser_main(struct hid_parser *parser, struct hid_item *item)
+{
+	__u32 data;
+	int ret;
+
+	data = item_udata(item);
+
+	switch (item->tag) {
+		case HID_MAIN_ITEM_TAG_BEGIN_COLLECTION:
+			ret = open_collection(parser, data & 0xff);
+			break;
+		case HID_MAIN_ITEM_TAG_END_COLLECTION:
+			ret = close_collection(parser);
+			break;
+		case HID_MAIN_ITEM_TAG_INPUT:
+			ret = hid_add_field(parser, HID_INPUT_REPORT, data);
+			break;
+		case HID_MAIN_ITEM_TAG_OUTPUT:
+			ret = hid_add_field(parser, HID_OUTPUT_REPORT, data);
+			break;
+		case HID_MAIN_ITEM_TAG_FEATURE:
+			ret = hid_add_field(parser, HID_FEATURE_REPORT, data);
+			break;
+		default:
+			dbg("unknown main item tag 0x%x", item->tag);
+			ret = 0;
+	}
+
+	memset(&parser->local, 0, sizeof(parser->local));	/* Reset the local parser environment */
+
+	return ret;
+}
+
+/*
+ * Process a reserved item.
+ */
+
+static int hid_parser_reserved(struct hid_parser *parser, struct hid_item *item)
+{
+	dbg("reserved item type, tag 0x%x", item->tag);
+	return 0;
+}
+
+/*
+ * Free a report and all registered fields. The field->usage and
+ * field->value table's are allocated behind the field, so we need
+ * only to free(field) itself.
+ */
+
+static void hid_free_report(struct hid_report *report)
+{
+	unsigned n;
+
+	for (n = 0; n < report->maxfield; n++)
+		kfree(report->field[n]);
+	kfree(report);
+}
+
+/*
+ * Free a device structure, all reports, and all fields.
+ */
+
+void hid_free_device(struct hid_device *device)
+{
+	unsigned i,j;
+
+	for (i = 0; i < HID_REPORT_TYPES; i++) {
+		struct hid_report_enum *report_enum = device->report_enum + i;
+
+		for (j = 0; j < 256; j++) {
+			struct hid_report *report = report_enum->report_id_hash[j];
+			if (report)
+				hid_free_report(report);
+		}
+	}
+
+	kfree(device->rdesc);
+	kfree(device);
+}
+EXPORT_SYMBOL_GPL(hid_free_device);
+
+/*
+ * Fetch a report description item from the data stream. We support long
+ * items, though they are not used yet.
+ */
+
+static u8 *fetch_item(__u8 *start, __u8 *end, struct hid_item *item)
+{
+	u8 b;
+
+	if ((end - start) <= 0)
+		return NULL;
+
+	b = *start++;
+
+	item->type = (b >> 2) & 3;
+	item->tag  = (b >> 4) & 15;
+
+	if (item->tag == HID_ITEM_TAG_LONG) {
+
+		item->format = HID_ITEM_FORMAT_LONG;
+
+		if ((end - start) < 2)
+			return NULL;
+
+		item->size = *start++;
+		item->tag  = *start++;
+
+		if ((end - start) < item->size)
+			return NULL;
+
+		item->data.longdata = start;
+		start += item->size;
+		return start;
+	}
+
+	item->format = HID_ITEM_FORMAT_SHORT;
+	item->size = b & 3;
+
+	switch (item->size) {
+
+		case 0:
+			return start;
+
+		case 1:
+			if ((end - start) < 1)
+				return NULL;
+			item->data.u8 = *start++;
+			return start;
+
+		case 2:
+			if ((end - start) < 2)
+				return NULL;
+			item->data.u16 = le16_to_cpu(get_unaligned((__le16*)start));
+			start = (__u8 *)((__le16 *)start + 1);
+			return start;
+
+		case 3:
+			item->size++;
+			if ((end - start) < 4)
+				return NULL;
+			item->data.u32 = le32_to_cpu(get_unaligned((__le32*)start));
+			start = (__u8 *)((__le32 *)start + 1);
+			return start;
+	}
+
+	return NULL;
+}
+
+/*
+ * Parse a report description into a hid_device structure. Reports are
+ * enumerated, fields are attached to these reports.
+ */
+
+struct hid_device *hid_parse_report(__u8 *start, unsigned size)
+{
+	struct hid_device *device;
+	struct hid_parser *parser;
+	struct hid_item item;
+	__u8 *end;
+	unsigned i;
+	static int (*dispatch_type[])(struct hid_parser *parser,
+				      struct hid_item *item) = {
+		hid_parser_main,
+		hid_parser_global,
+		hid_parser_local,
+		hid_parser_reserved
+	};
+
+	if (!(device = kzalloc(sizeof(struct hid_device), GFP_KERNEL)))
+		return NULL;
+
+	if (!(device->collection = kzalloc(sizeof(struct hid_collection) *
+				   HID_DEFAULT_NUM_COLLECTIONS, GFP_KERNEL))) {
+		kfree(device);
+		return NULL;
+	}
+	device->collection_size = HID_DEFAULT_NUM_COLLECTIONS;
+
+	for (i = 0; i < HID_REPORT_TYPES; i++)
+		INIT_LIST_HEAD(&device->report_enum[i].report_list);
+
+	if (!(device->rdesc = (__u8 *)kmalloc(size, GFP_KERNEL))) {
+		kfree(device->collection);
+		kfree(device);
+		return NULL;
+	}
+	memcpy(device->rdesc, start, size);
+	device->rsize = size;
+
+	if (!(parser = kzalloc(sizeof(struct hid_parser), GFP_KERNEL))) {
+		kfree(device->rdesc);
+		kfree(device->collection);
+		kfree(device);
+		return NULL;
+	}
+	parser->device = device;
+
+	end = start + size;
+	while ((start = fetch_item(start, end, &item)) != NULL) {
+
+		if (item.format != HID_ITEM_FORMAT_SHORT) {
+			dbg("unexpected long global item");
+			kfree(device->collection);
+			hid_free_device(device);
+			kfree(parser);
+			return NULL;
+		}
+
+		if (dispatch_type[item.type](parser, &item)) {
+			dbg("item %u %u %u %u parsing failed\n",
+				item.format, (unsigned)item.size, (unsigned)item.type, (unsigned)item.tag);
+			kfree(device->collection);
+			hid_free_device(device);
+			kfree(parser);
+			return NULL;
+		}
+
+		if (start == end) {
+			if (parser->collection_stack_ptr) {
+				dbg("unbalanced collection at end of report description");
+				kfree(device->collection);
+				hid_free_device(device);
+				kfree(parser);
+				return NULL;
+			}
+			if (parser->local.delimiter_depth) {
+				dbg("unbalanced delimiter at end of report description");
+				kfree(device->collection);
+				hid_free_device(device);
+				kfree(parser);
+				return NULL;
+			}
+			kfree(parser);
+			return device;
+		}
+	}
+
+	dbg("item fetching failed at offset %d\n", (int)(end - start));
+	kfree(device->collection);
+	hid_free_device(device);
+	kfree(parser);
+	return NULL;
+}
+EXPORT_SYMBOL_GPL(hid_parse_report);
+
+/*
+ * Convert a signed n-bit integer to signed 32-bit integer. Common
+ * cases are done through the compiler, the screwed things has to be
+ * done by hand.
+ */
+
+static s32 snto32(__u32 value, unsigned n)
+{
+	switch (n) {
+		case 8:  return ((__s8)value);
+		case 16: return ((__s16)value);
+		case 32: return ((__s32)value);
+	}
+	return value & (1 << (n - 1)) ? value | (-1 << n) : value;
+}
+
+/*
+ * Convert a signed 32-bit integer to a signed n-bit integer.
+ */
+
+static u32 s32ton(__s32 value, unsigned n)
+{
+	s32 a = value >> (n - 1);
+	if (a && a != -1)
+		return value < 0 ? 1 << (n - 1) : (1 << (n - 1)) - 1;
+	return value & ((1 << n) - 1);
+}
+
+/*
+ * Extract/implement a data field from/to a little endian report (bit array).
+ *
+ * Code sort-of follows HID spec:
+ *     http://www.usb.org/developers/devclass_docs/HID1_11.pdf
+ *
+ * While the USB HID spec allows unlimited length bit fields in "report
+ * descriptors", most devices never use more than 16 bits.
+ * One model of UPS is claimed to report "LINEV" as a 32-bit field.
+ * Search linux-kernel and linux-usb-devel archives for "hid-core extract".
+ */
+
+static __inline__ __u32 extract(__u8 *report, unsigned offset, unsigned n)
+{
+	u64 x;
+
+	WARN_ON(n > 32);
+
+	report += offset >> 3;  /* adjust byte index */
+	offset &= 7;            /* now only need bit offset into one byte */
+	x = get_unaligned((u64 *) report);
+	x = le64_to_cpu(x);
+	x = (x >> offset) & ((1ULL << n) - 1);  /* extract bit field */
+	return (u32) x;
+}
+
+/*
+ * "implement" : set bits in a little endian bit stream.
+ * Same concepts as "extract" (see comments above).
+ * The data mangled in the bit stream remains in little endian
+ * order the whole time. It make more sense to talk about
+ * endianness of register values by considering a register
+ * a "cached" copy of the little endiad bit stream.
+ */
+static __inline__ void implement(__u8 *report, unsigned offset, unsigned n, __u32 value)
+{
+	u64 x;
+	u64 m = (1ULL << n) - 1;
+
+	WARN_ON(n > 32);
+
+	WARN_ON(value > m);
+	value &= m;
+
+	report += offset >> 3;
+	offset &= 7;
+
+	x = get_unaligned((u64 *)report);
+	x &= cpu_to_le64(~(m << offset));
+	x |= cpu_to_le64(((u64) value) << offset);
+	put_unaligned(x, (u64 *) report);
+}
+
+/*
+ * Search an array for a value.
+ */
+
+static __inline__ int search(__s32 *array, __s32 value, unsigned n)
+{
+	while (n--) {
+		if (*array++ == value)
+			return 0;
+	}
+	return -1;
+}
+
+static void hid_process_event(struct hid_device *hid, struct hid_field *field, struct hid_usage *usage, __s32 value, int interrupt)
+{
+	hid_dump_input(usage, value);
+	if (hid->claimed & HID_CLAIMED_INPUT)
+		hidinput_hid_event(hid, field, usage, value);
+	if (hid->claimed & HID_CLAIMED_HIDDEV && interrupt && hid->hiddev_hid_event)
+		hid->hiddev_hid_event(hid, field, usage, value);
+}
+
+/*
+ * Analyse a received field, and fetch the data from it. The field
+ * content is stored for next report processing (we do differential
+ * reporting to the layer).
+ */
+
+void hid_input_field(struct hid_device *hid, struct hid_field *field, __u8 *data, int interrupt)
+{
+	unsigned n;
+	unsigned count = field->report_count;
+	unsigned offset = field->report_offset;
+	unsigned size = field->report_size;
+	__s32 min = field->logical_minimum;
+	__s32 max = field->logical_maximum;
+	__s32 *value;
+
+	if (!(value = kmalloc(sizeof(__s32) * count, GFP_ATOMIC)))
+		return;
+
+	for (n = 0; n < count; n++) {
+
+			value[n] = min < 0 ? snto32(extract(data, offset + n * size, size), size) :
+						    extract(data, offset + n * size, size);
+
+			if (!(field->flags & HID_MAIN_ITEM_VARIABLE) /* Ignore report if ErrorRollOver */
+			    && value[n] >= min && value[n] <= max
+			    && field->usage[value[n] - min].hid == HID_UP_KEYBOARD + 1)
+				goto exit;
+	}
+
+	for (n = 0; n < count; n++) {
+
+		if (HID_MAIN_ITEM_VARIABLE & field->flags) {
+			hid_process_event(hid, field, &field->usage[n], value[n], interrupt);
+			continue;
+		}
+
+		if (field->value[n] >= min && field->value[n] <= max
+			&& field->usage[field->value[n] - min].hid
+			&& search(value, field->value[n], count))
+				hid_process_event(hid, field, &field->usage[field->value[n] - min], 0, interrupt);
+
+		if (value[n] >= min && value[n] <= max
+			&& field->usage[value[n] - min].hid
+			&& search(field->value, value[n], count))
+				hid_process_event(hid, field, &field->usage[value[n] - min], 1, interrupt);
+	}
+
+	memcpy(field->value, value, count * sizeof(__s32));
+exit:
+	kfree(value);
+}
+EXPORT_SYMBOL_GPL(hid_input_field);
+
+/*
+ * Output the field into the report.
+ */
+
+static void hid_output_field(struct hid_field *field, __u8 *data)
+{
+	unsigned count = field->report_count;
+	unsigned offset = field->report_offset;
+	unsigned size = field->report_size;
+	unsigned n;
+
+	for (n = 0; n < count; n++) {
+		if (field->logical_minimum < 0)	/* signed values */
+			implement(data, offset + n * size, size, s32ton(field->value[n], size));
+		else				/* unsigned values */
+			implement(data, offset + n * size, size, field->value[n]);
+	}
+}
+
+/*
+ * Create a report.
+ */
+
+void hid_output_report(struct hid_report *report, __u8 *data)
+{
+	unsigned n;
+
+	if (report->id > 0)
+		*data++ = report->id;
+
+	for (n = 0; n < report->maxfield; n++)
+		hid_output_field(report->field[n], data);
+}
+EXPORT_SYMBOL_GPL(hid_output_report);
+
+/*
+ * Set a field value. The report this field belongs to has to be
+ * created and transferred to the device, to set this value in the
+ * device.
+ */
+
+int hid_set_field(struct hid_field *field, unsigned offset, __s32 value)
+{
+	unsigned size = field->report_size;
+
+	hid_dump_input(field->usage + offset, value);
+
+	if (offset >= field->report_count) {
+		dbg("offset (%d) exceeds report_count (%d)", offset, field->report_count);
+		hid_dump_field(field, 8);
+		return -1;
+	}
+	if (field->logical_minimum < 0) {
+		if (value != snto32(s32ton(value, size), size)) {
+			dbg("value %d is out of range", value);
+			return -1;
+		}
+	}
+	field->value[offset] = value;
+	return 0;
+}
+EXPORT_SYMBOL_GPL(hid_set_field);
+
+int hid_input_report(struct hid_device *hid, int type, u8 *data, int size, int interrupt)
+{
+	struct hid_report_enum *report_enum = hid->report_enum + type;
+	struct hid_report *report;
+	int n, rsize;
+
+	if (!hid)
+		return -ENODEV;
+
+	if (!size) {
+		dbg("empty report");
+		return -1;
+	}
+
+#ifdef DEBUG_DATA
+	printk(KERN_DEBUG __FILE__ ": report (size %u) (%snumbered)\n", len, report_enum->numbered ? "" : "un");
+#endif
+
+	n = 0;                          /* Normally report number is 0 */
+	if (report_enum->numbered) {    /* Device uses numbered reports, data[0] is report number */
+		n = *data++;
+		size--;
+	}
+
+#ifdef DEBUG_DATA
+	{
+		int i;
+		printk(KERN_DEBUG __FILE__ ": report %d (size %u) = ", n, size);
+		for (i = 0; i < size; i++)
+			printk(" %02x", data[i]);
+		printk("\n");
+	}
+#endif
+
+	if (!(report = report_enum->report_id_hash[n])) {
+		dbg("undefined report_id %d received", n);
+		return -1;
+	}
+
+	rsize = ((report->size - 1) >> 3) + 1;
+
+	if (size < rsize) {
+		dbg("report %d is too short, (%d < %d)", report->id, size, rsize);
+		return -1;
+	}
+
+	if ((hid->claimed & HID_CLAIMED_HIDDEV) && hid->hiddev_report_event)
+		hid->hiddev_report_event(hid, report);
+
+	for (n = 0; n < report->maxfield; n++)
+		hid_input_field(hid, report->field[n], data, interrupt);
+
+	if (hid->claimed & HID_CLAIMED_INPUT)
+		hidinput_report_event(hid, report);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(hid_input_report);
+
+MODULE_LICENSE(DRIVER_LICENSE);
+
diff --git a/drivers/usb/input/hid-input.c b/drivers/hid/hid-input.c
index 3a7e5fbff025..14cdf09316ce 100644
--- a/drivers/usb/input/hid-input.c
+++ b/drivers/hid/hid-input.c
@@ -2,8 +2,9 @@
  * $Id: hid-input.c,v 1.2 2002/04/23 00:59:25 rdamazio Exp $
  *
  *  Copyright (c) 2000-2001 Vojtech Pavlik
+ *  Copyright (c) 2006 Jiri Kosina
  *
- *  USB HID to Linux Input mapping
+ *  HID to Linux Input mapping
  */
 
 /*
@@ -33,7 +34,7 @@
 
 #undef DEBUG
 
-#include "hid.h"
+#include <linux/hid.h>
 
 #define unk	KEY_UNKNOWN
 
@@ -81,42 +82,42 @@ struct hidinput_key_translation {
 
 static struct hidinput_key_translation powerbook_fn_keys[] = {
 	{ KEY_BACKSPACE, KEY_DELETE },
-	{ KEY_F1,	KEY_BRIGHTNESSDOWN,	POWERBOOK_FLAG_FKEY },
-	{ KEY_F2,	KEY_BRIGHTNESSUP,	POWERBOOK_FLAG_FKEY },
-	{ KEY_F3,	KEY_MUTE,		POWERBOOK_FLAG_FKEY },
-	{ KEY_F4,	KEY_VOLUMEDOWN,		POWERBOOK_FLAG_FKEY },
-	{ KEY_F5,	KEY_VOLUMEUP,		POWERBOOK_FLAG_FKEY },
-	{ KEY_F6,	KEY_NUMLOCK,		POWERBOOK_FLAG_FKEY },
-	{ KEY_F7,	KEY_SWITCHVIDEOMODE,	POWERBOOK_FLAG_FKEY },
-	{ KEY_F8,	KEY_KBDILLUMTOGGLE,	POWERBOOK_FLAG_FKEY },
-	{ KEY_F9,	KEY_KBDILLUMDOWN,	POWERBOOK_FLAG_FKEY },
-	{ KEY_F10,	KEY_KBDILLUMUP,		POWERBOOK_FLAG_FKEY },
-	{ KEY_UP,	KEY_PAGEUP },
-	{ KEY_DOWN,	KEY_PAGEDOWN },
-	{ KEY_LEFT,	KEY_HOME },
-	{ KEY_RIGHT,	KEY_END },
+	{ KEY_F1,       KEY_BRIGHTNESSDOWN,     POWERBOOK_FLAG_FKEY },
+	{ KEY_F2,       KEY_BRIGHTNESSUP,       POWERBOOK_FLAG_FKEY },
+	{ KEY_F3,       KEY_MUTE,               POWERBOOK_FLAG_FKEY },
+	{ KEY_F4,       KEY_VOLUMEDOWN,         POWERBOOK_FLAG_FKEY },
+	{ KEY_F5,       KEY_VOLUMEUP,           POWERBOOK_FLAG_FKEY },
+	{ KEY_F6,       KEY_NUMLOCK,            POWERBOOK_FLAG_FKEY },
+	{ KEY_F7,       KEY_SWITCHVIDEOMODE,    POWERBOOK_FLAG_FKEY },
+	{ KEY_F8,       KEY_KBDILLUMTOGGLE,     POWERBOOK_FLAG_FKEY },
+	{ KEY_F9,       KEY_KBDILLUMDOWN,       POWERBOOK_FLAG_FKEY },
+	{ KEY_F10,      KEY_KBDILLUMUP,         POWERBOOK_FLAG_FKEY },
+	{ KEY_UP,       KEY_PAGEUP },
+	{ KEY_DOWN,     KEY_PAGEDOWN },
+	{ KEY_LEFT,     KEY_HOME },
+	{ KEY_RIGHT,    KEY_END },
 	{ }
 };
 
 static struct hidinput_key_translation powerbook_numlock_keys[] = {
-	{ KEY_J,	KEY_KP1 },
-	{ KEY_K,	KEY_KP2 },
-	{ KEY_L,	KEY_KP3 },
-	{ KEY_U,	KEY_KP4 },
-	{ KEY_I,	KEY_KP5 },
-	{ KEY_O,	KEY_KP6 },
-	{ KEY_7,	KEY_KP7 },
-	{ KEY_8,	KEY_KP8 },
-	{ KEY_9,	KEY_KP9 },
-	{ KEY_M,	KEY_KP0 },
-	{ KEY_DOT,	KEY_KPDOT },
-	{ KEY_SLASH,	KEY_KPPLUS },
+	{ KEY_J,        KEY_KP1 },
+	{ KEY_K,        KEY_KP2 },
+	{ KEY_L,        KEY_KP3 },
+	{ KEY_U,        KEY_KP4 },
+	{ KEY_I,        KEY_KP5 },
+	{ KEY_O,        KEY_KP6 },
+	{ KEY_7,        KEY_KP7 },
+	{ KEY_8,        KEY_KP8 },
+	{ KEY_9,        KEY_KP9 },
+	{ KEY_M,        KEY_KP0 },
+	{ KEY_DOT,      KEY_KPDOT },
+	{ KEY_SLASH,    KEY_KPPLUS },
 	{ KEY_SEMICOLON, KEY_KPMINUS },
-	{ KEY_P,	KEY_KPASTERISK },
-	{ KEY_MINUS,	KEY_KPEQUAL },
-	{ KEY_0,	KEY_KPSLASH },
-	{ KEY_F6,	KEY_NUMLOCK },
-	{ KEY_KPENTER,	KEY_KPENTER },
+	{ KEY_P,        KEY_KPASTERISK },
+	{ KEY_MINUS,    KEY_KPEQUAL },
+	{ KEY_0,        KEY_KPSLASH },
+	{ KEY_F6,       KEY_NUMLOCK },
+	{ KEY_KPENTER,  KEY_KPENTER },
 	{ KEY_BACKSPACE, KEY_BACKSPACE },
 	{ }
 };
@@ -127,11 +128,6 @@ static struct hidinput_key_translation powerbook_iso_keyboard[] = {
 	{ }
 };
 
-static int usbhid_pb_fnmode = 1;
-module_param_named(pb_fnmode, usbhid_pb_fnmode, int, 0644);
-MODULE_PARM_DESC(pb_fnmode,
-	"Mode of fn key on PowerBooks (0 = disabled, 1 = fkeyslast, 2 = fkeysfirst)");
-
 static struct hidinput_key_translation *find_translation(struct hidinput_key_translation *table, u16 from)
 {
 	struct hidinput_key_translation *trans;
@@ -145,7 +141,7 @@ static struct hidinput_key_translation *find_translation(struct hidinput_key_tra
 }
 
 static int hidinput_pb_event(struct hid_device *hid, struct input_dev *input,
-			     struct hid_usage *usage, __s32 value)
+		struct hid_usage *usage, __s32 value)
 {
 	struct hidinput_key_translation *trans;
 
@@ -158,7 +154,7 @@ static int hidinput_pb_event(struct hid_device *hid, struct input_dev *input,
 		return 1;
 	}
 
-	if (usbhid_pb_fnmode) {
+	if (hid->pb_fnmode) {
 		int do_translate;
 
 		trans = find_translation(powerbook_fn_keys, usage->code);
@@ -167,8 +163,8 @@ static int hidinput_pb_event(struct hid_device *hid, struct input_dev *input,
 				do_translate = 1;
 			else if (trans->flags & POWERBOOK_FLAG_FKEY)
 				do_translate =
-					(usbhid_pb_fnmode == 2 &&  (hid->quirks & HID_QUIRK_POWERBOOK_FN_ON)) ||
-					(usbhid_pb_fnmode == 1 && !(hid->quirks & HID_QUIRK_POWERBOOK_FN_ON));
+					(hid->pb_fnmode == 2 &&  (hid->quirks & HID_QUIRK_POWERBOOK_FN_ON)) ||
+					(hid->pb_fnmode == 1 && !(hid->quirks & HID_QUIRK_POWERBOOK_FN_ON));
 			else
 				do_translate = (hid->quirks & HID_QUIRK_POWERBOOK_FN_ON);
 
@@ -185,7 +181,7 @@ static int hidinput_pb_event(struct hid_device *hid, struct input_dev *input,
 		}
 
 		if (test_bit(usage->code, hid->pb_pressed_numlock) ||
-		    test_bit(LED_NUML, input->led)) {
+				test_bit(LED_NUML, input->led)) {
 			trans = find_translation(powerbook_numlock_keys, usage->code);
 
 			if (trans) {
@@ -227,10 +223,11 @@ static void hidinput_pb_setup(struct input_dev *input)
 
 	for (trans = powerbook_iso_keyboard; trans->from; trans++)
 		set_bit(trans->to, input->keybit);
+
 }
 #else
 static inline int hidinput_pb_event(struct hid_device *hid, struct input_dev *input,
-				    struct hid_usage *usage, __s32 value)
+		struct hid_usage *usage, __s32 value)
 {
 	return 0;
 }
@@ -582,7 +579,7 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
 		goto ignore;
 
 	if ((device->quirks & HID_QUIRK_BAD_RELATIVE_KEYS) &&
-	    usage->type == EV_KEY && (field->flags & HID_MAIN_ITEM_RELATIVE))
+		usage->type == EV_KEY && (field->flags & HID_MAIN_ITEM_RELATIVE))
 		field->flags &= ~HID_MAIN_ITEM_RELATIVE;
 
 	set_bit(usage->type, input->evbit);
@@ -724,8 +721,9 @@ void hidinput_report_event(struct hid_device *hid, struct hid_report *report)
 	list_for_each_entry(hidinput, &hid->inputs, list)
 		input_sync(hidinput->input);
 }
+EXPORT_SYMBOL_GPL(hidinput_report_event);
 
-static int hidinput_find_field(struct hid_device *hid, unsigned int type, unsigned int code, struct hid_field **field)
+int hidinput_find_field(struct hid_device *hid, unsigned int type, unsigned int code, struct hid_field **field)
 {
 	struct hid_report *report;
 	int i, j;
@@ -740,41 +738,7 @@ static int hidinput_find_field(struct hid_device *hid, unsigned int type, unsign
 	}
 	return -1;
 }
-
-static int hidinput_input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
-{
-	struct hid_device *hid = dev->private;
-	struct hid_field *field;
-	int offset;
-
-	if (type == EV_FF)
-		return input_ff_event(dev, type, code, value);
-
-	if (type != EV_LED)
-		return -1;
-
-	if ((offset = hidinput_find_field(hid, type, code, &field)) == -1) {
-		warn("event field not found");
-		return -1;
-	}
-
-	hid_set_field(field, offset, value);
-	hid_submit_report(hid, field->report, USB_DIR_OUT);
-
-	return 0;
-}
-
-static int hidinput_open(struct input_dev *dev)
-{
-	struct hid_device *hid = dev->private;
-	return hid_open(hid);
-}
-
-static void hidinput_close(struct input_dev *dev)
-{
-	struct hid_device *hid = dev->private;
-	hid_close(hid);
-}
+EXPORT_SYMBOL_GPL(hidinput_find_field);
 
 /*
  * Register the input device; print a message.
@@ -784,7 +748,6 @@ static void hidinput_close(struct input_dev *dev)
 
 int hidinput_connect(struct hid_device *hid)
 {
-	struct usb_device *dev = hid->dev;
 	struct hid_report *report;
 	struct hid_input *hidinput = NULL;
 	struct input_dev *input_dev;
@@ -818,16 +781,18 @@ int hidinput_connect(struct hid_device *hid)
 				}
 
 				input_dev->private = hid;
-				input_dev->event = hidinput_input_event;
-				input_dev->open = hidinput_open;
-				input_dev->close = hidinput_close;
+				input_dev->event = hid->hidinput_input_event;
+				input_dev->open = hid->hidinput_open;
+				input_dev->close = hid->hidinput_close;
 
 				input_dev->name = hid->name;
 				input_dev->phys = hid->phys;
 				input_dev->uniq = hid->uniq;
-				usb_to_input_id(dev, &input_dev->id);
-				input_dev->cdev.dev = &hid->intf->dev;
-
+				input_dev->id.bustype = hid->bus;
+				input_dev->id.vendor  = hid->vendor;
+				input_dev->id.product = hid->product;
+				input_dev->id.version = hid->version;
+				input_dev->cdev.dev = hid->dev;
 				hidinput->input = input_dev;
 				list_add_tail(&hidinput->list, &hid->inputs);
 			}
@@ -849,16 +814,12 @@ int hidinput_connect(struct hid_device *hid)
 			}
 		}
 
-	/* This only gets called when we are a single-input (most of the
-	 * time). IOW, not a HID_QUIRK_MULTI_INPUT. The hid_ff_init() is
-	 * only useful in this case, and not for multi-input quirks. */
-	if (hidinput) {
-		hid_ff_init(hid);
+	if (hidinput)
 		input_register_device(hidinput->input);
-	}
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(hidinput_connect);
 
 void hidinput_disconnect(struct hid_device *hid)
 {
@@ -870,3 +831,5 @@ void hidinput_disconnect(struct hid_device *hid)
 		kfree(hidinput);
 	}
 }
+EXPORT_SYMBOL_GPL(hidinput_disconnect);
+
diff --git a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c
index 94a4e9a3013c..2e22a2ffa606 100644
--- a/drivers/i2c/i2c-dev.c
+++ b/drivers/i2c/i2c-dev.c
@@ -119,7 +119,7 @@ static ssize_t i2cdev_read (struct file *file, char __user *buf, size_t count,
 		return -ENOMEM;
 
 	pr_debug("i2c-dev: i2c-%d reading %zd bytes.\n",
-		iminor(file->f_dentry->d_inode), count);
+		iminor(file->f_path.dentry->d_inode), count);
 
 	ret = i2c_master_recv(client,tmp,count);
 	if (ret >= 0)
@@ -147,7 +147,7 @@ static ssize_t i2cdev_write (struct file *file, const char __user *buf, size_t c
 	}
 
 	pr_debug("i2c-dev: i2c-%d writing %zd bytes.\n",
-		iminor(file->f_dentry->d_inode), count);
+		iminor(file->f_path.dentry->d_inode), count);
 
 	ret = i2c_master_send(client,tmp,count);
 	kfree(tmp);
diff --git a/drivers/ide/pci/alim15x3.c b/drivers/ide/pci/alim15x3.c
index d419e4bb54f4..89109be5162c 100644
--- a/drivers/ide/pci/alim15x3.c
+++ b/drivers/ide/pci/alim15x3.c
@@ -586,11 +586,11 @@ static unsigned int __devinit init_chipset_ali15x3 (struct pci_dev *dev, const c
 {
 	unsigned long flags;
 	u8 tmpbyte;
-	struct pci_dev *north = pci_find_slot(0, PCI_DEVFN(0,0));
+	struct pci_dev *north = pci_get_slot(dev->bus, PCI_DEVFN(0,0));
 
 	pci_read_config_byte(dev, PCI_REVISION_ID, &m5229_revision);
 
-	isa_dev = pci_find_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, NULL);
+	isa_dev = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, NULL);
 
 #if defined(DISPLAY_ALI_TIMINGS) && defined(CONFIG_PROC_FS)
 	if (!ali_proc) {
@@ -613,8 +613,7 @@ static unsigned int __devinit init_chipset_ali15x3 (struct pci_dev *dev, const c
 		 * clear bit 7
 		 */
 		pci_write_config_byte(dev, 0x4b, tmpbyte & 0x7F);
-		local_irq_restore(flags);
-		return 0;
+		goto out;
 	}
 
 	/*
@@ -637,10 +636,8 @@ static unsigned int __devinit init_chipset_ali15x3 (struct pci_dev *dev, const c
 	 * box without a device at 0:0.0. The ALi bridge will be at
 	 * 0:0.0 so if we didn't find one we know what is cooking.
 	 */
-	if (north && north->vendor != PCI_VENDOR_ID_AL) {
-		local_irq_restore(flags);
-	        return 0;
-	}
+	if (north && north->vendor != PCI_VENDOR_ID_AL)
+		goto out;
 
 	if (m5229_revision < 0xC5 && isa_dev)
 	{	
@@ -661,6 +658,9 @@ static unsigned int __devinit init_chipset_ali15x3 (struct pci_dev *dev, const c
 			pci_write_config_byte(isa_dev, 0x79, tmpbyte | 0x02);
 		}
 	}
+out:
+	pci_dev_put(north);
+	pci_dev_put(isa_dev);
 	local_irq_restore(flags);
 	return 0;
 }
diff --git a/drivers/ide/pci/pdc202xx_new.c b/drivers/ide/pci/pdc202xx_new.c
index 6c097e80b4df..3ca581063f72 100644
--- a/drivers/ide/pci/pdc202xx_new.c
+++ b/drivers/ide/pci/pdc202xx_new.c
@@ -9,6 +9,7 @@
  *  Split from:
  *  linux/drivers/ide/pdc202xx.c	Version 0.35	Mar. 30, 2002
  *  Copyright (C) 1998-2002		Andre Hedrick <andre@linux-ide.org>
+ *  Copyright (C) 2005-2006		MontaVista Software, Inc.
  *  Portions Copyright (C) 1999 Promise Technology, Inc.
  *  Author: Frank Tiernan (frankt@promise.com)
  *  Released under terms of General Public License
@@ -168,12 +169,8 @@ static int pdcnew_new_tune_chipset (ide_drive_t *drive, u8 xferspeed)
  */
 static void pdcnew_tune_drive(ide_drive_t *drive, u8 pio)
 {
-	u8 speed;
-
-	if (pio == 5) pio = 4;
-	speed = XFER_PIO_0 + ide_get_best_pio_mode(drive, 255, pio, NULL);
-
-	(void)pdcnew_new_tune_chipset(drive, speed);
+	pio = ide_get_best_pio_mode(drive, pio, 4, NULL);
+	(void)pdcnew_new_tune_chipset(drive, XFER_PIO_0 + pio);
 }
 
 static u8 pdcnew_new_cable_detect (ide_hwif_t *hwif)
@@ -207,10 +204,8 @@ static int config_chipset_for_dma (ide_drive_t *drive)
 
 	speed = ide_dma_speed(drive, pdcnew_ratemask(drive));
 
-	if (!(speed)) {
-		hwif->tuneproc(drive, 5);
+	if (!speed)
 		return 0;
-	}
 
 	(void) hwif->speedproc(drive, speed);
 	return ide_dma_enable(drive);
@@ -234,7 +229,7 @@ static int pdcnew_config_drive_xfer_rate (ide_drive_t *drive)
 
 	} else if ((id->capability & 8) || (id->field_valid & 2)) {
 fast_ata_pio:
-		hwif->tuneproc(drive, 5);
+		hwif->tuneproc(drive, 255);
 		return hwif->ide_dma_off_quietly(drive);
 	}
 	/* IORDY not supported */
@@ -362,6 +357,7 @@ static int __devinit init_setup_pdc20270(struct pci_dev *dev,
 					 ide_pci_device_t *d)
 {
 	struct pci_dev *findev = NULL;
+	int ret;
 
 	if ((dev->bus->self &&
 	     dev->bus->self->vendor == PCI_VENDOR_ID_DEC) &&
@@ -369,14 +365,16 @@ static int __devinit init_setup_pdc20270(struct pci_dev *dev,
 		if (PCI_SLOT(dev->devfn) & 2)
 			return -ENODEV;
 		d->extra = 0;
-		while ((findev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, findev)) != NULL) {
+		while ((findev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, findev)) != NULL) {
 			if ((findev->vendor == dev->vendor) &&
 			    (findev->device == dev->device) &&
 			    (PCI_SLOT(findev->devfn) & 2)) {
 				if (findev->irq != dev->irq) {
 					findev->irq = dev->irq;
 				}
-				return ide_setup_pci_devices(dev, findev, d);
+				ret = ide_setup_pci_devices(dev, findev, d);
+				pci_dev_put(findev);
+				return ret;
 			}
 		}
 	}
diff --git a/drivers/ide/pci/sis5513.c b/drivers/ide/pci/sis5513.c
index 92edf76bd7ad..6b313139b5e4 100644
--- a/drivers/ide/pci/sis5513.c
+++ b/drivers/ide/pci/sis5513.c
@@ -800,9 +800,10 @@ static unsigned int __devinit init_chipset_sis5513 (struct pci_dev *dev, const c
 
 			if (trueid == 0x5517) { /* SiS 961/961B */
 
-				lpc_bridge = pci_find_slot(0x00, 0x10); /* Bus 0, Dev 2, Fn 0 */
+				lpc_bridge = pci_get_slot(dev->bus, 0x10); /* Bus 0, Dev 2, Fn 0 */
 				pci_read_config_byte(lpc_bridge, PCI_REVISION_ID, &sbrev);
 				pci_read_config_byte(dev, 0x49, &prefctl);
+				pci_dev_put(lpc_bridge);
 
 				if (sbrev == 0x10 && (prefctl & 0x80)) {
 					printk(KERN_INFO "SIS5513: SiS 961B MuTIOL IDE UDMA133 controller\n");
diff --git a/drivers/ide/pci/sl82c105.c b/drivers/ide/pci/sl82c105.c
index 0b4b60498515..5afefe8692fe 100644
--- a/drivers/ide/pci/sl82c105.c
+++ b/drivers/ide/pci/sl82c105.c
@@ -299,14 +299,14 @@ static void sl82c105_selectproc(ide_drive_t *drive)
 	//DBG(("sl82c105_selectproc(drive:%s)\n", drive->name));
 
 	mask = hwif->channel ? CTRL_P1F16 : CTRL_P0F16;
-	old = val = *((u32 *)&hwif->hwif_data);
+	old = val = (u32)pci_get_drvdata(dev);
 	if (drive->using_dma)
 		val &= ~mask;
 	else
 		val |= mask;
 	if (old != val) {
 		pci_write_config_dword(dev, 0x40, val);	
-		*((u32 *)&hwif->hwif_data) = val;
+		pci_set_drvdata(dev, (void *)val);
 	}
 }
 
@@ -316,14 +316,13 @@ static void sl82c105_selectproc(ide_drive_t *drive)
  */
 static void sl82c105_resetproc(ide_drive_t *drive)
 {
-	ide_hwif_t *hwif = HWIF(drive);
-	struct pci_dev *dev = hwif->pci_dev;
+	struct pci_dev *dev = HWIF(drive)->pci_dev;
 	u32 val;
 
 	DBG(("sl82c105_resetproc(drive:%s)\n", drive->name));
 
 	pci_read_config_dword(dev, 0x40, &val);
-	*((u32 *)&hwif->hwif_data) = val;
+	pci_set_drvdata(dev, (void *)val);
 }
 	
 /*
@@ -394,6 +393,7 @@ static unsigned int __devinit init_chipset_sl82c105(struct pci_dev *dev, const c
 	pci_read_config_dword(dev, 0x40, &val);
 	val |= CTRL_P0EN | CTRL_P0F16 | CTRL_P1F16;
 	pci_write_config_dword(dev, 0x40, val);
+	pci_set_drvdata(dev, (void *)val);
 
 	return dev->irq;
 }
@@ -404,30 +404,25 @@ static unsigned int __devinit init_chipset_sl82c105(struct pci_dev *dev, const c
 
 static void __devinit init_hwif_sl82c105(ide_hwif_t *hwif)
 {
-	struct pci_dev *dev = hwif->pci_dev;
 	unsigned int rev;
 	u8 dma_state;
-	u32 val;
-	
+
 	DBG(("init_hwif_sl82c105(hwif: ide%d)\n", hwif->index));
 
 	hwif->tuneproc = tune_sl82c105;
 	hwif->selectproc = sl82c105_selectproc;
 	hwif->resetproc = sl82c105_resetproc;
-	
-	/* Default to PIO 0 for fallback unless tuned otherwise,
-	 * we always autotune PIO, this is done before DMA is
-	 * checked, so there is no risk of accidentally disabling
-	 * DMA
-	  */
+
+	/*
+	 * Default to PIO 0 for fallback unless tuned otherwise.
+	 * We always autotune PIO,  this is done before DMA is checked,
+	 * so there's no risk of accidentally disabling DMA
+	 */
 	hwif->drives[0].pio_speed = XFER_PIO_0;
 	hwif->drives[0].autotune = 1;
-	hwif->drives[1].pio_speed = XFER_PIO_1;
+	hwif->drives[1].pio_speed = XFER_PIO_0;
 	hwif->drives[1].autotune = 1;
 
-	pci_read_config_dword(dev, 0x40, &val);
-	*((u32 *)&hwif->hwif_data) = val;
-	
 	hwif->atapi_dma = 0;
 	hwif->mwdma_mask = 0;
 	hwif->swdma_mask = 0;
diff --git a/drivers/ieee1394/ieee1394_core.h b/drivers/ieee1394/ieee1394_core.h
index af4a78a8ef3b..536ba3f580fd 100644
--- a/drivers/ieee1394/ieee1394_core.h
+++ b/drivers/ieee1394/ieee1394_core.h
@@ -217,7 +217,7 @@ void hpsb_packet_received(struct hpsb_host *host, quadlet_t *data, size_t size,
 /* return the index (within a minor number block) of a file */
 static inline unsigned char ieee1394_file_to_instance(struct file *file)
 {
-	return file->f_dentry->d_inode->i_cindex;
+	return file->f_path.dentry->d_inode->i_cindex;
 }
 
 extern int hpsb_disable_irm;
diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c
index 4e16314e8e6d..a617ca7b6923 100644
--- a/drivers/infiniband/core/uverbs_main.c
+++ b/drivers/infiniband/core/uverbs_main.c
@@ -534,9 +534,9 @@ struct file *ib_uverbs_alloc_event_file(struct ib_uverbs_file *uverbs_file,
 	 * module reference.
 	 */
 	filp->f_op 	   = fops_get(&uverbs_event_fops);
-	filp->f_vfsmnt 	   = mntget(uverbs_event_mnt);
-	filp->f_dentry 	   = dget(uverbs_event_mnt->mnt_root);
-	filp->f_mapping    = filp->f_dentry->d_inode->i_mapping;
+	filp->f_path.mnt 	   = mntget(uverbs_event_mnt);
+	filp->f_path.dentry 	   = dget(uverbs_event_mnt->mnt_root);
+	filp->f_mapping    = filp->f_path.dentry->d_inode->i_mapping;
 	filp->f_flags      = O_RDONLY;
 	filp->f_mode       = FMODE_READ;
 	filp->private_data = ev_file;
diff --git a/drivers/infiniband/hw/ipath/ipath_file_ops.c b/drivers/infiniband/hw/ipath/ipath_file_ops.c
index a9ddc6911f66..340f27e3ebff 100644
--- a/drivers/infiniband/hw/ipath/ipath_file_ops.c
+++ b/drivers/infiniband/hw/ipath/ipath_file_ops.c
@@ -1745,9 +1745,9 @@ static int ipath_assign_port(struct file *fp,
 		goto done;
 	}
 
-	i_minor = iminor(fp->f_dentry->d_inode) - IPATH_USER_MINOR_BASE;
+	i_minor = iminor(fp->f_path.dentry->d_inode) - IPATH_USER_MINOR_BASE;
 	ipath_cdbg(VERBOSE, "open on dev %lx (minor %d)\n",
-		   (long)fp->f_dentry->d_inode->i_rdev, i_minor);
+		   (long)fp->f_path.dentry->d_inode->i_rdev, i_minor);
 
 	if (i_minor)
 		ret = find_free_port(i_minor - 1, fp, uinfo);
diff --git a/drivers/infiniband/hw/ipath/ipath_fs.c b/drivers/infiniband/hw/ipath/ipath_fs.c
index d9ff283f725e..79a60f020a21 100644
--- a/drivers/infiniband/hw/ipath/ipath_fs.c
+++ b/drivers/infiniband/hw/ipath/ipath_fs.c
@@ -118,7 +118,7 @@ static ssize_t atomic_counters_read(struct file *file, char __user *buf,
 	u16 i;
 	struct ipath_devdata *dd;
 
-	dd = file->f_dentry->d_inode->i_private;
+	dd = file->f_path.dentry->d_inode->i_private;
 
 	for (i = 0; i < NUM_COUNTERS; i++)
 		counters[i] = ipath_snap_cntr(dd, i);
@@ -138,7 +138,7 @@ static ssize_t atomic_node_info_read(struct file *file, char __user *buf,
 	struct ipath_devdata *dd;
 	u64 guid;
 
-	dd = file->f_dentry->d_inode->i_private;
+	dd = file->f_path.dentry->d_inode->i_private;
 
 	guid = be64_to_cpu(dd->ipath_guid);
 
@@ -177,7 +177,7 @@ static ssize_t atomic_port_info_read(struct file *file, char __user *buf,
 	u32 tmp, tmp2;
 	struct ipath_devdata *dd;
 
-	dd = file->f_dentry->d_inode->i_private;
+	dd = file->f_path.dentry->d_inode->i_private;
 
 	/* so we only initialize non-zero fields. */
 	memset(portinfo, 0, sizeof portinfo);
@@ -324,7 +324,7 @@ static ssize_t flash_read(struct file *file, char __user *buf,
 		goto bail;
 	}
 
-	dd = file->f_dentry->d_inode->i_private;
+	dd = file->f_path.dentry->d_inode->i_private;
 	if (ipath_eeprom_read(dd, pos, tmp, count)) {
 		ipath_dev_err(dd, "failed to read from flash\n");
 		ret = -ENXIO;
@@ -377,7 +377,7 @@ static ssize_t flash_write(struct file *file, const char __user *buf,
 		goto bail_tmp;
 	}
 
-	dd = file->f_dentry->d_inode->i_private;
+	dd = file->f_path.dentry->d_inode->i_private;
 	if (ipath_eeprom_write(dd, pos, tmp, count)) {
 		ret = -ENXIO;
 		ipath_dev_err(dd, "failed to write to flash\n");
diff --git a/drivers/infiniband/hw/mthca/mthca_provider.c b/drivers/infiniband/hw/mthca/mthca_provider.c
index 21422a3336ad..7ec7c4b937f9 100644
--- a/drivers/infiniband/hw/mthca/mthca_provider.c
+++ b/drivers/infiniband/hw/mthca/mthca_provider.c
@@ -124,7 +124,7 @@ static int mthca_query_device(struct ib_device *ibdev,
 		props->max_map_per_fmr = 255;
 	else
 		props->max_map_per_fmr =
-			(1 << (32 - long_log2(mdev->limits.num_mpts))) - 1;
+			(1 << (32 - ilog2(mdev->limits.num_mpts))) - 1;
 
 	err = 0;
  out:
@@ -816,7 +816,7 @@ static int mthca_resize_cq(struct ib_cq *ibcq, int entries, struct ib_udata *uda
 		lkey = ucmd.lkey;
 	}
 
-	ret = mthca_RESIZE_CQ(dev, cq->cqn, lkey, long_log2(entries), &status);
+	ret = mthca_RESIZE_CQ(dev, cq->cqn, lkey, ilog2(entries), &status);
 	if (status)
 		ret = -EINVAL;
 
diff --git a/drivers/infiniband/hw/mthca/mthca_qp.c b/drivers/infiniband/hw/mthca/mthca_qp.c
index 33e3ba7937f1..d844a2569b47 100644
--- a/drivers/infiniband/hw/mthca/mthca_qp.c
+++ b/drivers/infiniband/hw/mthca/mthca_qp.c
@@ -636,11 +636,11 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask,
 
 	if (mthca_is_memfree(dev)) {
 		if (qp->rq.max)
-			qp_context->rq_size_stride = long_log2(qp->rq.max) << 3;
+			qp_context->rq_size_stride = ilog2(qp->rq.max) << 3;
 		qp_context->rq_size_stride |= qp->rq.wqe_shift - 4;
 
 		if (qp->sq.max)
-			qp_context->sq_size_stride = long_log2(qp->sq.max) << 3;
+			qp_context->sq_size_stride = ilog2(qp->sq.max) << 3;
 		qp_context->sq_size_stride |= qp->sq.wqe_shift - 4;
 	}
 
diff --git a/drivers/infiniband/hw/mthca/mthca_srq.c b/drivers/infiniband/hw/mthca/mthca_srq.c
index 34d2c4768962..10684da33d58 100644
--- a/drivers/infiniband/hw/mthca/mthca_srq.c
+++ b/drivers/infiniband/hw/mthca/mthca_srq.c
@@ -120,7 +120,7 @@ static void mthca_arbel_init_srq_context(struct mthca_dev *dev,
 
 	memset(context, 0, sizeof *context);
 
-	logsize = long_log2(srq->max);
+	logsize = ilog2(srq->max);
 	context->state_logsize_srqn = cpu_to_be32(logsize << 24 | srq->srqn);
 	context->lkey = cpu_to_be32(srq->mr.ibmr.lkey);
 	context->db_index = cpu_to_be32(srq->db_index);
@@ -213,7 +213,7 @@ int mthca_alloc_srq(struct mthca_dev *dev, struct mthca_pd *pd,
 	if (!mthca_is_memfree(dev) && (ds > dev->limits.max_desc_sz))
 		return -EINVAL;
 
-	srq->wqe_shift = long_log2(ds);
+	srq->wqe_shift = ilog2(ds);
 
 	srq->srqn = mthca_alloc(&dev->srq_table.alloc);
 	if (srq->srqn == -1)
diff --git a/drivers/infiniband/ulp/iser/iser_memory.c b/drivers/infiniband/ulp/iser/iser_memory.c
index 5e122501fd80..3aedd59b8a84 100644
--- a/drivers/infiniband/ulp/iser/iser_memory.c
+++ b/drivers/infiniband/ulp/iser/iser_memory.c
@@ -114,7 +114,7 @@ int iser_start_rdma_unaligned_sg(struct iscsi_iser_cmd_task  *iser_ctask,
 
 	if (cmd_data_len > ISER_KMALLOC_THRESHOLD)
 		mem = (void *)__get_free_pages(GFP_NOIO,
-		      long_log2(roundup_pow_of_two(cmd_data_len)) - PAGE_SHIFT);
+		      ilog2(roundup_pow_of_two(cmd_data_len)) - PAGE_SHIFT);
 	else
 		mem = kmalloc(cmd_data_len, GFP_NOIO);
 
@@ -211,7 +211,7 @@ void iser_finalize_rdma_unaligned_sg(struct iscsi_iser_cmd_task *iser_ctask,
 
 	if (cmd_data_len > ISER_KMALLOC_THRESHOLD)
 		free_pages((unsigned long)mem_copy->copy_buf,
-			   long_log2(roundup_pow_of_two(cmd_data_len)) - PAGE_SHIFT);
+			   ilog2(roundup_pow_of_two(cmd_data_len)) - PAGE_SHIFT);
 	else
 		kfree(mem_copy->copy_buf);
 
diff --git a/drivers/input/Makefile b/drivers/input/Makefile
index a005b1df5f1a..da575deb3c7a 100644
--- a/drivers/input/Makefile
+++ b/drivers/input/Makefile
@@ -21,3 +21,4 @@ obj-$(CONFIG_INPUT_MOUSE)	+= mouse/
 obj-$(CONFIG_INPUT_JOYSTICK)	+= joystick/
 obj-$(CONFIG_INPUT_TOUCHSCREEN)	+= touchscreen/
 obj-$(CONFIG_INPUT_MISC)	+= misc/
+
diff --git a/drivers/isdn/act2000/module.c b/drivers/isdn/act2000/module.c
index 90593e2ef872..e3e5c1399076 100644
--- a/drivers/isdn/act2000/module.c
+++ b/drivers/isdn/act2000/module.c
@@ -573,12 +573,11 @@ act2000_alloccard(int bus, int port, int irq, char *id)
 {
 	int i;
         act2000_card *card;
-        if (!(card = (act2000_card *) kmalloc(sizeof(act2000_card), GFP_KERNEL))) {
+        if (!(card = kzalloc(sizeof(act2000_card), GFP_KERNEL))) {
                 printk(KERN_WARNING
 		       "act2000: (%s) Could not allocate card-struct.\n", id);
                 return;
         }
-        memset((char *) card, 0, sizeof(act2000_card));
         spin_lock_init(&card->lock);
         spin_lock_init(&card->mnlock);
 	skb_queue_head_init(&card->sndq);
diff --git a/drivers/isdn/capi/capi.c b/drivers/isdn/capi/capi.c
index 11844bbfe933..d22c0224fde6 100644
--- a/drivers/isdn/capi/capi.c
+++ b/drivers/isdn/capi/capi.c
@@ -215,13 +215,12 @@ static struct capiminor *capiminor_alloc(struct capi20_appl *ap, u32 ncci)
 	unsigned int minor = 0;
 	unsigned long flags;
 
-	mp = kmalloc(sizeof(*mp), GFP_ATOMIC);
+	mp = kzalloc(sizeof(*mp), GFP_ATOMIC);
   	if (!mp) {
   		printk(KERN_ERR "capi: can't alloc capiminor\n");
 		return NULL;
 	}
 
-	memset(mp, 0, sizeof(struct capiminor));
 	mp->ap = ap;
 	mp->ncci = ncci;
 	mp->msgid = 0;
@@ -304,10 +303,9 @@ static struct capincci *capincci_alloc(struct capidev *cdev, u32 ncci)
 	struct capiminor *mp = NULL;
 #endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
 
-	np = kmalloc(sizeof(*np), GFP_ATOMIC);
+	np = kzalloc(sizeof(*np), GFP_ATOMIC);
 	if (!np)
 		return NULL;
-	memset(np, 0, sizeof(struct capincci));
 	np->ncci = ncci;
 	np->cdev = cdev;
 #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
@@ -384,10 +382,9 @@ static struct capidev *capidev_alloc(void)
 	struct capidev *cdev;
 	unsigned long flags;
 
-	cdev = kmalloc(sizeof(*cdev), GFP_KERNEL);
+	cdev = kzalloc(sizeof(*cdev), GFP_KERNEL);
 	if (!cdev)
 		return NULL;
-	memset(cdev, 0, sizeof(struct capidev));
 
 	init_MUTEX(&cdev->ncci_list_sem);
 	skb_queue_head_init(&cdev->recvqueue);
@@ -1010,7 +1007,7 @@ static int capinc_tty_open(struct tty_struct * tty, struct file * file)
 {
 	struct capiminor *mp;
 
-	if ((mp = capiminor_find(iminor(file->f_dentry->d_inode))) == 0)
+	if ((mp = capiminor_find(iminor(file->f_path.dentry->d_inode))) == 0)
 		return -ENXIO;
 	if (mp->nccip == 0)
 		return -ENXIO;
@@ -1203,7 +1200,7 @@ static int capinc_tty_ioctl(struct tty_struct *tty, struct file * file,
 	return error;
 }
 
-static void capinc_tty_set_termios(struct tty_struct *tty, struct termios * old)
+static void capinc_tty_set_termios(struct tty_struct *tty, struct ktermios * old)
 {
 #ifdef _DEBUG_TTYFUNCS
 	printk(KERN_DEBUG "capinc_tty_set_termios\n");
diff --git a/drivers/isdn/capi/capidrv.c b/drivers/isdn/capi/capidrv.c
index b6f9476c0501..097bfa7bc323 100644
--- a/drivers/isdn/capi/capidrv.c
+++ b/drivers/isdn/capi/capidrv.c
@@ -334,12 +334,11 @@ static capidrv_plci *new_plci(capidrv_contr * card, int chan)
 {
 	capidrv_plci *plcip;
 
-	plcip = (capidrv_plci *) kmalloc(sizeof(capidrv_plci), GFP_ATOMIC);
+	plcip = kzalloc(sizeof(capidrv_plci), GFP_ATOMIC);
 
 	if (plcip == 0)
 		return NULL;
 
-	memset(plcip, 0, sizeof(capidrv_plci));
 	plcip->state = ST_PLCI_NONE;
 	plcip->plci = 0;
 	plcip->msgid = 0;
@@ -404,12 +403,11 @@ static inline capidrv_ncci *new_ncci(capidrv_contr * card,
 {
 	capidrv_ncci *nccip;
 
-	nccip = (capidrv_ncci *) kmalloc(sizeof(capidrv_ncci), GFP_ATOMIC);
+	nccip = kzalloc(sizeof(capidrv_ncci), GFP_ATOMIC);
 
 	if (nccip == 0)
 		return NULL;
 
-	memset(nccip, 0, sizeof(capidrv_ncci));
 	nccip->ncci = ncci;
 	nccip->state = ST_NCCI_NONE;
 	nccip->plcip = plcip;
@@ -2005,12 +2003,11 @@ static int capidrv_addcontr(u16 contr, struct capi_profile *profp)
 		printk(KERN_WARNING "capidrv: (%s) Could not reserve module\n", id);
 		return -1;
 	}
-	if (!(card = (capidrv_contr *) kmalloc(sizeof(capidrv_contr), GFP_ATOMIC))) {
+	if (!(card = kzalloc(sizeof(capidrv_contr), GFP_ATOMIC))) {
 		printk(KERN_WARNING
 		 "capidrv: (%s) Could not allocate contr-struct.\n", id);
 		return -1;
 	}
-	memset(card, 0, sizeof(capidrv_contr));
 	card->owner = THIS_MODULE;
 	init_timer(&card->listentimer);
 	strcpy(card->name, id);
diff --git a/drivers/isdn/gigaset/Kconfig b/drivers/isdn/gigaset/Kconfig
index 5b203fe21dcd..708d47a6484b 100644
--- a/drivers/isdn/gigaset/Kconfig
+++ b/drivers/isdn/gigaset/Kconfig
@@ -5,6 +5,7 @@ config ISDN_DRV_GIGASET
 	tristate "Siemens Gigaset support (isdn)"
 	depends on ISDN_I4L
 	select CRC_CCITT
+	select BITREVERSE
 	help
 	  Say m here if you have a Gigaset or Sinus isdn device.
 
diff --git a/drivers/isdn/gigaset/asyncdata.c b/drivers/isdn/gigaset/asyncdata.c
index ce3cd77094b3..88e958f176d2 100644
--- a/drivers/isdn/gigaset/asyncdata.c
+++ b/drivers/isdn/gigaset/asyncdata.c
@@ -15,6 +15,7 @@
 
 #include "gigaset.h"
 #include <linux/crc-ccitt.h>
+#include <linux/bitrev.h>
 
 //#define GIG_M10x_STUFF_VOICE_DATA
 
@@ -302,7 +303,7 @@ static inline int iraw_loop(unsigned char c, unsigned char *src, int numbytes,
 				inputstate |= INS_skip_frame;
 				break;
 			}
-			*__skb_put(skb, 1) = gigaset_invtab[c];
+			*__skb_put(skb, 1) = bitrev8(c);
 		}
 
 		if (unlikely(!numbytes))
@@ -543,7 +544,7 @@ static struct sk_buff *iraw_encode(struct sk_buff *skb, int head, int tail)
 	cp = skb->data;
 	len = skb->len;
 	while (len--) {
-		c = gigaset_invtab[*cp++];
+		c = bitrev8(*cp++);
 		if (c == DLE_FLAG)
 			*(skb_put(iraw_skb, 1)) = c;
 		*(skb_put(iraw_skb, 1)) = c;
diff --git a/drivers/isdn/gigaset/common.c b/drivers/isdn/gigaset/common.c
index defd5743dba6..95eff3b2917a 100644
--- a/drivers/isdn/gigaset/common.c
+++ b/drivers/isdn/gigaset/common.c
@@ -33,43 +33,6 @@ MODULE_PARM_DESC(debug, "debug level");
 #define VALID_ID	0x02
 #define ASSIGNED	0x04
 
-/* bitwise byte inversion table */
-__u8 gigaset_invtab[256] = {
-	0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
-	0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
-	0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
-	0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
-	0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
-	0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
-	0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
-	0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
-	0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
-	0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
-	0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
-	0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
-	0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
-	0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
-	0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
-	0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
-	0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
-	0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
-	0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
-	0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
-	0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
-	0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
-	0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
-	0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
-	0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
-	0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
-	0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
-	0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
-	0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
-	0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
-	0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
-	0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff
-};
-EXPORT_SYMBOL_GPL(gigaset_invtab);
-
 void gigaset_dbg_buffer(enum debuglevel level, const unsigned char *msg,
 			size_t len, const unsigned char *buf)
 {
diff --git a/drivers/isdn/gigaset/gigaset.h b/drivers/isdn/gigaset/gigaset.h
index 06298cc52bf5..a0317abaeb11 100644
--- a/drivers/isdn/gigaset/gigaset.h
+++ b/drivers/isdn/gigaset/gigaset.h
@@ -876,10 +876,6 @@ static inline void gigaset_rcv_error(struct sk_buff *procskb,
 	}
 }
 
-
-/* bitwise byte inversion table */
-extern __u8 gigaset_invtab[];	/* in common.c */
-
 /* append received bytes to inbuf */
 int gigaset_fill_inbuf(struct inbuf_t *inbuf, const unsigned char *src,
 		       unsigned numbytes);
diff --git a/drivers/isdn/gigaset/interface.c b/drivers/isdn/gigaset/interface.c
index 7edea015867e..458b6462f937 100644
--- a/drivers/isdn/gigaset/interface.c
+++ b/drivers/isdn/gigaset/interface.c
@@ -127,7 +127,7 @@ static int  if_write_room(struct tty_struct *tty);
 static int  if_chars_in_buffer(struct tty_struct *tty);
 static void if_throttle(struct tty_struct *tty);
 static void if_unthrottle(struct tty_struct *tty);
-static void if_set_termios(struct tty_struct *tty, struct termios *old);
+static void if_set_termios(struct tty_struct *tty, struct ktermios *old);
 static int  if_tiocmget(struct tty_struct *tty, struct file *file);
 static int  if_tiocmset(struct tty_struct *tty, struct file *file,
 			unsigned int set, unsigned int clear);
@@ -490,7 +490,7 @@ static void if_unthrottle(struct tty_struct *tty)
 	mutex_unlock(&cs->mutex);
 }
 
-static void if_set_termios(struct tty_struct *tty, struct termios *old)
+static void if_set_termios(struct tty_struct *tty, struct ktermios *old)
 {
 	struct cardstate *cs;
 	unsigned int iflag;
diff --git a/drivers/isdn/gigaset/isocdata.c b/drivers/isdn/gigaset/isocdata.c
index 8667daaa1a82..df988eb0e36f 100644
--- a/drivers/isdn/gigaset/isocdata.c
+++ b/drivers/isdn/gigaset/isocdata.c
@@ -14,6 +14,7 @@
 
 #include "gigaset.h"
 #include <linux/crc-ccitt.h>
+#include <linux/bitrev.h>
 
 /* access methods for isowbuf_t */
 /* ============================ */
@@ -487,7 +488,7 @@ static inline int trans_buildframe(struct isowbuf_t *iwb,
 	gig_dbg(DEBUG_STREAM, "put %d bytes", count);
 	write = atomic_read(&iwb->write);
 	do {
-		c = gigaset_invtab[*in++];
+		c = bitrev8(*in++);
 		iwb->data[write++] = c;
 		write %= BAS_OUTBUFSIZE;
 	} while (--count > 0);
@@ -876,7 +877,7 @@ static inline void trans_receive(unsigned char *src, unsigned count,
 	while (count > 0) {
 		dst = skb_put(skb, count < dobytes ? count : dobytes);
 		while (count > 0 && dobytes > 0) {
-			*dst++ = gigaset_invtab[*src++];
+			*dst++ = bitrev8(*src++);
 			count--;
 			dobytes--;
 		}
diff --git a/drivers/isdn/hardware/avm/avm_cs.c b/drivers/isdn/hardware/avm/avm_cs.c
index fd5d7364a487..eba10466ccc6 100644
--- a/drivers/isdn/hardware/avm/avm_cs.c
+++ b/drivers/isdn/hardware/avm/avm_cs.c
@@ -121,10 +121,9 @@ static int avmcs_probe(struct pcmcia_device *p_dev)
     p_dev->conf.Present = PRESENT_OPTION;
 
     /* Allocate space for private device-specific data */
-    local = kmalloc(sizeof(local_info_t), GFP_KERNEL);
+    local = kzalloc(sizeof(local_info_t), GFP_KERNEL);
     if (!local)
         goto err;
-    memset(local, 0, sizeof(local_info_t));
     p_dev->priv = local;
 
     return avmcs_config(p_dev);
diff --git a/drivers/isdn/hardware/avm/b1.c b/drivers/isdn/hardware/avm/b1.c
index da2729247713..7a69a18d07e2 100644
--- a/drivers/isdn/hardware/avm/b1.c
+++ b/drivers/isdn/hardware/avm/b1.c
@@ -65,18 +65,15 @@ avmcard *b1_alloc_card(int nr_controllers)
 	avmctrl_info *cinfo;
 	int i;
 
-	card = kmalloc(sizeof(*card), GFP_KERNEL);
+	card = kzalloc(sizeof(*card), GFP_KERNEL);
 	if (!card)
 		return NULL;
 
-	memset(card, 0, sizeof(*card));
-
-        cinfo = kmalloc(sizeof(*cinfo) * nr_controllers, GFP_KERNEL);
+	cinfo = kzalloc(sizeof(*cinfo) * nr_controllers, GFP_KERNEL);
 	if (!cinfo) {
 		kfree(card);
 		return NULL;
 	}
-	memset(cinfo, 0, sizeof(*cinfo) * nr_controllers);
 
 	card->ctrlinfo = cinfo;
 	for (i = 0; i < nr_controllers; i++) {
@@ -718,12 +715,11 @@ avmcard_dma_alloc(char *name, struct pci_dev *pdev, long rsize, long ssize)
 	avmcard_dmainfo *p;
 	void *buf;
 
-	p = kmalloc(sizeof(avmcard_dmainfo), GFP_KERNEL);
+	p = kzalloc(sizeof(avmcard_dmainfo), GFP_KERNEL);
 	if (!p) {
 		printk(KERN_WARNING "%s: no memory.\n", name);
 		goto err;
 	}
-	memset(p, 0, sizeof(avmcard_dmainfo));
 
 	p->recvbuf.size = rsize;
 	buf = pci_alloc_consistent(pdev, rsize, &p->recvbuf.dmaaddr);
diff --git a/drivers/isdn/hardware/avm/t1isa.c b/drivers/isdn/hardware/avm/t1isa.c
index e47c60b0a8ec..c925020fe9b7 100644
--- a/drivers/isdn/hardware/avm/t1isa.c
+++ b/drivers/isdn/hardware/avm/t1isa.c
@@ -584,6 +584,7 @@ static void __exit t1isa_exit(void)
 {
 	int i;
 
+	unregister_capi_driver(&capi_driver_t1isa);
 	for (i = 0; i < MAX_CARDS; i++) {
 		if (!io[i])
 			break;
diff --git a/drivers/isdn/hardware/eicon/debug.c b/drivers/isdn/hardware/eicon/debug.c
index 6851c6270ce8..d835e74ecf18 100644
--- a/drivers/isdn/hardware/eicon/debug.c
+++ b/drivers/isdn/hardware/eicon/debug.c
@@ -756,14 +756,14 @@ int diva_get_driver_info (dword id, byte* data, int data_length) {
 
     data_length -= 9;
 
-    if ((to_copy = MIN(strlen(clients[id].drvName), data_length-1))) {
+    if ((to_copy = min(strlen(clients[id].drvName), (size_t)(data_length-1)))) {
       memcpy (p, clients[id].drvName, to_copy);
       p += to_copy;
       data_length -= to_copy;
       if ((data_length >= 4) && clients[id].hDbg->drvTag[0]) {
         *p++ = '(';
         data_length -= 1;
-        if ((to_copy = MIN(strlen(clients[id].hDbg->drvTag), data_length-2))) {
+        if ((to_copy = min(strlen(clients[id].hDbg->drvTag), (size_t)(data_length-2)))) {
           memcpy (p, clients[id].hDbg->drvTag, to_copy);
           p += to_copy;
           data_length -= to_copy;
diff --git a/drivers/isdn/hardware/eicon/di.c b/drivers/isdn/hardware/eicon/di.c
index 0617d7cabf06..e1df8d98c311 100644
--- a/drivers/isdn/hardware/eicon/di.c
+++ b/drivers/isdn/hardware/eicon/di.c
@@ -133,7 +133,7 @@ void pr_out(ADAPTER * a)
     i = this->XCurrent;
     X = PTR_X(a,this);
     while(i<this->XNum && length<270) {
-      clength = MIN((word)(270-length),X[i].PLength-this->XOffset);
+      clength = min((word)(270-length),(word)(X[i].PLength-this->XOffset));
       a->ram_out_buffer(a,
                         &ReqOut->XBuffer.P[length],
                         PTR_P(a,this,&X[i].P[this->XOffset]),
@@ -622,7 +622,7 @@ byte isdn_ind(ADAPTER * a,
                                                      sizeof(a->stream_buffer),
                                                      &final, NULL, NULL);
         }
-        IoAdapter->RBuffer.length = MIN(MLength, 270);
+        IoAdapter->RBuffer.length = min(MLength, (word)270);
         if (IoAdapter->RBuffer.length != MLength) {
           this->complete = 0;
         } else {
@@ -676,9 +676,9 @@ byte isdn_ind(ADAPTER * a,
         this->RCurrent++;
       }
       if (cma) {
-        clength = MIN(MLength, R[this->RCurrent].PLength-this->ROffset);
+        clength = min(MLength, (word)(R[this->RCurrent].PLength-this->ROffset));
       } else {
-        clength = MIN(a->ram_inw(a, &RBuffer->length)-offset,
+        clength = min(a->ram_inw(a, &RBuffer->length)-offset,
                       R[this->RCurrent].PLength-this->ROffset);
       }
       if(R[this->RCurrent].P) {
diff --git a/drivers/isdn/hardware/eicon/divasmain.c b/drivers/isdn/hardware/eicon/divasmain.c
index dae2e83dd5e8..91fc92c01afe 100644
--- a/drivers/isdn/hardware/eicon/divasmain.c
+++ b/drivers/isdn/hardware/eicon/divasmain.c
@@ -185,7 +185,7 @@ void diva_log_info(unsigned char *format, ...)
 	unsigned char line[160];
 
 	va_start(args, format);
-	vsprintf(line, format, args);
+	vsnprintf(line, sizeof(line), format, args);
 	va_end(args);
 
 	printk(KERN_INFO "%s: %s\n", DRIVERLNAME, line);
diff --git a/drivers/isdn/hardware/eicon/io.c b/drivers/isdn/hardware/eicon/io.c
index 4a27e230b0a5..6fd9b007417d 100644
--- a/drivers/isdn/hardware/eicon/io.c
+++ b/drivers/isdn/hardware/eicon/io.c
@@ -262,7 +262,7 @@ void request(PISDN_ADAPTER IoAdapter, ENTITY * e)
     case IDI_SYNC_REQ_XDI_GET_CAPI_PARAMS: {
        diva_xdi_get_capi_parameters_t prms, *pI = &syncReq->xdi_capi_prms.info;
        memset (&prms, 0x00, sizeof(prms));
-       prms.structure_length = MIN(sizeof(prms), pI->structure_length);
+       prms.structure_length = min_t(size_t, sizeof(prms), pI->structure_length);
        memset (pI, 0x00, pI->structure_length);
        prms.flag_dynamic_l1_down    = (IoAdapter->capi_cfg.cfg_1 & \
          DIVA_XDI_CAPI_CFG_1_DYNAMIC_L1_ON) ? 1 : 0;
diff --git a/drivers/isdn/hardware/eicon/istream.c b/drivers/isdn/hardware/eicon/istream.c
index 23139668d9b1..18f8798442fa 100644
--- a/drivers/isdn/hardware/eicon/istream.c
+++ b/drivers/isdn/hardware/eicon/istream.c
@@ -92,7 +92,7 @@ int diva_istream_write (void* context,
     return (-1); /* was not able to write       */
    break;     /* only part of message was written */
   }
-  to_write = MIN(length, DIVA_DFIFO_DATA_SZ);
+  to_write = min(length, DIVA_DFIFO_DATA_SZ);
   if (to_write) {
    a->ram_out_buffer (a,
 #ifdef PLATFORM_GT_32BIT
@@ -176,7 +176,7 @@ int diva_istream_read (void* context,
     return (-1); /* was not able to read */
    break;
   }
-  to_read = MIN(max_length, tmp[1]);
+  to_read = min(max_length, (int)tmp[1]);
   if (to_read) {
    a->ram_in_buffer(a,
 #ifdef PLATFORM_GT_32BIT
diff --git a/drivers/isdn/hardware/eicon/platform.h b/drivers/isdn/hardware/eicon/platform.h
index a66836cf756c..2444811e0b38 100644
--- a/drivers/isdn/hardware/eicon/platform.h
+++ b/drivers/isdn/hardware/eicon/platform.h
@@ -83,14 +83,6 @@
 #define	NULL	((void *) 0)
 #endif
 
-#ifndef	MIN
-#define MIN(a,b)	((a)>(b) ? (b) : (a))
-#endif
-
-#ifndef	MAX
-#define MAX(a,b)	((a)>(b) ? (a) : (b))
-#endif
-
 #ifndef	far
 #define far
 #endif
diff --git a/drivers/isdn/hisax/Kconfig b/drivers/isdn/hisax/Kconfig
index cfd2718a490d..6fa12cc8e4ff 100644
--- a/drivers/isdn/hisax/Kconfig
+++ b/drivers/isdn/hisax/Kconfig
@@ -349,13 +349,6 @@ config HISAX_ENTERNOW_PCI
 	  This enables HiSax support for the Formula-n enter:now PCI
 	  ISDN card.
 
-config HISAX_AMD7930
-	bool "Am7930 (EXPERIMENTAL)"
-	depends on EXPERIMENTAL && SPARC && BROKEN
-	help
-	  This enables HiSax support for the AMD7930 chips on some SPARCs.
-	  This code is not finished yet.
-
 endif
 
 if ISDN_DRV_HISAX
@@ -402,6 +395,7 @@ config HISAX_ST5481
 	tristate "ST5481 USB ISDN modem (EXPERIMENTAL)"
 	depends on USB && EXPERIMENTAL
 	select CRC_CCITT
+	select BITREVERSE
 	help
 	  This enables the driver for ST5481 based USB ISDN adapters,
 	  e.g. the BeWan Gazel 128 USB
diff --git a/drivers/isdn/hisax/avma1_cs.c b/drivers/isdn/hisax/avma1_cs.c
index 876fec6c6be8..9e70c206779e 100644
--- a/drivers/isdn/hisax/avma1_cs.c
+++ b/drivers/isdn/hisax/avma1_cs.c
@@ -123,11 +123,10 @@ static int avma1cs_probe(struct pcmcia_device *p_dev)
     DEBUG(0, "avma1cs_attach()\n");
 
     /* Allocate space for private device-specific data */
-    local = kmalloc(sizeof(local_info_t), GFP_KERNEL);
+    local = kzalloc(sizeof(local_info_t), GFP_KERNEL);
     if (!local)
 	return -ENOMEM;
 
-    memset(local, 0, sizeof(local_info_t));
     p_dev->priv = local;
 
     /* The io structure describes IO port mapping */
diff --git a/drivers/isdn/hisax/config.c b/drivers/isdn/hisax/config.c
index cede72cdbb31..17ec0b70ba1d 100644
--- a/drivers/isdn/hisax/config.c
+++ b/drivers/isdn/hisax/config.c
@@ -227,14 +227,6 @@ const char *CardType[] = {
 #define DEFAULT_CFG {5,0x2E0,0,0}
 #endif
 
-
-#ifdef CONFIG_HISAX_AMD7930
-#undef DEFAULT_CARD
-#undef DEFAULT_CFG
-#define DEFAULT_CARD ISDN_CTYPE_AMD7930
-#define DEFAULT_CFG {12,0x3e0,0,0}
-#endif
-
 #ifdef CONFIG_HISAX_NICCY
 #undef DEFAULT_CARD
 #undef DEFAULT_CFG
@@ -545,10 +537,6 @@ extern int setup_hfcpci(struct IsdnCard *card);
 extern int setup_hfcsx(struct IsdnCard *card);
 #endif
 
-#if CARD_AMD7930
-extern int setup_amd7930(struct IsdnCard *card);
-#endif
-
 #if CARD_NICCY
 extern int setup_niccy(struct IsdnCard *card);
 #endif
@@ -869,14 +857,13 @@ static int checkcard(int cardnr, char *id, int *busy_flag, struct module *lockow
 	struct IsdnCard *card = cards + cardnr;
 	struct IsdnCardState *cs;
 
-	cs = kmalloc(sizeof(struct IsdnCardState), GFP_ATOMIC);
+	cs = kzalloc(sizeof(struct IsdnCardState), GFP_ATOMIC);
 	if (!cs) {
 		printk(KERN_WARNING
 		       "HiSax: No memory for IsdnCardState(card %d)\n",
 		       cardnr + 1);
 		goto out;
 	}
-	memset(cs, 0, sizeof(struct IsdnCardState));
 	card->cs = cs;
 	spin_lock_init(&cs->statlock);
 	spin_lock_init(&cs->lock);
@@ -1064,11 +1051,6 @@ static int checkcard(int cardnr, char *id, int *busy_flag, struct module *lockow
 		ret = setup_niccy(card);
 		break;
 #endif
-#if CARD_AMD7930
-	case ISDN_CTYPE_AMD7930:
-		ret = setup_amd7930(card);
-		break;
-#endif
 #if CARD_ISURF
 	case ISDN_CTYPE_ISURF:
 		ret = setup_isurf(card);
@@ -1437,7 +1419,6 @@ static int __init HiSax_init(void)
 			break;
 		case ISDN_CTYPE_ELSA_PCI:
 		case ISDN_CTYPE_NETJET_S:
-		case ISDN_CTYPE_AMD7930:
 		case ISDN_CTYPE_TELESPCI:
 		case ISDN_CTYPE_W6692:
 		case ISDN_CTYPE_NETJET_U:
diff --git a/drivers/isdn/hisax/diva.c b/drivers/isdn/hisax/diva.c
index 3dacfff93f5f..6eebeb441bfd 100644
--- a/drivers/isdn/hisax/diva.c
+++ b/drivers/isdn/hisax/diva.c
@@ -1121,7 +1121,11 @@ setup_diva(struct IsdnCard *card)
 			bytecnt = 32;
 		}
 	}
+
+#ifdef __ISAPNP__
 ready:
+#endif
+
 	printk(KERN_INFO
 		"Diva: %s card configured at %#lx IRQ %d\n",
 		(cs->subtyp == DIVA_PCI) ? "PCI" :
diff --git a/drivers/isdn/hisax/elsa_cs.c b/drivers/isdn/hisax/elsa_cs.c
index 4e180d210faa..79ab9dda7d08 100644
--- a/drivers/isdn/hisax/elsa_cs.c
+++ b/drivers/isdn/hisax/elsa_cs.c
@@ -146,9 +146,8 @@ static int elsa_cs_probe(struct pcmcia_device *link)
     DEBUG(0, "elsa_cs_attach()\n");
 
     /* Allocate space for private device-specific data */
-    local = kmalloc(sizeof(local_info_t), GFP_KERNEL);
+    local = kzalloc(sizeof(local_info_t), GFP_KERNEL);
     if (!local) return -ENOMEM;
-    memset(local, 0, sizeof(local_info_t));
 
     local->p_dev = link;
     link->priv = local;
diff --git a/drivers/isdn/hisax/fsm.c b/drivers/isdn/hisax/fsm.c
index 0d44a3f480ac..34fade96a581 100644
--- a/drivers/isdn/hisax/fsm.c
+++ b/drivers/isdn/hisax/fsm.c
@@ -26,12 +26,10 @@ FsmNew(struct Fsm *fsm, struct FsmNode *fnlist, int fncount)
 	int i;
 
 	fsm->jumpmatrix = (FSMFNPTR *)
-		kmalloc(sizeof (FSMFNPTR) * fsm->state_count * fsm->event_count, GFP_KERNEL);
+		kzalloc(sizeof (FSMFNPTR) * fsm->state_count * fsm->event_count, GFP_KERNEL);
 	if (!fsm->jumpmatrix)
 		return -ENOMEM;
 
-	memset(fsm->jumpmatrix, 0, sizeof (FSMFNPTR) * fsm->state_count * fsm->event_count);
-
 	for (i = 0; i < fncount; i++) 
 		if ((fnlist[i].state>=fsm->state_count) || (fnlist[i].event>=fsm->event_count)) {
 			printk(KERN_ERR "FsmNew Error line %d st(%ld/%ld) ev(%ld/%ld)\n",
diff --git a/drivers/isdn/hisax/hfc4s8s_l1.c b/drivers/isdn/hisax/hfc4s8s_l1.c
index de9b1a4d6bac..a2fa4ecb8c88 100644
--- a/drivers/isdn/hisax/hfc4s8s_l1.c
+++ b/drivers/isdn/hisax/hfc4s8s_l1.c
@@ -1591,11 +1591,10 @@ hfc4s8s_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	hfc4s8s_param *driver_data = (hfc4s8s_param *) ent->driver_data;
 	hfc4s8s_hw *hw;
 
-	if (!(hw = kmalloc(sizeof(hfc4s8s_hw), GFP_ATOMIC))) {
+	if (!(hw = kzalloc(sizeof(hfc4s8s_hw), GFP_ATOMIC))) {
 		printk(KERN_ERR "No kmem for HFC-4S/8S card\n");
 		return (err);
 	}
-	memset(hw, 0, sizeof(hfc4s8s_hw));
 
 	hw->pdev = pdev;
 	err = pci_enable_device(pdev);
diff --git a/drivers/isdn/hisax/hfc_pci.c b/drivers/isdn/hisax/hfc_pci.c
index 5db0a85b827f..8a48a3ce0a55 100644
--- a/drivers/isdn/hisax/hfc_pci.c
+++ b/drivers/isdn/hisax/hfc_pci.c
@@ -1211,7 +1211,7 @@ HFCPCI_l1hw(struct PStack *st, int pr, void *arg)
 			break;
 		case (HW_TESTLOOP | REQUEST):
 			spin_lock_irqsave(&cs->lock, flags);
-			switch ((int) arg) {
+			switch ((long) arg) {
 				case (1):
 					Write_hfc(cs, HFCPCI_B1_SSL, 0x80);	/* tx slot */
 					Write_hfc(cs, HFCPCI_B1_RSL, 0x80);	/* rx slot */
@@ -1229,7 +1229,7 @@ HFCPCI_l1hw(struct PStack *st, int pr, void *arg)
 				default:
 					spin_unlock_irqrestore(&cs->lock, flags);
 					if (cs->debug & L1_DEB_WARN)
-						debugl1(cs, "hfcpci_l1hw loop invalid %4x", (int) arg);
+						debugl1(cs, "hfcpci_l1hw loop invalid %4lx", (long) arg);
 					return;
 			}
 			cs->hw.hfcpci.trm |= 0x80;	/* enable IOM-loop */
@@ -1711,9 +1711,9 @@ setup_hfcpci(struct IsdnCard *card)
 		pci_write_config_dword(cs->hw.hfcpci.dev, 0x80, (u_int) virt_to_bus(cs->hw.hfcpci.fifos));
 		cs->hw.hfcpci.pci_io = ioremap((ulong) cs->hw.hfcpci.pci_io, 256);
 		printk(KERN_INFO
-		       "HFC-PCI: defined at mem %#x fifo %#x(%#x) IRQ %d HZ %d\n",
-		       (u_int) cs->hw.hfcpci.pci_io,
-		       (u_int) cs->hw.hfcpci.fifos,
+		       "HFC-PCI: defined at mem %p fifo %p(%#x) IRQ %d HZ %d\n",
+		       cs->hw.hfcpci.pci_io,
+		       cs->hw.hfcpci.fifos,
 		       (u_int) virt_to_bus(cs->hw.hfcpci.fifos),
 		       cs->irq, HZ);
 		spin_lock_irqsave(&cs->lock, flags);
diff --git a/drivers/isdn/hisax/hfc_usb.c b/drivers/isdn/hisax/hfc_usb.c
index 7105b043add8..5a6989f23fcf 100644
--- a/drivers/isdn/hisax/hfc_usb.c
+++ b/drivers/isdn/hisax/hfc_usb.c
@@ -1481,9 +1481,8 @@ hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
 			iface = iface_used;
 			if (!
 			    (context =
-			     kmalloc(sizeof(hfcusb_data), GFP_KERNEL)))
+			     kzalloc(sizeof(hfcusb_data), GFP_KERNEL)))
 				return (-ENOMEM);	/* got no mem */
-			memset(context, 0, sizeof(hfcusb_data));
 
 			ep = iface->endpoint;
 			vcf = validconf[small_match];
diff --git a/drivers/isdn/hisax/hisax.h b/drivers/isdn/hisax/hisax.h
index 159c5896061e..3f1137e34678 100644
--- a/drivers/isdn/hisax/hisax.h
+++ b/drivers/isdn/hisax/hisax.h
@@ -1139,12 +1139,6 @@ struct IsdnCardState {
 #define  CARD_HFC_SX 0
 #endif
 
-#ifdef  CONFIG_HISAX_AMD7930
-#define CARD_AMD7930 1
-#else
-#define CARD_AMD7930 0
-#endif
-
 #ifdef	CONFIG_HISAX_NICCY
 #define	CARD_NICCY 1
 #ifndef ISDN_CHIP_ISAC
diff --git a/drivers/isdn/hisax/hisax_fcpcipnp.c b/drivers/isdn/hisax/hisax_fcpcipnp.c
index f6db55a752c4..9e088fce8c3a 100644
--- a/drivers/isdn/hisax/hisax_fcpcipnp.c
+++ b/drivers/isdn/hisax/hisax_fcpcipnp.c
@@ -841,12 +841,10 @@ new_adapter(void)
 	struct hisax_b_if *b_if[2];
 	int i;
 
-	adapter = kmalloc(sizeof(struct fritz_adapter), GFP_KERNEL);
+	adapter = kzalloc(sizeof(struct fritz_adapter), GFP_KERNEL);
 	if (!adapter)
 		return NULL;
 
-	memset(adapter, 0, sizeof(struct fritz_adapter));
-
 	adapter->isac.hisax_d_if.owner = THIS_MODULE;
 	adapter->isac.hisax_d_if.ifc.priv = &adapter->isac;
 	adapter->isac.hisax_d_if.ifc.l2l1 = isac_d_l2l1;
diff --git a/drivers/isdn/hisax/hisax_isac.c b/drivers/isdn/hisax/hisax_isac.c
index 81eac344bb03..d0fefcf999cb 100644
--- a/drivers/isdn/hisax/hisax_isac.c
+++ b/drivers/isdn/hisax/hisax_isac.c
@@ -433,7 +433,7 @@ static void l1m_debug(struct FsmInst *fi, char *fmt, ...)
 	char buf[256];
 	
 	va_start(args, fmt);
-	vsprintf(buf, fmt, args);
+	vsnprintf(buf, sizeof(buf), fmt, args);
 	DBG(DBG_L1M, "%s", buf);
 	va_end(args);
 }
diff --git a/drivers/isdn/hisax/isdnhdlc.c b/drivers/isdn/hisax/isdnhdlc.c
index cbdf54c5af84..268dced6c34a 100644
--- a/drivers/isdn/hisax/isdnhdlc.c
+++ b/drivers/isdn/hisax/isdnhdlc.c
@@ -35,30 +35,6 @@ MODULE_LICENSE("GPL");
 
 /*-------------------------------------------------------------------*/
 
-/* bit swap table.
- * Very handy for devices with different bit order,
- * and neccessary for each transparent B-channel access for all
- * devices which works with this HDLC decoder without bit reversal.
- */
-const unsigned char isdnhdlc_bit_rev_tab[256] = {
-	0x00,0x80,0x40,0xC0,0x20,0xA0,0x60,0xE0,0x10,0x90,0x50,0xD0,0x30,0xB0,0x70,0xF0,
-	0x08,0x88,0x48,0xC8,0x28,0xA8,0x68,0xE8,0x18,0x98,0x58,0xD8,0x38,0xB8,0x78,0xF8,
-	0x04,0x84,0x44,0xC4,0x24,0xA4,0x64,0xE4,0x14,0x94,0x54,0xD4,0x34,0xB4,0x74,0xF4,
-	0x0C,0x8C,0x4C,0xCC,0x2C,0xAC,0x6C,0xEC,0x1C,0x9C,0x5C,0xDC,0x3C,0xBC,0x7C,0xFC,
-	0x02,0x82,0x42,0xC2,0x22,0xA2,0x62,0xE2,0x12,0x92,0x52,0xD2,0x32,0xB2,0x72,0xF2,
-	0x0A,0x8A,0x4A,0xCA,0x2A,0xAA,0x6A,0xEA,0x1A,0x9A,0x5A,0xDA,0x3A,0xBA,0x7A,0xFA,
-	0x06,0x86,0x46,0xC6,0x26,0xA6,0x66,0xE6,0x16,0x96,0x56,0xD6,0x36,0xB6,0x76,0xF6,
-	0x0E,0x8E,0x4E,0xCE,0x2E,0xAE,0x6E,0xEE,0x1E,0x9E,0x5E,0xDE,0x3E,0xBE,0x7E,0xFE,
-	0x01,0x81,0x41,0xC1,0x21,0xA1,0x61,0xE1,0x11,0x91,0x51,0xD1,0x31,0xB1,0x71,0xF1,
-	0x09,0x89,0x49,0xC9,0x29,0xA9,0x69,0xE9,0x19,0x99,0x59,0xD9,0x39,0xB9,0x79,0xF9,
-	0x05,0x85,0x45,0xC5,0x25,0xA5,0x65,0xE5,0x15,0x95,0x55,0xD5,0x35,0xB5,0x75,0xF5,
-	0x0D,0x8D,0x4D,0xCD,0x2D,0xAD,0x6D,0xED,0x1D,0x9D,0x5D,0xDD,0x3D,0xBD,0x7D,0xFD,
-	0x03,0x83,0x43,0xC3,0x23,0xA3,0x63,0xE3,0x13,0x93,0x53,0xD3,0x33,0xB3,0x73,0xF3,
-	0x0B,0x8B,0x4B,0xCB,0x2B,0xAB,0x6B,0xEB,0x1B,0x9B,0x5B,0xDB,0x3B,0xBB,0x7B,0xFB,
-	0x07,0x87,0x47,0xC7,0x27,0xA7,0x67,0xE7,0x17,0x97,0x57,0xD7,0x37,0xB7,0x77,0xF7,
-	0x0F,0x8F,0x4F,0xCF,0x2F,0xAF,0x6F,0xEF,0x1F,0x9F,0x5F,0xDF,0x3F,0xBF,0x7F,0xFF
-};
-
 enum {
 	HDLC_FAST_IDLE,HDLC_GET_FLAG_B0,HDLC_GETFLAG_B1A6,HDLC_GETFLAG_B7,
 	HDLC_GET_DATA,HDLC_FAST_FLAG
@@ -621,7 +597,6 @@ int isdnhdlc_encode(struct isdnhdlc_vars *hdlc, const unsigned char *src,
 	return len;
 }
 
-EXPORT_SYMBOL(isdnhdlc_bit_rev_tab);
 EXPORT_SYMBOL(isdnhdlc_rcv_init);
 EXPORT_SYMBOL(isdnhdlc_decode);
 EXPORT_SYMBOL(isdnhdlc_out_init);
diff --git a/drivers/isdn/hisax/isdnhdlc.h b/drivers/isdn/hisax/isdnhdlc.h
index 5655b5f9c48e..45167d2f8fb0 100644
--- a/drivers/isdn/hisax/isdnhdlc.h
+++ b/drivers/isdn/hisax/isdnhdlc.h
@@ -57,8 +57,6 @@ struct isdnhdlc_vars {
 #define HDLC_CRC_ERROR         2
 #define HDLC_LENGTH_ERROR      3
 
-extern const unsigned char isdnhdlc_bit_rev_tab[256];
-
 extern void isdnhdlc_rcv_init (struct isdnhdlc_vars *hdlc, int do_adapt56);
 
 extern int isdnhdlc_decode (struct isdnhdlc_vars *hdlc, const unsigned char *src, int slen,int *count,
diff --git a/drivers/isdn/hisax/sedlbauer.c b/drivers/isdn/hisax/sedlbauer.c
index 9522141f4351..030d1625c5c6 100644
--- a/drivers/isdn/hisax/sedlbauer.c
+++ b/drivers/isdn/hisax/sedlbauer.c
@@ -677,7 +677,11 @@ setup_sedlbauer(struct IsdnCard *card)
 		return (0);
 #endif /* CONFIG_PCI */
 	}	
+
+#ifdef __ISAPNP__
 ready:	
+#endif
+
 	/* In case of the sedlbauer pcmcia card, this region is in use,
 	 * reserved for us by the card manager. So we do not check it
 	 * here, it would fail.
diff --git a/drivers/isdn/hisax/sedlbauer_cs.c b/drivers/isdn/hisax/sedlbauer_cs.c
index 46ed65334c51..45debde05fbd 100644
--- a/drivers/isdn/hisax/sedlbauer_cs.c
+++ b/drivers/isdn/hisax/sedlbauer_cs.c
@@ -155,9 +155,8 @@ static int sedlbauer_probe(struct pcmcia_device *link)
     DEBUG(0, "sedlbauer_attach()\n");
 
     /* Allocate space for private device-specific data */
-    local = kmalloc(sizeof(local_info_t), GFP_KERNEL);
+    local = kzalloc(sizeof(local_info_t), GFP_KERNEL);
     if (!local) return -ENOMEM;
-    memset(local, 0, sizeof(local_info_t));
     local->cardnr = -1;
 
     local->p_dev = link;
diff --git a/drivers/isdn/hisax/st5481_b.c b/drivers/isdn/hisax/st5481_b.c
index 75d0f248e4ee..fa64115cd7c7 100644
--- a/drivers/isdn/hisax/st5481_b.c
+++ b/drivers/isdn/hisax/st5481_b.c
@@ -14,6 +14,7 @@
 #include <linux/usb.h>
 #include <linux/slab.h>
 #include <linux/netdevice.h>
+#include <linux/bitrev.h>
 #include "st5481.h"
 
 static inline void B_L1L2(struct st5481_bcs *bcs, int pr, void *arg)
@@ -72,7 +73,7 @@ static void usb_b_out(struct st5481_bcs *bcs,int buf_nr)
 					register unsigned char *dest = urb->transfer_buffer+len;
 					register unsigned int count;
 					for (count = 0; count < bytes_sent; count++)
-						*dest++ = isdnhdlc_bit_rev_tab[*src++];
+						*dest++ = bitrev8(*src++);
 				}
 				len += bytes_sent;
 			} else {
diff --git a/drivers/isdn/hisax/st5481_d.c b/drivers/isdn/hisax/st5481_d.c
index 1d8c2618366c..b8c4855cc889 100644
--- a/drivers/isdn/hisax/st5481_d.c
+++ b/drivers/isdn/hisax/st5481_d.c
@@ -173,7 +173,7 @@ static void l1m_debug(struct FsmInst *fi, char *fmt, ...)
 	char buf[256];
 	
 	va_start(args, fmt);
-	vsprintf(buf, fmt, args);
+	vsnprintf(buf, sizeof(buf), fmt, args);
 	DBG(8, "%s", buf);
 	va_end(args);
 }
@@ -275,7 +275,7 @@ static void dout_debug(struct FsmInst *fi, char *fmt, ...)
 	char buf[256];
 	
 	va_start(args, fmt);
-	vsprintf(buf, fmt, args);
+	vsnprintf(buf, sizeof(buf), fmt, args);
 	DBG(0x2, "%s", buf);
 	va_end(args);
 }
diff --git a/drivers/isdn/hisax/st5481_init.c b/drivers/isdn/hisax/st5481_init.c
index 2716aa5c60f7..bb3a28a53ff4 100644
--- a/drivers/isdn/hisax/st5481_init.c
+++ b/drivers/isdn/hisax/st5481_init.c
@@ -69,12 +69,10 @@ static int probe_st5481(struct usb_interface *intf,
 	     le16_to_cpu(dev->descriptor.idProduct),
 	     number_of_leds);
 
-	adapter = kmalloc(sizeof(struct st5481_adapter), GFP_KERNEL);
+	adapter = kzalloc(sizeof(struct st5481_adapter), GFP_KERNEL);
 	if (!adapter)
 		return -ENOMEM;
 
-	memset(adapter, 0, sizeof(struct st5481_adapter));
-
 	adapter->number_of_leds = number_of_leds;
 	adapter->usb_dev = dev;
 
diff --git a/drivers/isdn/hisax/teles_cs.c b/drivers/isdn/hisax/teles_cs.c
index 6b754f183796..3e3e18239ec7 100644
--- a/drivers/isdn/hisax/teles_cs.c
+++ b/drivers/isdn/hisax/teles_cs.c
@@ -137,9 +137,8 @@ static int teles_probe(struct pcmcia_device *link)
     DEBUG(0, "teles_attach()\n");
 
     /* Allocate space for private device-specific data */
-    local = kmalloc(sizeof(local_info_t), GFP_KERNEL);
+    local = kzalloc(sizeof(local_info_t), GFP_KERNEL);
     if (!local) return -ENOMEM;
-    memset(local, 0, sizeof(local_info_t));
     local->cardnr = -1;
 
     local->p_dev = link;
diff --git a/drivers/isdn/hysdn/hycapi.c b/drivers/isdn/hysdn/hycapi.c
index 6bac43cc91bd..b2ae4ec1e49e 100644
--- a/drivers/isdn/hysdn/hycapi.c
+++ b/drivers/isdn/hysdn/hycapi.c
@@ -745,12 +745,11 @@ hycapi_capi_create(hysdn_card *card)
 		return 1;
 	}
 	if (!card->hyctrlinfo) {
-		cinfo = (hycapictrl_info *) kmalloc(sizeof(hycapictrl_info), GFP_ATOMIC);
+		cinfo = kzalloc(sizeof(hycapictrl_info), GFP_ATOMIC);
 		if (!cinfo) {
 			printk(KERN_WARNING "HYSDN: no memory for capi-ctrl.\n");
 			return -ENOMEM;
 		}
-		memset(cinfo, 0, sizeof(hycapictrl_info));
 		card->hyctrlinfo = cinfo;
 		cinfo->card = card;
 		spin_lock_init(&cinfo->lock);
diff --git a/drivers/isdn/hysdn/hysdn_boot.c b/drivers/isdn/hysdn/hysdn_boot.c
index 6d0eb0f42fca..be787e16bb79 100644
--- a/drivers/isdn/hysdn/hysdn_boot.c
+++ b/drivers/isdn/hysdn/hysdn_boot.c
@@ -278,14 +278,13 @@ pof_write_open(hysdn_card * card, unsigned char **bufp)
 		return (-ERR_ALREADY_BOOT);	/* boot already active */
 	}
 	/* error no mem available */
-	if (!(boot = kmalloc(sizeof(struct boot_data), GFP_KERNEL))) {
+	if (!(boot = kzalloc(sizeof(struct boot_data), GFP_KERNEL))) {
 		if (card->debug_flags & LOG_MEM_ERR)
 			hysdn_addlog(card, "POF open: unable to allocate mem");
 		return (-EFAULT);
 	}
 	card->boot = boot;
 	card->state = CARD_STATE_BOOTING;
-	memset(boot, 0, sizeof(struct boot_data));
 
 	card->stopcard(card);	/* first stop the card */
 	if (card->testram(card)) {
diff --git a/drivers/isdn/hysdn/hysdn_init.c b/drivers/isdn/hysdn/hysdn_init.c
index b702ed27252b..9e01748a176e 100644
--- a/drivers/isdn/hysdn/hysdn_init.c
+++ b/drivers/isdn/hysdn/hysdn_init.c
@@ -81,11 +81,10 @@ search_cards(void)
 		if (pci_enable_device(akt_pcidev))
 			continue;
 
-		if (!(card = kmalloc(sizeof(hysdn_card), GFP_KERNEL))) {
+		if (!(card = kzalloc(sizeof(hysdn_card), GFP_KERNEL))) {
 			printk(KERN_ERR "HYSDN: unable to alloc device mem \n");
 			return;
 		}
-		memset(card, 0, sizeof(hysdn_card));
 		card->myid = cardmax;	/* set own id */
 		card->bus = akt_pcidev->bus->number;
 		card->devfn = akt_pcidev->devfn;	/* slot + function */
diff --git a/drivers/isdn/hysdn/hysdn_net.c b/drivers/isdn/hysdn/hysdn_net.c
index d205249a1242..557d96c78a62 100644
--- a/drivers/isdn/hysdn/hysdn_net.c
+++ b/drivers/isdn/hysdn/hysdn_net.c
@@ -278,11 +278,10 @@ hysdn_net_create(hysdn_card * card)
 		return (-ENOMEM);
 	}
 	hysdn_net_release(card);	/* release an existing net device */
-	if ((dev = kmalloc(sizeof(struct net_local), GFP_KERNEL)) == NULL) {
+	if ((dev = kzalloc(sizeof(struct net_local), GFP_KERNEL)) == NULL) {
 		printk(KERN_WARNING "HYSDN: unable to allocate mem\n");
 		return (-ENOMEM);
 	}
-	memset(dev, 0, sizeof(struct net_local));	/* clean the structure */
 
 	spin_lock_init(&((struct net_local *) dev)->lock);
 
diff --git a/drivers/isdn/hysdn/hysdn_proclog.c b/drivers/isdn/hysdn/hysdn_proclog.c
index fcd49920b220..f241f5e551cb 100644
--- a/drivers/isdn/hysdn/hysdn_proclog.c
+++ b/drivers/isdn/hysdn/hysdn_proclog.c
@@ -204,7 +204,7 @@ hysdn_log_read(struct file *file, char __user *buf, size_t count, loff_t * off)
 {
 	struct log_data *inf;
 	int len;
-	struct proc_dir_entry *pde = PDE(file->f_dentry->d_inode);
+	struct proc_dir_entry *pde = PDE(file->f_path.dentry->d_inode);
 	struct procdata *pd = NULL;
 	hysdn_card *card;
 
@@ -354,7 +354,7 @@ static unsigned int
 hysdn_log_poll(struct file *file, poll_table * wait)
 {
 	unsigned int mask = 0;
-	struct proc_dir_entry *pde = PDE(file->f_dentry->d_inode);
+	struct proc_dir_entry *pde = PDE(file->f_path.dentry->d_inode);
 	hysdn_card *card;
 	struct procdata *pd = NULL;
 
@@ -405,8 +405,7 @@ hysdn_proclog_init(hysdn_card * card)
 
 	/* create a cardlog proc entry */
 
-	if ((pd = (struct procdata *) kmalloc(sizeof(struct procdata), GFP_KERNEL)) != NULL) {
-		memset(pd, 0, sizeof(struct procdata));
+	if ((pd = kzalloc(sizeof(struct procdata), GFP_KERNEL)) != NULL) {
 		sprintf(pd->log_name, "%s%d", PROC_LOG_BASENAME, card->myid);
 		if ((pd->log = create_proc_entry(pd->log_name, S_IFREG | S_IRUGO | S_IWUSR, hysdn_proc_entry)) != NULL) {
 		        pd->log->proc_fops = &log_fops; 
diff --git a/drivers/isdn/i4l/isdn_bsdcomp.c b/drivers/isdn/i4l/isdn_bsdcomp.c
index 0afe442db3b0..a20f33b4a220 100644
--- a/drivers/isdn/i4l/isdn_bsdcomp.c
+++ b/drivers/isdn/i4l/isdn_bsdcomp.c
@@ -331,12 +331,10 @@ static void *bsd_alloc (struct isdn_ppp_comp_data *data)
 	 * Allocate the main control structure for this instance.
 	 */
 	maxmaxcode = MAXCODE(bits);
-	db = (struct bsd_db *) kmalloc (sizeof (struct bsd_db),GFP_KERNEL);
+	db = kzalloc (sizeof (struct bsd_db),GFP_KERNEL);
 	if (!db)
 		return NULL;
 
-	memset (db, 0, sizeof(struct bsd_db));
-
 	db->xmit = data->flags & IPPP_COMP_FLAG_XMIT;
 	decomp = db->xmit ? 0 : 1;
 
diff --git a/drivers/isdn/i4l/isdn_common.c b/drivers/isdn/i4l/isdn_common.c
index 69aee2602aa6..6a2ef0a87ed9 100644
--- a/drivers/isdn/i4l/isdn_common.c
+++ b/drivers/isdn/i4l/isdn_common.c
@@ -1059,7 +1059,7 @@ isdn_info_update(void)
 static ssize_t
 isdn_read(struct file *file, char __user *buf, size_t count, loff_t * off)
 {
-	uint minor = iminor(file->f_dentry->d_inode);
+	uint minor = iminor(file->f_path.dentry->d_inode);
 	int len = 0;
 	int drvidx;
 	int chidx;
@@ -1166,7 +1166,7 @@ isdn_read(struct file *file, char __user *buf, size_t count, loff_t * off)
 static ssize_t
 isdn_write(struct file *file, const char __user *buf, size_t count, loff_t * off)
 {
-	uint minor = iminor(file->f_dentry->d_inode);
+	uint minor = iminor(file->f_path.dentry->d_inode);
 	int drvidx;
 	int chidx;
 	int retval;
@@ -1228,7 +1228,7 @@ static unsigned int
 isdn_poll(struct file *file, poll_table * wait)
 {
 	unsigned int mask = 0;
-	unsigned int minor = iminor(file->f_dentry->d_inode);
+	unsigned int minor = iminor(file->f_path.dentry->d_inode);
 	int drvidx = isdn_minor2drv(minor - ISDN_MINOR_CTRL);
 
 	lock_kernel();
@@ -2072,21 +2072,19 @@ isdn_add_channels(isdn_driver_t *d, int drvidx, int n, int adding)
 
 	if ((adding) && (d->rcverr))
 		kfree(d->rcverr);
-	if (!(d->rcverr = kmalloc(sizeof(int) * m, GFP_ATOMIC))) {
+	if (!(d->rcverr = kzalloc(sizeof(int) * m, GFP_ATOMIC))) {
 		printk(KERN_WARNING "register_isdn: Could not alloc rcverr\n");
 		return -1;
 	}
-	memset((char *) d->rcverr, 0, sizeof(int) * m);
 
 	if ((adding) && (d->rcvcount))
 		kfree(d->rcvcount);
-	if (!(d->rcvcount = kmalloc(sizeof(int) * m, GFP_ATOMIC))) {
+	if (!(d->rcvcount = kzalloc(sizeof(int) * m, GFP_ATOMIC))) {
 		printk(KERN_WARNING "register_isdn: Could not alloc rcvcount\n");
 		if (!adding)
 			kfree(d->rcverr);
 		return -1;
 	}
-	memset((char *) d->rcvcount, 0, sizeof(int) * m);
 
 	if ((adding) && (d->rpqueue)) {
 		for (j = 0; j < d->channels; j++)
@@ -2226,11 +2224,10 @@ register_isdn(isdn_if * i)
 		printk(KERN_WARNING "register_isdn: No write routine given.\n");
 		return 0;
 	}
-	if (!(d = kmalloc(sizeof(isdn_driver_t), GFP_KERNEL))) {
+	if (!(d = kzalloc(sizeof(isdn_driver_t), GFP_KERNEL))) {
 		printk(KERN_WARNING "register_isdn: Could not alloc driver-struct\n");
 		return 0;
 	}
-	memset((char *) d, 0, sizeof(isdn_driver_t));
 
 	d->maxbufsize = i->maxbufsize;
 	d->pktcount = 0;
diff --git a/drivers/isdn/i4l/isdn_net.c b/drivers/isdn/i4l/isdn_net.c
index 2e4daebfb7e0..c36c817578cb 100644
--- a/drivers/isdn/i4l/isdn_net.c
+++ b/drivers/isdn/i4l/isdn_net.c
@@ -2542,17 +2542,15 @@ isdn_net_new(char *name, struct net_device *master)
 		printk(KERN_WARNING "isdn_net: interface %s already exists\n", name);
 		return NULL;
 	}
-	if (!(netdev = (isdn_net_dev *) kmalloc(sizeof(isdn_net_dev), GFP_KERNEL))) {
+	if (!(netdev = kzalloc(sizeof(isdn_net_dev), GFP_KERNEL))) {
 		printk(KERN_WARNING "isdn_net: Could not allocate net-device\n");
 		return NULL;
 	}
-	memset(netdev, 0, sizeof(isdn_net_dev));
-	if (!(netdev->local = (isdn_net_local *) kmalloc(sizeof(isdn_net_local), GFP_KERNEL))) {
+	if (!(netdev->local = kzalloc(sizeof(isdn_net_local), GFP_KERNEL))) {
 		printk(KERN_WARNING "isdn_net: Could not allocate device locals\n");
 		kfree(netdev);
 		return NULL;
 	}
-	memset(netdev->local, 0, sizeof(isdn_net_local));
 	if (name == NULL)
 		strcpy(netdev->local->name, "         ");
 	else
diff --git a/drivers/isdn/i4l/isdn_ppp.c b/drivers/isdn/i4l/isdn_ppp.c
index 119412d6bd15..43811795b46b 100644
--- a/drivers/isdn/i4l/isdn_ppp.c
+++ b/drivers/isdn/i4l/isdn_ppp.c
@@ -667,7 +667,7 @@ isdn_ppp_poll(struct file *file, poll_table * wait)
 
 	if (is->debug & 0x2)
 		printk(KERN_DEBUG "isdn_ppp_poll: minor: %d\n",
-				iminor(file->f_dentry->d_inode));
+				iminor(file->f_path.dentry->d_inode));
 
 	/* just registers wait_queue hook. This doesn't really wait. */
 	poll_wait(file, &is->wq, wait);
@@ -876,14 +876,12 @@ isdn_ppp_init(void)
 #endif /* CONFIG_ISDN_MPP */
 
 	for (i = 0; i < ISDN_MAX_CHANNELS; i++) {
-		if (!(ippp_table[i] = (struct ippp_struct *)
-		      kmalloc(sizeof(struct ippp_struct), GFP_KERNEL))) {
+		if (!(ippp_table[i] = kzalloc(sizeof(struct ippp_struct), GFP_KERNEL))) {
 			printk(KERN_WARNING "isdn_ppp_init: Could not alloc ippp_table\n");
 			for (j = 0; j < i; j++)
 				kfree(ippp_table[j]);
 			return -1;
 		}
-		memset((char *) ippp_table[i], 0, sizeof(struct ippp_struct));
 		spin_lock_init(&ippp_table[i]->buflock);
 		ippp_table[i]->state = 0;
 		ippp_table[i]->first = ippp_table[i]->rq + NUM_RCV_BUFFS - 1;
@@ -1529,10 +1527,8 @@ static int isdn_ppp_mp_bundle_array_init(void)
 {
 	int i;
 	int sz = ISDN_MAX_CHANNELS*sizeof(ippp_bundle);
-	if( (isdn_ppp_bundle_arr = (ippp_bundle*)kmalloc(sz, 
-							GFP_KERNEL)) == NULL )
+	if( (isdn_ppp_bundle_arr = kzalloc(sz, GFP_KERNEL)) == NULL )
 		return -ENOMEM;
-	memset(isdn_ppp_bundle_arr, 0, sz);
 	for( i = 0; i < ISDN_MAX_CHANNELS; i++ )
 		spin_lock_init(&isdn_ppp_bundle_arr[i].lock);
 	return 0;
@@ -2246,13 +2242,12 @@ static void isdn_ppp_ccp_xmit_reset(struct ippp_struct *is, int proto,
 static struct ippp_ccp_reset *isdn_ppp_ccp_reset_alloc(struct ippp_struct *is)
 {
 	struct ippp_ccp_reset *r;
-	r = kmalloc(sizeof(struct ippp_ccp_reset), GFP_KERNEL);
+	r = kzalloc(sizeof(struct ippp_ccp_reset), GFP_KERNEL);
 	if(!r) {
 		printk(KERN_ERR "ippp_ccp: failed to allocate reset data"
 		       " structure - no mem\n");
 		return NULL;
 	}
-	memset(r, 0, sizeof(struct ippp_ccp_reset));
 	printk(KERN_DEBUG "ippp_ccp: allocated reset data structure %p\n", r);
 	is->reset = r;
 	return r;
@@ -2338,10 +2333,9 @@ static struct ippp_ccp_reset_state *isdn_ppp_ccp_reset_alloc_state(struct ippp_s
 		       id);
 		return NULL;
 	} else {
-		rs = kmalloc(sizeof(struct ippp_ccp_reset_state), GFP_KERNEL);
+		rs = kzalloc(sizeof(struct ippp_ccp_reset_state), GFP_KERNEL);
 		if(!rs)
 			return NULL;
-		memset(rs, 0, sizeof(struct ippp_ccp_reset_state));
 		rs->state = CCPResetIdle;
 		rs->is = is;
 		rs->id = id;
@@ -2536,6 +2530,11 @@ static struct sk_buff *isdn_ppp_decompress(struct sk_buff *skb,struct ippp_struc
   		rsparm.maxdlen = IPPP_RESET_MAXDATABYTES;
   
   		skb_out = dev_alloc_skb(is->mru + PPP_HDRLEN);
+  		if (!skb_out) {
+  			kfree_skb(skb);
+  			printk(KERN_ERR "ippp: decomp memory allocation failure\n");
+			return NULL;
+  		}
 		len = ipc->decompress(stat, skb, skb_out, &rsparm);
 		kfree_skb(skb);
 		if (len <= 0) {
diff --git a/drivers/isdn/i4l/isdn_tty.c b/drivers/isdn/i4l/isdn_tty.c
index 2b91bb07fc7f..fc80afe555b9 100644
--- a/drivers/isdn/i4l/isdn_tty.c
+++ b/drivers/isdn/i4l/isdn_tty.c
@@ -1464,7 +1464,7 @@ isdn_tty_ioctl(struct tty_struct *tty, struct file *file,
 }
 
 static void
-isdn_tty_set_termios(struct tty_struct *tty, struct termios *old_termios)
+isdn_tty_set_termios(struct tty_struct *tty, struct ktermios *old_termios)
 {
 	modem_info *info = (modem_info *) tty->driver_data;
 
diff --git a/drivers/isdn/i4l/isdn_v110.c b/drivers/isdn/i4l/isdn_v110.c
index 38619e8cd823..5484d3c38a57 100644
--- a/drivers/isdn/i4l/isdn_v110.c
+++ b/drivers/isdn/i4l/isdn_v110.c
@@ -92,9 +92,8 @@ isdn_v110_open(unsigned char key, int hdrlen, int maxsize)
 	int i;
 	isdn_v110_stream *v;
 
-	if ((v = kmalloc(sizeof(isdn_v110_stream), GFP_ATOMIC)) == NULL)
+	if ((v = kzalloc(sizeof(isdn_v110_stream), GFP_ATOMIC)) == NULL)
 		return NULL;
-	memset(v, 0, sizeof(isdn_v110_stream));
 	v->key = key;
 	v->nbits = 0;
 	for (i = 0; key & (1 << i); i++)
diff --git a/drivers/isdn/icn/icn.c b/drivers/isdn/icn/icn.c
index 730bbd07ebc7..1e699bcaba0f 100644
--- a/drivers/isdn/icn/icn.c
+++ b/drivers/isdn/icn/icn.c
@@ -1519,12 +1519,11 @@ icn_initcard(int port, char *id)
 	icn_card *card;
 	int i;
 
-	if (!(card = (icn_card *) kmalloc(sizeof(icn_card), GFP_KERNEL))) {
+	if (!(card = kzalloc(sizeof(icn_card), GFP_KERNEL))) {
 		printk(KERN_WARNING
 		       "icn: (%s) Could not allocate card-struct.\n", id);
 		return (icn_card *) 0;
 	}
-	memset((char *) card, 0, sizeof(icn_card));
 	spin_lock_init(&card->lock);
 	card->port = port;
 	card->interface.owner = THIS_MODULE;
diff --git a/drivers/isdn/isdnloop/isdnloop.c b/drivers/isdn/isdnloop/isdnloop.c
index c3ae2edaf6fa..e3add27dd0e1 100644
--- a/drivers/isdn/isdnloop/isdnloop.c
+++ b/drivers/isdn/isdnloop/isdnloop.c
@@ -1430,12 +1430,11 @@ isdnloop_initcard(char *id)
 	isdnloop_card *card;
 	int i;
 
-	if (!(card = (isdnloop_card *) kmalloc(sizeof(isdnloop_card), GFP_KERNEL))) {
+	if (!(card = kzalloc(sizeof(isdnloop_card), GFP_KERNEL))) {
 		printk(KERN_WARNING
 		 "isdnloop: (%s) Could not allocate card-struct.\n", id);
 		return (isdnloop_card *) 0;
 	}
-	memset((char *) card, 0, sizeof(isdnloop_card));
 	card->interface.owner = THIS_MODULE;
 	card->interface.channels = ISDNLOOP_BCH;
 	card->interface.hl_hdrlen  = 1; /* scratch area for storing ack flag*/ 
diff --git a/drivers/isdn/pcbit/drv.c b/drivers/isdn/pcbit/drv.c
index 1966f3410a13..11c1b0b6e390 100644
--- a/drivers/isdn/pcbit/drv.c
+++ b/drivers/isdn/pcbit/drv.c
@@ -73,14 +73,13 @@ int pcbit_init_dev(int board, int mem_base, int irq)
 	struct pcbit_dev *dev;
 	isdn_if *dev_if;
 
-	if ((dev=kmalloc(sizeof(struct pcbit_dev), GFP_KERNEL)) == NULL)
+	if ((dev=kzalloc(sizeof(struct pcbit_dev), GFP_KERNEL)) == NULL)
 	{
 		printk("pcbit_init: couldn't malloc pcbit_dev struct\n");
 		return -ENOMEM;
 	}
 
 	dev_pcbit[board] = dev;
-	memset(dev, 0, sizeof(struct pcbit_dev));
 	init_waitqueue_head(&dev->set_running_wq);
 	spin_lock_init(&dev->lock);
 
@@ -104,7 +103,7 @@ int pcbit_init_dev(int board, int mem_base, int irq)
 		return -EACCES;
 	}
 
-	dev->b1 = kmalloc(sizeof(struct pcbit_chan), GFP_KERNEL);
+	dev->b1 = kzalloc(sizeof(struct pcbit_chan), GFP_KERNEL);
 	if (!dev->b1) {
 		printk("pcbit_init: couldn't malloc pcbit_chan struct\n");
 		iounmap(dev->sh_mem);
@@ -113,7 +112,7 @@ int pcbit_init_dev(int board, int mem_base, int irq)
 		return -ENOMEM;
 	}
     
-	dev->b2 = kmalloc(sizeof(struct pcbit_chan), GFP_KERNEL);
+	dev->b2 = kzalloc(sizeof(struct pcbit_chan), GFP_KERNEL);
 	if (!dev->b2) {
 		printk("pcbit_init: couldn't malloc pcbit_chan struct\n");
 		kfree(dev->b1);
@@ -123,8 +122,6 @@ int pcbit_init_dev(int board, int mem_base, int irq)
 		return -ENOMEM;
 	}
 
-	memset(dev->b1, 0, sizeof(struct pcbit_chan));
-	memset(dev->b2, 0, sizeof(struct pcbit_chan));
 	dev->b2->id = 1;
 
 	INIT_WORK(&dev->qdelivery, pcbit_deliver);
diff --git a/drivers/isdn/pcbit/layer2.c b/drivers/isdn/pcbit/layer2.c
index 0c9f6df873fc..6ff85574e941 100644
--- a/drivers/isdn/pcbit/layer2.c
+++ b/drivers/isdn/pcbit/layer2.c
@@ -369,13 +369,12 @@ pcbit_receive(struct pcbit_dev *dev)
 			kfree(dev->read_frame);
 			dev->read_frame = NULL;
 		}
-		frame = kmalloc(sizeof(struct frame_buf), GFP_ATOMIC);
+		frame = kzalloc(sizeof(struct frame_buf), GFP_ATOMIC);
 
 		if (frame == NULL) {
 			printk(KERN_WARNING "kmalloc failed\n");
 			return;
 		}
-		memset(frame, 0, sizeof(struct frame_buf));
 
 		cpu = pcbit_readb(dev);
 		proc = pcbit_readb(dev);
diff --git a/drivers/isdn/sc/init.c b/drivers/isdn/sc/init.c
index 06c9872e8c6a..150759a5cddf 100644
--- a/drivers/isdn/sc/init.c
+++ b/drivers/isdn/sc/init.c
@@ -271,14 +271,13 @@ static int __init sc_init(void)
 		 * Horray! We found a board, Make sure we can register
 		 * it with ISDN4Linux
 		 */
-		interface = kmalloc(sizeof(isdn_if), GFP_KERNEL);
+		interface = kzalloc(sizeof(isdn_if), GFP_KERNEL);
 		if (interface == NULL) {
 			/*
 			 * Oops, can't malloc isdn_if
 			 */
 			continue;
 		}
-		memset(interface, 0, sizeof(isdn_if));
 
 		interface->owner = THIS_MODULE;
 		interface->hl_hdrlen = 0;
@@ -294,7 +293,7 @@ static int __init sc_init(void)
 		/*
 		 * Allocate the board structure
 		 */
-		sc_adapter[cinst] = kmalloc(sizeof(board), GFP_KERNEL);
+		sc_adapter[cinst] = kzalloc(sizeof(board), GFP_KERNEL);
 		if (sc_adapter[cinst] == NULL) {
 			/*
 			 * Oops, can't alloc memory for the board
@@ -302,7 +301,6 @@ static int __init sc_init(void)
 			kfree(interface);
 			continue;
 		}
-		memset(sc_adapter[cinst], 0, sizeof(board));
 		spin_lock_init(&sc_adapter[cinst]->lock);
 
 		if(!register_isdn(interface)) {
@@ -326,7 +324,7 @@ static int __init sc_init(void)
 		/*
 		 * Allocate channels status structures
 		 */
-		sc_adapter[cinst]->channel = kmalloc(sizeof(bchan) * channels, GFP_KERNEL);
+		sc_adapter[cinst]->channel = kzalloc(sizeof(bchan) * channels, GFP_KERNEL);
 		if (sc_adapter[cinst]->channel == NULL) {
 			/*
 			 * Oops, can't alloc memory for the channels
@@ -336,7 +334,6 @@ static int __init sc_init(void)
 			kfree(sc_adapter[cinst]);
 			continue;
 		}
-		memset(sc_adapter[cinst]->channel, 0, sizeof(bchan) * channels);
 
 		/*
 		 * Lock down the hardware resources
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c
index d6f614738bbd..5432d07c074d 100644
--- a/drivers/md/bitmap.c
+++ b/drivers/md/bitmap.c
@@ -212,8 +212,8 @@ char *file_path(struct file *file, char *buf, int count)
 	if (!buf)
 		return NULL;
 
-	d = file->f_dentry;
-	v = file->f_vfsmnt;
+	d = file->f_path.dentry;
+	v = file->f_path.mnt;
 
 	buf = d_path(d, v, buf, count);
 
@@ -349,7 +349,7 @@ static struct page *read_page(struct file *file, unsigned long index,
 			      unsigned long count)
 {
 	struct page *page = NULL;
-	struct inode *inode = file->f_dentry->d_inode;
+	struct inode *inode = file->f_path.dentry->d_inode;
 	struct buffer_head *bh;
 	sector_t block;
 
@@ -662,7 +662,7 @@ static void bitmap_file_put(struct bitmap *bitmap)
 	bitmap_file_unmap(bitmap);
 
 	if (file) {
-		struct inode *inode = file->f_dentry->d_inode;
+		struct inode *inode = file->f_path.dentry->d_inode;
 		invalidate_inode_pages(inode->i_mapping);
 		fput(file);
 	}
diff --git a/drivers/md/dm-bio-list.h b/drivers/md/dm-bio-list.h
index bbf4615f0e30..da4349649f7f 100644
--- a/drivers/md/dm-bio-list.h
+++ b/drivers/md/dm-bio-list.h
@@ -44,6 +44,20 @@ static inline void bio_list_merge(struct bio_list *bl, struct bio_list *bl2)
 	bl->tail = bl2->tail;
 }
 
+static inline void bio_list_merge_head(struct bio_list *bl,
+				       struct bio_list *bl2)
+{
+	if (!bl2->head)
+		return;
+
+	if (bl->head)
+		bl2->tail->bi_next = bl->head;
+	else
+		bl->tail = bl2->tail;
+
+	bl->head = bl2->head;
+}
+
 static inline struct bio *bio_list_pop(struct bio_list *bl)
 {
 	struct bio *bio = bl->head;
diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c
index a1086ee8cccd..4c2471ee054a 100644
--- a/drivers/md/dm-crypt.c
+++ b/drivers/md/dm-crypt.c
@@ -220,7 +220,7 @@ static int crypt_iv_benbi_ctr(struct crypt_config *cc, struct dm_target *ti,
 			      const char *opts)
 {
 	unsigned int bs = crypto_blkcipher_blocksize(cc->tfm);
-	int log = long_log2(bs);
+	int log = ilog2(bs);
 
 	/* we need to calculate how far we must shift the sector count
 	 * to get the cipher block count, we use this shift in _gen */
@@ -962,7 +962,7 @@ static int crypt_map(struct dm_target *ti, struct bio *bio,
 	atomic_set(&io->pending, 0);
 	kcryptd_queue_io(io);
 
-	return 0;
+	return DM_MAPIO_SUBMITTED;
 }
 
 static int crypt_status(struct dm_target *ti, status_type_t type,
diff --git a/drivers/md/dm-emc.c b/drivers/md/dm-emc.c
index 2b2d45d7baaa..265c467854da 100644
--- a/drivers/md/dm-emc.c
+++ b/drivers/md/dm-emc.c
@@ -40,7 +40,7 @@ static inline void free_bio(struct bio *bio)
 
 static int emc_endio(struct bio *bio, unsigned int bytes_done, int error)
 {
-	struct path *path = bio->bi_private;
+	struct dm_path *path = bio->bi_private;
 
 	if (bio->bi_size)
 		return 1;
@@ -61,7 +61,7 @@ static int emc_endio(struct bio *bio, unsigned int bytes_done, int error)
 	return 0;
 }
 
-static struct bio *get_failover_bio(struct path *path, unsigned data_size)
+static struct bio *get_failover_bio(struct dm_path *path, unsigned data_size)
 {
 	struct bio *bio;
 	struct page *page;
@@ -96,7 +96,7 @@ static struct bio *get_failover_bio(struct path *path, unsigned data_size)
 }
 
 static struct request *get_failover_req(struct emc_handler *h,
-					struct bio *bio, struct path *path)
+					struct bio *bio, struct dm_path *path)
 {
 	struct request *rq;
 	struct block_device *bdev = bio->bi_bdev;
@@ -133,7 +133,7 @@ static struct request *get_failover_req(struct emc_handler *h,
 }
 
 static struct request *emc_trespass_get(struct emc_handler *h,
-					struct path *path)
+					struct dm_path *path)
 {
 	struct bio *bio;
 	struct request *rq;
@@ -191,7 +191,7 @@ static struct request *emc_trespass_get(struct emc_handler *h,
 }
 
 static void emc_pg_init(struct hw_handler *hwh, unsigned bypassed,
-			struct path *path)
+			struct dm_path *path)
 {
 	struct request *rq;
 	struct request_queue *q = bdev_get_queue(path->dev->bdev);
diff --git a/drivers/md/dm-hw-handler.h b/drivers/md/dm-hw-handler.h
index 15f5629e231a..32eff28e4adc 100644
--- a/drivers/md/dm-hw-handler.h
+++ b/drivers/md/dm-hw-handler.h
@@ -32,7 +32,7 @@ struct hw_handler_type {
 	void (*destroy) (struct hw_handler *hwh);
 
 	void (*pg_init) (struct hw_handler *hwh, unsigned bypassed,
-			 struct path *path);
+			 struct dm_path *path);
 	unsigned (*error) (struct hw_handler *hwh, struct bio *bio);
 	int (*status) (struct hw_handler *hwh, status_type_t type,
 		       char *result, unsigned int maxlen);
diff --git a/drivers/md/dm-io.c b/drivers/md/dm-io.c
index da663d2ff552..4eb73d395213 100644
--- a/drivers/md/dm-io.c
+++ b/drivers/md/dm-io.c
@@ -92,12 +92,12 @@ void dm_io_put(unsigned int num_pages)
  *---------------------------------------------------------------*/
 static inline void bio_set_region(struct bio *bio, unsigned region)
 {
-	bio->bi_io_vec[bio->bi_max_vecs - 1].bv_len = region;
+	bio->bi_io_vec[bio->bi_max_vecs].bv_len = region;
 }
 
 static inline unsigned bio_get_region(struct bio *bio)
 {
-	return bio->bi_io_vec[bio->bi_max_vecs - 1].bv_len;
+	return bio->bi_io_vec[bio->bi_max_vecs].bv_len;
 }
 
 /*-----------------------------------------------------------------
@@ -136,6 +136,7 @@ static int endio(struct bio *bio, unsigned int done, int error)
 		zero_fill_bio(bio);
 
 	dec_count(io, bio_get_region(bio), error);
+	bio->bi_max_vecs++;
 	bio_put(bio);
 
 	return 0;
@@ -250,16 +251,18 @@ static void do_region(int rw, unsigned int region, struct io_region *where,
 
 	while (remaining) {
 		/*
-		 * Allocate a suitably sized bio, we add an extra
-		 * bvec for bio_get/set_region().
+		 * Allocate a suitably sized-bio: we add an extra
+		 * bvec for bio_get/set_region() and decrement bi_max_vecs
+		 * to hide it from bio_add_page().
 		 */
-		num_bvecs = (remaining / (PAGE_SIZE >> 9)) + 2;
+		num_bvecs = (remaining / (PAGE_SIZE >> SECTOR_SHIFT)) + 2;
 		bio = bio_alloc_bioset(GFP_NOIO, num_bvecs, _bios);
 		bio->bi_sector = where->sector + (where->count - remaining);
 		bio->bi_bdev = where->bdev;
 		bio->bi_end_io = endio;
 		bio->bi_private = io;
 		bio->bi_destructor = dm_bio_destructor;
+		bio->bi_max_vecs--;
 		bio_set_region(bio, region);
 
 		/*
@@ -302,7 +305,7 @@ static void dispatch_io(int rw, unsigned int num_regions,
 	}
 
 	/*
-	 * Drop the extra refence that we were holding to avoid
+	 * Drop the extra reference that we were holding to avoid
 	 * the io being completed too early.
 	 */
 	dec_count(io, 0, 0);
diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c
index 4510ad8f971c..cd6a184536a1 100644
--- a/drivers/md/dm-ioctl.c
+++ b/drivers/md/dm-ioctl.c
@@ -765,7 +765,7 @@ out:
 static int do_suspend(struct dm_ioctl *param)
 {
 	int r = 0;
-	int do_lockfs = 1;
+	unsigned suspend_flags = DM_SUSPEND_LOCKFS_FLAG;
 	struct mapped_device *md;
 
 	md = find_device(param);
@@ -773,10 +773,12 @@ static int do_suspend(struct dm_ioctl *param)
 		return -ENXIO;
 
 	if (param->flags & DM_SKIP_LOCKFS_FLAG)
-		do_lockfs = 0;
+		suspend_flags &= ~DM_SUSPEND_LOCKFS_FLAG;
+	if (param->flags & DM_NOFLUSH_FLAG)
+		suspend_flags |= DM_SUSPEND_NOFLUSH_FLAG;
 
 	if (!dm_suspended(md))
-		r = dm_suspend(md, do_lockfs);
+		r = dm_suspend(md, suspend_flags);
 
 	if (!r)
 		r = __dev_status(md, param);
@@ -788,7 +790,7 @@ static int do_suspend(struct dm_ioctl *param)
 static int do_resume(struct dm_ioctl *param)
 {
 	int r = 0;
-	int do_lockfs = 1;
+	unsigned suspend_flags = DM_SUSPEND_LOCKFS_FLAG;
 	struct hash_cell *hc;
 	struct mapped_device *md;
 	struct dm_table *new_map;
@@ -814,9 +816,11 @@ static int do_resume(struct dm_ioctl *param)
 	if (new_map) {
 		/* Suspend if it isn't already suspended */
 		if (param->flags & DM_SKIP_LOCKFS_FLAG)
-			do_lockfs = 0;
+			suspend_flags &= ~DM_SUSPEND_LOCKFS_FLAG;
+		if (param->flags & DM_NOFLUSH_FLAG)
+			suspend_flags |= DM_SUSPEND_NOFLUSH_FLAG;
 		if (!dm_suspended(md))
-			dm_suspend(md, do_lockfs);
+			dm_suspend(md, suspend_flags);
 
 		r = dm_swap_table(md, new_map);
 		if (r) {
diff --git a/drivers/md/dm-linear.c b/drivers/md/dm-linear.c
index 00234909b3db..17753d80ad22 100644
--- a/drivers/md/dm-linear.c
+++ b/drivers/md/dm-linear.c
@@ -77,7 +77,7 @@ static int linear_map(struct dm_target *ti, struct bio *bio,
 	bio->bi_bdev = lc->dev->bdev;
 	bio->bi_sector = lc->start + (bio->bi_sector - ti->begin);
 
-	return 1;
+	return DM_MAPIO_REMAPPED;
 }
 
 static int linear_status(struct dm_target *ti, status_type_t type,
@@ -108,7 +108,7 @@ static int linear_ioctl(struct dm_target *ti, struct inode *inode,
 	struct dentry fake_dentry = {};
 
 	fake_file.f_mode = lc->dev->mode;
-	fake_file.f_dentry = &fake_dentry;
+	fake_file.f_path.dentry = &fake_dentry;
 	fake_dentry.d_inode = bdev->bd_inode;
 
 	return blkdev_driver_ioctl(bdev->bd_inode, &fake_file, bdev->bd_disk, cmd, arg);
diff --git a/drivers/md/dm-log.c b/drivers/md/dm-log.c
index 64b764bd02cc..6a9261351848 100644
--- a/drivers/md/dm-log.c
+++ b/drivers/md/dm-log.c
@@ -466,6 +466,7 @@ static int disk_resume(struct dirty_log *log)
 	/* copy clean across to sync */
 	memcpy(lc->sync_bits, lc->clean_bits, size);
 	lc->sync_count = count_bits32(lc->clean_bits, lc->bitset_uint32_count);
+	lc->sync_search = 0;
 
 	/* set the correct number of regions in the header */
 	lc->header.nr_regions = lc->region_count;
@@ -480,6 +481,13 @@ static uint32_t core_get_region_size(struct dirty_log *log)
 	return lc->region_size;
 }
 
+static int core_resume(struct dirty_log *log)
+{
+	struct log_c *lc = (struct log_c *) log->context;
+	lc->sync_search = 0;
+	return 0;
+}
+
 static int core_is_clean(struct dirty_log *log, region_t region)
 {
 	struct log_c *lc = (struct log_c *) log->context;
@@ -549,16 +557,19 @@ static int core_get_resync_work(struct dirty_log *log, region_t *region)
 	return 1;
 }
 
-static void core_complete_resync_work(struct dirty_log *log, region_t region,
-				      int success)
+static void core_set_region_sync(struct dirty_log *log, region_t region,
+				 int in_sync)
 {
 	struct log_c *lc = (struct log_c *) log->context;
 
 	log_clear_bit(lc, lc->recovering_bits, region);
-	if (success) {
+	if (in_sync) {
 		log_set_bit(lc, lc->sync_bits, region);
                 lc->sync_count++;
-        }
+        } else if (log_test_bit(lc->sync_bits, region)) {
+		lc->sync_count--;
+		log_clear_bit(lc, lc->sync_bits, region);
+	}
 }
 
 static region_t core_get_sync_count(struct dirty_log *log)
@@ -618,6 +629,7 @@ static struct dirty_log_type _core_type = {
 	.module = THIS_MODULE,
 	.ctr = core_ctr,
 	.dtr = core_dtr,
+	.resume = core_resume,
 	.get_region_size = core_get_region_size,
 	.is_clean = core_is_clean,
 	.in_sync = core_in_sync,
@@ -625,7 +637,7 @@ static struct dirty_log_type _core_type = {
 	.mark_region = core_mark_region,
 	.clear_region = core_clear_region,
 	.get_resync_work = core_get_resync_work,
-	.complete_resync_work = core_complete_resync_work,
+	.set_region_sync = core_set_region_sync,
 	.get_sync_count = core_get_sync_count,
 	.status = core_status,
 };
@@ -644,7 +656,7 @@ static struct dirty_log_type _disk_type = {
 	.mark_region = core_mark_region,
 	.clear_region = core_clear_region,
 	.get_resync_work = core_get_resync_work,
-	.complete_resync_work = core_complete_resync_work,
+	.set_region_sync = core_set_region_sync,
 	.get_sync_count = core_get_sync_count,
 	.status = disk_status,
 };
diff --git a/drivers/md/dm-log.h b/drivers/md/dm-log.h
index 5ae5309ebf28..86a301c8daf1 100644
--- a/drivers/md/dm-log.h
+++ b/drivers/md/dm-log.h
@@ -90,12 +90,12 @@ struct dirty_log_type {
 	int (*get_resync_work)(struct dirty_log *log, region_t *region);
 
 	/*
-	 * This notifies the log that the resync of an area has
-	 * been completed.  The log should then mark this region
-	 * as CLEAN.
+	 * This notifies the log that the resync status of a region
+	 * has changed.  It also clears the region from the recovering
+	 * list (if present).
 	 */
-	void (*complete_resync_work)(struct dirty_log *log,
-				     region_t region, int success);
+	void (*set_region_sync)(struct dirty_log *log,
+				region_t region, int in_sync);
 
         /*
 	 * Returns the number of regions that are in sync.
diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c
index cf8bf052138e..3aa013506967 100644
--- a/drivers/md/dm-mpath.c
+++ b/drivers/md/dm-mpath.c
@@ -31,7 +31,7 @@ struct pgpath {
 	struct priority_group *pg;	/* Owning PG */
 	unsigned fail_count;		/* Cumulative failure count */
 
-	struct path path;
+	struct dm_path path;
 };
 
 #define path_to_pgpath(__pgp) container_of((__pgp), struct pgpath, path)
@@ -229,7 +229,7 @@ static void __switch_pg(struct multipath *m, struct pgpath *pgpath)
 
 static int __choose_path_in_pg(struct multipath *m, struct priority_group *pg)
 {
-	struct path *path;
+	struct dm_path *path;
 
 	path = pg->ps.type->select_path(&pg->ps, &m->repeat_count);
 	if (!path)
@@ -282,10 +282,27 @@ failed:
 	m->current_pg = NULL;
 }
 
+/*
+ * Check whether bios must be queued in the device-mapper core rather
+ * than here in the target.
+ *
+ * m->lock must be held on entry.
+ *
+ * If m->queue_if_no_path and m->saved_queue_if_no_path hold the
+ * same value then we are not between multipath_presuspend()
+ * and multipath_resume() calls and we have no need to check
+ * for the DMF_NOFLUSH_SUSPENDING flag.
+ */
+static int __must_push_back(struct multipath *m)
+{
+	return (m->queue_if_no_path != m->saved_queue_if_no_path &&
+		dm_noflush_suspending(m->ti));
+}
+
 static int map_io(struct multipath *m, struct bio *bio, struct mpath_io *mpio,
 		  unsigned was_queued)
 {
-	int r = 1;
+	int r = DM_MAPIO_REMAPPED;
 	unsigned long flags;
 	struct pgpath *pgpath;
 
@@ -310,11 +327,13 @@ static int map_io(struct multipath *m, struct bio *bio, struct mpath_io *mpio,
 		    !m->queue_io)
 			queue_work(kmultipathd, &m->process_queued_ios);
 		pgpath = NULL;
-		r = 0;
-	} else if (!pgpath)
-		r = -EIO;		/* Failed */
-	else
+		r = DM_MAPIO_SUBMITTED;
+	} else if (pgpath)
 		bio->bi_bdev = pgpath->path.dev->bdev;
+	else if (__must_push_back(m))
+		r = DM_MAPIO_REQUEUE;
+	else
+		r = -EIO;	/* Failed */
 
 	mpio->pgpath = pgpath;
 
@@ -372,8 +391,10 @@ static void dispatch_queued_ios(struct multipath *m)
 		r = map_io(m, bio, mpio, 1);
 		if (r < 0)
 			bio_endio(bio, bio->bi_size, r);
-		else if (r == 1)
+		else if (r == DM_MAPIO_REMAPPED)
 			generic_make_request(bio);
+		else if (r == DM_MAPIO_REQUEUE)
+			bio_endio(bio, bio->bi_size, -EIO);
 
 		bio = next;
 	}
@@ -783,7 +804,7 @@ static int multipath_map(struct dm_target *ti, struct bio *bio,
 	map_context->ptr = mpio;
 	bio->bi_rw |= (1 << BIO_RW_FAILFAST);
 	r = map_io(m, bio, mpio, 0);
-	if (r < 0)
+	if (r < 0 || r == DM_MAPIO_REQUEUE)
 		mempool_free(mpio, m->mpio_pool);
 
 	return r;
@@ -957,7 +978,7 @@ static int bypass_pg_num(struct multipath *m, const char *pgstr, int bypassed)
 /*
  * pg_init must call this when it has completed its initialisation
  */
-void dm_pg_init_complete(struct path *path, unsigned err_flags)
+void dm_pg_init_complete(struct dm_path *path, unsigned err_flags)
 {
 	struct pgpath *pgpath = path_to_pgpath(path);
 	struct priority_group *pg = pgpath->pg;
@@ -1007,7 +1028,10 @@ static int do_end_io(struct multipath *m, struct bio *bio,
 
 	spin_lock_irqsave(&m->lock, flags);
 	if (!m->nr_valid_paths) {
-		if (!m->queue_if_no_path) {
+		if (__must_push_back(m)) {
+			spin_unlock_irqrestore(&m->lock, flags);
+			return DM_ENDIO_REQUEUE;
+		} else if (!m->queue_if_no_path) {
 			spin_unlock_irqrestore(&m->lock, flags);
 			return -EIO;
 		} else {
@@ -1042,7 +1066,7 @@ static int do_end_io(struct multipath *m, struct bio *bio,
 		queue_work(kmultipathd, &m->process_queued_ios);
 	spin_unlock_irqrestore(&m->lock, flags);
 
-	return 1;	/* io not complete */
+	return DM_ENDIO_INCOMPLETE;	/* io not complete */
 }
 
 static int multipath_end_io(struct dm_target *ti, struct bio *bio,
@@ -1060,7 +1084,7 @@ static int multipath_end_io(struct dm_target *ti, struct bio *bio,
 		if (ps->type->end_io)
 			ps->type->end_io(ps, &pgpath->path);
 	}
-	if (r <= 0)
+	if (r != DM_ENDIO_INCOMPLETE)
 		mempool_free(mpio, m->mpio_pool);
 
 	return r;
@@ -1272,7 +1296,7 @@ static int multipath_ioctl(struct dm_target *ti, struct inode *inode,
 	struct dentry fake_dentry = {};
 	int r = 0;
 
-	fake_file.f_dentry = &fake_dentry;
+	fake_file.f_path.dentry = &fake_dentry;
 
 	spin_lock_irqsave(&m->lock, flags);
 
diff --git a/drivers/md/dm-mpath.h b/drivers/md/dm-mpath.h
index 8a4bf2b6d52e..b9cdcbb3ed59 100644
--- a/drivers/md/dm-mpath.h
+++ b/drivers/md/dm-mpath.h
@@ -11,7 +11,7 @@
 
 struct dm_dev;
 
-struct path {
+struct dm_path {
 	struct dm_dev *dev;	/* Read-only */
 	unsigned is_active;	/* Read-only */
 
@@ -20,6 +20,6 @@ struct path {
 };
 
 /* Callback for hwh_pg_init_fn to use when complete */
-void dm_pg_init_complete(struct path *path, unsigned err_flags);
+void dm_pg_init_complete(struct dm_path *path, unsigned err_flags);
 
 #endif
diff --git a/drivers/md/dm-path-selector.h b/drivers/md/dm-path-selector.h
index 732d06a84f85..27357b85d73d 100644
--- a/drivers/md/dm-path-selector.h
+++ b/drivers/md/dm-path-selector.h
@@ -44,7 +44,7 @@ struct path_selector_type {
 	 * Add an opaque path object, along with some selector specific
 	 * path args (eg, path priority).
 	 */
-	int (*add_path) (struct path_selector *ps, struct path *path,
+	int (*add_path) (struct path_selector *ps, struct dm_path *path,
 			 int argc, char **argv, char **error);
 
 	/*
@@ -55,27 +55,27 @@ struct path_selector_type {
 	 * calling the function again.  0 means don't call it again unless
 	 * the path fails.
 	 */
-	struct path *(*select_path) (struct path_selector *ps,
+	struct dm_path *(*select_path) (struct path_selector *ps,
 				     unsigned *repeat_count);
 
 	/*
 	 * Notify the selector that a path has failed.
 	 */
-	void (*fail_path) (struct path_selector *ps, struct path *p);
+	void (*fail_path) (struct path_selector *ps, struct dm_path *p);
 
 	/*
 	 * Ask selector to reinstate a path.
 	 */
-	int (*reinstate_path) (struct path_selector *ps, struct path *p);
+	int (*reinstate_path) (struct path_selector *ps, struct dm_path *p);
 
 	/*
 	 * Table content based on parameters added in ps_add_path_fn
 	 * or path selector status
 	 */
-	int (*status) (struct path_selector *ps, struct path *path,
+	int (*status) (struct path_selector *ps, struct dm_path *path,
 		       status_type_t type, char *result, unsigned int maxlen);
 
-	int (*end_io) (struct path_selector *ps, struct path *path);
+	int (*end_io) (struct path_selector *ps, struct dm_path *path);
 };
 
 /* Register a path selector */
diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c
index fc8cbb168e3e..23a642619bed 100644
--- a/drivers/md/dm-raid1.c
+++ b/drivers/md/dm-raid1.c
@@ -344,6 +344,17 @@ static void dispatch_bios(struct mirror_set *ms, struct bio_list *bio_list)
 	}
 }
 
+static void complete_resync_work(struct region *reg, int success)
+{
+	struct region_hash *rh = reg->rh;
+
+	rh->log->type->set_region_sync(rh->log, reg->key, success);
+	dispatch_bios(rh->ms, &reg->delayed_bios);
+	if (atomic_dec_and_test(&rh->recovery_in_flight))
+		wake_up_all(&_kmirrord_recovery_stopped);
+	up(&rh->recovery_count);
+}
+
 static void rh_update_states(struct region_hash *rh)
 {
 	struct region *reg, *next;
@@ -383,11 +394,7 @@ static void rh_update_states(struct region_hash *rh)
 	 */
 	list_for_each_entry_safe (reg, next, &recovered, list) {
 		rh->log->type->clear_region(rh->log, reg->key);
-		rh->log->type->complete_resync_work(rh->log, reg->key, 1);
-		dispatch_bios(rh->ms, &reg->delayed_bios);
-		if (atomic_dec_and_test(&rh->recovery_in_flight))
-			wake_up_all(&_kmirrord_recovery_stopped);
-		up(&rh->recovery_count);
+		complete_resync_work(reg, 1);
 		mempool_free(reg, rh->region_pool);
 	}
 
@@ -1137,7 +1144,7 @@ static int mirror_map(struct dm_target *ti, struct bio *bio,
 
 	if (rw == WRITE) {
 		queue_bio(ms, bio, rw);
-		return 0;
+		return DM_MAPIO_SUBMITTED;
 	}
 
 	r = ms->rh.log->type->in_sync(ms->rh.log,
@@ -1146,7 +1153,7 @@ static int mirror_map(struct dm_target *ti, struct bio *bio,
 		return r;
 
 	if (r == -EWOULDBLOCK)	/* FIXME: ugly */
-		r = 0;
+		r = DM_MAPIO_SUBMITTED;
 
 	/*
 	 * We don't want to fast track a recovery just for a read
@@ -1159,7 +1166,7 @@ static int mirror_map(struct dm_target *ti, struct bio *bio,
 	if (!r) {
 		/* Pass this io over to the daemon */
 		queue_bio(ms, bio, rw);
-		return 0;
+		return DM_MAPIO_SUBMITTED;
 	}
 
 	m = choose_mirror(ms, bio->bi_sector);
@@ -1167,7 +1174,7 @@ static int mirror_map(struct dm_target *ti, struct bio *bio,
 		return -EIO;
 
 	map_bio(ms, m, bio);
-	return 1;
+	return DM_MAPIO_REMAPPED;
 }
 
 static int mirror_end_io(struct dm_target *ti, struct bio *bio,
diff --git a/drivers/md/dm-round-robin.c b/drivers/md/dm-round-robin.c
index 6f9fcd4db9b5..a348a97b65af 100644
--- a/drivers/md/dm-round-robin.c
+++ b/drivers/md/dm-round-robin.c
@@ -21,7 +21,7 @@
  *---------------------------------------------------------------*/
 struct path_info {
 	struct list_head list;
-	struct path *path;
+	struct dm_path *path;
 	unsigned repeat_count;
 };
 
@@ -80,7 +80,7 @@ static void rr_destroy(struct path_selector *ps)
 	ps->context = NULL;
 }
 
-static int rr_status(struct path_selector *ps, struct path *path,
+static int rr_status(struct path_selector *ps, struct dm_path *path,
 		     status_type_t type, char *result, unsigned int maxlen)
 {
 	struct path_info *pi;
@@ -106,7 +106,7 @@ static int rr_status(struct path_selector *ps, struct path *path,
  * Called during initialisation to register each path with an
  * optional repeat_count.
  */
-static int rr_add_path(struct path_selector *ps, struct path *path,
+static int rr_add_path(struct path_selector *ps, struct dm_path *path,
 		       int argc, char **argv, char **error)
 {
 	struct selector *s = (struct selector *) ps->context;
@@ -141,7 +141,7 @@ static int rr_add_path(struct path_selector *ps, struct path *path,
 	return 0;
 }
 
-static void rr_fail_path(struct path_selector *ps, struct path *p)
+static void rr_fail_path(struct path_selector *ps, struct dm_path *p)
 {
 	struct selector *s = (struct selector *) ps->context;
 	struct path_info *pi = p->pscontext;
@@ -149,7 +149,7 @@ static void rr_fail_path(struct path_selector *ps, struct path *p)
 	list_move(&pi->list, &s->invalid_paths);
 }
 
-static int rr_reinstate_path(struct path_selector *ps, struct path *p)
+static int rr_reinstate_path(struct path_selector *ps, struct dm_path *p)
 {
 	struct selector *s = (struct selector *) ps->context;
 	struct path_info *pi = p->pscontext;
@@ -159,7 +159,7 @@ static int rr_reinstate_path(struct path_selector *ps, struct path *p)
 	return 0;
 }
 
-static struct path *rr_select_path(struct path_selector *ps,
+static struct dm_path *rr_select_path(struct path_selector *ps,
 				   unsigned *repeat_count)
 {
 	struct selector *s = (struct selector *) ps->context;
diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c
index b0ce2ce82278..0821a2b68a73 100644
--- a/drivers/md/dm-snap.c
+++ b/drivers/md/dm-snap.c
@@ -39,7 +39,7 @@
  */
 #define SNAPSHOT_PAGES 256
 
-struct workqueue_struct *ksnapd;
+static struct workqueue_struct *ksnapd;
 static void flush_queued_bios(struct work_struct *work);
 
 struct pending_exception {
@@ -564,6 +564,17 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv)
 	return r;
 }
 
+static void __free_exceptions(struct dm_snapshot *s)
+{
+	kcopyd_client_destroy(s->kcopyd_client);
+	s->kcopyd_client = NULL;
+
+	exit_exception_table(&s->pending, pending_cache);
+	exit_exception_table(&s->complete, exception_cache);
+
+	s->store.destroy(&s->store);
+}
+
 static void snapshot_dtr(struct dm_target *ti)
 {
 	struct dm_snapshot *s = (struct dm_snapshot *) ti->private;
@@ -574,13 +585,7 @@ static void snapshot_dtr(struct dm_target *ti)
 	/* After this returns there can be no new kcopyd jobs. */
 	unregister_snapshot(s);
 
-	kcopyd_client_destroy(s->kcopyd_client);
-
-	exit_exception_table(&s->pending, pending_cache);
-	exit_exception_table(&s->complete, exception_cache);
-
-	/* Deallocate memory used */
-	s->store.destroy(&s->store);
+	__free_exceptions(s);
 
 	dm_put_device(ti, s->origin);
 	dm_put_device(ti, s->cow);
@@ -868,7 +873,7 @@ static int snapshot_map(struct dm_target *ti, struct bio *bio,
 {
 	struct exception *e;
 	struct dm_snapshot *s = (struct dm_snapshot *) ti->private;
-	int r = 1;
+	int r = DM_MAPIO_REMAPPED;
 	chunk_t chunk;
 	struct pending_exception *pe = NULL;
 
@@ -914,7 +919,7 @@ static int snapshot_map(struct dm_target *ti, struct bio *bio,
 		remap_exception(s, &pe->e, bio);
 		bio_list_add(&pe->snapshot_bios, bio);
 
-		r = 0;
+		r = DM_MAPIO_SUBMITTED;
 
 		if (!pe->started) {
 			/* this is protected by snap->lock */
@@ -992,7 +997,7 @@ static int snapshot_status(struct dm_target *ti, status_type_t type,
  *---------------------------------------------------------------*/
 static int __origin_write(struct list_head *snapshots, struct bio *bio)
 {
-	int r = 1, first = 0;
+	int r = DM_MAPIO_REMAPPED, first = 0;
 	struct dm_snapshot *snap;
 	struct exception *e;
 	struct pending_exception *pe, *next_pe, *primary_pe = NULL;
@@ -1050,7 +1055,7 @@ static int __origin_write(struct list_head *snapshots, struct bio *bio)
 
 			bio_list_add(&primary_pe->origin_bios, bio);
 
-			r = 0;
+			r = DM_MAPIO_SUBMITTED;
 		}
 
 		if (!pe->primary_pe) {
@@ -1099,7 +1104,7 @@ static int __origin_write(struct list_head *snapshots, struct bio *bio)
 static int do_origin(struct dm_dev *origin, struct bio *bio)
 {
 	struct origin *o;
-	int r = 1;
+	int r = DM_MAPIO_REMAPPED;
 
 	down_read(&_origins_lock);
 	o = __lookup_origin(origin->bdev);
@@ -1156,7 +1161,7 @@ static int origin_map(struct dm_target *ti, struct bio *bio,
 		return -EOPNOTSUPP;
 
 	/* Only tell snapshots if this is a write */
-	return (bio_rw(bio) == WRITE) ? do_origin(dev, bio) : 1;
+	return (bio_rw(bio) == WRITE) ? do_origin(dev, bio) : DM_MAPIO_REMAPPED;
 }
 
 #define min_not_zero(l, r) (l == 0) ? r : ((r == 0) ? l : min(l, r))
diff --git a/drivers/md/dm-stripe.c b/drivers/md/dm-stripe.c
index 6c29fcecd892..51f5e0760012 100644
--- a/drivers/md/dm-stripe.c
+++ b/drivers/md/dm-stripe.c
@@ -186,7 +186,7 @@ static int stripe_map(struct dm_target *ti, struct bio *bio,
 	bio->bi_bdev = sc->stripe[stripe].dev->bdev;
 	bio->bi_sector = sc->stripe[stripe].physical_start +
 	    (chunk << sc->chunk_shift) + (offset & sc->chunk_mask);
-	return 1;
+	return DM_MAPIO_REMAPPED;
 }
 
 static int stripe_status(struct dm_target *ti,
diff --git a/drivers/md/dm-zero.c b/drivers/md/dm-zero.c
index ea569f7348d2..f314d7dc9c26 100644
--- a/drivers/md/dm-zero.c
+++ b/drivers/md/dm-zero.c
@@ -46,7 +46,7 @@ static int zero_map(struct dm_target *ti, struct bio *bio,
 	bio_endio(bio, bio->bi_size, 0);
 
 	/* accepted bio, don't make new request */
-	return 0;
+	return DM_MAPIO_SUBMITTED;
 }
 
 static struct target_type zero_target = {
diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index 7ec1b112a6d5..fe7c56e10435 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -68,10 +68,12 @@ union map_info *dm_get_mapinfo(struct bio *bio)
 #define DMF_FROZEN 2
 #define DMF_FREEING 3
 #define DMF_DELETING 4
+#define DMF_NOFLUSH_SUSPENDING 5
 
 struct mapped_device {
 	struct rw_semaphore io_lock;
 	struct semaphore suspend_lock;
+	spinlock_t pushback_lock;
 	rwlock_t map_lock;
 	atomic_t holders;
 	atomic_t open_count;
@@ -89,7 +91,8 @@ struct mapped_device {
 	 */
 	atomic_t pending;
 	wait_queue_head_t wait;
- 	struct bio_list deferred;
+	struct bio_list deferred;
+	struct bio_list pushback;
 
 	/*
 	 * The current mapping.
@@ -444,23 +447,50 @@ int dm_set_geometry(struct mapped_device *md, struct hd_geometry *geo)
  *   you this clearly demarcated crap.
  *---------------------------------------------------------------*/
 
+static int __noflush_suspending(struct mapped_device *md)
+{
+	return test_bit(DMF_NOFLUSH_SUSPENDING, &md->flags);
+}
+
 /*
  * Decrements the number of outstanding ios that a bio has been
  * cloned into, completing the original io if necc.
  */
 static void dec_pending(struct dm_io *io, int error)
 {
-	if (error)
+	unsigned long flags;
+
+	/* Push-back supersedes any I/O errors */
+	if (error && !(io->error > 0 && __noflush_suspending(io->md)))
 		io->error = error;
 
 	if (atomic_dec_and_test(&io->io_count)) {
+		if (io->error == DM_ENDIO_REQUEUE) {
+			/*
+			 * Target requested pushing back the I/O.
+			 * This must be handled before the sleeper on
+			 * suspend queue merges the pushback list.
+			 */
+			spin_lock_irqsave(&io->md->pushback_lock, flags);
+			if (__noflush_suspending(io->md))
+				bio_list_add(&io->md->pushback, io->bio);
+			else
+				/* noflush suspend was interrupted. */
+				io->error = -EIO;
+			spin_unlock_irqrestore(&io->md->pushback_lock, flags);
+		}
+
 		if (end_io_acct(io))
 			/* nudge anyone waiting on suspend queue */
 			wake_up(&io->md->wait);
 
-		blk_add_trace_bio(io->md->queue, io->bio, BLK_TA_COMPLETE);
+		if (io->error != DM_ENDIO_REQUEUE) {
+			blk_add_trace_bio(io->md->queue, io->bio,
+					  BLK_TA_COMPLETE);
+
+			bio_endio(io->bio, io->bio->bi_size, io->error);
+		}
 
-		bio_endio(io->bio, io->bio->bi_size, io->error);
 		free_io(io->md, io);
 	}
 }
@@ -480,12 +510,19 @@ static int clone_endio(struct bio *bio, unsigned int done, int error)
 
 	if (endio) {
 		r = endio(tio->ti, bio, error, &tio->info);
-		if (r < 0)
+		if (r < 0 || r == DM_ENDIO_REQUEUE)
+			/*
+			 * error and requeue request are handled
+			 * in dec_pending().
+			 */
 			error = r;
-
-		else if (r > 0)
-			/* the target wants another shot at the io */
+		else if (r == DM_ENDIO_INCOMPLETE)
+			/* The target will handle the io */
 			return 1;
+		else if (r) {
+			DMWARN("unimplemented target endio return value: %d", r);
+			BUG();
+		}
 	}
 
 	dec_pending(tio->io, error);
@@ -543,7 +580,7 @@ static void __map_bio(struct dm_target *ti, struct bio *clone,
 	atomic_inc(&tio->io->io_count);
 	sector = clone->bi_sector;
 	r = ti->type->map(ti, clone, &tio->info);
-	if (r > 0) {
+	if (r == DM_MAPIO_REMAPPED) {
 		/* the bio has been remapped so dispatch it */
 
 		blk_add_trace_remap(bdev_get_queue(clone->bi_bdev), clone,
@@ -551,10 +588,8 @@ static void __map_bio(struct dm_target *ti, struct bio *clone,
 				    clone->bi_sector);
 
 		generic_make_request(clone);
-	}
-
-	else if (r < 0) {
-		/* error the io and bail out */
+	} else if (r < 0 || r == DM_MAPIO_REQUEUE) {
+		/* error the io and bail out, or requeue it if needed */
 		md = tio->io->md;
 		dec_pending(tio->io, r);
 		/*
@@ -563,6 +598,9 @@ static void __map_bio(struct dm_target *ti, struct bio *clone,
 		clone->bi_private = md->bs;
 		bio_put(clone);
 		free_tio(md, tio);
+	} else if (r) {
+		DMWARN("unimplemented target map return value: %d", r);
+		BUG();
 	}
 }
 
@@ -948,6 +986,7 @@ static struct mapped_device *alloc_dev(int minor)
 	memset(md, 0, sizeof(*md));
 	init_rwsem(&md->io_lock);
 	init_MUTEX(&md->suspend_lock);
+	spin_lock_init(&md->pushback_lock);
 	rwlock_init(&md->map_lock);
 	atomic_set(&md->holders, 1);
 	atomic_set(&md->open_count, 0);
@@ -966,8 +1005,8 @@ static struct mapped_device *alloc_dev(int minor)
 	md->queue->issue_flush_fn = dm_flush_all;
 
 	md->io_pool = mempool_create_slab_pool(MIN_IOS, _io_cache);
- 	if (!md->io_pool)
- 		goto bad2;
+	if (!md->io_pool)
+		goto bad2;
 
 	md->tio_pool = mempool_create_slab_pool(MIN_IOS, _tio_cache);
 	if (!md->tio_pool)
@@ -1275,12 +1314,15 @@ static void unlock_fs(struct mapped_device *md)
  * dm_bind_table, dm_suspend must be called to flush any in
  * flight bios and ensure that any further io gets deferred.
  */
-int dm_suspend(struct mapped_device *md, int do_lockfs)
+int dm_suspend(struct mapped_device *md, unsigned suspend_flags)
 {
 	struct dm_table *map = NULL;
+	unsigned long flags;
 	DECLARE_WAITQUEUE(wait, current);
 	struct bio *def;
 	int r = -EINVAL;
+	int do_lockfs = suspend_flags & DM_SUSPEND_LOCKFS_FLAG ? 1 : 0;
+	int noflush = suspend_flags & DM_SUSPEND_NOFLUSH_FLAG ? 1 : 0;
 
 	down(&md->suspend_lock);
 
@@ -1289,6 +1331,13 @@ int dm_suspend(struct mapped_device *md, int do_lockfs)
 
 	map = dm_get_table(md);
 
+	/*
+	 * DMF_NOFLUSH_SUSPENDING must be set before presuspend.
+	 * This flag is cleared before dm_suspend returns.
+	 */
+	if (noflush)
+		set_bit(DMF_NOFLUSH_SUSPENDING, &md->flags);
+
 	/* This does not get reverted if there's an error later. */
 	dm_table_presuspend_targets(map);
 
@@ -1296,11 +1345,14 @@ int dm_suspend(struct mapped_device *md, int do_lockfs)
 	if (!md->suspended_bdev) {
 		DMWARN("bdget failed in dm_suspend");
 		r = -ENOMEM;
-		goto out;
+		goto flush_and_out;
 	}
 
-	/* Flush I/O to the device. */
-	if (do_lockfs) {
+	/*
+	 * Flush I/O to the device.
+	 * noflush supersedes do_lockfs, because lock_fs() needs to flush I/Os.
+	 */
+	if (do_lockfs && !noflush) {
 		r = lock_fs(md);
 		if (r)
 			goto out;
@@ -1336,6 +1388,14 @@ int dm_suspend(struct mapped_device *md, int do_lockfs)
 	down_write(&md->io_lock);
 	remove_wait_queue(&md->wait, &wait);
 
+	if (noflush) {
+		spin_lock_irqsave(&md->pushback_lock, flags);
+		clear_bit(DMF_NOFLUSH_SUSPENDING, &md->flags);
+		bio_list_merge_head(&md->deferred, &md->pushback);
+		bio_list_init(&md->pushback);
+		spin_unlock_irqrestore(&md->pushback_lock, flags);
+	}
+
 	/* were we interrupted ? */
 	r = -EINTR;
 	if (atomic_read(&md->pending)) {
@@ -1344,7 +1404,7 @@ int dm_suspend(struct mapped_device *md, int do_lockfs)
 		__flush_deferred_io(md, def);
 		up_write(&md->io_lock);
 		unlock_fs(md);
-		goto out;
+		goto out; /* pushback list is already flushed, so skip flush */
 	}
 	up_write(&md->io_lock);
 
@@ -1354,6 +1414,25 @@ int dm_suspend(struct mapped_device *md, int do_lockfs)
 
 	r = 0;
 
+flush_and_out:
+	if (r && noflush) {
+		/*
+		 * Because there may be already I/Os in the pushback list,
+		 * flush them before return.
+		 */
+		down_write(&md->io_lock);
+
+		spin_lock_irqsave(&md->pushback_lock, flags);
+		clear_bit(DMF_NOFLUSH_SUSPENDING, &md->flags);
+		bio_list_merge_head(&md->deferred, &md->pushback);
+		bio_list_init(&md->pushback);
+		spin_unlock_irqrestore(&md->pushback_lock, flags);
+
+		def = bio_list_get(&md->deferred);
+		__flush_deferred_io(md, def);
+		up_write(&md->io_lock);
+	}
+
 out:
 	if (r && md->suspended_bdev) {
 		bdput(md->suspended_bdev);
@@ -1440,6 +1519,17 @@ int dm_suspended(struct mapped_device *md)
 	return test_bit(DMF_SUSPENDED, &md->flags);
 }
 
+int dm_noflush_suspending(struct dm_target *ti)
+{
+	struct mapped_device *md = dm_table_get_md(ti->table);
+	int r = __noflush_suspending(md);
+
+	dm_put(md);
+
+	return r;
+}
+EXPORT_SYMBOL_GPL(dm_noflush_suspending);
+
 static struct block_device_operations dm_blk_dops = {
 	.open = dm_blk_open,
 	.release = dm_blk_close,
diff --git a/drivers/md/dm.h b/drivers/md/dm.h
index a48ec5e3c1f4..2f796b1436b2 100644
--- a/drivers/md/dm.h
+++ b/drivers/md/dm.h
@@ -33,6 +33,25 @@
 #define SECTOR_SHIFT 9
 
 /*
+ * Definitions of return values from target end_io function.
+ */
+#define DM_ENDIO_INCOMPLETE	1
+#define DM_ENDIO_REQUEUE	2
+
+/*
+ * Definitions of return values from target map function.
+ */
+#define DM_MAPIO_SUBMITTED	0
+#define DM_MAPIO_REMAPPED	1
+#define DM_MAPIO_REQUEUE	DM_ENDIO_REQUEUE
+
+/*
+ * Suspend feature flags
+ */
+#define DM_SUSPEND_LOCKFS_FLAG		(1 << 0)
+#define DM_SUSPEND_NOFLUSH_FLAG		(1 << 1)
+
+/*
  * List of devices that a metadevice uses and should open/close.
  */
 struct dm_dev {
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 6c4345bde07e..53bd46dba0cb 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -1413,7 +1413,7 @@ static int lock_rdev(mdk_rdev_t *rdev, dev_t dev)
 	struct block_device *bdev;
 	char b[BDEVNAME_SIZE];
 
-	bdev = open_partition_by_devnum(dev, FMODE_READ|FMODE_WRITE);
+	bdev = open_by_devnum(dev, FMODE_READ|FMODE_WRITE);
 	if (IS_ERR(bdev)) {
 		printk(KERN_ERR "md: could not open %s.\n",
 			__bdevname(dev, b));
@@ -1423,7 +1423,7 @@ static int lock_rdev(mdk_rdev_t *rdev, dev_t dev)
 	if (err) {
 		printk(KERN_ERR "md: could not bd_claim %s.\n",
 			bdevname(bdev, b));
-		blkdev_put_partition(bdev);
+		blkdev_put(bdev);
 		return err;
 	}
 	rdev->bdev = bdev;
@@ -1437,7 +1437,7 @@ static void unlock_rdev(mdk_rdev_t *rdev)
 	if (!bdev)
 		MD_BUG();
 	bd_release(bdev);
-	blkdev_put_partition(bdev);
+	blkdev_put(bdev);
 }
 
 void md_autodetect_dev(dev_t dev);
@@ -4423,7 +4423,7 @@ static int md_open(struct inode *inode, struct file *file)
 	mddev_t *mddev = inode->i_bdev->bd_disk->private_data;
 	int err;
 
-	if ((err = mddev_lock(mddev)))
+	if ((err = mutex_lock_interruptible_nested(&mddev->reconfig_mutex, 1)))
 		goto out;
 
 	err = 0;
@@ -4846,8 +4846,8 @@ static int md_seq_show(struct seq_file *seq, void *v)
 				chunk_kb ? "KB" : "B");
 			if (bitmap->file) {
 				seq_printf(seq, ", file: ");
-				seq_path(seq, bitmap->file->f_vfsmnt,
-					 bitmap->file->f_dentry," \t\n");
+				seq_path(seq, bitmap->file->f_path.mnt,
+					 bitmap->file->f_path.dentry," \t\n");
 			}
 
 			seq_printf(seq, "\n");
diff --git a/drivers/media/video/compat_ioctl32.c b/drivers/media/video/compat_ioctl32.c
index d82a488f12a6..f065ad12cc61 100644
--- a/drivers/media/video/compat_ioctl32.c
+++ b/drivers/media/video/compat_ioctl32.c
@@ -118,7 +118,7 @@ static int native_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 		ret = file->f_op->unlocked_ioctl(file, cmd, arg);
 	else if (file->f_op->ioctl) {
 		lock_kernel();
-		ret = file->f_op->ioctl(file->f_dentry->d_inode, file, cmd, arg);
+		ret = file->f_op->ioctl(file->f_path.dentry->d_inode, file, cmd, arg);
 		unlock_kernel();
 	}
 
diff --git a/drivers/media/video/videodev.c b/drivers/media/video/videodev.c
index d424a4129d69..41ec0c4b35a2 100644
--- a/drivers/media/video/videodev.c
+++ b/drivers/media/video/videodev.c
@@ -105,7 +105,7 @@ static DEFINE_MUTEX(videodev_lock);
 
 struct video_device* video_devdata(struct file *file)
 {
-	return video_device[iminor(file->f_dentry->d_inode)];
+	return video_device[iminor(file->f_path.dentry->d_inode)];
 }
 
 /*
diff --git a/drivers/media/video/zoran_procfs.c b/drivers/media/video/zoran_procfs.c
index c7f6f6488360..c374c76b3753 100644
--- a/drivers/media/video/zoran_procfs.c
+++ b/drivers/media/video/zoran_procfs.c
@@ -144,7 +144,7 @@ static int zoran_open(struct inode *inode, struct file *file)
 static ssize_t zoran_write(struct file *file, const char __user *buffer,
 			size_t count, loff_t *ppos)
 {
-	struct zoran *zr = PDE(file->f_dentry->d_inode)->data;
+	struct zoran *zr = PDE(file->f_path.dentry->d_inode)->data;
 	char *string, *sp;
 	char *line, *ldelim, *varname, *svar, *tdelim;
 
@@ -165,7 +165,7 @@ static ssize_t zoran_write(struct file *file, const char __user *buffer,
 	}
 	string[count] = 0;
 	dprintk(4, KERN_INFO "%s: write_proc: name=%s count=%zu zr=%p\n",
-		ZR_DEVNAME(zr), file->f_dentry->d_name.name, count, zr);
+		ZR_DEVNAME(zr), file->f_path.dentry->d_name.name, count, zr);
 	ldelim = " \t\n";
 	tdelim = "=";
 	line = strpbrk(sp, ldelim);
diff --git a/drivers/mmc/au1xmmc.c b/drivers/mmc/au1xmmc.c
index 447fba5825fd..800527cf40d5 100644
--- a/drivers/mmc/au1xmmc.c
+++ b/drivers/mmc/au1xmmc.c
@@ -875,7 +875,7 @@ static void au1xmmc_init_dma(struct au1xmmc_host *host)
 	host->rx_chan = rxchan;
 }
 
-struct const mmc_host_ops au1xmmc_ops = {
+static const struct mmc_host_ops au1xmmc_ops = {
 	.request	= au1xmmc_request,
 	.set_ios	= au1xmmc_set_ios,
 };
diff --git a/drivers/mmc/pxamci.c b/drivers/mmc/pxamci.c
index 471e9f4e0530..45a9283ce498 100644
--- a/drivers/mmc/pxamci.c
+++ b/drivers/mmc/pxamci.c
@@ -355,7 +355,7 @@ static int pxamci_get_ro(struct mmc_host *mmc)
 	struct pxamci_host *host = mmc_priv(mmc);
 
 	if (host->pdata && host->pdata->get_ro)
-		return host->pdata->get_ro(mmc->dev);
+		return host->pdata->get_ro(mmc_dev(mmc));
 	/* Host doesn't support read only detection so assume writeable */
 	return 0;
 }
@@ -383,7 +383,7 @@ static void pxamci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 		host->power_mode = ios->power_mode;
 
 		if (host->pdata && host->pdata->setpower)
-			host->pdata->setpower(mmc->dev, ios->vdd);
+			host->pdata->setpower(mmc_dev(mmc), ios->vdd);
 
 		if (ios->power_mode == MMC_POWER_ON)
 			host->cmdat |= CMDAT_INIT;
diff --git a/drivers/mmc/tifm_sd.c b/drivers/mmc/tifm_sd.c
index e846499a004c..f18ad998b3cb 100644
--- a/drivers/mmc/tifm_sd.c
+++ b/drivers/mmc/tifm_sd.c
@@ -387,7 +387,7 @@ static void tifm_sd_prepare_data(struct tifm_sd *card, struct mmc_command *cmd)
 
 	writel(TIFM_FIFO_INT_SETALL,
 		sock->addr + SOCK_DMA_FIFO_INT_ENABLE_CLEAR);
-	writel(long_log2(cmd->data->blksz) - 2,
+	writel(ilog2(cmd->data->blksz) - 2,
 			sock->addr + SOCK_FIFO_PAGE_SIZE);
 	writel(TIFM_FIFO_ENABLE, sock->addr + SOCK_FIFO_CONTROL);
 	writel(TIFM_FIFO_INTMASK, sock->addr + SOCK_DMA_FIFO_INT_ENABLE_SET);
diff --git a/drivers/net/irda/irtty-sir.c b/drivers/net/irda/irtty-sir.c
index 6a98b7ae4975..ad1857364d51 100644
--- a/drivers/net/irda/irtty-sir.c
+++ b/drivers/net/irda/irtty-sir.c
@@ -117,7 +117,7 @@ static int irtty_change_speed(struct sir_dev *dev, unsigned speed)
 {
 	struct sirtty_cb *priv = dev->priv;
 	struct tty_struct *tty;
-        struct termios old_termios;
+        struct ktermios old_termios;
 	int cflag;
 
 	IRDA_ASSERT(priv != NULL, return -1;);
@@ -318,7 +318,7 @@ static void irtty_write_wakeup(struct tty_struct *tty)
 
 static inline void irtty_stop_receiver(struct tty_struct *tty, int stop)
 {
-	struct termios old_termios;
+	struct ktermios old_termios;
 	int cflag;
 
 	lock_kernel();
diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c
index 74f894795a1b..4587f23f4e4b 100644
--- a/drivers/net/via-velocity.c
+++ b/drivers/net/via-velocity.c
@@ -3132,7 +3132,7 @@ static u16 wol_calc_crc(int size, u8 * pattern, u8 *mask_pattern)
 	}
 	/*	Finally, invert the result once to get the correct data */
 	crc = ~crc;
-	return bitreverse(crc) >> 16;
+	return bitrev32(crc) >> 16;
 }
 
 /**
diff --git a/drivers/net/wan/cosa.c b/drivers/net/wan/cosa.c
index e1bf8b93f958..6c7dfb50143f 100644
--- a/drivers/net/wan/cosa.c
+++ b/drivers/net/wan/cosa.c
@@ -974,12 +974,12 @@ static int cosa_open(struct inode *inode, struct file *file)
 	unsigned long flags;
 	int n;
 
-	if ((n=iminor(file->f_dentry->d_inode)>>CARD_MINOR_BITS)
+	if ((n=iminor(file->f_path.dentry->d_inode)>>CARD_MINOR_BITS)
 		>= nr_cards)
 		return -ENODEV;
 	cosa = cosa_cards+n;
 
-	if ((n=iminor(file->f_dentry->d_inode)
+	if ((n=iminor(file->f_path.dentry->d_inode)
 		& ((1<<CARD_MINOR_BITS)-1)) >= cosa->nchannels)
 		return -ENODEV;
 	chan = cosa->chan + n;
diff --git a/drivers/net/wireless/strip.c b/drivers/net/wireless/strip.c
index 337c692f6fd6..ce3a8bac66ff 100644
--- a/drivers/net/wireless/strip.c
+++ b/drivers/net/wireless/strip.c
@@ -798,7 +798,7 @@ static unsigned int get_baud(struct tty_struct *tty)
  */
 static void set_baud(struct tty_struct *tty, unsigned int baudcode)
 {
-	struct termios old_termios = *(tty->termios);
+	struct ktermios old_termios = *(tty->termios);
 	tty->termios->c_cflag &= ~CBAUD;	/* Clear the old baud setting */
 	tty->termios->c_cflag |= baudcode;	/* Set the new baud setting */
 	tty->driver->set_termios(tty, &old_termios);
diff --git a/drivers/oprofile/buffer_sync.c b/drivers/oprofile/buffer_sync.c
index 43e521e99126..78c2e6e4b42e 100644
--- a/drivers/oprofile/buffer_sync.c
+++ b/drivers/oprofile/buffer_sync.c
@@ -220,8 +220,8 @@ static unsigned long get_exec_dcookie(struct mm_struct * mm)
 			continue;
 		if (!(vma->vm_flags & VM_EXECUTABLE))
 			continue;
-		cookie = fast_get_dcookie(vma->vm_file->f_dentry,
-			vma->vm_file->f_vfsmnt);
+		cookie = fast_get_dcookie(vma->vm_file->f_path.dentry,
+			vma->vm_file->f_path.mnt);
 		break;
 	}
 
@@ -246,8 +246,8 @@ static unsigned long lookup_dcookie(struct mm_struct * mm, unsigned long addr, o
 			continue;
 
 		if (vma->vm_file) {
-			cookie = fast_get_dcookie(vma->vm_file->f_dentry,
-				vma->vm_file->f_vfsmnt);
+			cookie = fast_get_dcookie(vma->vm_file->f_path.dentry,
+				vma->vm_file->f_path.mnt);
 			*offset = (vma->vm_pgoff << PAGE_SHIFT) + addr -
 				vma->vm_start;
 		} else {
diff --git a/drivers/pci/proc.c b/drivers/pci/proc.c
index 99cf33379769..4a6760a3b31f 100644
--- a/drivers/pci/proc.c
+++ b/drivers/pci/proc.c
@@ -23,7 +23,7 @@ static loff_t
 proc_bus_pci_lseek(struct file *file, loff_t off, int whence)
 {
 	loff_t new = -1;
-	struct inode *inode = file->f_dentry->d_inode;
+	struct inode *inode = file->f_path.dentry->d_inode;
 
 	mutex_lock(&inode->i_mutex);
 	switch (whence) {
@@ -48,7 +48,7 @@ proc_bus_pci_lseek(struct file *file, loff_t off, int whence)
 static ssize_t
 proc_bus_pci_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos)
 {
-	const struct inode *ino = file->f_dentry->d_inode;
+	const struct inode *ino = file->f_path.dentry->d_inode;
 	const struct proc_dir_entry *dp = PDE(ino);
 	struct pci_dev *dev = dp->data;
 	unsigned int pos = *ppos;
@@ -130,7 +130,7 @@ proc_bus_pci_read(struct file *file, char __user *buf, size_t nbytes, loff_t *pp
 static ssize_t
 proc_bus_pci_write(struct file *file, const char __user *buf, size_t nbytes, loff_t *ppos)
 {
-	const struct inode *ino = file->f_dentry->d_inode;
+	const struct inode *ino = file->f_path.dentry->d_inode;
 	const struct proc_dir_entry *dp = PDE(ino);
 	struct pci_dev *dev = dp->data;
 	int pos = *ppos;
@@ -245,7 +245,7 @@ static int proc_bus_pci_ioctl(struct inode *inode, struct file *file, unsigned i
 #ifdef HAVE_PCI_MMAP
 static int proc_bus_pci_mmap(struct file *file, struct vm_area_struct *vma)
 {
-	struct inode *inode = file->f_dentry->d_inode;
+	struct inode *inode = file->f_path.dentry->d_inode;
 	const struct proc_dir_entry *dp = PDE(inode);
 	struct pci_dev *dev = dp->data;
 	struct pci_filp_private *fpriv = file->private_data;
diff --git a/drivers/pcmcia/pcmcia_ioctl.c b/drivers/pcmcia/pcmcia_ioctl.c
index d077870c6731..327372b7a54e 100644
--- a/drivers/pcmcia/pcmcia_ioctl.c
+++ b/drivers/pcmcia/pcmcia_ioctl.c
@@ -486,7 +486,7 @@ static ssize_t ds_read(struct file *file, char __user *buf,
     user_info_t *user;
     int ret;
 
-    ds_dbg(2, "ds_read(socket %d)\n", iminor(file->f_dentry->d_inode));
+    ds_dbg(2, "ds_read(socket %d)\n", iminor(file->f_path.dentry->d_inode));
 
     if (count < 4)
 	return -EINVAL;
@@ -511,7 +511,7 @@ static ssize_t ds_read(struct file *file, char __user *buf,
 static ssize_t ds_write(struct file *file, const char __user *buf,
 			size_t count, loff_t *ppos)
 {
-    ds_dbg(2, "ds_write(socket %d)\n", iminor(file->f_dentry->d_inode));
+    ds_dbg(2, "ds_write(socket %d)\n", iminor(file->f_path.dentry->d_inode));
 
     if (count != 4)
 	return -EINVAL;
@@ -529,7 +529,7 @@ static u_int ds_poll(struct file *file, poll_table *wait)
     struct pcmcia_socket *s;
     user_info_t *user;
 
-    ds_dbg(2, "ds_poll(socket %d)\n", iminor(file->f_dentry->d_inode));
+    ds_dbg(2, "ds_poll(socket %d)\n", iminor(file->f_path.dentry->d_inode));
 
     user = file->private_data;
     if (CHECK_USER(user))
diff --git a/drivers/pnp/isapnp/proc.c b/drivers/pnp/isapnp/proc.c
index 958c11bedd0d..d21f3c1e72fc 100644
--- a/drivers/pnp/isapnp/proc.c
+++ b/drivers/pnp/isapnp/proc.c
@@ -56,7 +56,7 @@ static loff_t isapnp_proc_bus_lseek(struct file *file, loff_t off, int whence)
 
 static ssize_t isapnp_proc_bus_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos)
 {
-	struct inode *ino = file->f_dentry->d_inode;
+	struct inode *ino = file->f_path.dentry->d_inode;
 	struct proc_dir_entry *dp = PDE(ino);
 	struct pnp_dev *dev = dp->data;
 	int pos = *ppos;
diff --git a/drivers/s390/block/dasd_ioctl.c b/drivers/s390/block/dasd_ioctl.c
index 8fed3603e9ea..758cfb542865 100644
--- a/drivers/s390/block/dasd_ioctl.c
+++ b/drivers/s390/block/dasd_ioctl.c
@@ -430,7 +430,7 @@ dasd_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
 	int rval;
 
 	lock_kernel();
-	rval = dasd_ioctl(filp->f_dentry->d_inode, filp, cmd, arg);
+	rval = dasd_ioctl(filp->f_path.dentry->d_inode, filp, cmd, arg);
 	unlock_kernel();
 
 	return (rval == -EINVAL) ? -ENOIOCTLCMD : rval;
diff --git a/drivers/s390/char/fs3270.c b/drivers/s390/char/fs3270.c
index 78f8bda81dae..0893d306ae80 100644
--- a/drivers/s390/char/fs3270.c
+++ b/drivers/s390/char/fs3270.c
@@ -419,16 +419,20 @@ fs3270_open(struct inode *inode, struct file *filp)
 	struct idal_buffer *ib;
 	int minor, rc;
 
-	if (imajor(filp->f_dentry->d_inode) != IBM_FS3270_MAJOR)
+	if (imajor(filp->f_path.dentry->d_inode) != IBM_FS3270_MAJOR)
 		return -ENODEV;
-	minor = iminor(filp->f_dentry->d_inode);
+	minor = iminor(filp->f_path.dentry->d_inode);
 	/* Check for minor 0 multiplexer. */
 	if (minor == 0) {
-		if (!current->signal->tty)
+		struct tty_struct *tty;
+		mutex_lock(&tty_mutex);
+		tty = get_current_tty();
+		if (!tty || tty->driver->major != IBM_TTY3270_MAJOR) {
+			mutex_unlock(&tty_mutex);
 			return -ENODEV;
-		if (current->signal->tty->driver->major != IBM_TTY3270_MAJOR)
-			return -ENODEV;
-		minor = current->signal->tty->index + RAW3270_FIRSTMINOR;
+		}
+		minor = tty->index + RAW3270_FIRSTMINOR;
+		mutex_unlock(&tty_mutex);
 	}
 	/* Check if some other program is already using fullscreen mode. */
 	fp = (struct fs3270 *) raw3270_find_view(&fs3270_fn, minor);
diff --git a/drivers/s390/char/sclp_tty.c b/drivers/s390/char/sclp_tty.c
index 6f43e04dbefd..2d173e5c8a09 100644
--- a/drivers/s390/char/sclp_tty.c
+++ b/drivers/s390/char/sclp_tty.c
@@ -60,8 +60,6 @@ static unsigned short int sclp_tty_chars_count;
 
 struct tty_driver *sclp_tty_driver;
 
-extern struct termios  tty_std_termios;
-
 static struct sclp_ioctls sclp_ioctls;
 static struct sclp_ioctls sclp_ioctls_init =
 {
diff --git a/drivers/s390/char/tape_char.c b/drivers/s390/char/tape_char.c
index 97f75237bed6..31198c8f2718 100644
--- a/drivers/s390/char/tape_char.c
+++ b/drivers/s390/char/tape_char.c
@@ -298,13 +298,13 @@ tapechar_open (struct inode *inode, struct file *filp)
 	int minor, rc;
 
 	DBF_EVENT(6, "TCHAR:open: %i:%i\n",
-		imajor(filp->f_dentry->d_inode),
-		iminor(filp->f_dentry->d_inode));
+		imajor(filp->f_path.dentry->d_inode),
+		iminor(filp->f_path.dentry->d_inode));
 
-	if (imajor(filp->f_dentry->d_inode) != tapechar_major)
+	if (imajor(filp->f_path.dentry->d_inode) != tapechar_major)
 		return -ENODEV;
 
-	minor = iminor(filp->f_dentry->d_inode);
+	minor = iminor(filp->f_path.dentry->d_inode);
 	device = tape_get_device(minor / TAPE_MINORS_PER_DEV);
 	if (IS_ERR(device)) {
 		DBF_EVENT(3, "TCHAR:open: tape_get_device() failed\n");
diff --git a/drivers/s390/char/tty3270.c b/drivers/s390/char/tty3270.c
index 4717c3611601..09844621edc0 100644
--- a/drivers/s390/char/tty3270.c
+++ b/drivers/s390/char/tty3270.c
@@ -1659,7 +1659,7 @@ tty3270_flush_buffer(struct tty_struct *tty)
  * Check for visible/invisible input switches
  */
 static void
-tty3270_set_termios(struct tty_struct *tty, struct termios *old)
+tty3270_set_termios(struct tty_struct *tty, struct ktermios *old)
 {
 	struct tty3270 *tp;
 	int new;
diff --git a/drivers/sbus/char/bpp.c b/drivers/sbus/char/bpp.c
index 385f4f768311..ac7d1258efee 100644
--- a/drivers/sbus/char/bpp.c
+++ b/drivers/sbus/char/bpp.c
@@ -621,7 +621,7 @@ static long read_ecp(unsigned minor, char __user *c, unsigned long cnt)
 static ssize_t bpp_read(struct file *f, char __user *c, size_t cnt, loff_t * ppos)
 {
       long rc;
-      unsigned minor = iminor(f->f_dentry->d_inode);
+      unsigned minor = iminor(f->f_path.dentry->d_inode);
       if (minor >= BPP_NO) return -ENODEV;
       if (!instances[minor].present) return -ENODEV;
 
@@ -774,7 +774,7 @@ static long write_ecp(unsigned minor, const char __user *c, unsigned long cnt)
 static ssize_t bpp_write(struct file *f, const char __user *c, size_t cnt, loff_t * ppos)
 {
       long errno = 0;
-      unsigned minor = iminor(f->f_dentry->d_inode);
+      unsigned minor = iminor(f->f_path.dentry->d_inode);
       if (minor >= BPP_NO) return -ENODEV;
       if (!instances[minor].present) return -ENODEV;
 
diff --git a/drivers/sbus/char/cpwatchdog.c b/drivers/sbus/char/cpwatchdog.c
index f5803ecb1999..ad1c7db96cb4 100644
--- a/drivers/sbus/char/cpwatchdog.c
+++ b/drivers/sbus/char/cpwatchdog.c
@@ -404,7 +404,7 @@ static long wd_compat_ioctl(struct file *file, unsigned int cmd,
 	case WIOCSTOP:
 	case WIOCGSTAT:
 		lock_kernel();
-		rval = wd_ioctl(file->f_dentry->d_inode, file, cmd, arg);
+		rval = wd_ioctl(file->f_path.dentry->d_inode, file, cmd, arg);
 		unlock_kernel();
 		break;
 	/* everything else is handled by the generic compat layer */
diff --git a/drivers/sbus/char/display7seg.c b/drivers/sbus/char/display7seg.c
index d92bc8827a9e..a4909e0c7f83 100644
--- a/drivers/sbus/char/display7seg.c
+++ b/drivers/sbus/char/display7seg.c
@@ -121,7 +121,7 @@ static long d7s_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 	__u8 ireg = 0;
 	int error = 0;
 
-	if (D7S_MINOR != iminor(file->f_dentry->d_inode))
+	if (D7S_MINOR != iminor(file->f_path.dentry->d_inode))
 		return -ENODEV;
 
 	lock_kernel();
diff --git a/drivers/sbus/char/openprom.c b/drivers/sbus/char/openprom.c
index 81ba2d71cee2..4e2a0e2dcc2e 100644
--- a/drivers/sbus/char/openprom.c
+++ b/drivers/sbus/char/openprom.c
@@ -676,7 +676,7 @@ static long openprom_compat_ioctl(struct file *file, unsigned int cmd,
 	case OPROMSETCUR:
 	case OPROMPCI2NODE:
 	case OPROMPATH2NODE:
-		rval = openprom_ioctl(file->f_dentry->d_inode, file, cmd, arg);
+		rval = openprom_ioctl(file->f_path.dentry->d_inode, file, cmd, arg);
 		break;
 	}
 
diff --git a/drivers/sbus/char/vfc_dev.c b/drivers/sbus/char/vfc_dev.c
index 55b2b31bd7ab..2722af5d3404 100644
--- a/drivers/sbus/char/vfc_dev.c
+++ b/drivers/sbus/char/vfc_dev.c
@@ -610,7 +610,7 @@ static int vfc_mmap(struct file *file, struct vm_area_struct *vma)
 	unsigned int map_size, ret, map_offset;
 	struct vfc_dev *dev;
 	
-	dev = vfc_get_dev_ptr(iminor(file->f_dentry->d_inode));
+	dev = vfc_get_dev_ptr(iminor(file->f_path.dentry->d_inode));
 	if(dev == NULL)
 		return -ENODEV;
 
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index f6a452846fab..978bfc1e0c6a 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -863,7 +863,7 @@ static void sd_rescan(struct device *dev)
  */
 static long sd_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 {
-	struct block_device *bdev = file->f_dentry->d_inode->i_bdev;
+	struct block_device *bdev = file->f_path.dentry->d_inode->i_bdev;
 	struct gendisk *disk = bdev->bd_disk;
 	struct scsi_device *sdev = scsi_disk(disk)->device;
 
diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c
index 587274dd7059..e016e0906e1a 100644
--- a/drivers/scsi/st.c
+++ b/drivers/scsi/st.c
@@ -922,7 +922,7 @@ static int check_tape(struct scsi_tape *STp, struct file *filp)
 	struct st_modedef *STm;
 	struct st_partstat *STps;
 	char *name = tape_name(STp);
-	struct inode *inode = filp->f_dentry->d_inode;
+	struct inode *inode = filp->f_path.dentry->d_inode;
 	int mode = TAPE_MODE(inode);
 
 	STp->ready = ST_READY;
diff --git a/drivers/serial/21285.c b/drivers/serial/21285.c
index 6a1a568ca649..facb67855619 100644
--- a/drivers/serial/21285.c
+++ b/drivers/serial/21285.c
@@ -214,8 +214,8 @@ static void serial21285_shutdown(struct uart_port *port)
 }
 
 static void
-serial21285_set_termios(struct uart_port *port, struct termios *termios,
-			struct termios *old)
+serial21285_set_termios(struct uart_port *port, struct ktermios *termios,
+			struct ktermios *old)
 {
 	unsigned long flags;
 	unsigned int baud, quot, h_lcr;
diff --git a/drivers/serial/68328serial.c b/drivers/serial/68328serial.c
index 9b8b585513ec..cad426c9711e 100644
--- a/drivers/serial/68328serial.c
+++ b/drivers/serial/68328serial.c
@@ -1061,7 +1061,7 @@ static int rs_ioctl(struct tty_struct *tty, struct file * file,
 	return 0;
 }
 
-static void rs_set_termios(struct tty_struct *tty, struct termios *old_termios)
+static void rs_set_termios(struct tty_struct *tty, struct ktermios *old_termios)
 {
 	struct m68k_serial *info = (struct m68k_serial *)tty->driver_data;
 
diff --git a/drivers/serial/68360serial.c b/drivers/serial/68360serial.c
index 634ecca36a77..68817a7d8c0d 100644
--- a/drivers/serial/68360serial.c
+++ b/drivers/serial/68360serial.c
@@ -1523,7 +1523,7 @@ static int rs_360_ioctl(struct tty_struct *tty, struct file * file,
 
 /* FIX UP modem control here someday......
 */
-static void rs_360_set_termios(struct tty_struct *tty, struct termios *old_termios)
+static void rs_360_set_termios(struct tty_struct *tty, struct ktermios *old_termios)
 {
 	ser_info_t *info = (ser_info_t *)tty->driver_data;
 
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
index e34bd03cfce7..51f3c739f7e1 100644
--- a/drivers/serial/8250.c
+++ b/drivers/serial/8250.c
@@ -1763,8 +1763,8 @@ static unsigned int serial8250_get_divisor(struct uart_port *port, unsigned int
 }
 
 static void
-serial8250_set_termios(struct uart_port *port, struct termios *termios,
-		       struct termios *old)
+serial8250_set_termios(struct uart_port *port, struct ktermios *termios,
+		       struct ktermios *old)
 {
 	struct uart_8250_port *up = (struct uart_8250_port *)port;
 	unsigned char cval, fcr = 0;
diff --git a/drivers/serial/amba-pl010.c b/drivers/serial/amba-pl010.c
index 4d3626ef4643..61db6973755a 100644
--- a/drivers/serial/amba-pl010.c
+++ b/drivers/serial/amba-pl010.c
@@ -345,8 +345,8 @@ static void pl010_shutdown(struct uart_port *port)
 }
 
 static void
-pl010_set_termios(struct uart_port *port, struct termios *termios,
-		     struct termios *old)
+pl010_set_termios(struct uart_port *port, struct ktermios *termios,
+		     struct ktermios *old)
 {
 	unsigned int lcr_h, old_cr;
 	unsigned long flags;
diff --git a/drivers/serial/amba-pl011.c b/drivers/serial/amba-pl011.c
index d503625730df..9a3b374b2a08 100644
--- a/drivers/serial/amba-pl011.c
+++ b/drivers/serial/amba-pl011.c
@@ -412,8 +412,8 @@ static void pl011_shutdown(struct uart_port *port)
 }
 
 static void
-pl011_set_termios(struct uart_port *port, struct termios *termios,
-		     struct termios *old)
+pl011_set_termios(struct uart_port *port, struct ktermios *termios,
+		     struct ktermios *old)
 {
 	unsigned int lcr_h, old_cr;
 	unsigned long flags;
diff --git a/drivers/serial/atmel_serial.c b/drivers/serial/atmel_serial.c
index 9217ee6c7865..ed7f7209ea59 100644
--- a/drivers/serial/atmel_serial.c
+++ b/drivers/serial/atmel_serial.c
@@ -478,7 +478,7 @@ static void atmel_serial_pm(struct uart_port *port, unsigned int state, unsigned
 /*
  * Change the port parameters
  */
-static void atmel_set_termios(struct uart_port *port, struct termios * termios, struct termios * old)
+static void atmel_set_termios(struct uart_port *port, struct ktermios * termios, struct ktermios * old)
 {
 	unsigned long flags;
 	unsigned int mode, imr, quot, baud;
diff --git a/drivers/serial/clps711x.c b/drivers/serial/clps711x.c
index 598012714882..23827189ec0e 100644
--- a/drivers/serial/clps711x.c
+++ b/drivers/serial/clps711x.c
@@ -286,8 +286,8 @@ static void clps711xuart_shutdown(struct uart_port *port)
 }
 
 static void
-clps711xuart_set_termios(struct uart_port *port, struct termios *termios,
-			 struct termios *old)
+clps711xuart_set_termios(struct uart_port *port, struct ktermios *termios,
+			 struct ktermios *old)
 {
 	unsigned int ubrlcr, baud, quot;
 	unsigned long flags;
diff --git a/drivers/serial/crisv10.c b/drivers/serial/crisv10.c
index 7a24e53546c7..42b050c46abe 100644
--- a/drivers/serial/crisv10.c
+++ b/drivers/serial/crisv10.c
@@ -804,8 +804,8 @@ static struct e100_serial rs_table[] = {
 
 #define NR_PORTS (sizeof(rs_table)/sizeof(struct e100_serial))
 
-static struct termios *serial_termios[NR_PORTS];
-static struct termios *serial_termios_locked[NR_PORTS];
+static struct ktermios *serial_termios[NR_PORTS];
+static struct ktermios *serial_termios_locked[NR_PORTS];
 #ifdef CONFIG_ETRAX_SERIAL_FAST_TIMER
 static struct fast_timer fast_timers[NR_PORTS];
 #endif
@@ -4223,7 +4223,7 @@ rs_ioctl(struct tty_struct *tty, struct file * file,
 }
 
 static void
-rs_set_termios(struct tty_struct *tty, struct termios *old_termios)
+rs_set_termios(struct tty_struct *tty, struct ktermios *old_termios)
 {
 	struct e100_serial *info = (struct e100_serial *)tty->driver_data;
 
@@ -4877,6 +4877,8 @@ rs_init(void)
 	driver->init_termios = tty_std_termios;
 	driver->init_termios.c_cflag =
 		B115200 | CS8 | CREAD | HUPCL | CLOCAL; /* is normally B9600 default... */
+	driver->init_termios.c_ispeed = 115200;
+	driver->init_termios.c_ospeed = 115200;
 	driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
 	driver->termios = serial_termios;
 	driver->termios_locked = serial_termios_locked;
diff --git a/drivers/serial/crisv10.h b/drivers/serial/crisv10.h
index f30b93d6ef79..4a23340663aa 100644
--- a/drivers/serial/crisv10.h
+++ b/drivers/serial/crisv10.h
@@ -93,8 +93,8 @@ struct e100_serial {
 
 	struct work_struct	work;
 	struct async_icount	icount;   /* error-statistics etc.*/
-	struct termios		normal_termios;
-	struct termios		callout_termios;
+	struct ktermios		normal_termios;
+	struct ktermios		callout_termios;
 #ifdef DECLARE_WAITQUEUE
 	wait_queue_head_t	open_wait;
 	wait_queue_head_t	close_wait;
diff --git a/drivers/serial/dz.c b/drivers/serial/dz.c
index af1544f3356f..587d87b9eb3c 100644
--- a/drivers/serial/dz.c
+++ b/drivers/serial/dz.c
@@ -461,8 +461,8 @@ static void dz_break_ctl(struct uart_port *uport, int break_state)
 	spin_unlock_irqrestore(&uport->lock, flags);
 }
 
-static void dz_set_termios(struct uart_port *uport, struct termios *termios,
-			   struct termios *old_termios)
+static void dz_set_termios(struct uart_port *uport, struct ktermios *termios,
+			   struct ktermios *old_termios)
 {
 	struct dz_port *dport = (struct dz_port *)uport;
 	unsigned long flags;
diff --git a/drivers/serial/icom.c b/drivers/serial/icom.c
index 8aa0f641866b..7d623003e65e 100644
--- a/drivers/serial/icom.c
+++ b/drivers/serial/icom.c
@@ -1087,8 +1087,8 @@ static void icom_close(struct uart_port *port)
 }
 
 static void icom_set_termios(struct uart_port *port,
-			     struct termios *termios,
-			     struct termios *old_termios)
+			     struct ktermios *termios,
+			     struct ktermios *old_termios)
 {
 	int baud;
 	unsigned cflag, iflag;
diff --git a/drivers/serial/imx.c b/drivers/serial/imx.c
index ee5c782597dd..e216dcf29376 100644
--- a/drivers/serial/imx.c
+++ b/drivers/serial/imx.c
@@ -459,8 +459,8 @@ static void imx_shutdown(struct uart_port *port)
 }
 
 static void
-imx_set_termios(struct uart_port *port, struct termios *termios,
-		   struct termios *old)
+imx_set_termios(struct uart_port *port, struct ktermios *termios,
+		   struct ktermios *old)
 {
 	struct imx_port *sport = (struct imx_port *)port;
 	unsigned long flags;
diff --git a/drivers/serial/ioc3_serial.c b/drivers/serial/ioc3_serial.c
index 2308d26c8629..9cc0be932316 100644
--- a/drivers/serial/ioc3_serial.c
+++ b/drivers/serial/ioc3_serial.c
@@ -950,7 +950,7 @@ static void transmit_chars(struct uart_port *the_port)
  */
 static void
 ioc3_change_speed(struct uart_port *the_port,
-		  struct termios *new_termios, struct termios *old_termios)
+		  struct ktermios *new_termios, struct ktermios *old_termios)
 {
 	struct ioc3_port *port = get_ioc3_port(the_port);
 	unsigned int cflag;
@@ -1853,7 +1853,7 @@ static int ic3_startup(struct uart_port *the_port)
  */
 static void
 ic3_set_termios(struct uart_port *the_port,
-		struct termios *termios, struct termios *old_termios)
+		struct ktermios *termios, struct ktermios *old_termios)
 {
 	unsigned long port_flags;
 
diff --git a/drivers/serial/ioc4_serial.c b/drivers/serial/ioc4_serial.c
index 711bd1511439..c862f67c985a 100644
--- a/drivers/serial/ioc4_serial.c
+++ b/drivers/serial/ioc4_serial.c
@@ -1681,7 +1681,7 @@ static void transmit_chars(struct uart_port *the_port)
  */
 static void
 ioc4_change_speed(struct uart_port *the_port,
-		  struct termios *new_termios, struct termios *old_termios)
+		  struct ktermios *new_termios, struct ktermios *old_termios)
 {
 	struct ioc4_port *port = get_ioc4_port(the_port, 0);
 	int baud, bits;
@@ -1802,7 +1802,7 @@ static inline int ic4_startup_local(struct uart_port *the_port)
 	ioc4_set_proto(port, the_port->mapbase);
 
 	/* set the speed of the serial port */
-	ioc4_change_speed(the_port, info->tty->termios, (struct termios *)0);
+	ioc4_change_speed(the_port, info->tty->termios, (struct ktermios *)0);
 
 	return 0;
 }
@@ -2570,7 +2570,7 @@ static int ic4_startup(struct uart_port *the_port)
  */
 static void
 ic4_set_termios(struct uart_port *the_port,
-		struct termios *termios, struct termios *old_termios)
+		struct ktermios *termios, struct ktermios *old_termios)
 {
 	unsigned long port_flags;
 
diff --git a/drivers/serial/ip22zilog.c b/drivers/serial/ip22zilog.c
index dca6c1bde8f9..0746c9446ae0 100644
--- a/drivers/serial/ip22zilog.c
+++ b/drivers/serial/ip22zilog.c
@@ -840,8 +840,8 @@ ip22zilog_convert_to_zs(struct uart_ip22zilog_port *up, unsigned int cflag,
 
 /* The port lock is not held.  */
 static void
-ip22zilog_set_termios(struct uart_port *port, struct termios *termios,
-		      struct termios *old)
+ip22zilog_set_termios(struct uart_port *port, struct ktermios *termios,
+		      struct ktermios *old)
 {
 	struct uart_ip22zilog_port *up = (struct uart_ip22zilog_port *) port;
 	unsigned long flags;
diff --git a/drivers/serial/jsm/jsm_tty.c b/drivers/serial/jsm/jsm_tty.c
index f8262e6ad8d3..7cf1c60027f8 100644
--- a/drivers/serial/jsm/jsm_tty.c
+++ b/drivers/serial/jsm/jsm_tty.c
@@ -142,7 +142,7 @@ static void jsm_tty_send_xchar(struct uart_port *port, char ch)
 {
 	unsigned long lock_flags;
 	struct jsm_channel *channel = (struct jsm_channel *)port;
-	struct termios *termios;
+	struct ktermios *termios;
 
 	spin_lock_irqsave(&port->lock, lock_flags);
 	termios = port->info->tty->termios;
@@ -180,7 +180,7 @@ static int jsm_tty_open(struct uart_port *port)
 	struct jsm_board *brd;
 	int rc = 0;
 	struct jsm_channel *channel = (struct jsm_channel *)port;
-	struct termios *termios;
+	struct ktermios *termios;
 
 	/* Get board pointer from our array of majors we have allocated */
 	brd = channel->ch_bd;
@@ -269,7 +269,7 @@ static int jsm_tty_open(struct uart_port *port)
 static void jsm_tty_close(struct uart_port *port)
 {
 	struct jsm_board *bd;
-	struct termios *ts;
+	struct ktermios *ts;
 	struct jsm_channel *channel = (struct jsm_channel *)port;
 
 	jsm_printk(CLOSE, INFO, &channel->ch_bd->pci_dev, "start\n");
@@ -302,8 +302,8 @@ static void jsm_tty_close(struct uart_port *port)
 }
 
 static void jsm_tty_set_termios(struct uart_port *port,
-				 struct termios *termios,
-				 struct termios *old_termios)
+				 struct ktermios *termios,
+				 struct ktermios *old_termios)
 {
 	unsigned long lock_flags;
 	struct jsm_channel *channel = (struct jsm_channel *)port;
diff --git a/drivers/serial/m32r_sio.c b/drivers/serial/m32r_sio.c
index 7656a35f5e2f..6e09c8b395e8 100644
--- a/drivers/serial/m32r_sio.c
+++ b/drivers/serial/m32r_sio.c
@@ -699,7 +699,7 @@ static unsigned int m32r_sio_get_divisor(struct uart_port *port,
 }
 
 static void m32r_sio_set_termios(struct uart_port *port,
-	struct termios *termios, struct termios *old)
+	struct ktermios *termios, struct ktermios *old)
 {
 	struct uart_sio_port *up = (struct uart_sio_port *)port;
 	unsigned char cval = 0;
diff --git a/drivers/serial/mcfserial.c b/drivers/serial/mcfserial.c
index 3db206d29b33..08430961a895 100644
--- a/drivers/serial/mcfserial.c
+++ b/drivers/serial/mcfserial.c
@@ -1132,7 +1132,7 @@ static int mcfrs_ioctl(struct tty_struct *tty, struct file * file,
 	return 0;
 }
 
-static void mcfrs_set_termios(struct tty_struct *tty, struct termios *old_termios)
+static void mcfrs_set_termios(struct tty_struct *tty, struct ktermios *old_termios)
 {
 	struct mcf_serial *info = (struct mcf_serial *)tty->driver_data;
 
diff --git a/drivers/serial/mpc52xx_uart.c b/drivers/serial/mpc52xx_uart.c
index 6dd579ed9777..9d11a75663e6 100644
--- a/drivers/serial/mpc52xx_uart.c
+++ b/drivers/serial/mpc52xx_uart.c
@@ -270,8 +270,8 @@ mpc52xx_uart_shutdown(struct uart_port *port)
 }
 
 static void
-mpc52xx_uart_set_termios(struct uart_port *port, struct termios *new,
-                         struct termios *old)
+mpc52xx_uart_set_termios(struct uart_port *port, struct ktermios *new,
+                         struct ktermios *old)
 {
 	struct mpc52xx_psc __iomem *psc = PSC(port);
 	unsigned long flags;
diff --git a/drivers/serial/mpsc.c b/drivers/serial/mpsc.c
index 29823bd60fb0..3d2fcc57b1ce 100644
--- a/drivers/serial/mpsc.c
+++ b/drivers/serial/mpsc.c
@@ -1440,8 +1440,8 @@ mpsc_shutdown(struct uart_port *port)
 }
 
 static void
-mpsc_set_termios(struct uart_port *port, struct termios *termios,
-		 struct termios *old)
+mpsc_set_termios(struct uart_port *port, struct ktermios *termios,
+		 struct ktermios *old)
 {
 	struct mpsc_port_info *pi = (struct mpsc_port_info *)port;
 	u32 baud;
diff --git a/drivers/serial/mux.c b/drivers/serial/mux.c
index 8ad1b8c5ec5d..ccb8fa1800a5 100644
--- a/drivers/serial/mux.c
+++ b/drivers/serial/mux.c
@@ -273,8 +273,8 @@ static void mux_shutdown(struct uart_port *port)
  * The Serial Mux does not support this function.
  */
 static void
-mux_set_termios(struct uart_port *port, struct termios *termios,
-	        struct termios *old)
+mux_set_termios(struct uart_port *port, struct ktermios *termios,
+	        struct ktermios *old)
 {
 }
 
diff --git a/drivers/serial/netx-serial.c b/drivers/serial/netx-serial.c
index 062bad457b1a..b56f7db45031 100644
--- a/drivers/serial/netx-serial.c
+++ b/drivers/serial/netx-serial.c
@@ -337,8 +337,8 @@ static void netx_shutdown(struct uart_port *port)
 }
 
 static void
-netx_set_termios(struct uart_port *port, struct termios *termios,
-		   struct termios *old)
+netx_set_termios(struct uart_port *port, struct ktermios *termios,
+		   struct ktermios *old)
 {
 	unsigned int baud, quot;
 	unsigned char old_cr;
diff --git a/drivers/serial/pmac_zilog.c b/drivers/serial/pmac_zilog.c
index bf9809ed9c0b..752ef07516b9 100644
--- a/drivers/serial/pmac_zilog.c
+++ b/drivers/serial/pmac_zilog.c
@@ -1262,8 +1262,8 @@ static void pmz_irda_setup(struct uart_pmac_port *uap, unsigned long *baud)
 }
 
 
-static void __pmz_set_termios(struct uart_port *port, struct termios *termios,
-			      struct termios *old)
+static void __pmz_set_termios(struct uart_port *port, struct ktermios *termios,
+			      struct ktermios *old)
 {
 	struct uart_pmac_port *uap = to_pmz(port);
 	unsigned long baud;
@@ -1273,7 +1273,7 @@ static void __pmz_set_termios(struct uart_port *port, struct termios *termios,
 	if (ZS_IS_ASLEEP(uap))
 		return;
 
-	memcpy(&uap->termios_cache, termios, sizeof(struct termios));
+	memcpy(&uap->termios_cache, termios, sizeof(struct ktermios));
 
 	/* XXX Check which revs of machines actually allow 1 and 4Mb speeds
 	 * on the IR dongle. Note that the IRTTY driver currently doesn't know
@@ -1313,8 +1313,8 @@ static void __pmz_set_termios(struct uart_port *port, struct termios *termios,
 }
 
 /* The port lock is not held.  */
-static void pmz_set_termios(struct uart_port *port, struct termios *termios,
-			    struct termios *old)
+static void pmz_set_termios(struct uart_port *port, struct ktermios *termios,
+			    struct ktermios *old)
 {
 	struct uart_pmac_port *uap = to_pmz(port);
 	unsigned long flags;
diff --git a/drivers/serial/pmac_zilog.h b/drivers/serial/pmac_zilog.h
index c03f9bfacdd8..570b0d925e83 100644
--- a/drivers/serial/pmac_zilog.h
+++ b/drivers/serial/pmac_zilog.h
@@ -60,7 +60,7 @@ struct uart_pmac_port {
 	volatile struct dbdma_regs	__iomem *tx_dma_regs;
 	volatile struct dbdma_regs	__iomem *rx_dma_regs;
 
-	struct termios			termios_cache;
+	struct ktermios			termios_cache;
 };
 
 #define to_pmz(p) ((struct uart_pmac_port *)(p))
diff --git a/drivers/serial/pxa.c b/drivers/serial/pxa.c
index 415fe9633a9b..d403aaa55092 100644
--- a/drivers/serial/pxa.c
+++ b/drivers/serial/pxa.c
@@ -433,8 +433,8 @@ static void serial_pxa_shutdown(struct uart_port *port)
 }
 
 static void
-serial_pxa_set_termios(struct uart_port *port, struct termios *termios,
-		       struct termios *old)
+serial_pxa_set_termios(struct uart_port *port, struct ktermios *termios,
+		       struct ktermios *old)
 {
 	struct uart_pxa_port *up = (struct uart_pxa_port *)port;
 	unsigned char cval, fcr = 0;
diff --git a/drivers/serial/s3c2410.c b/drivers/serial/s3c2410.c
index 8dfc2dd058ca..3ba9208ebd0c 100644
--- a/drivers/serial/s3c2410.c
+++ b/drivers/serial/s3c2410.c
@@ -738,8 +738,8 @@ static unsigned int s3c24xx_serial_getclk(struct uart_port *port,
 }
 
 static void s3c24xx_serial_set_termios(struct uart_port *port,
-				       struct termios *termios,
-				       struct termios *old)
+				       struct ktermios *termios,
+				       struct ktermios *old)
 {
 	struct s3c2410_uartcfg *cfg = s3c24xx_port_to_cfg(port);
 	struct s3c24xx_uart_port *ourport = to_ourport(port);
diff --git a/drivers/serial/sa1100.c b/drivers/serial/sa1100.c
index d4065266b6fc..58a83c27e14b 100644
--- a/drivers/serial/sa1100.c
+++ b/drivers/serial/sa1100.c
@@ -408,8 +408,8 @@ static void sa1100_shutdown(struct uart_port *port)
 }
 
 static void
-sa1100_set_termios(struct uart_port *port, struct termios *termios,
-		   struct termios *old)
+sa1100_set_termios(struct uart_port *port, struct ktermios *termios,
+		   struct ktermios *old)
 {
 	struct sa1100_port *sport = (struct sa1100_port *)port;
 	unsigned long flags;
diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c
index c67b05e9a451..f84982e508c7 100644
--- a/drivers/serial/serial_core.c
+++ b/drivers/serial/serial_core.c
@@ -65,7 +65,7 @@ static struct lock_class_key port_lock_key;
 #define uart_console(port)	(0)
 #endif
 
-static void uart_change_speed(struct uart_state *state, struct termios *old_termios);
+static void uart_change_speed(struct uart_state *state, struct ktermios *old_termios);
 static void uart_wait_until_sent(struct tty_struct *tty, int timeout);
 static void uart_change_pm(struct uart_state *state, int pm_state);
 
@@ -338,8 +338,8 @@ EXPORT_SYMBOL(uart_update_timeout);
  *	we're actually going to be using.
  */
 unsigned int
-uart_get_baud_rate(struct uart_port *port, struct termios *termios,
-		   struct termios *old, unsigned int min, unsigned int max)
+uart_get_baud_rate(struct uart_port *port, struct ktermios *termios,
+		   struct ktermios *old, unsigned int min, unsigned int max)
 {
 	unsigned int try, baud, altbaud = 38400;
 	upf_t flags = port->flags & UPF_SPD_MASK;
@@ -421,11 +421,11 @@ uart_get_divisor(struct uart_port *port, unsigned int baud)
 EXPORT_SYMBOL(uart_get_divisor);
 
 static void
-uart_change_speed(struct uart_state *state, struct termios *old_termios)
+uart_change_speed(struct uart_state *state, struct ktermios *old_termios)
 {
 	struct tty_struct *tty = state->info->tty;
 	struct uart_port *port = state->port;
-	struct termios *termios;
+	struct ktermios *termios;
 
 	/*
 	 * If we have no tty, termios, or the port does not exist,
@@ -1139,7 +1139,7 @@ uart_ioctl(struct tty_struct *tty, struct file *filp, unsigned int cmd,
 	return ret;
 }
 
-static void uart_set_termios(struct tty_struct *tty, struct termios *old_termios)
+static void uart_set_termios(struct tty_struct *tty, struct ktermios *old_termios)
 {
 	struct uart_state *state = tty->driver_data;
 	unsigned long flags;
@@ -1866,7 +1866,7 @@ int __init
 uart_set_options(struct uart_port *port, struct console *co,
 		 int baud, int parity, int bits, int flow)
 {
-	struct termios termios;
+	struct ktermios termios;
 	int i;
 
 	/*
@@ -1876,7 +1876,7 @@ uart_set_options(struct uart_port *port, struct console *co,
 	spin_lock_init(&port->lock);
 	lockdep_set_class(&port->lock, &port_lock_key);
 
-	memset(&termios, 0, sizeof(struct termios));
+	memset(&termios, 0, sizeof(struct ktermios));
 
 	termios.c_cflag = CREAD | HUPCL | CLOCAL;
 
@@ -1991,12 +1991,12 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *port)
 	 * Re-enable the console device after suspending.
 	 */
 	if (uart_console(port)) {
-		struct termios termios;
+		struct ktermios termios;
 
 		/*
 		 * First try to use the console cflag setting.
 		 */
-		memset(&termios, 0, sizeof(struct termios));
+		memset(&termios, 0, sizeof(struct ktermios));
 		termios.c_cflag = port->cons->cflag;
 
 		/*
@@ -2189,6 +2189,7 @@ int uart_register_driver(struct uart_driver *drv)
 	normal->subtype		= SERIAL_TYPE_NORMAL;
 	normal->init_termios	= tty_std_termios;
 	normal->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
+	normal->init_termios.c_ispeed = normal->init_termios.c_ospeed = 9600;
 	normal->flags		= TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
 	normal->driver_state    = drv;
 	tty_set_operations(normal, &uart_ops);
diff --git a/drivers/serial/serial_lh7a40x.c b/drivers/serial/serial_lh7a40x.c
index 5e1ac356bbb0..eb18d429752d 100644
--- a/drivers/serial/serial_lh7a40x.c
+++ b/drivers/serial/serial_lh7a40x.c
@@ -348,8 +348,8 @@ static void lh7a40xuart_shutdown (struct uart_port* port)
 }
 
 static void lh7a40xuart_set_termios (struct uart_port* port,
-				     struct termios* termios,
-				     struct termios* old)
+				     struct ktermios* termios,
+				     struct ktermios* old)
 {
 	unsigned int con;
 	unsigned int inten;
diff --git a/drivers/serial/serial_txx9.c b/drivers/serial/serial_txx9.c
index 2a48289ac722..7186a82c4759 100644
--- a/drivers/serial/serial_txx9.c
+++ b/drivers/serial/serial_txx9.c
@@ -556,8 +556,8 @@ static void serial_txx9_shutdown(struct uart_port *port)
 }
 
 static void
-serial_txx9_set_termios(struct uart_port *port, struct termios *termios,
-		       struct termios *old)
+serial_txx9_set_termios(struct uart_port *port, struct ktermios *termios,
+		       struct ktermios *old)
 {
 	struct uart_txx9_port *up = (struct uart_txx9_port *)port;
 	unsigned int cval, fcr = 0;
diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c
index 3b5f19ec2126..9031b57f12dd 100644
--- a/drivers/serial/sh-sci.c
+++ b/drivers/serial/sh-sci.c
@@ -943,8 +943,8 @@ static void sci_shutdown(struct uart_port *port)
 		s->disable(port);
 }
 
-static void sci_set_termios(struct uart_port *port, struct termios *termios,
-			    struct termios *old)
+static void sci_set_termios(struct uart_port *port, struct ktermios *termios,
+			    struct ktermios *old)
 {
 	struct sci_port *s = &sci_ports[port->line];
 	unsigned int status, baud, smr_val;
diff --git a/drivers/serial/sn_console.c b/drivers/serial/sn_console.c
index 956b2cf08e1e..253ceb895ca7 100644
--- a/drivers/serial/sn_console.c
+++ b/drivers/serial/sn_console.c
@@ -361,8 +361,8 @@ static int snp_startup(struct uart_port *port)
  *
  */
 static void
-snp_set_termios(struct uart_port *port, struct termios *termios,
-		struct termios *old)
+snp_set_termios(struct uart_port *port, struct ktermios *termios,
+		struct ktermios *old)
 {
 }
 
diff --git a/drivers/serial/sunhv.c b/drivers/serial/sunhv.c
index 03941d27d15d..40d48566215c 100644
--- a/drivers/serial/sunhv.c
+++ b/drivers/serial/sunhv.c
@@ -281,8 +281,8 @@ static void sunhv_shutdown(struct uart_port *port)
 }
 
 /* port->lock is not held.  */
-static void sunhv_set_termios(struct uart_port *port, struct termios *termios,
-			      struct termios *old)
+static void sunhv_set_termios(struct uart_port *port, struct ktermios *termios,
+			      struct ktermios *old)
 {
 	unsigned int baud = uart_get_baud_rate(port, termios, old, 0, 4000000);
 	unsigned int quot = uart_get_divisor(port, baud);
diff --git a/drivers/serial/sunsab.c b/drivers/serial/sunsab.c
index 08a7cd6a3a0c..493d5bbb661b 100644
--- a/drivers/serial/sunsab.c
+++ b/drivers/serial/sunsab.c
@@ -786,8 +786,8 @@ static void sunsab_convert_to_sab(struct uart_sunsab_port *up, unsigned int cfla
 }
 
 /* port->lock is not held.  */
-static void sunsab_set_termios(struct uart_port *port, struct termios *termios,
-			       struct termios *old)
+static void sunsab_set_termios(struct uart_port *port, struct ktermios *termios,
+			       struct ktermios *old)
 {
 	struct uart_sunsab_port *up = (struct uart_sunsab_port *) port;
 	unsigned long flags;
diff --git a/drivers/serial/sunsu.c b/drivers/serial/sunsu.c
index c577faea60e8..564592b2b2ba 100644
--- a/drivers/serial/sunsu.c
+++ b/drivers/serial/sunsu.c
@@ -893,8 +893,8 @@ sunsu_change_speed(struct uart_port *port, unsigned int cflag,
 }
 
 static void
-sunsu_set_termios(struct uart_port *port, struct termios *termios,
-		  struct termios *old)
+sunsu_set_termios(struct uart_port *port, struct ktermios *termios,
+		  struct ktermios *old)
 {
 	unsigned int baud, quot;
 
diff --git a/drivers/serial/sunzilog.c b/drivers/serial/sunzilog.c
index b2cc703b2b9e..75de919a9471 100644
--- a/drivers/serial/sunzilog.c
+++ b/drivers/serial/sunzilog.c
@@ -922,8 +922,8 @@ sunzilog_convert_to_zs(struct uart_sunzilog_port *up, unsigned int cflag,
 
 /* The port lock is not held.  */
 static void
-sunzilog_set_termios(struct uart_port *port, struct termios *termios,
-		     struct termios *old)
+sunzilog_set_termios(struct uart_port *port, struct ktermios *termios,
+		     struct ktermios *old)
 {
 	struct uart_sunzilog_port *up = (struct uart_sunzilog_port *) port;
 	unsigned long flags;
diff --git a/drivers/serial/uartlite.c b/drivers/serial/uartlite.c
index 83690653b78b..92eba893559d 100644
--- a/drivers/serial/uartlite.c
+++ b/drivers/serial/uartlite.c
@@ -214,8 +214,8 @@ static void ulite_shutdown(struct uart_port *port)
 	free_irq(port->irq, port);
 }
 
-static void ulite_set_termios(struct uart_port *port, struct termios *termios,
-			      struct termios *old)
+static void ulite_set_termios(struct uart_port *port, struct ktermios *termios,
+			      struct ktermios *old)
 {
 	unsigned long flags;
 	unsigned int baud;
diff --git a/drivers/serial/v850e_uart.c b/drivers/serial/v850e_uart.c
index 28f3bbff87bf..dd98aca6ed08 100644
--- a/drivers/serial/v850e_uart.c
+++ b/drivers/serial/v850e_uart.c
@@ -404,8 +404,8 @@ static void v850e_uart_shutdown (struct uart_port *port)
 }
 
 static void
-v850e_uart_set_termios (struct uart_port *port, struct termios *termios,
-		        struct termios *old)
+v850e_uart_set_termios (struct uart_port *port, struct ktermios *termios,
+		        struct ktermios *old)
 {
 	unsigned cflags = termios->c_cflag;
 
diff --git a/drivers/serial/vr41xx_siu.c b/drivers/serial/vr41xx_siu.c
index fd51f8182dec..cf0e663b42ed 100644
--- a/drivers/serial/vr41xx_siu.c
+++ b/drivers/serial/vr41xx_siu.c
@@ -562,8 +562,8 @@ static void siu_shutdown(struct uart_port *port)
 	free_irq(port->irq, port);
 }
 
-static void siu_set_termios(struct uart_port *port, struct termios *new,
-                            struct termios *old)
+static void siu_set_termios(struct uart_port *port, struct ktermios *new,
+                            struct ktermios *old)
 {
 	tcflag_t c_cflag, c_iflag;
 	uint8_t lcr, fcr, ier;
diff --git a/drivers/tc/zs.c b/drivers/tc/zs.c
index 792becdfe6f8..fc3197273663 100644
--- a/drivers/tc/zs.c
+++ b/drivers/tc/zs.c
@@ -1238,7 +1238,7 @@ static int rs_ioctl(struct tty_struct *tty, struct file * file,
 	return 0;
 }
 
-static void rs_set_termios(struct tty_struct *tty, struct termios *old_termios)
+static void rs_set_termios(struct tty_struct *tty, struct ktermios *old_termios)
 {
 	struct dec_serial *info = (struct dec_serial *)tty->driver_data;
 	int was_stopped;
diff --git a/drivers/telephony/ixj.c b/drivers/telephony/ixj.c
index 1b601b6cf2a2..df4cc1fb5f68 100644
--- a/drivers/telephony/ixj.c
+++ b/drivers/telephony/ixj.c
@@ -2747,7 +2747,7 @@ static void alaw2ulaw(unsigned char *buff, unsigned long len)
 static ssize_t ixj_read(struct file * file_p, char __user *buf, size_t length, loff_t * ppos)
 {
 	unsigned long i = *ppos;
-	IXJ * j = get_ixj(NUM(file_p->f_dentry->d_inode));
+	IXJ * j = get_ixj(NUM(file_p->f_path.dentry->d_inode));
 
 	DECLARE_WAITQUEUE(wait, current);
 
@@ -2804,7 +2804,7 @@ static ssize_t ixj_enhanced_read(struct file * file_p, char __user *buf, size_t
 {
 	int pre_retval;
 	ssize_t read_retval = 0;
-	IXJ *j = get_ixj(NUM(file_p->f_dentry->d_inode));
+	IXJ *j = get_ixj(NUM(file_p->f_path.dentry->d_inode));
 
 	pre_retval = ixj_PreRead(j, 0L);
 	switch (pre_retval) {
@@ -2883,7 +2883,7 @@ static ssize_t ixj_enhanced_write(struct file * file_p, const char __user *buf,
 	int pre_retval;
 	ssize_t write_retval = 0;
 
-	IXJ *j = get_ixj(NUM(file_p->f_dentry->d_inode));
+	IXJ *j = get_ixj(NUM(file_p->f_path.dentry->d_inode));
 
 	pre_retval = ixj_PreWrite(j, 0L);
 	switch (pre_retval) {
@@ -4582,7 +4582,7 @@ static unsigned int ixj_poll(struct file *file_p, poll_table * wait)
 {
 	unsigned int mask = 0;
 
-	IXJ *j = get_ixj(NUM(file_p->f_dentry->d_inode));
+	IXJ *j = get_ixj(NUM(file_p->f_path.dentry->d_inode));
 
 	poll_wait(file_p, &(j->poll_q), wait);
 	if (j->read_buffer_ready > 0)
@@ -6657,7 +6657,7 @@ static int ixj_ioctl(struct inode *inode, struct file *file_p, unsigned int cmd,
 
 static int ixj_fasync(int fd, struct file *file_p, int mode)
 {
-	IXJ *j = get_ixj(NUM(file_p->f_dentry->d_inode));
+	IXJ *j = get_ixj(NUM(file_p->f_path.dentry->d_inode));
 
 	return fasync_helper(fd, file_p, mode, &j->async_queue);
 }
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
index 7f1fa956dcdb..98199628e394 100644
--- a/drivers/usb/class/cdc-acm.c
+++ b/drivers/usb/class/cdc-acm.c
@@ -677,10 +677,10 @@ static const __u8 acm_tty_size[] = {
 	5, 6, 7, 8
 };
 
-static void acm_tty_set_termios(struct tty_struct *tty, struct termios *termios_old)
+static void acm_tty_set_termios(struct tty_struct *tty, struct ktermios *termios_old)
 {
 	struct acm *acm = tty->driver_data;
-	struct termios *termios = tty->termios;
+	struct ktermios *termios = tty->termios;
 	struct usb_cdc_line_coding newline;
 	int newctrl = acm->ctrlout;
 
diff --git a/drivers/usb/core/inode.c b/drivers/usb/core/inode.c
index b5d6a79af0be..11dad22da41c 100644
--- a/drivers/usb/core/inode.c
+++ b/drivers/usb/core/inode.c
@@ -379,7 +379,7 @@ static loff_t default_file_lseek (struct file *file, loff_t offset, int orig)
 {
 	loff_t retval = -EINVAL;
 
-	mutex_lock(&file->f_dentry->d_inode->i_mutex);
+	mutex_lock(&file->f_path.dentry->d_inode->i_mutex);
 	switch(orig) {
 	case 0:
 		if (offset > 0) {
@@ -396,7 +396,7 @@ static loff_t default_file_lseek (struct file *file, loff_t offset, int orig)
 	default:
 		break;
 	}
-	mutex_unlock(&file->f_dentry->d_inode->i_mutex);
+	mutex_unlock(&file->f_path.dentry->d_inode->i_mutex);
 	return retval;
 }
 
diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c
index c98316ce8384..a265e262a2ee 100644
--- a/drivers/usb/gadget/file_storage.c
+++ b/drivers/usb/gadget/file_storage.c
@@ -1909,10 +1909,10 @@ static int fsync_sub(struct lun *curlun)
 	if (!filp->f_op->fsync)
 		return -EINVAL;
 
-	inode = filp->f_dentry->d_inode;
+	inode = filp->f_path.dentry->d_inode;
 	mutex_lock(&inode->i_mutex);
 	rc = filemap_fdatawrite(inode->i_mapping);
-	err = filp->f_op->fsync(filp, filp->f_dentry, 1);
+	err = filp->f_op->fsync(filp, filp->f_path.dentry, 1);
 	if (!rc)
 		rc = err;
 	err = filemap_fdatawait(inode->i_mapping);
@@ -1950,7 +1950,7 @@ static int do_synchronize_cache(struct fsg_dev *fsg)
 static void invalidate_sub(struct lun *curlun)
 {
 	struct file	*filp = curlun->filp;
-	struct inode	*inode = filp->f_dentry->d_inode;
+	struct inode	*inode = filp->f_path.dentry->d_inode;
 	unsigned long	rc;
 
 	rc = invalidate_inode_pages(inode->i_mapping);
@@ -3526,8 +3526,8 @@ static int open_backing_file(struct lun *curlun, const char *filename)
 	if (!(filp->f_mode & FMODE_WRITE))
 		ro = 1;
 
-	if (filp->f_dentry)
-		inode = filp->f_dentry->d_inode;
+	if (filp->f_path.dentry)
+		inode = filp->f_path.dentry->d_inode;
 	if (inode && S_ISBLK(inode->i_mode)) {
 		if (bdev_read_only(inode->i_bdev))
 			ro = 1;
@@ -3606,7 +3606,7 @@ static ssize_t show_file(struct device *dev, struct device_attribute *attr, char
 
 	down_read(&fsg->filesem);
 	if (backing_file_is_open(curlun)) {	// Get the complete pathname
-		p = d_path(curlun->filp->f_dentry, curlun->filp->f_vfsmnt,
+		p = d_path(curlun->filp->f_path.dentry, curlun->filp->f_path.mnt,
 				buf, PAGE_SIZE - 1);
 		if (IS_ERR(p))
 			rc = PTR_ERR(p);
@@ -4030,8 +4030,8 @@ static int __init fsg_bind(struct usb_gadget *gadget)
 		if (backing_file_is_open(curlun)) {
 			p = NULL;
 			if (pathbuf) {
-				p = d_path(curlun->filp->f_dentry,
-					curlun->filp->f_vfsmnt,
+				p = d_path(curlun->filp->f_path.dentry,
+					curlun->filp->f_path.mnt,
 					pathbuf, PATH_MAX);
 				if (IS_ERR(p))
 					p = NULL;
diff --git a/drivers/usb/gadget/serial.c b/drivers/usb/gadget/serial.c
index 208e55a667ac..5516c59ed5ec 100644
--- a/drivers/usb/gadget/serial.c
+++ b/drivers/usb/gadget/serial.c
@@ -200,7 +200,7 @@ static void gs_unthrottle(struct tty_struct * tty);
 static void gs_break(struct tty_struct *tty, int break_state);
 static int  gs_ioctl(struct tty_struct *tty, struct file *file,
 	unsigned int cmd, unsigned long arg);
-static void gs_set_termios(struct tty_struct *tty, struct termios *old);
+static void gs_set_termios(struct tty_struct *tty, struct ktermios *old);
 
 static int gs_send(struct gs_dev *dev);
 static int gs_send_packet(struct gs_dev *dev, char *packet,
@@ -1077,7 +1077,7 @@ static int gs_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd,
 /*
  * gs_set_termios
  */
-static void gs_set_termios(struct tty_struct *tty, struct termios *old)
+static void gs_set_termios(struct tty_struct *tty, struct ktermios *old)
 {
 }
 
diff --git a/drivers/usb/input/Kconfig b/drivers/usb/input/Kconfig
index 661af7aa6236..8a62d4785755 100644
--- a/drivers/usb/input/Kconfig
+++ b/drivers/usb/input/Kconfig
@@ -6,9 +6,10 @@ comment "USB Input Devices"
 
 config USB_HID
 	tristate "USB Human Interface Device (full HID) support"
-	depends on USB
+	default y
+	depends on USB && HID
 	---help---
-	  Say Y here if you want full HID support to connect keyboards,
+	  Say Y here if you want full HID support to connect USB keyboards,
 	  mice, joysticks, graphic tablets, or any other HID based devices
 	  to your computer via USB. You also need to select HID Input layer
 	  support (below) if you want to use keyboards, mice, joysticks and
@@ -27,20 +28,10 @@ config USB_HID
 comment "Input core support is needed for USB HID input layer or HIDBP support"
 	depends on USB_HID && INPUT=n
 
-config USB_HIDINPUT
-	bool "HID input layer support"
-	default y
-	depends on INPUT && USB_HID
-	help
-	  Say Y here if you want to use a USB keyboard, mouse or joystick,
-	  or any other HID input device.
-
-	  If unsure, say Y.
-
-config USB_HIDINPUT_POWERBOOK
+config USB_HID_POWERBOOK
 	bool "Enable support for iBook/PowerBook special keys"
 	default n
-	depends on USB_HIDINPUT
+	depends on USB_HID
 	help
 	  Say Y here if you want support for the special keys (Fn, Numlock) on
 	  Apple iBooks and PowerBooks.
@@ -49,7 +40,7 @@ config USB_HIDINPUT_POWERBOOK
 
 config HID_FF
 	bool "Force feedback support (EXPERIMENTAL)"
-	depends on USB_HIDINPUT && EXPERIMENTAL
+	depends on USB_HID && EXPERIMENTAL
 	help
 	  Say Y here is you want force feedback support for a few HID devices.
 	  See below for a list of supported devices.
diff --git a/drivers/usb/input/Makefile b/drivers/usb/input/Makefile
index d946d5213b30..1a24b5bfa05f 100644
--- a/drivers/usb/input/Makefile
+++ b/drivers/usb/input/Makefile
@@ -11,9 +11,6 @@ usbhid-objs	:= hid-core.o
 ifeq ($(CONFIG_USB_HIDDEV),y)
 	usbhid-objs	+= hiddev.o
 endif
-ifeq ($(CONFIG_USB_HIDINPUT),y)
-	usbhid-objs	+= hid-input.o
-endif
 ifeq ($(CONFIG_HID_PID),y)
 	usbhid-objs	+= hid-pidff.o
 endif
diff --git a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c
index 0811c39bd14f..89fa6885709b 100644
--- a/drivers/usb/input/hid-core.c
+++ b/drivers/usb/input/hid-core.c
@@ -4,6 +4,7 @@
  *  Copyright (c) 1999 Andreas Gal
  *  Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz>
  *  Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc
+ *  Copyright (c) 2006 Jiri Kosina
  */
 
 /*
@@ -32,8 +33,9 @@
 
 #include <linux/usb.h>
 
-#include "hid.h"
+#include <linux/hid.h>
 #include <linux/hiddev.h>
+#include "usbhid.h"
 
 /*
  * Version Information
@@ -54,886 +56,10 @@ static unsigned int hid_mousepoll_interval;
 module_param_named(mousepoll, hid_mousepoll_interval, uint, 0644);
 MODULE_PARM_DESC(mousepoll, "Polling interval of mice");
 
-/*
- * Register a new report for a device.
- */
-
-static struct hid_report *hid_register_report(struct hid_device *device, unsigned type, unsigned id)
-{
-	struct hid_report_enum *report_enum = device->report_enum + type;
-	struct hid_report *report;
-
-	if (report_enum->report_id_hash[id])
-		return report_enum->report_id_hash[id];
-
-	if (!(report = kzalloc(sizeof(struct hid_report), GFP_KERNEL)))
-		return NULL;
-
-	if (id != 0)
-		report_enum->numbered = 1;
-
-	report->id = id;
-	report->type = type;
-	report->size = 0;
-	report->device = device;
-	report_enum->report_id_hash[id] = report;
-
-	list_add_tail(&report->list, &report_enum->report_list);
-
-	return report;
-}
-
-/*
- * Register a new field for this report.
- */
-
-static struct hid_field *hid_register_field(struct hid_report *report, unsigned usages, unsigned values)
-{
-	struct hid_field *field;
-
-	if (report->maxfield == HID_MAX_FIELDS) {
-		dbg("too many fields in report");
-		return NULL;
-	}
-
-	if (!(field = kzalloc(sizeof(struct hid_field) + usages * sizeof(struct hid_usage)
-		+ values * sizeof(unsigned), GFP_KERNEL))) return NULL;
-
-	field->index = report->maxfield++;
-	report->field[field->index] = field;
-	field->usage = (struct hid_usage *)(field + 1);
-	field->value = (unsigned *)(field->usage + usages);
-	field->report = report;
-
-	return field;
-}
-
-/*
- * Open a collection. The type/usage is pushed on the stack.
- */
-
-static int open_collection(struct hid_parser *parser, unsigned type)
-{
-	struct hid_collection *collection;
-	unsigned usage;
-
-	usage = parser->local.usage[0];
-
-	if (parser->collection_stack_ptr == HID_COLLECTION_STACK_SIZE) {
-		dbg("collection stack overflow");
-		return -1;
-	}
-
-	if (parser->device->maxcollection == parser->device->collection_size) {
-		collection = kmalloc(sizeof(struct hid_collection) *
-				parser->device->collection_size * 2, GFP_KERNEL);
-		if (collection == NULL) {
-			dbg("failed to reallocate collection array");
-			return -1;
-		}
-		memcpy(collection, parser->device->collection,
-			sizeof(struct hid_collection) *
-			parser->device->collection_size);
-		memset(collection + parser->device->collection_size, 0,
-			sizeof(struct hid_collection) *
-			parser->device->collection_size);
-		kfree(parser->device->collection);
-		parser->device->collection = collection;
-		parser->device->collection_size *= 2;
-	}
-
-	parser->collection_stack[parser->collection_stack_ptr++] =
-		parser->device->maxcollection;
-
-	collection = parser->device->collection +
-		parser->device->maxcollection++;
-	collection->type = type;
-	collection->usage = usage;
-	collection->level = parser->collection_stack_ptr - 1;
-
-	if (type == HID_COLLECTION_APPLICATION)
-		parser->device->maxapplication++;
-
-	return 0;
-}
-
-/*
- * Close a collection.
- */
-
-static int close_collection(struct hid_parser *parser)
-{
-	if (!parser->collection_stack_ptr) {
-		dbg("collection stack underflow");
-		return -1;
-	}
-	parser->collection_stack_ptr--;
-	return 0;
-}
-
-/*
- * Climb up the stack, search for the specified collection type
- * and return the usage.
- */
-
-static unsigned hid_lookup_collection(struct hid_parser *parser, unsigned type)
-{
-	int n;
-	for (n = parser->collection_stack_ptr - 1; n >= 0; n--)
-		if (parser->device->collection[parser->collection_stack[n]].type == type)
-			return parser->device->collection[parser->collection_stack[n]].usage;
-	return 0; /* we know nothing about this usage type */
-}
-
-/*
- * Add a usage to the temporary parser table.
- */
-
-static int hid_add_usage(struct hid_parser *parser, unsigned usage)
-{
-	if (parser->local.usage_index >= HID_MAX_USAGES) {
-		dbg("usage index exceeded");
-		return -1;
-	}
-	parser->local.usage[parser->local.usage_index] = usage;
-	parser->local.collection_index[parser->local.usage_index] =
-		parser->collection_stack_ptr ?
-		parser->collection_stack[parser->collection_stack_ptr - 1] : 0;
-	parser->local.usage_index++;
-	return 0;
-}
-
-/*
- * Register a new field for this report.
- */
-
-static int hid_add_field(struct hid_parser *parser, unsigned report_type, unsigned flags)
-{
-	struct hid_report *report;
-	struct hid_field *field;
-	int usages;
-	unsigned offset;
-	int i;
-
-	if (!(report = hid_register_report(parser->device, report_type, parser->global.report_id))) {
-		dbg("hid_register_report failed");
-		return -1;
-	}
-
-	if (parser->global.logical_maximum < parser->global.logical_minimum) {
-		dbg("logical range invalid %d %d", parser->global.logical_minimum, parser->global.logical_maximum);
-		return -1;
-	}
-
-	offset = report->size;
-	report->size += parser->global.report_size * parser->global.report_count;
-
-	if (!parser->local.usage_index) /* Ignore padding fields */
-		return 0;
-
-	usages = max_t(int, parser->local.usage_index, parser->global.report_count);
-
-	if ((field = hid_register_field(report, usages, parser->global.report_count)) == NULL)
-		return 0;
-
-	field->physical = hid_lookup_collection(parser, HID_COLLECTION_PHYSICAL);
-	field->logical = hid_lookup_collection(parser, HID_COLLECTION_LOGICAL);
-	field->application = hid_lookup_collection(parser, HID_COLLECTION_APPLICATION);
-
-	for (i = 0; i < usages; i++) {
-		int j = i;
-		/* Duplicate the last usage we parsed if we have excess values */
-		if (i >= parser->local.usage_index)
-			j = parser->local.usage_index - 1;
-		field->usage[i].hid = parser->local.usage[j];
-		field->usage[i].collection_index =
-			parser->local.collection_index[j];
-	}
-
-	field->maxusage = usages;
-	field->flags = flags;
-	field->report_offset = offset;
-	field->report_type = report_type;
-	field->report_size = parser->global.report_size;
-	field->report_count = parser->global.report_count;
-	field->logical_minimum = parser->global.logical_minimum;
-	field->logical_maximum = parser->global.logical_maximum;
-	field->physical_minimum = parser->global.physical_minimum;
-	field->physical_maximum = parser->global.physical_maximum;
-	field->unit_exponent = parser->global.unit_exponent;
-	field->unit = parser->global.unit;
-
-	return 0;
-}
-
-/*
- * Read data value from item.
- */
-
-static u32 item_udata(struct hid_item *item)
-{
-	switch (item->size) {
-		case 1: return item->data.u8;
-		case 2: return item->data.u16;
-		case 4: return item->data.u32;
-	}
-	return 0;
-}
-
-static s32 item_sdata(struct hid_item *item)
-{
-	switch (item->size) {
-		case 1: return item->data.s8;
-		case 2: return item->data.s16;
-		case 4: return item->data.s32;
-	}
-	return 0;
-}
-
-/*
- * Process a global item.
- */
-
-static int hid_parser_global(struct hid_parser *parser, struct hid_item *item)
-{
-	switch (item->tag) {
-
-		case HID_GLOBAL_ITEM_TAG_PUSH:
-
-			if (parser->global_stack_ptr == HID_GLOBAL_STACK_SIZE) {
-				dbg("global enviroment stack overflow");
-				return -1;
-			}
-
-			memcpy(parser->global_stack + parser->global_stack_ptr++,
-				&parser->global, sizeof(struct hid_global));
-			return 0;
-
-		case HID_GLOBAL_ITEM_TAG_POP:
-
-			if (!parser->global_stack_ptr) {
-				dbg("global enviroment stack underflow");
-				return -1;
-			}
-
-			memcpy(&parser->global, parser->global_stack + --parser->global_stack_ptr,
-				sizeof(struct hid_global));
-			return 0;
-
-		case HID_GLOBAL_ITEM_TAG_USAGE_PAGE:
-			parser->global.usage_page = item_udata(item);
-			return 0;
-
-		case HID_GLOBAL_ITEM_TAG_LOGICAL_MINIMUM:
-			parser->global.logical_minimum = item_sdata(item);
-			return 0;
-
-		case HID_GLOBAL_ITEM_TAG_LOGICAL_MAXIMUM:
-			if (parser->global.logical_minimum < 0)
-				parser->global.logical_maximum = item_sdata(item);
-			else
-				parser->global.logical_maximum = item_udata(item);
-			return 0;
-
-		case HID_GLOBAL_ITEM_TAG_PHYSICAL_MINIMUM:
-			parser->global.physical_minimum = item_sdata(item);
-			return 0;
-
-		case HID_GLOBAL_ITEM_TAG_PHYSICAL_MAXIMUM:
-			if (parser->global.physical_minimum < 0)
-				parser->global.physical_maximum = item_sdata(item);
-			else
-				parser->global.physical_maximum = item_udata(item);
-			return 0;
-
-		case HID_GLOBAL_ITEM_TAG_UNIT_EXPONENT:
-			parser->global.unit_exponent = item_sdata(item);
-			return 0;
-
-		case HID_GLOBAL_ITEM_TAG_UNIT:
-			parser->global.unit = item_udata(item);
-			return 0;
-
-		case HID_GLOBAL_ITEM_TAG_REPORT_SIZE:
-			if ((parser->global.report_size = item_udata(item)) > 32) {
-				dbg("invalid report_size %d", parser->global.report_size);
-				return -1;
-			}
-			return 0;
-
-		case HID_GLOBAL_ITEM_TAG_REPORT_COUNT:
-			if ((parser->global.report_count = item_udata(item)) > HID_MAX_USAGES) {
-				dbg("invalid report_count %d", parser->global.report_count);
-				return -1;
-			}
-			return 0;
-
-		case HID_GLOBAL_ITEM_TAG_REPORT_ID:
-			if ((parser->global.report_id = item_udata(item)) == 0) {
-				dbg("report_id 0 is invalid");
-				return -1;
-			}
-			return 0;
-
-		default:
-			dbg("unknown global tag 0x%x", item->tag);
-			return -1;
-	}
-}
-
-/*
- * Process a local item.
- */
-
-static int hid_parser_local(struct hid_parser *parser, struct hid_item *item)
-{
-	__u32 data;
-	unsigned n;
-
-	if (item->size == 0) {
-		dbg("item data expected for local item");
-		return -1;
-	}
-
-	data = item_udata(item);
-
-	switch (item->tag) {
-
-		case HID_LOCAL_ITEM_TAG_DELIMITER:
-
-			if (data) {
-				/*
-				 * We treat items before the first delimiter
-				 * as global to all usage sets (branch 0).
-				 * In the moment we process only these global
-				 * items and the first delimiter set.
-				 */
-				if (parser->local.delimiter_depth != 0) {
-					dbg("nested delimiters");
-					return -1;
-				}
-				parser->local.delimiter_depth++;
-				parser->local.delimiter_branch++;
-			} else {
-				if (parser->local.delimiter_depth < 1) {
-					dbg("bogus close delimiter");
-					return -1;
-				}
-				parser->local.delimiter_depth--;
-			}
-			return 1;
-
-		case HID_LOCAL_ITEM_TAG_USAGE:
-
-			if (parser->local.delimiter_branch > 1) {
-				dbg("alternative usage ignored");
-				return 0;
-			}
-
-			if (item->size <= 2)
-				data = (parser->global.usage_page << 16) + data;
-
-			return hid_add_usage(parser, data);
-
-		case HID_LOCAL_ITEM_TAG_USAGE_MINIMUM:
-
-			if (parser->local.delimiter_branch > 1) {
-				dbg("alternative usage ignored");
-				return 0;
-			}
-
-			if (item->size <= 2)
-				data = (parser->global.usage_page << 16) + data;
-
-			parser->local.usage_minimum = data;
-			return 0;
-
-		case HID_LOCAL_ITEM_TAG_USAGE_MAXIMUM:
-
-			if (parser->local.delimiter_branch > 1) {
-				dbg("alternative usage ignored");
-				return 0;
-			}
-
-			if (item->size <= 2)
-				data = (parser->global.usage_page << 16) + data;
-
-			for (n = parser->local.usage_minimum; n <= data; n++)
-				if (hid_add_usage(parser, n)) {
-					dbg("hid_add_usage failed\n");
-					return -1;
-				}
-			return 0;
-
-		default:
-
-			dbg("unknown local item tag 0x%x", item->tag);
-			return 0;
-	}
-	return 0;
-}
-
-/*
- * Process a main item.
- */
-
-static int hid_parser_main(struct hid_parser *parser, struct hid_item *item)
-{
-	__u32 data;
-	int ret;
-
-	data = item_udata(item);
-
-	switch (item->tag) {
-		case HID_MAIN_ITEM_TAG_BEGIN_COLLECTION:
-			ret = open_collection(parser, data & 0xff);
-			break;
-		case HID_MAIN_ITEM_TAG_END_COLLECTION:
-			ret = close_collection(parser);
-			break;
-		case HID_MAIN_ITEM_TAG_INPUT:
-			ret = hid_add_field(parser, HID_INPUT_REPORT, data);
-			break;
-		case HID_MAIN_ITEM_TAG_OUTPUT:
-			ret = hid_add_field(parser, HID_OUTPUT_REPORT, data);
-			break;
-		case HID_MAIN_ITEM_TAG_FEATURE:
-			ret = hid_add_field(parser, HID_FEATURE_REPORT, data);
-			break;
-		default:
-			dbg("unknown main item tag 0x%x", item->tag);
-			ret = 0;
-	}
-
-	memset(&parser->local, 0, sizeof(parser->local));	/* Reset the local parser environment */
-
-	return ret;
-}
-
-/*
- * Process a reserved item.
- */
-
-static int hid_parser_reserved(struct hid_parser *parser, struct hid_item *item)
-{
-	dbg("reserved item type, tag 0x%x", item->tag);
-	return 0;
-}
-
-/*
- * Free a report and all registered fields. The field->usage and
- * field->value table's are allocated behind the field, so we need
- * only to free(field) itself.
- */
-
-static void hid_free_report(struct hid_report *report)
-{
-	unsigned n;
-
-	for (n = 0; n < report->maxfield; n++)
-		kfree(report->field[n]);
-	kfree(report);
-}
-
-/*
- * Free a device structure, all reports, and all fields.
- */
-
-static void hid_free_device(struct hid_device *device)
-{
-	unsigned i,j;
-
-	for (i = 0; i < HID_REPORT_TYPES; i++) {
-		struct hid_report_enum *report_enum = device->report_enum + i;
-
-		for (j = 0; j < 256; j++) {
-			struct hid_report *report = report_enum->report_id_hash[j];
-			if (report)
-				hid_free_report(report);
-		}
-	}
-
-	kfree(device->rdesc);
-	kfree(device);
-}
-
-/*
- * Fetch a report description item from the data stream. We support long
- * items, though they are not used yet.
- */
-
-static u8 *fetch_item(__u8 *start, __u8 *end, struct hid_item *item)
-{
-	u8 b;
-
-	if ((end - start) <= 0)
-		return NULL;
-
-	b = *start++;
-
-	item->type = (b >> 2) & 3;
-	item->tag  = (b >> 4) & 15;
-
-	if (item->tag == HID_ITEM_TAG_LONG) {
-
-		item->format = HID_ITEM_FORMAT_LONG;
-
-		if ((end - start) < 2)
-			return NULL;
-
-		item->size = *start++;
-		item->tag  = *start++;
-
-		if ((end - start) < item->size)
-			return NULL;
-
-		item->data.longdata = start;
-		start += item->size;
-		return start;
-	}
-
-	item->format = HID_ITEM_FORMAT_SHORT;
-	item->size = b & 3;
-
-	switch (item->size) {
-
-		case 0:
-			return start;
-
-		case 1:
-			if ((end - start) < 1)
-				return NULL;
-			item->data.u8 = *start++;
-			return start;
-
-		case 2:
-			if ((end - start) < 2)
-				return NULL;
-			item->data.u16 = le16_to_cpu(get_unaligned((__le16*)start));
-			start = (__u8 *)((__le16 *)start + 1);
-			return start;
-
-		case 3:
-			item->size++;
-			if ((end - start) < 4)
-				return NULL;
-			item->data.u32 = le32_to_cpu(get_unaligned((__le32*)start));
-			start = (__u8 *)((__le32 *)start + 1);
-			return start;
-	}
-
-	return NULL;
-}
-
-/*
- * Parse a report description into a hid_device structure. Reports are
- * enumerated, fields are attached to these reports.
- */
-
-static struct hid_device *hid_parse_report(__u8 *start, unsigned size)
-{
-	struct hid_device *device;
-	struct hid_parser *parser;
-	struct hid_item item;
-	__u8 *end;
-	unsigned i;
-	static int (*dispatch_type[])(struct hid_parser *parser,
-				      struct hid_item *item) = {
-		hid_parser_main,
-		hid_parser_global,
-		hid_parser_local,
-		hid_parser_reserved
-	};
-
-	if (!(device = kzalloc(sizeof(struct hid_device), GFP_KERNEL)))
-		return NULL;
-
-	if (!(device->collection = kzalloc(sizeof(struct hid_collection) *
-				   HID_DEFAULT_NUM_COLLECTIONS, GFP_KERNEL))) {
-		kfree(device);
-		return NULL;
-	}
-	device->collection_size = HID_DEFAULT_NUM_COLLECTIONS;
-
-	for (i = 0; i < HID_REPORT_TYPES; i++)
-		INIT_LIST_HEAD(&device->report_enum[i].report_list);
-
-	if (!(device->rdesc = (__u8 *)kmalloc(size, GFP_KERNEL))) {
-		kfree(device->collection);
-		kfree(device);
-		return NULL;
-	}
-	memcpy(device->rdesc, start, size);
-	device->rsize = size;
-
-	if (!(parser = kzalloc(sizeof(struct hid_parser), GFP_KERNEL))) {
-		kfree(device->rdesc);
-		kfree(device->collection);
-		kfree(device);
-		return NULL;
-	}
-	parser->device = device;
-
-	end = start + size;
-	while ((start = fetch_item(start, end, &item)) != NULL) {
-
-		if (item.format != HID_ITEM_FORMAT_SHORT) {
-			dbg("unexpected long global item");
-			kfree(device->collection);
-			hid_free_device(device);
-			kfree(parser);
-			return NULL;
-		}
-
-		if (dispatch_type[item.type](parser, &item)) {
-			dbg("item %u %u %u %u parsing failed\n",
-				item.format, (unsigned)item.size, (unsigned)item.type, (unsigned)item.tag);
-			kfree(device->collection);
-			hid_free_device(device);
-			kfree(parser);
-			return NULL;
-		}
-
-		if (start == end) {
-			if (parser->collection_stack_ptr) {
-				dbg("unbalanced collection at end of report description");
-				kfree(device->collection);
-				hid_free_device(device);
-				kfree(parser);
-				return NULL;
-			}
-			if (parser->local.delimiter_depth) {
-				dbg("unbalanced delimiter at end of report description");
-				kfree(device->collection);
-				hid_free_device(device);
-				kfree(parser);
-				return NULL;
-			}
-			kfree(parser);
-			return device;
-		}
-	}
-
-	dbg("item fetching failed at offset %d\n", (int)(end - start));
-	kfree(device->collection);
-	hid_free_device(device);
-	kfree(parser);
-	return NULL;
-}
-
-/*
- * Convert a signed n-bit integer to signed 32-bit integer. Common
- * cases are done through the compiler, the screwed things has to be
- * done by hand.
- */
-
-static s32 snto32(__u32 value, unsigned n)
-{
-	switch (n) {
-		case 8:  return ((__s8)value);
-		case 16: return ((__s16)value);
-		case 32: return ((__s32)value);
-	}
-	return value & (1 << (n - 1)) ? value | (-1 << n) : value;
-}
-
-/*
- * Convert a signed 32-bit integer to a signed n-bit integer.
- */
-
-static u32 s32ton(__s32 value, unsigned n)
-{
-	s32 a = value >> (n - 1);
-	if (a && a != -1)
-		return value < 0 ? 1 << (n - 1) : (1 << (n - 1)) - 1;
-	return value & ((1 << n) - 1);
-}
-
-/*
- * Extract/implement a data field from/to a little endian report (bit array).
- *
- * Code sort-of follows HID spec:
- *     http://www.usb.org/developers/devclass_docs/HID1_11.pdf
- *
- * While the USB HID spec allows unlimited length bit fields in "report
- * descriptors", most devices never use more than 16 bits.
- * One model of UPS is claimed to report "LINEV" as a 32-bit field.
- * Search linux-kernel and linux-usb-devel archives for "hid-core extract".
- */
-
-static __inline__ __u32 extract(__u8 *report, unsigned offset, unsigned n)
-{
-	u64 x;
-
-	WARN_ON(n > 32);
-
-	report += offset >> 3;  /* adjust byte index */
-	offset &= 7;		/* now only need bit offset into one byte */
-	x = get_unaligned((u64 *) report);
-	x = le64_to_cpu(x);
-	x = (x >> offset) & ((1ULL << n) - 1);	/* extract bit field */
-	return (u32) x;
-}
-
-/*
- * "implement" : set bits in a little endian bit stream.
- * Same concepts as "extract" (see comments above).
- * The data mangled in the bit stream remains in little endian
- * order the whole time. It make more sense to talk about
- * endianness of register values by considering a register
- * a "cached" copy of the little endiad bit stream.
- */
-static __inline__ void implement(__u8 *report, unsigned offset, unsigned n, __u32 value)
-{
-	u64 x;
-	u64 m = (1ULL << n) - 1;
-
-	WARN_ON(n > 32);
-
-	WARN_ON(value > m);
-	value &= m;
-
-	report += offset >> 3;
-	offset &= 7;
-
-	x = get_unaligned((u64 *)report);
-	x &= cpu_to_le64(~(m << offset));
-	x |= cpu_to_le64(((u64) value) << offset);
-	put_unaligned(x, (u64 *) report);
-}
-
-/*
- * Search an array for a value.
- */
-
-static __inline__ int search(__s32 *array, __s32 value, unsigned n)
-{
-	while (n--) {
-		if (*array++ == value)
-			return 0;
-	}
-	return -1;
-}
-
-static void hid_process_event(struct hid_device *hid, struct hid_field *field, struct hid_usage *usage, __s32 value, int interrupt)
-{
-	hid_dump_input(usage, value);
-	if (hid->claimed & HID_CLAIMED_INPUT)
-		hidinput_hid_event(hid, field, usage, value);
-	if (hid->claimed & HID_CLAIMED_HIDDEV && interrupt)
-		hiddev_hid_event(hid, field, usage, value);
-}
-
-/*
- * Analyse a received field, and fetch the data from it. The field
- * content is stored for next report processing (we do differential
- * reporting to the layer).
- */
-
-static void hid_input_field(struct hid_device *hid, struct hid_field *field, __u8 *data, int interrupt)
-{
-	unsigned n;
-	unsigned count = field->report_count;
-	unsigned offset = field->report_offset;
-	unsigned size = field->report_size;
-	__s32 min = field->logical_minimum;
-	__s32 max = field->logical_maximum;
-	__s32 *value;
-
-	if (!(value = kmalloc(sizeof(__s32) * count, GFP_ATOMIC)))
-		return;
-
-	for (n = 0; n < count; n++) {
-
-			value[n] = min < 0 ? snto32(extract(data, offset + n * size, size), size) :
-						    extract(data, offset + n * size, size);
-
-			if (!(field->flags & HID_MAIN_ITEM_VARIABLE) /* Ignore report if ErrorRollOver */
-			    && value[n] >= min && value[n] <= max
-			    && field->usage[value[n] - min].hid == HID_UP_KEYBOARD + 1)
-				goto exit;
-	}
-
-	for (n = 0; n < count; n++) {
-
-		if (HID_MAIN_ITEM_VARIABLE & field->flags) {
-			hid_process_event(hid, field, &field->usage[n], value[n], interrupt);
-			continue;
-		}
-
-		if (field->value[n] >= min && field->value[n] <= max
-			&& field->usage[field->value[n] - min].hid
-			&& search(value, field->value[n], count))
-				hid_process_event(hid, field, &field->usage[field->value[n] - min], 0, interrupt);
-
-		if (value[n] >= min && value[n] <= max
-			&& field->usage[value[n] - min].hid
-			&& search(field->value, value[n], count))
-				hid_process_event(hid, field, &field->usage[value[n] - min], 1, interrupt);
-	}
-
-	memcpy(field->value, value, count * sizeof(__s32));
-exit:
-	kfree(value);
-}
-
-static int hid_input_report(int type, struct urb *urb, int interrupt)
-{
-	struct hid_device *hid = urb->context;
-	struct hid_report_enum *report_enum = hid->report_enum + type;
-	u8 *data = urb->transfer_buffer;
-	int len = urb->actual_length;
-	struct hid_report *report;
-	int n, size;
-
-	if (!len) {
-		dbg("empty report");
-		return -1;
-	}
-
-#ifdef DEBUG_DATA
-	printk(KERN_DEBUG __FILE__ ": report (size %u) (%snumbered)\n", len, report_enum->numbered ? "" : "un");
-#endif
-
-	n = 0;				/* Normally report number is 0 */
-	if (report_enum->numbered) {	/* Device uses numbered reports, data[0] is report number */
-		n = *data++;
-		len--;
-	}
-
-#ifdef DEBUG_DATA
-	{
-		int i;
-		printk(KERN_DEBUG __FILE__ ": report %d (size %u) = ", n, len);
-		for (i = 0; i < len; i++)
-			printk(" %02x", data[i]);
-		printk("\n");
-	}
-#endif
-
-	if (!(report = report_enum->report_id_hash[n])) {
-		dbg("undefined report_id %d received", n);
-		return -1;
-	}
-
-	size = ((report->size - 1) >> 3) + 1;
-
-	if (len < size) {
-		dbg("report %d is too short, (%d < %d)", report->id, len, size);
-		memset(data + len, 0, size - len);
-	}
-
-	if (hid->claimed & HID_CLAIMED_HIDDEV)
-		hiddev_report_event(hid, report);
-
-	for (n = 0; n < report->maxfield; n++)
-		hid_input_field(hid, report->field[n], data, interrupt);
-
-	if (hid->claimed & HID_CLAIMED_INPUT)
-		hidinput_report_event(hid, report);
-
-	return 0;
-}
+static int usbhid_pb_fnmode = 1;
+module_param_named(pb_fnmode, usbhid_pb_fnmode, int, 0644);
+MODULE_PARM_DESC(pb_fnmode,
+		"Mode of fn key on PowerBooks (0 = disabled, 1 = fkeyslast, 2 = fkeysfirst)");
 
 /*
  * Input submission and I/O error handler.
@@ -946,15 +72,16 @@ static int hid_start_in(struct hid_device *hid)
 {
 	unsigned long flags;
 	int rc = 0;
+	struct usbhid_device *usbhid = hid->driver_data;
 
-	spin_lock_irqsave(&hid->inlock, flags);
-	if (hid->open > 0 && !test_bit(HID_SUSPENDED, &hid->iofl) &&
-			!test_and_set_bit(HID_IN_RUNNING, &hid->iofl)) {
-		rc = usb_submit_urb(hid->urbin, GFP_ATOMIC);
+	spin_lock_irqsave(&usbhid->inlock, flags);
+	if (hid->open > 0 && !test_bit(HID_SUSPENDED, &usbhid->iofl) &&
+			!test_and_set_bit(HID_IN_RUNNING, &usbhid->iofl)) {
+		rc = usb_submit_urb(usbhid->urbin, GFP_ATOMIC);
 		if (rc != 0)
-			clear_bit(HID_IN_RUNNING, &hid->iofl);
+			clear_bit(HID_IN_RUNNING, &usbhid->iofl);
 	}
-	spin_unlock_irqrestore(&hid->inlock, flags);
+	spin_unlock_irqrestore(&usbhid->inlock, flags);
 	return rc;
 }
 
@@ -962,8 +89,9 @@ static int hid_start_in(struct hid_device *hid)
 static void hid_retry_timeout(unsigned long _hid)
 {
 	struct hid_device *hid = (struct hid_device *) _hid;
+	struct usbhid_device *usbhid = hid->driver_data;
 
-	dev_dbg(&hid->intf->dev, "retrying intr urb\n");
+	dev_dbg(&usbhid->intf->dev, "retrying intr urb\n");
 	if (hid_start_in(hid))
 		hid_io_error(hid);
 }
@@ -971,38 +99,39 @@ static void hid_retry_timeout(unsigned long _hid)
 /* Workqueue routine to reset the device or clear a halt */
 static void hid_reset(struct work_struct *work)
 {
-	struct hid_device *hid =
-		container_of(work, struct hid_device, reset_work);
+	struct usbhid_device *usbhid =
+		container_of(work, struct usbhid_device, reset_work);
+	struct hid_device *hid = usbhid->hid;
 	int rc_lock, rc = 0;
 
-	if (test_bit(HID_CLEAR_HALT, &hid->iofl)) {
-		dev_dbg(&hid->intf->dev, "clear halt\n");
-		rc = usb_clear_halt(hid->dev, hid->urbin->pipe);
-		clear_bit(HID_CLEAR_HALT, &hid->iofl);
+	if (test_bit(HID_CLEAR_HALT, &usbhid->iofl)) {
+		dev_dbg(&usbhid->intf->dev, "clear halt\n");
+		rc = usb_clear_halt(to_usb_device(hid->dev), usbhid->urbin->pipe);
+		clear_bit(HID_CLEAR_HALT, &usbhid->iofl);
 		hid_start_in(hid);
 	}
 
-	else if (test_bit(HID_RESET_PENDING, &hid->iofl)) {
-		dev_dbg(&hid->intf->dev, "resetting device\n");
-		rc = rc_lock = usb_lock_device_for_reset(hid->dev, hid->intf);
+	else if (test_bit(HID_RESET_PENDING, &usbhid->iofl)) {
+		dev_dbg(&usbhid->intf->dev, "resetting device\n");
+		rc = rc_lock = usb_lock_device_for_reset(to_usb_device(hid->dev), usbhid->intf);
 		if (rc_lock >= 0) {
-			rc = usb_reset_composite_device(hid->dev, hid->intf);
+			rc = usb_reset_composite_device(to_usb_device(hid->dev), usbhid->intf);
 			if (rc_lock)
-				usb_unlock_device(hid->dev);
+				usb_unlock_device(to_usb_device(hid->dev));
 		}
-		clear_bit(HID_RESET_PENDING, &hid->iofl);
+		clear_bit(HID_RESET_PENDING, &usbhid->iofl);
 	}
 
 	switch (rc) {
 	case 0:
-		if (!test_bit(HID_IN_RUNNING, &hid->iofl))
+		if (!test_bit(HID_IN_RUNNING, &usbhid->iofl))
 			hid_io_error(hid);
 		break;
 	default:
 		err("can't reset device, %s-%s/input%d, status %d",
-				hid->dev->bus->bus_name,
-				hid->dev->devpath,
-				hid->ifnum, rc);
+				to_usb_device(hid->dev)->bus->bus_name,
+				to_usb_device(hid->dev)->devpath,
+				usbhid->ifnum, rc);
 		/* FALLTHROUGH */
 	case -EHOSTUNREACH:
 	case -ENODEV:
@@ -1015,33 +144,34 @@ static void hid_reset(struct work_struct *work)
 static void hid_io_error(struct hid_device *hid)
 {
 	unsigned long flags;
+	struct usbhid_device *usbhid = hid->driver_data;
 
-	spin_lock_irqsave(&hid->inlock, flags);
+	spin_lock_irqsave(&usbhid->inlock, flags);
 
 	/* Stop when disconnected */
-	if (usb_get_intfdata(hid->intf) == NULL)
+	if (usb_get_intfdata(usbhid->intf) == NULL)
 		goto done;
 
 	/* When an error occurs, retry at increasing intervals */
-	if (hid->retry_delay == 0) {
-		hid->retry_delay = 13;	/* Then 26, 52, 104, 104, ... */
-		hid->stop_retry = jiffies + msecs_to_jiffies(1000);
-	} else if (hid->retry_delay < 100)
-		hid->retry_delay *= 2;
+	if (usbhid->retry_delay == 0) {
+		usbhid->retry_delay = 13;	/* Then 26, 52, 104, 104, ... */
+		usbhid->stop_retry = jiffies + msecs_to_jiffies(1000);
+	} else if (usbhid->retry_delay < 100)
+		usbhid->retry_delay *= 2;
 
-	if (time_after(jiffies, hid->stop_retry)) {
+	if (time_after(jiffies, usbhid->stop_retry)) {
 
 		/* Retries failed, so do a port reset */
-		if (!test_and_set_bit(HID_RESET_PENDING, &hid->iofl)) {
-			schedule_work(&hid->reset_work);
+		if (!test_and_set_bit(HID_RESET_PENDING, &usbhid->iofl)) {
+			schedule_work(&usbhid->reset_work);
 			goto done;
 		}
 	}
 
-	mod_timer(&hid->io_retry,
-			jiffies + msecs_to_jiffies(hid->retry_delay));
+	mod_timer(&usbhid->io_retry,
+			jiffies + msecs_to_jiffies(usbhid->retry_delay));
 done:
-	spin_unlock_irqrestore(&hid->inlock, flags);
+	spin_unlock_irqrestore(&usbhid->inlock, flags);
 }
 
 /*
@@ -1051,28 +181,31 @@ done:
 static void hid_irq_in(struct urb *urb)
 {
 	struct hid_device	*hid = urb->context;
+	struct usbhid_device 	*usbhid = hid->driver_data;
 	int			status;
 
 	switch (urb->status) {
 		case 0:			/* success */
-			hid->retry_delay = 0;
-			hid_input_report(HID_INPUT_REPORT, urb, 1);
+			usbhid->retry_delay = 0;
+			hid_input_report(urb->context, HID_INPUT_REPORT,
+					 urb->transfer_buffer,
+					 urb->actual_length, 1);
 			break;
 		case -EPIPE:		/* stall */
-			clear_bit(HID_IN_RUNNING, &hid->iofl);
-			set_bit(HID_CLEAR_HALT, &hid->iofl);
-			schedule_work(&hid->reset_work);
+			clear_bit(HID_IN_RUNNING, &usbhid->iofl);
+			set_bit(HID_CLEAR_HALT, &usbhid->iofl);
+			schedule_work(&usbhid->reset_work);
 			return;
 		case -ECONNRESET:	/* unlink */
 		case -ENOENT:
 		case -ESHUTDOWN:	/* unplug */
-			clear_bit(HID_IN_RUNNING, &hid->iofl);
+			clear_bit(HID_IN_RUNNING, &usbhid->iofl);
 			return;
 		case -EILSEQ:		/* protocol error or unplug */
 		case -EPROTO:		/* protocol error or unplug */
 		case -ETIME:		/* protocol error or unplug */
 		case -ETIMEDOUT:	/* Should never happen, but... */
-			clear_bit(HID_IN_RUNNING, &hid->iofl);
+			clear_bit(HID_IN_RUNNING, &usbhid->iofl);
 			hid_io_error(hid);
 			return;
 		default:		/* error */
@@ -1081,79 +214,18 @@ static void hid_irq_in(struct urb *urb)
 
 	status = usb_submit_urb(urb, GFP_ATOMIC);
 	if (status) {
-		clear_bit(HID_IN_RUNNING, &hid->iofl);
+		clear_bit(HID_IN_RUNNING, &usbhid->iofl);
 		if (status != -EPERM) {
 			err("can't resubmit intr, %s-%s/input%d, status %d",
-					hid->dev->bus->bus_name,
-					hid->dev->devpath,
-					hid->ifnum, status);
+					to_usb_device(hid->dev)->bus->bus_name,
+					to_usb_device(hid->dev)->devpath,
+					usbhid->ifnum, status);
 			hid_io_error(hid);
 		}
 	}
 }
 
 /*
- * Output the field into the report.
- */
-
-static void hid_output_field(struct hid_field *field, __u8 *data)
-{
-	unsigned count = field->report_count;
-	unsigned offset = field->report_offset;
-	unsigned size = field->report_size;
-	unsigned n;
-
-	for (n = 0; n < count; n++) {
-		if (field->logical_minimum < 0)	/* signed values */
-			implement(data, offset + n * size, size, s32ton(field->value[n], size));
-		else				/* unsigned values */
-			implement(data, offset + n * size, size, field->value[n]);
-	}
-}
-
-/*
- * Create a report.
- */
-
-static void hid_output_report(struct hid_report *report, __u8 *data)
-{
-	unsigned n;
-
-	if (report->id > 0)
-		*data++ = report->id;
-
-	for (n = 0; n < report->maxfield; n++)
-		hid_output_field(report->field[n], data);
-}
-
-/*
- * Set a field value. The report this field belongs to has to be
- * created and transferred to the device, to set this value in the
- * device.
- */
-
-int hid_set_field(struct hid_field *field, unsigned offset, __s32 value)
-{
-	unsigned size = field->report_size;
-
-	hid_dump_input(field->usage + offset, value);
-
-	if (offset >= field->report_count) {
-		dbg("offset (%d) exceeds report_count (%d)", offset, field->report_count);
-		hid_dump_field(field, 8);
-		return -1;
-	}
-	if (field->logical_minimum < 0) {
-		if (value != snto32(s32ton(value, size), size)) {
-			dbg("value %d is out of range", value);
-			return -1;
-		}
-	}
-	field->value[offset] = value;
-	return 0;
-}
-
-/*
  * Find a report field with a specified HID usage.
  */
 #if 0
@@ -1173,16 +245,17 @@ struct hid_field *hid_find_field_by_usage(struct hid_device *hid, __u32 wanted_u
 static int hid_submit_out(struct hid_device *hid)
 {
 	struct hid_report *report;
+	struct usbhid_device *usbhid = hid->driver_data;
 
-	report = hid->out[hid->outtail];
+	report = usbhid->out[usbhid->outtail];
 
-	hid_output_report(report, hid->outbuf);
-	hid->urbout->transfer_buffer_length = ((report->size - 1) >> 3) + 1 + (report->id > 0);
-	hid->urbout->dev = hid->dev;
+	hid_output_report(report, usbhid->outbuf);
+	usbhid->urbout->transfer_buffer_length = ((report->size - 1) >> 3) + 1 + (report->id > 0);
+	usbhid->urbout->dev = to_usb_device(hid->dev);
 
 	dbg("submitting out urb");
 
-	if (usb_submit_urb(hid->urbout, GFP_ATOMIC)) {
+	if (usb_submit_urb(usbhid->urbout, GFP_ATOMIC)) {
 		err("usb_submit_urb(out) failed");
 		return -1;
 	}
@@ -1195,42 +268,43 @@ static int hid_submit_ctrl(struct hid_device *hid)
 	struct hid_report *report;
 	unsigned char dir;
 	int len;
+	struct usbhid_device *usbhid = hid->driver_data;
 
-	report = hid->ctrl[hid->ctrltail].report;
-	dir = hid->ctrl[hid->ctrltail].dir;
+	report = usbhid->ctrl[usbhid->ctrltail].report;
+	dir = usbhid->ctrl[usbhid->ctrltail].dir;
 
 	len = ((report->size - 1) >> 3) + 1 + (report->id > 0);
 	if (dir == USB_DIR_OUT) {
-		hid_output_report(report, hid->ctrlbuf);
-		hid->urbctrl->pipe = usb_sndctrlpipe(hid->dev, 0);
-		hid->urbctrl->transfer_buffer_length = len;
+		hid_output_report(report, usbhid->ctrlbuf);
+		usbhid->urbctrl->pipe = usb_sndctrlpipe(to_usb_device(hid->dev), 0);
+		usbhid->urbctrl->transfer_buffer_length = len;
 	} else {
 		int maxpacket, padlen;
 
-		hid->urbctrl->pipe = usb_rcvctrlpipe(hid->dev, 0);
-		maxpacket = usb_maxpacket(hid->dev, hid->urbctrl->pipe, 0);
+		usbhid->urbctrl->pipe = usb_rcvctrlpipe(to_usb_device(hid->dev), 0);
+		maxpacket = usb_maxpacket(to_usb_device(hid->dev), usbhid->urbctrl->pipe, 0);
 		if (maxpacket > 0) {
 			padlen = (len + maxpacket - 1) / maxpacket;
 			padlen *= maxpacket;
-			if (padlen > hid->bufsize)
-				padlen = hid->bufsize;
+			if (padlen > usbhid->bufsize)
+				padlen = usbhid->bufsize;
 		} else
 			padlen = 0;
-		hid->urbctrl->transfer_buffer_length = padlen;
+		usbhid->urbctrl->transfer_buffer_length = padlen;
 	}
-	hid->urbctrl->dev = hid->dev;
+	usbhid->urbctrl->dev = to_usb_device(hid->dev);
 
-	hid->cr->bRequestType = USB_TYPE_CLASS | USB_RECIP_INTERFACE | dir;
-	hid->cr->bRequest = (dir == USB_DIR_OUT) ? HID_REQ_SET_REPORT : HID_REQ_GET_REPORT;
-	hid->cr->wValue = cpu_to_le16(((report->type + 1) << 8) | report->id);
-	hid->cr->wIndex = cpu_to_le16(hid->ifnum);
-	hid->cr->wLength = cpu_to_le16(len);
+	usbhid->cr->bRequestType = USB_TYPE_CLASS | USB_RECIP_INTERFACE | dir;
+	usbhid->cr->bRequest = (dir == USB_DIR_OUT) ? HID_REQ_SET_REPORT : HID_REQ_GET_REPORT;
+	usbhid->cr->wValue = cpu_to_le16(((report->type + 1) << 8) | report->id);
+	usbhid->cr->wIndex = cpu_to_le16(usbhid->ifnum);
+	usbhid->cr->wLength = cpu_to_le16(len);
 
 	dbg("submitting ctrl urb: %s wValue=0x%04x wIndex=0x%04x wLength=%u",
-		hid->cr->bRequest == HID_REQ_SET_REPORT ? "Set_Report" : "Get_Report",
-		hid->cr->wValue, hid->cr->wIndex, hid->cr->wLength);
+		usbhid->cr->bRequest == HID_REQ_SET_REPORT ? "Set_Report" : "Get_Report",
+		usbhid->cr->wValue, usbhid->cr->wIndex, usbhid->cr->wLength);
 
-	if (usb_submit_urb(hid->urbctrl, GFP_ATOMIC)) {
+	if (usb_submit_urb(usbhid->urbctrl, GFP_ATOMIC)) {
 		err("usb_submit_urb(ctrl) failed");
 		return -1;
 	}
@@ -1245,6 +319,7 @@ static int hid_submit_ctrl(struct hid_device *hid)
 static void hid_irq_out(struct urb *urb)
 {
 	struct hid_device *hid = urb->context;
+	struct usbhid_device *usbhid = hid->driver_data;
 	unsigned long flags;
 	int unplug = 0;
 
@@ -1262,24 +337,24 @@ static void hid_irq_out(struct urb *urb)
 			warn("output irq status %d received", urb->status);
 	}
 
-	spin_lock_irqsave(&hid->outlock, flags);
+	spin_lock_irqsave(&usbhid->outlock, flags);
 
 	if (unplug)
-		hid->outtail = hid->outhead;
+		usbhid->outtail = usbhid->outhead;
 	else
-		hid->outtail = (hid->outtail + 1) & (HID_OUTPUT_FIFO_SIZE - 1);
+		usbhid->outtail = (usbhid->outtail + 1) & (HID_OUTPUT_FIFO_SIZE - 1);
 
-	if (hid->outhead != hid->outtail) {
+	if (usbhid->outhead != usbhid->outtail) {
 		if (hid_submit_out(hid)) {
-			clear_bit(HID_OUT_RUNNING, &hid->iofl);
+			clear_bit(HID_OUT_RUNNING, &usbhid->iofl);
 			wake_up(&hid->wait);
 		}
-		spin_unlock_irqrestore(&hid->outlock, flags);
+		spin_unlock_irqrestore(&usbhid->outlock, flags);
 		return;
 	}
 
-	clear_bit(HID_OUT_RUNNING, &hid->iofl);
-	spin_unlock_irqrestore(&hid->outlock, flags);
+	clear_bit(HID_OUT_RUNNING, &usbhid->iofl);
+	spin_unlock_irqrestore(&usbhid->outlock, flags);
 	wake_up(&hid->wait);
 }
 
@@ -1290,15 +365,17 @@ static void hid_irq_out(struct urb *urb)
 static void hid_ctrl(struct urb *urb)
 {
 	struct hid_device *hid = urb->context;
+	struct usbhid_device *usbhid = hid->driver_data;
 	unsigned long flags;
 	int unplug = 0;
 
-	spin_lock_irqsave(&hid->ctrllock, flags);
+	spin_lock_irqsave(&usbhid->ctrllock, flags);
 
 	switch (urb->status) {
 		case 0:			/* success */
-			if (hid->ctrl[hid->ctrltail].dir == USB_DIR_IN)
-				hid_input_report(hid->ctrl[hid->ctrltail].report->type, urb, 0);
+			if (usbhid->ctrl[usbhid->ctrltail].dir == USB_DIR_IN)
+				hid_input_report(urb->context, usbhid->ctrl[usbhid->ctrltail].report->type,
+						urb->transfer_buffer, urb->actual_length, 0);
 			break;
 		case -ESHUTDOWN:	/* unplug */
 			unplug = 1;
@@ -1313,76 +390,102 @@ static void hid_ctrl(struct urb *urb)
 	}
 
 	if (unplug)
-		hid->ctrltail = hid->ctrlhead;
+		usbhid->ctrltail = usbhid->ctrlhead;
 	else
-		hid->ctrltail = (hid->ctrltail + 1) & (HID_CONTROL_FIFO_SIZE - 1);
+		usbhid->ctrltail = (usbhid->ctrltail + 1) & (HID_CONTROL_FIFO_SIZE - 1);
 
-	if (hid->ctrlhead != hid->ctrltail) {
+	if (usbhid->ctrlhead != usbhid->ctrltail) {
 		if (hid_submit_ctrl(hid)) {
-			clear_bit(HID_CTRL_RUNNING, &hid->iofl);
+			clear_bit(HID_CTRL_RUNNING, &usbhid->iofl);
 			wake_up(&hid->wait);
 		}
-		spin_unlock_irqrestore(&hid->ctrllock, flags);
+		spin_unlock_irqrestore(&usbhid->ctrllock, flags);
 		return;
 	}
 
-	clear_bit(HID_CTRL_RUNNING, &hid->iofl);
-	spin_unlock_irqrestore(&hid->ctrllock, flags);
+	clear_bit(HID_CTRL_RUNNING, &usbhid->iofl);
+	spin_unlock_irqrestore(&usbhid->ctrllock, flags);
 	wake_up(&hid->wait);
 }
 
-void hid_submit_report(struct hid_device *hid, struct hid_report *report, unsigned char dir)
+void usbhid_submit_report(struct hid_device *hid, struct hid_report *report, unsigned char dir)
 {
 	int head;
 	unsigned long flags;
+	struct usbhid_device *usbhid = hid->driver_data;
 
 	if ((hid->quirks & HID_QUIRK_NOGET) && dir == USB_DIR_IN)
 		return;
 
-	if (hid->urbout && dir == USB_DIR_OUT && report->type == HID_OUTPUT_REPORT) {
+	if (usbhid->urbout && dir == USB_DIR_OUT && report->type == HID_OUTPUT_REPORT) {
 
-		spin_lock_irqsave(&hid->outlock, flags);
+		spin_lock_irqsave(&usbhid->outlock, flags);
 
-		if ((head = (hid->outhead + 1) & (HID_OUTPUT_FIFO_SIZE - 1)) == hid->outtail) {
-			spin_unlock_irqrestore(&hid->outlock, flags);
+		if ((head = (usbhid->outhead + 1) & (HID_OUTPUT_FIFO_SIZE - 1)) == usbhid->outtail) {
+			spin_unlock_irqrestore(&usbhid->outlock, flags);
 			warn("output queue full");
 			return;
 		}
 
-		hid->out[hid->outhead] = report;
-		hid->outhead = head;
+		usbhid->out[usbhid->outhead] = report;
+		usbhid->outhead = head;
 
-		if (!test_and_set_bit(HID_OUT_RUNNING, &hid->iofl))
+		if (!test_and_set_bit(HID_OUT_RUNNING, &usbhid->iofl))
 			if (hid_submit_out(hid))
-				clear_bit(HID_OUT_RUNNING, &hid->iofl);
+				clear_bit(HID_OUT_RUNNING, &usbhid->iofl);
 
-		spin_unlock_irqrestore(&hid->outlock, flags);
+		spin_unlock_irqrestore(&usbhid->outlock, flags);
 		return;
 	}
 
-	spin_lock_irqsave(&hid->ctrllock, flags);
+	spin_lock_irqsave(&usbhid->ctrllock, flags);
 
-	if ((head = (hid->ctrlhead + 1) & (HID_CONTROL_FIFO_SIZE - 1)) == hid->ctrltail) {
-		spin_unlock_irqrestore(&hid->ctrllock, flags);
+	if ((head = (usbhid->ctrlhead + 1) & (HID_CONTROL_FIFO_SIZE - 1)) == usbhid->ctrltail) {
+		spin_unlock_irqrestore(&usbhid->ctrllock, flags);
 		warn("control queue full");
 		return;
 	}
 
-	hid->ctrl[hid->ctrlhead].report = report;
-	hid->ctrl[hid->ctrlhead].dir = dir;
-	hid->ctrlhead = head;
+	usbhid->ctrl[usbhid->ctrlhead].report = report;
+	usbhid->ctrl[usbhid->ctrlhead].dir = dir;
+	usbhid->ctrlhead = head;
 
-	if (!test_and_set_bit(HID_CTRL_RUNNING, &hid->iofl))
+	if (!test_and_set_bit(HID_CTRL_RUNNING, &usbhid->iofl))
 		if (hid_submit_ctrl(hid))
-			clear_bit(HID_CTRL_RUNNING, &hid->iofl);
+			clear_bit(HID_CTRL_RUNNING, &usbhid->iofl);
 
-	spin_unlock_irqrestore(&hid->ctrllock, flags);
+	spin_unlock_irqrestore(&usbhid->ctrllock, flags);
 }
 
-int hid_wait_io(struct hid_device *hid)
+static int usb_hidinput_input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
 {
-	if (!wait_event_timeout(hid->wait, (!test_bit(HID_CTRL_RUNNING, &hid->iofl) &&
-					!test_bit(HID_OUT_RUNNING, &hid->iofl)),
+	struct hid_device *hid = dev->private;
+	struct hid_field *field;
+	int offset;
+
+	if (type == EV_FF)
+		return input_ff_event(dev, type, code, value);
+
+	if (type != EV_LED)
+		return -1;
+
+	if ((offset = hidinput_find_field(hid, type, code, &field)) == -1) {
+		warn("event field not found");
+		return -1;
+	}
+
+	hid_set_field(field, offset, value);
+	usbhid_submit_report(hid, field->report, USB_DIR_OUT);
+
+	return 0;
+}
+
+int usbhid_wait_io(struct hid_device *hid)
+{
+	struct usbhid_device *usbhid = hid->driver_data;
+
+	if (!wait_event_timeout(hid->wait, (!test_bit(HID_CTRL_RUNNING, &usbhid->iofl) &&
+					!test_bit(HID_OUT_RUNNING, &usbhid->iofl)),
 					10*HZ)) {
 		dbg("timeout waiting for ctrl or out queue to clear");
 		return -1;
@@ -1414,7 +517,7 @@ static int hid_get_class_descriptor(struct usb_device *dev, int ifnum,
 	return result;
 }
 
-int hid_open(struct hid_device *hid)
+int usbhid_open(struct hid_device *hid)
 {
 	++hid->open;
 	if (hid_start_in(hid))
@@ -1422,10 +525,24 @@ int hid_open(struct hid_device *hid)
 	return 0;
 }
 
-void hid_close(struct hid_device *hid)
+void usbhid_close(struct hid_device *hid)
 {
+	struct usbhid_device *usbhid = hid->driver_data;
+
 	if (!--hid->open)
-		usb_kill_urb(hid->urbin);
+		usb_kill_urb(usbhid->urbin);
+}
+
+static int hidinput_open(struct input_dev *dev)
+{
+	struct hid_device *hid = dev->private;
+	return usbhid_open(hid);
+}
+
+static void hidinput_close(struct input_dev *dev)
+{
+	struct hid_device *hid = dev->private;
+	usbhid_close(hid);
 }
 
 #define USB_VENDOR_ID_PANJIT		0x134c
@@ -1437,26 +554,27 @@ void hid_close(struct hid_device *hid)
  * Initialize all reports
  */
 
-void hid_init_reports(struct hid_device *hid)
+void usbhid_init_reports(struct hid_device *hid)
 {
 	struct hid_report *report;
+	struct usbhid_device *usbhid = hid->driver_data;
 	int err, ret;
 
 	list_for_each_entry(report, &hid->report_enum[HID_INPUT_REPORT].report_list, list)
-		hid_submit_report(hid, report, USB_DIR_IN);
+		usbhid_submit_report(hid, report, USB_DIR_IN);
 
 	list_for_each_entry(report, &hid->report_enum[HID_FEATURE_REPORT].report_list, list)
-		hid_submit_report(hid, report, USB_DIR_IN);
+		usbhid_submit_report(hid, report, USB_DIR_IN);
 
 	err = 0;
-	ret = hid_wait_io(hid);
+	ret = usbhid_wait_io(hid);
 	while (ret) {
 		err |= ret;
-		if (test_bit(HID_CTRL_RUNNING, &hid->iofl))
-			usb_kill_urb(hid->urbctrl);
-		if (test_bit(HID_OUT_RUNNING, &hid->iofl))
-			usb_kill_urb(hid->urbout);
-		ret = hid_wait_io(hid);
+		if (test_bit(HID_CTRL_RUNNING, &usbhid->iofl))
+			usb_kill_urb(usbhid->urbctrl);
+		if (test_bit(HID_OUT_RUNNING, &usbhid->iofl))
+			usb_kill_urb(usbhid->urbout);
+		ret = usbhid_wait_io(hid);
 	}
 
 	if (err)
@@ -1869,13 +987,15 @@ static void hid_find_max_report(struct hid_device *hid, unsigned int type, int *
 
 static int hid_alloc_buffers(struct usb_device *dev, struct hid_device *hid)
 {
-	if (!(hid->inbuf = usb_buffer_alloc(dev, hid->bufsize, GFP_ATOMIC, &hid->inbuf_dma)))
+	struct usbhid_device *usbhid = hid->driver_data;
+
+	if (!(usbhid->inbuf = usb_buffer_alloc(dev, usbhid->bufsize, GFP_ATOMIC, &usbhid->inbuf_dma)))
 		return -1;
-	if (!(hid->outbuf = usb_buffer_alloc(dev, hid->bufsize, GFP_ATOMIC, &hid->outbuf_dma)))
+	if (!(usbhid->outbuf = usb_buffer_alloc(dev, usbhid->bufsize, GFP_ATOMIC, &usbhid->outbuf_dma)))
 		return -1;
-	if (!(hid->cr = usb_buffer_alloc(dev, sizeof(*(hid->cr)), GFP_ATOMIC, &hid->cr_dma)))
+	if (!(usbhid->cr = usb_buffer_alloc(dev, sizeof(*(usbhid->cr)), GFP_ATOMIC, &usbhid->cr_dma)))
 		return -1;
-	if (!(hid->ctrlbuf = usb_buffer_alloc(dev, hid->bufsize, GFP_ATOMIC, &hid->ctrlbuf_dma)))
+	if (!(usbhid->ctrlbuf = usb_buffer_alloc(dev, usbhid->bufsize, GFP_ATOMIC, &usbhid->ctrlbuf_dma)))
 		return -1;
 
 	return 0;
@@ -1883,14 +1003,16 @@ static int hid_alloc_buffers(struct usb_device *dev, struct hid_device *hid)
 
 static void hid_free_buffers(struct usb_device *dev, struct hid_device *hid)
 {
-	if (hid->inbuf)
-		usb_buffer_free(dev, hid->bufsize, hid->inbuf, hid->inbuf_dma);
-	if (hid->outbuf)
-		usb_buffer_free(dev, hid->bufsize, hid->outbuf, hid->outbuf_dma);
-	if (hid->cr)
-		usb_buffer_free(dev, sizeof(*(hid->cr)), hid->cr, hid->cr_dma);
-	if (hid->ctrlbuf)
-		usb_buffer_free(dev, hid->bufsize, hid->ctrlbuf, hid->ctrlbuf_dma);
+	struct usbhid_device *usbhid = hid->driver_data;
+
+	if (usbhid->inbuf)
+		usb_buffer_free(dev, usbhid->bufsize, usbhid->inbuf, usbhid->inbuf_dma);
+	if (usbhid->outbuf)
+		usb_buffer_free(dev, usbhid->bufsize, usbhid->outbuf, usbhid->outbuf_dma);
+	if (usbhid->cr)
+		usb_buffer_free(dev, sizeof(*(usbhid->cr)), usbhid->cr, usbhid->cr_dma);
+	if (usbhid->ctrlbuf)
+		usb_buffer_free(dev, usbhid->bufsize, usbhid->ctrlbuf, usbhid->ctrlbuf_dma);
 }
 
 /*
@@ -1916,6 +1038,7 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf)
 	unsigned quirks = 0, rsize = 0;
 	char *rdesc;
 	int n, len, insize = 0;
+	struct usbhid_device *usbhid;
 
         /* Ignore all Wacom devices */
         if (le16_to_cpu(dev->descriptor.idVendor) == USB_VENDOR_ID_WACOM)
@@ -1985,13 +1108,19 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf)
 	kfree(rdesc);
 	hid->quirks = quirks;
 
-	hid->bufsize = HID_MIN_BUFFER_SIZE;
-	hid_find_max_report(hid, HID_INPUT_REPORT, &hid->bufsize);
-	hid_find_max_report(hid, HID_OUTPUT_REPORT, &hid->bufsize);
-	hid_find_max_report(hid, HID_FEATURE_REPORT, &hid->bufsize);
+	if (!(usbhid = kzalloc(sizeof(struct usbhid_device), GFP_KERNEL)))
+		goto fail;
+
+	hid->driver_data = usbhid;
+	usbhid->hid = hid;
+
+	usbhid->bufsize = HID_MIN_BUFFER_SIZE;
+	hid_find_max_report(hid, HID_INPUT_REPORT, &usbhid->bufsize);
+	hid_find_max_report(hid, HID_OUTPUT_REPORT, &usbhid->bufsize);
+	hid_find_max_report(hid, HID_FEATURE_REPORT, &usbhid->bufsize);
 
-	if (hid->bufsize > HID_MAX_BUFFER_SIZE)
-		hid->bufsize = HID_MAX_BUFFER_SIZE;
+	if (usbhid->bufsize > HID_MAX_BUFFER_SIZE)
+		usbhid->bufsize = HID_MAX_BUFFER_SIZE;
 
 	hid_find_max_report(hid, HID_INPUT_REPORT, &insize);
 
@@ -2020,47 +1149,47 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf)
 			interval = hid_mousepoll_interval;
 
 		if (usb_endpoint_dir_in(endpoint)) {
-			if (hid->urbin)
+			if (usbhid->urbin)
 				continue;
-			if (!(hid->urbin = usb_alloc_urb(0, GFP_KERNEL)))
+			if (!(usbhid->urbin = usb_alloc_urb(0, GFP_KERNEL)))
 				goto fail;
 			pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);
-			usb_fill_int_urb(hid->urbin, dev, pipe, hid->inbuf, insize,
+			usb_fill_int_urb(usbhid->urbin, dev, pipe, usbhid->inbuf, insize,
 					 hid_irq_in, hid, interval);
-			hid->urbin->transfer_dma = hid->inbuf_dma;
-			hid->urbin->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+			usbhid->urbin->transfer_dma = usbhid->inbuf_dma;
+			usbhid->urbin->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
 		} else {
-			if (hid->urbout)
+			if (usbhid->urbout)
 				continue;
-			if (!(hid->urbout = usb_alloc_urb(0, GFP_KERNEL)))
+			if (!(usbhid->urbout = usb_alloc_urb(0, GFP_KERNEL)))
 				goto fail;
 			pipe = usb_sndintpipe(dev, endpoint->bEndpointAddress);
-			usb_fill_int_urb(hid->urbout, dev, pipe, hid->outbuf, 0,
+			usb_fill_int_urb(usbhid->urbout, dev, pipe, usbhid->outbuf, 0,
 					 hid_irq_out, hid, interval);
-			hid->urbout->transfer_dma = hid->outbuf_dma;
-			hid->urbout->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+			usbhid->urbout->transfer_dma = usbhid->outbuf_dma;
+			usbhid->urbout->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
 		}
 	}
 
-	if (!hid->urbin) {
+	if (!usbhid->urbin) {
 		err("couldn't find an input interrupt endpoint");
 		goto fail;
 	}
 
 	init_waitqueue_head(&hid->wait);
 
-	INIT_WORK(&hid->reset_work, hid_reset);
-	setup_timer(&hid->io_retry, hid_retry_timeout, (unsigned long) hid);
+	INIT_WORK(&usbhid->reset_work, hid_reset);
+	setup_timer(&usbhid->io_retry, hid_retry_timeout, (unsigned long) hid);
 
-	spin_lock_init(&hid->inlock);
-	spin_lock_init(&hid->outlock);
-	spin_lock_init(&hid->ctrllock);
+	spin_lock_init(&usbhid->inlock);
+	spin_lock_init(&usbhid->outlock);
+	spin_lock_init(&usbhid->ctrllock);
 
 	hid->version = le16_to_cpu(hdesc->bcdHID);
 	hid->country = hdesc->bCountryCode;
-	hid->dev = dev;
-	hid->intf = intf;
-	hid->ifnum = interface->desc.bInterfaceNumber;
+	hid->dev = &dev->dev;
+	usbhid->intf = intf;
+	usbhid->ifnum = interface->desc.bInterfaceNumber;
 
 	hid->name[0] = 0;
 
@@ -2078,6 +1207,10 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf)
 			 le16_to_cpu(dev->descriptor.idVendor),
 			 le16_to_cpu(dev->descriptor.idProduct));
 
+	hid->bus = BUS_USB;
+	hid->vendor = dev->descriptor.idVendor;
+	hid->product = dev->descriptor.idProduct;
+
 	usb_make_path(dev, hid->phys, sizeof(hid->phys));
 	strlcat(hid->phys, "/input", sizeof(hid->phys));
 	len = strlen(hid->phys);
@@ -2088,22 +1221,32 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf)
 	if (usb_string(dev, dev->descriptor.iSerialNumber, hid->uniq, 64) <= 0)
 		hid->uniq[0] = 0;
 
-	hid->urbctrl = usb_alloc_urb(0, GFP_KERNEL);
-	if (!hid->urbctrl)
+	usbhid->urbctrl = usb_alloc_urb(0, GFP_KERNEL);
+	if (!usbhid->urbctrl)
 		goto fail;
 
-	usb_fill_control_urb(hid->urbctrl, dev, 0, (void *) hid->cr,
-			     hid->ctrlbuf, 1, hid_ctrl, hid);
-	hid->urbctrl->setup_dma = hid->cr_dma;
-	hid->urbctrl->transfer_dma = hid->ctrlbuf_dma;
-	hid->urbctrl->transfer_flags |= (URB_NO_TRANSFER_DMA_MAP | URB_NO_SETUP_DMA_MAP);
+	usb_fill_control_urb(usbhid->urbctrl, dev, 0, (void *) usbhid->cr,
+			     usbhid->ctrlbuf, 1, hid_ctrl, hid);
+	usbhid->urbctrl->setup_dma = usbhid->cr_dma;
+	usbhid->urbctrl->transfer_dma = usbhid->ctrlbuf_dma;
+	usbhid->urbctrl->transfer_flags |= (URB_NO_TRANSFER_DMA_MAP | URB_NO_SETUP_DMA_MAP);
+	hid->hidinput_input_event = usb_hidinput_input_event;
+	hid->hidinput_open = hidinput_open;
+	hid->hidinput_close = hidinput_close;
+#ifdef CONFIG_USB_HIDDEV
+	hid->hiddev_hid_event = hiddev_hid_event;
+	hid->hiddev_report_event = hiddev_report_event;
+#endif
+#ifdef CONFIG_USB_HIDINPUT_POWERBOOK
+	hid->pb_fnmode = usbhid_pb_fnmode;
+#endif
 
 	return hid;
 
 fail:
-	usb_free_urb(hid->urbin);
-	usb_free_urb(hid->urbout);
-	usb_free_urb(hid->urbctrl);
+	usb_free_urb(usbhid->urbin);
+	usb_free_urb(usbhid->urbout);
+	usb_free_urb(usbhid->urbctrl);
 	hid_free_buffers(dev, hid);
 	hid_free_device(hid);
 
@@ -2113,18 +1256,21 @@ fail:
 static void hid_disconnect(struct usb_interface *intf)
 {
 	struct hid_device *hid = usb_get_intfdata (intf);
+	struct usbhid_device *usbhid;
 
 	if (!hid)
 		return;
 
-	spin_lock_irq(&hid->inlock);	/* Sync with error handler */
+	usbhid = hid->driver_data;
+
+	spin_lock_irq(&usbhid->inlock);	/* Sync with error handler */
 	usb_set_intfdata(intf, NULL);
-	spin_unlock_irq(&hid->inlock);
-	usb_kill_urb(hid->urbin);
-	usb_kill_urb(hid->urbout);
-	usb_kill_urb(hid->urbctrl);
+	spin_unlock_irq(&usbhid->inlock);
+	usb_kill_urb(usbhid->urbin);
+	usb_kill_urb(usbhid->urbout);
+	usb_kill_urb(usbhid->urbctrl);
 
-	del_timer_sync(&hid->io_retry);
+	del_timer_sync(&usbhid->io_retry);
 	flush_scheduled_work();
 
 	if (hid->claimed & HID_CLAIMED_INPUT)
@@ -2132,11 +1278,11 @@ static void hid_disconnect(struct usb_interface *intf)
 	if (hid->claimed & HID_CLAIMED_HIDDEV)
 		hiddev_disconnect(hid);
 
-	usb_free_urb(hid->urbin);
-	usb_free_urb(hid->urbctrl);
-	usb_free_urb(hid->urbout);
+	usb_free_urb(usbhid->urbin);
+	usb_free_urb(usbhid->urbctrl);
+	usb_free_urb(usbhid->urbout);
 
-	hid_free_buffers(hid->dev, hid);
+	hid_free_buffers(to_usb_device(hid->dev), hid);
 	hid_free_device(hid);
 }
 
@@ -2153,7 +1299,7 @@ static int hid_probe(struct usb_interface *intf, const struct usb_device_id *id)
 	if (!(hid = usb_hid_configure(intf)))
 		return -ENODEV;
 
-	hid_init_reports(hid);
+	usbhid_init_reports(hid);
 	hid_dump_device(hid);
 
 	if (!hidinput_connect(hid))
@@ -2169,6 +1315,13 @@ static int hid_probe(struct usb_interface *intf, const struct usb_device_id *id)
 		return -ENODEV;
 	}
 
+	/* This only gets called when we are a single-input (most of the
+	 * time). IOW, not a HID_QUIRK_MULTI_INPUT. The hid_ff_init() is
+	 * only useful in this case, and not for multi-input quirks. */
+	if ((hid->claimed & HID_CLAIMED_INPUT) &&
+			!(hid->quirks & HID_QUIRK_MULTI_INPUT))
+		hid_ff_init(hid);
+
 	printk(KERN_INFO);
 
 	if (hid->claimed & HID_CLAIMED_INPUT)
@@ -2199,12 +1352,13 @@ static int hid_probe(struct usb_interface *intf, const struct usb_device_id *id)
 static int hid_suspend(struct usb_interface *intf, pm_message_t message)
 {
 	struct hid_device *hid = usb_get_intfdata (intf);
+	struct usbhid_device *usbhid = hid->driver_data;
 
-	spin_lock_irq(&hid->inlock);	/* Sync with error handler */
-	set_bit(HID_SUSPENDED, &hid->iofl);
-	spin_unlock_irq(&hid->inlock);
-	del_timer(&hid->io_retry);
-	usb_kill_urb(hid->urbin);
+	spin_lock_irq(&usbhid->inlock);	/* Sync with error handler */
+	set_bit(HID_SUSPENDED, &usbhid->iofl);
+	spin_unlock_irq(&usbhid->inlock);
+	del_timer(&usbhid->io_retry);
+	usb_kill_urb(usbhid->urbin);
 	dev_dbg(&intf->dev, "suspend\n");
 	return 0;
 }
@@ -2212,10 +1366,11 @@ static int hid_suspend(struct usb_interface *intf, pm_message_t message)
 static int hid_resume(struct usb_interface *intf)
 {
 	struct hid_device *hid = usb_get_intfdata (intf);
+	struct usbhid_device *usbhid = hid->driver_data;
 	int status;
 
-	clear_bit(HID_SUSPENDED, &hid->iofl);
-	hid->retry_delay = 0;
+	clear_bit(HID_SUSPENDED, &usbhid->iofl);
+	usbhid->retry_delay = 0;
 	status = hid_start_in(hid);
 	dev_dbg(&intf->dev, "resume status %d\n", status);
 	return status;
diff --git a/drivers/usb/input/hid-debug.h b/drivers/usb/input/hid-debug.h
deleted file mode 100644
index f04d6d75c098..000000000000
--- a/drivers/usb/input/hid-debug.h
+++ /dev/null
@@ -1,757 +0,0 @@
-/*
- * $Id: hid-debug.h,v 1.8 2001/09/25 09:37:57 vojtech Exp $
- *
- *  (c) 1999 Andreas Gal		<gal@cs.uni-magdeburg.de>
- *  (c) 2000-2001 Vojtech Pavlik	<vojtech@ucw.cz>
- *
- *  Some debug stuff for the HID parser.
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Should you need to contact me, the author, you can do so either by
- * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
- * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
- */
-
-#include <linux/input.h>
-
-struct hid_usage_entry {
-	unsigned  page;
-	unsigned  usage;
-	char     *description;
-};
-
-static const struct hid_usage_entry hid_usage_table[] = {
-  {  0,      0, "Undefined" },
-  {  1,      0, "GenericDesktop" },
-    {0, 0x01, "Pointer"},
-    {0, 0x02, "Mouse"},
-    {0, 0x04, "Joystick"},
-    {0, 0x05, "GamePad"},
-    {0, 0x06, "Keyboard"},
-    {0, 0x07, "Keypad"},
-    {0, 0x08, "MultiAxis"},
-      {0, 0x30, "X"},
-      {0, 0x31, "Y"},
-      {0, 0x32, "Z"},
-      {0, 0x33, "Rx"},
-      {0, 0x34, "Ry"},
-      {0, 0x35, "Rz"},
-      {0, 0x36, "Slider"},
-      {0, 0x37, "Dial"},
-      {0, 0x38, "Wheel"},
-      {0, 0x39, "HatSwitch"},
-    {0, 0x3a, "CountedBuffer"},
-      {0, 0x3b, "ByteCount"},
-      {0, 0x3c, "MotionWakeup"},
-      {0, 0x3d, "Start"},
-      {0, 0x3e, "Select"},
-      {0, 0x40, "Vx"},
-      {0, 0x41, "Vy"},
-      {0, 0x42, "Vz"},
-      {0, 0x43, "Vbrx"},
-      {0, 0x44, "Vbry"},
-      {0, 0x45, "Vbrz"},
-      {0, 0x46, "Vno"},
-    {0, 0x80, "SystemControl"},
-      {0, 0x81, "SystemPowerDown"},
-      {0, 0x82, "SystemSleep"},
-      {0, 0x83, "SystemWakeUp"},
-      {0, 0x84, "SystemContextMenu"},
-      {0, 0x85, "SystemMainMenu"},
-      {0, 0x86, "SystemAppMenu"},
-      {0, 0x87, "SystemMenuHelp"},
-      {0, 0x88, "SystemMenuExit"},
-      {0, 0x89, "SystemMenuSelect"},
-      {0, 0x8a, "SystemMenuRight"},
-      {0, 0x8b, "SystemMenuLeft"},
-      {0, 0x8c, "SystemMenuUp"},
-      {0, 0x8d, "SystemMenuDown"},
-      {0, 0x90, "D-PadUp"},
-      {0, 0x91, "D-PadDown"},
-      {0, 0x92, "D-PadRight"},
-      {0, 0x93, "D-PadLeft"},
-  {  2, 0, "Simulation" },
-      {0, 0xb0, "Aileron"},
-      {0, 0xb1, "AileronTrim"},
-      {0, 0xb2, "Anti-Torque"},
-      {0, 0xb3, "Autopilot"},
-      {0, 0xb4, "Chaff"},
-      {0, 0xb5, "Collective"},
-      {0, 0xb6, "DiveBrake"},
-      {0, 0xb7, "ElectronicCountermeasures"},
-      {0, 0xb8, "Elevator"},
-      {0, 0xb9, "ElevatorTrim"},
-      {0, 0xba, "Rudder"},
-      {0, 0xbb, "Throttle"},
-      {0, 0xbc, "FlightCommunications"},
-      {0, 0xbd, "FlareRelease"},
-      {0, 0xbe, "LandingGear"},
-      {0, 0xbf, "ToeBrake"},
-  {  7, 0, "Keyboard" },
-  {  8, 0, "LED" },
-      {0, 0x01, "NumLock"},
-      {0, 0x02, "CapsLock"},
-      {0, 0x03, "ScrollLock"},
-      {0, 0x04, "Compose"},
-      {0, 0x05, "Kana"},
-      {0, 0x4b, "GenericIndicator"},
-  {  9, 0, "Button" },
-  { 10, 0, "Ordinal" },
-  { 12, 0, "Consumer" },
-      {0, 0x238, "HorizontalWheel"},
-  { 13, 0, "Digitizers" },
-    {0, 0x01, "Digitizer"},
-    {0, 0x02, "Pen"},
-    {0, 0x03, "LightPen"},
-    {0, 0x04, "TouchScreen"},
-    {0, 0x05, "TouchPad"},
-    {0, 0x20, "Stylus"},
-    {0, 0x21, "Puck"},
-    {0, 0x22, "Finger"},
-    {0, 0x30, "TipPressure"},
-    {0, 0x31, "BarrelPressure"},
-    {0, 0x32, "InRange"},
-    {0, 0x33, "Touch"},
-    {0, 0x34, "UnTouch"},
-    {0, 0x35, "Tap"},
-    {0, 0x39, "TabletFunctionKey"},
-    {0, 0x3a, "ProgramChangeKey"},
-    {0, 0x3c, "Invert"},
-    {0, 0x42, "TipSwitch"},
-    {0, 0x43, "SecondaryTipSwitch"},
-    {0, 0x44, "BarrelSwitch"},
-    {0, 0x45, "Eraser"},
-    {0, 0x46, "TabletPick"},
-  { 15, 0, "PhysicalInterfaceDevice" },
-    {0, 0x00, "Undefined"},
-    {0, 0x01, "Physical_Interface_Device"},
-      {0, 0x20, "Normal"},
-    {0, 0x21, "Set_Effect_Report"},
-      {0, 0x22, "Effect_Block_Index"},
-      {0, 0x23, "Parameter_Block_Offset"},
-      {0, 0x24, "ROM_Flag"},
-      {0, 0x25, "Effect_Type"},
-        {0, 0x26, "ET_Constant_Force"},
-        {0, 0x27, "ET_Ramp"},
-        {0, 0x28, "ET_Custom_Force_Data"},
-        {0, 0x30, "ET_Square"},
-        {0, 0x31, "ET_Sine"},
-        {0, 0x32, "ET_Triangle"},
-        {0, 0x33, "ET_Sawtooth_Up"},
-        {0, 0x34, "ET_Sawtooth_Down"},
-        {0, 0x40, "ET_Spring"},
-        {0, 0x41, "ET_Damper"},
-        {0, 0x42, "ET_Inertia"},
-        {0, 0x43, "ET_Friction"},
-      {0, 0x50, "Duration"},
-      {0, 0x51, "Sample_Period"},
-      {0, 0x52, "Gain"},
-      {0, 0x53, "Trigger_Button"},
-      {0, 0x54, "Trigger_Repeat_Interval"},
-      {0, 0x55, "Axes_Enable"},
-        {0, 0x56, "Direction_Enable"},
-      {0, 0x57, "Direction"},
-      {0, 0x58, "Type_Specific_Block_Offset"},
-        {0, 0x59, "Block_Type"},
-        {0, 0x5A, "Set_Envelope_Report"},
-          {0, 0x5B, "Attack_Level"},
-          {0, 0x5C, "Attack_Time"},
-          {0, 0x5D, "Fade_Level"},
-          {0, 0x5E, "Fade_Time"},
-        {0, 0x5F, "Set_Condition_Report"},
-        {0, 0x60, "CP_Offset"},
-        {0, 0x61, "Positive_Coefficient"},
-        {0, 0x62, "Negative_Coefficient"},
-        {0, 0x63, "Positive_Saturation"},
-        {0, 0x64, "Negative_Saturation"},
-        {0, 0x65, "Dead_Band"},
-      {0, 0x66, "Download_Force_Sample"},
-      {0, 0x67, "Isoch_Custom_Force_Enable"},
-      {0, 0x68, "Custom_Force_Data_Report"},
-        {0, 0x69, "Custom_Force_Data"},
-        {0, 0x6A, "Custom_Force_Vendor_Defined_Data"},
-      {0, 0x6B, "Set_Custom_Force_Report"},
-        {0, 0x6C, "Custom_Force_Data_Offset"},
-        {0, 0x6D, "Sample_Count"},
-      {0, 0x6E, "Set_Periodic_Report"},
-        {0, 0x6F, "Offset"},
-        {0, 0x70, "Magnitude"},
-        {0, 0x71, "Phase"},
-        {0, 0x72, "Period"},
-      {0, 0x73, "Set_Constant_Force_Report"},
-        {0, 0x74, "Set_Ramp_Force_Report"},
-        {0, 0x75, "Ramp_Start"},
-        {0, 0x76, "Ramp_End"},
-      {0, 0x77, "Effect_Operation_Report"},
-        {0, 0x78, "Effect_Operation"},
-          {0, 0x79, "Op_Effect_Start"},
-          {0, 0x7A, "Op_Effect_Start_Solo"},
-          {0, 0x7B, "Op_Effect_Stop"},
-          {0, 0x7C, "Loop_Count"},
-      {0, 0x7D, "Device_Gain_Report"},
-        {0, 0x7E, "Device_Gain"},
-    {0, 0x7F, "PID_Pool_Report"},
-      {0, 0x80, "RAM_Pool_Size"},
-      {0, 0x81, "ROM_Pool_Size"},
-      {0, 0x82, "ROM_Effect_Block_Count"},
-      {0, 0x83, "Simultaneous_Effects_Max"},
-      {0, 0x84, "Pool_Alignment"},
-    {0, 0x85, "PID_Pool_Move_Report"},
-      {0, 0x86, "Move_Source"},
-      {0, 0x87, "Move_Destination"},
-      {0, 0x88, "Move_Length"},
-    {0, 0x89, "PID_Block_Load_Report"},
-      {0, 0x8B, "Block_Load_Status"},
-      {0, 0x8C, "Block_Load_Success"},
-      {0, 0x8D, "Block_Load_Full"},
-      {0, 0x8E, "Block_Load_Error"},
-      {0, 0x8F, "Block_Handle"},
-      {0, 0x90, "PID_Block_Free_Report"},
-      {0, 0x91, "Type_Specific_Block_Handle"},
-    {0, 0x92, "PID_State_Report"},
-      {0, 0x94, "Effect_Playing"},
-      {0, 0x95, "PID_Device_Control_Report"},
-        {0, 0x96, "PID_Device_Control"},
-        {0, 0x97, "DC_Enable_Actuators"},
-        {0, 0x98, "DC_Disable_Actuators"},
-        {0, 0x99, "DC_Stop_All_Effects"},
-        {0, 0x9A, "DC_Device_Reset"},
-        {0, 0x9B, "DC_Device_Pause"},
-        {0, 0x9C, "DC_Device_Continue"},
-      {0, 0x9F, "Device_Paused"},
-      {0, 0xA0, "Actuators_Enabled"},
-      {0, 0xA4, "Safety_Switch"},
-      {0, 0xA5, "Actuator_Override_Switch"},
-      {0, 0xA6, "Actuator_Power"},
-    {0, 0xA7, "Start_Delay"},
-    {0, 0xA8, "Parameter_Block_Size"},
-    {0, 0xA9, "Device_Managed_Pool"},
-    {0, 0xAA, "Shared_Parameter_Blocks"},
-    {0, 0xAB, "Create_New_Effect_Report"},
-    {0, 0xAC, "RAM_Pool_Available"},
-  { 0x84, 0, "Power Device" },
-    { 0x84, 0x02, "PresentStatus" },
-    { 0x84, 0x03, "ChangeStatus" },
-    { 0x84, 0x04, "UPS" },
-    { 0x84, 0x05, "PowerSupply" },
-    { 0x84, 0x10, "BatterySystem" },
-    { 0x84, 0x11, "BatterySystemID" },
-    { 0x84, 0x12, "Battery" },
-    { 0x84, 0x13, "BatteryID" },
-    { 0x84, 0x14, "Charger" },
-    { 0x84, 0x15, "ChargerID" },
-    { 0x84, 0x16, "PowerConverter" },
-    { 0x84, 0x17, "PowerConverterID" },
-    { 0x84, 0x18, "OutletSystem" },
-    { 0x84, 0x19, "OutletSystemID" },
-    { 0x84, 0x1a, "Input" },
-    { 0x84, 0x1b, "InputID" },
-    { 0x84, 0x1c, "Output" },
-    { 0x84, 0x1d, "OutputID" },
-    { 0x84, 0x1e, "Flow" },
-    { 0x84, 0x1f, "FlowID" },
-    { 0x84, 0x20, "Outlet" },
-    { 0x84, 0x21, "OutletID" },
-    { 0x84, 0x22, "Gang" },
-    { 0x84, 0x24, "PowerSummary" },
-    { 0x84, 0x25, "PowerSummaryID" },
-    { 0x84, 0x30, "Voltage" },
-    { 0x84, 0x31, "Current" },
-    { 0x84, 0x32, "Frequency" },
-    { 0x84, 0x33, "ApparentPower" },
-    { 0x84, 0x35, "PercentLoad" },
-    { 0x84, 0x40, "ConfigVoltage" },
-    { 0x84, 0x41, "ConfigCurrent" },
-    { 0x84, 0x43, "ConfigApparentPower" },
-    { 0x84, 0x53, "LowVoltageTransfer" },
-    { 0x84, 0x54, "HighVoltageTransfer" },
-    { 0x84, 0x56, "DelayBeforeStartup" },
-    { 0x84, 0x57, "DelayBeforeShutdown" },
-    { 0x84, 0x58, "Test" },
-    { 0x84, 0x5a, "AudibleAlarmControl" },
-    { 0x84, 0x60, "Present" },
-    { 0x84, 0x61, "Good" },
-    { 0x84, 0x62, "InternalFailure" },
-    { 0x84, 0x65, "Overload" },
-    { 0x84, 0x66, "OverCharged" },
-    { 0x84, 0x67, "OverTemperature" },
-    { 0x84, 0x68, "ShutdownRequested" },
-    { 0x84, 0x69, "ShutdownImminent" },
-    { 0x84, 0x6b, "SwitchOn/Off" },
-    { 0x84, 0x6c, "Switchable" },
-    { 0x84, 0x6d, "Used" },
-    { 0x84, 0x6e, "Boost" },
-    { 0x84, 0x73, "CommunicationLost" },
-    { 0x84, 0xfd, "iManufacturer" },
-    { 0x84, 0xfe, "iProduct" },
-    { 0x84, 0xff, "iSerialNumber" },
-  { 0x85, 0, "Battery System" },
-    { 0x85, 0x01, "SMBBatteryMode" },
-    { 0x85, 0x02, "SMBBatteryStatus" },
-    { 0x85, 0x03, "SMBAlarmWarning" },
-    { 0x85, 0x04, "SMBChargerMode" },
-    { 0x85, 0x05, "SMBChargerStatus" },
-    { 0x85, 0x06, "SMBChargerSpecInfo" },
-    { 0x85, 0x07, "SMBSelectorState" },
-    { 0x85, 0x08, "SMBSelectorPresets" },
-    { 0x85, 0x09, "SMBSelectorInfo" },
-    { 0x85, 0x29, "RemainingCapacityLimit" },
-    { 0x85, 0x2c, "CapacityMode" },
-    { 0x85, 0x42, "BelowRemainingCapacityLimit" },
-    { 0x85, 0x44, "Charging" },
-    { 0x85, 0x45, "Discharging" },
-    { 0x85, 0x4b, "NeedReplacement" },
-    { 0x85, 0x66, "RemainingCapacity" },
-    { 0x85, 0x68, "RunTimeToEmpty" },
-    { 0x85, 0x6a, "AverageTimeToFull" },
-    { 0x85, 0x83, "DesignCapacity" },
-    { 0x85, 0x85, "ManufacturerDate" },
-    { 0x85, 0x89, "iDeviceChemistry" },
-    { 0x85, 0x8b, "Rechargable" },
-    { 0x85, 0x8f, "iOEMInformation" },
-    { 0x85, 0x8d, "CapacityGranularity1" },
-    { 0x85, 0xd0, "ACPresent" },
-  /* pages 0xff00 to 0xffff are vendor-specific */
-  { 0xffff, 0, "Vendor-specific-FF" },
-  { 0, 0, NULL }
-};
-
-static void resolv_usage_page(unsigned page) {
-	const struct hid_usage_entry *p;
-
-	for (p = hid_usage_table; p->description; p++)
-		if (p->page == page) {
-			printk("%s", p->description);
-			return;
-		}
-	printk("%04x", page);
-}
-
-static void resolv_usage(unsigned usage) {
-	const struct hid_usage_entry *p;
-
-	resolv_usage_page(usage >> 16);
-	printk(".");
-	for (p = hid_usage_table; p->description; p++)
-		if (p->page == (usage >> 16)) {
-			for(++p; p->description && p->usage != 0; p++)
-				if (p->usage == (usage & 0xffff)) {
-					printk("%s", p->description);
-					return;
-				}
-			break;
-		}
-	printk("%04x", usage & 0xffff);
-}
-
-__inline__ static void tab(int n) {
-	while (n--) printk(" ");
-}
-
-static void hid_dump_field(struct hid_field *field, int n) {
-	int j;
-
-	if (field->physical) {
-		tab(n);
-		printk("Physical(");
-		resolv_usage(field->physical); printk(")\n");
-	}
-	if (field->logical) {
-		tab(n);
-		printk("Logical(");
-		resolv_usage(field->logical); printk(")\n");
-	}
-	tab(n); printk("Usage(%d)\n", field->maxusage);
-	for (j = 0; j < field->maxusage; j++) {
-		tab(n+2);resolv_usage(field->usage[j].hid); printk("\n");
-	}
-	if (field->logical_minimum != field->logical_maximum) {
-		tab(n); printk("Logical Minimum(%d)\n", field->logical_minimum);
-		tab(n); printk("Logical Maximum(%d)\n", field->logical_maximum);
-	}
-	if (field->physical_minimum != field->physical_maximum) {
-		tab(n); printk("Physical Minimum(%d)\n", field->physical_minimum);
-		tab(n); printk("Physical Maximum(%d)\n", field->physical_maximum);
-	}
-	if (field->unit_exponent) {
-		tab(n); printk("Unit Exponent(%d)\n", field->unit_exponent);
-	}
-	if (field->unit) {
-		char *systems[5] = { "None", "SI Linear", "SI Rotation", "English Linear", "English Rotation" };
-		char *units[5][8] = {
-			{ "None", "None", "None", "None", "None", "None", "None", "None" },
-			{ "None", "Centimeter", "Gram", "Seconds", "Kelvin",     "Ampere", "Candela", "None" },
-			{ "None", "Radians",    "Gram", "Seconds", "Kelvin",     "Ampere", "Candela", "None" },
-			{ "None", "Inch",       "Slug", "Seconds", "Fahrenheit", "Ampere", "Candela", "None" },
-			{ "None", "Degrees",    "Slug", "Seconds", "Fahrenheit", "Ampere", "Candela", "None" }
-		};
-
-		int i;
-		int sys;
-                __u32 data = field->unit;
-
-		/* First nibble tells us which system we're in. */
-		sys = data & 0xf;
-		data >>= 4;
-
-		if(sys > 4) {
-			tab(n); printk("Unit(Invalid)\n");
-		}
-		else {
-			int earlier_unit = 0;
-
-			tab(n); printk("Unit(%s : ", systems[sys]);
-
-			for (i=1 ; i<sizeof(__u32)*2 ; i++) {
-				char nibble = data & 0xf;
-				data >>= 4;
-				if (nibble != 0) {
-					if(earlier_unit++ > 0)
-						printk("*");
-					printk("%s", units[sys][i]);
-					if(nibble != 1) {
-						/* This is a _signed_ nibble(!) */
-
-						int val = nibble & 0x7;
-						if(nibble & 0x08)
-							val = -((0x7 & ~val) +1);
-						printk("^%d", val);
-					}
-				}
-			}
-			printk(")\n");
-		}
-	}
-	tab(n); printk("Report Size(%u)\n", field->report_size);
-	tab(n); printk("Report Count(%u)\n", field->report_count);
-	tab(n); printk("Report Offset(%u)\n", field->report_offset);
-
-	tab(n); printk("Flags( ");
-	j = field->flags;
-	printk("%s", HID_MAIN_ITEM_CONSTANT & j ? "Constant " : "");
-	printk("%s", HID_MAIN_ITEM_VARIABLE & j ? "Variable " : "Array ");
-	printk("%s", HID_MAIN_ITEM_RELATIVE & j ? "Relative " : "Absolute ");
-	printk("%s", HID_MAIN_ITEM_WRAP & j ? "Wrap " : "");
-	printk("%s", HID_MAIN_ITEM_NONLINEAR & j ? "NonLinear " : "");
-	printk("%s", HID_MAIN_ITEM_NO_PREFERRED & j ? "NoPrefferedState " : "");
-	printk("%s", HID_MAIN_ITEM_NULL_STATE & j ? "NullState " : "");
-	printk("%s", HID_MAIN_ITEM_VOLATILE & j ? "Volatile " : "");
-	printk("%s", HID_MAIN_ITEM_BUFFERED_BYTE & j ? "BufferedByte " : "");
-	printk(")\n");
-}
-
-static void __attribute__((unused)) hid_dump_device(struct hid_device *device) {
-	struct hid_report_enum *report_enum;
-	struct hid_report *report;
-	struct list_head *list;
-	unsigned i,k;
-	static char *table[] = {"INPUT", "OUTPUT", "FEATURE"};
-
-	for (i = 0; i < HID_REPORT_TYPES; i++) {
-		report_enum = device->report_enum + i;
-		list = report_enum->report_list.next;
-		while (list != &report_enum->report_list) {
-			report = (struct hid_report *) list;
-			tab(2);
-			printk("%s", table[i]);
-			if (report->id)
-				printk("(%d)", report->id);
-			printk("[%s]", table[report->type]);
-			printk("\n");
-			for (k = 0; k < report->maxfield; k++) {
-				tab(4);
-				printk("Field(%d)\n", k);
-				hid_dump_field(report->field[k], 6);
-			}
-			list = list->next;
-		}
-	}
-}
-
-static void __attribute__((unused)) hid_dump_input(struct hid_usage *usage, __s32 value) {
-	printk("hid-debug: input ");
-	resolv_usage(usage->hid);
-	printk(" = %d\n", value);
-}
-
-
-static char *events[EV_MAX + 1] = {
-	[EV_SYN] = "Sync",			[EV_KEY] = "Key",
-	[EV_REL] = "Relative",			[EV_ABS] = "Absolute",
-	[EV_MSC] = "Misc",			[EV_LED] = "LED",
-	[EV_SND] = "Sound",			[EV_REP] = "Repeat",
-	[EV_FF] = "ForceFeedback",		[EV_PWR] = "Power",
-	[EV_FF_STATUS] = "ForceFeedbackStatus",
-};
-
-static char *syncs[2] = {
-	[SYN_REPORT] = "Report",		[SYN_CONFIG] = "Config",
-};
-static char *keys[KEY_MAX + 1] = {
-	[KEY_RESERVED] = "Reserved",		[KEY_ESC] = "Esc",
-	[KEY_1] = "1",				[KEY_2] = "2",
-	[KEY_3] = "3",				[KEY_4] = "4",
-	[KEY_5] = "5",				[KEY_6] = "6",
-	[KEY_7] = "7",				[KEY_8] = "8",
-	[KEY_9] = "9",				[KEY_0] = "0",
-	[KEY_MINUS] = "Minus",			[KEY_EQUAL] = "Equal",
-	[KEY_BACKSPACE] = "Backspace",		[KEY_TAB] = "Tab",
-	[KEY_Q] = "Q",				[KEY_W] = "W",
-	[KEY_E] = "E",				[KEY_R] = "R",
-	[KEY_T] = "T",				[KEY_Y] = "Y",
-	[KEY_U] = "U",				[KEY_I] = "I",
-	[KEY_O] = "O",				[KEY_P] = "P",
-	[KEY_LEFTBRACE] = "LeftBrace",		[KEY_RIGHTBRACE] = "RightBrace",
-	[KEY_ENTER] = "Enter",			[KEY_LEFTCTRL] = "LeftControl",
-	[KEY_A] = "A",				[KEY_S] = "S",
-	[KEY_D] = "D",				[KEY_F] = "F",
-	[KEY_G] = "G",				[KEY_H] = "H",
-	[KEY_J] = "J",				[KEY_K] = "K",
-	[KEY_L] = "L",				[KEY_SEMICOLON] = "Semicolon",
-	[KEY_APOSTROPHE] = "Apostrophe",	[KEY_GRAVE] = "Grave",
-	[KEY_LEFTSHIFT] = "LeftShift",		[KEY_BACKSLASH] = "BackSlash",
-	[KEY_Z] = "Z",				[KEY_X] = "X",
-	[KEY_C] = "C",				[KEY_V] = "V",
-	[KEY_B] = "B",				[KEY_N] = "N",
-	[KEY_M] = "M",				[KEY_COMMA] = "Comma",
-	[KEY_DOT] = "Dot",			[KEY_SLASH] = "Slash",
-	[KEY_RIGHTSHIFT] = "RightShift",	[KEY_KPASTERISK] = "KPAsterisk",
-	[KEY_LEFTALT] = "LeftAlt",		[KEY_SPACE] = "Space",
-	[KEY_CAPSLOCK] = "CapsLock",		[KEY_F1] = "F1",
-	[KEY_F2] = "F2",			[KEY_F3] = "F3",
-	[KEY_F4] = "F4",			[KEY_F5] = "F5",
-	[KEY_F6] = "F6",			[KEY_F7] = "F7",
-	[KEY_F8] = "F8",			[KEY_F9] = "F9",
-	[KEY_F10] = "F10",			[KEY_NUMLOCK] = "NumLock",
-	[KEY_SCROLLLOCK] = "ScrollLock",	[KEY_KP7] = "KP7",
-	[KEY_KP8] = "KP8",			[KEY_KP9] = "KP9",
-	[KEY_KPMINUS] = "KPMinus",		[KEY_KP4] = "KP4",
-	[KEY_KP5] = "KP5",			[KEY_KP6] = "KP6",
-	[KEY_KPPLUS] = "KPPlus",		[KEY_KP1] = "KP1",
-	[KEY_KP2] = "KP2",			[KEY_KP3] = "KP3",
-	[KEY_KP0] = "KP0",			[KEY_KPDOT] = "KPDot",
-	[KEY_ZENKAKUHANKAKU] = "Zenkaku/Hankaku", [KEY_102ND] = "102nd",
-	[KEY_F11] = "F11",			[KEY_F12] = "F12",
-	[KEY_RO] = "RO",			[KEY_KATAKANA] = "Katakana",
-	[KEY_HIRAGANA] = "HIRAGANA",		[KEY_HENKAN] = "Henkan",
-	[KEY_KATAKANAHIRAGANA] = "Katakana/Hiragana", [KEY_MUHENKAN] = "Muhenkan",
-	[KEY_KPJPCOMMA] = "KPJpComma",		[KEY_KPENTER] = "KPEnter",
-	[KEY_RIGHTCTRL] = "RightCtrl",		[KEY_KPSLASH] = "KPSlash",
-	[KEY_SYSRQ] = "SysRq",			[KEY_RIGHTALT] = "RightAlt",
-	[KEY_LINEFEED] = "LineFeed",		[KEY_HOME] = "Home",
-	[KEY_UP] = "Up",			[KEY_PAGEUP] = "PageUp",
-	[KEY_LEFT] = "Left",			[KEY_RIGHT] = "Right",
-	[KEY_END] = "End",			[KEY_DOWN] = "Down",
-	[KEY_PAGEDOWN] = "PageDown",		[KEY_INSERT] = "Insert",
-	[KEY_DELETE] = "Delete",		[KEY_MACRO] = "Macro",
-	[KEY_MUTE] = "Mute",			[KEY_VOLUMEDOWN] = "VolumeDown",
-	[KEY_VOLUMEUP] = "VolumeUp",		[KEY_POWER] = "Power",
-	[KEY_KPEQUAL] = "KPEqual",		[KEY_KPPLUSMINUS] = "KPPlusMinus",
-	[KEY_PAUSE] = "Pause",			[KEY_KPCOMMA] = "KPComma",
-	[KEY_HANGUEL] = "Hangeul",		[KEY_HANJA] = "Hanja",
-	[KEY_YEN] = "Yen",			[KEY_LEFTMETA] = "LeftMeta",
-	[KEY_RIGHTMETA] = "RightMeta",		[KEY_COMPOSE] = "Compose",
-	[KEY_STOP] = "Stop",			[KEY_AGAIN] = "Again",
-	[KEY_PROPS] = "Props",			[KEY_UNDO] = "Undo",
-	[KEY_FRONT] = "Front",			[KEY_COPY] = "Copy",
-	[KEY_OPEN] = "Open",			[KEY_PASTE] = "Paste",
-	[KEY_FIND] = "Find",			[KEY_CUT] = "Cut",
-	[KEY_HELP] = "Help",			[KEY_MENU] = "Menu",
-	[KEY_CALC] = "Calc",			[KEY_SETUP] = "Setup",
-	[KEY_SLEEP] = "Sleep",			[KEY_WAKEUP] = "WakeUp",
-	[KEY_FILE] = "File",			[KEY_SENDFILE] = "SendFile",
-	[KEY_DELETEFILE] = "DeleteFile",	[KEY_XFER] = "X-fer",
-	[KEY_PROG1] = "Prog1",			[KEY_PROG2] = "Prog2",
-	[KEY_WWW] = "WWW",			[KEY_MSDOS] = "MSDOS",
-	[KEY_COFFEE] = "Coffee",		[KEY_DIRECTION] = "Direction",
-	[KEY_CYCLEWINDOWS] = "CycleWindows",	[KEY_MAIL] = "Mail",
-	[KEY_BOOKMARKS] = "Bookmarks",		[KEY_COMPUTER] = "Computer",
-	[KEY_BACK] = "Back",			[KEY_FORWARD] = "Forward",
-	[KEY_CLOSECD] = "CloseCD",		[KEY_EJECTCD] = "EjectCD",
-	[KEY_EJECTCLOSECD] = "EjectCloseCD",	[KEY_NEXTSONG] = "NextSong",
-	[KEY_PLAYPAUSE] = "PlayPause",		[KEY_PREVIOUSSONG] = "PreviousSong",
-	[KEY_STOPCD] = "StopCD",		[KEY_RECORD] = "Record",
-	[KEY_REWIND] = "Rewind",		[KEY_PHONE] = "Phone",
-	[KEY_ISO] = "ISOKey",			[KEY_CONFIG] = "Config",
-	[KEY_HOMEPAGE] = "HomePage",		[KEY_REFRESH] = "Refresh",
-	[KEY_EXIT] = "Exit",			[KEY_MOVE] = "Move",
-	[KEY_EDIT] = "Edit",			[KEY_SCROLLUP] = "ScrollUp",
-	[KEY_SCROLLDOWN] = "ScrollDown",	[KEY_KPLEFTPAREN] = "KPLeftParenthesis",
-	[KEY_KPRIGHTPAREN] = "KPRightParenthesis", [KEY_NEW] = "New",
-	[KEY_REDO] = "Redo",			[KEY_F13] = "F13",
-	[KEY_F14] = "F14",			[KEY_F15] = "F15",
-	[KEY_F16] = "F16",			[KEY_F17] = "F17",
-	[KEY_F18] = "F18",			[KEY_F19] = "F19",
-	[KEY_F20] = "F20",			[KEY_F21] = "F21",
-	[KEY_F22] = "F22",			[KEY_F23] = "F23",
-	[KEY_F24] = "F24",			[KEY_PLAYCD] = "PlayCD",
-	[KEY_PAUSECD] = "PauseCD",		[KEY_PROG3] = "Prog3",
-	[KEY_PROG4] = "Prog4",			[KEY_SUSPEND] = "Suspend",
-	[KEY_CLOSE] = "Close",			[KEY_PLAY] = "Play",
-	[KEY_FASTFORWARD] = "FastForward",	[KEY_BASSBOOST] = "BassBoost",
-	[KEY_PRINT] = "Print",			[KEY_HP] = "HP",
-	[KEY_CAMERA] = "Camera",		[KEY_SOUND] = "Sound",
-	[KEY_QUESTION] = "Question",		[KEY_EMAIL] = "Email",
-	[KEY_CHAT] = "Chat",			[KEY_SEARCH] = "Search",
-	[KEY_CONNECT] = "Connect",		[KEY_FINANCE] = "Finance",
-	[KEY_SPORT] = "Sport",			[KEY_SHOP] = "Shop",
-	[KEY_ALTERASE] = "AlternateErase",	[KEY_CANCEL] = "Cancel",
-	[KEY_BRIGHTNESSDOWN] = "BrightnessDown", [KEY_BRIGHTNESSUP] = "BrightnessUp",
-	[KEY_MEDIA] = "Media",			[KEY_UNKNOWN] = "Unknown",
-	[BTN_0] = "Btn0",			[BTN_1] = "Btn1",
-	[BTN_2] = "Btn2",			[BTN_3] = "Btn3",
-	[BTN_4] = "Btn4",			[BTN_5] = "Btn5",
-	[BTN_6] = "Btn6",			[BTN_7] = "Btn7",
-	[BTN_8] = "Btn8",			[BTN_9] = "Btn9",
-	[BTN_LEFT] = "LeftBtn",			[BTN_RIGHT] = "RightBtn",
-	[BTN_MIDDLE] = "MiddleBtn",		[BTN_SIDE] = "SideBtn",
-	[BTN_EXTRA] = "ExtraBtn",		[BTN_FORWARD] = "ForwardBtn",
-	[BTN_BACK] = "BackBtn",			[BTN_TASK] = "TaskBtn",
-	[BTN_TRIGGER] = "Trigger",		[BTN_THUMB] = "ThumbBtn",
-	[BTN_THUMB2] = "ThumbBtn2",		[BTN_TOP] = "TopBtn",
-	[BTN_TOP2] = "TopBtn2",			[BTN_PINKIE] = "PinkieBtn",
-	[BTN_BASE] = "BaseBtn",			[BTN_BASE2] = "BaseBtn2",
-	[BTN_BASE3] = "BaseBtn3",		[BTN_BASE4] = "BaseBtn4",
-	[BTN_BASE5] = "BaseBtn5",		[BTN_BASE6] = "BaseBtn6",
-	[BTN_DEAD] = "BtnDead",			[BTN_A] = "BtnA",
-	[BTN_B] = "BtnB",			[BTN_C] = "BtnC",
-	[BTN_X] = "BtnX",			[BTN_Y] = "BtnY",
-	[BTN_Z] = "BtnZ",			[BTN_TL] = "BtnTL",
-	[BTN_TR] = "BtnTR",			[BTN_TL2] = "BtnTL2",
-	[BTN_TR2] = "BtnTR2",			[BTN_SELECT] = "BtnSelect",
-	[BTN_START] = "BtnStart",		[BTN_MODE] = "BtnMode",
-	[BTN_THUMBL] = "BtnThumbL",		[BTN_THUMBR] = "BtnThumbR",
-	[BTN_TOOL_PEN] = "ToolPen",		[BTN_TOOL_RUBBER] = "ToolRubber",
-	[BTN_TOOL_BRUSH] = "ToolBrush",		[BTN_TOOL_PENCIL] = "ToolPencil",
-	[BTN_TOOL_AIRBRUSH] = "ToolAirbrush",	[BTN_TOOL_FINGER] = "ToolFinger",
-	[BTN_TOOL_MOUSE] = "ToolMouse",		[BTN_TOOL_LENS] = "ToolLens",
-	[BTN_TOUCH] = "Touch",			[BTN_STYLUS] = "Stylus",
-	[BTN_STYLUS2] = "Stylus2",		[BTN_TOOL_DOUBLETAP] = "ToolDoubleTap",
-	[BTN_TOOL_TRIPLETAP] = "ToolTripleTap", [BTN_GEAR_DOWN] = "WheelBtn",
-	[BTN_GEAR_UP] = "Gear up",		[KEY_OK] = "Ok",
-	[KEY_SELECT] = "Select",		[KEY_GOTO] = "Goto",
-	[KEY_CLEAR] = "Clear",			[KEY_POWER2] = "Power2",
-	[KEY_OPTION] = "Option",		[KEY_INFO] = "Info",
-	[KEY_TIME] = "Time",			[KEY_VENDOR] = "Vendor",
-	[KEY_ARCHIVE] = "Archive",		[KEY_PROGRAM] = "Program",
-	[KEY_CHANNEL] = "Channel",		[KEY_FAVORITES] = "Favorites",
-	[KEY_EPG] = "EPG",			[KEY_PVR] = "PVR",
-	[KEY_MHP] = "MHP",			[KEY_LANGUAGE] = "Language",
-	[KEY_TITLE] = "Title",			[KEY_SUBTITLE] = "Subtitle",
-	[KEY_ANGLE] = "Angle",			[KEY_ZOOM] = "Zoom",
-	[KEY_MODE] = "Mode",			[KEY_KEYBOARD] = "Keyboard",
-	[KEY_SCREEN] = "Screen",		[KEY_PC] = "PC",
-	[KEY_TV] = "TV",			[KEY_TV2] = "TV2",
-	[KEY_VCR] = "VCR",			[KEY_VCR2] = "VCR2",
-	[KEY_SAT] = "Sat",			[KEY_SAT2] = "Sat2",
-	[KEY_CD] = "CD",			[KEY_TAPE] = "Tape",
-	[KEY_RADIO] = "Radio",			[KEY_TUNER] = "Tuner",
-	[KEY_PLAYER] = "Player",		[KEY_TEXT] = "Text",
-	[KEY_DVD] = "DVD",			[KEY_AUX] = "Aux",
-	[KEY_MP3] = "MP3",			[KEY_AUDIO] = "Audio",
-	[KEY_VIDEO] = "Video",			[KEY_DIRECTORY] = "Directory",
-	[KEY_LIST] = "List",			[KEY_MEMO] = "Memo",
-	[KEY_CALENDAR] = "Calendar",		[KEY_RED] = "Red",
-	[KEY_GREEN] = "Green",			[KEY_YELLOW] = "Yellow",
-	[KEY_BLUE] = "Blue",			[KEY_CHANNELUP] = "ChannelUp",
-	[KEY_CHANNELDOWN] = "ChannelDown",	[KEY_FIRST] = "First",
-	[KEY_LAST] = "Last",			[KEY_AB] = "AB",
-	[KEY_NEXT] = "Next",			[KEY_RESTART] = "Restart",
-	[KEY_SLOW] = "Slow",			[KEY_SHUFFLE] = "Shuffle",
-	[KEY_BREAK] = "Break",			[KEY_PREVIOUS] = "Previous",
-	[KEY_DIGITS] = "Digits",		[KEY_TEEN] = "TEEN",
-	[KEY_TWEN] = "TWEN",			[KEY_DEL_EOL] = "DeleteEOL",
-	[KEY_DEL_EOS] = "DeleteEOS",		[KEY_INS_LINE] = "InsertLine",
-	[KEY_DEL_LINE] = "DeleteLine",
-	[KEY_SEND] = "Send",			[KEY_REPLY] = "Reply",
-	[KEY_FORWARDMAIL] = "ForwardMail",	[KEY_SAVE] = "Save",
-	[KEY_DOCUMENTS] = "Documents",
-	[KEY_FN] = "Fn",			[KEY_FN_ESC] = "Fn+ESC",
-	[KEY_FN_1] = "Fn+1",			[KEY_FN_2] = "Fn+2",
-	[KEY_FN_B] = "Fn+B",			[KEY_FN_D] = "Fn+D",
-	[KEY_FN_E] = "Fn+E",			[KEY_FN_F] = "Fn+F",
-	[KEY_FN_S] = "Fn+S",
-	[KEY_FN_F1] = "Fn+F1",			[KEY_FN_F2] = "Fn+F2",
-	[KEY_FN_F3] = "Fn+F3",			[KEY_FN_F4] = "Fn+F4",
-	[KEY_FN_F5] = "Fn+F5",			[KEY_FN_F6] = "Fn+F6",
-	[KEY_FN_F7] = "Fn+F7",			[KEY_FN_F8] = "Fn+F8",
-	[KEY_FN_F9] = "Fn+F9",			[KEY_FN_F10] = "Fn+F10",
-	[KEY_FN_F11] = "Fn+F11",		[KEY_FN_F12] = "Fn+F12",
-	[KEY_KBDILLUMTOGGLE] = "KbdIlluminationToggle",
-	[KEY_KBDILLUMDOWN] = "KbdIlluminationDown",
-	[KEY_KBDILLUMUP] = "KbdIlluminationUp",
-	[KEY_SWITCHVIDEOMODE] = "SwitchVideoMode",
-};
-
-static char *relatives[REL_MAX + 1] = {
-	[REL_X] = "X",			[REL_Y] = "Y",
-	[REL_Z] = "Z",			[REL_HWHEEL] = "HWheel",
-	[REL_DIAL] = "Dial",		[REL_WHEEL] = "Wheel",
-	[REL_MISC] = "Misc",
-};
-
-static char *absolutes[ABS_MAX + 1] = {
-	[ABS_X] = "X",			[ABS_Y] = "Y",
-	[ABS_Z] = "Z",			[ABS_RX] = "Rx",
-	[ABS_RY] = "Ry",		[ABS_RZ] = "Rz",
-	[ABS_THROTTLE] = "Throttle",	[ABS_RUDDER] = "Rudder",
-	[ABS_WHEEL] = "Wheel",		[ABS_GAS] = "Gas",
-	[ABS_BRAKE] = "Brake",		[ABS_HAT0X] = "Hat0X",
-	[ABS_HAT0Y] = "Hat0Y",		[ABS_HAT1X] = "Hat1X",
-	[ABS_HAT1Y] = "Hat1Y",		[ABS_HAT2X] = "Hat2X",
-	[ABS_HAT2Y] = "Hat2Y",		[ABS_HAT3X] = "Hat3X",
-	[ABS_HAT3Y] = "Hat 3Y",		[ABS_PRESSURE] = "Pressure",
-	[ABS_DISTANCE] = "Distance",	[ABS_TILT_X] = "XTilt",
-	[ABS_TILT_Y] = "YTilt",		[ABS_TOOL_WIDTH] = "Tool Width",
-	[ABS_VOLUME] = "Volume",	[ABS_MISC] = "Misc",
-};
-
-static char *misc[MSC_MAX + 1] = {
-	[MSC_SERIAL] = "Serial",	[MSC_PULSELED] = "Pulseled",
-	[MSC_GESTURE] = "Gesture",	[MSC_RAW] = "RawData"
-};
-
-static char *leds[LED_MAX + 1] = {
-	[LED_NUML] = "NumLock",		[LED_CAPSL] = "CapsLock",
-	[LED_SCROLLL] = "ScrollLock",	[LED_COMPOSE] = "Compose",
-	[LED_KANA] = "Kana",		[LED_SLEEP] = "Sleep",
-	[LED_SUSPEND] = "Suspend",	[LED_MUTE] = "Mute",
-	[LED_MISC] = "Misc",
-};
-
-static char *repeats[REP_MAX + 1] = {
-	[REP_DELAY] = "Delay",		[REP_PERIOD] = "Period"
-};
-
-static char *sounds[SND_MAX + 1] = {
-	[SND_CLICK] = "Click",		[SND_BELL] = "Bell",
-	[SND_TONE] = "Tone"
-};
-
-static char **names[EV_MAX + 1] = {
-	[EV_SYN] = syncs,			[EV_KEY] = keys,
-	[EV_REL] = relatives,			[EV_ABS] = absolutes,
-	[EV_MSC] = misc,			[EV_LED] = leds,
-	[EV_SND] = sounds,			[EV_REP] = repeats,
-};
-
-static void __attribute__((unused)) resolv_event(__u8 type, __u16 code) {
-
-	printk("%s.%s", events[type] ? events[type] : "?",
-		names[type] ? (names[type][code] ? names[type][code] : "?") : "?");
-}
diff --git a/drivers/usb/input/hid-ff.c b/drivers/usb/input/hid-ff.c
index a8fc46c721c5..f8f660ee3fac 100644
--- a/drivers/usb/input/hid-ff.c
+++ b/drivers/usb/input/hid-ff.c
@@ -32,7 +32,7 @@
 #undef DEBUG
 #include <linux/usb.h>
 
-#include "hid.h"
+#include <linux/hid.h>
 
 /*
  * This table contains pointers to initializers. To add support for new
@@ -70,8 +70,8 @@ static struct hid_ff_initializer inits[] = {
 int hid_ff_init(struct hid_device* hid)
 {
 	struct hid_ff_initializer *init;
-	int vendor = le16_to_cpu(hid->dev->descriptor.idVendor);
-	int product = le16_to_cpu(hid->dev->descriptor.idProduct);
+	int vendor = le16_to_cpu(to_usb_device(hid->dev)->descriptor.idVendor);
+	int product = le16_to_cpu(to_usb_device(hid->dev)->descriptor.idProduct);
 
 	for (init = inits; init->idVendor; init++)
 		if (init->idVendor == vendor && init->idProduct == product)
@@ -79,3 +79,5 @@ int hid_ff_init(struct hid_device* hid)
 
 	return init->init(hid);
 }
+EXPORT_SYMBOL_GPL(hid_ff_init);
+
diff --git a/drivers/usb/input/hid-lgff.c b/drivers/usb/input/hid-lgff.c
index 93da222b6da8..e47466268565 100644
--- a/drivers/usb/input/hid-lgff.c
+++ b/drivers/usb/input/hid-lgff.c
@@ -29,7 +29,8 @@
 
 #include <linux/input.h>
 #include <linux/usb.h>
-#include "hid.h"
+#include <linux/hid.h>
+#include "usbhid.h"
 
 struct device_type {
 	u16 idVendor;
@@ -75,7 +76,7 @@ static int hid_lgff_play(struct input_dev *dev, void *data, struct ff_effect *ef
 		report->field[0]->value[2] = x;
 		report->field[0]->value[3] = y;
 		dbg("(x, y)=(%04x, %04x)", x, y);
-		hid_submit_report(hid, report, USB_DIR_OUT);
+		usbhid_submit_report(hid, report, USB_DIR_OUT);
 		break;
 
 	case FF_RUMBLE:
@@ -90,7 +91,7 @@ static int hid_lgff_play(struct input_dev *dev, void *data, struct ff_effect *ef
 		report->field[0]->value[2] = left;
 		report->field[0]->value[3] = right;
 		dbg("(left, right)=(%04x, %04x)", left, right);
-		hid_submit_report(hid, report, USB_DIR_OUT);
+		usbhid_submit_report(hid, report, USB_DIR_OUT);
 		break;
 	}
 	return 0;
diff --git a/drivers/usb/input/hid-pidff.c b/drivers/usb/input/hid-pidff.c
index 5420c13eb8eb..cbd2d53fefff 100644
--- a/drivers/usb/input/hid-pidff.c
+++ b/drivers/usb/input/hid-pidff.c
@@ -28,7 +28,9 @@
 #include <linux/input.h>
 #include <linux/usb.h>
 
-#include "hid.h"
+#include <linux/hid.h>
+
+#include "usbhid.h"
 
 #define	PID_EFFECTS_MAX		64
 
@@ -260,7 +262,7 @@ static void pidff_set_envelope_report(struct pidff_device *pidff,
 	debug("attack %u => %d", envelope->attack_level,
 	      pidff->set_envelope[PID_ATTACK_LEVEL].value[0]);
 
-	hid_submit_report(pidff->hid, pidff->reports[PID_SET_ENVELOPE],
+	usbhid_submit_report(pidff->hid, pidff->reports[PID_SET_ENVELOPE],
 			  USB_DIR_OUT);
 }
 
@@ -287,7 +289,7 @@ static void pidff_set_constant_force_report(struct pidff_device *pidff,
 	pidff_set_signed(&pidff->set_constant[PID_MAGNITUDE],
 			 effect->u.constant.level);
 
-	hid_submit_report(pidff->hid, pidff->reports[PID_SET_CONSTANT],
+	usbhid_submit_report(pidff->hid, pidff->reports[PID_SET_CONSTANT],
 			  USB_DIR_OUT);
 }
 
@@ -322,7 +324,7 @@ static void pidff_set_effect_report(struct pidff_device *pidff,
 				pidff->effect_direction);
 	pidff->set_effect[PID_START_DELAY].value[0] = effect->replay.delay;
 
-	hid_submit_report(pidff->hid, pidff->reports[PID_SET_EFFECT],
+	usbhid_submit_report(pidff->hid, pidff->reports[PID_SET_EFFECT],
 			  USB_DIR_OUT);
 }
 
@@ -354,7 +356,7 @@ static void pidff_set_periodic_report(struct pidff_device *pidff,
 	pidff_set(&pidff->set_periodic[PID_PHASE], effect->u.periodic.phase);
 	pidff->set_periodic[PID_PERIOD].value[0] = effect->u.periodic.period;
 
-	hid_submit_report(pidff->hid, pidff->reports[PID_SET_PERIODIC],
+	usbhid_submit_report(pidff->hid, pidff->reports[PID_SET_PERIODIC],
 			  USB_DIR_OUT);
 
 }
@@ -396,8 +398,8 @@ static void pidff_set_condition_report(struct pidff_device *pidff,
 			  effect->u.condition[i].left_saturation);
 		pidff_set(&pidff->set_condition[PID_DEAD_BAND],
 			  effect->u.condition[i].deadband);
-		hid_wait_io(pidff->hid);
-		hid_submit_report(pidff->hid, pidff->reports[PID_SET_CONDITION],
+		usbhid_wait_io(pidff->hid);
+		usbhid_submit_report(pidff->hid, pidff->reports[PID_SET_CONDITION],
 				  USB_DIR_OUT);
 	}
 }
@@ -438,7 +440,7 @@ static void pidff_set_ramp_force_report(struct pidff_device *pidff,
 			 effect->u.ramp.start_level);
 	pidff_set_signed(&pidff->set_ramp[PID_RAMP_END],
 			 effect->u.ramp.end_level);
-	hid_submit_report(pidff->hid, pidff->reports[PID_SET_RAMP],
+	usbhid_submit_report(pidff->hid, pidff->reports[PID_SET_RAMP],
 			  USB_DIR_OUT);
 }
 
@@ -463,19 +465,19 @@ static int pidff_request_effect_upload(struct pidff_device *pidff, int efnum)
 	int j;
 
 	pidff->create_new_effect_type->value[0] = efnum;
-	hid_submit_report(pidff->hid, pidff->reports[PID_CREATE_NEW_EFFECT],
+	usbhid_submit_report(pidff->hid, pidff->reports[PID_CREATE_NEW_EFFECT],
 			  USB_DIR_OUT);
 	debug("create_new_effect sent, type: %d", efnum);
 
 	pidff->block_load[PID_EFFECT_BLOCK_INDEX].value[0] = 0;
 	pidff->block_load_status->value[0] = 0;
-	hid_wait_io(pidff->hid);
+	usbhid_wait_io(pidff->hid);
 
 	for (j = 0; j < 60; j++) {
 		debug("pid_block_load requested");
-		hid_submit_report(pidff->hid, pidff->reports[PID_BLOCK_LOAD],
+		usbhid_submit_report(pidff->hid, pidff->reports[PID_BLOCK_LOAD],
 				  USB_DIR_IN);
-		hid_wait_io(pidff->hid);
+		usbhid_wait_io(pidff->hid);
 		if (pidff->block_load_status->value[0] ==
 		    pidff->status_id[PID_BLOCK_LOAD_SUCCESS]) {
 			debug("device reported free memory: %d bytes",
@@ -511,8 +513,8 @@ static void pidff_playback_pid(struct pidff_device *pidff, int pid_id, int n)
 		pidff->effect_operation[PID_LOOP_COUNT].value[0] = n;
 	}
 
-	hid_wait_io(pidff->hid);
-	hid_submit_report(pidff->hid, pidff->reports[PID_EFFECT_OPERATION],
+	usbhid_wait_io(pidff->hid);
+	usbhid_submit_report(pidff->hid, pidff->reports[PID_EFFECT_OPERATION],
 			  USB_DIR_OUT);
 }
 
@@ -534,7 +536,7 @@ static int pidff_playback(struct input_dev *dev, int effect_id, int value)
 static void pidff_erase_pid(struct pidff_device *pidff, int pid_id)
 {
 	pidff->block_free[PID_EFFECT_BLOCK_INDEX].value[0] = pid_id;
-	hid_submit_report(pidff->hid, pidff->reports[PID_BLOCK_FREE],
+	usbhid_submit_report(pidff->hid, pidff->reports[PID_BLOCK_FREE],
 			  USB_DIR_OUT);
 }
 
@@ -714,7 +716,7 @@ static void pidff_set_gain(struct input_dev *dev, u16 gain)
 	struct pidff_device *pidff = dev->ff->private;
 
 	pidff_set(&pidff->device_gain[PID_DEVICE_GAIN_FIELD], gain);
-	hid_submit_report(pidff->hid, pidff->reports[PID_DEVICE_GAIN],
+	usbhid_submit_report(pidff->hid, pidff->reports[PID_DEVICE_GAIN],
 			  USB_DIR_OUT);
 }
 
@@ -739,7 +741,7 @@ static void pidff_autocenter(struct pidff_device *pidff, u16 magnitude)
 	pidff_set(&pidff->set_effect[PID_GAIN], magnitude);
 	pidff->set_effect[PID_START_DELAY].value[0] = 0;
 
-	hid_submit_report(pidff->hid, pidff->reports[PID_SET_EFFECT],
+	usbhid_submit_report(pidff->hid, pidff->reports[PID_SET_EFFECT],
 			  USB_DIR_OUT);
 }
 
@@ -1163,19 +1165,19 @@ static void pidff_reset(struct pidff_device *pidff)
 
 	pidff->device_control->value[0] = pidff->control_id[PID_RESET];
 	/* We reset twice as sometimes hid_wait_io isn't waiting long enough */
-	hid_submit_report(hid, pidff->reports[PID_DEVICE_CONTROL], USB_DIR_OUT);
-	hid_wait_io(hid);
-	hid_submit_report(hid, pidff->reports[PID_DEVICE_CONTROL], USB_DIR_OUT);
-	hid_wait_io(hid);
+	usbhid_submit_report(hid, pidff->reports[PID_DEVICE_CONTROL], USB_DIR_OUT);
+	usbhid_wait_io(hid);
+	usbhid_submit_report(hid, pidff->reports[PID_DEVICE_CONTROL], USB_DIR_OUT);
+	usbhid_wait_io(hid);
 
 	pidff->device_control->value[0] =
 		pidff->control_id[PID_ENABLE_ACTUATORS];
-	hid_submit_report(hid, pidff->reports[PID_DEVICE_CONTROL], USB_DIR_OUT);
-	hid_wait_io(hid);
+	usbhid_submit_report(hid, pidff->reports[PID_DEVICE_CONTROL], USB_DIR_OUT);
+	usbhid_wait_io(hid);
 
 	/* pool report is sometimes messed up, refetch it */
-	hid_submit_report(hid, pidff->reports[PID_POOL], USB_DIR_IN);
-	hid_wait_io(hid);
+	usbhid_submit_report(hid, pidff->reports[PID_POOL], USB_DIR_IN);
+	usbhid_wait_io(hid);
 
 	if (pidff->pool[PID_SIMULTANEOUS_MAX].value) {
 		int sim_effects = pidff->pool[PID_SIMULTANEOUS_MAX].value[0];
@@ -1187,9 +1189,9 @@ static void pidff_reset(struct pidff_device *pidff)
 				break;
 			}
 			debug("pid_pool requested again");
-			hid_submit_report(hid, pidff->reports[PID_POOL],
+			usbhid_submit_report(hid, pidff->reports[PID_POOL],
 					  USB_DIR_IN);
-			hid_wait_io(hid);
+			usbhid_wait_io(hid);
 		}
 	}
 }
@@ -1275,7 +1277,7 @@ int hid_pidff_init(struct hid_device *hid)
 
 	if (test_bit(FF_GAIN, dev->ffbit)) {
 		pidff_set(&pidff->device_gain[PID_DEVICE_GAIN_FIELD], 0xffff);
-		hid_submit_report(pidff->hid, pidff->reports[PID_DEVICE_GAIN],
+		usbhid_submit_report(pidff->hid, pidff->reports[PID_DEVICE_GAIN],
 				  USB_DIR_OUT);
 	}
 
diff --git a/drivers/usb/input/hid-tmff.c b/drivers/usb/input/hid-tmff.c
index 2d5be4c318ac..ab67331620d0 100644
--- a/drivers/usb/input/hid-tmff.c
+++ b/drivers/usb/input/hid-tmff.c
@@ -32,7 +32,8 @@
 #undef DEBUG
 #include <linux/usb.h>
 
-#include "hid.h"
+#include <linux/hid.h>
+#include "usbhid.h"
 
 /* Usages for thrustmaster devices I know about */
 #define THRUSTMASTER_USAGE_RUMBLE_LR	(HID_UP_GENDESK | 0xbb)
@@ -70,7 +71,7 @@ static int hid_tmff_play(struct input_dev *dev, void *data, struct ff_effect *ef
 	tmff->rumble->value[0] = left;
 	tmff->rumble->value[1] = right;
 	dbg("(left,right)=(%08x, %08x)", left, right);
-	hid_submit_report(hid, tmff->report, USB_DIR_OUT);
+	usbhid_submit_report(hid, tmff->report, USB_DIR_OUT);
 
 	return 0;
 }
diff --git a/drivers/usb/input/hid-zpff.c b/drivers/usb/input/hid-zpff.c
index d2ce3214572c..7bd8238ca212 100644
--- a/drivers/usb/input/hid-zpff.c
+++ b/drivers/usb/input/hid-zpff.c
@@ -27,7 +27,8 @@
 
 #include <linux/input.h>
 #include <linux/usb.h>
-#include "hid.h"
+#include <linux/hid.h>
+#include "usbhid.h"
 
 struct zpff_device {
 	struct hid_report *report;
@@ -56,7 +57,7 @@ static int hid_zpff_play(struct input_dev *dev, void *data,
 	zpff->report->field[2]->value[0] = left;
 	zpff->report->field[3]->value[0] = right;
 	debug("running with 0x%02x 0x%02x", left, right);
-	hid_submit_report(hid, zpff->report, USB_DIR_OUT);
+	usbhid_submit_report(hid, zpff->report, USB_DIR_OUT);
 
 	return 0;
 }
@@ -101,7 +102,7 @@ int hid_zpff_init(struct hid_device *hid)
 	zpff->report->field[1]->value[0] = 0x02;
 	zpff->report->field[2]->value[0] = 0x00;
 	zpff->report->field[3]->value[0] = 0x00;
-	hid_submit_report(hid, zpff->report, USB_DIR_OUT);
+	usbhid_submit_report(hid, zpff->report, USB_DIR_OUT);
 
 	printk(KERN_INFO "Force feedback for Zeroplus based devices by "
 	       "Anssi Hannula <anssi.hannula@gmail.com>\n");
diff --git a/drivers/usb/input/hid.h b/drivers/usb/input/hid.h
deleted file mode 100644
index 76ad68d9edfd..000000000000
--- a/drivers/usb/input/hid.h
+++ /dev/null
@@ -1,540 +0,0 @@
-#ifndef __HID_H
-#define __HID_H
-
-/*
- * $Id: hid.h,v 1.24 2001/12/27 10:37:41 vojtech Exp $
- *
- *  Copyright (c) 1999 Andreas Gal
- *  Copyright (c) 2000-2001 Vojtech Pavlik
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Should you need to contact me, the author, you can do so either by
- * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
- * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
- */
-
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <linux/list.h>
-#include <linux/timer.h>
-#include <linux/workqueue.h>
-
-/*
- * USB HID (Human Interface Device) interface class code
- */
-
-#define USB_INTERFACE_CLASS_HID		3
-
-/*
- * USB HID interface subclass and protocol codes
- */
-
-#define USB_INTERFACE_SUBCLASS_BOOT	1
-#define USB_INTERFACE_PROTOCOL_KEYBOARD	1
-#define USB_INTERFACE_PROTOCOL_MOUSE	2
-
-/*
- * HID class requests
- */
-
-#define HID_REQ_GET_REPORT		0x01
-#define HID_REQ_GET_IDLE		0x02
-#define HID_REQ_GET_PROTOCOL		0x03
-#define HID_REQ_SET_REPORT		0x09
-#define HID_REQ_SET_IDLE		0x0A
-#define HID_REQ_SET_PROTOCOL		0x0B
-
-/*
- * HID class descriptor types
- */
-
-#define HID_DT_HID			(USB_TYPE_CLASS | 0x01)
-#define HID_DT_REPORT			(USB_TYPE_CLASS | 0x02)
-#define HID_DT_PHYSICAL			(USB_TYPE_CLASS | 0x03)
-
-/*
- * We parse each description item into this structure. Short items data
- * values are expanded to 32-bit signed int, long items contain a pointer
- * into the data area.
- */
-
-struct hid_item {
-	unsigned  format;
-	__u8      size;
-	__u8      type;
-	__u8      tag;
-	union {
-	    __u8   u8;
-	    __s8   s8;
-	    __u16  u16;
-	    __s16  s16;
-	    __u32  u32;
-	    __s32  s32;
-	    __u8  *longdata;
-	} data;
-};
-
-/*
- * HID report item format
- */
-
-#define HID_ITEM_FORMAT_SHORT	0
-#define HID_ITEM_FORMAT_LONG	1
-
-/*
- * Special tag indicating long items
- */
-
-#define HID_ITEM_TAG_LONG	15
-
-/*
- * HID report descriptor item type (prefix bit 2,3)
- */
-
-#define HID_ITEM_TYPE_MAIN		0
-#define HID_ITEM_TYPE_GLOBAL		1
-#define HID_ITEM_TYPE_LOCAL		2
-#define HID_ITEM_TYPE_RESERVED		3
-
-/*
- * HID report descriptor main item tags
- */
-
-#define HID_MAIN_ITEM_TAG_INPUT			8
-#define HID_MAIN_ITEM_TAG_OUTPUT		9
-#define HID_MAIN_ITEM_TAG_FEATURE		11
-#define HID_MAIN_ITEM_TAG_BEGIN_COLLECTION	10
-#define HID_MAIN_ITEM_TAG_END_COLLECTION	12
-
-/*
- * HID report descriptor main item contents
- */
-
-#define HID_MAIN_ITEM_CONSTANT		0x001
-#define HID_MAIN_ITEM_VARIABLE		0x002
-#define HID_MAIN_ITEM_RELATIVE		0x004
-#define HID_MAIN_ITEM_WRAP		0x008
-#define HID_MAIN_ITEM_NONLINEAR		0x010
-#define HID_MAIN_ITEM_NO_PREFERRED	0x020
-#define HID_MAIN_ITEM_NULL_STATE	0x040
-#define HID_MAIN_ITEM_VOLATILE		0x080
-#define HID_MAIN_ITEM_BUFFERED_BYTE	0x100
-
-/*
- * HID report descriptor collection item types
- */
-
-#define HID_COLLECTION_PHYSICAL		0
-#define HID_COLLECTION_APPLICATION	1
-#define HID_COLLECTION_LOGICAL		2
-
-/*
- * HID report descriptor global item tags
- */
-
-#define HID_GLOBAL_ITEM_TAG_USAGE_PAGE		0
-#define HID_GLOBAL_ITEM_TAG_LOGICAL_MINIMUM	1
-#define HID_GLOBAL_ITEM_TAG_LOGICAL_MAXIMUM	2
-#define HID_GLOBAL_ITEM_TAG_PHYSICAL_MINIMUM	3
-#define HID_GLOBAL_ITEM_TAG_PHYSICAL_MAXIMUM	4
-#define HID_GLOBAL_ITEM_TAG_UNIT_EXPONENT	5
-#define HID_GLOBAL_ITEM_TAG_UNIT		6
-#define HID_GLOBAL_ITEM_TAG_REPORT_SIZE		7
-#define HID_GLOBAL_ITEM_TAG_REPORT_ID		8
-#define HID_GLOBAL_ITEM_TAG_REPORT_COUNT	9
-#define HID_GLOBAL_ITEM_TAG_PUSH		10
-#define HID_GLOBAL_ITEM_TAG_POP			11
-
-/*
- * HID report descriptor local item tags
- */
-
-#define HID_LOCAL_ITEM_TAG_USAGE		0
-#define HID_LOCAL_ITEM_TAG_USAGE_MINIMUM	1
-#define HID_LOCAL_ITEM_TAG_USAGE_MAXIMUM	2
-#define HID_LOCAL_ITEM_TAG_DESIGNATOR_INDEX	3
-#define HID_LOCAL_ITEM_TAG_DESIGNATOR_MINIMUM	4
-#define HID_LOCAL_ITEM_TAG_DESIGNATOR_MAXIMUM	5
-#define HID_LOCAL_ITEM_TAG_STRING_INDEX		7
-#define HID_LOCAL_ITEM_TAG_STRING_MINIMUM	8
-#define HID_LOCAL_ITEM_TAG_STRING_MAXIMUM	9
-#define HID_LOCAL_ITEM_TAG_DELIMITER		10
-
-/*
- * HID usage tables
- */
-
-#define HID_USAGE_PAGE		0xffff0000
-
-#define HID_UP_UNDEFINED	0x00000000
-#define HID_UP_GENDESK		0x00010000
-#define HID_UP_SIMULATION	0x00020000
-#define HID_UP_KEYBOARD		0x00070000
-#define HID_UP_LED		0x00080000
-#define HID_UP_BUTTON		0x00090000
-#define HID_UP_ORDINAL		0x000a0000
-#define HID_UP_CONSUMER		0x000c0000
-#define HID_UP_DIGITIZER	0x000d0000
-#define HID_UP_PID		0x000f0000
-#define HID_UP_HPVENDOR         0xff7f0000
-#define HID_UP_MSVENDOR		0xff000000
-#define HID_UP_CUSTOM		0x00ff0000
-#define HID_UP_LOGIVENDOR	0xffbc0000
-
-#define HID_USAGE		0x0000ffff
-
-#define HID_GD_POINTER		0x00010001
-#define HID_GD_MOUSE		0x00010002
-#define HID_GD_JOYSTICK		0x00010004
-#define HID_GD_GAMEPAD		0x00010005
-#define HID_GD_KEYBOARD		0x00010006
-#define HID_GD_KEYPAD		0x00010007
-#define HID_GD_MULTIAXIS	0x00010008
-#define HID_GD_X		0x00010030
-#define HID_GD_Y		0x00010031
-#define HID_GD_Z		0x00010032
-#define HID_GD_RX		0x00010033
-#define HID_GD_RY		0x00010034
-#define HID_GD_RZ		0x00010035
-#define HID_GD_SLIDER		0x00010036
-#define HID_GD_DIAL		0x00010037
-#define HID_GD_WHEEL		0x00010038
-#define HID_GD_HATSWITCH	0x00010039
-#define HID_GD_BUFFER		0x0001003a
-#define HID_GD_BYTECOUNT	0x0001003b
-#define HID_GD_MOTION		0x0001003c
-#define HID_GD_START		0x0001003d
-#define HID_GD_SELECT		0x0001003e
-#define HID_GD_VX		0x00010040
-#define HID_GD_VY		0x00010041
-#define HID_GD_VZ		0x00010042
-#define HID_GD_VBRX		0x00010043
-#define HID_GD_VBRY		0x00010044
-#define HID_GD_VBRZ		0x00010045
-#define HID_GD_VNO		0x00010046
-#define HID_GD_FEATURE		0x00010047
-#define HID_GD_UP		0x00010090
-#define HID_GD_DOWN		0x00010091
-#define HID_GD_RIGHT		0x00010092
-#define HID_GD_LEFT		0x00010093
-
-/*
- * HID report types --- Ouch! HID spec says 1 2 3!
- */
-
-#define HID_INPUT_REPORT	0
-#define HID_OUTPUT_REPORT	1
-#define HID_FEATURE_REPORT	2
-
-/*
- * HID device quirks.
- */
-
-#define HID_QUIRK_INVERT			0x00000001
-#define HID_QUIRK_NOTOUCH			0x00000002
-#define HID_QUIRK_IGNORE			0x00000004
-#define HID_QUIRK_NOGET				0x00000008
-#define HID_QUIRK_HIDDEV			0x00000010
-#define HID_QUIRK_BADPAD			0x00000020
-#define HID_QUIRK_MULTI_INPUT			0x00000040
-#define HID_QUIRK_2WHEEL_MOUSE_HACK_7		0x00000080
-#define HID_QUIRK_2WHEEL_MOUSE_HACK_5		0x00000100
-#define HID_QUIRK_2WHEEL_MOUSE_HACK_ON		0x00000200
-#define HID_QUIRK_MIGHTYMOUSE			0x00000400
-#define HID_QUIRK_CYMOTION			0x00000800
-#define HID_QUIRK_POWERBOOK_HAS_FN		0x00001000
-#define HID_QUIRK_POWERBOOK_FN_ON		0x00002000
-#define HID_QUIRK_INVERT_HWHEEL			0x00004000
-#define HID_QUIRK_POWERBOOK_ISO_KEYBOARD	0x00008000
-#define HID_QUIRK_BAD_RELATIVE_KEYS		0x00010000
-
-/*
- * This is the global environment of the parser. This information is
- * persistent for main-items. The global environment can be saved and
- * restored with PUSH/POP statements.
- */
-
-struct hid_global {
-	unsigned usage_page;
-	__s32    logical_minimum;
-	__s32    logical_maximum;
-	__s32    physical_minimum;
-	__s32    physical_maximum;
-	__s32    unit_exponent;
-	unsigned unit;
-	unsigned report_id;
-	unsigned report_size;
-	unsigned report_count;
-};
-
-/*
- * This is the local environment. It is persistent up the next main-item.
- */
-
-#define HID_MAX_DESCRIPTOR_SIZE		4096
-#define HID_MAX_USAGES			1024
-#define HID_DEFAULT_NUM_COLLECTIONS	16
-
-struct hid_local {
-	unsigned usage[HID_MAX_USAGES]; /* usage array */
-	unsigned collection_index[HID_MAX_USAGES]; /* collection index array */
-	unsigned usage_index;
-	unsigned usage_minimum;
-	unsigned delimiter_depth;
-	unsigned delimiter_branch;
-};
-
-/*
- * This is the collection stack. We climb up the stack to determine
- * application and function of each field.
- */
-
-struct hid_collection {
-	unsigned type;
-	unsigned usage;
-	unsigned level;
-};
-
-struct hid_usage {
-	unsigned  hid;			/* hid usage code */
-	unsigned  collection_index;	/* index into collection array */
-	/* hidinput data */
-	__u16     code;			/* input driver code */
-	__u8      type;			/* input driver type */
-	__s8	  hat_min;		/* hat switch fun */
-	__s8	  hat_max;		/* ditto */
-	__s8	  hat_dir;		/* ditto */
-};
-
-struct hid_input;
-
-struct hid_field {
-	unsigned  physical;		/* physical usage for this field */
-	unsigned  logical;		/* logical usage for this field */
-	unsigned  application;		/* application usage for this field */
-	struct hid_usage *usage;	/* usage table for this function */
-	unsigned  maxusage;		/* maximum usage index */
-	unsigned  flags;		/* main-item flags (i.e. volatile,array,constant) */
-	unsigned  report_offset;	/* bit offset in the report */
-	unsigned  report_size;		/* size of this field in the report */
-	unsigned  report_count;		/* number of this field in the report */
-	unsigned  report_type;		/* (input,output,feature) */
-	__s32    *value;		/* last known value(s) */
-	__s32     logical_minimum;
-	__s32     logical_maximum;
-	__s32     physical_minimum;
-	__s32     physical_maximum;
-	__s32     unit_exponent;
-	unsigned  unit;
-	struct hid_report *report;	/* associated report */
-	unsigned index;			/* index into report->field[] */
-	/* hidinput data */
-	struct hid_input *hidinput;	/* associated input structure */
-	__u16 dpad;			/* dpad input code */
-};
-
-#define HID_MAX_FIELDS 64
-
-struct hid_report {
-	struct list_head list;
-	unsigned id;					/* id of this report */
-	unsigned type;					/* report type */
-	struct hid_field *field[HID_MAX_FIELDS];	/* fields of the report */
-	unsigned maxfield;				/* maximum valid field index */
-	unsigned size;					/* size of the report (bits) */
-	struct hid_device *device;			/* associated device */
-};
-
-struct hid_report_enum {
-	unsigned numbered;
-	struct list_head report_list;
-	struct hid_report *report_id_hash[256];
-};
-
-#define HID_REPORT_TYPES 3
-
-#define HID_MIN_BUFFER_SIZE	64		/* make sure there is at least a packet size of space */
-#define HID_MAX_BUFFER_SIZE	4096		/* 4kb */
-#define HID_CONTROL_FIFO_SIZE	256		/* to init devices with >100 reports */
-#define HID_OUTPUT_FIFO_SIZE	64
-
-struct hid_control_fifo {
-	unsigned char dir;
-	struct hid_report *report;
-};
-
-#define HID_CLAIMED_INPUT	1
-#define HID_CLAIMED_HIDDEV	2
-
-#define HID_CTRL_RUNNING	1
-#define HID_OUT_RUNNING		2
-#define HID_IN_RUNNING		3
-#define HID_RESET_PENDING	4
-#define HID_SUSPENDED		5
-#define HID_CLEAR_HALT		6
-
-struct hid_input {
-	struct list_head list;
-	struct hid_report *report;
-	struct input_dev *input;
-};
-
-struct hid_device {							/* device report descriptor */
-	 __u8 *rdesc;
-	unsigned rsize;
-	struct hid_collection *collection;				/* List of HID collections */
-	unsigned collection_size;					/* Number of allocated hid_collections */
-	unsigned maxcollection;						/* Number of parsed collections */
-	unsigned maxapplication;					/* Number of applications */
-	unsigned version;						/* HID version */
-	unsigned country;						/* HID country */
-	struct hid_report_enum report_enum[HID_REPORT_TYPES];
-
-	struct usb_device *dev;						/* USB device */
-	struct usb_interface *intf;					/* USB interface */
-	int ifnum;							/* USB interface number */
-
-	unsigned long iofl;						/* I/O flags (CTRL_RUNNING, OUT_RUNNING) */
-	struct timer_list io_retry;					/* Retry timer */
-	unsigned long stop_retry;					/* Time to give up, in jiffies */
-	unsigned int retry_delay;					/* Delay length in ms */
-	struct work_struct reset_work;					/* Task context for resets */
-
-	unsigned int bufsize;						/* URB buffer size */
-
-	struct urb *urbin;						/* Input URB */
-	char *inbuf;							/* Input buffer */
-	dma_addr_t inbuf_dma;						/* Input buffer dma */
-	spinlock_t inlock;						/* Input fifo spinlock */
-
-	struct urb *urbctrl;						/* Control URB */
-	struct usb_ctrlrequest *cr;					/* Control request struct */
-	dma_addr_t cr_dma;						/* Control request struct dma */
-	struct hid_control_fifo ctrl[HID_CONTROL_FIFO_SIZE];		/* Control fifo */
-	unsigned char ctrlhead, ctrltail;				/* Control fifo head & tail */
-	char *ctrlbuf;							/* Control buffer */
-	dma_addr_t ctrlbuf_dma;						/* Control buffer dma */
-	spinlock_t ctrllock;						/* Control fifo spinlock */
-
-	struct urb *urbout;						/* Output URB */
-	struct hid_report *out[HID_CONTROL_FIFO_SIZE];			/* Output pipe fifo */
-	unsigned char outhead, outtail;					/* Output pipe fifo head & tail */
-	char *outbuf;							/* Output buffer */
-	dma_addr_t outbuf_dma;						/* Output buffer dma */
-	spinlock_t outlock;						/* Output fifo spinlock */
-
-	unsigned claimed;						/* Claimed by hidinput, hiddev? */
-	unsigned quirks;						/* Various quirks the device can pull on us */
-
-	struct list_head inputs;					/* The list of inputs */
-	void *hiddev;							/* The hiddev structure */
-	int minor;							/* Hiddev minor number */
-
-	wait_queue_head_t wait;						/* For sleeping */
-
-	int open;							/* is the device open by anyone? */
-	char name[128];							/* Device name */
-	char phys[64];							/* Device physical location */
-	char uniq[64];							/* Device unique identifier (serial #) */
-
-#ifdef CONFIG_USB_HIDINPUT_POWERBOOK
-	unsigned long pb_pressed_fn[NBITS(KEY_MAX)];
-	unsigned long pb_pressed_numlock[NBITS(KEY_MAX)];
-#endif
-};
-
-#define HID_GLOBAL_STACK_SIZE 4
-#define HID_COLLECTION_STACK_SIZE 4
-
-struct hid_parser {
-	struct hid_global     global;
-	struct hid_global     global_stack[HID_GLOBAL_STACK_SIZE];
-	unsigned              global_stack_ptr;
-	struct hid_local      local;
-	unsigned              collection_stack[HID_COLLECTION_STACK_SIZE];
-	unsigned              collection_stack_ptr;
-	struct hid_device    *device;
-};
-
-struct hid_class_descriptor {
-	__u8  bDescriptorType;
-	__u16 wDescriptorLength;
-} __attribute__ ((packed));
-
-struct hid_descriptor {
-	__u8  bLength;
-	__u8  bDescriptorType;
-	__u16 bcdHID;
-	__u8  bCountryCode;
-	__u8  bNumDescriptors;
-
-	struct hid_class_descriptor desc[1];
-} __attribute__ ((packed));
-
-#ifdef DEBUG
-#include "hid-debug.h"
-#else
-#define hid_dump_input(a,b)	do { } while (0)
-#define hid_dump_device(c)	do { } while (0)
-#define hid_dump_field(a,b)	do { } while (0)
-#define resolv_usage(a)		do { } while (0)
-#define resolv_event(a,b)	do { } while (0)
-#endif
-
-#endif
-
-#ifdef CONFIG_USB_HIDINPUT
-/* Applications from HID Usage Tables 4/8/99 Version 1.1 */
-/* We ignore a few input applications that are not widely used */
-#define IS_INPUT_APPLICATION(a) (((a >= 0x00010000) && (a <= 0x00010008)) || (a == 0x00010080) || (a == 0x000c0001))
-extern void hidinput_hid_event(struct hid_device *, struct hid_field *, struct hid_usage *, __s32);
-extern void hidinput_report_event(struct hid_device *hid, struct hid_report *report);
-extern int hidinput_connect(struct hid_device *);
-extern void hidinput_disconnect(struct hid_device *);
-#else
-#define IS_INPUT_APPLICATION(a) (0)
-static inline void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct hid_usage *usage, __s32 value) { }
-static inline void hidinput_report_event(struct hid_device *hid, struct hid_report *report) { }
-static inline int hidinput_connect(struct hid_device *hid) { return -ENODEV; }
-static inline void hidinput_disconnect(struct hid_device *hid) { }
-#endif
-
-int hid_open(struct hid_device *);
-void hid_close(struct hid_device *);
-int hid_set_field(struct hid_field *, unsigned, __s32);
-void hid_submit_report(struct hid_device *, struct hid_report *, unsigned char dir);
-void hid_init_reports(struct hid_device *hid);
-int hid_wait_io(struct hid_device* hid);
-
-
-#ifdef CONFIG_HID_FF
-int hid_ff_init(struct hid_device *hid);
-
-int hid_lgff_init(struct hid_device *hid);
-int hid_tmff_init(struct hid_device *hid);
-int hid_zpff_init(struct hid_device *hid);
-#ifdef CONFIG_HID_PID
-int hid_pidff_init(struct hid_device *hid);
-#else
-static inline int hid_pidff_init(struct hid_device *hid) { return -ENODEV; }
-#endif
-
-#else
-static inline int hid_ff_init(struct hid_device *hid) { return -1; }
-#endif
-
diff --git a/drivers/usb/input/hiddev.c b/drivers/usb/input/hiddev.c
index 7dc14d0cacc1..114d6c9f64b1 100644
--- a/drivers/usb/input/hiddev.c
+++ b/drivers/usb/input/hiddev.c
@@ -32,8 +32,9 @@
 #include <linux/smp_lock.h>
 #include <linux/input.h>
 #include <linux/usb.h>
-#include "hid.h"
+#include <linux/hid.h>
 #include <linux/hiddev.h>
+#include "usbhid.h"
 
 #ifdef CONFIG_USB_DYNAMIC_MINORS
 #define HIDDEV_MINOR_BASE	0
@@ -196,7 +197,7 @@ void hiddev_hid_event(struct hid_device *hid, struct hid_field *field,
 
 	hiddev_send_event(hid, &uref);
 }
-
+EXPORT_SYMBOL_GPL(hiddev_hid_event);
 
 void hiddev_report_event(struct hid_device *hid, struct hid_report *report)
 {
@@ -213,6 +214,7 @@ void hiddev_report_event(struct hid_device *hid, struct hid_report *report)
 
 	hiddev_send_event(hid, &uref);
 }
+
 /*
  * fasync file op
  */
@@ -239,7 +241,7 @@ static int hiddev_release(struct inode * inode, struct file * file)
 
 	if (!--list->hiddev->open) {
 		if (list->hiddev->exist)
-			hid_close(list->hiddev->hid);
+			usbhid_close(list->hiddev->hid);
 		else
 			kfree(list->hiddev);
 	}
@@ -270,7 +272,7 @@ static int hiddev_open(struct inode *inode, struct file *file)
 
 	if (!list->hiddev->open++)
 		if (list->hiddev->exist)
-			hid_open(hiddev_table[i]->hid);
+			usbhid_open(hiddev_table[i]->hid);
 
 	return 0;
 }
@@ -382,7 +384,7 @@ static int hiddev_ioctl(struct inode *inode, struct file *file, unsigned int cmd
 	struct hiddev_list *list = file->private_data;
 	struct hiddev *hiddev = list->hiddev;
 	struct hid_device *hid = hiddev->hid;
-	struct usb_device *dev = hid->dev;
+	struct usb_device *dev = to_usb_device(hid->dev);
 	struct hiddev_collection_info cinfo;
 	struct hiddev_report_info rinfo;
 	struct hiddev_field_info finfo;
@@ -391,6 +393,7 @@ static int hiddev_ioctl(struct inode *inode, struct file *file, unsigned int cmd
 	struct hiddev_devinfo dinfo;
 	struct hid_report *report;
 	struct hid_field *field;
+	struct usbhid_device *usbhid = hid->driver_data;
 	void __user *user_arg = (void __user *)arg;
 	int i;
 
@@ -420,7 +423,7 @@ static int hiddev_ioctl(struct inode *inode, struct file *file, unsigned int cmd
 		dinfo.bustype = BUS_USB;
 		dinfo.busnum = dev->bus->busnum;
 		dinfo.devnum = dev->devnum;
-		dinfo.ifnum = hid->ifnum;
+		dinfo.ifnum = usbhid->ifnum;
 		dinfo.vendor = le16_to_cpu(dev->descriptor.idVendor);
 		dinfo.product = le16_to_cpu(dev->descriptor.idProduct);
 		dinfo.version = le16_to_cpu(dev->descriptor.bcdDevice);
@@ -479,7 +482,7 @@ static int hiddev_ioctl(struct inode *inode, struct file *file, unsigned int cmd
 		}
 
 	case HIDIOCINITREPORT:
-		hid_init_reports(hid);
+		usbhid_init_reports(hid);
 
 		return 0;
 
@@ -493,8 +496,8 @@ static int hiddev_ioctl(struct inode *inode, struct file *file, unsigned int cmd
 		if ((report = hiddev_lookup_report(hid, &rinfo)) == NULL)
 			return -EINVAL;
 
-		hid_submit_report(hid, report, USB_DIR_IN);
-		hid_wait_io(hid);
+		usbhid_submit_report(hid, report, USB_DIR_IN);
+		usbhid_wait_io(hid);
 
 		return 0;
 
@@ -508,8 +511,8 @@ static int hiddev_ioctl(struct inode *inode, struct file *file, unsigned int cmd
 		if ((report = hiddev_lookup_report(hid, &rinfo)) == NULL)
 			return -EINVAL;
 
-		hid_submit_report(hid, report, USB_DIR_OUT);
-		hid_wait_io(hid);
+		usbhid_submit_report(hid, report, USB_DIR_OUT);
+		usbhid_wait_io(hid);
 
 		return 0;
 
@@ -745,6 +748,7 @@ static struct usb_class_driver hiddev_class = {
 int hiddev_connect(struct hid_device *hid)
 {
 	struct hiddev *hiddev;
+	struct usbhid_device *usbhid = hid->driver_data;
 	int i;
 	int retval;
 
@@ -760,7 +764,7 @@ int hiddev_connect(struct hid_device *hid)
 	if (!(hiddev = kzalloc(sizeof(struct hiddev), GFP_KERNEL)))
 		return -1;
 
-	retval = usb_register_dev(hid->intf, &hiddev_class);
+	retval = usb_register_dev(usbhid->intf, &hiddev_class);
 	if (retval) {
 		err("Not able to get a minor for this device.");
 		kfree(hiddev);
@@ -772,10 +776,10 @@ int hiddev_connect(struct hid_device *hid)
 	hiddev->hid = hid;
 	hiddev->exist = 1;
 
-	hid->minor = hid->intf->minor;
+	hid->minor = usbhid->intf->minor;
 	hid->hiddev = hiddev;
 
-	hiddev_table[hid->intf->minor - HIDDEV_MINOR_BASE] = hiddev;
+	hiddev_table[usbhid->intf->minor - HIDDEV_MINOR_BASE] = hiddev;
 
 	return 0;
 }
@@ -788,14 +792,15 @@ static struct usb_class_driver hiddev_class;
 void hiddev_disconnect(struct hid_device *hid)
 {
 	struct hiddev *hiddev = hid->hiddev;
+	struct usbhid_device *usbhid = hid->driver_data;
 
 	hiddev->exist = 0;
 
 	hiddev_table[hiddev->hid->minor - HIDDEV_MINOR_BASE] = NULL;
-	usb_deregister_dev(hiddev->hid->intf, &hiddev_class);
+	usb_deregister_dev(usbhid->intf, &hiddev_class);
 
 	if (hiddev->open) {
-		hid_close(hiddev->hid);
+		usbhid_close(hiddev->hid);
 		wake_up_interruptible(&hiddev->wait);
 	} else {
 		kfree(hiddev);
diff --git a/drivers/usb/input/usbhid.h b/drivers/usb/input/usbhid.h
new file mode 100644
index 000000000000..830107e5251f
--- /dev/null
+++ b/drivers/usb/input/usbhid.h
@@ -0,0 +1,84 @@
+#ifndef __USBHID_H
+#define __USBHID_H
+
+/*
+ *  Copyright (c) 1999 Andreas Gal
+ *  Copyright (c) 2000-2001 Vojtech Pavlik
+ *  Copyright (c) 2006 Jiri Kosina
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/workqueue.h>
+#include <linux/input.h>
+
+/*  API provided by hid-core.c for USB HID drivers */
+int usbhid_wait_io(struct hid_device* hid);
+void usbhid_close(struct hid_device *hid);
+int usbhid_open(struct hid_device *hid);
+void usbhid_init_reports(struct hid_device *hid);
+void usbhid_submit_report(struct hid_device *hid, struct hid_report *report, unsigned char dir);
+
+/*
+ * USB-specific HID struct, to be pointed to
+ * from struct hid_device->driver_data
+ */
+
+struct usbhid_device {
+	struct hid_device *hid;						/* pointer to corresponding HID dev */
+
+	struct usb_interface *intf;                                     /* USB interface */
+	int ifnum;                                                      /* USB interface number */
+
+	unsigned int bufsize;                                           /* URB buffer size */
+
+	struct urb *urbin;                                              /* Input URB */
+	char *inbuf;                                                    /* Input buffer */
+	dma_addr_t inbuf_dma;                                           /* Input buffer dma */
+	spinlock_t inlock;                                              /* Input fifo spinlock */
+
+	struct urb *urbctrl;                                            /* Control URB */
+	struct usb_ctrlrequest *cr;                                     /* Control request struct */
+	dma_addr_t cr_dma;                                              /* Control request struct dma */
+	struct hid_control_fifo ctrl[HID_CONTROL_FIFO_SIZE];  		/* Control fifo */
+	unsigned char ctrlhead, ctrltail;                               /* Control fifo head & tail */
+	char *ctrlbuf;                                                  /* Control buffer */
+	dma_addr_t ctrlbuf_dma;                                         /* Control buffer dma */
+	spinlock_t ctrllock;                                            /* Control fifo spinlock */
+
+	struct urb *urbout;                                             /* Output URB */
+	struct hid_report *out[HID_CONTROL_FIFO_SIZE];                  /* Output pipe fifo */
+	unsigned char outhead, outtail;                                 /* Output pipe fifo head & tail */
+	char *outbuf;                                                   /* Output buffer */
+	dma_addr_t outbuf_dma;                                          /* Output buffer dma */
+	spinlock_t outlock;                                             /* Output fifo spinlock */
+
+	unsigned long iofl;                                             /* I/O flags (CTRL_RUNNING, OUT_RUNNING) */
+	struct timer_list io_retry;                                     /* Retry timer */
+	unsigned long stop_retry;                                       /* Time to give up, in jiffies */
+	unsigned int retry_delay;                                       /* Delay length in ms */
+	struct work_struct reset_work;                                  /* Task context for resets */
+
+};
+
+#endif
+
diff --git a/drivers/usb/misc/sisusbvga/sisusb.c b/drivers/usb/misc/sisusbvga/sisusb.c
index b99ca9c79821..0398908b15d4 100644
--- a/drivers/usb/misc/sisusbvga/sisusb.c
+++ b/drivers/usb/misc/sisusbvga/sisusb.c
@@ -3168,7 +3168,7 @@ sisusb_compat_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
 		case SISUSB_GET_CONFIG:
 		case SISUSB_COMMAND:
 			lock_kernel();
-			retval = sisusb_ioctl(f->f_dentry->d_inode, f, cmd, arg);
+			retval = sisusb_ioctl(f->f_path.dentry->d_inode, f, cmd, arg);
 			unlock_kernel();
 			return retval;
 
diff --git a/drivers/usb/serial/ark3116.c b/drivers/usb/serial/ark3116.c
index 863966c1c5ac..5261cd22ee6b 100644
--- a/drivers/usb/serial/ark3116.c
+++ b/drivers/usb/serial/ark3116.c
@@ -156,7 +156,7 @@ cleanup:
 }
 
 static void ark3116_set_termios(struct usb_serial_port *port,
-				struct termios *old_termios)
+				struct ktermios *old_termios)
 {
 	struct usb_serial *serial = port->serial;
 	struct ark3116_private *priv = usb_get_serial_port_data(port);
@@ -326,7 +326,7 @@ static void ark3116_set_termios(struct usb_serial_port *port,
 
 static int ark3116_open(struct usb_serial_port *port, struct file *filp)
 {
-	struct termios tmp_termios;
+	struct ktermios tmp_termios;
 	struct usb_serial *serial = port->serial;
 	char *buf;
 	int result = 0;
diff --git a/drivers/usb/serial/belkin_sa.c b/drivers/usb/serial/belkin_sa.c
index 8835bb58ca9b..38b4dae319ee 100644
--- a/drivers/usb/serial/belkin_sa.c
+++ b/drivers/usb/serial/belkin_sa.c
@@ -92,7 +92,7 @@ static void belkin_sa_shutdown		(struct usb_serial *serial);
 static int  belkin_sa_open		(struct usb_serial_port *port, struct file *filp);
 static void belkin_sa_close		(struct usb_serial_port *port, struct file *filp);
 static void belkin_sa_read_int_callback (struct urb *urb);
-static void belkin_sa_set_termios	(struct usb_serial_port *port, struct termios * old);
+static void belkin_sa_set_termios	(struct usb_serial_port *port, struct ktermios * old);
 static int  belkin_sa_ioctl		(struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg);
 static void belkin_sa_break_ctl		(struct usb_serial_port *port, int break_state );
 static int  belkin_sa_tiocmget		(struct usb_serial_port *port, struct file *file);
@@ -333,7 +333,7 @@ exit:
 		     __FUNCTION__, retval);
 }
 
-static void belkin_sa_set_termios (struct usb_serial_port *port, struct termios *old_termios)
+static void belkin_sa_set_termios (struct usb_serial_port *port, struct ktermios *old_termios)
 {
 	struct usb_serial *serial = port->serial;
 	struct belkin_sa_private *priv = usb_get_serial_port_data(port);
diff --git a/drivers/usb/serial/console.c b/drivers/usb/serial/console.c
index 7167728d764c..9386e216d681 100644
--- a/drivers/usb/serial/console.c
+++ b/drivers/usb/serial/console.c
@@ -65,7 +65,7 @@ static int usb_console_setup(struct console *co, char *options)
 	struct usb_serial_port *port;
 	int retval = 0;
 	struct tty_struct *tty;
-	struct termios *termios;
+	struct ktermios *termios;
 
 	dbg ("%s", __FUNCTION__);
 
diff --git a/drivers/usb/serial/cp2101.c b/drivers/usb/serial/cp2101.c
index f95d42c0d16a..2f9b7ac32663 100644
--- a/drivers/usb/serial/cp2101.c
+++ b/drivers/usb/serial/cp2101.c
@@ -41,7 +41,7 @@ static int cp2101_open(struct usb_serial_port*, struct file*);
 static void cp2101_cleanup(struct usb_serial_port*);
 static void cp2101_close(struct usb_serial_port*, struct file*);
 static void cp2101_get_termios(struct usb_serial_port*);
-static void cp2101_set_termios(struct usb_serial_port*, struct termios*);
+static void cp2101_set_termios(struct usb_serial_port*, struct ktermios*);
 static int cp2101_tiocmget (struct usb_serial_port *, struct file *);
 static int cp2101_tiocmset (struct usb_serial_port *, struct file *,
 		unsigned int, unsigned int);
@@ -506,7 +506,7 @@ static void cp2101_get_termios (struct usb_serial_port *port)
 }
 
 static void cp2101_set_termios (struct usb_serial_port *port,
-		struct termios *old_termios)
+		struct ktermios *old_termios)
 {
 	unsigned int cflag, old_cflag=0;
 	int baud=0, bits;
diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c
index 093f303b3189..a1fdb85b8c0a 100644
--- a/drivers/usb/serial/cypress_m8.c
+++ b/drivers/usb/serial/cypress_m8.c
@@ -143,7 +143,7 @@ struct cypress_private {
 	wait_queue_head_t delta_msr_wait;  /* used for TIOCMIWAIT */
 	char prev_status, diff_status;	   /* used for TIOCMIWAIT */
 	/* we pass a pointer to this as the arguement sent to cypress_set_termios old_termios */
-	struct termios tmp_termios; 	   /* stores the old termios settings */
+	struct ktermios tmp_termios; 	   /* stores the old termios settings */
 };
 
 /* write buffer structure */
@@ -165,7 +165,7 @@ static int  cypress_write		(struct usb_serial_port *port, const unsigned char *b
 static void cypress_send		(struct usb_serial_port *port);
 static int  cypress_write_room		(struct usb_serial_port *port);
 static int  cypress_ioctl		(struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg);
-static void cypress_set_termios		(struct usb_serial_port *port, struct termios * old);
+static void cypress_set_termios		(struct usb_serial_port *port, struct ktermios * old);
 static int  cypress_tiocmget		(struct usb_serial_port *port, struct file *file);
 static int  cypress_tiocmset		(struct usb_serial_port *port, struct file *file, unsigned int set, unsigned int clear);
 static int  cypress_chars_in_buffer	(struct usb_serial_port *port);
@@ -949,13 +949,13 @@ static int cypress_ioctl (struct usb_serial_port *port, struct file * file, unsi
 
 	switch (cmd) {
 		case TIOCGSERIAL:
-			if (copy_to_user((void __user *)arg, port->tty->termios, sizeof(struct termios))) {
+			if (copy_to_user((void __user *)arg, port->tty->termios, sizeof(struct ktermios))) {
 				return -EFAULT;
 			}
 			return (0);
 			break;
 		case TIOCSSERIAL:
-			if (copy_from_user(port->tty->termios, (void __user *)arg, sizeof(struct termios))) {
+			if (copy_from_user(port->tty->termios, (void __user *)arg, sizeof(struct ktermios))) {
 				return -EFAULT;
 			}
 			/* here we need to call cypress_set_termios to invoke the new settings */
@@ -1019,7 +1019,7 @@ static int cypress_ioctl (struct usb_serial_port *port, struct file * file, unsi
 
 
 static void cypress_set_termios (struct usb_serial_port *port,
-		struct termios *old_termios)
+		struct ktermios *old_termios)
 {
 	struct cypress_private *priv = usb_get_serial_port_data(port);
 	struct tty_struct *tty;
diff --git a/drivers/usb/serial/digi_acceleport.c b/drivers/usb/serial/digi_acceleport.c
index 83d0e21145b0..9d9ea874639c 100644
--- a/drivers/usb/serial/digi_acceleport.c
+++ b/drivers/usb/serial/digi_acceleport.c
@@ -449,7 +449,7 @@ static int digi_transmit_idle( struct usb_serial_port *port,
 static void digi_rx_throttle (struct usb_serial_port *port);
 static void digi_rx_unthrottle (struct usb_serial_port *port);
 static void digi_set_termios( struct usb_serial_port *port, 
-	struct termios *old_termios );
+	struct ktermios *old_termios );
 static void digi_break_ctl( struct usb_serial_port *port, int break_state );
 static int digi_ioctl( struct usb_serial_port *port, struct file *file,
 	unsigned int cmd, unsigned long arg );
@@ -976,7 +976,7 @@ dbg( "digi_rx_unthrottle: TOP: port=%d", priv->dp_port_num );
 
 
 static void digi_set_termios( struct usb_serial_port *port, 
-	struct termios *old_termios )
+	struct ktermios *old_termios )
 {
 
 	struct digi_port *priv = usb_get_serial_port_data(port);
@@ -1463,7 +1463,7 @@ static int digi_open( struct usb_serial_port *port, struct file *filp )
 	int ret;
 	unsigned char buf[32];
 	struct digi_port *priv = usb_get_serial_port_data(port);
-	struct termios not_termios;
+	struct ktermios not_termios;
 	unsigned long flags = 0;
 
 
diff --git a/drivers/usb/serial/empeg.c b/drivers/usb/serial/empeg.c
index 4ce10a831953..92beeb19795f 100644
--- a/drivers/usb/serial/empeg.c
+++ b/drivers/usb/serial/empeg.c
@@ -92,7 +92,7 @@ static int  empeg_ioctl			(struct usb_serial_port *port,
 					struct file * file,
 					unsigned int cmd,
 					unsigned long arg);
-static void empeg_set_termios		(struct usb_serial_port *port, struct termios *old_termios);
+static void empeg_set_termios		(struct usb_serial_port *port, struct ktermios *old_termios);
 static void empeg_write_bulk_callback	(struct urb *urb);
 static void empeg_read_bulk_callback	(struct urb *urb);
 
@@ -442,7 +442,7 @@ static int empeg_ioctl (struct usb_serial_port *port, struct file * file, unsign
 }
 
 
-static void empeg_set_termios (struct usb_serial_port *port, struct termios *old_termios)
+static void empeg_set_termios (struct usb_serial_port *port, struct ktermios *old_termios)
 {
 
 	dbg("%s - port %d", __FUNCTION__, port->number);
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
index 72e4d48f51e9..41b0ad2d56ac 100644
--- a/drivers/usb/serial/ftdi_sio.c
+++ b/drivers/usb/serial/ftdi_sio.c
@@ -595,7 +595,7 @@ static int  ftdi_chars_in_buffer	(struct usb_serial_port *port);
 static void ftdi_write_bulk_callback	(struct urb *urb);
 static void ftdi_read_bulk_callback	(struct urb *urb);
 static void ftdi_process_read		(struct work_struct *work);
-static void ftdi_set_termios		(struct usb_serial_port *port, struct termios * old);
+static void ftdi_set_termios		(struct usb_serial_port *port, struct ktermios * old);
 static int  ftdi_tiocmget               (struct usb_serial_port *port, struct file *file);
 static int  ftdi_tiocmset		(struct usb_serial_port *port, struct file * file, unsigned int set, unsigned int clear);
 static int  ftdi_ioctl			(struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg);
@@ -1880,7 +1880,7 @@ static void ftdi_break_ctl( struct usb_serial_port *port, int break_state )
  * WARNING: set_termios calls this with old_termios in kernel space
  */
 
-static void ftdi_set_termios (struct usb_serial_port *port, struct termios *old_termios)
+static void ftdi_set_termios (struct usb_serial_port *port, struct ktermios *old_termios)
 { /* ftdi_termios */
 	struct usb_device *dev = port->serial->dev;
 	unsigned int cflag = port->tty->termios->c_cflag;
diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c
index d06547a13f28..f623d58370a4 100644
--- a/drivers/usb/serial/io_edgeport.c
+++ b/drivers/usb/serial/io_edgeport.c
@@ -229,7 +229,7 @@ static int  edge_write_room		(struct usb_serial_port *port);
 static int  edge_chars_in_buffer	(struct usb_serial_port *port);
 static void edge_throttle		(struct usb_serial_port *port);
 static void edge_unthrottle		(struct usb_serial_port *port);
-static void edge_set_termios		(struct usb_serial_port *port, struct termios *old_termios);
+static void edge_set_termios		(struct usb_serial_port *port, struct ktermios *old_termios);
 static int  edge_ioctl			(struct usb_serial_port *port, struct file *file, unsigned int cmd, unsigned long arg);
 static void edge_break			(struct usb_serial_port *port, int break_state);
 static int  edge_tiocmget		(struct usb_serial_port *port, struct file *file);
@@ -257,7 +257,7 @@ static void handle_new_lsr		(struct edgeport_port *edge_port, __u8 lsrData, __u8
 static int  send_iosp_ext_cmd		(struct edgeport_port *edge_port, __u8 command, __u8 param);
 static int  calc_baud_rate_divisor	(int baud_rate, int *divisor);
 static int  send_cmd_write_baud_rate	(struct edgeport_port *edge_port, int baudRate);
-static void change_port_settings	(struct edgeport_port *edge_port, struct termios *old_termios);
+static void change_port_settings	(struct edgeport_port *edge_port, struct ktermios *old_termios);
 static int  send_cmd_write_uart_register	(struct edgeport_port *edge_port, __u8 regNum, __u8 regValue);
 static int  write_cmd_usb		(struct edgeport_port *edge_port, unsigned char *buffer, int writeLength);
 static void send_more_port_data		(struct edgeport_serial *edge_serial, struct edgeport_port *edge_port);
@@ -1431,7 +1431,7 @@ static void edge_unthrottle (struct usb_serial_port *port)
  * SerialSetTermios
  *	this function is called by the tty driver when it wants to change the termios structure
  *****************************************************************************/
-static void edge_set_termios (struct usb_serial_port *port, struct termios *old_termios)
+static void edge_set_termios (struct usb_serial_port *port, struct ktermios *old_termios)
 {
 	struct edgeport_port *edge_port = usb_get_serial_port_data(port);
 	struct tty_struct *tty = port->tty;
@@ -2412,7 +2412,7 @@ static int send_cmd_write_uart_register (struct edgeport_port *edge_port, __u8 r
 #ifndef CMSPAR
 #define CMSPAR 0
 #endif
-static void change_port_settings (struct edgeport_port *edge_port, struct termios *old_termios)
+static void change_port_settings (struct edgeport_port *edge_port, struct ktermios *old_termios)
 {
 	struct tty_struct *tty;
 	int baud;
diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c
index ee0c921e1520..2da2684e0809 100644
--- a/drivers/usb/serial/io_ti.c
+++ b/drivers/usb/serial/io_ti.c
@@ -238,7 +238,7 @@ static void edge_tty_recv(struct device *dev, struct tty_struct *tty, unsigned c
 static void stop_read(struct edgeport_port *edge_port);
 static int restart_read(struct edgeport_port *edge_port);
 
-static void edge_set_termios (struct usb_serial_port *port, struct termios *old_termios);
+static void edge_set_termios (struct usb_serial_port *port, struct ktermios *old_termios);
 static void edge_send(struct usb_serial_port *port);
 
 /* circular buffer */
@@ -2361,7 +2361,7 @@ static int restart_read(struct edgeport_port *edge_port)
 	return status;
 }
 
-static void change_port_settings (struct edgeport_port *edge_port, struct termios *old_termios)
+static void change_port_settings (struct edgeport_port *edge_port, struct ktermios *old_termios)
 {
 	struct ump_uart_config *config;
 	struct tty_struct *tty;
@@ -2512,7 +2512,7 @@ static void change_port_settings (struct edgeport_port *edge_port, struct termio
 	return;
 }
 
-static void edge_set_termios (struct usb_serial_port *port, struct termios *old_termios)
+static void edge_set_termios (struct usb_serial_port *port, struct ktermios *old_termios)
 {
 	struct edgeport_port *edge_port = usb_get_serial_port_data(port);
 	struct tty_struct *tty = port->tty;
diff --git a/drivers/usb/serial/ir-usb.c b/drivers/usb/serial/ir-usb.c
index 331bf81556fc..8fdf486e3465 100644
--- a/drivers/usb/serial/ir-usb.c
+++ b/drivers/usb/serial/ir-usb.c
@@ -107,7 +107,7 @@ static void ir_close (struct usb_serial_port *port, struct file *filep);
 static int  ir_write (struct usb_serial_port *port, const unsigned char *buf, int count);
 static void ir_write_bulk_callback (struct urb *urb);
 static void ir_read_bulk_callback (struct urb *urb);
-static void ir_set_termios (struct usb_serial_port *port, struct termios *old_termios);
+static void ir_set_termios (struct usb_serial_port *port, struct ktermios *old_termios);
 
 static u8 ir_baud = 0;
 static u8 ir_xbof = 0;
@@ -497,7 +497,7 @@ static void ir_read_bulk_callback (struct urb *urb)
 	return;
 }
 
-static void ir_set_termios (struct usb_serial_port *port, struct termios *old_termios)
+static void ir_set_termios (struct usb_serial_port *port, struct ktermios *old_termios)
 {
 	unsigned char *transfer_buffer;
 	unsigned int cflag;
diff --git a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c
index 7639652cec42..9d2fdfd6865f 100644
--- a/drivers/usb/serial/keyspan.c
+++ b/drivers/usb/serial/keyspan.c
@@ -264,7 +264,7 @@ static void keyspan_break_ctl (struct usb_serial_port *port, int break_state)
 
 
 static void keyspan_set_termios (struct usb_serial_port *port, 
-				     struct termios *old_termios)
+				     struct ktermios *old_termios)
 {
 	int				baud_rate, device_port;
 	struct keyspan_port_private 	*p_priv;
diff --git a/drivers/usb/serial/keyspan.h b/drivers/usb/serial/keyspan.h
index 7472ed6bf626..6413d73c139c 100644
--- a/drivers/usb/serial/keyspan.h
+++ b/drivers/usb/serial/keyspan.h
@@ -59,7 +59,7 @@ static int  keyspan_ioctl		(struct usb_serial_port *port,
 					 unsigned int cmd,
 					 unsigned long arg);
 static void keyspan_set_termios		(struct usb_serial_port *port,
-					 struct termios *old);
+					 struct ktermios *old);
 static void keyspan_break_ctl		(struct usb_serial_port *port,
 					 int break_state);
 static int  keyspan_tiocmget		(struct usb_serial_port *port,
diff --git a/drivers/usb/serial/keyspan_pda.c b/drivers/usb/serial/keyspan_pda.c
index e09a0bfe6231..126b9703bbaf 100644
--- a/drivers/usb/serial/keyspan_pda.c
+++ b/drivers/usb/serial/keyspan_pda.c
@@ -365,7 +365,7 @@ static void keyspan_pda_break_ctl (struct usb_serial_port *port, int break_state
 
 
 static void keyspan_pda_set_termios (struct usb_serial_port *port, 
-				     struct termios *old_termios)
+				     struct ktermios *old_termios)
 {
 	struct usb_serial *serial = port->serial;
 	unsigned int cflag = port->tty->termios->c_cflag;
diff --git a/drivers/usb/serial/kl5kusb105.c b/drivers/usb/serial/kl5kusb105.c
index 17e205699c2b..73d755df4840 100644
--- a/drivers/usb/serial/kl5kusb105.c
+++ b/drivers/usb/serial/kl5kusb105.c
@@ -86,7 +86,7 @@ static int  klsi_105_write_room          (struct usb_serial_port *port);
 
 static void klsi_105_read_bulk_callback  (struct urb *urb);
 static void klsi_105_set_termios         (struct usb_serial_port *port,
-					  struct termios * old);
+					  struct ktermios *old);
 static int  klsi_105_ioctl	         (struct usb_serial_port *port,
 					  struct file * file,
 					  unsigned int cmd,
@@ -164,7 +164,7 @@ struct klsi_105_port_settings {
 #define URB_TRANSFER_BUFFER_SIZE	64
 struct klsi_105_private {
 	struct klsi_105_port_settings	cfg;
-	struct termios			termios;
+	struct ktermios			termios;
 	unsigned long			line_state; /* modem line settings */
 	/* write pool */
 	struct urb *			write_urb_pool[NUM_URBS];
@@ -688,7 +688,7 @@ static void klsi_105_read_bulk_callback (struct urb *urb)
 
 
 static void klsi_105_set_termios (struct usb_serial_port *port,
-				  struct termios *old_termios)
+				  struct ktermios *old_termios)
 {
 	struct klsi_105_private *priv = usb_get_serial_port_data(port);
 	unsigned int iflag = port->tty->termios->c_iflag;
diff --git a/drivers/usb/serial/kobil_sct.c b/drivers/usb/serial/kobil_sct.c
index 237289920f03..e284d6c0fd35 100644
--- a/drivers/usb/serial/kobil_sct.c
+++ b/drivers/usb/serial/kobil_sct.c
@@ -136,7 +136,7 @@ struct kobil_private {
 	int cur_pos; // index of the next char to send in buf
 	__u16 device_type;
 	int line_state;
-	struct termios internal_termios;
+	struct ktermios internal_termios;
 };
 
 
@@ -624,11 +624,11 @@ static int  kobil_ioctl(struct usb_serial_port *port, struct file *file,
 
 	switch (cmd) {
 	case TCGETS:   // 0x5401
-		if (!access_ok(VERIFY_WRITE, user_arg, sizeof(struct termios))) {
+		if (!access_ok(VERIFY_WRITE, user_arg, sizeof(struct ktermios))) {
 			dbg("%s - port %d Error in access_ok", __FUNCTION__, port->number);
 			return -EFAULT;
 		}
-		if (kernel_termios_to_user_termios((struct termios __user *)arg,
+		if (kernel_termios_to_user_termios((struct ktermios __user *)arg,
 						   &priv->internal_termios))
 			return -EFAULT;
 		return 0;
@@ -638,12 +638,12 @@ static int  kobil_ioctl(struct usb_serial_port *port, struct file *file,
 			dbg("%s - port %d Error: port->tty->termios is NULL", __FUNCTION__, port->number);
 			return -ENOTTY;
 		}
-		if (!access_ok(VERIFY_READ, user_arg, sizeof(struct termios))) {
+		if (!access_ok(VERIFY_READ, user_arg, sizeof(struct ktermios))) {
 			dbg("%s - port %d Error in access_ok", __FUNCTION__, port->number);
 			return -EFAULT;
 		}
 		if (user_termios_to_kernel_termios(&priv->internal_termios,
-						   (struct termios __user *)arg))
+						   (struct ktermios __user *)arg))
 			return -EFAULT;
 		
 		settings = kzalloc(50, GFP_KERNEL);
diff --git a/drivers/usb/serial/mct_u232.c b/drivers/usb/serial/mct_u232.c
index a906e500a02b..38b1d17e06ef 100644
--- a/drivers/usb/serial/mct_u232.c
+++ b/drivers/usb/serial/mct_u232.c
@@ -98,7 +98,7 @@ static void mct_u232_close	         (struct usb_serial_port *port,
 					  struct file *filp);
 static void mct_u232_read_int_callback   (struct urb *urb);
 static void mct_u232_set_termios         (struct usb_serial_port *port,
-					  struct termios * old);
+					  struct ktermios * old);
 static int  mct_u232_ioctl	         (struct usb_serial_port *port,
 					  struct file * file,
 					  unsigned int cmd,
@@ -556,7 +556,7 @@ exit:
 } /* mct_u232_read_int_callback */
 
 static void mct_u232_set_termios (struct usb_serial_port *port,
-				  struct termios *old_termios)
+				  struct ktermios *old_termios)
 {
 	struct usb_serial *serial = port->serial;
 	struct mct_u232_private *priv = usb_get_serial_port_data(port);
diff --git a/drivers/usb/serial/mos7720.c b/drivers/usb/serial/mos7720.c
index 70f93b18292f..e55f4ed81d7b 100644
--- a/drivers/usb/serial/mos7720.c
+++ b/drivers/usb/serial/mos7720.c
@@ -1014,7 +1014,7 @@ static int send_cmd_write_baud_rate(struct moschip_port *mos7720_port,
  *      the specified new settings.
  */
 static void change_port_settings(struct moschip_port *mos7720_port,
-				 struct termios *old_termios)
+				 struct ktermios *old_termios)
 {
 	struct usb_serial_port *port;
 	struct usb_serial *serial;
@@ -1203,7 +1203,7 @@ static void change_port_settings(struct moschip_port *mos7720_port,
  *	termios structure.
  */
 static void mos7720_set_termios(struct usb_serial_port *port,
-				struct termios *old_termios)
+				struct ktermios *old_termios)
 {
 	int status;
 	unsigned int cflag;
diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c
index 5432c6340086..8cc728a49e41 100644
--- a/drivers/usb/serial/mos7840.c
+++ b/drivers/usb/serial/mos7840.c
@@ -1931,7 +1931,7 @@ static int mos7840_send_cmd_write_baud_rate(struct moschip_port *mos7840_port,
  *****************************************************************************/
 
 static void mos7840_change_port_settings(struct moschip_port *mos7840_port,
-					 struct termios *old_termios)
+					 struct ktermios *old_termios)
 {
 	struct tty_struct *tty;
 	int baud;
@@ -2118,7 +2118,7 @@ static void mos7840_change_port_settings(struct moschip_port *mos7840_port,
  *****************************************************************************/
 
 static void mos7840_set_termios(struct usb_serial_port *port,
-				struct termios *old_termios)
+				struct ktermios *old_termios)
 {
 	int status;
 	unsigned int cflag;
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
index 130afbbd3fca..0ae4098718c3 100644
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -59,7 +59,7 @@ static int  option_chars_in_buffer(struct usb_serial_port *port);
 static int  option_ioctl(struct usb_serial_port *port, struct file *file,
 			unsigned int cmd, unsigned long arg);
 static void option_set_termios(struct usb_serial_port *port,
-				struct termios *old);
+				struct ktermios *old);
 static void option_break_ctl(struct usb_serial_port *port, int break_state);
 static int  option_tiocmget(struct usb_serial_port *port, struct file *file);
 static int  option_tiocmset(struct usb_serial_port *port, struct file *file,
@@ -230,7 +230,7 @@ static void option_break_ctl(struct usb_serial_port *port, int break_state)
 }
 
 static void option_set_termios(struct usb_serial_port *port,
-			struct termios *old_termios)
+			struct ktermios *old_termios)
 {
 	dbg("%s", __FUNCTION__);
 
diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c
index bc800c8787a8..d124d780e42e 100644
--- a/drivers/usb/serial/pl2303.c
+++ b/drivers/usb/serial/pl2303.c
@@ -455,7 +455,7 @@ static int pl2303_chars_in_buffer(struct usb_serial_port *port)
 }
 
 static void pl2303_set_termios(struct usb_serial_port *port,
-			       struct termios *old_termios)
+			       struct ktermios *old_termios)
 {
 	struct usb_serial *serial = port->serial;
 	struct pl2303_private *priv = usb_get_serial_port_data(port);
@@ -687,7 +687,7 @@ static void pl2303_close(struct usb_serial_port *port, struct file *filp)
 
 static int pl2303_open(struct usb_serial_port *port, struct file *filp)
 {
-	struct termios tmp_termios;
+	struct ktermios tmp_termios;
 	struct usb_serial *serial = port->serial;
 	struct pl2303_private *priv = usb_get_serial_port_data(port);
 	unsigned char *buf;
diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c
index 4b5097fa48d7..6d8e91e00ecf 100644
--- a/drivers/usb/serial/sierra.c
+++ b/drivers/usb/serial/sierra.c
@@ -145,7 +145,7 @@ static void sierra_break_ctl(struct usb_serial_port *port, int break_state)
 }
 
 static void sierra_set_termios(struct usb_serial_port *port,
-			struct termios *old_termios)
+			struct ktermios *old_termios)
 {
 	dbg("%s", __FUNCTION__);
 
diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c
index ae98d8cbdbb8..f42eb9ea6405 100644
--- a/drivers/usb/serial/ti_usb_3410_5052.c
+++ b/drivers/usb/serial/ti_usb_3410_5052.c
@@ -161,7 +161,7 @@ static void ti_throttle(struct usb_serial_port *port);
 static void ti_unthrottle(struct usb_serial_port *port);
 static int ti_ioctl(struct usb_serial_port *port, struct file *file, unsigned int cmd, unsigned long arg);
 static void ti_set_termios(struct usb_serial_port *port,
-	struct termios *old_termios);
+	struct ktermios *old_termios);
 static int ti_tiocmget(struct usb_serial_port *port, struct file *file);
 static int ti_tiocmset(struct usb_serial_port *port, struct file *file,
 	unsigned int set, unsigned int clear);
@@ -881,7 +881,7 @@ static int ti_ioctl(struct usb_serial_port *port, struct file *file,
 
 
 static void ti_set_termios(struct usb_serial_port *port,
-	struct termios *old_termios)
+	struct ktermios *old_termios)
 {
 	struct ti_port *tport = usb_get_serial_port_data(port);
 	struct tty_struct *tty = port->tty;
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
index 3d5072f14b8d..716f6806cc89 100644
--- a/drivers/usb/serial/usb-serial.c
+++ b/drivers/usb/serial/usb-serial.c
@@ -397,7 +397,7 @@ exit:
 	return retval;
 }
 
-static void serial_set_termios (struct tty_struct *tty, struct termios * old)
+static void serial_set_termios (struct tty_struct *tty, struct ktermios * old)
 {
 	struct usb_serial_port *port = tty->driver_data;
 
diff --git a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c
index eef5eaa5fa0b..b09f06096056 100644
--- a/drivers/usb/serial/visor.c
+++ b/drivers/usb/serial/visor.c
@@ -46,7 +46,7 @@ static int  visor_probe		(struct usb_serial *serial, const struct usb_device_id
 static int  visor_calc_num_ports(struct usb_serial *serial);
 static void visor_shutdown	(struct usb_serial *serial);
 static int  visor_ioctl		(struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg);
-static void visor_set_termios	(struct usb_serial_port *port, struct termios *old_termios);
+static void visor_set_termios	(struct usb_serial_port *port, struct ktermios *old_termios);
 static void visor_write_bulk_callback	(struct urb *urb);
 static void visor_read_bulk_callback	(struct urb *urb);
 static void visor_read_int_callback	(struct urb *urb);
@@ -916,7 +916,7 @@ static int visor_ioctl (struct usb_serial_port *port, struct file * file, unsign
 
 
 /* This function is all nice and good, but we don't change anything based on it :) */
-static void visor_set_termios (struct usb_serial_port *port, struct termios *old_termios)
+static void visor_set_termios (struct usb_serial_port *port, struct ktermios *old_termios)
 {
 	unsigned int cflag;
 
diff --git a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c
index 154c7d290597..dc45e58e2b8c 100644
--- a/drivers/usb/serial/whiteheat.c
+++ b/drivers/usb/serial/whiteheat.c
@@ -145,7 +145,7 @@ static void whiteheat_close		(struct usb_serial_port *port, struct file *filp);
 static int  whiteheat_write		(struct usb_serial_port *port, const unsigned char *buf, int count);
 static int  whiteheat_write_room	(struct usb_serial_port *port);
 static int  whiteheat_ioctl		(struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg);
-static void whiteheat_set_termios	(struct usb_serial_port *port, struct termios * old);
+static void whiteheat_set_termios	(struct usb_serial_port *port, struct ktermios * old);
 static int  whiteheat_tiocmget		(struct usb_serial_port *port, struct file *file);
 static int  whiteheat_tiocmset		(struct usb_serial_port *port, struct file *file, unsigned int set, unsigned int clear);
 static void whiteheat_break_ctl		(struct usb_serial_port *port, int break_state);
@@ -597,7 +597,7 @@ static void whiteheat_shutdown (struct usb_serial *serial)
 static int whiteheat_open (struct usb_serial_port *port, struct file *filp)
 {
 	int		retval = 0;
-	struct termios	old_term;
+	struct ktermios	old_term;
 
 	dbg("%s - port %d", __FUNCTION__, port->number);
 
@@ -870,7 +870,7 @@ static int whiteheat_ioctl (struct usb_serial_port *port, struct file * file, un
 }
 
 
-static void whiteheat_set_termios (struct usb_serial_port *port, struct termios *old_termios)
+static void whiteheat_set_termios (struct usb_serial_port *port, struct ktermios *old_termios)
 {
 	dbg("%s -port %d", __FUNCTION__, port->number);
 
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 7a43020fa583..ab1daecfeac6 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -541,6 +541,7 @@ config FB_TGA
 	select FB_CFB_FILLRECT
 	select FB_CFB_COPYAREA
 	select FB_CFB_IMAGEBLIT
+	select BITREVERSE
 	help
 	  This is the frame buffer device driver for generic TGA graphic
 	  cards. Say Y if you have one of those.
@@ -551,6 +552,7 @@ config FB_VESA
 	select FB_CFB_FILLRECT
 	select FB_CFB_COPYAREA
 	select FB_CFB_IMAGEBLIT
+	select VIDEO_SELECT
 	help
 	  This is the frame buffer device driver for generic VESA 2.0
 	  compliant graphic cards. The older VESA 1.2 cards are not supported.
@@ -705,6 +707,7 @@ config FB_NVIDIA
 	select FB_CFB_FILLRECT
 	select FB_CFB_COPYAREA
 	select FB_CFB_IMAGEBLIT
+	select BITREVERSE
 	help
 	  This driver supports graphics boards with the nVidia chips, TNT
 	  and newer. For very old chipsets, such as the RIVA128, then use
@@ -744,6 +747,7 @@ config FB_RIVA
 	select FB_CFB_FILLRECT
 	select FB_CFB_COPYAREA
 	select FB_CFB_IMAGEBLIT
+	select BITREVERSE
 	help
 	  This driver supports graphics boards with the nVidia Riva/Geforce
 	  chips.
diff --git a/drivers/video/S3triofb.c b/drivers/video/S3triofb.c
index 397005eb392d..b3717c8f1bc2 100644
--- a/drivers/video/S3triofb.c
+++ b/drivers/video/S3triofb.c
@@ -535,8 +535,11 @@ static void __init s3triofb_of_init(struct device_node *dp)
 #endif
 
     fb_info.flags = FBINFO_FLAG_DEFAULT;
-    if (register_framebuffer(&fb_info) < 0)
-	return;
+    if (register_framebuffer(&fb_info) < 0) {
+		iounmap(fb_info.screen_base);
+		fb_info.screen_base = NULL;
+		return;
+    }
 
     printk("fb%d: S3 Trio frame buffer device on %s\n",
 	   fb_info.node, dp->full_name);
diff --git a/drivers/video/amifb.c b/drivers/video/amifb.c
index a4e3fca05891..88a47845c4f7 100644
--- a/drivers/video/amifb.c
+++ b/drivers/video/amifb.c
@@ -2407,10 +2407,10 @@ default_chipset:
 						   fb_info.fix.smem_len);
 	if (!videomemory) {
 		printk("amifb: WARNING! unable to map videomem cached writethrough\n");
-		videomemory = ZTWO_VADDR(fb_info.fix.smem_start);
-	}
+		fb_info.screen_base = (char *)ZTWO_VADDR(fb_info.fix.smem_start);
+	} else
+		fb_info.screen_base = (char *)videomemory;
 
-	fb_info.screen_base = (char *)videomemory;
 	memset(dummysprite, 0, DUMMYSPRITEMEMSIZE);
 
 	/*
@@ -2453,6 +2453,8 @@ static void amifb_deinit(void)
 {
 	fb_dealloc_cmap(&fb_info.cmap);
 	chipfree();
+	if (videomemory)
+		iounmap((void*)videomemory);
 	release_mem_region(CUSTOM_PHYSADDR+0xe0, 0x120);
 	custom.dmacon = DMAF_ALL | DMAF_MASTER;
 }
diff --git a/drivers/video/arcfb.c b/drivers/video/arcfb.c
index ab34b96acc31..30a8369757e7 100644
--- a/drivers/video/arcfb.c
+++ b/drivers/video/arcfb.c
@@ -454,7 +454,7 @@ static ssize_t arcfb_write(struct file *file, const char __user *buf, size_t cou
 	unsigned int xres;
 
 	p = *ppos;
-	inode = file->f_dentry->d_inode;
+	inode = file->f_path.dentry->d_inode;
 	fbidx = iminor(inode);
 	info = registered_fb[fbidx];
 
diff --git a/drivers/video/atafb.c b/drivers/video/atafb.c
index 02c41a626fa2..602db660bc73 100644
--- a/drivers/video/atafb.c
+++ b/drivers/video/atafb.c
@@ -2804,8 +2804,19 @@ int __init atafb_init(void)
 	atafb_set_disp(-1, &fb_info);
 	do_install_cmap(0, &fb_info);
 
-	if (register_framebuffer(&fb_info) < 0)
+	if (register_framebuffer(&fb_info) < 0) {
+#ifdef ATAFB_EXT
+		if (external_addr) {
+			iounmap(external_addr);
+			external_addr = NULL;
+		}
+		if (external_vgaiobase) {
+			iounmap((void*)external_vgaiobase);
+			external_vgaiobase = 0;
+		}
+#endif
 		return -EINVAL;
+	}
 
 	printk("Determined %dx%d, depth %d\n",
 	       disp.var.xres, disp.var.yres, disp.var.bits_per_pixel);
diff --git a/drivers/video/aty/aty128fb.c b/drivers/video/aty/aty128fb.c
index 276a21530b95..3feddf89d100 100644
--- a/drivers/video/aty/aty128fb.c
+++ b/drivers/video/aty/aty128fb.c
@@ -1333,6 +1333,8 @@ static int aty128_var_to_pll(u32 period_in_ps, struct aty128_pll *pll,
 	if (vclk * 12 < c.ppll_min)
 		vclk = c.ppll_min/12;
 
+	pll->post_divider = -1;
+
 	/* now, find an acceptable divider */
 	for (i = 0; i < sizeof(post_dividers); i++) {
 		output_freq = post_dividers[i] * vclk;
@@ -1342,6 +1344,9 @@ static int aty128_var_to_pll(u32 period_in_ps, struct aty128_pll *pll,
 		}
 	}
 
+	if (pll->post_divider < 0)
+		return -EINVAL;
+
 	/* calculate feedback divider */
 	n = c.ref_divider * output_freq;
 	d = c.ref_clk;
diff --git a/drivers/video/aty/atyfb.h b/drivers/video/aty/atyfb.h
index b04f49fb976a..f72faff33c0c 100644
--- a/drivers/video/aty/atyfb.h
+++ b/drivers/video/aty/atyfb.h
@@ -126,7 +126,6 @@ union aty_pll {
      */
 
 struct atyfb_par {
-	struct aty_cmap_regs __iomem *aty_cmap_regs;
 	struct { u8 red, green, blue; } palette[256];
 	const struct aty_dac_ops *dac_ops;
 	const struct aty_pll_ops *pll_ops;
@@ -186,6 +185,7 @@ struct atyfb_par {
 	int mtrr_aper;
 	int mtrr_reg;
 #endif
+	u32 mem_cntl;
 };
 
     /*
@@ -227,7 +227,7 @@ static inline u32 aty_ld_le32(int regindex, const struct atyfb_par *par)
 		regindex -= 0x800;
 
 #ifdef CONFIG_ATARI
-	return in_le32((volatile u32 *)(par->ati_regbase + regindex));
+	return in_le32(par->ati_regbase + regindex);
 #else
 	return readl(par->ati_regbase + regindex);
 #endif
@@ -240,7 +240,7 @@ static inline void aty_st_le32(int regindex, u32 val, const struct atyfb_par *pa
 		regindex -= 0x800;
 
 #ifdef CONFIG_ATARI
-	out_le32((volatile u32 *)(par->ati_regbase + regindex), val);
+	out_le32(par->ati_regbase + regindex, val);
 #else
 	writel(val, par->ati_regbase + regindex);
 #endif
@@ -253,7 +253,7 @@ static inline void aty_st_le16(int regindex, u16 val,
 	if (regindex >= 0x400)
 		regindex -= 0x800;
 #ifdef CONFIG_ATARI
-	out_le16((volatile u16 *)(par->ati_regbase + regindex), val);
+	out_le16(par->ati_regbase + regindex, val);
 #else
 	writel(val, par->ati_regbase + regindex);
 #endif
@@ -315,6 +315,7 @@ struct aty_pll_ops {
 	void (*set_pll)   (const struct fb_info * info, const union aty_pll * pll);
 	void (*get_pll)   (const struct fb_info *info, union aty_pll * pll);
 	int (*init_pll)   (const struct fb_info * info, union aty_pll * pll);
+	void (*resume_pll)(const struct fb_info *info, union aty_pll *pll);
 };
 
 extern const struct aty_pll_ops aty_pll_ati18818_1; /* ATI 18818 */
diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c
index e815b354c09d..176f9b85cdbe 100644
--- a/drivers/video/aty/atyfb_base.c
+++ b/drivers/video/aty/atyfb_base.c
@@ -203,14 +203,6 @@ static void ATIReduceRatio(int *Numerator, int *Denominator)
      *  The Hardware parameters for each card
      */
 
-struct aty_cmap_regs {
-	u8 windex;
-	u8 lut;
-	u8 mask;
-	u8 rindex;
-	u8 cntl;
-};
-
 struct pci_mmap_map {
 	unsigned long voff;
 	unsigned long poff;
@@ -249,7 +241,8 @@ static int atyfb_sync(struct fb_info *info);
      *  Internal routines
      */
 
-static int aty_init(struct fb_info *info, const char *name);
+static int aty_init(struct fb_info *info);
+static void aty_resume_chip(struct fb_info *info);
 #ifdef CONFIG_ATARI
 static int store_video_par(char *videopar, unsigned char m64_num);
 #endif
@@ -1937,17 +1930,14 @@ static void atyfb_save_palette(struct atyfb_par *par, int enter)
 		aty_st_8(DAC_CNTL, tmp, par);
 		aty_st_8(DAC_MASK, 0xff, par);
 
-		writeb(i, &par->aty_cmap_regs->rindex);
-		atyfb_save.r[enter][i] = readb(&par->aty_cmap_regs->lut);
-		atyfb_save.g[enter][i] = readb(&par->aty_cmap_regs->lut);
-		atyfb_save.b[enter][i] = readb(&par->aty_cmap_regs->lut);
-		writeb(i, &par->aty_cmap_regs->windex);
-		writeb(atyfb_save.r[1 - enter][i],
-		       &par->aty_cmap_regs->lut);
-		writeb(atyfb_save.g[1 - enter][i],
-		       &par->aty_cmap_regs->lut);
-		writeb(atyfb_save.b[1 - enter][i],
-		       &par->aty_cmap_regs->lut);
+		aty_st_8(DAC_R_INDEX, i, par);
+		atyfb_save.r[enter][i] = aty_ld_8(DAC_DATA, par);
+		atyfb_save.g[enter][i] = aty_ld_8(DAC_DATA, par);
+		atyfb_save.b[enter][i] = aty_ld_8(DAC_DATA, par);
+		aty_st_8(DAC_W_INDEX, i, par);
+		aty_st_8(DAC_DATA, atyfb_save.r[1 - enter][i], par);
+		aty_st_8(DAC_DATA, atyfb_save.g[1 - enter][i], par);
+		aty_st_8(DAC_DATA, atyfb_save.b[1 - enter][i], par);
 	}
 }
 
@@ -1982,6 +1972,7 @@ static void atyfb_palette(int enter)
 
 #if defined(CONFIG_PM) && defined(CONFIG_PCI)
 
+#ifdef CONFIG_PPC_PMAC
 /* Power management routines. Those are used for PowerBook sleep.
  */
 static int aty_power_mgmt(int sleep, struct atyfb_par *par)
@@ -2038,21 +2029,13 @@ static int aty_power_mgmt(int sleep, struct atyfb_par *par)
 
 	return timeout ? 0 : -EIO;
 }
+#endif
 
 static int atyfb_pci_suspend(struct pci_dev *pdev, pm_message_t state)
 {
 	struct fb_info *info = pci_get_drvdata(pdev);
 	struct atyfb_par *par = (struct atyfb_par *) info->par;
 
-#ifndef CONFIG_PPC_PMAC
-	/* HACK ALERT ! Once I find a proper way to say to each driver
-	 * individually what will happen with it's PCI slot, I'll change
-	 * that. On laptops, the AGP slot is just unclocked, so D2 is
-	 * expected, while on desktops, the card is powered off
-	 */
-	return 0;
-#endif /* CONFIG_PPC_PMAC */
-
 	if (state.event == pdev->dev.power.power_state.event)
 		return 0;
 
@@ -2070,6 +2053,7 @@ static int atyfb_pci_suspend(struct pci_dev *pdev, pm_message_t state)
 	par->asleep = 1;
 	par->lock_blank = 1;
 
+#ifdef CONFIG_PPC_PMAC
 	/* Set chip to "suspend" mode */
 	if (aty_power_mgmt(1, par)) {
 		par->asleep = 0;
@@ -2079,6 +2063,9 @@ static int atyfb_pci_suspend(struct pci_dev *pdev, pm_message_t state)
 		release_console_sem();
 		return -EIO;
 	}
+#else
+	pci_set_power_state(pdev, pci_choose_state(pdev, state));
+#endif
 
 	release_console_sem();
 
@@ -2097,8 +2084,15 @@ static int atyfb_pci_resume(struct pci_dev *pdev)
 
 	acquire_console_sem();
 
+#ifdef CONFIG_PPC_PMAC
 	if (pdev->dev.power.power_state.event == 2)
 		aty_power_mgmt(0, par);
+#else
+	pci_set_power_state(pdev, PCI_D0);
+#endif
+
+	aty_resume_chip(info);
+
 	par->asleep = 0;
 
 	/* Restore display */
@@ -2344,24 +2338,16 @@ static int __devinit atyfb_get_timings_from_lcd(struct atyfb_par *par,
 }
 #endif /* defined(__i386__) && defined(CONFIG_FB_ATY_GENERIC_LCD) */
 
-static int __devinit aty_init(struct fb_info *info, const char *name)
+static int __devinit aty_init(struct fb_info *info)
 {
 	struct atyfb_par *par = (struct atyfb_par *) info->par;
 	const char *ramname = NULL, *xtal;
 	int gtb_memsize, has_var = 0;
 	struct fb_var_screeninfo var;
-	u8 pll_ref_div;
-	u32 i;
-#if defined(CONFIG_PPC)
-	int sense;
-#endif
 
 	init_waitqueue_head(&par->vblank.wait);
 	spin_lock_init(&par->int_lock);
 
-	par->aty_cmap_regs =
-	    (struct aty_cmap_regs __iomem *) (par->ati_regbase + 0xc0);
-
 #ifdef CONFIG_PPC_PMAC
 	/* The Apple iBook1 uses non-standard memory frequencies. We detect it
 	 * and set the frequency manually. */
@@ -2464,18 +2450,21 @@ static int __devinit aty_init(struct fb_info *info, const char *name)
 			par->pll_limits.mclk = 63;
 	}
 
-	if (M64_HAS(GTB_DSP)
-	    && (pll_ref_div = aty_ld_pll_ct(PLL_REF_DIV, par))) {
-		int diff1, diff2;
-		diff1 = 510 * 14 / pll_ref_div - par->pll_limits.pll_max;
-		diff2 = 510 * 29 / pll_ref_div - par->pll_limits.pll_max;
-		if (diff1 < 0)
-			diff1 = -diff1;
-		if (diff2 < 0)
-			diff2 = -diff2;
-		if (diff2 < diff1) {
-			par->ref_clk_per = 1000000000000ULL / 29498928;
-			xtal = "29.498928";
+	if (M64_HAS(GTB_DSP)) {
+		u8 pll_ref_div = aty_ld_pll_ct(PLL_REF_DIV, par);
+
+		if (pll_ref_div) {
+			int diff1, diff2;
+			diff1 = 510 * 14 / pll_ref_div - par->pll_limits.pll_max;
+			diff2 = 510 * 29 / pll_ref_div - par->pll_limits.pll_max;
+			if (diff1 < 0)
+				diff1 = -diff1;
+			if (diff2 < 0)
+				diff2 = -diff2;
+			if (diff2 < diff1) {
+				par->ref_clk_per = 1000000000000ULL / 29498928;
+				xtal = "29.498928";
+			}
 		}
 	}
 #endif /* CONFIG_FB_ATY_CT */
@@ -2485,10 +2474,10 @@ static int __devinit aty_init(struct fb_info *info, const char *name)
 	if(par->pll_ops->get_pll)
 		par->pll_ops->get_pll(info, &saved_pll);
 
-	i = aty_ld_le32(MEM_CNTL, par);
+	par->mem_cntl = aty_ld_le32(MEM_CNTL, par);
 	gtb_memsize = M64_HAS(GTB_DSP);
 	if (gtb_memsize)
-		switch (i & 0xF) {	/* 0xF used instead of MEM_SIZE_ALIAS */
+		switch (par->mem_cntl & 0xF) {	/* 0xF used instead of MEM_SIZE_ALIAS */
 		case MEM_SIZE_512K:
 			info->fix.smem_len = 0x80000;
 			break;
@@ -2510,7 +2499,7 @@ static int __devinit aty_init(struct fb_info *info, const char *name)
 		default:
 			info->fix.smem_len = 0x80000;
 	} else
-		switch (i & MEM_SIZE_ALIAS) {
+		switch (par->mem_cntl & MEM_SIZE_ALIAS) {
 		case MEM_SIZE_512K:
 			info->fix.smem_len = 0x80000;
 			break;
@@ -2540,20 +2529,20 @@ static int __devinit aty_init(struct fb_info *info, const char *name)
 
 	if (vram) {
 		info->fix.smem_len = vram * 1024;
-		i = i & ~(gtb_memsize ? 0xF : MEM_SIZE_ALIAS);
+		par->mem_cntl &= ~(gtb_memsize ? 0xF : MEM_SIZE_ALIAS);
 		if (info->fix.smem_len <= 0x80000)
-			i |= MEM_SIZE_512K;
+			par->mem_cntl |= MEM_SIZE_512K;
 		else if (info->fix.smem_len <= 0x100000)
-			i |= MEM_SIZE_1M;
+			par->mem_cntl |= MEM_SIZE_1M;
 		else if (info->fix.smem_len <= 0x200000)
-			i |= gtb_memsize ? MEM_SIZE_2M_GTB : MEM_SIZE_2M;
+			par->mem_cntl |= gtb_memsize ? MEM_SIZE_2M_GTB : MEM_SIZE_2M;
 		else if (info->fix.smem_len <= 0x400000)
-			i |= gtb_memsize ? MEM_SIZE_4M_GTB : MEM_SIZE_4M;
+			par->mem_cntl |= gtb_memsize ? MEM_SIZE_4M_GTB : MEM_SIZE_4M;
 		else if (info->fix.smem_len <= 0x600000)
-			i |= gtb_memsize ? MEM_SIZE_6M_GTB : MEM_SIZE_6M;
+			par->mem_cntl |= gtb_memsize ? MEM_SIZE_6M_GTB : MEM_SIZE_6M;
 		else
-			i |= gtb_memsize ? MEM_SIZE_8M_GTB : MEM_SIZE_8M;
-		aty_st_le32(MEM_CNTL, i, par);
+			par->mem_cntl |= gtb_memsize ? MEM_SIZE_8M_GTB : MEM_SIZE_8M;
+		aty_st_le32(MEM_CNTL, par->mem_cntl, par);
 	}
 
 	/*
@@ -2599,11 +2588,12 @@ static int __devinit aty_init(struct fb_info *info, const char *name)
 #endif
 	if(par->pll_ops->init_pll)
 		par->pll_ops->init_pll(info, &par->pll);
+	if (par->pll_ops->resume_pll)
+		par->pll_ops->resume_pll(info, &par->pll);
 
 	/*
-	 *  Last page of 8 MB (4 MB on ISA) aperture is MMIO
-	 *  FIXME: we should use the auxiliary aperture instead so we can access
-	 *  the full 8 MB of video RAM on 8 MB boards
+	 *  Last page of 8 MB (4 MB on ISA) aperture is MMIO,
+	 *  unless the auxiliary register aperture is used.
 	 */
 
 	if (!par->aux_start &&
@@ -2669,6 +2659,7 @@ static int __devinit aty_init(struct fb_info *info, const char *name)
 				has_var = 1;
 		} else {
 			if (default_vmode == VMODE_CHOOSE) {
+				int sense;
 				if (M64_HAS(G3_PB_1024x768))
 					/* G3 PowerBook with 1024x768 LCD */
 					default_vmode = VMODE_1024_768_60;
@@ -2749,7 +2740,7 @@ static int __devinit aty_init(struct fb_info *info, const char *name)
 	fb_list = info;
 
 	PRINTKI("fb%d: %s frame buffer device on %s\n",
-	       info->node, info->fix.id, name);
+		info->node, info->fix.id, par->bus_type == ISA ? "ISA" : "PCI");
 	return 0;
 
 aty_init_exit:
@@ -2770,6 +2761,19 @@ aty_init_exit:
 	return -1;
 }
 
+static void aty_resume_chip(struct fb_info *info)
+{
+	struct atyfb_par *par = info->par;
+
+	aty_st_le32(MEM_CNTL, par->mem_cntl, par);
+
+	if (par->pll_ops->resume_pll)
+		par->pll_ops->resume_pll(info, &par->pll);
+
+	if (par->aux_start)
+		aty_st_le32(BUS_CNTL, aty_ld_le32(BUS_CNTL, par) | BUS_APER_REG_DIS, par);
+}
+
 #ifdef CONFIG_ATARI
 static int __devinit store_video_par(char *video_str, unsigned char m64_num)
 {
@@ -2826,9 +2830,9 @@ static int atyfb_blank(int blank, struct fb_info *info)
 #endif
 
 	gen_cntl = aty_ld_le32(CRTC_GEN_CNTL, par);
+	gen_cntl &= ~0x400004c;
 	switch (blank) {
-        	case FB_BLANK_UNBLANK:
-			gen_cntl &= ~0x400004c;
+		case FB_BLANK_UNBLANK:
 			break;
 		case FB_BLANK_NORMAL:
 			gen_cntl |= 0x4000040;
@@ -2863,17 +2867,10 @@ static int atyfb_blank(int blank, struct fb_info *info)
 static void aty_st_pal(u_int regno, u_int red, u_int green, u_int blue,
 		       const struct atyfb_par *par)
 {
-#ifdef CONFIG_ATARI
-	out_8(&par->aty_cmap_regs->windex, regno);
-	out_8(&par->aty_cmap_regs->lut, red);
-	out_8(&par->aty_cmap_regs->lut, green);
-	out_8(&par->aty_cmap_regs->lut, blue);
-#else
-	writeb(regno, &par->aty_cmap_regs->windex);
-	writeb(red, &par->aty_cmap_regs->lut);
-	writeb(green, &par->aty_cmap_regs->lut);
-	writeb(blue, &par->aty_cmap_regs->lut);
-#endif
+	aty_st_8(DAC_W_INDEX, regno, par);
+	aty_st_8(DAC_DATA, red, par);
+	aty_st_8(DAC_DATA, green, par);
+	aty_st_8(DAC_DATA, blue, par);
 }
 
     /*
@@ -3182,7 +3179,7 @@ static int __devinit atyfb_setup_sparc(struct pci_dev *pdev,
 
 #ifdef __i386__
 #ifdef CONFIG_FB_ATY_GENERIC_LCD
-static void aty_init_lcd(struct atyfb_par *par, u32 bios_base)
+static void __devinit aty_init_lcd(struct atyfb_par *par, u32 bios_base)
 {
 	u32 driv_inf_tab, sig;
 	u16 lcd_ofs;
@@ -3527,6 +3524,10 @@ static int __devinit atyfb_setup_generic(struct pci_dev *pdev, struct fb_info *i
 atyfb_setup_generic_fail:
 	iounmap(par->ati_regbase);
 	par->ati_regbase = NULL;
+	if (info->screen_base) {
+		iounmap(info->screen_base);
+		info->screen_base = NULL;
+	}
 	return ret;
 }
 
@@ -3594,7 +3595,7 @@ static int __devinit atyfb_pci_probe(struct pci_dev *pdev, const struct pci_devi
 	pci_set_drvdata(pdev, info);
 
 	/* Init chip & register framebuffer */
-	if (aty_init(info, "PCI"))
+	if (aty_init(info))
 		goto err_release_io;
 
 #ifdef __sparc__
@@ -3641,12 +3642,13 @@ err_release_mem:
 
 #ifdef CONFIG_ATARI
 
-static int __devinit atyfb_atari_probe(void)
+static int __init atyfb_atari_probe(void)
 {
 	struct atyfb_par *par;
 	struct fb_info *info;
 	int m64_num;
 	u32 clock_r;
+	int num_found = 0;
 
 	for (m64_num = 0; m64_num < mach64_count; m64_num++) {
 		if (!phys_vmembase[m64_num] || !phys_size[m64_num] ||
@@ -3694,16 +3696,34 @@ static int __devinit atyfb_atari_probe(void)
 			break;
 		}
 
-		if (aty_init(info, "ISA bus")) {
+		/* Fake pci_id for correct_chipset() */
+		switch (aty_ld_le32(CONFIG_CHIP_ID, par) & CFG_CHIP_TYPE) {
+		case 0x00d7:
+			par->pci_id = PCI_CHIP_MACH64GX;
+			break;
+		case 0x0057:
+			par->pci_id = PCI_CHIP_MACH64CX;
+			break;
+		default:
+			break;
+		}
+
+		if (correct_chipset(par) || aty_init(info)) {
+			iounmap(info->screen_base);
+			iounmap(par->ati_regbase);
 			framebuffer_release(info);
-			/* This is insufficient! kernel_map has added two large chunks!! */
-			return -ENXIO;
+		} else {
+			num_found++;
 		}
 	}
+
+	return num_found ? 0 : -ENXIO;
 }
 
 #endif /* CONFIG_ATARI */
 
+#ifdef CONFIG_PCI
+
 static void __devexit atyfb_remove(struct fb_info *info)
 {
 	struct atyfb_par *par = (struct atyfb_par *) info->par;
@@ -3751,7 +3771,6 @@ static void __devexit atyfb_remove(struct fb_info *info)
 	framebuffer_release(info);
 }
 
-#ifdef CONFIG_PCI
 
 static void __devexit atyfb_pci_remove(struct pci_dev *pdev)
 {
@@ -3786,7 +3805,7 @@ static struct pci_driver atyfb_driver = {
 #endif /* CONFIG_PCI */
 
 #ifndef MODULE
-static int __devinit atyfb_setup(char *options)
+static int __init atyfb_setup(char *options)
 {
 	char *this_opt;
 
@@ -3858,7 +3877,7 @@ static int __devinit atyfb_setup(char *options)
 }
 #endif  /*  MODULE  */
 
-static int __devinit atyfb_init(void)
+static int __init atyfb_init(void)
 {
     int err1 = 1, err2 = 1;
 #ifndef MODULE
diff --git a/drivers/video/aty/mach64_ct.c b/drivers/video/aty/mach64_ct.c
index 5080816be653..f3b487b8710b 100644
--- a/drivers/video/aty/mach64_ct.c
+++ b/drivers/video/aty/mach64_ct.c
@@ -370,8 +370,8 @@ void aty_set_pll_ct(const struct fb_info *info, const union aty_pll *pll)
 #endif
 }
 
-static void __init aty_get_pll_ct(const struct fb_info *info,
-				  union aty_pll *pll)
+static void __devinit aty_get_pll_ct(const struct fb_info *info,
+				     union aty_pll *pll)
 {
 	struct atyfb_par *par = (struct atyfb_par *) info->par;
 	u8 tmp, clock;
@@ -394,12 +394,12 @@ static void __init aty_get_pll_ct(const struct fb_info *info,
 	}
 }
 
-static int __init aty_init_pll_ct(const struct fb_info *info,
-				 union aty_pll *pll)
+static int __devinit aty_init_pll_ct(const struct fb_info *info,
+				     union aty_pll *pll)
 {
 	struct atyfb_par *par = (struct atyfb_par *) info->par;
-	u8 mpost_div, xpost_div, sclk_post_div_real, sclk_fb_div, spll_cntl2;
-	u32 q, i, memcntl, trp;
+	u8 mpost_div, xpost_div, sclk_post_div_real;
+	u32 q, memcntl, trp;
 	u32 dsp_config, dsp_on_off, vga_dsp_config, vga_dsp_on_off;
 #ifdef DEBUG
 	int pllmclk, pllsclk;
@@ -575,14 +575,30 @@ static int __init aty_init_pll_ct(const struct fb_info *info,
 			mpost_div += (q <  32*8);
 		}
 		sclk_post_div_real = postdividers[mpost_div];
-		sclk_fb_div = q * sclk_post_div_real / 8;
-		spll_cntl2 = mpost_div << 4;
+		pll->ct.sclk_fb_div = q * sclk_post_div_real / 8;
+		pll->ct.spll_cntl2 = mpost_div << 4;
 #ifdef DEBUG
-		pllsclk = (1000000 * 2 * sclk_fb_div) /
+		pllsclk = (1000000 * 2 * pll->ct.sclk_fb_div) /
 			(par->ref_clk_per * pll->ct.pll_ref_div);
 		printk("atyfb(%s): use sclk, pllsclk=%d MHz, sclk=mclk=%d MHz\n",
 			__FUNCTION__, pllsclk, pllsclk / sclk_post_div_real);
 #endif
+	}
+
+	/* Disable the extra precision pixel clock controls since we do not use them. */
+	pll->ct.ext_vpll_cntl = aty_ld_pll_ct(EXT_VPLL_CNTL, par);
+	pll->ct.ext_vpll_cntl &= ~(EXT_VPLL_EN | EXT_VPLL_VGA_EN | EXT_VPLL_INSYNC);
+
+	return 0;
+}
+
+static void aty_resume_pll_ct(const struct fb_info *info,
+			      union aty_pll *pll)
+{
+	struct atyfb_par *par = info->par;
+
+	if (par->mclk_per != par->xclk_per) {
+		int i;
 		/*
 		* This disables the sclk, crashes the computer as reported:
 		* aty_st_pll_ct(SPLL_CNTL2, 3, info);
@@ -590,8 +606,8 @@ static int __init aty_init_pll_ct(const struct fb_info *info,
 		* So it seems the sclk must be enabled before it is used;
 		* so PLL_GEN_CNTL must be programmed *after* the sclk.
 		*/
-		aty_st_pll_ct(SCLK_FB_DIV, sclk_fb_div, par);
-		aty_st_pll_ct(SPLL_CNTL2, spll_cntl2, par);
+		aty_st_pll_ct(SCLK_FB_DIV, pll->ct.sclk_fb_div, par);
+		aty_st_pll_ct(SPLL_CNTL2, pll->ct.spll_cntl2, par);
 		/*
 		 * The sclk has been started. However, I believe the first clock
 		 * ticks it generates are not very stable. Hope this primitive loop
@@ -605,11 +621,7 @@ static int __init aty_init_pll_ct(const struct fb_info *info,
 	aty_st_pll_ct(PLL_GEN_CNTL, pll->ct.pll_gen_cntl, par);
 	aty_st_pll_ct(MCLK_FB_DIV, pll->ct.mclk_fb_div, par);
 	aty_st_pll_ct(PLL_EXT_CNTL, pll->ct.pll_ext_cntl, par);
-	/* Disable the extra precision pixel clock controls since we do not use them. */
-	aty_st_pll_ct(EXT_VPLL_CNTL, aty_ld_pll_ct(EXT_VPLL_CNTL, par) &
-		~(EXT_VPLL_EN | EXT_VPLL_VGA_EN | EXT_VPLL_INSYNC), par);
-
-	return 0;
+	aty_st_pll_ct(EXT_VPLL_CNTL, pll->ct.ext_vpll_cntl, par);
 }
 
 static int dummy(void)
@@ -626,5 +638,6 @@ const struct aty_pll_ops aty_pll_ct = {
 	.pll_to_var	= aty_pll_to_var_ct,
 	.set_pll	= aty_set_pll_ct,
 	.get_pll	= aty_get_pll_ct,
-	.init_pll       = aty_init_pll_ct
+	.init_pll	= aty_init_pll_ct,
+	.resume_pll	= aty_resume_pll_ct,
 };
diff --git a/drivers/video/aty/radeon_monitor.c b/drivers/video/aty/radeon_monitor.c
index ea531a6f45d1..38c7dbf8c151 100644
--- a/drivers/video/aty/radeon_monitor.c
+++ b/drivers/video/aty/radeon_monitor.c
@@ -104,10 +104,9 @@ static int __devinit radeon_parse_montype_prop(struct device_node *dp, u8 **out_
 	if (pedid == NULL)
 		return mt;
 
-	tmp = (u8 *)kmalloc(EDID_LENGTH, GFP_KERNEL);
+	tmp = kmemdup(pedid, EDID_LENGTH, GFP_KERNEL);
 	if (!tmp)
 		return mt;
-	memcpy(tmp, pedid, EDID_LENGTH);
 	*out_EDID = tmp;
 	return mt;
 }
diff --git a/drivers/video/au1100fb.h b/drivers/video/au1100fb.h
index 2855534dc235..164fe2f231ec 100644
--- a/drivers/video/au1100fb.h
+++ b/drivers/video/au1100fb.h
@@ -274,7 +274,7 @@ static struct au1100fb_panel known_lcd_panels[] =
 		.bpp = 16,
 		.control_base =	0x0004886A |
 			LCD_CONTROL_DEFAULT_PO | LCD_CONTROL_DEFAULT_SBPPF |
-			LCD_CONTROL_BPP_16,
+			LCD_CONTROL_BPP_16 | LCD_CONTROL_SBB_4,
 		.clkcontrol_base = 0x00020000,
 		.horztiming = 0x005aff1f,
 		.verttiming = 0x16000e57,
diff --git a/drivers/video/backlight/backlight.c b/drivers/video/backlight/backlight.c
index 27597c576eff..db8c191b1201 100644
--- a/drivers/video/backlight/backlight.c
+++ b/drivers/video/backlight/backlight.c
@@ -14,6 +14,59 @@
 #include <linux/err.h>
 #include <linux/fb.h>
 
+
+#if defined(CONFIG_FB) || (defined(CONFIG_FB_MODULE) && \
+			   defined(CONFIG_BACKLIGHT_CLASS_DEVICE_MODULE))
+/* This callback gets called when something important happens inside a
+ * framebuffer driver. We're looking if that important event is blanking,
+ * and if it is, we're switching backlight power as well ...
+ */
+static int fb_notifier_callback(struct notifier_block *self,
+				unsigned long event, void *data)
+{
+	struct backlight_device *bd;
+	struct fb_event *evdata = data;
+
+	/* If we aren't interested in this event, skip it immediately ... */
+	if (event != FB_EVENT_BLANK)
+		return 0;
+
+	bd = container_of(self, struct backlight_device, fb_notif);
+	down(&bd->sem);
+	if (bd->props)
+		if (!bd->props->check_fb ||
+		    bd->props->check_fb(evdata->info)) {
+			bd->props->fb_blank = *(int *)evdata->data;
+			if (likely(bd->props && bd->props->update_status))
+				bd->props->update_status(bd);
+		}
+	up(&bd->sem);
+	return 0;
+}
+
+static int backlight_register_fb(struct backlight_device *bd)
+{
+	memset(&bd->fb_notif, 0, sizeof(bd->fb_notif));
+	bd->fb_notif.notifier_call = fb_notifier_callback;
+
+	return fb_register_client(&bd->fb_notif);
+}
+
+static void backlight_unregister_fb(struct backlight_device *bd)
+{
+	fb_unregister_client(&bd->fb_notif);
+}
+#else
+static inline int backlight_register_fb(struct backlight_device *bd)
+{
+	return 0;
+}
+
+static inline void backlight_unregister_fb(struct backlight_device *bd)
+{
+}
+#endif /* CONFIG_FB */
+
 static ssize_t backlight_show_power(struct class_device *cdev, char *buf)
 {
 	int rc = -ENXIO;
@@ -142,7 +195,7 @@ static struct class backlight_class = {
 	.store	= _store,					\
 }
 
-static struct class_device_attribute bl_class_device_attributes[] = {
+static const struct class_device_attribute bl_class_device_attributes[] = {
 	DECLARE_ATTR(power, 0644, backlight_show_power, backlight_store_power),
 	DECLARE_ATTR(brightness, 0644, backlight_show_brightness,
 		     backlight_store_brightness),
@@ -151,33 +204,6 @@ static struct class_device_attribute bl_class_device_attributes[] = {
 	DECLARE_ATTR(max_brightness, 0444, backlight_show_max_brightness, NULL),
 };
 
-/* This callback gets called when something important happens inside a
- * framebuffer driver. We're looking if that important event is blanking,
- * and if it is, we're switching backlight power as well ...
- */
-static int fb_notifier_callback(struct notifier_block *self,
-				unsigned long event, void *data)
-{
-	struct backlight_device *bd;
-	struct fb_event *evdata =(struct fb_event *)data;
-
-	/* If we aren't interested in this event, skip it immediately ... */
-	if (event != FB_EVENT_BLANK)
-		return 0;
-
-	bd = container_of(self, struct backlight_device, fb_notif);
-	down(&bd->sem);
-	if (bd->props)
-		if (!bd->props->check_fb ||
-		    bd->props->check_fb(evdata->info)) {
-			bd->props->fb_blank = *(int *)evdata->data;
-			if (likely(bd->props && bd->props->update_status))
-				bd->props->update_status(bd);
-		}
-	up(&bd->sem);
-	return 0;
-}
-
 /**
  * backlight_device_register - create and register a new object of
  *   backlight_device class.
@@ -215,10 +241,7 @@ error:		kfree(new_bd);
 		return ERR_PTR(rc);
 	}
 
-	memset(&new_bd->fb_notif, 0, sizeof(new_bd->fb_notif));
-	new_bd->fb_notif.notifier_call = fb_notifier_callback;
-
-	rc = fb_register_client(&new_bd->fb_notif);
+	rc = backlight_register_fb(new_bd);
 	if (unlikely(rc))
 		goto error;
 
@@ -259,16 +282,10 @@ void backlight_device_unregister(struct backlight_device *bd)
 					 &bl_class_device_attributes[i]);
 
 	down(&bd->sem);
-	if (likely(bd->props && bd->props->update_status)) {
-		bd->props->brightness = 0;
-		bd->props->power = 0;
-		bd->props->update_status(bd);
-	}
-
 	bd->props = NULL;
 	up(&bd->sem);
 
-	fb_unregister_client(&bd->fb_notif);
+	backlight_unregister_fb(bd);
 
 	class_device_unregister(&bd->class_dev);
 }
diff --git a/drivers/video/backlight/corgi_bl.c b/drivers/video/backlight/corgi_bl.c
index d07ecb53c68b..61587ca2cdbb 100644
--- a/drivers/video/backlight/corgi_bl.c
+++ b/drivers/video/backlight/corgi_bl.c
@@ -135,6 +135,10 @@ static int corgibl_probe(struct platform_device *pdev)
 
 static int corgibl_remove(struct platform_device *dev)
 {
+	corgibl_data.power = 0;
+	corgibl_data.brightness = 0;
+	corgibl_send_intensity(corgi_backlight_device);
+
 	backlight_device_unregister(corgi_backlight_device);
 
 	printk("Corgi Backlight Driver Unloaded\n");
diff --git a/drivers/video/backlight/hp680_bl.c b/drivers/video/backlight/hp680_bl.c
index e3993213d10e..1c569fb543ae 100644
--- a/drivers/video/backlight/hp680_bl.c
+++ b/drivers/video/backlight/hp680_bl.c
@@ -117,6 +117,10 @@ static int __init hp680bl_probe(struct platform_device *dev)
 
 static int hp680bl_remove(struct platform_device *dev)
 {
+	hp680bl_data.brightness = 0;
+	hp680bl_data.power = 0;
+	hp680bl_send_intensity(hp680_backlight_device);
+
 	backlight_device_unregister(hp680_backlight_device);
 
 	return 0;
diff --git a/drivers/video/backlight/lcd.c b/drivers/video/backlight/lcd.c
index bc8ab005a3fb..f6e041627edb 100644
--- a/drivers/video/backlight/lcd.c
+++ b/drivers/video/backlight/lcd.c
@@ -14,6 +14,53 @@
 #include <linux/err.h>
 #include <linux/fb.h>
 
+#if defined(CONFIG_FB) || (defined(CONFIG_FB_MODULE) && \
+			   defined(CONFIG_LCD_CLASS_DEVICE_MODULE))
+/* This callback gets called when something important happens inside a
+ * framebuffer driver. We're looking if that important event is blanking,
+ * and if it is, we're switching lcd power as well ...
+ */
+static int fb_notifier_callback(struct notifier_block *self,
+				 unsigned long event, void *data)
+{
+	struct lcd_device *ld;
+	struct fb_event *evdata = data;
+
+	/* If we aren't interested in this event, skip it immediately ... */
+	if (event != FB_EVENT_BLANK)
+		return 0;
+
+	ld = container_of(self, struct lcd_device, fb_notif);
+	down(&ld->sem);
+	if (ld->props)
+		if (!ld->props->check_fb || ld->props->check_fb(evdata->info))
+			ld->props->set_power(ld, *(int *)evdata->data);
+	up(&ld->sem);
+	return 0;
+}
+
+static int lcd_register_fb(struct lcd_device *ld)
+{
+	memset(&ld->fb_notif, 0, sizeof(&ld->fb_notif));
+	ld->fb_notif.notifier_call = fb_notifier_callback;
+	return fb_register_client(&ld->fb_notif);
+}
+
+static void lcd_unregister_fb(struct lcd_device *ld)
+{
+	fb_unregister_client(&ld->fb_notif);
+}
+#else
+static int lcd_register_fb(struct lcd_device *ld)
+{
+	return 0;
+}
+
+static inline void lcd_unregister_fb(struct lcd_device *ld)
+{
+}
+#endif /* CONFIG_FB */
+
 static ssize_t lcd_show_power(struct class_device *cdev, char *buf)
 {
 	int rc;
@@ -121,35 +168,12 @@ static struct class lcd_class = {
 	.store	= _store,					\
 }
 
-static struct class_device_attribute lcd_class_device_attributes[] = {
+static const struct class_device_attribute lcd_class_device_attributes[] = {
 	DECLARE_ATTR(power, 0644, lcd_show_power, lcd_store_power),
 	DECLARE_ATTR(contrast, 0644, lcd_show_contrast, lcd_store_contrast),
 	DECLARE_ATTR(max_contrast, 0444, lcd_show_max_contrast, NULL),
 };
 
-/* This callback gets called when something important happens inside a
- * framebuffer driver. We're looking if that important event is blanking,
- * and if it is, we're switching lcd power as well ...
- */
-static int fb_notifier_callback(struct notifier_block *self,
-				 unsigned long event, void *data)
-{
-	struct lcd_device *ld;
-	struct fb_event *evdata =(struct fb_event *)data;
-
-	/* If we aren't interested in this event, skip it immediately ... */
-	if (event != FB_EVENT_BLANK)
-		return 0;
-
-	ld = container_of(self, struct lcd_device, fb_notif);
-	down(&ld->sem);
-	if (ld->props)
-		if (!ld->props->check_fb || ld->props->check_fb(evdata->info))
-			ld->props->set_power(ld, *(int *)evdata->data);
-	up(&ld->sem);
-	return 0;
-}
-
 /**
  * lcd_device_register - register a new object of lcd_device class.
  * @name: the name of the new object(must be the same as the name of the
@@ -186,10 +210,8 @@ error:		kfree(new_ld);
 		return ERR_PTR(rc);
 	}
 
-	memset(&new_ld->fb_notif, 0, sizeof(new_ld->fb_notif));
-	new_ld->fb_notif.notifier_call = fb_notifier_callback;
+	rc = lcd_register_fb(new_ld);
 
-	rc = fb_register_client(&new_ld->fb_notif);
 	if (unlikely(rc))
 		goto error;
 
@@ -232,9 +254,7 @@ void lcd_device_unregister(struct lcd_device *ld)
 	down(&ld->sem);
 	ld->props = NULL;
 	up(&ld->sem);
-
-	fb_unregister_client(&ld->fb_notif);
-
+	lcd_unregister_fb(ld);
 	class_device_unregister(&ld->class_dev);
 }
 EXPORT_SYMBOL(lcd_device_unregister);
diff --git a/drivers/video/backlight/locomolcd.c b/drivers/video/backlight/locomolcd.c
index 628571c63bac..2d7905410b2a 100644
--- a/drivers/video/backlight/locomolcd.c
+++ b/drivers/video/backlight/locomolcd.c
@@ -200,6 +200,10 @@ static int locomolcd_remove(struct locomo_dev *dev)
 {
 	unsigned long flags;
 
+	locomobl_data.brightness = 0;
+	locomobl_data.power = 0;
+	locomolcd_set_intensity(locomolcd_bl_device);
+
 	backlight_device_unregister(locomolcd_bl_device);
 	local_irq_save(flags);
 	locomolcd_dev = NULL;
diff --git a/drivers/video/cfbimgblt.c b/drivers/video/cfbimgblt.c
index 51d35386a945..261004473c8e 100644
--- a/drivers/video/cfbimgblt.c
+++ b/drivers/video/cfbimgblt.c
@@ -42,7 +42,7 @@
 #define DPRINTK(fmt, args...)
 #endif
 
-static u32 cfb_tab8[] = {
+static const u32 cfb_tab8[] = {
 #if defined(__BIG_ENDIAN)
     0x00000000,0x000000ff,0x0000ff00,0x0000ffff,
     0x00ff0000,0x00ff00ff,0x00ffff00,0x00ffffff,
@@ -58,7 +58,7 @@ static u32 cfb_tab8[] = {
 #endif
 };
 
-static u32 cfb_tab16[] = {
+static const u32 cfb_tab16[] = {
 #if defined(__BIG_ENDIAN)
     0x00000000, 0x0000ffff, 0xffff0000, 0xffffffff
 #elif defined(__LITTLE_ENDIAN)
@@ -68,7 +68,7 @@ static u32 cfb_tab16[] = {
 #endif
 };
 
-static u32 cfb_tab32[] = {
+static const u32 cfb_tab32[] = {
 	0x00000000, 0xffffffff
 };
 
@@ -218,7 +218,7 @@ static inline void fast_imageblit(const struct fb_image *image, struct fb_info *
 	u32 bit_mask, end_mask, eorx, shift;
 	const char *s = image->data, *src;
 	u32 __iomem *dst;
-	u32 *tab = NULL;
+	const u32 *tab = NULL;
 	int i, j, k;
 		
 	switch (bpp) {
diff --git a/drivers/video/cirrusfb.c b/drivers/video/cirrusfb.c
index daf43f535a0b..2c4bc6205738 100644
--- a/drivers/video/cirrusfb.c
+++ b/drivers/video/cirrusfb.c
@@ -2442,7 +2442,10 @@ static int cirrusfb_pci_register (struct pci_dev *pdev,
 	printk ("Cirrus Logic chipset on PCI bus\n");
 	pci_set_drvdata(pdev, info);
 
-	return cirrusfb_register(cinfo);
+	ret = cirrusfb_register(cinfo);
+	if (ret)
+		iounmap(cinfo->fbmem);
+	return ret;
 
 err_release_legacy:
 	if (release_io_ports)
@@ -2574,7 +2577,15 @@ static int cirrusfb_zorro_register(struct zorro_dev *z,
 	printk (KERN_INFO "Cirrus Logic chipset on Zorro bus\n");
 	zorro_set_drvdata(z, info);
 
-	return cirrusfb_register(cinfo);
+	ret = cirrusfb_register(cinfo);
+	if (ret) {
+		if (btype == BT_PICASSO4) {
+			iounmap(cinfo->fbmem);
+			iounmap(cinfo->regbase - 0x600000);
+		} else if (board_addr > 0x01000000)
+			iounmap(cinfo->fbmem);
+	}
+	return ret;
 
 err_unmap_regbase:
 	/* Parental advisory: explicit hack */
diff --git a/drivers/video/console/softcursor.c b/drivers/video/console/softcursor.c
index 7d07d8383569..f577bd80e020 100644
--- a/drivers/video/console/softcursor.c
+++ b/drivers/video/console/softcursor.c
@@ -1,11 +1,13 @@
 /*
- * linux/drivers/video/softcursor.c -- Generic software cursor for frame buffer devices
+ * linux/drivers/video/softcursor.c
+ *
+ * Generic software cursor for frame buffer devices
  *
  *  Created 14 Nov 2002 by James Simmons
  *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file COPYING in the main directory of this archive
- * for more details.
+ * This file 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.
  */
 
 #include <linux/module.h>
@@ -25,7 +27,7 @@ int soft_cursor(struct fb_info *info, struct fb_cursor *cursor)
 	unsigned int buf_align = info->pixmap.buf_align - 1;
 	unsigned int i, size, dsize, s_pitch, d_pitch;
 	struct fb_image *image;
-	u8 *dst;
+	u8 *src, *dst;
 
 	if (info->state != FBINFO_STATE_RUNNING)
 		return 0;
@@ -45,7 +47,8 @@ int soft_cursor(struct fb_info *info, struct fb_cursor *cursor)
 		}
 	}
 
-	image = (struct fb_image *) (ops->cursor_src + dsize);
+	src = ops->cursor_src + sizeof(struct fb_image);
+	image = (struct fb_image *)ops->cursor_src;
 	*image = cursor->image;
 	d_pitch = (s_pitch + scan_align) & ~scan_align;
 
@@ -57,21 +60,18 @@ int soft_cursor(struct fb_info *info, struct fb_cursor *cursor)
 		switch (cursor->rop) {
 		case ROP_XOR:
 			for (i = 0; i < dsize; i++)
-				ops->cursor_src[i] = image->data[i] ^
-					cursor->mask[i];
+				src[i] = image->data[i] ^ cursor->mask[i];
 			break;
 		case ROP_COPY:
 		default:
 			for (i = 0; i < dsize; i++)
-				ops->cursor_src[i] = image->data[i] &
-					cursor->mask[i];
+				src[i] = image->data[i] & cursor->mask[i];
 			break;
 		}
 	} else
-		memcpy(ops->cursor_src, image->data, dsize);
+		memcpy(src, image->data, dsize);
 
-	fb_pad_aligned_buffer(dst, d_pitch, ops->cursor_src, s_pitch,
-			      image->height);
+	fb_pad_aligned_buffer(dst, d_pitch, src, s_pitch, image->height);
 	image->data = dst;
 	info->fbops->fb_imageblit(info, image);
 	return 0;
diff --git a/drivers/video/console/sticon.c b/drivers/video/console/sticon.c
index 45586aaabd1e..57b21e533036 100644
--- a/drivers/video/console/sticon.c
+++ b/drivers/video/console/sticon.c
@@ -345,7 +345,7 @@ static void sticon_save_screen(struct vc_data *conp)
 {
 }
 
-static struct consw sti_con = {
+static const struct consw sti_con = {
 	.owner			= THIS_MODULE,
 	.con_startup		= sticon_startup,
 	.con_init		= sticon_init,
diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c
index 0a2c10a1abf8..4a9bde2c839b 100644
--- a/drivers/video/console/vgacon.c
+++ b/drivers/video/console/vgacon.c
@@ -93,27 +93,27 @@ static void vgacon_invert_region(struct vc_data *c, u16 * p, int count);
 static unsigned long vgacon_uni_pagedir[2];
 
 /* Description of the hardware situation */
-static unsigned long	vga_vram_base;		/* Base of video memory */
-static unsigned long	vga_vram_end;		/* End of video memory */
-static int		vga_vram_size;		/* Size of video memory */
-static u16		vga_video_port_reg;	/* Video register select port */
-static u16		vga_video_port_val;	/* Video register value port */
-static unsigned int	vga_video_num_columns;	/* Number of text columns */
-static unsigned int	vga_video_num_lines;	/* Number of text lines */
-static int		vga_can_do_color = 0;	/* Do we support colors? */
-static unsigned int	vga_default_font_height;/* Height of default screen font */
-static unsigned char	vga_video_type;		/* Card type */
-static unsigned char	vga_hardscroll_enabled;
-static unsigned char	vga_hardscroll_user_enable = 1;
+static int		vga_init_done		__read_mostly;
+static unsigned long	vga_vram_base		__read_mostly;	/* Base of video memory */
+static unsigned long	vga_vram_end		__read_mostly;	/* End of video memory */
+static unsigned int	vga_vram_size		__read_mostly;	/* Size of video memory */
+static u16		vga_video_port_reg	__read_mostly;	/* Video register select port */
+static u16		vga_video_port_val	__read_mostly;	/* Video register value port */
+static unsigned int	vga_video_num_columns;			/* Number of text columns */
+static unsigned int	vga_video_num_lines;			/* Number of text lines */
+static int		vga_can_do_color	__read_mostly;	/* Do we support colors? */
+static unsigned int	vga_default_font_height __read_mostly;	/* Height of default screen font */
+static unsigned char	vga_video_type		__read_mostly;	/* Card type */
+static unsigned char	vga_hardscroll_enabled	__read_mostly;
+static unsigned char	vga_hardscroll_user_enable __read_mostly = 1;
 static unsigned char	vga_font_is_default = 1;
 static int		vga_vesa_blanked;
 static int 		vga_palette_blanked;
 static int 		vga_is_gfx;
 static int 		vga_512_chars;
 static int 		vga_video_font_height;
-static int 		vga_scan_lines;
-static unsigned int 	vga_rolled_over = 0;
-static int              vga_init_done;
+static int 		vga_scan_lines		__read_mostly;
+static unsigned int 	vga_rolled_over;
 
 static int __init no_scroll(char *str)
 {
diff --git a/drivers/video/cyberfb.c b/drivers/video/cyberfb.c
index c40e72dafb0e..0b8d5b121152 100644
--- a/drivers/video/cyberfb.c
+++ b/drivers/video/cyberfb.c
@@ -109,8 +109,6 @@ static void cv64_dump(void);
 #define wb_64(regs,reg,dat) (*(((volatile unsigned char *)regs) + reg) = dat)
 #define rb_64(regs, reg) (*(((volatile unsigned char *)regs) + reg))
 
-#define ww_64(regs,reg,dat) (*((volatile unsigned short *)(regs + reg) = dat)
-
 struct cyberfb_par {
 	struct fb_var_screeninfo var;
 	__u32 type;
@@ -1055,6 +1053,8 @@ int __init cyberfb_init(void)
 
 	    if (register_framebuffer(&fb_info) < 0) {
 		    DPRINTK("EXIT - register_framebuffer failed\n");
+			if (CyberBase)
+				iounmap(CyberBase);
 		    release_mem_region(CyberMem_phys, 0x400000);
 		    release_mem_region(CyberRegs_phys, 0x10000);
 		    return -EINVAL;
diff --git a/drivers/video/epson1355fb.c b/drivers/video/epson1355fb.c
index 737257d278f0..29e07c109887 100644
--- a/drivers/video/epson1355fb.c
+++ b/drivers/video/epson1355fb.c
@@ -405,7 +405,7 @@ static inline unsigned long copy_to_user16(void *to, const void *from,
 static ssize_t
 epson1355fb_read(struct file *file, char *buf, size_t count, loff_t * ppos)
 {
-	struct inode *inode = file->f_dentry->d_inode;
+	struct inode *inode = file->f_path.dentry->d_inode;
 	int fbidx = iminor(inode);
 	struct fb_info *info = registered_fb[fbidx];
 	unsigned long p = *ppos;
@@ -437,7 +437,7 @@ static ssize_t
 epson1355fb_write(struct file *file, const char *buf,
 		  size_t count, loff_t * ppos)
 {
-	struct inode *inode = file->f_dentry->d_inode;
+	struct inode *inode = file->f_path.dentry->d_inode;
 	int fbidx = iminor(inode);
 	struct fb_info *info = registered_fb[fbidx];
 	unsigned long p = *ppos;
diff --git a/drivers/video/fbcmap.c b/drivers/video/fbcmap.c
index e8b135f3d80d..148108afdd51 100644
--- a/drivers/video/fbcmap.c
+++ b/drivers/video/fbcmap.c
@@ -18,63 +18,64 @@
 
 #include <asm/uaccess.h>
 
-static u16 red2[] = {
+static u16 red2[] __read_mostly = {
     0x0000, 0xaaaa
 };
-static u16 green2[] = {
+static u16 green2[] __read_mostly = {
     0x0000, 0xaaaa
 };
-static u16 blue2[] = {
+static u16 blue2[] __read_mostly = {
     0x0000, 0xaaaa
 };
 
-static u16 red4[] = {
+static u16 red4[] __read_mostly = {
     0x0000, 0xaaaa, 0x5555, 0xffff
 };
-static u16 green4[] = {
+static u16 green4[] __read_mostly = {
     0x0000, 0xaaaa, 0x5555, 0xffff
 };
-static u16 blue4[] = {
+static u16 blue4[] __read_mostly = {
     0x0000, 0xaaaa, 0x5555, 0xffff
 };
 
-static u16 red8[] = {
+static u16 red8[] __read_mostly = {
     0x0000, 0x0000, 0x0000, 0x0000, 0xaaaa, 0xaaaa, 0xaaaa, 0xaaaa
 };
-static u16 green8[] = {
+static u16 green8[] __read_mostly = {
     0x0000, 0x0000, 0xaaaa, 0xaaaa, 0x0000, 0x0000, 0x5555, 0xaaaa
 };
-static u16 blue8[] = {
+static u16 blue8[] __read_mostly = {
     0x0000, 0xaaaa, 0x0000, 0xaaaa, 0x0000, 0xaaaa, 0x0000, 0xaaaa
 };
 
-static u16 red16[] = {
+static u16 red16[] __read_mostly = {
     0x0000, 0x0000, 0x0000, 0x0000, 0xaaaa, 0xaaaa, 0xaaaa, 0xaaaa,
     0x5555, 0x5555, 0x5555, 0x5555, 0xffff, 0xffff, 0xffff, 0xffff
 };
-static u16 green16[] = {
+static u16 green16[] __read_mostly = {
     0x0000, 0x0000, 0xaaaa, 0xaaaa, 0x0000, 0x0000, 0x5555, 0xaaaa,
     0x5555, 0x5555, 0xffff, 0xffff, 0x5555, 0x5555, 0xffff, 0xffff
 };
-static u16 blue16[] = {
+static u16 blue16[] __read_mostly = {
     0x0000, 0xaaaa, 0x0000, 0xaaaa, 0x0000, 0xaaaa, 0x0000, 0xaaaa,
     0x5555, 0xffff, 0x5555, 0xffff, 0x5555, 0xffff, 0x5555, 0xffff
 };
 
-static struct fb_cmap default_2_colors = {
-    0, 2, red2, green2, blue2, NULL
+static const struct fb_cmap default_2_colors = {
+    .len=2, .red=red2, .green=green2, .blue=blue2
 };
-static struct fb_cmap default_8_colors = {
-    0, 8, red8, green8, blue8, NULL
+static const struct fb_cmap default_8_colors = {
+    .len=8, .red=red8, .green=green8, .blue=blue8
 };
-static struct fb_cmap default_4_colors = {
-    0, 4, red4, green4, blue4, NULL
+static const struct fb_cmap default_4_colors = {
+    .len=4, .red=red4, .green=green4, .blue=blue4
 };
-static struct fb_cmap default_16_colors = {
-    0, 16, red16, green16, blue16, NULL
+static const struct fb_cmap default_16_colors = {
+    .len=16, .red=red16, .green=green16, .blue=blue16
 };
 
 
+
 /**
  *	fb_alloc_cmap - allocate a colormap
  *	@cmap: frame buffer colormap structure
@@ -146,7 +147,7 @@ void fb_dealloc_cmap(struct fb_cmap *cmap)
  *	Copy contents of colormap from @from to @to.
  */
 
-int fb_copy_cmap(struct fb_cmap *from, struct fb_cmap *to)
+int fb_copy_cmap(const struct fb_cmap *from, struct fb_cmap *to)
 {
 	int tooff = 0, fromoff = 0;
 	int size;
@@ -170,7 +171,7 @@ int fb_copy_cmap(struct fb_cmap *from, struct fb_cmap *to)
 	return 0;
 }
 
-int fb_cmap_to_user(struct fb_cmap *from, struct fb_cmap_user *to)
+int fb_cmap_to_user(const struct fb_cmap *from, struct fb_cmap_user *to)
 {
 	int tooff = 0, fromoff = 0;
 	int size;
@@ -282,7 +283,7 @@ int fb_set_user_cmap(struct fb_cmap_user *cmap, struct fb_info *info)
  *
  */
 
-struct fb_cmap *fb_default_cmap(int len)
+const struct fb_cmap *fb_default_cmap(int len)
 {
     if (len <= 2)
 	return &default_2_colors;
@@ -305,22 +306,22 @@ void fb_invert_cmaps(void)
 {
     u_int i;
 
-    for (i = 0; i < 2; i++) {
+    for (i = 0; i < ARRAY_SIZE(red2); i++) {
 	red2[i] = ~red2[i];
 	green2[i] = ~green2[i];
 	blue2[i] = ~blue2[i];
     }
-    for (i = 0; i < 4; i++) {
+    for (i = 0; i < ARRAY_SIZE(red4); i++) {
 	red4[i] = ~red4[i];
 	green4[i] = ~green4[i];
 	blue4[i] = ~blue4[i];
     }
-    for (i = 0; i < 8; i++) {
+    for (i = 0; i < ARRAY_SIZE(red8); i++) {
 	red8[i] = ~red8[i];
 	green8[i] = ~green8[i];
 	blue8[i] = ~blue8[i];
     }
-    for (i = 0; i < 16; i++) {
+    for (i = 0; i < ARRAY_SIZE(red16); i++) {
 	red16[i] = ~red16[i];
 	green16[i] = ~green16[i];
 	blue16[i] = ~blue16[i];
diff --git a/drivers/video/fbcvt.c b/drivers/video/fbcvt.c
index b5498999c4ec..0847c5e72cbd 100644
--- a/drivers/video/fbcvt.c
+++ b/drivers/video/fbcvt.c
@@ -57,7 +57,7 @@ struct fb_cvt_data {
 	u32 status;
 };
 
-static int fb_cvt_vbi_tab[] = {
+static const unsigned char fb_cvt_vbi_tab[] = {
 	4,        /* 4:3      */
 	5,        /* 16:9     */
 	6,        /* 16:10    */
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
index e973a87fbb01..3cfea315a48f 100644
--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbmem.c
@@ -52,8 +52,8 @@
 
 #define FBPIXMAPSIZE	(1024 * 8)
 
-struct fb_info *registered_fb[FB_MAX];
-int num_registered_fb;
+struct fb_info *registered_fb[FB_MAX] __read_mostly;
+int num_registered_fb __read_mostly;
 
 /*
  * Helpers
@@ -202,7 +202,7 @@ static void  fb_set_logo_truepalette(struct fb_info *info,
 					    const struct linux_logo *logo,
 					    u32 *palette)
 {
-	unsigned char mask[9] = { 0,0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe,0xff };
+	static const unsigned char mask[] = { 0,0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe,0xff };
 	unsigned char redmask, greenmask, bluemask;
 	int redshift, greenshift, blueshift;
 	int i;
@@ -317,7 +317,7 @@ static struct logo_data {
 	int needs_truepalette;
 	int needs_cmapreset;
 	const struct linux_logo *logo;
-} fb_logo;
+} fb_logo __read_mostly;
 
 static void fb_rotate_logo_ud(const u8 *in, u8 *out, u32 width, u32 height)
 {
@@ -572,7 +572,7 @@ static ssize_t
 fb_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
 {
 	unsigned long p = *ppos;
-	struct inode *inode = file->f_dentry->d_inode;
+	struct inode *inode = file->f_path.dentry->d_inode;
 	int fbidx = iminor(inode);
 	struct fb_info *info = registered_fb[fbidx];
 	u32 *buffer, *dst;
@@ -647,7 +647,7 @@ static ssize_t
 fb_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
 {
 	unsigned long p = *ppos;
-	struct inode *inode = file->f_dentry->d_inode;
+	struct inode *inode = file->f_path.dentry->d_inode;
 	int fbidx = iminor(inode);
 	struct fb_info *info = registered_fb[fbidx];
 	u32 *buffer, *src;
@@ -1081,7 +1081,7 @@ static int fb_get_fscreeninfo(struct inode *inode, struct file *file,
 static long
 fb_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 {
-	struct inode *inode = file->f_dentry->d_inode;
+	struct inode *inode = file->f_path.dentry->d_inode;
 	int fbidx = iminor(inode);
 	struct fb_info *info = registered_fb[fbidx];
 	struct fb_ops *fb = info->fbops;
@@ -1121,7 +1121,7 @@ fb_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 static int 
 fb_mmap(struct file *file, struct vm_area_struct * vma)
 {
-	int fbidx = iminor(file->f_dentry->d_inode);
+	int fbidx = iminor(file->f_path.dentry->d_inode);
 	struct fb_info *info = registered_fb[fbidx];
 	struct fb_ops *fb = info->fbops;
 	unsigned long off;
@@ -1253,7 +1253,7 @@ fb_release(struct inode *inode, struct file *file)
 	return 0;
 }
 
-static struct file_operations fb_fops = {
+static const struct file_operations fb_fops = {
 	.owner =	THIS_MODULE,
 	.read =		fb_read,
 	.write =	fb_write,
@@ -1459,8 +1459,8 @@ int fb_new_modelist(struct fb_info *info)
 	return err;
 }
 
-static char *video_options[FB_MAX];
-static int ofonly;
+static char *video_options[FB_MAX] __read_mostly;
+static int ofonly __read_mostly;
 
 extern const char *global_mode_option;
 
diff --git a/drivers/video/fbmon.c b/drivers/video/fbmon.c
index de93139ccbb5..6b385c39b8b5 100644
--- a/drivers/video/fbmon.c
+++ b/drivers/video/fbmon.c
@@ -58,7 +58,7 @@ struct broken_edid {
 	u32 fix;
 };
 
-static struct broken_edid brokendb[] = {
+static const struct broken_edid brokendb[] = {
 	/* DEC FR-PCXAV-YZ */
 	{
 		.manufacturer = "DEC",
diff --git a/drivers/video/ffb.c b/drivers/video/ffb.c
index 2a0e8210d398..949141bd44d4 100644
--- a/drivers/video/ffb.c
+++ b/drivers/video/ffb.c
@@ -968,6 +968,8 @@ static int ffb_init_one(struct of_device *op)
 
 	if (fb_alloc_cmap(&all->info.cmap, 256, 0)) {
 		printk(KERN_ERR "ffb: Could not allocate color map.\n");
+		of_iounmap(all->par.fbc, sizeof(struct ffb_fbc));
+		of_iounmap(all->par.dac, sizeof(struct ffb_dac));
 		kfree(all);
 		return -ENOMEM;
 	}
@@ -978,6 +980,8 @@ static int ffb_init_one(struct of_device *op)
 	if (err < 0) {
 		printk(KERN_ERR "ffb: Could not register framebuffer.\n");
 		fb_dealloc_cmap(&all->info.cmap);
+		of_iounmap(all->par.fbc, sizeof(struct ffb_fbc));
+		of_iounmap(all->par.dac, sizeof(struct ffb_dac));
 		kfree(all);
 		return err;
 	}
diff --git a/drivers/video/fm2fb.c b/drivers/video/fm2fb.c
index 998374cfae6d..70ff55b14596 100644
--- a/drivers/video/fm2fb.c
+++ b/drivers/video/fm2fb.c
@@ -283,6 +283,7 @@ static int __devinit fm2fb_probe(struct zorro_dev *z,
 
 	if (register_framebuffer(info) < 0) {
 		fb_dealloc_cmap(&info->cmap);
+		iounmap(info->screen_base);
 		framebuffer_release(info);
 		zorro_release_device(z);
 		return -EINVAL;
diff --git a/drivers/video/geode/Kconfig b/drivers/video/geode/Kconfig
index 4e173ef20a7d..a814b6c2605c 100644
--- a/drivers/video/geode/Kconfig
+++ b/drivers/video/geode/Kconfig
@@ -23,6 +23,26 @@ config FB_GEODE_GX
 
 	  If unsure, say N.
 
+config FB_GEODE_GX_SET_FBSIZE
+	bool "Manually specify the Geode GX framebuffer size"
+	depends on FB_GEODE_GX
+	default n
+	---help---
+	  If you want to manually specify the size of your GX framebuffer,
+	  say Y here, otherwise say N to dynamically probe it.
+
+	  Say N unless you know what you are doing.
+
+config FB_GEODE_GX_FBSIZE
+	hex "Size of the GX framebuffer, in bytes"
+	depends on FB_GEODE_GX_SET_FBSIZE
+	default "0x1600000"
+	---help---
+	  Specify the size of the GX framebuffer.  Normally, you will
+	  want this to be MB aligned.  Common values are 0x80000 (8MB)
+	  and 0x1600000 (16MB).  Don't change this unless you know what
+	  you are doing
+
 config FB_GEODE_GX1
 	tristate "AMD Geode GX1 framebuffer support (EXPERIMENTAL)"
 	depends on FB && FB_GEODE && EXPERIMENTAL
diff --git a/drivers/video/geode/display_gx.c b/drivers/video/geode/display_gx.c
index 825c3405f5c2..0f16e4bffc6c 100644
--- a/drivers/video/geode/display_gx.c
+++ b/drivers/video/geode/display_gx.c
@@ -21,11 +21,27 @@
 #include "geodefb.h"
 #include "display_gx.h"
 
-int gx_frame_buffer_size(void)
+#ifdef CONFIG_FB_GEODE_GX_SET_FBSIZE
+unsigned int gx_frame_buffer_size(void)
 {
-	/* Assuming 16 MiB. */
-	return 16*1024*1024;
+	return CONFIG_FB_GEODE_GX_FBSIZE;
 }
+#else
+unsigned int gx_frame_buffer_size(void)
+{
+	unsigned int val;
+
+	/* FB size is reported by a virtual register */
+	/* Virtual register class = 0x02 */
+	/* VG_MEM_SIZE(512Kb units) = 0x00 */
+
+	outw(0xFC53, 0xAC1C);
+	outw(0x0200, 0xAC1C);
+
+	val = (unsigned int)(inw(0xAC1E)) & 0xFFl;
+	return (val << 19);
+}
+#endif
 
 int gx_line_delta(int xres, int bpp)
 {
@@ -81,6 +97,7 @@ static void gx_set_mode(struct fb_info *info)
 	writel(((info->var.xres * info->var.bits_per_pixel/8) >> 3) + 2,
 	       par->dc_regs + DC_LINE_SIZE);
 
+
 	/* Enable graphics and video data and unmask address lines. */
 	dcfg |= DC_DCFG_GDEN | DC_DCFG_VDEN | DC_DCFG_A20M | DC_DCFG_A18M;
 
diff --git a/drivers/video/geode/display_gx.h b/drivers/video/geode/display_gx.h
index 86c623361305..0af33f329e88 100644
--- a/drivers/video/geode/display_gx.h
+++ b/drivers/video/geode/display_gx.h
@@ -11,11 +11,15 @@
 #ifndef __DISPLAY_GX_H__
 #define __DISPLAY_GX_H__
 
-int gx_frame_buffer_size(void);
+unsigned int gx_frame_buffer_size(void);
 int gx_line_delta(int xres, int bpp);
 
 extern struct geode_dc_ops gx_dc_ops;
 
+/* MSR that tells us if a TFT or CRT is attached */
+#define GLD_MSR_CONFIG   0xC0002001
+#define GLD_MSR_CONFIG_DM_FP 0x40
+
 /* Display controller registers */
 
 #define DC_UNLOCK 0x00
@@ -93,4 +97,5 @@ extern struct geode_dc_ops gx_dc_ops;
 #define DC_PAL_ADDRESS 0x70
 #define DC_PAL_DATA    0x74
 
+#define DC_GLIU0_MEM_OFFSET 0x84
 #endif /* !__DISPLAY_GX1_H__ */
diff --git a/drivers/video/geode/gxfb_core.c b/drivers/video/geode/gxfb_core.c
index a454dcb8e215..cf841efa229a 100644
--- a/drivers/video/geode/gxfb_core.c
+++ b/drivers/video/geode/gxfb_core.c
@@ -35,10 +35,10 @@
 #include "display_gx.h"
 #include "video_gx.h"
 
-static char mode_option[32] = "640x480-16@60";
+static char *mode_option;
 
 /* Modes relevant to the GX (taken from modedb.c) */
-static const struct fb_videomode __initdata gx_modedb[] = {
+static const struct fb_videomode gx_modedb[] __initdata = {
 	/* 640x480-60 VESA */
 	{ NULL, 60, 640, 480, 39682,  48, 16, 33, 10, 96, 2,
 	  0, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
@@ -240,6 +240,12 @@ static int __init gxfb_map_video_memory(struct fb_info *info, struct pci_dev *de
 	if (!info->screen_base)
 		return -ENOMEM;
 
+	/* Set the 16MB aligned base address of the graphics memory region
+	 * in the display controller */
+
+	writel(info->fix.smem_start & 0xFF000000,
+			par->dc_regs + DC_GLIU0_MEM_OFFSET);
+
 	dev_info(&dev->dev, "%d Kibyte of video memory at 0x%lx\n",
 		 info->fix.smem_len / 1024, info->fix.smem_start);
 
@@ -302,6 +308,7 @@ static int __init gxfb_probe(struct pci_dev *pdev, const struct pci_device_id *i
 	struct geodefb_par *par;
 	struct fb_info *info;
 	int ret;
+	unsigned long val;
 
 	info = gxfb_init_fbinfo(&pdev->dev);
 	if (!info)
@@ -317,6 +324,15 @@ static int __init gxfb_probe(struct pci_dev *pdev, const struct pci_device_id *i
 		goto err;
 	}
 
+	/* Figure out if this is a TFT or CRT part */
+
+	rdmsrl(GLD_MSR_CONFIG, val);
+
+	if ((val & GLD_MSR_CONFIG_DM_FP) == GLD_MSR_CONFIG_DM_FP)
+		par->enable_crt = 0;
+	else
+		par->enable_crt = 1;
+
 	ret = fb_find_mode(&info->var, info, mode_option,
 			   gx_modedb, ARRAY_SIZE(gx_modedb), NULL, 16);
 	if (ret == 0 || ret == 4) {
@@ -325,7 +341,8 @@ static int __init gxfb_probe(struct pci_dev *pdev, const struct pci_device_id *i
 		goto err;
 	}
 
-        /* Clear the frame buffer of garbage. */
+
+	/* Clear the frame buffer of garbage. */
         memset_io(info->screen_base, 0, info->fix.smem_len);
 
 	gxfb_check_var(&info->var, info);
@@ -395,11 +412,35 @@ static struct pci_driver gxfb_driver = {
 	.remove		= gxfb_remove,
 };
 
+#ifndef MODULE
+static int __init gxfb_setup(char *options)
+{
+
+	char *opt;
+
+	if (!options || !*options)
+		return 0;
+
+	while ((opt = strsep(&options, ",")) != NULL) {
+		if (!*opt)
+			continue;
+
+		mode_option = opt;
+	}
+
+	return 0;
+}
+#endif
+
 static int __init gxfb_init(void)
 {
 #ifndef MODULE
-	if (fb_get_options("gxfb", NULL))
+	char *option = NULL;
+
+	if (fb_get_options("gxfb", &option))
 		return -ENODEV;
+
+	gxfb_setup(option);
 #endif
 	return pci_register_driver(&gxfb_driver);
 }
@@ -412,8 +453,8 @@ static void __exit gxfb_cleanup(void)
 module_init(gxfb_init);
 module_exit(gxfb_cleanup);
 
-module_param_string(mode, mode_option, sizeof(mode_option), 0444);
-MODULE_PARM_DESC(mode, "video mode (<x>x<y>[-<bpp>][@<refr>])");
+module_param(mode_option, charp, 0);
+MODULE_PARM_DESC(mode_option, "video mode (<x>x<y>[-<bpp>][@<refr>])");
 
 MODULE_DESCRIPTION("Framebuffer driver for the AMD Geode GX");
 MODULE_LICENSE("GPL");
diff --git a/drivers/video/geode/video_gx.c b/drivers/video/geode/video_gx.c
index 2b2a7880ea75..7f3f18d06718 100644
--- a/drivers/video/geode/video_gx.c
+++ b/drivers/video/geode/video_gx.c
@@ -175,13 +175,88 @@ static void gx_set_dclk_frequency(struct fb_info *info)
 	} while (timeout-- && !(dotpll & MSR_GLCP_DOTPLL_LOCK));
 }
 
+static void
+gx_configure_tft(struct fb_info *info)
+{
+	struct geodefb_par *par = info->par;
+	unsigned long val;
+	unsigned long fp;
+
+	/* Set up the DF pad select MSR */
+
+	rdmsrl(GX_VP_MSR_PAD_SELECT, val);
+	val &= ~GX_VP_PAD_SELECT_MASK;
+	val |= GX_VP_PAD_SELECT_TFT;
+	wrmsrl(GX_VP_MSR_PAD_SELECT, val);
+
+	/* Turn off the panel */
+
+	fp = readl(par->vid_regs + GX_FP_PM);
+	fp &= ~GX_FP_PM_P;
+	writel(fp, par->vid_regs + GX_FP_PM);
+
+	/* Set timing 1 */
+
+	fp = readl(par->vid_regs + GX_FP_PT1);
+	fp &= GX_FP_PT1_VSIZE_MASK;
+	fp |= info->var.yres << GX_FP_PT1_VSIZE_SHIFT;
+	writel(fp, par->vid_regs + GX_FP_PT1);
+
+	/* Timing 2 */
+	/* Set bits that are always on for TFT */
+
+	fp = 0x0F100000;
+
+	/* Add sync polarity */
+
+	if (!(info->var.sync & FB_SYNC_VERT_HIGH_ACT))
+		fp |= GX_FP_PT2_VSP;
+
+	if (!(info->var.sync & FB_SYNC_HOR_HIGH_ACT))
+		fp |= GX_FP_PT2_HSP;
+
+	writel(fp, par->vid_regs + GX_FP_PT2);
+
+	/*  Set the dither control */
+	writel(0x70, par->vid_regs + GX_FP_DFC);
+
+	/* Enable the FP data and power (in case the BIOS didn't) */
+
+	fp = readl(par->vid_regs + GX_DCFG);
+	fp |= GX_DCFG_FP_PWR_EN | GX_DCFG_FP_DATA_EN;
+	writel(fp, par->vid_regs + GX_DCFG);
+
+	/* Unblank the panel */
+
+	fp = readl(par->vid_regs + GX_FP_PM);
+	fp |= GX_FP_PM_P;
+	writel(fp, par->vid_regs + GX_FP_PM);
+}
+
 static void gx_configure_display(struct fb_info *info)
 {
 	struct geodefb_par *par = info->par;
-	u32 dcfg, fp_pm;
+	u32 dcfg, misc;
+
+	/* Set up the MISC register */
+
+	misc = readl(par->vid_regs + GX_MISC);
+
+	/* Power up the DAC */
+	misc &= ~(GX_MISC_A_PWRDN | GX_MISC_DAC_PWRDN);
+
+	/* Disable gamma correction */
+	misc |= GX_MISC_GAM_EN;
+
+	writel(misc, par->vid_regs + GX_MISC);
 
+	/* Write the display configuration */
 	dcfg = readl(par->vid_regs + GX_DCFG);
 
+	/* Disable hsync and vsync */
+	dcfg &= ~(GX_DCFG_VSYNC_EN | GX_DCFG_HSYNC_EN);
+	writel(dcfg, par->vid_regs + GX_DCFG);
+
 	/* Clear bits from existing mode. */
 	dcfg &= ~(GX_DCFG_CRT_SYNC_SKW_MASK
 		  | GX_DCFG_CRT_HSYNC_POL   | GX_DCFG_CRT_VSYNC_POL
@@ -199,12 +274,19 @@ static void gx_configure_display(struct fb_info *info)
 	if (info->var.sync & FB_SYNC_VERT_HIGH_ACT)
 		dcfg |= GX_DCFG_CRT_VSYNC_POL;
 
+	/* Enable the display logic */
+	/* Set up the DACS to blank normally */
+
+	dcfg |= GX_DCFG_CRT_EN | GX_DCFG_DAC_BL_EN;
+
+	/* Enable the external DAC VREF? */
+
 	writel(dcfg, par->vid_regs + GX_DCFG);
 
-	/* Power on flat panel. */
-	fp_pm = readl(par->vid_regs + GX_FP_PM);
-	fp_pm |= GX_FP_PM_P;
-	writel(fp_pm, par->vid_regs + GX_FP_PM);
+	/* Set up the flat panel (if it is enabled) */
+
+	if (par->enable_crt == 0)
+		gx_configure_tft(info);
 }
 
 static int gx_blank_display(struct fb_info *info, int blank_mode)
@@ -245,12 +327,15 @@ static int gx_blank_display(struct fb_info *info, int blank_mode)
 	writel(dcfg, par->vid_regs + GX_DCFG);
 
 	/* Power on/off flat panel. */
-	fp_pm = readl(par->vid_regs + GX_FP_PM);
-	if (blank_mode == FB_BLANK_POWERDOWN)
-		fp_pm &= ~GX_FP_PM_P;
-	else
-		fp_pm |= GX_FP_PM_P;
-	writel(fp_pm, par->vid_regs + GX_FP_PM);
+
+	if (par->enable_crt == 0) {
+		fp_pm = readl(par->vid_regs + GX_FP_PM);
+		if (blank_mode == FB_BLANK_POWERDOWN)
+			fp_pm &= ~GX_FP_PM_P;
+		else
+			fp_pm |= GX_FP_PM_P;
+		writel(fp_pm, par->vid_regs + GX_FP_PM);
+	}
 
 	return 0;
 }
diff --git a/drivers/video/geode/video_gx.h b/drivers/video/geode/video_gx.h
index 2d9211f3ed84..ce28d8f382dc 100644
--- a/drivers/video/geode/video_gx.h
+++ b/drivers/video/geode/video_gx.h
@@ -13,6 +13,11 @@
 
 extern struct geode_vid_ops gx_vid_ops;
 
+/* GX Flatpanel control MSR */
+#define GX_VP_MSR_PAD_SELECT           0xC0002011
+#define GX_VP_PAD_SELECT_MASK          0x3FFFFFFF
+#define GX_VP_PAD_SELECT_TFT           0x1FFFFFFF
+
 /* Geode GX video processor registers */
 
 #define GX_DCFG		0x0008
@@ -20,6 +25,8 @@ extern struct geode_vid_ops gx_vid_ops;
 #  define GX_DCFG_HSYNC_EN		0x00000002
 #  define GX_DCFG_VSYNC_EN		0x00000004
 #  define GX_DCFG_DAC_BL_EN		0x00000008
+#  define GX_DCFG_FP_PWR_EN		0x00000040
+#  define GX_DCFG_FP_DATA_EN		0x00000080
 #  define GX_DCFG_CRT_HSYNC_POL		0x00000100
 #  define GX_DCFG_CRT_VSYNC_POL		0x00000200
 #  define GX_DCFG_CRT_SYNC_SKW_MASK	0x0001C000
@@ -28,10 +35,28 @@ extern struct geode_vid_ops gx_vid_ops;
 #  define GX_DCFG_GV_GAM		0x00200000
 #  define GX_DCFG_DAC_VREF		0x04000000
 
+/* Geode GX MISC video configuration */
+
+#define GX_MISC 0x50
+#define GX_MISC_GAM_EN     0x00000001
+#define GX_MISC_DAC_PWRDN  0x00000400
+#define GX_MISC_A_PWRDN    0x00000800
+
 /* Geode GX flat panel display control registers */
+
+#define GX_FP_PT1 0x0400
+#define GX_FP_PT1_VSIZE_MASK 0x7FF0000
+#define GX_FP_PT1_VSIZE_SHIFT 16
+
+#define GX_FP_PT2 0x408
+#define GX_FP_PT2_VSP (1 << 23)
+#define GX_FP_PT2_HSP (1 << 22)
+
 #define GX_FP_PM 0x410
 #  define GX_FP_PM_P 0x01000000
 
+#define GX_FP_DFC 0x418
+
 /* Geode GX clock control MSRs */
 
 #define MSR_GLCP_SYS_RSTPLL	0x4c000014
diff --git a/drivers/video/hpfb.c b/drivers/video/hpfb.c
index 91cf3b577d15..9ab9b839a0f5 100644
--- a/drivers/video/hpfb.c
+++ b/drivers/video/hpfb.c
@@ -295,6 +295,8 @@ static int __init hpfb_init_one(unsigned long phys_base, unsigned long virt_base
 
 	if (register_framebuffer(&fb_info) < 0) {
 		fb_dealloc_cmap(&fb_info.cmap);
+		iounmap(fb_info.screen_base);
+		fb_info.screen_base = NULL;
 		return 1;
 	}
 
diff --git a/drivers/video/i810/i810-i2c.c b/drivers/video/i810/i810-i2c.c
index b38d805db313..b952e4504abe 100644
--- a/drivers/video/i810/i810-i2c.c
+++ b/drivers/video/i810/i810-i2c.c
@@ -162,9 +162,7 @@ int i810_probe_i2c_connector(struct fb_info *info, u8 **out_edid, int conn)
 
 		if (e != NULL) {
 			DPRINTK("i810-i2c: Getting EDID from BIOS\n");
-			edid = kmalloc(EDID_LENGTH, GFP_KERNEL);
-			if (edid)
-				memcpy(edid, e, EDID_LENGTH);
+			edid = kmemdup(e, EDID_LENGTH, GFP_KERNEL);
 		}
 	}
 
diff --git a/drivers/video/igafb.c b/drivers/video/igafb.c
index e6df492c22a5..655ae0fa99ca 100644
--- a/drivers/video/igafb.c
+++ b/drivers/video/igafb.c
@@ -384,19 +384,21 @@ int __init igafb_init(void)
         if (!con_is_present())
                 return -ENXIO;
 
-        pdev = pci_find_device(PCI_VENDOR_ID_INTERG, 
+        pdev = pci_get_device(PCI_VENDOR_ID_INTERG,
                                PCI_DEVICE_ID_INTERG_1682, 0);
 	if (pdev == NULL) {
 		/*
 		 * XXX We tried to use cyber2000fb.c for IGS 2000.
 		 * But it does not initialize the chip in JavaStation-E, alas.
 		 */
-        	pdev = pci_find_device(PCI_VENDOR_ID_INTERG, 0x2000, 0);
+        	pdev = pci_get_device(PCI_VENDOR_ID_INTERG, 0x2000, 0);
         	if(pdev == NULL) {
         	        return -ENXIO;
 		}
 		iga2000 = 1;
 	}
+	/* We leak a reference here but as it cannot be unloaded this is
+	   fine. If you write unload code remember to free it in unload */
 	
 	size = sizeof(struct fb_info) + sizeof(struct iga_par) + sizeof(u32)*16;
 
diff --git a/drivers/video/intelfb/intelfbdrv.c b/drivers/video/intelfb/intelfbdrv.c
index 6f9de04193d2..664fc5cf962a 100644
--- a/drivers/video/intelfb/intelfbdrv.c
+++ b/drivers/video/intelfb/intelfbdrv.c
@@ -1058,10 +1058,9 @@ intelfb_init_var(struct intelfb_info *dinfo)
 		u8 *edid_d = NULL;
 
 		if (edid_s) {
-			edid_d = kmalloc(EDID_LENGTH, GFP_KERNEL);
+			edid_d = kmemdup(edid_s, EDID_LENGTH, GFP_KERNEL);
 
 			if (edid_d) {
-				memcpy(edid_d, edid_s, EDID_LENGTH);
 				fb_edid_to_monspecs(edid_d,
 						    &dinfo->info->monspecs);
 				kfree(edid_d);
diff --git a/drivers/video/macfb.c b/drivers/video/macfb.c
index 80a043807161..180d94c2b4d2 100644
--- a/drivers/video/macfb.c
+++ b/drivers/video/macfb.c
@@ -608,6 +608,22 @@ void __init macfb_setup(char *options)
 	}
 }
 
+static void __init iounmap_macfb(void)
+{
+	if (valkyrie_cmap_regs)
+		iounmap(valkyrie_cmap_regs);
+	if (dafb_cmap_regs)
+		iounmap(dafb_cmap_regs);
+	if (v8_brazil_cmap_regs)
+		iounmap(v8_brazil_cmap_regs);
+	if (rbv_cmap_regs)
+		iounmap(rbv_cmap_regs);
+	if (civic_cmap_regs)
+		iounmap(civic_cmap_regs);
+	if (csc_cmap_regs)
+		iounmap(csc_cmap_regs);
+}
+
 static int __init macfb_init(void)
 {
 	int video_cmap_len, video_is_nubus = 0;
@@ -962,6 +978,10 @@ static int __init macfb_init(void)
 	if (!err)
 		printk("fb%d: %s frame buffer device\n",
 		       fb_info.node, fb_info.fix.id);
+	else {
+		iounmap(fb_info.screen_base);
+		iounmap_macfb();
+	}
 	return err;
 }
 
diff --git a/drivers/video/mbx/mbxdebugfs.c b/drivers/video/mbx/mbxdebugfs.c
index 84aab3ad024e..472a3ca3d92d 100644
--- a/drivers/video/mbx/mbxdebugfs.c
+++ b/drivers/video/mbx/mbxdebugfs.c
@@ -10,6 +10,8 @@ struct mbxfb_debugfs_data {
 	struct dentry *clock;
 	struct dentry *display;
 	struct dentry *gsctl;
+	struct dentry *sdram;
+	struct dentry *misc;
 };
 
 static int open_file_generic(struct inode *inode, struct file *file)
@@ -29,11 +31,11 @@ static ssize_t sysconf_read_file(struct file *file, char __user *userbuf,
 {
 	char * s = big_buffer;
 
-	s += sprintf(s, "SYSCFG = %08lx\n", SYSCFG);
-	s += sprintf(s, "PFBASE = %08lx\n", PFBASE);
-	s += sprintf(s, "PFCEIL = %08lx\n", PFCEIL);
-	s += sprintf(s, "POLLFLAG = %08lx\n", POLLFLAG);
-	s += sprintf(s, "SYSRST = %08lx\n", SYSRST);
+	s += sprintf(s, "SYSCFG = %08x\n", readl(SYSCFG));
+	s += sprintf(s, "PFBASE = %08x\n", readl(PFBASE));
+	s += sprintf(s, "PFCEIL = %08x\n", readl(PFCEIL));
+	s += sprintf(s, "POLLFLAG = %08x\n", readl(POLLFLAG));
+	s += sprintf(s, "SYSRST = %08x\n", readl(SYSRST));
 
 	return  simple_read_from_buffer(userbuf, count, ppos,
 					big_buffer, s-big_buffer);
@@ -45,24 +47,24 @@ static ssize_t gsctl_read_file(struct file *file, char __user *userbuf,
 {
 	char * s = big_buffer;
 
-	s += sprintf(s, "GSCTRL = %08lx\n", GSCTRL);
-	s += sprintf(s, "VSCTRL = %08lx\n", VSCTRL);
-	s += sprintf(s, "GBBASE = %08lx\n", GBBASE);
-	s += sprintf(s, "VBBASE = %08lx\n", VBBASE);
-	s += sprintf(s, "GDRCTRL = %08lx\n", GDRCTRL);
-	s += sprintf(s, "VCMSK = %08lx\n", VCMSK);
-	s += sprintf(s, "GSCADR = %08lx\n", GSCADR);
-	s += sprintf(s, "VSCADR = %08lx\n", VSCADR);
-	s += sprintf(s, "VUBASE = %08lx\n", VUBASE);
-	s += sprintf(s, "VVBASE = %08lx\n", VVBASE);
-	s += sprintf(s, "GSADR = %08lx\n", GSADR);
-	s += sprintf(s, "VSADR = %08lx\n", VSADR);
-	s += sprintf(s, "HCCTRL = %08lx\n", HCCTRL);
-	s += sprintf(s, "HCSIZE = %08lx\n", HCSIZE);
-	s += sprintf(s, "HCPOS = %08lx\n", HCPOS);
-	s += sprintf(s, "HCBADR = %08lx\n", HCBADR);
-	s += sprintf(s, "HCCKMSK = %08lx\n", HCCKMSK);
-	s += sprintf(s, "GPLUT = %08lx\n", GPLUT);
+	s += sprintf(s, "GSCTRL = %08x\n", readl(GSCTRL));
+	s += sprintf(s, "VSCTRL = %08x\n", readl(VSCTRL));
+	s += sprintf(s, "GBBASE = %08x\n", readl(GBBASE));
+	s += sprintf(s, "VBBASE = %08x\n", readl(VBBASE));
+	s += sprintf(s, "GDRCTRL = %08x\n", readl(GDRCTRL));
+	s += sprintf(s, "VCMSK = %08x\n", readl(VCMSK));
+	s += sprintf(s, "GSCADR = %08x\n", readl(GSCADR));
+	s += sprintf(s, "VSCADR = %08x\n", readl(VSCADR));
+	s += sprintf(s, "VUBASE = %08x\n", readl(VUBASE));
+	s += sprintf(s, "VVBASE = %08x\n", readl(VVBASE));
+	s += sprintf(s, "GSADR = %08x\n", readl(GSADR));
+	s += sprintf(s, "VSADR = %08x\n", readl(VSADR));
+	s += sprintf(s, "HCCTRL = %08x\n", readl(HCCTRL));
+	s += sprintf(s, "HCSIZE = %08x\n", readl(HCSIZE));
+	s += sprintf(s, "HCPOS = %08x\n", readl(HCPOS));
+	s += sprintf(s, "HCBADR = %08x\n", readl(HCBADR));
+	s += sprintf(s, "HCCKMSK = %08x\n", readl(HCCKMSK));
+	s += sprintf(s, "GPLUT = %08x\n", readl(GPLUT));
 
 	return  simple_read_from_buffer(userbuf, count, ppos,
 					big_buffer, s-big_buffer);
@@ -73,36 +75,36 @@ static ssize_t display_read_file(struct file *file, char __user *userbuf,
 {
 	char * s = big_buffer;
 
-	s += sprintf(s, "DSCTRL = %08lx\n", DSCTRL);
-	s += sprintf(s, "DHT01 = %08lx\n", DHT01);
-	s += sprintf(s, "DHT02 = %08lx\n", DHT02);
-	s += sprintf(s, "DHT03 = %08lx\n", DHT03);
-	s += sprintf(s, "DVT01 = %08lx\n", DVT01);
-	s += sprintf(s, "DVT02 = %08lx\n", DVT02);
-	s += sprintf(s, "DVT03 = %08lx\n", DVT03);
-	s += sprintf(s, "DBCOL = %08lx\n", DBCOL);
-	s += sprintf(s, "BGCOLOR = %08lx\n", BGCOLOR);
-	s += sprintf(s, "DINTRS = %08lx\n", DINTRS);
-	s += sprintf(s, "DINTRE = %08lx\n", DINTRE);
-	s += sprintf(s, "DINTRCNT = %08lx\n", DINTRCNT);
-	s += sprintf(s, "DSIG = %08lx\n", DSIG);
-	s += sprintf(s, "DMCTRL = %08lx\n", DMCTRL);
-	s += sprintf(s, "CLIPCTRL = %08lx\n", CLIPCTRL);
-	s += sprintf(s, "SPOCTRL = %08lx\n", SPOCTRL);
-	s += sprintf(s, "SVCTRL = %08lx\n", SVCTRL);
-	s += sprintf(s, "DLSTS = %08lx\n", DLSTS);
-	s += sprintf(s, "DLLCTRL = %08lx\n", DLLCTRL);
-	s += sprintf(s, "DVLNUM = %08lx\n", DVLNUM);
-	s += sprintf(s, "DUCTRL = %08lx\n", DUCTRL);
-	s += sprintf(s, "DVECTRL = %08lx\n", DVECTRL);
-	s += sprintf(s, "DHDET = %08lx\n", DHDET);
-	s += sprintf(s, "DVDET = %08lx\n", DVDET);
-	s += sprintf(s, "DODMSK = %08lx\n", DODMSK);
-	s += sprintf(s, "CSC01 = %08lx\n", CSC01);
-	s += sprintf(s, "CSC02 = %08lx\n", CSC02);
-	s += sprintf(s, "CSC03 = %08lx\n", CSC03);
-	s += sprintf(s, "CSC04 = %08lx\n", CSC04);
-	s += sprintf(s, "CSC05 = %08lx\n", CSC05);
+	s += sprintf(s, "DSCTRL = %08x\n", readl(DSCTRL));
+	s += sprintf(s, "DHT01 = %08x\n", readl(DHT01));
+	s += sprintf(s, "DHT02 = %08x\n", readl(DHT02));
+	s += sprintf(s, "DHT03 = %08x\n", readl(DHT03));
+	s += sprintf(s, "DVT01 = %08x\n", readl(DVT01));
+	s += sprintf(s, "DVT02 = %08x\n", readl(DVT02));
+	s += sprintf(s, "DVT03 = %08x\n", readl(DVT03));
+	s += sprintf(s, "DBCOL = %08x\n", readl(DBCOL));
+	s += sprintf(s, "BGCOLOR = %08x\n", readl(BGCOLOR));
+	s += sprintf(s, "DINTRS = %08x\n", readl(DINTRS));
+	s += sprintf(s, "DINTRE = %08x\n", readl(DINTRE));
+	s += sprintf(s, "DINTRCNT = %08x\n", readl(DINTRCNT));
+	s += sprintf(s, "DSIG = %08x\n", readl(DSIG));
+	s += sprintf(s, "DMCTRL = %08x\n", readl(DMCTRL));
+	s += sprintf(s, "CLIPCTRL = %08x\n", readl(CLIPCTRL));
+	s += sprintf(s, "SPOCTRL = %08x\n", readl(SPOCTRL));
+	s += sprintf(s, "SVCTRL = %08x\n", readl(SVCTRL));
+	s += sprintf(s, "DLSTS = %08x\n", readl(DLSTS));
+	s += sprintf(s, "DLLCTRL = %08x\n", readl(DLLCTRL));
+	s += sprintf(s, "DVLNUM = %08x\n", readl(DVLNUM));
+	s += sprintf(s, "DUCTRL = %08x\n", readl(DUCTRL));
+	s += sprintf(s, "DVECTRL = %08x\n", readl(DVECTRL));
+	s += sprintf(s, "DHDET = %08x\n", readl(DHDET));
+	s += sprintf(s, "DVDET = %08x\n", readl(DVDET));
+	s += sprintf(s, "DODMSK = %08x\n", readl(DODMSK));
+	s += sprintf(s, "CSC01 = %08x\n", readl(CSC01));
+	s += sprintf(s, "CSC02 = %08x\n", readl(CSC02));
+	s += sprintf(s, "CSC03 = %08x\n", readl(CSC03));
+	s += sprintf(s, "CSC04 = %08x\n", readl(CSC04));
+	s += sprintf(s, "CSC05 = %08x\n", readl(CSC05));
 
 	return  simple_read_from_buffer(userbuf, count, ppos,
 					big_buffer, s-big_buffer);
@@ -113,24 +115,61 @@ static ssize_t clock_read_file(struct file *file, char __user *userbuf,
 {
 	char * s = big_buffer;
 
-	s += sprintf(s, "SYSCLKSRC = %08lx\n", SYSCLKSRC);
-	s += sprintf(s, "PIXCLKSRC = %08lx\n", PIXCLKSRC);
-	s += sprintf(s, "CLKSLEEP = %08lx\n", CLKSLEEP);
-	s += sprintf(s, "COREPLL = %08lx\n", COREPLL);
-	s += sprintf(s, "DISPPLL = %08lx\n", DISPPLL);
-	s += sprintf(s, "PLLSTAT = %08lx\n", PLLSTAT);
-	s += sprintf(s, "VOVRCLK = %08lx\n", VOVRCLK);
-	s += sprintf(s, "PIXCLK = %08lx\n", PIXCLK);
-	s += sprintf(s, "MEMCLK = %08lx\n", MEMCLK);
-	s += sprintf(s, "M24CLK = %08lx\n", M24CLK);
-	s += sprintf(s, "MBXCLK = %08lx\n", MBXCLK);
-	s += sprintf(s, "SDCLK = %08lx\n", SDCLK);
-	s += sprintf(s, "PIXCLKDIV = %08lx\n", PIXCLKDIV);
+	s += sprintf(s, "SYSCLKSRC = %08x\n", readl(SYSCLKSRC));
+	s += sprintf(s, "PIXCLKSRC = %08x\n", readl(PIXCLKSRC));
+	s += sprintf(s, "CLKSLEEP = %08x\n", readl(CLKSLEEP));
+	s += sprintf(s, "COREPLL = %08x\n", readl(COREPLL));
+	s += sprintf(s, "DISPPLL = %08x\n", readl(DISPPLL));
+	s += sprintf(s, "PLLSTAT = %08x\n", readl(PLLSTAT));
+	s += sprintf(s, "VOVRCLK = %08x\n", readl(VOVRCLK));
+	s += sprintf(s, "PIXCLK = %08x\n", readl(PIXCLK));
+	s += sprintf(s, "MEMCLK = %08x\n", readl(MEMCLK));
+	s += sprintf(s, "M24CLK = %08x\n", readl(M24CLK));
+	s += sprintf(s, "MBXCLK = %08x\n", readl(MBXCLK));
+	s += sprintf(s, "SDCLK = %08x\n", readl(SDCLK));
+	s += sprintf(s, "PIXCLKDIV = %08x\n", readl(PIXCLKDIV));
 
 	return  simple_read_from_buffer(userbuf, count, ppos,
 					big_buffer, s-big_buffer);
 }
 
+static ssize_t sdram_read_file(struct file *file, char __user *userbuf,
+			       size_t count, loff_t *ppos)
+{
+	char * s = big_buffer;
+
+	s += sprintf(s, "LMRST = %08x\n", readl(LMRST));
+	s += sprintf(s, "LMCFG = %08x\n", readl(LMCFG));
+	s += sprintf(s, "LMPWR = %08x\n", readl(LMPWR));
+	s += sprintf(s, "LMPWRSTAT = %08x\n", readl(LMPWRSTAT));
+	s += sprintf(s, "LMCEMR = %08x\n", readl(LMCEMR));
+	s += sprintf(s, "LMTYPE = %08x\n", readl(LMTYPE));
+	s += sprintf(s, "LMTIM = %08x\n", readl(LMTIM));
+	s += sprintf(s, "LMREFRESH = %08x\n", readl(LMREFRESH));
+	s += sprintf(s, "LMPROTMIN = %08x\n", readl(LMPROTMIN));
+	s += sprintf(s, "LMPROTMAX = %08x\n", readl(LMPROTMAX));
+	s += sprintf(s, "LMPROTCFG = %08x\n", readl(LMPROTCFG));
+	s += sprintf(s, "LMPROTERR = %08x\n", readl(LMPROTERR));
+
+	return  simple_read_from_buffer(userbuf, count, ppos,
+					big_buffer, s-big_buffer);
+}
+
+static ssize_t misc_read_file(struct file *file, char __user *userbuf,
+			       size_t count, loff_t *ppos)
+{
+	char * s = big_buffer;
+
+	s += sprintf(s, "LCD_CONFIG = %08x\n", readl(LCD_CONFIG));
+	s += sprintf(s, "ODFBPWR = %08x\n", readl(ODFBPWR));
+	s += sprintf(s, "ODFBSTAT = %08x\n", readl(ODFBSTAT));
+	s += sprintf(s, "ID = %08x\n", readl(ID));
+
+	return  simple_read_from_buffer(userbuf, count, ppos,
+					big_buffer, s-big_buffer);
+}
+
+
 static struct file_operations sysconf_fops = {
 	.read = sysconf_read_file,
 	.write = write_file_dummy,
@@ -155,6 +194,17 @@ static struct file_operations gsctl_fops = {
 	.open = open_file_generic,
 };
 
+static struct file_operations sdram_fops = {
+	.read = sdram_read_file,
+	.write = write_file_dummy,
+	.open = open_file_generic,
+};
+
+static struct file_operations misc_fops = {
+	.read = misc_read_file,
+	.write = write_file_dummy,
+	.open = open_file_generic,
+};
 
 static void __devinit mbxfb_debugfs_init(struct fb_info *fbi)
 {
@@ -173,6 +223,10 @@ static void __devinit mbxfb_debugfs_init(struct fb_info *fbi)
 				      fbi, &display_fops);
 	dbg->gsctl = debugfs_create_file("gsctl", 0444, dbg->dir,
 				    fbi, &gsctl_fops);
+	dbg->sdram = debugfs_create_file("sdram", 0444, dbg->dir,
+					fbi, &sdram_fops);
+	dbg->misc = debugfs_create_file("misc", 0444, dbg->dir,
+					fbi, &misc_fops);
 }
 
 static void __devexit mbxfb_debugfs_remove(struct fb_info *fbi)
@@ -180,6 +234,8 @@ static void __devexit mbxfb_debugfs_remove(struct fb_info *fbi)
 	struct mbxfb_info *mfbi = fbi->par;
 	struct mbxfb_debugfs_data *dbg = mfbi->debugfs_data;
 
+	debugfs_remove(dbg->misc);
+	debugfs_remove(dbg->sdram);
 	debugfs_remove(dbg->gsctl);
 	debugfs_remove(dbg->display);
 	debugfs_remove(dbg->clock);
diff --git a/drivers/video/mbx/mbxfb.c b/drivers/video/mbx/mbxfb.c
index a32d1af79e07..980d5f623902 100644
--- a/drivers/video/mbx/mbxfb.c
+++ b/drivers/video/mbx/mbxfb.c
@@ -1,8 +1,14 @@
 /*
  *  linux/drivers/video/mbx/mbxfb.c
  *
+ *  Copyright (C) 2006 8D Technologies inc
+ *  Raphael Assenat <raph@8d.com>
+ *  	- Added video overlay support
+ *  	- Various improvements
+ *
  *  Copyright (C) 2006 Compulab, Ltd.
  *  Mike Rapoport <mike@compulab.co.il>
+ *  	- Creation of driver
  *
  *   Based on pxafb.c
  *
@@ -19,6 +25,7 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
+#include <linux/uaccess.h>
 
 #include <asm/io.h>
 
@@ -29,6 +36,14 @@
 
 static unsigned long virt_base_2700;
 
+#define write_reg(val, reg) do { writel((val), (reg)); } while(0)
+
+/* Without this delay, the graphics appears somehow scaled and
+ * there is a lot of jitter in scanlines. This delay is probably
+ * needed only after setting some specific register(s) somewhere,
+ * not all over the place... */
+#define write_reg_dly(val, reg) do { writel((val), reg); udelay(1000); } while(0)
+
 #define MIN_XRES	16
 #define MIN_YRES	16
 #define MAX_XRES	2048
@@ -257,19 +272,17 @@ static int mbxfb_set_par(struct fb_info *info)
 	gsctrl &= ~(FMsk(GSCTRL_GSWIDTH) | FMsk(GSCTRL_GSHEIGHT));
 	gsctrl |= Gsctrl_Width(info->var.xres) |
 		Gsctrl_Height(info->var.yres);
-	writel(gsctrl, GSCTRL);
-	udelay(1000);
+	write_reg_dly(gsctrl, GSCTRL);
 
 	gsadr &= ~(FMsk(GSADR_SRCSTRIDE));
 	gsadr |= Gsadr_Srcstride(info->var.xres * info->var.bits_per_pixel /
 				 (8 * 16) - 1);
-	writel(gsadr, GSADR);
-	udelay(1000);
+	write_reg_dly(gsadr, GSADR);
 
 	/* setup timings */
 	var->pixclock = mbxfb_get_pixclock(info->var.pixclock, &div);
 
-	writel((Disp_Pll_M(div.m) | Disp_Pll_N(div.n) |
+	write_reg_dly((Disp_Pll_M(div.m) | Disp_Pll_N(div.n) |
 		Disp_Pll_P(div.p) | DISP_PLL_EN), DISPPLL);
 
 	hbps = var->hsync_len;
@@ -282,18 +295,20 @@ static int mbxfb_set_par(struct fb_info *info)
 	vfps = vas + var->yres;
 	vt = vfps + var->lower_margin;
 
-	writel((Dht01_Hbps(hbps) | Dht01_Ht(ht)), DHT01);
-	writel((Dht02_Hlbs(has) | Dht02_Has(has)), DHT02);
-	writel((Dht03_Hfps(hfps) | Dht03_Hrbs(hfps)), DHT03);
-	writel((Dhdet_Hdes(has) | Dhdet_Hdef(hfps)), DHDET);
+	write_reg_dly((Dht01_Hbps(hbps) | Dht01_Ht(ht)), DHT01);
+	write_reg_dly((Dht02_Hlbs(has) | Dht02_Has(has)), DHT02);
+	write_reg_dly((Dht03_Hfps(hfps) | Dht03_Hrbs(hfps)), DHT03);
+	write_reg_dly((Dhdet_Hdes(has) | Dhdet_Hdef(hfps)), DHDET);
 
-	writel((Dvt01_Vbps(vbps) | Dvt01_Vt(vt)), DVT01);
-	writel((Dvt02_Vtbs(vas) | Dvt02_Vas(vas)), DVT02);
-	writel((Dvt03_Vfps(vfps) | Dvt03_Vbbs(vfps)), DVT03);
-	writel((Dvdet_Vdes(vas) | Dvdet_Vdef(vfps)), DVDET);
-	writel((Dvectrl_Vevent(vfps) | Dvectrl_Vfetch(vbps)), DVECTRL);
+	write_reg_dly((Dvt01_Vbps(vbps) | Dvt01_Vt(vt)), DVT01);
+	write_reg_dly((Dvt02_Vtbs(vas) | Dvt02_Vas(vas)), DVT02);
+	write_reg_dly((Dvt03_Vfps(vfps) | Dvt03_Vbbs(vfps)), DVT03);
+	write_reg_dly((Dvdet_Vdes(vas) | Dvdet_Vdef(vfps)), DVDET);
+	write_reg_dly((Dvectrl_Vevent(vfps) | Dvectrl_Vfetch(vbps)), DVECTRL);
 
-	writel((readl(DSCTRL) | DSCTRL_SYNCGEN_EN), DSCTRL);
+	write_reg_dly((readl(DSCTRL) | DSCTRL_SYNCGEN_EN), DSCTRL);
+
+	write_reg_dly(DINTRE_VEVENT0_EN, DINTRE);
 
 	return 0;
 }
@@ -305,23 +320,203 @@ static int mbxfb_blank(int blank, struct fb_info *info)
 	case FB_BLANK_VSYNC_SUSPEND:
 	case FB_BLANK_HSYNC_SUSPEND:
 	case FB_BLANK_NORMAL:
-		writel((readl(DSCTRL) & ~DSCTRL_SYNCGEN_EN), DSCTRL);
-		udelay(1000);
-		writel((readl(PIXCLK) & ~PIXCLK_EN), PIXCLK);
-		udelay(1000);
-		writel((readl(VOVRCLK) & ~VOVRCLK_EN), VOVRCLK);
-		udelay(1000);
+		write_reg_dly((readl(DSCTRL) & ~DSCTRL_SYNCGEN_EN), DSCTRL);
+		write_reg_dly((readl(PIXCLK) & ~PIXCLK_EN), PIXCLK);
+		write_reg_dly((readl(VOVRCLK) & ~VOVRCLK_EN), VOVRCLK);
 		break;
 	case FB_BLANK_UNBLANK:
-		writel((readl(DSCTRL) | DSCTRL_SYNCGEN_EN), DSCTRL);
-		udelay(1000);
-		writel((readl(PIXCLK) | PIXCLK_EN), PIXCLK);
-		udelay(1000);
+		write_reg_dly((readl(DSCTRL) | DSCTRL_SYNCGEN_EN), DSCTRL);
+		write_reg_dly((readl(PIXCLK) | PIXCLK_EN), PIXCLK);
 		break;
 	}
 	return 0;
 }
 
+static int mbxfb_setupOverlay(struct mbxfb_overlaySetup *set)
+{
+	u32 vsctrl, vbbase, vscadr, vsadr;
+	u32 sssize, spoctrl, svctrl, shctrl;
+	u32 vubase, vvbase;
+	u32 vovrclk;
+
+	if (set->scaled_width==0 || set->scaled_height==0)
+		return -EINVAL;
+
+	/* read registers which have reserved bits
+	 * so we can write them back as-is. */
+	vovrclk = readl(VOVRCLK);
+	vsctrl = readl(VSCTRL);
+	vscadr = readl(VSCADR);
+	vubase = readl(VUBASE);
+	vvbase = readl(VVBASE);
+
+	spoctrl = readl(SPOCTRL);
+	sssize = readl(SSSIZE);
+
+
+	vbbase = Vbbase_Glalpha(set->alpha);
+
+	vsctrl &= ~(	FMsk(VSCTRL_VSWIDTH) |
+					FMsk(VSCTRL_VSHEIGHT) |
+					FMsk(VSCTRL_VPIXFMT) |
+					VSCTRL_GAMMA_EN | VSCTRL_CSC_EN |
+					VSCTRL_COSITED );
+	vsctrl |= Vsctrl_Width(set->width) | Vsctrl_Height(set->height) |
+				VSCTRL_CSC_EN;
+
+	vscadr &= ~(VSCADR_STR_EN | VSCADR_COLKEY_EN | VSCADR_COLKEYSRC |
+				FMsk(VSCADR_BLEND_M) | FMsk(VSCADR_BLEND_POS) |
+				FMsk(VSCADR_VBASE_ADR) );
+	vubase &= ~(VUBASE_UVHALFSTR | FMsk(VUBASE_UBASE_ADR));
+	vvbase &= ~(FMsk(VVBASE_VBASE_ADR));
+
+	switch (set->fmt)
+	{
+		case MBXFB_FMT_YUV12:
+			vsctrl |= VSCTRL_VPIXFMT_YUV12;
+
+			set->Y_stride = ((set->width) + 0xf ) & ~0xf;
+
+			break;
+		case MBXFB_FMT_UY0VY1:
+			vsctrl |= VSCTRL_VPIXFMT_UY0VY1;
+			set->Y_stride = (set->width*2 + 0xf ) & ~0xf;
+			break;
+		case MBXFB_FMT_VY0UY1:
+			vsctrl |= VSCTRL_VPIXFMT_VY0UY1;
+			set->Y_stride = (set->width*2 + 0xf ) & ~0xf;
+			break;
+		case MBXFB_FMT_Y0UY1V:
+			vsctrl |= VSCTRL_VPIXFMT_Y0UY1V;
+			set->Y_stride = (set->width*2 + 0xf ) & ~0xf;
+			break;
+		case MBXFB_FMT_Y0VY1U:
+			vsctrl |= VSCTRL_VPIXFMT_Y0VY1U;
+			set->Y_stride = (set->width*2 + 0xf ) & ~0xf;
+			break;
+		default:
+			return -EINVAL;
+	}
+
+	/* VSCTRL has the bits which sets the Video Pixel Format.
+	 * When passing from a packed to planar format,
+	 * if we write VSCTRL first, VVBASE and VUBASE would
+	 * be zero if we would not set them here. (And then,
+	 * the chips hangs and only a reset seems to fix it).
+	 *
+	 * If course, the values calculated here have no meaning
+	 * for packed formats.
+	 */
+	set->UV_stride = ((set->width/2) + 0x7 ) & ~0x7;
+		set->U_offset = set->height * set->Y_stride;
+		set->V_offset = set->U_offset +
+						set->height * set->UV_stride;
+	vubase |= Vubase_Ubase_Adr(
+			(0x60000 + set->mem_offset + set->U_offset)>>3);
+	vvbase |= Vvbase_Vbase_Adr(
+			(0x60000 + set->mem_offset + set->V_offset)>>3);
+
+
+	vscadr |= VSCADR_BLEND_VID | VSCADR_BLEND_GLOB |
+		Vscadr_Vbase_Adr((0x60000 + set->mem_offset)>>4);
+
+	if (set->enable)
+		vscadr |= VSCADR_STR_EN;
+
+
+	vsadr = Vsadr_Srcstride((set->Y_stride)/16-1) |
+		Vsadr_Xstart(set->x) | Vsadr_Ystart(set->y);
+
+	sssize &= ~(FMsk(SSSIZE_SC_WIDTH) | FMsk(SSSIZE_SC_HEIGHT));
+	sssize = Sssize_Sc_Width(set->scaled_width-1) |
+			Sssize_Sc_Height(set->scaled_height-1);
+
+	spoctrl &= ~(SPOCTRL_H_SC_BP | SPOCTRL_V_SC_BP |
+			SPOCTRL_HV_SC_OR | SPOCTRL_VS_UR_C |
+			FMsk(SPOCTRL_VORDER) | FMsk(SPOCTRL_VPITCH));
+	spoctrl = Spoctrl_Vpitch((set->height<<11)/set->scaled_height)
+							| SPOCTRL_VORDER_2TAP;
+
+	/* Bypass horiz/vert scaler when same size */
+	if (set->scaled_width == set->width)
+		spoctrl |= SPOCTRL_H_SC_BP;
+	if (set->scaled_height == set->height)
+		spoctrl |= SPOCTRL_V_SC_BP;
+
+	svctrl = Svctrl_Initial1(1<<10) | Svctrl_Initial2(1<<10);
+
+	shctrl = Shctrl_Hinitial(4<<11)
+			| Shctrl_Hpitch((set->width<<11)/set->scaled_width);
+
+	/* Video plane registers */
+	write_reg(vsctrl, VSCTRL);
+	write_reg(vbbase, VBBASE);
+	write_reg(vscadr, VSCADR);
+	write_reg(vubase, VUBASE);
+	write_reg(vvbase, VVBASE);
+	write_reg(vsadr, VSADR);
+
+	/* Video scaler registers */
+	write_reg(sssize, SSSIZE);
+	write_reg(spoctrl, SPOCTRL);
+	write_reg(svctrl, SVCTRL);
+	write_reg(shctrl, SHCTRL);
+
+	/* RAPH: Using those coefficients, the scaled
+	 * image is quite blurry. I dont know how
+	 * to improve them ; The chip documentation
+	 * was not helpful.. */
+	write_reg(0x21212121, VSCOEFF0);
+	write_reg(0x21212121, VSCOEFF1);
+	write_reg(0x21212121, VSCOEFF2);
+	write_reg(0x21212121, VSCOEFF3);
+	write_reg(0x21212121, VSCOEFF4);
+	write_reg(0x00000000, HSCOEFF0);
+	write_reg(0x00000000, HSCOEFF1);
+	write_reg(0x00000000, HSCOEFF2);
+	write_reg(0x03020201, HSCOEFF3);
+	write_reg(0x09070604, HSCOEFF4);
+	write_reg(0x0f0e0c0a, HSCOEFF5);
+	write_reg(0x15141211, HSCOEFF6);
+	write_reg(0x19181716, HSCOEFF7);
+	write_reg(0x00000019, HSCOEFF8);
+
+	/* Clock */
+	if (set->enable)
+		vovrclk |= 1;
+	else
+		vovrclk &= ~1;
+
+	write_reg(vovrclk, VOVRCLK);
+
+	return 0;
+}
+
+static int mbxfb_ioctl(struct fb_info *info, unsigned int cmd,
+				unsigned long arg)
+{
+	struct mbxfb_overlaySetup setup;
+	int res;
+
+	if (cmd == MBXFB_IOCX_OVERLAY)
+	{
+		if (copy_from_user(&setup, (void __user*)arg,
+					sizeof(struct mbxfb_overlaySetup)))
+			return -EFAULT;
+
+		res = mbxfb_setupOverlay(&setup);
+		if (res)
+			return res;
+
+		if (copy_to_user((void __user*)arg, &setup,
+					sizeof(struct mbxfb_overlaySetup)))
+			return -EFAULT;
+
+		return 0;
+	}
+	return -EINVAL;
+}
+
 static struct fb_ops mbxfb_ops = {
 	.owner = THIS_MODULE,
 	.fb_check_var = mbxfb_check_var,
@@ -331,6 +526,7 @@ static struct fb_ops mbxfb_ops = {
 	.fb_copyarea = cfb_copyarea,
 	.fb_imageblit = cfb_imageblit,
 	.fb_blank = mbxfb_blank,
+	.fb_ioctl = mbxfb_ioctl,
 };
 
 /*
@@ -339,36 +535,29 @@ static struct fb_ops mbxfb_ops = {
 */
 static void __devinit setup_memc(struct fb_info *fbi)
 {
-	struct mbxfb_info *mfbi = fbi->par;
 	unsigned long tmp;
 	int i;
 
 	/* FIXME: use platfrom specific parameters */
 	/* setup SDRAM controller */
-	writel((LMCFG_LMC_DS | LMCFG_LMC_TS | LMCFG_LMD_TS |
+	write_reg_dly((LMCFG_LMC_DS | LMCFG_LMC_TS | LMCFG_LMD_TS |
 		LMCFG_LMA_TS),
 	       LMCFG);
-	udelay(1000);
 
-	writel(LMPWR_MC_PWR_ACT, LMPWR);
-	udelay(1000);
+	write_reg_dly(LMPWR_MC_PWR_ACT, LMPWR);
 
 	/* setup SDRAM timings */
-	writel((Lmtim_Tras(7) | Lmtim_Trp(3) | Lmtim_Trcd(3) |
+	write_reg_dly((Lmtim_Tras(7) | Lmtim_Trp(3) | Lmtim_Trcd(3) |
 		Lmtim_Trc(9) | Lmtim_Tdpl(2)),
 	       LMTIM);
-	udelay(1000);
 	/* setup SDRAM refresh rate */
-	writel(0xc2b, LMREFRESH);
-	udelay(1000);
+	write_reg_dly(0xc2b, LMREFRESH);
 	/* setup SDRAM type parameters */
-	writel((LMTYPE_CASLAT_3 | LMTYPE_BKSZ_2 | LMTYPE_ROWSZ_11 |
+	write_reg_dly((LMTYPE_CASLAT_3 | LMTYPE_BKSZ_2 | LMTYPE_ROWSZ_11 |
 		LMTYPE_COLSZ_8),
 	       LMTYPE);
-	udelay(1000);
 	/* enable memory controller */
-	writel(LMPWR_MC_PWR_ACT, LMPWR);
-	udelay(1000);
+	write_reg_dly(LMPWR_MC_PWR_ACT, LMPWR);
 
 	/* perform dummy reads */
 	for ( i = 0; i < 16; i++ ) {
@@ -379,34 +568,30 @@ static void __devinit setup_memc(struct fb_info *fbi)
 static void enable_clocks(struct fb_info *fbi)
 {
 	/* enable clocks */
-	writel(SYSCLKSRC_PLL_2, SYSCLKSRC);
-	udelay(1000);
-	writel(PIXCLKSRC_PLL_1, PIXCLKSRC);
-	udelay(1000);
-	writel(0x00000000, CLKSLEEP);
-	udelay(1000);
-	writel((Core_Pll_M(0x17) | Core_Pll_N(0x3) | Core_Pll_P(0x0) |
+	write_reg_dly(SYSCLKSRC_PLL_2, SYSCLKSRC);
+	write_reg_dly(PIXCLKSRC_PLL_1, PIXCLKSRC);
+	write_reg_dly(0x00000000, CLKSLEEP);
+
+	/* PLL output = (Frefclk * M) / (N * 2^P )
+	 *
+	 * M: 0x17, N: 0x3, P: 0x0 == 100 Mhz!
+	 * M: 0xb, N: 0x1, P: 0x1 == 71 Mhz
+	 * */
+	write_reg_dly((Core_Pll_M(0xb) | Core_Pll_N(0x1) | Core_Pll_P(0x1) |
 		CORE_PLL_EN),
 	       COREPLL);
-	udelay(1000);
-	writel((Disp_Pll_M(0x1b) | Disp_Pll_N(0x7) | Disp_Pll_P(0x1) |
+
+	write_reg_dly((Disp_Pll_M(0x1b) | Disp_Pll_N(0x7) | Disp_Pll_P(0x1) |
 		DISP_PLL_EN),
 	       DISPPLL);
 
-	writel(0x00000000, VOVRCLK);
-	udelay(1000);
-	writel(PIXCLK_EN, PIXCLK);
-	udelay(1000);
-	writel(MEMCLK_EN, MEMCLK);
-	udelay(1000);
-	writel(0x00000006, M24CLK);
-	udelay(1000);
-	writel(0x00000006, MBXCLK);
-	udelay(1000);
-	writel(SDCLK_EN, SDCLK);
-	udelay(1000);
-	writel(0x00000001, PIXCLKDIV);
-	udelay(1000);
+	write_reg_dly(0x00000000, VOVRCLK);
+	write_reg_dly(PIXCLK_EN, PIXCLK);
+	write_reg_dly(MEMCLK_EN, MEMCLK);
+	write_reg_dly(0x00000006, M24CLK);
+	write_reg_dly(0x00000006, MBXCLK);
+	write_reg_dly(SDCLK_EN, SDCLK);
+	write_reg_dly(0x00000001, PIXCLKDIV);
 }
 
 static void __devinit setup_graphics(struct fb_info *fbi)
@@ -430,16 +615,11 @@ static void __devinit setup_graphics(struct fb_info *fbi)
 		break;
 	}
 
-	writel(gsctrl, GSCTRL);
-	udelay(1000);
-	writel(0x00000000, GBBASE);
-	udelay(1000);
-	writel(0x00ffffff, GDRCTRL);
-	udelay(1000);
-	writel((GSCADR_STR_EN | Gscadr_Gbase_Adr(0x6000)), GSCADR);
-	udelay(1000);
-	writel(0x00000000, GPLUT);
-	udelay(1000);
+	write_reg_dly(gsctrl, GSCTRL);
+	write_reg_dly(0x00000000, GBBASE);
+	write_reg_dly(0x00ffffff, GDRCTRL);
+	write_reg_dly((GSCADR_STR_EN | Gscadr_Gbase_Adr(0x6000)), GSCADR);
+	write_reg_dly(0x00000000, GPLUT);
 }
 
 static void __devinit setup_display(struct fb_info *fbi)
@@ -451,17 +631,14 @@ static void __devinit setup_display(struct fb_info *fbi)
 		dsctrl |= DSCTRL_HS_POL;
 	if (fbi->var.sync & FB_SYNC_VERT_HIGH_ACT)
 		dsctrl |= DSCTRL_VS_POL;
-	writel(dsctrl, DSCTRL);
-	udelay(1000);
-	writel(0xd0303010, DMCTRL);
-	udelay(1000);
-	writel((readl(DSCTRL) | DSCTRL_SYNCGEN_EN), DSCTRL);
+	write_reg_dly(dsctrl, DSCTRL);
+	write_reg_dly(0xd0303010, DMCTRL);
+	write_reg_dly((readl(DSCTRL) | DSCTRL_SYNCGEN_EN), DSCTRL);
 }
 
 static void __devinit enable_controller(struct fb_info *fbi)
 {
-	writel(SYSRST_RST, SYSRST);
-	udelay(1000);
+	write_reg_dly(SYSRST_RST, SYSRST);
 
 
 	enable_clocks(fbi);
@@ -478,12 +655,12 @@ static void __devinit enable_controller(struct fb_info *fbi)
 static int mbxfb_suspend(struct platform_device *dev, pm_message_t state)
 {
 	/* make frame buffer memory enter self-refresh mode */
-	writel(LMPWR_MC_PWR_SRM, LMPWR);
+	write_reg_dly(LMPWR_MC_PWR_SRM, LMPWR);
 	while (LMPWRSTAT != LMPWRSTAT_MC_PWR_SRM)
 		; /* empty statement */
 
 	/* reset the device, since it's initial state is 'mostly sleeping' */
-	writel(SYSRST_RST, SYSRST);
+	write_reg_dly(SYSRST_RST, SYSRST);
 	return 0;
 }
 
@@ -495,7 +672,7 @@ static int mbxfb_resume(struct platform_device *dev)
 /* 	setup_graphics(fbi); */
 /* 	setup_display(fbi); */
 
-	writel((readl(DSCTRL) | DSCTRL_SYNCGEN_EN), DSCTRL);
+	write_reg_dly((readl(DSCTRL) | DSCTRL_SYNCGEN_EN), DSCTRL);
 	return 0;
 }
 #else
@@ -520,6 +697,12 @@ static int __devinit mbxfb_probe(struct platform_device *dev)
 
 	dev_dbg(dev, "mbxfb_probe\n");
 
+	pdata = dev->dev.platform_data;
+	if (!pdata) {
+		dev_err(&dev->dev, "platform data is required\n");
+		return -EINVAL;
+	}
+
 	fbi = framebuffer_alloc(sizeof(struct mbxfb_info), &dev->dev);
 	if (fbi == NULL) {
 		dev_err(&dev->dev, "framebuffer_alloc failed\n");
@@ -528,7 +711,8 @@ static int __devinit mbxfb_probe(struct platform_device *dev)
 
 	mfbi = fbi->par;
 	fbi->pseudo_palette = mfbi->pseudo_palette;
-	pdata = dev->dev.platform_data;
+
+
 	if (pdata->probe)
 		mfbi->platform_probe = pdata->probe;
 	if (pdata->remove)
@@ -578,16 +762,16 @@ static int __devinit mbxfb_probe(struct platform_device *dev)
 		goto err4;
 	}
 
-	/* FIXME: get from platform */
 	fbi->screen_base = (char __iomem *)(mfbi->fb_virt_addr + 0x60000);
-	fbi->screen_size = 8 * 1024 * 1024;	/* 8 Megs */
+	fbi->screen_size = pdata->memsize;
 	fbi->fbops = &mbxfb_ops;
 
 	fbi->var = mbxfb_default;
 	fbi->fix = mbxfb_fix;
 	fbi->fix.smem_start = mfbi->fb_phys_addr + 0x60000;
-	fbi->fix.smem_len = 8 * 1024 * 1024;
-	fbi->fix.line_length = 640 * 2;
+	fbi->fix.smem_len = pdata->memsize;
+	fbi->fix.line_length = mbxfb_default.xres_virtual *
+					mbxfb_default.bits_per_pixel / 8;
 
 	ret = fb_alloc_cmap(&fbi->cmap, 256, 0);
 	if (ret < 0) {
@@ -636,8 +820,7 @@ static int __devexit mbxfb_remove(struct platform_device *dev)
 {
 	struct fb_info *fbi = platform_get_drvdata(dev);
 
-	writel(SYSRST_RST, SYSRST);
-	udelay(1000);
+	write_reg_dly(SYSRST_RST, SYSRST);
 
 	mbxfb_debugfs_remove(fbi);
 
diff --git a/drivers/video/mbx/reg_bits.h b/drivers/video/mbx/reg_bits.h
index c226a8e45312..9a24fb0c7d48 100644
--- a/drivers/video/mbx/reg_bits.h
+++ b/drivers/video/mbx/reg_bits.h
@@ -242,6 +242,67 @@
 #define GPLUT_LUTDATA	Fld(24,0)
 #define Gplut_Lutdata(x)	((x) << FShft(GPLUT_LUTDATA))
 
+/* VSCTRL - Video Surface Control Register */
+#define VSCTRL_VPIXFMT		Fld(4,27)
+#define VSCTRL_VPIXFMT_YUV12	((0x9) << FShft(VSCTRL_VPIXFMT))
+#define VSCTRL_VPIXFMT_UY0VY1	((0xc) << FShft(VSCTRL_VPIXFMT))
+#define VSCTRL_VPIXFMT_VY0UY1	((0xd) << FShft(VSCTRL_VPIXFMT))
+#define VSCTRL_VPIXFMT_Y0UY1V	((0xe) << FShft(VSCTRL_VPIXFMT))
+#define VSCTRL_VPIXFMT_Y0VY1U	((0xf) << FShft(VSCTRL_VPIXFMT))
+#define VSCTRL_GAMMA_EN		(1 << 26)
+#define VSCTRL_CSC_EN		(1 << 25)
+#define VSCTRL_COSITED		(1 << 22)
+#define VSCTRL_VSWIDTH		Fld(11,11)
+#define Vsctrl_Width(Pixels) /* Video Width [1-2048] */ \
+			(((Pixels) - 1) << FShft(VSCTRL_VSWIDTH))
+#define VSCTRL_VSHEIGHT		Fld(11,0)
+#define Vsctrl_Height(Pixels) /* Video Height [1-2048] */ \
+			(((Pixels) - 1) << FShft(VSCTRL_VSHEIGHT))
+
+/* VBBASE - Video Blending Base Register */
+#define VBBASE_GLALPHA		Fld(8,24)
+#define Vbbase_Glalpha(x)	((x) << FShft(VBBASE_GLALPHA))
+
+#define VBBASE_COLKEY		Fld(24,0)
+#define Vbbase_Colkey(x)	((x) << FShft(VBBASE_COLKEY))
+
+/* VCMSK - Video Color Key Mask Register */
+#define VCMSK_COLKEY_M		Fld(24,0)
+#define Vcmsk_colkey_m(x)	((x) << FShft(VCMSK_COLKEY_M))
+
+/* VSCADR - Video Stream Control Rddress Register */
+#define VSCADR_STR_EN		(1 << 31)
+#define VSCADR_COLKEY_EN	(1 << 30)
+#define VSCADR_COLKEYSRC	(1 << 29)
+#define VSCADR_BLEND_M		Fld(2,27)
+#define VSCADR_BLEND_NONE	((0x0) << FShft(VSCADR_BLEND_M))
+#define VSCADR_BLEND_INV	((0x1) << FShft(VSCADR_BLEND_M))
+#define VSCADR_BLEND_GLOB	((0x2) << FShft(VSCADR_BLEND_M))
+#define VSCADR_BLEND_PIX	((0x3) << FShft(VSCADR_BLEND_M))
+#define VSCADR_BLEND_POS	Fld(2,24)
+#define VSCADR_BLEND_GFX	((0x0) << FShft(VSCADR_BLEND_POS))
+#define VSCADR_BLEND_VID	((0x1) << FShft(VSCADR_BLEND_POS))
+#define VSCADR_BLEND_CUR	((0x2) << FShft(VSCADR_BLEND_POS))
+#define VSCADR_VBASE_ADR	Fld(23,0)
+#define Vscadr_Vbase_Adr(x)	((x) << FShft(VSCADR_VBASE_ADR))
+
+/* VUBASE - Video U Base Register */
+#define VUBASE_UVHALFSTR	(1 << 31)
+#define VUBASE_UBASE_ADR	Fld(24,0)
+#define Vubase_Ubase_Adr(x)	((x) << FShft(VUBASE_UBASE_ADR))
+
+/* VVBASE - Video V Base Register */
+#define VVBASE_VBASE_ADR	Fld(24,0)
+#define Vvbase_Vbase_Adr(x)	((x) << FShft(VVBASE_VBASE_ADR))
+
+/* VSADR - Video Stride Address Register */
+#define VSADR_SRCSTRIDE		Fld(10,22)
+#define Vsadr_Srcstride(x)	((x) << FShft(VSADR_SRCSTRIDE))
+#define VSADR_XSTART		Fld(11,11)
+#define Vsadr_Xstart(x)		((x) << FShft(VSADR_XSTART))
+#define VSADR_YSTART		Fld(11,0)
+#define Vsadr_Ystart(x)		((x) << FShft(VSADR_YSTART))
+
 /* HCCTRL - Hardware Cursor Register fields */
 #define HCCTRL_CUR_EN	(1 << 31)
 #define HCCTRL_COLKEY_EN	(1 << 29)
@@ -394,6 +455,30 @@
 #define DMCTRL_BURSTLEN	Fld(6,0)
 #define Dmctrl_Burstlen(x)	((x) << FShft(DMCTRL_BURSTLEN))
 
+/* DINTRS - Display Interrupt Status Register */
+#define DINTRS_CUR_OR_S		(1 << 18)
+#define DINTRS_STR2_OR_S	(1 << 17)
+#define DINTRS_STR1_OR_S	(1 << 16)
+#define DINTRS_CUR_UR_S		(1 << 6)
+#define DINTRS_STR2_UR_S	(1 << 5)
+#define DINTRS_STR1_UR_S	(1 << 4)
+#define DINTRS_VEVENT1_S	(1 << 3)
+#define DINTRS_VEVENT0_S	(1 << 2)
+#define DINTRS_HBLNK1_S		(1 << 1)
+#define DINTRS_HBLNK0_S		(1 << 0)
+
+/* DINTRE - Display Interrupt Enable Register */
+#define DINTRE_CUR_OR_EN	(1 << 18)
+#define DINTRE_STR2_OR_EN	(1 << 17)
+#define DINTRE_STR1_OR_EN	(1 << 16)
+#define DINTRE_CUR_UR_EN	(1 << 6)
+#define DINTRE_STR2_UR_EN	(1 << 5)
+#define DINTRE_STR1_UR_EN	(1 << 4)
+#define DINTRE_VEVENT1_EN	(1 << 3)
+#define DINTRE_VEVENT0_EN	(1 << 2)
+#define DINTRE_HBLNK1_EN	(1 << 1)
+#define DINTRE_HBLNK0_EN	(1 << 0)
+
 
 /* DLSTS - display load status register */
 #define DLSTS_RLD_ADONE	(1 << 23)
@@ -403,16 +488,41 @@
 #define DLLCTRL_RLD_ADRLN	Fld(8,24)
 #define Dllctrl_Rld_Adrln(x)	((x) << FShft(DLLCTRL_RLD_ADRLN))
 
+/* CLIPCTRL - Clipping Control Register */
+#define CLIPCTRL_HSKIP		Fld(11,16)
+#define Clipctrl_Hskip		((x) << FShft(CLIPCTRL_HSKIP))
+#define CLIPCTRL_VSKIP		Fld(11,0)
+#define Clipctrl_Vskip		((x) << FShft(CLIPCTRL_VSKIP))
+
 /* SPOCTRL - Scale Pitch/Order Control Register */
 #define SPOCTRL_H_SC_BP		(1 << 31)
 #define SPOCTRL_V_SC_BP		(1 << 30)
 #define SPOCTRL_HV_SC_OR	(1 << 29)
 #define SPOCTRL_VS_UR_C		(1 << 27)
-#define SPOCTRL_VORDER	Fld(2,16)
+#define SPOCTRL_VORDER		Fld(2,16)
 #define SPOCTRL_VORDER_1TAP	((0x0) << FShft(SPOCTRL_VORDER))
 #define SPOCTRL_VORDER_2TAP	((0x1) << FShft(SPOCTRL_VORDER))
 #define SPOCTRL_VORDER_4TAP	((0x3) << FShft(SPOCTRL_VORDER))
-#define SPOCTRL_VPITCH	Fld(16,0)
+#define SPOCTRL_VPITCH		Fld(16,0)
 #define Spoctrl_Vpitch(x)	((x) << FShft(SPOCTRL_VPITCH))
 
+/* SVCTRL - Scale Vertical Control Register */
+#define SVCTRL_INITIAL1		Fld(16,16)
+#define Svctrl_Initial1(x)	((x) << FShft(SVCTRL_INITIAL1))
+#define SVCTRL_INITIAL2		Fld(16,0)
+#define Svctrl_Initial2(x)	((x) << FShft(SVCTRL_INITIAL2))
+
+/* SHCTRL - Scale Horizontal Control Register */
+#define SHCTRL_HINITIAL		Fld(16,16)
+#define Shctrl_Hinitial(x)	((x) << FShft(SHCTRL_HINITIAL))
+#define SHCTRL_HDECIM		(1 << 15)
+#define SHCTRL_HPITCH		Fld(15,0)
+#define Shctrl_Hpitch(x)	((x) << FShft(SHCTRL_HPITCH))
+
+/* SSSIZE - Scale Surface Size Register */
+#define SSSIZE_SC_WIDTH		Fld(11,16)
+#define Sssize_Sc_Width(x)	((x) << FShft(SSSIZE_SC_WIDTH))
+#define SSSIZE_SC_HEIGHT	Fld(11,0)
+#define Sssize_Sc_Height(x)	((x) << FShft(SSSIZE_SC_HEIGHT))
+
 #endif /* __REG_BITS_2700G_ */
diff --git a/drivers/video/mbx/regs.h b/drivers/video/mbx/regs.h
index ad20be07666b..a7c63d865aad 100644
--- a/drivers/video/mbx/regs.h
+++ b/drivers/video/mbx/regs.h
@@ -127,7 +127,7 @@
 #define HSCOEFF0	__REG_2700G(0x000021b4)
 #define HSCOEFF1	__REG_2700G(0x000021b8)
 #define HSCOEFF2	__REG_2700G(0x000021bc)
-#define HSCOEFF3	__REG_2700G(0x000021b0)
+#define HSCOEFF3	__REG_2700G(0x000021c0)
 #define HSCOEFF4	__REG_2700G(0x000021c4)
 #define HSCOEFF5	__REG_2700G(0x000021c8)
 #define HSCOEFF6	__REG_2700G(0x000021cc)
diff --git a/drivers/video/modedb.c b/drivers/video/modedb.c
index d1267904c280..5df41f6f2b86 100644
--- a/drivers/video/modedb.c
+++ b/drivers/video/modedb.c
@@ -34,8 +34,6 @@ const char *global_mode_option;
      *  Standard video mode definitions (taken from XFree86)
      */
 
-#define DEFAULT_MODEDB_INDEX	0
-
 static const struct fb_videomode modedb[] = {
     {
 	/* 640x400 @ 70 Hz, 31.5 kHz hsync */
@@ -505,8 +503,10 @@ int fb_find_mode(struct fb_var_screeninfo *var,
 	db = modedb;
 	dbsize = ARRAY_SIZE(modedb);
     }
+
     if (!default_mode)
-	default_mode = &modedb[DEFAULT_MODEDB_INDEX];
+	default_mode = &db[0];
+
     if (!default_bpp)
 	default_bpp = 8;
 
diff --git a/drivers/video/neofb.c b/drivers/video/neofb.c
index 59a6f5fa5ae6..deaf820cb38f 100644
--- a/drivers/video/neofb.c
+++ b/drivers/video/neofb.c
@@ -1932,7 +1932,7 @@ static int __devinit neo_init_hw(struct fb_info *info)
 	printk(KERN_DEBUG "--- Neo extended register dump ---\n");
 	for (int w = 0; w < 0x85; w++)
 		printk(KERN_DEBUG "CR %p: %p\n", (void *) w,
-		       (void *) vga_rcrt(NULL, w);
+		       (void *) vga_rcrt(NULL, w));
 	for (int w = 0; w < 0xC7; w++)
 		printk(KERN_DEBUG "GR %p: %p\n", (void *) w,
 		       (void *) vga_rgfx(NULL, w));
diff --git a/drivers/video/nvidia/nv_accel.c b/drivers/video/nvidia/nv_accel.c
index 4aefb8f41637..9efb8a3854e2 100644
--- a/drivers/video/nvidia/nv_accel.c
+++ b/drivers/video/nvidia/nv_accel.c
@@ -261,41 +261,6 @@ void NVResetGraphics(struct fb_info *info)
 	NVDmaKickoff(par);
 }
 
-u8 byte_rev[256] = {
-	0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
-	0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
-	0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
-	0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
-	0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
-	0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
-	0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
-	0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
-	0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
-	0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
-	0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
-	0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
-	0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
-	0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
-	0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
-	0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
-	0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
-	0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
-	0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
-	0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
-	0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
-	0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
-	0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
-	0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
-	0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
-	0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
-	0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
-	0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
-	0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
-	0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
-	0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
-	0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff,
-};
-
 int nvidiafb_sync(struct fb_info *info)
 {
 	struct nvidia_par *par = info->par;
diff --git a/drivers/video/nvidia/nv_i2c.c b/drivers/video/nvidia/nv_i2c.c
index 19eef3a09023..442e85328341 100644
--- a/drivers/video/nvidia/nv_i2c.c
+++ b/drivers/video/nvidia/nv_i2c.c
@@ -210,11 +210,8 @@ int nvidia_probe_i2c_connector(struct fb_info *info, int conn, u8 **out_edid)
 		/* try to get from firmware */
 		const u8 *e = fb_firmware_edid(info->device);
 
-		if (e != NULL) {
-			edid = kmalloc(EDID_LENGTH, GFP_KERNEL);
-			if (edid)
-				memcpy(edid, e, EDID_LENGTH);
-		}
+		if (e != NULL)
+			edid = kmemdup(e, EDID_LENGTH, GFP_KERNEL);
 	}
 
 	*out_edid = edid;
diff --git a/drivers/video/nvidia/nv_local.h b/drivers/video/nvidia/nv_local.h
index 4243d7fae972..e009d242ea10 100644
--- a/drivers/video/nvidia/nv_local.h
+++ b/drivers/video/nvidia/nv_local.h
@@ -96,13 +96,16 @@
 #define READ_GET(par) (NV_RD32(&(par)->FIFO[0x0011], 0) >> 2)
 
 #ifdef __LITTLE_ENDIAN
+
+#include <linux/bitrev.h>
+
 #define reverse_order(l)        \
 do {                            \
 	u8 *a = (u8 *)(l);      \
-	*a = byte_rev[*a], a++; \
-	*a = byte_rev[*a], a++; \
-	*a = byte_rev[*a], a++; \
-	*a = byte_rev[*a];      \
+	a[0] = bitrev8(a[0]);   \
+	a[1] = bitrev8(a[1]);   \
+	a[2] = bitrev8(a[2]);   \
+	a[3] = bitrev8(a[3]);   \
 } while(0)
 #else
 #define reverse_order(l) do { } while(0)
diff --git a/drivers/video/nvidia/nv_of.c b/drivers/video/nvidia/nv_of.c
index d9af88c2b580..181875fe35c6 100644
--- a/drivers/video/nvidia/nv_of.c
+++ b/drivers/video/nvidia/nv_of.c
@@ -72,10 +72,9 @@ int nvidia_probe_of_connector(struct fb_info *info, int conn, u8 **out_edid)
 		}
 	}
 	if (pedid) {
-		*out_edid = kmalloc(EDID_LENGTH, GFP_KERNEL);
+		*out_edid = kmemdup(pedid, EDID_LENGTH, GFP_KERNEL);
 		if (*out_edid == NULL)
 			return -1;
-		memcpy(*out_edid, pedid, EDID_LENGTH);
 		printk(KERN_DEBUG "nvidiafb: Found OF EDID for head %d\n", conn);
 		return 0;
 	}
diff --git a/drivers/video/nvidia/nv_proto.h b/drivers/video/nvidia/nv_proto.h
index 861271017655..43058d0cf5b7 100644
--- a/drivers/video/nvidia/nv_proto.h
+++ b/drivers/video/nvidia/nv_proto.h
@@ -62,7 +62,6 @@ extern void nvidiafb_fillrect(struct fb_info *info,
 extern void nvidiafb_imageblit(struct fb_info *info,
 			       const struct fb_image *image);
 extern int nvidiafb_sync(struct fb_info *info);
-extern u8 byte_rev[256];
 
 /* in nv_backlight.h */
 #ifdef CONFIG_FB_NVIDIA_BACKLIGHT
diff --git a/drivers/video/offb.c b/drivers/video/offb.c
index 9a40bbecf76b..9576a55eaf16 100644
--- a/drivers/video/offb.c
+++ b/drivers/video/offb.c
@@ -402,6 +402,9 @@ static void __init offb_init_fb(const char *name, const char *full_name,
 	fb_alloc_cmap(&info->cmap, 256, 0);
 
 	if (register_framebuffer(info) < 0) {
+		iounmap(par->cmap_adr);
+		par->cmap_adr = NULL;
+		iounmap(info->screen_base);
 		kfree(info);
 		release_mem_region(res_start, res_size);
 		return;
diff --git a/drivers/video/platinumfb.c b/drivers/video/platinumfb.c
index cb26c6df0583..233871655824 100644
--- a/drivers/video/platinumfb.c
+++ b/drivers/video/platinumfb.c
@@ -627,6 +627,9 @@ static int __devinit platinumfb_probe(struct of_device* odev,
 	
 	rc = platinum_init_fb(info);
 	if (rc != 0) {
+		iounmap(pinfo->frame_buffer);
+		iounmap(pinfo->platinum_regs);
+		iounmap(pinfo->cmap_regs);
 		dev_set_drvdata(&odev->dev, NULL);
 		framebuffer_release(info);
 	}
diff --git a/drivers/video/pmagb-b-fb.c b/drivers/video/pmagb-b-fb.c
index 73e2d7d16608..a06a064ad757 100644
--- a/drivers/video/pmagb-b-fb.c
+++ b/drivers/video/pmagb-b-fb.c
@@ -186,7 +186,7 @@ static void __init pmagbbfb_screen_setup(struct fb_info *info)
 static void __init pmagbbfb_osc_setup(struct fb_info *info)
 {
 	static unsigned int pmagbbfb_freqs[] __initdata = {
-		130808, 119843, 104000, 92980, 74367, 72800,
+		130808, 119843, 104000, 92980, 74370, 72800,
 		69197, 66000, 65000, 50350, 36000, 32000, 25175
 	};
 	struct pmagbbfb_par *par = info->par;
diff --git a/drivers/video/pvr2fb.c b/drivers/video/pvr2fb.c
index c7bc80921f16..a93618bc9d27 100644
--- a/drivers/video/pvr2fb.c
+++ b/drivers/video/pvr2fb.c
@@ -905,6 +905,15 @@ static int __init pvr2fb_dc_init(void)
 
 static void pvr2fb_dc_exit(void)
 {
+	if (fb_info->screen_base) {
+		iounmap(fb_info->screen_base);
+		fb_info->screen_base = NULL;
+	}
+	if (currentpar->mmio_base) {
+		iounmap((void *)currentpar->mmio_base);
+		currentpar->mmio_base = 0;
+	}
+
 	free_irq(HW_EVENT_VSYNC, 0);
 #ifdef CONFIG_SH_DMA
 	free_dma(pvr2dma);
@@ -946,6 +955,15 @@ static int __devinit pvr2fb_pci_probe(struct pci_dev *pdev,
 
 static void __devexit pvr2fb_pci_remove(struct pci_dev *pdev)
 {
+	if (fb_info->screen_base) {
+		iounmap(fb_info->screen_base);
+		fb_info->screen_base = NULL;
+	}
+	if (currentpar->mmio_base) {
+		iounmap((void *)currentpar->mmio_base);
+		currentpar->mmio_base = 0;
+	}
+
 	pci_release_regions(pdev);
 }
 
diff --git a/drivers/video/retz3fb.c b/drivers/video/retz3fb.c
index cf41ff177644..bc7ffc84e185 100644
--- a/drivers/video/retz3fb.c
+++ b/drivers/video/retz3fb.c
@@ -1423,8 +1423,10 @@ int __init retz3fb_init(void)
 
 		do_install_cmap(0, fb_info);
 
-		if (register_framebuffer(fb_info) < 0)
+		if (register_framebuffer(fb_info) < 0) {
+			iounmap(zinfo->base);
 			return -EINVAL;
+		}
 
 		printk(KERN_INFO "fb%d: %s frame buffer device, using %ldK of "
 		       "video memory\n", fb_info->node,
diff --git a/drivers/video/riva/fbdev.c b/drivers/video/riva/fbdev.c
index a433cc78ef90..345e8b1c1af8 100644
--- a/drivers/video/riva/fbdev.c
+++ b/drivers/video/riva/fbdev.c
@@ -40,6 +40,7 @@
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/backlight.h>
+#include <linux/bitrev.h>
 #ifdef CONFIG_MTRR
 #include <asm/mtrr.h>
 #endif
@@ -521,48 +522,13 @@ static inline unsigned char MISCin(struct riva_par *par)
 	return (VGA_RD08(par->riva.PVIO, 0x3cc));
 }
 
-static u8 byte_rev[256] = {
-	0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
-	0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
-	0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
-	0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
-	0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
-	0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
-	0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
-	0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
-	0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
-	0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
-	0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
-	0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
-	0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
-	0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
-	0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
-	0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
-	0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
-	0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
-	0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
-	0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
-	0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
-	0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
-	0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
-	0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
-	0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
-	0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
-	0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
-	0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
-	0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
-	0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
-	0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
-	0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff,
-};
-
 static inline void reverse_order(u32 *l)
 {
 	u8 *a = (u8 *)l;
-	*a = byte_rev[*a], a++;
-	*a = byte_rev[*a], a++;
-	*a = byte_rev[*a], a++;
-	*a = byte_rev[*a];
+	a[0] = bitrev8(a[0]);
+	a[1] = bitrev8(a[1]);
+	a[2] = bitrev8(a[2]);
+	a[3] = bitrev8(a[3]);
 }
 
 /* ------------------------------------------------------------------------- *
@@ -774,11 +740,12 @@ static void riva_load_state(struct riva_par *par, struct riva_regs *regs)
  * CALLED FROM:
  * rivafb_set_par()
  */
-static void riva_load_video_mode(struct fb_info *info)
+static int riva_load_video_mode(struct fb_info *info)
 {
 	int bpp, width, hDisplaySize, hDisplay, hStart,
 	    hEnd, hTotal, height, vDisplay, vStart, vEnd, vTotal, dotClock;
 	int hBlankStart, hBlankEnd, vBlankStart, vBlankEnd;
+	int rc;
 	struct riva_par *par = info->par;
 	struct riva_regs newmode;
 	
@@ -884,8 +851,10 @@ static void riva_load_video_mode(struct fb_info *info)
 	else
 		newmode.misc_output |= 0x80;	
 
-	par->riva.CalcStateExt(&par->riva, &newmode.ext, bpp, width,
-				  hDisplaySize, height, dotClock);
+	rc = CalcStateExt(&par->riva, &newmode.ext, bpp, width,
+			  hDisplaySize, height, dotClock);
+	if (rc)
+		goto out;
 
 	newmode.ext.scale = NV_RD32(par->riva.PRAMDAC, 0x00000848) &
 		0xfff000ff;
@@ -917,8 +886,12 @@ static void riva_load_video_mode(struct fb_info *info)
 	par->current_state = newmode;
 	riva_load_state(par, &par->current_state);
 	par->riva.LockUnlock(&par->riva, 0); /* important for HW cursor */
+
+out:
 	rivafb_blank(FB_BLANK_UNBLANK, info);
 	NVTRACE_LEAVE();
+
+	return rc;
 }
 
 static void riva_update_var(struct fb_var_screeninfo *var, struct fb_videomode *modedb)
@@ -1286,12 +1259,15 @@ static int rivafb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
 static int rivafb_set_par(struct fb_info *info)
 {
 	struct riva_par *par = info->par;
+	int rc = 0;
 
 	NVTRACE_ENTER();
 	/* vgaHWunlock() + riva unlock (0x7F) */
 	CRTCout(par, 0x11, 0xFF);
 	par->riva.LockUnlock(&par->riva, 0);
-	riva_load_video_mode(info);
+	rc = riva_load_video_mode(info);
+	if (rc)
+		goto out;
 	if(!(info->flags & FBINFO_HWACCEL_DISABLED))
 		riva_setup_accel(info);
 	
@@ -1304,8 +1280,10 @@ static int rivafb_set_par(struct fb_info *info)
 		info->pixmap.scan_align = 1;
 	else
 		info->pixmap.scan_align = 4;
+
+out:
 	NVTRACE_LEAVE();
-	return 0;
+	return rc;
 }
 
 /**
diff --git a/drivers/video/riva/riva_hw.c b/drivers/video/riva/riva_hw.c
index b6f8690b96c9..e0b8c521cc9c 100644
--- a/drivers/video/riva/riva_hw.c
+++ b/drivers/video/riva/riva_hw.c
@@ -1227,7 +1227,7 @@ static int CalcVClock
  * Calculate extended mode parameters (SVGA) and save in a 
  * mode state structure.
  */
-static void CalcStateExt
+int CalcStateExt
 (
     RIVA_HW_INST  *chip,
     RIVA_HW_STATE *state,
@@ -1249,7 +1249,8 @@ static void CalcStateExt
      * Extended RIVA registers.
      */
     pixelDepth = (bpp + 1)/8;
-    CalcVClock(dotClock, &VClk, &m, &n, &p, chip);
+    if (!CalcVClock(dotClock, &VClk, &m, &n, &p, chip))
+    	return -EINVAL;
 
     switch (chip->Architecture)
     {
@@ -1327,6 +1328,8 @@ static void CalcStateExt
     state->pitch1   =
     state->pitch2   =
     state->pitch3   = pixelDepth * width;
+
+    return 0;
 }
 /*
  * Load fixed function state and pre-calculated/stored state.
@@ -2026,7 +2029,6 @@ static void nv3GetConfig
      */
     chip->Busy            = nv3Busy;
     chip->ShowHideCursor  = ShowHideCursor;
-    chip->CalcStateExt    = CalcStateExt;
     chip->LoadStateExt    = LoadStateExt;
     chip->UnloadStateExt  = UnloadStateExt;
     chip->SetStartAddress = SetStartAddress3;
@@ -2084,7 +2086,6 @@ static void nv4GetConfig
      */
     chip->Busy            = nv4Busy;
     chip->ShowHideCursor  = ShowHideCursor;
-    chip->CalcStateExt    = CalcStateExt;
     chip->LoadStateExt    = LoadStateExt;
     chip->UnloadStateExt  = UnloadStateExt;
     chip->SetStartAddress = SetStartAddress;
@@ -2186,7 +2187,6 @@ static void nv10GetConfig
      */
     chip->Busy            = nv10Busy;
     chip->ShowHideCursor  = ShowHideCursor;
-    chip->CalcStateExt    = CalcStateExt;
     chip->LoadStateExt    = LoadStateExt;
     chip->UnloadStateExt  = UnloadStateExt;
     chip->SetStartAddress = SetStartAddress;
diff --git a/drivers/video/riva/riva_hw.h b/drivers/video/riva/riva_hw.h
index a1e71a626df2..c2769f73e0b2 100644
--- a/drivers/video/riva/riva_hw.h
+++ b/drivers/video/riva/riva_hw.h
@@ -463,7 +463,6 @@ typedef struct _riva_hw_inst
      * Common chip functions.
      */
     int  (*Busy)(struct _riva_hw_inst *);
-    void (*CalcStateExt)(struct _riva_hw_inst *,struct _riva_hw_state *,int,int,int,int,int);
     void (*LoadStateExt)(struct _riva_hw_inst *,struct _riva_hw_state *);
     void (*UnloadStateExt)(struct _riva_hw_inst *,struct _riva_hw_state *);
     void (*SetStartAddress)(struct _riva_hw_inst *,U032);
@@ -528,6 +527,22 @@ typedef struct _riva_hw_state
     U032 pitch2;
     U032 pitch3;
 } RIVA_HW_STATE;
+
+/*
+ * function prototypes
+ */
+
+extern int CalcStateExt
+(
+    RIVA_HW_INST  *chip,
+    RIVA_HW_STATE *state,
+    int            bpp,
+    int            width,
+    int            hDisplaySize,
+    int            height,
+    int            dotClock
+);
+
 /*
  * External routines.
  */
diff --git a/drivers/video/s3c2410fb.c b/drivers/video/s3c2410fb.c
index 59407343cc73..ccef56d0c157 100644
--- a/drivers/video/s3c2410fb.c
+++ b/drivers/video/s3c2410fb.c
@@ -131,7 +131,7 @@ static void s3c2410fb_set_lcdaddr(struct s3c2410fb_info *fbi)
 	saddr2 += (var->xres * var->yres * var->bits_per_pixel)/8;
 	saddr2>>= 1;
 
-	saddr3 =  S3C2410_OFFSIZE(0) | S3C2410_PAGEWIDTH(var->xres);
+	saddr3 =  S3C2410_OFFSIZE(0) | S3C2410_PAGEWIDTH((var->xres * var->bits_per_pixel / 16) & 0x3ff);
 
 	dprintk("LCDSADDR1 = 0x%08lx\n", saddr1);
 	dprintk("LCDSADDR2 = 0x%08lx\n", saddr2);
@@ -199,28 +199,86 @@ static int s3c2410fb_check_var(struct fb_var_screeninfo *var,
 		var->bits_per_pixel = fbi->mach_info->bpp.min;
 
 	/* set r/g/b positions */
+	switch (var->bits_per_pixel) {
+		case 1:
+		case 2:
+		case 4:
+			var->red.offset    	= 0;
+			var->red.length    	= var->bits_per_pixel;
+			var->green         	= var->red;
+			var->blue          	= var->red;
+			var->transp.offset 	= 0;
+			var->transp.length 	= 0;
+			break;
+		case 8:
+			if ( fbi->mach_info->type != S3C2410_LCDCON1_TFT ) {
+				/* 8 bpp 332 */
+				var->red.length		= 3;
+				var->red.offset		= 5;
+				var->green.length	= 3;
+				var->green.offset	= 2;
+				var->blue.length	= 2;
+				var->blue.offset	= 0;
+				var->transp.length	= 0;
+			} else {
+				var->red.offset    	= 0;
+				var->red.length    	= var->bits_per_pixel;
+				var->green         	= var->red;
+				var->blue          	= var->red;
+				var->transp.offset 	= 0;
+				var->transp.length 	= 0;
+			}
+			break;
+		case 12:
+			/* 12 bpp 444 */
+			var->red.length		= 4;
+			var->red.offset		= 8;
+			var->green.length	= 4;
+			var->green.offset	= 4;
+			var->blue.length	= 4;
+			var->blue.offset	= 0;
+			var->transp.length	= 0;
+			break;
+
+		default:
+		case 16:
+			if (fbi->regs.lcdcon5 & S3C2410_LCDCON5_FRM565 ) {
+				/* 16 bpp, 565 format */
+				var->red.offset		= 11;
+				var->green.offset	= 5;
+				var->blue.offset	= 0;
+				var->red.length		= 5;
+				var->green.length	= 6;
+				var->blue.length	= 5;
+				var->transp.length	= 0;
+			} else {
+				/* 16 bpp, 5551 format */
+				var->red.offset		= 11;
+				var->green.offset	= 6;
+				var->blue.offset	= 1;
+				var->red.length		= 5;
+				var->green.length	= 5;
+				var->blue.length	= 5;
+				var->transp.length	= 0;
+			}
+			break;
+		case 24:
+			/* 24 bpp 888 */
+			var->red.length		= 8;
+			var->red.offset		= 16;
+			var->green.length	= 8;
+			var->green.offset	= 8;
+			var->blue.length	= 8;
+			var->blue.offset	= 0;
+			var->transp.length	= 0;
+			break;
 
-	if (var->bits_per_pixel == 16) {
-		var->red.offset		= 11;
-		var->green.offset	= 5;
-		var->blue.offset	= 0;
-		var->red.length		= 5;
-		var->green.length	= 6;
-		var->blue.length	= 5;
-		var->transp.length	= 0;
-	} else {
-		var->red.length		= var->bits_per_pixel;
-		var->red.offset		= 0;
-		var->green.length	= var->bits_per_pixel;
-		var->green.offset	= 0;
-		var->blue.length	= var->bits_per_pixel;
-		var->blue.offset	= 0;
-		var->transp.length	= 0;
-	}
 
+	}
 	return 0;
 }
 
+
 /* s3c2410fb_activate_var
  *
  * activate (set) the controller from the given framebuffer
@@ -230,29 +288,61 @@ static int s3c2410fb_check_var(struct fb_var_screeninfo *var,
 static void s3c2410fb_activate_var(struct s3c2410fb_info *fbi,
 				   struct fb_var_screeninfo *var)
 {
+	int hs;
+
 	fbi->regs.lcdcon1 &= ~S3C2410_LCDCON1_MODEMASK;
+	fbi->regs.lcdcon1 &= ~S3C2410_LCDCON1_TFT;
 
 	dprintk("%s: var->xres  = %d\n", __FUNCTION__, var->xres);
 	dprintk("%s: var->yres  = %d\n", __FUNCTION__, var->yres);
 	dprintk("%s: var->bpp   = %d\n", __FUNCTION__, var->bits_per_pixel);
 
-	switch (var->bits_per_pixel) {
-	case 1:
-		fbi->regs.lcdcon1 |= S3C2410_LCDCON1_TFT1BPP;
-		break;
-	case 2:
-		fbi->regs.lcdcon1 |= S3C2410_LCDCON1_TFT2BPP;
-		break;
-	case 4:
-		fbi->regs.lcdcon1 |= S3C2410_LCDCON1_TFT4BPP;
-		break;
-	case 8:
-		fbi->regs.lcdcon1 |= S3C2410_LCDCON1_TFT8BPP;
-		break;
-	case 16:
-		fbi->regs.lcdcon1 |= S3C2410_LCDCON1_TFT16BPP;
-		break;
-	}
+	fbi->regs.lcdcon1 |= fbi->mach_info->type;
+
+	if (fbi->mach_info->type == S3C2410_LCDCON1_TFT)
+		switch (var->bits_per_pixel) {
+		case 1:
+			fbi->regs.lcdcon1 |= S3C2410_LCDCON1_TFT1BPP;
+			break;
+		case 2:
+			fbi->regs.lcdcon1 |= S3C2410_LCDCON1_TFT2BPP;
+			break;
+		case 4:
+			fbi->regs.lcdcon1 |= S3C2410_LCDCON1_TFT4BPP;
+			break;
+		case 8:
+			fbi->regs.lcdcon1 |= S3C2410_LCDCON1_TFT8BPP;
+			break;
+		case 16:
+			fbi->regs.lcdcon1 |= S3C2410_LCDCON1_TFT16BPP;
+			break;
+
+		default:
+			/* invalid pixel depth */
+			dev_err(fbi->dev, "invalid bpp %d\n", var->bits_per_pixel);
+		}
+	else
+		switch (var->bits_per_pixel) {
+		case 1:
+			fbi->regs.lcdcon1 |= S3C2410_LCDCON1_STN1BPP;
+			break;
+		case 2:
+			fbi->regs.lcdcon1 |= S3C2410_LCDCON1_STN2GREY;
+			break;
+		case 4:
+			fbi->regs.lcdcon1 |= S3C2410_LCDCON1_STN4GREY;
+			break;
+		case 8:
+			fbi->regs.lcdcon1 |= S3C2410_LCDCON1_STN8BPP;
+			break;
+		case 12:
+			fbi->regs.lcdcon1 |= S3C2410_LCDCON1_STN12BPP;
+			break;
+
+		default:
+			/* invalid pixel depth */
+			dev_err(fbi->dev, "invalid bpp %d\n", var->bits_per_pixel);
+		}
 
 	/* check to see if we need to update sync/borders */
 
@@ -283,15 +373,44 @@ static void s3c2410fb_activate_var(struct s3c2410fb_info *fbi,
 	fbi->regs.lcdcon2 &= ~S3C2410_LCDCON2_LINEVAL(0x3ff);
 	fbi->regs.lcdcon2 |=  S3C2410_LCDCON2_LINEVAL(var->yres - 1);
 
+	switch(fbi->mach_info->type) {
+		case S3C2410_LCDCON1_DSCAN4:
+		case S3C2410_LCDCON1_STN8:
+			hs = var->xres / 8;
+			break;
+		case S3C2410_LCDCON1_STN4:
+			hs = var->xres / 4;
+			break;
+		default:
+		case S3C2410_LCDCON1_TFT:
+			hs = var->xres;
+			break;
+
+	}
+
+	/* Special cases : STN color displays */
+	if ( ((fbi->regs.lcdcon1 & S3C2410_LCDCON1_MODEMASK) == S3C2410_LCDCON1_STN8BPP) \
+	  || ((fbi->regs.lcdcon1 & S3C2410_LCDCON1_MODEMASK) == S3C2410_LCDCON1_STN12BPP) ) {
+		hs = hs * 3;
+	}
+
+
 	fbi->regs.lcdcon3 &= ~S3C2410_LCDCON3_HOZVAL(0x7ff);
-	fbi->regs.lcdcon3 |=  S3C2410_LCDCON3_HOZVAL(var->xres - 1);
+	fbi->regs.lcdcon3 |=  S3C2410_LCDCON3_HOZVAL(hs - 1);
 
 	if (var->pixclock > 0) {
 		int clkdiv = s3c2410fb_calc_pixclk(fbi, var->pixclock);
 
-		clkdiv = (clkdiv / 2) -1;
-		if (clkdiv < 0)
-			clkdiv = 0;
+		if (fbi->mach_info->type == S3C2410_LCDCON1_TFT) {
+			clkdiv = (clkdiv / 2) -1;
+			if (clkdiv < 0)
+				clkdiv = 0;
+		}
+		else {
+			clkdiv = (clkdiv / 2);
+			if (clkdiv < 2)
+				clkdiv = 2;
+		}
 
 		fbi->regs.lcdcon1 &= ~S3C2410_LCDCON1_CLKVAL(0x3ff);
 		fbi->regs.lcdcon1 |=  S3C2410_LCDCON1_CLKVAL(clkdiv);
@@ -329,10 +448,18 @@ static int s3c2410fb_set_par(struct fb_info *info)
 	struct s3c2410fb_info *fbi = info->par;
 	struct fb_var_screeninfo *var = &info->var;
 
-	if (var->bits_per_pixel == 16)
-		fbi->fb->fix.visual = FB_VISUAL_TRUECOLOR;
-	else
-		fbi->fb->fix.visual = FB_VISUAL_PSEUDOCOLOR;
+	switch (var->bits_per_pixel)
+	{
+		case 16:
+			fbi->fb->fix.visual = FB_VISUAL_TRUECOLOR;
+			break;
+		case 1:
+			 fbi->fb->fix.visual = FB_VISUAL_MONO01;
+			 break;
+		default:
+			 fbi->fb->fix.visual = FB_VISUAL_PSEUDOCOLOR;
+			 break;
+	}
 
 	fbi->fb->fix.line_length     = (var->width*var->bits_per_pixel)/8;
 
diff --git a/drivers/video/savage/savagefb-i2c.c b/drivers/video/savage/savagefb-i2c.c
index 3f94223b7f0c..cef5bf591cdf 100644
--- a/drivers/video/savage/savagefb-i2c.c
+++ b/drivers/video/savage/savagefb-i2c.c
@@ -227,11 +227,8 @@ int savagefb_probe_i2c_connector(struct fb_info *info, u8 **out_edid)
 		/* try to get from firmware */
 		const u8 *e = fb_firmware_edid(info->device);
 
-		if (e) {
-			edid = kmalloc(EDID_LENGTH, GFP_KERNEL);
-			if (edid)
-				memcpy(edid, e, EDID_LENGTH);
-		}
+		if (e)
+			edid = kmemdup(e, EDID_LENGTH, GFP_KERNEL);
 	}
 
 	*out_edid = edid;
diff --git a/drivers/video/sis/init301.c b/drivers/video/sis/init301.c
index f13faddc6181..47e1896cffeb 100644
--- a/drivers/video/sis/init301.c
+++ b/drivers/video/sis/init301.c
@@ -445,11 +445,8 @@ SiS_CR36BIOSWord23d(struct SiS_Private *SiS_Pr)
 void
 SiS_DDC2Delay(struct SiS_Private *SiS_Pr, unsigned int delaytime)
 {
-   unsigned int i, j;
-
-   for(i = 0; i < delaytime; i++) {
-      j += SiS_GetReg(SiS_Pr->SiS_P3c4,0x05);
-   }
+   while (delaytime-- > 0)
+      SiS_GetReg(SiS_Pr->SiS_P3c4, 0x05);
 }
 
 #if defined(SIS300) || defined(SIS315H)
diff --git a/drivers/video/stifb.c b/drivers/video/stifb.c
index 3e16e2d9d55d..69f3b264a22e 100644
--- a/drivers/video/stifb.c
+++ b/drivers/video/stifb.c
@@ -1291,6 +1291,7 @@ out_err3:
 out_err2:
 	release_mem_region(fix->smem_start, fix->smem_len);
 out_err1:
+	iounmap(info->screen_base);
 	fb_dealloc_cmap(&info->cmap);
 out_err0:
 	kfree(fb);
@@ -1364,6 +1365,8 @@ stifb_cleanup(void)
 			unregister_framebuffer(sti->info);
 			release_mem_region(info->fix.mmio_start, info->fix.mmio_len);
 		        release_mem_region(info->fix.smem_start, info->fix.smem_len);
+				if (info->screen_base)
+					iounmap(info->screen_base);
 		        fb_dealloc_cmap(&info->cmap);
 		        kfree(info); 
 		}
diff --git a/drivers/video/tgafb.c b/drivers/video/tgafb.c
index 94fde625a6c0..4b88fab83b74 100644
--- a/drivers/video/tgafb.c
+++ b/drivers/video/tgafb.c
@@ -23,6 +23,7 @@
 #include <linux/fb.h>
 #include <linux/pci.h>
 #include <linux/selection.h>
+#include <linux/bitrev.h>
 #include <asm/io.h>
 #include <video/tgafb.h>
 
@@ -517,41 +518,6 @@ tgafb_blank(int blank, struct fb_info *info)
 static void
 tgafb_imageblit(struct fb_info *info, const struct fb_image *image)
 {
-	static unsigned char const bitrev[256] = {
-		0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
-		0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
-		0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
-		0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
-		0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
-		0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
-		0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
-		0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
-		0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
-		0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
-		0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
-		0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
-		0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
-		0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
-		0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
-		0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
-		0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
-		0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
-		0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
-		0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
-		0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
-		0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
-		0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
-		0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
-		0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
-		0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
-		0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
-		0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
-		0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
-		0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
-		0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
-		0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff
-	};
-
 	struct tga_par *par = (struct tga_par *) info->par;
 	u32 fgcolor, bgcolor, dx, dy, width, height, vxres, vyres, pixelmask;
 	unsigned long rincr, line_length, shift, pos, is8bpp;
@@ -649,7 +615,7 @@ tgafb_imageblit(struct fb_info *info, const struct fb_image *image)
 			/* The image data is bit big endian; we need
 			   little endian.  */
 			for (j = 0; j < bwidth; ++j)
-				mask |= bitrev[data[j]] << (j * 8);
+				mask |= bitrev8(data[j]) << (j * 8);
 
 			__raw_writel(mask << shift, fb_base + pos);
 
@@ -676,10 +642,10 @@ tgafb_imageblit(struct fb_info *info, const struct fb_image *image)
 		for (i = 0; i < height; ++i) {
 			for (j = 0; j < bwidth; j += 4) {
 				u32 mask = 0;
-				mask |= bitrev[data[j+0]] << (0 * 8);
-				mask |= bitrev[data[j+1]] << (1 * 8);
-				mask |= bitrev[data[j+2]] << (2 * 8);
-				mask |= bitrev[data[j+3]] << (3 * 8);
+				mask |= bitrev8(data[j+0]) << (0 * 8);
+				mask |= bitrev8(data[j+1]) << (1 * 8);
+				mask |= bitrev8(data[j+2]) << (2 * 8);
+				mask |= bitrev8(data[j+3]) << (3 * 8);
 				__raw_writel(mask, fb_base + pos + j*bincr);
 			}
 			pos += line_length;
@@ -699,7 +665,7 @@ tgafb_imageblit(struct fb_info *info, const struct fb_image *image)
 			for (i = 0; i < height; ++i) {
 				u32 mask = 0;
 				for (j = 0; j < bwidth; ++j)
-					mask |= bitrev[data[j]] << (j * 8);
+					mask |= bitrev8(data[j]) << (j * 8);
 				__raw_writel(mask, fb_base + pos);
 				pos += line_length;
 				data += rincr;
@@ -726,8 +692,8 @@ tgafb_imageblit(struct fb_info *info, const struct fb_image *image)
 		for (i = 0; i < height; ++i) {
 			for (j = 0; j < bwidth; j += 2) {
 				u32 mask = 0;
-				mask |= bitrev[data[j+0]] << (0 * 8);
-				mask |= bitrev[data[j+1]] << (1 * 8);
+				mask |= bitrev8(data[j+0]) << (0 * 8);
+				mask |= bitrev8(data[j+1]) << (1 * 8);
 				mask <<= shift;
 				__raw_writel(mask, fb_base + pos + j*bincr);
 			}
@@ -746,9 +712,9 @@ tgafb_imageblit(struct fb_info *info, const struct fb_image *image)
 			bwidth = (width & 15) > 8;
 
 			for (i = 0; i < height; ++i) {
-				u32 mask = bitrev[data[0]];
+				u32 mask = bitrev8(data[0]);
 				if (bwidth)
-					mask |= bitrev[data[1]] << 8;
+					mask |= bitrev8(data[1]) << 8;
 				mask <<= shift;
 				__raw_writel(mask, fb_base + pos);
 				pos += line_length;
@@ -1473,6 +1439,8 @@ tgafb_pci_register(struct pci_dev *pdev, const struct pci_device_id *ent)
 	return 0;
 
  err1:
+	if (mem_base)
+		iounmap(mem_base);
 	release_mem_region(bar0_start, bar0_len);
  err0:
 	kfree(all);
diff --git a/drivers/video/tridentfb.c b/drivers/video/tridentfb.c
index 14175cdb9c9c..55e8aa450bfa 100644
--- a/drivers/video/tridentfb.c
+++ b/drivers/video/tridentfb.c
@@ -1130,7 +1130,8 @@ static int __devinit trident_pci_probe(struct pci_dev * dev, const struct pci_de
 	
 	if (!request_mem_region(tridentfb_fix.smem_start, tridentfb_fix.smem_len, "tridentfb")) {
 		debug("request_mem_region failed!\n");
-		return -1;
+		err = -1;
+		goto out_unmap;
 	}
 
 	fb_info.screen_base = ioremap_nocache(tridentfb_fix.smem_start,
@@ -1139,7 +1140,8 @@ static int __devinit trident_pci_probe(struct pci_dev * dev, const struct pci_de
 	if (!fb_info.screen_base) {
 		release_mem_region(tridentfb_fix.smem_start, tridentfb_fix.smem_len);
 		debug("ioremap failed\n");
-		return -1;
+		err = -1;
+		goto out_unmap;
 	}
 
 	output("%s board found\n", pci_name(dev));
@@ -1162,8 +1164,10 @@ static int __devinit trident_pci_probe(struct pci_dev * dev, const struct pci_de
 #endif
 	fb_info.pseudo_palette = pseudo_pal;
 
-	if (!fb_find_mode(&default_var,&fb_info,mode,NULL,0,NULL,bpp))
-		return -EINVAL;
+	if (!fb_find_mode(&default_var,&fb_info,mode,NULL,0,NULL,bpp)) {
+		err = -EINVAL;
+		goto out_unmap;
+	}
 	fb_alloc_cmap(&fb_info.cmap,256,0);
 	if (defaultaccel && acc)
 		default_var.accel_flags |= FB_ACCELF_TEXT;
@@ -1174,12 +1178,20 @@ static int __devinit trident_pci_probe(struct pci_dev * dev, const struct pci_de
 	fb_info.device = &dev->dev;
 	if (register_framebuffer(&fb_info) < 0) {
 		printk(KERN_ERR "tridentfb: could not register Trident framebuffer\n");
-		return -EINVAL;
+		err = -EINVAL;
+		goto out_unmap;
 	}
 	output("fb%d: %s frame buffer device %dx%d-%dbpp\n",
 	   fb_info.node, fb_info.fix.id,default_var.xres,
 	   default_var.yres,default_var.bits_per_pixel);
 	return 0;
+
+out_unmap:
+	if (default_par.io_virt)
+		iounmap(default_par.io_virt);
+	if (fb_info.screen_base)
+		iounmap(fb_info.screen_base);
+	return err;
 }
 
 static void __devexit trident_pci_remove(struct pci_dev * dev)
diff --git a/drivers/video/vesafb.c b/drivers/video/vesafb.c
index 2196448396ec..e16322d157d0 100644
--- a/drivers/video/vesafb.c
+++ b/drivers/video/vesafb.c
@@ -47,17 +47,16 @@ static struct fb_fix_screeninfo vesafb_fix __initdata = {
 	.accel	= FB_ACCEL_NONE,
 };
 
-static int             inverse   = 0;
-static int             mtrr      = 0; /* disable mtrr */
-static int	       vram_remap __initdata = 0; /* Set amount of memory to be used */
-static int	       vram_total __initdata = 0; /* Set total amount of memory */
-static int             pmi_setpal = 1;	/* pmi for palette changes ??? */
-static int             ypan       = 0;  /* 0..nothing, 1..ypan, 2..ywrap */
-static unsigned short  *pmi_base  = NULL;
-static void            (*pmi_start)(void);
-static void            (*pmi_pal)(void);
-static int             depth;
-static int             vga_compat;
+static int   inverse    __read_mostly;
+static int   mtrr       __read_mostly;		/* disable mtrr */
+static int   vram_remap __initdata;		/* Set amount of memory to be used */
+static int   vram_total __initdata;		/* Set total amount of memory */
+static int   pmi_setpal __read_mostly = 1;	/* pmi for palette changes ??? */
+static int   ypan       __read_mostly;		/* 0..nothing, 1..ypan, 2..ywrap */
+static void  (*pmi_start)(void) __read_mostly;
+static void  (*pmi_pal)  (void) __read_mostly;
+static int   depth      __read_mostly;
+static int   vga_compat __read_mostly;
 /* --------------------------------------------------------------------- */
 
 static int vesafb_pan_display(struct fb_var_screeninfo *var,
@@ -312,6 +311,7 @@ static int __init vesafb_probe(struct platform_device *dev)
 		ypan = pmi_setpal = 0; /* not available or some DOS TSR ... */
 
 	if (ypan || pmi_setpal) {
+		unsigned short *pmi_base;
 		pmi_base  = (unsigned short*)phys_to_virt(((unsigned long)screen_info.vesapm_seg << 4) + screen_info.vesapm_off);
 		pmi_start = (void*)((char*)pmi_base + pmi_base[1]);
 		pmi_pal   = (void*)((char*)pmi_base + pmi_base[2]);
@@ -456,6 +456,8 @@ static int __init vesafb_probe(struct platform_device *dev)
 	       info->node, info->fix.id);
 	return 0;
 err:
+	if (info->screen_base)
+		iounmap(info->screen_base);
 	framebuffer_release(info);
 	release_mem_region(vesafb_fix.smem_start, size_total);
 	return err;
diff --git a/drivers/video/vga16fb.c b/drivers/video/vga16fb.c
index 43d5a6d9c4a6..6aff63d5b295 100644
--- a/drivers/video/vga16fb.c
+++ b/drivers/video/vga16fb.c
@@ -264,7 +264,7 @@ static void vga16fb_clock_chip(struct vga16fb_par *par,
 			       const struct fb_info *info,
 			       int mul, int div)
 {
-	static struct {
+	static const struct {
 		u32 pixclock;
 		u8  misc;
 		u8  seq_clock_mode;
@@ -652,7 +652,7 @@ static int vga16fb_set_par(struct fb_info *info)
 
 static void ega16_setpalette(int regno, unsigned red, unsigned green, unsigned blue)
 {
-	static unsigned char map[] = { 000, 001, 010, 011 };
+	static const unsigned char map[] = { 000, 001, 010, 011 };
 	int val;
 	
 	if (regno >= 16)
@@ -1139,23 +1139,19 @@ static void vga16fb_copyarea(struct fb_info *info, const struct fb_copyarea *are
 	}
 }
 
-#ifdef __LITTLE_ENDIAN
-static unsigned int transl_l[] =
-{0x0,0x8,0x4,0xC,0x2,0xA,0x6,0xE,0x1,0x9,0x5,0xD,0x3,0xB,0x7,0xF};
-static unsigned int transl_h[] =
-{0x000, 0x800, 0x400, 0xC00, 0x200, 0xA00, 0x600, 0xE00,
- 0x100, 0x900, 0x500, 0xD00, 0x300, 0xB00, 0x700, 0xF00};
-#else
-#ifdef __BIG_ENDIAN
-static unsigned int transl_h[] =
-{0x0,0x8,0x4,0xC,0x2,0xA,0x6,0xE,0x1,0x9,0x5,0xD,0x3,0xB,0x7,0xF};
-static unsigned int transl_l[] =
-{0x000, 0x800, 0x400, 0xC00, 0x200, 0xA00, 0x600, 0xE00,
- 0x100, 0x900, 0x500, 0xD00, 0x300, 0xB00, 0x700, 0xF00};
+#define TRANS_MASK_LOW  {0x0,0x8,0x4,0xC,0x2,0xA,0x6,0xE,0x1,0x9,0x5,0xD,0x3,0xB,0x7,0xF}
+#define TRANS_MASK_HIGH {0x000, 0x800, 0x400, 0xC00, 0x200, 0xA00, 0x600, 0xE00, \
+			 0x100, 0x900, 0x500, 0xD00, 0x300, 0xB00, 0x700, 0xF00}
+
+#if defined(__LITTLE_ENDIAN)
+static const u16 transl_l[] = TRANS_MASK_LOW;
+static const u16 transl_h[] = TRANS_MASK_HIGH;
+#elif defined(__BIG_ENDIAN)
+static const u16 transl_l[] = TRANS_MASK_HIGH;
+static const u16 transl_h[] = TRANS_MASK_LOW;
 #else
 #error "Only __BIG_ENDIAN and __LITTLE_ENDIAN are supported in vga-planes"
 #endif
-#endif
 
 static void vga_8planes_imageblit(struct fb_info *info, const struct fb_image *image)
 {
diff --git a/drivers/video/virgefb.c b/drivers/video/virgefb.c
index 64378959dd7b..b9fb6fb3600d 100644
--- a/drivers/video/virgefb.c
+++ b/drivers/video/virgefb.c
@@ -1799,7 +1799,7 @@ int __init virgefb_init(void)
 		#warning release resources
 		printk(KERN_ERR "virgefb.c: register_framebuffer failed\n");
 		DPRINTK("EXIT\n");
-		return -EINVAL;
+		goto out_unmap;
 	}
 
 	printk(KERN_INFO "fb%d: %s frame buffer device, using %ldK of video memory\n",
@@ -1809,6 +1809,21 @@ int __init virgefb_init(void)
 
 	DPRINTK("EXIT\n");
 	return 0;
+
+out_unmap:
+	if (board_addr >= 0x01000000) {
+		if (v_ram)
+			iounmap((void*)v_ram);
+		if (vgaio_regs)
+			iounmap(vgaio_regs);
+		if (mmio_regs)
+			iounmap(mmio_regs);
+		if (vcode_switch_base)
+			iounmap((void*)vcode_switch_base);
+		v_ram = vcode_switch_base = 0;
+		vgaio_regs = mmio_regs = NULL;
+	}
+	return -EINVAL;
 }
 
 
diff --git a/drivers/zorro/proc.c b/drivers/zorro/proc.c
index 7aa2d3de6d37..60b05bc15642 100644
--- a/drivers/zorro/proc.c
+++ b/drivers/zorro/proc.c
@@ -47,7 +47,7 @@ proc_bus_zorro_lseek(struct file *file, loff_t off, int whence)
 static ssize_t
 proc_bus_zorro_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos)
 {
-	struct inode *ino = file->f_dentry->d_inode;
+	struct inode *ino = file->f_path.dentry->d_inode;
 	struct proc_dir_entry *dp = PDE(ino);
 	struct zorro_dev *z = dp->data;
 	struct ConfigDev cd;