aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/00-INDEX2
-rw-r--r--Documentation/feature-removal-schedule.txt8
-rw-r--r--Documentation/filesystems/proc.txt7
-rw-r--r--Documentation/timers/00-INDEX10
-rw-r--r--Documentation/timers/hpet.txt (renamed from Documentation/hpet.txt)43
-rw-r--r--MAINTAINERS18
-rw-r--r--arch/Kconfig14
-rw-r--r--arch/alpha/Kconfig4
-rw-r--r--arch/alpha/include/asm/statfs.h4
-rw-r--r--arch/arm/Kconfig4
-rw-r--r--arch/arm/include/asm/statfs.h34
-rw-r--r--arch/arm/kernel/dma.c17
-rw-r--r--arch/avr32/include/asm/a.out.h20
-rw-r--r--arch/blackfin/include/asm/a.out.h19
-rw-r--r--arch/blackfin/kernel/bfin_dma_5xx.c13
-rw-r--r--arch/blackfin/mach-bf527/include/mach/bfin_serial_5xx.h6
-rw-r--r--arch/blackfin/mach-bf533/include/mach/bfin_serial_5xx.h4
-rw-r--r--arch/blackfin/mach-bf537/include/mach/bfin_serial_5xx.h6
-rw-r--r--arch/blackfin/mach-bf548/include/mach/bfin_serial_5xx.h6
-rw-r--r--arch/blackfin/mach-bf561/include/mach/bfin_serial_5xx.h4
-rw-r--r--arch/cris/arch-v10/boot/tools/build.c1
-rw-r--r--arch/h8300/Kconfig3
-rw-r--r--arch/h8300/include/asm/a.out.h20
-rw-r--r--arch/h8300/kernel/process.c1
-rw-r--r--arch/ia64/include/asm/a.out.h32
-rw-r--r--arch/ia64/include/asm/statfs.h52
-rw-r--r--arch/ia64/mm/init.c1
-rw-r--r--arch/m32r/Kconfig3
-rw-r--r--arch/m68k/Kconfig4
-rw-r--r--arch/m68knommu/Kconfig3
-rw-r--r--arch/m68knommu/include/asm/a.out.h1
-rw-r--r--arch/m68knommu/kernel/process.c1
-rw-r--r--arch/m68knommu/kernel/traps.c1
-rw-r--r--arch/mips/include/asm/a.out.h35
-rw-r--r--arch/mips/kernel/process.c1
-rw-r--r--arch/mips/kernel/syscall.c1
-rw-r--r--arch/mn10300/Kconfig3
-rw-r--r--arch/parisc/Kconfig3
-rw-r--r--arch/powerpc/include/asm/a.out.h20
-rw-r--r--arch/powerpc/include/asm/statfs.h54
-rw-r--r--arch/powerpc/kernel/softemu8xx.c1
-rw-r--r--arch/powerpc/kernel/traps.c1
-rw-r--r--arch/powerpc/platforms/chrp/setup.c1
-rw-r--r--arch/powerpc/platforms/maple/setup.c1
-rw-r--r--arch/powerpc/platforms/powermac/setup.c1
-rw-r--r--arch/powerpc/platforms/pseries/setup.c1
-rw-r--r--arch/s390/include/asm/statfs.h11
-rw-r--r--arch/sparc/include/asm/Kbuild2
-rw-r--r--arch/sparc/include/asm/serial.h6
-rw-r--r--arch/sparc/include/asm/statfs.h8
-rw-r--r--arch/sparc/include/asm/statfs_32.h6
-rw-r--r--arch/sparc/include/asm/statfs_64.h54
-rw-r--r--arch/um/Kconfig.i3868
-rw-r--r--arch/um/Kconfig.x86_643
-rw-r--r--arch/um/drivers/line.c2
-rw-r--r--arch/x86/Kconfig6
-rw-r--r--arch/x86/Kconfig.cpu29
-rw-r--r--arch/x86/Makefile_32.cpu1
-rw-r--r--arch/x86/configs/i386_defconfig1
-rw-r--r--arch/x86/configs/x86_64_defconfig1
-rw-r--r--arch/x86/ia32/ia32entry.S26
-rw-r--r--arch/x86/kernel/Makefile2
-rw-r--r--arch/x86/kernel/alternative.c2
-rw-r--r--arch/x86/kernel/apic_32.c4
-rw-r--r--arch/x86/kernel/apic_64.c4
-rw-r--r--arch/x86/kernel/cpu/common.c45
-rw-r--r--arch/x86/kernel/doublefault_32.c2
-rw-r--r--arch/x86/kernel/dumpstack_32.c447
-rw-r--r--arch/x86/kernel/dumpstack_64.c573
-rw-r--r--arch/x86/kernel/entry_32.S22
-rw-r--r--arch/x86/kernel/entry_64.S15
-rw-r--r--arch/x86/kernel/es7000_32.c28
-rw-r--r--arch/x86/kernel/genx2apic_uv_x.c23
-rw-r--r--arch/x86/kernel/head.c1
-rw-r--r--arch/x86/kernel/hpet.c6
-rw-r--r--arch/x86/kernel/irqinit_64.c43
-rw-r--r--arch/x86/kernel/process_32.c4
-rw-r--r--arch/x86/kernel/process_64.c7
-rw-r--r--arch/x86/kernel/quirks.c41
-rw-r--r--arch/x86/kernel/setup.c10
-rw-r--r--arch/x86/kernel/smpboot.c87
-rw-r--r--arch/x86/kernel/time_32.c7
-rw-r--r--arch/x86/kernel/time_64.c23
-rw-r--r--arch/x86/kernel/traps.c (renamed from arch/x86/kernel/traps_32.c)893
-rw-r--r--arch/x86/kernel/traps_64.c1214
-rw-r--r--arch/x86/mach-generic/es7000.c20
-rw-r--r--arch/x86/mm/Makefile6
-rw-r--r--arch/x86/mm/fault.c5
-rw-r--r--arch/x86/mm/gup.c10
-rw-r--r--arch/x86/mm/init_32.c2
-rw-r--r--arch/x86/mm/init_64.c9
-rw-r--r--arch/x86/mm/ioremap.c143
-rw-r--r--arch/x86/mm/numa_32.c (renamed from arch/x86/mm/discontig_32.c)0
-rw-r--r--arch/x86/mm/srat_64.c2
-rw-r--r--arch/x86/oprofile/Makefile2
-rw-r--r--arch/x86/oprofile/nmi_int.c27
-rw-r--r--arch/x86/oprofile/op_model_amd.c543
-rw-r--r--arch/x86/oprofile/op_model_athlon.c190
-rw-r--r--arch/x86/oprofile/op_x86_model.h4
-rw-r--r--arch/x86/pci/fixup.c28
-rw-r--r--drivers/bluetooth/hci_ldisc.c2
-rw-r--r--drivers/char/Kconfig4
-rw-r--r--drivers/char/Makefile2
-rw-r--r--drivers/char/amiserial.c6
-rw-r--r--drivers/char/applicom.c6
-rw-r--r--drivers/char/cyclades.c21
-rw-r--r--drivers/char/epca.c5
-rw-r--r--drivers/char/generic_serial.c21
-rw-r--r--drivers/char/hpet.c159
-rw-r--r--drivers/char/hvc_console.c4
-rw-r--r--drivers/char/ip2/Makefile2
-rw-r--r--drivers/char/ip2/i2ellis.c32
-rw-r--r--drivers/char/ip2/i2ellis.h2
-rw-r--r--drivers/char/ip2/ip2base.c108
-rw-r--r--drivers/char/ip2/ip2main.c550
-rw-r--r--drivers/char/isicom.c61
-rw-r--r--drivers/char/istallion.c113
-rw-r--r--drivers/char/moxa.c61
-rw-r--r--drivers/char/mxser.c193
-rw-r--r--drivers/char/n_hdlc.c2
-rw-r--r--drivers/char/n_r3964.c8
-rw-r--r--drivers/char/n_tty.c125
-rw-r--r--drivers/char/nozomi.c5
-rw-r--r--drivers/char/pcmcia/ipwireless/tty.c19
-rw-r--r--drivers/char/pty.c335
-rw-r--r--drivers/char/stallion.c139
-rw-r--r--drivers/char/sx.c4
-rw-r--r--drivers/char/tpm/tpm.c96
-rw-r--r--drivers/char/tpm/tpm.h3
-rw-r--r--drivers/char/tpm/tpm_tis.c14
-rw-r--r--drivers/char/tty_audit.c2
-rw-r--r--drivers/char/tty_buffer.c511
-rw-r--r--drivers/char/tty_io.c1380
-rw-r--r--drivers/char/tty_ioctl.c212
-rw-r--r--drivers/char/tty_port.c96
-rw-r--r--drivers/char/vt.c84
-rw-r--r--drivers/char/vt_ioctl.c2
-rw-r--r--drivers/isdn/capi/capi.c2
-rw-r--r--drivers/isdn/gigaset/ser-gigaset.c27
-rw-r--r--drivers/media/video/cafe_ccic.c13
-rw-r--r--drivers/mmc/host/sdhci-pci.c2
-rw-r--r--drivers/mtd/nand/cafe_nand.c6
-rw-r--r--drivers/net/wan/Kconfig2
-rw-r--r--drivers/oprofile/buffer_sync.c209
-rw-r--r--drivers/oprofile/cpu_buffer.c74
-rw-r--r--drivers/oprofile/cpu_buffer.h2
-rw-r--r--drivers/s390/char/fs3270.c17
-rw-r--r--drivers/serial/8250.c52
-rw-r--r--drivers/serial/8250_pci.c4
-rw-r--r--drivers/serial/Kconfig17
-rw-r--r--drivers/serial/Makefile16
-rw-r--r--drivers/serial/bfin_5xx.c123
-rw-r--r--drivers/serial/crisv10.c5
-rw-r--r--drivers/serial/mcfserial.c1965
-rw-r--r--drivers/serial/mcfserial.h74
-rw-r--r--drivers/serial/serial_core.c12
-rw-r--r--drivers/usb/serial/aircable.c15
-rw-r--r--drivers/usb/serial/belkin_sa.c3
-rw-r--r--drivers/usb/serial/console.c8
-rw-r--r--drivers/usb/serial/cyberjack.c3
-rw-r--r--drivers/usb/serial/cypress_m8.c5
-rw-r--r--drivers/usb/serial/digi_acceleport.c19
-rw-r--r--drivers/usb/serial/empeg.c8
-rw-r--r--drivers/usb/serial/ftdi_sio.c25
-rw-r--r--drivers/usb/serial/garmin_gps.c3
-rw-r--r--drivers/usb/serial/generic.c3
-rw-r--r--drivers/usb/serial/io_edgeport.c43
-rw-r--r--drivers/usb/serial/io_ti.c26
-rw-r--r--drivers/usb/serial/ipaq.c3
-rw-r--r--drivers/usb/serial/ipw.c3
-rw-r--r--drivers/usb/serial/ir-usb.c3
-rw-r--r--drivers/usb/serial/iuu_phoenix.c3
-rw-r--r--drivers/usb/serial/keyspan.c77
-rw-r--r--drivers/usb/serial/keyspan_pda.c16
-rw-r--r--drivers/usb/serial/kl5kusb105.c3
-rw-r--r--drivers/usb/serial/kobil_sct.c3
-rw-r--r--drivers/usb/serial/mct_u232.c6
-rw-r--r--drivers/usb/serial/mos7720.c36
-rw-r--r--drivers/usb/serial/mos7840.c7
-rw-r--r--drivers/usb/serial/navman.c3
-rw-r--r--drivers/usb/serial/omninet.c10
-rw-r--r--drivers/usb/serial/option.c18
-rw-r--r--drivers/usb/serial/oti6858.c7
-rw-r--r--drivers/usb/serial/pl2303.c15
-rw-r--r--drivers/usb/serial/safe_serial.c11
-rw-r--r--drivers/usb/serial/sierra.c16
-rw-r--r--drivers/usb/serial/spcp8x5.c3
-rw-r--r--drivers/usb/serial/ti_usb_3410_5052.c44
-rw-r--r--drivers/usb/serial/usb-serial.c24
-rw-r--r--drivers/usb/serial/visor.c18
-rw-r--r--drivers/usb/serial/whiteheat.c8
-rw-r--r--drivers/video/backlight/mbp_nvidia_bl.c4
-rw-r--r--fs/Kconfig.binfmt6
-rw-r--r--fs/debugfs/inode.c3
-rw-r--r--fs/devpts/inode.c66
-rw-r--r--fs/dquot.c6
-rw-r--r--fs/efs/super.c2
-rw-r--r--fs/open.c3
-rw-r--r--fs/proc/Kconfig10
-rw-r--r--fs/proc/array.c7
-rw-r--r--fs/proc/base.c21
-rw-r--r--fs/proc/inode.c2
-rw-r--r--fs/proc/internal.h2
-rw-r--r--fs/proc/proc_misc.c1
-rw-r--r--fs/proc/proc_sysctl.c6
-rw-r--r--fs/proc/task_mmu.c16
-rw-r--r--fs/proc/task_nommu.c5
-rw-r--r--fs/proc/vmcore.c6
-rw-r--r--include/asm-cris/a.out.h26
-rw-r--r--include/asm-generic/statfs.h65
-rw-r--r--include/asm-m32r/a.out.h20
-rw-r--r--include/asm-parisc/a.out.h20
-rw-r--r--include/asm-parisc/statfs.h55
-rw-r--r--include/asm-x86/desc.h14
-rw-r--r--include/asm-x86/es7000/mpparse.h1
-rw-r--r--include/asm-x86/fixmap_32.h4
-rw-r--r--include/asm-x86/fixmap_64.h12
-rw-r--r--include/asm-x86/io.h15
-rw-r--r--include/asm-x86/io_64.h3
-rw-r--r--include/asm-x86/ioctls.h6
-rw-r--r--include/asm-x86/irqflags.h21
-rw-r--r--include/asm-x86/kdebug.h3
-rw-r--r--include/asm-x86/kprobes.h9
-rw-r--r--include/asm-x86/mach-default/mach_traps.h6
-rw-r--r--include/asm-x86/module.h2
-rw-r--r--include/asm-x86/nmi.h4
-rw-r--r--include/asm-x86/page.h8
-rw-r--r--include/asm-x86/page_32.h10
-rw-r--r--include/asm-x86/pgtable.h16
-rw-r--r--include/asm-x86/ptrace.h4
-rw-r--r--include/asm-x86/segment.h6
-rw-r--r--include/asm-x86/smp.h8
-rw-r--r--include/asm-x86/statfs.h61
-rw-r--r--include/asm-x86/system.h5
-rw-r--r--include/asm-x86/traps.h73
-rw-r--r--include/asm-xtensa/a.out.h29
-rw-r--r--include/linux/devpts_fs.h31
-rw-r--r--include/linux/dmi.h41
-rw-r--r--include/linux/hpet.h14
-rw-r--r--include/linux/magic.h4
-rw-r--r--include/linux/mod_devicetable.h47
-rw-r--r--include/linux/oprofile.h2
-rw-r--r--include/linux/pci_ids.h4
-rw-r--r--include/linux/serial.h16
-rw-r--r--include/linux/serial_core.h2
-rw-r--r--include/linux/termios.h15
-rw-r--r--include/linux/tty.h45
-rw-r--r--include/linux/tty_driver.h56
-rw-r--r--include/linux/vt_kern.h2
-rw-r--r--include/net/cipso_ipv4.h55
-rw-r--r--include/net/netlabel.h51
-rw-r--r--include/sound/soc-dapm.h1
-rw-r--r--init/Kconfig10
-rw-r--r--kernel/acct.c2
-rw-r--r--kernel/auditsc.c9
-rw-r--r--kernel/fork.c5
-rw-r--r--kernel/printk.c16
-rw-r--r--kernel/sched_debug.c2
-rw-r--r--kernel/sys.c4
-rw-r--r--kernel/sysctl.c11
-rw-r--r--mm/shmem.c4
-rw-r--r--net/ipv4/cipso_ipv4.c656
-rw-r--r--net/ipv4/ip_options.c2
-rw-r--r--net/netlabel/Makefile3
-rw-r--r--net/netlabel/netlabel_addrlist.c388
-rw-r--r--net/netlabel/netlabel_addrlist.h189
-rw-r--r--net/netlabel/netlabel_cipso_v4.c136
-rw-r--r--net/netlabel/netlabel_cipso_v4.h10
-rw-r--r--net/netlabel/netlabel_domainhash.c393
-rw-r--r--net/netlabel/netlabel_domainhash.h40
-rw-r--r--net/netlabel/netlabel_kapi.c272
-rw-r--r--net/netlabel/netlabel_mgmt.c410
-rw-r--r--net/netlabel/netlabel_mgmt.h59
-rw-r--r--net/netlabel/netlabel_unlabeled.c456
-rw-r--r--scripts/mod/file2alias.c57
-rw-r--r--security/inode.c3
-rw-r--r--security/selinux/hooks.c232
-rw-r--r--security/selinux/include/netlabel.h44
-rw-r--r--security/selinux/include/objsec.h9
-rw-r--r--security/selinux/netlabel.c280
-rw-r--r--security/selinux/ss/services.c13
-rw-r--r--security/smack/smack_lsm.c5
-rw-r--r--security/smack/smackfs.c4
-rw-r--r--sound/oss/ac97_codec.c2
-rw-r--r--sound/pci/ac97/ac97_patch.c2
-rw-r--r--sound/pci/hda/patch_sigmatel.c50
-rw-r--r--sound/soc/at91/Kconfig17
-rw-r--r--sound/soc/at91/Makefile5
-rw-r--r--sound/soc/at91/at91-ssc.c2
-rw-r--r--sound/soc/at91/eti_b1_wm8731.c349
-rw-r--r--sound/soc/blackfin/Kconfig16
-rw-r--r--sound/soc/blackfin/Makefile3
-rw-r--r--sound/soc/blackfin/bf5xx-ac97-pcm.c42
-rw-r--r--sound/soc/blackfin/bf5xx-ac97.c1
-rw-r--r--sound/soc/blackfin/bf5xx-ad73311.c240
-rw-r--r--sound/soc/blackfin/bf5xx-i2s.c47
-rw-r--r--sound/soc/blackfin/bf5xx-sport.h2
-rw-r--r--sound/soc/codecs/Kconfig11
-rw-r--r--sound/soc/codecs/Makefile4
-rw-r--r--sound/soc/codecs/ac97.c3
-rw-r--r--sound/soc/codecs/ad1980.c1
-rw-r--r--sound/soc/codecs/ad73311.c107
-rw-r--r--sound/soc/codecs/ad73311.h90
-rw-r--r--sound/soc/codecs/ak4535.c1
-rw-r--r--sound/soc/codecs/ssm2602.c1
-rw-r--r--sound/soc/codecs/tlv320aic23.c714
-rw-r--r--sound/soc/codecs/tlv320aic23.h122
-rw-r--r--sound/soc/codecs/tlv320aic3x.c5
-rw-r--r--sound/soc/codecs/uda1380.c1
-rw-r--r--sound/soc/codecs/wm8510.c111
-rw-r--r--sound/soc/codecs/wm8510.h1
-rw-r--r--sound/soc/codecs/wm8580.c2
-rw-r--r--sound/soc/codecs/wm8731.c1
-rw-r--r--sound/soc/codecs/wm8750.c1
-rw-r--r--sound/soc/codecs/wm8753.c75
-rw-r--r--sound/soc/codecs/wm8753.h4
-rw-r--r--sound/soc/codecs/wm8900.c1
-rw-r--r--sound/soc/codecs/wm8903.c4
-rw-r--r--sound/soc/codecs/wm8971.c1
-rw-r--r--sound/soc/codecs/wm8990.c1
-rw-r--r--sound/soc/codecs/wm9712.c3
-rw-r--r--sound/soc/codecs/wm9713.c3
-rw-r--r--sound/soc/omap/Kconfig8
-rw-r--r--sound/soc/omap/Makefile2
-rw-r--r--sound/soc/omap/n810.c6
-rw-r--r--sound/soc/omap/omap-mcbsp.c181
-rw-r--r--sound/soc/omap/omap-mcbsp.h16
-rw-r--r--sound/soc/omap/omap-pcm.c4
-rw-r--r--sound/soc/omap/osk5912.c232
-rw-r--r--sound/soc/pxa/corgi.c6
-rw-r--r--sound/soc/pxa/em-x270.c2
-rw-r--r--sound/soc/pxa/poodle.c6
-rw-r--r--sound/soc/pxa/pxa2xx-i2s.c4
-rw-r--r--sound/soc/pxa/spitz.c16
-rw-r--r--sound/soc/pxa/tosa.c6
-rw-r--r--sound/soc/s3c24xx/neo1973_wm8753.c72
-rw-r--r--sound/soc/soc-core.c5
-rw-r--r--sound/soc/soc-dapm.c25
338 files changed, 10745 insertions, 9330 deletions
diff --git a/Documentation/00-INDEX b/Documentation/00-INDEX
index 73060819ed99..438277800103 100644
--- a/Documentation/00-INDEX
+++ b/Documentation/00-INDEX
@@ -159,8 +159,6 @@ hayes-esp.txt
159 - info on using the Hayes ESP serial driver. 159 - info on using the Hayes ESP serial driver.
160highuid.txt 160highuid.txt
161 - notes on the change from 16 bit to 32 bit user/group IDs. 161 - notes on the change from 16 bit to 32 bit user/group IDs.
162hpet.txt
163 - High Precision Event Timer Driver for Linux.
164timers/ 162timers/
165 - info on the timer related topics 163 - info on the timer related topics
166hw_random.txt 164hw_random.txt
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
index 3d2d0c29f027..cc8093c15cf5 100644
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -287,14 +287,6 @@ Who: Glauber Costa <gcosta@redhat.com>
287 287
288--------------------------- 288---------------------------
289 289
290What: old style serial driver for ColdFire (CONFIG_SERIAL_COLDFIRE)
291When: 2.6.28
292Why: This driver still uses the old interface and has been replaced
293 by CONFIG_SERIAL_MCF.
294Who: Sebastian Siewior <sebastian@breakpoint.cc>
295
296---------------------------
297
298What: /sys/o2cb symlink 290What: /sys/o2cb symlink
299When: January 2010 291When: January 2010
300Why: /sys/fs/o2cb is the proper location for this information - /sys/o2cb 292Why: /sys/fs/o2cb is the proper location for this information - /sys/o2cb
diff --git a/Documentation/filesystems/proc.txt b/Documentation/filesystems/proc.txt
index d831d24d2a6c..b488edad743c 100644
--- a/Documentation/filesystems/proc.txt
+++ b/Documentation/filesystems/proc.txt
@@ -1331,13 +1331,6 @@ determine whether or not they are still functioning properly.
1331Because the NMI watchdog shares registers with oprofile, by disabling the NMI 1331Because the NMI watchdog shares registers with oprofile, by disabling the NMI
1332watchdog, oprofile may have more registers to utilize. 1332watchdog, oprofile may have more registers to utilize.
1333 1333
1334maps_protect
1335------------
1336
1337Enables/Disables the protection of the per-process proc entries "maps" and
1338"smaps". When enabled, the contents of these files are visible only to
1339readers that are allowed to ptrace() the given process.
1340
1341msgmni 1334msgmni
1342------ 1335------
1343 1336
diff --git a/Documentation/timers/00-INDEX b/Documentation/timers/00-INDEX
new file mode 100644
index 000000000000..397dc35e1323
--- /dev/null
+++ b/Documentation/timers/00-INDEX
@@ -0,0 +1,10 @@
100-INDEX
2 - this file
3highres.txt
4 - High resolution timers and dynamic ticks design notes
5hpet.txt
6 - High Precision Event Timer Driver for Linux
7hrtimers.txt
8 - subsystem for high-resolution kernel timers
9timer_stats.txt
10 - timer usage statistics
diff --git a/Documentation/hpet.txt b/Documentation/timers/hpet.txt
index 6ad52d9dad6c..e7c09abcfab4 100644
--- a/Documentation/hpet.txt
+++ b/Documentation/timers/hpet.txt
@@ -1,21 +1,32 @@
1 High Precision Event Timer Driver for Linux 1 High Precision Event Timer Driver for Linux
2 2
3The High Precision Event Timer (HPET) hardware is the future replacement 3The High Precision Event Timer (HPET) hardware follows a specification
4for the 8254 and Real Time Clock (RTC) periodic timer functionality. 4by Intel and Microsoft which can be found at
5Each HPET can have up to 32 timers. It is possible to configure the 5
6first two timers as legacy replacements for 8254 and RTC periodic timers. 6 http://www.intel.com/technology/architecture/hpetspec.htm
7A specification done by Intel and Microsoft can be found at 7
8<http://www.intel.com/technology/architecture/hpetspec.htm>. 8Each HPET has one fixed-rate counter (at 10+ MHz, hence "High Precision")
9and up to 32 comparators. Normally three or more comparators are provided,
10each of which can generate oneshot interupts and at least one of which has
11additional hardware to support periodic interrupts. The comparators are
12also called "timers", which can be misleading since usually timers are
13independent of each other ... these share a counter, complicating resets.
14
15HPET devices can support two interrupt routing modes. In one mode, the
16comparators are additional interrupt sources with no particular system
17role. Many x86 BIOS writers don't route HPET interrupts at all, which
18prevents use of that mode. They support the other "legacy replacement"
19mode where the first two comparators block interrupts from 8254 timers
20and from the RTC.
9 21
10The driver supports detection of HPET driver allocation and initialization 22The driver supports detection of HPET driver allocation and initialization
11of the HPET before the driver module_init routine is called. This enables 23of the HPET before the driver module_init routine is called. This enables
12platform code which uses timer 0 or 1 as the main timer to intercept HPET 24platform code which uses timer 0 or 1 as the main timer to intercept HPET
13initialization. An example of this initialization can be found in 25initialization. An example of this initialization can be found in
14arch/i386/kernel/time_hpet.c. 26arch/x86/kernel/hpet.c.
15 27
16The driver provides two APIs which are very similar to the API found in 28The driver provides a userspace API which resembles the API found in the
17the rtc.c driver. There is a user space API and a kernel space API. 29RTC driver framework. An example user space program is provided below.
18An example user space program is provided below.
19 30
20#include <stdio.h> 31#include <stdio.h>
21#include <stdlib.h> 32#include <stdlib.h>
@@ -286,15 +297,3 @@ out:
286 297
287 return; 298 return;
288} 299}
289
290The kernel API has three interfaces exported from the driver:
291
292 hpet_register(struct hpet_task *tp, int periodic)
293 hpet_unregister(struct hpet_task *tp)
294 hpet_control(struct hpet_task *tp, unsigned int cmd, unsigned long arg)
295
296The kernel module using this interface fills in the ht_func and ht_data
297members of the hpet_task structure before calling hpet_register.
298hpet_control simply vectors to the hpet_ioctl routine and has the same
299commands and respective arguments as the user API. hpet_unregister
300is used to terminate usage of the HPET timer reserved by hpet_register.
diff --git a/MAINTAINERS b/MAINTAINERS
index 6ba3ee822838..74b808205312 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2797,15 +2797,6 @@ L: linux-mtd@lists.infradead.org
2797T: git git://git.infradead.org/mtd-2.6.git 2797T: git git://git.infradead.org/mtd-2.6.git
2798S: Maintained 2798S: Maintained
2799 2799
2800MEI MN10300/AM33 PORT
2801P: David Howells
2802M: dhowells@redhat.com
2803P: Koichi Yasutake
2804M: yasutake.koichi@jp.panasonic.com
2805L: linux-am33-list@redhat.com (moderated for non-subscribers)
2806W: ftp://ftp.redhat.com/pub/redhat/gnupro/AM33/
2807S: Maintained
2808
2809MICROTEK X6 SCANNER 2800MICROTEK X6 SCANNER
2810P: Oliver Neukum 2801P: Oliver Neukum
2811M: oliver@neukum.name 2802M: oliver@neukum.name
@@ -3170,6 +3161,15 @@ M: olof@lixom.net
3170L: i2c@lm-sensors.org 3161L: i2c@lm-sensors.org
3171S: Maintained 3162S: Maintained
3172 3163
3164PANASONIC MN10300/AM33 PORT
3165P: David Howells
3166M: dhowells@redhat.com
3167P: Koichi Yasutake
3168M: yasutake.koichi@jp.panasonic.com
3169L: linux-am33-list@redhat.com (moderated for non-subscribers)
3170W: ftp://ftp.redhat.com/pub/redhat/gnupro/AM33/
3171S: Maintained
3172
3173PARALLEL PORT SUPPORT 3173PARALLEL PORT SUPPORT
3174L: linux-parport@lists.infradead.org (subscribers-only) 3174L: linux-parport@lists.infradead.org (subscribers-only)
3175S: Orphan 3175S: Orphan
diff --git a/arch/Kconfig b/arch/Kconfig
index 364c6dadde0a..0267babe5eb9 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -13,6 +13,20 @@ config OPROFILE
13 13
14 If unsure, say N. 14 If unsure, say N.
15 15
16config OPROFILE_IBS
17 bool "OProfile AMD IBS support (EXPERIMENTAL)"
18 default n
19 depends on OPROFILE && SMP && X86
20 help
21 Instruction-Based Sampling (IBS) is a new profiling
22 technique that provides rich, precise program performance
23 information. IBS is introduced by AMD Family10h processors
24 (AMD Opteron Quad-Core processor “Barcelona”) to overcome
25 the limitations of conventional performance counter
26 sampling.
27
28 If unsure, say N.
29
16config HAVE_OPROFILE 30config HAVE_OPROFILE
17 def_bool n 31 def_bool n
18 32
diff --git a/arch/alpha/Kconfig b/arch/alpha/Kconfig
index 1bec55d63ef6..ee35226c44e9 100644
--- a/arch/alpha/Kconfig
+++ b/arch/alpha/Kconfig
@@ -5,6 +5,7 @@
5config ALPHA 5config ALPHA
6 bool 6 bool
7 default y 7 default y
8 select HAVE_AOUT
8 select HAVE_IDE 9 select HAVE_IDE
9 select HAVE_OPROFILE 10 select HAVE_OPROFILE
10 help 11 help
@@ -68,9 +69,6 @@ config AUTO_IRQ_AFFINITY
68 depends on SMP 69 depends on SMP
69 default y 70 default y
70 71
71config ARCH_SUPPORTS_AOUT
72 def_bool y
73
74source "init/Kconfig" 72source "init/Kconfig"
75 73
76 74
diff --git a/arch/alpha/include/asm/statfs.h b/arch/alpha/include/asm/statfs.h
index ad15830baefe..de35cd438a10 100644
--- a/arch/alpha/include/asm/statfs.h
+++ b/arch/alpha/include/asm/statfs.h
@@ -1,6 +1,10 @@
1#ifndef _ALPHA_STATFS_H 1#ifndef _ALPHA_STATFS_H
2#define _ALPHA_STATFS_H 2#define _ALPHA_STATFS_H
3 3
4/* Alpha is the only 64-bit platform with 32-bit statfs. And doesn't
5 even seem to implement statfs64 */
6#define __statfs_word __u32
7
4#include <asm-generic/statfs.h> 8#include <asm-generic/statfs.h>
5 9
6#endif 10#endif
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index efeed65b4a66..4853f9df37bd 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -8,6 +8,7 @@ mainmenu "Linux Kernel Configuration"
8config ARM 8config ARM
9 bool 9 bool
10 default y 10 default y
11 select HAVE_AOUT
11 select HAVE_IDE 12 select HAVE_IDE
12 select RTC_LIB 13 select RTC_LIB
13 select SYS_SUPPORTS_APM_EMULATION 14 select SYS_SUPPORTS_APM_EMULATION
@@ -140,9 +141,6 @@ config GENERIC_CALIBRATE_DELAY
140 bool 141 bool
141 default y 142 default y
142 143
143config ARCH_SUPPORTS_AOUT
144 def_bool y
145
146config ARCH_MAY_HAVE_PC_FDC 144config ARCH_MAY_HAVE_PC_FDC
147 bool 145 bool
148 146
diff --git a/arch/arm/include/asm/statfs.h b/arch/arm/include/asm/statfs.h
index a02e6a8c3d70..079447c05ba7 100644
--- a/arch/arm/include/asm/statfs.h
+++ b/arch/arm/include/asm/statfs.h
@@ -1,42 +1,12 @@
1#ifndef _ASMARM_STATFS_H 1#ifndef _ASMARM_STATFS_H
2#define _ASMARM_STATFS_H 2#define _ASMARM_STATFS_H
3 3
4#ifndef __KERNEL_STRICT_NAMES
5# include <linux/types.h>
6typedef __kernel_fsid_t fsid_t;
7#endif
8
9struct statfs {
10 __u32 f_type;
11 __u32 f_bsize;
12 __u32 f_blocks;
13 __u32 f_bfree;
14 __u32 f_bavail;
15 __u32 f_files;
16 __u32 f_ffree;
17 __kernel_fsid_t f_fsid;
18 __u32 f_namelen;
19 __u32 f_frsize;
20 __u32 f_spare[5];
21};
22
23/* 4/*
24 * With EABI there is 4 bytes of padding added to this structure. 5 * With EABI there is 4 bytes of padding added to this structure.
25 * Let's pack it so the padding goes away to simplify dual ABI support. 6 * Let's pack it so the padding goes away to simplify dual ABI support.
26 * Note that user space does NOT have to pack this structure. 7 * Note that user space does NOT have to pack this structure.
27 */ 8 */
28struct statfs64 { 9#define ARCH_PACK_STATFS64 __attribute__((packed,aligned(4)))
29 __u32 f_type;
30 __u32 f_bsize;
31 __u64 f_blocks;
32 __u64 f_bfree;
33 __u64 f_bavail;
34 __u64 f_files;
35 __u64 f_ffree;
36 __kernel_fsid_t f_fsid;
37 __u32 f_namelen;
38 __u32 f_frsize;
39 __u32 f_spare[5];
40} __attribute__ ((packed,aligned(4)));
41 10
11#include <asm-generic/statfs.h>
42#endif 12#endif
diff --git a/arch/arm/kernel/dma.c b/arch/arm/kernel/dma.c
index ba99a2035523..d006085ed7e7 100644
--- a/arch/arm/kernel/dma.c
+++ b/arch/arm/kernel/dma.c
@@ -26,23 +26,6 @@ EXPORT_SYMBOL(dma_spin_lock);
26static dma_t dma_chan[MAX_DMA_CHANNELS]; 26static dma_t dma_chan[MAX_DMA_CHANNELS];
27 27
28/* 28/*
29 * Get dma list for /proc/dma
30 */
31int get_dma_list(char *buf)
32{
33 dma_t *dma;
34 char *p = buf;
35 int i;
36
37 for (i = 0, dma = dma_chan; i < MAX_DMA_CHANNELS; i++, dma++)
38 if (dma->lock)
39 p += sprintf(p, "%2d: %14s %s\n", i,
40 dma->d_ops->type, dma->device_id);
41
42 return p - buf;
43}
44
45/*
46 * Request DMA channel 29 * Request DMA channel
47 * 30 *
48 * On certain platforms, we have to allocate an interrupt as well... 31 * On certain platforms, we have to allocate an interrupt as well...
diff --git a/arch/avr32/include/asm/a.out.h b/arch/avr32/include/asm/a.out.h
deleted file mode 100644
index e46375a34a72..000000000000
--- a/arch/avr32/include/asm/a.out.h
+++ /dev/null
@@ -1,20 +0,0 @@
1#ifndef __ASM_AVR32_A_OUT_H
2#define __ASM_AVR32_A_OUT_H
3
4struct exec
5{
6 unsigned long a_info; /* Use macros N_MAGIC, etc for access */
7 unsigned a_text; /* length of text, in bytes */
8 unsigned a_data; /* length of data, in bytes */
9 unsigned a_bss; /* length of uninitialized data area for file, in bytes */
10 unsigned a_syms; /* length of symbol table data in file, in bytes */
11 unsigned a_entry; /* start address */
12 unsigned a_trsize; /* length of relocation info for text, in bytes */
13 unsigned a_drsize; /* length of relocation info for data, in bytes */
14};
15
16#define N_TRSIZE(a) ((a).a_trsize)
17#define N_DRSIZE(a) ((a).a_drsize)
18#define N_SYMSIZE(a) ((a).a_syms)
19
20#endif /* __ASM_AVR32_A_OUT_H */
diff --git a/arch/blackfin/include/asm/a.out.h b/arch/blackfin/include/asm/a.out.h
deleted file mode 100644
index 6c3d652ebd33..000000000000
--- a/arch/blackfin/include/asm/a.out.h
+++ /dev/null
@@ -1,19 +0,0 @@
1#ifndef __BFIN_A_OUT_H__
2#define __BFIN_A_OUT_H__
3
4struct exec {
5 unsigned long a_info; /* Use macros N_MAGIC, etc for access */
6 unsigned a_text; /* length of text, in bytes */
7 unsigned a_data; /* length of data, in bytes */
8 unsigned a_bss; /* length of uninitialized data area for file, in bytes */
9 unsigned a_syms; /* length of symbol table data in file, in bytes */
10 unsigned a_entry; /* start address */
11 unsigned a_trsize; /* length of relocation info for text, in bytes */
12 unsigned a_drsize; /* length of relocation info for data, in bytes */
13};
14
15#define N_TRSIZE(a) ((a).a_trsize)
16#define N_DRSIZE(a) ((a).a_drsize)
17#define N_SYMSIZE(a) ((a).a_syms)
18
19#endif /* __BFIN_A_OUT_H__ */
diff --git a/arch/blackfin/kernel/bfin_dma_5xx.c b/arch/blackfin/kernel/bfin_dma_5xx.c
index 93229b3d6e3e..339293d677cc 100644
--- a/arch/blackfin/kernel/bfin_dma_5xx.c
+++ b/arch/blackfin/kernel/bfin_dma_5xx.c
@@ -117,15 +117,14 @@ int request_dma(unsigned int channel, char *device_id)
117 117
118#ifdef CONFIG_BF54x 118#ifdef CONFIG_BF54x
119 if (channel >= CH_UART2_RX && channel <= CH_UART3_TX) { 119 if (channel >= CH_UART2_RX && channel <= CH_UART3_TX) {
120 if (strncmp(device_id, "BFIN_UART", 9) == 0) { 120 unsigned int per_map;
121 dma_ch[channel].regs->peripheral_map &= 0x0FFF; 121 per_map = dma_ch[channel].regs->peripheral_map & 0xFFF;
122 dma_ch[channel].regs->peripheral_map |= 122 if (strncmp(device_id, "BFIN_UART", 9) == 0)
123 dma_ch[channel].regs->peripheral_map = per_map |
123 ((channel - CH_UART2_RX + 0xC)<<12); 124 ((channel - CH_UART2_RX + 0xC)<<12);
124 } else { 125 else
125 dma_ch[channel].regs->peripheral_map &= 0x0FFF; 126 dma_ch[channel].regs->peripheral_map = per_map |
126 dma_ch[channel].regs->peripheral_map |=
127 ((channel - CH_UART2_RX + 0x6)<<12); 127 ((channel - CH_UART2_RX + 0x6)<<12);
128 }
129 } 128 }
130#endif 129#endif
131 130
diff --git a/arch/blackfin/mach-bf527/include/mach/bfin_serial_5xx.h b/arch/blackfin/mach-bf527/include/mach/bfin_serial_5xx.h
index 2526b6ed6faa..75722d6008b0 100644
--- a/arch/blackfin/mach-bf527/include/mach/bfin_serial_5xx.h
+++ b/arch/blackfin/mach-bf527/include/mach/bfin_serial_5xx.h
@@ -78,6 +78,9 @@
78# define CONFIG_UART1_RTS_PIN -1 78# define CONFIG_UART1_RTS_PIN -1
79# endif 79# endif
80#endif 80#endif
81
82#define BFIN_UART_TX_FIFO_SIZE 2
83
81/* 84/*
82 * The pin configuration is different from schematic 85 * The pin configuration is different from schematic
83 */ 86 */
@@ -119,7 +122,6 @@ static inline void UART_CLEAR_LSR(struct bfin_serial_port *uart)
119 bfin_write16(uart->port.membase + OFFSET_LSR, -1); 122 bfin_write16(uart->port.membase + OFFSET_LSR, -1);
120} 123}
121 124
122struct bfin_serial_port bfin_serial_ports[BFIN_UART_NR_PORTS];
123struct bfin_serial_res { 125struct bfin_serial_res {
124 unsigned long uart_base_addr; 126 unsigned long uart_base_addr;
125 int uart_irq; 127 int uart_irq;
@@ -164,8 +166,6 @@ struct bfin_serial_res bfin_serial_resource[] = {
164#endif 166#endif
165}; 167};
166 168
167int nr_ports = ARRAY_SIZE(bfin_serial_resource);
168
169#define DRIVER_NAME "bfin-uart" 169#define DRIVER_NAME "bfin-uart"
170 170
171static void bfin_serial_hw_init(struct bfin_serial_port *uart) 171static void bfin_serial_hw_init(struct bfin_serial_port *uart)
diff --git a/arch/blackfin/mach-bf533/include/mach/bfin_serial_5xx.h b/arch/blackfin/mach-bf533/include/mach/bfin_serial_5xx.h
index ebf592b59aab..815bfe5dd1a9 100644
--- a/arch/blackfin/mach-bf533/include/mach/bfin_serial_5xx.h
+++ b/arch/blackfin/mach-bf533/include/mach/bfin_serial_5xx.h
@@ -69,6 +69,8 @@
69# endif 69# endif
70#endif 70#endif
71 71
72#define BFIN_UART_TX_FIFO_SIZE 2
73
72struct bfin_serial_port { 74struct bfin_serial_port {
73 struct uart_port port; 75 struct uart_port port;
74 unsigned int old_status; 76 unsigned int old_status;
@@ -111,7 +113,6 @@ static inline void UART_CLEAR_LSR(struct bfin_serial_port *uart)
111 bfin_write16(uart->port.membase + OFFSET_LSR, -1); 113 bfin_write16(uart->port.membase + OFFSET_LSR, -1);
112} 114}
113 115
114struct bfin_serial_port bfin_serial_ports[BFIN_UART_NR_PORTS];
115struct bfin_serial_res { 116struct bfin_serial_res {
116 unsigned long uart_base_addr; 117 unsigned long uart_base_addr;
117 int uart_irq; 118 int uart_irq;
@@ -142,7 +143,6 @@ struct bfin_serial_res bfin_serial_resource[] = {
142 143
143#define DRIVER_NAME "bfin-uart" 144#define DRIVER_NAME "bfin-uart"
144 145
145int nr_ports = BFIN_UART_NR_PORTS;
146static void bfin_serial_hw_init(struct bfin_serial_port *uart) 146static void bfin_serial_hw_init(struct bfin_serial_port *uart)
147{ 147{
148 148
diff --git a/arch/blackfin/mach-bf537/include/mach/bfin_serial_5xx.h b/arch/blackfin/mach-bf537/include/mach/bfin_serial_5xx.h
index 1bf56ffa22f9..b3f87e1d16a2 100644
--- a/arch/blackfin/mach-bf537/include/mach/bfin_serial_5xx.h
+++ b/arch/blackfin/mach-bf537/include/mach/bfin_serial_5xx.h
@@ -78,6 +78,9 @@
78# define CONFIG_UART1_RTS_PIN -1 78# define CONFIG_UART1_RTS_PIN -1
79# endif 79# endif
80#endif 80#endif
81
82#define BFIN_UART_TX_FIFO_SIZE 2
83
81/* 84/*
82 * The pin configuration is different from schematic 85 * The pin configuration is different from schematic
83 */ 86 */
@@ -119,7 +122,6 @@ static inline void UART_CLEAR_LSR(struct bfin_serial_port *uart)
119 bfin_write16(uart->port.membase + OFFSET_LSR, -1); 122 bfin_write16(uart->port.membase + OFFSET_LSR, -1);
120} 123}
121 124
122struct bfin_serial_port bfin_serial_ports[BFIN_UART_NR_PORTS];
123struct bfin_serial_res { 125struct bfin_serial_res {
124 unsigned long uart_base_addr; 126 unsigned long uart_base_addr;
125 int uart_irq; 127 int uart_irq;
@@ -164,8 +166,6 @@ struct bfin_serial_res bfin_serial_resource[] = {
164#endif 166#endif
165}; 167};
166 168
167int nr_ports = ARRAY_SIZE(bfin_serial_resource);
168
169#define DRIVER_NAME "bfin-uart" 169#define DRIVER_NAME "bfin-uart"
170 170
171static void bfin_serial_hw_init(struct bfin_serial_port *uart) 171static void bfin_serial_hw_init(struct bfin_serial_port *uart)
diff --git a/arch/blackfin/mach-bf548/include/mach/bfin_serial_5xx.h b/arch/blackfin/mach-bf548/include/mach/bfin_serial_5xx.h
index 5e29446a8e03..e4cf35e7ab9f 100644
--- a/arch/blackfin/mach-bf548/include/mach/bfin_serial_5xx.h
+++ b/arch/blackfin/mach-bf548/include/mach/bfin_serial_5xx.h
@@ -82,6 +82,9 @@
82# define CONFIG_UART1_RTS_PIN -1 82# define CONFIG_UART1_RTS_PIN -1
83# endif 83# endif
84#endif 84#endif
85
86#define BFIN_UART_TX_FIFO_SIZE 2
87
85/* 88/*
86 * The pin configuration is different from schematic 89 * The pin configuration is different from schematic
87 */ 90 */
@@ -105,7 +108,6 @@ struct bfin_serial_port {
105#endif 108#endif
106}; 109};
107 110
108struct bfin_serial_port bfin_serial_ports[BFIN_UART_NR_PORTS];
109struct bfin_serial_res { 111struct bfin_serial_res {
110 unsigned long uart_base_addr; 112 unsigned long uart_base_addr;
111 int uart_irq; 113 int uart_irq;
@@ -170,8 +172,6 @@ struct bfin_serial_res bfin_serial_resource[] = {
170#endif 172#endif
171}; 173};
172 174
173int nr_ports = ARRAY_SIZE(bfin_serial_resource);
174
175#define DRIVER_NAME "bfin-uart" 175#define DRIVER_NAME "bfin-uart"
176 176
177static void bfin_serial_hw_init(struct bfin_serial_port *uart) 177static void bfin_serial_hw_init(struct bfin_serial_port *uart)
diff --git a/arch/blackfin/mach-bf561/include/mach/bfin_serial_5xx.h b/arch/blackfin/mach-bf561/include/mach/bfin_serial_5xx.h
index 8aa02780e642..e0ce0c1843d4 100644
--- a/arch/blackfin/mach-bf561/include/mach/bfin_serial_5xx.h
+++ b/arch/blackfin/mach-bf561/include/mach/bfin_serial_5xx.h
@@ -69,6 +69,8 @@
69# endif 69# endif
70#endif 70#endif
71 71
72#define BFIN_UART_TX_FIFO_SIZE 2
73
72struct bfin_serial_port { 74struct bfin_serial_port {
73 struct uart_port port; 75 struct uart_port port;
74 unsigned int old_status; 76 unsigned int old_status;
@@ -111,7 +113,6 @@ static inline void UART_CLEAR_LSR(struct bfin_serial_port *uart)
111 bfin_write16(uart->port.membase + OFFSET_LSR, -1); 113 bfin_write16(uart->port.membase + OFFSET_LSR, -1);
112} 114}
113 115
114struct bfin_serial_port bfin_serial_ports[BFIN_UART_NR_PORTS];
115struct bfin_serial_res { 116struct bfin_serial_res {
116 unsigned long uart_base_addr; 117 unsigned long uart_base_addr;
117 int uart_irq; 118 int uart_irq;
@@ -142,7 +143,6 @@ struct bfin_serial_res bfin_serial_resource[] = {
142 143
143#define DRIVER_NAME "bfin-uart" 144#define DRIVER_NAME "bfin-uart"
144 145
145int nr_ports = BFIN_UART_NR_PORTS;
146static void bfin_serial_hw_init(struct bfin_serial_port *uart) 146static void bfin_serial_hw_init(struct bfin_serial_port *uart)
147{ 147{
148 148
diff --git a/arch/cris/arch-v10/boot/tools/build.c b/arch/cris/arch-v10/boot/tools/build.c
index 2f9bbb26d603..c8adef364160 100644
--- a/arch/cris/arch-v10/boot/tools/build.c
+++ b/arch/cris/arch-v10/boot/tools/build.c
@@ -30,7 +30,6 @@
30#include <sys/sysmacros.h> 30#include <sys/sysmacros.h>
31#include <unistd.h> /* contains read/write */ 31#include <unistd.h> /* contains read/write */
32#include <fcntl.h> 32#include <fcntl.h>
33#include <linux/a.out.h>
34#include <errno.h> 33#include <errno.h>
35 34
36#define MINIX_HEADER 32 35#define MINIX_HEADER 32
diff --git a/arch/h8300/Kconfig b/arch/h8300/Kconfig
index 396ab059efa3..107cb5bb9f39 100644
--- a/arch/h8300/Kconfig
+++ b/arch/h8300/Kconfig
@@ -66,9 +66,6 @@ config TIME_LOW_RES
66 bool 66 bool
67 default y 67 default y
68 68
69config ARCH_SUPPORTS_AOUT
70 def_bool y
71
72config NO_IOPORT 69config NO_IOPORT
73 def_bool y 70 def_bool y
74 71
diff --git a/arch/h8300/include/asm/a.out.h b/arch/h8300/include/asm/a.out.h
deleted file mode 100644
index ded780f0a492..000000000000
--- a/arch/h8300/include/asm/a.out.h
+++ /dev/null
@@ -1,20 +0,0 @@
1#ifndef __H8300_A_OUT_H__
2#define __H8300_A_OUT_H__
3
4struct exec
5{
6 unsigned long a_info; /* Use macros N_MAGIC, etc for access */
7 unsigned a_text; /* length of text, in bytes */
8 unsigned a_data; /* length of data, in bytes */
9 unsigned a_bss; /* length of uninitialized data area for file, in bytes */
10 unsigned a_syms; /* length of symbol table data in file, in bytes */
11 unsigned a_entry; /* start address */
12 unsigned a_trsize; /* length of relocation info for text, in bytes */
13 unsigned a_drsize; /* length of relocation info for data, in bytes */
14};
15
16#define N_TRSIZE(a) ((a).a_trsize)
17#define N_DRSIZE(a) ((a).a_drsize)
18#define N_SYMSIZE(a) ((a).a_syms)
19
20#endif /* __H8300_A_OUT_H__ */
diff --git a/arch/h8300/kernel/process.c b/arch/h8300/kernel/process.c
index dfbe7ab9ffe2..a8ef654a5a0b 100644
--- a/arch/h8300/kernel/process.c
+++ b/arch/h8300/kernel/process.c
@@ -34,7 +34,6 @@
34#include <linux/ptrace.h> 34#include <linux/ptrace.h>
35#include <linux/slab.h> 35#include <linux/slab.h>
36#include <linux/user.h> 36#include <linux/user.h>
37#include <linux/a.out.h>
38#include <linux/interrupt.h> 37#include <linux/interrupt.h>
39#include <linux/reboot.h> 38#include <linux/reboot.h>
40#include <linux/fs.h> 39#include <linux/fs.h>
diff --git a/arch/ia64/include/asm/a.out.h b/arch/ia64/include/asm/a.out.h
deleted file mode 100644
index 193dcfb67596..000000000000
--- a/arch/ia64/include/asm/a.out.h
+++ /dev/null
@@ -1,32 +0,0 @@
1#ifndef _ASM_IA64_A_OUT_H
2#define _ASM_IA64_A_OUT_H
3
4/*
5 * No a.out format has been (or should be) defined so this file is
6 * just a dummy that allows us to get binfmt_elf compiled. It
7 * probably would be better to clean up binfmt_elf.c so it does not
8 * necessarily depend on there being a.out support.
9 *
10 * Modified 1998-2002
11 * David Mosberger-Tang <davidm@hpl.hp.com>, Hewlett-Packard Co.
12 */
13
14#include <linux/types.h>
15
16struct exec {
17 unsigned long a_info;
18 unsigned long a_text;
19 unsigned long a_data;
20 unsigned long a_bss;
21 unsigned long a_entry;
22};
23
24#define N_TXTADDR(x) 0
25#define N_DATADDR(x) 0
26#define N_BSSADDR(x) 0
27#define N_DRSIZE(x) 0
28#define N_TRSIZE(x) 0
29#define N_SYMSIZE(x) 0
30#define N_TXTOFF(x) 0
31
32#endif /* _ASM_IA64_A_OUT_H */
diff --git a/arch/ia64/include/asm/statfs.h b/arch/ia64/include/asm/statfs.h
index 811097974f31..1e589669de56 100644
--- a/arch/ia64/include/asm/statfs.h
+++ b/arch/ia64/include/asm/statfs.h
@@ -8,55 +8,13 @@
8 * David Mosberger-Tang <davidm@hpl.hp.com>, Hewlett-Packard Co 8 * David Mosberger-Tang <davidm@hpl.hp.com>, Hewlett-Packard Co
9 */ 9 */
10 10
11#ifndef __KERNEL_STRICT_NAMES
12# include <linux/types.h>
13typedef __kernel_fsid_t fsid_t;
14#endif
15
16/* 11/*
17 * This is ugly --- we're already 64-bit, so just duplicate the definitions 12 * We need compat_statfs64 to be packed, because the i386 ABI won't
13 * add padding at the end to bring it to a multiple of 8 bytes, but
14 * the IA64 ABI will.
18 */ 15 */
19struct statfs { 16#define ARCH_PACK_COMPAT_STATFS64 __attribute__((packed,aligned(4)))
20 long f_type;
21 long f_bsize;
22 long f_blocks;
23 long f_bfree;
24 long f_bavail;
25 long f_files;
26 long f_ffree;
27 __kernel_fsid_t f_fsid;
28 long f_namelen;
29 long f_frsize;
30 long f_spare[5];
31};
32
33
34struct statfs64 {
35 long f_type;
36 long f_bsize;
37 long f_blocks;
38 long f_bfree;
39 long f_bavail;
40 long f_files;
41 long f_ffree;
42 __kernel_fsid_t f_fsid;
43 long f_namelen;
44 long f_frsize;
45 long f_spare[5];
46};
47 17
48struct compat_statfs64 { 18#include <asm-generic/statfs.h>
49 __u32 f_type;
50 __u32 f_bsize;
51 __u64 f_blocks;
52 __u64 f_bfree;
53 __u64 f_bavail;
54 __u64 f_files;
55 __u64 f_ffree;
56 __kernel_fsid_t f_fsid;
57 __u32 f_namelen;
58 __u32 f_frsize;
59 __u32 f_spare[5];
60} __attribute__((packed));
61 19
62#endif /* _ASM_IA64_STATFS_H */ 20#endif /* _ASM_IA64_STATFS_H */
diff --git a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c
index 200100ea7610..f482a9098e32 100644
--- a/arch/ia64/mm/init.c
+++ b/arch/ia64/mm/init.c
@@ -21,7 +21,6 @@
21#include <linux/bitops.h> 21#include <linux/bitops.h>
22#include <linux/kexec.h> 22#include <linux/kexec.h>
23 23
24#include <asm/a.out.h>
25#include <asm/dma.h> 24#include <asm/dma.h>
26#include <asm/ia32.h> 25#include <asm/ia32.h>
27#include <asm/io.h> 26#include <asm/io.h>
diff --git a/arch/m32r/Kconfig b/arch/m32r/Kconfig
index f57113f1f892..00289c178f89 100644
--- a/arch/m32r/Kconfig
+++ b/arch/m32r/Kconfig
@@ -36,9 +36,6 @@ config NO_IOPORT
36config NO_DMA 36config NO_DMA
37 def_bool y 37 def_bool y
38 38
39config ARCH_SUPPORTS_AOUT
40 def_bool y
41
42config HZ 39config HZ
43 int 40 int
44 default 100 41 default 100
diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig
index 8c5e1de68fcb..41e5bf02e230 100644
--- a/arch/m68k/Kconfig
+++ b/arch/m68k/Kconfig
@@ -5,6 +5,7 @@
5config M68K 5config M68K
6 bool 6 bool
7 default y 7 default y
8 select HAVE_AOUT
8 select HAVE_IDE 9 select HAVE_IDE
9 10
10config MMU 11config MMU
@@ -53,9 +54,6 @@ config NO_IOPORT
53config NO_DMA 54config NO_DMA
54 def_bool SUN3 55 def_bool SUN3
55 56
56config ARCH_SUPPORTS_AOUT
57 def_bool y
58
59config HZ 57config HZ
60 int 58 int
61 default 100 59 default 100
diff --git a/arch/m68knommu/Kconfig b/arch/m68knommu/Kconfig
index 2e7515e8db98..0a8998315e5e 100644
--- a/arch/m68knommu/Kconfig
+++ b/arch/m68knommu/Kconfig
@@ -73,9 +73,6 @@ config GENERIC_CLOCKEVENTS
73config NO_IOPORT 73config NO_IOPORT
74 def_bool y 74 def_bool y
75 75
76config ARCH_SUPPORTS_AOUT
77 def_bool y
78
79source "init/Kconfig" 76source "init/Kconfig"
80 77
81menu "Processor type and features" 78menu "Processor type and features"
diff --git a/arch/m68knommu/include/asm/a.out.h b/arch/m68knommu/include/asm/a.out.h
deleted file mode 100644
index ce18ef99de04..000000000000
--- a/arch/m68knommu/include/asm/a.out.h
+++ /dev/null
@@ -1 +0,0 @@
1#include <asm-m68k/a.out.h>
diff --git a/arch/m68knommu/kernel/process.c b/arch/m68knommu/kernel/process.c
index 47502d5ec19f..3f2d7745f31e 100644
--- a/arch/m68knommu/kernel/process.c
+++ b/arch/m68knommu/kernel/process.c
@@ -25,7 +25,6 @@
25#include <linux/ptrace.h> 25#include <linux/ptrace.h>
26#include <linux/slab.h> 26#include <linux/slab.h>
27#include <linux/user.h> 27#include <linux/user.h>
28#include <linux/a.out.h>
29#include <linux/interrupt.h> 28#include <linux/interrupt.h>
30#include <linux/reboot.h> 29#include <linux/reboot.h>
31#include <linux/fs.h> 30#include <linux/fs.h>
diff --git a/arch/m68knommu/kernel/traps.c b/arch/m68knommu/kernel/traps.c
index 46f8f9d0c408..5d5d56bcd0ef 100644
--- a/arch/m68knommu/kernel/traps.c
+++ b/arch/m68knommu/kernel/traps.c
@@ -22,7 +22,6 @@
22#include <linux/mm.h> 22#include <linux/mm.h>
23#include <linux/module.h> 23#include <linux/module.h>
24#include <linux/types.h> 24#include <linux/types.h>
25#include <linux/a.out.h>
26#include <linux/user.h> 25#include <linux/user.h>
27#include <linux/string.h> 26#include <linux/string.h>
28#include <linux/linkage.h> 27#include <linux/linkage.h>
diff --git a/arch/mips/include/asm/a.out.h b/arch/mips/include/asm/a.out.h
deleted file mode 100644
index cad8371422ab..000000000000
--- a/arch/mips/include/asm/a.out.h
+++ /dev/null
@@ -1,35 +0,0 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (C) 1994 - 1999, 2003 by Ralf Baechle
7 */
8#ifndef _ASM_A_OUT_H
9#define _ASM_A_OUT_H
10
11#ifdef __KERNEL__
12
13
14#endif
15
16struct exec
17{
18 unsigned long a_info; /* Use macros N_MAGIC, etc for access */
19 unsigned a_text; /* length of text, in bytes */
20 unsigned a_data; /* length of data, in bytes */
21 unsigned a_bss; /* length of uninitialized data area for
22 file, in bytes */
23 unsigned a_syms; /* length of symbol table data in file,
24 in bytes */
25 unsigned a_entry; /* start address */
26 unsigned a_trsize; /* length of relocation info for text, in
27 bytes */
28 unsigned a_drsize; /* length of relocation info for data, in bytes */
29};
30
31#define N_TRSIZE(a) ((a).a_trsize)
32#define N_DRSIZE(a) ((a).a_drsize)
33#define N_SYMSIZE(a) ((a).a_syms)
34
35#endif /* _ASM_A_OUT_H */
diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c
index 22fc19bbe87f..ca2e4026ad20 100644
--- a/arch/mips/kernel/process.c
+++ b/arch/mips/kernel/process.c
@@ -22,7 +22,6 @@
22#include <linux/personality.h> 22#include <linux/personality.h>
23#include <linux/sys.h> 23#include <linux/sys.h>
24#include <linux/user.h> 24#include <linux/user.h>
25#include <linux/a.out.h>
26#include <linux/init.h> 25#include <linux/init.h>
27#include <linux/completion.h> 26#include <linux/completion.h>
28#include <linux/kallsyms.h> 27#include <linux/kallsyms.h>
diff --git a/arch/mips/kernel/syscall.c b/arch/mips/kernel/syscall.c
index 343015a2f418..37970d9b2186 100644
--- a/arch/mips/kernel/syscall.c
+++ b/arch/mips/kernel/syscall.c
@@ -7,7 +7,6 @@
7 * Copyright (C) 1999, 2000 Silicon Graphics, Inc. 7 * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
8 * Copyright (C) 2001 MIPS Technologies, Inc. 8 * Copyright (C) 2001 MIPS Technologies, Inc.
9 */ 9 */
10#include <linux/a.out.h>
11#include <linux/capability.h> 10#include <linux/capability.h>
12#include <linux/errno.h> 11#include <linux/errno.h>
13#include <linux/linkage.h> 12#include <linux/linkage.h>
diff --git a/arch/mn10300/Kconfig b/arch/mn10300/Kconfig
index e856218da90d..dd557c9cf001 100644
--- a/arch/mn10300/Kconfig
+++ b/arch/mn10300/Kconfig
@@ -53,9 +53,6 @@ config QUICKLIST
53config ARCH_HAS_ILOG2_U32 53config ARCH_HAS_ILOG2_U32
54 def_bool y 54 def_bool y
55 55
56config ARCH_SUPPORTS_AOUT
57 def_bool n
58
59# Use the generic interrupt handling code in kernel/irq/ 56# Use the generic interrupt handling code in kernel/irq/
60config GENERIC_HARDIRQS 57config GENERIC_HARDIRQS
61 def_bool y 58 def_bool y
diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig
index a7d4fd353c2b..8313fccced5e 100644
--- a/arch/parisc/Kconfig
+++ b/arch/parisc/Kconfig
@@ -76,9 +76,6 @@ config IRQ_PER_CPU
76 bool 76 bool
77 default y 77 default y
78 78
79config ARCH_SUPPORTS_AOUT
80 def_bool y
81
82# unless you want to implement ACPI on PA-RISC ... ;-) 79# unless you want to implement ACPI on PA-RISC ... ;-)
83config PM 80config PM
84 bool 81 bool
diff --git a/arch/powerpc/include/asm/a.out.h b/arch/powerpc/include/asm/a.out.h
deleted file mode 100644
index 89cead6b176e..000000000000
--- a/arch/powerpc/include/asm/a.out.h
+++ /dev/null
@@ -1,20 +0,0 @@
1#ifndef _ASM_POWERPC_A_OUT_H
2#define _ASM_POWERPC_A_OUT_H
3
4struct exec
5{
6 unsigned long a_info; /* Use macros N_MAGIC, etc for access */
7 unsigned a_text; /* length of text, in bytes */
8 unsigned a_data; /* length of data, in bytes */
9 unsigned a_bss; /* length of uninitialized data area for file, in bytes */
10 unsigned a_syms; /* length of symbol table data in file, in bytes */
11 unsigned a_entry; /* start address */
12 unsigned a_trsize; /* length of relocation info for text, in bytes */
13 unsigned a_drsize; /* length of relocation info for data, in bytes */
14};
15
16#define N_TRSIZE(a) ((a).a_trsize)
17#define N_DRSIZE(a) ((a).a_drsize)
18#define N_SYMSIZE(a) ((a).a_syms)
19
20#endif /* _ASM_POWERPC_A_OUT_H */
diff --git a/arch/powerpc/include/asm/statfs.h b/arch/powerpc/include/asm/statfs.h
index 67024026c10d..5244834583a4 100644
--- a/arch/powerpc/include/asm/statfs.h
+++ b/arch/powerpc/include/asm/statfs.h
@@ -1,60 +1,6 @@
1#ifndef _ASM_POWERPC_STATFS_H 1#ifndef _ASM_POWERPC_STATFS_H
2#define _ASM_POWERPC_STATFS_H 2#define _ASM_POWERPC_STATFS_H
3 3
4/* For ppc32 we just use the generic definitions, not so simple on ppc64 */
5
6#ifndef __powerpc64__
7#include <asm-generic/statfs.h> 4#include <asm-generic/statfs.h>
8#else
9
10#ifndef __KERNEL_STRICT_NAMES
11#include <linux/types.h>
12typedef __kernel_fsid_t fsid_t;
13#endif
14
15/*
16 * We're already 64-bit, so duplicate the definition
17 */
18struct statfs {
19 long f_type;
20 long f_bsize;
21 long f_blocks;
22 long f_bfree;
23 long f_bavail;
24 long f_files;
25 long f_ffree;
26 __kernel_fsid_t f_fsid;
27 long f_namelen;
28 long f_frsize;
29 long f_spare[5];
30};
31
32struct statfs64 {
33 long f_type;
34 long f_bsize;
35 long f_blocks;
36 long f_bfree;
37 long f_bavail;
38 long f_files;
39 long f_ffree;
40 __kernel_fsid_t f_fsid;
41 long f_namelen;
42 long f_frsize;
43 long f_spare[5];
44};
45 5
46struct compat_statfs64 {
47 __u32 f_type;
48 __u32 f_bsize;
49 __u64 f_blocks;
50 __u64 f_bfree;
51 __u64 f_bavail;
52 __u64 f_files;
53 __u64 f_ffree;
54 __kernel_fsid_t f_fsid;
55 __u32 f_namelen;
56 __u32 f_frsize;
57 __u32 f_spare[5];
58};
59#endif /* ! __powerpc64__ */
60#endif 6#endif
diff --git a/arch/powerpc/kernel/softemu8xx.c b/arch/powerpc/kernel/softemu8xx.c
index c906c4bf6835..23c8c5e7dc4d 100644
--- a/arch/powerpc/kernel/softemu8xx.c
+++ b/arch/powerpc/kernel/softemu8xx.c
@@ -23,7 +23,6 @@
23#include <linux/ptrace.h> 23#include <linux/ptrace.h>
24#include <linux/slab.h> 24#include <linux/slab.h>
25#include <linux/user.h> 25#include <linux/user.h>
26#include <linux/a.out.h>
27#include <linux/interrupt.h> 26#include <linux/interrupt.h>
28 27
29#include <asm/pgtable.h> 28#include <asm/pgtable.h>
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index 81ccb8dd1a54..f5def6cf5cd6 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -23,7 +23,6 @@
23#include <linux/ptrace.h> 23#include <linux/ptrace.h>
24#include <linux/slab.h> 24#include <linux/slab.h>
25#include <linux/user.h> 25#include <linux/user.h>
26#include <linux/a.out.h>
27#include <linux/interrupt.h> 26#include <linux/interrupt.h>
28#include <linux/init.h> 27#include <linux/init.h>
29#include <linux/module.h> 28#include <linux/module.h>
diff --git a/arch/powerpc/platforms/chrp/setup.c b/arch/powerpc/platforms/chrp/setup.c
index 1ba7ce5aafae..272d79a8d289 100644
--- a/arch/powerpc/platforms/chrp/setup.c
+++ b/arch/powerpc/platforms/chrp/setup.c
@@ -17,7 +17,6 @@
17#include <linux/ptrace.h> 17#include <linux/ptrace.h>
18#include <linux/slab.h> 18#include <linux/slab.h>
19#include <linux/user.h> 19#include <linux/user.h>
20#include <linux/a.out.h>
21#include <linux/tty.h> 20#include <linux/tty.h>
22#include <linux/major.h> 21#include <linux/major.h>
23#include <linux/interrupt.h> 22#include <linux/interrupt.h>
diff --git a/arch/powerpc/platforms/maple/setup.c b/arch/powerpc/platforms/maple/setup.c
index 364714757cf1..d4c61c3c9669 100644
--- a/arch/powerpc/platforms/maple/setup.c
+++ b/arch/powerpc/platforms/maple/setup.c
@@ -23,7 +23,6 @@
23#include <linux/ptrace.h> 23#include <linux/ptrace.h>
24#include <linux/slab.h> 24#include <linux/slab.h>
25#include <linux/user.h> 25#include <linux/user.h>
26#include <linux/a.out.h>
27#include <linux/tty.h> 26#include <linux/tty.h>
28#include <linux/string.h> 27#include <linux/string.h>
29#include <linux/delay.h> 28#include <linux/delay.h>
diff --git a/arch/powerpc/platforms/powermac/setup.c b/arch/powerpc/platforms/powermac/setup.c
index 88ccf3a08a9c..82c14d203d8b 100644
--- a/arch/powerpc/platforms/powermac/setup.c
+++ b/arch/powerpc/platforms/powermac/setup.c
@@ -33,7 +33,6 @@
33#include <linux/ptrace.h> 33#include <linux/ptrace.h>
34#include <linux/slab.h> 34#include <linux/slab.h>
35#include <linux/user.h> 35#include <linux/user.h>
36#include <linux/a.out.h>
37#include <linux/tty.h> 36#include <linux/tty.h>
38#include <linux/string.h> 37#include <linux/string.h>
39#include <linux/delay.h> 38#include <linux/delay.h>
diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c
index 7b01d67b4e48..ec341707e41b 100644
--- a/arch/powerpc/platforms/pseries/setup.c
+++ b/arch/powerpc/platforms/pseries/setup.c
@@ -25,7 +25,6 @@
25#include <linux/unistd.h> 25#include <linux/unistd.h>
26#include <linux/slab.h> 26#include <linux/slab.h>
27#include <linux/user.h> 27#include <linux/user.h>
28#include <linux/a.out.h>
29#include <linux/tty.h> 28#include <linux/tty.h>
30#include <linux/major.h> 29#include <linux/major.h>
31#include <linux/interrupt.h> 30#include <linux/interrupt.h>
diff --git a/arch/s390/include/asm/statfs.h b/arch/s390/include/asm/statfs.h
index 099a45579190..06cc70307ece 100644
--- a/arch/s390/include/asm/statfs.h
+++ b/arch/s390/include/asm/statfs.h
@@ -12,19 +12,16 @@
12#ifndef __s390x__ 12#ifndef __s390x__
13#include <asm-generic/statfs.h> 13#include <asm-generic/statfs.h>
14#else 14#else
15/*
16 * We can't use <asm-generic/statfs.h> because in 64-bit mode
17 * we mix ints of different sizes in our struct statfs.
18 */
15 19
16#ifndef __KERNEL_STRICT_NAMES 20#ifndef __KERNEL_STRICT_NAMES
17
18#include <linux/types.h> 21#include <linux/types.h>
19
20typedef __kernel_fsid_t fsid_t; 22typedef __kernel_fsid_t fsid_t;
21
22#endif 23#endif
23 24
24/*
25 * This is ugly -- we're already 64-bit clean, so just duplicate the
26 * definitions.
27 */
28struct statfs { 25struct statfs {
29 int f_type; 26 int f_type;
30 int f_bsize; 27 int f_bsize;
diff --git a/arch/sparc/include/asm/Kbuild b/arch/sparc/include/asm/Kbuild
index 2ba7183bc1f0..2d2769d766ec 100644
--- a/arch/sparc/include/asm/Kbuild
+++ b/arch/sparc/include/asm/Kbuild
@@ -15,8 +15,6 @@ header-y += signal_32.h
15header-y += signal_64.h 15header-y += signal_64.h
16header-y += stat_32.h 16header-y += stat_32.h
17header-y += stat_64.h 17header-y += stat_64.h
18header-y += statfs_32.h
19header-y += statfs_64.h
20header-y += unistd_32.h 18header-y += unistd_32.h
21header-y += unistd_64.h 19header-y += unistd_64.h
22 20
diff --git a/arch/sparc/include/asm/serial.h b/arch/sparc/include/asm/serial.h
new file mode 100644
index 000000000000..f90d61c28059
--- /dev/null
+++ b/arch/sparc/include/asm/serial.h
@@ -0,0 +1,6 @@
1#ifndef __SPARC_SERIAL_H
2#define __SPARC_SERIAL_H
3
4#define BASE_BAUD ( 1843200 / 16 )
5
6#endif /* __SPARC_SERIAL_H */
diff --git a/arch/sparc/include/asm/statfs.h b/arch/sparc/include/asm/statfs.h
index 5e937a73743d..55e607ad461d 100644
--- a/arch/sparc/include/asm/statfs.h
+++ b/arch/sparc/include/asm/statfs.h
@@ -1,8 +1,6 @@
1#ifndef ___ASM_SPARC_STATFS_H 1#ifndef ___ASM_SPARC_STATFS_H
2#define ___ASM_SPARC_STATFS_H 2#define ___ASM_SPARC_STATFS_H
3#if defined(__sparc__) && defined(__arch64__) 3
4#include <asm/statfs_64.h> 4#include <asm-generic/statfs.h>
5#else 5
6#include <asm/statfs_32.h>
7#endif
8#endif 6#endif
diff --git a/arch/sparc/include/asm/statfs_32.h b/arch/sparc/include/asm/statfs_32.h
deleted file mode 100644
index 304520fa8863..000000000000
--- a/arch/sparc/include/asm/statfs_32.h
+++ /dev/null
@@ -1,6 +0,0 @@
1#ifndef _SPARC_STATFS_H
2#define _SPARC_STATFS_H
3
4#include <asm-generic/statfs.h>
5
6#endif
diff --git a/arch/sparc/include/asm/statfs_64.h b/arch/sparc/include/asm/statfs_64.h
deleted file mode 100644
index 79b3c890a5fa..000000000000
--- a/arch/sparc/include/asm/statfs_64.h
+++ /dev/null
@@ -1,54 +0,0 @@
1#ifndef _SPARC64_STATFS_H
2#define _SPARC64_STATFS_H
3
4#ifndef __KERNEL_STRICT_NAMES
5
6#include <linux/types.h>
7
8typedef __kernel_fsid_t fsid_t;
9
10#endif
11
12struct statfs {
13 long f_type;
14 long f_bsize;
15 long f_blocks;
16 long f_bfree;
17 long f_bavail;
18 long f_files;
19 long f_ffree;
20 __kernel_fsid_t f_fsid;
21 long f_namelen;
22 long f_frsize;
23 long f_spare[5];
24};
25
26struct statfs64 {
27 long f_type;
28 long f_bsize;
29 long f_blocks;
30 long f_bfree;
31 long f_bavail;
32 long f_files;
33 long f_ffree;
34 __kernel_fsid_t f_fsid;
35 long f_namelen;
36 long f_frsize;
37 long f_spare[5];
38};
39
40struct compat_statfs64 {
41 __u32 f_type;
42 __u32 f_bsize;
43 __u64 f_blocks;
44 __u64 f_bfree;
45 __u64 f_bavail;
46 __u64 f_files;
47 __u64 f_ffree;
48 __kernel_fsid_t f_fsid;
49 __u32 f_namelen;
50 __u32 f_frsize;
51 __u32 f_spare[5];
52};
53
54#endif
diff --git a/arch/um/Kconfig.i386 b/arch/um/Kconfig.i386
index e09edfa560da..1f57c113df6d 100644
--- a/arch/um/Kconfig.i386
+++ b/arch/um/Kconfig.i386
@@ -9,8 +9,9 @@ config UML_X86
9 default y 9 default y
10 10
11config X86_32 11config X86_32
12 bool 12 bool
13 default y 13 default y
14 select HAVE_AOUT
14 15
15config RWSEM_XCHGADD_ALGORITHM 16config RWSEM_XCHGADD_ALGORITHM
16 def_bool y 17 def_bool y
@@ -42,6 +43,3 @@ config ARCH_REUSE_HOST_VSYSCALL_AREA
42config GENERIC_HWEIGHT 43config GENERIC_HWEIGHT
43 bool 44 bool
44 default y 45 default y
45
46config ARCH_SUPPORTS_AOUT
47 def_bool y
diff --git a/arch/um/Kconfig.x86_64 b/arch/um/Kconfig.x86_64
index 5696e7b374b3..40b3407cfe16 100644
--- a/arch/um/Kconfig.x86_64
+++ b/arch/um/Kconfig.x86_64
@@ -37,6 +37,3 @@ config SMP_BROKEN
37config GENERIC_HWEIGHT 37config GENERIC_HWEIGHT
38 bool 38 bool
39 default y 39 default y
40
41config ARCH_SUPPORTS_AOUT
42 def_bool y
diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c
index d741f35d7b3a..14a102e877d6 100644
--- a/arch/um/drivers/line.c
+++ b/arch/um/drivers/line.c
@@ -275,6 +275,8 @@ int line_ioctl(struct tty_struct *tty, struct file * file,
275 case TIOCGLTC: 275 case TIOCGLTC:
276 case TIOCSLTC: 276 case TIOCSLTC:
277#endif 277#endif
278 /* Note: these are out of date as we now have TCGETS2 etc but this
279 whole lot should probably go away */
278 case TCGETS: 280 case TCGETS:
279 case TCSETSF: 281 case TCSETSF:
280 case TCSETSW: 282 case TCSETSW:
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index fc8351f374fd..f65c2744d573 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -18,6 +18,7 @@ config X86_64
18### Arch settings 18### Arch settings
19config X86 19config X86
20 def_bool y 20 def_bool y
21 select HAVE_AOUT if X86_32
21 select HAVE_UNSTABLE_SCHED_CLOCK 22 select HAVE_UNSTABLE_SCHED_CLOCK
22 select HAVE_IDE 23 select HAVE_IDE
23 select HAVE_OPROFILE 24 select HAVE_OPROFILE
@@ -152,9 +153,6 @@ config AUDIT_ARCH
152 bool 153 bool
153 default X86_64 154 default X86_64
154 155
155config ARCH_SUPPORTS_AOUT
156 def_bool y
157
158config ARCH_SUPPORTS_OPTIMIZED_INLINING 156config ARCH_SUPPORTS_OPTIMIZED_INLINING
159 def_bool y 157 def_bool y
160 158
@@ -1885,7 +1883,7 @@ config IA32_EMULATION
1885 1883
1886config IA32_AOUT 1884config IA32_AOUT
1887 tristate "IA32 a.out support" 1885 tristate "IA32 a.out support"
1888 depends on IA32_EMULATION && ARCH_SUPPORTS_AOUT 1886 depends on IA32_EMULATION
1889 help 1887 help
1890 Support old a.out binaries in the 32bit emulation. 1888 Support old a.out binaries in the 32bit emulation.
1891 1889
diff --git a/arch/x86/Kconfig.cpu b/arch/x86/Kconfig.cpu
index c5f101360520..0b7c4a3f0651 100644
--- a/arch/x86/Kconfig.cpu
+++ b/arch/x86/Kconfig.cpu
@@ -38,8 +38,7 @@ config M386
38 - "Crusoe" for the Transmeta Crusoe series. 38 - "Crusoe" for the Transmeta Crusoe series.
39 - "Efficeon" for the Transmeta Efficeon series. 39 - "Efficeon" for the Transmeta Efficeon series.
40 - "Winchip-C6" for original IDT Winchip. 40 - "Winchip-C6" for original IDT Winchip.
41 - "Winchip-2" for IDT Winchip 2. 41 - "Winchip-2" for IDT Winchips with 3dNow! capabilities.
42 - "Winchip-2A" for IDT Winchips with 3dNow! capabilities.
43 - "GeodeGX1" for Geode GX1 (Cyrix MediaGX). 42 - "GeodeGX1" for Geode GX1 (Cyrix MediaGX).
44 - "Geode GX/LX" For AMD Geode GX and LX processors. 43 - "Geode GX/LX" For AMD Geode GX and LX processors.
45 - "CyrixIII/VIA C3" for VIA Cyrix III or VIA C3. 44 - "CyrixIII/VIA C3" for VIA Cyrix III or VIA C3.
@@ -194,19 +193,11 @@ config MWINCHIPC6
194 treat this chip as a 586TSC with some extended instructions 193 treat this chip as a 586TSC with some extended instructions
195 and alignment requirements. 194 and alignment requirements.
196 195
197config MWINCHIP2
198 bool "Winchip-2"
199 depends on X86_32
200 help
201 Select this for an IDT Winchip-2. Linux and GCC
202 treat this chip as a 586TSC with some extended instructions
203 and alignment requirements.
204
205config MWINCHIP3D 196config MWINCHIP3D
206 bool "Winchip-2A/Winchip-3" 197 bool "Winchip-2/Winchip-2A/Winchip-3"
207 depends on X86_32 198 depends on X86_32
208 help 199 help
209 Select this for an IDT Winchip-2A or 3. Linux and GCC 200 Select this for an IDT Winchip-2, 2A or 3. Linux and GCC
210 treat this chip as a 586TSC with some extended instructions 201 treat this chip as a 586TSC with some extended instructions
211 and alignment requirements. Also enable out of order memory 202 and alignment requirements. Also enable out of order memory
212 stores for this CPU, which can increase performance of some 203 stores for this CPU, which can increase performance of some
@@ -318,7 +309,7 @@ config X86_L1_CACHE_SHIFT
318 int 309 int
319 default "7" if MPENTIUM4 || X86_GENERIC || GENERIC_CPU || MPSC 310 default "7" if MPENTIUM4 || X86_GENERIC || GENERIC_CPU || MPSC
320 default "4" if X86_ELAN || M486 || M386 || MGEODEGX1 311 default "4" if X86_ELAN || M486 || M386 || MGEODEGX1
321 default "5" if MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCRUSOE || MEFFICEON || MCYRIXIII || MK6 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || MVIAC3_2 || MGEODE_LX 312 default "5" if MWINCHIP3D || MWINCHIPC6 || MCRUSOE || MEFFICEON || MCYRIXIII || MK6 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || MVIAC3_2 || MGEODE_LX
322 default "6" if MK7 || MK8 || MPENTIUMM || MCORE2 || MVIAC7 313 default "6" if MK7 || MK8 || MPENTIUMM || MCORE2 || MVIAC7
323 314
324config X86_XADD 315config X86_XADD
@@ -360,7 +351,7 @@ config X86_POPAD_OK
360 351
361config X86_ALIGNMENT_16 352config X86_ALIGNMENT_16
362 def_bool y 353 def_bool y
363 depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK6 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODEGX1 354 depends on MWINCHIP3D || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK6 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODEGX1
364 355
365config X86_INTEL_USERCOPY 356config X86_INTEL_USERCOPY
366 def_bool y 357 def_bool y
@@ -368,7 +359,7 @@ config X86_INTEL_USERCOPY
368 359
369config X86_USE_PPRO_CHECKSUM 360config X86_USE_PPRO_CHECKSUM
370 def_bool y 361 def_bool y
371 depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MK8 || MVIAC3_2 || MEFFICEON || MGEODE_LX || MCORE2 362 depends on MWINCHIP3D || MWINCHIPC6 || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MK8 || MVIAC3_2 || MEFFICEON || MGEODE_LX || MCORE2
372 363
373config X86_USE_3DNOW 364config X86_USE_3DNOW
374 def_bool y 365 def_bool y
@@ -376,7 +367,7 @@ config X86_USE_3DNOW
376 367
377config X86_OOSTORE 368config X86_OOSTORE
378 def_bool y 369 def_bool y
379 depends on (MWINCHIP3D || MWINCHIP2 || MWINCHIPC6) && MTRR 370 depends on (MWINCHIP3D || MWINCHIPC6) && MTRR
380 371
381# 372#
382# P6_NOPs are a relatively minor optimization that require a family >= 373# P6_NOPs are a relatively minor optimization that require a family >=
@@ -396,7 +387,7 @@ config X86_P6_NOP
396 387
397config X86_TSC 388config X86_TSC
398 def_bool y 389 def_bool y
399 depends on ((MWINCHIP3D || MWINCHIP2 || MCRUSOE || MEFFICEON || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || MK8 || MVIAC3_2 || MVIAC7 || MGEODEGX1 || MGEODE_LX || MCORE2) && !X86_NUMAQ) || X86_64 390 depends on ((MWINCHIP3D || MCRUSOE || MEFFICEON || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || MK8 || MVIAC3_2 || MVIAC7 || MGEODEGX1 || MGEODE_LX || MCORE2) && !X86_NUMAQ) || X86_64
400 391
401config X86_CMPXCHG64 392config X86_CMPXCHG64
402 def_bool y 393 def_bool y
@@ -406,7 +397,7 @@ config X86_CMPXCHG64
406# generates cmov. 397# generates cmov.
407config X86_CMOV 398config X86_CMOV
408 def_bool y 399 def_bool y
409 depends on (MK7 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MVIAC3_2 || MVIAC7 || X86_64) 400 depends on (MK8 || MK7 || MCORE2 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MVIAC3_2 || MVIAC7 || MCRUSOE || MEFFICEON || X86_64)
410 401
411config X86_MINIMUM_CPU_FAMILY 402config X86_MINIMUM_CPU_FAMILY
412 int 403 int
@@ -417,7 +408,7 @@ config X86_MINIMUM_CPU_FAMILY
417 408
418config X86_DEBUGCTLMSR 409config X86_DEBUGCTLMSR
419 def_bool y 410 def_bool y
420 depends on !(MK6 || MWINCHIPC6 || MWINCHIP2 || MWINCHIP3D || MCYRIXIII || M586MMX || M586TSC || M586 || M486 || M386) 411 depends on !(MK6 || MWINCHIPC6 || MWINCHIP3D || MCYRIXIII || M586MMX || M586TSC || M586 || M486 || M386)
421 412
422menuconfig PROCESSOR_SELECT 413menuconfig PROCESSOR_SELECT
423 bool "Supported processor vendors" if EMBEDDED 414 bool "Supported processor vendors" if EMBEDDED
diff --git a/arch/x86/Makefile_32.cpu b/arch/x86/Makefile_32.cpu
index b72b4f753113..80177ec052f0 100644
--- a/arch/x86/Makefile_32.cpu
+++ b/arch/x86/Makefile_32.cpu
@@ -28,7 +28,6 @@ cflags-$(CONFIG_MK8) += $(call cc-option,-march=k8,-march=athlon)
28cflags-$(CONFIG_MCRUSOE) += -march=i686 $(align)-functions=0 $(align)-jumps=0 $(align)-loops=0 28cflags-$(CONFIG_MCRUSOE) += -march=i686 $(align)-functions=0 $(align)-jumps=0 $(align)-loops=0
29cflags-$(CONFIG_MEFFICEON) += -march=i686 $(call tune,pentium3) $(align)-functions=0 $(align)-jumps=0 $(align)-loops=0 29cflags-$(CONFIG_MEFFICEON) += -march=i686 $(call tune,pentium3) $(align)-functions=0 $(align)-jumps=0 $(align)-loops=0
30cflags-$(CONFIG_MWINCHIPC6) += $(call cc-option,-march=winchip-c6,-march=i586) 30cflags-$(CONFIG_MWINCHIPC6) += $(call cc-option,-march=winchip-c6,-march=i586)
31cflags-$(CONFIG_MWINCHIP2) += $(call cc-option,-march=winchip2,-march=i586)
32cflags-$(CONFIG_MWINCHIP3D) += $(call cc-option,-march=winchip2,-march=i586) 31cflags-$(CONFIG_MWINCHIP3D) += $(call cc-option,-march=winchip2,-march=i586)
33cflags-$(CONFIG_MCYRIXIII) += $(call cc-option,-march=c3,-march=i486) $(align)-functions=0 $(align)-jumps=0 $(align)-loops=0 32cflags-$(CONFIG_MCYRIXIII) += $(call cc-option,-march=c3,-march=i486) $(align)-functions=0 $(align)-jumps=0 $(align)-loops=0
34cflags-$(CONFIG_MVIAC3_2) += $(call cc-option,-march=c3-2,-march=i686) 33cflags-$(CONFIG_MVIAC3_2) += $(call cc-option,-march=c3-2,-march=i686)
diff --git a/arch/x86/configs/i386_defconfig b/arch/x86/configs/i386_defconfig
index ca226ca31288..52d0359719d7 100644
--- a/arch/x86/configs/i386_defconfig
+++ b/arch/x86/configs/i386_defconfig
@@ -213,7 +213,6 @@ CONFIG_M686=y
213# CONFIG_MCRUSOE is not set 213# CONFIG_MCRUSOE is not set
214# CONFIG_MEFFICEON is not set 214# CONFIG_MEFFICEON is not set
215# CONFIG_MWINCHIPC6 is not set 215# CONFIG_MWINCHIPC6 is not set
216# CONFIG_MWINCHIP2 is not set
217# CONFIG_MWINCHIP3D is not set 216# CONFIG_MWINCHIP3D is not set
218# CONFIG_MGEODEGX1 is not set 217# CONFIG_MGEODEGX1 is not set
219# CONFIG_MGEODE_LX is not set 218# CONFIG_MGEODE_LX is not set
diff --git a/arch/x86/configs/x86_64_defconfig b/arch/x86/configs/x86_64_defconfig
index 2c4b1c771e28..f0a03d7a7d63 100644
--- a/arch/x86/configs/x86_64_defconfig
+++ b/arch/x86/configs/x86_64_defconfig
@@ -210,7 +210,6 @@ CONFIG_X86_PC=y
210# CONFIG_MCRUSOE is not set 210# CONFIG_MCRUSOE is not set
211# CONFIG_MEFFICEON is not set 211# CONFIG_MEFFICEON is not set
212# CONFIG_MWINCHIPC6 is not set 212# CONFIG_MWINCHIPC6 is not set
213# CONFIG_MWINCHIP2 is not set
214# CONFIG_MWINCHIP3D is not set 213# CONFIG_MWINCHIP3D is not set
215# CONFIG_MGEODEGX1 is not set 214# CONFIG_MGEODEGX1 is not set
216# CONFIG_MGEODE_LX is not set 215# CONFIG_MGEODE_LX is not set
diff --git a/arch/x86/ia32/ia32entry.S b/arch/x86/ia32/ia32entry.S
index ffc1bb4fed7d..eb4314768bf7 100644
--- a/arch/x86/ia32/ia32entry.S
+++ b/arch/x86/ia32/ia32entry.S
@@ -39,11 +39,11 @@
39 .endm 39 .endm
40 40
41 /* clobbers %eax */ 41 /* clobbers %eax */
42 .macro CLEAR_RREGS 42 .macro CLEAR_RREGS _r9=rax
43 xorl %eax,%eax 43 xorl %eax,%eax
44 movq %rax,R11(%rsp) 44 movq %rax,R11(%rsp)
45 movq %rax,R10(%rsp) 45 movq %rax,R10(%rsp)
46 movq %rax,R9(%rsp) 46 movq %\_r9,R9(%rsp)
47 movq %rax,R8(%rsp) 47 movq %rax,R8(%rsp)
48 .endm 48 .endm
49 49
@@ -52,11 +52,10 @@
52 * We don't reload %eax because syscall_trace_enter() returned 52 * We don't reload %eax because syscall_trace_enter() returned
53 * the value it wants us to use in the table lookup. 53 * the value it wants us to use in the table lookup.
54 */ 54 */
55 .macro LOAD_ARGS32 offset 55 .macro LOAD_ARGS32 offset, _r9=0
56 movl \offset(%rsp),%r11d 56 .if \_r9
57 movl \offset+8(%rsp),%r10d
58 movl \offset+16(%rsp),%r9d 57 movl \offset+16(%rsp),%r9d
59 movl \offset+24(%rsp),%r8d 58 .endif
60 movl \offset+40(%rsp),%ecx 59 movl \offset+40(%rsp),%ecx
61 movl \offset+48(%rsp),%edx 60 movl \offset+48(%rsp),%edx
62 movl \offset+56(%rsp),%esi 61 movl \offset+56(%rsp),%esi
@@ -145,7 +144,7 @@ ENTRY(ia32_sysenter_target)
145 SAVE_ARGS 0,0,1 144 SAVE_ARGS 0,0,1
146 /* no need to do an access_ok check here because rbp has been 145 /* no need to do an access_ok check here because rbp has been
147 32bit zero extended */ 146 32bit zero extended */
1481: movl (%rbp),%r9d 1471: movl (%rbp),%ebp
149 .section __ex_table,"a" 148 .section __ex_table,"a"
150 .quad 1b,ia32_badarg 149 .quad 1b,ia32_badarg
151 .previous 150 .previous
@@ -157,7 +156,7 @@ ENTRY(ia32_sysenter_target)
157 cmpl $(IA32_NR_syscalls-1),%eax 156 cmpl $(IA32_NR_syscalls-1),%eax
158 ja ia32_badsys 157 ja ia32_badsys
159sysenter_do_call: 158sysenter_do_call:
160 IA32_ARG_FIXUP 1 159 IA32_ARG_FIXUP
161sysenter_dispatch: 160sysenter_dispatch:
162 call *ia32_sys_call_table(,%rax,8) 161 call *ia32_sys_call_table(,%rax,8)
163 movq %rax,RAX-ARGOFFSET(%rsp) 162 movq %rax,RAX-ARGOFFSET(%rsp)
@@ -234,20 +233,17 @@ sysexit_audit:
234#endif 233#endif
235 234
236sysenter_tracesys: 235sysenter_tracesys:
237 xchgl %r9d,%ebp
238#ifdef CONFIG_AUDITSYSCALL 236#ifdef CONFIG_AUDITSYSCALL
239 testl $(_TIF_WORK_SYSCALL_ENTRY & ~_TIF_SYSCALL_AUDIT),TI_flags(%r10) 237 testl $(_TIF_WORK_SYSCALL_ENTRY & ~_TIF_SYSCALL_AUDIT),TI_flags(%r10)
240 jz sysenter_auditsys 238 jz sysenter_auditsys
241#endif 239#endif
242 SAVE_REST 240 SAVE_REST
243 CLEAR_RREGS 241 CLEAR_RREGS
244 movq %r9,R9(%rsp)
245 movq $-ENOSYS,RAX(%rsp)/* ptrace can change this for a bad syscall */ 242 movq $-ENOSYS,RAX(%rsp)/* ptrace can change this for a bad syscall */
246 movq %rsp,%rdi /* &pt_regs -> arg1 */ 243 movq %rsp,%rdi /* &pt_regs -> arg1 */
247 call syscall_trace_enter 244 call syscall_trace_enter
248 LOAD_ARGS32 ARGOFFSET /* reload args from stack in case ptrace changed it */ 245 LOAD_ARGS32 ARGOFFSET /* reload args from stack in case ptrace changed it */
249 RESTORE_REST 246 RESTORE_REST
250 xchgl %ebp,%r9d
251 cmpl $(IA32_NR_syscalls-1),%eax 247 cmpl $(IA32_NR_syscalls-1),%eax
252 ja int_ret_from_sys_call /* sysenter_tracesys has set RAX(%rsp) */ 248 ja int_ret_from_sys_call /* sysenter_tracesys has set RAX(%rsp) */
253 jmp sysenter_do_call 249 jmp sysenter_do_call
@@ -314,9 +310,9 @@ ENTRY(ia32_cstar_target)
314 testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%r10) 310 testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%r10)
315 CFI_REMEMBER_STATE 311 CFI_REMEMBER_STATE
316 jnz cstar_tracesys 312 jnz cstar_tracesys
317cstar_do_call:
318 cmpl $IA32_NR_syscalls-1,%eax 313 cmpl $IA32_NR_syscalls-1,%eax
319 ja ia32_badsys 314 ja ia32_badsys
315cstar_do_call:
320 IA32_ARG_FIXUP 1 316 IA32_ARG_FIXUP 1
321cstar_dispatch: 317cstar_dispatch:
322 call *ia32_sys_call_table(,%rax,8) 318 call *ia32_sys_call_table(,%rax,8)
@@ -357,15 +353,13 @@ cstar_tracesys:
357#endif 353#endif
358 xchgl %r9d,%ebp 354 xchgl %r9d,%ebp
359 SAVE_REST 355 SAVE_REST
360 CLEAR_RREGS 356 CLEAR_RREGS r9
361 movq %r9,R9(%rsp)
362 movq $-ENOSYS,RAX(%rsp) /* ptrace can change this for a bad syscall */ 357 movq $-ENOSYS,RAX(%rsp) /* ptrace can change this for a bad syscall */
363 movq %rsp,%rdi /* &pt_regs -> arg1 */ 358 movq %rsp,%rdi /* &pt_regs -> arg1 */
364 call syscall_trace_enter 359 call syscall_trace_enter
365 LOAD_ARGS32 ARGOFFSET /* reload args from stack in case ptrace changed it */ 360 LOAD_ARGS32 ARGOFFSET, 1 /* reload args from stack in case ptrace changed it */
366 RESTORE_REST 361 RESTORE_REST
367 xchgl %ebp,%r9d 362 xchgl %ebp,%r9d
368 movl RSP-ARGOFFSET(%rsp), %r8d
369 cmpl $(IA32_NR_syscalls-1),%eax 363 cmpl $(IA32_NR_syscalls-1),%eax
370 ja int_ret_from_sys_call /* cstar_tracesys has set RAX(%rsp) */ 364 ja int_ret_from_sys_call /* cstar_tracesys has set RAX(%rsp) */
371 jmp cstar_do_call 365 jmp cstar_do_call
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
index 5098585f87ce..0d41f0343dc0 100644
--- a/arch/x86/kernel/Makefile
+++ b/arch/x86/kernel/Makefile
@@ -23,7 +23,7 @@ CFLAGS_hpet.o := $(nostackp)
23CFLAGS_tsc.o := $(nostackp) 23CFLAGS_tsc.o := $(nostackp)
24 24
25obj-y := process_$(BITS).o signal_$(BITS).o entry_$(BITS).o 25obj-y := process_$(BITS).o signal_$(BITS).o entry_$(BITS).o
26obj-y += traps_$(BITS).o irq_$(BITS).o 26obj-y += traps.o irq_$(BITS).o dumpstack_$(BITS).o
27obj-y += time_$(BITS).o ioport.o ldt.o 27obj-y += time_$(BITS).o ioport.o ldt.o
28obj-y += setup.o i8259.o irqinit_$(BITS).o setup_percpu.o 28obj-y += setup.o i8259.o irqinit_$(BITS).o setup_percpu.o
29obj-$(CONFIG_X86_VISWS) += visws_quirks.o 29obj-$(CONFIG_X86_VISWS) += visws_quirks.o
diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c
index fb04e49776ba..a84ac7b570e6 100644
--- a/arch/x86/kernel/alternative.c
+++ b/arch/x86/kernel/alternative.c
@@ -444,7 +444,7 @@ void __init alternative_instructions(void)
444 _text, _etext); 444 _text, _etext);
445 445
446 /* Only switch to UP mode if we don't immediately boot others */ 446 /* Only switch to UP mode if we don't immediately boot others */
447 if (num_possible_cpus() == 1 || setup_max_cpus <= 1) 447 if (num_present_cpus() == 1 || setup_max_cpus <= 1)
448 alternatives_smp_switch(0); 448 alternatives_smp_switch(0);
449 } 449 }
450#endif 450#endif
diff --git a/arch/x86/kernel/apic_32.c b/arch/x86/kernel/apic_32.c
index a91c57cb666a..21c831d96af3 100644
--- a/arch/x86/kernel/apic_32.c
+++ b/arch/x86/kernel/apic_32.c
@@ -295,6 +295,9 @@ static void __setup_APIC_LVTT(unsigned int clocks, int oneshot, int irqen)
295 * 295 *
296 * Vector mappings are hard coded. On K8 only offset 0 (APIC500) and 296 * Vector mappings are hard coded. On K8 only offset 0 (APIC500) and
297 * MCE interrupts are supported. Thus MCE offset must be set to 0. 297 * MCE interrupts are supported. Thus MCE offset must be set to 0.
298 *
299 * If mask=1, the LVT entry does not generate interrupts while mask=0
300 * enables the vector. See also the BKDGs.
298 */ 301 */
299 302
300#define APIC_EILVT_LVTOFF_MCE 0 303#define APIC_EILVT_LVTOFF_MCE 0
@@ -319,6 +322,7 @@ u8 setup_APIC_eilvt_ibs(u8 vector, u8 msg_type, u8 mask)
319 setup_APIC_eilvt(APIC_EILVT_LVTOFF_IBS, vector, msg_type, mask); 322 setup_APIC_eilvt(APIC_EILVT_LVTOFF_IBS, vector, msg_type, mask);
320 return APIC_EILVT_LVTOFF_IBS; 323 return APIC_EILVT_LVTOFF_IBS;
321} 324}
325EXPORT_SYMBOL_GPL(setup_APIC_eilvt_ibs);
322 326
323/* 327/*
324 * Program the next event, relative to now 328 * Program the next event, relative to now
diff --git a/arch/x86/kernel/apic_64.c b/arch/x86/kernel/apic_64.c
index 53898b65a6ae..94ddb69ae15e 100644
--- a/arch/x86/kernel/apic_64.c
+++ b/arch/x86/kernel/apic_64.c
@@ -307,6 +307,9 @@ static void __setup_APIC_LVTT(unsigned int clocks, int oneshot, int irqen)
307 * 307 *
308 * Vector mappings are hard coded. On K8 only offset 0 (APIC500) and 308 * Vector mappings are hard coded. On K8 only offset 0 (APIC500) and
309 * MCE interrupts are supported. Thus MCE offset must be set to 0. 309 * MCE interrupts are supported. Thus MCE offset must be set to 0.
310 *
311 * If mask=1, the LVT entry does not generate interrupts while mask=0
312 * enables the vector. See also the BKDGs.
310 */ 313 */
311 314
312#define APIC_EILVT_LVTOFF_MCE 0 315#define APIC_EILVT_LVTOFF_MCE 0
@@ -331,6 +334,7 @@ u8 setup_APIC_eilvt_ibs(u8 vector, u8 msg_type, u8 mask)
331 setup_APIC_eilvt(APIC_EILVT_LVTOFF_IBS, vector, msg_type, mask); 334 setup_APIC_eilvt(APIC_EILVT_LVTOFF_IBS, vector, msg_type, mask);
332 return APIC_EILVT_LVTOFF_IBS; 335 return APIC_EILVT_LVTOFF_IBS;
333} 336}
337EXPORT_SYMBOL_GPL(setup_APIC_eilvt_ibs);
334 338
335/* 339/*
336 * Program the next event, relative to now 340 * Program the next event, relative to now
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index fb789dd9e691..25581dcb280e 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -124,18 +124,25 @@ static inline int flag_is_changeable_p(u32 flag)
124{ 124{
125 u32 f1, f2; 125 u32 f1, f2;
126 126
127 asm("pushfl\n\t" 127 /*
128 "pushfl\n\t" 128 * Cyrix and IDT cpus allow disabling of CPUID
129 "popl %0\n\t" 129 * so the code below may return different results
130 "movl %0,%1\n\t" 130 * when it is executed before and after enabling
131 "xorl %2,%0\n\t" 131 * the CPUID. Add "volatile" to not allow gcc to
132 "pushl %0\n\t" 132 * optimize the subsequent calls to this function.
133 "popfl\n\t" 133 */
134 "pushfl\n\t" 134 asm volatile ("pushfl\n\t"
135 "popl %0\n\t" 135 "pushfl\n\t"
136 "popfl\n\t" 136 "popl %0\n\t"
137 : "=&r" (f1), "=&r" (f2) 137 "movl %0,%1\n\t"
138 : "ir" (flag)); 138 "xorl %2,%0\n\t"
139 "pushl %0\n\t"
140 "popfl\n\t"
141 "pushfl\n\t"
142 "popl %0\n\t"
143 "popfl\n\t"
144 : "=&r" (f1), "=&r" (f2)
145 : "ir" (flag));
139 146
140 return ((f1^f2) & flag) != 0; 147 return ((f1^f2) & flag) != 0;
141} 148}
@@ -719,12 +726,24 @@ static void __cpuinit identify_cpu(struct cpuinfo_x86 *c)
719#endif 726#endif
720} 727}
721 728
729#ifdef CONFIG_X86_64
730static void vgetcpu_set_mode(void)
731{
732 if (cpu_has(&boot_cpu_data, X86_FEATURE_RDTSCP))
733 vgetcpu_mode = VGETCPU_RDTSCP;
734 else
735 vgetcpu_mode = VGETCPU_LSL;
736}
737#endif
738
722void __init identify_boot_cpu(void) 739void __init identify_boot_cpu(void)
723{ 740{
724 identify_cpu(&boot_cpu_data); 741 identify_cpu(&boot_cpu_data);
725#ifdef CONFIG_X86_32 742#ifdef CONFIG_X86_32
726 sysenter_setup(); 743 sysenter_setup();
727 enable_sep_cpu(); 744 enable_sep_cpu();
745#else
746 vgetcpu_set_mode();
728#endif 747#endif
729} 748}
730 749
@@ -797,7 +816,7 @@ void __cpuinit print_cpu_info(struct cpuinfo_x86 *c)
797 else if (c->cpuid_level >= 0) 816 else if (c->cpuid_level >= 0)
798 vendor = c->x86_vendor_id; 817 vendor = c->x86_vendor_id;
799 818
800 if (vendor && strncmp(c->x86_model_id, vendor, strlen(vendor))) 819 if (vendor && !strstr(c->x86_model_id, vendor))
801 printk(KERN_CONT "%s ", vendor); 820 printk(KERN_CONT "%s ", vendor);
802 821
803 if (c->x86_model_id[0]) 822 if (c->x86_model_id[0])
diff --git a/arch/x86/kernel/doublefault_32.c b/arch/x86/kernel/doublefault_32.c
index 395acb12b0d1..b4f14c6c09d9 100644
--- a/arch/x86/kernel/doublefault_32.c
+++ b/arch/x86/kernel/doublefault_32.c
@@ -66,6 +66,6 @@ struct tss_struct doublefault_tss __cacheline_aligned = {
66 .ds = __USER_DS, 66 .ds = __USER_DS,
67 .fs = __KERNEL_PERCPU, 67 .fs = __KERNEL_PERCPU,
68 68
69 .__cr3 = __phys_addr_const((unsigned long)swapper_pg_dir) 69 .__cr3 = __pa_nodebug(swapper_pg_dir),
70 } 70 }
71}; 71};
diff --git a/arch/x86/kernel/dumpstack_32.c b/arch/x86/kernel/dumpstack_32.c
new file mode 100644
index 000000000000..201ee359a1a9
--- /dev/null
+++ b/arch/x86/kernel/dumpstack_32.c
@@ -0,0 +1,447 @@
1/*
2 * Copyright (C) 1991, 1992 Linus Torvalds
3 * Copyright (C) 2000, 2001, 2002 Andi Kleen, SuSE Labs
4 */
5#include <linux/kallsyms.h>
6#include <linux/kprobes.h>
7#include <linux/uaccess.h>
8#include <linux/utsname.h>
9#include <linux/hardirq.h>
10#include <linux/kdebug.h>
11#include <linux/module.h>
12#include <linux/ptrace.h>
13#include <linux/kexec.h>
14#include <linux/bug.h>
15#include <linux/nmi.h>
16
17#include <asm/stacktrace.h>
18
19#define STACKSLOTS_PER_LINE 8
20#define get_bp(bp) asm("movl %%ebp, %0" : "=r" (bp) :)
21
22int panic_on_unrecovered_nmi;
23int kstack_depth_to_print = 3 * STACKSLOTS_PER_LINE;
24static unsigned int code_bytes = 64;
25static int die_counter;
26
27void printk_address(unsigned long address, int reliable)
28{
29 printk(" [<%p>] %s%pS\n", (void *) address,
30 reliable ? "" : "? ", (void *) address);
31}
32
33static inline int valid_stack_ptr(struct thread_info *tinfo,
34 void *p, unsigned int size, void *end)
35{
36 void *t = tinfo;
37 if (end) {
38 if (p < end && p >= (end-THREAD_SIZE))
39 return 1;
40 else
41 return 0;
42 }
43 return p > t && p < t + THREAD_SIZE - size;
44}
45
46/* The form of the top of the frame on the stack */
47struct stack_frame {
48 struct stack_frame *next_frame;
49 unsigned long return_address;
50};
51
52static inline unsigned long
53print_context_stack(struct thread_info *tinfo,
54 unsigned long *stack, unsigned long bp,
55 const struct stacktrace_ops *ops, void *data,
56 unsigned long *end)
57{
58 struct stack_frame *frame = (struct stack_frame *)bp;
59
60 while (valid_stack_ptr(tinfo, stack, sizeof(*stack), end)) {
61 unsigned long addr;
62
63 addr = *stack;
64 if (__kernel_text_address(addr)) {
65 if ((unsigned long) stack == bp + sizeof(long)) {
66 ops->address(data, addr, 1);
67 frame = frame->next_frame;
68 bp = (unsigned long) frame;
69 } else {
70 ops->address(data, addr, bp == 0);
71 }
72 }
73 stack++;
74 }
75 return bp;
76}
77
78void dump_trace(struct task_struct *task, struct pt_regs *regs,
79 unsigned long *stack, unsigned long bp,
80 const struct stacktrace_ops *ops, void *data)
81{
82 if (!task)
83 task = current;
84
85 if (!stack) {
86 unsigned long dummy;
87 stack = &dummy;
88 if (task && task != current)
89 stack = (unsigned long *)task->thread.sp;
90 }
91
92#ifdef CONFIG_FRAME_POINTER
93 if (!bp) {
94 if (task == current) {
95 /* Grab bp right from our regs */
96 get_bp(bp);
97 } else {
98 /* bp is the last reg pushed by switch_to */
99 bp = *(unsigned long *) task->thread.sp;
100 }
101 }
102#endif
103
104 for (;;) {
105 struct thread_info *context;
106
107 context = (struct thread_info *)
108 ((unsigned long)stack & (~(THREAD_SIZE - 1)));
109 bp = print_context_stack(context, stack, bp, ops, data, NULL);
110
111 stack = (unsigned long *)context->previous_esp;
112 if (!stack)
113 break;
114 if (ops->stack(data, "IRQ") < 0)
115 break;
116 touch_nmi_watchdog();
117 }
118}
119EXPORT_SYMBOL(dump_trace);
120
121static void
122print_trace_warning_symbol(void *data, char *msg, unsigned long symbol)
123{
124 printk(data);
125 print_symbol(msg, symbol);
126 printk("\n");
127}
128
129static void print_trace_warning(void *data, char *msg)
130{
131 printk("%s%s\n", (char *)data, msg);
132}
133
134static int print_trace_stack(void *data, char *name)
135{
136 printk("%s <%s> ", (char *)data, name);
137 return 0;
138}
139
140/*
141 * Print one address/symbol entries per line.
142 */
143static void print_trace_address(void *data, unsigned long addr, int reliable)
144{
145 touch_nmi_watchdog();
146 printk(data);
147 printk_address(addr, reliable);
148}
149
150static const struct stacktrace_ops print_trace_ops = {
151 .warning = print_trace_warning,
152 .warning_symbol = print_trace_warning_symbol,
153 .stack = print_trace_stack,
154 .address = print_trace_address,
155};
156
157static void
158show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs,
159 unsigned long *stack, unsigned long bp, char *log_lvl)
160{
161 printk("%sCall Trace:\n", log_lvl);
162 dump_trace(task, regs, stack, bp, &print_trace_ops, log_lvl);
163}
164
165void show_trace(struct task_struct *task, struct pt_regs *regs,
166 unsigned long *stack, unsigned long bp)
167{
168 show_trace_log_lvl(task, regs, stack, bp, "");
169}
170
171static void
172show_stack_log_lvl(struct task_struct *task, struct pt_regs *regs,
173 unsigned long *sp, unsigned long bp, char *log_lvl)
174{
175 unsigned long *stack;
176 int i;
177
178 if (sp == NULL) {
179 if (task)
180 sp = (unsigned long *)task->thread.sp;
181 else
182 sp = (unsigned long *)&sp;
183 }
184
185 stack = sp;
186 for (i = 0; i < kstack_depth_to_print; i++) {
187 if (kstack_end(stack))
188 break;
189 if (i && ((i % STACKSLOTS_PER_LINE) == 0))
190 printk("\n%s", log_lvl);
191 printk(" %08lx", *stack++);
192 touch_nmi_watchdog();
193 }
194 printk("\n");
195 show_trace_log_lvl(task, regs, sp, bp, log_lvl);
196}
197
198void show_stack(struct task_struct *task, unsigned long *sp)
199{
200 show_stack_log_lvl(task, NULL, sp, 0, "");
201}
202
203/*
204 * The architecture-independent dump_stack generator
205 */
206void dump_stack(void)
207{
208 unsigned long bp = 0;
209 unsigned long stack;
210
211#ifdef CONFIG_FRAME_POINTER
212 if (!bp)
213 get_bp(bp);
214#endif
215
216 printk("Pid: %d, comm: %.20s %s %s %.*s\n",
217 current->pid, current->comm, print_tainted(),
218 init_utsname()->release,
219 (int)strcspn(init_utsname()->version, " "),
220 init_utsname()->version);
221 show_trace(NULL, NULL, &stack, bp);
222}
223
224EXPORT_SYMBOL(dump_stack);
225
226void show_registers(struct pt_regs *regs)
227{
228 int i;
229
230 print_modules();
231 __show_regs(regs, 0);
232
233 printk(KERN_EMERG "Process %.*s (pid: %d, ti=%p task=%p task.ti=%p)\n",
234 TASK_COMM_LEN, current->comm, task_pid_nr(current),
235 current_thread_info(), current, task_thread_info(current));
236 /*
237 * When in-kernel, we also print out the stack and code at the
238 * time of the fault..
239 */
240 if (!user_mode_vm(regs)) {
241 unsigned int code_prologue = code_bytes * 43 / 64;
242 unsigned int code_len = code_bytes;
243 unsigned char c;
244 u8 *ip;
245
246 printk(KERN_EMERG "Stack:\n");
247 show_stack_log_lvl(NULL, regs, &regs->sp,
248 0, KERN_EMERG);
249
250 printk(KERN_EMERG "Code: ");
251
252 ip = (u8 *)regs->ip - code_prologue;
253 if (ip < (u8 *)PAGE_OFFSET || probe_kernel_address(ip, c)) {
254 /* try starting at IP */
255 ip = (u8 *)regs->ip;
256 code_len = code_len - code_prologue + 1;
257 }
258 for (i = 0; i < code_len; i++, ip++) {
259 if (ip < (u8 *)PAGE_OFFSET ||
260 probe_kernel_address(ip, c)) {
261 printk(" Bad EIP value.");
262 break;
263 }
264 if (ip == (u8 *)regs->ip)
265 printk("<%02x> ", c);
266 else
267 printk("%02x ", c);
268 }
269 }
270 printk("\n");
271}
272
273int is_valid_bugaddr(unsigned long ip)
274{
275 unsigned short ud2;
276
277 if (ip < PAGE_OFFSET)
278 return 0;
279 if (probe_kernel_address((unsigned short *)ip, ud2))
280 return 0;
281
282 return ud2 == 0x0b0f;
283}
284
285static raw_spinlock_t die_lock = __RAW_SPIN_LOCK_UNLOCKED;
286static int die_owner = -1;
287static unsigned int die_nest_count;
288
289unsigned __kprobes long oops_begin(void)
290{
291 unsigned long flags;
292
293 oops_enter();
294
295 if (die_owner != raw_smp_processor_id()) {
296 console_verbose();
297 raw_local_irq_save(flags);
298 __raw_spin_lock(&die_lock);
299 die_owner = smp_processor_id();
300 die_nest_count = 0;
301 bust_spinlocks(1);
302 } else {
303 raw_local_irq_save(flags);
304 }
305 die_nest_count++;
306 return flags;
307}
308
309void __kprobes oops_end(unsigned long flags, struct pt_regs *regs, int signr)
310{
311 bust_spinlocks(0);
312 die_owner = -1;
313 add_taint(TAINT_DIE);
314 __raw_spin_unlock(&die_lock);
315 raw_local_irq_restore(flags);
316
317 if (!regs)
318 return;
319
320 if (kexec_should_crash(current))
321 crash_kexec(regs);
322 if (in_interrupt())
323 panic("Fatal exception in interrupt");
324 if (panic_on_oops)
325 panic("Fatal exception");
326 oops_exit();
327 do_exit(signr);
328}
329
330int __kprobes __die(const char *str, struct pt_regs *regs, long err)
331{
332 unsigned short ss;
333 unsigned long sp;
334
335 printk(KERN_EMERG "%s: %04lx [#%d] ", str, err & 0xffff, ++die_counter);
336#ifdef CONFIG_PREEMPT
337 printk("PREEMPT ");
338#endif
339#ifdef CONFIG_SMP
340 printk("SMP ");
341#endif
342#ifdef CONFIG_DEBUG_PAGEALLOC
343 printk("DEBUG_PAGEALLOC");
344#endif
345 printk("\n");
346 if (notify_die(DIE_OOPS, str, regs, err,
347 current->thread.trap_no, SIGSEGV) == NOTIFY_STOP)
348 return 1;
349
350 show_registers(regs);
351 /* Executive summary in case the oops scrolled away */
352 sp = (unsigned long) (&regs->sp);
353 savesegment(ss, ss);
354 if (user_mode(regs)) {
355 sp = regs->sp;
356 ss = regs->ss & 0xffff;
357 }
358 printk(KERN_EMERG "EIP: [<%08lx>] ", regs->ip);
359 print_symbol("%s", regs->ip);
360 printk(" SS:ESP %04x:%08lx\n", ss, sp);
361 return 0;
362}
363
364/*
365 * This is gone through when something in the kernel has done something bad
366 * and is about to be terminated:
367 */
368void die(const char *str, struct pt_regs *regs, long err)
369{
370 unsigned long flags = oops_begin();
371
372 if (die_nest_count < 3) {
373 report_bug(regs->ip, regs);
374
375 if (__die(str, regs, err))
376 regs = NULL;
377 } else {
378 printk(KERN_EMERG "Recursive die() failure, output suppressed\n");
379 }
380
381 oops_end(flags, regs, SIGSEGV);
382}
383
384static DEFINE_SPINLOCK(nmi_print_lock);
385
386void notrace __kprobes
387die_nmi(char *str, struct pt_regs *regs, int do_panic)
388{
389 if (notify_die(DIE_NMIWATCHDOG, str, regs, 0, 2, SIGINT) == NOTIFY_STOP)
390 return;
391
392 spin_lock(&nmi_print_lock);
393 /*
394 * We are in trouble anyway, lets at least try
395 * to get a message out:
396 */
397 bust_spinlocks(1);
398 printk(KERN_EMERG "%s", str);
399 printk(" on CPU%d, ip %08lx, registers:\n",
400 smp_processor_id(), regs->ip);
401 show_registers(regs);
402 if (do_panic)
403 panic("Non maskable interrupt");
404 console_silent();
405 spin_unlock(&nmi_print_lock);
406 bust_spinlocks(0);
407
408 /*
409 * If we are in kernel we are probably nested up pretty bad
410 * and might aswell get out now while we still can:
411 */
412 if (!user_mode_vm(regs)) {
413 current->thread.trap_no = 2;
414 crash_kexec(regs);
415 }
416
417 do_exit(SIGSEGV);
418}
419
420static int __init oops_setup(char *s)
421{
422 if (!s)
423 return -EINVAL;
424 if (!strcmp(s, "panic"))
425 panic_on_oops = 1;
426 return 0;
427}
428early_param("oops", oops_setup);
429
430static int __init kstack_setup(char *s)
431{
432 if (!s)
433 return -EINVAL;
434 kstack_depth_to_print = simple_strtoul(s, NULL, 0);
435 return 0;
436}
437early_param("kstack", kstack_setup);
438
439static int __init code_bytes_setup(char *s)
440{
441 code_bytes = simple_strtoul(s, NULL, 0);
442 if (code_bytes > 8192)
443 code_bytes = 8192;
444
445 return 1;
446}
447__setup("code_bytes=", code_bytes_setup);
diff --git a/arch/x86/kernel/dumpstack_64.c b/arch/x86/kernel/dumpstack_64.c
new file mode 100644
index 000000000000..086cc8118e39
--- /dev/null
+++ b/arch/x86/kernel/dumpstack_64.c
@@ -0,0 +1,573 @@
1/*
2 * Copyright (C) 1991, 1992 Linus Torvalds
3 * Copyright (C) 2000, 2001, 2002 Andi Kleen, SuSE Labs
4 */
5#include <linux/kallsyms.h>
6#include <linux/kprobes.h>
7#include <linux/uaccess.h>
8#include <linux/utsname.h>
9#include <linux/hardirq.h>
10#include <linux/kdebug.h>
11#include <linux/module.h>
12#include <linux/ptrace.h>
13#include <linux/kexec.h>
14#include <linux/bug.h>
15#include <linux/nmi.h>
16
17#include <asm/stacktrace.h>
18
19#define STACKSLOTS_PER_LINE 4
20#define get_bp(bp) asm("movq %%rbp, %0" : "=r" (bp) :)
21
22int panic_on_unrecovered_nmi;
23int kstack_depth_to_print = 3 * STACKSLOTS_PER_LINE;
24static unsigned int code_bytes = 64;
25static int die_counter;
26
27void printk_address(unsigned long address, int reliable)
28{
29 printk(" [<%p>] %s%pS\n", (void *) address,
30 reliable ? "" : "? ", (void *) address);
31}
32
33static unsigned long *in_exception_stack(unsigned cpu, unsigned long stack,
34 unsigned *usedp, char **idp)
35{
36 static char ids[][8] = {
37 [DEBUG_STACK - 1] = "#DB",
38 [NMI_STACK - 1] = "NMI",
39 [DOUBLEFAULT_STACK - 1] = "#DF",
40 [STACKFAULT_STACK - 1] = "#SS",
41 [MCE_STACK - 1] = "#MC",
42#if DEBUG_STKSZ > EXCEPTION_STKSZ
43 [N_EXCEPTION_STACKS ...
44 N_EXCEPTION_STACKS + DEBUG_STKSZ / EXCEPTION_STKSZ - 2] = "#DB[?]"
45#endif
46 };
47 unsigned k;
48
49 /*
50 * Iterate over all exception stacks, and figure out whether
51 * 'stack' is in one of them:
52 */
53 for (k = 0; k < N_EXCEPTION_STACKS; k++) {
54 unsigned long end = per_cpu(orig_ist, cpu).ist[k];
55 /*
56 * Is 'stack' above this exception frame's end?
57 * If yes then skip to the next frame.
58 */
59 if (stack >= end)
60 continue;
61 /*
62 * Is 'stack' above this exception frame's start address?
63 * If yes then we found the right frame.
64 */
65 if (stack >= end - EXCEPTION_STKSZ) {
66 /*
67 * Make sure we only iterate through an exception
68 * stack once. If it comes up for the second time
69 * then there's something wrong going on - just
70 * break out and return NULL:
71 */
72 if (*usedp & (1U << k))
73 break;
74 *usedp |= 1U << k;
75 *idp = ids[k];
76 return (unsigned long *)end;
77 }
78 /*
79 * If this is a debug stack, and if it has a larger size than
80 * the usual exception stacks, then 'stack' might still
81 * be within the lower portion of the debug stack:
82 */
83#if DEBUG_STKSZ > EXCEPTION_STKSZ
84 if (k == DEBUG_STACK - 1 && stack >= end - DEBUG_STKSZ) {
85 unsigned j = N_EXCEPTION_STACKS - 1;
86
87 /*
88 * Black magic. A large debug stack is composed of
89 * multiple exception stack entries, which we
90 * iterate through now. Dont look:
91 */
92 do {
93 ++j;
94 end -= EXCEPTION_STKSZ;
95 ids[j][4] = '1' + (j - N_EXCEPTION_STACKS);
96 } while (stack < end - EXCEPTION_STKSZ);
97 if (*usedp & (1U << j))
98 break;
99 *usedp |= 1U << j;
100 *idp = ids[j];
101 return (unsigned long *)end;
102 }
103#endif
104 }
105 return NULL;
106}
107
108/*
109 * x86-64 can have up to three kernel stacks:
110 * process stack
111 * interrupt stack
112 * severe exception (double fault, nmi, stack fault, debug, mce) hardware stack
113 */
114
115static inline int valid_stack_ptr(struct thread_info *tinfo,
116 void *p, unsigned int size, void *end)
117{
118 void *t = tinfo;
119 if (end) {
120 if (p < end && p >= (end-THREAD_SIZE))
121 return 1;
122 else
123 return 0;
124 }
125 return p > t && p < t + THREAD_SIZE - size;
126}
127
128/* The form of the top of the frame on the stack */
129struct stack_frame {
130 struct stack_frame *next_frame;
131 unsigned long return_address;
132};
133
134static inline unsigned long
135print_context_stack(struct thread_info *tinfo,
136 unsigned long *stack, unsigned long bp,
137 const struct stacktrace_ops *ops, void *data,
138 unsigned long *end)
139{
140 struct stack_frame *frame = (struct stack_frame *)bp;
141
142 while (valid_stack_ptr(tinfo, stack, sizeof(*stack), end)) {
143 unsigned long addr;
144
145 addr = *stack;
146 if (__kernel_text_address(addr)) {
147 if ((unsigned long) stack == bp + sizeof(long)) {
148 ops->address(data, addr, 1);
149 frame = frame->next_frame;
150 bp = (unsigned long) frame;
151 } else {
152 ops->address(data, addr, bp == 0);
153 }
154 }
155 stack++;
156 }
157 return bp;
158}
159
160void dump_trace(struct task_struct *task, struct pt_regs *regs,
161 unsigned long *stack, unsigned long bp,
162 const struct stacktrace_ops *ops, void *data)
163{
164 const unsigned cpu = get_cpu();
165 unsigned long *irqstack_end = (unsigned long *)cpu_pda(cpu)->irqstackptr;
166 unsigned used = 0;
167 struct thread_info *tinfo;
168
169 if (!task)
170 task = current;
171
172 if (!stack) {
173 unsigned long dummy;
174 stack = &dummy;
175 if (task && task != current)
176 stack = (unsigned long *)task->thread.sp;
177 }
178
179#ifdef CONFIG_FRAME_POINTER
180 if (!bp) {
181 if (task == current) {
182 /* Grab bp right from our regs */
183 get_bp(bp);
184 } else {
185 /* bp is the last reg pushed by switch_to */
186 bp = *(unsigned long *) task->thread.sp;
187 }
188 }
189#endif
190
191 /*
192 * Print function call entries in all stacks, starting at the
193 * current stack address. If the stacks consist of nested
194 * exceptions
195 */
196 tinfo = task_thread_info(task);
197 for (;;) {
198 char *id;
199 unsigned long *estack_end;
200 estack_end = in_exception_stack(cpu, (unsigned long)stack,
201 &used, &id);
202
203 if (estack_end) {
204 if (ops->stack(data, id) < 0)
205 break;
206
207 bp = print_context_stack(tinfo, stack, bp, ops,
208 data, estack_end);
209 ops->stack(data, "<EOE>");
210 /*
211 * We link to the next stack via the
212 * second-to-last pointer (index -2 to end) in the
213 * exception stack:
214 */
215 stack = (unsigned long *) estack_end[-2];
216 continue;
217 }
218 if (irqstack_end) {
219 unsigned long *irqstack;
220 irqstack = irqstack_end -
221 (IRQSTACKSIZE - 64) / sizeof(*irqstack);
222
223 if (stack >= irqstack && stack < irqstack_end) {
224 if (ops->stack(data, "IRQ") < 0)
225 break;
226 bp = print_context_stack(tinfo, stack, bp,
227 ops, data, irqstack_end);
228 /*
229 * We link to the next stack (which would be
230 * the process stack normally) the last
231 * pointer (index -1 to end) in the IRQ stack:
232 */
233 stack = (unsigned long *) (irqstack_end[-1]);
234 irqstack_end = NULL;
235 ops->stack(data, "EOI");
236 continue;
237 }
238 }
239 break;
240 }
241
242 /*
243 * This handles the process stack:
244 */
245 bp = print_context_stack(tinfo, stack, bp, ops, data, NULL);
246 put_cpu();
247}
248EXPORT_SYMBOL(dump_trace);
249
250static void
251print_trace_warning_symbol(void *data, char *msg, unsigned long symbol)
252{
253 printk(data);
254 print_symbol(msg, symbol);
255 printk("\n");
256}
257
258static void print_trace_warning(void *data, char *msg)
259{
260 printk("%s%s\n", (char *)data, msg);
261}
262
263static int print_trace_stack(void *data, char *name)
264{
265 printk("%s <%s> ", (char *)data, name);
266 return 0;
267}
268
269/*
270 * Print one address/symbol entries per line.
271 */
272static void print_trace_address(void *data, unsigned long addr, int reliable)
273{
274 touch_nmi_watchdog();
275 printk(data);
276 printk_address(addr, reliable);
277}
278
279static const struct stacktrace_ops print_trace_ops = {
280 .warning = print_trace_warning,
281 .warning_symbol = print_trace_warning_symbol,
282 .stack = print_trace_stack,
283 .address = print_trace_address,
284};
285
286static void
287show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs,
288 unsigned long *stack, unsigned long bp, char *log_lvl)
289{
290 printk("%sCall Trace:\n", log_lvl);
291 dump_trace(task, regs, stack, bp, &print_trace_ops, log_lvl);
292}
293
294void show_trace(struct task_struct *task, struct pt_regs *regs,
295 unsigned long *stack, unsigned long bp)
296{
297 show_trace_log_lvl(task, regs, stack, bp, "");
298}
299
300static void
301show_stack_log_lvl(struct task_struct *task, struct pt_regs *regs,
302 unsigned long *sp, unsigned long bp, char *log_lvl)
303{
304 unsigned long *stack;
305 int i;
306 const int cpu = smp_processor_id();
307 unsigned long *irqstack_end =
308 (unsigned long *) (cpu_pda(cpu)->irqstackptr);
309 unsigned long *irqstack =
310 (unsigned long *) (cpu_pda(cpu)->irqstackptr - IRQSTACKSIZE);
311
312 /*
313 * debugging aid: "show_stack(NULL, NULL);" prints the
314 * back trace for this cpu.
315 */
316
317 if (sp == NULL) {
318 if (task)
319 sp = (unsigned long *)task->thread.sp;
320 else
321 sp = (unsigned long *)&sp;
322 }
323
324 stack = sp;
325 for (i = 0; i < kstack_depth_to_print; i++) {
326 if (stack >= irqstack && stack <= irqstack_end) {
327 if (stack == irqstack_end) {
328 stack = (unsigned long *) (irqstack_end[-1]);
329 printk(" <EOI> ");
330 }
331 } else {
332 if (((long) stack & (THREAD_SIZE-1)) == 0)
333 break;
334 }
335 if (i && ((i % STACKSLOTS_PER_LINE) == 0))
336 printk("\n%s", log_lvl);
337 printk(" %016lx", *stack++);
338 touch_nmi_watchdog();
339 }
340 printk("\n");
341 show_trace_log_lvl(task, regs, sp, bp, log_lvl);
342}
343
344void show_stack(struct task_struct *task, unsigned long *sp)
345{
346 show_stack_log_lvl(task, NULL, sp, 0, "");
347}
348
349/*
350 * The architecture-independent dump_stack generator
351 */
352void dump_stack(void)
353{
354 unsigned long bp = 0;
355 unsigned long stack;
356
357#ifdef CONFIG_FRAME_POINTER
358 if (!bp)
359 get_bp(bp);
360#endif
361
362 printk("Pid: %d, comm: %.20s %s %s %.*s\n",
363 current->pid, current->comm, print_tainted(),
364 init_utsname()->release,
365 (int)strcspn(init_utsname()->version, " "),
366 init_utsname()->version);
367 show_trace(NULL, NULL, &stack, bp);
368}
369EXPORT_SYMBOL(dump_stack);
370
371void show_registers(struct pt_regs *regs)
372{
373 int i;
374 unsigned long sp;
375 const int cpu = smp_processor_id();
376 struct task_struct *cur = cpu_pda(cpu)->pcurrent;
377
378 sp = regs->sp;
379 printk("CPU %d ", cpu);
380 __show_regs(regs, 1);
381 printk("Process %s (pid: %d, threadinfo %p, task %p)\n",
382 cur->comm, cur->pid, task_thread_info(cur), cur);
383
384 /*
385 * When in-kernel, we also print out the stack and code at the
386 * time of the fault..
387 */
388 if (!user_mode(regs)) {
389 unsigned int code_prologue = code_bytes * 43 / 64;
390 unsigned int code_len = code_bytes;
391 unsigned char c;
392 u8 *ip;
393
394 printk(KERN_EMERG "Stack:\n");
395 show_stack_log_lvl(NULL, regs, (unsigned long *)sp,
396 regs->bp, KERN_EMERG);
397
398 printk(KERN_EMERG "Code: ");
399
400 ip = (u8 *)regs->ip - code_prologue;
401 if (ip < (u8 *)PAGE_OFFSET || probe_kernel_address(ip, c)) {
402 /* try starting at IP */
403 ip = (u8 *)regs->ip;
404 code_len = code_len - code_prologue + 1;
405 }
406 for (i = 0; i < code_len; i++, ip++) {
407 if (ip < (u8 *)PAGE_OFFSET ||
408 probe_kernel_address(ip, c)) {
409 printk(" Bad RIP value.");
410 break;
411 }
412 if (ip == (u8 *)regs->ip)
413 printk("<%02x> ", c);
414 else
415 printk("%02x ", c);
416 }
417 }
418 printk("\n");
419}
420
421int is_valid_bugaddr(unsigned long ip)
422{
423 unsigned short ud2;
424
425 if (__copy_from_user(&ud2, (const void __user *) ip, sizeof(ud2)))
426 return 0;
427
428 return ud2 == 0x0b0f;
429}
430
431static raw_spinlock_t die_lock = __RAW_SPIN_LOCK_UNLOCKED;
432static int die_owner = -1;
433static unsigned int die_nest_count;
434
435unsigned __kprobes long oops_begin(void)
436{
437 int cpu;
438 unsigned long flags;
439
440 oops_enter();
441
442 /* racy, but better than risking deadlock. */
443 raw_local_irq_save(flags);
444 cpu = smp_processor_id();
445 if (!__raw_spin_trylock(&die_lock)) {
446 if (cpu == die_owner)
447 /* nested oops. should stop eventually */;
448 else
449 __raw_spin_lock(&die_lock);
450 }
451 die_nest_count++;
452 die_owner = cpu;
453 console_verbose();
454 bust_spinlocks(1);
455 return flags;
456}
457
458void __kprobes oops_end(unsigned long flags, struct pt_regs *regs, int signr)
459{
460 die_owner = -1;
461 bust_spinlocks(0);
462 die_nest_count--;
463 if (!die_nest_count)
464 /* Nest count reaches zero, release the lock. */
465 __raw_spin_unlock(&die_lock);
466 raw_local_irq_restore(flags);
467 if (!regs) {
468 oops_exit();
469 return;
470 }
471 if (in_interrupt())
472 panic("Fatal exception in interrupt");
473 if (panic_on_oops)
474 panic("Fatal exception");
475 oops_exit();
476 do_exit(signr);
477}
478
479int __kprobes __die(const char *str, struct pt_regs *regs, long err)
480{
481 printk(KERN_EMERG "%s: %04lx [#%d] ", str, err & 0xffff, ++die_counter);
482#ifdef CONFIG_PREEMPT
483 printk("PREEMPT ");
484#endif
485#ifdef CONFIG_SMP
486 printk("SMP ");
487#endif
488#ifdef CONFIG_DEBUG_PAGEALLOC
489 printk("DEBUG_PAGEALLOC");
490#endif
491 printk("\n");
492 if (notify_die(DIE_OOPS, str, regs, err,
493 current->thread.trap_no, SIGSEGV) == NOTIFY_STOP)
494 return 1;
495
496 show_registers(regs);
497 add_taint(TAINT_DIE);
498 /* Executive summary in case the oops scrolled away */
499 printk(KERN_ALERT "RIP ");
500 printk_address(regs->ip, 1);
501 printk(" RSP <%016lx>\n", regs->sp);
502 if (kexec_should_crash(current))
503 crash_kexec(regs);
504 return 0;
505}
506
507void die(const char *str, struct pt_regs *regs, long err)
508{
509 unsigned long flags = oops_begin();
510
511 if (!user_mode(regs))
512 report_bug(regs->ip, regs);
513
514 if (__die(str, regs, err))
515 regs = NULL;
516 oops_end(flags, regs, SIGSEGV);
517}
518
519notrace __kprobes void
520die_nmi(char *str, struct pt_regs *regs, int do_panic)
521{
522 unsigned long flags;
523
524 if (notify_die(DIE_NMIWATCHDOG, str, regs, 0, 2, SIGINT) == NOTIFY_STOP)
525 return;
526
527 flags = oops_begin();
528 /*
529 * We are in trouble anyway, lets at least try
530 * to get a message out.
531 */
532 printk(KERN_EMERG "%s", str);
533 printk(" on CPU%d, ip %08lx, registers:\n",
534 smp_processor_id(), regs->ip);
535 show_registers(regs);
536 if (kexec_should_crash(current))
537 crash_kexec(regs);
538 if (do_panic || panic_on_oops)
539 panic("Non maskable interrupt");
540 oops_end(flags, NULL, SIGBUS);
541 nmi_exit();
542 local_irq_enable();
543 do_exit(SIGBUS);
544}
545
546static int __init oops_setup(char *s)
547{
548 if (!s)
549 return -EINVAL;
550 if (!strcmp(s, "panic"))
551 panic_on_oops = 1;
552 return 0;
553}
554early_param("oops", oops_setup);
555
556static int __init kstack_setup(char *s)
557{
558 if (!s)
559 return -EINVAL;
560 kstack_depth_to_print = simple_strtoul(s, NULL, 0);
561 return 0;
562}
563early_param("kstack", kstack_setup);
564
565static int __init code_bytes_setup(char *s)
566{
567 code_bytes = simple_strtoul(s, NULL, 0);
568 if (code_bytes > 8192)
569 code_bytes = 8192;
570
571 return 1;
572}
573__setup("code_bytes=", code_bytes_setup);
diff --git a/arch/x86/kernel/entry_32.S b/arch/x86/kernel/entry_32.S
index 109792bc7cfa..b21fbfaffe39 100644
--- a/arch/x86/kernel/entry_32.S
+++ b/arch/x86/kernel/entry_32.S
@@ -730,6 +730,7 @@ error_code:
730 movl $(__USER_DS), %ecx 730 movl $(__USER_DS), %ecx
731 movl %ecx, %ds 731 movl %ecx, %ds
732 movl %ecx, %es 732 movl %ecx, %es
733 TRACE_IRQS_OFF
733 movl %esp,%eax # pt_regs pointer 734 movl %esp,%eax # pt_regs pointer
734 call *%edi 735 call *%edi
735 jmp ret_from_exception 736 jmp ret_from_exception
@@ -760,20 +761,9 @@ ENTRY(device_not_available)
760 RING0_INT_FRAME 761 RING0_INT_FRAME
761 pushl $-1 # mark this as an int 762 pushl $-1 # mark this as an int
762 CFI_ADJUST_CFA_OFFSET 4 763 CFI_ADJUST_CFA_OFFSET 4
763 SAVE_ALL 764 pushl $do_device_not_available
764 GET_CR0_INTO_EAX
765 testl $0x4, %eax # EM (math emulation bit)
766 jne device_not_available_emulate
767 preempt_stop(CLBR_ANY)
768 call math_state_restore
769 jmp ret_from_exception
770device_not_available_emulate:
771 pushl $0 # temporary storage for ORIG_EIP
772 CFI_ADJUST_CFA_OFFSET 4 765 CFI_ADJUST_CFA_OFFSET 4
773 call math_emulate 766 jmp error_code
774 addl $4, %esp
775 CFI_ADJUST_CFA_OFFSET -4
776 jmp ret_from_exception
777 CFI_ENDPROC 767 CFI_ENDPROC
778END(device_not_available) 768END(device_not_available)
779 769
@@ -814,6 +804,7 @@ debug_stack_correct:
814 pushl $-1 # mark this as an int 804 pushl $-1 # mark this as an int
815 CFI_ADJUST_CFA_OFFSET 4 805 CFI_ADJUST_CFA_OFFSET 4
816 SAVE_ALL 806 SAVE_ALL
807 TRACE_IRQS_OFF
817 xorl %edx,%edx # error code 0 808 xorl %edx,%edx # error code 0
818 movl %esp,%eax # pt_regs pointer 809 movl %esp,%eax # pt_regs pointer
819 call do_debug 810 call do_debug
@@ -858,6 +849,7 @@ nmi_stack_correct:
858 pushl %eax 849 pushl %eax
859 CFI_ADJUST_CFA_OFFSET 4 850 CFI_ADJUST_CFA_OFFSET 4
860 SAVE_ALL 851 SAVE_ALL
852 TRACE_IRQS_OFF
861 xorl %edx,%edx # zero error code 853 xorl %edx,%edx # zero error code
862 movl %esp,%eax # pt_regs pointer 854 movl %esp,%eax # pt_regs pointer
863 call do_nmi 855 call do_nmi
@@ -898,6 +890,7 @@ nmi_espfix_stack:
898 pushl %eax 890 pushl %eax
899 CFI_ADJUST_CFA_OFFSET 4 891 CFI_ADJUST_CFA_OFFSET 4
900 SAVE_ALL 892 SAVE_ALL
893 TRACE_IRQS_OFF
901 FIXUP_ESPFIX_STACK # %eax == %esp 894 FIXUP_ESPFIX_STACK # %eax == %esp
902 xorl %edx,%edx # zero error code 895 xorl %edx,%edx # zero error code
903 call do_nmi 896 call do_nmi
@@ -928,6 +921,7 @@ KPROBE_ENTRY(int3)
928 pushl $-1 # mark this as an int 921 pushl $-1 # mark this as an int
929 CFI_ADJUST_CFA_OFFSET 4 922 CFI_ADJUST_CFA_OFFSET 4
930 SAVE_ALL 923 SAVE_ALL
924 TRACE_IRQS_OFF
931 xorl %edx,%edx # zero error code 925 xorl %edx,%edx # zero error code
932 movl %esp,%eax # pt_regs pointer 926 movl %esp,%eax # pt_regs pointer
933 call do_int3 927 call do_int3
@@ -1030,7 +1024,7 @@ ENTRY(machine_check)
1030 RING0_INT_FRAME 1024 RING0_INT_FRAME
1031 pushl $0 1025 pushl $0
1032 CFI_ADJUST_CFA_OFFSET 4 1026 CFI_ADJUST_CFA_OFFSET 4
1033 pushl machine_check_vector 1027 pushl $do_machine_check
1034 CFI_ADJUST_CFA_OFFSET 4 1028 CFI_ADJUST_CFA_OFFSET 4
1035 jmp error_code 1029 jmp error_code
1036 CFI_ENDPROC 1030 CFI_ENDPROC
diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S
index cf3a0b2d0059..1db6ce4314e1 100644
--- a/arch/x86/kernel/entry_64.S
+++ b/arch/x86/kernel/entry_64.S
@@ -667,6 +667,13 @@ END(stub_rt_sigreturn)
667 SAVE_ARGS 667 SAVE_ARGS
668 leaq -ARGOFFSET(%rsp),%rdi # arg1 for handler 668 leaq -ARGOFFSET(%rsp),%rdi # arg1 for handler
669 pushq %rbp 669 pushq %rbp
670 /*
671 * Save rbp twice: One is for marking the stack frame, as usual, and the
672 * other, to fill pt_regs properly. This is because bx comes right
673 * before the last saved register in that structure, and not bp. If the
674 * base pointer were in the place bx is today, this would not be needed.
675 */
676 movq %rbp, -8(%rsp)
670 CFI_ADJUST_CFA_OFFSET 8 677 CFI_ADJUST_CFA_OFFSET 8
671 CFI_REL_OFFSET rbp, 0 678 CFI_REL_OFFSET rbp, 0
672 movq %rsp,%rbp 679 movq %rsp,%rbp
@@ -932,6 +939,9 @@ END(spurious_interrupt)
932 .if \ist 939 .if \ist
933 movq %gs:pda_data_offset, %rbp 940 movq %gs:pda_data_offset, %rbp
934 .endif 941 .endif
942 .if \irqtrace
943 TRACE_IRQS_OFF
944 .endif
935 movq %rsp,%rdi 945 movq %rsp,%rdi
936 movq ORIG_RAX(%rsp),%rsi 946 movq ORIG_RAX(%rsp),%rsi
937 movq $-1,ORIG_RAX(%rsp) 947 movq $-1,ORIG_RAX(%rsp)
@@ -1058,7 +1068,8 @@ KPROBE_ENTRY(error_entry)
1058 je error_kernelspace 1068 je error_kernelspace
1059error_swapgs: 1069error_swapgs:
1060 SWAPGS 1070 SWAPGS
1061error_sti: 1071error_sti:
1072 TRACE_IRQS_OFF
1062 movq %rdi,RDI(%rsp) 1073 movq %rdi,RDI(%rsp)
1063 CFI_REL_OFFSET rdi,RDI 1074 CFI_REL_OFFSET rdi,RDI
1064 movq %rsp,%rdi 1075 movq %rsp,%rdi
@@ -1232,7 +1243,7 @@ ENTRY(simd_coprocessor_error)
1232END(simd_coprocessor_error) 1243END(simd_coprocessor_error)
1233 1244
1234ENTRY(device_not_available) 1245ENTRY(device_not_available)
1235 zeroentry math_state_restore 1246 zeroentry do_device_not_available
1236END(device_not_available) 1247END(device_not_available)
1237 1248
1238 /* runs on exception stack */ 1249 /* runs on exception stack */
diff --git a/arch/x86/kernel/es7000_32.c b/arch/x86/kernel/es7000_32.c
index 849e5cd485b8..f454c78fcef6 100644
--- a/arch/x86/kernel/es7000_32.c
+++ b/arch/x86/kernel/es7000_32.c
@@ -109,6 +109,7 @@ struct oem_table {
109}; 109};
110 110
111extern int find_unisys_acpi_oem_table(unsigned long *oem_addr); 111extern int find_unisys_acpi_oem_table(unsigned long *oem_addr);
112extern void unmap_unisys_acpi_oem_table(unsigned long oem_addr);
112#endif 113#endif
113 114
114struct mip_reg { 115struct mip_reg {
@@ -243,21 +244,38 @@ parse_unisys_oem (char *oemptr)
243} 244}
244 245
245#ifdef CONFIG_ACPI 246#ifdef CONFIG_ACPI
246int __init 247static unsigned long oem_addrX;
247find_unisys_acpi_oem_table(unsigned long *oem_addr) 248static unsigned long oem_size;
249int __init find_unisys_acpi_oem_table(unsigned long *oem_addr)
248{ 250{
249 struct acpi_table_header *header = NULL; 251 struct acpi_table_header *header = NULL;
250 int i = 0; 252 int i = 0;
251 while (ACPI_SUCCESS(acpi_get_table("OEM1", i++, &header))) { 253 acpi_size tbl_size;
254
255 while (ACPI_SUCCESS(acpi_get_table_with_size("OEM1", i++, &header, &tbl_size))) {
252 if (!memcmp((char *) &header->oem_id, "UNISYS", 6)) { 256 if (!memcmp((char *) &header->oem_id, "UNISYS", 6)) {
253 struct oem_table *t = (struct oem_table *)header; 257 struct oem_table *t = (struct oem_table *)header;
254 *oem_addr = (unsigned long)__acpi_map_table(t->OEMTableAddr, 258
255 t->OEMTableSize); 259 oem_addrX = t->OEMTableAddr;
260 oem_size = t->OEMTableSize;
261 early_acpi_os_unmap_memory(header, tbl_size);
262
263 *oem_addr = (unsigned long)__acpi_map_table(oem_addrX,
264 oem_size);
256 return 0; 265 return 0;
257 } 266 }
267 early_acpi_os_unmap_memory(header, tbl_size);
258 } 268 }
259 return -1; 269 return -1;
260} 270}
271
272void __init unmap_unisys_acpi_oem_table(unsigned long oem_addr)
273{
274 if (!oem_addr)
275 return;
276
277 __acpi_unmap_table((char *)oem_addr, oem_size);
278}
261#endif 279#endif
262 280
263static void 281static void
diff --git a/arch/x86/kernel/genx2apic_uv_x.c b/arch/x86/kernel/genx2apic_uv_x.c
index ae2ffc8a400c..33581d94a90e 100644
--- a/arch/x86/kernel/genx2apic_uv_x.c
+++ b/arch/x86/kernel/genx2apic_uv_x.c
@@ -114,7 +114,7 @@ static void uv_send_IPI_one(int cpu, int vector)
114 unsigned long val, apicid, lapicid; 114 unsigned long val, apicid, lapicid;
115 int pnode; 115 int pnode;
116 116
117 apicid = per_cpu(x86_cpu_to_apicid, cpu); /* ZZZ - cache node-local ? */ 117 apicid = per_cpu(x86_cpu_to_apicid, cpu);
118 lapicid = apicid & 0x3f; /* ZZZ macro needed */ 118 lapicid = apicid & 0x3f; /* ZZZ macro needed */
119 pnode = uv_apicid_to_pnode(apicid); 119 pnode = uv_apicid_to_pnode(apicid);
120 val = 120 val =
@@ -202,12 +202,10 @@ static unsigned int phys_pkg_id(int index_msb)
202 return uv_read_apic_id() >> index_msb; 202 return uv_read_apic_id() >> index_msb;
203} 203}
204 204
205#ifdef ZZZ /* Needs x2apic patch */
206static void uv_send_IPI_self(int vector) 205static void uv_send_IPI_self(int vector)
207{ 206{
208 apic_write(APIC_SELF_IPI, vector); 207 apic_write(APIC_SELF_IPI, vector);
209} 208}
210#endif
211 209
212struct genapic apic_x2apic_uv_x = { 210struct genapic apic_x2apic_uv_x = {
213 .name = "UV large system", 211 .name = "UV large system",
@@ -215,15 +213,15 @@ struct genapic apic_x2apic_uv_x = {
215 .int_delivery_mode = dest_Fixed, 213 .int_delivery_mode = dest_Fixed,
216 .int_dest_mode = (APIC_DEST_PHYSICAL != 0), 214 .int_dest_mode = (APIC_DEST_PHYSICAL != 0),
217 .target_cpus = uv_target_cpus, 215 .target_cpus = uv_target_cpus,
218 .vector_allocation_domain = uv_vector_allocation_domain,/* Fixme ZZZ */ 216 .vector_allocation_domain = uv_vector_allocation_domain,
219 .apic_id_registered = uv_apic_id_registered, 217 .apic_id_registered = uv_apic_id_registered,
220 .init_apic_ldr = uv_init_apic_ldr, 218 .init_apic_ldr = uv_init_apic_ldr,
221 .send_IPI_all = uv_send_IPI_all, 219 .send_IPI_all = uv_send_IPI_all,
222 .send_IPI_allbutself = uv_send_IPI_allbutself, 220 .send_IPI_allbutself = uv_send_IPI_allbutself,
223 .send_IPI_mask = uv_send_IPI_mask, 221 .send_IPI_mask = uv_send_IPI_mask,
224 /* ZZZ.send_IPI_self = uv_send_IPI_self, */ 222 .send_IPI_self = uv_send_IPI_self,
225 .cpu_mask_to_apicid = uv_cpu_mask_to_apicid, 223 .cpu_mask_to_apicid = uv_cpu_mask_to_apicid,
226 .phys_pkg_id = phys_pkg_id, /* Fixme ZZZ */ 224 .phys_pkg_id = phys_pkg_id,
227 .get_apic_id = get_apic_id, 225 .get_apic_id = get_apic_id,
228 .set_apic_id = set_apic_id, 226 .set_apic_id = set_apic_id,
229 .apic_id_mask = (0xFFFFFFFFu), 227 .apic_id_mask = (0xFFFFFFFFu),
@@ -286,12 +284,13 @@ static __init void map_low_mmrs(void)
286 284
287enum map_type {map_wb, map_uc}; 285enum map_type {map_wb, map_uc};
288 286
289static __init void map_high(char *id, unsigned long base, int shift, enum map_type map_type) 287static __init void map_high(char *id, unsigned long base, int shift,
288 int max_pnode, enum map_type map_type)
290{ 289{
291 unsigned long bytes, paddr; 290 unsigned long bytes, paddr;
292 291
293 paddr = base << shift; 292 paddr = base << shift;
294 bytes = (1UL << shift); 293 bytes = (1UL << shift) * (max_pnode + 1);
295 printk(KERN_INFO "UV: Map %s_HI 0x%lx - 0x%lx\n", id, paddr, 294 printk(KERN_INFO "UV: Map %s_HI 0x%lx - 0x%lx\n", id, paddr,
296 paddr + bytes); 295 paddr + bytes);
297 if (map_type == map_uc) 296 if (map_type == map_uc)
@@ -307,7 +306,7 @@ static __init void map_gru_high(int max_pnode)
307 306
308 gru.v = uv_read_local_mmr(UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR); 307 gru.v = uv_read_local_mmr(UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR);
309 if (gru.s.enable) 308 if (gru.s.enable)
310 map_high("GRU", gru.s.base, shift, map_wb); 309 map_high("GRU", gru.s.base, shift, max_pnode, map_wb);
311} 310}
312 311
313static __init void map_config_high(int max_pnode) 312static __init void map_config_high(int max_pnode)
@@ -317,7 +316,7 @@ static __init void map_config_high(int max_pnode)
317 316
318 cfg.v = uv_read_local_mmr(UVH_RH_GAM_CFG_OVERLAY_CONFIG_MMR); 317 cfg.v = uv_read_local_mmr(UVH_RH_GAM_CFG_OVERLAY_CONFIG_MMR);
319 if (cfg.s.enable) 318 if (cfg.s.enable)
320 map_high("CONFIG", cfg.s.base, shift, map_uc); 319 map_high("CONFIG", cfg.s.base, shift, max_pnode, map_uc);
321} 320}
322 321
323static __init void map_mmr_high(int max_pnode) 322static __init void map_mmr_high(int max_pnode)
@@ -327,7 +326,7 @@ static __init void map_mmr_high(int max_pnode)
327 326
328 mmr.v = uv_read_local_mmr(UVH_RH_GAM_MMR_OVERLAY_CONFIG_MMR); 327 mmr.v = uv_read_local_mmr(UVH_RH_GAM_MMR_OVERLAY_CONFIG_MMR);
329 if (mmr.s.enable) 328 if (mmr.s.enable)
330 map_high("MMR", mmr.s.base, shift, map_uc); 329 map_high("MMR", mmr.s.base, shift, max_pnode, map_uc);
331} 330}
332 331
333static __init void map_mmioh_high(int max_pnode) 332static __init void map_mmioh_high(int max_pnode)
@@ -337,7 +336,7 @@ static __init void map_mmioh_high(int max_pnode)
337 336
338 mmioh.v = uv_read_local_mmr(UVH_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR); 337 mmioh.v = uv_read_local_mmr(UVH_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR);
339 if (mmioh.s.enable) 338 if (mmioh.s.enable)
340 map_high("MMIOH", mmioh.s.base, shift, map_uc); 339 map_high("MMIOH", mmioh.s.base, shift, max_pnode, map_uc);
341} 340}
342 341
343static __init void uv_rtc_init(void) 342static __init void uv_rtc_init(void)
diff --git a/arch/x86/kernel/head.c b/arch/x86/kernel/head.c
index 3e66bd364a9d..1dcb0f13897e 100644
--- a/arch/x86/kernel/head.c
+++ b/arch/x86/kernel/head.c
@@ -35,6 +35,7 @@ void __init reserve_ebda_region(void)
35 35
36 /* start of EBDA area */ 36 /* start of EBDA area */
37 ebda_addr = get_bios_ebda(); 37 ebda_addr = get_bios_ebda();
38 printk(KERN_INFO "BIOS EBDA/lowmem at: %08x/%08x\n", ebda_addr, lowmem);
38 39
39 /* Fixup: bios puts an EBDA in the top 64K segment */ 40 /* Fixup: bios puts an EBDA in the top 64K segment */
40 /* of conventional memory, but does not adjust lowmem. */ 41 /* of conventional memory, but does not adjust lowmem. */
diff --git a/arch/x86/kernel/hpet.c b/arch/x86/kernel/hpet.c
index 73deaffadd03..acf62fc233da 100644
--- a/arch/x86/kernel/hpet.c
+++ b/arch/x86/kernel/hpet.c
@@ -115,13 +115,17 @@ static void hpet_reserve_platform_timers(unsigned long id)
115 hd.hd_phys_address = hpet_address; 115 hd.hd_phys_address = hpet_address;
116 hd.hd_address = hpet; 116 hd.hd_address = hpet;
117 hd.hd_nirqs = nrtimers; 117 hd.hd_nirqs = nrtimers;
118 hd.hd_flags = HPET_DATA_PLATFORM;
119 hpet_reserve_timer(&hd, 0); 118 hpet_reserve_timer(&hd, 0);
120 119
121#ifdef CONFIG_HPET_EMULATE_RTC 120#ifdef CONFIG_HPET_EMULATE_RTC
122 hpet_reserve_timer(&hd, 1); 121 hpet_reserve_timer(&hd, 1);
123#endif 122#endif
124 123
124 /*
125 * NOTE that hd_irq[] reflects IOAPIC input pins (LEGACY_8254
126 * is wrong for i8259!) not the output IRQ. Many BIOS writers
127 * don't bother configuring *any* comparator interrupts.
128 */
125 hd.hd_irq[0] = HPET_LEGACY_8254; 129 hd.hd_irq[0] = HPET_LEGACY_8254;
126 hd.hd_irq[1] = HPET_LEGACY_RTC; 130 hd.hd_irq[1] = HPET_LEGACY_RTC;
127 131
diff --git a/arch/x86/kernel/irqinit_64.c b/arch/x86/kernel/irqinit_64.c
index 1f26fd9ec4f4..5b5be9d43c2a 100644
--- a/arch/x86/kernel/irqinit_64.c
+++ b/arch/x86/kernel/irqinit_64.c
@@ -135,7 +135,7 @@ DEFINE_PER_CPU(vector_irq_t, vector_irq) = {
135 [IRQ15_VECTOR + 1 ... NR_VECTORS - 1] = -1 135 [IRQ15_VECTOR + 1 ... NR_VECTORS - 1] = -1
136}; 136};
137 137
138static void __init init_ISA_irqs (void) 138void __init init_ISA_irqs(void)
139{ 139{
140 int i; 140 int i;
141 141
@@ -164,22 +164,8 @@ static void __init init_ISA_irqs (void)
164 164
165void init_IRQ(void) __attribute__((weak, alias("native_init_IRQ"))); 165void init_IRQ(void) __attribute__((weak, alias("native_init_IRQ")));
166 166
167void __init native_init_IRQ(void) 167static void __init smp_intr_init(void)
168{ 168{
169 int i;
170
171 init_ISA_irqs();
172 /*
173 * Cover the whole vector space, no vector can escape
174 * us. (some of these will be overridden and become
175 * 'special' SMP interrupts)
176 */
177 for (i = 0; i < (NR_VECTORS - FIRST_EXTERNAL_VECTOR); i++) {
178 int vector = FIRST_EXTERNAL_VECTOR + i;
179 if (vector != IA32_SYSCALL_VECTOR)
180 set_intr_gate(vector, interrupt[i]);
181 }
182
183#ifdef CONFIG_SMP 169#ifdef CONFIG_SMP
184 /* 170 /*
185 * The reschedule interrupt is a CPU-to-CPU reschedule-helper 171 * The reschedule interrupt is a CPU-to-CPU reschedule-helper
@@ -207,6 +193,12 @@ void __init native_init_IRQ(void)
207 /* Low priority IPI to cleanup after moving an irq */ 193 /* Low priority IPI to cleanup after moving an irq */
208 set_intr_gate(IRQ_MOVE_CLEANUP_VECTOR, irq_move_cleanup_interrupt); 194 set_intr_gate(IRQ_MOVE_CLEANUP_VECTOR, irq_move_cleanup_interrupt);
209#endif 195#endif
196}
197
198static void __init apic_intr_init(void)
199{
200 smp_intr_init();
201
210 alloc_intr_gate(THERMAL_APIC_VECTOR, thermal_interrupt); 202 alloc_intr_gate(THERMAL_APIC_VECTOR, thermal_interrupt);
211 alloc_intr_gate(THRESHOLD_APIC_VECTOR, threshold_interrupt); 203 alloc_intr_gate(THRESHOLD_APIC_VECTOR, threshold_interrupt);
212 204
@@ -216,6 +208,25 @@ void __init native_init_IRQ(void)
216 /* IPI vectors for APIC spurious and error interrupts */ 208 /* IPI vectors for APIC spurious and error interrupts */
217 alloc_intr_gate(SPURIOUS_APIC_VECTOR, spurious_interrupt); 209 alloc_intr_gate(SPURIOUS_APIC_VECTOR, spurious_interrupt);
218 alloc_intr_gate(ERROR_APIC_VECTOR, error_interrupt); 210 alloc_intr_gate(ERROR_APIC_VECTOR, error_interrupt);
211}
212
213void __init native_init_IRQ(void)
214{
215 int i;
216
217 init_ISA_irqs();
218 /*
219 * Cover the whole vector space, no vector can escape
220 * us. (some of these will be overridden and become
221 * 'special' SMP interrupts)
222 */
223 for (i = 0; i < (NR_VECTORS - FIRST_EXTERNAL_VECTOR); i++) {
224 int vector = FIRST_EXTERNAL_VECTOR + i;
225 if (vector != IA32_SYSCALL_VECTOR)
226 set_intr_gate(vector, interrupt[i]);
227 }
228
229 apic_intr_init();
219 230
220 if (!acpi_ioapic) 231 if (!acpi_ioapic)
221 setup_irq(2, &irq2); 232 setup_irq(2, &irq2);
diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c
index 922c14058f97..0a1302fe6d45 100644
--- a/arch/x86/kernel/process_32.c
+++ b/arch/x86/kernel/process_32.c
@@ -123,7 +123,7 @@ void cpu_idle(void)
123 } 123 }
124} 124}
125 125
126void __show_registers(struct pt_regs *regs, int all) 126void __show_regs(struct pt_regs *regs, int all)
127{ 127{
128 unsigned long cr0 = 0L, cr2 = 0L, cr3 = 0L, cr4 = 0L; 128 unsigned long cr0 = 0L, cr2 = 0L, cr3 = 0L, cr4 = 0L;
129 unsigned long d0, d1, d2, d3, d6, d7; 129 unsigned long d0, d1, d2, d3, d6, d7;
@@ -189,7 +189,7 @@ void __show_registers(struct pt_regs *regs, int all)
189 189
190void show_regs(struct pt_regs *regs) 190void show_regs(struct pt_regs *regs)
191{ 191{
192 __show_registers(regs, 1); 192 __show_regs(regs, 1);
193 show_trace(NULL, regs, &regs->sp, regs->bp); 193 show_trace(NULL, regs, &regs->sp, regs->bp);
194} 194}
195 195
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c
index ca80394ef5b8..cd8c0ed02b7e 100644
--- a/arch/x86/kernel/process_64.c
+++ b/arch/x86/kernel/process_64.c
@@ -136,7 +136,7 @@ void cpu_idle(void)
136} 136}
137 137
138/* Prints also some state that isn't saved in the pt_regs */ 138/* Prints also some state that isn't saved in the pt_regs */
139void __show_regs(struct pt_regs *regs) 139void __show_regs(struct pt_regs *regs, int all)
140{ 140{
141 unsigned long cr0 = 0L, cr2 = 0L, cr3 = 0L, cr4 = 0L, fs, gs, shadowgs; 141 unsigned long cr0 = 0L, cr2 = 0L, cr3 = 0L, cr4 = 0L, fs, gs, shadowgs;
142 unsigned long d0, d1, d2, d3, d6, d7; 142 unsigned long d0, d1, d2, d3, d6, d7;
@@ -175,6 +175,9 @@ void __show_regs(struct pt_regs *regs)
175 rdmsrl(MSR_GS_BASE, gs); 175 rdmsrl(MSR_GS_BASE, gs);
176 rdmsrl(MSR_KERNEL_GS_BASE, shadowgs); 176 rdmsrl(MSR_KERNEL_GS_BASE, shadowgs);
177 177
178 if (!all)
179 return;
180
178 cr0 = read_cr0(); 181 cr0 = read_cr0();
179 cr2 = read_cr2(); 182 cr2 = read_cr2();
180 cr3 = read_cr3(); 183 cr3 = read_cr3();
@@ -200,7 +203,7 @@ void __show_regs(struct pt_regs *regs)
200void show_regs(struct pt_regs *regs) 203void show_regs(struct pt_regs *regs)
201{ 204{
202 printk(KERN_INFO "CPU %d:", smp_processor_id()); 205 printk(KERN_INFO "CPU %d:", smp_processor_id());
203 __show_regs(regs); 206 __show_regs(regs, 1);
204 show_trace(NULL, regs, (void *)(regs + 1), regs->bp); 207 show_trace(NULL, regs, (void *)(regs + 1), regs->bp);
205} 208}
206 209
diff --git a/arch/x86/kernel/quirks.c b/arch/x86/kernel/quirks.c
index d13858818100..f6a11b9b1f98 100644
--- a/arch/x86/kernel/quirks.c
+++ b/arch/x86/kernel/quirks.c
@@ -354,9 +354,27 @@ static void ati_force_hpet_resume(void)
354 printk(KERN_DEBUG "Force enabled HPET at resume\n"); 354 printk(KERN_DEBUG "Force enabled HPET at resume\n");
355} 355}
356 356
357static u32 ati_ixp4x0_rev(struct pci_dev *dev)
358{
359 u32 d;
360 u8 b;
361
362 pci_read_config_byte(dev, 0xac, &b);
363 b &= ~(1<<5);
364 pci_write_config_byte(dev, 0xac, b);
365 pci_read_config_dword(dev, 0x70, &d);
366 d |= 1<<8;
367 pci_write_config_dword(dev, 0x70, d);
368 pci_read_config_dword(dev, 0x8, &d);
369 d &= 0xff;
370 dev_printk(KERN_DEBUG, &dev->dev, "SB4X0 revision 0x%x\n", d);
371 return d;
372}
373
357static void ati_force_enable_hpet(struct pci_dev *dev) 374static void ati_force_enable_hpet(struct pci_dev *dev)
358{ 375{
359 u32 uninitialized_var(val); 376 u32 d, val;
377 u8 b;
360 378
361 if (hpet_address || force_hpet_address) 379 if (hpet_address || force_hpet_address)
362 return; 380 return;
@@ -366,14 +384,33 @@ static void ati_force_enable_hpet(struct pci_dev *dev)
366 return; 384 return;
367 } 385 }
368 386
387 d = ati_ixp4x0_rev(dev);
388 if (d < 0x82)
389 return;
390
391 /* base address */
369 pci_write_config_dword(dev, 0x14, 0xfed00000); 392 pci_write_config_dword(dev, 0x14, 0xfed00000);
370 pci_read_config_dword(dev, 0x14, &val); 393 pci_read_config_dword(dev, 0x14, &val);
394
395 /* enable interrupt */
396 outb(0x72, 0xcd6); b = inb(0xcd7);
397 b |= 0x1;
398 outb(0x72, 0xcd6); outb(b, 0xcd7);
399 outb(0x72, 0xcd6); b = inb(0xcd7);
400 if (!(b & 0x1))
401 return;
402 pci_read_config_dword(dev, 0x64, &d);
403 d |= (1<<10);
404 pci_write_config_dword(dev, 0x64, d);
405 pci_read_config_dword(dev, 0x64, &d);
406 if (!(d & (1<<10)))
407 return;
408
371 force_hpet_address = val; 409 force_hpet_address = val;
372 force_hpet_resume_type = ATI_FORCE_HPET_RESUME; 410 force_hpet_resume_type = ATI_FORCE_HPET_RESUME;
373 dev_printk(KERN_DEBUG, &dev->dev, "Force enabled HPET at 0x%lx\n", 411 dev_printk(KERN_DEBUG, &dev->dev, "Force enabled HPET at 0x%lx\n",
374 force_hpet_address); 412 force_hpet_address);
375 cached_dev = dev; 413 cached_dev = dev;
376 return;
377} 414}
378DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP400_SMBUS, 415DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP400_SMBUS,
379 ati_force_enable_hpet); 416 ati_force_enable_hpet);
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index 21b8e0a59780..2255782e8d4b 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -302,7 +302,7 @@ static void __init relocate_initrd(void)
302 if (clen > MAX_MAP_CHUNK-slop) 302 if (clen > MAX_MAP_CHUNK-slop)
303 clen = MAX_MAP_CHUNK-slop; 303 clen = MAX_MAP_CHUNK-slop;
304 mapaddr = ramdisk_image & PAGE_MASK; 304 mapaddr = ramdisk_image & PAGE_MASK;
305 p = early_ioremap(mapaddr, clen+slop); 305 p = early_memremap(mapaddr, clen+slop);
306 memcpy(q, p+slop, clen); 306 memcpy(q, p+slop, clen);
307 early_iounmap(p, clen+slop); 307 early_iounmap(p, clen+slop);
308 q += clen; 308 q += clen;
@@ -379,7 +379,7 @@ static void __init parse_setup_data(void)
379 return; 379 return;
380 pa_data = boot_params.hdr.setup_data; 380 pa_data = boot_params.hdr.setup_data;
381 while (pa_data) { 381 while (pa_data) {
382 data = early_ioremap(pa_data, PAGE_SIZE); 382 data = early_memremap(pa_data, PAGE_SIZE);
383 switch (data->type) { 383 switch (data->type) {
384 case SETUP_E820_EXT: 384 case SETUP_E820_EXT:
385 parse_e820_ext(data, pa_data); 385 parse_e820_ext(data, pa_data);
@@ -402,7 +402,7 @@ static void __init e820_reserve_setup_data(void)
402 return; 402 return;
403 pa_data = boot_params.hdr.setup_data; 403 pa_data = boot_params.hdr.setup_data;
404 while (pa_data) { 404 while (pa_data) {
405 data = early_ioremap(pa_data, sizeof(*data)); 405 data = early_memremap(pa_data, sizeof(*data));
406 e820_update_range(pa_data, sizeof(*data)+data->len, 406 e820_update_range(pa_data, sizeof(*data)+data->len,
407 E820_RAM, E820_RESERVED_KERN); 407 E820_RAM, E820_RESERVED_KERN);
408 found = 1; 408 found = 1;
@@ -428,7 +428,7 @@ static void __init reserve_early_setup_data(void)
428 return; 428 return;
429 pa_data = boot_params.hdr.setup_data; 429 pa_data = boot_params.hdr.setup_data;
430 while (pa_data) { 430 while (pa_data) {
431 data = early_ioremap(pa_data, sizeof(*data)); 431 data = early_memremap(pa_data, sizeof(*data));
432 sprintf(buf, "setup data %x", data->type); 432 sprintf(buf, "setup data %x", data->type);
433 reserve_early(pa_data, pa_data+sizeof(*data)+data->len, buf); 433 reserve_early(pa_data, pa_data+sizeof(*data)+data->len, buf);
434 pa_data = data->next; 434 pa_data = data->next;
@@ -998,6 +998,8 @@ void __init setup_arch(char **cmdline_p)
998 */ 998 */
999 acpi_boot_table_init(); 999 acpi_boot_table_init();
1000 1000
1001 early_acpi_boot_init();
1002
1001#ifdef CONFIG_ACPI_NUMA 1003#ifdef CONFIG_ACPI_NUMA
1002 /* 1004 /*
1003 * Parse SRAT to discover nodes. 1005 * Parse SRAT to discover nodes.
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index 76b6f50978f7..8c3aca7cb343 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -334,14 +334,17 @@ static void __cpuinit start_secondary(void *unused)
334 * does not change while we are assigning vectors to cpus. Holding 334 * does not change while we are assigning vectors to cpus. Holding
335 * this lock ensures we don't half assign or remove an irq from a cpu. 335 * this lock ensures we don't half assign or remove an irq from a cpu.
336 */ 336 */
337 ipi_call_lock_irq(); 337 ipi_call_lock();
338 lock_vector_lock(); 338 lock_vector_lock();
339 __setup_vector_irq(smp_processor_id()); 339 __setup_vector_irq(smp_processor_id());
340 cpu_set(smp_processor_id(), cpu_online_map); 340 cpu_set(smp_processor_id(), cpu_online_map);
341 unlock_vector_lock(); 341 unlock_vector_lock();
342 ipi_call_unlock_irq(); 342 ipi_call_unlock();
343 per_cpu(cpu_state, smp_processor_id()) = CPU_ONLINE; 343 per_cpu(cpu_state, smp_processor_id()) = CPU_ONLINE;
344 344
345 /* enable local interrupts */
346 local_irq_enable();
347
345 setup_secondary_clock(); 348 setup_secondary_clock();
346 349
347 wmb(); 350 wmb();
@@ -596,10 +599,12 @@ wakeup_secondary_cpu(int logical_apicid, unsigned long start_eip)
596 * Give the other CPU some time to accept the IPI. 599 * Give the other CPU some time to accept the IPI.
597 */ 600 */
598 udelay(200); 601 udelay(200);
599 maxlvt = lapic_get_maxlvt(); 602 if (APIC_INTEGRATED(apic_version[phys_apicid])) {
600 if (maxlvt > 3) /* Due to the Pentium erratum 3AP. */ 603 maxlvt = lapic_get_maxlvt();
601 apic_write(APIC_ESR, 0); 604 if (maxlvt > 3) /* Due to the Pentium erratum 3AP. */
602 accept_status = (apic_read(APIC_ESR) & 0xEF); 605 apic_write(APIC_ESR, 0);
606 accept_status = (apic_read(APIC_ESR) & 0xEF);
607 }
603 pr_debug("NMI sent.\n"); 608 pr_debug("NMI sent.\n");
604 609
605 if (send_status) 610 if (send_status)
@@ -1256,39 +1261,6 @@ void __init native_smp_cpus_done(unsigned int max_cpus)
1256 check_nmi_watchdog(); 1261 check_nmi_watchdog();
1257} 1262}
1258 1263
1259#ifdef CONFIG_HOTPLUG_CPU
1260
1261static void remove_siblinginfo(int cpu)
1262{
1263 int sibling;
1264 struct cpuinfo_x86 *c = &cpu_data(cpu);
1265
1266 for_each_cpu_mask_nr(sibling, per_cpu(cpu_core_map, cpu)) {
1267 cpu_clear(cpu, per_cpu(cpu_core_map, sibling));
1268 /*/
1269 * last thread sibling in this cpu core going down
1270 */
1271 if (cpus_weight(per_cpu(cpu_sibling_map, cpu)) == 1)
1272 cpu_data(sibling).booted_cores--;
1273 }
1274
1275 for_each_cpu_mask_nr(sibling, per_cpu(cpu_sibling_map, cpu))
1276 cpu_clear(cpu, per_cpu(cpu_sibling_map, sibling));
1277 cpus_clear(per_cpu(cpu_sibling_map, cpu));
1278 cpus_clear(per_cpu(cpu_core_map, cpu));
1279 c->phys_proc_id = 0;
1280 c->cpu_core_id = 0;
1281 cpu_clear(cpu, cpu_sibling_setup_map);
1282}
1283
1284static int additional_cpus __initdata = -1;
1285
1286static __init int setup_additional_cpus(char *s)
1287{
1288 return s && get_option(&s, &additional_cpus) ? 0 : -EINVAL;
1289}
1290early_param("additional_cpus", setup_additional_cpus);
1291
1292/* 1264/*
1293 * cpu_possible_map should be static, it cannot change as cpu's 1265 * cpu_possible_map should be static, it cannot change as cpu's
1294 * are onlined, or offlined. The reason is per-cpu data-structures 1266 * are onlined, or offlined. The reason is per-cpu data-structures
@@ -1308,21 +1280,13 @@ early_param("additional_cpus", setup_additional_cpus);
1308 */ 1280 */
1309__init void prefill_possible_map(void) 1281__init void prefill_possible_map(void)
1310{ 1282{
1311 int i; 1283 int i, possible;
1312 int possible;
1313 1284
1314 /* no processor from mptable or madt */ 1285 /* no processor from mptable or madt */
1315 if (!num_processors) 1286 if (!num_processors)
1316 num_processors = 1; 1287 num_processors = 1;
1317 1288
1318 if (additional_cpus == -1) { 1289 possible = num_processors + disabled_cpus;
1319 if (disabled_cpus > 0)
1320 additional_cpus = disabled_cpus;
1321 else
1322 additional_cpus = 0;
1323 }
1324
1325 possible = num_processors + additional_cpus;
1326 if (possible > NR_CPUS) 1290 if (possible > NR_CPUS)
1327 possible = NR_CPUS; 1291 possible = NR_CPUS;
1328 1292
@@ -1335,6 +1299,31 @@ __init void prefill_possible_map(void)
1335 nr_cpu_ids = possible; 1299 nr_cpu_ids = possible;
1336} 1300}
1337 1301
1302#ifdef CONFIG_HOTPLUG_CPU
1303
1304static void remove_siblinginfo(int cpu)
1305{
1306 int sibling;
1307 struct cpuinfo_x86 *c = &cpu_data(cpu);
1308
1309 for_each_cpu_mask_nr(sibling, per_cpu(cpu_core_map, cpu)) {
1310 cpu_clear(cpu, per_cpu(cpu_core_map, sibling));
1311 /*/
1312 * last thread sibling in this cpu core going down
1313 */
1314 if (cpus_weight(per_cpu(cpu_sibling_map, cpu)) == 1)
1315 cpu_data(sibling).booted_cores--;
1316 }
1317
1318 for_each_cpu_mask_nr(sibling, per_cpu(cpu_sibling_map, cpu))
1319 cpu_clear(cpu, per_cpu(cpu_sibling_map, sibling));
1320 cpus_clear(per_cpu(cpu_sibling_map, cpu));
1321 cpus_clear(per_cpu(cpu_core_map, cpu));
1322 c->phys_proc_id = 0;
1323 c->cpu_core_id = 0;
1324 cpu_clear(cpu, cpu_sibling_setup_map);
1325}
1326
1338static void __ref remove_cpu_from_maps(int cpu) 1327static void __ref remove_cpu_from_maps(int cpu)
1339{ 1328{
1340 cpu_clear(cpu, cpu_online_map); 1329 cpu_clear(cpu, cpu_online_map);
diff --git a/arch/x86/kernel/time_32.c b/arch/x86/kernel/time_32.c
index bbecf8b6bf96..77b400f06ea2 100644
--- a/arch/x86/kernel/time_32.c
+++ b/arch/x86/kernel/time_32.c
@@ -47,10 +47,9 @@ unsigned long profile_pc(struct pt_regs *regs)
47 unsigned long pc = instruction_pointer(regs); 47 unsigned long pc = instruction_pointer(regs);
48 48
49#ifdef CONFIG_SMP 49#ifdef CONFIG_SMP
50 if (!v8086_mode(regs) && SEGMENT_IS_KERNEL_CODE(regs->cs) && 50 if (!user_mode_vm(regs) && in_lock_functions(pc)) {
51 in_lock_functions(pc)) {
52#ifdef CONFIG_FRAME_POINTER 51#ifdef CONFIG_FRAME_POINTER
53 return *(unsigned long *)(regs->bp + 4); 52 return *(unsigned long *)(regs->bp + sizeof(long));
54#else 53#else
55 unsigned long *sp = (unsigned long *)&regs->sp; 54 unsigned long *sp = (unsigned long *)&regs->sp;
56 55
@@ -95,6 +94,7 @@ irqreturn_t timer_interrupt(int irq, void *dev_id)
95 94
96 do_timer_interrupt_hook(); 95 do_timer_interrupt_hook();
97 96
97#ifdef CONFIG_MCA
98 if (MCA_bus) { 98 if (MCA_bus) {
99 /* The PS/2 uses level-triggered interrupts. You can't 99 /* The PS/2 uses level-triggered interrupts. You can't
100 turn them off, nor would you want to (any attempt to 100 turn them off, nor would you want to (any attempt to
@@ -108,6 +108,7 @@ irqreturn_t timer_interrupt(int irq, void *dev_id)
108 u8 irq_v = inb_p( 0x61 ); /* read the current state */ 108 u8 irq_v = inb_p( 0x61 ); /* read the current state */
109 outb_p( irq_v|0x80, 0x61 ); /* reset the IRQ */ 109 outb_p( irq_v|0x80, 0x61 ); /* reset the IRQ */
110 } 110 }
111#endif
111 112
112 return IRQ_HANDLED; 113 return IRQ_HANDLED;
113} 114}
diff --git a/arch/x86/kernel/time_64.c b/arch/x86/kernel/time_64.c
index e3d49c553af2..cb19d650c216 100644
--- a/arch/x86/kernel/time_64.c
+++ b/arch/x86/kernel/time_64.c
@@ -16,6 +16,7 @@
16#include <linux/interrupt.h> 16#include <linux/interrupt.h>
17#include <linux/module.h> 17#include <linux/module.h>
18#include <linux/time.h> 18#include <linux/time.h>
19#include <linux/mca.h>
19 20
20#include <asm/i8253.h> 21#include <asm/i8253.h>
21#include <asm/hpet.h> 22#include <asm/hpet.h>
@@ -33,23 +34,34 @@ unsigned long profile_pc(struct pt_regs *regs)
33 /* Assume the lock function has either no stack frame or a copy 34 /* Assume the lock function has either no stack frame or a copy
34 of flags from PUSHF 35 of flags from PUSHF
35 Eflags always has bits 22 and up cleared unlike kernel addresses. */ 36 Eflags always has bits 22 and up cleared unlike kernel addresses. */
36 if (!user_mode(regs) && in_lock_functions(pc)) { 37 if (!user_mode_vm(regs) && in_lock_functions(pc)) {
38#ifdef CONFIG_FRAME_POINTER
39 return *(unsigned long *)(regs->bp + sizeof(long));
40#else
37 unsigned long *sp = (unsigned long *)regs->sp; 41 unsigned long *sp = (unsigned long *)regs->sp;
38 if (sp[0] >> 22) 42 if (sp[0] >> 22)
39 return sp[0]; 43 return sp[0];
40 if (sp[1] >> 22) 44 if (sp[1] >> 22)
41 return sp[1]; 45 return sp[1];
46#endif
42 } 47 }
43 return pc; 48 return pc;
44} 49}
45EXPORT_SYMBOL(profile_pc); 50EXPORT_SYMBOL(profile_pc);
46 51
47static irqreturn_t timer_event_interrupt(int irq, void *dev_id) 52irqreturn_t timer_interrupt(int irq, void *dev_id)
48{ 53{
49 add_pda(irq0_irqs, 1); 54 add_pda(irq0_irqs, 1);
50 55
51 global_clock_event->event_handler(global_clock_event); 56 global_clock_event->event_handler(global_clock_event);
52 57
58#ifdef CONFIG_MCA
59 if (MCA_bus) {
60 u8 irq_v = inb_p(0x61); /* read the current state */
61 outb_p(irq_v|0x80, 0x61); /* reset the IRQ */
62 }
63#endif
64
53 return IRQ_HANDLED; 65 return IRQ_HANDLED;
54} 66}
55 67
@@ -100,7 +112,7 @@ unsigned long __init calibrate_cpu(void)
100} 112}
101 113
102static struct irqaction irq0 = { 114static struct irqaction irq0 = {
103 .handler = timer_event_interrupt, 115 .handler = timer_interrupt,
104 .flags = IRQF_DISABLED | IRQF_IRQPOLL | IRQF_NOBALANCING, 116 .flags = IRQF_DISABLED | IRQF_IRQPOLL | IRQF_NOBALANCING,
105 .mask = CPU_MASK_NONE, 117 .mask = CPU_MASK_NONE,
106 .name = "timer" 118 .name = "timer"
@@ -111,16 +123,13 @@ void __init hpet_time_init(void)
111 if (!hpet_enable()) 123 if (!hpet_enable())
112 setup_pit_timer(); 124 setup_pit_timer();
113 125
126 irq0.mask = cpumask_of_cpu(0);
114 setup_irq(0, &irq0); 127 setup_irq(0, &irq0);
115} 128}
116 129
117void __init time_init(void) 130void __init time_init(void)
118{ 131{
119 tsc_init(); 132 tsc_init();
120 if (cpu_has(&boot_cpu_data, X86_FEATURE_RDTSCP))
121 vgetcpu_mode = VGETCPU_RDTSCP;
122 else
123 vgetcpu_mode = VGETCPU_LSL;
124 133
125 late_time_init = choose_time_init(); 134 late_time_init = choose_time_init();
126} 135}
diff --git a/arch/x86/kernel/traps_32.c b/arch/x86/kernel/traps.c
index 0429c5de5ea9..e062974cce34 100644
--- a/arch/x86/kernel/traps_32.c
+++ b/arch/x86/kernel/traps.c
@@ -7,13 +7,11 @@
7 */ 7 */
8 8
9/* 9/*
10 * 'Traps.c' handles hardware traps and faults after we have saved some 10 * Handle hardware traps and faults.
11 * state in 'asm.s'.
12 */ 11 */
13#include <linux/interrupt.h> 12#include <linux/interrupt.h>
14#include <linux/kallsyms.h> 13#include <linux/kallsyms.h>
15#include <linux/spinlock.h> 14#include <linux/spinlock.h>
16#include <linux/highmem.h>
17#include <linux/kprobes.h> 15#include <linux/kprobes.h>
18#include <linux/uaccess.h> 16#include <linux/uaccess.h>
19#include <linux/utsname.h> 17#include <linux/utsname.h>
@@ -32,6 +30,8 @@
32#include <linux/bug.h> 30#include <linux/bug.h>
33#include <linux/nmi.h> 31#include <linux/nmi.h>
34#include <linux/mm.h> 32#include <linux/mm.h>
33#include <linux/smp.h>
34#include <linux/io.h>
35 35
36#ifdef CONFIG_EISA 36#ifdef CONFIG_EISA
37#include <linux/ioport.h> 37#include <linux/ioport.h>
@@ -46,21 +46,31 @@
46#include <linux/edac.h> 46#include <linux/edac.h>
47#endif 47#endif
48 48
49#include <asm/arch_hooks.h>
50#include <asm/stacktrace.h> 49#include <asm/stacktrace.h>
51#include <asm/processor.h> 50#include <asm/processor.h>
52#include <asm/debugreg.h> 51#include <asm/debugreg.h>
53#include <asm/atomic.h> 52#include <asm/atomic.h>
54#include <asm/system.h> 53#include <asm/system.h>
55#include <asm/unwind.h> 54#include <asm/unwind.h>
55#include <asm/traps.h>
56#include <asm/desc.h> 56#include <asm/desc.h>
57#include <asm/i387.h> 57#include <asm/i387.h>
58
59#include <mach_traps.h>
60
61#ifdef CONFIG_X86_64
62#include <asm/pgalloc.h>
63#include <asm/proto.h>
64#include <asm/pda.h>
65#else
66#include <asm/processor-flags.h>
67#include <asm/arch_hooks.h>
58#include <asm/nmi.h> 68#include <asm/nmi.h>
59#include <asm/smp.h> 69#include <asm/smp.h>
60#include <asm/io.h> 70#include <asm/io.h>
61#include <asm/traps.h> 71#include <asm/traps.h>
62 72
63#include "mach_traps.h" 73#include "cpu/mcheck/mce.h"
64 74
65DECLARE_BITMAP(used_vectors, NR_VECTORS); 75DECLARE_BITMAP(used_vectors, NR_VECTORS);
66EXPORT_SYMBOL_GPL(used_vectors); 76EXPORT_SYMBOL_GPL(used_vectors);
@@ -77,418 +87,104 @@ char ignore_fpu_irq;
77 */ 87 */
78gate_desc idt_table[256] 88gate_desc idt_table[256]
79 __attribute__((__section__(".data.idt"))) = { { { { 0, 0 } } }, }; 89 __attribute__((__section__(".data.idt"))) = { { { { 0, 0 } } }, };
80
81int panic_on_unrecovered_nmi;
82int kstack_depth_to_print = 24;
83static unsigned int code_bytes = 64;
84static int ignore_nmis;
85static int die_counter;
86
87void printk_address(unsigned long address, int reliable)
88{
89#ifdef CONFIG_KALLSYMS
90 unsigned long offset = 0;
91 unsigned long symsize;
92 const char *symname;
93 char *modname;
94 char *delim = ":";
95 char namebuf[KSYM_NAME_LEN];
96 char reliab[4] = "";
97
98 symname = kallsyms_lookup(address, &symsize, &offset,
99 &modname, namebuf);
100 if (!symname) {
101 printk(" [<%08lx>]\n", address);
102 return;
103 }
104 if (!reliable)
105 strcpy(reliab, "? ");
106
107 if (!modname)
108 modname = delim = "";
109 printk(" [<%08lx>] %s%s%s%s%s+0x%lx/0x%lx\n",
110 address, reliab, delim, modname, delim, symname, offset, symsize);
111#else
112 printk(" [<%08lx>]\n", address);
113#endif 90#endif
114}
115
116static inline int valid_stack_ptr(struct thread_info *tinfo,
117 void *p, unsigned int size)
118{
119 void *t = tinfo;
120 return p > t && p <= t + THREAD_SIZE - size;
121}
122
123/* The form of the top of the frame on the stack */
124struct stack_frame {
125 struct stack_frame *next_frame;
126 unsigned long return_address;
127};
128
129static inline unsigned long
130print_context_stack(struct thread_info *tinfo,
131 unsigned long *stack, unsigned long bp,
132 const struct stacktrace_ops *ops, void *data)
133{
134 struct stack_frame *frame = (struct stack_frame *)bp;
135
136 while (valid_stack_ptr(tinfo, stack, sizeof(*stack))) {
137 unsigned long addr;
138
139 addr = *stack;
140 if (__kernel_text_address(addr)) {
141 if ((unsigned long) stack == bp + 4) {
142 ops->address(data, addr, 1);
143 frame = frame->next_frame;
144 bp = (unsigned long) frame;
145 } else {
146 ops->address(data, addr, bp == 0);
147 }
148 }
149 stack++;
150 }
151 return bp;
152}
153
154void dump_trace(struct task_struct *task, struct pt_regs *regs,
155 unsigned long *stack, unsigned long bp,
156 const struct stacktrace_ops *ops, void *data)
157{
158 if (!task)
159 task = current;
160
161 if (!stack) {
162 unsigned long dummy;
163 stack = &dummy;
164 if (task != current)
165 stack = (unsigned long *)task->thread.sp;
166 }
167
168#ifdef CONFIG_FRAME_POINTER
169 if (!bp) {
170 if (task == current) {
171 /* Grab bp right from our regs */
172 asm("movl %%ebp, %0" : "=r" (bp) :);
173 } else {
174 /* bp is the last reg pushed by switch_to */
175 bp = *(unsigned long *) task->thread.sp;
176 }
177 }
178#endif
179
180 for (;;) {
181 struct thread_info *context;
182
183 context = (struct thread_info *)
184 ((unsigned long)stack & (~(THREAD_SIZE - 1)));
185 bp = print_context_stack(context, stack, bp, ops, data);
186 /*
187 * Should be after the line below, but somewhere
188 * in early boot context comes out corrupted and we
189 * can't reference it:
190 */
191 if (ops->stack(data, "IRQ") < 0)
192 break;
193 stack = (unsigned long *)context->previous_esp;
194 if (!stack)
195 break;
196 touch_nmi_watchdog();
197 }
198}
199EXPORT_SYMBOL(dump_trace);
200
201static void
202print_trace_warning_symbol(void *data, char *msg, unsigned long symbol)
203{
204 printk(data);
205 print_symbol(msg, symbol);
206 printk("\n");
207}
208
209static void print_trace_warning(void *data, char *msg)
210{
211 printk("%s%s\n", (char *)data, msg);
212}
213 91
214static int print_trace_stack(void *data, char *name) 92static int ignore_nmis;
215{
216 return 0;
217}
218
219/*
220 * Print one address/symbol entries per line.
221 */
222static void print_trace_address(void *data, unsigned long addr, int reliable)
223{
224 printk("%s [<%08lx>] ", (char *)data, addr);
225 if (!reliable)
226 printk("? ");
227 print_symbol("%s\n", addr);
228 touch_nmi_watchdog();
229}
230
231static const struct stacktrace_ops print_trace_ops = {
232 .warning = print_trace_warning,
233 .warning_symbol = print_trace_warning_symbol,
234 .stack = print_trace_stack,
235 .address = print_trace_address,
236};
237 93
238static void 94static inline void conditional_sti(struct pt_regs *regs)
239show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs,
240 unsigned long *stack, unsigned long bp, char *log_lvl)
241{ 95{
242 dump_trace(task, regs, stack, bp, &print_trace_ops, log_lvl); 96 if (regs->flags & X86_EFLAGS_IF)
243 printk("%s =======================\n", log_lvl); 97 local_irq_enable();
244} 98}
245 99
246void show_trace(struct task_struct *task, struct pt_regs *regs, 100static inline void preempt_conditional_sti(struct pt_regs *regs)
247 unsigned long *stack, unsigned long bp)
248{ 101{
249 show_trace_log_lvl(task, regs, stack, bp, ""); 102 inc_preempt_count();
103 if (regs->flags & X86_EFLAGS_IF)
104 local_irq_enable();
250} 105}
251 106
252static void 107static inline void preempt_conditional_cli(struct pt_regs *regs)
253show_stack_log_lvl(struct task_struct *task, struct pt_regs *regs,
254 unsigned long *sp, unsigned long bp, char *log_lvl)
255{ 108{
256 unsigned long *stack; 109 if (regs->flags & X86_EFLAGS_IF)
257 int i; 110 local_irq_disable();
258 111 dec_preempt_count();
259 if (sp == NULL) {
260 if (task)
261 sp = (unsigned long *)task->thread.sp;
262 else
263 sp = (unsigned long *)&sp;
264 }
265
266 stack = sp;
267 for (i = 0; i < kstack_depth_to_print; i++) {
268 if (kstack_end(stack))
269 break;
270 if (i && ((i % 8) == 0))
271 printk("\n%s ", log_lvl);
272 printk("%08lx ", *stack++);
273 }
274 printk("\n%sCall Trace:\n", log_lvl);
275
276 show_trace_log_lvl(task, regs, sp, bp, log_lvl);
277} 112}
278 113
279void show_stack(struct task_struct *task, unsigned long *sp) 114#ifdef CONFIG_X86_32
115static inline void
116die_if_kernel(const char *str, struct pt_regs *regs, long err)
280{ 117{
281 printk(" "); 118 if (!user_mode_vm(regs))
282 show_stack_log_lvl(task, NULL, sp, 0, ""); 119 die(str, regs, err);
283} 120}
284 121
285/* 122/*
286 * The architecture-independent dump_stack generator 123 * Perform the lazy TSS's I/O bitmap copy. If the TSS has an
124 * invalid offset set (the LAZY one) and the faulting thread has
125 * a valid I/O bitmap pointer, we copy the I/O bitmap in the TSS,
126 * we set the offset field correctly and return 1.
287 */ 127 */
288void dump_stack(void) 128static int lazy_iobitmap_copy(void)
289{ 129{
290 unsigned long bp = 0; 130 struct thread_struct *thread;
291 unsigned long stack; 131 struct tss_struct *tss;
292 132 int cpu;
293#ifdef CONFIG_FRAME_POINTER
294 if (!bp)
295 asm("movl %%ebp, %0" : "=r" (bp):);
296#endif
297
298 printk("Pid: %d, comm: %.20s %s %s %.*s\n",
299 current->pid, current->comm, print_tainted(),
300 init_utsname()->release,
301 (int)strcspn(init_utsname()->version, " "),
302 init_utsname()->version);
303
304 show_trace(current, NULL, &stack, bp);
305}
306
307EXPORT_SYMBOL(dump_stack);
308
309void show_registers(struct pt_regs *regs)
310{
311 int i;
312 133
313 print_modules(); 134 cpu = get_cpu();
314 __show_registers(regs, 0); 135 tss = &per_cpu(init_tss, cpu);
136 thread = &current->thread;
315 137
316 printk(KERN_EMERG "Process %.*s (pid: %d, ti=%p task=%p task.ti=%p)", 138 if (tss->x86_tss.io_bitmap_base == INVALID_IO_BITMAP_OFFSET_LAZY &&
317 TASK_COMM_LEN, current->comm, task_pid_nr(current), 139 thread->io_bitmap_ptr) {
318 current_thread_info(), current, task_thread_info(current)); 140 memcpy(tss->io_bitmap, thread->io_bitmap_ptr,
319 /* 141 thread->io_bitmap_max);
320 * When in-kernel, we also print out the stack and code at the 142 /*
321 * time of the fault.. 143 * If the previously set map was extending to higher ports
322 */ 144 * than the current one, pad extra space with 0xff (no access).
323 if (!user_mode_vm(regs)) { 145 */
324 unsigned int code_prologue = code_bytes * 43 / 64; 146 if (thread->io_bitmap_max < tss->io_bitmap_max) {
325 unsigned int code_len = code_bytes; 147 memset((char *) tss->io_bitmap +
326 unsigned char c; 148 thread->io_bitmap_max, 0xff,
327 u8 *ip; 149 tss->io_bitmap_max - thread->io_bitmap_max);
328
329 printk("\n" KERN_EMERG "Stack: ");
330 show_stack_log_lvl(NULL, regs, &regs->sp, 0, KERN_EMERG);
331
332 printk(KERN_EMERG "Code: ");
333
334 ip = (u8 *)regs->ip - code_prologue;
335 if (ip < (u8 *)PAGE_OFFSET || probe_kernel_address(ip, c)) {
336 /* try starting at EIP */
337 ip = (u8 *)regs->ip;
338 code_len = code_len - code_prologue + 1;
339 }
340 for (i = 0; i < code_len; i++, ip++) {
341 if (ip < (u8 *)PAGE_OFFSET ||
342 probe_kernel_address(ip, c)) {
343 printk(" Bad EIP value.");
344 break;
345 }
346 if (ip == (u8 *)regs->ip)
347 printk("<%02x> ", c);
348 else
349 printk("%02x ", c);
350 } 150 }
351 } 151 tss->io_bitmap_max = thread->io_bitmap_max;
352 printk("\n"); 152 tss->x86_tss.io_bitmap_base = IO_BITMAP_OFFSET;
353} 153 tss->io_bitmap_owner = thread;
354 154 put_cpu();
355int is_valid_bugaddr(unsigned long ip)
356{
357 unsigned short ud2;
358
359 if (ip < PAGE_OFFSET)
360 return 0;
361 if (probe_kernel_address((unsigned short *)ip, ud2))
362 return 0;
363
364 return ud2 == 0x0b0f;
365}
366
367static raw_spinlock_t die_lock = __RAW_SPIN_LOCK_UNLOCKED;
368static int die_owner = -1;
369static unsigned int die_nest_count;
370
371unsigned __kprobes long oops_begin(void)
372{
373 unsigned long flags;
374
375 oops_enter();
376
377 if (die_owner != raw_smp_processor_id()) {
378 console_verbose();
379 raw_local_irq_save(flags);
380 __raw_spin_lock(&die_lock);
381 die_owner = smp_processor_id();
382 die_nest_count = 0;
383 bust_spinlocks(1);
384 } else {
385 raw_local_irq_save(flags);
386 }
387 die_nest_count++;
388 return flags;
389}
390
391void __kprobes oops_end(unsigned long flags, struct pt_regs *regs, int signr)
392{
393 bust_spinlocks(0);
394 die_owner = -1;
395 add_taint(TAINT_DIE);
396 __raw_spin_unlock(&die_lock);
397 raw_local_irq_restore(flags);
398
399 if (!regs)
400 return;
401
402 if (kexec_should_crash(current))
403 crash_kexec(regs);
404
405 if (in_interrupt())
406 panic("Fatal exception in interrupt");
407
408 if (panic_on_oops)
409 panic("Fatal exception");
410
411 oops_exit();
412 do_exit(signr);
413}
414
415int __kprobes __die(const char *str, struct pt_regs *regs, long err)
416{
417 unsigned short ss;
418 unsigned long sp;
419 155
420 printk(KERN_EMERG "%s: %04lx [#%d] ", str, err & 0xffff, ++die_counter);
421#ifdef CONFIG_PREEMPT
422 printk("PREEMPT ");
423#endif
424#ifdef CONFIG_SMP
425 printk("SMP ");
426#endif
427#ifdef CONFIG_DEBUG_PAGEALLOC
428 printk("DEBUG_PAGEALLOC");
429#endif
430 printk("\n");
431 if (notify_die(DIE_OOPS, str, regs, err,
432 current->thread.trap_no, SIGSEGV) == NOTIFY_STOP)
433 return 1; 156 return 1;
434
435 show_registers(regs);
436 /* Executive summary in case the oops scrolled away */
437 sp = (unsigned long) (&regs->sp);
438 savesegment(ss, ss);
439 if (user_mode(regs)) {
440 sp = regs->sp;
441 ss = regs->ss & 0xffff;
442 } 157 }
443 printk(KERN_EMERG "EIP: [<%08lx>] ", regs->ip); 158 put_cpu();
444 print_symbol("%s", regs->ip);
445 printk(" SS:ESP %04x:%08lx\n", ss, sp);
446 return 0;
447}
448
449/*
450 * This is gone through when something in the kernel has done something bad
451 * and is about to be terminated:
452 */
453void die(const char *str, struct pt_regs *regs, long err)
454{
455 unsigned long flags = oops_begin();
456
457 if (die_nest_count < 3) {
458 report_bug(regs->ip, regs);
459
460 if (__die(str, regs, err))
461 regs = NULL;
462 } else {
463 printk(KERN_EMERG "Recursive die() failure, output suppressed\n");
464 }
465
466 oops_end(flags, regs, SIGSEGV);
467}
468 159
469static inline void 160 return 0;
470die_if_kernel(const char *str, struct pt_regs *regs, long err)
471{
472 if (!user_mode_vm(regs))
473 die(str, regs, err);
474} 161}
162#endif
475 163
476static void __kprobes 164static void __kprobes
477do_trap(int trapnr, int signr, char *str, int vm86, struct pt_regs *regs, 165do_trap(int trapnr, int signr, char *str, struct pt_regs *regs,
478 long error_code, siginfo_t *info) 166 long error_code, siginfo_t *info)
479{ 167{
480 struct task_struct *tsk = current; 168 struct task_struct *tsk = current;
481 169
170#ifdef CONFIG_X86_32
482 if (regs->flags & X86_VM_MASK) { 171 if (regs->flags & X86_VM_MASK) {
483 if (vm86) 172 /*
173 * traps 0, 1, 3, 4, and 5 should be forwarded to vm86.
174 * On nmi (interrupt 2), do_trap should not be called.
175 */
176 if (trapnr < 6)
484 goto vm86_trap; 177 goto vm86_trap;
485 goto trap_signal; 178 goto trap_signal;
486 } 179 }
180#endif
487 181
488 if (!user_mode(regs)) 182 if (!user_mode(regs))
489 goto kernel_trap; 183 goto kernel_trap;
490 184
185#ifdef CONFIG_X86_32
491trap_signal: 186trap_signal:
187#endif
492 /* 188 /*
493 * We want error_code and trap_no set for userspace faults and 189 * We want error_code and trap_no set for userspace faults and
494 * kernelspace faults which result in die(), but not 190 * kernelspace faults which result in die(), but not
@@ -501,6 +197,18 @@ trap_signal:
501 tsk->thread.error_code = error_code; 197 tsk->thread.error_code = error_code;
502 tsk->thread.trap_no = trapnr; 198 tsk->thread.trap_no = trapnr;
503 199
200#ifdef CONFIG_X86_64
201 if (show_unhandled_signals && unhandled_signal(tsk, signr) &&
202 printk_ratelimit()) {
203 printk(KERN_INFO
204 "%s[%d] trap %s ip:%lx sp:%lx error:%lx",
205 tsk->comm, tsk->pid, str,
206 regs->ip, regs->sp, error_code);
207 print_vma_addr(" in ", regs->ip);
208 printk("\n");
209 }
210#endif
211
504 if (info) 212 if (info)
505 force_sig_info(signr, info, tsk); 213 force_sig_info(signr, info, tsk);
506 else 214 else
@@ -515,29 +223,29 @@ kernel_trap:
515 } 223 }
516 return; 224 return;
517 225
226#ifdef CONFIG_X86_32
518vm86_trap: 227vm86_trap:
519 if (handle_vm86_trap((struct kernel_vm86_regs *) regs, 228 if (handle_vm86_trap((struct kernel_vm86_regs *) regs,
520 error_code, trapnr)) 229 error_code, trapnr))
521 goto trap_signal; 230 goto trap_signal;
522 return; 231 return;
232#endif
523} 233}
524 234
525#define DO_ERROR(trapnr, signr, str, name) \ 235#define DO_ERROR(trapnr, signr, str, name) \
526void do_##name(struct pt_regs *regs, long error_code) \ 236dotraplinkage void do_##name(struct pt_regs *regs, long error_code) \
527{ \ 237{ \
528 trace_hardirqs_fixup(); \
529 if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) \ 238 if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) \
530 == NOTIFY_STOP) \ 239 == NOTIFY_STOP) \
531 return; \ 240 return; \
532 do_trap(trapnr, signr, str, 0, regs, error_code, NULL); \ 241 conditional_sti(regs); \
242 do_trap(trapnr, signr, str, regs, error_code, NULL); \
533} 243}
534 244
535#define DO_ERROR_INFO(trapnr, signr, str, name, sicode, siaddr, irq) \ 245#define DO_ERROR_INFO(trapnr, signr, str, name, sicode, siaddr) \
536void do_##name(struct pt_regs *regs, long error_code) \ 246dotraplinkage void do_##name(struct pt_regs *regs, long error_code) \
537{ \ 247{ \
538 siginfo_t info; \ 248 siginfo_t info; \
539 if (irq) \
540 local_irq_enable(); \
541 info.si_signo = signr; \ 249 info.si_signo = signr; \
542 info.si_errno = 0; \ 250 info.si_errno = 0; \
543 info.si_code = sicode; \ 251 info.si_code = sicode; \
@@ -545,90 +253,68 @@ void do_##name(struct pt_regs *regs, long error_code) \
545 if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) \ 253 if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) \
546 == NOTIFY_STOP) \ 254 == NOTIFY_STOP) \
547 return; \ 255 return; \
548 do_trap(trapnr, signr, str, 0, regs, error_code, &info); \ 256 conditional_sti(regs); \
257 do_trap(trapnr, signr, str, regs, error_code, &info); \
549} 258}
550 259
551#define DO_VM86_ERROR(trapnr, signr, str, name) \ 260DO_ERROR_INFO(0, SIGFPE, "divide error", divide_error, FPE_INTDIV, regs->ip)
552void do_##name(struct pt_regs *regs, long error_code) \ 261DO_ERROR(4, SIGSEGV, "overflow", overflow)
553{ \ 262DO_ERROR(5, SIGSEGV, "bounds", bounds)
554 if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) \ 263DO_ERROR_INFO(6, SIGILL, "invalid opcode", invalid_op, ILL_ILLOPN, regs->ip)
555 == NOTIFY_STOP) \
556 return; \
557 do_trap(trapnr, signr, str, 1, regs, error_code, NULL); \
558}
559
560#define DO_VM86_ERROR_INFO(trapnr, signr, str, name, sicode, siaddr) \
561void do_##name(struct pt_regs *regs, long error_code) \
562{ \
563 siginfo_t info; \
564 info.si_signo = signr; \
565 info.si_errno = 0; \
566 info.si_code = sicode; \
567 info.si_addr = (void __user *)siaddr; \
568 trace_hardirqs_fixup(); \
569 if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) \
570 == NOTIFY_STOP) \
571 return; \
572 do_trap(trapnr, signr, str, 1, regs, error_code, &info); \
573}
574
575DO_VM86_ERROR_INFO(0, SIGFPE, "divide error", divide_error, FPE_INTDIV, regs->ip)
576#ifndef CONFIG_KPROBES
577DO_VM86_ERROR(3, SIGTRAP, "int3", int3)
578#endif
579DO_VM86_ERROR(4, SIGSEGV, "overflow", overflow)
580DO_VM86_ERROR(5, SIGSEGV, "bounds", bounds)
581DO_ERROR_INFO(6, SIGILL, "invalid opcode", invalid_op, ILL_ILLOPN, regs->ip, 0)
582DO_ERROR(9, SIGFPE, "coprocessor segment overrun", coprocessor_segment_overrun) 264DO_ERROR(9, SIGFPE, "coprocessor segment overrun", coprocessor_segment_overrun)
583DO_ERROR(10, SIGSEGV, "invalid TSS", invalid_TSS) 265DO_ERROR(10, SIGSEGV, "invalid TSS", invalid_TSS)
584DO_ERROR(11, SIGBUS, "segment not present", segment_not_present) 266DO_ERROR(11, SIGBUS, "segment not present", segment_not_present)
267#ifdef CONFIG_X86_32
585DO_ERROR(12, SIGBUS, "stack segment", stack_segment) 268DO_ERROR(12, SIGBUS, "stack segment", stack_segment)
586DO_ERROR_INFO(17, SIGBUS, "alignment check", alignment_check, BUS_ADRALN, 0, 0) 269#endif
587DO_ERROR_INFO(32, SIGILL, "iret exception", iret_error, ILL_BADSTK, 0, 1) 270DO_ERROR_INFO(17, SIGBUS, "alignment check", alignment_check, BUS_ADRALN, 0)
271
272#ifdef CONFIG_X86_64
273/* Runs on IST stack */
274dotraplinkage void do_stack_segment(struct pt_regs *regs, long error_code)
275{
276 if (notify_die(DIE_TRAP, "stack segment", regs, error_code,
277 12, SIGBUS) == NOTIFY_STOP)
278 return;
279 preempt_conditional_sti(regs);
280 do_trap(12, SIGBUS, "stack segment", regs, error_code, NULL);
281 preempt_conditional_cli(regs);
282}
283
284dotraplinkage void do_double_fault(struct pt_regs *regs, long error_code)
285{
286 static const char str[] = "double fault";
287 struct task_struct *tsk = current;
288
289 /* Return not checked because double check cannot be ignored */
290 notify_die(DIE_TRAP, str, regs, error_code, 8, SIGSEGV);
588 291
589void __kprobes 292 tsk->thread.error_code = error_code;
293 tsk->thread.trap_no = 8;
294
295 /* This is always a kernel trap and never fixable (and thus must
296 never return). */
297 for (;;)
298 die(str, regs, error_code);
299}
300#endif
301
302dotraplinkage void __kprobes
590do_general_protection(struct pt_regs *regs, long error_code) 303do_general_protection(struct pt_regs *regs, long error_code)
591{ 304{
592 struct task_struct *tsk; 305 struct task_struct *tsk;
593 struct thread_struct *thread;
594 struct tss_struct *tss;
595 int cpu;
596 306
597 cpu = get_cpu(); 307 conditional_sti(regs);
598 tss = &per_cpu(init_tss, cpu);
599 thread = &current->thread;
600
601 /*
602 * Perform the lazy TSS's I/O bitmap copy. If the TSS has an
603 * invalid offset set (the LAZY one) and the faulting thread has
604 * a valid I/O bitmap pointer, we copy the I/O bitmap in the TSS
605 * and we set the offset field correctly. Then we let the CPU to
606 * restart the faulting instruction.
607 */
608 if (tss->x86_tss.io_bitmap_base == INVALID_IO_BITMAP_OFFSET_LAZY &&
609 thread->io_bitmap_ptr) {
610 memcpy(tss->io_bitmap, thread->io_bitmap_ptr,
611 thread->io_bitmap_max);
612 /*
613 * If the previously set map was extending to higher ports
614 * than the current one, pad extra space with 0xff (no access).
615 */
616 if (thread->io_bitmap_max < tss->io_bitmap_max) {
617 memset((char *) tss->io_bitmap +
618 thread->io_bitmap_max, 0xff,
619 tss->io_bitmap_max - thread->io_bitmap_max);
620 }
621 tss->io_bitmap_max = thread->io_bitmap_max;
622 tss->x86_tss.io_bitmap_base = IO_BITMAP_OFFSET;
623 tss->io_bitmap_owner = thread;
624 put_cpu();
625 308
309#ifdef CONFIG_X86_32
310 if (lazy_iobitmap_copy()) {
311 /* restart the faulting instruction */
626 return; 312 return;
627 } 313 }
628 put_cpu();
629 314
630 if (regs->flags & X86_VM_MASK) 315 if (regs->flags & X86_VM_MASK)
631 goto gp_in_vm86; 316 goto gp_in_vm86;
317#endif
632 318
633 tsk = current; 319 tsk = current;
634 if (!user_mode(regs)) 320 if (!user_mode(regs))
@@ -650,10 +336,12 @@ do_general_protection(struct pt_regs *regs, long error_code)
650 force_sig(SIGSEGV, tsk); 336 force_sig(SIGSEGV, tsk);
651 return; 337 return;
652 338
339#ifdef CONFIG_X86_32
653gp_in_vm86: 340gp_in_vm86:
654 local_irq_enable(); 341 local_irq_enable();
655 handle_vm86_fault((struct kernel_vm86_regs *) regs, error_code); 342 handle_vm86_fault((struct kernel_vm86_regs *) regs, error_code);
656 return; 343 return;
344#endif
657 345
658gp_in_kernel: 346gp_in_kernel:
659 if (fixup_exception(regs)) 347 if (fixup_exception(regs))
@@ -690,7 +378,8 @@ mem_parity_error(unsigned char reason, struct pt_regs *regs)
690 printk(KERN_EMERG "Dazed and confused, but trying to continue\n"); 378 printk(KERN_EMERG "Dazed and confused, but trying to continue\n");
691 379
692 /* Clear and disable the memory parity error line. */ 380 /* Clear and disable the memory parity error line. */
693 clear_mem_error(reason); 381 reason = (reason & 0xf) | 4;
382 outb(reason, 0x61);
694} 383}
695 384
696static notrace __kprobes void 385static notrace __kprobes void
@@ -716,7 +405,8 @@ io_check_error(unsigned char reason, struct pt_regs *regs)
716static notrace __kprobes void 405static notrace __kprobes void
717unknown_nmi_error(unsigned char reason, struct pt_regs *regs) 406unknown_nmi_error(unsigned char reason, struct pt_regs *regs)
718{ 407{
719 if (notify_die(DIE_NMIUNKNOWN, "nmi", regs, reason, 2, SIGINT) == NOTIFY_STOP) 408 if (notify_die(DIE_NMIUNKNOWN, "nmi", regs, reason, 2, SIGINT) ==
409 NOTIFY_STOP)
720 return; 410 return;
721#ifdef CONFIG_MCA 411#ifdef CONFIG_MCA
722 /* 412 /*
@@ -739,41 +429,6 @@ unknown_nmi_error(unsigned char reason, struct pt_regs *regs)
739 printk(KERN_EMERG "Dazed and confused, but trying to continue\n"); 429 printk(KERN_EMERG "Dazed and confused, but trying to continue\n");
740} 430}
741 431
742static DEFINE_SPINLOCK(nmi_print_lock);
743
744void notrace __kprobes die_nmi(char *str, struct pt_regs *regs, int do_panic)
745{
746 if (notify_die(DIE_NMIWATCHDOG, str, regs, 0, 2, SIGINT) == NOTIFY_STOP)
747 return;
748
749 spin_lock(&nmi_print_lock);
750 /*
751 * We are in trouble anyway, lets at least try
752 * to get a message out:
753 */
754 bust_spinlocks(1);
755 printk(KERN_EMERG "%s", str);
756 printk(" on CPU%d, ip %08lx, registers:\n",
757 smp_processor_id(), regs->ip);
758 show_registers(regs);
759 if (do_panic)
760 panic("Non maskable interrupt");
761 console_silent();
762 spin_unlock(&nmi_print_lock);
763 bust_spinlocks(0);
764
765 /*
766 * If we are in kernel we are probably nested up pretty bad
767 * and might aswell get out now while we still can:
768 */
769 if (!user_mode_vm(regs)) {
770 current->thread.trap_no = 2;
771 crash_kexec(regs);
772 }
773
774 do_exit(SIGSEGV);
775}
776
777static notrace __kprobes void default_do_nmi(struct pt_regs *regs) 432static notrace __kprobes void default_do_nmi(struct pt_regs *regs)
778{ 433{
779 unsigned char reason = 0; 434 unsigned char reason = 0;
@@ -812,22 +467,25 @@ static notrace __kprobes void default_do_nmi(struct pt_regs *regs)
812 mem_parity_error(reason, regs); 467 mem_parity_error(reason, regs);
813 if (reason & 0x40) 468 if (reason & 0x40)
814 io_check_error(reason, regs); 469 io_check_error(reason, regs);
470#ifdef CONFIG_X86_32
815 /* 471 /*
816 * Reassert NMI in case it became active meanwhile 472 * Reassert NMI in case it became active meanwhile
817 * as it's edge-triggered: 473 * as it's edge-triggered:
818 */ 474 */
819 reassert_nmi(); 475 reassert_nmi();
476#endif
820} 477}
821 478
822notrace __kprobes void do_nmi(struct pt_regs *regs, long error_code) 479dotraplinkage notrace __kprobes void
480do_nmi(struct pt_regs *regs, long error_code)
823{ 481{
824 int cpu;
825
826 nmi_enter(); 482 nmi_enter();
827 483
828 cpu = smp_processor_id(); 484#ifdef CONFIG_X86_32
829 485 { int cpu; cpu = smp_processor_id(); ++nmi_count(cpu); }
830 ++nmi_count(cpu); 486#else
487 add_pda(__nmi_count, 1);
488#endif
831 489
832 if (!ignore_nmis) 490 if (!ignore_nmis)
833 default_do_nmi(regs); 491 default_do_nmi(regs);
@@ -847,21 +505,44 @@ void restart_nmi(void)
847 acpi_nmi_enable(); 505 acpi_nmi_enable();
848} 506}
849 507
850#ifdef CONFIG_KPROBES 508/* May run on IST stack. */
851void __kprobes do_int3(struct pt_regs *regs, long error_code) 509dotraplinkage void __kprobes do_int3(struct pt_regs *regs, long error_code)
852{ 510{
853 trace_hardirqs_fixup(); 511#ifdef CONFIG_KPROBES
854
855 if (notify_die(DIE_INT3, "int3", regs, error_code, 3, SIGTRAP) 512 if (notify_die(DIE_INT3, "int3", regs, error_code, 3, SIGTRAP)
856 == NOTIFY_STOP) 513 == NOTIFY_STOP)
857 return; 514 return;
858 /* 515#else
859 * This is an interrupt gate, because kprobes wants interrupts 516 if (notify_die(DIE_TRAP, "int3", regs, error_code, 3, SIGTRAP)
860 * disabled. Normal trap handlers don't. 517 == NOTIFY_STOP)
861 */ 518 return;
862 restore_interrupts(regs); 519#endif
520
521 preempt_conditional_sti(regs);
522 do_trap(3, SIGTRAP, "int3", regs, error_code, NULL);
523 preempt_conditional_cli(regs);
524}
863 525
864 do_trap(3, SIGTRAP, "int3", 1, regs, error_code, NULL); 526#ifdef CONFIG_X86_64
527/* Help handler running on IST stack to switch back to user stack
528 for scheduling or signal handling. The actual stack switch is done in
529 entry.S */
530asmlinkage __kprobes struct pt_regs *sync_regs(struct pt_regs *eregs)
531{
532 struct pt_regs *regs = eregs;
533 /* Did already sync */
534 if (eregs == (struct pt_regs *)eregs->sp)
535 ;
536 /* Exception from user space */
537 else if (user_mode(eregs))
538 regs = task_pt_regs(current);
539 /* Exception from kernel and interrupts are enabled. Move to
540 kernel process stack. */
541 else if (eregs->flags & X86_EFLAGS_IF)
542 regs = (struct pt_regs *)(eregs->sp -= sizeof(struct pt_regs));
543 if (eregs != regs)
544 *regs = *eregs;
545 return regs;
865} 546}
866#endif 547#endif
867 548
@@ -886,15 +567,15 @@ void __kprobes do_int3(struct pt_regs *regs, long error_code)
886 * about restoring all the debug state, and ptrace doesn't have to 567 * about restoring all the debug state, and ptrace doesn't have to
887 * find every occurrence of the TF bit that could be saved away even 568 * find every occurrence of the TF bit that could be saved away even
888 * by user code) 569 * by user code)
570 *
571 * May run on IST stack.
889 */ 572 */
890void __kprobes do_debug(struct pt_regs *regs, long error_code) 573dotraplinkage void __kprobes do_debug(struct pt_regs *regs, long error_code)
891{ 574{
892 struct task_struct *tsk = current; 575 struct task_struct *tsk = current;
893 unsigned int condition; 576 unsigned long condition;
894 int si_code; 577 int si_code;
895 578
896 trace_hardirqs_fixup();
897
898 get_debugreg(condition, 6); 579 get_debugreg(condition, 6);
899 580
900 /* 581 /*
@@ -906,9 +587,9 @@ void __kprobes do_debug(struct pt_regs *regs, long error_code)
906 if (notify_die(DIE_DEBUG, "debug", regs, condition, error_code, 587 if (notify_die(DIE_DEBUG, "debug", regs, condition, error_code,
907 SIGTRAP) == NOTIFY_STOP) 588 SIGTRAP) == NOTIFY_STOP)
908 return; 589 return;
590
909 /* It's safe to allow irq's after DR6 has been saved */ 591 /* It's safe to allow irq's after DR6 has been saved */
910 if (regs->flags & X86_EFLAGS_IF) 592 preempt_conditional_sti(regs);
911 local_irq_enable();
912 593
913 /* Mask out spurious debug traps due to lazy DR7 setting */ 594 /* Mask out spurious debug traps due to lazy DR7 setting */
914 if (condition & (DR_TRAP0|DR_TRAP1|DR_TRAP2|DR_TRAP3)) { 595 if (condition & (DR_TRAP0|DR_TRAP1|DR_TRAP2|DR_TRAP3)) {
@@ -916,8 +597,10 @@ void __kprobes do_debug(struct pt_regs *regs, long error_code)
916 goto clear_dr7; 597 goto clear_dr7;
917 } 598 }
918 599
600#ifdef CONFIG_X86_32
919 if (regs->flags & X86_VM_MASK) 601 if (regs->flags & X86_VM_MASK)
920 goto debug_vm86; 602 goto debug_vm86;
603#endif
921 604
922 /* Save debug status register where ptrace can see it */ 605 /* Save debug status register where ptrace can see it */
923 tsk->thread.debugreg6 = condition; 606 tsk->thread.debugreg6 = condition;
@@ -927,16 +610,11 @@ void __kprobes do_debug(struct pt_regs *regs, long error_code)
927 * kernel space (but re-enable TF when returning to user mode). 610 * kernel space (but re-enable TF when returning to user mode).
928 */ 611 */
929 if (condition & DR_STEP) { 612 if (condition & DR_STEP) {
930 /*
931 * We already checked v86 mode above, so we can
932 * check for kernel mode by just checking the CPL
933 * of CS.
934 */
935 if (!user_mode(regs)) 613 if (!user_mode(regs))
936 goto clear_TF_reenable; 614 goto clear_TF_reenable;
937 } 615 }
938 616
939 si_code = get_si_code((unsigned long)condition); 617 si_code = get_si_code(condition);
940 /* Ok, finally something we can handle */ 618 /* Ok, finally something we can handle */
941 send_sigtrap(tsk, regs, error_code, si_code); 619 send_sigtrap(tsk, regs, error_code, si_code);
942 620
@@ -946,18 +624,37 @@ void __kprobes do_debug(struct pt_regs *regs, long error_code)
946 */ 624 */
947clear_dr7: 625clear_dr7:
948 set_debugreg(0, 7); 626 set_debugreg(0, 7);
627 preempt_conditional_cli(regs);
949 return; 628 return;
950 629
630#ifdef CONFIG_X86_32
951debug_vm86: 631debug_vm86:
952 handle_vm86_trap((struct kernel_vm86_regs *) regs, error_code, 1); 632 handle_vm86_trap((struct kernel_vm86_regs *) regs, error_code, 1);
633 preempt_conditional_cli(regs);
953 return; 634 return;
635#endif
954 636
955clear_TF_reenable: 637clear_TF_reenable:
956 set_tsk_thread_flag(tsk, TIF_SINGLESTEP); 638 set_tsk_thread_flag(tsk, TIF_SINGLESTEP);
957 regs->flags &= ~X86_EFLAGS_TF; 639 regs->flags &= ~X86_EFLAGS_TF;
640 preempt_conditional_cli(regs);
958 return; 641 return;
959} 642}
960 643
644#ifdef CONFIG_X86_64
645static int kernel_math_error(struct pt_regs *regs, const char *str, int trapnr)
646{
647 if (fixup_exception(regs))
648 return 1;
649
650 notify_die(DIE_GPF, str, regs, 0, trapnr, SIGFPE);
651 /* Illegal floating point operation in the kernel */
652 current->thread.trap_no = trapnr;
653 die(str, regs, 0);
654 return 0;
655}
656#endif
657
961/* 658/*
962 * Note that we play around with the 'TS' bit in an attempt to get 659 * Note that we play around with the 'TS' bit in an attempt to get
963 * the correct behaviour even in the presence of the asynchronous 660 * the correct behaviour even in the presence of the asynchronous
@@ -994,7 +691,9 @@ void math_error(void __user *ip)
994 swd = get_fpu_swd(task); 691 swd = get_fpu_swd(task);
995 switch (swd & ~cwd & 0x3f) { 692 switch (swd & ~cwd & 0x3f) {
996 case 0x000: /* No unmasked exception */ 693 case 0x000: /* No unmasked exception */
694#ifdef CONFIG_X86_32
997 return; 695 return;
696#endif
998 default: /* Multiple exceptions */ 697 default: /* Multiple exceptions */
999 break; 698 break;
1000 case 0x001: /* Invalid Op */ 699 case 0x001: /* Invalid Op */
@@ -1022,9 +721,18 @@ void math_error(void __user *ip)
1022 force_sig_info(SIGFPE, &info, task); 721 force_sig_info(SIGFPE, &info, task);
1023} 722}
1024 723
1025void do_coprocessor_error(struct pt_regs *regs, long error_code) 724dotraplinkage void do_coprocessor_error(struct pt_regs *regs, long error_code)
1026{ 725{
726 conditional_sti(regs);
727
728#ifdef CONFIG_X86_32
1027 ignore_fpu_irq = 1; 729 ignore_fpu_irq = 1;
730#else
731 if (!user_mode(regs) &&
732 kernel_math_error(regs, "kernel x87 math error", 16))
733 return;
734#endif
735
1028 math_error((void __user *)regs->ip); 736 math_error((void __user *)regs->ip);
1029} 737}
1030 738
@@ -1076,8 +784,12 @@ static void simd_math_error(void __user *ip)
1076 force_sig_info(SIGFPE, &info, task); 784 force_sig_info(SIGFPE, &info, task);
1077} 785}
1078 786
1079void do_simd_coprocessor_error(struct pt_regs *regs, long error_code) 787dotraplinkage void
788do_simd_coprocessor_error(struct pt_regs *regs, long error_code)
1080{ 789{
790 conditional_sti(regs);
791
792#ifdef CONFIG_X86_32
1081 if (cpu_has_xmm) { 793 if (cpu_has_xmm) {
1082 /* Handle SIMD FPU exceptions on PIII+ processors. */ 794 /* Handle SIMD FPU exceptions on PIII+ processors. */
1083 ignore_fpu_irq = 1; 795 ignore_fpu_irq = 1;
@@ -1096,16 +808,25 @@ void do_simd_coprocessor_error(struct pt_regs *regs, long error_code)
1096 current->thread.error_code = error_code; 808 current->thread.error_code = error_code;
1097 die_if_kernel("cache flush denied", regs, error_code); 809 die_if_kernel("cache flush denied", regs, error_code);
1098 force_sig(SIGSEGV, current); 810 force_sig(SIGSEGV, current);
811#else
812 if (!user_mode(regs) &&
813 kernel_math_error(regs, "kernel simd math error", 19))
814 return;
815 simd_math_error((void __user *)regs->ip);
816#endif
1099} 817}
1100 818
1101void do_spurious_interrupt_bug(struct pt_regs *regs, long error_code) 819dotraplinkage void
820do_spurious_interrupt_bug(struct pt_regs *regs, long error_code)
1102{ 821{
822 conditional_sti(regs);
1103#if 0 823#if 0
1104 /* No need to warn about this any longer. */ 824 /* No need to warn about this any longer. */
1105 printk(KERN_INFO "Ignoring P6 Local APIC Spurious Interrupt Bug...\n"); 825 printk(KERN_INFO "Ignoring P6 Local APIC Spurious Interrupt Bug...\n");
1106#endif 826#endif
1107} 827}
1108 828
829#ifdef CONFIG_X86_32
1109unsigned long patch_espfix_desc(unsigned long uesp, unsigned long kesp) 830unsigned long patch_espfix_desc(unsigned long uesp, unsigned long kesp)
1110{ 831{
1111 struct desc_struct *gdt = get_cpu_gdt_table(smp_processor_id()); 832 struct desc_struct *gdt = get_cpu_gdt_table(smp_processor_id());
@@ -1124,6 +845,15 @@ unsigned long patch_espfix_desc(unsigned long uesp, unsigned long kesp)
1124 845
1125 return new_kesp; 846 return new_kesp;
1126} 847}
848#else
849asmlinkage void __attribute__((weak)) smp_thermal_interrupt(void)
850{
851}
852
853asmlinkage void __attribute__((weak)) mce_threshold_interrupt(void)
854{
855}
856#endif
1127 857
1128/* 858/*
1129 * 'math_state_restore()' saves the current math information in the 859 * 'math_state_restore()' saves the current math information in the
@@ -1156,14 +886,24 @@ asmlinkage void math_state_restore(void)
1156 } 886 }
1157 887
1158 clts(); /* Allow maths ops (or we recurse) */ 888 clts(); /* Allow maths ops (or we recurse) */
889#ifdef CONFIG_X86_32
1159 restore_fpu(tsk); 890 restore_fpu(tsk);
891#else
892 /*
893 * Paranoid restore. send a SIGSEGV if we fail to restore the state.
894 */
895 if (unlikely(restore_fpu_checking(tsk))) {
896 stts();
897 force_sig(SIGSEGV, tsk);
898 return;
899 }
900#endif
1160 thread->status |= TS_USEDFPU; /* So we fnsave on switch_to() */ 901 thread->status |= TS_USEDFPU; /* So we fnsave on switch_to() */
1161 tsk->fpu_counter++; 902 tsk->fpu_counter++;
1162} 903}
1163EXPORT_SYMBOL_GPL(math_state_restore); 904EXPORT_SYMBOL_GPL(math_state_restore);
1164 905
1165#ifndef CONFIG_MATH_EMULATION 906#ifndef CONFIG_MATH_EMULATION
1166
1167asmlinkage void math_emulate(long arg) 907asmlinkage void math_emulate(long arg)
1168{ 908{
1169 printk(KERN_EMERG 909 printk(KERN_EMERG
@@ -1172,12 +912,54 @@ asmlinkage void math_emulate(long arg)
1172 force_sig(SIGFPE, current); 912 force_sig(SIGFPE, current);
1173 schedule(); 913 schedule();
1174} 914}
1175
1176#endif /* CONFIG_MATH_EMULATION */ 915#endif /* CONFIG_MATH_EMULATION */
1177 916
917dotraplinkage void __kprobes
918do_device_not_available(struct pt_regs *regs, long error)
919{
920#ifdef CONFIG_X86_32
921 if (read_cr0() & X86_CR0_EM) {
922 conditional_sti(regs);
923 math_emulate(0);
924 } else {
925 math_state_restore(); /* interrupts still off */
926 conditional_sti(regs);
927 }
928#else
929 math_state_restore();
930#endif
931}
932
933#ifdef CONFIG_X86_32
934#ifdef CONFIG_X86_MCE
935dotraplinkage void __kprobes do_machine_check(struct pt_regs *regs, long error)
936{
937 conditional_sti(regs);
938 machine_check_vector(regs, error);
939}
940#endif
941
942dotraplinkage void do_iret_error(struct pt_regs *regs, long error_code)
943{
944 siginfo_t info;
945 local_irq_enable();
946
947 info.si_signo = SIGILL;
948 info.si_errno = 0;
949 info.si_code = ILL_BADSTK;
950 info.si_addr = 0;
951 if (notify_die(DIE_TRAP, "iret exception",
952 regs, error_code, 32, SIGILL) == NOTIFY_STOP)
953 return;
954 do_trap(32, SIGILL, "iret exception", regs, error_code, &info);
955}
956#endif
957
1178void __init trap_init(void) 958void __init trap_init(void)
1179{ 959{
960#ifdef CONFIG_X86_32
1180 int i; 961 int i;
962#endif
1181 963
1182#ifdef CONFIG_EISA 964#ifdef CONFIG_EISA
1183 void __iomem *p = early_ioremap(0x0FFFD9, 4); 965 void __iomem *p = early_ioremap(0x0FFFD9, 4);
@@ -1187,29 +969,40 @@ void __init trap_init(void)
1187 early_iounmap(p, 4); 969 early_iounmap(p, 4);
1188#endif 970#endif
1189 971
1190 set_trap_gate(0, &divide_error); 972 set_intr_gate(0, &divide_error);
1191 set_intr_gate(1, &debug); 973 set_intr_gate_ist(1, &debug, DEBUG_STACK);
1192 set_intr_gate(2, &nmi); 974 set_intr_gate_ist(2, &nmi, NMI_STACK);
1193 set_system_intr_gate(3, &int3); /* int3 can be called from all */ 975 /* int3 can be called from all */
1194 set_system_gate(4, &overflow); /* int4 can be called from all */ 976 set_system_intr_gate_ist(3, &int3, DEBUG_STACK);
1195 set_trap_gate(5, &bounds); 977 /* int4 can be called from all */
1196 set_trap_gate(6, &invalid_op); 978 set_system_intr_gate(4, &overflow);
1197 set_trap_gate(7, &device_not_available); 979 set_intr_gate(5, &bounds);
980 set_intr_gate(6, &invalid_op);
981 set_intr_gate(7, &device_not_available);
982#ifdef CONFIG_X86_32
1198 set_task_gate(8, GDT_ENTRY_DOUBLEFAULT_TSS); 983 set_task_gate(8, GDT_ENTRY_DOUBLEFAULT_TSS);
1199 set_trap_gate(9, &coprocessor_segment_overrun); 984#else
1200 set_trap_gate(10, &invalid_TSS); 985 set_intr_gate_ist(8, &double_fault, DOUBLEFAULT_STACK);
1201 set_trap_gate(11, &segment_not_present); 986#endif
1202 set_trap_gate(12, &stack_segment); 987 set_intr_gate(9, &coprocessor_segment_overrun);
1203 set_trap_gate(13, &general_protection); 988 set_intr_gate(10, &invalid_TSS);
989 set_intr_gate(11, &segment_not_present);
990 set_intr_gate_ist(12, &stack_segment, STACKFAULT_STACK);
991 set_intr_gate(13, &general_protection);
1204 set_intr_gate(14, &page_fault); 992 set_intr_gate(14, &page_fault);
1205 set_trap_gate(15, &spurious_interrupt_bug); 993 set_intr_gate(15, &spurious_interrupt_bug);
1206 set_trap_gate(16, &coprocessor_error); 994 set_intr_gate(16, &coprocessor_error);
1207 set_trap_gate(17, &alignment_check); 995 set_intr_gate(17, &alignment_check);
1208#ifdef CONFIG_X86_MCE 996#ifdef CONFIG_X86_MCE
1209 set_trap_gate(18, &machine_check); 997 set_intr_gate_ist(18, &machine_check, MCE_STACK);
1210#endif 998#endif
1211 set_trap_gate(19, &simd_coprocessor_error); 999 set_intr_gate(19, &simd_coprocessor_error);
1212 1000
1001#ifdef CONFIG_IA32_EMULATION
1002 set_system_intr_gate(IA32_SYSCALL_VECTOR, ia32_syscall);
1003#endif
1004
1005#ifdef CONFIG_X86_32
1213 if (cpu_has_fxsr) { 1006 if (cpu_has_fxsr) {
1214 printk(KERN_INFO "Enabling fast FPU save and restore... "); 1007 printk(KERN_INFO "Enabling fast FPU save and restore... ");
1215 set_in_cr4(X86_CR4_OSFXSR); 1008 set_in_cr4(X86_CR4_OSFXSR);
@@ -1222,36 +1015,20 @@ void __init trap_init(void)
1222 printk("done.\n"); 1015 printk("done.\n");
1223 } 1016 }
1224 1017
1225 set_system_gate(SYSCALL_VECTOR, &system_call); 1018 set_system_trap_gate(SYSCALL_VECTOR, &system_call);
1226 1019
1227 /* Reserve all the builtin and the syscall vector: */ 1020 /* Reserve all the builtin and the syscall vector: */
1228 for (i = 0; i < FIRST_EXTERNAL_VECTOR; i++) 1021 for (i = 0; i < FIRST_EXTERNAL_VECTOR; i++)
1229 set_bit(i, used_vectors); 1022 set_bit(i, used_vectors);
1230 1023
1231 set_bit(SYSCALL_VECTOR, used_vectors); 1024 set_bit(SYSCALL_VECTOR, used_vectors);
1232 1025#endif
1233 /* 1026 /*
1234 * Should be a barrier for any external CPU state: 1027 * Should be a barrier for any external CPU state:
1235 */ 1028 */
1236 cpu_init(); 1029 cpu_init();
1237 1030
1031#ifdef CONFIG_X86_32
1238 trap_init_hook(); 1032 trap_init_hook();
1033#endif
1239} 1034}
1240
1241static int __init kstack_setup(char *s)
1242{
1243 kstack_depth_to_print = simple_strtoul(s, NULL, 0);
1244
1245 return 1;
1246}
1247__setup("kstack=", kstack_setup);
1248
1249static int __init code_bytes_setup(char *s)
1250{
1251 code_bytes = simple_strtoul(s, NULL, 0);
1252 if (code_bytes > 8192)
1253 code_bytes = 8192;
1254
1255 return 1;
1256}
1257__setup("code_bytes=", code_bytes_setup);
diff --git a/arch/x86/kernel/traps_64.c b/arch/x86/kernel/traps_64.c
deleted file mode 100644
index 9c0ac0cab013..000000000000
--- a/arch/x86/kernel/traps_64.c
+++ /dev/null
@@ -1,1214 +0,0 @@
1/*
2 * Copyright (C) 1991, 1992 Linus Torvalds
3 * Copyright (C) 2000, 2001, 2002 Andi Kleen, SuSE Labs
4 *
5 * Pentium III FXSR, SSE support
6 * Gareth Hughes <gareth@valinux.com>, May 2000
7 */
8
9/*
10 * 'Traps.c' handles hardware traps and faults after we have saved some
11 * state in 'entry.S'.
12 */
13#include <linux/moduleparam.h>
14#include <linux/interrupt.h>
15#include <linux/kallsyms.h>
16#include <linux/spinlock.h>
17#include <linux/kprobes.h>
18#include <linux/uaccess.h>
19#include <linux/utsname.h>
20#include <linux/kdebug.h>
21#include <linux/kernel.h>
22#include <linux/module.h>
23#include <linux/ptrace.h>
24#include <linux/string.h>
25#include <linux/unwind.h>
26#include <linux/delay.h>
27#include <linux/errno.h>
28#include <linux/kexec.h>
29#include <linux/sched.h>
30#include <linux/timer.h>
31#include <linux/init.h>
32#include <linux/bug.h>
33#include <linux/nmi.h>
34#include <linux/mm.h>
35#include <linux/smp.h>
36#include <linux/io.h>
37
38#if defined(CONFIG_EDAC)
39#include <linux/edac.h>
40#endif
41
42#include <asm/stacktrace.h>
43#include <asm/processor.h>
44#include <asm/debugreg.h>
45#include <asm/atomic.h>
46#include <asm/system.h>
47#include <asm/unwind.h>
48#include <asm/desc.h>
49#include <asm/i387.h>
50#include <asm/pgalloc.h>
51#include <asm/proto.h>
52#include <asm/pda.h>
53#include <asm/traps.h>
54
55#include <mach_traps.h>
56
57int panic_on_unrecovered_nmi;
58int kstack_depth_to_print = 12;
59static unsigned int code_bytes = 64;
60static int ignore_nmis;
61static int die_counter;
62
63static inline void conditional_sti(struct pt_regs *regs)
64{
65 if (regs->flags & X86_EFLAGS_IF)
66 local_irq_enable();
67}
68
69static inline void preempt_conditional_sti(struct pt_regs *regs)
70{
71 inc_preempt_count();
72 if (regs->flags & X86_EFLAGS_IF)
73 local_irq_enable();
74}
75
76static inline void preempt_conditional_cli(struct pt_regs *regs)
77{
78 if (regs->flags & X86_EFLAGS_IF)
79 local_irq_disable();
80 /* Make sure to not schedule here because we could be running
81 on an exception stack. */
82 dec_preempt_count();
83}
84
85void printk_address(unsigned long address, int reliable)
86{
87 printk(" [<%016lx>] %s%pS\n",
88 address, reliable ? "" : "? ", (void *) address);
89}
90
91static unsigned long *in_exception_stack(unsigned cpu, unsigned long stack,
92 unsigned *usedp, char **idp)
93{
94 static char ids[][8] = {
95 [DEBUG_STACK - 1] = "#DB",
96 [NMI_STACK - 1] = "NMI",
97 [DOUBLEFAULT_STACK - 1] = "#DF",
98 [STACKFAULT_STACK - 1] = "#SS",
99 [MCE_STACK - 1] = "#MC",
100#if DEBUG_STKSZ > EXCEPTION_STKSZ
101 [N_EXCEPTION_STACKS ...
102 N_EXCEPTION_STACKS + DEBUG_STKSZ / EXCEPTION_STKSZ - 2] = "#DB[?]"
103#endif
104 };
105 unsigned k;
106
107 /*
108 * Iterate over all exception stacks, and figure out whether
109 * 'stack' is in one of them:
110 */
111 for (k = 0; k < N_EXCEPTION_STACKS; k++) {
112 unsigned long end = per_cpu(orig_ist, cpu).ist[k];
113 /*
114 * Is 'stack' above this exception frame's end?
115 * If yes then skip to the next frame.
116 */
117 if (stack >= end)
118 continue;
119 /*
120 * Is 'stack' above this exception frame's start address?
121 * If yes then we found the right frame.
122 */
123 if (stack >= end - EXCEPTION_STKSZ) {
124 /*
125 * Make sure we only iterate through an exception
126 * stack once. If it comes up for the second time
127 * then there's something wrong going on - just
128 * break out and return NULL:
129 */
130 if (*usedp & (1U << k))
131 break;
132 *usedp |= 1U << k;
133 *idp = ids[k];
134 return (unsigned long *)end;
135 }
136 /*
137 * If this is a debug stack, and if it has a larger size than
138 * the usual exception stacks, then 'stack' might still
139 * be within the lower portion of the debug stack:
140 */
141#if DEBUG_STKSZ > EXCEPTION_STKSZ
142 if (k == DEBUG_STACK - 1 && stack >= end - DEBUG_STKSZ) {
143 unsigned j = N_EXCEPTION_STACKS - 1;
144
145 /*
146 * Black magic. A large debug stack is composed of
147 * multiple exception stack entries, which we
148 * iterate through now. Dont look:
149 */
150 do {
151 ++j;
152 end -= EXCEPTION_STKSZ;
153 ids[j][4] = '1' + (j - N_EXCEPTION_STACKS);
154 } while (stack < end - EXCEPTION_STKSZ);
155 if (*usedp & (1U << j))
156 break;
157 *usedp |= 1U << j;
158 *idp = ids[j];
159 return (unsigned long *)end;
160 }
161#endif
162 }
163 return NULL;
164}
165
166/*
167 * x86-64 can have up to three kernel stacks:
168 * process stack
169 * interrupt stack
170 * severe exception (double fault, nmi, stack fault, debug, mce) hardware stack
171 */
172
173static inline int valid_stack_ptr(struct thread_info *tinfo,
174 void *p, unsigned int size, void *end)
175{
176 void *t = tinfo;
177 if (end) {
178 if (p < end && p >= (end-THREAD_SIZE))
179 return 1;
180 else
181 return 0;
182 }
183 return p > t && p < t + THREAD_SIZE - size;
184}
185
186/* The form of the top of the frame on the stack */
187struct stack_frame {
188 struct stack_frame *next_frame;
189 unsigned long return_address;
190};
191
192static inline unsigned long
193print_context_stack(struct thread_info *tinfo,
194 unsigned long *stack, unsigned long bp,
195 const struct stacktrace_ops *ops, void *data,
196 unsigned long *end)
197{
198 struct stack_frame *frame = (struct stack_frame *)bp;
199
200 while (valid_stack_ptr(tinfo, stack, sizeof(*stack), end)) {
201 unsigned long addr;
202
203 addr = *stack;
204 if (__kernel_text_address(addr)) {
205 if ((unsigned long) stack == bp + 8) {
206 ops->address(data, addr, 1);
207 frame = frame->next_frame;
208 bp = (unsigned long) frame;
209 } else {
210 ops->address(data, addr, bp == 0);
211 }
212 }
213 stack++;
214 }
215 return bp;
216}
217
218void dump_trace(struct task_struct *task, struct pt_regs *regs,
219 unsigned long *stack, unsigned long bp,
220 const struct stacktrace_ops *ops, void *data)
221{
222 const unsigned cpu = get_cpu();
223 unsigned long *irqstack_end = (unsigned long *)cpu_pda(cpu)->irqstackptr;
224 unsigned used = 0;
225 struct thread_info *tinfo;
226
227 if (!task)
228 task = current;
229
230 if (!stack) {
231 unsigned long dummy;
232 stack = &dummy;
233 if (task && task != current)
234 stack = (unsigned long *)task->thread.sp;
235 }
236
237#ifdef CONFIG_FRAME_POINTER
238 if (!bp) {
239 if (task == current) {
240 /* Grab bp right from our regs */
241 asm("movq %%rbp, %0" : "=r" (bp) : );
242 } else {
243 /* bp is the last reg pushed by switch_to */
244 bp = *(unsigned long *) task->thread.sp;
245 }
246 }
247#endif
248
249 /*
250 * Print function call entries in all stacks, starting at the
251 * current stack address. If the stacks consist of nested
252 * exceptions
253 */
254 tinfo = task_thread_info(task);
255 for (;;) {
256 char *id;
257 unsigned long *estack_end;
258 estack_end = in_exception_stack(cpu, (unsigned long)stack,
259 &used, &id);
260
261 if (estack_end) {
262 if (ops->stack(data, id) < 0)
263 break;
264
265 bp = print_context_stack(tinfo, stack, bp, ops,
266 data, estack_end);
267 ops->stack(data, "<EOE>");
268 /*
269 * We link to the next stack via the
270 * second-to-last pointer (index -2 to end) in the
271 * exception stack:
272 */
273 stack = (unsigned long *) estack_end[-2];
274 continue;
275 }
276 if (irqstack_end) {
277 unsigned long *irqstack;
278 irqstack = irqstack_end -
279 (IRQSTACKSIZE - 64) / sizeof(*irqstack);
280
281 if (stack >= irqstack && stack < irqstack_end) {
282 if (ops->stack(data, "IRQ") < 0)
283 break;
284 bp = print_context_stack(tinfo, stack, bp,
285 ops, data, irqstack_end);
286 /*
287 * We link to the next stack (which would be
288 * the process stack normally) the last
289 * pointer (index -1 to end) in the IRQ stack:
290 */
291 stack = (unsigned long *) (irqstack_end[-1]);
292 irqstack_end = NULL;
293 ops->stack(data, "EOI");
294 continue;
295 }
296 }
297 break;
298 }
299
300 /*
301 * This handles the process stack:
302 */
303 bp = print_context_stack(tinfo, stack, bp, ops, data, NULL);
304 put_cpu();
305}
306EXPORT_SYMBOL(dump_trace);
307
308static void
309print_trace_warning_symbol(void *data, char *msg, unsigned long symbol)
310{
311 print_symbol(msg, symbol);
312 printk("\n");
313}
314
315static void print_trace_warning(void *data, char *msg)
316{
317 printk("%s\n", msg);
318}
319
320static int print_trace_stack(void *data, char *name)
321{
322 printk(" <%s> ", name);
323 return 0;
324}
325
326static void print_trace_address(void *data, unsigned long addr, int reliable)
327{
328 touch_nmi_watchdog();
329 printk_address(addr, reliable);
330}
331
332static const struct stacktrace_ops print_trace_ops = {
333 .warning = print_trace_warning,
334 .warning_symbol = print_trace_warning_symbol,
335 .stack = print_trace_stack,
336 .address = print_trace_address,
337};
338
339static void
340show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs,
341 unsigned long *stack, unsigned long bp, char *log_lvl)
342{
343 printk("Call Trace:\n");
344 dump_trace(task, regs, stack, bp, &print_trace_ops, log_lvl);
345}
346
347void show_trace(struct task_struct *task, struct pt_regs *regs,
348 unsigned long *stack, unsigned long bp)
349{
350 show_trace_log_lvl(task, regs, stack, bp, "");
351}
352
353static void
354show_stack_log_lvl(struct task_struct *task, struct pt_regs *regs,
355 unsigned long *sp, unsigned long bp, char *log_lvl)
356{
357 unsigned long *stack;
358 int i;
359 const int cpu = smp_processor_id();
360 unsigned long *irqstack_end =
361 (unsigned long *) (cpu_pda(cpu)->irqstackptr);
362 unsigned long *irqstack =
363 (unsigned long *) (cpu_pda(cpu)->irqstackptr - IRQSTACKSIZE);
364
365 /*
366 * debugging aid: "show_stack(NULL, NULL);" prints the
367 * back trace for this cpu.
368 */
369
370 if (sp == NULL) {
371 if (task)
372 sp = (unsigned long *)task->thread.sp;
373 else
374 sp = (unsigned long *)&sp;
375 }
376
377 stack = sp;
378 for (i = 0; i < kstack_depth_to_print; i++) {
379 if (stack >= irqstack && stack <= irqstack_end) {
380 if (stack == irqstack_end) {
381 stack = (unsigned long *) (irqstack_end[-1]);
382 printk(" <EOI> ");
383 }
384 } else {
385 if (((long) stack & (THREAD_SIZE-1)) == 0)
386 break;
387 }
388 if (i && ((i % 4) == 0))
389 printk("\n");
390 printk(" %016lx", *stack++);
391 touch_nmi_watchdog();
392 }
393 printk("\n");
394 show_trace_log_lvl(task, regs, sp, bp, log_lvl);
395}
396
397void show_stack(struct task_struct *task, unsigned long *sp)
398{
399 show_stack_log_lvl(task, NULL, sp, 0, "");
400}
401
402/*
403 * The architecture-independent dump_stack generator
404 */
405void dump_stack(void)
406{
407 unsigned long bp = 0;
408 unsigned long stack;
409
410#ifdef CONFIG_FRAME_POINTER
411 if (!bp)
412 asm("movq %%rbp, %0" : "=r" (bp) : );
413#endif
414
415 printk("Pid: %d, comm: %.20s %s %s %.*s\n",
416 current->pid, current->comm, print_tainted(),
417 init_utsname()->release,
418 (int)strcspn(init_utsname()->version, " "),
419 init_utsname()->version);
420 show_trace(NULL, NULL, &stack, bp);
421}
422EXPORT_SYMBOL(dump_stack);
423
424void show_registers(struct pt_regs *regs)
425{
426 int i;
427 unsigned long sp;
428 const int cpu = smp_processor_id();
429 struct task_struct *cur = cpu_pda(cpu)->pcurrent;
430
431 sp = regs->sp;
432 printk("CPU %d ", cpu);
433 __show_regs(regs);
434 printk("Process %s (pid: %d, threadinfo %p, task %p)\n",
435 cur->comm, cur->pid, task_thread_info(cur), cur);
436
437 /*
438 * When in-kernel, we also print out the stack and code at the
439 * time of the fault..
440 */
441 if (!user_mode(regs)) {
442 unsigned int code_prologue = code_bytes * 43 / 64;
443 unsigned int code_len = code_bytes;
444 unsigned char c;
445 u8 *ip;
446
447 printk("Stack: ");
448 show_stack_log_lvl(NULL, regs, (unsigned long *)sp,
449 regs->bp, "");
450
451 printk(KERN_EMERG "Code: ");
452
453 ip = (u8 *)regs->ip - code_prologue;
454 if (ip < (u8 *)PAGE_OFFSET || probe_kernel_address(ip, c)) {
455 /* try starting at RIP */
456 ip = (u8 *)regs->ip;
457 code_len = code_len - code_prologue + 1;
458 }
459 for (i = 0; i < code_len; i++, ip++) {
460 if (ip < (u8 *)PAGE_OFFSET ||
461 probe_kernel_address(ip, c)) {
462 printk(" Bad RIP value.");
463 break;
464 }
465 if (ip == (u8 *)regs->ip)
466 printk("<%02x> ", c);
467 else
468 printk("%02x ", c);
469 }
470 }
471 printk("\n");
472}
473
474int is_valid_bugaddr(unsigned long ip)
475{
476 unsigned short ud2;
477
478 if (__copy_from_user(&ud2, (const void __user *) ip, sizeof(ud2)))
479 return 0;
480
481 return ud2 == 0x0b0f;
482}
483
484static raw_spinlock_t die_lock = __RAW_SPIN_LOCK_UNLOCKED;
485static int die_owner = -1;
486static unsigned int die_nest_count;
487
488unsigned __kprobes long oops_begin(void)
489{
490 int cpu;
491 unsigned long flags;
492
493 oops_enter();
494
495 /* racy, but better than risking deadlock. */
496 raw_local_irq_save(flags);
497 cpu = smp_processor_id();
498 if (!__raw_spin_trylock(&die_lock)) {
499 if (cpu == die_owner)
500 /* nested oops. should stop eventually */;
501 else
502 __raw_spin_lock(&die_lock);
503 }
504 die_nest_count++;
505 die_owner = cpu;
506 console_verbose();
507 bust_spinlocks(1);
508 return flags;
509}
510
511void __kprobes oops_end(unsigned long flags, struct pt_regs *regs, int signr)
512{
513 die_owner = -1;
514 bust_spinlocks(0);
515 die_nest_count--;
516 if (!die_nest_count)
517 /* Nest count reaches zero, release the lock. */
518 __raw_spin_unlock(&die_lock);
519 raw_local_irq_restore(flags);
520 if (!regs) {
521 oops_exit();
522 return;
523 }
524 if (panic_on_oops)
525 panic("Fatal exception");
526 oops_exit();
527 do_exit(signr);
528}
529
530int __kprobes __die(const char *str, struct pt_regs *regs, long err)
531{
532 printk(KERN_EMERG "%s: %04lx [%u] ", str, err & 0xffff, ++die_counter);
533#ifdef CONFIG_PREEMPT
534 printk("PREEMPT ");
535#endif
536#ifdef CONFIG_SMP
537 printk("SMP ");
538#endif
539#ifdef CONFIG_DEBUG_PAGEALLOC
540 printk("DEBUG_PAGEALLOC");
541#endif
542 printk("\n");
543 if (notify_die(DIE_OOPS, str, regs, err,
544 current->thread.trap_no, SIGSEGV) == NOTIFY_STOP)
545 return 1;
546
547 show_registers(regs);
548 add_taint(TAINT_DIE);
549 /* Executive summary in case the oops scrolled away */
550 printk(KERN_ALERT "RIP ");
551 printk_address(regs->ip, 1);
552 printk(" RSP <%016lx>\n", regs->sp);
553 if (kexec_should_crash(current))
554 crash_kexec(regs);
555 return 0;
556}
557
558void die(const char *str, struct pt_regs *regs, long err)
559{
560 unsigned long flags = oops_begin();
561
562 if (!user_mode(regs))
563 report_bug(regs->ip, regs);
564
565 if (__die(str, regs, err))
566 regs = NULL;
567 oops_end(flags, regs, SIGSEGV);
568}
569
570notrace __kprobes void
571die_nmi(char *str, struct pt_regs *regs, int do_panic)
572{
573 unsigned long flags;
574
575 if (notify_die(DIE_NMIWATCHDOG, str, regs, 0, 2, SIGINT) == NOTIFY_STOP)
576 return;
577
578 flags = oops_begin();
579 /*
580 * We are in trouble anyway, lets at least try
581 * to get a message out.
582 */
583 printk(KERN_EMERG "%s", str);
584 printk(" on CPU%d, ip %08lx, registers:\n",
585 smp_processor_id(), regs->ip);
586 show_registers(regs);
587 if (kexec_should_crash(current))
588 crash_kexec(regs);
589 if (do_panic || panic_on_oops)
590 panic("Non maskable interrupt");
591 oops_end(flags, NULL, SIGBUS);
592 nmi_exit();
593 local_irq_enable();
594 do_exit(SIGBUS);
595}
596
597static void __kprobes
598do_trap(int trapnr, int signr, char *str, struct pt_regs *regs,
599 long error_code, siginfo_t *info)
600{
601 struct task_struct *tsk = current;
602
603 if (!user_mode(regs))
604 goto kernel_trap;
605
606 /*
607 * We want error_code and trap_no set for userspace faults and
608 * kernelspace faults which result in die(), but not
609 * kernelspace faults which are fixed up. die() gives the
610 * process no chance to handle the signal and notice the
611 * kernel fault information, so that won't result in polluting
612 * the information about previously queued, but not yet
613 * delivered, faults. See also do_general_protection below.
614 */
615 tsk->thread.error_code = error_code;
616 tsk->thread.trap_no = trapnr;
617
618 if (show_unhandled_signals && unhandled_signal(tsk, signr) &&
619 printk_ratelimit()) {
620 printk(KERN_INFO
621 "%s[%d] trap %s ip:%lx sp:%lx error:%lx",
622 tsk->comm, tsk->pid, str,
623 regs->ip, regs->sp, error_code);
624 print_vma_addr(" in ", regs->ip);
625 printk("\n");
626 }
627
628 if (info)
629 force_sig_info(signr, info, tsk);
630 else
631 force_sig(signr, tsk);
632 return;
633
634kernel_trap:
635 if (!fixup_exception(regs)) {
636 tsk->thread.error_code = error_code;
637 tsk->thread.trap_no = trapnr;
638 die(str, regs, error_code);
639 }
640 return;
641}
642
643#define DO_ERROR(trapnr, signr, str, name) \
644asmlinkage void do_##name(struct pt_regs *regs, long error_code) \
645{ \
646 if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) \
647 == NOTIFY_STOP) \
648 return; \
649 conditional_sti(regs); \
650 do_trap(trapnr, signr, str, regs, error_code, NULL); \
651}
652
653#define DO_ERROR_INFO(trapnr, signr, str, name, sicode, siaddr) \
654asmlinkage void do_##name(struct pt_regs *regs, long error_code) \
655{ \
656 siginfo_t info; \
657 info.si_signo = signr; \
658 info.si_errno = 0; \
659 info.si_code = sicode; \
660 info.si_addr = (void __user *)siaddr; \
661 trace_hardirqs_fixup(); \
662 if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) \
663 == NOTIFY_STOP) \
664 return; \
665 conditional_sti(regs); \
666 do_trap(trapnr, signr, str, regs, error_code, &info); \
667}
668
669DO_ERROR_INFO(0, SIGFPE, "divide error", divide_error, FPE_INTDIV, regs->ip)
670DO_ERROR(4, SIGSEGV, "overflow", overflow)
671DO_ERROR(5, SIGSEGV, "bounds", bounds)
672DO_ERROR_INFO(6, SIGILL, "invalid opcode", invalid_op, ILL_ILLOPN, regs->ip)
673DO_ERROR(9, SIGFPE, "coprocessor segment overrun", coprocessor_segment_overrun)
674DO_ERROR(10, SIGSEGV, "invalid TSS", invalid_TSS)
675DO_ERROR(11, SIGBUS, "segment not present", segment_not_present)
676DO_ERROR_INFO(17, SIGBUS, "alignment check", alignment_check, BUS_ADRALN, 0)
677
678/* Runs on IST stack */
679asmlinkage void do_stack_segment(struct pt_regs *regs, long error_code)
680{
681 if (notify_die(DIE_TRAP, "stack segment", regs, error_code,
682 12, SIGBUS) == NOTIFY_STOP)
683 return;
684 preempt_conditional_sti(regs);
685 do_trap(12, SIGBUS, "stack segment", regs, error_code, NULL);
686 preempt_conditional_cli(regs);
687}
688
689asmlinkage void do_double_fault(struct pt_regs *regs, long error_code)
690{
691 static const char str[] = "double fault";
692 struct task_struct *tsk = current;
693
694 /* Return not checked because double check cannot be ignored */
695 notify_die(DIE_TRAP, str, regs, error_code, 8, SIGSEGV);
696
697 tsk->thread.error_code = error_code;
698 tsk->thread.trap_no = 8;
699
700 /* This is always a kernel trap and never fixable (and thus must
701 never return). */
702 for (;;)
703 die(str, regs, error_code);
704}
705
706asmlinkage void __kprobes
707do_general_protection(struct pt_regs *regs, long error_code)
708{
709 struct task_struct *tsk;
710
711 conditional_sti(regs);
712
713 tsk = current;
714 if (!user_mode(regs))
715 goto gp_in_kernel;
716
717 tsk->thread.error_code = error_code;
718 tsk->thread.trap_no = 13;
719
720 if (show_unhandled_signals && unhandled_signal(tsk, SIGSEGV) &&
721 printk_ratelimit()) {
722 printk(KERN_INFO
723 "%s[%d] general protection ip:%lx sp:%lx error:%lx",
724 tsk->comm, tsk->pid,
725 regs->ip, regs->sp, error_code);
726 print_vma_addr(" in ", regs->ip);
727 printk("\n");
728 }
729
730 force_sig(SIGSEGV, tsk);
731 return;
732
733gp_in_kernel:
734 if (fixup_exception(regs))
735 return;
736
737 tsk->thread.error_code = error_code;
738 tsk->thread.trap_no = 13;
739 if (notify_die(DIE_GPF, "general protection fault", regs,
740 error_code, 13, SIGSEGV) == NOTIFY_STOP)
741 return;
742 die("general protection fault", regs, error_code);
743}
744
745static notrace __kprobes void
746mem_parity_error(unsigned char reason, struct pt_regs *regs)
747{
748 printk(KERN_EMERG "Uhhuh. NMI received for unknown reason %02x.\n",
749 reason);
750 printk(KERN_EMERG "You have some hardware problem, likely on the PCI bus.\n");
751
752#if defined(CONFIG_EDAC)
753 if (edac_handler_set()) {
754 edac_atomic_assert_error();
755 return;
756 }
757#endif
758
759 if (panic_on_unrecovered_nmi)
760 panic("NMI: Not continuing");
761
762 printk(KERN_EMERG "Dazed and confused, but trying to continue\n");
763
764 /* Clear and disable the memory parity error line. */
765 reason = (reason & 0xf) | 4;
766 outb(reason, 0x61);
767}
768
769static notrace __kprobes void
770io_check_error(unsigned char reason, struct pt_regs *regs)
771{
772 printk("NMI: IOCK error (debug interrupt?)\n");
773 show_registers(regs);
774
775 /* Re-enable the IOCK line, wait for a few seconds */
776 reason = (reason & 0xf) | 8;
777 outb(reason, 0x61);
778 mdelay(2000);
779 reason &= ~8;
780 outb(reason, 0x61);
781}
782
783static notrace __kprobes void
784unknown_nmi_error(unsigned char reason, struct pt_regs *regs)
785{
786 if (notify_die(DIE_NMIUNKNOWN, "nmi", regs, reason, 2, SIGINT) ==
787 NOTIFY_STOP)
788 return;
789 printk(KERN_EMERG "Uhhuh. NMI received for unknown reason %02x.\n",
790 reason);
791 printk(KERN_EMERG "Do you have a strange power saving mode enabled?\n");
792
793 if (panic_on_unrecovered_nmi)
794 panic("NMI: Not continuing");
795
796 printk(KERN_EMERG "Dazed and confused, but trying to continue\n");
797}
798
799/* Runs on IST stack. This code must keep interrupts off all the time.
800 Nested NMIs are prevented by the CPU. */
801asmlinkage notrace __kprobes void default_do_nmi(struct pt_regs *regs)
802{
803 unsigned char reason = 0;
804 int cpu;
805
806 cpu = smp_processor_id();
807
808 /* Only the BSP gets external NMIs from the system. */
809 if (!cpu)
810 reason = get_nmi_reason();
811
812 if (!(reason & 0xc0)) {
813 if (notify_die(DIE_NMI_IPI, "nmi_ipi", regs, reason, 2, SIGINT)
814 == NOTIFY_STOP)
815 return;
816 /*
817 * Ok, so this is none of the documented NMI sources,
818 * so it must be the NMI watchdog.
819 */
820 if (nmi_watchdog_tick(regs, reason))
821 return;
822 if (!do_nmi_callback(regs, cpu))
823 unknown_nmi_error(reason, regs);
824
825 return;
826 }
827 if (notify_die(DIE_NMI, "nmi", regs, reason, 2, SIGINT) == NOTIFY_STOP)
828 return;
829
830 /* AK: following checks seem to be broken on modern chipsets. FIXME */
831 if (reason & 0x80)
832 mem_parity_error(reason, regs);
833 if (reason & 0x40)
834 io_check_error(reason, regs);
835}
836
837asmlinkage notrace __kprobes void
838do_nmi(struct pt_regs *regs, long error_code)
839{
840 nmi_enter();
841
842 add_pda(__nmi_count, 1);
843
844 if (!ignore_nmis)
845 default_do_nmi(regs);
846
847 nmi_exit();
848}
849
850void stop_nmi(void)
851{
852 acpi_nmi_disable();
853 ignore_nmis++;
854}
855
856void restart_nmi(void)
857{
858 ignore_nmis--;
859 acpi_nmi_enable();
860}
861
862/* runs on IST stack. */
863asmlinkage void __kprobes do_int3(struct pt_regs *regs, long error_code)
864{
865 trace_hardirqs_fixup();
866
867 if (notify_die(DIE_INT3, "int3", regs, error_code, 3, SIGTRAP)
868 == NOTIFY_STOP)
869 return;
870
871 preempt_conditional_sti(regs);
872 do_trap(3, SIGTRAP, "int3", regs, error_code, NULL);
873 preempt_conditional_cli(regs);
874}
875
876/* Help handler running on IST stack to switch back to user stack
877 for scheduling or signal handling. The actual stack switch is done in
878 entry.S */
879asmlinkage __kprobes struct pt_regs *sync_regs(struct pt_regs *eregs)
880{
881 struct pt_regs *regs = eregs;
882 /* Did already sync */
883 if (eregs == (struct pt_regs *)eregs->sp)
884 ;
885 /* Exception from user space */
886 else if (user_mode(eregs))
887 regs = task_pt_regs(current);
888 /* Exception from kernel and interrupts are enabled. Move to
889 kernel process stack. */
890 else if (eregs->flags & X86_EFLAGS_IF)
891 regs = (struct pt_regs *)(eregs->sp -= sizeof(struct pt_regs));
892 if (eregs != regs)
893 *regs = *eregs;
894 return regs;
895}
896
897/* runs on IST stack. */
898asmlinkage void __kprobes do_debug(struct pt_regs *regs,
899 unsigned long error_code)
900{
901 struct task_struct *tsk = current;
902 unsigned long condition;
903 siginfo_t info;
904
905 trace_hardirqs_fixup();
906
907 get_debugreg(condition, 6);
908
909 /*
910 * The processor cleared BTF, so don't mark that we need it set.
911 */
912 clear_tsk_thread_flag(tsk, TIF_DEBUGCTLMSR);
913 tsk->thread.debugctlmsr = 0;
914
915 if (notify_die(DIE_DEBUG, "debug", regs, condition, error_code,
916 SIGTRAP) == NOTIFY_STOP)
917 return;
918
919 preempt_conditional_sti(regs);
920
921 /* Mask out spurious debug traps due to lazy DR7 setting */
922 if (condition & (DR_TRAP0|DR_TRAP1|DR_TRAP2|DR_TRAP3)) {
923 if (!tsk->thread.debugreg7)
924 goto clear_dr7;
925 }
926
927 tsk->thread.debugreg6 = condition;
928
929 /*
930 * Single-stepping through TF: make sure we ignore any events in
931 * kernel space (but re-enable TF when returning to user mode).
932 */
933 if (condition & DR_STEP) {
934 if (!user_mode(regs))
935 goto clear_TF_reenable;
936 }
937
938 /* Ok, finally something we can handle */
939 tsk->thread.trap_no = 1;
940 tsk->thread.error_code = error_code;
941 info.si_signo = SIGTRAP;
942 info.si_errno = 0;
943 info.si_code = get_si_code(condition);
944 info.si_addr = user_mode(regs) ? (void __user *)regs->ip : NULL;
945 force_sig_info(SIGTRAP, &info, tsk);
946
947clear_dr7:
948 set_debugreg(0, 7);
949 preempt_conditional_cli(regs);
950 return;
951
952clear_TF_reenable:
953 set_tsk_thread_flag(tsk, TIF_SINGLESTEP);
954 regs->flags &= ~X86_EFLAGS_TF;
955 preempt_conditional_cli(regs);
956 return;
957}
958
959static int kernel_math_error(struct pt_regs *regs, const char *str, int trapnr)
960{
961 if (fixup_exception(regs))
962 return 1;
963
964 notify_die(DIE_GPF, str, regs, 0, trapnr, SIGFPE);
965 /* Illegal floating point operation in the kernel */
966 current->thread.trap_no = trapnr;
967 die(str, regs, 0);
968 return 0;
969}
970
971/*
972 * Note that we play around with the 'TS' bit in an attempt to get
973 * the correct behaviour even in the presence of the asynchronous
974 * IRQ13 behaviour
975 */
976asmlinkage void do_coprocessor_error(struct pt_regs *regs)
977{
978 void __user *ip = (void __user *)(regs->ip);
979 struct task_struct *task;
980 siginfo_t info;
981 unsigned short cwd, swd;
982
983 conditional_sti(regs);
984 if (!user_mode(regs) &&
985 kernel_math_error(regs, "kernel x87 math error", 16))
986 return;
987
988 /*
989 * Save the info for the exception handler and clear the error.
990 */
991 task = current;
992 save_init_fpu(task);
993 task->thread.trap_no = 16;
994 task->thread.error_code = 0;
995 info.si_signo = SIGFPE;
996 info.si_errno = 0;
997 info.si_code = __SI_FAULT;
998 info.si_addr = ip;
999 /*
1000 * (~cwd & swd) will mask out exceptions that are not set to unmasked
1001 * status. 0x3f is the exception bits in these regs, 0x200 is the
1002 * C1 reg you need in case of a stack fault, 0x040 is the stack
1003 * fault bit. We should only be taking one exception at a time,
1004 * so if this combination doesn't produce any single exception,
1005 * then we have a bad program that isn't synchronizing its FPU usage
1006 * and it will suffer the consequences since we won't be able to
1007 * fully reproduce the context of the exception
1008 */
1009 cwd = get_fpu_cwd(task);
1010 swd = get_fpu_swd(task);
1011 switch (swd & ~cwd & 0x3f) {
1012 case 0x000: /* No unmasked exception */
1013 default: /* Multiple exceptions */
1014 break;
1015 case 0x001: /* Invalid Op */
1016 /*
1017 * swd & 0x240 == 0x040: Stack Underflow
1018 * swd & 0x240 == 0x240: Stack Overflow
1019 * User must clear the SF bit (0x40) if set
1020 */
1021 info.si_code = FPE_FLTINV;
1022 break;
1023 case 0x002: /* Denormalize */
1024 case 0x010: /* Underflow */
1025 info.si_code = FPE_FLTUND;
1026 break;
1027 case 0x004: /* Zero Divide */
1028 info.si_code = FPE_FLTDIV;
1029 break;
1030 case 0x008: /* Overflow */
1031 info.si_code = FPE_FLTOVF;
1032 break;
1033 case 0x020: /* Precision */
1034 info.si_code = FPE_FLTRES;
1035 break;
1036 }
1037 force_sig_info(SIGFPE, &info, task);
1038}
1039
1040asmlinkage void bad_intr(void)
1041{
1042 printk("bad interrupt");
1043}
1044
1045asmlinkage void do_simd_coprocessor_error(struct pt_regs *regs)
1046{
1047 void __user *ip = (void __user *)(regs->ip);
1048 struct task_struct *task;
1049 siginfo_t info;
1050 unsigned short mxcsr;
1051
1052 conditional_sti(regs);
1053 if (!user_mode(regs) &&
1054 kernel_math_error(regs, "kernel simd math error", 19))
1055 return;
1056
1057 /*
1058 * Save the info for the exception handler and clear the error.
1059 */
1060 task = current;
1061 save_init_fpu(task);
1062 task->thread.trap_no = 19;
1063 task->thread.error_code = 0;
1064 info.si_signo = SIGFPE;
1065 info.si_errno = 0;
1066 info.si_code = __SI_FAULT;
1067 info.si_addr = ip;
1068 /*
1069 * The SIMD FPU exceptions are handled a little differently, as there
1070 * is only a single status/control register. Thus, to determine which
1071 * unmasked exception was caught we must mask the exception mask bits
1072 * at 0x1f80, and then use these to mask the exception bits at 0x3f.
1073 */
1074 mxcsr = get_fpu_mxcsr(task);
1075 switch (~((mxcsr & 0x1f80) >> 7) & (mxcsr & 0x3f)) {
1076 case 0x000:
1077 default:
1078 break;
1079 case 0x001: /* Invalid Op */
1080 info.si_code = FPE_FLTINV;
1081 break;
1082 case 0x002: /* Denormalize */
1083 case 0x010: /* Underflow */
1084 info.si_code = FPE_FLTUND;
1085 break;
1086 case 0x004: /* Zero Divide */
1087 info.si_code = FPE_FLTDIV;
1088 break;
1089 case 0x008: /* Overflow */
1090 info.si_code = FPE_FLTOVF;
1091 break;
1092 case 0x020: /* Precision */
1093 info.si_code = FPE_FLTRES;
1094 break;
1095 }
1096 force_sig_info(SIGFPE, &info, task);
1097}
1098
1099asmlinkage void do_spurious_interrupt_bug(struct pt_regs *regs)
1100{
1101}
1102
1103asmlinkage void __attribute__((weak)) smp_thermal_interrupt(void)
1104{
1105}
1106
1107asmlinkage void __attribute__((weak)) mce_threshold_interrupt(void)
1108{
1109}
1110
1111/*
1112 * 'math_state_restore()' saves the current math information in the
1113 * old math state array, and gets the new ones from the current task
1114 *
1115 * Careful.. There are problems with IBM-designed IRQ13 behaviour.
1116 * Don't touch unless you *really* know how it works.
1117 */
1118asmlinkage void math_state_restore(void)
1119{
1120 struct task_struct *me = current;
1121
1122 if (!used_math()) {
1123 local_irq_enable();
1124 /*
1125 * does a slab alloc which can sleep
1126 */
1127 if (init_fpu(me)) {
1128 /*
1129 * ran out of memory!
1130 */
1131 do_group_exit(SIGKILL);
1132 return;
1133 }
1134 local_irq_disable();
1135 }
1136
1137 clts(); /* Allow maths ops (or we recurse) */
1138 /*
1139 * Paranoid restore. send a SIGSEGV if we fail to restore the state.
1140 */
1141 if (unlikely(restore_fpu_checking(me))) {
1142 stts();
1143 force_sig(SIGSEGV, me);
1144 return;
1145 }
1146 task_thread_info(me)->status |= TS_USEDFPU;
1147 me->fpu_counter++;
1148}
1149EXPORT_SYMBOL_GPL(math_state_restore);
1150
1151void __init trap_init(void)
1152{
1153 set_intr_gate(0, &divide_error);
1154 set_intr_gate_ist(1, &debug, DEBUG_STACK);
1155 set_intr_gate_ist(2, &nmi, NMI_STACK);
1156 /* int3 can be called from all */
1157 set_system_gate_ist(3, &int3, DEBUG_STACK);
1158 /* int4 can be called from all */
1159 set_system_gate(4, &overflow);
1160 set_intr_gate(5, &bounds);
1161 set_intr_gate(6, &invalid_op);
1162 set_intr_gate(7, &device_not_available);
1163 set_intr_gate_ist(8, &double_fault, DOUBLEFAULT_STACK);
1164 set_intr_gate(9, &coprocessor_segment_overrun);
1165 set_intr_gate(10, &invalid_TSS);
1166 set_intr_gate(11, &segment_not_present);
1167 set_intr_gate_ist(12, &stack_segment, STACKFAULT_STACK);
1168 set_intr_gate(13, &general_protection);
1169 set_intr_gate(14, &page_fault);
1170 set_intr_gate(15, &spurious_interrupt_bug);
1171 set_intr_gate(16, &coprocessor_error);
1172 set_intr_gate(17, &alignment_check);
1173#ifdef CONFIG_X86_MCE
1174 set_intr_gate_ist(18, &machine_check, MCE_STACK);
1175#endif
1176 set_intr_gate(19, &simd_coprocessor_error);
1177
1178#ifdef CONFIG_IA32_EMULATION
1179 set_system_gate(IA32_SYSCALL_VECTOR, ia32_syscall);
1180#endif
1181 /*
1182 * Should be a barrier for any external CPU state:
1183 */
1184 cpu_init();
1185}
1186
1187static int __init oops_setup(char *s)
1188{
1189 if (!s)
1190 return -EINVAL;
1191 if (!strcmp(s, "panic"))
1192 panic_on_oops = 1;
1193 return 0;
1194}
1195early_param("oops", oops_setup);
1196
1197static int __init kstack_setup(char *s)
1198{
1199 if (!s)
1200 return -EINVAL;
1201 kstack_depth_to_print = simple_strtoul(s, NULL, 0);
1202 return 0;
1203}
1204early_param("kstack", kstack_setup);
1205
1206static int __init code_bytes_setup(char *s)
1207{
1208 code_bytes = simple_strtoul(s, NULL, 0);
1209 if (code_bytes > 8192)
1210 code_bytes = 8192;
1211
1212 return 1;
1213}
1214__setup("code_bytes=", code_bytes_setup);
diff --git a/arch/x86/mach-generic/es7000.c b/arch/x86/mach-generic/es7000.c
index 520cca0ee04e..6513d41ea21e 100644
--- a/arch/x86/mach-generic/es7000.c
+++ b/arch/x86/mach-generic/es7000.c
@@ -47,16 +47,26 @@ static __init int mps_oem_check(struct mp_config_table *mpc, char *oem,
47/* Hook from generic ACPI tables.c */ 47/* Hook from generic ACPI tables.c */
48static int __init acpi_madt_oem_check(char *oem_id, char *oem_table_id) 48static int __init acpi_madt_oem_check(char *oem_id, char *oem_table_id)
49{ 49{
50 unsigned long oem_addr; 50 unsigned long oem_addr = 0;
51 int check_dsdt;
52 int ret = 0;
53
54 /* check dsdt at first to avoid clear fix_map for oem_addr */
55 check_dsdt = es7000_check_dsdt();
56
51 if (!find_unisys_acpi_oem_table(&oem_addr)) { 57 if (!find_unisys_acpi_oem_table(&oem_addr)) {
52 if (es7000_check_dsdt()) 58 if (check_dsdt)
53 return parse_unisys_oem((char *)oem_addr); 59 ret = parse_unisys_oem((char *)oem_addr);
54 else { 60 else {
55 setup_unisys(); 61 setup_unisys();
56 return 1; 62 ret = 1;
57 } 63 }
64 /*
65 * we need to unmap it
66 */
67 unmap_unisys_acpi_oem_table(oem_addr);
58 } 68 }
59 return 0; 69 return ret;
60} 70}
61#else 71#else
62static int __init acpi_madt_oem_check(char *oem_id, char *oem_table_id) 72static int __init acpi_madt_oem_check(char *oem_id, char *oem_table_id)
diff --git a/arch/x86/mm/Makefile b/arch/x86/mm/Makefile
index dfb932dcf136..59f89b434b45 100644
--- a/arch/x86/mm/Makefile
+++ b/arch/x86/mm/Makefile
@@ -13,12 +13,8 @@ obj-$(CONFIG_MMIOTRACE) += mmiotrace.o
13mmiotrace-y := pf_in.o mmio-mod.o 13mmiotrace-y := pf_in.o mmio-mod.o
14obj-$(CONFIG_MMIOTRACE_TEST) += testmmiotrace.o 14obj-$(CONFIG_MMIOTRACE_TEST) += testmmiotrace.o
15 15
16ifeq ($(CONFIG_X86_32),y) 16obj-$(CONFIG_NUMA) += numa_$(BITS).o
17obj-$(CONFIG_NUMA) += discontig_32.o
18else
19obj-$(CONFIG_NUMA) += numa_64.o
20obj-$(CONFIG_K8_NUMA) += k8topology_64.o 17obj-$(CONFIG_K8_NUMA) += k8topology_64.o
21endif
22obj-$(CONFIG_ACPI_NUMA) += srat_$(BITS).o 18obj-$(CONFIG_ACPI_NUMA) += srat_$(BITS).o
23 19
24obj-$(CONFIG_MEMTEST) += memtest.o 20obj-$(CONFIG_MEMTEST) += memtest.o
diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c
index a742d753d5b0..3f2b8962cbd0 100644
--- a/arch/x86/mm/fault.c
+++ b/arch/x86/mm/fault.c
@@ -592,11 +592,6 @@ void __kprobes do_page_fault(struct pt_regs *regs, unsigned long error_code)
592 unsigned long flags; 592 unsigned long flags;
593#endif 593#endif
594 594
595 /*
596 * We can fault from pretty much anywhere, with unknown IRQ state.
597 */
598 trace_hardirqs_fixup();
599
600 tsk = current; 595 tsk = current;
601 mm = tsk->mm; 596 mm = tsk->mm;
602 prefetchw(&mm->mmap_sem); 597 prefetchw(&mm->mmap_sem);
diff --git a/arch/x86/mm/gup.c b/arch/x86/mm/gup.c
index 007bb06c7504..4ba373c5b8c8 100644
--- a/arch/x86/mm/gup.c
+++ b/arch/x86/mm/gup.c
@@ -82,7 +82,7 @@ static noinline int gup_pte_range(pmd_t pmd, unsigned long addr,
82 pte_t pte = gup_get_pte(ptep); 82 pte_t pte = gup_get_pte(ptep);
83 struct page *page; 83 struct page *page;
84 84
85 if ((pte_val(pte) & (mask | _PAGE_SPECIAL)) != mask) { 85 if ((pte_flags(pte) & (mask | _PAGE_SPECIAL)) != mask) {
86 pte_unmap(ptep); 86 pte_unmap(ptep);
87 return 0; 87 return 0;
88 } 88 }
@@ -116,10 +116,10 @@ static noinline int gup_huge_pmd(pmd_t pmd, unsigned long addr,
116 mask = _PAGE_PRESENT|_PAGE_USER; 116 mask = _PAGE_PRESENT|_PAGE_USER;
117 if (write) 117 if (write)
118 mask |= _PAGE_RW; 118 mask |= _PAGE_RW;
119 if ((pte_val(pte) & mask) != mask) 119 if ((pte_flags(pte) & mask) != mask)
120 return 0; 120 return 0;
121 /* hugepages are never "special" */ 121 /* hugepages are never "special" */
122 VM_BUG_ON(pte_val(pte) & _PAGE_SPECIAL); 122 VM_BUG_ON(pte_flags(pte) & _PAGE_SPECIAL);
123 VM_BUG_ON(!pfn_valid(pte_pfn(pte))); 123 VM_BUG_ON(!pfn_valid(pte_pfn(pte)));
124 124
125 refs = 0; 125 refs = 0;
@@ -173,10 +173,10 @@ static noinline int gup_huge_pud(pud_t pud, unsigned long addr,
173 mask = _PAGE_PRESENT|_PAGE_USER; 173 mask = _PAGE_PRESENT|_PAGE_USER;
174 if (write) 174 if (write)
175 mask |= _PAGE_RW; 175 mask |= _PAGE_RW;
176 if ((pte_val(pte) & mask) != mask) 176 if ((pte_flags(pte) & mask) != mask)
177 return 0; 177 return 0;
178 /* hugepages are never "special" */ 178 /* hugepages are never "special" */
179 VM_BUG_ON(pte_val(pte) & _PAGE_SPECIAL); 179 VM_BUG_ON(pte_flags(pte) & _PAGE_SPECIAL);
180 VM_BUG_ON(!pfn_valid(pte_pfn(pte))); 180 VM_BUG_ON(!pfn_valid(pte_pfn(pte)));
181 181
182 refs = 0; 182 refs = 0;
diff --git a/arch/x86/mm/init_32.c b/arch/x86/mm/init_32.c
index bbe044dbe014..8396868e82c5 100644
--- a/arch/x86/mm/init_32.c
+++ b/arch/x86/mm/init_32.c
@@ -558,7 +558,7 @@ void zap_low_mappings(void)
558 558
559int nx_enabled; 559int nx_enabled;
560 560
561pteval_t __supported_pte_mask __read_mostly = ~(_PAGE_NX | _PAGE_GLOBAL); 561pteval_t __supported_pte_mask __read_mostly = ~(_PAGE_NX | _PAGE_GLOBAL | _PAGE_IOMAP);
562EXPORT_SYMBOL_GPL(__supported_pte_mask); 562EXPORT_SYMBOL_GPL(__supported_pte_mask);
563 563
564#ifdef CONFIG_X86_PAE 564#ifdef CONFIG_X86_PAE
diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c
index 3e10054c5731..b8e461d49412 100644
--- a/arch/x86/mm/init_64.c
+++ b/arch/x86/mm/init_64.c
@@ -89,7 +89,7 @@ early_param("gbpages", parse_direct_gbpages_on);
89 89
90int after_bootmem; 90int after_bootmem;
91 91
92unsigned long __supported_pte_mask __read_mostly = ~0UL; 92pteval_t __supported_pte_mask __read_mostly = ~_PAGE_IOMAP;
93EXPORT_SYMBOL_GPL(__supported_pte_mask); 93EXPORT_SYMBOL_GPL(__supported_pte_mask);
94 94
95static int do_not_nx __cpuinitdata; 95static int do_not_nx __cpuinitdata;
@@ -196,9 +196,6 @@ set_pte_vaddr_pud(pud_t *pud_page, unsigned long vaddr, pte_t new_pte)
196 } 196 }
197 197
198 pte = pte_offset_kernel(pmd, vaddr); 198 pte = pte_offset_kernel(pmd, vaddr);
199 if (!pte_none(*pte) && pte_val(new_pte) &&
200 pte_val(*pte) != (pte_val(new_pte) & __supported_pte_mask))
201 pte_ERROR(*pte);
202 set_pte(pte, new_pte); 199 set_pte(pte, new_pte);
203 200
204 /* 201 /*
@@ -313,7 +310,7 @@ static __ref void *alloc_low_page(unsigned long *phys)
313 if (pfn >= table_top) 310 if (pfn >= table_top)
314 panic("alloc_low_page: ran out of memory"); 311 panic("alloc_low_page: ran out of memory");
315 312
316 adr = early_ioremap(pfn * PAGE_SIZE, PAGE_SIZE); 313 adr = early_memremap(pfn * PAGE_SIZE, PAGE_SIZE);
317 memset(adr, 0, PAGE_SIZE); 314 memset(adr, 0, PAGE_SIZE);
318 *phys = pfn * PAGE_SIZE; 315 *phys = pfn * PAGE_SIZE;
319 return adr; 316 return adr;
@@ -749,7 +746,7 @@ unsigned long __init_refok init_memory_mapping(unsigned long start,
749 old_start = mr[i].start; 746 old_start = mr[i].start;
750 memmove(&mr[i], &mr[i+1], 747 memmove(&mr[i], &mr[i+1],
751 (nr_range - 1 - i) * sizeof (struct map_range)); 748 (nr_range - 1 - i) * sizeof (struct map_range));
752 mr[i].start = old_start; 749 mr[i--].start = old_start;
753 nr_range--; 750 nr_range--;
754 } 751 }
755 752
diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c
index 8cbeda15cd29..e4c43ec71b29 100644
--- a/arch/x86/mm/ioremap.c
+++ b/arch/x86/mm/ioremap.c
@@ -45,6 +45,27 @@ unsigned long __phys_addr(unsigned long x)
45} 45}
46EXPORT_SYMBOL(__phys_addr); 46EXPORT_SYMBOL(__phys_addr);
47 47
48bool __virt_addr_valid(unsigned long x)
49{
50 if (x >= __START_KERNEL_map) {
51 x -= __START_KERNEL_map;
52 if (x >= KERNEL_IMAGE_SIZE)
53 return false;
54 x += phys_base;
55 } else {
56 if (x < PAGE_OFFSET)
57 return false;
58 x -= PAGE_OFFSET;
59 if (system_state == SYSTEM_BOOTING ?
60 x > MAXMEM : !phys_addr_valid(x)) {
61 return false;
62 }
63 }
64
65 return pfn_valid(x >> PAGE_SHIFT);
66}
67EXPORT_SYMBOL(__virt_addr_valid);
68
48#else 69#else
49 70
50static inline int phys_addr_valid(unsigned long addr) 71static inline int phys_addr_valid(unsigned long addr)
@@ -56,13 +77,24 @@ static inline int phys_addr_valid(unsigned long addr)
56unsigned long __phys_addr(unsigned long x) 77unsigned long __phys_addr(unsigned long x)
57{ 78{
58 /* VMALLOC_* aren't constants; not available at the boot time */ 79 /* VMALLOC_* aren't constants; not available at the boot time */
59 VIRTUAL_BUG_ON(x < PAGE_OFFSET || (system_state != SYSTEM_BOOTING && 80 VIRTUAL_BUG_ON(x < PAGE_OFFSET);
60 is_vmalloc_addr((void *)x))); 81 VIRTUAL_BUG_ON(system_state != SYSTEM_BOOTING &&
82 is_vmalloc_addr((void *) x));
61 return x - PAGE_OFFSET; 83 return x - PAGE_OFFSET;
62} 84}
63EXPORT_SYMBOL(__phys_addr); 85EXPORT_SYMBOL(__phys_addr);
64#endif 86#endif
65 87
88bool __virt_addr_valid(unsigned long x)
89{
90 if (x < PAGE_OFFSET)
91 return false;
92 if (system_state != SYSTEM_BOOTING && is_vmalloc_addr((void *) x))
93 return false;
94 return pfn_valid((x - PAGE_OFFSET) >> PAGE_SHIFT);
95}
96EXPORT_SYMBOL(__virt_addr_valid);
97
66#endif 98#endif
67 99
68int page_is_ram(unsigned long pagenr) 100int page_is_ram(unsigned long pagenr)
@@ -242,16 +274,16 @@ static void __iomem *__ioremap_caller(resource_size_t phys_addr,
242 switch (prot_val) { 274 switch (prot_val) {
243 case _PAGE_CACHE_UC: 275 case _PAGE_CACHE_UC:
244 default: 276 default:
245 prot = PAGE_KERNEL_NOCACHE; 277 prot = PAGE_KERNEL_IO_NOCACHE;
246 break; 278 break;
247 case _PAGE_CACHE_UC_MINUS: 279 case _PAGE_CACHE_UC_MINUS:
248 prot = PAGE_KERNEL_UC_MINUS; 280 prot = PAGE_KERNEL_IO_UC_MINUS;
249 break; 281 break;
250 case _PAGE_CACHE_WC: 282 case _PAGE_CACHE_WC:
251 prot = PAGE_KERNEL_WC; 283 prot = PAGE_KERNEL_IO_WC;
252 break; 284 break;
253 case _PAGE_CACHE_WB: 285 case _PAGE_CACHE_WB:
254 prot = PAGE_KERNEL; 286 prot = PAGE_KERNEL_IO;
255 break; 287 break;
256 } 288 }
257 289
@@ -568,12 +600,12 @@ static void __init __early_set_fixmap(enum fixed_addresses idx,
568} 600}
569 601
570static inline void __init early_set_fixmap(enum fixed_addresses idx, 602static inline void __init early_set_fixmap(enum fixed_addresses idx,
571 unsigned long phys) 603 unsigned long phys, pgprot_t prot)
572{ 604{
573 if (after_paging_init) 605 if (after_paging_init)
574 set_fixmap(idx, phys); 606 __set_fixmap(idx, phys, prot);
575 else 607 else
576 __early_set_fixmap(idx, phys, PAGE_KERNEL); 608 __early_set_fixmap(idx, phys, prot);
577} 609}
578 610
579static inline void __init early_clear_fixmap(enum fixed_addresses idx) 611static inline void __init early_clear_fixmap(enum fixed_addresses idx)
@@ -584,16 +616,22 @@ static inline void __init early_clear_fixmap(enum fixed_addresses idx)
584 __early_set_fixmap(idx, 0, __pgprot(0)); 616 __early_set_fixmap(idx, 0, __pgprot(0));
585} 617}
586 618
587 619static void *prev_map[FIX_BTMAPS_SLOTS] __initdata;
588static int __initdata early_ioremap_nested; 620static unsigned long prev_size[FIX_BTMAPS_SLOTS] __initdata;
589
590static int __init check_early_ioremap_leak(void) 621static int __init check_early_ioremap_leak(void)
591{ 622{
592 if (!early_ioremap_nested) 623 int count = 0;
624 int i;
625
626 for (i = 0; i < FIX_BTMAPS_SLOTS; i++)
627 if (prev_map[i])
628 count++;
629
630 if (!count)
593 return 0; 631 return 0;
594 WARN(1, KERN_WARNING 632 WARN(1, KERN_WARNING
595 "Debug warning: early ioremap leak of %d areas detected.\n", 633 "Debug warning: early ioremap leak of %d areas detected.\n",
596 early_ioremap_nested); 634 count);
597 printk(KERN_WARNING 635 printk(KERN_WARNING
598 "please boot with early_ioremap_debug and report the dmesg.\n"); 636 "please boot with early_ioremap_debug and report the dmesg.\n");
599 637
@@ -601,18 +639,33 @@ static int __init check_early_ioremap_leak(void)
601} 639}
602late_initcall(check_early_ioremap_leak); 640late_initcall(check_early_ioremap_leak);
603 641
604void __init *early_ioremap(unsigned long phys_addr, unsigned long size) 642static void __init *__early_ioremap(unsigned long phys_addr, unsigned long size, pgprot_t prot)
605{ 643{
606 unsigned long offset, last_addr; 644 unsigned long offset, last_addr;
607 unsigned int nrpages, nesting; 645 unsigned int nrpages;
608 enum fixed_addresses idx0, idx; 646 enum fixed_addresses idx0, idx;
647 int i, slot;
609 648
610 WARN_ON(system_state != SYSTEM_BOOTING); 649 WARN_ON(system_state != SYSTEM_BOOTING);
611 650
612 nesting = early_ioremap_nested; 651 slot = -1;
652 for (i = 0; i < FIX_BTMAPS_SLOTS; i++) {
653 if (!prev_map[i]) {
654 slot = i;
655 break;
656 }
657 }
658
659 if (slot < 0) {
660 printk(KERN_INFO "early_iomap(%08lx, %08lx) not found slot\n",
661 phys_addr, size);
662 WARN_ON(1);
663 return NULL;
664 }
665
613 if (early_ioremap_debug) { 666 if (early_ioremap_debug) {
614 printk(KERN_INFO "early_ioremap(%08lx, %08lx) [%d] => ", 667 printk(KERN_INFO "early_ioremap(%08lx, %08lx) [%d] => ",
615 phys_addr, size, nesting); 668 phys_addr, size, slot);
616 dump_stack(); 669 dump_stack();
617 } 670 }
618 671
@@ -623,11 +676,7 @@ void __init *early_ioremap(unsigned long phys_addr, unsigned long size)
623 return NULL; 676 return NULL;
624 } 677 }
625 678
626 if (nesting >= FIX_BTMAPS_NESTING) { 679 prev_size[slot] = size;
627 WARN_ON(1);
628 return NULL;
629 }
630 early_ioremap_nested++;
631 /* 680 /*
632 * Mappings have to be page-aligned 681 * Mappings have to be page-aligned
633 */ 682 */
@@ -647,10 +696,10 @@ void __init *early_ioremap(unsigned long phys_addr, unsigned long size)
647 /* 696 /*
648 * Ok, go for it.. 697 * Ok, go for it..
649 */ 698 */
650 idx0 = FIX_BTMAP_BEGIN - NR_FIX_BTMAPS*nesting; 699 idx0 = FIX_BTMAP_BEGIN - NR_FIX_BTMAPS*slot;
651 idx = idx0; 700 idx = idx0;
652 while (nrpages > 0) { 701 while (nrpages > 0) {
653 early_set_fixmap(idx, phys_addr); 702 early_set_fixmap(idx, phys_addr, prot);
654 phys_addr += PAGE_SIZE; 703 phys_addr += PAGE_SIZE;
655 --idx; 704 --idx;
656 --nrpages; 705 --nrpages;
@@ -658,7 +707,20 @@ void __init *early_ioremap(unsigned long phys_addr, unsigned long size)
658 if (early_ioremap_debug) 707 if (early_ioremap_debug)
659 printk(KERN_CONT "%08lx + %08lx\n", offset, fix_to_virt(idx0)); 708 printk(KERN_CONT "%08lx + %08lx\n", offset, fix_to_virt(idx0));
660 709
661 return (void *) (offset + fix_to_virt(idx0)); 710 prev_map[slot] = (void *) (offset + fix_to_virt(idx0));
711 return prev_map[slot];
712}
713
714/* Remap an IO device */
715void __init *early_ioremap(unsigned long phys_addr, unsigned long size)
716{
717 return __early_ioremap(phys_addr, size, PAGE_KERNEL_IO);
718}
719
720/* Remap memory */
721void __init *early_memremap(unsigned long phys_addr, unsigned long size)
722{
723 return __early_ioremap(phys_addr, size, PAGE_KERNEL);
662} 724}
663 725
664void __init early_iounmap(void *addr, unsigned long size) 726void __init early_iounmap(void *addr, unsigned long size)
@@ -667,15 +729,33 @@ void __init early_iounmap(void *addr, unsigned long size)
667 unsigned long offset; 729 unsigned long offset;
668 unsigned int nrpages; 730 unsigned int nrpages;
669 enum fixed_addresses idx; 731 enum fixed_addresses idx;
670 int nesting; 732 int i, slot;
733
734 slot = -1;
735 for (i = 0; i < FIX_BTMAPS_SLOTS; i++) {
736 if (prev_map[i] == addr) {
737 slot = i;
738 break;
739 }
740 }
671 741
672 nesting = --early_ioremap_nested; 742 if (slot < 0) {
673 if (WARN_ON(nesting < 0)) 743 printk(KERN_INFO "early_iounmap(%p, %08lx) not found slot\n",
744 addr, size);
745 WARN_ON(1);
746 return;
747 }
748
749 if (prev_size[slot] != size) {
750 printk(KERN_INFO "early_iounmap(%p, %08lx) [%d] size not consistent %08lx\n",
751 addr, size, slot, prev_size[slot]);
752 WARN_ON(1);
674 return; 753 return;
754 }
675 755
676 if (early_ioremap_debug) { 756 if (early_ioremap_debug) {
677 printk(KERN_INFO "early_iounmap(%p, %08lx) [%d]\n", addr, 757 printk(KERN_INFO "early_iounmap(%p, %08lx) [%d]\n", addr,
678 size, nesting); 758 size, slot);
679 dump_stack(); 759 dump_stack();
680 } 760 }
681 761
@@ -687,12 +767,13 @@ void __init early_iounmap(void *addr, unsigned long size)
687 offset = virt_addr & ~PAGE_MASK; 767 offset = virt_addr & ~PAGE_MASK;
688 nrpages = PAGE_ALIGN(offset + size - 1) >> PAGE_SHIFT; 768 nrpages = PAGE_ALIGN(offset + size - 1) >> PAGE_SHIFT;
689 769
690 idx = FIX_BTMAP_BEGIN - NR_FIX_BTMAPS*nesting; 770 idx = FIX_BTMAP_BEGIN - NR_FIX_BTMAPS*slot;
691 while (nrpages > 0) { 771 while (nrpages > 0) {
692 early_clear_fixmap(idx); 772 early_clear_fixmap(idx);
693 --idx; 773 --idx;
694 --nrpages; 774 --nrpages;
695 } 775 }
776 prev_map[slot] = 0;
696} 777}
697 778
698void __this_fixmap_does_not_exist(void) 779void __this_fixmap_does_not_exist(void)
diff --git a/arch/x86/mm/discontig_32.c b/arch/x86/mm/numa_32.c
index 847c164725f4..847c164725f4 100644
--- a/arch/x86/mm/discontig_32.c
+++ b/arch/x86/mm/numa_32.c
diff --git a/arch/x86/mm/srat_64.c b/arch/x86/mm/srat_64.c
index 1b4763e26ea9..51c0a2fc14fe 100644
--- a/arch/x86/mm/srat_64.c
+++ b/arch/x86/mm/srat_64.c
@@ -138,7 +138,7 @@ acpi_numa_processor_affinity_init(struct acpi_srat_cpu_affinity *pa)
138 return; 138 return;
139 } 139 }
140 140
141 if (is_uv_system()) 141 if (get_uv_system_type() >= UV_X2APIC)
142 apic_id = (pa->apic_id << 8) | pa->local_sapic_eid; 142 apic_id = (pa->apic_id << 8) | pa->local_sapic_eid;
143 else 143 else
144 apic_id = pa->apic_id; 144 apic_id = pa->apic_id;
diff --git a/arch/x86/oprofile/Makefile b/arch/x86/oprofile/Makefile
index 30f3eb366667..446902b2a6b6 100644
--- a/arch/x86/oprofile/Makefile
+++ b/arch/x86/oprofile/Makefile
@@ -7,6 +7,6 @@ DRIVER_OBJS = $(addprefix ../../../drivers/oprofile/, \
7 timer_int.o ) 7 timer_int.o )
8 8
9oprofile-y := $(DRIVER_OBJS) init.o backtrace.o 9oprofile-y := $(DRIVER_OBJS) init.o backtrace.o
10oprofile-$(CONFIG_X86_LOCAL_APIC) += nmi_int.o op_model_athlon.o \ 10oprofile-$(CONFIG_X86_LOCAL_APIC) += nmi_int.o op_model_amd.o \
11 op_model_ppro.o op_model_p4.o 11 op_model_ppro.o op_model_p4.o
12oprofile-$(CONFIG_X86_IO_APIC) += nmi_timer_int.o 12oprofile-$(CONFIG_X86_IO_APIC) += nmi_timer_int.o
diff --git a/arch/x86/oprofile/nmi_int.c b/arch/x86/oprofile/nmi_int.c
index 8a5f1614a3d5..57f6c9088081 100644
--- a/arch/x86/oprofile/nmi_int.c
+++ b/arch/x86/oprofile/nmi_int.c
@@ -1,10 +1,11 @@
1/** 1/**
2 * @file nmi_int.c 2 * @file nmi_int.c
3 * 3 *
4 * @remark Copyright 2002 OProfile authors 4 * @remark Copyright 2002-2008 OProfile authors
5 * @remark Read the file COPYING 5 * @remark Read the file COPYING
6 * 6 *
7 * @author John Levon <levon@movementarian.org> 7 * @author John Levon <levon@movementarian.org>
8 * @author Robert Richter <robert.richter@amd.com>
8 */ 9 */
9 10
10#include <linux/init.h> 11#include <linux/init.h>
@@ -439,6 +440,7 @@ int __init op_nmi_init(struct oprofile_operations *ops)
439 __u8 vendor = boot_cpu_data.x86_vendor; 440 __u8 vendor = boot_cpu_data.x86_vendor;
440 __u8 family = boot_cpu_data.x86; 441 __u8 family = boot_cpu_data.x86;
441 char *cpu_type; 442 char *cpu_type;
443 int ret = 0;
442 444
443 if (!cpu_has_apic) 445 if (!cpu_has_apic)
444 return -ENODEV; 446 return -ENODEV;
@@ -451,19 +453,23 @@ int __init op_nmi_init(struct oprofile_operations *ops)
451 default: 453 default:
452 return -ENODEV; 454 return -ENODEV;
453 case 6: 455 case 6:
454 model = &op_athlon_spec; 456 model = &op_amd_spec;
455 cpu_type = "i386/athlon"; 457 cpu_type = "i386/athlon";
456 break; 458 break;
457 case 0xf: 459 case 0xf:
458 model = &op_athlon_spec; 460 model = &op_amd_spec;
459 /* Actually it could be i386/hammer too, but give 461 /* Actually it could be i386/hammer too, but give
460 user space an consistent name. */ 462 user space an consistent name. */
461 cpu_type = "x86-64/hammer"; 463 cpu_type = "x86-64/hammer";
462 break; 464 break;
463 case 0x10: 465 case 0x10:
464 model = &op_athlon_spec; 466 model = &op_amd_spec;
465 cpu_type = "x86-64/family10"; 467 cpu_type = "x86-64/family10";
466 break; 468 break;
469 case 0x11:
470 model = &op_amd_spec;
471 cpu_type = "x86-64/family11h";
472 break;
467 } 473 }
468 break; 474 break;
469 475
@@ -490,17 +496,24 @@ int __init op_nmi_init(struct oprofile_operations *ops)
490 return -ENODEV; 496 return -ENODEV;
491 } 497 }
492 498
493 init_sysfs();
494#ifdef CONFIG_SMP 499#ifdef CONFIG_SMP
495 register_cpu_notifier(&oprofile_cpu_nb); 500 register_cpu_notifier(&oprofile_cpu_nb);
496#endif 501#endif
497 using_nmi = 1; 502 /* default values, can be overwritten by model */
498 ops->create_files = nmi_create_files; 503 ops->create_files = nmi_create_files;
499 ops->setup = nmi_setup; 504 ops->setup = nmi_setup;
500 ops->shutdown = nmi_shutdown; 505 ops->shutdown = nmi_shutdown;
501 ops->start = nmi_start; 506 ops->start = nmi_start;
502 ops->stop = nmi_stop; 507 ops->stop = nmi_stop;
503 ops->cpu_type = cpu_type; 508 ops->cpu_type = cpu_type;
509
510 if (model->init)
511 ret = model->init(ops);
512 if (ret)
513 return ret;
514
515 init_sysfs();
516 using_nmi = 1;
504 printk(KERN_INFO "oprofile: using NMI interrupt.\n"); 517 printk(KERN_INFO "oprofile: using NMI interrupt.\n");
505 return 0; 518 return 0;
506} 519}
@@ -513,4 +526,6 @@ void op_nmi_exit(void)
513 unregister_cpu_notifier(&oprofile_cpu_nb); 526 unregister_cpu_notifier(&oprofile_cpu_nb);
514#endif 527#endif
515 } 528 }
529 if (model->exit)
530 model->exit();
516} 531}
diff --git a/arch/x86/oprofile/op_model_amd.c b/arch/x86/oprofile/op_model_amd.c
new file mode 100644
index 000000000000..d9faf607b3a6
--- /dev/null
+++ b/arch/x86/oprofile/op_model_amd.c
@@ -0,0 +1,543 @@
1/*
2 * @file op_model_amd.c
3 * athlon / K7 / K8 / Family 10h model-specific MSR operations
4 *
5 * @remark Copyright 2002-2008 OProfile authors
6 * @remark Read the file COPYING
7 *
8 * @author John Levon
9 * @author Philippe Elie
10 * @author Graydon Hoare
11 * @author Robert Richter <robert.richter@amd.com>
12 * @author Barry Kasindorf
13*/
14
15#include <linux/oprofile.h>
16#include <linux/device.h>
17#include <linux/pci.h>
18
19#include <asm/ptrace.h>
20#include <asm/msr.h>
21#include <asm/nmi.h>
22
23#include "op_x86_model.h"
24#include "op_counter.h"
25
26#define NUM_COUNTERS 4
27#define NUM_CONTROLS 4
28
29#define CTR_IS_RESERVED(msrs, c) (msrs->counters[(c)].addr ? 1 : 0)
30#define CTR_READ(l, h, msrs, c) do {rdmsr(msrs->counters[(c)].addr, (l), (h)); } while (0)
31#define CTR_WRITE(l, msrs, c) do {wrmsr(msrs->counters[(c)].addr, -(unsigned int)(l), -1); } while (0)
32#define CTR_OVERFLOWED(n) (!((n) & (1U<<31)))
33
34#define CTRL_IS_RESERVED(msrs, c) (msrs->controls[(c)].addr ? 1 : 0)
35#define CTRL_READ(l, h, msrs, c) do {rdmsr(msrs->controls[(c)].addr, (l), (h)); } while (0)
36#define CTRL_WRITE(l, h, msrs, c) do {wrmsr(msrs->controls[(c)].addr, (l), (h)); } while (0)
37#define CTRL_SET_ACTIVE(n) (n |= (1<<22))
38#define CTRL_SET_INACTIVE(n) (n &= ~(1<<22))
39#define CTRL_CLEAR_LO(x) (x &= (1<<21))
40#define CTRL_CLEAR_HI(x) (x &= 0xfffffcf0)
41#define CTRL_SET_ENABLE(val) (val |= 1<<20)
42#define CTRL_SET_USR(val, u) (val |= ((u & 1) << 16))
43#define CTRL_SET_KERN(val, k) (val |= ((k & 1) << 17))
44#define CTRL_SET_UM(val, m) (val |= (m << 8))
45#define CTRL_SET_EVENT_LOW(val, e) (val |= (e & 0xff))
46#define CTRL_SET_EVENT_HIGH(val, e) (val |= ((e >> 8) & 0xf))
47#define CTRL_SET_HOST_ONLY(val, h) (val |= ((h & 1) << 9))
48#define CTRL_SET_GUEST_ONLY(val, h) (val |= ((h & 1) << 8))
49
50static unsigned long reset_value[NUM_COUNTERS];
51
52#ifdef CONFIG_OPROFILE_IBS
53
54/* IbsFetchCtl bits/masks */
55#define IBS_FETCH_HIGH_VALID_BIT (1UL << 17) /* bit 49 */
56#define IBS_FETCH_HIGH_ENABLE (1UL << 16) /* bit 48 */
57#define IBS_FETCH_LOW_MAX_CNT_MASK 0x0000FFFFUL /* MaxCnt mask */
58
59/*IbsOpCtl bits */
60#define IBS_OP_LOW_VALID_BIT (1ULL<<18) /* bit 18 */
61#define IBS_OP_LOW_ENABLE (1ULL<<17) /* bit 17 */
62
63/* Codes used in cpu_buffer.c */
64/* This produces duplicate code, need to be fixed */
65#define IBS_FETCH_BEGIN 3
66#define IBS_OP_BEGIN 4
67
68/* The function interface needs to be fixed, something like add
69 data. Should then be added to linux/oprofile.h. */
70extern void oprofile_add_ibs_sample(struct pt_regs *const regs,
71 unsigned int * const ibs_sample, u8 code);
72
73struct ibs_fetch_sample {
74 /* MSRC001_1031 IBS Fetch Linear Address Register */
75 unsigned int ibs_fetch_lin_addr_low;
76 unsigned int ibs_fetch_lin_addr_high;
77 /* MSRC001_1030 IBS Fetch Control Register */
78 unsigned int ibs_fetch_ctl_low;
79 unsigned int ibs_fetch_ctl_high;
80 /* MSRC001_1032 IBS Fetch Physical Address Register */
81 unsigned int ibs_fetch_phys_addr_low;
82 unsigned int ibs_fetch_phys_addr_high;
83};
84
85struct ibs_op_sample {
86 /* MSRC001_1034 IBS Op Logical Address Register (IbsRIP) */
87 unsigned int ibs_op_rip_low;
88 unsigned int ibs_op_rip_high;
89 /* MSRC001_1035 IBS Op Data Register */
90 unsigned int ibs_op_data1_low;
91 unsigned int ibs_op_data1_high;
92 /* MSRC001_1036 IBS Op Data 2 Register */
93 unsigned int ibs_op_data2_low;
94 unsigned int ibs_op_data2_high;
95 /* MSRC001_1037 IBS Op Data 3 Register */
96 unsigned int ibs_op_data3_low;
97 unsigned int ibs_op_data3_high;
98 /* MSRC001_1038 IBS DC Linear Address Register (IbsDcLinAd) */
99 unsigned int ibs_dc_linear_low;
100 unsigned int ibs_dc_linear_high;
101 /* MSRC001_1039 IBS DC Physical Address Register (IbsDcPhysAd) */
102 unsigned int ibs_dc_phys_low;
103 unsigned int ibs_dc_phys_high;
104};
105
106/*
107 * unitialize the APIC for the IBS interrupts if needed on AMD Family10h+
108*/
109static void clear_ibs_nmi(void);
110
111static int ibs_allowed; /* AMD Family10h and later */
112
113struct op_ibs_config {
114 unsigned long op_enabled;
115 unsigned long fetch_enabled;
116 unsigned long max_cnt_fetch;
117 unsigned long max_cnt_op;
118 unsigned long rand_en;
119 unsigned long dispatched_ops;
120};
121
122static struct op_ibs_config ibs_config;
123
124#endif
125
126/* functions for op_amd_spec */
127
128static void op_amd_fill_in_addresses(struct op_msrs * const msrs)
129{
130 int i;
131
132 for (i = 0; i < NUM_COUNTERS; i++) {
133 if (reserve_perfctr_nmi(MSR_K7_PERFCTR0 + i))
134 msrs->counters[i].addr = MSR_K7_PERFCTR0 + i;
135 else
136 msrs->counters[i].addr = 0;
137 }
138
139 for (i = 0; i < NUM_CONTROLS; i++) {
140 if (reserve_evntsel_nmi(MSR_K7_EVNTSEL0 + i))
141 msrs->controls[i].addr = MSR_K7_EVNTSEL0 + i;
142 else
143 msrs->controls[i].addr = 0;
144 }
145}
146
147
148static void op_amd_setup_ctrs(struct op_msrs const * const msrs)
149{
150 unsigned int low, high;
151 int i;
152
153 /* clear all counters */
154 for (i = 0 ; i < NUM_CONTROLS; ++i) {
155 if (unlikely(!CTRL_IS_RESERVED(msrs, i)))
156 continue;
157 CTRL_READ(low, high, msrs, i);
158 CTRL_CLEAR_LO(low);
159 CTRL_CLEAR_HI(high);
160 CTRL_WRITE(low, high, msrs, i);
161 }
162
163 /* avoid a false detection of ctr overflows in NMI handler */
164 for (i = 0; i < NUM_COUNTERS; ++i) {
165 if (unlikely(!CTR_IS_RESERVED(msrs, i)))
166 continue;
167 CTR_WRITE(1, msrs, i);
168 }
169
170 /* enable active counters */
171 for (i = 0; i < NUM_COUNTERS; ++i) {
172 if ((counter_config[i].enabled) && (CTR_IS_RESERVED(msrs, i))) {
173 reset_value[i] = counter_config[i].count;
174
175 CTR_WRITE(counter_config[i].count, msrs, i);
176
177 CTRL_READ(low, high, msrs, i);
178 CTRL_CLEAR_LO(low);
179 CTRL_CLEAR_HI(high);
180 CTRL_SET_ENABLE(low);
181 CTRL_SET_USR(low, counter_config[i].user);
182 CTRL_SET_KERN(low, counter_config[i].kernel);
183 CTRL_SET_UM(low, counter_config[i].unit_mask);
184 CTRL_SET_EVENT_LOW(low, counter_config[i].event);
185 CTRL_SET_EVENT_HIGH(high, counter_config[i].event);
186 CTRL_SET_HOST_ONLY(high, 0);
187 CTRL_SET_GUEST_ONLY(high, 0);
188
189 CTRL_WRITE(low, high, msrs, i);
190 } else {
191 reset_value[i] = 0;
192 }
193 }
194}
195
196#ifdef CONFIG_OPROFILE_IBS
197
198static inline int
199op_amd_handle_ibs(struct pt_regs * const regs,
200 struct op_msrs const * const msrs)
201{
202 unsigned int low, high;
203 struct ibs_fetch_sample ibs_fetch;
204 struct ibs_op_sample ibs_op;
205
206 if (!ibs_allowed)
207 return 1;
208
209 if (ibs_config.fetch_enabled) {
210 rdmsr(MSR_AMD64_IBSFETCHCTL, low, high);
211 if (high & IBS_FETCH_HIGH_VALID_BIT) {
212 ibs_fetch.ibs_fetch_ctl_high = high;
213 ibs_fetch.ibs_fetch_ctl_low = low;
214 rdmsr(MSR_AMD64_IBSFETCHLINAD, low, high);
215 ibs_fetch.ibs_fetch_lin_addr_high = high;
216 ibs_fetch.ibs_fetch_lin_addr_low = low;
217 rdmsr(MSR_AMD64_IBSFETCHPHYSAD, low, high);
218 ibs_fetch.ibs_fetch_phys_addr_high = high;
219 ibs_fetch.ibs_fetch_phys_addr_low = low;
220
221 oprofile_add_ibs_sample(regs,
222 (unsigned int *)&ibs_fetch,
223 IBS_FETCH_BEGIN);
224
225 /*reenable the IRQ */
226 rdmsr(MSR_AMD64_IBSFETCHCTL, low, high);
227 high &= ~IBS_FETCH_HIGH_VALID_BIT;
228 high |= IBS_FETCH_HIGH_ENABLE;
229 low &= IBS_FETCH_LOW_MAX_CNT_MASK;
230 wrmsr(MSR_AMD64_IBSFETCHCTL, low, high);
231 }
232 }
233
234 if (ibs_config.op_enabled) {
235 rdmsr(MSR_AMD64_IBSOPCTL, low, high);
236 if (low & IBS_OP_LOW_VALID_BIT) {
237 rdmsr(MSR_AMD64_IBSOPRIP, low, high);
238 ibs_op.ibs_op_rip_low = low;
239 ibs_op.ibs_op_rip_high = high;
240 rdmsr(MSR_AMD64_IBSOPDATA, low, high);
241 ibs_op.ibs_op_data1_low = low;
242 ibs_op.ibs_op_data1_high = high;
243 rdmsr(MSR_AMD64_IBSOPDATA2, low, high);
244 ibs_op.ibs_op_data2_low = low;
245 ibs_op.ibs_op_data2_high = high;
246 rdmsr(MSR_AMD64_IBSOPDATA3, low, high);
247 ibs_op.ibs_op_data3_low = low;
248 ibs_op.ibs_op_data3_high = high;
249 rdmsr(MSR_AMD64_IBSDCLINAD, low, high);
250 ibs_op.ibs_dc_linear_low = low;
251 ibs_op.ibs_dc_linear_high = high;
252 rdmsr(MSR_AMD64_IBSDCPHYSAD, low, high);
253 ibs_op.ibs_dc_phys_low = low;
254 ibs_op.ibs_dc_phys_high = high;
255
256 /* reenable the IRQ */
257 oprofile_add_ibs_sample(regs,
258 (unsigned int *)&ibs_op,
259 IBS_OP_BEGIN);
260 rdmsr(MSR_AMD64_IBSOPCTL, low, high);
261 high = 0;
262 low &= ~IBS_OP_LOW_VALID_BIT;
263 low |= IBS_OP_LOW_ENABLE;
264 wrmsr(MSR_AMD64_IBSOPCTL, low, high);
265 }
266 }
267
268 return 1;
269}
270
271#endif
272
273static int op_amd_check_ctrs(struct pt_regs * const regs,
274 struct op_msrs const * const msrs)
275{
276 unsigned int low, high;
277 int i;
278
279 for (i = 0 ; i < NUM_COUNTERS; ++i) {
280 if (!reset_value[i])
281 continue;
282 CTR_READ(low, high, msrs, i);
283 if (CTR_OVERFLOWED(low)) {
284 oprofile_add_sample(regs, i);
285 CTR_WRITE(reset_value[i], msrs, i);
286 }
287 }
288
289#ifdef CONFIG_OPROFILE_IBS
290 op_amd_handle_ibs(regs, msrs);
291#endif
292
293 /* See op_model_ppro.c */
294 return 1;
295}
296
297static void op_amd_start(struct op_msrs const * const msrs)
298{
299 unsigned int low, high;
300 int i;
301 for (i = 0 ; i < NUM_COUNTERS ; ++i) {
302 if (reset_value[i]) {
303 CTRL_READ(low, high, msrs, i);
304 CTRL_SET_ACTIVE(low);
305 CTRL_WRITE(low, high, msrs, i);
306 }
307 }
308
309#ifdef CONFIG_OPROFILE_IBS
310 if (ibs_allowed && ibs_config.fetch_enabled) {
311 low = (ibs_config.max_cnt_fetch >> 4) & 0xFFFF;
312 high = IBS_FETCH_HIGH_ENABLE;
313 wrmsr(MSR_AMD64_IBSFETCHCTL, low, high);
314 }
315
316 if (ibs_allowed && ibs_config.op_enabled) {
317 low = ((ibs_config.max_cnt_op >> 4) & 0xFFFF) + IBS_OP_LOW_ENABLE;
318 high = 0;
319 wrmsr(MSR_AMD64_IBSOPCTL, low, high);
320 }
321#endif
322}
323
324
325static void op_amd_stop(struct op_msrs const * const msrs)
326{
327 unsigned int low, high;
328 int i;
329
330 /* Subtle: stop on all counters to avoid race with
331 * setting our pm callback */
332 for (i = 0 ; i < NUM_COUNTERS ; ++i) {
333 if (!reset_value[i])
334 continue;
335 CTRL_READ(low, high, msrs, i);
336 CTRL_SET_INACTIVE(low);
337 CTRL_WRITE(low, high, msrs, i);
338 }
339
340#ifdef CONFIG_OPROFILE_IBS
341 if (ibs_allowed && ibs_config.fetch_enabled) {
342 low = 0; /* clear max count and enable */
343 high = 0;
344 wrmsr(MSR_AMD64_IBSFETCHCTL, low, high);
345 }
346
347 if (ibs_allowed && ibs_config.op_enabled) {
348 low = 0; /* clear max count and enable */
349 high = 0;
350 wrmsr(MSR_AMD64_IBSOPCTL, low, high);
351 }
352#endif
353}
354
355static void op_amd_shutdown(struct op_msrs const * const msrs)
356{
357 int i;
358
359 for (i = 0 ; i < NUM_COUNTERS ; ++i) {
360 if (CTR_IS_RESERVED(msrs, i))
361 release_perfctr_nmi(MSR_K7_PERFCTR0 + i);
362 }
363 for (i = 0 ; i < NUM_CONTROLS ; ++i) {
364 if (CTRL_IS_RESERVED(msrs, i))
365 release_evntsel_nmi(MSR_K7_EVNTSEL0 + i);
366 }
367}
368
369#ifndef CONFIG_OPROFILE_IBS
370
371/* no IBS support */
372
373static int op_amd_init(struct oprofile_operations *ops)
374{
375 return 0;
376}
377
378static void op_amd_exit(void) {}
379
380#else
381
382static u8 ibs_eilvt_off;
383
384static inline void apic_init_ibs_nmi_per_cpu(void *arg)
385{
386 ibs_eilvt_off = setup_APIC_eilvt_ibs(0, APIC_EILVT_MSG_NMI, 0);
387}
388
389static inline void apic_clear_ibs_nmi_per_cpu(void *arg)
390{
391 setup_APIC_eilvt_ibs(0, APIC_EILVT_MSG_FIX, 1);
392}
393
394static int pfm_amd64_setup_eilvt(void)
395{
396#define IBSCTL_LVTOFFSETVAL (1 << 8)
397#define IBSCTL 0x1cc
398 struct pci_dev *cpu_cfg;
399 int nodes;
400 u32 value = 0;
401
402 /* per CPU setup */
403 on_each_cpu(apic_init_ibs_nmi_per_cpu, NULL, 1);
404
405 nodes = 0;
406 cpu_cfg = NULL;
407 do {
408 cpu_cfg = pci_get_device(PCI_VENDOR_ID_AMD,
409 PCI_DEVICE_ID_AMD_10H_NB_MISC,
410 cpu_cfg);
411 if (!cpu_cfg)
412 break;
413 ++nodes;
414 pci_write_config_dword(cpu_cfg, IBSCTL, ibs_eilvt_off
415 | IBSCTL_LVTOFFSETVAL);
416 pci_read_config_dword(cpu_cfg, IBSCTL, &value);
417 if (value != (ibs_eilvt_off | IBSCTL_LVTOFFSETVAL)) {
418 printk(KERN_DEBUG "Failed to setup IBS LVT offset, "
419 "IBSCTL = 0x%08x", value);
420 return 1;
421 }
422 } while (1);
423
424 if (!nodes) {
425 printk(KERN_DEBUG "No CPU node configured for IBS");
426 return 1;
427 }
428
429#ifdef CONFIG_NUMA
430 /* Sanity check */
431 /* Works only for 64bit with proper numa implementation. */
432 if (nodes != num_possible_nodes()) {
433 printk(KERN_DEBUG "Failed to setup CPU node(s) for IBS, "
434 "found: %d, expected %d",
435 nodes, num_possible_nodes());
436 return 1;
437 }
438#endif
439 return 0;
440}
441
442/*
443 * initialize the APIC for the IBS interrupts
444 * if available (AMD Family10h rev B0 and later)
445 */
446static void setup_ibs(void)
447{
448 ibs_allowed = boot_cpu_has(X86_FEATURE_IBS);
449
450 if (!ibs_allowed)
451 return;
452
453 if (pfm_amd64_setup_eilvt()) {
454 ibs_allowed = 0;
455 return;
456 }
457
458 printk(KERN_INFO "oprofile: AMD IBS detected\n");
459}
460
461
462/*
463 * unitialize the APIC for the IBS interrupts if needed on AMD Family10h
464 * rev B0 and later */
465static void clear_ibs_nmi(void)
466{
467 if (ibs_allowed)
468 on_each_cpu(apic_clear_ibs_nmi_per_cpu, NULL, 1);
469}
470
471static int (*create_arch_files)(struct super_block * sb, struct dentry * root);
472
473static int setup_ibs_files(struct super_block * sb, struct dentry * root)
474{
475 char buf[12];
476 struct dentry *dir;
477 int ret = 0;
478
479 /* architecture specific files */
480 if (create_arch_files)
481 ret = create_arch_files(sb, root);
482
483 if (ret)
484 return ret;
485
486 if (!ibs_allowed)
487 return ret;
488
489 /* model specific files */
490
491 /* setup some reasonable defaults */
492 ibs_config.max_cnt_fetch = 250000;
493 ibs_config.fetch_enabled = 0;
494 ibs_config.max_cnt_op = 250000;
495 ibs_config.op_enabled = 0;
496 ibs_config.dispatched_ops = 1;
497 snprintf(buf, sizeof(buf), "ibs_fetch");
498 dir = oprofilefs_mkdir(sb, root, buf);
499 oprofilefs_create_ulong(sb, dir, "rand_enable",
500 &ibs_config.rand_en);
501 oprofilefs_create_ulong(sb, dir, "enable",
502 &ibs_config.fetch_enabled);
503 oprofilefs_create_ulong(sb, dir, "max_count",
504 &ibs_config.max_cnt_fetch);
505 snprintf(buf, sizeof(buf), "ibs_uops");
506 dir = oprofilefs_mkdir(sb, root, buf);
507 oprofilefs_create_ulong(sb, dir, "enable",
508 &ibs_config.op_enabled);
509 oprofilefs_create_ulong(sb, dir, "max_count",
510 &ibs_config.max_cnt_op);
511 oprofilefs_create_ulong(sb, dir, "dispatched_ops",
512 &ibs_config.dispatched_ops);
513
514 return 0;
515}
516
517static int op_amd_init(struct oprofile_operations *ops)
518{
519 setup_ibs();
520 create_arch_files = ops->create_files;
521 ops->create_files = setup_ibs_files;
522 return 0;
523}
524
525static void op_amd_exit(void)
526{
527 clear_ibs_nmi();
528}
529
530#endif
531
532struct op_x86_model_spec const op_amd_spec = {
533 .init = op_amd_init,
534 .exit = op_amd_exit,
535 .num_counters = NUM_COUNTERS,
536 .num_controls = NUM_CONTROLS,
537 .fill_in_addresses = &op_amd_fill_in_addresses,
538 .setup_ctrs = &op_amd_setup_ctrs,
539 .check_ctrs = &op_amd_check_ctrs,
540 .start = &op_amd_start,
541 .stop = &op_amd_stop,
542 .shutdown = &op_amd_shutdown
543};
diff --git a/arch/x86/oprofile/op_model_athlon.c b/arch/x86/oprofile/op_model_athlon.c
deleted file mode 100644
index 3d534879a9dc..000000000000
--- a/arch/x86/oprofile/op_model_athlon.c
+++ /dev/null
@@ -1,190 +0,0 @@
1/*
2 * @file op_model_athlon.h
3 * athlon / K7 / K8 / Family 10h model-specific MSR operations
4 *
5 * @remark Copyright 2002 OProfile authors
6 * @remark Read the file COPYING
7 *
8 * @author John Levon
9 * @author Philippe Elie
10 * @author Graydon Hoare
11 */
12
13#include <linux/oprofile.h>
14#include <asm/ptrace.h>
15#include <asm/msr.h>
16#include <asm/nmi.h>
17
18#include "op_x86_model.h"
19#include "op_counter.h"
20
21#define NUM_COUNTERS 4
22#define NUM_CONTROLS 4
23
24#define CTR_IS_RESERVED(msrs, c) (msrs->counters[(c)].addr ? 1 : 0)
25#define CTR_READ(l, h, msrs, c) do {rdmsr(msrs->counters[(c)].addr, (l), (h)); } while (0)
26#define CTR_WRITE(l, msrs, c) do {wrmsr(msrs->counters[(c)].addr, -(unsigned int)(l), -1); } while (0)
27#define CTR_OVERFLOWED(n) (!((n) & (1U<<31)))
28
29#define CTRL_IS_RESERVED(msrs, c) (msrs->controls[(c)].addr ? 1 : 0)
30#define CTRL_READ(l, h, msrs, c) do {rdmsr(msrs->controls[(c)].addr, (l), (h)); } while (0)
31#define CTRL_WRITE(l, h, msrs, c) do {wrmsr(msrs->controls[(c)].addr, (l), (h)); } while (0)
32#define CTRL_SET_ACTIVE(n) (n |= (1<<22))
33#define CTRL_SET_INACTIVE(n) (n &= ~(1<<22))
34#define CTRL_CLEAR_LO(x) (x &= (1<<21))
35#define CTRL_CLEAR_HI(x) (x &= 0xfffffcf0)
36#define CTRL_SET_ENABLE(val) (val |= 1<<20)
37#define CTRL_SET_USR(val, u) (val |= ((u & 1) << 16))
38#define CTRL_SET_KERN(val, k) (val |= ((k & 1) << 17))
39#define CTRL_SET_UM(val, m) (val |= (m << 8))
40#define CTRL_SET_EVENT_LOW(val, e) (val |= (e & 0xff))
41#define CTRL_SET_EVENT_HIGH(val, e) (val |= ((e >> 8) & 0xf))
42#define CTRL_SET_HOST_ONLY(val, h) (val |= ((h & 1) << 9))
43#define CTRL_SET_GUEST_ONLY(val, h) (val |= ((h & 1) << 8))
44
45static unsigned long reset_value[NUM_COUNTERS];
46
47static void athlon_fill_in_addresses(struct op_msrs * const msrs)
48{
49 int i;
50
51 for (i = 0; i < NUM_COUNTERS; i++) {
52 if (reserve_perfctr_nmi(MSR_K7_PERFCTR0 + i))
53 msrs->counters[i].addr = MSR_K7_PERFCTR0 + i;
54 else
55 msrs->counters[i].addr = 0;
56 }
57
58 for (i = 0; i < NUM_CONTROLS; i++) {
59 if (reserve_evntsel_nmi(MSR_K7_EVNTSEL0 + i))
60 msrs->controls[i].addr = MSR_K7_EVNTSEL0 + i;
61 else
62 msrs->controls[i].addr = 0;
63 }
64}
65
66
67static void athlon_setup_ctrs(struct op_msrs const * const msrs)
68{
69 unsigned int low, high;
70 int i;
71
72 /* clear all counters */
73 for (i = 0 ; i < NUM_CONTROLS; ++i) {
74 if (unlikely(!CTRL_IS_RESERVED(msrs, i)))
75 continue;
76 CTRL_READ(low, high, msrs, i);
77 CTRL_CLEAR_LO(low);
78 CTRL_CLEAR_HI(high);
79 CTRL_WRITE(low, high, msrs, i);
80 }
81
82 /* avoid a false detection of ctr overflows in NMI handler */
83 for (i = 0; i < NUM_COUNTERS; ++i) {
84 if (unlikely(!CTR_IS_RESERVED(msrs, i)))
85 continue;
86 CTR_WRITE(1, msrs, i);
87 }
88
89 /* enable active counters */
90 for (i = 0; i < NUM_COUNTERS; ++i) {
91 if ((counter_config[i].enabled) && (CTR_IS_RESERVED(msrs, i))) {
92 reset_value[i] = counter_config[i].count;
93
94 CTR_WRITE(counter_config[i].count, msrs, i);
95
96 CTRL_READ(low, high, msrs, i);
97 CTRL_CLEAR_LO(low);
98 CTRL_CLEAR_HI(high);
99 CTRL_SET_ENABLE(low);
100 CTRL_SET_USR(low, counter_config[i].user);
101 CTRL_SET_KERN(low, counter_config[i].kernel);
102 CTRL_SET_UM(low, counter_config[i].unit_mask);
103 CTRL_SET_EVENT_LOW(low, counter_config[i].event);
104 CTRL_SET_EVENT_HIGH(high, counter_config[i].event);
105 CTRL_SET_HOST_ONLY(high, 0);
106 CTRL_SET_GUEST_ONLY(high, 0);
107
108 CTRL_WRITE(low, high, msrs, i);
109 } else {
110 reset_value[i] = 0;
111 }
112 }
113}
114
115
116static int athlon_check_ctrs(struct pt_regs * const regs,
117 struct op_msrs const * const msrs)
118{
119 unsigned int low, high;
120 int i;
121
122 for (i = 0 ; i < NUM_COUNTERS; ++i) {
123 if (!reset_value[i])
124 continue;
125 CTR_READ(low, high, msrs, i);
126 if (CTR_OVERFLOWED(low)) {
127 oprofile_add_sample(regs, i);
128 CTR_WRITE(reset_value[i], msrs, i);
129 }
130 }
131
132 /* See op_model_ppro.c */
133 return 1;
134}
135
136
137static void athlon_start(struct op_msrs const * const msrs)
138{
139 unsigned int low, high;
140 int i;
141 for (i = 0 ; i < NUM_COUNTERS ; ++i) {
142 if (reset_value[i]) {
143 CTRL_READ(low, high, msrs, i);
144 CTRL_SET_ACTIVE(low);
145 CTRL_WRITE(low, high, msrs, i);
146 }
147 }
148}
149
150
151static void athlon_stop(struct op_msrs const * const msrs)
152{
153 unsigned int low, high;
154 int i;
155
156 /* Subtle: stop on all counters to avoid race with
157 * setting our pm callback */
158 for (i = 0 ; i < NUM_COUNTERS ; ++i) {
159 if (!reset_value[i])
160 continue;
161 CTRL_READ(low, high, msrs, i);
162 CTRL_SET_INACTIVE(low);
163 CTRL_WRITE(low, high, msrs, i);
164 }
165}
166
167static void athlon_shutdown(struct op_msrs const * const msrs)
168{
169 int i;
170
171 for (i = 0 ; i < NUM_COUNTERS ; ++i) {
172 if (CTR_IS_RESERVED(msrs, i))
173 release_perfctr_nmi(MSR_K7_PERFCTR0 + i);
174 }
175 for (i = 0 ; i < NUM_CONTROLS ; ++i) {
176 if (CTRL_IS_RESERVED(msrs, i))
177 release_evntsel_nmi(MSR_K7_EVNTSEL0 + i);
178 }
179}
180
181struct op_x86_model_spec const op_athlon_spec = {
182 .num_counters = NUM_COUNTERS,
183 .num_controls = NUM_CONTROLS,
184 .fill_in_addresses = &athlon_fill_in_addresses,
185 .setup_ctrs = &athlon_setup_ctrs,
186 .check_ctrs = &athlon_check_ctrs,
187 .start = &athlon_start,
188 .stop = &athlon_stop,
189 .shutdown = &athlon_shutdown
190};
diff --git a/arch/x86/oprofile/op_x86_model.h b/arch/x86/oprofile/op_x86_model.h
index 45b605fa71d0..05a0261ba0c3 100644
--- a/arch/x86/oprofile/op_x86_model.h
+++ b/arch/x86/oprofile/op_x86_model.h
@@ -32,6 +32,8 @@ struct pt_regs;
32 * various x86 CPU models' perfctr support. 32 * various x86 CPU models' perfctr support.
33 */ 33 */
34struct op_x86_model_spec { 34struct op_x86_model_spec {
35 int (*init)(struct oprofile_operations *ops);
36 void (*exit)(void);
35 unsigned int const num_counters; 37 unsigned int const num_counters;
36 unsigned int const num_controls; 38 unsigned int const num_controls;
37 void (*fill_in_addresses)(struct op_msrs * const msrs); 39 void (*fill_in_addresses)(struct op_msrs * const msrs);
@@ -46,6 +48,6 @@ struct op_x86_model_spec {
46extern struct op_x86_model_spec const op_ppro_spec; 48extern struct op_x86_model_spec const op_ppro_spec;
47extern struct op_x86_model_spec const op_p4_spec; 49extern struct op_x86_model_spec const op_p4_spec;
48extern struct op_x86_model_spec const op_p4_ht2_spec; 50extern struct op_x86_model_spec const op_p4_ht2_spec;
49extern struct op_x86_model_spec const op_athlon_spec; 51extern struct op_x86_model_spec const op_amd_spec;
50 52
51#endif /* OP_X86_MODEL_H */ 53#endif /* OP_X86_MODEL_H */
diff --git a/arch/x86/pci/fixup.c b/arch/x86/pci/fixup.c
index 4bdaa590375d..3c27a809393b 100644
--- a/arch/x86/pci/fixup.c
+++ b/arch/x86/pci/fixup.c
@@ -511,3 +511,31 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, 0x1201, fam10h_pci_cfg_space_size);
511DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, 0x1202, fam10h_pci_cfg_space_size); 511DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, 0x1202, fam10h_pci_cfg_space_size);
512DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, 0x1203, fam10h_pci_cfg_space_size); 512DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, 0x1203, fam10h_pci_cfg_space_size);
513DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, 0x1204, fam10h_pci_cfg_space_size); 513DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, 0x1204, fam10h_pci_cfg_space_size);
514
515/*
516 * SB600: Disable BAR1 on device 14.0 to avoid HPET resources from
517 * confusing the PCI engine:
518 */
519static void sb600_disable_hpet_bar(struct pci_dev *dev)
520{
521 u8 val;
522
523 /*
524 * The SB600 and SB700 both share the same device
525 * ID, but the PM register 0x55 does something different
526 * for the SB700, so make sure we are dealing with the
527 * SB600 before touching the bit:
528 */
529
530 pci_read_config_byte(dev, 0x08, &val);
531
532 if (val < 0x2F) {
533 outb(0x55, 0xCD6);
534 val = inb(0xCD7);
535
536 /* Set bit 7 in PM register 0x55 */
537 outb(0x55, 0xCD6);
538 outb(val | 0x80, 0xCD7);
539 }
540}
541DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_ATI, 0x4385, sb600_disable_hpet_bar);
diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c
index 8dfcf77cb717..4426bb552bd9 100644
--- a/drivers/bluetooth/hci_ldisc.c
+++ b/drivers/bluetooth/hci_ldisc.c
@@ -484,7 +484,7 @@ static int hci_uart_tty_ioctl(struct tty_struct *tty, struct file * file,
484 return -EUNATCH; 484 return -EUNATCH;
485 485
486 default: 486 default:
487 err = n_tty_ioctl(tty, file, cmd, arg); 487 err = n_tty_ioctl_helper(tty, file, cmd, arg);
488 break; 488 break;
489 }; 489 };
490 490
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index caff85149b9d..700ff9679457 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -350,7 +350,7 @@ config STALDRV
350 350
351config STALLION 351config STALLION
352 tristate "Stallion EasyIO or EC8/32 support" 352 tristate "Stallion EasyIO or EC8/32 support"
353 depends on STALDRV && BROKEN_ON_SMP && (ISA || EISA || PCI) 353 depends on STALDRV && (ISA || EISA || PCI)
354 help 354 help
355 If you have an EasyIO or EasyConnection 8/32 multiport Stallion 355 If you have an EasyIO or EasyConnection 8/32 multiport Stallion
356 card, then this is for you; say Y. Make sure to read 356 card, then this is for you; say Y. Make sure to read
@@ -361,7 +361,7 @@ config STALLION
361 361
362config ISTALLION 362config ISTALLION
363 tristate "Stallion EC8/64, ONboard, Brumby support" 363 tristate "Stallion EC8/64, ONboard, Brumby support"
364 depends on STALDRV && BROKEN_ON_SMP && (ISA || EISA || PCI) 364 depends on STALDRV && (ISA || EISA || PCI)
365 help 365 help
366 If you have an EasyConnection 8/64, ONboard, Brumby or Stallion 366 If you have an EasyConnection 8/64, ONboard, Brumby or Stallion
367 serial multiport card, say Y here. Make sure to read 367 serial multiport card, say Y here. Make sure to read
diff --git a/drivers/char/Makefile b/drivers/char/Makefile
index 6850f6da7576..1a4247dccac4 100644
--- a/drivers/char/Makefile
+++ b/drivers/char/Makefile
@@ -7,7 +7,7 @@
7# 7#
8FONTMAPFILE = cp437.uni 8FONTMAPFILE = cp437.uni
9 9
10obj-y += mem.o random.o tty_io.o n_tty.o tty_ioctl.o tty_ldisc.o 10obj-y += mem.o random.o tty_io.o n_tty.o tty_ioctl.o tty_ldisc.o tty_buffer.o tty_port.o
11 11
12obj-$(CONFIG_LEGACY_PTYS) += pty.o 12obj-$(CONFIG_LEGACY_PTYS) += pty.o
13obj-$(CONFIG_UNIX98_PTYS) += pty.o 13obj-$(CONFIG_UNIX98_PTYS) += pty.o
diff --git a/drivers/char/amiserial.c b/drivers/char/amiserial.c
index 6e763e3f5a81..98821f97583c 100644
--- a/drivers/char/amiserial.c
+++ b/drivers/char/amiserial.c
@@ -837,9 +837,6 @@ static int rs_put_char(struct tty_struct *tty, unsigned char ch)
837 struct async_struct *info; 837 struct async_struct *info;
838 unsigned long flags; 838 unsigned long flags;
839 839
840 if (!tty)
841 return 0;
842
843 info = tty->driver_data; 840 info = tty->driver_data;
844 841
845 if (serial_paranoia_check(info, tty->name, "rs_put_char")) 842 if (serial_paranoia_check(info, tty->name, "rs_put_char"))
@@ -892,9 +889,6 @@ static int rs_write(struct tty_struct * tty, const unsigned char *buf, int count
892 struct async_struct *info; 889 struct async_struct *info;
893 unsigned long flags; 890 unsigned long flags;
894 891
895 if (!tty)
896 return 0;
897
898 info = tty->driver_data; 892 info = tty->driver_data;
899 893
900 if (serial_paranoia_check(info, tty->name, "rs_write")) 894 if (serial_paranoia_check(info, tty->name, "rs_write"))
diff --git a/drivers/char/applicom.c b/drivers/char/applicom.c
index 31d08b641f5b..b899d9182c7d 100644
--- a/drivers/char/applicom.c
+++ b/drivers/char/applicom.c
@@ -712,8 +712,7 @@ static int ac_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
712 712
713 IndexCard = adgl->num_card-1; 713 IndexCard = adgl->num_card-1;
714 714
715 if(cmd != 0 && cmd != 6 && 715 if(cmd != 6 && ((IndexCard >= MAX_BOARD) || !apbs[IndexCard].RamIO)) {
716 ((IndexCard >= MAX_BOARD) || !apbs[IndexCard].RamIO)) {
717 static int warncount = 10; 716 static int warncount = 10;
718 if (warncount) { 717 if (warncount) {
719 printk( KERN_WARNING "APPLICOM driver IOCTL, bad board number %d\n",(int)IndexCard+1); 718 printk( KERN_WARNING "APPLICOM driver IOCTL, bad board number %d\n",(int)IndexCard+1);
@@ -832,8 +831,7 @@ static int ac_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
832 } 831 }
833 break; 832 break;
834 default: 833 default:
835 printk(KERN_INFO "APPLICOM driver ioctl, unknown function code %d\n",cmd) ; 834 ret = -ENOTTY;
836 ret = -EINVAL;
837 break; 835 break;
838 } 836 }
839 Dummy = readb(apbs[IndexCard].RamIO + VERS); 837 Dummy = readb(apbs[IndexCard].RamIO + VERS);
diff --git a/drivers/char/cyclades.c b/drivers/char/cyclades.c
index fe6d774fe2e4..5e5b1dc1a0a7 100644
--- a/drivers/char/cyclades.c
+++ b/drivers/char/cyclades.c
@@ -4993,12 +4993,14 @@ static int __devinit cy_pci_probe(struct pci_dev *pdev,
4993 device_id == PCI_DEVICE_ID_CYCLOM_Y_Hi) { 4993 device_id == PCI_DEVICE_ID_CYCLOM_Y_Hi) {
4994 card_name = "Cyclom-Y"; 4994 card_name = "Cyclom-Y";
4995 4995
4996 addr0 = pci_iomap(pdev, 0, CyPCI_Yctl); 4996 addr0 = ioremap_nocache(pci_resource_start(pdev, 0),
4997 CyPCI_Yctl);
4997 if (addr0 == NULL) { 4998 if (addr0 == NULL) {
4998 dev_err(&pdev->dev, "can't remap ctl region\n"); 4999 dev_err(&pdev->dev, "can't remap ctl region\n");
4999 goto err_reg; 5000 goto err_reg;
5000 } 5001 }
5001 addr2 = pci_iomap(pdev, 2, CyPCI_Ywin); 5002 addr2 = ioremap_nocache(pci_resource_start(pdev, 2),
5003 CyPCI_Ywin);
5002 if (addr2 == NULL) { 5004 if (addr2 == NULL) {
5003 dev_err(&pdev->dev, "can't remap base region\n"); 5005 dev_err(&pdev->dev, "can't remap base region\n");
5004 goto err_unmap; 5006 goto err_unmap;
@@ -5013,7 +5015,8 @@ static int __devinit cy_pci_probe(struct pci_dev *pdev,
5013 } else if (device_id == PCI_DEVICE_ID_CYCLOM_Z_Hi) { 5015 } else if (device_id == PCI_DEVICE_ID_CYCLOM_Z_Hi) {
5014 struct RUNTIME_9060 __iomem *ctl_addr; 5016 struct RUNTIME_9060 __iomem *ctl_addr;
5015 5017
5016 ctl_addr = addr0 = pci_iomap(pdev, 0, CyPCI_Zctl); 5018 ctl_addr = addr0 = ioremap_nocache(pci_resource_start(pdev, 0),
5019 CyPCI_Zctl);
5017 if (addr0 == NULL) { 5020 if (addr0 == NULL) {
5018 dev_err(&pdev->dev, "can't remap ctl region\n"); 5021 dev_err(&pdev->dev, "can't remap ctl region\n");
5019 goto err_reg; 5022 goto err_reg;
@@ -5026,8 +5029,8 @@ static int __devinit cy_pci_probe(struct pci_dev *pdev,
5026 5029
5027 mailbox = (u32)readl(&ctl_addr->mail_box_0); 5030 mailbox = (u32)readl(&ctl_addr->mail_box_0);
5028 5031
5029 addr2 = pci_iomap(pdev, 2, mailbox == ZE_V1 ? 5032 addr2 = ioremap_nocache(pci_resource_start(pdev, 2),
5030 CyPCI_Ze_win : CyPCI_Zwin); 5033 mailbox == ZE_V1 ? CyPCI_Ze_win : CyPCI_Zwin);
5031 if (addr2 == NULL) { 5034 if (addr2 == NULL) {
5032 dev_err(&pdev->dev, "can't remap base region\n"); 5035 dev_err(&pdev->dev, "can't remap base region\n");
5033 goto err_unmap; 5036 goto err_unmap;
@@ -5159,9 +5162,9 @@ err_null:
5159 cy_card[card_no].base_addr = NULL; 5162 cy_card[card_no].base_addr = NULL;
5160 free_irq(irq, &cy_card[card_no]); 5163 free_irq(irq, &cy_card[card_no]);
5161err_unmap: 5164err_unmap:
5162 pci_iounmap(pdev, addr0); 5165 iounmap(addr0);
5163 if (addr2) 5166 if (addr2)
5164 pci_iounmap(pdev, addr2); 5167 iounmap(addr2);
5165err_reg: 5168err_reg:
5166 pci_release_regions(pdev); 5169 pci_release_regions(pdev);
5167err_dis: 5170err_dis:
@@ -5186,9 +5189,9 @@ static void __devexit cy_pci_remove(struct pci_dev *pdev)
5186 cy_writew(cinfo->ctl_addr + 0x68, 5189 cy_writew(cinfo->ctl_addr + 0x68,
5187 readw(cinfo->ctl_addr + 0x68) & ~0x0900); 5190 readw(cinfo->ctl_addr + 0x68) & ~0x0900);
5188 5191
5189 pci_iounmap(pdev, cinfo->base_addr); 5192 iounmap(cinfo->base_addr);
5190 if (cinfo->ctl_addr) 5193 if (cinfo->ctl_addr)
5191 pci_iounmap(pdev, cinfo->ctl_addr); 5194 iounmap(cinfo->ctl_addr);
5192 if (cinfo->irq 5195 if (cinfo->irq
5193#ifndef CONFIG_CYZ_INTR 5196#ifndef CONFIG_CYZ_INTR
5194 && !IS_CYC_Z(*cinfo) 5197 && !IS_CYC_Z(*cinfo)
diff --git a/drivers/char/epca.c b/drivers/char/epca.c
index 456e4ede049f..4998b2761e8f 100644
--- a/drivers/char/epca.c
+++ b/drivers/char/epca.c
@@ -1376,6 +1376,7 @@ static void post_fep_init(unsigned int crd)
1376 unsigned long flags; 1376 unsigned long flags;
1377 u16 tseg, rseg; 1377 u16 tseg, rseg;
1378 1378
1379 tty_port_init(&ch->port);
1379 ch->brdchan = bc; 1380 ch->brdchan = bc;
1380 ch->mailbox = gd; 1381 ch->mailbox = gd;
1381 INIT_WORK(&ch->tqueue, do_softint); 1382 INIT_WORK(&ch->tqueue, do_softint);
@@ -1510,10 +1511,6 @@ static void post_fep_init(unsigned int crd)
1510 ch->fepstopca = 0; 1511 ch->fepstopca = 0;
1511 1512
1512 ch->close_delay = 50; 1513 ch->close_delay = 50;
1513 ch->port.count = 0;
1514 ch->port.blocked_open = 0;
1515 init_waitqueue_head(&ch->port.open_wait);
1516 init_waitqueue_head(&ch->port.close_wait);
1517 1514
1518 spin_unlock_irqrestore(&epca_lock, flags); 1515 spin_unlock_irqrestore(&epca_lock, flags);
1519 } 1516 }
diff --git a/drivers/char/generic_serial.c b/drivers/char/generic_serial.c
index 19d3afb0e50c..c6090f84a2e4 100644
--- a/drivers/char/generic_serial.c
+++ b/drivers/char/generic_serial.c
@@ -54,8 +54,6 @@ int gs_put_char(struct tty_struct * tty, unsigned char ch)
54 54
55 func_enter (); 55 func_enter ();
56 56
57 if (!tty) return 0;
58
59 port = tty->driver_data; 57 port = tty->driver_data;
60 58
61 if (!port) return 0; 59 if (!port) return 0;
@@ -97,8 +95,6 @@ int gs_write(struct tty_struct * tty,
97 95
98 func_enter (); 96 func_enter ();
99 97
100 if (!tty) return 0;
101
102 port = tty->driver_data; 98 port = tty->driver_data;
103 99
104 if (!port) return 0; 100 if (!port) return 0;
@@ -185,7 +181,6 @@ static int gs_real_chars_in_buffer(struct tty_struct *tty)
185 struct gs_port *port; 181 struct gs_port *port;
186 func_enter (); 182 func_enter ();
187 183
188 if (!tty) return 0;
189 port = tty->driver_data; 184 port = tty->driver_data;
190 185
191 if (!port->rd) return 0; 186 if (!port->rd) return 0;
@@ -274,8 +269,6 @@ void gs_flush_buffer(struct tty_struct *tty)
274 269
275 func_enter (); 270 func_enter ();
276 271
277 if (!tty) return;
278
279 port = tty->driver_data; 272 port = tty->driver_data;
280 273
281 if (!port) return; 274 if (!port) return;
@@ -296,8 +289,6 @@ void gs_flush_chars(struct tty_struct * tty)
296 289
297 func_enter (); 290 func_enter ();
298 291
299 if (!tty) return;
300
301 port = tty->driver_data; 292 port = tty->driver_data;
302 293
303 if (!port) return; 294 if (!port) return;
@@ -321,8 +312,6 @@ void gs_stop(struct tty_struct * tty)
321 312
322 func_enter (); 313 func_enter ();
323 314
324 if (!tty) return;
325
326 port = tty->driver_data; 315 port = tty->driver_data;
327 316
328 if (!port) return; 317 if (!port) return;
@@ -341,8 +330,6 @@ void gs_start(struct tty_struct * tty)
341{ 330{
342 struct gs_port *port; 331 struct gs_port *port;
343 332
344 if (!tty) return;
345
346 port = tty->driver_data; 333 port = tty->driver_data;
347 334
348 if (!port) return; 335 if (!port) return;
@@ -393,8 +380,6 @@ void gs_hangup(struct tty_struct *tty)
393 380
394 func_enter (); 381 func_enter ();
395 382
396 if (!tty) return;
397
398 port = tty->driver_data; 383 port = tty->driver_data;
399 tty = port->port.tty; 384 tty = port->port.tty;
400 if (!tty) 385 if (!tty)
@@ -426,8 +411,6 @@ int gs_block_til_ready(void *port_, struct file * filp)
426 411
427 tty = port->port.tty; 412 tty = port->port.tty;
428 413
429 if (!tty) return 0;
430
431 gs_dprintk (GS_DEBUG_BTR, "Entering gs_block_till_ready.\n"); 414 gs_dprintk (GS_DEBUG_BTR, "Entering gs_block_till_ready.\n");
432 /* 415 /*
433 * If the device is in the middle of being closed, then block 416 * If the device is in the middle of being closed, then block
@@ -523,8 +506,6 @@ void gs_close(struct tty_struct * tty, struct file * filp)
523 506
524 func_enter (); 507 func_enter ();
525 508
526 if (!tty) return;
527
528 port = (struct gs_port *) tty->driver_data; 509 port = (struct gs_port *) tty->driver_data;
529 510
530 if (!port) return; 511 if (!port) return;
@@ -621,8 +602,6 @@ void gs_set_termios (struct tty_struct * tty,
621 602
622 func_enter(); 603 func_enter();
623 604
624 if (!tty) return;
625
626 port = tty->driver_data; 605 port = tty->driver_data;
627 606
628 if (!port) return; 607 if (!port) return;
diff --git a/drivers/char/hpet.c b/drivers/char/hpet.c
index b3f5dbc6d880..f3cfb4c76125 100644
--- a/drivers/char/hpet.c
+++ b/drivers/char/hpet.c
@@ -53,6 +53,11 @@
53 53
54#define HPET_RANGE_SIZE 1024 /* from HPET spec */ 54#define HPET_RANGE_SIZE 1024 /* from HPET spec */
55 55
56
57/* WARNING -- don't get confused. These macros are never used
58 * to write the (single) counter, and rarely to read it.
59 * They're badly named; to fix, someday.
60 */
56#if BITS_PER_LONG == 64 61#if BITS_PER_LONG == 64
57#define write_counter(V, MC) writeq(V, MC) 62#define write_counter(V, MC) writeq(V, MC)
58#define read_counter(MC) readq(MC) 63#define read_counter(MC) readq(MC)
@@ -77,7 +82,7 @@ static struct clocksource clocksource_hpet = {
77 .rating = 250, 82 .rating = 250,
78 .read = read_hpet, 83 .read = read_hpet,
79 .mask = CLOCKSOURCE_MASK(64), 84 .mask = CLOCKSOURCE_MASK(64),
80 .mult = 0, /*to be caluclated*/ 85 .mult = 0, /* to be calculated */
81 .shift = 10, 86 .shift = 10,
82 .flags = CLOCK_SOURCE_IS_CONTINUOUS, 87 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
83}; 88};
@@ -86,8 +91,6 @@ static struct clocksource *hpet_clocksource;
86 91
87/* A lock for concurrent access by app and isr hpet activity. */ 92/* A lock for concurrent access by app and isr hpet activity. */
88static DEFINE_SPINLOCK(hpet_lock); 93static DEFINE_SPINLOCK(hpet_lock);
89/* A lock for concurrent intermodule access to hpet and isr hpet activity. */
90static DEFINE_SPINLOCK(hpet_task_lock);
91 94
92#define HPET_DEV_NAME (7) 95#define HPET_DEV_NAME (7)
93 96
@@ -99,7 +102,6 @@ struct hpet_dev {
99 unsigned long hd_irqdata; 102 unsigned long hd_irqdata;
100 wait_queue_head_t hd_waitqueue; 103 wait_queue_head_t hd_waitqueue;
101 struct fasync_struct *hd_async_queue; 104 struct fasync_struct *hd_async_queue;
102 struct hpet_task *hd_task;
103 unsigned int hd_flags; 105 unsigned int hd_flags;
104 unsigned int hd_irq; 106 unsigned int hd_irq;
105 unsigned int hd_hdwirq; 107 unsigned int hd_hdwirq;
@@ -173,11 +175,6 @@ static irqreturn_t hpet_interrupt(int irq, void *data)
173 writel(isr, &devp->hd_hpet->hpet_isr); 175 writel(isr, &devp->hd_hpet->hpet_isr);
174 spin_unlock(&hpet_lock); 176 spin_unlock(&hpet_lock);
175 177
176 spin_lock(&hpet_task_lock);
177 if (devp->hd_task)
178 devp->hd_task->ht_func(devp->hd_task->ht_data);
179 spin_unlock(&hpet_task_lock);
180
181 wake_up_interruptible(&devp->hd_waitqueue); 178 wake_up_interruptible(&devp->hd_waitqueue);
182 179
183 kill_fasync(&devp->hd_async_queue, SIGIO, POLL_IN); 180 kill_fasync(&devp->hd_async_queue, SIGIO, POLL_IN);
@@ -185,6 +182,67 @@ static irqreturn_t hpet_interrupt(int irq, void *data)
185 return IRQ_HANDLED; 182 return IRQ_HANDLED;
186} 183}
187 184
185static void hpet_timer_set_irq(struct hpet_dev *devp)
186{
187 unsigned long v;
188 int irq, gsi;
189 struct hpet_timer __iomem *timer;
190
191 spin_lock_irq(&hpet_lock);
192 if (devp->hd_hdwirq) {
193 spin_unlock_irq(&hpet_lock);
194 return;
195 }
196
197 timer = devp->hd_timer;
198
199 /* we prefer level triggered mode */
200 v = readl(&timer->hpet_config);
201 if (!(v & Tn_INT_TYPE_CNF_MASK)) {
202 v |= Tn_INT_TYPE_CNF_MASK;
203 writel(v, &timer->hpet_config);
204 }
205 spin_unlock_irq(&hpet_lock);
206
207 v = (readq(&timer->hpet_config) & Tn_INT_ROUTE_CAP_MASK) >>
208 Tn_INT_ROUTE_CAP_SHIFT;
209
210 /*
211 * In PIC mode, skip IRQ0-4, IRQ6-9, IRQ12-15 which is always used by
212 * legacy device. In IO APIC mode, we skip all the legacy IRQS.
213 */
214 if (acpi_irq_model == ACPI_IRQ_MODEL_PIC)
215 v &= ~0xf3df;
216 else
217 v &= ~0xffff;
218
219 for (irq = find_first_bit(&v, HPET_MAX_IRQ); irq < HPET_MAX_IRQ;
220 irq = find_next_bit(&v, HPET_MAX_IRQ, 1 + irq)) {
221
222 if (irq >= NR_IRQS) {
223 irq = HPET_MAX_IRQ;
224 break;
225 }
226
227 gsi = acpi_register_gsi(irq, ACPI_LEVEL_SENSITIVE,
228 ACPI_ACTIVE_LOW);
229 if (gsi > 0)
230 break;
231
232 /* FIXME: Setup interrupt source table */
233 }
234
235 if (irq < HPET_MAX_IRQ) {
236 spin_lock_irq(&hpet_lock);
237 v = readl(&timer->hpet_config);
238 v |= irq << Tn_INT_ROUTE_CNF_SHIFT;
239 writel(v, &timer->hpet_config);
240 devp->hd_hdwirq = gsi;
241 spin_unlock_irq(&hpet_lock);
242 }
243 return;
244}
245
188static int hpet_open(struct inode *inode, struct file *file) 246static int hpet_open(struct inode *inode, struct file *file)
189{ 247{
190 struct hpet_dev *devp; 248 struct hpet_dev *devp;
@@ -199,8 +257,7 @@ static int hpet_open(struct inode *inode, struct file *file)
199 257
200 for (devp = NULL, hpetp = hpets; hpetp && !devp; hpetp = hpetp->hp_next) 258 for (devp = NULL, hpetp = hpets; hpetp && !devp; hpetp = hpetp->hp_next)
201 for (i = 0; i < hpetp->hp_ntimer; i++) 259 for (i = 0; i < hpetp->hp_ntimer; i++)
202 if (hpetp->hp_dev[i].hd_flags & HPET_OPEN 260 if (hpetp->hp_dev[i].hd_flags & HPET_OPEN)
203 || hpetp->hp_dev[i].hd_task)
204 continue; 261 continue;
205 else { 262 else {
206 devp = &hpetp->hp_dev[i]; 263 devp = &hpetp->hp_dev[i];
@@ -219,6 +276,8 @@ static int hpet_open(struct inode *inode, struct file *file)
219 spin_unlock_irq(&hpet_lock); 276 spin_unlock_irq(&hpet_lock);
220 unlock_kernel(); 277 unlock_kernel();
221 278
279 hpet_timer_set_irq(devp);
280
222 return 0; 281 return 0;
223} 282}
224 283
@@ -441,7 +500,11 @@ static int hpet_ioctl_ieon(struct hpet_dev *devp)
441 devp->hd_irq = irq; 500 devp->hd_irq = irq;
442 t = devp->hd_ireqfreq; 501 t = devp->hd_ireqfreq;
443 v = readq(&timer->hpet_config); 502 v = readq(&timer->hpet_config);
444 g = v | Tn_INT_ENB_CNF_MASK; 503
504 /* 64-bit comparators are not yet supported through the ioctls,
505 * so force this into 32-bit mode if it supports both modes
506 */
507 g = v | Tn_32MODE_CNF_MASK | Tn_INT_ENB_CNF_MASK;
445 508
446 if (devp->hd_flags & HPET_PERIODIC) { 509 if (devp->hd_flags & HPET_PERIODIC) {
447 write_counter(t, &timer->hpet_compare); 510 write_counter(t, &timer->hpet_compare);
@@ -451,6 +514,12 @@ static int hpet_ioctl_ieon(struct hpet_dev *devp)
451 v |= Tn_VAL_SET_CNF_MASK; 514 v |= Tn_VAL_SET_CNF_MASK;
452 writeq(v, &timer->hpet_config); 515 writeq(v, &timer->hpet_config);
453 local_irq_save(flags); 516 local_irq_save(flags);
517
518 /* NOTE: what we modify here is a hidden accumulator
519 * register supported by periodic-capable comparators.
520 * We never want to modify the (single) counter; that
521 * would affect all the comparators.
522 */
454 m = read_counter(&hpet->hpet_mc); 523 m = read_counter(&hpet->hpet_mc);
455 write_counter(t + m + hpetp->hp_delta, &timer->hpet_compare); 524 write_counter(t + m + hpetp->hp_delta, &timer->hpet_compare);
456 } else { 525 } else {
@@ -604,57 +673,6 @@ static int hpet_is_known(struct hpet_data *hdp)
604 return 0; 673 return 0;
605} 674}
606 675
607static inline int hpet_tpcheck(struct hpet_task *tp)
608{
609 struct hpet_dev *devp;
610 struct hpets *hpetp;
611
612 devp = tp->ht_opaque;
613
614 if (!devp)
615 return -ENXIO;
616
617 for (hpetp = hpets; hpetp; hpetp = hpetp->hp_next)
618 if (devp >= hpetp->hp_dev
619 && devp < (hpetp->hp_dev + hpetp->hp_ntimer)
620 && devp->hd_hpet == hpetp->hp_hpet)
621 return 0;
622
623 return -ENXIO;
624}
625
626#if 0
627int hpet_unregister(struct hpet_task *tp)
628{
629 struct hpet_dev *devp;
630 struct hpet_timer __iomem *timer;
631 int err;
632
633 if ((err = hpet_tpcheck(tp)))
634 return err;
635
636 spin_lock_irq(&hpet_task_lock);
637 spin_lock(&hpet_lock);
638
639 devp = tp->ht_opaque;
640 if (devp->hd_task != tp) {
641 spin_unlock(&hpet_lock);
642 spin_unlock_irq(&hpet_task_lock);
643 return -ENXIO;
644 }
645
646 timer = devp->hd_timer;
647 writeq((readq(&timer->hpet_config) & ~Tn_INT_ENB_CNF_MASK),
648 &timer->hpet_config);
649 devp->hd_flags &= ~(HPET_IE | HPET_PERIODIC);
650 devp->hd_task = NULL;
651 spin_unlock(&hpet_lock);
652 spin_unlock_irq(&hpet_task_lock);
653
654 return 0;
655}
656#endif /* 0 */
657
658static ctl_table hpet_table[] = { 676static ctl_table hpet_table[] = {
659 { 677 {
660 .ctl_name = CTL_UNNUMBERED, 678 .ctl_name = CTL_UNNUMBERED,
@@ -746,6 +764,7 @@ int hpet_alloc(struct hpet_data *hdp)
746 static struct hpets *last = NULL; 764 static struct hpets *last = NULL;
747 unsigned long period; 765 unsigned long period;
748 unsigned long long temp; 766 unsigned long long temp;
767 u32 remainder;
749 768
750 /* 769 /*
751 * hpet_alloc can be called by platform dependent code. 770 * hpet_alloc can be called by platform dependent code.
@@ -809,9 +828,13 @@ int hpet_alloc(struct hpet_data *hdp)
809 printk("%s %d", i > 0 ? "," : "", hdp->hd_irq[i]); 828 printk("%s %d", i > 0 ? "," : "", hdp->hd_irq[i]);
810 printk("\n"); 829 printk("\n");
811 830
812 printk(KERN_INFO "hpet%u: %u %d-bit timers, %Lu Hz\n", 831 temp = hpetp->hp_tick_freq;
813 hpetp->hp_which, hpetp->hp_ntimer, 832 remainder = do_div(temp, 1000000);
814 cap & HPET_COUNTER_SIZE_MASK ? 64 : 32, hpetp->hp_tick_freq); 833 printk(KERN_INFO
834 "hpet%u: %u comparators, %d-bit %u.%06u MHz counter\n",
835 hpetp->hp_which, hpetp->hp_ntimer,
836 cap & HPET_COUNTER_SIZE_MASK ? 64 : 32,
837 (unsigned) temp, remainder);
815 838
816 mcfg = readq(&hpet->hpet_config); 839 mcfg = readq(&hpet->hpet_config);
817 if ((mcfg & HPET_ENABLE_CNF_MASK) == 0) { 840 if ((mcfg & HPET_ENABLE_CNF_MASK) == 0) {
@@ -874,8 +897,6 @@ static acpi_status hpet_resources(struct acpi_resource *res, void *data)
874 hdp->hd_address = ioremap(addr.minimum, addr.address_length); 897 hdp->hd_address = ioremap(addr.minimum, addr.address_length);
875 898
876 if (hpet_is_known(hdp)) { 899 if (hpet_is_known(hdp)) {
877 printk(KERN_DEBUG "%s: 0x%lx is busy\n",
878 __func__, hdp->hd_phys_address);
879 iounmap(hdp->hd_address); 900 iounmap(hdp->hd_address);
880 return AE_ALREADY_EXISTS; 901 return AE_ALREADY_EXISTS;
881 } 902 }
@@ -891,8 +912,6 @@ static acpi_status hpet_resources(struct acpi_resource *res, void *data)
891 HPET_RANGE_SIZE); 912 HPET_RANGE_SIZE);
892 913
893 if (hpet_is_known(hdp)) { 914 if (hpet_is_known(hdp)) {
894 printk(KERN_DEBUG "%s: 0x%lx is busy\n",
895 __func__, hdp->hd_phys_address);
896 iounmap(hdp->hd_address); 915 iounmap(hdp->hd_address);
897 return AE_ALREADY_EXISTS; 916 return AE_ALREADY_EXISTS;
898 } 917 }
diff --git a/drivers/char/hvc_console.c b/drivers/char/hvc_console.c
index fd64137b1ab9..ec7aded0a2df 100644
--- a/drivers/char/hvc_console.c
+++ b/drivers/char/hvc_console.c
@@ -819,11 +819,11 @@ static int hvc_init(void)
819 hvc_driver = drv; 819 hvc_driver = drv;
820 return 0; 820 return 0;
821 821
822put_tty:
823 put_tty_driver(hvc_driver);
824stop_thread: 822stop_thread:
825 kthread_stop(hvc_task); 823 kthread_stop(hvc_task);
826 hvc_task = NULL; 824 hvc_task = NULL;
825put_tty:
826 put_tty_driver(drv);
827out: 827out:
828 return err; 828 return err;
829} 829}
diff --git a/drivers/char/ip2/Makefile b/drivers/char/ip2/Makefile
index 939618f62fe1..bc397d92b499 100644
--- a/drivers/char/ip2/Makefile
+++ b/drivers/char/ip2/Makefile
@@ -4,5 +4,5 @@
4 4
5obj-$(CONFIG_COMPUTONE) += ip2.o 5obj-$(CONFIG_COMPUTONE) += ip2.o
6 6
7ip2-objs := ip2base.o ip2main.o 7ip2-objs := ip2main.o
8 8
diff --git a/drivers/char/ip2/i2ellis.c b/drivers/char/ip2/i2ellis.c
index 3601017f58cf..29db44de399f 100644
--- a/drivers/char/ip2/i2ellis.c
+++ b/drivers/char/ip2/i2ellis.c
@@ -69,38 +69,6 @@ static DEFINE_RWLOCK(Dl_spinlock);
69//======================================================= 69//=======================================================
70 70
71//****************************************************************************** 71//******************************************************************************
72// Function: iiEllisInit()
73// Parameters: None
74//
75// Returns: Nothing
76//
77// Description:
78//
79// This routine performs any required initialization of the iiEllis subsystem.
80//
81//******************************************************************************
82static void
83iiEllisInit(void)
84{
85}
86
87//******************************************************************************
88// Function: iiEllisCleanup()
89// Parameters: None
90//
91// Returns: Nothing
92//
93// Description:
94//
95// This routine performs any required cleanup of the iiEllis subsystem.
96//
97//******************************************************************************
98static void
99iiEllisCleanup(void)
100{
101}
102
103//******************************************************************************
104// Function: iiSetAddress(pB, address, delay) 72// Function: iiSetAddress(pB, address, delay)
105// Parameters: pB - pointer to the board structure 73// Parameters: pB - pointer to the board structure
106// address - the purported I/O address of the board 74// address - the purported I/O address of the board
diff --git a/drivers/char/ip2/i2ellis.h b/drivers/char/ip2/i2ellis.h
index c88a64e527aa..fb6df2456018 100644
--- a/drivers/char/ip2/i2ellis.h
+++ b/drivers/char/ip2/i2ellis.h
@@ -511,7 +511,6 @@ typedef void (*delayFunc_t)(unsigned int);
511// 511//
512// Initialization of a board & structure is in four (five!) parts: 512// Initialization of a board & structure is in four (five!) parts:
513// 513//
514// 0) iiEllisInit() - Initialize iiEllis subsystem.
515// 1) iiSetAddress() - Define the board address & delay function for a board. 514// 1) iiSetAddress() - Define the board address & delay function for a board.
516// 2) iiReset() - Reset the board (provided it exists) 515// 2) iiReset() - Reset the board (provided it exists)
517// -- Note you may do this to several boards -- 516// -- Note you may do this to several boards --
@@ -523,7 +522,6 @@ typedef void (*delayFunc_t)(unsigned int);
523// loadware. To change loadware, you must begin again with step 2, resetting 522// loadware. To change loadware, you must begin again with step 2, resetting
524// the board again (step 1 not needed). 523// the board again (step 1 not needed).
525 524
526static void iiEllisInit(void);
527static int iiSetAddress(i2eBordStrPtr, int, delayFunc_t ); 525static int iiSetAddress(i2eBordStrPtr, int, delayFunc_t );
528static int iiReset(i2eBordStrPtr); 526static int iiReset(i2eBordStrPtr);
529static int iiResetDelay(i2eBordStrPtr); 527static int iiResetDelay(i2eBordStrPtr);
diff --git a/drivers/char/ip2/ip2base.c b/drivers/char/ip2/ip2base.c
deleted file mode 100644
index 8155e247c04b..000000000000
--- a/drivers/char/ip2/ip2base.c
+++ /dev/null
@@ -1,108 +0,0 @@
1// ip2.c
2// This is a dummy module to make the firmware available when needed
3// and allows it to be unloaded when not. Rumor is the __initdata
4// macro doesn't always works on all platforms so we use this kludge.
5// If not compiled as a module it just makes fip_firm avaliable then
6// __initdata should work as advertized
7//
8
9#include <linux/module.h>
10#include <linux/init.h>
11#include <linux/wait.h>
12
13#ifndef __init
14#define __init
15#endif
16#ifndef __initfunc
17#define __initfunc(a) a
18#endif
19#ifndef __initdata
20#define __initdata
21#endif
22
23#include "ip2types.h"
24
25int
26ip2_loadmain(int *, int *); // ref into ip2main.c
27
28/* Note: Add compiled in defaults to these arrays, not to the structure
29 in ip2.h any longer. That structure WILL get overridden
30 by these values, or command line values, or insmod values!!! =mhw=
31*/
32static int io[IP2_MAX_BOARDS]= { 0, 0, 0, 0 };
33static int irq[IP2_MAX_BOARDS] = { -1, -1, -1, -1 };
34
35static int poll_only = 0;
36
37MODULE_AUTHOR("Doug McNash");
38MODULE_DESCRIPTION("Computone IntelliPort Plus Driver");
39module_param_array(irq, int, NULL, 0);
40MODULE_PARM_DESC(irq,"Interrupts for IntelliPort Cards");
41module_param_array(io, int, NULL, 0);
42MODULE_PARM_DESC(io,"I/O ports for IntelliPort Cards");
43module_param(poll_only, bool, 0);
44MODULE_PARM_DESC(poll_only,"Do not use card interrupts");
45
46
47static int __init ip2_init(void)
48{
49 if( poll_only ) {
50 /* Hard lock the interrupts to zero */
51 irq[0] = irq[1] = irq[2] = irq[3] = 0;
52 }
53
54 return ip2_loadmain(io, irq);
55}
56module_init(ip2_init);
57
58MODULE_LICENSE("GPL");
59
60#ifndef MODULE
61/******************************************************************************
62 * ip2_setup:
63 * str: kernel command line string
64 *
65 * Can't autoprobe the boards so user must specify configuration on
66 * kernel command line. Sane people build it modular but the others
67 * come here.
68 *
69 * Alternating pairs of io,irq for up to 4 boards.
70 * ip2=io0,irq0,io1,irq1,io2,irq2,io3,irq3
71 *
72 * io=0 => No board
73 * io=1 => PCI
74 * io=2 => EISA
75 * else => ISA I/O address
76 *
77 * irq=0 or invalid for ISA will revert to polling mode
78 *
79 * Any value = -1, do not overwrite compiled in value.
80 *
81 ******************************************************************************/
82static int __init ip2_setup(char *str)
83{
84 int ints[10]; /* 4 boards, 2 parameters + 2 */
85 int i, j;
86
87 str = get_options (str, ARRAY_SIZE(ints), ints);
88
89 for( i = 0, j = 1; i < 4; i++ ) {
90 if( j > ints[0] ) {
91 break;
92 }
93 if( ints[j] >= 0 ) {
94 io[i] = ints[j];
95 }
96 j++;
97 if( j > ints[0] ) {
98 break;
99 }
100 if( ints[j] >= 0 ) {
101 irq[i] = ints[j];
102 }
103 j++;
104 }
105 return 1;
106}
107__setup("ip2=", ip2_setup);
108#endif /* !MODULE */
diff --git a/drivers/char/ip2/ip2main.c b/drivers/char/ip2/ip2main.c
index 689f9dcd3b86..6774572d3759 100644
--- a/drivers/char/ip2/ip2main.c
+++ b/drivers/char/ip2/ip2main.c
@@ -150,15 +150,12 @@ static int ip2_read_proc(char *, char **, off_t, int, int *, void * );
150/*************/ 150/*************/
151 151
152/* String constants to identify ourselves */ 152/* String constants to identify ourselves */
153static char *pcName = "Computone IntelliPort Plus multiport driver"; 153static const char pcName[] = "Computone IntelliPort Plus multiport driver";
154static char *pcVersion = "1.2.14"; 154static const char pcVersion[] = "1.2.14";
155 155
156/* String constants for port names */ 156/* String constants for port names */
157static char *pcDriver_name = "ip2"; 157static const char pcDriver_name[] = "ip2";
158static char *pcIpl = "ip2ipl"; 158static const char pcIpl[] = "ip2ipl";
159
160// cheezy kludge or genius - you decide?
161int ip2_loadmain(int *, int *);
162 159
163/***********************/ 160/***********************/
164/* Function Prototypes */ 161/* Function Prototypes */
@@ -240,8 +237,8 @@ static const struct file_operations ip2_ipl = {
240 .open = ip2_ipl_open, 237 .open = ip2_ipl_open,
241}; 238};
242 239
243static unsigned long irq_counter = 0; 240static unsigned long irq_counter;
244static unsigned long bh_counter = 0; 241static unsigned long bh_counter;
245 242
246// Use immediate queue to service interrupts 243// Use immediate queue to service interrupts
247#define USE_IQI 244#define USE_IQI
@@ -252,7 +249,6 @@ static unsigned long bh_counter = 0;
252 */ 249 */
253#define POLL_TIMEOUT (jiffies + 1) 250#define POLL_TIMEOUT (jiffies + 1)
254static DEFINE_TIMER(PollTimer, ip2_poll, 0, 0); 251static DEFINE_TIMER(PollTimer, ip2_poll, 0, 0);
255static char TimerOn;
256 252
257#ifdef IP2DEBUG_TRACE 253#ifdef IP2DEBUG_TRACE
258/* Trace (debug) buffer data */ 254/* Trace (debug) buffer data */
@@ -268,8 +264,8 @@ static int tracewrap;
268/**********/ 264/**********/
269 265
270#if defined(MODULE) && defined(IP2DEBUG_OPEN) 266#if defined(MODULE) && defined(IP2DEBUG_OPEN)
271#define DBG_CNT(s) printk(KERN_DEBUG "(%s): [%x] refc=%d, ttyc=%d, modc=%x -> %s\n", \ 267#define DBG_CNT(s) printk(KERN_DEBUG "(%s): [%x] ttyc=%d, modc=%x -> %s\n", \
272 tty->name,(pCh->flags),ip2_tty_driver->refcount, \ 268 tty->name,(pCh->flags), \
273 tty->count,/*GET_USE_COUNT(module)*/0,s) 269 tty->count,/*GET_USE_COUNT(module)*/0,s)
274#else 270#else
275#define DBG_CNT(s) 271#define DBG_CNT(s)
@@ -287,8 +283,9 @@ static int tracewrap;
287 283
288MODULE_AUTHOR("Doug McNash"); 284MODULE_AUTHOR("Doug McNash");
289MODULE_DESCRIPTION("Computone IntelliPort Plus Driver"); 285MODULE_DESCRIPTION("Computone IntelliPort Plus Driver");
286MODULE_LICENSE("GPL");
290 287
291static int poll_only = 0; 288static int poll_only;
292 289
293static int Eisa_irq; 290static int Eisa_irq;
294static int Eisa_slot; 291static int Eisa_slot;
@@ -297,34 +294,46 @@ static int iindx;
297static char rirqs[IP2_MAX_BOARDS]; 294static char rirqs[IP2_MAX_BOARDS];
298static int Valid_Irqs[] = { 3, 4, 5, 7, 10, 11, 12, 15, 0}; 295static int Valid_Irqs[] = { 3, 4, 5, 7, 10, 11, 12, 15, 0};
299 296
297/* Note: Add compiled in defaults to these arrays, not to the structure
298 in ip2.h any longer. That structure WILL get overridden
299 by these values, or command line values, or insmod values!!! =mhw=
300*/
301static int io[IP2_MAX_BOARDS];
302static int irq[IP2_MAX_BOARDS] = { -1, -1, -1, -1 };
303
304MODULE_AUTHOR("Doug McNash");
305MODULE_DESCRIPTION("Computone IntelliPort Plus Driver");
306module_param_array(irq, int, NULL, 0);
307MODULE_PARM_DESC(irq, "Interrupts for IntelliPort Cards");
308module_param_array(io, int, NULL, 0);
309MODULE_PARM_DESC(io, "I/O ports for IntelliPort Cards");
310module_param(poll_only, bool, 0);
311MODULE_PARM_DESC(poll_only, "Do not use card interrupts");
312
300/* for sysfs class support */ 313/* for sysfs class support */
301static struct class *ip2_class; 314static struct class *ip2_class;
302 315
303// Some functions to keep track of what irq's we have 316/* Some functions to keep track of what irqs we have */
304 317
305static int 318static int __init is_valid_irq(int irq)
306is_valid_irq(int irq)
307{ 319{
308 int *i = Valid_Irqs; 320 int *i = Valid_Irqs;
309 321
310 while ((*i != 0) && (*i != irq)) { 322 while (*i != 0 && *i != irq)
311 i++; 323 i++;
312 } 324
313 return (*i); 325 return *i;
314} 326}
315 327
316static void 328static void __init mark_requested_irq(char irq)
317mark_requested_irq( char irq )
318{ 329{
319 rirqs[iindx++] = irq; 330 rirqs[iindx++] = irq;
320} 331}
321 332
322#ifdef MODULE 333static int __exit clear_requested_irq(char irq)
323static int
324clear_requested_irq( char irq )
325{ 334{
326 int i; 335 int i;
327 for ( i = 0; i < IP2_MAX_BOARDS; ++i ) { 336 for (i = 0; i < IP2_MAX_BOARDS; ++i) {
328 if (rirqs[i] == irq) { 337 if (rirqs[i] == irq) {
329 rirqs[i] = 0; 338 rirqs[i] = 0;
330 return 1; 339 return 1;
@@ -332,17 +341,15 @@ clear_requested_irq( char irq )
332 } 341 }
333 return 0; 342 return 0;
334} 343}
335#endif
336 344
337static int 345static int have_requested_irq(char irq)
338have_requested_irq( char irq )
339{ 346{
340 // array init to zeros so 0 irq will not be requested as a side effect 347 /* array init to zeros so 0 irq will not be requested as a side
348 * effect */
341 int i; 349 int i;
342 for ( i = 0; i < IP2_MAX_BOARDS; ++i ) { 350 for (i = 0; i < IP2_MAX_BOARDS; ++i)
343 if (rirqs[i] == irq) 351 if (rirqs[i] == irq)
344 return 1; 352 return 1;
345 }
346 return 0; 353 return 0;
347} 354}
348 355
@@ -361,53 +368,45 @@ have_requested_irq( char irq )
361/* handle subsequent installations of the driver. All memory allocated by the */ 368/* handle subsequent installations of the driver. All memory allocated by the */
362/* driver should be returned since it may be unloaded from memory. */ 369/* driver should be returned since it may be unloaded from memory. */
363/******************************************************************************/ 370/******************************************************************************/
364#ifdef MODULE 371static void __exit ip2_cleanup_module(void)
365void __exit
366ip2_cleanup_module(void)
367{ 372{
368 int err; 373 int err;
369 int i; 374 int i;
370 375
371#ifdef IP2DEBUG_INIT 376 del_timer_sync(&PollTimer);
372 printk (KERN_DEBUG "Unloading %s: version %s\n", pcName, pcVersion );
373#endif
374 /* Stop poll timer if we had one. */
375 if ( TimerOn ) {
376 del_timer ( &PollTimer );
377 TimerOn = 0;
378 }
379 377
380 /* Reset the boards we have. */ 378 /* Reset the boards we have. */
381 for( i = 0; i < IP2_MAX_BOARDS; ++i ) { 379 for (i = 0; i < IP2_MAX_BOARDS; i++)
382 if ( i2BoardPtrTable[i] ) { 380 if (i2BoardPtrTable[i])
383 iiReset( i2BoardPtrTable[i] ); 381 iiReset(i2BoardPtrTable[i]);
384 }
385 }
386 382
387 /* The following is done at most once, if any boards were installed. */ 383 /* The following is done at most once, if any boards were installed. */
388 for ( i = 0; i < IP2_MAX_BOARDS; ++i ) { 384 for (i = 0; i < IP2_MAX_BOARDS; i++) {
389 if ( i2BoardPtrTable[i] ) { 385 if (i2BoardPtrTable[i]) {
390 iiResetDelay( i2BoardPtrTable[i] ); 386 iiResetDelay(i2BoardPtrTable[i]);
391 /* free io addresses and Tibet */ 387 /* free io addresses and Tibet */
392 release_region( ip2config.addr[i], 8 ); 388 release_region(ip2config.addr[i], 8);
393 device_destroy(ip2_class, MKDEV(IP2_IPL_MAJOR, 4 * i)); 389 device_destroy(ip2_class, MKDEV(IP2_IPL_MAJOR, 4 * i));
394 device_destroy(ip2_class, MKDEV(IP2_IPL_MAJOR, 4 * i + 1)); 390 device_destroy(ip2_class, MKDEV(IP2_IPL_MAJOR,
391 4 * i + 1));
395 } 392 }
396 /* Disable and remove interrupt handler. */ 393 /* Disable and remove interrupt handler. */
397 if ( (ip2config.irq[i] > 0) && have_requested_irq(ip2config.irq[i]) ) { 394 if (ip2config.irq[i] > 0 &&
398 free_irq ( ip2config.irq[i], (void *)&pcName); 395 have_requested_irq(ip2config.irq[i])) {
399 clear_requested_irq( ip2config.irq[i]); 396 free_irq(ip2config.irq[i], (void *)&pcName);
397 clear_requested_irq(ip2config.irq[i]);
400 } 398 }
401 } 399 }
402 class_destroy(ip2_class); 400 class_destroy(ip2_class);
403 if ( ( err = tty_unregister_driver ( ip2_tty_driver ) ) ) { 401 err = tty_unregister_driver(ip2_tty_driver);
404 printk(KERN_ERR "IP2: failed to unregister tty driver (%d)\n", err); 402 if (err)
405 } 403 printk(KERN_ERR "IP2: failed to unregister tty driver (%d)\n",
404 err);
406 put_tty_driver(ip2_tty_driver); 405 put_tty_driver(ip2_tty_driver);
407 unregister_chrdev(IP2_IPL_MAJOR, pcIpl); 406 unregister_chrdev(IP2_IPL_MAJOR, pcIpl);
408 remove_proc_entry("ip2mem", NULL); 407 remove_proc_entry("ip2mem", NULL);
409 408
410 // free memory 409 /* free memory */
411 for (i = 0; i < IP2_MAX_BOARDS; i++) { 410 for (i = 0; i < IP2_MAX_BOARDS; i++) {
412 void *pB; 411 void *pB;
413#ifdef CONFIG_PCI 412#ifdef CONFIG_PCI
@@ -417,24 +416,18 @@ ip2_cleanup_module(void)
417 ip2config.pci_dev[i] = NULL; 416 ip2config.pci_dev[i] = NULL;
418 } 417 }
419#endif 418#endif
420 if ((pB = i2BoardPtrTable[i]) != 0 ) { 419 pB = i2BoardPtrTable[i];
421 kfree ( pB ); 420 if (pB != NULL) {
421 kfree(pB);
422 i2BoardPtrTable[i] = NULL; 422 i2BoardPtrTable[i] = NULL;
423 } 423 }
424 if ((DevTableMem[i]) != NULL ) { 424 if (DevTableMem[i] != NULL) {
425 kfree ( DevTableMem[i] ); 425 kfree(DevTableMem[i]);
426 DevTableMem[i] = NULL; 426 DevTableMem[i] = NULL;
427 } 427 }
428 } 428 }
429
430 /* Cleanup the iiEllis subsystem. */
431 iiEllisCleanup();
432#ifdef IP2DEBUG_INIT
433 printk (KERN_DEBUG "IP2 Unloaded\n" );
434#endif
435} 429}
436module_exit(ip2_cleanup_module); 430module_exit(ip2_cleanup_module);
437#endif /* MODULE */
438 431
439static const struct tty_operations ip2_ops = { 432static const struct tty_operations ip2_ops = {
440 .open = ip2_open, 433 .open = ip2_open,
@@ -494,139 +487,168 @@ static const struct firmware *ip2_request_firmware(void)
494 return fw; 487 return fw;
495} 488}
496 489
497int 490#ifndef MODULE
498ip2_loadmain(int *iop, int *irqp) 491/******************************************************************************
492 * ip2_setup:
493 * str: kernel command line string
494 *
495 * Can't autoprobe the boards so user must specify configuration on
496 * kernel command line. Sane people build it modular but the others
497 * come here.
498 *
499 * Alternating pairs of io,irq for up to 4 boards.
500 * ip2=io0,irq0,io1,irq1,io2,irq2,io3,irq3
501 *
502 * io=0 => No board
503 * io=1 => PCI
504 * io=2 => EISA
505 * else => ISA I/O address
506 *
507 * irq=0 or invalid for ISA will revert to polling mode
508 *
509 * Any value = -1, do not overwrite compiled in value.
510 *
511 ******************************************************************************/
512static int __init ip2_setup(char *str)
513{
514 int j, ints[10]; /* 4 boards, 2 parameters + 2 */
515 unsigned int i;
516
517 str = get_options(str, ARRAY_SIZE(ints), ints);
518
519 for (i = 0, j = 1; i < 4; i++) {
520 if (j > ints[0])
521 break;
522 if (ints[j] >= 0)
523 io[i] = ints[j];
524 j++;
525 if (j > ints[0])
526 break;
527 if (ints[j] >= 0)
528 irq[i] = ints[j];
529 j++;
530 }
531 return 1;
532}
533__setup("ip2=", ip2_setup);
534#endif /* !MODULE */
535
536static int __init ip2_loadmain(void)
499{ 537{
500 int i, j, box; 538 int i, j, box;
501 int err = 0; 539 int err = 0;
502 static int loaded;
503 i2eBordStrPtr pB = NULL; 540 i2eBordStrPtr pB = NULL;
504 int rc = -1; 541 int rc = -1;
505 static struct pci_dev *pci_dev_i = NULL; 542 struct pci_dev *pdev = NULL;
506 const struct firmware *fw = NULL; 543 const struct firmware *fw = NULL;
507 544
508 ip2trace (ITRC_NO_PORT, ITRC_INIT, ITRC_ENTER, 0 ); 545 if (poll_only) {
546 /* Hard lock the interrupts to zero */
547 irq[0] = irq[1] = irq[2] = irq[3] = poll_only = 0;
548 }
549
550 ip2trace(ITRC_NO_PORT, ITRC_INIT, ITRC_ENTER, 0);
509 551
510 /* process command line arguments to modprobe or 552 /* process command line arguments to modprobe or
511 insmod i.e. iop & irqp */ 553 insmod i.e. iop & irqp */
512 /* irqp and iop should ALWAYS be specified now... But we check 554 /* irqp and iop should ALWAYS be specified now... But we check
513 them individually just to be sure, anyways... */ 555 them individually just to be sure, anyways... */
514 for ( i = 0; i < IP2_MAX_BOARDS; ++i ) { 556 for (i = 0; i < IP2_MAX_BOARDS; ++i) {
515 if (iop) { 557 ip2config.addr[i] = io[i];
516 ip2config.addr[i] = iop[i]; 558 if (irq[i] >= 0)
517 if (irqp) { 559 ip2config.irq[i] = irq[i];
518 if( irqp[i] >= 0 ) { 560 else
519 ip2config.irq[i] = irqp[i]; 561 ip2config.irq[i] = 0;
520 } else { 562 /* This is a little bit of a hack. If poll_only=1 on command
521 ip2config.irq[i] = 0; 563 line back in ip2.c OR all IRQs on all specified boards are
522 } 564 explicitly set to 0, then drop to poll only mode and override
523 // This is a little bit of a hack. If poll_only=1 on command 565 PCI or EISA interrupts. This superceeds the old hack of
524 // line back in ip2.c OR all IRQs on all specified boards are 566 triggering if all interrupts were zero (like da default).
525 // explicitly set to 0, then drop to poll only mode and override 567 Still a hack but less prone to random acts of terrorism.
526 // PCI or EISA interrupts. This superceeds the old hack of 568
527 // triggering if all interrupts were zero (like da default). 569 What we really should do, now that the IRQ default is set
528 // Still a hack but less prone to random acts of terrorism. 570 to -1, is to use 0 as a hard coded, do not probe.
529 // 571
530 // What we really should do, now that the IRQ default is set 572 /\/\|=mhw=|\/\/
531 // to -1, is to use 0 as a hard coded, do not probe. 573 */
532 // 574 poll_only |= irq[i];
533 // /\/\|=mhw=|\/\/
534 poll_only |= irqp[i];
535 }
536 }
537 } 575 }
538 poll_only = !poll_only; 576 poll_only = !poll_only;
539 577
540 /* Announce our presence */ 578 /* Announce our presence */
541 printk( KERN_INFO "%s version %s\n", pcName, pcVersion ); 579 printk(KERN_INFO "%s version %s\n", pcName, pcVersion);
542
543 // ip2 can be unloaded and reloaded for no good reason
544 // we can't let that happen here or bad things happen
545 // second load hoses board but not system - fixme later
546 if (loaded) {
547 printk( KERN_INFO "Still loaded\n" );
548 return 0;
549 }
550 loaded++;
551 580
552 ip2_tty_driver = alloc_tty_driver(IP2_MAX_PORTS); 581 ip2_tty_driver = alloc_tty_driver(IP2_MAX_PORTS);
553 if (!ip2_tty_driver) 582 if (!ip2_tty_driver)
554 return -ENOMEM; 583 return -ENOMEM;
555 584
556 /* Initialise the iiEllis subsystem. */
557 iiEllisInit();
558
559 /* Initialize arrays. */
560 memset( i2BoardPtrTable, 0, sizeof i2BoardPtrTable );
561 memset( DevTable, 0, sizeof DevTable );
562
563 /* Initialise all the boards we can find (up to the maximum). */ 585 /* Initialise all the boards we can find (up to the maximum). */
564 for ( i = 0; i < IP2_MAX_BOARDS; ++i ) { 586 for (i = 0; i < IP2_MAX_BOARDS; ++i) {
565 switch ( ip2config.addr[i] ) { 587 switch (ip2config.addr[i]) {
566 case 0: /* skip this slot even if card is present */ 588 case 0: /* skip this slot even if card is present */
567 break; 589 break;
568 default: /* ISA */ 590 default: /* ISA */
569 /* ISA address must be specified */ 591 /* ISA address must be specified */
570 if ( (ip2config.addr[i] < 0x100) || (ip2config.addr[i] > 0x3f8) ) { 592 if (ip2config.addr[i] < 0x100 ||
571 printk ( KERN_ERR "IP2: Bad ISA board %d address %x\n", 593 ip2config.addr[i] > 0x3f8) {
572 i, ip2config.addr[i] ); 594 printk(KERN_ERR "IP2: Bad ISA board %d "
595 "address %x\n", i,
596 ip2config.addr[i]);
573 ip2config.addr[i] = 0; 597 ip2config.addr[i] = 0;
574 } else { 598 break;
575 ip2config.type[i] = ISA; 599 }
576 600 ip2config.type[i] = ISA;
577 /* Check for valid irq argument, set for polling if invalid */ 601
578 if (ip2config.irq[i] && !is_valid_irq(ip2config.irq[i])) { 602 /* Check for valid irq argument, set for polling if
579 printk(KERN_ERR "IP2: Bad IRQ(%d) specified\n",ip2config.irq[i]); 603 * invalid */
580 ip2config.irq[i] = 0;// 0 is polling and is valid in that sense 604 if (ip2config.irq[i] &&
581 } 605 !is_valid_irq(ip2config.irq[i])) {
606 printk(KERN_ERR "IP2: Bad IRQ(%d) specified\n",
607 ip2config.irq[i]);
608 /* 0 is polling and is valid in that sense */
609 ip2config.irq[i] = 0;
582 } 610 }
583 break; 611 break;
584 case PCI: 612 case PCI:
585#ifdef CONFIG_PCI 613#ifdef CONFIG_PCI
586 { 614 {
587 int status; 615 u32 addr;
616 int status;
588 617
589 pci_dev_i = pci_get_device(PCI_VENDOR_ID_COMPUTONE, 618 pdev = pci_get_device(PCI_VENDOR_ID_COMPUTONE,
590 PCI_DEVICE_ID_COMPUTONE_IP2EX, pci_dev_i); 619 PCI_DEVICE_ID_COMPUTONE_IP2EX, pdev);
591 if (pci_dev_i != NULL) { 620 if (pdev == NULL) {
592 unsigned int addr; 621 ip2config.addr[i] = 0;
593 622 printk(KERN_ERR "IP2: PCI board %d not "
594 if (pci_enable_device(pci_dev_i)) { 623 "found\n", i);
595 printk( KERN_ERR "IP2: can't enable PCI device at %s\n", 624 break;
596 pci_name(pci_dev_i)); 625 }
597 break;
598 }
599 ip2config.type[i] = PCI;
600 ip2config.pci_dev[i] = pci_dev_get(pci_dev_i);
601 status =
602 pci_read_config_dword(pci_dev_i, PCI_BASE_ADDRESS_1, &addr);
603 if ( addr & 1 ) {
604 ip2config.addr[i]=(USHORT)(addr&0xfffe);
605 } else {
606 printk( KERN_ERR "IP2: PCI I/O address error\n");
607 }
608 626
609// If the PCI BIOS assigned it, lets try and use it. If we 627 if (pci_enable_device(pdev)) {
610// can't acquire it or it screws up, deal with it then. 628 dev_err(&pdev->dev, "can't enable device\n");
611 629 break;
612// if (!is_valid_irq(pci_irq)) {
613// printk( KERN_ERR "IP2: Bad PCI BIOS IRQ(%d)\n",pci_irq);
614// pci_irq = 0;
615// }
616 ip2config.irq[i] = pci_dev_i->irq;
617 } else { // ann error
618 ip2config.addr[i] = 0;
619 printk(KERN_ERR "IP2: PCI board %d not found\n", i);
620 }
621 } 630 }
631 ip2config.type[i] = PCI;
632 ip2config.pci_dev[i] = pci_dev_get(pdev);
633 status = pci_read_config_dword(pdev, PCI_BASE_ADDRESS_1,
634 &addr);
635 if (addr & 1)
636 ip2config.addr[i] = (USHORT)(addr & 0xfffe);
637 else
638 dev_err(&pdev->dev, "I/O address error\n");
639
640 ip2config.irq[i] = pdev->irq;
641 }
622#else 642#else
623 printk( KERN_ERR "IP2: PCI card specified but PCI support not\n"); 643 printk(KERN_ERR "IP2: PCI card specified but PCI "
624 printk( KERN_ERR "IP2: configured in this kernel.\n"); 644 "support not enabled.\n");
625 printk( KERN_ERR "IP2: Recompile kernel with CONFIG_PCI defined!\n"); 645 printk(KERN_ERR "IP2: Recompile kernel with CONFIG_PCI "
646 "defined!\n");
626#endif /* CONFIG_PCI */ 647#endif /* CONFIG_PCI */
627 break; 648 break;
628 case EISA: 649 case EISA:
629 if ( (ip2config.addr[i] = find_eisa_board( Eisa_slot + 1 )) != 0) { 650 ip2config.addr[i] = find_eisa_board(Eisa_slot + 1);
651 if (ip2config.addr[i] != 0) {
630 /* Eisa_irq set as side effect, boo */ 652 /* Eisa_irq set as side effect, boo */
631 ip2config.type[i] = EISA; 653 ip2config.type[i] = EISA;
632 } 654 }
@@ -634,31 +656,32 @@ ip2_loadmain(int *iop, int *irqp)
634 break; 656 break;
635 } /* switch */ 657 } /* switch */
636 } /* for */ 658 } /* for */
637 if (pci_dev_i) 659 pci_dev_put(pdev);
638 pci_dev_put(pci_dev_i);
639 660
640 for ( i = 0; i < IP2_MAX_BOARDS; ++i ) { 661 for (i = 0; i < IP2_MAX_BOARDS; ++i) {
641 if ( ip2config.addr[i] ) { 662 if (ip2config.addr[i]) {
642 pB = kzalloc(sizeof(i2eBordStr), GFP_KERNEL); 663 pB = kzalloc(sizeof(i2eBordStr), GFP_KERNEL);
643 if (pB) { 664 if (pB) {
644 i2BoardPtrTable[i] = pB; 665 i2BoardPtrTable[i] = pB;
645 iiSetAddress( pB, ip2config.addr[i], ii2DelayTimer ); 666 iiSetAddress(pB, ip2config.addr[i],
646 iiReset( pB ); 667 ii2DelayTimer);
647 } else { 668 iiReset(pB);
648 printk(KERN_ERR "IP2: board memory allocation error\n"); 669 } else
649 } 670 printk(KERN_ERR "IP2: board memory allocation "
671 "error\n");
650 } 672 }
651 } 673 }
652 for ( i = 0; i < IP2_MAX_BOARDS; ++i ) { 674 for (i = 0; i < IP2_MAX_BOARDS; ++i) {
653 if ( ( pB = i2BoardPtrTable[i] ) != NULL ) { 675 pB = i2BoardPtrTable[i];
654 iiResetDelay( pB ); 676 if (pB != NULL) {
677 iiResetDelay(pB);
655 break; 678 break;
656 } 679 }
657 } 680 }
658 for ( i = 0; i < IP2_MAX_BOARDS; ++i ) { 681 for (i = 0; i < IP2_MAX_BOARDS; ++i) {
659 /* We don't want to request the firmware unless we have at 682 /* We don't want to request the firmware unless we have at
660 least one board */ 683 least one board */
661 if ( i2BoardPtrTable[i] != NULL ) { 684 if (i2BoardPtrTable[i] != NULL) {
662 if (!fw) 685 if (!fw)
663 fw = ip2_request_firmware(); 686 fw = ip2_request_firmware();
664 if (!fw) 687 if (!fw)
@@ -669,7 +692,7 @@ ip2_loadmain(int *iop, int *irqp)
669 if (fw) 692 if (fw)
670 release_firmware(fw); 693 release_firmware(fw);
671 694
672 ip2trace (ITRC_NO_PORT, ITRC_INIT, 2, 0 ); 695 ip2trace(ITRC_NO_PORT, ITRC_INIT, 2, 0);
673 696
674 ip2_tty_driver->owner = THIS_MODULE; 697 ip2_tty_driver->owner = THIS_MODULE;
675 ip2_tty_driver->name = "ttyF"; 698 ip2_tty_driver->name = "ttyF";
@@ -680,20 +703,23 @@ ip2_loadmain(int *iop, int *irqp)
680 ip2_tty_driver->subtype = SERIAL_TYPE_NORMAL; 703 ip2_tty_driver->subtype = SERIAL_TYPE_NORMAL;
681 ip2_tty_driver->init_termios = tty_std_termios; 704 ip2_tty_driver->init_termios = tty_std_termios;
682 ip2_tty_driver->init_termios.c_cflag = B9600|CS8|CREAD|HUPCL|CLOCAL; 705 ip2_tty_driver->init_termios.c_cflag = B9600|CS8|CREAD|HUPCL|CLOCAL;
683 ip2_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; 706 ip2_tty_driver->flags = TTY_DRIVER_REAL_RAW |
707 TTY_DRIVER_DYNAMIC_DEV;
684 tty_set_operations(ip2_tty_driver, &ip2_ops); 708 tty_set_operations(ip2_tty_driver, &ip2_ops);
685 709
686 ip2trace (ITRC_NO_PORT, ITRC_INIT, 3, 0 ); 710 ip2trace(ITRC_NO_PORT, ITRC_INIT, 3, 0);
687 711
688 /* Register the tty devices. */ 712 err = tty_register_driver(ip2_tty_driver);
689 if ( ( err = tty_register_driver ( ip2_tty_driver ) ) ) { 713 if (err) {
690 printk(KERN_ERR "IP2: failed to register tty driver (%d)\n", err); 714 printk(KERN_ERR "IP2: failed to register tty driver\n");
691 put_tty_driver(ip2_tty_driver); 715 put_tty_driver(ip2_tty_driver);
692 return -EINVAL; 716 return err; /* leaking resources */
693 } else 717 }
694 /* Register the IPL driver. */ 718
695 if ( ( err = register_chrdev ( IP2_IPL_MAJOR, pcIpl, &ip2_ipl ) ) ) { 719 err = register_chrdev(IP2_IPL_MAJOR, pcIpl, &ip2_ipl);
696 printk(KERN_ERR "IP2: failed to register IPL device (%d)\n", err ); 720 if (err) {
721 printk(KERN_ERR "IP2: failed to register IPL device (%d)\n",
722 err);
697 } else { 723 } else {
698 /* create the sysfs class */ 724 /* create the sysfs class */
699 ip2_class = class_create(THIS_MODULE, "ip2"); 725 ip2_class = class_create(THIS_MODULE, "ip2");
@@ -705,84 +731,86 @@ ip2_loadmain(int *iop, int *irqp)
705 /* Register the read_procmem thing */ 731 /* Register the read_procmem thing */
706 if (!proc_create("ip2mem",0,NULL,&ip2mem_proc_fops)) { 732 if (!proc_create("ip2mem",0,NULL,&ip2mem_proc_fops)) {
707 printk(KERN_ERR "IP2: failed to register read_procmem\n"); 733 printk(KERN_ERR "IP2: failed to register read_procmem\n");
708 } else { 734 return -EIO; /* leaking resources */
735 }
709 736
710 ip2trace (ITRC_NO_PORT, ITRC_INIT, 4, 0 ); 737 ip2trace(ITRC_NO_PORT, ITRC_INIT, 4, 0);
711 /* Register the interrupt handler or poll handler, depending upon the 738 /* Register the interrupt handler or poll handler, depending upon the
712 * specified interrupt. 739 * specified interrupt.
713 */ 740 */
714 741
715 for( i = 0; i < IP2_MAX_BOARDS; ++i ) { 742 for (i = 0; i < IP2_MAX_BOARDS; ++i) {
716 if ( 0 == ip2config.addr[i] ) { 743 if (ip2config.addr[i] == 0)
717 continue; 744 continue;
718 }
719 745
720 if ( NULL != ( pB = i2BoardPtrTable[i] ) ) { 746 pB = i2BoardPtrTable[i];
721 device_create_drvdata(ip2_class, NULL, 747 if (pB != NULL) {
722 MKDEV(IP2_IPL_MAJOR, 4 * i), 748 device_create_drvdata(ip2_class, NULL,
723 NULL, "ipl%d", i); 749 MKDEV(IP2_IPL_MAJOR, 4 * i),
724 device_create_drvdata(ip2_class, NULL, 750 NULL, "ipl%d", i);
725 MKDEV(IP2_IPL_MAJOR, 4 * i + 1), 751 device_create_drvdata(ip2_class, NULL,
726 NULL, "stat%d", i); 752 MKDEV(IP2_IPL_MAJOR, 4 * i + 1),
727 753 NULL, "stat%d", i);
728 for ( box = 0; box < ABS_MAX_BOXES; ++box ) 754
729 { 755 for (box = 0; box < ABS_MAX_BOXES; box++)
730 for ( j = 0; j < ABS_BIGGEST_BOX; ++j ) 756 for (j = 0; j < ABS_BIGGEST_BOX; j++)
731 { 757 if (pB->i2eChannelMap[box] & (1 << j))
732 if ( pB->i2eChannelMap[box] & (1 << j) ) 758 tty_register_device(
733 { 759 ip2_tty_driver,
734 tty_register_device(ip2_tty_driver, 760 j + ABS_BIGGEST_BOX *
735 j + ABS_BIGGEST_BOX * 761 (box+i*ABS_MAX_BOXES),
736 (box+i*ABS_MAX_BOXES), NULL); 762 NULL);
737 } 763 }
738 }
739 }
740 }
741 764
742 if (poll_only) { 765 if (poll_only) {
743// Poll only forces driver to only use polling and 766 /* Poll only forces driver to only use polling and
744// to ignore the probed PCI or EISA interrupts. 767 to ignore the probed PCI or EISA interrupts. */
745 ip2config.irq[i] = CIR_POLL; 768 ip2config.irq[i] = CIR_POLL;
746 } 769 }
747 if ( ip2config.irq[i] == CIR_POLL ) { 770 if (ip2config.irq[i] == CIR_POLL) {
748retry: 771retry:
749 if (!TimerOn) { 772 if (!timer_pending(&PollTimer)) {
750 PollTimer.expires = POLL_TIMEOUT; 773 mod_timer(&PollTimer, POLL_TIMEOUT);
751 add_timer ( &PollTimer ); 774 printk(KERN_INFO "IP2: polling\n");
752 TimerOn = 1;
753 printk( KERN_INFO "IP2: polling\n");
754 }
755 } else {
756 if (have_requested_irq(ip2config.irq[i]))
757 continue;
758 rc = request_irq( ip2config.irq[i], ip2_interrupt,
759 IP2_SA_FLAGS | (ip2config.type[i] == PCI ? IRQF_SHARED : 0),
760 pcName, i2BoardPtrTable[i]);
761 if (rc) {
762 printk(KERN_ERR "IP2: an request_irq failed: error %d\n",rc);
763 ip2config.irq[i] = CIR_POLL;
764 printk( KERN_INFO "IP2: Polling %ld/sec.\n",
765 (POLL_TIMEOUT - jiffies));
766 goto retry;
767 }
768 mark_requested_irq(ip2config.irq[i]);
769 /* Initialise the interrupt handler bottom half (aka slih). */
770 } 775 }
771 } 776 } else {
772 for( i = 0; i < IP2_MAX_BOARDS; ++i ) { 777 if (have_requested_irq(ip2config.irq[i]))
773 if ( i2BoardPtrTable[i] ) { 778 continue;
774 set_irq( i, ip2config.irq[i] ); /* set and enable board interrupt */ 779 rc = request_irq(ip2config.irq[i], ip2_interrupt,
780 IP2_SA_FLAGS |
781 (ip2config.type[i] == PCI ? IRQF_SHARED : 0),
782 pcName, i2BoardPtrTable[i]);
783 if (rc) {
784 printk(KERN_ERR "IP2: request_irq failed: "
785 "error %d\n", rc);
786 ip2config.irq[i] = CIR_POLL;
787 printk(KERN_INFO "IP2: Polling %ld/sec.\n",
788 (POLL_TIMEOUT - jiffies));
789 goto retry;
775 } 790 }
791 mark_requested_irq(ip2config.irq[i]);
792 /* Initialise the interrupt handler bottom half
793 * (aka slih). */
776 } 794 }
777 } 795 }
778 ip2trace (ITRC_NO_PORT, ITRC_INIT, ITRC_RETURN, 0 ); 796
779 goto out; 797 for (i = 0; i < IP2_MAX_BOARDS; ++i) {
798 if (i2BoardPtrTable[i]) {
799 /* set and enable board interrupt */
800 set_irq(i, ip2config.irq[i]);
801 }
802 }
803
804 ip2trace(ITRC_NO_PORT, ITRC_INIT, ITRC_RETURN, 0);
805
806 return 0;
780 807
781out_chrdev: 808out_chrdev:
782 unregister_chrdev(IP2_IPL_MAJOR, "ip2"); 809 unregister_chrdev(IP2_IPL_MAJOR, "ip2");
783out: 810 /* unregister and put tty here */
784 return err; 811 return err;
785} 812}
813module_init(ip2_loadmain);
786 814
787/******************************************************************************/ 815/******************************************************************************/
788/* Function: ip2_init_board() */ 816/* Function: ip2_init_board() */
@@ -1199,9 +1227,8 @@ ip2_polled_interrupt(void)
1199{ 1227{
1200 int i; 1228 int i;
1201 i2eBordStrPtr pB; 1229 i2eBordStrPtr pB;
1202 const int irq = 0;
1203 1230
1204 ip2trace (ITRC_NO_PORT, ITRC_INTR, 99, 1, irq ); 1231 ip2trace(ITRC_NO_PORT, ITRC_INTR, 99, 1, 0);
1205 1232
1206 /* Service just the boards on the list using this irq */ 1233 /* Service just the boards on the list using this irq */
1207 for( i = 0; i < i2nBoards; ++i ) { 1234 for( i = 0; i < i2nBoards; ++i ) {
@@ -1210,9 +1237,8 @@ ip2_polled_interrupt(void)
1210// Only process those boards which match our IRQ. 1237// Only process those boards which match our IRQ.
1211// IRQ = 0 for polled boards, we won't poll "IRQ" boards 1238// IRQ = 0 for polled boards, we won't poll "IRQ" boards
1212 1239
1213 if ( pB && (pB->i2eUsingIrq == irq) ) { 1240 if (pB && pB->i2eUsingIrq == 0)
1214 ip2_irq_work(pB); 1241 ip2_irq_work(pB);
1215 }
1216 } 1242 }
1217 1243
1218 ++irq_counter; 1244 ++irq_counter;
@@ -1250,16 +1276,12 @@ ip2_poll(unsigned long arg)
1250{ 1276{
1251 ip2trace (ITRC_NO_PORT, ITRC_INTR, 100, 0 ); 1277 ip2trace (ITRC_NO_PORT, ITRC_INTR, 100, 0 );
1252 1278
1253 TimerOn = 0; // it's the truth but not checked in service
1254
1255 // Just polled boards, IRQ = 0 will hit all non-interrupt boards. 1279 // Just polled boards, IRQ = 0 will hit all non-interrupt boards.
1256 // It will NOT poll boards handled by hard interrupts. 1280 // It will NOT poll boards handled by hard interrupts.
1257 // The issue of queued BH interrupts is handled in ip2_interrupt(). 1281 // The issue of queued BH interrupts is handled in ip2_interrupt().
1258 ip2_polled_interrupt(); 1282 ip2_polled_interrupt();
1259 1283
1260 PollTimer.expires = POLL_TIMEOUT; 1284 mod_timer(&PollTimer, POLL_TIMEOUT);
1261 add_timer( &PollTimer );
1262 TimerOn = 1;
1263 1285
1264 ip2trace (ITRC_NO_PORT, ITRC_INTR, ITRC_RETURN, 0 ); 1286 ip2trace (ITRC_NO_PORT, ITRC_INTR, ITRC_RETURN, 0 );
1265} 1287}
@@ -2871,7 +2893,7 @@ ip2_ipl_ioctl (struct file *pFile, UINT cmd, ULONG arg )
2871 case 13: 2893 case 13:
2872 switch ( cmd ) { 2894 switch ( cmd ) {
2873 case 64: /* Driver - ip2stat */ 2895 case 64: /* Driver - ip2stat */
2874 rc = put_user(ip2_tty_driver->refcount, pIndex++ ); 2896 rc = put_user(-1, pIndex++ );
2875 rc = put_user(irq_counter, pIndex++ ); 2897 rc = put_user(irq_counter, pIndex++ );
2876 rc = put_user(bh_counter, pIndex++ ); 2898 rc = put_user(bh_counter, pIndex++ );
2877 break; 2899 break;
diff --git a/drivers/char/isicom.c b/drivers/char/isicom.c
index 8f7cc190b62d..7d30ee1d3fca 100644
--- a/drivers/char/isicom.c
+++ b/drivers/char/isicom.c
@@ -421,17 +421,16 @@ static void isicom_tx(unsigned long _data)
421 if (retries >= 100) 421 if (retries >= 100)
422 goto unlock; 422 goto unlock;
423 423
424 tty = tty_port_tty_get(&port->port);
425 if (tty == NULL)
426 goto put_unlock;
427
424 for (; count > 0; count--, port++) { 428 for (; count > 0; count--, port++) {
425 /* port not active or tx disabled to force flow control */ 429 /* port not active or tx disabled to force flow control */
426 if (!(port->port.flags & ASYNC_INITIALIZED) || 430 if (!(port->port.flags & ASYNC_INITIALIZED) ||
427 !(port->status & ISI_TXOK)) 431 !(port->status & ISI_TXOK))
428 continue; 432 continue;
429 433
430 tty = port->port.tty;
431
432 if (tty == NULL)
433 continue;
434
435 txcount = min_t(short, TX_SIZE, port->xmit_cnt); 434 txcount = min_t(short, TX_SIZE, port->xmit_cnt);
436 if (txcount <= 0 || tty->stopped || tty->hw_stopped) 435 if (txcount <= 0 || tty->stopped || tty->hw_stopped)
437 continue; 436 continue;
@@ -489,6 +488,8 @@ static void isicom_tx(unsigned long _data)
489 tty_wakeup(tty); 488 tty_wakeup(tty);
490 } 489 }
491 490
491put_unlock:
492 tty_kref_put(tty);
492unlock: 493unlock:
493 spin_unlock_irqrestore(&isi_card[card].card_lock, flags); 494 spin_unlock_irqrestore(&isi_card[card].card_lock, flags);
494 /* schedule another tx for hopefully in about 10ms */ 495 /* schedule another tx for hopefully in about 10ms */
@@ -547,7 +548,7 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id)
547 return IRQ_HANDLED; 548 return IRQ_HANDLED;
548 } 549 }
549 550
550 tty = port->port.tty; 551 tty = tty_port_tty_get(&port->port);
551 if (tty == NULL) { 552 if (tty == NULL) {
552 word_count = byte_count >> 1; 553 word_count = byte_count >> 1;
553 while (byte_count > 1) { 554 while (byte_count > 1) {
@@ -588,7 +589,7 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id)
588 } 589 }
589 590
590 if (port->port.flags & ASYNC_CTS_FLOW) { 591 if (port->port.flags & ASYNC_CTS_FLOW) {
591 if (port->port.tty->hw_stopped) { 592 if (tty->hw_stopped) {
592 if (header & ISI_CTS) { 593 if (header & ISI_CTS) {
593 port->port.tty->hw_stopped = 0; 594 port->port.tty->hw_stopped = 0;
594 /* start tx ing */ 595 /* start tx ing */
@@ -597,7 +598,7 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id)
597 tty_wakeup(tty); 598 tty_wakeup(tty);
598 } 599 }
599 } else if (!(header & ISI_CTS)) { 600 } else if (!(header & ISI_CTS)) {
600 port->port.tty->hw_stopped = 1; 601 tty->hw_stopped = 1;
601 /* stop tx ing */ 602 /* stop tx ing */
602 port->status &= ~(ISI_TXOK | ISI_CTS); 603 port->status &= ~(ISI_TXOK | ISI_CTS);
603 } 604 }
@@ -660,24 +661,21 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id)
660 } 661 }
661 outw(0x0000, base+0x04); /* enable interrupts */ 662 outw(0x0000, base+0x04); /* enable interrupts */
662 spin_unlock(&card->card_lock); 663 spin_unlock(&card->card_lock);
664 tty_kref_put(tty);
663 665
664 return IRQ_HANDLED; 666 return IRQ_HANDLED;
665} 667}
666 668
667static void isicom_config_port(struct isi_port *port) 669static void isicom_config_port(struct tty_struct *tty)
668{ 670{
671 struct isi_port *port = tty->driver_data;
669 struct isi_board *card = port->card; 672 struct isi_board *card = port->card;
670 struct tty_struct *tty;
671 unsigned long baud; 673 unsigned long baud;
672 unsigned long base = card->base; 674 unsigned long base = card->base;
673 u16 channel_setup, channel = port->channel, 675 u16 channel_setup, channel = port->channel,
674 shift_count = card->shift_count; 676 shift_count = card->shift_count;
675 unsigned char flow_ctrl; 677 unsigned char flow_ctrl;
676 678
677 tty = port->port.tty;
678
679 if (tty == NULL)
680 return;
681 /* FIXME: Switch to new tty baud API */ 679 /* FIXME: Switch to new tty baud API */
682 baud = C_BAUD(tty); 680 baud = C_BAUD(tty);
683 if (baud & CBAUDEX) { 681 if (baud & CBAUDEX) {
@@ -690,7 +688,7 @@ static void isicom_config_port(struct isi_port *port)
690 688
691 /* 1,2,3,4 => 57.6, 115.2, 230, 460 kbps resp. */ 689 /* 1,2,3,4 => 57.6, 115.2, 230, 460 kbps resp. */
692 if (baud < 1 || baud > 4) 690 if (baud < 1 || baud > 4)
693 port->port.tty->termios->c_cflag &= ~CBAUDEX; 691 tty->termios->c_cflag &= ~CBAUDEX;
694 else 692 else
695 baud += 15; 693 baud += 15;
696 } 694 }
@@ -797,8 +795,9 @@ static inline void isicom_setup_board(struct isi_board *bp)
797 spin_unlock_irqrestore(&bp->card_lock, flags); 795 spin_unlock_irqrestore(&bp->card_lock, flags);
798} 796}
799 797
800static int isicom_setup_port(struct isi_port *port) 798static int isicom_setup_port(struct tty_struct *tty)
801{ 799{
800 struct isi_port *port = tty->driver_data;
802 struct isi_board *card = port->card; 801 struct isi_board *card = port->card;
803 unsigned long flags; 802 unsigned long flags;
804 803
@@ -808,8 +807,7 @@ static int isicom_setup_port(struct isi_port *port)
808 return -ENOMEM; 807 return -ENOMEM;
809 808
810 spin_lock_irqsave(&card->card_lock, flags); 809 spin_lock_irqsave(&card->card_lock, flags);
811 if (port->port.tty) 810 clear_bit(TTY_IO_ERROR, &tty->flags);
812 clear_bit(TTY_IO_ERROR, &port->port.tty->flags);
813 if (port->port.count == 1) 811 if (port->port.count == 1)
814 card->count++; 812 card->count++;
815 813
@@ -823,7 +821,7 @@ static int isicom_setup_port(struct isi_port *port)
823 InterruptTheCard(card->base); 821 InterruptTheCard(card->base);
824 } 822 }
825 823
826 isicom_config_port(port); 824 isicom_config_port(tty);
827 port->port.flags |= ASYNC_INITIALIZED; 825 port->port.flags |= ASYNC_INITIALIZED;
828 spin_unlock_irqrestore(&card->card_lock, flags); 826 spin_unlock_irqrestore(&card->card_lock, flags);
829 827
@@ -934,8 +932,8 @@ static int isicom_open(struct tty_struct *tty, struct file *filp)
934 932
935 port->port.count++; 933 port->port.count++;
936 tty->driver_data = port; 934 tty->driver_data = port;
937 port->port.tty = tty; 935 tty_port_tty_set(&port->port, tty);
938 error = isicom_setup_port(port); 936 error = isicom_setup_port(tty);
939 if (error == 0) 937 if (error == 0)
940 error = block_til_ready(tty, filp, port); 938 error = block_til_ready(tty, filp, port);
941 return error; 939 return error;
@@ -955,15 +953,17 @@ static void isicom_shutdown_port(struct isi_port *port)
955 struct isi_board *card = port->card; 953 struct isi_board *card = port->card;
956 struct tty_struct *tty; 954 struct tty_struct *tty;
957 955
958 tty = port->port.tty; 956 tty = tty_port_tty_get(&port->port);
959 957
960 if (!(port->port.flags & ASYNC_INITIALIZED)) 958 if (!(port->port.flags & ASYNC_INITIALIZED)) {
959 tty_kref_put(tty);
961 return; 960 return;
961 }
962 962
963 tty_port_free_xmit_buf(&port->port); 963 tty_port_free_xmit_buf(&port->port);
964 port->port.flags &= ~ASYNC_INITIALIZED; 964 port->port.flags &= ~ASYNC_INITIALIZED;
965 /* 3rd October 2000 : Vinayak P Risbud */ 965 /* 3rd October 2000 : Vinayak P Risbud */
966 port->port.tty = NULL; 966 tty_port_tty_set(&port->port, NULL);
967 967
968 /*Fix done by Anil .S on 30-04-2001 968 /*Fix done by Anil .S on 30-04-2001
969 remote login through isi port has dtr toggle problem 969 remote login through isi port has dtr toggle problem
@@ -1243,9 +1243,10 @@ static int isicom_tiocmset(struct tty_struct *tty, struct file *file,
1243 return 0; 1243 return 0;
1244} 1244}
1245 1245
1246static int isicom_set_serial_info(struct isi_port *port, 1246static int isicom_set_serial_info(struct tty_struct *tty,
1247 struct serial_struct __user *info) 1247 struct serial_struct __user *info)
1248{ 1248{
1249 struct isi_port *port = tty->driver_data;
1249 struct serial_struct newinfo; 1250 struct serial_struct newinfo;
1250 int reconfig_port; 1251 int reconfig_port;
1251 1252
@@ -1276,7 +1277,7 @@ static int isicom_set_serial_info(struct isi_port *port,
1276 if (reconfig_port) { 1277 if (reconfig_port) {
1277 unsigned long flags; 1278 unsigned long flags;
1278 spin_lock_irqsave(&port->card->card_lock, flags); 1279 spin_lock_irqsave(&port->card->card_lock, flags);
1279 isicom_config_port(port); 1280 isicom_config_port(tty);
1280 spin_unlock_irqrestore(&port->card->card_lock, flags); 1281 spin_unlock_irqrestore(&port->card->card_lock, flags);
1281 } 1282 }
1282 unlock_kernel(); 1283 unlock_kernel();
@@ -1318,7 +1319,7 @@ static int isicom_ioctl(struct tty_struct *tty, struct file *filp,
1318 return isicom_get_serial_info(port, argp); 1319 return isicom_get_serial_info(port, argp);
1319 1320
1320 case TIOCSSERIAL: 1321 case TIOCSSERIAL:
1321 return isicom_set_serial_info(port, argp); 1322 return isicom_set_serial_info(tty, argp);
1322 1323
1323 default: 1324 default:
1324 return -ENOIOCTLCMD; 1325 return -ENOIOCTLCMD;
@@ -1341,7 +1342,7 @@ static void isicom_set_termios(struct tty_struct *tty,
1341 return; 1342 return;
1342 1343
1343 spin_lock_irqsave(&port->card->card_lock, flags); 1344 spin_lock_irqsave(&port->card->card_lock, flags);
1344 isicom_config_port(port); 1345 isicom_config_port(tty);
1345 spin_unlock_irqrestore(&port->card->card_lock, flags); 1346 spin_unlock_irqrestore(&port->card->card_lock, flags);
1346 1347
1347 if ((old_termios->c_cflag & CRTSCTS) && 1348 if ((old_termios->c_cflag & CRTSCTS) &&
@@ -1419,7 +1420,7 @@ static void isicom_hangup(struct tty_struct *tty)
1419 1420
1420 port->port.count = 0; 1421 port->port.count = 0;
1421 port->port.flags &= ~ASYNC_NORMAL_ACTIVE; 1422 port->port.flags &= ~ASYNC_NORMAL_ACTIVE;
1422 port->port.tty = NULL; 1423 tty_port_tty_set(&port->port, NULL);
1423 wake_up_interruptible(&port->port.open_wait); 1424 wake_up_interruptible(&port->port.open_wait);
1424} 1425}
1425 1426
diff --git a/drivers/char/istallion.c b/drivers/char/istallion.c
index 843a2afaf204..505d7a1f6b8c 100644
--- a/drivers/char/istallion.c
+++ b/drivers/char/istallion.c
@@ -623,24 +623,25 @@ static int stli_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, un
623static void stli_brdpoll(struct stlibrd *brdp, cdkhdr_t __iomem *hdrp); 623static void stli_brdpoll(struct stlibrd *brdp, cdkhdr_t __iomem *hdrp);
624static void stli_poll(unsigned long arg); 624static void stli_poll(unsigned long arg);
625static int stli_hostcmd(struct stlibrd *brdp, struct stliport *portp); 625static int stli_hostcmd(struct stlibrd *brdp, struct stliport *portp);
626static int stli_initopen(struct stlibrd *brdp, struct stliport *portp); 626static int stli_initopen(struct tty_struct *tty, struct stlibrd *brdp, struct stliport *portp);
627static int stli_rawopen(struct stlibrd *brdp, struct stliport *portp, unsigned long arg, int wait); 627static int stli_rawopen(struct stlibrd *brdp, struct stliport *portp, unsigned long arg, int wait);
628static int stli_rawclose(struct stlibrd *brdp, struct stliport *portp, unsigned long arg, int wait); 628static int stli_rawclose(struct stlibrd *brdp, struct stliport *portp, unsigned long arg, int wait);
629static int stli_waitcarrier(struct stlibrd *brdp, struct stliport *portp, struct file *filp); 629static int stli_waitcarrier(struct tty_struct *tty, struct stlibrd *brdp,
630static int stli_setport(struct stliport *portp); 630 struct stliport *portp, struct file *filp);
631static int stli_setport(struct tty_struct *tty);
631static int stli_cmdwait(struct stlibrd *brdp, struct stliport *portp, unsigned long cmd, void *arg, int size, int copyback); 632static int stli_cmdwait(struct stlibrd *brdp, struct stliport *portp, unsigned long cmd, void *arg, int size, int copyback);
632static void stli_sendcmd(struct stlibrd *brdp, struct stliport *portp, unsigned long cmd, void *arg, int size, int copyback); 633static void stli_sendcmd(struct stlibrd *brdp, struct stliport *portp, unsigned long cmd, void *arg, int size, int copyback);
633static void __stli_sendcmd(struct stlibrd *brdp, struct stliport *portp, unsigned long cmd, void *arg, int size, int copyback); 634static void __stli_sendcmd(struct stlibrd *brdp, struct stliport *portp, unsigned long cmd, void *arg, int size, int copyback);
634static void stli_dodelaycmd(struct stliport *portp, cdkctrl_t __iomem *cp); 635static void stli_dodelaycmd(struct stliport *portp, cdkctrl_t __iomem *cp);
635static void stli_mkasyport(struct stliport *portp, asyport_t *pp, struct ktermios *tiosp); 636static void stli_mkasyport(struct tty_struct *tty, struct stliport *portp, asyport_t *pp, struct ktermios *tiosp);
636static void stli_mkasysigs(asysigs_t *sp, int dtr, int rts); 637static void stli_mkasysigs(asysigs_t *sp, int dtr, int rts);
637static long stli_mktiocm(unsigned long sigvalue); 638static long stli_mktiocm(unsigned long sigvalue);
638static void stli_read(struct stlibrd *brdp, struct stliport *portp); 639static void stli_read(struct stlibrd *brdp, struct stliport *portp);
639static int stli_getserial(struct stliport *portp, struct serial_struct __user *sp); 640static int stli_getserial(struct stliport *portp, struct serial_struct __user *sp);
640static int stli_setserial(struct stliport *portp, struct serial_struct __user *sp); 641static int stli_setserial(struct tty_struct *tty, struct serial_struct __user *sp);
641static int stli_getbrdstats(combrd_t __user *bp); 642static int stli_getbrdstats(combrd_t __user *bp);
642static int stli_getportstats(struct stliport *portp, comstats_t __user *cp); 643static int stli_getportstats(struct tty_struct *tty, struct stliport *portp, comstats_t __user *cp);
643static int stli_portcmdstats(struct stliport *portp); 644static int stli_portcmdstats(struct tty_struct *tty, struct stliport *portp);
644static int stli_clrportstats(struct stliport *portp, comstats_t __user *cp); 645static int stli_clrportstats(struct stliport *portp, comstats_t __user *cp);
645static int stli_getportstruct(struct stliport __user *arg); 646static int stli_getportstruct(struct stliport __user *arg);
646static int stli_getbrdstruct(struct stlibrd __user *arg); 647static int stli_getbrdstruct(struct stlibrd __user *arg);
@@ -731,12 +732,16 @@ static void stli_cleanup_ports(struct stlibrd *brdp)
731{ 732{
732 struct stliport *portp; 733 struct stliport *portp;
733 unsigned int j; 734 unsigned int j;
735 struct tty_struct *tty;
734 736
735 for (j = 0; j < STL_MAXPORTS; j++) { 737 for (j = 0; j < STL_MAXPORTS; j++) {
736 portp = brdp->ports[j]; 738 portp = brdp->ports[j];
737 if (portp != NULL) { 739 if (portp != NULL) {
738 if (portp->port.tty != NULL) 740 tty = tty_port_tty_get(&portp->port);
739 tty_hangup(portp->port.tty); 741 if (tty != NULL) {
742 tty_hangup(tty);
743 tty_kref_put(tty);
744 }
740 kfree(portp); 745 kfree(portp);
741 } 746 }
742 } 747 }
@@ -824,7 +829,7 @@ static int stli_open(struct tty_struct *tty, struct file *filp)
824 * requires several commands to the board we will need to wait for any 829 * requires several commands to the board we will need to wait for any
825 * other open that is already initializing the port. 830 * other open that is already initializing the port.
826 */ 831 */
827 portp->port.tty = tty; 832 tty_port_tty_set(&portp->port, tty);
828 tty->driver_data = portp; 833 tty->driver_data = portp;
829 portp->port.count++; 834 portp->port.count++;
830 835
@@ -835,7 +840,7 @@ static int stli_open(struct tty_struct *tty, struct file *filp)
835 840
836 if ((portp->port.flags & ASYNC_INITIALIZED) == 0) { 841 if ((portp->port.flags & ASYNC_INITIALIZED) == 0) {
837 set_bit(ST_INITIALIZING, &portp->state); 842 set_bit(ST_INITIALIZING, &portp->state);
838 if ((rc = stli_initopen(brdp, portp)) >= 0) { 843 if ((rc = stli_initopen(tty, brdp, portp)) >= 0) {
839 portp->port.flags |= ASYNC_INITIALIZED; 844 portp->port.flags |= ASYNC_INITIALIZED;
840 clear_bit(TTY_IO_ERROR, &tty->flags); 845 clear_bit(TTY_IO_ERROR, &tty->flags);
841 } 846 }
@@ -864,7 +869,7 @@ static int stli_open(struct tty_struct *tty, struct file *filp)
864 * then also we might have to wait for carrier. 869 * then also we might have to wait for carrier.
865 */ 870 */
866 if (!(filp->f_flags & O_NONBLOCK)) { 871 if (!(filp->f_flags & O_NONBLOCK)) {
867 if ((rc = stli_waitcarrier(brdp, portp, filp)) != 0) 872 if ((rc = stli_waitcarrier(tty, brdp, portp, filp)) != 0)
868 return rc; 873 return rc;
869 } 874 }
870 portp->port.flags |= ASYNC_NORMAL_ACTIVE; 875 portp->port.flags |= ASYNC_NORMAL_ACTIVE;
@@ -930,7 +935,7 @@ static void stli_close(struct tty_struct *tty, struct file *filp)
930 stli_flushbuffer(tty); 935 stli_flushbuffer(tty);
931 936
932 tty->closing = 0; 937 tty->closing = 0;
933 portp->port.tty = NULL; 938 tty_port_tty_set(&portp->port, NULL);
934 939
935 if (portp->openwaitcnt) { 940 if (portp->openwaitcnt) {
936 if (portp->close_delay) 941 if (portp->close_delay)
@@ -952,9 +957,9 @@ static void stli_close(struct tty_struct *tty, struct file *filp)
952 * this still all happens pretty quickly. 957 * this still all happens pretty quickly.
953 */ 958 */
954 959
955static int stli_initopen(struct stlibrd *brdp, struct stliport *portp) 960static int stli_initopen(struct tty_struct *tty,
961 struct stlibrd *brdp, struct stliport *portp)
956{ 962{
957 struct tty_struct *tty;
958 asynotify_t nt; 963 asynotify_t nt;
959 asyport_t aport; 964 asyport_t aport;
960 int rc; 965 int rc;
@@ -969,10 +974,7 @@ static int stli_initopen(struct stlibrd *brdp, struct stliport *portp)
969 sizeof(asynotify_t), 0)) < 0) 974 sizeof(asynotify_t), 0)) < 0)
970 return rc; 975 return rc;
971 976
972 tty = portp->port.tty; 977 stli_mkasyport(tty, portp, &aport, tty->termios);
973 if (tty == NULL)
974 return -ENODEV;
975 stli_mkasyport(portp, &aport, tty->termios);
976 if ((rc = stli_cmdwait(brdp, portp, A_SETPORT, &aport, 978 if ((rc = stli_cmdwait(brdp, portp, A_SETPORT, &aport,
977 sizeof(asyport_t), 0)) < 0) 979 sizeof(asyport_t), 0)) < 0)
978 return rc; 980 return rc;
@@ -1161,22 +1163,21 @@ static int stli_cmdwait(struct stlibrd *brdp, struct stliport *portp, unsigned l
1161 * waiting for the command to complete - so must have user context. 1163 * waiting for the command to complete - so must have user context.
1162 */ 1164 */
1163 1165
1164static int stli_setport(struct stliport *portp) 1166static int stli_setport(struct tty_struct *tty)
1165{ 1167{
1168 struct stliport *portp = tty->driver_data;
1166 struct stlibrd *brdp; 1169 struct stlibrd *brdp;
1167 asyport_t aport; 1170 asyport_t aport;
1168 1171
1169 if (portp == NULL) 1172 if (portp == NULL)
1170 return -ENODEV; 1173 return -ENODEV;
1171 if (portp->port.tty == NULL)
1172 return -ENODEV;
1173 if (portp->brdnr >= stli_nrbrds) 1174 if (portp->brdnr >= stli_nrbrds)
1174 return -ENODEV; 1175 return -ENODEV;
1175 brdp = stli_brds[portp->brdnr]; 1176 brdp = stli_brds[portp->brdnr];
1176 if (brdp == NULL) 1177 if (brdp == NULL)
1177 return -ENODEV; 1178 return -ENODEV;
1178 1179
1179 stli_mkasyport(portp, &aport, portp->port.tty->termios); 1180 stli_mkasyport(tty, portp, &aport, tty->termios);
1180 return(stli_cmdwait(brdp, portp, A_SETPORT, &aport, sizeof(asyport_t), 0)); 1181 return(stli_cmdwait(brdp, portp, A_SETPORT, &aport, sizeof(asyport_t), 0));
1181} 1182}
1182 1183
@@ -1187,7 +1188,8 @@ static int stli_setport(struct stliport *portp)
1187 * maybe because if we are clocal then we don't need to wait... 1188 * maybe because if we are clocal then we don't need to wait...
1188 */ 1189 */
1189 1190
1190static int stli_waitcarrier(struct stlibrd *brdp, struct stliport *portp, struct file *filp) 1191static int stli_waitcarrier(struct tty_struct *tty, struct stlibrd *brdp,
1192 struct stliport *portp, struct file *filp)
1191{ 1193{
1192 unsigned long flags; 1194 unsigned long flags;
1193 int rc, doclocal; 1195 int rc, doclocal;
@@ -1195,7 +1197,7 @@ static int stli_waitcarrier(struct stlibrd *brdp, struct stliport *portp, struct
1195 rc = 0; 1197 rc = 0;
1196 doclocal = 0; 1198 doclocal = 0;
1197 1199
1198 if (portp->port.tty->termios->c_cflag & CLOCAL) 1200 if (tty->termios->c_cflag & CLOCAL)
1199 doclocal++; 1201 doclocal++;
1200 1202
1201 spin_lock_irqsave(&stli_lock, flags); 1203 spin_lock_irqsave(&stli_lock, flags);
@@ -1373,8 +1375,6 @@ static void stli_flushchars(struct tty_struct *tty)
1373 stli_txcookrealsize = 0; 1375 stli_txcookrealsize = 0;
1374 stli_txcooktty = NULL; 1376 stli_txcooktty = NULL;
1375 1377
1376 if (tty == NULL)
1377 return;
1378 if (cooktty == NULL) 1378 if (cooktty == NULL)
1379 return; 1379 return;
1380 if (tty != cooktty) 1380 if (tty != cooktty)
@@ -1572,10 +1572,11 @@ static int stli_getserial(struct stliport *portp, struct serial_struct __user *s
1572 * just quietly ignore any requests to change irq, etc. 1572 * just quietly ignore any requests to change irq, etc.
1573 */ 1573 */
1574 1574
1575static int stli_setserial(struct stliport *portp, struct serial_struct __user *sp) 1575static int stli_setserial(struct tty_struct *tty, struct serial_struct __user *sp)
1576{ 1576{
1577 struct serial_struct sio; 1577 struct serial_struct sio;
1578 int rc; 1578 int rc;
1579 struct stliport *portp = tty->driver_data;
1579 1580
1580 if (copy_from_user(&sio, sp, sizeof(struct serial_struct))) 1581 if (copy_from_user(&sio, sp, sizeof(struct serial_struct)))
1581 return -EFAULT; 1582 return -EFAULT;
@@ -1594,7 +1595,7 @@ static int stli_setserial(struct stliport *portp, struct serial_struct __user *s
1594 portp->closing_wait = sio.closing_wait; 1595 portp->closing_wait = sio.closing_wait;
1595 portp->custom_divisor = sio.custom_divisor; 1596 portp->custom_divisor = sio.custom_divisor;
1596 1597
1597 if ((rc = stli_setport(portp)) < 0) 1598 if ((rc = stli_setport(tty)) < 0)
1598 return rc; 1599 return rc;
1599 return 0; 1600 return 0;
1600} 1601}
@@ -1685,17 +1686,17 @@ static int stli_ioctl(struct tty_struct *tty, struct file *file, unsigned int cm
1685 rc = stli_getserial(portp, argp); 1686 rc = stli_getserial(portp, argp);
1686 break; 1687 break;
1687 case TIOCSSERIAL: 1688 case TIOCSSERIAL:
1688 rc = stli_setserial(portp, argp); 1689 rc = stli_setserial(tty, argp);
1689 break; 1690 break;
1690 case STL_GETPFLAG: 1691 case STL_GETPFLAG:
1691 rc = put_user(portp->pflag, (unsigned __user *)argp); 1692 rc = put_user(portp->pflag, (unsigned __user *)argp);
1692 break; 1693 break;
1693 case STL_SETPFLAG: 1694 case STL_SETPFLAG:
1694 if ((rc = get_user(portp->pflag, (unsigned __user *)argp)) == 0) 1695 if ((rc = get_user(portp->pflag, (unsigned __user *)argp)) == 0)
1695 stli_setport(portp); 1696 stli_setport(tty);
1696 break; 1697 break;
1697 case COM_GETPORTSTATS: 1698 case COM_GETPORTSTATS:
1698 rc = stli_getportstats(portp, argp); 1699 rc = stli_getportstats(tty, portp, argp);
1699 break; 1700 break;
1700 case COM_CLRPORTSTATS: 1701 case COM_CLRPORTSTATS:
1701 rc = stli_clrportstats(portp, argp); 1702 rc = stli_clrportstats(portp, argp);
@@ -1729,8 +1730,6 @@ static void stli_settermios(struct tty_struct *tty, struct ktermios *old)
1729 struct ktermios *tiosp; 1730 struct ktermios *tiosp;
1730 asyport_t aport; 1731 asyport_t aport;
1731 1732
1732 if (tty == NULL)
1733 return;
1734 portp = tty->driver_data; 1733 portp = tty->driver_data;
1735 if (portp == NULL) 1734 if (portp == NULL)
1736 return; 1735 return;
@@ -1742,7 +1741,7 @@ static void stli_settermios(struct tty_struct *tty, struct ktermios *old)
1742 1741
1743 tiosp = tty->termios; 1742 tiosp = tty->termios;
1744 1743
1745 stli_mkasyport(portp, &aport, tiosp); 1744 stli_mkasyport(tty, portp, &aport, tiosp);
1746 stli_cmdwait(brdp, portp, A_SETPORT, &aport, sizeof(asyport_t), 0); 1745 stli_cmdwait(brdp, portp, A_SETPORT, &aport, sizeof(asyport_t), 0);
1747 stli_mkasysigs(&portp->asig, ((tiosp->c_cflag & CBAUD) ? 1 : 0), -1); 1746 stli_mkasysigs(&portp->asig, ((tiosp->c_cflag & CBAUD) ? 1 : 0), -1);
1748 stli_cmdwait(brdp, portp, A_SETSIGNALS, &portp->asig, 1747 stli_cmdwait(brdp, portp, A_SETSIGNALS, &portp->asig,
@@ -1854,7 +1853,7 @@ static void stli_hangup(struct tty_struct *tty)
1854 clear_bit(ST_TXBUSY, &portp->state); 1853 clear_bit(ST_TXBUSY, &portp->state);
1855 clear_bit(ST_RXSTOP, &portp->state); 1854 clear_bit(ST_RXSTOP, &portp->state);
1856 set_bit(TTY_IO_ERROR, &tty->flags); 1855 set_bit(TTY_IO_ERROR, &tty->flags);
1857 portp->port.tty = NULL; 1856 tty_port_tty_set(&portp->port, NULL);
1858 portp->port.flags &= ~ASYNC_NORMAL_ACTIVE; 1857 portp->port.flags &= ~ASYNC_NORMAL_ACTIVE;
1859 portp->port.count = 0; 1858 portp->port.count = 0;
1860 spin_unlock_irqrestore(&stli_lock, flags); 1859 spin_unlock_irqrestore(&stli_lock, flags);
@@ -1935,8 +1934,6 @@ static void stli_waituntilsent(struct tty_struct *tty, int timeout)
1935 struct stliport *portp; 1934 struct stliport *portp;
1936 unsigned long tend; 1935 unsigned long tend;
1937 1936
1938 if (tty == NULL)
1939 return;
1940 portp = tty->driver_data; 1937 portp = tty->driver_data;
1941 if (portp == NULL) 1938 if (portp == NULL)
1942 return; 1939 return;
@@ -1998,7 +1995,7 @@ static int stli_portinfo(struct stlibrd *brdp, struct stliport *portp, int portn
1998 char *sp, *uart; 1995 char *sp, *uart;
1999 int rc, cnt; 1996 int rc, cnt;
2000 1997
2001 rc = stli_portcmdstats(portp); 1998 rc = stli_portcmdstats(NULL, portp);
2002 1999
2003 uart = "UNKNOWN"; 2000 uart = "UNKNOWN";
2004 if (brdp->state & BST_STARTED) { 2001 if (brdp->state & BST_STARTED) {
@@ -2188,7 +2185,7 @@ static void stli_read(struct stlibrd *brdp, struct stliport *portp)
2188 2185
2189 if (test_bit(ST_RXSTOP, &portp->state)) 2186 if (test_bit(ST_RXSTOP, &portp->state))
2190 return; 2187 return;
2191 tty = portp->port.tty; 2188 tty = tty_port_tty_get(&portp->port);
2192 if (tty == NULL) 2189 if (tty == NULL)
2193 return; 2190 return;
2194 2191
@@ -2230,6 +2227,7 @@ static void stli_read(struct stlibrd *brdp, struct stliport *portp)
2230 set_bit(ST_RXING, &portp->state); 2227 set_bit(ST_RXING, &portp->state);
2231 2228
2232 tty_schedule_flip(tty); 2229 tty_schedule_flip(tty);
2230 tty_kref_put(tty);
2233} 2231}
2234 2232
2235/*****************************************************************************/ 2233/*****************************************************************************/
@@ -2362,7 +2360,7 @@ static int stli_hostcmd(struct stlibrd *brdp, struct stliport *portp)
2362 if (ap->notify) { 2360 if (ap->notify) {
2363 nt = ap->changed; 2361 nt = ap->changed;
2364 ap->notify = 0; 2362 ap->notify = 0;
2365 tty = portp->port.tty; 2363 tty = tty_port_tty_get(&portp->port);
2366 2364
2367 if (nt.signal & SG_DCD) { 2365 if (nt.signal & SG_DCD) {
2368 oldsigs = portp->sigs; 2366 oldsigs = portp->sigs;
@@ -2399,6 +2397,7 @@ static int stli_hostcmd(struct stlibrd *brdp, struct stliport *portp)
2399 tty_schedule_flip(tty); 2397 tty_schedule_flip(tty);
2400 } 2398 }
2401 } 2399 }
2400 tty_kref_put(tty);
2402 2401
2403 if (nt.data & DT_RXBUSY) { 2402 if (nt.data & DT_RXBUSY) {
2404 donerx++; 2403 donerx++;
@@ -2535,14 +2534,15 @@ static void stli_poll(unsigned long arg)
2535 * the slave. 2534 * the slave.
2536 */ 2535 */
2537 2536
2538static void stli_mkasyport(struct stliport *portp, asyport_t *pp, struct ktermios *tiosp) 2537static void stli_mkasyport(struct tty_struct *tty, struct stliport *portp,
2538 asyport_t *pp, struct ktermios *tiosp)
2539{ 2539{
2540 memset(pp, 0, sizeof(asyport_t)); 2540 memset(pp, 0, sizeof(asyport_t));
2541 2541
2542/* 2542/*
2543 * Start of by setting the baud, char size, parity and stop bit info. 2543 * Start of by setting the baud, char size, parity and stop bit info.
2544 */ 2544 */
2545 pp->baudout = tty_get_baud_rate(portp->port.tty); 2545 pp->baudout = tty_get_baud_rate(tty);
2546 if ((tiosp->c_cflag & CBAUD) == B38400) { 2546 if ((tiosp->c_cflag & CBAUD) == B38400) {
2547 if ((portp->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) 2547 if ((portp->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
2548 pp->baudout = 57600; 2548 pp->baudout = 57600;
@@ -2695,7 +2695,7 @@ static int stli_initports(struct stlibrd *brdp)
2695 printk("STALLION: failed to allocate port structure\n"); 2695 printk("STALLION: failed to allocate port structure\n");
2696 continue; 2696 continue;
2697 } 2697 }
2698 2698 tty_port_init(&portp->port);
2699 portp->magic = STLI_PORTMAGIC; 2699 portp->magic = STLI_PORTMAGIC;
2700 portp->portnr = i; 2700 portp->portnr = i;
2701 portp->brdnr = brdp->brdnr; 2701 portp->brdnr = brdp->brdnr;
@@ -4220,7 +4220,7 @@ static struct stliport *stli_getport(unsigned int brdnr, unsigned int panelnr,
4220 * what port to get stats for (used through board control device). 4220 * what port to get stats for (used through board control device).
4221 */ 4221 */
4222 4222
4223static int stli_portcmdstats(struct stliport *portp) 4223static int stli_portcmdstats(struct tty_struct *tty, struct stliport *portp)
4224{ 4224{
4225 unsigned long flags; 4225 unsigned long flags;
4226 struct stlibrd *brdp; 4226 struct stlibrd *brdp;
@@ -4249,15 +4249,15 @@ static int stli_portcmdstats(struct stliport *portp)
4249 stli_comstats.flags = portp->port.flags; 4249 stli_comstats.flags = portp->port.flags;
4250 4250
4251 spin_lock_irqsave(&brd_lock, flags); 4251 spin_lock_irqsave(&brd_lock, flags);
4252 if (portp->port.tty != NULL) { 4252 if (tty != NULL) {
4253 if (portp->port.tty->driver_data == portp) { 4253 if (portp->port.tty == tty) {
4254 stli_comstats.ttystate = portp->port.tty->flags; 4254 stli_comstats.ttystate = tty->flags;
4255 stli_comstats.rxbuffered = -1; 4255 stli_comstats.rxbuffered = -1;
4256 if (portp->port.tty->termios != NULL) { 4256 if (tty->termios != NULL) {
4257 stli_comstats.cflags = portp->port.tty->termios->c_cflag; 4257 stli_comstats.cflags = tty->termios->c_cflag;
4258 stli_comstats.iflags = portp->port.tty->termios->c_iflag; 4258 stli_comstats.iflags = tty->termios->c_iflag;
4259 stli_comstats.oflags = portp->port.tty->termios->c_oflag; 4259 stli_comstats.oflags = tty->termios->c_oflag;
4260 stli_comstats.lflags = portp->port.tty->termios->c_lflag; 4260 stli_comstats.lflags = tty->termios->c_lflag;
4261 } 4261 }
4262 } 4262 }
4263 } 4263 }
@@ -4294,7 +4294,8 @@ static int stli_portcmdstats(struct stliport *portp)
4294 * what port to get stats for (used through board control device). 4294 * what port to get stats for (used through board control device).
4295 */ 4295 */
4296 4296
4297static int stli_getportstats(struct stliport *portp, comstats_t __user *cp) 4297static int stli_getportstats(struct tty_struct *tty, struct stliport *portp,
4298 comstats_t __user *cp)
4298{ 4299{
4299 struct stlibrd *brdp; 4300 struct stlibrd *brdp;
4300 int rc; 4301 int rc;
@@ -4312,7 +4313,7 @@ static int stli_getportstats(struct stliport *portp, comstats_t __user *cp)
4312 if (!brdp) 4313 if (!brdp)
4313 return -ENODEV; 4314 return -ENODEV;
4314 4315
4315 if ((rc = stli_portcmdstats(portp)) < 0) 4316 if ((rc = stli_portcmdstats(tty, portp)) < 0)
4316 return rc; 4317 return rc;
4317 4318
4318 return copy_to_user(cp, &stli_comstats, sizeof(comstats_t)) ? 4319 return copy_to_user(cp, &stli_comstats, sizeof(comstats_t)) ?
@@ -4427,7 +4428,7 @@ static int stli_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, un
4427 4428
4428 switch (cmd) { 4429 switch (cmd) {
4429 case COM_GETPORTSTATS: 4430 case COM_GETPORTSTATS:
4430 rc = stli_getportstats(NULL, argp); 4431 rc = stli_getportstats(NULL, NULL, argp);
4431 done++; 4432 done++;
4432 break; 4433 break;
4433 case COM_CLRPORTSTATS: 4434 case COM_CLRPORTSTATS:
diff --git a/drivers/char/moxa.c b/drivers/char/moxa.c
index d3d7864e0c1e..5df4003ad873 100644
--- a/drivers/char/moxa.c
+++ b/drivers/char/moxa.c
@@ -205,7 +205,7 @@ static int moxa_tiocmset(struct tty_struct *tty, struct file *file,
205static void moxa_poll(unsigned long); 205static void moxa_poll(unsigned long);
206static void moxa_set_tty_param(struct tty_struct *, struct ktermios *); 206static void moxa_set_tty_param(struct tty_struct *, struct ktermios *);
207static void moxa_setup_empty_event(struct tty_struct *); 207static void moxa_setup_empty_event(struct tty_struct *);
208static void moxa_shut_down(struct moxa_port *); 208static void moxa_shut_down(struct tty_struct *);
209/* 209/*
210 * moxa board interface functions: 210 * moxa board interface functions:
211 */ 211 */
@@ -217,7 +217,7 @@ static void MoxaPortLineCtrl(struct moxa_port *, int, int);
217static void MoxaPortFlowCtrl(struct moxa_port *, int, int, int, int, int); 217static void MoxaPortFlowCtrl(struct moxa_port *, int, int, int, int, int);
218static int MoxaPortLineStatus(struct moxa_port *); 218static int MoxaPortLineStatus(struct moxa_port *);
219static void MoxaPortFlushData(struct moxa_port *, int); 219static void MoxaPortFlushData(struct moxa_port *, int);
220static int MoxaPortWriteData(struct moxa_port *, const unsigned char *, int); 220static int MoxaPortWriteData(struct tty_struct *, const unsigned char *, int);
221static int MoxaPortReadData(struct moxa_port *); 221static int MoxaPortReadData(struct moxa_port *);
222static int MoxaPortTxQueue(struct moxa_port *); 222static int MoxaPortTxQueue(struct moxa_port *);
223static int MoxaPortRxQueue(struct moxa_port *); 223static int MoxaPortRxQueue(struct moxa_port *);
@@ -332,6 +332,7 @@ static int moxa_ioctl(struct tty_struct *tty, struct file *file,
332 for (i = 0; i < MAX_BOARDS; i++) { 332 for (i = 0; i < MAX_BOARDS; i++) {
333 p = moxa_boards[i].ports; 333 p = moxa_boards[i].ports;
334 for (j = 0; j < MAX_PORTS_PER_BOARD; j++, p++, argm++) { 334 for (j = 0; j < MAX_PORTS_PER_BOARD; j++, p++, argm++) {
335 struct tty_struct *ttyp;
335 memset(&tmp, 0, sizeof(tmp)); 336 memset(&tmp, 0, sizeof(tmp));
336 if (!moxa_boards[i].ready) 337 if (!moxa_boards[i].ready)
337 goto copy; 338 goto copy;
@@ -344,10 +345,12 @@ static int moxa_ioctl(struct tty_struct *tty, struct file *file,
344 if (status & 4) 345 if (status & 4)
345 tmp.dcd = 1; 346 tmp.dcd = 1;
346 347
347 if (!p->port.tty || !p->port.tty->termios) 348 ttyp = tty_port_tty_get(&p->port);
349 if (!ttyp || !ttyp->termios)
348 tmp.cflag = p->cflag; 350 tmp.cflag = p->cflag;
349 else 351 else
350 tmp.cflag = p->port.tty->termios->c_cflag; 352 tmp.cflag = ttyp->termios->c_cflag;
353 tty_kref_put(tty);
351copy: 354copy:
352 if (copy_to_user(argm, &tmp, sizeof(tmp))) { 355 if (copy_to_user(argm, &tmp, sizeof(tmp))) {
353 mutex_unlock(&moxa_openlock); 356 mutex_unlock(&moxa_openlock);
@@ -880,8 +883,14 @@ static void moxa_board_deinit(struct moxa_board_conf *brd)
880 883
881 /* pci hot-un-plug support */ 884 /* pci hot-un-plug support */
882 for (a = 0; a < brd->numPorts; a++) 885 for (a = 0; a < brd->numPorts; a++)
883 if (brd->ports[a].port.flags & ASYNC_INITIALIZED) 886 if (brd->ports[a].port.flags & ASYNC_INITIALIZED) {
884 tty_hangup(brd->ports[a].port.tty); 887 struct tty_struct *tty = tty_port_tty_get(
888 &brd->ports[a].port);
889 if (tty) {
890 tty_hangup(tty);
891 tty_kref_put(tty);
892 }
893 }
885 while (1) { 894 while (1) {
886 opened = 0; 895 opened = 0;
887 for (a = 0; a < brd->numPorts; a++) 896 for (a = 0; a < brd->numPorts; a++)
@@ -1096,13 +1105,14 @@ static void __exit moxa_exit(void)
1096module_init(moxa_init); 1105module_init(moxa_init);
1097module_exit(moxa_exit); 1106module_exit(moxa_exit);
1098 1107
1099static void moxa_close_port(struct moxa_port *ch) 1108static void moxa_close_port(struct tty_struct *tty)
1100{ 1109{
1101 moxa_shut_down(ch); 1110 struct moxa_port *ch = tty->driver_data;
1111 moxa_shut_down(tty);
1102 MoxaPortFlushData(ch, 2); 1112 MoxaPortFlushData(ch, 2);
1103 ch->port.flags &= ~ASYNC_NORMAL_ACTIVE; 1113 ch->port.flags &= ~ASYNC_NORMAL_ACTIVE;
1104 ch->port.tty->driver_data = NULL; 1114 tty->driver_data = NULL;
1105 ch->port.tty = NULL; 1115 tty_port_tty_set(&ch->port, NULL);
1106} 1116}
1107 1117
1108static int moxa_block_till_ready(struct tty_struct *tty, struct file *filp, 1118static int moxa_block_till_ready(struct tty_struct *tty, struct file *filp,
@@ -1161,7 +1171,7 @@ static int moxa_open(struct tty_struct *tty, struct file *filp)
1161 ch = &brd->ports[port % MAX_PORTS_PER_BOARD]; 1171 ch = &brd->ports[port % MAX_PORTS_PER_BOARD];
1162 ch->port.count++; 1172 ch->port.count++;
1163 tty->driver_data = ch; 1173 tty->driver_data = ch;
1164 ch->port.tty = tty; 1174 tty_port_tty_set(&ch->port, tty);
1165 if (!(ch->port.flags & ASYNC_INITIALIZED)) { 1175 if (!(ch->port.flags & ASYNC_INITIALIZED)) {
1166 ch->statusflags = 0; 1176 ch->statusflags = 0;
1167 moxa_set_tty_param(tty, tty->termios); 1177 moxa_set_tty_param(tty, tty->termios);
@@ -1179,7 +1189,7 @@ static int moxa_open(struct tty_struct *tty, struct file *filp)
1179 if (retval) { 1189 if (retval) {
1180 if (ch->port.count) /* 0 means already hung up... */ 1190 if (ch->port.count) /* 0 means already hung up... */
1181 if (--ch->port.count == 0) 1191 if (--ch->port.count == 0)
1182 moxa_close_port(ch); 1192 moxa_close_port(tty);
1183 } else 1193 } else
1184 ch->port.flags |= ASYNC_NORMAL_ACTIVE; 1194 ch->port.flags |= ASYNC_NORMAL_ACTIVE;
1185 mutex_unlock(&moxa_openlock); 1195 mutex_unlock(&moxa_openlock);
@@ -1219,7 +1229,7 @@ static void moxa_close(struct tty_struct *tty, struct file *filp)
1219 tty_wait_until_sent(tty, 30 * HZ); /* 30 seconds timeout */ 1229 tty_wait_until_sent(tty, 30 * HZ); /* 30 seconds timeout */
1220 } 1230 }
1221 1231
1222 moxa_close_port(ch); 1232 moxa_close_port(tty);
1223unlock: 1233unlock:
1224 mutex_unlock(&moxa_openlock); 1234 mutex_unlock(&moxa_openlock);
1225} 1235}
@@ -1234,7 +1244,7 @@ static int moxa_write(struct tty_struct *tty,
1234 return 0; 1244 return 0;
1235 1245
1236 spin_lock_bh(&moxa_lock); 1246 spin_lock_bh(&moxa_lock);
1237 len = MoxaPortWriteData(ch, buf, count); 1247 len = MoxaPortWriteData(tty, buf, count);
1238 spin_unlock_bh(&moxa_lock); 1248 spin_unlock_bh(&moxa_lock);
1239 1249
1240 ch->statusflags |= LOWWAIT; 1250 ch->statusflags |= LOWWAIT;
@@ -1409,7 +1419,7 @@ static void moxa_hangup(struct tty_struct *tty)
1409 return; 1419 return;
1410 } 1420 }
1411 ch->port.count = 0; 1421 ch->port.count = 0;
1412 moxa_close_port(ch); 1422 moxa_close_port(tty);
1413 mutex_unlock(&moxa_openlock); 1423 mutex_unlock(&moxa_openlock);
1414 1424
1415 wake_up_interruptible(&ch->port.open_wait); 1425 wake_up_interruptible(&ch->port.open_wait);
@@ -1417,11 +1427,14 @@ static void moxa_hangup(struct tty_struct *tty)
1417 1427
1418static void moxa_new_dcdstate(struct moxa_port *p, u8 dcd) 1428static void moxa_new_dcdstate(struct moxa_port *p, u8 dcd)
1419{ 1429{
1430 struct tty_struct *tty;
1420 dcd = !!dcd; 1431 dcd = !!dcd;
1421 1432
1422 if (dcd != p->DCDState && p->port.tty && C_CLOCAL(p->port.tty)) { 1433 if (dcd != p->DCDState) {
1423 if (!dcd) 1434 tty = tty_port_tty_get(&p->port);
1424 tty_hangup(p->port.tty); 1435 if (tty && C_CLOCAL(tty) && !dcd)
1436 tty_hangup(tty);
1437 tty_kref_put(tty);
1425 } 1438 }
1426 p->DCDState = dcd; 1439 p->DCDState = dcd;
1427} 1440}
@@ -1429,7 +1442,7 @@ static void moxa_new_dcdstate(struct moxa_port *p, u8 dcd)
1429static int moxa_poll_port(struct moxa_port *p, unsigned int handle, 1442static int moxa_poll_port(struct moxa_port *p, unsigned int handle,
1430 u16 __iomem *ip) 1443 u16 __iomem *ip)
1431{ 1444{
1432 struct tty_struct *tty = p->port.tty; 1445 struct tty_struct *tty = tty_port_tty_get(&p->port);
1433 void __iomem *ofsAddr; 1446 void __iomem *ofsAddr;
1434 unsigned int inited = p->port.flags & ASYNC_INITIALIZED; 1447 unsigned int inited = p->port.flags & ASYNC_INITIALIZED;
1435 u16 intr; 1448 u16 intr;
@@ -1476,6 +1489,7 @@ static int moxa_poll_port(struct moxa_port *p, unsigned int handle,
1476 tty_insert_flip_char(tty, 0, TTY_BREAK); 1489 tty_insert_flip_char(tty, 0, TTY_BREAK);
1477 tty_schedule_flip(tty); 1490 tty_schedule_flip(tty);
1478 } 1491 }
1492 tty_kref_put(tty);
1479 1493
1480 if (intr & IntrLine) 1494 if (intr & IntrLine)
1481 moxa_new_dcdstate(p, readb(ofsAddr + FlagStat) & DCD_state); 1495 moxa_new_dcdstate(p, readb(ofsAddr + FlagStat) & DCD_state);
@@ -1560,9 +1574,9 @@ static void moxa_setup_empty_event(struct tty_struct *tty)
1560 spin_unlock_bh(&moxa_lock); 1574 spin_unlock_bh(&moxa_lock);
1561} 1575}
1562 1576
1563static void moxa_shut_down(struct moxa_port *ch) 1577static void moxa_shut_down(struct tty_struct *tty)
1564{ 1578{
1565 struct tty_struct *tp = ch->port.tty; 1579 struct moxa_port *ch = tty->driver_data;
1566 1580
1567 if (!(ch->port.flags & ASYNC_INITIALIZED)) 1581 if (!(ch->port.flags & ASYNC_INITIALIZED))
1568 return; 1582 return;
@@ -1572,7 +1586,7 @@ static void moxa_shut_down(struct moxa_port *ch)
1572 /* 1586 /*
1573 * If we're a modem control device and HUPCL is on, drop RTS & DTR. 1587 * If we're a modem control device and HUPCL is on, drop RTS & DTR.
1574 */ 1588 */
1575 if (C_HUPCL(tp)) 1589 if (C_HUPCL(tty))
1576 MoxaPortLineCtrl(ch, 0, 0); 1590 MoxaPortLineCtrl(ch, 0, 0);
1577 1591
1578 spin_lock_bh(&moxa_lock); 1592 spin_lock_bh(&moxa_lock);
@@ -1953,9 +1967,10 @@ static int MoxaPortLineStatus(struct moxa_port *port)
1953 return val; 1967 return val;
1954} 1968}
1955 1969
1956static int MoxaPortWriteData(struct moxa_port *port, 1970static int MoxaPortWriteData(struct tty_struct *tty,
1957 const unsigned char *buffer, int len) 1971 const unsigned char *buffer, int len)
1958{ 1972{
1973 struct moxa_port *port = tty->driver_data;
1959 void __iomem *baseAddr, *ofsAddr, *ofs; 1974 void __iomem *baseAddr, *ofsAddr, *ofs;
1960 unsigned int c, total; 1975 unsigned int c, total;
1961 u16 head, tail, tx_mask, spage, epage; 1976 u16 head, tail, tx_mask, spage, epage;
diff --git a/drivers/char/mxser.c b/drivers/char/mxser.c
index b638403e8e9c..8beef50f95a0 100644
--- a/drivers/char/mxser.c
+++ b/drivers/char/mxser.c
@@ -610,15 +610,13 @@ static int mxser_block_til_ready(struct tty_struct *tty, struct file *filp,
610 return 0; 610 return 0;
611} 611}
612 612
613static int mxser_set_baud(struct mxser_port *info, long newspd) 613static int mxser_set_baud(struct tty_struct *tty, long newspd)
614{ 614{
615 struct mxser_port *info = tty->driver_data;
615 int quot = 0, baud; 616 int quot = 0, baud;
616 unsigned char cval; 617 unsigned char cval;
617 618
618 if (!info->port.tty || !info->port.tty->termios) 619 if (!info->ioaddr)
619 return -1;
620
621 if (!(info->ioaddr))
622 return -1; 620 return -1;
623 621
624 if (newspd > info->max_baud) 622 if (newspd > info->max_baud)
@@ -626,13 +624,13 @@ static int mxser_set_baud(struct mxser_port *info, long newspd)
626 624
627 if (newspd == 134) { 625 if (newspd == 134) {
628 quot = 2 * info->baud_base / 269; 626 quot = 2 * info->baud_base / 269;
629 tty_encode_baud_rate(info->port.tty, 134, 134); 627 tty_encode_baud_rate(tty, 134, 134);
630 } else if (newspd) { 628 } else if (newspd) {
631 quot = info->baud_base / newspd; 629 quot = info->baud_base / newspd;
632 if (quot == 0) 630 if (quot == 0)
633 quot = 1; 631 quot = 1;
634 baud = info->baud_base/quot; 632 baud = info->baud_base/quot;
635 tty_encode_baud_rate(info->port.tty, baud, baud); 633 tty_encode_baud_rate(tty, baud, baud);
636 } else { 634 } else {
637 quot = 0; 635 quot = 0;
638 } 636 }
@@ -658,7 +656,7 @@ static int mxser_set_baud(struct mxser_port *info, long newspd)
658 outb(cval, info->ioaddr + UART_LCR); /* reset DLAB */ 656 outb(cval, info->ioaddr + UART_LCR); /* reset DLAB */
659 657
660#ifdef BOTHER 658#ifdef BOTHER
661 if (C_BAUD(info->port.tty) == BOTHER) { 659 if (C_BAUD(tty) == BOTHER) {
662 quot = info->baud_base % newspd; 660 quot = info->baud_base % newspd;
663 quot *= 8; 661 quot *= 8;
664 if (quot % newspd > newspd / 2) { 662 if (quot % newspd > newspd / 2) {
@@ -679,21 +677,20 @@ static int mxser_set_baud(struct mxser_port *info, long newspd)
679 * This routine is called to set the UART divisor registers to match 677 * This routine is called to set the UART divisor registers to match
680 * the specified baud rate for a serial port. 678 * the specified baud rate for a serial port.
681 */ 679 */
682static int mxser_change_speed(struct mxser_port *info, 680static int mxser_change_speed(struct tty_struct *tty,
683 struct ktermios *old_termios) 681 struct ktermios *old_termios)
684{ 682{
683 struct mxser_port *info = tty->driver_data;
685 unsigned cflag, cval, fcr; 684 unsigned cflag, cval, fcr;
686 int ret = 0; 685 int ret = 0;
687 unsigned char status; 686 unsigned char status;
688 687
689 if (!info->port.tty || !info->port.tty->termios) 688 cflag = tty->termios->c_cflag;
690 return ret; 689 if (!info->ioaddr)
691 cflag = info->port.tty->termios->c_cflag;
692 if (!(info->ioaddr))
693 return ret; 690 return ret;
694 691
695 if (mxser_set_baud_method[info->port.tty->index] == 0) 692 if (mxser_set_baud_method[tty->index] == 0)
696 mxser_set_baud(info, tty_get_baud_rate(info->port.tty)); 693 mxser_set_baud(tty, tty_get_baud_rate(tty));
697 694
698 /* byte size and parity */ 695 /* byte size and parity */
699 switch (cflag & CSIZE) { 696 switch (cflag & CSIZE) {
@@ -762,9 +759,9 @@ static int mxser_change_speed(struct mxser_port *info,
762 info->MCR |= UART_MCR_AFE; 759 info->MCR |= UART_MCR_AFE;
763 } else { 760 } else {
764 status = inb(info->ioaddr + UART_MSR); 761 status = inb(info->ioaddr + UART_MSR);
765 if (info->port.tty->hw_stopped) { 762 if (tty->hw_stopped) {
766 if (status & UART_MSR_CTS) { 763 if (status & UART_MSR_CTS) {
767 info->port.tty->hw_stopped = 0; 764 tty->hw_stopped = 0;
768 if (info->type != PORT_16550A && 765 if (info->type != PORT_16550A &&
769 !info->board->chip_flag) { 766 !info->board->chip_flag) {
770 outb(info->IER & ~UART_IER_THRI, 767 outb(info->IER & ~UART_IER_THRI,
@@ -774,11 +771,11 @@ static int mxser_change_speed(struct mxser_port *info,
774 outb(info->IER, info->ioaddr + 771 outb(info->IER, info->ioaddr +
775 UART_IER); 772 UART_IER);
776 } 773 }
777 tty_wakeup(info->port.tty); 774 tty_wakeup(tty);
778 } 775 }
779 } else { 776 } else {
780 if (!(status & UART_MSR_CTS)) { 777 if (!(status & UART_MSR_CTS)) {
781 info->port.tty->hw_stopped = 1; 778 tty->hw_stopped = 1;
782 if ((info->type != PORT_16550A) && 779 if ((info->type != PORT_16550A) &&
783 (!info->board->chip_flag)) { 780 (!info->board->chip_flag)) {
784 info->IER &= ~UART_IER_THRI; 781 info->IER &= ~UART_IER_THRI;
@@ -804,21 +801,21 @@ static int mxser_change_speed(struct mxser_port *info,
804 * Set up parity check flag 801 * Set up parity check flag
805 */ 802 */
806 info->read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR; 803 info->read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR;
807 if (I_INPCK(info->port.tty)) 804 if (I_INPCK(tty))
808 info->read_status_mask |= UART_LSR_FE | UART_LSR_PE; 805 info->read_status_mask |= UART_LSR_FE | UART_LSR_PE;
809 if (I_BRKINT(info->port.tty) || I_PARMRK(info->port.tty)) 806 if (I_BRKINT(tty) || I_PARMRK(tty))
810 info->read_status_mask |= UART_LSR_BI; 807 info->read_status_mask |= UART_LSR_BI;
811 808
812 info->ignore_status_mask = 0; 809 info->ignore_status_mask = 0;
813 810
814 if (I_IGNBRK(info->port.tty)) { 811 if (I_IGNBRK(tty)) {
815 info->ignore_status_mask |= UART_LSR_BI; 812 info->ignore_status_mask |= UART_LSR_BI;
816 info->read_status_mask |= UART_LSR_BI; 813 info->read_status_mask |= UART_LSR_BI;
817 /* 814 /*
818 * If we're ignore parity and break indicators, ignore 815 * If we're ignore parity and break indicators, ignore
819 * overruns too. (For real raw support). 816 * overruns too. (For real raw support).
820 */ 817 */
821 if (I_IGNPAR(info->port.tty)) { 818 if (I_IGNPAR(tty)) {
822 info->ignore_status_mask |= 819 info->ignore_status_mask |=
823 UART_LSR_OE | 820 UART_LSR_OE |
824 UART_LSR_PE | 821 UART_LSR_PE |
@@ -830,16 +827,16 @@ static int mxser_change_speed(struct mxser_port *info,
830 } 827 }
831 } 828 }
832 if (info->board->chip_flag) { 829 if (info->board->chip_flag) {
833 mxser_set_must_xon1_value(info->ioaddr, START_CHAR(info->port.tty)); 830 mxser_set_must_xon1_value(info->ioaddr, START_CHAR(tty));
834 mxser_set_must_xoff1_value(info->ioaddr, STOP_CHAR(info->port.tty)); 831 mxser_set_must_xoff1_value(info->ioaddr, STOP_CHAR(tty));
835 if (I_IXON(info->port.tty)) { 832 if (I_IXON(tty)) {
836 mxser_enable_must_rx_software_flow_control( 833 mxser_enable_must_rx_software_flow_control(
837 info->ioaddr); 834 info->ioaddr);
838 } else { 835 } else {
839 mxser_disable_must_rx_software_flow_control( 836 mxser_disable_must_rx_software_flow_control(
840 info->ioaddr); 837 info->ioaddr);
841 } 838 }
842 if (I_IXOFF(info->port.tty)) { 839 if (I_IXOFF(tty)) {
843 mxser_enable_must_tx_software_flow_control( 840 mxser_enable_must_tx_software_flow_control(
844 info->ioaddr); 841 info->ioaddr);
845 } else { 842 } else {
@@ -855,7 +852,8 @@ static int mxser_change_speed(struct mxser_port *info,
855 return ret; 852 return ret;
856} 853}
857 854
858static void mxser_check_modem_status(struct mxser_port *port, int status) 855static void mxser_check_modem_status(struct tty_struct *tty,
856 struct mxser_port *port, int status)
859{ 857{
860 /* update input line counters */ 858 /* update input line counters */
861 if (status & UART_MSR_TERI) 859 if (status & UART_MSR_TERI)
@@ -874,10 +872,11 @@ static void mxser_check_modem_status(struct mxser_port *port, int status)
874 wake_up_interruptible(&port->port.open_wait); 872 wake_up_interruptible(&port->port.open_wait);
875 } 873 }
876 874
875 tty = tty_port_tty_get(&port->port);
877 if (port->port.flags & ASYNC_CTS_FLOW) { 876 if (port->port.flags & ASYNC_CTS_FLOW) {
878 if (port->port.tty->hw_stopped) { 877 if (tty->hw_stopped) {
879 if (status & UART_MSR_CTS) { 878 if (status & UART_MSR_CTS) {
880 port->port.tty->hw_stopped = 0; 879 tty->hw_stopped = 0;
881 880
882 if ((port->type != PORT_16550A) && 881 if ((port->type != PORT_16550A) &&
883 (!port->board->chip_flag)) { 882 (!port->board->chip_flag)) {
@@ -887,11 +886,11 @@ static void mxser_check_modem_status(struct mxser_port *port, int status)
887 outb(port->IER, port->ioaddr + 886 outb(port->IER, port->ioaddr +
888 UART_IER); 887 UART_IER);
889 } 888 }
890 tty_wakeup(port->port.tty); 889 tty_wakeup(tty);
891 } 890 }
892 } else { 891 } else {
893 if (!(status & UART_MSR_CTS)) { 892 if (!(status & UART_MSR_CTS)) {
894 port->port.tty->hw_stopped = 1; 893 tty->hw_stopped = 1;
895 if (port->type != PORT_16550A && 894 if (port->type != PORT_16550A &&
896 !port->board->chip_flag) { 895 !port->board->chip_flag) {
897 port->IER &= ~UART_IER_THRI; 896 port->IER &= ~UART_IER_THRI;
@@ -903,8 +902,9 @@ static void mxser_check_modem_status(struct mxser_port *port, int status)
903 } 902 }
904} 903}
905 904
906static int mxser_startup(struct mxser_port *info) 905static int mxser_startup(struct tty_struct *tty)
907{ 906{
907 struct mxser_port *info = tty->driver_data;
908 unsigned long page; 908 unsigned long page;
909 unsigned long flags; 909 unsigned long flags;
910 910
@@ -921,8 +921,7 @@ static int mxser_startup(struct mxser_port *info)
921 } 921 }
922 922
923 if (!info->ioaddr || !info->type) { 923 if (!info->ioaddr || !info->type) {
924 if (info->port.tty) 924 set_bit(TTY_IO_ERROR, &tty->flags);
925 set_bit(TTY_IO_ERROR, &info->port.tty->flags);
926 free_page(page); 925 free_page(page);
927 spin_unlock_irqrestore(&info->slock, flags); 926 spin_unlock_irqrestore(&info->slock, flags);
928 return 0; 927 return 0;
@@ -952,8 +951,8 @@ static int mxser_startup(struct mxser_port *info)
952 if (inb(info->ioaddr + UART_LSR) == 0xff) { 951 if (inb(info->ioaddr + UART_LSR) == 0xff) {
953 spin_unlock_irqrestore(&info->slock, flags); 952 spin_unlock_irqrestore(&info->slock, flags);
954 if (capable(CAP_SYS_ADMIN)) { 953 if (capable(CAP_SYS_ADMIN)) {
955 if (info->port.tty) 954 if (tty)
956 set_bit(TTY_IO_ERROR, &info->port.tty->flags); 955 set_bit(TTY_IO_ERROR, &tty->flags);
957 return 0; 956 return 0;
958 } else 957 } else
959 return -ENODEV; 958 return -ENODEV;
@@ -991,14 +990,13 @@ static int mxser_startup(struct mxser_port *info)
991 (void) inb(info->ioaddr + UART_IIR); 990 (void) inb(info->ioaddr + UART_IIR);
992 (void) inb(info->ioaddr + UART_MSR); 991 (void) inb(info->ioaddr + UART_MSR);
993 992
994 if (info->port.tty) 993 clear_bit(TTY_IO_ERROR, &tty->flags);
995 clear_bit(TTY_IO_ERROR, &info->port.tty->flags);
996 info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; 994 info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
997 995
998 /* 996 /*
999 * and set the speed of the serial port 997 * and set the speed of the serial port
1000 */ 998 */
1001 mxser_change_speed(info, NULL); 999 mxser_change_speed(tty, NULL);
1002 info->port.flags |= ASYNC_INITIALIZED; 1000 info->port.flags |= ASYNC_INITIALIZED;
1003 spin_unlock_irqrestore(&info->slock, flags); 1001 spin_unlock_irqrestore(&info->slock, flags);
1004 1002
@@ -1009,8 +1007,9 @@ static int mxser_startup(struct mxser_port *info)
1009 * This routine will shutdown a serial port; interrupts maybe disabled, and 1007 * This routine will shutdown a serial port; interrupts maybe disabled, and
1010 * DTR is dropped if the hangup on close termio flag is on. 1008 * DTR is dropped if the hangup on close termio flag is on.
1011 */ 1009 */
1012static void mxser_shutdown(struct mxser_port *info) 1010static void mxser_shutdown(struct tty_struct *tty)
1013{ 1011{
1012 struct mxser_port *info = tty->driver_data;
1014 unsigned long flags; 1013 unsigned long flags;
1015 1014
1016 if (!(info->port.flags & ASYNC_INITIALIZED)) 1015 if (!(info->port.flags & ASYNC_INITIALIZED))
@@ -1035,7 +1034,7 @@ static void mxser_shutdown(struct mxser_port *info)
1035 info->IER = 0; 1034 info->IER = 0;
1036 outb(0x00, info->ioaddr + UART_IER); 1035 outb(0x00, info->ioaddr + UART_IER);
1037 1036
1038 if (!info->port.tty || (info->port.tty->termios->c_cflag & HUPCL)) 1037 if (tty->termios->c_cflag & HUPCL)
1039 info->MCR &= ~(UART_MCR_DTR | UART_MCR_RTS); 1038 info->MCR &= ~(UART_MCR_DTR | UART_MCR_RTS);
1040 outb(info->MCR, info->ioaddr + UART_MCR); 1039 outb(info->MCR, info->ioaddr + UART_MCR);
1041 1040
@@ -1051,8 +1050,7 @@ static void mxser_shutdown(struct mxser_port *info)
1051 /* read data port to reset things */ 1050 /* read data port to reset things */
1052 (void) inb(info->ioaddr + UART_RX); 1051 (void) inb(info->ioaddr + UART_RX);
1053 1052
1054 if (info->port.tty) 1053 set_bit(TTY_IO_ERROR, &tty->flags);
1055 set_bit(TTY_IO_ERROR, &info->port.tty->flags);
1056 1054
1057 info->port.flags &= ~ASYNC_INITIALIZED; 1055 info->port.flags &= ~ASYNC_INITIALIZED;
1058 1056
@@ -1084,14 +1082,14 @@ static int mxser_open(struct tty_struct *tty, struct file *filp)
1084 return -ENODEV; 1082 return -ENODEV;
1085 1083
1086 tty->driver_data = info; 1084 tty->driver_data = info;
1087 info->port.tty = tty; 1085 tty_port_tty_set(&info->port, tty);
1088 /* 1086 /*
1089 * Start up serial port 1087 * Start up serial port
1090 */ 1088 */
1091 spin_lock_irqsave(&info->slock, flags); 1089 spin_lock_irqsave(&info->slock, flags);
1092 info->port.count++; 1090 info->port.count++;
1093 spin_unlock_irqrestore(&info->slock, flags); 1091 spin_unlock_irqrestore(&info->slock, flags);
1094 retval = mxser_startup(info); 1092 retval = mxser_startup(tty);
1095 if (retval) 1093 if (retval)
1096 return retval; 1094 return retval;
1097 1095
@@ -1209,13 +1207,13 @@ static void mxser_close(struct tty_struct *tty, struct file *filp)
1209 break; 1207 break;
1210 } 1208 }
1211 } 1209 }
1212 mxser_shutdown(info); 1210 mxser_shutdown(tty);
1213 1211
1214 mxser_flush_buffer(tty); 1212 mxser_flush_buffer(tty);
1215 tty_ldisc_flush(tty); 1213 tty_ldisc_flush(tty);
1216 1214
1217 tty->closing = 0; 1215 tty->closing = 0;
1218 info->port.tty = NULL; 1216 tty_port_tty_set(&info->port, NULL);
1219 if (info->port.blocked_open) { 1217 if (info->port.blocked_open) {
1220 if (info->port.close_delay) 1218 if (info->port.close_delay)
1221 schedule_timeout_interruptible(info->port.close_delay); 1219 schedule_timeout_interruptible(info->port.close_delay);
@@ -1337,12 +1335,13 @@ static int mxser_chars_in_buffer(struct tty_struct *tty)
1337 * friends of mxser_ioctl() 1335 * friends of mxser_ioctl()
1338 * ------------------------------------------------------------ 1336 * ------------------------------------------------------------
1339 */ 1337 */
1340static int mxser_get_serial_info(struct mxser_port *info, 1338static int mxser_get_serial_info(struct tty_struct *tty,
1341 struct serial_struct __user *retinfo) 1339 struct serial_struct __user *retinfo)
1342{ 1340{
1341 struct mxser_port *info = tty->driver_data;
1343 struct serial_struct tmp = { 1342 struct serial_struct tmp = {
1344 .type = info->type, 1343 .type = info->type,
1345 .line = info->port.tty->index, 1344 .line = tty->index,
1346 .port = info->ioaddr, 1345 .port = info->ioaddr,
1347 .irq = info->board->irq, 1346 .irq = info->board->irq,
1348 .flags = info->port.flags, 1347 .flags = info->port.flags,
@@ -1357,9 +1356,10 @@ static int mxser_get_serial_info(struct mxser_port *info,
1357 return 0; 1356 return 0;
1358} 1357}
1359 1358
1360static int mxser_set_serial_info(struct mxser_port *info, 1359static int mxser_set_serial_info(struct tty_struct *tty,
1361 struct serial_struct __user *new_info) 1360 struct serial_struct __user *new_info)
1362{ 1361{
1362 struct mxser_port *info = tty->driver_data;
1363 struct serial_struct new_serial; 1363 struct serial_struct new_serial;
1364 speed_t baud; 1364 speed_t baud;
1365 unsigned long sl_flags; 1365 unsigned long sl_flags;
@@ -1393,14 +1393,14 @@ static int mxser_set_serial_info(struct mxser_port *info,
1393 (new_serial.flags & ASYNC_FLAGS)); 1393 (new_serial.flags & ASYNC_FLAGS));
1394 info->port.close_delay = new_serial.close_delay * HZ / 100; 1394 info->port.close_delay = new_serial.close_delay * HZ / 100;
1395 info->port.closing_wait = new_serial.closing_wait * HZ / 100; 1395 info->port.closing_wait = new_serial.closing_wait * HZ / 100;
1396 info->port.tty->low_latency = 1396 tty->low_latency = (info->port.flags & ASYNC_LOW_LATENCY)
1397 (info->port.flags & ASYNC_LOW_LATENCY) ? 1 : 0; 1397 ? 1 : 0;
1398 if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST && 1398 if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST &&
1399 (new_serial.baud_base != info->baud_base || 1399 (new_serial.baud_base != info->baud_base ||
1400 new_serial.custom_divisor != 1400 new_serial.custom_divisor !=
1401 info->custom_divisor)) { 1401 info->custom_divisor)) {
1402 baud = new_serial.baud_base / new_serial.custom_divisor; 1402 baud = new_serial.baud_base / new_serial.custom_divisor;
1403 tty_encode_baud_rate(info->port.tty, baud, baud); 1403 tty_encode_baud_rate(tty, baud, baud);
1404 } 1404 }
1405 } 1405 }
1406 1406
@@ -1411,11 +1411,11 @@ static int mxser_set_serial_info(struct mxser_port *info,
1411 if (info->port.flags & ASYNC_INITIALIZED) { 1411 if (info->port.flags & ASYNC_INITIALIZED) {
1412 if (flags != (info->port.flags & ASYNC_SPD_MASK)) { 1412 if (flags != (info->port.flags & ASYNC_SPD_MASK)) {
1413 spin_lock_irqsave(&info->slock, sl_flags); 1413 spin_lock_irqsave(&info->slock, sl_flags);
1414 mxser_change_speed(info, NULL); 1414 mxser_change_speed(tty, NULL);
1415 spin_unlock_irqrestore(&info->slock, sl_flags); 1415 spin_unlock_irqrestore(&info->slock, sl_flags);
1416 } 1416 }
1417 } else 1417 } else
1418 retval = mxser_startup(info); 1418 retval = mxser_startup(tty);
1419 1419
1420 return retval; 1420 return retval;
1421} 1421}
@@ -1461,7 +1461,7 @@ static int mxser_tiocmget(struct tty_struct *tty, struct file *file)
1461 spin_lock_irqsave(&info->slock, flags); 1461 spin_lock_irqsave(&info->slock, flags);
1462 status = inb(info->ioaddr + UART_MSR); 1462 status = inb(info->ioaddr + UART_MSR);
1463 if (status & UART_MSR_ANY_DELTA) 1463 if (status & UART_MSR_ANY_DELTA)
1464 mxser_check_modem_status(info, status); 1464 mxser_check_modem_status(tty, info, status);
1465 spin_unlock_irqrestore(&info->slock, flags); 1465 spin_unlock_irqrestore(&info->slock, flags);
1466 return ((control & UART_MCR_RTS) ? TIOCM_RTS : 0) | 1466 return ((control & UART_MCR_RTS) ? TIOCM_RTS : 0) |
1467 ((control & UART_MCR_DTR) ? TIOCM_DTR : 0) | 1467 ((control & UART_MCR_DTR) ? TIOCM_DTR : 0) |
@@ -1606,6 +1606,7 @@ static int __init mxser_read_register(int port, unsigned short *regs)
1606static int mxser_ioctl_special(unsigned int cmd, void __user *argp) 1606static int mxser_ioctl_special(unsigned int cmd, void __user *argp)
1607{ 1607{
1608 struct mxser_port *port; 1608 struct mxser_port *port;
1609 struct tty_struct *tty;
1609 int result, status; 1610 int result, status;
1610 unsigned int i, j; 1611 unsigned int i, j;
1611 int ret = 0; 1612 int ret = 0;
@@ -1643,12 +1644,14 @@ static int mxser_ioctl_special(unsigned int cmd, void __user *argp)
1643 1644
1644 if (!port->ioaddr) 1645 if (!port->ioaddr)
1645 goto copy; 1646 goto copy;
1647
1648 tty = tty_port_tty_get(&port->port);
1646 1649
1647 if (!port->port.tty || !port->port.tty->termios) 1650 if (!tty || !tty->termios)
1648 ms.cflag = port->normal_termios.c_cflag; 1651 ms.cflag = port->normal_termios.c_cflag;
1649 else 1652 else
1650 ms.cflag = port->port.tty->termios->c_cflag; 1653 ms.cflag = tty->termios->c_cflag;
1651 1654 tty_kref_put(tty);
1652 status = inb(port->ioaddr + UART_MSR); 1655 status = inb(port->ioaddr + UART_MSR);
1653 if (status & UART_MSR_DCD) 1656 if (status & UART_MSR_DCD)
1654 ms.dcd = 1; 1657 ms.dcd = 1;
@@ -1704,15 +1707,18 @@ static int mxser_ioctl_special(unsigned int cmd, void __user *argp)
1704 me->up_txcnt[p] = port->mon_data.up_txcnt; 1707 me->up_txcnt[p] = port->mon_data.up_txcnt;
1705 me->modem_status[p] = 1708 me->modem_status[p] =
1706 port->mon_data.modem_status; 1709 port->mon_data.modem_status;
1707 me->baudrate[p] = tty_get_baud_rate(port->port.tty); 1710 tty = tty_port_tty_get(&port->port);
1708 1711
1709 if (!port->port.tty || !port->port.tty->termios) { 1712 if (!tty || !tty->termios) {
1710 cflag = port->normal_termios.c_cflag; 1713 cflag = port->normal_termios.c_cflag;
1711 iflag = port->normal_termios.c_iflag; 1714 iflag = port->normal_termios.c_iflag;
1715 me->baudrate[p] = tty_termios_baud_rate(&port->normal_termios);
1712 } else { 1716 } else {
1713 cflag = port->port.tty->termios->c_cflag; 1717 cflag = tty->termios->c_cflag;
1714 iflag = port->port.tty->termios->c_iflag; 1718 iflag = tty->termios->c_iflag;
1719 me->baudrate[p] = tty_get_baud_rate(tty);
1715 } 1720 }
1721 tty_kref_put(tty);
1716 1722
1717 me->databits[p] = cflag & CSIZE; 1723 me->databits[p] = cflag & CSIZE;
1718 me->stopbits[p] = cflag & CSTOPB; 1724 me->stopbits[p] = cflag & CSTOPB;
@@ -1822,12 +1828,12 @@ static int mxser_ioctl(struct tty_struct *tty, struct file *file,
1822 switch (cmd) { 1828 switch (cmd) {
1823 case TIOCGSERIAL: 1829 case TIOCGSERIAL:
1824 lock_kernel(); 1830 lock_kernel();
1825 retval = mxser_get_serial_info(info, argp); 1831 retval = mxser_get_serial_info(tty, argp);
1826 unlock_kernel(); 1832 unlock_kernel();
1827 return retval; 1833 return retval;
1828 case TIOCSSERIAL: 1834 case TIOCSSERIAL:
1829 lock_kernel(); 1835 lock_kernel();
1830 retval = mxser_set_serial_info(info, argp); 1836 retval = mxser_set_serial_info(tty, argp);
1831 unlock_kernel(); 1837 unlock_kernel();
1832 return retval; 1838 return retval;
1833 case TIOCSERGETLSR: /* Get line status register */ 1839 case TIOCSERGETLSR: /* Get line status register */
@@ -1896,7 +1902,7 @@ static int mxser_ioctl(struct tty_struct *tty, struct file *file,
1896 1902
1897 lock_kernel(); 1903 lock_kernel();
1898 status = mxser_get_msr(info->ioaddr, 1, tty->index); 1904 status = mxser_get_msr(info->ioaddr, 1, tty->index);
1899 mxser_check_modem_status(info, status); 1905 mxser_check_modem_status(tty, info, status);
1900 1906
1901 mcr = inb(info->ioaddr + UART_MCR); 1907 mcr = inb(info->ioaddr + UART_MCR);
1902 if (mcr & MOXA_MUST_MCR_XON_FLAG) 1908 if (mcr & MOXA_MUST_MCR_XON_FLAG)
@@ -1909,7 +1915,7 @@ static int mxser_ioctl(struct tty_struct *tty, struct file *file,
1909 else 1915 else
1910 info->mon_data.hold_reason |= NPPI_NOTIFY_XOFFXENT; 1916 info->mon_data.hold_reason |= NPPI_NOTIFY_XOFFXENT;
1911 1917
1912 if (info->port.tty->hw_stopped) 1918 if (tty->hw_stopped)
1913 info->mon_data.hold_reason |= NPPI_NOTIFY_CTSHOLD; 1919 info->mon_data.hold_reason |= NPPI_NOTIFY_CTSHOLD;
1914 else 1920 else
1915 info->mon_data.hold_reason &= ~NPPI_NOTIFY_CTSHOLD; 1921 info->mon_data.hold_reason &= ~NPPI_NOTIFY_CTSHOLD;
@@ -1958,7 +1964,7 @@ static void mxser_stoprx(struct tty_struct *tty)
1958 } 1964 }
1959 } 1965 }
1960 1966
1961 if (info->port.tty->termios->c_cflag & CRTSCTS) { 1967 if (tty->termios->c_cflag & CRTSCTS) {
1962 info->MCR &= ~UART_MCR_RTS; 1968 info->MCR &= ~UART_MCR_RTS;
1963 outb(info->MCR, info->ioaddr + UART_MCR); 1969 outb(info->MCR, info->ioaddr + UART_MCR);
1964 } 1970 }
@@ -1995,7 +2001,7 @@ static void mxser_unthrottle(struct tty_struct *tty)
1995 } 2001 }
1996 } 2002 }
1997 2003
1998 if (info->port.tty->termios->c_cflag & CRTSCTS) { 2004 if (tty->termios->c_cflag & CRTSCTS) {
1999 info->MCR |= UART_MCR_RTS; 2005 info->MCR |= UART_MCR_RTS;
2000 outb(info->MCR, info->ioaddr + UART_MCR); 2006 outb(info->MCR, info->ioaddr + UART_MCR);
2001 } 2007 }
@@ -2040,7 +2046,7 @@ static void mxser_set_termios(struct tty_struct *tty, struct ktermios *old_termi
2040 unsigned long flags; 2046 unsigned long flags;
2041 2047
2042 spin_lock_irqsave(&info->slock, flags); 2048 spin_lock_irqsave(&info->slock, flags);
2043 mxser_change_speed(info, old_termios); 2049 mxser_change_speed(tty, old_termios);
2044 spin_unlock_irqrestore(&info->slock, flags); 2050 spin_unlock_irqrestore(&info->slock, flags);
2045 2051
2046 if ((old_termios->c_cflag & CRTSCTS) && 2052 if ((old_termios->c_cflag & CRTSCTS) &&
@@ -2138,10 +2144,10 @@ static void mxser_hangup(struct tty_struct *tty)
2138 struct mxser_port *info = tty->driver_data; 2144 struct mxser_port *info = tty->driver_data;
2139 2145
2140 mxser_flush_buffer(tty); 2146 mxser_flush_buffer(tty);
2141 mxser_shutdown(info); 2147 mxser_shutdown(tty);
2142 info->port.count = 0; 2148 info->port.count = 0;
2143 info->port.flags &= ~ASYNC_NORMAL_ACTIVE; 2149 info->port.flags &= ~ASYNC_NORMAL_ACTIVE;
2144 info->port.tty = NULL; 2150 tty_port_tty_set(&info->port, NULL);
2145 wake_up_interruptible(&info->port.open_wait); 2151 wake_up_interruptible(&info->port.open_wait);
2146} 2152}
2147 2153
@@ -2164,9 +2170,9 @@ static int mxser_rs_break(struct tty_struct *tty, int break_state)
2164 return 0; 2170 return 0;
2165} 2171}
2166 2172
2167static void mxser_receive_chars(struct mxser_port *port, int *status) 2173static void mxser_receive_chars(struct tty_struct *tty,
2174 struct mxser_port *port, int *status)
2168{ 2175{
2169 struct tty_struct *tty = port->port.tty;
2170 unsigned char ch, gdl; 2176 unsigned char ch, gdl;
2171 int ignored = 0; 2177 int ignored = 0;
2172 int cnt = 0; 2178 int cnt = 0;
@@ -2174,9 +2180,8 @@ static void mxser_receive_chars(struct mxser_port *port, int *status)
2174 int max = 256; 2180 int max = 256;
2175 2181
2176 recv_room = tty->receive_room; 2182 recv_room = tty->receive_room;
2177 if ((recv_room == 0) && (!port->ldisc_stop_rx)) 2183 if (recv_room == 0 && !port->ldisc_stop_rx)
2178 mxser_stoprx(tty); 2184 mxser_stoprx(tty);
2179
2180 if (port->board->chip_flag != MOXA_OTHER_UART) { 2185 if (port->board->chip_flag != MOXA_OTHER_UART) {
2181 2186
2182 if (*status & UART_LSR_SPECIAL) 2187 if (*status & UART_LSR_SPECIAL)
@@ -2253,7 +2258,7 @@ intr_old:
2253 } while (*status & UART_LSR_DR); 2258 } while (*status & UART_LSR_DR);
2254 2259
2255end_intr: 2260end_intr:
2256 mxvar_log.rxcnt[port->port.tty->index] += cnt; 2261 mxvar_log.rxcnt[tty->index] += cnt;
2257 port->mon_data.rxcnt += cnt; 2262 port->mon_data.rxcnt += cnt;
2258 port->mon_data.up_rxcnt += cnt; 2263 port->mon_data.up_rxcnt += cnt;
2259 2264
@@ -2267,14 +2272,14 @@ end_intr:
2267 spin_lock(&port->slock); 2272 spin_lock(&port->slock);
2268} 2273}
2269 2274
2270static void mxser_transmit_chars(struct mxser_port *port) 2275static void mxser_transmit_chars(struct tty_struct *tty, struct mxser_port *port)
2271{ 2276{
2272 int count, cnt; 2277 int count, cnt;
2273 2278
2274 if (port->x_char) { 2279 if (port->x_char) {
2275 outb(port->x_char, port->ioaddr + UART_TX); 2280 outb(port->x_char, port->ioaddr + UART_TX);
2276 port->x_char = 0; 2281 port->x_char = 0;
2277 mxvar_log.txcnt[port->port.tty->index]++; 2282 mxvar_log.txcnt[tty->index]++;
2278 port->mon_data.txcnt++; 2283 port->mon_data.txcnt++;
2279 port->mon_data.up_txcnt++; 2284 port->mon_data.up_txcnt++;
2280 port->icount.tx++; 2285 port->icount.tx++;
@@ -2284,8 +2289,8 @@ static void mxser_transmit_chars(struct mxser_port *port)
2284 if (port->port.xmit_buf == NULL) 2289 if (port->port.xmit_buf == NULL)
2285 return; 2290 return;
2286 2291
2287 if ((port->xmit_cnt <= 0) || port->port.tty->stopped || 2292 if (port->xmit_cnt <= 0 || tty->stopped ||
2288 (port->port.tty->hw_stopped && 2293 (tty->hw_stopped &&
2289 (port->type != PORT_16550A) && 2294 (port->type != PORT_16550A) &&
2290 (!port->board->chip_flag))) { 2295 (!port->board->chip_flag))) {
2291 port->IER &= ~UART_IER_THRI; 2296 port->IER &= ~UART_IER_THRI;
@@ -2302,14 +2307,14 @@ static void mxser_transmit_chars(struct mxser_port *port)
2302 if (--port->xmit_cnt <= 0) 2307 if (--port->xmit_cnt <= 0)
2303 break; 2308 break;
2304 } while (--count > 0); 2309 } while (--count > 0);
2305 mxvar_log.txcnt[port->port.tty->index] += (cnt - port->xmit_cnt); 2310 mxvar_log.txcnt[tty->index] += (cnt - port->xmit_cnt);
2306 2311
2307 port->mon_data.txcnt += (cnt - port->xmit_cnt); 2312 port->mon_data.txcnt += (cnt - port->xmit_cnt);
2308 port->mon_data.up_txcnt += (cnt - port->xmit_cnt); 2313 port->mon_data.up_txcnt += (cnt - port->xmit_cnt);
2309 port->icount.tx += (cnt - port->xmit_cnt); 2314 port->icount.tx += (cnt - port->xmit_cnt);
2310 2315
2311 if (port->xmit_cnt < WAKEUP_CHARS) 2316 if (port->xmit_cnt < WAKEUP_CHARS && tty)
2312 tty_wakeup(port->port.tty); 2317 tty_wakeup(tty);
2313 2318
2314 if (port->xmit_cnt <= 0) { 2319 if (port->xmit_cnt <= 0) {
2315 port->IER &= ~UART_IER_THRI; 2320 port->IER &= ~UART_IER_THRI;
@@ -2328,6 +2333,7 @@ static irqreturn_t mxser_interrupt(int irq, void *dev_id)
2328 int max, irqbits, bits, msr; 2333 int max, irqbits, bits, msr;
2329 unsigned int int_cnt, pass_counter = 0; 2334 unsigned int int_cnt, pass_counter = 0;
2330 int handled = IRQ_NONE; 2335 int handled = IRQ_NONE;
2336 struct tty_struct *tty;
2331 2337
2332 for (i = 0; i < MXSER_BOARDS; i++) 2338 for (i = 0; i < MXSER_BOARDS; i++)
2333 if (dev_id == &mxser_boards[i]) { 2339 if (dev_id == &mxser_boards[i]) {
@@ -2360,13 +2366,15 @@ static irqreturn_t mxser_interrupt(int irq, void *dev_id)
2360 if (iir & UART_IIR_NO_INT) 2366 if (iir & UART_IIR_NO_INT)
2361 break; 2367 break;
2362 iir &= MOXA_MUST_IIR_MASK; 2368 iir &= MOXA_MUST_IIR_MASK;
2363 if (!port->port.tty || 2369 tty = tty_port_tty_get(&port->port);
2370 if (!tty ||
2364 (port->port.flags & ASYNC_CLOSING) || 2371 (port->port.flags & ASYNC_CLOSING) ||
2365 !(port->port.flags & 2372 !(port->port.flags &
2366 ASYNC_INITIALIZED)) { 2373 ASYNC_INITIALIZED)) {
2367 status = inb(port->ioaddr + UART_LSR); 2374 status = inb(port->ioaddr + UART_LSR);
2368 outb(0x27, port->ioaddr + UART_FCR); 2375 outb(0x27, port->ioaddr + UART_FCR);
2369 inb(port->ioaddr + UART_MSR); 2376 inb(port->ioaddr + UART_MSR);
2377 tty_kref_put(tty);
2370 break; 2378 break;
2371 } 2379 }
2372 2380
@@ -2387,27 +2395,28 @@ static irqreturn_t mxser_interrupt(int irq, void *dev_id)
2387 iir == MOXA_MUST_IIR_RDA || 2395 iir == MOXA_MUST_IIR_RDA ||
2388 iir == MOXA_MUST_IIR_RTO || 2396 iir == MOXA_MUST_IIR_RTO ||
2389 iir == MOXA_MUST_IIR_LSR) 2397 iir == MOXA_MUST_IIR_LSR)
2390 mxser_receive_chars(port, 2398 mxser_receive_chars(tty, port,
2391 &status); 2399 &status);
2392 2400
2393 } else { 2401 } else {
2394 status &= port->read_status_mask; 2402 status &= port->read_status_mask;
2395 if (status & UART_LSR_DR) 2403 if (status & UART_LSR_DR)
2396 mxser_receive_chars(port, 2404 mxser_receive_chars(tty, port,
2397 &status); 2405 &status);
2398 } 2406 }
2399 msr = inb(port->ioaddr + UART_MSR); 2407 msr = inb(port->ioaddr + UART_MSR);
2400 if (msr & UART_MSR_ANY_DELTA) 2408 if (msr & UART_MSR_ANY_DELTA)
2401 mxser_check_modem_status(port, msr); 2409 mxser_check_modem_status(tty, port, msr);
2402 2410
2403 if (port->board->chip_flag) { 2411 if (port->board->chip_flag) {
2404 if (iir == 0x02 && (status & 2412 if (iir == 0x02 && (status &
2405 UART_LSR_THRE)) 2413 UART_LSR_THRE))
2406 mxser_transmit_chars(port); 2414 mxser_transmit_chars(tty, port);
2407 } else { 2415 } else {
2408 if (status & UART_LSR_THRE) 2416 if (status & UART_LSR_THRE)
2409 mxser_transmit_chars(port); 2417 mxser_transmit_chars(tty, port);
2410 } 2418 }
2419 tty_kref_put(tty);
2411 } while (int_cnt++ < MXSER_ISR_PASS_LIMIT); 2420 } while (int_cnt++ < MXSER_ISR_PASS_LIMIT);
2412 spin_unlock(&port->slock); 2421 spin_unlock(&port->slock);
2413 } 2422 }
diff --git a/drivers/char/n_hdlc.c b/drivers/char/n_hdlc.c
index 69ec6399c714..bacb3e2872ae 100644
--- a/drivers/char/n_hdlc.c
+++ b/drivers/char/n_hdlc.c
@@ -764,7 +764,7 @@ static int n_hdlc_tty_ioctl(struct tty_struct *tty, struct file *file,
764 break; 764 break;
765 765
766 default: 766 default:
767 error = n_tty_ioctl (tty, file, cmd, arg); 767 error = n_tty_ioctl_helper(tty, file, cmd, arg);
768 break; 768 break;
769 } 769 }
770 return error; 770 return error;
diff --git a/drivers/char/n_r3964.c b/drivers/char/n_r3964.c
index ae377aa473ba..4a8215a89ad3 100644
--- a/drivers/char/n_r3964.c
+++ b/drivers/char/n_r3964.c
@@ -372,14 +372,8 @@ static void remove_from_rx_queue(struct r3964_info *pInfo,
372static void put_char(struct r3964_info *pInfo, unsigned char ch) 372static void put_char(struct r3964_info *pInfo, unsigned char ch)
373{ 373{
374 struct tty_struct *tty = pInfo->tty; 374 struct tty_struct *tty = pInfo->tty;
375
376 if (tty == NULL)
377 return;
378
379 /* FIXME: put_char should not be called from an IRQ */ 375 /* FIXME: put_char should not be called from an IRQ */
380 if (tty->ops->put_char) { 376 tty_put_char(tty, ch);
381 tty->ops->put_char(tty, ch);
382 }
383 pInfo->bcc ^= ch; 377 pInfo->bcc ^= ch;
384} 378}
385 379
diff --git a/drivers/char/n_tty.c b/drivers/char/n_tty.c
index 708c2b1dbe51..efbfe9612658 100644
--- a/drivers/char/n_tty.c
+++ b/drivers/char/n_tty.c
@@ -26,7 +26,7 @@
26 * 26 *
27 * 2002/03/18 Implemented n_tty_wakeup to send SIGIO POLL_OUTs to 27 * 2002/03/18 Implemented n_tty_wakeup to send SIGIO POLL_OUTs to
28 * waiting writing processes-Sapan Bhatia <sapan@corewars.org>. 28 * waiting writing processes-Sapan Bhatia <sapan@corewars.org>.
29 * Also fixed a bug in BLOCKING mode where write_chan returns 29 * Also fixed a bug in BLOCKING mode where n_tty_write returns
30 * EAGAIN 30 * EAGAIN
31 */ 31 */
32 32
@@ -99,6 +99,7 @@ static inline int tty_put_user(struct tty_struct *tty, unsigned char x,
99 99
100static void n_tty_set_room(struct tty_struct *tty) 100static void n_tty_set_room(struct tty_struct *tty)
101{ 101{
102 /* tty->read_cnt is not read locked ? */
102 int left = N_TTY_BUF_SIZE - tty->read_cnt - 1; 103 int left = N_TTY_BUF_SIZE - tty->read_cnt - 1;
103 104
104 /* 105 /*
@@ -121,6 +122,16 @@ static void put_tty_queue_nolock(unsigned char c, struct tty_struct *tty)
121 } 122 }
122} 123}
123 124
125/**
126 * put_tty_queue - add character to tty
127 * @c: character
128 * @tty: tty device
129 *
130 * Add a character to the tty read_buf queue. This is done under the
131 * read_lock to serialize character addition and also to protect us
132 * against parallel reads or flushes
133 */
134
124static void put_tty_queue(unsigned char c, struct tty_struct *tty) 135static void put_tty_queue(unsigned char c, struct tty_struct *tty)
125{ 136{
126 unsigned long flags; 137 unsigned long flags;
@@ -137,14 +148,11 @@ static void put_tty_queue(unsigned char c, struct tty_struct *tty)
137 * check_unthrottle - allow new receive data 148 * check_unthrottle - allow new receive data
138 * @tty; tty device 149 * @tty; tty device
139 * 150 *
140 * Check whether to call the driver.unthrottle function. 151 * Check whether to call the driver unthrottle functions
141 * We test the TTY_THROTTLED bit first so that it always 152 *
142 * indicates the current state. The decision about whether
143 * it is worth allowing more input has been taken by the caller.
144 * Can sleep, may be called under the atomic_read_lock mutex but 153 * Can sleep, may be called under the atomic_read_lock mutex but
145 * this is not guaranteed. 154 * this is not guaranteed.
146 */ 155 */
147
148static void check_unthrottle(struct tty_struct *tty) 156static void check_unthrottle(struct tty_struct *tty)
149{ 157{
150 if (tty->count) 158 if (tty->count)
@@ -158,6 +166,8 @@ static void check_unthrottle(struct tty_struct *tty)
158 * Reset the read buffer counters, clear the flags, 166 * Reset the read buffer counters, clear the flags,
159 * and make sure the driver is unthrottled. Called 167 * and make sure the driver is unthrottled. Called
160 * from n_tty_open() and n_tty_flush_buffer(). 168 * from n_tty_open() and n_tty_flush_buffer().
169 *
170 * Locking: tty_read_lock for read fields.
161 */ 171 */
162static void reset_buffer_flags(struct tty_struct *tty) 172static void reset_buffer_flags(struct tty_struct *tty)
163{ 173{
@@ -181,7 +191,7 @@ static void reset_buffer_flags(struct tty_struct *tty)
181 * at hangup) or when the N_TTY line discipline internally has to 191 * at hangup) or when the N_TTY line discipline internally has to
182 * clean the pending queue (for example some signals). 192 * clean the pending queue (for example some signals).
183 * 193 *
184 * Locking: ctrl_lock 194 * Locking: ctrl_lock, read_lock.
185 */ 195 */
186 196
187static void n_tty_flush_buffer(struct tty_struct *tty) 197static void n_tty_flush_buffer(struct tty_struct *tty)
@@ -207,6 +217,8 @@ static void n_tty_flush_buffer(struct tty_struct *tty)
207 * 217 *
208 * Report the number of characters buffered to be delivered to user 218 * Report the number of characters buffered to be delivered to user
209 * at this instant in time. 219 * at this instant in time.
220 *
221 * Locking: read_lock
210 */ 222 */
211 223
212static ssize_t n_tty_chars_in_buffer(struct tty_struct *tty) 224static ssize_t n_tty_chars_in_buffer(struct tty_struct *tty)
@@ -346,7 +358,7 @@ static int opost(unsigned char c, struct tty_struct *tty)
346 * the simple cases normally found and helps to generate blocks of 358 * the simple cases normally found and helps to generate blocks of
347 * symbols for the console driver and thus improve performance. 359 * symbols for the console driver and thus improve performance.
348 * 360 *
349 * Called from write_chan under the tty layer write lock. Relies 361 * Called from n_tty_write under the tty layer write lock. Relies
350 * on lock_kernel for the tty->column state. 362 * on lock_kernel for the tty->column state.
351 */ 363 */
352 364
@@ -410,6 +422,8 @@ break_out:
410 * 422 *
411 * Echo user input back onto the screen. This must be called only when 423 * Echo user input back onto the screen. This must be called only when
412 * L_ECHO(tty) is true. Called from the driver receive_buf path. 424 * L_ECHO(tty) is true. Called from the driver receive_buf path.
425 *
426 * Relies on BKL for tty column locking
413 */ 427 */
414 428
415static void echo_char(unsigned char c, struct tty_struct *tty) 429static void echo_char(unsigned char c, struct tty_struct *tty)
@@ -422,6 +436,12 @@ static void echo_char(unsigned char c, struct tty_struct *tty)
422 opost(c, tty); 436 opost(c, tty);
423} 437}
424 438
439/**
440 * finsh_erasing - complete erase
441 * @tty: tty doing the erase
442 *
443 * Relies on BKL for tty column locking
444 */
425static inline void finish_erasing(struct tty_struct *tty) 445static inline void finish_erasing(struct tty_struct *tty)
426{ 446{
427 if (tty->erasing) { 447 if (tty->erasing) {
@@ -439,6 +459,8 @@ static inline void finish_erasing(struct tty_struct *tty)
439 * Perform erase and necessary output when an erase character is 459 * Perform erase and necessary output when an erase character is
440 * present in the stream from the driver layer. Handles the complexities 460 * present in the stream from the driver layer. Handles the complexities
441 * of UTF-8 multibyte symbols. 461 * of UTF-8 multibyte symbols.
462 *
463 * Locking: read_lock for tty buffers, BKL for column/erasing state
442 */ 464 */
443 465
444static void eraser(unsigned char c, struct tty_struct *tty) 466static void eraser(unsigned char c, struct tty_struct *tty)
@@ -447,6 +469,7 @@ static void eraser(unsigned char c, struct tty_struct *tty)
447 int head, seen_alnums, cnt; 469 int head, seen_alnums, cnt;
448 unsigned long flags; 470 unsigned long flags;
449 471
472 /* FIXME: locking needed ? */
450 if (tty->read_head == tty->canon_head) { 473 if (tty->read_head == tty->canon_head) {
451 /* opost('\a', tty); */ /* what do you think? */ 474 /* opost('\a', tty); */ /* what do you think? */
452 return; 475 return;
@@ -481,6 +504,7 @@ static void eraser(unsigned char c, struct tty_struct *tty)
481 } 504 }
482 505
483 seen_alnums = 0; 506 seen_alnums = 0;
507 /* FIXME: Locking ?? */
484 while (tty->read_head != tty->canon_head) { 508 while (tty->read_head != tty->canon_head) {
485 head = tty->read_head; 509 head = tty->read_head;
486 510
@@ -583,6 +607,8 @@ static void eraser(unsigned char c, struct tty_struct *tty)
583 * may caus terminal flushing to take place according to the termios 607 * may caus terminal flushing to take place according to the termios
584 * settings and character used. Called from the driver receive_buf 608 * settings and character used. Called from the driver receive_buf
585 * path so serialized. 609 * path so serialized.
610 *
611 * Locking: ctrl_lock, read_lock (both via flush buffer)
586 */ 612 */
587 613
588static inline void isig(int sig, struct tty_struct *tty, int flush) 614static inline void isig(int sig, struct tty_struct *tty, int flush)
@@ -1007,12 +1033,26 @@ int is_ignored(int sig)
1007 * and is protected from re-entry by the tty layer. The user is 1033 * and is protected from re-entry by the tty layer. The user is
1008 * guaranteed that this function will not be re-entered or in progress 1034 * guaranteed that this function will not be re-entered or in progress
1009 * when the ldisc is closed. 1035 * when the ldisc is closed.
1036 *
1037 * Locking: Caller holds tty->termios_mutex
1010 */ 1038 */
1011 1039
1012static void n_tty_set_termios(struct tty_struct *tty, struct ktermios *old) 1040static void n_tty_set_termios(struct tty_struct *tty, struct ktermios *old)
1013{ 1041{
1014 if (!tty) 1042 int canon_change = 1;
1015 return; 1043 BUG_ON(!tty);
1044
1045 if (old)
1046 canon_change = (old->c_lflag ^ tty->termios->c_lflag) & ICANON;
1047 if (canon_change) {
1048 memset(&tty->read_flags, 0, sizeof tty->read_flags);
1049 tty->canon_head = tty->read_tail;
1050 tty->canon_data = 0;
1051 tty->erasing = 0;
1052 }
1053
1054 if (canon_change && !L_ICANON(tty) && tty->read_cnt)
1055 wake_up_interruptible(&tty->read_wait);
1016 1056
1017 tty->icanon = (L_ICANON(tty) != 0); 1057 tty->icanon = (L_ICANON(tty) != 0);
1018 if (test_bit(TTY_HW_COOK_IN, &tty->flags)) { 1058 if (test_bit(TTY_HW_COOK_IN, &tty->flags)) {
@@ -1143,7 +1183,7 @@ static inline int input_available_p(struct tty_struct *tty, int amt)
1143 * @b: user data 1183 * @b: user data
1144 * @nr: size of data 1184 * @nr: size of data
1145 * 1185 *
1146 * Helper function to speed up read_chan. It is only called when 1186 * Helper function to speed up n_tty_read. It is only called when
1147 * ICANON is off; it copies characters straight from the tty queue to 1187 * ICANON is off; it copies characters straight from the tty queue to
1148 * user space directly. It can be profitably called twice; once to 1188 * user space directly. It can be profitably called twice; once to
1149 * drain the space from the tail pointer to the (physical) end of the 1189 * drain the space from the tail pointer to the (physical) end of the
@@ -1210,7 +1250,7 @@ static int job_control(struct tty_struct *tty, struct file *file)
1210 if (file->f_op->write != redirected_tty_write && 1250 if (file->f_op->write != redirected_tty_write &&
1211 current->signal->tty == tty) { 1251 current->signal->tty == tty) {
1212 if (!tty->pgrp) 1252 if (!tty->pgrp)
1213 printk(KERN_ERR "read_chan: no tty->pgrp!\n"); 1253 printk(KERN_ERR "n_tty_read: no tty->pgrp!\n");
1214 else if (task_pgrp(current) != tty->pgrp) { 1254 else if (task_pgrp(current) != tty->pgrp) {
1215 if (is_ignored(SIGTTIN) || 1255 if (is_ignored(SIGTTIN) ||
1216 is_current_pgrp_orphaned()) 1256 is_current_pgrp_orphaned())
@@ -1225,7 +1265,7 @@ static int job_control(struct tty_struct *tty, struct file *file)
1225 1265
1226 1266
1227/** 1267/**
1228 * read_chan - read function for tty 1268 * n_tty_read - read function for tty
1229 * @tty: tty device 1269 * @tty: tty device
1230 * @file: file object 1270 * @file: file object
1231 * @buf: userspace buffer pointer 1271 * @buf: userspace buffer pointer
@@ -1239,7 +1279,7 @@ static int job_control(struct tty_struct *tty, struct file *file)
1239 * This code must be sure never to sleep through a hangup. 1279 * This code must be sure never to sleep through a hangup.
1240 */ 1280 */
1241 1281
1242static ssize_t read_chan(struct tty_struct *tty, struct file *file, 1282static ssize_t n_tty_read(struct tty_struct *tty, struct file *file,
1243 unsigned char __user *buf, size_t nr) 1283 unsigned char __user *buf, size_t nr)
1244{ 1284{
1245 unsigned char __user *b = buf; 1285 unsigned char __user *b = buf;
@@ -1254,10 +1294,7 @@ static ssize_t read_chan(struct tty_struct *tty, struct file *file,
1254 1294
1255do_it_again: 1295do_it_again:
1256 1296
1257 if (!tty->read_buf) { 1297 BUG_ON(!tty->read_buf);
1258 printk(KERN_ERR "n_tty_read_chan: read_buf == NULL?!?\n");
1259 return -EIO;
1260 }
1261 1298
1262 c = job_control(tty, file); 1299 c = job_control(tty, file);
1263 if (c < 0) 1300 if (c < 0)
@@ -1444,7 +1481,7 @@ do_it_again:
1444} 1481}
1445 1482
1446/** 1483/**
1447 * write_chan - write function for tty 1484 * n_tty_write - write function for tty
1448 * @tty: tty device 1485 * @tty: tty device
1449 * @file: file object 1486 * @file: file object
1450 * @buf: userspace buffer pointer 1487 * @buf: userspace buffer pointer
@@ -1458,7 +1495,7 @@ do_it_again:
1458 * This code must be sure never to sleep through a hangup. 1495 * This code must be sure never to sleep through a hangup.
1459 */ 1496 */
1460 1497
1461static ssize_t write_chan(struct tty_struct *tty, struct file *file, 1498static ssize_t n_tty_write(struct tty_struct *tty, struct file *file,
1462 const unsigned char *buf, size_t nr) 1499 const unsigned char *buf, size_t nr)
1463{ 1500{
1464 const unsigned char *b = buf; 1501 const unsigned char *b = buf;
@@ -1532,7 +1569,7 @@ break_out:
1532} 1569}
1533 1570
1534/** 1571/**
1535 * normal_poll - poll method for N_TTY 1572 * n_tty_poll - poll method for N_TTY
1536 * @tty: terminal device 1573 * @tty: terminal device
1537 * @file: file accessing it 1574 * @file: file accessing it
1538 * @wait: poll table 1575 * @wait: poll table
@@ -1545,7 +1582,7 @@ break_out:
1545 * Called without the kernel lock held - fine 1582 * Called without the kernel lock held - fine
1546 */ 1583 */
1547 1584
1548static unsigned int normal_poll(struct tty_struct *tty, struct file *file, 1585static unsigned int n_tty_poll(struct tty_struct *tty, struct file *file,
1549 poll_table *wait) 1586 poll_table *wait)
1550{ 1587{
1551 unsigned int mask = 0; 1588 unsigned int mask = 0;
@@ -1573,6 +1610,44 @@ static unsigned int normal_poll(struct tty_struct *tty, struct file *file,
1573 return mask; 1610 return mask;
1574} 1611}
1575 1612
1613static unsigned long inq_canon(struct tty_struct *tty)
1614{
1615 int nr, head, tail;
1616
1617 if (!tty->canon_data)
1618 return 0;
1619 head = tty->canon_head;
1620 tail = tty->read_tail;
1621 nr = (head - tail) & (N_TTY_BUF_SIZE-1);
1622 /* Skip EOF-chars.. */
1623 while (head != tail) {
1624 if (test_bit(tail, tty->read_flags) &&
1625 tty->read_buf[tail] == __DISABLED_CHAR)
1626 nr--;
1627 tail = (tail+1) & (N_TTY_BUF_SIZE-1);
1628 }
1629 return nr;
1630}
1631
1632static int n_tty_ioctl(struct tty_struct *tty, struct file *file,
1633 unsigned int cmd, unsigned long arg)
1634{
1635 int retval;
1636
1637 switch (cmd) {
1638 case TIOCOUTQ:
1639 return put_user(tty_chars_in_buffer(tty), (int __user *) arg);
1640 case TIOCINQ:
1641 /* FIXME: Locking */
1642 retval = tty->read_cnt;
1643 if (L_ICANON(tty))
1644 retval = inq_canon(tty);
1645 return put_user(retval, (unsigned int __user *) arg);
1646 default:
1647 return n_tty_ioctl_helper(tty, file, cmd, arg);
1648 }
1649}
1650
1576struct tty_ldisc_ops tty_ldisc_N_TTY = { 1651struct tty_ldisc_ops tty_ldisc_N_TTY = {
1577 .magic = TTY_LDISC_MAGIC, 1652 .magic = TTY_LDISC_MAGIC,
1578 .name = "n_tty", 1653 .name = "n_tty",
@@ -1580,11 +1655,11 @@ struct tty_ldisc_ops tty_ldisc_N_TTY = {
1580 .close = n_tty_close, 1655 .close = n_tty_close,
1581 .flush_buffer = n_tty_flush_buffer, 1656 .flush_buffer = n_tty_flush_buffer,
1582 .chars_in_buffer = n_tty_chars_in_buffer, 1657 .chars_in_buffer = n_tty_chars_in_buffer,
1583 .read = read_chan, 1658 .read = n_tty_read,
1584 .write = write_chan, 1659 .write = n_tty_write,
1585 .ioctl = n_tty_ioctl, 1660 .ioctl = n_tty_ioctl,
1586 .set_termios = n_tty_set_termios, 1661 .set_termios = n_tty_set_termios,
1587 .poll = normal_poll, 1662 .poll = n_tty_poll,
1588 .receive_buf = n_tty_receive_buf, 1663 .receive_buf = n_tty_receive_buf,
1589 .write_wakeup = n_tty_write_wakeup 1664 .write_wakeup = n_tty_write_wakeup
1590}; 1665};
diff --git a/drivers/char/nozomi.c b/drivers/char/nozomi.c
index 66a0f931c66c..9a34a1935283 100644
--- a/drivers/char/nozomi.c
+++ b/drivers/char/nozomi.c
@@ -1599,7 +1599,10 @@ static int ntty_open(struct tty_struct *tty, struct file *file)
1599 return 0; 1599 return 0;
1600} 1600}
1601 1601
1602/* Called when the userspace process close the tty, /dev/noz*. */ 1602/* Called when the userspace process close the tty, /dev/noz*. Also
1603 called immediately if ntty_open fails in which case tty->driver_data
1604 will be NULL an we exit by the first return */
1605
1603static void ntty_close(struct tty_struct *tty, struct file *file) 1606static void ntty_close(struct tty_struct *tty, struct file *file)
1604{ 1607{
1605 struct nozomi *dc = get_dc_by_tty(tty); 1608 struct nozomi *dc = get_dc_by_tty(tty);
diff --git a/drivers/char/pcmcia/ipwireless/tty.c b/drivers/char/pcmcia/ipwireless/tty.c
index 3a23e7694d55..569f2f7743a7 100644
--- a/drivers/char/pcmcia/ipwireless/tty.c
+++ b/drivers/char/pcmcia/ipwireless/tty.c
@@ -276,6 +276,7 @@ static int ipw_write_room(struct tty_struct *linux_tty)
276 struct ipw_tty *tty = linux_tty->driver_data; 276 struct ipw_tty *tty = linux_tty->driver_data;
277 int room; 277 int room;
278 278
279 /* FIXME: Exactly how is the tty object locked here .. */
279 if (!tty) 280 if (!tty)
280 return -ENODEV; 281 return -ENODEV;
281 282
@@ -397,6 +398,7 @@ static int set_control_lines(struct ipw_tty *tty, unsigned int set,
397static int ipw_tiocmget(struct tty_struct *linux_tty, struct file *file) 398static int ipw_tiocmget(struct tty_struct *linux_tty, struct file *file)
398{ 399{
399 struct ipw_tty *tty = linux_tty->driver_data; 400 struct ipw_tty *tty = linux_tty->driver_data;
401 /* FIXME: Exactly how is the tty object locked here .. */
400 402
401 if (!tty) 403 if (!tty)
402 return -ENODEV; 404 return -ENODEV;
@@ -412,6 +414,7 @@ ipw_tiocmset(struct tty_struct *linux_tty, struct file *file,
412 unsigned int set, unsigned int clear) 414 unsigned int set, unsigned int clear)
413{ 415{
414 struct ipw_tty *tty = linux_tty->driver_data; 416 struct ipw_tty *tty = linux_tty->driver_data;
417 /* FIXME: Exactly how is the tty object locked here .. */
415 418
416 if (!tty) 419 if (!tty)
417 return -ENODEV; 420 return -ENODEV;
@@ -433,6 +436,8 @@ static int ipw_ioctl(struct tty_struct *linux_tty, struct file *file,
433 if (!tty->open_count) 436 if (!tty->open_count)
434 return -EINVAL; 437 return -EINVAL;
435 438
439 /* FIXME: Exactly how is the tty object locked here .. */
440
436 switch (cmd) { 441 switch (cmd) {
437 case TIOCGSERIAL: 442 case TIOCGSERIAL:
438 return ipwireless_get_serial_info(tty, (void __user *) arg); 443 return ipwireless_get_serial_info(tty, (void __user *) arg);
@@ -467,13 +472,6 @@ static int ipw_ioctl(struct tty_struct *linux_tty, struct file *file,
467 } 472 }
468 return 0; 473 return 0;
469 474
470 case TCGETS:
471 case TCGETA:
472 return n_tty_ioctl(linux_tty, file, cmd, arg);
473
474 case TCFLSH:
475 return n_tty_ioctl(linux_tty, file, cmd, arg);
476
477 case FIONREAD: 475 case FIONREAD:
478 { 476 {
479 int val = 0; 477 int val = 0;
@@ -482,10 +480,11 @@ static int ipw_ioctl(struct tty_struct *linux_tty, struct file *file,
482 return -EFAULT; 480 return -EFAULT;
483 } 481 }
484 return 0; 482 return 0;
483 case TCFLSH:
484 return tty_perform_flush(linux_tty, arg);
485 } 485 }
486 } 486 }
487 487 return tty_mode_ioctl(linux_tty, file, cmd , arg);
488 return -ENOIOCTLCMD;
489} 488}
490 489
491static int add_tty(dev_node_t *nodesp, int j, 490static int add_tty(dev_node_t *nodesp, int j,
@@ -588,6 +587,8 @@ void ipwireless_tty_free(struct ipw_tty *tty)
588 tty_hangup(ttyj->linux_tty); 587 tty_hangup(ttyj->linux_tty);
589 /* Wait till the tty_hangup has completed */ 588 /* Wait till the tty_hangup has completed */
590 flush_scheduled_work(); 589 flush_scheduled_work();
590 /* FIXME: Exactly how is the tty object locked here
591 against a parallel ioctl etc */
591 mutex_lock(&ttyj->ipw_tty_mutex); 592 mutex_lock(&ttyj->ipw_tty_mutex);
592 } 593 }
593 while (ttyj->open_count) 594 while (ttyj->open_count)
diff --git a/drivers/char/pty.c b/drivers/char/pty.c
index 76b27932d229..6d4582712b1f 100644
--- a/drivers/char/pty.c
+++ b/drivers/char/pty.c
@@ -8,10 +8,12 @@
8 * Added TTY_DO_WRITE_WAKEUP to enable n_tty to send POLL_OUT to 8 * Added TTY_DO_WRITE_WAKEUP to enable n_tty to send POLL_OUT to
9 * waiting writers -- Sapan Bhatia <sapan@corewars.org> 9 * waiting writers -- Sapan Bhatia <sapan@corewars.org>
10 * 10 *
11 * 11 * When reading this code see also fs/devpts. In particular note that the
12 * driver_data field is used by the devpts side as a binding to the devpts
13 * inode.
12 */ 14 */
13 15
14#include <linux/module.h> /* For EXPORT_SYMBOL */ 16#include <linux/module.h>
15 17
16#include <linux/errno.h> 18#include <linux/errno.h>
17#include <linux/interrupt.h> 19#include <linux/interrupt.h>
@@ -23,26 +25,25 @@
23#include <linux/mm.h> 25#include <linux/mm.h>
24#include <linux/init.h> 26#include <linux/init.h>
25#include <linux/sysctl.h> 27#include <linux/sysctl.h>
26 28#include <linux/device.h>
27#include <asm/uaccess.h> 29#include <linux/uaccess.h>
28#include <asm/system.h>
29#include <linux/bitops.h> 30#include <linux/bitops.h>
30#include <linux/devpts_fs.h> 31#include <linux/devpts_fs.h>
31 32
33#include <asm/system.h>
34
32/* These are global because they are accessed in tty_io.c */ 35/* These are global because they are accessed in tty_io.c */
33#ifdef CONFIG_UNIX98_PTYS 36#ifdef CONFIG_UNIX98_PTYS
34struct tty_driver *ptm_driver; 37struct tty_driver *ptm_driver;
35static struct tty_driver *pts_driver; 38static struct tty_driver *pts_driver;
36#endif 39#endif
37 40
38static void pty_close(struct tty_struct * tty, struct file * filp) 41static void pty_close(struct tty_struct *tty, struct file *filp)
39{ 42{
40 if (!tty) 43 BUG_ON(!tty);
41 return; 44 if (tty->driver->subtype == PTY_TYPE_MASTER)
42 if (tty->driver->subtype == PTY_TYPE_MASTER) { 45 WARN_ON(tty->count > 1);
43 if (tty->count > 1) 46 else {
44 printk("master pty_close: count = %d!!\n", tty->count);
45 } else {
46 if (tty->count > 2) 47 if (tty->count > 2)
47 return; 48 return;
48 } 49 }
@@ -59,7 +60,7 @@ static void pty_close(struct tty_struct * tty, struct file * filp)
59 set_bit(TTY_OTHER_CLOSED, &tty->flags); 60 set_bit(TTY_OTHER_CLOSED, &tty->flags);
60#ifdef CONFIG_UNIX98_PTYS 61#ifdef CONFIG_UNIX98_PTYS
61 if (tty->driver == ptm_driver) 62 if (tty->driver == ptm_driver)
62 devpts_pty_kill(tty->index); 63 devpts_pty_kill(tty->link);
63#endif 64#endif
64 tty_vhangup(tty->link); 65 tty_vhangup(tty->link);
65 } 66 }
@@ -69,13 +70,13 @@ static void pty_close(struct tty_struct * tty, struct file * filp)
69 * The unthrottle routine is called by the line discipline to signal 70 * The unthrottle routine is called by the line discipline to signal
70 * that it can receive more characters. For PTY's, the TTY_THROTTLED 71 * that it can receive more characters. For PTY's, the TTY_THROTTLED
71 * flag is always set, to force the line discipline to always call the 72 * flag is always set, to force the line discipline to always call the
72 * unthrottle routine when there are fewer than TTY_THRESHOLD_UNTHROTTLE 73 * unthrottle routine when there are fewer than TTY_THRESHOLD_UNTHROTTLE
73 * characters in the queue. This is necessary since each time this 74 * characters in the queue. This is necessary since each time this
74 * happens, we need to wake up any sleeping processes that could be 75 * happens, we need to wake up any sleeping processes that could be
75 * (1) trying to send data to the pty, or (2) waiting in wait_until_sent() 76 * (1) trying to send data to the pty, or (2) waiting in wait_until_sent()
76 * for the pty buffer to be drained. 77 * for the pty buffer to be drained.
77 */ 78 */
78static void pty_unthrottle(struct tty_struct * tty) 79static void pty_unthrottle(struct tty_struct *tty)
79{ 80{
80 struct tty_struct *o_tty = tty->link; 81 struct tty_struct *o_tty = tty->link;
81 82
@@ -87,7 +88,7 @@ static void pty_unthrottle(struct tty_struct * tty)
87} 88}
88 89
89/* 90/*
90 * WSH 05/24/97: modified to 91 * WSH 05/24/97: modified to
91 * (1) use space in tty->flip instead of a shared temp buffer 92 * (1) use space in tty->flip instead of a shared temp buffer
92 * The flip buffers aren't being used for a pty, so there's lots 93 * The flip buffers aren't being used for a pty, so there's lots
93 * of space available. The buffer is protected by a per-pty 94 * of space available. The buffer is protected by a per-pty
@@ -100,7 +101,8 @@ static void pty_unthrottle(struct tty_struct * tty)
100 * not our partners. We can't just take the other one blindly without 101 * not our partners. We can't just take the other one blindly without
101 * risking deadlocks. 102 * risking deadlocks.
102 */ 103 */
103static int pty_write(struct tty_struct * tty, const unsigned char *buf, int count) 104static int pty_write(struct tty_struct *tty, const unsigned char *buf,
105 int count)
104{ 106{
105 struct tty_struct *to = tty->link; 107 struct tty_struct *to = tty->link;
106 int c; 108 int c;
@@ -112,7 +114,7 @@ static int pty_write(struct tty_struct * tty, const unsigned char *buf, int coun
112 if (c > count) 114 if (c > count)
113 c = count; 115 c = count;
114 to->ldisc.ops->receive_buf(to, buf, NULL, c); 116 to->ldisc.ops->receive_buf(to, buf, NULL, c);
115 117
116 return c; 118 return c;
117} 119}
118 120
@@ -128,17 +130,17 @@ static int pty_write_room(struct tty_struct *tty)
128 130
129/* 131/*
130 * WSH 05/24/97: Modified for asymmetric MASTER/SLAVE behavior 132 * WSH 05/24/97: Modified for asymmetric MASTER/SLAVE behavior
131 * The chars_in_buffer() value is used by the ldisc select() function 133 * The chars_in_buffer() value is used by the ldisc select() function
132 * to hold off writing when chars_in_buffer > WAKEUP_CHARS (== 256). 134 * to hold off writing when chars_in_buffer > WAKEUP_CHARS (== 256).
133 * The pty driver chars_in_buffer() Master/Slave must behave differently: 135 * The pty driver chars_in_buffer() Master/Slave must behave differently:
134 * 136 *
135 * The Master side needs to allow typed-ahead commands to accumulate 137 * The Master side needs to allow typed-ahead commands to accumulate
136 * while being canonicalized, so we report "our buffer" as empty until 138 * while being canonicalized, so we report "our buffer" as empty until
137 * some threshold is reached, and then report the count. (Any count > 139 * some threshold is reached, and then report the count. (Any count >
138 * WAKEUP_CHARS is regarded by select() as "full".) To avoid deadlock 140 * WAKEUP_CHARS is regarded by select() as "full".) To avoid deadlock
139 * the count returned must be 0 if no canonical data is available to be 141 * the count returned must be 0 if no canonical data is available to be
140 * read. (The N_TTY ldisc.chars_in_buffer now knows this.) 142 * read. (The N_TTY ldisc.chars_in_buffer now knows this.)
141 * 143 *
142 * The Slave side passes all characters in raw mode to the Master side's 144 * The Slave side passes all characters in raw mode to the Master side's
143 * buffer where they can be read immediately, so in this case we can 145 * buffer where they can be read immediately, so in this case we can
144 * return the true count in the buffer. 146 * return the true count in the buffer.
@@ -155,21 +157,22 @@ static int pty_chars_in_buffer(struct tty_struct *tty)
155 /* The ldisc must report 0 if no characters available to be read */ 157 /* The ldisc must report 0 if no characters available to be read */
156 count = to->ldisc.ops->chars_in_buffer(to); 158 count = to->ldisc.ops->chars_in_buffer(to);
157 159
158 if (tty->driver->subtype == PTY_TYPE_SLAVE) return count; 160 if (tty->driver->subtype == PTY_TYPE_SLAVE)
161 return count;
159 162
160 /* Master side driver ... if the other side's read buffer is less than 163 /* Master side driver ... if the other side's read buffer is less than
161 * half full, return 0 to allow writers to proceed; otherwise return 164 * half full, return 0 to allow writers to proceed; otherwise return
162 * the count. This leaves a comfortable margin to avoid overflow, 165 * the count. This leaves a comfortable margin to avoid overflow,
163 * and still allows half a buffer's worth of typed-ahead commands. 166 * and still allows half a buffer's worth of typed-ahead commands.
164 */ 167 */
165 return ((count < N_TTY_BUF_SIZE/2) ? 0 : count); 168 return (count < N_TTY_BUF_SIZE/2) ? 0 : count;
166} 169}
167 170
168/* Set the lock flag on a pty */ 171/* Set the lock flag on a pty */
169static int pty_set_lock(struct tty_struct *tty, int __user * arg) 172static int pty_set_lock(struct tty_struct *tty, int __user *arg)
170{ 173{
171 int val; 174 int val;
172 if (get_user(val,arg)) 175 if (get_user(val, arg))
173 return -EFAULT; 176 return -EFAULT;
174 if (val) 177 if (val)
175 set_bit(TTY_PTY_LOCK, &tty->flags); 178 set_bit(TTY_PTY_LOCK, &tty->flags);
@@ -182,13 +185,13 @@ static void pty_flush_buffer(struct tty_struct *tty)
182{ 185{
183 struct tty_struct *to = tty->link; 186 struct tty_struct *to = tty->link;
184 unsigned long flags; 187 unsigned long flags;
185 188
186 if (!to) 189 if (!to)
187 return; 190 return;
188 191
189 if (to->ldisc.ops->flush_buffer) 192 if (to->ldisc.ops->flush_buffer)
190 to->ldisc.ops->flush_buffer(to); 193 to->ldisc.ops->flush_buffer(to);
191 194
192 if (to->packet) { 195 if (to->packet) {
193 spin_lock_irqsave(&tty->ctrl_lock, flags); 196 spin_lock_irqsave(&tty->ctrl_lock, flags);
194 tty->ctrl_status |= TIOCPKT_FLUSHWRITE; 197 tty->ctrl_status |= TIOCPKT_FLUSHWRITE;
@@ -197,7 +200,7 @@ static void pty_flush_buffer(struct tty_struct *tty)
197 } 200 }
198} 201}
199 202
200static int pty_open(struct tty_struct *tty, struct file * filp) 203static int pty_open(struct tty_struct *tty, struct file *filp)
201{ 204{
202 int retval = -ENODEV; 205 int retval = -ENODEV;
203 206
@@ -220,13 +223,65 @@ out:
220 return retval; 223 return retval;
221} 224}
222 225
223static void pty_set_termios(struct tty_struct *tty, struct ktermios *old_termios) 226static void pty_set_termios(struct tty_struct *tty,
227 struct ktermios *old_termios)
228{
229 tty->termios->c_cflag &= ~(CSIZE | PARENB);
230 tty->termios->c_cflag |= (CS8 | CREAD);
231}
232
233static int pty_install(struct tty_driver *driver, struct tty_struct *tty)
224{ 234{
225 tty->termios->c_cflag &= ~(CSIZE | PARENB); 235 struct tty_struct *o_tty;
226 tty->termios->c_cflag |= (CS8 | CREAD); 236 int idx = tty->index;
237 int retval;
238
239 o_tty = alloc_tty_struct();
240 if (!o_tty)
241 return -ENOMEM;
242 if (!try_module_get(driver->other->owner)) {
243 /* This cannot in fact currently happen */
244 free_tty_struct(o_tty);
245 return -ENOMEM;
246 }
247 initialize_tty_struct(o_tty, driver->other, idx);
248
249 /* We always use new tty termios data so we can do this
250 the easy way .. */
251 retval = tty_init_termios(tty);
252 if (retval)
253 goto free_mem_out;
254
255 retval = tty_init_termios(o_tty);
256 if (retval) {
257 tty_free_termios(tty);
258 goto free_mem_out;
259 }
260
261 /*
262 * Everything allocated ... set up the o_tty structure.
263 */
264 driver->other->ttys[idx] = o_tty;
265 tty_driver_kref_get(driver->other);
266 if (driver->subtype == PTY_TYPE_MASTER)
267 o_tty->count++;
268 /* Establish the links in both directions */
269 tty->link = o_tty;
270 o_tty->link = tty;
271
272 tty_driver_kref_get(driver);
273 tty->count++;
274 driver->ttys[idx] = tty;
275 return 0;
276free_mem_out:
277 module_put(o_tty->driver->owner);
278 free_tty_struct(o_tty);
279 return -ENOMEM;
227} 280}
228 281
282
229static const struct tty_operations pty_ops = { 283static const struct tty_operations pty_ops = {
284 .install = pty_install,
230 .open = pty_open, 285 .open = pty_open,
231 .close = pty_close, 286 .close = pty_close,
232 .write = pty_write, 287 .write = pty_write,
@@ -329,8 +384,11 @@ static inline void legacy_pty_init(void) { }
329 * Otherwise one can eat up all kernel memory by opening /dev/ptmx repeatedly. 384 * Otherwise one can eat up all kernel memory by opening /dev/ptmx repeatedly.
330 */ 385 */
331int pty_limit = NR_UNIX98_PTY_DEFAULT; 386int pty_limit = NR_UNIX98_PTY_DEFAULT;
332static int pty_limit_min = 0; 387static int pty_limit_min;
333static int pty_limit_max = NR_UNIX98_PTY_MAX; 388static int pty_limit_max = NR_UNIX98_PTY_MAX;
389static int pty_count;
390
391static struct cdev ptmx_cdev;
334 392
335static struct ctl_table pty_table[] = { 393static struct ctl_table pty_table[] = {
336 { 394 {
@@ -348,6 +406,7 @@ static struct ctl_table pty_table[] = {
348 .procname = "nr", 406 .procname = "nr",
349 .maxlen = sizeof(int), 407 .maxlen = sizeof(int),
350 .mode = 0444, 408 .mode = 0444,
409 .data = &pty_count,
351 .proc_handler = &proc_dointvec, 410 .proc_handler = &proc_dointvec,
352 }, { 411 }, {
353 .ctl_name = 0 412 .ctl_name = 0
@@ -388,7 +447,127 @@ static int pty_unix98_ioctl(struct tty_struct *tty, struct file *file,
388 return -ENOIOCTLCMD; 447 return -ENOIOCTLCMD;
389} 448}
390 449
450/**
451 * ptm_unix98_lookup - find a pty master
452 * @driver: ptm driver
453 * @idx: tty index
454 *
455 * Look up a pty master device. Called under the tty_mutex for now.
456 * This provides our locking.
457 */
458
459static struct tty_struct *ptm_unix98_lookup(struct tty_driver *driver,
460 struct inode *ptm_inode, int idx)
461{
462 struct tty_struct *tty = devpts_get_tty(ptm_inode, idx);
463 if (tty)
464 tty = tty->link;
465 return tty;
466}
467
468/**
469 * pts_unix98_lookup - find a pty slave
470 * @driver: pts driver
471 * @idx: tty index
472 *
473 * Look up a pty master device. Called under the tty_mutex for now.
474 * This provides our locking.
475 */
476
477static struct tty_struct *pts_unix98_lookup(struct tty_driver *driver,
478 struct inode *pts_inode, int idx)
479{
480 struct tty_struct *tty = devpts_get_tty(pts_inode, idx);
481 /* Master must be open before slave */
482 if (!tty)
483 return ERR_PTR(-EIO);
484 return tty;
485}
486
487static void pty_unix98_shutdown(struct tty_struct *tty)
488{
489 /* We have our own method as we don't use the tty index */
490 kfree(tty->termios);
491}
492
493/* We have no need to install and remove our tty objects as devpts does all
494 the work for us */
495
496static int pty_unix98_install(struct tty_driver *driver, struct tty_struct *tty)
497{
498 struct tty_struct *o_tty;
499 int idx = tty->index;
500
501 o_tty = alloc_tty_struct();
502 if (!o_tty)
503 return -ENOMEM;
504 if (!try_module_get(driver->other->owner)) {
505 /* This cannot in fact currently happen */
506 free_tty_struct(o_tty);
507 return -ENOMEM;
508 }
509 initialize_tty_struct(o_tty, driver->other, idx);
510
511 tty->termios = kzalloc(sizeof(struct ktermios[2]), GFP_KERNEL);
512 if (tty->termios == NULL)
513 goto free_mem_out;
514 *tty->termios = driver->init_termios;
515 tty->termios_locked = tty->termios + 1;
516
517 o_tty->termios = kzalloc(sizeof(struct ktermios[2]), GFP_KERNEL);
518 if (o_tty->termios == NULL)
519 goto free_mem_out;
520 *o_tty->termios = driver->other->init_termios;
521 o_tty->termios_locked = o_tty->termios + 1;
522
523 tty_driver_kref_get(driver->other);
524 if (driver->subtype == PTY_TYPE_MASTER)
525 o_tty->count++;
526 /* Establish the links in both directions */
527 tty->link = o_tty;
528 o_tty->link = tty;
529 /*
530 * All structures have been allocated, so now we install them.
531 * Failures after this point use release_tty to clean up, so
532 * there's no need to null out the local pointers.
533 */
534 tty_driver_kref_get(driver);
535 tty->count++;
536 pty_count++;
537 return 0;
538free_mem_out:
539 kfree(o_tty->termios);
540 module_put(o_tty->driver->owner);
541 free_tty_struct(o_tty);
542 kfree(tty->termios);
543 return -ENOMEM;
544}
545
546static void pty_unix98_remove(struct tty_driver *driver, struct tty_struct *tty)
547{
548 pty_count--;
549}
550
551static const struct tty_operations ptm_unix98_ops = {
552 .lookup = ptm_unix98_lookup,
553 .install = pty_unix98_install,
554 .remove = pty_unix98_remove,
555 .open = pty_open,
556 .close = pty_close,
557 .write = pty_write,
558 .write_room = pty_write_room,
559 .flush_buffer = pty_flush_buffer,
560 .chars_in_buffer = pty_chars_in_buffer,
561 .unthrottle = pty_unthrottle,
562 .set_termios = pty_set_termios,
563 .ioctl = pty_unix98_ioctl,
564 .shutdown = pty_unix98_shutdown
565};
566
391static const struct tty_operations pty_unix98_ops = { 567static const struct tty_operations pty_unix98_ops = {
568 .lookup = pts_unix98_lookup,
569 .install = pty_unix98_install,
570 .remove = pty_unix98_remove,
392 .open = pty_open, 571 .open = pty_open,
393 .close = pty_close, 572 .close = pty_close,
394 .write = pty_write, 573 .write = pty_write,
@@ -397,9 +576,73 @@ static const struct tty_operations pty_unix98_ops = {
397 .chars_in_buffer = pty_chars_in_buffer, 576 .chars_in_buffer = pty_chars_in_buffer,
398 .unthrottle = pty_unthrottle, 577 .unthrottle = pty_unthrottle,
399 .set_termios = pty_set_termios, 578 .set_termios = pty_set_termios,
400 .ioctl = pty_unix98_ioctl 579 .shutdown = pty_unix98_shutdown
401}; 580};
402 581
582/**
583 * ptmx_open - open a unix 98 pty master
584 * @inode: inode of device file
585 * @filp: file pointer to tty
586 *
587 * Allocate a unix98 pty master device from the ptmx driver.
588 *
589 * Locking: tty_mutex protects the init_dev work. tty->count should
590 * protect the rest.
591 * allocated_ptys_lock handles the list of free pty numbers
592 */
593
594static int __ptmx_open(struct inode *inode, struct file *filp)
595{
596 struct tty_struct *tty;
597 int retval;
598 int index;
599
600 nonseekable_open(inode, filp);
601
602 /* find a device that is not in use. */
603 index = devpts_new_index(inode);
604 if (index < 0)
605 return index;
606
607 mutex_lock(&tty_mutex);
608 tty = tty_init_dev(ptm_driver, index, 1);
609 mutex_unlock(&tty_mutex);
610
611 if (IS_ERR(tty)) {
612 retval = PTR_ERR(tty);
613 goto out;
614 }
615
616 set_bit(TTY_PTY_LOCK, &tty->flags); /* LOCK THE SLAVE */
617 filp->private_data = tty;
618 file_move(filp, &tty->tty_files);
619
620 retval = devpts_pty_new(inode, tty->link);
621 if (retval)
622 goto out1;
623
624 retval = ptm_driver->ops->open(tty, filp);
625 if (!retval)
626 return 0;
627out1:
628 tty_release_dev(filp);
629 return retval;
630out:
631 devpts_kill_index(inode, index);
632 return retval;
633}
634
635static int ptmx_open(struct inode *inode, struct file *filp)
636{
637 int ret;
638
639 lock_kernel();
640 ret = __ptmx_open(inode, filp);
641 unlock_kernel();
642 return ret;
643}
644
645static struct file_operations ptmx_fops;
403 646
404static void __init unix98_pty_init(void) 647static void __init unix98_pty_init(void)
405{ 648{
@@ -427,7 +670,7 @@ static void __init unix98_pty_init(void)
427 ptm_driver->flags = TTY_DRIVER_RESET_TERMIOS | TTY_DRIVER_REAL_RAW | 670 ptm_driver->flags = TTY_DRIVER_RESET_TERMIOS | TTY_DRIVER_REAL_RAW |
428 TTY_DRIVER_DYNAMIC_DEV | TTY_DRIVER_DEVPTS_MEM; 671 TTY_DRIVER_DYNAMIC_DEV | TTY_DRIVER_DEVPTS_MEM;
429 ptm_driver->other = pts_driver; 672 ptm_driver->other = pts_driver;
430 tty_set_operations(ptm_driver, &pty_unix98_ops); 673 tty_set_operations(ptm_driver, &ptm_unix98_ops);
431 674
432 pts_driver->owner = THIS_MODULE; 675 pts_driver->owner = THIS_MODULE;
433 pts_driver->driver_name = "pty_slave"; 676 pts_driver->driver_name = "pty_slave";
@@ -443,16 +686,26 @@ static void __init unix98_pty_init(void)
443 pts_driver->flags = TTY_DRIVER_RESET_TERMIOS | TTY_DRIVER_REAL_RAW | 686 pts_driver->flags = TTY_DRIVER_RESET_TERMIOS | TTY_DRIVER_REAL_RAW |
444 TTY_DRIVER_DYNAMIC_DEV | TTY_DRIVER_DEVPTS_MEM; 687 TTY_DRIVER_DYNAMIC_DEV | TTY_DRIVER_DEVPTS_MEM;
445 pts_driver->other = ptm_driver; 688 pts_driver->other = ptm_driver;
446 tty_set_operations(pts_driver, &pty_ops); 689 tty_set_operations(pts_driver, &pty_unix98_ops);
447 690
448 if (tty_register_driver(ptm_driver)) 691 if (tty_register_driver(ptm_driver))
449 panic("Couldn't register Unix98 ptm driver"); 692 panic("Couldn't register Unix98 ptm driver");
450 if (tty_register_driver(pts_driver)) 693 if (tty_register_driver(pts_driver))
451 panic("Couldn't register Unix98 pts driver"); 694 panic("Couldn't register Unix98 pts driver");
452 695
453 pty_table[1].data = &ptm_driver->refcount;
454 register_sysctl_table(pty_root_table); 696 register_sysctl_table(pty_root_table);
697
698 /* Now create the /dev/ptmx special device */
699 tty_default_fops(&ptmx_fops);
700 ptmx_fops.open = ptmx_open;
701
702 cdev_init(&ptmx_cdev, &ptmx_fops);
703 if (cdev_add(&ptmx_cdev, MKDEV(TTYAUX_MAJOR, 2), 1) ||
704 register_chrdev_region(MKDEV(TTYAUX_MAJOR, 2), 1, "/dev/ptmx") < 0)
705 panic("Couldn't register /dev/ptmx driver\n");
706 device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 2), NULL, "ptmx");
455} 707}
708
456#else 709#else
457static inline void unix98_pty_init(void) { } 710static inline void unix98_pty_init(void) { }
458#endif 711#endif
diff --git a/drivers/char/stallion.c b/drivers/char/stallion.c
index 19db1eb87c26..8b8f07a7f505 100644
--- a/drivers/char/stallion.c
+++ b/drivers/char/stallion.c
@@ -405,9 +405,9 @@ static unsigned int stl_baudrates[] = {
405 405
406static int stl_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, unsigned long arg); 406static int stl_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, unsigned long arg);
407static int stl_brdinit(struct stlbrd *brdp); 407static int stl_brdinit(struct stlbrd *brdp);
408static int stl_getportstats(struct stlport *portp, comstats_t __user *cp); 408static int stl_getportstats(struct tty_struct *tty, struct stlport *portp, comstats_t __user *cp);
409static int stl_clrportstats(struct stlport *portp, comstats_t __user *cp); 409static int stl_clrportstats(struct stlport *portp, comstats_t __user *cp);
410static int stl_waitcarrier(struct stlport *portp, struct file *filp); 410static int stl_waitcarrier(struct tty_struct *tty, struct stlport *portp, struct file *filp);
411 411
412/* 412/*
413 * CD1400 uart specific handling functions. 413 * CD1400 uart specific handling functions.
@@ -612,8 +612,9 @@ static struct class *stallion_class;
612static void stl_cd_change(struct stlport *portp) 612static void stl_cd_change(struct stlport *portp)
613{ 613{
614 unsigned int oldsigs = portp->sigs; 614 unsigned int oldsigs = portp->sigs;
615 struct tty_struct *tty = tty_port_tty_get(&portp->port);
615 616
616 if (!portp->port.tty) 617 if (!tty)
617 return; 618 return;
618 619
619 portp->sigs = stl_getsignals(portp); 620 portp->sigs = stl_getsignals(portp);
@@ -623,7 +624,8 @@ static void stl_cd_change(struct stlport *portp)
623 624
624 if ((oldsigs & TIOCM_CD) && ((portp->sigs & TIOCM_CD) == 0)) 625 if ((oldsigs & TIOCM_CD) && ((portp->sigs & TIOCM_CD) == 0))
625 if (portp->port.flags & ASYNC_CHECK_CD) 626 if (portp->port.flags & ASYNC_CHECK_CD)
626 tty_hangup(portp->port.tty); 627 tty_hangup(tty);
628 tty_kref_put(tty);
627} 629}
628 630
629/* 631/*
@@ -734,7 +736,7 @@ static int stl_open(struct tty_struct *tty, struct file *filp)
734 * On the first open of the device setup the port hardware, and 736 * On the first open of the device setup the port hardware, and
735 * initialize the per port data structure. 737 * initialize the per port data structure.
736 */ 738 */
737 portp->port.tty = tty; 739 tty_port_tty_set(&portp->port, tty);
738 tty->driver_data = portp; 740 tty->driver_data = portp;
739 portp->port.count++; 741 portp->port.count++;
740 742
@@ -774,7 +776,7 @@ static int stl_open(struct tty_struct *tty, struct file *filp)
774 * then also we might have to wait for carrier. 776 * then also we might have to wait for carrier.
775 */ 777 */
776 if (!(filp->f_flags & O_NONBLOCK)) 778 if (!(filp->f_flags & O_NONBLOCK))
777 if ((rc = stl_waitcarrier(portp, filp)) != 0) 779 if ((rc = stl_waitcarrier(tty, portp, filp)) != 0)
778 return rc; 780 return rc;
779 781
780 portp->port.flags |= ASYNC_NORMAL_ACTIVE; 782 portp->port.flags |= ASYNC_NORMAL_ACTIVE;
@@ -789,7 +791,8 @@ static int stl_open(struct tty_struct *tty, struct file *filp)
789 * maybe because if we are clocal then we don't need to wait... 791 * maybe because if we are clocal then we don't need to wait...
790 */ 792 */
791 793
792static int stl_waitcarrier(struct stlport *portp, struct file *filp) 794static int stl_waitcarrier(struct tty_struct *tty, struct stlport *portp,
795 struct file *filp)
793{ 796{
794 unsigned long flags; 797 unsigned long flags;
795 int rc, doclocal; 798 int rc, doclocal;
@@ -801,7 +804,7 @@ static int stl_waitcarrier(struct stlport *portp, struct file *filp)
801 804
802 spin_lock_irqsave(&stallion_lock, flags); 805 spin_lock_irqsave(&stallion_lock, flags);
803 806
804 if (portp->port.tty->termios->c_cflag & CLOCAL) 807 if (tty->termios->c_cflag & CLOCAL)
805 doclocal++; 808 doclocal++;
806 809
807 portp->openwaitcnt++; 810 portp->openwaitcnt++;
@@ -846,8 +849,6 @@ static void stl_flushbuffer(struct tty_struct *tty)
846 849
847 pr_debug("stl_flushbuffer(tty=%p)\n", tty); 850 pr_debug("stl_flushbuffer(tty=%p)\n", tty);
848 851
849 if (tty == NULL)
850 return;
851 portp = tty->driver_data; 852 portp = tty->driver_data;
852 if (portp == NULL) 853 if (portp == NULL)
853 return; 854 return;
@@ -865,8 +866,6 @@ static void stl_waituntilsent(struct tty_struct *tty, int timeout)
865 866
866 pr_debug("stl_waituntilsent(tty=%p,timeout=%d)\n", tty, timeout); 867 pr_debug("stl_waituntilsent(tty=%p,timeout=%d)\n", tty, timeout);
867 868
868 if (tty == NULL)
869 return;
870 portp = tty->driver_data; 869 portp = tty->driver_data;
871 if (portp == NULL) 870 if (portp == NULL)
872 return; 871 return;
@@ -949,7 +948,7 @@ static void stl_close(struct tty_struct *tty, struct file *filp)
949 tty_ldisc_flush(tty); 948 tty_ldisc_flush(tty);
950 949
951 tty->closing = 0; 950 tty->closing = 0;
952 portp->port.tty = NULL; 951 tty_port_tty_set(&portp->port, NULL);
953 952
954 if (portp->openwaitcnt) { 953 if (portp->openwaitcnt) {
955 if (portp->close_delay) 954 if (portp->close_delay)
@@ -1033,8 +1032,6 @@ static int stl_putchar(struct tty_struct *tty, unsigned char ch)
1033 1032
1034 pr_debug("stl_putchar(tty=%p,ch=%x)\n", tty, ch); 1033 pr_debug("stl_putchar(tty=%p,ch=%x)\n", tty, ch);
1035 1034
1036 if (tty == NULL)
1037 return -EINVAL;
1038 portp = tty->driver_data; 1035 portp = tty->driver_data;
1039 if (portp == NULL) 1036 if (portp == NULL)
1040 return -EINVAL; 1037 return -EINVAL;
@@ -1070,8 +1067,6 @@ static void stl_flushchars(struct tty_struct *tty)
1070 1067
1071 pr_debug("stl_flushchars(tty=%p)\n", tty); 1068 pr_debug("stl_flushchars(tty=%p)\n", tty);
1072 1069
1073 if (tty == NULL)
1074 return;
1075 portp = tty->driver_data; 1070 portp = tty->driver_data;
1076 if (portp == NULL) 1071 if (portp == NULL)
1077 return; 1072 return;
@@ -1090,8 +1085,6 @@ static int stl_writeroom(struct tty_struct *tty)
1090 1085
1091 pr_debug("stl_writeroom(tty=%p)\n", tty); 1086 pr_debug("stl_writeroom(tty=%p)\n", tty);
1092 1087
1093 if (tty == NULL)
1094 return 0;
1095 portp = tty->driver_data; 1088 portp = tty->driver_data;
1096 if (portp == NULL) 1089 if (portp == NULL)
1097 return 0; 1090 return 0;
@@ -1122,8 +1115,6 @@ static int stl_charsinbuffer(struct tty_struct *tty)
1122 1115
1123 pr_debug("stl_charsinbuffer(tty=%p)\n", tty); 1116 pr_debug("stl_charsinbuffer(tty=%p)\n", tty);
1124 1117
1125 if (tty == NULL)
1126 return 0;
1127 portp = tty->driver_data; 1118 portp = tty->driver_data;
1128 if (portp == NULL) 1119 if (portp == NULL)
1129 return 0; 1120 return 0;
@@ -1183,8 +1174,9 @@ static int stl_getserial(struct stlport *portp, struct serial_struct __user *sp)
1183 * just quietly ignore any requests to change irq, etc. 1174 * just quietly ignore any requests to change irq, etc.
1184 */ 1175 */
1185 1176
1186static int stl_setserial(struct stlport *portp, struct serial_struct __user *sp) 1177static int stl_setserial(struct tty_struct *tty, struct serial_struct __user *sp)
1187{ 1178{
1179 struct stlport * portp = tty->driver_data;
1188 struct serial_struct sio; 1180 struct serial_struct sio;
1189 1181
1190 pr_debug("stl_setserial(portp=%p,sp=%p)\n", portp, sp); 1182 pr_debug("stl_setserial(portp=%p,sp=%p)\n", portp, sp);
@@ -1205,7 +1197,7 @@ static int stl_setserial(struct stlport *portp, struct serial_struct __user *sp)
1205 portp->close_delay = sio.close_delay; 1197 portp->close_delay = sio.close_delay;
1206 portp->closing_wait = sio.closing_wait; 1198 portp->closing_wait = sio.closing_wait;
1207 portp->custom_divisor = sio.custom_divisor; 1199 portp->custom_divisor = sio.custom_divisor;
1208 stl_setport(portp, portp->port.tty->termios); 1200 stl_setport(portp, tty->termios);
1209 return 0; 1201 return 0;
1210} 1202}
1211 1203
@@ -1215,8 +1207,6 @@ static int stl_tiocmget(struct tty_struct *tty, struct file *file)
1215{ 1207{
1216 struct stlport *portp; 1208 struct stlport *portp;
1217 1209
1218 if (tty == NULL)
1219 return -ENODEV;
1220 portp = tty->driver_data; 1210 portp = tty->driver_data;
1221 if (portp == NULL) 1211 if (portp == NULL)
1222 return -ENODEV; 1212 return -ENODEV;
@@ -1232,8 +1222,6 @@ static int stl_tiocmset(struct tty_struct *tty, struct file *file,
1232 struct stlport *portp; 1222 struct stlport *portp;
1233 int rts = -1, dtr = -1; 1223 int rts = -1, dtr = -1;
1234 1224
1235 if (tty == NULL)
1236 return -ENODEV;
1237 portp = tty->driver_data; 1225 portp = tty->driver_data;
1238 if (portp == NULL) 1226 if (portp == NULL)
1239 return -ENODEV; 1227 return -ENODEV;
@@ -1262,8 +1250,6 @@ static int stl_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd
1262 pr_debug("stl_ioctl(tty=%p,file=%p,cmd=%x,arg=%lx)\n", tty, file, cmd, 1250 pr_debug("stl_ioctl(tty=%p,file=%p,cmd=%x,arg=%lx)\n", tty, file, cmd,
1263 arg); 1251 arg);
1264 1252
1265 if (tty == NULL)
1266 return -ENODEV;
1267 portp = tty->driver_data; 1253 portp = tty->driver_data;
1268 if (portp == NULL) 1254 if (portp == NULL)
1269 return -ENODEV; 1255 return -ENODEV;
@@ -1282,10 +1268,10 @@ static int stl_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd
1282 rc = stl_getserial(portp, argp); 1268 rc = stl_getserial(portp, argp);
1283 break; 1269 break;
1284 case TIOCSSERIAL: 1270 case TIOCSSERIAL:
1285 rc = stl_setserial(portp, argp); 1271 rc = stl_setserial(tty, argp);
1286 break; 1272 break;
1287 case COM_GETPORTSTATS: 1273 case COM_GETPORTSTATS:
1288 rc = stl_getportstats(portp, argp); 1274 rc = stl_getportstats(tty, portp, argp);
1289 break; 1275 break;
1290 case COM_CLRPORTSTATS: 1276 case COM_CLRPORTSTATS:
1291 rc = stl_clrportstats(portp, argp); 1277 rc = stl_clrportstats(portp, argp);
@@ -1317,8 +1303,6 @@ static void stl_start(struct tty_struct *tty)
1317 1303
1318 pr_debug("stl_start(tty=%p)\n", tty); 1304 pr_debug("stl_start(tty=%p)\n", tty);
1319 1305
1320 if (tty == NULL)
1321 return;
1322 portp = tty->driver_data; 1306 portp = tty->driver_data;
1323 if (portp == NULL) 1307 if (portp == NULL)
1324 return; 1308 return;
@@ -1334,8 +1318,6 @@ static void stl_settermios(struct tty_struct *tty, struct ktermios *old)
1334 1318
1335 pr_debug("stl_settermios(tty=%p,old=%p)\n", tty, old); 1319 pr_debug("stl_settermios(tty=%p,old=%p)\n", tty, old);
1336 1320
1337 if (tty == NULL)
1338 return;
1339 portp = tty->driver_data; 1321 portp = tty->driver_data;
1340 if (portp == NULL) 1322 if (portp == NULL)
1341 return; 1323 return;
@@ -1369,8 +1351,6 @@ static void stl_throttle(struct tty_struct *tty)
1369 1351
1370 pr_debug("stl_throttle(tty=%p)\n", tty); 1352 pr_debug("stl_throttle(tty=%p)\n", tty);
1371 1353
1372 if (tty == NULL)
1373 return;
1374 portp = tty->driver_data; 1354 portp = tty->driver_data;
1375 if (portp == NULL) 1355 if (portp == NULL)
1376 return; 1356 return;
@@ -1389,8 +1369,6 @@ static void stl_unthrottle(struct tty_struct *tty)
1389 1369
1390 pr_debug("stl_unthrottle(tty=%p)\n", tty); 1370 pr_debug("stl_unthrottle(tty=%p)\n", tty);
1391 1371
1392 if (tty == NULL)
1393 return;
1394 portp = tty->driver_data; 1372 portp = tty->driver_data;
1395 if (portp == NULL) 1373 if (portp == NULL)
1396 return; 1374 return;
@@ -1410,8 +1388,6 @@ static void stl_stop(struct tty_struct *tty)
1410 1388
1411 pr_debug("stl_stop(tty=%p)\n", tty); 1389 pr_debug("stl_stop(tty=%p)\n", tty);
1412 1390
1413 if (tty == NULL)
1414 return;
1415 portp = tty->driver_data; 1391 portp = tty->driver_data;
1416 if (portp == NULL) 1392 if (portp == NULL)
1417 return; 1393 return;
@@ -1432,8 +1408,6 @@ static void stl_hangup(struct tty_struct *tty)
1432 1408
1433 pr_debug("stl_hangup(tty=%p)\n", tty); 1409 pr_debug("stl_hangup(tty=%p)\n", tty);
1434 1410
1435 if (tty == NULL)
1436 return;
1437 portp = tty->driver_data; 1411 portp = tty->driver_data;
1438 if (portp == NULL) 1412 if (portp == NULL)
1439 return; 1413 return;
@@ -1452,7 +1426,7 @@ static void stl_hangup(struct tty_struct *tty)
1452 portp->tx.head = NULL; 1426 portp->tx.head = NULL;
1453 portp->tx.tail = NULL; 1427 portp->tx.tail = NULL;
1454 } 1428 }
1455 portp->port.tty = NULL; 1429 tty_port_tty_set(&portp->port, NULL);
1456 portp->port.flags &= ~ASYNC_NORMAL_ACTIVE; 1430 portp->port.flags &= ~ASYNC_NORMAL_ACTIVE;
1457 portp->port.count = 0; 1431 portp->port.count = 0;
1458 wake_up_interruptible(&portp->port.open_wait); 1432 wake_up_interruptible(&portp->port.open_wait);
@@ -1466,8 +1440,6 @@ static int stl_breakctl(struct tty_struct *tty, int state)
1466 1440
1467 pr_debug("stl_breakctl(tty=%p,state=%d)\n", tty, state); 1441 pr_debug("stl_breakctl(tty=%p,state=%d)\n", tty, state);
1468 1442
1469 if (tty == NULL)
1470 return -EINVAL;
1471 portp = tty->driver_data; 1443 portp = tty->driver_data;
1472 if (portp == NULL) 1444 if (portp == NULL)
1473 return -EINVAL; 1445 return -EINVAL;
@@ -1484,8 +1456,6 @@ static void stl_sendxchar(struct tty_struct *tty, char ch)
1484 1456
1485 pr_debug("stl_sendxchar(tty=%p,ch=%x)\n", tty, ch); 1457 pr_debug("stl_sendxchar(tty=%p,ch=%x)\n", tty, ch);
1486 1458
1487 if (tty == NULL)
1488 return;
1489 portp = tty->driver_data; 1459 portp = tty->driver_data;
1490 if (portp == NULL) 1460 if (portp == NULL)
1491 return; 1461 return;
@@ -1805,7 +1775,7 @@ static int __devinit stl_initports(struct stlbrd *brdp, struct stlpanel *panelp)
1805 "(size=%Zd)\n", sizeof(struct stlport)); 1775 "(size=%Zd)\n", sizeof(struct stlport));
1806 break; 1776 break;
1807 } 1777 }
1808 1778 tty_port_init(&portp->port);
1809 portp->magic = STL_PORTMAGIC; 1779 portp->magic = STL_PORTMAGIC;
1810 portp->portnr = i; 1780 portp->portnr = i;
1811 portp->brdnr = panelp->brdnr; 1781 portp->brdnr = panelp->brdnr;
@@ -1832,6 +1802,7 @@ static void stl_cleanup_panels(struct stlbrd *brdp)
1832 struct stlpanel *panelp; 1802 struct stlpanel *panelp;
1833 struct stlport *portp; 1803 struct stlport *portp;
1834 unsigned int j, k; 1804 unsigned int j, k;
1805 struct tty_struct *tty;
1835 1806
1836 for (j = 0; j < STL_MAXPANELS; j++) { 1807 for (j = 0; j < STL_MAXPANELS; j++) {
1837 panelp = brdp->panels[j]; 1808 panelp = brdp->panels[j];
@@ -1841,8 +1812,11 @@ static void stl_cleanup_panels(struct stlbrd *brdp)
1841 portp = panelp->ports[k]; 1812 portp = panelp->ports[k];
1842 if (portp == NULL) 1813 if (portp == NULL)
1843 continue; 1814 continue;
1844 if (portp->port.tty != NULL) 1815 tty = tty_port_tty_get(&portp->port);
1845 stl_hangup(portp->port.tty); 1816 if (tty != NULL) {
1817 stl_hangup(tty);
1818 tty_kref_put(tty);
1819 }
1846 kfree(portp->tx.buf); 1820 kfree(portp->tx.buf);
1847 kfree(portp); 1821 kfree(portp);
1848 } 1822 }
@@ -2498,7 +2472,7 @@ static struct stlport *stl_getport(int brdnr, int panelnr, int portnr)
2498 * what port to get stats for (used through board control device). 2472 * what port to get stats for (used through board control device).
2499 */ 2473 */
2500 2474
2501static int stl_getportstats(struct stlport *portp, comstats_t __user *cp) 2475static int stl_getportstats(struct tty_struct *tty, struct stlport *portp, comstats_t __user *cp)
2502{ 2476{
2503 comstats_t stl_comstats; 2477 comstats_t stl_comstats;
2504 unsigned char *head, *tail; 2478 unsigned char *head, *tail;
@@ -2525,18 +2499,17 @@ static int stl_getportstats(struct stlport *portp, comstats_t __user *cp)
2525 portp->stats.rxbuffered = 0; 2499 portp->stats.rxbuffered = 0;
2526 2500
2527 spin_lock_irqsave(&stallion_lock, flags); 2501 spin_lock_irqsave(&stallion_lock, flags);
2528 if (portp->port.tty != NULL) 2502 if (tty != NULL && portp->port.tty == tty) {
2529 if (portp->port.tty->driver_data == portp) { 2503 portp->stats.ttystate = tty->flags;
2530 portp->stats.ttystate = portp->port.tty->flags; 2504 /* No longer available as a statistic */
2531 /* No longer available as a statistic */ 2505 portp->stats.rxbuffered = 1; /*tty->flip.count; */
2532 portp->stats.rxbuffered = 1; /*portp->port.tty->flip.count; */ 2506 if (tty->termios != NULL) {
2533 if (portp->port.tty->termios != NULL) { 2507 portp->stats.cflags = tty->termios->c_cflag;
2534 portp->stats.cflags = portp->port.tty->termios->c_cflag; 2508 portp->stats.iflags = tty->termios->c_iflag;
2535 portp->stats.iflags = portp->port.tty->termios->c_iflag; 2509 portp->stats.oflags = tty->termios->c_oflag;
2536 portp->stats.oflags = portp->port.tty->termios->c_oflag; 2510 portp->stats.lflags = tty->termios->c_lflag;
2537 portp->stats.lflags = portp->port.tty->termios->c_lflag;
2538 }
2539 } 2511 }
2512 }
2540 spin_unlock_irqrestore(&stallion_lock, flags); 2513 spin_unlock_irqrestore(&stallion_lock, flags);
2541 2514
2542 head = portp->tx.head; 2515 head = portp->tx.head;
@@ -2640,7 +2613,7 @@ static int stl_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, uns
2640 2613
2641 switch (cmd) { 2614 switch (cmd) {
2642 case COM_GETPORTSTATS: 2615 case COM_GETPORTSTATS:
2643 rc = stl_getportstats(NULL, argp); 2616 rc = stl_getportstats(NULL, NULL, argp);
2644 break; 2617 break;
2645 case COM_CLRPORTSTATS: 2618 case COM_CLRPORTSTATS:
2646 rc = stl_clrportstats(NULL, argp); 2619 rc = stl_clrportstats(NULL, argp);
@@ -3243,7 +3216,7 @@ static void stl_cd1400flowctrl(struct stlport *portp, int state)
3243 3216
3244 if (portp == NULL) 3217 if (portp == NULL)
3245 return; 3218 return;
3246 tty = portp->port.tty; 3219 tty = tty_port_tty_get(&portp->port);
3247 if (tty == NULL) 3220 if (tty == NULL)
3248 return; 3221 return;
3249 3222
@@ -3288,6 +3261,7 @@ static void stl_cd1400flowctrl(struct stlport *portp, int state)
3288 3261
3289 BRDDISABLE(portp->brdnr); 3262 BRDDISABLE(portp->brdnr);
3290 spin_unlock_irqrestore(&brd_lock, flags); 3263 spin_unlock_irqrestore(&brd_lock, flags);
3264 tty_kref_put(tty);
3291} 3265}
3292 3266
3293/*****************************************************************************/ 3267/*****************************************************************************/
@@ -3305,7 +3279,7 @@ static void stl_cd1400sendflow(struct stlport *portp, int state)
3305 3279
3306 if (portp == NULL) 3280 if (portp == NULL)
3307 return; 3281 return;
3308 tty = portp->port.tty; 3282 tty = tty_port_tty_get(&portp->port);
3309 if (tty == NULL) 3283 if (tty == NULL)
3310 return; 3284 return;
3311 3285
@@ -3325,6 +3299,7 @@ static void stl_cd1400sendflow(struct stlport *portp, int state)
3325 } 3299 }
3326 BRDDISABLE(portp->brdnr); 3300 BRDDISABLE(portp->brdnr);
3327 spin_unlock_irqrestore(&brd_lock, flags); 3301 spin_unlock_irqrestore(&brd_lock, flags);
3302 tty_kref_put(tty);
3328} 3303}
3329 3304
3330/*****************************************************************************/ 3305/*****************************************************************************/
@@ -3478,6 +3453,7 @@ static void stl_cd1400txisr(struct stlpanel *panelp, int ioaddr)
3478 int len, stlen; 3453 int len, stlen;
3479 char *head, *tail; 3454 char *head, *tail;
3480 unsigned char ioack, srer; 3455 unsigned char ioack, srer;
3456 struct tty_struct *tty;
3481 3457
3482 pr_debug("stl_cd1400txisr(panelp=%p,ioaddr=%x)\n", panelp, ioaddr); 3458 pr_debug("stl_cd1400txisr(panelp=%p,ioaddr=%x)\n", panelp, ioaddr);
3483 3459
@@ -3504,8 +3480,11 @@ static void stl_cd1400txisr(struct stlpanel *panelp, int ioaddr)
3504 if ((len == 0) || ((len < STL_TXBUFLOW) && 3480 if ((len == 0) || ((len < STL_TXBUFLOW) &&
3505 (test_bit(ASYI_TXLOW, &portp->istate) == 0))) { 3481 (test_bit(ASYI_TXLOW, &portp->istate) == 0))) {
3506 set_bit(ASYI_TXLOW, &portp->istate); 3482 set_bit(ASYI_TXLOW, &portp->istate);
3507 if (portp->port.tty) 3483 tty = tty_port_tty_get(&portp->port);
3508 tty_wakeup(portp->port.tty); 3484 if (tty) {
3485 tty_wakeup(tty);
3486 tty_kref_put(tty);
3487 }
3509 } 3488 }
3510 3489
3511 if (len == 0) { 3490 if (len == 0) {
@@ -3569,7 +3548,7 @@ static void stl_cd1400rxisr(struct stlpanel *panelp, int ioaddr)
3569 return; 3548 return;
3570 } 3549 }
3571 portp = panelp->ports[(ioack >> 3)]; 3550 portp = panelp->ports[(ioack >> 3)];
3572 tty = portp->port.tty; 3551 tty = tty_port_tty_get(&portp->port);
3573 3552
3574 if ((ioack & ACK_TYPMASK) == ACK_TYPRXGOOD) { 3553 if ((ioack & ACK_TYPMASK) == ACK_TYPRXGOOD) {
3575 outb((RDCR + portp->uartaddr), ioaddr); 3554 outb((RDCR + portp->uartaddr), ioaddr);
@@ -3633,10 +3612,12 @@ static void stl_cd1400rxisr(struct stlpanel *panelp, int ioaddr)
3633 } 3612 }
3634 } else { 3613 } else {
3635 printk("STALLION: bad RX interrupt ack value=%x\n", ioack); 3614 printk("STALLION: bad RX interrupt ack value=%x\n", ioack);
3615 tty_kref_put(tty);
3636 return; 3616 return;
3637 } 3617 }
3638 3618
3639stl_rxalldone: 3619stl_rxalldone:
3620 tty_kref_put(tty);
3640 outb((EOSRR + portp->uartaddr), ioaddr); 3621 outb((EOSRR + portp->uartaddr), ioaddr);
3641 outb(0, (ioaddr + EREG_DATA)); 3622 outb(0, (ioaddr + EREG_DATA));
3642} 3623}
@@ -4175,7 +4156,7 @@ static void stl_sc26198flowctrl(struct stlport *portp, int state)
4175 4156
4176 if (portp == NULL) 4157 if (portp == NULL)
4177 return; 4158 return;
4178 tty = portp->port.tty; 4159 tty = tty_port_tty_get(&portp->port);
4179 if (tty == NULL) 4160 if (tty == NULL)
4180 return; 4161 return;
4181 4162
@@ -4226,6 +4207,7 @@ static void stl_sc26198flowctrl(struct stlport *portp, int state)
4226 4207
4227 BRDDISABLE(portp->brdnr); 4208 BRDDISABLE(portp->brdnr);
4228 spin_unlock_irqrestore(&brd_lock, flags); 4209 spin_unlock_irqrestore(&brd_lock, flags);
4210 tty_kref_put(tty);
4229} 4211}
4230 4212
4231/*****************************************************************************/ 4213/*****************************************************************************/
@@ -4244,7 +4226,7 @@ static void stl_sc26198sendflow(struct stlport *portp, int state)
4244 4226
4245 if (portp == NULL) 4227 if (portp == NULL)
4246 return; 4228 return;
4247 tty = portp->port.tty; 4229 tty = tty_port_tty_get(&portp->port);
4248 if (tty == NULL) 4230 if (tty == NULL)
4249 return; 4231 return;
4250 4232
@@ -4269,6 +4251,7 @@ static void stl_sc26198sendflow(struct stlport *portp, int state)
4269 } 4251 }
4270 BRDDISABLE(portp->brdnr); 4252 BRDDISABLE(portp->brdnr);
4271 spin_unlock_irqrestore(&brd_lock, flags); 4253 spin_unlock_irqrestore(&brd_lock, flags);
4254 tty_kref_put(tty);
4272} 4255}
4273 4256
4274/*****************************************************************************/ 4257/*****************************************************************************/
@@ -4408,6 +4391,7 @@ static void stl_sc26198intr(struct stlpanel *panelp, unsigned int iobase)
4408 4391
4409static void stl_sc26198txisr(struct stlport *portp) 4392static void stl_sc26198txisr(struct stlport *portp)
4410{ 4393{
4394 struct tty_struct *tty;
4411 unsigned int ioaddr; 4395 unsigned int ioaddr;
4412 unsigned char mr0; 4396 unsigned char mr0;
4413 int len, stlen; 4397 int len, stlen;
@@ -4422,8 +4406,11 @@ static void stl_sc26198txisr(struct stlport *portp)
4422 if ((len == 0) || ((len < STL_TXBUFLOW) && 4406 if ((len == 0) || ((len < STL_TXBUFLOW) &&
4423 (test_bit(ASYI_TXLOW, &portp->istate) == 0))) { 4407 (test_bit(ASYI_TXLOW, &portp->istate) == 0))) {
4424 set_bit(ASYI_TXLOW, &portp->istate); 4408 set_bit(ASYI_TXLOW, &portp->istate);
4425 if (portp->port.tty) 4409 tty = tty_port_tty_get(&portp->port);
4426 tty_wakeup(portp->port.tty); 4410 if (tty) {
4411 tty_wakeup(tty);
4412 tty_kref_put(tty);
4413 }
4427 } 4414 }
4428 4415
4429 if (len == 0) { 4416 if (len == 0) {
@@ -4476,7 +4463,7 @@ static void stl_sc26198rxisr(struct stlport *portp, unsigned int iack)
4476 4463
4477 pr_debug("stl_sc26198rxisr(portp=%p,iack=%x)\n", portp, iack); 4464 pr_debug("stl_sc26198rxisr(portp=%p,iack=%x)\n", portp, iack);
4478 4465
4479 tty = portp->port.tty; 4466 tty = tty_port_tty_get(&portp->port);
4480 ioaddr = portp->ioaddr; 4467 ioaddr = portp->ioaddr;
4481 outb(GIBCR, (ioaddr + XP_ADDR)); 4468 outb(GIBCR, (ioaddr + XP_ADDR));
4482 len = inb(ioaddr + XP_DATA) + 1; 4469 len = inb(ioaddr + XP_DATA) + 1;
@@ -4515,6 +4502,7 @@ static void stl_sc26198rxisr(struct stlport *portp, unsigned int iack)
4515 stl_sc26198txunflow(portp, tty); 4502 stl_sc26198txunflow(portp, tty);
4516 } 4503 }
4517 } 4504 }
4505 tty_kref_put(tty);
4518} 4506}
4519 4507
4520/*****************************************************************************/ 4508/*****************************************************************************/
@@ -4528,7 +4516,7 @@ static void stl_sc26198rxbadch(struct stlport *portp, unsigned char status, char
4528 struct tty_struct *tty; 4516 struct tty_struct *tty;
4529 unsigned int ioaddr; 4517 unsigned int ioaddr;
4530 4518
4531 tty = portp->port.tty; 4519 tty = tty_port_tty_get(&portp->port);
4532 ioaddr = portp->ioaddr; 4520 ioaddr = portp->ioaddr;
4533 4521
4534 if (status & SR_RXPARITY) 4522 if (status & SR_RXPARITY)
@@ -4566,6 +4554,7 @@ static void stl_sc26198rxbadch(struct stlport *portp, unsigned char status, char
4566 if (status == 0) 4554 if (status == 0)
4567 portp->stats.rxtotal++; 4555 portp->stats.rxtotal++;
4568 } 4556 }
4557 tty_kref_put(tty);
4569} 4558}
4570 4559
4571/*****************************************************************************/ 4560/*****************************************************************************/
diff --git a/drivers/char/sx.c b/drivers/char/sx.c
index c385206f9db5..5b8d7a1aa3e6 100644
--- a/drivers/char/sx.c
+++ b/drivers/char/sx.c
@@ -2504,7 +2504,7 @@ static void __devexit sx_remove_card(struct sx_board *board,
2504 del_timer(&board->timer); 2504 del_timer(&board->timer);
2505 if (pdev) { 2505 if (pdev) {
2506#ifdef CONFIG_PCI 2506#ifdef CONFIG_PCI
2507 pci_iounmap(pdev, board->base); 2507 pci_iounmap(pdev, board->base2);
2508 pci_release_region(pdev, IS_CF_BOARD(board) ? 3 : 2); 2508 pci_release_region(pdev, IS_CF_BOARD(board) ? 3 : 2);
2509#endif 2509#endif
2510 } else { 2510 } else {
@@ -2703,7 +2703,7 @@ static int __devinit sx_pci_probe(struct pci_dev *pdev,
2703 2703
2704 return 0; 2704 return 0;
2705err_unmap: 2705err_unmap:
2706 pci_iounmap(pdev, board->base); 2706 pci_iounmap(pdev, board->base2);
2707err_reg: 2707err_reg:
2708 pci_release_region(pdev, reg); 2708 pci_release_region(pdev, reg);
2709err_flag: 2709err_flag:
diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c
index ae766d868454..1fee7034a386 100644
--- a/drivers/char/tpm/tpm.c
+++ b/drivers/char/tpm/tpm.c
@@ -954,72 +954,63 @@ EXPORT_SYMBOL_GPL(tpm_store_cancel);
954 954
955/* 955/*
956 * Device file system interface to the TPM 956 * Device file system interface to the TPM
957 *
958 * It's assured that the chip will be opened just once,
959 * by the check of is_open variable, which is protected
960 * by driver_lock.
957 */ 961 */
958int tpm_open(struct inode *inode, struct file *file) 962int tpm_open(struct inode *inode, struct file *file)
959{ 963{
960 int rc = 0, minor = iminor(inode); 964 int minor = iminor(inode);
961 struct tpm_chip *chip = NULL, *pos; 965 struct tpm_chip *chip = NULL, *pos;
962 966
963 lock_kernel(); 967 rcu_read_lock();
964 spin_lock(&driver_lock); 968 list_for_each_entry_rcu(pos, &tpm_chip_list, list) {
965
966 list_for_each_entry(pos, &tpm_chip_list, list) {
967 if (pos->vendor.miscdev.minor == minor) { 969 if (pos->vendor.miscdev.minor == minor) {
968 chip = pos; 970 chip = pos;
971 get_device(chip->dev);
969 break; 972 break;
970 } 973 }
971 } 974 }
975 rcu_read_unlock();
972 976
973 if (chip == NULL) { 977 if (!chip)
974 rc = -ENODEV; 978 return -ENODEV;
975 goto err_out;
976 }
977 979
978 if (chip->num_opens) { 980 if (test_and_set_bit(0, &chip->is_open)) {
979 dev_dbg(chip->dev, "Another process owns this TPM\n"); 981 dev_dbg(chip->dev, "Another process owns this TPM\n");
980 rc = -EBUSY; 982 put_device(chip->dev);
981 goto err_out; 983 return -EBUSY;
982 } 984 }
983 985
984 chip->num_opens++;
985 get_device(chip->dev);
986
987 spin_unlock(&driver_lock);
988
989 chip->data_buffer = kmalloc(TPM_BUFSIZE * sizeof(u8), GFP_KERNEL); 986 chip->data_buffer = kmalloc(TPM_BUFSIZE * sizeof(u8), GFP_KERNEL);
990 if (chip->data_buffer == NULL) { 987 if (chip->data_buffer == NULL) {
991 chip->num_opens--; 988 clear_bit(0, &chip->is_open);
992 put_device(chip->dev); 989 put_device(chip->dev);
993 unlock_kernel();
994 return -ENOMEM; 990 return -ENOMEM;
995 } 991 }
996 992
997 atomic_set(&chip->data_pending, 0); 993 atomic_set(&chip->data_pending, 0);
998 994
999 file->private_data = chip; 995 file->private_data = chip;
1000 unlock_kernel();
1001 return 0; 996 return 0;
1002
1003err_out:
1004 spin_unlock(&driver_lock);
1005 unlock_kernel();
1006 return rc;
1007} 997}
1008EXPORT_SYMBOL_GPL(tpm_open); 998EXPORT_SYMBOL_GPL(tpm_open);
1009 999
1000/*
1001 * Called on file close
1002 */
1010int tpm_release(struct inode *inode, struct file *file) 1003int tpm_release(struct inode *inode, struct file *file)
1011{ 1004{
1012 struct tpm_chip *chip = file->private_data; 1005 struct tpm_chip *chip = file->private_data;
1013 1006
1007 del_singleshot_timer_sync(&chip->user_read_timer);
1014 flush_scheduled_work(); 1008 flush_scheduled_work();
1015 spin_lock(&driver_lock);
1016 file->private_data = NULL; 1009 file->private_data = NULL;
1017 del_singleshot_timer_sync(&chip->user_read_timer);
1018 atomic_set(&chip->data_pending, 0); 1010 atomic_set(&chip->data_pending, 0);
1019 chip->num_opens--;
1020 put_device(chip->dev);
1021 kfree(chip->data_buffer); 1011 kfree(chip->data_buffer);
1022 spin_unlock(&driver_lock); 1012 clear_bit(0, &chip->is_open);
1013 put_device(chip->dev);
1023 return 0; 1014 return 0;
1024} 1015}
1025EXPORT_SYMBOL_GPL(tpm_release); 1016EXPORT_SYMBOL_GPL(tpm_release);
@@ -1093,13 +1084,11 @@ void tpm_remove_hardware(struct device *dev)
1093 } 1084 }
1094 1085
1095 spin_lock(&driver_lock); 1086 spin_lock(&driver_lock);
1096 1087 list_del_rcu(&chip->list);
1097 list_del(&chip->list);
1098
1099 spin_unlock(&driver_lock); 1088 spin_unlock(&driver_lock);
1089 synchronize_rcu();
1100 1090
1101 misc_deregister(&chip->vendor.miscdev); 1091 misc_deregister(&chip->vendor.miscdev);
1102
1103 sysfs_remove_group(&dev->kobj, chip->vendor.attr_group); 1092 sysfs_remove_group(&dev->kobj, chip->vendor.attr_group);
1104 tpm_bios_log_teardown(chip->bios_dir); 1093 tpm_bios_log_teardown(chip->bios_dir);
1105 1094
@@ -1144,25 +1133,33 @@ int tpm_pm_resume(struct device *dev)
1144} 1133}
1145EXPORT_SYMBOL_GPL(tpm_pm_resume); 1134EXPORT_SYMBOL_GPL(tpm_pm_resume);
1146 1135
1136/* In case vendor provided release function, call it too.*/
1137
1138void tpm_dev_vendor_release(struct tpm_chip *chip)
1139{
1140 if (chip->vendor.release)
1141 chip->vendor.release(chip->dev);
1142
1143 clear_bit(chip->dev_num, dev_mask);
1144 kfree(chip->vendor.miscdev.name);
1145}
1146EXPORT_SYMBOL_GPL(tpm_dev_vendor_release);
1147
1148
1147/* 1149/*
1148 * Once all references to platform device are down to 0, 1150 * Once all references to platform device are down to 0,
1149 * release all allocated structures. 1151 * release all allocated structures.
1150 * In case vendor provided release function,
1151 * call it too.
1152 */ 1152 */
1153static void tpm_dev_release(struct device *dev) 1153static void tpm_dev_release(struct device *dev)
1154{ 1154{
1155 struct tpm_chip *chip = dev_get_drvdata(dev); 1155 struct tpm_chip *chip = dev_get_drvdata(dev);
1156 1156
1157 if (chip->vendor.release) 1157 tpm_dev_vendor_release(chip);
1158 chip->vendor.release(dev);
1159 1158
1160 chip->release(dev); 1159 chip->release(dev);
1161
1162 clear_bit(chip->dev_num, dev_mask);
1163 kfree(chip->vendor.miscdev.name);
1164 kfree(chip); 1160 kfree(chip);
1165} 1161}
1162EXPORT_SYMBOL_GPL(tpm_dev_release);
1166 1163
1167/* 1164/*
1168 * Called from tpm_<specific>.c probe function only for devices 1165 * Called from tpm_<specific>.c probe function only for devices
@@ -1171,8 +1168,8 @@ static void tpm_dev_release(struct device *dev)
1171 * upon errant exit from this function specific probe function should call 1168 * upon errant exit from this function specific probe function should call
1172 * pci_disable_device 1169 * pci_disable_device
1173 */ 1170 */
1174struct tpm_chip *tpm_register_hardware(struct device *dev, const struct tpm_vendor_specific 1171struct tpm_chip *tpm_register_hardware(struct device *dev,
1175 *entry) 1172 const struct tpm_vendor_specific *entry)
1176{ 1173{
1177#define DEVNAME_SIZE 7 1174#define DEVNAME_SIZE 7
1178 1175
@@ -1231,21 +1228,20 @@ struct tpm_chip *tpm_register_hardware(struct device *dev, const struct tpm_vend
1231 return NULL; 1228 return NULL;
1232 } 1229 }
1233 1230
1234 spin_lock(&driver_lock);
1235
1236 list_add(&chip->list, &tpm_chip_list);
1237
1238 spin_unlock(&driver_lock);
1239
1240 if (sysfs_create_group(&dev->kobj, chip->vendor.attr_group)) { 1231 if (sysfs_create_group(&dev->kobj, chip->vendor.attr_group)) {
1241 list_del(&chip->list);
1242 misc_deregister(&chip->vendor.miscdev); 1232 misc_deregister(&chip->vendor.miscdev);
1243 put_device(chip->dev); 1233 put_device(chip->dev);
1234
1244 return NULL; 1235 return NULL;
1245 } 1236 }
1246 1237
1247 chip->bios_dir = tpm_bios_log_setup(devname); 1238 chip->bios_dir = tpm_bios_log_setup(devname);
1248 1239
1240 /* Make chip available */
1241 spin_lock(&driver_lock);
1242 list_add_rcu(&chip->list, &tpm_chip_list);
1243 spin_unlock(&driver_lock);
1244
1249 return chip; 1245 return chip;
1250} 1246}
1251EXPORT_SYMBOL_GPL(tpm_register_hardware); 1247EXPORT_SYMBOL_GPL(tpm_register_hardware);
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
index e885148b4cfb..8e30df4a4388 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -90,7 +90,7 @@ struct tpm_chip {
90 struct device *dev; /* Device stuff */ 90 struct device *dev; /* Device stuff */
91 91
92 int dev_num; /* /dev/tpm# */ 92 int dev_num; /* /dev/tpm# */
93 int num_opens; /* only one allowed */ 93 unsigned long is_open; /* only one allowed */
94 int time_expired; 94 int time_expired;
95 95
96 /* Data passed to and from the tpm via the read/write calls */ 96 /* Data passed to and from the tpm via the read/write calls */
@@ -132,6 +132,7 @@ extern struct tpm_chip* tpm_register_hardware(struct device *,
132 const struct tpm_vendor_specific *); 132 const struct tpm_vendor_specific *);
133extern int tpm_open(struct inode *, struct file *); 133extern int tpm_open(struct inode *, struct file *);
134extern int tpm_release(struct inode *, struct file *); 134extern int tpm_release(struct inode *, struct file *);
135extern void tpm_dev_vendor_release(struct tpm_chip *);
135extern ssize_t tpm_write(struct file *, const char __user *, size_t, 136extern ssize_t tpm_write(struct file *, const char __user *, size_t,
136 loff_t *); 137 loff_t *);
137extern ssize_t tpm_read(struct file *, char __user *, size_t, loff_t *); 138extern ssize_t tpm_read(struct file *, char __user *, size_t, loff_t *);
diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c
index ed1879c0dd8d..717af7ad1bdf 100644
--- a/drivers/char/tpm/tpm_tis.c
+++ b/drivers/char/tpm/tpm_tis.c
@@ -630,12 +630,23 @@ static struct pnp_device_id tpm_pnp_tbl[] __devinitdata = {
630 {"", 0} /* Terminator */ 630 {"", 0} /* Terminator */
631}; 631};
632 632
633static __devexit void tpm_tis_pnp_remove(struct pnp_dev *dev)
634{
635 struct tpm_chip *chip = pnp_get_drvdata(dev);
636
637 tpm_dev_vendor_release(chip);
638
639 kfree(chip);
640}
641
642
633static struct pnp_driver tis_pnp_driver = { 643static struct pnp_driver tis_pnp_driver = {
634 .name = "tpm_tis", 644 .name = "tpm_tis",
635 .id_table = tpm_pnp_tbl, 645 .id_table = tpm_pnp_tbl,
636 .probe = tpm_tis_pnp_init, 646 .probe = tpm_tis_pnp_init,
637 .suspend = tpm_tis_pnp_suspend, 647 .suspend = tpm_tis_pnp_suspend,
638 .resume = tpm_tis_pnp_resume, 648 .resume = tpm_tis_pnp_resume,
649 .remove = tpm_tis_pnp_remove,
639}; 650};
640 651
641#define TIS_HID_USR_IDX sizeof(tpm_pnp_tbl)/sizeof(struct pnp_device_id) -2 652#define TIS_HID_USR_IDX sizeof(tpm_pnp_tbl)/sizeof(struct pnp_device_id) -2
@@ -683,6 +694,7 @@ static void __exit cleanup_tis(void)
683 spin_lock(&tis_lock); 694 spin_lock(&tis_lock);
684 list_for_each_entry_safe(i, j, &tis_chips, list) { 695 list_for_each_entry_safe(i, j, &tis_chips, list) {
685 chip = to_tpm_chip(i); 696 chip = to_tpm_chip(i);
697 tpm_remove_hardware(chip->dev);
686 iowrite32(~TPM_GLOBAL_INT_ENABLE & 698 iowrite32(~TPM_GLOBAL_INT_ENABLE &
687 ioread32(chip->vendor.iobase + 699 ioread32(chip->vendor.iobase +
688 TPM_INT_ENABLE(chip->vendor. 700 TPM_INT_ENABLE(chip->vendor.
@@ -694,9 +706,9 @@ static void __exit cleanup_tis(void)
694 free_irq(chip->vendor.irq, chip); 706 free_irq(chip->vendor.irq, chip);
695 iounmap(i->iobase); 707 iounmap(i->iobase);
696 list_del(&i->list); 708 list_del(&i->list);
697 tpm_remove_hardware(chip->dev);
698 } 709 }
699 spin_unlock(&tis_lock); 710 spin_unlock(&tis_lock);
711
700 if (force) { 712 if (force) {
701 platform_device_unregister(pdev); 713 platform_device_unregister(pdev);
702 driver_unregister(&tis_drv); 714 driver_unregister(&tis_drv);
diff --git a/drivers/char/tty_audit.c b/drivers/char/tty_audit.c
index 3582f43345a8..5787249934c8 100644
--- a/drivers/char/tty_audit.c
+++ b/drivers/char/tty_audit.c
@@ -93,7 +93,7 @@ static void tty_audit_buf_push(struct task_struct *tsk, uid_t loginuid,
93 get_task_comm(name, tsk); 93 get_task_comm(name, tsk);
94 audit_log_untrustedstring(ab, name); 94 audit_log_untrustedstring(ab, name);
95 audit_log_format(ab, " data="); 95 audit_log_format(ab, " data=");
96 audit_log_n_untrustedstring(ab, buf->data, buf->valid); 96 audit_log_n_hex(ab, buf->data, buf->valid);
97 audit_log_end(ab); 97 audit_log_end(ab);
98 } 98 }
99 buf->valid = 0; 99 buf->valid = 0;
diff --git a/drivers/char/tty_buffer.c b/drivers/char/tty_buffer.c
new file mode 100644
index 000000000000..810ee25d66a4
--- /dev/null
+++ b/drivers/char/tty_buffer.c
@@ -0,0 +1,511 @@
1/*
2 * Tty buffer allocation management
3 */
4
5#include <linux/types.h>
6#include <linux/errno.h>
7#include <linux/tty.h>
8#include <linux/tty_driver.h>
9#include <linux/tty_flip.h>
10#include <linux/timer.h>
11#include <linux/string.h>
12#include <linux/slab.h>
13#include <linux/sched.h>
14#include <linux/init.h>
15#include <linux/wait.h>
16#include <linux/bitops.h>
17#include <linux/delay.h>
18#include <linux/module.h>
19
20/**
21 * tty_buffer_free_all - free buffers used by a tty
22 * @tty: tty to free from
23 *
24 * Remove all the buffers pending on a tty whether queued with data
25 * or in the free ring. Must be called when the tty is no longer in use
26 *
27 * Locking: none
28 */
29
30void tty_buffer_free_all(struct tty_struct *tty)
31{
32 struct tty_buffer *thead;
33 while ((thead = tty->buf.head) != NULL) {
34 tty->buf.head = thead->next;
35 kfree(thead);
36 }
37 while ((thead = tty->buf.free) != NULL) {
38 tty->buf.free = thead->next;
39 kfree(thead);
40 }
41 tty->buf.tail = NULL;
42 tty->buf.memory_used = 0;
43}
44
45/**
46 * tty_buffer_alloc - allocate a tty buffer
47 * @tty: tty device
48 * @size: desired size (characters)
49 *
50 * Allocate a new tty buffer to hold the desired number of characters.
51 * Return NULL if out of memory or the allocation would exceed the
52 * per device queue
53 *
54 * Locking: Caller must hold tty->buf.lock
55 */
56
57static struct tty_buffer *tty_buffer_alloc(struct tty_struct *tty, size_t size)
58{
59 struct tty_buffer *p;
60
61 if (tty->buf.memory_used + size > 65536)
62 return NULL;
63 p = kmalloc(sizeof(struct tty_buffer) + 2 * size, GFP_ATOMIC);
64 if (p == NULL)
65 return NULL;
66 p->used = 0;
67 p->size = size;
68 p->next = NULL;
69 p->commit = 0;
70 p->read = 0;
71 p->char_buf_ptr = (char *)(p->data);
72 p->flag_buf_ptr = (unsigned char *)p->char_buf_ptr + size;
73 tty->buf.memory_used += size;
74 return p;
75}
76
77/**
78 * tty_buffer_free - free a tty buffer
79 * @tty: tty owning the buffer
80 * @b: the buffer to free
81 *
82 * Free a tty buffer, or add it to the free list according to our
83 * internal strategy
84 *
85 * Locking: Caller must hold tty->buf.lock
86 */
87
88static void tty_buffer_free(struct tty_struct *tty, struct tty_buffer *b)
89{
90 /* Dumb strategy for now - should keep some stats */
91 tty->buf.memory_used -= b->size;
92 WARN_ON(tty->buf.memory_used < 0);
93
94 if (b->size >= 512)
95 kfree(b);
96 else {
97 b->next = tty->buf.free;
98 tty->buf.free = b;
99 }
100}
101
102/**
103 * __tty_buffer_flush - flush full tty buffers
104 * @tty: tty to flush
105 *
106 * flush all the buffers containing receive data. Caller must
107 * hold the buffer lock and must have ensured no parallel flush to
108 * ldisc is running.
109 *
110 * Locking: Caller must hold tty->buf.lock
111 */
112
113static void __tty_buffer_flush(struct tty_struct *tty)
114{
115 struct tty_buffer *thead;
116
117 while ((thead = tty->buf.head) != NULL) {
118 tty->buf.head = thead->next;
119 tty_buffer_free(tty, thead);
120 }
121 tty->buf.tail = NULL;
122}
123
124/**
125 * tty_buffer_flush - flush full tty buffers
126 * @tty: tty to flush
127 *
128 * flush all the buffers containing receive data. If the buffer is
129 * being processed by flush_to_ldisc then we defer the processing
130 * to that function
131 *
132 * Locking: none
133 */
134
135void tty_buffer_flush(struct tty_struct *tty)
136{
137 unsigned long flags;
138 spin_lock_irqsave(&tty->buf.lock, flags);
139
140 /* If the data is being pushed to the tty layer then we can't
141 process it here. Instead set a flag and the flush_to_ldisc
142 path will process the flush request before it exits */
143 if (test_bit(TTY_FLUSHING, &tty->flags)) {
144 set_bit(TTY_FLUSHPENDING, &tty->flags);
145 spin_unlock_irqrestore(&tty->buf.lock, flags);
146 wait_event(tty->read_wait,
147 test_bit(TTY_FLUSHPENDING, &tty->flags) == 0);
148 return;
149 } else
150 __tty_buffer_flush(tty);
151 spin_unlock_irqrestore(&tty->buf.lock, flags);
152}
153
154/**
155 * tty_buffer_find - find a free tty buffer
156 * @tty: tty owning the buffer
157 * @size: characters wanted
158 *
159 * Locate an existing suitable tty buffer or if we are lacking one then
160 * allocate a new one. We round our buffers off in 256 character chunks
161 * to get better allocation behaviour.
162 *
163 * Locking: Caller must hold tty->buf.lock
164 */
165
166static struct tty_buffer *tty_buffer_find(struct tty_struct *tty, size_t size)
167{
168 struct tty_buffer **tbh = &tty->buf.free;
169 while ((*tbh) != NULL) {
170 struct tty_buffer *t = *tbh;
171 if (t->size >= size) {
172 *tbh = t->next;
173 t->next = NULL;
174 t->used = 0;
175 t->commit = 0;
176 t->read = 0;
177 tty->buf.memory_used += t->size;
178 return t;
179 }
180 tbh = &((*tbh)->next);
181 }
182 /* Round the buffer size out */
183 size = (size + 0xFF) & ~0xFF;
184 return tty_buffer_alloc(tty, size);
185 /* Should possibly check if this fails for the largest buffer we
186 have queued and recycle that ? */
187}
188
189/**
190 * tty_buffer_request_room - grow tty buffer if needed
191 * @tty: tty structure
192 * @size: size desired
193 *
194 * Make at least size bytes of linear space available for the tty
195 * buffer. If we fail return the size we managed to find.
196 *
197 * Locking: Takes tty->buf.lock
198 */
199int tty_buffer_request_room(struct tty_struct *tty, size_t size)
200{
201 struct tty_buffer *b, *n;
202 int left;
203 unsigned long flags;
204
205 spin_lock_irqsave(&tty->buf.lock, flags);
206
207 /* OPTIMISATION: We could keep a per tty "zero" sized buffer to
208 remove this conditional if its worth it. This would be invisible
209 to the callers */
210 if ((b = tty->buf.tail) != NULL)
211 left = b->size - b->used;
212 else
213 left = 0;
214
215 if (left < size) {
216 /* This is the slow path - looking for new buffers to use */
217 if ((n = tty_buffer_find(tty, size)) != NULL) {
218 if (b != NULL) {
219 b->next = n;
220 b->commit = b->used;
221 } else
222 tty->buf.head = n;
223 tty->buf.tail = n;
224 } else
225 size = left;
226 }
227
228 spin_unlock_irqrestore(&tty->buf.lock, flags);
229 return size;
230}
231EXPORT_SYMBOL_GPL(tty_buffer_request_room);
232
233/**
234 * tty_insert_flip_string - Add characters to the tty buffer
235 * @tty: tty structure
236 * @chars: characters
237 * @size: size
238 *
239 * Queue a series of bytes to the tty buffering. All the characters
240 * passed are marked as without error. Returns the number added.
241 *
242 * Locking: Called functions may take tty->buf.lock
243 */
244
245int tty_insert_flip_string(struct tty_struct *tty, const unsigned char *chars,
246 size_t size)
247{
248 int copied = 0;
249 do {
250 int space = tty_buffer_request_room(tty, size - copied);
251 struct tty_buffer *tb = tty->buf.tail;
252 /* If there is no space then tb may be NULL */
253 if (unlikely(space == 0))
254 break;
255 memcpy(tb->char_buf_ptr + tb->used, chars, space);
256 memset(tb->flag_buf_ptr + tb->used, TTY_NORMAL, space);
257 tb->used += space;
258 copied += space;
259 chars += space;
260 /* There is a small chance that we need to split the data over
261 several buffers. If this is the case we must loop */
262 } while (unlikely(size > copied));
263 return copied;
264}
265EXPORT_SYMBOL(tty_insert_flip_string);
266
267/**
268 * tty_insert_flip_string_flags - Add characters to the tty buffer
269 * @tty: tty structure
270 * @chars: characters
271 * @flags: flag bytes
272 * @size: size
273 *
274 * Queue a series of bytes to the tty buffering. For each character
275 * the flags array indicates the status of the character. Returns the
276 * number added.
277 *
278 * Locking: Called functions may take tty->buf.lock
279 */
280
281int tty_insert_flip_string_flags(struct tty_struct *tty,
282 const unsigned char *chars, const char *flags, size_t size)
283{
284 int copied = 0;
285 do {
286 int space = tty_buffer_request_room(tty, size - copied);
287 struct tty_buffer *tb = tty->buf.tail;
288 /* If there is no space then tb may be NULL */
289 if (unlikely(space == 0))
290 break;
291 memcpy(tb->char_buf_ptr + tb->used, chars, space);
292 memcpy(tb->flag_buf_ptr + tb->used, flags, space);
293 tb->used += space;
294 copied += space;
295 chars += space;
296 flags += space;
297 /* There is a small chance that we need to split the data over
298 several buffers. If this is the case we must loop */
299 } while (unlikely(size > copied));
300 return copied;
301}
302EXPORT_SYMBOL(tty_insert_flip_string_flags);
303
304/**
305 * tty_schedule_flip - push characters to ldisc
306 * @tty: tty to push from
307 *
308 * Takes any pending buffers and transfers their ownership to the
309 * ldisc side of the queue. It then schedules those characters for
310 * processing by the line discipline.
311 *
312 * Locking: Takes tty->buf.lock
313 */
314
315void tty_schedule_flip(struct tty_struct *tty)
316{
317 unsigned long flags;
318 spin_lock_irqsave(&tty->buf.lock, flags);
319 if (tty->buf.tail != NULL)
320 tty->buf.tail->commit = tty->buf.tail->used;
321 spin_unlock_irqrestore(&tty->buf.lock, flags);
322 schedule_delayed_work(&tty->buf.work, 1);
323}
324EXPORT_SYMBOL(tty_schedule_flip);
325
326/**
327 * tty_prepare_flip_string - make room for characters
328 * @tty: tty
329 * @chars: return pointer for character write area
330 * @size: desired size
331 *
332 * Prepare a block of space in the buffer for data. Returns the length
333 * available and buffer pointer to the space which is now allocated and
334 * accounted for as ready for normal characters. This is used for drivers
335 * that need their own block copy routines into the buffer. There is no
336 * guarantee the buffer is a DMA target!
337 *
338 * Locking: May call functions taking tty->buf.lock
339 */
340
341int tty_prepare_flip_string(struct tty_struct *tty, unsigned char **chars,
342 size_t size)
343{
344 int space = tty_buffer_request_room(tty, size);
345 if (likely(space)) {
346 struct tty_buffer *tb = tty->buf.tail;
347 *chars = tb->char_buf_ptr + tb->used;
348 memset(tb->flag_buf_ptr + tb->used, TTY_NORMAL, space);
349 tb->used += space;
350 }
351 return space;
352}
353EXPORT_SYMBOL_GPL(tty_prepare_flip_string);
354
355/**
356 * tty_prepare_flip_string_flags - make room for characters
357 * @tty: tty
358 * @chars: return pointer for character write area
359 * @flags: return pointer for status flag write area
360 * @size: desired size
361 *
362 * Prepare a block of space in the buffer for data. Returns the length
363 * available and buffer pointer to the space which is now allocated and
364 * accounted for as ready for characters. This is used for drivers
365 * that need their own block copy routines into the buffer. There is no
366 * guarantee the buffer is a DMA target!
367 *
368 * Locking: May call functions taking tty->buf.lock
369 */
370
371int tty_prepare_flip_string_flags(struct tty_struct *tty,
372 unsigned char **chars, char **flags, size_t size)
373{
374 int space = tty_buffer_request_room(tty, size);
375 if (likely(space)) {
376 struct tty_buffer *tb = tty->buf.tail;
377 *chars = tb->char_buf_ptr + tb->used;
378 *flags = tb->flag_buf_ptr + tb->used;
379 tb->used += space;
380 }
381 return space;
382}
383EXPORT_SYMBOL_GPL(tty_prepare_flip_string_flags);
384
385
386
387/**
388 * flush_to_ldisc
389 * @work: tty structure passed from work queue.
390 *
391 * This routine is called out of the software interrupt to flush data
392 * from the buffer chain to the line discipline.
393 *
394 * Locking: holds tty->buf.lock to guard buffer list. Drops the lock
395 * while invoking the line discipline receive_buf method. The
396 * receive_buf method is single threaded for each tty instance.
397 */
398
399static void flush_to_ldisc(struct work_struct *work)
400{
401 struct tty_struct *tty =
402 container_of(work, struct tty_struct, buf.work.work);
403 unsigned long flags;
404 struct tty_ldisc *disc;
405 struct tty_buffer *tbuf, *head;
406 char *char_buf;
407 unsigned char *flag_buf;
408
409 disc = tty_ldisc_ref(tty);
410 if (disc == NULL) /* !TTY_LDISC */
411 return;
412
413 spin_lock_irqsave(&tty->buf.lock, flags);
414 /* So we know a flush is running */
415 set_bit(TTY_FLUSHING, &tty->flags);
416 head = tty->buf.head;
417 if (head != NULL) {
418 tty->buf.head = NULL;
419 for (;;) {
420 int count = head->commit - head->read;
421 if (!count) {
422 if (head->next == NULL)
423 break;
424 tbuf = head;
425 head = head->next;
426 tty_buffer_free(tty, tbuf);
427 continue;
428 }
429 /* Ldisc or user is trying to flush the buffers
430 we are feeding to the ldisc, stop feeding the
431 line discipline as we want to empty the queue */
432 if (test_bit(TTY_FLUSHPENDING, &tty->flags))
433 break;
434 if (!tty->receive_room) {
435 schedule_delayed_work(&tty->buf.work, 1);
436 break;
437 }
438 if (count > tty->receive_room)
439 count = tty->receive_room;
440 char_buf = head->char_buf_ptr + head->read;
441 flag_buf = head->flag_buf_ptr + head->read;
442 head->read += count;
443 spin_unlock_irqrestore(&tty->buf.lock, flags);
444 disc->ops->receive_buf(tty, char_buf,
445 flag_buf, count);
446 spin_lock_irqsave(&tty->buf.lock, flags);
447 }
448 /* Restore the queue head */
449 tty->buf.head = head;
450 }
451 /* We may have a deferred request to flush the input buffer,
452 if so pull the chain under the lock and empty the queue */
453 if (test_bit(TTY_FLUSHPENDING, &tty->flags)) {
454 __tty_buffer_flush(tty);
455 clear_bit(TTY_FLUSHPENDING, &tty->flags);
456 wake_up(&tty->read_wait);
457 }
458 clear_bit(TTY_FLUSHING, &tty->flags);
459 spin_unlock_irqrestore(&tty->buf.lock, flags);
460
461 tty_ldisc_deref(disc);
462}
463
464/**
465 * tty_flip_buffer_push - terminal
466 * @tty: tty to push
467 *
468 * Queue a push of the terminal flip buffers to the line discipline. This
469 * function must not be called from IRQ context if tty->low_latency is set.
470 *
471 * In the event of the queue being busy for flipping the work will be
472 * held off and retried later.
473 *
474 * Locking: tty buffer lock. Driver locks in low latency mode.
475 */
476
477void tty_flip_buffer_push(struct tty_struct *tty)
478{
479 unsigned long flags;
480 spin_lock_irqsave(&tty->buf.lock, flags);
481 if (tty->buf.tail != NULL)
482 tty->buf.tail->commit = tty->buf.tail->used;
483 spin_unlock_irqrestore(&tty->buf.lock, flags);
484
485 if (tty->low_latency)
486 flush_to_ldisc(&tty->buf.work.work);
487 else
488 schedule_delayed_work(&tty->buf.work, 1);
489}
490EXPORT_SYMBOL(tty_flip_buffer_push);
491
492/**
493 * tty_buffer_init - prepare a tty buffer structure
494 * @tty: tty to initialise
495 *
496 * Set up the initial state of the buffer management for a tty device.
497 * Must be called before the other tty buffer functions are used.
498 *
499 * Locking: none
500 */
501
502void tty_buffer_init(struct tty_struct *tty)
503{
504 spin_lock_init(&tty->buf.lock);
505 tty->buf.head = NULL;
506 tty->buf.tail = NULL;
507 tty->buf.free = NULL;
508 tty->buf.memory_used = 0;
509 INIT_DELAYED_WORK(&tty->buf.work, flush_to_ldisc);
510}
511
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index e4dce8709541..7053d6333692 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -49,7 +49,7 @@
49 * implement CONFIG_VT and generalize console device interface. 49 * implement CONFIG_VT and generalize console device interface.
50 * -- Marko Kohtala <Marko.Kohtala@hut.fi>, March 97 50 * -- Marko Kohtala <Marko.Kohtala@hut.fi>, March 97
51 * 51 *
52 * Rewrote init_dev and release_dev to eliminate races. 52 * Rewrote tty_init_dev and tty_release_dev to eliminate races.
53 * -- Bill Hawes <whawes@star.net>, June 97 53 * -- Bill Hawes <whawes@star.net>, June 97
54 * 54 *
55 * Added devfs support. 55 * Added devfs support.
@@ -136,13 +136,6 @@ LIST_HEAD(tty_drivers); /* linked list of tty drivers */
136DEFINE_MUTEX(tty_mutex); 136DEFINE_MUTEX(tty_mutex);
137EXPORT_SYMBOL(tty_mutex); 137EXPORT_SYMBOL(tty_mutex);
138 138
139#ifdef CONFIG_UNIX98_PTYS
140extern struct tty_driver *ptm_driver; /* Unix98 pty masters; for /dev/ptmx */
141static int ptmx_open(struct inode *, struct file *);
142#endif
143
144static void initialize_tty_struct(struct tty_struct *tty);
145
146static ssize_t tty_read(struct file *, char __user *, size_t, loff_t *); 139static ssize_t tty_read(struct file *, char __user *, size_t, loff_t *);
147static ssize_t tty_write(struct file *, const char __user *, size_t, loff_t *); 140static ssize_t tty_write(struct file *, const char __user *, size_t, loff_t *);
148ssize_t redirected_tty_write(struct file *, const char __user *, 141ssize_t redirected_tty_write(struct file *, const char __user *,
@@ -171,13 +164,11 @@ static void proc_set_tty(struct task_struct *tsk, struct tty_struct *tty);
171 * Locking: none 164 * Locking: none
172 */ 165 */
173 166
174static struct tty_struct *alloc_tty_struct(void) 167struct tty_struct *alloc_tty_struct(void)
175{ 168{
176 return kzalloc(sizeof(struct tty_struct), GFP_KERNEL); 169 return kzalloc(sizeof(struct tty_struct), GFP_KERNEL);
177} 170}
178 171
179static void tty_buffer_free_all(struct tty_struct *);
180
181/** 172/**
182 * free_tty_struct - free a disused tty 173 * free_tty_struct - free a disused tty
183 * @tty: tty struct to free 174 * @tty: tty struct to free
@@ -187,7 +178,7 @@ static void tty_buffer_free_all(struct tty_struct *);
187 * Locking: none. Must be called after tty is definitely unused 178 * Locking: none. Must be called after tty is definitely unused
188 */ 179 */
189 180
190static inline void free_tty_struct(struct tty_struct *tty) 181void free_tty_struct(struct tty_struct *tty)
191{ 182{
192 kfree(tty->write_buf); 183 kfree(tty->write_buf);
193 tty_buffer_free_all(tty); 184 tty_buffer_free_all(tty);
@@ -263,398 +254,6 @@ static int check_tty_count(struct tty_struct *tty, const char *routine)
263 return 0; 254 return 0;
264} 255}
265 256
266/*
267 * Tty buffer allocation management
268 */
269
270/**
271 * tty_buffer_free_all - free buffers used by a tty
272 * @tty: tty to free from
273 *
274 * Remove all the buffers pending on a tty whether queued with data
275 * or in the free ring. Must be called when the tty is no longer in use
276 *
277 * Locking: none
278 */
279
280static void tty_buffer_free_all(struct tty_struct *tty)
281{
282 struct tty_buffer *thead;
283 while ((thead = tty->buf.head) != NULL) {
284 tty->buf.head = thead->next;
285 kfree(thead);
286 }
287 while ((thead = tty->buf.free) != NULL) {
288 tty->buf.free = thead->next;
289 kfree(thead);
290 }
291 tty->buf.tail = NULL;
292 tty->buf.memory_used = 0;
293}
294
295/**
296 * tty_buffer_init - prepare a tty buffer structure
297 * @tty: tty to initialise
298 *
299 * Set up the initial state of the buffer management for a tty device.
300 * Must be called before the other tty buffer functions are used.
301 *
302 * Locking: none
303 */
304
305static void tty_buffer_init(struct tty_struct *tty)
306{
307 spin_lock_init(&tty->buf.lock);
308 tty->buf.head = NULL;
309 tty->buf.tail = NULL;
310 tty->buf.free = NULL;
311 tty->buf.memory_used = 0;
312}
313
314/**
315 * tty_buffer_alloc - allocate a tty buffer
316 * @tty: tty device
317 * @size: desired size (characters)
318 *
319 * Allocate a new tty buffer to hold the desired number of characters.
320 * Return NULL if out of memory or the allocation would exceed the
321 * per device queue
322 *
323 * Locking: Caller must hold tty->buf.lock
324 */
325
326static struct tty_buffer *tty_buffer_alloc(struct tty_struct *tty, size_t size)
327{
328 struct tty_buffer *p;
329
330 if (tty->buf.memory_used + size > 65536)
331 return NULL;
332 p = kmalloc(sizeof(struct tty_buffer) + 2 * size, GFP_ATOMIC);
333 if (p == NULL)
334 return NULL;
335 p->used = 0;
336 p->size = size;
337 p->next = NULL;
338 p->commit = 0;
339 p->read = 0;
340 p->char_buf_ptr = (char *)(p->data);
341 p->flag_buf_ptr = (unsigned char *)p->char_buf_ptr + size;
342 tty->buf.memory_used += size;
343 return p;
344}
345
346/**
347 * tty_buffer_free - free a tty buffer
348 * @tty: tty owning the buffer
349 * @b: the buffer to free
350 *
351 * Free a tty buffer, or add it to the free list according to our
352 * internal strategy
353 *
354 * Locking: Caller must hold tty->buf.lock
355 */
356
357static void tty_buffer_free(struct tty_struct *tty, struct tty_buffer *b)
358{
359 /* Dumb strategy for now - should keep some stats */
360 tty->buf.memory_used -= b->size;
361 WARN_ON(tty->buf.memory_used < 0);
362
363 if (b->size >= 512)
364 kfree(b);
365 else {
366 b->next = tty->buf.free;
367 tty->buf.free = b;
368 }
369}
370
371/**
372 * __tty_buffer_flush - flush full tty buffers
373 * @tty: tty to flush
374 *
375 * flush all the buffers containing receive data. Caller must
376 * hold the buffer lock and must have ensured no parallel flush to
377 * ldisc is running.
378 *
379 * Locking: Caller must hold tty->buf.lock
380 */
381
382static void __tty_buffer_flush(struct tty_struct *tty)
383{
384 struct tty_buffer *thead;
385
386 while ((thead = tty->buf.head) != NULL) {
387 tty->buf.head = thead->next;
388 tty_buffer_free(tty, thead);
389 }
390 tty->buf.tail = NULL;
391}
392
393/**
394 * tty_buffer_flush - flush full tty buffers
395 * @tty: tty to flush
396 *
397 * flush all the buffers containing receive data. If the buffer is
398 * being processed by flush_to_ldisc then we defer the processing
399 * to that function
400 *
401 * Locking: none
402 */
403
404static void tty_buffer_flush(struct tty_struct *tty)
405{
406 unsigned long flags;
407 spin_lock_irqsave(&tty->buf.lock, flags);
408
409 /* If the data is being pushed to the tty layer then we can't
410 process it here. Instead set a flag and the flush_to_ldisc
411 path will process the flush request before it exits */
412 if (test_bit(TTY_FLUSHING, &tty->flags)) {
413 set_bit(TTY_FLUSHPENDING, &tty->flags);
414 spin_unlock_irqrestore(&tty->buf.lock, flags);
415 wait_event(tty->read_wait,
416 test_bit(TTY_FLUSHPENDING, &tty->flags) == 0);
417 return;
418 } else
419 __tty_buffer_flush(tty);
420 spin_unlock_irqrestore(&tty->buf.lock, flags);
421}
422
423/**
424 * tty_buffer_find - find a free tty buffer
425 * @tty: tty owning the buffer
426 * @size: characters wanted
427 *
428 * Locate an existing suitable tty buffer or if we are lacking one then
429 * allocate a new one. We round our buffers off in 256 character chunks
430 * to get better allocation behaviour.
431 *
432 * Locking: Caller must hold tty->buf.lock
433 */
434
435static struct tty_buffer *tty_buffer_find(struct tty_struct *tty, size_t size)
436{
437 struct tty_buffer **tbh = &tty->buf.free;
438 while ((*tbh) != NULL) {
439 struct tty_buffer *t = *tbh;
440 if (t->size >= size) {
441 *tbh = t->next;
442 t->next = NULL;
443 t->used = 0;
444 t->commit = 0;
445 t->read = 0;
446 tty->buf.memory_used += t->size;
447 return t;
448 }
449 tbh = &((*tbh)->next);
450 }
451 /* Round the buffer size out */
452 size = (size + 0xFF) & ~0xFF;
453 return tty_buffer_alloc(tty, size);
454 /* Should possibly check if this fails for the largest buffer we
455 have queued and recycle that ? */
456}
457
458/**
459 * tty_buffer_request_room - grow tty buffer if needed
460 * @tty: tty structure
461 * @size: size desired
462 *
463 * Make at least size bytes of linear space available for the tty
464 * buffer. If we fail return the size we managed to find.
465 *
466 * Locking: Takes tty->buf.lock
467 */
468int tty_buffer_request_room(struct tty_struct *tty, size_t size)
469{
470 struct tty_buffer *b, *n;
471 int left;
472 unsigned long flags;
473
474 spin_lock_irqsave(&tty->buf.lock, flags);
475
476 /* OPTIMISATION: We could keep a per tty "zero" sized buffer to
477 remove this conditional if its worth it. This would be invisible
478 to the callers */
479 if ((b = tty->buf.tail) != NULL)
480 left = b->size - b->used;
481 else
482 left = 0;
483
484 if (left < size) {
485 /* This is the slow path - looking for new buffers to use */
486 if ((n = tty_buffer_find(tty, size)) != NULL) {
487 if (b != NULL) {
488 b->next = n;
489 b->commit = b->used;
490 } else
491 tty->buf.head = n;
492 tty->buf.tail = n;
493 } else
494 size = left;
495 }
496
497 spin_unlock_irqrestore(&tty->buf.lock, flags);
498 return size;
499}
500EXPORT_SYMBOL_GPL(tty_buffer_request_room);
501
502/**
503 * tty_insert_flip_string - Add characters to the tty buffer
504 * @tty: tty structure
505 * @chars: characters
506 * @size: size
507 *
508 * Queue a series of bytes to the tty buffering. All the characters
509 * passed are marked as without error. Returns the number added.
510 *
511 * Locking: Called functions may take tty->buf.lock
512 */
513
514int tty_insert_flip_string(struct tty_struct *tty, const unsigned char *chars,
515 size_t size)
516{
517 int copied = 0;
518 do {
519 int space = tty_buffer_request_room(tty, size - copied);
520 struct tty_buffer *tb = tty->buf.tail;
521 /* If there is no space then tb may be NULL */
522 if (unlikely(space == 0))
523 break;
524 memcpy(tb->char_buf_ptr + tb->used, chars, space);
525 memset(tb->flag_buf_ptr + tb->used, TTY_NORMAL, space);
526 tb->used += space;
527 copied += space;
528 chars += space;
529 /* There is a small chance that we need to split the data over
530 several buffers. If this is the case we must loop */
531 } while (unlikely(size > copied));
532 return copied;
533}
534EXPORT_SYMBOL(tty_insert_flip_string);
535
536/**
537 * tty_insert_flip_string_flags - Add characters to the tty buffer
538 * @tty: tty structure
539 * @chars: characters
540 * @flags: flag bytes
541 * @size: size
542 *
543 * Queue a series of bytes to the tty buffering. For each character
544 * the flags array indicates the status of the character. Returns the
545 * number added.
546 *
547 * Locking: Called functions may take tty->buf.lock
548 */
549
550int tty_insert_flip_string_flags(struct tty_struct *tty,
551 const unsigned char *chars, const char *flags, size_t size)
552{
553 int copied = 0;
554 do {
555 int space = tty_buffer_request_room(tty, size - copied);
556 struct tty_buffer *tb = tty->buf.tail;
557 /* If there is no space then tb may be NULL */
558 if (unlikely(space == 0))
559 break;
560 memcpy(tb->char_buf_ptr + tb->used, chars, space);
561 memcpy(tb->flag_buf_ptr + tb->used, flags, space);
562 tb->used += space;
563 copied += space;
564 chars += space;
565 flags += space;
566 /* There is a small chance that we need to split the data over
567 several buffers. If this is the case we must loop */
568 } while (unlikely(size > copied));
569 return copied;
570}
571EXPORT_SYMBOL(tty_insert_flip_string_flags);
572
573/**
574 * tty_schedule_flip - push characters to ldisc
575 * @tty: tty to push from
576 *
577 * Takes any pending buffers and transfers their ownership to the
578 * ldisc side of the queue. It then schedules those characters for
579 * processing by the line discipline.
580 *
581 * Locking: Takes tty->buf.lock
582 */
583
584void tty_schedule_flip(struct tty_struct *tty)
585{
586 unsigned long flags;
587 spin_lock_irqsave(&tty->buf.lock, flags);
588 if (tty->buf.tail != NULL)
589 tty->buf.tail->commit = tty->buf.tail->used;
590 spin_unlock_irqrestore(&tty->buf.lock, flags);
591 schedule_delayed_work(&tty->buf.work, 1);
592}
593EXPORT_SYMBOL(tty_schedule_flip);
594
595/**
596 * tty_prepare_flip_string - make room for characters
597 * @tty: tty
598 * @chars: return pointer for character write area
599 * @size: desired size
600 *
601 * Prepare a block of space in the buffer for data. Returns the length
602 * available and buffer pointer to the space which is now allocated and
603 * accounted for as ready for normal characters. This is used for drivers
604 * that need their own block copy routines into the buffer. There is no
605 * guarantee the buffer is a DMA target!
606 *
607 * Locking: May call functions taking tty->buf.lock
608 */
609
610int tty_prepare_flip_string(struct tty_struct *tty, unsigned char **chars,
611 size_t size)
612{
613 int space = tty_buffer_request_room(tty, size);
614 if (likely(space)) {
615 struct tty_buffer *tb = tty->buf.tail;
616 *chars = tb->char_buf_ptr + tb->used;
617 memset(tb->flag_buf_ptr + tb->used, TTY_NORMAL, space);
618 tb->used += space;
619 }
620 return space;
621}
622
623EXPORT_SYMBOL_GPL(tty_prepare_flip_string);
624
625/**
626 * tty_prepare_flip_string_flags - make room for characters
627 * @tty: tty
628 * @chars: return pointer for character write area
629 * @flags: return pointer for status flag write area
630 * @size: desired size
631 *
632 * Prepare a block of space in the buffer for data. Returns the length
633 * available and buffer pointer to the space which is now allocated and
634 * accounted for as ready for characters. This is used for drivers
635 * that need their own block copy routines into the buffer. There is no
636 * guarantee the buffer is a DMA target!
637 *
638 * Locking: May call functions taking tty->buf.lock
639 */
640
641int tty_prepare_flip_string_flags(struct tty_struct *tty,
642 unsigned char **chars, char **flags, size_t size)
643{
644 int space = tty_buffer_request_room(tty, size);
645 if (likely(space)) {
646 struct tty_buffer *tb = tty->buf.tail;
647 *chars = tb->char_buf_ptr + tb->used;
648 *flags = tb->flag_buf_ptr + tb->used;
649 tb->used += space;
650 }
651 return space;
652}
653
654EXPORT_SYMBOL_GPL(tty_prepare_flip_string_flags);
655
656
657
658/** 257/**
659 * get_tty_driver - find device of a tty 258 * get_tty_driver - find device of a tty
660 * @dev_t: device identifier 259 * @dev_t: device identifier
@@ -675,7 +274,7 @@ static struct tty_driver *get_tty_driver(dev_t device, int *index)
675 if (device < base || device >= base + p->num) 274 if (device < base || device >= base + p->num)
676 continue; 275 continue;
677 *index = device - base; 276 *index = device - base;
678 return p; 277 return tty_driver_kref_get(p);
679 } 278 }
680 return NULL; 279 return NULL;
681} 280}
@@ -719,7 +318,7 @@ struct tty_driver *tty_find_polling_driver(char *name, int *line)
719 318
720 if (tty_line >= 0 && tty_line <= p->num && p->ops && 319 if (tty_line >= 0 && tty_line <= p->num && p->ops &&
721 p->ops->poll_init && !p->ops->poll_init(p, tty_line, str)) { 320 p->ops->poll_init && !p->ops->poll_init(p, tty_line, str)) {
722 res = p; 321 res = tty_driver_kref_get(p);
723 *line = tty_line; 322 *line = tty_line;
724 break; 323 break;
725 } 324 }
@@ -819,20 +418,6 @@ static const struct file_operations tty_fops = {
819 .fasync = tty_fasync, 418 .fasync = tty_fasync,
820}; 419};
821 420
822#ifdef CONFIG_UNIX98_PTYS
823static const struct file_operations ptmx_fops = {
824 .llseek = no_llseek,
825 .read = tty_read,
826 .write = tty_write,
827 .poll = tty_poll,
828 .unlocked_ioctl = tty_ioctl,
829 .compat_ioctl = tty_compat_ioctl,
830 .open = ptmx_open,
831 .release = tty_release,
832 .fasync = tty_fasync,
833};
834#endif
835
836static const struct file_operations console_fops = { 421static const struct file_operations console_fops = {
837 .llseek = no_llseek, 422 .llseek = no_llseek,
838 .read = tty_read, 423 .read = tty_read,
@@ -953,6 +538,7 @@ static void do_tty_hangup(struct work_struct *work)
953 struct tty_ldisc *ld; 538 struct tty_ldisc *ld;
954 int closecount = 0, n; 539 int closecount = 0, n;
955 unsigned long flags; 540 unsigned long flags;
541 int refs = 0;
956 542
957 if (!tty) 543 if (!tty)
958 return; 544 return;
@@ -1019,8 +605,12 @@ static void do_tty_hangup(struct work_struct *work)
1019 if (tty->session) { 605 if (tty->session) {
1020 do_each_pid_task(tty->session, PIDTYPE_SID, p) { 606 do_each_pid_task(tty->session, PIDTYPE_SID, p) {
1021 spin_lock_irq(&p->sighand->siglock); 607 spin_lock_irq(&p->sighand->siglock);
1022 if (p->signal->tty == tty) 608 if (p->signal->tty == tty) {
1023 p->signal->tty = NULL; 609 p->signal->tty = NULL;
610 /* We defer the dereferences outside fo
611 the tasklist lock */
612 refs++;
613 }
1024 if (!p->signal->leader) { 614 if (!p->signal->leader) {
1025 spin_unlock_irq(&p->sighand->siglock); 615 spin_unlock_irq(&p->sighand->siglock);
1026 continue; 616 continue;
@@ -1046,6 +636,10 @@ static void do_tty_hangup(struct work_struct *work)
1046 tty->ctrl_status = 0; 636 tty->ctrl_status = 0;
1047 spin_unlock_irqrestore(&tty->ctrl_lock, flags); 637 spin_unlock_irqrestore(&tty->ctrl_lock, flags);
1048 638
639 /* Account for the p->signal references we killed */
640 while (refs--)
641 tty_kref_put(tty);
642
1049 /* 643 /*
1050 * If one of the devices matches a console pointer, we 644 * If one of the devices matches a console pointer, we
1051 * cannot just call hangup() because that will cause 645 * cannot just call hangup() because that will cause
@@ -1115,6 +709,23 @@ void tty_vhangup(struct tty_struct *tty)
1115EXPORT_SYMBOL(tty_vhangup); 709EXPORT_SYMBOL(tty_vhangup);
1116 710
1117/** 711/**
712 * tty_vhangup_self - process vhangup for own ctty
713 *
714 * Perform a vhangup on the current controlling tty
715 */
716
717void tty_vhangup_self(void)
718{
719 struct tty_struct *tty;
720
721 tty = get_current_tty();
722 if (tty) {
723 tty_vhangup(tty);
724 tty_kref_put(tty);
725 }
726}
727
728/**
1118 * tty_hung_up_p - was tty hung up 729 * tty_hung_up_p - was tty hung up
1119 * @filp: file pointer of tty 730 * @filp: file pointer of tty
1120 * 731 *
@@ -1167,16 +778,14 @@ void disassociate_ctty(int on_exit)
1167 struct pid *tty_pgrp = NULL; 778 struct pid *tty_pgrp = NULL;
1168 779
1169 780
1170 mutex_lock(&tty_mutex);
1171 tty = get_current_tty(); 781 tty = get_current_tty();
1172 if (tty) { 782 if (tty) {
1173 tty_pgrp = get_pid(tty->pgrp); 783 tty_pgrp = get_pid(tty->pgrp);
1174 lock_kernel(); 784 lock_kernel();
1175 mutex_unlock(&tty_mutex);
1176 /* XXX: here we race, there is nothing protecting tty */
1177 if (on_exit && tty->driver->type != TTY_DRIVER_TYPE_PTY) 785 if (on_exit && tty->driver->type != TTY_DRIVER_TYPE_PTY)
1178 tty_vhangup(tty); 786 tty_vhangup(tty);
1179 unlock_kernel(); 787 unlock_kernel();
788 tty_kref_put(tty);
1180 } else if (on_exit) { 789 } else if (on_exit) {
1181 struct pid *old_pgrp; 790 struct pid *old_pgrp;
1182 spin_lock_irq(&current->sighand->siglock); 791 spin_lock_irq(&current->sighand->siglock);
@@ -1188,7 +797,6 @@ void disassociate_ctty(int on_exit)
1188 kill_pgrp(old_pgrp, SIGCONT, on_exit); 797 kill_pgrp(old_pgrp, SIGCONT, on_exit);
1189 put_pid(old_pgrp); 798 put_pid(old_pgrp);
1190 } 799 }
1191 mutex_unlock(&tty_mutex);
1192 return; 800 return;
1193 } 801 }
1194 if (tty_pgrp) { 802 if (tty_pgrp) {
@@ -1203,8 +811,6 @@ void disassociate_ctty(int on_exit)
1203 current->signal->tty_old_pgrp = NULL; 811 current->signal->tty_old_pgrp = NULL;
1204 spin_unlock_irq(&current->sighand->siglock); 812 spin_unlock_irq(&current->sighand->siglock);
1205 813
1206 mutex_lock(&tty_mutex);
1207 /* It is possible that do_tty_hangup has free'd this tty */
1208 tty = get_current_tty(); 814 tty = get_current_tty();
1209 if (tty) { 815 if (tty) {
1210 unsigned long flags; 816 unsigned long flags;
@@ -1214,13 +820,13 @@ void disassociate_ctty(int on_exit)
1214 tty->session = NULL; 820 tty->session = NULL;
1215 tty->pgrp = NULL; 821 tty->pgrp = NULL;
1216 spin_unlock_irqrestore(&tty->ctrl_lock, flags); 822 spin_unlock_irqrestore(&tty->ctrl_lock, flags);
823 tty_kref_put(tty);
1217 } else { 824 } else {
1218#ifdef TTY_DEBUG_HANGUP 825#ifdef TTY_DEBUG_HANGUP
1219 printk(KERN_DEBUG "error attempted to write to tty [0x%p]" 826 printk(KERN_DEBUG "error attempted to write to tty [0x%p]"
1220 " = NULL", tty); 827 " = NULL", tty);
1221#endif 828#endif
1222 } 829 }
1223 mutex_unlock(&tty_mutex);
1224 830
1225 /* Now clear signal->tty under the lock */ 831 /* Now clear signal->tty under the lock */
1226 read_lock(&tasklist_lock); 832 read_lock(&tasklist_lock);
@@ -1420,19 +1026,19 @@ static inline ssize_t do_tty_write(
1420 1026
1421 /* write_buf/write_cnt is protected by the atomic_write_lock mutex */ 1027 /* write_buf/write_cnt is protected by the atomic_write_lock mutex */
1422 if (tty->write_cnt < chunk) { 1028 if (tty->write_cnt < chunk) {
1423 unsigned char *buf; 1029 unsigned char *buf_chunk;
1424 1030
1425 if (chunk < 1024) 1031 if (chunk < 1024)
1426 chunk = 1024; 1032 chunk = 1024;
1427 1033
1428 buf = kmalloc(chunk, GFP_KERNEL); 1034 buf_chunk = kmalloc(chunk, GFP_KERNEL);
1429 if (!buf) { 1035 if (!buf_chunk) {
1430 ret = -ENOMEM; 1036 ret = -ENOMEM;
1431 goto out; 1037 goto out;
1432 } 1038 }
1433 kfree(tty->write_buf); 1039 kfree(tty->write_buf);
1434 tty->write_cnt = chunk; 1040 tty->write_cnt = chunk;
1435 tty->write_buf = buf; 1041 tty->write_buf = buf_chunk;
1436 } 1042 }
1437 1043
1438 /* Do the write .. */ 1044 /* Do the write .. */
@@ -1466,6 +1072,31 @@ out:
1466 return ret; 1072 return ret;
1467} 1073}
1468 1074
1075/**
1076 * tty_write_message - write a message to a certain tty, not just the console.
1077 * @tty: the destination tty_struct
1078 * @msg: the message to write
1079 *
1080 * This is used for messages that need to be redirected to a specific tty.
1081 * We don't put it into the syslog queue right now maybe in the future if
1082 * really needed.
1083 *
1084 * We must still hold the BKL and test the CLOSING flag for the moment.
1085 */
1086
1087void tty_write_message(struct tty_struct *tty, char *msg)
1088{
1089 lock_kernel();
1090 if (tty) {
1091 mutex_lock(&tty->atomic_write_lock);
1092 if (tty->ops->write && !test_bit(TTY_CLOSING, &tty->flags))
1093 tty->ops->write(tty, msg, strlen(msg));
1094 tty_write_unlock(tty);
1095 }
1096 unlock_kernel();
1097 return;
1098}
1099
1469 1100
1470/** 1101/**
1471 * tty_write - write method for tty device file 1102 * tty_write - write method for tty device file
@@ -1533,42 +1164,6 @@ ssize_t redirected_tty_write(struct file *file, const char __user *buf,
1533 return tty_write(file, buf, count, ppos); 1164 return tty_write(file, buf, count, ppos);
1534} 1165}
1535 1166
1536void tty_port_init(struct tty_port *port)
1537{
1538 memset(port, 0, sizeof(*port));
1539 init_waitqueue_head(&port->open_wait);
1540 init_waitqueue_head(&port->close_wait);
1541 mutex_init(&port->mutex);
1542 port->close_delay = (50 * HZ) / 100;
1543 port->closing_wait = (3000 * HZ) / 100;
1544}
1545EXPORT_SYMBOL(tty_port_init);
1546
1547int tty_port_alloc_xmit_buf(struct tty_port *port)
1548{
1549 /* We may sleep in get_zeroed_page() */
1550 mutex_lock(&port->mutex);
1551 if (port->xmit_buf == NULL)
1552 port->xmit_buf = (unsigned char *)get_zeroed_page(GFP_KERNEL);
1553 mutex_unlock(&port->mutex);
1554 if (port->xmit_buf == NULL)
1555 return -ENOMEM;
1556 return 0;
1557}
1558EXPORT_SYMBOL(tty_port_alloc_xmit_buf);
1559
1560void tty_port_free_xmit_buf(struct tty_port *port)
1561{
1562 mutex_lock(&port->mutex);
1563 if (port->xmit_buf != NULL) {
1564 free_page((unsigned long)port->xmit_buf);
1565 port->xmit_buf = NULL;
1566 }
1567 mutex_unlock(&port->mutex);
1568}
1569EXPORT_SYMBOL(tty_port_free_xmit_buf);
1570
1571
1572static char ptychar[] = "pqrstuvwxyzabcde"; 1167static char ptychar[] = "pqrstuvwxyzabcde";
1573 1168
1574/** 1169/**
@@ -1592,7 +1187,7 @@ static void pty_line_name(struct tty_driver *driver, int index, char *p)
1592} 1187}
1593 1188
1594/** 1189/**
1595 * pty_line_name - generate name for a tty 1190 * tty_line_name - generate name for a tty
1596 * @driver: the tty driver in use 1191 * @driver: the tty driver in use
1597 * @index: the minor number 1192 * @index: the minor number
1598 * @p: output buffer of at least 7 bytes 1193 * @p: output buffer of at least 7 bytes
@@ -1608,10 +1203,148 @@ static void tty_line_name(struct tty_driver *driver, int index, char *p)
1608} 1203}
1609 1204
1610/** 1205/**
1611 * init_dev - initialise a tty device 1206 * tty_driver_lookup_tty() - find an existing tty, if any
1207 * @driver: the driver for the tty
1208 * @idx: the minor number
1209 *
1210 * Return the tty, if found or ERR_PTR() otherwise.
1211 *
1212 * Locking: tty_mutex must be held. If tty is found, the mutex must
1213 * be held until the 'fast-open' is also done. Will change once we
1214 * have refcounting in the driver and per driver locking
1215 */
1216struct tty_struct *tty_driver_lookup_tty(struct tty_driver *driver,
1217 struct inode *inode, int idx)
1218{
1219 struct tty_struct *tty;
1220
1221 if (driver->ops->lookup)
1222 return driver->ops->lookup(driver, inode, idx);
1223
1224 tty = driver->ttys[idx];
1225 return tty;
1226}
1227
1228/**
1229 * tty_init_termios - helper for termios setup
1230 * @tty: the tty to set up
1231 *
1232 * Initialise the termios structures for this tty. Thus runs under
1233 * the tty_mutex currently so we can be relaxed about ordering.
1234 */
1235
1236int tty_init_termios(struct tty_struct *tty)
1237{
1238 struct ktermios *tp;
1239 int idx = tty->index;
1240
1241 tp = tty->driver->termios[idx];
1242 if (tp == NULL) {
1243 tp = kzalloc(sizeof(struct ktermios[2]), GFP_KERNEL);
1244 if (tp == NULL)
1245 return -ENOMEM;
1246 memcpy(tp, &tty->driver->init_termios,
1247 sizeof(struct ktermios));
1248 tty->driver->termios[idx] = tp;
1249 }
1250 tty->termios = tp;
1251 tty->termios_locked = tp + 1;
1252
1253 /* Compatibility until drivers always set this */
1254 tty->termios->c_ispeed = tty_termios_input_baud_rate(tty->termios);
1255 tty->termios->c_ospeed = tty_termios_baud_rate(tty->termios);
1256 return 0;
1257}
1258
1259/**
1260 * tty_driver_install_tty() - install a tty entry in the driver
1261 * @driver: the driver for the tty
1262 * @tty: the tty
1263 *
1264 * Install a tty object into the driver tables. The tty->index field
1265 * will be set by the time this is called. This method is responsible
1266 * for ensuring any need additional structures are allocated and
1267 * configured.
1268 *
1269 * Locking: tty_mutex for now
1270 */
1271static int tty_driver_install_tty(struct tty_driver *driver,
1272 struct tty_struct *tty)
1273{
1274 int idx = tty->index;
1275
1276 if (driver->ops->install)
1277 return driver->ops->install(driver, tty);
1278
1279 if (tty_init_termios(tty) == 0) {
1280 tty_driver_kref_get(driver);
1281 tty->count++;
1282 driver->ttys[idx] = tty;
1283 return 0;
1284 }
1285 return -ENOMEM;
1286}
1287
1288/**
1289 * tty_driver_remove_tty() - remove a tty from the driver tables
1290 * @driver: the driver for the tty
1291 * @idx: the minor number
1292 *
1293 * Remvoe a tty object from the driver tables. The tty->index field
1294 * will be set by the time this is called.
1295 *
1296 * Locking: tty_mutex for now
1297 */
1298static void tty_driver_remove_tty(struct tty_driver *driver,
1299 struct tty_struct *tty)
1300{
1301 if (driver->ops->remove)
1302 driver->ops->remove(driver, tty);
1303 else
1304 driver->ttys[tty->index] = NULL;
1305}
1306
1307/*
1308 * tty_reopen() - fast re-open of an open tty
1309 * @tty - the tty to open
1310 *
1311 * Return 0 on success, -errno on error.
1312 *
1313 * Locking: tty_mutex must be held from the time the tty was found
1314 * till this open completes.
1315 */
1316static int tty_reopen(struct tty_struct *tty)
1317{
1318 struct tty_driver *driver = tty->driver;
1319
1320 if (test_bit(TTY_CLOSING, &tty->flags))
1321 return -EIO;
1322
1323 if (driver->type == TTY_DRIVER_TYPE_PTY &&
1324 driver->subtype == PTY_TYPE_MASTER) {
1325 /*
1326 * special case for PTY masters: only one open permitted,
1327 * and the slave side open count is incremented as well.
1328 */
1329 if (tty->count)
1330 return -EIO;
1331
1332 tty->link->count++;
1333 }
1334 tty->count++;
1335 tty->driver = driver; /* N.B. why do this every time?? */
1336
1337 WARN_ON(!test_bit(TTY_LDISC, &tty->flags));
1338
1339 return 0;
1340}
1341
1342/**
1343 * tty_init_dev - initialise a tty device
1612 * @driver: tty driver we are opening a device on 1344 * @driver: tty driver we are opening a device on
1613 * @idx: device index 1345 * @idx: device index
1614 * @tty: returned tty structure 1346 * @ret_tty: returned tty structure
1347 * @first_ok: ok to open a new device (used by ptmx)
1615 * 1348 *
1616 * Prepare a tty device. This may not be a "new" clean device but 1349 * Prepare a tty device. This may not be a "new" clean device but
1617 * could also be an active device. The pty drivers require special 1350 * could also be an active device. The pty drivers require special
@@ -1631,37 +1364,16 @@ static void tty_line_name(struct tty_driver *driver, int index, char *p)
1631 * relaxed for the (most common) case of reopening a tty. 1364 * relaxed for the (most common) case of reopening a tty.
1632 */ 1365 */
1633 1366
1634static int init_dev(struct tty_driver *driver, int idx, 1367struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx,
1635 struct tty_struct **ret_tty) 1368 int first_ok)
1636{ 1369{
1637 struct tty_struct *tty, *o_tty; 1370 struct tty_struct *tty;
1638 struct ktermios *tp, **tp_loc, *o_tp, **o_tp_loc; 1371 int retval;
1639 struct ktermios *ltp, **ltp_loc, *o_ltp, **o_ltp_loc;
1640 int retval = 0;
1641 1372
1642 /* check whether we're reopening an existing tty */ 1373 /* Check if pty master is being opened multiple times */
1643 if (driver->flags & TTY_DRIVER_DEVPTS_MEM) { 1374 if (driver->subtype == PTY_TYPE_MASTER &&
1644 tty = devpts_get_tty(idx); 1375 (driver->flags & TTY_DRIVER_DEVPTS_MEM) && !first_ok)
1645 /* 1376 return ERR_PTR(-EIO);
1646 * If we don't have a tty here on a slave open, it's because
1647 * the master already started the close process and there's
1648 * no relation between devpts file and tty anymore.
1649 */
1650 if (!tty && driver->subtype == PTY_TYPE_SLAVE) {
1651 retval = -EIO;
1652 goto end_init;
1653 }
1654 /*
1655 * It's safe from now on because init_dev() is called with
1656 * tty_mutex held and release_dev() won't change tty->count
1657 * or tty->flags without having to grab tty_mutex
1658 */
1659 if (tty && driver->subtype == PTY_TYPE_MASTER)
1660 tty = tty->link;
1661 } else {
1662 tty = driver->ttys[idx];
1663 }
1664 if (tty) goto fast_track;
1665 1377
1666 /* 1378 /*
1667 * First time open is complex, especially for PTY devices. 1379 * First time open is complex, especially for PTY devices.
@@ -1671,189 +1383,69 @@ static int init_dev(struct tty_driver *driver, int idx,
1671 * and locked termios may be retained.) 1383 * and locked termios may be retained.)
1672 */ 1384 */
1673 1385
1674 if (!try_module_get(driver->owner)) { 1386 if (!try_module_get(driver->owner))
1675 retval = -ENODEV; 1387 return ERR_PTR(-ENODEV);
1676 goto end_init;
1677 }
1678
1679 o_tty = NULL;
1680 tp = o_tp = NULL;
1681 ltp = o_ltp = NULL;
1682 1388
1683 tty = alloc_tty_struct(); 1389 tty = alloc_tty_struct();
1684 if (!tty) 1390 if (!tty)
1685 goto fail_no_mem; 1391 goto fail_no_mem;
1686 initialize_tty_struct(tty); 1392 initialize_tty_struct(tty, driver, idx);
1687 tty->driver = driver;
1688 tty->ops = driver->ops;
1689 tty->index = idx;
1690 tty_line_name(driver, idx, tty->name);
1691
1692 if (driver->flags & TTY_DRIVER_DEVPTS_MEM) {
1693 tp_loc = &tty->termios;
1694 ltp_loc = &tty->termios_locked;
1695 } else {
1696 tp_loc = &driver->termios[idx];
1697 ltp_loc = &driver->termios_locked[idx];
1698 }
1699
1700 if (!*tp_loc) {
1701 tp = kmalloc(sizeof(struct ktermios), GFP_KERNEL);
1702 if (!tp)
1703 goto free_mem_out;
1704 *tp = driver->init_termios;
1705 }
1706
1707 if (!*ltp_loc) {
1708 ltp = kzalloc(sizeof(struct ktermios), GFP_KERNEL);
1709 if (!ltp)
1710 goto free_mem_out;
1711 }
1712
1713 if (driver->type == TTY_DRIVER_TYPE_PTY) {
1714 o_tty = alloc_tty_struct();
1715 if (!o_tty)
1716 goto free_mem_out;
1717 initialize_tty_struct(o_tty);
1718 o_tty->driver = driver->other;
1719 o_tty->ops = driver->ops;
1720 o_tty->index = idx;
1721 tty_line_name(driver->other, idx, o_tty->name);
1722 1393
1723 if (driver->flags & TTY_DRIVER_DEVPTS_MEM) { 1394 retval = tty_driver_install_tty(driver, tty);
1724 o_tp_loc = &o_tty->termios; 1395 if (retval < 0) {
1725 o_ltp_loc = &o_tty->termios_locked; 1396 free_tty_struct(tty);
1726 } else { 1397 module_put(driver->owner);
1727 o_tp_loc = &driver->other->termios[idx]; 1398 return ERR_PTR(retval);
1728 o_ltp_loc = &driver->other->termios_locked[idx];
1729 }
1730
1731 if (!*o_tp_loc) {
1732 o_tp = kmalloc(sizeof(struct ktermios), GFP_KERNEL);
1733 if (!o_tp)
1734 goto free_mem_out;
1735 *o_tp = driver->other->init_termios;
1736 }
1737
1738 if (!*o_ltp_loc) {
1739 o_ltp = kzalloc(sizeof(struct ktermios), GFP_KERNEL);
1740 if (!o_ltp)
1741 goto free_mem_out;
1742 }
1743
1744 /*
1745 * Everything allocated ... set up the o_tty structure.
1746 */
1747 if (!(driver->other->flags & TTY_DRIVER_DEVPTS_MEM))
1748 driver->other->ttys[idx] = o_tty;
1749 if (!*o_tp_loc)
1750 *o_tp_loc = o_tp;
1751 if (!*o_ltp_loc)
1752 *o_ltp_loc = o_ltp;
1753 o_tty->termios = *o_tp_loc;
1754 o_tty->termios_locked = *o_ltp_loc;
1755 driver->other->refcount++;
1756 if (driver->subtype == PTY_TYPE_MASTER)
1757 o_tty->count++;
1758
1759 /* Establish the links in both directions */
1760 tty->link = o_tty;
1761 o_tty->link = tty;
1762 } 1399 }
1763 1400
1764 /* 1401 /*
1765 * All structures have been allocated, so now we install them.
1766 * Failures after this point use release_tty to clean up, so
1767 * there's no need to null out the local pointers.
1768 */
1769 if (!(driver->flags & TTY_DRIVER_DEVPTS_MEM))
1770 driver->ttys[idx] = tty;
1771
1772 if (!*tp_loc)
1773 *tp_loc = tp;
1774 if (!*ltp_loc)
1775 *ltp_loc = ltp;
1776 tty->termios = *tp_loc;
1777 tty->termios_locked = *ltp_loc;
1778 /* Compatibility until drivers always set this */
1779 tty->termios->c_ispeed = tty_termios_input_baud_rate(tty->termios);
1780 tty->termios->c_ospeed = tty_termios_baud_rate(tty->termios);
1781 driver->refcount++;
1782 tty->count++;
1783
1784 /*
1785 * Structures all installed ... call the ldisc open routines. 1402 * Structures all installed ... call the ldisc open routines.
1786 * If we fail here just call release_tty to clean up. No need 1403 * If we fail here just call release_tty to clean up. No need
1787 * to decrement the use counts, as release_tty doesn't care. 1404 * to decrement the use counts, as release_tty doesn't care.
1788 */ 1405 */
1789 1406
1790 retval = tty_ldisc_setup(tty, o_tty); 1407 retval = tty_ldisc_setup(tty, tty->link);
1791
1792 if (retval) 1408 if (retval)
1793 goto release_mem_out; 1409 goto release_mem_out;
1794 goto success; 1410 return tty;
1795
1796 /*
1797 * This fast open can be used if the tty is already open.
1798 * No memory is allocated, and the only failures are from
1799 * attempting to open a closing tty or attempting multiple
1800 * opens on a pty master.
1801 */
1802fast_track:
1803 if (test_bit(TTY_CLOSING, &tty->flags)) {
1804 retval = -EIO;
1805 goto end_init;
1806 }
1807 if (driver->type == TTY_DRIVER_TYPE_PTY &&
1808 driver->subtype == PTY_TYPE_MASTER) {
1809 /*
1810 * special case for PTY masters: only one open permitted,
1811 * and the slave side open count is incremented as well.
1812 */
1813 if (tty->count) {
1814 retval = -EIO;
1815 goto end_init;
1816 }
1817 tty->link->count++;
1818 }
1819 tty->count++;
1820 tty->driver = driver; /* N.B. why do this every time?? */
1821
1822 /* FIXME */
1823 if (!test_bit(TTY_LDISC, &tty->flags))
1824 printk(KERN_ERR "init_dev but no ldisc\n");
1825success:
1826 *ret_tty = tty;
1827
1828 /* All paths come through here to release the mutex */
1829end_init:
1830 return retval;
1831
1832 /* Release locally allocated memory ... nothing placed in slots */
1833free_mem_out:
1834 kfree(o_tp);
1835 if (o_tty)
1836 free_tty_struct(o_tty);
1837 kfree(ltp);
1838 kfree(tp);
1839 free_tty_struct(tty);
1840 1411
1841fail_no_mem: 1412fail_no_mem:
1842 module_put(driver->owner); 1413 module_put(driver->owner);
1843 retval = -ENOMEM; 1414 return ERR_PTR(-ENOMEM);
1844 goto end_init;
1845 1415
1846 /* call the tty release_tty routine to clean out this slot */ 1416 /* call the tty release_tty routine to clean out this slot */
1847release_mem_out: 1417release_mem_out:
1848 if (printk_ratelimit()) 1418 if (printk_ratelimit())
1849 printk(KERN_INFO "init_dev: ldisc open failed, " 1419 printk(KERN_INFO "tty_init_dev: ldisc open failed, "
1850 "clearing slot %d\n", idx); 1420 "clearing slot %d\n", idx);
1851 release_tty(tty, idx); 1421 release_tty(tty, idx);
1852 goto end_init; 1422 return ERR_PTR(retval);
1853} 1423}
1854 1424
1425void tty_free_termios(struct tty_struct *tty)
1426{
1427 struct ktermios *tp;
1428 int idx = tty->index;
1429 /* Kill this flag and push into drivers for locking etc */
1430 if (tty->driver->flags & TTY_DRIVER_RESET_TERMIOS) {
1431 /* FIXME: Locking on ->termios array */
1432 tp = tty->termios;
1433 tty->driver->termios[idx] = NULL;
1434 kfree(tp);
1435 }
1436}
1437EXPORT_SYMBOL(tty_free_termios);
1438
1439void tty_shutdown(struct tty_struct *tty)
1440{
1441 tty_driver_remove_tty(tty->driver, tty);
1442 tty_free_termios(tty);
1443}
1444EXPORT_SYMBOL(tty_shutdown);
1445
1855/** 1446/**
1856 * release_one_tty - release tty structure memory 1447 * release_one_tty - release tty structure memory
1448 * @kref: kref of tty we are obliterating
1857 * 1449 *
1858 * Releases memory associated with a tty structure, and clears out the 1450 * Releases memory associated with a tty structure, and clears out the
1859 * driver table slots. This function is called when a device is no longer 1451 * driver table slots. This function is called when a device is no longer
@@ -1863,31 +1455,19 @@ release_mem_out:
1863 * tty_mutex - sometimes only 1455 * tty_mutex - sometimes only
1864 * takes the file list lock internally when working on the list 1456 * takes the file list lock internally when working on the list
1865 * of ttys that the driver keeps. 1457 * of ttys that the driver keeps.
1866 * FIXME: should we require tty_mutex is held here ??
1867 */ 1458 */
1868static void release_one_tty(struct tty_struct *tty, int idx) 1459static void release_one_tty(struct kref *kref)
1869{ 1460{
1870 int devpts = tty->driver->flags & TTY_DRIVER_DEVPTS_MEM; 1461 struct tty_struct *tty = container_of(kref, struct tty_struct, kref);
1871 struct ktermios *tp; 1462 struct tty_driver *driver = tty->driver;
1872
1873 if (!devpts)
1874 tty->driver->ttys[idx] = NULL;
1875
1876 if (tty->driver->flags & TTY_DRIVER_RESET_TERMIOS) {
1877 tp = tty->termios;
1878 if (!devpts)
1879 tty->driver->termios[idx] = NULL;
1880 kfree(tp);
1881
1882 tp = tty->termios_locked;
1883 if (!devpts)
1884 tty->driver->termios_locked[idx] = NULL;
1885 kfree(tp);
1886 }
1887
1888 1463
1464 if (tty->ops->shutdown)
1465 tty->ops->shutdown(tty);
1466 else
1467 tty_shutdown(tty);
1889 tty->magic = 0; 1468 tty->magic = 0;
1890 tty->driver->refcount--; 1469 tty_driver_kref_put(driver);
1470 module_put(driver->owner);
1891 1471
1892 file_list_lock(); 1472 file_list_lock();
1893 list_del_init(&tty->tty_files); 1473 list_del_init(&tty->tty_files);
@@ -1897,6 +1477,21 @@ static void release_one_tty(struct tty_struct *tty, int idx)
1897} 1477}
1898 1478
1899/** 1479/**
1480 * tty_kref_put - release a tty kref
1481 * @tty: tty device
1482 *
1483 * Release a reference to a tty device and if need be let the kref
1484 * layer destruct the object for us
1485 */
1486
1487void tty_kref_put(struct tty_struct *tty)
1488{
1489 if (tty)
1490 kref_put(&tty->kref, release_one_tty);
1491}
1492EXPORT_SYMBOL(tty_kref_put);
1493
1494/**
1900 * release_tty - release tty structure memory 1495 * release_tty - release tty structure memory
1901 * 1496 *
1902 * Release both @tty and a possible linked partner (think pty pair), 1497 * Release both @tty and a possible linked partner (think pty pair),
@@ -1907,15 +1502,16 @@ static void release_one_tty(struct tty_struct *tty, int idx)
1907 * takes the file list lock internally when working on the list 1502 * takes the file list lock internally when working on the list
1908 * of ttys that the driver keeps. 1503 * of ttys that the driver keeps.
1909 * FIXME: should we require tty_mutex is held here ?? 1504 * FIXME: should we require tty_mutex is held here ??
1505 *
1910 */ 1506 */
1911static void release_tty(struct tty_struct *tty, int idx) 1507static void release_tty(struct tty_struct *tty, int idx)
1912{ 1508{
1913 struct tty_driver *driver = tty->driver; 1509 /* This should always be true but check for the moment */
1510 WARN_ON(tty->index != idx);
1914 1511
1915 if (tty->link) 1512 if (tty->link)
1916 release_one_tty(tty->link, idx); 1513 tty_kref_put(tty->link);
1917 release_one_tty(tty, idx); 1514 tty_kref_put(tty);
1918 module_put(driver->owner);
1919} 1515}
1920 1516
1921/* 1517/*
@@ -1926,20 +1522,21 @@ static void release_tty(struct tty_struct *tty, int idx)
1926 * WSH 09/09/97: rewritten to avoid some nasty race conditions that could 1522 * WSH 09/09/97: rewritten to avoid some nasty race conditions that could
1927 * lead to double frees or releasing memory still in use. 1523 * lead to double frees or releasing memory still in use.
1928 */ 1524 */
1929static void release_dev(struct file *filp) 1525void tty_release_dev(struct file *filp)
1930{ 1526{
1931 struct tty_struct *tty, *o_tty; 1527 struct tty_struct *tty, *o_tty;
1932 int pty_master, tty_closing, o_tty_closing, do_sleep; 1528 int pty_master, tty_closing, o_tty_closing, do_sleep;
1933 int devpts; 1529 int devpts;
1934 int idx; 1530 int idx;
1935 char buf[64]; 1531 char buf[64];
1532 struct inode *inode;
1936 1533
1534 inode = filp->f_path.dentry->d_inode;
1937 tty = (struct tty_struct *)filp->private_data; 1535 tty = (struct tty_struct *)filp->private_data;
1938 if (tty_paranoia_check(tty, filp->f_path.dentry->d_inode, 1536 if (tty_paranoia_check(tty, inode, "tty_release_dev"))
1939 "release_dev"))
1940 return; 1537 return;
1941 1538
1942 check_tty_count(tty, "release_dev"); 1539 check_tty_count(tty, "tty_release_dev");
1943 1540
1944 tty_fasync(-1, filp, 0); 1541 tty_fasync(-1, filp, 0);
1945 1542
@@ -1951,33 +1548,27 @@ static void release_dev(struct file *filp)
1951 1548
1952#ifdef TTY_PARANOIA_CHECK 1549#ifdef TTY_PARANOIA_CHECK
1953 if (idx < 0 || idx >= tty->driver->num) { 1550 if (idx < 0 || idx >= tty->driver->num) {
1954 printk(KERN_DEBUG "release_dev: bad idx when trying to " 1551 printk(KERN_DEBUG "tty_release_dev: bad idx when trying to "
1955 "free (%s)\n", tty->name); 1552 "free (%s)\n", tty->name);
1956 return; 1553 return;
1957 } 1554 }
1958 if (!(tty->driver->flags & TTY_DRIVER_DEVPTS_MEM)) { 1555 if (!devpts) {
1959 if (tty != tty->driver->ttys[idx]) { 1556 if (tty != tty->driver->ttys[idx]) {
1960 printk(KERN_DEBUG "release_dev: driver.table[%d] not tty " 1557 printk(KERN_DEBUG "tty_release_dev: driver.table[%d] not tty "
1961 "for (%s)\n", idx, tty->name); 1558 "for (%s)\n", idx, tty->name);
1962 return; 1559 return;
1963 } 1560 }
1964 if (tty->termios != tty->driver->termios[idx]) { 1561 if (tty->termios != tty->driver->termios[idx]) {
1965 printk(KERN_DEBUG "release_dev: driver.termios[%d] not termios " 1562 printk(KERN_DEBUG "tty_release_dev: driver.termios[%d] not termios "
1966 "for (%s)\n", 1563 "for (%s)\n",
1967 idx, tty->name); 1564 idx, tty->name);
1968 return; 1565 return;
1969 } 1566 }
1970 if (tty->termios_locked != tty->driver->termios_locked[idx]) {
1971 printk(KERN_DEBUG "release_dev: driver.termios_locked[%d] not "
1972 "termios_locked for (%s)\n",
1973 idx, tty->name);
1974 return;
1975 }
1976 } 1567 }
1977#endif 1568#endif
1978 1569
1979#ifdef TTY_DEBUG_HANGUP 1570#ifdef TTY_DEBUG_HANGUP
1980 printk(KERN_DEBUG "release_dev of %s (tty count=%d)...", 1571 printk(KERN_DEBUG "tty_release_dev of %s (tty count=%d)...",
1981 tty_name(tty, buf), tty->count); 1572 tty_name(tty, buf), tty->count);
1982#endif 1573#endif
1983 1574
@@ -1985,26 +1576,19 @@ static void release_dev(struct file *filp)
1985 if (tty->driver->other && 1576 if (tty->driver->other &&
1986 !(tty->driver->flags & TTY_DRIVER_DEVPTS_MEM)) { 1577 !(tty->driver->flags & TTY_DRIVER_DEVPTS_MEM)) {
1987 if (o_tty != tty->driver->other->ttys[idx]) { 1578 if (o_tty != tty->driver->other->ttys[idx]) {
1988 printk(KERN_DEBUG "release_dev: other->table[%d] " 1579 printk(KERN_DEBUG "tty_release_dev: other->table[%d] "
1989 "not o_tty for (%s)\n", 1580 "not o_tty for (%s)\n",
1990 idx, tty->name); 1581 idx, tty->name);
1991 return; 1582 return;
1992 } 1583 }
1993 if (o_tty->termios != tty->driver->other->termios[idx]) { 1584 if (o_tty->termios != tty->driver->other->termios[idx]) {
1994 printk(KERN_DEBUG "release_dev: other->termios[%d] " 1585 printk(KERN_DEBUG "tty_release_dev: other->termios[%d] "
1995 "not o_termios for (%s)\n", 1586 "not o_termios for (%s)\n",
1996 idx, tty->name); 1587 idx, tty->name);
1997 return; 1588 return;
1998 } 1589 }
1999 if (o_tty->termios_locked !=
2000 tty->driver->other->termios_locked[idx]) {
2001 printk(KERN_DEBUG "release_dev: other->termios_locked["
2002 "%d] not o_termios_locked for (%s)\n",
2003 idx, tty->name);
2004 return;
2005 }
2006 if (o_tty->link != tty) { 1590 if (o_tty->link != tty) {
2007 printk(KERN_DEBUG "release_dev: bad pty pointers\n"); 1591 printk(KERN_DEBUG "tty_release_dev: bad pty pointers\n");
2008 return; 1592 return;
2009 } 1593 }
2010 } 1594 }
@@ -2062,7 +1646,7 @@ static void release_dev(struct file *filp)
2062 if (!do_sleep) 1646 if (!do_sleep)
2063 break; 1647 break;
2064 1648
2065 printk(KERN_WARNING "release_dev: %s: read/write wait queue " 1649 printk(KERN_WARNING "tty_release_dev: %s: read/write wait queue "
2066 "active!\n", tty_name(tty, buf)); 1650 "active!\n", tty_name(tty, buf));
2067 mutex_unlock(&tty_mutex); 1651 mutex_unlock(&tty_mutex);
2068 schedule(); 1652 schedule();
@@ -2075,14 +1659,14 @@ static void release_dev(struct file *filp)
2075 */ 1659 */
2076 if (pty_master) { 1660 if (pty_master) {
2077 if (--o_tty->count < 0) { 1661 if (--o_tty->count < 0) {
2078 printk(KERN_WARNING "release_dev: bad pty slave count " 1662 printk(KERN_WARNING "tty_release_dev: bad pty slave count "
2079 "(%d) for %s\n", 1663 "(%d) for %s\n",
2080 o_tty->count, tty_name(o_tty, buf)); 1664 o_tty->count, tty_name(o_tty, buf));
2081 o_tty->count = 0; 1665 o_tty->count = 0;
2082 } 1666 }
2083 } 1667 }
2084 if (--tty->count < 0) { 1668 if (--tty->count < 0) {
2085 printk(KERN_WARNING "release_dev: bad tty->count (%d) for %s\n", 1669 printk(KERN_WARNING "tty_release_dev: bad tty->count (%d) for %s\n",
2086 tty->count, tty_name(tty, buf)); 1670 tty->count, tty_name(tty, buf));
2087 tty->count = 0; 1671 tty->count = 0;
2088 } 1672 }
@@ -2145,11 +1729,11 @@ static void release_dev(struct file *filp)
2145 1729
2146 /* Make this pty number available for reallocation */ 1730 /* Make this pty number available for reallocation */
2147 if (devpts) 1731 if (devpts)
2148 devpts_kill_index(idx); 1732 devpts_kill_index(inode, idx);
2149} 1733}
2150 1734
2151/** 1735/**
2152 * tty_open - open a tty device 1736 * __tty_open - open a tty device
2153 * @inode: inode of device file 1737 * @inode: inode of device file
2154 * @filp: file pointer to tty 1738 * @filp: file pointer to tty
2155 * 1739 *
@@ -2164,14 +1748,14 @@ static void release_dev(struct file *filp)
2164 * The termios state of a pty is reset on first open so that 1748 * The termios state of a pty is reset on first open so that
2165 * settings don't persist across reuse. 1749 * settings don't persist across reuse.
2166 * 1750 *
2167 * Locking: tty_mutex protects tty, get_tty_driver and init_dev work. 1751 * Locking: tty_mutex protects tty, get_tty_driver and tty_init_dev work.
2168 * tty->count should protect the rest. 1752 * tty->count should protect the rest.
2169 * ->siglock protects ->signal/->sighand 1753 * ->siglock protects ->signal/->sighand
2170 */ 1754 */
2171 1755
2172static int __tty_open(struct inode *inode, struct file *filp) 1756static int __tty_open(struct inode *inode, struct file *filp)
2173{ 1757{
2174 struct tty_struct *tty; 1758 struct tty_struct *tty = NULL;
2175 int noctty, retval; 1759 int noctty, retval;
2176 struct tty_driver *driver; 1760 struct tty_driver *driver;
2177 int index; 1761 int index;
@@ -2193,23 +1777,25 @@ retry_open:
2193 mutex_unlock(&tty_mutex); 1777 mutex_unlock(&tty_mutex);
2194 return -ENXIO; 1778 return -ENXIO;
2195 } 1779 }
2196 driver = tty->driver; 1780 driver = tty_driver_kref_get(tty->driver);
2197 index = tty->index; 1781 index = tty->index;
2198 filp->f_flags |= O_NONBLOCK; /* Don't let /dev/tty block */ 1782 filp->f_flags |= O_NONBLOCK; /* Don't let /dev/tty block */
2199 /* noctty = 1; */ 1783 /* noctty = 1; */
1784 /* FIXME: Should we take a driver reference ? */
1785 tty_kref_put(tty);
2200 goto got_driver; 1786 goto got_driver;
2201 } 1787 }
2202#ifdef CONFIG_VT 1788#ifdef CONFIG_VT
2203 if (device == MKDEV(TTY_MAJOR, 0)) { 1789 if (device == MKDEV(TTY_MAJOR, 0)) {
2204 extern struct tty_driver *console_driver; 1790 extern struct tty_driver *console_driver;
2205 driver = console_driver; 1791 driver = tty_driver_kref_get(console_driver);
2206 index = fg_console; 1792 index = fg_console;
2207 noctty = 1; 1793 noctty = 1;
2208 goto got_driver; 1794 goto got_driver;
2209 } 1795 }
2210#endif 1796#endif
2211 if (device == MKDEV(TTYAUX_MAJOR, 1)) { 1797 if (device == MKDEV(TTYAUX_MAJOR, 1)) {
2212 driver = console_device(&index); 1798 driver = tty_driver_kref_get(console_device(&index));
2213 if (driver) { 1799 if (driver) {
2214 /* Don't let /dev/console block */ 1800 /* Don't let /dev/console block */
2215 filp->f_flags |= O_NONBLOCK; 1801 filp->f_flags |= O_NONBLOCK;
@@ -2226,10 +1812,25 @@ retry_open:
2226 return -ENODEV; 1812 return -ENODEV;
2227 } 1813 }
2228got_driver: 1814got_driver:
2229 retval = init_dev(driver, index, &tty); 1815 if (!tty) {
1816 /* check whether we're reopening an existing tty */
1817 tty = tty_driver_lookup_tty(driver, inode, index);
1818
1819 if (IS_ERR(tty))
1820 return PTR_ERR(tty);
1821 }
1822
1823 if (tty) {
1824 retval = tty_reopen(tty);
1825 if (retval)
1826 tty = ERR_PTR(retval);
1827 } else
1828 tty = tty_init_dev(driver, index, 0);
1829
2230 mutex_unlock(&tty_mutex); 1830 mutex_unlock(&tty_mutex);
2231 if (retval) 1831 tty_driver_kref_put(driver);
2232 return retval; 1832 if (IS_ERR(tty))
1833 return PTR_ERR(tty);
2233 1834
2234 filp->private_data = tty; 1835 filp->private_data = tty;
2235 file_move(filp, &tty->tty_files); 1836 file_move(filp, &tty->tty_files);
@@ -2257,7 +1858,7 @@ got_driver:
2257 printk(KERN_DEBUG "error %d in opening %s...", retval, 1858 printk(KERN_DEBUG "error %d in opening %s...", retval,
2258 tty->name); 1859 tty->name);
2259#endif 1860#endif
2260 release_dev(filp); 1861 tty_release_dev(filp);
2261 if (retval != -ERESTARTSYS) 1862 if (retval != -ERESTARTSYS)
2262 return retval; 1863 return retval;
2263 if (signal_pending(current)) 1864 if (signal_pending(current))
@@ -2296,69 +1897,6 @@ static int tty_open(struct inode *inode, struct file *filp)
2296 1897
2297 1898
2298 1899
2299#ifdef CONFIG_UNIX98_PTYS
2300/**
2301 * ptmx_open - open a unix 98 pty master
2302 * @inode: inode of device file
2303 * @filp: file pointer to tty
2304 *
2305 * Allocate a unix98 pty master device from the ptmx driver.
2306 *
2307 * Locking: tty_mutex protects theinit_dev work. tty->count should
2308 * protect the rest.
2309 * allocated_ptys_lock handles the list of free pty numbers
2310 */
2311
2312static int __ptmx_open(struct inode *inode, struct file *filp)
2313{
2314 struct tty_struct *tty;
2315 int retval;
2316 int index;
2317
2318 nonseekable_open(inode, filp);
2319
2320 /* find a device that is not in use. */
2321 index = devpts_new_index();
2322 if (index < 0)
2323 return index;
2324
2325 mutex_lock(&tty_mutex);
2326 retval = init_dev(ptm_driver, index, &tty);
2327 mutex_unlock(&tty_mutex);
2328
2329 if (retval)
2330 goto out;
2331
2332 set_bit(TTY_PTY_LOCK, &tty->flags); /* LOCK THE SLAVE */
2333 filp->private_data = tty;
2334 file_move(filp, &tty->tty_files);
2335
2336 retval = devpts_pty_new(tty->link);
2337 if (retval)
2338 goto out1;
2339
2340 check_tty_count(tty, "ptmx_open");
2341 retval = ptm_driver->ops->open(tty, filp);
2342 if (!retval)
2343 return 0;
2344out1:
2345 release_dev(filp);
2346 return retval;
2347out:
2348 devpts_kill_index(index);
2349 return retval;
2350}
2351
2352static int ptmx_open(struct inode *inode, struct file *filp)
2353{
2354 int ret;
2355
2356 lock_kernel();
2357 ret = __ptmx_open(inode, filp);
2358 unlock_kernel();
2359 return ret;
2360}
2361#endif
2362 1900
2363/** 1901/**
2364 * tty_release - vfs callback for close 1902 * tty_release - vfs callback for close
@@ -2369,13 +1907,13 @@ static int ptmx_open(struct inode *inode, struct file *filp)
2369 * this tty. There may however be several such references. 1907 * this tty. There may however be several such references.
2370 * 1908 *
2371 * Locking: 1909 * Locking:
2372 * Takes bkl. See release_dev 1910 * Takes bkl. See tty_release_dev
2373 */ 1911 */
2374 1912
2375static int tty_release(struct inode *inode, struct file *filp) 1913static int tty_release(struct inode *inode, struct file *filp)
2376{ 1914{
2377 lock_kernel(); 1915 lock_kernel();
2378 release_dev(filp); 1916 tty_release_dev(filp);
2379 unlock_kernel(); 1917 unlock_kernel();
2380 return 0; 1918 return 0;
2381} 1919}
@@ -2524,7 +2062,7 @@ int tty_do_resize(struct tty_struct *tty, struct tty_struct *real_tty,
2524 2062
2525 /* For a PTY we need to lock the tty side */ 2063 /* For a PTY we need to lock the tty side */
2526 mutex_lock(&real_tty->termios_mutex); 2064 mutex_lock(&real_tty->termios_mutex);
2527 if (!memcmp(ws, &tty->winsize, sizeof(*ws))) 2065 if (!memcmp(ws, &real_tty->winsize, sizeof(*ws)))
2528 goto done; 2066 goto done;
2529 /* Get the PID values and reference them so we can 2067 /* Get the PID values and reference them so we can
2530 avoid holding the tty ctrl lock while sending signals */ 2068 avoid holding the tty ctrl lock while sending signals */
@@ -2996,7 +2534,7 @@ long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
2996 case TIOCSTI: 2534 case TIOCSTI:
2997 return tiocsti(tty, p); 2535 return tiocsti(tty, p);
2998 case TIOCGWINSZ: 2536 case TIOCGWINSZ:
2999 return tiocgwinsz(tty, p); 2537 return tiocgwinsz(real_tty, p);
3000 case TIOCSWINSZ: 2538 case TIOCSWINSZ:
3001 return tiocswinsz(tty, real_tty, p); 2539 return tiocswinsz(tty, real_tty, p);
3002 case TIOCCONS: 2540 case TIOCCONS:
@@ -3026,10 +2564,6 @@ long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
3026 return put_user(tty->ldisc.ops->num, (int __user *)p); 2564 return put_user(tty->ldisc.ops->num, (int __user *)p);
3027 case TIOCSETD: 2565 case TIOCSETD:
3028 return tiocsetd(tty, p); 2566 return tiocsetd(tty, p);
3029#ifdef CONFIG_VT
3030 case TIOCLINUX:
3031 return tioclinux(tty, arg);
3032#endif
3033 /* 2567 /*
3034 * Break handling 2568 * Break handling
3035 */ 2569 */
@@ -3220,113 +2754,6 @@ void do_SAK(struct tty_struct *tty)
3220EXPORT_SYMBOL(do_SAK); 2754EXPORT_SYMBOL(do_SAK);
3221 2755
3222/** 2756/**
3223 * flush_to_ldisc
3224 * @work: tty structure passed from work queue.
3225 *
3226 * This routine is called out of the software interrupt to flush data
3227 * from the buffer chain to the line discipline.
3228 *
3229 * Locking: holds tty->buf.lock to guard buffer list. Drops the lock
3230 * while invoking the line discipline receive_buf method. The
3231 * receive_buf method is single threaded for each tty instance.
3232 */
3233
3234static void flush_to_ldisc(struct work_struct *work)
3235{
3236 struct tty_struct *tty =
3237 container_of(work, struct tty_struct, buf.work.work);
3238 unsigned long flags;
3239 struct tty_ldisc *disc;
3240 struct tty_buffer *tbuf, *head;
3241 char *char_buf;
3242 unsigned char *flag_buf;
3243
3244 disc = tty_ldisc_ref(tty);
3245 if (disc == NULL) /* !TTY_LDISC */
3246 return;
3247
3248 spin_lock_irqsave(&tty->buf.lock, flags);
3249 /* So we know a flush is running */
3250 set_bit(TTY_FLUSHING, &tty->flags);
3251 head = tty->buf.head;
3252 if (head != NULL) {
3253 tty->buf.head = NULL;
3254 for (;;) {
3255 int count = head->commit - head->read;
3256 if (!count) {
3257 if (head->next == NULL)
3258 break;
3259 tbuf = head;
3260 head = head->next;
3261 tty_buffer_free(tty, tbuf);
3262 continue;
3263 }
3264 /* Ldisc or user is trying to flush the buffers
3265 we are feeding to the ldisc, stop feeding the
3266 line discipline as we want to empty the queue */
3267 if (test_bit(TTY_FLUSHPENDING, &tty->flags))
3268 break;
3269 if (!tty->receive_room) {
3270 schedule_delayed_work(&tty->buf.work, 1);
3271 break;
3272 }
3273 if (count > tty->receive_room)
3274 count = tty->receive_room;
3275 char_buf = head->char_buf_ptr + head->read;
3276 flag_buf = head->flag_buf_ptr + head->read;
3277 head->read += count;
3278 spin_unlock_irqrestore(&tty->buf.lock, flags);
3279 disc->ops->receive_buf(tty, char_buf,
3280 flag_buf, count);
3281 spin_lock_irqsave(&tty->buf.lock, flags);
3282 }
3283 /* Restore the queue head */
3284 tty->buf.head = head;
3285 }
3286 /* We may have a deferred request to flush the input buffer,
3287 if so pull the chain under the lock and empty the queue */
3288 if (test_bit(TTY_FLUSHPENDING, &tty->flags)) {
3289 __tty_buffer_flush(tty);
3290 clear_bit(TTY_FLUSHPENDING, &tty->flags);
3291 wake_up(&tty->read_wait);
3292 }
3293 clear_bit(TTY_FLUSHING, &tty->flags);
3294 spin_unlock_irqrestore(&tty->buf.lock, flags);
3295
3296 tty_ldisc_deref(disc);
3297}
3298
3299/**
3300 * tty_flip_buffer_push - terminal
3301 * @tty: tty to push
3302 *
3303 * Queue a push of the terminal flip buffers to the line discipline. This
3304 * function must not be called from IRQ context if tty->low_latency is set.
3305 *
3306 * In the event of the queue being busy for flipping the work will be
3307 * held off and retried later.
3308 *
3309 * Locking: tty buffer lock. Driver locks in low latency mode.
3310 */
3311
3312void tty_flip_buffer_push(struct tty_struct *tty)
3313{
3314 unsigned long flags;
3315 spin_lock_irqsave(&tty->buf.lock, flags);
3316 if (tty->buf.tail != NULL)
3317 tty->buf.tail->commit = tty->buf.tail->used;
3318 spin_unlock_irqrestore(&tty->buf.lock, flags);
3319
3320 if (tty->low_latency)
3321 flush_to_ldisc(&tty->buf.work.work);
3322 else
3323 schedule_delayed_work(&tty->buf.work, 1);
3324}
3325
3326EXPORT_SYMBOL(tty_flip_buffer_push);
3327
3328
3329/**
3330 * initialize_tty_struct 2757 * initialize_tty_struct
3331 * @tty: tty to initialize 2758 * @tty: tty to initialize
3332 * 2759 *
@@ -3336,9 +2763,11 @@ EXPORT_SYMBOL(tty_flip_buffer_push);
3336 * Locking: none - tty in question must not be exposed at this point 2763 * Locking: none - tty in question must not be exposed at this point
3337 */ 2764 */
3338 2765
3339static void initialize_tty_struct(struct tty_struct *tty) 2766void initialize_tty_struct(struct tty_struct *tty,
2767 struct tty_driver *driver, int idx)
3340{ 2768{
3341 memset(tty, 0, sizeof(struct tty_struct)); 2769 memset(tty, 0, sizeof(struct tty_struct));
2770 kref_init(&tty->kref);
3342 tty->magic = TTY_MAGIC; 2771 tty->magic = TTY_MAGIC;
3343 tty_ldisc_init(tty); 2772 tty_ldisc_init(tty);
3344 tty->session = NULL; 2773 tty->session = NULL;
@@ -3346,7 +2775,6 @@ static void initialize_tty_struct(struct tty_struct *tty)
3346 tty->overrun_time = jiffies; 2775 tty->overrun_time = jiffies;
3347 tty->buf.head = tty->buf.tail = NULL; 2776 tty->buf.head = tty->buf.tail = NULL;
3348 tty_buffer_init(tty); 2777 tty_buffer_init(tty);
3349 INIT_DELAYED_WORK(&tty->buf.work, flush_to_ldisc);
3350 mutex_init(&tty->termios_mutex); 2778 mutex_init(&tty->termios_mutex);
3351 init_waitqueue_head(&tty->write_wait); 2779 init_waitqueue_head(&tty->write_wait);
3352 init_waitqueue_head(&tty->read_wait); 2780 init_waitqueue_head(&tty->read_wait);
@@ -3357,6 +2785,11 @@ static void initialize_tty_struct(struct tty_struct *tty)
3357 spin_lock_init(&tty->ctrl_lock); 2785 spin_lock_init(&tty->ctrl_lock);
3358 INIT_LIST_HEAD(&tty->tty_files); 2786 INIT_LIST_HEAD(&tty->tty_files);
3359 INIT_WORK(&tty->SAK_work, do_SAK_work); 2787 INIT_WORK(&tty->SAK_work, do_SAK_work);
2788
2789 tty->driver = driver;
2790 tty->ops = driver->ops;
2791 tty->index = idx;
2792 tty_line_name(driver, idx, tty->name);
3360} 2793}
3361 2794
3362/** 2795/**
@@ -3377,10 +2810,9 @@ int tty_put_char(struct tty_struct *tty, unsigned char ch)
3377 return tty->ops->put_char(tty, ch); 2810 return tty->ops->put_char(tty, ch);
3378 return tty->ops->write(tty, &ch, 1); 2811 return tty->ops->write(tty, &ch, 1);
3379} 2812}
3380
3381EXPORT_SYMBOL_GPL(tty_put_char); 2813EXPORT_SYMBOL_GPL(tty_put_char);
3382 2814
3383static struct class *tty_class; 2815struct class *tty_class;
3384 2816
3385/** 2817/**
3386 * tty_register_device - register a tty device 2818 * tty_register_device - register a tty device
@@ -3420,6 +2852,7 @@ struct device *tty_register_device(struct tty_driver *driver, unsigned index,
3420 2852
3421 return device_create_drvdata(tty_class, device, dev, NULL, name); 2853 return device_create_drvdata(tty_class, device, dev, NULL, name);
3422} 2854}
2855EXPORT_SYMBOL(tty_register_device);
3423 2856
3424/** 2857/**
3425 * tty_unregister_device - unregister a tty device 2858 * tty_unregister_device - unregister a tty device
@@ -3437,8 +2870,6 @@ void tty_unregister_device(struct tty_driver *driver, unsigned index)
3437 device_destroy(tty_class, 2870 device_destroy(tty_class,
3438 MKDEV(driver->major, driver->minor_start) + index); 2871 MKDEV(driver->major, driver->minor_start) + index);
3439} 2872}
3440
3441EXPORT_SYMBOL(tty_register_device);
3442EXPORT_SYMBOL(tty_unregister_device); 2873EXPORT_SYMBOL(tty_unregister_device);
3443 2874
3444struct tty_driver *alloc_tty_driver(int lines) 2875struct tty_driver *alloc_tty_driver(int lines)
@@ -3447,27 +2878,65 @@ struct tty_driver *alloc_tty_driver(int lines)
3447 2878
3448 driver = kzalloc(sizeof(struct tty_driver), GFP_KERNEL); 2879 driver = kzalloc(sizeof(struct tty_driver), GFP_KERNEL);
3449 if (driver) { 2880 if (driver) {
2881 kref_init(&driver->kref);
3450 driver->magic = TTY_DRIVER_MAGIC; 2882 driver->magic = TTY_DRIVER_MAGIC;
3451 driver->num = lines; 2883 driver->num = lines;
3452 /* later we'll move allocation of tables here */ 2884 /* later we'll move allocation of tables here */
3453 } 2885 }
3454 return driver; 2886 return driver;
3455} 2887}
2888EXPORT_SYMBOL(alloc_tty_driver);
3456 2889
3457void put_tty_driver(struct tty_driver *driver) 2890static void destruct_tty_driver(struct kref *kref)
3458{ 2891{
2892 struct tty_driver *driver = container_of(kref, struct tty_driver, kref);
2893 int i;
2894 struct ktermios *tp;
2895 void *p;
2896
2897 if (driver->flags & TTY_DRIVER_INSTALLED) {
2898 /*
2899 * Free the termios and termios_locked structures because
2900 * we don't want to get memory leaks when modular tty
2901 * drivers are removed from the kernel.
2902 */
2903 for (i = 0; i < driver->num; i++) {
2904 tp = driver->termios[i];
2905 if (tp) {
2906 driver->termios[i] = NULL;
2907 kfree(tp);
2908 }
2909 if (!(driver->flags & TTY_DRIVER_DYNAMIC_DEV))
2910 tty_unregister_device(driver, i);
2911 }
2912 p = driver->ttys;
2913 proc_tty_unregister_driver(driver);
2914 driver->ttys = NULL;
2915 driver->termios = NULL;
2916 kfree(p);
2917 cdev_del(&driver->cdev);
2918 }
3459 kfree(driver); 2919 kfree(driver);
3460} 2920}
3461 2921
2922void tty_driver_kref_put(struct tty_driver *driver)
2923{
2924 kref_put(&driver->kref, destruct_tty_driver);
2925}
2926EXPORT_SYMBOL(tty_driver_kref_put);
2927
3462void tty_set_operations(struct tty_driver *driver, 2928void tty_set_operations(struct tty_driver *driver,
3463 const struct tty_operations *op) 2929 const struct tty_operations *op)
3464{ 2930{
3465 driver->ops = op; 2931 driver->ops = op;
3466}; 2932};
2933EXPORT_SYMBOL(tty_set_operations);
3467 2934
3468EXPORT_SYMBOL(alloc_tty_driver); 2935void put_tty_driver(struct tty_driver *d)
2936{
2937 tty_driver_kref_put(d);
2938}
3469EXPORT_SYMBOL(put_tty_driver); 2939EXPORT_SYMBOL(put_tty_driver);
3470EXPORT_SYMBOL(tty_set_operations);
3471 2940
3472/* 2941/*
3473 * Called by a tty driver to register itself. 2942 * Called by a tty driver to register itself.
@@ -3479,11 +2948,8 @@ int tty_register_driver(struct tty_driver *driver)
3479 dev_t dev; 2948 dev_t dev;
3480 void **p = NULL; 2949 void **p = NULL;
3481 2950
3482 if (driver->flags & TTY_DRIVER_INSTALLED)
3483 return 0;
3484
3485 if (!(driver->flags & TTY_DRIVER_DEVPTS_MEM) && driver->num) { 2951 if (!(driver->flags & TTY_DRIVER_DEVPTS_MEM) && driver->num) {
3486 p = kzalloc(driver->num * 3 * sizeof(void *), GFP_KERNEL); 2952 p = kzalloc(driver->num * 2 * sizeof(void *), GFP_KERNEL);
3487 if (!p) 2953 if (!p)
3488 return -ENOMEM; 2954 return -ENOMEM;
3489 } 2955 }
@@ -3507,12 +2973,9 @@ int tty_register_driver(struct tty_driver *driver)
3507 if (p) { 2973 if (p) {
3508 driver->ttys = (struct tty_struct **)p; 2974 driver->ttys = (struct tty_struct **)p;
3509 driver->termios = (struct ktermios **)(p + driver->num); 2975 driver->termios = (struct ktermios **)(p + driver->num);
3510 driver->termios_locked = (struct ktermios **)
3511 (p + driver->num * 2);
3512 } else { 2976 } else {
3513 driver->ttys = NULL; 2977 driver->ttys = NULL;
3514 driver->termios = NULL; 2978 driver->termios = NULL;
3515 driver->termios_locked = NULL;
3516 } 2979 }
3517 2980
3518 cdev_init(&driver->cdev, &tty_fops); 2981 cdev_init(&driver->cdev, &tty_fops);
@@ -3521,7 +2984,7 @@ int tty_register_driver(struct tty_driver *driver)
3521 if (error) { 2984 if (error) {
3522 unregister_chrdev_region(dev, driver->num); 2985 unregister_chrdev_region(dev, driver->num);
3523 driver->ttys = NULL; 2986 driver->ttys = NULL;
3524 driver->termios = driver->termios_locked = NULL; 2987 driver->termios = NULL;
3525 kfree(p); 2988 kfree(p);
3526 return error; 2989 return error;
3527 } 2990 }
@@ -3535,6 +2998,7 @@ int tty_register_driver(struct tty_driver *driver)
3535 tty_register_device(driver, i, NULL); 2998 tty_register_device(driver, i, NULL);
3536 } 2999 }
3537 proc_tty_register_driver(driver); 3000 proc_tty_register_driver(driver);
3001 driver->flags |= TTY_DRIVER_INSTALLED;
3538 return 0; 3002 return 0;
3539} 3003}
3540 3004
@@ -3545,46 +3009,19 @@ EXPORT_SYMBOL(tty_register_driver);
3545 */ 3009 */
3546int tty_unregister_driver(struct tty_driver *driver) 3010int tty_unregister_driver(struct tty_driver *driver)
3547{ 3011{
3548 int i; 3012#if 0
3549 struct ktermios *tp; 3013 /* FIXME */
3550 void *p;
3551
3552 if (driver->refcount) 3014 if (driver->refcount)
3553 return -EBUSY; 3015 return -EBUSY;
3554 3016#endif
3555 unregister_chrdev_region(MKDEV(driver->major, driver->minor_start), 3017 unregister_chrdev_region(MKDEV(driver->major, driver->minor_start),
3556 driver->num); 3018 driver->num);
3557 mutex_lock(&tty_mutex); 3019 mutex_lock(&tty_mutex);
3558 list_del(&driver->tty_drivers); 3020 list_del(&driver->tty_drivers);
3559 mutex_unlock(&tty_mutex); 3021 mutex_unlock(&tty_mutex);
3560
3561 /*
3562 * Free the termios and termios_locked structures because
3563 * we don't want to get memory leaks when modular tty
3564 * drivers are removed from the kernel.
3565 */
3566 for (i = 0; i < driver->num; i++) {
3567 tp = driver->termios[i];
3568 if (tp) {
3569 driver->termios[i] = NULL;
3570 kfree(tp);
3571 }
3572 tp = driver->termios_locked[i];
3573 if (tp) {
3574 driver->termios_locked[i] = NULL;
3575 kfree(tp);
3576 }
3577 if (!(driver->flags & TTY_DRIVER_DYNAMIC_DEV))
3578 tty_unregister_device(driver, i);
3579 }
3580 p = driver->ttys;
3581 proc_tty_unregister_driver(driver);
3582 driver->ttys = NULL;
3583 driver->termios = driver->termios_locked = NULL;
3584 kfree(p);
3585 cdev_del(&driver->cdev);
3586 return 0; 3022 return 0;
3587} 3023}
3024
3588EXPORT_SYMBOL(tty_unregister_driver); 3025EXPORT_SYMBOL(tty_unregister_driver);
3589 3026
3590dev_t tty_devnum(struct tty_struct *tty) 3027dev_t tty_devnum(struct tty_struct *tty)
@@ -3595,9 +3032,12 @@ EXPORT_SYMBOL(tty_devnum);
3595 3032
3596void proc_clear_tty(struct task_struct *p) 3033void proc_clear_tty(struct task_struct *p)
3597{ 3034{
3035 struct tty_struct *tty;
3598 spin_lock_irq(&p->sighand->siglock); 3036 spin_lock_irq(&p->sighand->siglock);
3037 tty = p->signal->tty;
3599 p->signal->tty = NULL; 3038 p->signal->tty = NULL;
3600 spin_unlock_irq(&p->sighand->siglock); 3039 spin_unlock_irq(&p->sighand->siglock);
3040 tty_kref_put(tty);
3601} 3041}
3602 3042
3603/* Called under the sighand lock */ 3043/* Called under the sighand lock */
@@ -3613,9 +3053,13 @@ static void __proc_set_tty(struct task_struct *tsk, struct tty_struct *tty)
3613 tty->pgrp = get_pid(task_pgrp(tsk)); 3053 tty->pgrp = get_pid(task_pgrp(tsk));
3614 spin_unlock_irqrestore(&tty->ctrl_lock, flags); 3054 spin_unlock_irqrestore(&tty->ctrl_lock, flags);
3615 tty->session = get_pid(task_session(tsk)); 3055 tty->session = get_pid(task_session(tsk));
3056 if (tsk->signal->tty) {
3057 printk(KERN_DEBUG "tty not NULL!!\n");
3058 tty_kref_put(tsk->signal->tty);
3059 }
3616 } 3060 }
3617 put_pid(tsk->signal->tty_old_pgrp); 3061 put_pid(tsk->signal->tty_old_pgrp);
3618 tsk->signal->tty = tty; 3062 tsk->signal->tty = tty_kref_get(tty);
3619 tsk->signal->tty_old_pgrp = NULL; 3063 tsk->signal->tty_old_pgrp = NULL;
3620} 3064}
3621 3065
@@ -3629,18 +3073,20 @@ static void proc_set_tty(struct task_struct *tsk, struct tty_struct *tty)
3629struct tty_struct *get_current_tty(void) 3073struct tty_struct *get_current_tty(void)
3630{ 3074{
3631 struct tty_struct *tty; 3075 struct tty_struct *tty;
3632 WARN_ON_ONCE(!mutex_is_locked(&tty_mutex)); 3076 unsigned long flags;
3633 tty = current->signal->tty; 3077
3634 /* 3078 spin_lock_irqsave(&current->sighand->siglock, flags);
3635 * session->tty can be changed/cleared from under us, make sure we 3079 tty = tty_kref_get(current->signal->tty);
3636 * issue the load. The obtained pointer, when not NULL, is valid as 3080 spin_unlock_irqrestore(&current->sighand->siglock, flags);
3637 * long as we hold tty_mutex.
3638 */
3639 barrier();
3640 return tty; 3081 return tty;
3641} 3082}
3642EXPORT_SYMBOL_GPL(get_current_tty); 3083EXPORT_SYMBOL_GPL(get_current_tty);
3643 3084
3085void tty_default_fops(struct file_operations *fops)
3086{
3087 *fops = tty_fops;
3088}
3089
3644/* 3090/*
3645 * Initialize the console device. This is called *early*, so 3091 * Initialize the console device. This is called *early*, so
3646 * we can't necessarily depend on lots of kernel help here. 3092 * we can't necessarily depend on lots of kernel help here.
@@ -3678,12 +3124,6 @@ postcore_initcall(tty_class_init);
3678/* 3/2004 jmc: why do these devices exist? */ 3124/* 3/2004 jmc: why do these devices exist? */
3679 3125
3680static struct cdev tty_cdev, console_cdev; 3126static struct cdev tty_cdev, console_cdev;
3681#ifdef CONFIG_UNIX98_PTYS
3682static struct cdev ptmx_cdev;
3683#endif
3684#ifdef CONFIG_VT
3685static struct cdev vc0_cdev;
3686#endif
3687 3127
3688/* 3128/*
3689 * Ok, now we can initialize the rest of the tty devices and can count 3129 * Ok, now we can initialize the rest of the tty devices and can count
@@ -3695,32 +3135,18 @@ static int __init tty_init(void)
3695 if (cdev_add(&tty_cdev, MKDEV(TTYAUX_MAJOR, 0), 1) || 3135 if (cdev_add(&tty_cdev, MKDEV(TTYAUX_MAJOR, 0), 1) ||
3696 register_chrdev_region(MKDEV(TTYAUX_MAJOR, 0), 1, "/dev/tty") < 0) 3136 register_chrdev_region(MKDEV(TTYAUX_MAJOR, 0), 1, "/dev/tty") < 0)
3697 panic("Couldn't register /dev/tty driver\n"); 3137 panic("Couldn't register /dev/tty driver\n");
3698 device_create_drvdata(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 0), NULL, 3138 device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 0), NULL,
3699 "tty"); 3139 "tty");
3700 3140
3701 cdev_init(&console_cdev, &console_fops); 3141 cdev_init(&console_cdev, &console_fops);
3702 if (cdev_add(&console_cdev, MKDEV(TTYAUX_MAJOR, 1), 1) || 3142 if (cdev_add(&console_cdev, MKDEV(TTYAUX_MAJOR, 1), 1) ||
3703 register_chrdev_region(MKDEV(TTYAUX_MAJOR, 1), 1, "/dev/console") < 0) 3143 register_chrdev_region(MKDEV(TTYAUX_MAJOR, 1), 1, "/dev/console") < 0)
3704 panic("Couldn't register /dev/console driver\n"); 3144 panic("Couldn't register /dev/console driver\n");
3705 device_create_drvdata(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 1), NULL, 3145 device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 1), NULL,
3706 "console"); 3146 "console");
3707 3147
3708#ifdef CONFIG_UNIX98_PTYS
3709 cdev_init(&ptmx_cdev, &ptmx_fops);
3710 if (cdev_add(&ptmx_cdev, MKDEV(TTYAUX_MAJOR, 2), 1) ||
3711 register_chrdev_region(MKDEV(TTYAUX_MAJOR, 2), 1, "/dev/ptmx") < 0)
3712 panic("Couldn't register /dev/ptmx driver\n");
3713 device_create_drvdata(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 2), NULL, "ptmx");
3714#endif
3715
3716#ifdef CONFIG_VT 3148#ifdef CONFIG_VT
3717 cdev_init(&vc0_cdev, &console_fops); 3149 vty_init(&console_fops);
3718 if (cdev_add(&vc0_cdev, MKDEV(TTY_MAJOR, 0), 1) ||
3719 register_chrdev_region(MKDEV(TTY_MAJOR, 0), 1, "/dev/vc/0") < 0)
3720 panic("Couldn't register /dev/tty0 driver\n");
3721 device_create_drvdata(tty_class, NULL, MKDEV(TTY_MAJOR, 0), NULL, "tty0");
3722
3723 vty_init();
3724#endif 3150#endif
3725 return 0; 3151 return 0;
3726} 3152}
diff --git a/drivers/char/tty_ioctl.c b/drivers/char/tty_ioctl.c
index bf34e4597421..a408c8e487ec 100644
--- a/drivers/char/tty_ioctl.c
+++ b/drivers/char/tty_ioctl.c
@@ -40,6 +40,15 @@
40#define TERMIOS_OLD 8 40#define TERMIOS_OLD 8
41 41
42 42
43/**
44 * tty_chars_in_buffer - characters pending
45 * @tty: terminal
46 *
47 * Return the number of bytes of data in the device private
48 * output queue. If no private method is supplied there is assumed
49 * to be no queue on the device.
50 */
51
43int tty_chars_in_buffer(struct tty_struct *tty) 52int tty_chars_in_buffer(struct tty_struct *tty)
44{ 53{
45 if (tty->ops->chars_in_buffer) 54 if (tty->ops->chars_in_buffer)
@@ -47,26 +56,49 @@ int tty_chars_in_buffer(struct tty_struct *tty)
47 else 56 else
48 return 0; 57 return 0;
49} 58}
50
51EXPORT_SYMBOL(tty_chars_in_buffer); 59EXPORT_SYMBOL(tty_chars_in_buffer);
52 60
61/**
62 * tty_write_room - write queue space
63 * @tty: terminal
64 *
65 * Return the number of bytes that can be queued to this device
66 * at the present time. The result should be treated as a guarantee
67 * and the driver cannot offer a value it later shrinks by more than
68 * the number of bytes written. If no method is provided 2K is always
69 * returned and data may be lost as there will be no flow control.
70 */
71
53int tty_write_room(struct tty_struct *tty) 72int tty_write_room(struct tty_struct *tty)
54{ 73{
55 if (tty->ops->write_room) 74 if (tty->ops->write_room)
56 return tty->ops->write_room(tty); 75 return tty->ops->write_room(tty);
57 return 2048; 76 return 2048;
58} 77}
59
60EXPORT_SYMBOL(tty_write_room); 78EXPORT_SYMBOL(tty_write_room);
61 79
80/**
81 * tty_driver_flush_buffer - discard internal buffer
82 * @tty: terminal
83 *
84 * Discard the internal output buffer for this device. If no method
85 * is provided then either the buffer cannot be hardware flushed or
86 * there is no buffer driver side.
87 */
62void tty_driver_flush_buffer(struct tty_struct *tty) 88void tty_driver_flush_buffer(struct tty_struct *tty)
63{ 89{
64 if (tty->ops->flush_buffer) 90 if (tty->ops->flush_buffer)
65 tty->ops->flush_buffer(tty); 91 tty->ops->flush_buffer(tty);
66} 92}
67
68EXPORT_SYMBOL(tty_driver_flush_buffer); 93EXPORT_SYMBOL(tty_driver_flush_buffer);
69 94
95/**
96 * tty_throttle - flow control
97 * @tty: terminal
98 *
99 * Indicate that a tty should stop transmitting data down the stack.
100 */
101
70void tty_throttle(struct tty_struct *tty) 102void tty_throttle(struct tty_struct *tty)
71{ 103{
72 /* check TTY_THROTTLED first so it indicates our state */ 104 /* check TTY_THROTTLED first so it indicates our state */
@@ -76,6 +108,13 @@ void tty_throttle(struct tty_struct *tty)
76} 108}
77EXPORT_SYMBOL(tty_throttle); 109EXPORT_SYMBOL(tty_throttle);
78 110
111/**
112 * tty_unthrottle - flow control
113 * @tty: terminal
114 *
115 * Indicate that a tty may continue transmitting data down the stack.
116 */
117
79void tty_unthrottle(struct tty_struct *tty) 118void tty_unthrottle(struct tty_struct *tty)
80{ 119{
81 if (test_and_clear_bit(TTY_THROTTLED, &tty->flags) && 120 if (test_and_clear_bit(TTY_THROTTLED, &tty->flags) &&
@@ -112,6 +151,11 @@ void tty_wait_until_sent(struct tty_struct *tty, long timeout)
112} 151}
113EXPORT_SYMBOL(tty_wait_until_sent); 152EXPORT_SYMBOL(tty_wait_until_sent);
114 153
154
155/*
156 * Termios Helper Methods
157 */
158
115static void unset_locked_termios(struct ktermios *termios, 159static void unset_locked_termios(struct ktermios *termios,
116 struct ktermios *old, 160 struct ktermios *old,
117 struct ktermios *locked) 161 struct ktermios *locked)
@@ -346,6 +390,16 @@ void tty_termios_encode_baud_rate(struct ktermios *termios,
346} 390}
347EXPORT_SYMBOL_GPL(tty_termios_encode_baud_rate); 391EXPORT_SYMBOL_GPL(tty_termios_encode_baud_rate);
348 392
393/**
394 * tty_encode_baud_rate - set baud rate of the tty
395 * @ibaud: input baud rate
396 * @obad: output baud rate
397 *
398 * Update the current termios data for the tty with the new speed
399 * settings. The caller must hold the termios_mutex for the tty in
400 * question.
401 */
402
349void tty_encode_baud_rate(struct tty_struct *tty, speed_t ibaud, speed_t obaud) 403void tty_encode_baud_rate(struct tty_struct *tty, speed_t ibaud, speed_t obaud)
350{ 404{
351 tty_termios_encode_baud_rate(tty->termios, ibaud, obaud); 405 tty_termios_encode_baud_rate(tty->termios, ibaud, obaud);
@@ -430,12 +484,11 @@ EXPORT_SYMBOL(tty_termios_hw_change);
430 * is a bit of layering violation here with n_tty in terms of the 484 * is a bit of layering violation here with n_tty in terms of the
431 * internal knowledge of this function. 485 * internal knowledge of this function.
432 * 486 *
433 * Locking: termios_sem 487 * Locking: termios_mutex
434 */ 488 */
435 489
436static void change_termios(struct tty_struct *tty, struct ktermios *new_termios) 490static void change_termios(struct tty_struct *tty, struct ktermios *new_termios)
437{ 491{
438 int canon_change;
439 struct ktermios old_termios; 492 struct ktermios old_termios;
440 struct tty_ldisc *ld; 493 struct tty_ldisc *ld;
441 unsigned long flags; 494 unsigned long flags;
@@ -451,18 +504,6 @@ static void change_termios(struct tty_struct *tty, struct ktermios *new_termios)
451 old_termios = *tty->termios; 504 old_termios = *tty->termios;
452 *tty->termios = *new_termios; 505 *tty->termios = *new_termios;
453 unset_locked_termios(tty->termios, &old_termios, tty->termios_locked); 506 unset_locked_termios(tty->termios, &old_termios, tty->termios_locked);
454 canon_change = (old_termios.c_lflag ^ tty->termios->c_lflag) & ICANON;
455 if (canon_change) {
456 memset(&tty->read_flags, 0, sizeof tty->read_flags);
457 tty->canon_head = tty->read_tail;
458 tty->canon_data = 0;
459 tty->erasing = 0;
460 }
461
462 /* This bit should be in the ldisc code */
463 if (canon_change && !L_ICANON(tty) && tty->read_cnt)
464 /* Get characters left over from canonical mode. */
465 wake_up_interruptible(&tty->read_wait);
466 507
467 /* See if packet mode change of state. */ 508 /* See if packet mode change of state. */
468 if (tty->link && tty->link->packet) { 509 if (tty->link && tty->link->packet) {
@@ -508,7 +549,7 @@ static void change_termios(struct tty_struct *tty, struct ktermios *new_termios)
508 * functions before using change_termios to do the actual changes. 549 * functions before using change_termios to do the actual changes.
509 * 550 *
510 * Locking: 551 * Locking:
511 * Called functions take ldisc and termios_sem locks 552 * Called functions take ldisc and termios_mutex locks
512 */ 553 */
513 554
514static int set_termios(struct tty_struct *tty, void __user *arg, int opt) 555static int set_termios(struct tty_struct *tty, void __user *arg, int opt)
@@ -579,25 +620,51 @@ static int get_termio(struct tty_struct *tty, struct termio __user *termio)
579 return 0; 620 return 0;
580} 621}
581 622
582static unsigned long inq_canon(struct tty_struct *tty) 623
624#ifdef TCGETX
625
626/**
627 * set_termiox - set termiox fields if possible
628 * @tty: terminal
629 * @arg: termiox structure from user
630 * @opt: option flags for ioctl type
631 *
632 * Implement the device calling points for the SYS5 termiox ioctl
633 * interface in Linux
634 */
635
636static int set_termiox(struct tty_struct *tty, void __user *arg, int opt)
583{ 637{
584 int nr, head, tail; 638 struct termiox tnew;
639 struct tty_ldisc *ld;
585 640
586 if (!tty->canon_data || !tty->read_buf) 641 if (tty->termiox == NULL)
587 return 0; 642 return -EINVAL;
588 head = tty->canon_head; 643 if (copy_from_user(&tnew, arg, sizeof(struct termiox)))
589 tail = tty->read_tail; 644 return -EFAULT;
590 nr = (head - tail) & (N_TTY_BUF_SIZE-1); 645
591 /* Skip EOF-chars.. */ 646 ld = tty_ldisc_ref(tty);
592 while (head != tail) { 647 if (ld != NULL) {
593 if (test_bit(tail, tty->read_flags) && 648 if ((opt & TERMIOS_FLUSH) && ld->ops->flush_buffer)
594 tty->read_buf[tail] == __DISABLED_CHAR) 649 ld->ops->flush_buffer(tty);
595 nr--; 650 tty_ldisc_deref(ld);
596 tail = (tail+1) & (N_TTY_BUF_SIZE-1);
597 } 651 }
598 return nr; 652 if (opt & TERMIOS_WAIT) {
653 tty_wait_until_sent(tty, 0);
654 if (signal_pending(current))
655 return -EINTR;
656 }
657
658 mutex_lock(&tty->termios_mutex);
659 if (tty->ops->set_termiox)
660 tty->ops->set_termiox(tty, &tnew);
661 mutex_unlock(&tty->termios_mutex);
662 return 0;
599} 663}
600 664
665#endif
666
667
601#ifdef TIOCGETP 668#ifdef TIOCGETP
602/* 669/*
603 * These are deprecated, but there is limited support.. 670 * These are deprecated, but there is limited support..
@@ -671,7 +738,7 @@ static void set_sgflags(struct ktermios *termios, int flags)
671 * Updates a terminal from the legacy BSD style terminal information 738 * Updates a terminal from the legacy BSD style terminal information
672 * structure. 739 * structure.
673 * 740 *
674 * Locking: termios_sem 741 * Locking: termios_mutex
675 */ 742 */
676 743
677static int set_sgttyb(struct tty_struct *tty, struct sgttyb __user *sgttyb) 744static int set_sgttyb(struct tty_struct *tty, struct sgttyb __user *sgttyb)
@@ -849,6 +916,7 @@ int tty_mode_ioctl(struct tty_struct *tty, struct file *file,
849{ 916{
850 struct tty_struct *real_tty; 917 struct tty_struct *real_tty;
851 void __user *p = (void __user *)arg; 918 void __user *p = (void __user *)arg;
919 int ret = 0;
852 920
853 if (tty->driver->type == TTY_DRIVER_TYPE_PTY && 921 if (tty->driver->type == TTY_DRIVER_TYPE_PTY &&
854 tty->driver->subtype == PTY_TYPE_MASTER) 922 tty->driver->subtype == PTY_TYPE_MASTER)
@@ -884,18 +952,24 @@ int tty_mode_ioctl(struct tty_struct *tty, struct file *file,
884 return set_termios(real_tty, p, TERMIOS_OLD); 952 return set_termios(real_tty, p, TERMIOS_OLD);
885#ifndef TCGETS2 953#ifndef TCGETS2
886 case TCGETS: 954 case TCGETS:
955 mutex_lock(&real_tty->termios_mutex);
887 if (kernel_termios_to_user_termios((struct termios __user *)arg, real_tty->termios)) 956 if (kernel_termios_to_user_termios((struct termios __user *)arg, real_tty->termios))
888 return -EFAULT; 957 ret = -EFAULT;
889 return 0; 958 mutex_unlock(&real_tty->termios_mutex);
959 return ret;
890#else 960#else
891 case TCGETS: 961 case TCGETS:
962 mutex_lock(&real_tty->termios_mutex);
892 if (kernel_termios_to_user_termios_1((struct termios __user *)arg, real_tty->termios)) 963 if (kernel_termios_to_user_termios_1((struct termios __user *)arg, real_tty->termios))
893 return -EFAULT; 964 ret = -EFAULT;
894 return 0; 965 mutex_unlock(&real_tty->termios_mutex);
966 return ret;
895 case TCGETS2: 967 case TCGETS2:
968 mutex_lock(&real_tty->termios_mutex);
896 if (kernel_termios_to_user_termios((struct termios2 __user *)arg, real_tty->termios)) 969 if (kernel_termios_to_user_termios((struct termios2 __user *)arg, real_tty->termios))
897 return -EFAULT; 970 ret = -EFAULT;
898 return 0; 971 mutex_unlock(&real_tty->termios_mutex);
972 return ret;
899 case TCSETSF2: 973 case TCSETSF2:
900 return set_termios(real_tty, p, TERMIOS_FLUSH | TERMIOS_WAIT); 974 return set_termios(real_tty, p, TERMIOS_FLUSH | TERMIOS_WAIT);
901 case TCSETSW2: 975 case TCSETSW2:
@@ -913,34 +987,59 @@ int tty_mode_ioctl(struct tty_struct *tty, struct file *file,
913 return set_termios(real_tty, p, TERMIOS_TERMIO); 987 return set_termios(real_tty, p, TERMIOS_TERMIO);
914#ifndef TCGETS2 988#ifndef TCGETS2
915 case TIOCGLCKTRMIOS: 989 case TIOCGLCKTRMIOS:
990 mutex_lock(&real_tty->termios_mutex);
916 if (kernel_termios_to_user_termios((struct termios __user *)arg, real_tty->termios_locked)) 991 if (kernel_termios_to_user_termios((struct termios __user *)arg, real_tty->termios_locked))
917 return -EFAULT; 992 ret = -EFAULT;
918 return 0; 993 mutex_unlock(&real_tty->termios_mutex);
994 return ret;
919 case TIOCSLCKTRMIOS: 995 case TIOCSLCKTRMIOS:
920 if (!capable(CAP_SYS_ADMIN)) 996 if (!capable(CAP_SYS_ADMIN))
921 return -EPERM; 997 return -EPERM;
998 mutex_lock(&real_tty->termios_mutex);
922 if (user_termios_to_kernel_termios(real_tty->termios_locked, 999 if (user_termios_to_kernel_termios(real_tty->termios_locked,
923 (struct termios __user *) arg)) 1000 (struct termios __user *) arg))
924 return -EFAULT; 1001 ret = -EFAULT;
925 return 0; 1002 mutex_unlock(&real_tty->termios_mutex);
1003 return ret;
926#else 1004#else
927 case TIOCGLCKTRMIOS: 1005 case TIOCGLCKTRMIOS:
1006 mutex_lock(&real_tty->termios_mutex);
928 if (kernel_termios_to_user_termios_1((struct termios __user *)arg, real_tty->termios_locked)) 1007 if (kernel_termios_to_user_termios_1((struct termios __user *)arg, real_tty->termios_locked))
929 return -EFAULT; 1008 ret = -EFAULT;
930 return 0; 1009 mutex_unlock(&real_tty->termios_mutex);
1010 return ret;
931 case TIOCSLCKTRMIOS: 1011 case TIOCSLCKTRMIOS:
932 if (!capable(CAP_SYS_ADMIN)) 1012 if (!capable(CAP_SYS_ADMIN))
933 return -EPERM; 1013 ret = -EPERM;
1014 mutex_lock(&real_tty->termios_mutex);
934 if (user_termios_to_kernel_termios_1(real_tty->termios_locked, 1015 if (user_termios_to_kernel_termios_1(real_tty->termios_locked,
935 (struct termios __user *) arg)) 1016 (struct termios __user *) arg))
936 return -EFAULT; 1017 ret = -EFAULT;
937 return 0; 1018 mutex_unlock(&real_tty->termios_mutex);
1019 return ret;
938#endif 1020#endif
1021#ifdef TCGETX
1022 case TCGETX:
1023 if (real_tty->termiox == NULL)
1024 return -EINVAL;
1025 mutex_lock(&real_tty->termios_mutex);
1026 if (copy_to_user(p, real_tty->termiox, sizeof(struct termiox)))
1027 ret = -EFAULT;
1028 mutex_unlock(&real_tty->termios_mutex);
1029 return ret;
1030 case TCSETX:
1031 return set_termiox(real_tty, p, 0);
1032 case TCSETXW:
1033 return set_termiox(real_tty, p, TERMIOS_WAIT);
1034 case TCSETXF:
1035 return set_termiox(real_tty, p, TERMIOS_FLUSH);
1036#endif
939 case TIOCGSOFTCAR: 1037 case TIOCGSOFTCAR:
940 /* FIXME: for correctness we may need to take the termios 1038 mutex_lock(&real_tty->termios_mutex);
941 lock here - review */ 1039 ret = put_user(C_CLOCAL(real_tty) ? 1 : 0,
942 return put_user(C_CLOCAL(real_tty) ? 1 : 0,
943 (int __user *)arg); 1040 (int __user *)arg);
1041 mutex_unlock(&real_tty->termios_mutex);
1042 return ret;
944 case TIOCSSOFTCAR: 1043 case TIOCSSOFTCAR:
945 if (get_user(arg, (unsigned int __user *) arg)) 1044 if (get_user(arg, (unsigned int __user *) arg))
946 return -EFAULT; 1045 return -EFAULT;
@@ -980,7 +1079,7 @@ int tty_perform_flush(struct tty_struct *tty, unsigned long arg)
980} 1079}
981EXPORT_SYMBOL_GPL(tty_perform_flush); 1080EXPORT_SYMBOL_GPL(tty_perform_flush);
982 1081
983int n_tty_ioctl(struct tty_struct *tty, struct file *file, 1082int n_tty_ioctl_helper(struct tty_struct *tty, struct file *file,
984 unsigned int cmd, unsigned long arg) 1083 unsigned int cmd, unsigned long arg)
985{ 1084{
986 unsigned long flags; 1085 unsigned long flags;
@@ -1018,13 +1117,6 @@ int n_tty_ioctl(struct tty_struct *tty, struct file *file,
1018 return 0; 1117 return 0;
1019 case TCFLSH: 1118 case TCFLSH:
1020 return tty_perform_flush(tty, arg); 1119 return tty_perform_flush(tty, arg);
1021 case TIOCOUTQ:
1022 return put_user(tty_chars_in_buffer(tty), (int __user *) arg);
1023 case TIOCINQ:
1024 retval = tty->read_cnt;
1025 if (L_ICANON(tty))
1026 retval = inq_canon(tty);
1027 return put_user(retval, (unsigned int __user *) arg);
1028 case TIOCPKT: 1120 case TIOCPKT:
1029 { 1121 {
1030 int pktmode; 1122 int pktmode;
@@ -1050,4 +1142,4 @@ int n_tty_ioctl(struct tty_struct *tty, struct file *file,
1050 return tty_mode_ioctl(tty, file, cmd, arg); 1142 return tty_mode_ioctl(tty, file, cmd, arg);
1051 } 1143 }
1052} 1144}
1053EXPORT_SYMBOL(n_tty_ioctl); 1145EXPORT_SYMBOL(n_tty_ioctl_helper);
diff --git a/drivers/char/tty_port.c b/drivers/char/tty_port.c
new file mode 100644
index 000000000000..553b0e9d8d17
--- /dev/null
+++ b/drivers/char/tty_port.c
@@ -0,0 +1,96 @@
1/*
2 * Tty port functions
3 */
4
5#include <linux/types.h>
6#include <linux/errno.h>
7#include <linux/tty.h>
8#include <linux/tty_driver.h>
9#include <linux/tty_flip.h>
10#include <linux/timer.h>
11#include <linux/string.h>
12#include <linux/slab.h>
13#include <linux/sched.h>
14#include <linux/init.h>
15#include <linux/wait.h>
16#include <linux/bitops.h>
17#include <linux/delay.h>
18#include <linux/module.h>
19
20void tty_port_init(struct tty_port *port)
21{
22 memset(port, 0, sizeof(*port));
23 init_waitqueue_head(&port->open_wait);
24 init_waitqueue_head(&port->close_wait);
25 mutex_init(&port->mutex);
26 spin_lock_init(&port->lock);
27 port->close_delay = (50 * HZ) / 100;
28 port->closing_wait = (3000 * HZ) / 100;
29}
30EXPORT_SYMBOL(tty_port_init);
31
32int tty_port_alloc_xmit_buf(struct tty_port *port)
33{
34 /* We may sleep in get_zeroed_page() */
35 mutex_lock(&port->mutex);
36 if (port->xmit_buf == NULL)
37 port->xmit_buf = (unsigned char *)get_zeroed_page(GFP_KERNEL);
38 mutex_unlock(&port->mutex);
39 if (port->xmit_buf == NULL)
40 return -ENOMEM;
41 return 0;
42}
43EXPORT_SYMBOL(tty_port_alloc_xmit_buf);
44
45void tty_port_free_xmit_buf(struct tty_port *port)
46{
47 mutex_lock(&port->mutex);
48 if (port->xmit_buf != NULL) {
49 free_page((unsigned long)port->xmit_buf);
50 port->xmit_buf = NULL;
51 }
52 mutex_unlock(&port->mutex);
53}
54EXPORT_SYMBOL(tty_port_free_xmit_buf);
55
56
57/**
58 * tty_port_tty_get - get a tty reference
59 * @port: tty port
60 *
61 * Return a refcount protected tty instance or NULL if the port is not
62 * associated with a tty (eg due to close or hangup)
63 */
64
65struct tty_struct *tty_port_tty_get(struct tty_port *port)
66{
67 unsigned long flags;
68 struct tty_struct *tty;
69
70 spin_lock_irqsave(&port->lock, flags);
71 tty = tty_kref_get(port->tty);
72 spin_unlock_irqrestore(&port->lock, flags);
73 return tty;
74}
75EXPORT_SYMBOL(tty_port_tty_get);
76
77/**
78 * tty_port_tty_set - set the tty of a port
79 * @port: tty port
80 * @tty: the tty
81 *
82 * Associate the port and tty pair. Manages any internal refcounts.
83 * Pass NULL to deassociate a port
84 */
85
86void tty_port_tty_set(struct tty_port *port, struct tty_struct *tty)
87{
88 unsigned long flags;
89
90 spin_lock_irqsave(&port->lock, flags);
91 if (port->tty)
92 tty_kref_put(port->tty);
93 port->tty = tty;
94 spin_unlock_irqrestore(&port->lock, flags);
95}
96EXPORT_SYMBOL(tty_port_tty_set);
diff --git a/drivers/char/vt.c b/drivers/char/vt.c
index 60359c360912..57029fefd64a 100644
--- a/drivers/char/vt.c
+++ b/drivers/char/vt.c
@@ -100,10 +100,10 @@
100#include <linux/font.h> 100#include <linux/font.h>
101#include <linux/bitops.h> 101#include <linux/bitops.h>
102#include <linux/notifier.h> 102#include <linux/notifier.h>
103 103#include <linux/device.h>
104#include <asm/io.h> 104#include <linux/io.h>
105#include <asm/system.h> 105#include <asm/system.h>
106#include <asm/uaccess.h> 106#include <linux/uaccess.h>
107 107
108#define MAX_NR_CON_DRIVER 16 108#define MAX_NR_CON_DRIVER 16
109 109
@@ -2136,27 +2136,9 @@ static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int co
2136 release_console_sem(); 2136 release_console_sem();
2137 return 0; 2137 return 0;
2138 } 2138 }
2139 release_console_sem();
2140
2141 orig_buf = buf; 2139 orig_buf = buf;
2142 orig_count = count; 2140 orig_count = count;
2143 2141
2144 /* At this point 'buf' is guaranteed to be a kernel buffer
2145 * and therefore no access to userspace (and therefore sleeping)
2146 * will be needed. The con_buf_mtx serializes all tty based
2147 * console rendering and vcs write/read operations. We hold
2148 * the console spinlock during the entire write.
2149 */
2150
2151 acquire_console_sem();
2152
2153 vc = tty->driver_data;
2154 if (vc == NULL) {
2155 printk(KERN_ERR "vt: argh, driver_data _became_ NULL !\n");
2156 release_console_sem();
2157 goto out;
2158 }
2159
2160 himask = vc->vc_hi_font_mask; 2142 himask = vc->vc_hi_font_mask;
2161 charmask = himask ? 0x1ff : 0xff; 2143 charmask = himask ? 0x1ff : 0xff;
2162 2144
@@ -2370,8 +2352,6 @@ rescan_last_byte:
2370 FLUSH 2352 FLUSH
2371 console_conditional_schedule(); 2353 console_conditional_schedule();
2372 release_console_sem(); 2354 release_console_sem();
2373
2374out:
2375 notify_update(vc); 2355 notify_update(vc);
2376 return n; 2356 return n;
2377#undef FLUSH 2357#undef FLUSH
@@ -2583,8 +2563,6 @@ int tioclinux(struct tty_struct *tty, unsigned long arg)
2583 int lines; 2563 int lines;
2584 int ret; 2564 int ret;
2585 2565
2586 if (tty->driver->type != TTY_DRIVER_TYPE_CONSOLE)
2587 return -EINVAL;
2588 if (current->signal->tty != tty && !capable(CAP_SYS_ADMIN)) 2566 if (current->signal->tty != tty && !capable(CAP_SYS_ADMIN))
2589 return -EPERM; 2567 return -EPERM;
2590 if (get_user(type, p)) 2568 if (get_user(type, p))
@@ -2778,6 +2756,12 @@ static int con_open(struct tty_struct *tty, struct file *filp)
2778 ret = vc_allocate(currcons); 2756 ret = vc_allocate(currcons);
2779 if (ret == 0) { 2757 if (ret == 0) {
2780 struct vc_data *vc = vc_cons[currcons].d; 2758 struct vc_data *vc = vc_cons[currcons].d;
2759
2760 /* Still being freed */
2761 if (vc->vc_tty) {
2762 release_console_sem();
2763 return -ERESTARTSYS;
2764 }
2781 tty->driver_data = vc; 2765 tty->driver_data = vc;
2782 vc->vc_tty = tty; 2766 vc->vc_tty = tty;
2783 2767
@@ -2798,34 +2782,20 @@ static int con_open(struct tty_struct *tty, struct file *filp)
2798 return ret; 2782 return ret;
2799} 2783}
2800 2784
2801/*
2802 * We take tty_mutex in here to prevent another thread from coming in via init_dev
2803 * and taking a ref against the tty while we're in the process of forgetting
2804 * about it and cleaning things up.
2805 *
2806 * This is because vcs_remove_sysfs() can sleep and will drop the BKL.
2807 */
2808static void con_close(struct tty_struct *tty, struct file *filp) 2785static void con_close(struct tty_struct *tty, struct file *filp)
2809{ 2786{
2810 mutex_lock(&tty_mutex); 2787 /* Nothing to do - we defer to shutdown */
2811 acquire_console_sem(); 2788}
2812 if (tty && tty->count == 1) {
2813 struct vc_data *vc = tty->driver_data;
2814 2789
2815 if (vc) 2790static void con_shutdown(struct tty_struct *tty)
2816 vc->vc_tty = NULL; 2791{
2817 tty->driver_data = NULL; 2792 struct vc_data *vc = tty->driver_data;
2818 vcs_remove_sysfs(tty); 2793 BUG_ON(vc == NULL);
2819 release_console_sem(); 2794 acquire_console_sem();
2820 mutex_unlock(&tty_mutex); 2795 vc->vc_tty = NULL;
2821 /* 2796 vcs_remove_sysfs(tty);
2822 * tty_mutex is released, but we still hold BKL, so there is
2823 * still exclusion against init_dev()
2824 */
2825 return;
2826 }
2827 release_console_sem(); 2797 release_console_sem();
2828 mutex_unlock(&tty_mutex); 2798 tty_shutdown(tty);
2829} 2799}
2830 2800
2831static int default_italic_color = 2; // green (ASCII) 2801static int default_italic_color = 2; // green (ASCII)
@@ -2950,10 +2920,19 @@ static const struct tty_operations con_ops = {
2950 .throttle = con_throttle, 2920 .throttle = con_throttle,
2951 .unthrottle = con_unthrottle, 2921 .unthrottle = con_unthrottle,
2952 .resize = vt_resize, 2922 .resize = vt_resize,
2923 .shutdown = con_shutdown
2953}; 2924};
2954 2925
2955int __init vty_init(void) 2926static struct cdev vc0_cdev;
2927
2928int __init vty_init(const struct file_operations *console_fops)
2956{ 2929{
2930 cdev_init(&vc0_cdev, console_fops);
2931 if (cdev_add(&vc0_cdev, MKDEV(TTY_MAJOR, 0), 1) ||
2932 register_chrdev_region(MKDEV(TTY_MAJOR, 0), 1, "/dev/vc/0") < 0)
2933 panic("Couldn't register /dev/tty0 driver\n");
2934 device_create(tty_class, NULL, MKDEV(TTY_MAJOR, 0), NULL, "tty0");
2935
2957 vcs_init(); 2936 vcs_init();
2958 2937
2959 console_driver = alloc_tty_driver(MAX_NR_CONSOLES); 2938 console_driver = alloc_tty_driver(MAX_NR_CONSOLES);
@@ -2972,7 +2951,6 @@ int __init vty_init(void)
2972 tty_set_operations(console_driver, &con_ops); 2951 tty_set_operations(console_driver, &con_ops);
2973 if (tty_register_driver(console_driver)) 2952 if (tty_register_driver(console_driver))
2974 panic("Couldn't register console driver\n"); 2953 panic("Couldn't register console driver\n");
2975
2976 kbd_init(); 2954 kbd_init();
2977 console_map_init(); 2955 console_map_init();
2978#ifdef CONFIG_PROM_CONSOLE 2956#ifdef CONFIG_PROM_CONSOLE
@@ -3466,7 +3444,7 @@ int register_con_driver(const struct consw *csw, int first, int last)
3466 if (retval) 3444 if (retval)
3467 goto err; 3445 goto err;
3468 3446
3469 con_driver->dev = device_create_drvdata(vtconsole_class, NULL, 3447 con_driver->dev = device_create(vtconsole_class, NULL,
3470 MKDEV(0, con_driver->node), 3448 MKDEV(0, con_driver->node),
3471 NULL, "vtcon%i", 3449 NULL, "vtcon%i",
3472 con_driver->node); 3450 con_driver->node);
@@ -3577,7 +3555,7 @@ static int __init vtconsole_class_init(void)
3577 struct con_driver *con = &registered_con_driver[i]; 3555 struct con_driver *con = &registered_con_driver[i];
3578 3556
3579 if (con->con && !con->dev) { 3557 if (con->con && !con->dev) {
3580 con->dev = device_create_drvdata(vtconsole_class, NULL, 3558 con->dev = device_create(vtconsole_class, NULL,
3581 MKDEV(0, con->node), 3559 MKDEV(0, con->node),
3582 NULL, "vtcon%i", 3560 NULL, "vtcon%i",
3583 con->node); 3561 con->node);
diff --git a/drivers/char/vt_ioctl.c b/drivers/char/vt_ioctl.c
index c904e9ad4a71..8944ce508e2f 100644
--- a/drivers/char/vt_ioctl.c
+++ b/drivers/char/vt_ioctl.c
@@ -395,6 +395,8 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
395 395
396 kbd = kbd_table + console; 396 kbd = kbd_table + console;
397 switch (cmd) { 397 switch (cmd) {
398 case TIOCLINUX:
399 return tioclinux(tty, arg);
398 case KIOCSOUND: 400 case KIOCSOUND:
399 if (!perm) 401 if (!perm)
400 goto eperm; 402 goto eperm;
diff --git a/drivers/isdn/capi/capi.c b/drivers/isdn/capi/capi.c
index 871b0cbca5e4..798d7f3e42ef 100644
--- a/drivers/isdn/capi/capi.c
+++ b/drivers/isdn/capi/capi.c
@@ -1231,7 +1231,7 @@ static int capinc_tty_ioctl(struct tty_struct *tty, struct file * file,
1231 int error = 0; 1231 int error = 0;
1232 switch (cmd) { 1232 switch (cmd) {
1233 default: 1233 default:
1234 error = n_tty_ioctl (tty, file, cmd, arg); 1234 error = n_tty_ioctl_helper(tty, file, cmd, arg);
1235 break; 1235 break;
1236 } 1236 }
1237 return error; 1237 return error;
diff --git a/drivers/isdn/gigaset/ser-gigaset.c b/drivers/isdn/gigaset/ser-gigaset.c
index 5e89fa177816..07052ed2a0c5 100644
--- a/drivers/isdn/gigaset/ser-gigaset.c
+++ b/drivers/isdn/gigaset/ser-gigaset.c
@@ -571,6 +571,7 @@ gigaset_tty_close(struct tty_struct *tty)
571 } 571 }
572 572
573 /* prevent other callers from entering ldisc methods */ 573 /* prevent other callers from entering ldisc methods */
574 /* FIXME: should use the tty state flags */
574 tty->disc_data = NULL; 575 tty->disc_data = NULL;
575 576
576 if (!cs->hw.ser) 577 if (!cs->hw.ser)
@@ -642,10 +643,11 @@ gigaset_tty_ioctl(struct tty_struct *tty, struct file *file,
642 return -ENXIO; 643 return -ENXIO;
643 644
644 switch (cmd) { 645 switch (cmd) {
645 case TCGETS: 646
646 case TCGETA: 647 case FIONREAD:
647 /* pass through to underlying serial device */ 648 /* unused, always return zero */
648 rc = n_tty_ioctl(tty, file, cmd, arg); 649 val = 0;
650 rc = put_user(val, p);
649 break; 651 break;
650 652
651 case TCFLSH: 653 case TCFLSH:
@@ -659,20 +661,13 @@ gigaset_tty_ioctl(struct tty_struct *tty, struct file *file,
659 flush_send_queue(cs); 661 flush_send_queue(cs);
660 break; 662 break;
661 } 663 }
662 /* flush the serial port's buffer */ 664 /* Pass through */
663 rc = n_tty_ioctl(tty, file, cmd, arg);
664 break;
665
666 case FIONREAD:
667 /* unused, always return zero */
668 val = 0;
669 rc = put_user(val, p);
670 break;
671 665
672 default: 666 default:
673 rc = -ENOIOCTLCMD; 667 /* pass through to underlying serial device */
668 rc = n_tty_ioctl_helper(tty, file, cmd, arg);
669 break;
674 } 670 }
675
676 cs_put(cs); 671 cs_put(cs);
677 return rc; 672 return rc;
678} 673}
@@ -680,6 +675,8 @@ gigaset_tty_ioctl(struct tty_struct *tty, struct file *file,
680/* 675/*
681 * Poll on the tty. 676 * Poll on the tty.
682 * Unused, always return zero. 677 * Unused, always return zero.
678 *
679 * FIXME: should probably return an exception - especially on hangup
683 */ 680 */
684static unsigned int 681static unsigned int
685gigaset_tty_poll(struct tty_struct *tty, struct file *file, poll_table *wait) 682gigaset_tty_poll(struct tty_struct *tty, struct file *file, poll_table *wait)
diff --git a/drivers/media/video/cafe_ccic.c b/drivers/media/video/cafe_ccic.c
index 5405c30dbb04..08efbe7254ff 100644
--- a/drivers/media/video/cafe_ccic.c
+++ b/drivers/media/video/cafe_ccic.c
@@ -2092,15 +2092,8 @@ static int cafe_pci_probe(struct pci_dev *pdev,
2092 const struct pci_device_id *id) 2092 const struct pci_device_id *id)
2093{ 2093{
2094 int ret; 2094 int ret;
2095 u16 classword;
2096 struct cafe_camera *cam; 2095 struct cafe_camera *cam;
2097 /* 2096
2098 * Make sure we have a camera here - we'll get calls for
2099 * the other cafe devices as well.
2100 */
2101 pci_read_config_word(pdev, PCI_CLASS_DEVICE, &classword);
2102 if (classword != PCI_CLASS_MULTIMEDIA_VIDEO)
2103 return -ENODEV;
2104 /* 2097 /*
2105 * Start putting together one of our big camera structures. 2098 * Start putting together one of our big camera structures.
2106 */ 2099 */
@@ -2288,8 +2281,8 @@ static int cafe_pci_resume(struct pci_dev *pdev)
2288 2281
2289 2282
2290static struct pci_device_id cafe_ids[] = { 2283static struct pci_device_id cafe_ids[] = {
2291 { PCI_DEVICE(0x11ab, 0x4100) }, /* Eventual real ID */ 2284 { PCI_DEVICE(PCI_VENDOR_ID_MARVELL,
2292 { PCI_DEVICE(0x11ab, 0x4102) }, /* Really eventual real ID */ 2285 PCI_DEVICE_ID_MARVELL_88ALP01_CCIC) },
2293 { 0, } 2286 { 0, }
2294}; 2287};
2295 2288
diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c
index 0a84f10d719c..9bd7026b0021 100644
--- a/drivers/mmc/host/sdhci-pci.c
+++ b/drivers/mmc/host/sdhci-pci.c
@@ -327,7 +327,7 @@ static const struct pci_device_id pci_ids[] __devinitdata = {
327 327
328 { 328 {
329 .vendor = PCI_VENDOR_ID_MARVELL, 329 .vendor = PCI_VENDOR_ID_MARVELL,
330 .device = PCI_DEVICE_ID_MARVELL_CAFE_SD, 330 .device = PCI_DEVICE_ID_MARVELL_88ALP01_SD,
331 .subvendor = PCI_ANY_ID, 331 .subvendor = PCI_ANY_ID,
332 .subdevice = PCI_ANY_ID, 332 .subdevice = PCI_ANY_ID,
333 .driver_data = (kernel_ulong_t)&sdhci_cafe, 333 .driver_data = (kernel_ulong_t)&sdhci_cafe,
diff --git a/drivers/mtd/nand/cafe_nand.c b/drivers/mtd/nand/cafe_nand.c
index 95345d051579..b8064bf3aee4 100644
--- a/drivers/mtd/nand/cafe_nand.c
+++ b/drivers/mtd/nand/cafe_nand.c
@@ -1,6 +1,9 @@
1/* 1/*
2 * Driver for One Laptop Per Child ‘CAFÉ’ controller, aka Marvell 88ALP01 2 * Driver for One Laptop Per Child ‘CAFÉ’ controller, aka Marvell 88ALP01
3 * 3 *
4 * The data sheet for this device can be found at:
5 * http://www.marvell.com/products/pcconn/88ALP01.jsp
6 *
4 * Copyright © 2006 Red Hat, Inc. 7 * Copyright © 2006 Red Hat, Inc.
5 * Copyright © 2006 David Woodhouse <dwmw2@infradead.org> 8 * Copyright © 2006 David Woodhouse <dwmw2@infradead.org>
6 */ 9 */
@@ -842,7 +845,8 @@ static void __devexit cafe_nand_remove(struct pci_dev *pdev)
842} 845}
843 846
844static struct pci_device_id cafe_nand_tbl[] = { 847static struct pci_device_id cafe_nand_tbl[] = {
845 { 0x11ab, 0x4100, PCI_ANY_ID, PCI_ANY_ID }, 848 { PCI_VENDOR_ID_MARVELL, PCI_DEVICE_ID_MARVELL_88ALP01_NAND,
849 PCI_ANY_ID, PCI_ANY_ID },
846 { } 850 { }
847}; 851};
848 852
diff --git a/drivers/net/wan/Kconfig b/drivers/net/wan/Kconfig
index 2ae2ec40015d..21efd99b9294 100644
--- a/drivers/net/wan/Kconfig
+++ b/drivers/net/wan/Kconfig
@@ -205,7 +205,7 @@ config WANXL_BUILD_FIRMWARE
205 205
206config PC300 206config PC300
207 tristate "Cyclades-PC300 support (RS-232/V.35, X.21, T1/E1 boards)" 207 tristate "Cyclades-PC300 support (RS-232/V.35, X.21, T1/E1 boards)"
208 depends on HDLC && PCI 208 depends on HDLC && PCI && BROKEN
209 ---help--- 209 ---help---
210 Driver for the Cyclades-PC300 synchronous communication boards. 210 Driver for the Cyclades-PC300 synchronous communication boards.
211 211
diff --git a/drivers/oprofile/buffer_sync.c b/drivers/oprofile/buffer_sync.c
index 9304c4555079..ed982273fb8b 100644
--- a/drivers/oprofile/buffer_sync.c
+++ b/drivers/oprofile/buffer_sync.c
@@ -5,6 +5,7 @@
5 * @remark Read the file COPYING 5 * @remark Read the file COPYING
6 * 6 *
7 * @author John Levon <levon@movementarian.org> 7 * @author John Levon <levon@movementarian.org>
8 * @author Barry Kasindorf
8 * 9 *
9 * This is the core of the buffer management. Each 10 * This is the core of the buffer management. Each
10 * CPU buffer is processed and entered into the 11 * CPU buffer is processed and entered into the
@@ -33,7 +34,7 @@
33#include "event_buffer.h" 34#include "event_buffer.h"
34#include "cpu_buffer.h" 35#include "cpu_buffer.h"
35#include "buffer_sync.h" 36#include "buffer_sync.h"
36 37
37static LIST_HEAD(dying_tasks); 38static LIST_HEAD(dying_tasks);
38static LIST_HEAD(dead_tasks); 39static LIST_HEAD(dead_tasks);
39static cpumask_t marked_cpus = CPU_MASK_NONE; 40static cpumask_t marked_cpus = CPU_MASK_NONE;
@@ -48,10 +49,11 @@ static void process_task_mortuary(void);
48 * Can be invoked from softirq via RCU callback due to 49 * Can be invoked from softirq via RCU callback due to
49 * call_rcu() of the task struct, hence the _irqsave. 50 * call_rcu() of the task struct, hence the _irqsave.
50 */ 51 */
51static int task_free_notify(struct notifier_block * self, unsigned long val, void * data) 52static int
53task_free_notify(struct notifier_block *self, unsigned long val, void *data)
52{ 54{
53 unsigned long flags; 55 unsigned long flags;
54 struct task_struct * task = data; 56 struct task_struct *task = data;
55 spin_lock_irqsave(&task_mortuary, flags); 57 spin_lock_irqsave(&task_mortuary, flags);
56 list_add(&task->tasks, &dying_tasks); 58 list_add(&task->tasks, &dying_tasks);
57 spin_unlock_irqrestore(&task_mortuary, flags); 59 spin_unlock_irqrestore(&task_mortuary, flags);
@@ -62,13 +64,14 @@ static int task_free_notify(struct notifier_block * self, unsigned long val, voi
62/* The task is on its way out. A sync of the buffer means we can catch 64/* The task is on its way out. A sync of the buffer means we can catch
63 * any remaining samples for this task. 65 * any remaining samples for this task.
64 */ 66 */
65static int task_exit_notify(struct notifier_block * self, unsigned long val, void * data) 67static int
68task_exit_notify(struct notifier_block *self, unsigned long val, void *data)
66{ 69{
67 /* To avoid latency problems, we only process the current CPU, 70 /* To avoid latency problems, we only process the current CPU,
68 * hoping that most samples for the task are on this CPU 71 * hoping that most samples for the task are on this CPU
69 */ 72 */
70 sync_buffer(raw_smp_processor_id()); 73 sync_buffer(raw_smp_processor_id());
71 return 0; 74 return 0;
72} 75}
73 76
74 77
@@ -77,11 +80,12 @@ static int task_exit_notify(struct notifier_block * self, unsigned long val, voi
77 * we don't lose any. This does not have to be exact, it's a QoI issue 80 * we don't lose any. This does not have to be exact, it's a QoI issue
78 * only. 81 * only.
79 */ 82 */
80static int munmap_notify(struct notifier_block * self, unsigned long val, void * data) 83static int
84munmap_notify(struct notifier_block *self, unsigned long val, void *data)
81{ 85{
82 unsigned long addr = (unsigned long)data; 86 unsigned long addr = (unsigned long)data;
83 struct mm_struct * mm = current->mm; 87 struct mm_struct *mm = current->mm;
84 struct vm_area_struct * mpnt; 88 struct vm_area_struct *mpnt;
85 89
86 down_read(&mm->mmap_sem); 90 down_read(&mm->mmap_sem);
87 91
@@ -99,11 +103,12 @@ static int munmap_notify(struct notifier_block * self, unsigned long val, void *
99 return 0; 103 return 0;
100} 104}
101 105
102 106
103/* We need to be told about new modules so we don't attribute to a previously 107/* We need to be told about new modules so we don't attribute to a previously
104 * loaded module, or drop the samples on the floor. 108 * loaded module, or drop the samples on the floor.
105 */ 109 */
106static int module_load_notify(struct notifier_block * self, unsigned long val, void * data) 110static int
111module_load_notify(struct notifier_block *self, unsigned long val, void *data)
107{ 112{
108#ifdef CONFIG_MODULES 113#ifdef CONFIG_MODULES
109 if (val != MODULE_STATE_COMING) 114 if (val != MODULE_STATE_COMING)
@@ -118,7 +123,7 @@ static int module_load_notify(struct notifier_block * self, unsigned long val, v
118 return 0; 123 return 0;
119} 124}
120 125
121 126
122static struct notifier_block task_free_nb = { 127static struct notifier_block task_free_nb = {
123 .notifier_call = task_free_notify, 128 .notifier_call = task_free_notify,
124}; 129};
@@ -135,7 +140,7 @@ static struct notifier_block module_load_nb = {
135 .notifier_call = module_load_notify, 140 .notifier_call = module_load_notify,
136}; 141};
137 142
138 143
139static void end_sync(void) 144static void end_sync(void)
140{ 145{
141 end_cpu_work(); 146 end_cpu_work();
@@ -208,14 +213,14 @@ static inline unsigned long fast_get_dcookie(struct path *path)
208 * not strictly necessary but allows oprofile to associate 213 * not strictly necessary but allows oprofile to associate
209 * shared-library samples with particular applications 214 * shared-library samples with particular applications
210 */ 215 */
211static unsigned long get_exec_dcookie(struct mm_struct * mm) 216static unsigned long get_exec_dcookie(struct mm_struct *mm)
212{ 217{
213 unsigned long cookie = NO_COOKIE; 218 unsigned long cookie = NO_COOKIE;
214 struct vm_area_struct * vma; 219 struct vm_area_struct *vma;
215 220
216 if (!mm) 221 if (!mm)
217 goto out; 222 goto out;
218 223
219 for (vma = mm->mmap; vma; vma = vma->vm_next) { 224 for (vma = mm->mmap; vma; vma = vma->vm_next) {
220 if (!vma->vm_file) 225 if (!vma->vm_file)
221 continue; 226 continue;
@@ -235,13 +240,14 @@ out:
235 * sure to do this lookup before a mm->mmap modification happens so 240 * sure to do this lookup before a mm->mmap modification happens so
236 * we don't lose track. 241 * we don't lose track.
237 */ 242 */
238static unsigned long lookup_dcookie(struct mm_struct * mm, unsigned long addr, off_t * offset) 243static unsigned long
244lookup_dcookie(struct mm_struct *mm, unsigned long addr, off_t *offset)
239{ 245{
240 unsigned long cookie = NO_COOKIE; 246 unsigned long cookie = NO_COOKIE;
241 struct vm_area_struct * vma; 247 struct vm_area_struct *vma;
242 248
243 for (vma = find_vma(mm, addr); vma; vma = vma->vm_next) { 249 for (vma = find_vma(mm, addr); vma; vma = vma->vm_next) {
244 250
245 if (addr < vma->vm_start || addr >= vma->vm_end) 251 if (addr < vma->vm_start || addr >= vma->vm_end)
246 continue; 252 continue;
247 253
@@ -263,9 +269,20 @@ static unsigned long lookup_dcookie(struct mm_struct * mm, unsigned long addr, o
263 return cookie; 269 return cookie;
264} 270}
265 271
272static void increment_tail(struct oprofile_cpu_buffer *b)
273{
274 unsigned long new_tail = b->tail_pos + 1;
275
276 rmb(); /* be sure fifo pointers are synchromized */
277
278 if (new_tail < b->buffer_size)
279 b->tail_pos = new_tail;
280 else
281 b->tail_pos = 0;
282}
266 283
267static unsigned long last_cookie = INVALID_COOKIE; 284static unsigned long last_cookie = INVALID_COOKIE;
268 285
269static void add_cpu_switch(int i) 286static void add_cpu_switch(int i)
270{ 287{
271 add_event_entry(ESCAPE_CODE); 288 add_event_entry(ESCAPE_CODE);
@@ -278,16 +295,16 @@ static void add_kernel_ctx_switch(unsigned int in_kernel)
278{ 295{
279 add_event_entry(ESCAPE_CODE); 296 add_event_entry(ESCAPE_CODE);
280 if (in_kernel) 297 if (in_kernel)
281 add_event_entry(KERNEL_ENTER_SWITCH_CODE); 298 add_event_entry(KERNEL_ENTER_SWITCH_CODE);
282 else 299 else
283 add_event_entry(KERNEL_EXIT_SWITCH_CODE); 300 add_event_entry(KERNEL_EXIT_SWITCH_CODE);
284} 301}
285 302
286static void 303static void
287add_user_ctx_switch(struct task_struct const * task, unsigned long cookie) 304add_user_ctx_switch(struct task_struct const *task, unsigned long cookie)
288{ 305{
289 add_event_entry(ESCAPE_CODE); 306 add_event_entry(ESCAPE_CODE);
290 add_event_entry(CTX_SWITCH_CODE); 307 add_event_entry(CTX_SWITCH_CODE);
291 add_event_entry(task->pid); 308 add_event_entry(task->pid);
292 add_event_entry(cookie); 309 add_event_entry(cookie);
293 /* Another code for daemon back-compat */ 310 /* Another code for daemon back-compat */
@@ -296,7 +313,7 @@ add_user_ctx_switch(struct task_struct const * task, unsigned long cookie)
296 add_event_entry(task->tgid); 313 add_event_entry(task->tgid);
297} 314}
298 315
299 316
300static void add_cookie_switch(unsigned long cookie) 317static void add_cookie_switch(unsigned long cookie)
301{ 318{
302 add_event_entry(ESCAPE_CODE); 319 add_event_entry(ESCAPE_CODE);
@@ -304,13 +321,78 @@ static void add_cookie_switch(unsigned long cookie)
304 add_event_entry(cookie); 321 add_event_entry(cookie);
305} 322}
306 323
307 324
308static void add_trace_begin(void) 325static void add_trace_begin(void)
309{ 326{
310 add_event_entry(ESCAPE_CODE); 327 add_event_entry(ESCAPE_CODE);
311 add_event_entry(TRACE_BEGIN_CODE); 328 add_event_entry(TRACE_BEGIN_CODE);
312} 329}
313 330
331#ifdef CONFIG_OPROFILE_IBS
332
333#define IBS_FETCH_CODE_SIZE 2
334#define IBS_OP_CODE_SIZE 5
335#define IBS_EIP(offset) \
336 (((struct op_sample *)&cpu_buf->buffer[(offset)])->eip)
337#define IBS_EVENT(offset) \
338 (((struct op_sample *)&cpu_buf->buffer[(offset)])->event)
339
340/*
341 * Add IBS fetch and op entries to event buffer
342 */
343static void add_ibs_begin(struct oprofile_cpu_buffer *cpu_buf, int code,
344 int in_kernel, struct mm_struct *mm)
345{
346 unsigned long rip;
347 int i, count;
348 unsigned long ibs_cookie = 0;
349 off_t offset;
350
351 increment_tail(cpu_buf); /* move to RIP entry */
352
353 rip = IBS_EIP(cpu_buf->tail_pos);
354
355#ifdef __LP64__
356 rip += IBS_EVENT(cpu_buf->tail_pos) << 32;
357#endif
358
359 if (mm) {
360 ibs_cookie = lookup_dcookie(mm, rip, &offset);
361
362 if (ibs_cookie == NO_COOKIE)
363 offset = rip;
364 if (ibs_cookie == INVALID_COOKIE) {
365 atomic_inc(&oprofile_stats.sample_lost_no_mapping);
366 offset = rip;
367 }
368 if (ibs_cookie != last_cookie) {
369 add_cookie_switch(ibs_cookie);
370 last_cookie = ibs_cookie;
371 }
372 } else
373 offset = rip;
374
375 add_event_entry(ESCAPE_CODE);
376 add_event_entry(code);
377 add_event_entry(offset); /* Offset from Dcookie */
378
379 /* we send the Dcookie offset, but send the raw Linear Add also*/
380 add_event_entry(IBS_EIP(cpu_buf->tail_pos));
381 add_event_entry(IBS_EVENT(cpu_buf->tail_pos));
382
383 if (code == IBS_FETCH_CODE)
384 count = IBS_FETCH_CODE_SIZE; /*IBS FETCH is 2 int64s*/
385 else
386 count = IBS_OP_CODE_SIZE; /*IBS OP is 5 int64s*/
387
388 for (i = 0; i < count; i++) {
389 increment_tail(cpu_buf);
390 add_event_entry(IBS_EIP(cpu_buf->tail_pos));
391 add_event_entry(IBS_EVENT(cpu_buf->tail_pos));
392 }
393}
394
395#endif
314 396
315static void add_sample_entry(unsigned long offset, unsigned long event) 397static void add_sample_entry(unsigned long offset, unsigned long event)
316{ 398{
@@ -319,13 +401,13 @@ static void add_sample_entry(unsigned long offset, unsigned long event)
319} 401}
320 402
321 403
322static int add_us_sample(struct mm_struct * mm, struct op_sample * s) 404static int add_us_sample(struct mm_struct *mm, struct op_sample *s)
323{ 405{
324 unsigned long cookie; 406 unsigned long cookie;
325 off_t offset; 407 off_t offset;
326 408
327 cookie = lookup_dcookie(mm, s->eip, &offset); 409 cookie = lookup_dcookie(mm, s->eip, &offset);
328 410
329 if (cookie == INVALID_COOKIE) { 411 if (cookie == INVALID_COOKIE) {
330 atomic_inc(&oprofile_stats.sample_lost_no_mapping); 412 atomic_inc(&oprofile_stats.sample_lost_no_mapping);
331 return 0; 413 return 0;
@@ -341,13 +423,13 @@ static int add_us_sample(struct mm_struct * mm, struct op_sample * s)
341 return 1; 423 return 1;
342} 424}
343 425
344 426
345/* Add a sample to the global event buffer. If possible the 427/* Add a sample to the global event buffer. If possible the
346 * sample is converted into a persistent dentry/offset pair 428 * sample is converted into a persistent dentry/offset pair
347 * for later lookup from userspace. 429 * for later lookup from userspace.
348 */ 430 */
349static int 431static int
350add_sample(struct mm_struct * mm, struct op_sample * s, int in_kernel) 432add_sample(struct mm_struct *mm, struct op_sample *s, int in_kernel)
351{ 433{
352 if (in_kernel) { 434 if (in_kernel) {
353 add_sample_entry(s->eip, s->event); 435 add_sample_entry(s->eip, s->event);
@@ -359,9 +441,9 @@ add_sample(struct mm_struct * mm, struct op_sample * s, int in_kernel)
359 } 441 }
360 return 0; 442 return 0;
361} 443}
362
363 444
364static void release_mm(struct mm_struct * mm) 445
446static void release_mm(struct mm_struct *mm)
365{ 447{
366 if (!mm) 448 if (!mm)
367 return; 449 return;
@@ -370,9 +452,9 @@ static void release_mm(struct mm_struct * mm)
370} 452}
371 453
372 454
373static struct mm_struct * take_tasks_mm(struct task_struct * task) 455static struct mm_struct *take_tasks_mm(struct task_struct *task)
374{ 456{
375 struct mm_struct * mm = get_task_mm(task); 457 struct mm_struct *mm = get_task_mm(task);
376 if (mm) 458 if (mm)
377 down_read(&mm->mmap_sem); 459 down_read(&mm->mmap_sem);
378 return mm; 460 return mm;
@@ -383,10 +465,10 @@ static inline int is_code(unsigned long val)
383{ 465{
384 return val == ESCAPE_CODE; 466 return val == ESCAPE_CODE;
385} 467}
386 468
387 469
388/* "acquire" as many cpu buffer slots as we can */ 470/* "acquire" as many cpu buffer slots as we can */
389static unsigned long get_slots(struct oprofile_cpu_buffer * b) 471static unsigned long get_slots(struct oprofile_cpu_buffer *b)
390{ 472{
391 unsigned long head = b->head_pos; 473 unsigned long head = b->head_pos;
392 unsigned long tail = b->tail_pos; 474 unsigned long tail = b->tail_pos;
@@ -412,19 +494,6 @@ static unsigned long get_slots(struct oprofile_cpu_buffer * b)
412} 494}
413 495
414 496
415static void increment_tail(struct oprofile_cpu_buffer * b)
416{
417 unsigned long new_tail = b->tail_pos + 1;
418
419 rmb();
420
421 if (new_tail < b->buffer_size)
422 b->tail_pos = new_tail;
423 else
424 b->tail_pos = 0;
425}
426
427
428/* Move tasks along towards death. Any tasks on dead_tasks 497/* Move tasks along towards death. Any tasks on dead_tasks
429 * will definitely have no remaining references in any 498 * will definitely have no remaining references in any
430 * CPU buffers at this point, because we use two lists, 499 * CPU buffers at this point, because we use two lists,
@@ -435,8 +504,8 @@ static void process_task_mortuary(void)
435{ 504{
436 unsigned long flags; 505 unsigned long flags;
437 LIST_HEAD(local_dead_tasks); 506 LIST_HEAD(local_dead_tasks);
438 struct task_struct * task; 507 struct task_struct *task;
439 struct task_struct * ttask; 508 struct task_struct *ttask;
440 509
441 spin_lock_irqsave(&task_mortuary, flags); 510 spin_lock_irqsave(&task_mortuary, flags);
442 511
@@ -493,7 +562,7 @@ void sync_buffer(int cpu)
493{ 562{
494 struct oprofile_cpu_buffer *cpu_buf = &per_cpu(cpu_buffer, cpu); 563 struct oprofile_cpu_buffer *cpu_buf = &per_cpu(cpu_buffer, cpu);
495 struct mm_struct *mm = NULL; 564 struct mm_struct *mm = NULL;
496 struct task_struct * new; 565 struct task_struct *new;
497 unsigned long cookie = 0; 566 unsigned long cookie = 0;
498 int in_kernel = 1; 567 int in_kernel = 1;
499 unsigned int i; 568 unsigned int i;
@@ -501,7 +570,7 @@ void sync_buffer(int cpu)
501 unsigned long available; 570 unsigned long available;
502 571
503 mutex_lock(&buffer_mutex); 572 mutex_lock(&buffer_mutex);
504 573
505 add_cpu_switch(cpu); 574 add_cpu_switch(cpu);
506 575
507 /* Remember, only we can modify tail_pos */ 576 /* Remember, only we can modify tail_pos */
@@ -509,8 +578,8 @@ void sync_buffer(int cpu)
509 available = get_slots(cpu_buf); 578 available = get_slots(cpu_buf);
510 579
511 for (i = 0; i < available; ++i) { 580 for (i = 0; i < available; ++i) {
512 struct op_sample * s = &cpu_buf->buffer[cpu_buf->tail_pos]; 581 struct op_sample *s = &cpu_buf->buffer[cpu_buf->tail_pos];
513 582
514 if (is_code(s->eip)) { 583 if (is_code(s->eip)) {
515 if (s->event <= CPU_IS_KERNEL) { 584 if (s->event <= CPU_IS_KERNEL) {
516 /* kernel/userspace switch */ 585 /* kernel/userspace switch */
@@ -521,8 +590,18 @@ void sync_buffer(int cpu)
521 } else if (s->event == CPU_TRACE_BEGIN) { 590 } else if (s->event == CPU_TRACE_BEGIN) {
522 state = sb_bt_start; 591 state = sb_bt_start;
523 add_trace_begin(); 592 add_trace_begin();
593#ifdef CONFIG_OPROFILE_IBS
594 } else if (s->event == IBS_FETCH_BEGIN) {
595 state = sb_bt_start;
596 add_ibs_begin(cpu_buf,
597 IBS_FETCH_CODE, in_kernel, mm);
598 } else if (s->event == IBS_OP_BEGIN) {
599 state = sb_bt_start;
600 add_ibs_begin(cpu_buf,
601 IBS_OP_CODE, in_kernel, mm);
602#endif
524 } else { 603 } else {
525 struct mm_struct * oldmm = mm; 604 struct mm_struct *oldmm = mm;
526 605
527 /* userspace context switch */ 606 /* userspace context switch */
528 new = (struct task_struct *)s->event; 607 new = (struct task_struct *)s->event;
@@ -533,13 +612,11 @@ void sync_buffer(int cpu)
533 cookie = get_exec_dcookie(mm); 612 cookie = get_exec_dcookie(mm);
534 add_user_ctx_switch(new, cookie); 613 add_user_ctx_switch(new, cookie);
535 } 614 }
536 } else { 615 } else if (state >= sb_bt_start &&
537 if (state >= sb_bt_start && 616 !add_sample(mm, s, in_kernel)) {
538 !add_sample(mm, s, in_kernel)) { 617 if (state == sb_bt_start) {
539 if (state == sb_bt_start) { 618 state = sb_bt_ignore;
540 state = sb_bt_ignore; 619 atomic_inc(&oprofile_stats.bt_lost_no_mapping);
541 atomic_inc(&oprofile_stats.bt_lost_no_mapping);
542 }
543 } 620 }
544 } 621 }
545 622
diff --git a/drivers/oprofile/cpu_buffer.c b/drivers/oprofile/cpu_buffer.c
index 7ba78e6d210e..e1bd5a937f6c 100644
--- a/drivers/oprofile/cpu_buffer.c
+++ b/drivers/oprofile/cpu_buffer.c
@@ -5,6 +5,7 @@
5 * @remark Read the file COPYING 5 * @remark Read the file COPYING
6 * 6 *
7 * @author John Levon <levon@movementarian.org> 7 * @author John Levon <levon@movementarian.org>
8 * @author Barry Kasindorf <barry.kasindorf@amd.com>
8 * 9 *
9 * Each CPU has a local buffer that stores PC value/event 10 * Each CPU has a local buffer that stores PC value/event
10 * pairs. We also log context switches when we notice them. 11 * pairs. We also log context switches when we notice them.
@@ -209,7 +210,7 @@ static int log_sample(struct oprofile_cpu_buffer * cpu_buf, unsigned long pc,
209 return 1; 210 return 1;
210} 211}
211 212
212static int oprofile_begin_trace(struct oprofile_cpu_buffer * cpu_buf) 213static int oprofile_begin_trace(struct oprofile_cpu_buffer *cpu_buf)
213{ 214{
214 if (nr_available_slots(cpu_buf) < 4) { 215 if (nr_available_slots(cpu_buf) < 4) {
215 cpu_buf->sample_lost_overflow++; 216 cpu_buf->sample_lost_overflow++;
@@ -254,6 +255,75 @@ void oprofile_add_sample(struct pt_regs * const regs, unsigned long event)
254 oprofile_add_ext_sample(pc, regs, event, is_kernel); 255 oprofile_add_ext_sample(pc, regs, event, is_kernel);
255} 256}
256 257
258#ifdef CONFIG_OPROFILE_IBS
259
260#define MAX_IBS_SAMPLE_SIZE 14
261static int log_ibs_sample(struct oprofile_cpu_buffer *cpu_buf,
262 unsigned long pc, int is_kernel, unsigned int *ibs, int ibs_code)
263{
264 struct task_struct *task;
265
266 cpu_buf->sample_received++;
267
268 if (nr_available_slots(cpu_buf) < MAX_IBS_SAMPLE_SIZE) {
269 cpu_buf->sample_lost_overflow++;
270 return 0;
271 }
272
273 is_kernel = !!is_kernel;
274
275 /* notice a switch from user->kernel or vice versa */
276 if (cpu_buf->last_is_kernel != is_kernel) {
277 cpu_buf->last_is_kernel = is_kernel;
278 add_code(cpu_buf, is_kernel);
279 }
280
281 /* notice a task switch */
282 if (!is_kernel) {
283 task = current;
284
285 if (cpu_buf->last_task != task) {
286 cpu_buf->last_task = task;
287 add_code(cpu_buf, (unsigned long)task);
288 }
289 }
290
291 add_code(cpu_buf, ibs_code);
292 add_sample(cpu_buf, ibs[0], ibs[1]);
293 add_sample(cpu_buf, ibs[2], ibs[3]);
294 add_sample(cpu_buf, ibs[4], ibs[5]);
295
296 if (ibs_code == IBS_OP_BEGIN) {
297 add_sample(cpu_buf, ibs[6], ibs[7]);
298 add_sample(cpu_buf, ibs[8], ibs[9]);
299 add_sample(cpu_buf, ibs[10], ibs[11]);
300 }
301
302 return 1;
303}
304
305void oprofile_add_ibs_sample(struct pt_regs *const regs,
306 unsigned int * const ibs_sample, u8 code)
307{
308 int is_kernel = !user_mode(regs);
309 unsigned long pc = profile_pc(regs);
310
311 struct oprofile_cpu_buffer *cpu_buf =
312 &per_cpu(cpu_buffer, smp_processor_id());
313
314 if (!backtrace_depth) {
315 log_ibs_sample(cpu_buf, pc, is_kernel, ibs_sample, code);
316 return;
317 }
318
319 /* if log_sample() fails we can't backtrace since we lost the source
320 * of this event */
321 if (log_ibs_sample(cpu_buf, pc, is_kernel, ibs_sample, code))
322 oprofile_ops.backtrace(regs, backtrace_depth);
323}
324
325#endif
326
257void oprofile_add_pc(unsigned long pc, int is_kernel, unsigned long event) 327void oprofile_add_pc(unsigned long pc, int is_kernel, unsigned long event)
258{ 328{
259 struct oprofile_cpu_buffer *cpu_buf = &__get_cpu_var(cpu_buffer); 329 struct oprofile_cpu_buffer *cpu_buf = &__get_cpu_var(cpu_buffer);
@@ -296,7 +366,7 @@ static void wq_sync_buffer(struct work_struct *work)
296 struct oprofile_cpu_buffer * b = 366 struct oprofile_cpu_buffer * b =
297 container_of(work, struct oprofile_cpu_buffer, work.work); 367 container_of(work, struct oprofile_cpu_buffer, work.work);
298 if (b->cpu != smp_processor_id()) { 368 if (b->cpu != smp_processor_id()) {
299 printk("WQ on CPU%d, prefer CPU%d\n", 369 printk(KERN_DEBUG "WQ on CPU%d, prefer CPU%d\n",
300 smp_processor_id(), b->cpu); 370 smp_processor_id(), b->cpu);
301 } 371 }
302 sync_buffer(b->cpu); 372 sync_buffer(b->cpu);
diff --git a/drivers/oprofile/cpu_buffer.h b/drivers/oprofile/cpu_buffer.h
index c3e366b52261..9c44d004da69 100644
--- a/drivers/oprofile/cpu_buffer.h
+++ b/drivers/oprofile/cpu_buffer.h
@@ -55,5 +55,7 @@ void cpu_buffer_reset(struct oprofile_cpu_buffer * cpu_buf);
55/* transient events for the CPU buffer -> event buffer */ 55/* transient events for the CPU buffer -> event buffer */
56#define CPU_IS_KERNEL 1 56#define CPU_IS_KERNEL 1
57#define CPU_TRACE_BEGIN 2 57#define CPU_TRACE_BEGIN 2
58#define IBS_FETCH_BEGIN 3
59#define IBS_OP_BEGIN 4
58 60
59#endif /* OPROFILE_CPU_BUFFER_H */ 61#endif /* OPROFILE_CPU_BUFFER_H */
diff --git a/drivers/s390/char/fs3270.c b/drivers/s390/char/fs3270.c
index d18e6d2e0b49..40759c33477d 100644
--- a/drivers/s390/char/fs3270.c
+++ b/drivers/s390/char/fs3270.c
@@ -418,25 +418,22 @@ fs3270_open(struct inode *inode, struct file *filp)
418{ 418{
419 struct fs3270 *fp; 419 struct fs3270 *fp;
420 struct idal_buffer *ib; 420 struct idal_buffer *ib;
421 int minor, rc; 421 int minor, rc = 0;
422 422
423 if (imajor(filp->f_path.dentry->d_inode) != IBM_FS3270_MAJOR) 423 if (imajor(filp->f_path.dentry->d_inode) != IBM_FS3270_MAJOR)
424 return -ENODEV; 424 return -ENODEV;
425 lock_kernel();
426 minor = iminor(filp->f_path.dentry->d_inode); 425 minor = iminor(filp->f_path.dentry->d_inode);
427 /* Check for minor 0 multiplexer. */ 426 /* Check for minor 0 multiplexer. */
428 if (minor == 0) { 427 if (minor == 0) {
429 struct tty_struct *tty; 428 struct tty_struct *tty = get_current_tty();
430 mutex_lock(&tty_mutex);
431 tty = get_current_tty();
432 if (!tty || tty->driver->major != IBM_TTY3270_MAJOR) { 429 if (!tty || tty->driver->major != IBM_TTY3270_MAJOR) {
433 mutex_unlock(&tty_mutex); 430 tty_kref_put(tty);
434 rc = -ENODEV; 431 return -ENODEV;
435 goto out;
436 } 432 }
437 minor = tty->index + RAW3270_FIRSTMINOR; 433 minor = tty->index + RAW3270_FIRSTMINOR;
438 mutex_unlock(&tty_mutex); 434 tty_kref_put(tty);
439 } 435 }
436 lock_kernel();
440 /* Check if some other program is already using fullscreen mode. */ 437 /* Check if some other program is already using fullscreen mode. */
441 fp = (struct fs3270 *) raw3270_find_view(&fs3270_fn, minor); 438 fp = (struct fs3270 *) raw3270_find_view(&fs3270_fn, minor);
442 if (!IS_ERR(fp)) { 439 if (!IS_ERR(fp)) {
@@ -478,7 +475,7 @@ fs3270_open(struct inode *inode, struct file *filp)
478 filp->private_data = fp; 475 filp->private_data = fp;
479out: 476out:
480 unlock_kernel(); 477 unlock_kernel();
481 return 0; 478 return rc;
482} 479}
483 480
484/* 481/*
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
index 9ccc563d8730..d4104a3bbe87 100644
--- a/drivers/serial/8250.c
+++ b/drivers/serial/8250.c
@@ -44,6 +44,10 @@
44 44
45#include "8250.h" 45#include "8250.h"
46 46
47#ifdef CONFIG_SPARC
48#include "suncore.h"
49#endif
50
47/* 51/*
48 * Configuration: 52 * Configuration:
49 * share_irqs - whether we pass IRQF_SHARED to request_irq(). This option 53 * share_irqs - whether we pass IRQF_SHARED to request_irq(). This option
@@ -53,6 +57,13 @@ static unsigned int share_irqs = SERIAL8250_SHARE_IRQS;
53 57
54static unsigned int nr_uarts = CONFIG_SERIAL_8250_RUNTIME_UARTS; 58static unsigned int nr_uarts = CONFIG_SERIAL_8250_RUNTIME_UARTS;
55 59
60static struct uart_driver serial8250_reg;
61
62static int serial_index(struct uart_port *port)
63{
64 return (serial8250_reg.minor - 64) + port->line;
65}
66
56/* 67/*
57 * Debugging. 68 * Debugging.
58 */ 69 */
@@ -536,7 +547,7 @@ static unsigned int serial_icr_read(struct uart_8250_port *up, int offset)
536/* 547/*
537 * FIFO support. 548 * FIFO support.
538 */ 549 */
539static inline void serial8250_clear_fifos(struct uart_8250_port *p) 550static void serial8250_clear_fifos(struct uart_8250_port *p)
540{ 551{
541 if (p->capabilities & UART_CAP_FIFO) { 552 if (p->capabilities & UART_CAP_FIFO) {
542 serial_outp(p, UART_FCR, UART_FCR_ENABLE_FIFO); 553 serial_outp(p, UART_FCR, UART_FCR_ENABLE_FIFO);
@@ -551,7 +562,7 @@ static inline void serial8250_clear_fifos(struct uart_8250_port *p)
551 * capability" bit enabled. Note that on XR16C850s, we need to 562 * capability" bit enabled. Note that on XR16C850s, we need to
552 * reset LCR to write to IER. 563 * reset LCR to write to IER.
553 */ 564 */
554static inline void serial8250_set_sleep(struct uart_8250_port *p, int sleep) 565static void serial8250_set_sleep(struct uart_8250_port *p, int sleep)
555{ 566{
556 if (p->capabilities & UART_CAP_SLEEP) { 567 if (p->capabilities & UART_CAP_SLEEP) {
557 if (p->capabilities & UART_CAP_EFR) { 568 if (p->capabilities & UART_CAP_EFR) {
@@ -993,7 +1004,7 @@ static void autoconfig(struct uart_8250_port *up, unsigned int probeflags)
993 return; 1004 return;
994 1005
995 DEBUG_AUTOCONF("ttyS%d: autoconf (0x%04x, 0x%p): ", 1006 DEBUG_AUTOCONF("ttyS%d: autoconf (0x%04x, 0x%p): ",
996 up->port.line, up->port.iobase, up->port.membase); 1007 serial_index(&up->port), up->port.iobase, up->port.membase);
997 1008
998 /* 1009 /*
999 * We really do need global IRQs disabled here - we're going to 1010 * We really do need global IRQs disabled here - we're going to
@@ -1128,8 +1139,8 @@ static void autoconfig(struct uart_8250_port *up, unsigned int probeflags)
1128 if (up->capabilities != uart_config[up->port.type].flags) { 1139 if (up->capabilities != uart_config[up->port.type].flags) {
1129 printk(KERN_WARNING 1140 printk(KERN_WARNING
1130 "ttyS%d: detected caps %08x should be %08x\n", 1141 "ttyS%d: detected caps %08x should be %08x\n",
1131 up->port.line, up->capabilities, 1142 serial_index(&up->port), up->capabilities,
1132 uart_config[up->port.type].flags); 1143 uart_config[up->port.type].flags);
1133 } 1144 }
1134 1145
1135 up->port.fifosize = uart_config[up->port.type].fifo_size; 1146 up->port.fifosize = uart_config[up->port.type].fifo_size;
@@ -1424,8 +1435,7 @@ static unsigned int check_modem_status(struct uart_8250_port *up)
1424/* 1435/*
1425 * This handles the interrupt from one port. 1436 * This handles the interrupt from one port.
1426 */ 1437 */
1427static inline void 1438static void serial8250_handle_port(struct uart_8250_port *up)
1428serial8250_handle_port(struct uart_8250_port *up)
1429{ 1439{
1430 unsigned int status; 1440 unsigned int status;
1431 unsigned long flags; 1441 unsigned long flags;
@@ -1719,7 +1729,7 @@ static void serial8250_break_ctl(struct uart_port *port, int break_state)
1719/* 1729/*
1720 * Wait for transmitter & holding register to empty 1730 * Wait for transmitter & holding register to empty
1721 */ 1731 */
1722static inline void wait_for_xmitr(struct uart_8250_port *up, int bits) 1732static void wait_for_xmitr(struct uart_8250_port *up, int bits)
1723{ 1733{
1724 unsigned int status, tmout = 10000; 1734 unsigned int status, tmout = 10000;
1725 1735
@@ -1854,7 +1864,8 @@ static int serial8250_startup(struct uart_port *port)
1854 */ 1864 */
1855 if (!(up->port.flags & UPF_BUGGY_UART) && 1865 if (!(up->port.flags & UPF_BUGGY_UART) &&
1856 (serial_inp(up, UART_LSR) == 0xff)) { 1866 (serial_inp(up, UART_LSR) == 0xff)) {
1857 printk("ttyS%d: LSR safety check engaged!\n", up->port.line); 1867 printk(KERN_INFO "ttyS%d: LSR safety check engaged!\n",
1868 serial_index(&up->port));
1858 return -ENODEV; 1869 return -ENODEV;
1859 } 1870 }
1860 1871
@@ -1909,7 +1920,8 @@ static int serial8250_startup(struct uart_port *port)
1909 */ 1920 */
1910 if (!(iir1 & UART_IIR_NO_INT) && (iir & UART_IIR_NO_INT)) { 1921 if (!(iir1 & UART_IIR_NO_INT) && (iir & UART_IIR_NO_INT)) {
1911 up->bugs |= UART_BUG_THRE; 1922 up->bugs |= UART_BUG_THRE;
1912 pr_debug("ttyS%d - using backup timer\n", port->line); 1923 pr_debug("ttyS%d - using backup timer\n",
1924 serial_index(port));
1913 } 1925 }
1914 } 1926 }
1915 1927
@@ -1969,7 +1981,7 @@ static int serial8250_startup(struct uart_port *port)
1969 if (!(up->bugs & UART_BUG_TXEN)) { 1981 if (!(up->bugs & UART_BUG_TXEN)) {
1970 up->bugs |= UART_BUG_TXEN; 1982 up->bugs |= UART_BUG_TXEN;
1971 pr_debug("ttyS%d - enabling bad tx status workarounds\n", 1983 pr_debug("ttyS%d - enabling bad tx status workarounds\n",
1972 port->line); 1984 serial_index(port));
1973 } 1985 }
1974 } else { 1986 } else {
1975 up->bugs &= ~UART_BUG_TXEN; 1987 up->bugs &= ~UART_BUG_TXEN;
@@ -2630,7 +2642,6 @@ static int serial8250_console_early_setup(void)
2630 return serial8250_find_port_for_earlycon(); 2642 return serial8250_find_port_for_earlycon();
2631} 2643}
2632 2644
2633static struct uart_driver serial8250_reg;
2634static struct console serial8250_console = { 2645static struct console serial8250_console = {
2635 .name = "ttyS", 2646 .name = "ttyS",
2636 .write = serial8250_console_write, 2647 .write = serial8250_console_write,
@@ -2677,7 +2688,6 @@ static struct uart_driver serial8250_reg = {
2677 .dev_name = "ttyS", 2688 .dev_name = "ttyS",
2678 .major = TTY_MAJOR, 2689 .major = TTY_MAJOR,
2679 .minor = 64, 2690 .minor = 64,
2680 .nr = UART_NR,
2681 .cons = SERIAL8250_CONSOLE, 2691 .cons = SERIAL8250_CONSOLE,
2682}; 2692};
2683 2693
@@ -2959,10 +2969,12 @@ static int __init serial8250_init(void)
2959 "%d ports, IRQ sharing %sabled\n", nr_uarts, 2969 "%d ports, IRQ sharing %sabled\n", nr_uarts,
2960 share_irqs ? "en" : "dis"); 2970 share_irqs ? "en" : "dis");
2961 2971
2962 for (i = 0; i < NR_IRQS; i++) 2972#ifdef CONFIG_SPARC
2963 spin_lock_init(&irq_lists[i].lock); 2973 ret = sunserial_register_minors(&serial8250_reg, UART_NR);
2964 2974#else
2975 serial8250_reg.nr = UART_NR;
2965 ret = uart_register_driver(&serial8250_reg); 2976 ret = uart_register_driver(&serial8250_reg);
2977#endif
2966 if (ret) 2978 if (ret)
2967 goto out; 2979 goto out;
2968 2980
@@ -2987,7 +2999,11 @@ static int __init serial8250_init(void)
2987 put_dev: 2999 put_dev:
2988 platform_device_put(serial8250_isa_devs); 3000 platform_device_put(serial8250_isa_devs);
2989 unreg_uart_drv: 3001 unreg_uart_drv:
3002#ifdef CONFIG_SPARC
3003 sunserial_unregister_minors(&serial8250_reg, UART_NR);
3004#else
2990 uart_unregister_driver(&serial8250_reg); 3005 uart_unregister_driver(&serial8250_reg);
3006#endif
2991 out: 3007 out:
2992 return ret; 3008 return ret;
2993} 3009}
@@ -3006,7 +3022,11 @@ static void __exit serial8250_exit(void)
3006 platform_driver_unregister(&serial8250_isa_driver); 3022 platform_driver_unregister(&serial8250_isa_driver);
3007 platform_device_unregister(isa_dev); 3023 platform_device_unregister(isa_dev);
3008 3024
3025#ifdef CONFIG_SPARC
3026 sunserial_unregister_minors(&serial8250_reg, UART_NR);
3027#else
3009 uart_unregister_driver(&serial8250_reg); 3028 uart_unregister_driver(&serial8250_reg);
3029#endif
3010} 3030}
3011 3031
3012module_init(serial8250_init); 3032module_init(serial8250_init);
diff --git a/drivers/serial/8250_pci.c b/drivers/serial/8250_pci.c
index c2f23933155b..c014ffb110e9 100644
--- a/drivers/serial/8250_pci.c
+++ b/drivers/serial/8250_pci.c
@@ -2041,9 +2041,9 @@ static int pciserial_resume_one(struct pci_dev *dev)
2041 * The device may have been disabled. Re-enable it. 2041 * The device may have been disabled. Re-enable it.
2042 */ 2042 */
2043 err = pci_enable_device(dev); 2043 err = pci_enable_device(dev);
2044 /* FIXME: We cannot simply error out here */
2044 if (err) 2045 if (err)
2045 return err; 2046 printk(KERN_ERR "pciserial: Unable to re-enable ports, trying to continue.\n");
2046
2047 pciserial_resume_ports(priv); 2047 pciserial_resume_ports(priv);
2048 } 2048 }
2049 return 0; 2049 return 0;
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index 77cb34270fc1..31786b3b0a68 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -9,7 +9,6 @@ menu "Serial drivers"
9# The new 8250/16550 serial drivers 9# The new 8250/16550 serial drivers
10config SERIAL_8250 10config SERIAL_8250
11 tristate "8250/16550 and compatible serial support" 11 tristate "8250/16550 and compatible serial support"
12 depends on (BROKEN || !SPARC)
13 select SERIAL_CORE 12 select SERIAL_CORE
14 ---help--- 13 ---help---
15 This selects whether you want to include the driver for the standard 14 This selects whether you want to include the driver for the standard
@@ -994,24 +993,12 @@ config SERIAL_68328_RTS_CTS
994 bool "Support RTS/CTS on 68328 serial port" 993 bool "Support RTS/CTS on 68328 serial port"
995 depends on SERIAL_68328 994 depends on SERIAL_68328
996 995
997config SERIAL_COLDFIRE
998 bool "ColdFire serial support (DEPRECATED)"
999 depends on COLDFIRE
1000 help
1001 This driver supports the built-in serial ports of the Motorola ColdFire
1002 family of CPUs.
1003 This driver is deprecated because it supports only the old interface
1004 for serial drivers and features like magic keys are not working.
1005 Please switch to the new style driver because this driver will be
1006 removed soon.
1007
1008config SERIAL_MCF 996config SERIAL_MCF
1009 bool "Coldfire serial support (new style driver)" 997 bool "Coldfire serial support"
1010 depends on COLDFIRE 998 depends on COLDFIRE
1011 select SERIAL_CORE 999 select SERIAL_CORE
1012 help 1000 help
1013 This new serial driver supports the Freescale Coldfire serial ports 1001 This serial driver supports the Freescale Coldfire serial ports.
1014 using the new serial driver subsystem.
1015 1002
1016config SERIAL_MCF_BAUDRATE 1003config SERIAL_MCF_BAUDRATE
1017 int "Default baudrate for Coldfire serial ports" 1004 int "Default baudrate for Coldfire serial ports"
diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile
index 7e7383e890d8..0c17c8ddb19d 100644
--- a/drivers/serial/Makefile
+++ b/drivers/serial/Makefile
@@ -4,6 +4,16 @@
4 4
5obj-$(CONFIG_SERIAL_CORE) += serial_core.o 5obj-$(CONFIG_SERIAL_CORE) += serial_core.o
6obj-$(CONFIG_SERIAL_21285) += 21285.o 6obj-$(CONFIG_SERIAL_21285) += 21285.o
7
8# These Sparc drivers have to appear before others such as 8250
9# which share ttySx minor node space. Otherwise console device
10# names change and other unplesantries.
11obj-$(CONFIG_SERIAL_SUNCORE) += suncore.o
12obj-$(CONFIG_SERIAL_SUNHV) += sunhv.o
13obj-$(CONFIG_SERIAL_SUNZILOG) += sunzilog.o
14obj-$(CONFIG_SERIAL_SUNSU) += sunsu.o
15obj-$(CONFIG_SERIAL_SUNSAB) += sunsab.o
16
7obj-$(CONFIG_SERIAL_8250) += 8250.o 17obj-$(CONFIG_SERIAL_8250) += 8250.o
8obj-$(CONFIG_SERIAL_8250_PNP) += 8250_pnp.o 18obj-$(CONFIG_SERIAL_8250_PNP) += 8250_pnp.o
9obj-$(CONFIG_SERIAL_8250_GSC) += 8250_gsc.o 19obj-$(CONFIG_SERIAL_8250_GSC) += 8250_gsc.o
@@ -31,16 +41,10 @@ obj-$(CONFIG_SERIAL_S3C2400) += s3c2400.o
31obj-$(CONFIG_SERIAL_S3C2410) += s3c2410.o 41obj-$(CONFIG_SERIAL_S3C2410) += s3c2410.o
32obj-$(CONFIG_SERIAL_S3C2412) += s3c2412.o 42obj-$(CONFIG_SERIAL_S3C2412) += s3c2412.o
33obj-$(CONFIG_SERIAL_S3C2440) += s3c2440.o 43obj-$(CONFIG_SERIAL_S3C2440) += s3c2440.o
34obj-$(CONFIG_SERIAL_SUNCORE) += suncore.o
35obj-$(CONFIG_SERIAL_SUNHV) += sunhv.o
36obj-$(CONFIG_SERIAL_SUNZILOG) += sunzilog.o
37obj-$(CONFIG_SERIAL_IP22_ZILOG) += ip22zilog.o 44obj-$(CONFIG_SERIAL_IP22_ZILOG) += ip22zilog.o
38obj-$(CONFIG_SERIAL_SUNSU) += sunsu.o
39obj-$(CONFIG_SERIAL_SUNSAB) += sunsab.o
40obj-$(CONFIG_SERIAL_MUX) += mux.o 45obj-$(CONFIG_SERIAL_MUX) += mux.o
41obj-$(CONFIG_SERIAL_68328) += 68328serial.o 46obj-$(CONFIG_SERIAL_68328) += 68328serial.o
42obj-$(CONFIG_SERIAL_68360) += 68360serial.o 47obj-$(CONFIG_SERIAL_68360) += 68360serial.o
43obj-$(CONFIG_SERIAL_COLDFIRE) += mcfserial.o
44obj-$(CONFIG_SERIAL_MCF) += mcf.o 48obj-$(CONFIG_SERIAL_MCF) += mcf.o
45obj-$(CONFIG_SERIAL_PMACZILOG) += pmac_zilog.o 49obj-$(CONFIG_SERIAL_PMACZILOG) += pmac_zilog.o
46obj-$(CONFIG_SERIAL_LH7A40X) += serial_lh7a40x.o 50obj-$(CONFIG_SERIAL_LH7A40X) += serial_lh7a40x.o
diff --git a/drivers/serial/bfin_5xx.c b/drivers/serial/bfin_5xx.c
index 4a0d30bed9f1..569f0e2476c6 100644
--- a/drivers/serial/bfin_5xx.c
+++ b/drivers/serial/bfin_5xx.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Blackfin On-Chip Serial Driver 2 * Blackfin On-Chip Serial Driver
3 * 3 *
4 * Copyright 2006-2007 Analog Devices Inc. 4 * Copyright 2006-2008 Analog Devices Inc.
5 * 5 *
6 * Enter bugs at http://blackfin.uclinux.org/ 6 * Enter bugs at http://blackfin.uclinux.org/
7 * 7 *
@@ -42,6 +42,9 @@
42#define BFIN_SERIAL_MAJOR 204 42#define BFIN_SERIAL_MAJOR 204
43#define BFIN_SERIAL_MINOR 64 43#define BFIN_SERIAL_MINOR 64
44 44
45static struct bfin_serial_port bfin_serial_ports[BFIN_UART_NR_PORTS];
46static int nr_active_ports = ARRAY_SIZE(bfin_serial_resource);
47
45/* 48/*
46 * Setup for console. Argument comes from the menuconfig 49 * Setup for console. Argument comes from the menuconfig
47 */ 50 */
@@ -126,13 +129,13 @@ static int kgdb_entry_state;
126void kgdb_put_debug_char(int chr) 129void kgdb_put_debug_char(int chr)
127{ 130{
128 struct bfin_serial_port *uart; 131 struct bfin_serial_port *uart;
129 132
130 if (CONFIG_KGDB_UART_PORT < 0 133 if (CONFIG_KGDB_UART_PORT < 0
131 || CONFIG_KGDB_UART_PORT >= BFIN_UART_NR_PORTS) 134 || CONFIG_KGDB_UART_PORT >= BFIN_UART_NR_PORTS)
132 uart = &bfin_serial_ports[0]; 135 uart = &bfin_serial_ports[0];
133 else 136 else
134 uart = &bfin_serial_ports[CONFIG_KGDB_UART_PORT]; 137 uart = &bfin_serial_ports[CONFIG_KGDB_UART_PORT];
135 138
136 while (!(UART_GET_LSR(uart) & THRE)) { 139 while (!(UART_GET_LSR(uart) & THRE)) {
137 SSYNC(); 140 SSYNC();
138 } 141 }
@@ -152,7 +155,7 @@ int kgdb_get_debug_char(void)
152 uart = &bfin_serial_ports[0]; 155 uart = &bfin_serial_ports[0];
153 else 156 else
154 uart = &bfin_serial_ports[CONFIG_KGDB_UART_PORT]; 157 uart = &bfin_serial_ports[CONFIG_KGDB_UART_PORT];
155 158
156 while(!(UART_GET_LSR(uart) & DR)) { 159 while(!(UART_GET_LSR(uart) & DR)) {
157 SSYNC(); 160 SSYNC();
158 } 161 }
@@ -298,7 +301,11 @@ static void bfin_serial_tx_chars(struct bfin_serial_port *uart)
298 bfin_serial_mctrl_check(uart); 301 bfin_serial_mctrl_check(uart);
299 302
300 if (uart_circ_empty(xmit) || uart_tx_stopped(&uart->port)) { 303 if (uart_circ_empty(xmit) || uart_tx_stopped(&uart->port)) {
301 bfin_serial_stop_tx(&uart->port); 304#ifdef CONFIG_BF54x
305 /* Clear TFI bit */
306 UART_PUT_LSR(uart, TFI);
307#endif
308 UART_CLEAR_IER(uart, ETBEI);
302 return; 309 return;
303 } 310 }
304 311
@@ -317,9 +324,6 @@ static void bfin_serial_tx_chars(struct bfin_serial_port *uart)
317 324
318 if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) 325 if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
319 uart_write_wakeup(&uart->port); 326 uart_write_wakeup(&uart->port);
320
321 if (uart_circ_empty(xmit))
322 bfin_serial_stop_tx(&uart->port);
323} 327}
324 328
325static irqreturn_t bfin_serial_rx_int(int irq, void *dev_id) 329static irqreturn_t bfin_serial_rx_int(int irq, void *dev_id)
@@ -645,6 +649,42 @@ static int bfin_serial_startup(struct uart_port *port)
645 free_irq(uart->port.irq, uart); 649 free_irq(uart->port.irq, uart);
646 return -EBUSY; 650 return -EBUSY;
647 } 651 }
652
653# ifdef CONFIG_BF54x
654 {
655 unsigned uart_dma_ch_rx, uart_dma_ch_tx;
656
657 switch (uart->port.irq) {
658 case IRQ_UART3_RX:
659 uart_dma_ch_rx = CH_UART3_RX;
660 uart_dma_ch_tx = CH_UART3_TX;
661 break;
662 case IRQ_UART2_RX:
663 uart_dma_ch_rx = CH_UART2_RX;
664 uart_dma_ch_tx = CH_UART2_TX;
665 break;
666 default:
667 uart_dma_ch_rx = uart_dma_ch_tx = 0;
668 break;
669 };
670
671 if (uart_dma_ch_rx &&
672 request_dma(uart_dma_ch_rx, "BFIN_UART_RX") < 0) {
673 printk(KERN_NOTICE"Fail to attach UART interrupt\n");
674 free_irq(uart->port.irq, uart);
675 free_irq(uart->port.irq + 1, uart);
676 return -EBUSY;
677 }
678 if (uart_dma_ch_tx &&
679 request_dma(uart_dma_ch_tx, "BFIN_UART_TX") < 0) {
680 printk(KERN_NOTICE "Fail to attach UART interrupt\n");
681 free_dma(uart_dma_ch_rx);
682 free_irq(uart->port.irq, uart);
683 free_irq(uart->port.irq + 1, uart);
684 return -EBUSY;
685 }
686 }
687# endif
648#endif 688#endif
649 UART_SET_IER(uart, ERBFI); 689 UART_SET_IER(uart, ERBFI);
650 return 0; 690 return 0;
@@ -662,6 +702,20 @@ static void bfin_serial_shutdown(struct uart_port *port)
662 del_timer(&(uart->rx_dma_timer)); 702 del_timer(&(uart->rx_dma_timer));
663 dma_free_coherent(NULL, PAGE_SIZE, uart->rx_dma_buf.buf, 0); 703 dma_free_coherent(NULL, PAGE_SIZE, uart->rx_dma_buf.buf, 0);
664#else 704#else
705#ifdef CONFIG_BF54x
706 switch (uart->port.irq) {
707 case IRQ_UART3_RX:
708 free_dma(CH_UART3_RX);
709 free_dma(CH_UART3_TX);
710 break;
711 case IRQ_UART2_RX:
712 free_dma(CH_UART2_RX);
713 free_dma(CH_UART2_TX);
714 break;
715 default:
716 break;
717 };
718#endif
665#ifdef CONFIG_KGDB_UART 719#ifdef CONFIG_KGDB_UART
666 if (uart->port.line != CONFIG_KGDB_UART_PORT) 720 if (uart->port.line != CONFIG_KGDB_UART_PORT)
667#endif 721#endif
@@ -757,6 +811,9 @@ bfin_serial_set_termios(struct uart_port *port, struct ktermios *termios,
757 val |= UCEN; 811 val |= UCEN;
758 UART_PUT_GCTL(uart, val); 812 UART_PUT_GCTL(uart, val);
759 813
814 /* Port speed changed, update the per-port timeout. */
815 uart_update_timeout(port, termios->c_cflag, baud);
816
760 spin_unlock_irqrestore(&uart->port.lock, flags); 817 spin_unlock_irqrestore(&uart->port.lock, flags);
761} 818}
762 819
@@ -859,8 +916,9 @@ static void __init bfin_serial_init_ports(void)
859 return; 916 return;
860 first = 0; 917 first = 0;
861 918
862 for (i = 0; i < nr_ports; i++) { 919 for (i = 0; i < nr_active_ports; i++) {
863 bfin_serial_ports[i].port.uartclk = get_sclk(); 920 bfin_serial_ports[i].port.uartclk = get_sclk();
921 bfin_serial_ports[i].port.fifosize = BFIN_UART_TX_FIFO_SIZE;
864 bfin_serial_ports[i].port.ops = &bfin_serial_pops; 922 bfin_serial_ports[i].port.ops = &bfin_serial_pops;
865 bfin_serial_ports[i].port.line = i; 923 bfin_serial_ports[i].port.line = i;
866 bfin_serial_ports[i].port.iotype = UPIO_MEM; 924 bfin_serial_ports[i].port.iotype = UPIO_MEM;
@@ -961,7 +1019,7 @@ bfin_serial_console_setup(struct console *co, char *options)
961 * if so, search for the first available port that does have 1019 * if so, search for the first available port that does have
962 * console support. 1020 * console support.
963 */ 1021 */
964 if (co->index == -1 || co->index >= nr_ports) 1022 if (co->index == -1 || co->index >= nr_active_ports)
965 co->index = 0; 1023 co->index = 0;
966 uart = &bfin_serial_ports[co->index]; 1024 uart = &bfin_serial_ports[co->index];
967 1025
@@ -1056,7 +1114,7 @@ static __init void early_serial_write(struct console *con, const char *s,
1056 } 1114 }
1057} 1115}
1058 1116
1059static struct __init console bfin_early_serial_console = { 1117static struct __initdata console bfin_early_serial_console = {
1060 .name = "early_BFuart", 1118 .name = "early_BFuart",
1061 .write = early_serial_write, 1119 .write = early_serial_write,
1062 .device = uart_console_device, 1120 .device = uart_console_device,
@@ -1072,7 +1130,7 @@ struct console __init *bfin_earlyserial_init(unsigned int port,
1072 struct bfin_serial_port *uart; 1130 struct bfin_serial_port *uart;
1073 struct ktermios t; 1131 struct ktermios t;
1074 1132
1075 if (port == -1 || port >= nr_ports) 1133 if (port == -1 || port >= nr_active_ports)
1076 port = 0; 1134 port = 0;
1077 bfin_serial_init_ports(); 1135 bfin_serial_init_ports();
1078 bfin_early_serial_console.index = port; 1136 bfin_early_serial_console.index = port;
@@ -1100,20 +1158,26 @@ static struct uart_driver bfin_serial_reg = {
1100 1158
1101static int bfin_serial_suspend(struct platform_device *dev, pm_message_t state) 1159static int bfin_serial_suspend(struct platform_device *dev, pm_message_t state)
1102{ 1160{
1103 struct bfin_serial_port *uart = platform_get_drvdata(dev); 1161 int i;
1104 1162
1105 if (uart) 1163 for (i = 0; i < nr_active_ports; i++) {
1106 uart_suspend_port(&bfin_serial_reg, &uart->port); 1164 if (bfin_serial_ports[i].port.dev != &dev->dev)
1165 continue;
1166 uart_suspend_port(&bfin_serial_reg, &bfin_serial_ports[i].port);
1167 }
1107 1168
1108 return 0; 1169 return 0;
1109} 1170}
1110 1171
1111static int bfin_serial_resume(struct platform_device *dev) 1172static int bfin_serial_resume(struct platform_device *dev)
1112{ 1173{
1113 struct bfin_serial_port *uart = platform_get_drvdata(dev); 1174 int i;
1114 1175
1115 if (uart) 1176 for (i = 0; i < nr_active_ports; i++) {
1116 uart_resume_port(&bfin_serial_reg, &uart->port); 1177 if (bfin_serial_ports[i].port.dev != &dev->dev)
1178 continue;
1179 uart_resume_port(&bfin_serial_reg, &bfin_serial_ports[i].port);
1180 }
1117 1181
1118 return 0; 1182 return 0;
1119} 1183}
@@ -1128,32 +1192,31 @@ static int bfin_serial_probe(struct platform_device *dev)
1128 break; 1192 break;
1129 1193
1130 if (i < dev->num_resources) { 1194 if (i < dev->num_resources) {
1131 for (i = 0; i < nr_ports; i++, res++) { 1195 for (i = 0; i < nr_active_ports; i++, res++) {
1132 if (bfin_serial_ports[i].port.mapbase != res->start) 1196 if (bfin_serial_ports[i].port.mapbase != res->start)
1133 continue; 1197 continue;
1134 bfin_serial_ports[i].port.dev = &dev->dev; 1198 bfin_serial_ports[i].port.dev = &dev->dev;
1135 uart_add_one_port(&bfin_serial_reg, &bfin_serial_ports[i].port); 1199 uart_add_one_port(&bfin_serial_reg, &bfin_serial_ports[i].port);
1136 platform_set_drvdata(dev, &bfin_serial_ports[i]);
1137 } 1200 }
1138 } 1201 }
1139 1202
1140 return 0; 1203 return 0;
1141} 1204}
1142 1205
1143static int bfin_serial_remove(struct platform_device *pdev) 1206static int bfin_serial_remove(struct platform_device *dev)
1144{ 1207{
1145 struct bfin_serial_port *uart = platform_get_drvdata(pdev); 1208 int i;
1146
1147 1209
1210 for (i = 0; i < nr_active_ports; i++) {
1211 if (bfin_serial_ports[i].port.dev != &dev->dev)
1212 continue;
1213 uart_remove_one_port(&bfin_serial_reg, &bfin_serial_ports[i].port);
1214 bfin_serial_ports[i].port.dev = NULL;
1148#ifdef CONFIG_SERIAL_BFIN_CTSRTS 1215#ifdef CONFIG_SERIAL_BFIN_CTSRTS
1149 gpio_free(uart->cts_pin); 1216 gpio_free(bfin_serial_ports[i].cts_pin);
1150 gpio_free(uart->rts_pin); 1217 gpio_free(bfin_serial_ports[i].rts_pin);
1151#endif 1218#endif
1152 1219 }
1153 platform_set_drvdata(pdev, NULL);
1154
1155 if (uart)
1156 uart_remove_one_port(&bfin_serial_reg, &uart->port);
1157 1220
1158 return 0; 1221 return 0;
1159} 1222}
diff --git a/drivers/serial/crisv10.c b/drivers/serial/crisv10.c
index bf94a770bb44..211c21797ce0 100644
--- a/drivers/serial/crisv10.c
+++ b/drivers/serial/crisv10.c
@@ -457,7 +457,6 @@ static struct e100_serial rs_table[] = {
457#define NR_PORTS (sizeof(rs_table)/sizeof(struct e100_serial)) 457#define NR_PORTS (sizeof(rs_table)/sizeof(struct e100_serial))
458 458
459static struct ktermios *serial_termios[NR_PORTS]; 459static struct ktermios *serial_termios[NR_PORTS];
460static struct ktermios *serial_termios_locked[NR_PORTS];
461#ifdef CONFIG_ETRAX_SERIAL_FAST_TIMER 460#ifdef CONFIG_ETRAX_SERIAL_FAST_TIMER
462static struct fast_timer fast_timers[NR_PORTS]; 461static struct fast_timer fast_timers[NR_PORTS];
463#endif 462#endif
@@ -4419,6 +4418,7 @@ rs_init(void)
4419 rs485_pa_bit)) { 4418 rs485_pa_bit)) {
4420 printk(KERN_CRIT "ETRAX100LX serial: Could not allocate " 4419 printk(KERN_CRIT "ETRAX100LX serial: Could not allocate "
4421 "RS485 pin\n"); 4420 "RS485 pin\n");
4421 put_tty_driver(driver);
4422 return -EBUSY; 4422 return -EBUSY;
4423 } 4423 }
4424#endif 4424#endif
@@ -4427,6 +4427,7 @@ rs_init(void)
4427 rs485_port_g_bit)) { 4427 rs485_port_g_bit)) {
4428 printk(KERN_CRIT "ETRAX100LX serial: Could not allocate " 4428 printk(KERN_CRIT "ETRAX100LX serial: Could not allocate "
4429 "RS485 pin\n"); 4429 "RS485 pin\n");
4430 put_tty_driver(driver);
4430 return -EBUSY; 4431 return -EBUSY;
4431 } 4432 }
4432#endif 4433#endif
@@ -4446,8 +4447,6 @@ rs_init(void)
4446 driver->init_termios.c_ispeed = 115200; 4447 driver->init_termios.c_ispeed = 115200;
4447 driver->init_termios.c_ospeed = 115200; 4448 driver->init_termios.c_ospeed = 115200;
4448 driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; 4449 driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
4449 driver->termios = serial_termios;
4450 driver->termios_locked = serial_termios_locked;
4451 4450
4452 tty_set_operations(driver, &rs_ops); 4451 tty_set_operations(driver, &rs_ops);
4453 serial_driver = driver; 4452 serial_driver = driver;
diff --git a/drivers/serial/mcfserial.c b/drivers/serial/mcfserial.c
deleted file mode 100644
index fbe3835f6b77..000000000000
--- a/drivers/serial/mcfserial.c
+++ /dev/null
@@ -1,1965 +0,0 @@
1#warning This driver is deprecated. Check Kconfig for details.
2/*
3 * mcfserial.c -- serial driver for ColdFire internal UARTS.
4 *
5 * Copyright (C) 1999-2003 Greg Ungerer <gerg@snapgear.com>
6 * Copyright (c) 2000-2001 Lineo, Inc. <www.lineo.com>
7 * Copyright (C) 2001-2002 SnapGear Inc. <www.snapgear.com>
8 *
9 * Based on code from 68332serial.c which was:
10 *
11 * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
12 * Copyright (C) 1998 TSHG
13 * Copyright (c) 1999 Rt-Control Inc. <jeff@uclinux.org>
14 *
15 * Changes:
16 * 08/07/2003 Daniele Bellucci <bellucda@tiscali.it>
17 * some cleanups in mcfrs_write.
18 *
19 */
20
21#include <linux/module.h>
22#include <linux/errno.h>
23#include <linux/signal.h>
24#include <linux/sched.h>
25#include <linux/timer.h>
26#include <linux/wait.h>
27#include <linux/interrupt.h>
28#include <linux/tty.h>
29#include <linux/tty_flip.h>
30#include <linux/string.h>
31#include <linux/fcntl.h>
32#include <linux/mm.h>
33#include <linux/kernel.h>
34#include <linux/serial.h>
35#include <linux/serialP.h>
36#include <linux/console.h>
37#include <linux/init.h>
38#include <linux/bitops.h>
39#include <linux/delay.h>
40
41#include <asm/io.h>
42#include <asm/irq.h>
43#include <asm/system.h>
44#include <asm/delay.h>
45#include <asm/coldfire.h>
46#include <asm/mcfsim.h>
47#include <asm/mcfuart.h>
48#include <asm/nettel.h>
49#include <asm/uaccess.h>
50#include "mcfserial.h"
51
52struct timer_list mcfrs_timer_struct;
53
54/*
55 * Default console baud rate, we use this as the default
56 * for all ports so init can just open /dev/console and
57 * keep going. Perhaps one day the cflag settings for the
58 * console can be used instead.
59 */
60#if defined(CONFIG_HW_FEITH)
61#define CONSOLE_BAUD_RATE 38400
62#define DEFAULT_CBAUD B38400
63#elif defined(CONFIG_MOD5272) || defined(CONFIG_M5208EVB) || \
64 defined(CONFIG_M5329EVB) || defined(CONFIG_GILBARCO)
65#define CONSOLE_BAUD_RATE 115200
66#define DEFAULT_CBAUD B115200
67#elif defined(CONFIG_ARNEWSH) || defined(CONFIG_FREESCALE) || \
68 defined(CONFIG_senTec) || defined(CONFIG_SNEHA) || defined(CONFIG_AVNET)
69#define CONSOLE_BAUD_RATE 19200
70#define DEFAULT_CBAUD B19200
71#endif
72
73#ifndef CONSOLE_BAUD_RATE
74#define CONSOLE_BAUD_RATE 9600
75#define DEFAULT_CBAUD B9600
76#endif
77
78int mcfrs_console_inited = 0;
79int mcfrs_console_port = -1;
80int mcfrs_console_baud = CONSOLE_BAUD_RATE;
81int mcfrs_console_cbaud = DEFAULT_CBAUD;
82
83/*
84 * Driver data structures.
85 */
86static struct tty_driver *mcfrs_serial_driver;
87
88/* number of characters left in xmit buffer before we ask for more */
89#define WAKEUP_CHARS 256
90
91/* Debugging...
92 */
93#undef SERIAL_DEBUG_OPEN
94#undef SERIAL_DEBUG_FLOW
95
96#if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) || \
97 defined(CONFIG_M520x) || defined(CONFIG_M532x)
98#define IRQBASE (MCFINT_VECBASE+MCFINT_UART0)
99#else
100#define IRQBASE 73
101#endif
102
103/*
104 * Configuration table, UARTs to look for at startup.
105 */
106static struct mcf_serial mcfrs_table[] = {
107 { /* ttyS0 */
108 .magic = 0,
109 .addr = (volatile unsigned char *) (MCF_MBAR+MCFUART_BASE1),
110 .irq = IRQBASE,
111 .flags = ASYNC_BOOT_AUTOCONF,
112 },
113#ifdef MCFUART_BASE2
114 { /* ttyS1 */
115 .magic = 0,
116 .addr = (volatile unsigned char *) (MCF_MBAR+MCFUART_BASE2),
117 .irq = IRQBASE+1,
118 .flags = ASYNC_BOOT_AUTOCONF,
119 },
120#endif
121#ifdef MCFUART_BASE3
122 { /* ttyS2 */
123 .magic = 0,
124 .addr = (volatile unsigned char *) (MCF_MBAR+MCFUART_BASE3),
125 .irq = IRQBASE+2,
126 .flags = ASYNC_BOOT_AUTOCONF,
127 },
128#endif
129#ifdef MCFUART_BASE4
130 { /* ttyS3 */
131 .magic = 0,
132 .addr = (volatile unsigned char *) (MCF_MBAR+MCFUART_BASE4),
133 .irq = IRQBASE+3,
134 .flags = ASYNC_BOOT_AUTOCONF,
135 },
136#endif
137};
138
139
140#define NR_PORTS (sizeof(mcfrs_table) / sizeof(struct mcf_serial))
141
142/*
143 * This is used to figure out the divisor speeds and the timeouts.
144 */
145static int mcfrs_baud_table[] = {
146 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,
147 9600, 19200, 38400, 57600, 115200, 230400, 460800, 0
148};
149#define MCFRS_BAUD_TABLE_SIZE \
150 (sizeof(mcfrs_baud_table)/sizeof(mcfrs_baud_table[0]))
151
152
153#ifdef CONFIG_MAGIC_SYSRQ
154/*
155 * Magic system request keys. Used for debugging...
156 */
157extern int magic_sysrq_key(int ch);
158#endif
159
160
161/*
162 * Forware declarations...
163 */
164static void mcfrs_change_speed(struct mcf_serial *info);
165static void mcfrs_wait_until_sent(struct tty_struct *tty, int timeout);
166
167
168static inline int serial_paranoia_check(struct mcf_serial *info,
169 char *name, const char *routine)
170{
171#ifdef SERIAL_PARANOIA_CHECK
172 static const char badmagic[] =
173 "MCFRS(warning): bad magic number for serial struct %s in %s\n";
174 static const char badinfo[] =
175 "MCFRS(warning): null mcf_serial for %s in %s\n";
176
177 if (!info) {
178 printk(badinfo, name, routine);
179 return 1;
180 }
181 if (info->magic != SERIAL_MAGIC) {
182 printk(badmagic, name, routine);
183 return 1;
184 }
185#endif
186 return 0;
187}
188
189/*
190 * Sets or clears DTR and RTS on the requested line.
191 */
192static void mcfrs_setsignals(struct mcf_serial *info, int dtr, int rts)
193{
194 volatile unsigned char *uartp;
195 unsigned long flags;
196
197#if 0
198 printk("%s(%d): mcfrs_setsignals(info=%x,dtr=%d,rts=%d)\n",
199 __FILE__, __LINE__, info, dtr, rts);
200#endif
201
202 local_irq_save(flags);
203 if (dtr >= 0) {
204#ifdef MCFPP_DTR0
205 if (info->line)
206 mcf_setppdata(MCFPP_DTR1, (dtr ? 0 : MCFPP_DTR1));
207 else
208 mcf_setppdata(MCFPP_DTR0, (dtr ? 0 : MCFPP_DTR0));
209#endif
210 }
211 if (rts >= 0) {
212 uartp = info->addr;
213 if (rts) {
214 info->sigs |= TIOCM_RTS;
215 uartp[MCFUART_UOP1] = MCFUART_UOP_RTS;
216 } else {
217 info->sigs &= ~TIOCM_RTS;
218 uartp[MCFUART_UOP0] = MCFUART_UOP_RTS;
219 }
220 }
221 local_irq_restore(flags);
222 return;
223}
224
225/*
226 * Gets values of serial signals.
227 */
228static int mcfrs_getsignals(struct mcf_serial *info)
229{
230 volatile unsigned char *uartp;
231 unsigned long flags;
232 int sigs;
233#if defined(CONFIG_NETtel) && defined(CONFIG_M5307)
234 unsigned short ppdata;
235#endif
236
237#if 0
238 printk("%s(%d): mcfrs_getsignals(info=%x)\n", __FILE__, __LINE__);
239#endif
240
241 local_irq_save(flags);
242 uartp = info->addr;
243 sigs = (uartp[MCFUART_UIPR] & MCFUART_UIPR_CTS) ? 0 : TIOCM_CTS;
244 sigs |= (info->sigs & TIOCM_RTS);
245
246#ifdef MCFPP_DCD0
247{
248 unsigned int ppdata;
249 ppdata = mcf_getppdata();
250 if (info->line == 0) {
251 sigs |= (ppdata & MCFPP_DCD0) ? 0 : TIOCM_CD;
252 sigs |= (ppdata & MCFPP_DTR0) ? 0 : TIOCM_DTR;
253 } else if (info->line == 1) {
254 sigs |= (ppdata & MCFPP_DCD1) ? 0 : TIOCM_CD;
255 sigs |= (ppdata & MCFPP_DTR1) ? 0 : TIOCM_DTR;
256 }
257}
258#endif
259
260 local_irq_restore(flags);
261 return(sigs);
262}
263
264/*
265 * ------------------------------------------------------------
266 * mcfrs_stop() and mcfrs_start()
267 *
268 * This routines are called before setting or resetting tty->stopped.
269 * They enable or disable transmitter interrupts, as necessary.
270 * ------------------------------------------------------------
271 */
272static void mcfrs_stop(struct tty_struct *tty)
273{
274 volatile unsigned char *uartp;
275 struct mcf_serial *info = (struct mcf_serial *)tty->driver_data;
276 unsigned long flags;
277
278 if (serial_paranoia_check(info, tty->name, "mcfrs_stop"))
279 return;
280
281 local_irq_save(flags);
282 uartp = info->addr;
283 info->imr &= ~MCFUART_UIR_TXREADY;
284 uartp[MCFUART_UIMR] = info->imr;
285 local_irq_restore(flags);
286}
287
288static void mcfrs_start(struct tty_struct *tty)
289{
290 volatile unsigned char *uartp;
291 struct mcf_serial *info = (struct mcf_serial *)tty->driver_data;
292 unsigned long flags;
293
294 if (serial_paranoia_check(info, tty->name, "mcfrs_start"))
295 return;
296
297 local_irq_save(flags);
298 if (info->xmit_cnt && info->xmit_buf) {
299 uartp = info->addr;
300 info->imr |= MCFUART_UIR_TXREADY;
301 uartp[MCFUART_UIMR] = info->imr;
302 }
303 local_irq_restore(flags);
304}
305
306/*
307 * ----------------------------------------------------------------------
308 *
309 * Here starts the interrupt handling routines. All of the following
310 * subroutines are declared as inline and are folded into
311 * mcfrs_interrupt(). They were separated out for readability's sake.
312 *
313 * Note: mcfrs_interrupt() is a "fast" interrupt, which means that it
314 * runs with interrupts turned off. People who may want to modify
315 * mcfrs_interrupt() should try to keep the interrupt handler as fast as
316 * possible. After you are done making modifications, it is not a bad
317 * idea to do:
318 *
319 * gcc -S -DKERNEL -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer serial.c
320 *
321 * and look at the resulting assemble code in serial.s.
322 *
323 * - Ted Ts'o (tytso@mit.edu), 7-Mar-93
324 * -----------------------------------------------------------------------
325 */
326
327static inline void receive_chars(struct mcf_serial *info)
328{
329 volatile unsigned char *uartp;
330 struct tty_struct *tty = info->port.tty;
331 unsigned char status, ch, flag;
332
333 if (!tty)
334 return;
335
336 uartp = info->addr;
337
338 while ((status = uartp[MCFUART_USR]) & MCFUART_USR_RXREADY) {
339 ch = uartp[MCFUART_URB];
340 info->stats.rx++;
341
342#ifdef CONFIG_MAGIC_SYSRQ
343 if (mcfrs_console_inited && (info->line == mcfrs_console_port)) {
344 if (magic_sysrq_key(ch))
345 continue;
346 }
347#endif
348
349 flag = TTY_NORMAL;
350 if (status & MCFUART_USR_RXERR) {
351 uartp[MCFUART_UCR] = MCFUART_UCR_CMDRESETERR;
352 if (status & MCFUART_USR_RXBREAK) {
353 info->stats.rxbreak++;
354 flag = TTY_BREAK;
355 } else if (status & MCFUART_USR_RXPARITY) {
356 info->stats.rxparity++;
357 flag = TTY_PARITY;
358 } else if (status & MCFUART_USR_RXOVERRUN) {
359 info->stats.rxoverrun++;
360 flag = TTY_OVERRUN;
361 } else if (status & MCFUART_USR_RXFRAMING) {
362 info->stats.rxframing++;
363 flag = TTY_FRAME;
364 }
365 }
366 tty_insert_flip_char(tty, ch, flag);
367 }
368 tty_schedule_flip(tty);
369 return;
370}
371
372static inline void transmit_chars(struct mcf_serial *info)
373{
374 volatile unsigned char *uartp;
375
376 uartp = info->addr;
377
378 if (info->x_char) {
379 /* Send special char - probably flow control */
380 uartp[MCFUART_UTB] = info->x_char;
381 info->x_char = 0;
382 info->stats.tx++;
383 }
384
385 if ((info->xmit_cnt <= 0) || info->port.tty->stopped) {
386 info->imr &= ~MCFUART_UIR_TXREADY;
387 uartp[MCFUART_UIMR] = info->imr;
388 return;
389 }
390
391 while (uartp[MCFUART_USR] & MCFUART_USR_TXREADY) {
392 uartp[MCFUART_UTB] = info->xmit_buf[info->xmit_tail++];
393 info->xmit_tail = info->xmit_tail & (SERIAL_XMIT_SIZE-1);
394 info->stats.tx++;
395 if (--info->xmit_cnt <= 0)
396 break;
397 }
398
399 if (info->xmit_cnt < WAKEUP_CHARS)
400 schedule_work(&info->tqueue);
401 return;
402}
403
404/*
405 * This is the serial driver's generic interrupt routine
406 */
407irqreturn_t mcfrs_interrupt(int irq, void *dev_id)
408{
409 struct mcf_serial *info;
410 unsigned char isr;
411
412 info = &mcfrs_table[(irq - IRQBASE)];
413 isr = info->addr[MCFUART_UISR] & info->imr;
414
415 if (isr & MCFUART_UIR_RXREADY)
416 receive_chars(info);
417 if (isr & MCFUART_UIR_TXREADY)
418 transmit_chars(info);
419 return IRQ_HANDLED;
420}
421
422/*
423 * -------------------------------------------------------------------
424 * Here ends the serial interrupt routines.
425 * -------------------------------------------------------------------
426 */
427
428static void mcfrs_offintr(struct work_struct *work)
429{
430 struct mcf_serial *info = container_of(work, struct mcf_serial, tqueue);
431 struct tty_struct *tty = info->port.tty;
432
433 if (tty)
434 tty_wakeup(tty);
435}
436
437
438/*
439 * Change of state on a DCD line.
440 */
441void mcfrs_modem_change(struct mcf_serial *info, int dcd)
442{
443 if (info->count == 0)
444 return;
445
446 if (info->flags & ASYNC_CHECK_CD) {
447 if (dcd)
448 wake_up_interruptible(&info->open_wait);
449 else
450 schedule_work(&info->tqueue_hangup);
451 }
452}
453
454
455#ifdef MCFPP_DCD0
456
457unsigned short mcfrs_ppstatus;
458
459/*
460 * This subroutine is called when the RS_TIMER goes off. It is used
461 * to monitor the state of the DCD lines - since they have no edge
462 * sensors and interrupt generators.
463 */
464static void mcfrs_timer(void)
465{
466 unsigned int ppstatus, dcdval, i;
467
468 ppstatus = mcf_getppdata() & (MCFPP_DCD0 | MCFPP_DCD1);
469
470 if (ppstatus != mcfrs_ppstatus) {
471 for (i = 0; (i < 2); i++) {
472 dcdval = (i ? MCFPP_DCD1 : MCFPP_DCD0);
473 if ((ppstatus & dcdval) != (mcfrs_ppstatus & dcdval)) {
474 mcfrs_modem_change(&mcfrs_table[i],
475 ((ppstatus & dcdval) ? 0 : 1));
476 }
477 }
478 }
479 mcfrs_ppstatus = ppstatus;
480
481 /* Re-arm timer */
482 mcfrs_timer_struct.expires = jiffies + HZ/25;
483 add_timer(&mcfrs_timer_struct);
484}
485
486#endif /* MCFPP_DCD0 */
487
488
489/*
490 * This routine is called from the scheduler tqueue when the interrupt
491 * routine has signalled that a hangup has occurred. The path of
492 * hangup processing is:
493 *
494 * serial interrupt routine -> (scheduler tqueue) ->
495 * do_serial_hangup() -> tty->hangup() -> mcfrs_hangup()
496 *
497 */
498static void do_serial_hangup(struct work_struct *work)
499{
500 struct mcf_serial *info = container_of(work, struct mcf_serial, tqueue_hangup);
501 struct tty_struct *tty = info->port.tty;
502
503 if (tty)
504 tty_hangup(tty);
505}
506
507static int startup(struct mcf_serial * info)
508{
509 volatile unsigned char *uartp;
510 unsigned long flags;
511
512 if (info->flags & ASYNC_INITIALIZED)
513 return 0;
514
515 if (!info->xmit_buf) {
516 info->xmit_buf = (unsigned char *) __get_free_page(GFP_KERNEL);
517 if (!info->xmit_buf)
518 return -ENOMEM;
519 }
520
521 local_irq_save(flags);
522
523#ifdef SERIAL_DEBUG_OPEN
524 printk("starting up ttyS%d (irq %d)...\n", info->line, info->irq);
525#endif
526
527 /*
528 * Reset UART, get it into known state...
529 */
530 uartp = info->addr;
531 uartp[MCFUART_UCR] = MCFUART_UCR_CMDRESETRX; /* reset RX */
532 uartp[MCFUART_UCR] = MCFUART_UCR_CMDRESETTX; /* reset TX */
533 mcfrs_setsignals(info, 1, 1);
534
535 if (info->port.tty)
536 clear_bit(TTY_IO_ERROR, &info->port.tty->flags);
537 info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
538
539 /*
540 * and set the speed of the serial port
541 */
542 mcfrs_change_speed(info);
543
544 /*
545 * Lastly enable the UART transmitter and receiver, and
546 * interrupt enables.
547 */
548 info->imr = MCFUART_UIR_RXREADY;
549 uartp[MCFUART_UCR] = MCFUART_UCR_RXENABLE | MCFUART_UCR_TXENABLE;
550 uartp[MCFUART_UIMR] = info->imr;
551
552 info->flags |= ASYNC_INITIALIZED;
553 local_irq_restore(flags);
554 return 0;
555}
556
557/*
558 * This routine will shutdown a serial port; interrupts are disabled, and
559 * DTR is dropped if the hangup on close termio flag is on.
560 */
561static void shutdown(struct mcf_serial * info)
562{
563 volatile unsigned char *uartp;
564 unsigned long flags;
565
566 if (!(info->flags & ASYNC_INITIALIZED))
567 return;
568
569#ifdef SERIAL_DEBUG_OPEN
570 printk("Shutting down serial port %d (irq %d)....\n", info->line,
571 info->irq);
572#endif
573
574 local_irq_save(flags);
575
576 uartp = info->addr;
577 uartp[MCFUART_UIMR] = 0; /* mask all interrupts */
578 uartp[MCFUART_UCR] = MCFUART_UCR_CMDRESETRX; /* reset RX */
579 uartp[MCFUART_UCR] = MCFUART_UCR_CMDRESETTX; /* reset TX */
580
581 if (!info->port.tty || (info->port.tty->termios->c_cflag & HUPCL))
582 mcfrs_setsignals(info, 0, 0);
583
584 if (info->xmit_buf) {
585 free_page((unsigned long) info->xmit_buf);
586 info->xmit_buf = 0;
587 }
588
589 if (info->port.tty)
590 set_bit(TTY_IO_ERROR, &info->port.tty->flags);
591
592 info->flags &= ~ASYNC_INITIALIZED;
593 local_irq_restore(flags);
594}
595
596
597/*
598 * This routine is called to set the UART divisor registers to match
599 * the specified baud rate for a serial port.
600 */
601static void mcfrs_change_speed(struct mcf_serial *info)
602{
603 volatile unsigned char *uartp;
604 unsigned int baudclk, cflag;
605 unsigned long flags;
606 unsigned char mr1, mr2;
607 int i;
608#ifdef CONFIG_M5272
609 unsigned int fraction;
610#endif
611
612 if (!info->port.tty || !info->port.tty->termios)
613 return;
614 cflag = info->port.tty->termios->c_cflag;
615 if (info->addr == 0)
616 return;
617
618#if 0
619 printk("%s(%d): mcfrs_change_speed()\n", __FILE__, __LINE__);
620#endif
621
622 i = cflag & CBAUD;
623 if (i & CBAUDEX) {
624 i &= ~CBAUDEX;
625 if (i < 1 || i > 4)
626 info->port.tty->termios->c_cflag &= ~CBAUDEX;
627 else
628 i += 15;
629 }
630 if (i == 0) {
631 mcfrs_setsignals(info, 0, -1);
632 return;
633 }
634
635 /* compute the baudrate clock */
636#ifdef CONFIG_M5272
637 /*
638 * For the MCF5272, also compute the baudrate fraction.
639 */
640 baudclk = (MCF_BUSCLK / mcfrs_baud_table[i]) / 32;
641 fraction = MCF_BUSCLK - (baudclk * 32 * mcfrs_baud_table[i]);
642 fraction *= 16;
643 fraction /= (32 * mcfrs_baud_table[i]);
644#else
645 baudclk = ((MCF_BUSCLK / mcfrs_baud_table[i]) + 16) / 32;
646#endif
647
648 info->baud = mcfrs_baud_table[i];
649
650 mr1 = MCFUART_MR1_RXIRQRDY | MCFUART_MR1_RXERRCHAR;
651 mr2 = 0;
652
653 switch (cflag & CSIZE) {
654 case CS5: mr1 |= MCFUART_MR1_CS5; break;
655 case CS6: mr1 |= MCFUART_MR1_CS6; break;
656 case CS7: mr1 |= MCFUART_MR1_CS7; break;
657 case CS8:
658 default: mr1 |= MCFUART_MR1_CS8; break;
659 }
660
661 if (cflag & PARENB) {
662 if (cflag & CMSPAR) {
663 if (cflag & PARODD)
664 mr1 |= MCFUART_MR1_PARITYMARK;
665 else
666 mr1 |= MCFUART_MR1_PARITYSPACE;
667 } else {
668 if (cflag & PARODD)
669 mr1 |= MCFUART_MR1_PARITYODD;
670 else
671 mr1 |= MCFUART_MR1_PARITYEVEN;
672 }
673 } else {
674 mr1 |= MCFUART_MR1_PARITYNONE;
675 }
676
677 if (cflag & CSTOPB)
678 mr2 |= MCFUART_MR2_STOP2;
679 else
680 mr2 |= MCFUART_MR2_STOP1;
681
682 if (cflag & CRTSCTS) {
683 mr1 |= MCFUART_MR1_RXRTS;
684 mr2 |= MCFUART_MR2_TXCTS;
685 }
686
687 if (cflag & CLOCAL)
688 info->flags &= ~ASYNC_CHECK_CD;
689 else
690 info->flags |= ASYNC_CHECK_CD;
691
692 uartp = info->addr;
693
694 local_irq_save(flags);
695#if 0
696 printk("%s(%d): mr1=%x mr2=%x baudclk=%x\n", __FILE__, __LINE__,
697 mr1, mr2, baudclk);
698#endif
699 /*
700 Note: pg 12-16 of MCF5206e User's Manual states that a
701 software reset should be performed prior to changing
702 UMR1,2, UCSR, UACR, bit 7
703 */
704 uartp[MCFUART_UCR] = MCFUART_UCR_CMDRESETRX; /* reset RX */
705 uartp[MCFUART_UCR] = MCFUART_UCR_CMDRESETTX; /* reset TX */
706 uartp[MCFUART_UCR] = MCFUART_UCR_CMDRESETMRPTR; /* reset MR pointer */
707 uartp[MCFUART_UMR] = mr1;
708 uartp[MCFUART_UMR] = mr2;
709 uartp[MCFUART_UBG1] = (baudclk & 0xff00) >> 8; /* set msb byte */
710 uartp[MCFUART_UBG2] = (baudclk & 0xff); /* set lsb byte */
711#ifdef CONFIG_M5272
712 uartp[MCFUART_UFPD] = (fraction & 0xf); /* set fraction */
713#endif
714 uartp[MCFUART_UCSR] = MCFUART_UCSR_RXCLKTIMER | MCFUART_UCSR_TXCLKTIMER;
715 uartp[MCFUART_UCR] = MCFUART_UCR_RXENABLE | MCFUART_UCR_TXENABLE;
716 mcfrs_setsignals(info, 1, -1);
717 local_irq_restore(flags);
718 return;
719}
720
721static void mcfrs_flush_chars(struct tty_struct *tty)
722{
723 volatile unsigned char *uartp;
724 struct mcf_serial *info = (struct mcf_serial *)tty->driver_data;
725 unsigned long flags;
726
727 if (serial_paranoia_check(info, tty->name, "mcfrs_flush_chars"))
728 return;
729
730 uartp = (volatile unsigned char *) info->addr;
731
732 /*
733 * re-enable receiver interrupt
734 */
735 local_irq_save(flags);
736 if ((!(info->imr & MCFUART_UIR_RXREADY)) &&
737 (info->flags & ASYNC_INITIALIZED) ) {
738 info->imr |= MCFUART_UIR_RXREADY;
739 uartp[MCFUART_UIMR] = info->imr;
740 }
741 local_irq_restore(flags);
742
743 if (info->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped ||
744 !info->xmit_buf)
745 return;
746
747 /* Enable transmitter */
748 local_irq_save(flags);
749 info->imr |= MCFUART_UIR_TXREADY;
750 uartp[MCFUART_UIMR] = info->imr;
751 local_irq_restore(flags);
752}
753
754static int mcfrs_write(struct tty_struct * tty,
755 const unsigned char *buf, int count)
756{
757 volatile unsigned char *uartp;
758 struct mcf_serial *info = (struct mcf_serial *)tty->driver_data;
759 unsigned long flags;
760 int c, total = 0;
761
762#if 0
763 printk("%s(%d): mcfrs_write(tty=%x,buf=%x,count=%d)\n",
764 __FILE__, __LINE__, (int)tty, (int)buf, count);
765#endif
766
767 if (serial_paranoia_check(info, tty->name, "mcfrs_write"))
768 return 0;
769
770 if (!tty || !info->xmit_buf)
771 return 0;
772
773 local_save_flags(flags);
774 while (1) {
775 local_irq_disable();
776 c = min(count, (int) min(((int)SERIAL_XMIT_SIZE) - info->xmit_cnt - 1,
777 ((int)SERIAL_XMIT_SIZE) - info->xmit_head));
778 local_irq_restore(flags);
779
780 if (c <= 0)
781 break;
782
783 memcpy(info->xmit_buf + info->xmit_head, buf, c);
784
785 local_irq_disable();
786 info->xmit_head = (info->xmit_head + c) & (SERIAL_XMIT_SIZE-1);
787 info->xmit_cnt += c;
788 local_irq_restore(flags);
789
790 buf += c;
791 count -= c;
792 total += c;
793 }
794
795 local_irq_disable();
796 uartp = info->addr;
797 info->imr |= MCFUART_UIR_TXREADY;
798 uartp[MCFUART_UIMR] = info->imr;
799 local_irq_restore(flags);
800
801 return total;
802}
803
804static int mcfrs_write_room(struct tty_struct *tty)
805{
806 struct mcf_serial *info = (struct mcf_serial *)tty->driver_data;
807 int ret;
808
809 if (serial_paranoia_check(info, tty->name, "mcfrs_write_room"))
810 return 0;
811 ret = SERIAL_XMIT_SIZE - info->xmit_cnt - 1;
812 if (ret < 0)
813 ret = 0;
814 return ret;
815}
816
817static int mcfrs_chars_in_buffer(struct tty_struct *tty)
818{
819 struct mcf_serial *info = (struct mcf_serial *)tty->driver_data;
820
821 if (serial_paranoia_check(info, tty->name, "mcfrs_chars_in_buffer"))
822 return 0;
823 return info->xmit_cnt;
824}
825
826static void mcfrs_flush_buffer(struct tty_struct *tty)
827{
828 struct mcf_serial *info = (struct mcf_serial *)tty->driver_data;
829 unsigned long flags;
830
831 if (serial_paranoia_check(info, tty->name, "mcfrs_flush_buffer"))
832 return;
833
834 local_irq_save(flags);
835 info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
836 local_irq_restore(flags);
837
838 tty_wakeup(tty);
839}
840
841/*
842 * ------------------------------------------------------------
843 * mcfrs_throttle()
844 *
845 * This routine is called by the upper-layer tty layer to signal that
846 * incoming characters should be throttled.
847 * ------------------------------------------------------------
848 */
849static void mcfrs_throttle(struct tty_struct * tty)
850{
851 struct mcf_serial *info = (struct mcf_serial *)tty->driver_data;
852#ifdef SERIAL_DEBUG_THROTTLE
853 char buf[64];
854
855 printk("throttle %s: %d....\n", tty_name(tty, buf),
856 tty->ldisc.chars_in_buffer(tty));
857#endif
858
859 if (serial_paranoia_check(info, tty->name, "mcfrs_throttle"))
860 return;
861
862 if (I_IXOFF(tty))
863 info->x_char = STOP_CHAR(tty);
864
865 /* Turn off RTS line (do this atomic) */
866}
867
868static void mcfrs_unthrottle(struct tty_struct * tty)
869{
870 struct mcf_serial *info = (struct mcf_serial *)tty->driver_data;
871#ifdef SERIAL_DEBUG_THROTTLE
872 char buf[64];
873
874 printk("unthrottle %s: %d....\n", tty_name(tty, buf),
875 tty->ldisc.chars_in_buffer(tty));
876#endif
877
878 if (serial_paranoia_check(info, tty->name, "mcfrs_unthrottle"))
879 return;
880
881 if (I_IXOFF(tty)) {
882 if (info->x_char)
883 info->x_char = 0;
884 else
885 info->x_char = START_CHAR(tty);
886 }
887
888 /* Assert RTS line (do this atomic) */
889}
890
891/*
892 * ------------------------------------------------------------
893 * mcfrs_ioctl() and friends
894 * ------------------------------------------------------------
895 */
896
897static int get_serial_info(struct mcf_serial * info,
898 struct serial_struct * retinfo)
899{
900 struct serial_struct tmp;
901
902 if (!retinfo)
903 return -EFAULT;
904 memset(&tmp, 0, sizeof(tmp));
905 tmp.type = info->type;
906 tmp.line = info->line;
907 tmp.port = (unsigned int) info->addr;
908 tmp.irq = info->irq;
909 tmp.flags = info->flags;
910 tmp.baud_base = info->baud_base;
911 tmp.close_delay = info->close_delay;
912 tmp.closing_wait = info->closing_wait;
913 tmp.custom_divisor = info->custom_divisor;
914 return copy_to_user(retinfo,&tmp,sizeof(*retinfo)) ? -EFAULT : 0;
915}
916
917static int set_serial_info(struct mcf_serial * info,
918 struct serial_struct * new_info)
919{
920 struct serial_struct new_serial;
921 struct mcf_serial old_info;
922 int retval = 0;
923
924 if (!new_info)
925 return -EFAULT;
926 if (copy_from_user(&new_serial,new_info,sizeof(new_serial)))
927 return -EFAULT;
928 old_info = *info;
929
930 if (!capable(CAP_SYS_ADMIN)) {
931 if ((new_serial.baud_base != info->baud_base) ||
932 (new_serial.type != info->type) ||
933 (new_serial.close_delay != info->close_delay) ||
934 ((new_serial.flags & ~ASYNC_USR_MASK) !=
935 (info->flags & ~ASYNC_USR_MASK)))
936 return -EPERM;
937 info->flags = ((info->flags & ~ASYNC_USR_MASK) |
938 (new_serial.flags & ASYNC_USR_MASK));
939 info->custom_divisor = new_serial.custom_divisor;
940 goto check_and_exit;
941 }
942
943 if (info->count > 1)
944 return -EBUSY;
945
946 /*
947 * OK, past this point, all the error checking has been done.
948 * At this point, we start making changes.....
949 */
950
951 info->baud_base = new_serial.baud_base;
952 info->flags = ((info->flags & ~ASYNC_FLAGS) |
953 (new_serial.flags & ASYNC_FLAGS));
954 info->type = new_serial.type;
955 info->close_delay = new_serial.close_delay;
956 info->closing_wait = new_serial.closing_wait;
957
958check_and_exit:
959 retval = startup(info);
960 return retval;
961}
962
963/*
964 * get_lsr_info - get line status register info
965 *
966 * Purpose: Let user call ioctl() to get info when the UART physically
967 * is emptied. On bus types like RS485, the transmitter must
968 * release the bus after transmitting. This must be done when
969 * the transmit shift register is empty, not be done when the
970 * transmit holding register is empty. This functionality
971 * allows an RS485 driver to be written in user space.
972 */
973static int get_lsr_info(struct mcf_serial * info, unsigned int *value)
974{
975 volatile unsigned char *uartp;
976 unsigned long flags;
977 unsigned char status;
978
979 local_irq_save(flags);
980 uartp = info->addr;
981 status = (uartp[MCFUART_USR] & MCFUART_USR_TXEMPTY) ? TIOCSER_TEMT : 0;
982 local_irq_restore(flags);
983
984 return put_user(status,value);
985}
986
987/*
988 * This routine sends a break character out the serial port.
989 */
990static void send_break( struct mcf_serial * info, int duration)
991{
992 volatile unsigned char *uartp;
993 unsigned long flags;
994
995 if (!info->addr)
996 return;
997 set_current_state(TASK_INTERRUPTIBLE);
998 uartp = info->addr;
999
1000 local_irq_save(flags);
1001 uartp[MCFUART_UCR] = MCFUART_UCR_CMDBREAKSTART;
1002 schedule_timeout(duration);
1003 uartp[MCFUART_UCR] = MCFUART_UCR_CMDBREAKSTOP;
1004 local_irq_restore(flags);
1005}
1006
1007static int mcfrs_tiocmget(struct tty_struct *tty, struct file *file)
1008{
1009 struct mcf_serial * info = (struct mcf_serial *)tty->driver_data;
1010
1011 if (serial_paranoia_check(info, tty->name, "mcfrs_ioctl"))
1012 return -ENODEV;
1013 if (tty->flags & (1 << TTY_IO_ERROR))
1014 return -EIO;
1015
1016 return mcfrs_getsignals(info);
1017}
1018
1019static int mcfrs_tiocmset(struct tty_struct *tty, struct file *file,
1020 unsigned int set, unsigned int clear)
1021{
1022 struct mcf_serial * info = (struct mcf_serial *)tty->driver_data;
1023 int rts = -1, dtr = -1;
1024
1025 if (serial_paranoia_check(info, tty->name, "mcfrs_ioctl"))
1026 return -ENODEV;
1027 if (tty->flags & (1 << TTY_IO_ERROR))
1028 return -EIO;
1029
1030 if (set & TIOCM_RTS)
1031 rts = 1;
1032 if (set & TIOCM_DTR)
1033 dtr = 1;
1034 if (clear & TIOCM_RTS)
1035 rts = 0;
1036 if (clear & TIOCM_DTR)
1037 dtr = 0;
1038
1039 mcfrs_setsignals(info, dtr, rts);
1040
1041 return 0;
1042}
1043
1044static int mcfrs_ioctl(struct tty_struct *tty, struct file * file,
1045 unsigned int cmd, unsigned long arg)
1046{
1047 struct mcf_serial * info = (struct mcf_serial *)tty->driver_data;
1048 int retval, error;
1049
1050 if (serial_paranoia_check(info, tty->name, "mcfrs_ioctl"))
1051 return -ENODEV;
1052
1053 if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) &&
1054 (cmd != TIOCSERCONFIG) && (cmd != TIOCSERGWILD) &&
1055 (cmd != TIOCSERSWILD) && (cmd != TIOCSERGSTRUCT)) {
1056 if (tty->flags & (1 << TTY_IO_ERROR))
1057 return -EIO;
1058 }
1059
1060 switch (cmd) {
1061 case TCSBRK: /* SVID version: non-zero arg --> no break */
1062 retval = tty_check_change(tty);
1063 if (retval)
1064 return retval;
1065 tty_wait_until_sent(tty, 0);
1066 if (!arg)
1067 send_break(info, HZ/4); /* 1/4 second */
1068 return 0;
1069 case TCSBRKP: /* support for POSIX tcsendbreak() */
1070 retval = tty_check_change(tty);
1071 if (retval)
1072 return retval;
1073 tty_wait_until_sent(tty, 0);
1074 send_break(info, arg ? arg*(HZ/10) : HZ/4);
1075 return 0;
1076 case TIOCGSERIAL:
1077 if (access_ok(VERIFY_WRITE, (void *) arg,
1078 sizeof(struct serial_struct)))
1079 return get_serial_info(info,
1080 (struct serial_struct *) arg);
1081 return -EFAULT;
1082 case TIOCSSERIAL:
1083 return set_serial_info(info,
1084 (struct serial_struct *) arg);
1085 case TIOCSERGETLSR: /* Get line status register */
1086 if (access_ok(VERIFY_WRITE, (void *) arg,
1087 sizeof(unsigned int)))
1088 return get_lsr_info(info, (unsigned int *) arg);
1089 return -EFAULT;
1090 case TIOCSERGSTRUCT:
1091 error = copy_to_user((struct mcf_serial *) arg,
1092 info, sizeof(struct mcf_serial));
1093 if (error)
1094 return -EFAULT;
1095 return 0;
1096
1097#ifdef TIOCSET422
1098 case TIOCSET422: {
1099 unsigned int val;
1100 get_user(val, (unsigned int *) arg);
1101 mcf_setpa(MCFPP_PA11, (val ? 0 : MCFPP_PA11));
1102 break;
1103 }
1104 case TIOCGET422: {
1105 unsigned int val;
1106 val = (mcf_getpa() & MCFPP_PA11) ? 0 : 1;
1107 put_user(val, (unsigned int *) arg);
1108 break;
1109 }
1110#endif
1111
1112 default:
1113 return -ENOIOCTLCMD;
1114 }
1115 return 0;
1116}
1117
1118static void mcfrs_set_termios(struct tty_struct *tty, struct ktermios *old_termios)
1119{
1120 struct mcf_serial *info = (struct mcf_serial *)tty->driver_data;
1121
1122 if (tty->termios->c_cflag == old_termios->c_cflag)
1123 return;
1124
1125 mcfrs_change_speed(info);
1126
1127 if ((old_termios->c_cflag & CRTSCTS) &&
1128 !(tty->termios->c_cflag & CRTSCTS)) {
1129 tty->hw_stopped = 0;
1130 mcfrs_setsignals(info, -1, 1);
1131#if 0
1132 mcfrs_start(tty);
1133#endif
1134 }
1135}
1136
1137/*
1138 * ------------------------------------------------------------
1139 * mcfrs_close()
1140 *
1141 * This routine is called when the serial port gets closed. First, we
1142 * wait for the last remaining data to be sent. Then, we unlink its
1143 * S structure from the interrupt chain if necessary, and we free
1144 * that IRQ if nothing is left in the chain.
1145 * ------------------------------------------------------------
1146 */
1147static void mcfrs_close(struct tty_struct *tty, struct file * filp)
1148{
1149 volatile unsigned char *uartp;
1150 struct mcf_serial *info = (struct mcf_serial *)tty->driver_data;
1151 unsigned long flags;
1152
1153 if (!info || serial_paranoia_check(info, tty->name, "mcfrs_close"))
1154 return;
1155
1156 local_irq_save(flags);
1157
1158 if (tty_hung_up_p(filp)) {
1159 local_irq_restore(flags);
1160 return;
1161 }
1162
1163#ifdef SERIAL_DEBUG_OPEN
1164 printk("mcfrs_close ttyS%d, count = %d\n", info->line, info->count);
1165#endif
1166 if ((tty->count == 1) && (info->count != 1)) {
1167 /*
1168 * Uh, oh. tty->count is 1, which means that the tty
1169 * structure will be freed. Info->count should always
1170 * be one in these conditions. If it's greater than
1171 * one, we've got real problems, since it means the
1172 * serial port won't be shutdown.
1173 */
1174 printk("MCFRS: bad serial port count; tty->count is 1, "
1175 "info->count is %d\n", info->count);
1176 info->count = 1;
1177 }
1178 if (--info->count < 0) {
1179 printk("MCFRS: bad serial port count for ttyS%d: %d\n",
1180 info->line, info->count);
1181 info->count = 0;
1182 }
1183 if (info->count) {
1184 local_irq_restore(flags);
1185 return;
1186 }
1187 info->flags |= ASYNC_CLOSING;
1188
1189 /*
1190 * Now we wait for the transmit buffer to clear; and we notify
1191 * the line discipline to only process XON/XOFF characters.
1192 */
1193 tty->closing = 1;
1194 if (info->closing_wait != ASYNC_CLOSING_WAIT_NONE)
1195 tty_wait_until_sent(tty, info->closing_wait);
1196
1197 /*
1198 * At this point we stop accepting input. To do this, we
1199 * disable the receive line status interrupts, and tell the
1200 * interrupt driver to stop checking the data ready bit in the
1201 * line status register.
1202 */
1203 info->imr &= ~MCFUART_UIR_RXREADY;
1204 uartp = info->addr;
1205 uartp[MCFUART_UIMR] = info->imr;
1206
1207#if 0
1208 /* FIXME: do we need to keep this enabled for console?? */
1209 if (mcfrs_console_inited && (mcfrs_console_port == info->line)) {
1210 /* Do not disable the UART */ ;
1211 } else
1212#endif
1213 shutdown(info);
1214 mcfrs_flush_buffer(tty);
1215 tty_ldisc_flush(tty);
1216
1217 tty->closing = 0;
1218 info->event = 0;
1219 info->port.tty = NULL;
1220#if 0
1221 if (tty->ldisc.num != ldiscs[N_TTY].num) {
1222 if (tty->ldisc.close)
1223 (tty->ldisc.close)(tty);
1224 tty->ldisc = ldiscs[N_TTY];
1225 tty->termios->c_line = N_TTY;
1226 if (tty->ldisc.open)
1227 (tty->ldisc.open)(tty);
1228 }
1229#endif
1230 if (info->blocked_open) {
1231 if (info->close_delay) {
1232 msleep_interruptible(jiffies_to_msecs(info->close_delay));
1233 }
1234 wake_up_interruptible(&info->open_wait);
1235 }
1236 info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
1237 wake_up_interruptible(&info->close_wait);
1238 local_irq_restore(flags);
1239}
1240
1241/*
1242 * mcfrs_wait_until_sent() --- wait until the transmitter is empty
1243 */
1244static void
1245mcfrs_wait_until_sent(struct tty_struct *tty, int timeout)
1246{
1247#ifdef CONFIG_M5272
1248#define MCF5272_FIFO_SIZE 25 /* fifo size + shift reg */
1249
1250 struct mcf_serial * info = (struct mcf_serial *)tty->driver_data;
1251 volatile unsigned char *uartp;
1252 unsigned long orig_jiffies, fifo_time, char_time, fifo_cnt;
1253
1254 if (serial_paranoia_check(info, tty->name, "mcfrs_wait_until_sent"))
1255 return;
1256
1257 orig_jiffies = jiffies;
1258
1259 /*
1260 * Set the check interval to be 1/5 of the approximate time
1261 * to send the entire fifo, and make it at least 1. The check
1262 * interval should also be less than the timeout.
1263 *
1264 * Note: we have to use pretty tight timings here to satisfy
1265 * the NIST-PCTS.
1266 */
1267 lock_kernel();
1268
1269 fifo_time = (MCF5272_FIFO_SIZE * HZ * 10) / info->baud;
1270 char_time = fifo_time / 5;
1271 if (char_time == 0)
1272 char_time = 1;
1273 if (timeout && timeout < char_time)
1274 char_time = timeout;
1275
1276 /*
1277 * Clamp the timeout period at 2 * the time to empty the
1278 * fifo. Just to be safe, set the minimum at .5 seconds.
1279 */
1280 fifo_time *= 2;
1281 if (fifo_time < (HZ/2))
1282 fifo_time = HZ/2;
1283 if (!timeout || timeout > fifo_time)
1284 timeout = fifo_time;
1285
1286 /*
1287 * Account for the number of bytes in the UART
1288 * transmitter FIFO plus any byte being shifted out.
1289 */
1290 uartp = (volatile unsigned char *) info->addr;
1291 for (;;) {
1292 fifo_cnt = (uartp[MCFUART_UTF] & MCFUART_UTF_TXB);
1293 if ((uartp[MCFUART_USR] & (MCFUART_USR_TXREADY|
1294 MCFUART_USR_TXEMPTY)) ==
1295 MCFUART_USR_TXREADY)
1296 fifo_cnt++;
1297 if (fifo_cnt == 0)
1298 break;
1299 msleep_interruptible(jiffies_to_msecs(char_time));
1300 if (signal_pending(current))
1301 break;
1302 if (timeout && time_after(jiffies, orig_jiffies + timeout))
1303 break;
1304 }
1305 unlock_kernel();
1306#else
1307 /*
1308 * For the other coldfire models, assume all data has been sent
1309 */
1310#endif
1311}
1312
1313/*
1314 * mcfrs_hangup() --- called by tty_hangup() when a hangup is signaled.
1315 */
1316void mcfrs_hangup(struct tty_struct *tty)
1317{
1318 struct mcf_serial * info = (struct mcf_serial *)tty->driver_data;
1319
1320 if (serial_paranoia_check(info, tty->name, "mcfrs_hangup"))
1321 return;
1322
1323 mcfrs_flush_buffer(tty);
1324 shutdown(info);
1325 info->event = 0;
1326 info->count = 0;
1327 info->flags &= ~ASYNC_NORMAL_ACTIVE;
1328 info->port.tty = NULL;
1329 wake_up_interruptible(&info->open_wait);
1330}
1331
1332/*
1333 * ------------------------------------------------------------
1334 * mcfrs_open() and friends
1335 * ------------------------------------------------------------
1336 */
1337static int block_til_ready(struct tty_struct *tty, struct file * filp,
1338 struct mcf_serial *info)
1339{
1340 DECLARE_WAITQUEUE(wait, current);
1341 int retval;
1342 int do_clocal = 0;
1343
1344 /*
1345 * If the device is in the middle of being closed, then block
1346 * until it's done, and then try again.
1347 */
1348 if (info->flags & ASYNC_CLOSING) {
1349 interruptible_sleep_on(&info->close_wait);
1350#ifdef SERIAL_DO_RESTART
1351 if (info->flags & ASYNC_HUP_NOTIFY)
1352 return -EAGAIN;
1353 else
1354 return -ERESTARTSYS;
1355#else
1356 return -EAGAIN;
1357#endif
1358 }
1359
1360 /*
1361 * If non-blocking mode is set, or the port is not enabled,
1362 * then make the check up front and then exit.
1363 */
1364 if ((filp->f_flags & O_NONBLOCK) ||
1365 (tty->flags & (1 << TTY_IO_ERROR))) {
1366 info->flags |= ASYNC_NORMAL_ACTIVE;
1367 return 0;
1368 }
1369
1370 if (tty->termios->c_cflag & CLOCAL)
1371 do_clocal = 1;
1372
1373 /*
1374 * Block waiting for the carrier detect and the line to become
1375 * free (i.e., not in use by the callout). While we are in
1376 * this loop, info->count is dropped by one, so that
1377 * mcfrs_close() knows when to free things. We restore it upon
1378 * exit, either normal or abnormal.
1379 */
1380 retval = 0;
1381 add_wait_queue(&info->open_wait, &wait);
1382#ifdef SERIAL_DEBUG_OPEN
1383 printk("block_til_ready before block: ttyS%d, count = %d\n",
1384 info->line, info->count);
1385#endif
1386 info->count--;
1387 info->blocked_open++;
1388 while (1) {
1389 local_irq_disable();
1390 mcfrs_setsignals(info, 1, 1);
1391 local_irq_enable();
1392 current->state = TASK_INTERRUPTIBLE;
1393 if (tty_hung_up_p(filp) ||
1394 !(info->flags & ASYNC_INITIALIZED)) {
1395#ifdef SERIAL_DO_RESTART
1396 if (info->flags & ASYNC_HUP_NOTIFY)
1397 retval = -EAGAIN;
1398 else
1399 retval = -ERESTARTSYS;
1400#else
1401 retval = -EAGAIN;
1402#endif
1403 break;
1404 }
1405 if (!(info->flags & ASYNC_CLOSING) &&
1406 (do_clocal || (mcfrs_getsignals(info) & TIOCM_CD)))
1407 break;
1408 if (signal_pending(current)) {
1409 retval = -ERESTARTSYS;
1410 break;
1411 }
1412#ifdef SERIAL_DEBUG_OPEN
1413 printk("block_til_ready blocking: ttyS%d, count = %d\n",
1414 info->line, info->count);
1415#endif
1416 schedule();
1417 }
1418 current->state = TASK_RUNNING;
1419 remove_wait_queue(&info->open_wait, &wait);
1420 if (!tty_hung_up_p(filp))
1421 info->count++;
1422 info->blocked_open--;
1423#ifdef SERIAL_DEBUG_OPEN
1424 printk("block_til_ready after blocking: ttyS%d, count = %d\n",
1425 info->line, info->count);
1426#endif
1427 if (retval)
1428 return retval;
1429 info->flags |= ASYNC_NORMAL_ACTIVE;
1430 return 0;
1431}
1432
1433/*
1434 * This routine is called whenever a serial port is opened. It
1435 * enables interrupts for a serial port, linking in its structure into
1436 * the IRQ chain. It also performs the serial-specific
1437 * initialization for the tty structure.
1438 */
1439int mcfrs_open(struct tty_struct *tty, struct file * filp)
1440{
1441 struct mcf_serial *info;
1442 int retval, line;
1443
1444 line = tty->index;
1445 if ((line < 0) || (line >= NR_PORTS))
1446 return -ENODEV;
1447 info = mcfrs_table + line;
1448 if (serial_paranoia_check(info, tty->name, "mcfrs_open"))
1449 return -ENODEV;
1450#ifdef SERIAL_DEBUG_OPEN
1451 printk("mcfrs_open %s, count = %d\n", tty->name, info->count);
1452#endif
1453 info->count++;
1454 tty->driver_data = info;
1455 info->port.tty = tty;
1456
1457 /*
1458 * Start up serial port
1459 */
1460 retval = startup(info);
1461 if (retval)
1462 return retval;
1463
1464 retval = block_til_ready(tty, filp, info);
1465 if (retval) {
1466#ifdef SERIAL_DEBUG_OPEN
1467 printk("mcfrs_open returning after block_til_ready with %d\n",
1468 retval);
1469#endif
1470 return retval;
1471 }
1472
1473#ifdef SERIAL_DEBUG_OPEN
1474 printk("mcfrs_open %s successful...\n", tty->name);
1475#endif
1476 return 0;
1477}
1478
1479/*
1480 * Based on the line number set up the internal interrupt stuff.
1481 */
1482static void mcfrs_irqinit(struct mcf_serial *info)
1483{
1484#if defined(CONFIG_M5272)
1485 volatile unsigned long *icrp;
1486 volatile unsigned long *portp;
1487 volatile unsigned char *uartp;
1488
1489 uartp = info->addr;
1490 icrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_ICR2);
1491
1492 switch (info->line) {
1493 case 0:
1494 *icrp = 0xe0000000;
1495 break;
1496 case 1:
1497 *icrp = 0x0e000000;
1498 break;
1499 default:
1500 printk("MCFRS: don't know how to handle UART %d interrupt?\n",
1501 info->line);
1502 return;
1503 }
1504
1505 /* Enable the output lines for the serial ports */
1506 portp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_PBCNT);
1507 *portp = (*portp & ~0x000000ff) | 0x00000055;
1508 portp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_PDCNT);
1509 *portp = (*portp & ~0x000003fc) | 0x000002a8;
1510#elif defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x)
1511 volatile unsigned char *icrp, *uartp;
1512 volatile unsigned long *imrp;
1513
1514 uartp = info->addr;
1515
1516 icrp = (volatile unsigned char *) (MCF_MBAR + MCFICM_INTC0 +
1517 MCFINTC_ICR0 + MCFINT_UART0 + info->line);
1518 *icrp = 0x30 + info->line; /* level 6, line based priority */
1519
1520 imrp = (volatile unsigned long *) (MCF_MBAR + MCFICM_INTC0 +
1521 MCFINTC_IMRL);
1522 *imrp &= ~((1 << (info->irq - MCFINT_VECBASE)) | 1);
1523#if defined(CONFIG_M527x)
1524 {
1525 /*
1526 * External Pin Mask Setting & Enable External Pin for Interface
1527 * mrcbis@aliceposta.it
1528 */
1529 u16 *serpin_enable_mask;
1530 serpin_enable_mask = (u16 *) (MCF_IPSBAR + MCF_GPIO_PAR_UART);
1531 if (info->line == 0)
1532 *serpin_enable_mask |= UART0_ENABLE_MASK;
1533 else if (info->line == 1)
1534 *serpin_enable_mask |= UART1_ENABLE_MASK;
1535 else if (info->line == 2)
1536 *serpin_enable_mask |= UART2_ENABLE_MASK;
1537 }
1538#endif
1539#if defined(CONFIG_M528x)
1540 /* make sure PUAPAR is set for UART0 and UART1 */
1541 if (info->line < 2) {
1542 volatile unsigned char *portp = (volatile unsigned char *) (MCF_MBAR + MCF5282_GPIO_PUAPAR);
1543 *portp |= (0x03 << (info->line * 2));
1544 }
1545#endif
1546#elif defined(CONFIG_M520x)
1547 volatile unsigned char *icrp, *uartp;
1548 volatile unsigned long *imrp;
1549
1550 uartp = info->addr;
1551
1552 icrp = (volatile unsigned char *) (MCF_MBAR + MCFICM_INTC0 +
1553 MCFINTC_ICR0 + MCFINT_UART0 + info->line);
1554 *icrp = 0x03;
1555
1556 imrp = (volatile unsigned long *) (MCF_MBAR + MCFICM_INTC0 +
1557 MCFINTC_IMRL);
1558 *imrp &= ~((1 << (info->irq - MCFINT_VECBASE)) | 1);
1559 if (info->line < 2) {
1560 unsigned short *uart_par;
1561 uart_par = (unsigned short *)(MCF_IPSBAR + MCF_GPIO_PAR_UART);
1562 if (info->line == 0)
1563 *uart_par |= MCF_GPIO_PAR_UART_PAR_UTXD0
1564 | MCF_GPIO_PAR_UART_PAR_URXD0;
1565 else if (info->line == 1)
1566 *uart_par |= MCF_GPIO_PAR_UART_PAR_UTXD1
1567 | MCF_GPIO_PAR_UART_PAR_URXD1;
1568 } else if (info->line == 2) {
1569 unsigned char *feci2c_par;
1570 feci2c_par = (unsigned char *)(MCF_IPSBAR + MCF_GPIO_PAR_FECI2C);
1571 *feci2c_par &= ~0x0F;
1572 *feci2c_par |= MCF_GPIO_PAR_FECI2C_PAR_SCL_UTXD2
1573 | MCF_GPIO_PAR_FECI2C_PAR_SDA_URXD2;
1574 }
1575#elif defined(CONFIG_M532x)
1576 volatile unsigned char *uartp;
1577 uartp = info->addr;
1578 switch (info->line) {
1579 case 0:
1580 MCF_INTC0_ICR26 = 0x3;
1581 MCF_INTC0_CIMR = 26;
1582 /* GPIO initialization */
1583 MCF_GPIO_PAR_UART |= 0x000F;
1584 break;
1585 case 1:
1586 MCF_INTC0_ICR27 = 0x3;
1587 MCF_INTC0_CIMR = 27;
1588 /* GPIO initialization */
1589 MCF_GPIO_PAR_UART |= 0x0FF0;
1590 break;
1591 case 2:
1592 MCF_INTC0_ICR28 = 0x3;
1593 MCF_INTC0_CIMR = 28;
1594 /* GPIOs also must be initalized, depends on board */
1595 break;
1596 }
1597#else
1598 volatile unsigned char *icrp, *uartp;
1599
1600 switch (info->line) {
1601 case 0:
1602 icrp = (volatile unsigned char *) (MCF_MBAR + MCFSIM_UART1ICR);
1603 *icrp = /*MCFSIM_ICR_AUTOVEC |*/ MCFSIM_ICR_LEVEL6 |
1604 MCFSIM_ICR_PRI1;
1605 mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_UART1);
1606 break;
1607 case 1:
1608 icrp = (volatile unsigned char *) (MCF_MBAR + MCFSIM_UART2ICR);
1609 *icrp = /*MCFSIM_ICR_AUTOVEC |*/ MCFSIM_ICR_LEVEL6 |
1610 MCFSIM_ICR_PRI2;
1611 mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_UART2);
1612 break;
1613 default:
1614 printk("MCFRS: don't know how to handle UART %d interrupt?\n",
1615 info->line);
1616 return;
1617 }
1618
1619 uartp = info->addr;
1620 uartp[MCFUART_UIVR] = info->irq;
1621#endif
1622
1623 /* Clear mask, so no surprise interrupts. */
1624 uartp[MCFUART_UIMR] = 0;
1625
1626 if (request_irq(info->irq, mcfrs_interrupt, IRQF_DISABLED,
1627 "ColdFire UART", NULL)) {
1628 printk("MCFRS: Unable to attach ColdFire UART %d interrupt "
1629 "vector=%d\n", info->line, info->irq);
1630 }
1631
1632 return;
1633}
1634
1635
1636char *mcfrs_drivername = "ColdFire internal UART serial driver version 1.00\n";
1637
1638
1639/*
1640 * Serial stats reporting...
1641 */
1642int mcfrs_readproc(char *page, char **start, off_t off, int count,
1643 int *eof, void *data)
1644{
1645 struct mcf_serial *info;
1646 char str[20];
1647 int len, sigs, i;
1648
1649 len = sprintf(page, mcfrs_drivername);
1650 for (i = 0; (i < NR_PORTS); i++) {
1651 info = &mcfrs_table[i];
1652 len += sprintf((page + len), "%d: port:%x irq=%d baud:%d ",
1653 i, (unsigned int) info->addr, info->irq, info->baud);
1654 if (info->stats.rx || info->stats.tx)
1655 len += sprintf((page + len), "tx:%d rx:%d ",
1656 info->stats.tx, info->stats.rx);
1657 if (info->stats.rxframing)
1658 len += sprintf((page + len), "fe:%d ",
1659 info->stats.rxframing);
1660 if (info->stats.rxparity)
1661 len += sprintf((page + len), "pe:%d ",
1662 info->stats.rxparity);
1663 if (info->stats.rxbreak)
1664 len += sprintf((page + len), "brk:%d ",
1665 info->stats.rxbreak);
1666 if (info->stats.rxoverrun)
1667 len += sprintf((page + len), "oe:%d ",
1668 info->stats.rxoverrun);
1669
1670 str[0] = str[1] = 0;
1671 if ((sigs = mcfrs_getsignals(info))) {
1672 if (sigs & TIOCM_RTS)
1673 strcat(str, "|RTS");
1674 if (sigs & TIOCM_CTS)
1675 strcat(str, "|CTS");
1676 if (sigs & TIOCM_DTR)
1677 strcat(str, "|DTR");
1678 if (sigs & TIOCM_CD)
1679 strcat(str, "|CD");
1680 }
1681
1682 len += sprintf((page + len), "%s\n", &str[1]);
1683 }
1684
1685 return(len);
1686}
1687
1688
1689/* Finally, routines used to initialize the serial driver. */
1690
1691static void show_serial_version(void)
1692{
1693 printk(mcfrs_drivername);
1694}
1695
1696static const struct tty_operations mcfrs_ops = {
1697 .open = mcfrs_open,
1698 .close = mcfrs_close,
1699 .write = mcfrs_write,
1700 .flush_chars = mcfrs_flush_chars,
1701 .write_room = mcfrs_write_room,
1702 .chars_in_buffer = mcfrs_chars_in_buffer,
1703 .flush_buffer = mcfrs_flush_buffer,
1704 .ioctl = mcfrs_ioctl,
1705 .throttle = mcfrs_throttle,
1706 .unthrottle = mcfrs_unthrottle,
1707 .set_termios = mcfrs_set_termios,
1708 .stop = mcfrs_stop,
1709 .start = mcfrs_start,
1710 .hangup = mcfrs_hangup,
1711 .read_proc = mcfrs_readproc,
1712 .wait_until_sent = mcfrs_wait_until_sent,
1713 .tiocmget = mcfrs_tiocmget,
1714 .tiocmset = mcfrs_tiocmset,
1715};
1716
1717/* mcfrs_init inits the driver */
1718static int __init
1719mcfrs_init(void)
1720{
1721 struct mcf_serial *info;
1722 unsigned long flags;
1723 int i;
1724
1725 /* Setup base handler, and timer table. */
1726#ifdef MCFPP_DCD0
1727 init_timer(&mcfrs_timer_struct);
1728 mcfrs_timer_struct.function = mcfrs_timer;
1729 mcfrs_timer_struct.data = 0;
1730 mcfrs_timer_struct.expires = jiffies + HZ/25;
1731 add_timer(&mcfrs_timer_struct);
1732 mcfrs_ppstatus = mcf_getppdata() & (MCFPP_DCD0 | MCFPP_DCD1);
1733#endif
1734 mcfrs_serial_driver = alloc_tty_driver(NR_PORTS);
1735 if (!mcfrs_serial_driver)
1736 return -ENOMEM;
1737
1738 show_serial_version();
1739
1740 /* Initialize the tty_driver structure */
1741 mcfrs_serial_driver->owner = THIS_MODULE;
1742 mcfrs_serial_driver->name = "ttyS";
1743 mcfrs_serial_driver->driver_name = "mcfserial";
1744 mcfrs_serial_driver->major = TTY_MAJOR;
1745 mcfrs_serial_driver->minor_start = 64;
1746 mcfrs_serial_driver->type = TTY_DRIVER_TYPE_SERIAL;
1747 mcfrs_serial_driver->subtype = SERIAL_TYPE_NORMAL;
1748 mcfrs_serial_driver->init_termios = tty_std_termios;
1749
1750 mcfrs_serial_driver->init_termios.c_cflag =
1751 mcfrs_console_cbaud | CS8 | CREAD | HUPCL | CLOCAL;
1752 mcfrs_serial_driver->flags = TTY_DRIVER_REAL_RAW;
1753
1754 tty_set_operations(mcfrs_serial_driver, &mcfrs_ops);
1755
1756 if (tty_register_driver(mcfrs_serial_driver)) {
1757 printk("MCFRS: Couldn't register serial driver\n");
1758 put_tty_driver(mcfrs_serial_driver);
1759 return(-EBUSY);
1760 }
1761
1762 local_irq_save(flags);
1763
1764 /*
1765 * Configure all the attached serial ports.
1766 */
1767 for (i = 0, info = mcfrs_table; (i < NR_PORTS); i++, info++) {
1768 info->magic = SERIAL_MAGIC;
1769 info->line = i;
1770 info->port.tty = NULL;
1771 info->custom_divisor = 16;
1772 info->close_delay = 50;
1773 info->closing_wait = 3000;
1774 info->x_char = 0;
1775 info->event = 0;
1776 info->count = 0;
1777 info->blocked_open = 0;
1778 INIT_WORK(&info->tqueue, mcfrs_offintr);
1779 INIT_WORK(&info->tqueue_hangup, do_serial_hangup);
1780 init_waitqueue_head(&info->open_wait);
1781 init_waitqueue_head(&info->close_wait);
1782
1783 info->imr = 0;
1784 mcfrs_setsignals(info, 0, 0);
1785 mcfrs_irqinit(info);
1786
1787 printk("ttyS%d at 0x%04x (irq = %d)", info->line,
1788 (unsigned int) info->addr, info->irq);
1789 printk(" is a builtin ColdFire UART\n");
1790 }
1791
1792 local_irq_restore(flags);
1793 return 0;
1794}
1795
1796module_init(mcfrs_init);
1797
1798/****************************************************************************/
1799/* Serial Console */
1800/****************************************************************************/
1801
1802/*
1803 * Quick and dirty UART initialization, for console output.
1804 */
1805
1806void mcfrs_init_console(void)
1807{
1808 volatile unsigned char *uartp;
1809 unsigned int clk;
1810
1811 /*
1812 * Reset UART, get it into known state...
1813 */
1814 uartp = (volatile unsigned char *) (MCF_MBAR +
1815 (mcfrs_console_port ? MCFUART_BASE2 : MCFUART_BASE1));
1816
1817 uartp[MCFUART_UCR] = MCFUART_UCR_CMDRESETRX; /* reset RX */
1818 uartp[MCFUART_UCR] = MCFUART_UCR_CMDRESETTX; /* reset TX */
1819 uartp[MCFUART_UCR] = MCFUART_UCR_CMDRESETMRPTR; /* reset MR pointer */
1820
1821 /*
1822 * Set port for defined baud , 8 data bits, 1 stop bit, no parity.
1823 */
1824 uartp[MCFUART_UMR] = MCFUART_MR1_PARITYNONE | MCFUART_MR1_CS8;
1825 uartp[MCFUART_UMR] = MCFUART_MR2_STOP1;
1826
1827#ifdef CONFIG_M5272
1828{
1829 /*
1830 * For the MCF5272, also compute the baudrate fraction.
1831 */
1832 int fraction = MCF_BUSCLK - (clk * 32 * mcfrs_console_baud);
1833 fraction *= 16;
1834 fraction /= (32 * mcfrs_console_baud);
1835 uartp[MCFUART_UFPD] = (fraction & 0xf); /* set fraction */
1836 clk = (MCF_BUSCLK / mcfrs_console_baud) / 32;
1837}
1838#else
1839 clk = ((MCF_BUSCLK / mcfrs_console_baud) + 16) / 32; /* set baud */
1840#endif
1841
1842 uartp[MCFUART_UBG1] = (clk & 0xff00) >> 8; /* set msb baud */
1843 uartp[MCFUART_UBG2] = (clk & 0xff); /* set lsb baud */
1844 uartp[MCFUART_UCSR] = MCFUART_UCSR_RXCLKTIMER | MCFUART_UCSR_TXCLKTIMER;
1845 uartp[MCFUART_UCR] = MCFUART_UCR_RXENABLE | MCFUART_UCR_TXENABLE;
1846
1847 mcfrs_console_inited++;
1848 return;
1849}
1850
1851
1852/*
1853 * Setup for console. Argument comes from the boot command line.
1854 */
1855
1856int mcfrs_console_setup(struct console *cp, char *arg)
1857{
1858 int i, n = CONSOLE_BAUD_RATE;
1859
1860 if (!cp)
1861 return(-1);
1862
1863 if (!strncmp(cp->name, "ttyS", 4))
1864 mcfrs_console_port = cp->index;
1865 else if (!strncmp(cp->name, "cua", 3))
1866 mcfrs_console_port = cp->index;
1867 else
1868 return(-1);
1869
1870 if (arg)
1871 n = simple_strtoul(arg,NULL,0);
1872 for (i = 0; i < MCFRS_BAUD_TABLE_SIZE; i++)
1873 if (mcfrs_baud_table[i] == n)
1874 break;
1875 if (i < MCFRS_BAUD_TABLE_SIZE) {
1876 mcfrs_console_baud = n;
1877 mcfrs_console_cbaud = 0;
1878 if (i > 15) {
1879 mcfrs_console_cbaud |= CBAUDEX;
1880 i -= 15;
1881 }
1882 mcfrs_console_cbaud |= i;
1883 }
1884 mcfrs_init_console(); /* make sure baud rate changes */
1885 return(0);
1886}
1887
1888
1889static struct tty_driver *mcfrs_console_device(struct console *c, int *index)
1890{
1891 *index = c->index;
1892 return mcfrs_serial_driver;
1893}
1894
1895
1896/*
1897 * Output a single character, using UART polled mode.
1898 * This is used for console output.
1899 */
1900
1901int mcfrs_put_char(char ch)
1902{
1903 volatile unsigned char *uartp;
1904 unsigned long flags;
1905 int i;
1906
1907 uartp = (volatile unsigned char *) (MCF_MBAR +
1908 (mcfrs_console_port ? MCFUART_BASE2 : MCFUART_BASE1));
1909
1910 local_irq_save(flags);
1911 for (i = 0; (i < 0x10000); i++) {
1912 if (uartp[MCFUART_USR] & MCFUART_USR_TXREADY)
1913 break;
1914 }
1915 if (i < 0x10000) {
1916 uartp[MCFUART_UTB] = ch;
1917 for (i = 0; (i < 0x10000); i++)
1918 if (uartp[MCFUART_USR] & MCFUART_USR_TXEMPTY)
1919 break;
1920 }
1921 if (i >= 0x10000)
1922 mcfrs_init_console(); /* try and get it back */
1923 local_irq_restore(flags);
1924
1925 return 1;
1926}
1927
1928
1929/*
1930 * rs_console_write is registered for printk output.
1931 */
1932
1933void mcfrs_console_write(struct console *cp, const char *p, unsigned len)
1934{
1935 if (!mcfrs_console_inited)
1936 mcfrs_init_console();
1937 while (len-- > 0) {
1938 if (*p == '\n')
1939 mcfrs_put_char('\r');
1940 mcfrs_put_char(*p++);
1941 }
1942}
1943
1944/*
1945 * declare our consoles
1946 */
1947
1948struct console mcfrs_console = {
1949 .name = "ttyS",
1950 .write = mcfrs_console_write,
1951 .device = mcfrs_console_device,
1952 .setup = mcfrs_console_setup,
1953 .flags = CON_PRINTBUFFER,
1954 .index = -1,
1955};
1956
1957static int __init mcfrs_console_init(void)
1958{
1959 register_console(&mcfrs_console);
1960 return 0;
1961}
1962
1963console_initcall(mcfrs_console_init);
1964
1965/****************************************************************************/
diff --git a/drivers/serial/mcfserial.h b/drivers/serial/mcfserial.h
deleted file mode 100644
index 56420e2cb110..000000000000
--- a/drivers/serial/mcfserial.h
+++ /dev/null
@@ -1,74 +0,0 @@
1/*
2 * mcfserial.c -- serial driver for ColdFire internal UARTS.
3 *
4 * Copyright (c) 1999 Greg Ungerer <gerg@snapgear.com>
5 * Copyright (c) 2000-2001 Lineo, Inc. <www.lineo.com>
6 * Copyright (c) 2002 SnapGear Inc., <www.snapgear.com>
7 *
8 * Based on code from 68332serial.c which was:
9 *
10 * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
11 * Copyright (C) 1998 TSHG
12 * Copyright (c) 1999 Rt-Control Inc. <jeff@uclinux.org>
13 */
14#ifndef _MCF_SERIAL_H
15#define _MCF_SERIAL_H
16
17#include <linux/serial.h>
18
19#ifdef __KERNEL__
20
21/*
22 * Define a local serial stats structure.
23 */
24
25struct mcf_stats {
26 unsigned int rx;
27 unsigned int tx;
28 unsigned int rxbreak;
29 unsigned int rxframing;
30 unsigned int rxparity;
31 unsigned int rxoverrun;
32};
33
34
35/*
36 * This is our internal structure for each serial port's state.
37 * Each serial port has one of these structures associated with it.
38 */
39
40struct mcf_serial {
41 int magic;
42 volatile unsigned char *addr; /* UART memory address */
43 int irq;
44 int flags; /* defined in tty.h */
45 int type; /* UART type */
46 struct tty_struct *tty;
47 unsigned char imr; /* Software imr register */
48 unsigned int baud;
49 int sigs;
50 int custom_divisor;
51 int x_char; /* xon/xoff character */
52 int baud_base;
53 int close_delay;
54 unsigned short closing_wait;
55 unsigned short closing_wait2;
56 unsigned long event;
57 int line;
58 int count; /* # of fd on device */
59 int blocked_open; /* # of blocked opens */
60 unsigned char *xmit_buf;
61 int xmit_head;
62 int xmit_tail;
63 int xmit_cnt;
64 struct mcf_stats stats;
65 struct work_struct tqueue;
66 struct work_struct tqueue_hangup;
67 wait_queue_head_t open_wait;
68 wait_queue_head_t close_wait;
69
70};
71
72#endif /* __KERNEL__ */
73
74#endif /* _MCF_SERIAL_H */
diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c
index f977c98cfa95..6bdf3362e3b1 100644
--- a/drivers/serial/serial_core.c
+++ b/drivers/serial/serial_core.c
@@ -2051,7 +2051,8 @@ int uart_suspend_port(struct uart_driver *drv, struct uart_port *port)
2051 "transmitter\n", 2051 "transmitter\n",
2052 port->dev ? port->dev->bus_id : "", 2052 port->dev ? port->dev->bus_id : "",
2053 port->dev ? ": " : "", 2053 port->dev ? ": " : "",
2054 drv->dev_name, port->line); 2054 drv->dev_name,
2055 drv->tty_driver->name_base + port->line);
2055 2056
2056 ops->shutdown(port); 2057 ops->shutdown(port);
2057 } 2058 }
@@ -2154,12 +2155,11 @@ uart_report_port(struct uart_driver *drv, struct uart_port *port)
2154 2155
2155 switch (port->iotype) { 2156 switch (port->iotype) {
2156 case UPIO_PORT: 2157 case UPIO_PORT:
2157 snprintf(address, sizeof(address), 2158 snprintf(address, sizeof(address), "I/O 0x%lx", port->iobase);
2158 "I/O 0x%x", port->iobase);
2159 break; 2159 break;
2160 case UPIO_HUB6: 2160 case UPIO_HUB6:
2161 snprintf(address, sizeof(address), 2161 snprintf(address, sizeof(address),
2162 "I/O 0x%x offset 0x%x", port->iobase, port->hub6); 2162 "I/O 0x%lx offset 0x%x", port->iobase, port->hub6);
2163 break; 2163 break;
2164 case UPIO_MEM: 2164 case UPIO_MEM:
2165 case UPIO_MEM32: 2165 case UPIO_MEM32:
@@ -2177,7 +2177,9 @@ uart_report_port(struct uart_driver *drv, struct uart_port *port)
2177 printk(KERN_INFO "%s%s%s%d at %s (irq = %d) is a %s\n", 2177 printk(KERN_INFO "%s%s%s%d at %s (irq = %d) is a %s\n",
2178 port->dev ? port->dev->bus_id : "", 2178 port->dev ? port->dev->bus_id : "",
2179 port->dev ? ": " : "", 2179 port->dev ? ": " : "",
2180 drv->dev_name, port->line, address, port->irq, uart_type(port)); 2180 drv->dev_name,
2181 drv->tty_driver->name_base + port->line,
2182 address, port->irq, uart_type(port));
2181} 2183}
2182 2184
2183static void 2185static void
diff --git a/drivers/usb/serial/aircable.c b/drivers/usb/serial/aircable.c
index 79ea98c66fa8..99fb7dc59c45 100644
--- a/drivers/usb/serial/aircable.c
+++ b/drivers/usb/serial/aircable.c
@@ -272,7 +272,7 @@ static void aircable_read(struct work_struct *work)
272 * 64 bytes, to ensure I do not get throttled. 272 * 64 bytes, to ensure I do not get throttled.
273 * Ask USB mailing list for better aproach. 273 * Ask USB mailing list for better aproach.
274 */ 274 */
275 tty = port->port.tty; 275 tty = tty_port_tty_get(&port->port);
276 276
277 if (!tty) { 277 if (!tty) {
278 schedule_work(&priv->rx_work); 278 schedule_work(&priv->rx_work);
@@ -283,12 +283,13 @@ static void aircable_read(struct work_struct *work)
283 count = min(64, serial_buf_data_avail(priv->rx_buf)); 283 count = min(64, serial_buf_data_avail(priv->rx_buf));
284 284
285 if (count <= 0) 285 if (count <= 0)
286 return; /* We have finished sending everything. */ 286 goto out; /* We have finished sending everything. */
287 287
288 tty_prepare_flip_string(tty, &data, count); 288 tty_prepare_flip_string(tty, &data, count);
289 if (!data) { 289 if (!data) {
290 err("%s- kzalloc(%d) failed.", __func__, count); 290 dev_err(&port->dev, "%s- kzalloc(%d) failed.",
291 return; 291 __func__, count);
292 goto out;
292 } 293 }
293 294
294 serial_buf_get(priv->rx_buf, data, count); 295 serial_buf_get(priv->rx_buf, data, count);
@@ -297,7 +298,8 @@ static void aircable_read(struct work_struct *work)
297 298
298 if (serial_buf_data_avail(priv->rx_buf)) 299 if (serial_buf_data_avail(priv->rx_buf))
299 schedule_work(&priv->rx_work); 300 schedule_work(&priv->rx_work);
300 301out:
302 tty_kref_put(tty);
301 return; 303 return;
302} 304}
303/* End of private methods */ 305/* End of private methods */
@@ -495,7 +497,7 @@ static void aircable_read_bulk_callback(struct urb *urb)
495 usb_serial_debug_data(debug, &port->dev, __func__, 497 usb_serial_debug_data(debug, &port->dev, __func__,
496 urb->actual_length, urb->transfer_buffer); 498 urb->actual_length, urb->transfer_buffer);
497 499
498 tty = port->port.tty; 500 tty = tty_port_tty_get(&port->port);
499 if (tty && urb->actual_length) { 501 if (tty && urb->actual_length) {
500 if (urb->actual_length <= 2) { 502 if (urb->actual_length <= 2) {
501 /* This is an incomplete package */ 503 /* This is an incomplete package */
@@ -527,6 +529,7 @@ static void aircable_read_bulk_callback(struct urb *urb)
527 } 529 }
528 aircable_read(&priv->rx_work); 530 aircable_read(&priv->rx_work);
529 } 531 }
532 tty_kref_put(tty);
530 533
531 /* Schedule the next read _if_ we are still open */ 534 /* Schedule the next read _if_ we are still open */
532 if (port->port.count) { 535 if (port->port.count) {
diff --git a/drivers/usb/serial/belkin_sa.c b/drivers/usb/serial/belkin_sa.c
index 2ebe06c3405a..1913bc7c5f0b 100644
--- a/drivers/usb/serial/belkin_sa.c
+++ b/drivers/usb/serial/belkin_sa.c
@@ -322,7 +322,7 @@ static void belkin_sa_read_int_callback(struct urb *urb)
322 * to look in to this before committing any code. 322 * to look in to this before committing any code.
323 */ 323 */
324 if (priv->last_lsr & BELKIN_SA_LSR_ERR) { 324 if (priv->last_lsr & BELKIN_SA_LSR_ERR) {
325 tty = port->port.tty; 325 tty = tty_port_tty_get(&port->port);
326 /* Overrun Error */ 326 /* Overrun Error */
327 if (priv->last_lsr & BELKIN_SA_LSR_OE) { 327 if (priv->last_lsr & BELKIN_SA_LSR_OE) {
328 } 328 }
@@ -335,6 +335,7 @@ static void belkin_sa_read_int_callback(struct urb *urb)
335 /* Break Indicator */ 335 /* Break Indicator */
336 if (priv->last_lsr & BELKIN_SA_LSR_BI) { 336 if (priv->last_lsr & BELKIN_SA_LSR_BI) {
337 } 337 }
338 tty_kref_put(tty);
338 } 339 }
339#endif 340#endif
340 spin_unlock_irqrestore(&priv->lock, flags); 341 spin_unlock_irqrestore(&priv->lock, flags);
diff --git a/drivers/usb/serial/console.c b/drivers/usb/serial/console.c
index e980766bb84b..5b20de130e08 100644
--- a/drivers/usb/serial/console.c
+++ b/drivers/usb/serial/console.c
@@ -117,7 +117,7 @@ static int usb_console_setup(struct console *co, char *options)
117 } 117 }
118 118
119 port = serial->port[0]; 119 port = serial->port[0];
120 port->port.tty = NULL; 120 tty_port_tty_set(&port->port, NULL);
121 121
122 info->port = port; 122 info->port = port;
123 123
@@ -143,7 +143,7 @@ static int usb_console_setup(struct console *co, char *options)
143 } 143 }
144 memset(&dummy, 0, sizeof(struct ktermios)); 144 memset(&dummy, 0, sizeof(struct ktermios));
145 tty->termios = termios; 145 tty->termios = termios;
146 port->port.tty = tty; 146 tty_port_tty_set(&port->port, tty);
147 } 147 }
148 148
149 /* only call the device specific open if this 149 /* only call the device specific open if this
@@ -163,7 +163,7 @@ static int usb_console_setup(struct console *co, char *options)
163 tty_termios_encode_baud_rate(termios, baud, baud); 163 tty_termios_encode_baud_rate(termios, baud, baud);
164 serial->type->set_termios(tty, port, &dummy); 164 serial->type->set_termios(tty, port, &dummy);
165 165
166 port->port.tty = NULL; 166 tty_port_tty_set(&port->port, NULL);
167 kfree(termios); 167 kfree(termios);
168 kfree(tty); 168 kfree(tty);
169 } 169 }
@@ -176,7 +176,7 @@ out:
176 return retval; 176 return retval;
177free_termios: 177free_termios:
178 kfree(termios); 178 kfree(termios);
179 port->port.tty = NULL; 179 tty_port_tty_set(&port->port, NULL);
180free_tty: 180free_tty:
181 kfree(tty); 181 kfree(tty);
182reset_open_count: 182reset_open_count:
diff --git a/drivers/usb/serial/cyberjack.c b/drivers/usb/serial/cyberjack.c
index b4d72351cb96..94ef36c4764b 100644
--- a/drivers/usb/serial/cyberjack.c
+++ b/drivers/usb/serial/cyberjack.c
@@ -384,7 +384,7 @@ static void cyberjack_read_bulk_callback(struct urb *urb)
384 return; 384 return;
385 } 385 }
386 386
387 tty = port->port.tty; 387 tty = tty_port_tty_get(&port->port);
388 if (!tty) { 388 if (!tty) {
389 dbg("%s - ignoring since device not open\n", __func__); 389 dbg("%s - ignoring since device not open\n", __func__);
390 return; 390 return;
@@ -394,6 +394,7 @@ static void cyberjack_read_bulk_callback(struct urb *urb)
394 tty_insert_flip_string(tty, data, urb->actual_length); 394 tty_insert_flip_string(tty, data, urb->actual_length);
395 tty_flip_buffer_push(tty); 395 tty_flip_buffer_push(tty);
396 } 396 }
397 tty_kref_put(tty);
397 398
398 spin_lock(&priv->lock); 399 spin_lock(&priv->lock);
399 400
diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c
index 22837a3f2f89..f3514a91f915 100644
--- a/drivers/usb/serial/cypress_m8.c
+++ b/drivers/usb/serial/cypress_m8.c
@@ -1286,7 +1286,7 @@ static void cypress_read_int_callback(struct urb *urb)
1286 } 1286 }
1287 spin_unlock_irqrestore(&priv->lock, flags); 1287 spin_unlock_irqrestore(&priv->lock, flags);
1288 1288
1289 tty = port->port.tty; 1289 tty = tty_port_tty_get(&port->port);
1290 if (!tty) { 1290 if (!tty) {
1291 dbg("%s - bad tty pointer - exiting", __func__); 1291 dbg("%s - bad tty pointer - exiting", __func__);
1292 return; 1292 return;
@@ -1362,7 +1362,7 @@ static void cypress_read_int_callback(struct urb *urb)
1362 data[i]); 1362 data[i]);
1363 tty_insert_flip_char(tty, data[i], tty_flag); 1363 tty_insert_flip_char(tty, data[i], tty_flag);
1364 } 1364 }
1365 tty_flip_buffer_push(port->port.tty); 1365 tty_flip_buffer_push(tty);
1366 } 1366 }
1367 1367
1368 spin_lock_irqsave(&priv->lock, flags); 1368 spin_lock_irqsave(&priv->lock, flags);
@@ -1371,6 +1371,7 @@ static void cypress_read_int_callback(struct urb *urb)
1371 spin_unlock_irqrestore(&priv->lock, flags); 1371 spin_unlock_irqrestore(&priv->lock, flags);
1372 1372
1373continue_read: 1373continue_read:
1374 tty_kref_put(tty);
1374 1375
1375 /* Continue trying to always read... unless the port has closed. */ 1376 /* Continue trying to always read... unless the port has closed. */
1376 1377
diff --git a/drivers/usb/serial/digi_acceleport.c b/drivers/usb/serial/digi_acceleport.c
index 240aad1acaab..5756ac6d6c92 100644
--- a/drivers/usb/serial/digi_acceleport.c
+++ b/drivers/usb/serial/digi_acceleport.c
@@ -604,7 +604,9 @@ static void digi_wakeup_write_lock(struct work_struct *work)
604 604
605static void digi_wakeup_write(struct usb_serial_port *port) 605static void digi_wakeup_write(struct usb_serial_port *port)
606{ 606{
607 tty_wakeup(port->port.tty); 607 struct tty_struct *tty = tty_port_tty_get(&port->port);
608 tty_wakeup(tty);
609 tty_kref_put(tty);
608} 610}
609 611
610 612
@@ -1668,7 +1670,7 @@ static int digi_read_inb_callback(struct urb *urb)
1668{ 1670{
1669 1671
1670 struct usb_serial_port *port = urb->context; 1672 struct usb_serial_port *port = urb->context;
1671 struct tty_struct *tty = port->port.tty; 1673 struct tty_struct *tty;
1672 struct digi_port *priv = usb_get_serial_port_data(port); 1674 struct digi_port *priv = usb_get_serial_port_data(port);
1673 int opcode = ((unsigned char *)urb->transfer_buffer)[0]; 1675 int opcode = ((unsigned char *)urb->transfer_buffer)[0];
1674 int len = ((unsigned char *)urb->transfer_buffer)[1]; 1676 int len = ((unsigned char *)urb->transfer_buffer)[1];
@@ -1692,6 +1694,7 @@ static int digi_read_inb_callback(struct urb *urb)
1692 return -1; 1694 return -1;
1693 } 1695 }
1694 1696
1697 tty = tty_port_tty_get(&port->port);
1695 spin_lock(&priv->dp_port_lock); 1698 spin_lock(&priv->dp_port_lock);
1696 1699
1697 /* check for throttle; if set, do not resubmit read urb */ 1700 /* check for throttle; if set, do not resubmit read urb */
@@ -1735,6 +1738,7 @@ static int digi_read_inb_callback(struct urb *urb)
1735 } 1738 }
1736 } 1739 }
1737 spin_unlock(&priv->dp_port_lock); 1740 spin_unlock(&priv->dp_port_lock);
1741 tty_kref_put(tty);
1738 1742
1739 if (opcode == DIGI_CMD_RECEIVE_DISABLE) 1743 if (opcode == DIGI_CMD_RECEIVE_DISABLE)
1740 dbg("%s: got RECEIVE_DISABLE", __func__); 1744 dbg("%s: got RECEIVE_DISABLE", __func__);
@@ -1760,6 +1764,7 @@ static int digi_read_oob_callback(struct urb *urb)
1760 1764
1761 struct usb_serial_port *port = urb->context; 1765 struct usb_serial_port *port = urb->context;
1762 struct usb_serial *serial = port->serial; 1766 struct usb_serial *serial = port->serial;
1767 struct tty_struct *tty;
1763 struct digi_port *priv = usb_get_serial_port_data(port); 1768 struct digi_port *priv = usb_get_serial_port_data(port);
1764 int opcode, line, status, val; 1769 int opcode, line, status, val;
1765 int i; 1770 int i;
@@ -1787,10 +1792,11 @@ static int digi_read_oob_callback(struct urb *urb)
1787 if (priv == NULL) 1792 if (priv == NULL)
1788 return -1; 1793 return -1;
1789 1794
1795 tty = tty_port_tty_get(&port->port);
1790 rts = 0; 1796 rts = 0;
1791 if (port->port.count) 1797 if (port->port.count)
1792 rts = port->port.tty->termios->c_cflag & CRTSCTS; 1798 rts = tty->termios->c_cflag & CRTSCTS;
1793 1799
1794 if (opcode == DIGI_CMD_READ_INPUT_SIGNALS) { 1800 if (opcode == DIGI_CMD_READ_INPUT_SIGNALS) {
1795 spin_lock(&priv->dp_port_lock); 1801 spin_lock(&priv->dp_port_lock);
1796 /* convert from digi flags to termiox flags */ 1802 /* convert from digi flags to termiox flags */
@@ -1798,14 +1804,14 @@ static int digi_read_oob_callback(struct urb *urb)
1798 priv->dp_modem_signals |= TIOCM_CTS; 1804 priv->dp_modem_signals |= TIOCM_CTS;
1799 /* port must be open to use tty struct */ 1805 /* port must be open to use tty struct */
1800 if (rts) { 1806 if (rts) {
1801 port->port.tty->hw_stopped = 0; 1807 tty->hw_stopped = 0;
1802 digi_wakeup_write(port); 1808 digi_wakeup_write(port);
1803 } 1809 }
1804 } else { 1810 } else {
1805 priv->dp_modem_signals &= ~TIOCM_CTS; 1811 priv->dp_modem_signals &= ~TIOCM_CTS;
1806 /* port must be open to use tty struct */ 1812 /* port must be open to use tty struct */
1807 if (rts) 1813 if (rts)
1808 port->port.tty->hw_stopped = 1; 1814 tty->hw_stopped = 1;
1809 } 1815 }
1810 if (val & DIGI_READ_INPUT_SIGNALS_DSR) 1816 if (val & DIGI_READ_INPUT_SIGNALS_DSR)
1811 priv->dp_modem_signals |= TIOCM_DSR; 1817 priv->dp_modem_signals |= TIOCM_DSR;
@@ -1830,6 +1836,7 @@ static int digi_read_oob_callback(struct urb *urb)
1830 } else if (opcode == DIGI_CMD_IFLUSH_FIFO) { 1836 } else if (opcode == DIGI_CMD_IFLUSH_FIFO) {
1831 wake_up_interruptible(&priv->dp_flush_wait); 1837 wake_up_interruptible(&priv->dp_flush_wait);
1832 } 1838 }
1839 tty_kref_put(tty);
1833 } 1840 }
1834 return 0; 1841 return 0;
1835 1842
diff --git a/drivers/usb/serial/empeg.c b/drivers/usb/serial/empeg.c
index a6ab5b58d9ca..1072e847280f 100644
--- a/drivers/usb/serial/empeg.c
+++ b/drivers/usb/serial/empeg.c
@@ -33,9 +33,8 @@
33 * Moved MOD_DEC_USE_COUNT to end of empeg_close(). 33 * Moved MOD_DEC_USE_COUNT to end of empeg_close().
34 * 34 *
35 * (12/03/2000) gb 35 * (12/03/2000) gb
36 * Added port->port.tty->ldisc.set_termios(port->port.tty, NULL) to 36 * Added tty->ldisc.set_termios(port, tty, NULL) to empeg_open().
37 * empeg_open(). This notifies the tty driver that the termios have 37 * This notifies the tty driver that the termios have changed.
38 * changed.
39 * 38 *
40 * (11/13/2000) gb 39 * (11/13/2000) gb
41 * Moved tty->low_latency = 1 from empeg_read_bulk_callback() to 40 * Moved tty->low_latency = 1 from empeg_read_bulk_callback() to
@@ -354,7 +353,7 @@ static void empeg_read_bulk_callback(struct urb *urb)
354 353
355 usb_serial_debug_data(debug, &port->dev, __func__, 354 usb_serial_debug_data(debug, &port->dev, __func__,
356 urb->actual_length, data); 355 urb->actual_length, data);
357 tty = port->port.tty; 356 tty = tty_port_tty_get(&port->port);
358 357
359 if (urb->actual_length) { 358 if (urb->actual_length) {
360 tty_buffer_request_room(tty, urb->actual_length); 359 tty_buffer_request_room(tty, urb->actual_length);
@@ -362,6 +361,7 @@ static void empeg_read_bulk_callback(struct urb *urb)
362 tty_flip_buffer_push(tty); 361 tty_flip_buffer_push(tty);
363 bytes_in += urb->actual_length; 362 bytes_in += urb->actual_length;
364 } 363 }
364 tty_kref_put(tty);
365 365
366 /* Continue trying to always read */ 366 /* Continue trying to always read */
367 usb_fill_bulk_urb( 367 usb_fill_bulk_urb(
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
index 3dc93b542b30..c2ac129557aa 100644
--- a/drivers/usb/serial/ftdi_sio.c
+++ b/drivers/usb/serial/ftdi_sio.c
@@ -860,7 +860,7 @@ static int update_mctrl(struct usb_serial_port *port, unsigned int set,
860 860
861 kfree(buf); 861 kfree(buf);
862 if (rv < 0) { 862 if (rv < 0) {
863 err("%s Error from MODEM_CTRL urb: DTR %s, RTS %s", 863 dbg("%s Error from MODEM_CTRL urb: DTR %s, RTS %s",
864 __func__, 864 __func__,
865 (set & TIOCM_DTR) ? "HIGH" : 865 (set & TIOCM_DTR) ? "HIGH" :
866 (clear & TIOCM_DTR) ? "LOW" : "unchanged", 866 (clear & TIOCM_DTR) ? "LOW" : "unchanged",
@@ -1808,7 +1808,7 @@ static void ftdi_read_bulk_callback(struct urb *urb)
1808 if (port->port.count <= 0) 1808 if (port->port.count <= 0)
1809 return; 1809 return;
1810 1810
1811 tty = port->port.tty; 1811 tty = tty_port_tty_get(&port->port);
1812 if (!tty) { 1812 if (!tty) {
1813 dbg("%s - bad tty pointer - exiting", __func__); 1813 dbg("%s - bad tty pointer - exiting", __func__);
1814 return; 1814 return;
@@ -1817,7 +1817,7 @@ static void ftdi_read_bulk_callback(struct urb *urb)
1817 priv = usb_get_serial_port_data(port); 1817 priv = usb_get_serial_port_data(port);
1818 if (!priv) { 1818 if (!priv) {
1819 dbg("%s - bad port private data pointer - exiting", __func__); 1819 dbg("%s - bad port private data pointer - exiting", __func__);
1820 return; 1820 goto out;
1821 } 1821 }
1822 1822
1823 if (urb != port->read_urb) 1823 if (urb != port->read_urb)
@@ -1827,7 +1827,7 @@ static void ftdi_read_bulk_callback(struct urb *urb)
1827 /* This will happen at close every time so it is a dbg not an 1827 /* This will happen at close every time so it is a dbg not an
1828 err */ 1828 err */
1829 dbg("(this is ok on close) nonzero read bulk status received: %d", status); 1829 dbg("(this is ok on close) nonzero read bulk status received: %d", status);
1830 return; 1830 goto out;
1831 } 1831 }
1832 1832
1833 /* count data bytes, but not status bytes */ 1833 /* count data bytes, but not status bytes */
@@ -1838,7 +1838,8 @@ static void ftdi_read_bulk_callback(struct urb *urb)
1838 spin_unlock_irqrestore(&priv->rx_lock, flags); 1838 spin_unlock_irqrestore(&priv->rx_lock, flags);
1839 1839
1840 ftdi_process_read(&priv->rx_work.work); 1840 ftdi_process_read(&priv->rx_work.work);
1841 1841out:
1842 tty_kref_put(tty);
1842} /* ftdi_read_bulk_callback */ 1843} /* ftdi_read_bulk_callback */
1843 1844
1844 1845
@@ -1863,7 +1864,7 @@ static void ftdi_process_read(struct work_struct *work)
1863 if (port->port.count <= 0) 1864 if (port->port.count <= 0)
1864 return; 1865 return;
1865 1866
1866 tty = port->port.tty; 1867 tty = tty_port_tty_get(&port->port);
1867 if (!tty) { 1868 if (!tty) {
1868 dbg("%s - bad tty pointer - exiting", __func__); 1869 dbg("%s - bad tty pointer - exiting", __func__);
1869 return; 1870 return;
@@ -1872,13 +1873,13 @@ static void ftdi_process_read(struct work_struct *work)
1872 priv = usb_get_serial_port_data(port); 1873 priv = usb_get_serial_port_data(port);
1873 if (!priv) { 1874 if (!priv) {
1874 dbg("%s - bad port private data pointer - exiting", __func__); 1875 dbg("%s - bad port private data pointer - exiting", __func__);
1875 return; 1876 goto out;
1876 } 1877 }
1877 1878
1878 urb = port->read_urb; 1879 urb = port->read_urb;
1879 if (!urb) { 1880 if (!urb) {
1880 dbg("%s - bad read_urb pointer - exiting", __func__); 1881 dbg("%s - bad read_urb pointer - exiting", __func__);
1881 return; 1882 goto out;
1882 } 1883 }
1883 1884
1884 data = urb->transfer_buffer; 1885 data = urb->transfer_buffer;
@@ -2020,7 +2021,7 @@ static void ftdi_process_read(struct work_struct *work)
2020 schedule_delayed_work(&priv->rx_work, 1); 2021 schedule_delayed_work(&priv->rx_work, 1);
2021 else 2022 else
2022 dbg("%s - port is closed", __func__); 2023 dbg("%s - port is closed", __func__);
2023 return; 2024 goto out;
2024 } 2025 }
2025 2026
2026 /* urb is completely processed */ 2027 /* urb is completely processed */
@@ -2041,6 +2042,8 @@ static void ftdi_process_read(struct work_struct *work)
2041 err("%s - failed resubmitting read urb, error %d", 2042 err("%s - failed resubmitting read urb, error %d",
2042 __func__, result); 2043 __func__, result);
2043 } 2044 }
2045out:
2046 tty_kref_put(tty);
2044} /* ftdi_process_read */ 2047} /* ftdi_process_read */
2045 2048
2046 2049
@@ -2256,7 +2259,7 @@ static int ftdi_tiocmget(struct tty_struct *tty, struct file *file)
2256 0, 0, 2259 0, 0,
2257 buf, 1, WDR_TIMEOUT); 2260 buf, 1, WDR_TIMEOUT);
2258 if (ret < 0) { 2261 if (ret < 0) {
2259 err("%s Could not get modem status of device - err: %d", __func__, 2262 dbg("%s Could not get modem status of device - err: %d", __func__,
2260 ret); 2263 ret);
2261 return ret; 2264 return ret;
2262 } 2265 }
@@ -2275,7 +2278,7 @@ static int ftdi_tiocmget(struct tty_struct *tty, struct file *file)
2275 0, priv->interface, 2278 0, priv->interface,
2276 buf, 2, WDR_TIMEOUT); 2279 buf, 2, WDR_TIMEOUT);
2277 if (ret < 0) { 2280 if (ret < 0) {
2278 err("%s Could not get modem status of device - err: %d", __func__, 2281 dbg("%s Could not get modem status of device - err: %d", __func__,
2279 ret); 2282 ret);
2280 return ret; 2283 return ret;
2281 } 2284 }
diff --git a/drivers/usb/serial/garmin_gps.c b/drivers/usb/serial/garmin_gps.c
index d95382088075..2ad0569bcf19 100644
--- a/drivers/usb/serial/garmin_gps.c
+++ b/drivers/usb/serial/garmin_gps.c
@@ -276,7 +276,7 @@ static inline int isAbortTrfCmnd(const unsigned char *buf)
276static void send_to_tty(struct usb_serial_port *port, 276static void send_to_tty(struct usb_serial_port *port,
277 char *data, unsigned int actual_length) 277 char *data, unsigned int actual_length)
278{ 278{
279 struct tty_struct *tty = port->port.tty; 279 struct tty_struct *tty = tty_port_tty_get(&port->port);
280 280
281 if (tty && actual_length) { 281 if (tty && actual_length) {
282 282
@@ -287,6 +287,7 @@ static void send_to_tty(struct usb_serial_port *port,
287 tty_insert_flip_string(tty, data, actual_length); 287 tty_insert_flip_string(tty, data, actual_length);
288 tty_flip_buffer_push(tty); 288 tty_flip_buffer_push(tty);
289 } 289 }
290 tty_kref_put(tty);
290} 291}
291 292
292 293
diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c
index fe84c88ec20c..814909f1ee63 100644
--- a/drivers/usb/serial/generic.c
+++ b/drivers/usb/serial/generic.c
@@ -330,7 +330,7 @@ static void resubmit_read_urb(struct usb_serial_port *port, gfp_t mem_flags)
330static void flush_and_resubmit_read_urb(struct usb_serial_port *port) 330static void flush_and_resubmit_read_urb(struct usb_serial_port *port)
331{ 331{
332 struct urb *urb = port->read_urb; 332 struct urb *urb = port->read_urb;
333 struct tty_struct *tty = port->port.tty; 333 struct tty_struct *tty = tty_port_tty_get(&port->port);
334 int room; 334 int room;
335 335
336 /* Push data to tty */ 336 /* Push data to tty */
@@ -341,6 +341,7 @@ static void flush_and_resubmit_read_urb(struct usb_serial_port *port)
341 tty_flip_buffer_push(tty); 341 tty_flip_buffer_push(tty);
342 } 342 }
343 } 343 }
344 tty_kref_put(tty);
344 345
345 resubmit_read_urb(port, GFP_ATOMIC); 346 resubmit_read_urb(port, GFP_ATOMIC);
346} 347}
diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c
index bfa508ddb0fe..611f97fd62f1 100644
--- a/drivers/usb/serial/io_edgeport.c
+++ b/drivers/usb/serial/io_edgeport.c
@@ -600,6 +600,7 @@ static void edge_interrupt_callback(struct urb *urb)
600 struct edgeport_serial *edge_serial = urb->context; 600 struct edgeport_serial *edge_serial = urb->context;
601 struct edgeport_port *edge_port; 601 struct edgeport_port *edge_port;
602 struct usb_serial_port *port; 602 struct usb_serial_port *port;
603 struct tty_struct *tty;
603 unsigned char *data = urb->transfer_buffer; 604 unsigned char *data = urb->transfer_buffer;
604 int length = urb->actual_length; 605 int length = urb->actual_length;
605 int bytes_avail; 606 int bytes_avail;
@@ -675,9 +676,12 @@ static void edge_interrupt_callback(struct urb *urb)
675 676
676 /* tell the tty driver that something 677 /* tell the tty driver that something
677 has changed */ 678 has changed */
678 if (edge_port->port->port.tty) 679 tty = tty_port_tty_get(
679 tty_wakeup(edge_port->port->port.tty); 680 &edge_port->port->port);
680 681 if (tty) {
682 tty_wakeup(tty);
683 tty_kref_put(tty);
684 }
681 /* Since we have more credit, check 685 /* Since we have more credit, check
682 if more data can be sent */ 686 if more data can be sent */
683 send_more_port_data(edge_serial, 687 send_more_port_data(edge_serial,
@@ -778,13 +782,14 @@ static void edge_bulk_out_data_callback(struct urb *urb)
778 __func__, status); 782 __func__, status);
779 } 783 }
780 784
781 tty = edge_port->port->port.tty; 785 tty = tty_port_tty_get(&edge_port->port->port);
782 786
783 if (tty && edge_port->open) { 787 if (tty && edge_port->open) {
784 /* let the tty driver wakeup if it has a special 788 /* let the tty driver wakeup if it has a special
785 write_wakeup function */ 789 write_wakeup function */
786 tty_wakeup(tty); 790 tty_wakeup(tty);
787 } 791 }
792 tty_kref_put(tty);
788 793
789 /* Release the Write URB */ 794 /* Release the Write URB */
790 edge_port->write_in_progress = false; 795 edge_port->write_in_progress = false;
@@ -826,11 +831,12 @@ static void edge_bulk_out_cmd_callback(struct urb *urb)
826 } 831 }
827 832
828 /* Get pointer to tty */ 833 /* Get pointer to tty */
829 tty = edge_port->port->port.tty; 834 tty = tty_port_tty_get(&edge_port->port->port);
830 835
831 /* tell the tty driver that something has changed */ 836 /* tell the tty driver that something has changed */
832 if (tty && edge_port->open) 837 if (tty && edge_port->open)
833 tty_wakeup(tty); 838 tty_wakeup(tty);
839 tty_kref_put(tty);
834 840
835 /* we have completed the command */ 841 /* we have completed the command */
836 edge_port->commandPending = false; 842 edge_port->commandPending = false;
@@ -1932,11 +1938,13 @@ static void process_rcvd_data(struct edgeport_serial *edge_serial,
1932 edge_serial->rxPort]; 1938 edge_serial->rxPort];
1933 edge_port = usb_get_serial_port_data(port); 1939 edge_port = usb_get_serial_port_data(port);
1934 if (edge_port->open) { 1940 if (edge_port->open) {
1935 tty = edge_port->port->port.tty; 1941 tty = tty_port_tty_get(
1942 &edge_port->port->port);
1936 if (tty) { 1943 if (tty) {
1937 dbg("%s - Sending %d bytes to TTY for port %d", 1944 dbg("%s - Sending %d bytes to TTY for port %d",
1938 __func__, rxLen, edge_serial->rxPort); 1945 __func__, rxLen, edge_serial->rxPort);
1939 edge_tty_recv(&edge_serial->serial->dev->dev, tty, buffer, rxLen); 1946 edge_tty_recv(&edge_serial->serial->dev->dev, tty, buffer, rxLen);
1947 tty_kref_put(tty);
1940 } 1948 }
1941 edge_port->icount.rx += rxLen; 1949 edge_port->icount.rx += rxLen;
1942 } 1950 }
@@ -1971,6 +1979,7 @@ static void process_rcvd_status(struct edgeport_serial *edge_serial,
1971{ 1979{
1972 struct usb_serial_port *port; 1980 struct usb_serial_port *port;
1973 struct edgeport_port *edge_port; 1981 struct edgeport_port *edge_port;
1982 struct tty_struct *tty;
1974 __u8 code = edge_serial->rxStatusCode; 1983 __u8 code = edge_serial->rxStatusCode;
1975 1984
1976 /* switch the port pointer to the one being currently talked about */ 1985 /* switch the port pointer to the one being currently talked about */
@@ -2020,10 +2029,12 @@ static void process_rcvd_status(struct edgeport_serial *edge_serial,
2020 2029
2021 /* send the current line settings to the port so we are 2030 /* send the current line settings to the port so we are
2022 in sync with any further termios calls */ 2031 in sync with any further termios calls */
2023 /* FIXME: locking on tty */ 2032 tty = tty_port_tty_get(&edge_port->port->port);
2024 if (edge_port->port->port.tty) 2033 if (tty) {
2025 change_port_settings(edge_port->port->port.tty, 2034 change_port_settings(tty,
2026 edge_port, edge_port->port->port.tty->termios); 2035 edge_port, tty->termios);
2036 tty_kref_put(tty);
2037 }
2027 2038
2028 /* we have completed the open */ 2039 /* we have completed the open */
2029 edge_port->openPending = false; 2040 edge_port->openPending = false;
@@ -2163,10 +2174,14 @@ static void handle_new_lsr(struct edgeport_port *edge_port, __u8 lsrData,
2163 } 2174 }
2164 2175
2165 /* Place LSR data byte into Rx buffer */ 2176 /* Place LSR data byte into Rx buffer */
2166 if (lsrData && edge_port->port->port.tty) 2177 if (lsrData) {
2167 edge_tty_recv(&edge_port->port->dev, 2178 struct tty_struct *tty =
2168 edge_port->port->port.tty, &data, 1); 2179 tty_port_tty_get(&edge_port->port->port);
2169 2180 if (tty) {
2181 edge_tty_recv(&edge_port->port->dev, tty, &data, 1);
2182 tty_kref_put(tty);
2183 }
2184 }
2170 /* update input line counters */ 2185 /* update input line counters */
2171 icount = &edge_port->icount; 2186 icount = &edge_port->icount;
2172 if (newLsr & LSR_BREAK) 2187 if (newLsr & LSR_BREAK)
diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c
index cb4c54316cf5..541dd8e6e7a2 100644
--- a/drivers/usb/serial/io_ti.c
+++ b/drivers/usb/serial/io_ti.c
@@ -572,7 +572,7 @@ static void chase_port(struct edgeport_port *port, unsigned long timeout,
572 int flush) 572 int flush)
573{ 573{
574 int baud_rate; 574 int baud_rate;
575 struct tty_struct *tty = port->port->port.tty; 575 struct tty_struct *tty = tty_port_tty_get(&port->port->port);
576 wait_queue_t wait; 576 wait_queue_t wait;
577 unsigned long flags; 577 unsigned long flags;
578 578
@@ -599,6 +599,7 @@ static void chase_port(struct edgeport_port *port, unsigned long timeout,
599 if (flush) 599 if (flush)
600 edge_buf_clear(port->ep_out_buf); 600 edge_buf_clear(port->ep_out_buf);
601 spin_unlock_irqrestore(&port->ep_lock, flags); 601 spin_unlock_irqrestore(&port->ep_lock, flags);
602 tty_kref_put(tty);
602 603
603 /* wait for data to drain from the device */ 604 /* wait for data to drain from the device */
604 timeout += jiffies; 605 timeout += jiffies;
@@ -1554,7 +1555,7 @@ static void handle_new_msr(struct edgeport_port *edge_port, __u8 msr)
1554 /* Save the new modem status */ 1555 /* Save the new modem status */
1555 edge_port->shadow_msr = msr & 0xf0; 1556 edge_port->shadow_msr = msr & 0xf0;
1556 1557
1557 tty = edge_port->port->port.tty; 1558 tty = tty_port_tty_get(&edge_port->port->port);
1558 /* handle CTS flow control */ 1559 /* handle CTS flow control */
1559 if (tty && C_CRTSCTS(tty)) { 1560 if (tty && C_CRTSCTS(tty)) {
1560 if (msr & EDGEPORT_MSR_CTS) { 1561 if (msr & EDGEPORT_MSR_CTS) {
@@ -1564,6 +1565,7 @@ static void handle_new_msr(struct edgeport_port *edge_port, __u8 msr)
1564 tty->hw_stopped = 1; 1565 tty->hw_stopped = 1;
1565 } 1566 }
1566 } 1567 }
1568 tty_kref_put(tty);
1567 1569
1568 return; 1570 return;
1569} 1571}
@@ -1574,6 +1576,7 @@ static void handle_new_lsr(struct edgeport_port *edge_port, int lsr_data,
1574 struct async_icount *icount; 1576 struct async_icount *icount;
1575 __u8 new_lsr = (__u8)(lsr & (__u8)(LSR_OVER_ERR | LSR_PAR_ERR | 1577 __u8 new_lsr = (__u8)(lsr & (__u8)(LSR_OVER_ERR | LSR_PAR_ERR |
1576 LSR_FRM_ERR | LSR_BREAK)); 1578 LSR_FRM_ERR | LSR_BREAK));
1579 struct tty_struct *tty;
1577 1580
1578 dbg("%s - %02x", __func__, new_lsr); 1581 dbg("%s - %02x", __func__, new_lsr);
1579 1582
@@ -1587,8 +1590,13 @@ static void handle_new_lsr(struct edgeport_port *edge_port, int lsr_data,
1587 new_lsr &= (__u8)(LSR_OVER_ERR | LSR_BREAK); 1590 new_lsr &= (__u8)(LSR_OVER_ERR | LSR_BREAK);
1588 1591
1589 /* Place LSR data byte into Rx buffer */ 1592 /* Place LSR data byte into Rx buffer */
1590 if (lsr_data && edge_port->port->port.tty) 1593 if (lsr_data) {
1591 edge_tty_recv(&edge_port->port->dev, edge_port->port->port.tty, &data, 1); 1594 tty = tty_port_tty_get(&edge_port->port->port);
1595 if (tty) {
1596 edge_tty_recv(&edge_port->port->dev, tty, &data, 1);
1597 tty_kref_put(tty);
1598 }
1599 }
1592 1600
1593 /* update input line counters */ 1601 /* update input line counters */
1594 icount = &edge_port->icount; 1602 icount = &edge_port->icount;
@@ -1749,7 +1757,7 @@ static void edge_bulk_in_callback(struct urb *urb)
1749 ++data; 1757 ++data;
1750 } 1758 }
1751 1759
1752 tty = edge_port->port->port.tty; 1760 tty = tty_port_tty_get(&edge_port->port->port);
1753 if (tty && urb->actual_length) { 1761 if (tty && urb->actual_length) {
1754 usb_serial_debug_data(debug, &edge_port->port->dev, 1762 usb_serial_debug_data(debug, &edge_port->port->dev,
1755 __func__, urb->actual_length, data); 1763 __func__, urb->actual_length, data);
@@ -1761,6 +1769,7 @@ static void edge_bulk_in_callback(struct urb *urb)
1761 urb->actual_length); 1769 urb->actual_length);
1762 edge_port->icount.rx += urb->actual_length; 1770 edge_port->icount.rx += urb->actual_length;
1763 } 1771 }
1772 tty_kref_put(tty);
1764 1773
1765exit: 1774exit:
1766 /* continue read unless stopped */ 1775 /* continue read unless stopped */
@@ -1796,6 +1805,7 @@ static void edge_bulk_out_callback(struct urb *urb)
1796 struct usb_serial_port *port = urb->context; 1805 struct usb_serial_port *port = urb->context;
1797 struct edgeport_port *edge_port = usb_get_serial_port_data(port); 1806 struct edgeport_port *edge_port = usb_get_serial_port_data(port);
1798 int status = urb->status; 1807 int status = urb->status;
1808 struct tty_struct *tty;
1799 1809
1800 dbg("%s - port %d", __func__, port->number); 1810 dbg("%s - port %d", __func__, port->number);
1801 1811
@@ -1818,7 +1828,9 @@ static void edge_bulk_out_callback(struct urb *urb)
1818 } 1828 }
1819 1829
1820 /* send any buffered data */ 1830 /* send any buffered data */
1821 edge_send(port->port.tty); 1831 tty = tty_port_tty_get(&port->port);
1832 edge_send(tty);
1833 tty_kref_put(tty);
1822} 1834}
1823 1835
1824static int edge_open(struct tty_struct *tty, 1836static int edge_open(struct tty_struct *tty,
@@ -1876,7 +1888,7 @@ static int edge_open(struct tty_struct *tty,
1876 1888
1877 /* set up the port settings */ 1889 /* set up the port settings */
1878 if (tty) 1890 if (tty)
1879 edge_set_termios(tty, port, port->port.tty->termios); 1891 edge_set_termios(tty, port, tty->termios);
1880 1892
1881 /* open up the port */ 1893 /* open up the port */
1882 1894
diff --git a/drivers/usb/serial/ipaq.c b/drivers/usb/serial/ipaq.c
index cd9a2e138c8b..2affa9c118b2 100644
--- a/drivers/usb/serial/ipaq.c
+++ b/drivers/usb/serial/ipaq.c
@@ -764,13 +764,14 @@ static void ipaq_read_bulk_callback(struct urb *urb)
764 usb_serial_debug_data(debug, &port->dev, __func__, 764 usb_serial_debug_data(debug, &port->dev, __func__,
765 urb->actual_length, data); 765 urb->actual_length, data);
766 766
767 tty = port->port.tty; 767 tty = tty_port_tty_get(&port->port);
768 if (tty && urb->actual_length) { 768 if (tty && urb->actual_length) {
769 tty_buffer_request_room(tty, urb->actual_length); 769 tty_buffer_request_room(tty, urb->actual_length);
770 tty_insert_flip_string(tty, data, urb->actual_length); 770 tty_insert_flip_string(tty, data, urb->actual_length);
771 tty_flip_buffer_push(tty); 771 tty_flip_buffer_push(tty);
772 bytes_in += urb->actual_length; 772 bytes_in += urb->actual_length;
773 } 773 }
774 tty_kref_put(tty);
774 775
775 /* Continue trying to always read */ 776 /* Continue trying to always read */
776 usb_fill_bulk_urb(port->read_urb, port->serial->dev, 777 usb_fill_bulk_urb(port->read_urb, port->serial->dev,
diff --git a/drivers/usb/serial/ipw.c b/drivers/usb/serial/ipw.c
index a842025b9b57..480cac27d646 100644
--- a/drivers/usb/serial/ipw.c
+++ b/drivers/usb/serial/ipw.c
@@ -170,12 +170,13 @@ static void ipw_read_bulk_callback(struct urb *urb)
170 usb_serial_debug_data(debug, &port->dev, __func__, 170 usb_serial_debug_data(debug, &port->dev, __func__,
171 urb->actual_length, data); 171 urb->actual_length, data);
172 172
173 tty = port->port.tty; 173 tty = tty_port_tty_get(&port->port);
174 if (tty && urb->actual_length) { 174 if (tty && urb->actual_length) {
175 tty_buffer_request_room(tty, urb->actual_length); 175 tty_buffer_request_room(tty, urb->actual_length);
176 tty_insert_flip_string(tty, data, urb->actual_length); 176 tty_insert_flip_string(tty, data, urb->actual_length);
177 tty_flip_buffer_push(tty); 177 tty_flip_buffer_push(tty);
178 } 178 }
179 tty_kref_put(tty);
179 180
180 /* Continue trying to always read */ 181 /* Continue trying to always read */
181 usb_fill_bulk_urb(port->read_urb, port->serial->dev, 182 usb_fill_bulk_urb(port->read_urb, port->serial->dev,
diff --git a/drivers/usb/serial/ir-usb.c b/drivers/usb/serial/ir-usb.c
index e59155c6607d..45d4043e04ab 100644
--- a/drivers/usb/serial/ir-usb.c
+++ b/drivers/usb/serial/ir-usb.c
@@ -465,11 +465,12 @@ static void ir_read_bulk_callback(struct urb *urb)
465 ir_baud = *data & 0x0f; 465 ir_baud = *data & 0x0f;
466 usb_serial_debug_data(debug, &port->dev, __func__, 466 usb_serial_debug_data(debug, &port->dev, __func__,
467 urb->actual_length, data); 467 urb->actual_length, data);
468 tty = port->port.tty; 468 tty = tty_port_tty_get(&port->port);
469 if (tty_buffer_request_room(tty, urb->actual_length - 1)) { 469 if (tty_buffer_request_room(tty, urb->actual_length - 1)) {
470 tty_insert_flip_string(tty, data+1, urb->actual_length - 1); 470 tty_insert_flip_string(tty, data+1, urb->actual_length - 1);
471 tty_flip_buffer_push(tty); 471 tty_flip_buffer_push(tty);
472 } 472 }
473 tty_kref_put(tty);
473 474
474 /* 475 /*
475 * No break here. 476 * No break here.
diff --git a/drivers/usb/serial/iuu_phoenix.c b/drivers/usb/serial/iuu_phoenix.c
index ddff37fa6339..53710aa7eadd 100644
--- a/drivers/usb/serial/iuu_phoenix.c
+++ b/drivers/usb/serial/iuu_phoenix.c
@@ -629,13 +629,14 @@ static void read_buf_callback(struct urb *urb)
629 } 629 }
630 630
631 dbg("%s - %i chars to write", __func__, urb->actual_length); 631 dbg("%s - %i chars to write", __func__, urb->actual_length);
632 tty = port->port.tty; 632 tty = tty_port_tty_get(&port->port);
633 if (data == NULL) 633 if (data == NULL)
634 dbg("%s - data is NULL !!!", __func__); 634 dbg("%s - data is NULL !!!", __func__);
635 if (tty && urb->actual_length && data) { 635 if (tty && urb->actual_length && data) {
636 tty_insert_flip_string(tty, data, urb->actual_length); 636 tty_insert_flip_string(tty, data, urb->actual_length);
637 tty_flip_buffer_push(tty); 637 tty_flip_buffer_push(tty);
638 } 638 }
639 tty_kref_put(tty);
639 iuu_led_activity_on(urb); 640 iuu_led_activity_on(urb);
640} 641}
641 642
diff --git a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c
index 704716f6f6d3..15447af48691 100644
--- a/drivers/usb/serial/keyspan.c
+++ b/drivers/usb/serial/keyspan.c
@@ -430,7 +430,7 @@ static void usa26_indat_callback(struct urb *urb)
430 } 430 }
431 431
432 port = urb->context; 432 port = urb->context;
433 tty = port->port.tty; 433 tty = tty_port_tty_get(&port->port);
434 if (tty && urb->actual_length) { 434 if (tty && urb->actual_length) {
435 /* 0x80 bit is error flag */ 435 /* 0x80 bit is error flag */
436 if ((data[0] & 0x80) == 0) { 436 if ((data[0] & 0x80) == 0) {
@@ -459,6 +459,7 @@ static void usa26_indat_callback(struct urb *urb)
459 } 459 }
460 tty_flip_buffer_push(tty); 460 tty_flip_buffer_push(tty);
461 } 461 }
462 tty_kref_put(tty);
462 463
463 /* Resubmit urb so we continue receiving */ 464 /* Resubmit urb so we continue receiving */
464 urb->dev = port->serial->dev; 465 urb->dev = port->serial->dev;
@@ -513,6 +514,7 @@ static void usa26_instat_callback(struct urb *urb)
513 struct usb_serial *serial; 514 struct usb_serial *serial;
514 struct usb_serial_port *port; 515 struct usb_serial_port *port;
515 struct keyspan_port_private *p_priv; 516 struct keyspan_port_private *p_priv;
517 struct tty_struct *tty;
516 int old_dcd_state, err; 518 int old_dcd_state, err;
517 int status = urb->status; 519 int status = urb->status;
518 520
@@ -553,12 +555,11 @@ static void usa26_instat_callback(struct urb *urb)
553 p_priv->dcd_state = ((msg->gpia_dcd) ? 1 : 0); 555 p_priv->dcd_state = ((msg->gpia_dcd) ? 1 : 0);
554 p_priv->ri_state = ((msg->ri) ? 1 : 0); 556 p_priv->ri_state = ((msg->ri) ? 1 : 0);
555 557
556 if (port->port.tty && !C_CLOCAL(port->port.tty) 558 if (old_dcd_state != p_priv->dcd_state) {
557 && old_dcd_state != p_priv->dcd_state) { 559 tty = tty_port_tty_get(&port->port);
558 if (old_dcd_state) 560 if (tty && !C_CLOCAL(tty))
559 tty_hangup(port->port.tty); 561 tty_hangup(tty);
560 /* else */ 562 tty_kref_put(tty);
561 /* wake_up_interruptible(&p_priv->open_wait); */
562 } 563 }
563 564
564 /* Resubmit urb so we continue receiving */ 565 /* Resubmit urb so we continue receiving */
@@ -604,11 +605,12 @@ static void usa28_indat_callback(struct urb *urb)
604 p_priv = usb_get_serial_port_data(port); 605 p_priv = usb_get_serial_port_data(port);
605 data = urb->transfer_buffer; 606 data = urb->transfer_buffer;
606 607
607 tty = port->port.tty; 608 tty =tty_port_tty_get(&port->port);
608 if (urb->actual_length) { 609 if (tty && urb->actual_length) {
609 tty_insert_flip_string(tty, data, urb->actual_length); 610 tty_insert_flip_string(tty, data, urb->actual_length);
610 tty_flip_buffer_push(tty); 611 tty_flip_buffer_push(tty);
611 } 612 }
613 tty_kref_put(tty);
612 614
613 /* Resubmit urb so we continue receiving */ 615 /* Resubmit urb so we continue receiving */
614 urb->dev = port->serial->dev; 616 urb->dev = port->serial->dev;
@@ -652,6 +654,7 @@ static void usa28_instat_callback(struct urb *urb)
652 struct usb_serial *serial; 654 struct usb_serial *serial;
653 struct usb_serial_port *port; 655 struct usb_serial_port *port;
654 struct keyspan_port_private *p_priv; 656 struct keyspan_port_private *p_priv;
657 struct tty_struct *tty;
655 int old_dcd_state; 658 int old_dcd_state;
656 int status = urb->status; 659 int status = urb->status;
657 660
@@ -689,12 +692,11 @@ static void usa28_instat_callback(struct urb *urb)
689 p_priv->dcd_state = ((msg->dcd) ? 1 : 0); 692 p_priv->dcd_state = ((msg->dcd) ? 1 : 0);
690 p_priv->ri_state = ((msg->ri) ? 1 : 0); 693 p_priv->ri_state = ((msg->ri) ? 1 : 0);
691 694
692 if (port->port.tty && !C_CLOCAL(port->port.tty) 695 if( old_dcd_state != p_priv->dcd_state && old_dcd_state) {
693 && old_dcd_state != p_priv->dcd_state) { 696 tty = tty_port_tty_get(&port->port);
694 if (old_dcd_state) 697 if (tty && !C_CLOCAL(tty))
695 tty_hangup(port->port.tty); 698 tty_hangup(tty);
696 /* else */ 699 tty_kref_put(tty);
697 /* wake_up_interruptible(&p_priv->open_wait); */
698 } 700 }
699 701
700 /* Resubmit urb so we continue receiving */ 702 /* Resubmit urb so we continue receiving */
@@ -785,12 +787,11 @@ static void usa49_instat_callback(struct urb *urb)
785 p_priv->dcd_state = ((msg->dcd) ? 1 : 0); 787 p_priv->dcd_state = ((msg->dcd) ? 1 : 0);
786 p_priv->ri_state = ((msg->ri) ? 1 : 0); 788 p_priv->ri_state = ((msg->ri) ? 1 : 0);
787 789
788 if (port->port.tty && !C_CLOCAL(port->port.tty) 790 if (old_dcd_state != p_priv->dcd_state && old_dcd_state) {
789 && old_dcd_state != p_priv->dcd_state) { 791 struct tty_struct *tty = tty_port_tty_get(&port->port);
790 if (old_dcd_state) 792 if (tty && !C_CLOCAL(tty))
791 tty_hangup(port->port.tty); 793 tty_hangup(tty);
792 /* else */ 794 tty_kref_put(tty);
793 /* wake_up_interruptible(&p_priv->open_wait); */
794 } 795 }
795 796
796 /* Resubmit urb so we continue receiving */ 797 /* Resubmit urb so we continue receiving */
@@ -827,7 +828,7 @@ static void usa49_indat_callback(struct urb *urb)
827 } 828 }
828 829
829 port = urb->context; 830 port = urb->context;
830 tty = port->port.tty; 831 tty = tty_port_tty_get(&port->port);
831 if (tty && urb->actual_length) { 832 if (tty && urb->actual_length) {
832 /* 0x80 bit is error flag */ 833 /* 0x80 bit is error flag */
833 if ((data[0] & 0x80) == 0) { 834 if ((data[0] & 0x80) == 0) {
@@ -850,6 +851,7 @@ static void usa49_indat_callback(struct urb *urb)
850 } 851 }
851 tty_flip_buffer_push(tty); 852 tty_flip_buffer_push(tty);
852 } 853 }
854 tty_kref_put(tty);
853 855
854 /* Resubmit urb so we continue receiving */ 856 /* Resubmit urb so we continue receiving */
855 urb->dev = port->serial->dev; 857 urb->dev = port->serial->dev;
@@ -893,7 +895,7 @@ static void usa49wg_indat_callback(struct urb *urb)
893 return; 895 return;
894 } 896 }
895 port = serial->port[data[i++]]; 897 port = serial->port[data[i++]];
896 tty = port->port.tty; 898 tty = tty_port_tty_get(&port->port);
897 len = data[i++]; 899 len = data[i++];
898 900
899 /* 0x80 bit is error flag */ 901 /* 0x80 bit is error flag */
@@ -927,6 +929,7 @@ static void usa49wg_indat_callback(struct urb *urb)
927 } 929 }
928 if (port->port.count) 930 if (port->port.count)
929 tty_flip_buffer_push(tty); 931 tty_flip_buffer_push(tty);
932 tty_kref_put(tty);
930 } 933 }
931 } 934 }
932 935
@@ -967,8 +970,8 @@ static void usa90_indat_callback(struct urb *urb)
967 port = urb->context; 970 port = urb->context;
968 p_priv = usb_get_serial_port_data(port); 971 p_priv = usb_get_serial_port_data(port);
969 972
970 tty = port->port.tty;
971 if (urb->actual_length) { 973 if (urb->actual_length) {
974 tty = tty_port_tty_get(&port->port);
972 /* if current mode is DMA, looks like usa28 format 975 /* if current mode is DMA, looks like usa28 format
973 otherwise looks like usa26 data format */ 976 otherwise looks like usa26 data format */
974 977
@@ -1004,6 +1007,7 @@ static void usa90_indat_callback(struct urb *urb)
1004 } 1007 }
1005 } 1008 }
1006 tty_flip_buffer_push(tty); 1009 tty_flip_buffer_push(tty);
1010 tty_kref_put(tty);
1007 } 1011 }
1008 1012
1009 /* Resubmit urb so we continue receiving */ 1013 /* Resubmit urb so we continue receiving */
@@ -1025,6 +1029,7 @@ static void usa90_instat_callback(struct urb *urb)
1025 struct usb_serial *serial; 1029 struct usb_serial *serial;
1026 struct usb_serial_port *port; 1030 struct usb_serial_port *port;
1027 struct keyspan_port_private *p_priv; 1031 struct keyspan_port_private *p_priv;
1032 struct tty_struct *tty;
1028 int old_dcd_state, err; 1033 int old_dcd_state, err;
1029 int status = urb->status; 1034 int status = urb->status;
1030 1035
@@ -1053,12 +1058,11 @@ static void usa90_instat_callback(struct urb *urb)
1053 p_priv->dcd_state = ((msg->dcd) ? 1 : 0); 1058 p_priv->dcd_state = ((msg->dcd) ? 1 : 0);
1054 p_priv->ri_state = ((msg->ri) ? 1 : 0); 1059 p_priv->ri_state = ((msg->ri) ? 1 : 0);
1055 1060
1056 if (port->port.tty && !C_CLOCAL(port->port.tty) 1061 if (old_dcd_state != p_priv->dcd_state && old_dcd_state) {
1057 && old_dcd_state != p_priv->dcd_state) { 1062 tty = tty_port_tty_get(&port->port);
1058 if (old_dcd_state) 1063 if (tty && !C_CLOCAL(tty))
1059 tty_hangup(port->port.tty); 1064 tty_hangup(tty);
1060 /* else */ 1065 tty_kref_put(tty);
1061 /* wake_up_interruptible(&p_priv->open_wait); */
1062 } 1066 }
1063 1067
1064 /* Resubmit urb so we continue receiving */ 1068 /* Resubmit urb so we continue receiving */
@@ -1130,12 +1134,11 @@ static void usa67_instat_callback(struct urb *urb)
1130 p_priv->cts_state = ((msg->hskia_cts) ? 1 : 0); 1134 p_priv->cts_state = ((msg->hskia_cts) ? 1 : 0);
1131 p_priv->dcd_state = ((msg->gpia_dcd) ? 1 : 0); 1135 p_priv->dcd_state = ((msg->gpia_dcd) ? 1 : 0);
1132 1136
1133 if (port->port.tty && !C_CLOCAL(port->port.tty) 1137 if (old_dcd_state != p_priv->dcd_state && old_dcd_state) {
1134 && old_dcd_state != p_priv->dcd_state) { 1138 struct tty_struct *tty = tty_port_tty_get(&port->port);
1135 if (old_dcd_state) 1139 if (tty && !C_CLOCAL(tty))
1136 tty_hangup(port->port.tty); 1140 tty_hangup(tty);
1137 /* else */ 1141 tty_kref_put(tty);
1138 /* wake_up_interruptible(&p_priv->open_wait); */
1139 } 1142 }
1140 1143
1141 /* Resubmit urb so we continue receiving */ 1144 /* Resubmit urb so we continue receiving */
@@ -1332,7 +1335,7 @@ static void keyspan_close(struct tty_struct *tty,
1332 stop_urb(p_priv->out_urbs[i]); 1335 stop_urb(p_priv->out_urbs[i]);
1333 } 1336 }
1334 } 1337 }
1335 port->port.tty = NULL; 1338 tty_port_tty_set(&port->port, NULL);
1336} 1339}
1337 1340
1338/* download the firmware to a pre-renumeration device */ 1341/* download the firmware to a pre-renumeration device */
diff --git a/drivers/usb/serial/keyspan_pda.c b/drivers/usb/serial/keyspan_pda.c
index 040040a267d9..99e9a14c5bf6 100644
--- a/drivers/usb/serial/keyspan_pda.c
+++ b/drivers/usb/serial/keyspan_pda.c
@@ -172,8 +172,9 @@ static void keyspan_pda_wakeup_write(struct work_struct *work)
172 struct keyspan_pda_private *priv = 172 struct keyspan_pda_private *priv =
173 container_of(work, struct keyspan_pda_private, wakeup_work); 173 container_of(work, struct keyspan_pda_private, wakeup_work);
174 struct usb_serial_port *port = priv->port; 174 struct usb_serial_port *port = priv->port;
175 175 struct tty_struct *tty = tty_port_tty_get(&port->port);
176 tty_wakeup(port->port.tty); 176 tty_wakeup(tty);
177 tty_kref_put(tty);
177} 178}
178 179
179static void keyspan_pda_request_unthrottle(struct work_struct *work) 180static void keyspan_pda_request_unthrottle(struct work_struct *work)
@@ -205,7 +206,7 @@ static void keyspan_pda_request_unthrottle(struct work_struct *work)
205static void keyspan_pda_rx_interrupt(struct urb *urb) 206static void keyspan_pda_rx_interrupt(struct urb *urb)
206{ 207{
207 struct usb_serial_port *port = urb->context; 208 struct usb_serial_port *port = urb->context;
208 struct tty_struct *tty = port->port.tty; 209 struct tty_struct *tty = tty_port_tty_get(&port->port);
209 unsigned char *data = urb->transfer_buffer; 210 unsigned char *data = urb->transfer_buffer;
210 int retval; 211 int retval;
211 int status = urb->status; 212 int status = urb->status;
@@ -222,7 +223,7 @@ static void keyspan_pda_rx_interrupt(struct urb *urb)
222 /* this urb is terminated, clean up */ 223 /* this urb is terminated, clean up */
223 dbg("%s - urb shutting down with status: %d", 224 dbg("%s - urb shutting down with status: %d",
224 __func__, status); 225 __func__, status);
225 return; 226 goto out;
226 default: 227 default:
227 dbg("%s - nonzero urb status received: %d", 228 dbg("%s - nonzero urb status received: %d",
228 __func__, status); 229 __func__, status);
@@ -261,8 +262,11 @@ static void keyspan_pda_rx_interrupt(struct urb *urb)
261exit: 262exit:
262 retval = usb_submit_urb(urb, GFP_ATOMIC); 263 retval = usb_submit_urb(urb, GFP_ATOMIC);
263 if (retval) 264 if (retval)
264 err("%s - usb_submit_urb failed with result %d", 265 dev_err(&port->dev,
265 __func__, retval); 266 "%s - usb_submit_urb failed with result %d",
267 __func__, retval);
268out:
269 tty_kref_put(tty);
266} 270}
267 271
268 272
diff --git a/drivers/usb/serial/kl5kusb105.c b/drivers/usb/serial/kl5kusb105.c
index b84dddc71124..ff3a07f5102f 100644
--- a/drivers/usb/serial/kl5kusb105.c
+++ b/drivers/usb/serial/kl5kusb105.c
@@ -658,7 +658,7 @@ static void klsi_105_read_bulk_callback(struct urb *urb)
658 } else { 658 } else {
659 int bytes_sent = ((__u8 *) data)[0] + 659 int bytes_sent = ((__u8 *) data)[0] +
660 ((unsigned int) ((__u8 *) data)[1] << 8); 660 ((unsigned int) ((__u8 *) data)[1] << 8);
661 tty = port->port.tty; 661 tty = tty_port_tty_get(&port->port);
662 /* we should immediately resubmit the URB, before attempting 662 /* we should immediately resubmit the URB, before attempting
663 * to pass the data on to the tty layer. But that needs locking 663 * to pass the data on to the tty layer. But that needs locking
664 * against re-entry an then mixed-up data because of 664 * against re-entry an then mixed-up data because of
@@ -679,6 +679,7 @@ static void klsi_105_read_bulk_callback(struct urb *urb)
679 tty_buffer_request_room(tty, bytes_sent); 679 tty_buffer_request_room(tty, bytes_sent);
680 tty_insert_flip_string(tty, data + 2, bytes_sent); 680 tty_insert_flip_string(tty, data + 2, bytes_sent);
681 tty_flip_buffer_push(tty); 681 tty_flip_buffer_push(tty);
682 tty_kref_put(tty);
682 683
683 /* again lockless, but debug info only */ 684 /* again lockless, but debug info only */
684 priv->bytes_in += bytes_sent; 685 priv->bytes_in += bytes_sent;
diff --git a/drivers/usb/serial/kobil_sct.c b/drivers/usb/serial/kobil_sct.c
index deba28ec77e8..cfcf37c2b957 100644
--- a/drivers/usb/serial/kobil_sct.c
+++ b/drivers/usb/serial/kobil_sct.c
@@ -383,7 +383,7 @@ static void kobil_read_int_callback(struct urb *urb)
383 return; 383 return;
384 } 384 }
385 385
386 tty = port->port.tty; 386 tty = tty_port_tty_get(&port->port);
387 if (urb->actual_length) { 387 if (urb->actual_length) {
388 388
389 /* BEGIN DEBUG */ 389 /* BEGIN DEBUG */
@@ -405,6 +405,7 @@ static void kobil_read_int_callback(struct urb *urb)
405 tty_insert_flip_string(tty, data, urb->actual_length); 405 tty_insert_flip_string(tty, data, urb->actual_length);
406 tty_flip_buffer_push(tty); 406 tty_flip_buffer_push(tty);
407 } 407 }
408 tty_kref_put(tty);
408 /* someone sets the dev to 0 if the close method has been called */ 409 /* someone sets the dev to 0 if the close method has been called */
409 port->interrupt_in_urb->dev = port->serial->dev; 410 port->interrupt_in_urb->dev = port->serial->dev;
410 411
diff --git a/drivers/usb/serial/mct_u232.c b/drivers/usb/serial/mct_u232.c
index 0ded8bd6ec85..9b2cef81cde0 100644
--- a/drivers/usb/serial/mct_u232.c
+++ b/drivers/usb/serial/mct_u232.c
@@ -563,10 +563,11 @@ static void mct_u232_read_int_callback(struct urb *urb)
563 * Work-a-round: handle the 'usual' bulk-in pipe here 563 * Work-a-round: handle the 'usual' bulk-in pipe here
564 */ 564 */
565 if (urb->transfer_buffer_length > 2) { 565 if (urb->transfer_buffer_length > 2) {
566 tty = port->port.tty; 566 tty = tty_port_tty_get(&port->port);
567 if (urb->actual_length) { 567 if (urb->actual_length) {
568 tty_insert_flip_string(tty, data, urb->actual_length); 568 tty_insert_flip_string(tty, data, urb->actual_length);
569 tty_flip_buffer_push(tty); 569 tty_flip_buffer_push(tty);
570 tty_kref_put(tty);
570 } 571 }
571 goto exit; 572 goto exit;
572 } 573 }
@@ -591,7 +592,7 @@ static void mct_u232_read_int_callback(struct urb *urb)
591 * to look in to this before committing any code. 592 * to look in to this before committing any code.
592 */ 593 */
593 if (priv->last_lsr & MCT_U232_LSR_ERR) { 594 if (priv->last_lsr & MCT_U232_LSR_ERR) {
594 tty = port->port.tty; 595 tty = tty_port_tty_get(&port->port);
595 /* Overrun Error */ 596 /* Overrun Error */
596 if (priv->last_lsr & MCT_U232_LSR_OE) { 597 if (priv->last_lsr & MCT_U232_LSR_OE) {
597 } 598 }
@@ -604,6 +605,7 @@ static void mct_u232_read_int_callback(struct urb *urb)
604 /* Break Indicator */ 605 /* Break Indicator */
605 if (priv->last_lsr & MCT_U232_LSR_BI) { 606 if (priv->last_lsr & MCT_U232_LSR_BI) {
606 } 607 }
608 tty_kref_put(tty);
607 } 609 }
608#endif 610#endif
609 spin_unlock_irqrestore(&priv->lock, flags); 611 spin_unlock_irqrestore(&priv->lock, flags);
diff --git a/drivers/usb/serial/mos7720.c b/drivers/usb/serial/mos7720.c
index 7c4917d77c0a..7b538caec37f 100644
--- a/drivers/usb/serial/mos7720.c
+++ b/drivers/usb/serial/mos7720.c
@@ -216,12 +216,13 @@ static void mos7720_bulk_in_callback(struct urb *urb)
216 216
217 data = urb->transfer_buffer; 217 data = urb->transfer_buffer;
218 218
219 tty = port->port.tty; 219 tty = tty_port_tty_get(&port->port);
220 if (tty && urb->actual_length) { 220 if (tty && urb->actual_length) {
221 tty_buffer_request_room(tty, urb->actual_length); 221 tty_buffer_request_room(tty, urb->actual_length);
222 tty_insert_flip_string(tty, data, urb->actual_length); 222 tty_insert_flip_string(tty, data, urb->actual_length);
223 tty_flip_buffer_push(tty); 223 tty_flip_buffer_push(tty);
224 } 224 }
225 tty_kref_put(tty);
225 226
226 if (!port->read_urb) { 227 if (!port->read_urb) {
227 dbg("URB KILLED !!!"); 228 dbg("URB KILLED !!!");
@@ -262,10 +263,11 @@ static void mos7720_bulk_out_data_callback(struct urb *urb)
262 263
263 dbg("Entering ........."); 264 dbg("Entering .........");
264 265
265 tty = mos7720_port->port->port.tty; 266 tty = tty_port_tty_get(&mos7720_port->port->port);
266 267
267 if (tty && mos7720_port->open) 268 if (tty && mos7720_port->open)
268 tty_wakeup(tty); 269 tty_wakeup(tty);
270 tty_kref_put(tty);
269} 271}
270 272
271/* 273/*
@@ -1267,29 +1269,6 @@ static int get_lsr_info(struct tty_struct *tty,
1267 return 0; 1269 return 0;
1268} 1270}
1269 1271
1270/*
1271 * get_number_bytes_avail - get number of bytes available
1272 *
1273 * Purpose: Let user call ioctl to get the count of number of bytes available.
1274 */
1275static int get_number_bytes_avail(struct moschip_port *mos7720_port,
1276 unsigned int __user *value)
1277{
1278 unsigned int result = 0;
1279 struct tty_struct *tty = mos7720_port->port->port.tty;
1280
1281 if (!tty)
1282 return -ENOIOCTLCMD;
1283
1284 result = tty->read_cnt;
1285
1286 dbg("%s(%d) = %d", __func__, mos7720_port->port->number, result);
1287 if (copy_to_user(value, &result, sizeof(int)))
1288 return -EFAULT;
1289
1290 return -ENOIOCTLCMD;
1291}
1292
1293static int set_modem_info(struct moschip_port *mos7720_port, unsigned int cmd, 1272static int set_modem_info(struct moschip_port *mos7720_port, unsigned int cmd,
1294 unsigned int __user *value) 1273 unsigned int __user *value)
1295{ 1274{
@@ -1409,13 +1388,6 @@ static int mos7720_ioctl(struct tty_struct *tty, struct file *file,
1409 dbg("%s - port %d, cmd = 0x%x", __func__, port->number, cmd); 1388 dbg("%s - port %d, cmd = 0x%x", __func__, port->number, cmd);
1410 1389
1411 switch (cmd) { 1390 switch (cmd) {
1412 case TIOCINQ:
1413 /* return number of bytes available */
1414 dbg("%s (%d) TIOCINQ", __func__, port->number);
1415 return get_number_bytes_avail(mos7720_port,
1416 (unsigned int __user *)arg);
1417 break;
1418
1419 case TIOCSERGETLSR: 1391 case TIOCSERGETLSR:
1420 dbg("%s (%d) TIOCSERGETLSR", __func__, port->number); 1392 dbg("%s (%d) TIOCSERGETLSR", __func__, port->number);
1421 return get_lsr_info(tty, mos7720_port, 1393 return get_lsr_info(tty, mos7720_port,
diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c
index 09d82062b973..60543d79ef56 100644
--- a/drivers/usb/serial/mos7840.c
+++ b/drivers/usb/serial/mos7840.c
@@ -709,12 +709,13 @@ static void mos7840_bulk_in_callback(struct urb *urb)
709 dbg("%s", "Entering ........... \n"); 709 dbg("%s", "Entering ........... \n");
710 710
711 if (urb->actual_length) { 711 if (urb->actual_length) {
712 tty = mos7840_port->port->port.tty; 712 tty = tty_port_tty_get(&mos7840_port->port->port);
713 if (tty) { 713 if (tty) {
714 tty_buffer_request_room(tty, urb->actual_length); 714 tty_buffer_request_room(tty, urb->actual_length);
715 tty_insert_flip_string(tty, data, urb->actual_length); 715 tty_insert_flip_string(tty, data, urb->actual_length);
716 dbg(" %s \n", data); 716 dbg(" %s \n", data);
717 tty_flip_buffer_push(tty); 717 tty_flip_buffer_push(tty);
718 tty_kref_put(tty);
718 } 719 }
719 mos7840_port->icount.rx += urb->actual_length; 720 mos7840_port->icount.rx += urb->actual_length;
720 smp_wmb(); 721 smp_wmb();
@@ -773,10 +774,10 @@ static void mos7840_bulk_out_data_callback(struct urb *urb)
773 774
774 dbg("%s \n", "Entering ........."); 775 dbg("%s \n", "Entering .........");
775 776
776 tty = mos7840_port->port->port.tty; 777 tty = tty_port_tty_get(&mos7840_port->port->port);
777
778 if (tty && mos7840_port->open) 778 if (tty && mos7840_port->open)
779 tty_wakeup(tty); 779 tty_wakeup(tty);
780 tty_kref_put(tty);
780 781
781} 782}
782 783
diff --git a/drivers/usb/serial/navman.c b/drivers/usb/serial/navman.c
index d6736531a0fa..bcdcbb822705 100644
--- a/drivers/usb/serial/navman.c
+++ b/drivers/usb/serial/navman.c
@@ -64,12 +64,13 @@ static void navman_read_int_callback(struct urb *urb)
64 usb_serial_debug_data(debug, &port->dev, __func__, 64 usb_serial_debug_data(debug, &port->dev, __func__,
65 urb->actual_length, data); 65 urb->actual_length, data);
66 66
67 tty = port->port.tty; 67 tty = tty_port_tty_get(&port->port);
68 if (tty && urb->actual_length) { 68 if (tty && urb->actual_length) {
69 tty_buffer_request_room(tty, urb->actual_length); 69 tty_buffer_request_room(tty, urb->actual_length);
70 tty_insert_flip_string(tty, data, urb->actual_length); 70 tty_insert_flip_string(tty, data, urb->actual_length);
71 tty_flip_buffer_push(tty); 71 tty_flip_buffer_push(tty);
72 } 72 }
73 tty_kref_put(tty);
73 74
74exit: 75exit:
75 result = usb_submit_urb(urb, GFP_ATOMIC); 76 result = usb_submit_urb(urb, GFP_ATOMIC);
diff --git a/drivers/usb/serial/omninet.c b/drivers/usb/serial/omninet.c
index ae8e227f3db2..c4d70b0f1e48 100644
--- a/drivers/usb/serial/omninet.c
+++ b/drivers/usb/serial/omninet.c
@@ -172,7 +172,7 @@ static int omninet_open(struct tty_struct *tty,
172 dbg("%s - port %d", __func__, port->number); 172 dbg("%s - port %d", __func__, port->number);
173 173
174 wport = serial->port[1]; 174 wport = serial->port[1];
175 wport->port.tty = tty; /* FIXME */ 175 tty_port_tty_set(&wport->port, tty);
176 176
177 /* Start reading from the device */ 177 /* Start reading from the device */
178 usb_fill_bulk_urb(port->read_urb, serial->dev, 178 usb_fill_bulk_urb(port->read_urb, serial->dev,
@@ -229,9 +229,11 @@ static void omninet_read_bulk_callback(struct urb *urb)
229 } 229 }
230 230
231 if (urb->actual_length && header->oh_len) { 231 if (urb->actual_length && header->oh_len) {
232 tty_insert_flip_string(port->port.tty, 232 struct tty_struct *tty = tty_port_tty_get(&port->port);
233 data + OMNINET_DATAOFFSET, header->oh_len); 233 tty_insert_flip_string(tty, data + OMNINET_DATAOFFSET,
234 tty_flip_buffer_push(port->port.tty); 234 header->oh_len);
235 tty_flip_buffer_push(tty);
236 tty_kref_put(tty);
235 } 237 }
236 238
237 /* Continue trying to always read */ 239 /* Continue trying to always read */
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
index 73f8277f88f2..6b1727e751e3 100644
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -571,14 +571,14 @@ static void option_indat_callback(struct urb *urb)
571 dbg("%s: nonzero status: %d on endpoint %02x.", 571 dbg("%s: nonzero status: %d on endpoint %02x.",
572 __func__, status, endpoint); 572 __func__, status, endpoint);
573 } else { 573 } else {
574 tty = port->port.tty; 574 tty = tty_port_tty_get(&port->port);
575 if (urb->actual_length) { 575 if (urb->actual_length) {
576 tty_buffer_request_room(tty, urb->actual_length); 576 tty_buffer_request_room(tty, urb->actual_length);
577 tty_insert_flip_string(tty, data, urb->actual_length); 577 tty_insert_flip_string(tty, data, urb->actual_length);
578 tty_flip_buffer_push(tty); 578 tty_flip_buffer_push(tty);
579 } else { 579 } else
580 dbg("%s: empty read urb received", __func__); 580 dbg("%s: empty read urb received", __func__);
581 } 581 tty_kref_put(tty);
582 582
583 /* Resubmit urb so we continue receiving */ 583 /* Resubmit urb so we continue receiving */
584 if (port->port.count && status != -ESHUTDOWN) { 584 if (port->port.count && status != -ESHUTDOWN) {
@@ -647,9 +647,13 @@ static void option_instat_callback(struct urb *urb)
647 portdata->dsr_state = ((signals & 0x02) ? 1 : 0); 647 portdata->dsr_state = ((signals & 0x02) ? 1 : 0);
648 portdata->ri_state = ((signals & 0x08) ? 1 : 0); 648 portdata->ri_state = ((signals & 0x08) ? 1 : 0);
649 649
650 if (port->port.tty && !C_CLOCAL(port->port.tty) && 650 if (old_dcd_state && !portdata->dcd_state) {
651 old_dcd_state && !portdata->dcd_state) 651 struct tty_struct *tty =
652 tty_hangup(port->port.tty); 652 tty_port_tty_get(&port->port);
653 if (tty && !C_CLOCAL(tty))
654 tty_hangup(tty);
655 tty_kref_put(tty);
656 }
653 } else { 657 } else {
654 dbg("%s: type %x req %x", __func__, 658 dbg("%s: type %x req %x", __func__,
655 req_pkt->bRequestType, req_pkt->bRequest); 659 req_pkt->bRequestType, req_pkt->bRequest);
@@ -793,7 +797,7 @@ static void option_close(struct tty_struct *tty,
793 for (i = 0; i < N_OUT_URB; i++) 797 for (i = 0; i < N_OUT_URB; i++)
794 usb_kill_urb(portdata->out_urbs[i]); 798 usb_kill_urb(portdata->out_urbs[i]);
795 } 799 }
796 port->port.tty = NULL; /* FIXME */ 800 tty_port_tty_set(&port->port, NULL);
797} 801}
798 802
799/* Helper functions used by option_setup_urbs */ 803/* Helper functions used by option_setup_urbs */
diff --git a/drivers/usb/serial/oti6858.c b/drivers/usb/serial/oti6858.c
index 81db5715ee25..ba551f00f16f 100644
--- a/drivers/usb/serial/oti6858.c
+++ b/drivers/usb/serial/oti6858.c
@@ -224,10 +224,6 @@ struct oti6858_private {
224 struct usb_serial_port *port; /* USB port with which associated */ 224 struct usb_serial_port *port; /* USB port with which associated */
225}; 225};
226 226
227#undef dbg
228/* #define dbg(format, arg...) printk(KERN_INFO "%s: " format "\n", __FILE__, ## arg) */
229#define dbg(format, arg...) printk(KERN_INFO "" format "\n", ## arg)
230
231static void setup_line(struct work_struct *work) 227static void setup_line(struct work_struct *work)
232{ 228{
233 struct oti6858_private *priv = container_of(work, 229 struct oti6858_private *priv = container_of(work,
@@ -1002,11 +998,12 @@ static void oti6858_read_bulk_callback(struct urb *urb)
1002 return; 998 return;
1003 } 999 }
1004 1000
1005 tty = port->port.tty; 1001 tty = tty_port_tty_get(&port->port);
1006 if (tty != NULL && urb->actual_length > 0) { 1002 if (tty != NULL && urb->actual_length > 0) {
1007 tty_insert_flip_string(tty, data, urb->actual_length); 1003 tty_insert_flip_string(tty, data, urb->actual_length);
1008 tty_flip_buffer_push(tty); 1004 tty_flip_buffer_push(tty);
1009 } 1005 }
1006 tty_kref_put(tty);
1010 1007
1011 /* schedule the interrupt urb if we are still open */ 1008 /* schedule the interrupt urb if we are still open */
1012 if (port->port.count != 0) { 1009 if (port->port.count != 0) {
diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c
index 1ede1441cb1b..908437847165 100644
--- a/drivers/usb/serial/pl2303.c
+++ b/drivers/usb/serial/pl2303.c
@@ -154,7 +154,6 @@ struct pl2303_private {
154 wait_queue_head_t delta_msr_wait; 154 wait_queue_head_t delta_msr_wait;
155 u8 line_control; 155 u8 line_control;
156 u8 line_status; 156 u8 line_status;
157 u8 termios_initialized;
158 enum pl2303_type type; 157 enum pl2303_type type;
159}; 158};
160 159
@@ -526,16 +525,6 @@ static void pl2303_set_termios(struct tty_struct *tty,
526 525
527 dbg("%s - port %d", __func__, port->number); 526 dbg("%s - port %d", __func__, port->number);
528 527
529 spin_lock_irqsave(&priv->lock, flags);
530 if (!priv->termios_initialized) {
531 *(tty->termios) = tty_std_termios;
532 tty->termios->c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
533 tty->termios->c_ispeed = 9600;
534 tty->termios->c_ospeed = 9600;
535 priv->termios_initialized = 1;
536 }
537 spin_unlock_irqrestore(&priv->lock, flags);
538
539 /* The PL2303 is reported to lose bytes if you change 528 /* The PL2303 is reported to lose bytes if you change
540 serial settings even to the same values as before. Thus 529 serial settings even to the same values as before. Thus
541 we actually need to filter in this specific case */ 530 we actually need to filter in this specific case */
@@ -1057,7 +1046,7 @@ static void pl2303_read_bulk_callback(struct urb *urb)
1057 tty_flag = TTY_FRAME; 1046 tty_flag = TTY_FRAME;
1058 dbg("%s - tty_flag = %d", __func__, tty_flag); 1047 dbg("%s - tty_flag = %d", __func__, tty_flag);
1059 1048
1060 tty = port->port.tty; 1049 tty = tty_port_tty_get(&port->port);
1061 if (tty && urb->actual_length) { 1050 if (tty && urb->actual_length) {
1062 tty_buffer_request_room(tty, urb->actual_length + 1); 1051 tty_buffer_request_room(tty, urb->actual_length + 1);
1063 /* overrun is special, not associated with a char */ 1052 /* overrun is special, not associated with a char */
@@ -1067,7 +1056,7 @@ static void pl2303_read_bulk_callback(struct urb *urb)
1067 tty_insert_flip_char(tty, data[i], tty_flag); 1056 tty_insert_flip_char(tty, data[i], tty_flag);
1068 tty_flip_buffer_push(tty); 1057 tty_flip_buffer_push(tty);
1069 } 1058 }
1070 1059 tty_kref_put(tty);
1071 /* Schedule the next read _if_ we are still open */ 1060 /* Schedule the next read _if_ we are still open */
1072 if (port->port.count) { 1061 if (port->port.count) {
1073 urb->dev = port->serial->dev; 1062 urb->dev = port->serial->dev;
diff --git a/drivers/usb/serial/safe_serial.c b/drivers/usb/serial/safe_serial.c
index def52d07a4ea..72903ac9f5c0 100644
--- a/drivers/usb/serial/safe_serial.c
+++ b/drivers/usb/serial/safe_serial.c
@@ -217,6 +217,7 @@ static void safe_read_bulk_callback(struct urb *urb)
217 struct usb_serial_port *port = urb->context; 217 struct usb_serial_port *port = urb->context;
218 unsigned char *data = urb->transfer_buffer; 218 unsigned char *data = urb->transfer_buffer;
219 unsigned char length = urb->actual_length; 219 unsigned char length = urb->actual_length;
220 struct tty_struct *tty;
220 int result; 221 int result;
221 int status = urb->status; 222 int status = urb->status;
222 223
@@ -242,6 +243,7 @@ static void safe_read_bulk_callback(struct urb *urb)
242 printk("\n"); 243 printk("\n");
243 } 244 }
244#endif 245#endif
246 tty = tty_port_tty_get(&port->port);
245 if (safe) { 247 if (safe) {
246 __u16 fcs; 248 __u16 fcs;
247 fcs = fcs_compute10(data, length, CRC10_INITFCS); 249 fcs = fcs_compute10(data, length, CRC10_INITFCS);
@@ -250,9 +252,9 @@ static void safe_read_bulk_callback(struct urb *urb)
250 if (actual_length <= (length - 2)) { 252 if (actual_length <= (length - 2)) {
251 info("%s - actual: %d", __func__, 253 info("%s - actual: %d", __func__,
252 actual_length); 254 actual_length);
253 tty_insert_flip_string(port->port.tty, 255 tty_insert_flip_string(tty,
254 data, actual_length); 256 data, actual_length);
255 tty_flip_buffer_push(port->port.tty); 257 tty_flip_buffer_push(tty);
256 } else { 258 } else {
257 err("%s - inconsistent lengths %d:%d", 259 err("%s - inconsistent lengths %d:%d",
258 __func__, actual_length, length); 260 __func__, actual_length, length);
@@ -261,9 +263,10 @@ static void safe_read_bulk_callback(struct urb *urb)
261 err("%s - bad CRC %x", __func__, fcs); 263 err("%s - bad CRC %x", __func__, fcs);
262 } 264 }
263 } else { 265 } else {
264 tty_insert_flip_string(port->port.tty, data, length); 266 tty_insert_flip_string(tty, data, length);
265 tty_flip_buffer_push(port->port.tty); 267 tty_flip_buffer_push(tty);
266 } 268 }
269 tty_kref_put(tty);
267 270
268 /* Continue trying to always read */ 271 /* Continue trying to always read */
269 usb_fill_bulk_urb(urb, port->serial->dev, 272 usb_fill_bulk_urb(urb, port->serial->dev,
diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c
index ea1a103c99be..8b9eaf383679 100644
--- a/drivers/usb/serial/sierra.c
+++ b/drivers/usb/serial/sierra.c
@@ -440,14 +440,14 @@ static void sierra_indat_callback(struct urb *urb)
440 dbg("%s: nonzero status: %d on endpoint %02x.", 440 dbg("%s: nonzero status: %d on endpoint %02x.",
441 __func__, status, endpoint); 441 __func__, status, endpoint);
442 } else { 442 } else {
443 tty = port->port.tty;
444 if (urb->actual_length) { 443 if (urb->actual_length) {
444 tty = tty_port_tty_get(&port->port);
445 tty_buffer_request_room(tty, urb->actual_length); 445 tty_buffer_request_room(tty, urb->actual_length);
446 tty_insert_flip_string(tty, data, urb->actual_length); 446 tty_insert_flip_string(tty, data, urb->actual_length);
447 tty_flip_buffer_push(tty); 447 tty_flip_buffer_push(tty);
448 } else { 448 tty_kref_put(tty);
449 } else
449 dbg("%s: empty read urb received", __func__); 450 dbg("%s: empty read urb received", __func__);
450 }
451 451
452 /* Resubmit urb so we continue receiving */ 452 /* Resubmit urb so we continue receiving */
453 if (port->port.count && status != -ESHUTDOWN) { 453 if (port->port.count && status != -ESHUTDOWN) {
@@ -485,6 +485,7 @@ static void sierra_instat_callback(struct urb *urb)
485 unsigned char signals = *((unsigned char *) 485 unsigned char signals = *((unsigned char *)
486 urb->transfer_buffer + 486 urb->transfer_buffer +
487 sizeof(struct usb_ctrlrequest)); 487 sizeof(struct usb_ctrlrequest));
488 struct tty_struct *tty;
488 489
489 dbg("%s: signal x%x", __func__, signals); 490 dbg("%s: signal x%x", __func__, signals);
490 491
@@ -494,9 +495,11 @@ static void sierra_instat_callback(struct urb *urb)
494 portdata->dsr_state = ((signals & 0x02) ? 1 : 0); 495 portdata->dsr_state = ((signals & 0x02) ? 1 : 0);
495 portdata->ri_state = ((signals & 0x08) ? 1 : 0); 496 portdata->ri_state = ((signals & 0x08) ? 1 : 0);
496 497
497 if (port->port.tty && !C_CLOCAL(port->port.tty) && 498 tty = tty_port_tty_get(&port->port);
499 if (tty && !C_CLOCAL(tty) &&
498 old_dcd_state && !portdata->dcd_state) 500 old_dcd_state && !portdata->dcd_state)
499 tty_hangup(port->port.tty); 501 tty_hangup(tty);
502 tty_kref_put(tty);
500 } else { 503 } else {
501 dbg("%s: type %x req %x", __func__, 504 dbg("%s: type %x req %x", __func__,
502 req_pkt->bRequestType, req_pkt->bRequest); 505 req_pkt->bRequestType, req_pkt->bRequest);
@@ -616,8 +619,7 @@ static void sierra_close(struct tty_struct *tty,
616 } 619 }
617 620
618 usb_kill_urb(port->interrupt_in_urb); 621 usb_kill_urb(port->interrupt_in_urb);
619 622 tty_port_tty_set(&port->port, NULL);
620 port->port.tty = NULL; /* FIXME */
621} 623}
622 624
623static int sierra_startup(struct usb_serial *serial) 625static int sierra_startup(struct usb_serial *serial)
diff --git a/drivers/usb/serial/spcp8x5.c b/drivers/usb/serial/spcp8x5.c
index 283cf6b36b2c..1533d6e12238 100644
--- a/drivers/usb/serial/spcp8x5.c
+++ b/drivers/usb/serial/spcp8x5.c
@@ -755,7 +755,7 @@ static void spcp8x5_read_bulk_callback(struct urb *urb)
755 tty_flag = TTY_FRAME; 755 tty_flag = TTY_FRAME;
756 dev_dbg(&port->dev, "tty_flag = %d\n", tty_flag); 756 dev_dbg(&port->dev, "tty_flag = %d\n", tty_flag);
757 757
758 tty = port->port.tty; 758 tty = tty_port_tty_get(&port->port);
759 if (tty && urb->actual_length) { 759 if (tty && urb->actual_length) {
760 tty_buffer_request_room(tty, urb->actual_length + 1); 760 tty_buffer_request_room(tty, urb->actual_length + 1);
761 /* overrun is special, not associated with a char */ 761 /* overrun is special, not associated with a char */
@@ -765,6 +765,7 @@ static void spcp8x5_read_bulk_callback(struct urb *urb)
765 tty_insert_flip_char(tty, data[i], tty_flag); 765 tty_insert_flip_char(tty, data[i], tty_flag);
766 tty_flip_buffer_push(tty); 766 tty_flip_buffer_push(tty);
767 } 767 }
768 tty_kref_put(tty);
768 769
769 /* Schedule the next read _if_ we are still open */ 770 /* Schedule the next read _if_ we are still open */
770 if (port->port.count) { 771 if (port->port.count) {
diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c
index 9a3e495c769c..c90237d48b0e 100644
--- a/drivers/usb/serial/ti_usb_3410_5052.c
+++ b/drivers/usb/serial/ti_usb_3410_5052.c
@@ -179,7 +179,7 @@ static int ti_set_mcr(struct ti_port *tport, unsigned int mcr);
179static int ti_get_lsr(struct ti_port *tport); 179static int ti_get_lsr(struct ti_port *tport);
180static int ti_get_serial_info(struct ti_port *tport, 180static int ti_get_serial_info(struct ti_port *tport,
181 struct serial_struct __user *ret_arg); 181 struct serial_struct __user *ret_arg);
182static int ti_set_serial_info(struct ti_port *tport, 182static int ti_set_serial_info(struct tty_struct *tty, struct ti_port *tport,
183 struct serial_struct __user *new_arg); 183 struct serial_struct __user *new_arg);
184static void ti_handle_new_msr(struct ti_port *tport, __u8 msr); 184static void ti_handle_new_msr(struct ti_port *tport, __u8 msr);
185 185
@@ -857,8 +857,8 @@ static int ti_ioctl(struct tty_struct *tty, struct file *file,
857 (struct serial_struct __user *)arg); 857 (struct serial_struct __user *)arg);
858 case TIOCSSERIAL: 858 case TIOCSSERIAL:
859 dbg("%s - (%d) TIOCSSERIAL", __func__, port->number); 859 dbg("%s - (%d) TIOCSSERIAL", __func__, port->number);
860 return ti_set_serial_info(tport, 860 return ti_set_serial_info(tty, tport,
861 (struct serial_struct __user *)arg); 861 (struct serial_struct __user *)arg);
862 case TIOCMIWAIT: 862 case TIOCMIWAIT:
863 dbg("%s - (%d) TIOCMIWAIT", __func__, port->number); 863 dbg("%s - (%d) TIOCMIWAIT", __func__, port->number);
864 cprev = tport->tp_icount; 864 cprev = tport->tp_icount;
@@ -1211,6 +1211,7 @@ static void ti_bulk_in_callback(struct urb *urb)
1211 struct device *dev = &urb->dev->dev; 1211 struct device *dev = &urb->dev->dev;
1212 int status = urb->status; 1212 int status = urb->status;
1213 int retval = 0; 1213 int retval = 0;
1214 struct tty_struct *tty;
1214 1215
1215 dbg("%s", __func__); 1216 dbg("%s", __func__);
1216 1217
@@ -1239,20 +1240,22 @@ static void ti_bulk_in_callback(struct urb *urb)
1239 return; 1240 return;
1240 } 1241 }
1241 1242
1242 if (port->port.tty && urb->actual_length) { 1243 tty = tty_port_tty_get(&port->port);
1244 if (tty && urb->actual_length) {
1243 usb_serial_debug_data(debug, dev, __func__, 1245 usb_serial_debug_data(debug, dev, __func__,
1244 urb->actual_length, urb->transfer_buffer); 1246 urb->actual_length, urb->transfer_buffer);
1245 1247
1246 if (!tport->tp_is_open) 1248 if (!tport->tp_is_open)
1247 dbg("%s - port closed, dropping data", __func__); 1249 dbg("%s - port closed, dropping data", __func__);
1248 else 1250 else
1249 ti_recv(&urb->dev->dev, port->port.tty, 1251 ti_recv(&urb->dev->dev, tty,
1250 urb->transfer_buffer, 1252 urb->transfer_buffer,
1251 urb->actual_length); 1253 urb->actual_length);
1252 1254
1253 spin_lock(&tport->tp_lock); 1255 spin_lock(&tport->tp_lock);
1254 tport->tp_icount.rx += urb->actual_length; 1256 tport->tp_icount.rx += urb->actual_length;
1255 spin_unlock(&tport->tp_lock); 1257 spin_unlock(&tport->tp_lock);
1258 tty_kref_put(tty);
1256 } 1259 }
1257 1260
1258exit: 1261exit:
@@ -1330,7 +1333,7 @@ static void ti_send(struct ti_port *tport)
1330{ 1333{
1331 int count, result; 1334 int count, result;
1332 struct usb_serial_port *port = tport->tp_port; 1335 struct usb_serial_port *port = tport->tp_port;
1333 struct tty_struct *tty = port->port.tty; /* FIXME */ 1336 struct tty_struct *tty = tty_port_tty_get(&port->port); /* FIXME */
1334 unsigned long flags; 1337 unsigned long flags;
1335 1338
1336 1339
@@ -1338,19 +1341,15 @@ static void ti_send(struct ti_port *tport)
1338 1341
1339 spin_lock_irqsave(&tport->tp_lock, flags); 1342 spin_lock_irqsave(&tport->tp_lock, flags);
1340 1343
1341 if (tport->tp_write_urb_in_use) { 1344 if (tport->tp_write_urb_in_use)
1342 spin_unlock_irqrestore(&tport->tp_lock, flags); 1345 goto unlock;
1343 return;
1344 }
1345 1346
1346 count = ti_buf_get(tport->tp_write_buf, 1347 count = ti_buf_get(tport->tp_write_buf,
1347 port->write_urb->transfer_buffer, 1348 port->write_urb->transfer_buffer,
1348 port->bulk_out_size); 1349 port->bulk_out_size);
1349 1350
1350 if (count == 0) { 1351 if (count == 0)
1351 spin_unlock_irqrestore(&tport->tp_lock, flags); 1352 goto unlock;
1352 return;
1353 }
1354 1353
1355 tport->tp_write_urb_in_use = 1; 1354 tport->tp_write_urb_in_use = 1;
1356 1355
@@ -1380,7 +1379,13 @@ static void ti_send(struct ti_port *tport)
1380 /* more room in the buffer for new writes, wakeup */ 1379 /* more room in the buffer for new writes, wakeup */
1381 if (tty) 1380 if (tty)
1382 tty_wakeup(tty); 1381 tty_wakeup(tty);
1382 tty_kref_put(tty);
1383 wake_up_interruptible(&tport->tp_write_wait); 1383 wake_up_interruptible(&tport->tp_write_wait);
1384 return;
1385unlock:
1386 spin_unlock_irqrestore(&tport->tp_lock, flags);
1387 tty_kref_put(tty);
1388 return;
1384} 1389}
1385 1390
1386 1391
@@ -1464,20 +1469,16 @@ static int ti_get_serial_info(struct ti_port *tport,
1464} 1469}
1465 1470
1466 1471
1467static int ti_set_serial_info(struct ti_port *tport, 1472static int ti_set_serial_info(struct tty_struct *tty, struct ti_port *tport,
1468 struct serial_struct __user *new_arg) 1473 struct serial_struct __user *new_arg)
1469{ 1474{
1470 struct usb_serial_port *port = tport->tp_port;
1471 struct serial_struct new_serial; 1475 struct serial_struct new_serial;
1472 1476
1473 if (copy_from_user(&new_serial, new_arg, sizeof(new_serial))) 1477 if (copy_from_user(&new_serial, new_arg, sizeof(new_serial)))
1474 return -EFAULT; 1478 return -EFAULT;
1475 1479
1476 tport->tp_flags = new_serial.flags & TI_SET_SERIAL_FLAGS; 1480 tport->tp_flags = new_serial.flags & TI_SET_SERIAL_FLAGS;
1477 /* FIXME */ 1481 tty->low_latency = (tport->tp_flags & ASYNC_LOW_LATENCY) ? 1 : 0;
1478 if (port->port.tty)
1479 port->port.tty->low_latency =
1480 (tport->tp_flags & ASYNC_LOW_LATENCY) ? 1 : 0;
1481 tport->tp_closing_wait = new_serial.closing_wait; 1482 tport->tp_closing_wait = new_serial.closing_wait;
1482 1483
1483 return 0; 1484 return 0;
@@ -1510,7 +1511,7 @@ static void ti_handle_new_msr(struct ti_port *tport, __u8 msr)
1510 tport->tp_msr = msr & TI_MSR_MASK; 1511 tport->tp_msr = msr & TI_MSR_MASK;
1511 1512
1512 /* handle CTS flow control */ 1513 /* handle CTS flow control */
1513 tty = tport->tp_port->port.tty; 1514 tty = tty_port_tty_get(&tport->tp_port->port);
1514 if (tty && C_CRTSCTS(tty)) { 1515 if (tty && C_CRTSCTS(tty)) {
1515 if (msr & TI_MSR_CTS) { 1516 if (msr & TI_MSR_CTS) {
1516 tty->hw_stopped = 0; 1517 tty->hw_stopped = 0;
@@ -1519,6 +1520,7 @@ static void ti_handle_new_msr(struct ti_port *tport, __u8 msr)
1519 tty->hw_stopped = 1; 1520 tty->hw_stopped = 1;
1520 } 1521 }
1521 } 1522 }
1523 tty_kref_put(tty);
1522} 1524}
1523 1525
1524 1526
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
index 4f7f9e3ae0a4..e7d4246027b2 100644
--- a/drivers/usb/serial/usb-serial.c
+++ b/drivers/usb/serial/usb-serial.c
@@ -214,7 +214,7 @@ static int serial_open (struct tty_struct *tty, struct file *filp)
214 /* set up our port structure making the tty driver 214 /* set up our port structure making the tty driver
215 * remember our port object, and us it */ 215 * remember our port object, and us it */
216 tty->driver_data = port; 216 tty->driver_data = port;
217 port->port.tty = tty; 217 tty_port_tty_set(&port->port, tty);
218 218
219 if (port->port.count == 1) { 219 if (port->port.count == 1) {
220 220
@@ -246,7 +246,7 @@ bailout_module_put:
246bailout_mutex_unlock: 246bailout_mutex_unlock:
247 port->port.count = 0; 247 port->port.count = 0;
248 tty->driver_data = NULL; 248 tty->driver_data = NULL;
249 port->port.tty = NULL; 249 tty_port_tty_set(&port->port, NULL);
250 mutex_unlock(&port->mutex); 250 mutex_unlock(&port->mutex);
251bailout_kref_put: 251bailout_kref_put:
252 usb_serial_put(serial); 252 usb_serial_put(serial);
@@ -276,10 +276,11 @@ static void serial_close(struct tty_struct *tty, struct file *filp)
276 port->serial->type->close(tty, port, filp); 276 port->serial->type->close(tty, port, filp);
277 277
278 if (port->port.count == (port->console? 1 : 0)) { 278 if (port->port.count == (port->console? 1 : 0)) {
279 if (port->port.tty) { 279 struct tty_struct *tty = tty_port_tty_get(&port->port);
280 if (port->port.tty->driver_data) 280 if (tty) {
281 port->port.tty->driver_data = NULL; 281 if (tty->driver_data)
282 port->port.tty = NULL; 282 tty->driver_data = NULL;
283 tty_port_tty_set(&port->port, NULL);
283 } 284 }
284 } 285 }
285 286
@@ -508,11 +509,12 @@ static void usb_serial_port_work(struct work_struct *work)
508 if (!port) 509 if (!port)
509 return; 510 return;
510 511
511 tty = port->port.tty; 512 tty = tty_port_tty_get(&port->port);
512 if (!tty) 513 if (!tty)
513 return; 514 return;
514 515
515 tty_wakeup(tty); 516 tty_wakeup(tty);
517 tty_kref_put(tty);
516} 518}
517 519
518static void port_release(struct device *dev) 520static void port_release(struct device *dev)
@@ -819,6 +821,7 @@ int usb_serial_probe(struct usb_interface *interface,
819 port = kzalloc(sizeof(struct usb_serial_port), GFP_KERNEL); 821 port = kzalloc(sizeof(struct usb_serial_port), GFP_KERNEL);
820 if (!port) 822 if (!port)
821 goto probe_error; 823 goto probe_error;
824 tty_port_init(&port->port);
822 port->serial = serial; 825 port->serial = serial;
823 spin_lock_init(&port->lock); 826 spin_lock_init(&port->lock);
824 mutex_init(&port->mutex); 827 mutex_init(&port->mutex);
@@ -1040,8 +1043,11 @@ void usb_serial_disconnect(struct usb_interface *interface)
1040 for (i = 0; i < serial->num_ports; ++i) { 1043 for (i = 0; i < serial->num_ports; ++i) {
1041 port = serial->port[i]; 1044 port = serial->port[i];
1042 if (port) { 1045 if (port) {
1043 if (port->port.tty) 1046 struct tty_struct *tty = tty_port_tty_get(&port->port);
1044 tty_hangup(port->port.tty); 1047 if (tty) {
1048 tty_hangup(tty);
1049 tty_kref_put(tty);
1050 }
1045 kill_traffic(port); 1051 kill_traffic(port);
1046 } 1052 }
1047 } 1053 }
diff --git a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c
index cf8924f9a2cc..a6d1c75a1c89 100644
--- a/drivers/usb/serial/visor.c
+++ b/drivers/usb/serial/visor.c
@@ -499,7 +499,7 @@ static void visor_read_bulk_callback(struct urb *urb)
499 int status = urb->status; 499 int status = urb->status;
500 struct tty_struct *tty; 500 struct tty_struct *tty;
501 int result; 501 int result;
502 int available_room; 502 int available_room = 0;
503 503
504 dbg("%s - port %d", __func__, port->number); 504 dbg("%s - port %d", __func__, port->number);
505 505
@@ -512,13 +512,17 @@ static void visor_read_bulk_callback(struct urb *urb)
512 usb_serial_debug_data(debug, &port->dev, __func__, 512 usb_serial_debug_data(debug, &port->dev, __func__,
513 urb->actual_length, data); 513 urb->actual_length, data);
514 514
515 tty = port->port.tty; 515 if (urb->actual_length) {
516 if (tty && urb->actual_length) { 516 tty = tty_port_tty_get(&port->port);
517 available_room = tty_buffer_request_room(tty, 517 if (tty) {
518 available_room = tty_buffer_request_room(tty,
518 urb->actual_length); 519 urb->actual_length);
519 if (available_room) { 520 if (available_room) {
520 tty_insert_flip_string(tty, data, available_room); 521 tty_insert_flip_string(tty, data,
521 tty_flip_buffer_push(tty); 522 available_room);
523 tty_flip_buffer_push(tty);
524 }
525 tty_kref_put(tty);
522 } 526 }
523 spin_lock(&priv->lock); 527 spin_lock(&priv->lock);
524 priv->bytes_in += available_room; 528 priv->bytes_in += available_room;
diff --git a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c
index 3a9d14384a43..11c8b97a5177 100644
--- a/drivers/usb/serial/whiteheat.c
+++ b/drivers/usb/serial/whiteheat.c
@@ -1481,7 +1481,7 @@ static void rx_data_softint(struct work_struct *work)
1481 struct whiteheat_private *info = 1481 struct whiteheat_private *info =
1482 container_of(work, struct whiteheat_private, rx_work); 1482 container_of(work, struct whiteheat_private, rx_work);
1483 struct usb_serial_port *port = info->port; 1483 struct usb_serial_port *port = info->port;
1484 struct tty_struct *tty = port->port.tty; 1484 struct tty_struct *tty = tty_port_tty_get(&port->port);
1485 struct whiteheat_urb_wrap *wrap; 1485 struct whiteheat_urb_wrap *wrap;
1486 struct urb *urb; 1486 struct urb *urb;
1487 unsigned long flags; 1487 unsigned long flags;
@@ -1493,7 +1493,7 @@ static void rx_data_softint(struct work_struct *work)
1493 spin_lock_irqsave(&info->lock, flags); 1493 spin_lock_irqsave(&info->lock, flags);
1494 if (info->flags & THROTTLED) { 1494 if (info->flags & THROTTLED) {
1495 spin_unlock_irqrestore(&info->lock, flags); 1495 spin_unlock_irqrestore(&info->lock, flags);
1496 return; 1496 goto out;
1497 } 1497 }
1498 1498
1499 list_for_each_safe(tmp, tmp2, &info->rx_urb_q) { 1499 list_for_each_safe(tmp, tmp2, &info->rx_urb_q) {
@@ -1513,7 +1513,7 @@ static void rx_data_softint(struct work_struct *work)
1513 spin_unlock_irqrestore(&info->lock, flags); 1513 spin_unlock_irqrestore(&info->lock, flags);
1514 tty_flip_buffer_push(tty); 1514 tty_flip_buffer_push(tty);
1515 schedule_work(&info->rx_work); 1515 schedule_work(&info->rx_work);
1516 return; 1516 goto out;
1517 } 1517 }
1518 tty_insert_flip_string(tty, urb->transfer_buffer, len); 1518 tty_insert_flip_string(tty, urb->transfer_buffer, len);
1519 sent += len; 1519 sent += len;
@@ -1536,6 +1536,8 @@ static void rx_data_softint(struct work_struct *work)
1536 1536
1537 if (sent) 1537 if (sent)
1538 tty_flip_buffer_push(tty); 1538 tty_flip_buffer_push(tty);
1539out:
1540 tty_kref_put(tty);
1539} 1541}
1540 1542
1541 1543
diff --git a/drivers/video/backlight/mbp_nvidia_bl.c b/drivers/video/backlight/mbp_nvidia_bl.c
index 385cba40ea87..06964af761c6 100644
--- a/drivers/video/backlight/mbp_nvidia_bl.c
+++ b/drivers/video/backlight/mbp_nvidia_bl.c
@@ -111,6 +111,4 @@ module_exit(mbp_exit);
111MODULE_AUTHOR("Matthew Garrett <mjg@redhat.com>"); 111MODULE_AUTHOR("Matthew Garrett <mjg@redhat.com>");
112MODULE_DESCRIPTION("Nvidia-based Macbook Pro Backlight Driver"); 112MODULE_DESCRIPTION("Nvidia-based Macbook Pro Backlight Driver");
113MODULE_LICENSE("GPL"); 113MODULE_LICENSE("GPL");
114MODULE_ALIAS("svnAppleInc.:pnMacBookPro3,1"); 114MODULE_DEVICE_TABLE(dmi, mbp_device_table);
115MODULE_ALIAS("svnAppleInc.:pnMacBookPro3,2");
116MODULE_ALIAS("svnAppleInc.:pnMacBookPro4,1");
diff --git a/fs/Kconfig.binfmt b/fs/Kconfig.binfmt
index 4a551af6f3fc..17c9c5ec14c5 100644
--- a/fs/Kconfig.binfmt
+++ b/fs/Kconfig.binfmt
@@ -59,10 +59,12 @@ config BINFMT_SHARED_FLAT
59 help 59 help
60 Support FLAT shared libraries 60 Support FLAT shared libraries
61 61
62config HAVE_AOUT
63 def_bool n
64
62config BINFMT_AOUT 65config BINFMT_AOUT
63 tristate "Kernel support for a.out and ECOFF binaries" 66 tristate "Kernel support for a.out and ECOFF binaries"
64 depends on ARCH_SUPPORTS_AOUT && \ 67 depends on HAVE_AOUT
65 (X86_32 || ALPHA || ARM || M68K)
66 ---help--- 68 ---help---
67 A.out (Assembler.OUTput) is a set of formats for libraries and 69 A.out (Assembler.OUTput) is a set of formats for libraries and
68 executables used in the earliest versions of UNIX. Linux used 70 executables used in the earliest versions of UNIX. Linux used
diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c
index 08e28c9bb416..3dbe2169cf36 100644
--- a/fs/debugfs/inode.c
+++ b/fs/debugfs/inode.c
@@ -26,8 +26,7 @@
26#include <linux/debugfs.h> 26#include <linux/debugfs.h>
27#include <linux/fsnotify.h> 27#include <linux/fsnotify.h>
28#include <linux/string.h> 28#include <linux/string.h>
29 29#include <linux/magic.h>
30#define DEBUGFS_MAGIC 0x64626720
31 30
32static struct vfsmount *debugfs_mount; 31static struct vfsmount *debugfs_mount;
33static int debugfs_mount_count; 32static int debugfs_mount_count;
diff --git a/fs/devpts/inode.c b/fs/devpts/inode.c
index 488eb424f662..a70d5d0890c7 100644
--- a/fs/devpts/inode.c
+++ b/fs/devpts/inode.c
@@ -27,6 +27,7 @@
27#define DEVPTS_SUPER_MAGIC 0x1cd1 27#define DEVPTS_SUPER_MAGIC 0x1cd1
28 28
29#define DEVPTS_DEFAULT_MODE 0600 29#define DEVPTS_DEFAULT_MODE 0600
30#define PTMX_MINOR 2
30 31
31extern int pty_limit; /* Config limit on Unix98 ptys */ 32extern int pty_limit; /* Config limit on Unix98 ptys */
32static DEFINE_IDA(allocated_ptys); 33static DEFINE_IDA(allocated_ptys);
@@ -169,15 +170,7 @@ static struct file_system_type devpts_fs_type = {
169 * to the System V naming convention 170 * to the System V naming convention
170 */ 171 */
171 172
172static struct dentry *get_node(int num) 173int devpts_new_index(struct inode *ptmx_inode)
173{
174 char s[12];
175 struct dentry *root = devpts_root;
176 mutex_lock(&root->d_inode->i_mutex);
177 return lookup_one_len(s, root, sprintf(s, "%d", num));
178}
179
180int devpts_new_index(void)
181{ 174{
182 int index; 175 int index;
183 int ida_ret; 176 int ida_ret;
@@ -205,20 +198,21 @@ retry:
205 return index; 198 return index;
206} 199}
207 200
208void devpts_kill_index(int idx) 201void devpts_kill_index(struct inode *ptmx_inode, int idx)
209{ 202{
210 mutex_lock(&allocated_ptys_lock); 203 mutex_lock(&allocated_ptys_lock);
211 ida_remove(&allocated_ptys, idx); 204 ida_remove(&allocated_ptys, idx);
212 mutex_unlock(&allocated_ptys_lock); 205 mutex_unlock(&allocated_ptys_lock);
213} 206}
214 207
215int devpts_pty_new(struct tty_struct *tty) 208int devpts_pty_new(struct inode *ptmx_inode, struct tty_struct *tty)
216{ 209{
217 int number = tty->index; /* tty layer puts index from devpts_new_index() in here */ 210 int number = tty->index; /* tty layer puts index from devpts_new_index() in here */
218 struct tty_driver *driver = tty->driver; 211 struct tty_driver *driver = tty->driver;
219 dev_t device = MKDEV(driver->major, driver->minor_start+number); 212 dev_t device = MKDEV(driver->major, driver->minor_start+number);
220 struct dentry *dentry; 213 struct dentry *dentry;
221 struct inode *inode = new_inode(devpts_mnt->mnt_sb); 214 struct inode *inode = new_inode(devpts_mnt->mnt_sb);
215 char s[12];
222 216
223 /* We're supposed to be given the slave end of a pty */ 217 /* We're supposed to be given the slave end of a pty */
224 BUG_ON(driver->type != TTY_DRIVER_TYPE_PTY); 218 BUG_ON(driver->type != TTY_DRIVER_TYPE_PTY);
@@ -233,10 +227,15 @@ int devpts_pty_new(struct tty_struct *tty)
233 inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; 227 inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
234 init_special_inode(inode, S_IFCHR|config.mode, device); 228 init_special_inode(inode, S_IFCHR|config.mode, device);
235 inode->i_private = tty; 229 inode->i_private = tty;
230 tty->driver_data = inode;
236 231
237 dentry = get_node(number); 232 sprintf(s, "%d", number);
238 if (!IS_ERR(dentry) && !dentry->d_inode) { 233
239 d_instantiate(dentry, inode); 234 mutex_lock(&devpts_root->d_inode->i_mutex);
235
236 dentry = d_alloc_name(devpts_root, s);
237 if (!IS_ERR(dentry)) {
238 d_add(dentry, inode);
240 fsnotify_create(devpts_root->d_inode, dentry); 239 fsnotify_create(devpts_root->d_inode, dentry);
241 } 240 }
242 241
@@ -245,36 +244,31 @@ int devpts_pty_new(struct tty_struct *tty)
245 return 0; 244 return 0;
246} 245}
247 246
248struct tty_struct *devpts_get_tty(int number) 247struct tty_struct *devpts_get_tty(struct inode *pts_inode, int number)
249{ 248{
250 struct dentry *dentry = get_node(number); 249 BUG_ON(pts_inode->i_rdev == MKDEV(TTYAUX_MAJOR, PTMX_MINOR));
251 struct tty_struct *tty;
252
253 tty = NULL;
254 if (!IS_ERR(dentry)) {
255 if (dentry->d_inode)
256 tty = dentry->d_inode->i_private;
257 dput(dentry);
258 }
259 250
260 mutex_unlock(&devpts_root->d_inode->i_mutex); 251 if (pts_inode->i_sb->s_magic == DEVPTS_SUPER_MAGIC)
261 252 return (struct tty_struct *)pts_inode->i_private;
262 return tty; 253 return NULL;
263} 254}
264 255
265void devpts_pty_kill(int number) 256void devpts_pty_kill(struct tty_struct *tty)
266{ 257{
267 struct dentry *dentry = get_node(number); 258 struct inode *inode = tty->driver_data;
259 struct dentry *dentry;
268 260
269 if (!IS_ERR(dentry)) { 261 BUG_ON(inode->i_rdev == MKDEV(TTYAUX_MAJOR, PTMX_MINOR));
270 struct inode *inode = dentry->d_inode; 262
271 if (inode) { 263 mutex_lock(&devpts_root->d_inode->i_mutex);
272 inode->i_nlink--; 264
273 d_delete(dentry); 265 dentry = d_find_alias(inode);
274 dput(dentry); 266 if (dentry && !IS_ERR(dentry)) {
275 } 267 inode->i_nlink--;
268 d_delete(dentry);
276 dput(dentry); 269 dput(dentry);
277 } 270 }
271
278 mutex_unlock(&devpts_root->d_inode->i_mutex); 272 mutex_unlock(&devpts_root->d_inode->i_mutex);
279} 273}
280 274
diff --git a/fs/dquot.c b/fs/dquot.c
index 8ec4d6cc7633..ad7e59003e04 100644
--- a/fs/dquot.c
+++ b/fs/dquot.c
@@ -895,10 +895,9 @@ static void print_warning(struct dquot *dquot, const int warntype)
895 warntype == QUOTA_NL_BSOFTBELOW || !need_print_warning(dquot)) 895 warntype == QUOTA_NL_BSOFTBELOW || !need_print_warning(dquot))
896 return; 896 return;
897 897
898 mutex_lock(&tty_mutex);
899 tty = get_current_tty(); 898 tty = get_current_tty();
900 if (!tty) 899 if (!tty)
901 goto out_lock; 900 return;
902 tty_write_message(tty, dquot->dq_sb->s_id); 901 tty_write_message(tty, dquot->dq_sb->s_id);
903 if (warntype == QUOTA_NL_ISOFTWARN || warntype == QUOTA_NL_BSOFTWARN) 902 if (warntype == QUOTA_NL_ISOFTWARN || warntype == QUOTA_NL_BSOFTWARN)
904 tty_write_message(tty, ": warning, "); 903 tty_write_message(tty, ": warning, ");
@@ -926,8 +925,7 @@ static void print_warning(struct dquot *dquot, const int warntype)
926 break; 925 break;
927 } 926 }
928 tty_write_message(tty, msg); 927 tty_write_message(tty, msg);
929out_lock: 928 tty_kref_put(tty);
930 mutex_unlock(&tty_mutex);
931} 929}
932#endif 930#endif
933 931
diff --git a/fs/efs/super.c b/fs/efs/super.c
index 567b134fa1f1..73b19cfc91fc 100644
--- a/fs/efs/super.c
+++ b/fs/efs/super.c
@@ -341,8 +341,6 @@ static int efs_statfs(struct dentry *dentry, struct kstatfs *buf) {
341 sb->inode_blocks * 341 sb->inode_blocks *
342 (EFS_BLOCKSIZE / sizeof(struct efs_dinode)); 342 (EFS_BLOCKSIZE / sizeof(struct efs_dinode));
343 buf->f_ffree = sb->inode_free; /* free inodes */ 343 buf->f_ffree = sb->inode_free; /* free inodes */
344 buf->f_fsid.val[0] = (sb->fs_magic >> 16) & 0xffff; /* fs ID */
345 buf->f_fsid.val[1] = sb->fs_magic & 0xffff; /* fs ID */
346 buf->f_namelen = EFS_MAXNAMELEN; /* max filename length */ 344 buf->f_namelen = EFS_MAXNAMELEN; /* max filename length */
347 345
348 return 0; 346 return 0;
diff --git a/fs/open.c b/fs/open.c
index 07da9359481c..5596049863bf 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -1141,8 +1141,7 @@ EXPORT_SYMBOL(sys_close);
1141asmlinkage long sys_vhangup(void) 1141asmlinkage long sys_vhangup(void)
1142{ 1142{
1143 if (capable(CAP_SYS_TTY_CONFIG)) { 1143 if (capable(CAP_SYS_TTY_CONFIG)) {
1144 /* XXX: this needs locking */ 1144 tty_vhangup_self();
1145 tty_vhangup(current->signal->tty);
1146 return 0; 1145 return 0;
1147 } 1146 }
1148 return -EPERM; 1147 return -EPERM;
diff --git a/fs/proc/Kconfig b/fs/proc/Kconfig
index 73cd7a418f06..50f8f0600f06 100644
--- a/fs/proc/Kconfig
+++ b/fs/proc/Kconfig
@@ -57,3 +57,13 @@ config PROC_SYSCTL
57 As it is generally a good thing, you should say Y here unless 57 As it is generally a good thing, you should say Y here unless
58 building a kernel for install/rescue disks or your system is very 58 building a kernel for install/rescue disks or your system is very
59 limited in memory. 59 limited in memory.
60
61config PROC_PAGE_MONITOR
62 default y
63 depends on PROC_FS && MMU
64 bool "Enable /proc page monitoring" if EMBEDDED
65 help
66 Various /proc files exist to monitor process memory utilization:
67 /proc/pid/smaps, /proc/pid/clear_refs, /proc/pid/pagemap,
68 /proc/kpagecount, and /proc/kpageflags. Disabling these
69 interfaces will reduce the size of the kernel by approximately 4kb.
diff --git a/fs/proc/array.c b/fs/proc/array.c
index 71c9be59c9c2..f4bc0e789539 100644
--- a/fs/proc/array.c
+++ b/fs/proc/array.c
@@ -86,11 +86,6 @@
86#include <asm/processor.h> 86#include <asm/processor.h>
87#include "internal.h" 87#include "internal.h"
88 88
89/* Gcc optimizes away "strlen(x)" for constant x */
90#define ADDBUF(buffer, string) \
91do { memcpy(buffer, string, strlen(string)); \
92 buffer += strlen(string); } while (0)
93
94static inline void task_name(struct seq_file *m, struct task_struct *p) 89static inline void task_name(struct seq_file *m, struct task_struct *p)
95{ 90{
96 int i; 91 int i;
@@ -261,7 +256,6 @@ static inline void task_sig(struct seq_file *m, struct task_struct *p)
261 sigemptyset(&ignored); 256 sigemptyset(&ignored);
262 sigemptyset(&caught); 257 sigemptyset(&caught);
263 258
264 rcu_read_lock();
265 if (lock_task_sighand(p, &flags)) { 259 if (lock_task_sighand(p, &flags)) {
266 pending = p->pending.signal; 260 pending = p->pending.signal;
267 shpending = p->signal->shared_pending.signal; 261 shpending = p->signal->shared_pending.signal;
@@ -272,7 +266,6 @@ static inline void task_sig(struct seq_file *m, struct task_struct *p)
272 qlim = p->signal->rlim[RLIMIT_SIGPENDING].rlim_cur; 266 qlim = p->signal->rlim[RLIMIT_SIGPENDING].rlim_cur;
273 unlock_task_sighand(p, &flags); 267 unlock_task_sighand(p, &flags);
274 } 268 }
275 rcu_read_unlock();
276 269
277 seq_printf(m, "Threads:\t%d\n", num_threads); 270 seq_printf(m, "Threads:\t%d\n", num_threads);
278 seq_printf(m, "SigQ:\t%lu/%lu\n", qsize, qlim); 271 seq_printf(m, "SigQ:\t%lu/%lu\n", qsize, qlim);
diff --git a/fs/proc/base.c b/fs/proc/base.c
index a28840b11b89..b5918ae8ca79 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -148,9 +148,6 @@ static unsigned int pid_entry_count_dirs(const struct pid_entry *entries,
148 return count; 148 return count;
149} 149}
150 150
151int maps_protect;
152EXPORT_SYMBOL(maps_protect);
153
154static struct fs_struct *get_fs_struct(struct task_struct *task) 151static struct fs_struct *get_fs_struct(struct task_struct *task)
155{ 152{
156 struct fs_struct *fs; 153 struct fs_struct *fs;
@@ -164,7 +161,6 @@ static struct fs_struct *get_fs_struct(struct task_struct *task)
164 161
165static int get_nr_threads(struct task_struct *tsk) 162static int get_nr_threads(struct task_struct *tsk)
166{ 163{
167 /* Must be called with the rcu_read_lock held */
168 unsigned long flags; 164 unsigned long flags;
169 int count = 0; 165 int count = 0;
170 166
@@ -471,14 +467,10 @@ static int proc_pid_limits(struct task_struct *task, char *buffer)
471 467
472 struct rlimit rlim[RLIM_NLIMITS]; 468 struct rlimit rlim[RLIM_NLIMITS];
473 469
474 rcu_read_lock(); 470 if (!lock_task_sighand(task, &flags))
475 if (!lock_task_sighand(task,&flags)) {
476 rcu_read_unlock();
477 return 0; 471 return 0;
478 }
479 memcpy(rlim, task->signal->rlim, sizeof(struct rlimit) * RLIM_NLIMITS); 472 memcpy(rlim, task->signal->rlim, sizeof(struct rlimit) * RLIM_NLIMITS);
480 unlock_task_sighand(task, &flags); 473 unlock_task_sighand(task, &flags);
481 rcu_read_unlock();
482 474
483 /* 475 /*
484 * print the file header 476 * print the file header
@@ -2443,6 +2435,13 @@ static int proc_tgid_io_accounting(struct task_struct *task, char *buffer)
2443} 2435}
2444#endif /* CONFIG_TASK_IO_ACCOUNTING */ 2436#endif /* CONFIG_TASK_IO_ACCOUNTING */
2445 2437
2438static int proc_pid_personality(struct seq_file *m, struct pid_namespace *ns,
2439 struct pid *pid, struct task_struct *task)
2440{
2441 seq_printf(m, "%08x\n", task->personality);
2442 return 0;
2443}
2444
2446/* 2445/*
2447 * Thread groups 2446 * Thread groups
2448 */ 2447 */
@@ -2459,6 +2458,7 @@ static const struct pid_entry tgid_base_stuff[] = {
2459 REG("environ", S_IRUSR, environ), 2458 REG("environ", S_IRUSR, environ),
2460 INF("auxv", S_IRUSR, pid_auxv), 2459 INF("auxv", S_IRUSR, pid_auxv),
2461 ONE("status", S_IRUGO, pid_status), 2460 ONE("status", S_IRUGO, pid_status),
2461 ONE("personality", S_IRUSR, pid_personality),
2462 INF("limits", S_IRUSR, pid_limits), 2462 INF("limits", S_IRUSR, pid_limits),
2463#ifdef CONFIG_SCHED_DEBUG 2463#ifdef CONFIG_SCHED_DEBUG
2464 REG("sched", S_IRUGO|S_IWUSR, pid_sched), 2464 REG("sched", S_IRUGO|S_IWUSR, pid_sched),
@@ -2794,6 +2794,7 @@ static const struct pid_entry tid_base_stuff[] = {
2794 REG("environ", S_IRUSR, environ), 2794 REG("environ", S_IRUSR, environ),
2795 INF("auxv", S_IRUSR, pid_auxv), 2795 INF("auxv", S_IRUSR, pid_auxv),
2796 ONE("status", S_IRUGO, pid_status), 2796 ONE("status", S_IRUGO, pid_status),
2797 ONE("personality", S_IRUSR, pid_personality),
2797 INF("limits", S_IRUSR, pid_limits), 2798 INF("limits", S_IRUSR, pid_limits),
2798#ifdef CONFIG_SCHED_DEBUG 2799#ifdef CONFIG_SCHED_DEBUG
2799 REG("sched", S_IRUGO|S_IWUSR, pid_sched), 2800 REG("sched", S_IRUGO|S_IWUSR, pid_sched),
@@ -3088,9 +3089,7 @@ static int proc_task_getattr(struct vfsmount *mnt, struct dentry *dentry, struct
3088 generic_fillattr(inode, stat); 3089 generic_fillattr(inode, stat);
3089 3090
3090 if (p) { 3091 if (p) {
3091 rcu_read_lock();
3092 stat->nlink += get_nr_threads(p); 3092 stat->nlink += get_nr_threads(p);
3093 rcu_read_unlock();
3094 put_task_struct(p); 3093 put_task_struct(p);
3095 } 3094 }
3096 3095
diff --git a/fs/proc/inode.c b/fs/proc/inode.c
index 8bb03f056c28..c6b4fa7e3b49 100644
--- a/fs/proc/inode.c
+++ b/fs/proc/inode.c
@@ -342,7 +342,7 @@ static int proc_reg_open(struct inode *inode, struct file *file)
342 if (!pde->proc_fops) { 342 if (!pde->proc_fops) {
343 spin_unlock(&pde->pde_unload_lock); 343 spin_unlock(&pde->pde_unload_lock);
344 kfree(pdeo); 344 kfree(pdeo);
345 return rv; 345 return -EINVAL;
346 } 346 }
347 pde->pde_users++; 347 pde->pde_users++;
348 open = pde->proc_fops->open; 348 open = pde->proc_fops->open;
diff --git a/fs/proc/internal.h b/fs/proc/internal.h
index 442202314d53..3bfb7b8747b3 100644
--- a/fs/proc/internal.h
+++ b/fs/proc/internal.h
@@ -45,8 +45,6 @@ do { \
45extern int nommu_vma_show(struct seq_file *, struct vm_area_struct *); 45extern int nommu_vma_show(struct seq_file *, struct vm_area_struct *);
46#endif 46#endif
47 47
48extern int maps_protect;
49
50extern int proc_tid_stat(struct seq_file *m, struct pid_namespace *ns, 48extern int proc_tid_stat(struct seq_file *m, struct pid_namespace *ns,
51 struct pid *pid, struct task_struct *task); 49 struct pid *pid, struct task_struct *task);
52extern int proc_tgid_stat(struct seq_file *m, struct pid_namespace *ns, 50extern int proc_tgid_stat(struct seq_file *m, struct pid_namespace *ns,
diff --git a/fs/proc/proc_misc.c b/fs/proc/proc_misc.c
index 29e20c6b1f7f..66c1ab87656c 100644
--- a/fs/proc/proc_misc.c
+++ b/fs/proc/proc_misc.c
@@ -68,7 +68,6 @@
68extern int get_hardware_list(char *); 68extern int get_hardware_list(char *);
69extern int get_stram_list(char *); 69extern int get_stram_list(char *);
70extern int get_exec_domain_list(char *); 70extern int get_exec_domain_list(char *);
71extern int get_dma_list(char *);
72 71
73static int proc_calc_metrics(char *page, char **start, off_t off, 72static int proc_calc_metrics(char *page, char **start, off_t off,
74 int count, int *eof, int len) 73 int count, int *eof, int len)
diff --git a/fs/proc/proc_sysctl.c b/fs/proc/proc_sysctl.c
index f9a8b892718f..945a81043ba2 100644
--- a/fs/proc/proc_sysctl.c
+++ b/fs/proc/proc_sysctl.c
@@ -66,7 +66,7 @@ static struct ctl_table *find_in_table(struct ctl_table *p, struct qstr *name)
66 return NULL; 66 return NULL;
67} 67}
68 68
69struct ctl_table_header *grab_header(struct inode *inode) 69static struct ctl_table_header *grab_header(struct inode *inode)
70{ 70{
71 if (PROC_I(inode)->sysctl) 71 if (PROC_I(inode)->sysctl)
72 return sysctl_head_grab(PROC_I(inode)->sysctl); 72 return sysctl_head_grab(PROC_I(inode)->sysctl);
@@ -395,10 +395,10 @@ static struct dentry_operations proc_sys_dentry_operations = {
395 .d_compare = proc_sys_compare, 395 .d_compare = proc_sys_compare,
396}; 396};
397 397
398static struct proc_dir_entry *proc_sys_root;
399
400int proc_sys_init(void) 398int proc_sys_init(void)
401{ 399{
400 struct proc_dir_entry *proc_sys_root;
401
402 proc_sys_root = proc_mkdir("sys", NULL); 402 proc_sys_root = proc_mkdir("sys", NULL);
403 proc_sys_root->proc_iops = &proc_sys_dir_operations; 403 proc_sys_root->proc_iops = &proc_sys_dir_operations;
404 proc_sys_root->proc_fops = &proc_sys_dir_file_operations; 404 proc_sys_root->proc_fops = &proc_sys_dir_file_operations;
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
index 73d1891ee625..4806830ea2a1 100644
--- a/fs/proc/task_mmu.c
+++ b/fs/proc/task_mmu.c
@@ -210,9 +210,6 @@ static int show_map(struct seq_file *m, void *v)
210 dev_t dev = 0; 210 dev_t dev = 0;
211 int len; 211 int len;
212 212
213 if (maps_protect && !ptrace_may_access(task, PTRACE_MODE_READ))
214 return -EACCES;
215
216 if (file) { 213 if (file) {
217 struct inode *inode = vma->vm_file->f_path.dentry->d_inode; 214 struct inode *inode = vma->vm_file->f_path.dentry->d_inode;
218 dev = inode->i_sb->s_dev; 215 dev = inode->i_sb->s_dev;
@@ -742,22 +739,11 @@ const struct file_operations proc_pagemap_operations = {
742#ifdef CONFIG_NUMA 739#ifdef CONFIG_NUMA
743extern int show_numa_map(struct seq_file *m, void *v); 740extern int show_numa_map(struct seq_file *m, void *v);
744 741
745static int show_numa_map_checked(struct seq_file *m, void *v)
746{
747 struct proc_maps_private *priv = m->private;
748 struct task_struct *task = priv->task;
749
750 if (maps_protect && !ptrace_may_access(task, PTRACE_MODE_READ))
751 return -EACCES;
752
753 return show_numa_map(m, v);
754}
755
756static const struct seq_operations proc_pid_numa_maps_op = { 742static const struct seq_operations proc_pid_numa_maps_op = {
757 .start = m_start, 743 .start = m_start,
758 .next = m_next, 744 .next = m_next,
759 .stop = m_stop, 745 .stop = m_stop,
760 .show = show_numa_map_checked 746 .show = show_numa_map,
761}; 747};
762 748
763static int numa_maps_open(struct inode *inode, struct file *file) 749static int numa_maps_open(struct inode *inode, struct file *file)
diff --git a/fs/proc/task_nommu.c b/fs/proc/task_nommu.c
index 5d84e7121df8..219bd79ea894 100644
--- a/fs/proc/task_nommu.c
+++ b/fs/proc/task_nommu.c
@@ -110,11 +110,6 @@ int task_statm(struct mm_struct *mm, int *shared, int *text,
110static int show_map(struct seq_file *m, void *_vml) 110static int show_map(struct seq_file *m, void *_vml)
111{ 111{
112 struct vm_list_struct *vml = _vml; 112 struct vm_list_struct *vml = _vml;
113 struct proc_maps_private *priv = m->private;
114 struct task_struct *task = priv->task;
115
116 if (maps_protect && !ptrace_may_access(task, PTRACE_MODE_READ))
117 return -EACCES;
118 113
119 return nommu_vma_show(m, vml->vma); 114 return nommu_vma_show(m, vml->vma);
120} 115}
diff --git a/fs/proc/vmcore.c b/fs/proc/vmcore.c
index 9ac0f5e064e0..841368b87a29 100644
--- a/fs/proc/vmcore.c
+++ b/fs/proc/vmcore.c
@@ -165,14 +165,8 @@ static ssize_t read_vmcore(struct file *file, char __user *buffer,
165 return acc; 165 return acc;
166} 166}
167 167
168static int open_vmcore(struct inode *inode, struct file *filp)
169{
170 return 0;
171}
172
173const struct file_operations proc_vmcore_operations = { 168const struct file_operations proc_vmcore_operations = {
174 .read = read_vmcore, 169 .read = read_vmcore,
175 .open = open_vmcore,
176}; 170};
177 171
178static struct vmcore* __init get_new_element(void) 172static struct vmcore* __init get_new_element(void)
diff --git a/include/asm-cris/a.out.h b/include/asm-cris/a.out.h
deleted file mode 100644
index c82e9f9b75f6..000000000000
--- a/include/asm-cris/a.out.h
+++ /dev/null
@@ -1,26 +0,0 @@
1#ifndef __CRIS_A_OUT_H__
2#define __CRIS_A_OUT_H__
3
4/* we don't support a.out binaries on Linux/CRIS anyway, so this is
5 * not really used but still needed because binfmt_elf.c for some reason
6 * wants to know about a.out even if there is no interpreter available...
7 */
8
9struct exec
10{
11 unsigned long a_info; /* Use macros N_MAGIC, etc for access */
12 unsigned a_text; /* length of text, in bytes */
13 unsigned a_data; /* length of data, in bytes */
14 unsigned a_bss; /* length of uninitialized data area for file, in bytes */
15 unsigned a_syms; /* length of symbol table data in file, in bytes */
16 unsigned a_entry; /* start address */
17 unsigned a_trsize; /* length of relocation info for text, in bytes */
18 unsigned a_drsize; /* length of relocation info for data, in bytes */
19};
20
21
22#define N_TRSIZE(a) ((a).a_trsize)
23#define N_DRSIZE(a) ((a).a_drsize)
24#define N_SYMSIZE(a) ((a).a_syms)
25
26#endif
diff --git a/include/asm-generic/statfs.h b/include/asm-generic/statfs.h
index 1d01043e797d..6129d6802149 100644
--- a/include/asm-generic/statfs.h
+++ b/include/asm-generic/statfs.h
@@ -6,33 +6,64 @@
6typedef __kernel_fsid_t fsid_t; 6typedef __kernel_fsid_t fsid_t;
7#endif 7#endif
8 8
9/*
10 * Most 64-bit platforms use 'long', while most 32-bit platforms use '__u32'.
11 * Yes, they differ in signedness as well as size.
12 * Special cases can override it for themselves -- except for S390x, which
13 * is just a little too special for us. And MIPS, which I'm not touching
14 * with a 10' pole.
15 */
16#ifndef __statfs_word
17#if BITS_PER_LONG == 64
18#define __statfs_word long
19#else
20#define __statfs_word __u32
21#endif
22#endif
23
9struct statfs { 24struct statfs {
10 __u32 f_type; 25 __statfs_word f_type;
11 __u32 f_bsize; 26 __statfs_word f_bsize;
12 __u32 f_blocks; 27 __statfs_word f_blocks;
13 __u32 f_bfree; 28 __statfs_word f_bfree;
14 __u32 f_bavail; 29 __statfs_word f_bavail;
15 __u32 f_files; 30 __statfs_word f_files;
16 __u32 f_ffree; 31 __statfs_word f_ffree;
17 __kernel_fsid_t f_fsid; 32 __kernel_fsid_t f_fsid;
18 __u32 f_namelen; 33 __statfs_word f_namelen;
19 __u32 f_frsize; 34 __statfs_word f_frsize;
20 __u32 f_spare[5]; 35 __statfs_word f_spare[5];
21}; 36};
22 37
38/*
39 * ARM needs to avoid the 32-bit padding at the end, for consistency
40 * between EABI and OABI
41 */
42#ifndef ARCH_PACK_STATFS64
43#define ARCH_PACK_STATFS64
44#endif
45
23struct statfs64 { 46struct statfs64 {
24 __u32 f_type; 47 __statfs_word f_type;
25 __u32 f_bsize; 48 __statfs_word f_bsize;
26 __u64 f_blocks; 49 __u64 f_blocks;
27 __u64 f_bfree; 50 __u64 f_bfree;
28 __u64 f_bavail; 51 __u64 f_bavail;
29 __u64 f_files; 52 __u64 f_files;
30 __u64 f_ffree; 53 __u64 f_ffree;
31 __kernel_fsid_t f_fsid; 54 __kernel_fsid_t f_fsid;
32 __u32 f_namelen; 55 __statfs_word f_namelen;
33 __u32 f_frsize; 56 __statfs_word f_frsize;
34 __u32 f_spare[5]; 57 __statfs_word f_spare[5];
35}; 58} ARCH_PACK_STATFS64;
59
60/*
61 * IA64 and x86_64 need to avoid the 32-bit padding at the end,
62 * to be compatible with the i386 ABI
63 */
64#ifndef ARCH_PACK_COMPAT_STATFS64
65#define ARCH_PACK_COMPAT_STATFS64
66#endif
36 67
37struct compat_statfs64 { 68struct compat_statfs64 {
38 __u32 f_type; 69 __u32 f_type;
@@ -46,6 +77,6 @@ struct compat_statfs64 {
46 __u32 f_namelen; 77 __u32 f_namelen;
47 __u32 f_frsize; 78 __u32 f_frsize;
48 __u32 f_spare[5]; 79 __u32 f_spare[5];
49}; 80} ARCH_PACK_COMPAT_STATFS64;
50 81
51#endif 82#endif
diff --git a/include/asm-m32r/a.out.h b/include/asm-m32r/a.out.h
deleted file mode 100644
index ab150f5c1666..000000000000
--- a/include/asm-m32r/a.out.h
+++ /dev/null
@@ -1,20 +0,0 @@
1#ifndef _ASM_M32R_A_OUT_H
2#define _ASM_M32R_A_OUT_H
3
4struct exec
5{
6 unsigned long a_info; /* Use macros N_MAGIC, etc for access */
7 unsigned a_text; /* length of text, in bytes */
8 unsigned a_data; /* length of data, in bytes */
9 unsigned a_bss; /* length of uninitialized data area for file, in bytes */
10 unsigned a_syms; /* length of symbol table data in file, in bytes */
11 unsigned a_entry; /* start address */
12 unsigned a_trsize; /* length of relocation info for text, in bytes */
13 unsigned a_drsize; /* length of relocation info for data, in bytes */
14};
15
16#define N_TRSIZE(a) ((a).a_trsize)
17#define N_DRSIZE(a) ((a).a_drsize)
18#define N_SYMSIZE(a) ((a).a_syms)
19
20#endif /* _ASM_M32R_A_OUT_H */
diff --git a/include/asm-parisc/a.out.h b/include/asm-parisc/a.out.h
deleted file mode 100644
index eb04e34c5bb1..000000000000
--- a/include/asm-parisc/a.out.h
+++ /dev/null
@@ -1,20 +0,0 @@
1#ifndef __PARISC_A_OUT_H__
2#define __PARISC_A_OUT_H__
3
4struct exec
5{
6 unsigned int a_info; /* Use macros N_MAGIC, etc for access */
7 unsigned a_text; /* length of text, in bytes */
8 unsigned a_data; /* length of data, in bytes */
9 unsigned a_bss; /* length of uninitialized data area for file, in bytes */
10 unsigned a_syms; /* length of symbol table data in file, in bytes */
11 unsigned a_entry; /* start address */
12 unsigned a_trsize; /* length of relocation info for text, in bytes */
13 unsigned a_drsize; /* length of relocation info for data, in bytes */
14};
15
16#define N_TRSIZE(a) ((a).a_trsize)
17#define N_DRSIZE(a) ((a).a_drsize)
18#define N_SYMSIZE(a) ((a).a_syms)
19
20#endif /* __A_OUT_GNU_H__ */
diff --git a/include/asm-parisc/statfs.h b/include/asm-parisc/statfs.h
index 1d2b8130b23d..324bea905dc6 100644
--- a/include/asm-parisc/statfs.h
+++ b/include/asm-parisc/statfs.h
@@ -1,58 +1,7 @@
1#ifndef _PARISC_STATFS_H 1#ifndef _PARISC_STATFS_H
2#define _PARISC_STATFS_H 2#define _PARISC_STATFS_H
3 3
4#ifndef __KERNEL_STRICT_NAMES 4#define __statfs_word long
5 5#include <asm-generic/statfs.h>
6#include <linux/types.h>
7
8typedef __kernel_fsid_t fsid_t;
9
10#endif
11
12/*
13 * It appears that PARISC could be 64 _or_ 32 bit.
14 * 64-bit fields must be explicitly 64-bit in statfs64.
15 */
16struct statfs {
17 long f_type;
18 long f_bsize;
19 long f_blocks;
20 long f_bfree;
21 long f_bavail;
22 long f_files;
23 long f_ffree;
24 __kernel_fsid_t f_fsid;
25 long f_namelen;
26 long f_frsize;
27 long f_spare[5];
28};
29
30struct statfs64 {
31 long f_type;
32 long f_bsize;
33 __u64 f_blocks;
34 __u64 f_bfree;
35 __u64 f_bavail;
36 __u64 f_files;
37 __u64 f_ffree;
38 __kernel_fsid_t f_fsid;
39 long f_namelen;
40 long f_frsize;
41 long f_spare[5];
42};
43
44struct compat_statfs64 {
45 __u32 f_type;
46 __u32 f_bsize;
47 __u64 f_blocks;
48 __u64 f_bfree;
49 __u64 f_bavail;
50 __u64 f_files;
51 __u64 f_ffree;
52 __kernel_fsid_t f_fsid;
53 __u32 f_namelen;
54 __u32 f_frsize;
55 __u32 f_spare[5];
56};
57 6
58#endif 7#endif
diff --git a/include/asm-x86/desc.h b/include/asm-x86/desc.h
index ebc307817e98..f06adac7938c 100644
--- a/include/asm-x86/desc.h
+++ b/include/asm-x86/desc.h
@@ -351,20 +351,16 @@ static inline void set_system_intr_gate(unsigned int n, void *addr)
351 _set_gate(n, GATE_INTERRUPT, addr, 0x3, 0, __KERNEL_CS); 351 _set_gate(n, GATE_INTERRUPT, addr, 0x3, 0, __KERNEL_CS);
352} 352}
353 353
354static inline void set_trap_gate(unsigned int n, void *addr) 354static inline void set_system_trap_gate(unsigned int n, void *addr)
355{ 355{
356 BUG_ON((unsigned)n > 0xFF); 356 BUG_ON((unsigned)n > 0xFF);
357 _set_gate(n, GATE_TRAP, addr, 0, 0, __KERNEL_CS); 357 _set_gate(n, GATE_TRAP, addr, 0x3, 0, __KERNEL_CS);
358} 358}
359 359
360static inline void set_system_gate(unsigned int n, void *addr) 360static inline void set_trap_gate(unsigned int n, void *addr)
361{ 361{
362 BUG_ON((unsigned)n > 0xFF); 362 BUG_ON((unsigned)n > 0xFF);
363#ifdef CONFIG_X86_32 363 _set_gate(n, GATE_TRAP, addr, 0, 0, __KERNEL_CS);
364 _set_gate(n, GATE_TRAP, addr, 0x3, 0, __KERNEL_CS);
365#else
366 _set_gate(n, GATE_INTERRUPT, addr, 0x3, 0, __KERNEL_CS);
367#endif
368} 364}
369 365
370static inline void set_task_gate(unsigned int n, unsigned int gdt_entry) 366static inline void set_task_gate(unsigned int n, unsigned int gdt_entry)
@@ -379,7 +375,7 @@ static inline void set_intr_gate_ist(int n, void *addr, unsigned ist)
379 _set_gate(n, GATE_INTERRUPT, addr, 0, ist, __KERNEL_CS); 375 _set_gate(n, GATE_INTERRUPT, addr, 0, ist, __KERNEL_CS);
380} 376}
381 377
382static inline void set_system_gate_ist(int n, void *addr, unsigned ist) 378static inline void set_system_intr_gate_ist(int n, void *addr, unsigned ist)
383{ 379{
384 BUG_ON((unsigned)n > 0xFF); 380 BUG_ON((unsigned)n > 0xFF);
385 _set_gate(n, GATE_INTERRUPT, addr, 0x3, ist, __KERNEL_CS); 381 _set_gate(n, GATE_INTERRUPT, addr, 0x3, ist, __KERNEL_CS);
diff --git a/include/asm-x86/es7000/mpparse.h b/include/asm-x86/es7000/mpparse.h
index 7b5c889d8e7d..ed5a3caae141 100644
--- a/include/asm-x86/es7000/mpparse.h
+++ b/include/asm-x86/es7000/mpparse.h
@@ -5,6 +5,7 @@
5 5
6extern int parse_unisys_oem (char *oemptr); 6extern int parse_unisys_oem (char *oemptr);
7extern int find_unisys_acpi_oem_table(unsigned long *oem_addr); 7extern int find_unisys_acpi_oem_table(unsigned long *oem_addr);
8extern void unmap_unisys_acpi_oem_table(unsigned long oem_addr);
8extern void setup_unisys(void); 9extern void setup_unisys(void);
9 10
10#ifndef CONFIG_X86_GENERICARCH 11#ifndef CONFIG_X86_GENERICARCH
diff --git a/include/asm-x86/fixmap_32.h b/include/asm-x86/fixmap_32.h
index 784e3e759866..8844002da0e0 100644
--- a/include/asm-x86/fixmap_32.h
+++ b/include/asm-x86/fixmap_32.h
@@ -94,10 +94,10 @@ enum fixed_addresses {
94 * can have a single pgd entry and a single pte table: 94 * can have a single pgd entry and a single pte table:
95 */ 95 */
96#define NR_FIX_BTMAPS 64 96#define NR_FIX_BTMAPS 64
97#define FIX_BTMAPS_NESTING 4 97#define FIX_BTMAPS_SLOTS 4
98 FIX_BTMAP_END = __end_of_permanent_fixed_addresses + 256 - 98 FIX_BTMAP_END = __end_of_permanent_fixed_addresses + 256 -
99 (__end_of_permanent_fixed_addresses & 255), 99 (__end_of_permanent_fixed_addresses & 255),
100 FIX_BTMAP_BEGIN = FIX_BTMAP_END + NR_FIX_BTMAPS*FIX_BTMAPS_NESTING - 1, 100 FIX_BTMAP_BEGIN = FIX_BTMAP_END + NR_FIX_BTMAPS*FIX_BTMAPS_SLOTS - 1,
101 FIX_WP_TEST, 101 FIX_WP_TEST,
102#ifdef CONFIG_ACPI 102#ifdef CONFIG_ACPI
103 FIX_ACPI_BEGIN, 103 FIX_ACPI_BEGIN,
diff --git a/include/asm-x86/fixmap_64.h b/include/asm-x86/fixmap_64.h
index dafb24bc0424..dab4751d1307 100644
--- a/include/asm-x86/fixmap_64.h
+++ b/include/asm-x86/fixmap_64.h
@@ -49,6 +49,7 @@ enum fixed_addresses {
49#ifdef CONFIG_PARAVIRT 49#ifdef CONFIG_PARAVIRT
50 FIX_PARAVIRT_BOOTMAP, 50 FIX_PARAVIRT_BOOTMAP,
51#endif 51#endif
52 __end_of_permanent_fixed_addresses,
52#ifdef CONFIG_ACPI 53#ifdef CONFIG_ACPI
53 FIX_ACPI_BEGIN, 54 FIX_ACPI_BEGIN,
54 FIX_ACPI_END = FIX_ACPI_BEGIN + FIX_ACPI_PAGES - 1, 55 FIX_ACPI_END = FIX_ACPI_BEGIN + FIX_ACPI_PAGES - 1,
@@ -56,19 +57,18 @@ enum fixed_addresses {
56#ifdef CONFIG_PROVIDE_OHCI1394_DMA_INIT 57#ifdef CONFIG_PROVIDE_OHCI1394_DMA_INIT
57 FIX_OHCI1394_BASE, 58 FIX_OHCI1394_BASE,
58#endif 59#endif
59 __end_of_permanent_fixed_addresses,
60 /* 60 /*
61 * 256 temporary boot-time mappings, used by early_ioremap(), 61 * 256 temporary boot-time mappings, used by early_ioremap(),
62 * before ioremap() is functional. 62 * before ioremap() is functional.
63 * 63 *
64 * We round it up to the next 512 pages boundary so that we 64 * We round it up to the next 256 pages boundary so that we
65 * can have a single pgd entry and a single pte table: 65 * can have a single pgd entry and a single pte table:
66 */ 66 */
67#define NR_FIX_BTMAPS 64 67#define NR_FIX_BTMAPS 64
68#define FIX_BTMAPS_NESTING 4 68#define FIX_BTMAPS_SLOTS 4
69 FIX_BTMAP_END = __end_of_permanent_fixed_addresses + 512 - 69 FIX_BTMAP_END = __end_of_permanent_fixed_addresses + 256 -
70 (__end_of_permanent_fixed_addresses & 511), 70 (__end_of_permanent_fixed_addresses & 255),
71 FIX_BTMAP_BEGIN = FIX_BTMAP_END + NR_FIX_BTMAPS*FIX_BTMAPS_NESTING - 1, 71 FIX_BTMAP_BEGIN = FIX_BTMAP_END + NR_FIX_BTMAPS*FIX_BTMAPS_SLOTS - 1,
72 __end_of_fixed_addresses 72 __end_of_fixed_addresses
73}; 73};
74 74
diff --git a/include/asm-x86/io.h b/include/asm-x86/io.h
index 72b7719523bf..a233f835e0b5 100644
--- a/include/asm-x86/io.h
+++ b/include/asm-x86/io.h
@@ -5,20 +5,6 @@
5 5
6#include <linux/compiler.h> 6#include <linux/compiler.h>
7 7
8/*
9 * early_ioremap() and early_iounmap() are for temporary early boot-time
10 * mappings, before the real ioremap() is functional.
11 * A boot-time mapping is currently limited to at most 16 pages.
12 */
13#ifndef __ASSEMBLY__
14extern void early_ioremap_init(void);
15extern void early_ioremap_clear(void);
16extern void early_ioremap_reset(void);
17extern void *early_ioremap(unsigned long offset, unsigned long size);
18extern void early_iounmap(void *addr, unsigned long size);
19extern void __iomem *fix_ioremap(unsigned idx, unsigned long phys);
20#endif
21
22#define build_mmio_read(name, size, type, reg, barrier) \ 8#define build_mmio_read(name, size, type, reg, barrier) \
23static inline type name(const volatile void __iomem *addr) \ 9static inline type name(const volatile void __iomem *addr) \
24{ type ret; asm volatile("mov" size " %1,%0":reg (ret) \ 10{ type ret; asm volatile("mov" size " %1,%0":reg (ret) \
@@ -97,6 +83,7 @@ extern void early_ioremap_init(void);
97extern void early_ioremap_clear(void); 83extern void early_ioremap_clear(void);
98extern void early_ioremap_reset(void); 84extern void early_ioremap_reset(void);
99extern void *early_ioremap(unsigned long offset, unsigned long size); 85extern void *early_ioremap(unsigned long offset, unsigned long size);
86extern void *early_memremap(unsigned long offset, unsigned long size);
100extern void early_iounmap(void *addr, unsigned long size); 87extern void early_iounmap(void *addr, unsigned long size);
101extern void __iomem *fix_ioremap(unsigned idx, unsigned long phys); 88extern void __iomem *fix_ioremap(unsigned idx, unsigned long phys);
102 89
diff --git a/include/asm-x86/io_64.h b/include/asm-x86/io_64.h
index 64429e9431a8..ee6e086b7dfe 100644
--- a/include/asm-x86/io_64.h
+++ b/include/asm-x86/io_64.h
@@ -165,9 +165,6 @@ static inline void *phys_to_virt(unsigned long address)
165 165
166#include <asm-generic/iomap.h> 166#include <asm-generic/iomap.h>
167 167
168extern void *early_ioremap(unsigned long addr, unsigned long size);
169extern void early_iounmap(void *addr, unsigned long size);
170
171/* 168/*
172 * This one maps high address device memory and turns off caching for that area. 169 * This one maps high address device memory and turns off caching for that area.
173 * it's useful if some control registers are in such an area and write combining 170 * it's useful if some control registers are in such an area and write combining
diff --git a/include/asm-x86/ioctls.h b/include/asm-x86/ioctls.h
index 336603512399..06752a649044 100644
--- a/include/asm-x86/ioctls.h
+++ b/include/asm-x86/ioctls.h
@@ -51,9 +51,15 @@
51#define TCSETS2 _IOW('T', 0x2B, struct termios2) 51#define TCSETS2 _IOW('T', 0x2B, struct termios2)
52#define TCSETSW2 _IOW('T', 0x2C, struct termios2) 52#define TCSETSW2 _IOW('T', 0x2C, struct termios2)
53#define TCSETSF2 _IOW('T', 0x2D, struct termios2) 53#define TCSETSF2 _IOW('T', 0x2D, struct termios2)
54#define TIOCGRS485 0x542E
55#define TIOCSRS485 0x542F
54#define TIOCGPTN _IOR('T', 0x30, unsigned int) 56#define TIOCGPTN _IOR('T', 0x30, unsigned int)
55 /* Get Pty Number (of pty-mux device) */ 57 /* Get Pty Number (of pty-mux device) */
56#define TIOCSPTLCK _IOW('T', 0x31, int) /* Lock/unlock Pty */ 58#define TIOCSPTLCK _IOW('T', 0x31, int) /* Lock/unlock Pty */
59#define TCGETX 0x5432 /* SYS5 TCGETX compatibility */
60#define TCSETX 0x5433
61#define TCSETXF 0x5434
62#define TCSETXW 0x5435
57 63
58#define FIONCLEX 0x5450 64#define FIONCLEX 0x5450
59#define FIOCLEX 0x5451 65#define FIOCLEX 0x5451
diff --git a/include/asm-x86/irqflags.h b/include/asm-x86/irqflags.h
index 424acb48cd61..2bdab21f0898 100644
--- a/include/asm-x86/irqflags.h
+++ b/include/asm-x86/irqflags.h
@@ -166,27 +166,6 @@ static inline int raw_irqs_disabled(void)
166 return raw_irqs_disabled_flags(flags); 166 return raw_irqs_disabled_flags(flags);
167} 167}
168 168
169/*
170 * makes the traced hardirq state match with the machine state
171 *
172 * should be a rarely used function, only in places where its
173 * otherwise impossible to know the irq state, like in traps.
174 */
175static inline void trace_hardirqs_fixup_flags(unsigned long flags)
176{
177 if (raw_irqs_disabled_flags(flags))
178 trace_hardirqs_off();
179 else
180 trace_hardirqs_on();
181}
182
183static inline void trace_hardirqs_fixup(void)
184{
185 unsigned long flags = __raw_local_save_flags();
186
187 trace_hardirqs_fixup_flags(flags);
188}
189
190#else 169#else
191 170
192#ifdef CONFIG_X86_64 171#ifdef CONFIG_X86_64
diff --git a/include/asm-x86/kdebug.h b/include/asm-x86/kdebug.h
index 5ec3ad3e825c..fbbab66ee9df 100644
--- a/include/asm-x86/kdebug.h
+++ b/include/asm-x86/kdebug.h
@@ -27,10 +27,9 @@ extern void printk_address(unsigned long address, int reliable);
27extern void die(const char *, struct pt_regs *,long); 27extern void die(const char *, struct pt_regs *,long);
28extern int __must_check __die(const char *, struct pt_regs *, long); 28extern int __must_check __die(const char *, struct pt_regs *, long);
29extern void show_registers(struct pt_regs *regs); 29extern void show_registers(struct pt_regs *regs);
30extern void __show_registers(struct pt_regs *, int all);
31extern void show_trace(struct task_struct *t, struct pt_regs *regs, 30extern void show_trace(struct task_struct *t, struct pt_regs *regs,
32 unsigned long *sp, unsigned long bp); 31 unsigned long *sp, unsigned long bp);
33extern void __show_regs(struct pt_regs *regs); 32extern void __show_regs(struct pt_regs *regs, int all);
34extern void show_regs(struct pt_regs *regs); 33extern void show_regs(struct pt_regs *regs);
35extern unsigned long oops_begin(void); 34extern unsigned long oops_begin(void);
36extern void oops_end(unsigned long, struct pt_regs *, int signr); 35extern void oops_end(unsigned long, struct pt_regs *, int signr);
diff --git a/include/asm-x86/kprobes.h b/include/asm-x86/kprobes.h
index bd8407863c13..8a0748d01036 100644
--- a/include/asm-x86/kprobes.h
+++ b/include/asm-x86/kprobes.h
@@ -82,15 +82,6 @@ struct kprobe_ctlblk {
82 struct prev_kprobe prev_kprobe; 82 struct prev_kprobe prev_kprobe;
83}; 83};
84 84
85/* trap3/1 are intr gates for kprobes. So, restore the status of IF,
86 * if necessary, before executing the original int3/1 (trap) handler.
87 */
88static inline void restore_interrupts(struct pt_regs *regs)
89{
90 if (regs->flags & X86_EFLAGS_IF)
91 local_irq_enable();
92}
93
94extern int kprobe_fault_handler(struct pt_regs *regs, int trapnr); 85extern int kprobe_fault_handler(struct pt_regs *regs, int trapnr);
95extern int kprobe_exceptions_notify(struct notifier_block *self, 86extern int kprobe_exceptions_notify(struct notifier_block *self,
96 unsigned long val, void *data); 87 unsigned long val, void *data);
diff --git a/include/asm-x86/mach-default/mach_traps.h b/include/asm-x86/mach-default/mach_traps.h
index de9ac3f5c4ce..ff8778f26b84 100644
--- a/include/asm-x86/mach-default/mach_traps.h
+++ b/include/asm-x86/mach-default/mach_traps.h
@@ -7,12 +7,6 @@
7 7
8#include <asm/mc146818rtc.h> 8#include <asm/mc146818rtc.h>
9 9
10static inline void clear_mem_error(unsigned char reason)
11{
12 reason = (reason & 0xf) | 4;
13 outb(reason, 0x61);
14}
15
16static inline unsigned char get_nmi_reason(void) 10static inline unsigned char get_nmi_reason(void)
17{ 11{
18 return inb(0x61); 12 return inb(0x61);
diff --git a/include/asm-x86/module.h b/include/asm-x86/module.h
index 48dc3e0c07d9..864f2005fc1d 100644
--- a/include/asm-x86/module.h
+++ b/include/asm-x86/module.h
@@ -52,8 +52,6 @@ struct mod_arch_specific {};
52#define MODULE_PROC_FAMILY "EFFICEON " 52#define MODULE_PROC_FAMILY "EFFICEON "
53#elif defined CONFIG_MWINCHIPC6 53#elif defined CONFIG_MWINCHIPC6
54#define MODULE_PROC_FAMILY "WINCHIPC6 " 54#define MODULE_PROC_FAMILY "WINCHIPC6 "
55#elif defined CONFIG_MWINCHIP2
56#define MODULE_PROC_FAMILY "WINCHIP2 "
57#elif defined CONFIG_MWINCHIP3D 55#elif defined CONFIG_MWINCHIP3D
58#define MODULE_PROC_FAMILY "WINCHIP3D " 56#define MODULE_PROC_FAMILY "WINCHIP3D "
59#elif defined CONFIG_MCYRIXIII 57#elif defined CONFIG_MCYRIXIII
diff --git a/include/asm-x86/nmi.h b/include/asm-x86/nmi.h
index d5e715f024dc..a53f829a97c5 100644
--- a/include/asm-x86/nmi.h
+++ b/include/asm-x86/nmi.h
@@ -15,10 +15,6 @@
15 */ 15 */
16int do_nmi_callback(struct pt_regs *regs, int cpu); 16int do_nmi_callback(struct pt_regs *regs, int cpu);
17 17
18#ifdef CONFIG_X86_64
19extern void default_do_nmi(struct pt_regs *);
20#endif
21
22extern void die_nmi(char *str, struct pt_regs *regs, int do_panic); 18extern void die_nmi(char *str, struct pt_regs *regs, int do_panic);
23extern int check_nmi_watchdog(void); 19extern int check_nmi_watchdog(void);
24extern int nmi_watchdog_enabled; 20extern int nmi_watchdog_enabled;
diff --git a/include/asm-x86/page.h b/include/asm-x86/page.h
index c91574776751..d4f1d5791fc1 100644
--- a/include/asm-x86/page.h
+++ b/include/asm-x86/page.h
@@ -179,6 +179,7 @@ static inline pteval_t native_pte_flags(pte_t pte)
179#endif /* CONFIG_PARAVIRT */ 179#endif /* CONFIG_PARAVIRT */
180 180
181#define __pa(x) __phys_addr((unsigned long)(x)) 181#define __pa(x) __phys_addr((unsigned long)(x))
182#define __pa_nodebug(x) __phys_addr_nodebug((unsigned long)(x))
182/* __pa_symbol should be used for C visible symbols. 183/* __pa_symbol should be used for C visible symbols.
183 This seems to be the official gcc blessed way to do such arithmetic. */ 184 This seems to be the official gcc blessed way to do such arithmetic. */
184#define __pa_symbol(x) __pa(__phys_reloc_hide((unsigned long)(x))) 185#define __pa_symbol(x) __pa(__phys_reloc_hide((unsigned long)(x)))
@@ -188,9 +189,14 @@ static inline pteval_t native_pte_flags(pte_t pte)
188#define __boot_va(x) __va(x) 189#define __boot_va(x) __va(x)
189#define __boot_pa(x) __pa(x) 190#define __boot_pa(x) __pa(x)
190 191
192/*
193 * virt_to_page(kaddr) returns a valid pointer if and only if
194 * virt_addr_valid(kaddr) returns true.
195 */
191#define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT) 196#define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)
192#define pfn_to_kaddr(pfn) __va((pfn) << PAGE_SHIFT) 197#define pfn_to_kaddr(pfn) __va((pfn) << PAGE_SHIFT)
193#define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT) 198extern bool __virt_addr_valid(unsigned long kaddr);
199#define virt_addr_valid(kaddr) __virt_addr_valid((unsigned long) (kaddr))
194 200
195#endif /* __ASSEMBLY__ */ 201#endif /* __ASSEMBLY__ */
196 202
diff --git a/include/asm-x86/page_32.h b/include/asm-x86/page_32.h
index 9c5a737a9af9..e8d80d1de237 100644
--- a/include/asm-x86/page_32.h
+++ b/include/asm-x86/page_32.h
@@ -20,6 +20,12 @@
20#endif 20#endif
21#define THREAD_SIZE (PAGE_SIZE << THREAD_ORDER) 21#define THREAD_SIZE (PAGE_SIZE << THREAD_ORDER)
22 22
23#define STACKFAULT_STACK 0
24#define DOUBLEFAULT_STACK 1
25#define NMI_STACK 0
26#define DEBUG_STACK 0
27#define MCE_STACK 0
28#define N_EXCEPTION_STACKS 1
23 29
24#ifdef CONFIG_X86_PAE 30#ifdef CONFIG_X86_PAE
25/* 44=32+12, the limit we can fit into an unsigned long pfn */ 31/* 44=32+12, the limit we can fit into an unsigned long pfn */
@@ -73,11 +79,11 @@ typedef struct page *pgtable_t;
73#endif 79#endif
74 80
75#ifndef __ASSEMBLY__ 81#ifndef __ASSEMBLY__
76#define __phys_addr_const(x) ((x) - PAGE_OFFSET) 82#define __phys_addr_nodebug(x) ((x) - PAGE_OFFSET)
77#ifdef CONFIG_DEBUG_VIRTUAL 83#ifdef CONFIG_DEBUG_VIRTUAL
78extern unsigned long __phys_addr(unsigned long); 84extern unsigned long __phys_addr(unsigned long);
79#else 85#else
80#define __phys_addr(x) ((x) - PAGE_OFFSET) 86#define __phys_addr(x) __phys_addr_nodebug(x)
81#endif 87#endif
82#define __phys_reloc_hide(x) RELOC_HIDE((x), 0) 88#define __phys_reloc_hide(x) RELOC_HIDE((x), 0)
83 89
diff --git a/include/asm-x86/pgtable.h b/include/asm-x86/pgtable.h
index ed932453ef26..182f9d4c570f 100644
--- a/include/asm-x86/pgtable.h
+++ b/include/asm-x86/pgtable.h
@@ -15,7 +15,7 @@
15#define _PAGE_BIT_PAT 7 /* on 4KB pages */ 15#define _PAGE_BIT_PAT 7 /* on 4KB pages */
16#define _PAGE_BIT_GLOBAL 8 /* Global TLB entry PPro+ */ 16#define _PAGE_BIT_GLOBAL 8 /* Global TLB entry PPro+ */
17#define _PAGE_BIT_UNUSED1 9 /* available for programmer */ 17#define _PAGE_BIT_UNUSED1 9 /* available for programmer */
18#define _PAGE_BIT_UNUSED2 10 18#define _PAGE_BIT_IOMAP 10 /* flag used to indicate IO mapping */
19#define _PAGE_BIT_UNUSED3 11 19#define _PAGE_BIT_UNUSED3 11
20#define _PAGE_BIT_PAT_LARGE 12 /* On 2MB or 1GB pages */ 20#define _PAGE_BIT_PAT_LARGE 12 /* On 2MB or 1GB pages */
21#define _PAGE_BIT_SPECIAL _PAGE_BIT_UNUSED1 21#define _PAGE_BIT_SPECIAL _PAGE_BIT_UNUSED1
@@ -32,7 +32,7 @@
32#define _PAGE_PSE (_AT(pteval_t, 1) << _PAGE_BIT_PSE) 32#define _PAGE_PSE (_AT(pteval_t, 1) << _PAGE_BIT_PSE)
33#define _PAGE_GLOBAL (_AT(pteval_t, 1) << _PAGE_BIT_GLOBAL) 33#define _PAGE_GLOBAL (_AT(pteval_t, 1) << _PAGE_BIT_GLOBAL)
34#define _PAGE_UNUSED1 (_AT(pteval_t, 1) << _PAGE_BIT_UNUSED1) 34#define _PAGE_UNUSED1 (_AT(pteval_t, 1) << _PAGE_BIT_UNUSED1)
35#define _PAGE_UNUSED2 (_AT(pteval_t, 1) << _PAGE_BIT_UNUSED2) 35#define _PAGE_IOMAP (_AT(pteval_t, 1) << _PAGE_BIT_IOMAP)
36#define _PAGE_UNUSED3 (_AT(pteval_t, 1) << _PAGE_BIT_UNUSED3) 36#define _PAGE_UNUSED3 (_AT(pteval_t, 1) << _PAGE_BIT_UNUSED3)
37#define _PAGE_PAT (_AT(pteval_t, 1) << _PAGE_BIT_PAT) 37#define _PAGE_PAT (_AT(pteval_t, 1) << _PAGE_BIT_PAT)
38#define _PAGE_PAT_LARGE (_AT(pteval_t, 1) << _PAGE_BIT_PAT_LARGE) 38#define _PAGE_PAT_LARGE (_AT(pteval_t, 1) << _PAGE_BIT_PAT_LARGE)
@@ -99,6 +99,11 @@
99#define __PAGE_KERNEL_LARGE_NOCACHE (__PAGE_KERNEL | _PAGE_CACHE_UC | _PAGE_PSE) 99#define __PAGE_KERNEL_LARGE_NOCACHE (__PAGE_KERNEL | _PAGE_CACHE_UC | _PAGE_PSE)
100#define __PAGE_KERNEL_LARGE_EXEC (__PAGE_KERNEL_EXEC | _PAGE_PSE) 100#define __PAGE_KERNEL_LARGE_EXEC (__PAGE_KERNEL_EXEC | _PAGE_PSE)
101 101
102#define __PAGE_KERNEL_IO (__PAGE_KERNEL | _PAGE_IOMAP)
103#define __PAGE_KERNEL_IO_NOCACHE (__PAGE_KERNEL_NOCACHE | _PAGE_IOMAP)
104#define __PAGE_KERNEL_IO_UC_MINUS (__PAGE_KERNEL_UC_MINUS | _PAGE_IOMAP)
105#define __PAGE_KERNEL_IO_WC (__PAGE_KERNEL_WC | _PAGE_IOMAP)
106
102#define PAGE_KERNEL __pgprot(__PAGE_KERNEL) 107#define PAGE_KERNEL __pgprot(__PAGE_KERNEL)
103#define PAGE_KERNEL_RO __pgprot(__PAGE_KERNEL_RO) 108#define PAGE_KERNEL_RO __pgprot(__PAGE_KERNEL_RO)
104#define PAGE_KERNEL_EXEC __pgprot(__PAGE_KERNEL_EXEC) 109#define PAGE_KERNEL_EXEC __pgprot(__PAGE_KERNEL_EXEC)
@@ -113,6 +118,11 @@
113#define PAGE_KERNEL_VSYSCALL __pgprot(__PAGE_KERNEL_VSYSCALL) 118#define PAGE_KERNEL_VSYSCALL __pgprot(__PAGE_KERNEL_VSYSCALL)
114#define PAGE_KERNEL_VSYSCALL_NOCACHE __pgprot(__PAGE_KERNEL_VSYSCALL_NOCACHE) 119#define PAGE_KERNEL_VSYSCALL_NOCACHE __pgprot(__PAGE_KERNEL_VSYSCALL_NOCACHE)
115 120
121#define PAGE_KERNEL_IO __pgprot(__PAGE_KERNEL_IO)
122#define PAGE_KERNEL_IO_NOCACHE __pgprot(__PAGE_KERNEL_IO_NOCACHE)
123#define PAGE_KERNEL_IO_UC_MINUS __pgprot(__PAGE_KERNEL_IO_UC_MINUS)
124#define PAGE_KERNEL_IO_WC __pgprot(__PAGE_KERNEL_IO_WC)
125
116/* xwr */ 126/* xwr */
117#define __P000 PAGE_NONE 127#define __P000 PAGE_NONE
118#define __P001 PAGE_READONLY 128#define __P001 PAGE_READONLY
@@ -196,7 +206,7 @@ static inline int pte_exec(pte_t pte)
196 206
197static inline int pte_special(pte_t pte) 207static inline int pte_special(pte_t pte)
198{ 208{
199 return pte_val(pte) & _PAGE_SPECIAL; 209 return pte_flags(pte) & _PAGE_SPECIAL;
200} 210}
201 211
202static inline unsigned long pte_pfn(pte_t pte) 212static inline unsigned long pte_pfn(pte_t pte)
diff --git a/include/asm-x86/ptrace.h b/include/asm-x86/ptrace.h
index ac578f11c1c5..a2025525a15a 100644
--- a/include/asm-x86/ptrace.h
+++ b/include/asm-x86/ptrace.h
@@ -174,12 +174,8 @@ extern unsigned long profile_pc(struct pt_regs *regs);
174 174
175extern unsigned long 175extern unsigned long
176convert_ip_to_linear(struct task_struct *child, struct pt_regs *regs); 176convert_ip_to_linear(struct task_struct *child, struct pt_regs *regs);
177
178#ifdef CONFIG_X86_32
179extern void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, 177extern void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs,
180 int error_code, int si_code); 178 int error_code, int si_code);
181#endif
182
183void signal_fault(struct pt_regs *regs, void __user *frame, char *where); 179void signal_fault(struct pt_regs *regs, void __user *frame, char *where);
184 180
185extern long syscall_trace_enter(struct pt_regs *); 181extern long syscall_trace_enter(struct pt_regs *);
diff --git a/include/asm-x86/segment.h b/include/asm-x86/segment.h
index ea5f0a8686f7..5d6e69454891 100644
--- a/include/asm-x86/segment.h
+++ b/include/asm-x86/segment.h
@@ -131,12 +131,6 @@
131 * Matching rules for certain types of segments. 131 * Matching rules for certain types of segments.
132 */ 132 */
133 133
134/* Matches only __KERNEL_CS, ignoring PnP / USER / APM segments */
135#define SEGMENT_IS_KERNEL_CODE(x) (((x) & 0xfc) == GDT_ENTRY_KERNEL_CS * 8)
136
137/* Matches __KERNEL_CS and __USER_CS (they must be 2 entries apart) */
138#define SEGMENT_IS_FLAT_CODE(x) (((x) & 0xec) == GDT_ENTRY_KERNEL_CS * 8)
139
140/* Matches PNP_CS32 and PNP_CS16 (they must be consecutive) */ 134/* Matches PNP_CS32 and PNP_CS16 (they must be consecutive) */
141#define SEGMENT_IS_PNP_CODE(x) (((x) & 0xf4) == GDT_ENTRY_PNPBIOS_BASE * 8) 135#define SEGMENT_IS_PNP_CODE(x) (((x) & 0xf4) == GDT_ENTRY_PNPBIOS_BASE * 8)
142 136
diff --git a/include/asm-x86/smp.h b/include/asm-x86/smp.h
index 6df2615f9138..a6afc29f2dd9 100644
--- a/include/asm-x86/smp.h
+++ b/include/asm-x86/smp.h
@@ -141,6 +141,8 @@ void play_dead_common(void);
141void native_send_call_func_ipi(cpumask_t mask); 141void native_send_call_func_ipi(cpumask_t mask);
142void native_send_call_func_single_ipi(int cpu); 142void native_send_call_func_single_ipi(int cpu);
143 143
144extern void prefill_possible_map(void);
145
144void smp_store_cpu_info(int id); 146void smp_store_cpu_info(int id);
145#define cpu_physical_id(cpu) per_cpu(x86_cpu_to_apicid, cpu) 147#define cpu_physical_id(cpu) per_cpu(x86_cpu_to_apicid, cpu)
146 148
@@ -149,15 +151,11 @@ static inline int num_booting_cpus(void)
149{ 151{
150 return cpus_weight(cpu_callout_map); 152 return cpus_weight(cpu_callout_map);
151} 153}
152#endif /* CONFIG_SMP */
153
154#if defined(CONFIG_SMP) && defined(CONFIG_HOTPLUG_CPU)
155extern void prefill_possible_map(void);
156#else 154#else
157static inline void prefill_possible_map(void) 155static inline void prefill_possible_map(void)
158{ 156{
159} 157}
160#endif 158#endif /* CONFIG_SMP */
161 159
162extern unsigned disabled_cpus __cpuinitdata; 160extern unsigned disabled_cpus __cpuinitdata;
163 161
diff --git a/include/asm-x86/statfs.h b/include/asm-x86/statfs.h
index 3f005bc3aa5b..ca5dc19dd461 100644
--- a/include/asm-x86/statfs.h
+++ b/include/asm-x86/statfs.h
@@ -1,63 +1,12 @@
1#ifndef ASM_X86__STATFS_H 1#ifndef ASM_X86__STATFS_H
2#define ASM_X86__STATFS_H 2#define ASM_X86__STATFS_H
3 3
4#ifdef __i386__
5#include <asm-generic/statfs.h>
6#else
7
8#ifndef __KERNEL_STRICT_NAMES
9
10#include <linux/types.h>
11
12typedef __kernel_fsid_t fsid_t;
13
14#endif
15
16/* 4/*
17 * This is ugly -- we're already 64-bit clean, so just duplicate the 5 * We need compat_statfs64 to be packed, because the i386 ABI won't
18 * definitions. 6 * add padding at the end to bring it to a multiple of 8 bytes, but
7 * the x86_64 ABI will.
19 */ 8 */
20struct statfs { 9#define ARCH_PACK_COMPAT_STATFS64 __attribute__((packed,aligned(4)))
21 long f_type;
22 long f_bsize;
23 long f_blocks;
24 long f_bfree;
25 long f_bavail;
26 long f_files;
27 long f_ffree;
28 __kernel_fsid_t f_fsid;
29 long f_namelen;
30 long f_frsize;
31 long f_spare[5];
32};
33
34struct statfs64 {
35 long f_type;
36 long f_bsize;
37 long f_blocks;
38 long f_bfree;
39 long f_bavail;
40 long f_files;
41 long f_ffree;
42 __kernel_fsid_t f_fsid;
43 long f_namelen;
44 long f_frsize;
45 long f_spare[5];
46};
47 10
48struct compat_statfs64 { 11#include <asm-generic/statfs.h>
49 __u32 f_type;
50 __u32 f_bsize;
51 __u64 f_blocks;
52 __u64 f_bfree;
53 __u64 f_bavail;
54 __u64 f_files;
55 __u64 f_ffree;
56 __kernel_fsid_t f_fsid;
57 __u32 f_namelen;
58 __u32 f_frsize;
59 __u32 f_spare[5];
60} __attribute__((packed));
61
62#endif /* !__i386__ */
63#endif /* ASM_X86__STATFS_H */ 12#endif /* ASM_X86__STATFS_H */
diff --git a/include/asm-x86/system.h b/include/asm-x86/system.h
index 34505dd7b24d..b20c894660f9 100644
--- a/include/asm-x86/system.h
+++ b/include/asm-x86/system.h
@@ -64,7 +64,10 @@ do { \
64 \ 64 \
65 /* regparm parameters for __switch_to(): */ \ 65 /* regparm parameters for __switch_to(): */ \
66 [prev] "a" (prev), \ 66 [prev] "a" (prev), \
67 [next] "d" (next)); \ 67 [next] "d" (next) \
68 \
69 : /* reloaded segment registers */ \
70 "memory"); \
68} while (0) 71} while (0)
69 72
70/* 73/*
diff --git a/include/asm-x86/traps.h b/include/asm-x86/traps.h
index 7a692baa51ae..6c3dc2c65751 100644
--- a/include/asm-x86/traps.h
+++ b/include/asm-x86/traps.h
@@ -3,7 +3,12 @@
3 3
4#include <asm/debugreg.h> 4#include <asm/debugreg.h>
5 5
6/* Common in X86_32 and X86_64 */ 6#ifdef CONFIG_X86_32
7#define dotraplinkage
8#else
9#define dotraplinkage asmlinkage
10#endif
11
7asmlinkage void divide_error(void); 12asmlinkage void divide_error(void);
8asmlinkage void debug(void); 13asmlinkage void debug(void);
9asmlinkage void nmi(void); 14asmlinkage void nmi(void);
@@ -12,31 +17,47 @@ asmlinkage void overflow(void);
12asmlinkage void bounds(void); 17asmlinkage void bounds(void);
13asmlinkage void invalid_op(void); 18asmlinkage void invalid_op(void);
14asmlinkage void device_not_available(void); 19asmlinkage void device_not_available(void);
20#ifdef CONFIG_X86_64
21asmlinkage void double_fault(void);
22#endif
15asmlinkage void coprocessor_segment_overrun(void); 23asmlinkage void coprocessor_segment_overrun(void);
16asmlinkage void invalid_TSS(void); 24asmlinkage void invalid_TSS(void);
17asmlinkage void segment_not_present(void); 25asmlinkage void segment_not_present(void);
18asmlinkage void stack_segment(void); 26asmlinkage void stack_segment(void);
19asmlinkage void general_protection(void); 27asmlinkage void general_protection(void);
20asmlinkage void page_fault(void); 28asmlinkage void page_fault(void);
29asmlinkage void spurious_interrupt_bug(void);
21asmlinkage void coprocessor_error(void); 30asmlinkage void coprocessor_error(void);
22asmlinkage void simd_coprocessor_error(void);
23asmlinkage void alignment_check(void); 31asmlinkage void alignment_check(void);
24asmlinkage void spurious_interrupt_bug(void);
25#ifdef CONFIG_X86_MCE 32#ifdef CONFIG_X86_MCE
26asmlinkage void machine_check(void); 33asmlinkage void machine_check(void);
27#endif /* CONFIG_X86_MCE */ 34#endif /* CONFIG_X86_MCE */
35asmlinkage void simd_coprocessor_error(void);
28 36
29void do_divide_error(struct pt_regs *, long); 37dotraplinkage void do_divide_error(struct pt_regs *, long);
30void do_overflow(struct pt_regs *, long); 38dotraplinkage void do_debug(struct pt_regs *, long);
31void do_bounds(struct pt_regs *, long); 39dotraplinkage void do_nmi(struct pt_regs *, long);
32void do_coprocessor_segment_overrun(struct pt_regs *, long); 40dotraplinkage void do_int3(struct pt_regs *, long);
33void do_invalid_TSS(struct pt_regs *, long); 41dotraplinkage void do_overflow(struct pt_regs *, long);
34void do_segment_not_present(struct pt_regs *, long); 42dotraplinkage void do_bounds(struct pt_regs *, long);
35void do_stack_segment(struct pt_regs *, long); 43dotraplinkage void do_invalid_op(struct pt_regs *, long);
36void do_alignment_check(struct pt_regs *, long); 44dotraplinkage void do_device_not_available(struct pt_regs *, long);
37void do_invalid_op(struct pt_regs *, long); 45dotraplinkage void do_coprocessor_segment_overrun(struct pt_regs *, long);
38void do_general_protection(struct pt_regs *, long); 46dotraplinkage void do_invalid_TSS(struct pt_regs *, long);
39void do_nmi(struct pt_regs *, long); 47dotraplinkage void do_segment_not_present(struct pt_regs *, long);
48dotraplinkage void do_stack_segment(struct pt_regs *, long);
49dotraplinkage void do_general_protection(struct pt_regs *, long);
50dotraplinkage void do_page_fault(struct pt_regs *, unsigned long);
51dotraplinkage void do_spurious_interrupt_bug(struct pt_regs *, long);
52dotraplinkage void do_coprocessor_error(struct pt_regs *, long);
53dotraplinkage void do_alignment_check(struct pt_regs *, long);
54#ifdef CONFIG_X86_MCE
55dotraplinkage void do_machine_check(struct pt_regs *, long);
56#endif
57dotraplinkage void do_simd_coprocessor_error(struct pt_regs *, long);
58#ifdef CONFIG_X86_32
59dotraplinkage void do_iret_error(struct pt_regs *, long);
60#endif
40 61
41static inline int get_si_code(unsigned long condition) 62static inline int get_si_code(unsigned long condition)
42{ 63{
@@ -52,31 +73,9 @@ extern int panic_on_unrecovered_nmi;
52extern int kstack_depth_to_print; 73extern int kstack_depth_to_print;
53 74
54#ifdef CONFIG_X86_32 75#ifdef CONFIG_X86_32
55
56void do_iret_error(struct pt_regs *, long);
57void do_int3(struct pt_regs *, long);
58void do_debug(struct pt_regs *, long);
59void math_error(void __user *); 76void math_error(void __user *);
60void do_coprocessor_error(struct pt_regs *, long);
61void do_simd_coprocessor_error(struct pt_regs *, long);
62void do_spurious_interrupt_bug(struct pt_regs *, long);
63unsigned long patch_espfix_desc(unsigned long, unsigned long); 77unsigned long patch_espfix_desc(unsigned long, unsigned long);
64asmlinkage void math_emulate(long); 78asmlinkage void math_emulate(long);
79#endif
65 80
66void do_page_fault(struct pt_regs *regs, unsigned long error_code);
67
68#else /* CONFIG_X86_32 */
69
70asmlinkage void double_fault(void);
71
72asmlinkage void do_int3(struct pt_regs *, long);
73asmlinkage void do_stack_segment(struct pt_regs *, long);
74asmlinkage void do_debug(struct pt_regs *, unsigned long);
75asmlinkage void do_coprocessor_error(struct pt_regs *);
76asmlinkage void do_simd_coprocessor_error(struct pt_regs *);
77asmlinkage void do_spurious_interrupt_bug(struct pt_regs *);
78
79asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code);
80
81#endif /* CONFIG_X86_32 */
82#endif /* ASM_X86__TRAPS_H */ 81#endif /* ASM_X86__TRAPS_H */
diff --git a/include/asm-xtensa/a.out.h b/include/asm-xtensa/a.out.h
deleted file mode 100644
index fdf13702924a..000000000000
--- a/include/asm-xtensa/a.out.h
+++ /dev/null
@@ -1,29 +0,0 @@
1/*
2 * include/asm-xtensa/a.out.h
3 *
4 * Dummy a.out file. Xtensa does not support the a.out format, but the kernel
5 * seems to depend on it.
6 *
7 * This file is subject to the terms and conditions of the GNU General Public
8 * License. See the file "COPYING" in the main directory of this archive
9 * for more details.
10 *
11 * Copyright (C) 2001 - 2005 Tensilica Inc.
12 */
13
14#ifndef _XTENSA_A_OUT_H
15#define _XTENSA_A_OUT_H
16
17struct exec
18{
19 unsigned long a_info;
20 unsigned a_text;
21 unsigned a_data;
22 unsigned a_bss;
23 unsigned a_syms;
24 unsigned a_entry;
25 unsigned a_trsize;
26 unsigned a_drsize;
27};
28
29#endif /* _XTENSA_A_OUT_H */
diff --git a/include/linux/devpts_fs.h b/include/linux/devpts_fs.h
index 154769cad3f3..5ce0e5fd712e 100644
--- a/include/linux/devpts_fs.h
+++ b/include/linux/devpts_fs.h
@@ -17,20 +17,31 @@
17 17
18#ifdef CONFIG_UNIX98_PTYS 18#ifdef CONFIG_UNIX98_PTYS
19 19
20int devpts_new_index(void); 20int devpts_new_index(struct inode *ptmx_inode);
21void devpts_kill_index(int idx); 21void devpts_kill_index(struct inode *ptmx_inode, int idx);
22int devpts_pty_new(struct tty_struct *tty); /* mknod in devpts */ 22/* mknod in devpts */
23struct tty_struct *devpts_get_tty(int number); /* get tty structure */ 23int devpts_pty_new(struct inode *ptmx_inode, struct tty_struct *tty);
24void devpts_pty_kill(int number); /* unlink */ 24/* get tty structure */
25struct tty_struct *devpts_get_tty(struct inode *pts_inode, int number);
26/* unlink */
27void devpts_pty_kill(struct tty_struct *tty);
25 28
26#else 29#else
27 30
28/* Dummy stubs in the no-pty case */ 31/* Dummy stubs in the no-pty case */
29static inline int devpts_new_index(void) { return -EINVAL; } 32static inline int devpts_new_index(struct inode *ptmx_inode) { return -EINVAL; }
30static inline void devpts_kill_index(int idx) { } 33static inline void devpts_kill_index(struct inode *ptmx_inode, int idx) { }
31static inline int devpts_pty_new(struct tty_struct *tty) { return -EINVAL; } 34static inline int devpts_pty_new(struct inode *ptmx_inode,
32static inline struct tty_struct *devpts_get_tty(int number) { return NULL; } 35 struct tty_struct *tty)
33static inline void devpts_pty_kill(int number) { } 36{
37 return -EINVAL;
38}
39static inline struct tty_struct *devpts_get_tty(struct inode *pts_inode,
40 int number)
41{
42 return NULL;
43}
44static inline void devpts_pty_kill(struct tty_struct *tty) { }
34 45
35#endif 46#endif
36 47
diff --git a/include/linux/dmi.h b/include/linux/dmi.h
index 2a063b64133f..e5084eb5943a 100644
--- a/include/linux/dmi.h
+++ b/include/linux/dmi.h
@@ -2,29 +2,9 @@
2#define __DMI_H__ 2#define __DMI_H__
3 3
4#include <linux/list.h> 4#include <linux/list.h>
5#include <linux/mod_devicetable.h>
5 6
6enum dmi_field { 7/* enum dmi_field is in mod_devicetable.h */
7 DMI_NONE,
8 DMI_BIOS_VENDOR,
9 DMI_BIOS_VERSION,
10 DMI_BIOS_DATE,
11 DMI_SYS_VENDOR,
12 DMI_PRODUCT_NAME,
13 DMI_PRODUCT_VERSION,
14 DMI_PRODUCT_SERIAL,
15 DMI_PRODUCT_UUID,
16 DMI_BOARD_VENDOR,
17 DMI_BOARD_NAME,
18 DMI_BOARD_VERSION,
19 DMI_BOARD_SERIAL,
20 DMI_BOARD_ASSET_TAG,
21 DMI_CHASSIS_VENDOR,
22 DMI_CHASSIS_TYPE,
23 DMI_CHASSIS_VERSION,
24 DMI_CHASSIS_SERIAL,
25 DMI_CHASSIS_ASSET_TAG,
26 DMI_STRING_MAX,
27};
28 8
29enum dmi_device_type { 9enum dmi_device_type {
30 DMI_DEV_TYPE_ANY = 0, 10 DMI_DEV_TYPE_ANY = 0,
@@ -48,23 +28,6 @@ struct dmi_header {
48 u16 handle; 28 u16 handle;
49}; 29};
50 30
51/*
52 * DMI callbacks for problem boards
53 */
54struct dmi_strmatch {
55 u8 slot;
56 char *substr;
57};
58
59struct dmi_system_id {
60 int (*callback)(const struct dmi_system_id *);
61 const char *ident;
62 struct dmi_strmatch matches[4];
63 void *driver_data;
64};
65
66#define DMI_MATCH(a, b) { a, b }
67
68struct dmi_device { 31struct dmi_device {
69 struct list_head list; 32 struct list_head list;
70 int type; 33 int type;
diff --git a/include/linux/hpet.h b/include/linux/hpet.h
index 2dc29ce6c8e4..79f63a27bcef 100644
--- a/include/linux/hpet.h
+++ b/include/linux/hpet.h
@@ -37,6 +37,7 @@ struct hpet {
37#define hpet_compare _u1._hpet_compare 37#define hpet_compare _u1._hpet_compare
38 38
39#define HPET_MAX_TIMERS (32) 39#define HPET_MAX_TIMERS (32)
40#define HPET_MAX_IRQ (32)
40 41
41/* 42/*
42 * HPET general capabilities register 43 * HPET general capabilities register
@@ -64,7 +65,7 @@ struct hpet {
64 */ 65 */
65 66
66#define Tn_INT_ROUTE_CAP_MASK (0xffffffff00000000ULL) 67#define Tn_INT_ROUTE_CAP_MASK (0xffffffff00000000ULL)
67#define Tn_INI_ROUTE_CAP_SHIFT (32UL) 68#define Tn_INT_ROUTE_CAP_SHIFT (32UL)
68#define Tn_FSB_INT_DELCAP_MASK (0x8000UL) 69#define Tn_FSB_INT_DELCAP_MASK (0x8000UL)
69#define Tn_FSB_INT_DELCAP_SHIFT (15) 70#define Tn_FSB_INT_DELCAP_SHIFT (15)
70#define Tn_FSB_EN_CNF_MASK (0x4000UL) 71#define Tn_FSB_EN_CNF_MASK (0x4000UL)
@@ -91,23 +92,14 @@ struct hpet {
91 * exported interfaces 92 * exported interfaces
92 */ 93 */
93 94
94struct hpet_task {
95 void (*ht_func) (void *);
96 void *ht_data;
97 void *ht_opaque;
98};
99
100struct hpet_data { 95struct hpet_data {
101 unsigned long hd_phys_address; 96 unsigned long hd_phys_address;
102 void __iomem *hd_address; 97 void __iomem *hd_address;
103 unsigned short hd_nirqs; 98 unsigned short hd_nirqs;
104 unsigned short hd_flags;
105 unsigned int hd_state; /* timer allocated */ 99 unsigned int hd_state; /* timer allocated */
106 unsigned int hd_irq[HPET_MAX_TIMERS]; 100 unsigned int hd_irq[HPET_MAX_TIMERS];
107}; 101};
108 102
109#define HPET_DATA_PLATFORM 0x0001 /* platform call to hpet_alloc */
110
111static inline void hpet_reserve_timer(struct hpet_data *hd, int timer) 103static inline void hpet_reserve_timer(struct hpet_data *hd, int timer)
112{ 104{
113 hd->hd_state |= (1 << timer); 105 hd->hd_state |= (1 << timer);
@@ -125,7 +117,7 @@ struct hpet_info {
125 unsigned short hi_timer; 117 unsigned short hi_timer;
126}; 118};
127 119
128#define HPET_INFO_PERIODIC 0x0001 /* timer is periodic */ 120#define HPET_INFO_PERIODIC 0x0010 /* periodic-capable comparator */
129 121
130#define HPET_IE_ON _IO('h', 0x01) /* interrupt on */ 122#define HPET_IE_ON _IO('h', 0x01) /* interrupt on */
131#define HPET_IE_OFF _IO('h', 0x02) /* interrupt off */ 123#define HPET_IE_OFF _IO('h', 0x02) /* interrupt off */
diff --git a/include/linux/magic.h b/include/linux/magic.h
index 1fa0c2ce4dec..f7f3fdddbef0 100644
--- a/include/linux/magic.h
+++ b/include/linux/magic.h
@@ -6,6 +6,10 @@
6#define AFS_SUPER_MAGIC 0x5346414F 6#define AFS_SUPER_MAGIC 0x5346414F
7#define AUTOFS_SUPER_MAGIC 0x0187 7#define AUTOFS_SUPER_MAGIC 0x0187
8#define CODA_SUPER_MAGIC 0x73757245 8#define CODA_SUPER_MAGIC 0x73757245
9#define DEBUGFS_MAGIC 0x64626720
10#define SYSFS_MAGIC 0x62656572
11#define SECURITYFS_MAGIC 0x73636673
12#define TMPFS_MAGIC 0x01021994
9#define EFS_SUPER_MAGIC 0x414A53 13#define EFS_SUPER_MAGIC 0x414A53
10#define EXT2_SUPER_MAGIC 0xEF53 14#define EXT2_SUPER_MAGIC 0xEF53
11#define EXT3_SUPER_MAGIC 0xEF53 15#define EXT3_SUPER_MAGIC 0xEF53
diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h
index c4db5827963d..3481a7d5bc0a 100644
--- a/include/linux/mod_devicetable.h
+++ b/include/linux/mod_devicetable.h
@@ -388,5 +388,52 @@ struct i2c_device_id {
388 __attribute__((aligned(sizeof(kernel_ulong_t)))); 388 __attribute__((aligned(sizeof(kernel_ulong_t))));
389}; 389};
390 390
391/* dmi */
392enum dmi_field {
393 DMI_NONE,
394 DMI_BIOS_VENDOR,
395 DMI_BIOS_VERSION,
396 DMI_BIOS_DATE,
397 DMI_SYS_VENDOR,
398 DMI_PRODUCT_NAME,
399 DMI_PRODUCT_VERSION,
400 DMI_PRODUCT_SERIAL,
401 DMI_PRODUCT_UUID,
402 DMI_BOARD_VENDOR,
403 DMI_BOARD_NAME,
404 DMI_BOARD_VERSION,
405 DMI_BOARD_SERIAL,
406 DMI_BOARD_ASSET_TAG,
407 DMI_CHASSIS_VENDOR,
408 DMI_CHASSIS_TYPE,
409 DMI_CHASSIS_VERSION,
410 DMI_CHASSIS_SERIAL,
411 DMI_CHASSIS_ASSET_TAG,
412 DMI_STRING_MAX,
413};
414
415struct dmi_strmatch {
416 unsigned char slot;
417 char substr[79];
418};
419
420#ifndef __KERNEL__
421struct dmi_system_id {
422 kernel_ulong_t callback;
423 kernel_ulong_t ident;
424 struct dmi_strmatch matches[4];
425 kernel_ulong_t driver_data
426 __attribute__((aligned(sizeof(kernel_ulong_t))));
427};
428#else
429struct dmi_system_id {
430 int (*callback)(const struct dmi_system_id *);
431 const char *ident;
432 struct dmi_strmatch matches[4];
433 void *driver_data;
434};
435#endif
436
437#define DMI_MATCH(a, b) { a, b }
391 438
392#endif /* LINUX_MOD_DEVICETABLE_H */ 439#endif /* LINUX_MOD_DEVICETABLE_H */
diff --git a/include/linux/oprofile.h b/include/linux/oprofile.h
index 041bb31100f4..bcb8f725427c 100644
--- a/include/linux/oprofile.h
+++ b/include/linux/oprofile.h
@@ -36,6 +36,8 @@
36#define XEN_ENTER_SWITCH_CODE 10 36#define XEN_ENTER_SWITCH_CODE 10
37#define SPU_PROFILING_CODE 11 37#define SPU_PROFILING_CODE 11
38#define SPU_CTX_SWITCH_CODE 12 38#define SPU_CTX_SWITCH_CODE 12
39#define IBS_FETCH_CODE 13
40#define IBS_OP_CODE 14
39 41
40struct super_block; 42struct super_block;
41struct dentry; 43struct dentry;
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index f63b5455801c..1176f1f177e2 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -1533,7 +1533,9 @@
1533#define PCI_DEVICE_ID_MARVELL_GT64260 0x6430 1533#define PCI_DEVICE_ID_MARVELL_GT64260 0x6430
1534#define PCI_DEVICE_ID_MARVELL_MV64360 0x6460 1534#define PCI_DEVICE_ID_MARVELL_MV64360 0x6460
1535#define PCI_DEVICE_ID_MARVELL_MV64460 0x6480 1535#define PCI_DEVICE_ID_MARVELL_MV64460 0x6480
1536#define PCI_DEVICE_ID_MARVELL_CAFE_SD 0x4101 1536#define PCI_DEVICE_ID_MARVELL_88ALP01_NAND 0x4100
1537#define PCI_DEVICE_ID_MARVELL_88ALP01_SD 0x4101
1538#define PCI_DEVICE_ID_MARVELL_88ALP01_CCIC 0x4102
1537 1539
1538#define PCI_VENDOR_ID_V3 0x11b0 1540#define PCI_VENDOR_ID_V3 0x11b0
1539#define PCI_DEVICE_ID_V3_V960 0x0001 1541#define PCI_DEVICE_ID_V3_V960 0x0001
diff --git a/include/linux/serial.h b/include/linux/serial.h
index deb714314fb1..1ea8d9265bf6 100644
--- a/include/linux/serial.h
+++ b/include/linux/serial.h
@@ -173,6 +173,22 @@ struct serial_icounter_struct {
173 int reserved[9]; 173 int reserved[9];
174}; 174};
175 175
176/*
177 * Serial interface for controlling RS485 settings on chips with suitable
178 * support. Set with TIOCSRS485 and get with TIOCGRS485 if supported by your
179 * platform. The set function returns the new state, with any unsupported bits
180 * reverted appropriately.
181 */
182
183struct serial_rs485 {
184 __u32 flags; /* RS485 feature flags */
185#define SER_RS485_ENABLED (1 << 0)
186#define SER_RS485_RTS_ON_SEND (1 << 1)
187#define SER_RS485_RTS_AFTER_SEND (1 << 2)
188 __u32 delay_rts_before_send; /* Milliseconds */
189 __u32 padding[6]; /* Memory is cheap, new structs
190 are a royal PITA .. */
191};
176 192
177#ifdef __KERNEL__ 193#ifdef __KERNEL__
178#include <linux/compiler.h> 194#include <linux/compiler.h>
diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h
index 3b2f6c04855e..e27f216361fc 100644
--- a/include/linux/serial_core.h
+++ b/include/linux/serial_core.h
@@ -241,7 +241,7 @@ typedef unsigned int __bitwise__ upf_t;
241 241
242struct uart_port { 242struct uart_port {
243 spinlock_t lock; /* port lock */ 243 spinlock_t lock; /* port lock */
244 unsigned int iobase; /* in/out[bwl] */ 244 unsigned long iobase; /* in/out[bwl] */
245 unsigned char __iomem *membase; /* read/write[bwl] */ 245 unsigned char __iomem *membase; /* read/write[bwl] */
246 unsigned int irq; /* irq number */ 246 unsigned int irq; /* irq number */
247 unsigned int uartclk; /* base uart clock */ 247 unsigned int uartclk; /* base uart clock */
diff --git a/include/linux/termios.h b/include/linux/termios.h
index 478662889f48..2acd0c1f8a2a 100644
--- a/include/linux/termios.h
+++ b/include/linux/termios.h
@@ -4,4 +4,19 @@
4#include <linux/types.h> 4#include <linux/types.h>
5#include <asm/termios.h> 5#include <asm/termios.h>
6 6
7#define NFF 5
8
9struct termiox
10{
11 __u16 x_hflag;
12 __u16 x_cflag;
13 __u16 x_rflag[NFF];
14 __u16 x_sflag;
15};
16
17#define RTSXOFF 0x0001 /* RTS flow control on input */
18#define CTSXON 0x0002 /* CTS flow control on output */
19#define DTRXOFF 0x0004 /* DTR flow control on input */
20#define DSRXON 0x0008 /* DCD flow control on output */
21
7#endif 22#endif
diff --git a/include/linux/tty.h b/include/linux/tty.h
index 0cbec74ec086..3b8121d4e36f 100644
--- a/include/linux/tty.h
+++ b/include/linux/tty.h
@@ -23,7 +23,7 @@
23 */ 23 */
24#define NR_UNIX98_PTY_DEFAULT 4096 /* Default maximum for Unix98 ptys */ 24#define NR_UNIX98_PTY_DEFAULT 4096 /* Default maximum for Unix98 ptys */
25#define NR_UNIX98_PTY_MAX (1 << MINORBITS) /* Absolute limit */ 25#define NR_UNIX98_PTY_MAX (1 << MINORBITS) /* Absolute limit */
26#define NR_LDISCS 18 26#define NR_LDISCS 19
27 27
28/* line disciplines */ 28/* line disciplines */
29#define N_TTY 0 29#define N_TTY 0
@@ -45,6 +45,7 @@
45#define N_HCI 15 /* Bluetooth HCI UART */ 45#define N_HCI 15 /* Bluetooth HCI UART */
46#define N_GIGASET_M101 16 /* Siemens Gigaset M101 serial DECT adapter */ 46#define N_GIGASET_M101 16 /* Siemens Gigaset M101 serial DECT adapter */
47#define N_SLCAN 17 /* Serial / USB serial CAN Adaptors */ 47#define N_SLCAN 17 /* Serial / USB serial CAN Adaptors */
48#define N_PPS 18 /* Pulse per Second */
48 49
49/* 50/*
50 * This character is the same as _POSIX_VDISABLE: it cannot be used as 51 * This character is the same as _POSIX_VDISABLE: it cannot be used as
@@ -181,6 +182,7 @@ struct signal_struct;
181 182
182struct tty_port { 183struct tty_port {
183 struct tty_struct *tty; /* Back pointer */ 184 struct tty_struct *tty; /* Back pointer */
185 spinlock_t lock; /* Lock protecting tty field */
184 int blocked_open; /* Waiting to open */ 186 int blocked_open; /* Waiting to open */
185 int count; /* Usage count */ 187 int count; /* Usage count */
186 wait_queue_head_t open_wait; /* Open waiters */ 188 wait_queue_head_t open_wait; /* Open waiters */
@@ -208,6 +210,7 @@ struct tty_operations;
208 210
209struct tty_struct { 211struct tty_struct {
210 int magic; 212 int magic;
213 struct kref kref;
211 struct tty_driver *driver; 214 struct tty_driver *driver;
212 const struct tty_operations *ops; 215 const struct tty_operations *ops;
213 int index; 216 int index;
@@ -217,6 +220,7 @@ struct tty_struct {
217 spinlock_t ctrl_lock; 220 spinlock_t ctrl_lock;
218 /* Termios values are protected by the termios mutex */ 221 /* Termios values are protected by the termios mutex */
219 struct ktermios *termios, *termios_locked; 222 struct ktermios *termios, *termios_locked;
223 struct termiox *termiox; /* May be NULL for unsupported */
220 char name[64]; 224 char name[64];
221 struct pid *pgrp; /* Protected by ctrl lock */ 225 struct pid *pgrp; /* Protected by ctrl lock */
222 struct pid *session; 226 struct pid *session;
@@ -310,6 +314,25 @@ extern int kmsg_redirect;
310extern void console_init(void); 314extern void console_init(void);
311extern int vcs_init(void); 315extern int vcs_init(void);
312 316
317extern struct class *tty_class;
318
319/**
320 * tty_kref_get - get a tty reference
321 * @tty: tty device
322 *
323 * Return a new reference to a tty object. The caller must hold
324 * sufficient locks/counts to ensure that their existing reference cannot
325 * go away
326 */
327
328extern inline struct tty_struct *tty_kref_get(struct tty_struct *tty)
329{
330 if (tty)
331 kref_get(&tty->kref);
332 return tty;
333}
334extern void tty_kref_put(struct tty_struct *tty);
335
313extern int tty_paranoia_check(struct tty_struct *tty, struct inode *inode, 336extern int tty_paranoia_check(struct tty_struct *tty, struct inode *inode,
314 const char *routine); 337 const char *routine);
315extern char *tty_name(struct tty_struct *tty, char *buf); 338extern char *tty_name(struct tty_struct *tty, char *buf);
@@ -333,13 +356,15 @@ extern void tty_throttle(struct tty_struct *tty);
333extern void tty_unthrottle(struct tty_struct *tty); 356extern void tty_unthrottle(struct tty_struct *tty);
334extern int tty_do_resize(struct tty_struct *tty, struct tty_struct *real_tty, 357extern int tty_do_resize(struct tty_struct *tty, struct tty_struct *real_tty,
335 struct winsize *ws); 358 struct winsize *ws);
336 359extern void tty_shutdown(struct tty_struct *tty);
360extern void tty_free_termios(struct tty_struct *tty);
337extern int is_current_pgrp_orphaned(void); 361extern int is_current_pgrp_orphaned(void);
338extern struct pid *tty_get_pgrp(struct tty_struct *tty); 362extern struct pid *tty_get_pgrp(struct tty_struct *tty);
339extern int is_ignored(int sig); 363extern int is_ignored(int sig);
340extern int tty_signal(int sig, struct tty_struct *tty); 364extern int tty_signal(int sig, struct tty_struct *tty);
341extern void tty_hangup(struct tty_struct *tty); 365extern void tty_hangup(struct tty_struct *tty);
342extern void tty_vhangup(struct tty_struct *tty); 366extern void tty_vhangup(struct tty_struct *tty);
367extern void tty_vhangup_self(void);
343extern void tty_unhangup(struct file *filp); 368extern void tty_unhangup(struct file *filp);
344extern int tty_hung_up_p(struct file *filp); 369extern int tty_hung_up_p(struct file *filp);
345extern void do_SAK(struct tty_struct *tty); 370extern void do_SAK(struct tty_struct *tty);
@@ -347,6 +372,9 @@ extern void __do_SAK(struct tty_struct *tty);
347extern void disassociate_ctty(int priv); 372extern void disassociate_ctty(int priv);
348extern void no_tty(void); 373extern void no_tty(void);
349extern void tty_flip_buffer_push(struct tty_struct *tty); 374extern void tty_flip_buffer_push(struct tty_struct *tty);
375extern void tty_buffer_free_all(struct tty_struct *tty);
376extern void tty_buffer_flush(struct tty_struct *tty);
377extern void tty_buffer_init(struct tty_struct *tty);
350extern speed_t tty_get_baud_rate(struct tty_struct *tty); 378extern speed_t tty_get_baud_rate(struct tty_struct *tty);
351extern speed_t tty_termios_baud_rate(struct ktermios *termios); 379extern speed_t tty_termios_baud_rate(struct ktermios *termios);
352extern speed_t tty_termios_input_baud_rate(struct ktermios *termios); 380extern speed_t tty_termios_input_baud_rate(struct ktermios *termios);
@@ -372,6 +400,15 @@ extern int tty_perform_flush(struct tty_struct *tty, unsigned long arg);
372extern dev_t tty_devnum(struct tty_struct *tty); 400extern dev_t tty_devnum(struct tty_struct *tty);
373extern void proc_clear_tty(struct task_struct *p); 401extern void proc_clear_tty(struct task_struct *p);
374extern struct tty_struct *get_current_tty(void); 402extern struct tty_struct *get_current_tty(void);
403extern void tty_default_fops(struct file_operations *fops);
404extern struct tty_struct *alloc_tty_struct(void);
405extern void free_tty_struct(struct tty_struct *tty);
406extern void initialize_tty_struct(struct tty_struct *tty,
407 struct tty_driver *driver, int idx);
408extern struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx,
409 int first_ok);
410extern void tty_release_dev(struct file *filp);
411extern int tty_init_termios(struct tty_struct *tty);
375 412
376extern struct mutex tty_mutex; 413extern struct mutex tty_mutex;
377 414
@@ -382,6 +419,8 @@ extern int tty_write_lock(struct tty_struct *tty, int ndelay);
382extern void tty_port_init(struct tty_port *port); 419extern void tty_port_init(struct tty_port *port);
383extern int tty_port_alloc_xmit_buf(struct tty_port *port); 420extern int tty_port_alloc_xmit_buf(struct tty_port *port);
384extern void tty_port_free_xmit_buf(struct tty_port *port); 421extern void tty_port_free_xmit_buf(struct tty_port *port);
422extern struct tty_struct *tty_port_tty_get(struct tty_port *port);
423extern void tty_port_tty_set(struct tty_port *port, struct tty_struct *tty);
385 424
386extern int tty_register_ldisc(int disc, struct tty_ldisc_ops *new_ldisc); 425extern int tty_register_ldisc(int disc, struct tty_ldisc_ops *new_ldisc);
387extern int tty_unregister_ldisc(int disc); 426extern int tty_unregister_ldisc(int disc);
@@ -427,7 +466,7 @@ static inline void tty_audit_push_task(struct task_struct *tsk,
427#endif 466#endif
428 467
429/* tty_ioctl.c */ 468/* tty_ioctl.c */
430extern int n_tty_ioctl(struct tty_struct *tty, struct file *file, 469extern int n_tty_ioctl_helper(struct tty_struct *tty, struct file *file,
431 unsigned int cmd, unsigned long arg); 470 unsigned int cmd, unsigned long arg);
432 471
433/* serial.c */ 472/* serial.c */
diff --git a/include/linux/tty_driver.h b/include/linux/tty_driver.h
index 16d27944c321..78416b901589 100644
--- a/include/linux/tty_driver.h
+++ b/include/linux/tty_driver.h
@@ -7,6 +7,28 @@
7 * defined; unless noted otherwise, they are optional, and can be 7 * defined; unless noted otherwise, they are optional, and can be
8 * filled in with a null pointer. 8 * filled in with a null pointer.
9 * 9 *
10 * struct tty_struct * (*lookup)(struct tty_driver *self, int idx)
11 *
12 * Return the tty device corresponding to idx, NULL if there is not
13 * one currently in use and an ERR_PTR value on error. Called under
14 * tty_mutex (for now!)
15 *
16 * Optional method. Default behaviour is to use the ttys array
17 *
18 * int (*install)(struct tty_driver *self, struct tty_struct *tty)
19 *
20 * Install a new tty into the tty driver internal tables. Used in
21 * conjunction with lookup and remove methods.
22 *
23 * Optional method. Default behaviour is to use the ttys array
24 *
25 * void (*remove)(struct tty_driver *self, struct tty_struct *tty)
26 *
27 * Remove a closed tty from the tty driver internal tables. Used in
28 * conjunction with lookup and remove methods.
29 *
30 * Optional method. Default behaviour is to use the ttys array
31 *
10 * int (*open)(struct tty_struct * tty, struct file * filp); 32 * int (*open)(struct tty_struct * tty, struct file * filp);
11 * 33 *
12 * This routine is called when a particular tty device is opened. 34 * This routine is called when a particular tty device is opened.
@@ -21,6 +43,11 @@
21 * 43 *
22 * Required method. 44 * Required method.
23 * 45 *
46 * void (*shutdown)(struct tty_struct * tty);
47 *
48 * This routine is called when a particular tty device is closed for
49 * the last time freeing up the resources.
50 *
24 * int (*write)(struct tty_struct * tty, 51 * int (*write)(struct tty_struct * tty,
25 * const unsigned char *buf, int count); 52 * const unsigned char *buf, int count);
26 * 53 *
@@ -180,6 +207,14 @@
180 * not force errors here if they are not resizable objects (eg a serial 207 * not force errors here if they are not resizable objects (eg a serial
181 * line). See tty_do_resize() if you need to wrap the standard method 208 * line). See tty_do_resize() if you need to wrap the standard method
182 * in your own logic - the usual case. 209 * in your own logic - the usual case.
210 *
211 * void (*set_termiox)(struct tty_struct *tty, struct termiox *new);
212 *
213 * Called when the device receives a termiox based ioctl. Passes down
214 * the requested data from user space. This method will not be invoked
215 * unless the tty also has a valid tty->termiox pointer.
216 *
217 * Optional: Called under the termios lock
183 */ 218 */
184 219
185#include <linux/fs.h> 220#include <linux/fs.h>
@@ -190,8 +225,13 @@ struct tty_struct;
190struct tty_driver; 225struct tty_driver;
191 226
192struct tty_operations { 227struct tty_operations {
228 struct tty_struct * (*lookup)(struct tty_driver *driver,
229 struct inode *inode, int idx);
230 int (*install)(struct tty_driver *driver, struct tty_struct *tty);
231 void (*remove)(struct tty_driver *driver, struct tty_struct *tty);
193 int (*open)(struct tty_struct * tty, struct file * filp); 232 int (*open)(struct tty_struct * tty, struct file * filp);
194 void (*close)(struct tty_struct * tty, struct file * filp); 233 void (*close)(struct tty_struct * tty, struct file * filp);
234 void (*shutdown)(struct tty_struct *tty);
195 int (*write)(struct tty_struct * tty, 235 int (*write)(struct tty_struct * tty,
196 const unsigned char *buf, int count); 236 const unsigned char *buf, int count);
197 int (*put_char)(struct tty_struct *tty, unsigned char ch); 237 int (*put_char)(struct tty_struct *tty, unsigned char ch);
@@ -220,6 +260,7 @@ struct tty_operations {
220 unsigned int set, unsigned int clear); 260 unsigned int set, unsigned int clear);
221 int (*resize)(struct tty_struct *tty, struct tty_struct *real_tty, 261 int (*resize)(struct tty_struct *tty, struct tty_struct *real_tty,
222 struct winsize *ws); 262 struct winsize *ws);
263 int (*set_termiox)(struct tty_struct *tty, struct termiox *tnew);
223#ifdef CONFIG_CONSOLE_POLL 264#ifdef CONFIG_CONSOLE_POLL
224 int (*poll_init)(struct tty_driver *driver, int line, char *options); 265 int (*poll_init)(struct tty_driver *driver, int line, char *options);
225 int (*poll_get_char)(struct tty_driver *driver, int line); 266 int (*poll_get_char)(struct tty_driver *driver, int line);
@@ -229,6 +270,7 @@ struct tty_operations {
229 270
230struct tty_driver { 271struct tty_driver {
231 int magic; /* magic number for this structure */ 272 int magic; /* magic number for this structure */
273 struct kref kref; /* Reference management */
232 struct cdev cdev; 274 struct cdev cdev;
233 struct module *owner; 275 struct module *owner;
234 const char *driver_name; 276 const char *driver_name;
@@ -242,7 +284,6 @@ struct tty_driver {
242 short subtype; /* subtype of tty driver */ 284 short subtype; /* subtype of tty driver */
243 struct ktermios init_termios; /* Initial termios */ 285 struct ktermios init_termios; /* Initial termios */
244 int flags; /* tty driver flags */ 286 int flags; /* tty driver flags */
245 int refcount; /* for loadable tty drivers */
246 struct proc_dir_entry *proc_entry; /* /proc fs entry */ 287 struct proc_dir_entry *proc_entry; /* /proc fs entry */
247 struct tty_driver *other; /* only used for the PTY driver */ 288 struct tty_driver *other; /* only used for the PTY driver */
248 289
@@ -264,12 +305,19 @@ struct tty_driver {
264 305
265extern struct list_head tty_drivers; 306extern struct list_head tty_drivers;
266 307
267struct tty_driver *alloc_tty_driver(int lines); 308extern struct tty_driver *alloc_tty_driver(int lines);
268void put_tty_driver(struct tty_driver *driver); 309extern void put_tty_driver(struct tty_driver *driver);
269void tty_set_operations(struct tty_driver *driver, 310extern void tty_set_operations(struct tty_driver *driver,
270 const struct tty_operations *op); 311 const struct tty_operations *op);
271extern struct tty_driver *tty_find_polling_driver(char *name, int *line); 312extern struct tty_driver *tty_find_polling_driver(char *name, int *line);
272 313
314extern void tty_driver_kref_put(struct tty_driver *driver);
315extern inline struct tty_driver *tty_driver_kref_get(struct tty_driver *d)
316{
317 kref_get(&d->kref);
318 return d;
319}
320
273/* tty driver magic number */ 321/* tty driver magic number */
274#define TTY_DRIVER_MAGIC 0x5402 322#define TTY_DRIVER_MAGIC 0x5402
275 323
diff --git a/include/linux/vt_kern.h b/include/linux/vt_kern.h
index 1cbd0a7db4e6..2f1113467f70 100644
--- a/include/linux/vt_kern.h
+++ b/include/linux/vt_kern.h
@@ -96,7 +96,7 @@ void change_console(struct vc_data *new_vc);
96void reset_vc(struct vc_data *vc); 96void reset_vc(struct vc_data *vc);
97extern int unbind_con_driver(const struct consw *csw, int first, int last, 97extern int unbind_con_driver(const struct consw *csw, int first, int last,
98 int deflt); 98 int deflt);
99int vty_init(void); 99int vty_init(const struct file_operations *console_fops);
100 100
101/* 101/*
102 * vc_screen.c shares this temporary buffer with the console write code so that 102 * vc_screen.c shares this temporary buffer with the console write code so that
diff --git a/include/net/cipso_ipv4.h b/include/net/cipso_ipv4.h
index a6bb94530cfd..9909774eb998 100644
--- a/include/net/cipso_ipv4.h
+++ b/include/net/cipso_ipv4.h
@@ -40,11 +40,12 @@
40#include <linux/net.h> 40#include <linux/net.h>
41#include <linux/skbuff.h> 41#include <linux/skbuff.h>
42#include <net/netlabel.h> 42#include <net/netlabel.h>
43#include <asm/atomic.h>
43 44
44/* known doi values */ 45/* known doi values */
45#define CIPSO_V4_DOI_UNKNOWN 0x00000000 46#define CIPSO_V4_DOI_UNKNOWN 0x00000000
46 47
47/* tag types */ 48/* standard tag types */
48#define CIPSO_V4_TAG_INVALID 0 49#define CIPSO_V4_TAG_INVALID 0
49#define CIPSO_V4_TAG_RBITMAP 1 50#define CIPSO_V4_TAG_RBITMAP 1
50#define CIPSO_V4_TAG_ENUM 2 51#define CIPSO_V4_TAG_ENUM 2
@@ -52,10 +53,14 @@
52#define CIPSO_V4_TAG_PBITMAP 6 53#define CIPSO_V4_TAG_PBITMAP 6
53#define CIPSO_V4_TAG_FREEFORM 7 54#define CIPSO_V4_TAG_FREEFORM 7
54 55
56/* non-standard tag types (tags > 127) */
57#define CIPSO_V4_TAG_LOCAL 128
58
55/* doi mapping types */ 59/* doi mapping types */
56#define CIPSO_V4_MAP_UNKNOWN 0 60#define CIPSO_V4_MAP_UNKNOWN 0
57#define CIPSO_V4_MAP_STD 1 61#define CIPSO_V4_MAP_TRANS 1
58#define CIPSO_V4_MAP_PASS 2 62#define CIPSO_V4_MAP_PASS 2
63#define CIPSO_V4_MAP_LOCAL 3
59 64
60/* limits */ 65/* limits */
61#define CIPSO_V4_MAX_REM_LVLS 255 66#define CIPSO_V4_MAX_REM_LVLS 255
@@ -79,10 +84,9 @@ struct cipso_v4_doi {
79 } map; 84 } map;
80 u8 tags[CIPSO_V4_TAG_MAXCNT]; 85 u8 tags[CIPSO_V4_TAG_MAXCNT];
81 86
82 u32 valid; 87 atomic_t refcount;
83 struct list_head list; 88 struct list_head list;
84 struct rcu_head rcu; 89 struct rcu_head rcu;
85 struct list_head dom_list;
86}; 90};
87 91
88/* Standard CIPSO mapping table */ 92/* Standard CIPSO mapping table */
@@ -128,25 +132,26 @@ extern int cipso_v4_rbm_strictvalid;
128 132
129#ifdef CONFIG_NETLABEL 133#ifdef CONFIG_NETLABEL
130int cipso_v4_doi_add(struct cipso_v4_doi *doi_def); 134int cipso_v4_doi_add(struct cipso_v4_doi *doi_def);
131int cipso_v4_doi_remove(u32 doi, 135void cipso_v4_doi_free(struct cipso_v4_doi *doi_def);
132 struct netlbl_audit *audit_info, 136int cipso_v4_doi_remove(u32 doi, struct netlbl_audit *audit_info);
133 void (*callback) (struct rcu_head * head));
134struct cipso_v4_doi *cipso_v4_doi_getdef(u32 doi); 137struct cipso_v4_doi *cipso_v4_doi_getdef(u32 doi);
138void cipso_v4_doi_putdef(struct cipso_v4_doi *doi_def);
135int cipso_v4_doi_walk(u32 *skip_cnt, 139int cipso_v4_doi_walk(u32 *skip_cnt,
136 int (*callback) (struct cipso_v4_doi *doi_def, void *arg), 140 int (*callback) (struct cipso_v4_doi *doi_def, void *arg),
137 void *cb_arg); 141 void *cb_arg);
138int cipso_v4_doi_domhsh_add(struct cipso_v4_doi *doi_def, const char *domain);
139int cipso_v4_doi_domhsh_remove(struct cipso_v4_doi *doi_def,
140 const char *domain);
141#else 142#else
142static inline int cipso_v4_doi_add(struct cipso_v4_doi *doi_def) 143static inline int cipso_v4_doi_add(struct cipso_v4_doi *doi_def)
143{ 144{
144 return -ENOSYS; 145 return -ENOSYS;
145} 146}
146 147
148static inline void cipso_v4_doi_free(struct cipso_v4_doi *doi_def)
149{
150 return;
151}
152
147static inline int cipso_v4_doi_remove(u32 doi, 153static inline int cipso_v4_doi_remove(u32 doi,
148 struct netlbl_audit *audit_info, 154 struct netlbl_audit *audit_info)
149 void (*callback) (struct rcu_head * head))
150{ 155{
151 return 0; 156 return 0;
152} 157}
@@ -206,10 +211,15 @@ void cipso_v4_error(struct sk_buff *skb, int error, u32 gateway);
206int cipso_v4_sock_setattr(struct sock *sk, 211int cipso_v4_sock_setattr(struct sock *sk,
207 const struct cipso_v4_doi *doi_def, 212 const struct cipso_v4_doi *doi_def,
208 const struct netlbl_lsm_secattr *secattr); 213 const struct netlbl_lsm_secattr *secattr);
214void cipso_v4_sock_delattr(struct sock *sk);
209int cipso_v4_sock_getattr(struct sock *sk, struct netlbl_lsm_secattr *secattr); 215int cipso_v4_sock_getattr(struct sock *sk, struct netlbl_lsm_secattr *secattr);
216int cipso_v4_skbuff_setattr(struct sk_buff *skb,
217 const struct cipso_v4_doi *doi_def,
218 const struct netlbl_lsm_secattr *secattr);
219int cipso_v4_skbuff_delattr(struct sk_buff *skb);
210int cipso_v4_skbuff_getattr(const struct sk_buff *skb, 220int cipso_v4_skbuff_getattr(const struct sk_buff *skb,
211 struct netlbl_lsm_secattr *secattr); 221 struct netlbl_lsm_secattr *secattr);
212int cipso_v4_validate(unsigned char **option); 222int cipso_v4_validate(const struct sk_buff *skb, unsigned char **option);
213#else 223#else
214static inline void cipso_v4_error(struct sk_buff *skb, 224static inline void cipso_v4_error(struct sk_buff *skb,
215 int error, 225 int error,
@@ -225,19 +235,36 @@ static inline int cipso_v4_sock_setattr(struct sock *sk,
225 return -ENOSYS; 235 return -ENOSYS;
226} 236}
227 237
238static inline void cipso_v4_sock_delattr(struct sock *sk)
239{
240}
241
228static inline int cipso_v4_sock_getattr(struct sock *sk, 242static inline int cipso_v4_sock_getattr(struct sock *sk,
229 struct netlbl_lsm_secattr *secattr) 243 struct netlbl_lsm_secattr *secattr)
230{ 244{
231 return -ENOSYS; 245 return -ENOSYS;
232} 246}
233 247
248static inline int cipso_v4_skbuff_setattr(struct sk_buff *skb,
249 const struct cipso_v4_doi *doi_def,
250 const struct netlbl_lsm_secattr *secattr)
251{
252 return -ENOSYS;
253}
254
255static inline int cipso_v4_skbuff_delattr(struct sk_buff *skb)
256{
257 return -ENOSYS;
258}
259
234static inline int cipso_v4_skbuff_getattr(const struct sk_buff *skb, 260static inline int cipso_v4_skbuff_getattr(const struct sk_buff *skb,
235 struct netlbl_lsm_secattr *secattr) 261 struct netlbl_lsm_secattr *secattr)
236{ 262{
237 return -ENOSYS; 263 return -ENOSYS;
238} 264}
239 265
240static inline int cipso_v4_validate(unsigned char **option) 266static inline int cipso_v4_validate(const struct sk_buff *skb,
267 unsigned char **option)
241{ 268{
242 return -ENOSYS; 269 return -ENOSYS;
243} 270}
diff --git a/include/net/netlabel.h b/include/net/netlabel.h
index e4d2d6baa983..17c442a4514e 100644
--- a/include/net/netlabel.h
+++ b/include/net/netlabel.h
@@ -9,7 +9,7 @@
9 */ 9 */
10 10
11/* 11/*
12 * (c) Copyright Hewlett-Packard Development Company, L.P., 2006 12 * (c) Copyright Hewlett-Packard Development Company, L.P., 2006, 2008
13 * 13 *
14 * This program is free software; you can redistribute it and/or modify 14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by 15 * it under the terms of the GNU General Public License as published by
@@ -72,8 +72,10 @@ struct cipso_v4_doi;
72/* NetLabel NETLINK protocol version 72/* NetLabel NETLINK protocol version
73 * 1: initial version 73 * 1: initial version
74 * 2: added static labels for unlabeled connections 74 * 2: added static labels for unlabeled connections
75 * 3: network selectors added to the NetLabel/LSM domain mapping and the
76 * CIPSO_V4_MAP_LOCAL CIPSO mapping was added
75 */ 77 */
76#define NETLBL_PROTO_VERSION 2 78#define NETLBL_PROTO_VERSION 3
77 79
78/* NetLabel NETLINK types/families */ 80/* NetLabel NETLINK types/families */
79#define NETLBL_NLTYPE_NONE 0 81#define NETLBL_NLTYPE_NONE 0
@@ -87,6 +89,8 @@ struct cipso_v4_doi;
87#define NETLBL_NLTYPE_CIPSOV6_NAME "NLBL_CIPSOv6" 89#define NETLBL_NLTYPE_CIPSOV6_NAME "NLBL_CIPSOv6"
88#define NETLBL_NLTYPE_UNLABELED 5 90#define NETLBL_NLTYPE_UNLABELED 5
89#define NETLBL_NLTYPE_UNLABELED_NAME "NLBL_UNLBL" 91#define NETLBL_NLTYPE_UNLABELED_NAME "NLBL_UNLBL"
92#define NETLBL_NLTYPE_ADDRSELECT 6
93#define NETLBL_NLTYPE_ADDRSELECT_NAME "NLBL_ADRSEL"
90 94
91/* 95/*
92 * NetLabel - Kernel API for accessing the network packet label mappings. 96 * NetLabel - Kernel API for accessing the network packet label mappings.
@@ -200,7 +204,7 @@ struct netlbl_lsm_secattr {
200 u32 type; 204 u32 type;
201 char *domain; 205 char *domain;
202 struct netlbl_lsm_cache *cache; 206 struct netlbl_lsm_cache *cache;
203 union { 207 struct {
204 struct { 208 struct {
205 struct netlbl_lsm_secattr_catmap *cat; 209 struct netlbl_lsm_secattr_catmap *cat;
206 u32 lvl; 210 u32 lvl;
@@ -352,12 +356,9 @@ static inline void netlbl_secattr_free(struct netlbl_lsm_secattr *secattr)
352int netlbl_cfg_map_del(const char *domain, struct netlbl_audit *audit_info); 356int netlbl_cfg_map_del(const char *domain, struct netlbl_audit *audit_info);
353int netlbl_cfg_unlbl_add_map(const char *domain, 357int netlbl_cfg_unlbl_add_map(const char *domain,
354 struct netlbl_audit *audit_info); 358 struct netlbl_audit *audit_info);
355int netlbl_cfg_cipsov4_add(struct cipso_v4_doi *doi_def,
356 struct netlbl_audit *audit_info);
357int netlbl_cfg_cipsov4_add_map(struct cipso_v4_doi *doi_def, 359int netlbl_cfg_cipsov4_add_map(struct cipso_v4_doi *doi_def,
358 const char *domain, 360 const char *domain,
359 struct netlbl_audit *audit_info); 361 struct netlbl_audit *audit_info);
360int netlbl_cfg_cipsov4_del(u32 doi, struct netlbl_audit *audit_info);
361 362
362/* 363/*
363 * LSM security attribute operations 364 * LSM security attribute operations
@@ -380,12 +381,19 @@ int netlbl_secattr_catmap_setrng(struct netlbl_lsm_secattr_catmap *catmap,
380int netlbl_enabled(void); 381int netlbl_enabled(void);
381int netlbl_sock_setattr(struct sock *sk, 382int netlbl_sock_setattr(struct sock *sk,
382 const struct netlbl_lsm_secattr *secattr); 383 const struct netlbl_lsm_secattr *secattr);
384void netlbl_sock_delattr(struct sock *sk);
383int netlbl_sock_getattr(struct sock *sk, 385int netlbl_sock_getattr(struct sock *sk,
384 struct netlbl_lsm_secattr *secattr); 386 struct netlbl_lsm_secattr *secattr);
387int netlbl_conn_setattr(struct sock *sk,
388 struct sockaddr *addr,
389 const struct netlbl_lsm_secattr *secattr);
390int netlbl_skbuff_setattr(struct sk_buff *skb,
391 u16 family,
392 const struct netlbl_lsm_secattr *secattr);
385int netlbl_skbuff_getattr(const struct sk_buff *skb, 393int netlbl_skbuff_getattr(const struct sk_buff *skb,
386 u16 family, 394 u16 family,
387 struct netlbl_lsm_secattr *secattr); 395 struct netlbl_lsm_secattr *secattr);
388void netlbl_skbuff_err(struct sk_buff *skb, int error); 396void netlbl_skbuff_err(struct sk_buff *skb, int error, int gateway);
389 397
390/* 398/*
391 * LSM label mapping cache operations 399 * LSM label mapping cache operations
@@ -404,22 +412,12 @@ static inline int netlbl_cfg_unlbl_add_map(const char *domain,
404{ 412{
405 return -ENOSYS; 413 return -ENOSYS;
406} 414}
407static inline int netlbl_cfg_cipsov4_add(struct cipso_v4_doi *doi_def,
408 struct netlbl_audit *audit_info)
409{
410 return -ENOSYS;
411}
412static inline int netlbl_cfg_cipsov4_add_map(struct cipso_v4_doi *doi_def, 415static inline int netlbl_cfg_cipsov4_add_map(struct cipso_v4_doi *doi_def,
413 const char *domain, 416 const char *domain,
414 struct netlbl_audit *audit_info) 417 struct netlbl_audit *audit_info)
415{ 418{
416 return -ENOSYS; 419 return -ENOSYS;
417} 420}
418static inline int netlbl_cfg_cipsov4_del(u32 doi,
419 struct netlbl_audit *audit_info)
420{
421 return -ENOSYS;
422}
423static inline int netlbl_secattr_catmap_walk( 421static inline int netlbl_secattr_catmap_walk(
424 struct netlbl_lsm_secattr_catmap *catmap, 422 struct netlbl_lsm_secattr_catmap *catmap,
425 u32 offset) 423 u32 offset)
@@ -456,18 +454,35 @@ static inline int netlbl_sock_setattr(struct sock *sk,
456{ 454{
457 return -ENOSYS; 455 return -ENOSYS;
458} 456}
457static inline void netlbl_sock_delattr(struct sock *sk)
458{
459}
459static inline int netlbl_sock_getattr(struct sock *sk, 460static inline int netlbl_sock_getattr(struct sock *sk,
460 struct netlbl_lsm_secattr *secattr) 461 struct netlbl_lsm_secattr *secattr)
461{ 462{
462 return -ENOSYS; 463 return -ENOSYS;
463} 464}
465static inline int netlbl_conn_setattr(struct sock *sk,
466 struct sockaddr *addr,
467 const struct netlbl_lsm_secattr *secattr)
468{
469 return -ENOSYS;
470}
471static inline int netlbl_skbuff_setattr(struct sk_buff *skb,
472 u16 family,
473 const struct netlbl_lsm_secattr *secattr)
474{
475 return -ENOSYS;
476}
464static inline int netlbl_skbuff_getattr(const struct sk_buff *skb, 477static inline int netlbl_skbuff_getattr(const struct sk_buff *skb,
465 u16 family, 478 u16 family,
466 struct netlbl_lsm_secattr *secattr) 479 struct netlbl_lsm_secattr *secattr)
467{ 480{
468 return -ENOSYS; 481 return -ENOSYS;
469} 482}
470static inline void netlbl_skbuff_err(struct sk_buff *skb, int error) 483static inline void netlbl_skbuff_err(struct sk_buff *skb,
484 int error,
485 int gateway)
471{ 486{
472 return; 487 return;
473} 488}
diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h
index c1b26fcc0b5c..ca699a3017f3 100644
--- a/include/sound/soc-dapm.h
+++ b/include/sound/soc-dapm.h
@@ -240,6 +240,7 @@ int snd_soc_dapm_sys_add(struct device *dev);
240/* dapm audio pin control and status */ 240/* dapm audio pin control and status */
241int snd_soc_dapm_enable_pin(struct snd_soc_codec *codec, char *pin); 241int snd_soc_dapm_enable_pin(struct snd_soc_codec *codec, char *pin);
242int snd_soc_dapm_disable_pin(struct snd_soc_codec *codec, char *pin); 242int snd_soc_dapm_disable_pin(struct snd_soc_codec *codec, char *pin);
243int snd_soc_dapm_nc_pin(struct snd_soc_codec *codec, char *pin);
243int snd_soc_dapm_get_pin_status(struct snd_soc_codec *codec, char *pin); 244int snd_soc_dapm_get_pin_status(struct snd_soc_codec *codec, char *pin);
244int snd_soc_dapm_sync(struct snd_soc_codec *codec); 245int snd_soc_dapm_sync(struct snd_soc_codec *codec);
245 246
diff --git a/init/Kconfig b/init/Kconfig
index c11da38837e5..8a8e2d00c40e 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -779,16 +779,6 @@ config MARKERS
779 779
780source "arch/Kconfig" 780source "arch/Kconfig"
781 781
782config PROC_PAGE_MONITOR
783 default y
784 depends on PROC_FS && MMU
785 bool "Enable /proc page monitoring" if EMBEDDED
786 help
787 Various /proc files exist to monitor process memory utilization:
788 /proc/pid/smaps, /proc/pid/clear_refs, /proc/pid/pagemap,
789 /proc/kpagecount, and /proc/kpageflags. Disabling these
790 interfaces will reduce the size of the kernel by approximately 4kb.
791
792endmenu # General setup 782endmenu # General setup
793 783
794config HAVE_GENERIC_DMA_COHERENT 784config HAVE_GENERIC_DMA_COHERENT
diff --git a/kernel/acct.c b/kernel/acct.c
index dd68b9059418..f6006a60df5d 100644
--- a/kernel/acct.c
+++ b/kernel/acct.c
@@ -548,7 +548,7 @@ static void do_acct_process(struct bsd_acct_struct *acct,
548#endif 548#endif
549 549
550 spin_lock_irq(&current->sighand->siglock); 550 spin_lock_irq(&current->sighand->siglock);
551 tty = current->signal->tty; 551 tty = current->signal->tty; /* Safe as we hold the siglock */
552 ac.ac_tty = tty ? old_encode_dev(tty_devnum(tty)) : 0; 552 ac.ac_tty = tty ? old_encode_dev(tty_devnum(tty)) : 0;
553 ac.ac_utime = encode_comp_t(jiffies_to_AHZ(cputime_to_jiffies(pacct->ac_utime))); 553 ac.ac_utime = encode_comp_t(jiffies_to_AHZ(cputime_to_jiffies(pacct->ac_utime)));
554 ac.ac_stime = encode_comp_t(jiffies_to_AHZ(cputime_to_jiffies(pacct->ac_stime))); 554 ac.ac_stime = encode_comp_t(jiffies_to_AHZ(cputime_to_jiffies(pacct->ac_stime)));
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index 59cedfb040e7..cf5bc2f5f9c3 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -246,8 +246,8 @@ static int audit_match_perm(struct audit_context *ctx, int mask)
246 unsigned n; 246 unsigned n;
247 if (unlikely(!ctx)) 247 if (unlikely(!ctx))
248 return 0; 248 return 0;
249
250 n = ctx->major; 249 n = ctx->major;
250
251 switch (audit_classify_syscall(ctx->arch, n)) { 251 switch (audit_classify_syscall(ctx->arch, n)) {
252 case 0: /* native */ 252 case 0: /* native */
253 if ((mask & AUDIT_PERM_WRITE) && 253 if ((mask & AUDIT_PERM_WRITE) &&
@@ -1204,13 +1204,13 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts
1204 (context->return_valid==AUDITSC_SUCCESS)?"yes":"no", 1204 (context->return_valid==AUDITSC_SUCCESS)?"yes":"no",
1205 context->return_code); 1205 context->return_code);
1206 1206
1207 mutex_lock(&tty_mutex); 1207 spin_lock_irq(&tsk->sighand->siglock);
1208 read_lock(&tasklist_lock);
1209 if (tsk->signal && tsk->signal->tty && tsk->signal->tty->name) 1208 if (tsk->signal && tsk->signal->tty && tsk->signal->tty->name)
1210 tty = tsk->signal->tty->name; 1209 tty = tsk->signal->tty->name;
1211 else 1210 else
1212 tty = "(none)"; 1211 tty = "(none)";
1213 read_unlock(&tasklist_lock); 1212 spin_unlock_irq(&tsk->sighand->siglock);
1213
1214 audit_log_format(ab, 1214 audit_log_format(ab,
1215 " a0=%lx a1=%lx a2=%lx a3=%lx items=%d" 1215 " a0=%lx a1=%lx a2=%lx a3=%lx items=%d"
1216 " ppid=%d pid=%d auid=%u uid=%u gid=%u" 1216 " ppid=%d pid=%d auid=%u uid=%u gid=%u"
@@ -1230,7 +1230,6 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts
1230 context->egid, context->sgid, context->fsgid, tty, 1230 context->egid, context->sgid, context->fsgid, tty,
1231 tsk->sessionid); 1231 tsk->sessionid);
1232 1232
1233 mutex_unlock(&tty_mutex);
1234 1233
1235 audit_log_task_info(ab, tsk); 1234 audit_log_task_info(ab, tsk);
1236 if (context->filterkey) { 1235 if (context->filterkey) {
diff --git a/kernel/fork.c b/kernel/fork.c
index 7ce2ebe84796..30de644a40c4 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -802,6 +802,7 @@ static int copy_signal(unsigned long clone_flags, struct task_struct *tsk)
802 802
803 sig->leader = 0; /* session leadership doesn't inherit */ 803 sig->leader = 0; /* session leadership doesn't inherit */
804 sig->tty_old_pgrp = NULL; 804 sig->tty_old_pgrp = NULL;
805 sig->tty = NULL;
805 806
806 sig->utime = sig->stime = sig->cutime = sig->cstime = cputime_zero; 807 sig->utime = sig->stime = sig->cutime = sig->cstime = cputime_zero;
807 sig->gtime = cputime_zero; 808 sig->gtime = cputime_zero;
@@ -838,6 +839,7 @@ static int copy_signal(unsigned long clone_flags, struct task_struct *tsk)
838void __cleanup_signal(struct signal_struct *sig) 839void __cleanup_signal(struct signal_struct *sig)
839{ 840{
840 exit_thread_group_keys(sig); 841 exit_thread_group_keys(sig);
842 tty_kref_put(sig->tty);
841 kmem_cache_free(signal_cachep, sig); 843 kmem_cache_free(signal_cachep, sig);
842} 844}
843 845
@@ -1227,7 +1229,8 @@ static struct task_struct *copy_process(unsigned long clone_flags,
1227 p->nsproxy->pid_ns->child_reaper = p; 1229 p->nsproxy->pid_ns->child_reaper = p;
1228 1230
1229 p->signal->leader_pid = pid; 1231 p->signal->leader_pid = pid;
1230 p->signal->tty = current->signal->tty; 1232 tty_kref_put(p->signal->tty);
1233 p->signal->tty = tty_kref_get(current->signal->tty);
1231 set_task_pgrp(p, task_pgrp_nr(current)); 1234 set_task_pgrp(p, task_pgrp_nr(current));
1232 set_task_session(p, task_session_nr(current)); 1235 set_task_session(p, task_session_nr(current));
1233 attach_pid(p, PIDTYPE_PGID, task_pgrp(current)); 1236 attach_pid(p, PIDTYPE_PGID, task_pgrp(current));
diff --git a/kernel/printk.c b/kernel/printk.c
index b51b1567bb55..a430fd04008b 100644
--- a/kernel/printk.c
+++ b/kernel/printk.c
@@ -1291,22 +1291,6 @@ static int __init disable_boot_consoles(void)
1291} 1291}
1292late_initcall(disable_boot_consoles); 1292late_initcall(disable_boot_consoles);
1293 1293
1294/**
1295 * tty_write_message - write a message to a certain tty, not just the console.
1296 * @tty: the destination tty_struct
1297 * @msg: the message to write
1298 *
1299 * This is used for messages that need to be redirected to a specific tty.
1300 * We don't put it into the syslog queue right now maybe in the future if
1301 * really needed.
1302 */
1303void tty_write_message(struct tty_struct *tty, char *msg)
1304{
1305 if (tty && tty->ops->write)
1306 tty->ops->write(tty, msg, strlen(msg));
1307 return;
1308}
1309
1310#if defined CONFIG_PRINTK 1294#if defined CONFIG_PRINTK
1311 1295
1312/* 1296/*
diff --git a/kernel/sched_debug.c b/kernel/sched_debug.c
index bbe6b31c3c56..ad958c1ec708 100644
--- a/kernel/sched_debug.c
+++ b/kernel/sched_debug.c
@@ -333,12 +333,10 @@ void proc_sched_show_task(struct task_struct *p, struct seq_file *m)
333 unsigned long flags; 333 unsigned long flags;
334 int num_threads = 1; 334 int num_threads = 1;
335 335
336 rcu_read_lock();
337 if (lock_task_sighand(p, &flags)) { 336 if (lock_task_sighand(p, &flags)) {
338 num_threads = atomic_read(&p->signal->count); 337 num_threads = atomic_read(&p->signal->count);
339 unlock_task_sighand(p, &flags); 338 unlock_task_sighand(p, &flags);
340 } 339 }
341 rcu_read_unlock();
342 340
343 SEQ_printf(m, "%s (%d, #threads: %d)\n", p->comm, p->pid, num_threads); 341 SEQ_printf(m, "%s (%d, #threads: %d)\n", p->comm, p->pid, num_threads);
344 SEQ_printf(m, 342 SEQ_printf(m,
diff --git a/kernel/sys.c b/kernel/sys.c
index 038a7bc0901d..234d9454294e 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -1060,9 +1060,7 @@ asmlinkage long sys_setsid(void)
1060 group_leader->signal->leader = 1; 1060 group_leader->signal->leader = 1;
1061 __set_special_pids(sid); 1061 __set_special_pids(sid);
1062 1062
1063 spin_lock(&group_leader->sighand->siglock); 1063 proc_clear_tty(group_leader);
1064 group_leader->signal->tty = NULL;
1065 spin_unlock(&group_leader->sighand->siglock);
1066 1064
1067 err = session; 1065 err = session;
1068out: 1066out:
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index 1bf369bd4423..c468c3c6dfc5 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -80,7 +80,6 @@ extern int pid_max_min, pid_max_max;
80extern int sysctl_drop_caches; 80extern int sysctl_drop_caches;
81extern int percpu_pagelist_fraction; 81extern int percpu_pagelist_fraction;
82extern int compat_log; 82extern int compat_log;
83extern int maps_protect;
84extern int latencytop_enabled; 83extern int latencytop_enabled;
85extern int sysctl_nr_open_min, sysctl_nr_open_max; 84extern int sysctl_nr_open_min, sysctl_nr_open_max;
86#ifdef CONFIG_RCU_TORTURE_TEST 85#ifdef CONFIG_RCU_TORTURE_TEST
@@ -808,16 +807,6 @@ static struct ctl_table kern_table[] = {
808 .proc_handler = &proc_dointvec, 807 .proc_handler = &proc_dointvec,
809 }, 808 },
810#endif 809#endif
811#ifdef CONFIG_PROC_FS
812 {
813 .ctl_name = CTL_UNNUMBERED,
814 .procname = "maps_protect",
815 .data = &maps_protect,
816 .maxlen = sizeof(int),
817 .mode = 0644,
818 .proc_handler = &proc_dointvec,
819 },
820#endif
821 { 810 {
822 .ctl_name = CTL_UNNUMBERED, 811 .ctl_name = CTL_UNNUMBERED,
823 .procname = "poweroff_cmd", 812 .procname = "poweroff_cmd",
diff --git a/mm/shmem.c b/mm/shmem.c
index 04fb4f1ab88e..bf66d0191baf 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -50,14 +50,12 @@
50#include <linux/migrate.h> 50#include <linux/migrate.h>
51#include <linux/highmem.h> 51#include <linux/highmem.h>
52#include <linux/seq_file.h> 52#include <linux/seq_file.h>
53#include <linux/magic.h>
53 54
54#include <asm/uaccess.h> 55#include <asm/uaccess.h>
55#include <asm/div64.h> 56#include <asm/div64.h>
56#include <asm/pgtable.h> 57#include <asm/pgtable.h>
57 58
58/* This magic number is used in glibc for posix shared memory */
59#define TMPFS_MAGIC 0x01021994
60
61#define ENTRIES_PER_PAGE (PAGE_CACHE_SIZE/sizeof(unsigned long)) 59#define ENTRIES_PER_PAGE (PAGE_CACHE_SIZE/sizeof(unsigned long))
62#define ENTRIES_PER_PAGEPAGE (ENTRIES_PER_PAGE*ENTRIES_PER_PAGE) 60#define ENTRIES_PER_PAGEPAGE (ENTRIES_PER_PAGE*ENTRIES_PER_PAGE)
63#define BLOCKS_PER_PAGE (PAGE_CACHE_SIZE/512) 61#define BLOCKS_PER_PAGE (PAGE_CACHE_SIZE/512)
diff --git a/net/ipv4/cipso_ipv4.c b/net/ipv4/cipso_ipv4.c
index 2c0e4572cc90..490e035c6d90 100644
--- a/net/ipv4/cipso_ipv4.c
+++ b/net/ipv4/cipso_ipv4.c
@@ -13,7 +13,7 @@
13 */ 13 */
14 14
15/* 15/*
16 * (c) Copyright Hewlett-Packard Development Company, L.P., 2006 16 * (c) Copyright Hewlett-Packard Development Company, L.P., 2006, 2008
17 * 17 *
18 * This program is free software; you can redistribute it and/or modify 18 * This program is free software; you can redistribute it and/or modify
19 * it under the terms of the GNU General Public License as published by 19 * it under the terms of the GNU General Public License as published by
@@ -47,17 +47,7 @@
47#include <asm/bug.h> 47#include <asm/bug.h>
48#include <asm/unaligned.h> 48#include <asm/unaligned.h>
49 49
50struct cipso_v4_domhsh_entry {
51 char *domain;
52 u32 valid;
53 struct list_head list;
54 struct rcu_head rcu;
55};
56
57/* List of available DOI definitions */ 50/* List of available DOI definitions */
58/* XXX - Updates should be minimal so having a single lock for the
59 * cipso_v4_doi_list and the cipso_v4_doi_list->dom_list should be
60 * okay. */
61/* XXX - This currently assumes a minimal number of different DOIs in use, 51/* XXX - This currently assumes a minimal number of different DOIs in use,
62 * if in practice there are a lot of different DOIs this list should 52 * if in practice there are a lot of different DOIs this list should
63 * probably be turned into a hash table or something similar so we 53 * probably be turned into a hash table or something similar so we
@@ -119,6 +109,19 @@ int cipso_v4_rbm_strictvalid = 1;
119 * be omitted. */ 109 * be omitted. */
120#define CIPSO_V4_TAG_RNG_CAT_MAX 8 110#define CIPSO_V4_TAG_RNG_CAT_MAX 8
121 111
112/* Base length of the local tag (non-standard tag).
113 * Tag definition (may change between kernel versions)
114 *
115 * 0 8 16 24 32
116 * +----------+----------+----------+----------+
117 * | 10000000 | 00000110 | 32-bit secid value |
118 * +----------+----------+----------+----------+
119 * | in (host byte order)|
120 * +----------+----------+
121 *
122 */
123#define CIPSO_V4_TAG_LOC_BLEN 6
124
122/* 125/*
123 * Helper Functions 126 * Helper Functions
124 */ 127 */
@@ -194,25 +197,6 @@ static void cipso_v4_bitmap_setbit(unsigned char *bitmap,
194} 197}
195 198
196/** 199/**
197 * cipso_v4_doi_domhsh_free - Frees a domain list entry
198 * @entry: the entry's RCU field
199 *
200 * Description:
201 * This function is designed to be used as a callback to the call_rcu()
202 * function so that the memory allocated to a domain list entry can be released
203 * safely.
204 *
205 */
206static void cipso_v4_doi_domhsh_free(struct rcu_head *entry)
207{
208 struct cipso_v4_domhsh_entry *ptr;
209
210 ptr = container_of(entry, struct cipso_v4_domhsh_entry, rcu);
211 kfree(ptr->domain);
212 kfree(ptr);
213}
214
215/**
216 * cipso_v4_cache_entry_free - Frees a cache entry 200 * cipso_v4_cache_entry_free - Frees a cache entry
217 * @entry: the entry to free 201 * @entry: the entry to free
218 * 202 *
@@ -457,7 +441,7 @@ static struct cipso_v4_doi *cipso_v4_doi_search(u32 doi)
457 struct cipso_v4_doi *iter; 441 struct cipso_v4_doi *iter;
458 442
459 list_for_each_entry_rcu(iter, &cipso_v4_doi_list, list) 443 list_for_each_entry_rcu(iter, &cipso_v4_doi_list, list)
460 if (iter->doi == doi && iter->valid) 444 if (iter->doi == doi && atomic_read(&iter->refcount))
461 return iter; 445 return iter;
462 return NULL; 446 return NULL;
463} 447}
@@ -496,14 +480,17 @@ int cipso_v4_doi_add(struct cipso_v4_doi *doi_def)
496 if (doi_def->type != CIPSO_V4_MAP_PASS) 480 if (doi_def->type != CIPSO_V4_MAP_PASS)
497 return -EINVAL; 481 return -EINVAL;
498 break; 482 break;
483 case CIPSO_V4_TAG_LOCAL:
484 if (doi_def->type != CIPSO_V4_MAP_LOCAL)
485 return -EINVAL;
486 break;
499 default: 487 default:
500 return -EINVAL; 488 return -EINVAL;
501 } 489 }
502 } 490 }
503 491
504 doi_def->valid = 1; 492 atomic_set(&doi_def->refcount, 1);
505 INIT_RCU_HEAD(&doi_def->rcu); 493 INIT_RCU_HEAD(&doi_def->rcu);
506 INIT_LIST_HEAD(&doi_def->dom_list);
507 494
508 spin_lock(&cipso_v4_doi_list_lock); 495 spin_lock(&cipso_v4_doi_list_lock);
509 if (cipso_v4_doi_search(doi_def->doi) != NULL) 496 if (cipso_v4_doi_search(doi_def->doi) != NULL)
@@ -519,59 +506,129 @@ doi_add_failure:
519} 506}
520 507
521/** 508/**
509 * cipso_v4_doi_free - Frees a DOI definition
510 * @entry: the entry's RCU field
511 *
512 * Description:
513 * This function frees all of the memory associated with a DOI definition.
514 *
515 */
516void cipso_v4_doi_free(struct cipso_v4_doi *doi_def)
517{
518 if (doi_def == NULL)
519 return;
520
521 switch (doi_def->type) {
522 case CIPSO_V4_MAP_TRANS:
523 kfree(doi_def->map.std->lvl.cipso);
524 kfree(doi_def->map.std->lvl.local);
525 kfree(doi_def->map.std->cat.cipso);
526 kfree(doi_def->map.std->cat.local);
527 break;
528 }
529 kfree(doi_def);
530}
531
532/**
533 * cipso_v4_doi_free_rcu - Frees a DOI definition via the RCU pointer
534 * @entry: the entry's RCU field
535 *
536 * Description:
537 * This function is designed to be used as a callback to the call_rcu()
538 * function so that the memory allocated to the DOI definition can be released
539 * safely.
540 *
541 */
542static void cipso_v4_doi_free_rcu(struct rcu_head *entry)
543{
544 struct cipso_v4_doi *doi_def;
545
546 doi_def = container_of(entry, struct cipso_v4_doi, rcu);
547 cipso_v4_doi_free(doi_def);
548}
549
550/**
522 * cipso_v4_doi_remove - Remove an existing DOI from the CIPSO protocol engine 551 * cipso_v4_doi_remove - Remove an existing DOI from the CIPSO protocol engine
523 * @doi: the DOI value 552 * @doi: the DOI value
524 * @audit_secid: the LSM secid to use in the audit message 553 * @audit_secid: the LSM secid to use in the audit message
525 * @callback: the DOI cleanup/free callback
526 * 554 *
527 * Description: 555 * Description:
528 * Removes a DOI definition from the CIPSO engine, @callback is called to 556 * Removes a DOI definition from the CIPSO engine. The NetLabel routines will
529 * free any memory. The NetLabel routines will be called to release their own 557 * be called to release their own LSM domain mappings as well as our own
530 * LSM domain mappings as well as our own domain list. Returns zero on 558 * domain list. Returns zero on success and negative values on failure.
531 * success and negative values on failure.
532 * 559 *
533 */ 560 */
534int cipso_v4_doi_remove(u32 doi, 561int cipso_v4_doi_remove(u32 doi, struct netlbl_audit *audit_info)
535 struct netlbl_audit *audit_info,
536 void (*callback) (struct rcu_head * head))
537{ 562{
538 struct cipso_v4_doi *doi_def; 563 struct cipso_v4_doi *doi_def;
539 struct cipso_v4_domhsh_entry *dom_iter;
540 564
541 spin_lock(&cipso_v4_doi_list_lock); 565 spin_lock(&cipso_v4_doi_list_lock);
542 doi_def = cipso_v4_doi_search(doi); 566 doi_def = cipso_v4_doi_search(doi);
543 if (doi_def != NULL) { 567 if (doi_def == NULL) {
544 doi_def->valid = 0;
545 list_del_rcu(&doi_def->list);
546 spin_unlock(&cipso_v4_doi_list_lock); 568 spin_unlock(&cipso_v4_doi_list_lock);
547 rcu_read_lock(); 569 return -ENOENT;
548 list_for_each_entry_rcu(dom_iter, &doi_def->dom_list, list) 570 }
549 if (dom_iter->valid) 571 if (!atomic_dec_and_test(&doi_def->refcount)) {
550 netlbl_cfg_map_del(dom_iter->domain, 572 spin_unlock(&cipso_v4_doi_list_lock);
551 audit_info); 573 return -EBUSY;
552 rcu_read_unlock();
553 cipso_v4_cache_invalidate();
554 call_rcu(&doi_def->rcu, callback);
555 return 0;
556 } 574 }
575 list_del_rcu(&doi_def->list);
557 spin_unlock(&cipso_v4_doi_list_lock); 576 spin_unlock(&cipso_v4_doi_list_lock);
558 577
559 return -ENOENT; 578 cipso_v4_cache_invalidate();
579 call_rcu(&doi_def->rcu, cipso_v4_doi_free_rcu);
580
581 return 0;
560} 582}
561 583
562/** 584/**
563 * cipso_v4_doi_getdef - Returns a pointer to a valid DOI definition 585 * cipso_v4_doi_getdef - Returns a reference to a valid DOI definition
564 * @doi: the DOI value 586 * @doi: the DOI value
565 * 587 *
566 * Description: 588 * Description:
567 * Searches for a valid DOI definition and if one is found it is returned to 589 * Searches for a valid DOI definition and if one is found it is returned to
568 * the caller. Otherwise NULL is returned. The caller must ensure that 590 * the caller. Otherwise NULL is returned. The caller must ensure that
569 * rcu_read_lock() is held while accessing the returned definition. 591 * rcu_read_lock() is held while accessing the returned definition and the DOI
592 * definition reference count is decremented when the caller is done.
570 * 593 *
571 */ 594 */
572struct cipso_v4_doi *cipso_v4_doi_getdef(u32 doi) 595struct cipso_v4_doi *cipso_v4_doi_getdef(u32 doi)
573{ 596{
574 return cipso_v4_doi_search(doi); 597 struct cipso_v4_doi *doi_def;
598
599 rcu_read_lock();
600 doi_def = cipso_v4_doi_search(doi);
601 if (doi_def == NULL)
602 goto doi_getdef_return;
603 if (!atomic_inc_not_zero(&doi_def->refcount))
604 doi_def = NULL;
605
606doi_getdef_return:
607 rcu_read_unlock();
608 return doi_def;
609}
610
611/**
612 * cipso_v4_doi_putdef - Releases a reference for the given DOI definition
613 * @doi_def: the DOI definition
614 *
615 * Description:
616 * Releases a DOI definition reference obtained from cipso_v4_doi_getdef().
617 *
618 */
619void cipso_v4_doi_putdef(struct cipso_v4_doi *doi_def)
620{
621 if (doi_def == NULL)
622 return;
623
624 if (!atomic_dec_and_test(&doi_def->refcount))
625 return;
626 spin_lock(&cipso_v4_doi_list_lock);
627 list_del_rcu(&doi_def->list);
628 spin_unlock(&cipso_v4_doi_list_lock);
629
630 cipso_v4_cache_invalidate();
631 call_rcu(&doi_def->rcu, cipso_v4_doi_free_rcu);
575} 632}
576 633
577/** 634/**
@@ -597,7 +654,7 @@ int cipso_v4_doi_walk(u32 *skip_cnt,
597 654
598 rcu_read_lock(); 655 rcu_read_lock();
599 list_for_each_entry_rcu(iter_doi, &cipso_v4_doi_list, list) 656 list_for_each_entry_rcu(iter_doi, &cipso_v4_doi_list, list)
600 if (iter_doi->valid) { 657 if (atomic_read(&iter_doi->refcount) > 0) {
601 if (doi_cnt++ < *skip_cnt) 658 if (doi_cnt++ < *skip_cnt)
602 continue; 659 continue;
603 ret_val = callback(iter_doi, cb_arg); 660 ret_val = callback(iter_doi, cb_arg);
@@ -613,85 +670,6 @@ doi_walk_return:
613 return ret_val; 670 return ret_val;
614} 671}
615 672
616/**
617 * cipso_v4_doi_domhsh_add - Adds a domain entry to a DOI definition
618 * @doi_def: the DOI definition
619 * @domain: the domain to add
620 *
621 * Description:
622 * Adds the @domain to the DOI specified by @doi_def, this function
623 * should only be called by external functions (i.e. NetLabel). This function
624 * does allocate memory. Returns zero on success, negative values on failure.
625 *
626 */
627int cipso_v4_doi_domhsh_add(struct cipso_v4_doi *doi_def, const char *domain)
628{
629 struct cipso_v4_domhsh_entry *iter;
630 struct cipso_v4_domhsh_entry *new_dom;
631
632 new_dom = kzalloc(sizeof(*new_dom), GFP_KERNEL);
633 if (new_dom == NULL)
634 return -ENOMEM;
635 if (domain) {
636 new_dom->domain = kstrdup(domain, GFP_KERNEL);
637 if (new_dom->domain == NULL) {
638 kfree(new_dom);
639 return -ENOMEM;
640 }
641 }
642 new_dom->valid = 1;
643 INIT_RCU_HEAD(&new_dom->rcu);
644
645 spin_lock(&cipso_v4_doi_list_lock);
646 list_for_each_entry(iter, &doi_def->dom_list, list)
647 if (iter->valid &&
648 ((domain != NULL && iter->domain != NULL &&
649 strcmp(iter->domain, domain) == 0) ||
650 (domain == NULL && iter->domain == NULL))) {
651 spin_unlock(&cipso_v4_doi_list_lock);
652 kfree(new_dom->domain);
653 kfree(new_dom);
654 return -EEXIST;
655 }
656 list_add_tail_rcu(&new_dom->list, &doi_def->dom_list);
657 spin_unlock(&cipso_v4_doi_list_lock);
658
659 return 0;
660}
661
662/**
663 * cipso_v4_doi_domhsh_remove - Removes a domain entry from a DOI definition
664 * @doi_def: the DOI definition
665 * @domain: the domain to remove
666 *
667 * Description:
668 * Removes the @domain from the DOI specified by @doi_def, this function
669 * should only be called by external functions (i.e. NetLabel). Returns zero
670 * on success and negative values on error.
671 *
672 */
673int cipso_v4_doi_domhsh_remove(struct cipso_v4_doi *doi_def,
674 const char *domain)
675{
676 struct cipso_v4_domhsh_entry *iter;
677
678 spin_lock(&cipso_v4_doi_list_lock);
679 list_for_each_entry(iter, &doi_def->dom_list, list)
680 if (iter->valid &&
681 ((domain != NULL && iter->domain != NULL &&
682 strcmp(iter->domain, domain) == 0) ||
683 (domain == NULL && iter->domain == NULL))) {
684 iter->valid = 0;
685 list_del_rcu(&iter->list);
686 spin_unlock(&cipso_v4_doi_list_lock);
687 call_rcu(&iter->rcu, cipso_v4_doi_domhsh_free);
688 return 0;
689 }
690 spin_unlock(&cipso_v4_doi_list_lock);
691
692 return -ENOENT;
693}
694
695/* 673/*
696 * Label Mapping Functions 674 * Label Mapping Functions
697 */ 675 */
@@ -712,7 +690,7 @@ static int cipso_v4_map_lvl_valid(const struct cipso_v4_doi *doi_def, u8 level)
712 switch (doi_def->type) { 690 switch (doi_def->type) {
713 case CIPSO_V4_MAP_PASS: 691 case CIPSO_V4_MAP_PASS:
714 return 0; 692 return 0;
715 case CIPSO_V4_MAP_STD: 693 case CIPSO_V4_MAP_TRANS:
716 if (doi_def->map.std->lvl.cipso[level] < CIPSO_V4_INV_LVL) 694 if (doi_def->map.std->lvl.cipso[level] < CIPSO_V4_INV_LVL)
717 return 0; 695 return 0;
718 break; 696 break;
@@ -741,7 +719,7 @@ static int cipso_v4_map_lvl_hton(const struct cipso_v4_doi *doi_def,
741 case CIPSO_V4_MAP_PASS: 719 case CIPSO_V4_MAP_PASS:
742 *net_lvl = host_lvl; 720 *net_lvl = host_lvl;
743 return 0; 721 return 0;
744 case CIPSO_V4_MAP_STD: 722 case CIPSO_V4_MAP_TRANS:
745 if (host_lvl < doi_def->map.std->lvl.local_size && 723 if (host_lvl < doi_def->map.std->lvl.local_size &&
746 doi_def->map.std->lvl.local[host_lvl] < CIPSO_V4_INV_LVL) { 724 doi_def->map.std->lvl.local[host_lvl] < CIPSO_V4_INV_LVL) {
747 *net_lvl = doi_def->map.std->lvl.local[host_lvl]; 725 *net_lvl = doi_def->map.std->lvl.local[host_lvl];
@@ -775,7 +753,7 @@ static int cipso_v4_map_lvl_ntoh(const struct cipso_v4_doi *doi_def,
775 case CIPSO_V4_MAP_PASS: 753 case CIPSO_V4_MAP_PASS:
776 *host_lvl = net_lvl; 754 *host_lvl = net_lvl;
777 return 0; 755 return 0;
778 case CIPSO_V4_MAP_STD: 756 case CIPSO_V4_MAP_TRANS:
779 map_tbl = doi_def->map.std; 757 map_tbl = doi_def->map.std;
780 if (net_lvl < map_tbl->lvl.cipso_size && 758 if (net_lvl < map_tbl->lvl.cipso_size &&
781 map_tbl->lvl.cipso[net_lvl] < CIPSO_V4_INV_LVL) { 759 map_tbl->lvl.cipso[net_lvl] < CIPSO_V4_INV_LVL) {
@@ -812,7 +790,7 @@ static int cipso_v4_map_cat_rbm_valid(const struct cipso_v4_doi *doi_def,
812 switch (doi_def->type) { 790 switch (doi_def->type) {
813 case CIPSO_V4_MAP_PASS: 791 case CIPSO_V4_MAP_PASS:
814 return 0; 792 return 0;
815 case CIPSO_V4_MAP_STD: 793 case CIPSO_V4_MAP_TRANS:
816 cipso_cat_size = doi_def->map.std->cat.cipso_size; 794 cipso_cat_size = doi_def->map.std->cat.cipso_size;
817 cipso_array = doi_def->map.std->cat.cipso; 795 cipso_array = doi_def->map.std->cat.cipso;
818 for (;;) { 796 for (;;) {
@@ -860,7 +838,7 @@ static int cipso_v4_map_cat_rbm_hton(const struct cipso_v4_doi *doi_def,
860 u32 host_cat_size = 0; 838 u32 host_cat_size = 0;
861 u32 *host_cat_array = NULL; 839 u32 *host_cat_array = NULL;
862 840
863 if (doi_def->type == CIPSO_V4_MAP_STD) { 841 if (doi_def->type == CIPSO_V4_MAP_TRANS) {
864 host_cat_size = doi_def->map.std->cat.local_size; 842 host_cat_size = doi_def->map.std->cat.local_size;
865 host_cat_array = doi_def->map.std->cat.local; 843 host_cat_array = doi_def->map.std->cat.local;
866 } 844 }
@@ -875,7 +853,7 @@ static int cipso_v4_map_cat_rbm_hton(const struct cipso_v4_doi *doi_def,
875 case CIPSO_V4_MAP_PASS: 853 case CIPSO_V4_MAP_PASS:
876 net_spot = host_spot; 854 net_spot = host_spot;
877 break; 855 break;
878 case CIPSO_V4_MAP_STD: 856 case CIPSO_V4_MAP_TRANS:
879 if (host_spot >= host_cat_size) 857 if (host_spot >= host_cat_size)
880 return -EPERM; 858 return -EPERM;
881 net_spot = host_cat_array[host_spot]; 859 net_spot = host_cat_array[host_spot];
@@ -921,7 +899,7 @@ static int cipso_v4_map_cat_rbm_ntoh(const struct cipso_v4_doi *doi_def,
921 u32 net_cat_size = 0; 899 u32 net_cat_size = 0;
922 u32 *net_cat_array = NULL; 900 u32 *net_cat_array = NULL;
923 901
924 if (doi_def->type == CIPSO_V4_MAP_STD) { 902 if (doi_def->type == CIPSO_V4_MAP_TRANS) {
925 net_cat_size = doi_def->map.std->cat.cipso_size; 903 net_cat_size = doi_def->map.std->cat.cipso_size;
926 net_cat_array = doi_def->map.std->cat.cipso; 904 net_cat_array = doi_def->map.std->cat.cipso;
927 } 905 }
@@ -941,7 +919,7 @@ static int cipso_v4_map_cat_rbm_ntoh(const struct cipso_v4_doi *doi_def,
941 case CIPSO_V4_MAP_PASS: 919 case CIPSO_V4_MAP_PASS:
942 host_spot = net_spot; 920 host_spot = net_spot;
943 break; 921 break;
944 case CIPSO_V4_MAP_STD: 922 case CIPSO_V4_MAP_TRANS:
945 if (net_spot >= net_cat_size) 923 if (net_spot >= net_cat_size)
946 return -EPERM; 924 return -EPERM;
947 host_spot = net_cat_array[net_spot]; 925 host_spot = net_cat_array[net_spot];
@@ -1277,7 +1255,7 @@ static int cipso_v4_gentag_rbm(const struct cipso_v4_doi *doi_def,
1277 } else 1255 } else
1278 tag_len = 4; 1256 tag_len = 4;
1279 1257
1280 buffer[0] = 0x01; 1258 buffer[0] = CIPSO_V4_TAG_RBITMAP;
1281 buffer[1] = tag_len; 1259 buffer[1] = tag_len;
1282 buffer[3] = level; 1260 buffer[3] = level;
1283 1261
@@ -1373,7 +1351,7 @@ static int cipso_v4_gentag_enum(const struct cipso_v4_doi *doi_def,
1373 } else 1351 } else
1374 tag_len = 4; 1352 tag_len = 4;
1375 1353
1376 buffer[0] = 0x02; 1354 buffer[0] = CIPSO_V4_TAG_ENUM;
1377 buffer[1] = tag_len; 1355 buffer[1] = tag_len;
1378 buffer[3] = level; 1356 buffer[3] = level;
1379 1357
@@ -1469,7 +1447,7 @@ static int cipso_v4_gentag_rng(const struct cipso_v4_doi *doi_def,
1469 } else 1447 } else
1470 tag_len = 4; 1448 tag_len = 4;
1471 1449
1472 buffer[0] = 0x05; 1450 buffer[0] = CIPSO_V4_TAG_RANGE;
1473 buffer[1] = tag_len; 1451 buffer[1] = tag_len;
1474 buffer[3] = level; 1452 buffer[3] = level;
1475 1453
@@ -1523,6 +1501,54 @@ static int cipso_v4_parsetag_rng(const struct cipso_v4_doi *doi_def,
1523} 1501}
1524 1502
1525/** 1503/**
1504 * cipso_v4_gentag_loc - Generate a CIPSO local tag (non-standard)
1505 * @doi_def: the DOI definition
1506 * @secattr: the security attributes
1507 * @buffer: the option buffer
1508 * @buffer_len: length of buffer in bytes
1509 *
1510 * Description:
1511 * Generate a CIPSO option using the local tag. Returns the size of the tag
1512 * on success, negative values on failure.
1513 *
1514 */
1515static int cipso_v4_gentag_loc(const struct cipso_v4_doi *doi_def,
1516 const struct netlbl_lsm_secattr *secattr,
1517 unsigned char *buffer,
1518 u32 buffer_len)
1519{
1520 if (!(secattr->flags & NETLBL_SECATTR_SECID))
1521 return -EPERM;
1522
1523 buffer[0] = CIPSO_V4_TAG_LOCAL;
1524 buffer[1] = CIPSO_V4_TAG_LOC_BLEN;
1525 *(u32 *)&buffer[2] = secattr->attr.secid;
1526
1527 return CIPSO_V4_TAG_LOC_BLEN;
1528}
1529
1530/**
1531 * cipso_v4_parsetag_loc - Parse a CIPSO local tag
1532 * @doi_def: the DOI definition
1533 * @tag: the CIPSO tag
1534 * @secattr: the security attributes
1535 *
1536 * Description:
1537 * Parse a CIPSO local tag and return the security attributes in @secattr.
1538 * Return zero on success, negatives values on failure.
1539 *
1540 */
1541static int cipso_v4_parsetag_loc(const struct cipso_v4_doi *doi_def,
1542 const unsigned char *tag,
1543 struct netlbl_lsm_secattr *secattr)
1544{
1545 secattr->attr.secid = *(u32 *)&tag[2];
1546 secattr->flags |= NETLBL_SECATTR_SECID;
1547
1548 return 0;
1549}
1550
1551/**
1526 * cipso_v4_validate - Validate a CIPSO option 1552 * cipso_v4_validate - Validate a CIPSO option
1527 * @option: the start of the option, on error it is set to point to the error 1553 * @option: the start of the option, on error it is set to point to the error
1528 * 1554 *
@@ -1541,7 +1567,7 @@ static int cipso_v4_parsetag_rng(const struct cipso_v4_doi *doi_def,
1541 * that is unrecognized." 1567 * that is unrecognized."
1542 * 1568 *
1543 */ 1569 */
1544int cipso_v4_validate(unsigned char **option) 1570int cipso_v4_validate(const struct sk_buff *skb, unsigned char **option)
1545{ 1571{
1546 unsigned char *opt = *option; 1572 unsigned char *opt = *option;
1547 unsigned char *tag; 1573 unsigned char *tag;
@@ -1566,7 +1592,7 @@ int cipso_v4_validate(unsigned char **option)
1566 goto validate_return_locked; 1592 goto validate_return_locked;
1567 } 1593 }
1568 1594
1569 opt_iter = 6; 1595 opt_iter = CIPSO_V4_HDR_LEN;
1570 tag = opt + opt_iter; 1596 tag = opt + opt_iter;
1571 while (opt_iter < opt_len) { 1597 while (opt_iter < opt_len) {
1572 for (tag_iter = 0; doi_def->tags[tag_iter] != tag[0];) 1598 for (tag_iter = 0; doi_def->tags[tag_iter] != tag[0];)
@@ -1584,7 +1610,7 @@ int cipso_v4_validate(unsigned char **option)
1584 1610
1585 switch (tag[0]) { 1611 switch (tag[0]) {
1586 case CIPSO_V4_TAG_RBITMAP: 1612 case CIPSO_V4_TAG_RBITMAP:
1587 if (tag_len < 4) { 1613 if (tag_len < CIPSO_V4_TAG_RBM_BLEN) {
1588 err_offset = opt_iter + 1; 1614 err_offset = opt_iter + 1;
1589 goto validate_return_locked; 1615 goto validate_return_locked;
1590 } 1616 }
@@ -1602,7 +1628,7 @@ int cipso_v4_validate(unsigned char **option)
1602 err_offset = opt_iter + 3; 1628 err_offset = opt_iter + 3;
1603 goto validate_return_locked; 1629 goto validate_return_locked;
1604 } 1630 }
1605 if (tag_len > 4 && 1631 if (tag_len > CIPSO_V4_TAG_RBM_BLEN &&
1606 cipso_v4_map_cat_rbm_valid(doi_def, 1632 cipso_v4_map_cat_rbm_valid(doi_def,
1607 &tag[4], 1633 &tag[4],
1608 tag_len - 4) < 0) { 1634 tag_len - 4) < 0) {
@@ -1612,7 +1638,7 @@ int cipso_v4_validate(unsigned char **option)
1612 } 1638 }
1613 break; 1639 break;
1614 case CIPSO_V4_TAG_ENUM: 1640 case CIPSO_V4_TAG_ENUM:
1615 if (tag_len < 4) { 1641 if (tag_len < CIPSO_V4_TAG_ENUM_BLEN) {
1616 err_offset = opt_iter + 1; 1642 err_offset = opt_iter + 1;
1617 goto validate_return_locked; 1643 goto validate_return_locked;
1618 } 1644 }
@@ -1622,7 +1648,7 @@ int cipso_v4_validate(unsigned char **option)
1622 err_offset = opt_iter + 3; 1648 err_offset = opt_iter + 3;
1623 goto validate_return_locked; 1649 goto validate_return_locked;
1624 } 1650 }
1625 if (tag_len > 4 && 1651 if (tag_len > CIPSO_V4_TAG_ENUM_BLEN &&
1626 cipso_v4_map_cat_enum_valid(doi_def, 1652 cipso_v4_map_cat_enum_valid(doi_def,
1627 &tag[4], 1653 &tag[4],
1628 tag_len - 4) < 0) { 1654 tag_len - 4) < 0) {
@@ -1631,7 +1657,7 @@ int cipso_v4_validate(unsigned char **option)
1631 } 1657 }
1632 break; 1658 break;
1633 case CIPSO_V4_TAG_RANGE: 1659 case CIPSO_V4_TAG_RANGE:
1634 if (tag_len < 4) { 1660 if (tag_len < CIPSO_V4_TAG_RNG_BLEN) {
1635 err_offset = opt_iter + 1; 1661 err_offset = opt_iter + 1;
1636 goto validate_return_locked; 1662 goto validate_return_locked;
1637 } 1663 }
@@ -1641,7 +1667,7 @@ int cipso_v4_validate(unsigned char **option)
1641 err_offset = opt_iter + 3; 1667 err_offset = opt_iter + 3;
1642 goto validate_return_locked; 1668 goto validate_return_locked;
1643 } 1669 }
1644 if (tag_len > 4 && 1670 if (tag_len > CIPSO_V4_TAG_RNG_BLEN &&
1645 cipso_v4_map_cat_rng_valid(doi_def, 1671 cipso_v4_map_cat_rng_valid(doi_def,
1646 &tag[4], 1672 &tag[4],
1647 tag_len - 4) < 0) { 1673 tag_len - 4) < 0) {
@@ -1649,6 +1675,19 @@ int cipso_v4_validate(unsigned char **option)
1649 goto validate_return_locked; 1675 goto validate_return_locked;
1650 } 1676 }
1651 break; 1677 break;
1678 case CIPSO_V4_TAG_LOCAL:
1679 /* This is a non-standard tag that we only allow for
1680 * local connections, so if the incoming interface is
1681 * not the loopback device drop the packet. */
1682 if (!(skb->dev->flags & IFF_LOOPBACK)) {
1683 err_offset = opt_iter;
1684 goto validate_return_locked;
1685 }
1686 if (tag_len != CIPSO_V4_TAG_LOC_BLEN) {
1687 err_offset = opt_iter + 1;
1688 goto validate_return_locked;
1689 }
1690 break;
1652 default: 1691 default:
1653 err_offset = opt_iter; 1692 err_offset = opt_iter;
1654 goto validate_return_locked; 1693 goto validate_return_locked;
@@ -1704,48 +1743,27 @@ void cipso_v4_error(struct sk_buff *skb, int error, u32 gateway)
1704} 1743}
1705 1744
1706/** 1745/**
1707 * cipso_v4_sock_setattr - Add a CIPSO option to a socket 1746 * cipso_v4_genopt - Generate a CIPSO option
1708 * @sk: the socket 1747 * @buf: the option buffer
1748 * @buf_len: the size of opt_buf
1709 * @doi_def: the CIPSO DOI to use 1749 * @doi_def: the CIPSO DOI to use
1710 * @secattr: the specific security attributes of the socket 1750 * @secattr: the security attributes
1711 * 1751 *
1712 * Description: 1752 * Description:
1713 * Set the CIPSO option on the given socket using the DOI definition and 1753 * Generate a CIPSO option using the DOI definition and security attributes
1714 * security attributes passed to the function. This function requires 1754 * passed to the function. Returns the length of the option on success and
1715 * exclusive access to @sk, which means it either needs to be in the 1755 * negative values on failure.
1716 * process of being created or locked. Returns zero on success and negative
1717 * values on failure.
1718 * 1756 *
1719 */ 1757 */
1720int cipso_v4_sock_setattr(struct sock *sk, 1758static int cipso_v4_genopt(unsigned char *buf, u32 buf_len,
1721 const struct cipso_v4_doi *doi_def, 1759 const struct cipso_v4_doi *doi_def,
1722 const struct netlbl_lsm_secattr *secattr) 1760 const struct netlbl_lsm_secattr *secattr)
1723{ 1761{
1724 int ret_val = -EPERM; 1762 int ret_val;
1725 u32 iter; 1763 u32 iter;
1726 unsigned char *buf;
1727 u32 buf_len = 0;
1728 u32 opt_len;
1729 struct ip_options *opt = NULL;
1730 struct inet_sock *sk_inet;
1731 struct inet_connection_sock *sk_conn;
1732 1764
1733 /* In the case of sock_create_lite(), the sock->sk field is not 1765 if (buf_len <= CIPSO_V4_HDR_LEN)
1734 * defined yet but it is not a problem as the only users of these 1766 return -ENOSPC;
1735 * "lite" PF_INET sockets are functions which do an accept() call
1736 * afterwards so we will label the socket as part of the accept(). */
1737 if (sk == NULL)
1738 return 0;
1739
1740 /* We allocate the maximum CIPSO option size here so we are probably
1741 * being a little wasteful, but it makes our life _much_ easier later
1742 * on and after all we are only talking about 40 bytes. */
1743 buf_len = CIPSO_V4_OPT_LEN_MAX;
1744 buf = kmalloc(buf_len, GFP_ATOMIC);
1745 if (buf == NULL) {
1746 ret_val = -ENOMEM;
1747 goto socket_setattr_failure;
1748 }
1749 1767
1750 /* XXX - This code assumes only one tag per CIPSO option which isn't 1768 /* XXX - This code assumes only one tag per CIPSO option which isn't
1751 * really a good assumption to make but since we only support the MAC 1769 * really a good assumption to make but since we only support the MAC
@@ -1772,9 +1790,14 @@ int cipso_v4_sock_setattr(struct sock *sk,
1772 &buf[CIPSO_V4_HDR_LEN], 1790 &buf[CIPSO_V4_HDR_LEN],
1773 buf_len - CIPSO_V4_HDR_LEN); 1791 buf_len - CIPSO_V4_HDR_LEN);
1774 break; 1792 break;
1793 case CIPSO_V4_TAG_LOCAL:
1794 ret_val = cipso_v4_gentag_loc(doi_def,
1795 secattr,
1796 &buf[CIPSO_V4_HDR_LEN],
1797 buf_len - CIPSO_V4_HDR_LEN);
1798 break;
1775 default: 1799 default:
1776 ret_val = -EPERM; 1800 return -EPERM;
1777 goto socket_setattr_failure;
1778 } 1801 }
1779 1802
1780 iter++; 1803 iter++;
@@ -1782,9 +1805,58 @@ int cipso_v4_sock_setattr(struct sock *sk,
1782 iter < CIPSO_V4_TAG_MAXCNT && 1805 iter < CIPSO_V4_TAG_MAXCNT &&
1783 doi_def->tags[iter] != CIPSO_V4_TAG_INVALID); 1806 doi_def->tags[iter] != CIPSO_V4_TAG_INVALID);
1784 if (ret_val < 0) 1807 if (ret_val < 0)
1785 goto socket_setattr_failure; 1808 return ret_val;
1786 cipso_v4_gentag_hdr(doi_def, buf, ret_val); 1809 cipso_v4_gentag_hdr(doi_def, buf, ret_val);
1787 buf_len = CIPSO_V4_HDR_LEN + ret_val; 1810 return CIPSO_V4_HDR_LEN + ret_val;
1811}
1812
1813/**
1814 * cipso_v4_sock_setattr - Add a CIPSO option to a socket
1815 * @sk: the socket
1816 * @doi_def: the CIPSO DOI to use
1817 * @secattr: the specific security attributes of the socket
1818 *
1819 * Description:
1820 * Set the CIPSO option on the given socket using the DOI definition and
1821 * security attributes passed to the function. This function requires
1822 * exclusive access to @sk, which means it either needs to be in the
1823 * process of being created or locked. Returns zero on success and negative
1824 * values on failure.
1825 *
1826 */
1827int cipso_v4_sock_setattr(struct sock *sk,
1828 const struct cipso_v4_doi *doi_def,
1829 const struct netlbl_lsm_secattr *secattr)
1830{
1831 int ret_val = -EPERM;
1832 unsigned char *buf = NULL;
1833 u32 buf_len;
1834 u32 opt_len;
1835 struct ip_options *opt = NULL;
1836 struct inet_sock *sk_inet;
1837 struct inet_connection_sock *sk_conn;
1838
1839 /* In the case of sock_create_lite(), the sock->sk field is not
1840 * defined yet but it is not a problem as the only users of these
1841 * "lite" PF_INET sockets are functions which do an accept() call
1842 * afterwards so we will label the socket as part of the accept(). */
1843 if (sk == NULL)
1844 return 0;
1845
1846 /* We allocate the maximum CIPSO option size here so we are probably
1847 * being a little wasteful, but it makes our life _much_ easier later
1848 * on and after all we are only talking about 40 bytes. */
1849 buf_len = CIPSO_V4_OPT_LEN_MAX;
1850 buf = kmalloc(buf_len, GFP_ATOMIC);
1851 if (buf == NULL) {
1852 ret_val = -ENOMEM;
1853 goto socket_setattr_failure;
1854 }
1855
1856 ret_val = cipso_v4_genopt(buf, buf_len, doi_def, secattr);
1857 if (ret_val < 0)
1858 goto socket_setattr_failure;
1859 buf_len = ret_val;
1788 1860
1789 /* We can't use ip_options_get() directly because it makes a call to 1861 /* We can't use ip_options_get() directly because it makes a call to
1790 * ip_options_get_alloc() which allocates memory with GFP_KERNEL and 1862 * ip_options_get_alloc() which allocates memory with GFP_KERNEL and
@@ -1822,6 +1894,80 @@ socket_setattr_failure:
1822} 1894}
1823 1895
1824/** 1896/**
1897 * cipso_v4_sock_delattr - Delete the CIPSO option from a socket
1898 * @sk: the socket
1899 *
1900 * Description:
1901 * Removes the CIPSO option from a socket, if present.
1902 *
1903 */
1904void cipso_v4_sock_delattr(struct sock *sk)
1905{
1906 u8 hdr_delta;
1907 struct ip_options *opt;
1908 struct inet_sock *sk_inet;
1909
1910 sk_inet = inet_sk(sk);
1911 opt = sk_inet->opt;
1912 if (opt == NULL || opt->cipso == 0)
1913 return;
1914
1915 if (opt->srr || opt->rr || opt->ts || opt->router_alert) {
1916 u8 cipso_len;
1917 u8 cipso_off;
1918 unsigned char *cipso_ptr;
1919 int iter;
1920 int optlen_new;
1921
1922 cipso_off = opt->cipso - sizeof(struct iphdr);
1923 cipso_ptr = &opt->__data[cipso_off];
1924 cipso_len = cipso_ptr[1];
1925
1926 if (opt->srr > opt->cipso)
1927 opt->srr -= cipso_len;
1928 if (opt->rr > opt->cipso)
1929 opt->rr -= cipso_len;
1930 if (opt->ts > opt->cipso)
1931 opt->ts -= cipso_len;
1932 if (opt->router_alert > opt->cipso)
1933 opt->router_alert -= cipso_len;
1934 opt->cipso = 0;
1935
1936 memmove(cipso_ptr, cipso_ptr + cipso_len,
1937 opt->optlen - cipso_off - cipso_len);
1938
1939 /* determining the new total option length is tricky because of
1940 * the padding necessary, the only thing i can think to do at
1941 * this point is walk the options one-by-one, skipping the
1942 * padding at the end to determine the actual option size and
1943 * from there we can determine the new total option length */
1944 iter = 0;
1945 optlen_new = 0;
1946 while (iter < opt->optlen)
1947 if (opt->__data[iter] != IPOPT_NOP) {
1948 iter += opt->__data[iter + 1];
1949 optlen_new = iter;
1950 } else
1951 iter++;
1952 hdr_delta = opt->optlen;
1953 opt->optlen = (optlen_new + 3) & ~3;
1954 hdr_delta -= opt->optlen;
1955 } else {
1956 /* only the cipso option was present on the socket so we can
1957 * remove the entire option struct */
1958 sk_inet->opt = NULL;
1959 hdr_delta = opt->optlen;
1960 kfree(opt);
1961 }
1962
1963 if (sk_inet->is_icsk && hdr_delta > 0) {
1964 struct inet_connection_sock *sk_conn = inet_csk(sk);
1965 sk_conn->icsk_ext_hdr_len -= hdr_delta;
1966 sk_conn->icsk_sync_mss(sk, sk_conn->icsk_pmtu_cookie);
1967 }
1968}
1969
1970/**
1825 * cipso_v4_getattr - Helper function for the cipso_v4_*_getattr functions 1971 * cipso_v4_getattr - Helper function for the cipso_v4_*_getattr functions
1826 * @cipso: the CIPSO v4 option 1972 * @cipso: the CIPSO v4 option
1827 * @secattr: the security attributes 1973 * @secattr: the security attributes
@@ -1859,6 +2005,9 @@ static int cipso_v4_getattr(const unsigned char *cipso,
1859 case CIPSO_V4_TAG_RANGE: 2005 case CIPSO_V4_TAG_RANGE:
1860 ret_val = cipso_v4_parsetag_rng(doi_def, &cipso[6], secattr); 2006 ret_val = cipso_v4_parsetag_rng(doi_def, &cipso[6], secattr);
1861 break; 2007 break;
2008 case CIPSO_V4_TAG_LOCAL:
2009 ret_val = cipso_v4_parsetag_loc(doi_def, &cipso[6], secattr);
2010 break;
1862 } 2011 }
1863 if (ret_val == 0) 2012 if (ret_val == 0)
1864 secattr->type = NETLBL_NLTYPE_CIPSOV4; 2013 secattr->type = NETLBL_NLTYPE_CIPSOV4;
@@ -1893,6 +2042,123 @@ int cipso_v4_sock_getattr(struct sock *sk, struct netlbl_lsm_secattr *secattr)
1893} 2042}
1894 2043
1895/** 2044/**
2045 * cipso_v4_skbuff_setattr - Set the CIPSO option on a packet
2046 * @skb: the packet
2047 * @secattr: the security attributes
2048 *
2049 * Description:
2050 * Set the CIPSO option on the given packet based on the security attributes.
2051 * Returns a pointer to the IP header on success and NULL on failure.
2052 *
2053 */
2054int cipso_v4_skbuff_setattr(struct sk_buff *skb,
2055 const struct cipso_v4_doi *doi_def,
2056 const struct netlbl_lsm_secattr *secattr)
2057{
2058 int ret_val;
2059 struct iphdr *iph;
2060 struct ip_options *opt = &IPCB(skb)->opt;
2061 unsigned char buf[CIPSO_V4_OPT_LEN_MAX];
2062 u32 buf_len = CIPSO_V4_OPT_LEN_MAX;
2063 u32 opt_len;
2064 int len_delta;
2065
2066 buf_len = cipso_v4_genopt(buf, buf_len, doi_def, secattr);
2067 if (buf_len < 0)
2068 return buf_len;
2069 opt_len = (buf_len + 3) & ~3;
2070
2071 /* we overwrite any existing options to ensure that we have enough
2072 * room for the CIPSO option, the reason is that we _need_ to guarantee
2073 * that the security label is applied to the packet - we do the same
2074 * thing when using the socket options and it hasn't caused a problem,
2075 * if we need to we can always revisit this choice later */
2076
2077 len_delta = opt_len - opt->optlen;
2078 /* if we don't ensure enough headroom we could panic on the skb_push()
2079 * call below so make sure we have enough, we are also "mangling" the
2080 * packet so we should probably do a copy-on-write call anyway */
2081 ret_val = skb_cow(skb, skb_headroom(skb) + len_delta);
2082 if (ret_val < 0)
2083 return ret_val;
2084
2085 if (len_delta > 0) {
2086 /* we assume that the header + opt->optlen have already been
2087 * "pushed" in ip_options_build() or similar */
2088 iph = ip_hdr(skb);
2089 skb_push(skb, len_delta);
2090 memmove((char *)iph - len_delta, iph, iph->ihl << 2);
2091 skb_reset_network_header(skb);
2092 iph = ip_hdr(skb);
2093 } else if (len_delta < 0) {
2094 iph = ip_hdr(skb);
2095 memset(iph + 1, IPOPT_NOP, opt->optlen);
2096 } else
2097 iph = ip_hdr(skb);
2098
2099 if (opt->optlen > 0)
2100 memset(opt, 0, sizeof(*opt));
2101 opt->optlen = opt_len;
2102 opt->cipso = sizeof(struct iphdr);
2103 opt->is_changed = 1;
2104
2105 /* we have to do the following because we are being called from a
2106 * netfilter hook which means the packet already has had the header
2107 * fields populated and the checksum calculated - yes this means we
2108 * are doing more work than needed but we do it to keep the core
2109 * stack clean and tidy */
2110 memcpy(iph + 1, buf, buf_len);
2111 if (opt_len > buf_len)
2112 memset((char *)(iph + 1) + buf_len, 0, opt_len - buf_len);
2113 if (len_delta != 0) {
2114 iph->ihl = 5 + (opt_len >> 2);
2115 iph->tot_len = htons(skb->len);
2116 }
2117 ip_send_check(iph);
2118
2119 return 0;
2120}
2121
2122/**
2123 * cipso_v4_skbuff_delattr - Delete any CIPSO options from a packet
2124 * @skb: the packet
2125 *
2126 * Description:
2127 * Removes any and all CIPSO options from the given packet. Returns zero on
2128 * success, negative values on failure.
2129 *
2130 */
2131int cipso_v4_skbuff_delattr(struct sk_buff *skb)
2132{
2133 int ret_val;
2134 struct iphdr *iph;
2135 struct ip_options *opt = &IPCB(skb)->opt;
2136 unsigned char *cipso_ptr;
2137
2138 if (opt->cipso == 0)
2139 return 0;
2140
2141 /* since we are changing the packet we should make a copy */
2142 ret_val = skb_cow(skb, skb_headroom(skb));
2143 if (ret_val < 0)
2144 return ret_val;
2145
2146 /* the easiest thing to do is just replace the cipso option with noop
2147 * options since we don't change the size of the packet, although we
2148 * still need to recalculate the checksum */
2149
2150 iph = ip_hdr(skb);
2151 cipso_ptr = (unsigned char *)iph + opt->cipso;
2152 memset(cipso_ptr, IPOPT_NOOP, cipso_ptr[1]);
2153 opt->cipso = 0;
2154 opt->is_changed = 1;
2155
2156 ip_send_check(iph);
2157
2158 return 0;
2159}
2160
2161/**
1896 * cipso_v4_skbuff_getattr - Get the security attributes from the CIPSO option 2162 * cipso_v4_skbuff_getattr - Get the security attributes from the CIPSO option
1897 * @skb: the packet 2163 * @skb: the packet
1898 * @secattr: the security attributes 2164 * @secattr: the security attributes
diff --git a/net/ipv4/ip_options.c b/net/ipv4/ip_options.c
index be3f18a7a40e..2c88da6e7862 100644
--- a/net/ipv4/ip_options.c
+++ b/net/ipv4/ip_options.c
@@ -438,7 +438,7 @@ int ip_options_compile(struct net *net,
438 goto error; 438 goto error;
439 } 439 }
440 opt->cipso = optptr - iph; 440 opt->cipso = optptr - iph;
441 if (cipso_v4_validate(&optptr)) { 441 if (cipso_v4_validate(skb, &optptr)) {
442 pp_ptr = optptr; 442 pp_ptr = optptr;
443 goto error; 443 goto error;
444 } 444 }
diff --git a/net/netlabel/Makefile b/net/netlabel/Makefile
index 8af18c0a47d9..ea750e9df65f 100644
--- a/net/netlabel/Makefile
+++ b/net/netlabel/Makefile
@@ -5,7 +5,8 @@
5# 5#
6 6
7# base objects 7# base objects
8obj-y := netlabel_user.o netlabel_kapi.o netlabel_domainhash.o 8obj-y := netlabel_user.o netlabel_kapi.o
9obj-y += netlabel_domainhash.o netlabel_addrlist.o
9 10
10# management objects 11# management objects
11obj-y += netlabel_mgmt.o 12obj-y += netlabel_mgmt.o
diff --git a/net/netlabel/netlabel_addrlist.c b/net/netlabel/netlabel_addrlist.c
new file mode 100644
index 000000000000..b0925a303353
--- /dev/null
+++ b/net/netlabel/netlabel_addrlist.c
@@ -0,0 +1,388 @@
1/*
2 * NetLabel Network Address Lists
3 *
4 * This file contains network address list functions used to manage ordered
5 * lists of network addresses for use by the NetLabel subsystem. The NetLabel
6 * system manages static and dynamic label mappings for network protocols such
7 * as CIPSO and RIPSO.
8 *
9 * Author: Paul Moore <paul.moore@hp.com>
10 *
11 */
12
13/*
14 * (c) Copyright Hewlett-Packard Development Company, L.P., 2008
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
24 * the GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, write to the Free Software
28 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
29 *
30 */
31
32#include <linux/types.h>
33#include <linux/rcupdate.h>
34#include <linux/list.h>
35#include <linux/spinlock.h>
36#include <linux/in.h>
37#include <linux/in6.h>
38#include <linux/ip.h>
39#include <linux/ipv6.h>
40#include <net/ip.h>
41#include <net/ipv6.h>
42#include <linux/audit.h>
43
44#include "netlabel_addrlist.h"
45
46/*
47 * Address List Functions
48 */
49
50/**
51 * netlbl_af4list_search - Search for a matching IPv4 address entry
52 * @addr: IPv4 address
53 * @head: the list head
54 *
55 * Description:
56 * Searches the IPv4 address list given by @head. If a matching address entry
57 * is found it is returned, otherwise NULL is returned. The caller is
58 * responsible for calling the rcu_read_[un]lock() functions.
59 *
60 */
61struct netlbl_af4list *netlbl_af4list_search(__be32 addr,
62 struct list_head *head)
63{
64 struct netlbl_af4list *iter;
65
66 list_for_each_entry_rcu(iter, head, list)
67 if (iter->valid && (addr & iter->mask) == iter->addr)
68 return iter;
69
70 return NULL;
71}
72
73/**
74 * netlbl_af4list_search_exact - Search for an exact IPv4 address entry
75 * @addr: IPv4 address
76 * @mask: IPv4 address mask
77 * @head: the list head
78 *
79 * Description:
80 * Searches the IPv4 address list given by @head. If an exact match if found
81 * it is returned, otherwise NULL is returned. The caller is responsible for
82 * calling the rcu_read_[un]lock() functions.
83 *
84 */
85struct netlbl_af4list *netlbl_af4list_search_exact(__be32 addr,
86 __be32 mask,
87 struct list_head *head)
88{
89 struct netlbl_af4list *iter;
90
91 list_for_each_entry_rcu(iter, head, list)
92 if (iter->valid && iter->addr == addr && iter->mask == mask)
93 return iter;
94
95 return NULL;
96}
97
98
99#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
100/**
101 * netlbl_af6list_search - Search for a matching IPv6 address entry
102 * @addr: IPv6 address
103 * @head: the list head
104 *
105 * Description:
106 * Searches the IPv6 address list given by @head. If a matching address entry
107 * is found it is returned, otherwise NULL is returned. The caller is
108 * responsible for calling the rcu_read_[un]lock() functions.
109 *
110 */
111struct netlbl_af6list *netlbl_af6list_search(const struct in6_addr *addr,
112 struct list_head *head)
113{
114 struct netlbl_af6list *iter;
115
116 list_for_each_entry_rcu(iter, head, list)
117 if (iter->valid &&
118 ipv6_masked_addr_cmp(&iter->addr, &iter->mask, addr) == 0)
119 return iter;
120
121 return NULL;
122}
123
124/**
125 * netlbl_af6list_search_exact - Search for an exact IPv6 address entry
126 * @addr: IPv6 address
127 * @mask: IPv6 address mask
128 * @head: the list head
129 *
130 * Description:
131 * Searches the IPv6 address list given by @head. If an exact match if found
132 * it is returned, otherwise NULL is returned. The caller is responsible for
133 * calling the rcu_read_[un]lock() functions.
134 *
135 */
136struct netlbl_af6list *netlbl_af6list_search_exact(const struct in6_addr *addr,
137 const struct in6_addr *mask,
138 struct list_head *head)
139{
140 struct netlbl_af6list *iter;
141
142 list_for_each_entry_rcu(iter, head, list)
143 if (iter->valid &&
144 ipv6_addr_equal(&iter->addr, addr) &&
145 ipv6_addr_equal(&iter->mask, mask))
146 return iter;
147
148 return NULL;
149}
150#endif /* IPv6 */
151
152/**
153 * netlbl_af4list_add - Add a new IPv4 address entry to a list
154 * @entry: address entry
155 * @head: the list head
156 *
157 * Description:
158 * Add a new address entry to the list pointed to by @head. On success zero is
159 * returned, otherwise a negative value is returned. The caller is responsible
160 * for calling the necessary locking functions.
161 *
162 */
163int netlbl_af4list_add(struct netlbl_af4list *entry, struct list_head *head)
164{
165 struct netlbl_af4list *iter;
166
167 iter = netlbl_af4list_search(entry->addr, head);
168 if (iter != NULL &&
169 iter->addr == entry->addr && iter->mask == entry->mask)
170 return -EEXIST;
171
172 /* in order to speed up address searches through the list (the common
173 * case) we need to keep the list in order based on the size of the
174 * address mask such that the entry with the widest mask (smallest
175 * numerical value) appears first in the list */
176 list_for_each_entry_rcu(iter, head, list)
177 if (iter->valid &&
178 ntohl(entry->mask) > ntohl(iter->mask)) {
179 __list_add_rcu(&entry->list,
180 iter->list.prev,
181 &iter->list);
182 return 0;
183 }
184 list_add_tail_rcu(&entry->list, head);
185 return 0;
186}
187
188#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
189/**
190 * netlbl_af6list_add - Add a new IPv6 address entry to a list
191 * @entry: address entry
192 * @head: the list head
193 *
194 * Description:
195 * Add a new address entry to the list pointed to by @head. On success zero is
196 * returned, otherwise a negative value is returned. The caller is responsible
197 * for calling the necessary locking functions.
198 *
199 */
200int netlbl_af6list_add(struct netlbl_af6list *entry, struct list_head *head)
201{
202 struct netlbl_af6list *iter;
203
204 iter = netlbl_af6list_search(&entry->addr, head);
205 if (iter != NULL &&
206 ipv6_addr_equal(&iter->addr, &entry->addr) &&
207 ipv6_addr_equal(&iter->mask, &entry->mask))
208 return -EEXIST;
209
210 /* in order to speed up address searches through the list (the common
211 * case) we need to keep the list in order based on the size of the
212 * address mask such that the entry with the widest mask (smallest
213 * numerical value) appears first in the list */
214 list_for_each_entry_rcu(iter, head, list)
215 if (iter->valid &&
216 ipv6_addr_cmp(&entry->mask, &iter->mask) > 0) {
217 __list_add_rcu(&entry->list,
218 iter->list.prev,
219 &iter->list);
220 return 0;
221 }
222 list_add_tail_rcu(&entry->list, head);
223 return 0;
224}
225#endif /* IPv6 */
226
227/**
228 * netlbl_af4list_remove_entry - Remove an IPv4 address entry
229 * @entry: address entry
230 *
231 * Description:
232 * Remove the specified IP address entry. The caller is responsible for
233 * calling the necessary locking functions.
234 *
235 */
236void netlbl_af4list_remove_entry(struct netlbl_af4list *entry)
237{
238 entry->valid = 0;
239 list_del_rcu(&entry->list);
240}
241
242/**
243 * netlbl_af4list_remove - Remove an IPv4 address entry
244 * @addr: IP address
245 * @mask: IP address mask
246 * @head: the list head
247 *
248 * Description:
249 * Remove an IP address entry from the list pointed to by @head. Returns the
250 * entry on success, NULL on failure. The caller is responsible for calling
251 * the necessary locking functions.
252 *
253 */
254struct netlbl_af4list *netlbl_af4list_remove(__be32 addr, __be32 mask,
255 struct list_head *head)
256{
257 struct netlbl_af4list *entry;
258
259 entry = netlbl_af4list_search(addr, head);
260 if (entry != NULL && entry->addr == addr && entry->mask == mask) {
261 netlbl_af4list_remove_entry(entry);
262 return entry;
263 }
264
265 return NULL;
266}
267
268#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
269/**
270 * netlbl_af6list_remove_entry - Remove an IPv6 address entry
271 * @entry: address entry
272 *
273 * Description:
274 * Remove the specified IP address entry. The caller is responsible for
275 * calling the necessary locking functions.
276 *
277 */
278void netlbl_af6list_remove_entry(struct netlbl_af6list *entry)
279{
280 entry->valid = 0;
281 list_del_rcu(&entry->list);
282}
283
284/**
285 * netlbl_af6list_remove - Remove an IPv6 address entry
286 * @addr: IP address
287 * @mask: IP address mask
288 * @head: the list head
289 *
290 * Description:
291 * Remove an IP address entry from the list pointed to by @head. Returns the
292 * entry on success, NULL on failure. The caller is responsible for calling
293 * the necessary locking functions.
294 *
295 */
296struct netlbl_af6list *netlbl_af6list_remove(const struct in6_addr *addr,
297 const struct in6_addr *mask,
298 struct list_head *head)
299{
300 struct netlbl_af6list *entry;
301
302 entry = netlbl_af6list_search(addr, head);
303 if (entry != NULL &&
304 ipv6_addr_equal(&entry->addr, addr) &&
305 ipv6_addr_equal(&entry->mask, mask)) {
306 netlbl_af6list_remove_entry(entry);
307 return entry;
308 }
309
310 return NULL;
311}
312#endif /* IPv6 */
313
314/*
315 * Audit Helper Functions
316 */
317
318/**
319 * netlbl_af4list_audit_addr - Audit an IPv4 address
320 * @audit_buf: audit buffer
321 * @src: true if source address, false if destination
322 * @dev: network interface
323 * @addr: IP address
324 * @mask: IP address mask
325 *
326 * Description:
327 * Write the IPv4 address and address mask, if necessary, to @audit_buf.
328 *
329 */
330void netlbl_af4list_audit_addr(struct audit_buffer *audit_buf,
331 int src, const char *dev,
332 __be32 addr, __be32 mask)
333{
334 u32 mask_val = ntohl(mask);
335 char *dir = (src ? "src" : "dst");
336
337 if (dev != NULL)
338 audit_log_format(audit_buf, " netif=%s", dev);
339 audit_log_format(audit_buf, " %s=" NIPQUAD_FMT, dir, NIPQUAD(addr));
340 if (mask_val != 0xffffffff) {
341 u32 mask_len = 0;
342 while (mask_val > 0) {
343 mask_val <<= 1;
344 mask_len++;
345 }
346 audit_log_format(audit_buf, " %s_prefixlen=%d", dir, mask_len);
347 }
348}
349
350#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
351/**
352 * netlbl_af6list_audit_addr - Audit an IPv6 address
353 * @audit_buf: audit buffer
354 * @src: true if source address, false if destination
355 * @dev: network interface
356 * @addr: IP address
357 * @mask: IP address mask
358 *
359 * Description:
360 * Write the IPv6 address and address mask, if necessary, to @audit_buf.
361 *
362 */
363void netlbl_af6list_audit_addr(struct audit_buffer *audit_buf,
364 int src,
365 const char *dev,
366 const struct in6_addr *addr,
367 const struct in6_addr *mask)
368{
369 char *dir = (src ? "src" : "dst");
370
371 if (dev != NULL)
372 audit_log_format(audit_buf, " netif=%s", dev);
373 audit_log_format(audit_buf, " %s=" NIP6_FMT, dir, NIP6(*addr));
374 if (ntohl(mask->s6_addr32[3]) != 0xffffffff) {
375 u32 mask_len = 0;
376 u32 mask_val;
377 int iter = -1;
378 while (ntohl(mask->s6_addr32[++iter]) == 0xffffffff)
379 mask_len += 32;
380 mask_val = ntohl(mask->s6_addr32[iter]);
381 while (mask_val > 0) {
382 mask_val <<= 1;
383 mask_len++;
384 }
385 audit_log_format(audit_buf, " %s_prefixlen=%d", dir, mask_len);
386 }
387}
388#endif /* IPv6 */
diff --git a/net/netlabel/netlabel_addrlist.h b/net/netlabel/netlabel_addrlist.h
new file mode 100644
index 000000000000..0242bead405f
--- /dev/null
+++ b/net/netlabel/netlabel_addrlist.h
@@ -0,0 +1,189 @@
1/*
2 * NetLabel Network Address Lists
3 *
4 * This file contains network address list functions used to manage ordered
5 * lists of network addresses for use by the NetLabel subsystem. The NetLabel
6 * system manages static and dynamic label mappings for network protocols such
7 * as CIPSO and RIPSO.
8 *
9 * Author: Paul Moore <paul.moore@hp.com>
10 *
11 */
12
13/*
14 * (c) Copyright Hewlett-Packard Development Company, L.P., 2008
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
24 * the GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, write to the Free Software
28 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
29 *
30 */
31
32#ifndef _NETLABEL_ADDRLIST_H
33#define _NETLABEL_ADDRLIST_H
34
35#include <linux/types.h>
36#include <linux/rcupdate.h>
37#include <linux/list.h>
38#include <linux/in6.h>
39#include <linux/audit.h>
40
41/**
42 * struct netlbl_af4list - NetLabel IPv4 address list
43 * @addr: IPv4 address
44 * @mask: IPv4 address mask
45 * @valid: valid flag
46 * @list: list structure, used internally
47 */
48struct netlbl_af4list {
49 __be32 addr;
50 __be32 mask;
51
52 u32 valid;
53 struct list_head list;
54};
55
56/**
57 * struct netlbl_af6list - NetLabel IPv6 address list
58 * @addr: IPv6 address
59 * @mask: IPv6 address mask
60 * @valid: valid flag
61 * @list: list structure, used internally
62 */
63struct netlbl_af6list {
64 struct in6_addr addr;
65 struct in6_addr mask;
66
67 u32 valid;
68 struct list_head list;
69};
70
71#define __af4list_entry(ptr) container_of(ptr, struct netlbl_af4list, list)
72
73static inline struct netlbl_af4list *__af4list_valid(struct list_head *s,
74 struct list_head *h)
75{
76 struct list_head *i = s;
77 struct netlbl_af4list *n = __af4list_entry(s);
78 while (i != h && !n->valid) {
79 i = i->next;
80 n = __af4list_entry(i);
81 }
82 return n;
83}
84
85static inline struct netlbl_af4list *__af4list_valid_rcu(struct list_head *s,
86 struct list_head *h)
87{
88 struct list_head *i = s;
89 struct netlbl_af4list *n = __af4list_entry(s);
90 while (i != h && !n->valid) {
91 i = rcu_dereference(i->next);
92 n = __af4list_entry(i);
93 }
94 return n;
95}
96
97#define netlbl_af4list_foreach(iter, head) \
98 for (iter = __af4list_valid((head)->next, head); \
99 prefetch(iter->list.next), &iter->list != (head); \
100 iter = __af4list_valid(iter->list.next, head))
101
102#define netlbl_af4list_foreach_rcu(iter, head) \
103 for (iter = __af4list_valid_rcu((head)->next, head); \
104 prefetch(iter->list.next), &iter->list != (head); \
105 iter = __af4list_valid_rcu(iter->list.next, head))
106
107#define netlbl_af4list_foreach_safe(iter, tmp, head) \
108 for (iter = __af4list_valid((head)->next, head), \
109 tmp = __af4list_valid(iter->list.next, head); \
110 &iter->list != (head); \
111 iter = tmp, tmp = __af4list_valid(iter->list.next, head))
112
113int netlbl_af4list_add(struct netlbl_af4list *entry,
114 struct list_head *head);
115struct netlbl_af4list *netlbl_af4list_remove(__be32 addr, __be32 mask,
116 struct list_head *head);
117void netlbl_af4list_remove_entry(struct netlbl_af4list *entry);
118struct netlbl_af4list *netlbl_af4list_search(__be32 addr,
119 struct list_head *head);
120struct netlbl_af4list *netlbl_af4list_search_exact(__be32 addr,
121 __be32 mask,
122 struct list_head *head);
123void netlbl_af4list_audit_addr(struct audit_buffer *audit_buf,
124 int src, const char *dev,
125 __be32 addr, __be32 mask);
126
127#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
128
129#define __af6list_entry(ptr) container_of(ptr, struct netlbl_af6list, list)
130
131static inline struct netlbl_af6list *__af6list_valid(struct list_head *s,
132 struct list_head *h)
133{
134 struct list_head *i = s;
135 struct netlbl_af6list *n = __af6list_entry(s);
136 while (i != h && !n->valid) {
137 i = i->next;
138 n = __af6list_entry(i);
139 }
140 return n;
141}
142
143static inline struct netlbl_af6list *__af6list_valid_rcu(struct list_head *s,
144 struct list_head *h)
145{
146 struct list_head *i = s;
147 struct netlbl_af6list *n = __af6list_entry(s);
148 while (i != h && !n->valid) {
149 i = rcu_dereference(i->next);
150 n = __af6list_entry(i);
151 }
152 return n;
153}
154
155#define netlbl_af6list_foreach(iter, head) \
156 for (iter = __af6list_valid((head)->next, head); \
157 prefetch(iter->list.next), &iter->list != (head); \
158 iter = __af6list_valid(iter->list.next, head))
159
160#define netlbl_af6list_foreach_rcu(iter, head) \
161 for (iter = __af6list_valid_rcu((head)->next, head); \
162 prefetch(iter->list.next), &iter->list != (head); \
163 iter = __af6list_valid_rcu(iter->list.next, head))
164
165#define netlbl_af6list_foreach_safe(iter, tmp, head) \
166 for (iter = __af6list_valid((head)->next, head), \
167 tmp = __af6list_valid(iter->list.next, head); \
168 &iter->list != (head); \
169 iter = tmp, tmp = __af6list_valid(iter->list.next, head))
170
171int netlbl_af6list_add(struct netlbl_af6list *entry,
172 struct list_head *head);
173struct netlbl_af6list *netlbl_af6list_remove(const struct in6_addr *addr,
174 const struct in6_addr *mask,
175 struct list_head *head);
176void netlbl_af6list_remove_entry(struct netlbl_af6list *entry);
177struct netlbl_af6list *netlbl_af6list_search(const struct in6_addr *addr,
178 struct list_head *head);
179struct netlbl_af6list *netlbl_af6list_search_exact(const struct in6_addr *addr,
180 const struct in6_addr *mask,
181 struct list_head *head);
182void netlbl_af6list_audit_addr(struct audit_buffer *audit_buf,
183 int src,
184 const char *dev,
185 const struct in6_addr *addr,
186 const struct in6_addr *mask);
187#endif /* IPV6 */
188
189#endif
diff --git a/net/netlabel/netlabel_cipso_v4.c b/net/netlabel/netlabel_cipso_v4.c
index 0aec318bf0ef..fff32b70efa9 100644
--- a/net/netlabel/netlabel_cipso_v4.c
+++ b/net/netlabel/netlabel_cipso_v4.c
@@ -43,6 +43,7 @@
43#include "netlabel_user.h" 43#include "netlabel_user.h"
44#include "netlabel_cipso_v4.h" 44#include "netlabel_cipso_v4.h"
45#include "netlabel_mgmt.h" 45#include "netlabel_mgmt.h"
46#include "netlabel_domainhash.h"
46 47
47/* Argument struct for cipso_v4_doi_walk() */ 48/* Argument struct for cipso_v4_doi_walk() */
48struct netlbl_cipsov4_doiwalk_arg { 49struct netlbl_cipsov4_doiwalk_arg {
@@ -51,6 +52,12 @@ struct netlbl_cipsov4_doiwalk_arg {
51 u32 seq; 52 u32 seq;
52}; 53};
53 54
55/* Argument struct for netlbl_domhsh_walk() */
56struct netlbl_domhsh_walk_arg {
57 struct netlbl_audit *audit_info;
58 u32 doi;
59};
60
54/* NetLabel Generic NETLINK CIPSOv4 family */ 61/* NetLabel Generic NETLINK CIPSOv4 family */
55static struct genl_family netlbl_cipsov4_gnl_family = { 62static struct genl_family netlbl_cipsov4_gnl_family = {
56 .id = GENL_ID_GENERATE, 63 .id = GENL_ID_GENERATE,
@@ -81,32 +88,6 @@ static const struct nla_policy netlbl_cipsov4_genl_policy[NLBL_CIPSOV4_A_MAX + 1
81 */ 88 */
82 89
83/** 90/**
84 * netlbl_cipsov4_doi_free - Frees a CIPSO V4 DOI definition
85 * @entry: the entry's RCU field
86 *
87 * Description:
88 * This function is designed to be used as a callback to the call_rcu()
89 * function so that the memory allocated to the DOI definition can be released
90 * safely.
91 *
92 */
93void netlbl_cipsov4_doi_free(struct rcu_head *entry)
94{
95 struct cipso_v4_doi *ptr;
96
97 ptr = container_of(entry, struct cipso_v4_doi, rcu);
98 switch (ptr->type) {
99 case CIPSO_V4_MAP_STD:
100 kfree(ptr->map.std->lvl.cipso);
101 kfree(ptr->map.std->lvl.local);
102 kfree(ptr->map.std->cat.cipso);
103 kfree(ptr->map.std->cat.local);
104 break;
105 }
106 kfree(ptr);
107}
108
109/**
110 * netlbl_cipsov4_add_common - Parse the common sections of a ADD message 91 * netlbl_cipsov4_add_common - Parse the common sections of a ADD message
111 * @info: the Generic NETLINK info block 92 * @info: the Generic NETLINK info block
112 * @doi_def: the CIPSO V4 DOI definition 93 * @doi_def: the CIPSO V4 DOI definition
@@ -151,9 +132,9 @@ static int netlbl_cipsov4_add_common(struct genl_info *info,
151 * @info: the Generic NETLINK info block 132 * @info: the Generic NETLINK info block
152 * 133 *
153 * Description: 134 * Description:
154 * Create a new CIPSO_V4_MAP_STD DOI definition based on the given ADD message 135 * Create a new CIPSO_V4_MAP_TRANS DOI definition based on the given ADD
155 * and add it to the CIPSO V4 engine. Return zero on success and non-zero on 136 * message and add it to the CIPSO V4 engine. Return zero on success and
156 * error. 137 * non-zero on error.
157 * 138 *
158 */ 139 */
159static int netlbl_cipsov4_add_std(struct genl_info *info) 140static int netlbl_cipsov4_add_std(struct genl_info *info)
@@ -183,7 +164,7 @@ static int netlbl_cipsov4_add_std(struct genl_info *info)
183 ret_val = -ENOMEM; 164 ret_val = -ENOMEM;
184 goto add_std_failure; 165 goto add_std_failure;
185 } 166 }
186 doi_def->type = CIPSO_V4_MAP_STD; 167 doi_def->type = CIPSO_V4_MAP_TRANS;
187 168
188 ret_val = netlbl_cipsov4_add_common(info, doi_def); 169 ret_val = netlbl_cipsov4_add_common(info, doi_def);
189 if (ret_val != 0) 170 if (ret_val != 0)
@@ -342,7 +323,7 @@ static int netlbl_cipsov4_add_std(struct genl_info *info)
342 323
343add_std_failure: 324add_std_failure:
344 if (doi_def) 325 if (doi_def)
345 netlbl_cipsov4_doi_free(&doi_def->rcu); 326 cipso_v4_doi_free(doi_def);
346 return ret_val; 327 return ret_val;
347} 328}
348 329
@@ -379,7 +360,44 @@ static int netlbl_cipsov4_add_pass(struct genl_info *info)
379 return 0; 360 return 0;
380 361
381add_pass_failure: 362add_pass_failure:
382 netlbl_cipsov4_doi_free(&doi_def->rcu); 363 cipso_v4_doi_free(doi_def);
364 return ret_val;
365}
366
367/**
368 * netlbl_cipsov4_add_local - Adds a CIPSO V4 DOI definition
369 * @info: the Generic NETLINK info block
370 *
371 * Description:
372 * Create a new CIPSO_V4_MAP_LOCAL DOI definition based on the given ADD
373 * message and add it to the CIPSO V4 engine. Return zero on success and
374 * non-zero on error.
375 *
376 */
377static int netlbl_cipsov4_add_local(struct genl_info *info)
378{
379 int ret_val;
380 struct cipso_v4_doi *doi_def = NULL;
381
382 if (!info->attrs[NLBL_CIPSOV4_A_TAGLST])
383 return -EINVAL;
384
385 doi_def = kmalloc(sizeof(*doi_def), GFP_KERNEL);
386 if (doi_def == NULL)
387 return -ENOMEM;
388 doi_def->type = CIPSO_V4_MAP_LOCAL;
389
390 ret_val = netlbl_cipsov4_add_common(info, doi_def);
391 if (ret_val != 0)
392 goto add_local_failure;
393
394 ret_val = cipso_v4_doi_add(doi_def);
395 if (ret_val != 0)
396 goto add_local_failure;
397 return 0;
398
399add_local_failure:
400 cipso_v4_doi_free(doi_def);
383 return ret_val; 401 return ret_val;
384} 402}
385 403
@@ -412,14 +430,18 @@ static int netlbl_cipsov4_add(struct sk_buff *skb, struct genl_info *info)
412 430
413 type = nla_get_u32(info->attrs[NLBL_CIPSOV4_A_MTYPE]); 431 type = nla_get_u32(info->attrs[NLBL_CIPSOV4_A_MTYPE]);
414 switch (type) { 432 switch (type) {
415 case CIPSO_V4_MAP_STD: 433 case CIPSO_V4_MAP_TRANS:
416 type_str = "std"; 434 type_str = "trans";
417 ret_val = netlbl_cipsov4_add_std(info); 435 ret_val = netlbl_cipsov4_add_std(info);
418 break; 436 break;
419 case CIPSO_V4_MAP_PASS: 437 case CIPSO_V4_MAP_PASS:
420 type_str = "pass"; 438 type_str = "pass";
421 ret_val = netlbl_cipsov4_add_pass(info); 439 ret_val = netlbl_cipsov4_add_pass(info);
422 break; 440 break;
441 case CIPSO_V4_MAP_LOCAL:
442 type_str = "local";
443 ret_val = netlbl_cipsov4_add_local(info);
444 break;
423 } 445 }
424 if (ret_val == 0) 446 if (ret_val == 0)
425 atomic_inc(&netlabel_mgmt_protocount); 447 atomic_inc(&netlabel_mgmt_protocount);
@@ -491,7 +513,7 @@ list_start:
491 doi_def = cipso_v4_doi_getdef(doi); 513 doi_def = cipso_v4_doi_getdef(doi);
492 if (doi_def == NULL) { 514 if (doi_def == NULL) {
493 ret_val = -EINVAL; 515 ret_val = -EINVAL;
494 goto list_failure; 516 goto list_failure_lock;
495 } 517 }
496 518
497 ret_val = nla_put_u32(ans_skb, NLBL_CIPSOV4_A_MTYPE, doi_def->type); 519 ret_val = nla_put_u32(ans_skb, NLBL_CIPSOV4_A_MTYPE, doi_def->type);
@@ -516,7 +538,7 @@ list_start:
516 nla_nest_end(ans_skb, nla_a); 538 nla_nest_end(ans_skb, nla_a);
517 539
518 switch (doi_def->type) { 540 switch (doi_def->type) {
519 case CIPSO_V4_MAP_STD: 541 case CIPSO_V4_MAP_TRANS:
520 nla_a = nla_nest_start(ans_skb, NLBL_CIPSOV4_A_MLSLVLLST); 542 nla_a = nla_nest_start(ans_skb, NLBL_CIPSOV4_A_MLSLVLLST);
521 if (nla_a == NULL) { 543 if (nla_a == NULL) {
522 ret_val = -ENOMEM; 544 ret_val = -ENOMEM;
@@ -655,7 +677,7 @@ static int netlbl_cipsov4_listall(struct sk_buff *skb,
655 struct netlink_callback *cb) 677 struct netlink_callback *cb)
656{ 678{
657 struct netlbl_cipsov4_doiwalk_arg cb_arg; 679 struct netlbl_cipsov4_doiwalk_arg cb_arg;
658 int doi_skip = cb->args[0]; 680 u32 doi_skip = cb->args[0];
659 681
660 cb_arg.nl_cb = cb; 682 cb_arg.nl_cb = cb;
661 cb_arg.skb = skb; 683 cb_arg.skb = skb;
@@ -668,6 +690,29 @@ static int netlbl_cipsov4_listall(struct sk_buff *skb,
668} 690}
669 691
670/** 692/**
693 * netlbl_cipsov4_remove_cb - netlbl_cipsov4_remove() callback for REMOVE
694 * @entry: LSM domain mapping entry
695 * @arg: the netlbl_domhsh_walk_arg structure
696 *
697 * Description:
698 * This function is intended for use by netlbl_cipsov4_remove() as the callback
699 * for the netlbl_domhsh_walk() function; it removes LSM domain map entries
700 * which are associated with the CIPSO DOI specified in @arg. Returns zero on
701 * success, negative values on failure.
702 *
703 */
704static int netlbl_cipsov4_remove_cb(struct netlbl_dom_map *entry, void *arg)
705{
706 struct netlbl_domhsh_walk_arg *cb_arg = arg;
707
708 if (entry->type == NETLBL_NLTYPE_CIPSOV4 &&
709 entry->type_def.cipsov4->doi == cb_arg->doi)
710 return netlbl_domhsh_remove_entry(entry, cb_arg->audit_info);
711
712 return 0;
713}
714
715/**
671 * netlbl_cipsov4_remove - Handle a REMOVE message 716 * netlbl_cipsov4_remove - Handle a REMOVE message
672 * @skb: the NETLINK buffer 717 * @skb: the NETLINK buffer
673 * @info: the Generic NETLINK info block 718 * @info: the Generic NETLINK info block
@@ -681,8 +726,11 @@ static int netlbl_cipsov4_remove(struct sk_buff *skb, struct genl_info *info)
681{ 726{
682 int ret_val = -EINVAL; 727 int ret_val = -EINVAL;
683 u32 doi = 0; 728 u32 doi = 0;
729 struct netlbl_domhsh_walk_arg cb_arg;
684 struct audit_buffer *audit_buf; 730 struct audit_buffer *audit_buf;
685 struct netlbl_audit audit_info; 731 struct netlbl_audit audit_info;
732 u32 skip_bkt = 0;
733 u32 skip_chain = 0;
686 734
687 if (!info->attrs[NLBL_CIPSOV4_A_DOI]) 735 if (!info->attrs[NLBL_CIPSOV4_A_DOI])
688 return -EINVAL; 736 return -EINVAL;
@@ -690,11 +738,15 @@ static int netlbl_cipsov4_remove(struct sk_buff *skb, struct genl_info *info)
690 doi = nla_get_u32(info->attrs[NLBL_CIPSOV4_A_DOI]); 738 doi = nla_get_u32(info->attrs[NLBL_CIPSOV4_A_DOI]);
691 netlbl_netlink_auditinfo(skb, &audit_info); 739 netlbl_netlink_auditinfo(skb, &audit_info);
692 740
693 ret_val = cipso_v4_doi_remove(doi, 741 cb_arg.doi = doi;
694 &audit_info, 742 cb_arg.audit_info = &audit_info;
695 netlbl_cipsov4_doi_free); 743 ret_val = netlbl_domhsh_walk(&skip_bkt, &skip_chain,
696 if (ret_val == 0) 744 netlbl_cipsov4_remove_cb, &cb_arg);
697 atomic_dec(&netlabel_mgmt_protocount); 745 if (ret_val == 0 || ret_val == -ENOENT) {
746 ret_val = cipso_v4_doi_remove(doi, &audit_info);
747 if (ret_val == 0)
748 atomic_dec(&netlabel_mgmt_protocount);
749 }
698 750
699 audit_buf = netlbl_audit_start_common(AUDIT_MAC_CIPSOV4_DEL, 751 audit_buf = netlbl_audit_start_common(AUDIT_MAC_CIPSOV4_DEL,
700 &audit_info); 752 &audit_info);
diff --git a/net/netlabel/netlabel_cipso_v4.h b/net/netlabel/netlabel_cipso_v4.h
index 220cb9d06b49..c8a4079261f0 100644
--- a/net/netlabel/netlabel_cipso_v4.h
+++ b/net/netlabel/netlabel_cipso_v4.h
@@ -45,12 +45,13 @@
45 * NLBL_CIPSOV4_A_MTYPE 45 * NLBL_CIPSOV4_A_MTYPE
46 * NLBL_CIPSOV4_A_TAGLST 46 * NLBL_CIPSOV4_A_TAGLST
47 * 47 *
48 * If using CIPSO_V4_MAP_STD the following attributes are required: 48 * If using CIPSO_V4_MAP_TRANS the following attributes are required:
49 * 49 *
50 * NLBL_CIPSOV4_A_MLSLVLLST 50 * NLBL_CIPSOV4_A_MLSLVLLST
51 * NLBL_CIPSOV4_A_MLSCATLST 51 * NLBL_CIPSOV4_A_MLSCATLST
52 * 52 *
53 * If using CIPSO_V4_MAP_PASS no additional attributes are required. 53 * If using CIPSO_V4_MAP_PASS or CIPSO_V4_MAP_LOCAL no additional attributes
54 * are required.
54 * 55 *
55 * o REMOVE: 56 * o REMOVE:
56 * Sent by an application to remove a specific DOI mapping table from the 57 * Sent by an application to remove a specific DOI mapping table from the
@@ -76,12 +77,13 @@
76 * NLBL_CIPSOV4_A_MTYPE 77 * NLBL_CIPSOV4_A_MTYPE
77 * NLBL_CIPSOV4_A_TAGLST 78 * NLBL_CIPSOV4_A_TAGLST
78 * 79 *
79 * If using CIPSO_V4_MAP_STD the following attributes are required: 80 * If using CIPSO_V4_MAP_TRANS the following attributes are required:
80 * 81 *
81 * NLBL_CIPSOV4_A_MLSLVLLST 82 * NLBL_CIPSOV4_A_MLSLVLLST
82 * NLBL_CIPSOV4_A_MLSCATLST 83 * NLBL_CIPSOV4_A_MLSCATLST
83 * 84 *
84 * If using CIPSO_V4_MAP_PASS no additional attributes are required. 85 * If using CIPSO_V4_MAP_PASS or CIPSO_V4_MAP_LOCAL no additional attributes
86 * are required.
85 * 87 *
86 * o LISTALL: 88 * o LISTALL:
87 * This message is sent by an application to list the valid DOIs on the 89 * This message is sent by an application to list the valid DOIs on the
diff --git a/net/netlabel/netlabel_domainhash.c b/net/netlabel/netlabel_domainhash.c
index 643c032a3a57..5fadf10e5ddf 100644
--- a/net/netlabel/netlabel_domainhash.c
+++ b/net/netlabel/netlabel_domainhash.c
@@ -11,7 +11,7 @@
11 */ 11 */
12 12
13/* 13/*
14 * (c) Copyright Hewlett-Packard Development Company, L.P., 2006 14 * (c) Copyright Hewlett-Packard Development Company, L.P., 2006, 2008
15 * 15 *
16 * This program is free software; you can redistribute it and/or modify 16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by 17 * it under the terms of the GNU General Public License as published by
@@ -40,6 +40,7 @@
40#include <asm/bug.h> 40#include <asm/bug.h>
41 41
42#include "netlabel_mgmt.h" 42#include "netlabel_mgmt.h"
43#include "netlabel_addrlist.h"
43#include "netlabel_domainhash.h" 44#include "netlabel_domainhash.h"
44#include "netlabel_user.h" 45#include "netlabel_user.h"
45 46
@@ -72,8 +73,28 @@ static struct netlbl_dom_map *netlbl_domhsh_def = NULL;
72static void netlbl_domhsh_free_entry(struct rcu_head *entry) 73static void netlbl_domhsh_free_entry(struct rcu_head *entry)
73{ 74{
74 struct netlbl_dom_map *ptr; 75 struct netlbl_dom_map *ptr;
76 struct netlbl_af4list *iter4;
77 struct netlbl_af4list *tmp4;
78#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
79 struct netlbl_af6list *iter6;
80 struct netlbl_af6list *tmp6;
81#endif /* IPv6 */
75 82
76 ptr = container_of(entry, struct netlbl_dom_map, rcu); 83 ptr = container_of(entry, struct netlbl_dom_map, rcu);
84 if (ptr->type == NETLBL_NLTYPE_ADDRSELECT) {
85 netlbl_af4list_foreach_safe(iter4, tmp4,
86 &ptr->type_def.addrsel->list4) {
87 netlbl_af4list_remove_entry(iter4);
88 kfree(netlbl_domhsh_addr4_entry(iter4));
89 }
90#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
91 netlbl_af6list_foreach_safe(iter6, tmp6,
92 &ptr->type_def.addrsel->list6) {
93 netlbl_af6list_remove_entry(iter6);
94 kfree(netlbl_domhsh_addr6_entry(iter6));
95 }
96#endif /* IPv6 */
97 }
77 kfree(ptr->domain); 98 kfree(ptr->domain);
78 kfree(ptr); 99 kfree(ptr);
79} 100}
@@ -115,13 +136,13 @@ static u32 netlbl_domhsh_hash(const char *key)
115static struct netlbl_dom_map *netlbl_domhsh_search(const char *domain) 136static struct netlbl_dom_map *netlbl_domhsh_search(const char *domain)
116{ 137{
117 u32 bkt; 138 u32 bkt;
139 struct list_head *bkt_list;
118 struct netlbl_dom_map *iter; 140 struct netlbl_dom_map *iter;
119 141
120 if (domain != NULL) { 142 if (domain != NULL) {
121 bkt = netlbl_domhsh_hash(domain); 143 bkt = netlbl_domhsh_hash(domain);
122 list_for_each_entry_rcu(iter, 144 bkt_list = &rcu_dereference(netlbl_domhsh)->tbl[bkt];
123 &rcu_dereference(netlbl_domhsh)->tbl[bkt], 145 list_for_each_entry_rcu(iter, bkt_list, list)
124 list)
125 if (iter->valid && strcmp(iter->domain, domain) == 0) 146 if (iter->valid && strcmp(iter->domain, domain) == 0)
126 return iter; 147 return iter;
127 } 148 }
@@ -156,6 +177,69 @@ static struct netlbl_dom_map *netlbl_domhsh_search_def(const char *domain)
156 return entry; 177 return entry;
157} 178}
158 179
180/**
181 * netlbl_domhsh_audit_add - Generate an audit entry for an add event
182 * @entry: the entry being added
183 * @addr4: the IPv4 address information
184 * @addr6: the IPv6 address information
185 * @result: the result code
186 * @audit_info: NetLabel audit information
187 *
188 * Description:
189 * Generate an audit record for adding a new NetLabel/LSM mapping entry with
190 * the given information. Caller is responsibile for holding the necessary
191 * locks.
192 *
193 */
194static void netlbl_domhsh_audit_add(struct netlbl_dom_map *entry,
195 struct netlbl_af4list *addr4,
196 struct netlbl_af6list *addr6,
197 int result,
198 struct netlbl_audit *audit_info)
199{
200 struct audit_buffer *audit_buf;
201 struct cipso_v4_doi *cipsov4 = NULL;
202 u32 type;
203
204 audit_buf = netlbl_audit_start_common(AUDIT_MAC_MAP_ADD, audit_info);
205 if (audit_buf != NULL) {
206 audit_log_format(audit_buf, " nlbl_domain=%s",
207 entry->domain ? entry->domain : "(default)");
208 if (addr4 != NULL) {
209 struct netlbl_domaddr4_map *map4;
210 map4 = netlbl_domhsh_addr4_entry(addr4);
211 type = map4->type;
212 cipsov4 = map4->type_def.cipsov4;
213 netlbl_af4list_audit_addr(audit_buf, 0, NULL,
214 addr4->addr, addr4->mask);
215#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
216 } else if (addr6 != NULL) {
217 struct netlbl_domaddr6_map *map6;
218 map6 = netlbl_domhsh_addr6_entry(addr6);
219 type = map6->type;
220 netlbl_af6list_audit_addr(audit_buf, 0, NULL,
221 &addr6->addr, &addr6->mask);
222#endif /* IPv6 */
223 } else {
224 type = entry->type;
225 cipsov4 = entry->type_def.cipsov4;
226 }
227 switch (type) {
228 case NETLBL_NLTYPE_UNLABELED:
229 audit_log_format(audit_buf, " nlbl_protocol=unlbl");
230 break;
231 case NETLBL_NLTYPE_CIPSOV4:
232 BUG_ON(cipsov4 == NULL);
233 audit_log_format(audit_buf,
234 " nlbl_protocol=cipsov4 cipso_doi=%u",
235 cipsov4->doi);
236 break;
237 }
238 audit_log_format(audit_buf, " res=%u", result == 0 ? 1 : 0);
239 audit_log_end(audit_buf);
240 }
241}
242
159/* 243/*
160 * Domain Hash Table Functions 244 * Domain Hash Table Functions
161 */ 245 */
@@ -213,74 +297,106 @@ int __init netlbl_domhsh_init(u32 size)
213int netlbl_domhsh_add(struct netlbl_dom_map *entry, 297int netlbl_domhsh_add(struct netlbl_dom_map *entry,
214 struct netlbl_audit *audit_info) 298 struct netlbl_audit *audit_info)
215{ 299{
216 int ret_val; 300 int ret_val = 0;
217 u32 bkt; 301 struct netlbl_dom_map *entry_old;
218 struct audit_buffer *audit_buf; 302 struct netlbl_af4list *iter4;
219 303 struct netlbl_af4list *tmp4;
220 switch (entry->type) { 304#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
221 case NETLBL_NLTYPE_UNLABELED: 305 struct netlbl_af6list *iter6;
222 ret_val = 0; 306 struct netlbl_af6list *tmp6;
223 break; 307#endif /* IPv6 */
224 case NETLBL_NLTYPE_CIPSOV4:
225 ret_val = cipso_v4_doi_domhsh_add(entry->type_def.cipsov4,
226 entry->domain);
227 break;
228 default:
229 return -EINVAL;
230 }
231 if (ret_val != 0)
232 return ret_val;
233
234 entry->valid = 1;
235 INIT_RCU_HEAD(&entry->rcu);
236 308
237 rcu_read_lock(); 309 rcu_read_lock();
310
238 spin_lock(&netlbl_domhsh_lock); 311 spin_lock(&netlbl_domhsh_lock);
239 if (entry->domain != NULL) { 312 if (entry->domain != NULL)
240 bkt = netlbl_domhsh_hash(entry->domain); 313 entry_old = netlbl_domhsh_search(entry->domain);
241 if (netlbl_domhsh_search(entry->domain) == NULL) 314 else
315 entry_old = netlbl_domhsh_search_def(entry->domain);
316 if (entry_old == NULL) {
317 entry->valid = 1;
318 INIT_RCU_HEAD(&entry->rcu);
319
320 if (entry->domain != NULL) {
321 u32 bkt = netlbl_domhsh_hash(entry->domain);
242 list_add_tail_rcu(&entry->list, 322 list_add_tail_rcu(&entry->list,
243 &rcu_dereference(netlbl_domhsh)->tbl[bkt]); 323 &rcu_dereference(netlbl_domhsh)->tbl[bkt]);
244 else 324 } else {
245 ret_val = -EEXIST; 325 INIT_LIST_HEAD(&entry->list);
246 } else {
247 INIT_LIST_HEAD(&entry->list);
248 if (rcu_dereference(netlbl_domhsh_def) == NULL)
249 rcu_assign_pointer(netlbl_domhsh_def, entry); 326 rcu_assign_pointer(netlbl_domhsh_def, entry);
250 else
251 ret_val = -EEXIST;
252 }
253 spin_unlock(&netlbl_domhsh_lock);
254 audit_buf = netlbl_audit_start_common(AUDIT_MAC_MAP_ADD, audit_info);
255 if (audit_buf != NULL) {
256 audit_log_format(audit_buf,
257 " nlbl_domain=%s",
258 entry->domain ? entry->domain : "(default)");
259 switch (entry->type) {
260 case NETLBL_NLTYPE_UNLABELED:
261 audit_log_format(audit_buf, " nlbl_protocol=unlbl");
262 break;
263 case NETLBL_NLTYPE_CIPSOV4:
264 audit_log_format(audit_buf,
265 " nlbl_protocol=cipsov4 cipso_doi=%u",
266 entry->type_def.cipsov4->doi);
267 break;
268 } 327 }
269 audit_log_format(audit_buf, " res=%u", ret_val == 0 ? 1 : 0);
270 audit_log_end(audit_buf);
271 }
272 rcu_read_unlock();
273 328
274 if (ret_val != 0) { 329 if (entry->type == NETLBL_NLTYPE_ADDRSELECT) {
275 switch (entry->type) { 330 netlbl_af4list_foreach_rcu(iter4,
276 case NETLBL_NLTYPE_CIPSOV4: 331 &entry->type_def.addrsel->list4)
277 if (cipso_v4_doi_domhsh_remove(entry->type_def.cipsov4, 332 netlbl_domhsh_audit_add(entry, iter4, NULL,
278 entry->domain) != 0) 333 ret_val, audit_info);
279 BUG(); 334#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
280 break; 335 netlbl_af6list_foreach_rcu(iter6,
336 &entry->type_def.addrsel->list6)
337 netlbl_domhsh_audit_add(entry, NULL, iter6,
338 ret_val, audit_info);
339#endif /* IPv6 */
340 } else
341 netlbl_domhsh_audit_add(entry, NULL, NULL,
342 ret_val, audit_info);
343 } else if (entry_old->type == NETLBL_NLTYPE_ADDRSELECT &&
344 entry->type == NETLBL_NLTYPE_ADDRSELECT) {
345 struct list_head *old_list4;
346 struct list_head *old_list6;
347
348 old_list4 = &entry_old->type_def.addrsel->list4;
349 old_list6 = &entry_old->type_def.addrsel->list6;
350
351 /* we only allow the addition of address selectors if all of
352 * the selectors do not exist in the existing domain map */
353 netlbl_af4list_foreach_rcu(iter4,
354 &entry->type_def.addrsel->list4)
355 if (netlbl_af4list_search_exact(iter4->addr,
356 iter4->mask,
357 old_list4)) {
358 ret_val = -EEXIST;
359 goto add_return;
360 }
361#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
362 netlbl_af6list_foreach_rcu(iter6,
363 &entry->type_def.addrsel->list6)
364 if (netlbl_af6list_search_exact(&iter6->addr,
365 &iter6->mask,
366 old_list6)) {
367 ret_val = -EEXIST;
368 goto add_return;
369 }
370#endif /* IPv6 */
371
372 netlbl_af4list_foreach_safe(iter4, tmp4,
373 &entry->type_def.addrsel->list4) {
374 netlbl_af4list_remove_entry(iter4);
375 iter4->valid = 1;
376 ret_val = netlbl_af4list_add(iter4, old_list4);
377 netlbl_domhsh_audit_add(entry_old, iter4, NULL,
378 ret_val, audit_info);
379 if (ret_val != 0)
380 goto add_return;
281 } 381 }
282 } 382#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
383 netlbl_af6list_foreach_safe(iter6, tmp6,
384 &entry->type_def.addrsel->list6) {
385 netlbl_af6list_remove_entry(iter6);
386 iter6->valid = 1;
387 ret_val = netlbl_af6list_add(iter6, old_list6);
388 netlbl_domhsh_audit_add(entry_old, NULL, iter6,
389 ret_val, audit_info);
390 if (ret_val != 0)
391 goto add_return;
392 }
393#endif /* IPv6 */
394 } else
395 ret_val = -EINVAL;
283 396
397add_return:
398 spin_unlock(&netlbl_domhsh_lock);
399 rcu_read_unlock();
284 return ret_val; 400 return ret_val;
285} 401}
286 402
@@ -302,35 +418,26 @@ int netlbl_domhsh_add_default(struct netlbl_dom_map *entry,
302} 418}
303 419
304/** 420/**
305 * netlbl_domhsh_remove - Removes an entry from the domain hash table 421 * netlbl_domhsh_remove_entry - Removes a given entry from the domain table
306 * @domain: the domain to remove 422 * @entry: the entry to remove
307 * @audit_info: NetLabel audit information 423 * @audit_info: NetLabel audit information
308 * 424 *
309 * Description: 425 * Description:
310 * Removes an entry from the domain hash table and handles any updates to the 426 * Removes an entry from the domain hash table and handles any updates to the
311 * lower level protocol handler (i.e. CIPSO). Returns zero on success, 427 * lower level protocol handler (i.e. CIPSO). Caller is responsible for
312 * negative on failure. 428 * ensuring that the RCU read lock is held. Returns zero on success, negative
429 * on failure.
313 * 430 *
314 */ 431 */
315int netlbl_domhsh_remove(const char *domain, struct netlbl_audit *audit_info) 432int netlbl_domhsh_remove_entry(struct netlbl_dom_map *entry,
433 struct netlbl_audit *audit_info)
316{ 434{
317 int ret_val = -ENOENT; 435 int ret_val = 0;
318 struct netlbl_dom_map *entry;
319 struct audit_buffer *audit_buf; 436 struct audit_buffer *audit_buf;
320 437
321 rcu_read_lock();
322 if (domain)
323 entry = netlbl_domhsh_search(domain);
324 else
325 entry = netlbl_domhsh_search_def(domain);
326 if (entry == NULL) 438 if (entry == NULL)
327 goto remove_return; 439 return -ENOENT;
328 switch (entry->type) { 440
329 case NETLBL_NLTYPE_CIPSOV4:
330 cipso_v4_doi_domhsh_remove(entry->type_def.cipsov4,
331 entry->domain);
332 break;
333 }
334 spin_lock(&netlbl_domhsh_lock); 441 spin_lock(&netlbl_domhsh_lock);
335 if (entry->valid) { 442 if (entry->valid) {
336 entry->valid = 0; 443 entry->valid = 0;
@@ -338,8 +445,8 @@ int netlbl_domhsh_remove(const char *domain, struct netlbl_audit *audit_info)
338 list_del_rcu(&entry->list); 445 list_del_rcu(&entry->list);
339 else 446 else
340 rcu_assign_pointer(netlbl_domhsh_def, NULL); 447 rcu_assign_pointer(netlbl_domhsh_def, NULL);
341 ret_val = 0; 448 } else
342 } 449 ret_val = -ENOENT;
343 spin_unlock(&netlbl_domhsh_lock); 450 spin_unlock(&netlbl_domhsh_lock);
344 451
345 audit_buf = netlbl_audit_start_common(AUDIT_MAC_MAP_DEL, audit_info); 452 audit_buf = netlbl_audit_start_common(AUDIT_MAC_MAP_DEL, audit_info);
@@ -351,10 +458,54 @@ int netlbl_domhsh_remove(const char *domain, struct netlbl_audit *audit_info)
351 audit_log_end(audit_buf); 458 audit_log_end(audit_buf);
352 } 459 }
353 460
354remove_return: 461 if (ret_val == 0) {
355 rcu_read_unlock(); 462 struct netlbl_af4list *iter4;
356 if (ret_val == 0) 463 struct netlbl_domaddr4_map *map4;
464
465 switch (entry->type) {
466 case NETLBL_NLTYPE_ADDRSELECT:
467 netlbl_af4list_foreach_rcu(iter4,
468 &entry->type_def.addrsel->list4) {
469 map4 = netlbl_domhsh_addr4_entry(iter4);
470 cipso_v4_doi_putdef(map4->type_def.cipsov4);
471 }
472 /* no need to check the IPv6 list since we currently
473 * support only unlabeled protocols for IPv6 */
474 break;
475 case NETLBL_NLTYPE_CIPSOV4:
476 cipso_v4_doi_putdef(entry->type_def.cipsov4);
477 break;
478 }
357 call_rcu(&entry->rcu, netlbl_domhsh_free_entry); 479 call_rcu(&entry->rcu, netlbl_domhsh_free_entry);
480 }
481
482 return ret_val;
483}
484
485/**
486 * netlbl_domhsh_remove - Removes an entry from the domain hash table
487 * @domain: the domain to remove
488 * @audit_info: NetLabel audit information
489 *
490 * Description:
491 * Removes an entry from the domain hash table and handles any updates to the
492 * lower level protocol handler (i.e. CIPSO). Returns zero on success,
493 * negative on failure.
494 *
495 */
496int netlbl_domhsh_remove(const char *domain, struct netlbl_audit *audit_info)
497{
498 int ret_val;
499 struct netlbl_dom_map *entry;
500
501 rcu_read_lock();
502 if (domain)
503 entry = netlbl_domhsh_search(domain);
504 else
505 entry = netlbl_domhsh_search_def(domain);
506 ret_val = netlbl_domhsh_remove_entry(entry, audit_info);
507 rcu_read_unlock();
508
358 return ret_val; 509 return ret_val;
359} 510}
360 511
@@ -389,6 +540,70 @@ struct netlbl_dom_map *netlbl_domhsh_getentry(const char *domain)
389} 540}
390 541
391/** 542/**
543 * netlbl_domhsh_getentry_af4 - Get an entry from the domain hash table
544 * @domain: the domain name to search for
545 * @addr: the IP address to search for
546 *
547 * Description:
548 * Look through the domain hash table searching for an entry to match @domain
549 * and @addr, return a pointer to a copy of the entry or NULL. The caller is
550 * responsible for ensuring that rcu_read_[un]lock() is called.
551 *
552 */
553struct netlbl_domaddr4_map *netlbl_domhsh_getentry_af4(const char *domain,
554 __be32 addr)
555{
556 struct netlbl_dom_map *dom_iter;
557 struct netlbl_af4list *addr_iter;
558
559 dom_iter = netlbl_domhsh_search_def(domain);
560 if (dom_iter == NULL)
561 return NULL;
562 if (dom_iter->type != NETLBL_NLTYPE_ADDRSELECT)
563 return NULL;
564
565 addr_iter = netlbl_af4list_search(addr,
566 &dom_iter->type_def.addrsel->list4);
567 if (addr_iter == NULL)
568 return NULL;
569
570 return netlbl_domhsh_addr4_entry(addr_iter);
571}
572
573#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
574/**
575 * netlbl_domhsh_getentry_af6 - Get an entry from the domain hash table
576 * @domain: the domain name to search for
577 * @addr: the IP address to search for
578 *
579 * Description:
580 * Look through the domain hash table searching for an entry to match @domain
581 * and @addr, return a pointer to a copy of the entry or NULL. The caller is
582 * responsible for ensuring that rcu_read_[un]lock() is called.
583 *
584 */
585struct netlbl_domaddr6_map *netlbl_domhsh_getentry_af6(const char *domain,
586 const struct in6_addr *addr)
587{
588 struct netlbl_dom_map *dom_iter;
589 struct netlbl_af6list *addr_iter;
590
591 dom_iter = netlbl_domhsh_search_def(domain);
592 if (dom_iter == NULL)
593 return NULL;
594 if (dom_iter->type != NETLBL_NLTYPE_ADDRSELECT)
595 return NULL;
596
597 addr_iter = netlbl_af6list_search(addr,
598 &dom_iter->type_def.addrsel->list6);
599 if (addr_iter == NULL)
600 return NULL;
601
602 return netlbl_domhsh_addr6_entry(addr_iter);
603}
604#endif /* IPv6 */
605
606/**
392 * netlbl_domhsh_walk - Iterate through the domain mapping hash table 607 * netlbl_domhsh_walk - Iterate through the domain mapping hash table
393 * @skip_bkt: the number of buckets to skip at the start 608 * @skip_bkt: the number of buckets to skip at the start
394 * @skip_chain: the number of entries to skip in the first iterated bucket 609 * @skip_chain: the number of entries to skip in the first iterated bucket
@@ -410,6 +625,7 @@ int netlbl_domhsh_walk(u32 *skip_bkt,
410{ 625{
411 int ret_val = -ENOENT; 626 int ret_val = -ENOENT;
412 u32 iter_bkt; 627 u32 iter_bkt;
628 struct list_head *iter_list;
413 struct netlbl_dom_map *iter_entry; 629 struct netlbl_dom_map *iter_entry;
414 u32 chain_cnt = 0; 630 u32 chain_cnt = 0;
415 631
@@ -417,9 +633,8 @@ int netlbl_domhsh_walk(u32 *skip_bkt,
417 for (iter_bkt = *skip_bkt; 633 for (iter_bkt = *skip_bkt;
418 iter_bkt < rcu_dereference(netlbl_domhsh)->size; 634 iter_bkt < rcu_dereference(netlbl_domhsh)->size;
419 iter_bkt++, chain_cnt = 0) { 635 iter_bkt++, chain_cnt = 0) {
420 list_for_each_entry_rcu(iter_entry, 636 iter_list = &rcu_dereference(netlbl_domhsh)->tbl[iter_bkt];
421 &rcu_dereference(netlbl_domhsh)->tbl[iter_bkt], 637 list_for_each_entry_rcu(iter_entry, iter_list, list)
422 list)
423 if (iter_entry->valid) { 638 if (iter_entry->valid) {
424 if (chain_cnt++ < *skip_chain) 639 if (chain_cnt++ < *skip_chain)
425 continue; 640 continue;
diff --git a/net/netlabel/netlabel_domainhash.h b/net/netlabel/netlabel_domainhash.h
index 8220990ceb96..bfcb6763a1a1 100644
--- a/net/netlabel/netlabel_domainhash.h
+++ b/net/netlabel/netlabel_domainhash.h
@@ -11,7 +11,7 @@
11 */ 11 */
12 12
13/* 13/*
14 * (c) Copyright Hewlett-Packard Development Company, L.P., 2006 14 * (c) Copyright Hewlett-Packard Development Company, L.P., 2006, 2008
15 * 15 *
16 * This program is free software; you can redistribute it and/or modify 16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by 17 * it under the terms of the GNU General Public License as published by
@@ -36,16 +36,43 @@
36#include <linux/rcupdate.h> 36#include <linux/rcupdate.h>
37#include <linux/list.h> 37#include <linux/list.h>
38 38
39#include "netlabel_addrlist.h"
40
39/* Domain hash table size */ 41/* Domain hash table size */
40/* XXX - currently this number is an uneducated guess */ 42/* XXX - currently this number is an uneducated guess */
41#define NETLBL_DOMHSH_BITSIZE 7 43#define NETLBL_DOMHSH_BITSIZE 7
42 44
43/* Domain mapping definition struct */ 45/* Domain mapping definition structures */
46#define netlbl_domhsh_addr4_entry(iter) \
47 container_of(iter, struct netlbl_domaddr4_map, list)
48struct netlbl_domaddr4_map {
49 u32 type;
50 union {
51 struct cipso_v4_doi *cipsov4;
52 } type_def;
53
54 struct netlbl_af4list list;
55};
56#define netlbl_domhsh_addr6_entry(iter) \
57 container_of(iter, struct netlbl_domaddr6_map, list)
58struct netlbl_domaddr6_map {
59 u32 type;
60
61 /* NOTE: no 'type_def' union needed at present since we don't currently
62 * support any IPv6 labeling protocols */
63
64 struct netlbl_af6list list;
65};
66struct netlbl_domaddr_map {
67 struct list_head list4;
68 struct list_head list6;
69};
44struct netlbl_dom_map { 70struct netlbl_dom_map {
45 char *domain; 71 char *domain;
46 u32 type; 72 u32 type;
47 union { 73 union {
48 struct cipso_v4_doi *cipsov4; 74 struct cipso_v4_doi *cipsov4;
75 struct netlbl_domaddr_map *addrsel;
49 } type_def; 76 } type_def;
50 77
51 u32 valid; 78 u32 valid;
@@ -61,12 +88,21 @@ int netlbl_domhsh_add(struct netlbl_dom_map *entry,
61 struct netlbl_audit *audit_info); 88 struct netlbl_audit *audit_info);
62int netlbl_domhsh_add_default(struct netlbl_dom_map *entry, 89int netlbl_domhsh_add_default(struct netlbl_dom_map *entry,
63 struct netlbl_audit *audit_info); 90 struct netlbl_audit *audit_info);
91int netlbl_domhsh_remove_entry(struct netlbl_dom_map *entry,
92 struct netlbl_audit *audit_info);
64int netlbl_domhsh_remove(const char *domain, struct netlbl_audit *audit_info); 93int netlbl_domhsh_remove(const char *domain, struct netlbl_audit *audit_info);
65int netlbl_domhsh_remove_default(struct netlbl_audit *audit_info); 94int netlbl_domhsh_remove_default(struct netlbl_audit *audit_info);
66struct netlbl_dom_map *netlbl_domhsh_getentry(const char *domain); 95struct netlbl_dom_map *netlbl_domhsh_getentry(const char *domain);
96struct netlbl_domaddr4_map *netlbl_domhsh_getentry_af4(const char *domain,
97 __be32 addr);
67int netlbl_domhsh_walk(u32 *skip_bkt, 98int netlbl_domhsh_walk(u32 *skip_bkt,
68 u32 *skip_chain, 99 u32 *skip_chain,
69 int (*callback) (struct netlbl_dom_map *entry, void *arg), 100 int (*callback) (struct netlbl_dom_map *entry, void *arg),
70 void *cb_arg); 101 void *cb_arg);
71 102
103#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
104struct netlbl_domaddr6_map *netlbl_domhsh_getentry_af6(const char *domain,
105 const struct in6_addr *addr);
106#endif /* IPv6 */
107
72#endif 108#endif
diff --git a/net/netlabel/netlabel_kapi.c b/net/netlabel/netlabel_kapi.c
index 39793a1a93aa..b32eceb3ab0d 100644
--- a/net/netlabel/netlabel_kapi.c
+++ b/net/netlabel/netlabel_kapi.c
@@ -10,7 +10,7 @@
10 */ 10 */
11 11
12/* 12/*
13 * (c) Copyright Hewlett-Packard Development Company, L.P., 2006 13 * (c) Copyright Hewlett-Packard Development Company, L.P., 2006, 2008
14 * 14 *
15 * This program is free software; you can redistribute it and/or modify 15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by 16 * it under the terms of the GNU General Public License as published by
@@ -82,7 +82,7 @@ int netlbl_cfg_unlbl_add_map(const char *domain,
82 82
83 entry = kzalloc(sizeof(*entry), GFP_ATOMIC); 83 entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
84 if (entry == NULL) 84 if (entry == NULL)
85 goto cfg_unlbl_add_map_failure; 85 return -ENOMEM;
86 if (domain != NULL) { 86 if (domain != NULL) {
87 entry->domain = kstrdup(domain, GFP_ATOMIC); 87 entry->domain = kstrdup(domain, GFP_ATOMIC);
88 if (entry->domain == NULL) 88 if (entry->domain == NULL)
@@ -104,49 +104,6 @@ cfg_unlbl_add_map_failure:
104} 104}
105 105
106/** 106/**
107 * netlbl_cfg_cipsov4_add - Add a new CIPSOv4 DOI definition
108 * @doi_def: the DOI definition
109 * @audit_info: NetLabel audit information
110 *
111 * Description:
112 * Add a new CIPSOv4 DOI definition to the NetLabel subsystem. Returns zero on
113 * success, negative values on failure.
114 *
115 */
116int netlbl_cfg_cipsov4_add(struct cipso_v4_doi *doi_def,
117 struct netlbl_audit *audit_info)
118{
119 int ret_val;
120 const char *type_str;
121 struct audit_buffer *audit_buf;
122
123 ret_val = cipso_v4_doi_add(doi_def);
124
125 audit_buf = netlbl_audit_start_common(AUDIT_MAC_CIPSOV4_ADD,
126 audit_info);
127 if (audit_buf != NULL) {
128 switch (doi_def->type) {
129 case CIPSO_V4_MAP_STD:
130 type_str = "std";
131 break;
132 case CIPSO_V4_MAP_PASS:
133 type_str = "pass";
134 break;
135 default:
136 type_str = "(unknown)";
137 }
138 audit_log_format(audit_buf,
139 " cipso_doi=%u cipso_type=%s res=%u",
140 doi_def->doi,
141 type_str,
142 ret_val == 0 ? 1 : 0);
143 audit_log_end(audit_buf);
144 }
145
146 return ret_val;
147}
148
149/**
150 * netlbl_cfg_cipsov4_add_map - Add a new CIPSOv4 DOI definition and mapping 107 * netlbl_cfg_cipsov4_add_map - Add a new CIPSOv4 DOI definition and mapping
151 * @doi_def: the DOI definition 108 * @doi_def: the DOI definition
152 * @domain: the domain mapping to add 109 * @domain: the domain mapping to add
@@ -164,58 +121,71 @@ int netlbl_cfg_cipsov4_add_map(struct cipso_v4_doi *doi_def,
164 struct netlbl_audit *audit_info) 121 struct netlbl_audit *audit_info)
165{ 122{
166 int ret_val = -ENOMEM; 123 int ret_val = -ENOMEM;
124 u32 doi;
125 u32 doi_type;
167 struct netlbl_dom_map *entry; 126 struct netlbl_dom_map *entry;
127 const char *type_str;
128 struct audit_buffer *audit_buf;
129
130 doi = doi_def->doi;
131 doi_type = doi_def->type;
168 132
169 entry = kzalloc(sizeof(*entry), GFP_ATOMIC); 133 entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
170 if (entry == NULL) 134 if (entry == NULL)
171 goto cfg_cipsov4_add_map_failure; 135 return -ENOMEM;
172 if (domain != NULL) { 136 if (domain != NULL) {
173 entry->domain = kstrdup(domain, GFP_ATOMIC); 137 entry->domain = kstrdup(domain, GFP_ATOMIC);
174 if (entry->domain == NULL) 138 if (entry->domain == NULL)
175 goto cfg_cipsov4_add_map_failure; 139 goto cfg_cipsov4_add_map_failure;
176 } 140 }
177 entry->type = NETLBL_NLTYPE_CIPSOV4;
178 entry->type_def.cipsov4 = doi_def;
179
180 /* Grab a RCU read lock here so nothing happens to the doi_def variable
181 * between adding it to the CIPSOv4 protocol engine and adding a
182 * domain mapping for it. */
183 141
184 rcu_read_lock(); 142 ret_val = cipso_v4_doi_add(doi_def);
185 ret_val = netlbl_cfg_cipsov4_add(doi_def, audit_info);
186 if (ret_val != 0) 143 if (ret_val != 0)
187 goto cfg_cipsov4_add_map_failure_unlock; 144 goto cfg_cipsov4_add_map_failure_remove_doi;
145 entry->type = NETLBL_NLTYPE_CIPSOV4;
146 entry->type_def.cipsov4 = cipso_v4_doi_getdef(doi);
147 if (entry->type_def.cipsov4 == NULL) {
148 ret_val = -ENOENT;
149 goto cfg_cipsov4_add_map_failure_remove_doi;
150 }
188 ret_val = netlbl_domhsh_add(entry, audit_info); 151 ret_val = netlbl_domhsh_add(entry, audit_info);
189 if (ret_val != 0) 152 if (ret_val != 0)
190 goto cfg_cipsov4_add_map_failure_remove_doi; 153 goto cfg_cipsov4_add_map_failure_release_doi;
191 rcu_read_unlock();
192 154
193 return 0; 155cfg_cipsov4_add_map_return:
156 audit_buf = netlbl_audit_start_common(AUDIT_MAC_CIPSOV4_ADD,
157 audit_info);
158 if (audit_buf != NULL) {
159 switch (doi_type) {
160 case CIPSO_V4_MAP_TRANS:
161 type_str = "trans";
162 break;
163 case CIPSO_V4_MAP_PASS:
164 type_str = "pass";
165 break;
166 case CIPSO_V4_MAP_LOCAL:
167 type_str = "local";
168 break;
169 default:
170 type_str = "(unknown)";
171 }
172 audit_log_format(audit_buf,
173 " cipso_doi=%u cipso_type=%s res=%u",
174 doi, type_str, ret_val == 0 ? 1 : 0);
175 audit_log_end(audit_buf);
176 }
194 177
178 return ret_val;
179
180cfg_cipsov4_add_map_failure_release_doi:
181 cipso_v4_doi_putdef(doi_def);
195cfg_cipsov4_add_map_failure_remove_doi: 182cfg_cipsov4_add_map_failure_remove_doi:
196 cipso_v4_doi_remove(doi_def->doi, audit_info, netlbl_cipsov4_doi_free); 183 cipso_v4_doi_remove(doi, audit_info);
197cfg_cipsov4_add_map_failure_unlock:
198 rcu_read_unlock();
199cfg_cipsov4_add_map_failure: 184cfg_cipsov4_add_map_failure:
200 if (entry != NULL) 185 if (entry != NULL)
201 kfree(entry->domain); 186 kfree(entry->domain);
202 kfree(entry); 187 kfree(entry);
203 return ret_val; 188 goto cfg_cipsov4_add_map_return;
204}
205
206/**
207 * netlbl_cfg_cipsov4_del - Removean existing CIPSOv4 DOI definition
208 * @doi: the CIPSO DOI value
209 * @audit_info: NetLabel audit information
210 *
211 * Description:
212 * Removes an existing CIPSOv4 DOI definition from the NetLabel subsystem.
213 * Returns zero on success, negative values on failure.
214 *
215 */
216int netlbl_cfg_cipsov4_del(u32 doi, struct netlbl_audit *audit_info)
217{
218 return cipso_v4_doi_remove(doi, audit_info, netlbl_cipsov4_doi_free);
219} 189}
220 190
221/* 191/*
@@ -452,7 +422,9 @@ int netlbl_enabled(void)
452 * Attach the correct label to the given socket using the security attributes 422 * Attach the correct label to the given socket using the security attributes
453 * specified in @secattr. This function requires exclusive access to @sk, 423 * specified in @secattr. This function requires exclusive access to @sk,
454 * which means it either needs to be in the process of being created or locked. 424 * which means it either needs to be in the process of being created or locked.
455 * Returns zero on success, negative values on failure. 425 * Returns zero on success, -EDESTADDRREQ if the domain is configured to use
426 * network address selectors (can't blindly label the socket), and negative
427 * values on all other failures.
456 * 428 *
457 */ 429 */
458int netlbl_sock_setattr(struct sock *sk, 430int netlbl_sock_setattr(struct sock *sk,
@@ -466,6 +438,9 @@ int netlbl_sock_setattr(struct sock *sk,
466 if (dom_entry == NULL) 438 if (dom_entry == NULL)
467 goto socket_setattr_return; 439 goto socket_setattr_return;
468 switch (dom_entry->type) { 440 switch (dom_entry->type) {
441 case NETLBL_NLTYPE_ADDRSELECT:
442 ret_val = -EDESTADDRREQ;
443 break;
469 case NETLBL_NLTYPE_CIPSOV4: 444 case NETLBL_NLTYPE_CIPSOV4:
470 ret_val = cipso_v4_sock_setattr(sk, 445 ret_val = cipso_v4_sock_setattr(sk,
471 dom_entry->type_def.cipsov4, 446 dom_entry->type_def.cipsov4,
@@ -484,6 +459,20 @@ socket_setattr_return:
484} 459}
485 460
486/** 461/**
462 * netlbl_sock_delattr - Delete all the NetLabel labels on a socket
463 * @sk: the socket
464 *
465 * Description:
466 * Remove all the NetLabel labeling from @sk. The caller is responsible for
467 * ensuring that @sk is locked.
468 *
469 */
470void netlbl_sock_delattr(struct sock *sk)
471{
472 cipso_v4_sock_delattr(sk);
473}
474
475/**
487 * netlbl_sock_getattr - Determine the security attributes of a sock 476 * netlbl_sock_getattr - Determine the security attributes of a sock
488 * @sk: the sock 477 * @sk: the sock
489 * @secattr: the security attributes 478 * @secattr: the security attributes
@@ -501,6 +490,128 @@ int netlbl_sock_getattr(struct sock *sk, struct netlbl_lsm_secattr *secattr)
501} 490}
502 491
503/** 492/**
493 * netlbl_conn_setattr - Label a connected socket using the correct protocol
494 * @sk: the socket to label
495 * @addr: the destination address
496 * @secattr: the security attributes
497 *
498 * Description:
499 * Attach the correct label to the given connected socket using the security
500 * attributes specified in @secattr. The caller is responsible for ensuring
501 * that @sk is locked. Returns zero on success, negative values on failure.
502 *
503 */
504int netlbl_conn_setattr(struct sock *sk,
505 struct sockaddr *addr,
506 const struct netlbl_lsm_secattr *secattr)
507{
508 int ret_val;
509 struct sockaddr_in *addr4;
510 struct netlbl_domaddr4_map *af4_entry;
511
512 rcu_read_lock();
513 switch (addr->sa_family) {
514 case AF_INET:
515 addr4 = (struct sockaddr_in *)addr;
516 af4_entry = netlbl_domhsh_getentry_af4(secattr->domain,
517 addr4->sin_addr.s_addr);
518 if (af4_entry == NULL) {
519 ret_val = -ENOENT;
520 goto conn_setattr_return;
521 }
522 switch (af4_entry->type) {
523 case NETLBL_NLTYPE_CIPSOV4:
524 ret_val = cipso_v4_sock_setattr(sk,
525 af4_entry->type_def.cipsov4,
526 secattr);
527 break;
528 case NETLBL_NLTYPE_UNLABELED:
529 /* just delete the protocols we support for right now
530 * but we could remove other protocols if needed */
531 cipso_v4_sock_delattr(sk);
532 ret_val = 0;
533 break;
534 default:
535 ret_val = -ENOENT;
536 }
537 break;
538#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
539 case AF_INET6:
540 /* since we don't support any IPv6 labeling protocols right
541 * now we can optimize everything away until we do */
542 ret_val = 0;
543 break;
544#endif /* IPv6 */
545 default:
546 ret_val = 0;
547 }
548
549conn_setattr_return:
550 rcu_read_unlock();
551 return ret_val;
552}
553
554/**
555 * netlbl_skbuff_setattr - Label a packet using the correct protocol
556 * @skb: the packet
557 * @family: protocol family
558 * @secattr: the security attributes
559 *
560 * Description:
561 * Attach the correct label to the given packet using the security attributes
562 * specified in @secattr. Returns zero on success, negative values on failure.
563 *
564 */
565int netlbl_skbuff_setattr(struct sk_buff *skb,
566 u16 family,
567 const struct netlbl_lsm_secattr *secattr)
568{
569 int ret_val;
570 struct iphdr *hdr4;
571 struct netlbl_domaddr4_map *af4_entry;
572
573 rcu_read_lock();
574 switch (family) {
575 case AF_INET:
576 hdr4 = ip_hdr(skb);
577 af4_entry = netlbl_domhsh_getentry_af4(secattr->domain,
578 hdr4->daddr);
579 if (af4_entry == NULL) {
580 ret_val = -ENOENT;
581 goto skbuff_setattr_return;
582 }
583 switch (af4_entry->type) {
584 case NETLBL_NLTYPE_CIPSOV4:
585 ret_val = cipso_v4_skbuff_setattr(skb,
586 af4_entry->type_def.cipsov4,
587 secattr);
588 break;
589 case NETLBL_NLTYPE_UNLABELED:
590 /* just delete the protocols we support for right now
591 * but we could remove other protocols if needed */
592 ret_val = cipso_v4_skbuff_delattr(skb);
593 break;
594 default:
595 ret_val = -ENOENT;
596 }
597 break;
598#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
599 case AF_INET6:
600 /* since we don't support any IPv6 labeling protocols right
601 * now we can optimize everything away until we do */
602 ret_val = 0;
603 break;
604#endif /* IPv6 */
605 default:
606 ret_val = 0;
607 }
608
609skbuff_setattr_return:
610 rcu_read_unlock();
611 return ret_val;
612}
613
614/**
504 * netlbl_skbuff_getattr - Determine the security attributes of a packet 615 * netlbl_skbuff_getattr - Determine the security attributes of a packet
505 * @skb: the packet 616 * @skb: the packet
506 * @family: protocol family 617 * @family: protocol family
@@ -528,6 +639,7 @@ int netlbl_skbuff_getattr(const struct sk_buff *skb,
528 * netlbl_skbuff_err - Handle a LSM error on a sk_buff 639 * netlbl_skbuff_err - Handle a LSM error on a sk_buff
529 * @skb: the packet 640 * @skb: the packet
530 * @error: the error code 641 * @error: the error code
642 * @gateway: true if host is acting as a gateway, false otherwise
531 * 643 *
532 * Description: 644 * Description:
533 * Deal with a LSM problem when handling the packet in @skb, typically this is 645 * Deal with a LSM problem when handling the packet in @skb, typically this is
@@ -535,10 +647,10 @@ int netlbl_skbuff_getattr(const struct sk_buff *skb,
535 * according to the packet's labeling protocol. 647 * according to the packet's labeling protocol.
536 * 648 *
537 */ 649 */
538void netlbl_skbuff_err(struct sk_buff *skb, int error) 650void netlbl_skbuff_err(struct sk_buff *skb, int error, int gateway)
539{ 651{
540 if (CIPSO_V4_OPTEXIST(skb)) 652 if (CIPSO_V4_OPTEXIST(skb))
541 cipso_v4_error(skb, error, 0); 653 cipso_v4_error(skb, error, gateway);
542} 654}
543 655
544/** 656/**
diff --git a/net/netlabel/netlabel_mgmt.c b/net/netlabel/netlabel_mgmt.c
index 44be5d5261f4..ee769ecaa13c 100644
--- a/net/netlabel/netlabel_mgmt.c
+++ b/net/netlabel/netlabel_mgmt.c
@@ -10,7 +10,7 @@
10 */ 10 */
11 11
12/* 12/*
13 * (c) Copyright Hewlett-Packard Development Company, L.P., 2006 13 * (c) Copyright Hewlett-Packard Development Company, L.P., 2006, 2008
14 * 14 *
15 * This program is free software; you can redistribute it and/or modify 15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by 16 * it under the terms of the GNU General Public License as published by
@@ -32,9 +32,13 @@
32#include <linux/socket.h> 32#include <linux/socket.h>
33#include <linux/string.h> 33#include <linux/string.h>
34#include <linux/skbuff.h> 34#include <linux/skbuff.h>
35#include <linux/in.h>
36#include <linux/in6.h>
35#include <net/sock.h> 37#include <net/sock.h>
36#include <net/netlink.h> 38#include <net/netlink.h>
37#include <net/genetlink.h> 39#include <net/genetlink.h>
40#include <net/ip.h>
41#include <net/ipv6.h>
38#include <net/netlabel.h> 42#include <net/netlabel.h>
39#include <net/cipso_ipv4.h> 43#include <net/cipso_ipv4.h>
40#include <asm/atomic.h> 44#include <asm/atomic.h>
@@ -71,86 +75,337 @@ static const struct nla_policy netlbl_mgmt_genl_policy[NLBL_MGMT_A_MAX + 1] = {
71}; 75};
72 76
73/* 77/*
74 * NetLabel Command Handlers 78 * Helper Functions
75 */ 79 */
76 80
77/** 81/**
78 * netlbl_mgmt_add - Handle an ADD message 82 * netlbl_mgmt_add - Handle an ADD message
79 * @skb: the NETLINK buffer
80 * @info: the Generic NETLINK info block 83 * @info: the Generic NETLINK info block
84 * @audit_info: NetLabel audit information
81 * 85 *
82 * Description: 86 * Description:
83 * Process a user generated ADD message and add the domains from the message 87 * Helper function for the ADD and ADDDEF messages to add the domain mappings
84 * to the hash table. See netlabel.h for a description of the message format. 88 * from the message to the hash table. See netlabel.h for a description of the
85 * Returns zero on success, negative values on failure. 89 * message format. Returns zero on success, negative values on failure.
86 * 90 *
87 */ 91 */
88static int netlbl_mgmt_add(struct sk_buff *skb, struct genl_info *info) 92static int netlbl_mgmt_add_common(struct genl_info *info,
93 struct netlbl_audit *audit_info)
89{ 94{
90 int ret_val = -EINVAL; 95 int ret_val = -EINVAL;
91 struct netlbl_dom_map *entry = NULL; 96 struct netlbl_dom_map *entry = NULL;
92 size_t tmp_size; 97 struct netlbl_domaddr_map *addrmap = NULL;
98 struct cipso_v4_doi *cipsov4 = NULL;
93 u32 tmp_val; 99 u32 tmp_val;
94 struct netlbl_audit audit_info;
95
96 if (!info->attrs[NLBL_MGMT_A_DOMAIN] ||
97 !info->attrs[NLBL_MGMT_A_PROTOCOL])
98 goto add_failure;
99
100 netlbl_netlink_auditinfo(skb, &audit_info);
101 100
102 entry = kzalloc(sizeof(*entry), GFP_KERNEL); 101 entry = kzalloc(sizeof(*entry), GFP_KERNEL);
103 if (entry == NULL) { 102 if (entry == NULL) {
104 ret_val = -ENOMEM; 103 ret_val = -ENOMEM;
105 goto add_failure; 104 goto add_failure;
106 } 105 }
107 tmp_size = nla_len(info->attrs[NLBL_MGMT_A_DOMAIN]);
108 entry->domain = kmalloc(tmp_size, GFP_KERNEL);
109 if (entry->domain == NULL) {
110 ret_val = -ENOMEM;
111 goto add_failure;
112 }
113 entry->type = nla_get_u32(info->attrs[NLBL_MGMT_A_PROTOCOL]); 106 entry->type = nla_get_u32(info->attrs[NLBL_MGMT_A_PROTOCOL]);
114 nla_strlcpy(entry->domain, info->attrs[NLBL_MGMT_A_DOMAIN], tmp_size); 107 if (info->attrs[NLBL_MGMT_A_DOMAIN]) {
108 size_t tmp_size = nla_len(info->attrs[NLBL_MGMT_A_DOMAIN]);
109 entry->domain = kmalloc(tmp_size, GFP_KERNEL);
110 if (entry->domain == NULL) {
111 ret_val = -ENOMEM;
112 goto add_failure;
113 }
114 nla_strlcpy(entry->domain,
115 info->attrs[NLBL_MGMT_A_DOMAIN], tmp_size);
116 }
117
118 /* NOTE: internally we allow/use a entry->type value of
119 * NETLBL_NLTYPE_ADDRSELECT but we don't currently allow users
120 * to pass that as a protocol value because we need to know the
121 * "real" protocol */
115 122
116 switch (entry->type) { 123 switch (entry->type) {
117 case NETLBL_NLTYPE_UNLABELED: 124 case NETLBL_NLTYPE_UNLABELED:
118 ret_val = netlbl_domhsh_add(entry, &audit_info);
119 break; 125 break;
120 case NETLBL_NLTYPE_CIPSOV4: 126 case NETLBL_NLTYPE_CIPSOV4:
121 if (!info->attrs[NLBL_MGMT_A_CV4DOI]) 127 if (!info->attrs[NLBL_MGMT_A_CV4DOI])
122 goto add_failure; 128 goto add_failure;
123 129
124 tmp_val = nla_get_u32(info->attrs[NLBL_MGMT_A_CV4DOI]); 130 tmp_val = nla_get_u32(info->attrs[NLBL_MGMT_A_CV4DOI]);
125 /* We should be holding a rcu_read_lock() here while we hold 131 cipsov4 = cipso_v4_doi_getdef(tmp_val);
126 * the result but since the entry will always be deleted when 132 if (cipsov4 == NULL)
127 * the CIPSO DOI is deleted we aren't going to keep the
128 * lock. */
129 rcu_read_lock();
130 entry->type_def.cipsov4 = cipso_v4_doi_getdef(tmp_val);
131 if (entry->type_def.cipsov4 == NULL) {
132 rcu_read_unlock();
133 goto add_failure; 133 goto add_failure;
134 } 134 entry->type_def.cipsov4 = cipsov4;
135 ret_val = netlbl_domhsh_add(entry, &audit_info);
136 rcu_read_unlock();
137 break; 135 break;
138 default: 136 default:
139 goto add_failure; 137 goto add_failure;
140 } 138 }
139
140 if (info->attrs[NLBL_MGMT_A_IPV4ADDR]) {
141 struct in_addr *addr;
142 struct in_addr *mask;
143 struct netlbl_domaddr4_map *map;
144
145 addrmap = kzalloc(sizeof(*addrmap), GFP_KERNEL);
146 if (addrmap == NULL) {
147 ret_val = -ENOMEM;
148 goto add_failure;
149 }
150 INIT_LIST_HEAD(&addrmap->list4);
151 INIT_LIST_HEAD(&addrmap->list6);
152
153 if (nla_len(info->attrs[NLBL_MGMT_A_IPV4ADDR]) !=
154 sizeof(struct in_addr)) {
155 ret_val = -EINVAL;
156 goto add_failure;
157 }
158 if (nla_len(info->attrs[NLBL_MGMT_A_IPV4MASK]) !=
159 sizeof(struct in_addr)) {
160 ret_val = -EINVAL;
161 goto add_failure;
162 }
163 addr = nla_data(info->attrs[NLBL_MGMT_A_IPV4ADDR]);
164 mask = nla_data(info->attrs[NLBL_MGMT_A_IPV4MASK]);
165
166 map = kzalloc(sizeof(*map), GFP_KERNEL);
167 if (map == NULL) {
168 ret_val = -ENOMEM;
169 goto add_failure;
170 }
171 map->list.addr = addr->s_addr & mask->s_addr;
172 map->list.mask = mask->s_addr;
173 map->list.valid = 1;
174 map->type = entry->type;
175 if (cipsov4)
176 map->type_def.cipsov4 = cipsov4;
177
178 ret_val = netlbl_af4list_add(&map->list, &addrmap->list4);
179 if (ret_val != 0) {
180 kfree(map);
181 goto add_failure;
182 }
183
184 entry->type = NETLBL_NLTYPE_ADDRSELECT;
185 entry->type_def.addrsel = addrmap;
186#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
187 } else if (info->attrs[NLBL_MGMT_A_IPV6ADDR]) {
188 struct in6_addr *addr;
189 struct in6_addr *mask;
190 struct netlbl_domaddr6_map *map;
191
192 addrmap = kzalloc(sizeof(*addrmap), GFP_KERNEL);
193 if (addrmap == NULL) {
194 ret_val = -ENOMEM;
195 goto add_failure;
196 }
197 INIT_LIST_HEAD(&addrmap->list4);
198 INIT_LIST_HEAD(&addrmap->list6);
199
200 if (nla_len(info->attrs[NLBL_MGMT_A_IPV6ADDR]) !=
201 sizeof(struct in6_addr)) {
202 ret_val = -EINVAL;
203 goto add_failure;
204 }
205 if (nla_len(info->attrs[NLBL_MGMT_A_IPV6MASK]) !=
206 sizeof(struct in6_addr)) {
207 ret_val = -EINVAL;
208 goto add_failure;
209 }
210 addr = nla_data(info->attrs[NLBL_MGMT_A_IPV6ADDR]);
211 mask = nla_data(info->attrs[NLBL_MGMT_A_IPV6MASK]);
212
213 map = kzalloc(sizeof(*map), GFP_KERNEL);
214 if (map == NULL) {
215 ret_val = -ENOMEM;
216 goto add_failure;
217 }
218 ipv6_addr_copy(&map->list.addr, addr);
219 map->list.addr.s6_addr32[0] &= mask->s6_addr32[0];
220 map->list.addr.s6_addr32[1] &= mask->s6_addr32[1];
221 map->list.addr.s6_addr32[2] &= mask->s6_addr32[2];
222 map->list.addr.s6_addr32[3] &= mask->s6_addr32[3];
223 ipv6_addr_copy(&map->list.mask, mask);
224 map->list.valid = 1;
225 map->type = entry->type;
226
227 ret_val = netlbl_af6list_add(&map->list, &addrmap->list6);
228 if (ret_val != 0) {
229 kfree(map);
230 goto add_failure;
231 }
232
233 entry->type = NETLBL_NLTYPE_ADDRSELECT;
234 entry->type_def.addrsel = addrmap;
235#endif /* IPv6 */
236 }
237
238 ret_val = netlbl_domhsh_add(entry, audit_info);
141 if (ret_val != 0) 239 if (ret_val != 0)
142 goto add_failure; 240 goto add_failure;
143 241
144 return 0; 242 return 0;
145 243
146add_failure: 244add_failure:
245 if (cipsov4)
246 cipso_v4_doi_putdef(cipsov4);
147 if (entry) 247 if (entry)
148 kfree(entry->domain); 248 kfree(entry->domain);
249 kfree(addrmap);
149 kfree(entry); 250 kfree(entry);
150 return ret_val; 251 return ret_val;
151} 252}
152 253
153/** 254/**
255 * netlbl_mgmt_listentry - List a NetLabel/LSM domain map entry
256 * @skb: the NETLINK buffer
257 * @entry: the map entry
258 *
259 * Description:
260 * This function is a helper function used by the LISTALL and LISTDEF command
261 * handlers. The caller is responsibile for ensuring that the RCU read lock
262 * is held. Returns zero on success, negative values on failure.
263 *
264 */
265static int netlbl_mgmt_listentry(struct sk_buff *skb,
266 struct netlbl_dom_map *entry)
267{
268 int ret_val;
269 struct nlattr *nla_a;
270 struct nlattr *nla_b;
271 struct netlbl_af4list *iter4;
272#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
273 struct netlbl_af6list *iter6;
274#endif
275
276 if (entry->domain != NULL) {
277 ret_val = nla_put_string(skb,
278 NLBL_MGMT_A_DOMAIN, entry->domain);
279 if (ret_val != 0)
280 return ret_val;
281 }
282
283 switch (entry->type) {
284 case NETLBL_NLTYPE_ADDRSELECT:
285 nla_a = nla_nest_start(skb, NLBL_MGMT_A_SELECTORLIST);
286 if (nla_a == NULL)
287 return -ENOMEM;
288
289 netlbl_af4list_foreach_rcu(iter4,
290 &entry->type_def.addrsel->list4) {
291 struct netlbl_domaddr4_map *map4;
292 struct in_addr addr_struct;
293
294 nla_b = nla_nest_start(skb, NLBL_MGMT_A_ADDRSELECTOR);
295 if (nla_b == NULL)
296 return -ENOMEM;
297
298 addr_struct.s_addr = iter4->addr;
299 ret_val = nla_put(skb, NLBL_MGMT_A_IPV4ADDR,
300 sizeof(struct in_addr),
301 &addr_struct);
302 if (ret_val != 0)
303 return ret_val;
304 addr_struct.s_addr = iter4->mask;
305 ret_val = nla_put(skb, NLBL_MGMT_A_IPV4MASK,
306 sizeof(struct in_addr),
307 &addr_struct);
308 if (ret_val != 0)
309 return ret_val;
310 map4 = netlbl_domhsh_addr4_entry(iter4);
311 ret_val = nla_put_u32(skb, NLBL_MGMT_A_PROTOCOL,
312 map4->type);
313 if (ret_val != 0)
314 return ret_val;
315 switch (map4->type) {
316 case NETLBL_NLTYPE_CIPSOV4:
317 ret_val = nla_put_u32(skb, NLBL_MGMT_A_CV4DOI,
318 map4->type_def.cipsov4->doi);
319 if (ret_val != 0)
320 return ret_val;
321 break;
322 }
323
324 nla_nest_end(skb, nla_b);
325 }
326#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
327 netlbl_af6list_foreach_rcu(iter6,
328 &entry->type_def.addrsel->list6) {
329 struct netlbl_domaddr6_map *map6;
330
331 nla_b = nla_nest_start(skb, NLBL_MGMT_A_ADDRSELECTOR);
332 if (nla_b == NULL)
333 return -ENOMEM;
334
335 ret_val = nla_put(skb, NLBL_MGMT_A_IPV6ADDR,
336 sizeof(struct in6_addr),
337 &iter6->addr);
338 if (ret_val != 0)
339 return ret_val;
340 ret_val = nla_put(skb, NLBL_MGMT_A_IPV6MASK,
341 sizeof(struct in6_addr),
342 &iter6->mask);
343 if (ret_val != 0)
344 return ret_val;
345 map6 = netlbl_domhsh_addr6_entry(iter6);
346 ret_val = nla_put_u32(skb, NLBL_MGMT_A_PROTOCOL,
347 map6->type);
348 if (ret_val != 0)
349 return ret_val;
350
351 nla_nest_end(skb, nla_b);
352 }
353#endif /* IPv6 */
354
355 nla_nest_end(skb, nla_a);
356 break;
357 case NETLBL_NLTYPE_UNLABELED:
358 ret_val = nla_put_u32(skb, NLBL_MGMT_A_PROTOCOL, entry->type);
359 break;
360 case NETLBL_NLTYPE_CIPSOV4:
361 ret_val = nla_put_u32(skb, NLBL_MGMT_A_PROTOCOL, entry->type);
362 if (ret_val != 0)
363 return ret_val;
364 ret_val = nla_put_u32(skb, NLBL_MGMT_A_CV4DOI,
365 entry->type_def.cipsov4->doi);
366 break;
367 }
368
369 return ret_val;
370}
371
372/*
373 * NetLabel Command Handlers
374 */
375
376/**
377 * netlbl_mgmt_add - Handle an ADD message
378 * @skb: the NETLINK buffer
379 * @info: the Generic NETLINK info block
380 *
381 * Description:
382 * Process a user generated ADD message and add the domains from the message
383 * to the hash table. See netlabel.h for a description of the message format.
384 * Returns zero on success, negative values on failure.
385 *
386 */
387static int netlbl_mgmt_add(struct sk_buff *skb, struct genl_info *info)
388{
389 struct netlbl_audit audit_info;
390
391 if ((!info->attrs[NLBL_MGMT_A_DOMAIN]) ||
392 (!info->attrs[NLBL_MGMT_A_PROTOCOL]) ||
393 (info->attrs[NLBL_MGMT_A_IPV4ADDR] &&
394 info->attrs[NLBL_MGMT_A_IPV6ADDR]) ||
395 (info->attrs[NLBL_MGMT_A_IPV4MASK] &&
396 info->attrs[NLBL_MGMT_A_IPV6MASK]) ||
397 ((info->attrs[NLBL_MGMT_A_IPV4ADDR] != NULL) ^
398 (info->attrs[NLBL_MGMT_A_IPV4MASK] != NULL)) ||
399 ((info->attrs[NLBL_MGMT_A_IPV6ADDR] != NULL) ^
400 (info->attrs[NLBL_MGMT_A_IPV6MASK] != NULL)))
401 return -EINVAL;
402
403 netlbl_netlink_auditinfo(skb, &audit_info);
404
405 return netlbl_mgmt_add_common(info, &audit_info);
406}
407
408/**
154 * netlbl_mgmt_remove - Handle a REMOVE message 409 * netlbl_mgmt_remove - Handle a REMOVE message
155 * @skb: the NETLINK buffer 410 * @skb: the NETLINK buffer
156 * @info: the Generic NETLINK info block 411 * @info: the Generic NETLINK info block
@@ -198,23 +453,9 @@ static int netlbl_mgmt_listall_cb(struct netlbl_dom_map *entry, void *arg)
198 if (data == NULL) 453 if (data == NULL)
199 goto listall_cb_failure; 454 goto listall_cb_failure;
200 455
201 ret_val = nla_put_string(cb_arg->skb, 456 ret_val = netlbl_mgmt_listentry(cb_arg->skb, entry);
202 NLBL_MGMT_A_DOMAIN,
203 entry->domain);
204 if (ret_val != 0) 457 if (ret_val != 0)
205 goto listall_cb_failure; 458 goto listall_cb_failure;
206 ret_val = nla_put_u32(cb_arg->skb, NLBL_MGMT_A_PROTOCOL, entry->type);
207 if (ret_val != 0)
208 goto listall_cb_failure;
209 switch (entry->type) {
210 case NETLBL_NLTYPE_CIPSOV4:
211 ret_val = nla_put_u32(cb_arg->skb,
212 NLBL_MGMT_A_CV4DOI,
213 entry->type_def.cipsov4->doi);
214 if (ret_val != 0)
215 goto listall_cb_failure;
216 break;
217 }
218 459
219 cb_arg->seq++; 460 cb_arg->seq++;
220 return genlmsg_end(cb_arg->skb, data); 461 return genlmsg_end(cb_arg->skb, data);
@@ -268,56 +509,22 @@ static int netlbl_mgmt_listall(struct sk_buff *skb,
268 */ 509 */
269static int netlbl_mgmt_adddef(struct sk_buff *skb, struct genl_info *info) 510static int netlbl_mgmt_adddef(struct sk_buff *skb, struct genl_info *info)
270{ 511{
271 int ret_val = -EINVAL;
272 struct netlbl_dom_map *entry = NULL;
273 u32 tmp_val;
274 struct netlbl_audit audit_info; 512 struct netlbl_audit audit_info;
275 513
276 if (!info->attrs[NLBL_MGMT_A_PROTOCOL]) 514 if ((!info->attrs[NLBL_MGMT_A_PROTOCOL]) ||
277 goto adddef_failure; 515 (info->attrs[NLBL_MGMT_A_IPV4ADDR] &&
516 info->attrs[NLBL_MGMT_A_IPV6ADDR]) ||
517 (info->attrs[NLBL_MGMT_A_IPV4MASK] &&
518 info->attrs[NLBL_MGMT_A_IPV6MASK]) ||
519 ((info->attrs[NLBL_MGMT_A_IPV4ADDR] != NULL) ^
520 (info->attrs[NLBL_MGMT_A_IPV4MASK] != NULL)) ||
521 ((info->attrs[NLBL_MGMT_A_IPV6ADDR] != NULL) ^
522 (info->attrs[NLBL_MGMT_A_IPV6MASK] != NULL)))
523 return -EINVAL;
278 524
279 netlbl_netlink_auditinfo(skb, &audit_info); 525 netlbl_netlink_auditinfo(skb, &audit_info);
280 526
281 entry = kzalloc(sizeof(*entry), GFP_KERNEL); 527 return netlbl_mgmt_add_common(info, &audit_info);
282 if (entry == NULL) {
283 ret_val = -ENOMEM;
284 goto adddef_failure;
285 }
286 entry->type = nla_get_u32(info->attrs[NLBL_MGMT_A_PROTOCOL]);
287
288 switch (entry->type) {
289 case NETLBL_NLTYPE_UNLABELED:
290 ret_val = netlbl_domhsh_add_default(entry, &audit_info);
291 break;
292 case NETLBL_NLTYPE_CIPSOV4:
293 if (!info->attrs[NLBL_MGMT_A_CV4DOI])
294 goto adddef_failure;
295
296 tmp_val = nla_get_u32(info->attrs[NLBL_MGMT_A_CV4DOI]);
297 /* We should be holding a rcu_read_lock() here while we hold
298 * the result but since the entry will always be deleted when
299 * the CIPSO DOI is deleted we aren't going to keep the
300 * lock. */
301 rcu_read_lock();
302 entry->type_def.cipsov4 = cipso_v4_doi_getdef(tmp_val);
303 if (entry->type_def.cipsov4 == NULL) {
304 rcu_read_unlock();
305 goto adddef_failure;
306 }
307 ret_val = netlbl_domhsh_add_default(entry, &audit_info);
308 rcu_read_unlock();
309 break;
310 default:
311 goto adddef_failure;
312 }
313 if (ret_val != 0)
314 goto adddef_failure;
315
316 return 0;
317
318adddef_failure:
319 kfree(entry);
320 return ret_val;
321} 528}
322 529
323/** 530/**
@@ -371,19 +578,10 @@ static int netlbl_mgmt_listdef(struct sk_buff *skb, struct genl_info *info)
371 ret_val = -ENOENT; 578 ret_val = -ENOENT;
372 goto listdef_failure_lock; 579 goto listdef_failure_lock;
373 } 580 }
374 ret_val = nla_put_u32(ans_skb, NLBL_MGMT_A_PROTOCOL, entry->type); 581 ret_val = netlbl_mgmt_listentry(ans_skb, entry);
375 if (ret_val != 0)
376 goto listdef_failure_lock;
377 switch (entry->type) {
378 case NETLBL_NLTYPE_CIPSOV4:
379 ret_val = nla_put_u32(ans_skb,
380 NLBL_MGMT_A_CV4DOI,
381 entry->type_def.cipsov4->doi);
382 if (ret_val != 0)
383 goto listdef_failure_lock;
384 break;
385 }
386 rcu_read_unlock(); 582 rcu_read_unlock();
583 if (ret_val != 0)
584 goto listdef_failure;
387 585
388 genlmsg_end(ans_skb, data); 586 genlmsg_end(ans_skb, data);
389 return genlmsg_reply(ans_skb, info); 587 return genlmsg_reply(ans_skb, info);
diff --git a/net/netlabel/netlabel_mgmt.h b/net/netlabel/netlabel_mgmt.h
index a43bff169d6b..05d96431f819 100644
--- a/net/netlabel/netlabel_mgmt.h
+++ b/net/netlabel/netlabel_mgmt.h
@@ -45,6 +45,16 @@
45 * NLBL_MGMT_A_DOMAIN 45 * NLBL_MGMT_A_DOMAIN
46 * NLBL_MGMT_A_PROTOCOL 46 * NLBL_MGMT_A_PROTOCOL
47 * 47 *
48 * If IPv4 is specified the following attributes are required:
49 *
50 * NLBL_MGMT_A_IPV4ADDR
51 * NLBL_MGMT_A_IPV4MASK
52 *
53 * If IPv6 is specified the following attributes are required:
54 *
55 * NLBL_MGMT_A_IPV6ADDR
56 * NLBL_MGMT_A_IPV6MASK
57 *
48 * If using NETLBL_NLTYPE_CIPSOV4 the following attributes are required: 58 * If using NETLBL_NLTYPE_CIPSOV4 the following attributes are required:
49 * 59 *
50 * NLBL_MGMT_A_CV4DOI 60 * NLBL_MGMT_A_CV4DOI
@@ -68,13 +78,24 @@
68 * Required attributes: 78 * Required attributes:
69 * 79 *
70 * NLBL_MGMT_A_DOMAIN 80 * NLBL_MGMT_A_DOMAIN
81 *
82 * If the IP address selectors are not used the following attribute is
83 * required:
84 *
71 * NLBL_MGMT_A_PROTOCOL 85 * NLBL_MGMT_A_PROTOCOL
72 * 86 *
73 * If using NETLBL_NLTYPE_CIPSOV4 the following attributes are required: 87 * If the IP address selectors are used then the following attritbute is
88 * required:
89 *
90 * NLBL_MGMT_A_SELECTORLIST
91 *
92 * If the mapping is using the NETLBL_NLTYPE_CIPSOV4 type then the following
93 * attributes are required:
74 * 94 *
75 * NLBL_MGMT_A_CV4DOI 95 * NLBL_MGMT_A_CV4DOI
76 * 96 *
77 * If using NETLBL_NLTYPE_UNLABELED no other attributes are required. 97 * If the mapping is using the NETLBL_NLTYPE_UNLABELED type no other
98 * attributes are required.
78 * 99 *
79 * o ADDDEF: 100 * o ADDDEF:
80 * Sent by an application to set the default domain mapping for the NetLabel 101 * Sent by an application to set the default domain mapping for the NetLabel
@@ -100,15 +121,23 @@
100 * application there is no payload. On success the kernel should send a 121 * application there is no payload. On success the kernel should send a
101 * response using the following format. 122 * response using the following format.
102 * 123 *
103 * Required attributes: 124 * If the IP address selectors are not used the following attribute is
125 * required:
104 * 126 *
105 * NLBL_MGMT_A_PROTOCOL 127 * NLBL_MGMT_A_PROTOCOL
106 * 128 *
107 * If using NETLBL_NLTYPE_CIPSOV4 the following attributes are required: 129 * If the IP address selectors are used then the following attritbute is
130 * required:
131 *
132 * NLBL_MGMT_A_SELECTORLIST
133 *
134 * If the mapping is using the NETLBL_NLTYPE_CIPSOV4 type then the following
135 * attributes are required:
108 * 136 *
109 * NLBL_MGMT_A_CV4DOI 137 * NLBL_MGMT_A_CV4DOI
110 * 138 *
111 * If using NETLBL_NLTYPE_UNLABELED no other attributes are required. 139 * If the mapping is using the NETLBL_NLTYPE_UNLABELED type no other
140 * attributes are required.
112 * 141 *
113 * o PROTOCOLS: 142 * o PROTOCOLS:
114 * Sent by an application to request a list of configured NetLabel protocols 143 * Sent by an application to request a list of configured NetLabel protocols
@@ -162,6 +191,26 @@ enum {
162 NLBL_MGMT_A_CV4DOI, 191 NLBL_MGMT_A_CV4DOI,
163 /* (NLA_U32) 192 /* (NLA_U32)
164 * the CIPSOv4 DOI value */ 193 * the CIPSOv4 DOI value */
194 NLBL_MGMT_A_IPV6ADDR,
195 /* (NLA_BINARY, struct in6_addr)
196 * an IPv6 address */
197 NLBL_MGMT_A_IPV6MASK,
198 /* (NLA_BINARY, struct in6_addr)
199 * an IPv6 address mask */
200 NLBL_MGMT_A_IPV4ADDR,
201 /* (NLA_BINARY, struct in_addr)
202 * an IPv4 address */
203 NLBL_MGMT_A_IPV4MASK,
204 /* (NLA_BINARY, struct in_addr)
205 * and IPv4 address mask */
206 NLBL_MGMT_A_ADDRSELECTOR,
207 /* (NLA_NESTED)
208 * an IP address selector, must contain an address, mask, and protocol
209 * attribute plus any protocol specific attributes */
210 NLBL_MGMT_A_SELECTORLIST,
211 /* (NLA_NESTED)
212 * the selector list, there must be at least one
213 * NLBL_MGMT_A_ADDRSELECTOR attribute */
165 __NLBL_MGMT_A_MAX, 214 __NLBL_MGMT_A_MAX,
166}; 215};
167#define NLBL_MGMT_A_MAX (__NLBL_MGMT_A_MAX - 1) 216#define NLBL_MGMT_A_MAX (__NLBL_MGMT_A_MAX - 1)
diff --git a/net/netlabel/netlabel_unlabeled.c b/net/netlabel/netlabel_unlabeled.c
index 921c118ead89..e8a5c32b0f10 100644
--- a/net/netlabel/netlabel_unlabeled.c
+++ b/net/netlabel/netlabel_unlabeled.c
@@ -10,7 +10,7 @@
10 */ 10 */
11 11
12/* 12/*
13 * (c) Copyright Hewlett-Packard Development Company, L.P., 2006 - 2007 13 * (c) Copyright Hewlett-Packard Development Company, L.P., 2006 - 2008
14 * 14 *
15 * This program is free software; you can redistribute it and/or modify 15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by 16 * it under the terms of the GNU General Public License as published by
@@ -54,6 +54,7 @@
54#include <asm/atomic.h> 54#include <asm/atomic.h>
55 55
56#include "netlabel_user.h" 56#include "netlabel_user.h"
57#include "netlabel_addrlist.h"
57#include "netlabel_domainhash.h" 58#include "netlabel_domainhash.h"
58#include "netlabel_unlabeled.h" 59#include "netlabel_unlabeled.h"
59#include "netlabel_mgmt.h" 60#include "netlabel_mgmt.h"
@@ -76,22 +77,20 @@ struct netlbl_unlhsh_tbl {
76 struct list_head *tbl; 77 struct list_head *tbl;
77 u32 size; 78 u32 size;
78}; 79};
80#define netlbl_unlhsh_addr4_entry(iter) \
81 container_of(iter, struct netlbl_unlhsh_addr4, list)
79struct netlbl_unlhsh_addr4 { 82struct netlbl_unlhsh_addr4 {
80 __be32 addr;
81 __be32 mask;
82 u32 secid; 83 u32 secid;
83 84
84 u32 valid; 85 struct netlbl_af4list list;
85 struct list_head list;
86 struct rcu_head rcu; 86 struct rcu_head rcu;
87}; 87};
88#define netlbl_unlhsh_addr6_entry(iter) \
89 container_of(iter, struct netlbl_unlhsh_addr6, list)
88struct netlbl_unlhsh_addr6 { 90struct netlbl_unlhsh_addr6 {
89 struct in6_addr addr;
90 struct in6_addr mask;
91 u32 secid; 91 u32 secid;
92 92
93 u32 valid; 93 struct netlbl_af6list list;
94 struct list_head list;
95 struct rcu_head rcu; 94 struct rcu_head rcu;
96}; 95};
97struct netlbl_unlhsh_iface { 96struct netlbl_unlhsh_iface {
@@ -147,76 +146,6 @@ static const struct nla_policy netlbl_unlabel_genl_policy[NLBL_UNLABEL_A_MAX + 1
147}; 146};
148 147
149/* 148/*
150 * Audit Helper Functions
151 */
152
153/**
154 * netlbl_unlabel_audit_addr4 - Audit an IPv4 address
155 * @audit_buf: audit buffer
156 * @dev: network interface
157 * @addr: IP address
158 * @mask: IP address mask
159 *
160 * Description:
161 * Write the IPv4 address and address mask, if necessary, to @audit_buf.
162 *
163 */
164static void netlbl_unlabel_audit_addr4(struct audit_buffer *audit_buf,
165 const char *dev,
166 __be32 addr, __be32 mask)
167{
168 u32 mask_val = ntohl(mask);
169
170 if (dev != NULL)
171 audit_log_format(audit_buf, " netif=%s", dev);
172 audit_log_format(audit_buf, " src=" NIPQUAD_FMT, NIPQUAD(addr));
173 if (mask_val != 0xffffffff) {
174 u32 mask_len = 0;
175 while (mask_val > 0) {
176 mask_val <<= 1;
177 mask_len++;
178 }
179 audit_log_format(audit_buf, " src_prefixlen=%d", mask_len);
180 }
181}
182
183#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
184/**
185 * netlbl_unlabel_audit_addr6 - Audit an IPv6 address
186 * @audit_buf: audit buffer
187 * @dev: network interface
188 * @addr: IP address
189 * @mask: IP address mask
190 *
191 * Description:
192 * Write the IPv6 address and address mask, if necessary, to @audit_buf.
193 *
194 */
195static void netlbl_unlabel_audit_addr6(struct audit_buffer *audit_buf,
196 const char *dev,
197 const struct in6_addr *addr,
198 const struct in6_addr *mask)
199{
200 if (dev != NULL)
201 audit_log_format(audit_buf, " netif=%s", dev);
202 audit_log_format(audit_buf, " src=" NIP6_FMT, NIP6(*addr));
203 if (ntohl(mask->s6_addr32[3]) != 0xffffffff) {
204 u32 mask_len = 0;
205 u32 mask_val;
206 int iter = -1;
207 while (ntohl(mask->s6_addr32[++iter]) == 0xffffffff)
208 mask_len += 32;
209 mask_val = ntohl(mask->s6_addr32[iter]);
210 while (mask_val > 0) {
211 mask_val <<= 1;
212 mask_len++;
213 }
214 audit_log_format(audit_buf, " src_prefixlen=%d", mask_len);
215 }
216}
217#endif /* IPv6 */
218
219/*
220 * Unlabeled Connection Hash Table Functions 149 * Unlabeled Connection Hash Table Functions
221 */ 150 */
222 151
@@ -274,26 +203,28 @@ static void netlbl_unlhsh_free_addr6(struct rcu_head *entry)
274static void netlbl_unlhsh_free_iface(struct rcu_head *entry) 203static void netlbl_unlhsh_free_iface(struct rcu_head *entry)
275{ 204{
276 struct netlbl_unlhsh_iface *iface; 205 struct netlbl_unlhsh_iface *iface;
277 struct netlbl_unlhsh_addr4 *iter4; 206 struct netlbl_af4list *iter4;
278 struct netlbl_unlhsh_addr4 *tmp4; 207 struct netlbl_af4list *tmp4;
279 struct netlbl_unlhsh_addr6 *iter6; 208#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
280 struct netlbl_unlhsh_addr6 *tmp6; 209 struct netlbl_af6list *iter6;
210 struct netlbl_af6list *tmp6;
211#endif /* IPv6 */
281 212
282 iface = container_of(entry, struct netlbl_unlhsh_iface, rcu); 213 iface = container_of(entry, struct netlbl_unlhsh_iface, rcu);
283 214
284 /* no need for locks here since we are the only one with access to this 215 /* no need for locks here since we are the only one with access to this
285 * structure */ 216 * structure */
286 217
287 list_for_each_entry_safe(iter4, tmp4, &iface->addr4_list, list) 218 netlbl_af4list_foreach_safe(iter4, tmp4, &iface->addr4_list) {
288 if (iter4->valid) { 219 netlbl_af4list_remove_entry(iter4);
289 list_del_rcu(&iter4->list); 220 kfree(netlbl_unlhsh_addr4_entry(iter4));
290 kfree(iter4); 221 }
291 } 222#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
292 list_for_each_entry_safe(iter6, tmp6, &iface->addr6_list, list) 223 netlbl_af6list_foreach_safe(iter6, tmp6, &iface->addr6_list) {
293 if (iter6->valid) { 224 netlbl_af6list_remove_entry(iter6);
294 list_del_rcu(&iter6->list); 225 kfree(netlbl_unlhsh_addr6_entry(iter6));
295 kfree(iter6); 226 }
296 } 227#endif /* IPv6 */
297 kfree(iface); 228 kfree(iface);
298} 229}
299 230
@@ -316,59 +247,6 @@ static u32 netlbl_unlhsh_hash(int ifindex)
316} 247}
317 248
318/** 249/**
319 * netlbl_unlhsh_search_addr4 - Search for a matching IPv4 address entry
320 * @addr: IPv4 address
321 * @iface: the network interface entry
322 *
323 * Description:
324 * Searches the IPv4 address list of the network interface specified by @iface.
325 * If a matching address entry is found it is returned, otherwise NULL is
326 * returned. The caller is responsible for calling the rcu_read_[un]lock()
327 * functions.
328 *
329 */
330static struct netlbl_unlhsh_addr4 *netlbl_unlhsh_search_addr4(
331 __be32 addr,
332 const struct netlbl_unlhsh_iface *iface)
333{
334 struct netlbl_unlhsh_addr4 *iter;
335
336 list_for_each_entry_rcu(iter, &iface->addr4_list, list)
337 if (iter->valid && (addr & iter->mask) == iter->addr)
338 return iter;
339
340 return NULL;
341}
342
343#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
344/**
345 * netlbl_unlhsh_search_addr6 - Search for a matching IPv6 address entry
346 * @addr: IPv6 address
347 * @iface: the network interface entry
348 *
349 * Description:
350 * Searches the IPv6 address list of the network interface specified by @iface.
351 * If a matching address entry is found it is returned, otherwise NULL is
352 * returned. The caller is responsible for calling the rcu_read_[un]lock()
353 * functions.
354 *
355 */
356static struct netlbl_unlhsh_addr6 *netlbl_unlhsh_search_addr6(
357 const struct in6_addr *addr,
358 const struct netlbl_unlhsh_iface *iface)
359{
360 struct netlbl_unlhsh_addr6 *iter;
361
362 list_for_each_entry_rcu(iter, &iface->addr6_list, list)
363 if (iter->valid &&
364 ipv6_masked_addr_cmp(&iter->addr, &iter->mask, addr) == 0)
365 return iter;
366
367 return NULL;
368}
369#endif /* IPv6 */
370
371/**
372 * netlbl_unlhsh_search_iface - Search for a matching interface entry 250 * netlbl_unlhsh_search_iface - Search for a matching interface entry
373 * @ifindex: the network interface 251 * @ifindex: the network interface
374 * 252 *
@@ -381,12 +259,12 @@ static struct netlbl_unlhsh_addr6 *netlbl_unlhsh_search_addr6(
381static struct netlbl_unlhsh_iface *netlbl_unlhsh_search_iface(int ifindex) 259static struct netlbl_unlhsh_iface *netlbl_unlhsh_search_iface(int ifindex)
382{ 260{
383 u32 bkt; 261 u32 bkt;
262 struct list_head *bkt_list;
384 struct netlbl_unlhsh_iface *iter; 263 struct netlbl_unlhsh_iface *iter;
385 264
386 bkt = netlbl_unlhsh_hash(ifindex); 265 bkt = netlbl_unlhsh_hash(ifindex);
387 list_for_each_entry_rcu(iter, 266 bkt_list = &rcu_dereference(netlbl_unlhsh)->tbl[bkt];
388 &rcu_dereference(netlbl_unlhsh)->tbl[bkt], 267 list_for_each_entry_rcu(iter, bkt_list, list)
389 list)
390 if (iter->valid && iter->ifindex == ifindex) 268 if (iter->valid && iter->ifindex == ifindex)
391 return iter; 269 return iter;
392 270
@@ -439,43 +317,26 @@ static int netlbl_unlhsh_add_addr4(struct netlbl_unlhsh_iface *iface,
439 const struct in_addr *mask, 317 const struct in_addr *mask,
440 u32 secid) 318 u32 secid)
441{ 319{
320 int ret_val;
442 struct netlbl_unlhsh_addr4 *entry; 321 struct netlbl_unlhsh_addr4 *entry;
443 struct netlbl_unlhsh_addr4 *iter;
444 322
445 entry = kzalloc(sizeof(*entry), GFP_ATOMIC); 323 entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
446 if (entry == NULL) 324 if (entry == NULL)
447 return -ENOMEM; 325 return -ENOMEM;
448 326
449 entry->addr = addr->s_addr & mask->s_addr; 327 entry->list.addr = addr->s_addr & mask->s_addr;
450 entry->mask = mask->s_addr; 328 entry->list.mask = mask->s_addr;
451 entry->secid = secid; 329 entry->list.valid = 1;
452 entry->valid = 1;
453 INIT_RCU_HEAD(&entry->rcu); 330 INIT_RCU_HEAD(&entry->rcu);
331 entry->secid = secid;
454 332
455 spin_lock(&netlbl_unlhsh_lock); 333 spin_lock(&netlbl_unlhsh_lock);
456 iter = netlbl_unlhsh_search_addr4(entry->addr, iface); 334 ret_val = netlbl_af4list_add(&entry->list, &iface->addr4_list);
457 if (iter != NULL &&
458 iter->addr == addr->s_addr && iter->mask == mask->s_addr) {
459 spin_unlock(&netlbl_unlhsh_lock);
460 kfree(entry);
461 return -EEXIST;
462 }
463 /* in order to speed up address searches through the list (the common
464 * case) we need to keep the list in order based on the size of the
465 * address mask such that the entry with the widest mask (smallest
466 * numerical value) appears first in the list */
467 list_for_each_entry_rcu(iter, &iface->addr4_list, list)
468 if (iter->valid &&
469 ntohl(entry->mask) > ntohl(iter->mask)) {
470 __list_add_rcu(&entry->list,
471 iter->list.prev,
472 &iter->list);
473 spin_unlock(&netlbl_unlhsh_lock);
474 return 0;
475 }
476 list_add_tail_rcu(&entry->list, &iface->addr4_list);
477 spin_unlock(&netlbl_unlhsh_lock); 335 spin_unlock(&netlbl_unlhsh_lock);
478 return 0; 336
337 if (ret_val != 0)
338 kfree(entry);
339 return ret_val;
479} 340}
480 341
481#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 342#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
@@ -498,47 +359,29 @@ static int netlbl_unlhsh_add_addr6(struct netlbl_unlhsh_iface *iface,
498 const struct in6_addr *mask, 359 const struct in6_addr *mask,
499 u32 secid) 360 u32 secid)
500{ 361{
362 int ret_val;
501 struct netlbl_unlhsh_addr6 *entry; 363 struct netlbl_unlhsh_addr6 *entry;
502 struct netlbl_unlhsh_addr6 *iter;
503 364
504 entry = kzalloc(sizeof(*entry), GFP_ATOMIC); 365 entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
505 if (entry == NULL) 366 if (entry == NULL)
506 return -ENOMEM; 367 return -ENOMEM;
507 368
508 ipv6_addr_copy(&entry->addr, addr); 369 ipv6_addr_copy(&entry->list.addr, addr);
509 entry->addr.s6_addr32[0] &= mask->s6_addr32[0]; 370 entry->list.addr.s6_addr32[0] &= mask->s6_addr32[0];
510 entry->addr.s6_addr32[1] &= mask->s6_addr32[1]; 371 entry->list.addr.s6_addr32[1] &= mask->s6_addr32[1];
511 entry->addr.s6_addr32[2] &= mask->s6_addr32[2]; 372 entry->list.addr.s6_addr32[2] &= mask->s6_addr32[2];
512 entry->addr.s6_addr32[3] &= mask->s6_addr32[3]; 373 entry->list.addr.s6_addr32[3] &= mask->s6_addr32[3];
513 ipv6_addr_copy(&entry->mask, mask); 374 ipv6_addr_copy(&entry->list.mask, mask);
514 entry->secid = secid; 375 entry->list.valid = 1;
515 entry->valid = 1;
516 INIT_RCU_HEAD(&entry->rcu); 376 INIT_RCU_HEAD(&entry->rcu);
377 entry->secid = secid;
517 378
518 spin_lock(&netlbl_unlhsh_lock); 379 spin_lock(&netlbl_unlhsh_lock);
519 iter = netlbl_unlhsh_search_addr6(&entry->addr, iface); 380 ret_val = netlbl_af6list_add(&entry->list, &iface->addr6_list);
520 if (iter != NULL &&
521 (ipv6_addr_equal(&iter->addr, addr) &&
522 ipv6_addr_equal(&iter->mask, mask))) {
523 spin_unlock(&netlbl_unlhsh_lock);
524 kfree(entry);
525 return -EEXIST;
526 }
527 /* in order to speed up address searches through the list (the common
528 * case) we need to keep the list in order based on the size of the
529 * address mask such that the entry with the widest mask (smallest
530 * numerical value) appears first in the list */
531 list_for_each_entry_rcu(iter, &iface->addr6_list, list)
532 if (iter->valid &&
533 ipv6_addr_cmp(&entry->mask, &iter->mask) > 0) {
534 __list_add_rcu(&entry->list,
535 iter->list.prev,
536 &iter->list);
537 spin_unlock(&netlbl_unlhsh_lock);
538 return 0;
539 }
540 list_add_tail_rcu(&entry->list, &iface->addr6_list);
541 spin_unlock(&netlbl_unlhsh_lock); 381 spin_unlock(&netlbl_unlhsh_lock);
382
383 if (ret_val != 0)
384 kfree(entry);
542 return 0; 385 return 0;
543} 386}
544#endif /* IPv6 */ 387#endif /* IPv6 */
@@ -658,10 +501,10 @@ static int netlbl_unlhsh_add(struct net *net,
658 mask4 = (struct in_addr *)mask; 501 mask4 = (struct in_addr *)mask;
659 ret_val = netlbl_unlhsh_add_addr4(iface, addr4, mask4, secid); 502 ret_val = netlbl_unlhsh_add_addr4(iface, addr4, mask4, secid);
660 if (audit_buf != NULL) 503 if (audit_buf != NULL)
661 netlbl_unlabel_audit_addr4(audit_buf, 504 netlbl_af4list_audit_addr(audit_buf, 1,
662 dev_name, 505 dev_name,
663 addr4->s_addr, 506 addr4->s_addr,
664 mask4->s_addr); 507 mask4->s_addr);
665 break; 508 break;
666 } 509 }
667#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 510#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
@@ -672,9 +515,9 @@ static int netlbl_unlhsh_add(struct net *net,
672 mask6 = (struct in6_addr *)mask; 515 mask6 = (struct in6_addr *)mask;
673 ret_val = netlbl_unlhsh_add_addr6(iface, addr6, mask6, secid); 516 ret_val = netlbl_unlhsh_add_addr6(iface, addr6, mask6, secid);
674 if (audit_buf != NULL) 517 if (audit_buf != NULL)
675 netlbl_unlabel_audit_addr6(audit_buf, 518 netlbl_af6list_audit_addr(audit_buf, 1,
676 dev_name, 519 dev_name,
677 addr6, mask6); 520 addr6, mask6);
678 break; 521 break;
679 } 522 }
680#endif /* IPv6 */ 523#endif /* IPv6 */
@@ -719,35 +562,34 @@ static int netlbl_unlhsh_remove_addr4(struct net *net,
719 const struct in_addr *mask, 562 const struct in_addr *mask,
720 struct netlbl_audit *audit_info) 563 struct netlbl_audit *audit_info)
721{ 564{
722 int ret_val = -ENOENT; 565 int ret_val = 0;
566 struct netlbl_af4list *list_entry;
723 struct netlbl_unlhsh_addr4 *entry; 567 struct netlbl_unlhsh_addr4 *entry;
724 struct audit_buffer *audit_buf = NULL; 568 struct audit_buffer *audit_buf;
725 struct net_device *dev; 569 struct net_device *dev;
726 char *secctx = NULL; 570 char *secctx;
727 u32 secctx_len; 571 u32 secctx_len;
728 572
729 spin_lock(&netlbl_unlhsh_lock); 573 spin_lock(&netlbl_unlhsh_lock);
730 entry = netlbl_unlhsh_search_addr4(addr->s_addr, iface); 574 list_entry = netlbl_af4list_remove(addr->s_addr, mask->s_addr,
731 if (entry != NULL && 575 &iface->addr4_list);
732 entry->addr == addr->s_addr && entry->mask == mask->s_addr) {
733 entry->valid = 0;
734 list_del_rcu(&entry->list);
735 ret_val = 0;
736 }
737 spin_unlock(&netlbl_unlhsh_lock); 576 spin_unlock(&netlbl_unlhsh_lock);
577 if (list_entry == NULL)
578 ret_val = -ENOENT;
579 entry = netlbl_unlhsh_addr4_entry(list_entry);
738 580
739 audit_buf = netlbl_audit_start_common(AUDIT_MAC_UNLBL_STCDEL, 581 audit_buf = netlbl_audit_start_common(AUDIT_MAC_UNLBL_STCDEL,
740 audit_info); 582 audit_info);
741 if (audit_buf != NULL) { 583 if (audit_buf != NULL) {
742 dev = dev_get_by_index(net, iface->ifindex); 584 dev = dev_get_by_index(net, iface->ifindex);
743 netlbl_unlabel_audit_addr4(audit_buf, 585 netlbl_af4list_audit_addr(audit_buf, 1,
744 (dev != NULL ? dev->name : NULL), 586 (dev != NULL ? dev->name : NULL),
745 entry->addr, entry->mask); 587 addr->s_addr, mask->s_addr);
746 if (dev != NULL) 588 if (dev != NULL)
747 dev_put(dev); 589 dev_put(dev);
748 if (security_secid_to_secctx(entry->secid, 590 if (entry && security_secid_to_secctx(entry->secid,
749 &secctx, 591 &secctx,
750 &secctx_len) == 0) { 592 &secctx_len) == 0) {
751 audit_log_format(audit_buf, " sec_obj=%s", secctx); 593 audit_log_format(audit_buf, " sec_obj=%s", secctx);
752 security_release_secctx(secctx, secctx_len); 594 security_release_secctx(secctx, secctx_len);
753 } 595 }
@@ -781,36 +623,33 @@ static int netlbl_unlhsh_remove_addr6(struct net *net,
781 const struct in6_addr *mask, 623 const struct in6_addr *mask,
782 struct netlbl_audit *audit_info) 624 struct netlbl_audit *audit_info)
783{ 625{
784 int ret_val = -ENOENT; 626 int ret_val = 0;
627 struct netlbl_af6list *list_entry;
785 struct netlbl_unlhsh_addr6 *entry; 628 struct netlbl_unlhsh_addr6 *entry;
786 struct audit_buffer *audit_buf = NULL; 629 struct audit_buffer *audit_buf;
787 struct net_device *dev; 630 struct net_device *dev;
788 char *secctx = NULL; 631 char *secctx;
789 u32 secctx_len; 632 u32 secctx_len;
790 633
791 spin_lock(&netlbl_unlhsh_lock); 634 spin_lock(&netlbl_unlhsh_lock);
792 entry = netlbl_unlhsh_search_addr6(addr, iface); 635 list_entry = netlbl_af6list_remove(addr, mask, &iface->addr6_list);
793 if (entry != NULL &&
794 (ipv6_addr_equal(&entry->addr, addr) &&
795 ipv6_addr_equal(&entry->mask, mask))) {
796 entry->valid = 0;
797 list_del_rcu(&entry->list);
798 ret_val = 0;
799 }
800 spin_unlock(&netlbl_unlhsh_lock); 636 spin_unlock(&netlbl_unlhsh_lock);
637 if (list_entry == NULL)
638 ret_val = -ENOENT;
639 entry = netlbl_unlhsh_addr6_entry(list_entry);
801 640
802 audit_buf = netlbl_audit_start_common(AUDIT_MAC_UNLBL_STCDEL, 641 audit_buf = netlbl_audit_start_common(AUDIT_MAC_UNLBL_STCDEL,
803 audit_info); 642 audit_info);
804 if (audit_buf != NULL) { 643 if (audit_buf != NULL) {
805 dev = dev_get_by_index(net, iface->ifindex); 644 dev = dev_get_by_index(net, iface->ifindex);
806 netlbl_unlabel_audit_addr6(audit_buf, 645 netlbl_af6list_audit_addr(audit_buf, 1,
807 (dev != NULL ? dev->name : NULL), 646 (dev != NULL ? dev->name : NULL),
808 addr, mask); 647 addr, mask);
809 if (dev != NULL) 648 if (dev != NULL)
810 dev_put(dev); 649 dev_put(dev);
811 if (security_secid_to_secctx(entry->secid, 650 if (entry && security_secid_to_secctx(entry->secid,
812 &secctx, 651 &secctx,
813 &secctx_len) == 0) { 652 &secctx_len) == 0) {
814 audit_log_format(audit_buf, " sec_obj=%s", secctx); 653 audit_log_format(audit_buf, " sec_obj=%s", secctx);
815 security_release_secctx(secctx, secctx_len); 654 security_release_secctx(secctx, secctx_len);
816 } 655 }
@@ -836,16 +675,18 @@ static int netlbl_unlhsh_remove_addr6(struct net *net,
836 */ 675 */
837static void netlbl_unlhsh_condremove_iface(struct netlbl_unlhsh_iface *iface) 676static void netlbl_unlhsh_condremove_iface(struct netlbl_unlhsh_iface *iface)
838{ 677{
839 struct netlbl_unlhsh_addr4 *iter4; 678 struct netlbl_af4list *iter4;
840 struct netlbl_unlhsh_addr6 *iter6; 679#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
680 struct netlbl_af6list *iter6;
681#endif /* IPv6 */
841 682
842 spin_lock(&netlbl_unlhsh_lock); 683 spin_lock(&netlbl_unlhsh_lock);
843 list_for_each_entry_rcu(iter4, &iface->addr4_list, list) 684 netlbl_af4list_foreach_rcu(iter4, &iface->addr4_list)
844 if (iter4->valid) 685 goto unlhsh_condremove_failure;
845 goto unlhsh_condremove_failure; 686#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
846 list_for_each_entry_rcu(iter6, &iface->addr6_list, list) 687 netlbl_af6list_foreach_rcu(iter6, &iface->addr6_list)
847 if (iter6->valid) 688 goto unlhsh_condremove_failure;
848 goto unlhsh_condremove_failure; 689#endif /* IPv6 */
849 iface->valid = 0; 690 iface->valid = 0;
850 if (iface->ifindex > 0) 691 if (iface->ifindex > 0)
851 list_del_rcu(&iface->list); 692 list_del_rcu(&iface->list);
@@ -1349,7 +1190,7 @@ static int netlbl_unlabel_staticlist_gen(u32 cmd,
1349 if (addr4) { 1190 if (addr4) {
1350 struct in_addr addr_struct; 1191 struct in_addr addr_struct;
1351 1192
1352 addr_struct.s_addr = addr4->addr; 1193 addr_struct.s_addr = addr4->list.addr;
1353 ret_val = nla_put(cb_arg->skb, 1194 ret_val = nla_put(cb_arg->skb,
1354 NLBL_UNLABEL_A_IPV4ADDR, 1195 NLBL_UNLABEL_A_IPV4ADDR,
1355 sizeof(struct in_addr), 1196 sizeof(struct in_addr),
@@ -1357,7 +1198,7 @@ static int netlbl_unlabel_staticlist_gen(u32 cmd,
1357 if (ret_val != 0) 1198 if (ret_val != 0)
1358 goto list_cb_failure; 1199 goto list_cb_failure;
1359 1200
1360 addr_struct.s_addr = addr4->mask; 1201 addr_struct.s_addr = addr4->list.mask;
1361 ret_val = nla_put(cb_arg->skb, 1202 ret_val = nla_put(cb_arg->skb,
1362 NLBL_UNLABEL_A_IPV4MASK, 1203 NLBL_UNLABEL_A_IPV4MASK,
1363 sizeof(struct in_addr), 1204 sizeof(struct in_addr),
@@ -1370,14 +1211,14 @@ static int netlbl_unlabel_staticlist_gen(u32 cmd,
1370 ret_val = nla_put(cb_arg->skb, 1211 ret_val = nla_put(cb_arg->skb,
1371 NLBL_UNLABEL_A_IPV6ADDR, 1212 NLBL_UNLABEL_A_IPV6ADDR,
1372 sizeof(struct in6_addr), 1213 sizeof(struct in6_addr),
1373 &addr6->addr); 1214 &addr6->list.addr);
1374 if (ret_val != 0) 1215 if (ret_val != 0)
1375 goto list_cb_failure; 1216 goto list_cb_failure;
1376 1217
1377 ret_val = nla_put(cb_arg->skb, 1218 ret_val = nla_put(cb_arg->skb,
1378 NLBL_UNLABEL_A_IPV6MASK, 1219 NLBL_UNLABEL_A_IPV6MASK,
1379 sizeof(struct in6_addr), 1220 sizeof(struct in6_addr),
1380 &addr6->mask); 1221 &addr6->list.mask);
1381 if (ret_val != 0) 1222 if (ret_val != 0)
1382 goto list_cb_failure; 1223 goto list_cb_failure;
1383 1224
@@ -1425,8 +1266,11 @@ static int netlbl_unlabel_staticlist(struct sk_buff *skb,
1425 u32 iter_bkt; 1266 u32 iter_bkt;
1426 u32 iter_chain = 0, iter_addr4 = 0, iter_addr6 = 0; 1267 u32 iter_chain = 0, iter_addr4 = 0, iter_addr6 = 0;
1427 struct netlbl_unlhsh_iface *iface; 1268 struct netlbl_unlhsh_iface *iface;
1428 struct netlbl_unlhsh_addr4 *addr4; 1269 struct list_head *iter_list;
1429 struct netlbl_unlhsh_addr6 *addr6; 1270 struct netlbl_af4list *addr4;
1271#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
1272 struct netlbl_af6list *addr6;
1273#endif
1430 1274
1431 cb_arg.nl_cb = cb; 1275 cb_arg.nl_cb = cb;
1432 cb_arg.skb = skb; 1276 cb_arg.skb = skb;
@@ -1436,44 +1280,43 @@ static int netlbl_unlabel_staticlist(struct sk_buff *skb,
1436 for (iter_bkt = skip_bkt; 1280 for (iter_bkt = skip_bkt;
1437 iter_bkt < rcu_dereference(netlbl_unlhsh)->size; 1281 iter_bkt < rcu_dereference(netlbl_unlhsh)->size;
1438 iter_bkt++, iter_chain = 0, iter_addr4 = 0, iter_addr6 = 0) { 1282 iter_bkt++, iter_chain = 0, iter_addr4 = 0, iter_addr6 = 0) {
1439 list_for_each_entry_rcu(iface, 1283 iter_list = &rcu_dereference(netlbl_unlhsh)->tbl[iter_bkt];
1440 &rcu_dereference(netlbl_unlhsh)->tbl[iter_bkt], 1284 list_for_each_entry_rcu(iface, iter_list, list) {
1441 list) {
1442 if (!iface->valid || 1285 if (!iface->valid ||
1443 iter_chain++ < skip_chain) 1286 iter_chain++ < skip_chain)
1444 continue; 1287 continue;
1445 list_for_each_entry_rcu(addr4, 1288 netlbl_af4list_foreach_rcu(addr4,
1446 &iface->addr4_list, 1289 &iface->addr4_list) {
1447 list) { 1290 if (iter_addr4++ < skip_addr4)
1448 if (!addr4->valid || iter_addr4++ < skip_addr4)
1449 continue; 1291 continue;
1450 if (netlbl_unlabel_staticlist_gen( 1292 if (netlbl_unlabel_staticlist_gen(
1451 NLBL_UNLABEL_C_STATICLIST, 1293 NLBL_UNLABEL_C_STATICLIST,
1452 iface, 1294 iface,
1453 addr4, 1295 netlbl_unlhsh_addr4_entry(addr4),
1454 NULL, 1296 NULL,
1455 &cb_arg) < 0) { 1297 &cb_arg) < 0) {
1456 iter_addr4--; 1298 iter_addr4--;
1457 iter_chain--; 1299 iter_chain--;
1458 goto unlabel_staticlist_return; 1300 goto unlabel_staticlist_return;
1459 } 1301 }
1460 } 1302 }
1461 list_for_each_entry_rcu(addr6, 1303#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
1462 &iface->addr6_list, 1304 netlbl_af6list_foreach_rcu(addr6,
1463 list) { 1305 &iface->addr6_list) {
1464 if (!addr6->valid || iter_addr6++ < skip_addr6) 1306 if (iter_addr6++ < skip_addr6)
1465 continue; 1307 continue;
1466 if (netlbl_unlabel_staticlist_gen( 1308 if (netlbl_unlabel_staticlist_gen(
1467 NLBL_UNLABEL_C_STATICLIST, 1309 NLBL_UNLABEL_C_STATICLIST,
1468 iface, 1310 iface,
1469 NULL, 1311 NULL,
1470 addr6, 1312 netlbl_unlhsh_addr6_entry(addr6),
1471 &cb_arg) < 0) { 1313 &cb_arg) < 0) {
1472 iter_addr6--; 1314 iter_addr6--;
1473 iter_chain--; 1315 iter_chain--;
1474 goto unlabel_staticlist_return; 1316 goto unlabel_staticlist_return;
1475 } 1317 }
1476 } 1318 }
1319#endif /* IPv6 */
1477 } 1320 }
1478 } 1321 }
1479 1322
@@ -1504,9 +1347,12 @@ static int netlbl_unlabel_staticlistdef(struct sk_buff *skb,
1504 struct netlbl_unlhsh_iface *iface; 1347 struct netlbl_unlhsh_iface *iface;
1505 u32 skip_addr4 = cb->args[0]; 1348 u32 skip_addr4 = cb->args[0];
1506 u32 skip_addr6 = cb->args[1]; 1349 u32 skip_addr6 = cb->args[1];
1507 u32 iter_addr4 = 0, iter_addr6 = 0; 1350 u32 iter_addr4 = 0;
1508 struct netlbl_unlhsh_addr4 *addr4; 1351 struct netlbl_af4list *addr4;
1509 struct netlbl_unlhsh_addr6 *addr6; 1352#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
1353 u32 iter_addr6 = 0;
1354 struct netlbl_af6list *addr6;
1355#endif
1510 1356
1511 cb_arg.nl_cb = cb; 1357 cb_arg.nl_cb = cb;
1512 cb_arg.skb = skb; 1358 cb_arg.skb = skb;
@@ -1517,30 +1363,32 @@ static int netlbl_unlabel_staticlistdef(struct sk_buff *skb,
1517 if (iface == NULL || !iface->valid) 1363 if (iface == NULL || !iface->valid)
1518 goto unlabel_staticlistdef_return; 1364 goto unlabel_staticlistdef_return;
1519 1365
1520 list_for_each_entry_rcu(addr4, &iface->addr4_list, list) { 1366 netlbl_af4list_foreach_rcu(addr4, &iface->addr4_list) {
1521 if (!addr4->valid || iter_addr4++ < skip_addr4) 1367 if (iter_addr4++ < skip_addr4)
1522 continue; 1368 continue;
1523 if (netlbl_unlabel_staticlist_gen(NLBL_UNLABEL_C_STATICLISTDEF, 1369 if (netlbl_unlabel_staticlist_gen(NLBL_UNLABEL_C_STATICLISTDEF,
1524 iface, 1370 iface,
1525 addr4, 1371 netlbl_unlhsh_addr4_entry(addr4),
1526 NULL, 1372 NULL,
1527 &cb_arg) < 0) { 1373 &cb_arg) < 0) {
1528 iter_addr4--; 1374 iter_addr4--;
1529 goto unlabel_staticlistdef_return; 1375 goto unlabel_staticlistdef_return;
1530 } 1376 }
1531 } 1377 }
1532 list_for_each_entry_rcu(addr6, &iface->addr6_list, list) { 1378#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
1533 if (!addr6->valid || iter_addr6++ < skip_addr6) 1379 netlbl_af6list_foreach_rcu(addr6, &iface->addr6_list) {
1380 if (iter_addr6++ < skip_addr6)
1534 continue; 1381 continue;
1535 if (netlbl_unlabel_staticlist_gen(NLBL_UNLABEL_C_STATICLISTDEF, 1382 if (netlbl_unlabel_staticlist_gen(NLBL_UNLABEL_C_STATICLISTDEF,
1536 iface, 1383 iface,
1537 NULL, 1384 NULL,
1538 addr6, 1385 netlbl_unlhsh_addr6_entry(addr6),
1539 &cb_arg) < 0) { 1386 &cb_arg) < 0) {
1540 iter_addr6--; 1387 iter_addr6--;
1541 goto unlabel_staticlistdef_return; 1388 goto unlabel_staticlistdef_return;
1542 } 1389 }
1543 } 1390 }
1391#endif /* IPv6 */
1544 1392
1545unlabel_staticlistdef_return: 1393unlabel_staticlistdef_return:
1546 rcu_read_unlock(); 1394 rcu_read_unlock();
@@ -1718,25 +1566,27 @@ int netlbl_unlabel_getattr(const struct sk_buff *skb,
1718 switch (family) { 1566 switch (family) {
1719 case PF_INET: { 1567 case PF_INET: {
1720 struct iphdr *hdr4; 1568 struct iphdr *hdr4;
1721 struct netlbl_unlhsh_addr4 *addr4; 1569 struct netlbl_af4list *addr4;
1722 1570
1723 hdr4 = ip_hdr(skb); 1571 hdr4 = ip_hdr(skb);
1724 addr4 = netlbl_unlhsh_search_addr4(hdr4->saddr, iface); 1572 addr4 = netlbl_af4list_search(hdr4->saddr,
1573 &iface->addr4_list);
1725 if (addr4 == NULL) 1574 if (addr4 == NULL)
1726 goto unlabel_getattr_nolabel; 1575 goto unlabel_getattr_nolabel;
1727 secattr->attr.secid = addr4->secid; 1576 secattr->attr.secid = netlbl_unlhsh_addr4_entry(addr4)->secid;
1728 break; 1577 break;
1729 } 1578 }
1730#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 1579#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
1731 case PF_INET6: { 1580 case PF_INET6: {
1732 struct ipv6hdr *hdr6; 1581 struct ipv6hdr *hdr6;
1733 struct netlbl_unlhsh_addr6 *addr6; 1582 struct netlbl_af6list *addr6;
1734 1583
1735 hdr6 = ipv6_hdr(skb); 1584 hdr6 = ipv6_hdr(skb);
1736 addr6 = netlbl_unlhsh_search_addr6(&hdr6->saddr, iface); 1585 addr6 = netlbl_af6list_search(&hdr6->saddr,
1586 &iface->addr6_list);
1737 if (addr6 == NULL) 1587 if (addr6 == NULL)
1738 goto unlabel_getattr_nolabel; 1588 goto unlabel_getattr_nolabel;
1739 secattr->attr.secid = addr6->secid; 1589 secattr->attr.secid = netlbl_unlhsh_addr6_entry(addr6)->secid;
1740 break; 1590 break;
1741 } 1591 }
1742#endif /* IPv6 */ 1592#endif /* IPv6 */
diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c
index 4c9890ec2528..473f94e56ead 100644
--- a/scripts/mod/file2alias.c
+++ b/scripts/mod/file2alias.c
@@ -629,6 +629,59 @@ static int do_i2c_entry(const char *filename, struct i2c_device_id *id,
629 return 1; 629 return 1;
630} 630}
631 631
632static const struct dmifield {
633 const char *prefix;
634 int field;
635} dmi_fields[] = {
636 { "bvn", DMI_BIOS_VENDOR },
637 { "bvr", DMI_BIOS_VERSION },
638 { "bd", DMI_BIOS_DATE },
639 { "svn", DMI_SYS_VENDOR },
640 { "pn", DMI_PRODUCT_NAME },
641 { "pvr", DMI_PRODUCT_VERSION },
642 { "rvn", DMI_BOARD_VENDOR },
643 { "rn", DMI_BOARD_NAME },
644 { "rvr", DMI_BOARD_VERSION },
645 { "cvn", DMI_CHASSIS_VENDOR },
646 { "ct", DMI_CHASSIS_TYPE },
647 { "cvr", DMI_CHASSIS_VERSION },
648 { NULL, DMI_NONE }
649};
650
651static void dmi_ascii_filter(char *d, const char *s)
652{
653 /* Filter out characters we don't want to see in the modalias string */
654 for (; *s; s++)
655 if (*s > ' ' && *s < 127 && *s != ':')
656 *(d++) = *s;
657
658 *d = 0;
659}
660
661
662static int do_dmi_entry(const char *filename, struct dmi_system_id *id,
663 char *alias)
664{
665 int i, j;
666
667 sprintf(alias, "dmi*");
668
669 for (i = 0; i < ARRAY_SIZE(dmi_fields); i++) {
670 for (j = 0; j < 4; j++) {
671 if (id->matches[j].slot &&
672 id->matches[j].slot == dmi_fields[i].field) {
673 sprintf(alias + strlen(alias), ":%s*",
674 dmi_fields[i].prefix);
675 dmi_ascii_filter(alias + strlen(alias),
676 id->matches[j].substr);
677 strcat(alias, "*");
678 }
679 }
680 }
681
682 strcat(alias, ":");
683 return 1;
684}
632/* Ignore any prefix, eg. some architectures prepend _ */ 685/* Ignore any prefix, eg. some architectures prepend _ */
633static inline int sym_is(const char *symbol, const char *name) 686static inline int sym_is(const char *symbol, const char *name)
634{ 687{
@@ -760,6 +813,10 @@ void handle_moddevtable(struct module *mod, struct elf_info *info,
760 do_table(symval, sym->st_size, 813 do_table(symval, sym->st_size,
761 sizeof(struct i2c_device_id), "i2c", 814 sizeof(struct i2c_device_id), "i2c",
762 do_i2c_entry, mod); 815 do_i2c_entry, mod);
816 else if (sym_is(symname, "__mod_dmi_device_table"))
817 do_table(symval, sym->st_size,
818 sizeof(struct dmi_system_id), "dmi",
819 do_dmi_entry, mod);
763 free(zeros); 820 free(zeros);
764} 821}
765 822
diff --git a/security/inode.c b/security/inode.c
index ca4958ebad8d..efea5a605466 100644
--- a/security/inode.c
+++ b/security/inode.c
@@ -20,8 +20,7 @@
20#include <linux/init.h> 20#include <linux/init.h>
21#include <linux/namei.h> 21#include <linux/namei.h>
22#include <linux/security.h> 22#include <linux/security.h>
23 23#include <linux/magic.h>
24#define SECURITYFS_MAGIC 0x73636673
25 24
26static struct vfsmount *mount; 25static struct vfsmount *mount;
27static int mount_count; 26static int mount_count;
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 4a7374c12d9c..88f19536efad 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -291,6 +291,7 @@ static void sk_free_security(struct sock *sk)
291 struct sk_security_struct *ssec = sk->sk_security; 291 struct sk_security_struct *ssec = sk->sk_security;
292 292
293 sk->sk_security = NULL; 293 sk->sk_security = NULL;
294 selinux_netlbl_sk_security_free(ssec);
294 kfree(ssec); 295 kfree(ssec);
295} 296}
296 297
@@ -2121,7 +2122,6 @@ static inline void flush_unauthorized_files(struct files_struct *files)
2121 long j = -1; 2122 long j = -1;
2122 int drop_tty = 0; 2123 int drop_tty = 0;
2123 2124
2124 mutex_lock(&tty_mutex);
2125 tty = get_current_tty(); 2125 tty = get_current_tty();
2126 if (tty) { 2126 if (tty) {
2127 file_list_lock(); 2127 file_list_lock();
@@ -2139,8 +2139,8 @@ static inline void flush_unauthorized_files(struct files_struct *files)
2139 } 2139 }
2140 } 2140 }
2141 file_list_unlock(); 2141 file_list_unlock();
2142 tty_kref_put(tty);
2142 } 2143 }
2143 mutex_unlock(&tty_mutex);
2144 /* Reset controlling tty. */ 2144 /* Reset controlling tty. */
2145 if (drop_tty) 2145 if (drop_tty)
2146 no_tty(); 2146 no_tty();
@@ -3801,6 +3801,7 @@ out:
3801 3801
3802static int selinux_socket_connect(struct socket *sock, struct sockaddr *address, int addrlen) 3802static int selinux_socket_connect(struct socket *sock, struct sockaddr *address, int addrlen)
3803{ 3803{
3804 struct sock *sk = sock->sk;
3804 struct inode_security_struct *isec; 3805 struct inode_security_struct *isec;
3805 int err; 3806 int err;
3806 3807
@@ -3814,7 +3815,6 @@ static int selinux_socket_connect(struct socket *sock, struct sockaddr *address,
3814 isec = SOCK_INODE(sock)->i_security; 3815 isec = SOCK_INODE(sock)->i_security;
3815 if (isec->sclass == SECCLASS_TCP_SOCKET || 3816 if (isec->sclass == SECCLASS_TCP_SOCKET ||
3816 isec->sclass == SECCLASS_DCCP_SOCKET) { 3817 isec->sclass == SECCLASS_DCCP_SOCKET) {
3817 struct sock *sk = sock->sk;
3818 struct avc_audit_data ad; 3818 struct avc_audit_data ad;
3819 struct sockaddr_in *addr4 = NULL; 3819 struct sockaddr_in *addr4 = NULL;
3820 struct sockaddr_in6 *addr6 = NULL; 3820 struct sockaddr_in6 *addr6 = NULL;
@@ -3848,6 +3848,8 @@ static int selinux_socket_connect(struct socket *sock, struct sockaddr *address,
3848 goto out; 3848 goto out;
3849 } 3849 }
3850 3850
3851 err = selinux_netlbl_socket_connect(sk, address);
3852
3851out: 3853out:
3852 return err; 3854 return err;
3853} 3855}
@@ -4077,20 +4079,28 @@ static int selinux_sock_rcv_skb_iptables_compat(struct sock *sk,
4077} 4079}
4078 4080
4079static int selinux_sock_rcv_skb_compat(struct sock *sk, struct sk_buff *skb, 4081static int selinux_sock_rcv_skb_compat(struct sock *sk, struct sk_buff *skb,
4080 struct avc_audit_data *ad, 4082 u16 family)
4081 u16 family, char *addrp)
4082{ 4083{
4083 int err; 4084 int err;
4084 struct sk_security_struct *sksec = sk->sk_security; 4085 struct sk_security_struct *sksec = sk->sk_security;
4085 u32 peer_sid; 4086 u32 peer_sid;
4086 u32 sk_sid = sksec->sid; 4087 u32 sk_sid = sksec->sid;
4088 struct avc_audit_data ad;
4089 char *addrp;
4090
4091 AVC_AUDIT_DATA_INIT(&ad, NET);
4092 ad.u.net.netif = skb->iif;
4093 ad.u.net.family = family;
4094 err = selinux_parse_skb(skb, &ad, &addrp, 1, NULL);
4095 if (err)
4096 return err;
4087 4097
4088 if (selinux_compat_net) 4098 if (selinux_compat_net)
4089 err = selinux_sock_rcv_skb_iptables_compat(sk, skb, ad, 4099 err = selinux_sock_rcv_skb_iptables_compat(sk, skb, &ad,
4090 family, addrp); 4100 family, addrp);
4091 else 4101 else
4092 err = avc_has_perm(sk_sid, skb->secmark, SECCLASS_PACKET, 4102 err = avc_has_perm(sk_sid, skb->secmark, SECCLASS_PACKET,
4093 PACKET__RECV, ad); 4103 PACKET__RECV, &ad);
4094 if (err) 4104 if (err)
4095 return err; 4105 return err;
4096 4106
@@ -4099,12 +4109,14 @@ static int selinux_sock_rcv_skb_compat(struct sock *sk, struct sk_buff *skb,
4099 if (err) 4109 if (err)
4100 return err; 4110 return err;
4101 err = avc_has_perm(sk_sid, peer_sid, 4111 err = avc_has_perm(sk_sid, peer_sid,
4102 SECCLASS_PEER, PEER__RECV, ad); 4112 SECCLASS_PEER, PEER__RECV, &ad);
4113 if (err)
4114 selinux_netlbl_err(skb, err, 0);
4103 } else { 4115 } else {
4104 err = selinux_netlbl_sock_rcv_skb(sksec, skb, family, ad); 4116 err = selinux_netlbl_sock_rcv_skb(sksec, skb, family, &ad);
4105 if (err) 4117 if (err)
4106 return err; 4118 return err;
4107 err = selinux_xfrm_sock_rcv_skb(sksec->sid, skb, ad); 4119 err = selinux_xfrm_sock_rcv_skb(sksec->sid, skb, &ad);
4108 } 4120 }
4109 4121
4110 return err; 4122 return err;
@@ -4118,6 +4130,8 @@ static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
4118 u32 sk_sid = sksec->sid; 4130 u32 sk_sid = sksec->sid;
4119 struct avc_audit_data ad; 4131 struct avc_audit_data ad;
4120 char *addrp; 4132 char *addrp;
4133 u8 secmark_active;
4134 u8 peerlbl_active;
4121 4135
4122 if (family != PF_INET && family != PF_INET6) 4136 if (family != PF_INET && family != PF_INET6)
4123 return 0; 4137 return 0;
@@ -4126,6 +4140,18 @@ static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
4126 if (family == PF_INET6 && skb->protocol == htons(ETH_P_IP)) 4140 if (family == PF_INET6 && skb->protocol == htons(ETH_P_IP))
4127 family = PF_INET; 4141 family = PF_INET;
4128 4142
4143 /* If any sort of compatibility mode is enabled then handoff processing
4144 * to the selinux_sock_rcv_skb_compat() function to deal with the
4145 * special handling. We do this in an attempt to keep this function
4146 * as fast and as clean as possible. */
4147 if (selinux_compat_net || !selinux_policycap_netpeer)
4148 return selinux_sock_rcv_skb_compat(sk, skb, family);
4149
4150 secmark_active = selinux_secmark_enabled();
4151 peerlbl_active = netlbl_enabled() || selinux_xfrm_enabled();
4152 if (!secmark_active && !peerlbl_active)
4153 return 0;
4154
4129 AVC_AUDIT_DATA_INIT(&ad, NET); 4155 AVC_AUDIT_DATA_INIT(&ad, NET);
4130 ad.u.net.netif = skb->iif; 4156 ad.u.net.netif = skb->iif;
4131 ad.u.net.family = family; 4157 ad.u.net.family = family;
@@ -4133,15 +4159,7 @@ static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
4133 if (err) 4159 if (err)
4134 return err; 4160 return err;
4135 4161
4136 /* If any sort of compatibility mode is enabled then handoff processing 4162 if (peerlbl_active) {
4137 * to the selinux_sock_rcv_skb_compat() function to deal with the
4138 * special handling. We do this in an attempt to keep this function
4139 * as fast and as clean as possible. */
4140 if (selinux_compat_net || !selinux_policycap_netpeer)
4141 return selinux_sock_rcv_skb_compat(sk, skb, &ad,
4142 family, addrp);
4143
4144 if (netlbl_enabled() || selinux_xfrm_enabled()) {
4145 u32 peer_sid; 4163 u32 peer_sid;
4146 4164
4147 err = selinux_skb_peerlbl_sid(skb, family, &peer_sid); 4165 err = selinux_skb_peerlbl_sid(skb, family, &peer_sid);
@@ -4149,13 +4167,17 @@ static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
4149 return err; 4167 return err;
4150 err = selinux_inet_sys_rcv_skb(skb->iif, addrp, family, 4168 err = selinux_inet_sys_rcv_skb(skb->iif, addrp, family,
4151 peer_sid, &ad); 4169 peer_sid, &ad);
4152 if (err) 4170 if (err) {
4171 selinux_netlbl_err(skb, err, 0);
4153 return err; 4172 return err;
4173 }
4154 err = avc_has_perm(sk_sid, peer_sid, SECCLASS_PEER, 4174 err = avc_has_perm(sk_sid, peer_sid, SECCLASS_PEER,
4155 PEER__RECV, &ad); 4175 PEER__RECV, &ad);
4176 if (err)
4177 selinux_netlbl_err(skb, err, 0);
4156 } 4178 }
4157 4179
4158 if (selinux_secmark_enabled()) { 4180 if (secmark_active) {
4159 err = avc_has_perm(sk_sid, skb->secmark, SECCLASS_PACKET, 4181 err = avc_has_perm(sk_sid, skb->secmark, SECCLASS_PACKET,
4160 PACKET__RECV, &ad); 4182 PACKET__RECV, &ad);
4161 if (err) 4183 if (err)
@@ -4214,10 +4236,12 @@ static int selinux_socket_getpeersec_dgram(struct socket *sock, struct sk_buff *
4214 u32 peer_secid = SECSID_NULL; 4236 u32 peer_secid = SECSID_NULL;
4215 u16 family; 4237 u16 family;
4216 4238
4217 if (sock) 4239 if (skb && skb->protocol == htons(ETH_P_IP))
4240 family = PF_INET;
4241 else if (skb && skb->protocol == htons(ETH_P_IPV6))
4242 family = PF_INET6;
4243 else if (sock)
4218 family = sock->sk->sk_family; 4244 family = sock->sk->sk_family;
4219 else if (skb && skb->sk)
4220 family = skb->sk->sk_family;
4221 else 4245 else
4222 goto out; 4246 goto out;
4223 4247
@@ -4275,8 +4299,6 @@ static void selinux_sock_graft(struct sock *sk, struct socket *parent)
4275 sk->sk_family == PF_UNIX) 4299 sk->sk_family == PF_UNIX)
4276 isec->sid = sksec->sid; 4300 isec->sid = sksec->sid;
4277 sksec->sclass = isec->sclass; 4301 sksec->sclass = isec->sclass;
4278
4279 selinux_netlbl_sock_graft(sk, parent);
4280} 4302}
4281 4303
4282static int selinux_inet_conn_request(struct sock *sk, struct sk_buff *skb, 4304static int selinux_inet_conn_request(struct sock *sk, struct sk_buff *skb,
@@ -4284,10 +4306,15 @@ static int selinux_inet_conn_request(struct sock *sk, struct sk_buff *skb,
4284{ 4306{
4285 struct sk_security_struct *sksec = sk->sk_security; 4307 struct sk_security_struct *sksec = sk->sk_security;
4286 int err; 4308 int err;
4309 u16 family = sk->sk_family;
4287 u32 newsid; 4310 u32 newsid;
4288 u32 peersid; 4311 u32 peersid;
4289 4312
4290 err = selinux_skb_peerlbl_sid(skb, sk->sk_family, &peersid); 4313 /* handle mapped IPv4 packets arriving via IPv6 sockets */
4314 if (family == PF_INET6 && skb->protocol == htons(ETH_P_IP))
4315 family = PF_INET;
4316
4317 err = selinux_skb_peerlbl_sid(skb, family, &peersid);
4291 if (err) 4318 if (err)
4292 return err; 4319 return err;
4293 if (peersid == SECSID_NULL) { 4320 if (peersid == SECSID_NULL) {
@@ -4322,12 +4349,18 @@ static void selinux_inet_csk_clone(struct sock *newsk,
4322 selinux_netlbl_sk_security_reset(newsksec, req->rsk_ops->family); 4349 selinux_netlbl_sk_security_reset(newsksec, req->rsk_ops->family);
4323} 4350}
4324 4351
4325static void selinux_inet_conn_established(struct sock *sk, 4352static void selinux_inet_conn_established(struct sock *sk, struct sk_buff *skb)
4326 struct sk_buff *skb)
4327{ 4353{
4354 u16 family = sk->sk_family;
4328 struct sk_security_struct *sksec = sk->sk_security; 4355 struct sk_security_struct *sksec = sk->sk_security;
4329 4356
4330 selinux_skb_peerlbl_sid(skb, sk->sk_family, &sksec->peer_sid); 4357 /* handle mapped IPv4 packets arriving via IPv6 sockets */
4358 if (family == PF_INET6 && skb->protocol == htons(ETH_P_IP))
4359 family = PF_INET;
4360
4361 selinux_skb_peerlbl_sid(skb, family, &sksec->peer_sid);
4362
4363 selinux_netlbl_inet_conn_established(sk, family);
4331} 4364}
4332 4365
4333static void selinux_req_classify_flow(const struct request_sock *req, 4366static void selinux_req_classify_flow(const struct request_sock *req,
@@ -4377,39 +4410,54 @@ out:
4377static unsigned int selinux_ip_forward(struct sk_buff *skb, int ifindex, 4410static unsigned int selinux_ip_forward(struct sk_buff *skb, int ifindex,
4378 u16 family) 4411 u16 family)
4379{ 4412{
4413 int err;
4380 char *addrp; 4414 char *addrp;
4381 u32 peer_sid; 4415 u32 peer_sid;
4382 struct avc_audit_data ad; 4416 struct avc_audit_data ad;
4383 u8 secmark_active; 4417 u8 secmark_active;
4418 u8 netlbl_active;
4384 u8 peerlbl_active; 4419 u8 peerlbl_active;
4385 4420
4386 if (!selinux_policycap_netpeer) 4421 if (!selinux_policycap_netpeer)
4387 return NF_ACCEPT; 4422 return NF_ACCEPT;
4388 4423
4389 secmark_active = selinux_secmark_enabled(); 4424 secmark_active = selinux_secmark_enabled();
4390 peerlbl_active = netlbl_enabled() || selinux_xfrm_enabled(); 4425 netlbl_active = netlbl_enabled();
4426 peerlbl_active = netlbl_active || selinux_xfrm_enabled();
4391 if (!secmark_active && !peerlbl_active) 4427 if (!secmark_active && !peerlbl_active)
4392 return NF_ACCEPT; 4428 return NF_ACCEPT;
4393 4429
4430 if (selinux_skb_peerlbl_sid(skb, family, &peer_sid) != 0)
4431 return NF_DROP;
4432
4394 AVC_AUDIT_DATA_INIT(&ad, NET); 4433 AVC_AUDIT_DATA_INIT(&ad, NET);
4395 ad.u.net.netif = ifindex; 4434 ad.u.net.netif = ifindex;
4396 ad.u.net.family = family; 4435 ad.u.net.family = family;
4397 if (selinux_parse_skb(skb, &ad, &addrp, 1, NULL) != 0) 4436 if (selinux_parse_skb(skb, &ad, &addrp, 1, NULL) != 0)
4398 return NF_DROP; 4437 return NF_DROP;
4399 4438
4400 if (selinux_skb_peerlbl_sid(skb, family, &peer_sid) != 0) 4439 if (peerlbl_active) {
4401 return NF_DROP; 4440 err = selinux_inet_sys_rcv_skb(ifindex, addrp, family,
4402 4441 peer_sid, &ad);
4403 if (peerlbl_active) 4442 if (err) {
4404 if (selinux_inet_sys_rcv_skb(ifindex, addrp, family, 4443 selinux_netlbl_err(skb, err, 1);
4405 peer_sid, &ad) != 0)
4406 return NF_DROP; 4444 return NF_DROP;
4445 }
4446 }
4407 4447
4408 if (secmark_active) 4448 if (secmark_active)
4409 if (avc_has_perm(peer_sid, skb->secmark, 4449 if (avc_has_perm(peer_sid, skb->secmark,
4410 SECCLASS_PACKET, PACKET__FORWARD_IN, &ad)) 4450 SECCLASS_PACKET, PACKET__FORWARD_IN, &ad))
4411 return NF_DROP; 4451 return NF_DROP;
4412 4452
4453 if (netlbl_active)
4454 /* we do this in the FORWARD path and not the POST_ROUTING
4455 * path because we want to make sure we apply the necessary
4456 * labeling before IPsec is applied so we can leverage AH
4457 * protection */
4458 if (selinux_netlbl_skbuff_setsid(skb, family, peer_sid) != 0)
4459 return NF_DROP;
4460
4413 return NF_ACCEPT; 4461 return NF_ACCEPT;
4414} 4462}
4415 4463
@@ -4433,6 +4481,37 @@ static unsigned int selinux_ipv6_forward(unsigned int hooknum,
4433} 4481}
4434#endif /* IPV6 */ 4482#endif /* IPV6 */
4435 4483
4484static unsigned int selinux_ip_output(struct sk_buff *skb,
4485 u16 family)
4486{
4487 u32 sid;
4488
4489 if (!netlbl_enabled())
4490 return NF_ACCEPT;
4491
4492 /* we do this in the LOCAL_OUT path and not the POST_ROUTING path
4493 * because we want to make sure we apply the necessary labeling
4494 * before IPsec is applied so we can leverage AH protection */
4495 if (skb->sk) {
4496 struct sk_security_struct *sksec = skb->sk->sk_security;
4497 sid = sksec->sid;
4498 } else
4499 sid = SECINITSID_KERNEL;
4500 if (selinux_netlbl_skbuff_setsid(skb, family, sid) != 0)
4501 return NF_DROP;
4502
4503 return NF_ACCEPT;
4504}
4505
4506static unsigned int selinux_ipv4_output(unsigned int hooknum,
4507 struct sk_buff *skb,
4508 const struct net_device *in,
4509 const struct net_device *out,
4510 int (*okfn)(struct sk_buff *))
4511{
4512 return selinux_ip_output(skb, PF_INET);
4513}
4514
4436static int selinux_ip_postroute_iptables_compat(struct sock *sk, 4515static int selinux_ip_postroute_iptables_compat(struct sock *sk,
4437 int ifindex, 4516 int ifindex,
4438 struct avc_audit_data *ad, 4517 struct avc_audit_data *ad,
@@ -4500,30 +4579,36 @@ static int selinux_ip_postroute_iptables_compat(struct sock *sk,
4500 4579
4501static unsigned int selinux_ip_postroute_compat(struct sk_buff *skb, 4580static unsigned int selinux_ip_postroute_compat(struct sk_buff *skb,
4502 int ifindex, 4581 int ifindex,
4503 struct avc_audit_data *ad, 4582 u16 family)
4504 u16 family,
4505 char *addrp,
4506 u8 proto)
4507{ 4583{
4508 struct sock *sk = skb->sk; 4584 struct sock *sk = skb->sk;
4509 struct sk_security_struct *sksec; 4585 struct sk_security_struct *sksec;
4586 struct avc_audit_data ad;
4587 char *addrp;
4588 u8 proto;
4510 4589
4511 if (sk == NULL) 4590 if (sk == NULL)
4512 return NF_ACCEPT; 4591 return NF_ACCEPT;
4513 sksec = sk->sk_security; 4592 sksec = sk->sk_security;
4514 4593
4594 AVC_AUDIT_DATA_INIT(&ad, NET);
4595 ad.u.net.netif = ifindex;
4596 ad.u.net.family = family;
4597 if (selinux_parse_skb(skb, &ad, &addrp, 0, &proto))
4598 return NF_DROP;
4599
4515 if (selinux_compat_net) { 4600 if (selinux_compat_net) {
4516 if (selinux_ip_postroute_iptables_compat(skb->sk, ifindex, 4601 if (selinux_ip_postroute_iptables_compat(skb->sk, ifindex,
4517 ad, family, addrp)) 4602 &ad, family, addrp))
4518 return NF_DROP; 4603 return NF_DROP;
4519 } else { 4604 } else {
4520 if (avc_has_perm(sksec->sid, skb->secmark, 4605 if (avc_has_perm(sksec->sid, skb->secmark,
4521 SECCLASS_PACKET, PACKET__SEND, ad)) 4606 SECCLASS_PACKET, PACKET__SEND, &ad))
4522 return NF_DROP; 4607 return NF_DROP;
4523 } 4608 }
4524 4609
4525 if (selinux_policycap_netpeer) 4610 if (selinux_policycap_netpeer)
4526 if (selinux_xfrm_postroute_last(sksec->sid, skb, ad, proto)) 4611 if (selinux_xfrm_postroute_last(sksec->sid, skb, &ad, proto))
4527 return NF_DROP; 4612 return NF_DROP;
4528 4613
4529 return NF_ACCEPT; 4614 return NF_ACCEPT;
@@ -4537,23 +4622,15 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb, int ifindex,
4537 struct sock *sk; 4622 struct sock *sk;
4538 struct avc_audit_data ad; 4623 struct avc_audit_data ad;
4539 char *addrp; 4624 char *addrp;
4540 u8 proto;
4541 u8 secmark_active; 4625 u8 secmark_active;
4542 u8 peerlbl_active; 4626 u8 peerlbl_active;
4543 4627
4544 AVC_AUDIT_DATA_INIT(&ad, NET);
4545 ad.u.net.netif = ifindex;
4546 ad.u.net.family = family;
4547 if (selinux_parse_skb(skb, &ad, &addrp, 0, &proto))
4548 return NF_DROP;
4549
4550 /* If any sort of compatibility mode is enabled then handoff processing 4628 /* If any sort of compatibility mode is enabled then handoff processing
4551 * to the selinux_ip_postroute_compat() function to deal with the 4629 * to the selinux_ip_postroute_compat() function to deal with the
4552 * special handling. We do this in an attempt to keep this function 4630 * special handling. We do this in an attempt to keep this function
4553 * as fast and as clean as possible. */ 4631 * as fast and as clean as possible. */
4554 if (selinux_compat_net || !selinux_policycap_netpeer) 4632 if (selinux_compat_net || !selinux_policycap_netpeer)
4555 return selinux_ip_postroute_compat(skb, ifindex, &ad, 4633 return selinux_ip_postroute_compat(skb, ifindex, family);
4556 family, addrp, proto);
4557 4634
4558 /* If skb->dst->xfrm is non-NULL then the packet is undergoing an IPsec 4635 /* If skb->dst->xfrm is non-NULL then the packet is undergoing an IPsec
4559 * packet transformation so allow the packet to pass without any checks 4636 * packet transformation so allow the packet to pass without any checks
@@ -4569,21 +4646,45 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb, int ifindex,
4569 if (!secmark_active && !peerlbl_active) 4646 if (!secmark_active && !peerlbl_active)
4570 return NF_ACCEPT; 4647 return NF_ACCEPT;
4571 4648
4572 /* if the packet is locally generated (skb->sk != NULL) then use the 4649 /* if the packet is being forwarded then get the peer label from the
4573 * socket's label as the peer label, otherwise the packet is being 4650 * packet itself; otherwise check to see if it is from a local
4574 * forwarded through this system and we need to fetch the peer label 4651 * application or the kernel, if from an application get the peer label
4575 * directly from the packet */ 4652 * from the sending socket, otherwise use the kernel's sid */
4576 sk = skb->sk; 4653 sk = skb->sk;
4577 if (sk) { 4654 if (sk == NULL) {
4655 switch (family) {
4656 case PF_INET:
4657 if (IPCB(skb)->flags & IPSKB_FORWARDED)
4658 secmark_perm = PACKET__FORWARD_OUT;
4659 else
4660 secmark_perm = PACKET__SEND;
4661 break;
4662 case PF_INET6:
4663 if (IP6CB(skb)->flags & IP6SKB_FORWARDED)
4664 secmark_perm = PACKET__FORWARD_OUT;
4665 else
4666 secmark_perm = PACKET__SEND;
4667 break;
4668 default:
4669 return NF_DROP;
4670 }
4671 if (secmark_perm == PACKET__FORWARD_OUT) {
4672 if (selinux_skb_peerlbl_sid(skb, family, &peer_sid))
4673 return NF_DROP;
4674 } else
4675 peer_sid = SECINITSID_KERNEL;
4676 } else {
4578 struct sk_security_struct *sksec = sk->sk_security; 4677 struct sk_security_struct *sksec = sk->sk_security;
4579 peer_sid = sksec->sid; 4678 peer_sid = sksec->sid;
4580 secmark_perm = PACKET__SEND; 4679 secmark_perm = PACKET__SEND;
4581 } else {
4582 if (selinux_skb_peerlbl_sid(skb, family, &peer_sid))
4583 return NF_DROP;
4584 secmark_perm = PACKET__FORWARD_OUT;
4585 } 4680 }
4586 4681
4682 AVC_AUDIT_DATA_INIT(&ad, NET);
4683 ad.u.net.netif = ifindex;
4684 ad.u.net.family = family;
4685 if (selinux_parse_skb(skb, &ad, &addrp, 0, NULL))
4686 return NF_DROP;
4687
4587 if (secmark_active) 4688 if (secmark_active)
4588 if (avc_has_perm(peer_sid, skb->secmark, 4689 if (avc_has_perm(peer_sid, skb->secmark,
4589 SECCLASS_PACKET, secmark_perm, &ad)) 4690 SECCLASS_PACKET, secmark_perm, &ad))
@@ -5657,6 +5758,13 @@ static struct nf_hook_ops selinux_ipv4_ops[] = {
5657 .pf = PF_INET, 5758 .pf = PF_INET,
5658 .hooknum = NF_INET_FORWARD, 5759 .hooknum = NF_INET_FORWARD,
5659 .priority = NF_IP_PRI_SELINUX_FIRST, 5760 .priority = NF_IP_PRI_SELINUX_FIRST,
5761 },
5762 {
5763 .hook = selinux_ipv4_output,
5764 .owner = THIS_MODULE,
5765 .pf = PF_INET,
5766 .hooknum = NF_INET_LOCAL_OUT,
5767 .priority = NF_IP_PRI_SELINUX_FIRST,
5660 } 5768 }
5661}; 5769};
5662 5770
diff --git a/security/selinux/include/netlabel.h b/security/selinux/include/netlabel.h
index 487a7d81fe20..b913c8d06038 100644
--- a/security/selinux/include/netlabel.h
+++ b/security/selinux/include/netlabel.h
@@ -39,6 +39,9 @@
39#ifdef CONFIG_NETLABEL 39#ifdef CONFIG_NETLABEL
40void selinux_netlbl_cache_invalidate(void); 40void selinux_netlbl_cache_invalidate(void);
41 41
42void selinux_netlbl_err(struct sk_buff *skb, int error, int gateway);
43
44void selinux_netlbl_sk_security_free(struct sk_security_struct *ssec);
42void selinux_netlbl_sk_security_reset(struct sk_security_struct *ssec, 45void selinux_netlbl_sk_security_reset(struct sk_security_struct *ssec,
43 int family); 46 int family);
44 47
@@ -46,8 +49,11 @@ int selinux_netlbl_skbuff_getsid(struct sk_buff *skb,
46 u16 family, 49 u16 family,
47 u32 *type, 50 u32 *type,
48 u32 *sid); 51 u32 *sid);
52int selinux_netlbl_skbuff_setsid(struct sk_buff *skb,
53 u16 family,
54 u32 sid);
49 55
50void selinux_netlbl_sock_graft(struct sock *sk, struct socket *sock); 56void selinux_netlbl_inet_conn_established(struct sock *sk, u16 family);
51int selinux_netlbl_socket_post_create(struct socket *sock); 57int selinux_netlbl_socket_post_create(struct socket *sock);
52int selinux_netlbl_inode_permission(struct inode *inode, int mask); 58int selinux_netlbl_inode_permission(struct inode *inode, int mask);
53int selinux_netlbl_sock_rcv_skb(struct sk_security_struct *sksec, 59int selinux_netlbl_sock_rcv_skb(struct sk_security_struct *sksec,
@@ -57,12 +63,27 @@ int selinux_netlbl_sock_rcv_skb(struct sk_security_struct *sksec,
57int selinux_netlbl_socket_setsockopt(struct socket *sock, 63int selinux_netlbl_socket_setsockopt(struct socket *sock,
58 int level, 64 int level,
59 int optname); 65 int optname);
66int selinux_netlbl_socket_connect(struct sock *sk, struct sockaddr *addr);
67
60#else 68#else
61static inline void selinux_netlbl_cache_invalidate(void) 69static inline void selinux_netlbl_cache_invalidate(void)
62{ 70{
63 return; 71 return;
64} 72}
65 73
74static inline void selinux_netlbl_err(struct sk_buff *skb,
75 int error,
76 int gateway)
77{
78 return;
79}
80
81static inline void selinux_netlbl_sk_security_free(
82 struct sk_security_struct *ssec)
83{
84 return;
85}
86
66static inline void selinux_netlbl_sk_security_reset( 87static inline void selinux_netlbl_sk_security_reset(
67 struct sk_security_struct *ssec, 88 struct sk_security_struct *ssec,
68 int family) 89 int family)
@@ -79,9 +100,21 @@ static inline int selinux_netlbl_skbuff_getsid(struct sk_buff *skb,
79 *sid = SECSID_NULL; 100 *sid = SECSID_NULL;
80 return 0; 101 return 0;
81} 102}
103static inline int selinux_netlbl_skbuff_setsid(struct sk_buff *skb,
104 u16 family,
105 u32 sid)
106{
107 return 0;
108}
82 109
83static inline void selinux_netlbl_sock_graft(struct sock *sk, 110static inline int selinux_netlbl_conn_setsid(struct sock *sk,
84 struct socket *sock) 111 struct sockaddr *addr)
112{
113 return 0;
114}
115
116static inline void selinux_netlbl_inet_conn_established(struct sock *sk,
117 u16 family)
85{ 118{
86 return; 119 return;
87} 120}
@@ -107,6 +140,11 @@ static inline int selinux_netlbl_socket_setsockopt(struct socket *sock,
107{ 140{
108 return 0; 141 return 0;
109} 142}
143static inline int selinux_netlbl_socket_connect(struct sock *sk,
144 struct sockaddr *addr)
145{
146 return 0;
147}
110#endif /* CONFIG_NETLABEL */ 148#endif /* CONFIG_NETLABEL */
111 149
112#endif 150#endif
diff --git a/security/selinux/include/objsec.h b/security/selinux/include/objsec.h
index 91070ab874ce..f8be8d7fa26d 100644
--- a/security/selinux/include/objsec.h
+++ b/security/selinux/include/objsec.h
@@ -109,16 +109,19 @@ struct netport_security_struct {
109}; 109};
110 110
111struct sk_security_struct { 111struct sk_security_struct {
112 u32 sid; /* SID of this object */
113 u32 peer_sid; /* SID of peer */
114 u16 sclass; /* sock security class */
115#ifdef CONFIG_NETLABEL 112#ifdef CONFIG_NETLABEL
116 enum { /* NetLabel state */ 113 enum { /* NetLabel state */
117 NLBL_UNSET = 0, 114 NLBL_UNSET = 0,
118 NLBL_REQUIRE, 115 NLBL_REQUIRE,
119 NLBL_LABELED, 116 NLBL_LABELED,
117 NLBL_REQSKB,
118 NLBL_CONNLABELED,
120 } nlbl_state; 119 } nlbl_state;
120 struct netlbl_lsm_secattr *nlbl_secattr; /* NetLabel sec attributes */
121#endif 121#endif
122 u32 sid; /* SID of this object */
123 u32 peer_sid; /* SID of peer */
124 u16 sclass; /* sock security class */
122}; 125};
123 126
124struct key_security_struct { 127struct key_security_struct {
diff --git a/security/selinux/netlabel.c b/security/selinux/netlabel.c
index 89b418392f11..f58701a7b728 100644
--- a/security/selinux/netlabel.c
+++ b/security/selinux/netlabel.c
@@ -9,7 +9,7 @@
9 */ 9 */
10 10
11/* 11/*
12 * (c) Copyright Hewlett-Packard Development Company, L.P., 2007 12 * (c) Copyright Hewlett-Packard Development Company, L.P., 2007, 2008
13 * 13 *
14 * This program is free software; you can redistribute it and/or modify 14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by 15 * it under the terms of the GNU General Public License as published by
@@ -29,8 +29,12 @@
29 29
30#include <linux/spinlock.h> 30#include <linux/spinlock.h>
31#include <linux/rcupdate.h> 31#include <linux/rcupdate.h>
32#include <linux/ip.h>
33#include <linux/ipv6.h>
32#include <net/sock.h> 34#include <net/sock.h>
33#include <net/netlabel.h> 35#include <net/netlabel.h>
36#include <net/ip.h>
37#include <net/ipv6.h>
34 38
35#include "objsec.h" 39#include "objsec.h"
36#include "security.h" 40#include "security.h"
@@ -64,32 +68,69 @@ static int selinux_netlbl_sidlookup_cached(struct sk_buff *skb,
64} 68}
65 69
66/** 70/**
71 * selinux_netlbl_sock_genattr - Generate the NetLabel socket secattr
72 * @sk: the socket
73 *
74 * Description:
75 * Generate the NetLabel security attributes for a socket, making full use of
76 * the socket's attribute cache. Returns a pointer to the security attributes
77 * on success, NULL on failure.
78 *
79 */
80static struct netlbl_lsm_secattr *selinux_netlbl_sock_genattr(struct sock *sk)
81{
82 int rc;
83 struct sk_security_struct *sksec = sk->sk_security;
84 struct netlbl_lsm_secattr *secattr;
85
86 if (sksec->nlbl_secattr != NULL)
87 return sksec->nlbl_secattr;
88
89 secattr = netlbl_secattr_alloc(GFP_ATOMIC);
90 if (secattr == NULL)
91 return NULL;
92 rc = security_netlbl_sid_to_secattr(sksec->sid, secattr);
93 if (rc != 0) {
94 netlbl_secattr_free(secattr);
95 return NULL;
96 }
97 sksec->nlbl_secattr = secattr;
98
99 return secattr;
100}
101
102/**
67 * selinux_netlbl_sock_setsid - Label a socket using the NetLabel mechanism 103 * selinux_netlbl_sock_setsid - Label a socket using the NetLabel mechanism
68 * @sk: the socket to label 104 * @sk: the socket to label
69 * @sid: the SID to use
70 * 105 *
71 * Description: 106 * Description:
72 * Attempt to label a socket using the NetLabel mechanism using the given 107 * Attempt to label a socket using the NetLabel mechanism. Returns zero values
73 * SID. Returns zero values on success, negative values on failure. 108 * on success, negative values on failure.
74 * 109 *
75 */ 110 */
76static int selinux_netlbl_sock_setsid(struct sock *sk, u32 sid) 111static int selinux_netlbl_sock_setsid(struct sock *sk)
77{ 112{
78 int rc; 113 int rc;
79 struct sk_security_struct *sksec = sk->sk_security; 114 struct sk_security_struct *sksec = sk->sk_security;
80 struct netlbl_lsm_secattr secattr; 115 struct netlbl_lsm_secattr *secattr;
81 116
82 netlbl_secattr_init(&secattr); 117 if (sksec->nlbl_state != NLBL_REQUIRE)
118 return 0;
83 119
84 rc = security_netlbl_sid_to_secattr(sid, &secattr); 120 secattr = selinux_netlbl_sock_genattr(sk);
85 if (rc != 0) 121 if (secattr == NULL)
86 goto sock_setsid_return; 122 return -ENOMEM;
87 rc = netlbl_sock_setattr(sk, &secattr); 123 rc = netlbl_sock_setattr(sk, secattr);
88 if (rc == 0) 124 switch (rc) {
125 case 0:
89 sksec->nlbl_state = NLBL_LABELED; 126 sksec->nlbl_state = NLBL_LABELED;
127 break;
128 case -EDESTADDRREQ:
129 sksec->nlbl_state = NLBL_REQSKB;
130 rc = 0;
131 break;
132 }
90 133
91sock_setsid_return:
92 netlbl_secattr_destroy(&secattr);
93 return rc; 134 return rc;
94} 135}
95 136
@@ -106,6 +147,38 @@ void selinux_netlbl_cache_invalidate(void)
106} 147}
107 148
108/** 149/**
150 * selinux_netlbl_err - Handle a NetLabel packet error
151 * @skb: the packet
152 * @error: the error code
153 * @gateway: true if host is acting as a gateway, false otherwise
154 *
155 * Description:
156 * When a packet is dropped due to a call to avc_has_perm() pass the error
157 * code to the NetLabel subsystem so any protocol specific processing can be
158 * done. This is safe to call even if you are unsure if NetLabel labeling is
159 * present on the packet, NetLabel is smart enough to only act when it should.
160 *
161 */
162void selinux_netlbl_err(struct sk_buff *skb, int error, int gateway)
163{
164 netlbl_skbuff_err(skb, error, gateway);
165}
166
167/**
168 * selinux_netlbl_sk_security_free - Free the NetLabel fields
169 * @sssec: the sk_security_struct
170 *
171 * Description:
172 * Free all of the memory in the NetLabel fields of a sk_security_struct.
173 *
174 */
175void selinux_netlbl_sk_security_free(struct sk_security_struct *ssec)
176{
177 if (ssec->nlbl_secattr != NULL)
178 netlbl_secattr_free(ssec->nlbl_secattr);
179}
180
181/**
109 * selinux_netlbl_sk_security_reset - Reset the NetLabel fields 182 * selinux_netlbl_sk_security_reset - Reset the NetLabel fields
110 * @ssec: the sk_security_struct 183 * @ssec: the sk_security_struct
111 * @family: the socket family 184 * @family: the socket family
@@ -163,35 +236,118 @@ int selinux_netlbl_skbuff_getsid(struct sk_buff *skb,
163} 236}
164 237
165/** 238/**
166 * selinux_netlbl_sock_graft - Netlabel the new socket 239 * selinux_netlbl_skbuff_setsid - Set the NetLabel on a packet given a sid
240 * @skb: the packet
241 * @family: protocol family
242 * @sid: the SID
243 *
244 * Description
245 * Call the NetLabel mechanism to set the label of a packet using @sid.
246 * Returns zero on auccess, negative values on failure.
247 *
248 */
249int selinux_netlbl_skbuff_setsid(struct sk_buff *skb,
250 u16 family,
251 u32 sid)
252{
253 int rc;
254 struct netlbl_lsm_secattr secattr_storage;
255 struct netlbl_lsm_secattr *secattr = NULL;
256 struct sock *sk;
257
258 /* if this is a locally generated packet check to see if it is already
259 * being labeled by it's parent socket, if it is just exit */
260 sk = skb->sk;
261 if (sk != NULL) {
262 struct sk_security_struct *sksec = sk->sk_security;
263 if (sksec->nlbl_state != NLBL_REQSKB)
264 return 0;
265 secattr = sksec->nlbl_secattr;
266 }
267 if (secattr == NULL) {
268 secattr = &secattr_storage;
269 netlbl_secattr_init(secattr);
270 rc = security_netlbl_sid_to_secattr(sid, secattr);
271 if (rc != 0)
272 goto skbuff_setsid_return;
273 }
274
275 rc = netlbl_skbuff_setattr(skb, family, secattr);
276
277skbuff_setsid_return:
278 if (secattr == &secattr_storage)
279 netlbl_secattr_destroy(secattr);
280 return rc;
281}
282
283/**
284 * selinux_netlbl_inet_conn_established - Netlabel the newly accepted connection
167 * @sk: the new connection 285 * @sk: the new connection
168 * @sock: the new socket
169 * 286 *
170 * Description: 287 * Description:
171 * The connection represented by @sk is being grafted onto @sock so set the 288 * A new connection has been established on @sk so make sure it is labeled
172 * socket's NetLabel to match the SID of @sk. 289 * correctly with the NetLabel susbsystem.
173 * 290 *
174 */ 291 */
175void selinux_netlbl_sock_graft(struct sock *sk, struct socket *sock) 292void selinux_netlbl_inet_conn_established(struct sock *sk, u16 family)
176{ 293{
294 int rc;
177 struct sk_security_struct *sksec = sk->sk_security; 295 struct sk_security_struct *sksec = sk->sk_security;
178 struct netlbl_lsm_secattr secattr; 296 struct netlbl_lsm_secattr *secattr;
179 u32 nlbl_peer_sid; 297 struct inet_sock *sk_inet = inet_sk(sk);
298 struct sockaddr_in addr;
180 299
181 if (sksec->nlbl_state != NLBL_REQUIRE) 300 if (sksec->nlbl_state != NLBL_REQUIRE)
182 return; 301 return;
183 302
184 netlbl_secattr_init(&secattr); 303 secattr = selinux_netlbl_sock_genattr(sk);
185 if (netlbl_sock_getattr(sk, &secattr) == 0 && 304 if (secattr == NULL)
186 secattr.flags != NETLBL_SECATTR_NONE && 305 return;
187 security_netlbl_secattr_to_sid(&secattr, &nlbl_peer_sid) == 0)
188 sksec->peer_sid = nlbl_peer_sid;
189 netlbl_secattr_destroy(&secattr);
190 306
191 /* Try to set the NetLabel on the socket to save time later, if we fail 307 rc = netlbl_sock_setattr(sk, secattr);
192 * here we will pick up the pieces in later calls to 308 switch (rc) {
193 * selinux_netlbl_inode_permission(). */ 309 case 0:
194 selinux_netlbl_sock_setsid(sk, sksec->sid); 310 sksec->nlbl_state = NLBL_LABELED;
311 break;
312 case -EDESTADDRREQ:
313 /* no PF_INET6 support yet because we don't support any IPv6
314 * labeling protocols */
315 if (family != PF_INET) {
316 sksec->nlbl_state = NLBL_UNSET;
317 return;
318 }
319
320 addr.sin_family = family;
321 addr.sin_addr.s_addr = sk_inet->daddr;
322 if (netlbl_conn_setattr(sk, (struct sockaddr *)&addr,
323 secattr) != 0) {
324 /* we failed to label the connected socket (could be
325 * for a variety of reasons, the actual "why" isn't
326 * important here) so we have to go to our backup plan,
327 * labeling the packets individually in the netfilter
328 * local output hook. this is okay but we need to
329 * adjust the MSS of the connection to take into
330 * account any labeling overhead, since we don't know
331 * the exact overhead at this point we'll use the worst
332 * case value which is 40 bytes for IPv4 */
333 struct inet_connection_sock *sk_conn = inet_csk(sk);
334 sk_conn->icsk_ext_hdr_len += 40 -
335 (sk_inet->opt ? sk_inet->opt->optlen : 0);
336 sk_conn->icsk_sync_mss(sk, sk_conn->icsk_pmtu_cookie);
337
338 sksec->nlbl_state = NLBL_REQSKB;
339 } else
340 sksec->nlbl_state = NLBL_CONNLABELED;
341 break;
342 default:
343 /* note that we are failing to label the socket which could be
344 * a bad thing since it means traffic could leave the system
345 * without the desired labeling, however, all is not lost as
346 * we have a check in selinux_netlbl_inode_permission() to
347 * pick up the pieces that we might drop here because we can't
348 * return an error code */
349 break;
350 }
195} 351}
196 352
197/** 353/**
@@ -205,13 +361,7 @@ void selinux_netlbl_sock_graft(struct sock *sk, struct socket *sock)
205 */ 361 */
206int selinux_netlbl_socket_post_create(struct socket *sock) 362int selinux_netlbl_socket_post_create(struct socket *sock)
207{ 363{
208 struct sock *sk = sock->sk; 364 return selinux_netlbl_sock_setsid(sock->sk);
209 struct sk_security_struct *sksec = sk->sk_security;
210
211 if (sksec->nlbl_state != NLBL_REQUIRE)
212 return 0;
213
214 return selinux_netlbl_sock_setsid(sk, sksec->sid);
215} 365}
216 366
217/** 367/**
@@ -246,7 +396,7 @@ int selinux_netlbl_inode_permission(struct inode *inode, int mask)
246 local_bh_disable(); 396 local_bh_disable();
247 bh_lock_sock_nested(sk); 397 bh_lock_sock_nested(sk);
248 if (likely(sksec->nlbl_state == NLBL_REQUIRE)) 398 if (likely(sksec->nlbl_state == NLBL_REQUIRE))
249 rc = selinux_netlbl_sock_setsid(sk, sksec->sid); 399 rc = selinux_netlbl_sock_setsid(sk);
250 else 400 else
251 rc = 0; 401 rc = 0;
252 bh_unlock_sock(sk); 402 bh_unlock_sock(sk);
@@ -307,7 +457,7 @@ int selinux_netlbl_sock_rcv_skb(struct sk_security_struct *sksec,
307 return 0; 457 return 0;
308 458
309 if (nlbl_sid != SECINITSID_UNLABELED) 459 if (nlbl_sid != SECINITSID_UNLABELED)
310 netlbl_skbuff_err(skb, rc); 460 netlbl_skbuff_err(skb, rc, 0);
311 return rc; 461 return rc;
312} 462}
313 463
@@ -334,7 +484,8 @@ int selinux_netlbl_socket_setsockopt(struct socket *sock,
334 struct netlbl_lsm_secattr secattr; 484 struct netlbl_lsm_secattr secattr;
335 485
336 if (level == IPPROTO_IP && optname == IP_OPTIONS && 486 if (level == IPPROTO_IP && optname == IP_OPTIONS &&
337 sksec->nlbl_state == NLBL_LABELED) { 487 (sksec->nlbl_state == NLBL_LABELED ||
488 sksec->nlbl_state == NLBL_CONNLABELED)) {
338 netlbl_secattr_init(&secattr); 489 netlbl_secattr_init(&secattr);
339 lock_sock(sk); 490 lock_sock(sk);
340 rc = netlbl_sock_getattr(sk, &secattr); 491 rc = netlbl_sock_getattr(sk, &secattr);
@@ -346,3 +497,50 @@ int selinux_netlbl_socket_setsockopt(struct socket *sock,
346 497
347 return rc; 498 return rc;
348} 499}
500
501/**
502 * selinux_netlbl_socket_connect - Label a client-side socket on connect
503 * @sk: the socket to label
504 * @addr: the destination address
505 *
506 * Description:
507 * Attempt to label a connected socket with NetLabel using the given address.
508 * Returns zero values on success, negative values on failure.
509 *
510 */
511int selinux_netlbl_socket_connect(struct sock *sk, struct sockaddr *addr)
512{
513 int rc;
514 struct sk_security_struct *sksec = sk->sk_security;
515 struct netlbl_lsm_secattr *secattr;
516
517 if (sksec->nlbl_state != NLBL_REQSKB &&
518 sksec->nlbl_state != NLBL_CONNLABELED)
519 return 0;
520
521 local_bh_disable();
522 bh_lock_sock_nested(sk);
523
524 /* connected sockets are allowed to disconnect when the address family
525 * is set to AF_UNSPEC, if that is what is happening we want to reset
526 * the socket */
527 if (addr->sa_family == AF_UNSPEC) {
528 netlbl_sock_delattr(sk);
529 sksec->nlbl_state = NLBL_REQSKB;
530 rc = 0;
531 goto socket_connect_return;
532 }
533 secattr = selinux_netlbl_sock_genattr(sk);
534 if (secattr == NULL) {
535 rc = -ENOMEM;
536 goto socket_connect_return;
537 }
538 rc = netlbl_conn_setattr(sk, addr, secattr);
539 if (rc == 0)
540 sksec->nlbl_state = NLBL_CONNLABELED;
541
542socket_connect_return:
543 bh_unlock_sock(sk);
544 local_bh_enable();
545 return rc;
546}
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index ab0cc0c7b944..343c8ab14af0 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -2955,7 +2955,7 @@ netlbl_secattr_to_sid_return_cleanup:
2955 */ 2955 */
2956int security_netlbl_sid_to_secattr(u32 sid, struct netlbl_lsm_secattr *secattr) 2956int security_netlbl_sid_to_secattr(u32 sid, struct netlbl_lsm_secattr *secattr)
2957{ 2957{
2958 int rc = -ENOENT; 2958 int rc;
2959 struct context *ctx; 2959 struct context *ctx;
2960 2960
2961 if (!ss_initialized) 2961 if (!ss_initialized)
@@ -2963,11 +2963,18 @@ int security_netlbl_sid_to_secattr(u32 sid, struct netlbl_lsm_secattr *secattr)
2963 2963
2964 read_lock(&policy_rwlock); 2964 read_lock(&policy_rwlock);
2965 ctx = sidtab_search(&sidtab, sid); 2965 ctx = sidtab_search(&sidtab, sid);
2966 if (ctx == NULL) 2966 if (ctx == NULL) {
2967 rc = -ENOENT;
2967 goto netlbl_sid_to_secattr_failure; 2968 goto netlbl_sid_to_secattr_failure;
2969 }
2968 secattr->domain = kstrdup(policydb.p_type_val_to_name[ctx->type - 1], 2970 secattr->domain = kstrdup(policydb.p_type_val_to_name[ctx->type - 1],
2969 GFP_ATOMIC); 2971 GFP_ATOMIC);
2970 secattr->flags |= NETLBL_SECATTR_DOMAIN_CPY; 2972 if (secattr->domain == NULL) {
2973 rc = -ENOMEM;
2974 goto netlbl_sid_to_secattr_failure;
2975 }
2976 secattr->attr.secid = sid;
2977 secattr->flags |= NETLBL_SECATTR_DOMAIN_CPY | NETLBL_SECATTR_SECID;
2971 mls_export_netlbl_lvl(ctx, secattr); 2978 mls_export_netlbl_lvl(ctx, secattr);
2972 rc = mls_export_netlbl_cat(ctx, secattr); 2979 rc = mls_export_netlbl_cat(ctx, secattr);
2973 if (rc != 0) 2980 if (rc != 0)
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index 87d75417ea93..6e2dc0bab70d 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -2179,7 +2179,10 @@ static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
2179 * This is the simplist possible security model 2179 * This is the simplist possible security model
2180 * for networking. 2180 * for networking.
2181 */ 2181 */
2182 return smk_access(smack, ssp->smk_in, MAY_WRITE); 2182 rc = smk_access(smack, ssp->smk_in, MAY_WRITE);
2183 if (rc != 0)
2184 netlbl_skbuff_err(skb, rc, 0);
2185 return rc;
2183} 2186}
2184 2187
2185/** 2188/**
diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c
index e7c642458ec9..c21d8c8bf0c7 100644
--- a/security/smack/smackfs.c
+++ b/security/smack/smackfs.c
@@ -354,9 +354,11 @@ static void smk_cipso_doi(void)
354 doip->tags[rc] = CIPSO_V4_TAG_INVALID; 354 doip->tags[rc] = CIPSO_V4_TAG_INVALID;
355 355
356 rc = netlbl_cfg_cipsov4_add_map(doip, NULL, &audit_info); 356 rc = netlbl_cfg_cipsov4_add_map(doip, NULL, &audit_info);
357 if (rc != 0) 357 if (rc != 0) {
358 printk(KERN_WARNING "%s:%d add rc = %d\n", 358 printk(KERN_WARNING "%s:%d add rc = %d\n",
359 __func__, __LINE__, rc); 359 __func__, __LINE__, rc);
360 kfree(doip);
361 }
360} 362}
361 363
362/** 364/**
diff --git a/sound/oss/ac97_codec.c b/sound/oss/ac97_codec.c
index b63839e8f9bd..456a1b4d7832 100644
--- a/sound/oss/ac97_codec.c
+++ b/sound/oss/ac97_codec.c
@@ -30,7 +30,7 @@
30 ************************************************************************** 30 **************************************************************************
31 * 31 *
32 * History 32 * History
33 * May 02, 2003 Liam Girdwood <liam.girdwood@wolfsonmicro.com> 33 * May 02, 2003 Liam Girdwood <lrg@slimlogic.co.uk>
34 * Removed non existant WM9700 34 * Removed non existant WM9700
35 * Added support for WM9705, WM9708, WM9709, WM9710, WM9711 35 * Added support for WM9705, WM9708, WM9709, WM9710, WM9711
36 * WM9712 and WM9717 36 * WM9712 and WM9717
diff --git a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c
index 6ce3cbe98a6a..6e831aff1bd0 100644
--- a/sound/pci/ac97/ac97_patch.c
+++ b/sound/pci/ac97/ac97_patch.c
@@ -476,7 +476,7 @@ static int patch_yamaha_ymf753(struct snd_ac97 * ac97)
476} 476}
477 477
478/* 478/*
479 * May 2, 2003 Liam Girdwood <liam.girdwood@wolfsonmicro.com> 479 * May 2, 2003 Liam Girdwood <lrg@slimlogic.co.uk>
480 * removed broken wolfson00 patch. 480 * removed broken wolfson00 patch.
481 * added support for WM9705,WM9708,WM9709,WM9710,WM9711,WM9712 and WM9717. 481 * added support for WM9705,WM9708,WM9709,WM9710,WM9711,WM9712 and WM9717.
482 */ 482 */
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index c461baa83c2a..c59065513118 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -322,8 +322,8 @@ static hda_nid_t stac92hd71bxx_mux_nids[2] = {
322 0x1a, 0x1b 322 0x1a, 0x1b
323}; 323};
324 324
325static hda_nid_t stac92hd71bxx_dmux_nids[1] = { 325static hda_nid_t stac92hd71bxx_dmux_nids[2] = {
326 0x1c, 326 0x1c, 0x1d,
327}; 327};
328 328
329static hda_nid_t stac92hd71bxx_smux_nids[2] = { 329static hda_nid_t stac92hd71bxx_smux_nids[2] = {
@@ -861,20 +861,18 @@ static struct hda_verb stac92hd71bxx_core_init[] = {
861 { 0x28, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, 861 { 0x28, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
862 /* connect headphone jack to dac1 */ 862 /* connect headphone jack to dac1 */
863 { 0x0a, AC_VERB_SET_CONNECT_SEL, 0x01}, 863 { 0x0a, AC_VERB_SET_CONNECT_SEL, 0x01},
864 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Speaker */
865 /* unmute right and left channels for nodes 0x0a, 0xd, 0x0f */ 864 /* unmute right and left channels for nodes 0x0a, 0xd, 0x0f */
866 { 0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 865 { 0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
867 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 866 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
868 { 0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 867 { 0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
869}; 868};
870 869
871#define HD_DISABLE_PORTF 3 870#define HD_DISABLE_PORTF 2
872static struct hda_verb stac92hd71bxx_analog_core_init[] = { 871static struct hda_verb stac92hd71bxx_analog_core_init[] = {
873 /* start of config #1 */ 872 /* start of config #1 */
874 873
875 /* connect port 0f to audio mixer */ 874 /* connect port 0f to audio mixer */
876 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x2}, 875 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x2},
877 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Speaker */
878 /* unmute right and left channels for node 0x0f */ 876 /* unmute right and left channels for node 0x0f */
879 { 0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 877 { 0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
880 /* start of config #2 */ 878 /* start of config #2 */
@@ -883,10 +881,6 @@ static struct hda_verb stac92hd71bxx_analog_core_init[] = {
883 { 0x28, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, 881 { 0x28, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
884 /* connect headphone jack to dac1 */ 882 /* connect headphone jack to dac1 */
885 { 0x0a, AC_VERB_SET_CONNECT_SEL, 0x01}, 883 { 0x0a, AC_VERB_SET_CONNECT_SEL, 0x01},
886 /* connect port 0d to audio mixer */
887 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x2},
888 /* unmute dac0 input in audio mixer */
889 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f},
890 /* unmute right and left channels for nodes 0x0a, 0xd */ 884 /* unmute right and left channels for nodes 0x0a, 0xd */
891 { 0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 885 { 0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
892 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 886 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
@@ -1107,6 +1101,7 @@ static struct snd_kcontrol_new stac92hd83xxx_mixer[] = {
1107 1101
1108static struct snd_kcontrol_new stac92hd71bxx_analog_mixer[] = { 1102static struct snd_kcontrol_new stac92hd71bxx_analog_mixer[] = {
1109 STAC_INPUT_SOURCE(2), 1103 STAC_INPUT_SOURCE(2),
1104 STAC_ANALOG_LOOPBACK(0xFA0, 0x7A0, 2),
1110 1105
1111 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x1c, 0x0, HDA_OUTPUT), 1106 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x1c, 0x0, HDA_OUTPUT),
1112 HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1c, 0x0, HDA_OUTPUT), 1107 HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1c, 0x0, HDA_OUTPUT),
@@ -1119,8 +1114,17 @@ static struct snd_kcontrol_new stac92hd71bxx_analog_mixer[] = {
1119 HDA_CODEC_MUTE("PC Beep Switch", 0x17, 0x2, HDA_INPUT), 1114 HDA_CODEC_MUTE("PC Beep Switch", 0x17, 0x2, HDA_INPUT),
1120 */ 1115 */
1121 1116
1122 HDA_CODEC_MUTE("Analog Loopback 1", 0x17, 0x3, HDA_INPUT), 1117 HDA_CODEC_MUTE("Import0 Mux Capture Switch", 0x17, 0x0, HDA_INPUT),
1123 HDA_CODEC_MUTE("Analog Loopback 2", 0x17, 0x4, HDA_INPUT), 1118 HDA_CODEC_VOLUME("Import0 Mux Capture Volume", 0x17, 0x0, HDA_INPUT),
1119
1120 HDA_CODEC_MUTE("Import1 Mux Capture Switch", 0x17, 0x1, HDA_INPUT),
1121 HDA_CODEC_VOLUME("Import1 Mux Capture Volume", 0x17, 0x1, HDA_INPUT),
1122
1123 HDA_CODEC_MUTE("DAC0 Capture Switch", 0x17, 0x3, HDA_INPUT),
1124 HDA_CODEC_VOLUME("DAC0 Capture Volume", 0x17, 0x3, HDA_INPUT),
1125
1126 HDA_CODEC_MUTE("DAC1 Capture Switch", 0x17, 0x4, HDA_INPUT),
1127 HDA_CODEC_VOLUME("DAC1 Capture Volume", 0x17, 0x4, HDA_INPUT),
1124 { } /* end */ 1128 { } /* end */
1125}; 1129};
1126 1130
@@ -1649,7 +1653,7 @@ static struct snd_pci_quirk stac92hd83xxx_cfg_tbl[] = {
1649 1653
1650static unsigned int ref92hd71bxx_pin_configs[11] = { 1654static unsigned int ref92hd71bxx_pin_configs[11] = {
1651 0x02214030, 0x02a19040, 0x01a19020, 0x01014010, 1655 0x02214030, 0x02a19040, 0x01a19020, 0x01014010,
1652 0x0181302e, 0x01114010, 0x01019020, 0x90a000f0, 1656 0x0181302e, 0x01014010, 0x01019020, 0x90a000f0,
1653 0x90a000f0, 0x01452050, 0x01452050, 1657 0x90a000f0, 0x01452050, 0x01452050,
1654}; 1658};
1655 1659
@@ -3000,7 +3004,7 @@ static int stac92xx_auto_create_mono_output_ctls(struct hda_codec *codec)
3000 3004
3001/* labels for amp mux outputs */ 3005/* labels for amp mux outputs */
3002static const char *stac92xx_amp_labels[3] = { 3006static const char *stac92xx_amp_labels[3] = {
3003 "Front Microphone", "Microphone", "Line In" 3007 "Front Microphone", "Microphone", "Line In",
3004}; 3008};
3005 3009
3006/* create amp out controls mux on capable codecs */ 3010/* create amp out controls mux on capable codecs */
@@ -4327,6 +4331,16 @@ static struct hda_codec_ops stac92hd71bxx_patch_ops = {
4327#endif 4331#endif
4328}; 4332};
4329 4333
4334static struct hda_input_mux stac92hd71bxx_dmux = {
4335 .num_items = 4,
4336 .items = {
4337 { "Analog Inputs", 0x00 },
4338 { "Mixer", 0x01 },
4339 { "Digital Mic 1", 0x02 },
4340 { "Digital Mic 2", 0x03 },
4341 }
4342};
4343
4330static int patch_stac92hd71bxx(struct hda_codec *codec) 4344static int patch_stac92hd71bxx(struct hda_codec *codec)
4331{ 4345{
4332 struct sigmatel_spec *spec; 4346 struct sigmatel_spec *spec;
@@ -4341,6 +4355,8 @@ static int patch_stac92hd71bxx(struct hda_codec *codec)
4341 spec->num_pins = ARRAY_SIZE(stac92hd71bxx_pin_nids); 4355 spec->num_pins = ARRAY_SIZE(stac92hd71bxx_pin_nids);
4342 spec->num_pwrs = ARRAY_SIZE(stac92hd71bxx_pwr_nids); 4356 spec->num_pwrs = ARRAY_SIZE(stac92hd71bxx_pwr_nids);
4343 spec->pin_nids = stac92hd71bxx_pin_nids; 4357 spec->pin_nids = stac92hd71bxx_pin_nids;
4358 memcpy(&spec->private_dimux, &stac92hd71bxx_dmux,
4359 sizeof(stac92hd71bxx_dmux));
4344 spec->board_config = snd_hda_check_board_config(codec, 4360 spec->board_config = snd_hda_check_board_config(codec,
4345 STAC_92HD71BXX_MODELS, 4361 STAC_92HD71BXX_MODELS,
4346 stac92hd71bxx_models, 4362 stac92hd71bxx_models,
@@ -4392,6 +4408,7 @@ again:
4392 /* no output amps */ 4408 /* no output amps */
4393 spec->num_pwrs = 0; 4409 spec->num_pwrs = 0;
4394 spec->mixer = stac92hd71bxx_analog_mixer; 4410 spec->mixer = stac92hd71bxx_analog_mixer;
4411 spec->dinput_mux = &spec->private_dimux;
4395 4412
4396 /* disable VSW */ 4413 /* disable VSW */
4397 spec->init = &stac92hd71bxx_analog_core_init[HD_DISABLE_PORTF]; 4414 spec->init = &stac92hd71bxx_analog_core_init[HD_DISABLE_PORTF];
@@ -4409,12 +4426,13 @@ again:
4409 spec->num_pwrs = 0; 4426 spec->num_pwrs = 0;
4410 /* fallthru */ 4427 /* fallthru */
4411 default: 4428 default:
4429 spec->dinput_mux = &spec->private_dimux;
4412 spec->mixer = stac92hd71bxx_analog_mixer; 4430 spec->mixer = stac92hd71bxx_analog_mixer;
4413 spec->init = stac92hd71bxx_analog_core_init; 4431 spec->init = stac92hd71bxx_analog_core_init;
4414 codec->slave_dig_outs = stac92hd71bxx_slave_dig_outs; 4432 codec->slave_dig_outs = stac92hd71bxx_slave_dig_outs;
4415 } 4433 }
4416 4434
4417 spec->aloopback_mask = 0x20; 4435 spec->aloopback_mask = 0x50;
4418 spec->aloopback_shift = 0; 4436 spec->aloopback_shift = 0;
4419 4437
4420 if (spec->board_config > STAC_92HD71BXX_REF) { 4438 if (spec->board_config > STAC_92HD71BXX_REF) {
@@ -4456,6 +4474,10 @@ again:
4456 spec->multiout.num_dacs = 1; 4474 spec->multiout.num_dacs = 1;
4457 spec->multiout.hp_nid = 0x11; 4475 spec->multiout.hp_nid = 0x11;
4458 spec->multiout.dac_nids = stac92hd71bxx_dac_nids; 4476 spec->multiout.dac_nids = stac92hd71bxx_dac_nids;
4477 if (spec->dinput_mux)
4478 spec->private_dimux.num_items +=
4479 spec->num_dmics -
4480 (ARRAY_SIZE(stac92hd71bxx_dmic_nids) - 1);
4459 4481
4460 err = stac92xx_parse_auto_config(codec, 0x21, 0x23); 4482 err = stac92xx_parse_auto_config(codec, 0x21, 0x23);
4461 if (!err) { 4483 if (!err) {
diff --git a/sound/soc/at91/Kconfig b/sound/soc/at91/Kconfig
index 905186502e00..85a883299c2e 100644
--- a/sound/soc/at91/Kconfig
+++ b/sound/soc/at91/Kconfig
@@ -8,20 +8,3 @@ config SND_AT91_SOC
8 8
9config SND_AT91_SOC_SSC 9config SND_AT91_SOC_SSC
10 tristate 10 tristate
11
12config SND_AT91_SOC_ETI_B1_WM8731
13 tristate "SoC Audio support for WM8731-based Endrelia ETI-B1 boards"
14 depends on SND_AT91_SOC && (MACH_ETI_B1 || MACH_ETI_C1)
15 select SND_AT91_SOC_SSC
16 select SND_SOC_WM8731
17 help
18 Say Y if you want to add support for SoC audio on WM8731-based
19 Endrelia Technologies Inc ETI-B1 or ETI-C1 boards.
20
21config SND_AT91_SOC_ETI_SLAVE
22 bool "Run codec in slave Mode on Endrelia boards"
23 depends on SND_AT91_SOC_ETI_B1_WM8731
24 default n
25 help
26 Say Y if you want to run with the AT91 SSC generating the BCLK
27 and LRC signals on Endrelia boards.
diff --git a/sound/soc/at91/Makefile b/sound/soc/at91/Makefile
index f23da17cc328..b817f11df286 100644
--- a/sound/soc/at91/Makefile
+++ b/sound/soc/at91/Makefile
@@ -4,8 +4,3 @@ snd-soc-at91-ssc-objs := at91-ssc.o
4 4
5obj-$(CONFIG_SND_AT91_SOC) += snd-soc-at91.o 5obj-$(CONFIG_SND_AT91_SOC) += snd-soc-at91.o
6obj-$(CONFIG_SND_AT91_SOC_SSC) += snd-soc-at91-ssc.o 6obj-$(CONFIG_SND_AT91_SOC_SSC) += snd-soc-at91-ssc.o
7
8# AT91 Machine Support
9snd-soc-eti-b1-wm8731-objs := eti_b1_wm8731.o
10
11obj-$(CONFIG_SND_AT91_SOC_ETI_B1_WM8731) += snd-soc-eti-b1-wm8731.o
diff --git a/sound/soc/at91/at91-ssc.c b/sound/soc/at91/at91-ssc.c
index a5b1a79ebffb..1b61cc461261 100644
--- a/sound/soc/at91/at91-ssc.c
+++ b/sound/soc/at91/at91-ssc.c
@@ -5,7 +5,7 @@
5 * Endrelia Technologies Inc. 5 * Endrelia Technologies Inc.
6 * 6 *
7 * Based on pxa2xx Platform drivers by 7 * Based on pxa2xx Platform drivers by
8 * Liam Girdwood <liam.girdwood@wolfsonmicro.com> 8 * Liam Girdwood <lrg@slimlogic.co.uk>
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify it 10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the 11 * under the terms of the GNU General Public License as published by the
diff --git a/sound/soc/at91/eti_b1_wm8731.c b/sound/soc/at91/eti_b1_wm8731.c
deleted file mode 100644
index 684781e4088b..000000000000
--- a/sound/soc/at91/eti_b1_wm8731.c
+++ /dev/null
@@ -1,349 +0,0 @@
1/*
2 * eti_b1_wm8731 -- SoC audio for AT91RM9200-based Endrelia ETI_B1 board.
3 *
4 * Author: Frank Mandarino <fmandarino@endrelia.com>
5 * Endrelia Technologies Inc.
6 * Created: Mar 29, 2006
7 *
8 * Based on corgi.c by:
9 *
10 * Copyright 2005 Wolfson Microelectronics PLC.
11 * Copyright 2005 Openedhand Ltd.
12 *
13 * Authors: Liam Girdwood <liam.girdwood@wolfsonmicro.com>
14 * Richard Purdie <richard@openedhand.com>
15 *
16 * This program is free software; you can redistribute it and/or modify it
17 * under the terms of the GNU General Public License as published by the
18 * Free Software Foundation; either version 2 of the License, or (at your
19 * option) any later version.
20 *
21 */
22
23#include <linux/module.h>
24#include <linux/moduleparam.h>
25#include <linux/kernel.h>
26#include <linux/clk.h>
27#include <linux/timer.h>
28#include <linux/interrupt.h>
29#include <linux/platform_device.h>
30#include <sound/core.h>
31#include <sound/pcm.h>
32#include <sound/soc.h>
33#include <sound/soc-dapm.h>
34
35#include <mach/hardware.h>
36#include <mach/gpio.h>
37
38#include "../codecs/wm8731.h"
39#include "at91-pcm.h"
40#include "at91-ssc.h"
41
42#if 0
43#define DBG(x...) printk(KERN_INFO "eti_b1_wm8731: " x)
44#else
45#define DBG(x...)
46#endif
47
48static struct clk *pck1_clk;
49static struct clk *pllb_clk;
50
51
52static int eti_b1_startup(struct snd_pcm_substream *substream)
53{
54 struct snd_soc_pcm_runtime *rtd = substream->private_data;
55 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
56 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
57 int ret;
58
59 /* cpu clock is the AT91 master clock sent to the SSC */
60 ret = snd_soc_dai_set_sysclk(cpu_dai, AT91_SYSCLK_MCK,
61 60000000, SND_SOC_CLOCK_IN);
62 if (ret < 0)
63 return ret;
64
65 /* codec system clock is supplied by PCK1, set to 12MHz */
66 ret = snd_soc_dai_set_sysclk(codec_dai, WM8731_SYSCLK,
67 12000000, SND_SOC_CLOCK_IN);
68 if (ret < 0)
69 return ret;
70
71 /* Start PCK1 clock. */
72 clk_enable(pck1_clk);
73 DBG("pck1 started\n");
74
75 return 0;
76}
77
78static void eti_b1_shutdown(struct snd_pcm_substream *substream)
79{
80 /* Stop PCK1 clock. */
81 clk_disable(pck1_clk);
82 DBG("pck1 stopped\n");
83}
84
85static int eti_b1_hw_params(struct snd_pcm_substream *substream,
86 struct snd_pcm_hw_params *params)
87{
88 struct snd_soc_pcm_runtime *rtd = substream->private_data;
89 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
90 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
91 int ret;
92
93#ifdef CONFIG_SND_AT91_SOC_ETI_SLAVE
94 unsigned int rate;
95 int cmr_div, period;
96
97 /* set codec DAI configuration */
98 ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
99 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
100 if (ret < 0)
101 return ret;
102
103 /* set cpu DAI configuration */
104 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
105 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
106 if (ret < 0)
107 return ret;
108
109 /*
110 * The SSC clock dividers depend on the sample rate. The CMR.DIV
111 * field divides the system master clock MCK to drive the SSC TK
112 * signal which provides the codec BCLK. The TCMR.PERIOD and
113 * RCMR.PERIOD fields further divide the BCLK signal to drive
114 * the SSC TF and RF signals which provide the codec DACLRC and
115 * ADCLRC clocks.
116 *
117 * The dividers were determined through trial and error, where a
118 * CMR.DIV value is chosen such that the resulting BCLK value is
119 * divisible, or almost divisible, by (2 * sample rate), and then
120 * the TCMR.PERIOD or RCMR.PERIOD is BCLK / (2 * sample rate) - 1.
121 */
122 rate = params_rate(params);
123
124 switch (rate) {
125 case 8000:
126 cmr_div = 25; /* BCLK = 60MHz/(2*25) = 1.2MHz */
127 period = 74; /* LRC = BCLK/(2*(74+1)) = 8000Hz */
128 break;
129 case 32000:
130 cmr_div = 7; /* BCLK = 60MHz/(2*7) ~= 4.28571428MHz */
131 period = 66; /* LRC = BCLK/(2*(66+1)) = 31982.942Hz */
132 break;
133 case 48000:
134 cmr_div = 13; /* BCLK = 60MHz/(2*13) ~= 2.3076923MHz */
135 period = 23; /* LRC = BCLK/(2*(23+1)) = 48076.923Hz */
136 break;
137 default:
138 printk(KERN_WARNING "unsupported rate %d on ETI-B1 board\n", rate);
139 return -EINVAL;
140 }
141
142 /* set the MCK divider for BCLK */
143 ret = snd_soc_dai_set_clkdiv(cpu_dai, AT91SSC_CMR_DIV, cmr_div);
144 if (ret < 0)
145 return ret;
146
147 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
148 /* set the BCLK divider for DACLRC */
149 ret = snd_soc_dai_set_clkdiv(cpu_dai,
150 AT91SSC_TCMR_PERIOD, period);
151 } else {
152 /* set the BCLK divider for ADCLRC */
153 ret = snd_soc_dai_set_clkdiv(cpu_dai,
154 AT91SSC_RCMR_PERIOD, period);
155 }
156 if (ret < 0)
157 return ret;
158
159#else /* CONFIG_SND_AT91_SOC_ETI_SLAVE */
160 /*
161 * Codec in Master Mode.
162 */
163
164 /* set codec DAI configuration */
165 ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
166 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
167 if (ret < 0)
168 return ret;
169
170 /* set cpu DAI configuration */
171 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
172 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
173 if (ret < 0)
174 return ret;
175
176#endif /* CONFIG_SND_AT91_SOC_ETI_SLAVE */
177
178 return 0;
179}
180
181static struct snd_soc_ops eti_b1_ops = {
182 .startup = eti_b1_startup,
183 .hw_params = eti_b1_hw_params,
184 .shutdown = eti_b1_shutdown,
185};
186
187
188static const struct snd_soc_dapm_widget eti_b1_dapm_widgets[] = {
189 SND_SOC_DAPM_MIC("Int Mic", NULL),
190 SND_SOC_DAPM_SPK("Ext Spk", NULL),
191};
192
193static const struct snd_soc_dapm_route intercon[] = {
194
195 /* speaker connected to LHPOUT */
196 {"Ext Spk", NULL, "LHPOUT"},
197
198 /* mic is connected to Mic Jack, with WM8731 Mic Bias */
199 {"MICIN", NULL, "Mic Bias"},
200 {"Mic Bias", NULL, "Int Mic"},
201};
202
203/*
204 * Logic for a wm8731 as connected on a Endrelia ETI-B1 board.
205 */
206static int eti_b1_wm8731_init(struct snd_soc_codec *codec)
207{
208 DBG("eti_b1_wm8731_init() called\n");
209
210 /* Add specific widgets */
211 snd_soc_dapm_new_controls(codec, eti_b1_dapm_widgets,
212 ARRAY_SIZE(eti_b1_dapm_widgets));
213
214 /* Set up specific audio path interconnects */
215 snd_soc_dapm_add_route(codec, intercon, ARRAY_SIZE(intercon));
216
217 /* not connected */
218 snd_soc_dapm_disable_pin(codec, "RLINEIN");
219 snd_soc_dapm_disable_pin(codec, "LLINEIN");
220
221 /* always connected */
222 snd_soc_dapm_enable_pin(codec, "Int Mic");
223 snd_soc_dapm_enable_pin(codec, "Ext Spk");
224
225 snd_soc_dapm_sync(codec);
226
227 return 0;
228}
229
230static struct snd_soc_dai_link eti_b1_dai = {
231 .name = "WM8731",
232 .stream_name = "WM8731 PCM",
233 .cpu_dai = &at91_ssc_dai[1],
234 .codec_dai = &wm8731_dai,
235 .init = eti_b1_wm8731_init,
236 .ops = &eti_b1_ops,
237};
238
239static struct snd_soc_machine snd_soc_machine_eti_b1 = {
240 .name = "ETI_B1_WM8731",
241 .dai_link = &eti_b1_dai,
242 .num_links = 1,
243};
244
245static struct wm8731_setup_data eti_b1_wm8731_setup = {
246 .i2c_bus = 0,
247 .i2c_address = 0x1a,
248};
249
250static struct snd_soc_device eti_b1_snd_devdata = {
251 .machine = &snd_soc_machine_eti_b1,
252 .platform = &at91_soc_platform,
253 .codec_dev = &soc_codec_dev_wm8731,
254 .codec_data = &eti_b1_wm8731_setup,
255};
256
257static struct platform_device *eti_b1_snd_device;
258
259static int __init eti_b1_init(void)
260{
261 int ret;
262 struct at91_ssc_periph *ssc = eti_b1_dai.cpu_dai->private_data;
263
264 if (!request_mem_region(AT91RM9200_BASE_SSC1, SZ_16K, "soc-audio")) {
265 DBG("SSC1 memory region is busy\n");
266 return -EBUSY;
267 }
268
269 ssc->base = ioremap(AT91RM9200_BASE_SSC1, SZ_16K);
270 if (!ssc->base) {
271 DBG("SSC1 memory ioremap failed\n");
272 ret = -ENOMEM;
273 goto fail_release_mem;
274 }
275
276 ssc->pid = AT91RM9200_ID_SSC1;
277
278 eti_b1_snd_device = platform_device_alloc("soc-audio", -1);
279 if (!eti_b1_snd_device) {
280 DBG("platform device allocation failed\n");
281 ret = -ENOMEM;
282 goto fail_io_unmap;
283 }
284
285 platform_set_drvdata(eti_b1_snd_device, &eti_b1_snd_devdata);
286 eti_b1_snd_devdata.dev = &eti_b1_snd_device->dev;
287
288 ret = platform_device_add(eti_b1_snd_device);
289 if (ret) {
290 DBG("platform device add failed\n");
291 platform_device_put(eti_b1_snd_device);
292 goto fail_io_unmap;
293 }
294
295 at91_set_A_periph(AT91_PIN_PB6, 0); /* TF1 */
296 at91_set_A_periph(AT91_PIN_PB7, 0); /* TK1 */
297 at91_set_A_periph(AT91_PIN_PB8, 0); /* TD1 */
298 at91_set_A_periph(AT91_PIN_PB9, 0); /* RD1 */
299/* at91_set_A_periph(AT91_PIN_PB10, 0);*/ /* RK1 */
300 at91_set_A_periph(AT91_PIN_PB11, 0); /* RF1 */
301
302 /*
303 * Set PCK1 parent to PLLB and its rate to 12 Mhz.
304 */
305 pllb_clk = clk_get(NULL, "pllb");
306 pck1_clk = clk_get(NULL, "pck1");
307
308 clk_set_parent(pck1_clk, pllb_clk);
309 clk_set_rate(pck1_clk, 12000000);
310
311 DBG("MCLK rate %luHz\n", clk_get_rate(pck1_clk));
312
313 /* assign the GPIO pin to PCK1 */
314 at91_set_B_periph(AT91_PIN_PA24, 0);
315
316#ifdef CONFIG_SND_AT91_SOC_ETI_SLAVE
317 printk(KERN_INFO "eti_b1_wm8731: Codec in Slave Mode\n");
318#else
319 printk(KERN_INFO "eti_b1_wm8731: Codec in Master Mode\n");
320#endif
321 return ret;
322
323fail_io_unmap:
324 iounmap(ssc->base);
325fail_release_mem:
326 release_mem_region(AT91RM9200_BASE_SSC1, SZ_16K);
327 return ret;
328}
329
330static void __exit eti_b1_exit(void)
331{
332 struct at91_ssc_periph *ssc = eti_b1_dai.cpu_dai->private_data;
333
334 clk_put(pck1_clk);
335 clk_put(pllb_clk);
336
337 platform_device_unregister(eti_b1_snd_device);
338
339 iounmap(ssc->base);
340 release_mem_region(AT91RM9200_BASE_SSC1, SZ_16K);
341}
342
343module_init(eti_b1_init);
344module_exit(eti_b1_exit);
345
346/* Module information */
347MODULE_AUTHOR("Frank Mandarino <fmandarino@endrelia.com>");
348MODULE_DESCRIPTION("ALSA SoC ETI-B1-WM8731");
349MODULE_LICENSE("GPL");
diff --git a/sound/soc/blackfin/Kconfig b/sound/soc/blackfin/Kconfig
index f98331d099e7..dc006206f622 100644
--- a/sound/soc/blackfin/Kconfig
+++ b/sound/soc/blackfin/Kconfig
@@ -17,6 +17,22 @@ config SND_BF5XX_SOC_SSM2602
17 help 17 help
18 Say Y if you want to add support for SoC audio on BF527-EZKIT. 18 Say Y if you want to add support for SoC audio on BF527-EZKIT.
19 19
20config SND_BF5XX_SOC_AD73311
21 tristate "SoC AD73311 Audio support for Blackfin"
22 depends on SND_BF5XX_I2S
23 select SND_BF5XX_SOC_I2S
24 select SND_SOC_AD73311
25 help
26 Say Y if you want to add support for AD73311 codec on Blackfin.
27
28config SND_BFIN_AD73311_SE
29 int "PF pin for AD73311L Chip Select"
30 depends on SND_BF5XX_SOC_AD73311
31 default 4
32 help
33 Enter the GPIO used to control AD73311's SE pin. Acceptable
34 values are 0 to 7
35
20config SND_BF5XX_AC97 36config SND_BF5XX_AC97
21 tristate "SoC AC97 Audio for the ADI BF5xx chip" 37 tristate "SoC AC97 Audio for the ADI BF5xx chip"
22 depends on BLACKFIN && SND_SOC 38 depends on BLACKFIN && SND_SOC
diff --git a/sound/soc/blackfin/Makefile b/sound/soc/blackfin/Makefile
index 9ea8bd9e0ba3..97bb37a6359c 100644
--- a/sound/soc/blackfin/Makefile
+++ b/sound/soc/blackfin/Makefile
@@ -14,7 +14,8 @@ obj-$(CONFIG_SND_BF5XX_SOC_I2S) += snd-soc-bf5xx-i2s.o
14# Blackfin Machine Support 14# Blackfin Machine Support
15snd-ad1980-objs := bf5xx-ad1980.o 15snd-ad1980-objs := bf5xx-ad1980.o
16snd-ssm2602-objs := bf5xx-ssm2602.o 16snd-ssm2602-objs := bf5xx-ssm2602.o
17 17snd-ad73311-objs := bf5xx-ad73311.o
18 18
19obj-$(CONFIG_SND_BF5XX_SOC_AD1980) += snd-ad1980.o 19obj-$(CONFIG_SND_BF5XX_SOC_AD1980) += snd-ad1980.o
20obj-$(CONFIG_SND_BF5XX_SOC_SSM2602) += snd-ssm2602.o 20obj-$(CONFIG_SND_BF5XX_SOC_SSM2602) += snd-ssm2602.o
21obj-$(CONFIG_SND_BF5XX_SOC_AD73311) += snd-ad73311.o
diff --git a/sound/soc/blackfin/bf5xx-ac97-pcm.c b/sound/soc/blackfin/bf5xx-ac97-pcm.c
index 51f4907c4831..25e50d2ea1ec 100644
--- a/sound/soc/blackfin/bf5xx-ac97-pcm.c
+++ b/sound/soc/blackfin/bf5xx-ac97-pcm.c
@@ -56,6 +56,7 @@ static void bf5xx_mmap_copy(struct snd_pcm_substream *substream,
56 sport->tx_pos += runtime->period_size; 56 sport->tx_pos += runtime->period_size;
57 if (sport->tx_pos >= runtime->buffer_size) 57 if (sport->tx_pos >= runtime->buffer_size)
58 sport->tx_pos %= runtime->buffer_size; 58 sport->tx_pos %= runtime->buffer_size;
59 sport->tx_delay_pos = sport->tx_pos;
59 } else { 60 } else {
60 bf5xx_ac97_to_pcm( 61 bf5xx_ac97_to_pcm(
61 (struct ac97_frame *)sport->rx_dma_buf + sport->rx_pos, 62 (struct ac97_frame *)sport->rx_dma_buf + sport->rx_pos,
@@ -72,7 +73,15 @@ static void bf5xx_dma_irq(void *data)
72 struct snd_pcm_substream *pcm = data; 73 struct snd_pcm_substream *pcm = data;
73#if defined(CONFIG_SND_MMAP_SUPPORT) 74#if defined(CONFIG_SND_MMAP_SUPPORT)
74 struct snd_pcm_runtime *runtime = pcm->runtime; 75 struct snd_pcm_runtime *runtime = pcm->runtime;
76 struct sport_device *sport = runtime->private_data;
75 bf5xx_mmap_copy(pcm, runtime->period_size); 77 bf5xx_mmap_copy(pcm, runtime->period_size);
78 if (pcm->stream == SNDRV_PCM_STREAM_PLAYBACK) {
79 if (sport->once == 0) {
80 snd_pcm_period_elapsed(pcm);
81 bf5xx_mmap_copy(pcm, runtime->period_size);
82 sport->once = 1;
83 }
84 }
76#endif 85#endif
77 snd_pcm_period_elapsed(pcm); 86 snd_pcm_period_elapsed(pcm);
78} 87}
@@ -114,6 +123,10 @@ static int bf5xx_pcm_hw_params(struct snd_pcm_substream *substream,
114 123
115static int bf5xx_pcm_hw_free(struct snd_pcm_substream *substream) 124static int bf5xx_pcm_hw_free(struct snd_pcm_substream *substream)
116{ 125{
126 struct snd_pcm_runtime *runtime = substream->runtime;
127
128 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
129 memset(runtime->dma_area, 0, runtime->buffer_size);
117 snd_pcm_lib_free_pages(substream); 130 snd_pcm_lib_free_pages(substream);
118 return 0; 131 return 0;
119} 132}
@@ -127,16 +140,11 @@ static int bf5xx_pcm_prepare(struct snd_pcm_substream *substream)
127 * SPORT working in TMD mode(include AC97). 140 * SPORT working in TMD mode(include AC97).
128 */ 141 */
129#if defined(CONFIG_SND_MMAP_SUPPORT) 142#if defined(CONFIG_SND_MMAP_SUPPORT)
130 size_t size = bf5xx_pcm_hardware.buffer_bytes_max
131 * sizeof(struct ac97_frame) / 4;
132 /*clean up intermediate buffer*/
133 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 143 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
134 memset(sport->tx_dma_buf, 0, size);
135 sport_set_tx_callback(sport, bf5xx_dma_irq, substream); 144 sport_set_tx_callback(sport, bf5xx_dma_irq, substream);
136 sport_config_tx_dma(sport, sport->tx_dma_buf, runtime->periods, 145 sport_config_tx_dma(sport, sport->tx_dma_buf, runtime->periods,
137 runtime->period_size * sizeof(struct ac97_frame)); 146 runtime->period_size * sizeof(struct ac97_frame));
138 } else { 147 } else {
139 memset(sport->rx_dma_buf, 0, size);
140 sport_set_rx_callback(sport, bf5xx_dma_irq, substream); 148 sport_set_rx_callback(sport, bf5xx_dma_irq, substream);
141 sport_config_rx_dma(sport, sport->rx_dma_buf, runtime->periods, 149 sport_config_rx_dma(sport, sport->rx_dma_buf, runtime->periods,
142 runtime->period_size * sizeof(struct ac97_frame)); 150 runtime->period_size * sizeof(struct ac97_frame));
@@ -164,8 +172,12 @@ static int bf5xx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
164 pr_debug("%s enter\n", __func__); 172 pr_debug("%s enter\n", __func__);
165 switch (cmd) { 173 switch (cmd) {
166 case SNDRV_PCM_TRIGGER_START: 174 case SNDRV_PCM_TRIGGER_START:
167 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 175 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
176 bf5xx_mmap_copy(substream, runtime->period_size);
177 snd_pcm_period_elapsed(substream);
178 sport->tx_delay_pos = 0;
168 sport_tx_start(sport); 179 sport_tx_start(sport);
180 }
169 else 181 else
170 sport_rx_start(sport); 182 sport_rx_start(sport);
171 break; 183 break;
@@ -198,7 +210,7 @@ static snd_pcm_uframes_t bf5xx_pcm_pointer(struct snd_pcm_substream *substream)
198 210
199#if defined(CONFIG_SND_MMAP_SUPPORT) 211#if defined(CONFIG_SND_MMAP_SUPPORT)
200 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 212 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
201 curr = sport->tx_pos; 213 curr = sport->tx_delay_pos;
202 else 214 else
203 curr = sport->rx_pos; 215 curr = sport->rx_pos;
204#else 216#else
@@ -237,6 +249,21 @@ static int bf5xx_pcm_open(struct snd_pcm_substream *substream)
237 return ret; 249 return ret;
238} 250}
239 251
252static int bf5xx_pcm_close(struct snd_pcm_substream *substream)
253{
254 struct snd_pcm_runtime *runtime = substream->runtime;
255 struct sport_device *sport = runtime->private_data;
256
257 pr_debug("%s enter\n", __func__);
258 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
259 sport->once = 0;
260 memset(sport->tx_dma_buf, 0, runtime->buffer_size * sizeof(struct ac97_frame));
261 } else
262 memset(sport->rx_dma_buf, 0, runtime->buffer_size * sizeof(struct ac97_frame));
263
264 return 0;
265}
266
240#ifdef CONFIG_SND_MMAP_SUPPORT 267#ifdef CONFIG_SND_MMAP_SUPPORT
241static int bf5xx_pcm_mmap(struct snd_pcm_substream *substream, 268static int bf5xx_pcm_mmap(struct snd_pcm_substream *substream,
242 struct vm_area_struct *vma) 269 struct vm_area_struct *vma)
@@ -272,6 +299,7 @@ static int bf5xx_pcm_copy(struct snd_pcm_substream *substream, int channel,
272 299
273struct snd_pcm_ops bf5xx_pcm_ac97_ops = { 300struct snd_pcm_ops bf5xx_pcm_ac97_ops = {
274 .open = bf5xx_pcm_open, 301 .open = bf5xx_pcm_open,
302 .close = bf5xx_pcm_close,
275 .ioctl = snd_pcm_lib_ioctl, 303 .ioctl = snd_pcm_lib_ioctl,
276 .hw_params = bf5xx_pcm_hw_params, 304 .hw_params = bf5xx_pcm_hw_params,
277 .hw_free = bf5xx_pcm_hw_free, 305 .hw_free = bf5xx_pcm_hw_free,
diff --git a/sound/soc/blackfin/bf5xx-ac97.c b/sound/soc/blackfin/bf5xx-ac97.c
index c782e311fd56..5e5aafb6485f 100644
--- a/sound/soc/blackfin/bf5xx-ac97.c
+++ b/sound/soc/blackfin/bf5xx-ac97.c
@@ -129,7 +129,6 @@ static void enqueue_cmd(struct snd_ac97 *ac97, __u16 addr, __u16 data)
129 struct ac97_frame *nextwrite; 129 struct ac97_frame *nextwrite;
130 130
131 sport_incfrag(sport, &nextfrag, 1); 131 sport_incfrag(sport, &nextfrag, 1);
132 sport_incfrag(sport, &nextfrag, 1);
133 132
134 nextwrite = (struct ac97_frame *)(sport->tx_buf + \ 133 nextwrite = (struct ac97_frame *)(sport->tx_buf + \
135 nextfrag * sport->tx_fragsize); 134 nextfrag * sport->tx_fragsize);
diff --git a/sound/soc/blackfin/bf5xx-ad73311.c b/sound/soc/blackfin/bf5xx-ad73311.c
new file mode 100644
index 000000000000..622c9b909532
--- /dev/null
+++ b/sound/soc/blackfin/bf5xx-ad73311.c
@@ -0,0 +1,240 @@
1/*
2 * File: sound/soc/blackfin/bf5xx-ad73311.c
3 * Author: Cliff Cai <Cliff.Cai@analog.com>
4 *
5 * Created: Thur Sep 25 2008
6 * Description: Board driver for ad73311 sound chip
7 *
8 * Modified:
9 * Copyright 2008 Analog Devices Inc.
10 *
11 * Bugs: Enter bugs at http://blackfin.uclinux.org/
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, see the file COPYING, or write
25 * to the Free Software Foundation, Inc.,
26 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
27 */
28
29#include <linux/module.h>
30#include <linux/moduleparam.h>
31#include <linux/device.h>
32#include <linux/delay.h>
33#include <linux/gpio.h>
34
35#include <sound/core.h>
36#include <sound/pcm.h>
37#include <sound/soc.h>
38#include <sound/soc-dapm.h>
39#include <sound/pcm_params.h>
40
41#include <asm/blackfin.h>
42#include <asm/cacheflush.h>
43#include <asm/irq.h>
44#include <asm/dma.h>
45#include <asm/portmux.h>
46
47#include "../codecs/ad73311.h"
48#include "bf5xx-sport.h"
49#include "bf5xx-i2s-pcm.h"
50#include "bf5xx-i2s.h"
51
52#if CONFIG_SND_BF5XX_SPORT_NUM == 0
53#define bfin_write_SPORT_TCR1 bfin_write_SPORT0_TCR1
54#define bfin_read_SPORT_TCR1 bfin_read_SPORT0_TCR1
55#define bfin_write_SPORT_TCR2 bfin_write_SPORT0_TCR2
56#define bfin_write_SPORT_TX16 bfin_write_SPORT0_TX16
57#define bfin_read_SPORT_STAT bfin_read_SPORT0_STAT
58#else
59#define bfin_write_SPORT_TCR1 bfin_write_SPORT1_TCR1
60#define bfin_read_SPORT_TCR1 bfin_read_SPORT1_TCR1
61#define bfin_write_SPORT_TCR2 bfin_write_SPORT1_TCR2
62#define bfin_write_SPORT_TX16 bfin_write_SPORT1_TX16
63#define bfin_read_SPORT_STAT bfin_read_SPORT1_STAT
64#endif
65
66#define GPIO_SE CONFIG_SND_BFIN_AD73311_SE
67
68static struct snd_soc_machine bf5xx_ad73311;
69
70static int snd_ad73311_startup(void)
71{
72 pr_debug("%s enter\n", __func__);
73
74 /* Pull up SE pin on AD73311L */
75 gpio_set_value(GPIO_SE, 1);
76 return 0;
77}
78
79static int snd_ad73311_configure(void)
80{
81 unsigned short ctrl_regs[6];
82 unsigned short status = 0;
83 int count = 0;
84
85 /* DMCLK = MCLK = 16.384 MHz
86 * SCLK = DMCLK/8 = 2.048 MHz
87 * Sample Rate = DMCLK/2048 = 8 KHz
88 */
89 ctrl_regs[0] = AD_CONTROL | AD_WRITE | CTRL_REG_B | REGB_MCDIV(0) | \
90 REGB_SCDIV(0) | REGB_DIRATE(0);
91 ctrl_regs[1] = AD_CONTROL | AD_WRITE | CTRL_REG_C | REGC_PUDEV | \
92 REGC_PUADC | REGC_PUDAC | REGC_PUREF | REGC_REFUSE ;
93 ctrl_regs[2] = AD_CONTROL | AD_WRITE | CTRL_REG_D | REGD_OGS(2) | \
94 REGD_IGS(2);
95 ctrl_regs[3] = AD_CONTROL | AD_WRITE | CTRL_REG_E | REGE_DA(0x1f);
96 ctrl_regs[4] = AD_CONTROL | AD_WRITE | CTRL_REG_F | REGF_SEEN ;
97 ctrl_regs[5] = AD_CONTROL | AD_WRITE | CTRL_REG_A | REGA_MODE_DATA;
98
99 local_irq_disable();
100 snd_ad73311_startup();
101 udelay(1);
102
103 bfin_write_SPORT_TCR1(TFSR);
104 bfin_write_SPORT_TCR2(0xF);
105 SSYNC();
106
107 /* SPORT Tx Register is a 8 x 16 FIFO, all the data can be put to
108 * FIFO before enable SPORT to transfer the data
109 */
110 for (count = 0; count < 6; count++)
111 bfin_write_SPORT_TX16(ctrl_regs[count]);
112 SSYNC();
113 bfin_write_SPORT_TCR1(bfin_read_SPORT_TCR1() | TSPEN);
114 SSYNC();
115
116 /* When TUVF is set, the data is already send out */
117 while (!(status & TUVF) && count++ < 10000) {
118 udelay(1);
119 status = bfin_read_SPORT_STAT();
120 SSYNC();
121 }
122 bfin_write_SPORT_TCR1(bfin_read_SPORT_TCR1() & ~TSPEN);
123 SSYNC();
124 local_irq_enable();
125
126 if (count == 10000) {
127 printk(KERN_ERR "ad73311: failed to configure codec\n");
128 return -1;
129 }
130 return 0;
131}
132
133static int bf5xx_probe(struct platform_device *pdev)
134{
135 int err;
136 if (gpio_request(GPIO_SE, "AD73311_SE")) {
137 printk(KERN_ERR "%s: Failed ro request GPIO_%d\n", __func__, GPIO_SE);
138 return -EBUSY;
139 }
140
141 gpio_direction_output(GPIO_SE, 0);
142
143 err = snd_ad73311_configure();
144 if (err < 0)
145 return -EFAULT;
146
147 return 0;
148}
149
150static int bf5xx_ad73311_startup(struct snd_pcm_substream *substream)
151{
152 struct snd_soc_pcm_runtime *rtd = substream->private_data;
153 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
154
155 pr_debug("%s enter\n", __func__);
156 cpu_dai->private_data = sport_handle;
157 return 0;
158}
159
160static int bf5xx_ad73311_hw_params(struct snd_pcm_substream *substream,
161 struct snd_pcm_hw_params *params)
162{
163 struct snd_soc_pcm_runtime *rtd = substream->private_data;
164 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
165 int ret = 0;
166
167 pr_debug("%s rate %d format %x\n", __func__, params_rate(params),
168 params_format(params));
169
170 /* set cpu DAI configuration */
171 ret = cpu_dai->dai_ops.set_fmt(cpu_dai, SND_SOC_DAIFMT_DSP_A |
172 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
173 if (ret < 0)
174 return ret;
175
176 return 0;
177}
178
179
180static struct snd_soc_ops bf5xx_ad73311_ops = {
181 .startup = bf5xx_ad73311_startup,
182 .hw_params = bf5xx_ad73311_hw_params,
183};
184
185static struct snd_soc_dai_link bf5xx_ad73311_dai = {
186 .name = "ad73311",
187 .stream_name = "AD73311",
188 .cpu_dai = &bf5xx_i2s_dai,
189 .codec_dai = &ad73311_dai,
190 .ops = &bf5xx_ad73311_ops,
191};
192
193static struct snd_soc_machine bf5xx_ad73311 = {
194 .name = "bf5xx_ad73311",
195 .probe = bf5xx_probe,
196 .dai_link = &bf5xx_ad73311_dai,
197 .num_links = 1,
198};
199
200static struct snd_soc_device bf5xx_ad73311_snd_devdata = {
201 .machine = &bf5xx_ad73311,
202 .platform = &bf5xx_i2s_soc_platform,
203 .codec_dev = &soc_codec_dev_ad73311,
204};
205
206static struct platform_device *bf52x_ad73311_snd_device;
207
208static int __init bf5xx_ad73311_init(void)
209{
210 int ret;
211
212 pr_debug("%s enter\n", __func__);
213 bf52x_ad73311_snd_device = platform_device_alloc("soc-audio", -1);
214 if (!bf52x_ad73311_snd_device)
215 return -ENOMEM;
216
217 platform_set_drvdata(bf52x_ad73311_snd_device, &bf5xx_ad73311_snd_devdata);
218 bf5xx_ad73311_snd_devdata.dev = &bf52x_ad73311_snd_device->dev;
219 ret = platform_device_add(bf52x_ad73311_snd_device);
220
221 if (ret)
222 platform_device_put(bf52x_ad73311_snd_device);
223
224 return ret;
225}
226
227static void __exit bf5xx_ad73311_exit(void)
228{
229 pr_debug("%s enter\n", __func__);
230 platform_device_unregister(bf52x_ad73311_snd_device);
231}
232
233module_init(bf5xx_ad73311_init);
234module_exit(bf5xx_ad73311_exit);
235
236/* Module information */
237MODULE_AUTHOR("Cliff Cai");
238MODULE_DESCRIPTION("ALSA SoC AD73311 Blackfin");
239MODULE_LICENSE("GPL");
240
diff --git a/sound/soc/blackfin/bf5xx-i2s.c b/sound/soc/blackfin/bf5xx-i2s.c
index 43a4092eeb89..827587f08180 100644
--- a/sound/soc/blackfin/bf5xx-i2s.c
+++ b/sound/soc/blackfin/bf5xx-i2s.c
@@ -70,6 +70,13 @@ static struct sport_param sport_params[2] = {
70 } 70 }
71}; 71};
72 72
73static u16 sport_req[][7] = {
74 { P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS,
75 P_SPORT0_DRPRI, P_SPORT0_RSCLK, 0},
76 { P_SPORT1_DTPRI, P_SPORT1_TSCLK, P_SPORT1_RFS,
77 P_SPORT1_DRPRI, P_SPORT1_RSCLK, 0},
78};
79
73static int bf5xx_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai, 80static int bf5xx_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai,
74 unsigned int fmt) 81 unsigned int fmt)
75{ 82{
@@ -78,6 +85,14 @@ static int bf5xx_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai,
78 /* interface format:support I2S,slave mode */ 85 /* interface format:support I2S,slave mode */
79 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 86 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
80 case SND_SOC_DAIFMT_I2S: 87 case SND_SOC_DAIFMT_I2S:
88 bf5xx_i2s.tcr1 |= TFSR | TCKFE;
89 bf5xx_i2s.rcr1 |= RFSR | RCKFE;
90 bf5xx_i2s.tcr2 |= TSFSE;
91 bf5xx_i2s.rcr2 |= RSFSE;
92 break;
93 case SND_SOC_DAIFMT_DSP_A:
94 bf5xx_i2s.tcr1 |= TFSR;
95 bf5xx_i2s.rcr1 |= RFSR;
81 break; 96 break;
82 case SND_SOC_DAIFMT_LEFT_J: 97 case SND_SOC_DAIFMT_LEFT_J:
83 ret = -EINVAL; 98 ret = -EINVAL;
@@ -127,14 +142,17 @@ static int bf5xx_i2s_hw_params(struct snd_pcm_substream *substream,
127 case SNDRV_PCM_FORMAT_S16_LE: 142 case SNDRV_PCM_FORMAT_S16_LE:
128 bf5xx_i2s.tcr2 |= 15; 143 bf5xx_i2s.tcr2 |= 15;
129 bf5xx_i2s.rcr2 |= 15; 144 bf5xx_i2s.rcr2 |= 15;
145 sport_handle->wdsize = 2;
130 break; 146 break;
131 case SNDRV_PCM_FORMAT_S24_LE: 147 case SNDRV_PCM_FORMAT_S24_LE:
132 bf5xx_i2s.tcr2 |= 23; 148 bf5xx_i2s.tcr2 |= 23;
133 bf5xx_i2s.rcr2 |= 23; 149 bf5xx_i2s.rcr2 |= 23;
150 sport_handle->wdsize = 3;
134 break; 151 break;
135 case SNDRV_PCM_FORMAT_S32_LE: 152 case SNDRV_PCM_FORMAT_S32_LE:
136 bf5xx_i2s.tcr2 |= 31; 153 bf5xx_i2s.tcr2 |= 31;
137 bf5xx_i2s.rcr2 |= 31; 154 bf5xx_i2s.rcr2 |= 31;
155 sport_handle->wdsize = 4;
138 break; 156 break;
139 } 157 }
140 158
@@ -145,17 +163,17 @@ static int bf5xx_i2s_hw_params(struct snd_pcm_substream *substream,
145 * need to configure both of them at the time when the first 163 * need to configure both of them at the time when the first
146 * stream is opened. 164 * stream is opened.
147 * 165 *
148 * CPU DAI format:I2S, slave mode. 166 * CPU DAI:slave mode.
149 */ 167 */
150 ret = sport_config_rx(sport_handle, RFSR | RCKFE, 168 ret = sport_config_rx(sport_handle, bf5xx_i2s.rcr1,
151 RSFSE|bf5xx_i2s.rcr2, 0, 0); 169 bf5xx_i2s.rcr2, 0, 0);
152 if (ret) { 170 if (ret) {
153 pr_err("SPORT is busy!\n"); 171 pr_err("SPORT is busy!\n");
154 return -EBUSY; 172 return -EBUSY;
155 } 173 }
156 174
157 ret = sport_config_tx(sport_handle, TFSR | TCKFE, 175 ret = sport_config_tx(sport_handle, bf5xx_i2s.tcr1,
158 TSFSE|bf5xx_i2s.tcr2, 0, 0); 176 bf5xx_i2s.tcr2, 0, 0);
159 if (ret) { 177 if (ret) {
160 pr_err("SPORT is busy!\n"); 178 pr_err("SPORT is busy!\n");
161 return -EBUSY; 179 return -EBUSY;
@@ -174,13 +192,6 @@ static void bf5xx_i2s_shutdown(struct snd_pcm_substream *substream)
174static int bf5xx_i2s_probe(struct platform_device *pdev, 192static int bf5xx_i2s_probe(struct platform_device *pdev,
175 struct snd_soc_dai *dai) 193 struct snd_soc_dai *dai)
176{ 194{
177 u16 sport_req[][7] = {
178 { P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS,
179 P_SPORT0_DRPRI, P_SPORT0_RSCLK, 0},
180 { P_SPORT1_DTPRI, P_SPORT1_TSCLK, P_SPORT1_RFS,
181 P_SPORT1_DRPRI, P_SPORT1_RSCLK, 0},
182 };
183
184 pr_debug("%s enter\n", __func__); 195 pr_debug("%s enter\n", __func__);
185 if (peripheral_request_list(&sport_req[sport_num][0], "soc-audio")) { 196 if (peripheral_request_list(&sport_req[sport_num][0], "soc-audio")) {
186 pr_err("Requesting Peripherals failed\n"); 197 pr_err("Requesting Peripherals failed\n");
@@ -198,6 +209,13 @@ static int bf5xx_i2s_probe(struct platform_device *pdev,
198 return 0; 209 return 0;
199} 210}
200 211
212static void bf5xx_i2s_remove(struct platform_device *pdev,
213 struct snd_soc_dai *dai)
214{
215 pr_debug("%s enter\n", __func__);
216 peripheral_free_list(&sport_req[sport_num][0]);
217}
218
201#ifdef CONFIG_PM 219#ifdef CONFIG_PM
202static int bf5xx_i2s_suspend(struct platform_device *dev, 220static int bf5xx_i2s_suspend(struct platform_device *dev,
203 struct snd_soc_dai *dai) 221 struct snd_soc_dai *dai)
@@ -263,15 +281,16 @@ struct snd_soc_dai bf5xx_i2s_dai = {
263 .id = 0, 281 .id = 0,
264 .type = SND_SOC_DAI_I2S, 282 .type = SND_SOC_DAI_I2S,
265 .probe = bf5xx_i2s_probe, 283 .probe = bf5xx_i2s_probe,
284 .remove = bf5xx_i2s_remove,
266 .suspend = bf5xx_i2s_suspend, 285 .suspend = bf5xx_i2s_suspend,
267 .resume = bf5xx_i2s_resume, 286 .resume = bf5xx_i2s_resume,
268 .playback = { 287 .playback = {
269 .channels_min = 2, 288 .channels_min = 1,
270 .channels_max = 2, 289 .channels_max = 2,
271 .rates = BF5XX_I2S_RATES, 290 .rates = BF5XX_I2S_RATES,
272 .formats = BF5XX_I2S_FORMATS,}, 291 .formats = BF5XX_I2S_FORMATS,},
273 .capture = { 292 .capture = {
274 .channels_min = 2, 293 .channels_min = 1,
275 .channels_max = 2, 294 .channels_max = 2,
276 .rates = BF5XX_I2S_RATES, 295 .rates = BF5XX_I2S_RATES,
277 .formats = BF5XX_I2S_FORMATS,}, 296 .formats = BF5XX_I2S_FORMATS,},
diff --git a/sound/soc/blackfin/bf5xx-sport.h b/sound/soc/blackfin/bf5xx-sport.h
index 4c163454bbf8..fcadcc081f7f 100644
--- a/sound/soc/blackfin/bf5xx-sport.h
+++ b/sound/soc/blackfin/bf5xx-sport.h
@@ -123,6 +123,8 @@ struct sport_device {
123 int rx_pos; 123 int rx_pos;
124 unsigned int tx_buffer_size; 124 unsigned int tx_buffer_size;
125 unsigned int rx_buffer_size; 125 unsigned int rx_buffer_size;
126 int tx_delay_pos;
127 int once;
126#endif 128#endif
127 void *private_data; 129 void *private_data;
128}; 130};
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index e0b9869df0f1..4975d8573e4f 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -3,9 +3,11 @@ config SND_SOC_ALL_CODECS
3 depends on I2C 3 depends on I2C
4 select SPI 4 select SPI
5 select SPI_MASTER 5 select SPI_MASTER
6 select SND_SOC_AD73311
6 select SND_SOC_AK4535 7 select SND_SOC_AK4535
7 select SND_SOC_CS4270 8 select SND_SOC_CS4270
8 select SND_SOC_SSM2602 9 select SND_SOC_SSM2602
10 select SND_SOC_TLV320AIC23
9 select SND_SOC_TLV320AIC26 11 select SND_SOC_TLV320AIC26
10 select SND_SOC_TLV320AIC3X 12 select SND_SOC_TLV320AIC3X
11 select SND_SOC_UDA1380 13 select SND_SOC_UDA1380
@@ -34,6 +36,9 @@ config SND_SOC_AC97_CODEC
34config SND_SOC_AD1980 36config SND_SOC_AD1980
35 tristate 37 tristate
36 38
39config SND_SOC_AD73311
40 tristate
41
37config SND_SOC_AK4535 42config SND_SOC_AK4535
38 tristate 43 tristate
39 44
@@ -58,9 +63,13 @@ config SND_SOC_CS4270_VD33_ERRATA
58config SND_SOC_SSM2602 63config SND_SOC_SSM2602
59 tristate 64 tristate
60 65
66config SND_SOC_TLV320AIC23
67 tristate
68 depends on I2C
69
61config SND_SOC_TLV320AIC26 70config SND_SOC_TLV320AIC26
62 tristate "TI TLV320AIC26 Codec support" 71 tristate "TI TLV320AIC26 Codec support"
63 depends on SND_SOC && SPI 72 depends on SPI
64 73
65config SND_SOC_TLV320AIC3X 74config SND_SOC_TLV320AIC3X
66 tristate 75 tristate
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index f977978a3409..90f0a585fc70 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -1,8 +1,10 @@
1snd-soc-ac97-objs := ac97.o 1snd-soc-ac97-objs := ac97.o
2snd-soc-ad1980-objs := ad1980.o 2snd-soc-ad1980-objs := ad1980.o
3snd-soc-ad73311-objs := ad73311.o
3snd-soc-ak4535-objs := ak4535.o 4snd-soc-ak4535-objs := ak4535.o
4snd-soc-cs4270-objs := cs4270.o 5snd-soc-cs4270-objs := cs4270.o
5snd-soc-ssm2602-objs := ssm2602.o 6snd-soc-ssm2602-objs := ssm2602.o
7snd-soc-tlv320aic23-objs := tlv320aic23.o
6snd-soc-tlv320aic26-objs := tlv320aic26.o 8snd-soc-tlv320aic26-objs := tlv320aic26.o
7snd-soc-tlv320aic3x-objs := tlv320aic3x.o 9snd-soc-tlv320aic3x-objs := tlv320aic3x.o
8snd-soc-uda1380-objs := uda1380.o 10snd-soc-uda1380-objs := uda1380.o
@@ -20,9 +22,11 @@ snd-soc-wm9713-objs := wm9713.o
20 22
21obj-$(CONFIG_SND_SOC_AC97_CODEC) += snd-soc-ac97.o 23obj-$(CONFIG_SND_SOC_AC97_CODEC) += snd-soc-ac97.o
22obj-$(CONFIG_SND_SOC_AD1980) += snd-soc-ad1980.o 24obj-$(CONFIG_SND_SOC_AD1980) += snd-soc-ad1980.o
25obj-$(CONFIG_SND_SOC_AD73311) += snd-soc-ad73311.o
23obj-$(CONFIG_SND_SOC_AK4535) += snd-soc-ak4535.o 26obj-$(CONFIG_SND_SOC_AK4535) += snd-soc-ak4535.o
24obj-$(CONFIG_SND_SOC_CS4270) += snd-soc-cs4270.o 27obj-$(CONFIG_SND_SOC_CS4270) += snd-soc-cs4270.o
25obj-$(CONFIG_SND_SOC_SSM2602) += snd-soc-ssm2602.o 28obj-$(CONFIG_SND_SOC_SSM2602) += snd-soc-ssm2602.o
29obj-$(CONFIG_SND_SOC_TLV320AIC23) += snd-soc-tlv320aic23.o
26obj-$(CONFIG_SND_SOC_TLV320AIC26) += snd-soc-tlv320aic26.o 30obj-$(CONFIG_SND_SOC_TLV320AIC26) += snd-soc-tlv320aic26.o
27obj-$(CONFIG_SND_SOC_TLV320AIC3X) += snd-soc-tlv320aic3x.o 31obj-$(CONFIG_SND_SOC_TLV320AIC3X) += snd-soc-tlv320aic3x.o
28obj-$(CONFIG_SND_SOC_UDA1380) += snd-soc-uda1380.o 32obj-$(CONFIG_SND_SOC_UDA1380) += snd-soc-uda1380.o
diff --git a/sound/soc/codecs/ac97.c b/sound/soc/codecs/ac97.c
index 61fd96ca7bc7..bd1ebdc6c86c 100644
--- a/sound/soc/codecs/ac97.c
+++ b/sound/soc/codecs/ac97.c
@@ -2,8 +2,7 @@
2 * ac97.c -- ALSA Soc AC97 codec support 2 * ac97.c -- ALSA Soc AC97 codec support
3 * 3 *
4 * Copyright 2005 Wolfson Microelectronics PLC. 4 * Copyright 2005 Wolfson Microelectronics PLC.
5 * Author: Liam Girdwood 5 * Author: Liam Girdwood <lrg@slimlogic.co.uk>
6 * liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com
7 * 6 *
8 * This program is free software; you can redistribute it and/or modify it 7 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the 8 * under the terms of the GNU General Public License as published by the
diff --git a/sound/soc/codecs/ad1980.c b/sound/soc/codecs/ad1980.c
index 4e09c1f2c063..1397b8e06c0b 100644
--- a/sound/soc/codecs/ad1980.c
+++ b/sound/soc/codecs/ad1980.c
@@ -13,7 +13,6 @@
13 13
14#include <linux/init.h> 14#include <linux/init.h>
15#include <linux/module.h> 15#include <linux/module.h>
16#include <linux/version.h>
17#include <linux/kernel.h> 16#include <linux/kernel.h>
18#include <linux/device.h> 17#include <linux/device.h>
19#include <sound/core.h> 18#include <sound/core.h>
diff --git a/sound/soc/codecs/ad73311.c b/sound/soc/codecs/ad73311.c
new file mode 100644
index 000000000000..37af8607b00a
--- /dev/null
+++ b/sound/soc/codecs/ad73311.c
@@ -0,0 +1,107 @@
1/*
2 * ad73311.c -- ALSA Soc AD73311 codec support
3 *
4 * Copyright: Analog Device Inc.
5 * Author: Cliff Cai <cliff.cai@analog.com>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 *
12 * Revision history
13 * 25th Sep 2008 Initial version.
14 */
15
16#include <linux/init.h>
17#include <linux/module.h>
18#include <linux/version.h>
19#include <linux/kernel.h>
20#include <linux/device.h>
21#include <sound/core.h>
22#include <sound/pcm.h>
23#include <sound/ac97_codec.h>
24#include <sound/initval.h>
25#include <sound/soc.h>
26
27#include "ad73311.h"
28
29struct snd_soc_dai ad73311_dai = {
30 .name = "AD73311",
31 .playback = {
32 .stream_name = "Playback",
33 .channels_min = 1,
34 .channels_max = 1,
35 .rates = SNDRV_PCM_RATE_8000,
36 .formats = SNDRV_PCM_FMTBIT_S16_LE, },
37 .capture = {
38 .stream_name = "Capture",
39 .channels_min = 1,
40 .channels_max = 1,
41 .rates = SNDRV_PCM_RATE_8000,
42 .formats = SNDRV_PCM_FMTBIT_S16_LE, },
43};
44EXPORT_SYMBOL_GPL(ad73311_dai);
45
46static int ad73311_soc_probe(struct platform_device *pdev)
47{
48 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
49 struct snd_soc_codec *codec;
50 int ret = 0;
51
52 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
53 if (codec == NULL)
54 return -ENOMEM;
55 mutex_init(&codec->mutex);
56 codec->name = "AD73311";
57 codec->owner = THIS_MODULE;
58 codec->dai = &ad73311_dai;
59 codec->num_dai = 1;
60 socdev->codec = codec;
61 INIT_LIST_HEAD(&codec->dapm_widgets);
62 INIT_LIST_HEAD(&codec->dapm_paths);
63
64 /* register pcms */
65 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
66 if (ret < 0) {
67 printk(KERN_ERR "ad73311: failed to create pcms\n");
68 goto pcm_err;
69 }
70
71 ret = snd_soc_register_card(socdev);
72 if (ret < 0) {
73 printk(KERN_ERR "ad73311: failed to register card\n");
74 goto register_err;
75 }
76
77 return ret;
78
79register_err:
80 snd_soc_free_pcms(socdev);
81pcm_err:
82 kfree(socdev->codec);
83 socdev->codec = NULL;
84 return ret;
85}
86
87static int ad73311_soc_remove(struct platform_device *pdev)
88{
89 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
90 struct snd_soc_codec *codec = socdev->codec;
91
92 if (codec == NULL)
93 return 0;
94 snd_soc_free_pcms(socdev);
95 kfree(codec);
96 return 0;
97}
98
99struct snd_soc_codec_device soc_codec_dev_ad73311 = {
100 .probe = ad73311_soc_probe,
101 .remove = ad73311_soc_remove,
102};
103EXPORT_SYMBOL_GPL(soc_codec_dev_ad73311);
104
105MODULE_DESCRIPTION("ASoC ad73311 driver");
106MODULE_AUTHOR("Cliff Cai ");
107MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/ad73311.h b/sound/soc/codecs/ad73311.h
new file mode 100644
index 000000000000..507ce0c30edf
--- /dev/null
+++ b/sound/soc/codecs/ad73311.h
@@ -0,0 +1,90 @@
1/*
2 * File: sound/soc/codec/ad73311.h
3 * Based on:
4 * Author: Cliff Cai <cliff.cai@analog.com>
5 *
6 * Created: Thur Sep 25, 2008
7 * Description: definitions for AD73311 registers
8 *
9 *
10 * Modified:
11 * Copyright 2006 Analog Devices Inc.
12 *
13 * Bugs: Enter bugs at http://blackfin.uclinux.org/
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, see the file COPYING, or write
27 * to the Free Software Foundation, Inc.,
28 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
29 */
30
31#ifndef __AD73311_H__
32#define __AD73311_H__
33
34#define AD_CONTROL 0x8000
35#define AD_DATA 0x0000
36#define AD_READ 0x4000
37#define AD_WRITE 0x0000
38
39/* Control register A */
40#define CTRL_REG_A (0 << 8)
41
42#define REGA_MODE_PRO 0x00
43#define REGA_MODE_DATA 0x01
44#define REGA_MODE_MIXED 0x03
45#define REGA_DLB 0x04
46#define REGA_SLB 0x08
47#define REGA_DEVC(x) ((x & 0x7) << 4)
48#define REGA_RESET 0x80
49
50/* Control register B */
51#define CTRL_REG_B (1 << 8)
52
53#define REGB_DIRATE(x) (x & 0x3)
54#define REGB_SCDIV(x) ((x & 0x3) << 2)
55#define REGB_MCDIV(x) ((x & 0x7) << 4)
56#define REGB_CEE (1 << 7)
57
58/* Control register C */
59#define CTRL_REG_C (2 << 8)
60
61#define REGC_PUDEV (1 << 0)
62#define REGC_PUADC (1 << 3)
63#define REGC_PUDAC (1 << 4)
64#define REGC_PUREF (1 << 5)
65#define REGC_REFUSE (1 << 6)
66
67/* Control register D */
68#define CTRL_REG_D (3 << 8)
69
70#define REGD_IGS(x) (x & 0x7)
71#define REGD_RMOD (1 << 3)
72#define REGD_OGS(x) ((x & 0x7) << 4)
73#define REGD_MUTE (x << 7)
74
75/* Control register E */
76#define CTRL_REG_E (4 << 8)
77
78#define REGE_DA(x) (x & 0x1f)
79#define REGE_IBYP (1 << 5)
80
81/* Control register F */
82#define CTRL_REG_F (5 << 8)
83
84#define REGF_SEEN (1 << 5)
85#define REGF_INV (1 << 6)
86#define REGF_ALB (1 << 7)
87
88extern struct snd_soc_dai ad73311_dai;
89extern struct snd_soc_codec_device soc_codec_dev_ad73311;
90#endif
diff --git a/sound/soc/codecs/ak4535.c b/sound/soc/codecs/ak4535.c
index 088cf9927720..2a89b5888e11 100644
--- a/sound/soc/codecs/ak4535.c
+++ b/sound/soc/codecs/ak4535.c
@@ -28,7 +28,6 @@
28 28
29#include "ak4535.h" 29#include "ak4535.h"
30 30
31#define AUDIO_NAME "ak4535"
32#define AK4535_VERSION "0.3" 31#define AK4535_VERSION "0.3"
33 32
34struct snd_soc_codec_device soc_codec_dev_ak4535; 33struct snd_soc_codec_device soc_codec_dev_ak4535;
diff --git a/sound/soc/codecs/ssm2602.c b/sound/soc/codecs/ssm2602.c
index 940ce1c3522e..44ef0dacd564 100644
--- a/sound/soc/codecs/ssm2602.c
+++ b/sound/soc/codecs/ssm2602.c
@@ -42,7 +42,6 @@
42 42
43#include "ssm2602.h" 43#include "ssm2602.h"
44 44
45#define AUDIO_NAME "ssm2602"
46#define SSM2602_VERSION "0.1" 45#define SSM2602_VERSION "0.1"
47 46
48struct snd_soc_codec_device soc_codec_dev_ssm2602; 47struct snd_soc_codec_device soc_codec_dev_ssm2602;
diff --git a/sound/soc/codecs/tlv320aic23.c b/sound/soc/codecs/tlv320aic23.c
new file mode 100644
index 000000000000..bac7815e00fb
--- /dev/null
+++ b/sound/soc/codecs/tlv320aic23.c
@@ -0,0 +1,714 @@
1/*
2 * ALSA SoC TLV320AIC23 codec driver
3 *
4 * Author: Arun KS, <arunks@mistralsolutions.com>
5 * Copyright: (C) 2008 Mistral Solutions Pvt Ltd.,
6 *
7 * Based on sound/soc/codecs/wm8731.c by Richard Purdie
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 *
13 * Notes:
14 * The AIC23 is a driver for a low power stereo audio
15 * codec tlv320aic23
16 *
17 * The machine layer should disable unsupported inputs/outputs by
18 * snd_soc_dapm_disable_pin(codec, "LHPOUT"), etc.
19 */
20
21#include <linux/module.h>
22#include <linux/moduleparam.h>
23#include <linux/init.h>
24#include <linux/delay.h>
25#include <linux/pm.h>
26#include <linux/i2c.h>
27#include <linux/platform_device.h>
28#include <sound/core.h>
29#include <sound/pcm.h>
30#include <sound/pcm_params.h>
31#include <sound/soc.h>
32#include <sound/soc-dapm.h>
33#include <sound/tlv.h>
34#include <sound/initval.h>
35
36#include "tlv320aic23.h"
37
38#define AIC23_VERSION "0.1"
39
40struct tlv320aic23_srate_reg_info {
41 u32 sample_rate;
42 u8 control; /* SR3, SR2, SR1, SR0 and BOSR */
43 u8 divider; /* if 0 CLKIN = MCLK, if 1 CLKIN = MCLK/2 */
44};
45
46/*
47 * AIC23 register cache
48 */
49static const u16 tlv320aic23_reg[] = {
50 0x0097, 0x0097, 0x00F9, 0x00F9, /* 0 */
51 0x001A, 0x0004, 0x0007, 0x0001, /* 4 */
52 0x0020, 0x0000, 0x0000, 0x0000, /* 8 */
53 0x0000, 0x0000, 0x0000, 0x0000, /* 12 */
54};
55
56/*
57 * read tlv320aic23 register cache
58 */
59static inline unsigned int tlv320aic23_read_reg_cache(struct snd_soc_codec
60 *codec, unsigned int reg)
61{
62 u16 *cache = codec->reg_cache;
63 if (reg >= ARRAY_SIZE(tlv320aic23_reg))
64 return -1;
65 return cache[reg];
66}
67
68/*
69 * write tlv320aic23 register cache
70 */
71static inline void tlv320aic23_write_reg_cache(struct snd_soc_codec *codec,
72 u8 reg, u16 value)
73{
74 u16 *cache = codec->reg_cache;
75 if (reg >= ARRAY_SIZE(tlv320aic23_reg))
76 return;
77 cache[reg] = value;
78}
79
80/*
81 * write to the tlv320aic23 register space
82 */
83static int tlv320aic23_write(struct snd_soc_codec *codec, unsigned int reg,
84 unsigned int value)
85{
86
87 u8 data;
88
89 /* TLV320AIC23 has 7 bit address and 9 bits of data
90 * so we need to switch one data bit into reg and rest
91 * of data into val
92 */
93
94 if ((reg < 0 || reg > 9) && (reg != 15)) {
95 printk(KERN_WARNING "%s Invalid register R%d\n", __func__, reg);
96 return -1;
97 }
98
99 data = (reg << 1) | (value >> 8 & 0x01);
100
101 tlv320aic23_write_reg_cache(codec, reg, value);
102
103 if (codec->hw_write(codec->control_data, data,
104 (value & 0xff)) == 0)
105 return 0;
106
107 printk(KERN_ERR "%s cannot write %03x to register R%d\n", __func__,
108 value, reg);
109
110 return -EIO;
111}
112
113static const char *rec_src_text[] = { "Line", "Mic" };
114static const char *deemph_text[] = {"None", "32Khz", "44.1Khz", "48Khz"};
115
116static const struct soc_enum rec_src_enum =
117 SOC_ENUM_SINGLE(TLV320AIC23_ANLG, 2, 2, rec_src_text);
118
119static const struct snd_kcontrol_new tlv320aic23_rec_src_mux_controls =
120SOC_DAPM_ENUM("Input Select", rec_src_enum);
121
122static const struct soc_enum tlv320aic23_rec_src =
123 SOC_ENUM_SINGLE(TLV320AIC23_ANLG, 2, 2, rec_src_text);
124static const struct soc_enum tlv320aic23_deemph =
125 SOC_ENUM_SINGLE(TLV320AIC23_DIGT, 1, 4, deemph_text);
126
127static const DECLARE_TLV_DB_SCALE(out_gain_tlv, -12100, 100, 0);
128static const DECLARE_TLV_DB_SCALE(input_gain_tlv, -1725, 75, 0);
129static const DECLARE_TLV_DB_SCALE(sidetone_vol_tlv, -1800, 300, 0);
130
131static int snd_soc_tlv320aic23_put_volsw(struct snd_kcontrol *kcontrol,
132 struct snd_ctl_elem_value *ucontrol)
133{
134 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
135 u16 val, reg;
136
137 val = (ucontrol->value.integer.value[0] & 0x07);
138
139 /* linear conversion to userspace
140 * 000 = -6db
141 * 001 = -9db
142 * 010 = -12db
143 * 011 = -18db (Min)
144 * 100 = 0db (Max)
145 */
146 val = (val >= 4) ? 4 : (3 - val);
147
148 reg = tlv320aic23_read_reg_cache(codec, TLV320AIC23_ANLG) & (~0x1C0);
149 tlv320aic23_write(codec, TLV320AIC23_ANLG, reg | (val << 6));
150
151 return 0;
152}
153
154static int snd_soc_tlv320aic23_get_volsw(struct snd_kcontrol *kcontrol,
155 struct snd_ctl_elem_value *ucontrol)
156{
157 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
158 u16 val;
159
160 val = tlv320aic23_read_reg_cache(codec, TLV320AIC23_ANLG) & (0x1C0);
161 val = val >> 6;
162 val = (val >= 4) ? 4 : (3 - val);
163 ucontrol->value.integer.value[0] = val;
164 return 0;
165
166}
167
168#define SOC_TLV320AIC23_SINGLE_TLV(xname, reg, shift, max, invert, tlv_array) \
169{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
170 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
171 SNDRV_CTL_ELEM_ACCESS_READWRITE,\
172 .tlv.p = (tlv_array), \
173 .info = snd_soc_info_volsw, .get = snd_soc_tlv320aic23_get_volsw,\
174 .put = snd_soc_tlv320aic23_put_volsw, \
175 .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert) }
176
177static const struct snd_kcontrol_new tlv320aic23_snd_controls[] = {
178 SOC_DOUBLE_R_TLV("Digital Playback Volume", TLV320AIC23_LCHNVOL,
179 TLV320AIC23_RCHNVOL, 0, 127, 0, out_gain_tlv),
180 SOC_SINGLE("Digital Playback Switch", TLV320AIC23_DIGT, 3, 1, 1),
181 SOC_DOUBLE_R("Line Input Switch", TLV320AIC23_LINVOL,
182 TLV320AIC23_RINVOL, 7, 1, 0),
183 SOC_DOUBLE_R_TLV("Line Input Volume", TLV320AIC23_LINVOL,
184 TLV320AIC23_RINVOL, 0, 31, 0, input_gain_tlv),
185 SOC_SINGLE("Mic Input Switch", TLV320AIC23_ANLG, 1, 1, 1),
186 SOC_SINGLE("Mic Booster Switch", TLV320AIC23_ANLG, 0, 1, 0),
187 SOC_TLV320AIC23_SINGLE_TLV("Sidetone Volume", TLV320AIC23_ANLG,
188 6, 4, 0, sidetone_vol_tlv),
189 SOC_ENUM("Playback De-emphasis", tlv320aic23_deemph),
190};
191
192/* add non dapm controls */
193static int tlv320aic23_add_controls(struct snd_soc_codec *codec)
194{
195
196 int err, i;
197
198 for (i = 0; i < ARRAY_SIZE(tlv320aic23_snd_controls); i++) {
199 err = snd_ctl_add(codec->card,
200 snd_soc_cnew(&tlv320aic23_snd_controls[i],
201 codec, NULL));
202 if (err < 0)
203 return err;
204 }
205
206 return 0;
207
208}
209
210/* PGA Mixer controls for Line and Mic switch */
211static const struct snd_kcontrol_new tlv320aic23_output_mixer_controls[] = {
212 SOC_DAPM_SINGLE("Line Bypass Switch", TLV320AIC23_ANLG, 3, 1, 0),
213 SOC_DAPM_SINGLE("Mic Sidetone Switch", TLV320AIC23_ANLG, 5, 1, 0),
214 SOC_DAPM_SINGLE("Playback Switch", TLV320AIC23_ANLG, 4, 1, 0),
215};
216
217static const struct snd_soc_dapm_widget tlv320aic23_dapm_widgets[] = {
218 SND_SOC_DAPM_DAC("DAC", "Playback", TLV320AIC23_PWR, 3, 1),
219 SND_SOC_DAPM_ADC("ADC", "Capture", TLV320AIC23_PWR, 2, 1),
220 SND_SOC_DAPM_MUX("Capture Source", SND_SOC_NOPM, 0, 0,
221 &tlv320aic23_rec_src_mux_controls),
222 SND_SOC_DAPM_MIXER("Output Mixer", TLV320AIC23_PWR, 4, 1,
223 &tlv320aic23_output_mixer_controls[0],
224 ARRAY_SIZE(tlv320aic23_output_mixer_controls)),
225 SND_SOC_DAPM_PGA("Line Input", TLV320AIC23_PWR, 0, 1, NULL, 0),
226 SND_SOC_DAPM_PGA("Mic Input", TLV320AIC23_PWR, 1, 1, NULL, 0),
227
228 SND_SOC_DAPM_OUTPUT("LHPOUT"),
229 SND_SOC_DAPM_OUTPUT("RHPOUT"),
230 SND_SOC_DAPM_OUTPUT("LOUT"),
231 SND_SOC_DAPM_OUTPUT("ROUT"),
232
233 SND_SOC_DAPM_INPUT("LLINEIN"),
234 SND_SOC_DAPM_INPUT("RLINEIN"),
235
236 SND_SOC_DAPM_INPUT("MICIN"),
237};
238
239static const struct snd_soc_dapm_route intercon[] = {
240 /* Output Mixer */
241 {"Output Mixer", "Line Bypass Switch", "Line Input"},
242 {"Output Mixer", "Playback Switch", "DAC"},
243 {"Output Mixer", "Mic Sidetone Switch", "Mic Input"},
244
245 /* Outputs */
246 {"RHPOUT", NULL, "Output Mixer"},
247 {"LHPOUT", NULL, "Output Mixer"},
248 {"LOUT", NULL, "Output Mixer"},
249 {"ROUT", NULL, "Output Mixer"},
250
251 /* Inputs */
252 {"Line Input", "NULL", "LLINEIN"},
253 {"Line Input", "NULL", "RLINEIN"},
254
255 {"Mic Input", "NULL", "MICIN"},
256
257 /* input mux */
258 {"Capture Source", "Line", "Line Input"},
259 {"Capture Source", "Mic", "Mic Input"},
260 {"ADC", NULL, "Capture Source"},
261
262};
263
264/* tlv320aic23 related */
265static const struct tlv320aic23_srate_reg_info srate_reg_info[] = {
266 {4000, 0x06, 1}, /* 4000 */
267 {8000, 0x06, 0}, /* 8000 */
268 {16000, 0x0C, 1}, /* 16000 */
269 {22050, 0x11, 1}, /* 22050 */
270 {24000, 0x00, 1}, /* 24000 */
271 {32000, 0x0C, 0}, /* 32000 */
272 {44100, 0x11, 0}, /* 44100 */
273 {48000, 0x00, 0}, /* 48000 */
274 {88200, 0x1F, 0}, /* 88200 */
275 {96000, 0x0E, 0}, /* 96000 */
276};
277
278static int tlv320aic23_add_widgets(struct snd_soc_codec *codec)
279{
280 snd_soc_dapm_new_controls(codec, tlv320aic23_dapm_widgets,
281 ARRAY_SIZE(tlv320aic23_dapm_widgets));
282
283 /* set up audio path interconnects */
284 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
285
286 snd_soc_dapm_new_widgets(codec);
287 return 0;
288}
289
290static int tlv320aic23_hw_params(struct snd_pcm_substream *substream,
291 struct snd_pcm_hw_params *params)
292{
293 struct snd_soc_pcm_runtime *rtd = substream->private_data;
294 struct snd_soc_device *socdev = rtd->socdev;
295 struct snd_soc_codec *codec = socdev->codec;
296 u16 iface_reg, data;
297 u8 count = 0;
298
299 iface_reg =
300 tlv320aic23_read_reg_cache(codec,
301 TLV320AIC23_DIGT_FMT) & ~(0x03 << 2);
302
303 /* Search for the right sample rate */
304 /* Verify what happens if the rate is not supported
305 * now it goes to 96Khz */
306 while ((srate_reg_info[count].sample_rate != params_rate(params)) &&
307 (count < ARRAY_SIZE(srate_reg_info))) {
308 count++;
309 }
310
311 data = (srate_reg_info[count].divider << TLV320AIC23_CLKIN_SHIFT) |
312 (srate_reg_info[count]. control << TLV320AIC23_BOSR_SHIFT) |
313 TLV320AIC23_USB_CLK_ON;
314
315 tlv320aic23_write(codec, TLV320AIC23_SRATE, data);
316
317 switch (params_format(params)) {
318 case SNDRV_PCM_FORMAT_S16_LE:
319 break;
320 case SNDRV_PCM_FORMAT_S20_3LE:
321 iface_reg |= (0x01 << 2);
322 break;
323 case SNDRV_PCM_FORMAT_S24_LE:
324 iface_reg |= (0x02 << 2);
325 break;
326 case SNDRV_PCM_FORMAT_S32_LE:
327 iface_reg |= (0x03 << 2);
328 break;
329 }
330 tlv320aic23_write(codec, TLV320AIC23_DIGT_FMT, iface_reg);
331
332 return 0;
333}
334
335static int tlv320aic23_pcm_prepare(struct snd_pcm_substream *substream)
336{
337 struct snd_soc_pcm_runtime *rtd = substream->private_data;
338 struct snd_soc_device *socdev = rtd->socdev;
339 struct snd_soc_codec *codec = socdev->codec;
340
341 /* set active */
342 tlv320aic23_write(codec, TLV320AIC23_ACTIVE, 0x0001);
343
344 return 0;
345}
346
347static void tlv320aic23_shutdown(struct snd_pcm_substream *substream)
348{
349 struct snd_soc_pcm_runtime *rtd = substream->private_data;
350 struct snd_soc_device *socdev = rtd->socdev;
351 struct snd_soc_codec *codec = socdev->codec;
352
353 /* deactivate */
354 if (!codec->active) {
355 udelay(50);
356 tlv320aic23_write(codec, TLV320AIC23_ACTIVE, 0x0);
357 }
358}
359
360static int tlv320aic23_mute(struct snd_soc_dai *dai, int mute)
361{
362 struct snd_soc_codec *codec = dai->codec;
363 u16 reg;
364
365 reg = tlv320aic23_read_reg_cache(codec, TLV320AIC23_DIGT);
366 if (mute)
367 reg |= TLV320AIC23_DACM_MUTE;
368
369 else
370 reg &= ~TLV320AIC23_DACM_MUTE;
371
372 tlv320aic23_write(codec, TLV320AIC23_DIGT, reg);
373
374 return 0;
375}
376
377static int tlv320aic23_set_dai_fmt(struct snd_soc_dai *codec_dai,
378 unsigned int fmt)
379{
380 struct snd_soc_codec *codec = codec_dai->codec;
381 u16 iface_reg;
382
383 iface_reg =
384 tlv320aic23_read_reg_cache(codec, TLV320AIC23_DIGT_FMT) & (~0x03);
385
386 /* set master/slave audio interface */
387 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
388 case SND_SOC_DAIFMT_CBM_CFM:
389 iface_reg |= TLV320AIC23_MS_MASTER;
390 break;
391 case SND_SOC_DAIFMT_CBS_CFS:
392 break;
393 default:
394 return -EINVAL;
395
396 }
397
398 /* interface format */
399 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
400 case SND_SOC_DAIFMT_I2S:
401 iface_reg |= TLV320AIC23_FOR_I2S;
402 break;
403 case SND_SOC_DAIFMT_DSP_A:
404 iface_reg |= TLV320AIC23_FOR_DSP;
405 break;
406 case SND_SOC_DAIFMT_RIGHT_J:
407 break;
408 case SND_SOC_DAIFMT_LEFT_J:
409 iface_reg |= TLV320AIC23_FOR_LJUST;
410 break;
411 default:
412 return -EINVAL;
413
414 }
415
416 tlv320aic23_write(codec, TLV320AIC23_DIGT_FMT, iface_reg);
417
418 return 0;
419}
420
421static int tlv320aic23_set_dai_sysclk(struct snd_soc_dai *codec_dai,
422 int clk_id, unsigned int freq, int dir)
423{
424 struct snd_soc_codec *codec = codec_dai->codec;
425
426 switch (freq) {
427 case 12000000:
428 return 0;
429 }
430 return -EINVAL;
431}
432
433static int tlv320aic23_set_bias_level(struct snd_soc_codec *codec,
434 enum snd_soc_bias_level level)
435{
436 u16 reg = tlv320aic23_read_reg_cache(codec, TLV320AIC23_PWR) & 0xff7f;
437
438 switch (level) {
439 case SND_SOC_BIAS_ON:
440 /* vref/mid, osc on, dac unmute */
441 tlv320aic23_write(codec, TLV320AIC23_PWR, reg);
442 break;
443 case SND_SOC_BIAS_PREPARE:
444 break;
445 case SND_SOC_BIAS_STANDBY:
446 /* everything off except vref/vmid, */
447 tlv320aic23_write(codec, TLV320AIC23_PWR, reg | 0x0040);
448 break;
449 case SND_SOC_BIAS_OFF:
450 /* everything off, dac mute, inactive */
451 tlv320aic23_write(codec, TLV320AIC23_ACTIVE, 0x0);
452 tlv320aic23_write(codec, TLV320AIC23_PWR, 0xffff);
453 break;
454 }
455 codec->bias_level = level;
456 return 0;
457}
458
459#define AIC23_RATES SNDRV_PCM_RATE_8000_96000
460#define AIC23_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
461 SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE)
462
463struct snd_soc_dai tlv320aic23_dai = {
464 .name = "tlv320aic23",
465 .playback = {
466 .stream_name = "Playback",
467 .channels_min = 2,
468 .channels_max = 2,
469 .rates = AIC23_RATES,
470 .formats = AIC23_FORMATS,},
471 .capture = {
472 .stream_name = "Capture",
473 .channels_min = 2,
474 .channels_max = 2,
475 .rates = AIC23_RATES,
476 .formats = AIC23_FORMATS,},
477 .ops = {
478 .prepare = tlv320aic23_pcm_prepare,
479 .hw_params = tlv320aic23_hw_params,
480 .shutdown = tlv320aic23_shutdown,
481 },
482 .dai_ops = {
483 .digital_mute = tlv320aic23_mute,
484 .set_fmt = tlv320aic23_set_dai_fmt,
485 .set_sysclk = tlv320aic23_set_dai_sysclk,
486 }
487};
488EXPORT_SYMBOL_GPL(tlv320aic23_dai);
489
490static int tlv320aic23_suspend(struct platform_device *pdev,
491 pm_message_t state)
492{
493 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
494 struct snd_soc_codec *codec = socdev->codec;
495
496 tlv320aic23_write(codec, TLV320AIC23_ACTIVE, 0x0);
497 tlv320aic23_set_bias_level(codec, SND_SOC_BIAS_OFF);
498
499 return 0;
500}
501
502static int tlv320aic23_resume(struct platform_device *pdev)
503{
504 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
505 struct snd_soc_codec *codec = socdev->codec;
506 int i;
507 u16 reg;
508
509 /* Sync reg_cache with the hardware */
510 for (reg = 0; reg < ARRAY_SIZE(tlv320aic23_reg); i++) {
511 u16 val = tlv320aic23_read_reg_cache(codec, reg);
512 tlv320aic23_write(codec, reg, val);
513 }
514
515 tlv320aic23_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
516 tlv320aic23_set_bias_level(codec, codec->suspend_bias_level);
517
518 return 0;
519}
520
521/*
522 * initialise the AIC23 driver
523 * register the mixer and dsp interfaces with the kernel
524 */
525static int tlv320aic23_init(struct snd_soc_device *socdev)
526{
527 struct snd_soc_codec *codec = socdev->codec;
528 int ret = 0;
529 u16 reg;
530
531 codec->name = "tlv320aic23";
532 codec->owner = THIS_MODULE;
533 codec->read = tlv320aic23_read_reg_cache;
534 codec->write = tlv320aic23_write;
535 codec->set_bias_level = tlv320aic23_set_bias_level;
536 codec->dai = &tlv320aic23_dai;
537 codec->num_dai = 1;
538 codec->reg_cache_size = ARRAY_SIZE(tlv320aic23_reg);
539 codec->reg_cache =
540 kmemdup(tlv320aic23_reg, sizeof(tlv320aic23_reg), GFP_KERNEL);
541 if (codec->reg_cache == NULL)
542 return -ENOMEM;
543
544 /* Reset codec */
545 tlv320aic23_write(codec, TLV320AIC23_RESET, 0);
546
547 /* register pcms */
548 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
549 if (ret < 0) {
550 printk(KERN_ERR "tlv320aic23: failed to create pcms\n");
551 goto pcm_err;
552 }
553
554 /* power on device */
555 tlv320aic23_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
556
557 tlv320aic23_write(codec, TLV320AIC23_DIGT, TLV320AIC23_DEEMP_44K);
558
559 /* Unmute input */
560 reg = tlv320aic23_read_reg_cache(codec, TLV320AIC23_LINVOL);
561 tlv320aic23_write(codec, TLV320AIC23_LINVOL,
562 (reg & (~TLV320AIC23_LIM_MUTED)) |
563 (TLV320AIC23_LRS_ENABLED));
564
565 reg = tlv320aic23_read_reg_cache(codec, TLV320AIC23_RINVOL);
566 tlv320aic23_write(codec, TLV320AIC23_RINVOL,
567 (reg & (~TLV320AIC23_LIM_MUTED)) |
568 TLV320AIC23_LRS_ENABLED);
569
570 reg = tlv320aic23_read_reg_cache(codec, TLV320AIC23_ANLG);
571 tlv320aic23_write(codec, TLV320AIC23_ANLG,
572 (reg) & (~TLV320AIC23_BYPASS_ON) &
573 (~TLV320AIC23_MICM_MUTED));
574
575 /* Default output volume */
576 tlv320aic23_write(codec, TLV320AIC23_LCHNVOL,
577 TLV320AIC23_DEFAULT_OUT_VOL &
578 TLV320AIC23_OUT_VOL_MASK);
579 tlv320aic23_write(codec, TLV320AIC23_RCHNVOL,
580 TLV320AIC23_DEFAULT_OUT_VOL &
581 TLV320AIC23_OUT_VOL_MASK);
582
583 tlv320aic23_write(codec, TLV320AIC23_ACTIVE, 0x1);
584
585 tlv320aic23_add_controls(codec);
586 tlv320aic23_add_widgets(codec);
587 ret = snd_soc_register_card(socdev);
588 if (ret < 0) {
589 printk(KERN_ERR "tlv320aic23: failed to register card\n");
590 goto card_err;
591 }
592
593 return ret;
594
595card_err:
596 snd_soc_free_pcms(socdev);
597 snd_soc_dapm_free(socdev);
598pcm_err:
599 kfree(codec->reg_cache);
600 return ret;
601}
602static struct snd_soc_device *tlv320aic23_socdev;
603
604#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
605/*
606 * If the i2c layer weren't so broken, we could pass this kind of data
607 * around
608 */
609static int tlv320aic23_codec_probe(struct i2c_client *i2c,
610 const struct i2c_device_id *i2c_id)
611{
612 struct snd_soc_device *socdev = tlv320aic23_socdev;
613 struct snd_soc_codec *codec = socdev->codec;
614 int ret;
615
616 if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
617 return -EINVAL;
618
619 i2c_set_clientdata(i2c, codec);
620 codec->control_data = i2c;
621
622 ret = tlv320aic23_init(socdev);
623 if (ret < 0) {
624 printk(KERN_ERR "tlv320aic23: failed to initialise AIC23\n");
625 goto err;
626 }
627 return ret;
628
629err:
630 kfree(codec);
631 kfree(i2c);
632 return ret;
633}
634static int __exit tlv320aic23_i2c_remove(struct i2c_client *i2c)
635{
636 put_device(&i2c->dev);
637 return 0;
638}
639
640static const struct i2c_device_id tlv320aic23_id[] = {
641 {"tlv320aic23", 0},
642 {}
643};
644
645MODULE_DEVICE_TABLE(i2c, tlv320aic23_id);
646
647static struct i2c_driver tlv320aic23_i2c_driver = {
648 .driver = {
649 .name = "tlv320aic23",
650 },
651 .probe = tlv320aic23_codec_probe,
652 .remove = __exit_p(tlv320aic23_i2c_remove),
653 .id_table = tlv320aic23_id,
654};
655
656#endif
657
658static int tlv320aic23_probe(struct platform_device *pdev)
659{
660 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
661 struct snd_soc_codec *codec;
662 int ret = 0;
663
664 printk(KERN_INFO "AIC23 Audio Codec %s\n", AIC23_VERSION);
665
666 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
667 if (codec == NULL)
668 return -ENOMEM;
669
670 socdev->codec = codec;
671 mutex_init(&codec->mutex);
672 INIT_LIST_HEAD(&codec->dapm_widgets);
673 INIT_LIST_HEAD(&codec->dapm_paths);
674
675 tlv320aic23_socdev = socdev;
676#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
677 codec->hw_write = (hw_write_t) i2c_smbus_write_byte_data;
678 codec->hw_read = NULL;
679 ret = i2c_add_driver(&tlv320aic23_i2c_driver);
680 if (ret != 0)
681 printk(KERN_ERR "can't add i2c driver");
682#endif
683 return ret;
684}
685
686static int tlv320aic23_remove(struct platform_device *pdev)
687{
688 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
689 struct snd_soc_codec *codec = socdev->codec;
690
691 if (codec->control_data)
692 tlv320aic23_set_bias_level(codec, SND_SOC_BIAS_OFF);
693
694 snd_soc_free_pcms(socdev);
695 snd_soc_dapm_free(socdev);
696#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
697 i2c_del_driver(&tlv320aic23_i2c_driver);
698#endif
699 kfree(codec->reg_cache);
700 kfree(codec);
701
702 return 0;
703}
704struct snd_soc_codec_device soc_codec_dev_tlv320aic23 = {
705 .probe = tlv320aic23_probe,
706 .remove = tlv320aic23_remove,
707 .suspend = tlv320aic23_suspend,
708 .resume = tlv320aic23_resume,
709};
710EXPORT_SYMBOL_GPL(soc_codec_dev_tlv320aic23);
711
712MODULE_DESCRIPTION("ASoC TLV320AIC23 codec driver");
713MODULE_AUTHOR("Arun KS <arunks@mistralsolutions.com>");
714MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/tlv320aic23.h b/sound/soc/codecs/tlv320aic23.h
new file mode 100644
index 000000000000..79d1faf8e570
--- /dev/null
+++ b/sound/soc/codecs/tlv320aic23.h
@@ -0,0 +1,122 @@
1/*
2 * ALSA SoC TLV320AIC23 codec driver
3 *
4 * Author: Arun KS, <arunks@mistralsolutions.com>
5 * Copyright: (C) 2008 Mistral Solutions Pvt Ltd
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#ifndef _TLV320AIC23_H
13#define _TLV320AIC23_H
14
15/* Codec TLV320AIC23 */
16#define TLV320AIC23_LINVOL 0x00
17#define TLV320AIC23_RINVOL 0x01
18#define TLV320AIC23_LCHNVOL 0x02
19#define TLV320AIC23_RCHNVOL 0x03
20#define TLV320AIC23_ANLG 0x04
21#define TLV320AIC23_DIGT 0x05
22#define TLV320AIC23_PWR 0x06
23#define TLV320AIC23_DIGT_FMT 0x07
24#define TLV320AIC23_SRATE 0x08
25#define TLV320AIC23_ACTIVE 0x09
26#define TLV320AIC23_RESET 0x0F
27
28/* Left (right) line input volume control register */
29#define TLV320AIC23_LRS_ENABLED 0x0100
30#define TLV320AIC23_LIM_MUTED 0x0080
31#define TLV320AIC23_LIV_DEFAULT 0x0017
32#define TLV320AIC23_LIV_MAX 0x001f
33#define TLV320AIC23_LIV_MIN 0x0000
34
35/* Left (right) channel headphone volume control register */
36#define TLV320AIC23_LZC_ON 0x0080
37#define TLV320AIC23_LHV_DEFAULT 0x0079
38#define TLV320AIC23_LHV_MAX 0x007f
39#define TLV320AIC23_LHV_MIN 0x0000
40
41/* Analog audio path control register */
42#define TLV320AIC23_STA_REG(x) ((x)<<6)
43#define TLV320AIC23_STE_ENABLED 0x0020
44#define TLV320AIC23_DAC_SELECTED 0x0010
45#define TLV320AIC23_BYPASS_ON 0x0008
46#define TLV320AIC23_INSEL_MIC 0x0004
47#define TLV320AIC23_MICM_MUTED 0x0002
48#define TLV320AIC23_MICB_20DB 0x0001
49
50/* Digital audio path control register */
51#define TLV320AIC23_DACM_MUTE 0x0008
52#define TLV320AIC23_DEEMP_32K 0x0002
53#define TLV320AIC23_DEEMP_44K 0x0004
54#define TLV320AIC23_DEEMP_48K 0x0006
55#define TLV320AIC23_ADCHP_ON 0x0001
56
57/* Power control down register */
58#define TLV320AIC23_DEVICE_PWR_OFF 0x0080
59#define TLV320AIC23_CLK_OFF 0x0040
60#define TLV320AIC23_OSC_OFF 0x0020
61#define TLV320AIC23_OUT_OFF 0x0010
62#define TLV320AIC23_DAC_OFF 0x0008
63#define TLV320AIC23_ADC_OFF 0x0004
64#define TLV320AIC23_MIC_OFF 0x0002
65#define TLV320AIC23_LINE_OFF 0x0001
66
67/* Digital audio interface register */
68#define TLV320AIC23_MS_MASTER 0x0040
69#define TLV320AIC23_LRSWAP_ON 0x0020
70#define TLV320AIC23_LRP_ON 0x0010
71#define TLV320AIC23_IWL_16 0x0000
72#define TLV320AIC23_IWL_20 0x0004
73#define TLV320AIC23_IWL_24 0x0008
74#define TLV320AIC23_IWL_32 0x000C
75#define TLV320AIC23_FOR_I2S 0x0002
76#define TLV320AIC23_FOR_DSP 0x0003
77#define TLV320AIC23_FOR_LJUST 0x0001
78
79/* Sample rate control register */
80#define TLV320AIC23_CLKOUT_HALF 0x0080
81#define TLV320AIC23_CLKIN_HALF 0x0040
82#define TLV320AIC23_BOSR_384fs 0x0002 /* BOSR_272fs in USB mode */
83#define TLV320AIC23_USB_CLK_ON 0x0001
84#define TLV320AIC23_SR_MASK 0xf
85#define TLV320AIC23_CLKOUT_SHIFT 7
86#define TLV320AIC23_CLKIN_SHIFT 6
87#define TLV320AIC23_SR_SHIFT 2
88#define TLV320AIC23_BOSR_SHIFT 1
89
90/* Digital interface register */
91#define TLV320AIC23_ACT_ON 0x0001
92
93/*
94 * AUDIO related MACROS
95 */
96
97#define TLV320AIC23_DEFAULT_OUT_VOL 0x70
98#define TLV320AIC23_DEFAULT_IN_VOLUME 0x10
99
100#define TLV320AIC23_OUT_VOL_MIN TLV320AIC23_LHV_MIN
101#define TLV320AIC23_OUT_VOL_MAX TLV320AIC23_LHV_MAX
102#define TLV320AIC23_OUT_VO_RANGE (TLV320AIC23_OUT_VOL_MAX - \
103 TLV320AIC23_OUT_VOL_MIN)
104#define TLV320AIC23_OUT_VOL_MASK TLV320AIC23_OUT_VOL_MAX
105
106#define TLV320AIC23_IN_VOL_MIN TLV320AIC23_LIV_MIN
107#define TLV320AIC23_IN_VOL_MAX TLV320AIC23_LIV_MAX
108#define TLV320AIC23_IN_VOL_RANGE (TLV320AIC23_IN_VOL_MAX - \
109 TLV320AIC23_IN_VOL_MIN)
110#define TLV320AIC23_IN_VOL_MASK TLV320AIC23_IN_VOL_MAX
111
112#define TLV320AIC23_SIDETONE_MASK 0x1c0
113#define TLV320AIC23_SIDETONE_0 0x100
114#define TLV320AIC23_SIDETONE_6 0x000
115#define TLV320AIC23_SIDETONE_9 0x040
116#define TLV320AIC23_SIDETONE_12 0x080
117#define TLV320AIC23_SIDETONE_18 0x0c0
118
119extern struct snd_soc_dai tlv320aic23_dai;
120extern struct snd_soc_codec_device soc_codec_dev_tlv320aic23;
121
122#endif /* _TLV320AIC23_H */
diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c
index 566a427c928f..05336ed7e493 100644
--- a/sound/soc/codecs/tlv320aic3x.c
+++ b/sound/soc/codecs/tlv320aic3x.c
@@ -48,7 +48,6 @@
48 48
49#include "tlv320aic3x.h" 49#include "tlv320aic3x.h"
50 50
51#define AUDIO_NAME "aic3x"
52#define AIC3X_VERSION "0.2" 51#define AIC3X_VERSION "0.2"
53 52
54/* codec private data */ 53/* codec private data */
@@ -991,7 +990,7 @@ EXPORT_SYMBOL_GPL(aic3x_headset_detected);
991 SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE) 990 SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE)
992 991
993struct snd_soc_dai aic3x_dai = { 992struct snd_soc_dai aic3x_dai = {
994 .name = "aic3x", 993 .name = "tlv320aic3x",
995 .playback = { 994 .playback = {
996 .stream_name = "Playback", 995 .stream_name = "Playback",
997 .channels_min = 1, 996 .channels_min = 1,
@@ -1055,7 +1054,7 @@ static int aic3x_init(struct snd_soc_device *socdev)
1055 struct aic3x_setup_data *setup = socdev->codec_data; 1054 struct aic3x_setup_data *setup = socdev->codec_data;
1056 int reg, ret = 0; 1055 int reg, ret = 0;
1057 1056
1058 codec->name = "aic3x"; 1057 codec->name = "tlv320aic3x";
1059 codec->owner = THIS_MODULE; 1058 codec->owner = THIS_MODULE;
1060 codec->read = aic3x_read_reg_cache; 1059 codec->read = aic3x_read_reg_cache;
1061 codec->write = aic3x_write; 1060 codec->write = aic3x_write;
diff --git a/sound/soc/codecs/uda1380.c b/sound/soc/codecs/uda1380.c
index d206d7f892b6..a69ee72a7af5 100644
--- a/sound/soc/codecs/uda1380.c
+++ b/sound/soc/codecs/uda1380.c
@@ -36,7 +36,6 @@
36#include "uda1380.h" 36#include "uda1380.h"
37 37
38#define UDA1380_VERSION "0.6" 38#define UDA1380_VERSION "0.6"
39#define AUDIO_NAME "uda1380"
40 39
41/* 40/*
42 * uda1380 register cache 41 * uda1380 register cache
diff --git a/sound/soc/codecs/wm8510.c b/sound/soc/codecs/wm8510.c
index 9a37c8d95ed2..d8ca2da8d634 100644
--- a/sound/soc/codecs/wm8510.c
+++ b/sound/soc/codecs/wm8510.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * Copyright 2006 Wolfson Microelectronics PLC. 4 * Copyright 2006 Wolfson Microelectronics PLC.
5 * 5 *
6 * Author: Liam Girdwood <liam.girdwood@wolfsonmicro.com> 6 * Author: Liam Girdwood <lrg@slimlogic.co.uk>
7 * 7 *
8 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as 9 * it under the terms of the GNU General Public License version 2 as
@@ -18,6 +18,7 @@
18#include <linux/pm.h> 18#include <linux/pm.h>
19#include <linux/i2c.h> 19#include <linux/i2c.h>
20#include <linux/platform_device.h> 20#include <linux/platform_device.h>
21#include <linux/spi/spi.h>
21#include <sound/core.h> 22#include <sound/core.h>
22#include <sound/pcm.h> 23#include <sound/pcm.h>
23#include <sound/pcm_params.h> 24#include <sound/pcm_params.h>
@@ -27,7 +28,6 @@
27 28
28#include "wm8510.h" 29#include "wm8510.h"
29 30
30#define AUDIO_NAME "wm8510"
31#define WM8510_VERSION "0.6" 31#define WM8510_VERSION "0.6"
32 32
33struct snd_soc_codec_device soc_codec_dev_wm8510; 33struct snd_soc_codec_device soc_codec_dev_wm8510;
@@ -55,6 +55,9 @@ static const u16 wm8510_reg[WM8510_CACHEREGNUM] = {
55 0x0001, 55 0x0001,
56}; 56};
57 57
58#define WM8510_POWER1_BIASEN 0x08
59#define WM8510_POWER1_BUFIOEN 0x10
60
58/* 61/*
59 * read wm8510 register cache 62 * read wm8510 register cache
60 */ 63 */
@@ -224,9 +227,9 @@ SND_SOC_DAPM_PGA("SpkN Out", WM8510_POWER3, 5, 0, NULL, 0),
224SND_SOC_DAPM_PGA("SpkP Out", WM8510_POWER3, 6, 0, NULL, 0), 227SND_SOC_DAPM_PGA("SpkP Out", WM8510_POWER3, 6, 0, NULL, 0),
225SND_SOC_DAPM_PGA("Mono Out", WM8510_POWER3, 7, 0, NULL, 0), 228SND_SOC_DAPM_PGA("Mono Out", WM8510_POWER3, 7, 0, NULL, 0),
226 229
227SND_SOC_DAPM_PGA("Mic PGA", WM8510_POWER2, 2, 0, 230SND_SOC_DAPM_MIXER("Mic PGA", WM8510_POWER2, 2, 0,
228 &wm8510_micpga_controls[0], 231 &wm8510_micpga_controls[0],
229 ARRAY_SIZE(wm8510_micpga_controls)), 232 ARRAY_SIZE(wm8510_micpga_controls)),
230SND_SOC_DAPM_MIXER("Boost Mixer", WM8510_POWER2, 4, 0, 233SND_SOC_DAPM_MIXER("Boost Mixer", WM8510_POWER2, 4, 0,
231 &wm8510_boost_controls[0], 234 &wm8510_boost_controls[0],
232 ARRAY_SIZE(wm8510_boost_controls)), 235 ARRAY_SIZE(wm8510_boost_controls)),
@@ -526,23 +529,35 @@ static int wm8510_mute(struct snd_soc_dai *dai, int mute)
526static int wm8510_set_bias_level(struct snd_soc_codec *codec, 529static int wm8510_set_bias_level(struct snd_soc_codec *codec,
527 enum snd_soc_bias_level level) 530 enum snd_soc_bias_level level)
528{ 531{
532 u16 power1 = wm8510_read_reg_cache(codec, WM8510_POWER1) & ~0x3;
529 533
530 switch (level) { 534 switch (level) {
531 case SND_SOC_BIAS_ON: 535 case SND_SOC_BIAS_ON:
532 wm8510_write(codec, WM8510_POWER1, 0x1ff);
533 wm8510_write(codec, WM8510_POWER2, 0x1ff);
534 wm8510_write(codec, WM8510_POWER3, 0x1ff);
535 break;
536 case SND_SOC_BIAS_PREPARE: 536 case SND_SOC_BIAS_PREPARE:
537 power1 |= 0x1; /* VMID 50k */
538 wm8510_write(codec, WM8510_POWER1, power1);
539 break;
540
537 case SND_SOC_BIAS_STANDBY: 541 case SND_SOC_BIAS_STANDBY:
542 power1 |= WM8510_POWER1_BIASEN | WM8510_POWER1_BUFIOEN;
543
544 if (codec->bias_level == SND_SOC_BIAS_OFF) {
545 /* Initial cap charge at VMID 5k */
546 wm8510_write(codec, WM8510_POWER1, power1 | 0x3);
547 mdelay(100);
548 }
549
550 power1 |= 0x2; /* VMID 500k */
551 wm8510_write(codec, WM8510_POWER1, power1);
538 break; 552 break;
553
539 case SND_SOC_BIAS_OFF: 554 case SND_SOC_BIAS_OFF:
540 /* everything off, dac mute, inactive */ 555 wm8510_write(codec, WM8510_POWER1, 0);
541 wm8510_write(codec, WM8510_POWER1, 0x0); 556 wm8510_write(codec, WM8510_POWER2, 0);
542 wm8510_write(codec, WM8510_POWER2, 0x0); 557 wm8510_write(codec, WM8510_POWER3, 0);
543 wm8510_write(codec, WM8510_POWER3, 0x0);
544 break; 558 break;
545 } 559 }
560
546 codec->bias_level = level; 561 codec->bias_level = level;
547 return 0; 562 return 0;
548} 563}
@@ -640,6 +655,7 @@ static int wm8510_init(struct snd_soc_device *socdev)
640 } 655 }
641 656
642 /* power on device */ 657 /* power on device */
658 codec->bias_level = SND_SOC_BIAS_OFF;
643 wm8510_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 659 wm8510_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
644 wm8510_add_controls(codec); 660 wm8510_add_controls(codec);
645 wm8510_add_widgets(codec); 661 wm8510_add_widgets(codec);
@@ -747,6 +763,62 @@ err_driver:
747} 763}
748#endif 764#endif
749 765
766#if defined(CONFIG_SPI_MASTER)
767static int __devinit wm8510_spi_probe(struct spi_device *spi)
768{
769 struct snd_soc_device *socdev = wm8510_socdev;
770 struct snd_soc_codec *codec = socdev->codec;
771 int ret;
772
773 codec->control_data = spi;
774
775 ret = wm8510_init(socdev);
776 if (ret < 0)
777 dev_err(&spi->dev, "failed to initialise WM8510\n");
778
779 return ret;
780}
781
782static int __devexit wm8510_spi_remove(struct spi_device *spi)
783{
784 return 0;
785}
786
787static struct spi_driver wm8510_spi_driver = {
788 .driver = {
789 .name = "wm8510",
790 .bus = &spi_bus_type,
791 .owner = THIS_MODULE,
792 },
793 .probe = wm8510_spi_probe,
794 .remove = __devexit_p(wm8510_spi_remove),
795};
796
797static int wm8510_spi_write(struct spi_device *spi, const char *data, int len)
798{
799 struct spi_transfer t;
800 struct spi_message m;
801 u8 msg[2];
802
803 if (len <= 0)
804 return 0;
805
806 msg[0] = data[0];
807 msg[1] = data[1];
808
809 spi_message_init(&m);
810 memset(&t, 0, (sizeof t));
811
812 t.tx_buf = &msg[0];
813 t.len = len;
814
815 spi_message_add_tail(&t, &m);
816 spi_sync(spi, &m);
817
818 return len;
819}
820#endif /* CONFIG_SPI_MASTER */
821
750static int wm8510_probe(struct platform_device *pdev) 822static int wm8510_probe(struct platform_device *pdev)
751{ 823{
752 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 824 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
@@ -772,8 +844,14 @@ static int wm8510_probe(struct platform_device *pdev)
772 codec->hw_write = (hw_write_t)i2c_master_send; 844 codec->hw_write = (hw_write_t)i2c_master_send;
773 ret = wm8510_add_i2c_device(pdev, setup); 845 ret = wm8510_add_i2c_device(pdev, setup);
774 } 846 }
775#else 847#endif
776 /* Add other interfaces here */ 848#if defined(CONFIG_SPI_MASTER)
849 if (setup->spi) {
850 codec->hw_write = (hw_write_t)wm8510_spi_write;
851 ret = spi_register_driver(&wm8510_spi_driver);
852 if (ret != 0)
853 printk(KERN_ERR "can't add spi driver");
854 }
777#endif 855#endif
778 856
779 if (ret != 0) 857 if (ret != 0)
@@ -796,6 +874,9 @@ static int wm8510_remove(struct platform_device *pdev)
796 i2c_unregister_device(codec->control_data); 874 i2c_unregister_device(codec->control_data);
797 i2c_del_driver(&wm8510_i2c_driver); 875 i2c_del_driver(&wm8510_i2c_driver);
798#endif 876#endif
877#if defined(CONFIG_SPI_MASTER)
878 spi_unregister_driver(&wm8510_spi_driver);
879#endif
799 kfree(codec); 880 kfree(codec);
800 881
801 return 0; 882 return 0;
diff --git a/sound/soc/codecs/wm8510.h b/sound/soc/codecs/wm8510.h
index c53683960456..bdefcf5c69ff 100644
--- a/sound/soc/codecs/wm8510.h
+++ b/sound/soc/codecs/wm8510.h
@@ -94,6 +94,7 @@
94#define WM8510_MCLKDIV_12 (7 << 5) 94#define WM8510_MCLKDIV_12 (7 << 5)
95 95
96struct wm8510_setup_data { 96struct wm8510_setup_data {
97 int spi;
97 int i2c_bus; 98 int i2c_bus;
98 unsigned short i2c_address; 99 unsigned short i2c_address;
99}; 100};
diff --git a/sound/soc/codecs/wm8580.c b/sound/soc/codecs/wm8580.c
index df1ffbe305bf..627ebfb4209b 100644
--- a/sound/soc/codecs/wm8580.c
+++ b/sound/soc/codecs/wm8580.c
@@ -18,7 +18,6 @@
18 18
19#include <linux/module.h> 19#include <linux/module.h>
20#include <linux/moduleparam.h> 20#include <linux/moduleparam.h>
21#include <linux/version.h>
22#include <linux/kernel.h> 21#include <linux/kernel.h>
23#include <linux/init.h> 22#include <linux/init.h>
24#include <linux/delay.h> 23#include <linux/delay.h>
@@ -36,7 +35,6 @@
36 35
37#include "wm8580.h" 36#include "wm8580.h"
38 37
39#define AUDIO_NAME "wm8580"
40#define WM8580_VERSION "0.1" 38#define WM8580_VERSION "0.1"
41 39
42struct pll_state { 40struct pll_state {
diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c
index 7b64d9a7ff76..7f8a7e36b33e 100644
--- a/sound/soc/codecs/wm8731.c
+++ b/sound/soc/codecs/wm8731.c
@@ -29,7 +29,6 @@
29 29
30#include "wm8731.h" 30#include "wm8731.h"
31 31
32#define AUDIO_NAME "wm8731"
33#define WM8731_VERSION "0.13" 32#define WM8731_VERSION "0.13"
34 33
35struct snd_soc_codec_device soc_codec_dev_wm8731; 34struct snd_soc_codec_device soc_codec_dev_wm8731;
diff --git a/sound/soc/codecs/wm8750.c b/sound/soc/codecs/wm8750.c
index 4892e398a598..9b7296ee5b08 100644
--- a/sound/soc/codecs/wm8750.c
+++ b/sound/soc/codecs/wm8750.c
@@ -29,7 +29,6 @@
29 29
30#include "wm8750.h" 30#include "wm8750.h"
31 31
32#define AUDIO_NAME "WM8750"
33#define WM8750_VERSION "0.12" 32#define WM8750_VERSION "0.12"
34 33
35/* codec private data */ 34/* codec private data */
diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c
index 8c4df44f3345..d426eaa22185 100644
--- a/sound/soc/codecs/wm8753.c
+++ b/sound/soc/codecs/wm8753.c
@@ -2,8 +2,7 @@
2 * wm8753.c -- WM8753 ALSA Soc Audio driver 2 * wm8753.c -- WM8753 ALSA Soc Audio driver
3 * 3 *
4 * Copyright 2003 Wolfson Microelectronics PLC. 4 * Copyright 2003 Wolfson Microelectronics PLC.
5 * Author: Liam Girdwood 5 * Author: Liam Girdwood <lrg@slimlogic.co.uk>
6 * liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com
7 * 6 *
8 * This program is free software; you can redistribute it and/or modify it 7 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the 8 * under the terms of the GNU General Public License as published by the
@@ -40,6 +39,7 @@
40#include <linux/pm.h> 39#include <linux/pm.h>
41#include <linux/i2c.h> 40#include <linux/i2c.h>
42#include <linux/platform_device.h> 41#include <linux/platform_device.h>
42#include <linux/spi/spi.h>
43#include <sound/core.h> 43#include <sound/core.h>
44#include <sound/pcm.h> 44#include <sound/pcm.h>
45#include <sound/pcm_params.h> 45#include <sound/pcm_params.h>
@@ -51,7 +51,6 @@
51 51
52#include "wm8753.h" 52#include "wm8753.h"
53 53
54#define AUDIO_NAME "wm8753"
55#define WM8753_VERSION "0.16" 54#define WM8753_VERSION "0.16"
56 55
57static int caps_charge = 2000; 56static int caps_charge = 2000;
@@ -1719,6 +1718,63 @@ err_driver:
1719} 1718}
1720#endif 1719#endif
1721 1720
1721#if defined(CONFIG_SPI_MASTER)
1722static int __devinit wm8753_spi_probe(struct spi_device *spi)
1723{
1724 struct snd_soc_device *socdev = wm8753_socdev;
1725 struct snd_soc_codec *codec = socdev->codec;
1726 int ret;
1727
1728 codec->control_data = spi;
1729
1730 ret = wm8753_init(socdev);
1731 if (ret < 0)
1732 dev_err(&spi->dev, "failed to initialise WM8753\n");
1733
1734 return ret;
1735}
1736
1737static int __devexit wm8753_spi_remove(struct spi_device *spi)
1738{
1739 return 0;
1740}
1741
1742static struct spi_driver wm8753_spi_driver = {
1743 .driver = {
1744 .name = "wm8753",
1745 .bus = &spi_bus_type,
1746 .owner = THIS_MODULE,
1747 },
1748 .probe = wm8753_spi_probe,
1749 .remove = __devexit_p(wm8753_spi_remove),
1750};
1751
1752static int wm8753_spi_write(struct spi_device *spi, const char *data, int len)
1753{
1754 struct spi_transfer t;
1755 struct spi_message m;
1756 u8 msg[2];
1757
1758 if (len <= 0)
1759 return 0;
1760
1761 msg[0] = data[0];
1762 msg[1] = data[1];
1763
1764 spi_message_init(&m);
1765 memset(&t, 0, (sizeof t));
1766
1767 t.tx_buf = &msg[0];
1768 t.len = len;
1769
1770 spi_message_add_tail(&t, &m);
1771 spi_sync(spi, &m);
1772
1773 return len;
1774}
1775#endif
1776
1777
1722static int wm8753_probe(struct platform_device *pdev) 1778static int wm8753_probe(struct platform_device *pdev)
1723{ 1779{
1724 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 1780 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
@@ -1753,8 +1809,14 @@ static int wm8753_probe(struct platform_device *pdev)
1753 codec->hw_write = (hw_write_t)i2c_master_send; 1809 codec->hw_write = (hw_write_t)i2c_master_send;
1754 ret = wm8753_add_i2c_device(pdev, setup); 1810 ret = wm8753_add_i2c_device(pdev, setup);
1755 } 1811 }
1756#else 1812#endif
1757 /* Add other interfaces here */ 1813#if defined(CONFIG_SPI_MASTER)
1814 if (setup->spi) {
1815 codec->hw_write = (hw_write_t)wm8753_spi_write;
1816 ret = spi_register_driver(&wm8753_spi_driver);
1817 if (ret != 0)
1818 printk(KERN_ERR "can't add spi driver");
1819 }
1758#endif 1820#endif
1759 1821
1760 if (ret != 0) { 1822 if (ret != 0) {
@@ -1798,6 +1860,9 @@ static int wm8753_remove(struct platform_device *pdev)
1798 i2c_unregister_device(codec->control_data); 1860 i2c_unregister_device(codec->control_data);
1799 i2c_del_driver(&wm8753_i2c_driver); 1861 i2c_del_driver(&wm8753_i2c_driver);
1800#endif 1862#endif
1863#if defined(CONFIG_SPI_MASTER)
1864 spi_unregister_driver(&wm8753_spi_driver);
1865#endif
1801 kfree(codec->private_data); 1866 kfree(codec->private_data);
1802 kfree(codec); 1867 kfree(codec);
1803 1868
diff --git a/sound/soc/codecs/wm8753.h b/sound/soc/codecs/wm8753.h
index 7defde069f1d..f55704ce931b 100644
--- a/sound/soc/codecs/wm8753.h
+++ b/sound/soc/codecs/wm8753.h
@@ -2,8 +2,7 @@
2 * wm8753.h -- audio driver for WM8753 2 * wm8753.h -- audio driver for WM8753
3 * 3 *
4 * Copyright 2003 Wolfson Microelectronics PLC. 4 * Copyright 2003 Wolfson Microelectronics PLC.
5 * Author: Liam Girdwood 5 * Author: Liam Girdwood <lrg@slimlogic.co.uk>
6 * liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com
7 * 6 *
8 * This program is free software; you can redistribute it and/or modify it 7 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the 8 * under the terms of the GNU General Public License as published by the
@@ -79,6 +78,7 @@
79#define WM8753_ADCTL2 0x3f 78#define WM8753_ADCTL2 0x3f
80 79
81struct wm8753_setup_data { 80struct wm8753_setup_data {
81 int spi;
82 int i2c_bus; 82 int i2c_bus;
83 unsigned short i2c_address; 83 unsigned short i2c_address;
84}; 84};
diff --git a/sound/soc/codecs/wm8900.c b/sound/soc/codecs/wm8900.c
index 0b8c6d38b48f..3b326c9b5586 100644
--- a/sound/soc/codecs/wm8900.c
+++ b/sound/soc/codecs/wm8900.c
@@ -18,7 +18,6 @@
18 18
19#include <linux/module.h> 19#include <linux/module.h>
20#include <linux/moduleparam.h> 20#include <linux/moduleparam.h>
21#include <linux/version.h>
22#include <linux/kernel.h> 21#include <linux/kernel.h>
23#include <linux/init.h> 22#include <linux/init.h>
24#include <linux/delay.h> 23#include <linux/delay.h>
diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c
index a3f54ec4226e..ce40d7877605 100644
--- a/sound/soc/codecs/wm8903.c
+++ b/sound/soc/codecs/wm8903.c
@@ -653,14 +653,14 @@ static const struct snd_kcontrol_new wm8903_snd_controls[] = {
653 653
654/* Input PGAs - No TLV since the scale depends on PGA mode */ 654/* Input PGAs - No TLV since the scale depends on PGA mode */
655SOC_SINGLE("Left Input PGA Switch", WM8903_ANALOGUE_LEFT_INPUT_0, 655SOC_SINGLE("Left Input PGA Switch", WM8903_ANALOGUE_LEFT_INPUT_0,
656 7, 1, 0), 656 7, 1, 1),
657SOC_SINGLE("Left Input PGA Volume", WM8903_ANALOGUE_LEFT_INPUT_0, 657SOC_SINGLE("Left Input PGA Volume", WM8903_ANALOGUE_LEFT_INPUT_0,
658 0, 31, 0), 658 0, 31, 0),
659SOC_SINGLE("Left Input PGA Common Mode Switch", WM8903_ANALOGUE_LEFT_INPUT_1, 659SOC_SINGLE("Left Input PGA Common Mode Switch", WM8903_ANALOGUE_LEFT_INPUT_1,
660 6, 1, 0), 660 6, 1, 0),
661 661
662SOC_SINGLE("Right Input PGA Switch", WM8903_ANALOGUE_RIGHT_INPUT_0, 662SOC_SINGLE("Right Input PGA Switch", WM8903_ANALOGUE_RIGHT_INPUT_0,
663 7, 1, 0), 663 7, 1, 1),
664SOC_SINGLE("Right Input PGA Volume", WM8903_ANALOGUE_RIGHT_INPUT_0, 664SOC_SINGLE("Right Input PGA Volume", WM8903_ANALOGUE_RIGHT_INPUT_0,
665 0, 31, 0), 665 0, 31, 0),
666SOC_SINGLE("Right Input PGA Common Mode Switch", WM8903_ANALOGUE_RIGHT_INPUT_1, 666SOC_SINGLE("Right Input PGA Common Mode Switch", WM8903_ANALOGUE_RIGHT_INPUT_1,
diff --git a/sound/soc/codecs/wm8971.c b/sound/soc/codecs/wm8971.c
index 974a4cd0f3fd..f41a578ddd4f 100644
--- a/sound/soc/codecs/wm8971.c
+++ b/sound/soc/codecs/wm8971.c
@@ -29,7 +29,6 @@
29 29
30#include "wm8971.h" 30#include "wm8971.h"
31 31
32#define AUDIO_NAME "wm8971"
33#define WM8971_VERSION "0.9" 32#define WM8971_VERSION "0.9"
34 33
35#define WM8971_REG_COUNT 43 34#define WM8971_REG_COUNT 43
diff --git a/sound/soc/codecs/wm8990.c b/sound/soc/codecs/wm8990.c
index 63410d7b5efb..572d22b0880b 100644
--- a/sound/soc/codecs/wm8990.c
+++ b/sound/soc/codecs/wm8990.c
@@ -30,7 +30,6 @@
30 30
31#include "wm8990.h" 31#include "wm8990.h"
32 32
33#define AUDIO_NAME "wm8990"
34#define WM8990_VERSION "0.2" 33#define WM8990_VERSION "0.2"
35 34
36/* codec private data */ 35/* codec private data */
diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c
index 2f1c91b1d556..ffb471e420e2 100644
--- a/sound/soc/codecs/wm9712.c
+++ b/sound/soc/codecs/wm9712.c
@@ -2,8 +2,7 @@
2 * wm9712.c -- ALSA Soc WM9712 codec support 2 * wm9712.c -- ALSA Soc WM9712 codec support
3 * 3 *
4 * Copyright 2006 Wolfson Microelectronics PLC. 4 * Copyright 2006 Wolfson Microelectronics PLC.
5 * Author: Liam Girdwood 5 * Author: Liam Girdwood <lrg@slimlogic.co.uk>
6 * liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com
7 * 6 *
8 * This program is free software; you can redistribute it and/or modify it 7 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the 8 * under the terms of the GNU General Public License as published by the
diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c
index 441d0580db1f..aba402b3c999 100644
--- a/sound/soc/codecs/wm9713.c
+++ b/sound/soc/codecs/wm9713.c
@@ -2,8 +2,7 @@
2 * wm9713.c -- ALSA Soc WM9713 codec support 2 * wm9713.c -- ALSA Soc WM9713 codec support
3 * 3 *
4 * Copyright 2006 Wolfson Microelectronics PLC. 4 * Copyright 2006 Wolfson Microelectronics PLC.
5 * Author: Liam Girdwood 5 * Author: Liam Girdwood <lrg@slimlogic.co.uk>
6 * liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com
7 * 6 *
8 * This program is free software; you can redistribute it and/or modify it 7 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the 8 * under the terms of the GNU General Public License as published by the
diff --git a/sound/soc/omap/Kconfig b/sound/soc/omap/Kconfig
index aea27e70043c..8b7766b998d7 100644
--- a/sound/soc/omap/Kconfig
+++ b/sound/soc/omap/Kconfig
@@ -13,3 +13,11 @@ config SND_OMAP_SOC_N810
13 select SND_SOC_TLV320AIC3X 13 select SND_SOC_TLV320AIC3X
14 help 14 help
15 Say Y if you want to add support for SoC audio on Nokia N810. 15 Say Y if you want to add support for SoC audio on Nokia N810.
16
17config SND_OMAP_SOC_OSK5912
18 tristate "SoC Audio support for omap osk5912"
19 depends on SND_OMAP_SOC && MACH_OMAP_OSK
20 select SND_OMAP_SOC_MCBSP
21 select SND_SOC_TLV320AIC23
22 help
23 Say Y if you want to add support for SoC audio on osk5912.
diff --git a/sound/soc/omap/Makefile b/sound/soc/omap/Makefile
index d8d8d58075e3..e09d1f297f64 100644
--- a/sound/soc/omap/Makefile
+++ b/sound/soc/omap/Makefile
@@ -7,5 +7,7 @@ obj-$(CONFIG_SND_OMAP_SOC_MCBSP) += snd-soc-omap-mcbsp.o
7 7
8# OMAP Machine Support 8# OMAP Machine Support
9snd-soc-n810-objs := n810.o 9snd-soc-n810-objs := n810.o
10snd-soc-osk5912-objs := osk5912.o
10 11
11obj-$(CONFIG_SND_OMAP_SOC_N810) += snd-soc-n810.o 12obj-$(CONFIG_SND_OMAP_SOC_N810) += snd-soc-n810.o
13obj-$(CONFIG_SND_OMAP_SOC_OSK5912) += snd-soc-osk5912.o
diff --git a/sound/soc/omap/n810.c b/sound/soc/omap/n810.c
index d166b6b2a60d..fae3ad36e0bf 100644
--- a/sound/soc/omap/n810.c
+++ b/sound/soc/omap/n810.c
@@ -247,9 +247,9 @@ static int n810_aic33_init(struct snd_soc_codec *codec)
247 int i, err; 247 int i, err;
248 248
249 /* Not connected */ 249 /* Not connected */
250 snd_soc_dapm_disable_pin(codec, "MONO_LOUT"); 250 snd_soc_dapm_nc_pin(codec, "MONO_LOUT");
251 snd_soc_dapm_disable_pin(codec, "HPLCOM"); 251 snd_soc_dapm_nc_pin(codec, "HPLCOM");
252 snd_soc_dapm_disable_pin(codec, "HPRCOM"); 252 snd_soc_dapm_nc_pin(codec, "HPRCOM");
253 253
254 /* Add N810 specific controls */ 254 /* Add N810 specific controls */
255 for (i = 0; i < ARRAY_SIZE(aic33_n810_controls); i++) { 255 for (i = 0; i < ARRAY_SIZE(aic33_n810_controls); i++) {
diff --git a/sound/soc/omap/omap-mcbsp.c b/sound/soc/omap/omap-mcbsp.c
index 35310e16d7f3..0a063a98a661 100644
--- a/sound/soc/omap/omap-mcbsp.c
+++ b/sound/soc/omap/omap-mcbsp.c
@@ -59,12 +59,7 @@ static struct omap_mcbsp_data mcbsp_data[NUM_LINKS];
59 * Stream DMA parameters. DMA request line and port address are set runtime 59 * Stream DMA parameters. DMA request line and port address are set runtime
60 * since they are different between OMAP1 and later OMAPs 60 * since they are different between OMAP1 and later OMAPs
61 */ 61 */
62static struct omap_pcm_dma_data omap_mcbsp_dai_dma_params[NUM_LINKS][2] = { 62static struct omap_pcm_dma_data omap_mcbsp_dai_dma_params[NUM_LINKS][2];
63{
64 { .name = "I2S PCM Stereo out", },
65 { .name = "I2S PCM Stereo in", },
66},
67};
68 63
69#if defined(CONFIG_ARCH_OMAP15XX) || defined(CONFIG_ARCH_OMAP16XX) 64#if defined(CONFIG_ARCH_OMAP15XX) || defined(CONFIG_ARCH_OMAP16XX)
70static const int omap1_dma_reqs[][2] = { 65static const int omap1_dma_reqs[][2] = {
@@ -84,11 +79,22 @@ static const unsigned long omap1_mcbsp_port[][2] = {
84static const int omap1_dma_reqs[][2] = {}; 79static const int omap1_dma_reqs[][2] = {};
85static const unsigned long omap1_mcbsp_port[][2] = {}; 80static const unsigned long omap1_mcbsp_port[][2] = {};
86#endif 81#endif
87#if defined(CONFIG_ARCH_OMAP2420) 82
88static const int omap2420_dma_reqs[][2] = { 83#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
84static const int omap24xx_dma_reqs[][2] = {
89 { OMAP24XX_DMA_MCBSP1_TX, OMAP24XX_DMA_MCBSP1_RX }, 85 { OMAP24XX_DMA_MCBSP1_TX, OMAP24XX_DMA_MCBSP1_RX },
90 { OMAP24XX_DMA_MCBSP2_TX, OMAP24XX_DMA_MCBSP2_RX }, 86 { OMAP24XX_DMA_MCBSP2_TX, OMAP24XX_DMA_MCBSP2_RX },
87#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP34XX)
88 { OMAP24XX_DMA_MCBSP3_TX, OMAP24XX_DMA_MCBSP3_RX },
89 { OMAP24XX_DMA_MCBSP4_TX, OMAP24XX_DMA_MCBSP4_RX },
90 { OMAP24XX_DMA_MCBSP5_TX, OMAP24XX_DMA_MCBSP5_RX },
91#endif
91}; 92};
93#else
94static const int omap24xx_dma_reqs[][2] = {};
95#endif
96
97#if defined(CONFIG_ARCH_OMAP2420)
92static const unsigned long omap2420_mcbsp_port[][2] = { 98static const unsigned long omap2420_mcbsp_port[][2] = {
93 { OMAP24XX_MCBSP1_BASE + OMAP_MCBSP_REG_DXR1, 99 { OMAP24XX_MCBSP1_BASE + OMAP_MCBSP_REG_DXR1,
94 OMAP24XX_MCBSP1_BASE + OMAP_MCBSP_REG_DRR1 }, 100 OMAP24XX_MCBSP1_BASE + OMAP_MCBSP_REG_DRR1 },
@@ -96,10 +102,43 @@ static const unsigned long omap2420_mcbsp_port[][2] = {
96 OMAP24XX_MCBSP2_BASE + OMAP_MCBSP_REG_DRR1 }, 102 OMAP24XX_MCBSP2_BASE + OMAP_MCBSP_REG_DRR1 },
97}; 103};
98#else 104#else
99static const int omap2420_dma_reqs[][2] = {};
100static const unsigned long omap2420_mcbsp_port[][2] = {}; 105static const unsigned long omap2420_mcbsp_port[][2] = {};
101#endif 106#endif
102 107
108#if defined(CONFIG_ARCH_OMAP2430)
109static const unsigned long omap2430_mcbsp_port[][2] = {
110 { OMAP24XX_MCBSP1_BASE + OMAP_MCBSP_REG_DXR,
111 OMAP24XX_MCBSP1_BASE + OMAP_MCBSP_REG_DRR },
112 { OMAP24XX_MCBSP2_BASE + OMAP_MCBSP_REG_DXR,
113 OMAP24XX_MCBSP2_BASE + OMAP_MCBSP_REG_DRR },
114 { OMAP2430_MCBSP3_BASE + OMAP_MCBSP_REG_DXR,
115 OMAP2430_MCBSP3_BASE + OMAP_MCBSP_REG_DRR },
116 { OMAP2430_MCBSP4_BASE + OMAP_MCBSP_REG_DXR,
117 OMAP2430_MCBSP4_BASE + OMAP_MCBSP_REG_DRR },
118 { OMAP2430_MCBSP5_BASE + OMAP_MCBSP_REG_DXR,
119 OMAP2430_MCBSP5_BASE + OMAP_MCBSP_REG_DRR },
120};
121#else
122static const unsigned long omap2430_mcbsp_port[][2] = {};
123#endif
124
125#if defined(CONFIG_ARCH_OMAP34XX)
126static const unsigned long omap34xx_mcbsp_port[][2] = {
127 { OMAP34XX_MCBSP1_BASE + OMAP_MCBSP_REG_DXR,
128 OMAP34XX_MCBSP1_BASE + OMAP_MCBSP_REG_DRR },
129 { OMAP34XX_MCBSP2_BASE + OMAP_MCBSP_REG_DXR,
130 OMAP34XX_MCBSP2_BASE + OMAP_MCBSP_REG_DRR },
131 { OMAP34XX_MCBSP3_BASE + OMAP_MCBSP_REG_DXR,
132 OMAP34XX_MCBSP3_BASE + OMAP_MCBSP_REG_DRR },
133 { OMAP34XX_MCBSP4_BASE + OMAP_MCBSP_REG_DXR,
134 OMAP34XX_MCBSP4_BASE + OMAP_MCBSP_REG_DRR },
135 { OMAP34XX_MCBSP5_BASE + OMAP_MCBSP_REG_DXR,
136 OMAP34XX_MCBSP5_BASE + OMAP_MCBSP_REG_DRR },
137};
138#else
139static const unsigned long omap34xx_mcbsp_port[][2] = {};
140#endif
141
103static int omap_mcbsp_dai_startup(struct snd_pcm_substream *substream) 142static int omap_mcbsp_dai_startup(struct snd_pcm_substream *substream)
104{ 143{
105 struct snd_soc_pcm_runtime *rtd = substream->private_data; 144 struct snd_soc_pcm_runtime *rtd = substream->private_data;
@@ -167,14 +206,19 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
167 dma = omap1_dma_reqs[bus_id][substream->stream]; 206 dma = omap1_dma_reqs[bus_id][substream->stream];
168 port = omap1_mcbsp_port[bus_id][substream->stream]; 207 port = omap1_mcbsp_port[bus_id][substream->stream];
169 } else if (cpu_is_omap2420()) { 208 } else if (cpu_is_omap2420()) {
170 dma = omap2420_dma_reqs[bus_id][substream->stream]; 209 dma = omap24xx_dma_reqs[bus_id][substream->stream];
171 port = omap2420_mcbsp_port[bus_id][substream->stream]; 210 port = omap2420_mcbsp_port[bus_id][substream->stream];
211 } else if (cpu_is_omap2430()) {
212 dma = omap24xx_dma_reqs[bus_id][substream->stream];
213 port = omap2430_mcbsp_port[bus_id][substream->stream];
214 } else if (cpu_is_omap343x()) {
215 dma = omap24xx_dma_reqs[bus_id][substream->stream];
216 port = omap34xx_mcbsp_port[bus_id][substream->stream];
172 } else { 217 } else {
173 /*
174 * TODO: Add support for 2430 and 3430
175 */
176 return -ENODEV; 218 return -ENODEV;
177 } 219 }
220 omap_mcbsp_dai_dma_params[id][substream->stream].name =
221 substream->stream ? "Audio Capture" : "Audio Playback";
178 omap_mcbsp_dai_dma_params[id][substream->stream].dma_req = dma; 222 omap_mcbsp_dai_dma_params[id][substream->stream].dma_req = dma;
179 omap_mcbsp_dai_dma_params[id][substream->stream].port_addr = port; 223 omap_mcbsp_dai_dma_params[id][substream->stream].port_addr = port;
180 cpu_dai->dma_data = &omap_mcbsp_dai_dma_params[id][substream->stream]; 224 cpu_dai->dma_data = &omap_mcbsp_dai_dma_params[id][substream->stream];
@@ -245,6 +289,11 @@ static int omap_mcbsp_dai_set_dai_fmt(struct snd_soc_dai *cpu_dai,
245 regs->rcr2 |= RDATDLY(1); 289 regs->rcr2 |= RDATDLY(1);
246 regs->xcr2 |= XDATDLY(1); 290 regs->xcr2 |= XDATDLY(1);
247 break; 291 break;
292 case SND_SOC_DAIFMT_DSP_A:
293 /* 0-bit data delay */
294 regs->rcr2 |= RDATDLY(0);
295 regs->xcr2 |= XDATDLY(0);
296 break;
248 default: 297 default:
249 /* Unsupported data format */ 298 /* Unsupported data format */
250 return -EINVAL; 299 return -EINVAL;
@@ -310,7 +359,7 @@ static int omap_mcbsp_dai_set_clks_src(struct omap_mcbsp_data *mcbsp_data,
310 int clk_id) 359 int clk_id)
311{ 360{
312 int sel_bit; 361 int sel_bit;
313 u16 reg; 362 u16 reg, reg_devconf1 = OMAP243X_CONTROL_DEVCONF1;
314 363
315 if (cpu_class_is_omap1()) { 364 if (cpu_class_is_omap1()) {
316 /* OMAP1's can use only external source clock */ 365 /* OMAP1's can use only external source clock */
@@ -320,6 +369,12 @@ static int omap_mcbsp_dai_set_clks_src(struct omap_mcbsp_data *mcbsp_data,
320 return 0; 369 return 0;
321 } 370 }
322 371
372 if (cpu_is_omap2420() && mcbsp_data->bus_id > 1)
373 return -EINVAL;
374
375 if (cpu_is_omap343x())
376 reg_devconf1 = OMAP343X_CONTROL_DEVCONF1;
377
323 switch (mcbsp_data->bus_id) { 378 switch (mcbsp_data->bus_id) {
324 case 0: 379 case 0:
325 reg = OMAP2_CONTROL_DEVCONF0; 380 reg = OMAP2_CONTROL_DEVCONF0;
@@ -329,20 +384,26 @@ static int omap_mcbsp_dai_set_clks_src(struct omap_mcbsp_data *mcbsp_data,
329 reg = OMAP2_CONTROL_DEVCONF0; 384 reg = OMAP2_CONTROL_DEVCONF0;
330 sel_bit = 6; 385 sel_bit = 6;
331 break; 386 break;
332 /* TODO: Support for ports 3 - 5 in OMAP2430 and OMAP34xx */ 387 case 2:
388 reg = reg_devconf1;
389 sel_bit = 0;
390 break;
391 case 3:
392 reg = reg_devconf1;
393 sel_bit = 2;
394 break;
395 case 4:
396 reg = reg_devconf1;
397 sel_bit = 4;
398 break;
333 default: 399 default:
334 return -EINVAL; 400 return -EINVAL;
335 } 401 }
336 402
337 if (cpu_class_is_omap2()) { 403 if (clk_id == OMAP_MCBSP_SYSCLK_CLKS_FCLK)
338 if (clk_id == OMAP_MCBSP_SYSCLK_CLKS_FCLK) { 404 omap_ctrl_writel(omap_ctrl_readl(reg) & ~(1 << sel_bit), reg);
339 omap_ctrl_writel(omap_ctrl_readl(reg) & 405 else
340 ~(1 << sel_bit), reg); 406 omap_ctrl_writel(omap_ctrl_readl(reg) | (1 << sel_bit), reg);
341 } else {
342 omap_ctrl_writel(omap_ctrl_readl(reg) |
343 (1 << sel_bit), reg);
344 }
345 }
346 407
347 return 0; 408 return 0;
348} 409}
@@ -376,37 +437,49 @@ static int omap_mcbsp_dai_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
376 return err; 437 return err;
377} 438}
378 439
379struct snd_soc_dai omap_mcbsp_dai[NUM_LINKS] = { 440#define OMAP_MCBSP_DAI_BUILDER(link_id) \
380{ 441{ \
381 .name = "omap-mcbsp-dai", 442 .name = "omap-mcbsp-dai-(link_id)", \
382 .id = 0, 443 .id = (link_id), \
383 .type = SND_SOC_DAI_I2S, 444 .type = SND_SOC_DAI_I2S, \
384 .playback = { 445 .playback = { \
385 .channels_min = 2, 446 .channels_min = 2, \
386 .channels_max = 2, 447 .channels_max = 2, \
387 .rates = OMAP_MCBSP_RATES, 448 .rates = OMAP_MCBSP_RATES, \
388 .formats = SNDRV_PCM_FMTBIT_S16_LE, 449 .formats = SNDRV_PCM_FMTBIT_S16_LE, \
389 }, 450 }, \
390 .capture = { 451 .capture = { \
391 .channels_min = 2, 452 .channels_min = 2, \
392 .channels_max = 2, 453 .channels_max = 2, \
393 .rates = OMAP_MCBSP_RATES, 454 .rates = OMAP_MCBSP_RATES, \
394 .formats = SNDRV_PCM_FMTBIT_S16_LE, 455 .formats = SNDRV_PCM_FMTBIT_S16_LE, \
395 }, 456 }, \
396 .ops = { 457 .ops = { \
397 .startup = omap_mcbsp_dai_startup, 458 .startup = omap_mcbsp_dai_startup, \
398 .shutdown = omap_mcbsp_dai_shutdown, 459 .shutdown = omap_mcbsp_dai_shutdown, \
399 .trigger = omap_mcbsp_dai_trigger, 460 .trigger = omap_mcbsp_dai_trigger, \
400 .hw_params = omap_mcbsp_dai_hw_params, 461 .hw_params = omap_mcbsp_dai_hw_params, \
401 }, 462 }, \
402 .dai_ops = { 463 .dai_ops = { \
403 .set_fmt = omap_mcbsp_dai_set_dai_fmt, 464 .set_fmt = omap_mcbsp_dai_set_dai_fmt, \
404 .set_clkdiv = omap_mcbsp_dai_set_clkdiv, 465 .set_clkdiv = omap_mcbsp_dai_set_clkdiv, \
405 .set_sysclk = omap_mcbsp_dai_set_dai_sysclk, 466 .set_sysclk = omap_mcbsp_dai_set_dai_sysclk, \
406 }, 467 }, \
407 .private_data = &mcbsp_data[0].bus_id, 468 .private_data = &mcbsp_data[(link_id)].bus_id, \
408}, 469}
470
471struct snd_soc_dai omap_mcbsp_dai[] = {
472 OMAP_MCBSP_DAI_BUILDER(0),
473 OMAP_MCBSP_DAI_BUILDER(1),
474#if NUM_LINKS >= 3
475 OMAP_MCBSP_DAI_BUILDER(2),
476#endif
477#if NUM_LINKS == 5
478 OMAP_MCBSP_DAI_BUILDER(3),
479 OMAP_MCBSP_DAI_BUILDER(4),
480#endif
409}; 481};
482
410EXPORT_SYMBOL_GPL(omap_mcbsp_dai); 483EXPORT_SYMBOL_GPL(omap_mcbsp_dai);
411 484
412MODULE_AUTHOR("Jarkko Nikula <jarkko.nikula@nokia.com>"); 485MODULE_AUTHOR("Jarkko Nikula <jarkko.nikula@nokia.com>");
diff --git a/sound/soc/omap/omap-mcbsp.h b/sound/soc/omap/omap-mcbsp.h
index ed8afb550671..df7ad13ba73d 100644
--- a/sound/soc/omap/omap-mcbsp.h
+++ b/sound/soc/omap/omap-mcbsp.h
@@ -38,11 +38,17 @@ enum omap_mcbsp_div {
38 OMAP_MCBSP_CLKGDV, /* Sample rate generator divider */ 38 OMAP_MCBSP_CLKGDV, /* Sample rate generator divider */
39}; 39};
40 40
41/* 41#if defined(CONFIG_ARCH_OMAP2420)
42 * REVISIT: Preparation for the ASoC v2. Let the number of available links to 42#define NUM_LINKS 2
43 * be same than number of McBSP ports found in OMAP(s) we are compiling for. 43#endif
44 */ 44#if defined(CONFIG_ARCH_OMAP15XX) || defined(CONFIG_ARCH_OMAP16XX)
45#define NUM_LINKS 1 45#undef NUM_LINKS
46#define NUM_LINKS 3
47#endif
48#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP34XX)
49#undef NUM_LINKS
50#define NUM_LINKS 5
51#endif
46 52
47extern struct snd_soc_dai omap_mcbsp_dai[NUM_LINKS]; 53extern struct snd_soc_dai omap_mcbsp_dai[NUM_LINKS];
48 54
diff --git a/sound/soc/omap/omap-pcm.c b/sound/soc/omap/omap-pcm.c
index 690bfeaec4a0..e9084fdd2082 100644
--- a/sound/soc/omap/omap-pcm.c
+++ b/sound/soc/omap/omap-pcm.c
@@ -97,7 +97,7 @@ static int omap_pcm_hw_params(struct snd_pcm_substream *substream,
97 prtd->dma_data = dma_data; 97 prtd->dma_data = dma_data;
98 err = omap_request_dma(dma_data->dma_req, dma_data->name, 98 err = omap_request_dma(dma_data->dma_req, dma_data->name,
99 omap_pcm_dma_irq, substream, &prtd->dma_ch); 99 omap_pcm_dma_irq, substream, &prtd->dma_ch);
100 if (!cpu_is_omap1510()) { 100 if (!err & !cpu_is_omap1510()) {
101 /* 101 /*
102 * Link channel with itself so DMA doesn't need any 102 * Link channel with itself so DMA doesn't need any
103 * reprogramming while looping the buffer 103 * reprogramming while looping the buffer
@@ -147,12 +147,14 @@ static int omap_pcm_prepare(struct snd_pcm_substream *substream)
147 dma_params.src_or_dst_synch = OMAP_DMA_DST_SYNC; 147 dma_params.src_or_dst_synch = OMAP_DMA_DST_SYNC;
148 dma_params.src_start = runtime->dma_addr; 148 dma_params.src_start = runtime->dma_addr;
149 dma_params.dst_start = dma_data->port_addr; 149 dma_params.dst_start = dma_data->port_addr;
150 dma_params.dst_port = OMAP_DMA_PORT_MPUI;
150 } else { 151 } else {
151 dma_params.src_amode = OMAP_DMA_AMODE_CONSTANT; 152 dma_params.src_amode = OMAP_DMA_AMODE_CONSTANT;
152 dma_params.dst_amode = OMAP_DMA_AMODE_POST_INC; 153 dma_params.dst_amode = OMAP_DMA_AMODE_POST_INC;
153 dma_params.src_or_dst_synch = OMAP_DMA_SRC_SYNC; 154 dma_params.src_or_dst_synch = OMAP_DMA_SRC_SYNC;
154 dma_params.src_start = dma_data->port_addr; 155 dma_params.src_start = dma_data->port_addr;
155 dma_params.dst_start = runtime->dma_addr; 156 dma_params.dst_start = runtime->dma_addr;
157 dma_params.src_port = OMAP_DMA_PORT_MPUI;
156 } 158 }
157 /* 159 /*
158 * Set DMA transfer frame size equal to ALSA period size and frame 160 * Set DMA transfer frame size equal to ALSA period size and frame
diff --git a/sound/soc/omap/osk5912.c b/sound/soc/omap/osk5912.c
new file mode 100644
index 000000000000..0fe733796898
--- /dev/null
+++ b/sound/soc/omap/osk5912.c
@@ -0,0 +1,232 @@
1/*
2 * osk5912.c -- SoC audio for OSK 5912
3 *
4 * Copyright (C) 2008 Mistral Solutions
5 *
6 * Contact: Arun KS <arunks@mistralsolutions.com>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * version 2 as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA
21 *
22 */
23
24#include <linux/clk.h>
25#include <linux/platform_device.h>
26#include <sound/core.h>
27#include <sound/pcm.h>
28#include <sound/soc.h>
29#include <sound/soc-dapm.h>
30
31#include <asm/mach-types.h>
32#include <mach/hardware.h>
33#include <linux/gpio.h>
34#include <mach/mcbsp.h>
35
36#include "omap-mcbsp.h"
37#include "omap-pcm.h"
38#include "../codecs/tlv320aic23.h"
39
40#define CODEC_CLOCK 12000000
41
42static struct clk *tlv320aic23_mclk;
43
44static int osk_startup(struct snd_pcm_substream *substream)
45{
46 return clk_enable(tlv320aic23_mclk);
47}
48
49static void osk_shutdown(struct snd_pcm_substream *substream)
50{
51 clk_disable(tlv320aic23_mclk);
52}
53
54static int osk_hw_params(struct snd_pcm_substream *substream,
55 struct snd_pcm_hw_params *params)
56{
57 struct snd_soc_pcm_runtime *rtd = substream->private_data;
58 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
59 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
60 int err;
61
62 /* Set codec DAI configuration */
63 err = snd_soc_dai_set_fmt(codec_dai,
64 SND_SOC_DAIFMT_DSP_A |
65 SND_SOC_DAIFMT_NB_IF |
66 SND_SOC_DAIFMT_CBM_CFM);
67 if (err < 0) {
68 printk(KERN_ERR "can't set codec DAI configuration\n");
69 return err;
70 }
71
72 /* Set cpu DAI configuration */
73 err = snd_soc_dai_set_fmt(cpu_dai,
74 SND_SOC_DAIFMT_DSP_A |
75 SND_SOC_DAIFMT_NB_IF |
76 SND_SOC_DAIFMT_CBM_CFM);
77 if (err < 0) {
78 printk(KERN_ERR "can't set cpu DAI configuration\n");
79 return err;
80 }
81
82 /* Set the codec system clock for DAC and ADC */
83 err =
84 snd_soc_dai_set_sysclk(codec_dai, 0, CODEC_CLOCK, SND_SOC_CLOCK_IN);
85
86 if (err < 0) {
87 printk(KERN_ERR "can't set codec system clock\n");
88 return err;
89 }
90
91 return err;
92}
93
94static struct snd_soc_ops osk_ops = {
95 .startup = osk_startup,
96 .hw_params = osk_hw_params,
97 .shutdown = osk_shutdown,
98};
99
100static const struct snd_soc_dapm_widget tlv320aic23_dapm_widgets[] = {
101 SND_SOC_DAPM_HP("Headphone Jack", NULL),
102 SND_SOC_DAPM_LINE("Line In", NULL),
103 SND_SOC_DAPM_MIC("Mic Jack", NULL),
104};
105
106static const struct snd_soc_dapm_route audio_map[] = {
107 {"Headphone Jack", NULL, "LHPOUT"},
108 {"Headphone Jack", NULL, "RHPOUT"},
109
110 {"LLINEIN", NULL, "Line In"},
111 {"RLINEIN", NULL, "Line In"},
112
113 {"MICIN", NULL, "Mic Jack"},
114};
115
116static int osk_tlv320aic23_init(struct snd_soc_codec *codec)
117{
118
119 /* Add osk5912 specific widgets */
120 snd_soc_dapm_new_controls(codec, tlv320aic23_dapm_widgets,
121 ARRAY_SIZE(tlv320aic23_dapm_widgets));
122
123 /* Set up osk5912 specific audio path audio_map */
124 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
125
126 snd_soc_dapm_enable_pin(codec, "Headphone Jack");
127 snd_soc_dapm_enable_pin(codec, "Line In");
128 snd_soc_dapm_enable_pin(codec, "Mic Jack");
129
130 snd_soc_dapm_sync(codec);
131
132 return 0;
133}
134
135/* Digital audio interface glue - connects codec <--> CPU */
136static struct snd_soc_dai_link osk_dai = {
137 .name = "TLV320AIC23",
138 .stream_name = "AIC23",
139 .cpu_dai = &omap_mcbsp_dai[0],
140 .codec_dai = &tlv320aic23_dai,
141 .init = osk_tlv320aic23_init,
142 .ops = &osk_ops,
143};
144
145/* Audio machine driver */
146static struct snd_soc_machine snd_soc_machine_osk = {
147 .name = "OSK5912",
148 .dai_link = &osk_dai,
149 .num_links = 1,
150};
151
152/* Audio subsystem */
153static struct snd_soc_device osk_snd_devdata = {
154 .machine = &snd_soc_machine_osk,
155 .platform = &omap_soc_platform,
156 .codec_dev = &soc_codec_dev_tlv320aic23,
157};
158
159static struct platform_device *osk_snd_device;
160
161static int __init osk_soc_init(void)
162{
163 int err;
164 u32 curRate;
165 struct device *dev;
166
167 if (!(machine_is_omap_osk()))
168 return -ENODEV;
169
170 osk_snd_device = platform_device_alloc("soc-audio", -1);
171 if (!osk_snd_device)
172 return -ENOMEM;
173
174 platform_set_drvdata(osk_snd_device, &osk_snd_devdata);
175 osk_snd_devdata.dev = &osk_snd_device->dev;
176 *(unsigned int *)osk_dai.cpu_dai->private_data = 0; /* McBSP1 */
177 err = platform_device_add(osk_snd_device);
178 if (err)
179 goto err1;
180
181 dev = &osk_snd_device->dev;
182
183 tlv320aic23_mclk = clk_get(dev, "mclk");
184 if (IS_ERR(tlv320aic23_mclk)) {
185 printk(KERN_ERR "Could not get mclk clock\n");
186 return -ENODEV;
187 }
188
189 if (clk_get_usecount(tlv320aic23_mclk) > 0) {
190 /* MCLK is already in use */
191 printk(KERN_WARNING
192 "MCLK in use at %d Hz. We change it to %d Hz\n",
193 (uint) clk_get_rate(tlv320aic23_mclk), CODEC_CLOCK);
194 }
195
196 /*
197 * Configure 12 MHz output on MCLK.
198 */
199 curRate = (uint) clk_get_rate(tlv320aic23_mclk);
200 if (curRate != CODEC_CLOCK) {
201 if (clk_set_rate(tlv320aic23_mclk, CODEC_CLOCK)) {
202 printk(KERN_ERR "Cannot set MCLK for AIC23 CODEC\n");
203 err = -ECANCELED;
204 goto err1;
205 }
206 }
207
208 printk(KERN_INFO "MCLK = %d [%d], usecount = %d\n",
209 (uint) clk_get_rate(tlv320aic23_mclk), CODEC_CLOCK,
210 clk_get_usecount(tlv320aic23_mclk));
211
212 return 0;
213err1:
214 clk_put(tlv320aic23_mclk);
215 platform_device_del(osk_snd_device);
216 platform_device_put(osk_snd_device);
217
218 return err;
219
220}
221
222static void __exit osk_soc_exit(void)
223{
224 platform_device_unregister(osk_snd_device);
225}
226
227module_init(osk_soc_init);
228module_exit(osk_soc_exit);
229
230MODULE_AUTHOR("Arun KS <arunks@mistralsolutions.com>");
231MODULE_DESCRIPTION("ALSA SoC OSK 5912");
232MODULE_LICENSE("GPL");
diff --git a/sound/soc/pxa/corgi.c b/sound/soc/pxa/corgi.c
index 1a8373de7f3a..2718eaf7895f 100644
--- a/sound/soc/pxa/corgi.c
+++ b/sound/soc/pxa/corgi.c
@@ -4,7 +4,7 @@
4 * Copyright 2005 Wolfson Microelectronics PLC. 4 * Copyright 2005 Wolfson Microelectronics PLC.
5 * Copyright 2005 Openedhand Ltd. 5 * Copyright 2005 Openedhand Ltd.
6 * 6 *
7 * Authors: Liam Girdwood <liam.girdwood@wolfsonmicro.com> 7 * Authors: Liam Girdwood <lrg@slimlogic.co.uk>
8 * Richard Purdie <richard@openedhand.com> 8 * Richard Purdie <richard@openedhand.com>
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify it 10 * This program is free software; you can redistribute it and/or modify it
@@ -281,8 +281,8 @@ static int corgi_wm8731_init(struct snd_soc_codec *codec)
281{ 281{
282 int i, err; 282 int i, err;
283 283
284 snd_soc_dapm_disable_pin(codec, "LLINEIN"); 284 snd_soc_dapm_nc_pin(codec, "LLINEIN");
285 snd_soc_dapm_disable_pin(codec, "RLINEIN"); 285 snd_soc_dapm_nc_pin(codec, "RLINEIN");
286 286
287 /* Add corgi specific controls */ 287 /* Add corgi specific controls */
288 for (i = 0; i < ARRAY_SIZE(wm8731_corgi_controls); i++) { 288 for (i = 0; i < ARRAY_SIZE(wm8731_corgi_controls); i++) {
diff --git a/sound/soc/pxa/em-x270.c b/sound/soc/pxa/em-x270.c
index d9c3f7b28be2..e6ff6929ab4b 100644
--- a/sound/soc/pxa/em-x270.c
+++ b/sound/soc/pxa/em-x270.c
@@ -9,7 +9,7 @@
9 * Copyright 2005 Wolfson Microelectronics PLC. 9 * Copyright 2005 Wolfson Microelectronics PLC.
10 * Copyright 2005 Openedhand Ltd. 10 * Copyright 2005 Openedhand Ltd.
11 * 11 *
12 * Authors: Liam Girdwood <liam.girdwood@wolfsonmicro.com> 12 * Authors: Liam Girdwood <lrg@slimlogic.co.uk>
13 * Richard Purdie <richard@openedhand.com> 13 * Richard Purdie <richard@openedhand.com>
14 * 14 *
15 * This program is free software; you can redistribute it and/or modify it 15 * This program is free software; you can redistribute it and/or modify it
diff --git a/sound/soc/pxa/poodle.c b/sound/soc/pxa/poodle.c
index f84f7d8db09a..4d9930c52789 100644
--- a/sound/soc/pxa/poodle.c
+++ b/sound/soc/pxa/poodle.c
@@ -4,7 +4,7 @@
4 * Copyright 2005 Wolfson Microelectronics PLC. 4 * Copyright 2005 Wolfson Microelectronics PLC.
5 * Copyright 2005 Openedhand Ltd. 5 * Copyright 2005 Openedhand Ltd.
6 * 6 *
7 * Authors: Liam Girdwood <liam.girdwood@wolfsonmicro.com> 7 * Authors: Liam Girdwood <lrg@slimlogic.co.uk>
8 * Richard Purdie <richard@openedhand.com> 8 * Richard Purdie <richard@openedhand.com>
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify it 10 * This program is free software; you can redistribute it and/or modify it
@@ -242,8 +242,8 @@ static int poodle_wm8731_init(struct snd_soc_codec *codec)
242{ 242{
243 int i, err; 243 int i, err;
244 244
245 snd_soc_dapm_disable_pin(codec, "LLINEIN"); 245 snd_soc_dapm_nc_pin(codec, "LLINEIN");
246 snd_soc_dapm_disable_pin(codec, "RLINEIN"); 246 snd_soc_dapm_nc_pin(codec, "RLINEIN");
247 snd_soc_dapm_enable_pin(codec, "MICIN"); 247 snd_soc_dapm_enable_pin(codec, "MICIN");
248 248
249 /* Add poodle specific controls */ 249 /* Add poodle specific controls */
diff --git a/sound/soc/pxa/pxa2xx-i2s.c b/sound/soc/pxa/pxa2xx-i2s.c
index 2fb58298513b..e758034db5c3 100644
--- a/sound/soc/pxa/pxa2xx-i2s.c
+++ b/sound/soc/pxa/pxa2xx-i2s.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * Copyright 2005 Wolfson Microelectronics PLC. 4 * Copyright 2005 Wolfson Microelectronics PLC.
5 * Author: Liam Girdwood 5 * Author: Liam Girdwood
6 * liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com 6 * lrg@slimlogic.co.uk
7 * 7 *
8 * This program is free software; you can redistribute it and/or modify it 8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the 9 * under the terms of the GNU General Public License as published by the
@@ -405,6 +405,6 @@ module_init(pxa2xx_i2s_init);
405module_exit(pxa2xx_i2s_exit); 405module_exit(pxa2xx_i2s_exit);
406 406
407/* Module information */ 407/* Module information */
408MODULE_AUTHOR("Liam Girdwood, liam.girdwood@wolfsonmicro.com, www.wolfsonmicro.com"); 408MODULE_AUTHOR("Liam Girdwood, lrg@slimlogic.co.uk");
409MODULE_DESCRIPTION("pxa2xx I2S SoC Interface"); 409MODULE_DESCRIPTION("pxa2xx I2S SoC Interface");
410MODULE_LICENSE("GPL"); 410MODULE_LICENSE("GPL");
diff --git a/sound/soc/pxa/spitz.c b/sound/soc/pxa/spitz.c
index 9a70b00fc30e..d307b6757e95 100644
--- a/sound/soc/pxa/spitz.c
+++ b/sound/soc/pxa/spitz.c
@@ -4,7 +4,7 @@
4 * Copyright 2005 Wolfson Microelectronics PLC. 4 * Copyright 2005 Wolfson Microelectronics PLC.
5 * Copyright 2005 Openedhand Ltd. 5 * Copyright 2005 Openedhand Ltd.
6 * 6 *
7 * Authors: Liam Girdwood <liam.girdwood@wolfsonmicro.com> 7 * Authors: Liam Girdwood <lrg@slimlogic.co.uk>
8 * Richard Purdie <richard@openedhand.com> 8 * Richard Purdie <richard@openedhand.com>
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify it 10 * This program is free software; you can redistribute it and/or modify it
@@ -281,13 +281,13 @@ static int spitz_wm8750_init(struct snd_soc_codec *codec)
281 int i, err; 281 int i, err;
282 282
283 /* NC codec pins */ 283 /* NC codec pins */
284 snd_soc_dapm_disable_pin(codec, "RINPUT1"); 284 snd_soc_dapm_nc_pin(codec, "RINPUT1");
285 snd_soc_dapm_disable_pin(codec, "LINPUT2"); 285 snd_soc_dapm_nc_pin(codec, "LINPUT2");
286 snd_soc_dapm_disable_pin(codec, "RINPUT2"); 286 snd_soc_dapm_nc_pin(codec, "RINPUT2");
287 snd_soc_dapm_disable_pin(codec, "LINPUT3"); 287 snd_soc_dapm_nc_pin(codec, "LINPUT3");
288 snd_soc_dapm_disable_pin(codec, "RINPUT3"); 288 snd_soc_dapm_nc_pin(codec, "RINPUT3");
289 snd_soc_dapm_disable_pin(codec, "OUT3"); 289 snd_soc_dapm_nc_pin(codec, "OUT3");
290 snd_soc_dapm_disable_pin(codec, "MONO1"); 290 snd_soc_dapm_nc_pin(codec, "MONO1");
291 291
292 /* Add spitz specific controls */ 292 /* Add spitz specific controls */
293 for (i = 0; i < ARRAY_SIZE(wm8750_spitz_controls); i++) { 293 for (i = 0; i < ARRAY_SIZE(wm8750_spitz_controls); i++) {
diff --git a/sound/soc/pxa/tosa.c b/sound/soc/pxa/tosa.c
index 2baaa750f123..afefe41b8c46 100644
--- a/sound/soc/pxa/tosa.c
+++ b/sound/soc/pxa/tosa.c
@@ -4,7 +4,7 @@
4 * Copyright 2005 Wolfson Microelectronics PLC. 4 * Copyright 2005 Wolfson Microelectronics PLC.
5 * Copyright 2005 Openedhand Ltd. 5 * Copyright 2005 Openedhand Ltd.
6 * 6 *
7 * Authors: Liam Girdwood <liam.girdwood@wolfsonmicro.com> 7 * Authors: Liam Girdwood <lrg@slimlogic.co.uk>
8 * Richard Purdie <richard@openedhand.com> 8 * Richard Purdie <richard@openedhand.com>
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify it 10 * This program is free software; you can redistribute it and/or modify it
@@ -190,8 +190,8 @@ static int tosa_ac97_init(struct snd_soc_codec *codec)
190{ 190{
191 int i, err; 191 int i, err;
192 192
193 snd_soc_dapm_disable_pin(codec, "OUT3"); 193 snd_soc_dapm_nc_pin(codec, "OUT3");
194 snd_soc_dapm_disable_pin(codec, "MONOOUT"); 194 snd_soc_dapm_nc_pin(codec, "MONOOUT");
195 195
196 /* add tosa specific controls */ 196 /* add tosa specific controls */
197 for (i = 0; i < ARRAY_SIZE(tosa_controls); i++) { 197 for (i = 0; i < ARRAY_SIZE(tosa_controls); i++) {
diff --git a/sound/soc/s3c24xx/neo1973_wm8753.c b/sound/soc/s3c24xx/neo1973_wm8753.c
index 73a50e93a9a2..87ddfefcc2fb 100644
--- a/sound/soc/s3c24xx/neo1973_wm8753.c
+++ b/sound/soc/s3c24xx/neo1973_wm8753.c
@@ -511,21 +511,20 @@ static int neo1973_wm8753_init(struct snd_soc_codec *codec)
511 DBG("Entered %s\n", __func__); 511 DBG("Entered %s\n", __func__);
512 512
513 /* set up NC codec pins */ 513 /* set up NC codec pins */
514 snd_soc_dapm_disable_pin(codec, "LOUT2"); 514 snd_soc_dapm_nc_pin(codec, "LOUT2");
515 snd_soc_dapm_disable_pin(codec, "ROUT2"); 515 snd_soc_dapm_nc_pin(codec, "ROUT2");
516 snd_soc_dapm_disable_pin(codec, "OUT3"); 516 snd_soc_dapm_nc_pin(codec, "OUT3");
517 snd_soc_dapm_disable_pin(codec, "OUT4"); 517 snd_soc_dapm_nc_pin(codec, "OUT4");
518 snd_soc_dapm_disable_pin(codec, "LINE1"); 518 snd_soc_dapm_nc_pin(codec, "LINE1");
519 snd_soc_dapm_disable_pin(codec, "LINE2"); 519 snd_soc_dapm_nc_pin(codec, "LINE2");
520
521
522 /* set endpoints to default mode */
523 set_scenario_endpoints(codec, NEO_AUDIO_OFF);
524 520
525 /* Add neo1973 specific widgets */ 521 /* Add neo1973 specific widgets */
526 snd_soc_dapm_new_controls(codec, wm8753_dapm_widgets, 522 snd_soc_dapm_new_controls(codec, wm8753_dapm_widgets,
527 ARRAY_SIZE(wm8753_dapm_widgets)); 523 ARRAY_SIZE(wm8753_dapm_widgets));
528 524
525 /* set endpoints to default mode */
526 set_scenario_endpoints(codec, NEO_AUDIO_OFF);
527
529 /* add neo1973 specific controls */ 528 /* add neo1973 specific controls */
530 for (i = 0; i < ARRAY_SIZE(wm8753_neo1973_controls); i++) { 529 for (i = 0; i < ARRAY_SIZE(wm8753_neo1973_controls); i++) {
531 err = snd_ctl_add(codec->card, 530 err = snd_ctl_add(codec->card,
@@ -603,6 +602,8 @@ static int lm4857_i2c_probe(struct i2c_client *client,
603{ 602{
604 DBG("Entered %s\n", __func__); 603 DBG("Entered %s\n", __func__);
605 604
605 i2c = client;
606
606 lm4857_write_regs(); 607 lm4857_write_regs();
607 return 0; 608 return 0;
608} 609}
@@ -611,6 +612,8 @@ static int lm4857_i2c_remove(struct i2c_client *client)
611{ 612{
612 DBG("Entered %s\n", __func__); 613 DBG("Entered %s\n", __func__);
613 614
615 i2c = NULL;
616
614 return 0; 617 return 0;
615} 618}
616 619
@@ -650,7 +653,7 @@ static void lm4857_shutdown(struct i2c_client *dev)
650} 653}
651 654
652static const struct i2c_device_id lm4857_i2c_id[] = { 655static const struct i2c_device_id lm4857_i2c_id[] = {
653 { "neo1973_lm4857", 0 } 656 { "neo1973_lm4857", 0 },
654 { } 657 { }
655}; 658};
656 659
@@ -668,48 +671,6 @@ static struct i2c_driver lm4857_i2c_driver = {
668}; 671};
669 672
670static struct platform_device *neo1973_snd_device; 673static struct platform_device *neo1973_snd_device;
671static struct i2c_client *lm4857_client;
672
673static int __init neo1973_add_lm4857_device(struct platform_device *pdev,
674 int i2c_bus,
675 unsigned short i2c_address)
676{
677 struct i2c_board_info info;
678 struct i2c_adapter *adapter;
679 struct i2c_client *client;
680 int ret;
681
682 ret = i2c_add_driver(&lm4857_i2c_driver);
683 if (ret != 0) {
684 dev_err(&pdev->dev, "can't add lm4857 driver\n");
685 return ret;
686 }
687
688 memset(&info, 0, sizeof(struct i2c_board_info));
689 info.addr = i2c_address;
690 strlcpy(info.type, "neo1973_lm4857", I2C_NAME_SIZE);
691
692 adapter = i2c_get_adapter(i2c_bus);
693 if (!adapter) {
694 dev_err(&pdev->dev, "can't get i2c adapter %d\n", i2c_bus);
695 goto err_driver;
696 }
697
698 client = i2c_new_device(adapter, &info);
699 i2c_put_adapter(adapter);
700 if (!client) {
701 dev_err(&pdev->dev, "can't add lm4857 device at 0x%x\n",
702 (unsigned int)info.addr);
703 goto err_driver;
704 }
705
706 lm4857_client = client;
707 return 0;
708
709err_driver:
710 i2c_del_driver(&lm4857_i2c_driver);
711 return -ENODEV;
712}
713 674
714static int __init neo1973_init(void) 675static int __init neo1973_init(void)
715{ 676{
@@ -736,8 +697,8 @@ static int __init neo1973_init(void)
736 return ret; 697 return ret;
737 } 698 }
738 699
739 ret = neo1973_add_lm4857_device(neo1973_snd_device, 700 ret = i2c_add_driver(&lm4857_i2c_driver);
740 neo1973_wm8753_setup, 0x7C); 701
741 if (ret != 0) 702 if (ret != 0)
742 platform_device_unregister(neo1973_snd_device); 703 platform_device_unregister(neo1973_snd_device);
743 704
@@ -748,7 +709,6 @@ static void __exit neo1973_exit(void)
748{ 709{
749 DBG("Entered %s\n", __func__); 710 DBG("Entered %s\n", __func__);
750 711
751 i2c_unregister_device(lm4857_client);
752 i2c_del_driver(&lm4857_i2c_driver); 712 i2c_del_driver(&lm4857_i2c_driver);
753 platform_device_unregister(neo1973_snd_device); 713 platform_device_unregister(neo1973_snd_device);
754} 714}
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index ad381138fc2e..462e635dfc74 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -4,8 +4,7 @@
4 * Copyright 2005 Wolfson Microelectronics PLC. 4 * Copyright 2005 Wolfson Microelectronics PLC.
5 * Copyright 2005 Openedhand Ltd. 5 * Copyright 2005 Openedhand Ltd.
6 * 6 *
7 * Author: Liam Girdwood 7 * Author: Liam Girdwood <lrg@slimlogic.co.uk>
8 * liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com
9 * with code, comments and ideas from :- 8 * with code, comments and ideas from :-
10 * Richard Purdie <richard@openedhand.com> 9 * Richard Purdie <richard@openedhand.com>
11 * 10 *
@@ -1886,7 +1885,7 @@ module_init(snd_soc_init);
1886module_exit(snd_soc_exit); 1885module_exit(snd_soc_exit);
1887 1886
1888/* Module information */ 1887/* Module information */
1889MODULE_AUTHOR("Liam Girdwood, liam.girdwood@wolfsonmicro.com, www.wolfsonmicro.com"); 1888MODULE_AUTHOR("Liam Girdwood, lrg@slimlogic.co.uk");
1890MODULE_DESCRIPTION("ALSA SoC Core"); 1889MODULE_DESCRIPTION("ALSA SoC Core");
1891MODULE_LICENSE("GPL"); 1890MODULE_LICENSE("GPL");
1892MODULE_ALIAS("platform:soc-audio"); 1891MODULE_ALIAS("platform:soc-audio");
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index 9ca9c08610fa..efbd0b37810a 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -2,8 +2,7 @@
2 * soc-dapm.c -- ALSA SoC Dynamic Audio Power Management 2 * soc-dapm.c -- ALSA SoC Dynamic Audio Power Management
3 * 3 *
4 * Copyright 2005 Wolfson Microelectronics PLC. 4 * Copyright 2005 Wolfson Microelectronics PLC.
5 * Author: Liam Girdwood 5 * Author: Liam Girdwood <lrg@slimlogic.co.uk>
6 * liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com
7 * 6 *
8 * This program is free software; you can redistribute it and/or modify it 7 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the 8 * under the terms of the GNU General Public License as published by the
@@ -1484,6 +1483,26 @@ int snd_soc_dapm_disable_pin(struct snd_soc_codec *codec, char *pin)
1484EXPORT_SYMBOL_GPL(snd_soc_dapm_disable_pin); 1483EXPORT_SYMBOL_GPL(snd_soc_dapm_disable_pin);
1485 1484
1486/** 1485/**
1486 * snd_soc_dapm_nc_pin - permanently disable pin.
1487 * @codec: SoC codec
1488 * @pin: pin name
1489 *
1490 * Marks the specified pin as being not connected, disabling it along
1491 * any parent or child widgets. At present this is identical to
1492 * snd_soc_dapm_disable_pin() but in future it will be extended to do
1493 * additional things such as disabling controls which only affect
1494 * paths through the pin.
1495 *
1496 * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to
1497 * do any widget power switching.
1498 */
1499int snd_soc_dapm_nc_pin(struct snd_soc_codec *codec, char *pin)
1500{
1501 return snd_soc_dapm_set_pin(codec, pin, 0);
1502}
1503EXPORT_SYMBOL_GPL(snd_soc_dapm_nc_pin);
1504
1505/**
1487 * snd_soc_dapm_get_pin_status - get audio pin status 1506 * snd_soc_dapm_get_pin_status - get audio pin status
1488 * @codec: audio codec 1507 * @codec: audio codec
1489 * @pin: audio signal pin endpoint (or start point) 1508 * @pin: audio signal pin endpoint (or start point)
@@ -1521,6 +1540,6 @@ void snd_soc_dapm_free(struct snd_soc_device *socdev)
1521EXPORT_SYMBOL_GPL(snd_soc_dapm_free); 1540EXPORT_SYMBOL_GPL(snd_soc_dapm_free);
1522 1541
1523/* Module information */ 1542/* Module information */
1524MODULE_AUTHOR("Liam Girdwood, liam.girdwood@wolfsonmicro.com, www.wolfsonmicro.com"); 1543MODULE_AUTHOR("Liam Girdwood, lrg@slimlogic.co.uk");
1525MODULE_DESCRIPTION("Dynamic Audio Power Management core for ALSA SoC"); 1544MODULE_DESCRIPTION("Dynamic Audio Power Management core for ALSA SoC");
1526MODULE_LICENSE("GPL"); 1545MODULE_LICENSE("GPL");