From ffd58d0027989ff6a0a25943d11f154f49af662b Mon Sep 17 00:00:00 2001 From: Steve French Date: Fri, 8 Dec 2006 04:14:28 +0000 Subject: [PATCH] --- yaml --- r: 43875 b: refs/heads/master c: 33ec32fae0e2c4433bfd1e74cbde6cb16604a719 h: refs/heads/master i: 43873: 421a30bc9588993c8dc998b930d7280489261345 43871: 367d2cfd21c3a5c9ce12618c778cd2b4cc53c75a v: v3 --- [refs] | 2 +- trunk/CREDITS | 8 - .../Documentation/ABI/testing/debugfs-pktcdvd | 20 - .../ABI/testing/sysfs-class-pktcdvd | 72 - trunk/Documentation/DocBook/kernel-api.tmpl | 8 - trunk/Documentation/cdrom/packet-writing.txt | 35 - .../Documentation/fault-injection/failcmd.sh | 4 - .../fault-injection/failmodule.sh | 31 - .../fault-injection/fault-injection.txt | 225 - trunk/Documentation/ioctl-number.txt | 2 - trunk/Documentation/kernel-parameters.txt | 7 - trunk/Documentation/s390/driver-model.txt | 7 - trunk/MAINTAINERS | 34 +- trunk/arch/alpha/Kconfig | 8 - trunk/arch/alpha/kernel/osf_sys.c | 2 +- trunk/arch/arm/Kconfig | 8 - trunk/arch/arm26/Kconfig | 8 - trunk/arch/avr32/Kconfig | 8 - trunk/arch/cris/Kconfig | 8 - .../arch/cris/arch-v32/drivers/sync_serial.c | 8 +- trunk/arch/frv/Kconfig | 8 - trunk/arch/frv/mm/elf-fdpic.c | 4 +- trunk/arch/h8300/Kconfig | 8 - trunk/arch/i386/Kconfig | 5 - trunk/arch/i386/Kconfig.cpu | 8 - trunk/arch/i386/kernel/cpuid.c | 4 +- trunk/arch/i386/kernel/module.c | 4 +- trunk/arch/i386/kernel/msr.c | 6 +- trunk/arch/i386/kernel/smpboot.c | 2 +- trunk/arch/i386/kernel/traps.c | 41 +- trunk/arch/i386/kernel/vmlinux.lds.S | 2 - trunk/arch/i386/mach-visws/setup.c | 3 - trunk/arch/ia64/Kconfig | 8 - trunk/arch/ia64/ia32/sys_ia32.c | 4 +- trunk/arch/ia64/kernel/perfmon.c | 10 +- trunk/arch/ia64/kernel/salinfo.c | 6 +- trunk/arch/m32r/Kconfig | 8 - trunk/arch/m32r/boot/compressed/m32r_sio.c | 7 +- trunk/arch/m32r/kernel/entry.S | 67 +- trunk/arch/m32r/kernel/io_opsput.c | 71 +- trunk/arch/m32r/kernel/setup_opsput.c | 17 +- trunk/arch/m32r/mm/fault.c | 4 +- trunk/arch/m68k/Kconfig | 8 - trunk/arch/m68knommu/Kconfig | 8 - trunk/arch/mips/Kconfig | 8 - trunk/arch/mips/kernel/irixelf.c | 2 +- trunk/arch/mips/kernel/rtlx.c | 6 +- trunk/arch/mips/kernel/sysirix.c | 10 +- trunk/arch/mips/kernel/vpe.c | 2 +- trunk/arch/mips/lasat/sysctl.c | 6 +- trunk/arch/mips/mm/ioremap.c | 96 +- trunk/arch/parisc/Kconfig | 8 - trunk/arch/parisc/hpux/sys_hpux.c | 2 +- trunk/arch/parisc/mm/ioremap.c | 111 +- trunk/arch/powerpc/Kconfig | 8 - trunk/arch/powerpc/kernel/proc_ppc64.c | 6 +- trunk/arch/powerpc/kernel/rtas_flash.c | 16 +- .../arch/powerpc/platforms/cell/spufs/inode.c | 4 +- .../powerpc/platforms/cell/spufs/syscalls.c | 2 +- trunk/arch/powerpc/platforms/iseries/mf.c | 2 +- .../powerpc/platforms/pseries/hvCall_inst.c | 2 +- .../arch/powerpc/platforms/pseries/scanlog.c | 2 +- trunk/arch/ppc/8xx_io/cs4218_tdm.c | 12 +- trunk/arch/ppc/Kconfig | 13 - trunk/arch/ppc/kernel/traps.c | 64 +- trunk/arch/s390/Kconfig | 22 +- trunk/arch/s390/defconfig | 1 + trunk/arch/s390/hypfs/inode.c | 4 +- trunk/arch/s390/kernel/debug.c | 4 +- trunk/arch/s390/kernel/setup.c | 55 +- trunk/arch/s390/lib/uaccess_pt.c | 5 +- trunk/arch/s390/mm/Makefile | 2 +- trunk/arch/s390/mm/extmem.c | 106 +- trunk/arch/s390/mm/init.c | 184 +- trunk/arch/s390/mm/ioremap.c | 84 +- trunk/arch/s390/mm/vmem.c | 381 - trunk/arch/sh/Kconfig | 8 - trunk/arch/sh/mm/ioremap.c | 90 +- trunk/arch/sh/oprofile/op_model_sh7750.c | 2 +- trunk/arch/sh64/Kconfig | 8 - trunk/arch/sh64/mm/ioremap.c | 100 +- trunk/arch/sparc/Kconfig | 8 - trunk/arch/sparc/kernel/sys_sunos.c | 6 +- trunk/arch/sparc64/Kconfig | 8 - trunk/arch/sparc64/kernel/binfmt_aout32.c | 4 +- trunk/arch/sparc64/kernel/sys_sunos32.c | 4 +- trunk/arch/sparc64/solaris/fs.c | 4 +- trunk/arch/sparc64/solaris/ioctl.c | 6 +- trunk/arch/sparc64/solaris/misc.c | 6 +- trunk/arch/sparc64/solaris/socksys.c | 14 +- trunk/arch/sparc64/solaris/timod.c | 10 +- trunk/arch/um/Kconfig | 5 - trunk/arch/um/drivers/line.c | 2 +- trunk/arch/um/include/line.h | 2 +- trunk/arch/um/kernel/exec.c | 7 +- trunk/arch/um/sys-i386/Makefile | 2 +- trunk/arch/um/sys-i386/bug.c | 20 - trunk/arch/um/sys-x86_64/Makefile | 2 +- trunk/arch/um/sys-x86_64/bug.c | 20 - trunk/arch/v850/Kconfig | 8 - trunk/arch/x86_64/Kconfig | 13 - trunk/arch/x86_64/ia32/ia32_aout.c | 8 +- trunk/arch/x86_64/kernel/module.c | 5 +- trunk/arch/x86_64/kernel/traps.c | 36 +- trunk/arch/x86_64/kernel/vmlinux.lds.S | 2 - trunk/arch/xtensa/Kconfig | 8 - trunk/block/genhd.c | 31 - trunk/block/ioctl.c | 6 +- trunk/block/ll_rw_blk.c | 40 - trunk/drivers/Kconfig | 2 - trunk/drivers/Makefile | 1 - trunk/drivers/atm/Kconfig | 1 - trunk/drivers/atm/ambassador.c | 17 +- trunk/drivers/block/Kconfig | 14 +- trunk/drivers/block/acsi_slm.c | 4 +- trunk/drivers/block/cciss.c | 2 +- trunk/drivers/block/loop.c | 4 +- trunk/drivers/block/nbd.c | 2 +- trunk/drivers/block/pktcdvd.c | 547 +- trunk/drivers/char/Kconfig | 15 - trunk/drivers/char/Makefile | 1 - trunk/drivers/char/amiserial.c | 6 +- trunk/drivers/char/cs5535_gpio.c | 4 +- trunk/drivers/char/cyclades.c | 7775 ++++++++--------- trunk/drivers/char/drm/drm_ioc32.c | 56 +- trunk/drivers/char/drm/i915_ioc32.c | 12 +- trunk/drivers/char/drm/mga_ioc32.c | 8 +- trunk/drivers/char/drm/r128_ioc32.c | 10 +- trunk/drivers/char/drm/radeon_ioc32.c | 20 +- trunk/drivers/char/dsp56k.c | 6 +- trunk/drivers/char/dtlk.c | 4 +- trunk/drivers/char/epca.c | 16 +- trunk/drivers/char/esp.c | 2 +- trunk/drivers/char/generic_serial.c | 4 +- trunk/drivers/char/hvcs.c | 6 +- trunk/drivers/char/hvsi.c | 2 - trunk/drivers/char/ip2/ip2main.c | 12 +- trunk/drivers/char/ipmi/ipmi_devintf.c | 4 +- trunk/drivers/char/isicom.c | 296 +- trunk/drivers/char/istallion.c | 1164 +-- trunk/drivers/char/keyboard.c | 2 +- trunk/drivers/char/lp.c | 4 +- trunk/drivers/char/mem.c | 4 +- trunk/drivers/char/moxa.c | 18 +- trunk/drivers/char/mxser.c | 32 +- trunk/drivers/char/mxser_new.c | 2804 ------ trunk/drivers/char/mxser_new.h | 450 - trunk/drivers/char/n_r3964.c | 4 +- trunk/drivers/char/n_tty.c | 2 +- trunk/drivers/char/nsc_gpio.c | 4 +- trunk/drivers/char/pcmcia/synclink_cs.c | 2 +- trunk/drivers/char/ppdev.c | 4 +- trunk/drivers/char/pty.c | 10 +- trunk/drivers/char/random.c | 2 +- trunk/drivers/char/raw.c | 2 +- trunk/drivers/char/riscom8.c | 4 +- trunk/drivers/char/rocket.c | 10 +- trunk/drivers/char/ser_a2232.c | 2 - trunk/drivers/char/serial167.c | 2 +- trunk/drivers/char/sonypi.c | 2 +- trunk/drivers/char/specialix.c | 9 +- trunk/drivers/char/stallion.c | 2150 +++-- trunk/drivers/char/sx.c | 2232 +++-- trunk/drivers/char/sx.h | 1 - trunk/drivers/char/synclink.c | 4 +- trunk/drivers/char/synclink_gt.c | 6 +- trunk/drivers/char/synclinkmp.c | 6 +- trunk/drivers/char/tb0219.c | 4 +- trunk/drivers/char/tipar.c | 4 +- trunk/drivers/char/tty_io.c | 396 +- trunk/drivers/char/tty_ioctl.c | 264 +- trunk/drivers/char/vc_screen.c | 6 +- trunk/drivers/char/viotape.c | 10 +- trunk/drivers/char/vme_scc.c | 2 - trunk/drivers/char/vr41xx_giu.c | 4 +- trunk/drivers/clocksource/acpi_pm.c | 36 - trunk/drivers/hid/Kconfig | 18 - trunk/drivers/hid/Makefile | 15 - trunk/drivers/hid/hid-core.c | 1003 --- trunk/drivers/i2c/i2c-dev.c | 4 +- trunk/drivers/ide/pci/alim15x3.c | 16 +- trunk/drivers/ide/pci/pdc202xx_new.c | 22 +- trunk/drivers/ide/pci/sis5513.c | 3 +- trunk/drivers/ide/pci/sl82c105.c | 31 +- trunk/drivers/ieee1394/ieee1394_core.h | 2 +- trunk/drivers/infiniband/core/uverbs_main.c | 6 +- .../infiniband/hw/ipath/ipath_file_ops.c | 4 +- trunk/drivers/infiniband/hw/ipath/ipath_fs.c | 10 +- .../infiniband/hw/mthca/mthca_provider.c | 4 +- trunk/drivers/infiniband/hw/mthca/mthca_qp.c | 4 +- trunk/drivers/infiniband/hw/mthca/mthca_srq.c | 4 +- .../drivers/infiniband/ulp/iser/iser_memory.c | 4 +- trunk/drivers/input/Makefile | 1 - trunk/drivers/input/ff-core.c | 4 +- trunk/drivers/input/ff-memless.c | 2 +- trunk/drivers/input/gameport/gameport.c | 19 +- trunk/drivers/input/gameport/lightning.c | 4 +- trunk/drivers/input/input.c | 25 +- trunk/drivers/input/joystick/adi.c | 10 +- trunk/drivers/input/joystick/amijoy.c | 6 +- trunk/drivers/input/joystick/analog.c | 10 +- trunk/drivers/input/joystick/cobra.c | 7 +- trunk/drivers/input/joystick/gf2k.c | 4 +- trunk/drivers/input/joystick/grip_mp.c | 13 +- trunk/drivers/input/joystick/guillemot.c | 4 +- .../input/joystick/iforce/iforce-main.c | 31 +- .../input/joystick/iforce/iforce-serio.c | 20 +- trunk/drivers/input/joystick/interact.c | 4 +- trunk/drivers/input/joystick/magellan.c | 17 +- trunk/drivers/input/joystick/spaceball.c | 17 +- trunk/drivers/input/joystick/spaceorb.c | 17 +- trunk/drivers/input/joystick/stinger.c | 17 +- trunk/drivers/input/joystick/twidjoy.c | 17 +- trunk/drivers/input/joystick/warrior.c | 17 +- trunk/drivers/input/keyboard/Kconfig | 11 - trunk/drivers/input/keyboard/Makefile | 1 - trunk/drivers/input/keyboard/aaed2000_kbd.c | 203 - trunk/drivers/input/keyboard/amikbd.c | 22 +- trunk/drivers/input/keyboard/atkbd.c | 162 +- trunk/drivers/input/keyboard/corgikbd.c | 17 +- trunk/drivers/input/keyboard/hil_kbd.c | 3 +- trunk/drivers/input/keyboard/lkkbd.c | 17 +- trunk/drivers/input/keyboard/locomokbd.c | 28 +- trunk/drivers/input/keyboard/maple_keyb.c | 160 + trunk/drivers/input/keyboard/newtonkbd.c | 17 +- trunk/drivers/input/keyboard/spitzkbd.c | 24 +- trunk/drivers/input/keyboard/stowaway.c | 3 +- trunk/drivers/input/keyboard/sunkbd.c | 23 +- trunk/drivers/input/keyboard/xtkbd.c | 17 +- trunk/drivers/input/mouse/amimouse.c | 11 +- trunk/drivers/input/mouse/hil_ptr.c | 3 +- trunk/drivers/input/mouse/inport.c | 23 +- trunk/drivers/input/mouse/lifebook.c | 82 +- trunk/drivers/input/mouse/logibm.c | 24 +- trunk/drivers/input/mouse/logips2pp.c | 11 +- trunk/drivers/input/mouse/pc110pad.c | 26 +- trunk/drivers/input/mouse/psmouse-base.c | 101 +- trunk/drivers/input/mouse/rpcmouse.c | 20 +- trunk/drivers/input/mouse/sermouse.c | 16 +- trunk/drivers/input/mouse/trackpoint.c | 12 +- trunk/drivers/input/mouse/vsxxxaa.c | 16 +- trunk/drivers/input/mousedev.c | 2 +- trunk/drivers/input/serio/i8042-x86ia64io.h | 7 - trunk/drivers/input/serio/i8042.c | 39 +- trunk/drivers/input/serio/serio.c | 147 +- trunk/drivers/input/serio/serio_raw.c | 3 +- trunk/drivers/input/touchscreen/Kconfig | 15 - trunk/drivers/input/touchscreen/Makefile | 1 - trunk/drivers/input/touchscreen/ads7846.c | 95 +- trunk/drivers/input/touchscreen/corgi_ts.c | 30 +- trunk/drivers/input/touchscreen/elo.c | 3 +- trunk/drivers/input/touchscreen/gunze.c | 17 +- .../input/touchscreen/h3600_ts_input.c | 3 +- .../input/touchscreen/hp680_ts_input.c | 29 +- trunk/drivers/input/touchscreen/mk712.c | 26 +- trunk/drivers/input/touchscreen/mtouch.c | 16 +- trunk/drivers/input/touchscreen/penmount.c | 3 +- trunk/drivers/input/touchscreen/touchright.c | 3 +- trunk/drivers/input/touchscreen/touchwin.c | 3 +- trunk/drivers/input/touchscreen/ucb1400_ts.c | 579 -- trunk/drivers/isdn/act2000/module.c | 3 +- trunk/drivers/isdn/capi/capi.c | 13 +- trunk/drivers/isdn/capi/capidrv.c | 9 +- trunk/drivers/isdn/gigaset/Kconfig | 1 - trunk/drivers/isdn/gigaset/asyncdata.c | 5 +- trunk/drivers/isdn/gigaset/common.c | 37 + trunk/drivers/isdn/gigaset/gigaset.h | 4 + trunk/drivers/isdn/gigaset/interface.c | 4 +- trunk/drivers/isdn/gigaset/isocdata.c | 5 +- trunk/drivers/isdn/hardware/avm/avm_cs.c | 3 +- trunk/drivers/isdn/hardware/avm/b1.c | 10 +- trunk/drivers/isdn/hardware/avm/t1isa.c | 1 - trunk/drivers/isdn/hardware/eicon/debug.c | 4 +- trunk/drivers/isdn/hardware/eicon/di.c | 8 +- trunk/drivers/isdn/hardware/eicon/divasmain.c | 2 +- trunk/drivers/isdn/hardware/eicon/io.c | 2 +- trunk/drivers/isdn/hardware/eicon/istream.c | 4 +- trunk/drivers/isdn/hardware/eicon/platform.h | 8 + trunk/drivers/isdn/hisax/Kconfig | 8 +- trunk/drivers/isdn/hisax/avma1_cs.c | 3 +- trunk/drivers/isdn/hisax/config.c | 21 +- trunk/drivers/isdn/hisax/diva.c | 4 - trunk/drivers/isdn/hisax/elsa_cs.c | 3 +- trunk/drivers/isdn/hisax/fsm.c | 4 +- trunk/drivers/isdn/hisax/hfc4s8s_l1.c | 3 +- trunk/drivers/isdn/hisax/hfc_pci.c | 10 +- trunk/drivers/isdn/hisax/hfc_usb.c | 3 +- trunk/drivers/isdn/hisax/hisax.h | 6 + trunk/drivers/isdn/hisax/hisax_fcpcipnp.c | 4 +- trunk/drivers/isdn/hisax/hisax_isac.c | 2 +- trunk/drivers/isdn/hisax/isdnhdlc.c | 25 + trunk/drivers/isdn/hisax/isdnhdlc.h | 2 + trunk/drivers/isdn/hisax/sedlbauer.c | 4 - trunk/drivers/isdn/hisax/sedlbauer_cs.c | 3 +- trunk/drivers/isdn/hisax/st5481_b.c | 3 +- trunk/drivers/isdn/hisax/st5481_d.c | 4 +- trunk/drivers/isdn/hisax/st5481_init.c | 4 +- trunk/drivers/isdn/hisax/teles_cs.c | 3 +- trunk/drivers/isdn/hysdn/hycapi.c | 3 +- trunk/drivers/isdn/hysdn/hysdn_boot.c | 3 +- trunk/drivers/isdn/hysdn/hysdn_init.c | 3 +- trunk/drivers/isdn/hysdn/hysdn_net.c | 3 +- trunk/drivers/isdn/hysdn/hysdn_proclog.c | 7 +- trunk/drivers/isdn/i4l/isdn_bsdcomp.c | 4 +- trunk/drivers/isdn/i4l/isdn_common.c | 15 +- trunk/drivers/isdn/i4l/isdn_net.c | 6 +- trunk/drivers/isdn/i4l/isdn_ppp.c | 21 +- trunk/drivers/isdn/i4l/isdn_tty.c | 2 +- trunk/drivers/isdn/i4l/isdn_v110.c | 3 +- trunk/drivers/isdn/icn/icn.c | 3 +- trunk/drivers/isdn/isdnloop/isdnloop.c | 3 +- trunk/drivers/isdn/pcbit/drv.c | 9 +- trunk/drivers/isdn/pcbit/layer2.c | 3 +- trunk/drivers/isdn/sc/init.c | 9 +- trunk/drivers/macintosh/Kconfig | 1 + trunk/drivers/macintosh/adbhid.c | 10 +- trunk/drivers/macintosh/mac_hid.c | 8 +- trunk/drivers/md/bitmap.c | 8 +- trunk/drivers/md/dm-bio-list.h | 14 - trunk/drivers/md/dm-crypt.c | 4 +- trunk/drivers/md/dm-emc.c | 10 +- trunk/drivers/md/dm-hw-handler.h | 2 +- trunk/drivers/md/dm-io.c | 15 +- trunk/drivers/md/dm-ioctl.c | 16 +- trunk/drivers/md/dm-linear.c | 4 +- trunk/drivers/md/dm-log.c | 24 +- trunk/drivers/md/dm-log.h | 10 +- trunk/drivers/md/dm-mpath.c | 52 +- trunk/drivers/md/dm-mpath.h | 4 +- trunk/drivers/md/dm-path-selector.h | 12 +- trunk/drivers/md/dm-raid1.c | 25 +- trunk/drivers/md/dm-round-robin.c | 12 +- trunk/drivers/md/dm-snap.c | 33 +- trunk/drivers/md/dm-stripe.c | 2 +- trunk/drivers/md/dm-zero.c | 2 +- trunk/drivers/md/dm.c | 130 +- trunk/drivers/md/dm.h | 19 - trunk/drivers/md/md.c | 12 +- trunk/drivers/media/video/compat_ioctl32.c | 2 +- trunk/drivers/media/video/videodev.c | 2 +- trunk/drivers/media/video/zoran_procfs.c | 4 +- trunk/drivers/mmc/au1xmmc.c | 2 +- trunk/drivers/mmc/pxamci.c | 4 +- trunk/drivers/mmc/tifm_sd.c | 2 +- trunk/drivers/net/irda/irtty-sir.c | 4 +- trunk/drivers/net/via-velocity.c | 2 +- trunk/drivers/net/wan/cosa.c | 4 +- trunk/drivers/net/wireless/strip.c | 2 +- trunk/drivers/oprofile/buffer_sync.c | 8 +- trunk/drivers/pci/proc.c | 8 +- trunk/drivers/pcmcia/pcmcia_ioctl.c | 6 +- trunk/drivers/pnp/isapnp/proc.c | 2 +- trunk/drivers/s390/block/dasd.c | 8 +- trunk/drivers/s390/block/dasd_3990_erp.c | 23 +- trunk/drivers/s390/block/dasd_devmap.c | 49 - trunk/drivers/s390/block/dasd_int.h | 4 + trunk/drivers/s390/block/dasd_ioctl.c | 2 +- trunk/drivers/s390/char/ctrlchar.c | 9 +- trunk/drivers/s390/char/fs3270.c | 16 +- trunk/drivers/s390/char/sclp_tty.c | 2 + trunk/drivers/s390/char/tape.h | 3 +- trunk/drivers/s390/char/tape_34xx.c | 23 +- trunk/drivers/s390/char/tape_3590.c | 7 +- trunk/drivers/s390/char/tape_block.c | 14 +- trunk/drivers/s390/char/tape_char.c | 8 +- trunk/drivers/s390/char/tape_core.c | 14 +- trunk/drivers/s390/char/tty3270.c | 2 +- trunk/drivers/s390/cio/chsc.c | 28 +- trunk/drivers/s390/cio/cio.c | 62 +- trunk/drivers/s390/cio/cio.h | 6 +- trunk/drivers/s390/cio/css.c | 69 +- trunk/drivers/s390/cio/css.h | 9 - trunk/drivers/s390/cio/device.c | 456 +- trunk/drivers/s390/cio/device.h | 6 +- trunk/drivers/s390/cio/device_fsm.c | 58 +- trunk/drivers/s390/cio/device_ops.c | 28 +- trunk/drivers/s390/cio/qdio.c | 234 +- trunk/drivers/s390/cio/qdio.h | 28 +- trunk/drivers/s390/crypto/ap_bus.c | 17 - trunk/drivers/sbus/char/bpp.c | 4 +- trunk/drivers/sbus/char/cpwatchdog.c | 2 +- trunk/drivers/sbus/char/display7seg.c | 2 +- trunk/drivers/sbus/char/openprom.c | 2 +- trunk/drivers/sbus/char/vfc_dev.c | 2 +- trunk/drivers/scsi/sd.c | 2 +- trunk/drivers/scsi/st.c | 2 +- trunk/drivers/serial/21285.c | 4 +- trunk/drivers/serial/68328serial.c | 2 +- trunk/drivers/serial/68360serial.c | 2 +- trunk/drivers/serial/8250.c | 4 +- trunk/drivers/serial/amba-pl010.c | 4 +- trunk/drivers/serial/amba-pl011.c | 4 +- trunk/drivers/serial/atmel_serial.c | 2 +- trunk/drivers/serial/clps711x.c | 4 +- trunk/drivers/serial/crisv10.c | 8 +- trunk/drivers/serial/crisv10.h | 4 +- trunk/drivers/serial/dz.c | 4 +- trunk/drivers/serial/icom.c | 4 +- trunk/drivers/serial/imx.c | 4 +- trunk/drivers/serial/ioc3_serial.c | 4 +- trunk/drivers/serial/ioc4_serial.c | 6 +- trunk/drivers/serial/ip22zilog.c | 4 +- trunk/drivers/serial/jsm/jsm_tty.c | 10 +- trunk/drivers/serial/m32r_sio.c | 2 +- trunk/drivers/serial/mcfserial.c | 2 +- trunk/drivers/serial/mpc52xx_uart.c | 4 +- trunk/drivers/serial/mpsc.c | 4 +- trunk/drivers/serial/mux.c | 4 +- trunk/drivers/serial/netx-serial.c | 4 +- trunk/drivers/serial/pmac_zilog.c | 10 +- trunk/drivers/serial/pmac_zilog.h | 2 +- trunk/drivers/serial/pxa.c | 4 +- trunk/drivers/serial/s3c2410.c | 4 +- trunk/drivers/serial/sa1100.c | 4 +- trunk/drivers/serial/serial_core.c | 21 +- trunk/drivers/serial/serial_lh7a40x.c | 4 +- trunk/drivers/serial/serial_txx9.c | 4 +- trunk/drivers/serial/sh-sci.c | 4 +- trunk/drivers/serial/sn_console.c | 4 +- trunk/drivers/serial/sunhv.c | 4 +- trunk/drivers/serial/sunsab.c | 4 +- trunk/drivers/serial/sunsu.c | 4 +- trunk/drivers/serial/sunzilog.c | 4 +- trunk/drivers/serial/uartlite.c | 4 +- trunk/drivers/serial/v850e_uart.c | 4 +- trunk/drivers/serial/vr41xx_siu.c | 4 +- trunk/drivers/tc/zs.c | 2 +- trunk/drivers/telephony/ixj.c | 10 +- trunk/drivers/usb/class/cdc-acm.c | 4 +- trunk/drivers/usb/core/inode.c | 4 +- trunk/drivers/usb/gadget/file_storage.c | 16 +- trunk/drivers/usb/gadget/serial.c | 4 +- trunk/drivers/usb/input/Kconfig | 21 +- trunk/drivers/usb/input/Makefile | 3 + trunk/drivers/usb/input/appletouch.c | 95 +- trunk/drivers/usb/input/hid-core.c | 1422 ++- .../linux => drivers/usb/input}/hid-debug.h | 0 trunk/drivers/usb/input/hid-ff.c | 8 +- trunk/drivers/{hid => usb/input}/hid-input.c | 153 +- trunk/drivers/usb/input/hid-lgff.c | 7 +- trunk/drivers/usb/input/hid-pidff.c | 58 +- trunk/drivers/usb/input/hid-tmff.c | 5 +- trunk/drivers/usb/input/hid-zpff.c | 7 +- .../linux => drivers/usb/input}/hid.h | 87 +- trunk/drivers/usb/input/hiddev.c | 37 +- trunk/drivers/usb/input/usbhid.h | 84 - trunk/drivers/usb/misc/sisusbvga/sisusb.c | 2 +- trunk/drivers/usb/serial/ark3116.c | 4 +- trunk/drivers/usb/serial/belkin_sa.c | 4 +- trunk/drivers/usb/serial/console.c | 2 +- trunk/drivers/usb/serial/cp2101.c | 4 +- trunk/drivers/usb/serial/cypress_m8.c | 10 +- trunk/drivers/usb/serial/digi_acceleport.c | 6 +- trunk/drivers/usb/serial/empeg.c | 4 +- trunk/drivers/usb/serial/ftdi_sio.c | 4 +- trunk/drivers/usb/serial/io_edgeport.c | 8 +- trunk/drivers/usb/serial/io_ti.c | 6 +- trunk/drivers/usb/serial/ir-usb.c | 4 +- trunk/drivers/usb/serial/keyspan.c | 2 +- trunk/drivers/usb/serial/keyspan.h | 2 +- trunk/drivers/usb/serial/keyspan_pda.c | 2 +- trunk/drivers/usb/serial/kl5kusb105.c | 6 +- trunk/drivers/usb/serial/kobil_sct.c | 10 +- trunk/drivers/usb/serial/mct_u232.c | 4 +- trunk/drivers/usb/serial/mos7720.c | 4 +- trunk/drivers/usb/serial/mos7840.c | 4 +- trunk/drivers/usb/serial/option.c | 4 +- trunk/drivers/usb/serial/pl2303.c | 4 +- trunk/drivers/usb/serial/sierra.c | 2 +- trunk/drivers/usb/serial/ti_usb_3410_5052.c | 4 +- trunk/drivers/usb/serial/usb-serial.c | 2 +- trunk/drivers/usb/serial/visor.c | 4 +- trunk/drivers/usb/serial/whiteheat.c | 6 +- trunk/drivers/video/Kconfig | 4 - trunk/drivers/video/S3triofb.c | 7 +- trunk/drivers/video/amifb.c | 8 +- trunk/drivers/video/arcfb.c | 2 +- trunk/drivers/video/atafb.c | 13 +- trunk/drivers/video/aty/aty128fb.c | 5 - trunk/drivers/video/aty/atyfb.h | 9 +- trunk/drivers/video/aty/atyfb_base.c | 193 +- trunk/drivers/video/aty/mach64_ct.c | 47 +- trunk/drivers/video/aty/radeon_monitor.c | 3 +- trunk/drivers/video/au1100fb.h | 2 +- trunk/drivers/video/backlight/backlight.c | 95 +- trunk/drivers/video/backlight/corgi_bl.c | 4 - trunk/drivers/video/backlight/hp680_bl.c | 4 - trunk/drivers/video/backlight/lcd.c | 80 +- trunk/drivers/video/backlight/locomolcd.c | 4 - trunk/drivers/video/cfbimgblt.c | 8 +- trunk/drivers/video/cirrusfb.c | 15 +- trunk/drivers/video/console/softcursor.c | 26 +- trunk/drivers/video/console/sticon.c | 2 +- trunk/drivers/video/console/vgacon.c | 30 +- trunk/drivers/video/cyberfb.c | 4 +- trunk/drivers/video/epson1355fb.c | 4 +- trunk/drivers/video/fbcmap.c | 55 +- trunk/drivers/video/fbcvt.c | 2 +- trunk/drivers/video/fbmem.c | 22 +- trunk/drivers/video/fbmon.c | 2 +- trunk/drivers/video/ffb.c | 4 - trunk/drivers/video/fm2fb.c | 1 - trunk/drivers/video/geode/Kconfig | 20 - trunk/drivers/video/geode/display_gx.c | 23 +- trunk/drivers/video/geode/display_gx.h | 7 +- trunk/drivers/video/geode/gxfb_core.c | 53 +- trunk/drivers/video/geode/video_gx.c | 107 +- trunk/drivers/video/geode/video_gx.h | 25 - trunk/drivers/video/hpfb.c | 2 - trunk/drivers/video/i810/i810-i2c.c | 4 +- trunk/drivers/video/igafb.c | 6 +- trunk/drivers/video/intelfb/intelfbdrv.c | 3 +- trunk/drivers/video/macfb.c | 20 - trunk/drivers/video/mbx/mbxdebugfs.c | 188 +- trunk/drivers/video/mbx/mbxfb.c | 359 +- trunk/drivers/video/mbx/reg_bits.h | 114 +- trunk/drivers/video/mbx/regs.h | 2 +- trunk/drivers/video/modedb.c | 6 +- trunk/drivers/video/neofb.c | 2 +- trunk/drivers/video/nvidia/nv_accel.c | 35 + trunk/drivers/video/nvidia/nv_i2c.c | 7 +- trunk/drivers/video/nvidia/nv_local.h | 11 +- trunk/drivers/video/nvidia/nv_of.c | 3 +- trunk/drivers/video/nvidia/nv_proto.h | 1 + trunk/drivers/video/offb.c | 3 - trunk/drivers/video/platinumfb.c | 3 - trunk/drivers/video/pmagb-b-fb.c | 2 +- trunk/drivers/video/pvr2fb.c | 18 - trunk/drivers/video/retz3fb.c | 4 +- trunk/drivers/video/riva/fbdev.c | 66 +- trunk/drivers/video/riva/riva_hw.c | 10 +- trunk/drivers/video/riva/riva_hw.h | 17 +- trunk/drivers/video/s3c2410fb.c | 213 +- trunk/drivers/video/savage/savagefb-i2c.c | 7 +- trunk/drivers/video/sis/init301.c | 7 +- trunk/drivers/video/stifb.c | 3 - trunk/drivers/video/tgafb.c | 58 +- trunk/drivers/video/tridentfb.c | 22 +- trunk/drivers/video/vesafb.c | 24 +- trunk/drivers/video/vga16fb.c | 28 +- trunk/drivers/video/virgefb.c | 17 +- trunk/drivers/zorro/proc.c | 2 +- trunk/fs/9p/vfs_addr.c | 2 +- trunk/fs/9p/vfs_dir.c | 4 +- trunk/fs/9p/vfs_file.c | 8 +- trunk/fs/Makefile | 3 +- trunk/fs/adfs/dir.c | 2 +- trunk/fs/affs/dir.c | 4 +- trunk/fs/afs/dir.c | 4 +- trunk/fs/afs/mntpt.c | 10 +- trunk/fs/autofs/root.c | 4 +- trunk/fs/autofs4/autofs_i.h | 3 +- trunk/fs/autofs4/root.c | 16 +- trunk/fs/befs/linuxvfs.c | 4 +- trunk/fs/bfs/dir.c | 2 +- trunk/fs/binfmt_aout.c | 8 +- trunk/fs/binfmt_elf.c | 6 +- trunk/fs/binfmt_elf_fdpic.c | 8 +- trunk/fs/binfmt_flat.c | 2 +- trunk/fs/binfmt_misc.c | 10 +- trunk/fs/block_dev.c | 204 +- trunk/fs/cifs/CHANGES | 3 +- trunk/fs/cifs/cifsencrypt.c | 4 +- trunk/fs/cifs/cifsfs.c | 4 +- trunk/fs/cifs/cifspdu.h | 8 +- trunk/fs/cifs/fcntl.c | 4 +- trunk/fs/cifs/file.c | 114 +- trunk/fs/cifs/readdir.c | 32 +- trunk/fs/coda/dir.c | 8 +- trunk/fs/coda/file.c | 14 +- trunk/fs/coda/inode.c | 2 +- trunk/fs/compat.c | 12 +- trunk/fs/compat_ioctl.c | 2 +- trunk/fs/configfs/dir.c | 10 +- trunk/fs/configfs/file.c | 12 +- trunk/fs/cramfs/inode.c | 2 +- trunk/fs/dnotify.c | 4 +- trunk/fs/dquot.c | 18 +- trunk/fs/ecryptfs/dentry.c | 3 +- trunk/fs/ecryptfs/ecryptfs_kernel.h | 16 +- trunk/fs/ecryptfs/file.c | 15 +- trunk/fs/ecryptfs/inode.c | 79 +- trunk/fs/ecryptfs/main.c | 5 +- trunk/fs/ecryptfs/mmap.c | 16 +- trunk/fs/efs/dir.c | 2 +- trunk/fs/eventpoll.c | 4 +- trunk/fs/exec.c | 15 +- trunk/fs/ext2/dir.c | 2 +- trunk/fs/ext2/ioctl.c | 2 +- trunk/fs/ext2/super.c | 6 +- trunk/fs/ext3/dir.c | 8 +- trunk/fs/ext3/file.c | 2 +- trunk/fs/ext3/ioctl.c | 2 +- trunk/fs/ext3/namei.c | 4 +- trunk/fs/ext3/super.c | 6 +- trunk/fs/ext4/dir.c | 8 +- trunk/fs/ext4/file.c | 2 +- trunk/fs/ext4/inode.c | 2 +- trunk/fs/ext4/ioctl.c | 2 +- trunk/fs/ext4/namei.c | 4 +- trunk/fs/fat/dir.c | 6 +- trunk/fs/fat/file.c | 2 +- trunk/fs/fcntl.c | 2 +- trunk/fs/file_table.c | 10 +- trunk/fs/freevxfs/vxfs_lookup.c | 2 +- trunk/fs/fuse/control.c | 2 +- trunk/fs/fuse/dir.c | 2 +- trunk/fs/fuse/file.c | 18 +- trunk/fs/gfs2/ops_file.c | 6 +- trunk/fs/hfs/dir.c | 2 +- trunk/fs/hfs/inode.c | 2 +- trunk/fs/hfsplus/dir.c | 2 +- trunk/fs/hfsplus/inode.c | 2 +- trunk/fs/hostfs/hostfs_kern.c | 6 +- trunk/fs/hpfs/dir.c | 4 +- trunk/fs/hpfs/file.c | 2 +- trunk/fs/hppfs/hppfs_kern.c | 12 +- trunk/fs/hugetlbfs/inode.c | 6 +- trunk/fs/inode.c | 2 +- trunk/fs/inotify_user.c | 6 +- trunk/fs/ioctl.c | 14 +- trunk/fs/isofs/compress.c | 2 +- trunk/fs/isofs/dir.c | 5 +- trunk/fs/jffs/inode-v23.c | 6 +- trunk/fs/jffs2/dir.c | 6 +- trunk/fs/jfs/jfs_dtree.c | 2 +- trunk/fs/libfs.c | 14 +- trunk/fs/lockd/clntlock.c | 2 +- trunk/fs/lockd/clntproc.c | 2 +- trunk/fs/lockd/svclock.c | 16 +- trunk/fs/lockd/svcsubs.c | 2 +- trunk/fs/locks.c | 32 +- trunk/fs/minix/dir.c | 2 +- trunk/fs/namei.c | 15 +- trunk/fs/namespace.c | 113 +- trunk/fs/ncpfs/dir.c | 8 +- trunk/fs/ncpfs/file.c | 4 +- trunk/fs/ncpfs/inode.c | 4 +- trunk/fs/ncpfs/ioctl.c | 8 +- trunk/fs/ncpfs/mmap.c | 4 +- trunk/fs/nfs/dir.c | 18 +- trunk/fs/nfs/direct.c | 10 +- trunk/fs/nfs/file.c | 14 +- trunk/fs/nfs/getroot.c | 2 +- trunk/fs/nfs/idmap.c | 2 +- trunk/fs/nfs/inode.c | 6 +- trunk/fs/nfs/nfs3proc.c | 2 +- trunk/fs/nfs/proc.c | 2 +- trunk/fs/nfs/write.c | 4 +- trunk/fs/nfsd/nfs2acl.c | 8 +- trunk/fs/nfsd/nfs3acl.c | 8 +- trunk/fs/nfsd/nfs4recover.c | 2 +- trunk/fs/nfsd/nfs4state.c | 10 +- trunk/fs/nfsd/nfscache.c | 3 +- trunk/fs/nfsd/nfsctl.c | 2 +- trunk/fs/nfsd/vfs.c | 53 +- trunk/fs/ntfs/dir.c | 6 +- trunk/fs/ntfs/file.c | 2 +- trunk/fs/ocfs2/aops.c | 4 +- trunk/fs/ocfs2/dir.c | 2 +- trunk/fs/ocfs2/dlm/dlmfs.c | 4 +- trunk/fs/ocfs2/file.c | 34 +- trunk/fs/open.c | 27 +- trunk/fs/openpromfs/inode.c | 2 +- trunk/fs/partitions/check.c | 27 - trunk/fs/pipe.c | 28 +- trunk/fs/pnode.c | 2 +- trunk/fs/pnode.h | 2 +- trunk/fs/proc/array.c | 18 +- trunk/fs/proc/base.c | 137 +- trunk/fs/proc/generic.c | 10 +- trunk/fs/proc/nommu.c | 4 +- trunk/fs/proc/proc_misc.c | 9 +- trunk/fs/proc/task_mmu.c | 8 +- trunk/fs/proc/task_nommu.c | 4 +- trunk/fs/qnx4/dir.c | 2 +- trunk/fs/ramfs/file-nommu.c | 2 +- trunk/fs/read_write.c | 20 +- trunk/fs/readdir.c | 2 +- trunk/fs/reiserfs/bitmap.c | 2 +- trunk/fs/reiserfs/dir.c | 4 +- trunk/fs/reiserfs/file.c | 4 +- trunk/fs/reiserfs/fix_node.c | 6 +- trunk/fs/reiserfs/inode.c | 12 +- trunk/fs/reiserfs/ioctl.c | 2 +- trunk/fs/reiserfs/namei.c | 6 +- trunk/fs/reiserfs/procfs.c | 2 +- trunk/fs/reiserfs/stree.c | 42 +- trunk/fs/reiserfs/super.c | 2 +- trunk/fs/reiserfs/tail_conversion.c | 4 +- trunk/fs/reiserfs/xattr.c | 10 +- trunk/fs/romfs/inode.c | 2 +- trunk/fs/seq_file.c | 2 +- trunk/fs/smbfs/cache.c | 2 +- trunk/fs/smbfs/dir.c | 6 +- trunk/fs/smbfs/file.c | 14 +- trunk/fs/smbfs/proc.c | 10 +- trunk/fs/smbfs/sock.c | 4 +- trunk/fs/splice.c | 18 +- trunk/fs/stack.c | 40 - trunk/fs/stat.c | 2 +- trunk/fs/super.c | 2 +- trunk/fs/sync.c | 4 +- trunk/fs/sysfs/bin.c | 14 +- trunk/fs/sysfs/dir.c | 10 +- trunk/fs/sysfs/file.c | 16 +- trunk/fs/sysv/dir.c | 2 +- trunk/fs/udf/dir.c | 4 +- trunk/fs/udf/file.c | 2 +- trunk/fs/ufs/dir.c | 2 +- trunk/fs/xattr.c | 8 +- trunk/fs/xfs/linux-2.6/xfs_file.c | 28 +- trunk/fs/xfs/linux-2.6/xfs_ioctl.c | 10 +- trunk/fs/xfs/linux-2.6/xfs_ioctl32.c | 2 +- trunk/fs/xfs/linux-2.6/xfs_lrw.c | 2 +- trunk/fs/xfs/xfs_dfrag.c | 4 +- trunk/include/asm-alpha/termbits.h | 13 - trunk/include/asm-arm/arch-s3c2410/fb.h | 3 - trunk/include/asm-arm/termbits.h | 12 - trunk/include/asm-arm26/termbits.h | 12 - trunk/include/asm-avr32/termbits.h | 11 - trunk/include/asm-cris/termbits.h | 11 - trunk/include/asm-frv/bitops.h | 44 - trunk/include/asm-frv/termbits.h | 11 - trunk/include/asm-generic/bug.h | 18 +- trunk/include/asm-generic/page.h | 38 +- trunk/include/asm-generic/termios.h | 4 +- trunk/include/asm-generic/vmlinux.lds.h | 8 - trunk/include/asm-h8300/termbits.h | 11 - trunk/include/asm-i386/bug.h | 28 +- trunk/include/asm-i386/ide.h | 4 +- trunk/include/asm-i386/termbits.h | 11 - trunk/include/asm-ia64/termbits.h | 11 - trunk/include/asm-m32r/ide.h | 3 +- trunk/include/asm-m32r/m32102.h | 7 +- trunk/include/asm-m32r/ptrace.h | 28 +- trunk/include/asm-m32r/sigcontext.h | 13 +- trunk/include/asm-m32r/termbits.h | 11 - trunk/include/asm-m68k/termbits.h | 11 - trunk/include/asm-mips/termbits.h | 11 - trunk/include/asm-parisc/termbits.h | 11 - trunk/include/asm-powerpc/bitops.h | 21 +- trunk/include/asm-powerpc/page_32.h | 10 +- trunk/include/asm-powerpc/termbits.h | 13 - trunk/include/asm-s390/dasd.h | 2 - trunk/include/asm-s390/page.h | 22 +- trunk/include/asm-s390/pgalloc.h | 3 - trunk/include/asm-s390/pgtable.h | 16 +- trunk/include/asm-s390/termbits.h | 11 - trunk/include/asm-sh/termbits.h | 11 - trunk/include/asm-sparc/termbits.h | 12 - trunk/include/asm-sparc64/termbits.h | 12 - trunk/include/asm-um/bug.h | 4 +- trunk/include/asm-v850/termbits.h | 11 - trunk/include/asm-x86_64/bug.h | 44 +- trunk/include/asm-x86_64/ioctls.h | 4 - trunk/include/asm-x86_64/termbits.h | 27 +- trunk/include/asm-x86_64/termios.h | 6 +- trunk/include/linux/bitrev.h | 15 - trunk/include/linux/bug.h | 47 - trunk/include/linux/crc32.h | 4 +- trunk/include/linux/device-mapper.h | 7 +- trunk/include/linux/dm-ioctl.h | 9 +- trunk/include/linux/fault-inject.h | 84 - trunk/include/linux/fb.h | 6 +- trunk/include/linux/fs.h | 27 +- trunk/include/linux/fs_stack.h | 31 - trunk/include/linux/fsnotify.h | 2 +- trunk/include/linux/generic_serial.h | 2 +- trunk/include/linux/genhd.h | 4 - trunk/include/linux/init_task.h | 16 +- trunk/include/linux/input.h | 18 +- trunk/include/linux/isdn.h | 8 +- trunk/include/linux/istallion.h | 36 +- trunk/include/linux/kernel.h | 15 +- trunk/include/linux/lockd/lockd.h | 2 +- trunk/include/linux/log2.h | 157 - trunk/include/linux/mnt_namespace.h | 42 - trunk/include/linux/module.h | 7 - trunk/include/linux/mount.h | 4 +- trunk/include/linux/mutex.h | 2 - trunk/include/linux/namei.h | 5 - trunk/include/linux/namespace.h | 42 + trunk/include/linux/nsproxy.h | 7 +- trunk/include/linux/pci_ids.h | 3 - trunk/include/linux/pid.h | 5 +- trunk/include/linux/pid_namespace.h | 45 - trunk/include/linux/pktcdvd.h | 25 - trunk/include/linux/pspace.h | 23 + trunk/include/linux/reiserfs_fs.h | 44 +- trunk/include/linux/sched.h | 27 +- trunk/include/linux/serial_core.h | 8 +- trunk/include/linux/serio.h | 12 +- trunk/include/linux/stallion.h | 52 +- trunk/include/linux/tty.h | 20 +- trunk/include/linux/tty_driver.h | 12 +- trunk/include/linux/tty_ldisc.h | 4 +- trunk/include/linux/usb/serial.h | 2 +- trunk/include/net/irda/ircomm_tty.h | 2 +- trunk/include/video/mbxfb.h | 31 - trunk/include/video/pm3fb.h | 24 +- trunk/init/Makefile | 1 - trunk/init/main.c | 9 +- trunk/init/version.c | 5 +- trunk/ipc/mqueue.c | 16 +- trunk/ipc/shm.c | 16 +- trunk/kernel/acct.c | 26 +- trunk/kernel/auditsc.c | 6 +- trunk/kernel/cpuset.c | 22 +- trunk/kernel/exit.c | 67 +- trunk/kernel/fork.c | 43 +- trunk/kernel/futex.c | 10 +- trunk/kernel/irq/proc.c | 3 +- trunk/kernel/kallsyms.c | 16 +- trunk/kernel/kmod.c | 2 +- trunk/kernel/mutex.c | 9 - trunk/kernel/nsproxy.c | 42 +- trunk/kernel/pid.c | 75 +- trunk/kernel/relay.c | 4 +- trunk/kernel/signal.c | 13 +- trunk/kernel/sys.c | 23 +- trunk/kernel/sysctl.c | 333 +- trunk/lib/Kconfig | 4 - trunk/lib/Kconfig.debug | 35 +- trunk/lib/Makefile | 4 - trunk/lib/bitrev.c | 54 - trunk/lib/bug.c | 163 - trunk/lib/crc32.c | 28 +- trunk/lib/fault-inject.c | 336 - trunk/mm/fadvise.c | 2 +- trunk/mm/filemap.c | 2 +- trunk/mm/filemap_xip.c | 2 +- trunk/mm/mempolicy.c | 2 +- trunk/mm/mmap.c | 10 +- trunk/mm/nommu.c | 12 +- trunk/mm/page_alloc.c | 93 +- trunk/mm/readahead.c | 2 +- trunk/mm/shmem.c | 20 +- trunk/mm/slab.c | 80 +- trunk/mm/swapfile.c | 4 +- trunk/mm/tiny-shmem.c | 4 +- trunk/net/atm/proc.c | 2 +- trunk/net/bluetooth/rfcomm/tty.c | 4 +- trunk/net/ipv4/netfilter/ipt_CLUSTERIP.c | 2 +- trunk/net/ipv4/netfilter/ipt_recent.c | 2 +- trunk/net/irda/ircomm/ircomm_tty_ioctl.c | 2 +- trunk/net/netlink/af_netlink.c | 2 +- trunk/net/socket.c | 16 +- trunk/net/sunrpc/auth_gss/auth_gss.c | 2 +- trunk/net/sunrpc/cache.c | 10 +- trunk/net/sunrpc/rpc_pipe.c | 8 +- trunk/net/unix/garbage.c | 2 +- trunk/scripts/kallsyms.c | 2 +- trunk/security/selinux/hooks.c | 31 +- trunk/security/selinux/selinuxfs.c | 8 +- trunk/sound/core/info.c | 2 +- trunk/sound/core/pcm_native.c | 2 +- trunk/sound/oss/dmasound/dmasound_core.c | 4 +- trunk/sound/oss/msnd_pinnacle.c | 4 +- trunk/sound/oss/soundcard.c | 8 +- trunk/sound/sound_firmware.c | 2 +- 861 files changed, 13742 insertions(+), 22464 deletions(-) delete mode 100644 trunk/Documentation/ABI/testing/debugfs-pktcdvd delete mode 100644 trunk/Documentation/ABI/testing/sysfs-class-pktcdvd delete mode 100644 trunk/Documentation/fault-injection/failcmd.sh delete mode 100644 trunk/Documentation/fault-injection/failmodule.sh delete mode 100644 trunk/Documentation/fault-injection/fault-injection.txt delete mode 100644 trunk/arch/s390/mm/vmem.c delete mode 100644 trunk/arch/um/sys-i386/bug.c delete mode 100644 trunk/arch/um/sys-x86_64/bug.c delete mode 100644 trunk/drivers/char/mxser_new.c delete mode 100644 trunk/drivers/char/mxser_new.h delete mode 100644 trunk/drivers/hid/Kconfig delete mode 100644 trunk/drivers/hid/Makefile delete mode 100644 trunk/drivers/hid/hid-core.c delete mode 100644 trunk/drivers/input/keyboard/aaed2000_kbd.c create mode 100644 trunk/drivers/input/keyboard/maple_keyb.c delete mode 100644 trunk/drivers/input/touchscreen/ucb1400_ts.c rename trunk/{include/linux => drivers/usb/input}/hid-debug.h (100%) rename trunk/drivers/{hid => usb/input}/hid-input.c (88%) rename trunk/{include/linux => drivers/usb/input}/hid.h (86%) delete mode 100644 trunk/drivers/usb/input/usbhid.h delete mode 100644 trunk/fs/stack.c delete mode 100644 trunk/include/linux/bitrev.h delete mode 100644 trunk/include/linux/bug.h delete mode 100644 trunk/include/linux/fault-inject.h delete mode 100644 trunk/include/linux/fs_stack.h delete mode 100644 trunk/include/linux/log2.h delete mode 100644 trunk/include/linux/mnt_namespace.h create mode 100644 trunk/include/linux/namespace.h delete mode 100644 trunk/include/linux/pid_namespace.h create mode 100644 trunk/include/linux/pspace.h delete mode 100644 trunk/lib/bitrev.c delete mode 100644 trunk/lib/bug.c delete mode 100644 trunk/lib/fault-inject.c diff --git a/[refs] b/[refs] index 0f3fe860137b..2b13a040b4ad 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 88032b322a38b37335c8cb2e3473a45c81d280eb +refs/heads/master: 33ec32fae0e2c4433bfd1e74cbde6cb16604a719 diff --git a/trunk/CREDITS b/trunk/CREDITS index 8218e790f43d..d0880082c19b 100644 --- a/trunk/CREDITS +++ b/trunk/CREDITS @@ -1808,14 +1808,6 @@ S: Kruislaan 419 S: 1098 VA Amsterdam S: The Netherlands -N: Jiri Kosina -E: jikos@jikos.cz -E: jkosina@suse.cz -D: Generic HID layer - original code split, fixes -D: Various ACPI fixes, keeping correct battery state through suspend -D: various lockdep annotations, autofs and other random bugfixes -S: Prague, Czech Republic - N: Gene Kozin E: 74604.152@compuserve.com W: http://www.sangoma.com diff --git a/trunk/Documentation/ABI/testing/debugfs-pktcdvd b/trunk/Documentation/ABI/testing/debugfs-pktcdvd deleted file mode 100644 index 03dbd883cc41..000000000000 --- a/trunk/Documentation/ABI/testing/debugfs-pktcdvd +++ /dev/null @@ -1,20 +0,0 @@ -What: /debug/pktcdvd/pktcdvd[0-7] -Date: Oct. 2006 -KernelVersion: 2.6.19 -Contact: Thomas Maier -Description: - -debugfs interface ------------------ - -The pktcdvd module (packet writing driver) creates -these files in debugfs: - -/debug/pktcdvd/pktcdvd[0-7]/ - info (0444) Lots of human readable driver - statistics and infos. Multiple lines! - -Example: -------- - -cat /debug/pktcdvd/pktcdvd0/info diff --git a/trunk/Documentation/ABI/testing/sysfs-class-pktcdvd b/trunk/Documentation/ABI/testing/sysfs-class-pktcdvd deleted file mode 100644 index c4c55edc9a5c..000000000000 --- a/trunk/Documentation/ABI/testing/sysfs-class-pktcdvd +++ /dev/null @@ -1,72 +0,0 @@ -What: /sys/class/pktcdvd/ -Date: Oct. 2006 -KernelVersion: 2.6.19 -Contact: Thomas Maier -Description: - -sysfs interface ---------------- - -The pktcdvd module (packet writing driver) creates -these files in the sysfs: -( is in format major:minor ) - -/sys/class/pktcdvd/ - add (0200) Write a block device id (major:minor) - to create a new pktcdvd device and map - it to the block device. - - remove (0200) Write the pktcdvd device id (major:minor) - to it to remove the pktcdvd device. - - device_map (0444) Shows the device mapping in format: - pktcdvd[0-7] - -/sys/class/pktcdvd/pktcdvd[0-7]/ - dev (0444) Device id - uevent (0200) To send an uevent. - -/sys/class/pktcdvd/pktcdvd[0-7]/stat/ - packets_started (0444) Number of started packets. - packets_finished (0444) Number of finished packets. - - kb_written (0444) kBytes written. - kb_read (0444) kBytes read. - kb_read_gather (0444) kBytes read to fill write packets. - - reset (0200) Write any value to it to reset - pktcdvd device statistic values, like - bytes read/written. - -/sys/class/pktcdvd/pktcdvd[0-7]/write_queue/ - size (0444) Contains the size of the bio write - queue. - - congestion_off (0644) If bio write queue size is below - this mark, accept new bio requests - from the block layer. - - congestion_on (0644) If bio write queue size is higher - as this mark, do no longer accept - bio write requests from the block - layer and wait till the pktcdvd - device has processed enough bio's - so that bio write queue size is - below congestion off mark. - A value of <= 0 disables congestion - control. - - -Example: --------- -To use the pktcdvd sysfs interface directly, you can do: - -# create a new pktcdvd device mapped to /dev/hdc -echo "22:0" >/sys/class/pktcdvd/add -cat /sys/class/pktcdvd/device_map -# assuming device pktcdvd0 was created, look at stat's -cat /sys/class/pktcdvd/pktcdvd0/stat/kb_written -# print the device id of the mapped block device -fgrep pktcdvd0 /sys/class/pktcdvd/device_map -# remove device, using pktcdvd0 device id 253:0 -echo "253:0" >/sys/class/pktcdvd/remove diff --git a/trunk/Documentation/DocBook/kernel-api.tmpl b/trunk/Documentation/DocBook/kernel-api.tmpl index 3fa0c4b4541e..ca094913c555 100644 --- a/trunk/Documentation/DocBook/kernel-api.tmpl +++ b/trunk/Documentation/DocBook/kernel-api.tmpl @@ -559,12 +559,4 @@ X!Idrivers/video/console/fonts.c --> - - - Input Subsystem -!Iinclude/linux/input.h -!Edrivers/input/input.c -!Edrivers/input/ff-core.c -!Edrivers/input/ff-memless.c - diff --git a/trunk/Documentation/cdrom/packet-writing.txt b/trunk/Documentation/cdrom/packet-writing.txt index 7715d2247c4d..3d44c561fe6d 100644 --- a/trunk/Documentation/cdrom/packet-writing.txt +++ b/trunk/Documentation/cdrom/packet-writing.txt @@ -90,41 +90,6 @@ Notes to create an ext2 filesystem on the disc. -Using the pktcdvd sysfs interface ---------------------------------- - -Since Linux 2.6.19, the pktcdvd module has a sysfs interface -and can be controlled by it. For example the "pktcdvd" tool uses -this interface. (see http://people.freenet.de/BalaGi#pktcdvd ) - -"pktcdvd" works similar to "pktsetup", e.g.: - - # pktcdvd -a dev_name /dev/hdc - # mkudffs /dev/pktcdvd/dev_name - # mount -t udf -o rw,noatime /dev/pktcdvd/dev_name /dvdram - # cp files /dvdram - # umount /dvdram - # pktcdvd -r dev_name - - -For a description of the sysfs interface look into the file: - - Documentation/ABI/testing/sysfs-block-pktcdvd - - -Using the pktcdvd debugfs interface ------------------------------------ - -To read pktcdvd device infos in human readable form, do: - - # cat /debug/pktcdvd/pktcdvd[0-7]/info - -For a description of the debugfs interface look into the file: - - Documentation/ABI/testing/debugfs-pktcdvd - - - Links ----- diff --git a/trunk/Documentation/fault-injection/failcmd.sh b/trunk/Documentation/fault-injection/failcmd.sh deleted file mode 100644 index 63177aba8106..000000000000 --- a/trunk/Documentation/fault-injection/failcmd.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/bash - -echo 1 > /proc/self/make-it-fail -exec $* diff --git a/trunk/Documentation/fault-injection/failmodule.sh b/trunk/Documentation/fault-injection/failmodule.sh deleted file mode 100644 index 474a8b971f9c..000000000000 --- a/trunk/Documentation/fault-injection/failmodule.sh +++ /dev/null @@ -1,31 +0,0 @@ -#!/bin/bash -# -# Usage: failmodule [stacktrace-depth] -# -# : "failslab", "fail_alloc_page", or "fail_make_request" -# -# : module name that you want to inject faults. -# -# [stacktrace-depth]: the maximum number of stacktrace walking allowed -# - -STACKTRACE_DEPTH=5 -if [ $# -gt 2 ]; then - STACKTRACE_DEPTH=$3 -fi - -if [ ! -d /debug/$1 ]; then - echo "Fault-injection $1 does not exist" >&2 - exit 1 -fi -if [ ! -d /sys/module/$2 ]; then - echo "Module $2 does not exist" >&2 - exit 1 -fi - -# Disable any fault injection -echo 0 > /debug/$1/stacktrace-depth - -echo `cat /sys/module/$2/sections/.text` > /debug/$1/require-start -echo `cat /sys/module/$2/sections/.exit.text` > /debug/$1/require-end -echo $STACKTRACE_DEPTH > /debug/$1/stacktrace-depth diff --git a/trunk/Documentation/fault-injection/fault-injection.txt b/trunk/Documentation/fault-injection/fault-injection.txt deleted file mode 100644 index b7ca560b9340..000000000000 --- a/trunk/Documentation/fault-injection/fault-injection.txt +++ /dev/null @@ -1,225 +0,0 @@ -Fault injection capabilities infrastructure -=========================================== - -See also drivers/md/faulty.c and "every_nth" module option for scsi_debug. - - -Available fault injection capabilities --------------------------------------- - -o failslab - - injects slab allocation failures. (kmalloc(), kmem_cache_alloc(), ...) - -o fail_page_alloc - - injects page allocation failures. (alloc_pages(), get_free_pages(), ...) - -o fail_make_request - - injects disk IO errors on devices permitted by setting - /sys/block//make-it-fail or - /sys/block///make-it-fail. (generic_make_request()) - -Configure fault-injection capabilities behavior ------------------------------------------------ - -o debugfs entries - -fault-inject-debugfs kernel module provides some debugfs entries for runtime -configuration of fault-injection capabilities. - -- /debug/fail*/probability: - - likelihood of failure injection, in percent. - Format: - - Note that one-failure-per-hundred is a very high error rate - for some testcases. Consider setting probability=100 and configure - /debug/fail*/interval for such testcases. - -- /debug/fail*/interval: - - specifies the interval between failures, for calls to - should_fail() that pass all the other tests. - - Note that if you enable this, by setting interval>1, you will - probably want to set probability=100. - -- /debug/fail*/times: - - specifies how many times failures may happen at most. - A value of -1 means "no limit". - -- /debug/fail*/space: - - specifies an initial resource "budget", decremented by "size" - on each call to should_fail(,size). Failure injection is - suppressed until "space" reaches zero. - -- /debug/fail*/verbose - - Format: { 0 | 1 | 2 } - specifies the verbosity of the messages when failure is - injected. '0' means no messages; '1' will print only a single - log line per failure; '2' will print a call trace too -- useful - to debug the problems revealed by fault injection. - -- /debug/fail*/task-filter: - - Format: { 'Y' | 'N' } - A value of 'N' disables filtering by process (default). - Any positive value limits failures to only processes indicated by - /proc//make-it-fail==1. - -- /debug/fail*/require-start: -- /debug/fail*/require-end: -- /debug/fail*/reject-start: -- /debug/fail*/reject-end: - - specifies the range of virtual addresses tested during - stacktrace walking. Failure is injected only if some caller - in the walked stacktrace lies within the required range, and - none lies within the rejected range. - Default required range is [0,ULONG_MAX) (whole of virtual address space). - Default rejected range is [0,0). - -- /debug/fail*/stacktrace-depth: - - specifies the maximum stacktrace depth walked during search - for a caller within [require-start,require-end) OR - [reject-start,reject-end). - -- /debug/fail_page_alloc/ignore-gfp-highmem: - - Format: { 'Y' | 'N' } - default is 'N', setting it to 'Y' won't inject failures into - highmem/user allocations. - -- /debug/failslab/ignore-gfp-wait: -- /debug/fail_page_alloc/ignore-gfp-wait: - - Format: { 'Y' | 'N' } - default is 'N', setting it to 'Y' will inject failures - only into non-sleep allocations (GFP_ATOMIC allocations). - -o Boot option - -In order to inject faults while debugfs is not available (early boot time), -use the boot option: - - failslab= - fail_page_alloc= - fail_make_request=,,, - -How to add new fault injection capability ------------------------------------------ - -o #include - -o define the fault attributes - - DECLARE_FAULT_INJECTION(name); - - Please see the definition of struct fault_attr in fault-inject.h - for details. - -o provide a way to configure fault attributes - -- boot option - - If you need to enable the fault injection capability from boot time, you can - provide boot option to configure it. There is a helper function for it: - - setup_fault_attr(attr, str); - -- debugfs entries - - failslab, fail_page_alloc, and fail_make_request use this way. - Helper functions: - - init_fault_attr_entries(entries, attr, name); - void cleanup_fault_attr_entries(entries); - -- module parameters - - If the scope of the fault injection capability is limited to a - single kernel module, it is better to provide module parameters to - configure the fault attributes. - -o add a hook to insert failures - - Upon should_fail() returning true, client code should inject a failure. - - should_fail(attr, size); - -Application Examples --------------------- - -o inject slab allocation failures into module init/cleanup code - ------------------------------------------------------------------------------- -#!/bin/bash - -FAILCMD=Documentation/fault-injection/failcmd.sh -BLACKLIST="root_plug evbug" - -FAILNAME=failslab -echo Y > /debug/$FAILNAME/task-filter -echo 10 > /debug/$FAILNAME/probability -echo 100 > /debug/$FAILNAME/interval -echo -1 > /debug/$FAILNAME/times -echo 2 > /debug/$FAILNAME/verbose -echo 1 > /debug/$FAILNAME/ignore-gfp-wait - -blacklist() -{ - echo $BLACKLIST | grep $1 > /dev/null 2>&1 -} - -oops() -{ - dmesg | grep BUG > /dev/null 2>&1 -} - -find /lib/modules/`uname -r` -name '*.ko' -exec basename {} .ko \; | - while read i - do - oops && exit 1 - - if ! blacklist $i - then - echo inserting $i... - bash $FAILCMD modprobe $i - fi - done - -lsmod | awk '{ if ($3 == 0) { print $1 } }' | - while read i - do - oops && exit 1 - - if ! blacklist $i - then - echo removing $i... - bash $FAILCMD modprobe -r $i - fi - done - ------------------------------------------------------------------------------- - -o inject slab allocation failures only for a specific module - ------------------------------------------------------------------------------- -#!/bin/bash - -FAILMOD=Documentation/fault-injection/failmodule.sh - -echo injecting errors into the module $1... - -modprobe $1 -bash $FAILMOD failslab $1 10 -echo 25 > /debug/failslab/probability - ------------------------------------------------------------------------------- - diff --git a/trunk/Documentation/ioctl-number.txt b/trunk/Documentation/ioctl-number.txt index 5a8bd5bd88ef..edc04d74ae23 100644 --- a/trunk/Documentation/ioctl-number.txt +++ b/trunk/Documentation/ioctl-number.txt @@ -191,5 +191,3 @@ Code Seq# Include File Comments 0xF3 00-3F video/sisfb.h sisfb (in development) -0xF4 00-1F video/mbxfb.h mbxfb - diff --git a/trunk/Documentation/kernel-parameters.txt b/trunk/Documentation/kernel-parameters.txt index d8323b8893c3..b79bcdf16319 100644 --- a/trunk/Documentation/kernel-parameters.txt +++ b/trunk/Documentation/kernel-parameters.txt @@ -548,13 +548,6 @@ and is between 256 and 4096 characters. It is defined in the file eurwdt= [HW,WDT] Eurotech CPU-1220/1410 onboard watchdog. Format: [,] - failslab= - fail_page_alloc= - fail_make_request=[KNL] - General fault injection mechanism. - Format: ,,, - See also /Documentation/fault-injection/. - fd_mcs= [HW,SCSI] See header of drivers/scsi/fd_mcs.c. diff --git a/trunk/Documentation/s390/driver-model.txt b/trunk/Documentation/s390/driver-model.txt index e938c442277d..77bf450ec39b 100644 --- a/trunk/Documentation/s390/driver-model.txt +++ b/trunk/Documentation/s390/driver-model.txt @@ -18,18 +18,11 @@ devices/ - 0.0.0002/ - 0.1.0000/0.1.1234/ ... - - defunct/ In this example, device 0815 is accessed via subchannel 0 in subchannel set 0, device 4711 via subchannel 1 in subchannel set 0, and subchannel 2 is a non-I/O subchannel. Device 1234 is accessed via subchannel 0 in subchannel set 1. -The subchannel named 'defunct' does not represent any real subchannel on the -system; it is a pseudo subchannel where disconnnected ccw devices are moved to -if they are displaced by another ccw device becoming operational on their -former subchannel. The ccw devices will be moved again to a proper subchannel -if they become operational again on that subchannel. - You should address a ccw device via its bus id (e.g. 0.0.4711); the device can be found under bus/ccw/devices/. diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS index dbf449ba240c..89ef018cc4bc 100644 --- a/trunk/MAINTAINERS +++ b/trunk/MAINTAINERS @@ -684,7 +684,7 @@ S: Supported CIRRUS LOGIC GENERIC FBDEV DRIVER P: Jeff Garzik M: jgarzik@pobox.com -L: linux-fbdev-devel@lists.sourceforge.net (subscribers-only) +L: linux-fbdev-devel@lists.sourceforge.net S: Odd Fixes CIRRUS LOGIC CS4280/CS461x SOUNDDRIVER @@ -791,7 +791,7 @@ S: Maintained CYBLAFB FRAMEBUFFER DRIVER P: Knut Petersen M: Knut_Petersen@t-online.de -L: linux-fbdev-devel@lists.sourceforge.net (subscribers-only) +L: linux-fbdev-devel@lists.sourceforge.net S: Maintained CYCLADES 2X SYNC CARD DRIVER @@ -1128,7 +1128,7 @@ S: Supported FRAMEBUFFER LAYER P: Antonino Daplas M: adaplas@pol.net -L: linux-fbdev-devel@lists.sourceforge.net (subscribers-only) +L: linux-fbdev-devel@lists.sourceforge.net W: http://linux-fbdev.sourceforge.net/ S: Maintained @@ -1479,7 +1479,7 @@ S: Maintained IMS TWINTURBO FRAMEBUFFER DRIVER P: Paul Mundt M: lethal@chaoticdreams.org -L: linux-fbdev-devel@lists.sourceforge.net (subscribers-only) +L: linux-fbdev-devel@lists.sourceforge.net S: Maintained INFINIBAND SUBSYSTEM @@ -1512,13 +1512,13 @@ S: Maintained INTEL FRAMEBUFFER DRIVER (excluding 810 and 815) P: Sylvain Meyer M: sylvain.meyer@worldonline.fr -L: linux-fbdev-devel@lists.sourceforge.net (subscribers-only) +L: linux-fbdev-devel@lists.sourceforge.net S: Maintained INTEL 810/815 FRAMEBUFFER DRIVER P: Antonino Daplas M: adaplas@pol.net -L: linux-fbdev-devel@lists.sourceforge.net (subscribers-only) +L: linux-fbdev-devel@lists.sourceforge.net S: Maintained INTEL APIC/IOAPIC, LOWLEVEL X86 SMP SUPPORT @@ -1964,7 +1964,7 @@ S: Odd Fixes for 2.4; Maintained for 2.6. MATROX FRAMEBUFFER DRIVER P: Petr Vandrovec M: vandrove@vc.cvut.cz -L: linux-fbdev-devel@lists.sourceforge.net (subscribers-only) +L: linux-fbdev-devel@lists.sourceforge.net S: Maintained MEGARAID SCSI DRIVERS @@ -2025,12 +2025,6 @@ M: rubini@ipvvis.unipv.it L: linux-kernel@vger.kernel.org S: Maintained -MOXA SMARTIO/INDUSTIO SERIAL CARD (MXSER 2.0) -P: Jiri Slaby -M: jirislaby@gmail.com -L: linux-kernel@vger.kernel.org -S: Maintained - MSI LAPTOP SUPPORT P: Lennart Poettering M: mzxreary@0pointer.de @@ -2056,12 +2050,6 @@ P: Andrew Veliath M: andrewtv@usa.net S: Maintained -MULTITECH MULTIPORT CARD (ISICOM) -P: Jiri Slaby -M: jirislaby@gmail.com -L: linux-kernel@vger.kernel.org -S: Maintained - NATSEMI ETHERNET DRIVER (DP8381x) P: Tim Hockin M: thockin@hockin.org @@ -2222,7 +2210,7 @@ S: Maintained NVIDIA (rivafb and nvidiafb) FRAMEBUFFER DRIVER P: Antonino Daplas M: adaplas@pol.net -L: linux-fbdev-devel@lists.sourceforge.net (subscribers-only) +L: linux-fbdev-devel@lists.sourceforge.net S: Maintained OPENCORES I2C BUS DRIVER @@ -2506,13 +2494,13 @@ S: Maintained RADEON FRAMEBUFFER DISPLAY DRIVER P: Benjamin Herrenschmidt M: benh@kernel.crashing.org -L: linux-fbdev-devel@lists.sourceforge.net (subscribers-only) +L: linux-fbdev-devel@lists.sourceforge.net S: Maintained RAGE128 FRAMEBUFFER DISPLAY DRIVER P: Paul Mackerras M: paulus@samba.org -L: linux-fbdev-devel@lists.sourceforge.net (subscribers-only) +L: linux-fbdev-devel@lists.sourceforge.net S: Maintained RAYLINK/WEBGEAR 802.11 WIRELESS LAN DRIVER @@ -2582,7 +2570,7 @@ S: Orphan S3 SAVAGE FRAMEBUFFER DRIVER P: Antonino Daplas M: adaplas@pol.net -L: linux-fbdev-devel@lists.sourceforge.net (subscribers-only) +L: linux-fbdev-devel@lists.sourceforge.net S: Maintained S390 diff --git a/trunk/arch/alpha/Kconfig b/trunk/arch/alpha/Kconfig index 84caf50725b5..7e55ea66c6d4 100644 --- a/trunk/arch/alpha/Kconfig +++ b/trunk/arch/alpha/Kconfig @@ -25,14 +25,6 @@ config RWSEM_XCHGADD_ALGORITHM bool default y -config ARCH_HAS_ILOG2_U32 - bool - default n - -config ARCH_HAS_ILOG2_U64 - bool - default n - config GENERIC_FIND_NEXT_BIT bool default y diff --git a/trunk/arch/alpha/kernel/osf_sys.c b/trunk/arch/alpha/kernel/osf_sys.c index fb804043b320..ad6173651995 100644 --- a/trunk/arch/alpha/kernel/osf_sys.c +++ b/trunk/arch/alpha/kernel/osf_sys.c @@ -277,7 +277,7 @@ osf_fstatfs(unsigned long fd, struct osf_statfs __user *buffer, unsigned long bu retval = -EBADF; file = fget(fd); if (file) { - retval = do_osf_statfs(file->f_path.dentry, buffer, bufsiz); + retval = do_osf_statfs(file->f_dentry, buffer, bufsiz); fput(file); } return retval; diff --git a/trunk/arch/arm/Kconfig b/trunk/arch/arm/Kconfig index aa1d400d721a..8c05d4321ae9 100644 --- a/trunk/arch/arm/Kconfig +++ b/trunk/arch/arm/Kconfig @@ -74,14 +74,6 @@ config RWSEM_GENERIC_SPINLOCK config RWSEM_XCHGADD_ALGORITHM bool -config ARCH_HAS_ILOG2_U32 - bool - default n - -config ARCH_HAS_ILOG2_U64 - bool - default n - config GENERIC_HWEIGHT bool default y diff --git a/trunk/arch/arm26/Kconfig b/trunk/arch/arm26/Kconfig index 74eba8b5a8ca..c14fe918bc4c 100644 --- a/trunk/arch/arm26/Kconfig +++ b/trunk/arch/arm26/Kconfig @@ -41,14 +41,6 @@ config RWSEM_GENERIC_SPINLOCK config RWSEM_XCHGADD_ALGORITHM bool -config ARCH_HAS_ILOG2_U32 - bool - default n - -config ARCH_HAS_ILOG2_U64 - bool - default n - config GENERIC_HWEIGHT bool default y diff --git a/trunk/arch/avr32/Kconfig b/trunk/arch/avr32/Kconfig index bb059a4e1df9..5f1694eea842 100644 --- a/trunk/arch/avr32/Kconfig +++ b/trunk/arch/avr32/Kconfig @@ -45,14 +45,6 @@ config GENERIC_TIME config RWSEM_XCHGADD_ALGORITHM bool -config ARCH_HAS_ILOG2_U32 - bool - default n - -config ARCH_HAS_ILOG2_U64 - bool - default n - config GENERIC_BUST_SPINLOCK bool diff --git a/trunk/arch/cris/Kconfig b/trunk/arch/cris/Kconfig index 3474309e049c..6a1238a29d6c 100644 --- a/trunk/arch/cris/Kconfig +++ b/trunk/arch/cris/Kconfig @@ -16,14 +16,6 @@ config RWSEM_GENERIC_SPINLOCK config RWSEM_XCHGADD_ALGORITHM bool -config ARCH_HAS_ILOG2_U32 - bool - default n - -config ARCH_HAS_ILOG2_U64 - bool - default n - config GENERIC_FIND_NEXT_BIT bool default y diff --git a/trunk/arch/cris/arch-v32/drivers/sync_serial.c b/trunk/arch/cris/arch-v32/drivers/sync_serial.c index 424eb0eb1cd5..e067806b2208 100644 --- a/trunk/arch/cris/arch-v32/drivers/sync_serial.c +++ b/trunk/arch/cris/arch-v32/drivers/sync_serial.c @@ -504,7 +504,7 @@ static int sync_serial_release(struct inode *inode, struct file *file) static unsigned int sync_serial_poll(struct file *file, poll_table *wait) { - int dev = iminor(file->f_path.dentry->d_inode); + int dev = iminor(file->f_dentry->d_inode); unsigned int mask = 0; sync_port* port; DEBUGPOLL( static unsigned int prev_mask = 0; ); @@ -531,7 +531,7 @@ static int sync_serial_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { int return_val = 0; - int dev = iminor(file->f_path.dentry->d_inode); + int dev = iminor(file->f_dentry->d_inode); sync_port* port; reg_sser_rw_tr_cfg tr_cfg; reg_sser_rw_rec_cfg rec_cfg; @@ -789,7 +789,7 @@ static int sync_serial_ioctl(struct inode *inode, struct file *file, static ssize_t sync_serial_write(struct file * file, const char * buf, size_t count, loff_t *ppos) { - int dev = iminor(file->f_path.dentry->d_inode); + int dev = iminor(file->f_dentry->d_inode); DECLARE_WAITQUEUE(wait, current); sync_port *port; unsigned long c, c1; @@ -919,7 +919,7 @@ static ssize_t sync_serial_write(struct file * file, const char * buf, static ssize_t sync_serial_read(struct file * file, char * buf, size_t count, loff_t *ppos) { - int dev = iminor(file->f_path.dentry->d_inode); + int dev = iminor(file->f_dentry->d_inode); int avail; sync_port *port; unsigned char* start; diff --git a/trunk/arch/frv/Kconfig b/trunk/arch/frv/Kconfig index 7561d7b72e75..cf1c446e003a 100644 --- a/trunk/arch/frv/Kconfig +++ b/trunk/arch/frv/Kconfig @@ -41,14 +41,6 @@ config TIME_LOW_RES bool default y -config ARCH_HAS_ILOG2_U32 - bool - default y - -config ARCH_HAS_ILOG2_U64 - bool - default y - mainmenu "Fujitsu FR-V Kernel Configuration" source "init/Kconfig" diff --git a/trunk/arch/frv/mm/elf-fdpic.c b/trunk/arch/frv/mm/elf-fdpic.c index 9477ccce070e..f5a653033fe0 100644 --- a/trunk/arch/frv/mm/elf-fdpic.c +++ b/trunk/arch/frv/mm/elf-fdpic.c @@ -110,14 +110,14 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsi #if 0 printk("[area] l=%lx (ENOMEM) f='%s'\n", - len, filp ? filp->f_path.dentry->d_name.name : ""); + len, filp ? filp->f_dentry->d_name.name : ""); #endif return -ENOMEM; success: #if 0 printk("[area] l=%lx ad=%lx f='%s'\n", - len, addr, filp ? filp->f_path.dentry->d_name.name : ""); + len, addr, filp ? filp->f_dentry->d_name.name : ""); #endif return addr; } /* end arch_get_unmapped_area() */ diff --git a/trunk/arch/h8300/Kconfig b/trunk/arch/h8300/Kconfig index 34a84bc4baf5..cabf0bfffc53 100644 --- a/trunk/arch/h8300/Kconfig +++ b/trunk/arch/h8300/Kconfig @@ -29,14 +29,6 @@ config RWSEM_XCHGADD_ALGORITHM bool default n -config ARCH_HAS_ILOG2_U32 - bool - default n - -config ARCH_HAS_ILOG2_U64 - bool - default n - config GENERIC_FIND_NEXT_BIT bool default y diff --git a/trunk/arch/i386/Kconfig b/trunk/arch/i386/Kconfig index c2362c7ba749..ea70359b02d0 100644 --- a/trunk/arch/i386/Kconfig +++ b/trunk/arch/i386/Kconfig @@ -49,11 +49,6 @@ config GENERIC_IOMAP bool default y -config GENERIC_BUG - bool - default y - depends on BUG - config GENERIC_HWEIGHT bool default y diff --git a/trunk/arch/i386/Kconfig.cpu b/trunk/arch/i386/Kconfig.cpu index 2aecfba4ac4f..821fd269ca58 100644 --- a/trunk/arch/i386/Kconfig.cpu +++ b/trunk/arch/i386/Kconfig.cpu @@ -248,14 +248,6 @@ config RWSEM_XCHGADD_ALGORITHM depends on !M386 default y -config ARCH_HAS_ILOG2_U32 - bool - default n - -config ARCH_HAS_ILOG2_U64 - bool - default n - config GENERIC_CALIBRATE_DELAY bool default y diff --git a/trunk/arch/i386/kernel/cpuid.c b/trunk/arch/i386/kernel/cpuid.c index 51130b39cd2e..db6dd20c3589 100644 --- a/trunk/arch/i386/kernel/cpuid.c +++ b/trunk/arch/i386/kernel/cpuid.c @@ -116,7 +116,7 @@ static ssize_t cpuid_read(struct file *file, char __user *buf, char __user *tmp = buf; u32 data[4]; u32 reg = *ppos; - int cpu = iminor(file->f_path.dentry->d_inode); + int cpu = iminor(file->f_dentry->d_inode); if (count % 16) return -EINVAL; /* Invalid chunk size */ @@ -134,7 +134,7 @@ static ssize_t cpuid_read(struct file *file, char __user *buf, static int cpuid_open(struct inode *inode, struct file *file) { - unsigned int cpu = iminor(file->f_path.dentry->d_inode); + unsigned int cpu = iminor(file->f_dentry->d_inode); struct cpuinfo_x86 *c = &(cpu_data)[cpu]; if (cpu >= NR_CPUS || !cpu_online(cpu)) diff --git a/trunk/arch/i386/kernel/module.c b/trunk/arch/i386/kernel/module.c index 3db0a5442eb1..d7d9c8b23f72 100644 --- a/trunk/arch/i386/kernel/module.c +++ b/trunk/arch/i386/kernel/module.c @@ -21,7 +21,6 @@ #include #include #include -#include #if 0 #define DEBUGP printk @@ -142,11 +141,10 @@ int module_finalize(const Elf_Ehdr *hdr, apply_paravirt(pseg, pseg + para->sh_size); } - return module_bug_finalize(hdr, sechdrs, me); + return 0; } void module_arch_cleanup(struct module *mod) { alternatives_smp_module_del(mod); - module_bug_cleanup(mod); } diff --git a/trunk/arch/i386/kernel/msr.c b/trunk/arch/i386/kernel/msr.c index 4a472a17d1c6..1d1a56cae340 100644 --- a/trunk/arch/i386/kernel/msr.c +++ b/trunk/arch/i386/kernel/msr.c @@ -172,7 +172,7 @@ static ssize_t msr_read(struct file *file, char __user * buf, u32 __user *tmp = (u32 __user *) buf; u32 data[2]; u32 reg = *ppos; - int cpu = iminor(file->f_path.dentry->d_inode); + int cpu = iminor(file->f_dentry->d_inode); int err; if (count % 8) @@ -196,7 +196,7 @@ static ssize_t msr_write(struct file *file, const char __user *buf, const u32 __user *tmp = (const u32 __user *)buf; u32 data[2]; u32 reg = *ppos; - int cpu = iminor(file->f_path.dentry->d_inode); + int cpu = iminor(file->f_dentry->d_inode); int err; if (count % 8) @@ -216,7 +216,7 @@ static ssize_t msr_write(struct file *file, const char __user *buf, static int msr_open(struct inode *inode, struct file *file) { - unsigned int cpu = iminor(file->f_path.dentry->d_inode); + unsigned int cpu = iminor(file->f_dentry->d_inode); struct cpuinfo_x86 *c = &(cpu_data)[cpu]; if (cpu >= NR_CPUS || !cpu_online(cpu)) diff --git a/trunk/arch/i386/kernel/smpboot.c b/trunk/arch/i386/kernel/smpboot.c index 1e00b03163b9..4bf0e3c83b8b 100644 --- a/trunk/arch/i386/kernel/smpboot.c +++ b/trunk/arch/i386/kernel/smpboot.c @@ -1118,7 +1118,7 @@ static int __cpuinit __smp_prepare_cpu(int cpu) /* init low mem mapping */ clone_pgd_range(swapper_pg_dir, swapper_pg_dir + USER_PGD_PTRS, - min_t(unsigned long, KERNEL_PGD_PTRS, USER_PGD_PTRS)); + KERNEL_PGD_PTRS); flush_tlb_all(); schedule_work(&info.task); wait_for_completion(&done); diff --git a/trunk/arch/i386/kernel/traps.c b/trunk/arch/i386/kernel/traps.c index 2b30dbf8d117..68de48e498ca 100644 --- a/trunk/arch/i386/kernel/traps.c +++ b/trunk/arch/i386/kernel/traps.c @@ -30,7 +30,6 @@ #include #include #include -#include #ifdef CONFIG_EISA #include @@ -421,22 +420,43 @@ void show_registers(struct pt_regs *regs) printk("\n"); } -int is_valid_bugaddr(unsigned long eip) +static void handle_BUG(struct pt_regs *regs) { + unsigned long eip = regs->eip; unsigned short ud2; if (eip < PAGE_OFFSET) - return 0; + return; if (probe_kernel_address((unsigned short *)eip, ud2)) - return 0; + return; + if (ud2 != 0x0b0f) + return; + + printk(KERN_EMERG "------------[ cut here ]------------\n"); + +#ifdef CONFIG_DEBUG_BUGVERBOSE + do { + unsigned short line; + char *file; + char c; + + if (probe_kernel_address((unsigned short *)(eip + 2), line)) + break; + if (probe_kernel_address((char **)(eip + 4), file) || + (unsigned long)file < PAGE_OFFSET || + probe_kernel_address(file, c)) + file = ""; - return ud2 == 0x0b0f; + printk(KERN_EMERG "kernel BUG at %s:%d!\n", file, line); + return; + } while (0); +#endif + printk(KERN_EMERG "Kernel BUG at [verbose debug info unavailable]\n"); } -/* - * This is gone through when something in the kernel has done something bad and - * is about to be terminated. - */ +/* This is gone through when something in the kernel + * has done something bad and is about to be terminated. +*/ void die(const char * str, struct pt_regs * regs, long err) { static struct { @@ -468,8 +488,7 @@ void die(const char * str, struct pt_regs * regs, long err) unsigned long esp; unsigned short ss; - report_bug(regs->eip); - + handle_BUG(regs); printk(KERN_EMERG "%s: %04lx [#%d]\n", str, err & 0xffff, ++die_counter); #ifdef CONFIG_PREEMPT printk(KERN_EMERG "PREEMPT "); diff --git a/trunk/arch/i386/kernel/vmlinux.lds.S b/trunk/arch/i386/kernel/vmlinux.lds.S index 16d3c7133ad7..56e6ad5cb045 100644 --- a/trunk/arch/i386/kernel/vmlinux.lds.S +++ b/trunk/arch/i386/kernel/vmlinux.lds.S @@ -57,8 +57,6 @@ SECTIONS RODATA - BUG_TABLE - . = ALIGN(4); .tracedata : AT(ADDR(.tracedata) - LOAD_OFFSET) { __tracedata_start = .; diff --git a/trunk/arch/i386/mach-visws/setup.c b/trunk/arch/i386/mach-visws/setup.c index 233ee20907b9..885c7cbfd478 100644 --- a/trunk/arch/i386/mach-visws/setup.c +++ b/trunk/arch/i386/mach-visws/setup.c @@ -6,7 +6,6 @@ #include #include #include -#include #include #include @@ -143,8 +142,6 @@ void __init time_init_hook(void) unsigned long sgivwfb_mem_phys; unsigned long sgivwfb_mem_size; -EXPORT_SYMBOL(sgivwfb_mem_phys); -EXPORT_SYMBOL(sgivwfb_mem_size); long long mem_size __initdata = 0; diff --git a/trunk/arch/ia64/Kconfig b/trunk/arch/ia64/Kconfig index fcacfe291b9b..75d839715b2f 100644 --- a/trunk/arch/ia64/Kconfig +++ b/trunk/arch/ia64/Kconfig @@ -34,14 +34,6 @@ config RWSEM_XCHGADD_ALGORITHM bool default y -config ARCH_HAS_ILOG2_U32 - bool - default n - -config ARCH_HAS_ILOG2_U64 - bool - default n - config GENERIC_FIND_NEXT_BIT bool default y diff --git a/trunk/arch/ia64/ia32/sys_ia32.c b/trunk/arch/ia64/ia32/sys_ia32.c index 957681c39ad9..a4a6e1463af8 100644 --- a/trunk/arch/ia64/ia32/sys_ia32.c +++ b/trunk/arch/ia64/ia32/sys_ia32.c @@ -235,7 +235,7 @@ mmap_subpage (struct file *file, unsigned long start, unsigned long end, int pro if (!(flags & MAP_ANONYMOUS)) { /* read the file contents */ - inode = file->f_path.dentry->d_inode; + inode = file->f_dentry->d_inode; if (!inode->i_fop || !file->f_op->read || ((*file->f_op->read)(file, (char __user *) start, end - start, &off) < 0)) { @@ -837,7 +837,7 @@ emulate_mmap (struct file *file, unsigned long start, unsigned long len, int pro if (!is_congruent) { /* read the file contents */ - inode = file->f_path.dentry->d_inode; + inode = file->f_dentry->d_inode; if (!inode->i_fop || !file->f_op->read || ((*file->f_op->read)(file, (char __user *) pstart, pend - pstart, &poff) < 0)) diff --git a/trunk/arch/ia64/kernel/perfmon.c b/trunk/arch/ia64/kernel/perfmon.c index aa94f60fa8e7..dbb28164b19b 100644 --- a/trunk/arch/ia64/kernel/perfmon.c +++ b/trunk/arch/ia64/kernel/perfmon.c @@ -2188,13 +2188,13 @@ pfm_alloc_fd(struct file **cfile) /* * allocate a new dcache entry */ - file->f_path.dentry = d_alloc(pfmfs_mnt->mnt_sb->s_root, &this); - if (!file->f_path.dentry) goto out; + file->f_dentry = d_alloc(pfmfs_mnt->mnt_sb->s_root, &this); + if (!file->f_dentry) goto out; - file->f_path.dentry->d_op = &pfmfs_dentry_operations; + file->f_dentry->d_op = &pfmfs_dentry_operations; - d_add(file->f_path.dentry, inode); - file->f_path.mnt = mntget(pfmfs_mnt); + d_add(file->f_dentry, inode); + file->f_vfsmnt = mntget(pfmfs_mnt); file->f_mapping = inode->i_mapping; file->f_op = &pfm_file_ops; diff --git a/trunk/arch/ia64/kernel/salinfo.c b/trunk/arch/ia64/kernel/salinfo.c index e375a2f0f2c3..fd607ca51a8d 100644 --- a/trunk/arch/ia64/kernel/salinfo.c +++ b/trunk/arch/ia64/kernel/salinfo.c @@ -302,7 +302,7 @@ salinfo_event_open(struct inode *inode, struct file *file) static ssize_t salinfo_event_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos) { - struct inode *inode = file->f_path.dentry->d_inode; + struct inode *inode = file->f_dentry->d_inode; struct proc_dir_entry *entry = PDE(inode); struct salinfo_data *data = entry->data; char cmd[32]; @@ -464,7 +464,7 @@ salinfo_log_new_read(int cpu, struct salinfo_data *data) static ssize_t salinfo_log_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos) { - struct inode *inode = file->f_path.dentry->d_inode; + struct inode *inode = file->f_dentry->d_inode; struct proc_dir_entry *entry = PDE(inode); struct salinfo_data *data = entry->data; u8 *buf; @@ -525,7 +525,7 @@ salinfo_log_clear(struct salinfo_data *data, int cpu) static ssize_t salinfo_log_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos) { - struct inode *inode = file->f_path.dentry->d_inode; + struct inode *inode = file->f_dentry->d_inode; struct proc_dir_entry *entry = PDE(inode); struct salinfo_data *data = entry->data; char cmd[32]; diff --git a/trunk/arch/m32r/Kconfig b/trunk/arch/m32r/Kconfig index f383dab973f5..41fd490af3b4 100644 --- a/trunk/arch/m32r/Kconfig +++ b/trunk/arch/m32r/Kconfig @@ -214,14 +214,6 @@ config RWSEM_XCHGADD_ALGORITHM bool default n -config ARCH_HAS_ILOG2_U32 - bool - default n - -config ARCH_HAS_ILOG2_U64 - bool - default n - config GENERIC_FIND_NEXT_BIT bool default y diff --git a/trunk/arch/m32r/boot/compressed/m32r_sio.c b/trunk/arch/m32r/boot/compressed/m32r_sio.c index ee3c8be12fa0..bce8af5e3bb2 100644 --- a/trunk/arch/m32r/boot/compressed/m32r_sio.c +++ b/trunk/arch/m32r/boot/compressed/m32r_sio.c @@ -2,7 +2,6 @@ * arch/m32r/boot/compressed/m32r_sio.c * * 2003-02-12: Takeo Takahashi - * 2006-11-30: OPSPUT support by Kazuhiro Inaoka * */ @@ -17,7 +16,7 @@ static int puts(const char *s) return 0; } -#if defined(CONFIG_PLAT_M32700UT_Alpha) || defined(CONFIG_PLAT_M32700UT) || defined(CONFIG_PLAT_OPSPUT) +#if defined(CONFIG_PLAT_M32700UT_Alpha) || defined(CONFIG_PLAT_M32700UT) #include #include @@ -32,11 +31,7 @@ static int puts(const char *s) #define BOOT_SIO0TXB (volatile unsigned short *)(0x02c00000 + 0x2000c) #else #undef PLD_BASE -#if defined(CONFIG_PLAT_OPSPUT) -#define PLD_BASE 0x1cc00000 -#else #define PLD_BASE 0xa4c00000 -#endif #define BOOT_SIO0STS PLD_ESIO0STS #define BOOT_SIO0TXB PLD_ESIO0TXB #endif diff --git a/trunk/arch/m32r/kernel/entry.S b/trunk/arch/m32r/kernel/entry.S index a2c472c0549f..ac6d840b382b 100644 --- a/trunk/arch/m32r/kernel/entry.S +++ b/trunk/arch/m32r/kernel/entry.S @@ -23,35 +23,35 @@ * updated in fork.c:copy_thread, signal.c:do_signal, * ptrace.c and ptrace.h * - * M32R/M32Rx/M32R2 - * @(sp) - r4 - * @(0x04,sp) - r5 - * @(0x08,sp) - r6 - * @(0x0c,sp) - *pt_regs - * @(0x10,sp) - r0 - * @(0x14,sp) - r1 - * @(0x18,sp) - r2 - * @(0x1c,sp) - r3 - * @(0x20,sp) - r7 - * @(0x24,sp) - r8 - * @(0x28,sp) - r9 - * @(0x2c,sp) - r10 - * @(0x30,sp) - r11 - * @(0x34,sp) - r12 - * @(0x38,sp) - syscall_nr - * @(0x3c,sp) - acc0h - * @(0x40,sp) - acc0l - * @(0x44,sp) - acc1h ; ISA_DSP_LEVEL2 only - * @(0x48,sp) - acc1l ; ISA_DSP_LEVEL2 only - * @(0x4c,sp) - psw - * @(0x50,sp) - bpc - * @(0x54,sp) - bbpsw - * @(0x58,sp) - bbpc - * @(0x5c,sp) - spu (cr3) - * @(0x60,sp) - fp (r13) - * @(0x64,sp) - lr (r14) - * @(0x68,sp) - spi (cr2) - * @(0x6c,sp) - orig_r0 + * M32Rx/M32R2 M32R + * @(sp) - r4 ditto + * @(0x04,sp) - r5 ditto + * @(0x08,sp) - r6 ditto + * @(0x0c,sp) - *pt_regs ditto + * @(0x10,sp) - r0 ditto + * @(0x14,sp) - r1 ditto + * @(0x18,sp) - r2 ditto + * @(0x1c,sp) - r3 ditto + * @(0x20,sp) - r7 ditto + * @(0x24,sp) - r8 ditto + * @(0x28,sp) - r9 ditto + * @(0x2c,sp) - r10 ditto + * @(0x30,sp) - r11 ditto + * @(0x34,sp) - r12 ditto + * @(0x38,sp) - syscall_nr ditto + * @(0x3c,sp) - acc0h @(0x3c,sp) - acch + * @(0x40,sp) - acc0l @(0x40,sp) - accl + * @(0x44,sp) - acc1h @(0x44,sp) - dummy_acc1h + * @(0x48,sp) - acc1l @(0x48,sp) - dummy_acc1l + * @(0x4c,sp) - psw ditto + * @(0x50,sp) - bpc ditto + * @(0x54,sp) - bbpsw ditto + * @(0x58,sp) - bbpc ditto + * @(0x5c,sp) - spu (cr3) ditto + * @(0x60,sp) - fp (r13) ditto + * @(0x64,sp) - lr (r14) ditto + * @(0x68,sp) - spi (cr2) ditto + * @(0x6c,sp) - orig_r0 ditto */ #include @@ -95,10 +95,17 @@ #define R11(reg) @(0x30,reg) #define R12(reg) @(0x34,reg) #define SYSCALL_NR(reg) @(0x38,reg) +#if defined(CONFIG_ISA_M32R2) && defined(CONFIG_ISA_DSP_LEVEL2) #define ACC0H(reg) @(0x3C,reg) #define ACC0L(reg) @(0x40,reg) #define ACC1H(reg) @(0x44,reg) #define ACC1L(reg) @(0x48,reg) +#elif defined(CONFIG_ISA_M32R2) || defined(CONFIG_ISA_M32R) +#define ACCH(reg) @(0x3C,reg) +#define ACCL(reg) @(0x40,reg) +#else +#error unknown isa configuration +#endif #define PSW(reg) @(0x4C,reg) #define BPC(reg) @(0x50,reg) #define BBPSW(reg) @(0x54,reg) @@ -596,6 +603,8 @@ ENTRY(ace_handler) beqz r1, inst oprand: ld r2, @(low(MDEVA_offset),r2) ; set address + srli r2, #12 + slli r2, #12 srli r1, #1 bra 1f inst: diff --git a/trunk/arch/m32r/kernel/io_opsput.c b/trunk/arch/m32r/kernel/io_opsput.c index 3cbb1f717e50..da6c5f5c1f82 100644 --- a/trunk/arch/m32r/kernel/io_opsput.c +++ b/trunk/arch/m32r/kernel/io_opsput.c @@ -30,34 +30,14 @@ extern void pcc_iowrite_byte(int, unsigned long, void *, size_t, size_t, int); extern void pcc_iowrite_word(int, unsigned long, void *, size_t, size_t, int); #endif /* CONFIG_PCMCIA && CONFIG_M32R_CFC */ -#define PORT2ADDR(port) _port2addr(port) -#define PORT2ADDR_USB(port) _port2addr_usb(port) +#define PORT2ADDR(port) _port2addr(port) +#define PORT2ADDR_USB(port) _port2addr_usb(port) static inline void *_port2addr(unsigned long port) { return (void *)(port | NONCACHE_OFFSET); } -#if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC) -static inline void *__port2addr_ata(unsigned long port) -{ - static int dummy_reg; - - switch (port) { - case 0x1f0: return (void *)(0x0c002000 | NONCACHE_OFFSET); - case 0x1f1: return (void *)(0x0c012800 | NONCACHE_OFFSET); - case 0x1f2: return (void *)(0x0c012002 | NONCACHE_OFFSET); - case 0x1f3: return (void *)(0x0c012802 | NONCACHE_OFFSET); - case 0x1f4: return (void *)(0x0c012004 | NONCACHE_OFFSET); - case 0x1f5: return (void *)(0x0c012804 | NONCACHE_OFFSET); - case 0x1f6: return (void *)(0x0c012006 | NONCACHE_OFFSET); - case 0x1f7: return (void *)(0x0c012806 | NONCACHE_OFFSET); - case 0x3f6: return (void *)(0x0c01200e | NONCACHE_OFFSET); - default: return (void *)&dummy_reg; - } -} -#endif - /* * OPSPUT-LAN is located in the extended bus space * from 0x10000000 to 0x13ffffff on physical address. @@ -117,12 +97,6 @@ unsigned char _inb(unsigned long port) { if (port >= LAN_IOSTART && port < LAN_IOEND) return _ne_inb(PORT2ADDR_NE(port)); - -#if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC) - else if ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) { - return *(volatile unsigned char *)__port2addr_ata(port); - } -#endif #if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_CFC) else if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) { unsigned char b; @@ -138,11 +112,6 @@ unsigned short _inw(unsigned long port) { if (port >= LAN_IOSTART && port < LAN_IOEND) return _ne_inw(PORT2ADDR_NE(port)); -#if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC) - else if ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) { - return *(volatile unsigned short *)__port2addr_ata(port); - } -#endif #if defined(CONFIG_USB) else if(port >= 0x340 && port < 0x3a0) return *(volatile unsigned short *)PORT2ADDR_USB(port); @@ -195,11 +164,6 @@ void _outb(unsigned char b, unsigned long port) if (port >= LAN_IOSTART && port < LAN_IOEND) _ne_outb(b, PORT2ADDR_NE(port)); else -#if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC) - if ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) { - *(volatile unsigned char *)__port2addr_ata(port) = b; - } else -#endif #if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_CFC) if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) { pcc_iowrite_byte(0, port, &b, sizeof(b), 1, 0); @@ -213,11 +177,6 @@ void _outw(unsigned short w, unsigned long port) if (port >= LAN_IOSTART && port < LAN_IOEND) _ne_outw(w, PORT2ADDR_NE(port)); else -#if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC) - if ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) { - *(volatile unsigned short *)__port2addr_ata(port) = w; - } else -#endif #if defined(CONFIG_USB) if(port >= 0x340 && port < 0x3a0) *(volatile unsigned short *)PORT2ADDR_USB(port) = w; @@ -263,14 +222,6 @@ void _insb(unsigned int port, void *addr, unsigned long count) { if (port >= LAN_IOSTART && port < LAN_IOEND) _ne_insb(PORT2ADDR_NE(port), addr, count); -#if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC) - else if ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) { - unsigned char *buf = addr; - unsigned char *portp = __port2addr_ata(port); - while (count--) - *buf++ = *(volatile unsigned char *)portp; - } -#endif #if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_CFC) else if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) { pcc_ioread_byte(0, port, (void *)addr, sizeof(unsigned char), @@ -302,12 +253,6 @@ void _insw(unsigned int port, void *addr, unsigned long count) } else if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) { pcc_ioread_word(9, port, (void *)addr, sizeof(unsigned short), count, 1); -#endif -#if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC) - } else if ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) { - portp = __port2addr_ata(port); - while (count--) - *buf++ = *(volatile unsigned short *)portp; #endif } else { portp = PORT2ADDR(port); @@ -335,12 +280,6 @@ void _outsb(unsigned int port, const void *addr, unsigned long count) portp = PORT2ADDR_NE(port); while (count--) _ne_outb(*buf++, portp); -#if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC) - } else if ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) { - portp = __port2addr_ata(port); - while (count--) - *(volatile unsigned char *)portp = *buf++; -#endif #if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_CFC) } else if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) { pcc_iowrite_byte(0, port, (void *)addr, sizeof(unsigned char), @@ -366,12 +305,6 @@ void _outsw(unsigned int port, const void *addr, unsigned long count) portp = PORT2ADDR_NE(port); while (count--) *(volatile unsigned short *)portp = *buf++; -#if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC) - } else if ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) { - portp = __port2addr_ata(port); - while (count--) - *(volatile unsigned short *)portp = *buf++; -#endif #if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_CFC) } else if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) { pcc_iowrite_word(9, port, (void *)addr, sizeof(unsigned short), diff --git a/trunk/arch/m32r/kernel/setup_opsput.c b/trunk/arch/m32r/kernel/setup_opsput.c index 62d6b71de45f..61d3b01cbe07 100644 --- a/trunk/arch/m32r/kernel/setup_opsput.c +++ b/trunk/arch/m32r/kernel/setup_opsput.c @@ -218,13 +218,13 @@ static void shutdown_opsput_lanpld_irq(unsigned int irq) static struct hw_interrupt_type opsput_lanpld_irq_type = { - .typename = "OPSPUT-PLD-LAN-IRQ", - .startup = startup_opsput_lanpld_irq, - .shutdown = shutdown_opsput_lanpld_irq, - .enable = enable_opsput_lanpld_irq, - .disable = disable_opsput_lanpld_irq, - .ack = mask_and_ack_opsput_lanpld, - .end = end_opsput_lanpld_irq + "OPSPUT-PLD-LAN-IRQ", + startup_opsput_lanpld_irq, + shutdown_opsput_lanpld_irq, + enable_opsput_lanpld_irq, + disable_opsput_lanpld_irq, + mask_and_ack_opsput_lanpld, + end_opsput_lanpld_irq }; /* @@ -374,6 +374,7 @@ void __init init_IRQ(void) disable_opsput_pld_irq(PLD_IRQ_SIO0_SND); #endif /* CONFIG_SERIAL_M32R_PLDSIO */ +#if defined(CONFIG_M32R_CFC) /* INT#1: CFC IREQ on PLD */ irq_desc[PLD_IRQ_CFIREQ].status = IRQ_DISABLED; irq_desc[PLD_IRQ_CFIREQ].chip = &opsput_pld_irq_type; @@ -397,6 +398,8 @@ void __init init_IRQ(void) irq_desc[PLD_IRQ_CFC_EJECT].depth = 1; /* disable nested irq */ pld_icu_data[irq2pldirq(PLD_IRQ_CFC_EJECT)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD02; /* 'H' edge sense */ disable_opsput_pld_irq(PLD_IRQ_CFC_EJECT); +#endif /* CONFIG_M32R_CFC */ + /* * INT0# is used for LAN, DIO diff --git a/trunk/arch/m32r/mm/fault.c b/trunk/arch/m32r/mm/fault.c index 9b9feb0f1610..8d5f551b5754 100644 --- a/trunk/arch/m32r/mm/fault.c +++ b/trunk/arch/m32r/mm/fault.c @@ -173,7 +173,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code, goto good_area; if (!(vma->vm_flags & VM_GROWSDOWN)) goto bad_area; - +#if 0 if (error_code & ACE_USERMODE) { /* * accessing the stack below "spu" is always a bug. @@ -184,7 +184,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code, if (address + 4 < regs->spu) goto bad_area; } - +#endif if (expand_stack(vma, address)) goto bad_area; /* diff --git a/trunk/arch/m68k/Kconfig b/trunk/arch/m68k/Kconfig index 70a577c89c7c..7bc14461a6ac 100644 --- a/trunk/arch/m68k/Kconfig +++ b/trunk/arch/m68k/Kconfig @@ -17,14 +17,6 @@ config RWSEM_GENERIC_SPINLOCK config RWSEM_XCHGADD_ALGORITHM bool -config ARCH_HAS_ILOG2_U32 - bool - default n - -config ARCH_HAS_ILOG2_U64 - bool - default n - config GENERIC_HWEIGHT bool default y diff --git a/trunk/arch/m68knommu/Kconfig b/trunk/arch/m68knommu/Kconfig index 25993c2a8fbb..aa70dde54228 100644 --- a/trunk/arch/m68knommu/Kconfig +++ b/trunk/arch/m68knommu/Kconfig @@ -25,14 +25,6 @@ config RWSEM_XCHGADD_ALGORITHM bool default n -config ARCH_HAS_ILOG2_U32 - bool - default n - -config ARCH_HAS_ILOG2_U64 - bool - default n - config GENERIC_FIND_NEXT_BIT bool default y diff --git a/trunk/arch/mips/Kconfig b/trunk/arch/mips/Kconfig index 57af8d8cf46f..d8af858fe3f5 100644 --- a/trunk/arch/mips/Kconfig +++ b/trunk/arch/mips/Kconfig @@ -819,14 +819,6 @@ config RWSEM_GENERIC_SPINLOCK config RWSEM_XCHGADD_ALGORITHM bool -config ARCH_HAS_ILOG2_U32 - bool - default n - -config ARCH_HAS_ILOG2_U64 - bool - default n - config GENERIC_FIND_NEXT_BIT bool default y diff --git a/trunk/arch/mips/kernel/irixelf.c b/trunk/arch/mips/kernel/irixelf.c index 37cad5de515c..1bbefbf43373 100644 --- a/trunk/arch/mips/kernel/irixelf.c +++ b/trunk/arch/mips/kernel/irixelf.c @@ -1145,7 +1145,7 @@ static int irix_core_dump(long signr, struct pt_regs * regs, struct file *file) psinfo.pr_pid = prstatus.pr_pid = current->pid; psinfo.pr_ppid = prstatus.pr_ppid = current->parent->pid; psinfo.pr_pgrp = prstatus.pr_pgrp = process_group(current); - psinfo.pr_sid = prstatus.pr_sid = process_session(current); + psinfo.pr_sid = prstatus.pr_sid = current->signal->session; if (current->pid == current->tgid) { /* * This is the record for the group leader. Add in the diff --git a/trunk/arch/mips/kernel/rtlx.c b/trunk/arch/mips/kernel/rtlx.c index 5a99e3e0c96d..8c8c8324f775 100644 --- a/trunk/arch/mips/kernel/rtlx.c +++ b/trunk/arch/mips/kernel/rtlx.c @@ -415,7 +415,7 @@ static unsigned int file_poll(struct file *file, poll_table * wait) int minor; unsigned int mask = 0; - minor = iminor(file->f_path.dentry->d_inode); + minor = iminor(file->f_dentry->d_inode); poll_wait(file, &channel_wqs[minor].rt_queue, wait); poll_wait(file, &channel_wqs[minor].lx_queue, wait); @@ -437,7 +437,7 @@ static unsigned int file_poll(struct file *file, poll_table * wait) static ssize_t file_read(struct file *file, char __user * buffer, size_t count, loff_t * ppos) { - int minor = iminor(file->f_path.dentry->d_inode); + int minor = iminor(file->f_dentry->d_inode); /* data available? */ if (!rtlx_read_poll(minor, (file->f_flags & O_NONBLOCK) ? 0 : 1)) { @@ -454,7 +454,7 @@ static ssize_t file_write(struct file *file, const char __user * buffer, struct rtlx_channel *rt; DECLARE_WAITQUEUE(wait, current); - minor = iminor(file->f_path.dentry->d_inode); + minor = iminor(file->f_dentry->d_inode); rt = &rtlx->channel[minor]; /* any space left... */ diff --git a/trunk/arch/mips/kernel/sysirix.c b/trunk/arch/mips/kernel/sysirix.c index 6c2406a93f2b..93c74fefff76 100644 --- a/trunk/arch/mips/kernel/sysirix.c +++ b/trunk/arch/mips/kernel/sysirix.c @@ -732,7 +732,7 @@ asmlinkage int irix_fstatfs(unsigned int fd, struct irix_statfs __user *buf) goto out; } - error = vfs_statfs(file->f_path.dentry, &kbuf); + error = vfs_statfs(file->f_dentry, &kbuf); if (error) goto out_f; @@ -1041,7 +1041,7 @@ asmlinkage unsigned long irix_mmap32(unsigned long addr, size_t len, int prot, unsigned long old_pos; long max_size = offset + len; - if (max_size > file->f_path.dentry->d_inode->i_size) { + if (max_size > file->f_dentry->d_inode->i_size) { old_pos = sys_lseek (fd, max_size - 1, 0); sys_write (fd, (void __user *) "", 1); sys_lseek (fd, old_pos, 0); @@ -1406,7 +1406,7 @@ asmlinkage int irix_fstatvfs(int fd, struct irix_statvfs __user *buf) error = -EBADF; goto out; } - error = vfs_statfs(file->f_path.dentry, &kbuf); + error = vfs_statfs(file->f_dentry, &kbuf); if (error) goto out_f; @@ -1526,7 +1526,7 @@ asmlinkage int irix_mmap64(struct pt_regs *regs) unsigned long old_pos; long max_size = off2 + len; - if (max_size > file->f_path.dentry->d_inode->i_size) { + if (max_size > file->f_dentry->d_inode->i_size) { old_pos = sys_lseek (fd, max_size - 1, 0); sys_write (fd, (void __user *) "", 1); sys_lseek (fd, old_pos, 0); @@ -1658,7 +1658,7 @@ asmlinkage int irix_fstatvfs64(int fd, struct irix_statvfs __user *buf) error = -EBADF; goto out; } - error = vfs_statfs(file->f_path.dentry, &kbuf); + error = vfs_statfs(file->f_dentry, &kbuf); if (error) goto out_f; diff --git a/trunk/arch/mips/kernel/vpe.c b/trunk/arch/mips/kernel/vpe.c index 666bef484dcb..51ddd2166898 100644 --- a/trunk/arch/mips/kernel/vpe.c +++ b/trunk/arch/mips/kernel/vpe.c @@ -1179,7 +1179,7 @@ static ssize_t vpe_write(struct file *file, const char __user * buffer, size_t ret = count; struct vpe *v; - minor = iminor(file->f_path.dentry->d_inode); + minor = iminor(file->f_dentry->d_inode); if ((v = get_vpe(minor)) == NULL) return -ENODEV; diff --git a/trunk/arch/mips/lasat/sysctl.c b/trunk/arch/mips/lasat/sysctl.c index da35d4555491..6dd7ae1b7c25 100644 --- a/trunk/arch/mips/lasat/sysctl.c +++ b/trunk/arch/mips/lasat/sysctl.c @@ -286,11 +286,11 @@ int proc_lasat_eeprom_value(ctl_table *table, int write, struct file *filp, mutex_unlock(&lasat_info_mutex); return r; } - if (filp && filp->f_path.dentry) + if (filp && filp->f_dentry) { - if (!strcmp(filp->f_path.dentry->d_name.name, "prid")) + if (!strcmp(filp->f_dentry->d_name.name, "prid")) lasat_board_info.li_eeprom_info.prid = lasat_board_info.li_prid; - if (!strcmp(filp->f_path.dentry->d_name.name, "debugaccess")) + if (!strcmp(filp->f_dentry->d_name.name, "debugaccess")) lasat_board_info.li_eeprom_info.debugaccess = lasat_board_info.li_debugaccess; } lasat_write_eeprom_info(); diff --git a/trunk/arch/mips/mm/ioremap.c b/trunk/arch/mips/mm/ioremap.c index fc2c96f0a1fd..cea7d0ea36e4 100644 --- a/trunk/arch/mips/mm/ioremap.c +++ b/trunk/arch/mips/mm/ioremap.c @@ -6,13 +6,98 @@ * (C) Copyright 1995 1996 Linus Torvalds * (C) Copyright 2001, 2002 Ralf Baechle */ -#include #include #include #include #include -#include +#include +#include +#include + +static inline void remap_area_pte(pte_t * pte, unsigned long address, + phys_t size, phys_t phys_addr, unsigned long flags) +{ + phys_t end; + unsigned long pfn; + pgprot_t pgprot = __pgprot(_PAGE_GLOBAL | _PAGE_PRESENT | __READABLE + | __WRITEABLE | flags); + + address &= ~PMD_MASK; + end = address + size; + if (end > PMD_SIZE) + end = PMD_SIZE; + if (address >= end) + BUG(); + pfn = phys_addr >> PAGE_SHIFT; + do { + if (!pte_none(*pte)) { + printk("remap_area_pte: page already exists\n"); + BUG(); + } + set_pte(pte, pfn_pte(pfn, pgprot)); + address += PAGE_SIZE; + pfn++; + pte++; + } while (address && (address < end)); +} + +static inline int remap_area_pmd(pmd_t * pmd, unsigned long address, + phys_t size, phys_t phys_addr, unsigned long flags) +{ + phys_t end; + + address &= ~PGDIR_MASK; + end = address + size; + if (end > PGDIR_SIZE) + end = PGDIR_SIZE; + phys_addr -= address; + if (address >= end) + BUG(); + do { + pte_t * pte = pte_alloc_kernel(pmd, address); + if (!pte) + return -ENOMEM; + remap_area_pte(pte, address, end - address, address + phys_addr, flags); + address = (address + PMD_SIZE) & PMD_MASK; + pmd++; + } while (address && (address < end)); + return 0; +} + +static int remap_area_pages(unsigned long address, phys_t phys_addr, + phys_t size, unsigned long flags) +{ + int error; + pgd_t * dir; + unsigned long end = address + size; + + phys_addr -= address; + dir = pgd_offset(&init_mm, address); + flush_cache_all(); + if (address >= end) + BUG(); + do { + pud_t *pud; + pmd_t *pmd; + + error = -ENOMEM; + pud = pud_alloc(&init_mm, dir, address); + if (!pud) + break; + pmd = pmd_alloc(&init_mm, pud, address); + if (!pmd) + break; + if (remap_area_pmd(pmd, address, end - address, + phys_addr + address, flags)) + break; + error = 0; + address = (address + PGDIR_SIZE) & PGDIR_MASK; + dir++; + } while (address && (address < end)); + flush_tlb_all(); + return error; +} /* * Generic mapping function (not visible outside): @@ -36,7 +121,6 @@ void __iomem * __ioremap(phys_t phys_addr, phys_t size, unsigned long flags) unsigned long offset; phys_t last_addr; void * addr; - pgprot_t pgprot; phys_addr = fixup_bigphys_addr(phys_addr, size); @@ -68,9 +152,6 @@ void __iomem * __ioremap(phys_t phys_addr, phys_t size, unsigned long flags) return NULL; } - pgprot = __pgprot(_PAGE_GLOBAL | _PAGE_PRESENT | __READABLE - | __WRITEABLE | flags); - /* * Mappings have to be page-aligned */ @@ -85,8 +166,7 @@ void __iomem * __ioremap(phys_t phys_addr, phys_t size, unsigned long flags) if (!area) return NULL; addr = area->addr; - if (ioremap_page_range((unsigned long)addr, (unsigned long)addr + size, - phys_addr, pgprot)) { + if (remap_area_pages((unsigned long) addr, phys_addr, size, flags)) { vunmap(addr); return NULL; } diff --git a/trunk/arch/parisc/Kconfig b/trunk/arch/parisc/Kconfig index 0f9ff618c6d7..d2101237442e 100644 --- a/trunk/arch/parisc/Kconfig +++ b/trunk/arch/parisc/Kconfig @@ -25,14 +25,6 @@ config RWSEM_GENERIC_SPINLOCK config RWSEM_XCHGADD_ALGORITHM bool -config ARCH_HAS_ILOG2_U32 - bool - default n - -config ARCH_HAS_ILOG2_U64 - bool - default n - config GENERIC_FIND_NEXT_BIT bool default y diff --git a/trunk/arch/parisc/hpux/sys_hpux.c b/trunk/arch/parisc/hpux/sys_hpux.c index d88309209f56..2e2dc4f2c853 100644 --- a/trunk/arch/parisc/hpux/sys_hpux.c +++ b/trunk/arch/parisc/hpux/sys_hpux.c @@ -237,7 +237,7 @@ asmlinkage long hpux_fstatfs(unsigned int fd, struct hpux_statfs __user * buf) file = fget(fd); if (!file) goto out; - error = vfs_statfs_hpux(file->f_path.dentry, &tmp); + error = vfs_statfs_hpux(file->f_dentry, &tmp); if (!error && copy_to_user(buf, &tmp, sizeof(tmp))) error = -EFAULT; fput(file); diff --git a/trunk/arch/parisc/mm/ioremap.c b/trunk/arch/parisc/mm/ioremap.c index 44b42c7f639d..47a1d2ac9419 100644 --- a/trunk/arch/parisc/mm/ioremap.c +++ b/trunk/arch/parisc/mm/ioremap.c @@ -9,8 +9,110 @@ #include #include #include -#include +#include #include +#include +#include + +static inline void +remap_area_pte(pte_t *pte, unsigned long address, unsigned long size, + unsigned long phys_addr, unsigned long flags) +{ + unsigned long end, pfn; + pgprot_t pgprot = __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | + _PAGE_ACCESSED | flags); + + address &= ~PMD_MASK; + + end = address + size; + if (end > PMD_SIZE) + end = PMD_SIZE; + + BUG_ON(address >= end); + + pfn = phys_addr >> PAGE_SHIFT; + do { + BUG_ON(!pte_none(*pte)); + + set_pte(pte, pfn_pte(pfn, pgprot)); + + address += PAGE_SIZE; + pfn++; + pte++; + } while (address && (address < end)); +} + +static inline int +remap_area_pmd(pmd_t *pmd, unsigned long address, unsigned long size, + unsigned long phys_addr, unsigned long flags) +{ + unsigned long end; + + address &= ~PGDIR_MASK; + + end = address + size; + if (end > PGDIR_SIZE) + end = PGDIR_SIZE; + + BUG_ON(address >= end); + + phys_addr -= address; + do { + pte_t *pte = pte_alloc_kernel(pmd, address); + if (!pte) + return -ENOMEM; + + remap_area_pte(pte, address, end - address, + address + phys_addr, flags); + + address = (address + PMD_SIZE) & PMD_MASK; + pmd++; + } while (address && (address < end)); + + return 0; +} + +static int +remap_area_pages(unsigned long address, unsigned long phys_addr, + unsigned long size, unsigned long flags) +{ + pgd_t *dir; + int error = 0; + unsigned long end = address + size; + + BUG_ON(address >= end); + + phys_addr -= address; + dir = pgd_offset_k(address); + + flush_cache_all(); + + do { + pud_t *pud; + pmd_t *pmd; + + error = -ENOMEM; + pud = pud_alloc(&init_mm, dir, address); + if (!pud) + break; + + pmd = pmd_alloc(&init_mm, pud, address); + if (!pmd) + break; + + if (remap_area_pmd(pmd, address, end - address, + phys_addr + address, flags)) + break; + + error = 0; + address = (address + PGDIR_SIZE) & PGDIR_MASK; + dir++; + } while (address && (address < end)); + + flush_tlb_all(); + + return error; +} /* * Generic mapping function (not visible outside): @@ -29,7 +131,6 @@ void __iomem * __ioremap(unsigned long phys_addr, unsigned long size, unsigned l void *addr; struct vm_struct *area; unsigned long offset, last_addr; - pgprot_t pgprot; #ifdef CONFIG_EISA unsigned long end = phys_addr + size - 1; @@ -63,9 +164,6 @@ void __iomem * __ioremap(unsigned long phys_addr, unsigned long size, unsigned l } } - pgprot = __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | - _PAGE_ACCESSED | flags); - /* * Mappings have to be page-aligned */ @@ -81,8 +179,7 @@ void __iomem * __ioremap(unsigned long phys_addr, unsigned long size, unsigned l return NULL; addr = area->addr; - if (ioremap_page_range((unsigned long)addr, (unsigned long)addr + size, - phys_addr, pgprot)) { + if (remap_area_pages((unsigned long) addr, phys_addr, size, flags)) { vfree(addr); return NULL; } diff --git a/trunk/arch/powerpc/Kconfig b/trunk/arch/powerpc/Kconfig index 56c3c4065eb0..291c95ac4b31 100644 --- a/trunk/arch/powerpc/Kconfig +++ b/trunk/arch/powerpc/Kconfig @@ -41,14 +41,6 @@ config RWSEM_XCHGADD_ALGORITHM bool default y -config ARCH_HAS_ILOG2_U32 - bool - default y - -config ARCH_HAS_ILOG2_U64 - bool - default y if 64BIT - config GENERIC_HWEIGHT bool default y diff --git a/trunk/arch/powerpc/kernel/proc_ppc64.c b/trunk/arch/powerpc/kernel/proc_ppc64.c index dd7001cacf75..f598cb519539 100644 --- a/trunk/arch/powerpc/kernel/proc_ppc64.c +++ b/trunk/arch/powerpc/kernel/proc_ppc64.c @@ -83,7 +83,7 @@ __initcall(proc_ppc64_init); static loff_t page_map_seek( struct file *file, loff_t off, int whence) { loff_t new; - struct proc_dir_entry *dp = PDE(file->f_path.dentry->d_inode); + struct proc_dir_entry *dp = PDE(file->f_dentry->d_inode); switch(whence) { case 0: @@ -106,13 +106,13 @@ static loff_t page_map_seek( struct file *file, loff_t off, int whence) static ssize_t page_map_read( struct file *file, char __user *buf, size_t nbytes, loff_t *ppos) { - struct proc_dir_entry *dp = PDE(file->f_path.dentry->d_inode); + struct proc_dir_entry *dp = PDE(file->f_dentry->d_inode); return simple_read_from_buffer(buf, nbytes, ppos, dp->data, dp->size); } static int page_map_mmap( struct file *file, struct vm_area_struct *vma ) { - struct proc_dir_entry *dp = PDE(file->f_path.dentry->d_inode); + struct proc_dir_entry *dp = PDE(file->f_dentry->d_inode); if ((vma->vm_end - vma->vm_start) > dp->size) return -EINVAL; diff --git a/trunk/arch/powerpc/kernel/rtas_flash.c b/trunk/arch/powerpc/kernel/rtas_flash.c index 0c4fcd34bfe5..7d0f13fecc0e 100644 --- a/trunk/arch/powerpc/kernel/rtas_flash.c +++ b/trunk/arch/powerpc/kernel/rtas_flash.c @@ -193,7 +193,7 @@ static void free_flash_list(struct flash_block_list *f) static int rtas_flash_release(struct inode *inode, struct file *file) { - struct proc_dir_entry *dp = PDE(file->f_path.dentry->d_inode); + struct proc_dir_entry *dp = PDE(file->f_dentry->d_inode); struct rtas_update_flash_t *uf; uf = (struct rtas_update_flash_t *) dp->data; @@ -255,7 +255,7 @@ static void get_flash_status_msg(int status, char *buf) static ssize_t rtas_flash_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) { - struct proc_dir_entry *dp = PDE(file->f_path.dentry->d_inode); + struct proc_dir_entry *dp = PDE(file->f_dentry->d_inode); struct rtas_update_flash_t *uf; char msg[RTAS_MSG_MAXLEN]; int msglen; @@ -299,7 +299,7 @@ void rtas_block_ctor(void *ptr, struct kmem_cache *cache, unsigned long flags) static ssize_t rtas_flash_write(struct file *file, const char __user *buffer, size_t count, loff_t *off) { - struct proc_dir_entry *dp = PDE(file->f_path.dentry->d_inode); + struct proc_dir_entry *dp = PDE(file->f_dentry->d_inode); struct rtas_update_flash_t *uf; char *p; int next_free; @@ -391,7 +391,7 @@ static void manage_flash(struct rtas_manage_flash_t *args_buf) static ssize_t manage_flash_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) { - struct proc_dir_entry *dp = PDE(file->f_path.dentry->d_inode); + struct proc_dir_entry *dp = PDE(file->f_dentry->d_inode); struct rtas_manage_flash_t *args_buf; char msg[RTAS_MSG_MAXLEN]; int msglen; @@ -421,7 +421,7 @@ static ssize_t manage_flash_read(struct file *file, char __user *buf, static ssize_t manage_flash_write(struct file *file, const char __user *buf, size_t count, loff_t *off) { - struct proc_dir_entry *dp = PDE(file->f_path.dentry->d_inode); + struct proc_dir_entry *dp = PDE(file->f_dentry->d_inode); struct rtas_manage_flash_t *args_buf; const char reject_str[] = "0"; const char commit_str[] = "1"; @@ -492,7 +492,7 @@ static int get_validate_flash_msg(struct rtas_validate_flash_t *args_buf, static ssize_t validate_flash_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) { - struct proc_dir_entry *dp = PDE(file->f_path.dentry->d_inode); + struct proc_dir_entry *dp = PDE(file->f_dentry->d_inode); struct rtas_validate_flash_t *args_buf; char msg[RTAS_MSG_MAXLEN]; int msglen; @@ -520,7 +520,7 @@ static ssize_t validate_flash_read(struct file *file, char __user *buf, static ssize_t validate_flash_write(struct file *file, const char __user *buf, size_t count, loff_t *off) { - struct proc_dir_entry *dp = PDE(file->f_path.dentry->d_inode); + struct proc_dir_entry *dp = PDE(file->f_dentry->d_inode); struct rtas_validate_flash_t *args_buf; int rc; @@ -569,7 +569,7 @@ static ssize_t validate_flash_write(struct file *file, const char __user *buf, static int validate_flash_release(struct inode *inode, struct file *file) { - struct proc_dir_entry *dp = PDE(file->f_path.dentry->d_inode); + struct proc_dir_entry *dp = PDE(file->f_dentry->d_inode); struct rtas_validate_flash_t *args_buf; args_buf = (struct rtas_validate_flash_t *) dp->data; diff --git a/trunk/arch/powerpc/platforms/cell/spufs/inode.c b/trunk/arch/powerpc/platforms/cell/spufs/inode.c index 738b9244382f..e3af9112c026 100644 --- a/trunk/arch/powerpc/platforms/cell/spufs/inode.c +++ b/trunk/arch/powerpc/platforms/cell/spufs/inode.c @@ -205,7 +205,7 @@ static int spufs_dir_close(struct inode *inode, struct file *file) struct dentry *dir; int ret; - dir = file->f_path.dentry; + dir = file->f_dentry; parent = dir->d_parent->d_inode; ctx = SPUFS_I(dir->d_inode)->i_ctx; @@ -363,7 +363,7 @@ static int spufs_gang_close(struct inode *inode, struct file *file) struct dentry *dir; int ret; - dir = file->f_path.dentry; + dir = file->f_dentry; parent = dir->d_parent->d_inode; ret = spufs_rmgang(parent, dir); diff --git a/trunk/arch/powerpc/platforms/cell/spufs/syscalls.c b/trunk/arch/powerpc/platforms/cell/spufs/syscalls.c index 8e37bdf4dfda..a6d1ae4dc2a3 100644 --- a/trunk/arch/powerpc/platforms/cell/spufs/syscalls.c +++ b/trunk/arch/powerpc/platforms/cell/spufs/syscalls.c @@ -46,7 +46,7 @@ static long do_spu_run(struct file *filp, if (filp->f_op != &spufs_context_fops) goto out; - i = SPUFS_I(filp->f_path.dentry->d_inode); + i = SPUFS_I(filp->f_dentry->d_inode); ret = spufs_run_spu(filp, i->i_ctx, &npc, &status); if (put_user(npc, unpc)) diff --git a/trunk/arch/powerpc/platforms/iseries/mf.c b/trunk/arch/powerpc/platforms/iseries/mf.c index cff15ae24f6b..b5737d68d6c4 100644 --- a/trunk/arch/powerpc/platforms/iseries/mf.c +++ b/trunk/arch/powerpc/platforms/iseries/mf.c @@ -1178,7 +1178,7 @@ static ssize_t proc_mf_change_vmlinux(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { - struct proc_dir_entry *dp = PDE(file->f_path.dentry->d_inode); + struct proc_dir_entry *dp = PDE(file->f_dentry->d_inode); ssize_t rc; dma_addr_t dma_addr; char *page; diff --git a/trunk/arch/powerpc/platforms/pseries/hvCall_inst.c b/trunk/arch/powerpc/platforms/pseries/hvCall_inst.c index 80181c4c49eb..446e17d162a5 100644 --- a/trunk/arch/powerpc/platforms/pseries/hvCall_inst.c +++ b/trunk/arch/powerpc/platforms/pseries/hvCall_inst.c @@ -85,7 +85,7 @@ static int hcall_inst_seq_open(struct inode *inode, struct file *file) rc = seq_open(file, &hcall_inst_seq_ops); seq = file->private_data; - seq->private = file->f_path.dentry->d_inode->i_private; + seq->private = file->f_dentry->d_inode->i_private; return rc; } diff --git a/trunk/arch/powerpc/platforms/pseries/scanlog.c b/trunk/arch/powerpc/platforms/pseries/scanlog.c index 45368a57d7dd..77a5bb1d9c30 100644 --- a/trunk/arch/powerpc/platforms/pseries/scanlog.c +++ b/trunk/arch/powerpc/platforms/pseries/scanlog.c @@ -47,7 +47,7 @@ static struct proc_dir_entry *proc_ppc64_scan_log_dump; /* The proc file */ static ssize_t scanlog_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) { - struct inode * inode = file->f_path.dentry->d_inode; + struct inode * inode = file->f_dentry->d_inode; struct proc_dir_entry *dp; unsigned int *data; int status; diff --git a/trunk/arch/ppc/8xx_io/cs4218_tdm.c b/trunk/arch/ppc/8xx_io/cs4218_tdm.c index c71ef3c2e7bf..959d31c26cbb 100644 --- a/trunk/arch/ppc/8xx_io/cs4218_tdm.c +++ b/trunk/arch/ppc/8xx_io/cs4218_tdm.c @@ -2165,7 +2165,7 @@ static int sq_release(struct inode *inode, struct file *file) int rc = 0; if (sq.busy) - rc = sq_fsync(file, file->f_path.dentry); + rc = sq_fsync(file, file->f_dentry); sound.soft = sound.dsp; sound.hard = sound.dsp; sound_silence(); @@ -2218,25 +2218,25 @@ static int sq_ioctl(struct inode *inode, struct file *file, u_int cmd, return 0; case SNDCTL_DSP_POST: case SNDCTL_DSP_SYNC: - return sq_fsync(file, file->f_path.dentry); + return sq_fsync(file, file->f_dentry); /* ++TeSche: before changing any of these it's * probably wise to wait until sound playing has * settled down. */ case SNDCTL_DSP_SPEED: - sq_fsync(file, file->f_path.dentry); + sq_fsync(file, file->f_dentry); IOCTL_IN(arg, data); return IOCTL_OUT(arg, sound_set_speed(data)); case SNDCTL_DSP_STEREO: - sq_fsync(file, file->f_path.dentry); + sq_fsync(file, file->f_dentry); IOCTL_IN(arg, data); return IOCTL_OUT(arg, sound_set_stereo(data)); case SOUND_PCM_WRITE_CHANNELS: - sq_fsync(file, file->f_path.dentry); + sq_fsync(file, file->f_dentry); IOCTL_IN(arg, data); return IOCTL_OUT(arg, sound_set_stereo(data-1)+1); case SNDCTL_DSP_SETFMT: - sq_fsync(file, file->f_path.dentry); + sq_fsync(file, file->f_dentry); IOCTL_IN(arg, data); return IOCTL_OUT(arg, sound_set_format(data)); case SNDCTL_DSP_GETFMTS: diff --git a/trunk/arch/ppc/Kconfig b/trunk/arch/ppc/Kconfig index 692b5ba53209..edf71a4ecc95 100644 --- a/trunk/arch/ppc/Kconfig +++ b/trunk/arch/ppc/Kconfig @@ -19,14 +19,6 @@ config RWSEM_XCHGADD_ALGORITHM bool default y -config ARCH_HAS_ILOG2_U32 - bool - default y - -config ARCH_HAS_ILOG2_U64 - bool - default n - config GENERIC_HWEIGHT bool default y @@ -60,11 +52,6 @@ config ARCH_MAY_HAVE_PC_FDC bool default y -config GENERIC_BUG - bool - default y - depends on BUG - source "init/Kconfig" menu "Processor" diff --git a/trunk/arch/ppc/kernel/traps.c b/trunk/arch/ppc/kernel/traps.c index 810f7aa72e92..2f835b9e95e4 100644 --- a/trunk/arch/ppc/kernel/traps.c +++ b/trunk/arch/ppc/kernel/traps.c @@ -28,7 +28,6 @@ #include #include #include -#include #include #include @@ -560,9 +559,64 @@ static void emulate_single_step(struct pt_regs *regs) } } -int is_valid_bugaddr(unsigned long addr) +/* + * Look through the list of trap instructions that are used for BUG(), + * BUG_ON() and WARN_ON() and see if we hit one. At this point we know + * that the exception was caused by a trap instruction of some kind. + * Returns 1 if we should continue (i.e. it was a WARN_ON) or 0 + * otherwise. + */ +extern struct bug_entry __start___bug_table[], __stop___bug_table[]; + +#ifndef CONFIG_MODULES +#define module_find_bug(x) NULL +#endif + +struct bug_entry *find_bug(unsigned long bugaddr) +{ + struct bug_entry *bug; + + for (bug = __start___bug_table; bug < __stop___bug_table; ++bug) + if (bugaddr == bug->bug_addr) + return bug; + return module_find_bug(bugaddr); +} + +int check_bug_trap(struct pt_regs *regs) { - return addr >= PAGE_OFFSET; + struct bug_entry *bug; + unsigned long addr; + + if (regs->msr & MSR_PR) + return 0; /* not in kernel */ + addr = regs->nip; /* address of trap instruction */ + if (addr < PAGE_OFFSET) + return 0; + bug = find_bug(regs->nip); + if (bug == NULL) + return 0; + if (bug->line & BUG_WARNING_TRAP) { + /* this is a WARN_ON rather than BUG/BUG_ON */ +#ifdef CONFIG_XMON + xmon_printf(KERN_ERR "Badness in %s at %s:%ld\n", + bug->function, bug->file, + bug->line & ~BUG_WARNING_TRAP); +#endif /* CONFIG_XMON */ + printk(KERN_ERR "Badness in %s at %s:%ld\n", + bug->function, bug->file, + bug->line & ~BUG_WARNING_TRAP); + dump_stack(); + return 1; + } +#ifdef CONFIG_XMON + xmon_printf(KERN_CRIT "kernel BUG in %s at %s:%ld!\n", + bug->function, bug->file, bug->line); + xmon(regs); +#endif /* CONFIG_XMON */ + printk(KERN_CRIT "kernel BUG in %s at %s:%ld!\n", + bug->function, bug->file, bug->line); + + return 0; } void program_check_exception(struct pt_regs *regs) @@ -617,9 +671,7 @@ void program_check_exception(struct pt_regs *regs) /* trap exception */ if (debugger_bpt(regs)) return; - - if (!(regs->msr & MSR_PR) && /* not user-mode */ - report_bug(regs->nip) == BUG_TRAP_TYPE_WARN) { + if (check_bug_trap(regs)) { regs->nip += 4; return; } diff --git a/trunk/arch/s390/Kconfig b/trunk/arch/s390/Kconfig index ff690564edbd..583d9ff0a571 100644 --- a/trunk/arch/s390/Kconfig +++ b/trunk/arch/s390/Kconfig @@ -22,14 +22,6 @@ config RWSEM_XCHGADD_ALGORITHM bool default y -config ARCH_HAS_ILOG2_U32 - bool - default n - -config ARCH_HAS_ILOG2_U64 - bool - default n - config GENERIC_HWEIGHT bool default y @@ -241,14 +233,8 @@ config WARN_STACK_SIZE This allows you to specify the maximum frame size a function may have without the compiler complaining about it. -config ARCH_POPULATES_NODE_MAP - def_bool y - source "mm/Kconfig" -config HOLES_IN_ZONE - def_bool y - comment "I/O subsystem configuration" config MACHCHK_WARNING @@ -272,6 +258,14 @@ config QDIO If unsure, say Y. +config QDIO_PERF_STATS + bool "Performance statistics in /proc" + depends on QDIO + help + Say Y here to get performance statistics in /proc/qdio_perf + + If unsure, say N. + config QDIO_DEBUG bool "Extended debugging information" depends on QDIO diff --git a/trunk/arch/s390/defconfig b/trunk/arch/s390/defconfig index a6ec919ba83f..7cd51e73e274 100644 --- a/trunk/arch/s390/defconfig +++ b/trunk/arch/s390/defconfig @@ -134,6 +134,7 @@ CONFIG_RESOURCES_64BIT=y # CONFIG_MACHCHK_WARNING=y CONFIG_QDIO=y +# CONFIG_QDIO_PERF_STATS is not set # CONFIG_QDIO_DEBUG is not set # diff --git a/trunk/arch/s390/hypfs/inode.c b/trunk/arch/s390/hypfs/inode.c index b6716c4b9934..cd702ae45d6d 100644 --- a/trunk/arch/s390/hypfs/inode.c +++ b/trunk/arch/s390/hypfs/inode.c @@ -109,7 +109,7 @@ static void hypfs_drop_inode(struct inode *inode) static int hypfs_open(struct inode *inode, struct file *filp) { - char *data = filp->f_path.dentry->d_inode->i_private; + char *data = filp->f_dentry->d_inode->i_private; struct hypfs_sb_info *fs_info; if (filp->f_mode & FMODE_WRITE) { @@ -174,7 +174,7 @@ static ssize_t hypfs_aio_write(struct kiocb *iocb, const struct iovec *iov, struct hypfs_sb_info *fs_info; size_t count = iov_length(iov, nr_segs); - sb = iocb->ki_filp->f_path.dentry->d_inode->i_sb; + sb = iocb->ki_filp->f_dentry->d_inode->i_sb; fs_info = sb->s_fs_info; /* * Currently we only allow one update per second for two reasons: diff --git a/trunk/arch/s390/kernel/debug.c b/trunk/arch/s390/kernel/debug.c index ef5266fbce62..43f3d0c7e132 100644 --- a/trunk/arch/s390/kernel/debug.c +++ b/trunk/arch/s390/kernel/debug.c @@ -603,13 +603,13 @@ debug_open(struct inode *inode, struct file *file) debug_info_t *debug_info, *debug_info_snapshot; down(&debug_lock); - debug_info = file->f_path.dentry->d_inode->i_private; + debug_info = file->f_dentry->d_inode->i_private; /* find debug view */ for (i = 0; i < DEBUG_MAX_VIEWS; i++) { if (!debug_info->views[i]) continue; else if (debug_info->debugfs_entries[i] == - file->f_path.dentry) { + file->f_dentry) { goto found; /* found view ! */ } } diff --git a/trunk/arch/s390/kernel/setup.c b/trunk/arch/s390/kernel/setup.c index 49ef206ec880..b928fecdc743 100644 --- a/trunk/arch/s390/kernel/setup.c +++ b/trunk/arch/s390/kernel/setup.c @@ -64,8 +64,9 @@ unsigned int console_devno = -1; unsigned int console_irq = -1; unsigned long machine_flags = 0; -struct mem_chunk __initdata memory_chunk[MEMORY_CHUNKS]; +struct mem_chunk memory_chunk[MEMORY_CHUNKS]; volatile int __cpu_logical_map[NR_CPUS]; /* logical cpu to cpu address */ +unsigned long __initdata zholes_size[MAX_NR_ZONES]; static unsigned long __initdata memory_end; /* @@ -353,6 +354,21 @@ void machine_power_off(void) */ void (*pm_power_off)(void) = machine_power_off; +static void __init +add_memory_hole(unsigned long start, unsigned long end) +{ + unsigned long dma_pfn = MAX_DMA_ADDRESS >> PAGE_SHIFT; + + if (end <= dma_pfn) + zholes_size[ZONE_DMA] += end - start + 1; + else if (start > dma_pfn) + zholes_size[ZONE_NORMAL] += end - start + 1; + else { + zholes_size[ZONE_DMA] += dma_pfn - start + 1; + zholes_size[ZONE_NORMAL] += end - dma_pfn; + } +} + static int __init early_parse_mem(char *p) { memory_end = memparse(p, &p); @@ -505,6 +521,7 @@ setup_memory(void) { unsigned long bootmap_size; unsigned long start_pfn, end_pfn, init_pfn; + unsigned long last_rw_end; int i; /* @@ -560,27 +577,39 @@ setup_memory(void) /* * Register RAM areas with the bootmem allocator. */ + last_rw_end = start_pfn; for (i = 0; i < MEMORY_CHUNKS && memory_chunk[i].size > 0; i++) { - unsigned long start_chunk, end_chunk, pfn; + unsigned long start_chunk, end_chunk; if (memory_chunk[i].type != CHUNK_READ_WRITE) continue; - start_chunk = PFN_DOWN(memory_chunk[i].addr); - end_chunk = start_chunk + PFN_DOWN(memory_chunk[i].size) - 1; - end_chunk = min(end_chunk, end_pfn); - if (start_chunk >= end_chunk) - continue; - add_active_range(0, start_chunk, end_chunk); - pfn = max(start_chunk, start_pfn); - for (; pfn <= end_chunk; pfn++) - page_set_storage_key(PFN_PHYS(pfn), PAGE_DEFAULT_KEY); + start_chunk = (memory_chunk[i].addr + PAGE_SIZE - 1); + start_chunk >>= PAGE_SHIFT; + end_chunk = (memory_chunk[i].addr + memory_chunk[i].size); + end_chunk >>= PAGE_SHIFT; + if (start_chunk < start_pfn) + start_chunk = start_pfn; + if (end_chunk > end_pfn) + end_chunk = end_pfn; + if (start_chunk < end_chunk) { + /* Initialize storage key for RAM pages */ + for (init_pfn = start_chunk ; init_pfn < end_chunk; + init_pfn++) + page_set_storage_key(init_pfn << PAGE_SHIFT, + PAGE_DEFAULT_KEY); + free_bootmem(start_chunk << PAGE_SHIFT, + (end_chunk - start_chunk) << PAGE_SHIFT); + if (last_rw_end < start_chunk) + add_memory_hole(last_rw_end, start_chunk - 1); + last_rw_end = end_chunk; + } } psw_set_key(PAGE_DEFAULT_KEY); - free_bootmem_with_active_regions(0, max_pfn); - reserve_bootmem(0, PFN_PHYS(start_pfn)); + if (last_rw_end < end_pfn - 1) + add_memory_hole(last_rw_end, end_pfn - 1); /* * Reserve the bootmem bitmap itself as well. We do this in two diff --git a/trunk/arch/s390/lib/uaccess_pt.c b/trunk/arch/s390/lib/uaccess_pt.c index 633249c3ba91..8741bdc09299 100644 --- a/trunk/arch/s390/lib/uaccess_pt.c +++ b/trunk/arch/s390/lib/uaccess_pt.c @@ -8,8 +8,8 @@ */ #include -#include #include +#include #include static inline int __handle_fault(struct mm_struct *mm, unsigned long address, @@ -60,9 +60,8 @@ static inline int __handle_fault(struct mm_struct *mm, unsigned long address, out_of_memory: up_read(&mm->mmap_sem); - if (is_init(current)) { + if (current->pid == 1) { yield(); - down_read(&mm->mmap_sem); goto survive; } printk("VM: killing process %s\n", current->comm); diff --git a/trunk/arch/s390/mm/Makefile b/trunk/arch/s390/mm/Makefile index 8e09db1edbb9..aa9a42b6e62d 100644 --- a/trunk/arch/s390/mm/Makefile +++ b/trunk/arch/s390/mm/Makefile @@ -2,6 +2,6 @@ # Makefile for the linux s390-specific parts of the memory manager. # -obj-y := init.o fault.o ioremap.o extmem.o mmap.o vmem.o +obj-y := init.o fault.o ioremap.o extmem.o mmap.o obj-$(CONFIG_CMM) += cmm.o diff --git a/trunk/arch/s390/mm/extmem.c b/trunk/arch/s390/mm/extmem.c index 775bf19e742b..9e9bc48463a5 100644 --- a/trunk/arch/s390/mm/extmem.c +++ b/trunk/arch/s390/mm/extmem.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include #include @@ -238,6 +237,65 @@ query_segment_type (struct dcss_segment *seg) return rc; } +/* + * check if the given segment collides with guest storage. + * returns 1 if this is the case, 0 if no collision was found + */ +static int +segment_overlaps_storage(struct dcss_segment *seg) +{ + int i; + + for (i = 0; i < MEMORY_CHUNKS && memory_chunk[i].size > 0; i++) { + if (memory_chunk[i].type != CHUNK_READ_WRITE) + continue; + if ((memory_chunk[i].addr >> 20) > (seg->end >> 20)) + continue; + if (((memory_chunk[i].addr + memory_chunk[i].size - 1) >> 20) + < (seg->start_addr >> 20)) + continue; + return 1; + } + return 0; +} + +/* + * check if segment collides with other segments that are currently loaded + * returns 1 if this is the case, 0 if no collision was found + */ +static int +segment_overlaps_others (struct dcss_segment *seg) +{ + struct list_head *l; + struct dcss_segment *tmp; + + BUG_ON(!mutex_is_locked(&dcss_lock)); + list_for_each(l, &dcss_list) { + tmp = list_entry(l, struct dcss_segment, list); + if ((tmp->start_addr >> 20) > (seg->end >> 20)) + continue; + if ((tmp->end >> 20) < (seg->start_addr >> 20)) + continue; + if (seg == tmp) + continue; + return 1; + } + return 0; +} + +/* + * check if segment exceeds the kernel mapping range (detected or set via mem=) + * returns 1 if this is the case, 0 if segment fits into the range + */ +static inline int +segment_exceeds_range (struct dcss_segment *seg) +{ + int seg_last_pfn = (seg->end) >> PAGE_SHIFT; + if (seg_last_pfn > max_pfn) + return 1; + return 0; +} + /* * get info about a segment * possible return values: @@ -283,26 +341,24 @@ __segment_load (char *name, int do_nonshared, unsigned long *addr, unsigned long rc = query_segment_type (seg); if (rc < 0) goto out_free; - - rc = add_shared_memory(seg->start_addr, seg->end - seg->start_addr + 1); - - switch (rc) { - case 0: - break; - case -ENOSPC: - PRINT_WARN("segment_load: not loading segment %s - overlaps " - "storage/segment\n", name); + if (segment_exceeds_range(seg)) { + PRINT_WARN ("segment_load: not loading segment %s - exceeds" + " kernel mapping range\n",name); + rc = -ERANGE; goto out_free; - case -ERANGE: - PRINT_WARN("segment_load: not loading segment %s - exceeds " - "kernel mapping range\n", name); + } + if (segment_overlaps_storage(seg)) { + PRINT_WARN ("segment_load: not loading segment %s - overlaps" + " storage\n",name); + rc = -ENOSPC; goto out_free; - default: - PRINT_WARN("segment_load: not loading segment %s (rc: %d)\n", - name, rc); + } + if (segment_overlaps_others(seg)) { + PRINT_WARN ("segment_load: not loading segment %s - overlaps" + " other segments\n",name); + rc = -EBUSY; goto out_free; } - if (do_nonshared) dcss_command = DCSS_LOADNSR; else @@ -316,7 +372,7 @@ __segment_load (char *name, int do_nonshared, unsigned long *addr, unsigned long rc = dcss_diag_translate_rc (seg->end); dcss_diag(DCSS_PURGESEG, seg->dcss_name, &seg->start_addr, &seg->end); - goto out_shared; + goto out_free; } seg->do_nonshared = do_nonshared; atomic_set(&seg->ref_count, 1); @@ -335,8 +391,6 @@ __segment_load (char *name, int do_nonshared, unsigned long *addr, unsigned long (void*)seg->start_addr, (void*)seg->end, segtype_string[seg->vm_segtype]); goto out; - out_shared: - remove_shared_memory(seg->start_addr, seg->end - seg->start_addr + 1); out_free: kfree(seg); out: @@ -476,12 +530,12 @@ segment_unload(char *name) "please report to linux390@de.ibm.com\n",name); goto out_unlock; } - if (atomic_dec_return(&seg->ref_count) != 0) - goto out_unlock; - remove_shared_memory(seg->start_addr, seg->end - seg->start_addr + 1); - list_del(&seg->list); - dcss_diag(DCSS_PURGESEG, seg->dcss_name, &dummy, &dummy); - kfree(seg); + if (atomic_dec_return(&seg->ref_count) == 0) { + list_del(&seg->list); + dcss_diag(DCSS_PURGESEG, seg->dcss_name, + &dummy, &dummy); + kfree(seg); + } out_unlock: mutex_unlock(&dcss_lock); } diff --git a/trunk/arch/s390/mm/init.c b/trunk/arch/s390/mm/init.c index 4bb21be3b007..e1881c31b1cb 100644 --- a/trunk/arch/s390/mm/init.c +++ b/trunk/arch/s390/mm/init.c @@ -24,7 +24,6 @@ #include #include #include -#include #include #include @@ -70,8 +69,6 @@ void show_mem(void) printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10)); i = max_mapnr; while (i-- > 0) { - if (!pfn_valid(i)) - continue; page = pfn_to_page(i); total++; if (PageReserved(page)) @@ -87,52 +84,150 @@ void show_mem(void) printk("%d pages swap cached\n",cached); } -static void __init setup_ro_region(void) +extern unsigned long __initdata zholes_size[]; +/* + * paging_init() sets up the page tables + */ + +#ifndef CONFIG_64BIT +void __init paging_init(void) { - pgd_t *pgd; - pmd_t *pmd; - pte_t *pte; - pte_t new_pte; - unsigned long address, end; - - address = ((unsigned long)&__start_rodata) & PAGE_MASK; - end = PFN_ALIGN((unsigned long)&__end_rodata); - - for (; address < end; address += PAGE_SIZE) { - pgd = pgd_offset_k(address); - pmd = pmd_offset(pgd, address); - pte = pte_offset_kernel(pmd, address); - new_pte = mk_pte_phys(address, __pgprot(_PAGE_RO)); - set_pte(pte, new_pte); - } + pgd_t * pg_dir; + pte_t * pg_table; + pte_t pte; + int i; + unsigned long tmp; + unsigned long pfn = 0; + unsigned long pgdir_k = (__pa(swapper_pg_dir) & PAGE_MASK) | _KERNSEG_TABLE; + static const int ssm_mask = 0x04000000L; + unsigned long ro_start_pfn, ro_end_pfn; + unsigned long zones_size[MAX_NR_ZONES]; + + ro_start_pfn = PFN_DOWN((unsigned long)&__start_rodata); + ro_end_pfn = PFN_UP((unsigned long)&__end_rodata); + + memset(zones_size, 0, sizeof(zones_size)); + zones_size[ZONE_DMA] = max_low_pfn; + free_area_init_node(0, &contig_page_data, zones_size, + __pa(PAGE_OFFSET) >> PAGE_SHIFT, + zholes_size); + + /* unmap whole virtual address space */ + + pg_dir = swapper_pg_dir; + + for (i = 0; i < PTRS_PER_PGD; i++) + pmd_clear((pmd_t *) pg_dir++); + + /* + * map whole physical memory to virtual memory (identity mapping) + */ + + pg_dir = swapper_pg_dir; + + while (pfn < max_low_pfn) { + /* + * pg_table is physical at this point + */ + pg_table = (pte_t *) alloc_bootmem_pages(PAGE_SIZE); + + pmd_populate_kernel(&init_mm, (pmd_t *) pg_dir, pg_table); + pg_dir++; + + for (tmp = 0 ; tmp < PTRS_PER_PTE ; tmp++,pg_table++) { + if (pfn >= ro_start_pfn && pfn < ro_end_pfn) + pte = pfn_pte(pfn, __pgprot(_PAGE_RO)); + else + pte = pfn_pte(pfn, PAGE_KERNEL); + if (pfn >= max_low_pfn) + pte_val(pte) = _PAGE_TYPE_EMPTY; + set_pte(pg_table, pte); + pfn++; + } + } + + S390_lowcore.kernel_asce = pgdir_k; + + /* enable virtual mapping in kernel mode */ + __ctl_load(pgdir_k, 1, 1); + __ctl_load(pgdir_k, 7, 7); + __ctl_load(pgdir_k, 13, 13); + __raw_local_irq_ssm(ssm_mask); + + local_flush_tlb(); } -extern void vmem_map_init(void); +#else /* CONFIG_64BIT */ -/* - * paging_init() sets up the page tables - */ void __init paging_init(void) { - pgd_t *pg_dir; - int i; - unsigned long pgdir_k; + pgd_t * pg_dir; + pmd_t * pm_dir; + pte_t * pt_dir; + pte_t pte; + int i,j,k; + unsigned long pfn = 0; + unsigned long pgdir_k = (__pa(swapper_pg_dir) & PAGE_MASK) | + _KERN_REGION_TABLE; static const int ssm_mask = 0x04000000L; - unsigned long max_zone_pfns[MAX_NR_ZONES]; + unsigned long zones_size[MAX_NR_ZONES]; + unsigned long dma_pfn, high_pfn; + unsigned long ro_start_pfn, ro_end_pfn; + + memset(zones_size, 0, sizeof(zones_size)); + dma_pfn = MAX_DMA_ADDRESS >> PAGE_SHIFT; + high_pfn = max_low_pfn; + ro_start_pfn = PFN_DOWN((unsigned long)&__start_rodata); + ro_end_pfn = PFN_UP((unsigned long)&__end_rodata); + + if (dma_pfn > high_pfn) + zones_size[ZONE_DMA] = high_pfn; + else { + zones_size[ZONE_DMA] = dma_pfn; + zones_size[ZONE_NORMAL] = high_pfn - dma_pfn; + } + + /* Initialize mem_map[]. */ + free_area_init_node(0, &contig_page_data, zones_size, + __pa(PAGE_OFFSET) >> PAGE_SHIFT, zholes_size); - pg_dir = swapper_pg_dir; + /* + * map whole physical memory to virtual memory (identity mapping) + */ + + pg_dir = swapper_pg_dir; -#ifdef CONFIG_64BIT - pgdir_k = (__pa(swapper_pg_dir) & PAGE_MASK) | _KERN_REGION_TABLE; - for (i = 0; i < PTRS_PER_PGD; i++) - pgd_clear(pg_dir + i); -#else - pgdir_k = (__pa(swapper_pg_dir) & PAGE_MASK) | _KERNSEG_TABLE; - for (i = 0; i < PTRS_PER_PGD; i++) - pmd_clear((pmd_t *)(pg_dir + i)); -#endif - vmem_map_init(); - setup_ro_region(); + for (i = 0 ; i < PTRS_PER_PGD ; i++,pg_dir++) { + + if (pfn >= max_low_pfn) { + pgd_clear(pg_dir); + continue; + } + + pm_dir = (pmd_t *) alloc_bootmem_pages(PAGE_SIZE * 4); + pgd_populate(&init_mm, pg_dir, pm_dir); + + for (j = 0 ; j < PTRS_PER_PMD ; j++,pm_dir++) { + if (pfn >= max_low_pfn) { + pmd_clear(pm_dir); + continue; + } + + pt_dir = (pte_t *) alloc_bootmem_pages(PAGE_SIZE); + pmd_populate_kernel(&init_mm, pm_dir, pt_dir); + + for (k = 0 ; k < PTRS_PER_PTE ; k++,pt_dir++) { + if (pfn >= ro_start_pfn && pfn < ro_end_pfn) + pte = pfn_pte(pfn, __pgprot(_PAGE_RO)); + else + pte = pfn_pte(pfn, PAGE_KERNEL); + if (pfn >= max_low_pfn) + pte_val(pte) = _PAGE_TYPE_EMPTY; + set_pte(pt_dir, pte); + pfn++; + } + } + } S390_lowcore.kernel_asce = pgdir_k; @@ -142,11 +237,9 @@ void __init paging_init(void) __ctl_load(pgdir_k, 13, 13); __raw_local_irq_ssm(ssm_mask); - memset(max_zone_pfns, 0, sizeof(max_zone_pfns)); - max_zone_pfns[ZONE_DMA] = PFN_DOWN(MAX_DMA_ADDRESS); - max_zone_pfns[ZONE_NORMAL] = max_low_pfn; - free_area_init_nodes(max_zone_pfns); + local_flush_tlb(); } +#endif /* CONFIG_64BIT */ void __init mem_init(void) { @@ -176,8 +269,6 @@ void __init mem_init(void) printk("Write protected kernel read-only data: %#lx - %#lx\n", (unsigned long)&__start_rodata, PFN_ALIGN((unsigned long)&__end_rodata) - 1); - printk("Virtual memmap size: %ldk\n", - (max_pfn * sizeof(struct page)) >> 10); } void free_initmem(void) @@ -188,7 +279,6 @@ void free_initmem(void) for (; addr < (unsigned long)(&__init_end); addr += PAGE_SIZE) { ClearPageReserved(virt_to_page(addr)); init_page_count(virt_to_page(addr)); - memset((void *)addr, POISON_FREE_INITMEM, PAGE_SIZE); free_page(addr); totalram_pages++; } diff --git a/trunk/arch/s390/mm/ioremap.c b/trunk/arch/s390/mm/ioremap.c index 3d2100a4e209..0f6e9ecbefe2 100644 --- a/trunk/arch/s390/mm/ioremap.c +++ b/trunk/arch/s390/mm/ioremap.c @@ -15,8 +15,87 @@ #include #include -#include +#include #include +#include +#include + +static inline void remap_area_pte(pte_t * pte, unsigned long address, unsigned long size, + unsigned long phys_addr, unsigned long flags) +{ + unsigned long end; + unsigned long pfn; + + address &= ~PMD_MASK; + end = address + size; + if (end > PMD_SIZE) + end = PMD_SIZE; + if (address >= end) + BUG(); + pfn = phys_addr >> PAGE_SHIFT; + do { + if (!pte_none(*pte)) { + printk("remap_area_pte: page already exists\n"); + BUG(); + } + set_pte(pte, pfn_pte(pfn, __pgprot(flags))); + address += PAGE_SIZE; + pfn++; + pte++; + } while (address && (address < end)); +} + +static inline int remap_area_pmd(pmd_t * pmd, unsigned long address, unsigned long size, + unsigned long phys_addr, unsigned long flags) +{ + unsigned long end; + + address &= ~PGDIR_MASK; + end = address + size; + if (end > PGDIR_SIZE) + end = PGDIR_SIZE; + phys_addr -= address; + if (address >= end) + BUG(); + do { + pte_t * pte = pte_alloc_kernel(pmd, address); + if (!pte) + return -ENOMEM; + remap_area_pte(pte, address, end - address, address + phys_addr, flags); + address = (address + PMD_SIZE) & PMD_MASK; + pmd++; + } while (address && (address < end)); + return 0; +} + +static int remap_area_pages(unsigned long address, unsigned long phys_addr, + unsigned long size, unsigned long flags) +{ + int error; + pgd_t * dir; + unsigned long end = address + size; + + phys_addr -= address; + dir = pgd_offset(&init_mm, address); + flush_cache_all(); + if (address >= end) + BUG(); + do { + pmd_t *pmd; + pmd = pmd_alloc(&init_mm, dir, address); + error = -ENOMEM; + if (!pmd) + break; + if (remap_area_pmd(pmd, address, end - address, + phys_addr + address, flags)) + break; + error = 0; + address = (address + PGDIR_SIZE) & PGDIR_MASK; + dir++; + } while (address && (address < end)); + flush_tlb_all(); + return 0; +} /* * Generic mapping function (not visible outside): @@ -43,8 +122,7 @@ void * __ioremap(unsigned long phys_addr, unsigned long size, unsigned long flag if (!area) return NULL; addr = area->addr; - if (ioremap_page_range((unsigned long)addr, (unsigned long)addr + size, - phys_addr, __pgprot(flags))) { + if (remap_area_pages((unsigned long) addr, phys_addr, size, flags)) { vfree(addr); return NULL; } diff --git a/trunk/arch/s390/mm/vmem.c b/trunk/arch/s390/mm/vmem.c deleted file mode 100644 index 7f2944d3ec2a..000000000000 --- a/trunk/arch/s390/mm/vmem.c +++ /dev/null @@ -1,381 +0,0 @@ -/* - * arch/s390/mm/vmem.c - * - * Copyright IBM Corp. 2006 - * Author(s): Heiko Carstens - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -unsigned long vmalloc_end; -EXPORT_SYMBOL(vmalloc_end); - -static struct page *vmem_map; -static DEFINE_MUTEX(vmem_mutex); - -struct memory_segment { - struct list_head list; - unsigned long start; - unsigned long size; -}; - -static LIST_HEAD(mem_segs); - -void memmap_init(unsigned long size, int nid, unsigned long zone, - unsigned long start_pfn) -{ - struct page *start, *end; - struct page *map_start, *map_end; - int i; - - start = pfn_to_page(start_pfn); - end = start + size; - - for (i = 0; i < MEMORY_CHUNKS && memory_chunk[i].size > 0; i++) { - unsigned long cstart, cend; - - cstart = PFN_DOWN(memory_chunk[i].addr); - cend = cstart + PFN_DOWN(memory_chunk[i].size); - - map_start = mem_map + cstart; - map_end = mem_map + cend; - - if (map_start < start) - map_start = start; - if (map_end > end) - map_end = end; - - map_start -= ((unsigned long) map_start & (PAGE_SIZE - 1)) - / sizeof(struct page); - map_end += ((PFN_ALIGN((unsigned long) map_end) - - (unsigned long) map_end) - / sizeof(struct page)); - - if (map_start < map_end) - memmap_init_zone((unsigned long)(map_end - map_start), - nid, zone, page_to_pfn(map_start)); - } -} - -static inline void *vmem_alloc_pages(unsigned int order) -{ - if (slab_is_available()) - return (void *)__get_free_pages(GFP_KERNEL, order); - return alloc_bootmem_pages((1 << order) * PAGE_SIZE); -} - -static inline pmd_t *vmem_pmd_alloc(void) -{ - pmd_t *pmd; - int i; - - pmd = vmem_alloc_pages(PMD_ALLOC_ORDER); - if (!pmd) - return NULL; - for (i = 0; i < PTRS_PER_PMD; i++) - pmd_clear(pmd + i); - return pmd; -} - -static inline pte_t *vmem_pte_alloc(void) -{ - pte_t *pte; - pte_t empty_pte; - int i; - - pte = vmem_alloc_pages(PTE_ALLOC_ORDER); - if (!pte) - return NULL; - pte_val(empty_pte) = _PAGE_TYPE_EMPTY; - for (i = 0; i < PTRS_PER_PTE; i++) - set_pte(pte + i, empty_pte); - return pte; -} - -/* - * Add a physical memory range to the 1:1 mapping. - */ -static int vmem_add_range(unsigned long start, unsigned long size) -{ - unsigned long address; - pgd_t *pg_dir; - pmd_t *pm_dir; - pte_t *pt_dir; - pte_t pte; - int ret = -ENOMEM; - - for (address = start; address < start + size; address += PAGE_SIZE) { - pg_dir = pgd_offset_k(address); - if (pgd_none(*pg_dir)) { - pm_dir = vmem_pmd_alloc(); - if (!pm_dir) - goto out; - pgd_populate(&init_mm, pg_dir, pm_dir); - } - - pm_dir = pmd_offset(pg_dir, address); - if (pmd_none(*pm_dir)) { - pt_dir = vmem_pte_alloc(); - if (!pt_dir) - goto out; - pmd_populate_kernel(&init_mm, pm_dir, pt_dir); - } - - pt_dir = pte_offset_kernel(pm_dir, address); - pte = pfn_pte(address >> PAGE_SHIFT, PAGE_KERNEL); - set_pte(pt_dir, pte); - } - ret = 0; -out: - flush_tlb_kernel_range(start, start + size); - return ret; -} - -/* - * Remove a physical memory range from the 1:1 mapping. - * Currently only invalidates page table entries. - */ -static void vmem_remove_range(unsigned long start, unsigned long size) -{ - unsigned long address; - pgd_t *pg_dir; - pmd_t *pm_dir; - pte_t *pt_dir; - pte_t pte; - - pte_val(pte) = _PAGE_TYPE_EMPTY; - for (address = start; address < start + size; address += PAGE_SIZE) { - pg_dir = pgd_offset_k(address); - if (pgd_none(*pg_dir)) - continue; - pm_dir = pmd_offset(pg_dir, address); - if (pmd_none(*pm_dir)) - continue; - pt_dir = pte_offset_kernel(pm_dir, address); - set_pte(pt_dir, pte); - } - flush_tlb_kernel_range(start, start + size); -} - -/* - * Add a backed mem_map array to the virtual mem_map array. - */ -static int vmem_add_mem_map(unsigned long start, unsigned long size) -{ - unsigned long address, start_addr, end_addr; - struct page *map_start, *map_end; - pgd_t *pg_dir; - pmd_t *pm_dir; - pte_t *pt_dir; - pte_t pte; - int ret = -ENOMEM; - - map_start = vmem_map + PFN_DOWN(start); - map_end = vmem_map + PFN_DOWN(start + size); - - start_addr = (unsigned long) map_start & PAGE_MASK; - end_addr = PFN_ALIGN((unsigned long) map_end); - - for (address = start_addr; address < end_addr; address += PAGE_SIZE) { - pg_dir = pgd_offset_k(address); - if (pgd_none(*pg_dir)) { - pm_dir = vmem_pmd_alloc(); - if (!pm_dir) - goto out; - pgd_populate(&init_mm, pg_dir, pm_dir); - } - - pm_dir = pmd_offset(pg_dir, address); - if (pmd_none(*pm_dir)) { - pt_dir = vmem_pte_alloc(); - if (!pt_dir) - goto out; - pmd_populate_kernel(&init_mm, pm_dir, pt_dir); - } - - pt_dir = pte_offset_kernel(pm_dir, address); - if (pte_none(*pt_dir)) { - unsigned long new_page; - - new_page =__pa(vmem_alloc_pages(0)); - if (!new_page) - goto out; - pte = pfn_pte(new_page >> PAGE_SHIFT, PAGE_KERNEL); - set_pte(pt_dir, pte); - } - } - ret = 0; -out: - flush_tlb_kernel_range(start_addr, end_addr); - return ret; -} - -static int vmem_add_mem(unsigned long start, unsigned long size) -{ - int ret; - - ret = vmem_add_range(start, size); - if (ret) - return ret; - return vmem_add_mem_map(start, size); -} - -/* - * Add memory segment to the segment list if it doesn't overlap with - * an already present segment. - */ -static int insert_memory_segment(struct memory_segment *seg) -{ - struct memory_segment *tmp; - - if (PFN_DOWN(seg->start + seg->size) > max_pfn || - seg->start + seg->size < seg->start) - return -ERANGE; - - list_for_each_entry(tmp, &mem_segs, list) { - if (seg->start >= tmp->start + tmp->size) - continue; - if (seg->start + seg->size <= tmp->start) - continue; - return -ENOSPC; - } - list_add(&seg->list, &mem_segs); - return 0; -} - -/* - * Remove memory segment from the segment list. - */ -static void remove_memory_segment(struct memory_segment *seg) -{ - list_del(&seg->list); -} - -static void __remove_shared_memory(struct memory_segment *seg) -{ - remove_memory_segment(seg); - vmem_remove_range(seg->start, seg->size); -} - -int remove_shared_memory(unsigned long start, unsigned long size) -{ - struct memory_segment *seg; - int ret; - - mutex_lock(&vmem_mutex); - - ret = -ENOENT; - list_for_each_entry(seg, &mem_segs, list) { - if (seg->start == start && seg->size == size) - break; - } - - if (seg->start != start || seg->size != size) - goto out; - - ret = 0; - __remove_shared_memory(seg); - kfree(seg); -out: - mutex_unlock(&vmem_mutex); - return ret; -} - -int add_shared_memory(unsigned long start, unsigned long size) -{ - struct memory_segment *seg; - struct page *page; - unsigned long pfn, num_pfn, end_pfn; - int ret; - - mutex_lock(&vmem_mutex); - ret = -ENOMEM; - seg = kzalloc(sizeof(*seg), GFP_KERNEL); - if (!seg) - goto out; - seg->start = start; - seg->size = size; - - ret = insert_memory_segment(seg); - if (ret) - goto out_free; - - ret = vmem_add_mem(start, size); - if (ret) - goto out_remove; - - pfn = PFN_DOWN(start); - num_pfn = PFN_DOWN(size); - end_pfn = pfn + num_pfn; - - page = pfn_to_page(pfn); - memset(page, 0, num_pfn * sizeof(struct page)); - - for (; pfn < end_pfn; pfn++) { - page = pfn_to_page(pfn); - init_page_count(page); - reset_page_mapcount(page); - SetPageReserved(page); - INIT_LIST_HEAD(&page->lru); - } - goto out; - -out_remove: - __remove_shared_memory(seg); -out_free: - kfree(seg); -out: - mutex_unlock(&vmem_mutex); - return ret; -} - -/* - * map whole physical memory to virtual memory (identity mapping) - */ -void __init vmem_map_init(void) -{ - unsigned long map_size; - int i; - - map_size = ALIGN(max_low_pfn, MAX_ORDER_NR_PAGES) * sizeof(struct page); - vmalloc_end = PFN_ALIGN(VMALLOC_END_INIT) - PFN_ALIGN(map_size); - vmem_map = (struct page *) vmalloc_end; - NODE_DATA(0)->node_mem_map = vmem_map; - - for (i = 0; i < MEMORY_CHUNKS && memory_chunk[i].size > 0; i++) - vmem_add_mem(memory_chunk[i].addr, memory_chunk[i].size); -} - -/* - * Convert memory chunk array to a memory segment list so there is a single - * list that contains both r/w memory and shared memory segments. - */ -static int __init vmem_convert_memory_chunk(void) -{ - struct memory_segment *seg; - int i; - - mutex_lock(&vmem_mutex); - for (i = 0; i < MEMORY_CHUNKS && memory_chunk[i].size > 0; i++) { - if (!memory_chunk[i].size) - continue; - seg = kzalloc(sizeof(*seg), GFP_KERNEL); - if (!seg) - panic("Out of memory...\n"); - seg->start = memory_chunk[i].addr; - seg->size = memory_chunk[i].size; - insert_memory_segment(seg); - } - mutex_unlock(&vmem_mutex); - return 0; -} - -core_initcall(vmem_convert_memory_chunk); diff --git a/trunk/arch/sh/Kconfig b/trunk/arch/sh/Kconfig index 8e24c40662e3..d83d64af31f2 100644 --- a/trunk/arch/sh/Kconfig +++ b/trunk/arch/sh/Kconfig @@ -59,14 +59,6 @@ config LOCKDEP_SUPPORT bool default y -config ARCH_HAS_ILOG2_U32 - bool - default n - -config ARCH_HAS_ILOG2_U64 - bool - default n - source "init/Kconfig" menu "System type" diff --git a/trunk/arch/sh/mm/ioremap.c b/trunk/arch/sh/mm/ioremap.c index 90b494a0cf45..11d54c149821 100644 --- a/trunk/arch/sh/mm/ioremap.c +++ b/trunk/arch/sh/mm/ioremap.c @@ -16,13 +16,97 @@ #include #include #include -#include +#include #include #include #include #include #include +static inline void remap_area_pte(pte_t * pte, unsigned long address, + unsigned long size, unsigned long phys_addr, unsigned long flags) +{ + unsigned long end; + unsigned long pfn; + pgprot_t pgprot = __pgprot(pgprot_val(PAGE_KERNEL_NOCACHE) | flags); + + address &= ~PMD_MASK; + end = address + size; + if (end > PMD_SIZE) + end = PMD_SIZE; + if (address >= end) + BUG(); + pfn = phys_addr >> PAGE_SHIFT; + do { + if (!pte_none(*pte)) { + printk("remap_area_pte: page already exists\n"); + BUG(); + } + set_pte(pte, pfn_pte(pfn, pgprot)); + address += PAGE_SIZE; + pfn++; + pte++; + } while (address && (address < end)); +} + +static inline int remap_area_pmd(pmd_t * pmd, unsigned long address, + unsigned long size, unsigned long phys_addr, unsigned long flags) +{ + unsigned long end; + + address &= ~PGDIR_MASK; + end = address + size; + if (end > PGDIR_SIZE) + end = PGDIR_SIZE; + phys_addr -= address; + if (address >= end) + BUG(); + do { + pte_t * pte = pte_alloc_kernel(pmd, address); + if (!pte) + return -ENOMEM; + remap_area_pte(pte, address, end - address, address + phys_addr, flags); + address = (address + PMD_SIZE) & PMD_MASK; + pmd++; + } while (address && (address < end)); + return 0; +} + +int remap_area_pages(unsigned long address, unsigned long phys_addr, + unsigned long size, unsigned long flags) +{ + int error; + pgd_t * dir; + unsigned long end = address + size; + + phys_addr -= address; + dir = pgd_offset_k(address); + flush_cache_all(); + if (address >= end) + BUG(); + do { + pud_t *pud; + pmd_t *pmd; + + error = -ENOMEM; + + pud = pud_alloc(&init_mm, dir, address); + if (!pud) + break; + pmd = pmd_alloc(&init_mm, pud, address); + if (!pmd) + break; + if (remap_area_pmd(pmd, address, end - address, + phys_addr + address, flags)) + break; + error = 0; + address = (address + PGDIR_SIZE) & PGDIR_MASK; + dir++; + } while (address && (address < end)); + flush_tlb_all(); + return error; +} + /* * Remap an arbitrary physical address space into the kernel virtual * address space. Needed when the kernel wants to access high addresses @@ -37,7 +121,6 @@ void __iomem *__ioremap(unsigned long phys_addr, unsigned long size, { struct vm_struct * area; unsigned long offset, last_addr, addr, orig_addr; - pgprot_t pgprot; /* Don't allow wraparound or zero size */ last_addr = phys_addr + size - 1; @@ -107,9 +190,8 @@ void __iomem *__ioremap(unsigned long phys_addr, unsigned long size, } #endif - pgprot = __pgprot(pgprot_val(PAGE_KERNEL_NOCACHE) | flags); if (likely(size)) - if (ioremap_page_range(addr, addr + size, phys_addr, pgprot)) { + if (remap_area_pages(addr, phys_addr, size, flags)) { vunmap((void *)orig_addr); return NULL; } diff --git a/trunk/arch/sh/oprofile/op_model_sh7750.c b/trunk/arch/sh/oprofile/op_model_sh7750.c index 60402eec4b4d..c265185b22a7 100644 --- a/trunk/arch/sh/oprofile/op_model_sh7750.c +++ b/trunk/arch/sh/oprofile/op_model_sh7750.c @@ -142,7 +142,7 @@ static u64 sh7750_read_counter(int counter) */ static inline int to_counter(struct file *file) { - const unsigned char *name = file->f_path.dentry->d_parent->d_name.name; + const unsigned char *name = file->f_dentry->d_parent->d_name.name; return (int)simple_strtol(name, NULL, 10); } diff --git a/trunk/arch/sh64/Kconfig b/trunk/arch/sh64/Kconfig index 7bc0744b7ab6..58c678e06667 100644 --- a/trunk/arch/sh64/Kconfig +++ b/trunk/arch/sh64/Kconfig @@ -39,14 +39,6 @@ config RWSEM_XCHGADD_ALGORITHM config GENERIC_ISA_DMA bool -config ARCH_HAS_ILOG2_U32 - bool - default n - -config ARCH_HAS_ILOG2_U64 - bool - default n - source init/Kconfig menu "System type" diff --git a/trunk/arch/sh64/mm/ioremap.c b/trunk/arch/sh64/mm/ioremap.c index ff26c02511aa..80c56754f513 100644 --- a/trunk/arch/sh64/mm/ioremap.c +++ b/trunk/arch/sh64/mm/ioremap.c @@ -18,7 +18,7 @@ #include #include #include -#include +#include #include #include #include @@ -28,6 +28,96 @@ static void shmedia_mapioaddr(unsigned long, unsigned long); static unsigned long shmedia_ioremap(struct resource *, u32, int); +static inline void remap_area_pte(pte_t * pte, unsigned long address, unsigned long size, + unsigned long phys_addr, unsigned long flags) +{ + unsigned long end; + unsigned long pfn; + pgprot_t pgprot = __pgprot(_PAGE_PRESENT | _PAGE_READ | + _PAGE_WRITE | _PAGE_DIRTY | + _PAGE_ACCESSED | _PAGE_SHARED | flags); + + address &= ~PMD_MASK; + end = address + size; + if (end > PMD_SIZE) + end = PMD_SIZE; + if (address >= end) + BUG(); + + pfn = phys_addr >> PAGE_SHIFT; + + pr_debug(" %s: pte %p address %lx size %lx phys_addr %lx\n", + __FUNCTION__,pte,address,size,phys_addr); + + do { + if (!pte_none(*pte)) { + printk("remap_area_pte: page already exists\n"); + BUG(); + } + + set_pte(pte, pfn_pte(pfn, pgprot)); + address += PAGE_SIZE; + pfn++; + pte++; + } while (address && (address < end)); +} + +static inline int remap_area_pmd(pmd_t * pmd, unsigned long address, unsigned long size, + unsigned long phys_addr, unsigned long flags) +{ + unsigned long end; + + address &= ~PGDIR_MASK; + end = address + size; + + if (end > PGDIR_SIZE) + end = PGDIR_SIZE; + + phys_addr -= address; + + if (address >= end) + BUG(); + + do { + pte_t * pte = pte_alloc_kernel(pmd, address); + if (!pte) + return -ENOMEM; + remap_area_pte(pte, address, end - address, address + phys_addr, flags); + address = (address + PMD_SIZE) & PMD_MASK; + pmd++; + } while (address && (address < end)); + return 0; +} + +static int remap_area_pages(unsigned long address, unsigned long phys_addr, + unsigned long size, unsigned long flags) +{ + int error; + pgd_t * dir; + unsigned long end = address + size; + + phys_addr -= address; + dir = pgd_offset_k(address); + flush_cache_all(); + if (address >= end) + BUG(); + do { + pmd_t *pmd = pmd_alloc(&init_mm, dir, address); + error = -ENOMEM; + if (!pmd) + break; + if (remap_area_pmd(pmd, address, end - address, + phys_addr + address, flags)) { + break; + } + error = 0; + address = (address + PGDIR_SIZE) & PGDIR_MASK; + dir++; + } while (address && (address < end)); + flush_tlb_all(); + return 0; +} + /* * Generic mapping function (not visible outside): */ @@ -46,17 +136,12 @@ void * __ioremap(unsigned long phys_addr, unsigned long size, unsigned long flag void * addr; struct vm_struct * area; unsigned long offset, last_addr; - pgprot_t pgprot; /* Don't allow wraparound or zero size */ last_addr = phys_addr + size - 1; if (!size || last_addr < phys_addr) return NULL; - pgprot = __pgprot(_PAGE_PRESENT | _PAGE_READ | - _PAGE_WRITE | _PAGE_DIRTY | - _PAGE_ACCESSED | _PAGE_SHARED | flags); - /* * Mappings have to be page-aligned */ @@ -73,8 +158,7 @@ void * __ioremap(unsigned long phys_addr, unsigned long size, unsigned long flag return NULL; area->phys_addr = phys_addr; addr = area->addr; - if (ioremap_page_range((unsigned long)addr, (unsigned long)addr + size, - phys_addr, pgprot)) { + if (remap_area_pages((unsigned long)addr, phys_addr, size, flags)) { vunmap(addr); return NULL; } diff --git a/trunk/arch/sparc/Kconfig b/trunk/arch/sparc/Kconfig index d0dec1ea2eed..92a7c8a636d3 100644 --- a/trunk/arch/sparc/Kconfig +++ b/trunk/arch/sparc/Kconfig @@ -166,14 +166,6 @@ config ARCH_MAY_HAVE_PC_FDC bool default y -config ARCH_HAS_ILOG2_U32 - bool - default n - -config ARCH_HAS_ILOG2_U64 - bool - default n - config SUN_PM bool default y diff --git a/trunk/arch/sparc/kernel/sys_sunos.c b/trunk/arch/sparc/kernel/sys_sunos.c index 0bf8c165fc92..6f3ac548ee66 100644 --- a/trunk/arch/sparc/kernel/sys_sunos.c +++ b/trunk/arch/sparc/kernel/sys_sunos.c @@ -94,8 +94,8 @@ asmlinkage unsigned long sunos_mmap(unsigned long addr, unsigned long len, * SunOS is so stupid some times... hmph! */ if (file) { - if (imajor(file->f_path.dentry->d_inode) == MEM_MAJOR && - iminor(file->f_path.dentry->d_inode) == 5) { + if (imajor(file->f_dentry->d_inode) == MEM_MAJOR && + iminor(file->f_dentry->d_inode) == 5) { flags |= MAP_ANONYMOUS; fput(file); file = NULL; @@ -655,7 +655,7 @@ sunos_nfs_get_server_fd (int fd, struct sockaddr_in *addr) if (!file) goto out; - inode = file->f_path.dentry->d_inode; + inode = file->f_dentry->d_inode; socket = SOCKET_I(inode); local.sin_family = AF_INET; diff --git a/trunk/arch/sparc64/Kconfig b/trunk/arch/sparc64/Kconfig index d391d11f245a..b627f8dbcaad 100644 --- a/trunk/arch/sparc64/Kconfig +++ b/trunk/arch/sparc64/Kconfig @@ -34,14 +34,6 @@ config ARCH_MAY_HAVE_PC_FDC bool default y -config ARCH_HAS_ILOG2_U32 - bool - default n - -config ARCH_HAS_ILOG2_U64 - bool - default n - config AUDIT_ARCH bool default y diff --git a/trunk/arch/sparc64/kernel/binfmt_aout32.c b/trunk/arch/sparc64/kernel/binfmt_aout32.c index f205fc7cbcd0..d7caa60a0074 100644 --- a/trunk/arch/sparc64/kernel/binfmt_aout32.c +++ b/trunk/arch/sparc64/kernel/binfmt_aout32.c @@ -209,7 +209,7 @@ static int load_aout32_binary(struct linux_binprm * bprm, struct pt_regs * regs) if ((N_MAGIC(ex) != ZMAGIC && N_MAGIC(ex) != OMAGIC && N_MAGIC(ex) != QMAGIC && N_MAGIC(ex) != NMAGIC) || N_TRSIZE(ex) || N_DRSIZE(ex) || - bprm->file->f_path.dentry->d_inode->i_size < ex.a_text+ex.a_data+N_SYMSIZE(ex)+N_TXTOFF(ex)) { + bprm->file->f_dentry->d_inode->i_size < ex.a_text+ex.a_data+N_SYMSIZE(ex)+N_TXTOFF(ex)) { return -ENOEXEC; } @@ -349,7 +349,7 @@ static int load_aout32_library(struct file *file) int retval; struct exec ex; - inode = file->f_path.dentry->d_inode; + inode = file->f_dentry->d_inode; retval = -ENOEXEC; error = kernel_read(file, 0, (char *) &ex, sizeof(ex)); diff --git a/trunk/arch/sparc64/kernel/sys_sunos32.c b/trunk/arch/sparc64/kernel/sys_sunos32.c index 4446f66590fa..7da72d3b322a 100644 --- a/trunk/arch/sparc64/kernel/sys_sunos32.c +++ b/trunk/arch/sparc64/kernel/sys_sunos32.c @@ -83,7 +83,7 @@ asmlinkage u32 sunos_mmap(u32 addr, u32 len, u32 prot, u32 flags, u32 fd, u32 of file = fget(fd); if (!file) goto out; - inode = file->f_path.dentry->d_inode; + inode = file->f_dentry->d_inode; if (imajor(inode) == MEM_MAJOR && iminor(inode) == 5) { flags |= MAP_ANONYMOUS; fput(file); @@ -615,7 +615,7 @@ sunos_nfs_get_server_fd (int fd, struct sockaddr_in *addr) if (!file) return 0; - inode = file->f_path.dentry->d_inode; + inode = file->f_dentry->d_inode; socket = SOCKET_I(inode); local.sin_family = AF_INET; diff --git a/trunk/arch/sparc64/solaris/fs.c b/trunk/arch/sparc64/solaris/fs.c index 61be597bf430..12a940cc791f 100644 --- a/trunk/arch/sparc64/solaris/fs.c +++ b/trunk/arch/sparc64/solaris/fs.c @@ -449,7 +449,7 @@ asmlinkage int solaris_fstatvfs(unsigned int fd, u32 buf) error = -EBADF; file = fget(fd); if (file) { - error = report_statvfs(file->f_path.mnt, file->f_path.dentry->d_inode, buf); + error = report_statvfs(file->f_vfsmnt, file->f_dentry->d_inode, buf); fput(file); } @@ -481,7 +481,7 @@ asmlinkage int solaris_fstatvfs64(unsigned int fd, u32 buf) file = fget(fd); if (file) { lock_kernel(); - error = report_statvfs64(file->f_path.mnt, file->f_path.dentry->d_inode, buf); + error = report_statvfs64(file->f_vfsmnt, file->f_dentry->d_inode, buf); unlock_kernel(); fput(file); } diff --git a/trunk/arch/sparc64/solaris/ioctl.c b/trunk/arch/sparc64/solaris/ioctl.c index 330743c5b3d8..be0a054e3ed6 100644 --- a/trunk/arch/sparc64/solaris/ioctl.c +++ b/trunk/arch/sparc64/solaris/ioctl.c @@ -299,8 +299,8 @@ static inline int solaris_sockmod(unsigned int fd, unsigned int cmd, u32 arg) rcu_read_lock(); fdt = files_fdtable(current->files); if (! fdt->fd[fd] || - ! fdt->fd[fd]->f_path.dentry || - ! (ino = fdt->fd[fd]->f_path.dentry->d_inode) || + ! fdt->fd[fd]->f_dentry || + ! (ino = fdt->fd[fd]->f_dentry->d_inode) || ! S_ISSOCK(ino->i_mode)) { rcu_read_unlock(); return TBADF; @@ -480,7 +480,7 @@ static inline int solaris_S(struct file *filp, unsigned int fd, unsigned int cmd struct sol_socket_struct *sock; struct module_info *mi; - ino = filp->f_path.dentry->d_inode; + ino = filp->f_dentry->d_inode; if (!S_ISSOCK(ino->i_mode)) return -EBADF; sock = filp->private_data; diff --git a/trunk/arch/sparc64/solaris/misc.c b/trunk/arch/sparc64/solaris/misc.c index bca16e8c95c3..9ed997982f8d 100644 --- a/trunk/arch/sparc64/solaris/misc.c +++ b/trunk/arch/sparc64/solaris/misc.c @@ -77,7 +77,7 @@ static u32 do_solaris_mmap(u32 addr, u32 len, u32 prot, u32 flags, u32 fd, u64 o if (!file) goto out; else { - struct inode * inode = file->f_path.dentry->d_inode; + struct inode * inode = file->f_dentry->d_inode; if(imajor(inode) == MEM_MAJOR && iminor(inode) == 5) { flags |= MAP_ANONYMOUS; @@ -423,7 +423,9 @@ asmlinkage int solaris_procids(int cmd, s32 pid, s32 pgid) Solaris setpgrp and setsid? */ ret = sys_setpgid(0, 0); if (ret) return ret; - proc_clear_tty(current); + mutex_lock(&tty_mutex); + current->signal->tty = NULL; + mutex_unlock(&tty_mutex); return process_group(current); } case 2: /* getsid */ diff --git a/trunk/arch/sparc64/solaris/socksys.c b/trunk/arch/sparc64/solaris/socksys.c index 89a4757f192f..7c90e41fd3be 100644 --- a/trunk/arch/sparc64/solaris/socksys.c +++ b/trunk/arch/sparc64/solaris/socksys.c @@ -96,13 +96,13 @@ static int socksys_open(struct inode * inode, struct file * filp) * No shit. WTF is it supposed to do, anyway? * * Try instead: - * d_delete(filp->f_path.dentry), then d_instantiate with sock inode + * d_delete(filp->f_dentry), then d_instantiate with sock inode */ - dentry = filp->f_path.dentry; - filp->f_path.dentry = dget(fcheck(fd)->f_path.dentry); - filp->f_path.dentry->d_inode->i_rdev = inode->i_rdev; - filp->f_path.dentry->d_inode->i_flock = inode->i_flock; - SOCKET_I(filp->f_path.dentry->d_inode)->file = filp; + dentry = filp->f_dentry; + filp->f_dentry = dget(fcheck(fd)->f_dentry); + filp->f_dentry->d_inode->i_rdev = inode->i_rdev; + filp->f_dentry->d_inode->i_flock = inode->i_flock; + SOCKET_I(filp->f_dentry->d_inode)->file = filp; filp->f_op = &socksys_file_ops; sock = (struct sol_socket_struct*) mykmalloc(sizeof(struct sol_socket_struct), GFP_KERNEL); @@ -148,7 +148,7 @@ static unsigned int socksys_poll(struct file * filp, poll_table * wait) struct inode *ino; unsigned int mask = 0; - ino=filp->f_path.dentry->d_inode; + ino=filp->f_dentry->d_inode; if (ino && S_ISSOCK(ino->i_mode)) { struct sol_socket_struct *sock; sock = (struct sol_socket_struct*)filp->private_data; diff --git a/trunk/arch/sparc64/solaris/timod.c b/trunk/arch/sparc64/solaris/timod.c index a9d32ceabf26..b84e5456b025 100644 --- a/trunk/arch/sparc64/solaris/timod.c +++ b/trunk/arch/sparc64/solaris/timod.c @@ -147,7 +147,7 @@ static void timod_wake_socket(unsigned int fd) SOLD("wakeing socket"); fdt = files_fdtable(current->files); - sock = SOCKET_I(fdt->fd[fd]->f_path.dentry->d_inode); + sock = SOCKET_I(fdt->fd[fd]->f_dentry->d_inode); wake_up_interruptible(&sock->wait); read_lock(&sock->sk->sk_callback_lock); if (sock->fasync_list && !test_bit(SOCK_ASYNC_WAITDATA, &sock->flags)) @@ -361,7 +361,7 @@ int timod_putmsg(unsigned int fd, char __user *ctl_buf, int ctl_len, fdt = files_fdtable(current->files); filp = fdt->fd[fd]; - ino = filp->f_path.dentry->d_inode; + ino = filp->f_dentry->d_inode; sock = (struct sol_socket_struct *)filp->private_data; SOLD("entry"); if (get_user(ret, (int __user *)A(ctl_buf))) @@ -644,7 +644,7 @@ int timod_getmsg(unsigned int fd, char __user *ctl_buf, int ctl_maxlen, s32 __us SOLDD(("%u %p %d %p %p %d %p %d\n", fd, ctl_buf, ctl_maxlen, ctl_len, data_buf, data_maxlen, data_len, *flags_p)); fdt = files_fdtable(current->files); filp = fdt->fd[fd]; - ino = filp->f_path.dentry->d_inode; + ino = filp->f_dentry->d_inode; sock = (struct sol_socket_struct *)filp->private_data; SOLDD(("%p %p\n", sock->pfirst, sock->pfirst ? sock->pfirst->next : NULL)); if ( ctl_maxlen > 0 && !sock->pfirst && SOCKET_I(ino)->type == SOCK_STREAM @@ -865,7 +865,7 @@ asmlinkage int solaris_getmsg(unsigned int fd, u32 arg1, u32 arg2, u32 arg3) filp = fdt->fd[fd]; if(!filp) goto out; - ino = filp->f_path.dentry->d_inode; + ino = filp->f_dentry->d_inode; if (!ino || !S_ISSOCK(ino->i_mode)) goto out; @@ -933,7 +933,7 @@ asmlinkage int solaris_putmsg(unsigned int fd, u32 arg1, u32 arg2, u32 arg3) filp = fdt->fd[fd]; if(!filp) goto out; - ino = filp->f_path.dentry->d_inode; + ino = filp->f_dentry->d_inode; if (!ino) goto out; if (!S_ISSOCK(ino->i_mode) && diff --git a/trunk/arch/um/Kconfig b/trunk/arch/um/Kconfig index d32a80e6668c..5ac1f2963ae3 100644 --- a/trunk/arch/um/Kconfig +++ b/trunk/arch/um/Kconfig @@ -47,11 +47,6 @@ config GENERIC_CALIBRATE_DELAY bool default y -config GENERIC_BUG - bool - default y - depends on BUG - # Used in kernel/irq/manage.c and include/linux/irq.h config IRQ_RELEASE_METHOD bool diff --git a/trunk/arch/um/drivers/line.c b/trunk/arch/um/drivers/line.c index 83301e1ef67c..aa3090d05a8f 100644 --- a/trunk/arch/um/drivers/line.c +++ b/trunk/arch/um/drivers/line.c @@ -246,7 +246,7 @@ int line_write(struct tty_struct *tty, const unsigned char *buf, int len) return ret; } -void line_set_termios(struct tty_struct *tty, struct ktermios * old) +void line_set_termios(struct tty_struct *tty, struct termios * old) { /* nothing */ } diff --git a/trunk/arch/um/include/line.h b/trunk/arch/um/include/line.h index 5f232ae89fbb..214ee76c40df 100644 --- a/trunk/arch/um/include/line.h +++ b/trunk/arch/um/include/line.h @@ -76,7 +76,7 @@ extern int line_setup(struct line *lines, unsigned int sizeof_lines, extern int line_write(struct tty_struct *tty, const unsigned char *buf, int len); extern void line_put_char(struct tty_struct *tty, unsigned char ch); -extern void line_set_termios(struct tty_struct *tty, struct ktermios * old); +extern void line_set_termios(struct tty_struct *tty, struct termios * old); extern int line_chars_in_buffer(struct tty_struct *tty); extern void line_flush_buffer(struct tty_struct *tty); extern void line_flush_chars(struct tty_struct *tty); diff --git a/trunk/arch/um/kernel/exec.c b/trunk/arch/um/kernel/exec.c index 8d56ec6cca79..0561c43b4685 100644 --- a/trunk/arch/um/kernel/exec.c +++ b/trunk/arch/um/kernel/exec.c @@ -39,13 +39,12 @@ static long execve1(char *file, char __user * __user *argv, char __user *__user *env) { long error; - struct tty_struct *tty; #ifdef CONFIG_TTY_LOG mutex_lock(&tty_mutex); - tty = get_current_tty(); - if (tty) - log_exec(argv, tty); + task_lock(current); /* FIXME: is this needed ? */ + log_exec(argv, current->signal->tty); + task_unlock(current); mutex_unlock(&tty_mutex); #endif error = do_execve(file, argv, env, ¤t->thread.regs); diff --git a/trunk/arch/um/sys-i386/Makefile b/trunk/arch/um/sys-i386/Makefile index 098720be019a..0e32adf03be1 100644 --- a/trunk/arch/um/sys-i386/Makefile +++ b/trunk/arch/um/sys-i386/Makefile @@ -1,4 +1,4 @@ -obj-y = bug.o bugs.o checksum.o delay.o fault.o ksyms.o ldt.o ptrace.o \ +obj-y = bugs.o checksum.o delay.o fault.o ksyms.o ldt.o ptrace.o \ ptrace_user.o setjmp.o signal.o sigcontext.o syscalls.o sysrq.o \ sys_call_table.o tls.o diff --git a/trunk/arch/um/sys-i386/bug.c b/trunk/arch/um/sys-i386/bug.c deleted file mode 100644 index 200c8ba2879b..000000000000 --- a/trunk/arch/um/sys-i386/bug.c +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright (C) 2006 Jeff Dike (jdike@addtoit.com) - * Licensed under the GPL V2 - */ - -#include - -/* Mostly copied from i386/x86_86 - eliminated the eip < PAGE_OFFSET because - * that's not relevent in skas mode. - */ - -int is_valid_bugaddr(unsigned long eip) -{ - unsigned short ud2; - - if (probe_kernel_address((unsigned short __user *)eip, ud2)) - return 0; - - return ud2 == 0x0b0f; -} diff --git a/trunk/arch/um/sys-x86_64/Makefile b/trunk/arch/um/sys-x86_64/Makefile index 4d9e5efa6fb9..f41768b8e25e 100644 --- a/trunk/arch/um/sys-x86_64/Makefile +++ b/trunk/arch/um/sys-x86_64/Makefile @@ -4,7 +4,7 @@ # Licensed under the GPL # -obj-y = bug.o bugs.o delay.o fault.o ldt.o mem.o ptrace.o ptrace_user.o \ +obj-y = bugs.o delay.o fault.o ldt.o mem.o ptrace.o ptrace_user.o \ setjmp.o sigcontext.o signal.o syscalls.o syscall_table.o sysrq.o \ ksyms.o tls.o diff --git a/trunk/arch/um/sys-x86_64/bug.c b/trunk/arch/um/sys-x86_64/bug.c deleted file mode 100644 index 200c8ba2879b..000000000000 --- a/trunk/arch/um/sys-x86_64/bug.c +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright (C) 2006 Jeff Dike (jdike@addtoit.com) - * Licensed under the GPL V2 - */ - -#include - -/* Mostly copied from i386/x86_86 - eliminated the eip < PAGE_OFFSET because - * that's not relevent in skas mode. - */ - -int is_valid_bugaddr(unsigned long eip) -{ - unsigned short ud2; - - if (probe_kernel_address((unsigned short __user *)eip, ud2)) - return 0; - - return ud2 == 0x0b0f; -} diff --git a/trunk/arch/v850/Kconfig b/trunk/arch/v850/Kconfig index bcf825875d17..37ec644603ab 100644 --- a/trunk/arch/v850/Kconfig +++ b/trunk/arch/v850/Kconfig @@ -38,14 +38,6 @@ config TIME_LOW_RES bool default y -config ARCH_HAS_ILOG2_U32 - bool - default n - -config ARCH_HAS_ILOG2_U64 - bool - default n - # Turn off some random 386 crap that can affect device config config ISA bool diff --git a/trunk/arch/x86_64/Kconfig b/trunk/arch/x86_64/Kconfig index 3ac581d17202..bfbb9bcae123 100644 --- a/trunk/arch/x86_64/Kconfig +++ b/trunk/arch/x86_64/Kconfig @@ -96,19 +96,6 @@ config AUDIT_ARCH bool default y -config GENERIC_BUG - bool - default y - depends on BUG - -config ARCH_HAS_ILOG2_U32 - bool - default n - -config ARCH_HAS_ILOG2_U64 - bool - default n - source "init/Kconfig" diff --git a/trunk/arch/x86_64/ia32/ia32_aout.c b/trunk/arch/x86_64/ia32/ia32_aout.c index be87df506f39..396d3c100011 100644 --- a/trunk/arch/x86_64/ia32/ia32_aout.c +++ b/trunk/arch/x86_64/ia32/ia32_aout.c @@ -272,7 +272,7 @@ static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs) if ((N_MAGIC(ex) != ZMAGIC && N_MAGIC(ex) != OMAGIC && N_MAGIC(ex) != QMAGIC && N_MAGIC(ex) != NMAGIC) || N_TRSIZE(ex) || N_DRSIZE(ex) || - i_size_read(bprm->file->f_path.dentry->d_inode) < ex.a_text+ex.a_data+N_SYMSIZE(ex)+N_TXTOFF(ex)) { + i_size_read(bprm->file->f_dentry->d_inode) < ex.a_text+ex.a_data+N_SYMSIZE(ex)+N_TXTOFF(ex)) { return -ENOEXEC; } @@ -357,7 +357,7 @@ static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs) { printk(KERN_WARNING "fd_offset is not page aligned. Please convert program: %s\n", - bprm->file->f_path.dentry->d_name.name); + bprm->file->f_dentry->d_name.name); error_time = jiffies; } #endif @@ -440,7 +440,7 @@ static int load_aout_library(struct file *file) int retval; struct exec ex; - inode = file->f_path.dentry->d_inode; + inode = file->f_dentry->d_inode; retval = -ENOEXEC; error = kernel_read(file, 0, (char *) &ex, sizeof(ex)); @@ -471,7 +471,7 @@ static int load_aout_library(struct file *file) { printk(KERN_WARNING "N_TXTOFF is not page aligned. Please convert library: %s\n", - file->f_path.dentry->d_name.name); + file->f_dentry->d_name.name); error_time = jiffies; } #endif diff --git a/trunk/arch/x86_64/kernel/module.c b/trunk/arch/x86_64/kernel/module.c index a888e67f5874..9d0958ff547f 100644 --- a/trunk/arch/x86_64/kernel/module.c +++ b/trunk/arch/x86_64/kernel/module.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include @@ -174,12 +173,10 @@ int module_finalize(const Elf_Ehdr *hdr, lseg, lseg + locks->sh_size, tseg, tseg + text->sh_size); } - - return module_bug_finalize(hdr, sechdrs, me); + return 0; } void module_arch_cleanup(struct module *mod) { alternatives_smp_module_del(mod); - module_bug_cleanup(mod); } diff --git a/trunk/arch/x86_64/kernel/traps.c b/trunk/arch/x86_64/kernel/traps.c index b54ccc07f379..a1641ffdffcf 100644 --- a/trunk/arch/x86_64/kernel/traps.c +++ b/trunk/arch/x86_64/kernel/traps.c @@ -31,7 +31,6 @@ #include #include #include -#include #include #include @@ -525,15 +524,30 @@ void show_registers(struct pt_regs *regs) printk("\n"); } -int is_valid_bugaddr(unsigned long rip) -{ - unsigned short ud2; - - if (__copy_from_user(&ud2, (const void __user *) rip, sizeof(ud2))) - return 0; +void handle_BUG(struct pt_regs *regs) +{ + struct bug_frame f; + long len; + const char *prefix = ""; - return ud2 == 0x0b0f; -} + if (user_mode(regs)) + return; + if (__copy_from_user(&f, (const void __user *) regs->rip, + sizeof(struct bug_frame))) + return; + if (f.filename >= 0 || + f.ud2[0] != 0x0f || f.ud2[1] != 0x0b) + return; + len = __strnlen_user((char *)(long)f.filename, PATH_MAX) - 1; + if (len < 0 || len >= PATH_MAX) + f.filename = (int)(long)"unmapped filename"; + else if (len > 50) { + f.filename += len - 50; + prefix = "..."; + } + printk("----------- [cut here ] --------- [please bite here ] ---------\n"); + printk(KERN_ALERT "Kernel BUG at %s%.50s:%d\n", prefix, (char *)(long)f.filename, f.line); +} #ifdef CONFIG_BUG void out_of_line_bug(void) @@ -613,9 +627,7 @@ void die(const char * str, struct pt_regs * regs, long err) { unsigned long flags = oops_begin(); - if (!user_mode(regs)) - report_bug(regs->rip); - + handle_BUG(regs); __die(str, regs, err); oops_end(flags); do_exit(SIGSEGV); diff --git a/trunk/arch/x86_64/kernel/vmlinux.lds.S b/trunk/arch/x86_64/kernel/vmlinux.lds.S index 6c417788c54b..6a1f8f491e5d 100644 --- a/trunk/arch/x86_64/kernel/vmlinux.lds.S +++ b/trunk/arch/x86_64/kernel/vmlinux.lds.S @@ -51,8 +51,6 @@ SECTIONS RODATA - BUG_TABLE - . = ALIGN(PAGE_SIZE); /* Align data segment to page size boundary */ /* Data */ .data : AT(ADDR(.data) - LOAD_OFFSET) { diff --git a/trunk/arch/xtensa/Kconfig b/trunk/arch/xtensa/Kconfig index 9eccfbd1b536..c1e69a1f92a4 100644 --- a/trunk/arch/xtensa/Kconfig +++ b/trunk/arch/xtensa/Kconfig @@ -34,14 +34,6 @@ config GENERIC_HARDIRQS bool default y -config ARCH_HAS_ILOG2_U32 - bool - default n - -config ARCH_HAS_ILOG2_U64 - bool - default n - source "init/Kconfig" menu "Processor type and features" diff --git a/trunk/block/genhd.c b/trunk/block/genhd.c index 457fdac4c17d..653919d50cd4 100644 --- a/trunk/block/genhd.c +++ b/trunk/block/genhd.c @@ -417,34 +417,6 @@ static struct disk_attribute disk_attr_stat = { .show = disk_stats_read }; -#ifdef CONFIG_FAIL_MAKE_REQUEST - -static ssize_t disk_fail_store(struct gendisk * disk, - const char *buf, size_t count) -{ - int i; - - if (count > 0 && sscanf(buf, "%d", &i) > 0) { - if (i == 0) - disk->flags &= ~GENHD_FL_FAIL; - else - disk->flags |= GENHD_FL_FAIL; - } - - return count; -} -static ssize_t disk_fail_read(struct gendisk * disk, char *page) -{ - return sprintf(page, "%d\n", disk->flags & GENHD_FL_FAIL ? 1 : 0); -} -static struct disk_attribute disk_attr_fail = { - .attr = {.name = "make-it-fail", .mode = S_IRUGO | S_IWUSR }, - .store = disk_fail_store, - .show = disk_fail_read -}; - -#endif - static struct attribute * default_attrs[] = { &disk_attr_uevent.attr, &disk_attr_dev.attr, @@ -452,9 +424,6 @@ static struct attribute * default_attrs[] = { &disk_attr_removable.attr, &disk_attr_size.attr, &disk_attr_stat.attr, -#ifdef CONFIG_FAIL_MAKE_REQUEST - &disk_attr_fail.attr, -#endif NULL, }; diff --git a/trunk/block/ioctl.c b/trunk/block/ioctl.c index f6962b64660e..58aab630dfc1 100644 --- a/trunk/block/ioctl.c +++ b/trunk/block/ioctl.c @@ -72,7 +72,7 @@ static int blkpg_ioctl(struct block_device *bdev, struct blkpg_ioctl_arg __user bdevp = bdget_disk(disk, part); if (!bdevp) return -ENOMEM; - mutex_lock(&bdevp->bd_mutex); + mutex_lock_nested(&bdevp->bd_mutex, BD_MUTEX_PARTITION); if (bdevp->bd_openers) { mutex_unlock(&bdevp->bd_mutex); bdput(bdevp); @@ -82,7 +82,7 @@ static int blkpg_ioctl(struct block_device *bdev, struct blkpg_ioctl_arg __user fsync_bdev(bdevp); invalidate_bdev(bdevp, 0); - mutex_lock(&bdev->bd_mutex); + mutex_lock_nested(&bdev->bd_mutex, BD_MUTEX_WHOLE); delete_partition(disk, part); mutex_unlock(&bdev->bd_mutex); mutex_unlock(&bdevp->bd_mutex); @@ -290,7 +290,7 @@ int blkdev_ioctl(struct inode *inode, struct file *file, unsigned cmd, ENOIOCTLCMD for unknown ioctls. */ long compat_blkdev_ioctl(struct file *file, unsigned cmd, unsigned long arg) { - struct block_device *bdev = file->f_path.dentry->d_inode->i_bdev; + struct block_device *bdev = file->f_dentry->d_inode->i_bdev; struct gendisk *disk = bdev->bd_disk; int ret = -ENOIOCTLCMD; if (disk->fops->compat_ioctl) { diff --git a/trunk/block/ll_rw_blk.c b/trunk/block/ll_rw_blk.c index 4f83fd922377..31512cd9f3ad 100644 --- a/trunk/block/ll_rw_blk.c +++ b/trunk/block/ll_rw_blk.c @@ -28,7 +28,6 @@ #include #include #include -#include /* * for max sense size @@ -3057,42 +3056,6 @@ static void handle_bad_sector(struct bio *bio) set_bit(BIO_EOF, &bio->bi_flags); } -#ifdef CONFIG_FAIL_MAKE_REQUEST - -static DECLARE_FAULT_ATTR(fail_make_request); - -static int __init setup_fail_make_request(char *str) -{ - return setup_fault_attr(&fail_make_request, str); -} -__setup("fail_make_request=", setup_fail_make_request); - -static int should_fail_request(struct bio *bio) -{ - if ((bio->bi_bdev->bd_disk->flags & GENHD_FL_FAIL) || - (bio->bi_bdev->bd_part && bio->bi_bdev->bd_part->make_it_fail)) - return should_fail(&fail_make_request, bio->bi_size); - - return 0; -} - -static int __init fail_make_request_debugfs(void) -{ - return init_fault_attr_dentries(&fail_make_request, - "fail_make_request"); -} - -late_initcall(fail_make_request_debugfs); - -#else /* CONFIG_FAIL_MAKE_REQUEST */ - -static inline int should_fail_request(struct bio *bio) -{ - return 0; -} - -#endif /* CONFIG_FAIL_MAKE_REQUEST */ - /** * generic_make_request: hand a buffer to its device driver for I/O * @bio: The bio describing the location in memory and on the device. @@ -3178,9 +3141,6 @@ void generic_make_request(struct bio *bio) if (unlikely(test_bit(QUEUE_FLAG_DEAD, &q->queue_flags))) goto end_io; - if (should_fail_request(bio)) - goto end_io; - /* * If this device has partitions, remap block n * of partition p to block n+start(p) of the disk. diff --git a/trunk/drivers/Kconfig b/trunk/drivers/Kconfig index 4929e923b5c6..f39463418904 100644 --- a/trunk/drivers/Kconfig +++ b/trunk/drivers/Kconfig @@ -64,8 +64,6 @@ source "drivers/video/Kconfig" source "sound/Kconfig" -source "drivers/hid/Kconfig" - source "drivers/usb/Kconfig" source "drivers/mmc/Kconfig" diff --git a/trunk/drivers/Makefile b/trunk/drivers/Makefile index 50f76da598c9..67711770b1d9 100644 --- a/trunk/drivers/Makefile +++ b/trunk/drivers/Makefile @@ -77,5 +77,4 @@ 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/trunk/drivers/atm/Kconfig b/trunk/drivers/atm/Kconfig index 2ddd76fdbc43..cfa5af883e13 100644 --- a/trunk/drivers/atm/Kconfig +++ b/trunk/drivers/atm/Kconfig @@ -242,7 +242,6 @@ 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/trunk/drivers/atm/ambassador.c b/trunk/drivers/atm/ambassador.c index 3c372e08f77d..afa7d750a593 100644 --- a/trunk/drivers/atm/ambassador.c +++ b/trunk/drivers/atm/ambassador.c @@ -32,7 +32,6 @@ #include #include #include -#include #include #include @@ -2069,6 +2068,18 @@ 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; @@ -2090,9 +2101,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] = bitrev8(lower4>>(8*i)); + esi[i] = bit_swap (lower4>>(8*i)); else - esi[i] = bitrev8(upper2>>(8*(i-4))); + esi[i] = bit_swap (upper2>>(8*(i-4))); PRINTDM (DBG_INIT, " %02x", esi[i]); } diff --git a/trunk/drivers/block/Kconfig b/trunk/drivers/block/Kconfig index ce9cfcb6071c..85072446d772 100644 --- a/trunk/drivers/block/Kconfig +++ b/trunk/drivers/block/Kconfig @@ -431,18 +431,14 @@ config CDROM_PKTCDVD tristate "Packet writing on CD/DVD media" depends on !UML help - 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. + 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. - Currently only writing to CD-RW, DVD-RW, DVD+RW and DVDRAM discs - is possible. + Currently only writing to CD-RW, DVD-RW and DVD+RW discs is possible. DVD-RW disks must be in restricted overwrite mode. - See the file - 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/trunk/drivers/block/acsi_slm.c b/trunk/drivers/block/acsi_slm.c index e04be94d195c..8e41c87b026e 100644 --- a/trunk/drivers/block/acsi_slm.c +++ b/trunk/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_path.dentry->d_inode; + struct inode *node = file->f_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_path.dentry->d_inode; + struct inode *node = file->f_dentry->d_inode; int device = iminor(node); int n, filled, w, h; diff --git a/trunk/drivers/block/cciss.c b/trunk/drivers/block/cciss.c index ee159edb6b88..892e092afe9a 100644 --- a/trunk/drivers/block/cciss.c +++ b/trunk/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_path.dentry->d_inode, f, cmd, arg); + ret = cciss_ioctl(f->f_dentry->d_inode, f, cmd, arg); unlock_kernel(); return ret; } diff --git a/trunk/drivers/block/loop.c b/trunk/drivers/block/loop.c index 6b5b64207407..beab6d2643cb 100644 --- a/trunk/drivers/block/loop.c +++ b/trunk/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_path.mnt, file->f_path.dentry, &stat); + error = vfs_getattr(file->f_vfsmnt, file->f_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_path.dentry->d_inode; + struct inode *inode = file->f_dentry->d_inode; struct loop_device *lo = inode->i_bdev->bd_disk->private_data; int err; diff --git a/trunk/drivers/block/nbd.c b/trunk/drivers/block/nbd.c index 090796bef78f..7bf2cfbd6285 100644 --- a/trunk/drivers/block/nbd.c +++ b/trunk/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_path.dentry->d_inode; + inode = file->f_dentry->d_inode; if (S_ISSOCK(inode->i_mode)) { lo->file = file; lo->sock = SOCKET_I(inode); diff --git a/trunk/drivers/block/pktcdvd.c b/trunk/drivers/block/pktcdvd.c index 7c95c762950f..e45eaa264119 100644 --- a/trunk/drivers/block/pktcdvd.c +++ b/trunk/drivers/block/pktcdvd.c @@ -1,7 +1,6 @@ /* * Copyright (C) 2000 Jens Axboe * Copyright (C) 2001-2004 Peter Osterlund - * Copyright (C) 2006 Thomas Maier * * May be copied or modified under the terms of the GNU General Public * License. See linux/COPYING for more information. @@ -60,8 +59,6 @@ #include #include #include -#include -#include #include @@ -86,424 +83,9 @@ 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 - * - **********************************************************/ - -#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) { @@ -1311,7 +893,6 @@ 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"); @@ -1384,13 +965,7 @@ static int pkt_handle_queue(struct pktcdvd_device *pd) 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); @@ -2603,23 +2178,6 @@ 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. */ @@ -2739,9 +2297,6 @@ 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; } @@ -2881,33 +2436,36 @@ static struct block_device_operations pktcdvd_ops = { /* * Set up mapping from pktcdvd device to CD-ROM device. */ -static int pkt_setup_dev(dev_t dev, dev_t* pkt_dev) +static int pkt_setup_dev(struct pkt_ctrl_command *ctrl_cmd) { int idx; int ret = -ENOMEM; struct pktcdvd_device *pd; struct gendisk *disk; - - mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING); + dev_t dev = new_decode_dev(ctrl_cmd->dev); 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); - ret = -EBUSY; - goto out_mutex; + return -EBUSY; } pd = kzalloc(sizeof(struct pktcdvd_device), GFP_KERNEL); if (!pd) - goto out_mutex; + return ret; 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); @@ -2918,18 +2476,11 @@ static int pkt_setup_dev(dev_t dev, dev_t* pkt_dev) 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; - strcpy(disk->disk_name, pd->name); + sprintf(disk->disk_name, DRIVER_NAME"%d", idx); disk->private_data = pd; disk->queue = blk_alloc_queue(GFP_KERNEL); if (!disk->queue) @@ -2941,15 +2492,8 @@ static int pkt_setup_dev(dev_t dev, dev_t* pkt_dev) goto out_new_dev; add_disk(disk); - - pkt_sysfs_dev_new(pd); - pkt_debugfs_dev_new(pd); - pkt_devs[idx] = pd; - if (pkt_dev) - *pkt_dev = pd->pkt_dev; - - mutex_unlock(&ctl_mutex); + ctrl_cmd->pkt_dev = new_encode_dev(pd->pkt_dev); return 0; out_new_dev: @@ -2960,22 +2504,17 @@ static int pkt_setup_dev(dev_t dev, dev_t* pkt_dev) 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(dev_t pkt_dev) +static int pkt_remove_dev(struct pkt_ctrl_command *ctrl_cmd) { struct pktcdvd_device *pd; int idx; - int ret = 0; - - mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING); + dev_t pkt_dev = new_decode_dev(ctrl_cmd->pkt_dev); for (idx = 0; idx < MAX_WRITERS; idx++) { pd = pkt_devs[idx]; @@ -2984,22 +2523,15 @@ static int pkt_remove_dev(dev_t pkt_dev) } if (idx == MAX_WRITERS) { DPRINTK(DRIVER_NAME": dev not setup\n"); - ret = -ENXIO; - goto out; + return -ENXIO; } - if (pd->refcnt > 0) { - ret = -EBUSY; - goto out; - } + if (pd->refcnt > 0) + return -EBUSY; + 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); @@ -3009,24 +2541,18 @@ static int pkt_remove_dev(dev_t pkt_dev) 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); - -out: - mutex_unlock(&ctl_mutex); - return ret; + return 0; } static void pkt_get_status(struct pkt_ctrl_command *ctrl_cmd) { - struct pktcdvd_device *pd; - - mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING); - - pd = pkt_find_dev_from_minor(ctrl_cmd->dev_index); + struct pktcdvd_device *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); @@ -3035,8 +2561,6 @@ 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) @@ -3044,7 +2568,6 @@ 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; @@ -3056,16 +2579,21 @@ 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; - ret = pkt_setup_dev(new_decode_dev(ctrl_cmd.dev), &pkt_dev); - ctrl_cmd.pkt_dev = new_encode_dev(pkt_dev); + mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING); + ret = pkt_setup_dev(&ctrl_cmd); + mutex_unlock(&ctl_mutex); break; case PKT_CTRL_CMD_TEARDOWN: if (!capable(CAP_SYS_ADMIN)) return -EPERM; - ret = pkt_remove_dev(new_decode_dev(ctrl_cmd.pkt_dev)); + mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING); + ret = pkt_remove_dev(&ctrl_cmd); + mutex_unlock(&ctl_mutex); 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; @@ -3092,8 +2620,6 @@ 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) @@ -3107,25 +2633,18 @@ 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_misc; + goto out; } + 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: @@ -3137,10 +2656,6 @@ 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/trunk/drivers/char/Kconfig b/trunk/drivers/char/Kconfig index b10f4d8fdc7f..24f922f12783 100644 --- a/trunk/drivers/char/Kconfig +++ b/trunk/drivers/char/Kconfig @@ -201,21 +201,6 @@ 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/trunk/drivers/char/Makefile b/trunk/drivers/char/Makefile index fc110637ced6..b1fcdab90947 100644 --- a/trunk/drivers/char/Makefile +++ b/trunk/drivers/char/Makefile @@ -31,7 +31,6 @@ 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/trunk/drivers/char/amiserial.c b/trunk/drivers/char/amiserial.c index feb4ac802a0d..66086fa2d59a 100644 --- a/trunk/drivers/char/amiserial.c +++ b/trunk/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 ktermios *old); +static void change_speed(struct async_struct *info, struct termios *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 ktermios *old_termios) + struct termios *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 ktermios *old_termios) +static void rs_set_termios(struct tty_struct *tty, struct termios *old_termios) { struct async_struct *info = (struct async_struct *)tty->driver_data; unsigned long flags; diff --git a/trunk/drivers/char/cs5535_gpio.c b/trunk/drivers/char/cs5535_gpio.c index c02d9e99e050..8ce3f34cfc22 100644 --- a/trunk/drivers/char/cs5535_gpio.c +++ b/trunk/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_path.dentry->d_inode); + u32 m = iminor(file->f_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_path.dentry->d_inode); + u32 m = iminor(file->f_dentry->d_inode); u32 base = gpio_base + cs5535_lowhigh_base(m); int rd_bit = 1 << (m & 0x0f); int i; diff --git a/trunk/drivers/char/cyclades.c b/trunk/drivers/char/cyclades.c index 3ffa0807754c..acb2de5e3a98 100644 --- a/trunk/drivers/char/cyclades.c +++ b/trunk/drivers/char/cyclades.c @@ -1,6 +1,8 @@ #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 @@ -591,20 +593,18 @@ * */ -#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 @@ #undef CY_PCI_DEBUG #if 0 -#define PAUSE __asm__("nop") +#define PAUSE __asm__("nop"); #else -#define PAUSE do {} while (0) +#define PAUSE ; #endif /* @@ -663,7 +663,7 @@ 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 @@ #include #include -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,6 +698,8 @@ 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 @@ -711,28 +713,27 @@ 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. @@ -744,7 +745,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 @@ -756,42 +757,36 @@ 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. @@ -804,42 +799,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 *); @@ -847,9 +842,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); @@ -860,36 +855,41 @@ 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 - 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; - } + 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; + } #endif - return 0; -} /* serial_paranoia_check */ + return 0; +} /* serial_paranoia_check */ /* * This routine is used by the interrupt handler to schedule @@ -897,11 +897,13 @@ static inline int 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 @@ -928,36 +930,41 @@ 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); - tty_wakeup(tty); + 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); + } #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 */ @@ -972,339 +979,341 @@ 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; - } - udelay(10L); + /* Check to see that the previous command has completed */ + for(i = 0 ; i < 100 ; i++){ + if (cy_readb(base_addr+(CyCCR< 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< 0)? irq : 0; } -#endif /* CONFIG_ISA */ +#endif /* CONFIG_ISA */ -static void cyy_intr_chip(struct cyclades_card *cinfo, int chip, - void __iomem * base_addr, int status, int index) +/* 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) { - 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 */ + 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: rcvd intr, chip %d\n\r", chip); + printk("cyy_interrupt: spurious interrupt %d\n\r", irq); #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) { + 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]<card_lock); + save_xir = (u_char) cy_readb(base_addr+(CyRIR<first_line; + info = &cy_port[i]; + info->last_active = jiffies; + save_car = cy_readb(base_addr+(CyCAR<tty == 0){ + j = (cy_readb(base_addr+(CyRIVR<tty; + j = (cy_readb(base_addr+(CyRIVR<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<icount.rx++; + if (info->flags & ASYNC_SAK){ + do_SAK(tty); + } + }else if(data & CyFRAME){ + tty_insert_flip_char(tty, cy_readb(base_addr+(CyRDSR<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.frame_errs++; + }else if(data & CyPARITY){ + /* Pieces of seven... */ + tty_insert_flip_char(tty, cy_readb(base_addr+(CyRDSR<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<icount.rx++; info->idle_stats.overruns++; - } - } else { /* normal character reception */ - /* load # chars available from the chip */ - char_count = cy_readb(base_addr + - (CyRDCR << index)); + /* 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<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<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<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<first_line; + save_car = cy_readb(base_addr+(CyCAR<last_active = jiffies; + if(info->tty == 0){ + cy_writeb(base_addr+(CySRER<xmit_fifo_size; + + if(info->x_char) { /* send special char */ + outch = info->x_char; + cy_writeb(base_addr+(CyTDR<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<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<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<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<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<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); + */ + 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<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<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); - 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 { + 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<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<first_line]; + info->last_active = jiffies; + save_car = cy_readb(base_addr+(CyCAR<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++; - - 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); - } -} + /* 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++; -/* 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; - - /* 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); + cy_sched_event(info, Cy_EVENT_DELTA_WAKEUP); } - } - } 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 */ + 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<tty->hw_stopped = 1; + cy_writeb(base_addr+(CySRER<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<card_lock); + return IRQ_HANDLED; +} /* cyy_interrupt */ /***********************************************************/ /********* End of block of Cyclom-Y specific code **********/ @@ -1496,655 +1448,643 @@ static irqreturn_t 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 >= (int)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 >= 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); - } - /* Update rx_get */ - cy_writel(&buf_ctrl->rx_get, new_rx_get); + info->idle_stats.recv_idle = jiffies; + tty_schedule_flip(tty); } + /* 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); - } - /* Update tx_put */ - cy_writel(&buf_ctrl->tx_put, tx_put); + 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); + } } -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, ¶m) == 1) { - special_count = 0; - delta_count = 0; - info = &cy_port[channel + cinfo->first_line]; - if ((tty = info->tty) == 0) { - continue; + 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, ¶m) == 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); + } } - 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; + 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; - } - if (delta_count) - cy_sched_event(info, Cy_EVENT_DELTA_WAKEUP); - if (special_count) - tty_schedule_flip(tty); + 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); + } } #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]; + 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; - 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); + 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); - } - /* poll every 'cyz_polling_cycle' period */ - cyz_timerlist.expires = jiffies + cyz_polling_cycle; + if (!info->throttle) + cyz_handle_rx(info, ch_ctrl, buf_ctrl); + cyz_handle_tx(info, ch_ctrl, buf_ctrl); } - add_timer(&cyz_timerlist); -} /* cyz_poll */ + /* poll every 'cyz_polling_cycle' period */ + cyz_timerlist.expires = jiffies + cyz_polling_cycle; + } + add_timer(&cyz_timerlist); -#endif /* CONFIG_CYZ_INTR */ + return; +} /* cyz_poll */ + +#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]<default_timeout ? info->default_timeout : 0x02)); - /* 10ms rx timeout */ + cy_writeb(base_addr+(CyRTPR<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<flags |= ASYNC_INITIALIZED; + cy_writeb(base_addr+(CySRER<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_writel(&ch_ctrl[channel].op_mode, C_CH_ENABLE); + CY_LOCK(info, flags); + + 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 */ - /* 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); - } + 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); + } - /* 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); - } + /* 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); + } #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; - - CY_UNLOCK(info, flags); + 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); + } #ifdef CY_DEBUG_OPEN printk(" cyc startup done\n"); @@ -2154,165 +2094,165 @@ static int startup(struct cyclades_port *info) errout: CY_UNLOCK(info, flags); return retval; -} /* startup */ +} /* startup */ -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); +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]<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]<delta_msr_wait); + CY_LOCK(info, flags); - 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<tty || (info->tty->termios->c_cflag & HUPCL)) { + cy_writeb(base_addr+(CyMSVR1<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->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->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; - if (info->tty) { - set_bit(TTY_IO_ERROR, &info->tty->flags); - } - info->flags &= ~ASYNC_INITIALIZED; - - CY_UNLOCK(info, flags); - } + CY_UNLOCK(info, flags); + } #ifdef CY_DEBUG_OPEN - printk(" cyc shutdown done\n"); + printk(" cyc shutdown done\n"); #endif -} /* shutdown */ + return; +} /* shutdown */ + /* * ------------------------------------------------------------ @@ -2321,546 +2261,527 @@ static void 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); - } - return (info->flags & ASYNC_HUP_NOTIFY) ? -EAGAIN: -ERESTARTSYS; + 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); } - - /* - * 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); + 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); #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]<termios->c_cflag & CBAUD)){ + cy_writeb(base_addr+(CyCAR<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_UNLOCK(info, flags); - break; - } + CY_LOCK(info, flags); + cy_writeb(base_addr+(CyCAR<flags & ASYNC_CLOSING) + && (C_CLOCAL(tty) + || (cy_readb(base_addr+(CyMSVR1<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; - } + 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); - } + 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; + 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; } - - /* 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); - - 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; - } + 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); } -#endif /* CONFIG_CYZ_INTR */ - /* Make sure this Z port really exists in hardware */ - if (info->line > (cinfo->first_line + cinfo->nports - 1)) - return -ENODEV; + 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; + } #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) { + /* + * 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); + printk("cyc:cy_open returning after block_til_ready with %d\n", + retval); #endif - return retval; - } + return retval; + } - info->throttle = 0; + info->throttle = 0; #ifdef CY_DEBUG_OPEN - printk(" cyc:cy_open done\n"); - /**/ + printk(" cyc:cy_open done\n");/**/ #endif - return 0; -} /* cy_open */ + + 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]<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; + info->count = 0; + } + if (info->count) { CY_UNLOCK(info, flags); - if (info->closing_wait != CY_CLOSING_WAIT_NONE) { - tty_wait_until_sent(tty, info->closing_wait); + 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<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); } - 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 { + } 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 - } + /* 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); - shutdown(info); - if (tty->driver->flush_buffer) - tty->driver->flush_buffer(tty); - tty_ldisc_flush(tty); + if (info->close_delay) { + msleep_interruptible(jiffies_to_msecs(info->close_delay)); + } + wake_up_interruptible(&info->open_wait); 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); - CY_LOCK(info, flags); - } - info->flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING); - wake_up_interruptible(&info->close_wait); + } + 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); -} /* cy_close */ + CY_UNLOCK(info, flags); + return; +} /* cy_close */ + /* This routine gets called when tty_write has put something into * the write_queue. The characters may come from user space or @@ -2875,49 +2796,50 @@ static void 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; - - 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); + if (serial_paranoia_check(info, tty->name, "cy_write")){ + return 0; + } + + if (!info->xmit_buf) + return 0; - info->idle_stats.xmit_bytes += ret; - info->idle_stats.xmit_idle = jiffies; + 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_cnt && !tty->stopped && !tty->hw_stopped) { - start_xmit(info); - } - return ret; -} /* cy_write */ /* * This routine is called by the kernel to write a single @@ -2926,56 +2848,60 @@ static int 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 >= (int)(SERIAL_XMIT_SIZE - 1)) { - CY_UNLOCK(info, flags); - return; - } + CY_LOCK(info, flags); + if (info->xmit_cnt >= 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 (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 (info->xmit_cnt <= 0 || tty->stopped + || tty->hw_stopped || !info->xmit_buf) + return; + + start_xmit(info); +} /* cy_flush_chars */ - start_xmit(info); -} /* cy_flush_chars */ /* * This routine returns the numbers of characters the tty driver @@ -2983,70 +2909,75 @@ static void 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; + 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; - 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 */ + /* * ------------------------------------------------------------ @@ -3054,179 +2985,178 @@ static int 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; + 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; } - if (info->line == -1) { - return; + /* find the baud index */ + for (i = 0; i < 20; i++) { + if (baud == baud_table[i]) { + break; + } } - cflag = info->tty->termios->c_cflag; - iflag = info->tty->termios->c_iflag; + if (i == 20) { + i = 19; /* CD1400_MAX_SPEED */ + } - /* - * 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 ((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 */ + } } - - 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; + 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; + } + if (cflag & CLOCAL) + info->flags &= ~ASYNC_CHECK_CD; + else + info->flags |= ASYNC_CHECK_CD; /*********************************************** The hardware option, CyRtsAO, presents RTS when @@ -3238,319 +3168,300 @@ static void 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]<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); + CY_LOCK(info, flags); + cy_writeb(base_addr+(CyCAR<tco); + cy_writeb(base_addr+(CyTBPR<tbpr); + cy_writeb(base_addr+(CyRCOR<rco); + cy_writeb(base_addr+(CyRBPR<rbpr); + + /* set line characteristics according configuration */ + + cy_writeb(base_addr+(CySCHR1<tty)); + cy_writeb(base_addr+(CySCHR2<tty)); + cy_writeb(base_addr+(CyCOR1<cor1); + cy_writeb(base_addr+(CyCOR2<cor2); + cy_writeb(base_addr+(CyCOR3<cor3); + cy_writeb(base_addr+(CyCOR4<cor4); + cy_writeb(base_addr+(CyCOR5<cor5); + + cyy_issue_cmd(base_addr, + CyCOR_CHANGE|CyCOR1ch|CyCOR2ch|CyCOR3ch,index); + + cy_writeb(base_addr+(CyCAR<default_timeout + ? info->default_timeout + : 0x02)); /* 10ms rx timeout */ + + if (C_CLOCAL(info->tty)) { + /* without modem intr */ + cy_writeb(base_addr+(CySRER<0 modem transitions */ + if ((cflag & CRTSCTS) && info->rflow) { + cy_writeb(base_addr+(CyMCOR1<1 modem transitions */ + cy_writeb(base_addr+(CyMCOR2<0 modem transitions */ + if ((cflag & CRTSCTS) && info->rflow) { + cy_writeb(base_addr+(CyMCOR1<1 modem transitions */ + cy_writeb(base_addr+(CyMCOR2<rtsdtr_inv) { + cy_writeb(base_addr+(CyMSVR1<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); + cy_writeb(base_addr+(CyMSVR2<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<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<tty) { - clear_bit(TTY_IO_ERROR, &info->tty->flags); - } - CY_UNLOCK(info, flags); + 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; - } + } 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; + } - 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; - } + 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; + } - /* 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); - } + /* 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); + } - /* 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); + /* 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); - 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); - } + 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; - } + /* 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]; + 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 */ - 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 @@ -3562,452 +3473,441 @@ set_serial_info(struct cyclades_port *info, * 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; + + 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]<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; + + 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]<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); + if (info->rtsdtr_inv) { + result = ((status & CyRTS) ? TIOCM_DTR : 0) + | ((status & CyDTR) ? TIOCM_RTS : 0); } else { - base_addr = cy_card[card].base_addr; + 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; + } - if (cy_card[card].num_chips != -1) { - return -EINVAL; - } + 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; + } - 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 */ - } - 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]<rtsdtr_inv) { + cy_writeb(base_addr+(CyMSVR2<rtsdtr_inv) { + cy_writeb(base_addr+(CyMSVR2<rtsdtr_inv) { + cy_writeb(base_addr+(CyMSVR1<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<rtsdtr_inv) { + cy_writeb(base_addr+(CyMSVR1<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); + CY_UNLOCK(info, flags); + } + }else{ + return -ENODEV; } - return 0; -} /* cy_tiocmset */ + 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); + } + 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); - } - } - } else { - if (!info->breakoff) { - info->breakoff = 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 { - 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); - } + if (!info->breakoff) { + info->breakoff = 1; + if (!info->xmit_cnt) { + CY_UNLOCK(info, flags); + start_xmit(info); + CY_LOCK(info, flags); } + } } - CY_UNLOCK(info, flags); -} /* cy_break */ - -static int -get_mon_info(struct cyclades_port *info, struct cyclades_monitor __user * mon) -{ + } else { + int retval; - 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 (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 */ -static int set_threshold(struct cyclades_port *info, unsigned long value) +static int +get_mon_info(struct cyclades_port * info, struct cyclades_monitor __user * mon) { - 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; - 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 */ + 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 -get_threshold(struct cyclades_port *info, unsigned long __user * value) +set_threshold(struct cyclades_port * info, unsigned long value) { - void __iomem *base_addr; - int card, channel, chip, index; - unsigned long tmp; + 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]<cor3 &= ~CyREC_FIFO; + info->cor3 |= value & CyREC_FIFO; + + CY_LOCK(info, flags); + cy_writeb(base_addr+(CyCOR3<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); - - tmp = cy_readb(base_addr + (CyCOR3 << index)) & CyREC_FIFO; - return put_user(tmp, value); - } else { - /* Nothing to do! */ - return 0; - } -} /* get_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; + 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]<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) -{ - 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_default_threshold(struct cyclades_port * info, unsigned long __user *value) +{ + 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 get_timeout(struct cyclades_port *info, unsigned long __user * value) +static int +set_timeout(struct cyclades_port * info, unsigned long value) { - void __iomem *base_addr; - int card, channel, chip, index; - unsigned long tmp; + 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]<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 */ + CY_LOCK(info, flags); + cy_writeb(base_addr+(CyRTPR<default_timeout = value & 0xff; + 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]<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- @@ -4015,193 +3915,184 @@ 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; - break; - } - ret_val = 0; + if (copy_to_user(argp, &cy_card[info->card], + sizeof (struct cyclades_card))) { + ret_val = -EFAULT; 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); - /* note the counters on entry */ - cprev = info->icount; + cnow = info->icount; /* atomic copy */ 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 */ - CY_UNLOCK(info, flags); - - 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; + if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr && + cnow.dcd == cprev.dcd && cnow.cts == cprev.cts) { + return -EIO; /* no change => error */ } - /* 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. - */ + 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 @@ -4209,64 +4100,66 @@ 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 ktermios *old_termios) +static void +cy_set_termios(struct tty_struct *tty, struct termios * 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 -} /* cy_set_termios */ + + return; +} /* 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); } } @@ -4274,248 +4167,260 @@ static void 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 (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]<rtsdtr_inv) { + cy_writeb(base_addr+(CyMSVR2<throttle = 1; + } + } - if (I_IXOFF(tty)) { - if (!IS_CYC_Z(cy_card[card])) - cy_send_xchar(tty, STOP_CHAR(tty)); - else - info->throttle = 1; - } + return; +} /* cy_throttle */ - 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); + char buf[64]; + + printk("cyc:unthrottle %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_unthrottle")) { - return; - } + if (serial_paranoia_check(info, tty->name, "cy_unthrottle")){ + return; + } - if (I_IXOFF(tty)) { - if (info->x_char) - info->x_char = 0; - else - cy_send_xchar(tty, START_CHAR(tty)); + 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]<rtsdtr_inv) { + cy_writeb(base_addr+(CyMSVR2<throttle = 0; } + } + + return; +} /* cy_unthrottle */ - 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; + 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]<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<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; + 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]<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<driver_data; - int card, channel, retval; - unsigned long flags; +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; + #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; + if (serial_paranoia_check(info, tty->name, "cy_flush_buffer")) + return; - card = info->card; - channel = (info->line) - (cy_card[card].first_line); + card = info->card; + channel = (info->line) - (cy_card[card].first_line); + + CY_LOCK(info, flags); + info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; + CY_UNLOCK(info, flags); + if (IS_CYC_Z(cy_card[card])) { /* If it is a Z card, flush the on-board + buffers as well */ CY_LOCK(info, flags); - info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; + 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 */ - 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 */ + /* * --------------------------------------------------------------------- @@ -4528,84 +4433,82 @@ static void 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<= 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<= 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< 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); } /* @@ -4739,42 +4644,43 @@ static void 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); @@ -4782,497 +4688,482 @@ static int __init 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; - } + 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; + } - /* 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); + } + + /* 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) { + /* 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; - } - - /* 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; - } + 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; + } - 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); - } + /* 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); + } #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 but" - "no channels are available.\nChange " - "NR_PORTS in cyclades.c and recompile " - "kernel.\n", (ulong)cy_pci_phys2); - 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 ", + (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); + } - /* 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 - /* 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; + /* 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); + } } - } +#endif /* CONFIG_CYZ_INTR */ - 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); + + /* 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); #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 but no channels " - "are available.\nChange NR_PORTS in cyclades.c " - "and recompile kernel.\n", - (ulong) cy_pci_phys2); - 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 ", + (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); + } - /* 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 but no more cards can be " - "used.\nChange NR_CARDS in cyclades.c and recompile " - "kernel.\n", (unsigned int)Ze_phys2[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"); } - 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) { - printk("Cyclades driver " CY_VERSION "\n"); - printk(" built %s %s\n", __DATE__, __TIME__); -} /* show_version */ - -static int + 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 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; + 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); len += size; + pos = begin + len; - /* 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) { + len = 0; + begin = pos; } - *eof = 1; + if (pos > offset + length) + goto done; + } + *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! @@ -5294,288 +5185,290 @@ cyclades_get_proc_info(char *buf, char **start, off_t offset, int length, */ 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]<= 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 */ - - return 0; + } +#endif /* CONFIG_CYZ_INTR */ -} /* cy_init */ + return 0; + +} /* 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/trunk/drivers/char/drm/drm_ioc32.c b/trunk/drivers/char/drm/drm_ioc32.c index fafeb34f89d5..d4f874520082 100644 --- a/trunk/drivers/char/drm/drm_ioc32.c +++ b/trunk/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_path.dentry->d_inode, file, + err = drm_ioctl(file->f_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_path.dentry->d_inode, file, + err = drm_ioctl(file->f_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_path.dentry->d_inode, file, + return drm_ioctl(file->f_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_path.dentry->d_inode, file, + err = drm_ioctl(file->f_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_path.dentry->d_inode, file, + err = drm_ioctl(file->f_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_path.dentry->d_inode, file, + return drm_ioctl(file->f_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_path.dentry->d_inode, file, + err = drm_ioctl(file->f_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_path.dentry->d_inode, file, + err = drm_ioctl(file->f_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_path.dentry->d_inode, file, + err = drm_ioctl(file->f_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_path.dentry->d_inode, file, + return drm_ioctl(file->f_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_path.dentry->d_inode, file, + err = drm_ioctl(file->f_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_path.dentry->d_inode, file, + err = drm_ioctl(file->f_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_path.dentry->d_inode, file, + return drm_ioctl(file->f_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_path.dentry->d_inode, file, + return drm_ioctl(file->f_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_path.dentry->d_inode, file, + err = drm_ioctl(file->f_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_path.dentry->d_inode, file, + err = drm_ioctl(file->f_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_path.dentry->d_inode, file, + err = drm_ioctl(file->f_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_path.dentry->d_inode, file, + return drm_ioctl(file->f_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_path.dentry->d_inode, file, + err = drm_ioctl(file->f_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_path.dentry->d_inode, file, + err = drm_ioctl(file->f_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_path.dentry->d_inode, file, + drm_ioctl(file->f_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_path.dentry->d_inode, file, + return drm_ioctl(file->f_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_path.dentry->d_inode, file, + return drm_ioctl(file->f_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_path.dentry->d_inode, file, + return drm_ioctl(file->f_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_path.dentry->d_inode, file, + err = drm_ioctl(file->f_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_path.dentry->d_inode, file, + return drm_ioctl(file->f_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_path.dentry->d_inode, file, + err = drm_ioctl(file->f_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_path.dentry->d_inode, filp, cmd, arg); + ret = drm_ioctl(filp->f_dentry->d_inode, filp, cmd, arg); unlock_kernel(); return ret; diff --git a/trunk/drivers/char/drm/i915_ioc32.c b/trunk/drivers/char/drm/i915_ioc32.c index 1fe68a251b75..296248cdc767 100644 --- a/trunk/drivers/char/drm/i915_ioc32.c +++ b/trunk/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_path.dentry->d_inode, file, + return drm_ioctl(file->f_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_path.dentry->d_inode, file, + return drm_ioctl(file->f_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_path.dentry->d_inode, file, + return drm_ioctl(file->f_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_path.dentry->d_inode, file, + return drm_ioctl(file->f_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_path.dentry->d_inode, file, + return drm_ioctl(file->f_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_path.dentry->d_inode, filp, cmd, arg); + ret = drm_ioctl(filp->f_dentry->d_inode, filp, cmd, arg); unlock_kernel(); return ret; diff --git a/trunk/drivers/char/drm/mga_ioc32.c b/trunk/drivers/char/drm/mga_ioc32.c index 30d00478ddee..54a18eb2fc04 100644 --- a/trunk/drivers/char/drm/mga_ioc32.c +++ b/trunk/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_path.dentry->d_inode, file, + return drm_ioctl(file->f_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_path.dentry->d_inode, file, + return drm_ioctl(file->f_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_path.dentry->d_inode, file, + err = drm_ioctl(file->f_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_path.dentry->d_inode, filp, cmd, arg); + ret = drm_ioctl(filp->f_dentry->d_inode, filp, cmd, arg); unlock_kernel(); return ret; diff --git a/trunk/drivers/char/drm/r128_ioc32.c b/trunk/drivers/char/drm/r128_ioc32.c index d3cb676eee84..9dd6d4116e47 100644 --- a/trunk/drivers/char/drm/r128_ioc32.c +++ b/trunk/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_path.dentry->d_inode, file, + return drm_ioctl(file->f_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_path.dentry->d_inode, file, + return drm_ioctl(file->f_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_path.dentry->d_inode, file, + return drm_ioctl(file->f_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_path.dentry->d_inode, file, + return drm_ioctl(file->f_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_path.dentry->d_inode, filp, cmd, arg); + ret = drm_ioctl(filp->f_dentry->d_inode, filp, cmd, arg); unlock_kernel(); return ret; diff --git a/trunk/drivers/char/drm/radeon_ioc32.c b/trunk/drivers/char/drm/radeon_ioc32.c index 1f1f9cc055a4..0ccfd3618ff1 100644 --- a/trunk/drivers/char/drm/radeon_ioc32.c +++ b/trunk/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_path.dentry->d_inode, file, + return drm_ioctl(file->f_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_path.dentry->d_inode, file, + return drm_ioctl(file->f_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_path.dentry->d_inode, file, + return drm_ioctl(file->f_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_path.dentry->d_inode, file, + return drm_ioctl(file->f_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_path.dentry->d_inode, file, + return drm_ioctl(file->f_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_path.dentry->d_inode, file, + return drm_ioctl(file->f_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_path.dentry->d_inode, file, + return drm_ioctl(file->f_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_path.dentry->d_inode, file, + return drm_ioctl(file->f_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_path.dentry->d_inode, file, + return drm_ioctl(file->f_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_path.dentry->d_inode, filp, cmd, arg); + ret = drm_ioctl(filp->f_dentry->d_inode, filp, cmd, arg); unlock_kernel(); return ret; diff --git a/trunk/drivers/char/dsp56k.c b/trunk/drivers/char/dsp56k.c index 06f2dbf17710..9b1bf60ffbe7 100644 --- a/trunk/drivers/char/dsp56k.c +++ b/trunk/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_path.dentry->d_inode; + struct inode *inode = file->f_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_path.dentry->d_inode; + struct inode *inode = file->f_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_path.dentry->d_inode) & 0x0f; + int dev = iminor(file->f_dentry->d_inode) & 0x0f; switch(dev) { diff --git a/trunk/drivers/char/dtlk.c b/trunk/drivers/char/dtlk.c index d4005e94fe5f..5e82c3bad2e3 100644 --- a/trunk/drivers/char/dtlk.c +++ b/trunk/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_path.dentry->d_inode); + unsigned int minor = iminor(file->f_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_path.dentry->d_inode) != DTLK_MINOR) + if (iminor(file->f_dentry->d_inode) != DTLK_MINOR) return -EINVAL; while (1) { diff --git a/trunk/drivers/char/epca.c b/trunk/drivers/char/epca.c index a0f822c9d74d..7c71eb779802 100644 --- a/trunk/drivers/char/epca.c +++ b/trunk/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 ktermios *); +static void pc_set_termios(struct tty_struct *, struct termios *); static void do_softint(struct work_struct *work); static void pc_stop(struct tty_struct *); static void pc_start(struct tty_struct *); @@ -1236,8 +1236,6 @@ 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); @@ -1252,8 +1250,6 @@ 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); @@ -2003,7 +1999,7 @@ static void epcaparam(struct tty_struct *tty, struct channel *ch) { /* Begin epcaparam */ unsigned int cmdHead; - struct ktermios *ts; + struct termios *ts; struct board_chan __iomem *bc; unsigned mval, hflow, cflag, iflag; @@ -2118,7 +2114,7 @@ static void receive_data(struct channel *ch) { /* Begin receive_data */ unchar *rptr; - struct ktermios *ts = NULL; + struct termios *ts = NULL; struct tty_struct *tty; struct board_chan __iomem *bc; int dataToRead, wrapgap, bytesAvailable; @@ -2366,14 +2362,12 @@ 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 ktermios))) + if (copy_to_user(argp, tty->termios, sizeof(struct termios))) 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) @@ -2542,7 +2536,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 ktermios *old_termios) +static void pc_set_termios(struct tty_struct *tty, struct termios *old_termios) { /* Begin pc_set_termios */ struct channel *ch; diff --git a/trunk/drivers/char/esp.c b/trunk/drivers/char/esp.c index d1bfbaa2aa02..93b551962513 100644 --- a/trunk/drivers/char/esp.c +++ b/trunk/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 ktermios *old_termios) +static void rs_set_termios(struct tty_struct *tty, struct termios *old_termios) { struct esp_struct *info = (struct esp_struct *)tty->driver_data; unsigned long flags; diff --git a/trunk/drivers/char/generic_serial.c b/trunk/drivers/char/generic_serial.c index e769811e7417..87127e49c0db 100644 --- a/trunk/drivers/char/generic_serial.c +++ b/trunk/drivers/char/generic_serial.c @@ -718,11 +718,11 @@ static unsigned int gs_baudrates[] = { void gs_set_termios (struct tty_struct * tty, - struct ktermios * old_termios) + struct termios * old_termios) { struct gs_port *port; int baudrate, tmp, rv; - struct ktermios *tiosp; + struct termios *tiosp; func_enter(); diff --git a/trunk/drivers/char/hvcs.c b/trunk/drivers/char/hvcs.c index 207f7343ba60..d090622f1dea 100644 --- a/trunk/drivers/char/hvcs.c +++ b/trunk/drivers/char/hvcs.c @@ -192,13 +192,11 @@ 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 ktermios hvcs_tty_termios = { +static struct termios hvcs_tty_termios = { .c_iflag = IGNBRK | IGNPAR, .c_oflag = OPOST, .c_cflag = B38400 | CS8 | CREAD | HUPCL, - .c_cc = INIT_C_CC, - .c_ispeed = 38400, - .c_ospeed = 38400 + .c_cc = INIT_C_CC }; /* diff --git a/trunk/drivers/char/hvsi.c b/trunk/drivers/char/hvsi.c index d7806834fc17..82a41d5b4ed0 100644 --- a/trunk/drivers/char/hvsi.c +++ b/trunk/drivers/char/hvsi.c @@ -1161,8 +1161,6 @@ 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/trunk/drivers/char/ip2/ip2main.c b/trunk/drivers/char/ip2/ip2main.c index 7c70310a49b5..cda2459c1d60 100644 --- a/trunk/drivers/char/ip2/ip2main.c +++ b/trunk/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 ktermios *); +static void ip2_set_termios(PTTY, struct termios *); 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 ktermios *); +static void set_params (i2ChanStrPtr, struct termios *); 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 ktermios *old_termios ) +ip2_set_termios( PTTY tty, struct termios *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 ktermios *o_tios ) +set_params( i2ChanStrPtr pCh, struct termios *o_tios ) { tcflag_t cflag, iflag, lflag; char stop_char, start_char; - struct ktermios dummy; + struct termios 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_path.dentry->d_inode); + unsigned int minor = iminor(pFile->f_dentry->d_inode); int rc = 0; #ifdef IP2DEBUG_IPL diff --git a/trunk/drivers/char/ipmi/ipmi_devintf.c b/trunk/drivers/char/ipmi/ipmi_devintf.c index e257835a9a73..375d3378eecd 100644 --- a/trunk/drivers/char/ipmi/ipmi_devintf.c +++ b/trunk/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_path.dentry->d_inode, filep, + rc = ipmi_ioctl(filep->f_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_path.dentry->d_inode, filep, cmd, arg); + return ipmi_ioctl(filep->f_dentry->d_inode, filep, cmd, arg); } } #endif diff --git a/trunk/drivers/char/isicom.c b/trunk/drivers/char/isicom.c index 5a747e685993..1637c1d9a4ba 100644 --- a/trunk/drivers/char/isicom.c +++ b/trunk/drivers/char/isicom.c @@ -172,14 +172,12 @@ static struct pci_driver isicom_driver = { static int prev_card = 3; /* start servicing isi_card[0] */ static struct tty_driver *isicom_normal; -static DECLARE_COMPLETION(isi_timerdone); +static struct timer_list tx; 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[] = { @@ -195,9 +193,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 { @@ -516,11 +514,17 @@ static void isicom_tx(unsigned long _data) /* schedule another tx for hopefully in about 10ms */ sched_again: if (!re_schedule) { - complete(&isi_timerdone); + re_schedule = 2; return; } - mod_timer(&tx, jiffies + msecs_to_jiffies(10)); + init_timer(&tx); + tx.expires = jiffies + HZ/100; + tx.data = 0; + tx.function = isicom_tx; + add_timer(&tx); + + return; } /* Interrupt handlers */ @@ -558,12 +562,14 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id) base = card->base; spin_lock(&card->card_lock); - /* - * disable any interrupts from the PCI card and lower the - * interrupt line - */ - outw(0x8000, base+0x04); - ClearInterrupt(base); + if (card->isa == NO) { + /* + * 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); @@ -573,13 +579,19 @@ 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); - outw(0x0000, base+0x04); /* enable interrupts */ + if (card->isa) + ClearInterrupt(base); + else + outw(0x0000, base+0x04); /* enable interrupts */ spin_unlock(&card->card_lock); return IRQ_HANDLED; } port = card->ports + channel; if (!(port->flags & ASYNC_INITIALIZED)) { - outw(0x0000, base+0x04); /* enable interrupts */ + if (card->isa) + ClearInterrupt(base); + else + outw(0x0000, base+0x04); /* enable interrupts */ return IRQ_HANDLED; } @@ -592,7 +604,10 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id) } if (byte_count & 0x01) inw(base); - outw(0x0000, base+0x04); /* enable interrupts */ + if (card->isa == YES) + ClearInterrupt(base); + else + outw(0x0000, base+0x04); /* enable interrupts */ spin_unlock(&card->card_lock); return IRQ_HANDLED; } @@ -693,7 +708,10 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id) } tty_flip_buffer_push(tty); } - outw(0x0000, base+0x04); /* enable interrupts */ + if (card->isa == YES) + ClearInterrupt(base); + else + outw(0x0000, base+0x04); /* enable interrupts */ return IRQ_HANDLED; } @@ -946,8 +964,8 @@ static int isicom_open(struct tty_struct *tty, struct file *filp) { struct isi_port *port; struct isi_board *card; - unsigned int board; - int error, line; + unsigned int line, board; + int error; line = tty->index; if (line < 0 || line > PORT_COUNT-1) @@ -1381,7 +1399,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 ktermios *old_termios) + struct termios *old_termios) { struct isi_port *port = tty->driver_data; @@ -1502,6 +1520,37 @@ 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, @@ -1522,6 +1571,70 @@ 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) { @@ -1543,23 +1656,36 @@ static int __devinit reset_card(struct pci_dev *pdev, *signature = inw(base + 0x4) & 0xff; - 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; + 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; + } } switch (*signature) { case 0xa5: case 0xbb: case 0xdd: - board->port_count = (portcount == 4) ? 4 : 8; + board->port_count = (board->isa == NO && portcount == 4) ? 4 : + 8; board->shift_count = 12; break; case 0xcc: @@ -1705,11 +1831,6 @@ 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); @@ -1758,6 +1879,8 @@ static int __devinit load_firmware(struct pci_dev *pdev, /* * 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, @@ -1783,29 +1906,20 @@ 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 = 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; + retval = isicom_register_ioregion(pdev, index); + if (retval < 0) goto err; - } - 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); + retval = isicom_register_isr(pdev, index); + if (retval < 0) goto errunrr; - } retval = reset_card(pdev, index, &signature); if (retval < 0) @@ -1815,16 +1929,12 @@ 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: - pci_release_region(pdev, 3); + isicom_unregister_ioregion(pdev); err: board->base = 0; return retval; @@ -1833,21 +1943,18 @@ static int __devinit isicom_probe(struct pci_dev *pdev, 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); - pci_release_region(pdev, 3); + isicom_unregister_ioregion(pdev); } -static int __init isicom_init(void) +static int __devinit isicom_setup(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]; @@ -1868,65 +1975,66 @@ static int __init isicom_init(void) } isi_card[idx].base = 0; isi_card[idx].irq = 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); + if (!io[idx]) + continue; - retval = tty_register_driver(isicom_normal); - if (retval) { - pr_dbg("Couldn't register the dialin driver\n"); - goto err_puttty; + 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) + goto error; + retval = pci_register_driver(&isicom_driver); if (retval < 0) { printk(KERN_ERR "ISICOM: Unable to register pci driver.\n"); - goto err_unrtty; + goto errtty; } - mod_timer(&tx, jiffies + 1); + init_timer(&tx); + tx.expires = jiffies + 1; + tx.data = 0; + tx.function = isicom_tx; + re_schedule = 1; + add_timer(&tx); return 0; -err_unrtty: - tty_unregister_driver(isicom_normal); -err_puttty: - put_tty_driver(isicom_normal); +errtty: + isicom_unregister_tty_driver(); error: return retval; } static void __exit isicom_exit(void) { + unsigned int index = 0; + re_schedule = 0; - wait_for_completion_timeout(&isi_timerdone, HZ); + while (re_schedule != 2 && index++ < 100) + msleep(10); pci_unregister_driver(&isicom_driver); - tty_unregister_driver(isicom_normal); - put_tty_driver(isicom_normal); + isicom_unregister_tty_driver(); } -module_init(isicom_init); +module_init(isicom_setup); 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/trunk/drivers/char/istallion.c b/trunk/drivers/char/istallion.c index 68645d351873..8f591945ebd9 100644 --- a/trunk/drivers/char/istallion.c +++ b/trunk/drivers/char/istallion.c @@ -14,6 +14,14 @@ * 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. */ /*****************************************************************************/ @@ -33,7 +41,6 @@ #include #include #include -#include #include #include @@ -54,10 +61,21 @@ #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 @@ -101,16 +119,20 @@ * interrupt is required. */ -struct stlconf { +typedef struct { 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 unsigned int stli_nrbrds; +static int stli_nrbrds = ARRAY_SIZE(stli_brdconf); /* stli_lock must NOT be taken holding brd_lock */ static spinlock_t stli_lock; /* TTY logic lock */ @@ -172,11 +194,9 @@ 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 ktermios stli_deftermios = { +static struct termios stli_deftermios = { .c_cflag = (B9600 | CS8 | CREAD | HUPCL | CLOCAL), .c_cc = INIT_C_CC, - .c_ispeed = 9600, - .c_ospeed = 9600, }; /* @@ -185,12 +205,13 @@ static struct ktermios stli_deftermios = { */ static comstats_t stli_comstats; static combrd_t stli_brdstats; -static struct asystats stli_cdkstats; +static asystats_t stli_cdkstats; +static stlibrd_t stli_dummybrd; +static stliport_t stli_dummyport; /*****************************************************************************/ -static DEFINE_MUTEX(stli_brdslock); -static struct stlibrd *stli_brds[STL_MAXBRDS]; +static stlibrd_t *stli_brds[STL_MAXBRDS]; static int stli_shared; @@ -202,7 +223,6 @@ 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 @@ -235,18 +255,18 @@ static char *stli_brdnames[] = { "Brumby", "Brumby", "ONboard-EI", - NULL, + (char *) NULL, "ONboard", "ONboard-MC", "ONboard-MC", - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, + (char *) NULL, + (char *) NULL, + (char *) NULL, + (char *) NULL, + (char *) NULL, + (char *) NULL, + (char *) NULL, + (char *) NULL, "EasyIO", "EC8/32-AT", "EC8/32-MC", @@ -284,10 +304,12 @@ static char **stli_brdsp[] = { * parse any module arguments. */ -static struct stlibrdtype { +typedef struct stlibrdtype { char *name; int type; -} stli_brdstr[] = { +} stlibrdtype_t; + +static stlibrdtype_t stli_brdstr[] = { { "stallion", BRD_STALLION }, { "1", BRD_STALLION }, { "brumby", BRD_BRUMBY }, @@ -357,7 +379,6 @@ 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 @@ -375,11 +396,14 @@ 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 @@ -390,7 +414,7 @@ static struct pci_device_id istallion_pci_tbl[] = { }; MODULE_DEVICE_TABLE(pci, istallion_pci_tbl); -static struct pci_driver stli_pcidriver; +#endif /* CONFIG_PCI */ /*****************************************************************************/ @@ -590,11 +614,23 @@ static struct pci_driver stli_pcidriver; /*****************************************************************************/ +/* + * 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(struct stlconf *confp, char **argp); +static int stli_parsebrd(stlconf_t *confp, char **argp); +static int stli_init(void); 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); @@ -603,7 +639,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 ktermios *old); +static void stli_settermios(struct tty_struct *tty, struct termios *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); @@ -613,84 +649,86 @@ 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(struct stlibrd *brdp, struct stliport *portp, int portnr, char *pos); +static int stli_portinfo(stlibrd_t *brdp, stliport_t *portp, int portnr, char *pos); -static int stli_brdinit(struct stlibrd *brdp); -static int stli_startbrd(struct stlibrd *brdp); +static int stli_brdinit(stlibrd_t *brdp); +static int stli_startbrd(stlibrd_t *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(struct stlibrd *brdp, cdkhdr_t __iomem *hdrp); +static void stli_brdpoll(stlibrd_t *brdp, cdkhdr_t __iomem *hdrp); static void stli_poll(unsigned long arg); -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 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 void stli_dohangup(struct work_struct *); -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 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 void stli_mkasysigs(asysigs_t *sp, int dtr, int rts); static long stli_mktiocm(unsigned long sigvalue); -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 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 int stli_getbrdstats(combrd_t __user *bp); -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); +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); #endif -static int stli_initports(struct stlibrd *brdp); /*****************************************************************************/ @@ -728,19 +766,136 @@ static int stli_timeron; static struct class *istallion_class; -static void stli_cleanup_ports(struct stlibrd *brdp) +/* + * 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) { - 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); + 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; } + val = (val * base) + c; } + return(val); } /*****************************************************************************/ @@ -749,16 +904,16 @@ static void stli_cleanup_ports(struct stlibrd *brdp) * Parse the supplied argument string, into the board conf struct. */ -static int stli_parsebrd(struct stlconf *confp, char **argp) +static int stli_parsebrd(stlconf_t *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) @@ -771,9 +926,9 @@ static int stli_parsebrd(struct stlconf *confp, char **argp) confp->brdtype = stli_brdstr[i].type; if (argp[1] != NULL && *argp[1] != 0) - confp->ioaddr1 = simple_strtoul(argp[1], NULL, 0); + confp->ioaddr1 = stli_atol(argp[1]); if (argp[2] != NULL && *argp[2] != 0) - confp->memaddr = simple_strtoul(argp[2], NULL, 0); + confp->memaddr = stli_atol(argp[2]); return(1); } @@ -781,10 +936,10 @@ static int stli_parsebrd(struct stlconf *confp, char **argp) static int stli_open(struct tty_struct *tty, struct file *filp) { - struct stlibrd *brdp; - struct stliport *portp; - unsigned int minordev, brdnr, portnr; - int rc; + stlibrd_t *brdp; + stliport_t *portp; + unsigned int minordev; + int brdnr, portnr, rc; minordev = tty->index; brdnr = MINOR2BRD(minordev); @@ -796,7 +951,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 > brdp->nrports) + if ((portnr < 0) || (portnr > brdp->nrports)) return -ENODEV; portp = brdp->ports[portnr]; @@ -876,8 +1031,8 @@ static int stli_open(struct tty_struct *tty, struct file *filp) static void stli_close(struct tty_struct *tty, struct file *filp) { - struct stlibrd *brdp; - struct stliport *portp; + stlibrd_t *brdp; + stliport_t *portp; unsigned long flags; portp = tty->driver_data; @@ -954,7 +1109,7 @@ static void stli_close(struct tty_struct *tty, struct file *filp) * this still all happens pretty quickly. */ -static int stli_initopen(struct stlibrd *brdp, struct stliport *portp) +static int stli_initopen(stlibrd_t *brdp, stliport_t *portp) { struct tty_struct *tty; asynotify_t nt; @@ -1002,7 +1157,7 @@ static int stli_initopen(struct stlibrd *brdp, struct stliport *portp) * to overlap. */ -static int stli_rawopen(struct stlibrd *brdp, struct stliport *portp, unsigned long arg, int wait) +static int stli_rawopen(stlibrd_t *brdp, stliport_t *portp, unsigned long arg, int wait) { cdkhdr_t __iomem *hdrp; cdkctrl_t __iomem *cp; @@ -1073,7 +1228,7 @@ static int stli_rawopen(struct stlibrd *brdp, struct stliport *portp, unsigned l * wait is true then must have user context (to sleep). */ -static int stli_rawclose(struct stlibrd *brdp, struct stliport *portp, unsigned long arg, int wait) +static int stli_rawclose(stlibrd_t *brdp, stliport_t *portp, unsigned long arg, int wait) { cdkhdr_t __iomem *hdrp; cdkctrl_t __iomem *cp; @@ -1137,7 +1292,7 @@ static int stli_rawclose(struct stlibrd *brdp, struct stliport *portp, unsigned * to complete (as opposed to initiating the command then returning). */ -static int stli_cmdwait(struct stlibrd *brdp, struct stliport *portp, unsigned long cmd, void *arg, int size, int copyback) +static int stli_cmdwait(stlibrd_t *brdp, stliport_t *portp, unsigned long cmd, void *arg, int size, int copyback) { wait_event_interruptible(portp->raw_wait, !test_bit(ST_CMDING, &portp->state)); @@ -1163,16 +1318,16 @@ static int stli_cmdwait(struct stlibrd *brdp, struct stliport *portp, unsigned l * waiting for the command to complete - so must have user context. */ -static int stli_setport(struct stliport *portp) +static int stli_setport(stliport_t *portp) { - struct stlibrd *brdp; + stlibrd_t *brdp; asyport_t aport; if (portp == NULL) return -ENODEV; if (portp->tty == NULL) return -ENODEV; - if (portp->brdnr >= stli_nrbrds) + if (portp->brdnr < 0 && portp->brdnr >= stli_nrbrds) return -ENODEV; brdp = stli_brds[portp->brdnr]; if (brdp == NULL) @@ -1189,7 +1344,7 @@ static int stli_setport(struct stliport *portp) * maybe because if we are clocal then we don't need to wait... */ -static int stli_waitcarrier(struct stlibrd *brdp, struct stliport *portp, struct file *filp) +static int stli_waitcarrier(stlibrd_t *brdp, stliport_t *portp, struct file *filp) { unsigned long flags; int rc, doclocal; @@ -1254,8 +1409,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; - struct stliport *portp; - struct stlibrd *brdp; + stliport_t *portp; + stlibrd_t *brdp; unsigned int len, stlen, head, tail, size; unsigned long flags; @@ -1264,7 +1419,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 >= stli_nrbrds) + if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds)) return 0; brdp = stli_brds[portp->brdnr]; if (brdp == NULL) @@ -1290,12 +1445,12 @@ static int stli_write(struct tty_struct *tty, const unsigned char *buf, int coun stlen = len; } - len = min(len, (unsigned int)count); + len = MIN(len, 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; @@ -1361,8 +1516,8 @@ static void stli_flushchars(struct tty_struct *tty) unsigned char __iomem *bits; cdkasy_t __iomem *ap; struct tty_struct *cooktty; - struct stliport *portp; - struct stlibrd *brdp; + stliport_t *portp; + stlibrd_t *brdp; unsigned int len, stlen, head, tail, size, count, cooksize; unsigned char *buf; unsigned char __iomem *shbuf; @@ -1386,7 +1541,7 @@ static void stli_flushchars(struct tty_struct *tty) portp = tty->driver_data; if (portp == NULL) return; - if (portp->brdnr >= stli_nrbrds) + if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds)) return; brdp = stli_brds[portp->brdnr]; if (brdp == NULL) @@ -1409,13 +1564,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; @@ -1449,8 +1604,8 @@ static void stli_flushchars(struct tty_struct *tty) static int stli_writeroom(struct tty_struct *tty) { cdkasyrq_t __iomem *rp; - struct stliport *portp; - struct stlibrd *brdp; + stliport_t *portp; + stlibrd_t *brdp; unsigned int head, tail, len; unsigned long flags; @@ -1464,7 +1619,7 @@ static int stli_writeroom(struct tty_struct *tty) portp = tty->driver_data; if (portp == NULL) return 0; - if (portp->brdnr >= stli_nrbrds) + if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds)) return 0; brdp = stli_brds[portp->brdnr]; if (brdp == NULL) @@ -1502,8 +1657,8 @@ static int stli_writeroom(struct tty_struct *tty) static int stli_charsinbuffer(struct tty_struct *tty) { cdkasyrq_t __iomem *rp; - struct stliport *portp; - struct stlibrd *brdp; + stliport_t *portp; + stlibrd_t *brdp; unsigned int head, tail, len; unsigned long flags; @@ -1512,7 +1667,7 @@ static int stli_charsinbuffer(struct tty_struct *tty) portp = tty->driver_data; if (portp == NULL) return 0; - if (portp->brdnr >= stli_nrbrds) + if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds)) return 0; brdp = stli_brds[portp->brdnr]; if (brdp == NULL) @@ -1540,10 +1695,10 @@ static int stli_charsinbuffer(struct tty_struct *tty) * Generate the serial struct info. */ -static int stli_getserial(struct stliport *portp, struct serial_struct __user *sp) +static int stli_getserial(stliport_t *portp, struct serial_struct __user *sp) { struct serial_struct sio; - struct stlibrd *brdp; + stlibrd_t *brdp; memset(&sio, 0, sizeof(struct serial_struct)); sio.type = PORT_UNKNOWN; @@ -1573,7 +1728,7 @@ static int stli_getserial(struct stliport *portp, struct serial_struct __user *s * just quietly ignore any requests to change irq, etc. */ -static int stli_setserial(struct stliport *portp, struct serial_struct __user *sp) +static int stli_setserial(stliport_t *portp, struct serial_struct __user *sp) { struct serial_struct sio; int rc; @@ -1604,13 +1759,13 @@ static int stli_setserial(struct stliport *portp, struct serial_struct __user *s static int stli_tiocmget(struct tty_struct *tty, struct file *file) { - struct stliport *portp = tty->driver_data; - struct stlibrd *brdp; + stliport_t *portp = tty->driver_data; + stlibrd_t *brdp; int rc; if (portp == NULL) return -ENODEV; - if (portp->brdnr >= stli_nrbrds) + if (portp->brdnr < 0 || portp->brdnr >= stli_nrbrds) return 0; brdp = stli_brds[portp->brdnr]; if (brdp == NULL) @@ -1628,13 +1783,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) { - struct stliport *portp = tty->driver_data; - struct stlibrd *brdp; + stliport_t *portp = tty->driver_data; + stlibrd_t *brdp; int rts = -1, dtr = -1; if (portp == NULL) return -ENODEV; - if (portp->brdnr >= stli_nrbrds) + if (portp->brdnr < 0 || portp->brdnr >= stli_nrbrds) return 0; brdp = stli_brds[portp->brdnr]; if (brdp == NULL) @@ -1659,8 +1814,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) { - struct stliport *portp; - struct stlibrd *brdp; + stliport_t *portp; + stlibrd_t *brdp; unsigned int ival; int rc; void __user *argp = (void __user *)arg; @@ -1668,7 +1823,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 >= stli_nrbrds) + if (portp->brdnr < 0 || portp->brdnr >= stli_nrbrds) return 0; brdp = stli_brds[portp->brdnr]; if (brdp == NULL) @@ -1734,11 +1889,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 ktermios *old) +static void stli_settermios(struct tty_struct *tty, struct termios *old) { - struct stliport *portp; - struct stlibrd *brdp; - struct ktermios *tiosp; + stliport_t *portp; + stlibrd_t *brdp; + struct termios *tiosp; asyport_t aport; if (tty == NULL) @@ -1746,7 +1901,7 @@ static void stli_settermios(struct tty_struct *tty, struct ktermios *old) portp = tty->driver_data; if (portp == NULL) return; - if (portp->brdnr >= stli_nrbrds) + if (portp->brdnr < 0 || portp->brdnr >= stli_nrbrds) return; brdp = stli_brds[portp->brdnr]; if (brdp == NULL) @@ -1782,7 +1937,7 @@ static void stli_settermios(struct tty_struct *tty, struct ktermios *old) static void stli_throttle(struct tty_struct *tty) { - struct stliport *portp = tty->driver_data; + stliport_t *portp = tty->driver_data; if (portp == NULL) return; set_bit(ST_RXSTOP, &portp->state); @@ -1798,7 +1953,7 @@ static void stli_throttle(struct tty_struct *tty) static void stli_unthrottle(struct tty_struct *tty) { - struct stliport *portp = tty->driver_data; + stliport_t *portp = tty->driver_data; if (portp == NULL) return; clear_bit(ST_RXSTOP, &portp->state); @@ -1837,7 +1992,7 @@ static void stli_start(struct tty_struct *tty) static void stli_dohangup(struct work_struct *ugly_api) { - struct stliport *portp = container_of(ugly_api, struct stliport, tqhangup); + stliport_t *portp = container_of(ugly_api, stliport_t, tqhangup); if (portp->tty != NULL) { tty_hangup(portp->tty); } @@ -1854,14 +2009,14 @@ static void stli_dohangup(struct work_struct *ugly_api) static void stli_hangup(struct tty_struct *tty) { - struct stliport *portp; - struct stlibrd *brdp; + stliport_t *portp; + stlibrd_t *brdp; unsigned long flags; portp = tty->driver_data; if (portp == NULL) return; - if (portp->brdnr >= stli_nrbrds) + if (portp->brdnr < 0 || portp->brdnr >= stli_nrbrds) return; brdp = stli_brds[portp->brdnr]; if (brdp == NULL) @@ -1907,14 +2062,14 @@ static void stli_hangup(struct tty_struct *tty) static void stli_flushbuffer(struct tty_struct *tty) { - struct stliport *portp; - struct stlibrd *brdp; + stliport_t *portp; + stlibrd_t *brdp; unsigned long ftype, flags; portp = tty->driver_data; if (portp == NULL) return; - if (portp->brdnr >= stli_nrbrds) + if (portp->brdnr < 0 || portp->brdnr >= stli_nrbrds) return; brdp = stli_brds[portp->brdnr]; if (brdp == NULL) @@ -1944,14 +2099,14 @@ static void stli_flushbuffer(struct tty_struct *tty) static void stli_breakctl(struct tty_struct *tty, int state) { - struct stlibrd *brdp; - struct stliport *portp; + stlibrd_t *brdp; + stliport_t *portp; long arg; portp = tty->driver_data; if (portp == NULL) return; - if (portp->brdnr >= stli_nrbrds) + if (portp->brdnr < 0 || portp->brdnr >= stli_nrbrds) return; brdp = stli_brds[portp->brdnr]; if (brdp == NULL) @@ -1965,7 +2120,7 @@ static void stli_breakctl(struct tty_struct *tty, int state) static void stli_waituntilsent(struct tty_struct *tty, int timeout) { - struct stliport *portp; + stliport_t *portp; unsigned long tend; if (tty == NULL) @@ -1991,14 +2146,14 @@ static void stli_waituntilsent(struct tty_struct *tty, int timeout) static void stli_sendxchar(struct tty_struct *tty, char ch) { - struct stlibrd *brdp; - struct stliport *portp; + stlibrd_t *brdp; + stliport_t *portp; asyctrl_t actrl; portp = tty->driver_data; if (portp == NULL) return; - if (portp->brdnr >= stli_nrbrds) + if (portp->brdnr < 0 || portp->brdnr >= stli_nrbrds) return; brdp = stli_brds[portp->brdnr]; if (brdp == NULL) @@ -2026,7 +2181,7 @@ static void stli_sendxchar(struct tty_struct *tty, char ch) * short then padded with spaces). */ -static int stli_portinfo(struct stlibrd *brdp, struct stliport *portp, int portnr, char *pos) +static int stli_portinfo(stlibrd_t *brdp, stliport_t *portp, int portnr, char *pos) { char *sp, *uart; int rc, cnt; @@ -2089,9 +2244,9 @@ static int stli_portinfo(struct stlibrd *brdp, struct stliport *portp, int portn static int stli_readproc(char *page, char **start, off_t off, int count, int *eof, void *data) { - struct stlibrd *brdp; - struct stliport *portp; - unsigned int brdnr, portnr, totalport; + stlibrd_t *brdp; + stliport_t *portp; + int brdnr, portnr, totalport; int curoff, maxoff; char *pos; @@ -2161,7 +2316,7 @@ static int stli_readproc(char *page, char **start, off_t off, int count, int *eo * entry point) */ -static void __stli_sendcmd(struct stlibrd *brdp, struct stliport *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) { cdkhdr_t __iomem *hdrp; cdkctrl_t __iomem *cp; @@ -2197,7 +2352,7 @@ static void __stli_sendcmd(struct stlibrd *brdp, struct stliport *portp, unsigne spin_unlock_irqrestore(&brd_lock, flags); } -static void stli_sendcmd(struct stlibrd *brdp, struct stliport *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) { unsigned long flags; @@ -2216,7 +2371,7 @@ static void stli_sendcmd(struct stlibrd *brdp, struct stliport *portp, unsigned * more chars to unload. */ -static void stli_read(struct stlibrd *brdp, struct stliport *portp) +static void stli_read(stlibrd_t *brdp, stliport_t *portp) { cdkasyrq_t __iomem *rp; char __iomem *shbuf; @@ -2251,7 +2406,7 @@ static void stli_read(struct stlibrd *brdp, struct stliport *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; @@ -2278,7 +2433,7 @@ static void stli_read(struct stlibrd *brdp, struct stliport *portp) * difficult to deal with them here. */ -static void stli_dodelaycmd(struct stliport *portp, cdkctrl_t __iomem *cp) +static void stli_dodelaycmd(stliport_t *portp, cdkctrl_t __iomem *cp) { int cmd; @@ -2326,7 +2481,7 @@ static void stli_dodelaycmd(struct stliport *portp, cdkctrl_t __iomem *cp) * then port is still busy, otherwise no longer busy. */ -static int stli_hostcmd(struct stlibrd *brdp, struct stliport *portp) +static int stli_hostcmd(stlibrd_t *brdp, stliport_t *portp) { cdkasy_t __iomem *ap; cdkctrl_t __iomem *cp; @@ -2473,9 +2628,9 @@ static int stli_hostcmd(struct stlibrd *brdp, struct stliport *portp) * at the cdk header structure. */ -static void stli_brdpoll(struct stlibrd *brdp, cdkhdr_t __iomem *hdrp) +static void stli_brdpoll(stlibrd_t *brdp, cdkhdr_t __iomem *hdrp) { - struct stliport *portp; + stliport_t *portp; unsigned char hostbits[(STL_MAXCHANS / 8) + 1]; unsigned char slavebits[(STL_MAXCHANS / 8) + 1]; unsigned char __iomem *slavep; @@ -2542,10 +2697,11 @@ static void stli_brdpoll(struct stlibrd *brdp, cdkhdr_t __iomem *hdrp) static void stli_poll(unsigned long arg) { cdkhdr_t __iomem *hdrp; - struct stlibrd *brdp; - unsigned int brdnr; + stlibrd_t *brdp; + int brdnr; - mod_timer(&stli_timerlist, STLI_TIMEOUT); + stli_timerlist.expires = STLI_TIMEOUT; + add_timer(&stli_timerlist); /* * Check each board and do any servicing required. @@ -2574,7 +2730,7 @@ static void stli_poll(unsigned long arg) * the slave. */ -static void stli_mkasyport(struct stliport *portp, asyport_t *pp, struct ktermios *tiosp) +static void stli_mkasyport(stliport_t *portp, asyport_t *pp, struct termios *tiosp) { memset(pp, 0, sizeof(asyport_t)); @@ -2723,13 +2879,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(struct stlibrd *brdp) +static int stli_initports(stlibrd_t *brdp) { - struct stliport *portp; - unsigned int i, panelnr, panelport; + stliport_t *portp; + int i, panelnr, panelport; for (i = 0, panelnr = 0, panelport = 0; (i < brdp->nrports); i++) { - portp = kzalloc(sizeof(struct stliport), GFP_KERNEL); + portp = kzalloc(sizeof(stliport_t), GFP_KERNEL); if (!portp) { printk("STALLION: failed to allocate port structure\n"); continue; @@ -2763,7 +2919,7 @@ static int stli_initports(struct stlibrd *brdp) * All the following routines are board specific hardware operations. */ -static void stli_ecpinit(struct stlibrd *brdp) +static void stli_ecpinit(stlibrd_t *brdp) { unsigned long memconf; @@ -2778,21 +2934,21 @@ static void stli_ecpinit(struct stlibrd *brdp) /*****************************************************************************/ -static void stli_ecpenable(struct stlibrd *brdp) +static void stli_ecpenable(stlibrd_t *brdp) { outb(ECP_ATENABLE, (brdp->iobase + ECP_ATCONFR)); } /*****************************************************************************/ -static void stli_ecpdisable(struct stlibrd *brdp) +static void stli_ecpdisable(stlibrd_t *brdp) { outb(ECP_ATDISABLE, (brdp->iobase + ECP_ATCONFR)); } /*****************************************************************************/ -static void __iomem *stli_ecpgetmemptr(struct stlibrd *brdp, unsigned long offset, int line) +static void __iomem *stli_ecpgetmemptr(stlibrd_t *brdp, unsigned long offset, int line) { void __iomem *ptr; unsigned char val; @@ -2813,7 +2969,7 @@ static void __iomem *stli_ecpgetmemptr(struct stlibrd *brdp, unsigned long offse /*****************************************************************************/ -static void stli_ecpreset(struct stlibrd *brdp) +static void stli_ecpreset(stlibrd_t *brdp) { outb(ECP_ATSTOP, (brdp->iobase + ECP_ATCONFR)); udelay(10); @@ -2823,7 +2979,7 @@ static void stli_ecpreset(struct stlibrd *brdp) /*****************************************************************************/ -static void stli_ecpintr(struct stlibrd *brdp) +static void stli_ecpintr(stlibrd_t *brdp) { outb(0x1, brdp->iobase); } @@ -2834,7 +2990,7 @@ static void stli_ecpintr(struct stlibrd *brdp) * The following set of functions act on ECP EISA boards. */ -static void stli_ecpeiinit(struct stlibrd *brdp) +static void stli_ecpeiinit(stlibrd_t *brdp) { unsigned long memconf; @@ -2852,21 +3008,21 @@ static void stli_ecpeiinit(struct stlibrd *brdp) /*****************************************************************************/ -static void stli_ecpeienable(struct stlibrd *brdp) +static void stli_ecpeienable(stlibrd_t *brdp) { outb(ECP_EIENABLE, (brdp->iobase + ECP_EICONFR)); } /*****************************************************************************/ -static void stli_ecpeidisable(struct stlibrd *brdp) +static void stli_ecpeidisable(stlibrd_t *brdp) { outb(ECP_EIDISABLE, (brdp->iobase + ECP_EICONFR)); } /*****************************************************************************/ -static void __iomem *stli_ecpeigetmemptr(struct stlibrd *brdp, unsigned long offset, int line) +static void __iomem *stli_ecpeigetmemptr(stlibrd_t *brdp, unsigned long offset, int line) { void __iomem *ptr; unsigned char val; @@ -2890,7 +3046,7 @@ static void __iomem *stli_ecpeigetmemptr(struct stlibrd *brdp, unsigned long off /*****************************************************************************/ -static void stli_ecpeireset(struct stlibrd *brdp) +static void stli_ecpeireset(stlibrd_t *brdp) { outb(ECP_EISTOP, (brdp->iobase + ECP_EICONFR)); udelay(10); @@ -2904,21 +3060,21 @@ static void stli_ecpeireset(struct stlibrd *brdp) * The following set of functions act on ECP MCA boards. */ -static void stli_ecpmcenable(struct stlibrd *brdp) +static void stli_ecpmcenable(stlibrd_t *brdp) { outb(ECP_MCENABLE, (brdp->iobase + ECP_MCCONFR)); } /*****************************************************************************/ -static void stli_ecpmcdisable(struct stlibrd *brdp) +static void stli_ecpmcdisable(stlibrd_t *brdp) { outb(ECP_MCDISABLE, (brdp->iobase + ECP_MCCONFR)); } /*****************************************************************************/ -static void __iomem *stli_ecpmcgetmemptr(struct stlibrd *brdp, unsigned long offset, int line) +static void __iomem *stli_ecpmcgetmemptr(stlibrd_t *brdp, unsigned long offset, int line) { void __iomem *ptr; unsigned char val; @@ -2939,7 +3095,7 @@ static void __iomem *stli_ecpmcgetmemptr(struct stlibrd *brdp, unsigned long off /*****************************************************************************/ -static void stli_ecpmcreset(struct stlibrd *brdp) +static void stli_ecpmcreset(stlibrd_t *brdp) { outb(ECP_MCSTOP, (brdp->iobase + ECP_MCCONFR)); udelay(10); @@ -2953,7 +3109,7 @@ static void stli_ecpmcreset(struct stlibrd *brdp) * The following set of functions act on ECP PCI boards. */ -static void stli_ecppciinit(struct stlibrd *brdp) +static void stli_ecppciinit(stlibrd_t *brdp) { outb(ECP_PCISTOP, (brdp->iobase + ECP_PCICONFR)); udelay(10); @@ -2963,7 +3119,7 @@ static void stli_ecppciinit(struct stlibrd *brdp) /*****************************************************************************/ -static void __iomem *stli_ecppcigetmemptr(struct stlibrd *brdp, unsigned long offset, int line) +static void __iomem *stli_ecppcigetmemptr(stlibrd_t *brdp, unsigned long offset, int line) { void __iomem *ptr; unsigned char val; @@ -2984,7 +3140,7 @@ static void __iomem *stli_ecppcigetmemptr(struct stlibrd *brdp, unsigned long of /*****************************************************************************/ -static void stli_ecppcireset(struct stlibrd *brdp) +static void stli_ecppcireset(stlibrd_t *brdp) { outb(ECP_PCISTOP, (brdp->iobase + ECP_PCICONFR)); udelay(10); @@ -2998,7 +3154,7 @@ static void stli_ecppcireset(struct stlibrd *brdp) * The following routines act on ONboards. */ -static void stli_onbinit(struct stlibrd *brdp) +static void stli_onbinit(stlibrd_t *brdp) { unsigned long memconf; @@ -3015,21 +3171,21 @@ static void stli_onbinit(struct stlibrd *brdp) /*****************************************************************************/ -static void stli_onbenable(struct stlibrd *brdp) +static void stli_onbenable(stlibrd_t *brdp) { outb((brdp->enabval | ONB_ATENABLE), (brdp->iobase + ONB_ATCONFR)); } /*****************************************************************************/ -static void stli_onbdisable(struct stlibrd *brdp) +static void stli_onbdisable(stlibrd_t *brdp) { outb((brdp->enabval | ONB_ATDISABLE), (brdp->iobase + ONB_ATCONFR)); } /*****************************************************************************/ -static void __iomem *stli_onbgetmemptr(struct stlibrd *brdp, unsigned long offset, int line) +static void __iomem *stli_onbgetmemptr(stlibrd_t *brdp, unsigned long offset, int line) { void __iomem *ptr; @@ -3046,7 +3202,7 @@ static void __iomem *stli_onbgetmemptr(struct stlibrd *brdp, unsigned long offse /*****************************************************************************/ -static void stli_onbreset(struct stlibrd *brdp) +static void stli_onbreset(stlibrd_t *brdp) { outb(ONB_ATSTOP, (brdp->iobase + ONB_ATCONFR)); udelay(10); @@ -3060,7 +3216,7 @@ static void stli_onbreset(struct stlibrd *brdp) * The following routines act on ONboard EISA. */ -static void stli_onbeinit(struct stlibrd *brdp) +static void stli_onbeinit(stlibrd_t *brdp) { unsigned long memconf; @@ -3080,21 +3236,21 @@ static void stli_onbeinit(struct stlibrd *brdp) /*****************************************************************************/ -static void stli_onbeenable(struct stlibrd *brdp) +static void stli_onbeenable(stlibrd_t *brdp) { outb(ONB_EIENABLE, (brdp->iobase + ONB_EICONFR)); } /*****************************************************************************/ -static void stli_onbedisable(struct stlibrd *brdp) +static void stli_onbedisable(stlibrd_t *brdp) { outb(ONB_EIDISABLE, (brdp->iobase + ONB_EICONFR)); } /*****************************************************************************/ -static void __iomem *stli_onbegetmemptr(struct stlibrd *brdp, unsigned long offset, int line) +static void __iomem *stli_onbegetmemptr(stlibrd_t *brdp, unsigned long offset, int line) { void __iomem *ptr; unsigned char val; @@ -3118,7 +3274,7 @@ static void __iomem *stli_onbegetmemptr(struct stlibrd *brdp, unsigned long offs /*****************************************************************************/ -static void stli_onbereset(struct stlibrd *brdp) +static void stli_onbereset(stlibrd_t *brdp) { outb(ONB_EISTOP, (brdp->iobase + ONB_EICONFR)); udelay(10); @@ -3132,7 +3288,7 @@ static void stli_onbereset(struct stlibrd *brdp) * The following routines act on Brumby boards. */ -static void stli_bbyinit(struct stlibrd *brdp) +static void stli_bbyinit(stlibrd_t *brdp) { outb(BBY_ATSTOP, (brdp->iobase + BBY_ATCONFR)); udelay(10); @@ -3144,7 +3300,7 @@ static void stli_bbyinit(struct stlibrd *brdp) /*****************************************************************************/ -static void __iomem *stli_bbygetmemptr(struct stlibrd *brdp, unsigned long offset, int line) +static void __iomem *stli_bbygetmemptr(stlibrd_t *brdp, unsigned long offset, int line) { void __iomem *ptr; unsigned char val; @@ -3159,7 +3315,7 @@ static void __iomem *stli_bbygetmemptr(struct stlibrd *brdp, unsigned long offse /*****************************************************************************/ -static void stli_bbyreset(struct stlibrd *brdp) +static void stli_bbyreset(stlibrd_t *brdp) { outb(BBY_ATSTOP, (brdp->iobase + BBY_ATCONFR)); udelay(10); @@ -3173,7 +3329,7 @@ static void stli_bbyreset(struct stlibrd *brdp) * The following routines act on original old Stallion boards. */ -static void stli_stalinit(struct stlibrd *brdp) +static void stli_stalinit(stlibrd_t *brdp) { outb(0x1, brdp->iobase); mdelay(1000); @@ -3181,7 +3337,7 @@ static void stli_stalinit(struct stlibrd *brdp) /*****************************************************************************/ -static void __iomem *stli_stalgetmemptr(struct stlibrd *brdp, unsigned long offset, int line) +static void __iomem *stli_stalgetmemptr(stlibrd_t *brdp, unsigned long offset, int line) { BUG_ON(offset > brdp->memsize); return brdp->membase + (offset % STAL_PAGESIZE); @@ -3189,7 +3345,7 @@ static void __iomem *stli_stalgetmemptr(struct stlibrd *brdp, unsigned long offs /*****************************************************************************/ -static void stli_stalreset(struct stlibrd *brdp) +static void stli_stalreset(stlibrd_t *brdp) { u32 __iomem *vecp; @@ -3206,22 +3362,21 @@ static void stli_stalreset(struct stlibrd *brdp) * board types. */ -static int stli_initecp(struct stlibrd *brdp) +static int stli_initecp(stlibrd_t *brdp) { cdkecpsig_t sig; cdkecpsig_t __iomem *sigsp; unsigned int status, nxtid; char *name; - int retval, panelnr, nrports; - - if ((brdp->iobase == 0) || (brdp->memaddr == 0)) { - retval = -ENODEV; - goto err; - } + int panelnr, nrports; - if (!request_region(brdp->iobase, brdp->iosize, "istallion")) { - retval = -EIO; - goto err; + 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; } brdp->iosize = ECP_IOSIZE; @@ -3233,6 +3388,7 @@ static int stli_initecp(struct stlibrd *brdp) */ switch (brdp->brdtype) { case BRD_ECP: + brdp->membase = (void *) brdp->memaddr; brdp->memsize = ECP_MEMSIZE; brdp->pagesize = ECP_ATPAGESIZE; brdp->init = stli_ecpinit; @@ -3246,6 +3402,7 @@ static int stli_initecp(struct stlibrd *brdp) break; case BRD_ECPE: + brdp->membase = (void *) brdp->memaddr; brdp->memsize = ECP_MEMSIZE; brdp->pagesize = ECP_EIPAGESIZE; brdp->init = stli_ecpeiinit; @@ -3259,6 +3416,7 @@ static int stli_initecp(struct stlibrd *brdp) break; case BRD_ECPMC: + brdp->membase = (void *) brdp->memaddr; brdp->memsize = ECP_MEMSIZE; brdp->pagesize = ECP_MCPAGESIZE; brdp->init = NULL; @@ -3272,6 +3430,7 @@ static int stli_initecp(struct stlibrd *brdp) break; case BRD_ECPPCI: + brdp->membase = (void *) brdp->memaddr; brdp->memsize = ECP_PCIMEMSIZE; brdp->pagesize = ECP_PCIPAGESIZE; brdp->init = stli_ecppciinit; @@ -3285,8 +3444,8 @@ static int stli_initecp(struct stlibrd *brdp) break; default: - retval = -EINVAL; - goto err_reg; + release_region(brdp->iobase, brdp->iosize); + return -EINVAL; } /* @@ -3298,9 +3457,10 @@ static int stli_initecp(struct stlibrd *brdp) EBRDINIT(brdp); brdp->membase = ioremap(brdp->memaddr, brdp->memsize); - if (brdp->membase == NULL) { - retval = -ENOMEM; - goto err_reg; + if (brdp->membase == NULL) + { + release_region(brdp->iobase, brdp->iosize); + return -ENOMEM; } /* @@ -3313,9 +3473,12 @@ static int stli_initecp(struct stlibrd *brdp) memcpy_fromio(&sig, sigsp, sizeof(cdkecpsig_t)); EBRDDISABLE(brdp); - if (sig.magic != cpu_to_le32(ECP_MAGIC)) { - retval = -ENODEV; - goto err_unmap; + if (sig.magic != cpu_to_le32(ECP_MAGIC)) + { + release_region(brdp->iobase, brdp->iosize); + iounmap(brdp->membase); + brdp->membase = NULL; + return -ENODEV; } /* @@ -3340,13 +3503,6 @@ static int stli_initecp(struct stlibrd *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; } /*****************************************************************************/ @@ -3356,27 +3512,23 @@ static int stli_initecp(struct stlibrd *brdp) * This handles only these board types. */ -static int stli_initonb(struct stlibrd *brdp) +static int stli_initonb(stlibrd_t *brdp) { cdkonbsig_t sig; cdkonbsig_t __iomem *sigsp; char *name; - int i, retval; + int i; /* * Do a basic sanity check on the IO and memory addresses. */ - if (brdp->iobase == 0 || brdp->memaddr == 0) { - retval = -ENODEV; - goto err; - } + if (brdp->iobase == 0 || brdp->memaddr == 0) + return -ENODEV; brdp->iosize = ONB_IOSIZE; - if (!request_region(brdp->iobase, brdp->iosize, "istallion")) { - retval = -EIO; - goto err; - } + if (!request_region(brdp->iobase, brdp->iosize, "istallion")) + return -EIO; /* * Based on the specific board type setup the common vars to access @@ -3385,7 +3537,10 @@ static int stli_initonb(struct stlibrd *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; @@ -3416,6 +3571,8 @@ static int stli_initonb(struct stlibrd *brdp) break; case BRD_BRUMBY4: + case BRD_BRUMBY8: + case BRD_BRUMBY16: brdp->memsize = BBY_MEMSIZE; brdp->pagesize = BBY_PAGESIZE; brdp->init = stli_bbyinit; @@ -3442,8 +3599,8 @@ static int stli_initonb(struct stlibrd *brdp) break; default: - retval = -EINVAL; - goto err_reg; + release_region(brdp->iobase, brdp->iosize); + return -EINVAL; } /* @@ -3455,9 +3612,10 @@ static int stli_initonb(struct stlibrd *brdp) EBRDINIT(brdp); brdp->membase = ioremap(brdp->memaddr, brdp->memsize); - if (brdp->membase == NULL) { - retval = -ENOMEM; - goto err_reg; + if (brdp->membase == NULL) + { + release_region(brdp->iobase, brdp->iosize); + return -ENOMEM; } /* @@ -3473,9 +3631,12 @@ static int stli_initonb(struct stlibrd *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)) { - retval = -ENODEV; - goto err_unmap; + sig.magic3 != cpu_to_le16(ONB_MAGIC3)) + { + release_region(brdp->iobase, brdp->iosize); + iounmap(brdp->membase); + brdp->membase = NULL; + return -ENODEV; } /* @@ -3497,13 +3658,6 @@ static int stli_initonb(struct stlibrd *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; } /*****************************************************************************/ @@ -3514,15 +3668,14 @@ static int stli_initonb(struct stlibrd *brdp) * read in the memory map, and get the show on the road... */ -static int stli_startbrd(struct stlibrd *brdp) +static int stli_startbrd(stlibrd_t *brdp) { cdkhdr_t __iomem *hdrp; cdkmem_t __iomem *memp; cdkasy_t __iomem *ap; unsigned long flags; - unsigned int portnr, nrdevs, i; - struct stliport *portp; - int rc = 0; + stliport_t *portp; + int portnr, nrdevs, i, rc = 0; u32 memoff; spin_lock_irqsave(&brd_lock, flags); @@ -3609,7 +3762,8 @@ static int stli_startbrd(struct stlibrd *brdp) if (! stli_timeron) { stli_timeron++; - mod_timer(&stli_timerlist, STLI_TIMEOUT); + stli_timerlist.expires = STLI_TIMEOUT; + add_timer(&stli_timerlist); } return rc; @@ -3621,32 +3775,49 @@ static int stli_startbrd(struct stlibrd *brdp) * Probe and initialize the specified board. */ -static int __devinit stli_brdinit(struct stlibrd *brdp) +static int __init stli_brdinit(stlibrd_t *brdp) { - int retval; + stli_brds[brdp->brdnr] = brdp; switch (brdp->brdtype) { case BRD_ECP: case BRD_ECPE: case BRD_ECPMC: case BRD_ECPPCI: - retval = stli_initecp(brdp); + 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: - retval = stli_initonb(brdp); + 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); - retval = -ENODEV; + return -ENODEV; } - if (retval) - return retval; + 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; + } stli_initports(brdp); printk(KERN_INFO "STALLION: %s found, board=%d io=%x mem=%x " @@ -3656,7 +3827,6 @@ static int __devinit stli_brdinit(struct stlibrd *brdp) return 0; } -#if STLI_EISAPROBE != 0 /*****************************************************************************/ /* @@ -3664,7 +3834,7 @@ static int __devinit stli_brdinit(struct stlibrd *brdp) * might be. This is a bit if hack, but it is the best we can do. */ -static int stli_eisamemprobe(struct stlibrd *brdp) +static int stli_eisamemprobe(stlibrd_t *brdp) { cdkecpsig_t ecpsig, __iomem *ecpsigp; cdkonbsig_t onbsig, __iomem *onbsigp; @@ -3750,11 +3920,10 @@ static int stli_eisamemprobe(struct stlibrd *brdp) } return 0; } -#endif static int stli_getbrdnr(void) { - unsigned int i; + int i; for (i = 0; i < STL_MAXBRDS; i++) { if (!stli_brds[i]) { @@ -3766,7 +3935,6 @@ static int stli_getbrdnr(void) return -1; } -#if STLI_EISAPROBE != 0 /*****************************************************************************/ /* @@ -3781,9 +3949,9 @@ static int stli_getbrdnr(void) static int stli_findeisabrds(void) { - struct stlibrd *brdp; - unsigned int iobase, eid, i; - int brdnr, found = 0; + stlibrd_t *brdp; + unsigned int iobase, eid; + int i; /* * Firstly check if this is an EISA system. If this is not an EISA system then @@ -3821,11 +3989,9 @@ static int stli_findeisabrds(void) * Allocate a board structure and initialize it. */ if ((brdp = stli_allocbrd()) == NULL) - return found ? : -ENOMEM; - brdnr = stli_getbrdnr(); - if (brdnr < 0) - return found ? : -ENOMEM; - brdp->brdnr = (unsigned int)brdnr; + return -ENOMEM; + if ((brdp->brdnr = stli_getbrdnr()) < 0) + return -ENOMEM; eid = inb(iobase + 0xc82); if (eid == ECP_EISAID) brdp->brdtype = BRD_ECPE; @@ -3837,24 +4003,11 @@ static int stli_findeisabrds(void) outb(0x1, (iobase + 0xc84)); if (stli_eisamemprobe(brdp)) outb(0, (iobase + 0xc84)); - 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); + stli_brdinit(brdp); } - return found; + return 0; } -#else -static inline int stli_findeisabrds(void) { return 0; } -#endif /*****************************************************************************/ @@ -3864,104 +4017,72 @@ static inline int stli_findeisabrds(void) { return 0; } /*****************************************************************************/ +#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 __devinit stli_pciprobe(struct pci_dev *pdev, - const struct pci_device_id *ent) +static int stli_initpcibrd(int brdtype, struct pci_dev *devp) { - 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) { + stlibrd_t *brdp; + + if (pci_enable_device(devp)) + return -EIO; + if ((brdp = stli_allocbrd()) == NULL) + return -ENOMEM; + if ((brdp->brdnr = stli_getbrdnr()) < 0) { printk(KERN_INFO "STALLION: too many boards found, " "maximum supported %d\n", STL_MAXBRDS); - mutex_unlock(&stli_brdslock); - retval = -EIO; - goto err_fr; + return 0; } - brdp->brdnr = (unsigned int)brdnr; - stli_brds[brdp->brdnr] = brdp; - mutex_unlock(&stli_brdslock); - brdp->brdtype = BRD_ECPPCI; + brdp->brdtype = brdtype; /* * We have all resources from the board, so lets setup the actual * board structure now. */ - 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); + brdp->iobase = pci_resource_start(devp, 3); + brdp->memaddr = pci_resource_start(devp, 2); + stli_brdinit(brdp); 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); +/*****************************************************************************/ - stli_cleanup_ports(brdp); +/* + * Find all Stallion PCI boards that might be installed. Initialize each + * one as it is found. + */ - iounmap(brdp->membase); - if (brdp->iosize > 0) - release_region(brdp->iobase, brdp->iosize); +static int stli_findpcibrds(void) +{ + struct pci_dev *dev = NULL; - stli_brds[brdp->brdnr] = NULL; - kfree(brdp); + while ((dev = pci_get_device(PCI_VENDOR_ID_STALLION, PCI_DEVICE_ID_ECRA, dev))) { + stli_initpcibrd(BRD_ECPPCI, dev); + } + return 0; } -static struct pci_driver stli_pcidriver = { - .name = "istallion", - .id_table = istallion_pci_tbl, - .probe = stli_pciprobe, - .remove = __devexit_p(stli_pciremove) -}; +#endif + /*****************************************************************************/ /* * Allocate a new board structure. Fill out the basic info in it. */ -static struct stlibrd *stli_allocbrd(void) +static stlibrd_t *stli_allocbrd(void) { - struct stlibrd *brdp; + stlibrd_t *brdp; - brdp = kzalloc(sizeof(struct stlibrd), GFP_KERNEL); + brdp = kzalloc(sizeof(stlibrd_t), GFP_KERNEL); if (!brdp) { printk(KERN_ERR "STALLION: failed to allocate memory " - "(size=%Zd)\n", sizeof(struct stlibrd)); + "(size=%Zd)\n", sizeof(stlibrd_t)); return NULL; } brdp->magic = STLI_BOARDMAGIC; @@ -3977,37 +4098,43 @@ static struct stlibrd *stli_allocbrd(void) static int stli_initbrds(void) { - struct stlibrd *brdp, *nxtbrdp; - struct stlconf conf; - unsigned int i, j, found = 0; - int retval; + 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; + } - 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; +/* + * 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]); if ((brdp = stli_allocbrd()) == NULL) - 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); + return -ENOMEM; + brdp->brdnr = i; + brdp->brdtype = confp->brdtype; + brdp->iobase = confp->ioaddr1; + brdp->memaddr = confp->memaddr; + stli_brdinit(brdp); } - retval = stli_findeisabrds(); - if (retval > 0) - found += retval; +/* + * 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 /* * All found boards are initialized. Now for a little optimization, if @@ -4047,16 +4174,7 @@ 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; } /*****************************************************************************/ @@ -4071,13 +4189,12 @@ static ssize_t stli_memread(struct file *fp, char __user *buf, size_t count, lof { unsigned long flags; void __iomem *memptr; - struct stlibrd *brdp; - unsigned int brdnr; - int size, n; + stlibrd_t *brdp; + int brdnr, size, n; void *p; loff_t off = *offp; - brdnr = iminor(fp->f_path.dentry->d_inode); + brdnr = iminor(fp->f_dentry->d_inode); if (brdnr >= stli_nrbrds) return -ENODEV; brdp = stli_brds[brdnr]; @@ -4088,7 +4205,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, (size_t)(brdp->memsize - off)); + size = MIN(count, (brdp->memsize - off)); /* * Copy the data a page at a time @@ -4102,8 +4219,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, (int)(brdp->pagesize - (((unsigned long) off) % brdp->pagesize))); - n = min(n, (int)PAGE_SIZE); + n = MIN(size, (brdp->pagesize - (((unsigned long) off) % brdp->pagesize))); + n = MIN(n, PAGE_SIZE); memcpy_fromio(p, memptr, n); EBRDDISABLE(brdp); spin_unlock_irqrestore(&brd_lock, flags); @@ -4135,14 +4252,13 @@ static ssize_t stli_memwrite(struct file *fp, const char __user *buf, size_t cou { unsigned long flags; void __iomem *memptr; - struct stlibrd *brdp; + stlibrd_t *brdp; char __user *chbuf; - unsigned int brdnr; - int size, n; + int brdnr, size, n; void *p; loff_t off = *offp; - brdnr = iminor(fp->f_path.dentry->d_inode); + brdnr = iminor(fp->f_dentry->d_inode); if (brdnr >= stli_nrbrds) return -ENODEV; @@ -4155,7 +4271,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, (size_t)(brdp->memsize - off)); + size = MIN(count, (brdp->memsize - off)); /* * Copy the data a page at a time @@ -4166,8 +4282,8 @@ static ssize_t stli_memwrite(struct file *fp, const char __user *buf, size_t cou return -ENOMEM; while (size > 0) { - n = min(size, (int)(brdp->pagesize - (((unsigned long) off) % brdp->pagesize))); - n = min(n, (int)PAGE_SIZE); + n = MIN(size, (brdp->pagesize - (((unsigned long) off) % brdp->pagesize))); + n = MIN(n, PAGE_SIZE); if (copy_from_user(p, chbuf, n)) { if (count == 0) count = -EFAULT; @@ -4197,8 +4313,8 @@ static ssize_t stli_memwrite(struct file *fp, const char __user *buf, size_t cou static int stli_getbrdstats(combrd_t __user *bp) { - struct stlibrd *brdp; - unsigned int i; + stlibrd_t *brdp; + int i; if (copy_from_user(&stli_brdstats, bp, sizeof(combrd_t))) return -EFAULT; @@ -4234,20 +4350,19 @@ static int stli_getbrdstats(combrd_t __user *bp) * Resolve the referenced port number into a port struct pointer. */ -static struct stliport *stli_getport(unsigned int brdnr, unsigned int panelnr, - unsigned int portnr) +static stliport_t *stli_getport(int brdnr, int panelnr, int portnr) { - struct stlibrd *brdp; - unsigned int i; + stlibrd_t *brdp; + int i; - if (brdnr >= STL_MAXBRDS) + if (brdnr < 0 || 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 >= brdp->nrports) + if ((portnr < 0) || (portnr >= brdp->nrports)) return NULL; return brdp->ports[portnr]; } @@ -4260,10 +4375,10 @@ static struct stliport *stli_getport(unsigned int brdnr, unsigned int panelnr, * what port to get stats for (used through board control device). */ -static int stli_portcmdstats(struct stliport *portp) +static int stli_portcmdstats(stliport_t *portp) { unsigned long flags; - struct stlibrd *brdp; + stlibrd_t *brdp; int rc; memset(&stli_comstats, 0, sizeof(comstats_t)); @@ -4334,9 +4449,9 @@ static int stli_portcmdstats(struct stliport *portp) * what port to get stats for (used through board control device). */ -static int stli_getportstats(struct stliport *portp, comstats_t __user *cp) +static int stli_getportstats(stliport_t *portp, comstats_t __user *cp) { - struct stlibrd *brdp; + stlibrd_t *brdp; int rc; if (!portp) { @@ -4365,9 +4480,9 @@ static int stli_getportstats(struct stliport *portp, comstats_t __user *cp) * Clear the port stats structure. We also return it zeroed out... */ -static int stli_clrportstats(struct stliport *portp, comstats_t __user *cp) +static int stli_clrportstats(stliport_t *portp, comstats_t __user *cp) { - struct stlibrd *brdp; + stlibrd_t *brdp; int rc; if (!portp) { @@ -4404,18 +4519,17 @@ static int stli_clrportstats(struct stliport *portp, comstats_t __user *cp) * Return the entire driver ports structure to a user app. */ -static int stli_getportstruct(struct stliport __user *arg) +static int stli_getportstruct(stliport_t __user *arg) { - struct stliport stli_dummyport; - struct stliport *portp; + stliport_t *portp; - if (copy_from_user(&stli_dummyport, arg, sizeof(struct stliport))) + if (copy_from_user(&stli_dummyport, arg, sizeof(stliport_t))) 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(struct stliport))) + if (copy_to_user(arg, portp, sizeof(stliport_t))) return -EFAULT; return 0; } @@ -4426,19 +4540,18 @@ static int stli_getportstruct(struct stliport __user *arg) * Return the entire driver board structure to a user app. */ -static int stli_getbrdstruct(struct stlibrd __user *arg) +static int stli_getbrdstruct(stlibrd_t __user *arg) { - struct stlibrd stli_dummybrd; - struct stlibrd *brdp; + stlibrd_t *brdp; - if (copy_from_user(&stli_dummybrd, arg, sizeof(struct stlibrd))) + if (copy_from_user(&stli_dummybrd, arg, sizeof(stlibrd_t))) return -EFAULT; - if (stli_dummybrd.brdnr >= STL_MAXBRDS) + if ((stli_dummybrd.brdnr < 0) || (stli_dummybrd.brdnr >= STL_MAXBRDS)) return -ENODEV; brdp = stli_brds[stli_dummybrd.brdnr]; if (!brdp) return -ENODEV; - if (copy_to_user(arg, brdp, sizeof(struct stlibrd))) + if (copy_to_user(arg, brdp, sizeof(stlibrd_t))) return -EFAULT; return 0; } @@ -4453,7 +4566,7 @@ static int stli_getbrdstruct(struct stlibrd __user *arg) static int stli_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, unsigned long arg) { - struct stlibrd *brdp; + stlibrd_t *brdp; int brdnr, rc, done; void __user *argp = (void __user *)arg; @@ -4552,84 +4665,36 @@ 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); - 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) +static int __init stli_init(void) { - unsigned int i; - int retval; - + int i; printk(KERN_INFO "%s: version %s\n", stli_drvtitle, stli_drvversion); spin_lock_init(&stli_lock); spin_lock_init(&brd_lock); - stli_txcookbuf = kmalloc(STLI_TXBUFSIZE, GFP_KERNEL); - if (!stli_txcookbuf) { - printk(KERN_ERR "STALLION: failed to allocate memory " - "(size=%d)\n", STLI_TXBUFSIZE); - retval = -ENOMEM; - goto err; - } + stli_initbrds(); stli_serial = alloc_tty_driver(STL_MAXBRDS * STL_MAXPORTS); - if (!stli_serial) { - retval = -ENOMEM; - goto err_free; - } - - stli_serial->owner = THIS_MODULE; - stli_serial->driver_name = stli_drvname; - stli_serial->name = stli_serialname; - stli_serial->major = STL_SERIALMAJOR; - stli_serial->minor_start = 0; - 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 | TTY_DRIVER_DYNAMIC_DEV; - tty_set_operations(stli_serial, &stli_ops); - - retval = tty_register_driver(stli_serial); - if (retval) { - printk(KERN_ERR "STALLION: failed to register serial driver\n"); - goto err_ttyput; - } + if (!stli_serial) + return -ENOMEM; - retval = stli_initbrds(); - if (retval) - goto err_ttyunr; +/* + * Allocate a temporary write buffer. + */ + stli_txcookbuf = kmalloc(STLI_TXBUFSIZE, GFP_KERNEL); + if (!stli_txcookbuf) + printk(KERN_ERR "STALLION: failed to allocate memory " + "(size=%d)\n", STLI_TXBUFSIZE); /* * 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) { + if (register_chrdev(STL_SIOMEMMAJOR, "staliomem", &stli_fsiomem)) 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++) @@ -4637,49 +4702,26 @@ static int __init istallion_module_init(void) 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); +/* + * 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; + stli_serial->major = STL_SERIALMAJOR; + stli_serial->minor_start = 0; + 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; + tty_set_operations(stli_serial, &stli_ops); - if (stli_timeron) { - stli_timeron = 0; - del_timer_sync(&stli_timerlist); + if (tty_register_driver(stli_serial)) { + put_tty_driver(stli_serial); + printk(KERN_ERR "STALLION: failed to register serial driver\n"); + return -EBUSY; } - - 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); + return 0; } -module_init(istallion_module_init); -module_exit(istallion_module_exit); +/*****************************************************************************/ diff --git a/trunk/drivers/char/keyboard.c b/trunk/drivers/char/keyboard.c index 7a6c1c0b7a95..20b6c8b30248 100644 --- a/trunk/drivers/char/keyboard.c +++ b/trunk/drivers/char/keyboard.c @@ -710,7 +710,7 @@ static void k_fn(struct vc_data *vc, unsigned char value, char up_flag) static void k_cur(struct vc_data *vc, unsigned char value, char up_flag) { - static const char cur_chars[] = "BDCA"; + static const char *cur_chars = "BDCA"; if (up_flag) return; diff --git a/trunk/drivers/char/lp.c b/trunk/drivers/char/lp.c index b70b5388b5a8..1ecea7d448f1 100644 --- a/trunk/drivers/char/lp.c +++ b/trunk/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_path.dentry->d_inode); + unsigned int minor = iminor(file->f_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_path.dentry->d_inode); + unsigned int minor=iminor(file->f_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/trunk/drivers/char/mem.c b/trunk/drivers/char/mem.c index 089020e0ee5a..e67eef4867ba 100644 --- a/trunk/drivers/char/mem.c +++ b/trunk/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_path.dentry->d_inode->i_mutex); + mutex_lock(&file->f_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_path.dentry->d_inode->i_mutex); + mutex_unlock(&file->f_dentry->d_inode->i_mutex); return ret; } diff --git a/trunk/drivers/char/moxa.c b/trunk/drivers/char/moxa.c index f391a24a1b44..8b316953173d 100644 --- a/trunk/drivers/char/moxa.c +++ b/trunk/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 ktermios *); +static void moxa_set_termios(struct tty_struct *, struct termios *); 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 ktermios *, speed_t); +static int MoxaPortSetTermio(int, struct termios *, speed_t); static int MoxaPortGetLineOut(int, int *, int *); static void MoxaPortLineCtrl(int, int, int); static void MoxaPortFlowCtrl(int, int, int, int, int, int); @@ -355,8 +355,6 @@ 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); @@ -866,7 +864,7 @@ static void moxa_unthrottle(struct tty_struct *tty) } static void moxa_set_termios(struct tty_struct *tty, - struct ktermios *old_termios) + struct termios *old_termios) { struct moxa_str *ch = (struct moxa_str *) tty->driver_data; @@ -980,7 +978,7 @@ static void moxa_poll(unsigned long ignored) static void set_tty_param(struct tty_struct *tty) { - register struct ktermios *ts; + register struct termios *ts; struct moxa_str *ch; int rts, cts, txflow, rxflow, xany; @@ -1151,7 +1149,7 @@ static void shut_down(struct moxa_str *ch) static void receive_data(struct moxa_str *ch) { struct tty_struct *tp; - struct ktermios *ts; + struct termios *ts; unsigned long flags; ts = NULL; @@ -1914,9 +1912,9 @@ int MoxaPortsOfCard(int cardno) * * Function 12: Configure the port. * Syntax: - * int MoxaPortSetTermio(int port, struct ktermios *termio, speed_t baud); + * int MoxaPortSetTermio(int port, struct termios *termio, speed_t baud); * int port : port number (0 - 127) - * struct ktermios * termio : termio structure pointer + * struct termios * termio : termio structure pointer * speed_t baud : baud rate * * return: -1 : this port is invalid or termio == NULL @@ -2197,7 +2195,7 @@ long MoxaPortSetBaud(int port, long baud) return (baud); } -int MoxaPortSetTermio(int port, struct ktermios *termio, speed_t baud) +int MoxaPortSetTermio(int port, struct termios *termio, speed_t baud) { void __iomem *ofsAddr; tcflag_t cflag; diff --git a/trunk/drivers/char/mxser.c b/trunk/drivers/char/mxser.c index c063359baf78..5ed2486b7581 100644 --- a/trunk/drivers/char/mxser.c +++ b/trunk/drivers/char/mxser.c @@ -328,8 +328,8 @@ struct mxser_struct { int xmit_tail; int xmit_cnt; struct work_struct tqueue; - struct ktermios normal_termios; - struct ktermios callout_termios; + struct termios normal_termios; + struct termios 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 ktermios *mxvar_termios[MXSER_PORTS + 1]; -static struct ktermios *mxvar_termios_locked[MXSER_PORTS + 1]; +static struct termios *mxvar_termios[MXSER_PORTS + 1]; +static struct termios *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 ktermios *); +static void mxser_set_termios(struct tty_struct *, struct termios *); 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 ktermios *old_termios); +static int mxser_change_speed(struct mxser_struct *, struct termios *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,7 +515,6 @@ 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); @@ -557,7 +556,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 " ttyMI%d - ttyMI%d ", + printk(KERN_DEBUG " ttyM%d - ttyM%d ", n, n + hwconf->ports - 1); printk(" max. baud rate = %d bps.\n", hwconf->MaxCanSetBaudRate[0]); @@ -718,7 +717,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 = "ttyMI"; + mxvar_sdriver->name = "ttyM"; mxvar_sdriver->major = ttymajor; mxvar_sdriver->minor_start = 0; mxvar_sdriver->num = MXSER_PORTS + 1; @@ -726,8 +725,6 @@ 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; @@ -842,9 +839,9 @@ static int mxser_init(void) index = 0; b = 0; while (b < n) { - pdev = pci_get_device(mxser_pcibrds[b].vendor, + pdev = pci_find_device(mxser_pcibrds[b].vendor, mxser_pcibrds[b].device, pdev); - if (pdev == NULL) { + if (pdev == NULL) { b++; continue; } @@ -896,9 +893,6 @@ 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 @@ -1000,7 +994,7 @@ static int mxser_open(struct tty_struct *tty, struct file *filp) mxser_change_speed(info, NULL); } - info->session = process_session(current); + info->session = current->signal->session; info->pgrp = process_group(current); /* @@ -1751,7 +1745,7 @@ static void mxser_unthrottle(struct tty_struct *tty) /* MX_UNLOCK(&info->slock); */ } -static void mxser_set_termios(struct tty_struct *tty, struct ktermios *old_termios) +static void mxser_set_termios(struct tty_struct *tty, struct termios *old_termios) { struct mxser_struct *info = tty->driver_data; unsigned long flags; @@ -2543,7 +2537,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 ktermios *old_termios) +static int mxser_change_speed(struct mxser_struct *info, struct termios *old_termios) { unsigned cflag, cval, fcr; int ret = 0; diff --git a/trunk/drivers/char/mxser_new.c b/trunk/drivers/char/mxser_new.c deleted file mode 100644 index efa8076c33e0..000000000000 --- a/trunk/drivers/char/mxser_new.c +++ /dev/null @@ -1,2804 +0,0 @@ -/* - * mxser.c -- MOXA Smartio/Industio family multiport serial driver. - * - * Copyright (C) 1999-2006 Moxa Technologies (support@moxa.com.tw). - * Copyright (C) 2006 Jiri Slaby - * - * 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 - * . 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#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/trunk/drivers/char/mxser_new.h b/trunk/drivers/char/mxser_new.h deleted file mode 100644 index a08f0ecb09ba..000000000000 --- a/trunk/drivers/char/mxser_new.h +++ /dev/null @@ -1,450 +0,0 @@ -#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/trunk/drivers/char/n_r3964.c b/trunk/drivers/char/n_r3964.c index 103d338f21e2..203dc2b661d5 100644 --- a/trunk/drivers/char/n_r3964.c +++ b/trunk/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 ktermios * old); +static void r3964_set_termios(struct tty_struct *tty, struct termios * 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 ktermios * old) +static void r3964_set_termios(struct tty_struct *tty, struct termios * old) { TRACE_L("set_termios"); } diff --git a/trunk/drivers/char/n_tty.c b/trunk/drivers/char/n_tty.c index e96a00fe1389..603b9ade5eb0 100644 --- a/trunk/drivers/char/n_tty.c +++ b/trunk/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 ktermios * old) +static void n_tty_set_termios(struct tty_struct *tty, struct termios * old) { if (!tty) return; diff --git a/trunk/drivers/char/nsc_gpio.c b/trunk/drivers/char/nsc_gpio.c index 808d44e9a32a..4d47d79bcea7 100644 --- a/trunk/drivers/char/nsc_gpio.c +++ b/trunk/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_path.dentry->d_inode); + unsigned m = iminor(file->f_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_path.dentry->d_inode); + unsigned m = iminor(file->f_dentry->d_inode); int value; struct nsc_gpio_ops *amp = file->private_data; diff --git a/trunk/drivers/char/pcmcia/synclink_cs.c b/trunk/drivers/char/pcmcia/synclink_cs.c index 5152cedd8878..74d21c1c104f 100644 --- a/trunk/drivers/char/pcmcia/synclink_cs.c +++ b/trunk/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 ktermios *old_termios) +static void mgslpc_set_termios(struct tty_struct *tty, struct termios *old_termios) { MGSLPC_INFO *info = (MGSLPC_INFO *)tty->driver_data; unsigned long flags; diff --git a/trunk/drivers/char/ppdev.c b/trunk/drivers/char/ppdev.c index 4abd1eff61d6..c1e3dd837fc8 100644 --- a/trunk/drivers/char/ppdev.c +++ b/trunk/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_path.dentry->d_inode); + unsigned int minor = iminor(file->f_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_path.dentry->d_inode); + unsigned int minor = iminor(file->f_dentry->d_inode); struct pp_struct *pp = file->private_data; char * kbuffer; ssize_t bytes_written = 0; diff --git a/trunk/drivers/char/pty.c b/trunk/drivers/char/pty.c index c07a1b5cd05d..80d3eedd7f96 100644 --- a/trunk/drivers/char/pty.c +++ b/trunk/drivers/char/pty.c @@ -218,7 +218,7 @@ static int pty_open(struct tty_struct *tty, struct file * filp) return retval; } -static void pty_set_termios(struct tty_struct *tty, struct ktermios *old_termios) +static void pty_set_termios(struct tty_struct *tty, struct termios *old_termios) { tty->termios->c_cflag &= ~(CSIZE | PARENB); tty->termios->c_cflag |= (CS8 | CREAD); @@ -272,8 +272,6 @@ 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); @@ -288,8 +286,6 @@ 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; @@ -370,8 +366,6 @@ 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; @@ -387,8 +381,6 @@ 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/trunk/drivers/char/random.c b/trunk/drivers/char/random.c index 092a01cc02da..4c6782a1ecdb 100644 --- a/trunk/drivers/char/random.c +++ b/trunk/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_path.dentry->d_inode; + struct inode *inode = file->f_dentry->d_inode; inode->i_mtime = current_fs_time(inode->i_sb); mark_inode_dirty(inode); return (ssize_t)(p - buffer); diff --git a/trunk/drivers/char/raw.c b/trunk/drivers/char/raw.c index 645e20a06ece..3b32313f6eb4 100644 --- a/trunk/drivers/char/raw.c +++ b/trunk/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_path.dentry->d_inode->i_mapping = + filp->f_dentry->d_inode->i_mapping = bdev->bd_inode->i_mapping; filp->private_data = bdev; mutex_unlock(&raw_mutex); diff --git a/trunk/drivers/char/riscom8.c b/trunk/drivers/char/riscom8.c index e2a94bfb2a43..0a77bfcd5b5e 100644 --- a/trunk/drivers/char/riscom8.c +++ b/trunk/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 ktermios * old_termios) +static void rc_set_termios(struct tty_struct * tty, struct termios * old_termios) { struct riscom_port *port = (struct riscom_port *)tty->driver_data; unsigned long flags; @@ -1614,8 +1614,6 @@ 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/trunk/drivers/char/rocket.c b/trunk/drivers/char/rocket.c index e94a62e30fc4..bac80056f7e0 100644 --- a/trunk/drivers/char/rocket.c +++ b/trunk/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 ktermios *old_termios) + struct termios *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 = process_session(current); + info->session = current->signal->session; 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 ktermios *old_termios) + struct termios *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_get_device(PCI_VENDOR_ID_RP, PCI_ANY_ID, dev))) { + while ((dev = pci_find_device(PCI_VENDOR_ID_RP, PCI_ANY_ID, dev))) { if (register_PCI(count + boards_found, dev)) count++; } @@ -2436,8 +2436,6 @@ 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/trunk/drivers/char/ser_a2232.c b/trunk/drivers/char/ser_a2232.c index 75de5f66517a..4217d38caef9 100644 --- a/trunk/drivers/char/ser_a2232.c +++ b/trunk/drivers/char/ser_a2232.c @@ -695,8 +695,6 @@ 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/trunk/drivers/char/serial167.c b/trunk/drivers/char/serial167.c index af50d32ae2c7..9ba13af234be 100644 --- a/trunk/drivers/char/serial167.c +++ b/trunk/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 ktermios * old_termios) +cy_set_termios(struct tty_struct *tty, struct termios * old_termios) { struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; diff --git a/trunk/drivers/char/sonypi.c b/trunk/drivers/char/sonypi.c index 17d54e1331b2..fc87070f1866 100644 --- a/trunk/drivers/char/sonypi.c +++ b/trunk/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_path.dentry->d_inode; + struct inode *inode = file->f_dentry->d_inode; inode->i_atime = current_fs_time(inode->i_sb); } diff --git a/trunk/drivers/char/specialix.c b/trunk/drivers/char/specialix.c index 20946f5127e0..99137ab66b62 100644 --- a/trunk/drivers/char/specialix.c +++ b/trunk/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 ktermios * old_termios) +static void sx_set_termios(struct tty_struct * tty, struct termios * old_termios) { struct specialix_port *port = (struct specialix_port *)tty->driver_data; unsigned long flags; @@ -2400,8 +2400,6 @@ 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); @@ -2477,7 +2475,7 @@ static int __init specialix_init(void) i++; continue; } - pdev = pci_get_device (PCI_VENDOR_ID_SPECIALIX, + pdev = pci_find_device (PCI_VENDOR_ID_SPECIALIX, PCI_DEVICE_ID_SPECIALIX_IO8, pdev); if (!pdev) break; @@ -2493,9 +2491,6 @@ 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/trunk/drivers/char/stallion.c b/trunk/drivers/char/stallion.c index e45113a7a472..5e2de62bce70 100644 --- a/trunk/drivers/char/stallion.c +++ b/trunk/drivers/char/stallion.c @@ -41,12 +41,13 @@ #include #include #include -#include #include #include +#ifdef CONFIG_PCI #include +#endif /*****************************************************************************/ @@ -62,16 +63,45 @@ #define BRD_ECH64PCI 27 #define BRD_EASYIOPCI 28 -struct stlconf { - unsigned int brdtype; +/* + * 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; 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 unsigned int stl_nrbrds; +static int stl_nrbrds = ARRAY_SIZE(stl_brdconf); /*****************************************************************************/ @@ -113,13 +143,20 @@ 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 ktermios stl_deftermios = { +static struct termios 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. */ @@ -127,16 +164,13 @@ static char stl_unwanted[SC26198_RXFIFOSIZE]; /*****************************************************************************/ -static DEFINE_MUTEX(stl_brdslock); -static struct stlbrd *stl_brds[STL_MAXBRDS]; +static stlbrd_t *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 @@ -153,32 +187,32 @@ static struct stlbrd *stl_brds[STL_MAXBRDS]; * referencing boards when printing trace and stuff. */ static char *stl_brdnames[] = { - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - 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, + (char *) NULL, "EasyIO", "EC8/32-AT", "EC8/32-MC", - NULL, - NULL, - NULL, + (char *) NULL, + (char *) NULL, + (char *) NULL, "EC8/32-PCI", "EC8/64-PCI", "EasyIO-PCI", @@ -191,7 +225,7 @@ static char *stl_brdnames[] = { * load line. These allow for easy board definitions, and easy * modification of the io, memory and irq resoucres. */ -static unsigned int stl_nargs; +static int stl_nargs = 0; static char *board0[4]; static char *board1[4]; static char *board2[4]; @@ -209,10 +243,12 @@ static char **stl_brdsp[] = { * parse any module arguments. */ -static struct { +typedef struct stlbrdtype { char *name; int type; -} stl_brdstr[] = { +} stlbrdtype_t; + +static stlbrdtype_t stl_brdstr[] = { { "easyio", BRD_EASYIO }, { "eio", BRD_EASYIO }, { "20", BRD_EASYIO }, @@ -246,6 +282,9 @@ static struct { /* * 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]]"); @@ -347,6 +386,8 @@ static spinlock_t stallion_lock; /* Guard the tty driver */ /*****************************************************************************/ +#ifdef CONFIG_PCI + /* * Define the Stallion PCI vendor and device IDs. */ @@ -366,19 +407,22 @@ static spinlock_t stallion_lock; /* Guard the tty driver */ /* * Define structure to hold all Stallion PCI boards. */ - -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 }, - { } +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 }, }; -MODULE_DEVICE_TABLE(pci, stl_pcibrds); + +static int stl_nrpcibrds = ARRAY_SIZE(stl_pcibrds); + +#endif /*****************************************************************************/ @@ -398,74 +442,134 @@ 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_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); +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 /* * CD1400 uart specific handling functions. */ -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); +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); /* * SC26198 uart specific handling functions. */ -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); +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); /*****************************************************************************/ @@ -473,20 +577,20 @@ static void stl_sc26198otherisr(struct stlport *port, unsigned int iack); * Generic UART support structure. */ typedef struct uart { - 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); + 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); } uart_t; /* @@ -608,35 +712,184 @@ 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 __init stl_parsebrd(struct stlconf *confp, char **argp) +static int stl_parsebrd(stlconf_t *confp, char **argp) { char *sp; - unsigned int i; + int i; - pr_debug("stl_parsebrd(confp=%p,argp=%p)\n", confp, argp); +#ifdef DEBUG + printk("stl_parsebrd(confp=%x,argp=%x)\n", (int) confp, (int) argp); +#endif - if ((argp[0] == NULL) || (*argp[0] == 0)) + if ((argp[0] == (char *) 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; @@ -645,16 +898,16 @@ static int __init stl_parsebrd(struct stlconf *confp, char **argp) confp->brdtype = stl_brdstr[i].type; i = 1; - if ((argp[i] != NULL) && (*argp[i] != 0)) - confp->ioaddr1 = simple_strtoul(argp[i], NULL, 0); + if ((argp[i] != (char *) NULL) && (*argp[i] != 0)) + confp->ioaddr1 = stl_atol(argp[i]); i++; if (confp->brdtype == BRD_ECH) { - if ((argp[i] != NULL) && (*argp[i] != 0)) - confp->ioaddr2 = simple_strtoul(argp[i], NULL, 0); + if ((argp[i] != (char *) NULL) && (*argp[i] != 0)) + confp->ioaddr2 = stl_atol(argp[i]); i++; } - if ((argp[i] != NULL) && (*argp[i] != 0)) - confp->irq = simple_strtoul(argp[i], NULL, 0); + if ((argp[i] != (char *) NULL) && (*argp[i] != 0)) + confp->irq = stl_atol(argp[i]); return 1; } @@ -664,14 +917,14 @@ static int __init stl_parsebrd(struct stlconf *confp, char **argp) * Allocate a new board structure. Fill out the basic info in it. */ -static struct stlbrd *stl_allocbrd(void) +static stlbrd_t *stl_allocbrd(void) { - struct stlbrd *brdp; + stlbrd_t *brdp; - brdp = kzalloc(sizeof(struct stlbrd), GFP_KERNEL); + brdp = kzalloc(sizeof(stlbrd_t), GFP_KERNEL); if (!brdp) { printk("STALLION: failed to allocate memory (size=%Zd)\n", - sizeof(struct stlbrd)); + sizeof(stlbrd_t)); return NULL; } @@ -683,23 +936,26 @@ static struct stlbrd *stl_allocbrd(void) static int stl_open(struct tty_struct *tty, struct file *filp) { - 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); + 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 minordev = tty->index; brdnr = MINOR2BRD(minordev); if (brdnr >= stl_nrbrds) return -ENODEV; brdp = stl_brds[brdnr]; - if (brdp == NULL) + if (brdp == (stlbrd_t *) NULL) return -ENODEV; minordev = MINOR2PORT(minordev); - for (portnr = -1, panelnr = 0; panelnr < STL_MAXPANELS; panelnr++) { - if (brdp->panels[panelnr] == NULL) + for (portnr = -1, panelnr = 0; (panelnr < STL_MAXPANELS); panelnr++) { + if (brdp->panels[panelnr] == (stlpanel_t *) NULL) break; if (minordev < brdp->panels[panelnr]->nrports) { portnr = minordev; @@ -711,7 +967,7 @@ static int stl_open(struct tty_struct *tty, struct file *filp) return -ENODEV; portp = brdp->panels[panelnr]->ports[portnr]; - if (portp == NULL) + if (portp == (stlport_t *) NULL) return -ENODEV; /* @@ -757,10 +1013,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; @@ -773,12 +1029,14 @@ 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(struct stlport *portp, struct file *filp) +static int stl_waitcarrier(stlport_t *portp, struct file *filp) { unsigned long flags; int rc, doclocal; - pr_debug("stl_waitcarrier(portp=%p,filp=%p)\n", portp, filp); +#ifdef DEBUG + printk("stl_waitcarrier(portp=%x,filp=%x)\n", (int) portp, (int) filp); +#endif rc = 0; doclocal = 0; @@ -804,8 +1062,9 @@ static int stl_waitcarrier(struct stlport *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; @@ -824,61 +1083,17 @@ static int stl_waitcarrier(struct stlport *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) { - struct stlport *portp; + stlport_t *portp; unsigned long flags; - pr_debug("stl_close(tty=%p,filp=%p)\n", tty, filp); +#ifdef DEBUG + printk("stl_close(tty=%x,filp=%x)\n", (int) tty, (int) filp); +#endif portp = tty->driver_data; - if (portp == NULL) + if (portp == (stlport_t *) NULL) return; spin_lock_irqsave(&stallion_lock, flags); @@ -921,17 +1136,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 != NULL) { + if (portp->tx.buf != (char *) NULL) { kfree(portp->tx.buf); - portp->tx.buf = NULL; - portp->tx.head = NULL; - portp->tx.tail = NULL; + portp->tx.buf = (char *) NULL; + portp->tx.head = (char *) NULL; + portp->tx.tail = (char *) NULL; } set_bit(TTY_IO_ERROR, &tty->flags); tty_ldisc_flush(tty); tty->closing = 0; - portp->tty = NULL; + portp->tty = (struct tty_struct *) NULL; if (portp->openwaitcnt) { if (portp->close_delay) @@ -952,17 +1167,20 @@ 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) { - struct stlport *portp; + stlport_t *portp; unsigned int len, stlen; unsigned char *chbuf; char *head, *tail; - pr_debug("stl_write(tty=%p,buf=%p,count=%d)\n", tty, buf, count); +#ifdef DEBUG + printk("stl_write(tty=%x,buf=%x,count=%d)\n", + (int) tty, (int) buf, count); +#endif portp = tty->driver_data; - if (portp == NULL) + if (portp == (stlport_t *) NULL) return 0; - if (portp->tx.buf == NULL) + if (portp->tx.buf == (char *) NULL) return 0; /* @@ -983,10 +1201,10 @@ static int stl_write(struct tty_struct *tty, const unsigned char *buf, int count stlen = len; } - len = min(len, (unsigned int)count); + len = MIN(len, count); count = 0; while (len > 0) { - stlen = min(len, stlen); + stlen = MIN(len, stlen); memcpy(head, chbuf, stlen); len -= stlen; chbuf += stlen; @@ -1009,18 +1227,20 @@ 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) { - struct stlport *portp; + stlport_t *portp; unsigned int len; char *head, *tail; - pr_debug("stl_putchar(tty=%p,ch=%x)\n", tty, ch); +#ifdef DEBUG + printk("stl_putchar(tty=%x,ch=%x)\n", (int) tty, (int) ch); +#endif - if (tty == NULL) + if (tty == (struct tty_struct *) NULL) return; portp = tty->driver_data; - if (portp == NULL) + if (portp == (stlport_t *) NULL) return; - if (portp->tx.buf == NULL) + if (portp->tx.buf == (char *) NULL) return; head = portp->tx.head; @@ -1047,16 +1267,18 @@ static void stl_putchar(struct tty_struct *tty, unsigned char ch) static void stl_flushchars(struct tty_struct *tty) { - struct stlport *portp; + stlport_t *portp; - pr_debug("stl_flushchars(tty=%p)\n", tty); +#ifdef DEBUG + printk("stl_flushchars(tty=%x)\n", (int) tty); +#endif - if (tty == NULL) + if (tty == (struct tty_struct *) NULL) return; portp = tty->driver_data; - if (portp == NULL) + if (portp == (stlport_t *) NULL) return; - if (portp->tx.buf == NULL) + if (portp->tx.buf == (char *) NULL) return; stl_startrxtx(portp, -1, 1); @@ -1066,22 +1288,24 @@ static void stl_flushchars(struct tty_struct *tty) static int stl_writeroom(struct tty_struct *tty) { - struct stlport *portp; + stlport_t *portp; char *head, *tail; - pr_debug("stl_writeroom(tty=%p)\n", tty); +#ifdef DEBUG + printk("stl_writeroom(tty=%x)\n", (int) tty); +#endif - if (tty == NULL) + if (tty == (struct tty_struct *) NULL) return 0; portp = tty->driver_data; - if (portp == NULL) + if (portp == (stlport_t *) NULL) return 0; - if (portp->tx.buf == NULL) + if (portp->tx.buf == (char *) 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)); } /*****************************************************************************/ @@ -1097,18 +1321,20 @@ static int stl_writeroom(struct tty_struct *tty) static int stl_charsinbuffer(struct tty_struct *tty) { - struct stlport *portp; + stlport_t *portp; unsigned int size; char *head, *tail; - pr_debug("stl_charsinbuffer(tty=%p)\n", tty); +#ifdef DEBUG + printk("stl_charsinbuffer(tty=%x)\n", (int) tty); +#endif - if (tty == NULL) + if (tty == (struct tty_struct *) NULL) return 0; portp = tty->driver_data; - if (portp == NULL) + if (portp == (stlport_t *) NULL) return 0; - if (portp->tx.buf == NULL) + if (portp->tx.buf == (char *) NULL) return 0; head = portp->tx.head; @@ -1125,12 +1351,14 @@ static int stl_charsinbuffer(struct tty_struct *tty) * Generate the serial struct info. */ -static int stl_getserial(struct stlport *portp, struct serial_struct __user *sp) +static int stl_getserial(stlport_t *portp, struct serial_struct __user *sp) { struct serial_struct sio; - struct stlbrd *brdp; + stlbrd_t *brdp; - pr_debug("stl_getserial(portp=%p,sp=%p)\n", portp, sp); +#ifdef DEBUG + printk("stl_getserial(portp=%x,sp=%x)\n", (int) portp, (int) sp); +#endif memset(&sio, 0, sizeof(struct serial_struct)); sio.line = portp->portnr; @@ -1150,7 +1378,7 @@ static int stl_getserial(struct stlport *portp, struct serial_struct __user *sp) } brdp = stl_brds[portp->brdnr]; - if (brdp != NULL) + if (brdp != (stlbrd_t *) NULL) sio.irq = brdp->irq; return copy_to_user(sp, &sio, sizeof(struct serial_struct)) ? -EFAULT : 0; @@ -1164,11 +1392,13 @@ static int stl_getserial(struct stlport *portp, struct serial_struct __user *sp) * just quietly ignore any requests to change irq, etc. */ -static int stl_setserial(struct stlport *portp, struct serial_struct __user *sp) +static int stl_setserial(stlport_t *portp, struct serial_struct __user *sp) { struct serial_struct sio; - pr_debug("stl_setserial(portp=%p,sp=%p)\n", portp, sp); +#ifdef DEBUG + printk("stl_setserial(portp=%x,sp=%x)\n", (int) portp, (int) sp); +#endif if (copy_from_user(&sio, sp, sizeof(struct serial_struct))) return -EFAULT; @@ -1194,12 +1424,12 @@ static int stl_setserial(struct stlport *portp, struct serial_struct __user *sp) static int stl_tiocmget(struct tty_struct *tty, struct file *file) { - struct stlport *portp; + stlport_t *portp; - if (tty == NULL) + if (tty == (struct tty_struct *) NULL) return -ENODEV; portp = tty->driver_data; - if (portp == NULL) + if (portp == (stlport_t *) NULL) return -ENODEV; if (tty->flags & (1 << TTY_IO_ERROR)) return -EIO; @@ -1210,13 +1440,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) { - struct stlport *portp; + stlport_t *portp; int rts = -1, dtr = -1; - if (tty == NULL) + if (tty == (struct tty_struct *) NULL) return -ENODEV; portp = tty->driver_data; - if (portp == NULL) + if (portp == (stlport_t *) NULL) return -ENODEV; if (tty->flags & (1 << TTY_IO_ERROR)) return -EIO; @@ -1236,24 +1466,27 @@ 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) { - struct stlport *portp; + stlport_t *portp; unsigned int ival; int rc; void __user *argp = (void __user *)arg; - pr_debug("stl_ioctl(tty=%p,file=%p,cmd=%x,arg=%lx)\n", tty, file, cmd, - arg); +#ifdef DEBUG + printk("stl_ioctl(tty=%x,file=%x,cmd=%x,arg=%x)\n", + (int) tty, (int) file, cmd, (int) arg); +#endif - if (tty == NULL) + if (tty == (struct tty_struct *) NULL) return -ENODEV; portp = tty->driver_data; - if (portp == NULL) + if (portp == (stlport_t *) 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; @@ -1298,37 +1531,19 @@ static int stl_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd /*****************************************************************************/ -/* - * Start the transmitter again. Just turn TX interrupts back on. - */ - -static void stl_start(struct tty_struct *tty) -{ - struct stlport *portp; - - pr_debug("stl_start(tty=%p)\n", tty); - - if (tty == NULL) - return; - portp = tty->driver_data; - if (portp == NULL) - return; - stl_startrxtx(portp, -1, 1); -} - -/*****************************************************************************/ - -static void stl_settermios(struct tty_struct *tty, struct ktermios *old) +static void stl_settermios(struct tty_struct *tty, struct termios *old) { - struct stlport *portp; - struct ktermios *tiosp; + stlport_t *portp; + struct termios *tiosp; - pr_debug("stl_settermios(tty=%p,old=%p)\n", tty, old); +#ifdef DEBUG + printk("stl_settermios(tty=%x,old=%x)\n", (int) tty, (int) old); +#endif - if (tty == NULL) + if (tty == (struct tty_struct *) NULL) return; portp = tty->driver_data; - if (portp == NULL) + if (portp == (stlport_t *) NULL) return; tiosp = tty->termios; @@ -1356,14 +1571,16 @@ static void stl_settermios(struct tty_struct *tty, struct ktermios *old) static void stl_throttle(struct tty_struct *tty) { - struct stlport *portp; + stlport_t *portp; - pr_debug("stl_throttle(tty=%p)\n", tty); +#ifdef DEBUG + printk("stl_throttle(tty=%x)\n", (int) tty); +#endif - if (tty == NULL) + if (tty == (struct tty_struct *) NULL) return; portp = tty->driver_data; - if (portp == NULL) + if (portp == (stlport_t *) NULL) return; stl_flowctrl(portp, 0); } @@ -1376,14 +1593,16 @@ static void stl_throttle(struct tty_struct *tty) static void stl_unthrottle(struct tty_struct *tty) { - struct stlport *portp; + stlport_t *portp; - pr_debug("stl_unthrottle(tty=%p)\n", tty); +#ifdef DEBUG + printk("stl_unthrottle(tty=%x)\n", (int) tty); +#endif - if (tty == NULL) + if (tty == (struct tty_struct *) NULL) return; portp = tty->driver_data; - if (portp == NULL) + if (portp == (stlport_t *) NULL) return; stl_flowctrl(portp, 1); } @@ -1397,20 +1616,44 @@ static void stl_unthrottle(struct tty_struct *tty) static void stl_stop(struct tty_struct *tty) { - struct stlport *portp; + stlport_t *portp; - pr_debug("stl_stop(tty=%p)\n", tty); +#ifdef DEBUG + printk("stl_stop(tty=%x)\n", (int) tty); +#endif - if (tty == NULL) + if (tty == (struct tty_struct *) NULL) return; portp = tty->driver_data; - if (portp == NULL) + if (portp == (stlport_t *) NULL) return; stl_startrxtx(portp, -1, 0); } /*****************************************************************************/ +/* + * 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 @@ -1419,14 +1662,16 @@ static void stl_stop(struct tty_struct *tty) static void stl_hangup(struct tty_struct *tty) { - struct stlport *portp; + stlport_t *portp; - pr_debug("stl_hangup(tty=%p)\n", tty); +#ifdef DEBUG + printk("stl_hangup(tty=%x)\n", (int) tty); +#endif - if (tty == NULL) + if (tty == (struct tty_struct *) NULL) return; portp = tty->driver_data; - if (portp == NULL) + if (portp == (stlport_t *) NULL) return; portp->flags &= ~ASYNC_INITIALIZED; @@ -1437,13 +1682,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 != NULL) { + if (portp->tx.buf != (char *) NULL) { kfree(portp->tx.buf); - portp->tx.buf = NULL; - portp->tx.head = NULL; - portp->tx.tail = NULL; + portp->tx.buf = (char *) NULL; + portp->tx.head = (char *) NULL; + portp->tx.tail = (char *) NULL; } - portp->tty = NULL; + portp->tty = (struct tty_struct *) NULL; portp->flags &= ~ASYNC_NORMAL_ACTIVE; portp->refcount = 0; wake_up_interruptible(&portp->open_wait); @@ -1451,16 +1696,38 @@ 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) { - struct stlport *portp; + stlport_t *portp; - pr_debug("stl_breakctl(tty=%p,state=%d)\n", tty, state); +#ifdef DEBUG + printk("stl_breakctl(tty=%x,state=%d)\n", (int) tty, state); +#endif - if (tty == NULL) + if (tty == (struct tty_struct *) NULL) return; portp = tty->driver_data; - if (portp == NULL) + if (portp == (stlport_t *) NULL) return; stl_sendbreak(portp, ((state == -1) ? 1 : 2)); @@ -1468,16 +1735,48 @@ 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) { - struct stlport *portp; + stlport_t *portp; - pr_debug("stl_sendxchar(tty=%p,ch=%x)\n", tty, ch); +#ifdef DEBUG + printk("stl_sendxchar(tty=%x,ch=%x)\n", (int) tty, ch); +#endif - if (tty == NULL) + if (tty == (struct tty_struct *) NULL) return; portp = tty->driver_data; - if (portp == NULL) + if (portp == (stlport_t *) NULL) return; if (ch == STOP_CHAR(tty)) @@ -1498,7 +1797,7 @@ static void stl_sendxchar(struct tty_struct *tty, char ch) * short then padded with spaces). */ -static int stl_portinfo(struct stlport *portp, int portnr, char *pos) +static int stl_portinfo(stlport_t *portp, int portnr, char *pos) { char *sp; int sigs, cnt; @@ -1527,7 +1826,7 @@ static int stl_portinfo(struct stlport *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)] = '+'; @@ -1544,15 +1843,18 @@ static int stl_portinfo(struct stlport *portp, int portnr, char *pos) static int stl_readproc(char *page, char **start, off_t off, int count, int *eof, void *data) { - struct stlbrd *brdp; - struct stlpanel *panelp; - struct stlport *portp; - unsigned int brdnr, panelnr, portnr; - int totalport, curoff, maxoff; + stlbrd_t *brdp; + stlpanel_t *panelp; + stlport_t *portp; + int brdnr, panelnr, portnr, totalport; + int curoff, maxoff; char *pos; - pr_debug("stl_readproc(page=%p,start=%p,off=%lx,count=%d,eof=%p," - "data=%p\n", page, start, off, count, eof, data); +#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 pos = page; totalport = 0; @@ -1571,9 +1873,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 == NULL) + if (brdp == (stlbrd_t *) NULL) continue; if (brdp->state == 0) continue; @@ -1585,9 +1887,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 == NULL) + if (panelp == (stlpanel_t *) NULL) continue; maxoff = curoff + (panelp->nrports * MAXLINE); @@ -1597,10 +1899,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 == NULL) + if (portp == (stlport_t *) NULL) continue; if (off >= (curoff += MAXLINE)) continue; @@ -1615,7 +1917,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); } /*****************************************************************************/ @@ -1627,9 +1929,11 @@ static int stl_readproc(char *page, char **start, off_t off, int count, int *eof static irqreturn_t stl_intr(int irq, void *dev_id) { - struct stlbrd *brdp = dev_id; + stlbrd_t *brdp = (stlbrd_t *) dev_id; - pr_debug("stl_intr(brdp=%p,irq=%d)\n", brdp, irq); +#ifdef DEBUG + printk("stl_intr(brdp=%x,irq=%d)\n", (int) brdp, irq); +#endif return IRQ_RETVAL((* brdp->isr)(brdp)); } @@ -1640,9 +1944,9 @@ static irqreturn_t stl_intr(int irq, void *dev_id) * Interrupt service routine for EasyIO board types. */ -static int stl_eiointr(struct stlbrd *brdp) +static int stl_eiointr(stlbrd_t *brdp) { - struct stlpanel *panelp; + stlpanel_t *panelp; unsigned int iobase; int handled = 0; @@ -1663,17 +1967,18 @@ static int stl_eiointr(struct stlbrd *brdp) * Interrupt service routine for ECH-AT board types. */ -static int stl_echatintr(struct stlbrd *brdp) +static int stl_echatintr(stlbrd_t *brdp) { - struct stlpanel *panelp; - unsigned int ioaddr, bnknr; + stlpanel_t *panelp; + unsigned int ioaddr; + int 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]; @@ -1693,15 +1998,16 @@ static int stl_echatintr(struct stlbrd *brdp) * Interrupt service routine for ECH-MCA board types. */ -static int stl_echmcaintr(struct stlbrd *brdp) +static int stl_echmcaintr(stlbrd_t *brdp) { - struct stlpanel *panelp; - unsigned int ioaddr, bnknr; + stlpanel_t *panelp; + unsigned int ioaddr; + int 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]; @@ -1718,15 +2024,16 @@ static int stl_echmcaintr(struct stlbrd *brdp) * Interrupt service routine for ECH-PCI board types. */ -static int stl_echpciintr(struct stlbrd *brdp) +static int stl_echpciintr(stlbrd_t *brdp) { - struct stlpanel *panelp; - unsigned int ioaddr, bnknr, recheck; + stlpanel_t *panelp; + unsigned int ioaddr; + int 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) { @@ -1748,15 +2055,16 @@ static int stl_echpciintr(struct stlbrd *brdp) * Interrupt service routine for ECH-8/64-PCI board types. */ -static int stl_echpci64intr(struct stlbrd *brdp) +static int stl_echpci64intr(stlbrd_t *brdp) { - struct stlpanel *panelp; - unsigned int ioaddr, bnknr; + stlpanel_t *panelp; + unsigned int ioaddr; + int 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]; @@ -1775,32 +2083,35 @@ static int stl_echpci64intr(struct stlbrd *brdp) */ static void stl_offintr(struct work_struct *work) { - struct stlport *portp = container_of(work, struct stlport, tqueue); + stlport_t *portp = container_of(work, stlport_t, tqueue); struct tty_struct *tty; unsigned int oldsigs; - pr_debug("stl_offintr(portp=%p)\n", portp); +#ifdef DEBUG + printk("stl_offintr(portp=%x)\n", (int) portp); +#endif - if (portp == NULL) + if (portp == (stlport_t *) NULL) return; tty = portp->tty; - if (tty == NULL) + if (tty == (struct tty_struct *) 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(); } @@ -1811,13 +2122,14 @@ static void stl_offintr(struct work_struct *work) * Initialize all the ports on a panel. */ -static int __devinit stl_initports(struct stlbrd *brdp, struct stlpanel *panelp) +static int __init stl_initports(stlbrd_t *brdp, stlpanel_t *panelp) { - struct stlport *portp; - unsigned int i; - int chipmask; + stlport_t *portp; + int chipmask, i; - pr_debug("stl_initports(brdp=%p,panelp=%p)\n", brdp, panelp); +#ifdef DEBUG + printk("stl_initports(brdp=%x,panelp=%x)\n", (int) brdp, (int) panelp); +#endif chipmask = stl_panelinit(brdp, panelp); @@ -1825,11 +2137,11 @@ static int __devinit stl_initports(struct stlbrd *brdp, struct stlpanel *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(struct stlport), GFP_KERNEL); + for (i = 0; (i < panelp->nrports); i++) { + portp = kzalloc(sizeof(stlport_t), GFP_KERNEL); if (!portp) { printk("STALLION: failed to allocate memory " - "(size=%Zd)\n", sizeof(struct stlport)); + "(size=%Zd)\n", sizeof(stlport_t)); break; } @@ -1852,30 +2164,7 @@ static int __devinit stl_initports(struct stlbrd *brdp, struct stlpanel *panelp) stl_portinit(brdp, panelp, portp); } - 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); - } + return(0); } /*****************************************************************************/ @@ -1884,14 +2173,16 @@ static void stl_cleanup_panels(struct stlbrd *brdp) * Try to find and initialize an EasyIO board. */ -static int __devinit stl_initeio(struct stlbrd *brdp) +static inline int stl_initeio(stlbrd_t *brdp) { - struct stlpanel *panelp; + stlpanel_t *panelp; unsigned int status; char *name; - int retval; + int rc; - pr_debug("stl_initeio(brdp=%p)\n", brdp); +#ifdef DEBUG + printk("stl_initeio(brdp=%x)\n", (int) brdp); +#endif brdp->ioctrl = brdp->ioaddr1 + 1; brdp->iostatus = brdp->ioaddr1 + 2; @@ -1916,20 +2207,18 @@ static int __devinit stl_initeio(struct stlbrd *brdp) (stl_vecmap[brdp->irq] == (unsigned char) 0xff)) { printk("STALLION: invalid irq=%d for brd=%d\n", brdp->irq, brdp->brdnr); - retval = -EINVAL; - goto err; + return(-EINVAL); } 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); - goto err; + return(-EBUSY); } if (brdp->iosize2 > 0) @@ -1940,7 +2229,8 @@ static int __devinit stl_initeio(struct stlbrd *brdp) printk(KERN_WARNING "STALLION: Warning, also " "releasing board %d I/O address %x \n", brdp->brdnr, brdp->ioaddr1); - goto err_rel1; + release_region(brdp->ioaddr1, brdp->iosize1); + return(-EBUSY); } /* @@ -1949,7 +2239,6 @@ static int __devinit stl_initeio(struct stlbrd *brdp) brdp->clk = CD1400_CLK; brdp->isr = stl_eiointr; - retval = -ENODEV; switch (status & EIO_IDBITMASK) { case EIO_8PORTM: brdp->clk = CD1400_CLK8M; @@ -1973,11 +2262,11 @@ static int __devinit stl_initeio(struct stlbrd *brdp) brdp->nrports = 16; break; default: - goto err_rel2; + return(-ENODEV); } break; default: - goto err_rel2; + return(-ENODEV); } /* @@ -1985,12 +2274,11 @@ static int __devinit stl_initeio(struct stlbrd *brdp) * can complete the setup. */ - panelp = kzalloc(sizeof(struct stlpanel), GFP_KERNEL); + panelp = kzalloc(sizeof(stlpanel_t), GFP_KERNEL); if (!panelp) { printk(KERN_WARNING "STALLION: failed to allocate memory " - "(size=%Zd)\n", sizeof(struct stlpanel)); - retval = -ENOMEM; - goto err_rel2; + "(size=%Zd)\n", sizeof(stlpanel_t)); + return -ENOMEM; } panelp->magic = STL_PANELMAGIC; @@ -2000,10 +2288,10 @@ static int __devinit stl_initeio(struct stlbrd *brdp) panelp->iobase = brdp->ioaddr1; panelp->hwid = status; if ((status & EIO_IDBITMASK) == EIO_MK3) { - panelp->uartp = &stl_sc26198uart; + panelp->uartp = (void *) &stl_sc26198uart; panelp->isr = stl_sc26198intr; } else { - panelp->uartp = &stl_cd1400uart; + panelp->uartp = (void *) &stl_cd1400uart; panelp->isr = stl_cd1400eiointr; } @@ -2014,20 +2302,11 @@ static int __devinit stl_initeio(struct stlbrd *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); - retval = -ENODEV; - goto err_fr; + rc = -ENODEV; + } else { + rc = 0; } - - 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; + return rc; } /*****************************************************************************/ @@ -2037,14 +2316,16 @@ static int __devinit stl_initeio(struct stlbrd *brdp) * dealing with all types of ECH board. */ -static int __devinit stl_initech(struct stlbrd *brdp) +static inline int stl_initech(stlbrd_t *brdp) { - struct stlpanel *panelp; - unsigned int status, nxtid, ioaddr, conflict, panelnr, banknr, i; - int retval; + stlpanel_t *panelp; + unsigned int status, nxtid, ioaddr, conflict; + int panelnr, banknr, i; char *name; - pr_debug("stl_initech(brdp=%p)\n", brdp); +#ifdef DEBUG + printk("stl_initech(brdp=%x)\n", (int) brdp); +#endif status = 0; conflict = 0; @@ -2061,23 +2342,20 @@ static int __devinit stl_initech(struct stlbrd *brdp) brdp->ioctrl = brdp->ioaddr1 + 1; brdp->iostatus = brdp->ioaddr1 + 1; status = inb(brdp->iostatus); - if ((status & ECH_IDBITMASK) != ECH_ID) { - retval = -ENODEV; - goto err; - } + if ((status & ECH_IDBITMASK) != ECH_ID) + return(-ENODEV); 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); - retval = -EINVAL; - goto err; + return(-EINVAL); } 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; @@ -2090,16 +2368,13 @@ static int __devinit stl_initech(struct stlbrd *brdp) brdp->ioctrl = brdp->ioaddr1 + 0x20; brdp->iostatus = brdp->ioctrl; status = inb(brdp->iostatus); - if ((status & ECH_IDBITMASK) != ECH_ID) { - retval = -ENODEV; - goto err; - } + if ((status & ECH_IDBITMASK) != ECH_ID) + return(-ENODEV); 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); - retval = -EINVAL; - goto err; + return(-EINVAL); } outb(ECHMC_BRDRESET, brdp->ioctrl); outb(ECHMC_INTENABLE, brdp->ioctrl); @@ -2126,20 +2401,19 @@ static int __devinit stl_initech(struct stlbrd *brdp) default: printk("STALLION: unknown board type=%d\n", brdp->brdtype); - retval = -EINVAL; - goto err; + return(-EINVAL); + break; } /* * 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); - goto err; + return(-EBUSY); } if (brdp->iosize2 > 0) @@ -2150,7 +2424,8 @@ static int __devinit stl_initech(struct stlbrd *brdp) printk(KERN_WARNING "STALLION: Warning, also " "releasing board %d I/O address %x \n", brdp->brdnr, brdp->ioaddr1); - goto err_rel1; + release_region(brdp->ioaddr1, brdp->iosize1); + return(-EBUSY); } /* @@ -2165,19 +2440,19 @@ static int __devinit stl_initech(struct stlbrd *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) - goto err_fr; - panelp = kzalloc(sizeof(struct stlpanel), GFP_KERNEL); + break; + panelp = kzalloc(sizeof(stlpanel_t), GFP_KERNEL); if (!panelp) { printk("STALLION: failed to allocate memory " - "(size=%Zd)\n", sizeof(struct stlpanel)); - goto err_fr; + "(size=%Zd)\n", sizeof(stlpanel_t)); + break; } panelp->magic = STL_PANELMAGIC; panelp->brdnr = brdp->brdnr; @@ -2190,7 +2465,7 @@ static int __devinit stl_initech(struct stlbrd *brdp) brdp->bnkstataddr[banknr++] = ioaddr + ECH_PNLSTATUS; if (status & ECH_PNLXPID) { - panelp->uartp = &stl_sc26198uart; + panelp->uartp = (void *) &stl_sc26198uart; panelp->isr = stl_sc26198intr; if (status & ECH_PNL16PORT) { panelp->nrports = 16; @@ -2198,10 +2473,11 @@ static int __devinit stl_initech(struct stlbrd *brdp) brdp->bnkpageaddr[banknr] = nxtid; brdp->bnkstataddr[banknr++] = ioaddr + 4 + ECH_PNLSTATUS; - } else + } else { panelp->nrports = 8; + } } else { - panelp->uartp = &stl_cd1400uart; + panelp->uartp = (void *) &stl_cd1400uart; panelp->isr = stl_cd1400echintr; if (status & ECH_PNL16PORT) { panelp->nrports = 16; @@ -2224,7 +2500,7 @@ static int __devinit stl_initech(struct stlbrd *brdp) brdp->panels[panelnr++] = panelp; if ((brdp->brdtype != BRD_ECHPCI) && (ioaddr >= (brdp->ioaddr2 + brdp->iosize2))) - goto err_fr; + break; } brdp->nrpanels = panelnr; @@ -2236,19 +2512,12 @@ static int __devinit stl_initech(struct stlbrd *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); - retval = -ENODEV; - goto err_fr; + i = -ENODEV; + } else { + i = 0; } - 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; + return(i); } /*****************************************************************************/ @@ -2260,61 +2529,48 @@ static int __devinit stl_initech(struct stlbrd *brdp) * since the initial search and setup is very different. */ -static int __devinit stl_brdinit(struct stlbrd *brdp) +static int __init stl_brdinit(stlbrd_t *brdp) { - int i, retval; + int i; - pr_debug("stl_brdinit(brdp=%p)\n", brdp); +#ifdef DEBUG + printk("stl_brdinit(brdp=%x)\n", (int) brdp); +#endif switch (brdp->brdtype) { case BRD_EASYIO: case BRD_EASYIOPCI: - retval = stl_initeio(brdp); - if (retval) - goto err; + stl_initeio(brdp); break; case BRD_ECH: case BRD_ECHMC: case BRD_ECHPCI: case BRD_ECH64PCI: - retval = stl_initech(brdp); - if (retval) - goto err; + stl_initech(brdp); break; default: printk("STALLION: board=%d is unknown board type=%d\n", brdp->brdnr, brdp->brdtype); - retval = -ENODEV; - goto err; + return(ENODEV); } + 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); - goto err_free; + return(ENODEV); } - for (i = 0; i < STL_MAXPANELS; i++) - if (brdp->panels[i] != NULL) + for (i = 0; (i < STL_MAXPANELS); i++) + if (brdp->panels[i] != (stlpanel_t *) 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; -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; + return(0); } /*****************************************************************************/ @@ -2323,62 +2579,59 @@ static int __devinit stl_brdinit(struct stlbrd *brdp) * Find the next available board number that is free. */ -static int __devinit stl_getbrdnr(void) +static inline int stl_getbrdnr(void) { - unsigned int i; + int i; - for (i = 0; i < STL_MAXBRDS; i++) - if (stl_brds[i] == NULL) { + for (i = 0; (i < STL_MAXBRDS); i++) { + if (stl_brds[i] == (stlbrd_t *) 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 int __devinit stl_pciprobe(struct pci_dev *pdev, - const struct pci_device_id *ent) +static inline int stl_initpcibrd(int brdtype, struct pci_dev *devp) { - 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, " + 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, " "maximum supported %d\n", STL_MAXBRDS); - mutex_unlock(&stl_brdslock); - goto err_fr; + return(0); } - brdp->brdnr = (unsigned int)brdnr; - stl_brds[brdp->brdnr] = brdp; - mutex_unlock(&stl_brdslock); - brdp->brdtype = brdtype; - brdp->state |= STL_PROBED; + +/* + * 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 /* * We have all resources from the board, so let's setup the actual @@ -2386,70 +2639,120 @@ static int __devinit stl_pciprobe(struct pci_dev *pdev, */ switch (brdtype) { case BRD_ECHPCI: - brdp->ioaddr2 = pci_resource_start(pdev, 0); - brdp->ioaddr1 = pci_resource_start(pdev, 1); + brdp->ioaddr2 = pci_resource_start(devp, 0); + brdp->ioaddr1 = pci_resource_start(devp, 1); break; case BRD_ECH64PCI: - brdp->ioaddr2 = pci_resource_start(pdev, 2); - brdp->ioaddr1 = pci_resource_start(pdev, 1); + brdp->ioaddr2 = pci_resource_start(devp, 2); + brdp->ioaddr1 = pci_resource_start(devp, 1); break; case BRD_EASYIOPCI: - brdp->ioaddr1 = pci_resource_start(pdev, 2); - brdp->ioaddr2 = pci_resource_start(pdev, 1); + brdp->ioaddr1 = pci_resource_start(devp, 2); + brdp->ioaddr2 = pci_resource_start(devp, 1); break; default: - dev_err(&pdev->dev, "unknown PCI board type=%u\n", brdtype); + printk("STALLION: unknown PCI board type=%d\n", brdtype); break; } - brdp->irq = pdev->irq; - retval = stl_brdinit(brdp); - if (retval) - goto err_null; + 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. + */ + + +static inline int stl_findpcibrds(void) +{ + struct pci_dev *dev = NULL; + int i, rc; + +#ifdef DEBUG + printk("stl_findpcibrds()\n"); +#endif + + 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); + } + + return(0); +} - pci_set_drvdata(pdev, brdp); +#endif - for (i = 0; i < brdp->nrports; i++) - tty_register_device(stl_serial, - brdp->brdnr * STL_MAXPORTS + i, &pdev->dev); +/*****************************************************************************/ - return 0; -err_null: - stl_brds[brdp->brdnr] = NULL; -err_fr: - kfree(brdp); -err: - return retval; -} +/* + * 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 void __devexit stl_pciremove(struct pci_dev *pdev) +static inline int stl_initbrds(void) { - struct stlbrd *brdp = pci_get_drvdata(pdev); - unsigned int i; + stlbrd_t *brdp; + stlconf_t *confp; + int i; - free_irq(brdp->irq, brdp); +#ifdef DEBUG + printk("stl_initbrds()\n"); +#endif - stl_cleanup_panels(brdp); + if (stl_nrbrds > STL_MAXBRDS) { + printk("STALLION: too many boards in configuration table, " + "truncating to %d\n", STL_MAXBRDS); + stl_nrbrds = STL_MAXBRDS; + } - release_region(brdp->ioaddr1, brdp->iosize1); - if (brdp->iosize2 > 0) - release_region(brdp->ioaddr2, brdp->iosize2); +/* + * 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); + } - for (i = 0; i < brdp->nrports; i++) - tty_unregister_device(stl_serial, - brdp->brdnr * STL_MAXPORTS + i); +/* + * 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 - stl_brds[brdp->brdnr] = NULL; - kfree(brdp); + return(0); } -static struct pci_driver stl_pcidriver = { - .name = "stallion", - .id_table = stl_pcibrds, - .probe = stl_pciprobe, - .remove = __devexit_p(stl_pciremove) -}; - /*****************************************************************************/ /* @@ -2458,18 +2761,17 @@ static struct pci_driver stl_pcidriver = { static int stl_getbrdstats(combrd_t __user *bp) { - combrd_t stl_brdstats; - struct stlbrd *brdp; - struct stlpanel *panelp; - unsigned int i; + stlbrd_t *brdp; + stlpanel_t *panelp; + 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 == NULL) - return -ENODEV; + if (brdp == (stlbrd_t *) NULL) + return(-ENODEV); memset(&stl_brdstats, 0, sizeof(combrd_t)); stl_brdstats.brd = brdp->brdnr; @@ -2481,7 +2783,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; @@ -2497,24 +2799,24 @@ static int stl_getbrdstats(combrd_t __user *bp) * Resolve the referenced port number into a port struct pointer. */ -static struct stlport *stl_getport(int brdnr, int panelnr, int portnr) +static stlport_t *stl_getport(int brdnr, int panelnr, int portnr) { - struct stlbrd *brdp; - struct stlpanel *panelp; + stlbrd_t *brdp; + stlpanel_t *panelp; - if (brdnr < 0 || brdnr >= STL_MAXBRDS) - return NULL; + if ((brdnr < 0) || (brdnr >= STL_MAXBRDS)) + return((stlport_t *) NULL); brdp = stl_brds[brdnr]; - if (brdp == NULL) - return NULL; - if (panelnr < 0 || (unsigned int)panelnr >= brdp->nrpanels) - return NULL; + if (brdp == (stlbrd_t *) NULL) + return((stlport_t *) NULL); + if ((panelnr < 0) || (panelnr >= brdp->nrpanels)) + return((stlport_t *) NULL); panelp = brdp->panels[panelnr]; - if (panelp == NULL) - return NULL; - if (portnr < 0 || (unsigned int)portnr >= panelp->nrports) - return NULL; - return panelp->ports[portnr]; + if (panelp == (stlpanel_t *) NULL) + return((stlport_t *) NULL); + if ((portnr < 0) || (portnr >= panelp->nrports)) + return((stlport_t *) NULL); + return(panelp->ports[portnr]); } /*****************************************************************************/ @@ -2525,9 +2827,8 @@ static struct stlport *stl_getport(int brdnr, int panelnr, int portnr) * what port to get stats for (used through board control device). */ -static int stl_getportstats(struct stlport *portp, comstats_t __user *cp) +static int stl_getportstats(stlport_t *portp, comstats_t __user *cp) { - comstats_t stl_comstats; unsigned char *head, *tail; unsigned long flags; @@ -2536,8 +2837,8 @@ static int stl_getportstats(struct stlport *portp, comstats_t __user *cp) return -EFAULT; portp = stl_getport(stl_comstats.brd, stl_comstats.panel, stl_comstats.port); - if (portp == NULL) - return -ENODEV; + if (portp == (stlport_t *) NULL) + return(-ENODEV); } portp->stats.state = portp->istate; @@ -2552,24 +2853,25 @@ static int stl_getportstats(struct stlport *portp, comstats_t __user *cp) portp->stats.rxbuffered = 0; spin_lock_irqsave(&stallion_lock, flags); - if (portp->tty != NULL) + if (portp->tty != (struct tty_struct *) 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 != NULL) { + if (portp->tty->termios != (struct 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); @@ -2583,17 +2885,15 @@ static int stl_getportstats(struct stlport *portp, comstats_t __user *cp) * Clear the port stats structure. We also return it zeroed out... */ -static int stl_clrportstats(struct stlport *portp, comstats_t __user *cp) +static int stl_clrportstats(stlport_t *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 == NULL) - return -ENODEV; + if (portp == (stlport_t *) NULL) + return(-ENODEV); } memset(&portp->stats, 0, sizeof(comstats_t)); @@ -2610,18 +2910,17 @@ static int stl_clrportstats(struct stlport *portp, comstats_t __user *cp) * Return the entire driver ports structure to a user app. */ -static int stl_getportstruct(struct stlport __user *arg) +static int stl_getportstruct(stlport_t __user *arg) { - struct stlport stl_dummyport; - struct stlport *portp; + stlport_t *portp; - if (copy_from_user(&stl_dummyport, arg, sizeof(struct stlport))) + if (copy_from_user(&stl_dummyport, arg, sizeof(stlport_t))) 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(struct stlport)) ? -EFAULT : 0; + return copy_to_user(arg, portp, sizeof(stlport_t)) ? -EFAULT : 0; } /*****************************************************************************/ @@ -2630,19 +2929,18 @@ static int stl_getportstruct(struct stlport __user *arg) * Return the entire driver board structure to a user app. */ -static int stl_getbrdstruct(struct stlbrd __user *arg) +static int stl_getbrdstruct(stlbrd_t __user *arg) { - struct stlbrd stl_dummybrd; - struct stlbrd *brdp; + stlbrd_t *brdp; - if (copy_from_user(&stl_dummybrd, arg, sizeof(struct stlbrd))) + if (copy_from_user(&stl_dummybrd, arg, sizeof(stlbrd_t))) return -EFAULT; - if (stl_dummybrd.brdnr >= STL_MAXBRDS) + if ((stl_dummybrd.brdnr < 0) || (stl_dummybrd.brdnr >= STL_MAXBRDS)) return -ENODEV; brdp = stl_brds[stl_dummybrd.brdnr]; if (!brdp) - return -ENODEV; - return copy_to_user(arg, brdp, sizeof(struct stlbrd)) ? -EFAULT : 0; + return(-ENODEV); + return copy_to_user(arg, brdp, sizeof(stlbrd_t)) ? -EFAULT : 0; } /*****************************************************************************/ @@ -2658,11 +2956,14 @@ static int stl_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, uns int brdnr, rc; void __user *argp = (void __user *)arg; - pr_debug("stl_memioctl(ip=%p,fp=%p,cmd=%x,arg=%lx)\n", ip, fp, cmd,arg); +#ifdef DEBUG + printk("stl_memioctl(ip=%x,fp=%x,cmd=%x,arg=%x)\n", (int) ip, + (int) fp, cmd, (int) arg); +#endif brdnr = iminor(ip); if (brdnr >= STL_MAXBRDS) - return -ENODEV; + return(-ENODEV); rc = 0; switch (cmd) { @@ -2686,7 +2987,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 = { @@ -2713,6 +3014,55 @@ static const struct tty_operations stl_ops = { .tiocmset = stl_tiocmset, }; +/*****************************************************************************/ + +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 */ /*****************************************************************************/ @@ -2723,21 +3073,21 @@ static const struct tty_operations stl_ops = { * (Maybe should make this inline...) */ -static int stl_cd1400getreg(struct stlport *portp, int regnr) +static int stl_cd1400getreg(stlport_t *portp, int regnr) { outb((regnr + portp->uartaddr), portp->ioaddr); return inb(portp->ioaddr + EREG_DATA); } -static void stl_cd1400setreg(struct stlport *portp, int regnr, int value) +static void stl_cd1400setreg(stlport_t *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(struct stlport *portp, int regnr, int value) +static int stl_cd1400updatereg(stlport_t *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; @@ -2753,14 +3103,16 @@ static int stl_cd1400updatereg(struct stlport *portp, int regnr, int value) * identical when dealing with ports. */ -static int stl_cd1400panelinit(struct stlbrd *brdp, struct stlpanel *panelp) +static int stl_cd1400panelinit(stlbrd_t *brdp, stlpanel_t *panelp) { unsigned int gfrcr; int chipmask, i, j; int nrchips, uartaddr, ioaddr; unsigned long flags; - pr_debug("stl_panelinit(brdp=%p,panelp=%p)\n", brdp, panelp); +#ifdef DEBUG + printk("stl_panelinit(brdp=%x,panelp=%x)\n", (int) brdp, (int) panelp); +#endif spin_lock_irqsave(&brd_lock, flags); BRDENABLE(panelp->brdnr, panelp->pagenr); @@ -2770,12 +3122,13 @@ static int stl_cd1400panelinit(struct stlbrd *brdp, struct stlpanel *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)); @@ -2783,10 +3136,10 @@ static int stl_cd1400panelinit(struct stlbrd *brdp, struct stlpanel *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", @@ -2809,14 +3162,16 @@ static int stl_cd1400panelinit(struct stlbrd *brdp, struct stlpanel *panelp) * Initialize hardware specific port registers. */ -static void stl_cd1400portinit(struct stlbrd *brdp, struct stlpanel *panelp, struct stlport *portp) +static void stl_cd1400portinit(stlbrd_t *brdp, stlpanel_t *panelp, stlport_t *portp) { unsigned long flags; - pr_debug("stl_cd1400portinit(brdp=%p,panelp=%p,portp=%p)\n", brdp, - panelp, portp); +#ifdef DEBUG + printk("stl_cd1400portinit(brdp=%x,panelp=%x,portp=%x)\n", + (int) brdp, (int) panelp, (int) portp); +#endif - if ((brdp == NULL) || (panelp == NULL) || - (portp == NULL)) + if ((brdp == (stlbrd_t *) NULL) || (panelp == (stlpanel_t *) NULL) || + (portp == (stlport_t *) NULL)) return; spin_lock_irqsave(&brd_lock, flags); @@ -2840,13 +3195,15 @@ static void stl_cd1400portinit(struct stlbrd *brdp, struct stlpanel *panelp, str * since it won't usually take too long to be ready. */ -static void stl_cd1400ccrwait(struct stlport *portp) +static void stl_cd1400ccrwait(stlport_t *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); @@ -2859,9 +3216,9 @@ static void stl_cd1400ccrwait(struct stlport *portp) * settings. */ -static void stl_cd1400setport(struct stlport *portp, struct ktermios *tiosp) +static void stl_cd1400setport(stlport_t *portp, struct termios *tiosp) { - struct stlbrd *brdp; + stlbrd_t *brdp; unsigned long flags; unsigned int clkdiv, baudrate; unsigned char cor1, cor2, cor3; @@ -2885,7 +3242,7 @@ static void stl_cd1400setport(struct stlport *portp, struct ktermios *tiosp) sreroff = 0; brdp = stl_brds[portp->brdnr]; - if (brdp == NULL) + if (brdp == (stlbrd_t *) NULL) return; /* @@ -2982,8 +3339,8 @@ static void stl_cd1400setport(struct stlport *portp, struct ktermios *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; } @@ -2998,8 +3355,9 @@ static void stl_cd1400setport(struct stlport *portp, struct ktermios *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 @@ -3024,16 +3382,18 @@ static void stl_cd1400setport(struct stlport *portp, struct ktermios *tiosp) * them all up. */ - pr_debug("SETPORT: portnr=%d panelnr=%d brdnr=%d\n", +#ifdef DEBUG + printk("SETPORT: portnr=%d panelnr=%d brdnr=%d\n", portp->portnr, portp->panelnr, portp->brdnr); - pr_debug(" cor1=%x cor2=%x cor3=%x cor4=%x cor5=%x\n", + printk(" cor1=%x cor2=%x cor3=%x cor4=%x cor5=%x\n", cor1, cor2, cor3, cor4, cor5); - pr_debug(" mcor1=%x mcor2=%x rtpr=%x sreron=%x sreroff=%x\n", + printk(" mcor1=%x mcor2=%x rtpr=%x sreron=%x sreroff=%x\n", mcor1, mcor2, rtpr, sreron, sreroff); - 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", + printk(" tcor=%x tbpr=%x rcor=%x rbpr=%x\n", clk, div, clk, div); + printk(" 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); @@ -3081,13 +3441,15 @@ static void stl_cd1400setport(struct stlport *portp, struct ktermios *tiosp) * Set the state of the DTR and RTS signals. */ -static void stl_cd1400setsignals(struct stlport *portp, int dtr, int rts) +static void stl_cd1400setsignals(stlport_t *portp, int dtr, int rts) { unsigned char msvr1, msvr2; unsigned long flags; - pr_debug("stl_cd1400setsignals(portp=%p,dtr=%d,rts=%d)\n", - portp, dtr, rts); +#ifdef DEBUG + printk("stl_cd1400setsignals(portp=%x,dtr=%d,rts=%d)\n", + (int) portp, dtr, rts); +#endif msvr1 = 0; msvr2 = 0; @@ -3113,13 +3475,15 @@ static void stl_cd1400setsignals(struct stlport *portp, int dtr, int rts) * Return the state of the signals. */ -static int stl_cd1400getsignals(struct stlport *portp) +static int stl_cd1400getsignals(stlport_t *portp) { unsigned char msvr1, msvr2; unsigned long flags; int sigs; - pr_debug("stl_cd1400getsignals(portp=%p)\n", portp); +#ifdef DEBUG + printk("stl_cd1400getsignals(portp=%x)\n", (int) portp); +#endif spin_lock_irqsave(&brd_lock, flags); BRDENABLE(portp->brdnr, portp->pagenr); @@ -3149,13 +3513,15 @@ static int stl_cd1400getsignals(struct stlport *portp) * Enable/Disable the Transmitter and/or Receiver. */ -static void stl_cd1400enablerxtx(struct stlport *portp, int rx, int tx) +static void stl_cd1400enablerxtx(stlport_t *portp, int rx, int tx) { unsigned char ccr; unsigned long flags; - pr_debug("stl_cd1400enablerxtx(portp=%p,rx=%d,tx=%d)\n", portp, rx, tx); - +#ifdef DEBUG + printk("stl_cd1400enablerxtx(portp=%x,rx=%d,tx=%d)\n", + (int) portp, rx, tx); +#endif ccr = 0; if (tx == 0) @@ -3183,12 +3549,15 @@ static void stl_cd1400enablerxtx(struct stlport *portp, int rx, int tx) * Start/stop the Transmitter and/or Receiver. */ -static void stl_cd1400startrxtx(struct stlport *portp, int rx, int tx) +static void stl_cd1400startrxtx(stlport_t *portp, int rx, int tx) { unsigned char sreron, sreroff; unsigned long flags; - pr_debug("stl_cd1400startrxtx(portp=%p,rx=%d,tx=%d)\n", portp, rx, tx); +#ifdef DEBUG + printk("stl_cd1400startrxtx(portp=%x,rx=%d,tx=%d)\n", + (int) portp, rx, tx); +#endif sreron = 0; sreroff = 0; @@ -3220,12 +3589,13 @@ static void stl_cd1400startrxtx(struct stlport *portp, int rx, int tx) * Disable all interrupts from this port. */ -static void stl_cd1400disableintrs(struct stlport *portp) +static void stl_cd1400disableintrs(stlport_t *portp) { unsigned long flags; - pr_debug("stl_cd1400disableintrs(portp=%p)\n", portp); - +#ifdef DEBUG + printk("stl_cd1400disableintrs(portp=%x)\n", (int) portp); +#endif spin_lock_irqsave(&brd_lock, flags); BRDENABLE(portp->brdnr, portp->pagenr); stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); @@ -3236,11 +3606,13 @@ static void stl_cd1400disableintrs(struct stlport *portp) /*****************************************************************************/ -static void stl_cd1400sendbreak(struct stlport *portp, int len) +static void stl_cd1400sendbreak(stlport_t *portp, int len) { unsigned long flags; - pr_debug("stl_cd1400sendbreak(portp=%p,len=%d)\n", portp, len); +#ifdef DEBUG + printk("stl_cd1400sendbreak(portp=%x,len=%d)\n", (int) portp, len); +#endif spin_lock_irqsave(&brd_lock, flags); BRDENABLE(portp->brdnr, portp->pagenr); @@ -3261,17 +3633,19 @@ static void stl_cd1400sendbreak(struct stlport *portp, int len) * Take flow control actions... */ -static void stl_cd1400flowctrl(struct stlport *portp, int state) +static void stl_cd1400flowctrl(stlport_t *portp, int state) { struct tty_struct *tty; unsigned long flags; - pr_debug("stl_cd1400flowctrl(portp=%p,state=%x)\n", portp, state); +#ifdef DEBUG + printk("stl_cd1400flowctrl(portp=%x,state=%x)\n", (int) portp, state); +#endif - if (portp == NULL) + if (portp == (stlport_t *) NULL) return; tty = portp->tty; - if (tty == NULL) + if (tty == (struct tty_struct *) NULL) return; spin_lock_irqsave(&brd_lock, flags); @@ -3323,17 +3697,19 @@ static void stl_cd1400flowctrl(struct stlport *portp, int state) * Send a flow control character... */ -static void stl_cd1400sendflow(struct stlport *portp, int state) +static void stl_cd1400sendflow(stlport_t *portp, int state) { struct tty_struct *tty; unsigned long flags; - pr_debug("stl_cd1400sendflow(portp=%p,state=%x)\n", portp, state); +#ifdef DEBUG + printk("stl_cd1400sendflow(portp=%x,state=%x)\n", (int) portp, state); +#endif - if (portp == NULL) + if (portp == (stlport_t *) NULL) return; tty = portp->tty; - if (tty == NULL) + if (tty == (struct tty_struct *) NULL) return; spin_lock_irqsave(&brd_lock, flags); @@ -3356,13 +3732,15 @@ static void stl_cd1400sendflow(struct stlport *portp, int state) /*****************************************************************************/ -static void stl_cd1400flush(struct stlport *portp) +static void stl_cd1400flush(stlport_t *portp) { unsigned long flags; - pr_debug("stl_cd1400flush(portp=%p)\n", portp); +#ifdef DEBUG + printk("stl_cd1400flush(portp=%x)\n", (int) portp); +#endif - if (portp == NULL) + if (portp == (stlport_t *) NULL) return; spin_lock_irqsave(&brd_lock, flags); @@ -3385,11 +3763,13 @@ static void stl_cd1400flush(struct stlport *portp) * maintains the busy port flag. */ -static int stl_cd1400datastate(struct stlport *portp) +static int stl_cd1400datastate(stlport_t *portp) { - pr_debug("stl_cd1400datastate(portp=%p)\n", portp); +#ifdef DEBUG + printk("stl_cd1400datastate(portp=%x)\n", (int) portp); +#endif - if (portp == NULL) + if (portp == (stlport_t *) NULL) return 0; return test_bit(ASYI_TXBUSY, &portp->istate) ? 1 : 0; @@ -3401,11 +3781,14 @@ static int stl_cd1400datastate(struct stlport *portp) * Interrupt service routine for cd1400 EasyIO boards. */ -static void stl_cd1400eiointr(struct stlpanel *panelp, unsigned int iobase) +static void stl_cd1400eiointr(stlpanel_t *panelp, unsigned int iobase) { unsigned char svrtype; - pr_debug("stl_cd1400eiointr(panelp=%p,iobase=%x)\n", panelp, iobase); +#ifdef DEBUG + printk("stl_cd1400eiointr(panelp=%x,iobase=%x)\n", + (int) panelp, iobase); +#endif spin_lock(&brd_lock); outb(SVRR, iobase); @@ -3431,11 +3814,14 @@ static void stl_cd1400eiointr(struct stlpanel *panelp, unsigned int iobase) * Interrupt service routine for cd1400 panels. */ -static void stl_cd1400echintr(struct stlpanel *panelp, unsigned int iobase) +static void stl_cd1400echintr(stlpanel_t *panelp, unsigned int iobase) { unsigned char svrtype; - pr_debug("stl_cd1400echintr(panelp=%p,iobase=%x)\n", panelp, iobase); +#ifdef DEBUG + printk("stl_cd1400echintr(panelp=%x,iobase=%x)\n", (int) panelp, + iobase); +#endif outb(SVRR, iobase); svrtype = inb(iobase + EREG_DATA); @@ -3457,7 +3843,7 @@ static void stl_cd1400echintr(struct stlpanel *panelp, unsigned int iobase) * this is the only way to generate them on the cd1400. */ -static int stl_cd1400breakisr(struct stlport *portp, int ioaddr) +static inline int stl_cd1400breakisr(stlport_t *portp, int ioaddr) { if (portp->brklen == 1) { outb((COR2 + portp->uartaddr), ioaddr); @@ -3499,14 +3885,16 @@ static int stl_cd1400breakisr(struct stlport *portp, int ioaddr) * be NULL if the buffer has been freed. */ -static void stl_cd1400txisr(struct stlpanel *panelp, int ioaddr) +static void stl_cd1400txisr(stlpanel_t *panelp, int ioaddr) { - struct stlport *portp; + stlport_t *portp; int len, stlen; char *head, *tail; unsigned char ioack, srer; - pr_debug("stl_cd1400txisr(panelp=%p,ioaddr=%x)\n", panelp, ioaddr); +#ifdef DEBUG + printk("stl_cd1400txisr(panelp=%x,ioaddr=%x)\n", (int) panelp, ioaddr); +#endif ioack = inb(ioaddr + EREG_TXACK); if (((ioack & panelp->ackmask) != 0) || @@ -3545,9 +3933,9 @@ static void stl_cd1400txisr(struct stlpanel *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; @@ -3578,15 +3966,17 @@ static void stl_cd1400txisr(struct stlpanel *panelp, int ioaddr) * shutdown a port not in user context. Need to handle this case. */ -static void stl_cd1400rxisr(struct stlpanel *panelp, int ioaddr) +static void stl_cd1400rxisr(stlpanel_t *panelp, int ioaddr) { - struct stlport *portp; + stlport_t *portp; struct tty_struct *tty; unsigned int ioack, len, buflen; unsigned char status; char ch; - pr_debug("stl_cd1400rxisr(panelp=%p,ioaddr=%x)\n", panelp, ioaddr); +#ifdef DEBUG + printk("stl_cd1400rxisr(panelp=%x,ioaddr=%x)\n", (int) panelp, ioaddr); +#endif ioack = inb(ioaddr + EREG_RXACK); if ((ioack & panelp->ackmask) != 0) { @@ -3600,13 +3990,13 @@ static void stl_cd1400rxisr(struct stlpanel *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); @@ -3643,16 +4033,18 @@ static void stl_cd1400rxisr(struct stlpanel *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); } @@ -3674,13 +4066,15 @@ static void stl_cd1400rxisr(struct stlpanel *panelp, int ioaddr) * processing routine. */ -static void stl_cd1400mdmisr(struct stlpanel *panelp, int ioaddr) +static void stl_cd1400mdmisr(stlpanel_t *panelp, int ioaddr) { - struct stlport *portp; + stlport_t *portp; unsigned int ioack; unsigned char misr; - pr_debug("stl_cd1400mdmisr(panelp=%p)\n", panelp); +#ifdef DEBUG + printk("stl_cd1400mdmisr(panelp=%x)\n", (int) panelp); +#endif ioack = inb(ioaddr + EREG_MDACK); if (((ioack & panelp->ackmask) != 0) || @@ -3712,19 +4106,19 @@ static void stl_cd1400mdmisr(struct stlpanel *panelp, int ioaddr) * (Maybe should make this inline...) */ -static int stl_sc26198getreg(struct stlport *portp, int regnr) +static int stl_sc26198getreg(stlport_t *portp, int regnr) { outb((regnr | portp->uartaddr), (portp->ioaddr + XP_ADDR)); return inb(portp->ioaddr + XP_DATA); } -static void stl_sc26198setreg(struct stlport *portp, int regnr, int value) +static void stl_sc26198setreg(stlport_t *portp, int regnr, int value) { outb((regnr | portp->uartaddr), (portp->ioaddr + XP_ADDR)); outb(value, (portp->ioaddr + XP_DATA)); } -static int stl_sc26198updatereg(struct stlport *portp, int regnr, int value) +static int stl_sc26198updatereg(stlport_t *portp, int regnr, int value) { outb((regnr | portp->uartaddr), (portp->ioaddr + XP_ADDR)); if (inb(portp->ioaddr + XP_DATA) != value) { @@ -3740,14 +4134,14 @@ static int stl_sc26198updatereg(struct stlport *portp, int regnr, int value) * Functions to get and set the sc26198 global registers. */ -static int stl_sc26198getglobreg(struct stlport *portp, int regnr) +static int stl_sc26198getglobreg(stlport_t *portp, int regnr) { outb(regnr, (portp->ioaddr + XP_ADDR)); return inb(portp->ioaddr + XP_DATA); } #if 0 -static void stl_sc26198setglobreg(struct stlport *portp, int regnr, int value) +static void stl_sc26198setglobreg(stlport_t *portp, int regnr, int value) { outb(regnr, (portp->ioaddr + XP_ADDR)); outb(value, (portp->ioaddr + XP_DATA)); @@ -3762,12 +4156,15 @@ static void stl_sc26198setglobreg(struct stlport *portp, int regnr, int value) * identical when dealing with ports. */ -static int stl_sc26198panelinit(struct stlbrd *brdp, struct stlpanel *panelp) +static int stl_sc26198panelinit(stlbrd_t *brdp, stlpanel_t *panelp) { int chipmask, i; int nrchips, ioaddr; - pr_debug("stl_sc26198panelinit(brdp=%p,panelp=%p)\n", brdp, panelp); +#ifdef DEBUG + printk("stl_sc26198panelinit(brdp=%x,panelp=%x)\n", + (int) brdp, (int) panelp); +#endif BRDENABLE(panelp->brdnr, panelp->pagenr); @@ -3779,7 +4176,7 @@ static int stl_sc26198panelinit(struct stlbrd *brdp, struct stlpanel *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)); @@ -3807,13 +4204,15 @@ static int stl_sc26198panelinit(struct stlbrd *brdp, struct stlpanel *panelp) * Initialize hardware specific port registers. */ -static void stl_sc26198portinit(struct stlbrd *brdp, struct stlpanel *panelp, struct stlport *portp) +static void stl_sc26198portinit(stlbrd_t *brdp, stlpanel_t *panelp, stlport_t *portp) { - pr_debug("stl_sc26198portinit(brdp=%p,panelp=%p,portp=%p)\n", brdp, - panelp, portp); +#ifdef DEBUG + printk("stl_sc26198portinit(brdp=%x,panelp=%x,portp=%x)\n", + (int) brdp, (int) panelp, (int) portp); +#endif - if ((brdp == NULL) || (panelp == NULL) || - (portp == NULL)) + if ((brdp == (stlbrd_t *) NULL) || (panelp == (stlpanel_t *) NULL) || + (portp == (stlport_t *) NULL)) return; portp->ioaddr = panelp->iobase + ((portp->portnr < 8) ? 0 : 4); @@ -3833,9 +4232,9 @@ static void stl_sc26198portinit(struct stlbrd *brdp, struct stlpanel *panelp, st * settings. */ -static void stl_sc26198setport(struct stlport *portp, struct ktermios *tiosp) +static void stl_sc26198setport(stlport_t *portp, struct termios *tiosp) { - struct stlbrd *brdp; + stlbrd_t *brdp; unsigned long flags; unsigned int baudrate; unsigned char mr0, mr1, mr2, clk; @@ -3850,7 +4249,7 @@ static void stl_sc26198setport(struct stlport *portp, struct ktermios *tiosp) imroff = 0; brdp = stl_brds[portp->brdnr]; - if (brdp == NULL) + if (brdp == (stlbrd_t *) NULL) return; /* @@ -3899,8 +4298,9 @@ static void stl_sc26198setport(struct stlport *portp, struct ktermios *tiosp) mr1 |= (MR1_PARENB | MR1_PARODD); else mr1 |= (MR1_PARENB | MR1_PAREVEN); - } else + } else { mr1 |= MR1_PARNONE; + } mr1 |= MR1_ERRBLOCK; @@ -3940,10 +4340,12 @@ static void stl_sc26198setport(struct stlport *portp, struct ktermios *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. @@ -3965,9 +4367,9 @@ static void stl_sc26198setport(struct stlport *portp, struct ktermios *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; @@ -3981,13 +4383,15 @@ static void stl_sc26198setport(struct stlport *portp, struct ktermios *tiosp) * them all up. */ - pr_debug("SETPORT: portnr=%d panelnr=%d brdnr=%d\n", +#ifdef DEBUG + printk("SETPORT: portnr=%d panelnr=%d brdnr=%d\n", portp->portnr, portp->panelnr, portp->brdnr); - 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", + 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", 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); @@ -4025,13 +4429,15 @@ static void stl_sc26198setport(struct stlport *portp, struct ktermios *tiosp) * Set the state of the DTR and RTS signals. */ -static void stl_sc26198setsignals(struct stlport *portp, int dtr, int rts) +static void stl_sc26198setsignals(stlport_t *portp, int dtr, int rts) { unsigned char iopioron, iopioroff; unsigned long flags; - pr_debug("stl_sc26198setsignals(portp=%p,dtr=%d,rts=%d)\n", portp, - dtr, rts); +#ifdef DEBUG + printk("stl_sc26198setsignals(portp=%x,dtr=%d,rts=%d)\n", + (int) portp, dtr, rts); +#endif iopioron = 0; iopioroff = 0; @@ -4058,13 +4464,15 @@ static void stl_sc26198setsignals(struct stlport *portp, int dtr, int rts) * Return the state of the signals. */ -static int stl_sc26198getsignals(struct stlport *portp) +static int stl_sc26198getsignals(stlport_t *portp) { unsigned char ipr; unsigned long flags; int sigs; - pr_debug("stl_sc26198getsignals(portp=%p)\n", portp); +#ifdef DEBUG + printk("stl_sc26198getsignals(portp=%x)\n", (int) portp); +#endif spin_lock_irqsave(&brd_lock, flags); BRDENABLE(portp->brdnr, portp->pagenr); @@ -4087,12 +4495,15 @@ static int stl_sc26198getsignals(struct stlport *portp) * Enable/Disable the Transmitter and/or Receiver. */ -static void stl_sc26198enablerxtx(struct stlport *portp, int rx, int tx) +static void stl_sc26198enablerxtx(stlport_t *portp, int rx, int tx) { unsigned char ccr; unsigned long flags; - pr_debug("stl_sc26198enablerxtx(portp=%p,rx=%d,tx=%d)\n", portp, rx,tx); +#ifdef DEBUG + printk("stl_sc26198enablerxtx(portp=%x,rx=%d,tx=%d)\n", + (int) portp, rx, tx); +#endif ccr = portp->crenable; if (tx == 0) @@ -4118,12 +4529,15 @@ static void stl_sc26198enablerxtx(struct stlport *portp, int rx, int tx) * Start/stop the Transmitter and/or Receiver. */ -static void stl_sc26198startrxtx(struct stlport *portp, int rx, int tx) +static void stl_sc26198startrxtx(stlport_t *portp, int rx, int tx) { unsigned char imr; unsigned long flags; - pr_debug("stl_sc26198startrxtx(portp=%p,rx=%d,tx=%d)\n", portp, rx, tx); +#ifdef DEBUG + printk("stl_sc26198startrxtx(portp=%x,rx=%d,tx=%d)\n", + (int) portp, rx, tx); +#endif imr = portp->imr; if (tx == 0) @@ -4151,11 +4565,13 @@ static void stl_sc26198startrxtx(struct stlport *portp, int rx, int tx) * Disable all interrupts from this port. */ -static void stl_sc26198disableintrs(struct stlport *portp) +static void stl_sc26198disableintrs(stlport_t *portp) { unsigned long flags; - pr_debug("stl_sc26198disableintrs(portp=%p)\n", portp); +#ifdef DEBUG + printk("stl_sc26198disableintrs(portp=%x)\n", (int) portp); +#endif spin_lock_irqsave(&brd_lock, flags); BRDENABLE(portp->brdnr, portp->pagenr); @@ -4167,20 +4583,22 @@ static void stl_sc26198disableintrs(struct stlport *portp) /*****************************************************************************/ -static void stl_sc26198sendbreak(struct stlport *portp, int len) +static void stl_sc26198sendbreak(stlport_t *portp, int len) { unsigned long flags; - pr_debug("stl_sc26198sendbreak(portp=%p,len=%d)\n", portp, len); +#ifdef DEBUG + printk("stl_sc26198sendbreak(portp=%x,len=%d)\n", (int) portp, len); +#endif 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); } @@ -4191,18 +4609,20 @@ static void stl_sc26198sendbreak(struct stlport *portp, int len) * Take flow control actions... */ -static void stl_sc26198flowctrl(struct stlport *portp, int state) +static void stl_sc26198flowctrl(stlport_t *portp, int state) { struct tty_struct *tty; unsigned long flags; unsigned char mr0; - pr_debug("stl_sc26198flowctrl(portp=%p,state=%x)\n", portp, state); +#ifdef DEBUG + printk("stl_sc26198flowctrl(portp=%x,state=%x)\n", (int) portp, state); +#endif - if (portp == NULL) + if (portp == (stlport_t *) NULL) return; tty = portp->tty; - if (tty == NULL) + if (tty == (struct tty_struct *) NULL) return; spin_lock_irqsave(&brd_lock, flags); @@ -4260,18 +4680,20 @@ static void stl_sc26198flowctrl(struct stlport *portp, int state) * Send a flow control character. */ -static void stl_sc26198sendflow(struct stlport *portp, int state) +static void stl_sc26198sendflow(stlport_t *portp, int state) { struct tty_struct *tty; unsigned long flags; unsigned char mr0; - pr_debug("stl_sc26198sendflow(portp=%p,state=%x)\n", portp, state); +#ifdef DEBUG + printk("stl_sc26198sendflow(portp=%x,state=%x)\n", (int) portp, state); +#endif - if (portp == NULL) + if (portp == (stlport_t *) NULL) return; tty = portp->tty; - if (tty == NULL) + if (tty == (struct tty_struct *) NULL) return; spin_lock_irqsave(&brd_lock, flags); @@ -4299,13 +4721,15 @@ static void stl_sc26198sendflow(struct stlport *portp, int state) /*****************************************************************************/ -static void stl_sc26198flush(struct stlport *portp) +static void stl_sc26198flush(stlport_t *portp) { unsigned long flags; - pr_debug("stl_sc26198flush(portp=%p)\n", portp); +#ifdef DEBUG + printk("stl_sc26198flush(portp=%x)\n", (int) portp); +#endif - if (portp == NULL) + if (portp == (stlport_t *) NULL) return; spin_lock_irqsave(&brd_lock, flags); @@ -4327,14 +4751,16 @@ static void stl_sc26198flush(struct stlport *portp) * check the port statusy register to be sure. */ -static int stl_sc26198datastate(struct stlport *portp) +static int stl_sc26198datastate(stlport_t *portp) { unsigned long flags; unsigned char sr; - pr_debug("stl_sc26198datastate(portp=%p)\n", portp); +#ifdef DEBUG + printk("stl_sc26198datastate(portp=%x)\n", (int) portp); +#endif - if (portp == NULL) + if (portp == (stlport_t *) NULL) return 0; if (test_bit(ASYI_TXBUSY, &portp->istate)) return 1; @@ -4355,16 +4781,18 @@ static int stl_sc26198datastate(struct stlport *portp) * to process a command... */ -static void stl_sc26198wait(struct stlport *portp) +static void stl_sc26198wait(stlport_t *portp) { int i; - pr_debug("stl_sc26198wait(portp=%p)\n", portp); +#ifdef DEBUG + printk("stl_sc26198wait(portp=%x)\n", (int) portp); +#endif - if (portp == NULL) + if (portp == (stlport_t *) NULL) return; - for (i = 0; i < 20; i++) + for (i = 0; (i < 20); i++) stl_sc26198getglobreg(portp, TSTR); } @@ -4376,7 +4804,7 @@ static void stl_sc26198wait(struct stlport *portp) * automatic flow control modes of the sc26198. */ -static void stl_sc26198txunflow(struct stlport *portp, struct tty_struct *tty) +static inline void stl_sc26198txunflow(stlport_t *portp, struct tty_struct *tty) { unsigned char mr0; @@ -4394,9 +4822,9 @@ static void stl_sc26198txunflow(struct stlport *portp, struct tty_struct *tty) * Interrupt service routine for sc26198 panels. */ -static void stl_sc26198intr(struct stlpanel *panelp, unsigned int iobase) +static void stl_sc26198intr(stlpanel_t *panelp, unsigned int iobase) { - struct stlport *portp; + stlport_t *portp; unsigned int iack; spin_lock(&brd_lock); @@ -4432,14 +4860,16 @@ static void stl_sc26198intr(struct stlpanel *panelp, unsigned int iobase) * be NULL if the buffer has been freed. */ -static void stl_sc26198txisr(struct stlport *portp) +static void stl_sc26198txisr(stlport_t *portp) { unsigned int ioaddr; unsigned char mr0; int len, stlen; char *head, *tail; - pr_debug("stl_sc26198txisr(portp=%p)\n", portp); +#ifdef DEBUG + printk("stl_sc26198txisr(portp=%x)\n", (int) portp); +#endif ioaddr = portp->ioaddr; head = portp->tx.head; @@ -4464,9 +4894,9 @@ static void stl_sc26198txisr(struct stlport *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; @@ -4493,12 +4923,14 @@ static void stl_sc26198txisr(struct stlport *portp) * shutdown a port not in user context. Need to handle this case. */ -static void stl_sc26198rxisr(struct stlport *portp, unsigned int iack) +static void stl_sc26198rxisr(stlport_t *portp, unsigned int iack) { struct tty_struct *tty; unsigned int len, buflen, ioaddr; - pr_debug("stl_sc26198rxisr(portp=%p,iack=%x)\n", portp, iack); +#ifdef DEBUG + printk("stl_sc26198rxisr(portp=%x,iack=%x)\n", (int) portp, iack); +#endif tty = portp->tty; ioaddr = portp->ioaddr; @@ -4507,13 +4939,13 @@ static void stl_sc26198rxisr(struct stlport *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)); @@ -4533,8 +4965,8 @@ static void stl_sc26198rxisr(struct stlport *portp, unsigned int iack) * flow control modes of the sc26198. */ if (test_bit(ASYI_TXFLOWED, &portp->istate)) { - if ((tty != NULL) && - (tty->termios != NULL) && + if ((tty != (struct tty_struct *) NULL) && + (tty->termios != (struct termios *) NULL) && (tty->termios->c_iflag & IXANY)) { stl_sc26198txunflow(portp, tty); } @@ -4547,7 +4979,7 @@ static void stl_sc26198rxisr(struct stlport *portp, unsigned int iack) * Process an RX bad character. */ -static void stl_sc26198rxbadch(struct stlport *portp, unsigned char status, char ch) +static inline void stl_sc26198rxbadch(stlport_t *portp, unsigned char status, char ch) { struct tty_struct *tty; unsigned int ioaddr; @@ -4564,7 +4996,7 @@ static void stl_sc26198rxbadch(struct stlport *portp, unsigned char status, char if (status & SR_RXBREAK) portp->stats.rxbreaks++; - if ((tty != NULL) && + if ((tty != (struct tty_struct *) NULL) && ((portp->rxignoremsk & status) == 0)) { if (portp->rxmarkmsk & status) { if (status & SR_RXBREAK) { @@ -4573,16 +5005,18 @@ static void stl_sc26198rxbadch(struct stlport *portp, unsigned char status, char 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); @@ -4603,7 +5037,7 @@ static void stl_sc26198rxbadch(struct stlport *portp, unsigned char status, char * the FIFO). */ -static void stl_sc26198rxbadchars(struct stlport *portp) +static void stl_sc26198rxbadchars(stlport_t *portp) { unsigned char status, mr1; char ch; @@ -4636,11 +5070,13 @@ static void stl_sc26198rxbadchars(struct stlport *portp) * processing time. */ -static void stl_sc26198otherisr(struct stlport *portp, unsigned int iack) +static void stl_sc26198otherisr(stlport_t *portp, unsigned int iack) { unsigned char cir, ipr, xisr; - pr_debug("stl_sc26198otherisr(portp=%p,iack=%x)\n", portp, iack); +#ifdef DEBUG + printk("stl_sc26198otherisr(portp=%x,iack=%x)\n", (int) portp, iack); +#endif cir = stl_sc26198getglobreg(portp, CIR); @@ -4673,172 +5109,4 @@ static void stl_sc26198otherisr(struct stlport *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/trunk/drivers/char/sx.c b/trunk/drivers/char/sx.c index a3008ce13015..cc10af08cb05 100644 --- a/trunk/drivers/char/sx.c +++ b/trunk/drivers/char/sx.c @@ -32,6 +32,7 @@ * 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 @@ -198,7 +199,9 @@ * * */ -#define SX_VERSION 1.33 + +#define RCS_ID "$Id: sx.c,v 1.33 2000/03/08 10:01:02 wolff, pvdl Exp $" +#define RCS_REV "$Revision: 1.33 $" #include #include @@ -214,7 +217,6 @@ #include #include #include -#include #include #include #include @@ -238,6 +240,7 @@ #include #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. */ @@ -246,12 +249,21 @@ #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 @@ -265,6 +277,7 @@ interrupt. Use polling. */ #undef IRQ_RATE_LIMIT + #if 0 /* Not implemented */ /* @@ -273,33 +286,35 @@ */ #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. @@ -318,36 +333,27 @@ 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); @@ -362,12 +368,13 @@ 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 @@ -378,17 +385,23 @@ 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_enter2() sx_dprintk(SX_DEBUG_FLOW, "sx: enter %s (port %d)\n", \ - __FUNCTION__, port->line) + +#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) + + + /* * Firmware loader driver specific routines @@ -396,26 +409,31 @@ 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; @@ -438,24 +456,23 @@ 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 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) @@ -463,468 +480,419 @@ 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 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 doesn't matter*/ + write_sx_byte (board, SI1_ISA_RESET, 0); // value does not 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 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 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; @@ -939,83 +907,80 @@ 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 * * ********************************************************************** */ @@ -1031,260 +996,245 @@ 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); + 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; + /* 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; @@ -1293,20 +1243,19 @@ 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); } } @@ -1315,48 +1264,53 @@ 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;inports;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; + struct sx_board *board = (struct sx_board *) data; - func_enter(); + func_enter (); - sx_interrupt(0, board); + sx_interrupt (0, board); - mod_timer(&board->timer, jiffies + sx_poll); - func_exit(); + init_timer(&board->timer); + + board->timer.expires = jiffies + sx_poll; + add_timer (&board->timer); + func_exit (); } + + /* ********************************************************************** * * Here are the routines that actually * * interface with the generic_serial driver * @@ -1365,9 +1319,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; @@ -1375,28 +1329,30 @@ 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(); @@ -1404,7 +1360,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(); @@ -1412,48 +1368,55 @@ 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; @@ -1466,18 +1429,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); @@ -1486,13 +1449,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; @@ -1500,20 +1463,19 @@ 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); @@ -1522,76 +1484,75 @@ 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=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; @@ -1600,37 +1561,16 @@ 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 @@ -1638,54 +1578,33 @@ 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=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; @@ -1697,7 +1616,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)) { @@ -1705,115 +1624,103 @@ 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) ? 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= 0) + for (i=0;i= 0) sx_initialized++; break; case SXIO_SETDEBUG: @@ -1830,32 +1737,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; @@ -1863,7 +1770,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; @@ -1882,8 +1789,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; @@ -1896,10 +1803,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); @@ -1920,6 +1827,7 @@ 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 @@ -1936,7 +1844,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; @@ -1944,13 +1852,14 @@ 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; @@ -1964,11 +1873,15 @@ 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; @@ -1980,38 +1893,36 @@ 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; } @@ -2019,97 +1930,82 @@ 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.\nDon'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.\n" + "Don'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.\nDon'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.\n" + "Don'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) { - if (board->irq > 0) { + /* board->flags |= SX_BOARD_PRESENT; */ + 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 @@ -2117,48 +2013,52 @@ 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. */ - setup_timer(&board->timer, sx_pollfunc, (unsigned long)board); + /* The timer should be initialized anyway: That way we can safely + del_timer it when the module is unloaded. */ + init_timer (&board->timer); - if (board->poll) - mod_timer(&board->timer, jiffies + board->poll); + if (board->poll) { + board->timer.data = (unsigned long) board; + board->timer.function = sx_pollfunc; + board->timer.expires = jiffies + board->poll; + add_timer (&board->timer); + } } 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 __devinit printheader(void) + +static void 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 " __stringify(SX_VERSION) "\n"); + printk (KERN_INFO "Specialix SX driver " + "(C) 1998/1999 R.E.Wolff@BitWizard.nl \n"); + printk (KERN_INFO "sx: version %s\n", RCS_ID); header_printed = 1; } } -static int __devinit probe_sx(struct sx_board *board) + +static int probe_sx (struct sx_board *board) { struct vpd_prom vpdp; char *p; @@ -2166,57 +2066,51 @@ static int __devinit 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(); + 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 (!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"); } } } @@ -2224,15 +2118,17 @@ static int __devinit 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"); + sx_dprintk (SX_DEBUG_INIT, "reset the board...\n"); + + board->flags |= SX_BOARD_PRESENT; 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 @@ -2240,27 +2136,28 @@ static int __devinit 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 __devinit probe_si(struct sx_board *board) +static int 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; } } @@ -2270,20 +2167,20 @@ static int __devinit 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; } } @@ -2291,44 +2188,45 @@ static int __devinit 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"); + sx_dprintk (SX_DEBUG_INIT, "reset the board...\n"); + + board->flags |= SX_BOARD_PRESENT; 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, @@ -2363,23 +2261,34 @@ 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_ispeed = 9600; - sx_driver->init_termios.c_ospeed = 9600; + sx_driver->init_termios.c_cflag = + B9600 | CS8 | CREAD | HUPCL | CLOCAL; 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 int sx_init_portstructs(int nboards, int nports) + +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) { struct sx_board *board; struct sx_port *port; @@ -2390,9 +2299,8 @@ 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 = kcalloc(nports, sizeof(struct sx_port), GFP_KERNEL); + There is no reason not to allocate them dynamically. Is there? -- REW */ + sx_ports = ckmalloc(nports * sizeof (struct sx_port)); if (!sx_ports) return -ENOMEM; @@ -2400,10 +2308,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; @@ -2415,8 +2323,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++; } } @@ -2427,36 +2335,28 @@ 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;jch_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; */ @@ -2466,17 +2366,6 @@ 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(); @@ -2485,122 +2374,7 @@ static void __exit sx_release_drivers(void) func_exit(); } -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 - +#ifdef CONFIG_PCI /******************************************************** * Setting bit 17 in the CNTRL register of the PLX 9050 * * chip forces a retry on writes while a read is pending.* @@ -2612,265 +2386,233 @@ static struct eisa_driver sx_eisadriver = { 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 __devinit fix_sx_pci(struct pci_dev *pdev, struct sx_board *board) +static void 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 __devinit sx_pci_probe(struct pci_dev *pdev, - const struct pci_device_id *ent) +static int __init sx_init(void) { + int i; + int found = 0; + int eisa_slot; struct sx_board *board; - unsigned int i, reg; - 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); - - 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; +#ifdef CONFIG_PCI + struct pci_dev *pdev = NULL; + unsigned int tint; + unsigned short tshort; +#endif - /* 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; + 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; } - /* 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; + if (misc_register(&sx_fw_device) < 0) { + printk(KERN_ERR "SX: Unable to register firmware loader driver.\n"); + return -EIO; } - fix_sx_pci(pdev, board); - - pci_set_drvdata(pdev, board); - - 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; -} +#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; -static void __devexit sx_pci_remove(struct pci_dev *pdev) -{ - struct sx_board *board = pci_get_drvdata(pdev); + /* 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]; - sx_remove_card(board, pdev); -} + 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 */ + } -/* 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 } -}; + /* Most of the stuff on the CF board is offset by + 0x18000 .... */ + if (IS_CF_BOARD (board)) board->base += 0x18000; -MODULE_DEVICE_TABLE(pci, sx_pci_tbl); + board->irq = pdev->irq; -static struct pci_driver sx_pcidriver = { - .name = "sx", - .id_table = sx_pci_tbl, - .probe = sx_pci_probe, - .remove = __devexit_p(sx_pci_remove) -}; + sx_dprintk (SX_DEBUG_PROBE, "Got a specialix card: %x/%p(%d) %x.\n", + tint, boards[found].base, board->irq, board->flags); -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; + if (probe_sx (board)) { + found++; + fix_sx_pci (pdev, board); + } else + iounmap(board->base2); } +#endif - 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++) { + for (i=0;ihw_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, board->hw_len); - if (!board->base) - goto err_sx_reg; + board->base = ioremap(board->hw_base, SX_WINDOW_LEN); 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)) { - board->flags |= SX_BOARD_PRESENT; + if (probe_sx (board)) { 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;ihw_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, board->hw_len); - if (!board->base) - goto err_si_reg; + board->base = ioremap(board->hw_base, SI2_ISA_WINDOW_LEN); 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)) { - board->flags |= SX_BOARD_PRESENT; + if (probe_si (board)) { found++; } else { - iounmap(board->base); -err_si_reg: - release_region(board->hw_base, board->hw_len); + iounmap (board->base); } } - for (i = 0; i < NR_SI1_ADDRS; i++) { + for (i=0;ihw_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, board->hw_len); - if (!board->base) - goto err_si1_reg; + board->base = ioremap(board->hw_base, SI1_ISA_WINDOW_LEN); 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)) { - board->flags |= SX_BOARD_PRESENT; + if (probe_si (board)) { found++; } else { - iounmap(board->base); -err_si1_reg: - release_region(board->hw_base, board->hw_len); + iounmap (board->base); } } -#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); - retval = 0; - } else if (retval) { -#ifdef CONFIG_EISA - retval = retval1; - if (retval1) -#endif - misc_deregister(&sx_fw_device); + printk (KERN_INFO "sx: total of %d boards detected.\n", found); + } else { + misc_deregister(&sx_fw_device); } func_exit(); - return retval; + return found?0:-EIO; } -static void __exit sx_exit(void) + +static void __exit sx_exit (void) { - int i; + int i; + struct sx_board *board; func_enter(); -#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); - + 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); + } + } 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/trunk/drivers/char/sx.h b/trunk/drivers/char/sx.h index 432aad0a2ddd..e01f83cbe299 100644 --- a/trunk/drivers/char/sx.h +++ b/trunk/drivers/char/sx.h @@ -35,7 +35,6 @@ 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/trunk/drivers/char/synclink.c b/trunk/drivers/char/synclink.c index acc6fab601cc..645187b9141e 100644 --- a/trunk/drivers/char/synclink.c +++ b/trunk/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 ktermios *old_termios) +static void mgsl_set_termios(struct tty_struct *tty, struct termios *old_termios) { struct mgsl_struct *info = (struct mgsl_struct *)tty->driver_data; unsigned long flags; @@ -4405,8 +4405,6 @@ 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/trunk/drivers/char/synclink_gt.c b/trunk/drivers/char/synclink_gt.c index 792c79c315e0..e4730a7312b5 100644 --- a/trunk/drivers/char/synclink_gt.c +++ b/trunk/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 ktermios *old_termios); +static void set_termios(struct tty_struct *tty, struct termios *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 ktermios *old_termios) +static void set_termios(struct tty_struct *tty, struct termios *old_termios) { struct slgt_info *info = tty->driver_data; unsigned long flags; @@ -3546,8 +3546,6 @@ 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/trunk/drivers/char/synclinkmp.c b/trunk/drivers/char/synclinkmp.c index 53e8ccf94fe3..20a96ef250be 100644 --- a/trunk/drivers/char/synclinkmp.c +++ b/trunk/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 ktermios *old_termios); +static void set_termios(struct tty_struct *tty, struct termios *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 ktermios *old_termios) +static void set_termios(struct tty_struct *tty, struct termios *old_termios) { SLMP_INFO *info = (SLMP_INFO *)tty->driver_data; unsigned long flags; @@ -4034,8 +4034,6 @@ 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/trunk/drivers/char/tb0219.c b/trunk/drivers/char/tb0219.c index 4c431cb7cf1b..bb1bad4c18f9 100644 --- a/trunk/drivers/char/tb0219.c +++ b/trunk/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_path.dentry->d_inode); + minor = iminor(file->f_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_path.dentry->d_inode); + minor = iminor(file->f_dentry->d_inode); switch (minor) { case 0: type = TYPE_LED; diff --git a/trunk/drivers/char/tipar.c b/trunk/drivers/char/tipar.c index 47fb20f69695..9df0ca1be0e3 100644 --- a/trunk/drivers/char/tipar.c +++ b/trunk/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_path.dentry->d_inode) - TIPAR_MINOR; + unsigned int minor = iminor(file->f_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_path.dentry->d_inode) - TIPAR_MINOR; + unsigned int minor = iminor(file->f_dentry->d_inode) - TIPAR_MINOR; ssize_t retval = 0; ssize_t n = 0; diff --git a/trunk/drivers/char/tty_io.c b/trunk/drivers/char/tty_io.c index 4044c864fdd4..b3cfc8bc613c 100644 --- a/trunk/drivers/char/tty_io.c +++ b/trunk/drivers/char/tty_io.c @@ -109,15 +109,13 @@ #define TTY_PARANOIA_CHECK 1 #define CHECK_TTY_COUNT 1 -struct ktermios tty_std_termios = { /* for the benefit of tty drivers */ +struct termios 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_ispeed = 38400, - .c_ospeed = 38400 + .c_cc = INIT_C_CC }; EXPORT_SYMBOL(tty_std_termios); @@ -128,7 +126,7 @@ EXPORT_SYMBOL(tty_std_termios); LIST_HEAD(tty_drivers); /* linked list of tty drivers */ -/* Mutex to protect creating and releasing a tty. This is shared with +/* Semaphore 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); @@ -252,7 +250,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; } @@ -261,6 +259,18 @@ 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 @@ -604,7 +614,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_mutex + * Locking: takes termios_sem */ static void tty_set_termios_ldisc(struct tty_struct *tty, int num) @@ -905,7 +915,7 @@ static void tty_ldisc_enable(struct tty_struct *tty) * context. * * Locking: takes tty_ldisc_lock. - * called functions take termios_mutex + * called functions take termios_sem */ static int tty_set_ldisc(struct tty_struct *tty, int ldisc) @@ -1241,22 +1251,6 @@ 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 @@ -1273,12 +1267,12 @@ static void tty_reset_termios(struct tty_struct *tty) * * Locking: * BKL - * 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 + * 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 + * */ static void do_tty_hangup(struct work_struct *work) { @@ -1345,7 +1339,11 @@ static void do_tty_hangup(struct work_struct *work) * N_TTY. */ if (tty->driver->flags & TTY_DRIVER_RESET_TERMIOS) - tty_reset_termios(tty); + { + mutex_lock(&tty->termios_mutex); + *tty->termios = tty->driver->init_termios; + mutex_unlock(&tty->termios_mutex); + } /* Defer ldisc switch */ /* tty_deferred_ldisc_switch(N_TTY); @@ -1356,18 +1354,14 @@ 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) { - spin_unlock_irq(&p->sighand->siglock); + if (!p->signal->leader) 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); @@ -1459,14 +1453,6 @@ 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 @@ -1483,35 +1469,31 @@ static void session_clear_tty(pid_t session) * 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: + * Locking: tty_mutex is taken to protect current->signal->tty * BKL is taken for hysterical raisins - * 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 + * Tasklist lock is taken (under tty_mutex) to walk process + * lists for the session. */ 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 = get_current_tty(); + tty = current->signal->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 { - 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); + 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); } mutex_unlock(&tty_mutex); unlock_kernel(); @@ -1523,29 +1505,19 @@ void disassociate_ctty(int on_exit) kill_pg(tty_pgrp, SIGCONT, on_exit); } - spin_lock_irq(¤t->sighand->siglock); - current->signal->tty_old_pgrp = 0; - session = process_session(current); - spin_unlock_irq(¤t->sighand->siglock); - + /* Must lock changes to tty_old_pgrp */ 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); + current->signal->tty_old_pgrp = 0; + tty->session = 0; + tty->pgrp = -1; /* Now clear signal->tty under the lock */ read_lock(&tasklist_lock); - session_clear_tty(session); + do_each_task_pid(current->signal->session, PIDTYPE_SID, p) { + p->signal->tty = NULL; + } while_each_task_pid(current->signal->session, PIDTYPE_SID, p); read_unlock(&tasklist_lock); + mutex_unlock(&tty_mutex); unlock_kernel(); } @@ -1643,7 +1615,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_path.dentry->d_inode; + inode = file->f_dentry->d_inode; if (tty_paranoia_check(tty, inode, "tty_read")) return -EIO; if (!tty || (test_bit(TTY_IO_ERROR, &tty->flags))) @@ -1746,7 +1718,7 @@ static inline ssize_t do_tty_write( cond_resched(); } if (written) { - struct inode *inode = file->f_path.dentry->d_inode; + struct inode *inode = file->f_dentry->d_inode; inode->i_mtime = current_fs_time(inode->i_sb); ret = written; } @@ -1777,7 +1749,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_path.dentry->d_inode; + struct inode *inode = file->f_dentry->d_inode; ssize_t ret; struct tty_ldisc *ld; @@ -1884,8 +1856,8 @@ static int init_dev(struct tty_driver *driver, int idx, struct tty_struct **ret_tty) { struct tty_struct *tty, *o_tty; - struct ktermios *tp, **tp_loc, *o_tp, **o_tp_loc; - struct ktermios *ltp, **ltp_loc, *o_ltp, **o_ltp_loc; + struct termios *tp, **tp_loc, *o_tp, **o_tp_loc; + struct termios *ltp, **ltp_loc, *o_ltp, **o_ltp_loc; int retval = 0; /* check whether we're reopening an existing tty */ @@ -1932,7 +1904,7 @@ static int init_dev(struct tty_driver *driver, int idx, } if (!*tp_loc) { - tp = (struct ktermios *) kmalloc(sizeof(struct ktermios), + tp = (struct termios *) kmalloc(sizeof(struct termios), GFP_KERNEL); if (!tp) goto free_mem_out; @@ -1940,11 +1912,11 @@ static int init_dev(struct tty_driver *driver, int idx, } if (!*ltp_loc) { - ltp = (struct ktermios *) kmalloc(sizeof(struct ktermios), + ltp = (struct termios *) kmalloc(sizeof(struct termios), GFP_KERNEL); if (!ltp) goto free_mem_out; - memset(ltp, 0, sizeof(struct ktermios)); + memset(ltp, 0, sizeof(struct termios)); } if (driver->type == TTY_DRIVER_TYPE_PTY) { @@ -1965,19 +1937,19 @@ static int init_dev(struct tty_driver *driver, int idx, } if (!*o_tp_loc) { - o_tp = (struct ktermios *) - kmalloc(sizeof(struct ktermios), GFP_KERNEL); + o_tp = (struct termios *) + kmalloc(sizeof(struct termios), GFP_KERNEL); if (!o_tp) goto free_mem_out; *o_tp = driver->other->init_termios; } if (!*o_ltp_loc) { - o_ltp = (struct ktermios *) - kmalloc(sizeof(struct ktermios), GFP_KERNEL); + o_ltp = (struct termios *) + kmalloc(sizeof(struct termios), GFP_KERNEL); if (!o_ltp) goto free_mem_out; - memset(o_ltp, 0, sizeof(struct ktermios)); + memset(o_ltp, 0, sizeof(struct termios)); } /* @@ -2016,9 +1988,6 @@ 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++; @@ -2121,7 +2090,7 @@ static int init_dev(struct tty_driver *driver, int idx, static void release_mem(struct tty_struct *tty, int idx) { struct tty_struct *o_tty; - struct ktermios *tp; + struct termios *tp; int devpts = tty->driver->flags & TTY_DRIVER_DEVPTS_MEM; if ((o_tty = tty->link) != NULL) { @@ -2187,7 +2156,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_path.dentry->d_inode, "release_dev")) + if (tty_paranoia_check(tty, filp->f_dentry->d_inode, "release_dev")) return; check_tty_count(tty, "release_dev"); @@ -2368,10 +2337,16 @@ static void release_dev(struct file * filp) * tty. */ if (tty_closing || o_tty_closing) { + struct task_struct *p; + read_lock(&tasklist_lock); - session_clear_tty(tty->session); + do_each_task_pid(tty->session, PIDTYPE_SID, p) { + p->signal->tty = NULL; + } while_each_task_pid(tty->session, PIDTYPE_SID, p); if (o_tty) - session_clear_tty(o_tty->session); + do_each_task_pid(o_tty->session, PIDTYPE_SID, p) { + p->signal->tty = NULL; + } while_each_task_pid(o_tty->session, PIDTYPE_SID, p); read_unlock(&tasklist_lock); } @@ -2468,9 +2443,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 tty, get_tty_driver and init_dev work. - * tty->count should protect the rest. - * ->siglock protects ->signal/->sighand + * 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 */ static int tty_open(struct inode * inode, struct file * filp) @@ -2492,13 +2467,12 @@ static int tty_open(struct inode * inode, struct file * filp) mutex_lock(&tty_mutex); if (device == MKDEV(TTYAUX_MAJOR,0)) { - tty = get_current_tty(); - if (!tty) { + if (!current->signal->tty) { mutex_unlock(&tty_mutex); return -ENXIO; } - driver = tty->driver; - index = tty->index; + driver = current->signal->tty->driver; + index = current->signal->tty->index; filp->f_flags |= O_NONBLOCK; /* Don't let /dev/tty block */ /* noctty = 1; */ goto got_driver; @@ -2573,16 +2547,17 @@ static int tty_open(struct inode * inode, struct file * filp) filp->f_op = &tty_fops; goto retry_open; } - - mutex_lock(&tty_mutex); - spin_lock_irq(¤t->sighand->siglock); if (!noctty && current->signal->leader && !current->signal->tty && - tty->session == 0) - __proc_set_tty(current, tty); - spin_unlock_irq(¤t->sighand->siglock); - mutex_unlock(&tty_mutex); + 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); + } return 0; } @@ -2697,7 +2672,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_path.dentry->d_inode, "tty_poll")) + if (tty_paranoia_check(tty, filp->f_dentry->d_inode, "tty_poll")) return 0; ld = tty_ldisc_ref_wait(tty); @@ -2713,7 +2688,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_path.dentry->d_inode, "tty_fasync")) + if (tty_paranoia_check(tty, filp->f_dentry->d_inode, "tty_fasync")) return 0; retval = fasync_helper(fd, filp, on, &tty->fasync); @@ -2772,7 +2747,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_mutex is taken to ensure the winsize data + * Locking: tty->termios_sem is taken to ensure the winsize data * is consistent. */ @@ -2799,8 +2774,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_mutex is used to ensure we don't double - * resize and get confused. Lock order - tty->termios_mutex before + * The tty->termios_sem is used to ensure we don't double + * resize and get confused. Lock order - tty->termios.sem before * console sem */ @@ -2905,28 +2880,25 @@ 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) { - int ret = 0; - if (current->signal->leader && - (process_session(current) == tty->session)) - return ret; + struct task_struct *p; - mutex_lock(&tty_mutex); + if (current->signal->leader && + (current->signal->session == tty->session)) + return 0; /* * The process must be a session leader and * not have a controlling tty already. */ - if (!current->signal->leader || current->signal->tty) { - ret = -EPERM; - goto unlock; - } - + if (!current->signal->leader || current->signal->tty) + return -EPERM; if (tty->session > 0) { /* * This tty is already the controlling @@ -2936,18 +2908,24 @@ static int tiocsctty(struct tty_struct *tty, int arg) /* * Steal it away */ + read_lock(&tasklist_lock); - session_clear_tty(tty->session); + do_each_task_pid(tty->session, PIDTYPE_SID, p) { + p->signal->tty = NULL; + } while_each_task_pid(tty->session, PIDTYPE_SID, p); read_unlock(&tasklist_lock); - } else { - ret = -EPERM; - goto unlock; - } + } else + return -EPERM; } - proc_set_tty(current, tty); -unlock: + mutex_lock(&tty_mutex); + task_lock(current); + current->signal->tty = tty; + task_unlock(current); mutex_unlock(&tty_mutex); - return ret; + current->signal->tty_old_pgrp = 0; + tty->session = current->signal->session; + tty->pgrp = process_group(current); + return 0; } /** @@ -2959,7 +2937,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 current->signal->tty is safe. + * Locking: none. Reference to ->signal->tty is safe. */ static int tiocgpgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t __user *p) @@ -2996,13 +2974,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 != process_session(current))) + (real_tty->session != current->signal->session)) return -ENOTTY; if (get_user(pgrp, p)) return -EFAULT; if (pgrp < 0) return -EINVAL; - if (session_of_pgrp(pgrp) != process_session(current)) + if (session_of_pgrp(pgrp) != current->signal->session) return -EPERM; real_tty->pgrp = pgrp; return 0; @@ -3017,7 +2995,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 current->signal->tty is safe. + * Locking: none. Reference to ->signal->tty is safe. */ static int tiocgsid(struct tty_struct *tty, struct tty_struct *real_tty, pid_t __user *p) @@ -3236,11 +3214,14 @@ 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); - proc_clear_tty(current); + task_lock(current); + current->signal->tty = NULL; + task_unlock(current); return 0; case TIOCSCTTY: return tiocsctty(tty, arg); @@ -3340,7 +3321,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); @@ -3355,7 +3336,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): process_session(p)==tty->session\n", + " (%s): p->signal->session==tty->session\n", p->pid, p->comm); send_sig(SIGKILL, p, 1); } while_each_task_pid(session, PIDTYPE_SID, p); @@ -3365,7 +3346,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): process_session(p)==tty->session\n", + " (%s): p->signal->session==tty->session\n", p->pid, p->comm); send_sig(SIGKILL, p, 1); continue; @@ -3475,6 +3456,84 @@ 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 @@ -3697,8 +3756,8 @@ int tty_register_driver(struct tty_driver *driver) if (p) { driver->ttys = (struct tty_struct **)p; - driver->termios = (struct ktermios **)(p + driver->num); - driver->termios_locked = (struct ktermios **)(p + driver->num * 2); + driver->termios = (struct termios **)(p + driver->num); + driver->termios_locked = (struct termios **)(p + driver->num * 2); } else { driver->ttys = NULL; driver->termios = NULL; @@ -3737,7 +3796,7 @@ EXPORT_SYMBOL(tty_register_driver); int tty_unregister_driver(struct tty_driver *driver) { int i; - struct ktermios *tp; + struct termios *tp; void *p; if (driver->refcount) @@ -3775,52 +3834,9 @@ 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); -} +EXPORT_SYMBOL(tty_unregister_driver); -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/trunk/drivers/char/tty_ioctl.c b/trunk/drivers/char/tty_ioctl.c index dee47f40c6a3..3b6fa7b0be8b 100644 --- a/trunk/drivers/char/tty_ioctl.c +++ b/trunk/drivers/char/tty_ioctl.c @@ -36,7 +36,6 @@ #define TERMIOS_FLUSH 1 #define TERMIOS_WAIT 2 #define TERMIOS_TERMIO 4 -#define TERMIOS_OLD 8 /** @@ -85,9 +84,9 @@ void tty_wait_until_sent(struct tty_struct * tty, long timeout) EXPORT_SYMBOL(tty_wait_until_sent); -static void unset_locked_termios(struct ktermios *termios, - struct ktermios *old, - struct ktermios *locked) +static void unset_locked_termios(struct termios *termios, + struct termios *old, + struct termios *locked) { int i; @@ -106,204 +105,8 @@ static void unset_locked_termios(struct ktermios *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 @@ -316,10 +119,10 @@ EXPORT_SYMBOL(tty_get_baud_rate); * Locking: termios_sem */ -static void change_termios(struct tty_struct * tty, struct ktermios * new_termios) +static void change_termios(struct tty_struct * tty, struct termios * new_termios) { int canon_change; - struct ktermios old_termios = *tty->termios; + struct termios old_termios = *tty->termios; struct tty_ldisc *ld; /* @@ -392,39 +195,23 @@ static void change_termios(struct tty_struct * tty, struct ktermios * new_termio static int set_termios(struct tty_struct * tty, void __user *arg, int opt) { - struct ktermios tmp_termios; + struct termios 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 termios2 __user *)arg)) + (struct termios __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); @@ -499,8 +286,8 @@ static int get_sgttyb(struct tty_struct * tty, struct sgttyb __user * sgttyb) struct sgttyb tmp; mutex_lock(&tty->termios_mutex); - tmp.sg_ispeed = tty->termios->c_ispeed; - tmp.sg_ospeed = tty->termios->c_ospeed; + tmp.sg_ispeed = 0; + tmp.sg_ospeed = 0; tmp.sg_erase = tty->termios->c_cc[VERASE]; tmp.sg_kill = tty->termios->c_cc[VKILL]; tmp.sg_flags = get_sgflags(tty); @@ -509,7 +296,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 ktermios * termios, int flags) +static void set_sgflags(struct termios * termios, int flags) { termios->c_iflag = ICRNL | IXON; termios->c_oflag = 0; @@ -550,7 +337,7 @@ static int set_sgttyb(struct tty_struct * tty, struct sgttyb __user * sgttyb) { int retval; struct sgttyb tmp; - struct ktermios termios; + struct termios termios; retval = tty_check_change(tty); if (retval) @@ -564,10 +351,6 @@ 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; @@ -698,33 +481,16 @@ 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; -#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: + case TCSETSF: return set_termios(real_tty, p, TERMIOS_FLUSH | TERMIOS_WAIT); - case TCSETSW2: + case TCSETSW: return set_termios(real_tty, p, TERMIOS_WAIT); - case TCSETS2: + case TCSETS: return set_termios(real_tty, p, 0); -#endif case TCGETA: return get_termio(real_tty, p); case TCSETAF: diff --git a/trunk/drivers/char/vc_screen.c b/trunk/drivers/char/vc_screen.c index 26776517f04c..f442b574b44a 100644 --- a/trunk/drivers/char/vc_screen.c +++ b/trunk/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_path.dentry->d_inode); + size = vcs_size(file->f_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_path.dentry->d_inode; + struct inode *inode = file->f_dentry->d_inode; unsigned int currcons = iminor(inode); struct vc_data *vc; long pos; @@ -271,7 +271,7 @@ vcs_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) static ssize_t vcs_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { - struct inode *inode = file->f_path.dentry->d_inode; + struct inode *inode = file->f_dentry->d_inode; unsigned int currcons = iminor(inode); struct vc_data *vc; long pos; diff --git a/trunk/drivers/char/viotape.c b/trunk/drivers/char/viotape.c index 94d79cb8ce8d..73c78bf75d7f 100644 --- a/trunk/drivers/char/viotape.c +++ b/trunk/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_path.dentry->d_inode, &devi); + get_dev_info(file->f_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_path.dentry->d_inode, &devi); + get_dev_info(file->f_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_path.dentry->d_inode, &devi); + get_dev_info(file->f_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_path.dentry->d_inode, &devi); + get_dev_info(file->f_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_path.dentry->d_inode, &devi); + get_dev_info(file->f_dentry->d_inode, &devi); if (devi.devno >= viotape_numdev) { ret = -ENODEV; diff --git a/trunk/drivers/char/vme_scc.c b/trunk/drivers/char/vme_scc.c index e01317cb1a0e..d0b94dd1af6d 100644 --- a/trunk/drivers/char/vme_scc.c +++ b/trunk/drivers/char/vme_scc.c @@ -153,8 +153,6 @@ 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/trunk/drivers/char/vr41xx_giu.c b/trunk/drivers/char/vr41xx_giu.c index a744dad9cf45..8e7949305171 100644 --- a/trunk/drivers/char/vr41xx_giu.c +++ b/trunk/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_path.dentry->d_inode); + pin = iminor(file->f_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_path.dentry->d_inode); + pin = iminor(file->f_dentry->d_inode); if (pin >= giu_nr_pins) return -EBADF; diff --git a/trunk/drivers/clocksource/acpi_pm.c b/trunk/drivers/clocksource/acpi_pm.c index 8ab61ef97b4c..7fcb77a9d011 100644 --- a/trunk/drivers/clocksource/acpi_pm.c +++ b/trunk/drivers/clocksource/acpi_pm.c @@ -142,39 +142,6 @@ 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) { @@ -206,9 +173,6 @@ 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/trunk/drivers/hid/Kconfig b/trunk/drivers/hid/Kconfig deleted file mode 100644 index 96d4a0bb2203..000000000000 --- a/trunk/drivers/hid/Kconfig +++ /dev/null @@ -1,18 +0,0 @@ -# -# 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/trunk/drivers/hid/Makefile b/trunk/drivers/hid/Makefile deleted file mode 100644 index 6432392110bf..000000000000 --- a/trunk/drivers/hid/Makefile +++ /dev/null @@ -1,15 +0,0 @@ -# -# 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/trunk/drivers/hid/hid-core.c b/trunk/drivers/hid/hid-core.c deleted file mode 100644 index 18c2b3cf6bcc..000000000000 --- a/trunk/drivers/hid/hid-core.c +++ /dev/null @@ -1,1003 +0,0 @@ -/* - * HID support for Linux - * - * Copyright (c) 1999 Andreas Gal - * Copyright (c) 2000-2005 Vojtech Pavlik - * Copyright (c) 2005 Michael Haboustak 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#undef DEBUG -#undef DEBUG_DATA - -#include -#include - -/* - * 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/trunk/drivers/i2c/i2c-dev.c b/trunk/drivers/i2c/i2c-dev.c index 2e22a2ffa606..94a4e9a3013c 100644 --- a/trunk/drivers/i2c/i2c-dev.c +++ b/trunk/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_path.dentry->d_inode), count); + iminor(file->f_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_path.dentry->d_inode), count); + iminor(file->f_dentry->d_inode), count); ret = i2c_master_send(client,tmp,count); kfree(tmp); diff --git a/trunk/drivers/ide/pci/alim15x3.c b/trunk/drivers/ide/pci/alim15x3.c index 89109be5162c..d419e4bb54f4 100644 --- a/trunk/drivers/ide/pci/alim15x3.c +++ b/trunk/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_get_slot(dev->bus, PCI_DEVFN(0,0)); + struct pci_dev *north = pci_find_slot(0, PCI_DEVFN(0,0)); pci_read_config_byte(dev, PCI_REVISION_ID, &m5229_revision); - isa_dev = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, NULL); + isa_dev = pci_find_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, NULL); #if defined(DISPLAY_ALI_TIMINGS) && defined(CONFIG_PROC_FS) if (!ali_proc) { @@ -613,7 +613,8 @@ static unsigned int __devinit init_chipset_ali15x3 (struct pci_dev *dev, const c * clear bit 7 */ pci_write_config_byte(dev, 0x4b, tmpbyte & 0x7F); - goto out; + local_irq_restore(flags); + return 0; } /* @@ -636,8 +637,10 @@ 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) - goto out; + if (north && north->vendor != PCI_VENDOR_ID_AL) { + local_irq_restore(flags); + return 0; + } if (m5229_revision < 0xC5 && isa_dev) { @@ -658,9 +661,6 @@ 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/trunk/drivers/ide/pci/pdc202xx_new.c b/trunk/drivers/ide/pci/pdc202xx_new.c index 3ca581063f72..6c097e80b4df 100644 --- a/trunk/drivers/ide/pci/pdc202xx_new.c +++ b/trunk/drivers/ide/pci/pdc202xx_new.c @@ -9,7 +9,6 @@ * Split from: * linux/drivers/ide/pdc202xx.c Version 0.35 Mar. 30, 2002 * Copyright (C) 1998-2002 Andre Hedrick - * 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 @@ -169,8 +168,12 @@ static int pdcnew_new_tune_chipset (ide_drive_t *drive, u8 xferspeed) */ static void pdcnew_tune_drive(ide_drive_t *drive, u8 pio) { - pio = ide_get_best_pio_mode(drive, pio, 4, NULL); - (void)pdcnew_new_tune_chipset(drive, XFER_PIO_0 + 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); } static u8 pdcnew_new_cable_detect (ide_hwif_t *hwif) @@ -204,8 +207,10 @@ static int config_chipset_for_dma (ide_drive_t *drive) speed = ide_dma_speed(drive, pdcnew_ratemask(drive)); - if (!speed) + if (!(speed)) { + hwif->tuneproc(drive, 5); return 0; + } (void) hwif->speedproc(drive, speed); return ide_dma_enable(drive); @@ -229,7 +234,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, 255); + hwif->tuneproc(drive, 5); return hwif->ide_dma_off_quietly(drive); } /* IORDY not supported */ @@ -357,7 +362,6 @@ 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) && @@ -365,16 +369,14 @@ static int __devinit init_setup_pdc20270(struct pci_dev *dev, if (PCI_SLOT(dev->devfn) & 2) return -ENODEV; d->extra = 0; - while ((findev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, findev)) != NULL) { + while ((findev = pci_find_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; } - ret = ide_setup_pci_devices(dev, findev, d); - pci_dev_put(findev); - return ret; + return ide_setup_pci_devices(dev, findev, d); } } } diff --git a/trunk/drivers/ide/pci/sis5513.c b/trunk/drivers/ide/pci/sis5513.c index 6b313139b5e4..92edf76bd7ad 100644 --- a/trunk/drivers/ide/pci/sis5513.c +++ b/trunk/drivers/ide/pci/sis5513.c @@ -800,10 +800,9 @@ static unsigned int __devinit init_chipset_sis5513 (struct pci_dev *dev, const c if (trueid == 0x5517) { /* SiS 961/961B */ - lpc_bridge = pci_get_slot(dev->bus, 0x10); /* Bus 0, Dev 2, Fn 0 */ + lpc_bridge = pci_find_slot(0x00, 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/trunk/drivers/ide/pci/sl82c105.c b/trunk/drivers/ide/pci/sl82c105.c index 5afefe8692fe..0b4b60498515 100644 --- a/trunk/drivers/ide/pci/sl82c105.c +++ b/trunk/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)pci_get_drvdata(dev); + old = val = *((u32 *)&hwif->hwif_data); if (drive->using_dma) val &= ~mask; else val |= mask; if (old != val) { pci_write_config_dword(dev, 0x40, val); - pci_set_drvdata(dev, (void *)val); + *((u32 *)&hwif->hwif_data) = val; } } @@ -316,13 +316,14 @@ static void sl82c105_selectproc(ide_drive_t *drive) */ static void sl82c105_resetproc(ide_drive_t *drive) { - struct pci_dev *dev = HWIF(drive)->pci_dev; + ide_hwif_t *hwif = HWIF(drive); + struct pci_dev *dev = hwif->pci_dev; u32 val; DBG(("sl82c105_resetproc(drive:%s)\n", drive->name)); pci_read_config_dword(dev, 0x40, &val); - pci_set_drvdata(dev, (void *)val); + *((u32 *)&hwif->hwif_data) = val; } /* @@ -393,7 +394,6 @@ 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,25 +404,30 @@ 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's 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 is 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_0; + hwif->drives[1].pio_speed = XFER_PIO_1; 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/trunk/drivers/ieee1394/ieee1394_core.h b/trunk/drivers/ieee1394/ieee1394_core.h index 536ba3f580fd..af4a78a8ef3b 100644 --- a/trunk/drivers/ieee1394/ieee1394_core.h +++ b/trunk/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_path.dentry->d_inode->i_cindex; + return file->f_dentry->d_inode->i_cindex; } extern int hpsb_disable_irm; diff --git a/trunk/drivers/infiniband/core/uverbs_main.c b/trunk/drivers/infiniband/core/uverbs_main.c index a617ca7b6923..4e16314e8e6d 100644 --- a/trunk/drivers/infiniband/core/uverbs_main.c +++ b/trunk/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_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_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_flags = O_RDONLY; filp->f_mode = FMODE_READ; filp->private_data = ev_file; diff --git a/trunk/drivers/infiniband/hw/ipath/ipath_file_ops.c b/trunk/drivers/infiniband/hw/ipath/ipath_file_ops.c index 340f27e3ebff..a9ddc6911f66 100644 --- a/trunk/drivers/infiniband/hw/ipath/ipath_file_ops.c +++ b/trunk/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_path.dentry->d_inode) - IPATH_USER_MINOR_BASE; + i_minor = iminor(fp->f_dentry->d_inode) - IPATH_USER_MINOR_BASE; ipath_cdbg(VERBOSE, "open on dev %lx (minor %d)\n", - (long)fp->f_path.dentry->d_inode->i_rdev, i_minor); + (long)fp->f_dentry->d_inode->i_rdev, i_minor); if (i_minor) ret = find_free_port(i_minor - 1, fp, uinfo); diff --git a/trunk/drivers/infiniband/hw/ipath/ipath_fs.c b/trunk/drivers/infiniband/hw/ipath/ipath_fs.c index 79a60f020a21..d9ff283f725e 100644 --- a/trunk/drivers/infiniband/hw/ipath/ipath_fs.c +++ b/trunk/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_path.dentry->d_inode->i_private; + dd = file->f_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_path.dentry->d_inode->i_private; + dd = file->f_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_path.dentry->d_inode->i_private; + dd = file->f_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_path.dentry->d_inode->i_private; + dd = file->f_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_path.dentry->d_inode->i_private; + dd = file->f_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/trunk/drivers/infiniband/hw/mthca/mthca_provider.c b/trunk/drivers/infiniband/hw/mthca/mthca_provider.c index 7ec7c4b937f9..21422a3336ad 100644 --- a/trunk/drivers/infiniband/hw/mthca/mthca_provider.c +++ b/trunk/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 - ilog2(mdev->limits.num_mpts))) - 1; + (1 << (32 - long_log2(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, ilog2(entries), &status); + ret = mthca_RESIZE_CQ(dev, cq->cqn, lkey, long_log2(entries), &status); if (status) ret = -EINVAL; diff --git a/trunk/drivers/infiniband/hw/mthca/mthca_qp.c b/trunk/drivers/infiniband/hw/mthca/mthca_qp.c index d844a2569b47..33e3ba7937f1 100644 --- a/trunk/drivers/infiniband/hw/mthca/mthca_qp.c +++ b/trunk/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 = ilog2(qp->rq.max) << 3; + qp_context->rq_size_stride = long_log2(qp->rq.max) << 3; qp_context->rq_size_stride |= qp->rq.wqe_shift - 4; if (qp->sq.max) - qp_context->sq_size_stride = ilog2(qp->sq.max) << 3; + qp_context->sq_size_stride = long_log2(qp->sq.max) << 3; qp_context->sq_size_stride |= qp->sq.wqe_shift - 4; } diff --git a/trunk/drivers/infiniband/hw/mthca/mthca_srq.c b/trunk/drivers/infiniband/hw/mthca/mthca_srq.c index 10684da33d58..34d2c4768962 100644 --- a/trunk/drivers/infiniband/hw/mthca/mthca_srq.c +++ b/trunk/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 = ilog2(srq->max); + logsize = long_log2(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 = ilog2(ds); + srq->wqe_shift = long_log2(ds); srq->srqn = mthca_alloc(&dev->srq_table.alloc); if (srq->srqn == -1) diff --git a/trunk/drivers/infiniband/ulp/iser/iser_memory.c b/trunk/drivers/infiniband/ulp/iser/iser_memory.c index 3aedd59b8a84..5e122501fd80 100644 --- a/trunk/drivers/infiniband/ulp/iser/iser_memory.c +++ b/trunk/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, - ilog2(roundup_pow_of_two(cmd_data_len)) - PAGE_SHIFT); + long_log2(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, - ilog2(roundup_pow_of_two(cmd_data_len)) - PAGE_SHIFT); + long_log2(roundup_pow_of_two(cmd_data_len)) - PAGE_SHIFT); else kfree(mem_copy->copy_buf); diff --git a/trunk/drivers/input/Makefile b/trunk/drivers/input/Makefile index da575deb3c7a..a005b1df5f1a 100644 --- a/trunk/drivers/input/Makefile +++ b/trunk/drivers/input/Makefile @@ -21,4 +21,3 @@ obj-$(CONFIG_INPUT_MOUSE) += mouse/ obj-$(CONFIG_INPUT_JOYSTICK) += joystick/ obj-$(CONFIG_INPUT_TOUCHSCREEN) += touchscreen/ obj-$(CONFIG_INPUT_MISC) += misc/ - diff --git a/trunk/drivers/input/ff-core.c b/trunk/drivers/input/ff-core.c index 783b3412cead..35656cadc914 100644 --- a/trunk/drivers/input/ff-core.c +++ b/trunk/drivers/input/ff-core.c @@ -203,7 +203,7 @@ static int erase_effect(struct input_dev *dev, int effect_id, } /** - * input_ff_erase - erase a force-feedback effect from device + * input_ff_erase - erase an effect from device * @dev: input device to erase effect from * @effect_id: id of the ffect to be erased * @file: purported owner of the request @@ -347,7 +347,7 @@ EXPORT_SYMBOL_GPL(input_ff_create); /** * input_ff_free() - frees force feedback portion of input device - * @dev: input device supporting force feedback + * @dev: input device supporintg force feedback * * This function is only needed in error path as input core will * automatically free force feedback structures when device is diff --git a/trunk/drivers/input/ff-memless.c b/trunk/drivers/input/ff-memless.c index eba18b6ac5e4..cd8b7297e6df 100644 --- a/trunk/drivers/input/ff-memless.c +++ b/trunk/drivers/input/ff-memless.c @@ -460,7 +460,7 @@ static void ml_ff_destroy(struct ff_device *ff) } /** - * input_ff_create_memless() - create memoryless force-feedback device + * input_ff_create_memless() - create memoryless FF device * @dev: input device supporting force-feedback * @data: driver-specific data to be passed into @play_effect * @play_effect: driver-specific method for playing FF effect diff --git a/trunk/drivers/input/gameport/gameport.c b/trunk/drivers/input/gameport/gameport.c index a00fe470a829..79dfb4b25c97 100644 --- a/trunk/drivers/input/gameport/gameport.c +++ b/trunk/drivers/input/gameport/gameport.c @@ -731,6 +731,12 @@ static int gameport_driver_remove(struct device *dev) return 0; } +static struct bus_type gameport_bus = { + .name = "gameport", + .probe = gameport_driver_probe, + .remove = gameport_driver_remove, +}; + static void gameport_add_driver(struct gameport_driver *drv) { int error; @@ -776,15 +782,6 @@ static int gameport_bus_match(struct device *dev, struct device_driver *drv) return !gameport_drv->ignore; } -static struct bus_type gameport_bus = { - .name = "gameport", - .dev_attrs = gameport_device_attrs, - .drv_attrs = gameport_driver_attrs, - .match = gameport_bus_match, - .probe = gameport_driver_probe, - .remove = gameport_driver_remove, -}; - static void gameport_set_drv(struct gameport *gameport, struct gameport_driver *drv) { mutex_lock(&gameport->drv_mutex); @@ -794,6 +791,7 @@ static void gameport_set_drv(struct gameport *gameport, struct gameport_driver * int gameport_open(struct gameport *gameport, struct gameport_driver *drv, int mode) { + if (gameport->open) { if (gameport->open(gameport, mode)) { return -1; @@ -821,6 +819,9 @@ static int __init gameport_init(void) { int error; + gameport_bus.dev_attrs = gameport_device_attrs; + gameport_bus.drv_attrs = gameport_driver_attrs; + gameport_bus.match = gameport_bus_match; error = bus_register(&gameport_bus); if (error) { printk(KERN_ERR "gameport: failed to register gameport bus, error: %d\n", error); diff --git a/trunk/drivers/input/gameport/lightning.c b/trunk/drivers/input/gameport/lightning.c index 6b4d4561d465..d65d81080257 100644 --- a/trunk/drivers/input/gameport/lightning.c +++ b/trunk/drivers/input/gameport/lightning.c @@ -309,7 +309,7 @@ static int __init l4_init(void) int i, cards = 0; if (!request_region(L4_PORT, 1, "lightning")) - return -EBUSY; + return -1; for (i = 0; i < 2; i++) if (l4_add_card(i) == 0) @@ -319,7 +319,7 @@ static int __init l4_init(void) if (!cards) { release_region(L4_PORT, 1); - return -ENODEV; + return -1; } return 0; diff --git a/trunk/drivers/input/input.c b/trunk/drivers/input/input.c index 7cf2b4f603a3..1c8c8a5bc4a9 100644 --- a/trunk/drivers/input/input.c +++ b/trunk/drivers/input/input.c @@ -37,7 +37,7 @@ static struct input_handler *input_table[8]; /** * input_event() - report new input event - * @dev: device that generated the event + * @handle: device that generated the event * @type: type of the event * @code: event code * @value: value of the event @@ -900,15 +900,6 @@ struct class input_class = { }; EXPORT_SYMBOL_GPL(input_class); -/** - * input_allocate_device - allocate memory for new input device - * - * Returns prepared struct input_dev or NULL. - * - * NOTE: Use input_free_device() to free devices that have not been - * registered; input_unregister_device() should be used for already - * registered devices. - */ struct input_dev *input_allocate_device(void) { struct input_dev *dev; @@ -928,20 +919,6 @@ struct input_dev *input_allocate_device(void) } EXPORT_SYMBOL(input_allocate_device); -/** - * input_free_device - free memory occupied by input_dev structure - * @dev: input device to free - * - * This function should only be used if input_register_device() - * was not called yet or if it failed. Once device was registered - * use input_unregister_device() and memory will be freed once last - * refrence to the device is dropped. - * - * Device should be allocated by input_allocate_device(). - * - * NOTE: If there are references to the input device then memory - * will not be freed until last reference is dropped. - */ void input_free_device(struct input_dev *dev) { if (dev) { diff --git a/trunk/drivers/input/joystick/adi.c b/trunk/drivers/input/joystick/adi.c index 6279ced8a35b..704bf70f1db7 100644 --- a/trunk/drivers/input/joystick/adi.c +++ b/trunk/drivers/input/joystick/adi.c @@ -521,19 +521,11 @@ static int adi_connect(struct gameport *gameport, struct gameport_driver *drv) for (i = 0; i < 2; i++) if (port->adi[i].length > 0) { adi_init_center(port->adi + i); - err = input_register_device(port->adi[i].dev); - if (err) - goto fail3; + input_register_device(port->adi[i].dev); } return 0; - fail3: while (--i >= 0) { - if (port->adi[i].length > 0) { - input_unregister_device(port->adi[i].dev); - port->adi[i].dev = NULL; - } - } fail2: for (i = 0; i < 2; i++) if (port->adi[i].dev) input_free_device(port->adi[i].dev); diff --git a/trunk/drivers/input/joystick/amijoy.c b/trunk/drivers/input/joystick/amijoy.c index e608691b5a61..650acf3a30b7 100644 --- a/trunk/drivers/input/joystick/amijoy.c +++ b/trunk/drivers/input/joystick/amijoy.c @@ -147,11 +147,7 @@ static int __init amijoy_init(void) amijoy_dev[i]->absmax[ABS_X + j] = 1; } - err = input_register_device(amijoy_dev[i]); - if (err) { - input_free_device(amijoy_dev[i]); - goto fail; - } + input_register_device(amijoy_dev[i]); } return 0; diff --git a/trunk/drivers/input/joystick/analog.c b/trunk/drivers/input/joystick/analog.c index 7ef68456d7d6..e9a02db36ecc 100644 --- a/trunk/drivers/input/joystick/analog.c +++ b/trunk/drivers/input/joystick/analog.c @@ -434,7 +434,6 @@ static int analog_init_device(struct analog_port *port, struct analog *analog, i { struct input_dev *input_dev; int i, j, t, v, w, x, y, z; - int error; analog_name(analog); snprintf(analog->phys, sizeof(analog->phys), @@ -506,11 +505,7 @@ static int analog_init_device(struct analog_port *port, struct analog *analog, i analog_decode(analog, port->axes, port->initial, port->buttons); - error = input_register_device(analog->dev); - if (error) { - input_free_device(analog->dev); - return error; - } + input_register_device(analog->dev); return 0; } @@ -673,8 +668,7 @@ static int analog_connect(struct gameport *gameport, struct gameport_driver *drv return 0; fail3: while (--i >= 0) - if (port->analog[i].mask) - input_unregister_device(port->analog[i].dev); + input_unregister_device(port->analog[i].dev); fail2: gameport_close(gameport); fail1: gameport_set_drvdata(gameport, NULL); kfree(port); diff --git a/trunk/drivers/input/joystick/cobra.c b/trunk/drivers/input/joystick/cobra.c index 034ec39c251d..d5e42eb88a20 100644 --- a/trunk/drivers/input/joystick/cobra.c +++ b/trunk/drivers/input/joystick/cobra.c @@ -223,15 +223,12 @@ static int cobra_connect(struct gameport *gameport, struct gameport_driver *drv) for (j = 0; cobra_btn[j]; j++) set_bit(cobra_btn[j], input_dev->keybit); - err = input_register_device(cobra->dev[i]); - if (err) - goto fail4; + input_register_device(cobra->dev[i]); } return 0; - fail4: input_free_device(cobra->dev[i]); - fail3: while (--i >= 0) + fail3: for (i = 0; i < 2; i++) if (cobra->dev[i]) input_unregister_device(cobra->dev[i]); fail2: gameport_close(gameport); diff --git a/trunk/drivers/input/joystick/gf2k.c b/trunk/drivers/input/joystick/gf2k.c index bacbab5d1b6f..e4a699f6ec87 100644 --- a/trunk/drivers/input/joystick/gf2k.c +++ b/trunk/drivers/input/joystick/gf2k.c @@ -341,9 +341,7 @@ static int gf2k_connect(struct gameport *gameport, struct gameport_driver *drv) input_dev->absflat[gf2k_abs[i]] = (i < 2) ? 24 : 0; } - err = input_register_device(gf2k->dev); - if (err) - goto fail2; + input_register_device(gf2k->dev); return 0; diff --git a/trunk/drivers/input/joystick/grip_mp.c b/trunk/drivers/input/joystick/grip_mp.c index 8120a9c40773..62438944a69a 100644 --- a/trunk/drivers/input/joystick/grip_mp.c +++ b/trunk/drivers/input/joystick/grip_mp.c @@ -423,10 +423,7 @@ static int get_and_decode_packet(struct grip_mp *grip, int flags) if (!port->registered) { dbg("New Grip pad in multiport slot %d.\n", slot); - if (register_slot(slot, grip)) { - port->mode = GRIP_MODE_RESET; - port->dirty = 0; - } + register_slot(slot, grip); } return flags; } @@ -588,7 +585,6 @@ static int register_slot(int slot, struct grip_mp *grip) struct grip_port *port = grip->port[slot]; struct input_dev *input_dev; int j, t; - int err; port->dev = input_dev = input_allocate_device(); if (!input_dev) @@ -614,12 +610,7 @@ static int register_slot(int slot, struct grip_mp *grip) if (t > 0) set_bit(t, input_dev->keybit); - err = input_register_device(port->dev); - if (err) { - input_free_device(port->dev); - return err; - } - + input_register_device(port->dev); port->registered = 1; if (port->dirty) /* report initial state, if any */ diff --git a/trunk/drivers/input/joystick/guillemot.c b/trunk/drivers/input/joystick/guillemot.c index dbc5d92858b8..840ed9b512b2 100644 --- a/trunk/drivers/input/joystick/guillemot.c +++ b/trunk/drivers/input/joystick/guillemot.c @@ -250,9 +250,7 @@ static int guillemot_connect(struct gameport *gameport, struct gameport_driver * for (i = 0; (t = guillemot->type->btn[i]) >= 0; i++) set_bit(t, input_dev->keybit); - err = input_register_device(guillemot->dev); - if (err) - goto fail2; + input_register_device(guillemot->dev); return 0; diff --git a/trunk/drivers/input/joystick/iforce/iforce-main.c b/trunk/drivers/input/joystick/iforce/iforce-main.c index 3393a37fec39..24c684bc6337 100644 --- a/trunk/drivers/input/joystick/iforce/iforce-main.c +++ b/trunk/drivers/input/joystick/iforce/iforce-main.c @@ -325,8 +325,8 @@ int iforce_init_device(struct iforce *iforce) if (i == 20) { /* 5 seconds */ printk(KERN_ERR "iforce-main.c: Timeout waiting for response from device.\n"); - error = -ENODEV; - goto fail; + input_free_device(input_dev); + return -ENODEV; } /* @@ -439,8 +439,10 @@ int iforce_init_device(struct iforce *iforce) set_bit(iforce->type->ff[i], input_dev->ffbit); error = input_ff_create(input_dev, ff_effects); - if (error) - goto fail; + if (error) { + input_free_device(input_dev); + return error; + } ff = input_dev->ff; ff->upload = iforce_upload_effect; @@ -453,35 +455,22 @@ int iforce_init_device(struct iforce *iforce) * Register input device. */ - error = input_register_device(iforce->dev); - if (error) - goto fail; + input_register_device(iforce->dev); printk(KERN_DEBUG "iforce->dev->open = %p\n", iforce->dev->open); return 0; - - fail: input_free_device(input_dev); - return error; } static int __init iforce_init(void) { - int err = 0; - #ifdef CONFIG_JOYSTICK_IFORCE_USB - err = usb_register(&iforce_usb_driver); - if (err) - return err; + usb_register(&iforce_usb_driver); #endif #ifdef CONFIG_JOYSTICK_IFORCE_232 - err = serio_register_driver(&iforce_serio_drv); -#ifdef CONFIG_JOYSTICK_IFORCE_USB - if (err) - usb_deregister(&iforce_usb_driver); -#endif + serio_register_driver(&iforce_serio_drv); #endif - return err; + return 0; } static void __exit iforce_exit(void) diff --git a/trunk/drivers/input/joystick/iforce/iforce-serio.c b/trunk/drivers/input/joystick/iforce/iforce-serio.c index ec4be535f483..ca08f45c2040 100644 --- a/trunk/drivers/input/joystick/iforce/iforce-serio.c +++ b/trunk/drivers/input/joystick/iforce/iforce-serio.c @@ -141,19 +141,21 @@ static int iforce_serio_connect(struct serio *serio, struct serio_driver *drv) serio_set_drvdata(serio, iforce); err = serio_open(serio, drv); - if (err) - goto fail1; + if (err) { + serio_set_drvdata(serio, NULL); + kfree(iforce); + return err; + } err = iforce_init_device(iforce); - if (err) - goto fail2; + if (err) { + serio_close(serio); + serio_set_drvdata(serio, NULL); + kfree(iforce); + return -ENODEV; + } return 0; - - fail2: serio_close(serio); - fail1: serio_set_drvdata(serio, NULL); - kfree(iforce); - return err; } static void iforce_serio_disconnect(struct serio *serio) diff --git a/trunk/drivers/input/joystick/interact.c b/trunk/drivers/input/joystick/interact.c index fec8b3d0967d..bbfeb9c59b87 100644 --- a/trunk/drivers/input/joystick/interact.c +++ b/trunk/drivers/input/joystick/interact.c @@ -283,9 +283,7 @@ static int interact_connect(struct gameport *gameport, struct gameport_driver *d for (i = 0; (t = interact_type[interact->type].btn[i]) >= 0; i++) set_bit(t, input_dev->keybit); - err = input_register_device(interact->dev); - if (err) - goto fail2; + input_register_device(interact->dev); return 0; diff --git a/trunk/drivers/input/joystick/magellan.c b/trunk/drivers/input/joystick/magellan.c index 4112789f1196..e3d19444ba2e 100644 --- a/trunk/drivers/input/joystick/magellan.c +++ b/trunk/drivers/input/joystick/magellan.c @@ -157,7 +157,7 @@ static int magellan_connect(struct serio *serio, struct serio_driver *drv) magellan = kzalloc(sizeof(struct magellan), GFP_KERNEL); input_dev = input_allocate_device(); if (!magellan || !input_dev) - goto fail1; + goto fail; magellan->dev = input_dev; snprintf(magellan->phys, sizeof(magellan->phys), "%s/input0", serio->phys); @@ -183,17 +183,13 @@ static int magellan_connect(struct serio *serio, struct serio_driver *drv) err = serio_open(serio, drv); if (err) - goto fail2; - - err = input_register_device(magellan->dev); - if (err) - goto fail3; + goto fail; + input_register_device(magellan->dev); return 0; - fail3: serio_close(serio); - fail2: serio_set_drvdata(serio, NULL); - fail1: input_free_device(input_dev); + fail: serio_set_drvdata(serio, NULL); + input_free_device(input_dev); kfree(magellan); return err; } @@ -231,7 +227,8 @@ static struct serio_driver magellan_drv = { static int __init magellan_init(void) { - return serio_register_driver(&magellan_drv); + serio_register_driver(&magellan_drv); + return 0; } static void __exit magellan_exit(void) diff --git a/trunk/drivers/input/joystick/spaceball.c b/trunk/drivers/input/joystick/spaceball.c index 08bf113e62eb..2a9808cf826f 100644 --- a/trunk/drivers/input/joystick/spaceball.c +++ b/trunk/drivers/input/joystick/spaceball.c @@ -215,7 +215,7 @@ static int spaceball_connect(struct serio *serio, struct serio_driver *drv) spaceball = kmalloc(sizeof(struct spaceball), GFP_KERNEL); input_dev = input_allocate_device(); if (!spaceball || !input_dev) - goto fail1; + goto fail; spaceball->dev = input_dev; snprintf(spaceball->phys, sizeof(spaceball->phys), "%s/input0", serio->phys); @@ -252,17 +252,13 @@ static int spaceball_connect(struct serio *serio, struct serio_driver *drv) err = serio_open(serio, drv); if (err) - goto fail2; - - err = input_register_device(spaceball->dev); - if (err) - goto fail3; + goto fail; + input_register_device(spaceball->dev); return 0; - fail3: serio_close(serio); - fail2: serio_set_drvdata(serio, NULL); - fail1: input_free_device(input_dev); + fail: serio_set_drvdata(serio, NULL); + input_free_device(input_dev); kfree(spaceball); return err; } @@ -300,7 +296,8 @@ static struct serio_driver spaceball_drv = { static int __init spaceball_init(void) { - return serio_register_driver(&spaceball_drv); + serio_register_driver(&spaceball_drv); + return 0; } static void __exit spaceball_exit(void) diff --git a/trunk/drivers/input/joystick/spaceorb.c b/trunk/drivers/input/joystick/spaceorb.c index c9c79211af71..c4db0247c5fb 100644 --- a/trunk/drivers/input/joystick/spaceorb.c +++ b/trunk/drivers/input/joystick/spaceorb.c @@ -172,7 +172,7 @@ static int spaceorb_connect(struct serio *serio, struct serio_driver *drv) spaceorb = kzalloc(sizeof(struct spaceorb), GFP_KERNEL); input_dev = input_allocate_device(); if (!spaceorb || !input_dev) - goto fail1; + goto fail; spaceorb->dev = input_dev; snprintf(spaceorb->phys, sizeof(spaceorb->phys), "%s/input0", serio->phys); @@ -198,17 +198,13 @@ static int spaceorb_connect(struct serio *serio, struct serio_driver *drv) err = serio_open(serio, drv); if (err) - goto fail2; - - err = input_register_device(spaceorb->dev); - if (err) - goto fail3; + goto fail; + input_register_device(spaceorb->dev); return 0; - fail3: serio_close(serio); - fail2: serio_set_drvdata(serio, NULL); - fail1: input_free_device(input_dev); + fail: serio_set_drvdata(serio, NULL); + input_free_device(input_dev); kfree(spaceorb); return err; } @@ -246,7 +242,8 @@ static struct serio_driver spaceorb_drv = { static int __init spaceorb_init(void) { - return serio_register_driver(&spaceorb_drv); + serio_register_driver(&spaceorb_drv); + return 0; } static void __exit spaceorb_exit(void) diff --git a/trunk/drivers/input/joystick/stinger.c b/trunk/drivers/input/joystick/stinger.c index ecb0916215fa..1ffb03223311 100644 --- a/trunk/drivers/input/joystick/stinger.c +++ b/trunk/drivers/input/joystick/stinger.c @@ -143,7 +143,7 @@ static int stinger_connect(struct serio *serio, struct serio_driver *drv) stinger = kmalloc(sizeof(struct stinger), GFP_KERNEL); input_dev = input_allocate_device(); if (!stinger || !input_dev) - goto fail1; + goto fail; stinger->dev = input_dev; snprintf(stinger->phys, sizeof(stinger->phys), "%s/serio0", serio->phys); @@ -168,17 +168,13 @@ static int stinger_connect(struct serio *serio, struct serio_driver *drv) err = serio_open(serio, drv); if (err) - goto fail2; - - err = input_register_device(stinger->dev); - if (err) - goto fail3; + goto fail; + input_register_device(stinger->dev); return 0; - fail3: serio_close(serio); - fail2: serio_set_drvdata(serio, NULL); - fail1: input_free_device(input_dev); + fail: serio_set_drvdata(serio, NULL); + input_free_device(input_dev); kfree(stinger); return err; } @@ -216,7 +212,8 @@ static struct serio_driver stinger_drv = { static int __init stinger_init(void) { - return serio_register_driver(&stinger_drv); + serio_register_driver(&stinger_drv); + return 0; } static void __exit stinger_exit(void) diff --git a/trunk/drivers/input/joystick/twidjoy.c b/trunk/drivers/input/joystick/twidjoy.c index 9cf17d6ced82..49085df2d631 100644 --- a/trunk/drivers/input/joystick/twidjoy.c +++ b/trunk/drivers/input/joystick/twidjoy.c @@ -194,7 +194,7 @@ static int twidjoy_connect(struct serio *serio, struct serio_driver *drv) twidjoy = kzalloc(sizeof(struct twidjoy), GFP_KERNEL); input_dev = input_allocate_device(); if (!twidjoy || !input_dev) - goto fail1; + goto fail; twidjoy->dev = input_dev; snprintf(twidjoy->phys, sizeof(twidjoy->phys), "%s/input0", serio->phys); @@ -221,17 +221,13 @@ static int twidjoy_connect(struct serio *serio, struct serio_driver *drv) err = serio_open(serio, drv); if (err) - goto fail2; - - err = input_register_device(twidjoy->dev); - if (err) - goto fail3; + goto fail; + input_register_device(twidjoy->dev); return 0; - fail3: serio_close(serio); - fail2: serio_set_drvdata(serio, NULL); - fail1: input_free_device(input_dev); + fail: serio_set_drvdata(serio, NULL); + input_free_device(input_dev); kfree(twidjoy); return err; } @@ -269,7 +265,8 @@ static struct serio_driver twidjoy_drv = { static int __init twidjoy_init(void) { - return serio_register_driver(&twidjoy_drv); + serio_register_driver(&twidjoy_drv); + return 0; } static void __exit twidjoy_exit(void) diff --git a/trunk/drivers/input/joystick/warrior.c b/trunk/drivers/input/joystick/warrior.c index 29d339acf430..35edea1ab955 100644 --- a/trunk/drivers/input/joystick/warrior.c +++ b/trunk/drivers/input/joystick/warrior.c @@ -149,7 +149,7 @@ static int warrior_connect(struct serio *serio, struct serio_driver *drv) warrior = kzalloc(sizeof(struct warrior), GFP_KERNEL); input_dev = input_allocate_device(); if (!warrior || !input_dev) - goto fail1; + goto fail; warrior->dev = input_dev; snprintf(warrior->phys, sizeof(warrior->phys), "%s/input0", serio->phys); @@ -176,17 +176,13 @@ static int warrior_connect(struct serio *serio, struct serio_driver *drv) err = serio_open(serio, drv); if (err) - goto fail2; - - err = input_register_device(warrior->dev); - if (err) - goto fail3; + goto fail; + input_register_device(warrior->dev); return 0; - fail3: serio_close(serio); - fail2: serio_set_drvdata(serio, NULL); - fail1: input_free_device(input_dev); + fail: serio_set_drvdata(serio, NULL); + input_free_device(input_dev); kfree(warrior); return err; } @@ -224,7 +220,8 @@ static struct serio_driver warrior_drv = { static int __init warrior_init(void) { - return serio_register_driver(&warrior_drv); + serio_register_driver(&warrior_drv); + return 0; } static void __exit warrior_exit(void) diff --git a/trunk/drivers/input/keyboard/Kconfig b/trunk/drivers/input/keyboard/Kconfig index 049f2f544e75..81a333f73010 100644 --- a/trunk/drivers/input/keyboard/Kconfig +++ b/trunk/drivers/input/keyboard/Kconfig @@ -203,15 +203,4 @@ config KEYBOARD_OMAP To compile this driver as a module, choose M here: the module will be called omap-keypad. -config KEYBOARD_AAED2000 - tristate "AAED-2000 keyboard" - depends on MACH_AAED2000 - default y - help - Say Y here to enable the keyboard on the Agilent AAED-2000 - development board. - - To compile this driver as a module, choose M here: the - module will be called aaed2000_kbd. - endif diff --git a/trunk/drivers/input/keyboard/Makefile b/trunk/drivers/input/keyboard/Makefile index 568797907347..4c79e7bc9d06 100644 --- a/trunk/drivers/input/keyboard/Makefile +++ b/trunk/drivers/input/keyboard/Makefile @@ -17,5 +17,4 @@ obj-$(CONFIG_KEYBOARD_SPITZ) += spitzkbd.o obj-$(CONFIG_KEYBOARD_HIL) += hil_kbd.o obj-$(CONFIG_KEYBOARD_HIL_OLD) += hilkbd.o obj-$(CONFIG_KEYBOARD_OMAP) += omap-keypad.o -obj-$(CONFIG_KEYBOARD_AAED2000) += aaed2000_kbd.o diff --git a/trunk/drivers/input/keyboard/aaed2000_kbd.c b/trunk/drivers/input/keyboard/aaed2000_kbd.c deleted file mode 100644 index 65fcb6af63a8..000000000000 --- a/trunk/drivers/input/keyboard/aaed2000_kbd.c +++ /dev/null @@ -1,203 +0,0 @@ -/* - * Keyboard driver for the AAED-2000 dev board - * - * Copyright (c) 2006 Nicolas Bellido Y Ortega - * - * Based on corgikbd.c - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#define KB_ROWS 12 -#define KB_COLS 8 -#define KB_ROWMASK(r) (1 << (r)) -#define SCANCODE(r,c) (((c) * KB_ROWS) + (r)) -#define NR_SCANCODES (KB_COLS * KB_ROWS) - -#define SCAN_INTERVAL (50) /* ms */ -#define KB_ACTIVATE_DELAY (20) /* us */ - -static unsigned char aaedkbd_keycode[NR_SCANCODES] = { - KEY_9, KEY_0, KEY_MINUS, KEY_EQUAL, KEY_BACKSPACE, 0, KEY_SPACE, KEY_KP6, 0, KEY_KPDOT, 0, 0, - KEY_K, KEY_M, KEY_O, KEY_DOT, KEY_SLASH, 0, KEY_F, 0, 0, 0, KEY_LEFTSHIFT, 0, - KEY_I, KEY_P, KEY_LEFTBRACE, KEY_RIGHTBRACE, KEY_BACKSLASH, 0, 0, 0, 0, 0, KEY_RIGHTSHIFT, 0, - KEY_8, KEY_L, KEY_SEMICOLON, KEY_APOSTROPHE, KEY_ENTER, 0, 0, 0, 0, 0, 0, 0, - KEY_J, KEY_H, KEY_B, KEY_KP8, KEY_KP4, 0, KEY_C, KEY_D, KEY_S, KEY_A, 0, KEY_CAPSLOCK, - KEY_Y, KEY_U, KEY_N, KEY_T, 0, 0, KEY_R, KEY_E, KEY_W, KEY_Q, 0, KEY_TAB, - KEY_7, KEY_6, KEY_G, 0, KEY_5, 0, KEY_4, KEY_3, KEY_2, KEY_1, 0, KEY_GRAVE, - 0, 0, KEY_COMMA, 0, KEY_KP2, 0, KEY_V, KEY_LEFTALT, KEY_X, KEY_Z, 0, KEY_LEFTCTRL -}; - -struct aaedkbd { - unsigned char keycode[ARRAY_SIZE(aaedkbd_keycode)]; - struct input_dev *input; - struct work_struct workq; - int kbdscan_state[KB_COLS]; - int kbdscan_count[KB_COLS]; -}; - -#define KBDSCAN_STABLE_COUNT 2 - -static void aaedkbd_report_col(struct aaedkbd *aaedkbd, - unsigned int col, unsigned int rowd) -{ - unsigned int scancode, pressed; - unsigned int row; - - for (row = 0; row < KB_ROWS; row++) { - scancode = SCANCODE(row, col); - pressed = rowd & KB_ROWMASK(row); - - input_report_key(aaedkbd->input, aaedkbd->keycode[scancode], pressed); - } -} - -/* Scan the hardware keyboard and push any changes up through the input layer */ -static void aaedkbd_work(void *data) -{ - struct aaedkbd *aaedkbd = data; - unsigned int col, rowd; - - col = 0; - do { - AAEC_GPIO_KSCAN = col + 8; - udelay(KB_ACTIVATE_DELAY); - rowd = AAED_EXT_GPIO & AAED_EGPIO_KBD_SCAN; - - if (rowd != aaedkbd->kbdscan_state[col]) { - aaedkbd->kbdscan_count[col] = 0; - aaedkbd->kbdscan_state[col] = rowd; - } else if (++aaedkbd->kbdscan_count[col] >= KBDSCAN_STABLE_COUNT) { - aaedkbd_report_col(aaedkbd, col, rowd); - col++; - } - } while (col < KB_COLS); - - AAEC_GPIO_KSCAN = 0x07; - input_sync(aaedkbd->input); - - schedule_delayed_work(&aaedkbd->workq, msecs_to_jiffies(SCAN_INTERVAL)); -} - -static int aaedkbd_open(struct input_dev *indev) -{ - struct aaedkbd *aaedkbd = indev->private; - - schedule_delayed_work(&aaedkbd->workq, msecs_to_jiffies(SCAN_INTERVAL)); - - return 0; -} - -static void aaedkbd_close(struct input_dev *indev) -{ - struct aaedkbd *aaedkbd = indev->private; - - cancel_delayed_work(&aaedkbd->workq); - flush_scheduled_work(); -} - -static int __devinit aaedkbd_probe(struct platform_device *pdev) -{ - struct aaedkbd *aaedkbd; - struct input_dev *input_dev; - int i; - int error; - - aaedkbd = kzalloc(sizeof(struct aaedkbd), GFP_KERNEL); - input_dev = input_allocate_device(); - if (!aaedkbd || !input_dev) { - error = -ENOMEM; - goto fail; - } - - platform_set_drvdata(pdev, aaedkbd); - - aaedkbd->input = input_dev; - - /* Init keyboard rescan workqueue */ - INIT_WORK(&aaedkbd->workq, aaedkbd_work, aaedkbd); - - memcpy(aaedkbd->keycode, aaedkbd_keycode, sizeof(aaedkbd->keycode)); - - input_dev->name = "AAED-2000 Keyboard"; - input_dev->phys = "aaedkbd/input0"; - input_dev->id.bustype = BUS_HOST; - input_dev->id.vendor = 0x0001; - input_dev->id.product = 0x0001; - input_dev->id.version = 0x0100; - input_dev->cdev.dev = &pdev->dev; - input_dev->private = aaedkbd; - - input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP); - input_dev->keycode = aaedkbd->keycode; - input_dev->keycodesize = sizeof(unsigned char); - input_dev->keycodemax = ARRAY_SIZE(aaedkbd_keycode); - - for (i = 0; i < ARRAY_SIZE(aaedkbd_keycode); i++) - set_bit(aaedkbd->keycode[i], input_dev->keybit); - clear_bit(0, input_dev->keybit); - - input_dev->open = aaedkbd_open; - input_dev->close = aaedkbd_close; - - error = input_register_device(aaedkbd->input); - if (error) - goto fail; - - return 0; - - fail: kfree(aaedkbd); - input_free_device(input_dev); - return error; -} - -static int __devexit aaedkbd_remove(struct platform_device *pdev) -{ - struct aaedkbd *aaedkbd = platform_get_drvdata(pdev); - - input_unregister_device(aaedkbd->input); - kfree(aaedkbd); - - return 0; -} - -static struct platform_driver aaedkbd_driver = { - .probe = aaedkbd_probe, - .remove = __devexit_p(aaedkbd_remove), - .driver = { - .name = "aaed2000-keyboard", - }, -}; - -static int __init aaedkbd_init(void) -{ - return platform_driver_register(&aaedkbd_driver); -} - -static void __exit aaedkbd_exit(void) -{ - platform_driver_unregister(&aaedkbd_driver); -} - -module_init(aaedkbd_init); -module_exit(aaedkbd_exit); - -MODULE_AUTHOR("Nicolas Bellido Y Ortega"); -MODULE_DESCRIPTION("AAED-2000 Keyboard Driver"); -MODULE_LICENSE("GPLv2"); diff --git a/trunk/drivers/input/keyboard/amikbd.c b/trunk/drivers/input/keyboard/amikbd.c index 16583d71753b..8abdbd0ee8f9 100644 --- a/trunk/drivers/input/keyboard/amikbd.c +++ b/trunk/drivers/input/keyboard/amikbd.c @@ -190,7 +190,7 @@ static int __init amikbd_init(void) int i, j; if (!AMIGAHW_PRESENT(AMI_KEYBOARD)) - return -ENODEV; + return -EIO; if (!request_mem_region(CIAA_PHYSADDR-1+0xb00, 0x100, "amikeyb")) return -EBUSY; @@ -198,8 +198,8 @@ static int __init amikbd_init(void) amikbd_dev = input_allocate_device(); if (!amikbd_dev) { printk(KERN_ERR "amikbd: not enough memory for input device\n"); - err = -ENOMEM; - goto fail1; + release_mem_region(CIAA_PHYSADDR - 1 + 0xb00, 0x100); + return -ENOMEM; } amikbd_dev->name = "Amiga Keyboard"; @@ -231,22 +231,10 @@ static int __init amikbd_init(void) memcpy(key_maps[i], temp_map, sizeof(temp_map)); } ciaa.cra &= ~0x41; /* serial data in, turn off TA */ - if (request_irq(IRQ_AMIGA_CIAA_SP, amikbd_interrupt, 0, "amikbd", - amikbd_interrupt)) { - err = -EBUSY; - goto fail2; - } - - err = input_register_device(amikbd_dev); - if (err) - goto fail3; + request_irq(IRQ_AMIGA_CIAA_SP, amikbd_interrupt, 0, "amikbd", amikbd_interrupt); + input_register_device(amikbd_dev); return 0; - - fail3: free_irq(IRQ_AMIGA_CIAA_SP, amikbd_interrupt); - fail2: input_free_device(amikbd_dev); - fail1: release_mem_region(CIAA_PHYSADDR - 1 + 0xb00, 0x100); - return err; } static void __exit amikbd_exit(void) diff --git a/trunk/drivers/input/keyboard/atkbd.c b/trunk/drivers/input/keyboard/atkbd.c index c621a9177a56..8451b29a3db5 100644 --- a/trunk/drivers/input/keyboard/atkbd.c +++ b/trunk/drivers/input/keyboard/atkbd.c @@ -939,7 +939,7 @@ static int atkbd_connect(struct serio *serio, struct serio_driver *drv) atkbd = kzalloc(sizeof(struct atkbd), GFP_KERNEL); dev = input_allocate_device(); if (!atkbd || !dev) - goto fail1; + goto fail; atkbd->dev = dev; ps2_init(&atkbd->ps2dev, serio); @@ -967,13 +967,14 @@ static int atkbd_connect(struct serio *serio, struct serio_driver *drv) err = serio_open(serio, drv); if (err) - goto fail2; + goto fail; if (atkbd->write) { if (atkbd_probe(atkbd)) { + serio_close(serio); err = -ENODEV; - goto fail3; + goto fail; } atkbd->set = atkbd_select_set(atkbd, atkbd_set, atkbd_extra); @@ -987,22 +988,16 @@ static int atkbd_connect(struct serio *serio, struct serio_driver *drv) atkbd_set_keycode_table(atkbd); atkbd_set_device_attrs(atkbd); - err = sysfs_create_group(&serio->dev.kobj, &atkbd_attribute_group); - if (err) - goto fail3; + sysfs_create_group(&serio->dev.kobj, &atkbd_attribute_group); atkbd_enable(atkbd); - err = input_register_device(atkbd->dev); - if (err) - goto fail4; + input_register_device(atkbd->dev); return 0; - fail4: sysfs_remove_group(&serio->dev.kobj, &atkbd_attribute_group); - fail3: serio_close(serio); - fail2: serio_set_drvdata(serio, NULL); - fail1: input_free_device(dev); + fail: serio_set_drvdata(serio, NULL); + input_free_device(dev); kfree(atkbd); return err; } @@ -1138,11 +1133,9 @@ static ssize_t atkbd_show_extra(struct atkbd *atkbd, char *buf) static ssize_t atkbd_set_extra(struct atkbd *atkbd, const char *buf, size_t count) { - struct input_dev *old_dev, *new_dev; + struct input_dev *new_dev; unsigned long value; char *rest; - int err; - unsigned char old_extra, old_set; if (!atkbd->write) return -EIO; @@ -1154,36 +1147,17 @@ static ssize_t atkbd_set_extra(struct atkbd *atkbd, const char *buf, size_t coun if (atkbd->extra != value) { /* * Since device's properties will change we need to - * unregister old device. But allocate and register - * new one first to make sure we have it. + * unregister old device. But allocate new one first + * to make sure we have it. */ - old_dev = atkbd->dev; - old_extra = atkbd->extra; - old_set = atkbd->set; - - new_dev = input_allocate_device(); - if (!new_dev) + if (!(new_dev = input_allocate_device())) return -ENOMEM; - + input_unregister_device(atkbd->dev); atkbd->dev = new_dev; atkbd->set = atkbd_select_set(atkbd, atkbd->set, value); atkbd_activate(atkbd); - atkbd_set_keycode_table(atkbd); atkbd_set_device_attrs(atkbd); - - err = input_register_device(atkbd->dev); - if (err) { - input_free_device(new_dev); - - atkbd->dev = old_dev; - atkbd->set = atkbd_select_set(atkbd, old_set, old_extra); - atkbd_set_keycode_table(atkbd); - atkbd_set_device_attrs(atkbd); - - return err; - } - input_unregister_device(old_dev); - + input_register_device(atkbd->dev); } return count; } @@ -1195,41 +1169,23 @@ static ssize_t atkbd_show_scroll(struct atkbd *atkbd, char *buf) static ssize_t atkbd_set_scroll(struct atkbd *atkbd, const char *buf, size_t count) { - struct input_dev *old_dev, *new_dev; + struct input_dev *new_dev; unsigned long value; char *rest; - int err; - unsigned char old_scroll; value = simple_strtoul(buf, &rest, 10); if (*rest || value > 1) return -EINVAL; if (atkbd->scroll != value) { - old_dev = atkbd->dev; - old_scroll = atkbd->scroll; - - new_dev = input_allocate_device(); - if (!new_dev) + if (!(new_dev = input_allocate_device())) return -ENOMEM; - + input_unregister_device(atkbd->dev); atkbd->dev = new_dev; atkbd->scroll = value; atkbd_set_keycode_table(atkbd); atkbd_set_device_attrs(atkbd); - - err = input_register_device(atkbd->dev); - if (err) { - input_free_device(new_dev); - - atkbd->scroll = old_scroll; - atkbd->dev = old_dev; - atkbd_set_keycode_table(atkbd); - atkbd_set_device_attrs(atkbd); - - return err; - } - input_unregister_device(old_dev); + input_register_device(atkbd->dev); } return count; } @@ -1241,11 +1197,9 @@ static ssize_t atkbd_show_set(struct atkbd *atkbd, char *buf) static ssize_t atkbd_set_set(struct atkbd *atkbd, const char *buf, size_t count) { - struct input_dev *old_dev, *new_dev; + struct input_dev *new_dev; unsigned long value; char *rest; - int err; - unsigned char old_set, old_extra; if (!atkbd->write) return -EIO; @@ -1255,32 +1209,15 @@ static ssize_t atkbd_set_set(struct atkbd *atkbd, const char *buf, size_t count) return -EINVAL; if (atkbd->set != value) { - old_dev = atkbd->dev; - old_extra = atkbd->extra; - old_set = atkbd->set; - - new_dev = input_allocate_device(); - if (!new_dev) + if (!(new_dev = input_allocate_device())) return -ENOMEM; - + input_unregister_device(atkbd->dev); atkbd->dev = new_dev; atkbd->set = atkbd_select_set(atkbd, value, atkbd->extra); atkbd_activate(atkbd); atkbd_set_keycode_table(atkbd); atkbd_set_device_attrs(atkbd); - - err = input_register_device(atkbd->dev); - if (err) { - input_free_device(new_dev); - - atkbd->dev = old_dev; - atkbd->set = atkbd_select_set(atkbd, old_set, old_extra); - atkbd_set_keycode_table(atkbd); - atkbd_set_device_attrs(atkbd); - - return err; - } - input_unregister_device(old_dev); + input_register_device(atkbd->dev); } return count; } @@ -1292,11 +1229,9 @@ static ssize_t atkbd_show_softrepeat(struct atkbd *atkbd, char *buf) static ssize_t atkbd_set_softrepeat(struct atkbd *atkbd, const char *buf, size_t count) { - struct input_dev *old_dev, *new_dev; + struct input_dev *new_dev; unsigned long value; char *rest; - int err; - unsigned char old_softrepeat, old_softraw; if (!atkbd->write) return -EIO; @@ -1306,32 +1241,15 @@ static ssize_t atkbd_set_softrepeat(struct atkbd *atkbd, const char *buf, size_t return -EINVAL; if (atkbd->softrepeat != value) { - old_dev = atkbd->dev; - old_softrepeat = atkbd->softrepeat; - old_softraw = atkbd->softraw; - - new_dev = input_allocate_device(); - if (!new_dev) + if (!(new_dev = input_allocate_device())) return -ENOMEM; - + input_unregister_device(atkbd->dev); atkbd->dev = new_dev; atkbd->softrepeat = value; if (atkbd->softrepeat) atkbd->softraw = 1; atkbd_set_device_attrs(atkbd); - - err = input_register_device(atkbd->dev); - if (err) { - input_free_device(new_dev); - - atkbd->dev = old_dev; - atkbd->softrepeat = old_softrepeat; - atkbd->softraw = old_softraw; - atkbd_set_device_attrs(atkbd); - - return err; - } - input_unregister_device(old_dev); + input_register_device(atkbd->dev); } return count; } @@ -1344,39 +1262,22 @@ static ssize_t atkbd_show_softraw(struct atkbd *atkbd, char *buf) static ssize_t atkbd_set_softraw(struct atkbd *atkbd, const char *buf, size_t count) { - struct input_dev *old_dev, *new_dev; + struct input_dev *new_dev; unsigned long value; char *rest; - int err; - unsigned char old_softraw; value = simple_strtoul(buf, &rest, 10); if (*rest || value > 1) return -EINVAL; if (atkbd->softraw != value) { - old_dev = atkbd->dev; - old_softraw = atkbd->softraw; - - new_dev = input_allocate_device(); - if (!new_dev) + if (!(new_dev = input_allocate_device())) return -ENOMEM; - + input_unregister_device(atkbd->dev); atkbd->dev = new_dev; atkbd->softraw = value; atkbd_set_device_attrs(atkbd); - - err = input_register_device(atkbd->dev); - if (err) { - input_free_device(new_dev); - - atkbd->dev = old_dev; - atkbd->softraw = old_softraw; - atkbd_set_device_attrs(atkbd); - - return err; - } - input_unregister_device(old_dev); + input_register_device(atkbd->dev); } return count; } @@ -1389,7 +1290,8 @@ static ssize_t atkbd_show_err_count(struct atkbd *atkbd, char *buf) static int __init atkbd_init(void) { - return serio_register_driver(&atkbd_drv); + serio_register_driver(&atkbd_drv); + return 0; } static void __exit atkbd_exit(void) diff --git a/trunk/drivers/input/keyboard/corgikbd.c b/trunk/drivers/input/keyboard/corgikbd.c index 1016c94e65db..befdd6006b50 100644 --- a/trunk/drivers/input/keyboard/corgikbd.c +++ b/trunk/drivers/input/keyboard/corgikbd.c @@ -291,12 +291,15 @@ static int __init corgikbd_probe(struct platform_device *pdev) { struct corgikbd *corgikbd; struct input_dev *input_dev; - int i, err = -ENOMEM; + int i; corgikbd = kzalloc(sizeof(struct corgikbd), GFP_KERNEL); input_dev = input_allocate_device(); - if (!corgikbd || !input_dev) - goto fail; + if (!corgikbd || !input_dev) { + kfree(corgikbd); + input_free_device(input_dev); + return -ENOMEM; + } platform_set_drvdata(pdev, corgikbd); @@ -338,9 +341,7 @@ static int __init corgikbd_probe(struct platform_device *pdev) set_bit(SW_TABLET_MODE, input_dev->swbit); set_bit(SW_HEADPHONE_INSERT, input_dev->swbit); - err = input_register_device(corgikbd->input); - if (err) - goto fail; + input_register_device(corgikbd->input); mod_timer(&corgikbd->htimer, jiffies + msecs_to_jiffies(HINGE_SCAN_INTERVAL)); @@ -361,10 +362,6 @@ static int __init corgikbd_probe(struct platform_device *pdev) pxa_gpio_mode(CORGI_GPIO_AK_INT | GPIO_IN); return 0; - - fail: input_free_device(input_dev); - kfree(corgikbd); - return err; } static int corgikbd_remove(struct platform_device *pdev) diff --git a/trunk/drivers/input/keyboard/hil_kbd.c b/trunk/drivers/input/keyboard/hil_kbd.c index 7cc9728b04df..e774dd31e99b 100644 --- a/trunk/drivers/input/keyboard/hil_kbd.c +++ b/trunk/drivers/input/keyboard/hil_kbd.c @@ -381,7 +381,8 @@ struct serio_driver hil_kbd_serio_drv = { static int __init hil_kbd_init(void) { - return serio_register_driver(&hil_kbd_serio_drv); + serio_register_driver(&hil_kbd_serio_drv); + return 0; } static void __exit hil_kbd_exit(void) diff --git a/trunk/drivers/input/keyboard/lkkbd.c b/trunk/drivers/input/keyboard/lkkbd.c index 3d4d0a0ede28..b7f049b45b6b 100644 --- a/trunk/drivers/input/keyboard/lkkbd.c +++ b/trunk/drivers/input/keyboard/lkkbd.c @@ -646,7 +646,7 @@ lkkbd_connect (struct serio *serio, struct serio_driver *drv) input_dev = input_allocate_device (); if (!lk || !input_dev) { err = -ENOMEM; - goto fail1; + goto fail; } lk->serio = serio; @@ -691,19 +691,15 @@ lkkbd_connect (struct serio *serio, struct serio_driver *drv) err = serio_open (serio, drv); if (err) - goto fail2; - - err = input_register_device (lk->dev); - if (err) - goto fail3; + goto fail; + input_register_device (lk->dev); lk->serio->write (lk->serio, LK_CMD_POWERCYCLE_RESET); return 0; - fail3: serio_close (serio); - fail2: serio_set_drvdata (serio, NULL); - fail1: input_free_device (input_dev); + fail: serio_set_drvdata (serio, NULL); + input_free_device (input_dev); kfree (lk); return err; } @@ -753,7 +749,8 @@ static struct serio_driver lkkbd_drv = { static int __init lkkbd_init (void) { - return serio_register_driver(&lkkbd_drv); + serio_register_driver(&lkkbd_drv); + return 0; } static void __exit diff --git a/trunk/drivers/input/keyboard/locomokbd.c b/trunk/drivers/input/keyboard/locomokbd.c index 2ade5186cc41..5788dbc317bb 100644 --- a/trunk/drivers/input/keyboard/locomokbd.c +++ b/trunk/drivers/input/keyboard/locomokbd.c @@ -193,22 +193,22 @@ static int locomokbd_probe(struct locomo_dev *dev) { struct locomokbd *locomokbd; struct input_dev *input_dev; - int i, err; + int i, ret; locomokbd = kzalloc(sizeof(struct locomokbd), GFP_KERNEL); input_dev = input_allocate_device(); if (!locomokbd || !input_dev) { - err = -ENOMEM; - goto err_free_mem; + ret = -ENOMEM; + goto free; } /* try and claim memory region */ if (!request_mem_region((unsigned long) dev->mapbase, dev->length, LOCOMO_DRIVER_NAME(dev))) { - err = -EBUSY; + ret = -EBUSY; printk(KERN_ERR "locomokbd: Can't acquire access to io memory for keyboard\n"); - goto err_free_mem; + goto free; } locomokbd->ldev = dev; @@ -244,28 +244,24 @@ static int locomokbd_probe(struct locomo_dev *dev) clear_bit(0, input_dev->keybit); /* attempt to get the interrupt */ - err = request_irq(dev->irq[0], locomokbd_interrupt, 0, "locomokbd", locomokbd); - if (err) { + ret = request_irq(dev->irq[0], locomokbd_interrupt, 0, "locomokbd", locomokbd); + if (ret) { printk(KERN_ERR "locomokbd: Can't get irq for keyboard\n"); - goto err_release_region; + goto out; } - err = input_register_device(locomokbd->input); - if (err) - goto err_free_irq; + input_register_device(locomokbd->input); return 0; - err_free_irq: - free_irq(dev->irq[0], locomokbd); - err_release_region: +out: release_mem_region((unsigned long) dev->mapbase, dev->length); locomo_set_drvdata(dev, NULL); - err_free_mem: +free: input_free_device(input_dev); kfree(locomokbd); - return err; + return ret; } static int locomokbd_remove(struct locomo_dev *dev) diff --git a/trunk/drivers/input/keyboard/maple_keyb.c b/trunk/drivers/input/keyboard/maple_keyb.c new file mode 100644 index 000000000000..cc6aaf9e85be --- /dev/null +++ b/trunk/drivers/input/keyboard/maple_keyb.c @@ -0,0 +1,160 @@ +/* + * $Id: maple_keyb.c,v 1.4 2004/03/22 01:18:15 lethal Exp $ + * SEGA Dreamcast keyboard driver + * Based on drivers/usb/usbkbd.c + */ + +#include +#include +#include +#include +#include +#include +#include + +MODULE_AUTHOR("YAEGASHI Takeshi "); +MODULE_DESCRIPTION("SEGA Dreamcast keyboard driver"); +MODULE_LICENSE("GPL"); + +static unsigned char dc_kbd_keycode[256] = { + 0, 0, 0, 0, 30, 48, 46, 32, 18, 33, 34, 35, 23, 36, 37, 38, + 50, 49, 24, 25, 16, 19, 31, 20, 22, 47, 17, 45, 21, 44, 2, 3, + 4, 5, 6, 7, 8, 9, 10, 11, 28, 1, 14, 15, 57, 12, 13, 26, + 27, 43, 43, 39, 40, 41, 51, 52, 53, 58, 59, 60, 61, 62, 63, 64, + 65, 66, 67, 68, 87, 88, 99, 70,119,110,102,104,111,107,109,106, + 105,108,103, 69, 98, 55, 74, 78, 96, 79, 80, 81, 75, 76, 77, 71, + 72, 73, 82, 83, 86,127,116,117,183,184,185,186,187,188,189,190, + 191,192,193,194,134,138,130,132,128,129,131,137,133,135,136,113, + 115,114, 0, 0, 0,121, 0, 89, 93,124, 92, 94, 95, 0, 0, 0, + 122,123, 90, 91, 85, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 29, 42, 56,125, 97, 54,100,126,164,166,165,163,161,115,114,113, + 150,158,159,128,136,177,178,176,142,152,173,140 +}; + + +struct dc_kbd { + struct input_dev *dev; + unsigned char new[8]; + unsigned char old[8]; +}; + + +static void dc_scan_kbd(struct dc_kbd *kbd) +{ + int i; + struct input_dev *dev = kbd->dev; + + for (i = 0; i < 8; i++) + input_report_key(dev, dc_kbd_keycode[i + 224], (kbd->new[0] >> i) & 1); + + for (i = 2; i < 8; i++) { + + if (kbd->old[i] > 3 && memscan(kbd->new + 2, kbd->old[i], 6) == NULL) { + if (dc_kbd_keycode[kbd->old[i]]) + input_report_key(dev, dc_kbd_keycode[kbd->old[i]], 0); + else + printk("Unknown key (scancode %#x) released.", + kbd->old[i]); + } + + if (kbd->new[i] > 3 && memscan(kbd->old + 2, kbd->new[i], 6) != NULL) { + if(dc_kbd_keycode[kbd->new[i]]) + input_report_key(dev, dc_kbd_keycode[kbd->new[i]], 1); + else + printk("Unknown key (scancode %#x) pressed.", + kbd->new[i]); + } + } + + input_sync(dev); + + memcpy(kbd->old, kbd->new, 8); +} + + +static void dc_kbd_callback(struct mapleq *mq) +{ + struct maple_device *mapledev = mq->dev; + struct dc_kbd *kbd = mapledev->private_data; + unsigned long *buf = mq->recvbuf; + + if (buf[1] == mapledev->function) { + memcpy(kbd->new, buf + 2, 8); + dc_scan_kbd(kbd); + } +} + +static int dc_kbd_connect(struct maple_device *dev) +{ + struct dc_kbd *kbd; + struct input_dev *input_dev; + unsigned long data = be32_to_cpu(dev->devinfo.function_data[0]); + int i; + + dev->private_data = kbd = kzalloc(sizeof(struct dc_kbd), GFP_KERNEL); + input_dev = input_allocate_device(); + if (!kbd || !input_dev) { + kfree(kbd); + input_free_device(input_dev); + return -ENOMEM; + } + + kbd->dev = input_dev; + + input_dev->name = dev->product_name; + input_dev->id.bustype = BUS_MAPLE; + input_dev->private = kbd; + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP); + for (i = 0; i < 255; i++) + set_bit(dc_kbd_keycode[i], input_dev->keybit); + clear_bit(0, input_dev->keybit); + + input_register_device(kbd->dev); + + maple_getcond_callback(dev, dc_kbd_callback, 1, MAPLE_FUNC_KEYBOARD); + return 0; +} + + +static void dc_kbd_disconnect(struct maple_device *dev) +{ + struct dc_kbd *kbd = dev->private_data; + + input_unregister_device(kbd->dev); + kfree(kbd); +} + + +static struct maple_driver dc_kbd_driver = { + .function = MAPLE_FUNC_KEYBOARD, + .name = "Dreamcast keyboard", + .connect = dc_kbd_connect, + .disconnect = dc_kbd_disconnect, +}; + + +static int __init dc_kbd_init(void) +{ + maple_register_driver(&dc_kbd_driver); + return 0; +} + + +static void __exit dc_kbd_exit(void) +{ + maple_unregister_driver(&dc_kbd_driver); +} + + +module_init(dc_kbd_init); +module_exit(dc_kbd_exit); + +/* + * Local variables: + * c-basic-offset: 8 + * End: + */ diff --git a/trunk/drivers/input/keyboard/newtonkbd.c b/trunk/drivers/input/keyboard/newtonkbd.c index aa29b50765c9..9282e4e082bd 100644 --- a/trunk/drivers/input/keyboard/newtonkbd.c +++ b/trunk/drivers/input/keyboard/newtonkbd.c @@ -91,7 +91,7 @@ static int nkbd_connect(struct serio *serio, struct serio_driver *drv) nkbd = kzalloc(sizeof(struct nkbd), GFP_KERNEL); input_dev = input_allocate_device(); if (!nkbd || !input_dev) - goto fail1; + goto fail; nkbd->serio = serio; nkbd->dev = input_dev; @@ -119,17 +119,13 @@ static int nkbd_connect(struct serio *serio, struct serio_driver *drv) err = serio_open(serio, drv); if (err) - goto fail2; - - err = input_register_device(nkbd->dev); - if (err) - goto fail3; + goto fail; + input_register_device(nkbd->dev); return 0; - fail3: serio_close(serio); - fail2: serio_set_drvdata(serio, NULL); - fail1: input_free_device(input_dev); + fail: serio_set_drvdata(serio, NULL); + input_free_device(input_dev); kfree(nkbd); return err; } @@ -169,7 +165,8 @@ static struct serio_driver nkbd_drv = { static int __init nkbd_init(void) { - return serio_register_driver(&nkbd_drv); + serio_register_driver(&nkbd_drv); + return 0; } static void __exit nkbd_exit(void) diff --git a/trunk/drivers/input/keyboard/spitzkbd.c b/trunk/drivers/input/keyboard/spitzkbd.c index 8a2166c77ff4..28b2748e82d0 100644 --- a/trunk/drivers/input/keyboard/spitzkbd.c +++ b/trunk/drivers/input/keyboard/spitzkbd.c @@ -346,12 +346,17 @@ static int __init spitzkbd_probe(struct platform_device *dev) { struct spitzkbd *spitzkbd; struct input_dev *input_dev; - int i, err = -ENOMEM; + int i; spitzkbd = kzalloc(sizeof(struct spitzkbd), GFP_KERNEL); + if (!spitzkbd) + return -ENOMEM; + input_dev = input_allocate_device(); - if (!spitzkbd || !input_dev) - goto fail; + if (!input_dev) { + kfree(spitzkbd); + return -ENOMEM; + } platform_set_drvdata(dev, spitzkbd); strcpy(spitzkbd->phys, "spitzkbd/input0"); @@ -395,9 +400,7 @@ static int __init spitzkbd_probe(struct platform_device *dev) set_bit(SW_TABLET_MODE, input_dev->swbit); set_bit(SW_HEADPHONE_INSERT, input_dev->swbit); - err = input_register_device(input_dev); - if (err) - goto fail; + input_register_device(input_dev); mod_timer(&spitzkbd->htimer, jiffies + msecs_to_jiffies(HINGE_SCAN_INTERVAL)); @@ -431,15 +434,13 @@ static int __init spitzkbd_probe(struct platform_device *dev) request_irq(SPITZ_IRQ_GPIO_SWB, spitzkbd_hinge_isr, IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, "Spitzkbd SWB", spitzkbd); - request_irq(SPITZ_IRQ_GPIO_AK_INT, spitzkbd_hinge_isr, + request_irq(SPITZ_IRQ_GPIO_AK_INT, spitzkbd_hinge_isr, IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, "Spitzkbd HP", spitzkbd); - return 0; + printk(KERN_INFO "input: Spitz Keyboard Registered\n"); - fail: input_free_device(input_dev); - kfree(spitzkbd); - return err; + return 0; } static int spitzkbd_remove(struct platform_device *dev) @@ -473,7 +474,6 @@ static struct platform_driver spitzkbd_driver = { .resume = spitzkbd_resume, .driver = { .name = "spitz-keyboard", - .owner = THIS_MODULE, }, }; diff --git a/trunk/drivers/input/keyboard/stowaway.c b/trunk/drivers/input/keyboard/stowaway.c index f7b5c5b81451..e60937d17b1c 100644 --- a/trunk/drivers/input/keyboard/stowaway.c +++ b/trunk/drivers/input/keyboard/stowaway.c @@ -173,7 +173,8 @@ static struct serio_driver skbd_drv = { static int __init skbd_init(void) { - return serio_register_driver(&skbd_drv); + serio_register_driver(&skbd_drv); + return 0; } static void __exit skbd_exit(void) diff --git a/trunk/drivers/input/keyboard/sunkbd.c b/trunk/drivers/input/keyboard/sunkbd.c index 3826db9403e6..6cd887c5eb0a 100644 --- a/trunk/drivers/input/keyboard/sunkbd.c +++ b/trunk/drivers/input/keyboard/sunkbd.c @@ -243,7 +243,7 @@ static int sunkbd_connect(struct serio *serio, struct serio_driver *drv) sunkbd = kzalloc(sizeof(struct sunkbd), GFP_KERNEL); input_dev = input_allocate_device(); if (!sunkbd || !input_dev) - goto fail1; + goto fail; sunkbd->serio = serio; sunkbd->dev = input_dev; @@ -255,11 +255,11 @@ static int sunkbd_connect(struct serio *serio, struct serio_driver *drv) err = serio_open(serio, drv); if (err) - goto fail2; + goto fail; if (sunkbd_initialize(sunkbd) < 0) { - err = -ENODEV; - goto fail3; + serio_close(serio); + goto fail; } snprintf(sunkbd->name, sizeof(sunkbd->name), "Sun Type %d keyboard", sunkbd->type); @@ -287,17 +287,11 @@ static int sunkbd_connect(struct serio *serio, struct serio_driver *drv) clear_bit(0, input_dev->keybit); sunkbd_enable(sunkbd, 1); - - err = input_register_device(sunkbd->dev); - if (err) - goto fail4; - + input_register_device(sunkbd->dev); return 0; - fail4: sunkbd_enable(sunkbd, 0); - fail3: serio_close(serio); - fail2: serio_set_drvdata(serio, NULL); - fail1: input_free_device(input_dev); + fail: serio_set_drvdata(serio, NULL); + input_free_device(input_dev); kfree(sunkbd); return err; } @@ -352,7 +346,8 @@ static struct serio_driver sunkbd_drv = { static int __init sunkbd_init(void) { - return serio_register_driver(&sunkbd_drv); + serio_register_driver(&sunkbd_drv); + return 0; } static void __exit sunkbd_exit(void) diff --git a/trunk/drivers/input/keyboard/xtkbd.c b/trunk/drivers/input/keyboard/xtkbd.c index a82093432138..8c11dc935454 100644 --- a/trunk/drivers/input/keyboard/xtkbd.c +++ b/trunk/drivers/input/keyboard/xtkbd.c @@ -95,7 +95,7 @@ static int xtkbd_connect(struct serio *serio, struct serio_driver *drv) xtkbd = kmalloc(sizeof(struct xtkbd), GFP_KERNEL); input_dev = input_allocate_device(); if (!xtkbd || !input_dev) - goto fail1; + goto fail; xtkbd->serio = serio; xtkbd->dev = input_dev; @@ -124,17 +124,13 @@ static int xtkbd_connect(struct serio *serio, struct serio_driver *drv) err = serio_open(serio, drv); if (err) - goto fail2; - - err = input_register_device(xtkbd->dev); - if (err) - goto fail3; + goto fail; + input_register_device(xtkbd->dev); return 0; - fail3: serio_close(serio); - fail2: serio_set_drvdata(serio, NULL); - fail1: input_free_device(input_dev); + fail: serio_set_drvdata(serio, NULL); + input_free_device(input_dev); kfree(xtkbd); return err; } @@ -174,7 +170,8 @@ static struct serio_driver xtkbd_drv = { static int __init xtkbd_init(void) { - return serio_register_driver(&xtkbd_drv); + serio_register_driver(&xtkbd_drv); + return 0; } static void __exit xtkbd_exit(void) diff --git a/trunk/drivers/input/mouse/amimouse.c b/trunk/drivers/input/mouse/amimouse.c index 239a0e16d91a..599a7b2dc519 100644 --- a/trunk/drivers/input/mouse/amimouse.c +++ b/trunk/drivers/input/mouse/amimouse.c @@ -95,13 +95,10 @@ static void amimouse_close(struct input_dev *dev) static int __init amimouse_init(void) { - int err; - if (!MACH_IS_AMIGA || !AMIGAHW_PRESENT(AMI_MOUSE)) return -ENODEV; - amimouse_dev = input_allocate_device(); - if (!amimouse_dev) + if (!(amimouse_dev = input_allocate_device())) return -ENOMEM; amimouse_dev->name = "Amiga mouse"; @@ -117,11 +114,7 @@ static int __init amimouse_init(void) amimouse_dev->open = amimouse_open; amimouse_dev->close = amimouse_close; - err = input_register_device(amimouse_dev); - if (err) { - input_free_device(amimouse_dev); - return err; - } + input_register_device(amimouse_dev); return 0; } diff --git a/trunk/drivers/input/mouse/hil_ptr.c b/trunk/drivers/input/mouse/hil_ptr.c index bfb174fe3230..4f2b503c1ac7 100644 --- a/trunk/drivers/input/mouse/hil_ptr.c +++ b/trunk/drivers/input/mouse/hil_ptr.c @@ -417,7 +417,8 @@ static struct serio_driver hil_ptr_serio_driver = { static int __init hil_ptr_init(void) { - return serio_register_driver(&hil_ptr_serio_driver); + serio_register_driver(&hil_ptr_serio_driver); + return 0; } static void __exit hil_ptr_exit(void) diff --git a/trunk/drivers/input/mouse/inport.c b/trunk/drivers/input/mouse/inport.c index 13dd96785e39..e1252fa9a107 100644 --- a/trunk/drivers/input/mouse/inport.c +++ b/trunk/drivers/input/mouse/inport.c @@ -135,7 +135,6 @@ static void inport_close(struct input_dev *dev) static int __init inport_init(void) { unsigned char a, b, c; - int err; if (!request_region(INPORT_BASE, INPORT_EXTENT, "inport")) { printk(KERN_ERR "inport.c: Can't allocate ports at %#x\n", INPORT_BASE); @@ -146,16 +145,15 @@ static int __init inport_init(void) b = inb(INPORT_SIGNATURE_PORT); c = inb(INPORT_SIGNATURE_PORT); if (a == b || a != c) { + release_region(INPORT_BASE, INPORT_EXTENT); printk(KERN_ERR "inport.c: Didn't find InPort mouse at %#x\n", INPORT_BASE); - err = -ENODEV; - goto err_release_region; + return -ENODEV; } - inport_dev = input_allocate_device(); - if (!inport_dev) { + if (!(inport_dev = input_allocate_device())) { printk(KERN_ERR "inport.c: Not enough memory for input device\n"); - err = -ENOMEM; - goto err_release_region; + release_region(INPORT_BASE, INPORT_EXTENT); + return -ENOMEM; } inport_dev->name = INPORT_NAME; @@ -176,18 +174,9 @@ static int __init inport_init(void) outb(INPORT_REG_MODE, INPORT_CONTROL_PORT); outb(INPORT_MODE_BASE, INPORT_DATA_PORT); - err = input_register_device(inport_dev); - if (err) - goto err_free_dev; + input_register_device(inport_dev); return 0; - - err_free_dev: - input_free_device(inport_dev); - err_release_region: - release_region(INPORT_BASE, INPORT_EXTENT); - - return err; } static void __exit inport_exit(void) diff --git a/trunk/drivers/input/mouse/lifebook.c b/trunk/drivers/input/mouse/lifebook.c index 29542f0631cb..c57e8853b949 100644 --- a/trunk/drivers/input/mouse/lifebook.c +++ b/trunk/drivers/input/mouse/lifebook.c @@ -21,51 +21,47 @@ #include "lifebook.h" static struct dmi_system_id lifebook_dmi_table[] = { - { - .ident = "FLORA-ie 55mi", - .matches = { - DMI_MATCH(DMI_PRODUCT_NAME, "FLORA-ie 55mi"), - }, - }, - { - .ident = "LifeBook B", - .matches = { - DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook B Series"), - }, - }, - { - .ident = "Lifebook B", - .matches = { - DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK B Series"), - }, - }, - { - .ident = "Lifebook B213x/B2150", - .matches = { - DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook B2131/B2133/B2150"), - }, - }, - { - .ident = "Zephyr", - .matches = { - DMI_MATCH(DMI_PRODUCT_NAME, "ZEPHYR"), - }, - }, - { - .ident = "CF-18", - .matches = { - DMI_MATCH(DMI_PRODUCT_NAME, "CF-18"), - }, - }, - { - .ident = "Lifebook B142", - .matches = { - DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook B142"), - }, - }, - { } + { + .ident = "LifeBook B", + .matches = { + DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook B Series"), + }, + }, + { + .ident = "Lifebook B", + .matches = { + DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK B Series"), + }, + }, + { + .ident = "Lifebook B213x/B2150", + .matches = { + DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook B2131/B2133/B2150"), + }, + }, + { + .ident = "Zephyr", + .matches = { + DMI_MATCH(DMI_PRODUCT_NAME, "ZEPHYR"), + }, + }, + { + .ident = "CF-18", + .matches = { + DMI_MATCH(DMI_PRODUCT_NAME, "CF-18"), + }, + }, + { + .ident = "Lifebook B142", + .matches = { + DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook B142"), + }, + + }, + { } }; + static psmouse_ret_t lifebook_process_byte(struct psmouse *psmouse) { unsigned char *packet = psmouse->packet; diff --git a/trunk/drivers/input/mouse/logibm.c b/trunk/drivers/input/mouse/logibm.c index db205995bffd..8e9c2f3d69a8 100644 --- a/trunk/drivers/input/mouse/logibm.c +++ b/trunk/drivers/input/mouse/logibm.c @@ -124,8 +124,6 @@ static void logibm_close(struct input_dev *dev) static int __init logibm_init(void) { - int err; - if (!request_region(LOGIBM_BASE, LOGIBM_EXTENT, "logibm")) { printk(KERN_ERR "logibm.c: Can't allocate ports at %#x\n", LOGIBM_BASE); return -EBUSY; @@ -136,19 +134,18 @@ static int __init logibm_init(void) udelay(100); if (inb(LOGIBM_SIGNATURE_PORT) != LOGIBM_SIGNATURE_BYTE) { + release_region(LOGIBM_BASE, LOGIBM_EXTENT); printk(KERN_ERR "logibm.c: Didn't find Logitech busmouse at %#x\n", LOGIBM_BASE); - err = -ENODEV; - goto err_release_region; + return -ENODEV; } outb(LOGIBM_DEFAULT_MODE, LOGIBM_CONFIG_PORT); outb(LOGIBM_DISABLE_IRQ, LOGIBM_CONTROL_PORT); - logibm_dev = input_allocate_device(); - if (!logibm_dev) { + if (!(logibm_dev = input_allocate_device())) { printk(KERN_ERR "logibm.c: Not enough memory for input device\n"); - err = -ENOMEM; - goto err_release_region; + release_region(LOGIBM_BASE, LOGIBM_EXTENT); + return -ENOMEM; } logibm_dev->name = "Logitech bus mouse"; @@ -165,18 +162,9 @@ static int __init logibm_init(void) logibm_dev->open = logibm_open; logibm_dev->close = logibm_close; - err = input_register_device(logibm_dev); - if (err) - goto err_free_dev; + input_register_device(logibm_dev); return 0; - - err_free_dev: - input_free_device(logibm_dev); - err_release_region: - release_region(LOGIBM_BASE, LOGIBM_EXTENT); - - return err; } static void __exit logibm_exit(void) diff --git a/trunk/drivers/input/mouse/logips2pp.c b/trunk/drivers/input/mouse/logips2pp.c index d3ddea26b8ca..8a4f862709e7 100644 --- a/trunk/drivers/input/mouse/logips2pp.c +++ b/trunk/drivers/input/mouse/logips2pp.c @@ -328,7 +328,6 @@ int ps2pp_init(struct psmouse *psmouse, int set_properties) unsigned char model, buttons; const struct ps2pp_info *model_info; int use_ps2pp = 0; - int error; param[0] = 0; ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES); @@ -394,14 +393,8 @@ int ps2pp_init(struct psmouse *psmouse, int set_properties) psmouse->set_resolution = ps2pp_set_resolution; psmouse->disconnect = ps2pp_disconnect; - error = device_create_file(&psmouse->ps2dev.serio->dev, - &psmouse_attr_smartscroll.dattr); - if (error) { - printk(KERN_ERR - "logips2pp.c: failed to create smartscroll " - "sysfs attribute, error: %d\n", error); - return -1; - } + device_create_file(&psmouse->ps2dev.serio->dev, + &psmouse_attr_smartscroll.dattr); } } diff --git a/trunk/drivers/input/mouse/pc110pad.c b/trunk/drivers/input/mouse/pc110pad.c index f155c1fea04e..8c075aa7223b 100644 --- a/trunk/drivers/input/mouse/pc110pad.c +++ b/trunk/drivers/input/mouse/pc110pad.c @@ -108,7 +108,6 @@ static int pc110pad_open(struct input_dev *dev) static int __init pc110pad_init(void) { struct pci_dev *dev; - int err; dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL); if (dev) { @@ -125,16 +124,16 @@ static int __init pc110pad_init(void) outb(PC110PAD_OFF, pc110pad_io + 2); if (request_irq(pc110pad_irq, pc110pad_interrupt, 0, "pc110pad", NULL)) { + release_region(pc110pad_io, 4); printk(KERN_ERR "pc110pad: Unable to get irq %d.\n", pc110pad_irq); - err = -EBUSY; - goto err_release_region; + return -EBUSY; } - pc110pad_dev = input_allocate_device(); - if (!pc110pad_dev) { + if (!(pc110pad_dev = input_allocate_device())) { + free_irq(pc110pad_irq, NULL); + release_region(pc110pad_io, 4); printk(KERN_ERR "pc110pad: Not enough memory.\n"); - err = -ENOMEM; - goto err_free_irq; + return -ENOMEM; } pc110pad_dev->name = "IBM PC110 TouchPad"; @@ -154,20 +153,9 @@ static int __init pc110pad_init(void) pc110pad_dev->open = pc110pad_open; pc110pad_dev->close = pc110pad_close; - err = input_register_device(pc110pad_dev); - if (err) - goto err_free_dev; + input_register_device(pc110pad_dev); return 0; - - err_free_dev: - input_free_device(pc110pad_dev); - err_free_irq: - free_irq(pc110pad_irq, NULL); - err_release_region: - release_region(pc110pad_io, 4); - - return err; } static void __exit pc110pad_exit(void) diff --git a/trunk/drivers/input/mouse/psmouse-base.c b/trunk/drivers/input/mouse/psmouse-base.c index a0e4a033e2db..52bb2226ce2f 100644 --- a/trunk/drivers/input/mouse/psmouse-base.c +++ b/trunk/drivers/input/mouse/psmouse-base.c @@ -1103,7 +1103,7 @@ static int psmouse_connect(struct serio *serio, struct serio_driver *drv) { struct psmouse *psmouse, *parent = NULL; struct input_dev *input_dev; - int retval = 0, error = -ENOMEM; + int retval = -ENOMEM; mutex_lock(&psmouse_mutex); @@ -1119,7 +1119,7 @@ static int psmouse_connect(struct serio *serio, struct serio_driver *drv) psmouse = kzalloc(sizeof(struct psmouse), GFP_KERNEL); input_dev = input_allocate_device(); if (!psmouse || !input_dev) - goto err_free; + goto out; ps2_init(&psmouse->ps2dev, serio); INIT_WORK(&psmouse->resync_work, psmouse_resync); @@ -1130,13 +1130,14 @@ static int psmouse_connect(struct serio *serio, struct serio_driver *drv) serio_set_drvdata(serio, psmouse); - error = serio_open(serio, drv); - if (error) - goto err_clear_drvdata; + retval = serio_open(serio, drv); + if (retval) + goto out; if (psmouse_probe(psmouse) < 0) { - error = -ENODEV; - goto err_close_serio; + serio_close(serio); + retval = -ENODEV; + goto out; } psmouse->rate = psmouse_rate; @@ -1150,44 +1151,30 @@ static int psmouse_connect(struct serio *serio, struct serio_driver *drv) psmouse_set_state(psmouse, PSMOUSE_CMD_MODE); psmouse_initialize(psmouse); - error = input_register_device(psmouse->dev); - if (error) - goto err_protocol_disconnect; + input_register_device(psmouse->dev); if (parent && parent->pt_activate) parent->pt_activate(parent); - error = sysfs_create_group(&serio->dev.kobj, &psmouse_attribute_group); - if (error) - goto err_pt_deactivate; + sysfs_create_group(&serio->dev.kobj, &psmouse_attribute_group); psmouse_activate(psmouse); - out: + retval = 0; + +out: + if (retval) { + serio_set_drvdata(serio, NULL); + input_free_device(input_dev); + kfree(psmouse); + } + /* If this is a pass-through port the parent needs to be re-activated */ if (parent) psmouse_activate(parent); mutex_unlock(&psmouse_mutex); return retval; - - err_pt_deactivate: - if (parent && parent->pt_deactivate) - parent->pt_deactivate(parent); - err_protocol_disconnect: - if (psmouse->disconnect) - psmouse->disconnect(psmouse); - psmouse_set_state(psmouse, PSMOUSE_IGNORE); - err_close_serio: - serio_close(serio); - err_clear_drvdata: - serio_set_drvdata(serio, NULL); - err_free: - input_free_device(input_dev); - kfree(psmouse); - - retval = error; - goto out; } @@ -1350,14 +1337,14 @@ ssize_t psmouse_attr_set_helper(struct device *dev, struct device_attribute *dev static ssize_t psmouse_show_int_attr(struct psmouse *psmouse, void *offset, char *buf) { - unsigned int *field = (unsigned int *)((char *)psmouse + (size_t)offset); + unsigned long *field = (unsigned long *)((char *)psmouse + (size_t)offset); - return sprintf(buf, "%u\n", *field); + return sprintf(buf, "%lu\n", *field); } static ssize_t psmouse_set_int_attr(struct psmouse *psmouse, void *offset, const char *buf, size_t count) { - unsigned int *field = (unsigned int *)((char *)psmouse + (size_t)offset); + unsigned long *field = (unsigned long *)((char *)psmouse + (size_t)offset); unsigned long value; char *rest; @@ -1365,9 +1352,6 @@ static ssize_t psmouse_set_int_attr(struct psmouse *psmouse, void *offset, const if (*rest) return -EINVAL; - if ((unsigned int)value != value) - return -EINVAL; - *field = value; return count; @@ -1382,20 +1366,17 @@ static ssize_t psmouse_attr_set_protocol(struct psmouse *psmouse, void *data, co { struct serio *serio = psmouse->ps2dev.serio; struct psmouse *parent = NULL; - struct input_dev *old_dev, *new_dev; - const struct psmouse_protocol *proto, *old_proto; - int error; + struct input_dev *new_dev; + const struct psmouse_protocol *proto; int retry = 0; - proto = psmouse_protocol_by_name(buf, count); - if (!proto) + if (!(proto = psmouse_protocol_by_name(buf, count))) return -EINVAL; if (psmouse->type == proto->type) return count; - new_dev = input_allocate_device(); - if (!new_dev) + if (!(new_dev = input_allocate_device())) return -ENOMEM; while (serio->child) { @@ -1428,13 +1409,11 @@ static ssize_t psmouse_attr_set_protocol(struct psmouse *psmouse, void *data, co parent->pt_deactivate(parent); } - old_dev = psmouse->dev; - old_proto = psmouse_protocol_by_type(psmouse->type); - if (psmouse->disconnect) psmouse->disconnect(psmouse); psmouse_set_state(psmouse, PSMOUSE_IGNORE); + input_unregister_device(psmouse->dev); psmouse->dev = new_dev; psmouse_set_state(psmouse, PSMOUSE_INITIALIZING); @@ -1448,23 +1427,7 @@ static ssize_t psmouse_attr_set_protocol(struct psmouse *psmouse, void *data, co psmouse_initialize(psmouse); psmouse_set_state(psmouse, PSMOUSE_CMD_MODE); - error = input_register_device(psmouse->dev); - if (error) { - if (psmouse->disconnect) - psmouse->disconnect(psmouse); - - psmouse_set_state(psmouse, PSMOUSE_IGNORE); - input_free_device(new_dev); - psmouse->dev = old_dev; - psmouse_set_state(psmouse, PSMOUSE_INITIALIZING); - psmouse_switch_protocol(psmouse, old_proto); - psmouse_initialize(psmouse); - psmouse_set_state(psmouse, PSMOUSE_CMD_MODE); - - return error; - } - - input_unregister_device(old_dev); + input_register_device(psmouse->dev); if (parent && parent->pt_activate) parent->pt_activate(parent); @@ -1525,19 +1488,15 @@ static int psmouse_get_maxproto(char *buffer, struct kernel_param *kp) static int __init psmouse_init(void) { - int err; - kpsmoused_wq = create_singlethread_workqueue("kpsmoused"); if (!kpsmoused_wq) { printk(KERN_ERR "psmouse: failed to create kpsmoused workqueue\n"); return -ENOMEM; } - err = serio_register_driver(&psmouse_drv); - if (err) - destroy_workqueue(kpsmoused_wq); + serio_register_driver(&psmouse_drv); - return err; + return 0; } static void __exit psmouse_exit(void) diff --git a/trunk/drivers/input/mouse/rpcmouse.c b/trunk/drivers/input/mouse/rpcmouse.c index fbdcfd8eb4e9..ea0468569610 100644 --- a/trunk/drivers/input/mouse/rpcmouse.c +++ b/trunk/drivers/input/mouse/rpcmouse.c @@ -66,10 +66,7 @@ static irqreturn_t rpcmouse_irq(int irq, void *dev_id) static int __init rpcmouse_init(void) { - int err; - - rpcmouse_dev = input_allocate_device(); - if (!rpcmouse_dev) + if (!(rpcmouse_dev = input_allocate_device())) return -ENOMEM; rpcmouse_dev->name = "Acorn RiscPC Mouse"; @@ -88,22 +85,13 @@ static int __init rpcmouse_init(void) if (request_irq(IRQ_VSYNCPULSE, rpcmouse_irq, IRQF_SHARED, "rpcmouse", rpcmouse_dev)) { printk(KERN_ERR "rpcmouse: unable to allocate VSYNC interrupt\n"); - err = -EBUSY; - goto err_free_dev; + input_free_device(rpcmouse_dev); + return -EBUSY; } - err = input_register_device(rpcmouse_dev); - if (err) - goto err_free_irq; + input_register_device(rpcmouse_dev); return 0; - - err_free_irq: - free_irq(IRQ_VSYNCPULSE, rpcmouse_dev); - err_free_dev: - input_free_device(rpcmouse_dev); - - return err; } static void __exit rpcmouse_exit(void) diff --git a/trunk/drivers/input/mouse/sermouse.c b/trunk/drivers/input/mouse/sermouse.c index a85d74710b44..2a272c5daf08 100644 --- a/trunk/drivers/input/mouse/sermouse.c +++ b/trunk/drivers/input/mouse/sermouse.c @@ -246,7 +246,7 @@ static int sermouse_connect(struct serio *serio, struct serio_driver *drv) sermouse = kzalloc(sizeof(struct sermouse), GFP_KERNEL); input_dev = input_allocate_device(); if (!sermouse || !input_dev) - goto fail1; + goto fail; sermouse->dev = input_dev; snprintf(sermouse->phys, sizeof(sermouse->phys), "%s/input0", serio->phys); @@ -275,17 +275,14 @@ static int sermouse_connect(struct serio *serio, struct serio_driver *drv) err = serio_open(serio, drv); if (err) - goto fail2; + goto fail; - err = input_register_device(sermouse->dev); - if (err) - goto fail3; + input_register_device(sermouse->dev); return 0; - fail3: serio_close(serio); - fail2: serio_set_drvdata(serio, NULL); - fail1: input_free_device(input_dev); + fail: serio_set_drvdata(serio, NULL); + input_free_device(input_dev); kfree(sermouse); return err; } @@ -351,7 +348,8 @@ static struct serio_driver sermouse_drv = { static int __init sermouse_init(void) { - return serio_register_driver(&sermouse_drv); + serio_register_driver(&sermouse_drv); + return 0; } static void __exit sermouse_exit(void) diff --git a/trunk/drivers/input/mouse/trackpoint.c b/trunk/drivers/input/mouse/trackpoint.c index 9ab5b5ea809d..ae5871a0e060 100644 --- a/trunk/drivers/input/mouse/trackpoint.c +++ b/trunk/drivers/input/mouse/trackpoint.c @@ -293,7 +293,6 @@ int trackpoint_detect(struct psmouse *psmouse, int set_properties) struct ps2dev *ps2dev = &psmouse->ps2dev; unsigned char firmware_id; unsigned char button_info; - int error; if (trackpoint_start_protocol(psmouse, &firmware_id)) return -1; @@ -306,7 +305,7 @@ int trackpoint_detect(struct psmouse *psmouse, int set_properties) button_info = 0; } - psmouse->private = priv = kzalloc(sizeof(struct trackpoint_data), GFP_KERNEL); + psmouse->private = priv = kcalloc(1, sizeof(struct trackpoint_data), GFP_KERNEL); if (!priv) return -1; @@ -319,14 +318,7 @@ int trackpoint_detect(struct psmouse *psmouse, int set_properties) trackpoint_defaults(priv); trackpoint_sync(psmouse); - error = sysfs_create_group(&ps2dev->serio->dev.kobj, &trackpoint_attr_group); - if (error) { - printk(KERN_ERR - "trackpoint.c: failed to create sysfs attributes, error: %d\n", - error); - kfree(priv); - return -1; - } + sysfs_create_group(&ps2dev->serio->dev.kobj, &trackpoint_attr_group); printk(KERN_INFO "IBM TrackPoint firmware: 0x%02x, buttons: %d/%d\n", firmware_id, (button_info & 0xf0) >> 4, button_info & 0x0f); diff --git a/trunk/drivers/input/mouse/vsxxxaa.c b/trunk/drivers/input/mouse/vsxxxaa.c index c3d64fcc858d..ffdb50eee93d 100644 --- a/trunk/drivers/input/mouse/vsxxxaa.c +++ b/trunk/drivers/input/mouse/vsxxxaa.c @@ -497,7 +497,7 @@ vsxxxaa_connect (struct serio *serio, struct serio_driver *drv) mouse = kzalloc (sizeof (struct vsxxxaa), GFP_KERNEL); input_dev = input_allocate_device (); if (!mouse || !input_dev) - goto fail1; + goto fail; mouse->dev = input_dev; mouse->serio = serio; @@ -527,7 +527,7 @@ vsxxxaa_connect (struct serio *serio, struct serio_driver *drv) err = serio_open (serio, drv); if (err) - goto fail2; + goto fail; /* * Request selftest. Standard packet format and differential @@ -535,15 +535,12 @@ vsxxxaa_connect (struct serio *serio, struct serio_driver *drv) */ serio->write (serio, 'T'); /* Test */ - err = input_register_device (input_dev); - if (err) - goto fail3; + input_register_device (input_dev); return 0; - fail3: serio_close (serio); - fail2: serio_set_drvdata (serio, NULL); - fail1: input_free_device (input_dev); + fail: serio_set_drvdata (serio, NULL); + input_free_device (input_dev); kfree (mouse); return err; } @@ -574,7 +571,8 @@ static struct serio_driver vsxxxaa_drv = { static int __init vsxxxaa_init (void) { - return serio_register_driver(&vsxxxaa_drv); + serio_register_driver(&vsxxxaa_drv); + return 0; } static void __exit diff --git a/trunk/drivers/input/mousedev.c b/trunk/drivers/input/mousedev.c index 664bcc8116fc..a22a74a2a3dc 100644 --- a/trunk/drivers/input/mousedev.c +++ b/trunk/drivers/input/mousedev.c @@ -196,12 +196,12 @@ static void mousedev_key_event(struct mousedev *mousedev, unsigned int code, int switch (code) { case BTN_TOUCH: case BTN_0: + case BTN_FORWARD: case BTN_LEFT: index = 0; break; case BTN_STYLUS: case BTN_1: case BTN_RIGHT: index = 1; break; case BTN_2: - case BTN_FORWARD: case BTN_STYLUS2: case BTN_MIDDLE: index = 2; break; case BTN_3: diff --git a/trunk/drivers/input/serio/i8042-x86ia64io.h b/trunk/drivers/input/serio/i8042-x86ia64io.h index d36bd5475b6d..8738edda6610 100644 --- a/trunk/drivers/input/serio/i8042-x86ia64io.h +++ b/trunk/drivers/input/serio/i8042-x86ia64io.h @@ -110,13 +110,6 @@ static struct dmi_system_id __initdata i8042_dmi_nomux_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "P7010"), }, }, - { - .ident = "Fujitsu Lifebook P7010", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), - DMI_MATCH(DMI_PRODUCT_NAME, "0000000000"), - }, - }, { .ident = "Fujitsu Lifebook P5020D", .matches = { diff --git a/trunk/drivers/input/serio/i8042.c b/trunk/drivers/input/serio/i8042.c index debe9445488c..7e3141f37e32 100644 --- a/trunk/drivers/input/serio/i8042.c +++ b/trunk/drivers/input/serio/i8042.c @@ -255,10 +255,25 @@ static int i8042_kbd_write(struct serio *port, unsigned char c) static int i8042_aux_write(struct serio *serio, unsigned char c) { struct i8042_port *port = serio->port_data; + int retval; + +/* + * Send the byte out. + */ + + if (port->mux == -1) + retval = i8042_command(&c, I8042_CMD_AUX_SEND); + else + retval = i8042_command(&c, I8042_CMD_MUX_SEND + port->mux); + +/* + * Make sure the interrupt happens and the character is received even + * in the case the IRQ isn't wired, so that we can receive further + * characters later. + */ - return i8042_command(&c, port->mux == -1 ? - I8042_CMD_AUX_SEND : - I8042_CMD_MUX_SEND + port->mux); + i8042_interrupt(0, NULL); + return retval; } /* @@ -322,27 +337,23 @@ static irqreturn_t i8042_interrupt(int irq, void *dev_id) dfl = 0; if (str & I8042_STR_MUXERR) { dbg("MUX error, status is %02x, data is %02x", str, data); + switch (data) { + default: /* * When MUXERR condition is signalled the data register can only contain * 0xfd, 0xfe or 0xff if implementation follows the spec. Unfortunately - * it is not always the case. Some KBCs also report 0xfc when there is - * nothing connected to the port while others sometimes get confused which - * port the data came from and signal error leaving the data intact. They - * _do not_ revert to legacy mode (actually I've never seen KBC reverting - * to legacy mode yet, when we see one we'll add proper handling). - * Anyway, we process 0xfc, 0xfd, 0xfe and 0xff as timeouts, and for the - * rest assume that the data came from the same serio last byte + * it is not always the case. Some KBC just get confused which port the + * data came from and signal error leaving the data intact. They _do not_ + * revert to legacy mode (actually I've never seen KBC reverting to legacy + * mode yet, when we see one we'll add proper handling). + * Anyway, we will assume that the data came from the same serio last byte * was transmitted (if transmission happened not too long ago). */ - - switch (data) { - default: if (time_before(jiffies, last_transmit + HZ/10)) { str = last_str; break; } /* fall through - report timeout */ - case 0xfc: case 0xfd: case 0xfe: dfl = SERIO_TIMEOUT; data = 0xfe; break; case 0xff: dfl = SERIO_PARITY; data = 0xfe; break; diff --git a/trunk/drivers/input/serio/serio.c b/trunk/drivers/input/serio/serio.c index f0ce822c1028..5f1d4032fd57 100644 --- a/trunk/drivers/input/serio/serio.c +++ b/trunk/drivers/input/serio/serio.c @@ -45,7 +45,8 @@ EXPORT_SYMBOL(serio_interrupt); EXPORT_SYMBOL(__serio_register_port); EXPORT_SYMBOL(serio_unregister_port); EXPORT_SYMBOL(serio_unregister_child_port); -EXPORT_SYMBOL(serio_register_driver); +EXPORT_SYMBOL(__serio_unregister_port_delayed); +EXPORT_SYMBOL(__serio_register_driver); EXPORT_SYMBOL(serio_unregister_driver); EXPORT_SYMBOL(serio_open); EXPORT_SYMBOL(serio_close); @@ -62,10 +63,11 @@ static LIST_HEAD(serio_list); static struct bus_type serio_bus; +static void serio_add_driver(struct serio_driver *drv); static void serio_add_port(struct serio *serio); +static void serio_destroy_port(struct serio *serio); static void serio_reconnect_port(struct serio *serio); static void serio_disconnect_port(struct serio *serio); -static void serio_attach_driver(struct serio_driver *drv); static int serio_connect_driver(struct serio *serio, struct serio_driver *drv) { @@ -169,10 +171,11 @@ static void serio_find_driver(struct serio *serio) */ enum serio_event_type { - SERIO_RESCAN_PORT, - SERIO_RECONNECT_PORT, + SERIO_RESCAN, + SERIO_RECONNECT, SERIO_REGISTER_PORT, - SERIO_ATTACH_DRIVER, + SERIO_UNREGISTER_PORT, + SERIO_REGISTER_DRIVER, }; struct serio_event { @@ -187,12 +190,11 @@ static LIST_HEAD(serio_event_list); static DECLARE_WAIT_QUEUE_HEAD(serio_wait); static struct task_struct *serio_task; -static int serio_queue_event(void *object, struct module *owner, - enum serio_event_type event_type) +static void serio_queue_event(void *object, struct module *owner, + enum serio_event_type event_type) { unsigned long flags; struct serio_event *event; - int retval = 0; spin_lock_irqsave(&serio_event_lock, flags); @@ -211,34 +213,24 @@ static int serio_queue_event(void *object, struct module *owner, } } - event = kmalloc(sizeof(struct serio_event), GFP_ATOMIC); - if (!event) { - printk(KERN_ERR - "serio: Not enough memory to queue event %d\n", - event_type); - retval = -ENOMEM; - goto out; - } - - if (!try_module_get(owner)) { - printk(KERN_WARNING - "serio: Can't get module reference, dropping event %d\n", - event_type); - kfree(event); - retval = -EINVAL; - goto out; - } - - event->type = event_type; - event->object = object; - event->owner = owner; + if ((event = kmalloc(sizeof(struct serio_event), GFP_ATOMIC))) { + if (!try_module_get(owner)) { + printk(KERN_WARNING "serio: Can't get module reference, dropping event %d\n", event_type); + kfree(event); + goto out; + } - list_add_tail(&event->node, &serio_event_list); - wake_up(&serio_wait); + event->type = event_type; + event->object = object; + event->owner = owner; + list_add_tail(&event->node, &serio_event_list); + wake_up(&serio_wait); + } else { + printk(KERN_ERR "serio: Not enough memory to queue event %d\n", event_type); + } out: spin_unlock_irqrestore(&serio_event_lock, flags); - return retval; } static void serio_free_event(struct serio_event *event) @@ -316,17 +308,22 @@ static void serio_handle_event(void) serio_add_port(event->object); break; - case SERIO_RECONNECT_PORT: + case SERIO_UNREGISTER_PORT: + serio_disconnect_port(event->object); + serio_destroy_port(event->object); + break; + + case SERIO_RECONNECT: serio_reconnect_port(event->object); break; - case SERIO_RESCAN_PORT: + case SERIO_RESCAN: serio_disconnect_port(event->object); serio_find_driver(event->object); break; - case SERIO_ATTACH_DRIVER: - serio_attach_driver(event->object); + case SERIO_REGISTER_DRIVER: + serio_add_driver(event->object); break; default: @@ -678,12 +675,12 @@ static void serio_disconnect_port(struct serio *serio) void serio_rescan(struct serio *serio) { - serio_queue_event(serio, NULL, SERIO_RESCAN_PORT); + serio_queue_event(serio, NULL, SERIO_RESCAN); } void serio_reconnect(struct serio *serio) { - serio_queue_event(serio, NULL, SERIO_RECONNECT_PORT); + serio_queue_event(serio, NULL, SERIO_RECONNECT); } /* @@ -720,6 +717,16 @@ void serio_unregister_child_port(struct serio *serio) mutex_unlock(&serio_mutex); } +/* + * Submits register request to kseriod for subsequent execution. + * Can be used when it is not obvious whether the serio_mutex is + * taken or not and when delayed execution is feasible. + */ +void __serio_unregister_port_delayed(struct serio *serio, struct module *owner) +{ + serio_queue_event(serio, owner, SERIO_UNREGISTER_PORT); +} + /* * Serio driver operations @@ -778,52 +785,28 @@ static int serio_driver_remove(struct device *dev) return 0; } -static void serio_attach_driver(struct serio_driver *drv) -{ - int error; - - error = driver_attach(&drv->driver); - if (error) - printk(KERN_WARNING - "serio: driver_attach() failed for %s with error %d\n", - drv->driver.name, error); -} +static struct bus_type serio_bus = { + .name = "serio", + .probe = serio_driver_probe, + .remove = serio_driver_remove, +}; -int serio_register_driver(struct serio_driver *drv) +static void serio_add_driver(struct serio_driver *drv) { - int manual_bind = drv->manual_bind; int error; - drv->driver.bus = &serio_bus; - - /* - * Temporarily disable automatic binding because probing - * takes long time and we are better off doing it in kseriod - */ - drv->manual_bind = 1; - error = driver_register(&drv->driver); - if (error) { + if (error) printk(KERN_ERR "serio: driver_register() failed for %s, error: %d\n", drv->driver.name, error); - return error; - } +} - /* - * Restore original bind mode and let kseriod bind the - * driver to free ports - */ - if (!manual_bind) { - drv->manual_bind = 0; - error = serio_queue_event(drv, NULL, SERIO_ATTACH_DRIVER); - if (error) { - driver_unregister(&drv->driver); - return error; - } - } +void __serio_register_driver(struct serio_driver *drv, struct module *owner) +{ + drv->driver.bus = &serio_bus; - return 0; + serio_queue_event(drv, owner, SERIO_REGISTER_DRIVER); } void serio_unregister_driver(struct serio_driver *drv) @@ -964,21 +947,15 @@ irqreturn_t serio_interrupt(struct serio *serio, return ret; } -static struct bus_type serio_bus = { - .name = "serio", - .dev_attrs = serio_device_attrs, - .drv_attrs = serio_driver_attrs, - .match = serio_bus_match, - .uevent = serio_uevent, - .probe = serio_driver_probe, - .remove = serio_driver_remove, - .resume = serio_resume, -}; - static int __init serio_init(void) { int error; + serio_bus.dev_attrs = serio_device_attrs; + serio_bus.drv_attrs = serio_driver_attrs; + serio_bus.match = serio_bus_match; + serio_bus.uevent = serio_uevent; + serio_bus.resume = serio_resume; error = bus_register(&serio_bus); if (error) { printk(KERN_ERR "serio: failed to register serio bus, error: %d\n", error); diff --git a/trunk/drivers/input/serio/serio_raw.c b/trunk/drivers/input/serio/serio_raw.c index 088ebc348ba3..7c8d0399ae82 100644 --- a/trunk/drivers/input/serio/serio_raw.c +++ b/trunk/drivers/input/serio/serio_raw.c @@ -389,7 +389,8 @@ static struct serio_driver serio_raw_drv = { static int __init serio_raw_init(void) { - return serio_register_driver(&serio_raw_drv); + serio_register_driver(&serio_raw_drv); + return 0; } static void __exit serio_raw_exit(void) diff --git a/trunk/drivers/input/touchscreen/Kconfig b/trunk/drivers/input/touchscreen/Kconfig index 29ca0ab0acb8..9418bbe47072 100644 --- a/trunk/drivers/input/touchscreen/Kconfig +++ b/trunk/drivers/input/touchscreen/Kconfig @@ -144,19 +144,4 @@ config TOUCHSCREEN_TOUCHWIN To compile this driver as a module, choose M here: the module will be called touchwin. -config TOUCHSCREEN_UCB1400 - tristate "Philips UCB1400 touchscreen" - select SND_AC97_BUS - help - This enables support for the Philips UCB1400 touchscreen interface. - The UCB1400 is an AC97 audio codec. The touchscreen interface - will be initialized only after the ALSA subsystem has been - brought up and the UCB1400 detected. You therefore have to - configure ALSA support as well (either built-in or modular, - independently of whether this driver is itself built-in or - modular) for this driver to work. - - To compile this driver as a module, choose M here: the - module will be called ucb1400_ts. - endif diff --git a/trunk/drivers/input/touchscreen/Makefile b/trunk/drivers/input/touchscreen/Makefile index 30e6e2217a15..1abb8f10d608 100644 --- a/trunk/drivers/input/touchscreen/Makefile +++ b/trunk/drivers/input/touchscreen/Makefile @@ -15,4 +15,3 @@ obj-$(CONFIG_TOUCHSCREEN_HP600) += hp680_ts_input.o obj-$(CONFIG_TOUCHSCREEN_PENMOUNT) += penmount.o obj-$(CONFIG_TOUCHSCREEN_TOUCHRIGHT) += touchright.o obj-$(CONFIG_TOUCHSCREEN_TOUCHWIN) += touchwin.o -obj-$(CONFIG_TOUCHSCREEN_UCB1400) += ucb1400_ts.o diff --git a/trunk/drivers/input/touchscreen/ads7846.c b/trunk/drivers/input/touchscreen/ads7846.c index c6164b6f476a..0517c7387d67 100644 --- a/trunk/drivers/input/touchscreen/ads7846.c +++ b/trunk/drivers/input/touchscreen/ads7846.c @@ -76,7 +76,6 @@ struct ads7846 { char phys[32]; struct spi_device *spi; - struct attribute_group *attr_group; u16 model; u16 vref_delay_usecs; u16 x_plate_ohms; @@ -318,48 +317,6 @@ static ssize_t ads7846_disable_store(struct device *dev, static DEVICE_ATTR(disable, 0664, ads7846_disable_show, ads7846_disable_store); -static struct attribute *ads7846_attributes[] = { - &dev_attr_temp0.attr, - &dev_attr_temp1.attr, - &dev_attr_vbatt.attr, - &dev_attr_vaux.attr, - &dev_attr_pen_down.attr, - &dev_attr_disable.attr, - NULL, -}; - -static struct attribute_group ads7846_attr_group = { - .attrs = ads7846_attributes, -}; - -/* - * ads7843/7845 don't have temperature sensors, and - * use the other sensors a bit differently too - */ - -static struct attribute *ads7843_attributes[] = { - &dev_attr_vbatt.attr, - &dev_attr_vaux.attr, - &dev_attr_pen_down.attr, - &dev_attr_disable.attr, - NULL, -}; - -static struct attribute_group ads7843_attr_group = { - .attrs = ads7843_attributes, -}; - -static struct attribute *ads7845_attributes[] = { - &dev_attr_vaux.attr, - &dev_attr_pen_down.attr, - &dev_attr_disable.attr, - NULL, -}; - -static struct attribute_group ads7845_attr_group = { - .attrs = ads7845_attributes, -}; - /*--------------------------------------------------------------------------*/ /* @@ -831,30 +788,38 @@ static int __devinit ads7846_probe(struct spi_device *spi) (void) ads7846_read12_ser(&spi->dev, READ_12BIT_SER(vaux) | ADS_PD10_ALL_ON); - switch (ts->model) { - case 7846: - ts->attr_group = &ads7846_attr_group; - break; - case 7845: - ts->attr_group = &ads7845_attr_group; - break; - default: - ts->attr_group = &ads7843_attr_group; - break; + /* ads7843/7845 don't have temperature sensors, and + * use the other sensors a bit differently too + */ + if (ts->model == 7846) { + device_create_file(&spi->dev, &dev_attr_temp0); + device_create_file(&spi->dev, &dev_attr_temp1); } - err = sysfs_create_group(&spi->dev.kobj, ts->attr_group); - if (err) - goto err_free_irq; + if (ts->model != 7845) + device_create_file(&spi->dev, &dev_attr_vbatt); + device_create_file(&spi->dev, &dev_attr_vaux); + + device_create_file(&spi->dev, &dev_attr_pen_down); + + device_create_file(&spi->dev, &dev_attr_disable); err = input_register_device(input_dev); if (err) - goto err_remove_attr_group; + goto err_remove_attr; return 0; - err_remove_attr_group: - sysfs_remove_group(&spi->dev.kobj, ts->attr_group); - err_free_irq: + err_remove_attr: + device_remove_file(&spi->dev, &dev_attr_disable); + device_remove_file(&spi->dev, &dev_attr_pen_down); + if (ts->model == 7846) { + device_remove_file(&spi->dev, &dev_attr_temp1); + device_remove_file(&spi->dev, &dev_attr_temp0); + } + if (ts->model != 7845) + device_remove_file(&spi->dev, &dev_attr_vbatt); + device_remove_file(&spi->dev, &dev_attr_vaux); + free_irq(spi->irq, ts); err_free_mem: input_free_device(input_dev); @@ -870,7 +835,15 @@ static int __devexit ads7846_remove(struct spi_device *spi) ads7846_suspend(spi, PMSG_SUSPEND); - sysfs_remove_group(&spi->dev.kobj, ts->attr_group); + device_remove_file(&spi->dev, &dev_attr_disable); + device_remove_file(&spi->dev, &dev_attr_pen_down); + if (ts->model == 7846) { + device_remove_file(&spi->dev, &dev_attr_temp1); + device_remove_file(&spi->dev, &dev_attr_temp0); + } + if (ts->model != 7845) + device_remove_file(&spi->dev, &dev_attr_vbatt); + device_remove_file(&spi->dev, &dev_attr_vaux); free_irq(ts->spi->irq, ts); /* suspend left the IRQ disabled */ diff --git a/trunk/drivers/input/touchscreen/corgi_ts.c b/trunk/drivers/input/touchscreen/corgi_ts.c index e2945582828e..66121f6a89ad 100644 --- a/trunk/drivers/input/touchscreen/corgi_ts.c +++ b/trunk/drivers/input/touchscreen/corgi_ts.c @@ -175,19 +175,17 @@ static int read_xydata(struct corgi_ts *corgi_ts) static void new_data(struct corgi_ts *corgi_ts) { - struct input_dev *dev = corgi_ts->input; - if (corgi_ts->power_mode != PWR_MODE_ACTIVE) return; if (!corgi_ts->tc.pressure && corgi_ts->pendown == 0) return; - input_report_abs(dev, ABS_X, corgi_ts->tc.x); - input_report_abs(dev, ABS_Y, corgi_ts->tc.y); - input_report_abs(dev, ABS_PRESSURE, corgi_ts->tc.pressure); - input_report_key(dev, BTN_TOUCH, corgi_ts->pendown); - input_sync(dev); + input_report_abs(corgi_ts->input, ABS_X, corgi_ts->tc.x); + input_report_abs(corgi_ts->input, ABS_Y, corgi_ts->tc.y); + input_report_abs(corgi_ts->input, ABS_PRESSURE, corgi_ts->tc.pressure); + input_report_key(corgi_ts->input, BTN_TOUCH, (corgi_ts->pendown != 0)); + input_sync(corgi_ts->input); } static void ts_interrupt_main(struct corgi_ts *corgi_ts, int isTimer) @@ -221,14 +219,12 @@ static void ts_interrupt_main(struct corgi_ts *corgi_ts, int isTimer) static void corgi_ts_timer(unsigned long data) { struct corgi_ts *corgits_data = (struct corgi_ts *) data; - ts_interrupt_main(corgits_data, 1); } static irqreturn_t ts_interrupt(int irq, void *dev_id) { struct corgi_ts *corgits_data = dev_id; - ts_interrupt_main(corgits_data, 0); return IRQ_HANDLED; } @@ -276,7 +272,7 @@ static int __init corgits_probe(struct platform_device *pdev) corgi_ts = kzalloc(sizeof(struct corgi_ts), GFP_KERNEL); input_dev = input_allocate_device(); if (!corgi_ts || !input_dev) - goto fail1; + goto fail; platform_set_drvdata(pdev, corgi_ts); @@ -285,7 +281,7 @@ static int __init corgits_probe(struct platform_device *pdev) if (corgi_ts->irq_gpio < 0) { err = -ENODEV; - goto fail1; + goto fail; } corgi_ts->input = input_dev; @@ -323,12 +319,10 @@ static int __init corgits_probe(struct platform_device *pdev) if (request_irq(corgi_ts->irq_gpio, ts_interrupt, IRQF_DISABLED, "ts", corgi_ts)) { err = -EBUSY; - goto fail1; + goto fail; } - err = input_register_device(corgi_ts->input); - if (err) - goto fail2; + input_register_device(corgi_ts->input); corgi_ts->power_mode = PWR_MODE_ACTIVE; @@ -337,17 +331,17 @@ static int __init corgits_probe(struct platform_device *pdev) return 0; - fail2: free_irq(corgi_ts->irq_gpio, corgi_ts); - fail1: input_free_device(input_dev); + fail: input_free_device(input_dev); kfree(corgi_ts); return err; + } static int corgits_remove(struct platform_device *pdev) { struct corgi_ts *corgi_ts = platform_get_drvdata(pdev); - free_irq(corgi_ts->irq_gpio, corgi_ts); + free_irq(corgi_ts->irq_gpio, NULL); del_timer_sync(&corgi_ts->timer); corgi_ts->machinfo->put_hsync(); input_unregister_device(corgi_ts->input); diff --git a/trunk/drivers/input/touchscreen/elo.c b/trunk/drivers/input/touchscreen/elo.c index 9d61cd133d01..913e1b73bb0e 100644 --- a/trunk/drivers/input/touchscreen/elo.c +++ b/trunk/drivers/input/touchscreen/elo.c @@ -397,7 +397,8 @@ static struct serio_driver elo_drv = { static int __init elo_init(void) { - return serio_register_driver(&elo_drv); + serio_register_driver(&elo_drv); + return 0; } static void __exit elo_exit(void) diff --git a/trunk/drivers/input/touchscreen/gunze.c b/trunk/drivers/input/touchscreen/gunze.c index 9157eb148e84..817c2198933d 100644 --- a/trunk/drivers/input/touchscreen/gunze.c +++ b/trunk/drivers/input/touchscreen/gunze.c @@ -123,7 +123,7 @@ static int gunze_connect(struct serio *serio, struct serio_driver *drv) input_dev = input_allocate_device(); if (!gunze || !input_dev) { err = -ENOMEM; - goto fail1; + goto fail; } gunze->serio = serio; @@ -146,17 +146,13 @@ static int gunze_connect(struct serio *serio, struct serio_driver *drv) err = serio_open(serio, drv); if (err) - goto fail2; - - err = input_register_device(gunze->dev); - if (err) - goto fail3; + goto fail; + input_register_device(gunze->dev); return 0; - fail3: serio_close(serio); - fail2: serio_set_drvdata(serio, NULL); - fail1: input_free_device(input_dev); + fail: serio_set_drvdata(serio, NULL); + input_free_device(input_dev); kfree(gunze); return err; } @@ -194,7 +190,8 @@ static struct serio_driver gunze_drv = { static int __init gunze_init(void) { - return serio_register_driver(&gunze_drv); + serio_register_driver(&gunze_drv); + return 0; } static void __exit gunze_exit(void) diff --git a/trunk/drivers/input/touchscreen/h3600_ts_input.c b/trunk/drivers/input/touchscreen/h3600_ts_input.c index c4116d4f64e7..d9e61ee05ea9 100644 --- a/trunk/drivers/input/touchscreen/h3600_ts_input.c +++ b/trunk/drivers/input/touchscreen/h3600_ts_input.c @@ -478,7 +478,8 @@ static struct serio_driver h3600ts_drv = { static int __init h3600ts_init(void) { - return serio_register_driver(&h3600ts_drv); + serio_register_driver(&h3600ts_drv); + return 0; } static void __exit h3600ts_exit(void) diff --git a/trunk/drivers/input/touchscreen/hp680_ts_input.c b/trunk/drivers/input/touchscreen/hp680_ts_input.c index 249087472740..58fca316786c 100644 --- a/trunk/drivers/input/touchscreen/hp680_ts_input.c +++ b/trunk/drivers/input/touchscreen/hp680_ts_input.c @@ -76,47 +76,38 @@ static irqreturn_t hp680_ts_interrupt(int irq, void *dev) static int __init hp680_ts_init(void) { - int err; - hp680_ts_dev = input_allocate_device(); if (!hp680_ts_dev) return -ENOMEM; hp680_ts_dev->evbit[0] = BIT(EV_ABS) | BIT(EV_KEY); + hp680_ts_dev->absbit[0] = BIT(ABS_X) | BIT(ABS_Y); hp680_ts_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); - input_set_abs_params(hp680_ts_dev, ABS_X, - HP680_TS_ABS_X_MIN, HP680_TS_ABS_X_MAX, 0, 0); - input_set_abs_params(hp680_ts_dev, ABS_Y, - HP680_TS_ABS_Y_MIN, HP680_TS_ABS_Y_MAX, 0, 0); + hp680_ts_dev->absmin[ABS_X] = HP680_TS_ABS_X_MIN; + hp680_ts_dev->absmin[ABS_Y] = HP680_TS_ABS_Y_MIN; + hp680_ts_dev->absmax[ABS_X] = HP680_TS_ABS_X_MAX; + hp680_ts_dev->absmax[ABS_Y] = HP680_TS_ABS_Y_MAX; hp680_ts_dev->name = "HP Jornada touchscreen"; hp680_ts_dev->phys = "hp680_ts/input0"; + input_register_device(hp680_ts_dev); + if (request_irq(HP680_TS_IRQ, hp680_ts_interrupt, IRQF_DISABLED, MODNAME, 0) < 0) { printk(KERN_ERR "hp680_touchscreen.c: Can't allocate irq %d\n", HP680_TS_IRQ); - err = -EBUSY; - goto fail1; + input_unregister_device(hp680_ts_dev); + return -EBUSY; } - err = input_register_device(hp680_ts_dev); - if (err) - goto fail2; - return 0; - - fail2: free_irq(HP680_TS_IRQ, NULL); - cancel_delayed_work(&work); - flush_scheduled_work(); - fail1: input_free_device(hp680_ts_dev); - return err; } static void __exit hp680_ts_exit(void) { - free_irq(HP680_TS_IRQ, NULL); + free_irq(HP680_TS_IRQ, 0); cancel_delayed_work(&work); flush_scheduled_work(); input_unregister_device(hp680_ts_dev); diff --git a/trunk/drivers/input/touchscreen/mk712.c b/trunk/drivers/input/touchscreen/mk712.c index 44140feeffc5..4cbcaa6a71e5 100644 --- a/trunk/drivers/input/touchscreen/mk712.c +++ b/trunk/drivers/input/touchscreen/mk712.c @@ -96,13 +96,15 @@ static irqreturn_t mk712_interrupt(int irq, void *dev_id) goto end; } - if (~status & MK712_STATUS_TOUCH) { + if (~status & MK712_STATUS_TOUCH) + { debounce = 1; input_report_key(mk712_dev, BTN_TOUCH, 0); goto end; } - if (debounce) { + if (debounce) + { debounce = 0; goto end; } @@ -111,7 +113,8 @@ static irqreturn_t mk712_interrupt(int irq, void *dev_id) input_report_abs(mk712_dev, ABS_X, last_x); input_report_abs(mk712_dev, ABS_Y, last_y); - end: +end: + last_x = inw(mk712_io + MK712_X) & 0x0fff; last_y = inw(mk712_io + MK712_Y) & 0x0fff; input_sync(mk712_dev); @@ -166,14 +169,13 @@ static int __init mk712_init(void) (inw(mk712_io + MK712_STATUS) & 0xf333)) { printk(KERN_WARNING "mk712: device not present\n"); err = -ENODEV; - goto fail1; + goto fail; } - mk712_dev = input_allocate_device(); - if (!mk712_dev) { + if (!(mk712_dev = input_allocate_device())) { printk(KERN_ERR "mk712: not enough memory\n"); err = -ENOMEM; - goto fail1; + goto fail; } mk712_dev->name = "ICS MicroClock MK712 TouchScreen"; @@ -194,17 +196,13 @@ static int __init mk712_init(void) if (request_irq(mk712_irq, mk712_interrupt, 0, "mk712", mk712_dev)) { printk(KERN_WARNING "mk712: unable to get IRQ\n"); err = -EBUSY; - goto fail1; + goto fail; } - err = input_register_device(mk712_dev); - if (err) - goto fail2; - + input_register_device(mk712_dev); return 0; - fail2: free_irq(mk712_irq, mk712_dev); - fail1: input_free_device(mk712_dev); + fail: input_free_device(mk712_dev); release_region(mk712_io, 8); return err; } diff --git a/trunk/drivers/input/touchscreen/mtouch.c b/trunk/drivers/input/touchscreen/mtouch.c index c3c2d735d0ec..3b4c61664b63 100644 --- a/trunk/drivers/input/touchscreen/mtouch.c +++ b/trunk/drivers/input/touchscreen/mtouch.c @@ -137,7 +137,7 @@ static int mtouch_connect(struct serio *serio, struct serio_driver *drv) input_dev = input_allocate_device(); if (!mtouch || !input_dev) { err = -ENOMEM; - goto fail1; + goto fail; } mtouch->serio = serio; @@ -160,17 +160,14 @@ static int mtouch_connect(struct serio *serio, struct serio_driver *drv) err = serio_open(serio, drv); if (err) - goto fail2; + goto fail; - err = input_register_device(mtouch->dev); - if (err) - goto fail3; + input_register_device(mtouch->dev); return 0; - fail3: serio_close(serio); - fail2: serio_set_drvdata(serio, NULL); - fail1: input_free_device(input_dev); + fail: serio_set_drvdata(serio, NULL); + input_free_device(input_dev); kfree(mtouch); return err; } @@ -208,7 +205,8 @@ static struct serio_driver mtouch_drv = { static int __init mtouch_init(void) { - return serio_register_driver(&mtouch_drv); + serio_register_driver(&mtouch_drv); + return 0; } static void __exit mtouch_exit(void) diff --git a/trunk/drivers/input/touchscreen/penmount.c b/trunk/drivers/input/touchscreen/penmount.c index bd2767991ae9..6c7d0c2c76cc 100644 --- a/trunk/drivers/input/touchscreen/penmount.c +++ b/trunk/drivers/input/touchscreen/penmount.c @@ -171,7 +171,8 @@ static struct serio_driver pm_drv = { static int __init pm_init(void) { - return serio_register_driver(&pm_drv); + serio_register_driver(&pm_drv); + return 0; } static void __exit pm_exit(void) diff --git a/trunk/drivers/input/touchscreen/touchright.c b/trunk/drivers/input/touchscreen/touchright.c index 35ba46c6ad2d..c74f74e57af0 100644 --- a/trunk/drivers/input/touchscreen/touchright.c +++ b/trunk/drivers/input/touchscreen/touchright.c @@ -182,7 +182,8 @@ static struct serio_driver tr_drv = { static int __init tr_init(void) { - return serio_register_driver(&tr_drv); + serio_register_driver(&tr_drv); + return 0; } static void __exit tr_exit(void) diff --git a/trunk/drivers/input/touchscreen/touchwin.c b/trunk/drivers/input/touchscreen/touchwin.c index 4dc073dacabb..9911820fa2fe 100644 --- a/trunk/drivers/input/touchscreen/touchwin.c +++ b/trunk/drivers/input/touchscreen/touchwin.c @@ -189,7 +189,8 @@ static struct serio_driver tw_drv = { static int __init tw_init(void) { - return serio_register_driver(&tw_drv); + serio_register_driver(&tw_drv); + return 0; } static void __exit tw_exit(void) diff --git a/trunk/drivers/input/touchscreen/ucb1400_ts.c b/trunk/drivers/input/touchscreen/ucb1400_ts.c deleted file mode 100644 index 4358a0a78eaa..000000000000 --- a/trunk/drivers/input/touchscreen/ucb1400_ts.c +++ /dev/null @@ -1,579 +0,0 @@ -/* - * Philips UCB1400 touchscreen driver - * - * Author: Nicolas Pitre - * Created: September 25, 2006 - * Copyright: MontaVista Software, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This code is heavily based on ucb1x00-*.c copyrighted by Russell King - * covering the UCB1100, UCB1200 and UCB1300.. Support for the UCB1400 has - * been made separate from ucb1x00-core/ucb1x00-ts on Russell's request. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - - -/* - * Interesting UCB1400 AC-link registers - */ - -#define UCB_IE_RIS 0x5e -#define UCB_IE_FAL 0x60 -#define UCB_IE_STATUS 0x62 -#define UCB_IE_CLEAR 0x62 -#define UCB_IE_ADC (1 << 11) -#define UCB_IE_TSPX (1 << 12) - -#define UCB_TS_CR 0x64 -#define UCB_TS_CR_TSMX_POW (1 << 0) -#define UCB_TS_CR_TSPX_POW (1 << 1) -#define UCB_TS_CR_TSMY_POW (1 << 2) -#define UCB_TS_CR_TSPY_POW (1 << 3) -#define UCB_TS_CR_TSMX_GND (1 << 4) -#define UCB_TS_CR_TSPX_GND (1 << 5) -#define UCB_TS_CR_TSMY_GND (1 << 6) -#define UCB_TS_CR_TSPY_GND (1 << 7) -#define UCB_TS_CR_MODE_INT (0 << 8) -#define UCB_TS_CR_MODE_PRES (1 << 8) -#define UCB_TS_CR_MODE_POS (2 << 8) -#define UCB_TS_CR_BIAS_ENA (1 << 11) -#define UCB_TS_CR_TSPX_LOW (1 << 12) -#define UCB_TS_CR_TSMX_LOW (1 << 13) - -#define UCB_ADC_CR 0x66 -#define UCB_ADC_SYNC_ENA (1 << 0) -#define UCB_ADC_VREFBYP_CON (1 << 1) -#define UCB_ADC_INP_TSPX (0 << 2) -#define UCB_ADC_INP_TSMX (1 << 2) -#define UCB_ADC_INP_TSPY (2 << 2) -#define UCB_ADC_INP_TSMY (3 << 2) -#define UCB_ADC_INP_AD0 (4 << 2) -#define UCB_ADC_INP_AD1 (5 << 2) -#define UCB_ADC_INP_AD2 (6 << 2) -#define UCB_ADC_INP_AD3 (7 << 2) -#define UCB_ADC_EXT_REF (1 << 5) -#define UCB_ADC_START (1 << 7) -#define UCB_ADC_ENA (1 << 15) - -#define UCB_ADC_DATA 0x68 -#define UCB_ADC_DAT_VALID (1 << 15) -#define UCB_ADC_DAT_VALUE(x) ((x) & 0x3ff) - -#define UCB_ID 0x7e -#define UCB_ID_1400 0x4304 - - -struct ucb1400 { - ac97_t *ac97; - struct input_dev *ts_idev; - - int irq; - - wait_queue_head_t ts_wait; - struct task_struct *ts_task; - - unsigned int irq_pending; /* not bit field shared */ - unsigned int ts_restart:1; - unsigned int adcsync:1; -}; - -static int adcsync; - -static inline u16 ucb1400_reg_read(struct ucb1400 *ucb, u16 reg) -{ - return ucb->ac97->bus->ops->read(ucb->ac97, reg); -} - -static inline void ucb1400_reg_write(struct ucb1400 *ucb, u16 reg, u16 val) -{ - ucb->ac97->bus->ops->write(ucb->ac97, reg, val); -} - -static inline void ucb1400_adc_enable(struct ucb1400 *ucb) -{ - ucb1400_reg_write(ucb, UCB_ADC_CR, UCB_ADC_ENA); -} - -static unsigned int ucb1400_adc_read(struct ucb1400 *ucb, u16 adc_channel) -{ - unsigned int val; - - if (ucb->adcsync) - adc_channel |= UCB_ADC_SYNC_ENA; - - ucb1400_reg_write(ucb, UCB_ADC_CR, UCB_ADC_ENA | adc_channel); - ucb1400_reg_write(ucb, UCB_ADC_CR, UCB_ADC_ENA | adc_channel | UCB_ADC_START); - - for (;;) { - val = ucb1400_reg_read(ucb, UCB_ADC_DATA); - if (val & UCB_ADC_DAT_VALID) - break; - /* yield to other processes */ - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(1); - } - - return UCB_ADC_DAT_VALUE(val); -} - -static inline void ucb1400_adc_disable(struct ucb1400 *ucb) -{ - ucb1400_reg_write(ucb, UCB_ADC_CR, 0); -} - -/* Switch to interrupt mode. */ -static inline void ucb1400_ts_mode_int(struct ucb1400 *ucb) -{ - ucb1400_reg_write(ucb, UCB_TS_CR, - UCB_TS_CR_TSMX_POW | UCB_TS_CR_TSPX_POW | - UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_GND | - UCB_TS_CR_MODE_INT); -} - -/* - * Switch to pressure mode, and read pressure. We don't need to wait - * here, since both plates are being driven. - */ -static inline unsigned int ucb1400_ts_read_pressure(struct ucb1400 *ucb) -{ - ucb1400_reg_write(ucb, UCB_TS_CR, - UCB_TS_CR_TSMX_POW | UCB_TS_CR_TSPX_POW | - UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_GND | - UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA); - return ucb1400_adc_read(ucb, UCB_ADC_INP_TSPY); -} - -/* - * Switch to X position mode and measure Y plate. We switch the plate - * configuration in pressure mode, then switch to position mode. This - * gives a faster response time. Even so, we need to wait about 55us - * for things to stabilise. - */ -static inline unsigned int ucb1400_ts_read_xpos(struct ucb1400 *ucb) -{ - ucb1400_reg_write(ucb, UCB_TS_CR, - UCB_TS_CR_TSMX_GND | UCB_TS_CR_TSPX_POW | - UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA); - ucb1400_reg_write(ucb, UCB_TS_CR, - UCB_TS_CR_TSMX_GND | UCB_TS_CR_TSPX_POW | - UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA); - ucb1400_reg_write(ucb, UCB_TS_CR, - UCB_TS_CR_TSMX_GND | UCB_TS_CR_TSPX_POW | - UCB_TS_CR_MODE_POS | UCB_TS_CR_BIAS_ENA); - - udelay(55); - - return ucb1400_adc_read(ucb, UCB_ADC_INP_TSPY); -} - -/* - * Switch to Y position mode and measure X plate. We switch the plate - * configuration in pressure mode, then switch to position mode. This - * gives a faster response time. Even so, we need to wait about 55us - * for things to stabilise. - */ -static inline unsigned int ucb1400_ts_read_ypos(struct ucb1400 *ucb) -{ - ucb1400_reg_write(ucb, UCB_TS_CR, - UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_POW | - UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA); - ucb1400_reg_write(ucb, UCB_TS_CR, - UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_POW | - UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA); - ucb1400_reg_write(ucb, UCB_TS_CR, - UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_POW | - UCB_TS_CR_MODE_POS | UCB_TS_CR_BIAS_ENA); - - udelay(55); - - return ucb1400_adc_read(ucb, UCB_ADC_INP_TSPX); -} - -/* - * Switch to X plate resistance mode. Set MX to ground, PX to - * supply. Measure current. - */ -static inline unsigned int ucb1400_ts_read_xres(struct ucb1400 *ucb) -{ - ucb1400_reg_write(ucb, UCB_TS_CR, - UCB_TS_CR_TSMX_GND | UCB_TS_CR_TSPX_POW | - UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA); - return ucb1400_adc_read(ucb, 0); -} - -/* - * Switch to Y plate resistance mode. Set MY to ground, PY to - * supply. Measure current. - */ -static inline unsigned int ucb1400_ts_read_yres(struct ucb1400 *ucb) -{ - ucb1400_reg_write(ucb, UCB_TS_CR, - UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_POW | - UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA); - return ucb1400_adc_read(ucb, 0); -} - -static inline int ucb1400_ts_pen_down(struct ucb1400 *ucb) -{ - unsigned short val = ucb1400_reg_read(ucb, UCB_TS_CR); - return (val & (UCB_TS_CR_TSPX_LOW | UCB_TS_CR_TSMX_LOW)); -} - -static inline void ucb1400_ts_irq_enable(struct ucb1400 *ucb) -{ - ucb1400_reg_write(ucb, UCB_IE_CLEAR, UCB_IE_TSPX); - ucb1400_reg_write(ucb, UCB_IE_CLEAR, 0); - ucb1400_reg_write(ucb, UCB_IE_FAL, UCB_IE_TSPX); -} - -static inline void ucb1400_ts_irq_disable(struct ucb1400 *ucb) -{ - ucb1400_reg_write(ucb, UCB_IE_FAL, 0); -} - -static void ucb1400_ts_evt_add(struct input_dev *idev, u16 pressure, u16 x, u16 y) -{ - input_report_abs(idev, ABS_X, x); - input_report_abs(idev, ABS_Y, y); - input_report_abs(idev, ABS_PRESSURE, pressure); - input_sync(idev); -} - -static void ucb1400_ts_event_release(struct input_dev *idev) -{ - input_report_abs(idev, ABS_PRESSURE, 0); - input_sync(idev); -} - -static void ucb1400_handle_pending_irq(struct ucb1400 *ucb) -{ - unsigned int isr; - - isr = ucb1400_reg_read(ucb, UCB_IE_STATUS); - ucb1400_reg_write(ucb, UCB_IE_CLEAR, isr); - ucb1400_reg_write(ucb, UCB_IE_CLEAR, 0); - - if (isr & UCB_IE_TSPX) - ucb1400_ts_irq_disable(ucb); - else - printk(KERN_ERR "ucb1400: unexpected IE_STATUS = %#x\n", isr); - - enable_irq(ucb->irq); -} - -static int ucb1400_ts_thread(void *_ucb) -{ - struct ucb1400 *ucb = _ucb; - struct task_struct *tsk = current; - int valid = 0; - - tsk->policy = SCHED_FIFO; - tsk->rt_priority = 1; - - while (!kthread_should_stop()) { - unsigned int x, y, p; - long timeout; - - ucb->ts_restart = 0; - - if (ucb->irq_pending) { - ucb->irq_pending = 0; - ucb1400_handle_pending_irq(ucb); - } - - ucb1400_adc_enable(ucb); - x = ucb1400_ts_read_xpos(ucb); - y = ucb1400_ts_read_ypos(ucb); - p = ucb1400_ts_read_pressure(ucb); - ucb1400_adc_disable(ucb); - - /* Switch back to interrupt mode. */ - ucb1400_ts_mode_int(ucb); - - msleep(10); - - if (ucb1400_ts_pen_down(ucb)) { - ucb1400_ts_irq_enable(ucb); - - /* - * If we spat out a valid sample set last time, - * spit out a "pen off" sample here. - */ - if (valid) { - ucb1400_ts_event_release(ucb->ts_idev); - valid = 0; - } - - timeout = MAX_SCHEDULE_TIMEOUT; - } else { - valid = 1; - ucb1400_ts_evt_add(ucb->ts_idev, p, x, y); - timeout = msecs_to_jiffies(10); - } - - wait_event_interruptible_timeout(ucb->ts_wait, - ucb->irq_pending || ucb->ts_restart || kthread_should_stop(), - timeout); - try_to_freeze(); - } - - /* Send the "pen off" if we are stopping with the pen still active */ - if (valid) - ucb1400_ts_event_release(ucb->ts_idev); - - ucb->ts_task = NULL; - return 0; -} - -/* - * A restriction with interrupts exists when using the ucb1400, as - * the codec read/write routines may sleep while waiting for codec - * access completion and uses semaphores for access control to the - * AC97 bus. A complete codec read cycle could take anywhere from - * 60 to 100uSec so we *definitely* don't want to spin inside the - * interrupt handler waiting for codec access. So, we handle the - * interrupt by scheduling a RT kernel thread to run in process - * context instead of interrupt context. - */ -static irqreturn_t ucb1400_hard_irq(int irqnr, void *devid) -{ - struct ucb1400 *ucb = devid; - - if (irqnr == ucb->irq) { - disable_irq(ucb->irq); - ucb->irq_pending = 1; - wake_up(&ucb->ts_wait); - return IRQ_HANDLED; - } - return IRQ_NONE; -} - -static int ucb1400_ts_open(struct input_dev *idev) -{ - struct ucb1400 *ucb = idev->private; - int ret = 0; - - BUG_ON(ucb->ts_task); - - ucb->ts_task = kthread_run(ucb1400_ts_thread, ucb, "UCB1400_ts"); - if (IS_ERR(ucb->ts_task)) { - ret = PTR_ERR(ucb->ts_task); - ucb->ts_task = NULL; - } - - return ret; -} - -static void ucb1400_ts_close(struct input_dev *idev) -{ - struct ucb1400 *ucb = idev->private; - - if (ucb->ts_task) - kthread_stop(ucb->ts_task); - - ucb1400_ts_irq_disable(ucb); - ucb1400_reg_write(ucb, UCB_TS_CR, 0); -} - -#ifdef CONFIG_PM -static int ucb1400_ts_resume(struct device *dev) -{ - struct ucb1400 *ucb = dev_get_drvdata(dev); - - if (ucb->ts_task) { - /* - * Restart the TS thread to ensure the - * TS interrupt mode is set up again - * after sleep. - */ - ucb->ts_restart = 1; - wake_up(&ucb->ts_wait); - } - return 0; -} -#else -#define ucb1400_ts_resume NULL -#endif - -#ifndef NO_IRQ -#define NO_IRQ 0 -#endif - -/* - * Try to probe our interrupt, rather than relying on lots of - * hard-coded machine dependencies. - */ -static int ucb1400_detect_irq(struct ucb1400 *ucb) -{ - unsigned long mask, timeout; - - mask = probe_irq_on(); - if (!mask) { - probe_irq_off(mask); - return -EBUSY; - } - - /* Enable the ADC interrupt. */ - ucb1400_reg_write(ucb, UCB_IE_RIS, UCB_IE_ADC); - ucb1400_reg_write(ucb, UCB_IE_FAL, UCB_IE_ADC); - ucb1400_reg_write(ucb, UCB_IE_CLEAR, 0xffff); - ucb1400_reg_write(ucb, UCB_IE_CLEAR, 0); - - /* Cause an ADC interrupt. */ - ucb1400_reg_write(ucb, UCB_ADC_CR, UCB_ADC_ENA); - ucb1400_reg_write(ucb, UCB_ADC_CR, UCB_ADC_ENA | UCB_ADC_START); - - /* Wait for the conversion to complete. */ - timeout = jiffies + HZ/2; - while (!(ucb1400_reg_read(ucb, UCB_ADC_DATA) & UCB_ADC_DAT_VALID)) { - cpu_relax(); - if (time_after(jiffies, timeout)) { - printk(KERN_ERR "ucb1400: timed out in IRQ probe\n"); - probe_irq_off(mask); - return -ENODEV; - } - } - ucb1400_reg_write(ucb, UCB_ADC_CR, 0); - - /* Disable and clear interrupt. */ - ucb1400_reg_write(ucb, UCB_IE_RIS, 0); - ucb1400_reg_write(ucb, UCB_IE_FAL, 0); - ucb1400_reg_write(ucb, UCB_IE_CLEAR, 0xffff); - ucb1400_reg_write(ucb, UCB_IE_CLEAR, 0); - - /* Read triggered interrupt. */ - ucb->irq = probe_irq_off(mask); - if (ucb->irq < 0 || ucb->irq == NO_IRQ) - return -ENODEV; - - return 0; -} - -static int ucb1400_ts_probe(struct device *dev) -{ - struct ucb1400 *ucb; - struct input_dev *idev; - int error, id, x_res, y_res; - - ucb = kzalloc(sizeof(struct ucb1400), GFP_KERNEL); - idev = input_allocate_device(); - if (!ucb || !idev) { - error = -ENOMEM; - goto err_free_devs; - } - - ucb->ts_idev = idev; - ucb->adcsync = adcsync; - ucb->ac97 = to_ac97_t(dev); - init_waitqueue_head(&ucb->ts_wait); - - id = ucb1400_reg_read(ucb, UCB_ID); - if (id != UCB_ID_1400) { - error = -ENODEV; - goto err_free_devs; - } - - error = ucb1400_detect_irq(ucb); - if (error) { - printk(KERN_ERR "UCB1400: IRQ probe failed\n"); - goto err_free_devs; - } - - error = request_irq(ucb->irq, ucb1400_hard_irq, IRQF_TRIGGER_RISING, - "UCB1400", ucb); - if (error) { - printk(KERN_ERR "ucb1400: unable to grab irq%d: %d\n", - ucb->irq, error); - goto err_free_devs; - } - printk(KERN_DEBUG "UCB1400: found IRQ %d\n", ucb->irq); - - idev->private = ucb; - idev->cdev.dev = dev; - idev->name = "UCB1400 touchscreen interface"; - idev->id.vendor = ucb1400_reg_read(ucb, AC97_VENDOR_ID1); - idev->id.product = id; - idev->open = ucb1400_ts_open; - idev->close = ucb1400_ts_close; - idev->evbit[0] = BIT(EV_ABS); - - ucb1400_adc_enable(ucb); - x_res = ucb1400_ts_read_xres(ucb); - y_res = ucb1400_ts_read_yres(ucb); - ucb1400_adc_disable(ucb); - printk(KERN_DEBUG "UCB1400: x/y = %d/%d\n", x_res, y_res); - - input_set_abs_params(idev, ABS_X, 0, x_res, 0, 0); - input_set_abs_params(idev, ABS_Y, 0, y_res, 0, 0); - input_set_abs_params(idev, ABS_PRESSURE, 0, 0, 0, 0); - - error = input_register_device(idev); - if (error) - goto err_free_irq; - - dev_set_drvdata(dev, ucb); - return 0; - - err_free_irq: - free_irq(ucb->irq, ucb); - err_free_devs: - input_free_device(idev); - kfree(ucb); - return error; -} - -static int ucb1400_ts_remove(struct device *dev) -{ - struct ucb1400 *ucb = dev_get_drvdata(dev); - - free_irq(ucb->irq, ucb); - input_unregister_device(ucb->ts_idev); - dev_set_drvdata(dev, NULL); - kfree(ucb); - return 0; -} - -static struct device_driver ucb1400_ts_driver = { - .owner = THIS_MODULE, - .bus = &ac97_bus_type, - .probe = ucb1400_ts_probe, - .remove = ucb1400_ts_remove, - .resume = ucb1400_ts_resume, -}; - -static int __init ucb1400_ts_init(void) -{ - return driver_register(&ucb1400_ts_driver); -} - -static void __exit ucb1400_ts_exit(void) -{ - driver_unregister(&ucb1400_ts_driver); -} - -module_param(adcsync, int, 0444); - -module_init(ucb1400_ts_init); -module_exit(ucb1400_ts_exit); - -MODULE_DESCRIPTION("Philips UCB1400 touchscreen driver"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/isdn/act2000/module.c b/trunk/drivers/isdn/act2000/module.c index e3e5c1399076..90593e2ef872 100644 --- a/trunk/drivers/isdn/act2000/module.c +++ b/trunk/drivers/isdn/act2000/module.c @@ -573,11 +573,12 @@ act2000_alloccard(int bus, int port, int irq, char *id) { int i; act2000_card *card; - if (!(card = kzalloc(sizeof(act2000_card), GFP_KERNEL))) { + if (!(card = (act2000_card *) kmalloc(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/trunk/drivers/isdn/capi/capi.c b/trunk/drivers/isdn/capi/capi.c index d22c0224fde6..11844bbfe933 100644 --- a/trunk/drivers/isdn/capi/capi.c +++ b/trunk/drivers/isdn/capi/capi.c @@ -215,12 +215,13 @@ static struct capiminor *capiminor_alloc(struct capi20_appl *ap, u32 ncci) unsigned int minor = 0; unsigned long flags; - mp = kzalloc(sizeof(*mp), GFP_ATOMIC); + mp = kmalloc(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; @@ -303,9 +304,10 @@ static struct capincci *capincci_alloc(struct capidev *cdev, u32 ncci) struct capiminor *mp = NULL; #endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */ - np = kzalloc(sizeof(*np), GFP_ATOMIC); + np = kmalloc(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 @@ -382,9 +384,10 @@ static struct capidev *capidev_alloc(void) struct capidev *cdev; unsigned long flags; - cdev = kzalloc(sizeof(*cdev), GFP_KERNEL); + cdev = kmalloc(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); @@ -1007,7 +1010,7 @@ static int capinc_tty_open(struct tty_struct * tty, struct file * file) { struct capiminor *mp; - if ((mp = capiminor_find(iminor(file->f_path.dentry->d_inode))) == 0) + if ((mp = capiminor_find(iminor(file->f_dentry->d_inode))) == 0) return -ENXIO; if (mp->nccip == 0) return -ENXIO; @@ -1200,7 +1203,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 ktermios * old) +static void capinc_tty_set_termios(struct tty_struct *tty, struct termios * old) { #ifdef _DEBUG_TTYFUNCS printk(KERN_DEBUG "capinc_tty_set_termios\n"); diff --git a/trunk/drivers/isdn/capi/capidrv.c b/trunk/drivers/isdn/capi/capidrv.c index 097bfa7bc323..b6f9476c0501 100644 --- a/trunk/drivers/isdn/capi/capidrv.c +++ b/trunk/drivers/isdn/capi/capidrv.c @@ -334,11 +334,12 @@ static capidrv_plci *new_plci(capidrv_contr * card, int chan) { capidrv_plci *plcip; - plcip = kzalloc(sizeof(capidrv_plci), GFP_ATOMIC); + plcip = (capidrv_plci *) kmalloc(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; @@ -403,11 +404,12 @@ static inline capidrv_ncci *new_ncci(capidrv_contr * card, { capidrv_ncci *nccip; - nccip = kzalloc(sizeof(capidrv_ncci), GFP_ATOMIC); + nccip = (capidrv_ncci *) kmalloc(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; @@ -2003,11 +2005,12 @@ 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 = kzalloc(sizeof(capidrv_contr), GFP_ATOMIC))) { + if (!(card = (capidrv_contr *) kmalloc(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/trunk/drivers/isdn/gigaset/Kconfig b/trunk/drivers/isdn/gigaset/Kconfig index 708d47a6484b..5b203fe21dcd 100644 --- a/trunk/drivers/isdn/gigaset/Kconfig +++ b/trunk/drivers/isdn/gigaset/Kconfig @@ -5,7 +5,6 @@ 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/trunk/drivers/isdn/gigaset/asyncdata.c b/trunk/drivers/isdn/gigaset/asyncdata.c index 88e958f176d2..ce3cd77094b3 100644 --- a/trunk/drivers/isdn/gigaset/asyncdata.c +++ b/trunk/drivers/isdn/gigaset/asyncdata.c @@ -15,7 +15,6 @@ #include "gigaset.h" #include -#include //#define GIG_M10x_STUFF_VOICE_DATA @@ -303,7 +302,7 @@ static inline int iraw_loop(unsigned char c, unsigned char *src, int numbytes, inputstate |= INS_skip_frame; break; } - *__skb_put(skb, 1) = bitrev8(c); + *__skb_put(skb, 1) = gigaset_invtab[c]; } if (unlikely(!numbytes)) @@ -544,7 +543,7 @@ static struct sk_buff *iraw_encode(struct sk_buff *skb, int head, int tail) cp = skb->data; len = skb->len; while (len--) { - c = bitrev8(*cp++); + c = gigaset_invtab[*cp++]; if (c == DLE_FLAG) *(skb_put(iraw_skb, 1)) = c; *(skb_put(iraw_skb, 1)) = c; diff --git a/trunk/drivers/isdn/gigaset/common.c b/trunk/drivers/isdn/gigaset/common.c index 95eff3b2917a..defd5743dba6 100644 --- a/trunk/drivers/isdn/gigaset/common.c +++ b/trunk/drivers/isdn/gigaset/common.c @@ -33,6 +33,43 @@ 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/trunk/drivers/isdn/gigaset/gigaset.h b/trunk/drivers/isdn/gigaset/gigaset.h index a0317abaeb11..06298cc52bf5 100644 --- a/trunk/drivers/isdn/gigaset/gigaset.h +++ b/trunk/drivers/isdn/gigaset/gigaset.h @@ -876,6 +876,10 @@ 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/trunk/drivers/isdn/gigaset/interface.c b/trunk/drivers/isdn/gigaset/interface.c index 458b6462f937..7edea015867e 100644 --- a/trunk/drivers/isdn/gigaset/interface.c +++ b/trunk/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 ktermios *old); +static void if_set_termios(struct tty_struct *tty, struct termios *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 ktermios *old) +static void if_set_termios(struct tty_struct *tty, struct termios *old) { struct cardstate *cs; unsigned int iflag; diff --git a/trunk/drivers/isdn/gigaset/isocdata.c b/trunk/drivers/isdn/gigaset/isocdata.c index df988eb0e36f..8667daaa1a82 100644 --- a/trunk/drivers/isdn/gigaset/isocdata.c +++ b/trunk/drivers/isdn/gigaset/isocdata.c @@ -14,7 +14,6 @@ #include "gigaset.h" #include -#include /* access methods for isowbuf_t */ /* ============================ */ @@ -488,7 +487,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 = bitrev8(*in++); + c = gigaset_invtab[*in++]; iwb->data[write++] = c; write %= BAS_OUTBUFSIZE; } while (--count > 0); @@ -877,7 +876,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++ = bitrev8(*src++); + *dst++ = gigaset_invtab[*src++]; count--; dobytes--; } diff --git a/trunk/drivers/isdn/hardware/avm/avm_cs.c b/trunk/drivers/isdn/hardware/avm/avm_cs.c index eba10466ccc6..fd5d7364a487 100644 --- a/trunk/drivers/isdn/hardware/avm/avm_cs.c +++ b/trunk/drivers/isdn/hardware/avm/avm_cs.c @@ -121,9 +121,10 @@ static int avmcs_probe(struct pcmcia_device *p_dev) p_dev->conf.Present = PRESENT_OPTION; /* Allocate space for private device-specific data */ - local = kzalloc(sizeof(local_info_t), GFP_KERNEL); + local = kmalloc(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/trunk/drivers/isdn/hardware/avm/b1.c b/trunk/drivers/isdn/hardware/avm/b1.c index 7a69a18d07e2..da2729247713 100644 --- a/trunk/drivers/isdn/hardware/avm/b1.c +++ b/trunk/drivers/isdn/hardware/avm/b1.c @@ -65,15 +65,18 @@ avmcard *b1_alloc_card(int nr_controllers) avmctrl_info *cinfo; int i; - card = kzalloc(sizeof(*card), GFP_KERNEL); + card = kmalloc(sizeof(*card), GFP_KERNEL); if (!card) return NULL; - cinfo = kzalloc(sizeof(*cinfo) * nr_controllers, GFP_KERNEL); + memset(card, 0, sizeof(*card)); + + cinfo = kmalloc(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++) { @@ -715,11 +718,12 @@ avmcard_dma_alloc(char *name, struct pci_dev *pdev, long rsize, long ssize) avmcard_dmainfo *p; void *buf; - p = kzalloc(sizeof(avmcard_dmainfo), GFP_KERNEL); + p = kmalloc(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/trunk/drivers/isdn/hardware/avm/t1isa.c b/trunk/drivers/isdn/hardware/avm/t1isa.c index c925020fe9b7..e47c60b0a8ec 100644 --- a/trunk/drivers/isdn/hardware/avm/t1isa.c +++ b/trunk/drivers/isdn/hardware/avm/t1isa.c @@ -584,7 +584,6 @@ 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/trunk/drivers/isdn/hardware/eicon/debug.c b/trunk/drivers/isdn/hardware/eicon/debug.c index d835e74ecf18..6851c6270ce8 100644 --- a/trunk/drivers/isdn/hardware/eicon/debug.c +++ b/trunk/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), (size_t)(data_length-1)))) { + if ((to_copy = MIN(strlen(clients[id].drvName), 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), (size_t)(data_length-2)))) { + if ((to_copy = MIN(strlen(clients[id].hDbg->drvTag), data_length-2))) { memcpy (p, clients[id].hDbg->drvTag, to_copy); p += to_copy; data_length -= to_copy; diff --git a/trunk/drivers/isdn/hardware/eicon/di.c b/trunk/drivers/isdn/hardware/eicon/di.c index e1df8d98c311..0617d7cabf06 100644 --- a/trunk/drivers/isdn/hardware/eicon/di.c +++ b/trunk/drivers/isdn/hardware/eicon/di.c @@ -133,7 +133,7 @@ void pr_out(ADAPTER * a) i = this->XCurrent; X = PTR_X(a,this); while(iXNum && length<270) { - clength = min((word)(270-length),(word)(X[i].PLength-this->XOffset)); + clength = MIN((word)(270-length),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, (word)270); + IoAdapter->RBuffer.length = MIN(MLength, 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, (word)(R[this->RCurrent].PLength-this->ROffset)); + clength = MIN(MLength, 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/trunk/drivers/isdn/hardware/eicon/divasmain.c b/trunk/drivers/isdn/hardware/eicon/divasmain.c index 91fc92c01afe..dae2e83dd5e8 100644 --- a/trunk/drivers/isdn/hardware/eicon/divasmain.c +++ b/trunk/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); - vsnprintf(line, sizeof(line), format, args); + vsprintf(line, format, args); va_end(args); printk(KERN_INFO "%s: %s\n", DRIVERLNAME, line); diff --git a/trunk/drivers/isdn/hardware/eicon/io.c b/trunk/drivers/isdn/hardware/eicon/io.c index 6fd9b007417d..4a27e230b0a5 100644 --- a/trunk/drivers/isdn/hardware/eicon/io.c +++ b/trunk/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_t(size_t, sizeof(prms), pI->structure_length); + prms.structure_length = MIN(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/trunk/drivers/isdn/hardware/eicon/istream.c b/trunk/drivers/isdn/hardware/eicon/istream.c index 18f8798442fa..23139668d9b1 100644 --- a/trunk/drivers/isdn/hardware/eicon/istream.c +++ b/trunk/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, (int)tmp[1]); + to_read = MIN(max_length, tmp[1]); if (to_read) { a->ram_in_buffer(a, #ifdef PLATFORM_GT_32BIT diff --git a/trunk/drivers/isdn/hardware/eicon/platform.h b/trunk/drivers/isdn/hardware/eicon/platform.h index 2444811e0b38..a66836cf756c 100644 --- a/trunk/drivers/isdn/hardware/eicon/platform.h +++ b/trunk/drivers/isdn/hardware/eicon/platform.h @@ -83,6 +83,14 @@ #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/trunk/drivers/isdn/hisax/Kconfig b/trunk/drivers/isdn/hisax/Kconfig index 6fa12cc8e4ff..cfd2718a490d 100644 --- a/trunk/drivers/isdn/hisax/Kconfig +++ b/trunk/drivers/isdn/hisax/Kconfig @@ -349,6 +349,13 @@ 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 @@ -395,7 +402,6 @@ 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/trunk/drivers/isdn/hisax/avma1_cs.c b/trunk/drivers/isdn/hisax/avma1_cs.c index 9e70c206779e..876fec6c6be8 100644 --- a/trunk/drivers/isdn/hisax/avma1_cs.c +++ b/trunk/drivers/isdn/hisax/avma1_cs.c @@ -123,10 +123,11 @@ static int avma1cs_probe(struct pcmcia_device *p_dev) DEBUG(0, "avma1cs_attach()\n"); /* Allocate space for private device-specific data */ - local = kzalloc(sizeof(local_info_t), GFP_KERNEL); + local = kmalloc(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/trunk/drivers/isdn/hisax/config.c b/trunk/drivers/isdn/hisax/config.c index 17ec0b70ba1d..cede72cdbb31 100644 --- a/trunk/drivers/isdn/hisax/config.c +++ b/trunk/drivers/isdn/hisax/config.c @@ -227,6 +227,14 @@ 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 @@ -537,6 +545,10 @@ 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 @@ -857,13 +869,14 @@ static int checkcard(int cardnr, char *id, int *busy_flag, struct module *lockow struct IsdnCard *card = cards + cardnr; struct IsdnCardState *cs; - cs = kzalloc(sizeof(struct IsdnCardState), GFP_ATOMIC); + cs = kmalloc(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); @@ -1051,6 +1064,11 @@ 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); @@ -1419,6 +1437,7 @@ 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/trunk/drivers/isdn/hisax/diva.c b/trunk/drivers/isdn/hisax/diva.c index 6eebeb441bfd..3dacfff93f5f 100644 --- a/trunk/drivers/isdn/hisax/diva.c +++ b/trunk/drivers/isdn/hisax/diva.c @@ -1121,11 +1121,7 @@ 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/trunk/drivers/isdn/hisax/elsa_cs.c b/trunk/drivers/isdn/hisax/elsa_cs.c index 79ab9dda7d08..4e180d210faa 100644 --- a/trunk/drivers/isdn/hisax/elsa_cs.c +++ b/trunk/drivers/isdn/hisax/elsa_cs.c @@ -146,8 +146,9 @@ static int elsa_cs_probe(struct pcmcia_device *link) DEBUG(0, "elsa_cs_attach()\n"); /* Allocate space for private device-specific data */ - local = kzalloc(sizeof(local_info_t), GFP_KERNEL); + local = kmalloc(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/trunk/drivers/isdn/hisax/fsm.c b/trunk/drivers/isdn/hisax/fsm.c index 34fade96a581..0d44a3f480ac 100644 --- a/trunk/drivers/isdn/hisax/fsm.c +++ b/trunk/drivers/isdn/hisax/fsm.c @@ -26,10 +26,12 @@ FsmNew(struct Fsm *fsm, struct FsmNode *fnlist, int fncount) int i; fsm->jumpmatrix = (FSMFNPTR *) - kzalloc(sizeof (FSMFNPTR) * fsm->state_count * fsm->event_count, GFP_KERNEL); + kmalloc(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/trunk/drivers/isdn/hisax/hfc4s8s_l1.c b/trunk/drivers/isdn/hisax/hfc4s8s_l1.c index a2fa4ecb8c88..de9b1a4d6bac 100644 --- a/trunk/drivers/isdn/hisax/hfc4s8s_l1.c +++ b/trunk/drivers/isdn/hisax/hfc4s8s_l1.c @@ -1591,10 +1591,11 @@ 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 = kzalloc(sizeof(hfc4s8s_hw), GFP_ATOMIC))) { + if (!(hw = kmalloc(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/trunk/drivers/isdn/hisax/hfc_pci.c b/trunk/drivers/isdn/hisax/hfc_pci.c index 8a48a3ce0a55..5db0a85b827f 100644 --- a/trunk/drivers/isdn/hisax/hfc_pci.c +++ b/trunk/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 ((long) arg) { + switch ((int) 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 %4lx", (long) arg); + debugl1(cs, "hfcpci_l1hw loop invalid %4x", (int) 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 %p fifo %p(%#x) IRQ %d HZ %d\n", - cs->hw.hfcpci.pci_io, - cs->hw.hfcpci.fifos, + "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, (u_int) virt_to_bus(cs->hw.hfcpci.fifos), cs->irq, HZ); spin_lock_irqsave(&cs->lock, flags); diff --git a/trunk/drivers/isdn/hisax/hfc_usb.c b/trunk/drivers/isdn/hisax/hfc_usb.c index 5a6989f23fcf..7105b043add8 100644 --- a/trunk/drivers/isdn/hisax/hfc_usb.c +++ b/trunk/drivers/isdn/hisax/hfc_usb.c @@ -1481,8 +1481,9 @@ hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) iface = iface_used; if (! (context = - kzalloc(sizeof(hfcusb_data), GFP_KERNEL))) + kmalloc(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/trunk/drivers/isdn/hisax/hisax.h b/trunk/drivers/isdn/hisax/hisax.h index 3f1137e34678..159c5896061e 100644 --- a/trunk/drivers/isdn/hisax/hisax.h +++ b/trunk/drivers/isdn/hisax/hisax.h @@ -1139,6 +1139,12 @@ 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/trunk/drivers/isdn/hisax/hisax_fcpcipnp.c b/trunk/drivers/isdn/hisax/hisax_fcpcipnp.c index 9e088fce8c3a..f6db55a752c4 100644 --- a/trunk/drivers/isdn/hisax/hisax_fcpcipnp.c +++ b/trunk/drivers/isdn/hisax/hisax_fcpcipnp.c @@ -841,10 +841,12 @@ new_adapter(void) struct hisax_b_if *b_if[2]; int i; - adapter = kzalloc(sizeof(struct fritz_adapter), GFP_KERNEL); + adapter = kmalloc(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/trunk/drivers/isdn/hisax/hisax_isac.c b/trunk/drivers/isdn/hisax/hisax_isac.c index d0fefcf999cb..81eac344bb03 100644 --- a/trunk/drivers/isdn/hisax/hisax_isac.c +++ b/trunk/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); - vsnprintf(buf, sizeof(buf), fmt, args); + vsprintf(buf, fmt, args); DBG(DBG_L1M, "%s", buf); va_end(args); } diff --git a/trunk/drivers/isdn/hisax/isdnhdlc.c b/trunk/drivers/isdn/hisax/isdnhdlc.c index 268dced6c34a..cbdf54c5af84 100644 --- a/trunk/drivers/isdn/hisax/isdnhdlc.c +++ b/trunk/drivers/isdn/hisax/isdnhdlc.c @@ -35,6 +35,30 @@ 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 @@ -597,6 +621,7 @@ 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/trunk/drivers/isdn/hisax/isdnhdlc.h b/trunk/drivers/isdn/hisax/isdnhdlc.h index 45167d2f8fb0..5655b5f9c48e 100644 --- a/trunk/drivers/isdn/hisax/isdnhdlc.h +++ b/trunk/drivers/isdn/hisax/isdnhdlc.h @@ -57,6 +57,8 @@ 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/trunk/drivers/isdn/hisax/sedlbauer.c b/trunk/drivers/isdn/hisax/sedlbauer.c index 030d1625c5c6..9522141f4351 100644 --- a/trunk/drivers/isdn/hisax/sedlbauer.c +++ b/trunk/drivers/isdn/hisax/sedlbauer.c @@ -677,11 +677,7 @@ 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/trunk/drivers/isdn/hisax/sedlbauer_cs.c b/trunk/drivers/isdn/hisax/sedlbauer_cs.c index 45debde05fbd..46ed65334c51 100644 --- a/trunk/drivers/isdn/hisax/sedlbauer_cs.c +++ b/trunk/drivers/isdn/hisax/sedlbauer_cs.c @@ -155,8 +155,9 @@ static int sedlbauer_probe(struct pcmcia_device *link) DEBUG(0, "sedlbauer_attach()\n"); /* Allocate space for private device-specific data */ - local = kzalloc(sizeof(local_info_t), GFP_KERNEL); + local = kmalloc(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/trunk/drivers/isdn/hisax/st5481_b.c b/trunk/drivers/isdn/hisax/st5481_b.c index fa64115cd7c7..75d0f248e4ee 100644 --- a/trunk/drivers/isdn/hisax/st5481_b.c +++ b/trunk/drivers/isdn/hisax/st5481_b.c @@ -14,7 +14,6 @@ #include #include #include -#include #include "st5481.h" static inline void B_L1L2(struct st5481_bcs *bcs, int pr, void *arg) @@ -73,7 +72,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++ = bitrev8(*src++); + *dest++ = isdnhdlc_bit_rev_tab[*src++]; } len += bytes_sent; } else { diff --git a/trunk/drivers/isdn/hisax/st5481_d.c b/trunk/drivers/isdn/hisax/st5481_d.c index b8c4855cc889..1d8c2618366c 100644 --- a/trunk/drivers/isdn/hisax/st5481_d.c +++ b/trunk/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); - vsnprintf(buf, sizeof(buf), fmt, args); + vsprintf(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); - vsnprintf(buf, sizeof(buf), fmt, args); + vsprintf(buf, fmt, args); DBG(0x2, "%s", buf); va_end(args); } diff --git a/trunk/drivers/isdn/hisax/st5481_init.c b/trunk/drivers/isdn/hisax/st5481_init.c index bb3a28a53ff4..2716aa5c60f7 100644 --- a/trunk/drivers/isdn/hisax/st5481_init.c +++ b/trunk/drivers/isdn/hisax/st5481_init.c @@ -69,10 +69,12 @@ static int probe_st5481(struct usb_interface *intf, le16_to_cpu(dev->descriptor.idProduct), number_of_leds); - adapter = kzalloc(sizeof(struct st5481_adapter), GFP_KERNEL); + adapter = kmalloc(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/trunk/drivers/isdn/hisax/teles_cs.c b/trunk/drivers/isdn/hisax/teles_cs.c index 3e3e18239ec7..6b754f183796 100644 --- a/trunk/drivers/isdn/hisax/teles_cs.c +++ b/trunk/drivers/isdn/hisax/teles_cs.c @@ -137,8 +137,9 @@ static int teles_probe(struct pcmcia_device *link) DEBUG(0, "teles_attach()\n"); /* Allocate space for private device-specific data */ - local = kzalloc(sizeof(local_info_t), GFP_KERNEL); + local = kmalloc(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/trunk/drivers/isdn/hysdn/hycapi.c b/trunk/drivers/isdn/hysdn/hycapi.c index b2ae4ec1e49e..6bac43cc91bd 100644 --- a/trunk/drivers/isdn/hysdn/hycapi.c +++ b/trunk/drivers/isdn/hysdn/hycapi.c @@ -745,11 +745,12 @@ hycapi_capi_create(hysdn_card *card) return 1; } if (!card->hyctrlinfo) { - cinfo = kzalloc(sizeof(hycapictrl_info), GFP_ATOMIC); + cinfo = (hycapictrl_info *) kmalloc(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/trunk/drivers/isdn/hysdn/hysdn_boot.c b/trunk/drivers/isdn/hysdn/hysdn_boot.c index be787e16bb79..6d0eb0f42fca 100644 --- a/trunk/drivers/isdn/hysdn/hysdn_boot.c +++ b/trunk/drivers/isdn/hysdn/hysdn_boot.c @@ -278,13 +278,14 @@ pof_write_open(hysdn_card * card, unsigned char **bufp) return (-ERR_ALREADY_BOOT); /* boot already active */ } /* error no mem available */ - if (!(boot = kzalloc(sizeof(struct boot_data), GFP_KERNEL))) { + if (!(boot = kmalloc(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/trunk/drivers/isdn/hysdn/hysdn_init.c b/trunk/drivers/isdn/hysdn/hysdn_init.c index 9e01748a176e..b702ed27252b 100644 --- a/trunk/drivers/isdn/hysdn/hysdn_init.c +++ b/trunk/drivers/isdn/hysdn/hysdn_init.c @@ -81,10 +81,11 @@ search_cards(void) if (pci_enable_device(akt_pcidev)) continue; - if (!(card = kzalloc(sizeof(hysdn_card), GFP_KERNEL))) { + if (!(card = kmalloc(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/trunk/drivers/isdn/hysdn/hysdn_net.c b/trunk/drivers/isdn/hysdn/hysdn_net.c index 557d96c78a62..d205249a1242 100644 --- a/trunk/drivers/isdn/hysdn/hysdn_net.c +++ b/trunk/drivers/isdn/hysdn/hysdn_net.c @@ -278,10 +278,11 @@ hysdn_net_create(hysdn_card * card) return (-ENOMEM); } hysdn_net_release(card); /* release an existing net device */ - if ((dev = kzalloc(sizeof(struct net_local), GFP_KERNEL)) == NULL) { + if ((dev = kmalloc(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/trunk/drivers/isdn/hysdn/hysdn_proclog.c b/trunk/drivers/isdn/hysdn/hysdn_proclog.c index f241f5e551cb..fcd49920b220 100644 --- a/trunk/drivers/isdn/hysdn/hysdn_proclog.c +++ b/trunk/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_path.dentry->d_inode); + struct proc_dir_entry *pde = PDE(file->f_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_path.dentry->d_inode); + struct proc_dir_entry *pde = PDE(file->f_dentry->d_inode); hysdn_card *card; struct procdata *pd = NULL; @@ -405,7 +405,8 @@ hysdn_proclog_init(hysdn_card * card) /* create a cardlog proc entry */ - if ((pd = kzalloc(sizeof(struct procdata), GFP_KERNEL)) != NULL) { + if ((pd = (struct procdata *) kmalloc(sizeof(struct procdata), GFP_KERNEL)) != NULL) { + memset(pd, 0, sizeof(struct procdata)); 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/trunk/drivers/isdn/i4l/isdn_bsdcomp.c b/trunk/drivers/isdn/i4l/isdn_bsdcomp.c index a20f33b4a220..0afe442db3b0 100644 --- a/trunk/drivers/isdn/i4l/isdn_bsdcomp.c +++ b/trunk/drivers/isdn/i4l/isdn_bsdcomp.c @@ -331,10 +331,12 @@ static void *bsd_alloc (struct isdn_ppp_comp_data *data) * Allocate the main control structure for this instance. */ maxmaxcode = MAXCODE(bits); - db = kzalloc (sizeof (struct bsd_db),GFP_KERNEL); + db = (struct bsd_db *) kmalloc (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/trunk/drivers/isdn/i4l/isdn_common.c b/trunk/drivers/isdn/i4l/isdn_common.c index 6a2ef0a87ed9..69aee2602aa6 100644 --- a/trunk/drivers/isdn/i4l/isdn_common.c +++ b/trunk/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_path.dentry->d_inode); + uint minor = iminor(file->f_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_path.dentry->d_inode); + uint minor = iminor(file->f_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_path.dentry->d_inode); + unsigned int minor = iminor(file->f_dentry->d_inode); int drvidx = isdn_minor2drv(minor - ISDN_MINOR_CTRL); lock_kernel(); @@ -2072,19 +2072,21 @@ isdn_add_channels(isdn_driver_t *d, int drvidx, int n, int adding) if ((adding) && (d->rcverr)) kfree(d->rcverr); - if (!(d->rcverr = kzalloc(sizeof(int) * m, GFP_ATOMIC))) { + if (!(d->rcverr = kmalloc(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 = kzalloc(sizeof(int) * m, GFP_ATOMIC))) { + if (!(d->rcvcount = kmalloc(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++) @@ -2224,10 +2226,11 @@ register_isdn(isdn_if * i) printk(KERN_WARNING "register_isdn: No write routine given.\n"); return 0; } - if (!(d = kzalloc(sizeof(isdn_driver_t), GFP_KERNEL))) { + if (!(d = kmalloc(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/trunk/drivers/isdn/i4l/isdn_net.c b/trunk/drivers/isdn/i4l/isdn_net.c index c36c817578cb..2e4daebfb7e0 100644 --- a/trunk/drivers/isdn/i4l/isdn_net.c +++ b/trunk/drivers/isdn/i4l/isdn_net.c @@ -2542,15 +2542,17 @@ isdn_net_new(char *name, struct net_device *master) printk(KERN_WARNING "isdn_net: interface %s already exists\n", name); return NULL; } - if (!(netdev = kzalloc(sizeof(isdn_net_dev), GFP_KERNEL))) { + if (!(netdev = (isdn_net_dev *) kmalloc(sizeof(isdn_net_dev), GFP_KERNEL))) { printk(KERN_WARNING "isdn_net: Could not allocate net-device\n"); return NULL; } - if (!(netdev->local = kzalloc(sizeof(isdn_net_local), GFP_KERNEL))) { + memset(netdev, 0, sizeof(isdn_net_dev)); + if (!(netdev->local = (isdn_net_local *) kmalloc(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/trunk/drivers/isdn/i4l/isdn_ppp.c b/trunk/drivers/isdn/i4l/isdn_ppp.c index 43811795b46b..119412d6bd15 100644 --- a/trunk/drivers/isdn/i4l/isdn_ppp.c +++ b/trunk/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_path.dentry->d_inode)); + iminor(file->f_dentry->d_inode)); /* just registers wait_queue hook. This doesn't really wait. */ poll_wait(file, &is->wq, wait); @@ -876,12 +876,14 @@ isdn_ppp_init(void) #endif /* CONFIG_ISDN_MPP */ for (i = 0; i < ISDN_MAX_CHANNELS; i++) { - if (!(ippp_table[i] = kzalloc(sizeof(struct ippp_struct), GFP_KERNEL))) { + if (!(ippp_table[i] = (struct ippp_struct *) + kmalloc(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; @@ -1527,8 +1529,10 @@ static int isdn_ppp_mp_bundle_array_init(void) { int i; int sz = ISDN_MAX_CHANNELS*sizeof(ippp_bundle); - if( (isdn_ppp_bundle_arr = kzalloc(sz, GFP_KERNEL)) == NULL ) + if( (isdn_ppp_bundle_arr = (ippp_bundle*)kmalloc(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; @@ -2242,12 +2246,13 @@ 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 = kzalloc(sizeof(struct ippp_ccp_reset), GFP_KERNEL); + r = kmalloc(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; @@ -2333,9 +2338,10 @@ static struct ippp_ccp_reset_state *isdn_ppp_ccp_reset_alloc_state(struct ippp_s id); return NULL; } else { - rs = kzalloc(sizeof(struct ippp_ccp_reset_state), GFP_KERNEL); + rs = kmalloc(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; @@ -2530,11 +2536,6 @@ 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/trunk/drivers/isdn/i4l/isdn_tty.c b/trunk/drivers/isdn/i4l/isdn_tty.c index fc80afe555b9..2b91bb07fc7f 100644 --- a/trunk/drivers/isdn/i4l/isdn_tty.c +++ b/trunk/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 ktermios *old_termios) +isdn_tty_set_termios(struct tty_struct *tty, struct termios *old_termios) { modem_info *info = (modem_info *) tty->driver_data; diff --git a/trunk/drivers/isdn/i4l/isdn_v110.c b/trunk/drivers/isdn/i4l/isdn_v110.c index 5484d3c38a57..38619e8cd823 100644 --- a/trunk/drivers/isdn/i4l/isdn_v110.c +++ b/trunk/drivers/isdn/i4l/isdn_v110.c @@ -92,8 +92,9 @@ isdn_v110_open(unsigned char key, int hdrlen, int maxsize) int i; isdn_v110_stream *v; - if ((v = kzalloc(sizeof(isdn_v110_stream), GFP_ATOMIC)) == NULL) + if ((v = kmalloc(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/trunk/drivers/isdn/icn/icn.c b/trunk/drivers/isdn/icn/icn.c index 1e699bcaba0f..730bbd07ebc7 100644 --- a/trunk/drivers/isdn/icn/icn.c +++ b/trunk/drivers/isdn/icn/icn.c @@ -1519,11 +1519,12 @@ icn_initcard(int port, char *id) icn_card *card; int i; - if (!(card = kzalloc(sizeof(icn_card), GFP_KERNEL))) { + if (!(card = (icn_card *) kmalloc(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/trunk/drivers/isdn/isdnloop/isdnloop.c b/trunk/drivers/isdn/isdnloop/isdnloop.c index e3add27dd0e1..c3ae2edaf6fa 100644 --- a/trunk/drivers/isdn/isdnloop/isdnloop.c +++ b/trunk/drivers/isdn/isdnloop/isdnloop.c @@ -1430,11 +1430,12 @@ isdnloop_initcard(char *id) isdnloop_card *card; int i; - if (!(card = kzalloc(sizeof(isdnloop_card), GFP_KERNEL))) { + if (!(card = (isdnloop_card *) kmalloc(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/trunk/drivers/isdn/pcbit/drv.c b/trunk/drivers/isdn/pcbit/drv.c index 11c1b0b6e390..1966f3410a13 100644 --- a/trunk/drivers/isdn/pcbit/drv.c +++ b/trunk/drivers/isdn/pcbit/drv.c @@ -73,13 +73,14 @@ int pcbit_init_dev(int board, int mem_base, int irq) struct pcbit_dev *dev; isdn_if *dev_if; - if ((dev=kzalloc(sizeof(struct pcbit_dev), GFP_KERNEL)) == NULL) + if ((dev=kmalloc(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); @@ -103,7 +104,7 @@ int pcbit_init_dev(int board, int mem_base, int irq) return -EACCES; } - dev->b1 = kzalloc(sizeof(struct pcbit_chan), GFP_KERNEL); + dev->b1 = kmalloc(sizeof(struct pcbit_chan), GFP_KERNEL); if (!dev->b1) { printk("pcbit_init: couldn't malloc pcbit_chan struct\n"); iounmap(dev->sh_mem); @@ -112,7 +113,7 @@ int pcbit_init_dev(int board, int mem_base, int irq) return -ENOMEM; } - dev->b2 = kzalloc(sizeof(struct pcbit_chan), GFP_KERNEL); + dev->b2 = kmalloc(sizeof(struct pcbit_chan), GFP_KERNEL); if (!dev->b2) { printk("pcbit_init: couldn't malloc pcbit_chan struct\n"); kfree(dev->b1); @@ -122,6 +123,8 @@ 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/trunk/drivers/isdn/pcbit/layer2.c b/trunk/drivers/isdn/pcbit/layer2.c index 6ff85574e941..0c9f6df873fc 100644 --- a/trunk/drivers/isdn/pcbit/layer2.c +++ b/trunk/drivers/isdn/pcbit/layer2.c @@ -369,12 +369,13 @@ pcbit_receive(struct pcbit_dev *dev) kfree(dev->read_frame); dev->read_frame = NULL; } - frame = kzalloc(sizeof(struct frame_buf), GFP_ATOMIC); + frame = kmalloc(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/trunk/drivers/isdn/sc/init.c b/trunk/drivers/isdn/sc/init.c index 150759a5cddf..06c9872e8c6a 100644 --- a/trunk/drivers/isdn/sc/init.c +++ b/trunk/drivers/isdn/sc/init.c @@ -271,13 +271,14 @@ static int __init sc_init(void) * Horray! We found a board, Make sure we can register * it with ISDN4Linux */ - interface = kzalloc(sizeof(isdn_if), GFP_KERNEL); + interface = kmalloc(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; @@ -293,7 +294,7 @@ static int __init sc_init(void) /* * Allocate the board structure */ - sc_adapter[cinst] = kzalloc(sizeof(board), GFP_KERNEL); + sc_adapter[cinst] = kmalloc(sizeof(board), GFP_KERNEL); if (sc_adapter[cinst] == NULL) { /* * Oops, can't alloc memory for the board @@ -301,6 +302,7 @@ 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)) { @@ -324,7 +326,7 @@ static int __init sc_init(void) /* * Allocate channels status structures */ - sc_adapter[cinst]->channel = kzalloc(sizeof(bchan) * channels, GFP_KERNEL); + sc_adapter[cinst]->channel = kmalloc(sizeof(bchan) * channels, GFP_KERNEL); if (sc_adapter[cinst]->channel == NULL) { /* * Oops, can't alloc memory for the channels @@ -334,6 +336,7 @@ 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/trunk/drivers/macintosh/Kconfig b/trunk/drivers/macintosh/Kconfig index a9e747c39791..92ccee85e2a2 100644 --- a/trunk/drivers/macintosh/Kconfig +++ b/trunk/drivers/macintosh/Kconfig @@ -162,6 +162,7 @@ config INPUT_ADBHID config MAC_EMUMOUSEBTN bool "Support for mouse button 2+3 emulation" + depends on INPUT_ADBHID help This provides generic support for emulating the 2nd and 3rd mouse button with keypresses. If you say Y here, the emulation is still diff --git a/trunk/drivers/macintosh/adbhid.c b/trunk/drivers/macintosh/adbhid.c index 1c7d6f221b55..5066e7a8ea9c 100644 --- a/trunk/drivers/macintosh/adbhid.c +++ b/trunk/drivers/macintosh/adbhid.c @@ -689,6 +689,7 @@ adbhid_input_register(int id, int default_id, int original_handler_id, if (!hid || !input_dev) { err = -ENOMEM; goto fail; + } sprintf(hid->phys, "adb%d:%d.%02x/input", id, default_id, original_handler_id); @@ -806,9 +807,7 @@ adbhid_input_register(int id, int default_id, int original_handler_id, input_dev->keycode = hid->keycode; - err = input_register_device(input_dev); - if (err) - goto fail; + input_register_device(input_dev); if (default_id == ADB_KEYBOARD) { /* HACK WARNING!! This should go away as soon there is an utility @@ -821,10 +820,7 @@ adbhid_input_register(int id, int default_id, int original_handler_id, return 0; fail: input_free_device(input_dev); - if (hid) { - kfree(hid->keycode); - kfree(hid); - } + kfree(hid); adbhid[id] = NULL; return err; } diff --git a/trunk/drivers/macintosh/mac_hid.c b/trunk/drivers/macintosh/mac_hid.c index ee6b4ca69130..6b129eef7987 100644 --- a/trunk/drivers/macintosh/mac_hid.c +++ b/trunk/drivers/macintosh/mac_hid.c @@ -106,8 +106,6 @@ EXPORT_SYMBOL(mac_hid_mouse_emulate_buttons); static int emumousebtn_input_register(void) { - int ret; - emumousebtn = input_allocate_device(); if (!emumousebtn) return -ENOMEM; @@ -122,11 +120,9 @@ static int emumousebtn_input_register(void) emumousebtn->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT); emumousebtn->relbit[0] = BIT(REL_X) | BIT(REL_Y); - ret = input_register_device(emumousebtn); - if (ret) - input_free_device(emumousebtn); + input_register_device(emumousebtn); - return ret; + return 0; } int __init mac_hid_init(void) diff --git a/trunk/drivers/md/bitmap.c b/trunk/drivers/md/bitmap.c index 5432d07c074d..d6f614738bbd 100644 --- a/trunk/drivers/md/bitmap.c +++ b/trunk/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_path.dentry; - v = file->f_path.mnt; + d = file->f_dentry; + v = file->f_vfsmnt; 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_path.dentry->d_inode; + struct inode *inode = file->f_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_path.dentry->d_inode; + struct inode *inode = file->f_dentry->d_inode; invalidate_inode_pages(inode->i_mapping); fput(file); } diff --git a/trunk/drivers/md/dm-bio-list.h b/trunk/drivers/md/dm-bio-list.h index da4349649f7f..bbf4615f0e30 100644 --- a/trunk/drivers/md/dm-bio-list.h +++ b/trunk/drivers/md/dm-bio-list.h @@ -44,20 +44,6 @@ 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/trunk/drivers/md/dm-crypt.c b/trunk/drivers/md/dm-crypt.c index 4c2471ee054a..a1086ee8cccd 100644 --- a/trunk/drivers/md/dm-crypt.c +++ b/trunk/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 = ilog2(bs); + int log = long_log2(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 DM_MAPIO_SUBMITTED; + return 0; } static int crypt_status(struct dm_target *ti, status_type_t type, diff --git a/trunk/drivers/md/dm-emc.c b/trunk/drivers/md/dm-emc.c index 265c467854da..2b2d45d7baaa 100644 --- a/trunk/drivers/md/dm-emc.c +++ b/trunk/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 dm_path *path = bio->bi_private; + struct 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 dm_path *path, unsigned data_size) +static struct bio *get_failover_bio(struct path *path, unsigned data_size) { struct bio *bio; struct page *page; @@ -96,7 +96,7 @@ static struct bio *get_failover_bio(struct dm_path *path, unsigned data_size) } static struct request *get_failover_req(struct emc_handler *h, - struct bio *bio, struct dm_path *path) + struct bio *bio, struct 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 dm_path *path) + struct 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 dm_path *path) + struct path *path) { struct request *rq; struct request_queue *q = bdev_get_queue(path->dev->bdev); diff --git a/trunk/drivers/md/dm-hw-handler.h b/trunk/drivers/md/dm-hw-handler.h index 32eff28e4adc..15f5629e231a 100644 --- a/trunk/drivers/md/dm-hw-handler.h +++ b/trunk/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 dm_path *path); + struct 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/trunk/drivers/md/dm-io.c b/trunk/drivers/md/dm-io.c index 4eb73d395213..da663d2ff552 100644 --- a/trunk/drivers/md/dm-io.c +++ b/trunk/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].bv_len = region; + bio->bi_io_vec[bio->bi_max_vecs - 1].bv_len = region; } static inline unsigned bio_get_region(struct bio *bio) { - return bio->bi_io_vec[bio->bi_max_vecs].bv_len; + return bio->bi_io_vec[bio->bi_max_vecs - 1].bv_len; } /*----------------------------------------------------------------- @@ -136,7 +136,6 @@ 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; @@ -251,18 +250,16 @@ 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() and decrement bi_max_vecs - * to hide it from bio_add_page(). + * Allocate a suitably sized bio, we add an extra + * bvec for bio_get/set_region(). */ - num_bvecs = (remaining / (PAGE_SIZE >> SECTOR_SHIFT)) + 2; + num_bvecs = (remaining / (PAGE_SIZE >> 9)) + 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); /* @@ -305,7 +302,7 @@ static void dispatch_io(int rw, unsigned int num_regions, } /* - * Drop the extra reference that we were holding to avoid + * Drop the extra refence that we were holding to avoid * the io being completed too early. */ dec_count(io, 0, 0); diff --git a/trunk/drivers/md/dm-ioctl.c b/trunk/drivers/md/dm-ioctl.c index cd6a184536a1..4510ad8f971c 100644 --- a/trunk/drivers/md/dm-ioctl.c +++ b/trunk/drivers/md/dm-ioctl.c @@ -765,7 +765,7 @@ static int dev_set_geometry(struct dm_ioctl *param, size_t param_size) static int do_suspend(struct dm_ioctl *param) { int r = 0; - unsigned suspend_flags = DM_SUSPEND_LOCKFS_FLAG; + int do_lockfs = 1; struct mapped_device *md; md = find_device(param); @@ -773,12 +773,10 @@ static int do_suspend(struct dm_ioctl *param) return -ENXIO; if (param->flags & DM_SKIP_LOCKFS_FLAG) - suspend_flags &= ~DM_SUSPEND_LOCKFS_FLAG; - if (param->flags & DM_NOFLUSH_FLAG) - suspend_flags |= DM_SUSPEND_NOFLUSH_FLAG; + do_lockfs = 0; if (!dm_suspended(md)) - r = dm_suspend(md, suspend_flags); + r = dm_suspend(md, do_lockfs); if (!r) r = __dev_status(md, param); @@ -790,7 +788,7 @@ static int do_suspend(struct dm_ioctl *param) static int do_resume(struct dm_ioctl *param) { int r = 0; - unsigned suspend_flags = DM_SUSPEND_LOCKFS_FLAG; + int do_lockfs = 1; struct hash_cell *hc; struct mapped_device *md; struct dm_table *new_map; @@ -816,11 +814,9 @@ 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) - suspend_flags &= ~DM_SUSPEND_LOCKFS_FLAG; - if (param->flags & DM_NOFLUSH_FLAG) - suspend_flags |= DM_SUSPEND_NOFLUSH_FLAG; + do_lockfs = 0; if (!dm_suspended(md)) - dm_suspend(md, suspend_flags); + dm_suspend(md, do_lockfs); r = dm_swap_table(md, new_map); if (r) { diff --git a/trunk/drivers/md/dm-linear.c b/trunk/drivers/md/dm-linear.c index 17753d80ad22..00234909b3db 100644 --- a/trunk/drivers/md/dm-linear.c +++ b/trunk/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 DM_MAPIO_REMAPPED; + return 1; } 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_path.dentry = &fake_dentry; + fake_file.f_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/trunk/drivers/md/dm-log.c b/trunk/drivers/md/dm-log.c index 6a9261351848..64b764bd02cc 100644 --- a/trunk/drivers/md/dm-log.c +++ b/trunk/drivers/md/dm-log.c @@ -466,7 +466,6 @@ 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; @@ -481,13 +480,6 @@ 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; @@ -557,19 +549,16 @@ static int core_get_resync_work(struct dirty_log *log, region_t *region) return 1; } -static void core_set_region_sync(struct dirty_log *log, region_t region, - int in_sync) +static void core_complete_resync_work(struct dirty_log *log, region_t region, + int success) { struct log_c *lc = (struct log_c *) log->context; log_clear_bit(lc, lc->recovering_bits, region); - if (in_sync) { + if (success) { 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) @@ -629,7 +618,6 @@ 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, @@ -637,7 +625,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, - .set_region_sync = core_set_region_sync, + .complete_resync_work = core_complete_resync_work, .get_sync_count = core_get_sync_count, .status = core_status, }; @@ -656,7 +644,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, - .set_region_sync = core_set_region_sync, + .complete_resync_work = core_complete_resync_work, .get_sync_count = core_get_sync_count, .status = disk_status, }; diff --git a/trunk/drivers/md/dm-log.h b/trunk/drivers/md/dm-log.h index 86a301c8daf1..5ae5309ebf28 100644 --- a/trunk/drivers/md/dm-log.h +++ b/trunk/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 status of a region - * has changed. It also clears the region from the recovering - * list (if present). + * This notifies the log that the resync of an area has + * been completed. The log should then mark this region + * as CLEAN. */ - void (*set_region_sync)(struct dirty_log *log, - region_t region, int in_sync); + void (*complete_resync_work)(struct dirty_log *log, + region_t region, int success); /* * Returns the number of regions that are in sync. diff --git a/trunk/drivers/md/dm-mpath.c b/trunk/drivers/md/dm-mpath.c index 3aa013506967..cf8bf052138e 100644 --- a/trunk/drivers/md/dm-mpath.c +++ b/trunk/drivers/md/dm-mpath.c @@ -31,7 +31,7 @@ struct pgpath { struct priority_group *pg; /* Owning PG */ unsigned fail_count; /* Cumulative failure count */ - struct dm_path path; + struct 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 dm_path *path; + struct path *path; path = pg->ps.type->select_path(&pg->ps, &m->repeat_count); if (!path) @@ -282,27 +282,10 @@ static void __choose_pgpath(struct multipath *m) 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 = DM_MAPIO_REMAPPED; + int r = 1; unsigned long flags; struct pgpath *pgpath; @@ -327,13 +310,11 @@ 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 = DM_MAPIO_SUBMITTED; - } else if (pgpath) - bio->bi_bdev = pgpath->path.dev->bdev; - else if (__must_push_back(m)) - r = DM_MAPIO_REQUEUE; + r = 0; + } else if (!pgpath) + r = -EIO; /* Failed */ else - r = -EIO; /* Failed */ + bio->bi_bdev = pgpath->path.dev->bdev; mpio->pgpath = pgpath; @@ -391,10 +372,8 @@ 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 == DM_MAPIO_REMAPPED) + else if (r == 1) generic_make_request(bio); - else if (r == DM_MAPIO_REQUEUE) - bio_endio(bio, bio->bi_size, -EIO); bio = next; } @@ -804,7 +783,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 || r == DM_MAPIO_REQUEUE) + if (r < 0) mempool_free(mpio, m->mpio_pool); return r; @@ -978,7 +957,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 dm_path *path, unsigned err_flags) +void dm_pg_init_complete(struct path *path, unsigned err_flags) { struct pgpath *pgpath = path_to_pgpath(path); struct priority_group *pg = pgpath->pg; @@ -1028,10 +1007,7 @@ static int do_end_io(struct multipath *m, struct bio *bio, spin_lock_irqsave(&m->lock, flags); if (!m->nr_valid_paths) { - if (__must_push_back(m)) { - spin_unlock_irqrestore(&m->lock, flags); - return DM_ENDIO_REQUEUE; - } else if (!m->queue_if_no_path) { + if (!m->queue_if_no_path) { spin_unlock_irqrestore(&m->lock, flags); return -EIO; } else { @@ -1066,7 +1042,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 DM_ENDIO_INCOMPLETE; /* io not complete */ + return 1; /* io not complete */ } static int multipath_end_io(struct dm_target *ti, struct bio *bio, @@ -1084,7 +1060,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 != DM_ENDIO_INCOMPLETE) + if (r <= 0) mempool_free(mpio, m->mpio_pool); return r; @@ -1296,7 +1272,7 @@ static int multipath_ioctl(struct dm_target *ti, struct inode *inode, struct dentry fake_dentry = {}; int r = 0; - fake_file.f_path.dentry = &fake_dentry; + fake_file.f_dentry = &fake_dentry; spin_lock_irqsave(&m->lock, flags); diff --git a/trunk/drivers/md/dm-mpath.h b/trunk/drivers/md/dm-mpath.h index b9cdcbb3ed59..8a4bf2b6d52e 100644 --- a/trunk/drivers/md/dm-mpath.h +++ b/trunk/drivers/md/dm-mpath.h @@ -11,7 +11,7 @@ struct dm_dev; -struct dm_path { +struct path { struct dm_dev *dev; /* Read-only */ unsigned is_active; /* Read-only */ @@ -20,6 +20,6 @@ struct dm_path { }; /* Callback for hwh_pg_init_fn to use when complete */ -void dm_pg_init_complete(struct dm_path *path, unsigned err_flags); +void dm_pg_init_complete(struct path *path, unsigned err_flags); #endif diff --git a/trunk/drivers/md/dm-path-selector.h b/trunk/drivers/md/dm-path-selector.h index 27357b85d73d..732d06a84f85 100644 --- a/trunk/drivers/md/dm-path-selector.h +++ b/trunk/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 dm_path *path, + int (*add_path) (struct path_selector *ps, struct 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 dm_path *(*select_path) (struct path_selector *ps, + struct 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 dm_path *p); + void (*fail_path) (struct path_selector *ps, struct path *p); /* * Ask selector to reinstate a path. */ - int (*reinstate_path) (struct path_selector *ps, struct dm_path *p); + int (*reinstate_path) (struct path_selector *ps, struct path *p); /* * Table content based on parameters added in ps_add_path_fn * or path selector status */ - int (*status) (struct path_selector *ps, struct dm_path *path, + int (*status) (struct path_selector *ps, struct path *path, status_type_t type, char *result, unsigned int maxlen); - int (*end_io) (struct path_selector *ps, struct dm_path *path); + int (*end_io) (struct path_selector *ps, struct path *path); }; /* Register a path selector */ diff --git a/trunk/drivers/md/dm-raid1.c b/trunk/drivers/md/dm-raid1.c index 23a642619bed..fc8cbb168e3e 100644 --- a/trunk/drivers/md/dm-raid1.c +++ b/trunk/drivers/md/dm-raid1.c @@ -344,17 +344,6 @@ 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, ®->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; @@ -394,7 +383,11 @@ 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); - complete_resync_work(reg, 1); + rh->log->type->complete_resync_work(rh->log, reg->key, 1); + dispatch_bios(rh->ms, ®->delayed_bios); + if (atomic_dec_and_test(&rh->recovery_in_flight)) + wake_up_all(&_kmirrord_recovery_stopped); + up(&rh->recovery_count); mempool_free(reg, rh->region_pool); } @@ -1144,7 +1137,7 @@ static int mirror_map(struct dm_target *ti, struct bio *bio, if (rw == WRITE) { queue_bio(ms, bio, rw); - return DM_MAPIO_SUBMITTED; + return 0; } r = ms->rh.log->type->in_sync(ms->rh.log, @@ -1153,7 +1146,7 @@ static int mirror_map(struct dm_target *ti, struct bio *bio, return r; if (r == -EWOULDBLOCK) /* FIXME: ugly */ - r = DM_MAPIO_SUBMITTED; + r = 0; /* * We don't want to fast track a recovery just for a read @@ -1166,7 +1159,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 DM_MAPIO_SUBMITTED; + return 0; } m = choose_mirror(ms, bio->bi_sector); @@ -1174,7 +1167,7 @@ static int mirror_map(struct dm_target *ti, struct bio *bio, return -EIO; map_bio(ms, m, bio); - return DM_MAPIO_REMAPPED; + return 1; } static int mirror_end_io(struct dm_target *ti, struct bio *bio, diff --git a/trunk/drivers/md/dm-round-robin.c b/trunk/drivers/md/dm-round-robin.c index a348a97b65af..6f9fcd4db9b5 100644 --- a/trunk/drivers/md/dm-round-robin.c +++ b/trunk/drivers/md/dm-round-robin.c @@ -21,7 +21,7 @@ *---------------------------------------------------------------*/ struct path_info { struct list_head list; - struct dm_path *path; + struct 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 dm_path *path, +static int rr_status(struct path_selector *ps, struct 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 dm_path *path, * Called during initialisation to register each path with an * optional repeat_count. */ -static int rr_add_path(struct path_selector *ps, struct dm_path *path, +static int rr_add_path(struct path_selector *ps, struct 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 dm_path *path, return 0; } -static void rr_fail_path(struct path_selector *ps, struct dm_path *p) +static void rr_fail_path(struct path_selector *ps, struct 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 dm_path *p) list_move(&pi->list, &s->invalid_paths); } -static int rr_reinstate_path(struct path_selector *ps, struct dm_path *p) +static int rr_reinstate_path(struct path_selector *ps, struct 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 dm_path *p) return 0; } -static struct dm_path *rr_select_path(struct path_selector *ps, +static struct path *rr_select_path(struct path_selector *ps, unsigned *repeat_count) { struct selector *s = (struct selector *) ps->context; diff --git a/trunk/drivers/md/dm-snap.c b/trunk/drivers/md/dm-snap.c index 0821a2b68a73..b0ce2ce82278 100644 --- a/trunk/drivers/md/dm-snap.c +++ b/trunk/drivers/md/dm-snap.c @@ -39,7 +39,7 @@ */ #define SNAPSHOT_PAGES 256 -static struct workqueue_struct *ksnapd; +struct workqueue_struct *ksnapd; static void flush_queued_bios(struct work_struct *work); struct pending_exception { @@ -564,17 +564,6 @@ 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; @@ -585,7 +574,13 @@ static void snapshot_dtr(struct dm_target *ti) /* After this returns there can be no new kcopyd jobs. */ unregister_snapshot(s); - __free_exceptions(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); dm_put_device(ti, s->origin); dm_put_device(ti, s->cow); @@ -873,7 +868,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 = DM_MAPIO_REMAPPED; + int r = 1; chunk_t chunk; struct pending_exception *pe = NULL; @@ -919,7 +914,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 = DM_MAPIO_SUBMITTED; + r = 0; if (!pe->started) { /* this is protected by snap->lock */ @@ -997,7 +992,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 = DM_MAPIO_REMAPPED, first = 0; + int r = 1, first = 0; struct dm_snapshot *snap; struct exception *e; struct pending_exception *pe, *next_pe, *primary_pe = NULL; @@ -1055,7 +1050,7 @@ static int __origin_write(struct list_head *snapshots, struct bio *bio) bio_list_add(&primary_pe->origin_bios, bio); - r = DM_MAPIO_SUBMITTED; + r = 0; } if (!pe->primary_pe) { @@ -1104,7 +1099,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 = DM_MAPIO_REMAPPED; + int r = 1; down_read(&_origins_lock); o = __lookup_origin(origin->bdev); @@ -1161,7 +1156,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) : DM_MAPIO_REMAPPED; + return (bio_rw(bio) == WRITE) ? do_origin(dev, bio) : 1; } #define min_not_zero(l, r) (l == 0) ? r : ((r == 0) ? l : min(l, r)) diff --git a/trunk/drivers/md/dm-stripe.c b/trunk/drivers/md/dm-stripe.c index 51f5e0760012..6c29fcecd892 100644 --- a/trunk/drivers/md/dm-stripe.c +++ b/trunk/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 DM_MAPIO_REMAPPED; + return 1; } static int stripe_status(struct dm_target *ti, diff --git a/trunk/drivers/md/dm-zero.c b/trunk/drivers/md/dm-zero.c index f314d7dc9c26..ea569f7348d2 100644 --- a/trunk/drivers/md/dm-zero.c +++ b/trunk/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 DM_MAPIO_SUBMITTED; + return 0; } static struct target_type zero_target = { diff --git a/trunk/drivers/md/dm.c b/trunk/drivers/md/dm.c index fe7c56e10435..7ec1b112a6d5 100644 --- a/trunk/drivers/md/dm.c +++ b/trunk/drivers/md/dm.c @@ -68,12 +68,10 @@ 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; @@ -91,8 +89,7 @@ struct mapped_device { */ atomic_t pending; wait_queue_head_t wait; - struct bio_list deferred; - struct bio_list pushback; + struct bio_list deferred; /* * The current mapping. @@ -447,50 +444,23 @@ 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) { - unsigned long flags; - - /* Push-back supersedes any I/O errors */ - if (error && !(io->error > 0 && __noflush_suspending(io->md))) + if (error) 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); - 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); - } + blk_add_trace_bio(io->md->queue, io->bio, BLK_TA_COMPLETE); + bio_endio(io->bio, io->bio->bi_size, io->error); free_io(io->md, io); } } @@ -510,19 +480,12 @@ 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 || r == DM_ENDIO_REQUEUE) - /* - * error and requeue request are handled - * in dec_pending(). - */ + if (r < 0) error = r; - else if (r == DM_ENDIO_INCOMPLETE) - /* The target will handle the io */ + + else if (r > 0) + /* the target wants another shot at the io */ return 1; - else if (r) { - DMWARN("unimplemented target endio return value: %d", r); - BUG(); - } } dec_pending(tio->io, error); @@ -580,7 +543,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 == DM_MAPIO_REMAPPED) { + if (r > 0) { /* the bio has been remapped so dispatch it */ blk_add_trace_remap(bdev_get_queue(clone->bi_bdev), clone, @@ -588,8 +551,10 @@ static void __map_bio(struct dm_target *ti, struct bio *clone, clone->bi_sector); generic_make_request(clone); - } else if (r < 0 || r == DM_MAPIO_REQUEUE) { - /* error the io and bail out, or requeue it if needed */ + } + + else if (r < 0) { + /* error the io and bail out */ md = tio->io->md; dec_pending(tio->io, r); /* @@ -598,9 +563,6 @@ 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(); } } @@ -986,7 +948,6 @@ 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); @@ -1005,8 +966,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) @@ -1314,15 +1275,12 @@ 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, unsigned suspend_flags) +int dm_suspend(struct mapped_device *md, int do_lockfs) { 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); @@ -1331,13 +1289,6 @@ int dm_suspend(struct mapped_device *md, unsigned suspend_flags) 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); @@ -1345,14 +1296,11 @@ int dm_suspend(struct mapped_device *md, unsigned suspend_flags) if (!md->suspended_bdev) { DMWARN("bdget failed in dm_suspend"); r = -ENOMEM; - goto flush_and_out; + goto out; } - /* - * Flush I/O to the device. - * noflush supersedes do_lockfs, because lock_fs() needs to flush I/Os. - */ - if (do_lockfs && !noflush) { + /* Flush I/O to the device. */ + if (do_lockfs) { r = lock_fs(md); if (r) goto out; @@ -1388,14 +1336,6 @@ int dm_suspend(struct mapped_device *md, unsigned suspend_flags) 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)) { @@ -1404,7 +1344,7 @@ int dm_suspend(struct mapped_device *md, unsigned suspend_flags) __flush_deferred_io(md, def); up_write(&md->io_lock); unlock_fs(md); - goto out; /* pushback list is already flushed, so skip flush */ + goto out; } up_write(&md->io_lock); @@ -1414,25 +1354,6 @@ int dm_suspend(struct mapped_device *md, unsigned suspend_flags) 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); @@ -1519,17 +1440,6 @@ 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/trunk/drivers/md/dm.h b/trunk/drivers/md/dm.h index 2f796b1436b2..a48ec5e3c1f4 100644 --- a/trunk/drivers/md/dm.h +++ b/trunk/drivers/md/dm.h @@ -32,25 +32,6 @@ #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. */ diff --git a/trunk/drivers/md/md.c b/trunk/drivers/md/md.c index 53bd46dba0cb..6c4345bde07e 100644 --- a/trunk/drivers/md/md.c +++ b/trunk/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_by_devnum(dev, FMODE_READ|FMODE_WRITE); + bdev = open_partition_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(bdev); + blkdev_put_partition(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(bdev); + blkdev_put_partition(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 = mutex_lock_interruptible_nested(&mddev->reconfig_mutex, 1))) + if ((err = mddev_lock(mddev))) 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_path.mnt, - bitmap->file->f_path.dentry," \t\n"); + seq_path(seq, bitmap->file->f_vfsmnt, + bitmap->file->f_dentry," \t\n"); } seq_printf(seq, "\n"); diff --git a/trunk/drivers/media/video/compat_ioctl32.c b/trunk/drivers/media/video/compat_ioctl32.c index f065ad12cc61..d82a488f12a6 100644 --- a/trunk/drivers/media/video/compat_ioctl32.c +++ b/trunk/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_path.dentry->d_inode, file, cmd, arg); + ret = file->f_op->ioctl(file->f_dentry->d_inode, file, cmd, arg); unlock_kernel(); } diff --git a/trunk/drivers/media/video/videodev.c b/trunk/drivers/media/video/videodev.c index 41ec0c4b35a2..d424a4129d69 100644 --- a/trunk/drivers/media/video/videodev.c +++ b/trunk/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_path.dentry->d_inode)]; + return video_device[iminor(file->f_dentry->d_inode)]; } /* diff --git a/trunk/drivers/media/video/zoran_procfs.c b/trunk/drivers/media/video/zoran_procfs.c index c374c76b3753..c7f6f6488360 100644 --- a/trunk/drivers/media/video/zoran_procfs.c +++ b/trunk/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_path.dentry->d_inode)->data; + struct zoran *zr = PDE(file->f_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_path.dentry->d_name.name, count, zr); + ZR_DEVNAME(zr), file->f_dentry->d_name.name, count, zr); ldelim = " \t\n"; tdelim = "="; line = strpbrk(sp, ldelim); diff --git a/trunk/drivers/mmc/au1xmmc.c b/trunk/drivers/mmc/au1xmmc.c index 800527cf40d5..447fba5825fd 100644 --- a/trunk/drivers/mmc/au1xmmc.c +++ b/trunk/drivers/mmc/au1xmmc.c @@ -875,7 +875,7 @@ static void au1xmmc_init_dma(struct au1xmmc_host *host) host->rx_chan = rxchan; } -static const struct mmc_host_ops au1xmmc_ops = { +struct const mmc_host_ops au1xmmc_ops = { .request = au1xmmc_request, .set_ios = au1xmmc_set_ios, }; diff --git a/trunk/drivers/mmc/pxamci.c b/trunk/drivers/mmc/pxamci.c index 45a9283ce498..471e9f4e0530 100644 --- a/trunk/drivers/mmc/pxamci.c +++ b/trunk/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(mmc)); + return host->pdata->get_ro(mmc->dev); /* 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(mmc), ios->vdd); + host->pdata->setpower(mmc->dev, ios->vdd); if (ios->power_mode == MMC_POWER_ON) host->cmdat |= CMDAT_INIT; diff --git a/trunk/drivers/mmc/tifm_sd.c b/trunk/drivers/mmc/tifm_sd.c index f18ad998b3cb..e846499a004c 100644 --- a/trunk/drivers/mmc/tifm_sd.c +++ b/trunk/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(ilog2(cmd->data->blksz) - 2, + writel(long_log2(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/trunk/drivers/net/irda/irtty-sir.c b/trunk/drivers/net/irda/irtty-sir.c index ad1857364d51..6a98b7ae4975 100644 --- a/trunk/drivers/net/irda/irtty-sir.c +++ b/trunk/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 ktermios old_termios; + struct termios 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 ktermios old_termios; + struct termios old_termios; int cflag; lock_kernel(); diff --git a/trunk/drivers/net/via-velocity.c b/trunk/drivers/net/via-velocity.c index 4587f23f4e4b..74f894795a1b 100644 --- a/trunk/drivers/net/via-velocity.c +++ b/trunk/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 bitrev32(crc) >> 16; + return bitreverse(crc) >> 16; } /** diff --git a/trunk/drivers/net/wan/cosa.c b/trunk/drivers/net/wan/cosa.c index 6c7dfb50143f..e1bf8b93f958 100644 --- a/trunk/drivers/net/wan/cosa.c +++ b/trunk/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_path.dentry->d_inode)>>CARD_MINOR_BITS) + if ((n=iminor(file->f_dentry->d_inode)>>CARD_MINOR_BITS) >= nr_cards) return -ENODEV; cosa = cosa_cards+n; - if ((n=iminor(file->f_path.dentry->d_inode) + if ((n=iminor(file->f_dentry->d_inode) & ((1<= cosa->nchannels) return -ENODEV; chan = cosa->chan + n; diff --git a/trunk/drivers/net/wireless/strip.c b/trunk/drivers/net/wireless/strip.c index ce3a8bac66ff..337c692f6fd6 100644 --- a/trunk/drivers/net/wireless/strip.c +++ b/trunk/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 ktermios old_termios = *(tty->termios); + struct termios 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/trunk/drivers/oprofile/buffer_sync.c b/trunk/drivers/oprofile/buffer_sync.c index 78c2e6e4b42e..43e521e99126 100644 --- a/trunk/drivers/oprofile/buffer_sync.c +++ b/trunk/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_path.dentry, - vma->vm_file->f_path.mnt); + cookie = fast_get_dcookie(vma->vm_file->f_dentry, + vma->vm_file->f_vfsmnt); 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_path.dentry, - vma->vm_file->f_path.mnt); + cookie = fast_get_dcookie(vma->vm_file->f_dentry, + vma->vm_file->f_vfsmnt); *offset = (vma->vm_pgoff << PAGE_SHIFT) + addr - vma->vm_start; } else { diff --git a/trunk/drivers/pci/proc.c b/trunk/drivers/pci/proc.c index 4a6760a3b31f..99cf33379769 100644 --- a/trunk/drivers/pci/proc.c +++ b/trunk/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_path.dentry->d_inode; + struct inode *inode = file->f_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_path.dentry->d_inode; + const struct inode *ino = file->f_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_path.dentry->d_inode; + const struct inode *ino = file->f_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_path.dentry->d_inode; + struct inode *inode = file->f_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/trunk/drivers/pcmcia/pcmcia_ioctl.c b/trunk/drivers/pcmcia/pcmcia_ioctl.c index 327372b7a54e..d077870c6731 100644 --- a/trunk/drivers/pcmcia/pcmcia_ioctl.c +++ b/trunk/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_path.dentry->d_inode)); + ds_dbg(2, "ds_read(socket %d)\n", iminor(file->f_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_path.dentry->d_inode)); + ds_dbg(2, "ds_write(socket %d)\n", iminor(file->f_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_path.dentry->d_inode)); + ds_dbg(2, "ds_poll(socket %d)\n", iminor(file->f_dentry->d_inode)); user = file->private_data; if (CHECK_USER(user)) diff --git a/trunk/drivers/pnp/isapnp/proc.c b/trunk/drivers/pnp/isapnp/proc.c index d21f3c1e72fc..958c11bedd0d 100644 --- a/trunk/drivers/pnp/isapnp/proc.c +++ b/trunk/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_path.dentry->d_inode; + struct inode *ino = file->f_dentry->d_inode; struct proc_dir_entry *dp = PDE(ino); struct pnp_dev *dev = dp->data; int pos = *ppos; diff --git a/trunk/drivers/s390/block/dasd.c b/trunk/drivers/s390/block/dasd.c index 492b68bcd7cc..2af2d9b53d18 100644 --- a/trunk/drivers/s390/block/dasd.c +++ b/trunk/drivers/s390/block/dasd.c @@ -1050,10 +1050,10 @@ dasd_int_handler(struct ccw_device *cdev, unsigned long intparm, } } else { /* error */ memcpy(&cqr->irb, irb, sizeof (struct irb)); - if (device->features & DASD_FEATURE_ERPLOG) { - /* dump sense data */ - dasd_log_sense(cqr, irb); - } +#ifdef ERP_DEBUG + /* dump sense data */ + dasd_log_sense(cqr, irb); +#endif switch (era) { case dasd_era_fatal: cqr->status = DASD_CQR_FAILED; diff --git a/trunk/drivers/s390/block/dasd_3990_erp.c b/trunk/drivers/s390/block/dasd_3990_erp.c index 4d01040c2c63..669805d4402d 100644 --- a/trunk/drivers/s390/block/dasd_3990_erp.c +++ b/trunk/drivers/s390/block/dasd_3990_erp.c @@ -2641,12 +2641,14 @@ dasd_3990_erp_action(struct dasd_ccw_req * cqr) struct dasd_ccw_req *erp = NULL; struct dasd_device *device = cqr->device; __u32 cpa = cqr->irb.scsw.cpa; - struct dasd_ccw_req *temp_erp = NULL; - if (device->features & DASD_FEATURE_ERPLOG) { - /* print current erp_chain */ - DEV_MESSAGE(KERN_ERR, device, "%s", - "ERP chain at BEGINNING of ERP-ACTION"); +#ifdef ERP_DEBUG + /* print current erp_chain */ + DEV_MESSAGE(KERN_ERR, device, "%s", + "ERP chain at BEGINNING of ERP-ACTION"); + { + struct dasd_ccw_req *temp_erp = NULL; + for (temp_erp = cqr; temp_erp != NULL; temp_erp = temp_erp->refers) { @@ -2656,6 +2658,7 @@ dasd_3990_erp_action(struct dasd_ccw_req * cqr) temp_erp->refers); } } +#endif /* ERP_DEBUG */ /* double-check if current erp/cqr was successfull */ if ((cqr->irb.scsw.cstat == 0x00) && @@ -2692,10 +2695,11 @@ dasd_3990_erp_action(struct dasd_ccw_req * cqr) erp = dasd_3990_erp_handle_match_erp(cqr, erp); } - if (device->features & DASD_FEATURE_ERPLOG) { - /* print current erp_chain */ - DEV_MESSAGE(KERN_ERR, device, "%s", - "ERP chain at END of ERP-ACTION"); +#ifdef ERP_DEBUG + /* print current erp_chain */ + DEV_MESSAGE(KERN_ERR, device, "%s", "ERP chain at END of ERP-ACTION"); + { + struct dasd_ccw_req *temp_erp = NULL; for (temp_erp = erp; temp_erp != NULL; temp_erp = temp_erp->refers) { @@ -2705,6 +2709,7 @@ dasd_3990_erp_action(struct dasd_ccw_req * cqr) temp_erp->refers); } } +#endif /* ERP_DEBUG */ if (erp->status == DASD_CQR_FAILED) dasd_log_ccw(erp, 1, cpa); diff --git a/trunk/drivers/s390/block/dasd_devmap.c b/trunk/drivers/s390/block/dasd_devmap.c index 5943266152f5..cf28ccc57948 100644 --- a/trunk/drivers/s390/block/dasd_devmap.c +++ b/trunk/drivers/s390/block/dasd_devmap.c @@ -202,8 +202,6 @@ dasd_feature_list(char *str, char **endp) features |= DASD_FEATURE_READONLY; else if (len == 4 && !strncmp(str, "diag", 4)) features |= DASD_FEATURE_USEDIAG; - else if (len == 6 && !strncmp(str, "erplog", 6)) - features |= DASD_FEATURE_ERPLOG; else { MESSAGE(KERN_WARNING, "unsupported feature: %*s, " @@ -711,52 +709,6 @@ dasd_ro_store(struct device *dev, struct device_attribute *attr, } static DEVICE_ATTR(readonly, 0644, dasd_ro_show, dasd_ro_store); -/* - * erplog controls the logging of ERP related data - * (e.g. failing channel programs). - */ -static ssize_t -dasd_erplog_show(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct dasd_devmap *devmap; - int erplog; - - devmap = dasd_find_busid(dev->bus_id); - if (!IS_ERR(devmap)) - erplog = (devmap->features & DASD_FEATURE_ERPLOG) != 0; - else - erplog = (DASD_FEATURE_DEFAULT & DASD_FEATURE_ERPLOG) != 0; - return snprintf(buf, PAGE_SIZE, erplog ? "1\n" : "0\n"); -} - -static ssize_t -dasd_erplog_store(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - struct dasd_devmap *devmap; - int val; - char *endp; - - devmap = dasd_devmap_from_cdev(to_ccwdev(dev)); - if (IS_ERR(devmap)) - return PTR_ERR(devmap); - - val = simple_strtoul(buf, &endp, 0); - if (((endp + 1) < (buf + count)) || (val > 1)) - return -EINVAL; - - spin_lock(&dasd_devmap_lock); - if (val) - devmap->features |= DASD_FEATURE_ERPLOG; - else - devmap->features &= ~DASD_FEATURE_ERPLOG; - if (devmap->device) - devmap->device->features = devmap->features; - spin_unlock(&dasd_devmap_lock); - return count; -} - -static DEVICE_ATTR(erplog, 0644, dasd_erplog_show, dasd_erplog_store); /* * use_diag controls whether the driver should use diag rather than ssch @@ -944,7 +896,6 @@ static struct attribute * dasd_attrs[] = { &dev_attr_uid.attr, &dev_attr_use_diag.attr, &dev_attr_eer_enabled.attr, - &dev_attr_erplog.attr, NULL, }; diff --git a/trunk/drivers/s390/block/dasd_int.h b/trunk/drivers/s390/block/dasd_int.h index fb725e3b08fe..dc5dd509434d 100644 --- a/trunk/drivers/s390/block/dasd_int.h +++ b/trunk/drivers/s390/block/dasd_int.h @@ -13,6 +13,10 @@ #ifdef __KERNEL__ +/* erp debugging in dasd.c and dasd_3990_erp.c */ +#define ERP_DEBUG + + /* we keep old device allocation scheme; IOW, minors are still in 0..255 */ #define DASD_PER_MAJOR (1U << (MINORBITS - DASD_PARTN_BITS)) #define DASD_PARTN_MASK ((1 << DASD_PARTN_BITS) - 1) diff --git a/trunk/drivers/s390/block/dasd_ioctl.c b/trunk/drivers/s390/block/dasd_ioctl.c index 758cfb542865..8fed3603e9ea 100644 --- a/trunk/drivers/s390/block/dasd_ioctl.c +++ b/trunk/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_path.dentry->d_inode, filp, cmd, arg); + rval = dasd_ioctl(filp->f_dentry->d_inode, filp, cmd, arg); unlock_kernel(); return (rval == -EINVAL) ? -ENOIOCTLCMD : rval; diff --git a/trunk/drivers/s390/char/ctrlchar.c b/trunk/drivers/s390/char/ctrlchar.c index c6cbcb3f925e..49e9628d9297 100644 --- a/trunk/drivers/s390/char/ctrlchar.c +++ b/trunk/drivers/s390/char/ctrlchar.c @@ -16,15 +16,14 @@ #ifdef CONFIG_MAGIC_SYSRQ static int ctrlchar_sysrq_key; -static struct tty_struct *sysrq_tty; static void -ctrlchar_handle_sysrq(struct work_struct *work) +ctrlchar_handle_sysrq(void *tty) { - handle_sysrq(ctrlchar_sysrq_key, sysrq_tty); + handle_sysrq(ctrlchar_sysrq_key, (struct tty_struct *) tty); } -static DECLARE_WORK(ctrlchar_work, ctrlchar_handle_sysrq); +static DECLARE_WORK(ctrlchar_work, ctrlchar_handle_sysrq, NULL); #endif @@ -54,7 +53,7 @@ ctrlchar_handle(const unsigned char *buf, int len, struct tty_struct *tty) /* racy */ if (len == 3 && buf[1] == '-') { ctrlchar_sysrq_key = buf[2]; - sysrq_tty = tty; + ctrlchar_work.data = tty; schedule_work(&ctrlchar_work); return CTRLCHAR_SYSRQ; } diff --git a/trunk/drivers/s390/char/fs3270.c b/trunk/drivers/s390/char/fs3270.c index 0893d306ae80..78f8bda81dae 100644 --- a/trunk/drivers/s390/char/fs3270.c +++ b/trunk/drivers/s390/char/fs3270.c @@ -419,20 +419,16 @@ fs3270_open(struct inode *inode, struct file *filp) struct idal_buffer *ib; int minor, rc; - if (imajor(filp->f_path.dentry->d_inode) != IBM_FS3270_MAJOR) + if (imajor(filp->f_dentry->d_inode) != IBM_FS3270_MAJOR) return -ENODEV; - minor = iminor(filp->f_path.dentry->d_inode); + minor = iminor(filp->f_dentry->d_inode); /* Check for minor 0 multiplexer. */ if (minor == 0) { - struct tty_struct *tty; - mutex_lock(&tty_mutex); - tty = get_current_tty(); - if (!tty || tty->driver->major != IBM_TTY3270_MAJOR) { - mutex_unlock(&tty_mutex); + if (!current->signal->tty) return -ENODEV; - } - minor = tty->index + RAW3270_FIRSTMINOR; - mutex_unlock(&tty_mutex); + if (current->signal->tty->driver->major != IBM_TTY3270_MAJOR) + return -ENODEV; + minor = current->signal->tty->index + RAW3270_FIRSTMINOR; } /* Check if some other program is already using fullscreen mode. */ fp = (struct fs3270 *) raw3270_find_view(&fs3270_fn, minor); diff --git a/trunk/drivers/s390/char/sclp_tty.c b/trunk/drivers/s390/char/sclp_tty.c index 2d173e5c8a09..6f43e04dbefd 100644 --- a/trunk/drivers/s390/char/sclp_tty.c +++ b/trunk/drivers/s390/char/sclp_tty.c @@ -60,6 +60,8 @@ 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/trunk/drivers/s390/char/tape.h b/trunk/drivers/s390/char/tape.h index c9f1c4c8bb13..1f4c89967be4 100644 --- a/trunk/drivers/s390/char/tape.h +++ b/trunk/drivers/s390/char/tape.h @@ -179,7 +179,6 @@ struct tape_char_data { /* Block Frontend Data */ struct tape_blk_data { - struct tape_device * device; /* Block device request queue. */ request_queue_t * request_queue; spinlock_t request_queue_lock; @@ -241,7 +240,7 @@ struct tape_device { #endif /* Function to start or stop the next request later. */ - struct delayed_work tape_dnr; + struct work_struct tape_dnr; }; /* Externals from tape_core.c */ diff --git a/trunk/drivers/s390/char/tape_34xx.c b/trunk/drivers/s390/char/tape_34xx.c index e765875e8db2..7b95dab913d0 100644 --- a/trunk/drivers/s390/char/tape_34xx.c +++ b/trunk/drivers/s390/char/tape_34xx.c @@ -95,12 +95,6 @@ tape_34xx_medium_sense(struct tape_device *device) return rc; } -struct tape_34xx_work { - struct tape_device *device; - enum tape_op op; - struct work_struct work; -}; - /* * These functions are currently used only to schedule a medium_sense for * later execution. This is because we get an interrupt whenever a medium @@ -109,10 +103,13 @@ struct tape_34xx_work { * interrupt handler. */ static void -tape_34xx_work_handler(struct work_struct *work) +tape_34xx_work_handler(void *data) { - struct tape_34xx_work *p = - container_of(work, struct tape_34xx_work, work); + struct { + struct tape_device *device; + enum tape_op op; + struct work_struct work; + } *p = data; switch(p->op) { case TO_MSEN: @@ -129,13 +126,17 @@ tape_34xx_work_handler(struct work_struct *work) static int tape_34xx_schedule_work(struct tape_device *device, enum tape_op op) { - struct tape_34xx_work *p; + struct { + struct tape_device *device; + enum tape_op op; + struct work_struct work; + } *p; if ((p = kmalloc(sizeof(*p), GFP_ATOMIC)) == NULL) return -ENOMEM; memset(p, 0, sizeof(*p)); - INIT_WORK(&p->work, tape_34xx_work_handler); + INIT_WORK(&p->work, tape_34xx_work_handler, p); p->device = tape_get_device_reference(device); p->op = op; diff --git a/trunk/drivers/s390/char/tape_3590.c b/trunk/drivers/s390/char/tape_3590.c index 9df912f63188..928cbefc49d5 100644 --- a/trunk/drivers/s390/char/tape_3590.c +++ b/trunk/drivers/s390/char/tape_3590.c @@ -236,10 +236,9 @@ struct work_handler_data { }; static void -tape_3590_work_handler(struct work_struct *work) +tape_3590_work_handler(void *data) { - struct work_handler_data *p = - container_of(work, struct work_handler_data, work); + struct work_handler_data *p = data; switch (p->op) { case TO_MSEN: @@ -264,7 +263,7 @@ tape_3590_schedule_work(struct tape_device *device, enum tape_op op) if ((p = kzalloc(sizeof(*p), GFP_ATOMIC)) == NULL) return -ENOMEM; - INIT_WORK(&p->work, tape_3590_work_handler); + INIT_WORK(&p->work, tape_3590_work_handler, p); p->device = tape_get_device_reference(device); p->op = op; diff --git a/trunk/drivers/s390/char/tape_block.c b/trunk/drivers/s390/char/tape_block.c index c8a89b3b87d4..3225fcd1dcb4 100644 --- a/trunk/drivers/s390/char/tape_block.c +++ b/trunk/drivers/s390/char/tape_block.c @@ -15,7 +15,6 @@ #include #include #include -#include #include @@ -144,8 +143,7 @@ tapeblock_start_request(struct tape_device *device, struct request *req) * queue. */ static void -tapeblock_requeue(struct work_struct *work) { - struct tape_blk_data * blkdat; +tapeblock_requeue(void *data) { struct tape_device * device; request_queue_t * queue; int nr_queued; @@ -153,8 +151,7 @@ tapeblock_requeue(struct work_struct *work) { struct list_head * l; int rc; - blkdat = container_of(work, struct tape_blk_data, requeue_task); - device = blkdat->device; + device = (struct tape_device *) data; if (!device) return; @@ -215,7 +212,6 @@ tapeblock_setup_device(struct tape_device * device) int rc; blkdat = &device->blk_data; - blkdat->device = device; spin_lock_init(&blkdat->request_queue_lock); atomic_set(&blkdat->requeue_scheduled, 0); @@ -259,8 +255,8 @@ tapeblock_setup_device(struct tape_device * device) add_disk(disk); - tape_get_device_reference(device); - INIT_WORK(&blkdat->requeue_task, tapeblock_requeue); + INIT_WORK(&blkdat->requeue_task, tapeblock_requeue, + tape_get_device_reference(device)); return 0; @@ -275,7 +271,7 @@ void tapeblock_cleanup_device(struct tape_device *device) { flush_scheduled_work(); - tape_put_device(device); + device->blk_data.requeue_task.data = tape_put_device(device); if (!device->blk_data.disk) { PRINT_ERR("(%s): No gendisk to clean up!\n", diff --git a/trunk/drivers/s390/char/tape_char.c b/trunk/drivers/s390/char/tape_char.c index 31198c8f2718..97f75237bed6 100644 --- a/trunk/drivers/s390/char/tape_char.c +++ b/trunk/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_path.dentry->d_inode), - iminor(filp->f_path.dentry->d_inode)); + imajor(filp->f_dentry->d_inode), + iminor(filp->f_dentry->d_inode)); - if (imajor(filp->f_path.dentry->d_inode) != tapechar_major) + if (imajor(filp->f_dentry->d_inode) != tapechar_major) return -ENODEV; - minor = iminor(filp->f_path.dentry->d_inode); + minor = iminor(filp->f_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/trunk/drivers/s390/char/tape_core.c b/trunk/drivers/s390/char/tape_core.c index c6c2e918b990..2826aed91043 100644 --- a/trunk/drivers/s390/char/tape_core.c +++ b/trunk/drivers/s390/char/tape_core.c @@ -28,7 +28,7 @@ #define PRINTK_HEADER "TAPE_CORE: " static void __tape_do_irq (struct ccw_device *, unsigned long, struct irb *); -static void tape_delayed_next_request(struct work_struct *); +static void tape_delayed_next_request(void * data); /* * One list to contain all tape devices of all disciplines, so @@ -272,7 +272,7 @@ __tape_cancel_io(struct tape_device *device, struct tape_request *request) return 0; case -EBUSY: request->status = TAPE_REQUEST_CANCEL; - schedule_delayed_work(&device->tape_dnr, 0); + schedule_work(&device->tape_dnr); return 0; case -ENODEV: DBF_EXCEPTION(2, "device gone, retry\n"); @@ -470,7 +470,7 @@ tape_alloc_device(void) *device->modeset_byte = 0; device->first_minor = -1; atomic_set(&device->ref_count, 1); - INIT_DELAYED_WORK(&device->tape_dnr, tape_delayed_next_request); + INIT_WORK(&device->tape_dnr, tape_delayed_next_request, device); return device; } @@ -724,7 +724,7 @@ __tape_start_io(struct tape_device *device, struct tape_request *request) } else if (rc == -EBUSY) { /* The common I/O subsystem is currently busy. Retry later. */ request->status = TAPE_REQUEST_QUEUED; - schedule_delayed_work(&device->tape_dnr, 0); + schedule_work(&device->tape_dnr); rc = 0; } else { /* Start failed. Remove request and indicate failure. */ @@ -790,11 +790,11 @@ __tape_start_next_request(struct tape_device *device) } static void -tape_delayed_next_request(struct work_struct *work) +tape_delayed_next_request(void *data) { - struct tape_device *device = - container_of(work, struct tape_device, tape_dnr.work); + struct tape_device * device; + device = (struct tape_device *) data; DBF_LH(6, "tape_delayed_next_request(%p)\n", device); spin_lock_irq(get_ccwdev_lock(device->cdev)); __tape_start_next_request(device); diff --git a/trunk/drivers/s390/char/tty3270.c b/trunk/drivers/s390/char/tty3270.c index 09844621edc0..4717c3611601 100644 --- a/trunk/drivers/s390/char/tty3270.c +++ b/trunk/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 ktermios *old) +tty3270_set_termios(struct tty_struct *tty, struct termios *old) { struct tty3270 *tp; int new; diff --git a/trunk/drivers/s390/cio/chsc.c b/trunk/drivers/s390/cio/chsc.c index cbab8d2ce5cf..dbfb77b03928 100644 --- a/trunk/drivers/s390/cio/chsc.c +++ b/trunk/drivers/s390/cio/chsc.c @@ -183,7 +183,7 @@ css_get_ssd_info(struct subchannel *sch) page = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA); if (!page) return -ENOMEM; - spin_lock_irq(sch->lock); + spin_lock_irq(&sch->lock); ret = chsc_get_sch_desc_irq(sch, page); if (ret) { static int cio_chsc_err_msg; @@ -197,7 +197,7 @@ css_get_ssd_info(struct subchannel *sch) cio_chsc_err_msg = 1; } } - spin_unlock_irq(sch->lock); + spin_unlock_irq(&sch->lock); free_page((unsigned long)page); if (!ret) { int j, chpid, mask; @@ -233,7 +233,7 @@ s390_subchannel_remove_chpid(struct device *dev, void *data) if (j >= 8) return 0; - spin_lock_irq(sch->lock); + spin_lock_irq(&sch->lock); stsch(sch->schid, &schib); if (!schib.pmcw.dnv) @@ -265,10 +265,10 @@ s390_subchannel_remove_chpid(struct device *dev, void *data) else if (sch->lpm == mask) goto out_unreg; out_unlock: - spin_unlock_irq(sch->lock); + spin_unlock_irq(&sch->lock); return 0; out_unreg: - spin_unlock_irq(sch->lock); + spin_unlock_irq(&sch->lock); sch->lpm = 0; if (css_enqueue_subchannel_slow(sch->schid)) { css_clear_subchannel_slow_list(); @@ -378,12 +378,12 @@ __s390_process_res_acc(struct subchannel_id schid, void *data) /* Check if a subchannel is newly available. */ return s390_process_res_acc_new_sch(schid); - spin_lock_irq(sch->lock); + spin_lock_irq(&sch->lock); chp_mask = s390_process_res_acc_sch(res_data, sch); if (chp_mask == 0) { - spin_unlock_irq(sch->lock); + spin_unlock_irq(&sch->lock); put_device(&sch->dev); return 0; } @@ -397,7 +397,7 @@ __s390_process_res_acc(struct subchannel_id schid, void *data) else if (sch->driver && sch->driver->verify) sch->driver->verify(&sch->dev); - spin_unlock_irq(sch->lock); + spin_unlock_irq(&sch->lock); put_device(&sch->dev); return 0; } @@ -635,21 +635,21 @@ __chp_add(struct subchannel_id schid, void *data) if (!sch) /* Check if the subchannel is now available. */ return __chp_add_new_sch(schid); - spin_lock_irq(sch->lock); + spin_lock_irq(&sch->lock); for (i=0; i<8; i++) { mask = 0x80 >> i; if ((sch->schib.pmcw.pim & mask) && (sch->schib.pmcw.chpid[i] == chp->id)) { if (stsch(sch->schid, &sch->schib) != 0) { /* Endgame. */ - spin_unlock_irq(sch->lock); + spin_unlock_irq(&sch->lock); return -ENXIO; } break; } } if (i==8) { - spin_unlock_irq(sch->lock); + spin_unlock_irq(&sch->lock); return 0; } sch->lpm = ((sch->schib.pmcw.pim & @@ -660,7 +660,7 @@ __chp_add(struct subchannel_id schid, void *data) if (sch->driver && sch->driver->verify) sch->driver->verify(&sch->dev); - spin_unlock_irq(sch->lock); + spin_unlock_irq(&sch->lock); put_device(&sch->dev); return 0; } @@ -750,7 +750,7 @@ __s390_subchannel_vary_chpid(struct subchannel *sch, __u8 chpid, int on) if (!sch->ssd_info.valid) return; - spin_lock_irqsave(sch->lock, flags); + spin_lock_irqsave(&sch->lock, flags); old_lpm = sch->lpm; for (chp = 0; chp < 8; chp++) { if (sch->ssd_info.chpid[chp] != chpid) @@ -785,7 +785,7 @@ __s390_subchannel_vary_chpid(struct subchannel *sch, __u8 chpid, int on) sch->driver->verify(&sch->dev); break; } - spin_unlock_irqrestore(sch->lock, flags); + spin_unlock_irqrestore(&sch->lock, flags); } static int diff --git a/trunk/drivers/s390/cio/cio.c b/trunk/drivers/s390/cio/cio.c index 7835a714a405..20aee2783847 100644 --- a/trunk/drivers/s390/cio/cio.c +++ b/trunk/drivers/s390/cio/cio.c @@ -143,11 +143,11 @@ cio_tpi(void) return 1; local_bh_disable(); irq_enter (); - spin_lock(sch->lock); + spin_lock(&sch->lock); memcpy (&sch->schib.scsw, &irb->scsw, sizeof (struct scsw)); if (sch->driver && sch->driver->irq) sch->driver->irq(&sch->dev); - spin_unlock(sch->lock); + spin_unlock(&sch->lock); irq_exit (); _local_bh_enable(); return 1; @@ -415,8 +415,6 @@ cio_enable_subchannel (struct subchannel *sch, unsigned int isc) CIO_TRACE_EVENT (2, "ensch"); CIO_TRACE_EVENT (2, sch->dev.bus_id); - if (sch_is_pseudo_sch(sch)) - return -EINVAL; ccode = stsch (sch->schid, &sch->schib); if (ccode) return -ENODEV; @@ -464,8 +462,6 @@ cio_disable_subchannel (struct subchannel *sch) CIO_TRACE_EVENT (2, "dissch"); CIO_TRACE_EVENT (2, sch->dev.bus_id); - if (sch_is_pseudo_sch(sch)) - return 0; ccode = stsch (sch->schid, &sch->schib); if (ccode == 3) /* Not operational. */ return -ENODEV; @@ -500,15 +496,6 @@ cio_disable_subchannel (struct subchannel *sch) return ret; } -int cio_create_sch_lock(struct subchannel *sch) -{ - sch->lock = kmalloc(sizeof(spinlock_t), GFP_KERNEL); - if (!sch->lock) - return -ENOMEM; - spin_lock_init(sch->lock); - return 0; -} - /* * cio_validate_subchannel() * @@ -526,7 +513,6 @@ cio_validate_subchannel (struct subchannel *sch, struct subchannel_id schid) { char dbf_txt[15]; int ccode; - int err; sprintf (dbf_txt, "valsch%x", schid.sch_no); CIO_TRACE_EVENT (4, dbf_txt); @@ -534,15 +520,9 @@ cio_validate_subchannel (struct subchannel *sch, struct subchannel_id schid) /* Nuke all fields. */ memset(sch, 0, sizeof(struct subchannel)); - sch->schid = schid; - if (cio_is_console(schid)) { - sch->lock = cio_get_console_lock(); - } else { - err = cio_create_sch_lock(sch); - if (err) - goto out; - } + spin_lock_init(&sch->lock); mutex_init(&sch->reg_mutex); + /* Set a name for the subchannel */ snprintf (sch->dev.bus_id, BUS_ID_SIZE, "0.%x.%04x", schid.ssid, schid.sch_no); @@ -554,10 +534,10 @@ cio_validate_subchannel (struct subchannel *sch, struct subchannel_id schid) * is not valid. */ ccode = stsch_err (schid, &sch->schib); - if (ccode) { - err = (ccode == 3) ? -ENXIO : ccode; - goto out; - } + if (ccode) + return (ccode == 3) ? -ENXIO : ccode; + + sch->schid = schid; /* Copy subchannel type from path management control word. */ sch->st = sch->schib.pmcw.st; @@ -570,16 +550,14 @@ cio_validate_subchannel (struct subchannel *sch, struct subchannel_id schid) "non-I/O subchannel type %04X\n", sch->schid.ssid, sch->schid.sch_no, sch->st); /* We stop here for non-io subchannels. */ - err = sch->st; - goto out; + return sch->st; } /* Initialization for io subchannels. */ - if (!sch->schib.pmcw.dnv) { + if (!sch->schib.pmcw.dnv) /* io subchannel but device number is invalid. */ - err = -ENODEV; - goto out; - } + return -ENODEV; + /* Devno is valid. */ if (is_blacklisted (sch->schid.ssid, sch->schib.pmcw.dev)) { /* @@ -589,8 +567,7 @@ cio_validate_subchannel (struct subchannel *sch, struct subchannel_id schid) CIO_MSG_EVENT(0, "Blacklisted device detected " "at devno %04X, subchannel set %x\n", sch->schib.pmcw.dev, sch->schid.ssid); - err = -ENODEV; - goto out; + return -ENODEV; } sch->opm = 0xff; if (!cio_is_console(sch->schid)) @@ -618,11 +595,6 @@ cio_validate_subchannel (struct subchannel *sch, struct subchannel_id schid) if ((sch->lpm & (sch->lpm - 1)) != 0) sch->schib.pmcw.mp = 1; /* multipath mode */ return 0; -out: - if (!cio_is_console(schid)) - kfree(sch->lock); - sch->lock = NULL; - return err; } /* @@ -665,7 +637,7 @@ do_IRQ (struct pt_regs *regs) } sch = (struct subchannel *)(unsigned long)tpi_info->intparm; if (sch) - spin_lock(sch->lock); + spin_lock(&sch->lock); /* Store interrupt response block to lowcore. */ if (tsch (tpi_info->schid, irb) == 0 && sch) { /* Keep subchannel information word up to date. */ @@ -676,7 +648,7 @@ do_IRQ (struct pt_regs *regs) sch->driver->irq(&sch->dev); } if (sch) - spin_unlock(sch->lock); + spin_unlock(&sch->lock); /* * Are more interrupts pending? * If so, the tpi instruction will update the lowcore @@ -715,10 +687,10 @@ wait_cons_dev (void) __ctl_load (cr6, 6, 6); do { - spin_unlock(console_subchannel.lock); + spin_unlock(&console_subchannel.lock); if (!cio_tpi()) cpu_relax(); - spin_lock(console_subchannel.lock); + spin_lock(&console_subchannel.lock); } while (console_subchannel.schib.scsw.actl != 0); /* * restore previous isc value diff --git a/trunk/drivers/s390/cio/cio.h b/trunk/drivers/s390/cio/cio.h index 35154a210357..4541c1af4b66 100644 --- a/trunk/drivers/s390/cio/cio.h +++ b/trunk/drivers/s390/cio/cio.h @@ -87,7 +87,7 @@ struct orb { /* subchannel data structure used by I/O subroutines */ struct subchannel { struct subchannel_id schid; - spinlock_t *lock; /* subchannel lock */ + spinlock_t lock; /* subchannel lock */ struct mutex reg_mutex; enum { SUBCHANNEL_TYPE_IO = 0, @@ -131,19 +131,15 @@ extern int cio_set_options (struct subchannel *, int); extern int cio_get_options (struct subchannel *); extern int cio_modify (struct subchannel *); -int cio_create_sch_lock(struct subchannel *); - /* Use with care. */ #ifdef CONFIG_CCW_CONSOLE extern struct subchannel *cio_probe_console(void); extern void cio_release_console(void); extern int cio_is_console(struct subchannel_id); extern struct subchannel *cio_get_console_subchannel(void); -extern spinlock_t * cio_get_console_lock(void); #else #define cio_is_console(schid) 0 #define cio_get_console_subchannel() NULL -#define cio_get_console_lock() NULL; #endif extern int cio_show_msg; diff --git a/trunk/drivers/s390/cio/css.c b/trunk/drivers/s390/cio/css.c index 4c81d890791e..26cf2f5ae2e7 100644 --- a/trunk/drivers/s390/cio/css.c +++ b/trunk/drivers/s390/cio/css.c @@ -91,9 +91,9 @@ css_free_subchannel(struct subchannel *sch) /* Reset intparm to zeroes. */ sch->schib.pmcw.intparm = 0; cio_modify(sch); - kfree(sch->lock); kfree(sch); } + } static void @@ -102,10 +102,8 @@ css_subchannel_release(struct device *dev) struct subchannel *sch; sch = to_subchannel(dev); - if (!cio_is_console(sch->schid)) { - kfree(sch->lock); + if (!cio_is_console(sch->schid)) kfree(sch); - } } extern int css_get_ssd_info(struct subchannel *sch); @@ -137,16 +135,14 @@ css_register_subchannel(struct subchannel *sch) sch->dev.parent = &css[0]->device; sch->dev.bus = &css_bus_type; sch->dev.release = &css_subchannel_release; - sch->dev.groups = subch_attr_groups; - + /* make it known to the system */ ret = css_sch_device_register(sch); - if (ret) { + if (ret) printk (KERN_WARNING "%s: could not register %s\n", __func__, sch->dev.bus_id); - return ret; - } - css_get_ssd_info(sch); + else + css_get_ssd_info(sch); return ret; } @@ -205,18 +201,18 @@ static int css_evaluate_known_subchannel(struct subchannel *sch, int slow) unsigned long flags; enum { NONE, UNREGISTER, UNREGISTER_PROBE, REPROBE } action; - spin_lock_irqsave(sch->lock, flags); + spin_lock_irqsave(&sch->lock, flags); disc = device_is_disconnected(sch); if (disc && slow) { /* Disconnected devices are evaluated directly only.*/ - spin_unlock_irqrestore(sch->lock, flags); + spin_unlock_irqrestore(&sch->lock, flags); return 0; } /* No interrupt after machine check - kill pending timers. */ device_kill_pending_timer(sch); if (!disc && !slow) { /* Non-disconnected devices are evaluated on the slow path. */ - spin_unlock_irqrestore(sch->lock, flags); + spin_unlock_irqrestore(&sch->lock, flags); return -EAGAIN; } event = css_get_subchannel_status(sch); @@ -241,9 +237,9 @@ static int css_evaluate_known_subchannel(struct subchannel *sch, int slow) /* Ask driver what to do with device. */ action = UNREGISTER; if (sch->driver && sch->driver->notify) { - spin_unlock_irqrestore(sch->lock, flags); + spin_unlock_irqrestore(&sch->lock, flags); ret = sch->driver->notify(&sch->dev, event); - spin_lock_irqsave(sch->lock, flags); + spin_lock_irqsave(&sch->lock, flags); if (ret) action = NONE; } @@ -268,9 +264,9 @@ static int css_evaluate_known_subchannel(struct subchannel *sch, int slow) case UNREGISTER: case UNREGISTER_PROBE: /* Unregister device (will use subchannel lock). */ - spin_unlock_irqrestore(sch->lock, flags); + spin_unlock_irqrestore(&sch->lock, flags); css_sch_device_unregister(sch); - spin_lock_irqsave(sch->lock, flags); + spin_lock_irqsave(&sch->lock, flags); /* Reset intparm to zeroes. */ sch->schib.pmcw.intparm = 0; @@ -282,7 +278,7 @@ static int css_evaluate_known_subchannel(struct subchannel *sch, int slow) default: break; } - spin_unlock_irqrestore(sch->lock, flags); + spin_unlock_irqrestore(&sch->lock, flags); /* Probe if necessary. */ if (action == UNREGISTER_PROBE) ret = css_probe_device(sch->schid); @@ -577,24 +573,12 @@ css_cm_enable_store(struct device *dev, struct device_attribute *attr, static DEVICE_ATTR(cm_enable, 0644, css_cm_enable_show, css_cm_enable_store); -static inline int __init setup_css(int nr) +static inline void __init +setup_css(int nr) { u32 tod_high; - int ret; memset(css[nr], 0, sizeof(struct channel_subsystem)); - css[nr]->pseudo_subchannel = - kzalloc(sizeof(*css[nr]->pseudo_subchannel), GFP_KERNEL); - if (!css[nr]->pseudo_subchannel) - return -ENOMEM; - css[nr]->pseudo_subchannel->dev.parent = &css[nr]->device; - css[nr]->pseudo_subchannel->dev.release = css_subchannel_release; - sprintf(css[nr]->pseudo_subchannel->dev.bus_id, "defunct"); - ret = cio_create_sch_lock(css[nr]->pseudo_subchannel); - if (ret) { - kfree(css[nr]->pseudo_subchannel); - return ret; - } mutex_init(&css[nr]->mutex); css[nr]->valid = 1; css[nr]->cssid = nr; @@ -602,7 +586,6 @@ static inline int __init setup_css(int nr) css[nr]->device.release = channel_subsystem_release; tod_high = (u32) (get_clock() >> 32); css_generate_pgid(css[nr], tod_high); - return 0; } /* @@ -639,12 +622,10 @@ init_channel_subsystem (void) ret = -ENOMEM; goto out_unregister; } - ret = setup_css(i); - if (ret) - goto out_free; + setup_css(i); ret = device_register(&css[i]->device); if (ret) - goto out_free_all; + goto out_free; if (css_characteristics_avail && css_chsc_characteristics.secm) { ret = device_create_file(&css[i]->device, @@ -652,9 +633,6 @@ init_channel_subsystem (void) if (ret) goto out_device; } - ret = device_register(&css[i]->pseudo_subchannel->dev); - if (ret) - goto out_file; } css_init_done = 1; @@ -662,19 +640,13 @@ init_channel_subsystem (void) for_each_subchannel(__init_channel_subsystem, NULL); return 0; -out_file: - device_remove_file(&css[i]->device, &dev_attr_cm_enable); out_device: device_unregister(&css[i]->device); -out_free_all: - kfree(css[i]->pseudo_subchannel->lock); - kfree(css[i]->pseudo_subchannel); out_free: kfree(css[i]); out_unregister: while (i > 0) { i--; - device_unregister(&css[i]->pseudo_subchannel->dev); if (css_characteristics_avail && css_chsc_characteristics.secm) device_remove_file(&css[i]->device, &dev_attr_cm_enable); @@ -686,11 +658,6 @@ init_channel_subsystem (void) return ret; } -int sch_is_pseudo_sch(struct subchannel *sch) -{ - return sch == to_css(sch->dev.parent)->pseudo_subchannel; -} - /* * find a driver for a subchannel. They identify by the subchannel * type with the exception that the console subchannel driver has its own diff --git a/trunk/drivers/s390/cio/css.h b/trunk/drivers/s390/cio/css.h index 3464c5b875c4..9ff064e71767 100644 --- a/trunk/drivers/s390/cio/css.h +++ b/trunk/drivers/s390/cio/css.h @@ -73,8 +73,6 @@ struct senseid { } __attribute__ ((packed,aligned(4))); struct ccw_device_private { - struct ccw_device *cdev; - struct subchannel *sch; int state; /* device state */ atomic_t onoff; unsigned long registered; @@ -160,8 +158,6 @@ struct channel_subsystem { int cm_enabled; void *cub_addr1; void *cub_addr2; - /* for orphaned ccw devices */ - struct subchannel *pseudo_subchannel; }; #define to_css(dev) container_of(dev, struct channel_subsystem, device) @@ -189,11 +185,6 @@ void css_clear_subchannel_slow_list(void); int css_slow_subchannels_exist(void); extern int need_rescan; -int sch_is_pseudo_sch(struct subchannel *); - extern struct workqueue_struct *slow_path_wq; extern struct work_struct slow_path_work; - -int subchannel_add_files (struct device *); -extern struct attribute_group *subch_attr_groups[]; #endif diff --git a/trunk/drivers/s390/cio/device.c b/trunk/drivers/s390/cio/device.c index 803579053c2f..d3d3716ff84b 100644 --- a/trunk/drivers/s390/cio/device.c +++ b/trunk/drivers/s390/cio/device.c @@ -23,7 +23,6 @@ #include /* HZ */ #include "cio.h" -#include "cio_debug.h" #include "css.h" #include "device.h" #include "ioasm.h" @@ -235,11 +234,9 @@ chpids_show (struct device * dev, struct device_attribute *attr, char * buf) ssize_t ret = 0; int chp; - if (ssd) - for (chp = 0; chp < 8; chp++) - ret += sprintf (buf+ret, "%02x ", ssd->chpid[chp]); - else - ret += sprintf (buf, "n/a"); + for (chp = 0; chp < 8; chp++) + ret += sprintf (buf+ret, "%02x ", ssd->chpid[chp]); + ret += sprintf (buf+ret, "\n"); return min((ssize_t)PAGE_SIZE, ret); } @@ -297,44 +294,14 @@ online_show (struct device *dev, struct device_attribute *attr, char *buf) return sprintf(buf, cdev->online ? "1\n" : "0\n"); } -int ccw_device_is_orphan(struct ccw_device *cdev) -{ - return sch_is_pseudo_sch(to_subchannel(cdev->dev.parent)); -} - -static void ccw_device_unregister(struct work_struct *work) -{ - struct ccw_device_private *priv; - struct ccw_device *cdev; - - priv = container_of(work, struct ccw_device_private, kick_work); - cdev = priv->cdev; - if (test_and_clear_bit(1, &cdev->private->registered)) - device_unregister(&cdev->dev); - put_device(&cdev->dev); -} - static void ccw_device_remove_disconnected(struct ccw_device *cdev) { struct subchannel *sch; - unsigned long flags; /* * Forced offline in disconnected state means * 'throw away device'. */ - if (ccw_device_is_orphan(cdev)) { - /* Deregister ccw device. */ - spin_lock_irqsave(cdev->ccwlock, flags); - cdev->private->state = DEV_STATE_NOT_OPER; - spin_unlock_irqrestore(cdev->ccwlock, flags); - if (get_device(&cdev->dev)) { - PREPARE_WORK(&cdev->private->kick_work, - ccw_device_unregister); - queue_work(ccw_device_work, &cdev->private->kick_work); - } - return ; - } sch = to_subchannel(cdev->dev.parent); css_sch_device_unregister(sch); /* Reset intparm to zeroes. */ @@ -495,8 +462,6 @@ available_show (struct device *dev, struct device_attribute *attr, char *buf) struct ccw_device *cdev = to_ccwdev(dev); struct subchannel *sch; - if (ccw_device_is_orphan(cdev)) - return sprintf(buf, "no device\n"); switch (cdev->private->state) { case DEV_STATE_BOXED: return sprintf(buf, "boxed\n"); @@ -533,10 +498,11 @@ static struct attribute_group subch_attr_group = { .attrs = subch_attrs, }; -struct attribute_group *subch_attr_groups[] = { - &subch_attr_group, - NULL, -}; +static inline int +subchannel_add_files (struct device *dev) +{ + return sysfs_create_group(&dev->kobj, &subch_attr_group); +} static struct attribute * ccwdev_attrs[] = { &dev_attr_devtype.attr, @@ -597,10 +563,11 @@ match_devno(struct device * dev, void * data) cdev = to_ccwdev(dev); if ((cdev->private->state == DEV_STATE_DISCONNECTED) && - !ccw_device_is_orphan(cdev) && ccw_dev_id_is_equal(&cdev->private->dev_id, &d->dev_id) && - (cdev != d->sibling)) + (cdev != d->sibling)) { + cdev->private->state = DEV_STATE_NOT_OPER; return 1; + } return 0; } @@ -617,36 +584,13 @@ static struct ccw_device * get_disc_ccwdev_by_dev_id(struct ccw_dev_id *dev_id, return dev ? to_ccwdev(dev) : NULL; } -static int match_orphan(struct device *dev, void *data) -{ - struct ccw_dev_id *dev_id; - struct ccw_device *cdev; - - dev_id = data; - cdev = to_ccwdev(dev); - return ccw_dev_id_is_equal(&cdev->private->dev_id, dev_id); -} - -static struct ccw_device * -get_orphaned_ccwdev_by_dev_id(struct channel_subsystem *css, - struct ccw_dev_id *dev_id) -{ - struct device *dev; - - dev = device_find_child(&css->pseudo_subchannel->dev, dev_id, - match_orphan); - - return dev ? to_ccwdev(dev) : NULL; -} - static void -ccw_device_add_changed(struct work_struct *work) +ccw_device_add_changed(void *data) { - struct ccw_device_private *priv; + struct ccw_device *cdev; - priv = container_of(work, struct ccw_device_private, kick_work); - cdev = priv->cdev; + cdev = data; if (device_add(&cdev->dev)) { put_device(&cdev->dev); return; @@ -658,21 +602,64 @@ ccw_device_add_changed(struct work_struct *work) } } -void ccw_device_do_unreg_rereg(struct work_struct *work) +extern int css_get_ssd_info(struct subchannel *sch); + +void +ccw_device_do_unreg_rereg(void *data) { - struct ccw_device_private *priv; struct ccw_device *cdev; struct subchannel *sch; + int need_rename; - priv = container_of(work, struct ccw_device_private, kick_work); - cdev = priv->cdev; + cdev = data; sch = to_subchannel(cdev->dev.parent); - + if (cdev->private->dev_id.devno != sch->schib.pmcw.dev) { + /* + * The device number has changed. This is usually only when + * a device has been detached under VM and then re-appeared + * on another subchannel because of a different attachment + * order than before. Ideally, we should should just switch + * subchannels, but unfortunately, this is not possible with + * the current implementation. + * Instead, we search for the old subchannel for this device + * number and deregister so there are no collisions with the + * newly registered ccw_device. + * FIXME: Find another solution so the block layer doesn't + * get possibly sick... + */ + struct ccw_device *other_cdev; + struct ccw_dev_id dev_id; + + need_rename = 1; + dev_id.devno = sch->schib.pmcw.dev; + dev_id.ssid = sch->schid.ssid; + other_cdev = get_disc_ccwdev_by_dev_id(&dev_id, cdev); + if (other_cdev) { + struct subchannel *other_sch; + + other_sch = to_subchannel(other_cdev->dev.parent); + if (get_device(&other_sch->dev)) { + stsch(other_sch->schid, &other_sch->schib); + if (other_sch->schib.pmcw.dnv) { + other_sch->schib.pmcw.intparm = 0; + cio_modify(other_sch); + } + css_sch_device_unregister(other_sch); + } + } + /* Update ssd info here. */ + css_get_ssd_info(sch); + cdev->private->dev_id.devno = sch->schib.pmcw.dev; + } else + need_rename = 0; device_remove_files(&cdev->dev); if (test_and_clear_bit(1, &cdev->private->registered)) device_del(&cdev->dev); + if (need_rename) + snprintf (cdev->dev.bus_id, BUS_ID_SIZE, "0.%x.%04x", + sch->schid.ssid, sch->schib.pmcw.dev); PREPARE_WORK(&cdev->private->kick_work, - ccw_device_add_changed); + ccw_device_add_changed, cdev); queue_work(ccw_device_work, &cdev->private->kick_work); } @@ -686,194 +673,18 @@ ccw_device_release(struct device *dev) kfree(cdev); } -static struct ccw_device * io_subchannel_allocate_dev(struct subchannel *sch) -{ - struct ccw_device *cdev; - - cdev = kzalloc(sizeof(*cdev), GFP_KERNEL); - if (cdev) { - cdev->private = kzalloc(sizeof(struct ccw_device_private), - GFP_KERNEL | GFP_DMA); - if (cdev->private) - return cdev; - } - kfree(cdev); - return ERR_PTR(-ENOMEM); -} - -static int io_subchannel_initialize_dev(struct subchannel *sch, - struct ccw_device *cdev) -{ - cdev->private->cdev = cdev; - atomic_set(&cdev->private->onoff, 0); - cdev->dev.parent = &sch->dev; - cdev->dev.release = ccw_device_release; - INIT_LIST_HEAD(&cdev->private->kick_work.entry); - /* Do first half of device_register. */ - device_initialize(&cdev->dev); - if (!get_device(&sch->dev)) { - if (cdev->dev.release) - cdev->dev.release(&cdev->dev); - return -ENODEV; - } - return 0; -} - -static struct ccw_device * io_subchannel_create_ccwdev(struct subchannel *sch) -{ - struct ccw_device *cdev; - int ret; - - cdev = io_subchannel_allocate_dev(sch); - if (!IS_ERR(cdev)) { - ret = io_subchannel_initialize_dev(sch, cdev); - if (ret) { - kfree(cdev); - cdev = ERR_PTR(ret); - } - } - return cdev; -} - -static int io_subchannel_recog(struct ccw_device *, struct subchannel *); - -static void sch_attach_device(struct subchannel *sch, - struct ccw_device *cdev) -{ - spin_lock_irq(sch->lock); - sch->dev.driver_data = cdev; - cdev->private->schid = sch->schid; - cdev->ccwlock = sch->lock; - device_trigger_reprobe(sch); - spin_unlock_irq(sch->lock); -} - -static void sch_attach_disconnected_device(struct subchannel *sch, - struct ccw_device *cdev) -{ - struct subchannel *other_sch; - int ret; - - other_sch = to_subchannel(get_device(cdev->dev.parent)); - ret = device_move(&cdev->dev, &sch->dev); - if (ret) { - CIO_MSG_EVENT(2, "Moving disconnected device 0.%x.%04x failed " - "(ret=%d)!\n", cdev->private->dev_id.ssid, - cdev->private->dev_id.devno, ret); - put_device(&other_sch->dev); - return; - } - other_sch->dev.driver_data = NULL; - /* No need to keep a subchannel without ccw device around. */ - css_sch_device_unregister(other_sch); - put_device(&other_sch->dev); - sch_attach_device(sch, cdev); -} - -static void sch_attach_orphaned_device(struct subchannel *sch, - struct ccw_device *cdev) -{ - int ret; - - /* Try to move the ccw device to its new subchannel. */ - ret = device_move(&cdev->dev, &sch->dev); - if (ret) { - CIO_MSG_EVENT(0, "Moving device 0.%x.%04x from orphanage " - "failed (ret=%d)!\n", - cdev->private->dev_id.ssid, - cdev->private->dev_id.devno, ret); - return; - } - sch_attach_device(sch, cdev); -} - -static void sch_create_and_recog_new_device(struct subchannel *sch) -{ - struct ccw_device *cdev; - - /* Need to allocate a new ccw device. */ - cdev = io_subchannel_create_ccwdev(sch); - if (IS_ERR(cdev)) { - /* OK, we did everything we could... */ - css_sch_device_unregister(sch); - return; - } - spin_lock_irq(sch->lock); - sch->dev.driver_data = cdev; - spin_unlock_irq(sch->lock); - /* Start recognition for the new ccw device. */ - if (io_subchannel_recog(cdev, sch)) { - spin_lock_irq(sch->lock); - sch->dev.driver_data = NULL; - spin_unlock_irq(sch->lock); - if (cdev->dev.release) - cdev->dev.release(&cdev->dev); - css_sch_device_unregister(sch); - } -} - - -void ccw_device_move_to_orphanage(struct work_struct *work) -{ - struct ccw_device_private *priv; - struct ccw_device *cdev; - struct ccw_device *replacing_cdev; - struct subchannel *sch; - int ret; - struct channel_subsystem *css; - struct ccw_dev_id dev_id; - - priv = container_of(work, struct ccw_device_private, kick_work); - cdev = priv->cdev; - sch = to_subchannel(cdev->dev.parent); - css = to_css(sch->dev.parent); - dev_id.devno = sch->schib.pmcw.dev; - dev_id.ssid = sch->schid.ssid; - - /* - * Move the orphaned ccw device to the orphanage so the replacing - * ccw device can take its place on the subchannel. - */ - ret = device_move(&cdev->dev, &css->pseudo_subchannel->dev); - if (ret) { - CIO_MSG_EVENT(0, "Moving device 0.%x.%04x to orphanage failed " - "(ret=%d)!\n", cdev->private->dev_id.ssid, - cdev->private->dev_id.devno, ret); - return; - } - cdev->ccwlock = css->pseudo_subchannel->lock; - /* - * Search for the replacing ccw device - * - among the disconnected devices - * - in the orphanage - */ - replacing_cdev = get_disc_ccwdev_by_dev_id(&dev_id, cdev); - if (replacing_cdev) { - sch_attach_disconnected_device(sch, replacing_cdev); - return; - } - replacing_cdev = get_orphaned_ccwdev_by_dev_id(css, &dev_id); - if (replacing_cdev) { - sch_attach_orphaned_device(sch, replacing_cdev); - return; - } - sch_create_and_recog_new_device(sch); -} - /* * Register recognized device. */ static void -io_subchannel_register(struct work_struct *work) +io_subchannel_register(void *data) { - struct ccw_device_private *priv; struct ccw_device *cdev; struct subchannel *sch; int ret; unsigned long flags; - priv = container_of(work, struct ccw_device_private, kick_work); - cdev = priv->cdev; + cdev = data; sch = to_subchannel(cdev->dev.parent); /* @@ -898,9 +709,9 @@ io_subchannel_register(struct work_struct *work) printk (KERN_WARNING "%s: could not register %s\n", __func__, cdev->dev.bus_id); put_device(&cdev->dev); - spin_lock_irqsave(sch->lock, flags); + spin_lock_irqsave(&sch->lock, flags); sch->dev.driver_data = NULL; - spin_unlock_irqrestore(sch->lock, flags); + spin_unlock_irqrestore(&sch->lock, flags); kfree (cdev->private); kfree (cdev); put_device(&sch->dev); @@ -908,6 +719,11 @@ io_subchannel_register(struct work_struct *work) wake_up(&ccw_device_init_wq); return; } + + ret = subchannel_add_files(cdev->dev.parent); + if (ret) + printk(KERN_WARNING "%s: could not add attributes to %s\n", + __func__, sch->dev.bus_id); put_device(&cdev->dev); out: cdev->private->flags.recog_done = 1; @@ -918,14 +734,11 @@ io_subchannel_register(struct work_struct *work) } void -ccw_device_call_sch_unregister(struct work_struct *work) +ccw_device_call_sch_unregister(void *data) { - struct ccw_device_private *priv; - struct ccw_device *cdev; + struct ccw_device *cdev = data; struct subchannel *sch; - priv = container_of(work, struct ccw_device_private, kick_work); - cdev = priv->cdev; sch = to_subchannel(cdev->dev.parent); css_sch_device_unregister(sch); /* Reset intparm to zeroes. */ @@ -955,7 +768,7 @@ io_subchannel_recog_done(struct ccw_device *cdev) break; sch = to_subchannel(cdev->dev.parent); PREPARE_WORK(&cdev->private->kick_work, - ccw_device_call_sch_unregister); + ccw_device_call_sch_unregister, cdev); queue_work(slow_path_wq, &cdev->private->kick_work); if (atomic_dec_and_test(&ccw_device_init_count)) wake_up(&ccw_device_init_wq); @@ -970,7 +783,7 @@ io_subchannel_recog_done(struct ccw_device *cdev) if (!get_device(&cdev->dev)) break; PREPARE_WORK(&cdev->private->kick_work, - io_subchannel_register); + io_subchannel_register, cdev); queue_work(slow_path_wq, &cdev->private->kick_work); break; } @@ -984,7 +797,7 @@ io_subchannel_recog(struct ccw_device *cdev, struct subchannel *sch) sch->dev.driver_data = cdev; sch->driver = &io_subchannel_driver; - cdev->ccwlock = sch->lock; + cdev->ccwlock = &sch->lock; /* Init private data. */ priv = cdev->private; @@ -1004,9 +817,9 @@ io_subchannel_recog(struct ccw_device *cdev, struct subchannel *sch) atomic_inc(&ccw_device_init_count); /* Start async. device sensing. */ - spin_lock_irq(sch->lock); + spin_lock_irq(&sch->lock); rc = ccw_device_recognition(cdev); - spin_unlock_irq(sch->lock); + spin_unlock_irq(&sch->lock); if (rc) { if (atomic_dec_and_test(&ccw_device_init_count)) wake_up(&ccw_device_init_wq); @@ -1014,55 +827,12 @@ io_subchannel_recog(struct ccw_device *cdev, struct subchannel *sch) return rc; } -static void ccw_device_move_to_sch(struct work_struct *work) -{ - struct ccw_device_private *priv; - int rc; - struct subchannel *sch; - struct ccw_device *cdev; - struct subchannel *former_parent; - - priv = container_of(work, struct ccw_device_private, kick_work); - sch = priv->sch; - cdev = priv->cdev; - former_parent = ccw_device_is_orphan(cdev) ? - NULL : to_subchannel(get_device(cdev->dev.parent)); - mutex_lock(&sch->reg_mutex); - /* Try to move the ccw device to its new subchannel. */ - rc = device_move(&cdev->dev, &sch->dev); - mutex_unlock(&sch->reg_mutex); - if (rc) { - CIO_MSG_EVENT(2, "Moving device 0.%x.%04x to subchannel " - "0.%x.%04x failed (ret=%d)!\n", - cdev->private->dev_id.ssid, - cdev->private->dev_id.devno, sch->schid.ssid, - sch->schid.sch_no, rc); - css_sch_device_unregister(sch); - goto out; - } - if (former_parent) { - spin_lock_irq(former_parent->lock); - former_parent->dev.driver_data = NULL; - spin_unlock_irq(former_parent->lock); - css_sch_device_unregister(former_parent); - /* Reset intparm to zeroes. */ - former_parent->schib.pmcw.intparm = 0; - cio_modify(former_parent); - } - sch_attach_device(sch, cdev); -out: - if (former_parent) - put_device(&former_parent->dev); - put_device(&cdev->dev); -} - static int io_subchannel_probe (struct subchannel *sch) { struct ccw_device *cdev; int rc; unsigned long flags; - struct ccw_dev_id dev_id; if (sch->dev.driver_data) { /* @@ -1073,6 +843,7 @@ io_subchannel_probe (struct subchannel *sch) cdev = sch->dev.driver_data; device_initialize(&cdev->dev); ccw_device_register(cdev); + subchannel_add_files(&sch->dev); /* * Check if the device is already online. If it is * the reference count needs to be corrected @@ -1085,37 +856,33 @@ io_subchannel_probe (struct subchannel *sch) get_device(&cdev->dev); return 0; } - /* - * First check if a fitting device may be found amongst the - * disconnected devices or in the orphanage. - */ - dev_id.devno = sch->schib.pmcw.dev; - dev_id.ssid = sch->schid.ssid; - cdev = get_disc_ccwdev_by_dev_id(&dev_id, NULL); + cdev = kzalloc (sizeof(*cdev), GFP_KERNEL); if (!cdev) - cdev = get_orphaned_ccwdev_by_dev_id(to_css(sch->dev.parent), - &dev_id); - if (cdev) { - /* - * Schedule moving the device until when we have a registered - * subchannel to move to and succeed the probe. We can - * unregister later again, when the probe is through. - */ - cdev->private->sch = sch; - PREPARE_WORK(&cdev->private->kick_work, - ccw_device_move_to_sch); - queue_work(slow_path_wq, &cdev->private->kick_work); - return 0; + return -ENOMEM; + cdev->private = kzalloc(sizeof(struct ccw_device_private), + GFP_KERNEL | GFP_DMA); + if (!cdev->private) { + kfree(cdev); + return -ENOMEM; + } + atomic_set(&cdev->private->onoff, 0); + cdev->dev.parent = &sch->dev; + cdev->dev.release = ccw_device_release; + INIT_LIST_HEAD(&cdev->private->kick_work.entry); + /* Do first half of device_register. */ + device_initialize(&cdev->dev); + + if (!get_device(&sch->dev)) { + if (cdev->dev.release) + cdev->dev.release(&cdev->dev); + return -ENODEV; } - cdev = io_subchannel_create_ccwdev(sch); - if (IS_ERR(cdev)) - return PTR_ERR(cdev); rc = io_subchannel_recog(cdev, sch); if (rc) { - spin_lock_irqsave(sch->lock, flags); + spin_lock_irqsave(&sch->lock, flags); sch->dev.driver_data = NULL; - spin_unlock_irqrestore(sch->lock, flags); + spin_unlock_irqrestore(&sch->lock, flags); if (cdev->dev.release) cdev->dev.release(&cdev->dev); } @@ -1123,6 +890,17 @@ io_subchannel_probe (struct subchannel *sch) return rc; } +static void +ccw_device_unregister(void *data) +{ + struct ccw_device *cdev; + + cdev = (struct ccw_device *)data; + if (test_and_clear_bit(1, &cdev->private->registered)) + device_unregister(&cdev->dev); + put_device(&cdev->dev); +} + static int io_subchannel_remove (struct subchannel *sch) { @@ -1143,7 +921,7 @@ io_subchannel_remove (struct subchannel *sch) */ if (get_device(&cdev->dev)) { PREPARE_WORK(&cdev->private->kick_work, - ccw_device_unregister); + ccw_device_unregister, cdev); queue_work(ccw_device_work, &cdev->private->kick_work); } return 0; @@ -1225,13 +1003,6 @@ static struct ccw_device console_cdev; static struct ccw_device_private console_private; static int console_cdev_in_use; -static DEFINE_SPINLOCK(ccw_console_lock); - -spinlock_t * cio_get_console_lock(void) -{ - return &ccw_console_lock; -} - static int ccw_device_console_enable (struct ccw_device *cdev, struct subchannel *sch) { @@ -1277,7 +1048,6 @@ ccw_device_probe_console(void) memset(&console_cdev, 0, sizeof(struct ccw_device)); memset(&console_private, 0, sizeof(struct ccw_device_private)); console_cdev.private = &console_private; - console_private.cdev = &console_cdev; ret = ccw_device_console_enable(&console_cdev, sch); if (ret) { cio_release_console(); diff --git a/trunk/drivers/s390/cio/device.h b/trunk/drivers/s390/cio/device.h index 29db6341d632..9233b5c0bcc8 100644 --- a/trunk/drivers/s390/cio/device.h +++ b/trunk/drivers/s390/cio/device.h @@ -78,10 +78,8 @@ void io_subchannel_recog_done(struct ccw_device *cdev); int ccw_device_cancel_halt_clear(struct ccw_device *); -void ccw_device_do_unreg_rereg(struct work_struct *); -void ccw_device_call_sch_unregister(struct work_struct *); -void ccw_device_move_to_orphanage(struct work_struct *); -int ccw_device_is_orphan(struct ccw_device *); +void ccw_device_do_unreg_rereg(void *); +void ccw_device_call_sch_unregister(void *); int ccw_device_recognition(struct ccw_device *); int ccw_device_online(struct ccw_device *); diff --git a/trunk/drivers/s390/cio/device_fsm.c b/trunk/drivers/s390/cio/device_fsm.c index eed14572fc3b..09c7672eb3f3 100644 --- a/trunk/drivers/s390/cio/device_fsm.c +++ b/trunk/drivers/s390/cio/device_fsm.c @@ -186,14 +186,15 @@ ccw_device_handle_oper(struct ccw_device *cdev) /* * Check if cu type and device type still match. If * not, it is certainly another device and we have to - * de- and re-register. + * de- and re-register. Also check here for non-matching devno. */ if (cdev->id.cu_type != cdev->private->senseid.cu_type || cdev->id.cu_model != cdev->private->senseid.cu_model || cdev->id.dev_type != cdev->private->senseid.dev_type || - cdev->id.dev_model != cdev->private->senseid.dev_model) { + cdev->id.dev_model != cdev->private->senseid.dev_model || + cdev->private->dev_id.devno != sch->schib.pmcw.dev) { PREPARE_WORK(&cdev->private->kick_work, - ccw_device_do_unreg_rereg); + ccw_device_do_unreg_rereg, cdev); queue_work(ccw_device_work, &cdev->private->kick_work); return 0; } @@ -328,21 +329,19 @@ ccw_device_sense_id_done(struct ccw_device *cdev, int err) } static void -ccw_device_oper_notify(struct work_struct *work) +ccw_device_oper_notify(void *data) { - struct ccw_device_private *priv; struct ccw_device *cdev; struct subchannel *sch; int ret; - priv = container_of(work, struct ccw_device_private, kick_work); - cdev = priv->cdev; + cdev = data; sch = to_subchannel(cdev->dev.parent); ret = (sch->driver && sch->driver->notify) ? sch->driver->notify(&sch->dev, CIO_OPER) : 0; if (!ret) /* Driver doesn't want device back. */ - ccw_device_do_unreg_rereg(work); + ccw_device_do_unreg_rereg(cdev); else { /* Reenable channel measurements, if needed. */ cmf_reenable(cdev); @@ -378,7 +377,8 @@ ccw_device_done(struct ccw_device *cdev, int state) if (cdev->private->flags.donotify) { cdev->private->flags.donotify = 0; - PREPARE_WORK(&cdev->private->kick_work, ccw_device_oper_notify); + PREPARE_WORK(&cdev->private->kick_work, ccw_device_oper_notify, + cdev); queue_work(ccw_device_notify_work, &cdev->private->kick_work); } wake_up(&cdev->private->wait_q); @@ -528,15 +528,13 @@ ccw_device_recog_timeout(struct ccw_device *cdev, enum dev_event dev_event) static void -ccw_device_nopath_notify(struct work_struct *work) +ccw_device_nopath_notify(void *data) { - struct ccw_device_private *priv; struct ccw_device *cdev; struct subchannel *sch; int ret; - priv = container_of(work, struct ccw_device_private, kick_work); - cdev = priv->cdev; + cdev = data; sch = to_subchannel(cdev->dev.parent); /* Extra sanity. */ if (sch->lpm) @@ -549,7 +547,8 @@ ccw_device_nopath_notify(struct work_struct *work) cio_disable_subchannel(sch); if (get_device(&cdev->dev)) { PREPARE_WORK(&cdev->private->kick_work, - ccw_device_call_sch_unregister); + ccw_device_call_sch_unregister, + cdev); queue_work(ccw_device_work, &cdev->private->kick_work); } else @@ -608,7 +607,7 @@ ccw_device_verify_done(struct ccw_device *cdev, int err) /* Reset oper notify indication after verify error. */ cdev->private->flags.donotify = 0; PREPARE_WORK(&cdev->private->kick_work, - ccw_device_nopath_notify); + ccw_device_nopath_notify, cdev); queue_work(ccw_device_notify_work, &cdev->private->kick_work); ccw_device_done(cdev, DEV_STATE_NOT_OPER); break; @@ -675,10 +674,6 @@ ccw_device_offline(struct ccw_device *cdev) { struct subchannel *sch; - if (ccw_device_is_orphan(cdev)) { - ccw_device_done(cdev, DEV_STATE_OFFLINE); - return 0; - } sch = to_subchannel(cdev->dev.parent); if (stsch(sch->schid, &sch->schib) || !sch->schib.pmcw.dnv) return -ENODEV; @@ -743,7 +738,7 @@ ccw_device_offline_notoper(struct ccw_device *cdev, enum dev_event dev_event) sch = to_subchannel(cdev->dev.parent); if (get_device(&cdev->dev)) { PREPARE_WORK(&cdev->private->kick_work, - ccw_device_call_sch_unregister); + ccw_device_call_sch_unregister, cdev); queue_work(ccw_device_work, &cdev->private->kick_work); } wake_up(&cdev->private->wait_q); @@ -774,7 +769,7 @@ ccw_device_online_notoper(struct ccw_device *cdev, enum dev_event dev_event) } if (get_device(&cdev->dev)) { PREPARE_WORK(&cdev->private->kick_work, - ccw_device_call_sch_unregister); + ccw_device_call_sch_unregister, cdev); queue_work(ccw_device_work, &cdev->private->kick_work); } wake_up(&cdev->private->wait_q); @@ -879,7 +874,7 @@ ccw_device_online_timeout(struct ccw_device *cdev, enum dev_event dev_event) sch = to_subchannel(cdev->dev.parent); if (!sch->lpm) { PREPARE_WORK(&cdev->private->kick_work, - ccw_device_nopath_notify); + ccw_device_nopath_notify, cdev); queue_work(ccw_device_notify_work, &cdev->private->kick_work); } else @@ -974,7 +969,7 @@ ccw_device_killing_irq(struct ccw_device *cdev, enum dev_event dev_event) ERR_PTR(-EIO)); if (!sch->lpm) { PREPARE_WORK(&cdev->private->kick_work, - ccw_device_nopath_notify); + ccw_device_nopath_notify, cdev); queue_work(ccw_device_notify_work, &cdev->private->kick_work); } else if (cdev->private->flags.doverify) /* Start delayed path verification. */ @@ -997,7 +992,7 @@ ccw_device_killing_timeout(struct ccw_device *cdev, enum dev_event dev_event) sch = to_subchannel(cdev->dev.parent); if (!sch->lpm) { PREPARE_WORK(&cdev->private->kick_work, - ccw_device_nopath_notify); + ccw_device_nopath_notify, cdev); queue_work(ccw_device_notify_work, &cdev->private->kick_work); } else @@ -1026,7 +1021,7 @@ void device_kill_io(struct subchannel *sch) if (ret == -ENODEV) { if (!sch->lpm) { PREPARE_WORK(&cdev->private->kick_work, - ccw_device_nopath_notify); + ccw_device_nopath_notify, cdev); queue_work(ccw_device_notify_work, &cdev->private->kick_work); } else @@ -1038,7 +1033,7 @@ void device_kill_io(struct subchannel *sch) ERR_PTR(-EIO)); if (!sch->lpm) { PREPARE_WORK(&cdev->private->kick_work, - ccw_device_nopath_notify); + ccw_device_nopath_notify, cdev); queue_work(ccw_device_notify_work, &cdev->private->kick_work); } else /* Start delayed path verification. */ @@ -1109,8 +1104,7 @@ device_trigger_reprobe(struct subchannel *sch) /* Update some values. */ if (stsch(sch->schid, &sch->schib)) return; - if (!sch->schib.pmcw.dnv) - return; + /* * The pim, pam, pom values may not be accurate, but they are the best * we have before performing device selection :/ @@ -1124,13 +1118,7 @@ device_trigger_reprobe(struct subchannel *sch) sch->schib.pmcw.mp = 1; sch->schib.pmcw.intparm = (__u32)(unsigned long)sch; /* We should also udate ssd info, but this has to wait. */ - /* Check if this is another device which appeared on the same sch. */ - if (sch->schib.pmcw.dev != cdev->private->dev_id.devno) { - PREPARE_WORK(&cdev->private->kick_work, - ccw_device_move_to_orphanage); - queue_work(ccw_device_work, &cdev->private->kick_work); - } else - ccw_device_start_id(cdev, 0); + ccw_device_start_id(cdev, 0); } static void diff --git a/trunk/drivers/s390/cio/device_ops.c b/trunk/drivers/s390/cio/device_ops.c index d269607336ec..b39c1fa48acd 100644 --- a/trunk/drivers/s390/cio/device_ops.c +++ b/trunk/drivers/s390/cio/device_ops.c @@ -316,9 +316,9 @@ __ccw_device_retry_loop(struct ccw_device *cdev, struct ccw1 *ccw, long magic, _ ccw_device_set_timeout(cdev, 0); if (ret == -EBUSY) { /* Try again later. */ - spin_unlock_irq(sch->lock); + spin_unlock_irq(&sch->lock); msleep(10); - spin_lock_irq(sch->lock); + spin_lock_irq(&sch->lock); continue; } if (ret != 0) @@ -326,12 +326,12 @@ __ccw_device_retry_loop(struct ccw_device *cdev, struct ccw1 *ccw, long magic, _ break; /* Wait for end of request. */ cdev->private->intparm = magic; - spin_unlock_irq(sch->lock); + spin_unlock_irq(&sch->lock); wait_event(cdev->private->wait_q, (cdev->private->intparm == -EIO) || (cdev->private->intparm == -EAGAIN) || (cdev->private->intparm == 0)); - spin_lock_irq(sch->lock); + spin_lock_irq(&sch->lock); /* Check at least for channel end / device end */ if (cdev->private->intparm == -EIO) { /* Non-retryable error. */ @@ -342,9 +342,9 @@ __ccw_device_retry_loop(struct ccw_device *cdev, struct ccw1 *ccw, long magic, _ /* Success. */ break; /* Try again later. */ - spin_unlock_irq(sch->lock); + spin_unlock_irq(&sch->lock); msleep(10); - spin_lock_irq(sch->lock); + spin_lock_irq(&sch->lock); } while (1); return ret; @@ -389,7 +389,7 @@ read_dev_chars (struct ccw_device *cdev, void **buffer, int length) return ret; } - spin_lock_irq(sch->lock); + spin_lock_irq(&sch->lock); /* Save interrupt handler. */ handler = cdev->handler; /* Temporarily install own handler. */ @@ -406,7 +406,7 @@ read_dev_chars (struct ccw_device *cdev, void **buffer, int length) /* Restore interrupt handler. */ cdev->handler = handler; - spin_unlock_irq(sch->lock); + spin_unlock_irq(&sch->lock); clear_normalized_cda (rdc_ccw); kfree(rdc_ccw); @@ -463,7 +463,7 @@ read_conf_data_lpm (struct ccw_device *cdev, void **buffer, int *length, __u8 lp rcd_ccw->count = ciw->count; rcd_ccw->flags = CCW_FLAG_SLI; - spin_lock_irq(sch->lock); + spin_lock_irq(&sch->lock); /* Save interrupt handler. */ handler = cdev->handler; /* Temporarily install own handler. */ @@ -480,7 +480,7 @@ read_conf_data_lpm (struct ccw_device *cdev, void **buffer, int *length, __u8 lp /* Restore interrupt handler. */ cdev->handler = handler; - spin_unlock_irq(sch->lock); + spin_unlock_irq(&sch->lock); /* * on success we update the user input parms @@ -537,7 +537,7 @@ ccw_device_stlck(struct ccw_device *cdev) kfree(buf); return -ENOMEM; } - spin_lock_irqsave(sch->lock, flags); + spin_lock_irqsave(&sch->lock, flags); ret = cio_enable_subchannel(sch, 3); if (ret) goto out_unlock; @@ -559,9 +559,9 @@ ccw_device_stlck(struct ccw_device *cdev) goto out_unlock; } cdev->private->irb.scsw.actl |= SCSW_ACTL_START_PEND; - spin_unlock_irqrestore(sch->lock, flags); + spin_unlock_irqrestore(&sch->lock, flags); wait_event(cdev->private->wait_q, cdev->private->irb.scsw.actl == 0); - spin_lock_irqsave(sch->lock, flags); + spin_lock_irqsave(&sch->lock, flags); cio_disable_subchannel(sch); //FIXME: return code? if ((cdev->private->irb.scsw.dstat != (DEV_STAT_CHN_END|DEV_STAT_DEV_END)) || @@ -572,7 +572,7 @@ ccw_device_stlck(struct ccw_device *cdev) out_unlock: kfree(buf); kfree(buf2); - spin_unlock_irqrestore(sch->lock, flags); + spin_unlock_irqrestore(&sch->lock, flags); return ret; } diff --git a/trunk/drivers/s390/cio/qdio.c b/trunk/drivers/s390/cio/qdio.c index 9d4ea449a608..8d5fa1b4d11f 100644 --- a/trunk/drivers/s390/cio/qdio.c +++ b/trunk/drivers/s390/cio/qdio.c @@ -46,7 +46,6 @@ #include #include -#include #include #include "cio.h" @@ -66,12 +65,12 @@ MODULE_LICENSE("GPL"); /******************** HERE WE GO ***********************************/ static const char version[] = "QDIO base support version 2"; -extern struct bus_type ccw_bus_type; -static int qdio_performance_stats = 0; +#ifdef QDIO_PERFORMANCE_STATS static int proc_perf_file_registration; static unsigned long i_p_c, i_p_nc, o_p_c, o_p_nc, ii_p_c, ii_p_nc; static struct qdio_perf_stats perf_stats; +#endif /* QDIO_PERFORMANCE_STATS */ static int hydra_thinints; static int is_passthrough = 0; @@ -276,8 +275,9 @@ qdio_siga_sync(struct qdio_q *q, unsigned int gpr2, QDIO_DBF_TEXT4(0,trace,"sigasync"); QDIO_DBF_HEX4(0,trace,&q,sizeof(void*)); - if (qdio_performance_stats) - perf_stats.siga_syncs++; +#ifdef QDIO_PERFORMANCE_STATS + perf_stats.siga_syncs++; +#endif /* QDIO_PERFORMANCE_STATS */ cc = do_siga_sync(q->schid, gpr2, gpr3); if (cc) @@ -322,8 +322,9 @@ qdio_siga_output(struct qdio_q *q) __u32 busy_bit; __u64 start_time=0; - if (qdio_performance_stats) - perf_stats.siga_outs++; +#ifdef QDIO_PERFORMANCE_STATS + perf_stats.siga_outs++; +#endif /* QDIO_PERFORMANCE_STATS */ QDIO_DBF_TEXT4(0,trace,"sigaout"); QDIO_DBF_HEX4(0,trace,&q,sizeof(void*)); @@ -357,8 +358,9 @@ qdio_siga_input(struct qdio_q *q) QDIO_DBF_TEXT4(0,trace,"sigain"); QDIO_DBF_HEX4(0,trace,&q,sizeof(void*)); - if (qdio_performance_stats) - perf_stats.siga_ins++; +#ifdef QDIO_PERFORMANCE_STATS + perf_stats.siga_ins++; +#endif /* QDIO_PERFORMANCE_STATS */ cc = do_siga_input(q->schid, q->mask); @@ -952,8 +954,9 @@ __qdio_outbound_processing(struct qdio_q *q) if (unlikely(qdio_reserve_q(q))) { qdio_release_q(q); - if (qdio_performance_stats) - o_p_c++; +#ifdef QDIO_PERFORMANCE_STATS + o_p_c++; +#endif /* QDIO_PERFORMANCE_STATS */ /* as we're sissies, we'll check next time */ if (likely(!atomic_read(&q->is_in_shutdown))) { qdio_mark_q(q); @@ -961,10 +964,10 @@ __qdio_outbound_processing(struct qdio_q *q) } return; } - if (qdio_performance_stats) { - o_p_nc++; - perf_stats.tl_runs++; - } +#ifdef QDIO_PERFORMANCE_STATS + o_p_nc++; + perf_stats.tl_runs++; +#endif /* QDIO_PERFORMANCE_STATS */ /* see comment in qdio_kick_outbound_q */ siga_attempts=atomic_read(&q->busy_siga_counter); @@ -1139,16 +1142,15 @@ qdio_has_inbound_q_moved(struct qdio_q *q) { int i; +#ifdef QDIO_PERFORMANCE_STATS static int old_pcis=0; static int old_thinints=0; - if (qdio_performance_stats) { - if ((old_pcis==perf_stats.pcis)&& - (old_thinints==perf_stats.thinints)) - perf_stats.start_time_inbound=NOW; - else - old_pcis=perf_stats.pcis; - } + if ((old_pcis==perf_stats.pcis)&&(old_thinints==perf_stats.thinints)) + perf_stats.start_time_inbound=NOW; + else + old_pcis=perf_stats.pcis; +#endif /* QDIO_PERFORMANCE_STATS */ i=qdio_get_inbound_buffer_frontier(q); if ( (i!=GET_SAVED_FRONTIER(q)) || @@ -1338,10 +1340,10 @@ qdio_kick_inbound_handler(struct qdio_q *q) q->siga_error=0; q->error_status_flags=0; - if (qdio_performance_stats) { - perf_stats.inbound_time+=NOW-perf_stats.start_time_inbound; - perf_stats.inbound_cnt++; - } +#ifdef QDIO_PERFORMANCE_STATS + perf_stats.inbound_time+=NOW-perf_stats.start_time_inbound; + perf_stats.inbound_cnt++; +#endif /* QDIO_PERFORMANCE_STATS */ } static inline void @@ -1361,8 +1363,9 @@ __tiqdio_inbound_processing(struct qdio_q *q, int spare_ind_was_set) */ if (unlikely(qdio_reserve_q(q))) { qdio_release_q(q); - if (qdio_performance_stats) - ii_p_c++; +#ifdef QDIO_PERFORMANCE_STATS + ii_p_c++; +#endif /* QDIO_PERFORMANCE_STATS */ /* * as we might just be about to stop polling, we make * sure that we check again at least once more @@ -1370,8 +1373,9 @@ __tiqdio_inbound_processing(struct qdio_q *q, int spare_ind_was_set) tiqdio_sched_tl(); return; } - if (qdio_performance_stats) - ii_p_nc++; +#ifdef QDIO_PERFORMANCE_STATS + ii_p_nc++; +#endif /* QDIO_PERFORMANCE_STATS */ if (unlikely(atomic_read(&q->is_in_shutdown))) { qdio_unmark_q(q); goto out; @@ -1412,11 +1416,11 @@ __tiqdio_inbound_processing(struct qdio_q *q, int spare_ind_was_set) irq_ptr = (struct qdio_irq*)q->irq_ptr; for (i=0;ino_output_qs;i++) { oq = irq_ptr->output_qs[i]; - if (!qdio_is_outbound_q_done(oq)) { - if (qdio_performance_stats) - perf_stats.tl_runs--; +#ifdef QDIO_PERFORMANCE_STATS + perf_stats.tl_runs--; +#endif /* QDIO_PERFORMANCE_STATS */ + if (!qdio_is_outbound_q_done(oq)) __qdio_outbound_processing(oq); - } } } @@ -1453,8 +1457,9 @@ __qdio_inbound_processing(struct qdio_q *q) if (unlikely(qdio_reserve_q(q))) { qdio_release_q(q); - if (qdio_performance_stats) - i_p_c++; +#ifdef QDIO_PERFORMANCE_STATS + i_p_c++; +#endif /* QDIO_PERFORMANCE_STATS */ /* as we're sissies, we'll check next time */ if (likely(!atomic_read(&q->is_in_shutdown))) { qdio_mark_q(q); @@ -1462,10 +1467,10 @@ __qdio_inbound_processing(struct qdio_q *q) } return; } - if (qdio_performance_stats) { - i_p_nc++; - perf_stats.tl_runs++; - } +#ifdef QDIO_PERFORMANCE_STATS + i_p_nc++; + perf_stats.tl_runs++; +#endif /* QDIO_PERFORMANCE_STATS */ again: if (qdio_has_inbound_q_moved(q)) { @@ -1511,8 +1516,9 @@ tiqdio_reset_processing_state(struct qdio_q *q, int q_laps) if (unlikely(qdio_reserve_q(q))) { qdio_release_q(q); - if (qdio_performance_stats) - ii_p_c++; +#ifdef QDIO_PERFORMANCE_STATS + ii_p_c++; +#endif /* QDIO_PERFORMANCE_STATS */ /* * as we might just be about to stop polling, we make * sure that we check again at least once more @@ -1603,8 +1609,9 @@ tiqdio_tl(unsigned long data) { QDIO_DBF_TEXT4(0,trace,"iqdio_tl"); - if (qdio_performance_stats) - perf_stats.tl_runs++; +#ifdef QDIO_PERFORMANCE_STATS + perf_stats.tl_runs++; +#endif /* QDIO_PERFORMANCE_STATS */ tiqdio_inbound_checks(); } @@ -1911,10 +1918,10 @@ tiqdio_thinint_handler(void) { QDIO_DBF_TEXT4(0,trace,"thin_int"); - if (qdio_performance_stats) { - perf_stats.thinints++; - perf_stats.start_time_inbound=NOW; - } +#ifdef QDIO_PERFORMANCE_STATS + perf_stats.thinints++; + perf_stats.start_time_inbound=NOW; +#endif /* QDIO_PERFORMANCE_STATS */ /* SVS only when needed: * issue SVS to benefit from iqdio interrupt avoidance @@ -1969,17 +1976,18 @@ qdio_handle_pci(struct qdio_irq *irq_ptr) int i; struct qdio_q *q; - if (qdio_performance_stats) { - perf_stats.pcis++; - perf_stats.start_time_inbound=NOW; - } +#ifdef QDIO_PERFORMANCE_STATS + perf_stats.pcis++; + perf_stats.start_time_inbound=NOW; +#endif /* QDIO_PERFORMANCE_STATS */ for (i=0;ino_input_qs;i++) { q=irq_ptr->input_qs[i]; if (q->is_input_q&QDIO_FLAG_NO_INPUT_INTERRUPT_CONTEXT) qdio_mark_q(q); else { - if (qdio_performance_stats) - perf_stats.tl_runs--; +#ifdef QDIO_PERFORMANCE_STATS + perf_stats.tl_runs--; +#endif /* QDIO_PERFORMANCE_STATS */ __qdio_inbound_processing(q); } } @@ -1987,10 +1995,11 @@ qdio_handle_pci(struct qdio_irq *irq_ptr) return; for (i=0;ino_output_qs;i++) { q=irq_ptr->output_qs[i]; +#ifdef QDIO_PERFORMANCE_STATS + perf_stats.tl_runs--; +#endif /* QDIO_PERFORMANCE_STATS */ if (qdio_is_outbound_q_done(q)) continue; - if (qdio_performance_stats) - perf_stats.tl_runs--; if (!irq_ptr->sync_done_on_outb_pcis) SYNC_MEMORY; __qdio_outbound_processing(q); @@ -2036,13 +2045,11 @@ qdio_handle_activate_check(struct ccw_device *cdev, unsigned long intparm, } static void -qdio_call_shutdown(struct work_struct *work) +qdio_call_shutdown(void *data) { - struct ccw_device_private *priv; struct ccw_device *cdev; - priv = container_of(work, struct ccw_device_private, kick_work); - cdev = priv->cdev; + cdev = (struct ccw_device *)data; qdio_shutdown(cdev, QDIO_FLAG_CLEANUP_USING_CLEAR); put_device(&cdev->dev); } @@ -2084,7 +2091,7 @@ qdio_timeout_handler(struct ccw_device *cdev) if (get_device(&cdev->dev)) { /* Can't call shutdown from interrupt context. */ PREPARE_WORK(&cdev->private->kick_work, - qdio_call_shutdown); + qdio_call_shutdown, (void *)cdev); queue_work(ccw_device_work, &cdev->private->kick_work); } break; @@ -3451,18 +3458,19 @@ do_qdio_handle_outbound(struct qdio_q *q, unsigned int callflags, struct qdio_irq *irq = (struct qdio_irq *) q->irq_ptr; /* This is the outbound handling of queues */ - if (qdio_performance_stats) - perf_stats.start_time_outbound=NOW; +#ifdef QDIO_PERFORMANCE_STATS + perf_stats.start_time_outbound=NOW; +#endif /* QDIO_PERFORMANCE_STATS */ qdio_do_qdio_fill_output(q,qidx,count,buffers); used_elements=atomic_add_return(count, &q->number_of_buffers_used) - count; if (callflags&QDIO_FLAG_DONT_SIGA) { - if (qdio_performance_stats) { - perf_stats.outbound_time+=NOW-perf_stats.start_time_outbound; - perf_stats.outbound_cnt++; - } +#ifdef QDIO_PERFORMANCE_STATS + perf_stats.outbound_time+=NOW-perf_stats.start_time_outbound; + perf_stats.outbound_cnt++; +#endif /* QDIO_PERFORMANCE_STATS */ return; } if (q->is_iqdio_q) { @@ -3492,8 +3500,9 @@ do_qdio_handle_outbound(struct qdio_q *q, unsigned int callflags, qdio_kick_outbound_q(q); } else { QDIO_DBF_TEXT3(0,trace, "fast-req"); - if (qdio_performance_stats) - perf_stats.fast_reqs++; +#ifdef QDIO_PERFORMANCE_STATS + perf_stats.fast_reqs++; +#endif /* QDIO_PERFORMANCE_STATS */ } } /* @@ -3504,10 +3513,10 @@ do_qdio_handle_outbound(struct qdio_q *q, unsigned int callflags, __qdio_outbound_processing(q); } - if (qdio_performance_stats) { - perf_stats.outbound_time+=NOW-perf_stats.start_time_outbound; - perf_stats.outbound_cnt++; - } +#ifdef QDIO_PERFORMANCE_STATS + perf_stats.outbound_time+=NOW-perf_stats.start_time_outbound; + perf_stats.outbound_cnt++; +#endif /* QDIO_PERFORMANCE_STATS */ } /* count must be 1 in iqdio */ @@ -3565,6 +3574,7 @@ do_QDIO(struct ccw_device *cdev,unsigned int callflags, return 0; } +#ifdef QDIO_PERFORMANCE_STATS static int qdio_perf_procfile_read(char *buffer, char **buffer_location, off_t offset, int buffer_length, int *eof, void *data) @@ -3580,29 +3590,29 @@ qdio_perf_procfile_read(char *buffer, char **buffer_location, off_t offset, _OUTP_IT("i_p_nc/c=%lu/%lu\n",i_p_nc,i_p_c); _OUTP_IT("ii_p_nc/c=%lu/%lu\n",ii_p_nc,ii_p_c); _OUTP_IT("o_p_nc/c=%lu/%lu\n",o_p_nc,o_p_c); - _OUTP_IT("Number of tasklet runs (total) : %lu\n", + _OUTP_IT("Number of tasklet runs (total) : %u\n", perf_stats.tl_runs); _OUTP_IT("\n"); - _OUTP_IT("Number of SIGA sync's issued : %lu\n", + _OUTP_IT("Number of SIGA sync's issued : %u\n", perf_stats.siga_syncs); - _OUTP_IT("Number of SIGA in's issued : %lu\n", + _OUTP_IT("Number of SIGA in's issued : %u\n", perf_stats.siga_ins); - _OUTP_IT("Number of SIGA out's issued : %lu\n", + _OUTP_IT("Number of SIGA out's issued : %u\n", perf_stats.siga_outs); - _OUTP_IT("Number of PCIs caught : %lu\n", + _OUTP_IT("Number of PCIs caught : %u\n", perf_stats.pcis); - _OUTP_IT("Number of adapter interrupts caught : %lu\n", + _OUTP_IT("Number of adapter interrupts caught : %u\n", perf_stats.thinints); - _OUTP_IT("Number of fast requeues (outg. SBALs w/o SIGA) : %lu\n", + _OUTP_IT("Number of fast requeues (outg. SBALs w/o SIGA) : %u\n", perf_stats.fast_reqs); _OUTP_IT("\n"); - _OUTP_IT("Total time of all inbound actions (us) incl. UL : %lu\n", + _OUTP_IT("Total time of all inbound actions (us) incl. UL : %u\n", perf_stats.inbound_time); - _OUTP_IT("Number of inbound transfers : %lu\n", + _OUTP_IT("Number of inbound transfers : %u\n", perf_stats.inbound_cnt); - _OUTP_IT("Total time of all outbound do_QDIOs (us) : %lu\n", + _OUTP_IT("Total time of all outbound do_QDIOs (us) : %u\n", perf_stats.outbound_time); - _OUTP_IT("Number of do_QDIOs outbound : %lu\n", + _OUTP_IT("Number of do_QDIOs outbound : %u\n", perf_stats.outbound_cnt); _OUTP_IT("\n"); @@ -3610,10 +3620,12 @@ qdio_perf_procfile_read(char *buffer, char **buffer_location, off_t offset, } static struct proc_dir_entry *qdio_perf_proc_file; +#endif /* QDIO_PERFORMANCE_STATS */ static void qdio_add_procfs_entry(void) { +#ifdef QDIO_PERFORMANCE_STATS proc_perf_file_registration=0; qdio_perf_proc_file=create_proc_entry(QDIO_PERF, S_IFREG|0444,&proc_root); @@ -3625,58 +3637,20 @@ qdio_add_procfs_entry(void) QDIO_PRINT_WARN("was not able to register perf. " \ "proc-file (%i).\n", proc_perf_file_registration); +#endif /* QDIO_PERFORMANCE_STATS */ } static void qdio_remove_procfs_entry(void) { +#ifdef QDIO_PERFORMANCE_STATS perf_stats.tl_runs=0; if (!proc_perf_file_registration) /* means if it went ok earlier */ remove_proc_entry(QDIO_PERF,&proc_root); +#endif /* QDIO_PERFORMANCE_STATS */ } -/** - * attributes in sysfs - *****************************************************************************/ - -static ssize_t -qdio_performance_stats_show(struct bus_type *bus, char *buf) -{ - return sprintf(buf, "%i\n", qdio_performance_stats ? 1 : 0); -} - -static ssize_t -qdio_performance_stats_store(struct bus_type *bus, const char *buf, size_t count) -{ - char *tmp; - int i; - - i = simple_strtoul(buf, &tmp, 16); - if ((i == 0) || (i == 1)) { - if (i == qdio_performance_stats) - return count; - qdio_performance_stats = i; - if (i==0) { - /* reset perf. stat. info */ - i_p_nc = 0; - i_p_c = 0; - ii_p_nc = 0; - ii_p_c = 0; - o_p_nc = 0; - o_p_c = 0; - memset(&perf_stats, 0, sizeof(struct qdio_perf_stats)); - } - } else { - QDIO_PRINT_WARN("QDIO performance_stats: write 0 or 1 to this file!\n"); - return -EINVAL; - } - return count; -} - -static BUS_ATTR(qdio_performance_stats, 0644, qdio_performance_stats_show, - qdio_performance_stats_store); - static void tiqdio_register_thinints(void) { @@ -3721,7 +3695,6 @@ qdio_release_qdio_memory(void) kfree(indicators); } - static void qdio_unregister_dbf_views(void) { @@ -3823,7 +3796,9 @@ static int __init init_QDIO(void) { int res; +#ifdef QDIO_PERFORMANCE_STATS void *ptr; +#endif /* QDIO_PERFORMANCE_STATS */ printk("qdio: loading %s\n",version); @@ -3836,12 +3811,13 @@ init_QDIO(void) return res; QDIO_DBF_TEXT0(0,setup,"initQDIO"); - res = bus_create_file(&ccw_bus_type, &bus_attr_qdio_performance_stats); - memset((void*)&perf_stats,0,sizeof(perf_stats)); +#ifdef QDIO_PERFORMANCE_STATS + memset((void*)&perf_stats,0,sizeof(perf_stats)); QDIO_DBF_TEXT0(0,setup,"perfstat"); ptr=&perf_stats; QDIO_DBF_HEX0(0,setup,&ptr,sizeof(void*)); +#endif /* QDIO_PERFORMANCE_STATS */ qdio_add_procfs_entry(); @@ -3865,7 +3841,7 @@ cleanup_QDIO(void) qdio_release_qdio_memory(); qdio_unregister_dbf_views(); mempool_destroy(qdio_mempool_scssc); - bus_remove_file(&ccw_bus_type, &bus_attr_qdio_performance_stats); + printk("qdio: %s: module removed\n",version); } diff --git a/trunk/drivers/s390/cio/qdio.h b/trunk/drivers/s390/cio/qdio.h index ec9af72b2afc..42927c1b7451 100644 --- a/trunk/drivers/s390/cio/qdio.h +++ b/trunk/drivers/s390/cio/qdio.h @@ -12,6 +12,10 @@ #endif /* CONFIG_QDIO_DEBUG */ #define QDIO_USE_PROCESSING_STATE +#ifdef CONFIG_QDIO_PERF_STATS +#define QDIO_PERFORMANCE_STATS +#endif /* CONFIG_QDIO_PERF_STATS */ + #define QDIO_MINIMAL_BH_RELIEF_TIME 16 #define QDIO_TIMER_POLL_VALUE 1 #define IQDIO_TIMER_POLL_VALUE 1 @@ -405,23 +409,25 @@ do_clear_global_summary(void) #define CHSC_FLAG_SIGA_SYNC_DONE_ON_THININTS 0x08 #define CHSC_FLAG_SIGA_SYNC_DONE_ON_OUTB_PCIS 0x04 +#ifdef QDIO_PERFORMANCE_STATS struct qdio_perf_stats { - unsigned long tl_runs; + unsigned int tl_runs; - unsigned long siga_outs; - unsigned long siga_ins; - unsigned long siga_syncs; - unsigned long pcis; - unsigned long thinints; - unsigned long fast_reqs; + unsigned int siga_outs; + unsigned int siga_ins; + unsigned int siga_syncs; + unsigned int pcis; + unsigned int thinints; + unsigned int fast_reqs; __u64 start_time_outbound; - unsigned long outbound_cnt; - unsigned long outbound_time; + unsigned int outbound_cnt; + unsigned int outbound_time; __u64 start_time_inbound; - unsigned long inbound_cnt; - unsigned long inbound_time; + unsigned int inbound_cnt; + unsigned int inbound_time; }; +#endif /* QDIO_PERFORMANCE_STATS */ /* unlikely as the later the better */ #define SYNC_MEMORY if (unlikely(q->siga_sync)) qdio_siga_sync_q(q) diff --git a/trunk/drivers/s390/crypto/ap_bus.c b/trunk/drivers/s390/crypto/ap_bus.c index ad60afe5dd11..e4dc947e74e9 100644 --- a/trunk/drivers/s390/crypto/ap_bus.c +++ b/trunk/drivers/s390/crypto/ap_bus.c @@ -33,7 +33,6 @@ #include #include #include -#include #include "ap_bus.h" @@ -1129,19 +1128,6 @@ static void ap_poll_thread_stop(void) mutex_unlock(&ap_poll_thread_mutex); } -static void ap_reset(void) -{ - int i, j; - - for (i = 0; i < AP_DOMAINS; i++) - for (j = 0; j < AP_DEVICES; j++) - ap_reset_queue(AP_MKQID(j, i)); -} - -static struct reset_call ap_reset_call = { - .fn = ap_reset, -}; - /** * The module initialization code. */ @@ -1158,7 +1144,6 @@ int __init ap_module_init(void) printk(KERN_WARNING "AP instructions not installed.\n"); return -ENODEV; } - register_reset_call(&ap_reset_call); /* Create /sys/bus/ap. */ rc = bus_register(&ap_bus_type); @@ -1212,7 +1197,6 @@ int __init ap_module_init(void) bus_remove_file(&ap_bus_type, ap_bus_attrs[i]); bus_unregister(&ap_bus_type); out: - unregister_reset_call(&ap_reset_call); return rc; } @@ -1243,7 +1227,6 @@ void ap_module_exit(void) for (i = 0; ap_bus_attrs[i]; i++) bus_remove_file(&ap_bus_type, ap_bus_attrs[i]); bus_unregister(&ap_bus_type); - unregister_reset_call(&ap_reset_call); } #ifndef CONFIG_ZCRYPT_MONOLITHIC diff --git a/trunk/drivers/sbus/char/bpp.c b/trunk/drivers/sbus/char/bpp.c index ac7d1258efee..385f4f768311 100644 --- a/trunk/drivers/sbus/char/bpp.c +++ b/trunk/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_path.dentry->d_inode); + unsigned minor = iminor(f->f_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_path.dentry->d_inode); + unsigned minor = iminor(f->f_dentry->d_inode); if (minor >= BPP_NO) return -ENODEV; if (!instances[minor].present) return -ENODEV; diff --git a/trunk/drivers/sbus/char/cpwatchdog.c b/trunk/drivers/sbus/char/cpwatchdog.c index ad1c7db96cb4..f5803ecb1999 100644 --- a/trunk/drivers/sbus/char/cpwatchdog.c +++ b/trunk/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_path.dentry->d_inode, file, cmd, arg); + rval = wd_ioctl(file->f_dentry->d_inode, file, cmd, arg); unlock_kernel(); break; /* everything else is handled by the generic compat layer */ diff --git a/trunk/drivers/sbus/char/display7seg.c b/trunk/drivers/sbus/char/display7seg.c index a4909e0c7f83..d92bc8827a9e 100644 --- a/trunk/drivers/sbus/char/display7seg.c +++ b/trunk/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_path.dentry->d_inode)) + if (D7S_MINOR != iminor(file->f_dentry->d_inode)) return -ENODEV; lock_kernel(); diff --git a/trunk/drivers/sbus/char/openprom.c b/trunk/drivers/sbus/char/openprom.c index 4e2a0e2dcc2e..81ba2d71cee2 100644 --- a/trunk/drivers/sbus/char/openprom.c +++ b/trunk/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_path.dentry->d_inode, file, cmd, arg); + rval = openprom_ioctl(file->f_dentry->d_inode, file, cmd, arg); break; } diff --git a/trunk/drivers/sbus/char/vfc_dev.c b/trunk/drivers/sbus/char/vfc_dev.c index 2722af5d3404..55b2b31bd7ab 100644 --- a/trunk/drivers/sbus/char/vfc_dev.c +++ b/trunk/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_path.dentry->d_inode)); + dev = vfc_get_dev_ptr(iminor(file->f_dentry->d_inode)); if(dev == NULL) return -ENODEV; diff --git a/trunk/drivers/scsi/sd.c b/trunk/drivers/scsi/sd.c index 978bfc1e0c6a..f6a452846fab 100644 --- a/trunk/drivers/scsi/sd.c +++ b/trunk/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_path.dentry->d_inode->i_bdev; + struct block_device *bdev = file->f_dentry->d_inode->i_bdev; struct gendisk *disk = bdev->bd_disk; struct scsi_device *sdev = scsi_disk(disk)->device; diff --git a/trunk/drivers/scsi/st.c b/trunk/drivers/scsi/st.c index e016e0906e1a..587274dd7059 100644 --- a/trunk/drivers/scsi/st.c +++ b/trunk/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_path.dentry->d_inode; + struct inode *inode = filp->f_dentry->d_inode; int mode = TAPE_MODE(inode); STp->ready = ST_READY; diff --git a/trunk/drivers/serial/21285.c b/trunk/drivers/serial/21285.c index facb67855619..6a1a568ca649 100644 --- a/trunk/drivers/serial/21285.c +++ b/trunk/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 ktermios *termios, - struct ktermios *old) +serial21285_set_termios(struct uart_port *port, struct termios *termios, + struct termios *old) { unsigned long flags; unsigned int baud, quot, h_lcr; diff --git a/trunk/drivers/serial/68328serial.c b/trunk/drivers/serial/68328serial.c index cad426c9711e..9b8b585513ec 100644 --- a/trunk/drivers/serial/68328serial.c +++ b/trunk/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 ktermios *old_termios) +static void rs_set_termios(struct tty_struct *tty, struct termios *old_termios) { struct m68k_serial *info = (struct m68k_serial *)tty->driver_data; diff --git a/trunk/drivers/serial/68360serial.c b/trunk/drivers/serial/68360serial.c index 68817a7d8c0d..634ecca36a77 100644 --- a/trunk/drivers/serial/68360serial.c +++ b/trunk/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 ktermios *old_termios) +static void rs_360_set_termios(struct tty_struct *tty, struct termios *old_termios) { ser_info_t *info = (ser_info_t *)tty->driver_data; diff --git a/trunk/drivers/serial/8250.c b/trunk/drivers/serial/8250.c index 51f3c739f7e1..e34bd03cfce7 100644 --- a/trunk/drivers/serial/8250.c +++ b/trunk/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 ktermios *termios, - struct ktermios *old) +serial8250_set_termios(struct uart_port *port, struct termios *termios, + struct termios *old) { struct uart_8250_port *up = (struct uart_8250_port *)port; unsigned char cval, fcr = 0; diff --git a/trunk/drivers/serial/amba-pl010.c b/trunk/drivers/serial/amba-pl010.c index 61db6973755a..4d3626ef4643 100644 --- a/trunk/drivers/serial/amba-pl010.c +++ b/trunk/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 ktermios *termios, - struct ktermios *old) +pl010_set_termios(struct uart_port *port, struct termios *termios, + struct termios *old) { unsigned int lcr_h, old_cr; unsigned long flags; diff --git a/trunk/drivers/serial/amba-pl011.c b/trunk/drivers/serial/amba-pl011.c index 9a3b374b2a08..d503625730df 100644 --- a/trunk/drivers/serial/amba-pl011.c +++ b/trunk/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 ktermios *termios, - struct ktermios *old) +pl011_set_termios(struct uart_port *port, struct termios *termios, + struct termios *old) { unsigned int lcr_h, old_cr; unsigned long flags; diff --git a/trunk/drivers/serial/atmel_serial.c b/trunk/drivers/serial/atmel_serial.c index ed7f7209ea59..9217ee6c7865 100644 --- a/trunk/drivers/serial/atmel_serial.c +++ b/trunk/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 ktermios * termios, struct ktermios * old) +static void atmel_set_termios(struct uart_port *port, struct termios * termios, struct termios * old) { unsigned long flags; unsigned int mode, imr, quot, baud; diff --git a/trunk/drivers/serial/clps711x.c b/trunk/drivers/serial/clps711x.c index 23827189ec0e..598012714882 100644 --- a/trunk/drivers/serial/clps711x.c +++ b/trunk/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 ktermios *termios, - struct ktermios *old) +clps711xuart_set_termios(struct uart_port *port, struct termios *termios, + struct termios *old) { unsigned int ubrlcr, baud, quot; unsigned long flags; diff --git a/trunk/drivers/serial/crisv10.c b/trunk/drivers/serial/crisv10.c index 42b050c46abe..7a24e53546c7 100644 --- a/trunk/drivers/serial/crisv10.c +++ b/trunk/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 ktermios *serial_termios[NR_PORTS]; -static struct ktermios *serial_termios_locked[NR_PORTS]; +static struct termios *serial_termios[NR_PORTS]; +static struct termios *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 ktermios *old_termios) +rs_set_termios(struct tty_struct *tty, struct termios *old_termios) { struct e100_serial *info = (struct e100_serial *)tty->driver_data; @@ -4877,8 +4877,6 @@ 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/trunk/drivers/serial/crisv10.h b/trunk/drivers/serial/crisv10.h index 4a23340663aa..f30b93d6ef79 100644 --- a/trunk/drivers/serial/crisv10.h +++ b/trunk/drivers/serial/crisv10.h @@ -93,8 +93,8 @@ struct e100_serial { struct work_struct work; struct async_icount icount; /* error-statistics etc.*/ - struct ktermios normal_termios; - struct ktermios callout_termios; + struct termios normal_termios; + struct termios callout_termios; #ifdef DECLARE_WAITQUEUE wait_queue_head_t open_wait; wait_queue_head_t close_wait; diff --git a/trunk/drivers/serial/dz.c b/trunk/drivers/serial/dz.c index 587d87b9eb3c..af1544f3356f 100644 --- a/trunk/drivers/serial/dz.c +++ b/trunk/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 ktermios *termios, - struct ktermios *old_termios) +static void dz_set_termios(struct uart_port *uport, struct termios *termios, + struct termios *old_termios) { struct dz_port *dport = (struct dz_port *)uport; unsigned long flags; diff --git a/trunk/drivers/serial/icom.c b/trunk/drivers/serial/icom.c index 7d623003e65e..8aa0f641866b 100644 --- a/trunk/drivers/serial/icom.c +++ b/trunk/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 ktermios *termios, - struct ktermios *old_termios) + struct termios *termios, + struct termios *old_termios) { int baud; unsigned cflag, iflag; diff --git a/trunk/drivers/serial/imx.c b/trunk/drivers/serial/imx.c index e216dcf29376..ee5c782597dd 100644 --- a/trunk/drivers/serial/imx.c +++ b/trunk/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 ktermios *termios, - struct ktermios *old) +imx_set_termios(struct uart_port *port, struct termios *termios, + struct termios *old) { struct imx_port *sport = (struct imx_port *)port; unsigned long flags; diff --git a/trunk/drivers/serial/ioc3_serial.c b/trunk/drivers/serial/ioc3_serial.c index 9cc0be932316..2308d26c8629 100644 --- a/trunk/drivers/serial/ioc3_serial.c +++ b/trunk/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 ktermios *new_termios, struct ktermios *old_termios) + struct termios *new_termios, struct termios *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 ktermios *termios, struct ktermios *old_termios) + struct termios *termios, struct termios *old_termios) { unsigned long port_flags; diff --git a/trunk/drivers/serial/ioc4_serial.c b/trunk/drivers/serial/ioc4_serial.c index c862f67c985a..711bd1511439 100644 --- a/trunk/drivers/serial/ioc4_serial.c +++ b/trunk/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 ktermios *new_termios, struct ktermios *old_termios) + struct termios *new_termios, struct termios *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 ktermios *)0); + ioc4_change_speed(the_port, info->tty->termios, (struct termios *)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 ktermios *termios, struct ktermios *old_termios) + struct termios *termios, struct termios *old_termios) { unsigned long port_flags; diff --git a/trunk/drivers/serial/ip22zilog.c b/trunk/drivers/serial/ip22zilog.c index 0746c9446ae0..dca6c1bde8f9 100644 --- a/trunk/drivers/serial/ip22zilog.c +++ b/trunk/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 ktermios *termios, - struct ktermios *old) +ip22zilog_set_termios(struct uart_port *port, struct termios *termios, + struct termios *old) { struct uart_ip22zilog_port *up = (struct uart_ip22zilog_port *) port; unsigned long flags; diff --git a/trunk/drivers/serial/jsm/jsm_tty.c b/trunk/drivers/serial/jsm/jsm_tty.c index 7cf1c60027f8..f8262e6ad8d3 100644 --- a/trunk/drivers/serial/jsm/jsm_tty.c +++ b/trunk/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 ktermios *termios; + struct termios *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 ktermios *termios; + struct termios *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 ktermios *ts; + struct termios *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 ktermios *termios, - struct ktermios *old_termios) + struct termios *termios, + struct termios *old_termios) { unsigned long lock_flags; struct jsm_channel *channel = (struct jsm_channel *)port; diff --git a/trunk/drivers/serial/m32r_sio.c b/trunk/drivers/serial/m32r_sio.c index 6e09c8b395e8..7656a35f5e2f 100644 --- a/trunk/drivers/serial/m32r_sio.c +++ b/trunk/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 ktermios *termios, struct ktermios *old) + struct termios *termios, struct termios *old) { struct uart_sio_port *up = (struct uart_sio_port *)port; unsigned char cval = 0; diff --git a/trunk/drivers/serial/mcfserial.c b/trunk/drivers/serial/mcfserial.c index 08430961a895..3db206d29b33 100644 --- a/trunk/drivers/serial/mcfserial.c +++ b/trunk/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 ktermios *old_termios) +static void mcfrs_set_termios(struct tty_struct *tty, struct termios *old_termios) { struct mcf_serial *info = (struct mcf_serial *)tty->driver_data; diff --git a/trunk/drivers/serial/mpc52xx_uart.c b/trunk/drivers/serial/mpc52xx_uart.c index 9d11a75663e6..6dd579ed9777 100644 --- a/trunk/drivers/serial/mpc52xx_uart.c +++ b/trunk/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 ktermios *new, - struct ktermios *old) +mpc52xx_uart_set_termios(struct uart_port *port, struct termios *new, + struct termios *old) { struct mpc52xx_psc __iomem *psc = PSC(port); unsigned long flags; diff --git a/trunk/drivers/serial/mpsc.c b/trunk/drivers/serial/mpsc.c index 3d2fcc57b1ce..29823bd60fb0 100644 --- a/trunk/drivers/serial/mpsc.c +++ b/trunk/drivers/serial/mpsc.c @@ -1440,8 +1440,8 @@ mpsc_shutdown(struct uart_port *port) } static void -mpsc_set_termios(struct uart_port *port, struct ktermios *termios, - struct ktermios *old) +mpsc_set_termios(struct uart_port *port, struct termios *termios, + struct termios *old) { struct mpsc_port_info *pi = (struct mpsc_port_info *)port; u32 baud; diff --git a/trunk/drivers/serial/mux.c b/trunk/drivers/serial/mux.c index ccb8fa1800a5..8ad1b8c5ec5d 100644 --- a/trunk/drivers/serial/mux.c +++ b/trunk/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 ktermios *termios, - struct ktermios *old) +mux_set_termios(struct uart_port *port, struct termios *termios, + struct termios *old) { } diff --git a/trunk/drivers/serial/netx-serial.c b/trunk/drivers/serial/netx-serial.c index b56f7db45031..062bad457b1a 100644 --- a/trunk/drivers/serial/netx-serial.c +++ b/trunk/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 ktermios *termios, - struct ktermios *old) +netx_set_termios(struct uart_port *port, struct termios *termios, + struct termios *old) { unsigned int baud, quot; unsigned char old_cr; diff --git a/trunk/drivers/serial/pmac_zilog.c b/trunk/drivers/serial/pmac_zilog.c index 752ef07516b9..bf9809ed9c0b 100644 --- a/trunk/drivers/serial/pmac_zilog.c +++ b/trunk/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 ktermios *termios, - struct ktermios *old) +static void __pmz_set_termios(struct uart_port *port, struct termios *termios, + struct termios *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 ktermios *termios, if (ZS_IS_ASLEEP(uap)) return; - memcpy(&uap->termios_cache, termios, sizeof(struct ktermios)); + memcpy(&uap->termios_cache, termios, sizeof(struct termios)); /* 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 ktermios *termios, } /* The port lock is not held. */ -static void pmz_set_termios(struct uart_port *port, struct ktermios *termios, - struct ktermios *old) +static void pmz_set_termios(struct uart_port *port, struct termios *termios, + struct termios *old) { struct uart_pmac_port *uap = to_pmz(port); unsigned long flags; diff --git a/trunk/drivers/serial/pmac_zilog.h b/trunk/drivers/serial/pmac_zilog.h index 570b0d925e83..c03f9bfacdd8 100644 --- a/trunk/drivers/serial/pmac_zilog.h +++ b/trunk/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 ktermios termios_cache; + struct termios termios_cache; }; #define to_pmz(p) ((struct uart_pmac_port *)(p)) diff --git a/trunk/drivers/serial/pxa.c b/trunk/drivers/serial/pxa.c index d403aaa55092..415fe9633a9b 100644 --- a/trunk/drivers/serial/pxa.c +++ b/trunk/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 ktermios *termios, - struct ktermios *old) +serial_pxa_set_termios(struct uart_port *port, struct termios *termios, + struct termios *old) { struct uart_pxa_port *up = (struct uart_pxa_port *)port; unsigned char cval, fcr = 0; diff --git a/trunk/drivers/serial/s3c2410.c b/trunk/drivers/serial/s3c2410.c index 3ba9208ebd0c..8dfc2dd058ca 100644 --- a/trunk/drivers/serial/s3c2410.c +++ b/trunk/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 ktermios *termios, - struct ktermios *old) + struct termios *termios, + struct termios *old) { struct s3c2410_uartcfg *cfg = s3c24xx_port_to_cfg(port); struct s3c24xx_uart_port *ourport = to_ourport(port); diff --git a/trunk/drivers/serial/sa1100.c b/trunk/drivers/serial/sa1100.c index 58a83c27e14b..d4065266b6fc 100644 --- a/trunk/drivers/serial/sa1100.c +++ b/trunk/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 ktermios *termios, - struct ktermios *old) +sa1100_set_termios(struct uart_port *port, struct termios *termios, + struct termios *old) { struct sa1100_port *sport = (struct sa1100_port *)port; unsigned long flags; diff --git a/trunk/drivers/serial/serial_core.c b/trunk/drivers/serial/serial_core.c index f84982e508c7..c67b05e9a451 100644 --- a/trunk/drivers/serial/serial_core.c +++ b/trunk/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 ktermios *old_termios); +static void uart_change_speed(struct uart_state *state, struct termios *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 ktermios *termios, - struct ktermios *old, unsigned int min, unsigned int max) +uart_get_baud_rate(struct uart_port *port, struct termios *termios, + struct termios *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 ktermios *old_termios) +uart_change_speed(struct uart_state *state, struct termios *old_termios) { struct tty_struct *tty = state->info->tty; struct uart_port *port = state->port; - struct ktermios *termios; + struct termios *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 ktermios *old_termios) +static void uart_set_termios(struct tty_struct *tty, struct termios *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 ktermios termios; + struct termios 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 ktermios)); + memset(&termios, 0, sizeof(struct termios)); 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 ktermios termios; + struct termios termios; /* * First try to use the console cflag setting. */ - memset(&termios, 0, sizeof(struct ktermios)); + memset(&termios, 0, sizeof(struct termios)); termios.c_cflag = port->cons->cflag; /* @@ -2189,7 +2189,6 @@ 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/trunk/drivers/serial/serial_lh7a40x.c b/trunk/drivers/serial/serial_lh7a40x.c index eb18d429752d..5e1ac356bbb0 100644 --- a/trunk/drivers/serial/serial_lh7a40x.c +++ b/trunk/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 ktermios* termios, - struct ktermios* old) + struct termios* termios, + struct termios* old) { unsigned int con; unsigned int inten; diff --git a/trunk/drivers/serial/serial_txx9.c b/trunk/drivers/serial/serial_txx9.c index 7186a82c4759..2a48289ac722 100644 --- a/trunk/drivers/serial/serial_txx9.c +++ b/trunk/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 ktermios *termios, - struct ktermios *old) +serial_txx9_set_termios(struct uart_port *port, struct termios *termios, + struct termios *old) { struct uart_txx9_port *up = (struct uart_txx9_port *)port; unsigned int cval, fcr = 0; diff --git a/trunk/drivers/serial/sh-sci.c b/trunk/drivers/serial/sh-sci.c index 9031b57f12dd..3b5f19ec2126 100644 --- a/trunk/drivers/serial/sh-sci.c +++ b/trunk/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 ktermios *termios, - struct ktermios *old) +static void sci_set_termios(struct uart_port *port, struct termios *termios, + struct termios *old) { struct sci_port *s = &sci_ports[port->line]; unsigned int status, baud, smr_val; diff --git a/trunk/drivers/serial/sn_console.c b/trunk/drivers/serial/sn_console.c index 253ceb895ca7..956b2cf08e1e 100644 --- a/trunk/drivers/serial/sn_console.c +++ b/trunk/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 ktermios *termios, - struct ktermios *old) +snp_set_termios(struct uart_port *port, struct termios *termios, + struct termios *old) { } diff --git a/trunk/drivers/serial/sunhv.c b/trunk/drivers/serial/sunhv.c index 40d48566215c..03941d27d15d 100644 --- a/trunk/drivers/serial/sunhv.c +++ b/trunk/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 ktermios *termios, - struct ktermios *old) +static void sunhv_set_termios(struct uart_port *port, struct termios *termios, + struct termios *old) { unsigned int baud = uart_get_baud_rate(port, termios, old, 0, 4000000); unsigned int quot = uart_get_divisor(port, baud); diff --git a/trunk/drivers/serial/sunsab.c b/trunk/drivers/serial/sunsab.c index 493d5bbb661b..08a7cd6a3a0c 100644 --- a/trunk/drivers/serial/sunsab.c +++ b/trunk/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 ktermios *termios, - struct ktermios *old) +static void sunsab_set_termios(struct uart_port *port, struct termios *termios, + struct termios *old) { struct uart_sunsab_port *up = (struct uart_sunsab_port *) port; unsigned long flags; diff --git a/trunk/drivers/serial/sunsu.c b/trunk/drivers/serial/sunsu.c index 564592b2b2ba..c577faea60e8 100644 --- a/trunk/drivers/serial/sunsu.c +++ b/trunk/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 ktermios *termios, - struct ktermios *old) +sunsu_set_termios(struct uart_port *port, struct termios *termios, + struct termios *old) { unsigned int baud, quot; diff --git a/trunk/drivers/serial/sunzilog.c b/trunk/drivers/serial/sunzilog.c index 75de919a9471..b2cc703b2b9e 100644 --- a/trunk/drivers/serial/sunzilog.c +++ b/trunk/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 ktermios *termios, - struct ktermios *old) +sunzilog_set_termios(struct uart_port *port, struct termios *termios, + struct termios *old) { struct uart_sunzilog_port *up = (struct uart_sunzilog_port *) port; unsigned long flags; diff --git a/trunk/drivers/serial/uartlite.c b/trunk/drivers/serial/uartlite.c index 92eba893559d..83690653b78b 100644 --- a/trunk/drivers/serial/uartlite.c +++ b/trunk/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 ktermios *termios, - struct ktermios *old) +static void ulite_set_termios(struct uart_port *port, struct termios *termios, + struct termios *old) { unsigned long flags; unsigned int baud; diff --git a/trunk/drivers/serial/v850e_uart.c b/trunk/drivers/serial/v850e_uart.c index dd98aca6ed08..28f3bbff87bf 100644 --- a/trunk/drivers/serial/v850e_uart.c +++ b/trunk/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 ktermios *termios, - struct ktermios *old) +v850e_uart_set_termios (struct uart_port *port, struct termios *termios, + struct termios *old) { unsigned cflags = termios->c_cflag; diff --git a/trunk/drivers/serial/vr41xx_siu.c b/trunk/drivers/serial/vr41xx_siu.c index cf0e663b42ed..fd51f8182dec 100644 --- a/trunk/drivers/serial/vr41xx_siu.c +++ b/trunk/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 ktermios *new, - struct ktermios *old) +static void siu_set_termios(struct uart_port *port, struct termios *new, + struct termios *old) { tcflag_t c_cflag, c_iflag; uint8_t lcr, fcr, ier; diff --git a/trunk/drivers/tc/zs.c b/trunk/drivers/tc/zs.c index fc3197273663..792becdfe6f8 100644 --- a/trunk/drivers/tc/zs.c +++ b/trunk/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 ktermios *old_termios) +static void rs_set_termios(struct tty_struct *tty, struct termios *old_termios) { struct dec_serial *info = (struct dec_serial *)tty->driver_data; int was_stopped; diff --git a/trunk/drivers/telephony/ixj.c b/trunk/drivers/telephony/ixj.c index df4cc1fb5f68..1b601b6cf2a2 100644 --- a/trunk/drivers/telephony/ixj.c +++ b/trunk/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_path.dentry->d_inode)); + IXJ * j = get_ixj(NUM(file_p->f_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_path.dentry->d_inode)); + IXJ *j = get_ixj(NUM(file_p->f_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_path.dentry->d_inode)); + IXJ *j = get_ixj(NUM(file_p->f_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_path.dentry->d_inode)); + IXJ *j = get_ixj(NUM(file_p->f_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_path.dentry->d_inode)); + IXJ *j = get_ixj(NUM(file_p->f_dentry->d_inode)); return fasync_helper(fd, file_p, mode, &j->async_queue); } diff --git a/trunk/drivers/usb/class/cdc-acm.c b/trunk/drivers/usb/class/cdc-acm.c index 98199628e394..7f1fa956dcdb 100644 --- a/trunk/drivers/usb/class/cdc-acm.c +++ b/trunk/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 ktermios *termios_old) +static void acm_tty_set_termios(struct tty_struct *tty, struct termios *termios_old) { struct acm *acm = tty->driver_data; - struct ktermios *termios = tty->termios; + struct termios *termios = tty->termios; struct usb_cdc_line_coding newline; int newctrl = acm->ctrlout; diff --git a/trunk/drivers/usb/core/inode.c b/trunk/drivers/usb/core/inode.c index 11dad22da41c..b5d6a79af0be 100644 --- a/trunk/drivers/usb/core/inode.c +++ b/trunk/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_path.dentry->d_inode->i_mutex); + mutex_lock(&file->f_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_path.dentry->d_inode->i_mutex); + mutex_unlock(&file->f_dentry->d_inode->i_mutex); return retval; } diff --git a/trunk/drivers/usb/gadget/file_storage.c b/trunk/drivers/usb/gadget/file_storage.c index a265e262a2ee..c98316ce8384 100644 --- a/trunk/drivers/usb/gadget/file_storage.c +++ b/trunk/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_path.dentry->d_inode; + inode = filp->f_dentry->d_inode; mutex_lock(&inode->i_mutex); rc = filemap_fdatawrite(inode->i_mapping); - err = filp->f_op->fsync(filp, filp->f_path.dentry, 1); + err = filp->f_op->fsync(filp, filp->f_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_path.dentry->d_inode; + struct inode *inode = filp->f_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_path.dentry) - inode = filp->f_path.dentry->d_inode; + if (filp->f_dentry) + inode = filp->f_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_path.dentry, curlun->filp->f_path.mnt, + p = d_path(curlun->filp->f_dentry, curlun->filp->f_vfsmnt, 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_path.dentry, - curlun->filp->f_path.mnt, + p = d_path(curlun->filp->f_dentry, + curlun->filp->f_vfsmnt, pathbuf, PATH_MAX); if (IS_ERR(p)) p = NULL; diff --git a/trunk/drivers/usb/gadget/serial.c b/trunk/drivers/usb/gadget/serial.c index 5516c59ed5ec..208e55a667ac 100644 --- a/trunk/drivers/usb/gadget/serial.c +++ b/trunk/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 ktermios *old); +static void gs_set_termios(struct tty_struct *tty, struct termios *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 ktermios *old) +static void gs_set_termios(struct tty_struct *tty, struct termios *old) { } diff --git a/trunk/drivers/usb/input/Kconfig b/trunk/drivers/usb/input/Kconfig index 8a62d4785755..661af7aa6236 100644 --- a/trunk/drivers/usb/input/Kconfig +++ b/trunk/drivers/usb/input/Kconfig @@ -6,10 +6,9 @@ comment "USB Input Devices" config USB_HID tristate "USB Human Interface Device (full HID) support" - default y - depends on USB && HID + depends on USB ---help--- - Say Y here if you want full HID support to connect USB keyboards, + Say Y here if you want full HID support to connect 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 @@ -28,10 +27,20 @@ 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_HID_POWERBOOK +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 bool "Enable support for iBook/PowerBook special keys" default n - depends on USB_HID + depends on USB_HIDINPUT help Say Y here if you want support for the special keys (Fn, Numlock) on Apple iBooks and PowerBooks. @@ -40,7 +49,7 @@ config USB_HID_POWERBOOK config HID_FF bool "Force feedback support (EXPERIMENTAL)" - depends on USB_HID && EXPERIMENTAL + depends on USB_HIDINPUT && 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/trunk/drivers/usb/input/Makefile b/trunk/drivers/usb/input/Makefile index 1a24b5bfa05f..d946d5213b30 100644 --- a/trunk/drivers/usb/input/Makefile +++ b/trunk/drivers/usb/input/Makefile @@ -11,6 +11,9 @@ 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/trunk/drivers/usb/input/appletouch.c b/trunk/drivers/usb/input/appletouch.c index c77291d3d063..4c213513484d 100644 --- a/trunk/drivers/usb/input/appletouch.c +++ b/trunk/drivers/usb/input/appletouch.c @@ -38,29 +38,14 @@ #define APPLE_VENDOR_ID 0x05AC /* These names come from Info.plist in AppleUSBTrackpad.kext */ -#define FOUNTAIN_ANSI_PRODUCT_ID 0x020E -#define FOUNTAIN_ISO_PRODUCT_ID 0x020F - -#define FOUNTAIN_TP_ONLY_PRODUCT_ID 0x030A - -#define GEYSER1_TP_ONLY_PRODUCT_ID 0x030B - -#define GEYSER_ANSI_PRODUCT_ID 0x0214 -#define GEYSER_ISO_PRODUCT_ID 0x0215 -#define GEYSER_JIS_PRODUCT_ID 0x0216 +#define GEYSER_ANSI_PRODUCT_ID 0x0214 +#define GEYSER_ISO_PRODUCT_ID 0x0215 +#define GEYSER_JIS_PRODUCT_ID 0x0216 /* MacBook devices */ -#define GEYSER3_ANSI_PRODUCT_ID 0x0217 -#define GEYSER3_ISO_PRODUCT_ID 0x0218 -#define GEYSER3_JIS_PRODUCT_ID 0x0219 - -/* - * Geyser IV: same as Geyser III according to Info.plist in AppleUSBTrackpad.kext - * -> same IOClass (AppleUSBGrIIITrackpad), same acceleration tables - */ -#define GEYSER4_ANSI_PRODUCT_ID 0x021A -#define GEYSER4_ISO_PRODUCT_ID 0x021B -#define GEYSER4_JIS_PRODUCT_ID 0x021C +#define GEYSER3_ANSI_PRODUCT_ID 0x0217 +#define GEYSER3_ISO_PRODUCT_ID 0x0218 +#define GEYSER3_JIS_PRODUCT_ID 0x0219 #define ATP_DEVICE(prod) \ .match_flags = USB_DEVICE_ID_MATCH_DEVICE | \ @@ -73,26 +58,20 @@ /* table of devices that work with this driver */ static struct usb_device_id atp_table [] = { - { ATP_DEVICE(FOUNTAIN_ANSI_PRODUCT_ID) }, - { ATP_DEVICE(FOUNTAIN_ISO_PRODUCT_ID) }, - { ATP_DEVICE(FOUNTAIN_TP_ONLY_PRODUCT_ID) }, - { ATP_DEVICE(GEYSER1_TP_ONLY_PRODUCT_ID) }, + { ATP_DEVICE(0x020E) }, + { ATP_DEVICE(0x020F) }, + { ATP_DEVICE(0x030A) }, + { ATP_DEVICE(0x030B) }, /* PowerBooks Oct 2005 */ { ATP_DEVICE(GEYSER_ANSI_PRODUCT_ID) }, { ATP_DEVICE(GEYSER_ISO_PRODUCT_ID) }, { ATP_DEVICE(GEYSER_JIS_PRODUCT_ID) }, - /* Core Duo MacBook & MacBook Pro */ { ATP_DEVICE(GEYSER3_ANSI_PRODUCT_ID) }, { ATP_DEVICE(GEYSER3_ISO_PRODUCT_ID) }, { ATP_DEVICE(GEYSER3_JIS_PRODUCT_ID) }, - /* Core2 Duo MacBook & MacBook Pro */ - { ATP_DEVICE(GEYSER4_ANSI_PRODUCT_ID) }, - { ATP_DEVICE(GEYSER4_ISO_PRODUCT_ID) }, - { ATP_DEVICE(GEYSER4_JIS_PRODUCT_ID) }, - /* Terminating entry */ { } }; @@ -129,7 +108,7 @@ MODULE_DEVICE_TABLE (usb, atp_table); */ #define ATP_THRESHOLD 5 -/* MacBook Pro (Geyser 3 & 4) initialization constants */ +/* MacBook Pro (Geyser 3) initialization constants */ #define ATP_GEYSER3_MODE_READ_REQUEST_ID 1 #define ATP_GEYSER3_MODE_WRITE_REQUEST_ID 9 #define ATP_GEYSER3_MODE_REQUEST_VALUE 0x300 @@ -175,13 +154,6 @@ MODULE_AUTHOR("Johannes Berg, Stelian Pop, Frank Arnold, Michael Hanselmann"); MODULE_DESCRIPTION("Apple PowerBooks USB touchpad driver"); MODULE_LICENSE("GPL"); -/* - * Make the threshold a module parameter - */ -static int threshold = ATP_THRESHOLD; -module_param(threshold, int, 0644); -MODULE_PARM_DESC(threshold, "Discards any change in data from a sensor (trackpad has hundreds of these sensors) less than this value"); - static int debug = 1; module_param(debug, int, 0644); MODULE_PARM_DESC(debug, "Activate debugging output"); @@ -202,10 +174,7 @@ static inline int atp_is_geyser_3(struct atp *dev) return (productId == GEYSER3_ANSI_PRODUCT_ID) || (productId == GEYSER3_ISO_PRODUCT_ID) || - (productId == GEYSER3_JIS_PRODUCT_ID) || - (productId == GEYSER4_ANSI_PRODUCT_ID) || - (productId == GEYSER4_ISO_PRODUCT_ID) || - (productId == GEYSER4_JIS_PRODUCT_ID); + (productId == GEYSER3_JIS_PRODUCT_ID); } static int atp_calculate_abs(int *xy_sensors, int nb_sensors, int fact, @@ -214,48 +183,16 @@ static int atp_calculate_abs(int *xy_sensors, int nb_sensors, int fact, int i; /* values to calculate mean */ int pcum = 0, psum = 0; - int is_increasing = 0; *fingers = 0; for (i = 0; i < nb_sensors; i++) { - if (xy_sensors[i] < threshold) { - if (is_increasing) - is_increasing = 0; - + if (xy_sensors[i] < ATP_THRESHOLD) continue; - } - - /* - * Makes the finger detection more versatile. For example, - * two fingers with no gap will be detected. Also, my - * tests show it less likely to have intermittent loss - * of multiple finger readings while moving around (scrolling). - * - * Changes the multiple finger detection to counting humps on - * sensors (transitions from nonincreasing to increasing) - * instead of counting transitions from low sensors (no - * finger reading) to high sensors (finger above - * sensor) - * - * - Jason Parekh - */ - if (i < 1 || (!is_increasing && xy_sensors[i - 1] < xy_sensors[i])) { + if ((i - 1 < 0) || (xy_sensors[i - 1] < ATP_THRESHOLD)) (*fingers)++; - is_increasing = 1; - } else if (i > 0 && xy_sensors[i - 1] >= xy_sensors[i]) { - is_increasing = 0; - } - - /* - * Subtracts threshold so a high sensor that just passes the threshold - * won't skew the calculated absolute coordinate. Fixes an issue - * where slowly moving the mouse would occassionaly jump a number of - * pixels (let me restate--slowly moving the mouse makes this issue - * most apparent). - */ - pcum += (xy_sensors[i] - threshold) * i; - psum += (xy_sensors[i] - threshold); + pcum += xy_sensors[i] * i; + psum += xy_sensors[i]; } if (psum > 0) { diff --git a/trunk/drivers/usb/input/hid-core.c b/trunk/drivers/usb/input/hid-core.c index 89fa6885709b..f1d0e1d69828 100644 --- a/trunk/drivers/usb/input/hid-core.c +++ b/trunk/drivers/usb/input/hid-core.c @@ -4,7 +4,6 @@ * Copyright (c) 1999 Andreas Gal * Copyright (c) 2000-2005 Vojtech Pavlik * Copyright (c) 2005 Michael Haboustak for Concept2, Inc - * Copyright (c) 2006 Jiri Kosina */ /* @@ -33,9 +32,8 @@ #include -#include +#include "hid.h" #include -#include "usbhid.h" /* * Version Information @@ -56,10 +54,886 @@ static unsigned int hid_mousepoll_interval; module_param_named(mousepoll, hid_mousepoll_interval, uint, 0644); MODULE_PARM_DESC(mousepoll, "Polling interval of mice"); -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)"); +/* + * 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; +} /* * Input submission and I/O error handler. @@ -72,16 +946,15 @@ 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(&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); + 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); if (rc != 0) - clear_bit(HID_IN_RUNNING, &usbhid->iofl); + clear_bit(HID_IN_RUNNING, &hid->iofl); } - spin_unlock_irqrestore(&usbhid->inlock, flags); + spin_unlock_irqrestore(&hid->inlock, flags); return rc; } @@ -89,9 +962,8 @@ 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(&usbhid->intf->dev, "retrying intr urb\n"); + dev_dbg(&hid->intf->dev, "retrying intr urb\n"); if (hid_start_in(hid)) hid_io_error(hid); } @@ -99,39 +971,38 @@ 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 usbhid_device *usbhid = - container_of(work, struct usbhid_device, reset_work); - struct hid_device *hid = usbhid->hid; + struct hid_device *hid = + container_of(work, struct hid_device, reset_work); int rc_lock, rc = 0; - 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); + 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); hid_start_in(hid); } - 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); + 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); if (rc_lock >= 0) { - rc = usb_reset_composite_device(to_usb_device(hid->dev), usbhid->intf); + rc = usb_reset_composite_device(hid->dev, hid->intf); if (rc_lock) - usb_unlock_device(to_usb_device(hid->dev)); + usb_unlock_device(hid->dev); } - clear_bit(HID_RESET_PENDING, &usbhid->iofl); + clear_bit(HID_RESET_PENDING, &hid->iofl); } switch (rc) { case 0: - if (!test_bit(HID_IN_RUNNING, &usbhid->iofl)) + if (!test_bit(HID_IN_RUNNING, &hid->iofl)) hid_io_error(hid); break; default: err("can't reset device, %s-%s/input%d, status %d", - to_usb_device(hid->dev)->bus->bus_name, - to_usb_device(hid->dev)->devpath, - usbhid->ifnum, rc); + hid->dev->bus->bus_name, + hid->dev->devpath, + hid->ifnum, rc); /* FALLTHROUGH */ case -EHOSTUNREACH: case -ENODEV: @@ -144,34 +1015,33 @@ 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(&usbhid->inlock, flags); + spin_lock_irqsave(&hid->inlock, flags); /* Stop when disconnected */ - if (usb_get_intfdata(usbhid->intf) == NULL) + if (usb_get_intfdata(hid->intf) == NULL) goto done; /* When an error occurs, retry at increasing intervals */ - 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 (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 (time_after(jiffies, usbhid->stop_retry)) { + if (time_after(jiffies, hid->stop_retry)) { /* Retries failed, so do a port reset */ - if (!test_and_set_bit(HID_RESET_PENDING, &usbhid->iofl)) { - schedule_work(&usbhid->reset_work); + if (!test_and_set_bit(HID_RESET_PENDING, &hid->iofl)) { + schedule_work(&hid->reset_work); goto done; } } - mod_timer(&usbhid->io_retry, - jiffies + msecs_to_jiffies(usbhid->retry_delay)); + mod_timer(&hid->io_retry, + jiffies + msecs_to_jiffies(hid->retry_delay)); done: - spin_unlock_irqrestore(&usbhid->inlock, flags); + spin_unlock_irqrestore(&hid->inlock, flags); } /* @@ -181,31 +1051,28 @@ static void hid_io_error(struct hid_device *hid) 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 */ - usbhid->retry_delay = 0; - hid_input_report(urb->context, HID_INPUT_REPORT, - urb->transfer_buffer, - urb->actual_length, 1); + hid->retry_delay = 0; + hid_input_report(HID_INPUT_REPORT, urb, 1); break; case -EPIPE: /* stall */ - clear_bit(HID_IN_RUNNING, &usbhid->iofl); - set_bit(HID_CLEAR_HALT, &usbhid->iofl); - schedule_work(&usbhid->reset_work); + clear_bit(HID_IN_RUNNING, &hid->iofl); + set_bit(HID_CLEAR_HALT, &hid->iofl); + schedule_work(&hid->reset_work); return; case -ECONNRESET: /* unlink */ case -ENOENT: case -ESHUTDOWN: /* unplug */ - clear_bit(HID_IN_RUNNING, &usbhid->iofl); + clear_bit(HID_IN_RUNNING, &hid->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, &usbhid->iofl); + clear_bit(HID_IN_RUNNING, &hid->iofl); hid_io_error(hid); return; default: /* error */ @@ -214,17 +1081,78 @@ static void hid_irq_in(struct urb *urb) status = usb_submit_urb(urb, GFP_ATOMIC); if (status) { - clear_bit(HID_IN_RUNNING, &usbhid->iofl); + clear_bit(HID_IN_RUNNING, &hid->iofl); if (status != -EPERM) { err("can't resubmit intr, %s-%s/input%d, status %d", - to_usb_device(hid->dev)->bus->bus_name, - to_usb_device(hid->dev)->devpath, - usbhid->ifnum, status); + hid->dev->bus->bus_name, + hid->dev->devpath, + hid->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. */ @@ -245,17 +1173,16 @@ 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 = usbhid->out[usbhid->outtail]; + report = hid->out[hid->outtail]; - 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); + hid_output_report(report, hid->outbuf); + hid->urbout->transfer_buffer_length = ((report->size - 1) >> 3) + 1 + (report->id > 0); + hid->urbout->dev = hid->dev; dbg("submitting out urb"); - if (usb_submit_urb(usbhid->urbout, GFP_ATOMIC)) { + if (usb_submit_urb(hid->urbout, GFP_ATOMIC)) { err("usb_submit_urb(out) failed"); return -1; } @@ -268,43 +1195,42 @@ 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 = usbhid->ctrl[usbhid->ctrltail].report; - dir = usbhid->ctrl[usbhid->ctrltail].dir; + report = hid->ctrl[hid->ctrltail].report; + dir = hid->ctrl[hid->ctrltail].dir; len = ((report->size - 1) >> 3) + 1 + (report->id > 0); if (dir == USB_DIR_OUT) { - hid_output_report(report, usbhid->ctrlbuf); - usbhid->urbctrl->pipe = usb_sndctrlpipe(to_usb_device(hid->dev), 0); - usbhid->urbctrl->transfer_buffer_length = len; + hid_output_report(report, hid->ctrlbuf); + hid->urbctrl->pipe = usb_sndctrlpipe(hid->dev, 0); + hid->urbctrl->transfer_buffer_length = len; } else { int maxpacket, padlen; - usbhid->urbctrl->pipe = usb_rcvctrlpipe(to_usb_device(hid->dev), 0); - maxpacket = usb_maxpacket(to_usb_device(hid->dev), usbhid->urbctrl->pipe, 0); + hid->urbctrl->pipe = usb_rcvctrlpipe(hid->dev, 0); + maxpacket = usb_maxpacket(hid->dev, hid->urbctrl->pipe, 0); if (maxpacket > 0) { padlen = (len + maxpacket - 1) / maxpacket; padlen *= maxpacket; - if (padlen > usbhid->bufsize) - padlen = usbhid->bufsize; + if (padlen > hid->bufsize) + padlen = hid->bufsize; } else padlen = 0; - usbhid->urbctrl->transfer_buffer_length = padlen; + hid->urbctrl->transfer_buffer_length = padlen; } - usbhid->urbctrl->dev = to_usb_device(hid->dev); + hid->urbctrl->dev = hid->dev; - 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); + 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); dbg("submitting ctrl urb: %s wValue=0x%04x wIndex=0x%04x wLength=%u", - usbhid->cr->bRequest == HID_REQ_SET_REPORT ? "Set_Report" : "Get_Report", - usbhid->cr->wValue, usbhid->cr->wIndex, usbhid->cr->wLength); + hid->cr->bRequest == HID_REQ_SET_REPORT ? "Set_Report" : "Get_Report", + hid->cr->wValue, hid->cr->wIndex, hid->cr->wLength); - if (usb_submit_urb(usbhid->urbctrl, GFP_ATOMIC)) { + if (usb_submit_urb(hid->urbctrl, GFP_ATOMIC)) { err("usb_submit_urb(ctrl) failed"); return -1; } @@ -319,7 +1245,6 @@ 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; @@ -337,24 +1262,24 @@ static void hid_irq_out(struct urb *urb) warn("output irq status %d received", urb->status); } - spin_lock_irqsave(&usbhid->outlock, flags); + spin_lock_irqsave(&hid->outlock, flags); if (unplug) - usbhid->outtail = usbhid->outhead; + hid->outtail = hid->outhead; else - usbhid->outtail = (usbhid->outtail + 1) & (HID_OUTPUT_FIFO_SIZE - 1); + hid->outtail = (hid->outtail + 1) & (HID_OUTPUT_FIFO_SIZE - 1); - if (usbhid->outhead != usbhid->outtail) { + if (hid->outhead != hid->outtail) { if (hid_submit_out(hid)) { - clear_bit(HID_OUT_RUNNING, &usbhid->iofl); + clear_bit(HID_OUT_RUNNING, &hid->iofl); wake_up(&hid->wait); } - spin_unlock_irqrestore(&usbhid->outlock, flags); + spin_unlock_irqrestore(&hid->outlock, flags); return; } - clear_bit(HID_OUT_RUNNING, &usbhid->iofl); - spin_unlock_irqrestore(&usbhid->outlock, flags); + clear_bit(HID_OUT_RUNNING, &hid->iofl); + spin_unlock_irqrestore(&hid->outlock, flags); wake_up(&hid->wait); } @@ -365,17 +1290,15 @@ 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(&usbhid->ctrllock, flags); + spin_lock_irqsave(&hid->ctrllock, flags); switch (urb->status) { case 0: /* success */ - 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); + if (hid->ctrl[hid->ctrltail].dir == USB_DIR_IN) + hid_input_report(hid->ctrl[hid->ctrltail].report->type, urb, 0); break; case -ESHUTDOWN: /* unplug */ unplug = 1; @@ -390,102 +1313,76 @@ static void hid_ctrl(struct urb *urb) } if (unplug) - usbhid->ctrltail = usbhid->ctrlhead; + hid->ctrltail = hid->ctrlhead; else - usbhid->ctrltail = (usbhid->ctrltail + 1) & (HID_CONTROL_FIFO_SIZE - 1); + hid->ctrltail = (hid->ctrltail + 1) & (HID_CONTROL_FIFO_SIZE - 1); - if (usbhid->ctrlhead != usbhid->ctrltail) { + if (hid->ctrlhead != hid->ctrltail) { if (hid_submit_ctrl(hid)) { - clear_bit(HID_CTRL_RUNNING, &usbhid->iofl); + clear_bit(HID_CTRL_RUNNING, &hid->iofl); wake_up(&hid->wait); } - spin_unlock_irqrestore(&usbhid->ctrllock, flags); + spin_unlock_irqrestore(&hid->ctrllock, flags); return; } - clear_bit(HID_CTRL_RUNNING, &usbhid->iofl); - spin_unlock_irqrestore(&usbhid->ctrllock, flags); + clear_bit(HID_CTRL_RUNNING, &hid->iofl); + spin_unlock_irqrestore(&hid->ctrllock, flags); wake_up(&hid->wait); } -void usbhid_submit_report(struct hid_device *hid, struct hid_report *report, unsigned char dir) +void hid_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 (usbhid->urbout && dir == USB_DIR_OUT && report->type == HID_OUTPUT_REPORT) { + if (hid->urbout && dir == USB_DIR_OUT && report->type == HID_OUTPUT_REPORT) { - spin_lock_irqsave(&usbhid->outlock, flags); + spin_lock_irqsave(&hid->outlock, flags); - if ((head = (usbhid->outhead + 1) & (HID_OUTPUT_FIFO_SIZE - 1)) == usbhid->outtail) { - spin_unlock_irqrestore(&usbhid->outlock, flags); + if ((head = (hid->outhead + 1) & (HID_OUTPUT_FIFO_SIZE - 1)) == hid->outtail) { + spin_unlock_irqrestore(&hid->outlock, flags); warn("output queue full"); return; } - usbhid->out[usbhid->outhead] = report; - usbhid->outhead = head; + hid->out[hid->outhead] = report; + hid->outhead = head; - if (!test_and_set_bit(HID_OUT_RUNNING, &usbhid->iofl)) + if (!test_and_set_bit(HID_OUT_RUNNING, &hid->iofl)) if (hid_submit_out(hid)) - clear_bit(HID_OUT_RUNNING, &usbhid->iofl); + clear_bit(HID_OUT_RUNNING, &hid->iofl); - spin_unlock_irqrestore(&usbhid->outlock, flags); + spin_unlock_irqrestore(&hid->outlock, flags); return; } - spin_lock_irqsave(&usbhid->ctrllock, flags); + spin_lock_irqsave(&hid->ctrllock, flags); - if ((head = (usbhid->ctrlhead + 1) & (HID_CONTROL_FIFO_SIZE - 1)) == usbhid->ctrltail) { - spin_unlock_irqrestore(&usbhid->ctrllock, flags); + if ((head = (hid->ctrlhead + 1) & (HID_CONTROL_FIFO_SIZE - 1)) == hid->ctrltail) { + spin_unlock_irqrestore(&hid->ctrllock, flags); warn("control queue full"); return; } - usbhid->ctrl[usbhid->ctrlhead].report = report; - usbhid->ctrl[usbhid->ctrlhead].dir = dir; - usbhid->ctrlhead = head; + hid->ctrl[hid->ctrlhead].report = report; + hid->ctrl[hid->ctrlhead].dir = dir; + hid->ctrlhead = head; - if (!test_and_set_bit(HID_CTRL_RUNNING, &usbhid->iofl)) + if (!test_and_set_bit(HID_CTRL_RUNNING, &hid->iofl)) if (hid_submit_ctrl(hid)) - clear_bit(HID_CTRL_RUNNING, &usbhid->iofl); - - spin_unlock_irqrestore(&usbhid->ctrllock, flags); -} - -static int usb_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); - usbhid_submit_report(hid, field->report, USB_DIR_OUT); + clear_bit(HID_CTRL_RUNNING, &hid->iofl); - return 0; + spin_unlock_irqrestore(&hid->ctrllock, flags); } -int usbhid_wait_io(struct hid_device *hid) +int hid_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)), + if (!wait_event_timeout(hid->wait, (!test_bit(HID_CTRL_RUNNING, &hid->iofl) && + !test_bit(HID_OUT_RUNNING, &hid->iofl)), 10*HZ)) { dbg("timeout waiting for ctrl or out queue to clear"); return -1; @@ -517,7 +1414,7 @@ static int hid_get_class_descriptor(struct usb_device *dev, int ifnum, return result; } -int usbhid_open(struct hid_device *hid) +int hid_open(struct hid_device *hid) { ++hid->open; if (hid_start_in(hid)) @@ -525,24 +1422,10 @@ int usbhid_open(struct hid_device *hid) return 0; } -void usbhid_close(struct hid_device *hid) +void hid_close(struct hid_device *hid) { - struct usbhid_device *usbhid = hid->driver_data; - if (!--hid->open) - 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); + usb_kill_urb(hid->urbin); } #define USB_VENDOR_ID_PANJIT 0x134c @@ -554,27 +1437,26 @@ static void hidinput_close(struct input_dev *dev) * Initialize all reports */ -void usbhid_init_reports(struct hid_device *hid) +void hid_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) - usbhid_submit_report(hid, report, USB_DIR_IN); + hid_submit_report(hid, report, USB_DIR_IN); list_for_each_entry(report, &hid->report_enum[HID_FEATURE_REPORT].report_list, list) - usbhid_submit_report(hid, report, USB_DIR_IN); + hid_submit_report(hid, report, USB_DIR_IN); err = 0; - ret = usbhid_wait_io(hid); + ret = hid_wait_io(hid); while (ret) { err |= ret; - 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 (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 (err) @@ -788,9 +1670,6 @@ void usbhid_init_reports(struct hid_device *hid) #define USB_VENDOR_ID_AIRCABLE 0x16CA #define USB_DEVICE_ID_AIRCABLE1 0x1502 -#define USB_VENDOR_ID_LOGITECH 0x046d -#define USB_DEVICE_ID_LOGITECH_USB_RECEIVER 0xc101 - /* * Alphabetically sorted blacklist by quirk type. */ @@ -962,9 +1841,7 @@ static const struct hid_blacklist { { USB_VENDOR_ID_PANJIT, 0x0004, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_TURBOX, USB_DEVICE_ID_TURBOX_KEYBOARD, HID_QUIRK_NOGET }, - - { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_USB_RECEIVER, HID_QUIRK_BAD_RELATIVE_KEYS }, - + { 0, 0 } }; @@ -987,15 +1864,13 @@ 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) { - struct usbhid_device *usbhid = hid->driver_data; - - if (!(usbhid->inbuf = usb_buffer_alloc(dev, usbhid->bufsize, GFP_ATOMIC, &usbhid->inbuf_dma))) + if (!(hid->inbuf = usb_buffer_alloc(dev, hid->bufsize, GFP_ATOMIC, &hid->inbuf_dma))) return -1; - if (!(usbhid->outbuf = usb_buffer_alloc(dev, usbhid->bufsize, GFP_ATOMIC, &usbhid->outbuf_dma))) + if (!(hid->outbuf = usb_buffer_alloc(dev, hid->bufsize, GFP_ATOMIC, &hid->outbuf_dma))) return -1; - if (!(usbhid->cr = usb_buffer_alloc(dev, sizeof(*(usbhid->cr)), GFP_ATOMIC, &usbhid->cr_dma))) + if (!(hid->cr = usb_buffer_alloc(dev, sizeof(*(hid->cr)), GFP_ATOMIC, &hid->cr_dma))) return -1; - if (!(usbhid->ctrlbuf = usb_buffer_alloc(dev, usbhid->bufsize, GFP_ATOMIC, &usbhid->ctrlbuf_dma))) + if (!(hid->ctrlbuf = usb_buffer_alloc(dev, hid->bufsize, GFP_ATOMIC, &hid->ctrlbuf_dma))) return -1; return 0; @@ -1003,16 +1878,14 @@ 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) { - 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); + 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); } /* @@ -1038,7 +1911,6 @@ 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) @@ -1108,19 +1980,13 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf) kfree(rdesc); hid->quirks = quirks; - if (!(usbhid = kzalloc(sizeof(struct usbhid_device), GFP_KERNEL))) - goto fail; - - hid->driver_data = usbhid; - usbhid->hid = hid; + 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); - 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 (usbhid->bufsize > HID_MAX_BUFFER_SIZE) - usbhid->bufsize = HID_MAX_BUFFER_SIZE; + if (hid->bufsize > HID_MAX_BUFFER_SIZE) + hid->bufsize = HID_MAX_BUFFER_SIZE; hid_find_max_report(hid, HID_INPUT_REPORT, &insize); @@ -1149,47 +2015,47 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf) interval = hid_mousepoll_interval; if (usb_endpoint_dir_in(endpoint)) { - if (usbhid->urbin) + if (hid->urbin) continue; - if (!(usbhid->urbin = usb_alloc_urb(0, GFP_KERNEL))) + if (!(hid->urbin = usb_alloc_urb(0, GFP_KERNEL))) goto fail; pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress); - usb_fill_int_urb(usbhid->urbin, dev, pipe, usbhid->inbuf, insize, + usb_fill_int_urb(hid->urbin, dev, pipe, hid->inbuf, insize, hid_irq_in, hid, interval); - usbhid->urbin->transfer_dma = usbhid->inbuf_dma; - usbhid->urbin->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; + hid->urbin->transfer_dma = hid->inbuf_dma; + hid->urbin->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; } else { - if (usbhid->urbout) + if (hid->urbout) continue; - if (!(usbhid->urbout = usb_alloc_urb(0, GFP_KERNEL))) + if (!(hid->urbout = usb_alloc_urb(0, GFP_KERNEL))) goto fail; pipe = usb_sndintpipe(dev, endpoint->bEndpointAddress); - usb_fill_int_urb(usbhid->urbout, dev, pipe, usbhid->outbuf, 0, + usb_fill_int_urb(hid->urbout, dev, pipe, hid->outbuf, 0, hid_irq_out, hid, interval); - usbhid->urbout->transfer_dma = usbhid->outbuf_dma; - usbhid->urbout->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; + hid->urbout->transfer_dma = hid->outbuf_dma; + hid->urbout->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; } } - if (!usbhid->urbin) { + if (!hid->urbin) { err("couldn't find an input interrupt endpoint"); goto fail; } init_waitqueue_head(&hid->wait); - INIT_WORK(&usbhid->reset_work, hid_reset); - setup_timer(&usbhid->io_retry, hid_retry_timeout, (unsigned long) hid); + INIT_WORK(&hid->reset_work, hid_reset); + setup_timer(&hid->io_retry, hid_retry_timeout, (unsigned long) hid); - spin_lock_init(&usbhid->inlock); - spin_lock_init(&usbhid->outlock); - spin_lock_init(&usbhid->ctrllock); + spin_lock_init(&hid->inlock); + spin_lock_init(&hid->outlock); + spin_lock_init(&hid->ctrllock); hid->version = le16_to_cpu(hdesc->bcdHID); hid->country = hdesc->bCountryCode; - hid->dev = &dev->dev; - usbhid->intf = intf; - usbhid->ifnum = interface->desc.bInterfaceNumber; + hid->dev = dev; + hid->intf = intf; + hid->ifnum = interface->desc.bInterfaceNumber; hid->name[0] = 0; @@ -1207,10 +2073,6 @@ 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); @@ -1221,32 +2083,22 @@ 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; - usbhid->urbctrl = usb_alloc_urb(0, GFP_KERNEL); - if (!usbhid->urbctrl) + hid->urbctrl = usb_alloc_urb(0, GFP_KERNEL); + if (!hid->urbctrl) goto fail; - 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 + 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); return hid; fail: - usb_free_urb(usbhid->urbin); - usb_free_urb(usbhid->urbout); - usb_free_urb(usbhid->urbctrl); + usb_free_urb(hid->urbin); + usb_free_urb(hid->urbout); + usb_free_urb(hid->urbctrl); hid_free_buffers(dev, hid); hid_free_device(hid); @@ -1256,21 +2108,18 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf) static void hid_disconnect(struct usb_interface *intf) { struct hid_device *hid = usb_get_intfdata (intf); - struct usbhid_device *usbhid; if (!hid) return; - usbhid = hid->driver_data; - - spin_lock_irq(&usbhid->inlock); /* Sync with error handler */ + spin_lock_irq(&hid->inlock); /* Sync with error handler */ usb_set_intfdata(intf, NULL); - spin_unlock_irq(&usbhid->inlock); - usb_kill_urb(usbhid->urbin); - usb_kill_urb(usbhid->urbout); - usb_kill_urb(usbhid->urbctrl); + spin_unlock_irq(&hid->inlock); + usb_kill_urb(hid->urbin); + usb_kill_urb(hid->urbout); + usb_kill_urb(hid->urbctrl); - del_timer_sync(&usbhid->io_retry); + del_timer_sync(&hid->io_retry); flush_scheduled_work(); if (hid->claimed & HID_CLAIMED_INPUT) @@ -1278,11 +2127,11 @@ static void hid_disconnect(struct usb_interface *intf) if (hid->claimed & HID_CLAIMED_HIDDEV) hiddev_disconnect(hid); - usb_free_urb(usbhid->urbin); - usb_free_urb(usbhid->urbctrl); - usb_free_urb(usbhid->urbout); + usb_free_urb(hid->urbin); + usb_free_urb(hid->urbctrl); + usb_free_urb(hid->urbout); - hid_free_buffers(to_usb_device(hid->dev), hid); + hid_free_buffers(hid->dev, hid); hid_free_device(hid); } @@ -1299,7 +2148,7 @@ static int hid_probe(struct usb_interface *intf, const struct usb_device_id *id) if (!(hid = usb_hid_configure(intf))) return -ENODEV; - usbhid_init_reports(hid); + hid_init_reports(hid); hid_dump_device(hid); if (!hidinput_connect(hid)) @@ -1315,13 +2164,6 @@ 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) @@ -1352,13 +2194,12 @@ 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(&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); + 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); dev_dbg(&intf->dev, "suspend\n"); return 0; } @@ -1366,11 +2207,10 @@ 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, &usbhid->iofl); - usbhid->retry_delay = 0; + clear_bit(HID_SUSPENDED, &hid->iofl); + hid->retry_delay = 0; status = hid_start_in(hid); dev_dbg(&intf->dev, "resume status %d\n", status); return status; diff --git a/trunk/include/linux/hid-debug.h b/trunk/drivers/usb/input/hid-debug.h similarity index 100% rename from trunk/include/linux/hid-debug.h rename to trunk/drivers/usb/input/hid-debug.h diff --git a/trunk/drivers/usb/input/hid-ff.c b/trunk/drivers/usb/input/hid-ff.c index f8f660ee3fac..a8fc46c721c5 100644 --- a/trunk/drivers/usb/input/hid-ff.c +++ b/trunk/drivers/usb/input/hid-ff.c @@ -32,7 +32,7 @@ #undef DEBUG #include -#include +#include "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(to_usb_device(hid->dev)->descriptor.idVendor); - int product = le16_to_cpu(to_usb_device(hid->dev)->descriptor.idProduct); + int vendor = le16_to_cpu(hid->dev->descriptor.idVendor); + int product = le16_to_cpu(hid->dev->descriptor.idProduct); for (init = inits; init->idVendor; init++) if (init->idVendor == vendor && init->idProduct == product) @@ -79,5 +79,3 @@ int hid_ff_init(struct hid_device* hid) return init->init(hid); } -EXPORT_SYMBOL_GPL(hid_ff_init); - diff --git a/trunk/drivers/hid/hid-input.c b/trunk/drivers/usb/input/hid-input.c similarity index 88% rename from trunk/drivers/hid/hid-input.c rename to trunk/drivers/usb/input/hid-input.c index 14cdf09316ce..68e7ebb978a9 100644 --- a/trunk/drivers/hid/hid-input.c +++ b/trunk/drivers/usb/input/hid-input.c @@ -2,9 +2,8 @@ * $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 * - * HID to Linux Input mapping + * USB HID to Linux Input mapping */ /* @@ -34,7 +33,7 @@ #undef DEBUG -#include +#include "hid.h" #define unk KEY_UNKNOWN @@ -82,42 +81,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 }, { } }; @@ -128,6 +127,11 @@ 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; @@ -141,7 +145,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; @@ -154,7 +158,7 @@ static int hidinput_pb_event(struct hid_device *hid, struct input_dev *input, return 1; } - if (hid->pb_fnmode) { + if (usbhid_pb_fnmode) { int do_translate; trans = find_translation(powerbook_fn_keys, usage->code); @@ -163,8 +167,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 = - (hid->pb_fnmode == 2 && (hid->quirks & HID_QUIRK_POWERBOOK_FN_ON)) || - (hid->pb_fnmode == 1 && !(hid->quirks & HID_QUIRK_POWERBOOK_FN_ON)); + (usbhid_pb_fnmode == 2 && (hid->quirks & HID_QUIRK_POWERBOOK_FN_ON)) || + (usbhid_pb_fnmode == 1 && !(hid->quirks & HID_QUIRK_POWERBOOK_FN_ON)); else do_translate = (hid->quirks & HID_QUIRK_POWERBOOK_FN_ON); @@ -181,7 +185,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) { @@ -223,11 +227,10 @@ 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; } @@ -578,10 +581,6 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel || ((device->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_7) && (usage->hid == 0x00090007))) goto ignore; - if ((device->quirks & HID_QUIRK_BAD_RELATIVE_KEYS) && - usage->type == EV_KEY && (field->flags & HID_MAIN_ITEM_RELATIVE)) - field->flags &= ~HID_MAIN_ITEM_RELATIVE; - set_bit(usage->type, input->evbit); while (usage->code <= max && test_and_set_bit(usage->code, bit)) @@ -721,9 +720,8 @@ 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); -int hidinput_find_field(struct hid_device *hid, unsigned int type, unsigned int code, struct hid_field **field) +static 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; @@ -738,7 +736,41 @@ int hidinput_find_field(struct hid_device *hid, unsigned int type, unsigned int } return -1; } -EXPORT_SYMBOL_GPL(hidinput_find_field); + +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); +} /* * Register the input device; print a message. @@ -748,6 +780,7 @@ EXPORT_SYMBOL_GPL(hidinput_find_field); 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; @@ -781,18 +814,16 @@ int hidinput_connect(struct hid_device *hid) } input_dev->private = hid; - input_dev->event = hid->hidinput_input_event; - input_dev->open = hid->hidinput_open; - input_dev->close = hid->hidinput_close; + input_dev->event = hidinput_input_event; + input_dev->open = hidinput_open; + input_dev->close = hidinput_close; input_dev->name = hid->name; input_dev->phys = hid->phys; input_dev->uniq = hid->uniq; - 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; + usb_to_input_id(dev, &input_dev->id); + input_dev->cdev.dev = &hid->intf->dev; + hidinput->input = input_dev; list_add_tail(&hidinput->list, &hid->inputs); } @@ -814,12 +845,16 @@ int hidinput_connect(struct hid_device *hid) } } - if (hidinput) + /* 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); input_register_device(hidinput->input); + } return 0; } -EXPORT_SYMBOL_GPL(hidinput_connect); void hidinput_disconnect(struct hid_device *hid) { @@ -831,5 +866,3 @@ void hidinput_disconnect(struct hid_device *hid) kfree(hidinput); } } -EXPORT_SYMBOL_GPL(hidinput_disconnect); - diff --git a/trunk/drivers/usb/input/hid-lgff.c b/trunk/drivers/usb/input/hid-lgff.c index e47466268565..93da222b6da8 100644 --- a/trunk/drivers/usb/input/hid-lgff.c +++ b/trunk/drivers/usb/input/hid-lgff.c @@ -29,8 +29,7 @@ #include #include -#include -#include "usbhid.h" +#include "hid.h" struct device_type { u16 idVendor; @@ -76,7 +75,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); - usbhid_submit_report(hid, report, USB_DIR_OUT); + hid_submit_report(hid, report, USB_DIR_OUT); break; case FF_RUMBLE: @@ -91,7 +90,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); - usbhid_submit_report(hid, report, USB_DIR_OUT); + hid_submit_report(hid, report, USB_DIR_OUT); break; } return 0; diff --git a/trunk/drivers/usb/input/hid-pidff.c b/trunk/drivers/usb/input/hid-pidff.c index cbd2d53fefff..5420c13eb8eb 100644 --- a/trunk/drivers/usb/input/hid-pidff.c +++ b/trunk/drivers/usb/input/hid-pidff.c @@ -28,9 +28,7 @@ #include #include -#include - -#include "usbhid.h" +#include "hid.h" #define PID_EFFECTS_MAX 64 @@ -262,7 +260,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]); - usbhid_submit_report(pidff->hid, pidff->reports[PID_SET_ENVELOPE], + hid_submit_report(pidff->hid, pidff->reports[PID_SET_ENVELOPE], USB_DIR_OUT); } @@ -289,7 +287,7 @@ static void pidff_set_constant_force_report(struct pidff_device *pidff, pidff_set_signed(&pidff->set_constant[PID_MAGNITUDE], effect->u.constant.level); - usbhid_submit_report(pidff->hid, pidff->reports[PID_SET_CONSTANT], + hid_submit_report(pidff->hid, pidff->reports[PID_SET_CONSTANT], USB_DIR_OUT); } @@ -324,7 +322,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; - usbhid_submit_report(pidff->hid, pidff->reports[PID_SET_EFFECT], + hid_submit_report(pidff->hid, pidff->reports[PID_SET_EFFECT], USB_DIR_OUT); } @@ -356,7 +354,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; - usbhid_submit_report(pidff->hid, pidff->reports[PID_SET_PERIODIC], + hid_submit_report(pidff->hid, pidff->reports[PID_SET_PERIODIC], USB_DIR_OUT); } @@ -398,8 +396,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); - usbhid_wait_io(pidff->hid); - usbhid_submit_report(pidff->hid, pidff->reports[PID_SET_CONDITION], + hid_wait_io(pidff->hid); + hid_submit_report(pidff->hid, pidff->reports[PID_SET_CONDITION], USB_DIR_OUT); } } @@ -440,7 +438,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); - usbhid_submit_report(pidff->hid, pidff->reports[PID_SET_RAMP], + hid_submit_report(pidff->hid, pidff->reports[PID_SET_RAMP], USB_DIR_OUT); } @@ -465,19 +463,19 @@ static int pidff_request_effect_upload(struct pidff_device *pidff, int efnum) int j; pidff->create_new_effect_type->value[0] = efnum; - usbhid_submit_report(pidff->hid, pidff->reports[PID_CREATE_NEW_EFFECT], + hid_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; - usbhid_wait_io(pidff->hid); + hid_wait_io(pidff->hid); for (j = 0; j < 60; j++) { debug("pid_block_load requested"); - usbhid_submit_report(pidff->hid, pidff->reports[PID_BLOCK_LOAD], + hid_submit_report(pidff->hid, pidff->reports[PID_BLOCK_LOAD], USB_DIR_IN); - usbhid_wait_io(pidff->hid); + hid_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", @@ -513,8 +511,8 @@ static void pidff_playback_pid(struct pidff_device *pidff, int pid_id, int n) pidff->effect_operation[PID_LOOP_COUNT].value[0] = n; } - usbhid_wait_io(pidff->hid); - usbhid_submit_report(pidff->hid, pidff->reports[PID_EFFECT_OPERATION], + hid_wait_io(pidff->hid); + hid_submit_report(pidff->hid, pidff->reports[PID_EFFECT_OPERATION], USB_DIR_OUT); } @@ -536,7 +534,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; - usbhid_submit_report(pidff->hid, pidff->reports[PID_BLOCK_FREE], + hid_submit_report(pidff->hid, pidff->reports[PID_BLOCK_FREE], USB_DIR_OUT); } @@ -716,7 +714,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); - usbhid_submit_report(pidff->hid, pidff->reports[PID_DEVICE_GAIN], + hid_submit_report(pidff->hid, pidff->reports[PID_DEVICE_GAIN], USB_DIR_OUT); } @@ -741,7 +739,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; - usbhid_submit_report(pidff->hid, pidff->reports[PID_SET_EFFECT], + hid_submit_report(pidff->hid, pidff->reports[PID_SET_EFFECT], USB_DIR_OUT); } @@ -1165,19 +1163,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 */ - 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); + 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); pidff->device_control->value[0] = pidff->control_id[PID_ENABLE_ACTUATORS]; - usbhid_submit_report(hid, pidff->reports[PID_DEVICE_CONTROL], USB_DIR_OUT); - usbhid_wait_io(hid); + hid_submit_report(hid, pidff->reports[PID_DEVICE_CONTROL], USB_DIR_OUT); + hid_wait_io(hid); /* pool report is sometimes messed up, refetch it */ - usbhid_submit_report(hid, pidff->reports[PID_POOL], USB_DIR_IN); - usbhid_wait_io(hid); + hid_submit_report(hid, pidff->reports[PID_POOL], USB_DIR_IN); + hid_wait_io(hid); if (pidff->pool[PID_SIMULTANEOUS_MAX].value) { int sim_effects = pidff->pool[PID_SIMULTANEOUS_MAX].value[0]; @@ -1189,9 +1187,9 @@ static void pidff_reset(struct pidff_device *pidff) break; } debug("pid_pool requested again"); - usbhid_submit_report(hid, pidff->reports[PID_POOL], + hid_submit_report(hid, pidff->reports[PID_POOL], USB_DIR_IN); - usbhid_wait_io(hid); + hid_wait_io(hid); } } } @@ -1277,7 +1275,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); - usbhid_submit_report(pidff->hid, pidff->reports[PID_DEVICE_GAIN], + hid_submit_report(pidff->hid, pidff->reports[PID_DEVICE_GAIN], USB_DIR_OUT); } diff --git a/trunk/drivers/usb/input/hid-tmff.c b/trunk/drivers/usb/input/hid-tmff.c index ab67331620d0..2d5be4c318ac 100644 --- a/trunk/drivers/usb/input/hid-tmff.c +++ b/trunk/drivers/usb/input/hid-tmff.c @@ -32,8 +32,7 @@ #undef DEBUG #include -#include -#include "usbhid.h" +#include "hid.h" /* Usages for thrustmaster devices I know about */ #define THRUSTMASTER_USAGE_RUMBLE_LR (HID_UP_GENDESK | 0xbb) @@ -71,7 +70,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); - usbhid_submit_report(hid, tmff->report, USB_DIR_OUT); + hid_submit_report(hid, tmff->report, USB_DIR_OUT); return 0; } diff --git a/trunk/drivers/usb/input/hid-zpff.c b/trunk/drivers/usb/input/hid-zpff.c index 7bd8238ca212..d2ce3214572c 100644 --- a/trunk/drivers/usb/input/hid-zpff.c +++ b/trunk/drivers/usb/input/hid-zpff.c @@ -27,8 +27,7 @@ #include #include -#include -#include "usbhid.h" +#include "hid.h" struct zpff_device { struct hid_report *report; @@ -57,7 +56,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); - usbhid_submit_report(hid, zpff->report, USB_DIR_OUT); + hid_submit_report(hid, zpff->report, USB_DIR_OUT); return 0; } @@ -102,7 +101,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; - usbhid_submit_report(hid, zpff->report, USB_DIR_OUT); + hid_submit_report(hid, zpff->report, USB_DIR_OUT); printk(KERN_INFO "Force feedback for Zeroplus based devices by " "Anssi Hannula \n"); diff --git a/trunk/include/linux/hid.h b/trunk/drivers/usb/input/hid.h similarity index 86% rename from trunk/include/linux/hid.h rename to trunk/drivers/usb/input/hid.h index 770120add15a..2a9bf07944c0 100644 --- a/trunk/include/linux/hid.h +++ b/trunk/drivers/usb/input/hid.h @@ -6,7 +6,6 @@ * * Copyright (c) 1999 Andreas Gal * Copyright (c) 2000-2001 Vojtech Pavlik - * Copyright (c) 2006 Jiri Kosina */ /* @@ -34,7 +33,6 @@ #include #include #include -#include /* * USB HID (Human Interface Device) interface class code @@ -262,8 +260,7 @@ struct hid_item { #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 +#define HID_QUIRK_POWERBOOK_ISO_KEYBOARD 0x00008000 /* * This is the global environment of the parser. This information is @@ -403,14 +400,42 @@ struct hid_device { /* device report descriptor */ unsigned collection_size; /* Number of allocated hid_collections */ unsigned maxcollection; /* Number of parsed collections */ unsigned maxapplication; /* Number of applications */ - unsigned short bus; /* BUS ID */ - unsigned short vendor; /* Vendor ID */ - unsigned short product; /* Product ID */ unsigned version; /* HID version */ unsigned country; /* HID country */ struct hid_report_enum report_enum[HID_REPORT_TYPES]; - struct device *dev; /* device */ + 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 */ @@ -426,19 +451,7 @@ struct hid_device { /* device report descriptor */ char phys[64]; /* Device physical location */ char uniq[64]; /* Device unique identifier (serial #) */ - void *driver_data; - - /* device-specific function pointers */ - int (*hidinput_input_event) (struct input_dev *, unsigned int, unsigned int, int); - int (*hidinput_open) (struct input_dev *); - void (*hidinput_close) (struct input_dev *); - - /* hiddev event handler */ - void (*hiddev_hid_event) (struct hid_device *, struct hid_field *field, - struct hid_usage *, __s32); - void (*hiddev_report_event) (struct hid_device *, struct hid_report *); #ifdef CONFIG_USB_HIDINPUT_POWERBOOK - unsigned int pb_fnmode; unsigned long pb_pressed_fn[NBITS(KEY_MAX)]; unsigned long pb_pressed_numlock[NBITS(KEY_MAX)]; #endif @@ -482,23 +495,31 @@ struct hid_descriptor { #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)) - -/* HID core API */ 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); -int hid_input_report(struct hid_device *, int type, u8 *, int, int); -int hidinput_find_field(struct hid_device *hid, unsigned int type, unsigned int code, struct hid_field **field); -void hid_input_field(struct hid_device *hid, struct hid_field *field, __u8 *data, int interrupt); -void hid_output_report(struct hid_report *report, __u8 *data); -void hid_free_device(struct hid_device *device); -struct hid_device *hid_parse_report(__u8 *start, unsigned size); +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); @@ -515,14 +536,4 @@ static inline int hid_pidff_init(struct hid_device *hid) { return -ENODEV; } #else static inline int hid_ff_init(struct hid_device *hid) { return -1; } #endif -#ifdef DEBUG -#define dbg(format, arg...) printk(KERN_DEBUG "%s: " format "\n" , \ - __FILE__ , ## arg) -#else -#define dbg(format, arg...) do {} while (0) -#endif - -#define err(format, arg...) printk(KERN_ERR "%s: " format "\n" , \ - __FILE__ , ## arg) -#endif diff --git a/trunk/drivers/usb/input/hiddev.c b/trunk/drivers/usb/input/hiddev.c index 114d6c9f64b1..7dc14d0cacc1 100644 --- a/trunk/drivers/usb/input/hiddev.c +++ b/trunk/drivers/usb/input/hiddev.c @@ -32,9 +32,8 @@ #include #include #include -#include +#include "hid.h" #include -#include "usbhid.h" #ifdef CONFIG_USB_DYNAMIC_MINORS #define HIDDEV_MINOR_BASE 0 @@ -197,7 +196,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) { @@ -214,7 +213,6 @@ void hiddev_report_event(struct hid_device *hid, struct hid_report *report) hiddev_send_event(hid, &uref); } - /* * fasync file op */ @@ -241,7 +239,7 @@ static int hiddev_release(struct inode * inode, struct file * file) if (!--list->hiddev->open) { if (list->hiddev->exist) - usbhid_close(list->hiddev->hid); + hid_close(list->hiddev->hid); else kfree(list->hiddev); } @@ -272,7 +270,7 @@ static int hiddev_open(struct inode *inode, struct file *file) if (!list->hiddev->open++) if (list->hiddev->exist) - usbhid_open(hiddev_table[i]->hid); + hid_open(hiddev_table[i]->hid); return 0; } @@ -384,7 +382,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 = to_usb_device(hid->dev); + struct usb_device *dev = hid->dev; struct hiddev_collection_info cinfo; struct hiddev_report_info rinfo; struct hiddev_field_info finfo; @@ -393,7 +391,6 @@ 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; @@ -423,7 +420,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 = usbhid->ifnum; + dinfo.ifnum = hid->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); @@ -482,7 +479,7 @@ static int hiddev_ioctl(struct inode *inode, struct file *file, unsigned int cmd } case HIDIOCINITREPORT: - usbhid_init_reports(hid); + hid_init_reports(hid); return 0; @@ -496,8 +493,8 @@ static int hiddev_ioctl(struct inode *inode, struct file *file, unsigned int cmd if ((report = hiddev_lookup_report(hid, &rinfo)) == NULL) return -EINVAL; - usbhid_submit_report(hid, report, USB_DIR_IN); - usbhid_wait_io(hid); + hid_submit_report(hid, report, USB_DIR_IN); + hid_wait_io(hid); return 0; @@ -511,8 +508,8 @@ static int hiddev_ioctl(struct inode *inode, struct file *file, unsigned int cmd if ((report = hiddev_lookup_report(hid, &rinfo)) == NULL) return -EINVAL; - usbhid_submit_report(hid, report, USB_DIR_OUT); - usbhid_wait_io(hid); + hid_submit_report(hid, report, USB_DIR_OUT); + hid_wait_io(hid); return 0; @@ -748,7 +745,6 @@ 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; @@ -764,7 +760,7 @@ int hiddev_connect(struct hid_device *hid) if (!(hiddev = kzalloc(sizeof(struct hiddev), GFP_KERNEL))) return -1; - retval = usb_register_dev(usbhid->intf, &hiddev_class); + retval = usb_register_dev(hid->intf, &hiddev_class); if (retval) { err("Not able to get a minor for this device."); kfree(hiddev); @@ -776,10 +772,10 @@ int hiddev_connect(struct hid_device *hid) hiddev->hid = hid; hiddev->exist = 1; - hid->minor = usbhid->intf->minor; + hid->minor = hid->intf->minor; hid->hiddev = hiddev; - hiddev_table[usbhid->intf->minor - HIDDEV_MINOR_BASE] = hiddev; + hiddev_table[hid->intf->minor - HIDDEV_MINOR_BASE] = hiddev; return 0; } @@ -792,15 +788,14 @@ 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(usbhid->intf, &hiddev_class); + usb_deregister_dev(hiddev->hid->intf, &hiddev_class); if (hiddev->open) { - usbhid_close(hiddev->hid); + hid_close(hiddev->hid); wake_up_interruptible(&hiddev->wait); } else { kfree(hiddev); diff --git a/trunk/drivers/usb/input/usbhid.h b/trunk/drivers/usb/input/usbhid.h deleted file mode 100644 index 830107e5251f..000000000000 --- a/trunk/drivers/usb/input/usbhid.h +++ /dev/null @@ -1,84 +0,0 @@ -#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 -#include -#include -#include -#include -#include - -/* 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/trunk/drivers/usb/misc/sisusbvga/sisusb.c b/trunk/drivers/usb/misc/sisusbvga/sisusb.c index 0398908b15d4..b99ca9c79821 100644 --- a/trunk/drivers/usb/misc/sisusbvga/sisusb.c +++ b/trunk/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_path.dentry->d_inode, f, cmd, arg); + retval = sisusb_ioctl(f->f_dentry->d_inode, f, cmd, arg); unlock_kernel(); return retval; diff --git a/trunk/drivers/usb/serial/ark3116.c b/trunk/drivers/usb/serial/ark3116.c index 5261cd22ee6b..863966c1c5ac 100644 --- a/trunk/drivers/usb/serial/ark3116.c +++ b/trunk/drivers/usb/serial/ark3116.c @@ -156,7 +156,7 @@ static int ark3116_attach(struct usb_serial *serial) } static void ark3116_set_termios(struct usb_serial_port *port, - struct ktermios *old_termios) + struct termios *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 ktermios tmp_termios; + struct termios tmp_termios; struct usb_serial *serial = port->serial; char *buf; int result = 0; diff --git a/trunk/drivers/usb/serial/belkin_sa.c b/trunk/drivers/usb/serial/belkin_sa.c index 38b4dae319ee..8835bb58ca9b 100644 --- a/trunk/drivers/usb/serial/belkin_sa.c +++ b/trunk/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 ktermios * old); +static void belkin_sa_set_termios (struct usb_serial_port *port, struct termios * 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 @@ static void belkin_sa_read_int_callback (struct urb *urb) __FUNCTION__, retval); } -static void belkin_sa_set_termios (struct usb_serial_port *port, struct ktermios *old_termios) +static void belkin_sa_set_termios (struct usb_serial_port *port, struct termios *old_termios) { struct usb_serial *serial = port->serial; struct belkin_sa_private *priv = usb_get_serial_port_data(port); diff --git a/trunk/drivers/usb/serial/console.c b/trunk/drivers/usb/serial/console.c index 9386e216d681..7167728d764c 100644 --- a/trunk/drivers/usb/serial/console.c +++ b/trunk/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 ktermios *termios; + struct termios *termios; dbg ("%s", __FUNCTION__); diff --git a/trunk/drivers/usb/serial/cp2101.c b/trunk/drivers/usb/serial/cp2101.c index 2f9b7ac32663..f95d42c0d16a 100644 --- a/trunk/drivers/usb/serial/cp2101.c +++ b/trunk/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 ktermios*); +static void cp2101_set_termios(struct usb_serial_port*, struct termios*); 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 ktermios *old_termios) + struct termios *old_termios) { unsigned int cflag, old_cflag=0; int baud=0, bits; diff --git a/trunk/drivers/usb/serial/cypress_m8.c b/trunk/drivers/usb/serial/cypress_m8.c index a1fdb85b8c0a..093f303b3189 100644 --- a/trunk/drivers/usb/serial/cypress_m8.c +++ b/trunk/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 ktermios tmp_termios; /* stores the old termios settings */ + struct termios 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 ktermios * old); +static void cypress_set_termios (struct usb_serial_port *port, struct termios * 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 ktermios))) { + if (copy_to_user((void __user *)arg, port->tty->termios, sizeof(struct termios))) { return -EFAULT; } return (0); break; case TIOCSSERIAL: - if (copy_from_user(port->tty->termios, (void __user *)arg, sizeof(struct ktermios))) { + if (copy_from_user(port->tty->termios, (void __user *)arg, sizeof(struct termios))) { 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 ktermios *old_termios) + struct termios *old_termios) { struct cypress_private *priv = usb_get_serial_port_data(port); struct tty_struct *tty; diff --git a/trunk/drivers/usb/serial/digi_acceleport.c b/trunk/drivers/usb/serial/digi_acceleport.c index 9d9ea874639c..83d0e21145b0 100644 --- a/trunk/drivers/usb/serial/digi_acceleport.c +++ b/trunk/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 ktermios *old_termios ); + struct termios *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 ktermios *old_termios ) + struct termios *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 ktermios not_termios; + struct termios not_termios; unsigned long flags = 0; diff --git a/trunk/drivers/usb/serial/empeg.c b/trunk/drivers/usb/serial/empeg.c index 92beeb19795f..4ce10a831953 100644 --- a/trunk/drivers/usb/serial/empeg.c +++ b/trunk/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 ktermios *old_termios); +static void empeg_set_termios (struct usb_serial_port *port, struct termios *old_termios); static void empeg_write_bulk_callback (struct urb *urb); static void empeg_read_bulk_callback (struct urb *urb); @@ -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 ktermios *old_termios) +static void empeg_set_termios (struct usb_serial_port *port, struct termios *old_termios) { dbg("%s - port %d", __FUNCTION__, port->number); diff --git a/trunk/drivers/usb/serial/ftdi_sio.c b/trunk/drivers/usb/serial/ftdi_sio.c index 41b0ad2d56ac..72e4d48f51e9 100644 --- a/trunk/drivers/usb/serial/ftdi_sio.c +++ b/trunk/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 ktermios * old); +static void ftdi_set_termios (struct usb_serial_port *port, struct termios * 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 ktermios *old_termios) +static void ftdi_set_termios (struct usb_serial_port *port, struct termios *old_termios) { /* ftdi_termios */ struct usb_device *dev = port->serial->dev; unsigned int cflag = port->tty->termios->c_cflag; diff --git a/trunk/drivers/usb/serial/io_edgeport.c b/trunk/drivers/usb/serial/io_edgeport.c index f623d58370a4..d06547a13f28 100644 --- a/trunk/drivers/usb/serial/io_edgeport.c +++ b/trunk/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 ktermios *old_termios); +static void edge_set_termios (struct usb_serial_port *port, struct termios *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 ktermios *old_termios); +static void change_port_settings (struct edgeport_port *edge_port, struct termios *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 ktermios *old_termios) +static void edge_set_termios (struct usb_serial_port *port, struct termios *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 ktermios *old_termios) +static void change_port_settings (struct edgeport_port *edge_port, struct termios *old_termios) { struct tty_struct *tty; int baud; diff --git a/trunk/drivers/usb/serial/io_ti.c b/trunk/drivers/usb/serial/io_ti.c index 2da2684e0809..ee0c921e1520 100644 --- a/trunk/drivers/usb/serial/io_ti.c +++ b/trunk/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 ktermios *old_termios); +static void edge_set_termios (struct usb_serial_port *port, struct termios *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 ktermios *old_termios) +static void change_port_settings (struct edgeport_port *edge_port, struct termios *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 ktermi return; } -static void edge_set_termios (struct usb_serial_port *port, struct ktermios *old_termios) +static void edge_set_termios (struct usb_serial_port *port, struct termios *old_termios) { struct edgeport_port *edge_port = usb_get_serial_port_data(port); struct tty_struct *tty = port->tty; diff --git a/trunk/drivers/usb/serial/ir-usb.c b/trunk/drivers/usb/serial/ir-usb.c index 8fdf486e3465..331bf81556fc 100644 --- a/trunk/drivers/usb/serial/ir-usb.c +++ b/trunk/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 ktermios *old_termios); +static void ir_set_termios (struct usb_serial_port *port, struct termios *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 ktermios *old_termios) +static void ir_set_termios (struct usb_serial_port *port, struct termios *old_termios) { unsigned char *transfer_buffer; unsigned int cflag; diff --git a/trunk/drivers/usb/serial/keyspan.c b/trunk/drivers/usb/serial/keyspan.c index 9d2fdfd6865f..7639652cec42 100644 --- a/trunk/drivers/usb/serial/keyspan.c +++ b/trunk/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 ktermios *old_termios) + struct termios *old_termios) { int baud_rate, device_port; struct keyspan_port_private *p_priv; diff --git a/trunk/drivers/usb/serial/keyspan.h b/trunk/drivers/usb/serial/keyspan.h index 6413d73c139c..7472ed6bf626 100644 --- a/trunk/drivers/usb/serial/keyspan.h +++ b/trunk/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 ktermios *old); + struct termios *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/trunk/drivers/usb/serial/keyspan_pda.c b/trunk/drivers/usb/serial/keyspan_pda.c index 126b9703bbaf..e09a0bfe6231 100644 --- a/trunk/drivers/usb/serial/keyspan_pda.c +++ b/trunk/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 ktermios *old_termios) + struct termios *old_termios) { struct usb_serial *serial = port->serial; unsigned int cflag = port->tty->termios->c_cflag; diff --git a/trunk/drivers/usb/serial/kl5kusb105.c b/trunk/drivers/usb/serial/kl5kusb105.c index 73d755df4840..17e205699c2b 100644 --- a/trunk/drivers/usb/serial/kl5kusb105.c +++ b/trunk/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 ktermios *old); + struct termios * 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 ktermios termios; + struct termios 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 ktermios *old_termios) + struct termios *old_termios) { struct klsi_105_private *priv = usb_get_serial_port_data(port); unsigned int iflag = port->tty->termios->c_iflag; diff --git a/trunk/drivers/usb/serial/kobil_sct.c b/trunk/drivers/usb/serial/kobil_sct.c index e284d6c0fd35..237289920f03 100644 --- a/trunk/drivers/usb/serial/kobil_sct.c +++ b/trunk/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 ktermios internal_termios; + struct termios 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 ktermios))) { + if (!access_ok(VERIFY_WRITE, user_arg, sizeof(struct termios))) { dbg("%s - port %d Error in access_ok", __FUNCTION__, port->number); return -EFAULT; } - if (kernel_termios_to_user_termios((struct ktermios __user *)arg, + if (kernel_termios_to_user_termios((struct termios __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 ktermios))) { + if (!access_ok(VERIFY_READ, user_arg, sizeof(struct termios))) { dbg("%s - port %d Error in access_ok", __FUNCTION__, port->number); return -EFAULT; } if (user_termios_to_kernel_termios(&priv->internal_termios, - (struct ktermios __user *)arg)) + (struct termios __user *)arg)) return -EFAULT; settings = kzalloc(50, GFP_KERNEL); diff --git a/trunk/drivers/usb/serial/mct_u232.c b/trunk/drivers/usb/serial/mct_u232.c index 38b1d17e06ef..a906e500a02b 100644 --- a/trunk/drivers/usb/serial/mct_u232.c +++ b/trunk/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 ktermios * old); + struct termios * old); static int mct_u232_ioctl (struct usb_serial_port *port, struct file * file, unsigned int cmd, @@ -556,7 +556,7 @@ static void mct_u232_read_int_callback (struct urb *urb) } /* mct_u232_read_int_callback */ static void mct_u232_set_termios (struct usb_serial_port *port, - struct ktermios *old_termios) + struct termios *old_termios) { struct usb_serial *serial = port->serial; struct mct_u232_private *priv = usb_get_serial_port_data(port); diff --git a/trunk/drivers/usb/serial/mos7720.c b/trunk/drivers/usb/serial/mos7720.c index e55f4ed81d7b..70f93b18292f 100644 --- a/trunk/drivers/usb/serial/mos7720.c +++ b/trunk/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 ktermios *old_termios) + struct termios *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 ktermios *old_termios) + struct termios *old_termios) { int status; unsigned int cflag; diff --git a/trunk/drivers/usb/serial/mos7840.c b/trunk/drivers/usb/serial/mos7840.c index 8cc728a49e41..5432c6340086 100644 --- a/trunk/drivers/usb/serial/mos7840.c +++ b/trunk/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 ktermios *old_termios) + struct termios *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 ktermios *old_termios) + struct termios *old_termios) { int status; unsigned int cflag; diff --git a/trunk/drivers/usb/serial/option.c b/trunk/drivers/usb/serial/option.c index 0ae4098718c3..130afbbd3fca 100644 --- a/trunk/drivers/usb/serial/option.c +++ b/trunk/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 ktermios *old); + struct termios *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 ktermios *old_termios) + struct termios *old_termios) { dbg("%s", __FUNCTION__); diff --git a/trunk/drivers/usb/serial/pl2303.c b/trunk/drivers/usb/serial/pl2303.c index d124d780e42e..bc800c8787a8 100644 --- a/trunk/drivers/usb/serial/pl2303.c +++ b/trunk/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 ktermios *old_termios) + struct termios *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 ktermios tmp_termios; + struct termios tmp_termios; struct usb_serial *serial = port->serial; struct pl2303_private *priv = usb_get_serial_port_data(port); unsigned char *buf; diff --git a/trunk/drivers/usb/serial/sierra.c b/trunk/drivers/usb/serial/sierra.c index 6d8e91e00ecf..4b5097fa48d7 100644 --- a/trunk/drivers/usb/serial/sierra.c +++ b/trunk/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 ktermios *old_termios) + struct termios *old_termios) { dbg("%s", __FUNCTION__); diff --git a/trunk/drivers/usb/serial/ti_usb_3410_5052.c b/trunk/drivers/usb/serial/ti_usb_3410_5052.c index f42eb9ea6405..ae98d8cbdbb8 100644 --- a/trunk/drivers/usb/serial/ti_usb_3410_5052.c +++ b/trunk/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 ktermios *old_termios); + struct termios *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 ktermios *old_termios) + struct termios *old_termios) { struct ti_port *tport = usb_get_serial_port_data(port); struct tty_struct *tty = port->tty; diff --git a/trunk/drivers/usb/serial/usb-serial.c b/trunk/drivers/usb/serial/usb-serial.c index 716f6806cc89..3d5072f14b8d 100644 --- a/trunk/drivers/usb/serial/usb-serial.c +++ b/trunk/drivers/usb/serial/usb-serial.c @@ -397,7 +397,7 @@ static int serial_ioctl (struct tty_struct *tty, struct file * file, unsigned in return retval; } -static void serial_set_termios (struct tty_struct *tty, struct ktermios * old) +static void serial_set_termios (struct tty_struct *tty, struct termios * old) { struct usb_serial_port *port = tty->driver_data; diff --git a/trunk/drivers/usb/serial/visor.c b/trunk/drivers/usb/serial/visor.c index b09f06096056..eef5eaa5fa0b 100644 --- a/trunk/drivers/usb/serial/visor.c +++ b/trunk/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 ktermios *old_termios); +static void visor_set_termios (struct usb_serial_port *port, struct termios *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 ktermios *old_termios) +static void visor_set_termios (struct usb_serial_port *port, struct termios *old_termios) { unsigned int cflag; diff --git a/trunk/drivers/usb/serial/whiteheat.c b/trunk/drivers/usb/serial/whiteheat.c index dc45e58e2b8c..154c7d290597 100644 --- a/trunk/drivers/usb/serial/whiteheat.c +++ b/trunk/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 ktermios * old); +static void whiteheat_set_termios (struct usb_serial_port *port, struct termios * 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 ktermios old_term; + struct termios 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 ktermios *old_termios) +static void whiteheat_set_termios (struct usb_serial_port *port, struct termios *old_termios) { dbg("%s -port %d", __FUNCTION__, port->number); diff --git a/trunk/drivers/video/Kconfig b/trunk/drivers/video/Kconfig index ab1daecfeac6..7a43020fa583 100644 --- a/trunk/drivers/video/Kconfig +++ b/trunk/drivers/video/Kconfig @@ -541,7 +541,6 @@ 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. @@ -552,7 +551,6 @@ 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. @@ -707,7 +705,6 @@ 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 @@ -747,7 +744,6 @@ 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/trunk/drivers/video/S3triofb.c b/trunk/drivers/video/S3triofb.c index b3717c8f1bc2..397005eb392d 100644 --- a/trunk/drivers/video/S3triofb.c +++ b/trunk/drivers/video/S3triofb.c @@ -535,11 +535,8 @@ static void __init s3triofb_of_init(struct device_node *dp) #endif fb_info.flags = FBINFO_FLAG_DEFAULT; - if (register_framebuffer(&fb_info) < 0) { - iounmap(fb_info.screen_base); - fb_info.screen_base = NULL; - return; - } + if (register_framebuffer(&fb_info) < 0) + return; printk("fb%d: S3 Trio frame buffer device on %s\n", fb_info.node, dp->full_name); diff --git a/trunk/drivers/video/amifb.c b/trunk/drivers/video/amifb.c index 88a47845c4f7..a4e3fca05891 100644 --- a/trunk/drivers/video/amifb.c +++ b/trunk/drivers/video/amifb.c @@ -2407,10 +2407,10 @@ int __init amifb_init(void) fb_info.fix.smem_len); if (!videomemory) { printk("amifb: WARNING! unable to map videomem cached writethrough\n"); - fb_info.screen_base = (char *)ZTWO_VADDR(fb_info.fix.smem_start); - } else - fb_info.screen_base = (char *)videomemory; + videomemory = ZTWO_VADDR(fb_info.fix.smem_start); + } + fb_info.screen_base = (char *)videomemory; memset(dummysprite, 0, DUMMYSPRITEMEMSIZE); /* @@ -2453,8 +2453,6 @@ 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/trunk/drivers/video/arcfb.c b/trunk/drivers/video/arcfb.c index 30a8369757e7..ab34b96acc31 100644 --- a/trunk/drivers/video/arcfb.c +++ b/trunk/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_path.dentry->d_inode; + inode = file->f_dentry->d_inode; fbidx = iminor(inode); info = registered_fb[fbidx]; diff --git a/trunk/drivers/video/atafb.c b/trunk/drivers/video/atafb.c index 602db660bc73..02c41a626fa2 100644 --- a/trunk/drivers/video/atafb.c +++ b/trunk/drivers/video/atafb.c @@ -2804,19 +2804,8 @@ int __init atafb_init(void) atafb_set_disp(-1, &fb_info); do_install_cmap(0, &fb_info); - 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 + if (register_framebuffer(&fb_info) < 0) return -EINVAL; - } printk("Determined %dx%d, depth %d\n", disp.var.xres, disp.var.yres, disp.var.bits_per_pixel); diff --git a/trunk/drivers/video/aty/aty128fb.c b/trunk/drivers/video/aty/aty128fb.c index 3feddf89d100..276a21530b95 100644 --- a/trunk/drivers/video/aty/aty128fb.c +++ b/trunk/drivers/video/aty/aty128fb.c @@ -1333,8 +1333,6 @@ 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; @@ -1344,9 +1342,6 @@ 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/trunk/drivers/video/aty/atyfb.h b/trunk/drivers/video/aty/atyfb.h index f72faff33c0c..b04f49fb976a 100644 --- a/trunk/drivers/video/aty/atyfb.h +++ b/trunk/drivers/video/aty/atyfb.h @@ -126,6 +126,7 @@ 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; @@ -185,7 +186,6 @@ 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(par->ati_regbase + regindex); + return in_le32((volatile u32 *)(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(par->ati_regbase + regindex, val); + out_le32((volatile u32 *)(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(par->ati_regbase + regindex, val); + out_le16((volatile u16 *)(par->ati_regbase + regindex), val); #else writel(val, par->ati_regbase + regindex); #endif @@ -315,7 +315,6 @@ 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/trunk/drivers/video/aty/atyfb_base.c b/trunk/drivers/video/aty/atyfb_base.c index 176f9b85cdbe..e815b354c09d 100644 --- a/trunk/drivers/video/aty/atyfb_base.c +++ b/trunk/drivers/video/aty/atyfb_base.c @@ -203,6 +203,14 @@ 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; @@ -241,8 +249,7 @@ static int atyfb_sync(struct fb_info *info); * Internal routines */ -static int aty_init(struct fb_info *info); -static void aty_resume_chip(struct fb_info *info); +static int aty_init(struct fb_info *info, const char *name); #ifdef CONFIG_ATARI static int store_video_par(char *videopar, unsigned char m64_num); #endif @@ -1930,14 +1937,17 @@ 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); - 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); + 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); } } @@ -1972,7 +1982,6 @@ 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) @@ -2029,13 +2038,21 @@ 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; @@ -2053,7 +2070,6 @@ 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; @@ -2063,9 +2079,6 @@ 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(); @@ -2084,15 +2097,8 @@ 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 */ @@ -2338,16 +2344,24 @@ 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) +static int __devinit aty_init(struct fb_info *info, const char *name) { 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. */ @@ -2450,21 +2464,18 @@ static int __devinit aty_init(struct fb_info *info) par->pll_limits.mclk = 63; } - 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"; - } + 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"; } } #endif /* CONFIG_FB_ATY_CT */ @@ -2474,10 +2485,10 @@ static int __devinit aty_init(struct fb_info *info) if(par->pll_ops->get_pll) par->pll_ops->get_pll(info, &saved_pll); - par->mem_cntl = aty_ld_le32(MEM_CNTL, par); + i = aty_ld_le32(MEM_CNTL, par); gtb_memsize = M64_HAS(GTB_DSP); if (gtb_memsize) - switch (par->mem_cntl & 0xF) { /* 0xF used instead of MEM_SIZE_ALIAS */ + switch (i & 0xF) { /* 0xF used instead of MEM_SIZE_ALIAS */ case MEM_SIZE_512K: info->fix.smem_len = 0x80000; break; @@ -2499,7 +2510,7 @@ static int __devinit aty_init(struct fb_info *info) default: info->fix.smem_len = 0x80000; } else - switch (par->mem_cntl & MEM_SIZE_ALIAS) { + switch (i & MEM_SIZE_ALIAS) { case MEM_SIZE_512K: info->fix.smem_len = 0x80000; break; @@ -2529,20 +2540,20 @@ static int __devinit aty_init(struct fb_info *info) if (vram) { info->fix.smem_len = vram * 1024; - par->mem_cntl &= ~(gtb_memsize ? 0xF : MEM_SIZE_ALIAS); + i = i & ~(gtb_memsize ? 0xF : MEM_SIZE_ALIAS); if (info->fix.smem_len <= 0x80000) - par->mem_cntl |= MEM_SIZE_512K; + i |= MEM_SIZE_512K; else if (info->fix.smem_len <= 0x100000) - par->mem_cntl |= MEM_SIZE_1M; + i |= MEM_SIZE_1M; else if (info->fix.smem_len <= 0x200000) - par->mem_cntl |= gtb_memsize ? MEM_SIZE_2M_GTB : MEM_SIZE_2M; + i |= gtb_memsize ? MEM_SIZE_2M_GTB : MEM_SIZE_2M; else if (info->fix.smem_len <= 0x400000) - par->mem_cntl |= gtb_memsize ? MEM_SIZE_4M_GTB : MEM_SIZE_4M; + i |= gtb_memsize ? MEM_SIZE_4M_GTB : MEM_SIZE_4M; else if (info->fix.smem_len <= 0x600000) - par->mem_cntl |= gtb_memsize ? MEM_SIZE_6M_GTB : MEM_SIZE_6M; + i |= gtb_memsize ? MEM_SIZE_6M_GTB : MEM_SIZE_6M; else - par->mem_cntl |= gtb_memsize ? MEM_SIZE_8M_GTB : MEM_SIZE_8M; - aty_st_le32(MEM_CNTL, par->mem_cntl, par); + i |= gtb_memsize ? MEM_SIZE_8M_GTB : MEM_SIZE_8M; + aty_st_le32(MEM_CNTL, i, par); } /* @@ -2588,12 +2599,11 @@ static int __devinit aty_init(struct fb_info *info) #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, - * unless the auxiliary register aperture is used. + * 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 */ if (!par->aux_start && @@ -2659,7 +2669,6 @@ static int __devinit aty_init(struct fb_info *info) 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; @@ -2740,7 +2749,7 @@ static int __devinit aty_init(struct fb_info *info) fb_list = info; PRINTKI("fb%d: %s frame buffer device on %s\n", - info->node, info->fix.id, par->bus_type == ISA ? "ISA" : "PCI"); + info->node, info->fix.id, name); return 0; aty_init_exit: @@ -2761,19 +2770,6 @@ static int __devinit aty_init(struct fb_info *info) 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) { @@ -2830,9 +2826,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: + case FB_BLANK_UNBLANK: + gen_cntl &= ~0x400004c; break; case FB_BLANK_NORMAL: gen_cntl |= 0x4000040; @@ -2867,10 +2863,17 @@ 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) { - 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); +#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 } /* @@ -3179,7 +3182,7 @@ static int __devinit atyfb_setup_sparc(struct pci_dev *pdev, #ifdef __i386__ #ifdef CONFIG_FB_ATY_GENERIC_LCD -static void __devinit aty_init_lcd(struct atyfb_par *par, u32 bios_base) +static void aty_init_lcd(struct atyfb_par *par, u32 bios_base) { u32 driv_inf_tab, sig; u16 lcd_ofs; @@ -3524,10 +3527,6 @@ 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; } @@ -3595,7 +3594,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)) + if (aty_init(info, "PCI")) goto err_release_io; #ifdef __sparc__ @@ -3642,13 +3641,12 @@ static int __devinit atyfb_pci_probe(struct pci_dev *pdev, const struct pci_devi #ifdef CONFIG_ATARI -static int __init atyfb_atari_probe(void) +static int __devinit 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] || @@ -3696,34 +3694,16 @@ static int __init atyfb_atari_probe(void) break; } - /* 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); + if (aty_init(info, "ISA bus")) { framebuffer_release(info); - } else { - num_found++; + /* This is insufficient! kernel_map has added two large chunks!! */ + return -ENXIO; } } - - 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; @@ -3771,6 +3751,7 @@ 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) { @@ -3805,7 +3786,7 @@ static struct pci_driver atyfb_driver = { #endif /* CONFIG_PCI */ #ifndef MODULE -static int __init atyfb_setup(char *options) +static int __devinit atyfb_setup(char *options) { char *this_opt; @@ -3877,7 +3858,7 @@ static int __init atyfb_setup(char *options) } #endif /* MODULE */ -static int __init atyfb_init(void) +static int __devinit atyfb_init(void) { int err1 = 1, err2 = 1; #ifndef MODULE diff --git a/trunk/drivers/video/aty/mach64_ct.c b/trunk/drivers/video/aty/mach64_ct.c index f3b487b8710b..5080816be653 100644 --- a/trunk/drivers/video/aty/mach64_ct.c +++ b/trunk/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 __devinit aty_get_pll_ct(const struct fb_info *info, - union aty_pll *pll) +static void __init 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 __devinit aty_get_pll_ct(const struct fb_info *info, } } -static int __devinit aty_init_pll_ct(const struct fb_info *info, - union aty_pll *pll) +static int __init 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; - u32 q, memcntl, trp; + u8 mpost_div, xpost_div, sclk_post_div_real, sclk_fb_div, spll_cntl2; + u32 q, i, memcntl, trp; u32 dsp_config, dsp_on_off, vga_dsp_config, vga_dsp_on_off; #ifdef DEBUG int pllmclk, pllsclk; @@ -575,30 +575,14 @@ static int __devinit aty_init_pll_ct(const struct fb_info *info, mpost_div += (q < 32*8); } sclk_post_div_real = postdividers[mpost_div]; - pll->ct.sclk_fb_div = q * sclk_post_div_real / 8; - pll->ct.spll_cntl2 = mpost_div << 4; + sclk_fb_div = q * sclk_post_div_real / 8; + spll_cntl2 = mpost_div << 4; #ifdef DEBUG - pllsclk = (1000000 * 2 * pll->ct.sclk_fb_div) / + pllsclk = (1000000 * 2 * 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); @@ -606,8 +590,8 @@ static void aty_resume_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, pll->ct.sclk_fb_div, par); - aty_st_pll_ct(SPLL_CNTL2, pll->ct.spll_cntl2, par); + aty_st_pll_ct(SCLK_FB_DIV, sclk_fb_div, par); + aty_st_pll_ct(SPLL_CNTL2, 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 @@ -621,7 +605,11 @@ static void aty_resume_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); - aty_st_pll_ct(EXT_VPLL_CNTL, pll->ct.ext_vpll_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; } static int dummy(void) @@ -638,6 +626,5 @@ 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, - .resume_pll = aty_resume_pll_ct, + .init_pll = aty_init_pll_ct }; diff --git a/trunk/drivers/video/aty/radeon_monitor.c b/trunk/drivers/video/aty/radeon_monitor.c index 38c7dbf8c151..ea531a6f45d1 100644 --- a/trunk/drivers/video/aty/radeon_monitor.c +++ b/trunk/drivers/video/aty/radeon_monitor.c @@ -104,9 +104,10 @@ static int __devinit radeon_parse_montype_prop(struct device_node *dp, u8 **out_ if (pedid == NULL) return mt; - tmp = kmemdup(pedid, EDID_LENGTH, GFP_KERNEL); + tmp = (u8 *)kmalloc(EDID_LENGTH, GFP_KERNEL); if (!tmp) return mt; + memcpy(tmp, pedid, EDID_LENGTH); *out_EDID = tmp; return mt; } diff --git a/trunk/drivers/video/au1100fb.h b/trunk/drivers/video/au1100fb.h index 164fe2f231ec..2855534dc235 100644 --- a/trunk/drivers/video/au1100fb.h +++ b/trunk/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_SBB_4, + LCD_CONTROL_BPP_16, .clkcontrol_base = 0x00020000, .horztiming = 0x005aff1f, .verttiming = 0x16000e57, diff --git a/trunk/drivers/video/backlight/backlight.c b/trunk/drivers/video/backlight/backlight.c index db8c191b1201..27597c576eff 100644 --- a/trunk/drivers/video/backlight/backlight.c +++ b/trunk/drivers/video/backlight/backlight.c @@ -14,59 +14,6 @@ #include #include - -#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; @@ -195,7 +142,7 @@ static struct class backlight_class = { .store = _store, \ } -static const struct class_device_attribute bl_class_device_attributes[] = { +static 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), @@ -204,6 +151,33 @@ static const 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. @@ -241,7 +215,10 @@ error: kfree(new_bd); return ERR_PTR(rc); } - rc = backlight_register_fb(new_bd); + 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); if (unlikely(rc)) goto error; @@ -282,10 +259,16 @@ 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); - backlight_unregister_fb(bd); + fb_unregister_client(&bd->fb_notif); class_device_unregister(&bd->class_dev); } diff --git a/trunk/drivers/video/backlight/corgi_bl.c b/trunk/drivers/video/backlight/corgi_bl.c index 61587ca2cdbb..d07ecb53c68b 100644 --- a/trunk/drivers/video/backlight/corgi_bl.c +++ b/trunk/drivers/video/backlight/corgi_bl.c @@ -135,10 +135,6 @@ 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/trunk/drivers/video/backlight/hp680_bl.c b/trunk/drivers/video/backlight/hp680_bl.c index 1c569fb543ae..e3993213d10e 100644 --- a/trunk/drivers/video/backlight/hp680_bl.c +++ b/trunk/drivers/video/backlight/hp680_bl.c @@ -117,10 +117,6 @@ 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/trunk/drivers/video/backlight/lcd.c b/trunk/drivers/video/backlight/lcd.c index f6e041627edb..bc8ab005a3fb 100644 --- a/trunk/drivers/video/backlight/lcd.c +++ b/trunk/drivers/video/backlight/lcd.c @@ -14,53 +14,6 @@ #include #include -#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; @@ -168,12 +121,35 @@ static struct class lcd_class = { .store = _store, \ } -static const struct class_device_attribute lcd_class_device_attributes[] = { +static 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 @@ -210,8 +186,10 @@ error: kfree(new_ld); return ERR_PTR(rc); } - rc = lcd_register_fb(new_ld); + memset(&new_ld->fb_notif, 0, sizeof(new_ld->fb_notif)); + new_ld->fb_notif.notifier_call = fb_notifier_callback; + rc = fb_register_client(&new_ld->fb_notif); if (unlikely(rc)) goto error; @@ -254,7 +232,9 @@ void lcd_device_unregister(struct lcd_device *ld) down(&ld->sem); ld->props = NULL; up(&ld->sem); - lcd_unregister_fb(ld); + + fb_unregister_client(&ld->fb_notif); + class_device_unregister(&ld->class_dev); } EXPORT_SYMBOL(lcd_device_unregister); diff --git a/trunk/drivers/video/backlight/locomolcd.c b/trunk/drivers/video/backlight/locomolcd.c index 2d7905410b2a..628571c63bac 100644 --- a/trunk/drivers/video/backlight/locomolcd.c +++ b/trunk/drivers/video/backlight/locomolcd.c @@ -200,10 +200,6 @@ 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/trunk/drivers/video/cfbimgblt.c b/trunk/drivers/video/cfbimgblt.c index 261004473c8e..51d35386a945 100644 --- a/trunk/drivers/video/cfbimgblt.c +++ b/trunk/drivers/video/cfbimgblt.c @@ -42,7 +42,7 @@ #define DPRINTK(fmt, args...) #endif -static const u32 cfb_tab8[] = { +static u32 cfb_tab8[] = { #if defined(__BIG_ENDIAN) 0x00000000,0x000000ff,0x0000ff00,0x0000ffff, 0x00ff0000,0x00ff00ff,0x00ffff00,0x00ffffff, @@ -58,7 +58,7 @@ static const u32 cfb_tab8[] = { #endif }; -static const u32 cfb_tab16[] = { +static u32 cfb_tab16[] = { #if defined(__BIG_ENDIAN) 0x00000000, 0x0000ffff, 0xffff0000, 0xffffffff #elif defined(__LITTLE_ENDIAN) @@ -68,7 +68,7 @@ static const u32 cfb_tab16[] = { #endif }; -static const u32 cfb_tab32[] = { +static 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; - const u32 *tab = NULL; + u32 *tab = NULL; int i, j, k; switch (bpp) { diff --git a/trunk/drivers/video/cirrusfb.c b/trunk/drivers/video/cirrusfb.c index 2c4bc6205738..daf43f535a0b 100644 --- a/trunk/drivers/video/cirrusfb.c +++ b/trunk/drivers/video/cirrusfb.c @@ -2442,10 +2442,7 @@ static int cirrusfb_pci_register (struct pci_dev *pdev, printk ("Cirrus Logic chipset on PCI bus\n"); pci_set_drvdata(pdev, info); - ret = cirrusfb_register(cinfo); - if (ret) - iounmap(cinfo->fbmem); - return ret; + return cirrusfb_register(cinfo); err_release_legacy: if (release_io_ports) @@ -2577,15 +2574,7 @@ static int cirrusfb_zorro_register(struct zorro_dev *z, printk (KERN_INFO "Cirrus Logic chipset on Zorro bus\n"); zorro_set_drvdata(z, info); - 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; + return cirrusfb_register(cinfo); err_unmap_regbase: /* Parental advisory: explicit hack */ diff --git a/trunk/drivers/video/console/softcursor.c b/trunk/drivers/video/console/softcursor.c index f577bd80e020..7d07d8383569 100644 --- a/trunk/drivers/video/console/softcursor.c +++ b/trunk/drivers/video/console/softcursor.c @@ -1,13 +1,11 @@ /* - * 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 @@ -27,7 +25,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 *src, *dst; + u8 *dst; if (info->state != FBINFO_STATE_RUNNING) return 0; @@ -47,8 +45,7 @@ int soft_cursor(struct fb_info *info, struct fb_cursor *cursor) } } - src = ops->cursor_src + sizeof(struct fb_image); - image = (struct fb_image *)ops->cursor_src; + image = (struct fb_image *) (ops->cursor_src + dsize); *image = cursor->image; d_pitch = (s_pitch + scan_align) & ~scan_align; @@ -60,18 +57,21 @@ int soft_cursor(struct fb_info *info, struct fb_cursor *cursor) switch (cursor->rop) { case ROP_XOR: for (i = 0; i < dsize; i++) - src[i] = image->data[i] ^ cursor->mask[i]; + ops->cursor_src[i] = image->data[i] ^ + cursor->mask[i]; break; case ROP_COPY: default: for (i = 0; i < dsize; i++) - src[i] = image->data[i] & cursor->mask[i]; + ops->cursor_src[i] = image->data[i] & + cursor->mask[i]; break; } } else - memcpy(src, image->data, dsize); + memcpy(ops->cursor_src, image->data, dsize); - fb_pad_aligned_buffer(dst, d_pitch, src, s_pitch, image->height); + fb_pad_aligned_buffer(dst, d_pitch, ops->cursor_src, s_pitch, + image->height); image->data = dst; info->fbops->fb_imageblit(info, image); return 0; diff --git a/trunk/drivers/video/console/sticon.c b/trunk/drivers/video/console/sticon.c index 57b21e533036..45586aaabd1e 100644 --- a/trunk/drivers/video/console/sticon.c +++ b/trunk/drivers/video/console/sticon.c @@ -345,7 +345,7 @@ static void sticon_save_screen(struct vc_data *conp) { } -static const struct consw sti_con = { +static struct consw sti_con = { .owner = THIS_MODULE, .con_startup = sticon_startup, .con_init = sticon_init, diff --git a/trunk/drivers/video/console/vgacon.c b/trunk/drivers/video/console/vgacon.c index 4a9bde2c839b..0a2c10a1abf8 100644 --- a/trunk/drivers/video/console/vgacon.c +++ b/trunk/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 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 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 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 __read_mostly; -static unsigned int vga_rolled_over; +static int vga_scan_lines; +static unsigned int vga_rolled_over = 0; +static int vga_init_done; static int __init no_scroll(char *str) { diff --git a/trunk/drivers/video/cyberfb.c b/trunk/drivers/video/cyberfb.c index 0b8d5b121152..c40e72dafb0e 100644 --- a/trunk/drivers/video/cyberfb.c +++ b/trunk/drivers/video/cyberfb.c @@ -109,6 +109,8 @@ 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; @@ -1053,8 +1055,6 @@ 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/trunk/drivers/video/epson1355fb.c b/trunk/drivers/video/epson1355fb.c index 29e07c109887..737257d278f0 100644 --- a/trunk/drivers/video/epson1355fb.c +++ b/trunk/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_path.dentry->d_inode; + struct inode *inode = file->f_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_path.dentry->d_inode; + struct inode *inode = file->f_dentry->d_inode; int fbidx = iminor(inode); struct fb_info *info = registered_fb[fbidx]; unsigned long p = *ppos; diff --git a/trunk/drivers/video/fbcmap.c b/trunk/drivers/video/fbcmap.c index 148108afdd51..e8b135f3d80d 100644 --- a/trunk/drivers/video/fbcmap.c +++ b/trunk/drivers/video/fbcmap.c @@ -18,64 +18,63 @@ #include -static u16 red2[] __read_mostly = { +static u16 red2[] = { 0x0000, 0xaaaa }; -static u16 green2[] __read_mostly = { +static u16 green2[] = { 0x0000, 0xaaaa }; -static u16 blue2[] __read_mostly = { +static u16 blue2[] = { 0x0000, 0xaaaa }; -static u16 red4[] __read_mostly = { +static u16 red4[] = { 0x0000, 0xaaaa, 0x5555, 0xffff }; -static u16 green4[] __read_mostly = { +static u16 green4[] = { 0x0000, 0xaaaa, 0x5555, 0xffff }; -static u16 blue4[] __read_mostly = { +static u16 blue4[] = { 0x0000, 0xaaaa, 0x5555, 0xffff }; -static u16 red8[] __read_mostly = { +static u16 red8[] = { 0x0000, 0x0000, 0x0000, 0x0000, 0xaaaa, 0xaaaa, 0xaaaa, 0xaaaa }; -static u16 green8[] __read_mostly = { +static u16 green8[] = { 0x0000, 0x0000, 0xaaaa, 0xaaaa, 0x0000, 0x0000, 0x5555, 0xaaaa }; -static u16 blue8[] __read_mostly = { +static u16 blue8[] = { 0x0000, 0xaaaa, 0x0000, 0xaaaa, 0x0000, 0xaaaa, 0x0000, 0xaaaa }; -static u16 red16[] __read_mostly = { +static u16 red16[] = { 0x0000, 0x0000, 0x0000, 0x0000, 0xaaaa, 0xaaaa, 0xaaaa, 0xaaaa, 0x5555, 0x5555, 0x5555, 0x5555, 0xffff, 0xffff, 0xffff, 0xffff }; -static u16 green16[] __read_mostly = { +static u16 green16[] = { 0x0000, 0x0000, 0xaaaa, 0xaaaa, 0x0000, 0x0000, 0x5555, 0xaaaa, 0x5555, 0x5555, 0xffff, 0xffff, 0x5555, 0x5555, 0xffff, 0xffff }; -static u16 blue16[] __read_mostly = { +static u16 blue16[] = { 0x0000, 0xaaaa, 0x0000, 0xaaaa, 0x0000, 0xaaaa, 0x0000, 0xaaaa, 0x5555, 0xffff, 0x5555, 0xffff, 0x5555, 0xffff, 0x5555, 0xffff }; -static const struct fb_cmap default_2_colors = { - .len=2, .red=red2, .green=green2, .blue=blue2 +static struct fb_cmap default_2_colors = { + 0, 2, red2, green2, blue2, NULL }; -static const struct fb_cmap default_8_colors = { - .len=8, .red=red8, .green=green8, .blue=blue8 +static struct fb_cmap default_8_colors = { + 0, 8, red8, green8, blue8, NULL }; -static const struct fb_cmap default_4_colors = { - .len=4, .red=red4, .green=green4, .blue=blue4 +static struct fb_cmap default_4_colors = { + 0, 4, red4, green4, blue4, NULL }; -static const struct fb_cmap default_16_colors = { - .len=16, .red=red16, .green=green16, .blue=blue16 +static struct fb_cmap default_16_colors = { + 0, 16, red16, green16, blue16, NULL }; - /** * fb_alloc_cmap - allocate a colormap * @cmap: frame buffer colormap structure @@ -147,7 +146,7 @@ void fb_dealloc_cmap(struct fb_cmap *cmap) * Copy contents of colormap from @from to @to. */ -int fb_copy_cmap(const struct fb_cmap *from, struct fb_cmap *to) +int fb_copy_cmap(struct fb_cmap *from, struct fb_cmap *to) { int tooff = 0, fromoff = 0; int size; @@ -171,7 +170,7 @@ int fb_copy_cmap(const struct fb_cmap *from, struct fb_cmap *to) return 0; } -int fb_cmap_to_user(const struct fb_cmap *from, struct fb_cmap_user *to) +int fb_cmap_to_user(struct fb_cmap *from, struct fb_cmap_user *to) { int tooff = 0, fromoff = 0; int size; @@ -283,7 +282,7 @@ int fb_set_user_cmap(struct fb_cmap_user *cmap, struct fb_info *info) * */ -const struct fb_cmap *fb_default_cmap(int len) +struct fb_cmap *fb_default_cmap(int len) { if (len <= 2) return &default_2_colors; @@ -306,22 +305,22 @@ void fb_invert_cmaps(void) { u_int i; - for (i = 0; i < ARRAY_SIZE(red2); i++) { + for (i = 0; i < 2; i++) { red2[i] = ~red2[i]; green2[i] = ~green2[i]; blue2[i] = ~blue2[i]; } - for (i = 0; i < ARRAY_SIZE(red4); i++) { + for (i = 0; i < 4; i++) { red4[i] = ~red4[i]; green4[i] = ~green4[i]; blue4[i] = ~blue4[i]; } - for (i = 0; i < ARRAY_SIZE(red8); i++) { + for (i = 0; i < 8; i++) { red8[i] = ~red8[i]; green8[i] = ~green8[i]; blue8[i] = ~blue8[i]; } - for (i = 0; i < ARRAY_SIZE(red16); i++) { + for (i = 0; i < 16; i++) { red16[i] = ~red16[i]; green16[i] = ~green16[i]; blue16[i] = ~blue16[i]; diff --git a/trunk/drivers/video/fbcvt.c b/trunk/drivers/video/fbcvt.c index 0847c5e72cbd..b5498999c4ec 100644 --- a/trunk/drivers/video/fbcvt.c +++ b/trunk/drivers/video/fbcvt.c @@ -57,7 +57,7 @@ struct fb_cvt_data { u32 status; }; -static const unsigned char fb_cvt_vbi_tab[] = { +static int fb_cvt_vbi_tab[] = { 4, /* 4:3 */ 5, /* 16:9 */ 6, /* 16:10 */ diff --git a/trunk/drivers/video/fbmem.c b/trunk/drivers/video/fbmem.c index 3cfea315a48f..e973a87fbb01 100644 --- a/trunk/drivers/video/fbmem.c +++ b/trunk/drivers/video/fbmem.c @@ -52,8 +52,8 @@ #define FBPIXMAPSIZE (1024 * 8) -struct fb_info *registered_fb[FB_MAX] __read_mostly; -int num_registered_fb __read_mostly; +struct fb_info *registered_fb[FB_MAX]; +int num_registered_fb; /* * Helpers @@ -202,7 +202,7 @@ static void fb_set_logo_truepalette(struct fb_info *info, const struct linux_logo *logo, u32 *palette) { - static const unsigned char mask[] = { 0,0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe,0xff }; + unsigned char mask[9] = { 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 __read_mostly; +} fb_logo; 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_path.dentry->d_inode; + struct inode *inode = file->f_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_path.dentry->d_inode; + struct inode *inode = file->f_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_path.dentry->d_inode; + struct inode *inode = file->f_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_path.dentry->d_inode); + int fbidx = iminor(file->f_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 const struct file_operations fb_fops = { +static 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] __read_mostly; -static int ofonly __read_mostly; +static char *video_options[FB_MAX]; +static int ofonly; extern const char *global_mode_option; diff --git a/trunk/drivers/video/fbmon.c b/trunk/drivers/video/fbmon.c index 6b385c39b8b5..de93139ccbb5 100644 --- a/trunk/drivers/video/fbmon.c +++ b/trunk/drivers/video/fbmon.c @@ -58,7 +58,7 @@ struct broken_edid { u32 fix; }; -static const struct broken_edid brokendb[] = { +static struct broken_edid brokendb[] = { /* DEC FR-PCXAV-YZ */ { .manufacturer = "DEC", diff --git a/trunk/drivers/video/ffb.c b/trunk/drivers/video/ffb.c index 949141bd44d4..2a0e8210d398 100644 --- a/trunk/drivers/video/ffb.c +++ b/trunk/drivers/video/ffb.c @@ -968,8 +968,6 @@ 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; } @@ -980,8 +978,6 @@ 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/trunk/drivers/video/fm2fb.c b/trunk/drivers/video/fm2fb.c index 70ff55b14596..998374cfae6d 100644 --- a/trunk/drivers/video/fm2fb.c +++ b/trunk/drivers/video/fm2fb.c @@ -283,7 +283,6 @@ 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/trunk/drivers/video/geode/Kconfig b/trunk/drivers/video/geode/Kconfig index a814b6c2605c..4e173ef20a7d 100644 --- a/trunk/drivers/video/geode/Kconfig +++ b/trunk/drivers/video/geode/Kconfig @@ -23,26 +23,6 @@ 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/trunk/drivers/video/geode/display_gx.c b/trunk/drivers/video/geode/display_gx.c index 0f16e4bffc6c..825c3405f5c2 100644 --- a/trunk/drivers/video/geode/display_gx.c +++ b/trunk/drivers/video/geode/display_gx.c @@ -21,27 +21,11 @@ #include "geodefb.h" #include "display_gx.h" -#ifdef CONFIG_FB_GEODE_GX_SET_FBSIZE -unsigned int gx_frame_buffer_size(void) +int gx_frame_buffer_size(void) { - return CONFIG_FB_GEODE_GX_FBSIZE; + /* Assuming 16 MiB. */ + return 16*1024*1024; } -#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) { @@ -97,7 +81,6 @@ 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/trunk/drivers/video/geode/display_gx.h b/trunk/drivers/video/geode/display_gx.h index 0af33f329e88..86c623361305 100644 --- a/trunk/drivers/video/geode/display_gx.h +++ b/trunk/drivers/video/geode/display_gx.h @@ -11,15 +11,11 @@ #ifndef __DISPLAY_GX_H__ #define __DISPLAY_GX_H__ -unsigned int gx_frame_buffer_size(void); +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 @@ -97,5 +93,4 @@ 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/trunk/drivers/video/geode/gxfb_core.c b/trunk/drivers/video/geode/gxfb_core.c index cf841efa229a..a454dcb8e215 100644 --- a/trunk/drivers/video/geode/gxfb_core.c +++ b/trunk/drivers/video/geode/gxfb_core.c @@ -35,10 +35,10 @@ #include "display_gx.h" #include "video_gx.h" -static char *mode_option; +static char mode_option[32] = "640x480-16@60"; /* Modes relevant to the GX (taken from modedb.c) */ -static const struct fb_videomode gx_modedb[] __initdata = { +static const struct fb_videomode __initdata gx_modedb[] = { /* 640x480-60 VESA */ { NULL, 60, 640, 480, 39682, 48, 16, 33, 10, 96, 2, 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, @@ -240,12 +240,6 @@ 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); @@ -308,7 +302,6 @@ 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) @@ -324,15 +317,6 @@ 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) { @@ -341,8 +325,7 @@ 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); @@ -412,35 +395,11 @@ 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 - char *option = NULL; - - if (fb_get_options("gxfb", &option)) + if (fb_get_options("gxfb", NULL)) return -ENODEV; - - gxfb_setup(option); #endif return pci_register_driver(&gxfb_driver); } @@ -453,8 +412,8 @@ static void __exit gxfb_cleanup(void) module_init(gxfb_init); module_exit(gxfb_cleanup); -module_param(mode_option, charp, 0); -MODULE_PARM_DESC(mode_option, "video mode (x[-][@])"); +module_param_string(mode, mode_option, sizeof(mode_option), 0444); +MODULE_PARM_DESC(mode, "video mode (x[-][@])"); MODULE_DESCRIPTION("Framebuffer driver for the AMD Geode GX"); MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/video/geode/video_gx.c b/trunk/drivers/video/geode/video_gx.c index 7f3f18d06718..2b2a7880ea75 100644 --- a/trunk/drivers/video/geode/video_gx.c +++ b/trunk/drivers/video/geode/video_gx.c @@ -175,88 +175,13 @@ 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, 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); + u32 dcfg, fp_pm; - /* 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 @@ -274,19 +199,12 @@ 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); - /* Set up the flat panel (if it is enabled) */ - - if (par->enable_crt == 0) - gx_configure_tft(info); + /* 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); } static int gx_blank_display(struct fb_info *info, int blank_mode) @@ -327,15 +245,12 @@ static int gx_blank_display(struct fb_info *info, int blank_mode) writel(dcfg, par->vid_regs + GX_DCFG); /* Power on/off flat panel. */ - - 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); - } + 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/trunk/drivers/video/geode/video_gx.h b/trunk/drivers/video/geode/video_gx.h index ce28d8f382dc..2d9211f3ed84 100644 --- a/trunk/drivers/video/geode/video_gx.h +++ b/trunk/drivers/video/geode/video_gx.h @@ -13,11 +13,6 @@ 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 @@ -25,8 +20,6 @@ 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 @@ -35,28 +28,10 @@ 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/trunk/drivers/video/hpfb.c b/trunk/drivers/video/hpfb.c index 9ab9b839a0f5..91cf3b577d15 100644 --- a/trunk/drivers/video/hpfb.c +++ b/trunk/drivers/video/hpfb.c @@ -295,8 +295,6 @@ 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/trunk/drivers/video/i810/i810-i2c.c b/trunk/drivers/video/i810/i810-i2c.c index b952e4504abe..b38d805db313 100644 --- a/trunk/drivers/video/i810/i810-i2c.c +++ b/trunk/drivers/video/i810/i810-i2c.c @@ -162,7 +162,9 @@ 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 = kmemdup(e, EDID_LENGTH, GFP_KERNEL); + edid = kmalloc(EDID_LENGTH, GFP_KERNEL); + if (edid) + memcpy(edid, e, EDID_LENGTH); } } diff --git a/trunk/drivers/video/igafb.c b/trunk/drivers/video/igafb.c index 655ae0fa99ca..e6df492c22a5 100644 --- a/trunk/drivers/video/igafb.c +++ b/trunk/drivers/video/igafb.c @@ -384,21 +384,19 @@ int __init igafb_init(void) if (!con_is_present()) return -ENXIO; - pdev = pci_get_device(PCI_VENDOR_ID_INTERG, + pdev = pci_find_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_get_device(PCI_VENDOR_ID_INTERG, 0x2000, 0); + pdev = pci_find_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/trunk/drivers/video/intelfb/intelfbdrv.c b/trunk/drivers/video/intelfb/intelfbdrv.c index 664fc5cf962a..6f9de04193d2 100644 --- a/trunk/drivers/video/intelfb/intelfbdrv.c +++ b/trunk/drivers/video/intelfb/intelfbdrv.c @@ -1058,9 +1058,10 @@ intelfb_init_var(struct intelfb_info *dinfo) u8 *edid_d = NULL; if (edid_s) { - edid_d = kmemdup(edid_s, EDID_LENGTH, GFP_KERNEL); + edid_d = kmalloc(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/trunk/drivers/video/macfb.c b/trunk/drivers/video/macfb.c index 180d94c2b4d2..80a043807161 100644 --- a/trunk/drivers/video/macfb.c +++ b/trunk/drivers/video/macfb.c @@ -608,22 +608,6 @@ 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; @@ -978,10 +962,6 @@ 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/trunk/drivers/video/mbx/mbxdebugfs.c b/trunk/drivers/video/mbx/mbxdebugfs.c index 472a3ca3d92d..84aab3ad024e 100644 --- a/trunk/drivers/video/mbx/mbxdebugfs.c +++ b/trunk/drivers/video/mbx/mbxdebugfs.c @@ -10,8 +10,6 @@ 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) @@ -31,11 +29,11 @@ static ssize_t sysconf_read_file(struct file *file, char __user *userbuf, { char * s = big_buffer; - 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)); + 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); return simple_read_from_buffer(userbuf, count, ppos, big_buffer, s-big_buffer); @@ -47,24 +45,24 @@ static ssize_t gsctl_read_file(struct file *file, char __user *userbuf, { char * s = big_buffer; - 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)); + 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); return simple_read_from_buffer(userbuf, count, ppos, big_buffer, s-big_buffer); @@ -75,36 +73,36 @@ static ssize_t display_read_file(struct file *file, char __user *userbuf, { char * s = big_buffer; - 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)); + 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); return simple_read_from_buffer(userbuf, count, ppos, big_buffer, s-big_buffer); @@ -115,61 +113,24 @@ static ssize_t clock_read_file(struct file *file, char __user *userbuf, { char * s = big_buffer; - 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)); + 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); 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, @@ -194,17 +155,6 @@ 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) { @@ -223,10 +173,6 @@ 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) @@ -234,8 +180,6 @@ 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/trunk/drivers/video/mbx/mbxfb.c b/trunk/drivers/video/mbx/mbxfb.c index 980d5f623902..a32d1af79e07 100644 --- a/trunk/drivers/video/mbx/mbxfb.c +++ b/trunk/drivers/video/mbx/mbxfb.c @@ -1,14 +1,8 @@ /* * linux/drivers/video/mbx/mbxfb.c * - * Copyright (C) 2006 8D Technologies inc - * Raphael Assenat - * - Added video overlay support - * - Various improvements - * * Copyright (C) 2006 Compulab, Ltd. * Mike Rapoport - * - Creation of driver * * Based on pxafb.c * @@ -25,7 +19,6 @@ #include #include #include -#include #include @@ -36,14 +29,6 @@ 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 @@ -272,17 +257,19 @@ 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); - write_reg_dly(gsctrl, GSCTRL); + writel(gsctrl, GSCTRL); + udelay(1000); gsadr &= ~(FMsk(GSADR_SRCSTRIDE)); gsadr |= Gsadr_Srcstride(info->var.xres * info->var.bits_per_pixel / (8 * 16) - 1); - write_reg_dly(gsadr, GSADR); + writel(gsadr, GSADR); + udelay(1000); /* setup timings */ var->pixclock = mbxfb_get_pixclock(info->var.pixclock, &div); - write_reg_dly((Disp_Pll_M(div.m) | Disp_Pll_N(div.n) | + writel((Disp_Pll_M(div.m) | Disp_Pll_N(div.n) | Disp_Pll_P(div.p) | DISP_PLL_EN), DISPPLL); hbps = var->hsync_len; @@ -295,20 +282,18 @@ static int mbxfb_set_par(struct fb_info *info) vfps = vas + var->yres; vt = vfps + var->lower_margin; - 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((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((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((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((readl(DSCTRL) | DSCTRL_SYNCGEN_EN), DSCTRL); - - write_reg_dly(DINTRE_VEVENT0_EN, DINTRE); + writel((readl(DSCTRL) | DSCTRL_SYNCGEN_EN), DSCTRL); return 0; } @@ -320,203 +305,23 @@ static int mbxfb_blank(int blank, struct fb_info *info) case FB_BLANK_VSYNC_SUSPEND: case FB_BLANK_HSYNC_SUSPEND: case FB_BLANK_NORMAL: - 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); + 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); break; case FB_BLANK_UNBLANK: - write_reg_dly((readl(DSCTRL) | DSCTRL_SYNCGEN_EN), DSCTRL); - write_reg_dly((readl(PIXCLK) | PIXCLK_EN), PIXCLK); + writel((readl(DSCTRL) | DSCTRL_SYNCGEN_EN), DSCTRL); + udelay(1000); + writel((readl(PIXCLK) | PIXCLK_EN), PIXCLK); + udelay(1000); 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, @@ -526,7 +331,6 @@ static struct fb_ops mbxfb_ops = { .fb_copyarea = cfb_copyarea, .fb_imageblit = cfb_imageblit, .fb_blank = mbxfb_blank, - .fb_ioctl = mbxfb_ioctl, }; /* @@ -535,29 +339,36 @@ 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 */ - write_reg_dly((LMCFG_LMC_DS | LMCFG_LMC_TS | LMCFG_LMD_TS | + writel((LMCFG_LMC_DS | LMCFG_LMC_TS | LMCFG_LMD_TS | LMCFG_LMA_TS), LMCFG); + udelay(1000); - write_reg_dly(LMPWR_MC_PWR_ACT, LMPWR); + writel(LMPWR_MC_PWR_ACT, LMPWR); + udelay(1000); /* setup SDRAM timings */ - write_reg_dly((Lmtim_Tras(7) | Lmtim_Trp(3) | Lmtim_Trcd(3) | + writel((Lmtim_Tras(7) | Lmtim_Trp(3) | Lmtim_Trcd(3) | Lmtim_Trc(9) | Lmtim_Tdpl(2)), LMTIM); + udelay(1000); /* setup SDRAM refresh rate */ - write_reg_dly(0xc2b, LMREFRESH); + writel(0xc2b, LMREFRESH); + udelay(1000); /* setup SDRAM type parameters */ - write_reg_dly((LMTYPE_CASLAT_3 | LMTYPE_BKSZ_2 | LMTYPE_ROWSZ_11 | + writel((LMTYPE_CASLAT_3 | LMTYPE_BKSZ_2 | LMTYPE_ROWSZ_11 | LMTYPE_COLSZ_8), LMTYPE); + udelay(1000); /* enable memory controller */ - write_reg_dly(LMPWR_MC_PWR_ACT, LMPWR); + writel(LMPWR_MC_PWR_ACT, LMPWR); + udelay(1000); /* perform dummy reads */ for ( i = 0; i < 16; i++ ) { @@ -568,30 +379,34 @@ static void __devinit setup_memc(struct fb_info *fbi) static void enable_clocks(struct fb_info *fbi) { /* enable clocks */ - 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) | + 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) | CORE_PLL_EN), COREPLL); - - write_reg_dly((Disp_Pll_M(0x1b) | Disp_Pll_N(0x7) | Disp_Pll_P(0x1) | + udelay(1000); + writel((Disp_Pll_M(0x1b) | Disp_Pll_N(0x7) | Disp_Pll_P(0x1) | DISP_PLL_EN), DISPPLL); - 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); + 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); } static void __devinit setup_graphics(struct fb_info *fbi) @@ -615,11 +430,16 @@ static void __devinit setup_graphics(struct fb_info *fbi) break; } - 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); + 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); } static void __devinit setup_display(struct fb_info *fbi) @@ -631,14 +451,17 @@ 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; - write_reg_dly(dsctrl, DSCTRL); - write_reg_dly(0xd0303010, DMCTRL); - write_reg_dly((readl(DSCTRL) | DSCTRL_SYNCGEN_EN), DSCTRL); + writel(dsctrl, DSCTRL); + udelay(1000); + writel(0xd0303010, DMCTRL); + udelay(1000); + writel((readl(DSCTRL) | DSCTRL_SYNCGEN_EN), DSCTRL); } static void __devinit enable_controller(struct fb_info *fbi) { - write_reg_dly(SYSRST_RST, SYSRST); + writel(SYSRST_RST, SYSRST); + udelay(1000); enable_clocks(fbi); @@ -655,12 +478,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 */ - write_reg_dly(LMPWR_MC_PWR_SRM, LMPWR); + writel(LMPWR_MC_PWR_SRM, LMPWR); while (LMPWRSTAT != LMPWRSTAT_MC_PWR_SRM) ; /* empty statement */ /* reset the device, since it's initial state is 'mostly sleeping' */ - write_reg_dly(SYSRST_RST, SYSRST); + writel(SYSRST_RST, SYSRST); return 0; } @@ -672,7 +495,7 @@ static int mbxfb_resume(struct platform_device *dev) /* setup_graphics(fbi); */ /* setup_display(fbi); */ - write_reg_dly((readl(DSCTRL) | DSCTRL_SYNCGEN_EN), DSCTRL); + writel((readl(DSCTRL) | DSCTRL_SYNCGEN_EN), DSCTRL); return 0; } #else @@ -697,12 +520,6 @@ 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"); @@ -711,8 +528,7 @@ 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) @@ -762,16 +578,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 = pdata->memsize; + fbi->screen_size = 8 * 1024 * 1024; /* 8 Megs */ 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 = pdata->memsize; - fbi->fix.line_length = mbxfb_default.xres_virtual * - mbxfb_default.bits_per_pixel / 8; + fbi->fix.smem_len = 8 * 1024 * 1024; + fbi->fix.line_length = 640 * 2; ret = fb_alloc_cmap(&fbi->cmap, 256, 0); if (ret < 0) { @@ -820,7 +636,8 @@ static int __devexit mbxfb_remove(struct platform_device *dev) { struct fb_info *fbi = platform_get_drvdata(dev); - write_reg_dly(SYSRST_RST, SYSRST); + writel(SYSRST_RST, SYSRST); + udelay(1000); mbxfb_debugfs_remove(fbi); diff --git a/trunk/drivers/video/mbx/reg_bits.h b/trunk/drivers/video/mbx/reg_bits.h index 9a24fb0c7d48..c226a8e45312 100644 --- a/trunk/drivers/video/mbx/reg_bits.h +++ b/trunk/drivers/video/mbx/reg_bits.h @@ -242,67 +242,6 @@ #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) @@ -455,30 +394,6 @@ #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) @@ -488,41 +403,16 @@ #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/trunk/drivers/video/mbx/regs.h b/trunk/drivers/video/mbx/regs.h index a7c63d865aad..ad20be07666b 100644 --- a/trunk/drivers/video/mbx/regs.h +++ b/trunk/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(0x000021c0) +#define HSCOEFF3 __REG_2700G(0x000021b0) #define HSCOEFF4 __REG_2700G(0x000021c4) #define HSCOEFF5 __REG_2700G(0x000021c8) #define HSCOEFF6 __REG_2700G(0x000021cc) diff --git a/trunk/drivers/video/modedb.c b/trunk/drivers/video/modedb.c index 5df41f6f2b86..d1267904c280 100644 --- a/trunk/drivers/video/modedb.c +++ b/trunk/drivers/video/modedb.c @@ -34,6 +34,8 @@ 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 */ @@ -503,10 +505,8 @@ int fb_find_mode(struct fb_var_screeninfo *var, db = modedb; dbsize = ARRAY_SIZE(modedb); } - if (!default_mode) - default_mode = &db[0]; - + default_mode = &modedb[DEFAULT_MODEDB_INDEX]; if (!default_bpp) default_bpp = 8; diff --git a/trunk/drivers/video/neofb.c b/trunk/drivers/video/neofb.c index deaf820cb38f..59a6f5fa5ae6 100644 --- a/trunk/drivers/video/neofb.c +++ b/trunk/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/trunk/drivers/video/nvidia/nv_accel.c b/trunk/drivers/video/nvidia/nv_accel.c index 9efb8a3854e2..4aefb8f41637 100644 --- a/trunk/drivers/video/nvidia/nv_accel.c +++ b/trunk/drivers/video/nvidia/nv_accel.c @@ -261,6 +261,41 @@ 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/trunk/drivers/video/nvidia/nv_i2c.c b/trunk/drivers/video/nvidia/nv_i2c.c index 442e85328341..19eef3a09023 100644 --- a/trunk/drivers/video/nvidia/nv_i2c.c +++ b/trunk/drivers/video/nvidia/nv_i2c.c @@ -210,8 +210,11 @@ 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 = kmemdup(e, EDID_LENGTH, GFP_KERNEL); + if (e != NULL) { + edid = kmalloc(EDID_LENGTH, GFP_KERNEL); + if (edid) + memcpy(edid, e, EDID_LENGTH); + } } *out_edid = edid; diff --git a/trunk/drivers/video/nvidia/nv_local.h b/trunk/drivers/video/nvidia/nv_local.h index e009d242ea10..4243d7fae972 100644 --- a/trunk/drivers/video/nvidia/nv_local.h +++ b/trunk/drivers/video/nvidia/nv_local.h @@ -96,16 +96,13 @@ #define READ_GET(par) (NV_RD32(&(par)->FIFO[0x0011], 0) >> 2) #ifdef __LITTLE_ENDIAN - -#include - #define reverse_order(l) \ do { \ u8 *a = (u8 *)(l); \ - a[0] = bitrev8(a[0]); \ - a[1] = bitrev8(a[1]); \ - a[2] = bitrev8(a[2]); \ - a[3] = bitrev8(a[3]); \ + *a = byte_rev[*a], a++; \ + *a = byte_rev[*a], a++; \ + *a = byte_rev[*a], a++; \ + *a = byte_rev[*a]; \ } while(0) #else #define reverse_order(l) do { } while(0) diff --git a/trunk/drivers/video/nvidia/nv_of.c b/trunk/drivers/video/nvidia/nv_of.c index 181875fe35c6..d9af88c2b580 100644 --- a/trunk/drivers/video/nvidia/nv_of.c +++ b/trunk/drivers/video/nvidia/nv_of.c @@ -72,9 +72,10 @@ int nvidia_probe_of_connector(struct fb_info *info, int conn, u8 **out_edid) } } if (pedid) { - *out_edid = kmemdup(pedid, EDID_LENGTH, GFP_KERNEL); + *out_edid = kmalloc(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/trunk/drivers/video/nvidia/nv_proto.h b/trunk/drivers/video/nvidia/nv_proto.h index 43058d0cf5b7..861271017655 100644 --- a/trunk/drivers/video/nvidia/nv_proto.h +++ b/trunk/drivers/video/nvidia/nv_proto.h @@ -62,6 +62,7 @@ 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/trunk/drivers/video/offb.c b/trunk/drivers/video/offb.c index 9576a55eaf16..9a40bbecf76b 100644 --- a/trunk/drivers/video/offb.c +++ b/trunk/drivers/video/offb.c @@ -402,9 +402,6 @@ 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/trunk/drivers/video/platinumfb.c b/trunk/drivers/video/platinumfb.c index 233871655824..cb26c6df0583 100644 --- a/trunk/drivers/video/platinumfb.c +++ b/trunk/drivers/video/platinumfb.c @@ -627,9 +627,6 @@ 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/trunk/drivers/video/pmagb-b-fb.c b/trunk/drivers/video/pmagb-b-fb.c index a06a064ad757..73e2d7d16608 100644 --- a/trunk/drivers/video/pmagb-b-fb.c +++ b/trunk/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, 74370, 72800, + 130808, 119843, 104000, 92980, 74367, 72800, 69197, 66000, 65000, 50350, 36000, 32000, 25175 }; struct pmagbbfb_par *par = info->par; diff --git a/trunk/drivers/video/pvr2fb.c b/trunk/drivers/video/pvr2fb.c index a93618bc9d27..c7bc80921f16 100644 --- a/trunk/drivers/video/pvr2fb.c +++ b/trunk/drivers/video/pvr2fb.c @@ -905,15 +905,6 @@ 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); @@ -955,15 +946,6 @@ 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/trunk/drivers/video/retz3fb.c b/trunk/drivers/video/retz3fb.c index bc7ffc84e185..cf41ff177644 100644 --- a/trunk/drivers/video/retz3fb.c +++ b/trunk/drivers/video/retz3fb.c @@ -1423,10 +1423,8 @@ int __init retz3fb_init(void) do_install_cmap(0, fb_info); - if (register_framebuffer(fb_info) < 0) { - iounmap(zinfo->base); + if (register_framebuffer(fb_info) < 0) return -EINVAL; - } printk(KERN_INFO "fb%d: %s frame buffer device, using %ldK of " "video memory\n", fb_info->node, diff --git a/trunk/drivers/video/riva/fbdev.c b/trunk/drivers/video/riva/fbdev.c index 345e8b1c1af8..a433cc78ef90 100644 --- a/trunk/drivers/video/riva/fbdev.c +++ b/trunk/drivers/video/riva/fbdev.c @@ -40,7 +40,6 @@ #include #include #include -#include #ifdef CONFIG_MTRR #include #endif @@ -522,13 +521,48 @@ 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[0] = bitrev8(a[0]); - a[1] = bitrev8(a[1]); - a[2] = bitrev8(a[2]); - a[3] = bitrev8(a[3]); + *a = byte_rev[*a], a++; + *a = byte_rev[*a], a++; + *a = byte_rev[*a], a++; + *a = byte_rev[*a]; } /* ------------------------------------------------------------------------- * @@ -740,12 +774,11 @@ static void riva_load_state(struct riva_par *par, struct riva_regs *regs) * CALLED FROM: * rivafb_set_par() */ -static int riva_load_video_mode(struct fb_info *info) +static void 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; @@ -851,10 +884,8 @@ static int riva_load_video_mode(struct fb_info *info) else newmode.misc_output |= 0x80; - rc = CalcStateExt(&par->riva, &newmode.ext, bpp, width, - hDisplaySize, height, dotClock); - if (rc) - goto out; + par->riva.CalcStateExt(&par->riva, &newmode.ext, bpp, width, + hDisplaySize, height, dotClock); newmode.ext.scale = NV_RD32(par->riva.PRAMDAC, 0x00000848) & 0xfff000ff; @@ -886,12 +917,8 @@ static int 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) @@ -1259,15 +1286,12 @@ 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); - rc = riva_load_video_mode(info); - if (rc) - goto out; + riva_load_video_mode(info); if(!(info->flags & FBINFO_HWACCEL_DISABLED)) riva_setup_accel(info); @@ -1280,10 +1304,8 @@ static int rivafb_set_par(struct fb_info *info) info->pixmap.scan_align = 1; else info->pixmap.scan_align = 4; - -out: NVTRACE_LEAVE(); - return rc; + return 0; } /** diff --git a/trunk/drivers/video/riva/riva_hw.c b/trunk/drivers/video/riva/riva_hw.c index e0b8c521cc9c..b6f8690b96c9 100644 --- a/trunk/drivers/video/riva/riva_hw.c +++ b/trunk/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. */ -int CalcStateExt +static void CalcStateExt ( RIVA_HW_INST *chip, RIVA_HW_STATE *state, @@ -1249,8 +1249,7 @@ int CalcStateExt * Extended RIVA registers. */ pixelDepth = (bpp + 1)/8; - if (!CalcVClock(dotClock, &VClk, &m, &n, &p, chip)) - return -EINVAL; + CalcVClock(dotClock, &VClk, &m, &n, &p, chip); switch (chip->Architecture) { @@ -1328,8 +1327,6 @@ int CalcStateExt state->pitch1 = state->pitch2 = state->pitch3 = pixelDepth * width; - - return 0; } /* * Load fixed function state and pre-calculated/stored state. @@ -2029,6 +2026,7 @@ static void nv3GetConfig */ chip->Busy = nv3Busy; chip->ShowHideCursor = ShowHideCursor; + chip->CalcStateExt = CalcStateExt; chip->LoadStateExt = LoadStateExt; chip->UnloadStateExt = UnloadStateExt; chip->SetStartAddress = SetStartAddress3; @@ -2086,6 +2084,7 @@ static void nv4GetConfig */ chip->Busy = nv4Busy; chip->ShowHideCursor = ShowHideCursor; + chip->CalcStateExt = CalcStateExt; chip->LoadStateExt = LoadStateExt; chip->UnloadStateExt = UnloadStateExt; chip->SetStartAddress = SetStartAddress; @@ -2187,6 +2186,7 @@ static void nv10GetConfig */ chip->Busy = nv10Busy; chip->ShowHideCursor = ShowHideCursor; + chip->CalcStateExt = CalcStateExt; chip->LoadStateExt = LoadStateExt; chip->UnloadStateExt = UnloadStateExt; chip->SetStartAddress = SetStartAddress; diff --git a/trunk/drivers/video/riva/riva_hw.h b/trunk/drivers/video/riva/riva_hw.h index c2769f73e0b2..a1e71a626df2 100644 --- a/trunk/drivers/video/riva/riva_hw.h +++ b/trunk/drivers/video/riva/riva_hw.h @@ -463,6 +463,7 @@ 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); @@ -527,22 +528,6 @@ 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/trunk/drivers/video/s3c2410fb.c b/trunk/drivers/video/s3c2410fb.c index ccef56d0c157..59407343cc73 100644 --- a/trunk/drivers/video/s3c2410fb.c +++ b/trunk/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 * var->bits_per_pixel / 16) & 0x3ff); + saddr3 = S3C2410_OFFSIZE(0) | S3C2410_PAGEWIDTH(var->xres); dprintk("LCDSADDR1 = 0x%08lx\n", saddr1); dprintk("LCDSADDR2 = 0x%08lx\n", saddr2); @@ -199,86 +199,28 @@ 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 @@ -288,61 +230,29 @@ 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); - 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); - } + 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; + } /* check to see if we need to update sync/borders */ @@ -373,44 +283,15 @@ 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(hs - 1); + fbi->regs.lcdcon3 |= S3C2410_LCDCON3_HOZVAL(var->xres - 1); if (var->pixclock > 0) { int clkdiv = s3c2410fb_calc_pixclk(fbi, var->pixclock); - 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; - } + clkdiv = (clkdiv / 2) -1; + if (clkdiv < 0) + clkdiv = 0; fbi->regs.lcdcon1 &= ~S3C2410_LCDCON1_CLKVAL(0x3ff); fbi->regs.lcdcon1 |= S3C2410_LCDCON1_CLKVAL(clkdiv); @@ -448,18 +329,10 @@ static int s3c2410fb_set_par(struct fb_info *info) struct s3c2410fb_info *fbi = info->par; struct fb_var_screeninfo *var = &info->var; - 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; - } + if (var->bits_per_pixel == 16) + fbi->fb->fix.visual = FB_VISUAL_TRUECOLOR; + else + fbi->fb->fix.visual = FB_VISUAL_PSEUDOCOLOR; fbi->fb->fix.line_length = (var->width*var->bits_per_pixel)/8; diff --git a/trunk/drivers/video/savage/savagefb-i2c.c b/trunk/drivers/video/savage/savagefb-i2c.c index cef5bf591cdf..3f94223b7f0c 100644 --- a/trunk/drivers/video/savage/savagefb-i2c.c +++ b/trunk/drivers/video/savage/savagefb-i2c.c @@ -227,8 +227,11 @@ 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 = kmemdup(e, EDID_LENGTH, GFP_KERNEL); + if (e) { + edid = kmalloc(EDID_LENGTH, GFP_KERNEL); + if (edid) + memcpy(edid, e, EDID_LENGTH); + } } *out_edid = edid; diff --git a/trunk/drivers/video/sis/init301.c b/trunk/drivers/video/sis/init301.c index 47e1896cffeb..f13faddc6181 100644 --- a/trunk/drivers/video/sis/init301.c +++ b/trunk/drivers/video/sis/init301.c @@ -445,8 +445,11 @@ SiS_CR36BIOSWord23d(struct SiS_Private *SiS_Pr) void SiS_DDC2Delay(struct SiS_Private *SiS_Pr, unsigned int delaytime) { - while (delaytime-- > 0) - SiS_GetReg(SiS_Pr->SiS_P3c4, 0x05); + unsigned int i, j; + + for(i = 0; i < delaytime; i++) { + j += SiS_GetReg(SiS_Pr->SiS_P3c4,0x05); + } } #if defined(SIS300) || defined(SIS315H) diff --git a/trunk/drivers/video/stifb.c b/trunk/drivers/video/stifb.c index 69f3b264a22e..3e16e2d9d55d 100644 --- a/trunk/drivers/video/stifb.c +++ b/trunk/drivers/video/stifb.c @@ -1291,7 +1291,6 @@ stifb_init_fb(struct sti_struct *sti, int bpp_pref) 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); @@ -1365,8 +1364,6 @@ 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/trunk/drivers/video/tgafb.c b/trunk/drivers/video/tgafb.c index 4b88fab83b74..94fde625a6c0 100644 --- a/trunk/drivers/video/tgafb.c +++ b/trunk/drivers/video/tgafb.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include