aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/feature-removal-schedule.txt11
-rw-r--r--Documentation/highuid.txt2
-rw-r--r--Documentation/magic-number.txt1
-rw-r--r--arch/sparc/Kconfig12
-rw-r--r--arch/sparc/defconfig165
-rw-r--r--arch/sparc/kernel/Makefile10
-rw-r--r--arch/sparc/kernel/entry.S206
-rw-r--r--arch/sparc/kernel/errtbls.c144
-rw-r--r--arch/sparc/kernel/head.S37
-rw-r--r--arch/sparc/kernel/sclow.S86
-rw-r--r--arch/sparc/kernel/signal.c307
-rw-r--r--arch/sparc/kernel/sparc_ksyms.c8
-rw-r--r--arch/sparc/kernel/sunos_asm.S67
-rw-r--r--arch/sparc/kernel/sunos_ioctl.c230
-rw-r--r--arch/sparc/kernel/sys_solaris.c35
-rw-r--r--arch/sparc/kernel/sys_sunos.c1210
-rw-r--r--arch/sparc/kernel/systbls.S121
-rw-r--r--arch/sparc64/Kconfig47
-rw-r--r--arch/sparc64/Makefile1
-rw-r--r--arch/sparc64/defconfig29
-rw-r--r--arch/sparc64/kernel/Makefile9
-rw-r--r--arch/sparc64/kernel/binfmt_aout32.c419
-rw-r--r--arch/sparc64/kernel/entry.S61
-rw-r--r--arch/sparc64/kernel/signal.c1
-rw-r--r--arch/sparc64/kernel/signal32.c300
-rw-r--r--arch/sparc64/kernel/sparc64_ksyms.c41
-rw-r--r--arch/sparc64/kernel/sunos_ioctl32.c275
-rw-r--r--arch/sparc64/kernel/sys_sparc.c38
-rw-r--r--arch/sparc64/kernel/sys_sunos32.c1359
-rw-r--r--arch/sparc64/kernel/systbls.S122
-rw-r--r--arch/sparc64/kernel/systbls.h2
-rw-r--r--arch/sparc64/kernel/ttable.S14
-rw-r--r--arch/sparc64/solaris/Makefile10
-rw-r--r--arch/sparc64/solaris/conv.h38
-rw-r--r--arch/sparc64/solaris/entry64.S223
-rw-r--r--arch/sparc64/solaris/fs.c745
-rw-r--r--arch/sparc64/solaris/ioctl.c825
-rw-r--r--arch/sparc64/solaris/ipc.c126
-rw-r--r--arch/sparc64/solaris/misc.c786
-rw-r--r--arch/sparc64/solaris/signal.c429
-rw-r--r--arch/sparc64/solaris/signal.h108
-rw-r--r--arch/sparc64/solaris/socket.c461
-rw-r--r--arch/sparc64/solaris/socksys.c203
-rw-r--r--arch/sparc64/solaris/socksys.h208
-rw-r--r--arch/sparc64/solaris/systbl.S285
-rw-r--r--arch/sparc64/solaris/timod.c976
-rw-r--r--drivers/block/brd.c2
-rw-r--r--drivers/hid/hid-core.c19
-rw-r--r--drivers/hid/hid-debug.c2
-rw-r--r--drivers/hid/hid-input-quirks.c24
-rw-r--r--drivers/hid/usbhid/Kconfig12
-rw-r--r--drivers/hid/usbhid/Makefile3
-rw-r--r--drivers/hid/usbhid/hid-core.c69
-rw-r--r--drivers/hid/usbhid/hid-ff.c3
-rw-r--r--drivers/hid/usbhid/hid-lg2ff.c114
-rw-r--r--drivers/hid/usbhid/hid-quirks.c85
-rw-r--r--drivers/hid/usbhid/hiddev.c286
-rw-r--r--drivers/hid/usbhid/usbhid.h3
-rw-r--r--drivers/i2c/algos/Kconfig39
-rw-r--r--drivers/i2c/algos/i2c-algo-pca.c126
-rw-r--r--drivers/i2c/algos/i2c-algo-pca.h26
-rw-r--r--drivers/i2c/busses/Kconfig73
-rw-r--r--drivers/i2c/busses/Makefile3
-rw-r--r--drivers/i2c/busses/i2c-at91.c2
-rw-r--r--drivers/i2c/busses/i2c-au1550.c1
-rw-r--r--drivers/i2c/busses/i2c-bfin-twi.c475
-rw-r--r--drivers/i2c/busses/i2c-davinci.c9
-rw-r--r--drivers/i2c/busses/i2c-gpio.c1
-rw-r--r--drivers/i2c/busses/i2c-ibm_iic.c197
-rw-r--r--drivers/i2c/busses/i2c-iop3xx.c1
-rw-r--r--drivers/i2c/busses/i2c-ixp2000.c1
-rw-r--r--drivers/i2c/busses/i2c-mpc.c3
-rw-r--r--drivers/i2c/busses/i2c-ocores.c3
-rw-r--r--drivers/i2c/busses/i2c-omap.c1
-rw-r--r--drivers/i2c/busses/i2c-pca-isa.c53
-rw-r--r--drivers/i2c/busses/i2c-pca-platform.c298
-rw-r--r--drivers/i2c/busses/i2c-pmcmsp.c7
-rw-r--r--drivers/i2c/busses/i2c-pnx.c45
-rw-r--r--drivers/i2c/busses/i2c-powermac.c3
-rw-r--r--drivers/i2c/busses/i2c-pxa.c3
-rw-r--r--drivers/i2c/busses/i2c-s3c2410.c5
-rw-r--r--drivers/i2c/busses/i2c-sh7760.c577
-rw-r--r--drivers/i2c/busses/i2c-sh_mobile.c500
-rw-r--r--drivers/i2c/busses/i2c-simtec.c3
-rw-r--r--drivers/i2c/busses/i2c-versatile.c1
-rw-r--r--drivers/i2c/busses/scx200_acb.c2
-rw-r--r--drivers/i2c/chips/isp1301_omap.c28
-rw-r--r--drivers/i2c/i2c-core.c2
-rw-r--r--drivers/i2c/i2c-dev.c329
-rw-r--r--drivers/infiniband/hw/ipath/Kconfig2
-rw-r--r--drivers/infiniband/hw/ipath/Makefile6
-rw-r--r--drivers/infiniband/hw/ipath/ipath_driver.c2
-rw-r--r--drivers/infiniband/hw/ipath/ipath_iba7220.c23
-rw-r--r--drivers/infiniband/hw/ipath/ipath_verbs.c3
-rw-r--r--drivers/infiniband/hw/nes/nes.c6
-rw-r--r--drivers/infiniband/hw/nes/nes_nic.c9
-rw-r--r--drivers/mmc/core/core.c6
-rw-r--r--drivers/mmc/core/core.h4
-rw-r--r--drivers/mmc/core/host.c39
-rw-r--r--drivers/mmc/core/sdio_irq.c4
-rw-r--r--drivers/mmc/core/sdio_ops.c1
-rw-r--r--drivers/mmc/host/omap.c995
-rw-r--r--drivers/mmc/host/sdhci.c100
-rw-r--r--drivers/mmc/host/sdhci.h9
-rw-r--r--fs/Kconfig1
-rw-r--r--fs/Kconfig.binfmt2
-rw-r--r--fs/dlm/Makefile1
-rw-r--r--fs/dlm/config.c50
-rw-r--r--fs/dlm/config.h3
-rw-r--r--fs/dlm/dlm_internal.h8
-rw-r--r--fs/dlm/lock.c5
-rw-r--r--fs/dlm/lock.h1
-rw-r--r--fs/dlm/main.c7
-rw-r--r--fs/dlm/member.c34
-rw-r--r--fs/dlm/plock.c (renamed from fs/gfs2/locking/dlm/plock.c)169
-rw-r--r--fs/dlm/recoverd.c1
-rw-r--r--fs/gfs2/locking/dlm/Makefile2
-rw-r--r--fs/gfs2/locking/dlm/lock_dlm.h12
-rw-r--r--fs/gfs2/locking/dlm/main.c8
-rw-r--r--fs/gfs2/locking/dlm/mount.c21
-rw-r--r--fs/udf/Makefile2
-rw-r--r--fs/udf/balloc.c13
-rw-r--r--fs/udf/crc.c172
-rw-r--r--fs/udf/dir.c83
-rw-r--r--fs/udf/ecma_167.h13
-rw-r--r--fs/udf/file.c47
-rw-r--r--fs/udf/ialloc.c13
-rw-r--r--fs/udf/inode.c208
-rw-r--r--fs/udf/lowlevel.c1
-rw-r--r--fs/udf/misc.c26
-rw-r--r--fs/udf/namei.c218
-rw-r--r--fs/udf/partition.c67
-rw-r--r--fs/udf/super.c1262
-rw-r--r--fs/udf/symlink.c1
-rw-r--r--fs/udf/truncate.c81
-rw-r--r--fs/udf/udf_i.h30
-rw-r--r--fs/udf/udf_sb.h109
-rw-r--r--fs/udf/udfdecl.h67
-rw-r--r--fs/udf/udfend.h22
-rw-r--r--fs/udf/udftime.c35
-rw-r--r--fs/udf/unicode.c62
-rw-r--r--include/asm-arm/arch-omap/mmc.h2
-rw-r--r--include/asm-sh/i2c-sh7760.h22
-rw-r--r--include/asm-sparc/Kbuild1
-rw-r--r--include/asm-sparc/a.out-core.h52
-rw-r--r--include/asm-sparc/a.out.h97
-rw-r--r--include/asm-sparc/head.h33
-rw-r--r--include/asm-sparc/ioctls.h2
-rw-r--r--include/asm-sparc/mman.h13
-rw-r--r--include/asm-sparc/namei.h15
-rw-r--r--include/asm-sparc/pconf.h25
-rw-r--r--include/asm-sparc/processor.h3
-rw-r--r--include/asm-sparc/socket.h3
-rw-r--r--include/asm-sparc/solerrno.h132
-rw-r--r--include/asm-sparc/svr4.h119
-rw-r--r--include/asm-sparc/termios.h5
-rw-r--r--include/asm-sparc/user.h56
-rw-r--r--include/asm-sparc64/Kbuild1
-rw-r--r--include/asm-sparc64/a.out-core.h31
-rw-r--r--include/asm-sparc64/a.out.h1
-rw-r--r--include/asm-sparc64/ioctls.h2
-rw-r--r--include/asm-sparc64/mman.h13
-rw-r--r--include/asm-sparc64/namei.h15
-rw-r--r--include/asm-sparc64/pconf.h25
-rw-r--r--include/asm-sparc64/socket.h3
-rw-r--r--include/asm-sparc64/solerrno.h132
-rw-r--r--include/asm-sparc64/svr4.h120
-rw-r--r--include/asm-sparc64/termios.h5
-rw-r--r--include/asm-sparc64/ttable.h18
-rw-r--r--include/asm-sparc64/unistd.h10
-rw-r--r--include/asm-sparc64/user.h61
-rw-r--r--include/linux/Kbuild6
-rw-r--r--include/linux/dlm.h7
-rw-r--r--include/linux/dlm_device.h11
-rw-r--r--include/linux/dlm_plock.h50
-rw-r--r--include/linux/dlmconstants.h4
-rw-r--r--include/linux/hid.h17
-rw-r--r--include/linux/hidraw.h1
-rw-r--r--include/linux/i2c-algo-pca.h37
-rw-r--r--include/linux/i2c-pca-platform.h12
-rw-r--r--include/linux/lock_dlm_plock.h41
-rw-r--r--include/linux/udf_fs.h51
-rw-r--r--include/linux/udf_fs_i.h31
-rw-r--r--include/linux/udf_fs_sb.h117
-rw-r--r--kernel/sched.c1
-rw-r--r--net/core/sock.c9
186 files changed, 5161 insertions, 14549 deletions
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
index b45ea28abc99..448729fcaeb1 100644
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -261,17 +261,6 @@ Who: Michael Buesch <mb@bu3sch.de>
261 261
262--------------------------- 262---------------------------
263 263
264What: Solaris/SunOS syscall and binary support on Sparc
265When: 2.6.26
266Why: Largely unmaintained and almost entirely unused. File system
267 layering used to divert library and dynamic linker searches to
268 /usr/gnemul is extremely buggy and unfixable. Making it work
269 is largely pointless as without a lot of work only the most
270 trivial of Solaris binaries can work with the emulation code.
271Who: David S. Miller <davem@davemloft.net>
272
273---------------------------
274
275What: init_mm export 264What: init_mm export
276When: 2.6.26 265When: 2.6.26
277Why: Not used in-tree. The current out-of-tree users used it to 266Why: Not used in-tree. The current out-of-tree users used it to
diff --git a/Documentation/highuid.txt b/Documentation/highuid.txt
index 76034d9dbfc0..6bad6f1d1cac 100644
--- a/Documentation/highuid.txt
+++ b/Documentation/highuid.txt
@@ -28,8 +28,6 @@ What's left to be done for 32-bit UIDs on all Linux architectures:
28 uses the 32-bit UID system calls properly otherwise. 28 uses the 32-bit UID system calls properly otherwise.
29 29
30 This affects at least: 30 This affects at least:
31 SunOS emulation
32 Solaris emulation
33 iBCS on Intel 31 iBCS on Intel
34 32
35 sparc32 emulation on sparc64 33 sparc32 emulation on sparc64
diff --git a/Documentation/magic-number.txt b/Documentation/magic-number.txt
index bd450e797558..95070028d15e 100644
--- a/Documentation/magic-number.txt
+++ b/Documentation/magic-number.txt
@@ -95,7 +95,6 @@ RFCOMM_TTY_MAGIC 0x6d02 net/bluetooth/rfcomm/tty.c
95USB_SERIAL_PORT_MAGIC 0x7301 usb_serial_port drivers/usb/serial/usb-serial.h 95USB_SERIAL_PORT_MAGIC 0x7301 usb_serial_port drivers/usb/serial/usb-serial.h
96CG_MAGIC 0x00090255 ufs_cylinder_group include/linux/ufs_fs.h 96CG_MAGIC 0x00090255 ufs_cylinder_group include/linux/ufs_fs.h
97A2232_MAGIC 0x000a2232 gs_port drivers/char/ser_a2232.h 97A2232_MAGIC 0x000a2232 gs_port drivers/char/ser_a2232.h
98SOLARIS_SOCKET_MAGIC 0x000ADDED sol_socket_struct arch/sparc64/solaris/socksys.h
99RPORT_MAGIC 0x00525001 r_port drivers/char/rocket_int.h 98RPORT_MAGIC 0x00525001 r_port drivers/char/rocket_int.h
100LSEMAGIC 0x05091998 lse drivers/fc4/fc.c 99LSEMAGIC 0x05091998 lse drivers/fc4/fc.c
101GDTIOCTL_MAGIC 0x06030f07 gdth_iowr_str drivers/scsi/gdth_ioctl.h 100GDTIOCTL_MAGIC 0x06030f07 gdth_iowr_str drivers/scsi/gdth_ioctl.h
diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig
index c40343c54920..49590f8fe98c 100644
--- a/arch/sparc/Kconfig
+++ b/arch/sparc/Kconfig
@@ -27,9 +27,6 @@ config ARCH_NO_VIRT_TO_BUS
27config OF 27config OF
28 def_bool y 28 def_bool y
29 29
30config ARCH_SUPPORTS_AOUT
31 def_bool y
32
33config HZ 30config HZ
34 int 31 int
35 default 100 32 default 100
@@ -257,15 +254,6 @@ config SPARC_LED
257 254
258source "fs/Kconfig.binfmt" 255source "fs/Kconfig.binfmt"
259 256
260config SUNOS_EMUL
261 bool "SunOS binary emulation"
262 help
263 This allows you to run most SunOS binaries. If you want to do this,
264 say Y here and place appropriate files in /usr/gnemul/sunos. See
265 <http://www.ultralinux.org/faq.html> for more information. If you
266 want to run SunOS binaries on an Ultra you must also say Y to
267 "Kernel support for 32-bit a.out binaries" above.
268
269source "mm/Kconfig" 257source "mm/Kconfig"
270 258
271endmenu 259endmenu
diff --git a/arch/sparc/defconfig b/arch/sparc/defconfig
index f7a509149199..6a2c57a2fe71 100644
--- a/arch/sparc/defconfig
+++ b/arch/sparc/defconfig
@@ -1,7 +1,7 @@
1# 1#
2# Automatically generated make config: don't edit 2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.23-rc1 3# Linux kernel version: 2.6.25
4# Wed Jul 25 15:30:21 2007 4# Sun Apr 20 01:49:51 2008
5# 5#
6CONFIG_MMU=y 6CONFIG_MMU=y
7CONFIG_HIGHMEM=y 7CONFIG_HIGHMEM=y
@@ -9,18 +9,15 @@ CONFIG_ZONE_DMA=y
9CONFIG_GENERIC_ISA_DMA=y 9CONFIG_GENERIC_ISA_DMA=y
10CONFIG_ARCH_NO_VIRT_TO_BUS=y 10CONFIG_ARCH_NO_VIRT_TO_BUS=y
11CONFIG_OF=y 11CONFIG_OF=y
12CONFIG_HZ=100
12CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" 13CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
13 14
14# 15#
15# Code maturity level options 16# General setup
16# 17#
17CONFIG_EXPERIMENTAL=y 18CONFIG_EXPERIMENTAL=y
18CONFIG_BROKEN_ON_SMP=y 19CONFIG_BROKEN_ON_SMP=y
19CONFIG_INIT_ENV_ARG_LIMIT=32 20CONFIG_INIT_ENV_ARG_LIMIT=32
20
21#
22# General setup
23#
24CONFIG_LOCALVERSION="" 21CONFIG_LOCALVERSION=""
25CONFIG_LOCALVERSION_AUTO=y 22CONFIG_LOCALVERSION_AUTO=y
26CONFIG_SWAP=y 23CONFIG_SWAP=y
@@ -29,12 +26,23 @@ CONFIG_SYSVIPC_SYSCTL=y
29CONFIG_POSIX_MQUEUE=y 26CONFIG_POSIX_MQUEUE=y
30# CONFIG_BSD_PROCESS_ACCT is not set 27# CONFIG_BSD_PROCESS_ACCT is not set
31# CONFIG_TASKSTATS is not set 28# CONFIG_TASKSTATS is not set
32# CONFIG_USER_NS is not set
33# CONFIG_AUDIT is not set 29# CONFIG_AUDIT is not set
34# CONFIG_IKCONFIG is not set 30# CONFIG_IKCONFIG is not set
35CONFIG_LOG_BUF_SHIFT=14 31CONFIG_LOG_BUF_SHIFT=14
32# CONFIG_CGROUPS is not set
33CONFIG_GROUP_SCHED=y
34CONFIG_FAIR_GROUP_SCHED=y
35CONFIG_RT_GROUP_SCHED=y
36CONFIG_USER_SCHED=y
37# CONFIG_CGROUP_SCHED is not set
36CONFIG_SYSFS_DEPRECATED=y 38CONFIG_SYSFS_DEPRECATED=y
39CONFIG_SYSFS_DEPRECATED_V2=y
37# CONFIG_RELAY is not set 40# CONFIG_RELAY is not set
41CONFIG_NAMESPACES=y
42# CONFIG_UTS_NS is not set
43# CONFIG_IPC_NS is not set
44# CONFIG_USER_NS is not set
45# CONFIG_PID_NS is not set
38CONFIG_BLK_DEV_INITRD=y 46CONFIG_BLK_DEV_INITRD=y
39CONFIG_INITRAMFS_SOURCE="" 47CONFIG_INITRAMFS_SOURCE=""
40# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set 48# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
@@ -49,6 +57,7 @@ CONFIG_HOTPLUG=y
49CONFIG_PRINTK=y 57CONFIG_PRINTK=y
50CONFIG_BUG=y 58CONFIG_BUG=y
51CONFIG_ELF_CORE=y 59CONFIG_ELF_CORE=y
60CONFIG_COMPAT_BRK=y
52CONFIG_BASE_FULL=y 61CONFIG_BASE_FULL=y
53CONFIG_FUTEX=y 62CONFIG_FUTEX=y
54CONFIG_ANON_INODES=y 63CONFIG_ANON_INODES=y
@@ -61,6 +70,13 @@ CONFIG_VM_EVENT_COUNTERS=y
61CONFIG_SLAB=y 70CONFIG_SLAB=y
62# CONFIG_SLUB is not set 71# CONFIG_SLUB is not set
63# CONFIG_SLOB is not set 72# CONFIG_SLOB is not set
73# CONFIG_PROFILING is not set
74# CONFIG_MARKERS is not set
75CONFIG_HAVE_OPROFILE=y
76# CONFIG_HAVE_KPROBES is not set
77# CONFIG_HAVE_KRETPROBES is not set
78CONFIG_PROC_PAGE_MONITOR=y
79CONFIG_SLABINFO=y
64CONFIG_RT_MUTEXES=y 80CONFIG_RT_MUTEXES=y
65# CONFIG_TINY_SHMEM is not set 81# CONFIG_TINY_SHMEM is not set
66CONFIG_BASE_SMALL=0 82CONFIG_BASE_SMALL=0
@@ -88,6 +104,7 @@ CONFIG_IOSCHED_CFQ=y
88CONFIG_DEFAULT_CFQ=y 104CONFIG_DEFAULT_CFQ=y
89# CONFIG_DEFAULT_NOOP is not set 105# CONFIG_DEFAULT_NOOP is not set
90CONFIG_DEFAULT_IOSCHED="cfq" 106CONFIG_DEFAULT_IOSCHED="cfq"
107CONFIG_CLASSIC_RCU=y
91 108
92# 109#
93# General machine setup 110# General machine setup
@@ -113,14 +130,13 @@ CONFIG_SUN_PM=y
113CONFIG_PCI=y 130CONFIG_PCI=y
114CONFIG_PCI_SYSCALL=y 131CONFIG_PCI_SYSCALL=y
115# CONFIG_ARCH_SUPPORTS_MSI is not set 132# CONFIG_ARCH_SUPPORTS_MSI is not set
133CONFIG_PCI_LEGACY=y
116# CONFIG_PCI_DEBUG is not set 134# CONFIG_PCI_DEBUG is not set
117# CONFIG_NO_DMA is not set 135# CONFIG_NO_DMA is not set
118CONFIG_SUN_OPENPROMFS=m 136CONFIG_SUN_OPENPROMFS=m
119# CONFIG_SPARC_LED is not set 137# CONFIG_SPARC_LED is not set
120CONFIG_BINFMT_ELF=y 138CONFIG_BINFMT_ELF=y
121CONFIG_BINFMT_AOUT=y
122CONFIG_BINFMT_MISC=m 139CONFIG_BINFMT_MISC=m
123CONFIG_SUNOS_EMUL=y
124CONFIG_SELECT_MEMORY_MODEL=y 140CONFIG_SELECT_MEMORY_MODEL=y
125CONFIG_FLATMEM_MANUAL=y 141CONFIG_FLATMEM_MANUAL=y
126# CONFIG_DISCONTIGMEM_MANUAL is not set 142# CONFIG_DISCONTIGMEM_MANUAL is not set
@@ -128,6 +144,7 @@ CONFIG_FLATMEM_MANUAL=y
128CONFIG_FLATMEM=y 144CONFIG_FLATMEM=y
129CONFIG_FLAT_NODE_MEM_MAP=y 145CONFIG_FLAT_NODE_MEM_MAP=y
130# CONFIG_SPARSEMEM_STATIC is not set 146# CONFIG_SPARSEMEM_STATIC is not set
147# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
131CONFIG_SPLIT_PTLOCK_CPUS=4 148CONFIG_SPLIT_PTLOCK_CPUS=4
132# CONFIG_RESOURCES_64BIT is not set 149# CONFIG_RESOURCES_64BIT is not set
133CONFIG_ZONE_DMA_FLAG=1 150CONFIG_ZONE_DMA_FLAG=1
@@ -148,6 +165,7 @@ CONFIG_XFRM=y
148CONFIG_XFRM_USER=m 165CONFIG_XFRM_USER=m
149# CONFIG_XFRM_SUB_POLICY is not set 166# CONFIG_XFRM_SUB_POLICY is not set
150# CONFIG_XFRM_MIGRATE is not set 167# CONFIG_XFRM_MIGRATE is not set
168# CONFIG_XFRM_STATISTICS is not set
151CONFIG_NET_KEY=m 169CONFIG_NET_KEY=m
152# CONFIG_NET_KEY_MIGRATE is not set 170# CONFIG_NET_KEY_MIGRATE is not set
153CONFIG_INET=y 171CONFIG_INET=y
@@ -170,6 +188,7 @@ CONFIG_INET_TUNNEL=y
170CONFIG_INET_XFRM_MODE_TRANSPORT=y 188CONFIG_INET_XFRM_MODE_TRANSPORT=y
171CONFIG_INET_XFRM_MODE_TUNNEL=y 189CONFIG_INET_XFRM_MODE_TUNNEL=y
172CONFIG_INET_XFRM_MODE_BEET=y 190CONFIG_INET_XFRM_MODE_BEET=y
191# CONFIG_INET_LRO is not set
173CONFIG_INET_DIAG=y 192CONFIG_INET_DIAG=y
174CONFIG_INET_TCP_DIAG=y 193CONFIG_INET_TCP_DIAG=y
175# CONFIG_TCP_CONG_ADVANCED is not set 194# CONFIG_TCP_CONG_ADVANCED is not set
@@ -191,8 +210,10 @@ CONFIG_INET6_XFRM_MODE_TUNNEL=m
191CONFIG_INET6_XFRM_MODE_BEET=m 210CONFIG_INET6_XFRM_MODE_BEET=m
192# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set 211# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
193CONFIG_IPV6_SIT=m 212CONFIG_IPV6_SIT=m
213CONFIG_IPV6_NDISC_NODETYPE=y
194CONFIG_IPV6_TUNNEL=m 214CONFIG_IPV6_TUNNEL=m
195# CONFIG_IPV6_MULTIPLE_TABLES is not set 215# CONFIG_IPV6_MULTIPLE_TABLES is not set
216# CONFIG_IPV6_MROUTE is not set
196# CONFIG_NETWORK_SECMARK is not set 217# CONFIG_NETWORK_SECMARK is not set
197# CONFIG_NETFILTER is not set 218# CONFIG_NETFILTER is not set
198# CONFIG_IP_DCCP is not set 219# CONFIG_IP_DCCP is not set
@@ -214,10 +235,6 @@ CONFIG_SCTP_HMAC_MD5=y
214# CONFIG_LAPB is not set 235# CONFIG_LAPB is not set
215# CONFIG_ECONET is not set 236# CONFIG_ECONET is not set
216# CONFIG_WAN_ROUTER is not set 237# CONFIG_WAN_ROUTER is not set
217
218#
219# QoS and/or fair queueing
220#
221# CONFIG_NET_SCHED is not set 238# CONFIG_NET_SCHED is not set
222 239
223# 240#
@@ -225,6 +242,7 @@ CONFIG_SCTP_HMAC_MD5=y
225# 242#
226CONFIG_NET_PKTGEN=m 243CONFIG_NET_PKTGEN=m
227# CONFIG_HAMRADIO is not set 244# CONFIG_HAMRADIO is not set
245# CONFIG_CAN is not set
228# CONFIG_IRDA is not set 246# CONFIG_IRDA is not set
229# CONFIG_BT is not set 247# CONFIG_BT is not set
230CONFIG_AF_RXRPC=m 248CONFIG_AF_RXRPC=m
@@ -248,6 +266,7 @@ CONFIG_AF_RXRPC=m
248# 266#
249# Generic Driver Options 267# Generic Driver Options
250# 268#
269CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
251CONFIG_STANDALONE=y 270CONFIG_STANDALONE=y
252CONFIG_PREVENT_FIRMWARE_BUILD=y 271CONFIG_PREVENT_FIRMWARE_BUILD=y
253# CONFIG_FW_LOADER is not set 272# CONFIG_FW_LOADER is not set
@@ -271,7 +290,7 @@ CONFIG_BLK_DEV_CRYPTOLOOP=m
271CONFIG_BLK_DEV_RAM=y 290CONFIG_BLK_DEV_RAM=y
272CONFIG_BLK_DEV_RAM_COUNT=16 291CONFIG_BLK_DEV_RAM_COUNT=16
273CONFIG_BLK_DEV_RAM_SIZE=4096 292CONFIG_BLK_DEV_RAM_SIZE=4096
274CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 293# CONFIG_BLK_DEV_XIP is not set
275# CONFIG_CDROM_PKTCDVD is not set 294# CONFIG_CDROM_PKTCDVD is not set
276# CONFIG_ATA_OVER_ETH is not set 295# CONFIG_ATA_OVER_ETH is not set
277CONFIG_MISC_DEVICES=y 296CONFIG_MISC_DEVICES=y
@@ -279,6 +298,8 @@ CONFIG_MISC_DEVICES=y
279# CONFIG_EEPROM_93CX6 is not set 298# CONFIG_EEPROM_93CX6 is not set
280# CONFIG_SGI_IOC4 is not set 299# CONFIG_SGI_IOC4 is not set
281# CONFIG_TIFM_CORE is not set 300# CONFIG_TIFM_CORE is not set
301# CONFIG_ENCLOSURE_SERVICES is not set
302CONFIG_HAVE_IDE=y
282# CONFIG_IDE is not set 303# CONFIG_IDE is not set
283 304
284# 305#
@@ -318,6 +339,7 @@ CONFIG_SCSI_SPI_ATTRS=y
318# CONFIG_SCSI_FC_ATTRS is not set 339# CONFIG_SCSI_FC_ATTRS is not set
319# CONFIG_SCSI_ISCSI_ATTRS is not set 340# CONFIG_SCSI_ISCSI_ATTRS is not set
320# CONFIG_SCSI_SAS_LIBSAS is not set 341# CONFIG_SCSI_SAS_LIBSAS is not set
342# CONFIG_SCSI_SRP_ATTRS is not set
321CONFIG_SCSI_LOWLEVEL=y 343CONFIG_SCSI_LOWLEVEL=y
322# CONFIG_ISCSI_TCP is not set 344# CONFIG_ISCSI_TCP is not set
323# CONFIG_BLK_DEV_3W_XXXX_RAID is not set 345# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
@@ -338,6 +360,7 @@ CONFIG_SCSI_LOWLEVEL=y
338# CONFIG_SCSI_IPS is not set 360# CONFIG_SCSI_IPS is not set
339# CONFIG_SCSI_INITIO is not set 361# CONFIG_SCSI_INITIO is not set
340# CONFIG_SCSI_INIA100 is not set 362# CONFIG_SCSI_INIA100 is not set
363# CONFIG_SCSI_MVSAS is not set
341# CONFIG_SCSI_STEX is not set 364# CONFIG_SCSI_STEX is not set
342# CONFIG_SCSI_SYM53C8XX_2 is not set 365# CONFIG_SCSI_SYM53C8XX_2 is not set
343# CONFIG_SCSI_QLOGIC_1280 is not set 366# CONFIG_SCSI_QLOGIC_1280 is not set
@@ -353,14 +376,7 @@ CONFIG_SCSI_SUNESP=y
353# CONFIG_SCSI_SRP is not set 376# CONFIG_SCSI_SRP is not set
354# CONFIG_ATA is not set 377# CONFIG_ATA is not set
355# CONFIG_MD is not set 378# CONFIG_MD is not set
356
357#
358# Fusion MPT device support
359#
360# CONFIG_FUSION is not set 379# CONFIG_FUSION is not set
361# CONFIG_FUSION_SPI is not set
362# CONFIG_FUSION_FC is not set
363# CONFIG_FUSION_SAS is not set
364 380
365# 381#
366# IEEE 1394 (FireWire) support 382# IEEE 1394 (FireWire) support
@@ -375,6 +391,7 @@ CONFIG_DUMMY=m
375# CONFIG_MACVLAN is not set 391# CONFIG_MACVLAN is not set
376# CONFIG_EQUALIZER is not set 392# CONFIG_EQUALIZER is not set
377CONFIG_TUN=m 393CONFIG_TUN=m
394# CONFIG_VETH is not set
378# CONFIG_ARCNET is not set 395# CONFIG_ARCNET is not set
379# CONFIG_PHYLIB is not set 396# CONFIG_PHYLIB is not set
380CONFIG_NET_ETHERNET=y 397CONFIG_NET_ETHERNET=y
@@ -388,11 +405,20 @@ CONFIG_SUNQE=m
388# CONFIG_NET_VENDOR_3COM is not set 405# CONFIG_NET_VENDOR_3COM is not set
389# CONFIG_NET_TULIP is not set 406# CONFIG_NET_TULIP is not set
390# CONFIG_HP100 is not set 407# CONFIG_HP100 is not set
408# CONFIG_IBM_NEW_EMAC_ZMII is not set
409# CONFIG_IBM_NEW_EMAC_RGMII is not set
410# CONFIG_IBM_NEW_EMAC_TAH is not set
411# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
391# CONFIG_NET_PCI is not set 412# CONFIG_NET_PCI is not set
413# CONFIG_B44 is not set
392CONFIG_NETDEV_1000=y 414CONFIG_NETDEV_1000=y
393# CONFIG_ACENIC is not set 415# CONFIG_ACENIC is not set
394# CONFIG_DL2K is not set 416# CONFIG_DL2K is not set
395# CONFIG_E1000 is not set 417# CONFIG_E1000 is not set
418# CONFIG_E1000E is not set
419# CONFIG_E1000E_ENABLED is not set
420# CONFIG_IP1000 is not set
421# CONFIG_IGB is not set
396# CONFIG_MYRI_SBUS is not set 422# CONFIG_MYRI_SBUS is not set
397# CONFIG_NS83820 is not set 423# CONFIG_NS83820 is not set
398# CONFIG_HAMACHI is not set 424# CONFIG_HAMACHI is not set
@@ -409,11 +435,15 @@ CONFIG_NETDEV_1000=y
409CONFIG_NETDEV_10000=y 435CONFIG_NETDEV_10000=y
410# CONFIG_CHELSIO_T1 is not set 436# CONFIG_CHELSIO_T1 is not set
411# CONFIG_CHELSIO_T3 is not set 437# CONFIG_CHELSIO_T3 is not set
438# CONFIG_IXGBE is not set
412# CONFIG_IXGB is not set 439# CONFIG_IXGB is not set
413# CONFIG_S2IO is not set 440# CONFIG_S2IO is not set
414# CONFIG_MYRI10GE is not set 441# CONFIG_MYRI10GE is not set
415# CONFIG_NETXEN_NIC is not set 442# CONFIG_NETXEN_NIC is not set
443# CONFIG_NIU is not set
416# CONFIG_MLX4_CORE is not set 444# CONFIG_MLX4_CORE is not set
445# CONFIG_TEHUTI is not set
446# CONFIG_BNX2X is not set
417# CONFIG_TR is not set 447# CONFIG_TR is not set
418 448
419# 449#
@@ -421,13 +451,13 @@ CONFIG_NETDEV_10000=y
421# 451#
422# CONFIG_WLAN_PRE80211 is not set 452# CONFIG_WLAN_PRE80211 is not set
423# CONFIG_WLAN_80211 is not set 453# CONFIG_WLAN_80211 is not set
454# CONFIG_IWLWIFI_LEDS is not set
424# CONFIG_WAN is not set 455# CONFIG_WAN is not set
425# CONFIG_FDDI is not set 456# CONFIG_FDDI is not set
426# CONFIG_HIPPI is not set 457# CONFIG_HIPPI is not set
427# CONFIG_PPP is not set 458# CONFIG_PPP is not set
428# CONFIG_SLIP is not set 459# CONFIG_SLIP is not set
429# CONFIG_NET_FC is not set 460# CONFIG_NET_FC is not set
430# CONFIG_SHAPER is not set
431# CONFIG_NETCONSOLE is not set 461# CONFIG_NETCONSOLE is not set
432# CONFIG_NETPOLL is not set 462# CONFIG_NETPOLL is not set
433# CONFIG_NET_POLL_CONTROLLER is not set 463# CONFIG_NET_POLL_CONTROLLER is not set
@@ -449,7 +479,6 @@ CONFIG_INPUT_MOUSEDEV_PSAUX=y
449CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 479CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
450CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 480CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
451CONFIG_INPUT_JOYDEV=m 481CONFIG_INPUT_JOYDEV=m
452# CONFIG_INPUT_TSDEV is not set
453CONFIG_INPUT_EVDEV=m 482CONFIG_INPUT_EVDEV=m
454CONFIG_INPUT_EVBUG=m 483CONFIG_INPUT_EVBUG=m
455 484
@@ -498,6 +527,7 @@ CONFIG_VT_CONSOLE=y
498CONFIG_HW_CONSOLE=y 527CONFIG_HW_CONSOLE=y
499# CONFIG_VT_HW_CONSOLE_BINDING is not set 528# CONFIG_VT_HW_CONSOLE_BINDING is not set
500# CONFIG_SERIAL_NONSTANDARD is not set 529# CONFIG_SERIAL_NONSTANDARD is not set
530# CONFIG_NOZOMI is not set
501 531
502# 532#
503# Serial drivers 533# Serial drivers
@@ -519,7 +549,6 @@ CONFIG_UNIX98_PTYS=y
519CONFIG_LEGACY_PTYS=y 549CONFIG_LEGACY_PTYS=y
520CONFIG_LEGACY_PTY_COUNT=256 550CONFIG_LEGACY_PTY_COUNT=256
521# CONFIG_IPMI_HANDLER is not set 551# CONFIG_IPMI_HANDLER is not set
522# CONFIG_WATCHDOG is not set
523CONFIG_HW_RANDOM=m 552CONFIG_HW_RANDOM=m
524CONFIG_JS_RTC=m 553CONFIG_JS_RTC=m
525# CONFIG_R3964 is not set 554# CONFIG_R3964 is not set
@@ -538,9 +567,9 @@ CONFIG_DEVPORT=y
538# CONFIG_POWER_SUPPLY is not set 567# CONFIG_POWER_SUPPLY is not set
539CONFIG_HWMON=y 568CONFIG_HWMON=y
540# CONFIG_HWMON_VID is not set 569# CONFIG_HWMON_VID is not set
541# CONFIG_SENSORS_ABITUGURU is not set 570# CONFIG_SENSORS_I5K_AMB is not set
542# CONFIG_SENSORS_ABITUGURU3 is not set
543# CONFIG_SENSORS_F71805F is not set 571# CONFIG_SENSORS_F71805F is not set
572# CONFIG_SENSORS_F71882FG is not set
544# CONFIG_SENSORS_IT87 is not set 573# CONFIG_SENSORS_IT87 is not set
545# CONFIG_SENSORS_PC87360 is not set 574# CONFIG_SENSORS_PC87360 is not set
546# CONFIG_SENSORS_PC87427 is not set 575# CONFIG_SENSORS_PC87427 is not set
@@ -553,6 +582,14 @@ CONFIG_HWMON=y
553# CONFIG_SENSORS_W83627HF is not set 582# CONFIG_SENSORS_W83627HF is not set
554# CONFIG_SENSORS_W83627EHF is not set 583# CONFIG_SENSORS_W83627EHF is not set
555# CONFIG_HWMON_DEBUG_CHIP is not set 584# CONFIG_HWMON_DEBUG_CHIP is not set
585# CONFIG_THERMAL is not set
586# CONFIG_WATCHDOG is not set
587
588#
589# Sonics Silicon Backplane
590#
591CONFIG_SSB_POSSIBLE=y
592# CONFIG_SSB is not set
556 593
557# 594#
558# Multifunction device drivers 595# Multifunction device drivers
@@ -569,15 +606,15 @@ CONFIG_HWMON=y
569# 606#
570# Graphics support 607# Graphics support
571# 608#
609# CONFIG_VGASTATE is not set
610# CONFIG_VIDEO_OUTPUT_CONTROL is not set
611# CONFIG_FB is not set
572# CONFIG_BACKLIGHT_LCD_SUPPORT is not set 612# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
573 613
574# 614#
575# Display device support 615# Display device support
576# 616#
577# CONFIG_DISPLAY_SUPPORT is not set 617# CONFIG_DISPLAY_SUPPORT is not set
578# CONFIG_VGASTATE is not set
579# CONFIG_VIDEO_OUTPUT_CONTROL is not set
580# CONFIG_FB is not set
581 618
582# 619#
583# Console display driver support 620# Console display driver support
@@ -592,6 +629,7 @@ CONFIG_DUMMY_CONSOLE=y
592CONFIG_HID_SUPPORT=y 629CONFIG_HID_SUPPORT=y
593CONFIG_HID=y 630CONFIG_HID=y
594# CONFIG_HID_DEBUG is not set 631# CONFIG_HID_DEBUG is not set
632# CONFIG_HIDRAW is not set
595CONFIG_USB_SUPPORT=y 633CONFIG_USB_SUPPORT=y
596CONFIG_USB_ARCH_HAS_HCD=y 634CONFIG_USB_ARCH_HAS_HCD=y
597CONFIG_USB_ARCH_HAS_OHCI=y 635CONFIG_USB_ARCH_HAS_OHCI=y
@@ -601,34 +639,14 @@ CONFIG_USB_ARCH_HAS_EHCI=y
601# 639#
602# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' 640# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
603# 641#
604
605#
606# USB Gadget Support
607#
608# CONFIG_USB_GADGET is not set 642# CONFIG_USB_GADGET is not set
609# CONFIG_MMC is not set 643# CONFIG_MMC is not set
644# CONFIG_MEMSTICK is not set
610# CONFIG_NEW_LEDS is not set 645# CONFIG_NEW_LEDS is not set
611# CONFIG_INFINIBAND is not set 646# CONFIG_INFINIBAND is not set
612
613#
614# Real Time Clock
615#
616# CONFIG_RTC_CLASS is not set 647# CONFIG_RTC_CLASS is not set
617 648
618# 649#
619# DMA Engine support
620#
621# CONFIG_DMA_ENGINE is not set
622
623#
624# DMA Clients
625#
626
627#
628# DMA Devices
629#
630
631#
632# Userspace I/O 650# Userspace I/O
633# 651#
634# CONFIG_UIO is not set 652# CONFIG_UIO is not set
@@ -664,18 +682,14 @@ CONFIG_FS_MBCACHE=y
664CONFIG_FS_POSIX_ACL=y 682CONFIG_FS_POSIX_ACL=y
665CONFIG_XFS_FS=m 683CONFIG_XFS_FS=m
666CONFIG_XFS_QUOTA=y 684CONFIG_XFS_QUOTA=y
667CONFIG_XFS_SECURITY=y
668CONFIG_XFS_POSIX_ACL=y 685CONFIG_XFS_POSIX_ACL=y
669CONFIG_XFS_RT=y 686CONFIG_XFS_RT=y
670# CONFIG_GFS2_FS is not set
671# CONFIG_OCFS2_FS is not set 687# CONFIG_OCFS2_FS is not set
672# CONFIG_MINIX_FS is not set 688CONFIG_DNOTIFY=y
673CONFIG_ROMFS_FS=m
674CONFIG_INOTIFY=y 689CONFIG_INOTIFY=y
675CONFIG_INOTIFY_USER=y 690CONFIG_INOTIFY_USER=y
676# CONFIG_QUOTA is not set 691# CONFIG_QUOTA is not set
677CONFIG_QUOTACTL=y 692CONFIG_QUOTACTL=y
678CONFIG_DNOTIFY=y
679CONFIG_AUTOFS_FS=m 693CONFIG_AUTOFS_FS=m
680CONFIG_AUTOFS4_FS=m 694CONFIG_AUTOFS4_FS=m
681# CONFIG_FUSE_FS is not set 695# CONFIG_FUSE_FS is not set
@@ -704,7 +718,6 @@ CONFIG_PROC_SYSCTL=y
704CONFIG_SYSFS=y 718CONFIG_SYSFS=y
705# CONFIG_TMPFS is not set 719# CONFIG_TMPFS is not set
706# CONFIG_HUGETLB_PAGE is not set 720# CONFIG_HUGETLB_PAGE is not set
707CONFIG_RAMFS=y
708# CONFIG_CONFIGFS_FS is not set 721# CONFIG_CONFIGFS_FS is not set
709 722
710# 723#
@@ -721,14 +734,13 @@ CONFIG_BEFS_FS=m
721# CONFIG_EFS_FS is not set 734# CONFIG_EFS_FS is not set
722# CONFIG_CRAMFS is not set 735# CONFIG_CRAMFS is not set
723# CONFIG_VXFS_FS is not set 736# CONFIG_VXFS_FS is not set
737# CONFIG_MINIX_FS is not set
724# CONFIG_HPFS_FS is not set 738# CONFIG_HPFS_FS is not set
725# CONFIG_QNX4FS_FS is not set 739# CONFIG_QNX4FS_FS is not set
740CONFIG_ROMFS_FS=m
726# CONFIG_SYSV_FS is not set 741# CONFIG_SYSV_FS is not set
727# CONFIG_UFS_FS is not set 742# CONFIG_UFS_FS is not set
728 743CONFIG_NETWORK_FILESYSTEMS=y
729#
730# Network File Systems
731#
732CONFIG_NFS_FS=y 744CONFIG_NFS_FS=y
733# CONFIG_NFS_V3 is not set 745# CONFIG_NFS_V3 is not set
734# CONFIG_NFS_V4 is not set 746# CONFIG_NFS_V4 is not set
@@ -760,10 +772,6 @@ CONFIG_AFS_FS=m
760# CONFIG_PARTITION_ADVANCED is not set 772# CONFIG_PARTITION_ADVANCED is not set
761CONFIG_MSDOS_PARTITION=y 773CONFIG_MSDOS_PARTITION=y
762CONFIG_SUN_PARTITION=y 774CONFIG_SUN_PARTITION=y
763
764#
765# Native Language Support
766#
767CONFIG_NLS=y 775CONFIG_NLS=y
768CONFIG_NLS_DEFAULT="iso8859-1" 776CONFIG_NLS_DEFAULT="iso8859-1"
769# CONFIG_NLS_CODEPAGE_437 is not set 777# CONFIG_NLS_CODEPAGE_437 is not set
@@ -804,21 +812,14 @@ CONFIG_NLS_DEFAULT="iso8859-1"
804# CONFIG_NLS_KOI8_R is not set 812# CONFIG_NLS_KOI8_R is not set
805# CONFIG_NLS_KOI8_U is not set 813# CONFIG_NLS_KOI8_U is not set
806# CONFIG_NLS_UTF8 is not set 814# CONFIG_NLS_UTF8 is not set
807
808#
809# Distributed Lock Manager
810#
811# CONFIG_DLM is not set 815# CONFIG_DLM is not set
812 816
813# 817#
814# Instrumentation Support
815#
816# CONFIG_PROFILING is not set
817
818#
819# Kernel hacking 818# Kernel hacking
820# 819#
820CONFIG_TRACE_IRQFLAGS_SUPPORT=y
821# CONFIG_PRINTK_TIME is not set 821# CONFIG_PRINTK_TIME is not set
822# CONFIG_ENABLE_WARN_DEPRECATED is not set
822CONFIG_ENABLE_MUST_CHECK=y 823CONFIG_ENABLE_MUST_CHECK=y
823CONFIG_MAGIC_SYSRQ=y 824CONFIG_MAGIC_SYSRQ=y
824# CONFIG_UNUSED_SYMBOLS is not set 825# CONFIG_UNUSED_SYMBOLS is not set
@@ -842,9 +843,12 @@ CONFIG_DEBUG_BUGVERBOSE=y
842# CONFIG_DEBUG_INFO is not set 843# CONFIG_DEBUG_INFO is not set
843# CONFIG_DEBUG_VM is not set 844# CONFIG_DEBUG_VM is not set
844# CONFIG_DEBUG_LIST is not set 845# CONFIG_DEBUG_LIST is not set
845CONFIG_FORCED_INLINING=y 846# CONFIG_DEBUG_SG is not set
847# CONFIG_BOOT_PRINTK_DELAY is not set
846# CONFIG_RCU_TORTURE_TEST is not set 848# CONFIG_RCU_TORTURE_TEST is not set
849# CONFIG_BACKTRACE_SELF_TEST is not set
847# CONFIG_FAULT_INJECTION is not set 850# CONFIG_FAULT_INJECTION is not set
851# CONFIG_SAMPLES is not set
848# CONFIG_DEBUG_STACK_USAGE is not set 852# CONFIG_DEBUG_STACK_USAGE is not set
849 853
850# 854#
@@ -853,9 +857,12 @@ CONFIG_FORCED_INLINING=y
853CONFIG_KEYS=y 857CONFIG_KEYS=y
854# CONFIG_KEYS_DEBUG_PROC_KEYS is not set 858# CONFIG_KEYS_DEBUG_PROC_KEYS is not set
855# CONFIG_SECURITY is not set 859# CONFIG_SECURITY is not set
860# CONFIG_SECURITY_FILE_CAPABILITIES is not set
856CONFIG_CRYPTO=y 861CONFIG_CRYPTO=y
857CONFIG_CRYPTO_ALGAPI=y 862CONFIG_CRYPTO_ALGAPI=y
863CONFIG_CRYPTO_AEAD=y
858CONFIG_CRYPTO_BLKCIPHER=y 864CONFIG_CRYPTO_BLKCIPHER=y
865# CONFIG_CRYPTO_SEQIV is not set
859CONFIG_CRYPTO_HASH=y 866CONFIG_CRYPTO_HASH=y
860CONFIG_CRYPTO_MANAGER=y 867CONFIG_CRYPTO_MANAGER=y
861CONFIG_CRYPTO_HMAC=y 868CONFIG_CRYPTO_HMAC=y
@@ -873,6 +880,10 @@ CONFIG_CRYPTO_ECB=m
873CONFIG_CRYPTO_CBC=y 880CONFIG_CRYPTO_CBC=y
874CONFIG_CRYPTO_PCBC=m 881CONFIG_CRYPTO_PCBC=m
875# CONFIG_CRYPTO_LRW is not set 882# CONFIG_CRYPTO_LRW is not set
883# CONFIG_CRYPTO_XTS is not set
884# CONFIG_CRYPTO_CTR is not set
885# CONFIG_CRYPTO_GCM is not set
886# CONFIG_CRYPTO_CCM is not set
876# CONFIG_CRYPTO_CRYPTD is not set 887# CONFIG_CRYPTO_CRYPTD is not set
877CONFIG_CRYPTO_DES=y 888CONFIG_CRYPTO_DES=y
878# CONFIG_CRYPTO_FCRYPT is not set 889# CONFIG_CRYPTO_FCRYPT is not set
@@ -887,11 +898,15 @@ CONFIG_CRYPTO_CAST6=m
887CONFIG_CRYPTO_ARC4=m 898CONFIG_CRYPTO_ARC4=m
888# CONFIG_CRYPTO_KHAZAD is not set 899# CONFIG_CRYPTO_KHAZAD is not set
889# CONFIG_CRYPTO_ANUBIS is not set 900# CONFIG_CRYPTO_ANUBIS is not set
901# CONFIG_CRYPTO_SEED is not set
902# CONFIG_CRYPTO_SALSA20 is not set
890CONFIG_CRYPTO_DEFLATE=y 903CONFIG_CRYPTO_DEFLATE=y
891CONFIG_CRYPTO_MICHAEL_MIC=m 904CONFIG_CRYPTO_MICHAEL_MIC=m
892CONFIG_CRYPTO_CRC32C=m 905CONFIG_CRYPTO_CRC32C=m
893# CONFIG_CRYPTO_CAMELLIA is not set 906# CONFIG_CRYPTO_CAMELLIA is not set
894# CONFIG_CRYPTO_TEST is not set 907# CONFIG_CRYPTO_TEST is not set
908CONFIG_CRYPTO_AUTHENC=y
909# CONFIG_CRYPTO_LZO is not set
895# CONFIG_CRYPTO_HW is not set 910# CONFIG_CRYPTO_HW is not set
896 911
897# 912#
diff --git a/arch/sparc/kernel/Makefile b/arch/sparc/kernel/Makefile
index 2712bb166f6f..59700aaaae93 100644
--- a/arch/sparc/kernel/Makefile
+++ b/arch/sparc/kernel/Makefile
@@ -9,9 +9,9 @@ EXTRA_AFLAGS := -ansi
9IRQ_OBJS := irq.o sun4m_irq.o sun4c_irq.o sun4d_irq.o 9IRQ_OBJS := irq.o sun4m_irq.o sun4c_irq.o sun4d_irq.o
10obj-y := entry.o wof.o wuf.o etrap.o rtrap.o traps.o $(IRQ_OBJS) \ 10obj-y := entry.o wof.o wuf.o etrap.o rtrap.o traps.o $(IRQ_OBJS) \
11 process.o signal.o ioport.o setup.o idprom.o \ 11 process.o signal.o ioport.o setup.o idprom.o \
12 sys_sparc.o sunos_asm.o systbls.o \ 12 sys_sparc.o systbls.o \
13 time.o windows.o cpu.o devices.o sclow.o \ 13 time.o windows.o cpu.o devices.o \
14 tadpole.o tick14.o ptrace.o sys_solaris.o \ 14 tadpole.o tick14.o ptrace.o \
15 unaligned.o una_asm.o muldiv.o \ 15 unaligned.o una_asm.o muldiv.o \
16 prom.o of_device.o devres.o 16 prom.o of_device.o devres.o
17 17
@@ -25,7 +25,3 @@ obj-$(CONFIG_PCI) += ebus.o
25obj-$(CONFIG_SUN_PM) += apc.o pmc.o 25obj-$(CONFIG_SUN_PM) += apc.o pmc.o
26obj-$(CONFIG_MODULES) += module.o sparc_ksyms.o 26obj-$(CONFIG_MODULES) += module.o sparc_ksyms.o
27obj-$(CONFIG_SPARC_LED) += led.o 27obj-$(CONFIG_SPARC_LED) += led.o
28
29ifdef CONFIG_SUNOS_EMUL
30obj-y += sys_sunos.o sunos_ioctl.o
31endif
diff --git a/arch/sparc/kernel/entry.S b/arch/sparc/kernel/entry.S
index c2eed8f71516..135644f8add7 100644
--- a/arch/sparc/kernel/entry.S
+++ b/arch/sparc/kernel/entry.S
@@ -1186,36 +1186,6 @@ srmmu_fault:
1186 1186
1187 RESTORE_ALL 1187 RESTORE_ALL
1188 1188
1189#ifdef CONFIG_SUNOS_EMUL
1190 /* SunOS uses syscall zero as the 'indirect syscall' it looks
1191 * like indir_syscall(scall_num, arg0, arg1, arg2...); etc.
1192 * This is complete brain damage.
1193 */
1194 .globl sunos_indir
1195sunos_indir:
1196 mov %o7, %l4
1197 cmp %o0, NR_SYSCALLS
1198 blu,a 1f
1199 sll %o0, 0x2, %o0
1200
1201 sethi %hi(sunos_nosys), %l6
1202 b 2f
1203 or %l6, %lo(sunos_nosys), %l6
1204
12051:
1206 set sunos_sys_table, %l7
1207 ld [%l7 + %o0], %l6
1208
12092:
1210 mov %o1, %o0
1211 mov %o2, %o1
1212 mov %o3, %o2
1213 mov %o4, %o3
1214 mov %o5, %o4
1215 call %l6
1216 mov %l4, %o7
1217#endif
1218
1219 .align 4 1189 .align 4
1220 .globl sys_nis_syscall 1190 .globl sys_nis_syscall
1221sys_nis_syscall: 1191sys_nis_syscall:
@@ -1232,6 +1202,16 @@ sys_execve:
1232 call sparc_execve 1202 call sparc_execve
1233 mov %l5, %o7 1203 mov %l5, %o7
1234 1204
1205 .globl sunos_execv
1206sunos_execv:
1207 st %g0, [%sp + STACKFRAME_SZ + PT_I2]
1208
1209 call sparc_execve
1210 add %sp, STACKFRAME_SZ, %o0
1211
1212 b ret_sys_call
1213 ld [%sp + STACKFRAME_SZ + PT_I0], %o0
1214
1235 .align 4 1215 .align 4
1236 .globl sys_pipe 1216 .globl sys_pipe
1237sys_pipe: 1217sys_pipe:
@@ -1394,7 +1374,7 @@ ret_from_fork:
1394 b ret_sys_call 1374 b ret_sys_call
1395 ld [%sp + STACKFRAME_SZ + PT_I0], %o0 1375 ld [%sp + STACKFRAME_SZ + PT_I0], %o0
1396 1376
1397 /* Linux native and SunOS system calls enter here... */ 1377 /* Linux native system calls enter here... */
1398 .align 4 1378 .align 4
1399 .globl linux_sparc_syscall 1379 .globl linux_sparc_syscall
1400linux_sparc_syscall: 1380linux_sparc_syscall:
@@ -1472,170 +1452,6 @@ linux_syscall_trace2:
1472 st %l2, [%sp + STACKFRAME_SZ + PT_NPC] 1452 st %l2, [%sp + STACKFRAME_SZ + PT_NPC]
1473 1453
1474 1454
1475 /*
1476 * Solaris system calls and indirect system calls enter here.
1477 *
1478 * I have named the solaris indirect syscalls like that because
1479 * it seems like Solaris has some fast path syscalls that can
1480 * be handled as indirect system calls. - mig
1481 */
1482
1483linux_syscall_for_solaris:
1484 sethi %hi(sys_call_table), %l7
1485 b linux_sparc_syscall
1486 or %l7, %lo(sys_call_table), %l7
1487
1488 .align 4
1489 .globl solaris_syscall
1490solaris_syscall:
1491 cmp %g1,59
1492 be linux_syscall_for_solaris
1493 cmp %g1,2
1494 be linux_syscall_for_solaris
1495 cmp %g1,42
1496 be linux_syscall_for_solaris
1497 cmp %g1,119
1498 be,a linux_syscall_for_solaris
1499 mov 2, %g1
15001:
1501 SAVE_ALL_HEAD
1502 rd %wim, %l3
1503
1504 wr %l0, PSR_ET, %psr
1505 nop
1506 nop
1507 mov %i0, %l5
1508
1509 call do_solaris_syscall
1510 add %sp, STACKFRAME_SZ, %o0
1511
1512 st %o0, [%sp + STACKFRAME_SZ + PT_I0]
1513 set PSR_C, %g2
1514 cmp %o0, -ERESTART_RESTARTBLOCK
1515 bgeu 1f
1516 ld [%sp + STACKFRAME_SZ + PT_PSR], %g3
1517
1518 /* System call success, clear Carry condition code. */
1519 andn %g3, %g2, %g3
1520 clr %l6
1521 b 2f
1522 st %g3, [%sp + STACKFRAME_SZ + PT_PSR]
1523
15241:
1525 /* System call failure, set Carry condition code.
1526 * Also, get abs(errno) to return to the process.
1527 */
1528 sub %g0, %o0, %o0
1529 mov 1, %l6
1530 st %o0, [%sp + STACKFRAME_SZ + PT_I0]
1531 or %g3, %g2, %g3
1532 st %g3, [%sp + STACKFRAME_SZ + PT_PSR]
1533
1534 /* Advance the pc and npc over the trap instruction.
1535 * If the npc is unaligned (has a 1 in the lower byte), it means
1536 * the kernel does not want us to play magic (ie, skipping over
1537 * traps). Mainly when the Solaris code wants to set some PC and
1538 * nPC (setcontext).
1539 */
15402:
1541 ld [%sp + STACKFRAME_SZ + PT_NPC], %l1 /* pc = npc */
1542 andcc %l1, 1, %g0
1543 bne 1f
1544 add %l1, 0x4, %l2 /* npc = npc+4 */
1545 st %l1, [%sp + STACKFRAME_SZ + PT_PC]
1546 b ret_trap_entry
1547 st %l2, [%sp + STACKFRAME_SZ + PT_NPC]
1548
1549 /* kernel knows what it is doing, fixup npc and continue */
15501:
1551 sub %l1, 1, %l1
1552 b ret_trap_entry
1553 st %l1, [%sp + STACKFRAME_SZ + PT_NPC]
1554
1555#ifndef CONFIG_SUNOS_EMUL
1556 .align 4
1557 .globl sunos_syscall
1558sunos_syscall:
1559 SAVE_ALL_HEAD
1560 rd %wim, %l3
1561 wr %l0, PSR_ET, %psr
1562 nop
1563 nop
1564 mov %i0, %l5
1565 call do_sunos_syscall
1566 add %sp, STACKFRAME_SZ, %o0
1567#endif
1568
1569 /* {net, open}bsd system calls enter here... */
1570 .align 4
1571 .globl bsd_syscall
1572bsd_syscall:
1573 /* Direct access to user regs, must faster. */
1574 cmp %g1, NR_SYSCALLS
1575 blu,a 1f
1576 sll %g1, 2, %l4
1577
1578 set sys_ni_syscall, %l7
1579 b bsd_is_too_hard
1580 nop
1581
15821:
1583 ld [%l7 + %l4], %l7
1584
1585 .globl bsd_is_too_hard
1586bsd_is_too_hard:
1587 rd %wim, %l3
1588 SAVE_ALL
1589
1590 wr %l0, PSR_ET, %psr
1591 WRITE_PAUSE
1592
15932:
1594 mov %i0, %o0
1595 mov %i1, %o1
1596 mov %i2, %o2
1597 mov %i0, %l5
1598 mov %i3, %o3
1599 mov %i4, %o4
1600 call %l7
1601 mov %i5, %o5
1602
1603 st %o0, [%sp + STACKFRAME_SZ + PT_I0]
1604 set PSR_C, %g2
1605 cmp %o0, -ERESTART_RESTARTBLOCK
1606 bgeu 1f
1607 ld [%sp + STACKFRAME_SZ + PT_PSR], %g3
1608
1609 /* System call success, clear Carry condition code. */
1610 andn %g3, %g2, %g3
1611 clr %l6
1612 b 2f
1613 st %g3, [%sp + STACKFRAME_SZ + PT_PSR]
1614
16151:
1616 /* System call failure, set Carry condition code.
1617 * Also, get abs(errno) to return to the process.
1618 */
1619 sub %g0, %o0, %o0
1620#if 0 /* XXX todo XXX */
1621 sethi %hi(bsd_xlatb_rorl), %o3
1622 or %o3, %lo(bsd_xlatb_rorl), %o3
1623 sll %o0, 2, %o0
1624 ld [%o3 + %o0], %o0
1625#endif
1626 mov 1, %l6
1627 st %o0, [%sp + STACKFRAME_SZ + PT_I0]
1628 or %g3, %g2, %g3
1629 st %g3, [%sp + STACKFRAME_SZ + PT_PSR]
1630
1631 /* Advance the pc and npc over the trap instruction. */
16322:
1633 ld [%sp + STACKFRAME_SZ + PT_NPC], %l1 /* pc = npc */
1634 add %l1, 0x4, %l2 /* npc = npc+4 */
1635 st %l1, [%sp + STACKFRAME_SZ + PT_PC]
1636 b ret_trap_entry
1637 st %l2, [%sp + STACKFRAME_SZ + PT_NPC]
1638
1639/* Saving and restoring the FPU state is best done from lowlevel code. 1455/* Saving and restoring the FPU state is best done from lowlevel code.
1640 * 1456 *
1641 * void fpsave(unsigned long *fpregs, unsigned long *fsr, 1457 * void fpsave(unsigned long *fpregs, unsigned long *fsr,
diff --git a/arch/sparc/kernel/errtbls.c b/arch/sparc/kernel/errtbls.c
deleted file mode 100644
index ed14df7116e9..000000000000
--- a/arch/sparc/kernel/errtbls.c
+++ /dev/null
@@ -1,144 +0,0 @@
1/* errtbls.c: Error number conversion tables.
2 *
3 * Copyright (C) 1995, 2007 David S. Miller (davem@davemloft.net)
4 *
5 * Based upon preliminary work which is:
6 *
7 * Copyright (C) 1995 Adrian M. Rodriguez (adrian@remus.rutgers.edu)
8 */
9
10#include <asm/solerrno.h> /* Solaris errnos */
11
12/* Here is the table which converts between Linux error number values
13 * to the equivalent under Solaris. Note that since the Linux ones
14 * have been set up to match exactly those of SunOS, no translation
15 * table is needed for that OS.
16 */
17
18int solaris_errno[] = {
19 0,
20 SOL_EPERM,
21 SOL_ENOENT,
22 SOL_ESRCH,
23 SOL_EINTR,
24 SOL_EIO,
25 SOL_ENXIO,
26 SOL_E2BIG,
27 SOL_ENOEXEC,
28 SOL_EBADF,
29 SOL_ECHILD,
30 SOL_EAGAIN,
31 SOL_ENOMEM,
32 SOL_EACCES,
33 SOL_EFAULT,
34 SOL_NOTBLK,
35 SOL_EBUSY,
36 SOL_EEXIST,
37 SOL_EXDEV,
38 SOL_ENODEV,
39 SOL_ENOTDIR,
40 SOL_EISDIR,
41 SOL_EINVAL,
42 SOL_ENFILE,
43 SOL_EMFILE,
44 SOL_ENOTTY,
45 SOL_ETXTBSY,
46 SOL_EFBIG,
47 SOL_ENOSPC,
48 SOL_ESPIPE,
49 SOL_EROFS,
50 SOL_EMLINK,
51 SOL_EPIPE,
52 SOL_EDOM,
53 SOL_ERANGE,
54 SOL_EWOULDBLOCK,
55 SOL_EINPROGRESS,
56 SOL_EALREADY,
57 SOL_ENOTSOCK,
58 SOL_EDESTADDRREQ,
59 SOL_EMSGSIZE,
60 SOL_EPROTOTYPE,
61 SOL_ENOPROTOOPT,
62 SOL_EPROTONOSUPPORT,
63 SOL_ESOCKTNOSUPPORT,
64 SOL_EOPNOTSUPP,
65 SOL_EPFNOSUPPORT,
66 SOL_EAFNOSUPPORT,
67 SOL_EADDRINUSE,
68 SOL_EADDRNOTAVAIL,
69 SOL_ENETDOWN,
70 SOL_ENETUNREACH,
71 SOL_ENETRESET,
72 SOL_ECONNABORTED,
73 SOL_ECONNRESET,
74 SOL_ENOBUFS,
75 SOL_EISCONN,
76 SOL_ENOTONN,
77 SOL_ESHUTDOWN,
78 SOL_ETOOMANYREFS,
79 SOL_ETIMEDOUT,
80 SOL_ECONNREFUSED,
81 SOL_ELOOP,
82 SOL_ENAMETOOLONG,
83 SOL_EHOSTDOWN,
84 SOL_EHOSTUNREACH,
85 SOL_ENOTEMPTY,
86 SOL_EPROCLIM,
87 SOL_EUSERS,
88 SOL_EDQUOT,
89 SOL_ESTALE,
90 SOL_EREMOTE,
91 SOL_ENOSTR,
92 SOL_ETIME,
93 SOL_ENOSR,
94 SOL_ENOMSG,
95 SOL_EBADMSG,
96 SOL_IDRM,
97 SOL_EDEADLK,
98 SOL_ENOLCK,
99 SOL_ENONET,
100 SOL_ERREMOTE,
101 SOL_ENOLINK,
102 SOL_EADV,
103 SOL_ESRMNT,
104 SOL_ECOMM,
105 SOL_EPROTO,
106 SOL_EMULTIHOP,
107 SOL_EINVAL, /* EDOTDOT XXX??? */
108 SOL_REMCHG,
109 SOL_NOSYS,
110 SOL_STRPIPE,
111 SOL_EOVERFLOW,
112 SOL_EBADFD,
113 SOL_ECHRNG,
114 SOL_EL2NSYNC,
115 SOL_EL3HLT,
116 SOL_EL3RST,
117 SOL_NRNG,
118 SOL_EUNATCH,
119 SOL_ENOCSI,
120 SOL_EL2HLT,
121 SOL_EBADE,
122 SOL_EBADR,
123 SOL_EXFULL,
124 SOL_ENOANO,
125 SOL_EBADRQC,
126 SOL_EBADSLT,
127 SOL_EDEADLOCK,
128 SOL_EBFONT,
129 SOL_ELIBEXEC,
130 SOL_ENODATA,
131 SOL_ELIBBAD,
132 SOL_ENOPKG,
133 SOL_ELIBACC,
134 SOL_ENOTUNIQ,
135 SOL_ERESTART,
136 SOL_EUCLEAN,
137 SOL_ENOTNAM,
138 SOL_ENAVAIL,
139 SOL_EISNAM,
140 SOL_EREMOTEIO,
141 SOL_EILSEQ,
142 SOL_ELIBMAX,
143 SOL_ELIBSCN,
144};
diff --git a/arch/sparc/kernel/head.S b/arch/sparc/kernel/head.S
index 9a219e8b5ddb..b7f1e81c8ff2 100644
--- a/arch/sparc/kernel/head.S
+++ b/arch/sparc/kernel/head.S
@@ -78,11 +78,6 @@ sun4e_notsup:
78 .asciz "Sparc-Linux sun4e support does not exist\n\n" 78 .asciz "Sparc-Linux sun4e support does not exist\n\n"
79 .align 4 79 .align 4
80 80
81#ifndef CONFIG_SUNOS_EMUL
82#undef SUNOS_SYSCALL_TRAP
83#define SUNOS_SYSCALL_TRAP SUNOS_NO_SYSCALL_TRAP
84#endif
85
86 /* The Sparc trap table, bootloader gives us control at _start. */ 81 /* The Sparc trap table, bootloader gives us control at _start. */
87 .text 82 .text
88 .globl start, _stext, _start, __stext 83 .globl start, _stext, _start, __stext
@@ -158,7 +153,7 @@ t_bad6f:BAD_TRAP(0x6f) BAD_TRAP(0x70) BAD_TRAP(0x71) BAD_TRAP(0x72) BAD_TRAP(0x7
158t_bad74:BAD_TRAP(0x74) BAD_TRAP(0x75) BAD_TRAP(0x76) BAD_TRAP(0x77) BAD_TRAP(0x78) 153t_bad74:BAD_TRAP(0x74) BAD_TRAP(0x75) BAD_TRAP(0x76) BAD_TRAP(0x77) BAD_TRAP(0x78)
159t_bad79:BAD_TRAP(0x79) BAD_TRAP(0x7a) BAD_TRAP(0x7b) BAD_TRAP(0x7c) BAD_TRAP(0x7d) 154t_bad79:BAD_TRAP(0x79) BAD_TRAP(0x7a) BAD_TRAP(0x7b) BAD_TRAP(0x7c) BAD_TRAP(0x7d)
160t_bad7e:BAD_TRAP(0x7e) BAD_TRAP(0x7f) 155t_bad7e:BAD_TRAP(0x7e) BAD_TRAP(0x7f)
161t_sunos:SUNOS_SYSCALL_TRAP /* SunOS System Call */ 156t_bad80:BAD_TRAP(0x80) /* SunOS System Call */
162t_sbkpt:BREAKPOINT_TRAP /* Software Breakpoint/KGDB */ 157t_sbkpt:BREAKPOINT_TRAP /* Software Breakpoint/KGDB */
163t_divz: TRAP_ENTRY(0x82, do_hw_divzero) /* Divide by zero trap */ 158t_divz: TRAP_ENTRY(0x82, do_hw_divzero) /* Divide by zero trap */
164t_flwin:TRAP_ENTRY(0x83, do_flush_windows) /* Flush Windows Trap */ 159t_flwin:TRAP_ENTRY(0x83, do_flush_windows) /* Flush Windows Trap */
@@ -166,8 +161,8 @@ t_clwin:BAD_TRAP(0x84) /* Clean Windows Trap */
166t_rchk: BAD_TRAP(0x85) /* Range Check */ 161t_rchk: BAD_TRAP(0x85) /* Range Check */
167t_funal:BAD_TRAP(0x86) /* Fix Unaligned Access Trap */ 162t_funal:BAD_TRAP(0x86) /* Fix Unaligned Access Trap */
168t_iovf: BAD_TRAP(0x87) /* Integer Overflow Trap */ 163t_iovf: BAD_TRAP(0x87) /* Integer Overflow Trap */
169t_slowl:SOLARIS_SYSCALL_TRAP /* Slowaris System Call */ 164t_bad88:BAD_TRAP(0x88) /* Slowaris System Call */
170t_netbs:NETBSD_SYSCALL_TRAP /* Net-B.S. System Call */ 165t_bad89:BAD_TRAP(0x89) /* Net-B.S. System Call */
171t_bad8a:BAD_TRAP(0x8a) BAD_TRAP(0x8b) BAD_TRAP(0x8c) BAD_TRAP(0x8d) BAD_TRAP(0x8e) 166t_bad8a:BAD_TRAP(0x8a) BAD_TRAP(0x8b) BAD_TRAP(0x8c) BAD_TRAP(0x8d) BAD_TRAP(0x8e)
172t_bad8f:BAD_TRAP(0x8f) 167t_bad8f:BAD_TRAP(0x8f)
173t_linux:LINUX_SYSCALL_TRAP /* Linux System Call */ 168t_linux:LINUX_SYSCALL_TRAP /* Linux System Call */
@@ -178,7 +173,7 @@ t_getcc:GETCC_TRAP /* Get Condition Codes */
178t_setcc:SETCC_TRAP /* Set Condition Codes */ 173t_setcc:SETCC_TRAP /* Set Condition Codes */
179t_getpsr:GETPSR_TRAP /* Get PSR Register */ 174t_getpsr:GETPSR_TRAP /* Get PSR Register */
180t_bada3:BAD_TRAP(0xa3) BAD_TRAP(0xa4) BAD_TRAP(0xa5) BAD_TRAP(0xa6) 175t_bada3:BAD_TRAP(0xa3) BAD_TRAP(0xa4) BAD_TRAP(0xa5) BAD_TRAP(0xa6)
181t_slowi:INDIRECT_SOLARIS_SYSCALL(156) 176t_bada7:BAD_TRAP(0xa7)
182t_bada8:BAD_TRAP(0xa8) BAD_TRAP(0xa9) BAD_TRAP(0xaa) BAD_TRAP(0xab) 177t_bada8:BAD_TRAP(0xa8) BAD_TRAP(0xa9) BAD_TRAP(0xaa) BAD_TRAP(0xab)
183t_badac:BAD_TRAP(0xac) BAD_TRAP(0xad) BAD_TRAP(0xae) BAD_TRAP(0xaf) BAD_TRAP(0xb0) 178t_badac:BAD_TRAP(0xac) BAD_TRAP(0xad) BAD_TRAP(0xae) BAD_TRAP(0xaf) BAD_TRAP(0xb0)
184t_badb1:BAD_TRAP(0xb1) BAD_TRAP(0xb2) BAD_TRAP(0xb3) BAD_TRAP(0xb4) BAD_TRAP(0xb5) 179t_badb1:BAD_TRAP(0xb1) BAD_TRAP(0xb2) BAD_TRAP(0xb3) BAD_TRAP(0xb4) BAD_TRAP(0xb5)
@@ -243,19 +238,19 @@ trapbase_cpu1:
243 BAD_TRAP(0x74) BAD_TRAP(0x75) BAD_TRAP(0x76) BAD_TRAP(0x77) BAD_TRAP(0x78) 238 BAD_TRAP(0x74) BAD_TRAP(0x75) BAD_TRAP(0x76) BAD_TRAP(0x77) BAD_TRAP(0x78)
244 BAD_TRAP(0x79) BAD_TRAP(0x7a) BAD_TRAP(0x7b) BAD_TRAP(0x7c) BAD_TRAP(0x7d) 239 BAD_TRAP(0x79) BAD_TRAP(0x7a) BAD_TRAP(0x7b) BAD_TRAP(0x7c) BAD_TRAP(0x7d)
245 BAD_TRAP(0x7e) BAD_TRAP(0x7f) 240 BAD_TRAP(0x7e) BAD_TRAP(0x7f)
246 SUNOS_SYSCALL_TRAP 241 BAD_TRAP(0x80)
247 BREAKPOINT_TRAP 242 BREAKPOINT_TRAP
248 TRAP_ENTRY(0x82, do_hw_divzero) 243 TRAP_ENTRY(0x82, do_hw_divzero)
249 TRAP_ENTRY(0x83, do_flush_windows) BAD_TRAP(0x84) BAD_TRAP(0x85) 244 TRAP_ENTRY(0x83, do_flush_windows) BAD_TRAP(0x84) BAD_TRAP(0x85)
250 BAD_TRAP(0x86) BAD_TRAP(0x87) SOLARIS_SYSCALL_TRAP 245 BAD_TRAP(0x86) BAD_TRAP(0x87) BAD_TRAP(0x88)
251 NETBSD_SYSCALL_TRAP BAD_TRAP(0x8a) BAD_TRAP(0x8b) BAD_TRAP(0x8c) 246 BAD_TRAP(0x89) BAD_TRAP(0x8a) BAD_TRAP(0x8b) BAD_TRAP(0x8c)
252 BAD_TRAP(0x8d) BAD_TRAP(0x8e) BAD_TRAP(0x8f) 247 BAD_TRAP(0x8d) BAD_TRAP(0x8e) BAD_TRAP(0x8f)
253 LINUX_SYSCALL_TRAP BAD_TRAP(0x91) BAD_TRAP(0x92) BAD_TRAP(0x93) BAD_TRAP(0x94) 248 LINUX_SYSCALL_TRAP BAD_TRAP(0x91) BAD_TRAP(0x92) BAD_TRAP(0x93) BAD_TRAP(0x94)
254 BAD_TRAP(0x95) BAD_TRAP(0x96) BAD_TRAP(0x97) BAD_TRAP(0x98) BAD_TRAP(0x99) 249 BAD_TRAP(0x95) BAD_TRAP(0x96) BAD_TRAP(0x97) BAD_TRAP(0x98) BAD_TRAP(0x99)
255 BAD_TRAP(0x9a) BAD_TRAP(0x9b) BAD_TRAP(0x9c) BAD_TRAP(0x9d) BAD_TRAP(0x9e) 250 BAD_TRAP(0x9a) BAD_TRAP(0x9b) BAD_TRAP(0x9c) BAD_TRAP(0x9d) BAD_TRAP(0x9e)
256 BAD_TRAP(0x9f) GETCC_TRAP SETCC_TRAP GETPSR_TRAP 251 BAD_TRAP(0x9f) GETCC_TRAP SETCC_TRAP GETPSR_TRAP
257 BAD_TRAP(0xa3) BAD_TRAP(0xa4) BAD_TRAP(0xa5) BAD_TRAP(0xa6) 252 BAD_TRAP(0xa3) BAD_TRAP(0xa4) BAD_TRAP(0xa5) BAD_TRAP(0xa6)
258 INDIRECT_SOLARIS_SYSCALL(156) BAD_TRAP(0xa8) BAD_TRAP(0xa9) BAD_TRAP(0xaa) BAD_TRAP(0xab) 253 BAD_TRAP(0xa7) BAD_TRAP(0xa8) BAD_TRAP(0xa9) BAD_TRAP(0xaa) BAD_TRAP(0xab)
259 BAD_TRAP(0xac) BAD_TRAP(0xad) BAD_TRAP(0xae) BAD_TRAP(0xaf) BAD_TRAP(0xb0) 254 BAD_TRAP(0xac) BAD_TRAP(0xad) BAD_TRAP(0xae) BAD_TRAP(0xaf) BAD_TRAP(0xb0)
260 BAD_TRAP(0xb1) BAD_TRAP(0xb2) BAD_TRAP(0xb3) BAD_TRAP(0xb4) BAD_TRAP(0xb5) 255 BAD_TRAP(0xb1) BAD_TRAP(0xb2) BAD_TRAP(0xb3) BAD_TRAP(0xb4) BAD_TRAP(0xb5)
261 BAD_TRAP(0xb6) BAD_TRAP(0xb7) BAD_TRAP(0xb8) BAD_TRAP(0xb9) BAD_TRAP(0xba) 256 BAD_TRAP(0xb6) BAD_TRAP(0xb7) BAD_TRAP(0xb8) BAD_TRAP(0xb9) BAD_TRAP(0xba)
@@ -311,19 +306,19 @@ trapbase_cpu2:
311 BAD_TRAP(0x74) BAD_TRAP(0x75) BAD_TRAP(0x76) BAD_TRAP(0x77) BAD_TRAP(0x78) 306 BAD_TRAP(0x74) BAD_TRAP(0x75) BAD_TRAP(0x76) BAD_TRAP(0x77) BAD_TRAP(0x78)
312 BAD_TRAP(0x79) BAD_TRAP(0x7a) BAD_TRAP(0x7b) BAD_TRAP(0x7c) BAD_TRAP(0x7d) 307 BAD_TRAP(0x79) BAD_TRAP(0x7a) BAD_TRAP(0x7b) BAD_TRAP(0x7c) BAD_TRAP(0x7d)
313 BAD_TRAP(0x7e) BAD_TRAP(0x7f) 308 BAD_TRAP(0x7e) BAD_TRAP(0x7f)
314 SUNOS_SYSCALL_TRAP 309 BAD_TRAP(0x80)
315 BREAKPOINT_TRAP 310 BREAKPOINT_TRAP
316 TRAP_ENTRY(0x82, do_hw_divzero) 311 TRAP_ENTRY(0x82, do_hw_divzero)
317 TRAP_ENTRY(0x83, do_flush_windows) BAD_TRAP(0x84) BAD_TRAP(0x85) 312 TRAP_ENTRY(0x83, do_flush_windows) BAD_TRAP(0x84) BAD_TRAP(0x85)
318 BAD_TRAP(0x86) BAD_TRAP(0x87) SOLARIS_SYSCALL_TRAP 313 BAD_TRAP(0x86) BAD_TRAP(0x87) BAD_TRAP(0x88)
319 NETBSD_SYSCALL_TRAP BAD_TRAP(0x8a) BAD_TRAP(0x8b) BAD_TRAP(0x8c) 314 BAD_TRAP(0x89) BAD_TRAP(0x8a) BAD_TRAP(0x8b) BAD_TRAP(0x8c)
320 BAD_TRAP(0x8d) BAD_TRAP(0x8e) BAD_TRAP(0x8f) 315 BAD_TRAP(0x8d) BAD_TRAP(0x8e) BAD_TRAP(0x8f)
321 LINUX_SYSCALL_TRAP BAD_TRAP(0x91) BAD_TRAP(0x92) BAD_TRAP(0x93) BAD_TRAP(0x94) 316 LINUX_SYSCALL_TRAP BAD_TRAP(0x91) BAD_TRAP(0x92) BAD_TRAP(0x93) BAD_TRAP(0x94)
322 BAD_TRAP(0x95) BAD_TRAP(0x96) BAD_TRAP(0x97) BAD_TRAP(0x98) BAD_TRAP(0x99) 317 BAD_TRAP(0x95) BAD_TRAP(0x96) BAD_TRAP(0x97) BAD_TRAP(0x98) BAD_TRAP(0x99)
323 BAD_TRAP(0x9a) BAD_TRAP(0x9b) BAD_TRAP(0x9c) BAD_TRAP(0x9d) BAD_TRAP(0x9e) 318 BAD_TRAP(0x9a) BAD_TRAP(0x9b) BAD_TRAP(0x9c) BAD_TRAP(0x9d) BAD_TRAP(0x9e)
324 BAD_TRAP(0x9f) GETCC_TRAP SETCC_TRAP GETPSR_TRAP 319 BAD_TRAP(0x9f) GETCC_TRAP SETCC_TRAP GETPSR_TRAP
325 BAD_TRAP(0xa3) BAD_TRAP(0xa4) BAD_TRAP(0xa5) BAD_TRAP(0xa6) 320 BAD_TRAP(0xa3) BAD_TRAP(0xa4) BAD_TRAP(0xa5) BAD_TRAP(0xa6)
326 INDIRECT_SOLARIS_SYSCALL(156) BAD_TRAP(0xa8) BAD_TRAP(0xa9) BAD_TRAP(0xaa) BAD_TRAP(0xab) 321 BAD_TRAP(0xa7) BAD_TRAP(0xa8) BAD_TRAP(0xa9) BAD_TRAP(0xaa) BAD_TRAP(0xab)
327 BAD_TRAP(0xac) BAD_TRAP(0xad) BAD_TRAP(0xae) BAD_TRAP(0xaf) BAD_TRAP(0xb0) 322 BAD_TRAP(0xac) BAD_TRAP(0xad) BAD_TRAP(0xae) BAD_TRAP(0xaf) BAD_TRAP(0xb0)
328 BAD_TRAP(0xb1) BAD_TRAP(0xb2) BAD_TRAP(0xb3) BAD_TRAP(0xb4) BAD_TRAP(0xb5) 323 BAD_TRAP(0xb1) BAD_TRAP(0xb2) BAD_TRAP(0xb3) BAD_TRAP(0xb4) BAD_TRAP(0xb5)
329 BAD_TRAP(0xb6) BAD_TRAP(0xb7) BAD_TRAP(0xb8) BAD_TRAP(0xb9) BAD_TRAP(0xba) 324 BAD_TRAP(0xb6) BAD_TRAP(0xb7) BAD_TRAP(0xb8) BAD_TRAP(0xb9) BAD_TRAP(0xba)
@@ -379,19 +374,19 @@ trapbase_cpu3:
379 BAD_TRAP(0x74) BAD_TRAP(0x75) BAD_TRAP(0x76) BAD_TRAP(0x77) BAD_TRAP(0x78) 374 BAD_TRAP(0x74) BAD_TRAP(0x75) BAD_TRAP(0x76) BAD_TRAP(0x77) BAD_TRAP(0x78)
380 BAD_TRAP(0x79) BAD_TRAP(0x7a) BAD_TRAP(0x7b) BAD_TRAP(0x7c) BAD_TRAP(0x7d) 375 BAD_TRAP(0x79) BAD_TRAP(0x7a) BAD_TRAP(0x7b) BAD_TRAP(0x7c) BAD_TRAP(0x7d)
381 BAD_TRAP(0x7e) BAD_TRAP(0x7f) 376 BAD_TRAP(0x7e) BAD_TRAP(0x7f)
382 SUNOS_SYSCALL_TRAP 377 BAD_TRAP(0x80)
383 BREAKPOINT_TRAP 378 BREAKPOINT_TRAP
384 TRAP_ENTRY(0x82, do_hw_divzero) 379 TRAP_ENTRY(0x82, do_hw_divzero)
385 TRAP_ENTRY(0x83, do_flush_windows) BAD_TRAP(0x84) BAD_TRAP(0x85) 380 TRAP_ENTRY(0x83, do_flush_windows) BAD_TRAP(0x84) BAD_TRAP(0x85)
386 BAD_TRAP(0x86) BAD_TRAP(0x87) SOLARIS_SYSCALL_TRAP 381 BAD_TRAP(0x86) BAD_TRAP(0x87) BAD_TRAP(0x88)
387 NETBSD_SYSCALL_TRAP BAD_TRAP(0x8a) BAD_TRAP(0x8b) BAD_TRAP(0x8c) 382 BAD_TRAP(0x89) BAD_TRAP(0x8a) BAD_TRAP(0x8b) BAD_TRAP(0x8c)
388 BAD_TRAP(0x8d) BAD_TRAP(0x8e) BAD_TRAP(0x8f) 383 BAD_TRAP(0x8d) BAD_TRAP(0x8e) BAD_TRAP(0x8f)
389 LINUX_SYSCALL_TRAP BAD_TRAP(0x91) BAD_TRAP(0x92) BAD_TRAP(0x93) BAD_TRAP(0x94) 384 LINUX_SYSCALL_TRAP BAD_TRAP(0x91) BAD_TRAP(0x92) BAD_TRAP(0x93) BAD_TRAP(0x94)
390 BAD_TRAP(0x95) BAD_TRAP(0x96) BAD_TRAP(0x97) BAD_TRAP(0x98) BAD_TRAP(0x99) 385 BAD_TRAP(0x95) BAD_TRAP(0x96) BAD_TRAP(0x97) BAD_TRAP(0x98) BAD_TRAP(0x99)
391 BAD_TRAP(0x9a) BAD_TRAP(0x9b) BAD_TRAP(0x9c) BAD_TRAP(0x9d) BAD_TRAP(0x9e) 386 BAD_TRAP(0x9a) BAD_TRAP(0x9b) BAD_TRAP(0x9c) BAD_TRAP(0x9d) BAD_TRAP(0x9e)
392 BAD_TRAP(0x9f) GETCC_TRAP SETCC_TRAP GETPSR_TRAP 387 BAD_TRAP(0x9f) GETCC_TRAP SETCC_TRAP GETPSR_TRAP
393 BAD_TRAP(0xa3) BAD_TRAP(0xa4) BAD_TRAP(0xa5) BAD_TRAP(0xa6) 388 BAD_TRAP(0xa3) BAD_TRAP(0xa4) BAD_TRAP(0xa5) BAD_TRAP(0xa6)
394 INDIRECT_SOLARIS_SYSCALL(156) BAD_TRAP(0xa8) BAD_TRAP(0xa9) BAD_TRAP(0xaa) BAD_TRAP(0xab) 389 BAD_TRAP(0xa7) BAD_TRAP(0xa8) BAD_TRAP(0xa9) BAD_TRAP(0xaa) BAD_TRAP(0xab)
395 BAD_TRAP(0xac) BAD_TRAP(0xad) BAD_TRAP(0xae) BAD_TRAP(0xaf) BAD_TRAP(0xb0) 390 BAD_TRAP(0xac) BAD_TRAP(0xad) BAD_TRAP(0xae) BAD_TRAP(0xaf) BAD_TRAP(0xb0)
396 BAD_TRAP(0xb1) BAD_TRAP(0xb2) BAD_TRAP(0xb3) BAD_TRAP(0xb4) BAD_TRAP(0xb5) 391 BAD_TRAP(0xb1) BAD_TRAP(0xb2) BAD_TRAP(0xb3) BAD_TRAP(0xb4) BAD_TRAP(0xb5)
397 BAD_TRAP(0xb6) BAD_TRAP(0xb7) BAD_TRAP(0xb8) BAD_TRAP(0xb9) BAD_TRAP(0xba) 392 BAD_TRAP(0xb6) BAD_TRAP(0xb7) BAD_TRAP(0xb8) BAD_TRAP(0xb9) BAD_TRAP(0xba)
diff --git a/arch/sparc/kernel/sclow.S b/arch/sparc/kernel/sclow.S
deleted file mode 100644
index 136e37c53d49..000000000000
--- a/arch/sparc/kernel/sclow.S
+++ /dev/null
@@ -1,86 +0,0 @@
1/* sclow.S: Low level special syscall handling.
2 * Basically these are cases where we can completely
3 * handle the system call without saving any state
4 * because we know that the process will not sleep.
5 *
6 * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
7 */
8
9#include <asm/ptrace.h>
10#include <asm/asm-offsets.h>
11#include <asm/errno.h>
12#include <asm/winmacro.h>
13#include <asm/thread_info.h>
14#include <asm/psr.h>
15#include <asm/page.h>
16
17#define CC_AND_RETT \
18 set PSR_C, %l4; \
19 andn %l0, %l4, %l4; \
20 wr %l4, 0x0, %psr; \
21 nop; nop; nop; \
22 jmp %l2; \
23 rett %l2 + 4;
24
25#define SC_AND_RETT \
26 set PSR_C, %l4; \
27 or %l0, %l4, %l4; \
28 wr %l4, 0x0, %psr; \
29 nop; nop; nop; \
30 jmp %l2; \
31 rett %l2 + 4;
32
33#define LABEL(func) func##_low
34
35 .globl LABEL(sunosnop)
36LABEL(sunosnop):
37 CC_AND_RETT
38
39#if (ASIZ_task_uid == 2 && ASIZ_task_euid == 2)
40 .globl LABEL(sunosgetuid)
41LABEL(sunosgetuid):
42 LOAD_CURRENT(l4, l5)
43 ld [%l4 + TI_TASK], %l4
44 lduh [%l4 + AOFF_task_uid], %i0
45 lduh [%l4 + AOFF_task_euid], %i1
46 CC_AND_RETT
47#endif
48
49#if (ASIZ_task_gid == 2 && ASIZ_task_egid == 2)
50 .globl LABEL(sunosgetgid)
51LABEL(sunosgetgid):
52 LOAD_CURRENT(l4, l5)
53 ld [%l4 + TI_TASK], %l4
54 lduh [%l4 + AOFF_task_gid], %i0
55 lduh [%l4 + AOFF_task_egid], %i1
56 CC_AND_RETT
57#endif
58
59 .globl LABEL(sunosmctl)
60LABEL(sunosmctl):
61 mov 0, %i0
62 CC_AND_RETT
63
64 .globl LABEL(sunosgdtsize)
65LABEL(sunosgdtsize):
66 mov 256, %i0
67 CC_AND_RETT
68
69 .globl LABEL(getpagesize)
70LABEL(getpagesize):
71 set PAGE_SIZE, %i0
72 CC_AND_RETT
73
74 /* XXX sys_nice() XXX */
75 /* XXX sys_setpriority() XXX */
76 /* XXX sys_getpriority() XXX */
77 /* XXX sys_setregid() XXX */
78 /* XXX sys_setgid() XXX */
79 /* XXX sys_setreuid() XXX */
80 /* XXX sys_setuid() XXX */
81 /* XXX sys_setfsuid() XXX */
82 /* XXX sys_setfsgid() XXX */
83 /* XXX sys_setpgid() XXX */
84 /* XXX sys_getpgid() XXX */
85 /* XXX sys_setsid() XXX */
86 /* XXX sys_getsid() XXX */
diff --git a/arch/sparc/kernel/signal.c b/arch/sparc/kernel/signal.c
index 9994cac95078..1f730619a24a 100644
--- a/arch/sparc/kernel/signal.c
+++ b/arch/sparc/kernel/signal.c
@@ -22,7 +22,6 @@
22 22
23#include <asm/uaccess.h> 23#include <asm/uaccess.h>
24#include <asm/ptrace.h> 24#include <asm/ptrace.h>
25#include <asm/svr4.h>
26#include <asm/pgalloc.h> 25#include <asm/pgalloc.h>
27#include <asm/pgtable.h> 26#include <asm/pgtable.h>
28#include <asm/cacheflush.h> /* flush_sig_insns */ 27#include <asm/cacheflush.h> /* flush_sig_insns */
@@ -454,7 +453,6 @@ setup_frame(struct sigaction *sa, struct pt_regs *regs, int signr, sigset_t *old
454 break; 453 break;
455 case SIGSYS: 454 case SIGSYS:
456 if (info->si_code == (__SI_FAULT|0x100)) { 455 if (info->si_code == (__SI_FAULT|0x100)) {
457 /* See sys_sunos.c */
458 sig_code = info->si_trapno; 456 sig_code = info->si_trapno;
459 break; 457 break;
460 } 458 }
@@ -676,291 +674,17 @@ sigsegv:
676 force_sigsegv(signo, current); 674 force_sigsegv(signo, current);
677} 675}
678 676
679/* Setup a Solaris stack frame */
680static inline void
681setup_svr4_frame(struct sigaction *sa, unsigned long pc, unsigned long npc,
682 struct pt_regs *regs, int signr, sigset_t *oldset)
683{
684 svr4_signal_frame_t __user *sfp;
685 svr4_gregset_t __user *gr;
686 svr4_siginfo_t __user *si;
687 svr4_mcontext_t __user *mc;
688 svr4_gwindows_t __user *gw;
689 svr4_ucontext_t __user *uc;
690 svr4_sigset_t setv;
691 struct thread_info *tp = current_thread_info();
692 int window = 0, err;
693
694 synchronize_user_stack();
695 sfp = (svr4_signal_frame_t __user *)
696 get_sigframe(sa, regs, SVR4_SF_ALIGNED + sizeof(struct reg_window));
697
698 if (invalid_frame_pointer(sfp, sizeof(*sfp)))
699 goto sigill_and_return;
700
701 /* Start with a clean frame pointer and fill it */
702 err = __clear_user(sfp, sizeof(*sfp));
703
704 /* Setup convenience variables */
705 si = &sfp->si;
706 uc = &sfp->uc;
707 gw = &sfp->gw;
708 mc = &uc->mcontext;
709 gr = &mc->greg;
710
711 /* FIXME: where am I supposed to put this?
712 * sc->sigc_onstack = old_status;
713 * anyways, it does not look like it is used for anything at all.
714 */
715 setv.sigbits[0] = oldset->sig[0];
716 setv.sigbits[1] = oldset->sig[1];
717 if (_NSIG_WORDS >= 4) {
718 setv.sigbits[2] = oldset->sig[2];
719 setv.sigbits[3] = oldset->sig[3];
720 err |= __copy_to_user(&uc->sigmask, &setv, sizeof(svr4_sigset_t));
721 } else
722 err |= __copy_to_user(&uc->sigmask, &setv,
723 2 * sizeof(unsigned int));
724
725 /* Store registers */
726 err |= __put_user(regs->pc, &((*gr)[SVR4_PC]));
727 err |= __put_user(regs->npc, &((*gr)[SVR4_NPC]));
728 err |= __put_user(regs->psr, &((*gr)[SVR4_PSR]));
729 err |= __put_user(regs->y, &((*gr)[SVR4_Y]));
730
731 /* Copy g[1..7] and o[0..7] registers */
732 err |= __copy_to_user(&(*gr)[SVR4_G1], &regs->u_regs[UREG_G1],
733 sizeof(long) * 7);
734 err |= __copy_to_user(&(*gr)[SVR4_O0], &regs->u_regs[UREG_I0],
735 sizeof(long) * 8);
736
737 /* Setup sigaltstack */
738 err |= __put_user(current->sas_ss_sp, &uc->stack.sp);
739 err |= __put_user(sas_ss_flags(regs->u_regs[UREG_FP]), &uc->stack.flags);
740 err |= __put_user(current->sas_ss_size, &uc->stack.size);
741
742 /* Save the currently window file: */
743
744 /* 1. Link sfp->uc->gwins to our windows */
745 err |= __put_user(gw, &mc->gwin);
746
747 /* 2. Number of windows to restore at setcontext(): */
748 err |= __put_user(tp->w_saved, &gw->count);
749
750 /* 3. Save each valid window
751 * Currently, it makes a copy of the windows from the kernel copy.
752 * David's code for SunOS, makes the copy but keeps the pointer to
753 * the kernel. My version makes the pointer point to a userland
754 * copy of those. Mhm, I wonder if I shouldn't just ignore those
755 * on setcontext and use those that are on the kernel, the signal
756 * handler should not be modyfing those, mhm.
757 *
758 * These windows are just used in case synchronize_user_stack failed
759 * to flush the user windows.
760 */
761 for (window = 0; window < tp->w_saved; window++) {
762 err |= __put_user((int __user *) &(gw->win[window]), &gw->winptr[window]);
763 err |= __copy_to_user(&gw->win[window],
764 &tp->reg_window[window],
765 sizeof(svr4_rwindow_t));
766 err |= __put_user(0, gw->winptr[window]);
767 }
768
769 /* 4. We just pay attention to the gw->count field on setcontext */
770 tp->w_saved = 0; /* So process is allowed to execute. */
771
772 /* Setup the signal information. Solaris expects a bunch of
773 * information to be passed to the signal handler, we don't provide
774 * that much currently, should use siginfo.
775 */
776 err |= __put_user(signr, &si->siginfo.signo);
777 err |= __put_user(SVR4_SINOINFO, &si->siginfo.code);
778 if (err)
779 goto sigsegv;
780
781 regs->u_regs[UREG_FP] = (unsigned long) sfp;
782 regs->pc = (unsigned long) sa->sa_handler;
783 regs->npc = (regs->pc + 4);
784
785 /* Arguments passed to signal handler */
786 if (regs->u_regs[14]){
787 struct reg_window __user *rw = (struct reg_window __user *)
788 regs->u_regs[14];
789
790 err |= __put_user(signr, &rw->ins[0]);
791 err |= __put_user(si, &rw->ins[1]);
792 err |= __put_user(uc, &rw->ins[2]);
793 err |= __put_user(sfp, &rw->ins[6]); /* frame pointer */
794 if (err)
795 goto sigsegv;
796
797 regs->u_regs[UREG_I0] = signr;
798 regs->u_regs[UREG_I1] = (unsigned long) si;
799 regs->u_regs[UREG_I2] = (unsigned long) uc;
800 }
801 return;
802
803sigill_and_return:
804 do_exit(SIGILL);
805sigsegv:
806 force_sigsegv(signr, current);
807}
808
809asmlinkage int svr4_getcontext(svr4_ucontext_t __user *uc, struct pt_regs *regs)
810{
811 svr4_gregset_t __user *gr;
812 svr4_mcontext_t __user *mc;
813 svr4_sigset_t setv;
814 int err = 0;
815
816 synchronize_user_stack();
817
818 if (current_thread_info()->w_saved)
819 return -EFAULT;
820
821 err = clear_user(uc, sizeof(*uc));
822 if (err)
823 return -EFAULT;
824
825 /* Setup convenience variables */
826 mc = &uc->mcontext;
827 gr = &mc->greg;
828
829 setv.sigbits[0] = current->blocked.sig[0];
830 setv.sigbits[1] = current->blocked.sig[1];
831 if (_NSIG_WORDS >= 4) {
832 setv.sigbits[2] = current->blocked.sig[2];
833 setv.sigbits[3] = current->blocked.sig[3];
834 err |= __copy_to_user(&uc->sigmask, &setv, sizeof(svr4_sigset_t));
835 } else
836 err |= __copy_to_user(&uc->sigmask, &setv,
837 2 * sizeof(unsigned int));
838
839 /* Store registers */
840 err |= __put_user(regs->pc, &uc->mcontext.greg[SVR4_PC]);
841 err |= __put_user(regs->npc, &uc->mcontext.greg[SVR4_NPC]);
842 err |= __put_user(regs->psr, &uc->mcontext.greg[SVR4_PSR]);
843 err |= __put_user(regs->y, &uc->mcontext.greg[SVR4_Y]);
844
845 /* Copy g[1..7] and o[0..7] registers */
846 err |= __copy_to_user(&(*gr)[SVR4_G1], &regs->u_regs[UREG_G1],
847 sizeof(uint) * 7);
848 err |= __copy_to_user(&(*gr)[SVR4_O0], &regs->u_regs[UREG_I0],
849 sizeof(uint) * 8);
850
851 /* Setup sigaltstack */
852 err |= __put_user(current->sas_ss_sp, &uc->stack.sp);
853 err |= __put_user(sas_ss_flags(regs->u_regs[UREG_FP]), &uc->stack.flags);
854 err |= __put_user(current->sas_ss_size, &uc->stack.size);
855
856 /* The register file is not saved
857 * we have already stuffed all of it with sync_user_stack
858 */
859 return (err ? -EFAULT : 0);
860}
861
862/* Set the context for a svr4 application, this is Solaris way to sigreturn */
863asmlinkage int svr4_setcontext(svr4_ucontext_t __user *c, struct pt_regs *regs)
864{
865 svr4_gregset_t __user *gr;
866 unsigned long pc, npc, psr;
867 mm_segment_t old_fs;
868 sigset_t set;
869 svr4_sigset_t setv;
870 int err;
871 stack_t st;
872
873 /* Fixme: restore windows, or is this already taken care of in
874 * svr4_setup_frame when sync_user_windows is done?
875 */
876 flush_user_windows();
877
878 if (current_thread_info()->w_saved)
879 goto sigsegv_and_return;
880
881 if (((unsigned long) c) & 3)
882 goto sigsegv_and_return;
883
884 if (!__access_ok((unsigned long)c, sizeof(*c)))
885 goto sigsegv_and_return;
886
887 /* Check for valid PC and nPC */
888 gr = &c->mcontext.greg;
889 err = __get_user(pc, &((*gr)[SVR4_PC]));
890 err |= __get_user(npc, &((*gr)[SVR4_NPC]));
891
892 if ((pc | npc) & 3)
893 goto sigsegv_and_return;
894
895 /* Retrieve information from passed ucontext */
896 /* note that nPC is ored a 1, this is used to inform entry.S */
897 /* that we don't want it to mess with our PC and nPC */
898
899 /* This is pretty much atomic, no amount locking would prevent
900 * the races which exist anyways.
901 */
902 err |= __copy_from_user(&setv, &c->sigmask, sizeof(svr4_sigset_t));
903
904 err |= __get_user(st.ss_sp, &c->stack.sp);
905 err |= __get_user(st.ss_flags, &c->stack.flags);
906 err |= __get_user(st.ss_size, &c->stack.size);
907
908 if (err)
909 goto sigsegv_and_return;
910
911 /* It is more difficult to avoid calling this function than to
912 call it and ignore errors. */
913 old_fs = get_fs();
914 set_fs(KERNEL_DS);
915 do_sigaltstack((const stack_t __user *) &st, NULL,
916 regs->u_regs[UREG_I6]);
917 set_fs(old_fs);
918
919 set.sig[0] = setv.sigbits[0];
920 set.sig[1] = setv.sigbits[1];
921 if (_NSIG_WORDS >= 4) {
922 set.sig[2] = setv.sigbits[2];
923 set.sig[3] = setv.sigbits[3];
924 }
925 sigdelsetmask(&set, ~_BLOCKABLE);
926 spin_lock_irq(&current->sighand->siglock);
927 current->blocked = set;
928 recalc_sigpending();
929 spin_unlock_irq(&current->sighand->siglock);
930 regs->pc = pc;
931 regs->npc = npc | 1;
932 err |= __get_user(regs->y, &((*gr)[SVR4_Y]));
933 err |= __get_user(psr, &((*gr)[SVR4_PSR]));
934 regs->psr &= ~(PSR_ICC);
935 regs->psr |= (psr & PSR_ICC);
936
937 /* Restore g[1..7] and o[0..7] registers */
938 err |= __copy_from_user(&regs->u_regs[UREG_G1], &(*gr)[SVR4_G1],
939 sizeof(long) * 7);
940 err |= __copy_from_user(&regs->u_regs[UREG_I0], &(*gr)[SVR4_O0],
941 sizeof(long) * 8);
942 return (err ? -EFAULT : 0);
943
944sigsegv_and_return:
945 force_sig(SIGSEGV, current);
946 return -EFAULT;
947}
948
949static inline void 677static inline void
950handle_signal(unsigned long signr, struct k_sigaction *ka, 678handle_signal(unsigned long signr, struct k_sigaction *ka,
951 siginfo_t *info, sigset_t *oldset, struct pt_regs *regs, 679 siginfo_t *info, sigset_t *oldset, struct pt_regs *regs)
952 int svr4_signal)
953{ 680{
954 if (svr4_signal) 681 if (ka->sa.sa_flags & SA_SIGINFO)
955 setup_svr4_frame(&ka->sa, regs->pc, regs->npc, regs, signr, oldset); 682 new_setup_rt_frame(ka, regs, signr, oldset, info);
956 else { 683 else if (current->thread.new_signal)
957 if (ka->sa.sa_flags & SA_SIGINFO) 684 new_setup_frame(ka, regs, signr, oldset);
958 new_setup_rt_frame(ka, regs, signr, oldset, info); 685 else
959 else if (current->thread.new_signal) 686 setup_frame(&ka->sa, regs, signr, oldset, info);
960 new_setup_frame(ka, regs, signr, oldset); 687
961 else
962 setup_frame(&ka->sa, regs, signr, oldset, info);
963 }
964 spin_lock_irq(&current->sighand->siglock); 688 spin_lock_irq(&current->sighand->siglock);
965 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask); 689 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
966 if (!(ka->sa.sa_flags & SA_NOMASK)) 690 if (!(ka->sa.sa_flags & SA_NOMASK))
@@ -1002,17 +726,6 @@ asmlinkage void do_signal(struct pt_regs * regs, unsigned long orig_i0, int rest
1002 int signr; 726 int signr;
1003 sigset_t *oldset; 727 sigset_t *oldset;
1004 728
1005 /*
1006 * XXX Disable svr4 signal handling until solaris emulation works.
1007 * It is buggy - Anton
1008 */
1009#define SVR4_SIGNAL_BROKEN 1
1010#ifdef SVR4_SIGNAL_BROKEN
1011 int svr4_signal = 0;
1012#else
1013 int svr4_signal = current->personality == PER_SVR4;
1014#endif
1015
1016 cookie.restart_syscall = restart_syscall; 729 cookie.restart_syscall = restart_syscall;
1017 cookie.orig_i0 = orig_i0; 730 cookie.orig_i0 = orig_i0;
1018 731
@@ -1025,8 +738,8 @@ asmlinkage void do_signal(struct pt_regs * regs, unsigned long orig_i0, int rest
1025 if (signr > 0) { 738 if (signr > 0) {
1026 if (cookie.restart_syscall) 739 if (cookie.restart_syscall)
1027 syscall_restart(cookie.orig_i0, regs, &ka.sa); 740 syscall_restart(cookie.orig_i0, regs, &ka.sa);
1028 handle_signal(signr, &ka, &info, oldset, 741 handle_signal(signr, &ka, &info, oldset, regs);
1029 regs, svr4_signal); 742
1030 /* a signal was successfully delivered; the saved 743 /* a signal was successfully delivered; the saved
1031 * sigmask will have been stored in the signal frame, 744 * sigmask will have been stored in the signal frame,
1032 * and will be restored by sigreturn, so we can simply 745 * and will be restored by sigreturn, so we can simply
diff --git a/arch/sparc/kernel/sparc_ksyms.c b/arch/sparc/kernel/sparc_ksyms.c
index 97b1de0e9094..0bcf98a7ef38 100644
--- a/arch/sparc/kernel/sparc_ksyms.c
+++ b/arch/sparc/kernel/sparc_ksyms.c
@@ -36,12 +36,10 @@
36#include <asm/io.h> 36#include <asm/io.h>
37#include <asm/irq.h> 37#include <asm/irq.h>
38#include <asm/idprom.h> 38#include <asm/idprom.h>
39#include <asm/svr4.h>
40#include <asm/head.h> 39#include <asm/head.h>
41#include <asm/smp.h> 40#include <asm/smp.h>
42#include <asm/mostek.h> 41#include <asm/mostek.h>
43#include <asm/ptrace.h> 42#include <asm/ptrace.h>
44#include <asm/user.h>
45#include <asm/uaccess.h> 43#include <asm/uaccess.h>
46#include <asm/checksum.h> 44#include <asm/checksum.h>
47#ifdef CONFIG_SBUS 45#ifdef CONFIG_SBUS
@@ -62,8 +60,6 @@ struct poll {
62 short revents; 60 short revents;
63}; 61};
64 62
65extern int svr4_getcontext (svr4_ucontext_t *, struct pt_regs *);
66extern int svr4_setcontext (svr4_ucontext_t *, struct pt_regs *);
67extern void (*__copy_1page)(void *, const void *); 63extern void (*__copy_1page)(void *, const void *);
68extern void __memmove(void *, const void *, __kernel_size_t); 64extern void __memmove(void *, const void *, __kernel_size_t);
69extern void (*bzero_1page)(void *); 65extern void (*bzero_1page)(void *);
@@ -204,10 +200,6 @@ EXPORT_SYMBOL(kmap_atomic);
204EXPORT_SYMBOL(kunmap_atomic); 200EXPORT_SYMBOL(kunmap_atomic);
205#endif 201#endif
206 202
207/* Solaris/SunOS binary compatibility */
208EXPORT_SYMBOL(svr4_setcontext);
209EXPORT_SYMBOL(svr4_getcontext);
210
211/* prom symbols */ 203/* prom symbols */
212EXPORT_SYMBOL(idprom); 204EXPORT_SYMBOL(idprom);
213EXPORT_SYMBOL(prom_root_node); 205EXPORT_SYMBOL(prom_root_node);
diff --git a/arch/sparc/kernel/sunos_asm.S b/arch/sparc/kernel/sunos_asm.S
deleted file mode 100644
index 07fe86014fb5..000000000000
--- a/arch/sparc/kernel/sunos_asm.S
+++ /dev/null
@@ -1,67 +0,0 @@
1/* $Id: sunos_asm.S,v 1.15 2000/01/11 17:33:21 jj Exp $
2 * sunos_asm.S: SunOS system calls which must have a low-level
3 * entry point to operate correctly.
4 *
5 * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
6 *
7 * Based upon preliminary work which is:
8 *
9 * Copyright (C) 1995 Adrian M. Rodriguez (adrian@remus.rutgers.edu)
10 */
11
12#include <asm/ptrace.h>
13
14 .text
15 .align 4
16
17 /* When calling ret_sys_call, %o0 should contain the same
18 * value as in [%sp + STACKFRAME_SZ + PT_I0] */
19
20 /* SunOS getpid() returns pid in %o0 and ppid in %o1 */
21 .globl sunos_getpid
22sunos_getpid:
23 call sys_getppid
24 nop
25
26 call sys_getpid
27 st %o0, [%sp + STACKFRAME_SZ + PT_I1]
28
29 b ret_sys_call
30 st %o0, [%sp + STACKFRAME_SZ + PT_I0]
31
32 /* SunOS getuid() returns uid in %o0 and euid in %o1 */
33 .globl sunos_getuid
34sunos_getuid:
35 call sys_geteuid16
36 nop
37
38 call sys_getuid16
39 st %o0, [%sp + STACKFRAME_SZ + PT_I1]
40
41 b ret_sys_call
42 st %o0, [%sp + STACKFRAME_SZ + PT_I0]
43
44 /* SunOS getgid() returns gid in %o0 and egid in %o1 */
45 .globl sunos_getgid
46sunos_getgid:
47 call sys_getegid16
48 nop
49
50 call sys_getgid16
51 st %o0, [%sp + STACKFRAME_SZ + PT_I1]
52
53 b ret_sys_call
54 st %o0, [%sp + STACKFRAME_SZ + PT_I0]
55
56 /* SunOS's execv() call only specifies the argv argument, the
57 * environment settings are the same as the calling processes.
58 */
59 .globl sunos_execv
60sunos_execv:
61 st %g0, [%sp + STACKFRAME_SZ + PT_I2]
62
63 call sparc_execve
64 add %sp, STACKFRAME_SZ, %o0
65
66 b ret_sys_call
67 ld [%sp + STACKFRAME_SZ + PT_I0], %o0
diff --git a/arch/sparc/kernel/sunos_ioctl.c b/arch/sparc/kernel/sunos_ioctl.c
deleted file mode 100644
index e613cc6a10ba..000000000000
--- a/arch/sparc/kernel/sunos_ioctl.c
+++ /dev/null
@@ -1,230 +0,0 @@
1/* $Id: sunos_ioctl.c,v 1.34 2000/09/03 14:10:56 anton Exp $
2 * sunos_ioctl.c: The Linux Operating system: SunOS ioctl compatibility.
3 *
4 * Copyright (C) 1995 Miguel de Icaza (miguel@nuclecu.unam.mx)
5 * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
6 */
7
8#include <asm/uaccess.h>
9
10#include <linux/sched.h>
11#include <linux/errno.h>
12#include <linux/string.h>
13#include <linux/termios.h>
14#include <linux/tty.h>
15#include <linux/ioctl.h>
16#include <linux/route.h>
17#include <linux/sockios.h>
18#include <linux/if.h>
19#include <linux/netdevice.h>
20#include <linux/if_arp.h>
21#include <linux/fs.h>
22#include <linux/mm.h>
23#include <linux/smp.h>
24#include <linux/syscalls.h>
25#include <linux/file.h>
26
27#if 0
28extern char sunkbd_type;
29extern char sunkbd_layout;
30#endif
31
32/* NR_OPEN is now larger and dynamic in recent kernels. */
33#define SUNOS_NR_OPEN 256
34
35asmlinkage int sunos_ioctl (int fd, unsigned long cmd, unsigned long arg)
36{
37 int ret = -EBADF;
38
39 if (fd >= SUNOS_NR_OPEN || !fcheck(fd))
40 goto out;
41
42 /* First handle an easy compat. case for tty ldisc. */
43 if (cmd == TIOCSETD) {
44 int __user *p;
45 int ntty = N_TTY, tmp;
46 mm_segment_t oldfs;
47
48 p = (int __user *) arg;
49 ret = -EFAULT;
50 if (get_user(tmp, p))
51 goto out;
52 if (tmp == 2) {
53 oldfs = get_fs();
54 set_fs(KERNEL_DS);
55 ret = sys_ioctl(fd, cmd, (unsigned long) &ntty);
56 set_fs(oldfs);
57 ret = (ret == -EINVAL ? -EOPNOTSUPP : ret);
58 goto out;
59 }
60 }
61
62 /* Binary compatibility is good American knowhow fuckin' up. */
63 if (cmd == TIOCNOTTY) {
64 ret = sys_setsid();
65 goto out;
66 }
67
68 /* SunOS networking ioctls. */
69 switch (cmd) {
70 case _IOW('r', 10, struct rtentry):
71 ret = sys_ioctl(fd, SIOCADDRT, arg);
72 goto out;
73 case _IOW('r', 11, struct rtentry):
74 ret = sys_ioctl(fd, SIOCDELRT, arg);
75 goto out;
76 case _IOW('i', 12, struct ifreq):
77 ret = sys_ioctl(fd, SIOCSIFADDR, arg);
78 goto out;
79 case _IOWR('i', 13, struct ifreq):
80 ret = sys_ioctl(fd, SIOCGIFADDR, arg);
81 goto out;
82 case _IOW('i', 14, struct ifreq):
83 ret = sys_ioctl(fd, SIOCSIFDSTADDR, arg);
84 goto out;
85 case _IOWR('i', 15, struct ifreq):
86 ret = sys_ioctl(fd, SIOCGIFDSTADDR, arg);
87 goto out;
88 case _IOW('i', 16, struct ifreq):
89 ret = sys_ioctl(fd, SIOCSIFFLAGS, arg);
90 goto out;
91 case _IOWR('i', 17, struct ifreq):
92 ret = sys_ioctl(fd, SIOCGIFFLAGS, arg);
93 goto out;
94 case _IOW('i', 18, struct ifreq):
95 ret = sys_ioctl(fd, SIOCSIFMEM, arg);
96 goto out;
97 case _IOWR('i', 19, struct ifreq):
98 ret = sys_ioctl(fd, SIOCGIFMEM, arg);
99 goto out;
100 case _IOWR('i', 20, struct ifconf):
101 ret = sys_ioctl(fd, SIOCGIFCONF, arg);
102 goto out;
103 case _IOW('i', 21, struct ifreq): /* SIOCSIFMTU */
104 ret = sys_ioctl(fd, SIOCSIFMTU, arg);
105 goto out;
106 case _IOWR('i', 22, struct ifreq): /* SIOCGIFMTU */
107 ret = sys_ioctl(fd, SIOCGIFMTU, arg);
108 goto out;
109
110 case _IOWR('i', 23, struct ifreq):
111 ret = sys_ioctl(fd, SIOCGIFBRDADDR, arg);
112 goto out;
113 case _IOW('i', 24, struct ifreq):
114 ret = sys_ioctl(fd, SIOCSIFBRDADDR, arg);
115 goto out;
116 case _IOWR('i', 25, struct ifreq):
117 ret = sys_ioctl(fd, SIOCGIFNETMASK, arg);
118 goto out;
119 case _IOW('i', 26, struct ifreq):
120 ret = sys_ioctl(fd, SIOCSIFNETMASK, arg);
121 goto out;
122 case _IOWR('i', 27, struct ifreq):
123 ret = sys_ioctl(fd, SIOCGIFMETRIC, arg);
124 goto out;
125 case _IOW('i', 28, struct ifreq):
126 ret = sys_ioctl(fd, SIOCSIFMETRIC, arg);
127 goto out;
128
129 case _IOW('i', 30, struct arpreq):
130 ret = sys_ioctl(fd, SIOCSARP, arg);
131 goto out;
132 case _IOWR('i', 31, struct arpreq):
133 ret = sys_ioctl(fd, SIOCGARP, arg);
134 goto out;
135 case _IOW('i', 32, struct arpreq):
136 ret = sys_ioctl(fd, SIOCDARP, arg);
137 goto out;
138
139 case _IOW('i', 40, struct ifreq): /* SIOCUPPER */
140 case _IOW('i', 41, struct ifreq): /* SIOCLOWER */
141 case _IOW('i', 44, struct ifreq): /* SIOCSETSYNC */
142 case _IOW('i', 45, struct ifreq): /* SIOCGETSYNC */
143 case _IOW('i', 46, struct ifreq): /* SIOCSSDSTATS */
144 case _IOW('i', 47, struct ifreq): /* SIOCSSESTATS */
145 case _IOW('i', 48, struct ifreq): /* SIOCSPROMISC */
146 ret = -EOPNOTSUPP;
147 goto out;
148
149 case _IOW('i', 49, struct ifreq):
150 ret = sys_ioctl(fd, SIOCADDMULTI, arg);
151 goto out;
152 case _IOW('i', 50, struct ifreq):
153 ret = sys_ioctl(fd, SIOCDELMULTI, arg);
154 goto out;
155
156 /* FDDI interface ioctls, unsupported. */
157
158 case _IOW('i', 51, struct ifreq): /* SIOCFDRESET */
159 case _IOW('i', 52, struct ifreq): /* SIOCFDSLEEP */
160 case _IOW('i', 53, struct ifreq): /* SIOCSTRTFMWAR */
161 case _IOW('i', 54, struct ifreq): /* SIOCLDNSTRTFW */
162 case _IOW('i', 55, struct ifreq): /* SIOCGETFDSTAT */
163 case _IOW('i', 56, struct ifreq): /* SIOCFDNMIINT */
164 case _IOW('i', 57, struct ifreq): /* SIOCFDEXUSER */
165 case _IOW('i', 58, struct ifreq): /* SIOCFDGNETMAP */
166 case _IOW('i', 59, struct ifreq): /* SIOCFDGIOCTL */
167 printk("FDDI ioctl, returning EOPNOTSUPP\n");
168 ret = -EOPNOTSUPP;
169 goto out;
170
171 case _IOW('t', 125, int):
172 /* More stupid tty sunos ioctls, just
173 * say it worked.
174 */
175 ret = 0;
176 goto out;
177 /* Non posix grp */
178 case _IOW('t', 118, int): {
179 int oldval, newval, __user *ptr;
180
181 cmd = TIOCSPGRP;
182 ptr = (int __user *) arg;
183 ret = -EFAULT;
184 if (get_user(oldval, ptr))
185 goto out;
186 ret = sys_ioctl(fd, cmd, arg);
187 __get_user(newval, ptr);
188 if (newval == -1) {
189 __put_user(oldval, ptr);
190 ret = -EIO;
191 }
192 if (ret == -ENOTTY)
193 ret = -EIO;
194 goto out;
195 }
196
197 case _IOR('t', 119, int): {
198 int oldval, newval, __user *ptr;
199
200 cmd = TIOCGPGRP;
201 ptr = (int __user *) arg;
202 ret = -EFAULT;
203 if (get_user(oldval, ptr))
204 goto out;
205 ret = sys_ioctl(fd, cmd, arg);
206 __get_user(newval, ptr);
207 if (newval == -1) {
208 __put_user(oldval, ptr);
209 ret = -EIO;
210 }
211 if (ret == -ENOTTY)
212 ret = -EIO;
213 goto out;
214 }
215 }
216
217#if 0
218 if ((cmd & 0xff00) == ('k' << 8)) {
219 printk ("[[KBIO: %8.8x\n", (unsigned int) cmd);
220 }
221#endif
222
223 ret = sys_ioctl(fd, cmd, arg);
224 /* so stupid... */
225 ret = (ret == -EINVAL ? -EOPNOTSUPP : ret);
226out:
227 return ret;
228}
229
230
diff --git a/arch/sparc/kernel/sys_solaris.c b/arch/sparc/kernel/sys_solaris.c
deleted file mode 100644
index 2226a5992484..000000000000
--- a/arch/sparc/kernel/sys_solaris.c
+++ /dev/null
@@ -1,35 +0,0 @@
1/*
2 * linux/arch/sparc/kernel/sys_solaris.c
3 *
4 * Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx)
5 */
6
7#include <linux/sched.h>
8#include <linux/kernel.h>
9#include <linux/string.h>
10#include <linux/errno.h>
11#include <linux/personality.h>
12#include <linux/ptrace.h>
13#include <linux/mm.h>
14#include <linux/smp.h>
15#include <linux/module.h>
16
17asmlinkage int
18do_solaris_syscall (struct pt_regs *regs)
19{
20 static int cnt = 0;
21 if (++cnt < 10) printk ("No solaris handler\n");
22 force_sig(SIGSEGV, current);
23 return 0;
24}
25
26#ifndef CONFIG_SUNOS_EMUL
27asmlinkage int
28do_sunos_syscall (struct pt_regs *regs)
29{
30 static int cnt = 0;
31 if (++cnt < 10) printk ("SunOS binary emulation not compiled in\n");
32 force_sig (SIGSEGV, current);
33 return 0;
34}
35#endif
diff --git a/arch/sparc/kernel/sys_sunos.c b/arch/sparc/kernel/sys_sunos.c
deleted file mode 100644
index f5b608bbe8af..000000000000
--- a/arch/sparc/kernel/sys_sunos.c
+++ /dev/null
@@ -1,1210 +0,0 @@
1/* $Id: sys_sunos.c,v 1.137 2002/02/08 03:57:14 davem Exp $
2 * sys_sunos.c: SunOS specific syscall compatibility support.
3 *
4 * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
5 * Copyright (C) 1995 Miguel de Icaza (miguel@nuclecu.unam.mx)
6 *
7 * Based upon preliminary work which is:
8 *
9 * Copyright (C) 1995 Adrian M. Rodriguez (adrian@remus.rutgers.edu)
10 *
11 */
12
13#include <linux/kernel.h>
14#include <linux/sched.h>
15#include <linux/types.h>
16#include <linux/mman.h>
17#include <linux/mm.h>
18#include <linux/swap.h>
19#include <linux/fs.h>
20#include <linux/file.h>
21#include <linux/resource.h>
22#include <linux/ipc.h>
23#include <linux/shm.h>
24#include <linux/msg.h>
25#include <linux/sem.h>
26#include <linux/signal.h>
27#include <linux/uio.h>
28#include <linux/utsname.h>
29#include <linux/major.h>
30#include <linux/stat.h>
31#include <linux/slab.h>
32#include <linux/pagemap.h>
33#include <linux/capability.h>
34#include <linux/errno.h>
35#include <linux/smp.h>
36#include <linux/smp_lock.h>
37#include <linux/syscalls.h>
38
39#include <net/sock.h>
40
41#include <asm/uaccess.h>
42#ifndef KERNEL_DS
43#include <linux/segment.h>
44#endif
45
46#include <asm/page.h>
47#include <asm/pgtable.h>
48#include <asm/pconf.h>
49#include <asm/idprom.h> /* for gethostid() */
50#include <asm/unistd.h>
51#include <asm/system.h>
52
53/* For the nfs mount emulation */
54#include <linux/socket.h>
55#include <linux/in.h>
56#include <linux/nfs.h>
57#include <linux/nfs2.h>
58#include <linux/nfs_mount.h>
59
60/* for sunos_select */
61#include <linux/time.h>
62#include <linux/personality.h>
63
64/* NR_OPEN is now larger and dynamic in recent kernels. */
65#define SUNOS_NR_OPEN 256
66
67/* We use the SunOS mmap() semantics. */
68asmlinkage unsigned long sunos_mmap(unsigned long addr, unsigned long len,
69 unsigned long prot, unsigned long flags,
70 unsigned long fd, unsigned long off)
71{
72 struct file * file = NULL;
73 unsigned long retval, ret_type;
74
75 if (flags & MAP_NORESERVE) {
76 static int cnt;
77 if (cnt++ < 10)
78 printk("%s: unimplemented SunOS MAP_NORESERVE mmap() flag\n",
79 current->comm);
80 flags &= ~MAP_NORESERVE;
81 }
82 retval = -EBADF;
83 if (!(flags & MAP_ANONYMOUS)) {
84 if (fd >= SUNOS_NR_OPEN)
85 goto out;
86 file = fget(fd);
87 if (!file)
88 goto out;
89 }
90
91 retval = -EINVAL;
92 /* If this is ld.so or a shared library doing an mmap
93 * of /dev/zero, transform it into an anonymous mapping.
94 * SunOS is so stupid some times... hmph!
95 */
96 if (file) {
97 if (imajor(file->f_path.dentry->d_inode) == MEM_MAJOR &&
98 iminor(file->f_path.dentry->d_inode) == 5) {
99 flags |= MAP_ANONYMOUS;
100 fput(file);
101 file = NULL;
102 }
103 }
104 ret_type = flags & _MAP_NEW;
105 flags &= ~_MAP_NEW;
106
107 if (!(flags & MAP_FIXED))
108 addr = 0;
109 else {
110 if (ARCH_SUN4C_SUN4 &&
111 (len > 0x20000000 ||
112 ((flags & MAP_FIXED) &&
113 addr < 0xe0000000 && addr + len > 0x20000000)))
114 goto out_putf;
115
116 /* See asm-sparc/uaccess.h */
117 if (len > TASK_SIZE - PAGE_SIZE ||
118 addr + len > TASK_SIZE - PAGE_SIZE)
119 goto out_putf;
120 }
121
122 flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
123 down_write(&current->mm->mmap_sem);
124 retval = do_mmap(file, addr, len, prot, flags, off);
125 up_write(&current->mm->mmap_sem);
126 if (!ret_type)
127 retval = ((retval < PAGE_OFFSET) ? 0 : retval);
128
129out_putf:
130 if (file)
131 fput(file);
132out:
133 return retval;
134}
135
136/* lmbench calls this, just say "yeah, ok" */
137asmlinkage int sunos_mctl(unsigned long addr, unsigned long len, int function, char *arg)
138{
139 return 0;
140}
141
142/* SunOS is completely broken... it returns 0 on success, otherwise
143 * ENOMEM. For sys_sbrk() it wants the old brk value as a return
144 * on success and ENOMEM as before on failure.
145 */
146asmlinkage int sunos_brk(unsigned long brk)
147{
148 int freepages, retval = -ENOMEM;
149 unsigned long rlim;
150 unsigned long newbrk, oldbrk;
151
152 down_write(&current->mm->mmap_sem);
153 if (ARCH_SUN4C_SUN4) {
154 if (brk >= 0x20000000 && brk < 0xe0000000) {
155 goto out;
156 }
157 }
158
159 if (brk < current->mm->end_code)
160 goto out;
161
162 newbrk = PAGE_ALIGN(brk);
163 oldbrk = PAGE_ALIGN(current->mm->brk);
164 retval = 0;
165 if (oldbrk == newbrk) {
166 current->mm->brk = brk;
167 goto out;
168 }
169
170 /*
171 * Always allow shrinking brk
172 */
173 if (brk <= current->mm->brk) {
174 current->mm->brk = brk;
175 do_munmap(current->mm, newbrk, oldbrk-newbrk);
176 goto out;
177 }
178 /*
179 * Check against rlimit and stack..
180 */
181 retval = -ENOMEM;
182 rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur;
183 if (rlim >= RLIM_INFINITY)
184 rlim = ~0;
185 if (brk - current->mm->end_code > rlim)
186 goto out;
187
188 /*
189 * Check against existing mmap mappings.
190 */
191 if (find_vma_intersection(current->mm, oldbrk, newbrk+PAGE_SIZE))
192 goto out;
193
194 /*
195 * stupid algorithm to decide if we have enough memory: while
196 * simple, it hopefully works in most obvious cases.. Easy to
197 * fool it, but this should catch most mistakes.
198 */
199 freepages = global_page_state(NR_FILE_PAGES);
200 freepages >>= 1;
201 freepages += nr_free_pages();
202 freepages += nr_swap_pages;
203 freepages -= num_physpages >> 4;
204 freepages -= (newbrk-oldbrk) >> PAGE_SHIFT;
205 if (freepages < 0)
206 goto out;
207 /*
208 * Ok, we have probably got enough memory - let it rip.
209 */
210 current->mm->brk = brk;
211 do_brk(oldbrk, newbrk-oldbrk);
212 retval = 0;
213out:
214 up_write(&current->mm->mmap_sem);
215 return retval;
216}
217
218asmlinkage unsigned long sunos_sbrk(int increment)
219{
220 int error;
221 unsigned long oldbrk;
222
223 /* This should do it hopefully... */
224 lock_kernel();
225 oldbrk = current->mm->brk;
226 error = sunos_brk(((int) current->mm->brk) + increment);
227 if (!error)
228 error = oldbrk;
229 unlock_kernel();
230 return error;
231}
232
233/* XXX Completely undocumented, and completely magic...
234 * XXX I believe it is to increase the size of the stack by
235 * XXX argument 'increment' and return the new end of stack
236 * XXX area. Wheee...
237 */
238asmlinkage unsigned long sunos_sstk(int increment)
239{
240 lock_kernel();
241 printk("%s: Call to sunos_sstk(increment<%d>) is unsupported\n",
242 current->comm, increment);
243 unlock_kernel();
244 return -1;
245}
246
247/* Give hints to the kernel as to what paging strategy to use...
248 * Completely bogus, don't remind me.
249 */
250#define VA_NORMAL 0 /* Normal vm usage expected */
251#define VA_ABNORMAL 1 /* Abnormal/random vm usage probable */
252#define VA_SEQUENTIAL 2 /* Accesses will be of a sequential nature */
253#define VA_INVALIDATE 3 /* Page table entries should be flushed ??? */
254static char *vstrings[] = {
255 "VA_NORMAL",
256 "VA_ABNORMAL",
257 "VA_SEQUENTIAL",
258 "VA_INVALIDATE",
259};
260
261asmlinkage void sunos_vadvise(unsigned long strategy)
262{
263 /* I wanna see who uses this... */
264 lock_kernel();
265 printk("%s: Advises us to use %s paging strategy\n",
266 current->comm,
267 strategy <= 3 ? vstrings[strategy] : "BOGUS");
268 unlock_kernel();
269}
270
271/* This just wants the soft limit (ie. rlim_cur element) of the RLIMIT_NOFILE
272 * resource limit and is for backwards compatibility with older sunos
273 * revs.
274 */
275asmlinkage long sunos_getdtablesize(void)
276{
277 return SUNOS_NR_OPEN;
278}
279
280#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
281
282asmlinkage unsigned long sunos_sigblock(unsigned long blk_mask)
283{
284 unsigned long old;
285
286 spin_lock_irq(&current->sighand->siglock);
287 old = current->blocked.sig[0];
288 current->blocked.sig[0] |= (blk_mask & _BLOCKABLE);
289 recalc_sigpending();
290 spin_unlock_irq(&current->sighand->siglock);
291 return old;
292}
293
294asmlinkage unsigned long sunos_sigsetmask(unsigned long newmask)
295{
296 unsigned long retval;
297
298 spin_lock_irq(&current->sighand->siglock);
299 retval = current->blocked.sig[0];
300 current->blocked.sig[0] = (newmask & _BLOCKABLE);
301 recalc_sigpending();
302 spin_unlock_irq(&current->sighand->siglock);
303 return retval;
304}
305
306/* SunOS getdents is very similar to the newer Linux (iBCS2 compliant) */
307/* getdents system call, the format of the structure just has a different */
308/* layout (d_off+d_ino instead of d_ino+d_off) */
309struct sunos_dirent {
310 long d_off;
311 unsigned long d_ino;
312 unsigned short d_reclen;
313 unsigned short d_namlen;
314 char d_name[1];
315};
316
317struct sunos_dirent_callback {
318 struct sunos_dirent __user *curr;
319 struct sunos_dirent __user *previous;
320 int count;
321 int error;
322};
323
324#define NAME_OFFSET(de) ((int) ((de)->d_name - (char __user *) (de)))
325#define ROUND_UP(x) (((x)+sizeof(long)-1) & ~(sizeof(long)-1))
326
327static int sunos_filldir(void * __buf, const char * name, int namlen,
328 loff_t offset, u64 ino, unsigned int d_type)
329{
330 struct sunos_dirent __user *dirent;
331 struct sunos_dirent_callback * buf = __buf;
332 unsigned long d_ino;
333 int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1);
334
335 buf->error = -EINVAL; /* only used if we fail.. */
336 if (reclen > buf->count)
337 return -EINVAL;
338 d_ino = ino;
339 if (sizeof(d_ino) < sizeof(ino) && d_ino != ino)
340 return -EOVERFLOW;
341 dirent = buf->previous;
342 if (dirent)
343 put_user(offset, &dirent->d_off);
344 dirent = buf->curr;
345 buf->previous = dirent;
346 put_user(d_ino, &dirent->d_ino);
347 put_user(namlen, &dirent->d_namlen);
348 put_user(reclen, &dirent->d_reclen);
349 copy_to_user(dirent->d_name, name, namlen);
350 put_user(0, dirent->d_name + namlen);
351 dirent = (void __user *) dirent + reclen;
352 buf->curr = dirent;
353 buf->count -= reclen;
354 return 0;
355}
356
357asmlinkage int sunos_getdents(unsigned int fd, void __user *dirent, int cnt)
358{
359 struct file * file;
360 struct sunos_dirent __user *lastdirent;
361 struct sunos_dirent_callback buf;
362 int error = -EBADF;
363
364 if (fd >= SUNOS_NR_OPEN)
365 goto out;
366
367 file = fget(fd);
368 if (!file)
369 goto out;
370
371 error = -EINVAL;
372 if (cnt < (sizeof(struct sunos_dirent) + 255))
373 goto out_putf;
374
375 buf.curr = (struct sunos_dirent __user *) dirent;
376 buf.previous = NULL;
377 buf.count = cnt;
378 buf.error = 0;
379
380 error = vfs_readdir(file, sunos_filldir, &buf);
381 if (error < 0)
382 goto out_putf;
383
384 lastdirent = buf.previous;
385 error = buf.error;
386 if (lastdirent) {
387 put_user(file->f_pos, &lastdirent->d_off);
388 error = cnt - buf.count;
389 }
390
391out_putf:
392 fput(file);
393out:
394 return error;
395}
396
397/* Old sunos getdirentries, severely broken compatibility stuff here. */
398struct sunos_direntry {
399 unsigned long d_ino;
400 unsigned short d_reclen;
401 unsigned short d_namlen;
402 char d_name[1];
403};
404
405struct sunos_direntry_callback {
406 struct sunos_direntry __user *curr;
407 struct sunos_direntry __user *previous;
408 int count;
409 int error;
410};
411
412static int sunos_filldirentry(void * __buf, const char * name, int namlen,
413 loff_t offset, u64 ino, unsigned int d_type)
414{
415 struct sunos_direntry __user *dirent;
416 struct sunos_direntry_callback *buf = __buf;
417 unsigned long d_ino;
418 int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1);
419
420 buf->error = -EINVAL; /* only used if we fail.. */
421 if (reclen > buf->count)
422 return -EINVAL;
423 d_ino = ino;
424 if (sizeof(d_ino) < sizeof(ino) && d_ino != ino)
425 return -EOVERFLOW;
426 dirent = buf->previous;
427 dirent = buf->curr;
428 buf->previous = dirent;
429 put_user(d_ino, &dirent->d_ino);
430 put_user(namlen, &dirent->d_namlen);
431 put_user(reclen, &dirent->d_reclen);
432 copy_to_user(dirent->d_name, name, namlen);
433 put_user(0, dirent->d_name + namlen);
434 dirent = (void __user *) dirent + reclen;
435 buf->curr = dirent;
436 buf->count -= reclen;
437 return 0;
438}
439
440asmlinkage int sunos_getdirentries(unsigned int fd, void __user *dirent,
441 int cnt, unsigned int __user *basep)
442{
443 struct file * file;
444 struct sunos_direntry __user *lastdirent;
445 struct sunos_direntry_callback buf;
446 int error = -EBADF;
447
448 if (fd >= SUNOS_NR_OPEN)
449 goto out;
450
451 file = fget(fd);
452 if (!file)
453 goto out;
454
455 error = -EINVAL;
456 if (cnt < (sizeof(struct sunos_direntry) + 255))
457 goto out_putf;
458
459 buf.curr = (struct sunos_direntry __user *) dirent;
460 buf.previous = NULL;
461 buf.count = cnt;
462 buf.error = 0;
463
464 error = vfs_readdir(file, sunos_filldirentry, &buf);
465 if (error < 0)
466 goto out_putf;
467
468 lastdirent = buf.previous;
469 error = buf.error;
470 if (lastdirent) {
471 put_user(file->f_pos, basep);
472 error = cnt - buf.count;
473 }
474
475out_putf:
476 fput(file);
477out:
478 return error;
479}
480
481struct sunos_utsname {
482 char sname[9];
483 char nname[9];
484 char nnext[56];
485 char rel[9];
486 char ver[9];
487 char mach[9];
488};
489
490asmlinkage int sunos_uname(struct sunos_utsname __user *name)
491{
492 int ret;
493 down_read(&uts_sem);
494 ret = copy_to_user(&name->sname[0], &utsname()->sysname[0],
495 sizeof(name->sname) - 1);
496 if (!ret) {
497 ret |= __copy_to_user(&name->nname[0], &utsname()->nodename[0],
498 sizeof(name->nname) - 1);
499 ret |= __put_user('\0', &name->nname[8]);
500 ret |= __copy_to_user(&name->rel[0], &utsname()->release[0],
501 sizeof(name->rel) - 1);
502 ret |= __copy_to_user(&name->ver[0], &utsname()->version[0],
503 sizeof(name->ver) - 1);
504 ret |= __copy_to_user(&name->mach[0], &utsname()->machine[0],
505 sizeof(name->mach) - 1);
506 }
507 up_read(&uts_sem);
508 return ret ? -EFAULT : 0;
509}
510
511asmlinkage int sunos_nosys(void)
512{
513 struct pt_regs *regs;
514 siginfo_t info;
515 static int cnt;
516
517 lock_kernel();
518 regs = current->thread.kregs;
519 info.si_signo = SIGSYS;
520 info.si_errno = 0;
521 info.si_code = __SI_FAULT|0x100;
522 info.si_addr = (void __user *)regs->pc;
523 info.si_trapno = regs->u_regs[UREG_G1];
524 send_sig_info(SIGSYS, &info, current);
525 if (cnt++ < 4) {
526 printk("Process makes ni_syscall number %d, register dump:\n",
527 (int) regs->u_regs[UREG_G1]);
528 show_regs(regs);
529 }
530 unlock_kernel();
531 return -ENOSYS;
532}
533
534/* This is not a real and complete implementation yet, just to keep
535 * the easy SunOS binaries happy.
536 */
537asmlinkage int sunos_fpathconf(int fd, int name)
538{
539 int ret;
540
541 switch(name) {
542 case _PCONF_LINK:
543 ret = LINK_MAX;
544 break;
545 case _PCONF_CANON:
546 ret = MAX_CANON;
547 break;
548 case _PCONF_INPUT:
549 ret = MAX_INPUT;
550 break;
551 case _PCONF_NAME:
552 ret = NAME_MAX;
553 break;
554 case _PCONF_PATH:
555 ret = PATH_MAX;
556 break;
557 case _PCONF_PIPE:
558 ret = PIPE_BUF;
559 break;
560 case _PCONF_CHRESTRICT: /* XXX Investigate XXX */
561 ret = 1;
562 break;
563 case _PCONF_NOTRUNC: /* XXX Investigate XXX */
564 case _PCONF_VDISABLE:
565 ret = 0;
566 break;
567 default:
568 ret = -EINVAL;
569 break;
570 }
571 return ret;
572}
573
574asmlinkage int sunos_pathconf(char __user *path, int name)
575{
576 int ret;
577
578 ret = sunos_fpathconf(0, name); /* XXX cheese XXX */
579 return ret;
580}
581
582/* SunOS mount system call emulation */
583
584asmlinkage int sunos_select(int width, fd_set __user *inp, fd_set __user *outp,
585 fd_set __user *exp, struct timeval __user *tvp)
586{
587 int ret;
588
589 /* SunOS binaries expect that select won't change the tvp contents */
590 ret = sys_select (width, inp, outp, exp, tvp);
591 if (ret == -EINTR && tvp) {
592 time_t sec, usec;
593
594 __get_user(sec, &tvp->tv_sec);
595 __get_user(usec, &tvp->tv_usec);
596
597 if (sec == 0 && usec == 0)
598 ret = 0;
599 }
600 return ret;
601}
602
603asmlinkage void sunos_nop(void)
604{
605 return;
606}
607
608/* SunOS mount/umount. */
609#define SMNT_RDONLY 1
610#define SMNT_NOSUID 2
611#define SMNT_NEWTYPE 4
612#define SMNT_GRPID 8
613#define SMNT_REMOUNT 16
614#define SMNT_NOSUB 32
615#define SMNT_MULTI 64
616#define SMNT_SYS5 128
617
618struct sunos_fh_t {
619 char fh_data [NFS_FHSIZE];
620};
621
622struct sunos_nfs_mount_args {
623 struct sockaddr_in __user *addr; /* file server address */
624 struct nfs_fh __user *fh; /* File handle to be mounted */
625 int flags; /* flags */
626 int wsize; /* write size in bytes */
627 int rsize; /* read size in bytes */
628 int timeo; /* initial timeout in .1 secs */
629 int retrans; /* times to retry send */
630 char __user *hostname; /* server's hostname */
631 int acregmin; /* attr cache file min secs */
632 int acregmax; /* attr cache file max secs */
633 int acdirmin; /* attr cache dir min secs */
634 int acdirmax; /* attr cache dir max secs */
635 char __user *netname; /* server's netname */
636};
637
638
639/* Bind the socket on a local reserved port and connect it to the
640 * remote server. This on Linux/i386 is done by the mount program,
641 * not by the kernel.
642 */
643static int
644sunos_nfs_get_server_fd (int fd, struct sockaddr_in *addr)
645{
646 struct sockaddr_in local;
647 struct sockaddr_in server;
648 int try_port;
649 struct socket *socket;
650 struct inode *inode;
651 struct file *file;
652 int ret, result = 0;
653
654 file = fget(fd);
655 if (!file)
656 goto out;
657
658 inode = file->f_path.dentry->d_inode;
659
660 socket = SOCKET_I(inode);
661 local.sin_family = AF_INET;
662 local.sin_addr.s_addr = htonl(INADDR_ANY);
663
664 /* IPPORT_RESERVED = 1024, can't find the definition in the kernel */
665 try_port = 1024;
666 do {
667 local.sin_port = htons (--try_port);
668 ret = socket->ops->bind(socket, (struct sockaddr*)&local,
669 sizeof(local));
670 } while (ret && try_port > (1024 / 2));
671
672 if (ret)
673 goto out_putf;
674
675 server.sin_family = AF_INET;
676 server.sin_addr = addr->sin_addr;
677 server.sin_port = NFS_PORT;
678
679 /* Call sys_connect */
680 ret = socket->ops->connect (socket, (struct sockaddr *) &server,
681 sizeof (server), file->f_flags);
682 if (ret >= 0)
683 result = 1;
684
685out_putf:
686 fput(file);
687out:
688 return result;
689}
690
691static int get_default (int value, int def_value)
692{
693 if (value)
694 return value;
695 else
696 return def_value;
697}
698
699static int sunos_nfs_mount(char *dir_name, int linux_flags, void __user *data)
700{
701 int server_fd, err;
702 char *the_name, *mount_page;
703 struct nfs_mount_data linux_nfs_mount;
704 struct sunos_nfs_mount_args sunos_mount;
705
706 /* Ok, here comes the fun part: Linux's nfs mount needs a
707 * socket connection to the server, but SunOS mount does not
708 * require this, so we use the information on the destination
709 * address to create a socket and bind it to a reserved
710 * port on this system
711 */
712 if (copy_from_user(&sunos_mount, data, sizeof(sunos_mount)))
713 return -EFAULT;
714
715 server_fd = sys_socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP);
716 if (server_fd < 0)
717 return -ENXIO;
718
719 if (copy_from_user(&linux_nfs_mount.addr,sunos_mount.addr,
720 sizeof(*sunos_mount.addr)) ||
721 copy_from_user(&linux_nfs_mount.root,sunos_mount.fh,
722 sizeof(*sunos_mount.fh))) {
723 sys_close (server_fd);
724 return -EFAULT;
725 }
726
727 if (!sunos_nfs_get_server_fd (server_fd, &linux_nfs_mount.addr)){
728 sys_close (server_fd);
729 return -ENXIO;
730 }
731
732 /* Now, bind it to a locally reserved port */
733 linux_nfs_mount.version = NFS_MOUNT_VERSION;
734 linux_nfs_mount.flags = sunos_mount.flags;
735 linux_nfs_mount.fd = server_fd;
736
737 linux_nfs_mount.rsize = get_default (sunos_mount.rsize, 8192);
738 linux_nfs_mount.wsize = get_default (sunos_mount.wsize, 8192);
739 linux_nfs_mount.timeo = get_default (sunos_mount.timeo, 10);
740 linux_nfs_mount.retrans = sunos_mount.retrans;
741
742 linux_nfs_mount.acregmin = sunos_mount.acregmin;
743 linux_nfs_mount.acregmax = sunos_mount.acregmax;
744 linux_nfs_mount.acdirmin = sunos_mount.acdirmin;
745 linux_nfs_mount.acdirmax = sunos_mount.acdirmax;
746
747 the_name = getname(sunos_mount.hostname);
748 if (IS_ERR(the_name))
749 return PTR_ERR(the_name);
750
751 strlcpy(linux_nfs_mount.hostname, the_name,
752 sizeof(linux_nfs_mount.hostname));
753 putname (the_name);
754
755 mount_page = (char *) get_zeroed_page(GFP_KERNEL);
756 if (!mount_page)
757 return -ENOMEM;
758
759 memcpy(mount_page, &linux_nfs_mount, sizeof(linux_nfs_mount));
760
761 err = do_mount("", dir_name, "nfs", linux_flags, mount_page);
762
763 free_page((unsigned long) mount_page);
764 return err;
765}
766
767asmlinkage int
768sunos_mount(char __user *type, char __user *dir, int flags, void __user *data)
769{
770 int linux_flags = 0;
771 int ret = -EINVAL;
772 char *dev_fname = NULL;
773 char *dir_page, *type_page;
774
775 if (!capable (CAP_SYS_ADMIN))
776 return -EPERM;
777
778 lock_kernel();
779 /* We don't handle the integer fs type */
780 if ((flags & SMNT_NEWTYPE) == 0)
781 goto out;
782
783 /* Do not allow for those flags we don't support */
784 if (flags & (SMNT_GRPID|SMNT_NOSUB|SMNT_MULTI|SMNT_SYS5))
785 goto out;
786
787 if (flags & SMNT_REMOUNT)
788 linux_flags |= MS_REMOUNT;
789 if (flags & SMNT_RDONLY)
790 linux_flags |= MS_RDONLY;
791 if (flags & SMNT_NOSUID)
792 linux_flags |= MS_NOSUID;
793
794 dir_page = getname(dir);
795 ret = PTR_ERR(dir_page);
796 if (IS_ERR(dir_page))
797 goto out;
798
799 type_page = getname(type);
800 ret = PTR_ERR(type_page);
801 if (IS_ERR(type_page))
802 goto out1;
803
804 if (strcmp(type_page, "ext2") == 0) {
805 dev_fname = getname(data);
806 } else if (strcmp(type_page, "iso9660") == 0) {
807 dev_fname = getname(data);
808 } else if (strcmp(type_page, "minix") == 0) {
809 dev_fname = getname(data);
810 } else if (strcmp(type_page, "nfs") == 0) {
811 ret = sunos_nfs_mount (dir_page, flags, data);
812 goto out2;
813 } else if (strcmp(type_page, "ufs") == 0) {
814 printk("Warning: UFS filesystem mounts unsupported.\n");
815 ret = -ENODEV;
816 goto out2;
817 } else if (strcmp(type_page, "proc")) {
818 ret = -ENODEV;
819 goto out2;
820 }
821 ret = PTR_ERR(dev_fname);
822 if (IS_ERR(dev_fname))
823 goto out2;
824 ret = do_mount(dev_fname, dir_page, type_page, linux_flags, NULL);
825 if (dev_fname)
826 putname(dev_fname);
827out2:
828 putname(type_page);
829out1:
830 putname(dir_page);
831out:
832 unlock_kernel();
833 return ret;
834}
835
836
837asmlinkage int sunos_setpgrp(pid_t pid, pid_t pgid)
838{
839 int ret;
840
841 /* So stupid... */
842 if ((!pid || pid == current->pid) &&
843 !pgid) {
844 sys_setsid();
845 ret = 0;
846 } else {
847 ret = sys_setpgid(pid, pgid);
848 }
849 return ret;
850}
851
852/* So stupid... */
853asmlinkage int sunos_wait4(pid_t pid, unsigned int __user *stat_addr,
854 int options, struct rusage __user*ru)
855{
856 int ret;
857
858 ret = sys_wait4((pid ? pid : -1), stat_addr, options, ru);
859 return ret;
860}
861
862asmlinkage int sunos_killpg(int pgrp, int sig)
863{
864 int ret;
865
866 rcu_read_lock();
867 ret = -EINVAL;
868 if (pgrp > 0)
869 ret = kill_pgrp(find_vpid(pgrp), sig, 0);
870 rcu_read_unlock();
871
872 return ret;
873}
874
875asmlinkage int sunos_audit(void)
876{
877 lock_kernel();
878 printk ("sys_audit\n");
879 unlock_kernel();
880 return -1;
881}
882
883asmlinkage unsigned long sunos_gethostid(void)
884{
885 unsigned long ret;
886
887 lock_kernel();
888 ret = ((unsigned long)idprom->id_machtype << 24) |
889 (unsigned long)idprom->id_sernum;
890 unlock_kernel();
891 return ret;
892}
893
894/* sysconf options, for SunOS compatibility */
895#define _SC_ARG_MAX 1
896#define _SC_CHILD_MAX 2
897#define _SC_CLK_TCK 3
898#define _SC_NGROUPS_MAX 4
899#define _SC_OPEN_MAX 5
900#define _SC_JOB_CONTROL 6
901#define _SC_SAVED_IDS 7
902#define _SC_VERSION 8
903
904asmlinkage long sunos_sysconf (int name)
905{
906 long ret;
907
908 switch (name){
909 case _SC_ARG_MAX:
910 ret = ARG_MAX;
911 break;
912 case _SC_CHILD_MAX:
913 ret = current->signal->rlim[RLIMIT_NPROC].rlim_cur;
914 break;
915 case _SC_CLK_TCK:
916 ret = HZ;
917 break;
918 case _SC_NGROUPS_MAX:
919 ret = NGROUPS_MAX;
920 break;
921 case _SC_OPEN_MAX:
922 ret = current->signal->rlim[RLIMIT_NOFILE].rlim_cur;
923 break;
924 case _SC_JOB_CONTROL:
925 ret = 1; /* yes, we do support job control */
926 break;
927 case _SC_SAVED_IDS:
928 ret = 1; /* yes, we do support saved uids */
929 break;
930 case _SC_VERSION:
931 /* mhm, POSIX_VERSION is in /usr/include/unistd.h
932 * should it go on /usr/include/linux?
933 */
934 ret = 199009L;
935 break;
936 default:
937 ret = -1;
938 break;
939 };
940 return ret;
941}
942
943asmlinkage int sunos_semsys(int op, unsigned long arg1, unsigned long arg2,
944 unsigned long arg3, void *ptr)
945{
946 union semun arg4;
947 int ret;
948
949 switch (op) {
950 case 0:
951 /* Most arguments match on a 1:1 basis but cmd doesn't */
952 switch(arg3) {
953 case 4:
954 arg3=GETPID; break;
955 case 5:
956 arg3=GETVAL; break;
957 case 6:
958 arg3=GETALL; break;
959 case 3:
960 arg3=GETNCNT; break;
961 case 7:
962 arg3=GETZCNT; break;
963 case 8:
964 arg3=SETVAL; break;
965 case 9:
966 arg3=SETALL; break;
967 }
968 /* sys_semctl(): */
969 /* value to modify semaphore to */
970 arg4.__pad = (void __user *) ptr;
971 ret = sys_semctl((int)arg1, (int)arg2, (int)arg3, arg4 );
972 break;
973 case 1:
974 /* sys_semget(): */
975 ret = sys_semget((key_t)arg1, (int)arg2, (int)arg3);
976 break;
977 case 2:
978 /* sys_semop(): */
979 ret = sys_semop((int)arg1, (struct sembuf __user *)arg2, (unsigned)arg3);
980 break;
981 default:
982 ret = -EINVAL;
983 break;
984 };
985 return ret;
986}
987
988asmlinkage int sunos_msgsys(int op, unsigned long arg1, unsigned long arg2,
989 unsigned long arg3, unsigned long arg4)
990{
991 struct sparc_stackf *sp;
992 unsigned long arg5;
993 int rval;
994
995 switch(op) {
996 case 0:
997 rval = sys_msgget((key_t)arg1, (int)arg2);
998 break;
999 case 1:
1000 rval = sys_msgctl((int)arg1, (int)arg2,
1001 (struct msqid_ds __user *)arg3);
1002 break;
1003 case 2:
1004 lock_kernel();
1005 sp = (struct sparc_stackf *)current->thread.kregs->u_regs[UREG_FP];
1006 arg5 = sp->xxargs[0];
1007 unlock_kernel();
1008 rval = sys_msgrcv((int)arg1, (struct msgbuf __user *)arg2,
1009 (size_t)arg3, (long)arg4, (int)arg5);
1010 break;
1011 case 3:
1012 rval = sys_msgsnd((int)arg1, (struct msgbuf __user *)arg2,
1013 (size_t)arg3, (int)arg4);
1014 break;
1015 default:
1016 rval = -EINVAL;
1017 break;
1018 }
1019 return rval;
1020}
1021
1022asmlinkage int sunos_shmsys(int op, unsigned long arg1, unsigned long arg2,
1023 unsigned long arg3)
1024{
1025 unsigned long raddr;
1026 int rval;
1027
1028 switch(op) {
1029 case 0:
1030 /* do_shmat(): attach a shared memory area */
1031 rval = do_shmat((int)arg1,(char __user *)arg2,(int)arg3,&raddr);
1032 if (!rval)
1033 rval = (int) raddr;
1034 break;
1035 case 1:
1036 /* sys_shmctl(): modify shared memory area attr. */
1037 rval = sys_shmctl((int)arg1,(int)arg2,(struct shmid_ds __user *)arg3);
1038 break;
1039 case 2:
1040 /* sys_shmdt(): detach a shared memory area */
1041 rval = sys_shmdt((char __user *)arg1);
1042 break;
1043 case 3:
1044 /* sys_shmget(): get a shared memory area */
1045 rval = sys_shmget((key_t)arg1,(int)arg2,(int)arg3);
1046 break;
1047 default:
1048 rval = -EINVAL;
1049 break;
1050 };
1051 return rval;
1052}
1053
1054#define SUNOS_EWOULDBLOCK 35
1055
1056/* see the sunos man page read(2v) for an explanation
1057 of this garbage. We use O_NDELAY to mark
1058 file descriptors that have been set non-blocking
1059 using 4.2BSD style calls. (tridge) */
1060
1061static inline int check_nonblock(int ret, int fd)
1062{
1063 if (ret == -EAGAIN) {
1064 struct file * file = fget(fd);
1065 if (file) {
1066 if (file->f_flags & O_NDELAY)
1067 ret = -SUNOS_EWOULDBLOCK;
1068 fput(file);
1069 }
1070 }
1071 return ret;
1072}
1073
1074asmlinkage int sunos_read(unsigned int fd, char __user *buf, int count)
1075{
1076 int ret;
1077
1078 ret = check_nonblock(sys_read(fd,buf,count),fd);
1079 return ret;
1080}
1081
1082asmlinkage int sunos_readv(unsigned long fd, const struct iovec __user *vector,
1083 long count)
1084{
1085 int ret;
1086
1087 ret = check_nonblock(sys_readv(fd,vector,count),fd);
1088 return ret;
1089}
1090
1091asmlinkage int sunos_write(unsigned int fd, char __user *buf, int count)
1092{
1093 int ret;
1094
1095 ret = check_nonblock(sys_write(fd,buf,count),fd);
1096 return ret;
1097}
1098
1099asmlinkage int sunos_writev(unsigned long fd,
1100 const struct iovec __user *vector, long count)
1101{
1102 int ret;
1103
1104 ret = check_nonblock(sys_writev(fd,vector,count),fd);
1105 return ret;
1106}
1107
1108asmlinkage int sunos_recv(int fd, void __user *ubuf, int size, unsigned flags)
1109{
1110 int ret;
1111
1112 ret = check_nonblock(sys_recv(fd,ubuf,size,flags),fd);
1113 return ret;
1114}
1115
1116asmlinkage int sunos_send(int fd, void __user *buff, int len, unsigned flags)
1117{
1118 int ret;
1119
1120 ret = check_nonblock(sys_send(fd,buff,len,flags),fd);
1121 return ret;
1122}
1123
1124asmlinkage int sunos_accept(int fd, struct sockaddr __user *sa,
1125 int __user *addrlen)
1126{
1127 int ret;
1128
1129 while (1) {
1130 ret = check_nonblock(sys_accept(fd,sa,addrlen),fd);
1131 if (ret != -ENETUNREACH && ret != -EHOSTUNREACH)
1132 break;
1133 }
1134
1135 return ret;
1136}
1137
1138#define SUNOS_SV_INTERRUPT 2
1139
1140asmlinkage int
1141sunos_sigaction(int sig, const struct old_sigaction __user *act,
1142 struct old_sigaction __user *oact)
1143{
1144 struct k_sigaction new_ka, old_ka;
1145 int ret;
1146
1147 if (act) {
1148 old_sigset_t mask;
1149
1150 if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||
1151 __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
1152 __get_user(new_ka.sa.sa_flags, &act->sa_flags))
1153 return -EFAULT;
1154 __get_user(mask, &act->sa_mask);
1155 new_ka.sa.sa_restorer = NULL;
1156 new_ka.ka_restorer = NULL;
1157 siginitset(&new_ka.sa.sa_mask, mask);
1158 new_ka.sa.sa_flags ^= SUNOS_SV_INTERRUPT;
1159 }
1160
1161 ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
1162
1163 if (!ret && oact) {
1164 /* In the clone() case we could copy half consistent
1165 * state to the user, however this could sleep and
1166 * deadlock us if we held the signal lock on SMP. So for
1167 * now I take the easy way out and do no locking.
1168 * But then again we don't support SunOS lwp's anyways ;-)
1169 */
1170 old_ka.sa.sa_flags ^= SUNOS_SV_INTERRUPT;
1171 if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||
1172 __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
1173 __put_user(old_ka.sa.sa_flags, &oact->sa_flags))
1174 return -EFAULT;
1175 __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
1176 }
1177
1178 return ret;
1179}
1180
1181
1182asmlinkage int sunos_setsockopt(int fd, int level, int optname,
1183 char __user *optval, int optlen)
1184{
1185 int tr_opt = optname;
1186 int ret;
1187
1188 if (level == SOL_IP) {
1189 /* Multicast socketopts (ttl, membership) */
1190 if (tr_opt >=2 && tr_opt <= 6)
1191 tr_opt += 30;
1192 }
1193 ret = sys_setsockopt(fd, level, tr_opt, optval, optlen);
1194 return ret;
1195}
1196
1197asmlinkage int sunos_getsockopt(int fd, int level, int optname,
1198 char __user *optval, int __user *optlen)
1199{
1200 int tr_opt = optname;
1201 int ret;
1202
1203 if (level == SOL_IP) {
1204 /* Multicast socketopts (ttl, membership) */
1205 if (tr_opt >=2 && tr_opt <= 6)
1206 tr_opt += 30;
1207 }
1208 ret = sys_getsockopt(fd, level, tr_opt, optval, optlen);
1209 return ret;
1210}
diff --git a/arch/sparc/kernel/systbls.S b/arch/sparc/kernel/systbls.S
index 9064485dc40b..5a7c4c8345c3 100644
--- a/arch/sparc/kernel/systbls.S
+++ b/arch/sparc/kernel/systbls.S
@@ -81,124 +81,3 @@ sys_call_table:
81/*305*/ .long sys_set_mempolicy, sys_kexec_load, sys_move_pages, sys_getcpu, sys_epoll_pwait 81/*305*/ .long sys_set_mempolicy, sys_kexec_load, sys_move_pages, sys_getcpu, sys_epoll_pwait
82/*310*/ .long sys_utimensat, sys_signalfd, sys_timerfd_create, sys_eventfd, sys_fallocate 82/*310*/ .long sys_utimensat, sys_signalfd, sys_timerfd_create, sys_eventfd, sys_fallocate
83/*315*/ .long sys_timerfd_settime, sys_timerfd_gettime 83/*315*/ .long sys_timerfd_settime, sys_timerfd_gettime
84
85#ifdef CONFIG_SUNOS_EMUL
86 /* Now the SunOS syscall table. */
87
88 .align 4
89 .globl sunos_sys_table
90sunos_sys_table:
91/*0*/ .long sunos_indir, sys_exit, sys_fork
92 .long sunos_read, sunos_write, sys_open
93 .long sys_close, sunos_wait4, sys_creat
94 .long sys_link, sys_unlink, sunos_execv
95 .long sys_chdir, sunos_nosys, sys_mknod
96 .long sys_chmod, sys_lchown16, sunos_brk
97 .long sunos_nosys, sys_lseek, sunos_getpid
98 .long sunos_nosys, sunos_nosys, sunos_nosys
99 .long sunos_getuid, sunos_nosys, sys_ptrace
100 .long sunos_nosys, sunos_nosys, sunos_nosys
101 .long sunos_nosys, sunos_nosys, sunos_nosys
102 .long sys_access, sunos_nosys, sunos_nosys
103 .long sys_sync, sys_kill, sys_newstat
104 .long sunos_nosys, sys_newlstat, sys_dup
105 .long sys_pipe, sunos_nosys, sunos_nosys
106 .long sunos_nosys, sunos_nosys, sunos_getgid
107 .long sunos_nosys, sunos_nosys
108/*50*/ .long sunos_nosys, sys_acct, sunos_nosys
109 .long sunos_mctl, sunos_ioctl, sys_reboot
110 .long sunos_nosys, sys_symlink, sys_readlink
111 .long sys_execve, sys_umask, sys_chroot
112 .long sys_newfstat, sunos_nosys, sys_getpagesize
113 .long sys_msync, sys_vfork, sunos_nosys
114 .long sunos_nosys, sunos_sbrk, sunos_sstk
115 .long sunos_mmap, sunos_vadvise, sys_munmap
116 .long sys_mprotect, sys_madvise, sys_vhangup
117 .long sunos_nosys, sys_mincore, sys_getgroups16
118 .long sys_setgroups16, sys_getpgrp, sunos_setpgrp
119 .long sys_setitimer, sunos_nosys, sys_swapon
120 .long sys_getitimer, sys_gethostname, sys_sethostname
121 .long sunos_getdtablesize, sys_dup2, sunos_nop
122 .long sys_fcntl, sunos_select, sunos_nop
123 .long sys_fsync, sys_setpriority, sys_socket
124 .long sys_connect, sunos_accept
125/*100*/ .long sys_getpriority, sunos_send, sunos_recv
126 .long sunos_nosys, sys_bind, sunos_setsockopt
127 .long sys_listen, sunos_nosys, sunos_sigaction
128 .long sunos_sigblock, sunos_sigsetmask, sys_sigpause
129 .long sys_sigstack, sys_recvmsg, sys_sendmsg
130 .long sunos_nosys, sys_gettimeofday, sys_getrusage
131 .long sunos_getsockopt, sunos_nosys, sunos_readv
132 .long sunos_writev, sys_settimeofday, sys_fchown16
133 .long sys_fchmod, sys_recvfrom, sys_setreuid16
134 .long sys_setregid16, sys_rename, sys_truncate
135 .long sys_ftruncate, sys_flock, sunos_nosys
136 .long sys_sendto, sys_shutdown, sys_socketpair
137 .long sys_mkdir, sys_rmdir, sys_utimes
138 .long sys_sigreturn, sunos_nosys, sys_getpeername
139 .long sunos_gethostid, sunos_nosys, sys_getrlimit
140 .long sys_setrlimit, sunos_killpg, sunos_nosys
141 .long sunos_nosys, sunos_nosys
142/*150*/ .long sys_getsockname, sunos_nosys, sunos_nosys
143 .long sys_poll, sunos_nosys, sunos_nosys
144 .long sunos_getdirentries, sys_statfs, sys_fstatfs
145 .long sys_oldumount, sunos_nosys, sunos_nosys
146 .long sys_getdomainname, sys_setdomainname
147 .long sunos_nosys, sys_quotactl, sunos_nosys
148 .long sunos_mount, sys_ustat, sunos_semsys
149 .long sunos_msgsys, sunos_shmsys, sunos_audit
150 .long sunos_nosys, sunos_getdents, sys_setsid
151 .long sys_fchdir, sunos_nosys, sunos_nosys
152 .long sunos_nosys, sunos_nosys, sunos_nosys
153 .long sunos_nosys, sys_sigpending, sunos_nosys
154 .long sys_setpgid, sunos_pathconf, sunos_fpathconf
155 .long sunos_sysconf, sunos_uname, sunos_nosys
156 .long sunos_nosys, sunos_nosys, sunos_nosys
157 .long sunos_nosys, sunos_nosys, sunos_nosys
158 .long sunos_nosys, sunos_nosys, sunos_nosys
159/*200*/ .long sunos_nosys, sunos_nosys, sunos_nosys
160 .long sunos_nosys, sunos_nosys, sunos_nosys
161 .long sunos_nosys, sunos_nosys, sunos_nosys
162 .long sunos_nosys, sunos_nosys, sunos_nosys
163 .long sunos_nosys, sunos_nosys, sunos_nosys
164 .long sunos_nosys, sunos_nosys, sunos_nosys
165 .long sunos_nosys, sunos_nosys, sunos_nosys
166 .long sunos_nosys, sunos_nosys, sunos_nosys
167 .long sunos_nosys, sunos_nosys, sunos_nosys
168 .long sunos_nosys, sunos_nosys, sunos_nosys
169 .long sunos_nosys, sunos_nosys, sunos_nosys
170 .long sunos_nosys, sunos_nosys, sunos_nosys
171 .long sunos_nosys, sunos_nosys, sunos_nosys
172 .long sunos_nosys, sunos_nosys, sunos_nosys
173 .long sunos_nosys, sunos_nosys, sunos_nosys
174 .long sunos_nosys, sunos_nosys, sunos_nosys
175 .long sunos_nosys, sunos_nosys
176/*250*/ .long sunos_nosys, sunos_nosys, sunos_nosys
177 .long sunos_nosys, sunos_nosys, sunos_nosys
178 .long sunos_nosys, sunos_nosys, sunos_nosys
179 .long sunos_nosys
180/*260*/ .long sunos_nosys, sunos_nosys, sunos_nosys
181 .long sunos_nosys, sunos_nosys, sunos_nosys
182 .long sunos_nosys, sunos_nosys, sunos_nosys
183 .long sunos_nosys
184/*270*/ .long sunos_nosys, sunos_nosys, sunos_nosys
185 .long sunos_nosys, sunos_nosys, sunos_nosys
186 .long sunos_nosys, sunos_nosys, sunos_nosys
187 .long sunos_nosys
188/*280*/ .long sunos_nosys, sunos_nosys, sunos_nosys
189 .long sunos_nosys, sunos_nosys, sunos_nosys
190 .long sunos_nosys, sunos_nosys, sunos_nosys
191 .long sunos_nosys
192/*290*/ .long sunos_nosys, sunos_nosys, sunos_nosys
193 .long sunos_nosys, sunos_nosys, sunos_nosys
194 .long sunos_nosys, sunos_nosys, sunos_nosys
195 .long sunos_nosys
196/*300*/ .long sunos_nosys, sunos_nosys, sunos_nosys
197 .long sunos_nosys, sunos_nosys, sunos_nosys
198 .long sunos_nosys, sunos_nosys, sunos_nosys
199 .long sunos_nosys
200/*310*/ .long sunos_nosys, sunos_nosys, sunos_nosys
201 .long sunos_nosys, sunos_nosys, sunos_nosys
202 .long sunos_nosys
203
204#endif
diff --git a/arch/sparc64/Kconfig b/arch/sparc64/Kconfig
index 2667a9dee11d..df3eacb5ca15 100644
--- a/arch/sparc64/Kconfig
+++ b/arch/sparc64/Kconfig
@@ -88,9 +88,6 @@ config GENERIC_HARDIRQS_NO__DO_IRQ
88 bool 88 bool
89 def_bool y 89 def_bool y
90 90
91config ARCH_SUPPORTS_AOUT
92 def_bool y
93
94choice 91choice
95 prompt "Kernel page size" 92 prompt "Kernel page size"
96 default SPARC64_PAGE_SIZE_8KB 93 default SPARC64_PAGE_SIZE_8KB
@@ -148,11 +145,6 @@ config HOTPLUG_CPU
148 145
149source "init/Kconfig" 146source "init/Kconfig"
150 147
151config SYSVIPC_COMPAT
152 bool
153 depends on COMPAT && SYSVIPC
154 default y
155
156config GENERIC_HARDIRQS 148config GENERIC_HARDIRQS
157 bool 149 bool
158 default y 150 default y
@@ -380,6 +372,10 @@ config SUN_OPENPROMFS
380 To compile the /proc/openprom support as a module, choose M here: the 372 To compile the /proc/openprom support as a module, choose M here: the
381 module will be called openpromfs. If unsure, choose M. 373 module will be called openpromfs. If unsure, choose M.
382 374
375menu "Executable file formats"
376
377source "fs/Kconfig.binfmt"
378
383config SPARC32_COMPAT 379config SPARC32_COMPAT
384 bool "Kernel support for Linux/Sparc 32bit binary compatibility" 380 bool "Kernel support for Linux/Sparc 32bit binary compatibility"
385 help 381 help
@@ -392,37 +388,10 @@ config COMPAT
392 default y 388 default y
393 select COMPAT_BINFMT_ELF 389 select COMPAT_BINFMT_ELF
394 390
395config BINFMT_AOUT32 391config SYSVIPC_COMPAT
396 bool "Kernel support for 32-bit (ie. SunOS) a.out binaries" 392 bool
397 depends on SPARC32_COMPAT && ARCH_SUPPORTS_AOUT 393 depends on COMPAT && SYSVIPC
398 help 394 default y
399 This allows you to run 32-bit a.out format binaries on your Ultra.
400 If you want to run SunOS binaries (see SunOS binary emulation below)
401 or other a.out binaries, say Y. If unsure, say N.
402
403menu "Executable file formats"
404
405source "fs/Kconfig.binfmt"
406
407config SUNOS_EMUL
408 bool "SunOS binary emulation"
409 depends on BINFMT_AOUT32
410 help
411 This allows you to run most SunOS binaries. If you want to do this,
412 say Y here and place appropriate files in /usr/gnemul/sunos. See
413 <http://www.ultralinux.org/faq.html> for more information. If you
414 want to run SunOS binaries on an Ultra you must also say Y to
415 "Kernel support for 32-bit a.out binaries" above.
416
417config SOLARIS_EMUL
418 tristate "Solaris binary emulation (EXPERIMENTAL)"
419 depends on SPARC32_COMPAT && NET && EXPERIMENTAL
420 help
421 This is experimental code which will enable you to run (many)
422 Solaris binaries on your SPARC Linux machine.
423
424 To compile this code as a module, choose M here: the
425 module will be called solaris.
426 395
427endmenu 396endmenu
428 397
diff --git a/arch/sparc64/Makefile b/arch/sparc64/Makefile
index f0c22f826982..9cb75c852b45 100644
--- a/arch/sparc64/Makefile
+++ b/arch/sparc64/Makefile
@@ -27,7 +27,6 @@ endif
27head-y := arch/sparc64/kernel/head.o arch/sparc64/kernel/init_task.o 27head-y := arch/sparc64/kernel/head.o arch/sparc64/kernel/init_task.o
28 28
29core-y += arch/sparc64/kernel/ arch/sparc64/mm/ 29core-y += arch/sparc64/kernel/ arch/sparc64/mm/
30core-$(CONFIG_SOLARIS_EMUL) += arch/sparc64/solaris/
31core-y += arch/sparc64/math-emu/ 30core-y += arch/sparc64/math-emu/
32libs-y += arch/sparc64/prom/ arch/sparc64/lib/ 31libs-y += arch/sparc64/prom/ arch/sparc64/lib/
33drivers-$(CONFIG_OPROFILE) += arch/sparc64/oprofile/ 32drivers-$(CONFIG_OPROFILE) += arch/sparc64/oprofile/
diff --git a/arch/sparc64/defconfig b/arch/sparc64/defconfig
index 9d4bd2229493..e1835868ad36 100644
--- a/arch/sparc64/defconfig
+++ b/arch/sparc64/defconfig
@@ -1,7 +1,7 @@
1# 1#
2# Automatically generated make config: don't edit 2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.25-rc3 3# Linux kernel version: 2.6.25
4# Wed Mar 26 04:33:35 2008 4# Sun Apr 20 01:33:21 2008
5# 5#
6CONFIG_SPARC=y 6CONFIG_SPARC=y
7CONFIG_SPARC64=y 7CONFIG_SPARC64=y
@@ -22,7 +22,6 @@ CONFIG_HAVE_SETUP_PER_CPU_AREA=y
22CONFIG_ARCH_NO_VIRT_TO_BUS=y 22CONFIG_ARCH_NO_VIRT_TO_BUS=y
23CONFIG_OF=y 23CONFIG_OF=y
24CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y 24CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
25CONFIG_ARCH_SUPPORTS_AOUT=y
26CONFIG_SPARC64_PAGE_SIZE_8KB=y 25CONFIG_SPARC64_PAGE_SIZE_8KB=y
27# CONFIG_SPARC64_PAGE_SIZE_64KB is not set 26# CONFIG_SPARC64_PAGE_SIZE_64KB is not set
28# CONFIG_SPARC64_PAGE_SIZE_512KB is not set 27# CONFIG_SPARC64_PAGE_SIZE_512KB is not set
@@ -61,6 +60,7 @@ CONFIG_RT_GROUP_SCHED=y
61CONFIG_USER_SCHED=y 60CONFIG_USER_SCHED=y
62# CONFIG_CGROUP_SCHED is not set 61# CONFIG_CGROUP_SCHED is not set
63CONFIG_SYSFS_DEPRECATED=y 62CONFIG_SYSFS_DEPRECATED=y
63CONFIG_SYSFS_DEPRECATED_V2=y
64CONFIG_RELAY=y 64CONFIG_RELAY=y
65CONFIG_NAMESPACES=y 65CONFIG_NAMESPACES=y
66# CONFIG_UTS_NS is not set 66# CONFIG_UTS_NS is not set
@@ -100,7 +100,9 @@ CONFIG_PROFILING=y
100CONFIG_OPROFILE=m 100CONFIG_OPROFILE=m
101CONFIG_HAVE_OPROFILE=y 101CONFIG_HAVE_OPROFILE=y
102CONFIG_KPROBES=y 102CONFIG_KPROBES=y
103CONFIG_KRETPROBES=y
103CONFIG_HAVE_KPROBES=y 104CONFIG_HAVE_KPROBES=y
105CONFIG_HAVE_KRETPROBES=y
104CONFIG_PROC_PAGE_MONITOR=y 106CONFIG_PROC_PAGE_MONITOR=y
105CONFIG_SLABINFO=y 107CONFIG_SLABINFO=y
106CONFIG_RT_MUTEXES=y 108CONFIG_RT_MUTEXES=y
@@ -131,8 +133,6 @@ CONFIG_DEFAULT_AS=y
131# CONFIG_DEFAULT_NOOP is not set 133# CONFIG_DEFAULT_NOOP is not set
132CONFIG_DEFAULT_IOSCHED="anticipatory" 134CONFIG_DEFAULT_IOSCHED="anticipatory"
133CONFIG_CLASSIC_RCU=y 135CONFIG_CLASSIC_RCU=y
134# CONFIG_PREEMPT_RCU is not set
135CONFIG_SYSVIPC_COMPAT=y
136CONFIG_GENERIC_HARDIRQS=y 136CONFIG_GENERIC_HARDIRQS=y
137 137
138# 138#
@@ -182,9 +182,6 @@ CONFIG_PCI_MSI=y
182# CONFIG_PCI_LEGACY is not set 182# CONFIG_PCI_LEGACY is not set
183# CONFIG_PCI_DEBUG is not set 183# CONFIG_PCI_DEBUG is not set
184CONFIG_SUN_OPENPROMFS=m 184CONFIG_SUN_OPENPROMFS=m
185CONFIG_SPARC32_COMPAT=y
186CONFIG_COMPAT=y
187# CONFIG_BINFMT_AOUT32 is not set
188 185
189# 186#
190# Executable file formats 187# Executable file formats
@@ -192,13 +189,14 @@ CONFIG_COMPAT=y
192CONFIG_BINFMT_ELF=y 189CONFIG_BINFMT_ELF=y
193CONFIG_COMPAT_BINFMT_ELF=y 190CONFIG_COMPAT_BINFMT_ELF=y
194CONFIG_BINFMT_MISC=m 191CONFIG_BINFMT_MISC=m
195CONFIG_SOLARIS_EMUL=y 192CONFIG_SPARC32_COMPAT=y
193CONFIG_COMPAT=y
194CONFIG_SYSVIPC_COMPAT=y
196CONFIG_SCHED_SMT=y 195CONFIG_SCHED_SMT=y
197CONFIG_SCHED_MC=y 196CONFIG_SCHED_MC=y
198# CONFIG_PREEMPT_NONE is not set 197# CONFIG_PREEMPT_NONE is not set
199CONFIG_PREEMPT_VOLUNTARY=y 198CONFIG_PREEMPT_VOLUNTARY=y
200# CONFIG_PREEMPT is not set 199# CONFIG_PREEMPT is not set
201# CONFIG_RCU_TRACE is not set
202# CONFIG_CMDLINE_BOOL is not set 200# CONFIG_CMDLINE_BOOL is not set
203 201
204# 202#
@@ -263,8 +261,10 @@ CONFIG_INET6_XFRM_MODE_TUNNEL=m
263CONFIG_INET6_XFRM_MODE_BEET=m 261CONFIG_INET6_XFRM_MODE_BEET=m
264# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set 262# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
265CONFIG_IPV6_SIT=m 263CONFIG_IPV6_SIT=m
264CONFIG_IPV6_NDISC_NODETYPE=y
266CONFIG_IPV6_TUNNEL=m 265CONFIG_IPV6_TUNNEL=m
267# CONFIG_IPV6_MULTIPLE_TABLES is not set 266# CONFIG_IPV6_MULTIPLE_TABLES is not set
267# CONFIG_IPV6_MROUTE is not set
268# CONFIG_NETWORK_SECMARK is not set 268# CONFIG_NETWORK_SECMARK is not set
269# CONFIG_NETFILTER is not set 269# CONFIG_NETFILTER is not set
270CONFIG_IP_DCCP=m 270CONFIG_IP_DCCP=m
@@ -368,7 +368,7 @@ CONFIG_IDE=y
368CONFIG_BLK_DEV_IDE=y 368CONFIG_BLK_DEV_IDE=y
369 369
370# 370#
371# Please see Documentation/ide.txt for help/info on IDE drives 371# Please see Documentation/ide/ide.txt for help/info on IDE drives
372# 372#
373# CONFIG_BLK_DEV_IDE_SATA is not set 373# CONFIG_BLK_DEV_IDE_SATA is not set
374CONFIG_BLK_DEV_IDEDISK=y 374CONFIG_BLK_DEV_IDEDISK=y
@@ -384,7 +384,6 @@ CONFIG_IDE_PROC_FS=y
384# 384#
385# IDE chipset support/bugfixes 385# IDE chipset support/bugfixes
386# 386#
387CONFIG_IDE_GENERIC=y
388# CONFIG_BLK_DEV_PLATFORM is not set 387# CONFIG_BLK_DEV_PLATFORM is not set
389CONFIG_BLK_DEV_IDEDMA_SFF=y 388CONFIG_BLK_DEV_IDEDMA_SFF=y
390 389
@@ -422,7 +421,7 @@ CONFIG_BLK_DEV_ALI15X3=y
422# CONFIG_BLK_DEV_VIA82CXXX is not set 421# CONFIG_BLK_DEV_VIA82CXXX is not set
423# CONFIG_BLK_DEV_TC86C001 is not set 422# CONFIG_BLK_DEV_TC86C001 is not set
424CONFIG_BLK_DEV_IDEDMA=y 423CONFIG_BLK_DEV_IDEDMA=y
425CONFIG_IDE_ARCH_OBSOLETE_INIT=y 424# CONFIG_BLK_DEV_HD_ONLY is not set
426# CONFIG_BLK_DEV_HD is not set 425# CONFIG_BLK_DEV_HD is not set
427 426
428# 427#
@@ -588,7 +587,6 @@ CONFIG_E1000_NAPI=y
588# CONFIG_SIS190 is not set 587# CONFIG_SIS190 is not set
589# CONFIG_SKGE is not set 588# CONFIG_SKGE is not set
590# CONFIG_SKY2 is not set 589# CONFIG_SKY2 is not set
591# CONFIG_SK98LIN is not set
592# CONFIG_VIA_VELOCITY is not set 590# CONFIG_VIA_VELOCITY is not set
593CONFIG_TIGON3=m 591CONFIG_TIGON3=m
594CONFIG_BNX2=m 592CONFIG_BNX2=m
@@ -613,6 +611,7 @@ CONFIG_NIU=m
613# 611#
614# CONFIG_WLAN_PRE80211 is not set 612# CONFIG_WLAN_PRE80211 is not set
615# CONFIG_WLAN_80211 is not set 613# CONFIG_WLAN_80211 is not set
614# CONFIG_IWLWIFI_LEDS is not set
616 615
617# 616#
618# USB Network Adapters 617# USB Network Adapters
@@ -1472,7 +1471,7 @@ CONFIG_CRYPTO_MICHAEL_MIC=m
1472CONFIG_CRYPTO_CRC32C=m 1471CONFIG_CRYPTO_CRC32C=m
1473CONFIG_CRYPTO_CAMELLIA=m 1472CONFIG_CRYPTO_CAMELLIA=m
1474CONFIG_CRYPTO_TEST=m 1473CONFIG_CRYPTO_TEST=m
1475CONFIG_CRYPTO_AUTHENC=m 1474CONFIG_CRYPTO_AUTHENC=y
1476# CONFIG_CRYPTO_LZO is not set 1475# CONFIG_CRYPTO_LZO is not set
1477CONFIG_CRYPTO_HW=y 1476CONFIG_CRYPTO_HW=y
1478# CONFIG_CRYPTO_DEV_HIFN_795X is not set 1477# CONFIG_CRYPTO_DEV_HIFN_795X is not set
diff --git a/arch/sparc64/kernel/Makefile b/arch/sparc64/kernel/Makefile
index 459462e80a12..63c6ae0dd273 100644
--- a/arch/sparc64/kernel/Makefile
+++ b/arch/sparc64/kernel/Makefile
@@ -21,7 +21,6 @@ obj-$(CONFIG_PCI) += ebus.o isa.o pci_common.o \
21obj-$(CONFIG_PCI_MSI) += pci_msi.o 21obj-$(CONFIG_PCI_MSI) += pci_msi.o
22obj-$(CONFIG_SMP) += smp.o trampoline.o hvtramp.o 22obj-$(CONFIG_SMP) += smp.o trampoline.o hvtramp.o
23obj-$(CONFIG_SPARC32_COMPAT) += sys32.o sys_sparc32.o signal32.o 23obj-$(CONFIG_SPARC32_COMPAT) += sys32.o sys_sparc32.o signal32.o
24obj-$(CONFIG_BINFMT_AOUT32) += binfmt_aout32.o
25obj-$(CONFIG_MODULES) += module.o 24obj-$(CONFIG_MODULES) += module.o
26obj-$(CONFIG_US3_FREQ) += us3_cpufreq.o 25obj-$(CONFIG_US3_FREQ) += us3_cpufreq.o
27obj-$(CONFIG_US2E_FREQ) += us2e_cpufreq.o 26obj-$(CONFIG_US2E_FREQ) += us2e_cpufreq.o
@@ -30,11 +29,3 @@ obj-$(CONFIG_SUN_LDOMS) += ldc.o vio.o viohs.o ds.o
30obj-$(CONFIG_AUDIT) += audit.o 29obj-$(CONFIG_AUDIT) += audit.o
31obj-$(CONFIG_AUDIT)$(CONFIG_SPARC32_COMPAT) += compat_audit.o 30obj-$(CONFIG_AUDIT)$(CONFIG_SPARC32_COMPAT) += compat_audit.o
32obj-y += $(obj-yy) 31obj-y += $(obj-yy)
33
34ifdef CONFIG_SUNOS_EMUL
35 obj-y += sys_sunos32.o sunos_ioctl32.o
36else
37 ifdef CONFIG_SOLARIS_EMUL
38 obj-y += sys_sunos32.o sunos_ioctl32.o
39 endif
40endif
diff --git a/arch/sparc64/kernel/binfmt_aout32.c b/arch/sparc64/kernel/binfmt_aout32.c
deleted file mode 100644
index 9877f2d7672d..000000000000
--- a/arch/sparc64/kernel/binfmt_aout32.c
+++ /dev/null
@@ -1,419 +0,0 @@
1/*
2 * linux/fs/binfmt_aout.c
3 *
4 * Copyright (C) 1991, 1992, 1996 Linus Torvalds
5 *
6 * Hacked a bit by DaveM to make it work with 32-bit SunOS
7 * binaries on the sparc64 port.
8 */
9
10#include <linux/module.h>
11
12#include <linux/sched.h>
13#include <linux/kernel.h>
14#include <linux/mm.h>
15#include <linux/mman.h>
16#include <linux/a.out.h>
17#include <linux/errno.h>
18#include <linux/signal.h>
19#include <linux/string.h>
20#include <linux/fs.h>
21#include <linux/file.h>
22#include <linux/stat.h>
23#include <linux/fcntl.h>
24#include <linux/ptrace.h>
25#include <linux/user.h>
26#include <linux/slab.h>
27#include <linux/binfmts.h>
28#include <linux/personality.h>
29#include <linux/init.h>
30
31#include <asm/system.h>
32#include <asm/uaccess.h>
33#include <asm/pgalloc.h>
34#include <asm/mmu_context.h>
35#include <asm/a.out-core.h>
36
37static int load_aout32_binary(struct linux_binprm *, struct pt_regs * regs);
38static int load_aout32_library(struct file*);
39static int aout32_core_dump(long signr, struct pt_regs *regs, struct file *file, unsigned long limit);
40
41static struct linux_binfmt aout32_format = {
42 .module = THIS_MODULE,
43 .load_binary = load_aout32_binary,
44 .load_shlib = load_aout32_library,
45 .core_dump = aout32_core_dump,
46 .min_coredump = PAGE_SIZE,
47};
48
49static void set_brk(unsigned long start, unsigned long end)
50{
51 start = PAGE_ALIGN(start);
52 end = PAGE_ALIGN(end);
53 if (end <= start)
54 return;
55 down_write(&current->mm->mmap_sem);
56 do_brk(start, end - start);
57 up_write(&current->mm->mmap_sem);
58}
59
60/*
61 * These are the only things you should do on a core-file: use only these
62 * macros to write out all the necessary info.
63 */
64
65static int dump_write(struct file *file, const void *addr, int nr)
66{
67 return file->f_op->write(file, addr, nr, &file->f_pos) == nr;
68}
69
70#define DUMP_WRITE(addr, nr) \
71 if (!dump_write(file, (void *)(addr), (nr))) \
72 goto end_coredump;
73
74#define DUMP_SEEK(offset) \
75if (file->f_op->llseek) { \
76 if (file->f_op->llseek(file,(offset),0) != (offset)) \
77 goto end_coredump; \
78} else file->f_pos = (offset)
79
80/*
81 * Routine writes a core dump image in the current directory.
82 * Currently only a stub-function.
83 *
84 * Note that setuid/setgid files won't make a core-dump if the uid/gid
85 * changed due to the set[u|g]id. It's enforced by the "current->mm->dumpable"
86 * field, which also makes sure the core-dumps won't be recursive if the
87 * dumping of the process results in another error..
88 */
89
90static int aout32_core_dump(long signr, struct pt_regs *regs, struct file *file, unsigned long limit)
91{
92 mm_segment_t fs;
93 int has_dumped = 0;
94 unsigned long dump_start, dump_size;
95 struct user dump;
96# define START_DATA(u) (u.u_tsize)
97# define START_STACK(u) ((regs->u_regs[UREG_FP]) & ~(PAGE_SIZE - 1))
98
99 fs = get_fs();
100 set_fs(KERNEL_DS);
101 has_dumped = 1;
102 current->flags |= PF_DUMPCORE;
103 strncpy(dump.u_comm, current->comm, sizeof(dump.u_comm));
104 dump.signal = signr;
105 aout_dump_thread(regs, &dump);
106
107/* If the size of the dump file exceeds the rlimit, then see what would happen
108 if we wrote the stack, but not the data area. */
109 if (dump.u_dsize + dump.u_ssize > limit)
110 dump.u_dsize = 0;
111
112/* Make sure we have enough room to write the stack and data areas. */
113 if (dump.u_ssize > limit)
114 dump.u_ssize = 0;
115
116/* make sure we actually have a data and stack area to dump */
117 set_fs(USER_DS);
118 if (!access_ok(VERIFY_READ, (void __user *) START_DATA(dump), dump.u_dsize))
119 dump.u_dsize = 0;
120 if (!access_ok(VERIFY_READ, (void __user *) START_STACK(dump), dump.u_ssize))
121 dump.u_ssize = 0;
122
123 set_fs(KERNEL_DS);
124/* struct user */
125 DUMP_WRITE(&dump,sizeof(dump));
126/* now we start writing out the user space info */
127 set_fs(USER_DS);
128/* Dump the data area */
129 if (dump.u_dsize != 0) {
130 dump_start = START_DATA(dump);
131 dump_size = dump.u_dsize;
132 DUMP_WRITE(dump_start,dump_size);
133 }
134/* Now prepare to dump the stack area */
135 if (dump.u_ssize != 0) {
136 dump_start = START_STACK(dump);
137 dump_size = dump.u_ssize;
138 DUMP_WRITE(dump_start,dump_size);
139 }
140/* Finally dump the task struct. Not be used by gdb, but could be useful */
141 set_fs(KERNEL_DS);
142 DUMP_WRITE(current,sizeof(*current));
143end_coredump:
144 set_fs(fs);
145 return has_dumped;
146}
147
148/*
149 * create_aout32_tables() parses the env- and arg-strings in new user
150 * memory and creates the pointer tables from them, and puts their
151 * addresses on the "stack", returning the new stack pointer value.
152 */
153
154static u32 __user *create_aout32_tables(char __user *p, struct linux_binprm *bprm)
155{
156 u32 __user *argv;
157 u32 __user *envp;
158 u32 __user *sp;
159 int argc = bprm->argc;
160 int envc = bprm->envc;
161
162 sp = (u32 __user *)((-(unsigned long)sizeof(char *))&(unsigned long)p);
163
164 /* This imposes the proper stack alignment for a new process. */
165 sp = (u32 __user *) (((unsigned long) sp) & ~7);
166 if ((envc+argc+3)&1)
167 --sp;
168
169 sp -= envc+1;
170 envp = sp;
171 sp -= argc+1;
172 argv = sp;
173 put_user(argc,--sp);
174 current->mm->arg_start = (unsigned long) p;
175 while (argc-->0) {
176 char c;
177 put_user(((u32)(unsigned long)(p)),argv++);
178 do {
179 get_user(c,p++);
180 } while (c);
181 }
182 put_user(0,argv);
183 current->mm->arg_end = current->mm->env_start = (unsigned long) p;
184 while (envc-->0) {
185 char c;
186 put_user(((u32)(unsigned long)(p)),envp++);
187 do {
188 get_user(c,p++);
189 } while (c);
190 }
191 put_user(0,envp);
192 current->mm->env_end = (unsigned long) p;
193 return sp;
194}
195
196/*
197 * These are the functions used to load a.out style executables and shared
198 * libraries. There is no binary dependent code anywhere else.
199 */
200
201static int load_aout32_binary(struct linux_binprm * bprm, struct pt_regs * regs)
202{
203 struct exec ex;
204 unsigned long error;
205 unsigned long fd_offset;
206 unsigned long rlim;
207 unsigned long orig_thr_flags;
208 int retval;
209
210 ex = *((struct exec *) bprm->buf); /* exec-header */
211 if ((N_MAGIC(ex) != ZMAGIC && N_MAGIC(ex) != OMAGIC &&
212 N_MAGIC(ex) != QMAGIC && N_MAGIC(ex) != NMAGIC) ||
213 N_TRSIZE(ex) || N_DRSIZE(ex) ||
214 bprm->file->f_path.dentry->d_inode->i_size < ex.a_text+ex.a_data+N_SYMSIZE(ex)+N_TXTOFF(ex)) {
215 return -ENOEXEC;
216 }
217
218 fd_offset = N_TXTOFF(ex);
219
220 /* Check initial limits. This avoids letting people circumvent
221 * size limits imposed on them by creating programs with large
222 * arrays in the data or bss.
223 */
224 rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur;
225 if (rlim >= RLIM_INFINITY)
226 rlim = ~0;
227 if (ex.a_data + ex.a_bss > rlim)
228 return -ENOMEM;
229
230 /* Flush all traces of the currently running executable */
231 retval = flush_old_exec(bprm);
232 if (retval)
233 return retval;
234
235 /* OK, This is the point of no return */
236 set_personality(PER_SUNOS);
237
238 current->mm->end_code = ex.a_text +
239 (current->mm->start_code = N_TXTADDR(ex));
240 current->mm->end_data = ex.a_data +
241 (current->mm->start_data = N_DATADDR(ex));
242 current->mm->brk = ex.a_bss +
243 (current->mm->start_brk = N_BSSADDR(ex));
244 current->mm->free_area_cache = current->mm->mmap_base;
245 current->mm->cached_hole_size = 0;
246
247 current->mm->mmap = NULL;
248 compute_creds(bprm);
249 current->flags &= ~PF_FORKNOEXEC;
250 if (N_MAGIC(ex) == NMAGIC) {
251 loff_t pos = fd_offset;
252 /* Fuck me plenty... */
253 down_write(&current->mm->mmap_sem);
254 error = do_brk(N_TXTADDR(ex), ex.a_text);
255 up_write(&current->mm->mmap_sem);
256 bprm->file->f_op->read(bprm->file, (char __user *)N_TXTADDR(ex),
257 ex.a_text, &pos);
258 down_write(&current->mm->mmap_sem);
259 error = do_brk(N_DATADDR(ex), ex.a_data);
260 up_write(&current->mm->mmap_sem);
261 bprm->file->f_op->read(bprm->file, (char __user *)N_DATADDR(ex),
262 ex.a_data, &pos);
263 goto beyond_if;
264 }
265
266 if (N_MAGIC(ex) == OMAGIC) {
267 loff_t pos = fd_offset;
268 down_write(&current->mm->mmap_sem);
269 do_brk(N_TXTADDR(ex) & PAGE_MASK,
270 ex.a_text+ex.a_data + PAGE_SIZE - 1);
271 up_write(&current->mm->mmap_sem);
272 bprm->file->f_op->read(bprm->file, (char __user *)N_TXTADDR(ex),
273 ex.a_text+ex.a_data, &pos);
274 } else {
275 static unsigned long error_time;
276 if ((ex.a_text & 0xfff || ex.a_data & 0xfff) &&
277 (N_MAGIC(ex) != NMAGIC) && (jiffies-error_time) > 5*HZ)
278 {
279 printk(KERN_NOTICE "executable not page aligned\n");
280 error_time = jiffies;
281 }
282
283 if (!bprm->file->f_op->mmap) {
284 loff_t pos = fd_offset;
285 down_write(&current->mm->mmap_sem);
286 do_brk(0, ex.a_text+ex.a_data);
287 up_write(&current->mm->mmap_sem);
288 bprm->file->f_op->read(bprm->file,
289 (char __user *)N_TXTADDR(ex),
290 ex.a_text+ex.a_data, &pos);
291 goto beyond_if;
292 }
293
294 down_write(&current->mm->mmap_sem);
295 error = do_mmap(bprm->file, N_TXTADDR(ex), ex.a_text,
296 PROT_READ | PROT_EXEC,
297 MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE,
298 fd_offset);
299 up_write(&current->mm->mmap_sem);
300
301 if (error != N_TXTADDR(ex)) {
302 send_sig(SIGKILL, current, 0);
303 return error;
304 }
305
306 down_write(&current->mm->mmap_sem);
307 error = do_mmap(bprm->file, N_DATADDR(ex), ex.a_data,
308 PROT_READ | PROT_WRITE | PROT_EXEC,
309 MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE,
310 fd_offset + ex.a_text);
311 up_write(&current->mm->mmap_sem);
312 if (error != N_DATADDR(ex)) {
313 send_sig(SIGKILL, current, 0);
314 return error;
315 }
316 }
317beyond_if:
318 set_binfmt(&aout32_format);
319
320 set_brk(current->mm->start_brk, current->mm->brk);
321
322 /* Make sure STACK_TOP returns the right thing. */
323 orig_thr_flags = current_thread_info()->flags;
324 current_thread_info()->flags |= _TIF_32BIT;
325
326 retval = setup_arg_pages(bprm, STACK_TOP, EXSTACK_DEFAULT);
327 if (retval < 0) {
328 current_thread_info()->flags = orig_thr_flags;
329
330 /* Someone check-me: is this error path enough? */
331 send_sig(SIGKILL, current, 0);
332 return retval;
333 }
334
335 current->mm->start_stack =
336 (unsigned long) create_aout32_tables((char __user *)bprm->p, bprm);
337 tsb_context_switch(current->mm);
338
339 start_thread32(regs, ex.a_entry, current->mm->start_stack);
340 if (current->ptrace & PT_PTRACED)
341 send_sig(SIGTRAP, current, 0);
342 return 0;
343}
344
345/* N.B. Move to .h file and use code in fs/binfmt_aout.c? */
346static int load_aout32_library(struct file *file)
347{
348 struct inode * inode;
349 unsigned long bss, start_addr, len;
350 unsigned long error;
351 int retval;
352 struct exec ex;
353
354 inode = file->f_path.dentry->d_inode;
355
356 retval = -ENOEXEC;
357 error = kernel_read(file, 0, (char *) &ex, sizeof(ex));
358 if (error != sizeof(ex))
359 goto out;
360
361 /* We come in here for the regular a.out style of shared libraries */
362 if ((N_MAGIC(ex) != ZMAGIC && N_MAGIC(ex) != QMAGIC) || N_TRSIZE(ex) ||
363 N_DRSIZE(ex) || ((ex.a_entry & 0xfff) && N_MAGIC(ex) == ZMAGIC) ||
364 inode->i_size < ex.a_text+ex.a_data+N_SYMSIZE(ex)+N_TXTOFF(ex)) {
365 goto out;
366 }
367
368 if (N_MAGIC(ex) == ZMAGIC && N_TXTOFF(ex) &&
369 (N_TXTOFF(ex) < inode->i_sb->s_blocksize)) {
370 printk("N_TXTOFF < BLOCK_SIZE. Please convert library\n");
371 goto out;
372 }
373
374 if (N_FLAGS(ex))
375 goto out;
376
377 /* For QMAGIC, the starting address is 0x20 into the page. We mask
378 this off to get the starting address for the page */
379
380 start_addr = ex.a_entry & 0xfffff000;
381
382 /* Now use mmap to map the library into memory. */
383 down_write(&current->mm->mmap_sem);
384 error = do_mmap(file, start_addr, ex.a_text + ex.a_data,
385 PROT_READ | PROT_WRITE | PROT_EXEC,
386 MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE,
387 N_TXTOFF(ex));
388 up_write(&current->mm->mmap_sem);
389 retval = error;
390 if (error != start_addr)
391 goto out;
392
393 len = PAGE_ALIGN(ex.a_text + ex.a_data);
394 bss = ex.a_text + ex.a_data + ex.a_bss;
395 if (bss > len) {
396 down_write(&current->mm->mmap_sem);
397 error = do_brk(start_addr + len, bss - len);
398 up_write(&current->mm->mmap_sem);
399 retval = error;
400 if (error != start_addr + len)
401 goto out;
402 }
403 retval = 0;
404out:
405 return retval;
406}
407
408static int __init init_aout32_binfmt(void)
409{
410 return register_binfmt(&aout32_format);
411}
412
413static void __exit exit_aout32_binfmt(void)
414{
415 unregister_binfmt(&aout32_format);
416}
417
418module_init(init_aout32_binfmt);
419module_exit(exit_aout32_binfmt);
diff --git a/arch/sparc64/kernel/entry.S b/arch/sparc64/kernel/entry.S
index 49eca4b1cf25..fb43c76bdc26 100644
--- a/arch/sparc64/kernel/entry.S
+++ b/arch/sparc64/kernel/entry.S
@@ -1353,63 +1353,6 @@ breakpoint_trap:
1353 ba,pt %xcc, rtrap 1353 ba,pt %xcc, rtrap
1354 nop 1354 nop
1355 1355
1356#if defined(CONFIG_SUNOS_EMUL) || defined(CONFIG_SOLARIS_EMUL) || \
1357 defined(CONFIG_SOLARIS_EMUL_MODULE)
1358 /* SunOS uses syscall zero as the 'indirect syscall' it looks
1359 * like indir_syscall(scall_num, arg0, arg1, arg2...); etc.
1360 * This is complete brain damage.
1361 */
1362 .globl sunos_indir
1363sunos_indir:
1364 srl %o0, 0, %o0
1365 mov %o7, %l4
1366 cmp %o0, NR_SYSCALLS
1367 blu,a,pt %icc, 1f
1368 sll %o0, 0x2, %o0
1369 sethi %hi(sunos_nosys), %l6
1370 b,pt %xcc, 2f
1371 or %l6, %lo(sunos_nosys), %l6
13721: sethi %hi(sunos_sys_table), %l7
1373 or %l7, %lo(sunos_sys_table), %l7
1374 lduw [%l7 + %o0], %l6
13752: mov %o1, %o0
1376 mov %o2, %o1
1377 mov %o3, %o2
1378 mov %o4, %o3
1379 mov %o5, %o4
1380 call %l6
1381 mov %l4, %o7
1382
1383 .globl sunos_getpid
1384sunos_getpid:
1385 call sys_getppid
1386 nop
1387 call sys_getpid
1388 stx %o0, [%sp + PTREGS_OFF + PT_V9_I1]
1389 b,pt %xcc, ret_sys_call
1390 stx %o0, [%sp + PTREGS_OFF + PT_V9_I0]
1391
1392 /* SunOS getuid() returns uid in %o0 and euid in %o1 */
1393 .globl sunos_getuid
1394sunos_getuid:
1395 call sys32_geteuid16
1396 nop
1397 call sys32_getuid16
1398 stx %o0, [%sp + PTREGS_OFF + PT_V9_I1]
1399 b,pt %xcc, ret_sys_call
1400 stx %o0, [%sp + PTREGS_OFF + PT_V9_I0]
1401
1402 /* SunOS getgid() returns gid in %o0 and egid in %o1 */
1403 .globl sunos_getgid
1404sunos_getgid:
1405 call sys32_getegid16
1406 nop
1407 call sys32_getgid16
1408 stx %o0, [%sp + PTREGS_OFF + PT_V9_I1]
1409 b,pt %xcc, ret_sys_call
1410 stx %o0, [%sp + PTREGS_OFF + PT_V9_I0]
1411#endif
1412
1413 /* SunOS's execv() call only specifies the argv argument, the 1356 /* SunOS's execv() call only specifies the argv argument, the
1414 * environment settings are the same as the calling processes. 1357 * environment settings are the same as the calling processes.
1415 */ 1358 */
@@ -1591,7 +1534,7 @@ linux_syscall_trace:
1591 mov %i4, %o4 1534 mov %i4, %o4
1592 1535
1593 1536
1594 /* Linux 32-bit and SunOS system calls enter here... */ 1537 /* Linux 32-bit system calls enter here... */
1595 .align 32 1538 .align 32
1596 .globl linux_sparc_syscall32 1539 .globl linux_sparc_syscall32
1597linux_sparc_syscall32: 1540linux_sparc_syscall32:
@@ -1614,7 +1557,7 @@ linux_sparc_syscall32:
1614 srl %i3, 0, %o3 ! IEU0 1557 srl %i3, 0, %o3 ! IEU0
1615 ba,a,pt %xcc, 3f 1558 ba,a,pt %xcc, 3f
1616 1559
1617 /* Linux native and SunOS system calls enter here... */ 1560 /* Linux native system calls enter here... */
1618 .align 32 1561 .align 32
1619 .globl linux_sparc_syscall, ret_sys_call 1562 .globl linux_sparc_syscall, ret_sys_call
1620linux_sparc_syscall: 1563linux_sparc_syscall:
diff --git a/arch/sparc64/kernel/signal.c b/arch/sparc64/kernel/signal.c
index 9d51956e8e2f..1c47009eb5ec 100644
--- a/arch/sparc64/kernel/signal.c
+++ b/arch/sparc64/kernel/signal.c
@@ -25,7 +25,6 @@
25 25
26#include <asm/uaccess.h> 26#include <asm/uaccess.h>
27#include <asm/ptrace.h> 27#include <asm/ptrace.h>
28#include <asm/svr4.h>
29#include <asm/pgtable.h> 28#include <asm/pgtable.h>
30#include <asm/fpumacro.h> 29#include <asm/fpumacro.h>
31#include <asm/uctx.h> 30#include <asm/uctx.h>
diff --git a/arch/sparc64/kernel/signal32.c b/arch/sparc64/kernel/signal32.c
index 8c1c121330fb..74e0512f135c 100644
--- a/arch/sparc64/kernel/signal32.c
+++ b/arch/sparc64/kernel/signal32.c
@@ -23,7 +23,6 @@
23 23
24#include <asm/uaccess.h> 24#include <asm/uaccess.h>
25#include <asm/ptrace.h> 25#include <asm/ptrace.h>
26#include <asm/svr4.h>
27#include <asm/pgtable.h> 26#include <asm/pgtable.h>
28#include <asm/psrcompat.h> 27#include <asm/psrcompat.h>
29#include <asm/fpumacro.h> 28#include <asm/fpumacro.h>
@@ -798,281 +797,6 @@ sigsegv:
798 force_sigsegv(signo, current); 797 force_sigsegv(signo, current);
799} 798}
800 799
801/* Setup a Solaris stack frame */
802static void
803setup_svr4_frame32(struct sigaction *sa, unsigned long pc, unsigned long npc,
804 struct pt_regs *regs, int signr, sigset_t *oldset)
805{
806 svr4_signal_frame_t __user *sfp;
807 svr4_gregset_t __user *gr;
808 svr4_siginfo_t __user *si;
809 svr4_mcontext_t __user *mc;
810 svr4_gwindows_t __user *gw;
811 svr4_ucontext_t __user *uc;
812 svr4_sigset_t setv;
813 unsigned int psr;
814 int i, err;
815
816 synchronize_user_stack();
817 save_and_clear_fpu();
818
819 regs->u_regs[UREG_FP] &= 0x00000000ffffffffUL;
820 sfp = (svr4_signal_frame_t __user *)
821 get_sigframe(sa, regs,
822 sizeof(struct reg_window32) + SVR4_SF_ALIGNED);
823
824 if (invalid_frame_pointer(sfp, sizeof(*sfp)))
825 do_exit(SIGILL);
826
827 /* Start with a clean frame pointer and fill it */
828 err = clear_user(sfp, sizeof(*sfp));
829
830 /* Setup convenience variables */
831 si = &sfp->si;
832 uc = &sfp->uc;
833 gw = &sfp->gw;
834 mc = &uc->mcontext;
835 gr = &mc->greg;
836
837 /* FIXME: where am I supposed to put this?
838 * sc->sigc_onstack = old_status;
839 * anyways, it does not look like it is used for anything at all.
840 */
841 setv.sigbits[0] = oldset->sig[0];
842 setv.sigbits[1] = (oldset->sig[0] >> 32);
843 if (_NSIG_WORDS >= 2) {
844 setv.sigbits[2] = oldset->sig[1];
845 setv.sigbits[3] = (oldset->sig[1] >> 32);
846 err |= __copy_to_user(&uc->sigmask, &setv, sizeof(svr4_sigset_t));
847 } else
848 err |= __copy_to_user(&uc->sigmask, &setv,
849 2 * sizeof(unsigned int));
850
851 /* Store registers */
852 if (test_thread_flag(TIF_32BIT)) {
853 regs->tpc &= 0xffffffff;
854 regs->tnpc &= 0xffffffff;
855 }
856 err |= __put_user(regs->tpc, &((*gr)[SVR4_PC]));
857 err |= __put_user(regs->tnpc, &((*gr)[SVR4_NPC]));
858 psr = tstate_to_psr(regs->tstate);
859 if (current_thread_info()->fpsaved[0] & FPRS_FEF)
860 psr |= PSR_EF;
861 err |= __put_user(psr, &((*gr)[SVR4_PSR]));
862 err |= __put_user(regs->y, &((*gr)[SVR4_Y]));
863
864 /* Copy g[1..7] and o[0..7] registers */
865 for (i = 0; i < 7; i++)
866 err |= __put_user(regs->u_regs[UREG_G1+i], (&(*gr)[SVR4_G1])+i);
867 for (i = 0; i < 8; i++)
868 err |= __put_user(regs->u_regs[UREG_I0+i], (&(*gr)[SVR4_O0])+i);
869
870 /* Setup sigaltstack */
871 err |= __put_user(current->sas_ss_sp, &uc->stack.sp);
872 err |= __put_user(sas_ss_flags(regs->u_regs[UREG_FP]), &uc->stack.flags);
873 err |= __put_user(current->sas_ss_size, &uc->stack.size);
874
875 /* Save the currently window file: */
876
877 /* 1. Link sfp->uc->gwins to our windows */
878 err |= __put_user(ptr_to_compat(gw), &mc->gwin);
879
880 /* 2. Number of windows to restore at setcontext (): */
881 err |= __put_user(get_thread_wsaved(), &gw->count);
882
883 /* 3. We just pay attention to the gw->count field on setcontext */
884 set_thread_wsaved(0); /* So process is allowed to execute. */
885
886 /* Setup the signal information. Solaris expects a bunch of
887 * information to be passed to the signal handler, we don't provide
888 * that much currently, should use siginfo.
889 */
890 err |= __put_user(signr, &si->siginfo.signo);
891 err |= __put_user(SVR4_SINOINFO, &si->siginfo.code);
892 if (err)
893 goto sigsegv;
894
895 regs->u_regs[UREG_FP] = (unsigned long) sfp;
896 regs->tpc = (unsigned long) sa->sa_handler;
897 regs->tnpc = (regs->tpc + 4);
898 if (test_thread_flag(TIF_32BIT)) {
899 regs->tpc &= 0xffffffff;
900 regs->tnpc &= 0xffffffff;
901 }
902
903 /* Arguments passed to signal handler */
904 if (regs->u_regs[14]){
905 struct reg_window32 __user *rw = (struct reg_window32 __user *)
906 (regs->u_regs[14] & 0x00000000ffffffffUL);
907
908 err |= __put_user(signr, &rw->ins[0]);
909 err |= __put_user((u64)si, &rw->ins[1]);
910 err |= __put_user((u64)uc, &rw->ins[2]);
911 err |= __put_user((u64)sfp, &rw->ins[6]); /* frame pointer */
912 if (err)
913 goto sigsegv;
914
915 regs->u_regs[UREG_I0] = signr;
916 regs->u_regs[UREG_I1] = (u32)(u64) si;
917 regs->u_regs[UREG_I2] = (u32)(u64) uc;
918 }
919 return;
920
921sigsegv:
922 force_sigsegv(signr, current);
923}
924
925asmlinkage int
926svr4_getcontext(svr4_ucontext_t __user *uc, struct pt_regs *regs)
927{
928 svr4_gregset_t __user *gr;
929 svr4_mcontext_t __user *mc;
930 svr4_sigset_t setv;
931 int i, err;
932 u32 psr;
933
934 synchronize_user_stack();
935 save_and_clear_fpu();
936
937 if (get_thread_wsaved())
938 do_exit(SIGSEGV);
939
940 err = clear_user(uc, sizeof(*uc));
941
942 /* Setup convenience variables */
943 mc = &uc->mcontext;
944 gr = &mc->greg;
945
946 setv.sigbits[0] = current->blocked.sig[0];
947 setv.sigbits[1] = (current->blocked.sig[0] >> 32);
948 if (_NSIG_WORDS >= 2) {
949 setv.sigbits[2] = current->blocked.sig[1];
950 setv.sigbits[3] = (current->blocked.sig[1] >> 32);
951 err |= __copy_to_user(&uc->sigmask, &setv, sizeof(svr4_sigset_t));
952 } else
953 err |= __copy_to_user(&uc->sigmask, &setv, 2 * sizeof(unsigned));
954
955 /* Store registers */
956 if (test_thread_flag(TIF_32BIT)) {
957 regs->tpc &= 0xffffffff;
958 regs->tnpc &= 0xffffffff;
959 }
960 err |= __put_user(regs->tpc, &uc->mcontext.greg[SVR4_PC]);
961 err |= __put_user(regs->tnpc, &uc->mcontext.greg[SVR4_NPC]);
962
963 psr = tstate_to_psr(regs->tstate) & ~PSR_EF;
964 if (current_thread_info()->fpsaved[0] & FPRS_FEF)
965 psr |= PSR_EF;
966 err |= __put_user(psr, &uc->mcontext.greg[SVR4_PSR]);
967
968 err |= __put_user(regs->y, &uc->mcontext.greg[SVR4_Y]);
969
970 /* Copy g[1..7] and o[0..7] registers */
971 for (i = 0; i < 7; i++)
972 err |= __put_user(regs->u_regs[UREG_G1+i], (&(*gr)[SVR4_G1])+i);
973 for (i = 0; i < 8; i++)
974 err |= __put_user(regs->u_regs[UREG_I0+i], (&(*gr)[SVR4_O0])+i);
975
976 /* Setup sigaltstack */
977 err |= __put_user(current->sas_ss_sp, &uc->stack.sp);
978 err |= __put_user(sas_ss_flags(regs->u_regs[UREG_FP]), &uc->stack.flags);
979 err |= __put_user(current->sas_ss_size, &uc->stack.size);
980
981 /* The register file is not saved
982 * we have already stuffed all of it with sync_user_stack
983 */
984 return (err ? -EFAULT : 0);
985}
986
987
988/* Set the context for a svr4 application, this is Solaris way to sigreturn */
989asmlinkage int svr4_setcontext(svr4_ucontext_t __user *c, struct pt_regs *regs)
990{
991 svr4_gregset_t __user *gr;
992 mm_segment_t old_fs;
993 u32 pc, npc, psr, u_ss_sp;
994 sigset_t set;
995 svr4_sigset_t setv;
996 int i, err;
997 stack_t st;
998
999 /* Fixme: restore windows, or is this already taken care of in
1000 * svr4_setup_frame when sync_user_windows is done?
1001 */
1002 flush_user_windows();
1003
1004 if (get_thread_wsaved())
1005 goto sigsegv;
1006
1007 if (((unsigned long) c) & 3){
1008 printk("Unaligned structure passed\n");
1009 goto sigsegv;
1010 }
1011
1012 if (!__access_ok(c, sizeof(*c))) {
1013 /* Miguel, add nice debugging msg _here_. ;-) */
1014 goto sigsegv;
1015 }
1016
1017 /* Check for valid PC and nPC */
1018 gr = &c->mcontext.greg;
1019 err = __get_user(pc, &((*gr)[SVR4_PC]));
1020 err |= __get_user(npc, &((*gr)[SVR4_NPC]));
1021 if ((pc | npc) & 3)
1022 goto sigsegv;
1023
1024 /* Retrieve information from passed ucontext */
1025 /* note that nPC is ored a 1, this is used to inform entry.S */
1026 /* that we don't want it to mess with our PC and nPC */
1027
1028 err |= copy_from_user(&setv, &c->sigmask, sizeof(svr4_sigset_t));
1029 set.sig[0] = setv.sigbits[0] | (((long)setv.sigbits[1]) << 32);
1030 if (_NSIG_WORDS >= 2)
1031 set.sig[1] = setv.sigbits[2] | (((long)setv.sigbits[3]) << 32);
1032
1033 err |= __get_user(u_ss_sp, &c->stack.sp);
1034 st.ss_sp = compat_ptr(u_ss_sp);
1035 err |= __get_user(st.ss_flags, &c->stack.flags);
1036 err |= __get_user(st.ss_size, &c->stack.size);
1037 if (err)
1038 goto sigsegv;
1039
1040 /* It is more difficult to avoid calling this function than to
1041 call it and ignore errors. */
1042 old_fs = get_fs();
1043 set_fs(KERNEL_DS);
1044 do_sigaltstack((stack_t __user *) &st, NULL, regs->u_regs[UREG_I6]);
1045 set_fs(old_fs);
1046
1047 sigdelsetmask(&set, ~_BLOCKABLE);
1048 spin_lock_irq(&current->sighand->siglock);
1049 current->blocked = set;
1050 recalc_sigpending();
1051 spin_unlock_irq(&current->sighand->siglock);
1052 regs->tpc = pc;
1053 regs->tnpc = npc | 1;
1054 if (test_thread_flag(TIF_32BIT)) {
1055 regs->tpc &= 0xffffffff;
1056 regs->tnpc &= 0xffffffff;
1057 }
1058 err |= __get_user(regs->y, &((*gr)[SVR4_Y]));
1059 err |= __get_user(psr, &((*gr)[SVR4_PSR]));
1060 regs->tstate &= ~(TSTATE_ICC|TSTATE_XCC);
1061 regs->tstate |= psr_to_tstate_icc(psr);
1062
1063 /* Restore g[1..7] and o[0..7] registers */
1064 for (i = 0; i < 7; i++)
1065 err |= __get_user(regs->u_regs[UREG_G1+i], (&(*gr)[SVR4_G1])+i);
1066 for (i = 0; i < 8; i++)
1067 err |= __get_user(regs->u_regs[UREG_I0+i], (&(*gr)[SVR4_O0])+i);
1068 if (err)
1069 goto sigsegv;
1070
1071 return -EINTR;
1072sigsegv:
1073 return -EFAULT;
1074}
1075
1076static void setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs, 800static void setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs,
1077 unsigned long signr, sigset_t *oldset, 801 unsigned long signr, sigset_t *oldset,
1078 siginfo_t *info) 802 siginfo_t *info)
@@ -1216,20 +940,14 @@ sigsegv:
1216 940
1217static inline void handle_signal32(unsigned long signr, struct k_sigaction *ka, 941static inline void handle_signal32(unsigned long signr, struct k_sigaction *ka,
1218 siginfo_t *info, 942 siginfo_t *info,
1219 sigset_t *oldset, struct pt_regs *regs, 943 sigset_t *oldset, struct pt_regs *regs)
1220 int svr4_signal)
1221{ 944{
1222 if (svr4_signal) 945 if (ka->sa.sa_flags & SA_SIGINFO)
1223 setup_svr4_frame32(&ka->sa, regs->tpc, regs->tnpc, 946 setup_rt_frame32(ka, regs, signr, oldset, info);
1224 regs, signr, oldset); 947 else if (test_thread_flag(TIF_NEWSIGNALS))
1225 else { 948 new_setup_frame32(ka, regs, signr, oldset);
1226 if (ka->sa.sa_flags & SA_SIGINFO) 949 else
1227 setup_rt_frame32(ka, regs, signr, oldset, info); 950 setup_frame32(&ka->sa, regs, signr, oldset, info);
1228 else if (test_thread_flag(TIF_NEWSIGNALS))
1229 new_setup_frame32(ka, regs, signr, oldset);
1230 else
1231 setup_frame32(&ka->sa, regs, signr, oldset, info);
1232 }
1233 spin_lock_irq(&current->sighand->siglock); 951 spin_lock_irq(&current->sighand->siglock);
1234 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask); 952 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
1235 if (!(ka->sa.sa_flags & SA_NOMASK)) 953 if (!(ka->sa.sa_flags & SA_NOMASK))
@@ -1270,7 +988,6 @@ void do_signal32(sigset_t *oldset, struct pt_regs * regs,
1270 struct signal_deliver_cookie cookie; 988 struct signal_deliver_cookie cookie;
1271 struct k_sigaction ka; 989 struct k_sigaction ka;
1272 int signr; 990 int signr;
1273 int svr4_signal = current->personality == PER_SVR4;
1274 991
1275 cookie.restart_syscall = restart_syscall; 992 cookie.restart_syscall = restart_syscall;
1276 cookie.orig_i0 = orig_i0; 993 cookie.orig_i0 = orig_i0;
@@ -1279,8 +996,7 @@ void do_signal32(sigset_t *oldset, struct pt_regs * regs,
1279 if (signr > 0) { 996 if (signr > 0) {
1280 if (cookie.restart_syscall) 997 if (cookie.restart_syscall)
1281 syscall_restart32(orig_i0, regs, &ka.sa); 998 syscall_restart32(orig_i0, regs, &ka.sa);
1282 handle_signal32(signr, &ka, &info, oldset, 999 handle_signal32(signr, &ka, &info, oldset, regs);
1283 regs, svr4_signal);
1284 1000
1285 /* a signal was successfully delivered; the saved 1001 /* a signal was successfully delivered; the saved
1286 * sigmask will have been stored in the signal frame, 1002 * sigmask will have been stored in the signal frame,
diff --git a/arch/sparc64/kernel/sparc64_ksyms.c b/arch/sparc64/kernel/sparc64_ksyms.c
index 051b8d9cb989..38736460b8db 100644
--- a/arch/sparc64/kernel/sparc64_ksyms.c
+++ b/arch/sparc64/kernel/sparc64_ksyms.c
@@ -33,13 +33,11 @@
33#include <asm/io.h> 33#include <asm/io.h>
34#include <asm/irq.h> 34#include <asm/irq.h>
35#include <asm/idprom.h> 35#include <asm/idprom.h>
36#include <asm/svr4.h>
37#include <asm/elf.h> 36#include <asm/elf.h>
38#include <asm/head.h> 37#include <asm/head.h>
39#include <asm/smp.h> 38#include <asm/smp.h>
40#include <asm/mostek.h> 39#include <asm/mostek.h>
41#include <asm/ptrace.h> 40#include <asm/ptrace.h>
42#include <asm/user.h>
43#include <asm/uaccess.h> 41#include <asm/uaccess.h>
44#include <asm/checksum.h> 42#include <asm/checksum.h>
45#include <asm/fpumacro.h> 43#include <asm/fpumacro.h>
@@ -73,13 +71,8 @@ extern __kernel_size_t strlen(const char *);
73extern void linux_sparc_syscall(void); 71extern void linux_sparc_syscall(void);
74extern void rtrap(void); 72extern void rtrap(void);
75extern void show_regs(struct pt_regs *); 73extern void show_regs(struct pt_regs *);
76extern void solaris_syscall(void);
77extern void syscall_trace(struct pt_regs *, int); 74extern void syscall_trace(struct pt_regs *, int);
78extern u32 sunos_sys_table[], sys_call_table32[];
79extern void tl0_solaris(void);
80extern void sys_sigsuspend(void); 75extern void sys_sigsuspend(void);
81extern int svr4_getcontext(svr4_ucontext_t *uc, struct pt_regs *regs);
82extern int svr4_setcontext(svr4_ucontext_t *uc, struct pt_regs *regs);
83extern int compat_sys_ioctl(unsigned int fd, unsigned int cmd, u32 arg); 76extern int compat_sys_ioctl(unsigned int fd, unsigned int cmd, u32 arg);
84extern int (*handle_mathemu)(struct pt_regs *, struct fpustate *); 77extern int (*handle_mathemu)(struct pt_regs *, struct fpustate *);
85extern long sparc32_open(const char __user * filename, int flags, int mode); 78extern long sparc32_open(const char __user * filename, int flags, int mode);
@@ -90,8 +83,6 @@ extern int __ashrdi3(int, int);
90 83
91extern int dump_fpu (struct pt_regs * regs, elf_fpregset_t * fpregs); 84extern int dump_fpu (struct pt_regs * regs, elf_fpregset_t * fpregs);
92 85
93extern unsigned int sys_call_table[];
94
95extern void xor_vis_2(unsigned long, unsigned long *, unsigned long *); 86extern void xor_vis_2(unsigned long, unsigned long *, unsigned long *);
96extern void xor_vis_3(unsigned long, unsigned long *, unsigned long *, 87extern void xor_vis_3(unsigned long, unsigned long *, unsigned long *,
97 unsigned long *); 88 unsigned long *);
@@ -213,11 +204,6 @@ EXPORT_SYMBOL(pci_dma_supported);
213/* I/O device mmaping on Sparc64. */ 204/* I/O device mmaping on Sparc64. */
214EXPORT_SYMBOL(io_remap_pfn_range); 205EXPORT_SYMBOL(io_remap_pfn_range);
215 206
216#if defined(CONFIG_COMPAT) && defined(CONFIG_NET)
217/* Solaris/SunOS binary compatibility */
218EXPORT_SYMBOL(verify_compat_iovec);
219#endif
220
221EXPORT_SYMBOL(dump_fpu); 207EXPORT_SYMBOL(dump_fpu);
222EXPORT_SYMBOL(put_fs_struct); 208EXPORT_SYMBOL(put_fs_struct);
223 209
@@ -254,30 +240,6 @@ EXPORT_SYMBOL(strlen);
254EXPORT_SYMBOL(__strlen_user); 240EXPORT_SYMBOL(__strlen_user);
255EXPORT_SYMBOL(__strnlen_user); 241EXPORT_SYMBOL(__strnlen_user);
256 242
257#ifdef CONFIG_SOLARIS_EMUL_MODULE
258EXPORT_SYMBOL(linux_sparc_syscall);
259EXPORT_SYMBOL(rtrap);
260EXPORT_SYMBOL(show_regs);
261EXPORT_SYMBOL(solaris_syscall);
262EXPORT_SYMBOL(syscall_trace);
263EXPORT_SYMBOL(sunos_sys_table);
264EXPORT_SYMBOL(sys_call_table32);
265EXPORT_SYMBOL(tl0_solaris);
266EXPORT_SYMBOL(sys_sigsuspend);
267EXPORT_SYMBOL(sys_getppid);
268EXPORT_SYMBOL(sys_getpid);
269EXPORT_SYMBOL(sys_geteuid);
270EXPORT_SYMBOL(sys_getuid);
271EXPORT_SYMBOL(sys_getegid);
272EXPORT_SYMBOL(sysctl_nr_open);
273EXPORT_SYMBOL(sys_getgid);
274EXPORT_SYMBOL(svr4_getcontext);
275EXPORT_SYMBOL(svr4_setcontext);
276EXPORT_SYMBOL(compat_sys_ioctl);
277EXPORT_SYMBOL(sys_ioctl);
278EXPORT_SYMBOL(sparc32_open);
279#endif
280
281/* Special internal versions of library functions. */ 243/* Special internal versions of library functions. */
282EXPORT_SYMBOL(_clear_page); 244EXPORT_SYMBOL(_clear_page);
283EXPORT_SYMBOL(clear_user_page); 245EXPORT_SYMBOL(clear_user_page);
@@ -334,9 +296,6 @@ EXPORT_SYMBOL(do_BUG);
334/* for ns8703 */ 296/* for ns8703 */
335EXPORT_SYMBOL(ns87303_lock); 297EXPORT_SYMBOL(ns87303_lock);
336 298
337/* for solaris compat module */
338EXPORT_SYMBOL_GPL(sys_call_table);
339
340EXPORT_SYMBOL(tick_ops); 299EXPORT_SYMBOL(tick_ops);
341 300
342EXPORT_SYMBOL(xor_vis_2); 301EXPORT_SYMBOL(xor_vis_2);
diff --git a/arch/sparc64/kernel/sunos_ioctl32.c b/arch/sparc64/kernel/sunos_ioctl32.c
deleted file mode 100644
index 75d2bad49839..000000000000
--- a/arch/sparc64/kernel/sunos_ioctl32.c
+++ /dev/null
@@ -1,275 +0,0 @@
1/* $Id: sunos_ioctl32.c,v 1.11 2000/07/30 23:12:24 davem Exp $
2 * sunos_ioctl32.c: SunOS ioctl compatibility on sparc64.
3 *
4 * Copyright (C) 1995 Miguel de Icaza (miguel@nuclecu.unam.mx)
5 * Copyright (C) 1995, 1996, 1997 David S. Miller (davem@caip.rutgers.edu)
6 */
7
8#include <asm/uaccess.h>
9
10#include <linux/sched.h>
11#include <linux/errno.h>
12#include <linux/string.h>
13#include <linux/termios.h>
14#include <linux/tty.h>
15#include <linux/ioctl.h>
16#include <linux/route.h>
17#include <linux/sockios.h>
18#include <linux/if.h>
19#include <linux/netdevice.h>
20#include <linux/if_arp.h>
21#include <linux/fs.h>
22#include <linux/file.h>
23#include <linux/mm.h>
24#include <linux/smp.h>
25#include <linux/syscalls.h>
26#include <linux/compat.h>
27
28#define SUNOS_NR_OPEN 256
29
30struct rtentry32 {
31 u32 rt_pad1;
32 struct sockaddr rt_dst; /* target address */
33 struct sockaddr rt_gateway; /* gateway addr (RTF_GATEWAY) */
34 struct sockaddr rt_genmask; /* target network mask (IP) */
35 unsigned short rt_flags;
36 short rt_pad2;
37 u32 rt_pad3;
38 unsigned char rt_tos;
39 unsigned char rt_class;
40 short rt_pad4;
41 short rt_metric; /* +1 for binary compatibility! */
42 /* char * */ u32 rt_dev; /* forcing the device at add */
43 u32 rt_mtu; /* per route MTU/Window */
44 u32 rt_window; /* Window clamping */
45 unsigned short rt_irtt; /* Initial RTT */
46
47};
48
49struct ifmap32 {
50 u32 mem_start;
51 u32 mem_end;
52 unsigned short base_addr;
53 unsigned char irq;
54 unsigned char dma;
55 unsigned char port;
56};
57
58struct ifreq32 {
59#define IFHWADDRLEN 6
60#define IFNAMSIZ 16
61 union {
62 char ifrn_name[IFNAMSIZ]; /* if name, e.g. "en0" */
63 } ifr_ifrn;
64 union {
65 struct sockaddr ifru_addr;
66 struct sockaddr ifru_dstaddr;
67 struct sockaddr ifru_broadaddr;
68 struct sockaddr ifru_netmask;
69 struct sockaddr ifru_hwaddr;
70 short ifru_flags;
71 int ifru_ivalue;
72 int ifru_mtu;
73 struct ifmap32 ifru_map;
74 char ifru_slave[IFNAMSIZ]; /* Just fits the size */
75 compat_caddr_t ifru_data;
76 } ifr_ifru;
77};
78
79struct ifconf32 {
80 int ifc_len; /* size of buffer */
81 compat_caddr_t ifcbuf;
82};
83
84extern asmlinkage int compat_sys_ioctl(unsigned int, unsigned int, u32);
85
86asmlinkage int sunos_ioctl (int fd, u32 cmd, u32 arg)
87{
88 int ret = -EBADF;
89
90 if(fd >= SUNOS_NR_OPEN)
91 goto out;
92 if(!fcheck(fd))
93 goto out;
94
95 if(cmd == TIOCSETD) {
96 mm_segment_t old_fs = get_fs();
97 int __user *p;
98 int ntty = N_TTY;
99 int tmp;
100
101 p = (int __user *) (unsigned long) arg;
102 ret = -EFAULT;
103 if(get_user(tmp, p))
104 goto out;
105 if(tmp == 2) {
106 set_fs(KERNEL_DS);
107 ret = sys_ioctl(fd, cmd, (unsigned long) &ntty);
108 set_fs(old_fs);
109 ret = (ret == -EINVAL ? -EOPNOTSUPP : ret);
110 goto out;
111 }
112 }
113 if(cmd == TIOCNOTTY) {
114 ret = sys_setsid();
115 goto out;
116 }
117 switch(cmd) {
118 case _IOW('r', 10, struct rtentry32):
119 ret = compat_sys_ioctl(fd, SIOCADDRT, arg);
120 goto out;
121 case _IOW('r', 11, struct rtentry32):
122 ret = compat_sys_ioctl(fd, SIOCDELRT, arg);
123 goto out;
124
125 case _IOW('i', 12, struct ifreq32):
126 ret = compat_sys_ioctl(fd, SIOCSIFADDR, arg);
127 goto out;
128 case _IOWR('i', 13, struct ifreq32):
129 ret = compat_sys_ioctl(fd, SIOCGIFADDR, arg);
130 goto out;
131 case _IOW('i', 14, struct ifreq32):
132 ret = compat_sys_ioctl(fd, SIOCSIFDSTADDR, arg);
133 goto out;
134 case _IOWR('i', 15, struct ifreq32):
135 ret = compat_sys_ioctl(fd, SIOCGIFDSTADDR, arg);
136 goto out;
137 case _IOW('i', 16, struct ifreq32):
138 ret = compat_sys_ioctl(fd, SIOCSIFFLAGS, arg);
139 goto out;
140 case _IOWR('i', 17, struct ifreq32):
141 ret = compat_sys_ioctl(fd, SIOCGIFFLAGS, arg);
142 goto out;
143 case _IOW('i', 18, struct ifreq32):
144 ret = compat_sys_ioctl(fd, SIOCSIFMEM, arg);
145 goto out;
146 case _IOWR('i', 19, struct ifreq32):
147 ret = compat_sys_ioctl(fd, SIOCGIFMEM, arg);
148 goto out;
149
150 case _IOWR('i', 20, struct ifconf32):
151 ret = compat_sys_ioctl(fd, SIOCGIFCONF, arg);
152 goto out;
153
154 case _IOW('i', 21, struct ifreq32):
155 ret = compat_sys_ioctl(fd, SIOCSIFMTU, arg);
156 goto out;
157
158 case _IOWR('i', 22, struct ifreq32):
159 ret = compat_sys_ioctl(fd, SIOCGIFMTU, arg);
160 goto out;
161
162 case _IOWR('i', 23, struct ifreq32):
163 ret = compat_sys_ioctl(fd, SIOCGIFBRDADDR, arg);
164 goto out;
165 case _IOW('i', 24, struct ifreq32):
166 ret = compat_sys_ioctl(fd, SIOCSIFBRDADDR, arg);
167 goto out;
168 case _IOWR('i', 25, struct ifreq32):
169 ret = compat_sys_ioctl(fd, SIOCGIFNETMASK, arg);
170 goto out;
171 case _IOW('i', 26, struct ifreq32):
172 ret = compat_sys_ioctl(fd, SIOCSIFNETMASK, arg);
173 goto out;
174 case _IOWR('i', 27, struct ifreq32):
175 ret = compat_sys_ioctl(fd, SIOCGIFMETRIC, arg);
176 goto out;
177 case _IOW('i', 28, struct ifreq32):
178 ret = compat_sys_ioctl(fd, SIOCSIFMETRIC, arg);
179 goto out;
180
181 case _IOW('i', 30, struct arpreq):
182 ret = compat_sys_ioctl(fd, SIOCSARP, arg);
183 goto out;
184 case _IOWR('i', 31, struct arpreq):
185 ret = compat_sys_ioctl(fd, SIOCGARP, arg);
186 goto out;
187 case _IOW('i', 32, struct arpreq):
188 ret = compat_sys_ioctl(fd, SIOCDARP, arg);
189 goto out;
190
191 case _IOW('i', 40, struct ifreq32): /* SIOCUPPER */
192 case _IOW('i', 41, struct ifreq32): /* SIOCLOWER */
193 case _IOW('i', 44, struct ifreq32): /* SIOCSETSYNC */
194 case _IOW('i', 45, struct ifreq32): /* SIOCGETSYNC */
195 case _IOW('i', 46, struct ifreq32): /* SIOCSSDSTATS */
196 case _IOW('i', 47, struct ifreq32): /* SIOCSSESTATS */
197 case _IOW('i', 48, struct ifreq32): /* SIOCSPROMISC */
198 ret = -EOPNOTSUPP;
199 goto out;
200
201 case _IOW('i', 49, struct ifreq32):
202 ret = compat_sys_ioctl(fd, SIOCADDMULTI, arg);
203 goto out;
204 case _IOW('i', 50, struct ifreq32):
205 ret = compat_sys_ioctl(fd, SIOCDELMULTI, arg);
206 goto out;
207
208 /* FDDI interface ioctls, unsupported. */
209
210 case _IOW('i', 51, struct ifreq32): /* SIOCFDRESET */
211 case _IOW('i', 52, struct ifreq32): /* SIOCFDSLEEP */
212 case _IOW('i', 53, struct ifreq32): /* SIOCSTRTFMWAR */
213 case _IOW('i', 54, struct ifreq32): /* SIOCLDNSTRTFW */
214 case _IOW('i', 55, struct ifreq32): /* SIOCGETFDSTAT */
215 case _IOW('i', 56, struct ifreq32): /* SIOCFDNMIINT */
216 case _IOW('i', 57, struct ifreq32): /* SIOCFDEXUSER */
217 case _IOW('i', 58, struct ifreq32): /* SIOCFDGNETMAP */
218 case _IOW('i', 59, struct ifreq32): /* SIOCFDGIOCTL */
219 printk("FDDI ioctl, returning EOPNOTSUPP\n");
220 ret = -EOPNOTSUPP;
221 goto out;
222
223 case _IOW('t', 125, int):
224 /* More stupid tty sunos ioctls, just
225 * say it worked.
226 */
227 ret = 0;
228 goto out;
229
230 /* Non posix grp */
231 case _IOW('t', 118, int): {
232 int oldval, newval, __user *ptr;
233
234 cmd = TIOCSPGRP;
235 ptr = (int __user *) (unsigned long) arg;
236 ret = -EFAULT;
237 if(get_user(oldval, ptr))
238 goto out;
239 ret = compat_sys_ioctl(fd, cmd, arg);
240 __get_user(newval, ptr);
241 if(newval == -1) {
242 __put_user(oldval, ptr);
243 ret = -EIO;
244 }
245 if(ret == -ENOTTY)
246 ret = -EIO;
247 goto out;
248 }
249
250 case _IOR('t', 119, int): {
251 int oldval, newval, __user *ptr;
252
253 cmd = TIOCGPGRP;
254 ptr = (int __user *) (unsigned long) arg;
255 ret = -EFAULT;
256 if(get_user(oldval, ptr))
257 goto out;
258 ret = compat_sys_ioctl(fd, cmd, arg);
259 __get_user(newval, ptr);
260 if(newval == -1) {
261 __put_user(oldval, ptr);
262 ret = -EIO;
263 }
264 if(ret == -ENOTTY)
265 ret = -EIO;
266 goto out;
267 }
268 };
269
270 ret = compat_sys_ioctl(fd, cmd, arg);
271 /* so stupid... */
272 ret = (ret == -EINVAL ? -EOPNOTSUPP : ret);
273out:
274 return ret;
275}
diff --git a/arch/sparc64/kernel/sys_sparc.c b/arch/sparc64/kernel/sys_sparc.c
index f952745d0f3d..73ed01ba40dc 100644
--- a/arch/sparc64/kernel/sys_sparc.c
+++ b/arch/sparc64/kernel/sys_sparc.c
@@ -720,44 +720,6 @@ out:
720 return err; 720 return err;
721} 721}
722 722
723asmlinkage long solaris_syscall(struct pt_regs *regs)
724{
725 static int count;
726
727 regs->tpc = regs->tnpc;
728 regs->tnpc += 4;
729 if (test_thread_flag(TIF_32BIT)) {
730 regs->tpc &= 0xffffffff;
731 regs->tnpc &= 0xffffffff;
732 }
733 if (++count <= 5) {
734 printk ("For Solaris binary emulation you need solaris module loaded\n");
735 show_regs (regs);
736 }
737 send_sig(SIGSEGV, current, 1);
738
739 return -ENOSYS;
740}
741
742#ifndef CONFIG_SUNOS_EMUL
743asmlinkage long sunos_syscall(struct pt_regs *regs)
744{
745 static int count;
746
747 regs->tpc = regs->tnpc;
748 regs->tnpc += 4;
749 if (test_thread_flag(TIF_32BIT)) {
750 regs->tpc &= 0xffffffff;
751 regs->tnpc &= 0xffffffff;
752 }
753 if (++count <= 20)
754 printk ("SunOS binary emulation not compiled in\n");
755 force_sig(SIGSEGV, current);
756
757 return -ENOSYS;
758}
759#endif
760
761asmlinkage long sys_utrap_install(utrap_entry_t type, 723asmlinkage long sys_utrap_install(utrap_entry_t type,
762 utrap_handler_t new_p, 724 utrap_handler_t new_p,
763 utrap_handler_t new_d, 725 utrap_handler_t new_d,
diff --git a/arch/sparc64/kernel/sys_sunos32.c b/arch/sparc64/kernel/sys_sunos32.c
deleted file mode 100644
index e91194fe39d7..000000000000
--- a/arch/sparc64/kernel/sys_sunos32.c
+++ /dev/null
@@ -1,1359 +0,0 @@
1/* $Id: sys_sunos32.c,v 1.64 2002/02/09 19:49:31 davem Exp $
2 * sys_sunos32.c: SunOS binary compatibility layer on sparc64.
3 *
4 * Copyright (C) 1995, 1996, 1997 David S. Miller (davem@caip.rutgers.edu)
5 * Copyright (C) 1995 Miguel de Icaza (miguel@nuclecu.unam.mx)
6 *
7 * Based upon preliminary work which is:
8 *
9 * Copyright (C) 1995 Adrian M. Rodriguez (adrian@remus.rutgers.edu)
10 */
11
12#include <linux/kernel.h>
13#include <linux/sched.h>
14#include <linux/types.h>
15#include <linux/capability.h>
16#include <linux/compat.h>
17#include <linux/mman.h>
18#include <linux/mm.h>
19#include <linux/swap.h>
20#include <linux/fs.h>
21#include <linux/file.h>
22#include <linux/resource.h>
23#include <linux/ipc.h>
24#include <linux/shm.h>
25#include <linux/msg.h>
26#include <linux/sem.h>
27#include <linux/signal.h>
28#include <linux/uio.h>
29#include <linux/utsname.h>
30#include <linux/major.h>
31#include <linux/stat.h>
32#include <linux/slab.h>
33#include <linux/pagemap.h>
34#include <linux/errno.h>
35#include <linux/smp.h>
36#include <linux/smp_lock.h>
37#include <linux/syscalls.h>
38
39#include <asm/uaccess.h>
40#include <asm/page.h>
41#include <asm/pgtable.h>
42#include <asm/pconf.h>
43#include <asm/idprom.h> /* for gethostid() */
44#include <asm/unistd.h>
45#include <asm/system.h>
46#include <asm/compat_signal.h>
47
48/* For the nfs mount emulation */
49#include <linux/socket.h>
50#include <linux/in.h>
51#include <linux/nfs.h>
52#include <linux/nfs2.h>
53#include <linux/nfs_mount.h>
54
55/* for sunos_select */
56#include <linux/time.h>
57#include <linux/personality.h>
58
59/* For SOCKET_I */
60#include <net/sock.h>
61#include <net/compat.h>
62
63#define SUNOS_NR_OPEN 256
64
65asmlinkage u32 sunos_mmap(u32 addr, u32 len, u32 prot, u32 flags, u32 fd, u32 off)
66{
67 struct file *file = NULL;
68 unsigned long retval, ret_type;
69
70 if (flags & MAP_NORESERVE) {
71 static int cnt;
72 if (cnt++ < 10)
73 printk("%s: unimplemented SunOS MAP_NORESERVE mmap() flag\n",
74 current->comm);
75 flags &= ~MAP_NORESERVE;
76 }
77 retval = -EBADF;
78 if (!(flags & MAP_ANONYMOUS)) {
79 struct inode * inode;
80 if (fd >= SUNOS_NR_OPEN)
81 goto out;
82 file = fget(fd);
83 if (!file)
84 goto out;
85 inode = file->f_path.dentry->d_inode;
86 if (imajor(inode) == MEM_MAJOR && iminor(inode) == 5) {
87 flags |= MAP_ANONYMOUS;
88 fput(file);
89 file = NULL;
90 }
91 }
92
93 retval = -EINVAL;
94 if (!(flags & MAP_FIXED))
95 addr = 0;
96 else if (len > 0xf0000000 || addr > 0xf0000000 - len)
97 goto out_putf;
98 ret_type = flags & _MAP_NEW;
99 flags &= ~_MAP_NEW;
100
101 flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
102 down_write(&current->mm->mmap_sem);
103 retval = do_mmap(file,
104 (unsigned long) addr, (unsigned long) len,
105 (unsigned long) prot, (unsigned long) flags,
106 (unsigned long) off);
107 up_write(&current->mm->mmap_sem);
108 if (!ret_type)
109 retval = ((retval < 0xf0000000) ? 0 : retval);
110out_putf:
111 if (file)
112 fput(file);
113out:
114 return (u32) retval;
115}
116
117asmlinkage int sunos_mctl(u32 addr, u32 len, int function, u32 arg)
118{
119 return 0;
120}
121
122asmlinkage int sunos_brk(u32 baddr)
123{
124 int freepages, retval = -ENOMEM;
125 unsigned long rlim;
126 unsigned long newbrk, oldbrk, brk = (unsigned long) baddr;
127
128 down_write(&current->mm->mmap_sem);
129 if (brk < current->mm->end_code)
130 goto out;
131 newbrk = PAGE_ALIGN(brk);
132 oldbrk = PAGE_ALIGN(current->mm->brk);
133 retval = 0;
134 if (oldbrk == newbrk) {
135 current->mm->brk = brk;
136 goto out;
137 }
138 /* Always allow shrinking brk. */
139 if (brk <= current->mm->brk) {
140 current->mm->brk = brk;
141 do_munmap(current->mm, newbrk, oldbrk-newbrk);
142 goto out;
143 }
144 /* Check against rlimit and stack.. */
145 retval = -ENOMEM;
146 rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur;
147 if (rlim >= RLIM_INFINITY)
148 rlim = ~0;
149 if (brk - current->mm->end_code > rlim)
150 goto out;
151 /* Check against existing mmap mappings. */
152 if (find_vma_intersection(current->mm, oldbrk, newbrk+PAGE_SIZE))
153 goto out;
154 /* stupid algorithm to decide if we have enough memory: while
155 * simple, it hopefully works in most obvious cases.. Easy to
156 * fool it, but this should catch most mistakes.
157 */
158 freepages = global_page_state(NR_FILE_PAGES);
159 freepages >>= 1;
160 freepages += nr_free_pages();
161 freepages += nr_swap_pages;
162 freepages -= num_physpages >> 4;
163 freepages -= (newbrk-oldbrk) >> PAGE_SHIFT;
164 if (freepages < 0)
165 goto out;
166 /* Ok, we have probably got enough memory - let it rip. */
167 current->mm->brk = brk;
168 do_brk(oldbrk, newbrk-oldbrk);
169 retval = 0;
170out:
171 up_write(&current->mm->mmap_sem);
172 return retval;
173}
174
175asmlinkage u32 sunos_sbrk(int increment)
176{
177 int error, oldbrk;
178
179 /* This should do it hopefully... */
180 oldbrk = (int)current->mm->brk;
181 error = sunos_brk(((int) current->mm->brk) + increment);
182 if (!error)
183 error = oldbrk;
184 return error;
185}
186
187asmlinkage u32 sunos_sstk(int increment)
188{
189 printk("%s: Call to sunos_sstk(increment<%d>) is unsupported\n",
190 current->comm, increment);
191
192 return (u32)-1;
193}
194
195/* Give hints to the kernel as to what paging strategy to use...
196 * Completely bogus, don't remind me.
197 */
198#define VA_NORMAL 0 /* Normal vm usage expected */
199#define VA_ABNORMAL 1 /* Abnormal/random vm usage probable */
200#define VA_SEQUENTIAL 2 /* Accesses will be of a sequential nature */
201#define VA_INVALIDATE 3 /* Page table entries should be flushed ??? */
202static char *vstrings[] = {
203 "VA_NORMAL",
204 "VA_ABNORMAL",
205 "VA_SEQUENTIAL",
206 "VA_INVALIDATE",
207};
208
209asmlinkage void sunos_vadvise(u32 strategy)
210{
211 static int count;
212
213 /* I wanna see who uses this... */
214 if (count++ < 5)
215 printk("%s: Advises us to use %s paging strategy\n",
216 current->comm,
217 strategy <= 3 ? vstrings[strategy] : "BOGUS");
218}
219
220/* This just wants the soft limit (ie. rlim_cur element) of the RLIMIT_NOFILE
221 * resource limit and is for backwards compatibility with older sunos
222 * revs.
223 */
224asmlinkage int sunos_getdtablesize(void)
225{
226 return SUNOS_NR_OPEN;
227}
228
229
230#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
231
232asmlinkage u32 sunos_sigblock(u32 blk_mask)
233{
234 u32 old;
235
236 spin_lock_irq(&current->sighand->siglock);
237 old = (u32) current->blocked.sig[0];
238 current->blocked.sig[0] |= (blk_mask & _BLOCKABLE);
239 recalc_sigpending();
240 spin_unlock_irq(&current->sighand->siglock);
241 return old;
242}
243
244asmlinkage u32 sunos_sigsetmask(u32 newmask)
245{
246 u32 retval;
247
248 spin_lock_irq(&current->sighand->siglock);
249 retval = (u32) current->blocked.sig[0];
250 current->blocked.sig[0] = (newmask & _BLOCKABLE);
251 recalc_sigpending();
252 spin_unlock_irq(&current->sighand->siglock);
253 return retval;
254}
255
256/* SunOS getdents is very similar to the newer Linux (iBCS2 compliant) */
257/* getdents system call, the format of the structure just has a different */
258/* layout (d_off+d_ino instead of d_ino+d_off) */
259struct sunos_dirent {
260 s32 d_off;
261 u32 d_ino;
262 u16 d_reclen;
263 u16 d_namlen;
264 char d_name[1];
265};
266
267struct sunos_dirent_callback {
268 struct sunos_dirent __user *curr;
269 struct sunos_dirent __user *previous;
270 int count;
271 int error;
272};
273
274#define NAME_OFFSET(de) ((int) ((de)->d_name - (char __user *) (de)))
275#define ROUND_UP(x) (((x)+sizeof(s32)-1) & ~(sizeof(s32)-1))
276
277static int sunos_filldir(void * __buf, const char * name, int namlen,
278 loff_t offset, ino_t ino, unsigned int d_type)
279{
280 struct sunos_dirent __user *dirent;
281 struct sunos_dirent_callback * buf = (struct sunos_dirent_callback *) __buf;
282 int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1);
283 u32 d_ino;
284
285 buf->error = -EINVAL; /* only used if we fail.. */
286 if (reclen > buf->count)
287 return -EINVAL;
288 d_ino = ino;
289 if (sizeof(d_ino) < sizeof(ino) && d_ino != ino)
290 return -EOVERFLOW;
291 dirent = buf->previous;
292 if (dirent)
293 put_user(offset, &dirent->d_off);
294 dirent = buf->curr;
295 buf->previous = dirent;
296 put_user(d_ino, &dirent->d_ino);
297 put_user(namlen, &dirent->d_namlen);
298 put_user(reclen, &dirent->d_reclen);
299 if (copy_to_user(dirent->d_name, name, namlen))
300 return -EFAULT;
301 put_user(0, dirent->d_name + namlen);
302 dirent = (void __user *) dirent + reclen;
303 buf->curr = dirent;
304 buf->count -= reclen;
305 return 0;
306}
307
308asmlinkage int sunos_getdents(unsigned int fd, void __user *dirent, int cnt)
309{
310 struct file * file;
311 struct sunos_dirent __user *lastdirent;
312 struct sunos_dirent_callback buf;
313 int error = -EBADF;
314
315 if (fd >= SUNOS_NR_OPEN)
316 goto out;
317
318 file = fget(fd);
319 if (!file)
320 goto out;
321
322 error = -EINVAL;
323 if (cnt < (sizeof(struct sunos_dirent) + 255))
324 goto out_putf;
325
326 buf.curr = (struct sunos_dirent __user *) dirent;
327 buf.previous = NULL;
328 buf.count = cnt;
329 buf.error = 0;
330
331 error = vfs_readdir(file, sunos_filldir, &buf);
332 if (error < 0)
333 goto out_putf;
334
335 lastdirent = buf.previous;
336 error = buf.error;
337 if (lastdirent) {
338 put_user(file->f_pos, &lastdirent->d_off);
339 error = cnt - buf.count;
340 }
341
342out_putf:
343 fput(file);
344out:
345 return error;
346}
347
348/* Old sunos getdirentries, severely broken compatibility stuff here. */
349struct sunos_direntry {
350 u32 d_ino;
351 u16 d_reclen;
352 u16 d_namlen;
353 char d_name[1];
354};
355
356struct sunos_direntry_callback {
357 struct sunos_direntry __user *curr;
358 struct sunos_direntry __user *previous;
359 int count;
360 int error;
361};
362
363static int sunos_filldirentry(void * __buf, const char * name, int namlen,
364 loff_t offset, ino_t ino, unsigned int d_type)
365{
366 struct sunos_direntry __user *dirent;
367 struct sunos_direntry_callback * buf =
368 (struct sunos_direntry_callback *) __buf;
369 int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1);
370 u32 d_ino;
371
372 buf->error = -EINVAL; /* only used if we fail.. */
373 if (reclen > buf->count)
374 return -EINVAL;
375 d_ino = ino;
376 if (sizeof(d_ino) < sizeof(ino) && d_ino != ino)
377 return -EOVERFLOW;
378 dirent = buf->previous;
379 dirent = buf->curr;
380 buf->previous = dirent;
381 put_user(d_ino, &dirent->d_ino);
382 put_user(namlen, &dirent->d_namlen);
383 put_user(reclen, &dirent->d_reclen);
384 if (copy_to_user(dirent->d_name, name, namlen))
385 return -EFAULT;
386 put_user(0, dirent->d_name + namlen);
387 dirent = (void __user *) dirent + reclen;
388 buf->curr = dirent;
389 buf->count -= reclen;
390 return 0;
391}
392
393asmlinkage int sunos_getdirentries(unsigned int fd,
394 void __user *dirent,
395 int cnt,
396 unsigned int __user *basep)
397{
398 struct file * file;
399 struct sunos_direntry __user *lastdirent;
400 int error = -EBADF;
401 struct sunos_direntry_callback buf;
402
403 if (fd >= SUNOS_NR_OPEN)
404 goto out;
405
406 file = fget(fd);
407 if (!file)
408 goto out;
409
410 error = -EINVAL;
411 if (cnt < (sizeof(struct sunos_direntry) + 255))
412 goto out_putf;
413
414 buf.curr = (struct sunos_direntry __user *) dirent;
415 buf.previous = NULL;
416 buf.count = cnt;
417 buf.error = 0;
418
419 error = vfs_readdir(file, sunos_filldirentry, &buf);
420 if (error < 0)
421 goto out_putf;
422
423 lastdirent = buf.previous;
424 error = buf.error;
425 if (lastdirent) {
426 put_user(file->f_pos, basep);
427 error = cnt - buf.count;
428 }
429
430out_putf:
431 fput(file);
432out:
433 return error;
434}
435
436struct sunos_utsname {
437 char sname[9];
438 char nname[9];
439 char nnext[56];
440 char rel[9];
441 char ver[9];
442 char mach[9];
443};
444
445asmlinkage int sunos_uname(struct sunos_utsname __user *name)
446{
447 int ret;
448
449 down_read(&uts_sem);
450 ret = copy_to_user(&name->sname[0], &utsname()->sysname[0],
451 sizeof(name->sname) - 1);
452 ret |= copy_to_user(&name->nname[0], &utsname()->nodename[0],
453 sizeof(name->nname) - 1);
454 ret |= put_user('\0', &name->nname[8]);
455 ret |= copy_to_user(&name->rel[0], &utsname()->release[0],
456 sizeof(name->rel) - 1);
457 ret |= copy_to_user(&name->ver[0], &utsname()->version[0],
458 sizeof(name->ver) - 1);
459 ret |= copy_to_user(&name->mach[0], &utsname()->machine[0],
460 sizeof(name->mach) - 1);
461 up_read(&uts_sem);
462 return (ret ? -EFAULT : 0);
463}
464
465asmlinkage int sunos_nosys(void)
466{
467 struct pt_regs *regs;
468 siginfo_t info;
469 static int cnt;
470
471 regs = current_thread_info()->kregs;
472 if (test_thread_flag(TIF_32BIT)) {
473 regs->tpc &= 0xffffffff;
474 regs->tnpc &= 0xffffffff;
475 }
476 info.si_signo = SIGSYS;
477 info.si_errno = 0;
478 info.si_code = __SI_FAULT|0x100;
479 info.si_addr = (void __user *)regs->tpc;
480 info.si_trapno = regs->u_regs[UREG_G1];
481 send_sig_info(SIGSYS, &info, current);
482 if (cnt++ < 4) {
483 printk("Process makes ni_syscall number %d, register dump:\n",
484 (int) regs->u_regs[UREG_G1]);
485 show_regs(regs);
486 }
487 return -ENOSYS;
488}
489
490/* This is not a real and complete implementation yet, just to keep
491 * the easy SunOS binaries happy.
492 */
493asmlinkage int sunos_fpathconf(int fd, int name)
494{
495 int ret;
496
497 switch(name) {
498 case _PCONF_LINK:
499 ret = LINK_MAX;
500 break;
501 case _PCONF_CANON:
502 ret = MAX_CANON;
503 break;
504 case _PCONF_INPUT:
505 ret = MAX_INPUT;
506 break;
507 case _PCONF_NAME:
508 ret = NAME_MAX;
509 break;
510 case _PCONF_PATH:
511 ret = PATH_MAX;
512 break;
513 case _PCONF_PIPE:
514 ret = PIPE_BUF;
515 break;
516 case _PCONF_CHRESTRICT: /* XXX Investigate XXX */
517 ret = 1;
518 break;
519 case _PCONF_NOTRUNC: /* XXX Investigate XXX */
520 case _PCONF_VDISABLE:
521 ret = 0;
522 break;
523 default:
524 ret = -EINVAL;
525 break;
526 }
527 return ret;
528}
529
530asmlinkage int sunos_pathconf(u32 u_path, int name)
531{
532 int ret;
533
534 ret = sunos_fpathconf(0, name); /* XXX cheese XXX */
535 return ret;
536}
537
538asmlinkage int sunos_select(int width, u32 inp, u32 outp, u32 exp, u32 tvp_x)
539{
540 int ret;
541
542 /* SunOS binaries expect that select won't change the tvp contents */
543 ret = compat_sys_select(width, compat_ptr(inp), compat_ptr(outp),
544 compat_ptr(exp), compat_ptr(tvp_x));
545 if (ret == -EINTR && tvp_x) {
546 struct compat_timeval __user *tvp = compat_ptr(tvp_x);
547 time_t sec, usec;
548
549 __get_user(sec, &tvp->tv_sec);
550 __get_user(usec, &tvp->tv_usec);
551 if (sec == 0 && usec == 0)
552 ret = 0;
553 }
554 return ret;
555}
556
557asmlinkage void sunos_nop(void)
558{
559 return;
560}
561
562#if 0 /* This code doesn't translate user pointers correctly,
563 * disable for now. -DaveM
564 */
565
566/* XXXXXXXXXX SunOS mount/umount. XXXXXXXXXXX */
567#define SMNT_RDONLY 1
568#define SMNT_NOSUID 2
569#define SMNT_NEWTYPE 4
570#define SMNT_GRPID 8
571#define SMNT_REMOUNT 16
572#define SMNT_NOSUB 32
573#define SMNT_MULTI 64
574#define SMNT_SYS5 128
575
576struct sunos_fh_t {
577 char fh_data [NFS_FHSIZE];
578};
579
580struct sunos_nfs_mount_args {
581 struct sockaddr_in *addr; /* file server address */
582 struct nfs_fh *fh; /* File handle to be mounted */
583 int flags; /* flags */
584 int wsize; /* write size in bytes */
585 int rsize; /* read size in bytes */
586 int timeo; /* initial timeout in .1 secs */
587 int retrans; /* times to retry send */
588 char *hostname; /* server's hostname */
589 int acregmin; /* attr cache file min secs */
590 int acregmax; /* attr cache file max secs */
591 int acdirmin; /* attr cache dir min secs */
592 int acdirmax; /* attr cache dir max secs */
593 char *netname; /* server's netname */
594};
595
596
597/* Bind the socket on a local reserved port and connect it to the
598 * remote server. This on Linux/i386 is done by the mount program,
599 * not by the kernel.
600 */
601/* XXXXXXXXXXXXXXXXXXXX */
602static int
603sunos_nfs_get_server_fd (int fd, struct sockaddr_in *addr)
604{
605 struct sockaddr_in local;
606 struct sockaddr_in server;
607 int try_port;
608 int ret;
609 struct socket *socket;
610 struct inode *inode;
611 struct file *file;
612
613 file = fget(fd);
614 if (!file)
615 return 0;
616
617 inode = file->f_path.dentry->d_inode;
618
619 socket = SOCKET_I(inode);
620 local.sin_family = AF_INET;
621 local.sin_addr.s_addr = htonl(INADDR_ANY);
622
623 /* IPPORT_RESERVED = 1024, can't find the definition in the kernel */
624 try_port = 1024;
625 do {
626 local.sin_port = htons (--try_port);
627 ret = socket->ops->bind(socket, (struct sockaddr*)&local,
628 sizeof(local));
629 } while (ret && try_port > (1024 / 2));
630
631 if (ret) {
632 fput(file);
633 return 0;
634 }
635
636 server.sin_family = AF_INET;
637 server.sin_addr = addr->sin_addr;
638 server.sin_port = NFS_PORT;
639
640 /* Call sys_connect */
641 ret = socket->ops->connect (socket, (struct sockaddr *) &server,
642 sizeof (server), file->f_flags);
643 fput(file);
644 if (ret < 0)
645 return 0;
646 return 1;
647}
648
649/* XXXXXXXXXXXXXXXXXXXX */
650static int get_default (int value, int def_value)
651{
652 if (value)
653 return value;
654 else
655 return def_value;
656}
657
658/* XXXXXXXXXXXXXXXXXXXX */
659static int sunos_nfs_mount(char *dir_name, int linux_flags, void __user *data)
660{
661 int server_fd, err;
662 char *the_name, *mount_page;
663 struct nfs_mount_data linux_nfs_mount;
664 struct sunos_nfs_mount_args sunos_mount;
665
666 /* Ok, here comes the fun part: Linux's nfs mount needs a
667 * socket connection to the server, but SunOS mount does not
668 * require this, so we use the information on the destination
669 * address to create a socket and bind it to a reserved
670 * port on this system
671 */
672 if (copy_from_user(&sunos_mount, data, sizeof(sunos_mount)))
673 return -EFAULT;
674
675 server_fd = sys_socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP);
676 if (server_fd < 0)
677 return -ENXIO;
678
679 if (copy_from_user(&linux_nfs_mount.addr, sunos_mount.addr,
680 sizeof(*sunos_mount.addr)) ||
681 copy_from_user(&linux_nfs_mount.root, sunos_mount.fh,
682 sizeof(*sunos_mount.fh))) {
683 sys_close (server_fd);
684 return -EFAULT;
685 }
686
687 if (!sunos_nfs_get_server_fd (server_fd, &linux_nfs_mount.addr)){
688 sys_close (server_fd);
689 return -ENXIO;
690 }
691
692 /* Now, bind it to a locally reserved port */
693 linux_nfs_mount.version = NFS_MOUNT_VERSION;
694 linux_nfs_mount.flags = sunos_mount.flags;
695 linux_nfs_mount.fd = server_fd;
696
697 linux_nfs_mount.rsize = get_default (sunos_mount.rsize, 8192);
698 linux_nfs_mount.wsize = get_default (sunos_mount.wsize, 8192);
699 linux_nfs_mount.timeo = get_default (sunos_mount.timeo, 10);
700 linux_nfs_mount.retrans = sunos_mount.retrans;
701
702 linux_nfs_mount.acregmin = sunos_mount.acregmin;
703 linux_nfs_mount.acregmax = sunos_mount.acregmax;
704 linux_nfs_mount.acdirmin = sunos_mount.acdirmin;
705 linux_nfs_mount.acdirmax = sunos_mount.acdirmax;
706
707 the_name = getname(sunos_mount.hostname);
708 if (IS_ERR(the_name))
709 return PTR_ERR(the_name);
710
711 strlcpy(linux_nfs_mount.hostname, the_name,
712 sizeof(linux_nfs_mount.hostname));
713 putname (the_name);
714
715 mount_page = (char *) get_zeroed_page(GFP_KERNEL);
716 if (!mount_page)
717 return -ENOMEM;
718
719 memcpy(mount_page, &linux_nfs_mount, sizeof(linux_nfs_mount));
720
721 err = do_mount("", dir_name, "nfs", linux_flags, mount_page);
722
723 free_page((unsigned long) mount_page);
724 return err;
725}
726
727/* XXXXXXXXXXXXXXXXXXXX */
728asmlinkage int
729sunos_mount(char *type, char *dir, int flags, void *data)
730{
731 int linux_flags = 0;
732 int ret = -EINVAL;
733 char *dev_fname = 0;
734 char *dir_page, *type_page;
735
736 if (!capable (CAP_SYS_ADMIN))
737 return -EPERM;
738
739 /* We don't handle the integer fs type */
740 if ((flags & SMNT_NEWTYPE) == 0)
741 goto out;
742
743 /* Do not allow for those flags we don't support */
744 if (flags & (SMNT_GRPID|SMNT_NOSUB|SMNT_MULTI|SMNT_SYS5))
745 goto out;
746
747 if (flags & SMNT_REMOUNT)
748 linux_flags |= MS_REMOUNT;
749 if (flags & SMNT_RDONLY)
750 linux_flags |= MS_RDONLY;
751 if (flags & SMNT_NOSUID)
752 linux_flags |= MS_NOSUID;
753
754 dir_page = getname(dir);
755 ret = PTR_ERR(dir_page);
756 if (IS_ERR(dir_page))
757 goto out;
758
759 type_page = getname(type);
760 ret = PTR_ERR(type_page);
761 if (IS_ERR(type_page))
762 goto out1;
763
764 if (strcmp(type_page, "ext2") == 0) {
765 dev_fname = getname(data);
766 } else if (strcmp(type_page, "iso9660") == 0) {
767 dev_fname = getname(data);
768 } else if (strcmp(type_page, "minix") == 0) {
769 dev_fname = getname(data);
770 } else if (strcmp(type_page, "nfs") == 0) {
771 ret = sunos_nfs_mount (dir_page, flags, data);
772 goto out2;
773 } else if (strcmp(type_page, "ufs") == 0) {
774 printk("Warning: UFS filesystem mounts unsupported.\n");
775 ret = -ENODEV;
776 goto out2;
777 } else if (strcmp(type_page, "proc")) {
778 ret = -ENODEV;
779 goto out2;
780 }
781 ret = PTR_ERR(dev_fname);
782 if (IS_ERR(dev_fname))
783 goto out2;
784 lock_kernel();
785 ret = do_mount(dev_fname, dir_page, type_page, linux_flags, NULL);
786 unlock_kernel();
787 if (dev_fname)
788 putname(dev_fname);
789out2:
790 putname(type_page);
791out1:
792 putname(dir_page);
793out:
794 return ret;
795}
796#endif
797
798asmlinkage int sunos_setpgrp(pid_t pid, pid_t pgid)
799{
800 int ret;
801
802 /* So stupid... */
803 if ((!pid || pid == current->pid) &&
804 !pgid) {
805 sys_setsid();
806 ret = 0;
807 } else {
808 ret = sys_setpgid(pid, pgid);
809 }
810 return ret;
811}
812
813/* So stupid... */
814extern long compat_sys_wait4(compat_pid_t, compat_uint_t __user *, int,
815 struct compat_rusage __user *);
816
817asmlinkage int sunos_wait4(compat_pid_t pid, compat_uint_t __user *stat_addr, int options, struct compat_rusage __user *ru)
818{
819 int ret;
820
821 ret = compat_sys_wait4((pid ? pid : ((compat_pid_t)-1)),
822 stat_addr, options, ru);
823 return ret;
824}
825
826asmlinkage int sunos_killpg(int pgrp, int sig)
827{
828 int ret;
829
830 rcu_read_lock();
831 ret = -EINVAL;
832 if (pgrp > 0)
833 ret = kill_pgrp(find_vpid(pgrp), sig, 0);
834 rcu_read_unlock();
835
836 return ret;
837}
838
839asmlinkage int sunos_audit(void)
840{
841 printk ("sys_audit\n");
842 return -1;
843}
844
845asmlinkage u32 sunos_gethostid(void)
846{
847 u32 ret;
848
849 ret = (((u32)idprom->id_machtype << 24) | ((u32)idprom->id_sernum));
850
851 return ret;
852}
853
854/* sysconf options, for SunOS compatibility */
855#define _SC_ARG_MAX 1
856#define _SC_CHILD_MAX 2
857#define _SC_CLK_TCK 3
858#define _SC_NGROUPS_MAX 4
859#define _SC_OPEN_MAX 5
860#define _SC_JOB_CONTROL 6
861#define _SC_SAVED_IDS 7
862#define _SC_VERSION 8
863
864asmlinkage s32 sunos_sysconf (int name)
865{
866 s32 ret;
867
868 switch (name){
869 case _SC_ARG_MAX:
870 ret = ARG_MAX;
871 break;
872 case _SC_CHILD_MAX:
873 ret = current->signal->rlim[RLIMIT_NPROC].rlim_cur;
874 break;
875 case _SC_CLK_TCK:
876 ret = HZ;
877 break;
878 case _SC_NGROUPS_MAX:
879 ret = NGROUPS_MAX;
880 break;
881 case _SC_OPEN_MAX:
882 ret = current->signal->rlim[RLIMIT_NOFILE].rlim_cur;
883 break;
884 case _SC_JOB_CONTROL:
885 ret = 1; /* yes, we do support job control */
886 break;
887 case _SC_SAVED_IDS:
888 ret = 1; /* yes, we do support saved uids */
889 break;
890 case _SC_VERSION:
891 /* mhm, POSIX_VERSION is in /usr/include/unistd.h
892 * should it go on /usr/include/linux?
893 */
894 ret = 199009;
895 break;
896 default:
897 ret = -1;
898 break;
899 };
900 return ret;
901}
902
903asmlinkage int sunos_semsys(int op, u32 arg1, u32 arg2, u32 arg3, void __user *ptr)
904{
905 union semun arg4;
906 int ret;
907
908 switch (op) {
909 case 0:
910 /* Most arguments match on a 1:1 basis but cmd doesn't */
911 switch(arg3) {
912 case 4:
913 arg3=GETPID; break;
914 case 5:
915 arg3=GETVAL; break;
916 case 6:
917 arg3=GETALL; break;
918 case 3:
919 arg3=GETNCNT; break;
920 case 7:
921 arg3=GETZCNT; break;
922 case 8:
923 arg3=SETVAL; break;
924 case 9:
925 arg3=SETALL; break;
926 }
927 /* sys_semctl(): */
928 /* value to modify semaphore to */
929 arg4.__pad = ptr;
930 ret = sys_semctl((int)arg1, (int)arg2, (int)arg3, arg4);
931 break;
932 case 1:
933 /* sys_semget(): */
934 ret = sys_semget((key_t)arg1, (int)arg2, (int)arg3);
935 break;
936 case 2:
937 /* sys_semop(): */
938 ret = sys_semop((int)arg1, (struct sembuf __user *)(unsigned long)arg2,
939 (unsigned int) arg3);
940 break;
941 default:
942 ret = -EINVAL;
943 break;
944 };
945 return ret;
946}
947
948struct msgbuf32 {
949 s32 mtype;
950 char mtext[1];
951};
952
953struct ipc_perm32
954{
955 key_t key;
956 compat_uid_t uid;
957 compat_gid_t gid;
958 compat_uid_t cuid;
959 compat_gid_t cgid;
960 compat_mode_t mode;
961 unsigned short seq;
962};
963
964struct msqid_ds32
965{
966 struct ipc_perm32 msg_perm;
967 u32 msg_first;
968 u32 msg_last;
969 compat_time_t msg_stime;
970 compat_time_t msg_rtime;
971 compat_time_t msg_ctime;
972 u32 wwait;
973 u32 rwait;
974 unsigned short msg_cbytes;
975 unsigned short msg_qnum;
976 unsigned short msg_qbytes;
977 compat_ipc_pid_t msg_lspid;
978 compat_ipc_pid_t msg_lrpid;
979};
980
981static inline int sunos_msqid_get(struct msqid_ds32 __user *user,
982 struct msqid_ds *kern)
983{
984 if (get_user(kern->msg_perm.key, &user->msg_perm.key) ||
985 __get_user(kern->msg_perm.uid, &user->msg_perm.uid) ||
986 __get_user(kern->msg_perm.gid, &user->msg_perm.gid) ||
987 __get_user(kern->msg_perm.cuid, &user->msg_perm.cuid) ||
988 __get_user(kern->msg_perm.cgid, &user->msg_perm.cgid) ||
989 __get_user(kern->msg_stime, &user->msg_stime) ||
990 __get_user(kern->msg_rtime, &user->msg_rtime) ||
991 __get_user(kern->msg_ctime, &user->msg_ctime) ||
992 __get_user(kern->msg_ctime, &user->msg_cbytes) ||
993 __get_user(kern->msg_ctime, &user->msg_qnum) ||
994 __get_user(kern->msg_ctime, &user->msg_qbytes) ||
995 __get_user(kern->msg_ctime, &user->msg_lspid) ||
996 __get_user(kern->msg_ctime, &user->msg_lrpid))
997 return -EFAULT;
998 return 0;
999}
1000
1001static inline int sunos_msqid_put(struct msqid_ds32 __user *user,
1002 struct msqid_ds *kern)
1003{
1004 if (put_user(kern->msg_perm.key, &user->msg_perm.key) ||
1005 __put_user(kern->msg_perm.uid, &user->msg_perm.uid) ||
1006 __put_user(kern->msg_perm.gid, &user->msg_perm.gid) ||
1007 __put_user(kern->msg_perm.cuid, &user->msg_perm.cuid) ||
1008 __put_user(kern->msg_perm.cgid, &user->msg_perm.cgid) ||
1009 __put_user(kern->msg_stime, &user->msg_stime) ||
1010 __put_user(kern->msg_rtime, &user->msg_rtime) ||
1011 __put_user(kern->msg_ctime, &user->msg_ctime) ||
1012 __put_user(kern->msg_ctime, &user->msg_cbytes) ||
1013 __put_user(kern->msg_ctime, &user->msg_qnum) ||
1014 __put_user(kern->msg_ctime, &user->msg_qbytes) ||
1015 __put_user(kern->msg_ctime, &user->msg_lspid) ||
1016 __put_user(kern->msg_ctime, &user->msg_lrpid))
1017 return -EFAULT;
1018 return 0;
1019}
1020
1021static inline int sunos_msgbuf_get(struct msgbuf32 __user *user, struct msgbuf *kern, int len)
1022{
1023 if (get_user(kern->mtype, &user->mtype) ||
1024 __copy_from_user(kern->mtext, &user->mtext, len))
1025 return -EFAULT;
1026 return 0;
1027}
1028
1029static inline int sunos_msgbuf_put(struct msgbuf32 __user *user, struct msgbuf *kern, int len)
1030{
1031 if (put_user(kern->mtype, &user->mtype) ||
1032 __copy_to_user(user->mtext, kern->mtext, len))
1033 return -EFAULT;
1034 return 0;
1035}
1036
1037asmlinkage int sunos_msgsys(int op, u32 arg1, u32 arg2, u32 arg3, u32 arg4)
1038{
1039 struct sparc_stackf32 __user *sp;
1040 struct msqid_ds kds;
1041 struct msgbuf *kmbuf;
1042 mm_segment_t old_fs = get_fs();
1043 u32 arg5;
1044 int rval;
1045
1046 switch(op) {
1047 case 0:
1048 rval = sys_msgget((key_t)arg1, (int)arg2);
1049 break;
1050 case 1:
1051 if (!sunos_msqid_get((struct msqid_ds32 __user *)(unsigned long)arg3, &kds)) {
1052 set_fs(KERNEL_DS);
1053 rval = sys_msgctl((int)arg1, (int)arg2,
1054 (struct msqid_ds __user *)(unsigned long)arg3);
1055 set_fs(old_fs);
1056 if (!rval)
1057 rval = sunos_msqid_put((struct msqid_ds32 __user *)(unsigned long)arg3,
1058 &kds);
1059 } else
1060 rval = -EFAULT;
1061 break;
1062 case 2:
1063 rval = -EFAULT;
1064 kmbuf = kmalloc(sizeof(struct msgbuf) + arg3,
1065 GFP_KERNEL);
1066 if (!kmbuf)
1067 break;
1068 sp = (struct sparc_stackf32 __user *)
1069 (current_thread_info()->kregs->u_regs[UREG_FP] & 0xffffffffUL);
1070 if (get_user(arg5, &sp->xxargs[0])) {
1071 rval = -EFAULT;
1072 kfree(kmbuf);
1073 break;
1074 }
1075 set_fs(KERNEL_DS);
1076 rval = sys_msgrcv((int)arg1, (struct msgbuf __user *) kmbuf,
1077 (size_t)arg3,
1078 (long)arg4, (int)arg5);
1079 set_fs(old_fs);
1080 if (!rval)
1081 rval = sunos_msgbuf_put((struct msgbuf32 __user *)(unsigned long)arg2,
1082 kmbuf, arg3);
1083 kfree(kmbuf);
1084 break;
1085 case 3:
1086 rval = -EFAULT;
1087 kmbuf = kmalloc(sizeof(struct msgbuf) + arg3,
1088 GFP_KERNEL);
1089 if (!kmbuf || sunos_msgbuf_get((struct msgbuf32 __user *)(unsigned long)arg2,
1090 kmbuf, arg3))
1091 break;
1092 set_fs(KERNEL_DS);
1093 rval = sys_msgsnd((int)arg1, (struct msgbuf __user *) kmbuf,
1094 (size_t)arg3, (int)arg4);
1095 set_fs(old_fs);
1096 kfree(kmbuf);
1097 break;
1098 default:
1099 rval = -EINVAL;
1100 break;
1101 }
1102 return rval;
1103}
1104
1105struct shmid_ds32 {
1106 struct ipc_perm32 shm_perm;
1107 int shm_segsz;
1108 compat_time_t shm_atime;
1109 compat_time_t shm_dtime;
1110 compat_time_t shm_ctime;
1111 compat_ipc_pid_t shm_cpid;
1112 compat_ipc_pid_t shm_lpid;
1113 unsigned short shm_nattch;
1114};
1115
1116static inline int sunos_shmid_get(struct shmid_ds32 __user *user,
1117 struct shmid_ds *kern)
1118{
1119 if (get_user(kern->shm_perm.key, &user->shm_perm.key) ||
1120 __get_user(kern->shm_perm.uid, &user->shm_perm.uid) ||
1121 __get_user(kern->shm_perm.gid, &user->shm_perm.gid) ||
1122 __get_user(kern->shm_perm.cuid, &user->shm_perm.cuid) ||
1123 __get_user(kern->shm_perm.cgid, &user->shm_perm.cgid) ||
1124 __get_user(kern->shm_segsz, &user->shm_segsz) ||
1125 __get_user(kern->shm_atime, &user->shm_atime) ||
1126 __get_user(kern->shm_dtime, &user->shm_dtime) ||
1127 __get_user(kern->shm_ctime, &user->shm_ctime) ||
1128 __get_user(kern->shm_cpid, &user->shm_cpid) ||
1129 __get_user(kern->shm_lpid, &user->shm_lpid) ||
1130 __get_user(kern->shm_nattch, &user->shm_nattch))
1131 return -EFAULT;
1132 return 0;
1133}
1134
1135static inline int sunos_shmid_put(struct shmid_ds32 __user *user,
1136 struct shmid_ds *kern)
1137{
1138 if (put_user(kern->shm_perm.key, &user->shm_perm.key) ||
1139 __put_user(kern->shm_perm.uid, &user->shm_perm.uid) ||
1140 __put_user(kern->shm_perm.gid, &user->shm_perm.gid) ||
1141 __put_user(kern->shm_perm.cuid, &user->shm_perm.cuid) ||
1142 __put_user(kern->shm_perm.cgid, &user->shm_perm.cgid) ||
1143 __put_user(kern->shm_segsz, &user->shm_segsz) ||
1144 __put_user(kern->shm_atime, &user->shm_atime) ||
1145 __put_user(kern->shm_dtime, &user->shm_dtime) ||
1146 __put_user(kern->shm_ctime, &user->shm_ctime) ||
1147 __put_user(kern->shm_cpid, &user->shm_cpid) ||
1148 __put_user(kern->shm_lpid, &user->shm_lpid) ||
1149 __put_user(kern->shm_nattch, &user->shm_nattch))
1150 return -EFAULT;
1151 return 0;
1152}
1153
1154asmlinkage int sunos_shmsys(int op, u32 arg1, u32 arg2, u32 arg3)
1155{
1156 struct shmid_ds ksds;
1157 unsigned long raddr;
1158 mm_segment_t old_fs = get_fs();
1159 int rval;
1160
1161 switch(op) {
1162 case 0:
1163 /* do_shmat(): attach a shared memory area */
1164 rval = do_shmat((int)arg1,(char __user *)(unsigned long)arg2,(int)arg3,&raddr);
1165 if (!rval)
1166 rval = (int) raddr;
1167 break;
1168 case 1:
1169 /* sys_shmctl(): modify shared memory area attr. */
1170 if (!sunos_shmid_get((struct shmid_ds32 __user *)(unsigned long)arg3, &ksds)) {
1171 set_fs(KERNEL_DS);
1172 rval = sys_shmctl((int) arg1,(int) arg2,
1173 (struct shmid_ds __user *) &ksds);
1174 set_fs(old_fs);
1175 if (!rval)
1176 rval = sunos_shmid_put((struct shmid_ds32 __user *)(unsigned long)arg3,
1177 &ksds);
1178 } else
1179 rval = -EFAULT;
1180 break;
1181 case 2:
1182 /* sys_shmdt(): detach a shared memory area */
1183 rval = sys_shmdt((char __user *)(unsigned long)arg1);
1184 break;
1185 case 3:
1186 /* sys_shmget(): get a shared memory area */
1187 rval = sys_shmget((key_t)arg1,(int)arg2,(int)arg3);
1188 break;
1189 default:
1190 rval = -EINVAL;
1191 break;
1192 };
1193 return rval;
1194}
1195
1196extern asmlinkage long sparc32_open(const char __user * filename, int flags, int mode);
1197
1198asmlinkage int sunos_open(u32 fname, int flags, int mode)
1199{
1200 const char __user *filename = compat_ptr(fname);
1201
1202 return sparc32_open(filename, flags, mode);
1203}
1204
1205#define SUNOS_EWOULDBLOCK 35
1206
1207/* see the sunos man page read(2v) for an explanation
1208 of this garbage. We use O_NDELAY to mark
1209 file descriptors that have been set non-blocking
1210 using 4.2BSD style calls. (tridge) */
1211
1212static inline int check_nonblock(int ret, int fd)
1213{
1214 if (ret == -EAGAIN) {
1215 struct file * file = fget(fd);
1216 if (file) {
1217 if (file->f_flags & O_NDELAY)
1218 ret = -SUNOS_EWOULDBLOCK;
1219 fput(file);
1220 }
1221 }
1222 return ret;
1223}
1224
1225asmlinkage int sunos_read(unsigned int fd, char __user *buf, u32 count)
1226{
1227 int ret;
1228
1229 ret = check_nonblock(sys_read(fd, buf, count), fd);
1230 return ret;
1231}
1232
1233asmlinkage int sunos_readv(u32 fd, void __user *vector, s32 count)
1234{
1235 int ret;
1236
1237 ret = check_nonblock(compat_sys_readv(fd, vector, count), fd);
1238 return ret;
1239}
1240
1241asmlinkage int sunos_write(unsigned int fd, char __user *buf, u32 count)
1242{
1243 int ret;
1244
1245 ret = check_nonblock(sys_write(fd, buf, count), fd);
1246 return ret;
1247}
1248
1249asmlinkage int sunos_writev(u32 fd, void __user *vector, s32 count)
1250{
1251 int ret;
1252
1253 ret = check_nonblock(compat_sys_writev(fd, vector, count), fd);
1254 return ret;
1255}
1256
1257asmlinkage int sunos_recv(u32 __fd, void __user *ubuf, int size, unsigned flags)
1258{
1259 int ret, fd = (int) __fd;
1260
1261 ret = check_nonblock(sys_recv(fd, ubuf, size, flags), fd);
1262 return ret;
1263}
1264
1265asmlinkage int sunos_send(u32 __fd, void __user *buff, int len, unsigned flags)
1266{
1267 int ret, fd = (int) __fd;
1268
1269 ret = check_nonblock(sys_send(fd, buff, len, flags), fd);
1270 return ret;
1271}
1272
1273asmlinkage int sunos_accept(u32 __fd, struct sockaddr __user *sa, int __user *addrlen)
1274{
1275 int ret, fd = (int) __fd;
1276
1277 while (1) {
1278 ret = check_nonblock(sys_accept(fd, sa, addrlen), fd);
1279 if (ret != -ENETUNREACH && ret != -EHOSTUNREACH)
1280 break;
1281 }
1282 return ret;
1283}
1284
1285#define SUNOS_SV_INTERRUPT 2
1286
1287asmlinkage int sunos_sigaction (int sig,
1288 struct old_sigaction32 __user *act,
1289 struct old_sigaction32 __user *oact)
1290{
1291 struct k_sigaction new_ka, old_ka;
1292 int ret;
1293
1294 if (act) {
1295 compat_old_sigset_t mask;
1296 u32 u_handler;
1297
1298 if (get_user(u_handler, &act->sa_handler) ||
1299 __get_user(new_ka.sa.sa_flags, &act->sa_flags))
1300 return -EFAULT;
1301 new_ka.sa.sa_handler = compat_ptr(u_handler);
1302 __get_user(mask, &act->sa_mask);
1303 new_ka.sa.sa_restorer = NULL;
1304 new_ka.ka_restorer = NULL;
1305 siginitset(&new_ka.sa.sa_mask, mask);
1306 new_ka.sa.sa_flags ^= SUNOS_SV_INTERRUPT;
1307 }
1308
1309 ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
1310
1311 if (!ret && oact) {
1312 old_ka.sa.sa_flags ^= SUNOS_SV_INTERRUPT;
1313 if (put_user(ptr_to_compat(old_ka.sa.sa_handler), &oact->sa_handler) ||
1314 __put_user(old_ka.sa.sa_flags, &oact->sa_flags))
1315 return -EFAULT;
1316 __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
1317 }
1318
1319 return ret;
1320}
1321
1322asmlinkage int sunos_setsockopt(u32 __fd, u32 __level, u32 __optname,
1323 char __user *optval, u32 __optlen)
1324{
1325 int fd = (int) __fd;
1326 int level = (int) __level;
1327 int optname = (int) __optname;
1328 int optlen = (int) __optlen;
1329 int tr_opt = optname;
1330 int ret;
1331
1332 if (level == SOL_IP) {
1333 /* Multicast socketopts (ttl, membership) */
1334 if (tr_opt >=2 && tr_opt <= 6)
1335 tr_opt += 30;
1336 }
1337 ret = sys_setsockopt(fd, level, tr_opt,
1338 optval, optlen);
1339 return ret;
1340}
1341
1342asmlinkage int sunos_getsockopt(u32 __fd, u32 __level, u32 __optname,
1343 char __user *optval, int __user *optlen)
1344{
1345 int fd = (int) __fd;
1346 int level = (int) __level;
1347 int optname = (int) __optname;
1348 int tr_opt = optname;
1349 int ret;
1350
1351 if (level == SOL_IP) {
1352 /* Multicast socketopts (ttl, membership) */
1353 if (tr_opt >=2 && tr_opt <= 6)
1354 tr_opt += 30;
1355 }
1356 ret = compat_sys_getsockopt(fd, level, tr_opt,
1357 optval, optlen);
1358 return ret;
1359}
diff --git a/arch/sparc64/kernel/systbls.S b/arch/sparc64/kernel/systbls.S
index 6b9b718e24af..a4fef2ba1ae1 100644
--- a/arch/sparc64/kernel/systbls.S
+++ b/arch/sparc64/kernel/systbls.S
@@ -155,125 +155,3 @@ sys_call_table:
155 .word sys_set_mempolicy, sys_kexec_load, sys_move_pages, sys_getcpu, sys_epoll_pwait 155 .word sys_set_mempolicy, sys_kexec_load, sys_move_pages, sys_getcpu, sys_epoll_pwait
156/*310*/ .word sys_utimensat, sys_signalfd, sys_timerfd_create, sys_eventfd, sys_fallocate 156/*310*/ .word sys_utimensat, sys_signalfd, sys_timerfd_create, sys_eventfd, sys_fallocate
157 .word sys_timerfd_settime, sys_timerfd_gettime 157 .word sys_timerfd_settime, sys_timerfd_gettime
158
159#if defined(CONFIG_SUNOS_EMUL) || defined(CONFIG_SOLARIS_EMUL) || \
160 defined(CONFIG_SOLARIS_EMUL_MODULE)
161 /* Now the 32-bit SunOS syscall table. */
162
163 .align 4
164 .globl sunos_sys_table
165sunos_sys_table:
166/*0*/ .word sunos_indir, sys32_exit, sys_fork
167 .word sunos_read, sunos_write, sunos_open
168 .word sys_close, sunos_wait4, sys_creat
169 .word sys_link, sys_unlink, sunos_execv
170 .word sys_chdir, sunos_nosys, sys32_mknod
171 .word sys_chmod, sys32_lchown16, sunos_brk
172 .word sunos_nosys, sys32_lseek, sunos_getpid
173 .word sunos_nosys, sunos_nosys, sunos_nosys
174 .word sunos_getuid, sunos_nosys, sys_ptrace
175 .word sunos_nosys, sunos_nosys, sunos_nosys
176 .word sunos_nosys, sunos_nosys, sunos_nosys
177 .word sys_access, sunos_nosys, sunos_nosys
178 .word sys_sync, sys_kill, compat_sys_newstat
179 .word sunos_nosys, compat_sys_newlstat, sys_dup
180 .word sys_pipe, sunos_nosys, sunos_nosys
181 .word sunos_nosys, sunos_nosys, sunos_getgid
182 .word sunos_nosys, sunos_nosys
183/*50*/ .word sunos_nosys, sys_acct, sunos_nosys
184 .word sunos_mctl, sunos_ioctl, sys_reboot
185 .word sunos_nosys, sys_symlink, sys_readlink
186 .word sys32_execve, sys_umask, sys_chroot
187 .word compat_sys_newfstat, sunos_nosys, sys_getpagesize
188 .word sys_msync, sys_vfork, sunos_nosys
189 .word sunos_nosys, sunos_sbrk, sunos_sstk
190 .word sunos_mmap, sunos_vadvise, sys_munmap
191 .word sys_mprotect, sys_madvise, sys_vhangup
192 .word sunos_nosys, sys_mincore, sys32_getgroups16
193 .word sys32_setgroups16, sys_getpgrp, sunos_setpgrp
194 .word compat_sys_setitimer, sunos_nosys, sys_swapon
195 .word compat_sys_getitimer, sys_gethostname, sys_sethostname
196 .word sunos_getdtablesize, sys_dup2, sunos_nop
197 .word compat_sys_fcntl, sunos_select, sunos_nop
198 .word sys_fsync, sys32_setpriority, sys32_socket
199 .word sys32_connect, sunos_accept
200/*100*/ .word sys_getpriority, sunos_send, sunos_recv
201 .word sunos_nosys, sys32_bind, sunos_setsockopt
202 .word sys32_listen, sunos_nosys, sunos_sigaction
203 .word sunos_sigblock, sunos_sigsetmask, sys_sigpause
204 .word sys32_sigstack, sys32_recvmsg, sys32_sendmsg
205 .word sunos_nosys, sys32_gettimeofday, compat_sys_getrusage
206 .word sunos_getsockopt, sunos_nosys, sunos_readv
207 .word sunos_writev, sys32_settimeofday, sys32_fchown16
208 .word sys_fchmod, sys32_recvfrom, sys32_setreuid16
209 .word sys32_setregid16, sys_rename, sys_truncate
210 .word sys_ftruncate, sys_flock, sunos_nosys
211 .word sys32_sendto, sys32_shutdown, sys32_socketpair
212 .word sys_mkdir, sys_rmdir, sys32_utimes
213 .word sys32_sigreturn, sunos_nosys, sys32_getpeername
214 .word sunos_gethostid, sunos_nosys, compat_sys_getrlimit
215 .word compat_sys_setrlimit, sunos_killpg, sunos_nosys
216 .word sunos_nosys, sunos_nosys
217/*150*/ .word sys32_getsockname, sunos_nosys, sunos_nosys
218 .word sys_poll, sunos_nosys, sunos_nosys
219 .word sunos_getdirentries, compat_sys_statfs, compat_sys_fstatfs
220 .word sys_oldumount, sunos_nosys, sunos_nosys
221 .word sys_getdomainname, sys_setdomainname
222 .word sunos_nosys, sys_quotactl, sunos_nosys
223 .word sunos_nosys, sys_ustat, sunos_semsys
224 .word sunos_nosys, sunos_shmsys, sunos_audit
225 .word sunos_nosys, sunos_getdents, sys_setsid
226 .word sys_fchdir, sunos_nosys, sunos_nosys
227 .word sunos_nosys, sunos_nosys, sunos_nosys
228 .word sunos_nosys, compat_sys_sigpending, sunos_nosys
229 .word sys_setpgid, sunos_pathconf, sunos_fpathconf
230 .word sunos_sysconf, sunos_uname, sunos_nosys
231 .word sunos_nosys, sunos_nosys, sunos_nosys
232 .word sunos_nosys, sunos_nosys, sunos_nosys
233 .word sunos_nosys, sunos_nosys, sunos_nosys
234/*200*/ .word sunos_nosys, sunos_nosys, sunos_nosys
235 .word sunos_nosys, sunos_nosys, sunos_nosys
236 .word sunos_nosys, sunos_nosys, sunos_nosys
237 .word sunos_nosys, sunos_nosys, sunos_nosys
238 .word sunos_nosys, sunos_nosys, sunos_nosys
239 .word sunos_nosys, sunos_nosys, sunos_nosys
240 .word sunos_nosys, sunos_nosys, sunos_nosys
241 .word sunos_nosys, sunos_nosys, sunos_nosys
242 .word sunos_nosys, sunos_nosys, sunos_nosys
243 .word sunos_nosys, sunos_nosys, sunos_nosys
244 .word sunos_nosys, sunos_nosys, sunos_nosys
245 .word sunos_nosys, sunos_nosys, sunos_nosys
246 .word sunos_nosys, sunos_nosys, sunos_nosys
247 .word sunos_nosys, sunos_nosys, sunos_nosys
248 .word sunos_nosys, sunos_nosys, sunos_nosys
249 .word sunos_nosys, sunos_nosys, sunos_nosys
250 .word sunos_nosys, sunos_nosys
251/*250*/ .word sunos_nosys, sunos_nosys, sunos_nosys
252 .word sunos_nosys, sunos_nosys, sunos_nosys
253 .word sunos_nosys, sunos_nosys, sunos_nosys
254 .word sunos_nosys
255/*260*/ .word sunos_nosys, sunos_nosys, sunos_nosys
256 .word sunos_nosys, sunos_nosys, sunos_nosys
257 .word sunos_nosys, sunos_nosys, sunos_nosys
258 .word sunos_nosys
259/*270*/ .word sunos_nosys, sunos_nosys, sunos_nosys
260 .word sunos_nosys, sunos_nosys, sunos_nosys
261 .word sunos_nosys, sunos_nosys, sunos_nosys
262 .word sunos_nosys
263/*280*/ .word sunos_nosys, sunos_nosys, sunos_nosys
264 .word sunos_nosys, sunos_nosys, sunos_nosys
265 .word sunos_nosys, sunos_nosys, sunos_nosys
266 .word sunos_nosys
267/*290*/ .word sunos_nosys, sunos_nosys, sunos_nosys
268 .word sunos_nosys, sunos_nosys, sunos_nosys
269 .word sunos_nosys, sunos_nosys, sunos_nosys
270 .word sunos_nosys
271/*300*/ .word sunos_nosys, sunos_nosys, sunos_nosys
272 .word sunos_nosys, sunos_nosys, sunos_nosys
273 .word sunos_nosys, sunos_nosys, sunos_nosys
274 .word sunos_nosys
275/*310*/ .word sunos_nosys, sunos_nosys, sunos_nosys
276 .word sunos_nosys, sunos_nosys, sunos_nosys
277 .word sunos_nosys
278
279#endif
diff --git a/arch/sparc64/kernel/systbls.h b/arch/sparc64/kernel/systbls.h
index 8a0d20a35d0c..bc9f5dac4069 100644
--- a/arch/sparc64/kernel/systbls.h
+++ b/arch/sparc64/kernel/systbls.h
@@ -27,8 +27,6 @@ extern asmlinkage unsigned long sys64_mremap(unsigned long addr,
27 unsigned long new_addr); 27 unsigned long new_addr);
28extern asmlinkage unsigned long c_sys_nis_syscall(struct pt_regs *regs); 28extern asmlinkage unsigned long c_sys_nis_syscall(struct pt_regs *regs);
29extern asmlinkage long sys_getdomainname(char __user *name, int len); 29extern asmlinkage long sys_getdomainname(char __user *name, int len);
30extern asmlinkage long solaris_syscall(struct pt_regs *regs);
31extern asmlinkage long sunos_syscall(struct pt_regs *regs);
32extern asmlinkage long sys_utrap_install(utrap_entry_t type, 30extern asmlinkage long sys_utrap_install(utrap_entry_t type,
33 utrap_handler_t new_p, 31 utrap_handler_t new_p,
34 utrap_handler_t new_d, 32 utrap_handler_t new_d,
diff --git a/arch/sparc64/kernel/ttable.S b/arch/sparc64/kernel/ttable.S
index 7575aa371da8..b0de4c00b11a 100644
--- a/arch/sparc64/kernel/ttable.S
+++ b/arch/sparc64/kernel/ttable.S
@@ -117,16 +117,13 @@ tl0_f4o: FILL_4_OTHER
117tl0_f5o: FILL_5_OTHER 117tl0_f5o: FILL_5_OTHER
118tl0_f6o: FILL_6_OTHER 118tl0_f6o: FILL_6_OTHER
119tl0_f7o: FILL_7_OTHER 119tl0_f7o: FILL_7_OTHER
120tl0_sunos: SUNOS_SYSCALL_TRAP 120tl0_resv100: BTRAP(0x100)
121tl0_bkpt: BREAKPOINT_TRAP 121tl0_bkpt: BREAKPOINT_TRAP
122tl0_divz: TRAP(do_div0) 122tl0_divz: TRAP(do_div0)
123tl0_flushw: FLUSH_WINDOW_TRAP 123tl0_flushw: FLUSH_WINDOW_TRAP
124tl0_resv104: BTRAP(0x104) BTRAP(0x105) BTRAP(0x106) BTRAP(0x107) 124tl0_resv104: BTRAP(0x104) BTRAP(0x105) BTRAP(0x106) BTRAP(0x107) BTRAP(0x108)
125 .globl tl0_solaris 125tl0_resv109: BTRAP(0x109) BTRAP(0x10a) BTRAP(0x10b) BTRAP(0x10c) BTRAP(0x10d)
126tl0_solaris: SOLARIS_SYSCALL_TRAP 126tl0_resv10e: BTRAP(0x10e) BTRAP(0x10f)
127tl0_resv109: BTRAP(0x109)
128tl0_resv10a: BTRAP(0x10a) BTRAP(0x10b) BTRAP(0x10c) BTRAP(0x10d) BTRAP(0x10e)
129tl0_resv10f: BTRAP(0x10f)
130tl0_linux32: LINUX_32BIT_SYSCALL_TRAP 127tl0_linux32: LINUX_32BIT_SYSCALL_TRAP
131tl0_oldlinux64: LINUX_64BIT_SYSCALL_TRAP 128tl0_oldlinux64: LINUX_64BIT_SYSCALL_TRAP
132tl0_resv112: TRAP_UTRAP(UT_TRAP_INSTRUCTION_18,0x112) TRAP_UTRAP(UT_TRAP_INSTRUCTION_19,0x113) 129tl0_resv112: TRAP_UTRAP(UT_TRAP_INSTRUCTION_18,0x112) TRAP_UTRAP(UT_TRAP_INSTRUCTION_19,0x113)
@@ -139,8 +136,7 @@ tl0_resv11e: TRAP_UTRAP(UT_TRAP_INSTRUCTION_30,0x11e) TRAP_UTRAP(UT_TRAP_INSTRUC
139tl0_getcc: GETCC_TRAP 136tl0_getcc: GETCC_TRAP
140tl0_setcc: SETCC_TRAP 137tl0_setcc: SETCC_TRAP
141tl0_getpsr: TRAP(do_getpsr) 138tl0_getpsr: TRAP(do_getpsr)
142tl0_resv123: BTRAP(0x123) BTRAP(0x124) BTRAP(0x125) BTRAP(0x126) 139tl0_resv123: BTRAP(0x123) BTRAP(0x124) BTRAP(0x125) BTRAP(0x126) BTRAP(0x127)
143tl0_solindir: INDIRECT_SOLARIS_SYSCALL(156)
144tl0_resv128: BTRAP(0x128) BTRAP(0x129) BTRAP(0x12a) BTRAP(0x12b) BTRAP(0x12c) 140tl0_resv128: BTRAP(0x128) BTRAP(0x129) BTRAP(0x12a) BTRAP(0x12b) BTRAP(0x12c)
145tl0_resv12d: BTRAP(0x12d) BTRAP(0x12e) BTRAP(0x12f) BTRAP(0x130) BTRAP(0x131) 141tl0_resv12d: BTRAP(0x12d) BTRAP(0x12e) BTRAP(0x12f) BTRAP(0x130) BTRAP(0x131)
146tl0_resv132: BTRAP(0x132) BTRAP(0x133) BTRAP(0x134) BTRAP(0x135) BTRAP(0x136) 142tl0_resv132: BTRAP(0x132) BTRAP(0x133) BTRAP(0x134) BTRAP(0x135) BTRAP(0x136)
diff --git a/arch/sparc64/solaris/Makefile b/arch/sparc64/solaris/Makefile
deleted file mode 100644
index 8c8663033bfb..000000000000
--- a/arch/sparc64/solaris/Makefile
+++ /dev/null
@@ -1,10 +0,0 @@
1#
2# Makefile for the Solaris binary emulation.
3#
4
5EXTRA_AFLAGS := -ansi
6
7solaris-objs := entry64.o fs.o misc.o signal.o systbl.o socket.o \
8 ioctl.o ipc.o socksys.o timod.o
9
10obj-$(CONFIG_SOLARIS_EMUL) += solaris.o
diff --git a/arch/sparc64/solaris/conv.h b/arch/sparc64/solaris/conv.h
deleted file mode 100644
index 50e58232cf2b..000000000000
--- a/arch/sparc64/solaris/conv.h
+++ /dev/null
@@ -1,38 +0,0 @@
1/* $Id: conv.h,v 1.4 1998/08/15 20:42:51 davem Exp $
2 * conv.h: Utility macros for Solaris emulation
3 *
4 * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
5 */
6
7/* #define DEBUG_SOLARIS */
8#define DEBUG_SOLARIS_KMALLOC
9
10#ifndef __ASSEMBLY__
11
12#include <asm/unistd.h>
13
14/* Use this to get at 32-bit user passed pointers. */
15#define A(__x) \
16({ unsigned long __ret; \
17 __asm__ ("srl %0, 0, %0" \
18 : "=r" (__ret) \
19 : "0" (__x)); \
20 (void __user *)__ret; \
21})
22
23extern unsigned sys_call_table[];
24extern unsigned sys_call_table32[];
25extern unsigned sunos_sys_table[];
26
27#define SYS(name) ((long)sys_call_table[__NR_##name])
28#define SUNOS(x) ((long)sunos_sys_table[x])
29
30#ifdef DEBUG_SOLARIS
31#define SOLD(s) printk("%s,%d,%s(): %s\n",__FILE__,__LINE__,__func__,(s))
32#define SOLDD(s) printk("solaris: "); printk s
33#else
34#define SOLD(s)
35#define SOLDD(s)
36#endif
37
38#endif /* __ASSEMBLY__ */
diff --git a/arch/sparc64/solaris/entry64.S b/arch/sparc64/solaris/entry64.S
deleted file mode 100644
index f170324e8bf2..000000000000
--- a/arch/sparc64/solaris/entry64.S
+++ /dev/null
@@ -1,223 +0,0 @@
1/* $Id: entry64.S,v 1.7 2002/02/09 19:49:31 davem Exp $
2 * entry64.S: Solaris syscall emulation entry point.
3 *
4 * Copyright (C) 1996,1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
5 * Copyright (C) 1995,1997 David S. Miller (davem@caip.rutgers.edu)
6 * Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx)
7 */
8
9#include <linux/errno.h>
10
11#include <asm/head.h>
12#include <asm/asi.h>
13#include <asm/smp.h>
14#include <asm/ptrace.h>
15#include <asm/page.h>
16#include <asm/signal.h>
17#include <asm/pgtable.h>
18#include <asm/processor.h>
19#include <asm/thread_info.h>
20
21#include "conv.h"
22
23#define NR_SYSCALLS 256
24
25 .text
26solaris_syscall_trace:
27 add %sp, PTREGS_OFF, %o0
28 call syscall_trace
29 mov 0, %o1
30 srl %i0, 0, %o0
31 mov %i4, %o4
32 srl %i1, 0, %o1
33 mov %i5, %o5
34 andcc %l3, 1, %g0
35 be,pt %icc, 2f
36 srl %i2, 0, %o2
37 b,pt %xcc, 2f
38 add %sp, PTREGS_OFF, %o0
39
40solaris_sucks:
41/* Solaris is a big system which needs to be able to do all the things
42 * in Inf+1 different ways */
43 add %i6, 0x5c, %o0
44 mov %i0, %g1
45 mov %i1, %i0
46 mov %i2, %i1
47 srl %o0, 0, %o0
48 mov %i3, %i2
49 movrz %g1, 256, %g1 /* Ensure we don't loop forever */
50 mov %i4, %i3
51 mov %i5, %i4
52 ba,pt %xcc, solaris_sparc_syscall
53exen: lduwa [%o0] ASI_S, %i5
54
55exenf: ba,pt %xcc, solaris_sparc_syscall
56 clr %i5
57
58/* For shared binaries, binfmt_elf32 already sets up personality
59 and exec_domain. This is to handle static binaries as well */
60solaris_reg:
61 call solaris_register
62 nop
63 ba,pt %xcc, 1f
64 mov %i4, %o4
65
66linux_syscall_for_solaris:
67 sethi %hi(sys_call_table32), %l6
68 or %l6, %lo(sys_call_table32), %l6
69 sll %l3, 2, %l4
70 ba,pt %xcc, 10f
71 lduw [%l6 + %l4], %l3
72
73 /* Solaris system calls enter here... */
74 .align 32
75 .globl solaris_sparc_syscall, entry64_personality_patch
76solaris_sparc_syscall:
77entry64_personality_patch:
78 ldub [%g4 + 0x0], %l0
79 cmp %g1, 255
80 bg,pn %icc, solaris_unimplemented
81 srl %g1, 0, %g1
82 sethi %hi(solaris_sys_table), %l7
83 or %l7, %lo(solaris_sys_table), %l7
84 brz,pn %g1, solaris_sucks
85 mov %i4, %o4
86 sll %g1, 2, %l4
87 cmp %l0, 1
88 bne,pn %icc, solaris_reg
891: srl %i0, 0, %o0
90 lduw [%l7 + %l4], %l3
91 srl %i1, 0, %o1
92 ldx [%g6 + TI_FLAGS], %l5
93 cmp %l3, NR_SYSCALLS
94 bleu,a,pn %xcc, linux_syscall_for_solaris
95 nop
96 andcc %l3, 1, %g0
97 bne,a,pn %icc, 10f
98 add %sp, PTREGS_OFF, %o0
9910: srl %i2, 0, %o2
100 mov %i5, %o5
101 andn %l3, 3, %l7
102 andcc %l5, _TIF_SYSCALL_TRACE, %g0
103 bne,pn %icc, solaris_syscall_trace
104 mov %i0, %l5
1052: call %l7
106 srl %i3, 0, %o3
107ret_from_solaris:
108 stx %o0, [%sp + PTREGS_OFF + PT_V9_I0]
109 ldx [%g6 + TI_FLAGS], %l6
110 sra %o0, 0, %o0
111 mov %ulo(TSTATE_XCARRY | TSTATE_ICARRY), %g2
112 ldx [%sp + PTREGS_OFF + PT_V9_TSTATE], %g3
113 cmp %o0, -ERESTART_RESTARTBLOCK
114 sllx %g2, 32, %g2
115 bgeu,pn %xcc, 1f
116 andcc %l6, _TIF_SYSCALL_TRACE, %l6
117
118 /* System call success, clear Carry condition code. */
119 andn %g3, %g2, %g3
120 stx %g3, [%sp + PTREGS_OFF + PT_V9_TSTATE]
121 bne,pn %icc, solaris_syscall_trace2
122 ldx [%sp + PTREGS_OFF + PT_V9_TNPC], %l1
123 andcc %l1, 1, %g0
124 bne,pn %icc, 2f
125 clr %l6
126 add %l1, 0x4, %l2
127 stx %l1, [%sp + PTREGS_OFF + PT_V9_TPC] ! pc = npc
128 call rtrap
129 stx %l2, [%sp + PTREGS_OFF + PT_V9_TNPC] !npc = npc+4
130
131 /* When tnpc & 1, this comes from setcontext and we don't want to advance pc */
1322: andn %l1, 3, %l1
133 call rtrap
134 stx %l1, [%sp + PTREGS_OFF + PT_V9_TNPC] !npc = npc&~3
135
1361:
137 /* System call failure, set Carry condition code.
138 * Also, get abs(errno) to return to the process.
139 */
140 sub %g0, %o0, %o0
141 or %g3, %g2, %g3
142 cmp %o0, ERANGE /* 0-ERANGE are identity mapped */
143 bleu,pt %icc, 1f
144 cmp %o0, EMEDIUMTYPE
145 bgu,pn %icc, 1f
146 sethi %hi(solaris_err_table), %l6
147 sll %o0, 2, %o0
148 or %l6, %lo(solaris_err_table), %l6
149 ldsw [%l6 + %o0], %o0
1501: stx %o0, [%sp + PTREGS_OFF + PT_V9_I0]
151 mov 1, %l6
152 stx %g3, [%sp + PTREGS_OFF + PT_V9_TSTATE]
153 bne,pn %icc, solaris_syscall_trace2
154 ldx [%sp + PTREGS_OFF + PT_V9_TNPC], %l1
155 andcc %l1, 1, %g0
156 bne,pn %icc, 2b
157 add %l1, 0x4, %l2
158 stx %l1, [%sp + PTREGS_OFF + PT_V9_TPC] ! pc = npc
159 call rtrap
160 stx %l2, [%sp + PTREGS_OFF + PT_V9_TNPC] !npc = npc+4
161
162solaris_syscall_trace2:
163 add %sp, PTREGS_OFF, %o0
164 call syscall_trace
165 mov 1, %o1
166 add %l1, 0x4, %l2 /* npc = npc+4 */
167 andcc %l1, 1, %g0
168 bne,pn %icc, 2b
169 nop
170 stx %l1, [%sp + PTREGS_OFF + PT_V9_TPC]
171 call rtrap
172 stx %l2, [%sp + PTREGS_OFF + PT_V9_TNPC]
173
174 /* This one is tricky, so that's why we do it in assembly */
175 .globl solaris_sigsuspend
176solaris_sigsuspend:
177 call do_sol_sigsuspend
178 nop
179 brlz,pn %o0, ret_from_solaris
180 nop
181 call sys_sigsuspend
182 stx %o0, [%sp + PTREGS_OFF + PT_V9_I0]
183 b,pt %xcc, ret_from_solaris
184 nop
185
186 .globl solaris_getpid
187solaris_getpid:
188 call sys_getppid
189 nop
190 call sys_getpid
191 stx %o0, [%sp + PTREGS_OFF + PT_V9_I1]
192 b,pt %xcc, ret_from_solaris
193 nop
194
195 .globl solaris_getuid
196solaris_getuid:
197 call sys_geteuid
198 nop
199 call sys_getuid
200 stx %o1, [%sp + PTREGS_OFF + PT_V9_I1]
201 b,pt %xcc, ret_from_solaris
202 nop
203
204 .globl solaris_getgid
205solaris_getgid:
206 call sys_getegid
207 nop
208 call sys_getgid
209 stx %o1, [%sp + PTREGS_OFF + PT_V9_I1]
210 b,pt %xcc, ret_from_solaris
211 nop
212
213 .globl solaris_unimplemented
214solaris_unimplemented:
215 call do_sol_unimplemented
216 add %sp, PTREGS_OFF, %o0
217 ba,pt %xcc, ret_from_solaris
218 nop
219
220 .section __ex_table,"a"
221 .align 4
222 .word exen, exenf
223
diff --git a/arch/sparc64/solaris/fs.c b/arch/sparc64/solaris/fs.c
deleted file mode 100644
index 7d035f0d3ae1..000000000000
--- a/arch/sparc64/solaris/fs.c
+++ /dev/null
@@ -1,745 +0,0 @@
1/* $Id: fs.c,v 1.27 2002/02/08 03:57:14 davem Exp $
2 * fs.c: fs related syscall emulation for Solaris
3 *
4 * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
5 *
6 * 1999-08-19 Implemented solaris F_FREESP (truncate)
7 * fcntl, by Jason Rappleye (rappleye@ccr.buffalo.edu)
8 */
9
10#include <linux/types.h>
11#include <linux/sched.h>
12#include <linux/slab.h>
13#include <linux/capability.h>
14#include <linux/fs.h>
15#include <linux/namei.h>
16#include <linux/mm.h>
17#include <linux/file.h>
18#include <linux/stat.h>
19#include <linux/smp_lock.h>
20#include <linux/limits.h>
21#include <linux/resource.h>
22#include <linux/quotaops.h>
23#include <linux/mount.h>
24#include <linux/vfs.h>
25
26#include <asm/uaccess.h>
27#include <asm/string.h>
28#include <asm/ptrace.h>
29
30#include "conv.h"
31
32#define R3_VERSION 1
33#define R4_VERSION 2
34
35typedef struct {
36 s32 tv_sec;
37 s32 tv_nsec;
38} timestruct_t;
39
40struct sol_stat {
41 u32 st_dev;
42 s32 st_pad1[3]; /* network id */
43 u32 st_ino;
44 u32 st_mode;
45 u32 st_nlink;
46 u32 st_uid;
47 u32 st_gid;
48 u32 st_rdev;
49 s32 st_pad2[2];
50 s32 st_size;
51 s32 st_pad3; /* st_size, off_t expansion */
52 timestruct_t st_atime;
53 timestruct_t st_mtime;
54 timestruct_t st_ctime;
55 s32 st_blksize;
56 s32 st_blocks;
57 char st_fstype[16];
58 s32 st_pad4[8]; /* expansion area */
59};
60
61struct sol_stat64 {
62 u32 st_dev;
63 s32 st_pad1[3]; /* network id */
64 u64 st_ino;
65 u32 st_mode;
66 u32 st_nlink;
67 u32 st_uid;
68 u32 st_gid;
69 u32 st_rdev;
70 s32 st_pad2[2];
71 s64 st_size;
72 timestruct_t st_atime;
73 timestruct_t st_mtime;
74 timestruct_t st_ctime;
75 s64 st_blksize;
76 s32 st_blocks;
77 char st_fstype[16];
78 s32 st_pad4[4]; /* expansion area */
79};
80
81#define UFSMAGIC (((unsigned)'u'<<24)||((unsigned)'f'<<16)||((unsigned)'s'<<8))
82
83static inline int putstat(struct sol_stat __user *ubuf, struct kstat *kbuf)
84{
85 u32 ino;
86
87 if (kbuf->size > MAX_NON_LFS ||
88 !sysv_valid_dev(kbuf->dev) ||
89 !sysv_valid_dev(kbuf->rdev))
90 return -EOVERFLOW;
91 ino = kbuf->ino;
92 if (sizeof(ino) < sizeof(kbuf->ino) && ino != kbuf->ino)
93 return -EOVERFLOW;
94 if (put_user (sysv_encode_dev(kbuf->dev), &ubuf->st_dev) ||
95 __put_user (ino, &ubuf->st_ino) ||
96 __put_user (kbuf->mode, &ubuf->st_mode) ||
97 __put_user (kbuf->nlink, &ubuf->st_nlink) ||
98 __put_user (kbuf->uid, &ubuf->st_uid) ||
99 __put_user (kbuf->gid, &ubuf->st_gid) ||
100 __put_user (sysv_encode_dev(kbuf->rdev), &ubuf->st_rdev) ||
101 __put_user (kbuf->size, &ubuf->st_size) ||
102 __put_user (kbuf->atime.tv_sec, &ubuf->st_atime.tv_sec) ||
103 __put_user (kbuf->atime.tv_nsec, &ubuf->st_atime.tv_nsec) ||
104 __put_user (kbuf->mtime.tv_sec, &ubuf->st_mtime.tv_sec) ||
105 __put_user (kbuf->mtime.tv_nsec, &ubuf->st_mtime.tv_nsec) ||
106 __put_user (kbuf->ctime.tv_sec, &ubuf->st_ctime.tv_sec) ||
107 __put_user (kbuf->ctime.tv_nsec, &ubuf->st_ctime.tv_nsec) ||
108 __put_user (kbuf->blksize, &ubuf->st_blksize) ||
109 __put_user (kbuf->blocks, &ubuf->st_blocks) ||
110 __put_user (UFSMAGIC, (unsigned __user *)ubuf->st_fstype))
111 return -EFAULT;
112 return 0;
113}
114
115static inline int putstat64(struct sol_stat64 __user *ubuf, struct kstat *kbuf)
116{
117 if (!sysv_valid_dev(kbuf->dev) || !sysv_valid_dev(kbuf->rdev))
118 return -EOVERFLOW;
119 if (put_user (sysv_encode_dev(kbuf->dev), &ubuf->st_dev) ||
120 __put_user (kbuf->ino, &ubuf->st_ino) ||
121 __put_user (kbuf->mode, &ubuf->st_mode) ||
122 __put_user (kbuf->nlink, &ubuf->st_nlink) ||
123 __put_user (kbuf->uid, &ubuf->st_uid) ||
124 __put_user (kbuf->gid, &ubuf->st_gid) ||
125 __put_user (sysv_encode_dev(kbuf->rdev), &ubuf->st_rdev) ||
126 __put_user (kbuf->size, &ubuf->st_size) ||
127 __put_user (kbuf->atime.tv_sec, &ubuf->st_atime.tv_sec) ||
128 __put_user (kbuf->atime.tv_nsec, &ubuf->st_atime.tv_nsec) ||
129 __put_user (kbuf->mtime.tv_sec, &ubuf->st_mtime.tv_sec) ||
130 __put_user (kbuf->mtime.tv_nsec, &ubuf->st_mtime.tv_nsec) ||
131 __put_user (kbuf->ctime.tv_sec, &ubuf->st_ctime.tv_sec) ||
132 __put_user (kbuf->ctime.tv_nsec, &ubuf->st_ctime.tv_nsec) ||
133 __put_user (kbuf->blksize, &ubuf->st_blksize) ||
134 __put_user (kbuf->blocks, &ubuf->st_blocks) ||
135 __put_user (UFSMAGIC, (unsigned __user *)ubuf->st_fstype))
136 return -EFAULT;
137 return 0;
138}
139
140asmlinkage int solaris_stat(u32 filename, u32 statbuf)
141{
142 struct kstat s;
143 int ret = vfs_stat(A(filename), &s);
144 if (!ret)
145 return putstat(A(statbuf), &s);
146 return ret;
147}
148
149asmlinkage int solaris_xstat(int vers, u32 filename, u32 statbuf)
150{
151 /* Solaris doesn't bother with looking at vers, so we do neither */
152 return solaris_stat(filename, statbuf);
153}
154
155asmlinkage int solaris_stat64(u32 filename, u32 statbuf)
156{
157 struct kstat s;
158 int ret = vfs_stat(A(filename), &s);
159 if (!ret)
160 return putstat64(A(statbuf), &s);
161 return ret;
162}
163
164asmlinkage int solaris_lstat(u32 filename, u32 statbuf)
165{
166 struct kstat s;
167 int ret = vfs_lstat(A(filename), &s);
168 if (!ret)
169 return putstat(A(statbuf), &s);
170 return ret;
171}
172
173asmlinkage int solaris_lxstat(int vers, u32 filename, u32 statbuf)
174{
175 return solaris_lstat(filename, statbuf);
176}
177
178asmlinkage int solaris_lstat64(u32 filename, u32 statbuf)
179{
180 struct kstat s;
181 int ret = vfs_lstat(A(filename), &s);
182 if (!ret)
183 return putstat64(A(statbuf), &s);
184 return ret;
185}
186
187asmlinkage int solaris_fstat(unsigned int fd, u32 statbuf)
188{
189 struct kstat s;
190 int ret = vfs_fstat(fd, &s);
191 if (!ret)
192 return putstat(A(statbuf), &s);
193 return ret;
194}
195
196asmlinkage int solaris_fxstat(int vers, u32 fd, u32 statbuf)
197{
198 return solaris_fstat(fd, statbuf);
199}
200
201asmlinkage int solaris_fstat64(unsigned int fd, u32 statbuf)
202{
203 struct kstat s;
204 int ret = vfs_fstat(fd, &s);
205 if (!ret)
206 return putstat64(A(statbuf), &s);
207 return ret;
208}
209
210asmlinkage int solaris_mknod(u32 path, u32 mode, s32 dev)
211{
212 int (*sys_mknod)(const char __user *,int,unsigned) =
213 (int (*)(const char __user *,int,unsigned))SYS(mknod);
214 int major = sysv_major(dev);
215 int minor = sysv_minor(dev);
216
217 /* minor is guaranteed to be OK for MKDEV, major might be not */
218 if (major > 0xfff)
219 return -EINVAL;
220 return sys_mknod(A(path), mode, new_encode_dev(MKDEV(major,minor)));
221}
222
223asmlinkage int solaris_xmknod(int vers, u32 path, u32 mode, s32 dev)
224{
225 return solaris_mknod(path, mode, dev);
226}
227
228asmlinkage int solaris_getdents64(unsigned int fd, void __user *dirent, unsigned int count)
229{
230 int (*sys_getdents)(unsigned int, void __user *, unsigned int) =
231 (int (*)(unsigned int, void __user *, unsigned int))SYS(getdents);
232
233 return sys_getdents(fd, dirent, count);
234}
235
236/* This statfs thingie probably will go in the near future, but... */
237
238struct sol_statfs {
239 short f_type;
240 s32 f_bsize;
241 s32 f_frsize;
242 s32 f_blocks;
243 s32 f_bfree;
244 u32 f_files;
245 u32 f_ffree;
246 char f_fname[6];
247 char f_fpack[6];
248};
249
250asmlinkage int solaris_statfs(u32 path, u32 buf, int len, int fstype)
251{
252 int ret;
253 struct statfs s;
254 mm_segment_t old_fs = get_fs();
255 int (*sys_statfs)(const char __user *,struct statfs __user *) =
256 (int (*)(const char __user *,struct statfs __user *))SYS(statfs);
257 struct sol_statfs __user *ss = A(buf);
258
259 if (len != sizeof(struct sol_statfs)) return -EINVAL;
260 if (!fstype) {
261 /* FIXME: mixing userland and kernel pointers */
262 set_fs (KERNEL_DS);
263 ret = sys_statfs(A(path), &s);
264 set_fs (old_fs);
265 if (!ret) {
266 if (put_user (s.f_type, &ss->f_type) ||
267 __put_user (s.f_bsize, &ss->f_bsize) ||
268 __put_user (0, &ss->f_frsize) ||
269 __put_user (s.f_blocks, &ss->f_blocks) ||
270 __put_user (s.f_bfree, &ss->f_bfree) ||
271 __put_user (s.f_files, &ss->f_files) ||
272 __put_user (s.f_ffree, &ss->f_ffree) ||
273 __clear_user (&ss->f_fname, 12))
274 return -EFAULT;
275 }
276 return ret;
277 }
278/* Linux can't stat unmounted filesystems so we
279 * simply lie and claim 100MB of 1GB is free. Sorry.
280 */
281 if (put_user (fstype, &ss->f_type) ||
282 __put_user (1024, &ss->f_bsize) ||
283 __put_user (0, &ss->f_frsize) ||
284 __put_user (1024*1024, &ss->f_blocks) ||
285 __put_user (100*1024, &ss->f_bfree) ||
286 __put_user (60000, &ss->f_files) ||
287 __put_user (50000, &ss->f_ffree) ||
288 __clear_user (&ss->f_fname, 12))
289 return -EFAULT;
290 return 0;
291}
292
293asmlinkage int solaris_fstatfs(u32 fd, u32 buf, int len, int fstype)
294{
295 int ret;
296 struct statfs s;
297 mm_segment_t old_fs = get_fs();
298 int (*sys_fstatfs)(unsigned,struct statfs __user *) =
299 (int (*)(unsigned,struct statfs __user *))SYS(fstatfs);
300 struct sol_statfs __user *ss = A(buf);
301
302 if (len != sizeof(struct sol_statfs)) return -EINVAL;
303 if (!fstype) {
304 set_fs (KERNEL_DS);
305 ret = sys_fstatfs(fd, &s);
306 set_fs (old_fs);
307 if (!ret) {
308 if (put_user (s.f_type, &ss->f_type) ||
309 __put_user (s.f_bsize, &ss->f_bsize) ||
310 __put_user (0, &ss->f_frsize) ||
311 __put_user (s.f_blocks, &ss->f_blocks) ||
312 __put_user (s.f_bfree, &ss->f_bfree) ||
313 __put_user (s.f_files, &ss->f_files) ||
314 __put_user (s.f_ffree, &ss->f_ffree) ||
315 __clear_user (&ss->f_fname, 12))
316 return -EFAULT;
317 }
318 return ret;
319 }
320 /* Otherwise fstatfs is the same as statfs */
321 return solaris_statfs(0, buf, len, fstype);
322}
323
324struct sol_statvfs {
325 u32 f_bsize;
326 u32 f_frsize;
327 u32 f_blocks;
328 u32 f_bfree;
329 u32 f_bavail;
330 u32 f_files;
331 u32 f_ffree;
332 u32 f_favail;
333 u32 f_fsid;
334 char f_basetype[16];
335 u32 f_flag;
336 u32 f_namemax;
337 char f_fstr[32];
338 u32 f_filler[16];
339};
340
341struct sol_statvfs64 {
342 u32 f_bsize;
343 u32 f_frsize;
344 u64 f_blocks;
345 u64 f_bfree;
346 u64 f_bavail;
347 u64 f_files;
348 u64 f_ffree;
349 u64 f_favail;
350 u32 f_fsid;
351 char f_basetype[16];
352 u32 f_flag;
353 u32 f_namemax;
354 char f_fstr[32];
355 u32 f_filler[16];
356};
357
358static int report_statvfs(struct vfsmount *mnt, struct inode *inode, u32 buf)
359{
360 struct kstatfs s;
361 int error;
362 struct sol_statvfs __user *ss = A(buf);
363
364 error = vfs_statfs(mnt->mnt_root, &s);
365 if (!error) {
366 const char *p = mnt->mnt_sb->s_type->name;
367 int i = 0;
368 int j = strlen (p);
369
370 if (j > 15) j = 15;
371 if (IS_RDONLY(inode)) i = 1;
372 if (mnt->mnt_flags & MNT_NOSUID) i |= 2;
373 if (!sysv_valid_dev(inode->i_sb->s_dev))
374 return -EOVERFLOW;
375 if (put_user (s.f_bsize, &ss->f_bsize) ||
376 __put_user (0, &ss->f_frsize) ||
377 __put_user (s.f_blocks, &ss->f_blocks) ||
378 __put_user (s.f_bfree, &ss->f_bfree) ||
379 __put_user (s.f_bavail, &ss->f_bavail) ||
380 __put_user (s.f_files, &ss->f_files) ||
381 __put_user (s.f_ffree, &ss->f_ffree) ||
382 __put_user (s.f_ffree, &ss->f_favail) ||
383 __put_user (sysv_encode_dev(inode->i_sb->s_dev), &ss->f_fsid) ||
384 __copy_to_user (ss->f_basetype,p,j) ||
385 __put_user (0, (char __user *)&ss->f_basetype[j]) ||
386 __put_user (s.f_namelen, &ss->f_namemax) ||
387 __put_user (i, &ss->f_flag) ||
388 __clear_user (&ss->f_fstr, 32))
389 return -EFAULT;
390 }
391 return error;
392}
393
394static int report_statvfs64(struct vfsmount *mnt, struct inode *inode, u32 buf)
395{
396 struct kstatfs s;
397 int error;
398 struct sol_statvfs64 __user *ss = A(buf);
399
400 error = vfs_statfs(mnt->mnt_root, &s);
401 if (!error) {
402 const char *p = mnt->mnt_sb->s_type->name;
403 int i = 0;
404 int j = strlen (p);
405
406 if (j > 15) j = 15;
407 if (IS_RDONLY(inode)) i = 1;
408 if (mnt->mnt_flags & MNT_NOSUID) i |= 2;
409 if (!sysv_valid_dev(inode->i_sb->s_dev))
410 return -EOVERFLOW;
411 if (put_user (s.f_bsize, &ss->f_bsize) ||
412 __put_user (0, &ss->f_frsize) ||
413 __put_user (s.f_blocks, &ss->f_blocks) ||
414 __put_user (s.f_bfree, &ss->f_bfree) ||
415 __put_user (s.f_bavail, &ss->f_bavail) ||
416 __put_user (s.f_files, &ss->f_files) ||
417 __put_user (s.f_ffree, &ss->f_ffree) ||
418 __put_user (s.f_ffree, &ss->f_favail) ||
419 __put_user (sysv_encode_dev(inode->i_sb->s_dev), &ss->f_fsid) ||
420 __copy_to_user (ss->f_basetype,p,j) ||
421 __put_user (0, (char __user *)&ss->f_basetype[j]) ||
422 __put_user (s.f_namelen, &ss->f_namemax) ||
423 __put_user (i, &ss->f_flag) ||
424 __clear_user (&ss->f_fstr, 32))
425 return -EFAULT;
426 }
427 return error;
428}
429
430asmlinkage int solaris_statvfs(u32 path, u32 buf)
431{
432 struct nameidata nd;
433 int error;
434
435 error = user_path_walk(A(path),&nd);
436 if (!error) {
437 struct inode *inode = nd.path.dentry->d_inode;
438 error = report_statvfs(nd.path.mnt, inode, buf);
439 path_put(&nd.path);
440 }
441 return error;
442}
443
444asmlinkage int solaris_fstatvfs(unsigned int fd, u32 buf)
445{
446 struct file * file;
447 int error;
448
449 error = -EBADF;
450 file = fget(fd);
451 if (file) {
452 error = report_statvfs(file->f_path.mnt, file->f_path.dentry->d_inode, buf);
453 fput(file);
454 }
455
456 return error;
457}
458
459asmlinkage int solaris_statvfs64(u32 path, u32 buf)
460{
461 struct nameidata nd;
462 int error;
463
464 lock_kernel();
465 error = user_path_walk(A(path), &nd);
466 if (!error) {
467 struct inode *inode = nd.path.dentry->d_inode;
468 error = report_statvfs64(nd.path.mnt, inode, buf);
469 path_put(&nd.path);
470 }
471 unlock_kernel();
472 return error;
473}
474
475asmlinkage int solaris_fstatvfs64(unsigned int fd, u32 buf)
476{
477 struct file * file;
478 int error;
479
480 error = -EBADF;
481 file = fget(fd);
482 if (file) {
483 lock_kernel();
484 error = report_statvfs64(file->f_path.mnt, file->f_path.dentry->d_inode, buf);
485 unlock_kernel();
486 fput(file);
487 }
488 return error;
489}
490
491extern asmlinkage long sparc32_open(const char * filename, int flags, int mode);
492
493asmlinkage int solaris_open(u32 fname, int flags, u32 mode)
494{
495 const char *filename = (const char *)(long)fname;
496 int fl = flags & 0xf;
497
498 /* Translate flags first. */
499 if (flags & 0x2000) fl |= O_LARGEFILE;
500 if (flags & 0x8050) fl |= O_SYNC;
501 if (flags & 0x80) fl |= O_NONBLOCK;
502 if (flags & 0x100) fl |= O_CREAT;
503 if (flags & 0x200) fl |= O_TRUNC;
504 if (flags & 0x400) fl |= O_EXCL;
505 if (flags & 0x800) fl |= O_NOCTTY;
506 flags = fl;
507
508 return sparc32_open(filename, flags, mode);
509}
510
511#define SOL_F_SETLK 6
512#define SOL_F_SETLKW 7
513#define SOL_F_FREESP 11
514#define SOL_F_ISSTREAM 13
515#define SOL_F_GETLK 14
516#define SOL_F_PRIV 15
517#define SOL_F_NPRIV 16
518#define SOL_F_QUOTACTL 17
519#define SOL_F_BLOCKS 18
520#define SOL_F_BLKSIZE 19
521#define SOL_F_GETOWN 23
522#define SOL_F_SETOWN 24
523
524struct sol_flock {
525 short l_type;
526 short l_whence;
527 u32 l_start;
528 u32 l_len;
529 s32 l_sysid;
530 s32 l_pid;
531 s32 l_pad[4];
532};
533
534asmlinkage int solaris_fcntl(unsigned fd, unsigned cmd, u32 arg)
535{
536 int (*sys_fcntl)(unsigned,unsigned,unsigned long) =
537 (int (*)(unsigned,unsigned,unsigned long))SYS(fcntl);
538 int ret, flags;
539
540 switch (cmd) {
541 case F_DUPFD:
542 case F_GETFD:
543 case F_SETFD: return sys_fcntl(fd, cmd, (unsigned long)arg);
544 case F_GETFL:
545 flags = sys_fcntl(fd, cmd, 0);
546 ret = flags & 0xf;
547 if (flags & O_SYNC) ret |= 0x8050;
548 if (flags & O_NONBLOCK) ret |= 0x80;
549 return ret;
550 case F_SETFL:
551 flags = arg & 0xf;
552 if (arg & 0x8050) flags |= O_SYNC;
553 if (arg & 0x80) flags |= O_NONBLOCK;
554 return sys_fcntl(fd, cmd, (long)flags);
555 case SOL_F_GETLK:
556 case SOL_F_SETLK:
557 case SOL_F_SETLKW:
558 {
559 struct flock f;
560 struct sol_flock __user *p = A(arg);
561 mm_segment_t old_fs = get_fs();
562
563 switch (cmd) {
564 case SOL_F_GETLK: cmd = F_GETLK; break;
565 case SOL_F_SETLK: cmd = F_SETLK; break;
566 case SOL_F_SETLKW: cmd = F_SETLKW; break;
567 }
568
569 if (get_user (f.l_type, &p->l_type) ||
570 __get_user (f.l_whence, &p->l_whence) ||
571 __get_user (f.l_start, &p->l_start) ||
572 __get_user (f.l_len, &p->l_len) ||
573 __get_user (f.l_pid, &p->l_sysid))
574 return -EFAULT;
575
576 set_fs(KERNEL_DS);
577 ret = sys_fcntl(fd, cmd, (unsigned long)&f);
578 set_fs(old_fs);
579
580 if (__put_user (f.l_type, &p->l_type) ||
581 __put_user (f.l_whence, &p->l_whence) ||
582 __put_user (f.l_start, &p->l_start) ||
583 __put_user (f.l_len, &p->l_len) ||
584 __put_user (f.l_pid, &p->l_pid) ||
585 __put_user (0, &p->l_sysid))
586 return -EFAULT;
587
588 return ret;
589 }
590 case SOL_F_FREESP:
591 {
592 int length;
593 int (*sys_newftruncate)(unsigned int, unsigned long)=
594 (int (*)(unsigned int, unsigned long))SYS(ftruncate);
595
596 if (get_user(length, &((struct sol_flock __user *)A(arg))->l_start))
597 return -EFAULT;
598
599 return sys_newftruncate(fd, length);
600 }
601 };
602 return -EINVAL;
603}
604
605asmlinkage int solaris_ulimit(int cmd, int val)
606{
607 switch (cmd) {
608 case 1: /* UL_GETFSIZE - in 512B chunks */
609 return current->signal->rlim[RLIMIT_FSIZE].rlim_cur >> 9;
610 case 2: /* UL_SETFSIZE */
611 if ((unsigned long)val > (LONG_MAX>>9)) return -ERANGE;
612 val <<= 9;
613 task_lock(current->group_leader);
614 if (val > current->signal->rlim[RLIMIT_FSIZE].rlim_max) {
615 if (!capable(CAP_SYS_RESOURCE)) {
616 task_unlock(current->group_leader);
617 return -EPERM;
618 }
619 current->signal->rlim[RLIMIT_FSIZE].rlim_max = val;
620 }
621 current->signal->rlim[RLIMIT_FSIZE].rlim_cur = val;
622 task_unlock(current->group_leader);
623 return 0;
624 case 3: /* UL_GMEMLIM */
625 return current->signal->rlim[RLIMIT_DATA].rlim_cur;
626 case 4: /* UL_GDESLIM */
627 return sysctl_nr_open;
628 }
629 return -EINVAL;
630}
631
632/* At least at the time I'm writing this, Linux doesn't have ACLs, so we
633 just fake this */
634asmlinkage int solaris_acl(u32 filename, int cmd, int nentries, u32 aclbufp)
635{
636 return -ENOSYS;
637}
638
639asmlinkage int solaris_facl(unsigned int fd, int cmd, int nentries, u32 aclbufp)
640{
641 return -ENOSYS;
642}
643
644asmlinkage int solaris_pread(unsigned int fd, char __user *buf, u32 count, u32 pos)
645{
646 ssize_t (*sys_pread64)(unsigned int, char __user *, size_t, loff_t) =
647 (ssize_t (*)(unsigned int, char __user *, size_t, loff_t))SYS(pread64);
648
649 return sys_pread64(fd, buf, count, (loff_t)pos);
650}
651
652asmlinkage int solaris_pwrite(unsigned int fd, char __user *buf, u32 count, u32 pos)
653{
654 ssize_t (*sys_pwrite64)(unsigned int, char __user *, size_t, loff_t) =
655 (ssize_t (*)(unsigned int, char __user *, size_t, loff_t))SYS(pwrite64);
656
657 return sys_pwrite64(fd, buf, count, (loff_t)pos);
658}
659
660/* POSIX.1 names */
661#define _PC_LINK_MAX 1
662#define _PC_MAX_CANON 2
663#define _PC_MAX_INPUT 3
664#define _PC_NAME_MAX 4
665#define _PC_PATH_MAX 5
666#define _PC_PIPE_BUF 6
667#define _PC_NO_TRUNC 7
668#define _PC_VDISABLE 8
669#define _PC_CHOWN_RESTRICTED 9
670/* POSIX.4 names */
671#define _PC_ASYNC_IO 10
672#define _PC_PRIO_IO 11
673#define _PC_SYNC_IO 12
674#define _PC_LAST 12
675
676/* This is not a real and complete implementation yet, just to keep
677 * the easy Solaris binaries happy.
678 */
679asmlinkage int solaris_fpathconf(int fd, int name)
680{
681 int ret;
682
683 switch(name) {
684 case _PC_LINK_MAX:
685 ret = LINK_MAX;
686 break;
687 case _PC_MAX_CANON:
688 ret = MAX_CANON;
689 break;
690 case _PC_MAX_INPUT:
691 ret = MAX_INPUT;
692 break;
693 case _PC_NAME_MAX:
694 ret = NAME_MAX;
695 break;
696 case _PC_PATH_MAX:
697 ret = PATH_MAX;
698 break;
699 case _PC_PIPE_BUF:
700 ret = PIPE_BUF;
701 break;
702 case _PC_CHOWN_RESTRICTED:
703 ret = 1;
704 break;
705 case _PC_NO_TRUNC:
706 case _PC_VDISABLE:
707 ret = 0;
708 break;
709 default:
710 ret = -EINVAL;
711 break;
712 }
713 return ret;
714}
715
716asmlinkage int solaris_pathconf(u32 path, int name)
717{
718 return solaris_fpathconf(0, name);
719}
720
721/* solaris_llseek returns long long - quite difficult */
722asmlinkage long solaris_llseek(struct pt_regs *regs, u32 off_hi, u32 off_lo, int whence)
723{
724 int (*sys_llseek)(unsigned int, unsigned long, unsigned long, loff_t __user *, unsigned int) =
725 (int (*)(unsigned int, unsigned long, unsigned long, loff_t __user *, unsigned int))SYS(_llseek);
726 int ret;
727 mm_segment_t old_fs = get_fs();
728 loff_t retval;
729
730 set_fs(KERNEL_DS);
731 ret = sys_llseek((unsigned int)regs->u_regs[UREG_I0], off_hi, off_lo, &retval, whence);
732 set_fs(old_fs);
733 if (ret < 0) return ret;
734 regs->u_regs[UREG_I1] = (u32)retval;
735 return (retval >> 32);
736}
737
738/* Have to mask out all but lower 3 bits */
739asmlinkage int solaris_access(u32 filename, long mode)
740{
741 int (*sys_access)(const char __user *, int) =
742 (int (*)(const char __user *, int))SYS(access);
743
744 return sys_access(A(filename), mode & 7);
745}
diff --git a/arch/sparc64/solaris/ioctl.c b/arch/sparc64/solaris/ioctl.c
deleted file mode 100644
index 8ad10a6d993b..000000000000
--- a/arch/sparc64/solaris/ioctl.c
+++ /dev/null
@@ -1,825 +0,0 @@
1/* $Id: ioctl.c,v 1.17 2002/02/08 03:57:14 davem Exp $
2 * ioctl.c: Solaris ioctl emulation.
3 *
4 * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
5 * Copyright (C) 1997,1998 Patrik Rak (prak3264@ss1000.ms.mff.cuni.cz)
6 *
7 * Streams & timod emulation based on code
8 * Copyright (C) 1995, 1996 Mike Jagdis (jaggy@purplet.demon.co.uk)
9 *
10 * 1999-08-19 Implemented solaris 'm' (mag tape) and
11 * 'O' (openprom) ioctls, by Jason Rappleye
12 * (rappleye@ccr.buffalo.edu)
13 */
14
15#include <linux/types.h>
16#include <linux/kernel.h>
17#include <linux/sched.h>
18#include <linux/smp.h>
19#include <linux/smp_lock.h>
20#include <linux/syscalls.h>
21#include <linux/ioctl.h>
22#include <linux/fs.h>
23#include <linux/file.h>
24#include <linux/netdevice.h>
25#include <linux/mtio.h>
26#include <linux/time.h>
27#include <linux/rcupdate.h>
28#include <linux/compat.h>
29
30#include <net/sock.h>
31#include <net/net_namespace.h>
32
33#include <asm/uaccess.h>
34#include <asm/termios.h>
35#include <asm/openpromio.h>
36
37#include "conv.h"
38#include "socksys.h"
39
40extern asmlinkage int compat_sys_ioctl(unsigned int fd, unsigned int cmd,
41 u32 arg);
42asmlinkage int solaris_ioctl(unsigned int fd, unsigned int cmd, u32 arg);
43
44extern int timod_putmsg(unsigned int fd, char __user *ctl_buf, int ctl_len,
45 char __user *data_buf, int data_len, int flags);
46extern int timod_getmsg(unsigned int fd, char __user *ctl_buf, int ctl_maxlen, int __user *ctl_len,
47 char __user *data_buf, int data_maxlen, int __user *data_len, int *flags);
48
49/* termio* stuff {{{ */
50
51struct solaris_termios {
52 u32 c_iflag;
53 u32 c_oflag;
54 u32 c_cflag;
55 u32 c_lflag;
56 u8 c_cc[19];
57};
58
59struct solaris_termio {
60 u16 c_iflag;
61 u16 c_oflag;
62 u16 c_cflag;
63 u16 c_lflag;
64 s8 c_line;
65 u8 c_cc[8];
66};
67
68struct solaris_termiox {
69 u16 x_hflag;
70 u16 x_cflag;
71 u16 x_rflag[5];
72 u16 x_sflag;
73};
74
75static u32 solaris_to_linux_cflag(u32 cflag)
76{
77 cflag &= 0x7fdff000;
78 if (cflag & 0x200000) {
79 int baud = cflag & 0xf;
80 cflag &= ~0x20000f;
81 switch (baud) {
82 case 0: baud = B57600; break;
83 case 1: baud = B76800; break;
84 case 2: baud = B115200; break;
85 case 3: baud = B153600; break;
86 case 4: baud = B230400; break;
87 case 5: baud = B307200; break;
88 case 6: baud = B460800; break;
89 }
90 cflag |= CBAUDEX | baud;
91 }
92 return cflag;
93}
94
95static u32 linux_to_solaris_cflag(u32 cflag)
96{
97 cflag &= ~(CMSPAR | CIBAUD);
98 if (cflag & CBAUDEX) {
99 int baud = cflag & CBAUD;
100 cflag &= ~CBAUD;
101 switch (baud) {
102 case B57600: baud = 0; break;
103 case B76800: baud = 1; break;
104 case B115200: baud = 2; break;
105 case B153600: baud = 3; break;
106 case B230400: baud = 4; break;
107 case B307200: baud = 5; break;
108 case B460800: baud = 6; break;
109 case B614400: baud = 7; break;
110 case B921600: baud = 8; break;
111#if 0
112 case B1843200: baud = 9; break;
113#endif
114 }
115 cflag |= 0x200000 | baud;
116 }
117 return cflag;
118}
119
120static inline int linux_to_solaris_termio(unsigned int fd, unsigned int cmd, u32 arg)
121{
122 struct solaris_termio __user *p = A(arg);
123 int ret;
124
125 ret = sys_ioctl(fd, cmd, (unsigned long)p);
126 if (!ret) {
127 u32 cflag;
128
129 if (__get_user (cflag, &p->c_cflag))
130 return -EFAULT;
131 cflag = linux_to_solaris_cflag(cflag);
132 if (__put_user (cflag, &p->c_cflag))
133 return -EFAULT;
134 }
135 return ret;
136}
137
138static int solaris_to_linux_termio(unsigned int fd, unsigned int cmd, u32 arg)
139{
140 int ret;
141 struct solaris_termio s;
142 mm_segment_t old_fs = get_fs();
143
144 if (copy_from_user (&s, (struct solaris_termio __user *)A(arg), sizeof(struct solaris_termio)))
145 return -EFAULT;
146 s.c_cflag = solaris_to_linux_cflag(s.c_cflag);
147 set_fs(KERNEL_DS);
148 ret = sys_ioctl(fd, cmd, (unsigned long)&s);
149 set_fs(old_fs);
150 return ret;
151}
152
153static inline int linux_to_solaris_termios(unsigned int fd, unsigned int cmd, u32 arg)
154{
155 int ret;
156 struct solaris_termios s;
157 mm_segment_t old_fs = get_fs();
158
159 set_fs(KERNEL_DS);
160 ret = sys_ioctl(fd, cmd, (unsigned long)&s);
161 set_fs(old_fs);
162 if (!ret) {
163 struct solaris_termios __user *p = A(arg);
164 if (put_user (s.c_iflag, &p->c_iflag) ||
165 __put_user (s.c_oflag, &p->c_oflag) ||
166 __put_user (linux_to_solaris_cflag(s.c_cflag), &p->c_cflag) ||
167 __put_user (s.c_lflag, &p->c_lflag) ||
168 __copy_to_user (p->c_cc, s.c_cc, 16) ||
169 __clear_user (p->c_cc + 16, 2))
170 return -EFAULT;
171 }
172 return ret;
173}
174
175static int solaris_to_linux_termios(unsigned int fd, unsigned int cmd, u32 arg)
176{
177 int ret;
178 struct solaris_termios s;
179 struct solaris_termios __user *p = A(arg);
180 mm_segment_t old_fs = get_fs();
181
182 set_fs(KERNEL_DS);
183 ret = sys_ioctl(fd, TCGETS, (unsigned long)&s);
184 set_fs(old_fs);
185 if (ret) return ret;
186 if (put_user (s.c_iflag, &p->c_iflag) ||
187 __put_user (s.c_oflag, &p->c_oflag) ||
188 __put_user (s.c_cflag, &p->c_cflag) ||
189 __put_user (s.c_lflag, &p->c_lflag) ||
190 __copy_from_user (s.c_cc, p->c_cc, 16))
191 return -EFAULT;
192 s.c_cflag = solaris_to_linux_cflag(s.c_cflag);
193 set_fs(KERNEL_DS);
194 ret = sys_ioctl(fd, cmd, (unsigned long)&s);
195 set_fs(old_fs);
196 return ret;
197}
198
199static inline int solaris_T(unsigned int fd, unsigned int cmd, u32 arg)
200{
201 switch (cmd & 0xff) {
202 case 1: /* TCGETA */
203 return linux_to_solaris_termio(fd, TCGETA, arg);
204 case 2: /* TCSETA */
205 return solaris_to_linux_termio(fd, TCSETA, arg);
206 case 3: /* TCSETAW */
207 return solaris_to_linux_termio(fd, TCSETAW, arg);
208 case 4: /* TCSETAF */
209 return solaris_to_linux_termio(fd, TCSETAF, arg);
210 case 5: /* TCSBRK */
211 return sys_ioctl(fd, TCSBRK, arg);
212 case 6: /* TCXONC */
213 return sys_ioctl(fd, TCXONC, arg);
214 case 7: /* TCFLSH */
215 return sys_ioctl(fd, TCFLSH, arg);
216 case 13: /* TCGETS */
217 return linux_to_solaris_termios(fd, TCGETS, arg);
218 case 14: /* TCSETS */
219 return solaris_to_linux_termios(fd, TCSETS, arg);
220 case 15: /* TCSETSW */
221 return solaris_to_linux_termios(fd, TCSETSW, arg);
222 case 16: /* TCSETSF */
223 return solaris_to_linux_termios(fd, TCSETSF, arg);
224 case 103: /* TIOCSWINSZ */
225 return sys_ioctl(fd, TIOCSWINSZ, arg);
226 case 104: /* TIOCGWINSZ */
227 return sys_ioctl(fd, TIOCGWINSZ, arg);
228 }
229 return -ENOSYS;
230}
231
232static inline int solaris_t(unsigned int fd, unsigned int cmd, u32 arg)
233{
234 switch (cmd & 0xff) {
235 case 20: /* TIOCGPGRP */
236 return sys_ioctl(fd, TIOCGPGRP, arg);
237 case 21: /* TIOCSPGRP */
238 return sys_ioctl(fd, TIOCSPGRP, arg);
239 }
240 return -ENOSYS;
241}
242
243/* }}} */
244
245/* A pseudo STREAMS support {{{ */
246
247struct strioctl {
248 int cmd, timeout, len;
249 u32 data;
250};
251
252struct solaris_si_sockparams {
253 int sp_family;
254 int sp_type;
255 int sp_protocol;
256};
257
258struct solaris_o_si_udata {
259 int tidusize;
260 int addrsize;
261 int optsize;
262 int etsdusize;
263 int servtype;
264 int so_state;
265 int so_options;
266 int tsdusize;
267};
268
269struct solaris_si_udata {
270 int tidusize;
271 int addrsize;
272 int optsize;
273 int etsdusize;
274 int servtype;
275 int so_state;
276 int so_options;
277 int tsdusize;
278 struct solaris_si_sockparams sockparams;
279};
280
281#define SOLARIS_MODULE_TIMOD 0
282#define SOLARIS_MODULE_SOCKMOD 1
283#define SOLARIS_MODULE_MAX 2
284
285static struct module_info {
286 const char *name;
287 /* can be expanded further if needed */
288} module_table[ SOLARIS_MODULE_MAX + 1 ] = {
289 /* the ordering here must match the module numbers above! */
290 { "timod" },
291 { "sockmod" },
292 { NULL }
293};
294
295static inline int solaris_sockmod(unsigned int fd, unsigned int cmd, u32 arg)
296{
297 struct inode *ino;
298 struct fdtable *fdt;
299 /* I wonder which of these tests are superfluous... --patrik */
300 rcu_read_lock();
301 fdt = files_fdtable(current->files);
302 if (! fdt->fd[fd] ||
303 ! fdt->fd[fd]->f_path.dentry ||
304 ! (ino = fdt->fd[fd]->f_path.dentry->d_inode) ||
305 ! S_ISSOCK(ino->i_mode)) {
306 rcu_read_unlock();
307 return TBADF;
308 }
309 rcu_read_unlock();
310
311 switch (cmd & 0xff) {
312 case 109: /* SI_SOCKPARAMS */
313 {
314 struct solaris_si_sockparams si;
315 if (copy_from_user (&si, A(arg), sizeof(si)))
316 return (EFAULT << 8) | TSYSERR;
317
318 /* Should we modify socket ino->socket_i.ops and type? */
319 return 0;
320 }
321 case 110: /* SI_GETUDATA */
322 {
323 int etsdusize, servtype;
324 struct solaris_si_udata __user *p = A(arg);
325 switch (SOCKET_I(ino)->type) {
326 case SOCK_STREAM:
327 etsdusize = 1;
328 servtype = 2;
329 break;
330 default:
331 etsdusize = -2;
332 servtype = 3;
333 break;
334 }
335 if (put_user(16384, &p->tidusize) ||
336 __put_user(sizeof(struct sockaddr), &p->addrsize) ||
337 __put_user(-1, &p->optsize) ||
338 __put_user(etsdusize, &p->etsdusize) ||
339 __put_user(servtype, &p->servtype) ||
340 __put_user(0, &p->so_state) ||
341 __put_user(0, &p->so_options) ||
342 __put_user(16384, &p->tsdusize) ||
343 __put_user(SOCKET_I(ino)->ops->family, &p->sockparams.sp_family) ||
344 __put_user(SOCKET_I(ino)->type, &p->sockparams.sp_type) ||
345 __put_user(SOCKET_I(ino)->ops->family, &p->sockparams.sp_protocol))
346 return (EFAULT << 8) | TSYSERR;
347 return 0;
348 }
349 case 101: /* O_SI_GETUDATA */
350 {
351 int etsdusize, servtype;
352 struct solaris_o_si_udata __user *p = A(arg);
353 switch (SOCKET_I(ino)->type) {
354 case SOCK_STREAM:
355 etsdusize = 1;
356 servtype = 2;
357 break;
358 default:
359 etsdusize = -2;
360 servtype = 3;
361 break;
362 }
363 if (put_user(16384, &p->tidusize) ||
364 __put_user(sizeof(struct sockaddr), &p->addrsize) ||
365 __put_user(-1, &p->optsize) ||
366 __put_user(etsdusize, &p->etsdusize) ||
367 __put_user(servtype, &p->servtype) ||
368 __put_user(0, &p->so_state) ||
369 __put_user(0, &p->so_options) ||
370 __put_user(16384, &p->tsdusize))
371 return (EFAULT << 8) | TSYSERR;
372 return 0;
373 }
374 case 102: /* SI_SHUTDOWN */
375 case 103: /* SI_LISTEN */
376 case 104: /* SI_SETMYNAME */
377 case 105: /* SI_SETPEERNAME */
378 case 106: /* SI_GETINTRANSIT */
379 case 107: /* SI_TCL_LINK */
380 case 108: /* SI_TCL_UNLINK */
381 ;
382 }
383 return TNOTSUPPORT;
384}
385
386static inline int solaris_timod(unsigned int fd, unsigned int cmd, u32 arg,
387 int len, int __user *len_p)
388{
389 int ret;
390
391 switch (cmd & 0xff) {
392 case 141: /* TI_OPTMGMT */
393 {
394 int i;
395 u32 prim;
396 SOLD("TI_OPMGMT entry");
397 ret = timod_putmsg(fd, A(arg), len, NULL, -1, 0);
398 SOLD("timod_putmsg() returned");
399 if (ret)
400 return (-ret << 8) | TSYSERR;
401 i = MSG_HIPRI;
402 SOLD("calling timod_getmsg()");
403 ret = timod_getmsg(fd, A(arg), len, len_p, NULL, -1, NULL, &i);
404 SOLD("timod_getmsg() returned");
405 if (ret)
406 return (-ret << 8) | TSYSERR;
407 SOLD("ret ok");
408 if (get_user(prim, (u32 __user *)A(arg)))
409 return (EFAULT << 8) | TSYSERR;
410 SOLD("got prim");
411 if (prim == T_ERROR_ACK) {
412 u32 tmp, tmp2;
413 SOLD("prim is T_ERROR_ACK");
414 if (get_user(tmp, (u32 __user *)A(arg)+3) ||
415 get_user(tmp2, (u32 __user *)A(arg)+2))
416 return (EFAULT << 8) | TSYSERR;
417 return (tmp2 << 8) | tmp;
418 }
419 SOLD("TI_OPMGMT return 0");
420 return 0;
421 }
422 case 142: /* TI_BIND */
423 {
424 int i;
425 u32 prim;
426 SOLD("TI_BIND entry");
427 ret = timod_putmsg(fd, A(arg), len, NULL, -1, 0);
428 SOLD("timod_putmsg() returned");
429 if (ret)
430 return (-ret << 8) | TSYSERR;
431 len = 1024; /* Solaris allows arbitrary return size */
432 i = MSG_HIPRI;
433 SOLD("calling timod_getmsg()");
434 ret = timod_getmsg(fd, A(arg), len, len_p, NULL, -1, NULL, &i);
435 SOLD("timod_getmsg() returned");
436 if (ret)
437 return (-ret << 8) | TSYSERR;
438 SOLD("ret ok");
439 if (get_user(prim, (u32 __user *)A(arg)))
440 return (EFAULT << 8) | TSYSERR;
441 SOLD("got prim");
442 if (prim == T_ERROR_ACK) {
443 u32 tmp, tmp2;
444 SOLD("prim is T_ERROR_ACK");
445 if (get_user(tmp, (u32 __user *)A(arg)+3) ||
446 get_user(tmp2, (u32 __user *)A(arg)+2))
447 return (EFAULT << 8) | TSYSERR;
448 return (tmp2 << 8) | tmp;
449 }
450 SOLD("no ERROR_ACK requested");
451 if (prim != T_OK_ACK)
452 return TBADSEQ;
453 SOLD("OK_ACK requested");
454 i = MSG_HIPRI;
455 SOLD("calling timod_getmsg()");
456 ret = timod_getmsg(fd, A(arg), len, len_p, NULL, -1, NULL, &i);
457 SOLD("timod_getmsg() returned");
458 if (ret)
459 return (-ret << 8) | TSYSERR;
460 SOLD("TI_BIND return ok");
461 return 0;
462 }
463 case 140: /* TI_GETINFO */
464 case 143: /* TI_UNBIND */
465 case 144: /* TI_GETMYNAME */
466 case 145: /* TI_GETPEERNAME */
467 case 146: /* TI_SETMYNAME */
468 case 147: /* TI_SETPEERNAME */
469 ;
470 }
471 return TNOTSUPPORT;
472}
473
474static inline int solaris_S(struct file *filp, unsigned int fd, unsigned int cmd, u32 arg)
475{
476 char *p;
477 int ret;
478 mm_segment_t old_fs;
479 struct strioctl si;
480 struct inode *ino;
481 struct sol_socket_struct *sock;
482 struct module_info *mi;
483
484 ino = filp->f_path.dentry->d_inode;
485 if (!S_ISSOCK(ino->i_mode))
486 return -EBADF;
487 sock = filp->private_data;
488 if (! sock) {
489 printk("solaris_S: NULL private_data\n");
490 return -EBADF;
491 }
492 if (sock->magic != SOLARIS_SOCKET_MAGIC) {
493 printk("solaris_S: invalid magic\n");
494 return -EBADF;
495 }
496
497
498 switch (cmd & 0xff) {
499 case 1: /* I_NREAD */
500 return -ENOSYS;
501 case 2: /* I_PUSH */
502 {
503 p = getname (A(arg));
504 if (IS_ERR (p))
505 return PTR_ERR(p);
506 ret = -EINVAL;
507 for (mi = module_table; mi->name; mi++) {
508 if (strcmp(mi->name, p) == 0) {
509 sol_module m;
510 if (sock->modcount >= MAX_NR_STREAM_MODULES) {
511 ret = -ENXIO;
512 break;
513 }
514 m = (sol_module) (mi - module_table);
515 sock->module[sock->modcount++] = m;
516 ret = 0;
517 break;
518 }
519 }
520 putname (p);
521 return ret;
522 }
523 case 3: /* I_POP */
524 if (sock->modcount <= 0) return -EINVAL;
525 sock->modcount--;
526 return 0;
527 case 4: /* I_LOOK */
528 {
529 const char *p;
530 if (sock->modcount <= 0) return -EINVAL;
531 p = module_table[(unsigned)sock->module[sock->modcount]].name;
532 if (copy_to_user (A(arg), p, strlen(p)))
533 return -EFAULT;
534 return 0;
535 }
536 case 5: /* I_FLUSH */
537 return 0;
538 case 8: /* I_STR */
539 if (copy_from_user(&si, A(arg), sizeof(struct strioctl)))
540 return -EFAULT;
541 /* We ignore what module is actually at the top of stack. */
542 switch ((si.cmd >> 8) & 0xff) {
543 case 'I':
544 return solaris_sockmod(fd, si.cmd, si.data);
545 case 'T':
546 return solaris_timod(fd, si.cmd, si.data, si.len,
547 &((struct strioctl __user *)A(arg))->len);
548 default:
549 return solaris_ioctl(fd, si.cmd, si.data);
550 }
551 case 9: /* I_SETSIG */
552 return sys_ioctl(fd, FIOSETOWN, current->pid);
553 case 10: /* I_GETSIG */
554 old_fs = get_fs();
555 set_fs(KERNEL_DS);
556 sys_ioctl(fd, FIOGETOWN, (unsigned long)&ret);
557 set_fs(old_fs);
558 if (ret == current->pid) return 0x3ff;
559 else return -EINVAL;
560 case 11: /* I_FIND */
561 {
562 int i;
563 p = getname (A(arg));
564 if (IS_ERR (p))
565 return PTR_ERR(p);
566 ret = 0;
567 for (i = 0; i < sock->modcount; i++) {
568 unsigned m = sock->module[i];
569 if (strcmp(module_table[m].name, p) == 0) {
570 ret = 1;
571 break;
572 }
573 }
574 putname (p);
575 return ret;
576 }
577 case 19: /* I_SWROPT */
578 case 32: /* I_SETCLTIME */
579 return 0; /* Lie */
580 }
581 return -ENOSYS;
582}
583
584static inline int solaris_s(unsigned int fd, unsigned int cmd, u32 arg)
585{
586 switch (cmd & 0xff) {
587 case 0: /* SIOCSHIWAT */
588 case 2: /* SIOCSLOWAT */
589 return 0; /* We don't support them */
590 case 1: /* SIOCGHIWAT */
591 case 3: /* SIOCGLOWAT */
592 if (put_user (0, (u32 __user *)A(arg)))
593 return -EFAULT;
594 return 0; /* Lie */
595 case 7: /* SIOCATMARK */
596 return sys_ioctl(fd, SIOCATMARK, arg);
597 case 8: /* SIOCSPGRP */
598 return sys_ioctl(fd, SIOCSPGRP, arg);
599 case 9: /* SIOCGPGRP */
600 return sys_ioctl(fd, SIOCGPGRP, arg);
601 }
602 return -ENOSYS;
603}
604
605static inline int solaris_r(unsigned int fd, unsigned int cmd, u32 arg)
606{
607 switch (cmd & 0xff) {
608 case 10: /* SIOCADDRT */
609 return compat_sys_ioctl(fd, SIOCADDRT, arg);
610 case 11: /* SIOCDELRT */
611 return compat_sys_ioctl(fd, SIOCDELRT, arg);
612 }
613 return -ENOSYS;
614}
615
616static inline int solaris_i(unsigned int fd, unsigned int cmd, u32 arg)
617{
618 switch (cmd & 0xff) {
619 case 12: /* SIOCSIFADDR */
620 return compat_sys_ioctl(fd, SIOCSIFADDR, arg);
621 case 13: /* SIOCGIFADDR */
622 return compat_sys_ioctl(fd, SIOCGIFADDR, arg);
623 case 14: /* SIOCSIFDSTADDR */
624 return compat_sys_ioctl(fd, SIOCSIFDSTADDR, arg);
625 case 15: /* SIOCGIFDSTADDR */
626 return compat_sys_ioctl(fd, SIOCGIFDSTADDR, arg);
627 case 16: /* SIOCSIFFLAGS */
628 return compat_sys_ioctl(fd, SIOCSIFFLAGS, arg);
629 case 17: /* SIOCGIFFLAGS */
630 return compat_sys_ioctl(fd, SIOCGIFFLAGS, arg);
631 case 18: /* SIOCSIFMEM */
632 return compat_sys_ioctl(fd, SIOCSIFMEM, arg);
633 case 19: /* SIOCGIFMEM */
634 return compat_sys_ioctl(fd, SIOCGIFMEM, arg);
635 case 20: /* SIOCGIFCONF */
636 return compat_sys_ioctl(fd, SIOCGIFCONF, arg);
637 case 21: /* SIOCSIFMTU */
638 return compat_sys_ioctl(fd, SIOCSIFMTU, arg);
639 case 22: /* SIOCGIFMTU */
640 return compat_sys_ioctl(fd, SIOCGIFMTU, arg);
641 case 23: /* SIOCGIFBRDADDR */
642 return compat_sys_ioctl(fd, SIOCGIFBRDADDR, arg);
643 case 24: /* SIOCSIFBRDADDR */
644 return compat_sys_ioctl(fd, SIOCSIFBRDADDR, arg);
645 case 25: /* SIOCGIFNETMASK */
646 return compat_sys_ioctl(fd, SIOCGIFNETMASK, arg);
647 case 26: /* SIOCSIFNETMASK */
648 return compat_sys_ioctl(fd, SIOCSIFNETMASK, arg);
649 case 27: /* SIOCGIFMETRIC */
650 return compat_sys_ioctl(fd, SIOCGIFMETRIC, arg);
651 case 28: /* SIOCSIFMETRIC */
652 return compat_sys_ioctl(fd, SIOCSIFMETRIC, arg);
653 case 30: /* SIOCSARP */
654 return compat_sys_ioctl(fd, SIOCSARP, arg);
655 case 31: /* SIOCGARP */
656 return compat_sys_ioctl(fd, SIOCGARP, arg);
657 case 32: /* SIOCDARP */
658 return compat_sys_ioctl(fd, SIOCDARP, arg);
659 case 52: /* SIOCGETNAME */
660 case 53: /* SIOCGETPEER */
661 {
662 struct sockaddr uaddr;
663 int uaddr_len = sizeof(struct sockaddr), ret;
664 long args[3];
665 mm_segment_t old_fs = get_fs();
666 int (*sys_socketcall)(int, unsigned long *) =
667 (int (*)(int, unsigned long *))SYS(socketcall);
668
669 args[0] = fd; args[1] = (long)&uaddr; args[2] = (long)&uaddr_len;
670 set_fs(KERNEL_DS);
671 ret = sys_socketcall(((cmd & 0xff) == 52) ? SYS_GETSOCKNAME : SYS_GETPEERNAME,
672 args);
673 set_fs(old_fs);
674 if (ret >= 0) {
675 if (copy_to_user(A(arg), &uaddr, uaddr_len))
676 return -EFAULT;
677 }
678 return ret;
679 }
680#if 0
681 case 86: /* SIOCSOCKSYS */
682 return socksys_syscall(fd, arg);
683#endif
684 case 87: /* SIOCGIFNUM */
685 {
686 struct net_device *d;
687 int i = 0;
688
689 read_lock_bh(&dev_base_lock);
690 for_each_netdev(&init_net, d)
691 i++;
692 read_unlock_bh(&dev_base_lock);
693
694 if (put_user (i, (int __user *)A(arg)))
695 return -EFAULT;
696 return 0;
697 }
698 }
699 return -ENOSYS;
700}
701
702static int solaris_m(unsigned int fd, unsigned int cmd, u32 arg)
703{
704 int ret;
705
706 switch (cmd & 0xff) {
707 case 1: /* MTIOCTOP */
708 ret = sys_ioctl(fd, MTIOCTOP, (unsigned long)&arg);
709 break;
710 case 2: /* MTIOCGET */
711 ret = sys_ioctl(fd, MTIOCGET, (unsigned long)&arg);
712 break;
713 case 3: /* MTIOCGETDRIVETYPE */
714 case 4: /* MTIOCPERSISTENT */
715 case 5: /* MTIOCPERSISTENTSTATUS */
716 case 6: /* MTIOCLRERR */
717 case 7: /* MTIOCGUARANTEEDORDER */
718 case 8: /* MTIOCRESERVE */
719 case 9: /* MTIOCRELEASE */
720 case 10: /* MTIOCFORCERESERVE */
721 case 13: /* MTIOCSTATE */
722 case 14: /* MTIOCREADIGNOREILI */
723 case 15: /* MTIOCREADIGNOREEOFS */
724 case 16: /* MTIOCSHORTFMK */
725 default:
726 ret = -ENOSYS; /* linux doesn't support these */
727 break;
728 };
729
730 return ret;
731}
732
733static int solaris_O(unsigned int fd, unsigned int cmd, u32 arg)
734{
735 int ret = -EINVAL;
736
737 switch (cmd & 0xff) {
738 case 1: /* OPROMGETOPT */
739 ret = sys_ioctl(fd, OPROMGETOPT, arg);
740 break;
741 case 2: /* OPROMSETOPT */
742 ret = sys_ioctl(fd, OPROMSETOPT, arg);
743 break;
744 case 3: /* OPROMNXTOPT */
745 ret = sys_ioctl(fd, OPROMNXTOPT, arg);
746 break;
747 case 4: /* OPROMSETOPT2 */
748 ret = sys_ioctl(fd, OPROMSETOPT2, arg);
749 break;
750 case 5: /* OPROMNEXT */
751 ret = sys_ioctl(fd, OPROMNEXT, arg);
752 break;
753 case 6: /* OPROMCHILD */
754 ret = sys_ioctl(fd, OPROMCHILD, arg);
755 break;
756 case 7: /* OPROMGETPROP */
757 ret = sys_ioctl(fd, OPROMGETPROP, arg);
758 break;
759 case 8: /* OPROMNXTPROP */
760 ret = sys_ioctl(fd, OPROMNXTPROP, arg);
761 break;
762 case 9: /* OPROMU2P */
763 ret = sys_ioctl(fd, OPROMU2P, arg);
764 break;
765 case 10: /* OPROMGETCONS */
766 ret = sys_ioctl(fd, OPROMGETCONS, arg);
767 break;
768 case 11: /* OPROMGETFBNAME */
769 ret = sys_ioctl(fd, OPROMGETFBNAME, arg);
770 break;
771 case 12: /* OPROMGETBOOTARGS */
772 ret = sys_ioctl(fd, OPROMGETBOOTARGS, arg);
773 break;
774 case 13: /* OPROMGETVERSION */
775 case 14: /* OPROMPATH2DRV */
776 case 15: /* OPROMDEV2PROMNAME */
777 case 16: /* OPROMPROM2DEVNAME */
778 case 17: /* OPROMGETPROPLEN */
779 default:
780 ret = -EINVAL;
781 break;
782 };
783 return ret;
784}
785
786/* }}} */
787
788asmlinkage int solaris_ioctl(unsigned int fd, unsigned int cmd, u32 arg)
789{
790 struct file *filp;
791 int error = -EBADF;
792
793 filp = fget(fd);
794 if (!filp)
795 goto out;
796
797 lock_kernel();
798 error = -EFAULT;
799 switch ((cmd >> 8) & 0xff) {
800 case 'S': error = solaris_S(filp, fd, cmd, arg); break;
801 case 'T': error = solaris_T(fd, cmd, arg); break;
802 case 'i': error = solaris_i(fd, cmd, arg); break;
803 case 'r': error = solaris_r(fd, cmd, arg); break;
804 case 's': error = solaris_s(fd, cmd, arg); break;
805 case 't': error = solaris_t(fd, cmd, arg); break;
806 case 'f': error = sys_ioctl(fd, cmd, arg); break;
807 case 'm': error = solaris_m(fd, cmd, arg); break;
808 case 'O': error = solaris_O(fd, cmd, arg); break;
809 default:
810 error = -ENOSYS;
811 break;
812 }
813 unlock_kernel();
814 fput(filp);
815out:
816 if (error == -ENOSYS) {
817 unsigned char c = cmd>>8;
818
819 if (c < ' ' || c > 126) c = '.';
820 printk("solaris_ioctl: Unknown cmd fd(%d) cmd(%08x '%c') arg(%08x)\n",
821 (int)fd, (unsigned int)cmd, c, (unsigned int)arg);
822 error = -EINVAL;
823 }
824 return error;
825}
diff --git a/arch/sparc64/solaris/ipc.c b/arch/sparc64/solaris/ipc.c
deleted file mode 100644
index 499135fa7060..000000000000
--- a/arch/sparc64/solaris/ipc.c
+++ /dev/null
@@ -1,126 +0,0 @@
1/* $Id: ipc.c,v 1.5 1999/12/09 00:41:00 davem Exp $
2 * ipc.c: Solaris IPC emulation
3 *
4 * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
5 */
6
7#include <linux/kernel.h>
8#include <linux/types.h>
9#include <linux/wait.h>
10#include <linux/mm.h>
11#include <linux/shm.h>
12#include <linux/sem.h>
13#include <linux/msg.h>
14#include <linux/ipc.h>
15
16#include <asm/uaccess.h>
17#include <asm/string.h>
18
19#include "conv.h"
20
21struct solaris_ipc_perm {
22 s32 uid;
23 s32 gid;
24 s32 cuid;
25 s32 cgid;
26 u32 mode;
27 u32 seq;
28 int key;
29 s32 pad[4];
30};
31
32struct solaris_shmid_ds {
33 struct solaris_ipc_perm shm_perm;
34 int shm_segsz;
35 u32 shm_amp;
36 unsigned short shm_lkcnt;
37 char __padxx[2];
38 s32 shm_lpid;
39 s32 shm_cpid;
40 u32 shm_nattch;
41 u32 shm_cnattch;
42 s32 shm_atime;
43 s32 shm_pad1;
44 s32 shm_dtime;
45 s32 shm_pad2;
46 s32 shm_ctime;
47 s32 shm_pad3;
48 unsigned short shm_cv;
49 char shm_pad4[2];
50 u32 shm_sptas;
51 s32 shm_pad5[2];
52};
53
54asmlinkage long solaris_shmsys(int cmd, u32 arg1, u32 arg2, u32 arg3)
55{
56 int (*sys_ipc)(unsigned,int,int,unsigned long,void __user *,long) =
57 (int (*)(unsigned,int,int,unsigned long,void __user *,long))SYS(ipc);
58 mm_segment_t old_fs;
59 unsigned long raddr;
60 int ret;
61
62 switch (cmd) {
63 case 0: /* shmat */
64 old_fs = get_fs();
65 set_fs(KERNEL_DS);
66 ret = sys_ipc(SHMAT, arg1, arg3 & ~0x4000, (unsigned long)&raddr, A(arg2), 0);
67 set_fs(old_fs);
68 if (ret >= 0) return (u32)raddr;
69 else return ret;
70 case 1: /* shmctl */
71 switch (arg2) {
72 case 3: /* SHM_LOCK */
73 case 4: /* SHM_UNLOCK */
74 return sys_ipc(SHMCTL, arg1, (arg2 == 3) ? SHM_LOCK : SHM_UNLOCK, 0, NULL, 0);
75 case 10: /* IPC_RMID */
76 return sys_ipc(SHMCTL, arg1, IPC_RMID, 0, NULL, 0);
77 case 11: /* IPC_SET */
78 {
79 struct shmid_ds s;
80 struct solaris_shmid_ds __user *p = A(arg3);
81
82 if (get_user (s.shm_perm.uid, &p->shm_perm.uid) ||
83 __get_user (s.shm_perm.gid, &p->shm_perm.gid) ||
84 __get_user (s.shm_perm.mode, &p->shm_perm.mode))
85 return -EFAULT;
86 old_fs = get_fs();
87 set_fs(KERNEL_DS);
88 ret = sys_ipc(SHMCTL, arg1, IPC_SET, 0, &s, 0);
89 set_fs(old_fs);
90 return ret;
91 }
92 case 12: /* IPC_STAT */
93 {
94 struct shmid_ds s;
95 struct solaris_shmid_ds __user *p = A(arg3);
96
97 old_fs = get_fs();
98 set_fs(KERNEL_DS);
99 ret = sys_ipc(SHMCTL, arg1, IPC_SET, 0, &s, 0);
100 set_fs(old_fs);
101 if (put_user (s.shm_perm.uid, &(p->shm_perm.uid)) ||
102 __put_user (s.shm_perm.gid, &(p->shm_perm.gid)) ||
103 __put_user (s.shm_perm.cuid, &(p->shm_perm.cuid)) ||
104 __put_user (s.shm_perm.cgid, &(p->shm_perm.cgid)) ||
105 __put_user (s.shm_perm.mode, &(p->shm_perm.mode)) ||
106 __put_user (s.shm_perm.seq, &(p->shm_perm.seq)) ||
107 __put_user (s.shm_perm.key, &(p->shm_perm.key)) ||
108 __put_user (s.shm_segsz, &(p->shm_segsz)) ||
109 __put_user (s.shm_lpid, &(p->shm_lpid)) ||
110 __put_user (s.shm_cpid, &(p->shm_cpid)) ||
111 __put_user (s.shm_nattch, &(p->shm_nattch)) ||
112 __put_user (s.shm_atime, &(p->shm_atime)) ||
113 __put_user (s.shm_dtime, &(p->shm_dtime)) ||
114 __put_user (s.shm_ctime, &(p->shm_ctime)))
115 return -EFAULT;
116 return ret;
117 }
118 default: return -EINVAL;
119 }
120 case 2: /* shmdt */
121 return sys_ipc(SHMDT, 0, 0, 0, A(arg1), 0);
122 case 3: /* shmget */
123 return sys_ipc(SHMGET, arg1, arg2, arg3, NULL, 0);
124 }
125 return -EINVAL;
126}
diff --git a/arch/sparc64/solaris/misc.c b/arch/sparc64/solaris/misc.c
deleted file mode 100644
index d3e48e9701bf..000000000000
--- a/arch/sparc64/solaris/misc.c
+++ /dev/null
@@ -1,786 +0,0 @@
1/* $Id: misc.c,v 1.36 2002/02/09 19:49:31 davem Exp $
2 * misc.c: Miscellaneous syscall emulation for Solaris
3 *
4 * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
5 */
6
7#include <linux/module.h>
8#include <linux/types.h>
9#include <linux/utsname.h>
10#include <linux/limits.h>
11#include <linux/mm.h>
12#include <linux/smp.h>
13#include <linux/tty.h>
14#include <linux/mman.h>
15#include <linux/file.h>
16#include <linux/timex.h>
17#include <linux/major.h>
18#include <linux/compat.h>
19
20#include <asm/uaccess.h>
21#include <asm/string.h>
22#include <asm/oplib.h>
23#include <asm/idprom.h>
24#include <asm/smp.h>
25#include <asm/prom.h>
26
27#include "conv.h"
28
29/* Conversion from Linux to Solaris errnos. 0-34 are identity mapped.
30 Some Linux errnos (EPROCLIM, EDOTDOT, ERREMOTE, EUCLEAN, ENOTNAM,
31 ENAVAIL, EISNAM, EREMOTEIO, ENOMEDIUM, EMEDIUMTYPE) have no Solaris
32 equivalents. I return EINVAL in that case, which is very wrong. If
33 someone suggest a better value for them, you're welcomed.
34 On the other side, Solaris ECANCELED and ENOTSUP have no Linux equivalents,
35 but that doesn't matter here. --jj */
36int solaris_err_table[] = {
37/* 0 */ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
38/* 10 */ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
39/* 20 */ 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
40/* 30 */ 30, 31, 32, 33, 34, 22, 150, 149, 95, 96,
41/* 40 */ 97, 98, 99, 120, 121, 122, 123, 124, 125, 126,
42/* 50 */ 127, 128, 129, 130, 131, 132, 133, 134, 143, 144,
43/* 60 */ 145, 146, 90, 78, 147, 148, 93, 22, 94, 49,
44/* 70 */ 151, 66, 60, 62, 63, 35, 77, 36, 45, 46,
45/* 80 */ 64, 22, 67, 68, 69, 70, 71, 74, 22, 82,
46/* 90 */ 89, 92, 79, 81, 37, 38, 39, 40, 41, 42,
47/* 100 */ 43, 44, 50, 51, 52, 53, 54, 55, 56, 57,
48/* 110 */ 87, 61, 84, 65, 83, 80, 91, 22, 22, 22,
49/* 120 */ 22, 22, 88, 86, 85, 22, 22,
50};
51
52#define SOLARIS_NR_OPEN 256
53
54static u32 do_solaris_mmap(u32 addr, u32 len, u32 prot, u32 flags, u32 fd, u64 off)
55{
56 struct file *file = NULL;
57 unsigned long retval, ret_type;
58
59 /* Do we need it here? */
60 set_personality(PER_SVR4);
61 if (flags & MAP_NORESERVE) {
62 static int cnt;
63
64 if (cnt < 5) {
65 printk("%s: unimplemented Solaris MAP_NORESERVE mmap() flag\n",
66 current->comm);
67 cnt++;
68 }
69 flags &= ~MAP_NORESERVE;
70 }
71 retval = -EBADF;
72 if(!(flags & MAP_ANONYMOUS)) {
73 if(fd >= SOLARIS_NR_OPEN)
74 goto out;
75 file = fget(fd);
76 if (!file)
77 goto out;
78 else {
79 struct inode * inode = file->f_path.dentry->d_inode;
80 if(imajor(inode) == MEM_MAJOR &&
81 iminor(inode) == 5) {
82 flags |= MAP_ANONYMOUS;
83 fput(file);
84 file = NULL;
85 }
86 }
87 }
88
89 retval = -EINVAL;
90 len = PAGE_ALIGN(len);
91 if(!(flags & MAP_FIXED))
92 addr = 0;
93 else if (len > STACK_TOP32 || addr > STACK_TOP32 - len)
94 goto out_putf;
95 ret_type = flags & _MAP_NEW;
96 flags &= ~_MAP_NEW;
97
98 down_write(&current->mm->mmap_sem);
99 flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
100 retval = do_mmap(file,
101 (unsigned long) addr, (unsigned long) len,
102 (unsigned long) prot, (unsigned long) flags, off);
103 up_write(&current->mm->mmap_sem);
104 if(!ret_type)
105 retval = ((retval < STACK_TOP32) ? 0 : retval);
106
107out_putf:
108 if (file)
109 fput(file);
110out:
111 return (u32) retval;
112}
113
114asmlinkage u32 solaris_mmap(u32 addr, u32 len, u32 prot, u32 flags, u32 fd, u32 off)
115{
116 return do_solaris_mmap(addr, len, prot, flags, fd, (u64) off);
117}
118
119asmlinkage u32 solaris_mmap64(struct pt_regs *regs, u32 len, u32 prot, u32 flags, u32 fd, u32 offhi)
120{
121 u32 offlo;
122
123 if (regs->u_regs[UREG_G1]) {
124 if (get_user (offlo, (u32 __user *)(long)((u32)regs->u_regs[UREG_I6] + 0x5c)))
125 return -EFAULT;
126 } else {
127 if (get_user (offlo, (u32 __user *)(long)((u32)regs->u_regs[UREG_I6] + 0x60)))
128 return -EFAULT;
129 }
130 return do_solaris_mmap((u32)regs->u_regs[UREG_I0], len, prot, flags, fd, (((u64)offhi)<<32)|offlo);
131}
132
133asmlinkage int solaris_brk(u32 brk)
134{
135 int (*sunos_brk)(u32) = (int (*)(u32))SUNOS(17);
136
137 return sunos_brk(brk);
138}
139
140static int __set_utsfield(char __user *to, int to_size,
141 const char *from, int from_size,
142 int dotchop, int countfrom)
143{
144 int len = countfrom ? (to_size > from_size ?
145 from_size : to_size) : to_size;
146 int off;
147
148 if (copy_to_user(to, from, len))
149 return -EFAULT;
150
151 off = len < to_size? len: len - 1;
152 if (dotchop) {
153 const char *p = strnchr(from, len, '.');
154 if (p) off = p - from;
155 }
156
157 if (__put_user('\0', to + off))
158 return -EFAULT;
159
160 return 0;
161}
162
163#define set_utsfield(to, from, dotchop, countfrom) \
164 __set_utsfield((to), sizeof(to), \
165 (from), sizeof(from), \
166 (dotchop), (countfrom))
167
168struct sol_uname {
169 char sysname[9];
170 char nodename[9];
171 char release[9];
172 char version[9];
173 char machine[9];
174};
175
176struct sol_utsname {
177 char sysname[257];
178 char nodename[257];
179 char release[257];
180 char version[257];
181 char machine[257];
182};
183
184static char *machine(void)
185{
186 switch (sparc_cpu_model) {
187 case sun4: return "sun4";
188 case sun4c: return "sun4c";
189 case sun4e: return "sun4e";
190 case sun4m: return "sun4m";
191 case sun4d: return "sun4d";
192 case sun4u: return "sun4u";
193 default: return "sparc";
194 }
195}
196
197static char *platform(char *buffer, int sz)
198{
199 struct device_node *dp = of_find_node_by_path("/");
200 int len;
201
202 *buffer = 0;
203 len = strlen(dp->name);
204 if (len > sz)
205 len = sz;
206 memcpy(buffer, dp->name, len);
207 buffer[len] = 0;
208 if (*buffer) {
209 char *p;
210
211 for (p = buffer; *p; p++)
212 if (*p == '/' || *p == ' ') *p = '_';
213 return buffer;
214 }
215
216 return "sun4u";
217}
218
219static char *serial(char *buffer, int sz)
220{
221 struct device_node *dp = of_find_node_by_path("/options");
222 int len;
223
224 *buffer = 0;
225 if (dp) {
226 const char *val =
227 of_get_property(dp, "system-board-serial#", &len);
228
229 if (val && len > 0) {
230 if (len > sz)
231 len = sz;
232 memcpy(buffer, val, len);
233 buffer[len] = 0;
234 }
235 }
236 if (!*buffer)
237 return "4512348717234";
238 else
239 return buffer;
240}
241
242asmlinkage int solaris_utssys(u32 buf, u32 flags, int which, u32 buf2)
243{
244 struct sol_uname __user *v = A(buf);
245 int err;
246
247 switch (which) {
248 case 0: /* old uname */
249 /* Let's cheat */
250 err = set_utsfield(v->sysname, "SunOS", 1, 0);
251 down_read(&uts_sem);
252 err |= set_utsfield(v->nodename, utsname()->nodename,
253 1, 1);
254 up_read(&uts_sem);
255 err |= set_utsfield(v->release, "2.6", 0, 0);
256 err |= set_utsfield(v->version, "Generic", 0, 0);
257 err |= set_utsfield(v->machine, machine(), 0, 0);
258 return (err ? -EFAULT : 0);
259 case 2: /* ustat */
260 return -ENOSYS;
261 case 3: /* fusers */
262 return -ENOSYS;
263 default:
264 return -ENOSYS;
265 }
266}
267
268asmlinkage int solaris_utsname(u32 buf)
269{
270 struct sol_utsname __user *v = A(buf);
271 int err;
272
273 /* Why should we not lie a bit? */
274 down_read(&uts_sem);
275 err = set_utsfield(v->sysname, "SunOS", 0, 0);
276 err |= set_utsfield(v->nodename, utsname()->nodename, 1, 1);
277 err |= set_utsfield(v->release, "5.6", 0, 0);
278 err |= set_utsfield(v->version, "Generic", 0, 0);
279 err |= set_utsfield(v->machine, machine(), 0, 0);
280 up_read(&uts_sem);
281
282 return (err ? -EFAULT : 0);
283}
284
285#define SI_SYSNAME 1 /* return name of operating system */
286#define SI_HOSTNAME 2 /* return name of node */
287#define SI_RELEASE 3 /* return release of operating system */
288#define SI_VERSION 4 /* return version field of utsname */
289#define SI_MACHINE 5 /* return kind of machine */
290#define SI_ARCHITECTURE 6 /* return instruction set arch */
291#define SI_HW_SERIAL 7 /* return hardware serial number */
292#define SI_HW_PROVIDER 8 /* return hardware manufacturer */
293#define SI_SRPC_DOMAIN 9 /* return secure RPC domain */
294#define SI_PLATFORM 513 /* return platform identifier */
295
296asmlinkage int solaris_sysinfo(int cmd, u32 buf, s32 count)
297{
298 char *p, *q, *r;
299 char buffer[256];
300 int len;
301
302 /* Again, we cheat :)) */
303 switch (cmd) {
304 case SI_SYSNAME: r = "SunOS"; break;
305 case SI_HOSTNAME:
306 r = buffer + 256;
307 down_read(&uts_sem);
308 for (p = utsname()->nodename, q = buffer;
309 q < r && *p && *p != '.'; *q++ = *p++);
310 up_read(&uts_sem);
311 *q = 0;
312 r = buffer;
313 break;
314 case SI_RELEASE: r = "5.6"; break;
315 case SI_MACHINE: r = machine(); break;
316 case SI_ARCHITECTURE: r = "sparc"; break;
317 case SI_HW_PROVIDER: r = "Sun_Microsystems"; break;
318 case SI_HW_SERIAL: r = serial(buffer, sizeof(buffer)); break;
319 case SI_PLATFORM: r = platform(buffer, sizeof(buffer)); break;
320 case SI_SRPC_DOMAIN: r = ""; break;
321 case SI_VERSION: r = "Generic"; break;
322 default: return -EINVAL;
323 }
324 len = strlen(r) + 1;
325 if (count < len) {
326 if (copy_to_user(A(buf), r, count - 1) ||
327 __put_user(0, (char __user *)A(buf) + count - 1))
328 return -EFAULT;
329 } else {
330 if (copy_to_user(A(buf), r, len))
331 return -EFAULT;
332 }
333 return len;
334}
335
336#define SOLARIS_CONFIG_NGROUPS 2
337#define SOLARIS_CONFIG_CHILD_MAX 3
338#define SOLARIS_CONFIG_OPEN_FILES 4
339#define SOLARIS_CONFIG_POSIX_VER 5
340#define SOLARIS_CONFIG_PAGESIZE 6
341#define SOLARIS_CONFIG_CLK_TCK 7
342#define SOLARIS_CONFIG_XOPEN_VER 8
343#define SOLARIS_CONFIG_PROF_TCK 10
344#define SOLARIS_CONFIG_NPROC_CONF 11
345#define SOLARIS_CONFIG_NPROC_ONLN 12
346#define SOLARIS_CONFIG_AIO_LISTIO_MAX 13
347#define SOLARIS_CONFIG_AIO_MAX 14
348#define SOLARIS_CONFIG_AIO_PRIO_DELTA_MAX 15
349#define SOLARIS_CONFIG_DELAYTIMER_MAX 16
350#define SOLARIS_CONFIG_MQ_OPEN_MAX 17
351#define SOLARIS_CONFIG_MQ_PRIO_MAX 18
352#define SOLARIS_CONFIG_RTSIG_MAX 19
353#define SOLARIS_CONFIG_SEM_NSEMS_MAX 20
354#define SOLARIS_CONFIG_SEM_VALUE_MAX 21
355#define SOLARIS_CONFIG_SIGQUEUE_MAX 22
356#define SOLARIS_CONFIG_SIGRT_MIN 23
357#define SOLARIS_CONFIG_SIGRT_MAX 24
358#define SOLARIS_CONFIG_TIMER_MAX 25
359#define SOLARIS_CONFIG_PHYS_PAGES 26
360#define SOLARIS_CONFIG_AVPHYS_PAGES 27
361
362asmlinkage int solaris_sysconf(int id)
363{
364 switch (id) {
365 case SOLARIS_CONFIG_NGROUPS: return NGROUPS_MAX;
366 case SOLARIS_CONFIG_CHILD_MAX:
367 return current->signal->rlim[RLIMIT_NPROC].rlim_cur;
368 case SOLARIS_CONFIG_OPEN_FILES:
369 return current->signal->rlim[RLIMIT_NOFILE].rlim_cur;
370 case SOLARIS_CONFIG_POSIX_VER: return 199309;
371 case SOLARIS_CONFIG_PAGESIZE: return PAGE_SIZE;
372 case SOLARIS_CONFIG_XOPEN_VER: return 3;
373 case SOLARIS_CONFIG_CLK_TCK:
374 case SOLARIS_CONFIG_PROF_TCK:
375 return sparc64_get_clock_tick(smp_processor_id());
376#ifdef CONFIG_SMP
377 case SOLARIS_CONFIG_NPROC_CONF: return NR_CPUS;
378 case SOLARIS_CONFIG_NPROC_ONLN: return num_online_cpus();
379#else
380 case SOLARIS_CONFIG_NPROC_CONF: return 1;
381 case SOLARIS_CONFIG_NPROC_ONLN: return 1;
382#endif
383 case SOLARIS_CONFIG_SIGRT_MIN: return 37;
384 case SOLARIS_CONFIG_SIGRT_MAX: return 44;
385 case SOLARIS_CONFIG_PHYS_PAGES:
386 case SOLARIS_CONFIG_AVPHYS_PAGES:
387 {
388 struct sysinfo s;
389
390 si_meminfo(&s);
391 if (id == SOLARIS_CONFIG_PHYS_PAGES)
392 return s.totalram >>= PAGE_SHIFT;
393 else
394 return s.freeram >>= PAGE_SHIFT;
395 }
396 /* XXX support these as well -jj */
397 case SOLARIS_CONFIG_AIO_LISTIO_MAX: return -EINVAL;
398 case SOLARIS_CONFIG_AIO_MAX: return -EINVAL;
399 case SOLARIS_CONFIG_AIO_PRIO_DELTA_MAX: return -EINVAL;
400 case SOLARIS_CONFIG_DELAYTIMER_MAX: return -EINVAL;
401 case SOLARIS_CONFIG_MQ_OPEN_MAX: return -EINVAL;
402 case SOLARIS_CONFIG_MQ_PRIO_MAX: return -EINVAL;
403 case SOLARIS_CONFIG_RTSIG_MAX: return -EINVAL;
404 case SOLARIS_CONFIG_SEM_NSEMS_MAX: return -EINVAL;
405 case SOLARIS_CONFIG_SEM_VALUE_MAX: return -EINVAL;
406 case SOLARIS_CONFIG_SIGQUEUE_MAX: return -EINVAL;
407 case SOLARIS_CONFIG_TIMER_MAX: return -EINVAL;
408 default: return -EINVAL;
409 }
410}
411
412asmlinkage int solaris_procids(int cmd, s32 pid, s32 pgid)
413{
414 int ret;
415
416 switch (cmd) {
417 case 0: /* getpgrp */
418 return task_pgrp_vnr(current);
419 case 1: /* setpgrp */
420 {
421 int (*sys_setpgid)(pid_t,pid_t) =
422 (int (*)(pid_t,pid_t))SYS(setpgid);
423
424 /* can anyone explain me the difference between
425 Solaris setpgrp and setsid? */
426 ret = sys_setpgid(0, 0);
427 if (ret) return ret;
428 proc_clear_tty(current);
429 return task_pgrp_vnr(current);
430 }
431 case 2: /* getsid */
432 {
433 int (*sys_getsid)(pid_t) = (int (*)(pid_t))SYS(getsid);
434 return sys_getsid(pid);
435 }
436 case 3: /* setsid */
437 {
438 int (*sys_setsid)(void) = (int (*)(void))SYS(setsid);
439 return sys_setsid();
440 }
441 case 4: /* getpgid */
442 {
443 int (*sys_getpgid)(pid_t) = (int (*)(pid_t))SYS(getpgid);
444 return sys_getpgid(pid);
445 }
446 case 5: /* setpgid */
447 {
448 int (*sys_setpgid)(pid_t,pid_t) =
449 (int (*)(pid_t,pid_t))SYS(setpgid);
450 return sys_setpgid(pid,pgid);
451 }
452 }
453 return -EINVAL;
454}
455
456asmlinkage int solaris_gettimeofday(u32 tim)
457{
458 int (*sys_gettimeofday)(struct timeval *, struct timezone *) =
459 (int (*)(struct timeval *, struct timezone *))SYS(gettimeofday);
460
461 return sys_gettimeofday((struct timeval *)(u64)tim, NULL);
462}
463
464#define RLIM_SOL_INFINITY32 0x7fffffff
465#define RLIM_SOL_SAVED_MAX32 0x7ffffffe
466#define RLIM_SOL_SAVED_CUR32 0x7ffffffd
467#define RLIM_SOL_INFINITY ((u64)-3)
468#define RLIM_SOL_SAVED_MAX ((u64)-2)
469#define RLIM_SOL_SAVED_CUR ((u64)-1)
470#define RESOURCE32(x) ((x > RLIM_INFINITY32) ? RLIM_INFINITY32 : x)
471#define RLIMIT_SOL_NOFILE 5
472#define RLIMIT_SOL_VMEM 6
473
474struct rlimit32 {
475 u32 rlim_cur;
476 u32 rlim_max;
477};
478
479asmlinkage int solaris_getrlimit(unsigned int resource, struct rlimit32 __user *rlim)
480{
481 struct rlimit r;
482 int ret;
483 mm_segment_t old_fs = get_fs ();
484 int (*sys_getrlimit)(unsigned int, struct rlimit *) =
485 (int (*)(unsigned int, struct rlimit *))SYS(getrlimit);
486
487 if (resource > RLIMIT_SOL_VMEM)
488 return -EINVAL;
489 switch (resource) {
490 case RLIMIT_SOL_NOFILE: resource = RLIMIT_NOFILE; break;
491 case RLIMIT_SOL_VMEM: resource = RLIMIT_AS; break;
492 default: break;
493 }
494 set_fs (KERNEL_DS);
495 ret = sys_getrlimit(resource, &r);
496 set_fs (old_fs);
497 if (!ret) {
498 if (r.rlim_cur == RLIM_INFINITY)
499 r.rlim_cur = RLIM_SOL_INFINITY32;
500 else if ((u64)r.rlim_cur > RLIM_SOL_INFINITY32)
501 r.rlim_cur = RLIM_SOL_SAVED_CUR32;
502 if (r.rlim_max == RLIM_INFINITY)
503 r.rlim_max = RLIM_SOL_INFINITY32;
504 else if ((u64)r.rlim_max > RLIM_SOL_INFINITY32)
505 r.rlim_max = RLIM_SOL_SAVED_MAX32;
506 ret = put_user (r.rlim_cur, &rlim->rlim_cur);
507 ret |= __put_user (r.rlim_max, &rlim->rlim_max);
508 }
509 return ret;
510}
511
512asmlinkage int solaris_setrlimit(unsigned int resource, struct rlimit32 __user *rlim)
513{
514 struct rlimit r, rold;
515 int ret;
516 mm_segment_t old_fs = get_fs ();
517 int (*sys_getrlimit)(unsigned int, struct rlimit __user *) =
518 (int (*)(unsigned int, struct rlimit __user *))SYS(getrlimit);
519 int (*sys_setrlimit)(unsigned int, struct rlimit __user *) =
520 (int (*)(unsigned int, struct rlimit __user *))SYS(setrlimit);
521
522 if (resource > RLIMIT_SOL_VMEM)
523 return -EINVAL;
524 switch (resource) {
525 case RLIMIT_SOL_NOFILE: resource = RLIMIT_NOFILE; break;
526 case RLIMIT_SOL_VMEM: resource = RLIMIT_AS; break;
527 default: break;
528 }
529 if (get_user (r.rlim_cur, &rlim->rlim_cur) ||
530 __get_user (r.rlim_max, &rlim->rlim_max))
531 return -EFAULT;
532 set_fs (KERNEL_DS);
533 ret = sys_getrlimit(resource, &rold);
534 if (!ret) {
535 if (r.rlim_cur == RLIM_SOL_INFINITY32)
536 r.rlim_cur = RLIM_INFINITY;
537 else if (r.rlim_cur == RLIM_SOL_SAVED_CUR32)
538 r.rlim_cur = rold.rlim_cur;
539 else if (r.rlim_cur == RLIM_SOL_SAVED_MAX32)
540 r.rlim_cur = rold.rlim_max;
541 if (r.rlim_max == RLIM_SOL_INFINITY32)
542 r.rlim_max = RLIM_INFINITY;
543 else if (r.rlim_max == RLIM_SOL_SAVED_CUR32)
544 r.rlim_max = rold.rlim_cur;
545 else if (r.rlim_max == RLIM_SOL_SAVED_MAX32)
546 r.rlim_max = rold.rlim_max;
547 ret = sys_setrlimit(resource, &r);
548 }
549 set_fs (old_fs);
550 return ret;
551}
552
553asmlinkage int solaris_getrlimit64(unsigned int resource, struct rlimit __user *rlim)
554{
555 struct rlimit r;
556 int ret;
557 mm_segment_t old_fs = get_fs ();
558 int (*sys_getrlimit)(unsigned int, struct rlimit __user *) =
559 (int (*)(unsigned int, struct rlimit __user *))SYS(getrlimit);
560
561 if (resource > RLIMIT_SOL_VMEM)
562 return -EINVAL;
563 switch (resource) {
564 case RLIMIT_SOL_NOFILE: resource = RLIMIT_NOFILE; break;
565 case RLIMIT_SOL_VMEM: resource = RLIMIT_AS; break;
566 default: break;
567 }
568 set_fs (KERNEL_DS);
569 ret = sys_getrlimit(resource, &r);
570 set_fs (old_fs);
571 if (!ret) {
572 if (r.rlim_cur == RLIM_INFINITY)
573 r.rlim_cur = RLIM_SOL_INFINITY;
574 if (r.rlim_max == RLIM_INFINITY)
575 r.rlim_max = RLIM_SOL_INFINITY;
576 ret = put_user (r.rlim_cur, &rlim->rlim_cur);
577 ret |= __put_user (r.rlim_max, &rlim->rlim_max);
578 }
579 return ret;
580}
581
582asmlinkage int solaris_setrlimit64(unsigned int resource, struct rlimit __user *rlim)
583{
584 struct rlimit r, rold;
585 int ret;
586 mm_segment_t old_fs = get_fs ();
587 int (*sys_getrlimit)(unsigned int, struct rlimit __user *) =
588 (int (*)(unsigned int, struct rlimit __user *))SYS(getrlimit);
589 int (*sys_setrlimit)(unsigned int, struct rlimit __user *) =
590 (int (*)(unsigned int, struct rlimit __user *))SYS(setrlimit);
591
592 if (resource > RLIMIT_SOL_VMEM)
593 return -EINVAL;
594 switch (resource) {
595 case RLIMIT_SOL_NOFILE: resource = RLIMIT_NOFILE; break;
596 case RLIMIT_SOL_VMEM: resource = RLIMIT_AS; break;
597 default: break;
598 }
599 if (get_user (r.rlim_cur, &rlim->rlim_cur) ||
600 __get_user (r.rlim_max, &rlim->rlim_max))
601 return -EFAULT;
602 set_fs (KERNEL_DS);
603 ret = sys_getrlimit(resource, &rold);
604 if (!ret) {
605 if (r.rlim_cur == RLIM_SOL_INFINITY)
606 r.rlim_cur = RLIM_INFINITY;
607 else if (r.rlim_cur == RLIM_SOL_SAVED_CUR)
608 r.rlim_cur = rold.rlim_cur;
609 else if (r.rlim_cur == RLIM_SOL_SAVED_MAX)
610 r.rlim_cur = rold.rlim_max;
611 if (r.rlim_max == RLIM_SOL_INFINITY)
612 r.rlim_max = RLIM_INFINITY;
613 else if (r.rlim_max == RLIM_SOL_SAVED_CUR)
614 r.rlim_max = rold.rlim_cur;
615 else if (r.rlim_max == RLIM_SOL_SAVED_MAX)
616 r.rlim_max = rold.rlim_max;
617 ret = sys_setrlimit(resource, &r);
618 }
619 set_fs (old_fs);
620 return ret;
621}
622
623struct sol_ntptimeval {
624 struct compat_timeval time;
625 s32 maxerror;
626 s32 esterror;
627};
628
629struct sol_timex {
630 u32 modes;
631 s32 offset;
632 s32 freq;
633 s32 maxerror;
634 s32 esterror;
635 s32 status;
636 s32 constant;
637 s32 precision;
638 s32 tolerance;
639 s32 ppsfreq;
640 s32 jitter;
641 s32 shift;
642 s32 stabil;
643 s32 jitcnt;
644 s32 calcnt;
645 s32 errcnt;
646 s32 stbcnt;
647};
648
649asmlinkage int solaris_ntp_gettime(struct sol_ntptimeval __user *ntp)
650{
651 int (*sys_adjtimex)(struct timex __user *) =
652 (int (*)(struct timex __user *))SYS(adjtimex);
653 struct timex t;
654 int ret;
655 mm_segment_t old_fs = get_fs();
656
657 set_fs(KERNEL_DS);
658 t.modes = 0;
659 ret = sys_adjtimex(&t);
660 set_fs(old_fs);
661 if (ret < 0)
662 return ret;
663 ret = put_user (t.time.tv_sec, &ntp->time.tv_sec);
664 ret |= __put_user (t.time.tv_usec, &ntp->time.tv_usec);
665 ret |= __put_user (t.maxerror, &ntp->maxerror);
666 ret |= __put_user (t.esterror, &ntp->esterror);
667 return ret;
668}
669
670asmlinkage int solaris_ntp_adjtime(struct sol_timex __user *txp)
671{
672 int (*sys_adjtimex)(struct timex __user *) =
673 (int (*)(struct timex __user *))SYS(adjtimex);
674 struct timex t;
675 int ret, err;
676 mm_segment_t old_fs = get_fs();
677
678 ret = get_user (t.modes, &txp->modes);
679 ret |= __get_user (t.offset, &txp->offset);
680 ret |= __get_user (t.freq, &txp->freq);
681 ret |= __get_user (t.maxerror, &txp->maxerror);
682 ret |= __get_user (t.esterror, &txp->esterror);
683 ret |= __get_user (t.status, &txp->status);
684 ret |= __get_user (t.constant, &txp->constant);
685 set_fs(KERNEL_DS);
686 ret = sys_adjtimex(&t);
687 set_fs(old_fs);
688 if (ret < 0)
689 return ret;
690 err = put_user (t.offset, &txp->offset);
691 err |= __put_user (t.freq, &txp->freq);
692 err |= __put_user (t.maxerror, &txp->maxerror);
693 err |= __put_user (t.esterror, &txp->esterror);
694 err |= __put_user (t.status, &txp->status);
695 err |= __put_user (t.constant, &txp->constant);
696 err |= __put_user (t.precision, &txp->precision);
697 err |= __put_user (t.tolerance, &txp->tolerance);
698 err |= __put_user (t.ppsfreq, &txp->ppsfreq);
699 err |= __put_user (t.jitter, &txp->jitter);
700 err |= __put_user (t.shift, &txp->shift);
701 err |= __put_user (t.stabil, &txp->stabil);
702 err |= __put_user (t.jitcnt, &txp->jitcnt);
703 err |= __put_user (t.calcnt, &txp->calcnt);
704 err |= __put_user (t.errcnt, &txp->errcnt);
705 err |= __put_user (t.stbcnt, &txp->stbcnt);
706 if (err)
707 return -EFAULT;
708 return ret;
709}
710
711asmlinkage int do_sol_unimplemented(struct pt_regs *regs)
712{
713 printk ("Unimplemented Solaris syscall %d %08x %08x %08x %08x\n",
714 (int)regs->u_regs[UREG_G1],
715 (int)regs->u_regs[UREG_I0],
716 (int)regs->u_regs[UREG_I1],
717 (int)regs->u_regs[UREG_I2],
718 (int)regs->u_regs[UREG_I3]);
719 return -ENOSYS;
720}
721
722asmlinkage void solaris_register(void)
723{
724 set_personality(PER_SVR4);
725}
726
727extern long solaris_to_linux_signals[], linux_to_solaris_signals[];
728
729struct exec_domain solaris_exec_domain = {
730 .name = "Solaris",
731 .handler = NULL,
732 .pers_low = 1, /* PER_SVR4 personality */
733 .pers_high = 1,
734 .signal_map = solaris_to_linux_signals,
735 .signal_invmap =linux_to_solaris_signals,
736 .module = THIS_MODULE,
737 .next = NULL
738};
739
740extern int init_socksys(void);
741
742MODULE_AUTHOR("Jakub Jelinek (jj@ultra.linux.cz), Patrik Rak (prak3264@ss1000.ms.mff.cuni.cz)");
743MODULE_DESCRIPTION("Solaris binary emulation module");
744MODULE_LICENSE("GPL");
745
746extern u32 tl0_solaris[8];
747#define update_ttable(x) \
748 tl0_solaris[3] = (((long)(x) - (long)tl0_solaris - 3) >> 2) | 0x40000000; \
749 wmb(); \
750 __asm__ __volatile__ ("flush %0" : : "r" (&tl0_solaris[3]))
751
752extern u32 solaris_sparc_syscall[];
753extern u32 solaris_syscall[];
754extern void cleanup_socksys(void);
755
756extern u32 entry64_personality_patch;
757
758static int __init solaris_init(void)
759{
760 int ret;
761
762 SOLDD(("Solaris module at %p\n", solaris_sparc_syscall));
763 register_exec_domain(&solaris_exec_domain);
764 if ((ret = init_socksys())) {
765 unregister_exec_domain(&solaris_exec_domain);
766 return ret;
767 }
768 update_ttable(solaris_sparc_syscall);
769 entry64_personality_patch |=
770 (offsetof(struct task_struct, personality) +
771 (sizeof(unsigned long) - 1));
772 wmb();
773 __asm__ __volatile__("flush %0"
774 : : "r" (&entry64_personality_patch));
775 return 0;
776}
777
778static void __exit solaris_exit(void)
779{
780 update_ttable(solaris_syscall);
781 cleanup_socksys();
782 unregister_exec_domain(&solaris_exec_domain);
783}
784
785module_init(solaris_init);
786module_exit(solaris_exit);
diff --git a/arch/sparc64/solaris/signal.c b/arch/sparc64/solaris/signal.c
deleted file mode 100644
index de10c9716cfb..000000000000
--- a/arch/sparc64/solaris/signal.c
+++ /dev/null
@@ -1,429 +0,0 @@
1/* $Id: signal.c,v 1.7 2000/09/05 21:44:54 davem Exp $
2 * signal.c: Signal emulation for Solaris
3 *
4 * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
5 */
6
7#include <linux/types.h>
8#include <linux/errno.h>
9
10#include <asm/uaccess.h>
11#include <asm/svr4.h>
12#include <asm/string.h>
13
14#include "conv.h"
15#include "signal.h"
16
17#define _S(nr) (1L<<((nr)-1))
18
19#define _BLOCKABLE (~(_S(SIGKILL) | _S(SIGSTOP)))
20
21long linux_to_solaris_signals[] = {
22 0,
23 SOLARIS_SIGHUP, SOLARIS_SIGINT,
24 SOLARIS_SIGQUIT, SOLARIS_SIGILL,
25 SOLARIS_SIGTRAP, SOLARIS_SIGIOT,
26 SOLARIS_SIGEMT, SOLARIS_SIGFPE,
27 SOLARIS_SIGKILL, SOLARIS_SIGBUS,
28 SOLARIS_SIGSEGV, SOLARIS_SIGSYS,
29 SOLARIS_SIGPIPE, SOLARIS_SIGALRM,
30 SOLARIS_SIGTERM, SOLARIS_SIGURG,
31 SOLARIS_SIGSTOP, SOLARIS_SIGTSTP,
32 SOLARIS_SIGCONT, SOLARIS_SIGCLD,
33 SOLARIS_SIGTTIN, SOLARIS_SIGTTOU,
34 SOLARIS_SIGPOLL, SOLARIS_SIGXCPU,
35 SOLARIS_SIGXFSZ, SOLARIS_SIGVTALRM,
36 SOLARIS_SIGPROF, SOLARIS_SIGWINCH,
37 SOLARIS_SIGUSR1, SOLARIS_SIGUSR1,
38 SOLARIS_SIGUSR2, -1,
39};
40
41long solaris_to_linux_signals[] = {
42 0,
43 SIGHUP, SIGINT, SIGQUIT, SIGILL,
44 SIGTRAP, SIGIOT, SIGEMT, SIGFPE,
45 SIGKILL, SIGBUS, SIGSEGV, SIGSYS,
46 SIGPIPE, SIGALRM, SIGTERM, SIGUSR1,
47 SIGUSR2, SIGCHLD, -1, SIGWINCH,
48 SIGURG, SIGPOLL, SIGSTOP, SIGTSTP,
49 SIGCONT, SIGTTIN, SIGTTOU, SIGVTALRM,
50 SIGPROF, SIGXCPU, SIGXFSZ, -1,
51 -1, -1, -1, -1,
52 -1, -1, -1, -1,
53 -1, -1, -1, -1,
54};
55
56static inline long mapsig(long sig)
57{
58 if ((unsigned long)sig > SOLARIS_NSIGNALS)
59 return -EINVAL;
60 return solaris_to_linux_signals[sig];
61}
62
63asmlinkage int solaris_kill(int pid, int sig)
64{
65 int (*sys_kill)(int,int) =
66 (int (*)(int,int))SYS(kill);
67 int s = mapsig(sig);
68
69 if (s < 0) return s;
70 return sys_kill(pid, s);
71}
72
73static long sig_handler(int sig, u32 arg, int one_shot)
74{
75 struct sigaction sa, old;
76 int ret;
77 mm_segment_t old_fs = get_fs();
78 int (*sys_sigaction)(int,struct sigaction __user *,struct sigaction __user *) =
79 (int (*)(int,struct sigaction __user *,struct sigaction __user *))SYS(sigaction);
80
81 sigemptyset(&sa.sa_mask);
82 sa.sa_restorer = NULL;
83 sa.sa_handler = (__sighandler_t)A(arg);
84 sa.sa_flags = 0;
85 if (one_shot) sa.sa_flags = SA_ONESHOT | SA_NOMASK;
86 set_fs (KERNEL_DS);
87 ret = sys_sigaction(sig, (void __user *)&sa, (void __user *)&old);
88 set_fs (old_fs);
89 if (ret < 0) return ret;
90 return (u32)(unsigned long)old.sa_handler;
91}
92
93static inline long solaris_signal(int sig, u32 arg)
94{
95 return sig_handler (sig, arg, 1);
96}
97
98static long solaris_sigset(int sig, u32 arg)
99{
100 if (arg != 2) /* HOLD */ {
101 spin_lock_irq(&current->sighand->siglock);
102 sigdelsetmask(&current->blocked, _S(sig));
103 recalc_sigpending();
104 spin_unlock_irq(&current->sighand->siglock);
105 return sig_handler (sig, arg, 0);
106 } else {
107 spin_lock_irq(&current->sighand->siglock);
108 sigaddsetmask(&current->blocked, (_S(sig) & ~_BLOCKABLE));
109 recalc_sigpending();
110 spin_unlock_irq(&current->sighand->siglock);
111 return 0;
112 }
113}
114
115static inline long solaris_sighold(int sig)
116{
117 return solaris_sigset(sig, 2);
118}
119
120static inline long solaris_sigrelse(int sig)
121{
122 spin_lock_irq(&current->sighand->siglock);
123 sigdelsetmask(&current->blocked, _S(sig));
124 recalc_sigpending();
125 spin_unlock_irq(&current->sighand->siglock);
126 return 0;
127}
128
129static inline long solaris_sigignore(int sig)
130{
131 return sig_handler(sig, (u32)(unsigned long)SIG_IGN, 0);
132}
133
134static inline long solaris_sigpause(int sig)
135{
136 printk ("Need to support solaris sigpause\n");
137 return -ENOSYS;
138}
139
140asmlinkage long solaris_sigfunc(int sig, u32 arg)
141{
142 int func = sig & ~0xff;
143
144 sig = mapsig(sig & 0xff);
145 if (sig < 0) return sig;
146 switch (func) {
147 case 0: return solaris_signal(sig, arg);
148 case 0x100: return solaris_sigset(sig, arg);
149 case 0x200: return solaris_sighold(sig);
150 case 0x400: return solaris_sigrelse(sig);
151 case 0x800: return solaris_sigignore(sig);
152 case 0x1000: return solaris_sigpause(sig);
153 }
154 return -EINVAL;
155}
156
157typedef struct {
158 u32 __sigbits[4];
159} sol_sigset_t;
160
161static inline int mapin(u32 *p, sigset_t *q)
162{
163 int i;
164 u32 x;
165 int sig;
166
167 sigemptyset(q);
168 x = p[0];
169 for (i = 1; i <= SOLARIS_NSIGNALS; i++) {
170 if (x & 1) {
171 sig = solaris_to_linux_signals[i];
172 if (sig == -1)
173 return -EINVAL;
174 sigaddsetmask(q, (1L << (sig - 1)));
175 }
176 x >>= 1;
177 if (i == 32)
178 x = p[1];
179 }
180 return 0;
181}
182
183static inline int mapout(sigset_t *q, u32 *p)
184{
185 int i;
186 int sig;
187
188 p[0] = 0;
189 p[1] = 0;
190 for (i = 1; i <= 32; i++) {
191 if (sigismember(q, sigmask(i))) {
192 sig = linux_to_solaris_signals[i];
193 if (sig == -1)
194 return -EINVAL;
195 if (sig > 32)
196 p[1] |= 1L << (sig - 33);
197 else
198 p[0] |= 1L << (sig - 1);
199 }
200 }
201 return 0;
202}
203
204asmlinkage int solaris_sigprocmask(int how, u32 in, u32 out)
205{
206 sigset_t in_s, *ins, out_s, *outs;
207 mm_segment_t old_fs = get_fs();
208 int ret;
209 int (*sys_sigprocmask)(int,sigset_t __user *,sigset_t __user *) =
210 (int (*)(int,sigset_t __user *,sigset_t __user *))SYS(sigprocmask);
211
212 ins = NULL; outs = NULL;
213 if (in) {
214 u32 tmp[2];
215
216 if (copy_from_user (tmp, (void __user *)A(in), 2*sizeof(u32)))
217 return -EFAULT;
218 ins = &in_s;
219 if (mapin (tmp, ins)) return -EINVAL;
220 }
221 if (out) outs = &out_s;
222 set_fs (KERNEL_DS);
223 ret = sys_sigprocmask((how == 3) ? SIG_SETMASK : how,
224 (void __user *)ins, (void __user *)outs);
225 set_fs (old_fs);
226 if (ret) return ret;
227 if (out) {
228 u32 tmp[4];
229
230 tmp[2] = 0; tmp[3] = 0;
231 if (mapout (outs, tmp)) return -EINVAL;
232 if (copy_to_user((void __user *)A(out), tmp, 4*sizeof(u32)))
233 return -EFAULT;
234 }
235 return 0;
236}
237
238asmlinkage long do_sol_sigsuspend(u32 mask)
239{
240 sigset_t s;
241 u32 tmp[2];
242
243 if (copy_from_user (tmp, (sol_sigset_t __user *)A(mask), 2*sizeof(u32)))
244 return -EFAULT;
245 if (mapin (tmp, &s)) return -EINVAL;
246 return (long)s.sig[0];
247}
248
249struct sol_sigaction {
250 int sa_flags;
251 u32 sa_handler;
252 u32 sa_mask[4];
253 int sa_resv[2];
254};
255
256asmlinkage int solaris_sigaction(int sig, u32 act, u32 old)
257{
258 u32 tmp, tmp2[4];
259 struct sigaction s, s2;
260 int ret;
261 mm_segment_t old_fs = get_fs();
262 struct sol_sigaction __user *p = (void __user *)A(old);
263 int (*sys_sigaction)(int,struct sigaction __user *,struct sigaction __user *) =
264 (int (*)(int,struct sigaction __user *,struct sigaction __user *))SYS(sigaction);
265
266 sig = mapsig(sig);
267 if (sig < 0) {
268 /* We cheat a little bit for Solaris only signals */
269 if (old && clear_user(p, sizeof(struct sol_sigaction)))
270 return -EFAULT;
271 return 0;
272 }
273 if (act) {
274 if (get_user (tmp, &p->sa_flags))
275 return -EFAULT;
276 s.sa_flags = 0;
277 if (tmp & SOLARIS_SA_ONSTACK) s.sa_flags |= SA_STACK;
278 if (tmp & SOLARIS_SA_RESTART) s.sa_flags |= SA_RESTART;
279 if (tmp & SOLARIS_SA_NODEFER) s.sa_flags |= SA_NOMASK;
280 if (tmp & SOLARIS_SA_RESETHAND) s.sa_flags |= SA_ONESHOT;
281 if (tmp & SOLARIS_SA_NOCLDSTOP) s.sa_flags |= SA_NOCLDSTOP;
282 if (get_user (tmp, &p->sa_handler) ||
283 copy_from_user (tmp2, &p->sa_mask, 2*sizeof(u32)))
284 return -EFAULT;
285 s.sa_handler = (__sighandler_t)A(tmp);
286 if (mapin (tmp2, &s.sa_mask)) return -EINVAL;
287 s.sa_restorer = NULL;
288 }
289 set_fs(KERNEL_DS);
290 ret = sys_sigaction(sig, act ? (void __user *)&s : NULL,
291 old ? (void __user *)&s2 : NULL);
292 set_fs(old_fs);
293 if (ret) return ret;
294 if (old) {
295 if (mapout (&s2.sa_mask, tmp2)) return -EINVAL;
296 tmp = 0; tmp2[2] = 0; tmp2[3] = 0;
297 if (s2.sa_flags & SA_STACK) tmp |= SOLARIS_SA_ONSTACK;
298 if (s2.sa_flags & SA_RESTART) tmp |= SOLARIS_SA_RESTART;
299 if (s2.sa_flags & SA_NOMASK) tmp |= SOLARIS_SA_NODEFER;
300 if (s2.sa_flags & SA_ONESHOT) tmp |= SOLARIS_SA_RESETHAND;
301 if (s2.sa_flags & SA_NOCLDSTOP) tmp |= SOLARIS_SA_NOCLDSTOP;
302 if (put_user (tmp, &p->sa_flags) ||
303 __put_user ((u32)(unsigned long)s2.sa_handler, &p->sa_handler) ||
304 copy_to_user (&p->sa_mask, tmp2, 4*sizeof(u32)))
305 return -EFAULT;
306 }
307 return 0;
308}
309
310asmlinkage int solaris_sigpending(int which, u32 set)
311{
312 sigset_t s;
313 u32 tmp[4];
314 switch (which) {
315 case 1: /* sigpending */
316 spin_lock_irq(&current->sighand->siglock);
317 sigandsets(&s, &current->blocked, &current->pending.signal);
318 recalc_sigpending();
319 spin_unlock_irq(&current->sighand->siglock);
320 break;
321 case 2: /* sigfillset - I just set signals which have linux equivalents */
322 sigfillset(&s);
323 break;
324 default: return -EINVAL;
325 }
326 if (mapout (&s, tmp)) return -EINVAL;
327 tmp[2] = 0; tmp[3] = 0;
328 if (copy_to_user ((u32 __user *)A(set), tmp, sizeof(tmp)))
329 return -EFAULT;
330 return 0;
331}
332
333asmlinkage int solaris_wait(u32 stat_loc)
334{
335 unsigned __user *p = (unsigned __user *)A(stat_loc);
336 int (*sys_wait4)(pid_t,unsigned __user *, int, struct rusage __user *) =
337 (int (*)(pid_t,unsigned __user *, int, struct rusage __user *))SYS(wait4);
338 int ret, status;
339
340 ret = sys_wait4(-1, p, WUNTRACED, NULL);
341 if (ret >= 0 && stat_loc) {
342 if (get_user (status, p))
343 return -EFAULT;
344 if (((status - 1) & 0xffff) < 0xff)
345 status = linux_to_solaris_signals[status & 0x7f] & 0x7f;
346 else if ((status & 0xff) == 0x7f)
347 status = (linux_to_solaris_signals[(status >> 8) & 0xff] << 8) | 0x7f;
348 if (__put_user (status, p))
349 return -EFAULT;
350 }
351 return ret;
352}
353
354asmlinkage int solaris_waitid(int idtype, s32 pid, u32 info, int options)
355{
356 int (*sys_wait4)(pid_t,unsigned __user *, int, struct rusage __user *) =
357 (int (*)(pid_t,unsigned __user *, int, struct rusage __user *))SYS(wait4);
358 int opts, status, ret;
359
360 switch (idtype) {
361 case 0: /* P_PID */ break;
362 case 1: /* P_PGID */ pid = -pid; break;
363 case 7: /* P_ALL */ pid = -1; break;
364 default: return -EINVAL;
365 }
366 opts = 0;
367 if (options & SOLARIS_WUNTRACED) opts |= WUNTRACED;
368 if (options & SOLARIS_WNOHANG) opts |= WNOHANG;
369 current->state = TASK_RUNNING;
370 ret = sys_wait4(pid, (unsigned int __user *)A(info), opts, NULL);
371 if (ret < 0) return ret;
372 if (info) {
373 struct sol_siginfo __user *s = (void __user *)A(info);
374
375 if (get_user (status, (unsigned int __user *)A(info)))
376 return -EFAULT;
377
378 if (__put_user (SOLARIS_SIGCLD, &s->si_signo) ||
379 __put_user (ret, &s->_data._proc._pid))
380 return -EFAULT;
381
382 switch (status & 0xff) {
383 case 0: ret = SOLARIS_CLD_EXITED;
384 status = (status >> 8) & 0xff;
385 break;
386 case 0x7f:
387 status = (status >> 8) & 0xff;
388 switch (status) {
389 case SIGSTOP:
390 case SIGTSTP: ret = SOLARIS_CLD_STOPPED;
391 default: ret = SOLARIS_CLD_EXITED;
392 }
393 status = linux_to_solaris_signals[status];
394 break;
395 default:
396 if (status & 0x80) ret = SOLARIS_CLD_DUMPED;
397 else ret = SOLARIS_CLD_KILLED;
398 status = linux_to_solaris_signals[status & 0x7f];
399 break;
400 }
401
402 if (__put_user (ret, &s->si_code) ||
403 __put_user (status, &s->_data._proc._pdata._cld._status))
404 return -EFAULT;
405 }
406 return 0;
407}
408
409extern int svr4_setcontext(svr4_ucontext_t *c, struct pt_regs *regs);
410extern int svr4_getcontext(svr4_ucontext_t *c, struct pt_regs *regs);
411
412asmlinkage int solaris_context(struct pt_regs *regs)
413{
414 switch ((unsigned)regs->u_regs[UREG_I0]) {
415 case 0: /* getcontext */
416 return svr4_getcontext((svr4_ucontext_t *)(long)(u32)regs->u_regs[UREG_I1], regs);
417 case 1: /* setcontext */
418 return svr4_setcontext((svr4_ucontext_t *)(long)(u32)regs->u_regs[UREG_I1], regs);
419 default:
420 return -EINVAL;
421
422 }
423}
424
425asmlinkage int solaris_sigaltstack(u32 ss, u32 oss)
426{
427/* XXX Implement this soon */
428 return 0;
429}
diff --git a/arch/sparc64/solaris/signal.h b/arch/sparc64/solaris/signal.h
deleted file mode 100644
index e91570803050..000000000000
--- a/arch/sparc64/solaris/signal.h
+++ /dev/null
@@ -1,108 +0,0 @@
1/* $Id: signal.h,v 1.3 1998/04/12 06:20:33 davem Exp $
2 * signal.h: Signal emulation for Solaris
3 *
4 * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
5 */
6
7#define SOLARIS_SIGHUP 1
8#define SOLARIS_SIGINT 2
9#define SOLARIS_SIGQUIT 3
10#define SOLARIS_SIGILL 4
11#define SOLARIS_SIGTRAP 5
12#define SOLARIS_SIGIOT 6
13#define SOLARIS_SIGEMT 7
14#define SOLARIS_SIGFPE 8
15#define SOLARIS_SIGKILL 9
16#define SOLARIS_SIGBUS 10
17#define SOLARIS_SIGSEGV 11
18#define SOLARIS_SIGSYS 12
19#define SOLARIS_SIGPIPE 13
20#define SOLARIS_SIGALRM 14
21#define SOLARIS_SIGTERM 15
22#define SOLARIS_SIGUSR1 16
23#define SOLARIS_SIGUSR2 17
24#define SOLARIS_SIGCLD 18
25#define SOLARIS_SIGPWR 19
26#define SOLARIS_SIGWINCH 20
27#define SOLARIS_SIGURG 21
28#define SOLARIS_SIGPOLL 22
29#define SOLARIS_SIGSTOP 23
30#define SOLARIS_SIGTSTP 24
31#define SOLARIS_SIGCONT 25
32#define SOLARIS_SIGTTIN 26
33#define SOLARIS_SIGTTOU 27
34#define SOLARIS_SIGVTALRM 28
35#define SOLARIS_SIGPROF 29
36#define SOLARIS_SIGXCPU 30
37#define SOLARIS_SIGXFSZ 31
38#define SOLARIS_SIGWAITING 32
39#define SOLARIS_SIGLWP 33
40#define SOLARIS_SIGFREEZE 34
41#define SOLARIS_SIGTHAW 35
42#define SOLARIS_SIGCANCEL 36
43#define SOLARIS_SIGRTMIN 37
44#define SOLARIS_SIGRTMAX 44
45#define SOLARIS_NSIGNALS 44
46
47
48#define SOLARIS_SA_ONSTACK 1
49#define SOLARIS_SA_RESETHAND 2
50#define SOLARIS_SA_RESTART 4
51#define SOLARIS_SA_SIGINFO 8
52#define SOLARIS_SA_NODEFER 16
53#define SOLARIS_SA_NOCLDWAIT 0x10000
54#define SOLARIS_SA_NOCLDSTOP 0x20000
55
56struct sol_siginfo {
57 int si_signo;
58 int si_code;
59 int si_errno;
60 union {
61 char pad[128-3*sizeof(int)];
62 struct {
63 s32 _pid;
64 union {
65 struct {
66 s32 _uid;
67 s32 _value;
68 } _kill;
69 struct {
70 s32 _utime;
71 int _status;
72 s32 _stime;
73 } _cld;
74 } _pdata;
75 } _proc;
76 struct { /* SIGSEGV, SIGBUS, SIGILL and SIGFPE */
77 u32 _addr;
78 int _trapno;
79 } _fault;
80 struct { /* SIGPOLL, SIGXFSZ */
81 int _fd;
82 s32 _band;
83 } _file;
84 } _data;
85};
86
87#define SOLARIS_WUNTRACED 0x04
88#define SOLARIS_WNOHANG 0x40
89#define SOLARIS_WEXITED 0x01
90#define SOLARIS_WTRAPPED 0x02
91#define SOLARIS_WSTOPPED WUNTRACED
92#define SOLARIS_WCONTINUED 0x08
93#define SOLARIS_WNOWAIT 0x80
94
95#define SOLARIS_TRAP_BRKPT 1
96#define SOLARIS_TRAP_TRACE 2
97#define SOLARIS_CLD_EXITED 1
98#define SOLARIS_CLD_KILLED 2
99#define SOLARIS_CLD_DUMPED 3
100#define SOLARIS_CLD_TRAPPED 4
101#define SOLARIS_CLD_STOPPED 5
102#define SOLARIS_CLD_CONTINUED 6
103#define SOLARIS_POLL_IN 1
104#define SOLARIS_POLL_OUT 2
105#define SOLARIS_POLL_MSG 3
106#define SOLARIS_POLL_ERR 4
107#define SOLARIS_POLL_PRI 5
108#define SOLARIS_POLL_HUP 6
diff --git a/arch/sparc64/solaris/socket.c b/arch/sparc64/solaris/socket.c
deleted file mode 100644
index cc69847cf240..000000000000
--- a/arch/sparc64/solaris/socket.c
+++ /dev/null
@@ -1,461 +0,0 @@
1/* $Id: socket.c,v 1.6 2002/02/08 03:57:14 davem Exp $
2 * socket.c: Socket syscall emulation for Solaris 2.6+
3 *
4 * Copyright (C) 1998 Jakub Jelinek (jj@ultra.linux.cz)
5 *
6 * 1999-08-19 Fixed socketpair code
7 * Jason Rappleye (rappleye@ccr.buffalo.edu)
8 */
9
10#include <linux/types.h>
11#include <linux/mm.h>
12#include <linux/slab.h>
13#include <linux/socket.h>
14#include <linux/file.h>
15#include <linux/net.h>
16#include <linux/compat.h>
17#include <net/compat.h>
18#include <net/sock.h>
19
20#include <asm/uaccess.h>
21#include <asm/string.h>
22#include <asm/oplib.h>
23#include <asm/idprom.h>
24
25#include "conv.h"
26
27#define SOCK_SOL_STREAM 2
28#define SOCK_SOL_DGRAM 1
29#define SOCK_SOL_RAW 4
30#define SOCK_SOL_RDM 5
31#define SOCK_SOL_SEQPACKET 6
32
33#define SOL_SO_SNDLOWAT 0x1003
34#define SOL_SO_RCVLOWAT 0x1004
35#define SOL_SO_SNDTIMEO 0x1005
36#define SOL_SO_RCVTIMEO 0x1006
37#define SOL_SO_STATE 0x2000
38
39#define SOL_SS_NDELAY 0x040
40#define SOL_SS_NONBLOCK 0x080
41#define SOL_SS_ASYNC 0x100
42
43#define SO_STATE 0x000e
44
45static int socket_check(int family, int type)
46{
47 if (family != PF_UNIX && family != PF_INET)
48 return -ESOCKTNOSUPPORT;
49 switch (type) {
50 case SOCK_SOL_STREAM: type = SOCK_STREAM; break;
51 case SOCK_SOL_DGRAM: type = SOCK_DGRAM; break;
52 case SOCK_SOL_RAW: type = SOCK_RAW; break;
53 case SOCK_SOL_RDM: type = SOCK_RDM; break;
54 case SOCK_SOL_SEQPACKET: type = SOCK_SEQPACKET; break;
55 default: return -EINVAL;
56 }
57 return type;
58}
59
60static int solaris_to_linux_sockopt(int optname)
61{
62 switch (optname) {
63 case SOL_SO_SNDLOWAT: optname = SO_SNDLOWAT; break;
64 case SOL_SO_RCVLOWAT: optname = SO_RCVLOWAT; break;
65 case SOL_SO_SNDTIMEO: optname = SO_SNDTIMEO; break;
66 case SOL_SO_RCVTIMEO: optname = SO_RCVTIMEO; break;
67 case SOL_SO_STATE: optname = SO_STATE; break;
68 };
69
70 return optname;
71}
72
73asmlinkage int solaris_socket(int family, int type, int protocol)
74{
75 int (*sys_socket)(int, int, int) =
76 (int (*)(int, int, int))SYS(socket);
77
78 type = socket_check (family, type);
79 if (type < 0) return type;
80 return sys_socket(family, type, protocol);
81}
82
83asmlinkage int solaris_socketpair(int *usockvec)
84{
85 int (*sys_socketpair)(int, int, int, int *) =
86 (int (*)(int, int, int, int *))SYS(socketpair);
87
88 /* solaris socketpair really only takes one arg at the syscall
89 * level, int * usockvec. The libs apparently take care of
90 * making sure that family==AF_UNIX and type==SOCK_STREAM. The
91 * pointer we really want ends up residing in the first (and
92 * supposedly only) argument.
93 */
94
95 return sys_socketpair(AF_UNIX, SOCK_STREAM, 0, (int *)usockvec);
96}
97
98asmlinkage int solaris_bind(int fd, struct sockaddr *addr, int addrlen)
99{
100 int (*sys_bind)(int, struct sockaddr *, int) =
101 (int (*)(int, struct sockaddr *, int))SUNOS(104);
102
103 return sys_bind(fd, addr, addrlen);
104}
105
106asmlinkage int solaris_setsockopt(int fd, int level, int optname, u32 optval, int optlen)
107{
108 int (*sunos_setsockopt)(int, int, int, u32, int) =
109 (int (*)(int, int, int, u32, int))SUNOS(105);
110
111 optname = solaris_to_linux_sockopt(optname);
112 if (optname < 0)
113 return optname;
114 if (optname == SO_STATE)
115 return 0;
116
117 return sunos_setsockopt(fd, level, optname, optval, optlen);
118}
119
120asmlinkage int solaris_getsockopt(int fd, int level, int optname, u32 optval, u32 optlen)
121{
122 int (*sunos_getsockopt)(int, int, int, u32, u32) =
123 (int (*)(int, int, int, u32, u32))SUNOS(118);
124
125 optname = solaris_to_linux_sockopt(optname);
126 if (optname < 0)
127 return optname;
128
129 if (optname == SO_STATE)
130 optname = SOL_SO_STATE;
131
132 return sunos_getsockopt(fd, level, optname, optval, optlen);
133}
134
135asmlinkage int solaris_connect(int fd, struct sockaddr __user *addr, int addrlen)
136{
137 int (*sys_connect)(int, struct sockaddr __user *, int) =
138 (int (*)(int, struct sockaddr __user *, int))SYS(connect);
139
140 return sys_connect(fd, addr, addrlen);
141}
142
143asmlinkage int solaris_accept(int fd, struct sockaddr __user *addr, int __user *addrlen)
144{
145 int (*sys_accept)(int, struct sockaddr __user *, int __user *) =
146 (int (*)(int, struct sockaddr __user *, int __user *))SYS(accept);
147
148 return sys_accept(fd, addr, addrlen);
149}
150
151asmlinkage int solaris_listen(int fd, int backlog)
152{
153 int (*sys_listen)(int, int) =
154 (int (*)(int, int))SUNOS(106);
155
156 return sys_listen(fd, backlog);
157}
158
159asmlinkage int solaris_shutdown(int fd, int how)
160{
161 int (*sys_shutdown)(int, int) =
162 (int (*)(int, int))SYS(shutdown);
163
164 return sys_shutdown(fd, how);
165}
166
167#define MSG_SOL_OOB 0x1
168#define MSG_SOL_PEEK 0x2
169#define MSG_SOL_DONTROUTE 0x4
170#define MSG_SOL_EOR 0x8
171#define MSG_SOL_CTRUNC 0x10
172#define MSG_SOL_TRUNC 0x20
173#define MSG_SOL_WAITALL 0x40
174#define MSG_SOL_DONTWAIT 0x80
175
176static int solaris_to_linux_msgflags(int flags)
177{
178 int fl = flags & (MSG_OOB|MSG_PEEK|MSG_DONTROUTE);
179
180 if (flags & MSG_SOL_EOR) fl |= MSG_EOR;
181 if (flags & MSG_SOL_CTRUNC) fl |= MSG_CTRUNC;
182 if (flags & MSG_SOL_TRUNC) fl |= MSG_TRUNC;
183 if (flags & MSG_SOL_WAITALL) fl |= MSG_WAITALL;
184 if (flags & MSG_SOL_DONTWAIT) fl |= MSG_DONTWAIT;
185 return fl;
186}
187
188static int linux_to_solaris_msgflags(int flags)
189{
190 int fl = flags & (MSG_OOB|MSG_PEEK|MSG_DONTROUTE);
191
192 if (flags & MSG_EOR) fl |= MSG_SOL_EOR;
193 if (flags & MSG_CTRUNC) fl |= MSG_SOL_CTRUNC;
194 if (flags & MSG_TRUNC) fl |= MSG_SOL_TRUNC;
195 if (flags & MSG_WAITALL) fl |= MSG_SOL_WAITALL;
196 if (flags & MSG_DONTWAIT) fl |= MSG_SOL_DONTWAIT;
197 return fl;
198}
199
200asmlinkage int solaris_recvfrom(int s, char __user *buf, int len, int flags, u32 from, u32 fromlen)
201{
202 int (*sys_recvfrom)(int, void __user *, size_t, unsigned, struct sockaddr __user *, int __user *) =
203 (int (*)(int, void __user *, size_t, unsigned, struct sockaddr __user *, int __user *))SYS(recvfrom);
204
205 return sys_recvfrom(s, buf, len, solaris_to_linux_msgflags(flags), A(from), A(fromlen));
206}
207
208asmlinkage int solaris_recv(int s, char __user *buf, int len, int flags)
209{
210 int (*sys_recvfrom)(int, void __user *, size_t, unsigned, struct sockaddr __user *, int __user *) =
211 (int (*)(int, void __user *, size_t, unsigned, struct sockaddr __user *, int __user *))SYS(recvfrom);
212
213 return sys_recvfrom(s, buf, len, solaris_to_linux_msgflags(flags), NULL, NULL);
214}
215
216asmlinkage int solaris_sendto(int s, char __user *buf, int len, int flags, u32 to, u32 tolen)
217{
218 int (*sys_sendto)(int, void __user *, size_t, unsigned, struct sockaddr __user *, int __user *) =
219 (int (*)(int, void __user *, size_t, unsigned, struct sockaddr __user *, int __user *))SYS(sendto);
220
221 return sys_sendto(s, buf, len, solaris_to_linux_msgflags(flags), A(to), A(tolen));
222}
223
224asmlinkage int solaris_send(int s, char *buf, int len, int flags)
225{
226 int (*sys_sendto)(int, void *, size_t, unsigned, struct sockaddr *, int *) =
227 (int (*)(int, void *, size_t, unsigned, struct sockaddr *, int *))SYS(sendto);
228
229 return sys_sendto(s, buf, len, solaris_to_linux_msgflags(flags), NULL, NULL);
230}
231
232asmlinkage int solaris_getpeername(int fd, struct sockaddr *addr, int *addrlen)
233{
234 int (*sys_getpeername)(int, struct sockaddr *, int *) =
235 (int (*)(int, struct sockaddr *, int *))SYS(getpeername);
236
237 return sys_getpeername(fd, addr, addrlen);
238}
239
240asmlinkage int solaris_getsockname(int fd, struct sockaddr *addr, int *addrlen)
241{
242 int (*sys_getsockname)(int, struct sockaddr *, int *) =
243 (int (*)(int, struct sockaddr *, int *))SYS(getsockname);
244
245 return sys_getsockname(fd, addr, addrlen);
246}
247
248/* XXX This really belongs in some header file... -DaveM */
249#define MAX_SOCK_ADDR 128 /* 108 for Unix domain -
250 16 for IP, 16 for IPX,
251 24 for IPv6,
252 about 80 for AX.25 */
253
254struct sol_nmsghdr {
255 u32 msg_name;
256 int msg_namelen;
257 u32 msg_iov;
258 u32 msg_iovlen;
259 u32 msg_control;
260 u32 msg_controllen;
261 u32 msg_flags;
262};
263
264struct sol_cmsghdr {
265 u32 cmsg_len;
266 int cmsg_level;
267 int cmsg_type;
268 unsigned char cmsg_data[0];
269};
270
271static inline int msghdr_from_user32_to_kern(struct msghdr *kmsg,
272 struct sol_nmsghdr __user *umsg)
273{
274 u32 tmp1, tmp2, tmp3;
275 int err;
276
277 err = get_user(tmp1, &umsg->msg_name);
278 err |= __get_user(tmp2, &umsg->msg_iov);
279 err |= __get_user(tmp3, &umsg->msg_control);
280 if (err)
281 return -EFAULT;
282
283 kmsg->msg_name = A(tmp1);
284 kmsg->msg_iov = A(tmp2);
285 kmsg->msg_control = A(tmp3);
286
287 err = get_user(kmsg->msg_namelen, &umsg->msg_namelen);
288 err |= get_user(kmsg->msg_controllen, &umsg->msg_controllen);
289 err |= get_user(kmsg->msg_flags, &umsg->msg_flags);
290
291 kmsg->msg_flags = solaris_to_linux_msgflags(kmsg->msg_flags);
292
293 return err;
294}
295
296asmlinkage int solaris_sendmsg(int fd, struct sol_nmsghdr __user *user_msg, unsigned user_flags)
297{
298 struct socket *sock;
299 char address[MAX_SOCK_ADDR];
300 struct iovec iovstack[UIO_FASTIOV], *iov = iovstack;
301 unsigned char ctl[sizeof(struct cmsghdr) + 20];
302 unsigned char *ctl_buf = ctl;
303 struct msghdr msg_sys;
304 int err, ctl_len, iov_size, total_len;
305
306 err = -EFAULT;
307 if (msghdr_from_user32_to_kern(&msg_sys, user_msg))
308 goto out;
309
310 sock = sockfd_lookup(fd, &err);
311 if (!sock)
312 goto out;
313
314 /* do not move before msg_sys is valid */
315 err = -EMSGSIZE;
316 if (msg_sys.msg_iovlen > UIO_MAXIOV)
317 goto out_put;
318
319 /* Check whether to allocate the iovec area*/
320 err = -ENOMEM;
321 iov_size = msg_sys.msg_iovlen * sizeof(struct iovec);
322 if (msg_sys.msg_iovlen > UIO_FASTIOV) {
323 iov = sock_kmalloc(sock->sk, iov_size, GFP_KERNEL);
324 if (!iov)
325 goto out_put;
326 }
327
328 err = verify_compat_iovec(&msg_sys, iov, address, VERIFY_READ);
329 if (err < 0)
330 goto out_freeiov;
331 total_len = err;
332
333 err = -ENOBUFS;
334 if (msg_sys.msg_controllen > INT_MAX)
335 goto out_freeiov;
336
337 ctl_len = msg_sys.msg_controllen;
338 if (ctl_len) {
339 struct sol_cmsghdr __user *ucmsg = msg_sys.msg_control;
340 unsigned long *kcmsg;
341 compat_size_t cmlen;
342
343 err = -EINVAL;
344 if (ctl_len <= sizeof(compat_size_t))
345 goto out_freeiov;
346
347 if (ctl_len > sizeof(ctl)) {
348 err = -ENOBUFS;
349 ctl_buf = kmalloc(ctl_len, GFP_KERNEL);
350 if (!ctl_buf)
351 goto out_freeiov;
352 }
353 __get_user(cmlen, &ucmsg->cmsg_len);
354 kcmsg = (unsigned long *) ctl_buf;
355 *kcmsg++ = (unsigned long)cmlen;
356 err = -EFAULT;
357 if (copy_from_user(kcmsg, &ucmsg->cmsg_level,
358 ctl_len - sizeof(compat_size_t)))
359 goto out_freectl;
360 msg_sys.msg_control = ctl_buf;
361 }
362 msg_sys.msg_flags = solaris_to_linux_msgflags(user_flags);
363
364 if (sock->file->f_flags & O_NONBLOCK)
365 msg_sys.msg_flags |= MSG_DONTWAIT;
366 err = sock_sendmsg(sock, &msg_sys, total_len);
367
368out_freectl:
369 if (ctl_buf != ctl)
370 sock_kfree_s(sock->sk, ctl_buf, ctl_len);
371out_freeiov:
372 if (iov != iovstack)
373 sock_kfree_s(sock->sk, iov, iov_size);
374out_put:
375 sockfd_put(sock);
376out:
377 return err;
378}
379
380asmlinkage int solaris_recvmsg(int fd, struct sol_nmsghdr __user *user_msg, unsigned int user_flags)
381{
382 struct socket *sock;
383 struct iovec iovstack[UIO_FASTIOV];
384 struct iovec *iov = iovstack;
385 struct msghdr msg_sys;
386 unsigned long cmsg_ptr;
387 int err, iov_size, total_len, len;
388
389 /* kernel mode address */
390 char addr[MAX_SOCK_ADDR];
391
392 /* user mode address pointers */
393 struct sockaddr __user *uaddr;
394 int __user *uaddr_len;
395
396 if (msghdr_from_user32_to_kern(&msg_sys, user_msg))
397 return -EFAULT;
398
399 sock = sockfd_lookup(fd, &err);
400 if (!sock)
401 goto out;
402
403 err = -EMSGSIZE;
404 if (msg_sys.msg_iovlen > UIO_MAXIOV)
405 goto out_put;
406
407 /* Check whether to allocate the iovec area*/
408 err = -ENOMEM;
409 iov_size = msg_sys.msg_iovlen * sizeof(struct iovec);
410 if (msg_sys.msg_iovlen > UIO_FASTIOV) {
411 iov = sock_kmalloc(sock->sk, iov_size, GFP_KERNEL);
412 if (!iov)
413 goto out_put;
414 }
415
416 /*
417 * Save the user-mode address (verify_iovec will change the
418 * kernel msghdr to use the kernel address space)
419 */
420
421 uaddr = (void __user *) msg_sys.msg_name;
422 uaddr_len = &user_msg->msg_namelen;
423 err = verify_compat_iovec(&msg_sys, iov, addr, VERIFY_WRITE);
424 if (err < 0)
425 goto out_freeiov;
426 total_len = err;
427
428 cmsg_ptr = (unsigned long) msg_sys.msg_control;
429 msg_sys.msg_flags = MSG_CMSG_COMPAT;
430
431 if (sock->file->f_flags & O_NONBLOCK)
432 user_flags |= MSG_DONTWAIT;
433
434 err = sock_recvmsg(sock, &msg_sys, total_len, user_flags);
435 if(err < 0)
436 goto out_freeiov;
437
438 len = err;
439
440 if (uaddr != NULL) {
441 err = move_addr_to_user(addr, msg_sys.msg_namelen, uaddr, uaddr_len);
442 if (err < 0)
443 goto out_freeiov;
444 }
445 err = __put_user(linux_to_solaris_msgflags(msg_sys.msg_flags), &user_msg->msg_flags);
446 if (err)
447 goto out_freeiov;
448 err = __put_user((unsigned long)msg_sys.msg_control - cmsg_ptr,
449 &user_msg->msg_controllen);
450 if (err)
451 goto out_freeiov;
452 err = len;
453
454out_freeiov:
455 if (iov != iovstack)
456 sock_kfree_s(sock->sk, iov, iov_size);
457out_put:
458 sockfd_put(sock);
459out:
460 return err;
461}
diff --git a/arch/sparc64/solaris/socksys.c b/arch/sparc64/solaris/socksys.c
deleted file mode 100644
index 7736411f244f..000000000000
--- a/arch/sparc64/solaris/socksys.c
+++ /dev/null
@@ -1,203 +0,0 @@
1/* $Id: socksys.c,v 1.21 2002/02/08 03:57:14 davem Exp $
2 * socksys.c: /dev/inet/ stuff for Solaris emulation.
3 *
4 * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
5 * Copyright (C) 1997, 1998 Patrik Rak (prak3264@ss1000.ms.mff.cuni.cz)
6 * Copyright (C) 1995, 1996 Mike Jagdis (jaggy@purplet.demon.co.uk)
7 */
8
9/*
10 * Dave, _please_ give me specifications on this fscking mess so that I
11 * could at least get it into the state when it wouldn't screw the rest of
12 * the kernel over. socksys.c and timod.c _stink_ and we are not talking
13 * H2S here, it's isopropilmercaptan in concentrations way over LD50. -- AV
14 */
15
16#include <linux/types.h>
17#include <linux/kernel.h>
18#include <linux/sched.h>
19#include <linux/smp.h>
20#include <linux/ioctl.h>
21#include <linux/fs.h>
22#include <linux/file.h>
23#include <linux/init.h>
24#include <linux/poll.h>
25#include <linux/slab.h>
26#include <linux/syscalls.h>
27#include <linux/in.h>
28
29#include <net/sock.h>
30
31#include <asm/uaccess.h>
32#include <asm/termios.h>
33
34#include "conv.h"
35#include "socksys.h"
36
37static int af_inet_protocols[] = {
38IPPROTO_ICMP, IPPROTO_ICMP, IPPROTO_IGMP, IPPROTO_IPIP, IPPROTO_TCP,
39IPPROTO_EGP, IPPROTO_PUP, IPPROTO_UDP, IPPROTO_IDP, IPPROTO_RAW,
400, 0, 0, 0, 0, 0,
41};
42
43#ifndef DEBUG_SOLARIS_KMALLOC
44
45#define mykmalloc kmalloc
46#define mykfree kfree
47
48#else
49
50extern void * mykmalloc(size_t s, gfp_t gfp);
51extern void mykfree(void *);
52
53#endif
54
55static unsigned int (*sock_poll)(struct file *, poll_table *);
56
57static struct file_operations socksys_file_ops = {
58 /* Currently empty */
59};
60
61static int socksys_open(struct inode * inode, struct file * filp)
62{
63 int family, type, protocol, fd;
64 struct dentry *dentry;
65 int (*sys_socket)(int,int,int) =
66 (int (*)(int,int,int))SUNOS(97);
67 struct sol_socket_struct * sock;
68
69 family = ((iminor(inode) >> 4) & 0xf);
70 switch (family) {
71 case AF_UNIX:
72 type = SOCK_STREAM;
73 protocol = 0;
74 break;
75 case AF_INET:
76 protocol = af_inet_protocols[iminor(inode) & 0xf];
77 switch (protocol) {
78 case IPPROTO_TCP: type = SOCK_STREAM; break;
79 case IPPROTO_UDP: type = SOCK_DGRAM; break;
80 default: type = SOCK_RAW; break;
81 }
82 break;
83 default:
84 type = SOCK_RAW;
85 protocol = 0;
86 break;
87 }
88
89 fd = sys_socket(family, type, protocol);
90 if (fd < 0)
91 return fd;
92 /*
93 * N.B. The following operations are not legal!
94 *
95 * No shit. WTF is it supposed to do, anyway?
96 *
97 * Try instead:
98 * d_delete(filp->f_path.dentry), then d_instantiate with sock inode
99 */
100 dentry = filp->f_path.dentry;
101 filp->f_path.dentry = dget(fcheck(fd)->f_path.dentry);
102 filp->f_path.dentry->d_inode->i_rdev = inode->i_rdev;
103 filp->f_path.dentry->d_inode->i_flock = inode->i_flock;
104 SOCKET_I(filp->f_path.dentry->d_inode)->file = filp;
105 filp->f_op = &socksys_file_ops;
106 sock = (struct sol_socket_struct*)
107 mykmalloc(sizeof(struct sol_socket_struct), GFP_KERNEL);
108 if (!sock) return -ENOMEM;
109 SOLDD(("sock=%016lx(%016lx)\n", sock, filp));
110 sock->magic = SOLARIS_SOCKET_MAGIC;
111 sock->modcount = 0;
112 sock->state = TS_UNBND;
113 sock->offset = 0;
114 sock->pfirst = sock->plast = NULL;
115 filp->private_data = sock;
116 SOLDD(("filp->private_data %016lx\n", filp->private_data));
117
118 sys_close(fd);
119 dput(dentry);
120 return 0;
121}
122
123static int socksys_release(struct inode * inode, struct file * filp)
124{
125 struct sol_socket_struct * sock;
126 struct T_primsg *it;
127
128 /* XXX: check this */
129 sock = (struct sol_socket_struct *)filp->private_data;
130 SOLDD(("sock release %016lx(%016lx)\n", sock, filp));
131 it = sock->pfirst;
132 while (it) {
133 struct T_primsg *next = it->next;
134
135 SOLDD(("socksys_release %016lx->%016lx\n", it, next));
136 mykfree((char*)it);
137 it = next;
138 }
139 filp->private_data = NULL;
140 SOLDD(("socksys_release %016lx\n", sock));
141 mykfree((char*)sock);
142 return 0;
143}
144
145static unsigned int socksys_poll(struct file * filp, poll_table * wait)
146{
147 struct inode *ino;
148 unsigned int mask = 0;
149
150 ino=filp->f_path.dentry->d_inode;
151 if (ino && S_ISSOCK(ino->i_mode)) {
152 struct sol_socket_struct *sock;
153 sock = (struct sol_socket_struct*)filp->private_data;
154 if (sock && sock->pfirst) {
155 mask |= POLLIN | POLLRDNORM;
156 if (sock->pfirst->pri == MSG_HIPRI)
157 mask |= POLLPRI;
158 }
159 }
160 if (sock_poll)
161 mask |= (*sock_poll)(filp, wait);
162 return mask;
163}
164
165static const struct file_operations socksys_fops = {
166 .open = socksys_open,
167 .release = socksys_release,
168};
169
170int __init init_socksys(void)
171{
172 int ret;
173 struct file * file;
174 int (*sys_socket)(int,int,int) =
175 (int (*)(int,int,int))SUNOS(97);
176 int (*sys_close)(unsigned int) =
177 (int (*)(unsigned int))SYS(close);
178
179 ret = register_chrdev (30, "socksys", &socksys_fops);
180 if (ret < 0) {
181 printk ("Couldn't register socksys character device\n");
182 return ret;
183 }
184 ret = sys_socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
185 if (ret < 0) {
186 printk ("Couldn't create socket\n");
187 return ret;
188 }
189
190 file = fcheck(ret);
191 /* N.B. Is this valid? Suppose the f_ops are in a module ... */
192 socksys_file_ops = *file->f_op;
193 sys_close(ret);
194 sock_poll = socksys_file_ops.poll;
195 socksys_file_ops.poll = socksys_poll;
196 socksys_file_ops.release = socksys_release;
197 return 0;
198}
199
200void __exit cleanup_socksys(void)
201{
202 unregister_chrdev(30, "socksys");
203}
diff --git a/arch/sparc64/solaris/socksys.h b/arch/sparc64/solaris/socksys.h
deleted file mode 100644
index 5d1b78ec1600..000000000000
--- a/arch/sparc64/solaris/socksys.h
+++ /dev/null
@@ -1,208 +0,0 @@
1/* $Id: socksys.h,v 1.2 1998/03/26 08:46:07 jj Exp $
2 * socksys.h: Definitions for STREAMS modules emulation code.
3 *
4 * Copyright (C) 1998 Patrik Rak (prak3264@ss1000.ms.mff.cuni.cz)
5 */
6
7#define MSG_HIPRI 0x01
8#define MSG_ANY 0x02
9#define MSG_BAND 0x04
10
11#define MORECTL 1
12#define MOREDATA 2
13
14#define TBADADDR 1
15#define TBADOPT 2
16#define TACCES 3
17#define TBADF 4
18#define TNOADDR 5
19#define TOUTSTATE 6
20#define TBADSEQ 7
21#define TSYSERR 8
22#define TLOOK 9
23#define TBADDATA 10
24#define TBUFOVFLW 11
25#define TFLOW 12
26#define TNODATA 13
27#define TNODIS 14
28#define TNOUDERR 15
29#define TBADFLAG 16
30#define TNOREL 17
31#define TNOTSUPPORT 18
32#define TSTATECHNG 19
33
34#define T_CONN_REQ 0
35#define T_CONN_RES 1
36#define T_DISCON_REQ 2
37#define T_DATA_REQ 3
38#define T_EXDATA_REQ 4
39#define T_INFO_REQ 5
40#define T_BIND_REQ 6
41#define T_UNBIND_REQ 7
42#define T_UNITDATA_REQ 8
43#define T_OPTMGMT_REQ 9
44#define T_ORDREL_REQ 10
45
46#define T_CONN_IND 11
47#define T_CONN_CON 12
48#define T_DISCON_IND 13
49#define T_DATA_IND 14
50#define T_EXDATA_IND 15
51#define T_INFO_ACK 16
52#define T_BIND_ACK 17
53#define T_ERROR_ACK 18
54#define T_OK_ACK 19
55#define T_UNITDATA_IND 20
56#define T_UDERROR_IND 21
57#define T_OPTMGMT_ACK 22
58#define T_ORDREL_IND 23
59
60#define T_NEGOTIATE 0x0004
61#define T_FAILURE 0x0040
62
63#define TS_UNBND 0 /* unbound */
64#define TS_WACK_BREQ 1 /* waiting for T_BIND_REQ ack */
65#define TS_WACK_UREQ 2 /* waiting for T_UNBIND_REQ ack */
66#define TS_IDLE 3 /* idle */
67#define TS_WACK_OPTREQ 4 /* waiting for T_OPTMGMT_REQ ack */
68#define TS_WACK_CREQ 5 /* waiting for T_CONN_REQ ack */
69#define TS_WCON_CREQ 6 /* waiting for T_CONN_REQ confirmation */
70#define TS_WRES_CIND 7 /* waiting for T_CONN_IND */
71#define TS_WACK_CRES 8 /* waiting for T_CONN_RES ack */
72#define TS_DATA_XFER 9 /* data transfer */
73#define TS_WIND_ORDREL 10 /* releasing read but not write */
74#define TS_WREQ_ORDREL 11 /* wait to release write but not read */
75#define TS_WACK_DREQ6 12 /* waiting for T_DISCON_REQ ack */
76#define TS_WACK_DREQ7 13 /* waiting for T_DISCON_REQ ack */
77#define TS_WACK_DREQ9 14 /* waiting for T_DISCON_REQ ack */
78#define TS_WACK_DREQ10 15 /* waiting for T_DISCON_REQ ack */
79#define TS_WACK_DREQ11 16 /* waiting for T_DISCON_REQ ack */
80#define TS_NOSTATES 17
81
82struct T_conn_req {
83 s32 PRIM_type;
84 s32 DEST_length;
85 s32 DEST_offset;
86 s32 OPT_length;
87 s32 OPT_offset;
88};
89
90struct T_bind_req {
91 s32 PRIM_type;
92 s32 ADDR_length;
93 s32 ADDR_offset;
94 u32 CONIND_number;
95};
96
97struct T_unitdata_req {
98 s32 PRIM_type;
99 s32 DEST_length;
100 s32 DEST_offset;
101 s32 OPT_length;
102 s32 OPT_offset;
103};
104
105struct T_optmgmt_req {
106 s32 PRIM_type;
107 s32 OPT_length;
108 s32 OPT_offset;
109 s32 MGMT_flags;
110};
111
112struct T_bind_ack {
113 s32 PRIM_type;
114 s32 ADDR_length;
115 s32 ADDR_offset;
116 u32 CONIND_number;
117};
118
119struct T_error_ack {
120 s32 PRIM_type;
121 s32 ERROR_prim;
122 s32 TLI_error;
123 s32 UNIX_error;
124};
125
126struct T_ok_ack {
127 s32 PRIM_type;
128 s32 CORRECT_prim;
129};
130
131struct T_conn_ind {
132 s32 PRIM_type;
133 s32 SRC_length;
134 s32 SRC_offset;
135 s32 OPT_length;
136 s32 OPT_offset;
137 s32 SEQ_number;
138};
139
140struct T_conn_con {
141 s32 PRIM_type;
142 s32 RES_length;
143 s32 RES_offset;
144 s32 OPT_length;
145 s32 OPT_offset;
146};
147
148struct T_discon_ind {
149 s32 PRIM_type;
150 s32 DISCON_reason;
151 s32 SEQ_number;
152};
153
154struct T_unitdata_ind {
155 s32 PRIM_type;
156 s32 SRC_length;
157 s32 SRC_offset;
158 s32 OPT_length;
159 s32 OPT_offset;
160};
161
162struct T_optmgmt_ack {
163 s32 PRIM_type;
164 s32 OPT_length;
165 s32 OPT_offset;
166 s32 MGMT_flags;
167};
168
169struct opthdr {
170 s32 level;
171 s32 name;
172 s32 len;
173 char value[0];
174};
175
176struct T_primsg {
177 struct T_primsg *next;
178 unsigned char pri;
179 unsigned char band;
180 int length;
181 s32 type;
182};
183
184struct strbuf {
185 s32 maxlen;
186 s32 len;
187 u32 buf;
188} ;
189
190/* Constants used by STREAMS modules emulation code */
191
192typedef char sol_module;
193
194#define MAX_NR_STREAM_MODULES 16
195
196/* Private data structure assigned to sockets. */
197
198struct sol_socket_struct {
199 int magic;
200 int modcount;
201 sol_module module[MAX_NR_STREAM_MODULES];
202 long state;
203 int offset;
204 struct T_primsg *pfirst, *plast;
205};
206
207#define SOLARIS_SOCKET_MAGIC 0xADDED
208
diff --git a/arch/sparc64/solaris/systbl.S b/arch/sparc64/solaris/systbl.S
deleted file mode 100644
index 7043ca18caf9..000000000000
--- a/arch/sparc64/solaris/systbl.S
+++ /dev/null
@@ -1,285 +0,0 @@
1/* $Id: systbl.S,v 1.11 2000/03/13 21:57:35 davem Exp $
2 * systbl.S: System call entry point table for Solaris compatibility.
3 *
4 * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
5 * Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx)
6 */
7
8#include <asm/unistd.h>
9
10/* Fall back to sys_call_table32 entry */
11#define CHAIN(name) __NR_##name
12
13/* Pass pt_regs pointer as first argument */
14#define REGS(name) name+1
15
16/* Hack till all be implemented */
17#define solaris_getpmsg solaris_unimplemented
18#define solaris_hrtsys solaris_unimplemented
19#define solaris_msgsys solaris_unimplemented
20#define solaris_putpmsg solaris_unimplemented
21#define solaris_semsys solaris_unimplemented
22
23 .data
24 .globl solaris_sys_table
25solaris_sys_table:
26 .word solaris_unimplemented /* nosys 0 */
27 .word CHAIN(exit) /* exit d 1 */
28 .word CHAIN(fork) /* fork 2 */
29 .word CHAIN(read) /* read dpd 3 */
30 .word CHAIN(write) /* write dpd 4 */
31 .word solaris_open /* open soo 5 */
32 .word CHAIN(close) /* close d 6 */
33 .word solaris_wait /* wait xxx 7 */
34 .word CHAIN(creat) /* creat so 8 */
35 .word CHAIN(link) /* link ss 9 */
36 .word CHAIN(unlink) /* unlink s 10 */
37 .word solaris_unimplemented /* exec sxx 11 */
38 .word CHAIN(chdir) /* chdir s 12 */
39 .word CHAIN(time) /* time 13 */
40 .word solaris_mknod /* mknod sox 14 */
41 .word CHAIN(chmod) /* chmod so 15 */
42 .word CHAIN(chown) /* chown sdd 16 */
43 .word solaris_brk /* brk/break x 17 */
44 .word solaris_stat /* stat sp 18 */
45 .word CHAIN(lseek) /* seek/lseek ddd 19 */
46 .word solaris_getpid /* getpid 20 */
47 .word solaris_unimplemented /* mount 21 */
48 .word CHAIN(umount) /* umount s 22 */
49 .word CHAIN(setuid) /* setuid d 23 */
50 .word solaris_getuid /* getuid 24 */
51 .word CHAIN(stime) /* stime d 25 */
52#if 0
53 .word solaris_ptrace /* ptrace xdxx 26 */
54#else
55 .word CHAIN(ptrace) /* ptrace xdxx 26 */
56#endif
57 .word CHAIN(alarm) /* alarm d 27 */
58 .word solaris_fstat /* fstat dp 28 */
59 .word CHAIN(pause) /* pause 29 */
60 .word CHAIN(utime) /* utime xx 30 */
61 .word solaris_unimplemented /* stty 31 */
62 .word solaris_unimplemented /* gtty 32 */
63 .word solaris_access /* access so 33 */
64 .word CHAIN(nice) /* nice d 34 */
65 .word solaris_statfs /* statfs spdd 35 */
66 .word CHAIN(sync) /* sync 36 */
67 .word solaris_kill /* kill dd 37 */
68 .word solaris_fstatfs /* fstatfs dpdd 38 */
69 .word solaris_procids /* pgrpsys ddd 39 */
70 .word solaris_unimplemented /* xenix 40 */
71 .word CHAIN(dup) /* dup d 41 */
72 .word CHAIN(pipe) /* pipe 42 */
73 .word CHAIN(times) /* times p 43 */
74 .word 44 /*CHAIN(profil)*/ /* prof xxxx 44 */
75 .word solaris_unimplemented /* lock/plock 45 */
76 .word CHAIN(setgid) /* setgid d 46 */
77 .word solaris_getgid /* getgid 47 */
78 .word solaris_sigfunc /* sigfunc xx 48 */
79 .word REGS(solaris_msgsys) /* msgsys dxddd 49 */
80 .word solaris_unimplemented /* syssun/3b 50 */
81 .word CHAIN(acct) /* acct/sysacct x 51 */
82 .word solaris_shmsys /* shmsys ddxo 52 */
83 .word REGS(solaris_semsys) /* semsys dddx 53 */
84 .word solaris_ioctl /* ioctl dxx 54 */
85 .word solaris_unimplemented /* uadmin xxx 55 */
86 .word solaris_unimplemented /* reserved:exch 56 */
87 .word solaris_utssys /* utssys x 57 */
88 .word CHAIN(fsync) /* fsync d 58 */
89 .word CHAIN(execve) /* execv spp 59 */
90 .word CHAIN(umask) /* umask o 60 */
91 .word CHAIN(chroot) /* chroot s 61 */
92 .word solaris_fcntl /* fcntl dxx 62 */
93 .word solaris_ulimit /* ulimit xx 63 */
94 .word solaris_unimplemented /* ? 64 */
95 .word solaris_unimplemented /* ? 65 */
96 .word solaris_unimplemented /* ? 66 */
97 .word solaris_unimplemented /* ? 67 */
98 .word solaris_unimplemented /* ? 68 */
99 .word solaris_unimplemented /* ? 69 */
100 .word solaris_unimplemented /* advfs 70 */
101 .word solaris_unimplemented /* unadvfs 71 */
102 .word solaris_unimplemented /* rmount 72 */
103 .word solaris_unimplemented /* rumount 73 */
104 .word solaris_unimplemented /* rfstart 74 */
105 .word solaris_unimplemented /* ? 75 */
106 .word solaris_unimplemented /* rdebug 76 */
107 .word solaris_unimplemented /* rfstop 77 */
108 .word solaris_unimplemented /* rfsys 78 */
109 .word CHAIN(rmdir) /* rmdir s 79 */
110 .word CHAIN(mkdir) /* mkdir so 80 */
111 .word CHAIN(getdents) /* getdents dxd 81 */
112 .word solaris_unimplemented /* libattach 82 */
113 .word solaris_unimplemented /* libdetach 83 */
114 .word CHAIN(sysfs) /* sysfs dxx 84 */
115 .word solaris_getmsg /* getmsg dxxx 85 */
116 .word solaris_putmsg /* putmsg dxxd 86 */
117 .word CHAIN(poll) /* poll xdd 87 */
118 .word solaris_lstat /* lstat sp 88 */
119 .word CHAIN(symlink) /* symlink ss 89 */
120 .word CHAIN(readlink) /* readlink spd 90 */
121 .word CHAIN(setgroups) /* setgroups dp 91 */
122 .word CHAIN(getgroups) /* getgroups dp 92 */
123 .word CHAIN(fchmod) /* fchmod do 93 */
124 .word CHAIN(fchown) /* fchown ddd 94 */
125 .word solaris_sigprocmask /* sigprocmask dxx 95 */
126 .word solaris_sigsuspend /* sigsuspend x 96 */
127 .word solaris_sigaltstack /* sigaltstack xx 97 */
128 .word solaris_sigaction /* sigaction dxx 98 */
129 .word solaris_sigpending /* sigpending dd 99 */
130 .word REGS(solaris_context) /* context 100 */
131 .word solaris_unimplemented /* evsys 101 */
132 .word solaris_unimplemented /* evtrapret 102 */
133 .word solaris_statvfs /* statvfs sp 103 */
134 .word solaris_fstatvfs /* fstatvfs dp 104 */
135 .word solaris_unimplemented /* unknown 105 */
136 .word solaris_unimplemented /* nfssys 106 */
137 .word solaris_waitid /* waitid ddxd 107 */
138 .word solaris_unimplemented /* sigsendsys ddd 108 */
139 .word REGS(solaris_hrtsys) /* hrtsys xxx 109 */
140 .word solaris_unimplemented /* acancel dxd 110 */
141 .word solaris_unimplemented /* async 111 */
142 .word solaris_unimplemented /* priocntlsys 112 */
143 .word solaris_pathconf /* pathconf sd 113 */
144 .word CHAIN(mincore) /* mincore d 114 */
145 .word solaris_mmap /* mmap xxxxdx 115 */
146 .word CHAIN(mprotect) /* mprotect xdx 116 */
147 .word CHAIN(munmap) /* munmap xd 117 */
148 .word solaris_fpathconf /* fpathconf dd 118 */
149 .word CHAIN(fork) /* fork 119 */
150 .word solaris_unimplemented /* fchdir d 120 */
151 .word CHAIN(readv) /* readv dxd 121 */
152 .word CHAIN(writev) /* writev dxd 122 */
153 .word solaris_xstat /* xstat dsx 123 */
154 .word solaris_lxstat /* lxstat dsx 124 */
155 .word solaris_fxstat /* fxstat ddx 125 */
156 .word solaris_xmknod /* xmknod dsox 126 */
157 .word solaris_unimplemented /* syslocal d 127 */
158 .word solaris_setrlimit /* setrlimit dp 128 */
159 .word solaris_getrlimit /* getrlimit dp 129 */
160 .word CHAIN(chown) /* lchown sdd 130 */
161 .word solaris_unimplemented /* memcntl 131 */
162 .word solaris_getpmsg /* getpmsg dxxxx 132 */
163 .word solaris_putpmsg /* putpmsg dxxdd 133 */
164 .word CHAIN(rename) /* rename ss 134 */
165 .word solaris_utsname /* uname x 135 */
166 .word solaris_unimplemented /* setegid 136 */
167 .word solaris_sysconf /* sysconfig d 137 */
168 .word solaris_unimplemented /* adjtime 138 */
169 .word solaris_sysinfo /* systeminfo dsd 139 */
170 .word solaris_unimplemented /* ? 140 */
171 .word solaris_unimplemented /* seteuid 141 */
172 .word solaris_unimplemented /* ? 142 */
173 .word solaris_unimplemented /* ? 143 */
174 .word solaris_unimplemented /* secsys dx 144 */
175 .word solaris_unimplemented /* filepriv sdxd 145 */
176 .word solaris_unimplemented /* procpriv dxd 146 */
177 .word solaris_unimplemented /* devstat sdx 147 */
178 .word solaris_unimplemented /* aclipc ddddx 148 */
179 .word solaris_unimplemented /* fdevstat ddx 149 */
180 .word solaris_unimplemented /* flvlfile ddx 150 */
181 .word solaris_unimplemented /* lvlfile sdx 151 */
182 .word solaris_unimplemented /* ? 152 */
183 .word solaris_unimplemented /* fchroot d 153 */
184 .word solaris_unimplemented /* lvlproc dx 154 */
185 .word solaris_unimplemented /* ? 155 */
186 .word solaris_gettimeofday /* gettimeofday x 156 */
187 .word CHAIN(getitimer) /* getitimer dx 157 */
188 .word CHAIN(setitimer) /* setitimer dxx 158 */
189 .word solaris_unimplemented /* lwp-xxx 159 */
190 .word solaris_unimplemented /* lwp-xxx 160 */
191 .word solaris_unimplemented /* lwp-xxx 161 */
192 .word solaris_unimplemented /* lwp-xxx 162 */
193 .word solaris_unimplemented /* lwp-xxx 163 */
194 .word solaris_unimplemented /* lwp-xxx 164 */
195 .word solaris_unimplemented /* lwp-xxx 165 */
196 .word solaris_unimplemented /* lwp-xxx 166 */
197 .word solaris_unimplemented /* lwp-xxx 167 */
198 .word solaris_unimplemented /* lwp-xxx 168 */
199 .word solaris_unimplemented /* lwp-xxx 169 */
200 .word solaris_unimplemented /* lwp-xxx 170 */
201 .word solaris_unimplemented /* lwp-xxx 171 */
202 .word solaris_unimplemented /* lwp-xxx 172 */
203 .word solaris_pread /* pread dpdd 173 */
204 .word solaris_pwrite /* pwrite dpdd 174 */
205 .word REGS(solaris_llseek) /* llseek dLd 175 */
206 .word solaris_unimplemented /* lwpself 176 */
207 .word solaris_unimplemented /* lwpinfo 177 */
208 .word solaris_unimplemented /* lwpprivate 178 */
209 .word solaris_unimplemented /* processorbind 179 */
210 .word solaris_unimplemented /* processorexbind 180 */
211 .word solaris_unimplemented /* 181 */
212 .word solaris_unimplemented /* sync_mailbox 182 */
213 .word solaris_unimplemented /* prepblock 183 */
214 .word solaris_unimplemented /* block 184 */
215 .word solaris_acl /* acl sddp 185 */
216 .word solaris_unimplemented /* unblock 186 */
217 .word solaris_unimplemented /* cancelblock 187 */
218 .word solaris_unimplemented /* ? 188 */
219 .word solaris_unimplemented /* xxxxx 189 */
220 .word solaris_unimplemented /* xxxxxe 190 */
221 .word solaris_unimplemented /* 191 */
222 .word solaris_unimplemented /* 192 */
223 .word solaris_unimplemented /* 193 */
224 .word solaris_unimplemented /* 194 */
225 .word solaris_unimplemented /* 195 */
226 .word solaris_unimplemented /* 196 */
227 .word solaris_unimplemented /* 197 */
228 .word solaris_unimplemented /* 198 */
229 .word CHAIN(nanosleep) /* nanosleep dd 199 */
230 .word solaris_facl /* facl dddp 200 */
231 .word solaris_unimplemented /* 201 */
232 .word CHAIN(setreuid) /* setreuid dd 202 */
233 .word CHAIN(setregid) /* setregid dd 203 */
234 .word solaris_unimplemented /* 204 */
235 .word solaris_unimplemented /* 205 */
236 .word solaris_unimplemented /* 206 */
237 .word solaris_unimplemented /* 207 */
238 .word solaris_unimplemented /* 208 */
239 .word solaris_unimplemented /* 209 */
240 .word solaris_unimplemented /* 210 */
241 .word solaris_unimplemented /* 211 */
242 .word solaris_unimplemented /* 212 */
243 .word solaris_getdents64 /* getdents64 dpd 213 */
244 .word REGS(solaris_mmap64) /* mmap64 xxxxdX 214 */
245 .word solaris_stat64 /* stat64 sP 215 */
246 .word solaris_lstat64 /* lstat64 sP 216 */
247 .word solaris_fstat64 /* fstat64 dP 217 */
248 .word solaris_statvfs64 /* statvfs64 sP 218 */
249 .word solaris_fstatvfs64 /* fstatvfs64 dP 219 */
250 .word solaris_setrlimit64 /* setrlimit64 dP 220 */
251 .word solaris_getrlimit64 /* getrlimit64 dP 221 */
252 .word CHAIN(pread64) /* pread64 dpdD 222 */
253 .word CHAIN(pwrite64) /* pwrite64 dpdD 223 */
254 .word CHAIN(creat) /* creat64 so 224 */
255 .word solaris_open /* open64 soo 225 */
256 .word solaris_unimplemented /* 226 */
257 .word solaris_unimplemented /* 227 */
258 .word solaris_unimplemented /* 228 */
259 .word solaris_unimplemented /* 229 */
260 .word solaris_socket /* socket ddd 230 */
261 .word solaris_socketpair /* socketpair dddp 231 */
262 .word solaris_bind /* bind dpd 232 */
263 .word solaris_listen /* listen dd 233 */
264 .word solaris_accept /* accept dpp 234 */
265 .word solaris_connect /* connect dpd 235 */
266 .word solaris_shutdown /* shutdown dd 236 */
267 .word solaris_recv /* recv dpdd 237 */
268 .word solaris_recvfrom /* recvfrom dpddpp 238 */
269 .word solaris_recvmsg /* recvmsg dpd 239 */
270 .word solaris_send /* send dpdd 240 */
271 .word solaris_sendmsg /* sendmsg dpd 241 */
272 .word solaris_sendto /* sendto dpddpd 242 */
273 .word solaris_getpeername /* getpeername dpp 243 */
274 .word solaris_getsockname /* getsockname dpp 244 */
275 .word solaris_getsockopt /* getsockopt dddpp 245 */
276 .word solaris_setsockopt /* setsockopt dddpp 246 */
277 .word solaris_unimplemented /* 247 */
278 .word solaris_ntp_gettime /* ntp_gettime p 248 */
279 .word solaris_ntp_adjtime /* ntp_adjtime p 249 */
280 .word solaris_unimplemented /* 250 */
281 .word solaris_unimplemented /* 251 */
282 .word solaris_unimplemented /* 252 */
283 .word solaris_unimplemented /* 253 */
284 .word solaris_unimplemented /* 254 */
285 .word solaris_unimplemented /* 255 */
diff --git a/arch/sparc64/solaris/timod.c b/arch/sparc64/solaris/timod.c
deleted file mode 100644
index 15234fcd191a..000000000000
--- a/arch/sparc64/solaris/timod.c
+++ /dev/null
@@ -1,976 +0,0 @@
1/* $Id: timod.c,v 1.19 2002/02/08 03:57:14 davem Exp $
2 * timod.c: timod emulation.
3 *
4 * Copyright (C) 1998 Patrik Rak (prak3264@ss1000.ms.mff.cuni.cz)
5 *
6 * Streams & timod emulation based on code
7 * Copyright (C) 1995, 1996 Mike Jagdis (jaggy@purplet.demon.co.uk)
8 *
9 */
10
11#include <linux/types.h>
12#include <linux/kernel.h>
13#include <linux/sched.h>
14#include <linux/smp.h>
15#include <linux/smp_lock.h>
16#include <linux/ioctl.h>
17#include <linux/fs.h>
18#include <linux/file.h>
19#include <linux/netdevice.h>
20#include <linux/poll.h>
21
22#include <net/sock.h>
23
24#include <asm/uaccess.h>
25#include <asm/termios.h>
26
27#include "conv.h"
28#include "socksys.h"
29
30asmlinkage int solaris_ioctl(unsigned int fd, unsigned int cmd, u32 arg);
31
32static DEFINE_SPINLOCK(timod_pagelock);
33static char * page = NULL ;
34
35#ifndef DEBUG_SOLARIS_KMALLOC
36
37#define mykmalloc kmalloc
38#define mykfree kfree
39
40#else
41
42void * mykmalloc(size_t s, gfp_t gfp)
43{
44 static char * page;
45 static size_t free;
46 void * r;
47 s = ((s + 63) & ~63);
48 if( s > PAGE_SIZE ) {
49 SOLD("too big size, calling real kmalloc");
50 return kmalloc(s, gfp);
51 }
52 if( s > free ) {
53 /* we are wasting memory, but we don't care */
54 page = (char *)__get_free_page(gfp);
55 free = PAGE_SIZE;
56 }
57 r = page;
58 page += s;
59 free -= s;
60 return r;
61}
62
63void mykfree(void *p)
64{
65}
66
67#endif
68
69#ifndef DEBUG_SOLARIS
70
71#define BUF_SIZE PAGE_SIZE
72#define PUT_MAGIC(a,m)
73#define SCHECK_MAGIC(a,m)
74#define BUF_OFFSET 0
75#define MKCTL_TRAILER 0
76
77#else
78
79#define BUF_SIZE (PAGE_SIZE-2*sizeof(u64))
80#define BUFPAGE_MAGIC 0xBADC0DEDDEADBABEL
81#define MKCTL_MAGIC 0xDEADBABEBADC0DEDL
82#define PUT_MAGIC(a,m) do{(*(u64*)(a))=(m);}while(0)
83#define SCHECK_MAGIC(a,m) do{if((*(u64*)(a))!=(m))printk("%s,%u,%s(): magic %08x at %p corrupted!\n",\
84 __FILE__,__LINE__,__func__,(m),(a));}while(0)
85#define BUF_OFFSET sizeof(u64)
86#define MKCTL_TRAILER sizeof(u64)
87
88#endif
89
90static char *getpage( void )
91{
92 char *r;
93 SOLD("getting page");
94 spin_lock(&timod_pagelock);
95 if (page) {
96 r = page;
97 page = NULL;
98 spin_unlock(&timod_pagelock);
99 SOLD("got cached");
100 return r + BUF_OFFSET;
101 }
102 spin_unlock(&timod_pagelock);
103 SOLD("getting new");
104 r = (char *)__get_free_page(GFP_KERNEL);
105 PUT_MAGIC(r,BUFPAGE_MAGIC);
106 PUT_MAGIC(r+PAGE_SIZE-sizeof(u64),BUFPAGE_MAGIC);
107 return r + BUF_OFFSET;
108}
109
110static void putpage(char *p)
111{
112 SOLD("putting page");
113 p = p - BUF_OFFSET;
114 SCHECK_MAGIC(p,BUFPAGE_MAGIC);
115 SCHECK_MAGIC(p+PAGE_SIZE-sizeof(u64),BUFPAGE_MAGIC);
116 spin_lock(&timod_pagelock);
117 if (page) {
118 spin_unlock(&timod_pagelock);
119 free_page((unsigned long)p);
120 SOLD("freed it");
121 } else {
122 page = p;
123 spin_unlock(&timod_pagelock);
124 SOLD("cached it");
125 }
126}
127
128static struct T_primsg *timod_mkctl(int size)
129{
130 struct T_primsg *it;
131
132 SOLD("creating primsg");
133 it = (struct T_primsg *)mykmalloc(size+sizeof(*it)-sizeof(s32)+2*MKCTL_TRAILER, GFP_KERNEL);
134 if (it) {
135 SOLD("got it");
136 it->pri = MSG_HIPRI;
137 it->length = size;
138 PUT_MAGIC((char*)((u64)(((char *)&it->type)+size+7)&~7),MKCTL_MAGIC);
139 }
140 return it;
141}
142
143static void timod_wake_socket(unsigned int fd)
144{
145 struct socket *sock;
146 struct fdtable *fdt;
147
148 SOLD("wakeing socket");
149 fdt = files_fdtable(current->files);
150 sock = SOCKET_I(fdt->fd[fd]->f_path.dentry->d_inode);
151 wake_up_interruptible(&sock->wait);
152 read_lock(&sock->sk->sk_callback_lock);
153 if (sock->fasync_list && !test_bit(SOCK_ASYNC_WAITDATA, &sock->flags))
154 __kill_fasync(sock->fasync_list, SIGIO, POLL_IN);
155 read_unlock(&sock->sk->sk_callback_lock);
156 SOLD("done");
157}
158
159static void timod_queue(unsigned int fd, struct T_primsg *it)
160{
161 struct sol_socket_struct *sock;
162 struct fdtable *fdt;
163
164 SOLD("queuing primsg");
165 fdt = files_fdtable(current->files);
166 sock = (struct sol_socket_struct *)fdt->fd[fd]->private_data;
167 it->next = sock->pfirst;
168 sock->pfirst = it;
169 if (!sock->plast)
170 sock->plast = it;
171 timod_wake_socket(fd);
172 SOLD("done");
173}
174
175static void timod_queue_end(unsigned int fd, struct T_primsg *it)
176{
177 struct sol_socket_struct *sock;
178 struct fdtable *fdt;
179
180 SOLD("queuing primsg at end");
181 fdt = files_fdtable(current->files);
182 sock = (struct sol_socket_struct *)fdt->fd[fd]->private_data;
183 it->next = NULL;
184 if (sock->plast)
185 sock->plast->next = it;
186 else
187 sock->pfirst = it;
188 sock->plast = it;
189 SOLD("done");
190}
191
192static void timod_error(unsigned int fd, int prim, int terr, int uerr)
193{
194 struct T_primsg *it;
195
196 SOLD("making error");
197 it = timod_mkctl(sizeof(struct T_error_ack));
198 if (it) {
199 struct T_error_ack *err = (struct T_error_ack *)&it->type;
200
201 SOLD("got it");
202 err->PRIM_type = T_ERROR_ACK;
203 err->ERROR_prim = prim;
204 err->TLI_error = terr;
205 err->UNIX_error = uerr; /* FIXME: convert this */
206 timod_queue(fd, it);
207 }
208 SOLD("done");
209}
210
211static void timod_ok(unsigned int fd, int prim)
212{
213 struct T_primsg *it;
214 struct T_ok_ack *ok;
215
216 SOLD("creating ok ack");
217 it = timod_mkctl(sizeof(*ok));
218 if (it) {
219 SOLD("got it");
220 ok = (struct T_ok_ack *)&it->type;
221 ok->PRIM_type = T_OK_ACK;
222 ok->CORRECT_prim = prim;
223 timod_queue(fd, it);
224 }
225 SOLD("done");
226}
227
228static int timod_optmgmt(unsigned int fd, int flag, char __user *opt_buf, int opt_len, int do_ret)
229{
230 int error, failed;
231 int ret_space, ret_len;
232 long args[5];
233 char *ret_pos,*ret_buf;
234 int (*sys_socketcall)(int, unsigned long *) =
235 (int (*)(int, unsigned long *))SYS(socketcall);
236 mm_segment_t old_fs = get_fs();
237
238 SOLD("entry");
239 SOLDD(("fd %u flg %u buf %p len %u doret %u",fd,flag,opt_buf,opt_len,do_ret));
240 if (!do_ret && (!opt_buf || opt_len <= 0))
241 return 0;
242 SOLD("getting page");
243 ret_pos = ret_buf = getpage();
244 ret_space = BUF_SIZE;
245 ret_len = 0;
246
247 error = failed = 0;
248 SOLD("looping");
249 while(opt_len >= sizeof(struct opthdr)) {
250 struct opthdr *opt;
251 int orig_opt_len;
252 SOLD("loop start");
253 opt = (struct opthdr *)ret_pos;
254 if (ret_space < sizeof(struct opthdr)) {
255 failed = TSYSERR;
256 break;
257 }
258 SOLD("getting opthdr");
259 if (copy_from_user(opt, opt_buf, sizeof(struct opthdr)) ||
260 opt->len > opt_len) {
261 failed = TBADOPT;
262 break;
263 }
264 SOLD("got opthdr");
265 if (flag == T_NEGOTIATE) {
266 char *buf;
267
268 SOLD("handling T_NEGOTIATE");
269 buf = ret_pos + sizeof(struct opthdr);
270 if (ret_space < opt->len + sizeof(struct opthdr) ||
271 copy_from_user(buf, opt_buf+sizeof(struct opthdr), opt->len)) {
272 failed = TSYSERR;
273 break;
274 }
275 SOLD("got optdata");
276 args[0] = fd;
277 args[1] = opt->level;
278 args[2] = opt->name;
279 args[3] = (long)buf;
280 args[4] = opt->len;
281 SOLD("calling SETSOCKOPT");
282 set_fs(KERNEL_DS);
283 error = sys_socketcall(SYS_SETSOCKOPT, args);
284 set_fs(old_fs);
285 if (error) {
286 failed = TBADOPT;
287 break;
288 }
289 SOLD("SETSOCKOPT ok");
290 }
291 orig_opt_len = opt->len;
292 opt->len = ret_space - sizeof(struct opthdr);
293 if (opt->len < 0) {
294 failed = TSYSERR;
295 break;
296 }
297 args[0] = fd;
298 args[1] = opt->level;
299 args[2] = opt->name;
300 args[3] = (long)(ret_pos+sizeof(struct opthdr));
301 args[4] = (long)&opt->len;
302 SOLD("calling GETSOCKOPT");
303 set_fs(KERNEL_DS);
304 error = sys_socketcall(SYS_GETSOCKOPT, args);
305 set_fs(old_fs);
306 if (error) {
307 failed = TBADOPT;
308 break;
309 }
310 SOLD("GETSOCKOPT ok");
311 ret_space -= sizeof(struct opthdr) + opt->len;
312 ret_len += sizeof(struct opthdr) + opt->len;
313 ret_pos += sizeof(struct opthdr) + opt->len;
314 opt_len -= sizeof(struct opthdr) + orig_opt_len;
315 opt_buf += sizeof(struct opthdr) + orig_opt_len;
316 SOLD("loop end");
317 }
318 SOLD("loop done");
319 if (do_ret) {
320 SOLD("generating ret msg");
321 if (failed)
322 timod_error(fd, T_OPTMGMT_REQ, failed, -error);
323 else {
324 struct T_primsg *it;
325 it = timod_mkctl(sizeof(struct T_optmgmt_ack) + ret_len);
326 if (it) {
327 struct T_optmgmt_ack *ack =
328 (struct T_optmgmt_ack *)&it->type;
329 SOLD("got primsg");
330 ack->PRIM_type = T_OPTMGMT_ACK;
331 ack->OPT_length = ret_len;
332 ack->OPT_offset = sizeof(struct T_optmgmt_ack);
333 ack->MGMT_flags = (failed ? T_FAILURE : flag);
334 memcpy(((char*)ack)+sizeof(struct T_optmgmt_ack),
335 ret_buf, ret_len);
336 timod_queue(fd, it);
337 }
338 }
339 }
340 SOLDD(("put_page %p\n", ret_buf));
341 putpage(ret_buf);
342 SOLD("done");
343 return 0;
344}
345
346int timod_putmsg(unsigned int fd, char __user *ctl_buf, int ctl_len,
347 char __user *data_buf, int data_len, int flags)
348{
349 int ret, error, terror;
350 char *buf;
351 struct file *filp;
352 struct inode *ino;
353 struct fdtable *fdt;
354 struct sol_socket_struct *sock;
355 mm_segment_t old_fs = get_fs();
356 long args[6];
357 int (*sys_socketcall)(int, unsigned long __user *) =
358 (int (*)(int, unsigned long __user *))SYS(socketcall);
359 int (*sys_sendto)(int, void __user *, size_t, unsigned, struct sockaddr __user *, int) =
360 (int (*)(int, void __user *, size_t, unsigned, struct sockaddr __user *, int))SYS(sendto);
361
362 fdt = files_fdtable(current->files);
363 filp = fdt->fd[fd];
364 ino = filp->f_path.dentry->d_inode;
365 sock = (struct sol_socket_struct *)filp->private_data;
366 SOLD("entry");
367 if (get_user(ret, (int __user *)A(ctl_buf)))
368 return -EFAULT;
369 switch (ret) {
370 case T_BIND_REQ:
371 {
372 struct T_bind_req req;
373
374 SOLDD(("bind %016lx(%016lx)\n", sock, filp));
375 SOLD("T_BIND_REQ");
376 if (sock->state != TS_UNBND) {
377 timod_error(fd, T_BIND_REQ, TOUTSTATE, 0);
378 return 0;
379 }
380 SOLD("state ok");
381 if (copy_from_user(&req, ctl_buf, sizeof(req))) {
382 timod_error(fd, T_BIND_REQ, TSYSERR, EFAULT);
383 return 0;
384 }
385 SOLD("got ctl req");
386 if (req.ADDR_offset && req.ADDR_length) {
387 if (req.ADDR_length > BUF_SIZE) {
388 timod_error(fd, T_BIND_REQ, TSYSERR, EFAULT);
389 return 0;
390 }
391 SOLD("req size ok");
392 buf = getpage();
393 if (copy_from_user(buf, ctl_buf + req.ADDR_offset, req.ADDR_length)) {
394 timod_error(fd, T_BIND_REQ, TSYSERR, EFAULT);
395 putpage(buf);
396 return 0;
397 }
398 SOLD("got ctl data");
399 args[0] = fd;
400 args[1] = (long)buf;
401 args[2] = req.ADDR_length;
402 SOLD("calling BIND");
403 set_fs(KERNEL_DS);
404 error = sys_socketcall(SYS_BIND, args);
405 set_fs(old_fs);
406 putpage(buf);
407 SOLD("BIND returned");
408 } else
409 error = 0;
410 if (!error) {
411 struct T_primsg *it;
412 if (req.CONIND_number) {
413 args[0] = fd;
414 args[1] = req.CONIND_number;
415 SOLD("calling LISTEN");
416 set_fs(KERNEL_DS);
417 error = sys_socketcall(SYS_LISTEN, args);
418 set_fs(old_fs);
419 SOLD("LISTEN done");
420 }
421 it = timod_mkctl(sizeof(struct T_bind_ack)+sizeof(struct sockaddr));
422 if (it) {
423 struct T_bind_ack *ack;
424
425 ack = (struct T_bind_ack *)&it->type;
426 ack->PRIM_type = T_BIND_ACK;
427 ack->ADDR_offset = sizeof(*ack);
428 ack->ADDR_length = sizeof(struct sockaddr);
429 ack->CONIND_number = req.CONIND_number;
430 args[0] = fd;
431 args[1] = (long)(ack+sizeof(*ack));
432 args[2] = (long)&ack->ADDR_length;
433 set_fs(KERNEL_DS);
434 sys_socketcall(SYS_GETSOCKNAME,args);
435 set_fs(old_fs);
436 sock->state = TS_IDLE;
437 timod_ok(fd, T_BIND_REQ);
438 timod_queue_end(fd, it);
439 SOLD("BIND done");
440 return 0;
441 }
442 }
443 SOLD("some error");
444 switch (error) {
445 case -EINVAL:
446 terror = TOUTSTATE;
447 error = 0;
448 break;
449 case -EACCES:
450 terror = TACCES;
451 error = 0;
452 break;
453 case -EADDRNOTAVAIL:
454 case -EADDRINUSE:
455 terror = TNOADDR;
456 error = 0;
457 break;
458 default:
459 terror = TSYSERR;
460 break;
461 }
462 timod_error(fd, T_BIND_REQ, terror, -error);
463 SOLD("BIND done");
464 return 0;
465 }
466 case T_CONN_REQ:
467 {
468 struct T_conn_req req;
469 unsigned short oldflags;
470 struct T_primsg *it;
471 SOLD("T_CONN_REQ");
472 if (sock->state != TS_UNBND && sock->state != TS_IDLE) {
473 timod_error(fd, T_CONN_REQ, TOUTSTATE, 0);
474 return 0;
475 }
476 SOLD("state ok");
477 if (copy_from_user(&req, ctl_buf, sizeof(req))) {
478 timod_error(fd, T_CONN_REQ, TSYSERR, EFAULT);
479 return 0;
480 }
481 SOLD("got ctl req");
482 if (ctl_len > BUF_SIZE) {
483 timod_error(fd, T_CONN_REQ, TSYSERR, EFAULT);
484 return 0;
485 }
486 SOLD("req size ok");
487 buf = getpage();
488 if (copy_from_user(buf, ctl_buf, ctl_len)) {
489 timod_error(fd, T_CONN_REQ, TSYSERR, EFAULT);
490 putpage(buf);
491 return 0;
492 }
493#ifdef DEBUG_SOLARIS
494 {
495 char * ptr = buf;
496 int len = ctl_len;
497 printk("returned data (%d bytes): ",len);
498 while( len-- ) {
499 if (!(len & 7))
500 printk(" ");
501 printk("%02x",(unsigned char)*ptr++);
502 }
503 printk("\n");
504 }
505#endif
506 SOLD("got ctl data");
507 args[0] = fd;
508 args[1] = (long)buf+req.DEST_offset;
509 args[2] = req.DEST_length;
510 oldflags = filp->f_flags;
511 filp->f_flags &= ~O_NONBLOCK;
512 SOLD("calling CONNECT");
513 set_fs(KERNEL_DS);
514 error = sys_socketcall(SYS_CONNECT, args);
515 set_fs(old_fs);
516 filp->f_flags = oldflags;
517 SOLD("CONNECT done");
518 if (!error) {
519 struct T_conn_con *con;
520 SOLD("no error");
521 it = timod_mkctl(ctl_len);
522 if (!it) {
523 putpage(buf);
524 return -ENOMEM;
525 }
526 con = (struct T_conn_con *)&it->type;
527#ifdef DEBUG_SOLARIS
528 {
529 char * ptr = buf;
530 int len = ctl_len;
531 printk("returned data (%d bytes): ",len);
532 while( len-- ) {
533 if (!(len & 7))
534 printk(" ");
535 printk("%02x",(unsigned char)*ptr++);
536 }
537 printk("\n");
538 }
539#endif
540 memcpy(con, buf, ctl_len);
541 SOLD("copied ctl_buf");
542 con->PRIM_type = T_CONN_CON;
543 sock->state = TS_DATA_XFER;
544 } else {
545 struct T_discon_ind *dis;
546 SOLD("some error");
547 it = timod_mkctl(sizeof(*dis));
548 if (!it) {
549 putpage(buf);
550 return -ENOMEM;
551 }
552 SOLD("got primsg");
553 dis = (struct T_discon_ind *)&it->type;
554 dis->PRIM_type = T_DISCON_IND;
555 dis->DISCON_reason = -error; /* FIXME: convert this as in iABI_errors() */
556 dis->SEQ_number = 0;
557 }
558 putpage(buf);
559 timod_ok(fd, T_CONN_REQ);
560 it->pri = 0;
561 timod_queue_end(fd, it);
562 SOLD("CONNECT done");
563 return 0;
564 }
565 case T_OPTMGMT_REQ:
566 {
567 struct T_optmgmt_req req;
568 SOLD("OPTMGMT_REQ");
569 if (copy_from_user(&req, ctl_buf, sizeof(req)))
570 return -EFAULT;
571 SOLD("got req");
572 return timod_optmgmt(fd, req.MGMT_flags,
573 req.OPT_offset > 0 ? ctl_buf + req.OPT_offset : NULL,
574 req.OPT_length, 1);
575 }
576 case T_UNITDATA_REQ:
577 {
578 struct T_unitdata_req req;
579
580 int err;
581 SOLD("T_UNITDATA_REQ");
582 if (sock->state != TS_IDLE && sock->state != TS_DATA_XFER) {
583 timod_error(fd, T_CONN_REQ, TOUTSTATE, 0);
584 return 0;
585 }
586 SOLD("state ok");
587 if (copy_from_user(&req, ctl_buf, sizeof(req))) {
588 timod_error(fd, T_CONN_REQ, TSYSERR, EFAULT);
589 return 0;
590 }
591 SOLD("got ctl req");
592#ifdef DEBUG_SOLARIS
593 {
594 char * ptr = ctl_buf+req.DEST_offset;
595 int len = req.DEST_length;
596 printk("socket address (%d bytes): ",len);
597 while( len-- ) {
598 char c;
599 if (get_user(c,ptr))
600 printk("??");
601 else
602 printk("%02x",(unsigned char)c);
603 ptr++;
604 }
605 printk("\n");
606 }
607#endif
608 err = sys_sendto(fd, data_buf, data_len, 0, req.DEST_length > 0 ? (struct sockaddr __user *)(ctl_buf+req.DEST_offset) : NULL, req.DEST_length);
609 if (err == data_len)
610 return 0;
611 if(err >= 0) {
612 printk("timod: sendto failed to send all the data\n");
613 return 0;
614 }
615 timod_error(fd, T_CONN_REQ, TSYSERR, -err);
616 return 0;
617 }
618 default:
619 printk(KERN_INFO "timod_putmsg: unsupported command %u.\n", ret);
620 break;
621 }
622 return -EINVAL;
623}
624
625int timod_getmsg(unsigned int fd, char __user *ctl_buf, int ctl_maxlen, s32 __user *ctl_len,
626 char __user *data_buf, int data_maxlen, s32 __user *data_len, int *flags_p)
627{
628 int error;
629 int oldflags;
630 struct file *filp;
631 struct inode *ino;
632 struct fdtable *fdt;
633 struct sol_socket_struct *sock;
634 struct T_unitdata_ind udi;
635 mm_segment_t old_fs = get_fs();
636 long args[6];
637 char __user *tmpbuf;
638 int tmplen;
639 int (*sys_socketcall)(int, unsigned long __user *) =
640 (int (*)(int, unsigned long __user *))SYS(socketcall);
641 int (*sys_recvfrom)(int, void __user *, size_t, unsigned, struct sockaddr __user *, int __user *);
642
643 SOLD("entry");
644 SOLDD(("%u %p %d %p %p %d %p %d\n", fd, ctl_buf, ctl_maxlen, ctl_len, data_buf, data_maxlen, data_len, *flags_p));
645 fdt = files_fdtable(current->files);
646 filp = fdt->fd[fd];
647 ino = filp->f_path.dentry->d_inode;
648 sock = (struct sol_socket_struct *)filp->private_data;
649 SOLDD(("%p %p\n", sock->pfirst, sock->pfirst ? sock->pfirst->next : NULL));
650 if ( ctl_maxlen > 0 && !sock->pfirst && SOCKET_I(ino)->type == SOCK_STREAM
651 && sock->state == TS_IDLE) {
652 SOLD("calling LISTEN");
653 args[0] = fd;
654 args[1] = -1;
655 set_fs(KERNEL_DS);
656 sys_socketcall(SYS_LISTEN, args);
657 set_fs(old_fs);
658 SOLD("LISTEN done");
659 }
660 if (!(filp->f_flags & O_NONBLOCK)) {
661 struct poll_wqueues wait_table;
662 poll_table *wait;
663
664 poll_initwait(&wait_table);
665 wait = &wait_table.pt;
666 for(;;) {
667 SOLD("loop");
668 set_current_state(TASK_INTERRUPTIBLE);
669 /* ! ( l<0 || ( l>=0 && ( ! pfirst || (flags == HIPRI && pri != HIPRI) ) ) ) */
670 /* ( ! l<0 && ! ( l>=0 && ( ! pfirst || (flags == HIPRI && pri != HIPRI) ) ) ) */
671 /* ( l>=0 && ( ! l>=0 || ! ( ! pfirst || (flags == HIPRI && pri != HIPRI) ) ) ) */
672 /* ( l>=0 && ( l<0 || ( pfirst && ! (flags == HIPRI && pri != HIPRI) ) ) ) */
673 /* ( l>=0 && ( l<0 || ( pfirst && (flags != HIPRI || pri == HIPRI) ) ) ) */
674 /* ( l>=0 && ( pfirst && (flags != HIPRI || pri == HIPRI) ) ) */
675 if (ctl_maxlen >= 0 && sock->pfirst && (*flags_p != MSG_HIPRI || sock->pfirst->pri == MSG_HIPRI))
676 break;
677 SOLD("cond 1 passed");
678 if (
679 #if 1
680 *flags_p != MSG_HIPRI &&
681 #endif
682 ((filp->f_op->poll(filp, wait) & POLLIN) ||
683 (filp->f_op->poll(filp, NULL) & POLLIN) ||
684 signal_pending(current))
685 ) {
686 break;
687 }
688 if( *flags_p == MSG_HIPRI ) {
689 SOLD("avoiding lockup");
690 break ;
691 }
692 if(wait_table.error) {
693 SOLD("wait-table error");
694 poll_freewait(&wait_table);
695 return wait_table.error;
696 }
697 SOLD("scheduling");
698 schedule();
699 }
700 SOLD("loop done");
701 current->state = TASK_RUNNING;
702 poll_freewait(&wait_table);
703 if (signal_pending(current)) {
704 SOLD("signal pending");
705 return -EINTR;
706 }
707 }
708 if (ctl_maxlen >= 0 && sock->pfirst) {
709 struct T_primsg *it = sock->pfirst;
710 int l = min_t(int, ctl_maxlen, it->length);
711 SCHECK_MAGIC((char*)((u64)(((char *)&it->type)+sock->offset+it->length+7)&~7),MKCTL_MAGIC);
712 SOLD("purting ctl data");
713 if(copy_to_user(ctl_buf,
714 (char*)&it->type + sock->offset, l))
715 return -EFAULT;
716 SOLD("pur it");
717 if(put_user(l, ctl_len))
718 return -EFAULT;
719 SOLD("set ctl_len");
720 *flags_p = it->pri;
721 it->length -= l;
722 if (it->length) {
723 SOLD("more ctl");
724 sock->offset += l;
725 return MORECTL;
726 } else {
727 SOLD("removing message");
728 sock->pfirst = it->next;
729 if (!sock->pfirst)
730 sock->plast = NULL;
731 SOLDD(("getmsg kfree %016lx->%016lx\n", it, sock->pfirst));
732 mykfree(it);
733 sock->offset = 0;
734 SOLD("ctl done");
735 return 0;
736 }
737 }
738 *flags_p = 0;
739 if (ctl_maxlen >= 0) {
740 SOLD("ACCEPT perhaps?");
741 if (SOCKET_I(ino)->type == SOCK_STREAM && sock->state == TS_IDLE) {
742 struct T_conn_ind ind;
743 char *buf = getpage();
744 int len = BUF_SIZE;
745
746 SOLD("trying ACCEPT");
747 if (put_user(ctl_maxlen - sizeof(ind), ctl_len))
748 return -EFAULT;
749 args[0] = fd;
750 args[1] = (long)buf;
751 args[2] = (long)&len;
752 oldflags = filp->f_flags;
753 filp->f_flags |= O_NONBLOCK;
754 SOLD("calling ACCEPT");
755 set_fs(KERNEL_DS);
756 error = sys_socketcall(SYS_ACCEPT, args);
757 set_fs(old_fs);
758 filp->f_flags = oldflags;
759 if (error < 0) {
760 SOLD("some error");
761 putpage(buf);
762 return error;
763 }
764 if (error) {
765 SOLD("connect");
766 putpage(buf);
767 if (sizeof(ind) > ctl_maxlen) {
768 SOLD("generating CONN_IND");
769 ind.PRIM_type = T_CONN_IND;
770 ind.SRC_length = len;
771 ind.SRC_offset = sizeof(ind);
772 ind.OPT_length = ind.OPT_offset = 0;
773 ind.SEQ_number = error;
774 if(copy_to_user(ctl_buf, &ind, sizeof(ind))||
775 put_user(sizeof(ind)+ind.SRC_length,ctl_len))
776 return -EFAULT;
777 SOLD("CONN_IND created");
778 }
779 if (data_maxlen >= 0)
780 put_user(0, data_len);
781 SOLD("CONN_IND done");
782 return 0;
783 }
784 if (len>ctl_maxlen) {
785 SOLD("data don't fit");
786 putpage(buf);
787 return -EFAULT; /* XXX - is this ok ? */
788 }
789 if(copy_to_user(ctl_buf,buf,len) || put_user(len,ctl_len)){
790 SOLD("can't copy data");
791 putpage(buf);
792 return -EFAULT;
793 }
794 SOLD("ACCEPT done");
795 putpage(buf);
796 }
797 }
798 SOLD("checking data req");
799 if (data_maxlen <= 0) {
800 if (data_maxlen == 0)
801 put_user(0, data_len);
802 if (ctl_maxlen >= 0)
803 put_user(0, ctl_len);
804 return -EAGAIN;
805 }
806 SOLD("wants data");
807 if (ctl_maxlen > sizeof(udi) && sock->state == TS_IDLE) {
808 SOLD("udi fits");
809 tmpbuf = ctl_buf + sizeof(udi);
810 tmplen = ctl_maxlen - sizeof(udi);
811 } else {
812 SOLD("udi does not fit");
813 tmpbuf = NULL;
814 tmplen = 0;
815 }
816 if (put_user(tmplen, ctl_len))
817 return -EFAULT;
818 SOLD("set ctl_len");
819 oldflags = filp->f_flags;
820 filp->f_flags |= O_NONBLOCK;
821 SOLD("calling recvfrom");
822 sys_recvfrom = (int (*)(int, void __user *, size_t, unsigned, struct sockaddr __user *, int __user *))SYS(recvfrom);
823 error = sys_recvfrom(fd, data_buf, data_maxlen, 0, (struct sockaddr __user *)tmpbuf, ctl_len);
824 filp->f_flags = oldflags;
825 if (error < 0)
826 return error;
827 SOLD("error >= 0" ) ;
828 if (error && ctl_maxlen > sizeof(udi) && sock->state == TS_IDLE) {
829 SOLD("generating udi");
830 udi.PRIM_type = T_UNITDATA_IND;
831 if (get_user(udi.SRC_length, ctl_len))
832 return -EFAULT;
833 udi.SRC_offset = sizeof(udi);
834 udi.OPT_length = udi.OPT_offset = 0;
835 if (copy_to_user(ctl_buf, &udi, sizeof(udi)) ||
836 put_user(sizeof(udi)+udi.SRC_length, ctl_len))
837 return -EFAULT;
838 SOLD("udi done");
839 } else {
840 if (put_user(0, ctl_len))
841 return -EFAULT;
842 }
843 put_user(error, data_len);
844 SOLD("done");
845 return 0;
846}
847
848asmlinkage int solaris_getmsg(unsigned int fd, u32 arg1, u32 arg2, u32 arg3)
849{
850 struct file *filp;
851 struct inode *ino;
852 struct strbuf __user *ctlptr;
853 struct strbuf __user *datptr;
854 struct strbuf ctl, dat;
855 int __user *flgptr;
856 int flags;
857 int error = -EBADF;
858 struct fdtable *fdt;
859
860 SOLD("entry");
861 lock_kernel();
862 if (fd >= sysctl_nr_open)
863 goto out;
864
865 fdt = files_fdtable(current->files);
866 filp = fdt->fd[fd];
867 if(!filp) goto out;
868
869 ino = filp->f_path.dentry->d_inode;
870 if (!ino || !S_ISSOCK(ino->i_mode))
871 goto out;
872
873 ctlptr = (struct strbuf __user *)A(arg1);
874 datptr = (struct strbuf __user *)A(arg2);
875 flgptr = (int __user *)A(arg3);
876
877 error = -EFAULT;
878
879 if (ctlptr) {
880 if (copy_from_user(&ctl,ctlptr,sizeof(struct strbuf)) ||
881 put_user(-1,&ctlptr->len))
882 goto out;
883 } else
884 ctl.maxlen = -1;
885
886 if (datptr) {
887 if (copy_from_user(&dat,datptr,sizeof(struct strbuf)) ||
888 put_user(-1,&datptr->len))
889 goto out;
890 } else
891 dat.maxlen = -1;
892
893 if (get_user(flags,flgptr))
894 goto out;
895
896 switch (flags) {
897 case 0:
898 case MSG_HIPRI:
899 case MSG_ANY:
900 case MSG_BAND:
901 break;
902 default:
903 error = -EINVAL;
904 goto out;
905 }
906
907 error = timod_getmsg(fd,A(ctl.buf),ctl.maxlen,&ctlptr->len,
908 A(dat.buf),dat.maxlen,&datptr->len,&flags);
909
910 if (!error && put_user(flags,flgptr))
911 error = -EFAULT;
912out:
913 unlock_kernel();
914 SOLD("done");
915 return error;
916}
917
918asmlinkage int solaris_putmsg(unsigned int fd, u32 arg1, u32 arg2, u32 arg3)
919{
920 struct file *filp;
921 struct inode *ino;
922 struct strbuf __user *ctlptr;
923 struct strbuf __user *datptr;
924 struct strbuf ctl, dat;
925 int flags = (int) arg3;
926 int error = -EBADF;
927 struct fdtable *fdt;
928
929 SOLD("entry");
930 lock_kernel();
931 if (fd >= sysctl_nr_open)
932 goto out;
933
934 fdt = files_fdtable(current->files);
935 filp = fdt->fd[fd];
936 if(!filp) goto out;
937
938 ino = filp->f_path.dentry->d_inode;
939 if (!ino) goto out;
940
941 if (!S_ISSOCK(ino->i_mode) &&
942 (imajor(ino) != 30 || iminor(ino) != 1))
943 goto out;
944
945 ctlptr = A(arg1);
946 datptr = A(arg2);
947
948 error = -EFAULT;
949
950 if (ctlptr) {
951 if (copy_from_user(&ctl,ctlptr,sizeof(ctl)))
952 goto out;
953 if (ctl.len < 0 && flags) {
954 error = -EINVAL;
955 goto out;
956 }
957 } else {
958 ctl.len = 0;
959 ctl.buf = 0;
960 }
961
962 if (datptr) {
963 if (copy_from_user(&dat,datptr,sizeof(dat)))
964 goto out;
965 } else {
966 dat.len = 0;
967 dat.buf = 0;
968 }
969
970 error = timod_putmsg(fd,A(ctl.buf),ctl.len,
971 A(dat.buf),dat.len,flags);
972out:
973 unlock_kernel();
974 SOLD("done");
975 return error;
976}
diff --git a/drivers/block/brd.c b/drivers/block/brd.c
index 85364804364f..7bd76639544c 100644
--- a/drivers/block/brd.c
+++ b/drivers/block/brd.c
@@ -108,7 +108,7 @@ static struct page *brd_insert_page(struct brd_device *brd, sector_t sector)
108#ifndef CONFIG_BLK_DEV_XIP 108#ifndef CONFIG_BLK_DEV_XIP
109 gfp_flags |= __GFP_HIGHMEM; 109 gfp_flags |= __GFP_HIGHMEM;
110#endif 110#endif
111 page = alloc_page(GFP_NOIO | __GFP_HIGHMEM | __GFP_ZERO); 111 page = alloc_page(gfp_flags);
112 if (!page) 112 if (!page)
113 return NULL; 113 return NULL;
114 114
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index f0b00ec1e47e..e03c67dd3e63 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -44,8 +44,8 @@
44 44
45#ifdef CONFIG_HID_DEBUG 45#ifdef CONFIG_HID_DEBUG
46int hid_debug = 0; 46int hid_debug = 0;
47module_param_named(debug, hid_debug, bool, 0600); 47module_param_named(debug, hid_debug, int, 0600);
48MODULE_PARM_DESC(debug, "Turn HID debugging mode on and off"); 48MODULE_PARM_DESC(debug, "HID debugging (0=off, 1=probing info, 2=continuous data dumping)");
49EXPORT_SYMBOL_GPL(hid_debug); 49EXPORT_SYMBOL_GPL(hid_debug);
50#endif 50#endif
51 51
@@ -97,7 +97,7 @@ static struct hid_field *hid_register_field(struct hid_report *report, unsigned
97 field->index = report->maxfield++; 97 field->index = report->maxfield++;
98 report->field[field->index] = field; 98 report->field[field->index] = field;
99 field->usage = (struct hid_usage *)(field + 1); 99 field->usage = (struct hid_usage *)(field + 1);
100 field->value = (unsigned *)(field->usage + usages); 100 field->value = (s32 *)(field->usage + usages);
101 field->report = report; 101 field->report = report;
102 102
103 return field; 103 return field;
@@ -830,7 +830,8 @@ static void hid_process_event(struct hid_device *hid, struct hid_field *field, s
830 * reporting to the layer). 830 * reporting to the layer).
831 */ 831 */
832 832
833void hid_input_field(struct hid_device *hid, struct hid_field *field, __u8 *data, int interrupt) 833static void hid_input_field(struct hid_device *hid, struct hid_field *field,
834 __u8 *data, int interrupt)
834{ 835{
835 unsigned n; 836 unsigned n;
836 unsigned count = field->report_count; 837 unsigned count = field->report_count;
@@ -876,7 +877,6 @@ void hid_input_field(struct hid_device *hid, struct hid_field *field, __u8 *data
876exit: 877exit:
877 kfree(value); 878 kfree(value);
878} 879}
879EXPORT_SYMBOL_GPL(hid_input_field);
880 880
881/* 881/*
882 * Output the field into the report. 882 * Output the field into the report.
@@ -988,8 +988,13 @@ int hid_input_report(struct hid_device *hid, int type, u8 *data, int size, int i
988 988
989 if ((hid->claimed & HID_CLAIMED_HIDDEV) && hid->hiddev_report_event) 989 if ((hid->claimed & HID_CLAIMED_HIDDEV) && hid->hiddev_report_event)
990 hid->hiddev_report_event(hid, report); 990 hid->hiddev_report_event(hid, report);
991 if (hid->claimed & HID_CLAIMED_HIDRAW) 991 if (hid->claimed & HID_CLAIMED_HIDRAW) {
992 hidraw_report_event(hid, data, size); 992 /* numbered reports need to be passed with the report num */
993 if (report_enum->numbered)
994 hidraw_report_event(hid, data - 1, size + 1);
995 else
996 hidraw_report_event(hid, data, size);
997 }
993 998
994 for (n = 0; n < report->maxfield; n++) 999 for (n = 0; n < report->maxfield; n++)
995 hid_input_field(hid, report->field[n], data, interrupt); 1000 hid_input_field(hid, report->field[n], data, interrupt);
diff --git a/drivers/hid/hid-debug.c b/drivers/hid/hid-debug.c
index 5c24fe46d8eb..f88714b06000 100644
--- a/drivers/hid/hid-debug.c
+++ b/drivers/hid/hid-debug.c
@@ -498,7 +498,7 @@ void hid_dump_device(struct hid_device *device) {
498EXPORT_SYMBOL_GPL(hid_dump_device); 498EXPORT_SYMBOL_GPL(hid_dump_device);
499 499
500void hid_dump_input(struct hid_usage *usage, __s32 value) { 500void hid_dump_input(struct hid_usage *usage, __s32 value) {
501 if (!hid_debug) 501 if (hid_debug < 2)
502 return; 502 return;
503 503
504 printk(KERN_DEBUG "hid-debug: input "); 504 printk(KERN_DEBUG "hid-debug: input ");
diff --git a/drivers/hid/hid-input-quirks.c b/drivers/hid/hid-input-quirks.c
index dceadd0c1419..4c2052c658f1 100644
--- a/drivers/hid/hid-input-quirks.c
+++ b/drivers/hid/hid-input-quirks.c
@@ -276,6 +276,21 @@ static int quirk_btc_8193(struct hid_usage *usage, struct input_dev *input,
276 return 1; 276 return 1;
277} 277}
278 278
279static int quirk_sunplus_wdesktop(struct hid_usage *usage, struct input_dev *input,
280 unsigned long **bit, int *max)
281{
282 if ((usage->hid & HID_USAGE_PAGE) != HID_UP_CONSUMER)
283 return 0;
284
285 switch (usage->hid & HID_USAGE) {
286 case 0x2003: map_key_clear(KEY_ZOOMIN); break;
287 case 0x2103: map_key_clear(KEY_ZOOMOUT); break;
288 default:
289 return 0;
290 }
291 return 1;
292}
293
279#define VENDOR_ID_BELKIN 0x1020 294#define VENDOR_ID_BELKIN 0x1020
280#define DEVICE_ID_BELKIN_WIRELESS_KEYBOARD 0x0006 295#define DEVICE_ID_BELKIN_WIRELESS_KEYBOARD 0x0006
281 296
@@ -306,6 +321,9 @@ static int quirk_btc_8193(struct hid_usage *usage, struct input_dev *input,
306#define VENDOR_ID_PETALYNX 0x18b1 321#define VENDOR_ID_PETALYNX 0x18b1
307#define DEVICE_ID_PETALYNX_MAXTER_REMOTE 0x0037 322#define DEVICE_ID_PETALYNX_MAXTER_REMOTE 0x0037
308 323
324#define VENDOR_ID_SUNPLUS 0x04fc
325#define DEVICE_ID_SUNPLUS_WDESKTOP 0x05d8
326
309static const struct hid_input_blacklist { 327static const struct hid_input_blacklist {
310 __u16 idVendor; 328 __u16 idVendor;
311 __u16 idProduct; 329 __u16 idProduct;
@@ -332,8 +350,10 @@ static const struct hid_input_blacklist {
332 { VENDOR_ID_MONTEREY, DEVICE_ID_GENIUS_KB29E, quirk_cherry_genius_29e }, 350 { VENDOR_ID_MONTEREY, DEVICE_ID_GENIUS_KB29E, quirk_cherry_genius_29e },
333 351
334 { VENDOR_ID_PETALYNX, DEVICE_ID_PETALYNX_MAXTER_REMOTE, quirk_petalynx_remote }, 352 { VENDOR_ID_PETALYNX, DEVICE_ID_PETALYNX_MAXTER_REMOTE, quirk_petalynx_remote },
335 353
336 { 0, 0, 0 } 354 { VENDOR_ID_SUNPLUS, DEVICE_ID_SUNPLUS_WDESKTOP, quirk_sunplus_wdesktop },
355
356 { 0, 0, NULL }
337}; 357};
338 358
339int hidinput_mapping_quirks(struct hid_usage *usage, 359int hidinput_mapping_quirks(struct hid_usage *usage,
diff --git a/drivers/hid/usbhid/Kconfig b/drivers/hid/usbhid/Kconfig
index 7160fa65d79b..18f09104765c 100644
--- a/drivers/hid/usbhid/Kconfig
+++ b/drivers/hid/usbhid/Kconfig
@@ -71,6 +71,14 @@ config LOGITECH_FF
71 Note: if you say N here, this device will still be supported, but without 71 Note: if you say N here, this device will still be supported, but without
72 force feedback. 72 force feedback.
73 73
74config LOGIRUMBLEPAD2_FF
75 bool "Logitech Rumblepad 2 support"
76 depends on HID_FF
77 select INPUT_FF_MEMLESS if USB_HID
78 help
79 Say Y here if you want to enable force feedback support for Logitech
80 Rumblepad 2 devices.
81
74config PANTHERLORD_FF 82config PANTHERLORD_FF
75 bool "PantherLord/GreenAsia based device support" 83 bool "PantherLord/GreenAsia based device support"
76 depends on HID_FF 84 depends on HID_FF
@@ -80,8 +88,8 @@ config PANTHERLORD_FF
80 or adapter and want to enable force feedback support for it. 88 or adapter and want to enable force feedback support for it.
81 89
82config THRUSTMASTER_FF 90config THRUSTMASTER_FF
83 bool "ThrustMaster devices support (EXPERIMENTAL)" 91 bool "ThrustMaster devices support"
84 depends on HID_FF && EXPERIMENTAL 92 depends on HID_FF
85 select INPUT_FF_MEMLESS if USB_HID 93 select INPUT_FF_MEMLESS if USB_HID
86 help 94 help
87 Say Y here if you have a THRUSTMASTER FireStore Dual Power 2 or 95 Say Y here if you have a THRUSTMASTER FireStore Dual Power 2 or
diff --git a/drivers/hid/usbhid/Makefile b/drivers/hid/usbhid/Makefile
index 8e6ab5b164a2..00a7b7090192 100644
--- a/drivers/hid/usbhid/Makefile
+++ b/drivers/hid/usbhid/Makefile
@@ -16,6 +16,9 @@ endif
16ifeq ($(CONFIG_LOGITECH_FF),y) 16ifeq ($(CONFIG_LOGITECH_FF),y)
17 usbhid-objs += hid-lgff.o 17 usbhid-objs += hid-lgff.o
18endif 18endif
19ifeq ($(CONFIG_LOGIRUMBLEPAD2_FF),y)
20 usbhid-objs += hid-lg2ff.o
21endif
19ifeq ($(CONFIG_PANTHERLORD_FF),y) 22ifeq ($(CONFIG_PANTHERLORD_FF),y)
20 usbhid-objs += hid-plff.o 23 usbhid-objs += hid-plff.o
21endif 24endif
diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c
index d95979f0e028..e0d805f1b2bf 100644
--- a/drivers/hid/usbhid/hid-core.c
+++ b/drivers/hid/usbhid/hid-core.c
@@ -82,6 +82,7 @@ static int hid_start_in(struct hid_device *hid)
82 82
83 spin_lock_irqsave(&usbhid->inlock, flags); 83 spin_lock_irqsave(&usbhid->inlock, flags);
84 if (hid->open > 0 && !test_bit(HID_SUSPENDED, &usbhid->iofl) && 84 if (hid->open > 0 && !test_bit(HID_SUSPENDED, &usbhid->iofl) &&
85 !test_bit(HID_DISCONNECTED, &usbhid->iofl) &&
85 !test_and_set_bit(HID_IN_RUNNING, &usbhid->iofl)) { 86 !test_and_set_bit(HID_IN_RUNNING, &usbhid->iofl)) {
86 rc = usb_submit_urb(usbhid->urbin, GFP_ATOMIC); 87 rc = usb_submit_urb(usbhid->urbin, GFP_ATOMIC);
87 if (rc != 0) 88 if (rc != 0)
@@ -155,7 +156,7 @@ static void hid_io_error(struct hid_device *hid)
155 spin_lock_irqsave(&usbhid->inlock, flags); 156 spin_lock_irqsave(&usbhid->inlock, flags);
156 157
157 /* Stop when disconnected */ 158 /* Stop when disconnected */
158 if (usb_get_intfdata(usbhid->intf) == NULL) 159 if (test_bit(HID_DISCONNECTED, &usbhid->iofl))
159 goto done; 160 goto done;
160 161
161 /* If it has been a while since the last error, we'll assume 162 /* If it has been a while since the last error, we'll assume
@@ -341,7 +342,7 @@ static void hid_irq_out(struct urb *urb)
341 if (usbhid->outhead != usbhid->outtail) { 342 if (usbhid->outhead != usbhid->outtail) {
342 if (hid_submit_out(hid)) { 343 if (hid_submit_out(hid)) {
343 clear_bit(HID_OUT_RUNNING, &usbhid->iofl); 344 clear_bit(HID_OUT_RUNNING, &usbhid->iofl);
344 wake_up(&hid->wait); 345 wake_up(&usbhid->wait);
345 } 346 }
346 spin_unlock_irqrestore(&usbhid->outlock, flags); 347 spin_unlock_irqrestore(&usbhid->outlock, flags);
347 return; 348 return;
@@ -349,7 +350,7 @@ static void hid_irq_out(struct urb *urb)
349 350
350 clear_bit(HID_OUT_RUNNING, &usbhid->iofl); 351 clear_bit(HID_OUT_RUNNING, &usbhid->iofl);
351 spin_unlock_irqrestore(&usbhid->outlock, flags); 352 spin_unlock_irqrestore(&usbhid->outlock, flags);
352 wake_up(&hid->wait); 353 wake_up(&usbhid->wait);
353} 354}
354 355
355/* 356/*
@@ -391,7 +392,7 @@ static void hid_ctrl(struct urb *urb)
391 if (usbhid->ctrlhead != usbhid->ctrltail) { 392 if (usbhid->ctrlhead != usbhid->ctrltail) {
392 if (hid_submit_ctrl(hid)) { 393 if (hid_submit_ctrl(hid)) {
393 clear_bit(HID_CTRL_RUNNING, &usbhid->iofl); 394 clear_bit(HID_CTRL_RUNNING, &usbhid->iofl);
394 wake_up(&hid->wait); 395 wake_up(&usbhid->wait);
395 } 396 }
396 spin_unlock_irqrestore(&usbhid->ctrllock, flags); 397 spin_unlock_irqrestore(&usbhid->ctrllock, flags);
397 return; 398 return;
@@ -399,7 +400,7 @@ static void hid_ctrl(struct urb *urb)
399 400
400 clear_bit(HID_CTRL_RUNNING, &usbhid->iofl); 401 clear_bit(HID_CTRL_RUNNING, &usbhid->iofl);
401 spin_unlock_irqrestore(&usbhid->ctrllock, flags); 402 spin_unlock_irqrestore(&usbhid->ctrllock, flags);
402 wake_up(&hid->wait); 403 wake_up(&usbhid->wait);
403} 404}
404 405
405void usbhid_submit_report(struct hid_device *hid, struct hid_report *report, unsigned char dir) 406void usbhid_submit_report(struct hid_device *hid, struct hid_report *report, unsigned char dir)
@@ -478,8 +479,9 @@ int usbhid_wait_io(struct hid_device *hid)
478{ 479{
479 struct usbhid_device *usbhid = hid->driver_data; 480 struct usbhid_device *usbhid = hid->driver_data;
480 481
481 if (!wait_event_timeout(hid->wait, (!test_bit(HID_CTRL_RUNNING, &usbhid->iofl) && 482 if (!wait_event_timeout(usbhid->wait,
482 !test_bit(HID_OUT_RUNNING, &usbhid->iofl)), 483 (!test_bit(HID_CTRL_RUNNING, &usbhid->iofl) &&
484 !test_bit(HID_OUT_RUNNING, &usbhid->iofl)),
483 10*HZ)) { 485 10*HZ)) {
484 dbg_hid("timeout waiting for ctrl or out queue to clear\n"); 486 dbg_hid("timeout waiting for ctrl or out queue to clear\n");
485 return -1; 487 return -1;
@@ -610,10 +612,11 @@ static void usbhid_set_leds(struct hid_device *hid)
610/* 612/*
611 * Traverse the supplied list of reports and find the longest 613 * Traverse the supplied list of reports and find the longest
612 */ 614 */
613static void hid_find_max_report(struct hid_device *hid, unsigned int type, int *max) 615static void hid_find_max_report(struct hid_device *hid, unsigned int type,
616 unsigned int *max)
614{ 617{
615 struct hid_report *report; 618 struct hid_report *report;
616 int size; 619 unsigned int size;
617 620
618 list_for_each_entry(report, &hid->report_enum[type].report_list, list) { 621 list_for_each_entry(report, &hid->report_enum[type].report_list, list) {
619 size = ((report->size - 1) >> 3) + 1; 622 size = ((report->size - 1) >> 3) + 1;
@@ -705,9 +708,9 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf)
705 struct hid_descriptor *hdesc; 708 struct hid_descriptor *hdesc;
706 struct hid_device *hid; 709 struct hid_device *hid;
707 u32 quirks = 0; 710 u32 quirks = 0;
708 unsigned rsize = 0; 711 unsigned int insize = 0, rsize = 0;
709 char *rdesc; 712 char *rdesc;
710 int n, len, insize = 0; 713 int n, len;
711 struct usbhid_device *usbhid; 714 struct usbhid_device *usbhid;
712 715
713 quirks = usbhid_lookup_quirk(le16_to_cpu(dev->descriptor.idVendor), 716 quirks = usbhid_lookup_quirk(le16_to_cpu(dev->descriptor.idVendor),
@@ -800,6 +803,22 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf)
800 goto fail; 803 goto fail;
801 } 804 }
802 805
806 hid->name[0] = 0;
807
808 if (dev->manufacturer)
809 strlcpy(hid->name, dev->manufacturer, sizeof(hid->name));
810
811 if (dev->product) {
812 if (dev->manufacturer)
813 strlcat(hid->name, " ", sizeof(hid->name));
814 strlcat(hid->name, dev->product, sizeof(hid->name));
815 }
816
817 if (!strlen(hid->name))
818 snprintf(hid->name, sizeof(hid->name), "HID %04x:%04x",
819 le16_to_cpu(dev->descriptor.idVendor),
820 le16_to_cpu(dev->descriptor.idProduct));
821
803 for (n = 0; n < interface->desc.bNumEndpoints; n++) { 822 for (n = 0; n < interface->desc.bNumEndpoints; n++) {
804 823
805 struct usb_endpoint_descriptor *endpoint; 824 struct usb_endpoint_descriptor *endpoint;
@@ -812,6 +831,14 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf)
812 831
813 interval = endpoint->bInterval; 832 interval = endpoint->bInterval;
814 833
834 /* Some vendors give fullspeed interval on highspeed devides */
835 if (quirks & HID_QUIRK_FULLSPEED_INTERVAL &&
836 dev->speed == USB_SPEED_HIGH) {
837 interval = fls(endpoint->bInterval*8);
838 printk(KERN_INFO "%s: Fixing fullspeed to highspeed interval: %d -> %d\n",
839 hid->name, endpoint->bInterval, interval);
840 }
841
815 /* Change the polling interval of mice. */ 842 /* Change the polling interval of mice. */
816 if (hid->collection->usage == HID_GD_MOUSE && hid_mousepoll_interval > 0) 843 if (hid->collection->usage == HID_GD_MOUSE && hid_mousepoll_interval > 0)
817 interval = hid_mousepoll_interval; 844 interval = hid_mousepoll_interval;
@@ -844,8 +871,7 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf)
844 goto fail; 871 goto fail;
845 } 872 }
846 873
847 init_waitqueue_head(&hid->wait); 874 init_waitqueue_head(&usbhid->wait);
848
849 INIT_WORK(&usbhid->reset_work, hid_reset); 875 INIT_WORK(&usbhid->reset_work, hid_reset);
850 setup_timer(&usbhid->io_retry, hid_retry_timeout, (unsigned long) hid); 876 setup_timer(&usbhid->io_retry, hid_retry_timeout, (unsigned long) hid);
851 877
@@ -859,22 +885,6 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf)
859 usbhid->intf = intf; 885 usbhid->intf = intf;
860 usbhid->ifnum = interface->desc.bInterfaceNumber; 886 usbhid->ifnum = interface->desc.bInterfaceNumber;
861 887
862 hid->name[0] = 0;
863
864 if (dev->manufacturer)
865 strlcpy(hid->name, dev->manufacturer, sizeof(hid->name));
866
867 if (dev->product) {
868 if (dev->manufacturer)
869 strlcat(hid->name, " ", sizeof(hid->name));
870 strlcat(hid->name, dev->product, sizeof(hid->name));
871 }
872
873 if (!strlen(hid->name))
874 snprintf(hid->name, sizeof(hid->name), "HID %04x:%04x",
875 le16_to_cpu(dev->descriptor.idVendor),
876 le16_to_cpu(dev->descriptor.idProduct));
877
878 hid->bus = BUS_USB; 888 hid->bus = BUS_USB;
879 hid->vendor = le16_to_cpu(dev->descriptor.idVendor); 889 hid->vendor = le16_to_cpu(dev->descriptor.idVendor);
880 hid->product = le16_to_cpu(dev->descriptor.idProduct); 890 hid->product = le16_to_cpu(dev->descriptor.idProduct);
@@ -932,6 +942,7 @@ static void hid_disconnect(struct usb_interface *intf)
932 942
933 spin_lock_irq(&usbhid->inlock); /* Sync with error handler */ 943 spin_lock_irq(&usbhid->inlock); /* Sync with error handler */
934 usb_set_intfdata(intf, NULL); 944 usb_set_intfdata(intf, NULL);
945 set_bit(HID_DISCONNECTED, &usbhid->iofl);
935 spin_unlock_irq(&usbhid->inlock); 946 spin_unlock_irq(&usbhid->inlock);
936 usb_kill_urb(usbhid->urbin); 947 usb_kill_urb(usbhid->urbin);
937 usb_kill_urb(usbhid->urbout); 948 usb_kill_urb(usbhid->urbout);
diff --git a/drivers/hid/usbhid/hid-ff.c b/drivers/hid/usbhid/hid-ff.c
index 4c210e16b1b4..1d0dac52f166 100644
--- a/drivers/hid/usbhid/hid-ff.c
+++ b/drivers/hid/usbhid/hid-ff.c
@@ -59,6 +59,9 @@ static struct hid_ff_initializer inits[] = {
59 { 0x46d, 0xc295, hid_lgff_init }, /* Logitech MOMO force wheel */ 59 { 0x46d, 0xc295, hid_lgff_init }, /* Logitech MOMO force wheel */
60 { 0x46d, 0xca03, hid_lgff_init }, /* Logitech MOMO force wheel */ 60 { 0x46d, 0xca03, hid_lgff_init }, /* Logitech MOMO force wheel */
61#endif 61#endif
62#ifdef CONFIG_LOGIRUMBLEPAD2_FF
63 { 0x46d, 0xc218, hid_lg2ff_init }, /* Logitech Rumblepad 2 */
64#endif
62#ifdef CONFIG_PANTHERLORD_FF 65#ifdef CONFIG_PANTHERLORD_FF
63 { 0x810, 0x0001, hid_plff_init }, /* "Twin USB Joystick" */ 66 { 0x810, 0x0001, hid_plff_init }, /* "Twin USB Joystick" */
64 { 0xe8f, 0x0003, hid_plff_init }, /* "GreenAsia Inc. USB Joystick " */ 67 { 0xe8f, 0x0003, hid_plff_init }, /* "GreenAsia Inc. USB Joystick " */
diff --git a/drivers/hid/usbhid/hid-lg2ff.c b/drivers/hid/usbhid/hid-lg2ff.c
new file mode 100644
index 000000000000..d469bd0061c9
--- /dev/null
+++ b/drivers/hid/usbhid/hid-lg2ff.c
@@ -0,0 +1,114 @@
1/*
2 * Force feedback support for Logitech Rumblepad 2
3 *
4 * Copyright (c) 2008 Anssi Hannula <anssi.hannula@gmail.com>
5 */
6
7/*
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22
23
24#include <linux/input.h>
25#include <linux/usb.h>
26#include <linux/hid.h>
27#include "usbhid.h"
28
29struct lg2ff_device {
30 struct hid_report *report;
31};
32
33static int play_effect(struct input_dev *dev, void *data,
34 struct ff_effect *effect)
35{
36 struct hid_device *hid = input_get_drvdata(dev);
37 struct lg2ff_device *lg2ff = data;
38 int weak, strong;
39
40 strong = effect->u.rumble.strong_magnitude;
41 weak = effect->u.rumble.weak_magnitude;
42
43 if (weak || strong) {
44 weak = weak * 0xff / 0xffff;
45 strong = strong * 0xff / 0xffff;
46
47 lg2ff->report->field[0]->value[0] = 0x51;
48 lg2ff->report->field[0]->value[2] = weak;
49 lg2ff->report->field[0]->value[4] = strong;
50 } else {
51 lg2ff->report->field[0]->value[0] = 0xf3;
52 lg2ff->report->field[0]->value[2] = 0x00;
53 lg2ff->report->field[0]->value[4] = 0x00;
54 }
55
56 usbhid_submit_report(hid, lg2ff->report, USB_DIR_OUT);
57 return 0;
58}
59
60int hid_lg2ff_init(struct hid_device *hid)
61{
62 struct lg2ff_device *lg2ff;
63 struct hid_report *report;
64 struct hid_input *hidinput = list_entry(hid->inputs.next,
65 struct hid_input, list);
66 struct list_head *report_list =
67 &hid->report_enum[HID_OUTPUT_REPORT].report_list;
68 struct input_dev *dev = hidinput->input;
69 int error;
70
71 if (list_empty(report_list)) {
72 printk(KERN_ERR "hid-lg2ff: no output report found\n");
73 return -ENODEV;
74 }
75
76 report = list_entry(report_list->next, struct hid_report, list);
77
78 if (report->maxfield < 1) {
79 printk(KERN_ERR "hid-lg2ff: output report is empty\n");
80 return -ENODEV;
81 }
82 if (report->field[0]->report_count < 7) {
83 printk(KERN_ERR "hid-lg2ff: not enough values in the field\n");
84 return -ENODEV;
85 }
86
87 lg2ff = kmalloc(sizeof(struct lg2ff_device), GFP_KERNEL);
88 if (!lg2ff)
89 return -ENOMEM;
90
91 set_bit(FF_RUMBLE, dev->ffbit);
92
93 error = input_ff_create_memless(dev, lg2ff, play_effect);
94 if (error) {
95 kfree(lg2ff);
96 return error;
97 }
98
99 lg2ff->report = report;
100 report->field[0]->value[0] = 0xf3;
101 report->field[0]->value[1] = 0x00;
102 report->field[0]->value[2] = 0x00;
103 report->field[0]->value[3] = 0x00;
104 report->field[0]->value[4] = 0x00;
105 report->field[0]->value[5] = 0x00;
106 report->field[0]->value[6] = 0x00;
107
108 usbhid_submit_report(hid, report, USB_DIR_OUT);
109
110 printk(KERN_INFO "Force feedback for Logitech Rumblepad 2 by "
111 "Anssi Hannula <anssi.hannula@gmail.com>\n");
112
113 return 0;
114}
diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c
index e29a057cbea2..28ddc3fdd3d1 100644
--- a/drivers/hid/usbhid/hid-quirks.c
+++ b/drivers/hid/usbhid/hid-quirks.c
@@ -32,6 +32,9 @@
32#define USB_VENDOR_ID_ADS_TECH 0x06e1 32#define USB_VENDOR_ID_ADS_TECH 0x06e1
33#define USB_DEVICE_ID_ADS_TECH_RADIO_SI470X 0xa155 33#define USB_DEVICE_ID_ADS_TECH_RADIO_SI470X 0xa155
34 34
35#define USB_VENDOR_ID_AFATECH 0x15a4
36#define USB_DEVICE_ID_AFATECH_AF9016 0x9016
37
35#define USB_VENDOR_ID_AIPTEK 0x08ca 38#define USB_VENDOR_ID_AIPTEK 0x08ca
36#define USB_DEVICE_ID_AIPTEK_01 0x0001 39#define USB_DEVICE_ID_AIPTEK_01 0x0001
37#define USB_DEVICE_ID_AIPTEK_10 0x0010 40#define USB_DEVICE_ID_AIPTEK_10 0x0010
@@ -124,6 +127,9 @@
124#define USB_DEVICE_ID_DELORME_EARTHMATE 0x0100 127#define USB_DEVICE_ID_DELORME_EARTHMATE 0x0100
125#define USB_DEVICE_ID_DELORME_EM_LT20 0x0200 128#define USB_DEVICE_ID_DELORME_EM_LT20 0x0200
126 129
130#define USB_VENDOR_ID_DMI 0x0c0b
131#define USB_DEVICE_ID_DMI_ENC 0x5fab
132
127#define USB_VENDOR_ID_ELO 0x04E7 133#define USB_VENDOR_ID_ELO 0x04E7
128#define USB_DEVICE_ID_ELO_TS2700 0x0020 134#define USB_DEVICE_ID_ELO_TS2700 0x0020
129 135
@@ -199,17 +205,6 @@
199#define USB_DEVICE_ID_GTCO_502 0x0502 205#define USB_DEVICE_ID_GTCO_502 0x0502
200#define USB_DEVICE_ID_GTCO_503 0x0503 206#define USB_DEVICE_ID_GTCO_503 0x0503
201#define USB_DEVICE_ID_GTCO_504 0x0504 207#define USB_DEVICE_ID_GTCO_504 0x0504
202#define USB_DEVICE_ID_GTCO_600 0x0600
203#define USB_DEVICE_ID_GTCO_601 0x0601
204#define USB_DEVICE_ID_GTCO_602 0x0602
205#define USB_DEVICE_ID_GTCO_603 0x0603
206#define USB_DEVICE_ID_GTCO_604 0x0604
207#define USB_DEVICE_ID_GTCO_605 0x0605
208#define USB_DEVICE_ID_GTCO_606 0x0606
209#define USB_DEVICE_ID_GTCO_607 0x0607
210#define USB_DEVICE_ID_GTCO_608 0x0608
211#define USB_DEVICE_ID_GTCO_609 0x0609
212#define USB_DEVICE_ID_GTCO_609 0x0609
213#define USB_DEVICE_ID_GTCO_1000 0x1000 208#define USB_DEVICE_ID_GTCO_1000 0x1000
214#define USB_DEVICE_ID_GTCO_1001 0x1001 209#define USB_DEVICE_ID_GTCO_1001 0x1001
215#define USB_DEVICE_ID_GTCO_1002 0x1002 210#define USB_DEVICE_ID_GTCO_1002 0x1002
@@ -320,6 +315,7 @@
320#define USB_DEVICE_ID_LOGITECH_CORDLESS_DESKTOP_LX500 0xc512 315#define USB_DEVICE_ID_LOGITECH_CORDLESS_DESKTOP_LX500 0xc512
321#define USB_DEVICE_ID_MX3000_RECEIVER 0xc513 316#define USB_DEVICE_ID_MX3000_RECEIVER 0xc513
322#define USB_DEVICE_ID_DINOVO_EDGE 0xc714 317#define USB_DEVICE_ID_DINOVO_EDGE 0xc714
318#define USB_DEVICE_ID_DINOVO_MINI 0xc71f
323 319
324#define USB_VENDOR_ID_MCC 0x09db 320#define USB_VENDOR_ID_MCC 0x09db
325#define USB_DEVICE_ID_MCC_PMD1024LS 0x0076 321#define USB_DEVICE_ID_MCC_PMD1024LS 0x0076
@@ -332,6 +328,7 @@
332#define USB_VENDOR_ID_MICROSOFT 0x045e 328#define USB_VENDOR_ID_MICROSOFT 0x045e
333#define USB_DEVICE_ID_SIDEWINDER_GV 0x003b 329#define USB_DEVICE_ID_SIDEWINDER_GV 0x003b
334#define USB_DEVICE_ID_WIRELESS_OPTICAL_DESKTOP_3_0 0x009d 330#define USB_DEVICE_ID_WIRELESS_OPTICAL_DESKTOP_3_0 0x009d
331#define USB_DEVICE_ID_DESKTOP_RECV_1028 0x00f9
335#define USB_DEVICE_ID_MS_NE4K 0x00db 332#define USB_DEVICE_ID_MS_NE4K 0x00db
336#define USB_DEVICE_ID_MS_LK6K 0x00f9 333#define USB_DEVICE_ID_MS_LK6K 0x00f9
337 334
@@ -377,6 +374,9 @@
377#define USB_VENDOR_ID_SUN 0x0430 374#define USB_VENDOR_ID_SUN 0x0430
378#define USB_DEVICE_ID_RARITAN_KVM_DONGLE 0xcdab 375#define USB_DEVICE_ID_RARITAN_KVM_DONGLE 0xcdab
379 376
377#define USB_VENDOR_ID_SUNPLUS 0x04fc
378#define USB_DEVICE_ID_SUNPLUS_WDESKTOP 0x05d8
379
380#define USB_VENDOR_ID_TOPMAX 0x0663 380#define USB_VENDOR_ID_TOPMAX 0x0663
381#define USB_DEVICE_ID_TOPMAX_COBRAPAD 0x0103 381#define USB_DEVICE_ID_TOPMAX_COBRAPAD 0x0103
382 382
@@ -435,9 +435,13 @@ static const struct hid_blacklist {
435 { USB_VENDOR_ID_TOPMAX, USB_DEVICE_ID_TOPMAX_COBRAPAD, HID_QUIRK_BADPAD }, 435 { USB_VENDOR_ID_TOPMAX, USB_DEVICE_ID_TOPMAX_COBRAPAD, HID_QUIRK_BADPAD },
436 436
437 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_EDGE, HID_QUIRK_DUPLICATE_USAGES }, 437 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_EDGE, HID_QUIRK_DUPLICATE_USAGES },
438 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_MINI, HID_QUIRK_DUPLICATE_USAGES },
439
440 { USB_VENDOR_ID_AFATECH, USB_DEVICE_ID_AFATECH_AF9016, HID_QUIRK_FULLSPEED_INTERVAL },
438 441
439 { USB_VENDOR_ID_BELKIN, USB_DEVICE_ID_FLIP_KVM, HID_QUIRK_HIDDEV }, 442 { USB_VENDOR_ID_BELKIN, USB_DEVICE_ID_FLIP_KVM, HID_QUIRK_HIDDEV },
440 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL4, HID_QUIRK_HIDDEV | HID_QUIRK_IGNORE_HIDINPUT }, 443 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL4, HID_QUIRK_HIDDEV | HID_QUIRK_IGNORE_HIDINPUT },
444 { USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_IR_REMOTE, HID_QUIRK_HIDDEV | HID_QUIRK_IGNORE_HIDINPUT },
441 { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_SIDEWINDER_GV, HID_QUIRK_HIDINPUT }, 445 { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_SIDEWINDER_GV, HID_QUIRK_HIDINPUT },
442 446
443 { USB_VENDOR_ID_EZKEY, USB_DEVICE_ID_BTC_8193, HID_QUIRK_HWHEEL_WHEEL_INVERT }, 447 { USB_VENDOR_ID_EZKEY, USB_DEVICE_ID_BTC_8193, HID_QUIRK_HWHEEL_WHEEL_INVERT },
@@ -518,16 +522,6 @@ static const struct hid_blacklist {
518 { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_502, HID_QUIRK_IGNORE }, 522 { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_502, HID_QUIRK_IGNORE },
519 { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_503, HID_QUIRK_IGNORE }, 523 { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_503, HID_QUIRK_IGNORE },
520 { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_504, HID_QUIRK_IGNORE }, 524 { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_504, HID_QUIRK_IGNORE },
521 { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_600, HID_QUIRK_IGNORE },
522 { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_601, HID_QUIRK_IGNORE },
523 { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_602, HID_QUIRK_IGNORE },
524 { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_603, HID_QUIRK_IGNORE },
525 { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_604, HID_QUIRK_IGNORE },
526 { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_605, HID_QUIRK_IGNORE },
527 { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_606, HID_QUIRK_IGNORE },
528 { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_607, HID_QUIRK_IGNORE },
529 { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_608, HID_QUIRK_IGNORE },
530 { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_609, HID_QUIRK_IGNORE },
531 { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1000, HID_QUIRK_IGNORE }, 525 { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1000, HID_QUIRK_IGNORE },
532 { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1001, HID_QUIRK_IGNORE }, 526 { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1001, HID_QUIRK_IGNORE },
533 { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1002, HID_QUIRK_IGNORE }, 527 { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1002, HID_QUIRK_IGNORE },
@@ -601,6 +595,7 @@ static const struct hid_blacklist {
601 { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_2PORTKVM, HID_QUIRK_NOGET }, 595 { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_2PORTKVM, HID_QUIRK_NOGET },
602 { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVM, HID_QUIRK_NOGET }, 596 { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVM, HID_QUIRK_NOGET },
603 { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVMC, HID_QUIRK_NOGET }, 597 { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVMC, HID_QUIRK_NOGET },
598 { USB_VENDOR_ID_DMI, USB_DEVICE_ID_DMI_ENC, HID_QUIRK_NOGET },
604 { USB_VENDOR_ID_ELO, USB_DEVICE_ID_ELO_TS2700, HID_QUIRK_NOGET }, 599 { USB_VENDOR_ID_ELO, USB_DEVICE_ID_ELO_TS2700, HID_QUIRK_NOGET },
605 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_EXTREME_3D, HID_QUIRK_NOGET }, 600 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_EXTREME_3D, HID_QUIRK_NOGET },
606 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WHEEL, HID_QUIRK_NOGET }, 601 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WHEEL, HID_QUIRK_NOGET },
@@ -608,7 +603,7 @@ static const struct hid_blacklist {
608 { USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE, HID_QUIRK_NOGET }, 603 { USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE, HID_QUIRK_NOGET },
609 { USB_VENDOR_ID_SUN, USB_DEVICE_ID_RARITAN_KVM_DONGLE, HID_QUIRK_NOGET }, 604 { USB_VENDOR_ID_SUN, USB_DEVICE_ID_RARITAN_KVM_DONGLE, HID_QUIRK_NOGET },
610 { USB_VENDOR_ID_TURBOX, USB_DEVICE_ID_TURBOX_KEYBOARD, HID_QUIRK_NOGET }, 605 { USB_VENDOR_ID_TURBOX, USB_DEVICE_ID_TURBOX_KEYBOARD, HID_QUIRK_NOGET },
611 { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_DUAL_USB_JOYPAD, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT }, 606 { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_DUAL_USB_JOYPAD, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT | HID_QUIRK_SKIP_OUTPUT_REPORTS },
612 { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_QUAD_USB_JOYPAD, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT }, 607 { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_QUAD_USB_JOYPAD, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT },
613 608
614 { USB_VENDOR_ID_WISEGROUP_LTD, USB_DEVICE_ID_SMARTJOY_DUAL_PLUS, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT }, 609 { USB_VENDOR_ID_WISEGROUP_LTD, USB_DEVICE_ID_SMARTJOY_DUAL_PLUS, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT },
@@ -719,6 +714,7 @@ static const struct hid_rdesc_blacklist {
719 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_MX3000_RECEIVER, HID_QUIRK_RDESC_LOGITECH }, 714 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_MX3000_RECEIVER, HID_QUIRK_RDESC_LOGITECH },
720 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER, HID_QUIRK_RDESC_LOGITECH }, 715 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER, HID_QUIRK_RDESC_LOGITECH },
721 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER_2, HID_QUIRK_RDESC_LOGITECH }, 716 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER_2, HID_QUIRK_RDESC_LOGITECH },
717 { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_DESKTOP_RECV_1028, HID_QUIRK_RDESC_MICROSOFT_RECV_1028 },
722 718
723 { USB_VENDOR_ID_MONTEREY, USB_DEVICE_ID_GENIUS_KB29E, HID_QUIRK_RDESC_BUTTON_CONSUMER }, 719 { USB_VENDOR_ID_MONTEREY, USB_DEVICE_ID_GENIUS_KB29E, HID_QUIRK_RDESC_BUTTON_CONSUMER },
724 720
@@ -728,6 +724,8 @@ static const struct hid_rdesc_blacklist {
728 724
729 { USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_IR_REMOTE, HID_QUIRK_RDESC_SAMSUNG_REMOTE }, 725 { USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_IR_REMOTE, HID_QUIRK_RDESC_SAMSUNG_REMOTE },
730 726
727 { USB_VENDOR_ID_SUNPLUS, USB_DEVICE_ID_SUNPLUS_WDESKTOP, HID_QUIRK_RDESC_SUNPLUS_WDESKTOP },
728
731 { USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_1, HID_QUIRK_RDESC_SWAPPED_MIN_MAX }, 729 { USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_1, HID_QUIRK_RDESC_SWAPPED_MIN_MAX },
732 { USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_2, HID_QUIRK_RDESC_SWAPPED_MIN_MAX }, 730 { USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_2, HID_QUIRK_RDESC_SWAPPED_MIN_MAX },
733 731
@@ -793,8 +791,8 @@ static struct hid_blacklist *usbhid_exists_dquirk(const u16 idVendor,
793 * 791 *
794 * Returns: 0 OK, -error on failure. 792 * Returns: 0 OK, -error on failure.
795 */ 793 */
796int usbhid_modify_dquirk(const u16 idVendor, const u16 idProduct, 794static int usbhid_modify_dquirk(const u16 idVendor, const u16 idProduct,
797 const u32 quirks) 795 const u32 quirks)
798{ 796{
799 struct quirks_list_struct *q_new, *q; 797 struct quirks_list_struct *q_new, *q;
800 int list_edited = 0; 798 int list_edited = 0;
@@ -1002,6 +1000,17 @@ static void usbhid_fixup_logitech_descriptor(unsigned char *rdesc, int rsize)
1002 } 1000 }
1003} 1001}
1004 1002
1003static void usbhid_fixup_sunplus_wdesktop(unsigned char *rdesc, int rsize)
1004{
1005 if (rsize >= 107 && rdesc[104] == 0x26
1006 && rdesc[105] == 0x80
1007 && rdesc[106] == 0x03) {
1008 printk(KERN_INFO "Fixing up Sunplus Wireless Desktop report descriptor\n");
1009 rdesc[105] = rdesc[110] = 0x03;
1010 rdesc[106] = rdesc[111] = 0x21;
1011 }
1012}
1013
1005/* 1014/*
1006 * Samsung IrDA remote controller (reports as Cypress USB Mouse). 1015 * Samsung IrDA remote controller (reports as Cypress USB Mouse).
1007 * 1016 *
@@ -1089,6 +1098,28 @@ static void usbhid_fixup_button_consumer_descriptor(unsigned char *rdesc, int rs
1089 } 1098 }
1090} 1099}
1091 1100
1101/*
1102 * Microsoft Wireless Desktop Receiver (Model 1028) has several
1103 * 'Usage Min/Max' where it ought to have 'Physical Min/Max'
1104 */
1105static void usbhid_fixup_microsoft_descriptor(unsigned char *rdesc, int rsize)
1106{
1107 if (rsize == 571 && rdesc[284] == 0x19
1108 && rdesc[286] == 0x2a
1109 && rdesc[304] == 0x19
1110 && rdesc[306] == 0x29
1111 && rdesc[352] == 0x1a
1112 && rdesc[355] == 0x2a
1113 && rdesc[557] == 0x19
1114 && rdesc[559] == 0x29) {
1115 printk(KERN_INFO "Fixing up Microsoft Wireless Receiver Model 1028 report descriptor\n");
1116 rdesc[284] = rdesc[304] = rdesc[558] = 0x35;
1117 rdesc[352] = 0x36;
1118 rdesc[286] = rdesc[355] = 0x46;
1119 rdesc[306] = rdesc[559] = 0x45;
1120 }
1121}
1122
1092static void __usbhid_fixup_report_descriptor(__u32 quirks, char *rdesc, unsigned rsize) 1123static void __usbhid_fixup_report_descriptor(__u32 quirks, char *rdesc, unsigned rsize)
1093{ 1124{
1094 if ((quirks & HID_QUIRK_RDESC_CYMOTION)) 1125 if ((quirks & HID_QUIRK_RDESC_CYMOTION))
@@ -1112,6 +1143,11 @@ static void __usbhid_fixup_report_descriptor(__u32 quirks, char *rdesc, unsigned
1112 if (quirks & HID_QUIRK_RDESC_SAMSUNG_REMOTE) 1143 if (quirks & HID_QUIRK_RDESC_SAMSUNG_REMOTE)
1113 usbhid_fixup_samsung_irda_descriptor(rdesc, rsize); 1144 usbhid_fixup_samsung_irda_descriptor(rdesc, rsize);
1114 1145
1146 if (quirks & HID_QUIRK_RDESC_MICROSOFT_RECV_1028)
1147 usbhid_fixup_microsoft_descriptor(rdesc, rsize);
1148
1149 if (quirks & HID_QUIRK_RDESC_SUNPLUS_WDESKTOP)
1150 usbhid_fixup_sunplus_wdesktop(rdesc, rsize);
1115} 1151}
1116 1152
1117/** 1153/**
@@ -1150,5 +1186,4 @@ void usbhid_fixup_report_descriptor(const u16 idVendor, const u16 idProduct,
1150 else if (paramVendor == idVendor && paramProduct == idProduct) 1186 else if (paramVendor == idVendor && paramProduct == idProduct)
1151 __usbhid_fixup_report_descriptor(quirks, rdesc, rsize); 1187 __usbhid_fixup_report_descriptor(quirks, rdesc, rsize);
1152 } 1188 }
1153
1154} 1189}
diff --git a/drivers/hid/usbhid/hiddev.c b/drivers/hid/usbhid/hiddev.c
index 5fc4019956ba..95cc192bc7af 100644
--- a/drivers/hid/usbhid/hiddev.c
+++ b/drivers/hid/usbhid/hiddev.c
@@ -393,6 +393,153 @@ static unsigned int hiddev_poll(struct file *file, poll_table *wait)
393/* 393/*
394 * "ioctl" file op 394 * "ioctl" file op
395 */ 395 */
396static noinline int hiddev_ioctl_usage(struct hiddev *hiddev, unsigned int cmd, void __user *user_arg)
397{
398 struct hid_device *hid = hiddev->hid;
399 struct hiddev_report_info rinfo;
400 struct hiddev_usage_ref_multi *uref_multi = NULL;
401 struct hiddev_usage_ref *uref;
402 struct hid_report *report;
403 struct hid_field *field;
404 int i;
405
406 uref_multi = kmalloc(sizeof(struct hiddev_usage_ref_multi), GFP_KERNEL);
407 if (!uref_multi)
408 return -ENOMEM;
409 uref = &uref_multi->uref;
410 if (cmd == HIDIOCGUSAGES || cmd == HIDIOCSUSAGES) {
411 if (copy_from_user(uref_multi, user_arg,
412 sizeof(*uref_multi)))
413 goto fault;
414 } else {
415 if (copy_from_user(uref, user_arg, sizeof(*uref)))
416 goto fault;
417 }
418
419 switch (cmd) {
420 case HIDIOCGUCODE:
421 rinfo.report_type = uref->report_type;
422 rinfo.report_id = uref->report_id;
423 if ((report = hiddev_lookup_report(hid, &rinfo)) == NULL)
424 goto inval;
425
426 if (uref->field_index >= report->maxfield)
427 goto inval;
428
429 field = report->field[uref->field_index];
430 if (uref->usage_index >= field->maxusage)
431 goto inval;
432
433 uref->usage_code = field->usage[uref->usage_index].hid;
434
435 if (copy_to_user(user_arg, uref, sizeof(*uref)))
436 goto fault;
437
438 kfree(uref_multi);
439 return 0;
440
441 default:
442 if (cmd != HIDIOCGUSAGE &&
443 cmd != HIDIOCGUSAGES &&
444 uref->report_type == HID_REPORT_TYPE_INPUT)
445 goto inval;
446
447 if (uref->report_id == HID_REPORT_ID_UNKNOWN) {
448 field = hiddev_lookup_usage(hid, uref);
449 if (field == NULL)
450 goto inval;
451 } else {
452 rinfo.report_type = uref->report_type;
453 rinfo.report_id = uref->report_id;
454 if ((report = hiddev_lookup_report(hid, &rinfo)) == NULL)
455 goto inval;
456
457 if (uref->field_index >= report->maxfield)
458 goto inval;
459
460 field = report->field[uref->field_index];
461
462 if (cmd == HIDIOCGCOLLECTIONINDEX) {
463 if (uref->usage_index >= field->maxusage)
464 goto inval;
465 } else if (uref->usage_index >= field->report_count)
466 goto inval;
467
468 else if ((cmd == HIDIOCGUSAGES || cmd == HIDIOCSUSAGES) &&
469 (uref_multi->num_values > HID_MAX_MULTI_USAGES ||
470 uref->usage_index + uref_multi->num_values > field->report_count))
471 goto inval;
472 }
473
474 switch (cmd) {
475 case HIDIOCGUSAGE:
476 uref->value = field->value[uref->usage_index];
477 if (copy_to_user(user_arg, uref, sizeof(*uref)))
478 goto fault;
479 goto goodreturn;
480
481 case HIDIOCSUSAGE:
482 field->value[uref->usage_index] = uref->value;
483 goto goodreturn;
484
485 case HIDIOCGCOLLECTIONINDEX:
486 kfree(uref_multi);
487 return field->usage[uref->usage_index].collection_index;
488 case HIDIOCGUSAGES:
489 for (i = 0; i < uref_multi->num_values; i++)
490 uref_multi->values[i] =
491 field->value[uref->usage_index + i];
492 if (copy_to_user(user_arg, uref_multi,
493 sizeof(*uref_multi)))
494 goto fault;
495 goto goodreturn;
496 case HIDIOCSUSAGES:
497 for (i = 0; i < uref_multi->num_values; i++)
498 field->value[uref->usage_index + i] =
499 uref_multi->values[i];
500 goto goodreturn;
501 }
502
503goodreturn:
504 kfree(uref_multi);
505 return 0;
506fault:
507 kfree(uref_multi);
508 return -EFAULT;
509inval:
510 kfree(uref_multi);
511 return -EINVAL;
512 }
513}
514
515static noinline int hiddev_ioctl_string(struct hiddev *hiddev, unsigned int cmd, void __user *user_arg)
516{
517 struct hid_device *hid = hiddev->hid;
518 struct usb_device *dev = hid_to_usb_dev(hid);
519 int idx, len;
520 char *buf;
521
522 if (get_user(idx, (int __user *)user_arg))
523 return -EFAULT;
524
525 if ((buf = kmalloc(HID_STRING_SIZE, GFP_KERNEL)) == NULL)
526 return -ENOMEM;
527
528 if ((len = usb_string(dev, idx, buf, HID_STRING_SIZE-1)) < 0) {
529 kfree(buf);
530 return -EINVAL;
531 }
532
533 if (copy_to_user(user_arg+sizeof(int), buf, len+1)) {
534 kfree(buf);
535 return -EFAULT;
536 }
537
538 kfree(buf);
539
540 return len;
541}
542
396static int hiddev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) 543static int hiddev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
397{ 544{
398 struct hiddev_list *list = file->private_data; 545 struct hiddev_list *list = file->private_data;
@@ -402,8 +549,6 @@ static int hiddev_ioctl(struct inode *inode, struct file *file, unsigned int cmd
402 struct hiddev_collection_info cinfo; 549 struct hiddev_collection_info cinfo;
403 struct hiddev_report_info rinfo; 550 struct hiddev_report_info rinfo;
404 struct hiddev_field_info finfo; 551 struct hiddev_field_info finfo;
405 struct hiddev_usage_ref_multi *uref_multi = NULL;
406 struct hiddev_usage_ref *uref;
407 struct hiddev_devinfo dinfo; 552 struct hiddev_devinfo dinfo;
408 struct hid_report *report; 553 struct hid_report *report;
409 struct hid_field *field; 554 struct hid_field *field;
@@ -470,30 +615,7 @@ static int hiddev_ioctl(struct inode *inode, struct file *file, unsigned int cmd
470 } 615 }
471 616
472 case HIDIOCGSTRING: 617 case HIDIOCGSTRING:
473 { 618 return hiddev_ioctl_string(hiddev, cmd, user_arg);
474 int idx, len;
475 char *buf;
476
477 if (get_user(idx, (int __user *)arg))
478 return -EFAULT;
479
480 if ((buf = kmalloc(HID_STRING_SIZE, GFP_KERNEL)) == NULL)
481 return -ENOMEM;
482
483 if ((len = usb_string(dev, idx, buf, HID_STRING_SIZE-1)) < 0) {
484 kfree(buf);
485 return -EINVAL;
486 }
487
488 if (copy_to_user(user_arg+sizeof(int), buf, len+1)) {
489 kfree(buf);
490 return -EFAULT;
491 }
492
493 kfree(buf);
494
495 return len;
496 }
497 619
498 case HIDIOCINITREPORT: 620 case HIDIOCINITREPORT:
499 usbhid_init_reports(hid); 621 usbhid_init_reports(hid);
@@ -578,121 +700,13 @@ static int hiddev_ioctl(struct inode *inode, struct file *file, unsigned int cmd
578 return 0; 700 return 0;
579 701
580 case HIDIOCGUCODE: 702 case HIDIOCGUCODE:
581 uref_multi = kmalloc(sizeof(struct hiddev_usage_ref_multi), GFP_KERNEL); 703 /* fall through */
582 if (!uref_multi)
583 return -ENOMEM;
584 uref = &uref_multi->uref;
585 if (copy_from_user(uref, user_arg, sizeof(*uref)))
586 goto fault;
587
588 rinfo.report_type = uref->report_type;
589 rinfo.report_id = uref->report_id;
590 if ((report = hiddev_lookup_report(hid, &rinfo)) == NULL)
591 goto inval;
592
593 if (uref->field_index >= report->maxfield)
594 goto inval;
595
596 field = report->field[uref->field_index];
597 if (uref->usage_index >= field->maxusage)
598 goto inval;
599
600 uref->usage_code = field->usage[uref->usage_index].hid;
601
602 if (copy_to_user(user_arg, uref, sizeof(*uref)))
603 goto fault;
604
605 kfree(uref_multi);
606 return 0;
607
608 case HIDIOCGUSAGE: 704 case HIDIOCGUSAGE:
609 case HIDIOCSUSAGE: 705 case HIDIOCSUSAGE:
610 case HIDIOCGUSAGES: 706 case HIDIOCGUSAGES:
611 case HIDIOCSUSAGES: 707 case HIDIOCSUSAGES:
612 case HIDIOCGCOLLECTIONINDEX: 708 case HIDIOCGCOLLECTIONINDEX:
613 uref_multi = kmalloc(sizeof(struct hiddev_usage_ref_multi), GFP_KERNEL); 709 return hiddev_ioctl_usage(hiddev, cmd, user_arg);
614 if (!uref_multi)
615 return -ENOMEM;
616 uref = &uref_multi->uref;
617 if (cmd == HIDIOCGUSAGES || cmd == HIDIOCSUSAGES) {
618 if (copy_from_user(uref_multi, user_arg,
619 sizeof(*uref_multi)))
620 goto fault;
621 } else {
622 if (copy_from_user(uref, user_arg, sizeof(*uref)))
623 goto fault;
624 }
625
626 if (cmd != HIDIOCGUSAGE &&
627 cmd != HIDIOCGUSAGES &&
628 uref->report_type == HID_REPORT_TYPE_INPUT)
629 goto inval;
630
631 if (uref->report_id == HID_REPORT_ID_UNKNOWN) {
632 field = hiddev_lookup_usage(hid, uref);
633 if (field == NULL)
634 goto inval;
635 } else {
636 rinfo.report_type = uref->report_type;
637 rinfo.report_id = uref->report_id;
638 if ((report = hiddev_lookup_report(hid, &rinfo)) == NULL)
639 goto inval;
640
641 if (uref->field_index >= report->maxfield)
642 goto inval;
643
644 field = report->field[uref->field_index];
645
646 if (cmd == HIDIOCGCOLLECTIONINDEX) {
647 if (uref->usage_index >= field->maxusage)
648 goto inval;
649 } else if (uref->usage_index >= field->report_count)
650 goto inval;
651
652 else if ((cmd == HIDIOCGUSAGES || cmd == HIDIOCSUSAGES) &&
653 (uref_multi->num_values > HID_MAX_MULTI_USAGES ||
654 uref->usage_index + uref_multi->num_values > field->report_count))
655 goto inval;
656 }
657
658 switch (cmd) {
659 case HIDIOCGUSAGE:
660 uref->value = field->value[uref->usage_index];
661 if (copy_to_user(user_arg, uref, sizeof(*uref)))
662 goto fault;
663 goto goodreturn;
664
665 case HIDIOCSUSAGE:
666 field->value[uref->usage_index] = uref->value;
667 goto goodreturn;
668
669 case HIDIOCGCOLLECTIONINDEX:
670 kfree(uref_multi);
671 return field->usage[uref->usage_index].collection_index;
672 case HIDIOCGUSAGES:
673 for (i = 0; i < uref_multi->num_values; i++)
674 uref_multi->values[i] =
675 field->value[uref->usage_index + i];
676 if (copy_to_user(user_arg, uref_multi,
677 sizeof(*uref_multi)))
678 goto fault;
679 goto goodreturn;
680 case HIDIOCSUSAGES:
681 for (i = 0; i < uref_multi->num_values; i++)
682 field->value[uref->usage_index + i] =
683 uref_multi->values[i];
684 goto goodreturn;
685 }
686
687goodreturn:
688 kfree(uref_multi);
689 return 0;
690fault:
691 kfree(uref_multi);
692 return -EFAULT;
693inval:
694 kfree(uref_multi);
695 return -EINVAL;
696 710
697 case HIDIOCGCOLLECTIONINFO: 711 case HIDIOCGCOLLECTIONINFO:
698 if (copy_from_user(&cinfo, user_arg, sizeof(cinfo))) 712 if (copy_from_user(&cinfo, user_arg, sizeof(cinfo)))
diff --git a/drivers/hid/usbhid/usbhid.h b/drivers/hid/usbhid/usbhid.h
index 0023f96d4294..62d2d7c925bd 100644
--- a/drivers/hid/usbhid/usbhid.h
+++ b/drivers/hid/usbhid/usbhid.h
@@ -28,6 +28,7 @@
28#include <linux/slab.h> 28#include <linux/slab.h>
29#include <linux/list.h> 29#include <linux/list.h>
30#include <linux/timer.h> 30#include <linux/timer.h>
31#include <linux/wait.h>
31#include <linux/workqueue.h> 32#include <linux/workqueue.h>
32#include <linux/input.h> 33#include <linux/input.h>
33 34
@@ -77,7 +78,7 @@ struct usbhid_device {
77 unsigned long stop_retry; /* Time to give up, in jiffies */ 78 unsigned long stop_retry; /* Time to give up, in jiffies */
78 unsigned int retry_delay; /* Delay length in ms */ 79 unsigned int retry_delay; /* Delay length in ms */
79 struct work_struct reset_work; /* Task context for resets */ 80 struct work_struct reset_work; /* Task context for resets */
80 81 wait_queue_head_t wait; /* For sleeping */
81}; 82};
82 83
83#define hid_to_usb_dev(hid_dev) \ 84#define hid_to_usb_dev(hid_dev) \
diff --git a/drivers/i2c/algos/Kconfig b/drivers/i2c/algos/Kconfig
index 014dfa575be7..7137a17402fe 100644
--- a/drivers/i2c/algos/Kconfig
+++ b/drivers/i2c/algos/Kconfig
@@ -1,45 +1,16 @@
1# 1#
2# Character device configuration 2# I2C algorithm drivers configuration
3# 3#
4 4
5menu "I2C Algorithms"
6
7config I2C_ALGOBIT 5config I2C_ALGOBIT
8 tristate "I2C bit-banging interfaces" 6 tristate
9 help
10 This allows you to use a range of I2C adapters called bit-banging
11 adapters. Say Y if you own an I2C adapter belonging to this class
12 and then say Y to the specific driver for you adapter below.
13
14 This support is also available as a module. If so, the module
15 will be called i2c-algo-bit.
16 7
17config I2C_ALGOPCF 8config I2C_ALGOPCF
18 tristate "I2C PCF 8584 interfaces" 9 tristate
19 help
20 This allows you to use a range of I2C adapters called PCF adapters.
21 Say Y if you own an I2C adapter belonging to this class and then say
22 Y to the specific driver for you adapter below.
23
24 This support is also available as a module. If so, the module
25 will be called i2c-algo-pcf.
26 10
27config I2C_ALGOPCA 11config I2C_ALGOPCA
28 tristate "I2C PCA 9564 interfaces" 12 tristate
29 help
30 This allows you to use a range of I2C adapters called PCA adapters.
31 Say Y if you own an I2C adapter belonging to this class and then say
32 Y to the specific driver for you adapter below.
33
34 This support is also available as a module. If so, the module
35 will be called i2c-algo-pca.
36 13
37config I2C_ALGO_SGI 14config I2C_ALGO_SGI
38 tristate "I2C SGI interfaces" 15 tristate
39 depends on SGI_IP22 || SGI_IP32 || X86_VISWS 16 depends on SGI_IP22 || SGI_IP32 || X86_VISWS
40 help
41 Supports the SGI interfaces like the ones found on SGI Indy VINO
42 or SGI O2 MACE.
43
44endmenu
45
diff --git a/drivers/i2c/algos/i2c-algo-pca.c b/drivers/i2c/algos/i2c-algo-pca.c
index 2a16211f12e5..e954a20b97a6 100644
--- a/drivers/i2c/algos/i2c-algo-pca.c
+++ b/drivers/i2c/algos/i2c-algo-pca.c
@@ -1,6 +1,7 @@
1/* 1/*
2 * i2c-algo-pca.c i2c driver algorithms for PCA9564 adapters 2 * i2c-algo-pca.c i2c driver algorithms for PCA9564 adapters
3 * Copyright (C) 2004 Arcom Control Systems 3 * Copyright (C) 2004 Arcom Control Systems
4 * Copyright (C) 2008 Pengutronix
4 * 5 *
5 * This program is free software; you can redistribute it and/or modify 6 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by 7 * it under the terms of the GNU General Public License as published by
@@ -21,14 +22,10 @@
21#include <linux/module.h> 22#include <linux/module.h>
22#include <linux/moduleparam.h> 23#include <linux/moduleparam.h>
23#include <linux/delay.h> 24#include <linux/delay.h>
24#include <linux/slab.h>
25#include <linux/init.h> 25#include <linux/init.h>
26#include <linux/errno.h> 26#include <linux/errno.h>
27#include <linux/i2c.h> 27#include <linux/i2c.h>
28#include <linux/i2c-algo-pca.h> 28#include <linux/i2c-algo-pca.h>
29#include "i2c-algo-pca.h"
30
31#define DRIVER "i2c-algo-pca"
32 29
33#define DEB1(fmt, args...) do { if (i2c_debug>=1) printk(fmt, ## args); } while(0) 30#define DEB1(fmt, args...) do { if (i2c_debug>=1) printk(fmt, ## args); } while(0)
34#define DEB2(fmt, args...) do { if (i2c_debug>=2) printk(fmt, ## args); } while(0) 31#define DEB2(fmt, args...) do { if (i2c_debug>=2) printk(fmt, ## args); } while(0)
@@ -36,15 +33,15 @@
36 33
37static int i2c_debug; 34static int i2c_debug;
38 35
39#define pca_outw(adap, reg, val) adap->write_byte(adap, reg, val) 36#define pca_outw(adap, reg, val) adap->write_byte(adap->data, reg, val)
40#define pca_inw(adap, reg) adap->read_byte(adap, reg) 37#define pca_inw(adap, reg) adap->read_byte(adap->data, reg)
41 38
42#define pca_status(adap) pca_inw(adap, I2C_PCA_STA) 39#define pca_status(adap) pca_inw(adap, I2C_PCA_STA)
43#define pca_clock(adap) adap->get_clock(adap) 40#define pca_clock(adap) adap->i2c_clock
44#define pca_own(adap) adap->get_own(adap)
45#define pca_set_con(adap, val) pca_outw(adap, I2C_PCA_CON, val) 41#define pca_set_con(adap, val) pca_outw(adap, I2C_PCA_CON, val)
46#define pca_get_con(adap) pca_inw(adap, I2C_PCA_CON) 42#define pca_get_con(adap) pca_inw(adap, I2C_PCA_CON)
47#define pca_wait(adap) adap->wait_for_interrupt(adap) 43#define pca_wait(adap) adap->wait_for_completion(adap->data)
44#define pca_reset(adap) adap->reset_chip(adap->data)
48 45
49/* 46/*
50 * Generate a start condition on the i2c bus. 47 * Generate a start condition on the i2c bus.
@@ -99,7 +96,7 @@ static void pca_stop(struct i2c_algo_pca_data *adap)
99 * 96 *
100 * returns after the address has been sent 97 * returns after the address has been sent
101 */ 98 */
102static void pca_address(struct i2c_algo_pca_data *adap, 99static void pca_address(struct i2c_algo_pca_data *adap,
103 struct i2c_msg *msg) 100 struct i2c_msg *msg)
104{ 101{
105 int sta = pca_get_con(adap); 102 int sta = pca_get_con(adap);
@@ -108,9 +105,9 @@ static void pca_address(struct i2c_algo_pca_data *adap,
108 addr = ( (0x7f & msg->addr) << 1 ); 105 addr = ( (0x7f & msg->addr) << 1 );
109 if (msg->flags & I2C_M_RD ) 106 if (msg->flags & I2C_M_RD )
110 addr |= 1; 107 addr |= 1;
111 DEB2("=== SLAVE ADDRESS %#04x+%c=%#04x\n", 108 DEB2("=== SLAVE ADDRESS %#04x+%c=%#04x\n",
112 msg->addr, msg->flags & I2C_M_RD ? 'R' : 'W', addr); 109 msg->addr, msg->flags & I2C_M_RD ? 'R' : 'W', addr);
113 110
114 pca_outw(adap, I2C_PCA_DAT, addr); 111 pca_outw(adap, I2C_PCA_DAT, addr);
115 112
116 sta &= ~(I2C_PCA_CON_STO|I2C_PCA_CON_STA|I2C_PCA_CON_SI); 113 sta &= ~(I2C_PCA_CON_STO|I2C_PCA_CON_STA|I2C_PCA_CON_SI);
@@ -124,7 +121,7 @@ static void pca_address(struct i2c_algo_pca_data *adap,
124 * 121 *
125 * Returns after the byte has been transmitted 122 * Returns after the byte has been transmitted
126 */ 123 */
127static void pca_tx_byte(struct i2c_algo_pca_data *adap, 124static void pca_tx_byte(struct i2c_algo_pca_data *adap,
128 __u8 b) 125 __u8 b)
129{ 126{
130 int sta = pca_get_con(adap); 127 int sta = pca_get_con(adap);
@@ -142,19 +139,19 @@ static void pca_tx_byte(struct i2c_algo_pca_data *adap,
142 * 139 *
143 * returns immediately. 140 * returns immediately.
144 */ 141 */
145static void pca_rx_byte(struct i2c_algo_pca_data *adap, 142static void pca_rx_byte(struct i2c_algo_pca_data *adap,
146 __u8 *b, int ack) 143 __u8 *b, int ack)
147{ 144{
148 *b = pca_inw(adap, I2C_PCA_DAT); 145 *b = pca_inw(adap, I2C_PCA_DAT);
149 DEB2("=== READ %#04x %s\n", *b, ack ? "ACK" : "NACK"); 146 DEB2("=== READ %#04x %s\n", *b, ack ? "ACK" : "NACK");
150} 147}
151 148
152/* 149/*
153 * Setup ACK or NACK for next received byte and wait for it to arrive. 150 * Setup ACK or NACK for next received byte and wait for it to arrive.
154 * 151 *
155 * Returns after next byte has arrived. 152 * Returns after next byte has arrived.
156 */ 153 */
157static void pca_rx_ack(struct i2c_algo_pca_data *adap, 154static void pca_rx_ack(struct i2c_algo_pca_data *adap,
158 int ack) 155 int ack)
159{ 156{
160 int sta = pca_get_con(adap); 157 int sta = pca_get_con(adap);
@@ -168,15 +165,6 @@ static void pca_rx_ack(struct i2c_algo_pca_data *adap,
168 pca_wait(adap); 165 pca_wait(adap);
169} 166}
170 167
171/*
172 * Reset the i2c bus / SIO
173 */
174static void pca_reset(struct i2c_algo_pca_data *adap)
175{
176 /* apparently only an external reset will do it. not a lot can be done */
177 printk(KERN_ERR DRIVER ": Haven't figured out how to do a reset yet\n");
178}
179
180static int pca_xfer(struct i2c_adapter *i2c_adap, 168static int pca_xfer(struct i2c_adapter *i2c_adap,
181 struct i2c_msg *msgs, 169 struct i2c_msg *msgs,
182 int num) 170 int num)
@@ -187,7 +175,7 @@ static int pca_xfer(struct i2c_adapter *i2c_adap,
187 int numbytes = 0; 175 int numbytes = 0;
188 int state; 176 int state;
189 int ret; 177 int ret;
190 int timeout = 100; 178 int timeout = i2c_adap->timeout;
191 179
192 while ((state = pca_status(adap)) != 0xf8 && timeout--) { 180 while ((state = pca_status(adap)) != 0xf8 && timeout--) {
193 msleep(10); 181 msleep(10);
@@ -203,14 +191,14 @@ static int pca_xfer(struct i2c_adapter *i2c_adap,
203 for (curmsg = 0; curmsg < num; curmsg++) { 191 for (curmsg = 0; curmsg < num; curmsg++) {
204 int addr, i; 192 int addr, i;
205 msg = &msgs[curmsg]; 193 msg = &msgs[curmsg];
206 194
207 addr = (0x7f & msg->addr) ; 195 addr = (0x7f & msg->addr) ;
208 196
209 if (msg->flags & I2C_M_RD ) 197 if (msg->flags & I2C_M_RD )
210 printk(KERN_INFO " [%02d] RD %d bytes from %#02x [%#02x, ...]\n", 198 printk(KERN_INFO " [%02d] RD %d bytes from %#02x [%#02x, ...]\n",
211 curmsg, msg->len, addr, (addr<<1) | 1); 199 curmsg, msg->len, addr, (addr<<1) | 1);
212 else { 200 else {
213 printk(KERN_INFO " [%02d] WR %d bytes to %#02x [%#02x%s", 201 printk(KERN_INFO " [%02d] WR %d bytes to %#02x [%#02x%s",
214 curmsg, msg->len, addr, addr<<1, 202 curmsg, msg->len, addr, addr<<1,
215 msg->len == 0 ? "" : ", "); 203 msg->len == 0 ? "" : ", ");
216 for(i=0; i < msg->len; i++) 204 for(i=0; i < msg->len; i++)
@@ -237,7 +225,7 @@ static int pca_xfer(struct i2c_adapter *i2c_adap,
237 case 0x10: /* A repeated start condition has been transmitted */ 225 case 0x10: /* A repeated start condition has been transmitted */
238 pca_address(adap, msg); 226 pca_address(adap, msg);
239 break; 227 break;
240 228
241 case 0x18: /* SLA+W has been transmitted; ACK has been received */ 229 case 0x18: /* SLA+W has been transmitted; ACK has been received */
242 case 0x28: /* Data byte in I2CDAT has been transmitted; ACK has been received */ 230 case 0x28: /* Data byte in I2CDAT has been transmitted; ACK has been received */
243 if (numbytes < msg->len) { 231 if (numbytes < msg->len) {
@@ -287,7 +275,7 @@ static int pca_xfer(struct i2c_adapter *i2c_adap,
287 case 0x38: /* Arbitration lost during SLA+W, SLA+R or data bytes */ 275 case 0x38: /* Arbitration lost during SLA+W, SLA+R or data bytes */
288 DEB2("Arbitration lost\n"); 276 DEB2("Arbitration lost\n");
289 goto out; 277 goto out;
290 278
291 case 0x58: /* Data byte has been received; NOT ACK has been returned */ 279 case 0x58: /* Data byte has been received; NOT ACK has been returned */
292 if ( numbytes == msg->len - 1 ) { 280 if ( numbytes == msg->len - 1 ) {
293 pca_rx_byte(adap, &msg->buf[numbytes], 0); 281 pca_rx_byte(adap, &msg->buf[numbytes], 0);
@@ -317,16 +305,16 @@ static int pca_xfer(struct i2c_adapter *i2c_adap,
317 pca_reset(adap); 305 pca_reset(adap);
318 goto out; 306 goto out;
319 default: 307 default:
320 printk(KERN_ERR DRIVER ": unhandled SIO state 0x%02x\n", state); 308 dev_err(&i2c_adap->dev, "unhandled SIO state 0x%02x\n", state);
321 break; 309 break;
322 } 310 }
323 311
324 } 312 }
325 313
326 ret = curmsg; 314 ret = curmsg;
327 out: 315 out:
328 DEB1(KERN_CRIT "}}} transfered %d/%d messages. " 316 DEB1(KERN_CRIT "}}} transfered %d/%d messages. "
329 "status is %#04x. control is %#04x\n", 317 "status is %#04x. control is %#04x\n",
330 curmsg, num, pca_status(adap), 318 curmsg, num, pca_status(adap),
331 pca_get_con(adap)); 319 pca_get_con(adap));
332 return ret; 320 return ret;
@@ -337,53 +325,65 @@ static u32 pca_func(struct i2c_adapter *adap)
337 return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; 325 return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
338} 326}
339 327
340static int pca_init(struct i2c_algo_pca_data *adap) 328static const struct i2c_algorithm pca_algo = {
329 .master_xfer = pca_xfer,
330 .functionality = pca_func,
331};
332
333static int pca_init(struct i2c_adapter *adap)
341{ 334{
342 static int freqs[] = {330,288,217,146,88,59,44,36}; 335 static int freqs[] = {330,288,217,146,88,59,44,36};
343 int own, clock; 336 int clock;
337 struct i2c_algo_pca_data *pca_data = adap->algo_data;
338
339 if (pca_data->i2c_clock > 7) {
340 printk(KERN_WARNING "%s: Invalid I2C clock speed selected. Trying default.\n",
341 adap->name);
342 pca_data->i2c_clock = I2C_PCA_CON_59kHz;
343 }
344
345 adap->algo = &pca_algo;
344 346
345 own = pca_own(adap); 347 pca_reset(pca_data);
346 clock = pca_clock(adap);
347 DEB1(KERN_INFO DRIVER ": own address is %#04x\n", own);
348 DEB1(KERN_INFO DRIVER ": clock freqeuncy is %dkHz\n", freqs[clock]);
349 348
350 pca_outw(adap, I2C_PCA_ADR, own << 1); 349 clock = pca_clock(pca_data);
350 DEB1(KERN_INFO "%s: Clock frequency is %dkHz\n", adap->name, freqs[clock]);
351 351
352 pca_set_con(adap, I2C_PCA_CON_ENSIO | clock); 352 pca_set_con(pca_data, I2C_PCA_CON_ENSIO | clock);
353 udelay(500); /* 500 µs for oscilator to stabilise */ 353 udelay(500); /* 500 us for oscilator to stabilise */
354 354
355 return 0; 355 return 0;
356} 356}
357 357
358static const struct i2c_algorithm pca_algo = { 358/*
359 .master_xfer = pca_xfer, 359 * registering functions to load algorithms at runtime
360 .functionality = pca_func,
361};
362
363/*
364 * registering functions to load algorithms at runtime
365 */ 360 */
366int i2c_pca_add_bus(struct i2c_adapter *adap) 361int i2c_pca_add_bus(struct i2c_adapter *adap)
367{ 362{
368 struct i2c_algo_pca_data *pca_adap = adap->algo_data;
369 int rval; 363 int rval;
370 364
371 /* register new adapter to i2c module... */ 365 rval = pca_init(adap);
372 adap->algo = &pca_algo; 366 if (rval)
367 return rval;
373 368
374 adap->timeout = 100; /* default values, should */ 369 return i2c_add_adapter(adap);
375 adap->retries = 3; /* be replaced by defines */ 370}
371EXPORT_SYMBOL(i2c_pca_add_bus);
376 372
377 if ((rval = pca_init(pca_adap))) 373int i2c_pca_add_numbered_bus(struct i2c_adapter *adap)
378 return rval; 374{
375 int rval;
379 376
380 rval = i2c_add_adapter(adap); 377 rval = pca_init(adap);
378 if (rval)
379 return rval;
381 380
382 return rval; 381 return i2c_add_numbered_adapter(adap);
383} 382}
384EXPORT_SYMBOL(i2c_pca_add_bus); 383EXPORT_SYMBOL(i2c_pca_add_numbered_bus);
385 384
386MODULE_AUTHOR("Ian Campbell <icampbell@arcom.com>"); 385MODULE_AUTHOR("Ian Campbell <icampbell@arcom.com>, "
386 "Wolfram Sang <w.sang@pengutronix.de>");
387MODULE_DESCRIPTION("I2C-Bus PCA9564 algorithm"); 387MODULE_DESCRIPTION("I2C-Bus PCA9564 algorithm");
388MODULE_LICENSE("GPL"); 388MODULE_LICENSE("GPL");
389 389
diff --git a/drivers/i2c/algos/i2c-algo-pca.h b/drivers/i2c/algos/i2c-algo-pca.h
deleted file mode 100644
index 2fee07e05211..000000000000
--- a/drivers/i2c/algos/i2c-algo-pca.h
+++ /dev/null
@@ -1,26 +0,0 @@
1#ifndef I2C_PCA9564_H
2#define I2C_PCA9564_H 1
3
4#define I2C_PCA_STA 0x00 /* STATUS Read Only */
5#define I2C_PCA_TO 0x00 /* TIMEOUT Write Only */
6#define I2C_PCA_DAT 0x01 /* DATA Read/Write */
7#define I2C_PCA_ADR 0x02 /* OWN ADR Read/Write */
8#define I2C_PCA_CON 0x03 /* CONTROL Read/Write */
9
10#define I2C_PCA_CON_AA 0x80 /* Assert Acknowledge */
11#define I2C_PCA_CON_ENSIO 0x40 /* Enable */
12#define I2C_PCA_CON_STA 0x20 /* Start */
13#define I2C_PCA_CON_STO 0x10 /* Stop */
14#define I2C_PCA_CON_SI 0x08 /* Serial Interrupt */
15#define I2C_PCA_CON_CR 0x07 /* Clock Rate (MASK) */
16
17#define I2C_PCA_CON_330kHz 0x00
18#define I2C_PCA_CON_288kHz 0x01
19#define I2C_PCA_CON_217kHz 0x02
20#define I2C_PCA_CON_146kHz 0x03
21#define I2C_PCA_CON_88kHz 0x04
22#define I2C_PCA_CON_59kHz 0x05
23#define I2C_PCA_CON_44kHz 0x06
24#define I2C_PCA_CON_36kHz 0x07
25
26#endif /* I2C_PCA9564_H */
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index b04c99580d0d..48438cc5d0ca 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -100,9 +100,12 @@ config I2C_AU1550
100 100
101config I2C_BLACKFIN_TWI 101config I2C_BLACKFIN_TWI
102 tristate "Blackfin TWI I2C support" 102 tristate "Blackfin TWI I2C support"
103 depends on BF534 || BF536 || BF537 103 depends on BLACKFIN
104 help 104 help
105 This is the TWI I2C device driver for Blackfin 534/536/537/54x. 105 This is the TWI I2C device driver for Blackfin BF522, BF525,
106 BF527, BF534, BF536, BF537 and BF54x. For other Blackfin processors,
107 please don't use this driver.
108
106 This driver can also be built as a module. If so, the module 109 This driver can also be built as a module. If so, the module
107 will be called i2c-bfin-twi. 110 will be called i2c-bfin-twi.
108 111
@@ -135,7 +138,7 @@ config I2C_ELEKTOR
135 This supports the PCF8584 ISA bus I2C adapter. Say Y if you own 138 This supports the PCF8584 ISA bus I2C adapter. Say Y if you own
136 such an adapter. 139 such an adapter.
137 140
138 This support is also available as a module. If so, the module 141 This support is also available as a module. If so, the module
139 will be called i2c-elektor. 142 will be called i2c-elektor.
140 143
141config I2C_GPIO 144config I2C_GPIO
@@ -190,7 +193,7 @@ config I2C_I810
190 select I2C_ALGOBIT 193 select I2C_ALGOBIT
191 help 194 help
192 If you say yes to this option, support will be included for the Intel 195 If you say yes to this option, support will be included for the Intel
193 810/815 family of mainboard I2C interfaces. Specifically, the 196 810/815 family of mainboard I2C interfaces. Specifically, the
194 following versions of the chipset are supported: 197 following versions of the chipset are supported:
195 i810AA 198 i810AA
196 i810AB 199 i810AB
@@ -246,10 +249,10 @@ config I2C_PIIX4
246 249
247config I2C_IBM_IIC 250config I2C_IBM_IIC
248 tristate "IBM PPC 4xx on-chip I2C interface" 251 tristate "IBM PPC 4xx on-chip I2C interface"
249 depends on IBM_OCP 252 depends on 4xx
250 help 253 help
251 Say Y here if you want to use IIC peripheral found on 254 Say Y here if you want to use IIC peripheral found on
252 embedded IBM PPC 4xx based systems. 255 embedded IBM PPC 4xx based systems.
253 256
254 This driver can also be built as a module. If so, the module 257 This driver can also be built as a module. If so, the module
255 will be called i2c-ibm_iic. 258 will be called i2c-ibm_iic.
@@ -269,7 +272,7 @@ config I2C_IXP2000
269 depends on ARCH_IXP2000 272 depends on ARCH_IXP2000
270 select I2C_ALGOBIT 273 select I2C_ALGOBIT
271 help 274 help
272 Say Y here if you have an Intel IXP2000 (2400, 2800, 2850) based 275 Say Y here if you have an Intel IXP2000 (2400, 2800, 2850) based
273 system and are using GPIO lines for an I2C bus. 276 system and are using GPIO lines for an I2C bus.
274 277
275 This support is also available as a module. If so, the module 278 This support is also available as a module. If so, the module
@@ -354,7 +357,7 @@ config I2C_PARPORT
354 on the parport driver. This is meant for embedded systems. Don't say 357 on the parport driver. This is meant for embedded systems. Don't say
355 Y here if you intend to say Y or M there. 358 Y here if you intend to say Y or M there.
356 359
357 This support is also available as a module. If so, the module 360 This support is also available as a module. If so, the module
358 will be called i2c-parport. 361 will be called i2c-parport.
359 362
360config I2C_PARPORT_LIGHT 363config I2C_PARPORT_LIGHT
@@ -372,12 +375,12 @@ config I2C_PARPORT_LIGHT
372 the clean but heavy parport handling is not an option. The 375 the clean but heavy parport handling is not an option. The
373 drawback is a reduced portability and the impossibility to 376 drawback is a reduced portability and the impossibility to
374 daisy-chain other parallel port devices. 377 daisy-chain other parallel port devices.
375 378
376 Don't say Y here if you said Y or M to i2c-parport. Saying M to 379 Don't say Y here if you said Y or M to i2c-parport. Saying M to
377 both is possible but both modules should not be loaded at the same 380 both is possible but both modules should not be loaded at the same
378 time. 381 time.
379 382
380 This support is also available as a module. If so, the module 383 This support is also available as a module. If so, the module
381 will be called i2c-parport-light. 384 will be called i2c-parport-light.
382 385
383config I2C_PASEMI 386config I2C_PASEMI
@@ -401,7 +404,7 @@ config I2C_PROSAVAGE
401 404
402 This driver is deprecated in favor of the savagefb driver. 405 This driver is deprecated in favor of the savagefb driver.
403 406
404 This support is also available as a module. If so, the module 407 This support is also available as a module. If so, the module
405 will be called i2c-prosavage. 408 will be called i2c-prosavage.
406 409
407config I2C_S3C2410 410config I2C_S3C2410
@@ -417,7 +420,7 @@ config I2C_SAVAGE4
417 depends on PCI 420 depends on PCI
418 select I2C_ALGOBIT 421 select I2C_ALGOBIT
419 help 422 help
420 If you say yes to this option, support will be included for the 423 If you say yes to this option, support will be included for the
421 S3 Savage 4 I2C interface. 424 S3 Savage 4 I2C interface.
422 425
423 This driver is deprecated in favor of the savagefb driver. 426 This driver is deprecated in favor of the savagefb driver.
@@ -452,7 +455,7 @@ config SCx200_I2C
452 455
453 If you don't know what to do here, say N. 456 If you don't know what to do here, say N.
454 457
455 This support is also available as a module. If so, the module 458 This support is also available as a module. If so, the module
456 will be called scx200_i2c. 459 will be called scx200_i2c.
457 460
458 This driver is deprecated and will be dropped soon. Use i2c-gpio 461 This driver is deprecated and will be dropped soon. Use i2c-gpio
@@ -483,14 +486,14 @@ config SCx200_ACB
483 486
484 If you don't know what to do here, say N. 487 If you don't know what to do here, say N.
485 488
486 This support is also available as a module. If so, the module 489 This support is also available as a module. If so, the module
487 will be called scx200_acb. 490 will be called scx200_acb.
488 491
489config I2C_SIS5595 492config I2C_SIS5595
490 tristate "SiS 5595" 493 tristate "SiS 5595"
491 depends on PCI 494 depends on PCI
492 help 495 help
493 If you say yes to this option, support will be included for the 496 If you say yes to this option, support will be included for the
494 SiS5595 SMBus (a subset of I2C) interface. 497 SiS5595 SMBus (a subset of I2C) interface.
495 498
496 This driver can also be built as a module. If so, the module 499 This driver can also be built as a module. If so, the module
@@ -500,7 +503,7 @@ config I2C_SIS630
500 tristate "SiS 630/730" 503 tristate "SiS 630/730"
501 depends on PCI 504 depends on PCI
502 help 505 help
503 If you say yes to this option, support will be included for the 506 If you say yes to this option, support will be included for the
504 SiS630 and SiS730 SMBus (a subset of I2C) interface. 507 SiS630 and SiS730 SMBus (a subset of I2C) interface.
505 508
506 This driver can also be built as a module. If so, the module 509 This driver can also be built as a module. If so, the module
@@ -632,9 +635,9 @@ config I2C_PCA_ISA
632 select I2C_ALGOPCA 635 select I2C_ALGOPCA
633 default n 636 default n
634 help 637 help
635 This driver supports ISA boards using the Philips PCA 9564 638 This driver supports ISA boards using the Philips PCA9564
636 Parallel bus to I2C bus controller 639 parallel bus to I2C bus controller.
637 640
638 This driver can also be built as a module. If so, the module 641 This driver can also be built as a module. If so, the module
639 will be called i2c-pca-isa. 642 will be called i2c-pca-isa.
640 643
@@ -643,6 +646,17 @@ config I2C_PCA_ISA
643 delays when I2C/SMBus chip drivers are loaded (e.g. at boot 646 delays when I2C/SMBus chip drivers are loaded (e.g. at boot
644 time). If unsure, say N. 647 time). If unsure, say N.
645 648
649config I2C_PCA_PLATFORM
650 tristate "PCA9564 as platform device"
651 select I2C_ALGOPCA
652 default n
653 help
654 This driver supports a memory mapped Philips PCA9564
655 parallel bus to I2C bus controller.
656
657 This driver can also be built as a module. If so, the module
658 will be called i2c-pca-platform.
659
646config I2C_MV64XXX 660config I2C_MV64XXX
647 tristate "Marvell mv64xxx I2C Controller" 661 tristate "Marvell mv64xxx I2C Controller"
648 depends on (MV64X60 || PLAT_ORION) && EXPERIMENTAL 662 depends on (MV64X60 || PLAT_ORION) && EXPERIMENTAL
@@ -672,4 +686,23 @@ config I2C_PMCMSP
672 This driver can also be built as module. If so, the module 686 This driver can also be built as module. If so, the module
673 will be called i2c-pmcmsp. 687 will be called i2c-pmcmsp.
674 688
689config I2C_SH7760
690 tristate "Renesas SH7760 I2C Controller"
691 depends on CPU_SUBTYPE_SH7760
692 help
693 This driver supports the 2 I2C interfaces on the Renesas SH7760.
694
695 This driver can also be built as a module. If so, the module
696 will be called i2c-sh7760.
697
698config I2C_SH_MOBILE
699 tristate "SuperH Mobile I2C Controller"
700 depends on SUPERH
701 help
702 If you say yes to this option, support will be included for the
703 built-in I2C interface on the Renesas SH-Mobile processor.
704
705 This driver can also be built as a module. If so, the module
706 will be called i2c-sh_mobile.
707
675endmenu 708endmenu
diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
index ea7068f1eb6b..e8c882a5ea66 100644
--- a/drivers/i2c/busses/Makefile
+++ b/drivers/i2c/busses/Makefile
@@ -30,6 +30,7 @@ obj-$(CONFIG_I2C_PARPORT) += i2c-parport.o
30obj-$(CONFIG_I2C_PARPORT_LIGHT) += i2c-parport-light.o 30obj-$(CONFIG_I2C_PARPORT_LIGHT) += i2c-parport-light.o
31obj-$(CONFIG_I2C_PASEMI) += i2c-pasemi.o 31obj-$(CONFIG_I2C_PASEMI) += i2c-pasemi.o
32obj-$(CONFIG_I2C_PCA_ISA) += i2c-pca-isa.o 32obj-$(CONFIG_I2C_PCA_ISA) += i2c-pca-isa.o
33obj-$(CONFIG_I2C_PCA_PLATFORM) += i2c-pca-platform.o
33obj-$(CONFIG_I2C_PIIX4) += i2c-piix4.o 34obj-$(CONFIG_I2C_PIIX4) += i2c-piix4.o
34obj-$(CONFIG_I2C_PMCMSP) += i2c-pmcmsp.o 35obj-$(CONFIG_I2C_PMCMSP) += i2c-pmcmsp.o
35obj-$(CONFIG_I2C_PNX) += i2c-pnx.o 36obj-$(CONFIG_I2C_PNX) += i2c-pnx.o
@@ -37,6 +38,8 @@ obj-$(CONFIG_I2C_PROSAVAGE) += i2c-prosavage.o
37obj-$(CONFIG_I2C_PXA) += i2c-pxa.o 38obj-$(CONFIG_I2C_PXA) += i2c-pxa.o
38obj-$(CONFIG_I2C_S3C2410) += i2c-s3c2410.o 39obj-$(CONFIG_I2C_S3C2410) += i2c-s3c2410.o
39obj-$(CONFIG_I2C_SAVAGE4) += i2c-savage4.o 40obj-$(CONFIG_I2C_SAVAGE4) += i2c-savage4.o
41obj-$(CONFIG_I2C_SH7760) += i2c-sh7760.o
42obj-$(CONFIG_I2C_SH_MOBILE) += i2c-sh_mobile.o
40obj-$(CONFIG_I2C_SIBYTE) += i2c-sibyte.o 43obj-$(CONFIG_I2C_SIBYTE) += i2c-sibyte.o
41obj-$(CONFIG_I2C_SIMTEC) += i2c-simtec.o 44obj-$(CONFIG_I2C_SIMTEC) += i2c-simtec.o
42obj-$(CONFIG_I2C_SIS5595) += i2c-sis5595.o 45obj-$(CONFIG_I2C_SIS5595) += i2c-sis5595.o
diff --git a/drivers/i2c/busses/i2c-at91.c b/drivers/i2c/busses/i2c-at91.c
index c09b036913bd..73d61946a534 100644
--- a/drivers/i2c/busses/i2c-at91.c
+++ b/drivers/i2c/busses/i2c-at91.c
@@ -298,7 +298,7 @@ static int at91_i2c_resume(struct platform_device *pdev)
298#endif 298#endif
299 299
300/* work with "modprobe at91_i2c" from hotplugging or coldplugging */ 300/* work with "modprobe at91_i2c" from hotplugging or coldplugging */
301MODULE_ALIAS("at91_i2c"); 301MODULE_ALIAS("platform:at91_i2c");
302 302
303static struct platform_driver at91_i2c_driver = { 303static struct platform_driver at91_i2c_driver = {
304 .probe = at91_i2c_probe, 304 .probe = at91_i2c_probe,
diff --git a/drivers/i2c/busses/i2c-au1550.c b/drivers/i2c/busses/i2c-au1550.c
index 1953b26da56a..491718fe46b7 100644
--- a/drivers/i2c/busses/i2c-au1550.c
+++ b/drivers/i2c/busses/i2c-au1550.c
@@ -472,6 +472,7 @@ i2c_au1550_exit(void)
472MODULE_AUTHOR("Dan Malek, Embedded Edge, LLC."); 472MODULE_AUTHOR("Dan Malek, Embedded Edge, LLC.");
473MODULE_DESCRIPTION("SMBus adapter Alchemy pb1550"); 473MODULE_DESCRIPTION("SMBus adapter Alchemy pb1550");
474MODULE_LICENSE("GPL"); 474MODULE_LICENSE("GPL");
475MODULE_ALIAS("platform:au1xpsc_smbus");
475 476
476module_init (i2c_au1550_init); 477module_init (i2c_au1550_init);
477module_exit (i2c_au1550_exit); 478module_exit (i2c_au1550_exit);
diff --git a/drivers/i2c/busses/i2c-bfin-twi.c b/drivers/i2c/busses/i2c-bfin-twi.c
index 7dbdaeb707a9..48d084bdf7c8 100644
--- a/drivers/i2c/busses/i2c-bfin-twi.c
+++ b/drivers/i2c/busses/i2c-bfin-twi.c
@@ -1,25 +1,11 @@
1/* 1/*
2 * drivers/i2c/busses/i2c-bfin-twi.c 2 * Blackfin On-Chip Two Wire Interface Driver
3 * 3 *
4 * Description: Driver for Blackfin Two Wire Interface 4 * Copyright 2005-2007 Analog Devices Inc.
5 * 5 *
6 * Author: sonicz <sonic.zhang@analog.com> 6 * Enter bugs at http://blackfin.uclinux.org/
7 * 7 *
8 * Copyright (c) 2005-2007 Analog Devices, Inc. 8 * Licensed under the GPL-2 or later.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 */ 9 */
24 10
25#include <linux/module.h> 11#include <linux/module.h>
@@ -34,14 +20,16 @@
34#include <linux/platform_device.h> 20#include <linux/platform_device.h>
35 21
36#include <asm/blackfin.h> 22#include <asm/blackfin.h>
23#include <asm/portmux.h>
37#include <asm/irq.h> 24#include <asm/irq.h>
38 25
39#define POLL_TIMEOUT (2 * HZ) 26#define POLL_TIMEOUT (2 * HZ)
40 27
41/* SMBus mode*/ 28/* SMBus mode*/
42#define TWI_I2C_MODE_STANDARD 0x01 29#define TWI_I2C_MODE_STANDARD 1
43#define TWI_I2C_MODE_STANDARDSUB 0x02 30#define TWI_I2C_MODE_STANDARDSUB 2
44#define TWI_I2C_MODE_COMBINED 0x04 31#define TWI_I2C_MODE_COMBINED 3
32#define TWI_I2C_MODE_REPEAT 4
45 33
46struct bfin_twi_iface { 34struct bfin_twi_iface {
47 int irq; 35 int irq;
@@ -58,39 +46,74 @@ struct bfin_twi_iface {
58 struct timer_list timeout_timer; 46 struct timer_list timeout_timer;
59 struct i2c_adapter adap; 47 struct i2c_adapter adap;
60 struct completion complete; 48 struct completion complete;
49 struct i2c_msg *pmsg;
50 int msg_num;
51 int cur_msg;
52 void __iomem *regs_base;
61}; 53};
62 54
63static struct bfin_twi_iface twi_iface; 55
56#define DEFINE_TWI_REG(reg, off) \
57static inline u16 read_##reg(struct bfin_twi_iface *iface) \
58 { return bfin_read16(iface->regs_base + (off)); } \
59static inline void write_##reg(struct bfin_twi_iface *iface, u16 v) \
60 { bfin_write16(iface->regs_base + (off), v); }
61
62DEFINE_TWI_REG(CLKDIV, 0x00)
63DEFINE_TWI_REG(CONTROL, 0x04)
64DEFINE_TWI_REG(SLAVE_CTL, 0x08)
65DEFINE_TWI_REG(SLAVE_STAT, 0x0C)
66DEFINE_TWI_REG(SLAVE_ADDR, 0x10)
67DEFINE_TWI_REG(MASTER_CTL, 0x14)
68DEFINE_TWI_REG(MASTER_STAT, 0x18)
69DEFINE_TWI_REG(MASTER_ADDR, 0x1C)
70DEFINE_TWI_REG(INT_STAT, 0x20)
71DEFINE_TWI_REG(INT_MASK, 0x24)
72DEFINE_TWI_REG(FIFO_CTL, 0x28)
73DEFINE_TWI_REG(FIFO_STAT, 0x2C)
74DEFINE_TWI_REG(XMT_DATA8, 0x80)
75DEFINE_TWI_REG(XMT_DATA16, 0x84)
76DEFINE_TWI_REG(RCV_DATA8, 0x88)
77DEFINE_TWI_REG(RCV_DATA16, 0x8C)
78
79static const u16 pin_req[2][3] = {
80 {P_TWI0_SCL, P_TWI0_SDA, 0},
81 {P_TWI1_SCL, P_TWI1_SDA, 0},
82};
64 83
65static void bfin_twi_handle_interrupt(struct bfin_twi_iface *iface) 84static void bfin_twi_handle_interrupt(struct bfin_twi_iface *iface)
66{ 85{
67 unsigned short twi_int_status = bfin_read_TWI_INT_STAT(); 86 unsigned short twi_int_status = read_INT_STAT(iface);
68 unsigned short mast_stat = bfin_read_TWI_MASTER_STAT(); 87 unsigned short mast_stat = read_MASTER_STAT(iface);
69 88
70 if (twi_int_status & XMTSERV) { 89 if (twi_int_status & XMTSERV) {
71 /* Transmit next data */ 90 /* Transmit next data */
72 if (iface->writeNum > 0) { 91 if (iface->writeNum > 0) {
73 bfin_write_TWI_XMT_DATA8(*(iface->transPtr++)); 92 write_XMT_DATA8(iface, *(iface->transPtr++));
74 iface->writeNum--; 93 iface->writeNum--;
75 } 94 }
76 /* start receive immediately after complete sending in 95 /* start receive immediately after complete sending in
77 * combine mode. 96 * combine mode.
78 */ 97 */
79 else if (iface->cur_mode == TWI_I2C_MODE_COMBINED) { 98 else if (iface->cur_mode == TWI_I2C_MODE_COMBINED)
80 bfin_write_TWI_MASTER_CTL(bfin_read_TWI_MASTER_CTL() 99 write_MASTER_CTL(iface,
81 | MDIR | RSTART); 100 read_MASTER_CTL(iface) | MDIR | RSTART);
82 } else if (iface->manual_stop) 101 else if (iface->manual_stop)
83 bfin_write_TWI_MASTER_CTL(bfin_read_TWI_MASTER_CTL() 102 write_MASTER_CTL(iface,
84 | STOP); 103 read_MASTER_CTL(iface) | STOP);
104 else if (iface->cur_mode == TWI_I2C_MODE_REPEAT &&
105 iface->cur_msg+1 < iface->msg_num)
106 write_MASTER_CTL(iface,
107 read_MASTER_CTL(iface) | RSTART);
85 SSYNC(); 108 SSYNC();
86 /* Clear status */ 109 /* Clear status */
87 bfin_write_TWI_INT_STAT(XMTSERV); 110 write_INT_STAT(iface, XMTSERV);
88 SSYNC(); 111 SSYNC();
89 } 112 }
90 if (twi_int_status & RCVSERV) { 113 if (twi_int_status & RCVSERV) {
91 if (iface->readNum > 0) { 114 if (iface->readNum > 0) {
92 /* Receive next data */ 115 /* Receive next data */
93 *(iface->transPtr) = bfin_read_TWI_RCV_DATA8(); 116 *(iface->transPtr) = read_RCV_DATA8(iface);
94 if (iface->cur_mode == TWI_I2C_MODE_COMBINED) { 117 if (iface->cur_mode == TWI_I2C_MODE_COMBINED) {
95 /* Change combine mode into sub mode after 118 /* Change combine mode into sub mode after
96 * read first data. 119 * read first data.
@@ -105,28 +128,33 @@ static void bfin_twi_handle_interrupt(struct bfin_twi_iface *iface)
105 iface->transPtr++; 128 iface->transPtr++;
106 iface->readNum--; 129 iface->readNum--;
107 } else if (iface->manual_stop) { 130 } else if (iface->manual_stop) {
108 bfin_write_TWI_MASTER_CTL(bfin_read_TWI_MASTER_CTL() 131 write_MASTER_CTL(iface,
109 | STOP); 132 read_MASTER_CTL(iface) | STOP);
133 SSYNC();
134 } else if (iface->cur_mode == TWI_I2C_MODE_REPEAT &&
135 iface->cur_msg+1 < iface->msg_num) {
136 write_MASTER_CTL(iface,
137 read_MASTER_CTL(iface) | RSTART);
110 SSYNC(); 138 SSYNC();
111 } 139 }
112 /* Clear interrupt source */ 140 /* Clear interrupt source */
113 bfin_write_TWI_INT_STAT(RCVSERV); 141 write_INT_STAT(iface, RCVSERV);
114 SSYNC(); 142 SSYNC();
115 } 143 }
116 if (twi_int_status & MERR) { 144 if (twi_int_status & MERR) {
117 bfin_write_TWI_INT_STAT(MERR); 145 write_INT_STAT(iface, MERR);
118 bfin_write_TWI_INT_MASK(0); 146 write_INT_MASK(iface, 0);
119 bfin_write_TWI_MASTER_STAT(0x3e); 147 write_MASTER_STAT(iface, 0x3e);
120 bfin_write_TWI_MASTER_CTL(0); 148 write_MASTER_CTL(iface, 0);
121 SSYNC(); 149 SSYNC();
122 iface->result = -1; 150 iface->result = -EIO;
123 /* if both err and complete int stats are set, return proper 151 /* if both err and complete int stats are set, return proper
124 * results. 152 * results.
125 */ 153 */
126 if (twi_int_status & MCOMP) { 154 if (twi_int_status & MCOMP) {
127 bfin_write_TWI_INT_STAT(MCOMP); 155 write_INT_STAT(iface, MCOMP);
128 bfin_write_TWI_INT_MASK(0); 156 write_INT_MASK(iface, 0);
129 bfin_write_TWI_MASTER_CTL(0); 157 write_MASTER_CTL(iface, 0);
130 SSYNC(); 158 SSYNC();
131 /* If it is a quick transfer, only address bug no data, 159 /* If it is a quick transfer, only address bug no data,
132 * not an err, return 1. 160 * not an err, return 1.
@@ -143,7 +171,7 @@ static void bfin_twi_handle_interrupt(struct bfin_twi_iface *iface)
143 return; 171 return;
144 } 172 }
145 if (twi_int_status & MCOMP) { 173 if (twi_int_status & MCOMP) {
146 bfin_write_TWI_INT_STAT(MCOMP); 174 write_INT_STAT(iface, MCOMP);
147 SSYNC(); 175 SSYNC();
148 if (iface->cur_mode == TWI_I2C_MODE_COMBINED) { 176 if (iface->cur_mode == TWI_I2C_MODE_COMBINED) {
149 if (iface->readNum == 0) { 177 if (iface->readNum == 0) {
@@ -152,28 +180,63 @@ static void bfin_twi_handle_interrupt(struct bfin_twi_iface *iface)
152 */ 180 */
153 iface->readNum = 1; 181 iface->readNum = 1;
154 iface->manual_stop = 1; 182 iface->manual_stop = 1;
155 bfin_write_TWI_MASTER_CTL( 183 write_MASTER_CTL(iface,
156 bfin_read_TWI_MASTER_CTL() 184 read_MASTER_CTL(iface) | (0xff << 6));
157 | (0xff << 6));
158 } else { 185 } else {
159 /* set the readd number in other 186 /* set the readd number in other
160 * combine mode. 187 * combine mode.
161 */ 188 */
162 bfin_write_TWI_MASTER_CTL( 189 write_MASTER_CTL(iface,
163 (bfin_read_TWI_MASTER_CTL() & 190 (read_MASTER_CTL(iface) &
164 (~(0xff << 6))) | 191 (~(0xff << 6))) |
165 ( iface->readNum << 6)); 192 (iface->readNum << 6));
193 }
194 /* remove restart bit and enable master receive */
195 write_MASTER_CTL(iface,
196 read_MASTER_CTL(iface) & ~RSTART);
197 write_MASTER_CTL(iface,
198 read_MASTER_CTL(iface) | MEN | MDIR);
199 SSYNC();
200 } else if (iface->cur_mode == TWI_I2C_MODE_REPEAT &&
201 iface->cur_msg+1 < iface->msg_num) {
202 iface->cur_msg++;
203 iface->transPtr = iface->pmsg[iface->cur_msg].buf;
204 iface->writeNum = iface->readNum =
205 iface->pmsg[iface->cur_msg].len;
206 /* Set Transmit device address */
207 write_MASTER_ADDR(iface,
208 iface->pmsg[iface->cur_msg].addr);
209 if (iface->pmsg[iface->cur_msg].flags & I2C_M_RD)
210 iface->read_write = I2C_SMBUS_READ;
211 else {
212 iface->read_write = I2C_SMBUS_WRITE;
213 /* Transmit first data */
214 if (iface->writeNum > 0) {
215 write_XMT_DATA8(iface,
216 *(iface->transPtr++));
217 iface->writeNum--;
218 SSYNC();
219 }
220 }
221
222 if (iface->pmsg[iface->cur_msg].len <= 255)
223 write_MASTER_CTL(iface,
224 iface->pmsg[iface->cur_msg].len << 6);
225 else {
226 write_MASTER_CTL(iface, 0xff << 6);
227 iface->manual_stop = 1;
166 } 228 }
167 /* remove restart bit and enable master receive */ 229 /* remove restart bit and enable master receive */
168 bfin_write_TWI_MASTER_CTL(bfin_read_TWI_MASTER_CTL() & 230 write_MASTER_CTL(iface,
169 ~RSTART); 231 read_MASTER_CTL(iface) & ~RSTART);
170 bfin_write_TWI_MASTER_CTL(bfin_read_TWI_MASTER_CTL() | 232 write_MASTER_CTL(iface, read_MASTER_CTL(iface) |
171 MEN | MDIR); 233 MEN | ((iface->read_write == I2C_SMBUS_READ) ?
234 MDIR : 0));
172 SSYNC(); 235 SSYNC();
173 } else { 236 } else {
174 iface->result = 1; 237 iface->result = 1;
175 bfin_write_TWI_INT_MASK(0); 238 write_INT_MASK(iface, 0);
176 bfin_write_TWI_MASTER_CTL(0); 239 write_MASTER_CTL(iface, 0);
177 SSYNC(); 240 SSYNC();
178 complete(&iface->complete); 241 complete(&iface->complete);
179 } 242 }
@@ -221,91 +284,85 @@ static int bfin_twi_master_xfer(struct i2c_adapter *adap,
221{ 284{
222 struct bfin_twi_iface *iface = adap->algo_data; 285 struct bfin_twi_iface *iface = adap->algo_data;
223 struct i2c_msg *pmsg; 286 struct i2c_msg *pmsg;
224 int i, ret;
225 int rc = 0; 287 int rc = 0;
226 288
227 if (!(bfin_read_TWI_CONTROL() & TWI_ENA)) 289 if (!(read_CONTROL(iface) & TWI_ENA))
228 return -ENXIO; 290 return -ENXIO;
229 291
230 while (bfin_read_TWI_MASTER_STAT() & BUSBUSY) { 292 while (read_MASTER_STAT(iface) & BUSBUSY)
231 yield(); 293 yield();
294
295 iface->pmsg = msgs;
296 iface->msg_num = num;
297 iface->cur_msg = 0;
298
299 pmsg = &msgs[0];
300 if (pmsg->flags & I2C_M_TEN) {
301 dev_err(&adap->dev, "10 bits addr not supported!\n");
302 return -EINVAL;
232 } 303 }
233 304
234 ret = 0; 305 iface->cur_mode = TWI_I2C_MODE_REPEAT;
235 for (i = 0; rc >= 0 && i < num; i++) { 306 iface->manual_stop = 0;
236 pmsg = &msgs[i]; 307 iface->transPtr = pmsg->buf;
237 if (pmsg->flags & I2C_M_TEN) { 308 iface->writeNum = iface->readNum = pmsg->len;
238 dev_err(&(adap->dev), "i2c-bfin-twi: 10 bits addr " 309 iface->result = 0;
239 "not supported !\n"); 310 iface->timeout_count = 10;
240 rc = -EINVAL; 311 init_completion(&(iface->complete));
241 break; 312 /* Set Transmit device address */
242 } 313 write_MASTER_ADDR(iface, pmsg->addr);
243 314
244 iface->cur_mode = TWI_I2C_MODE_STANDARD; 315 /* FIFO Initiation. Data in FIFO should be
245 iface->manual_stop = 0; 316 * discarded before start a new operation.
246 iface->transPtr = pmsg->buf; 317 */
247 iface->writeNum = iface->readNum = pmsg->len; 318 write_FIFO_CTL(iface, 0x3);
248 iface->result = 0; 319 SSYNC();
249 iface->timeout_count = 10; 320 write_FIFO_CTL(iface, 0);
250 /* Set Transmit device address */ 321 SSYNC();
251 bfin_write_TWI_MASTER_ADDR(pmsg->addr);
252
253 /* FIFO Initiation. Data in FIFO should be
254 * discarded before start a new operation.
255 */
256 bfin_write_TWI_FIFO_CTL(0x3);
257 SSYNC();
258 bfin_write_TWI_FIFO_CTL(0);
259 SSYNC();
260 322
261 if (pmsg->flags & I2C_M_RD) 323 if (pmsg->flags & I2C_M_RD)
262 iface->read_write = I2C_SMBUS_READ; 324 iface->read_write = I2C_SMBUS_READ;
263 else { 325 else {
264 iface->read_write = I2C_SMBUS_WRITE; 326 iface->read_write = I2C_SMBUS_WRITE;
265 /* Transmit first data */ 327 /* Transmit first data */
266 if (iface->writeNum > 0) { 328 if (iface->writeNum > 0) {
267 bfin_write_TWI_XMT_DATA8(*(iface->transPtr++)); 329 write_XMT_DATA8(iface, *(iface->transPtr++));
268 iface->writeNum--; 330 iface->writeNum--;
269 SSYNC(); 331 SSYNC();
270 }
271 } 332 }
333 }
272 334
273 /* clear int stat */ 335 /* clear int stat */
274 bfin_write_TWI_INT_STAT(MERR|MCOMP|XMTSERV|RCVSERV); 336 write_INT_STAT(iface, MERR | MCOMP | XMTSERV | RCVSERV);
275 337
276 /* Interrupt mask . Enable XMT, RCV interrupt */ 338 /* Interrupt mask . Enable XMT, RCV interrupt */
277 bfin_write_TWI_INT_MASK(MCOMP | MERR | 339 write_INT_MASK(iface, MCOMP | MERR | RCVSERV | XMTSERV);
278 ((iface->read_write == I2C_SMBUS_READ)? 340 SSYNC();
279 RCVSERV : XMTSERV));
280 SSYNC();
281 341
282 if (pmsg->len > 0 && pmsg->len <= 255) 342 if (pmsg->len <= 255)
283 bfin_write_TWI_MASTER_CTL(pmsg->len << 6); 343 write_MASTER_CTL(iface, pmsg->len << 6);
284 else if (pmsg->len > 255) { 344 else {
285 bfin_write_TWI_MASTER_CTL(0xff << 6); 345 write_MASTER_CTL(iface, 0xff << 6);
286 iface->manual_stop = 1; 346 iface->manual_stop = 1;
287 } else 347 }
288 break;
289 348
290 iface->timeout_timer.expires = jiffies + POLL_TIMEOUT; 349 iface->timeout_timer.expires = jiffies + POLL_TIMEOUT;
291 add_timer(&iface->timeout_timer); 350 add_timer(&iface->timeout_timer);
292 351
293 /* Master enable */ 352 /* Master enable */
294 bfin_write_TWI_MASTER_CTL(bfin_read_TWI_MASTER_CTL() | MEN | 353 write_MASTER_CTL(iface, read_MASTER_CTL(iface) | MEN |
295 ((iface->read_write == I2C_SMBUS_READ) ? MDIR : 0) | 354 ((iface->read_write == I2C_SMBUS_READ) ? MDIR : 0) |
296 ((CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ>100) ? FAST : 0)); 355 ((CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ > 100) ? FAST : 0));
297 SSYNC(); 356 SSYNC();
298 357
299 wait_for_completion(&iface->complete); 358 wait_for_completion(&iface->complete);
300 359
301 rc = iface->result; 360 rc = iface->result;
302 if (rc == 1)
303 ret++;
304 else if (rc == -1)
305 break;
306 }
307 361
308 return ret; 362 if (rc == 1)
363 return num;
364 else
365 return rc;
309} 366}
310 367
311/* 368/*
@@ -319,12 +376,11 @@ int bfin_twi_smbus_xfer(struct i2c_adapter *adap, u16 addr,
319 struct bfin_twi_iface *iface = adap->algo_data; 376 struct bfin_twi_iface *iface = adap->algo_data;
320 int rc = 0; 377 int rc = 0;
321 378
322 if (!(bfin_read_TWI_CONTROL() & TWI_ENA)) 379 if (!(read_CONTROL(iface) & TWI_ENA))
323 return -ENXIO; 380 return -ENXIO;
324 381
325 while (bfin_read_TWI_MASTER_STAT() & BUSBUSY) { 382 while (read_MASTER_STAT(iface) & BUSBUSY)
326 yield(); 383 yield();
327 }
328 384
329 iface->writeNum = 0; 385 iface->writeNum = 0;
330 iface->readNum = 0; 386 iface->readNum = 0;
@@ -392,19 +448,20 @@ int bfin_twi_smbus_xfer(struct i2c_adapter *adap, u16 addr,
392 iface->read_write = read_write; 448 iface->read_write = read_write;
393 iface->command = command; 449 iface->command = command;
394 iface->timeout_count = 10; 450 iface->timeout_count = 10;
451 init_completion(&(iface->complete));
395 452
396 /* FIFO Initiation. Data in FIFO should be discarded before 453 /* FIFO Initiation. Data in FIFO should be discarded before
397 * start a new operation. 454 * start a new operation.
398 */ 455 */
399 bfin_write_TWI_FIFO_CTL(0x3); 456 write_FIFO_CTL(iface, 0x3);
400 SSYNC(); 457 SSYNC();
401 bfin_write_TWI_FIFO_CTL(0); 458 write_FIFO_CTL(iface, 0);
402 459
403 /* clear int stat */ 460 /* clear int stat */
404 bfin_write_TWI_INT_STAT(MERR|MCOMP|XMTSERV|RCVSERV); 461 write_INT_STAT(iface, MERR | MCOMP | XMTSERV | RCVSERV);
405 462
406 /* Set Transmit device address */ 463 /* Set Transmit device address */
407 bfin_write_TWI_MASTER_ADDR(addr); 464 write_MASTER_ADDR(iface, addr);
408 SSYNC(); 465 SSYNC();
409 466
410 iface->timeout_timer.expires = jiffies + POLL_TIMEOUT; 467 iface->timeout_timer.expires = jiffies + POLL_TIMEOUT;
@@ -412,60 +469,64 @@ int bfin_twi_smbus_xfer(struct i2c_adapter *adap, u16 addr,
412 469
413 switch (iface->cur_mode) { 470 switch (iface->cur_mode) {
414 case TWI_I2C_MODE_STANDARDSUB: 471 case TWI_I2C_MODE_STANDARDSUB:
415 bfin_write_TWI_XMT_DATA8(iface->command); 472 write_XMT_DATA8(iface, iface->command);
416 bfin_write_TWI_INT_MASK(MCOMP | MERR | 473 write_INT_MASK(iface, MCOMP | MERR |
417 ((iface->read_write == I2C_SMBUS_READ) ? 474 ((iface->read_write == I2C_SMBUS_READ) ?
418 RCVSERV : XMTSERV)); 475 RCVSERV : XMTSERV));
419 SSYNC(); 476 SSYNC();
420 477
421 if (iface->writeNum + 1 <= 255) 478 if (iface->writeNum + 1 <= 255)
422 bfin_write_TWI_MASTER_CTL((iface->writeNum + 1) << 6); 479 write_MASTER_CTL(iface, (iface->writeNum + 1) << 6);
423 else { 480 else {
424 bfin_write_TWI_MASTER_CTL(0xff << 6); 481 write_MASTER_CTL(iface, 0xff << 6);
425 iface->manual_stop = 1; 482 iface->manual_stop = 1;
426 } 483 }
427 /* Master enable */ 484 /* Master enable */
428 bfin_write_TWI_MASTER_CTL(bfin_read_TWI_MASTER_CTL() | MEN | 485 write_MASTER_CTL(iface, read_MASTER_CTL(iface) | MEN |
429 ((CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ>100) ? FAST : 0)); 486 ((CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ>100) ? FAST : 0));
430 break; 487 break;
431 case TWI_I2C_MODE_COMBINED: 488 case TWI_I2C_MODE_COMBINED:
432 bfin_write_TWI_XMT_DATA8(iface->command); 489 write_XMT_DATA8(iface, iface->command);
433 bfin_write_TWI_INT_MASK(MCOMP | MERR | RCVSERV | XMTSERV); 490 write_INT_MASK(iface, MCOMP | MERR | RCVSERV | XMTSERV);
434 SSYNC(); 491 SSYNC();
435 492
436 if (iface->writeNum > 0) 493 if (iface->writeNum > 0)
437 bfin_write_TWI_MASTER_CTL((iface->writeNum + 1) << 6); 494 write_MASTER_CTL(iface, (iface->writeNum + 1) << 6);
438 else 495 else
439 bfin_write_TWI_MASTER_CTL(0x1 << 6); 496 write_MASTER_CTL(iface, 0x1 << 6);
440 /* Master enable */ 497 /* Master enable */
441 bfin_write_TWI_MASTER_CTL(bfin_read_TWI_MASTER_CTL() | MEN | 498 write_MASTER_CTL(iface, read_MASTER_CTL(iface) | MEN |
442 ((CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ>100) ? FAST : 0)); 499 ((CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ>100) ? FAST : 0));
443 break; 500 break;
444 default: 501 default:
445 bfin_write_TWI_MASTER_CTL(0); 502 write_MASTER_CTL(iface, 0);
446 if (size != I2C_SMBUS_QUICK) { 503 if (size != I2C_SMBUS_QUICK) {
447 /* Don't access xmit data register when this is a 504 /* Don't access xmit data register when this is a
448 * read operation. 505 * read operation.
449 */ 506 */
450 if (iface->read_write != I2C_SMBUS_READ) { 507 if (iface->read_write != I2C_SMBUS_READ) {
451 if (iface->writeNum > 0) { 508 if (iface->writeNum > 0) {
452 bfin_write_TWI_XMT_DATA8(*(iface->transPtr++)); 509 write_XMT_DATA8(iface,
510 *(iface->transPtr++));
453 if (iface->writeNum <= 255) 511 if (iface->writeNum <= 255)
454 bfin_write_TWI_MASTER_CTL(iface->writeNum << 6); 512 write_MASTER_CTL(iface,
513 iface->writeNum << 6);
455 else { 514 else {
456 bfin_write_TWI_MASTER_CTL(0xff << 6); 515 write_MASTER_CTL(iface,
516 0xff << 6);
457 iface->manual_stop = 1; 517 iface->manual_stop = 1;
458 } 518 }
459 iface->writeNum--; 519 iface->writeNum--;
460 } else { 520 } else {
461 bfin_write_TWI_XMT_DATA8(iface->command); 521 write_XMT_DATA8(iface, iface->command);
462 bfin_write_TWI_MASTER_CTL(1 << 6); 522 write_MASTER_CTL(iface, 1 << 6);
463 } 523 }
464 } else { 524 } else {
465 if (iface->readNum > 0 && iface->readNum <= 255) 525 if (iface->readNum > 0 && iface->readNum <= 255)
466 bfin_write_TWI_MASTER_CTL(iface->readNum << 6); 526 write_MASTER_CTL(iface,
527 iface->readNum << 6);
467 else if (iface->readNum > 255) { 528 else if (iface->readNum > 255) {
468 bfin_write_TWI_MASTER_CTL(0xff << 6); 529 write_MASTER_CTL(iface, 0xff << 6);
469 iface->manual_stop = 1; 530 iface->manual_stop = 1;
470 } else { 531 } else {
471 del_timer(&iface->timeout_timer); 532 del_timer(&iface->timeout_timer);
@@ -473,13 +534,13 @@ int bfin_twi_smbus_xfer(struct i2c_adapter *adap, u16 addr,
473 } 534 }
474 } 535 }
475 } 536 }
476 bfin_write_TWI_INT_MASK(MCOMP | MERR | 537 write_INT_MASK(iface, MCOMP | MERR |
477 ((iface->read_write == I2C_SMBUS_READ) ? 538 ((iface->read_write == I2C_SMBUS_READ) ?
478 RCVSERV : XMTSERV)); 539 RCVSERV : XMTSERV));
479 SSYNC(); 540 SSYNC();
480 541
481 /* Master enable */ 542 /* Master enable */
482 bfin_write_TWI_MASTER_CTL(bfin_read_TWI_MASTER_CTL() | MEN | 543 write_MASTER_CTL(iface, read_MASTER_CTL(iface) | MEN |
483 ((iface->read_write == I2C_SMBUS_READ) ? MDIR : 0) | 544 ((iface->read_write == I2C_SMBUS_READ) ? MDIR : 0) |
484 ((CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ > 100) ? FAST : 0)); 545 ((CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ > 100) ? FAST : 0));
485 break; 546 break;
@@ -514,10 +575,10 @@ static struct i2c_algorithm bfin_twi_algorithm = {
514 575
515static int i2c_bfin_twi_suspend(struct platform_device *dev, pm_message_t state) 576static int i2c_bfin_twi_suspend(struct platform_device *dev, pm_message_t state)
516{ 577{
517/* struct bfin_twi_iface *iface = platform_get_drvdata(dev);*/ 578 struct bfin_twi_iface *iface = platform_get_drvdata(dev);
518 579
519 /* Disable TWI */ 580 /* Disable TWI */
520 bfin_write_TWI_CONTROL(bfin_read_TWI_CONTROL() & ~TWI_ENA); 581 write_CONTROL(iface, read_CONTROL(iface) & ~TWI_ENA);
521 SSYNC(); 582 SSYNC();
522 583
523 return 0; 584 return 0;
@@ -525,24 +586,52 @@ static int i2c_bfin_twi_suspend(struct platform_device *dev, pm_message_t state)
525 586
526static int i2c_bfin_twi_resume(struct platform_device *dev) 587static int i2c_bfin_twi_resume(struct platform_device *dev)
527{ 588{
528/* struct bfin_twi_iface *iface = platform_get_drvdata(dev);*/ 589 struct bfin_twi_iface *iface = platform_get_drvdata(dev);
529 590
530 /* Enable TWI */ 591 /* Enable TWI */
531 bfin_write_TWI_CONTROL(bfin_read_TWI_CONTROL() | TWI_ENA); 592 write_CONTROL(iface, read_CONTROL(iface) | TWI_ENA);
532 SSYNC(); 593 SSYNC();
533 594
534 return 0; 595 return 0;
535} 596}
536 597
537static int i2c_bfin_twi_probe(struct platform_device *dev) 598static int i2c_bfin_twi_probe(struct platform_device *pdev)
538{ 599{
539 struct bfin_twi_iface *iface = &twi_iface; 600 struct bfin_twi_iface *iface;
540 struct i2c_adapter *p_adap; 601 struct i2c_adapter *p_adap;
602 struct resource *res;
541 int rc; 603 int rc;
542 604
605 iface = kzalloc(sizeof(struct bfin_twi_iface), GFP_KERNEL);
606 if (!iface) {
607 dev_err(&pdev->dev, "Cannot allocate memory\n");
608 rc = -ENOMEM;
609 goto out_error_nomem;
610 }
611
543 spin_lock_init(&(iface->lock)); 612 spin_lock_init(&(iface->lock));
544 init_completion(&(iface->complete)); 613
545 iface->irq = IRQ_TWI; 614 /* Find and map our resources */
615 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
616 if (res == NULL) {
617 dev_err(&pdev->dev, "Cannot get IORESOURCE_MEM\n");
618 rc = -ENOENT;
619 goto out_error_get_res;
620 }
621
622 iface->regs_base = ioremap(res->start, res->end - res->start + 1);
623 if (iface->regs_base == NULL) {
624 dev_err(&pdev->dev, "Cannot map IO\n");
625 rc = -ENXIO;
626 goto out_error_ioremap;
627 }
628
629 iface->irq = platform_get_irq(pdev, 0);
630 if (iface->irq < 0) {
631 dev_err(&pdev->dev, "No IRQ specified\n");
632 rc = -ENOENT;
633 goto out_error_no_irq;
634 }
546 635
547 init_timer(&(iface->timeout_timer)); 636 init_timer(&(iface->timeout_timer));
548 iface->timeout_timer.function = bfin_twi_timeout; 637 iface->timeout_timer.function = bfin_twi_timeout;
@@ -550,39 +639,63 @@ static int i2c_bfin_twi_probe(struct platform_device *dev)
550 639
551 p_adap = &iface->adap; 640 p_adap = &iface->adap;
552 p_adap->id = I2C_HW_BLACKFIN; 641 p_adap->id = I2C_HW_BLACKFIN;
553 p_adap->nr = dev->id; 642 p_adap->nr = pdev->id;
554 strlcpy(p_adap->name, dev->name, sizeof(p_adap->name)); 643 strlcpy(p_adap->name, pdev->name, sizeof(p_adap->name));
555 p_adap->algo = &bfin_twi_algorithm; 644 p_adap->algo = &bfin_twi_algorithm;
556 p_adap->algo_data = iface; 645 p_adap->algo_data = iface;
557 p_adap->class = I2C_CLASS_ALL; 646 p_adap->class = I2C_CLASS_ALL;
558 p_adap->dev.parent = &dev->dev; 647 p_adap->dev.parent = &pdev->dev;
648
649 rc = peripheral_request_list(pin_req[pdev->id], "i2c-bfin-twi");
650 if (rc) {
651 dev_err(&pdev->dev, "Can't setup pin mux!\n");
652 goto out_error_pin_mux;
653 }
559 654
560 rc = request_irq(iface->irq, bfin_twi_interrupt_entry, 655 rc = request_irq(iface->irq, bfin_twi_interrupt_entry,
561 IRQF_DISABLED, dev->name, iface); 656 IRQF_DISABLED, pdev->name, iface);
562 if (rc) { 657 if (rc) {
563 dev_err(&(p_adap->dev), "i2c-bfin-twi: can't get IRQ %d !\n", 658 dev_err(&pdev->dev, "Can't get IRQ %d !\n", iface->irq);
564 iface->irq); 659 rc = -ENODEV;
565 return -ENODEV; 660 goto out_error_req_irq;
566 } 661 }
567 662
568 /* Set TWI internal clock as 10MHz */ 663 /* Set TWI internal clock as 10MHz */
569 bfin_write_TWI_CONTROL(((get_sclk() / 1024 / 1024 + 5) / 10) & 0x7F); 664 write_CONTROL(iface, ((get_sclk() / 1024 / 1024 + 5) / 10) & 0x7F);
570 665
571 /* Set Twi interface clock as specified */ 666 /* Set Twi interface clock as specified */
572 bfin_write_TWI_CLKDIV((( 5*1024 / CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ ) 667 write_CLKDIV(iface, ((5*1024 / CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ)
573 << 8) | (( 5*1024 / CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ ) 668 << 8) | ((5*1024 / CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ)
574 & 0xFF)); 669 & 0xFF));
575 670
576 /* Enable TWI */ 671 /* Enable TWI */
577 bfin_write_TWI_CONTROL(bfin_read_TWI_CONTROL() | TWI_ENA); 672 write_CONTROL(iface, read_CONTROL(iface) | TWI_ENA);
578 SSYNC(); 673 SSYNC();
579 674
580 rc = i2c_add_numbered_adapter(p_adap); 675 rc = i2c_add_numbered_adapter(p_adap);
581 if (rc < 0) 676 if (rc < 0) {
582 free_irq(iface->irq, iface); 677 dev_err(&pdev->dev, "Can't add i2c adapter!\n");
583 else 678 goto out_error_add_adapter;
584 platform_set_drvdata(dev, iface); 679 }
680
681 platform_set_drvdata(pdev, iface);
585 682
683 dev_info(&pdev->dev, "Blackfin BF5xx on-chip I2C TWI Contoller, "
684 "regs_base@%p\n", iface->regs_base);
685
686 return 0;
687
688out_error_add_adapter:
689 free_irq(iface->irq, iface);
690out_error_req_irq:
691out_error_no_irq:
692 peripheral_free_list(pin_req[pdev->id]);
693out_error_pin_mux:
694 iounmap(iface->regs_base);
695out_error_ioremap:
696out_error_get_res:
697 kfree(iface);
698out_error_nomem:
586 return rc; 699 return rc;
587} 700}
588 701
@@ -594,6 +707,9 @@ static int i2c_bfin_twi_remove(struct platform_device *pdev)
594 707
595 i2c_del_adapter(&(iface->adap)); 708 i2c_del_adapter(&(iface->adap));
596 free_irq(iface->irq, iface); 709 free_irq(iface->irq, iface);
710 peripheral_free_list(pin_req[pdev->id]);
711 iounmap(iface->regs_base);
712 kfree(iface);
597 713
598 return 0; 714 return 0;
599} 715}
@@ -611,8 +727,6 @@ static struct platform_driver i2c_bfin_twi_driver = {
611 727
612static int __init i2c_bfin_twi_init(void) 728static int __init i2c_bfin_twi_init(void)
613{ 729{
614 pr_info("I2C: Blackfin I2C TWI driver\n");
615
616 return platform_driver_register(&i2c_bfin_twi_driver); 730 return platform_driver_register(&i2c_bfin_twi_driver);
617} 731}
618 732
@@ -621,9 +735,10 @@ static void __exit i2c_bfin_twi_exit(void)
621 platform_driver_unregister(&i2c_bfin_twi_driver); 735 platform_driver_unregister(&i2c_bfin_twi_driver);
622} 736}
623 737
624MODULE_AUTHOR("Sonic Zhang <sonic.zhang@analog.com>");
625MODULE_DESCRIPTION("I2C-Bus adapter routines for Blackfin TWI");
626MODULE_LICENSE("GPL");
627
628module_init(i2c_bfin_twi_init); 738module_init(i2c_bfin_twi_init);
629module_exit(i2c_bfin_twi_exit); 739module_exit(i2c_bfin_twi_exit);
740
741MODULE_AUTHOR("Bryan Wu, Sonic Zhang");
742MODULE_DESCRIPTION("Blackfin BF5xx on-chip I2C TWI Contoller Driver");
743MODULE_LICENSE("GPL");
744MODULE_ALIAS("platform:i2c-bfin-twi");
diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c
index fde26345a379..7ecbfc429b19 100644
--- a/drivers/i2c/busses/i2c-davinci.c
+++ b/drivers/i2c/busses/i2c-davinci.c
@@ -328,7 +328,7 @@ i2c_davinci_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
328 int i; 328 int i;
329 int ret; 329 int ret;
330 330
331 dev_dbg(dev->dev, "%s: msgs: %d\n", __FUNCTION__, num); 331 dev_dbg(dev->dev, "%s: msgs: %d\n", __func__, num);
332 332
333 ret = i2c_davinci_wait_bus_not_busy(dev, 1); 333 ret = i2c_davinci_wait_bus_not_busy(dev, 1);
334 if (ret < 0) { 334 if (ret < 0) {
@@ -342,7 +342,7 @@ i2c_davinci_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
342 return ret; 342 return ret;
343 } 343 }
344 344
345 dev_dbg(dev->dev, "%s:%d ret: %d\n", __FUNCTION__, __LINE__, ret); 345 dev_dbg(dev->dev, "%s:%d ret: %d\n", __func__, __LINE__, ret);
346 346
347 return num; 347 return num;
348} 348}
@@ -364,7 +364,7 @@ static irqreturn_t i2c_davinci_isr(int this_irq, void *dev_id)
364 u16 w; 364 u16 w;
365 365
366 while ((stat = davinci_i2c_read_reg(dev, DAVINCI_I2C_IVR_REG))) { 366 while ((stat = davinci_i2c_read_reg(dev, DAVINCI_I2C_IVR_REG))) {
367 dev_dbg(dev->dev, "%s: stat=0x%x\n", __FUNCTION__, stat); 367 dev_dbg(dev->dev, "%s: stat=0x%x\n", __func__, stat);
368 if (count++ == 100) { 368 if (count++ == 100) {
369 dev_warn(dev->dev, "Too much work in one IRQ\n"); 369 dev_warn(dev->dev, "Too much work in one IRQ\n");
370 break; 370 break;
@@ -553,6 +553,9 @@ static int davinci_i2c_remove(struct platform_device *pdev)
553 return 0; 553 return 0;
554} 554}
555 555
556/* work with hotplug and coldplug */
557MODULE_ALIAS("platform:i2c_davinci");
558
556static struct platform_driver davinci_i2c_driver = { 559static struct platform_driver davinci_i2c_driver = {
557 .probe = davinci_i2c_probe, 560 .probe = davinci_i2c_probe,
558 .remove = davinci_i2c_remove, 561 .remove = davinci_i2c_remove,
diff --git a/drivers/i2c/busses/i2c-gpio.c b/drivers/i2c/busses/i2c-gpio.c
index 3ca19fc234fb..7c1b762aa681 100644
--- a/drivers/i2c/busses/i2c-gpio.c
+++ b/drivers/i2c/busses/i2c-gpio.c
@@ -220,3 +220,4 @@ module_exit(i2c_gpio_exit);
220MODULE_AUTHOR("Haavard Skinnemoen <hskinnemoen@atmel.com>"); 220MODULE_AUTHOR("Haavard Skinnemoen <hskinnemoen@atmel.com>");
221MODULE_DESCRIPTION("Platform-independent bitbanging I2C driver"); 221MODULE_DESCRIPTION("Platform-independent bitbanging I2C driver");
222MODULE_LICENSE("GPL"); 222MODULE_LICENSE("GPL");
223MODULE_ALIAS("platform:i2c-gpio");
diff --git a/drivers/i2c/busses/i2c-ibm_iic.c b/drivers/i2c/busses/i2c-ibm_iic.c
index 22bb247d0e60..85dbf34382e1 100644
--- a/drivers/i2c/busses/i2c-ibm_iic.c
+++ b/drivers/i2c/busses/i2c-ibm_iic.c
@@ -6,6 +6,9 @@
6 * Copyright (c) 2003, 2004 Zultys Technologies. 6 * Copyright (c) 2003, 2004 Zultys Technologies.
7 * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net> 7 * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
8 * 8 *
9 * Copyright (c) 2008 PIKA Technologies
10 * Sean MacLennan <smaclennan@pikatech.com>
11 *
9 * Based on original work by 12 * Based on original work by
10 * Ian DaSilva <idasilva@mvista.com> 13 * Ian DaSilva <idasilva@mvista.com>
11 * Armin Kuster <akuster@mvista.com> 14 * Armin Kuster <akuster@mvista.com>
@@ -39,12 +42,17 @@
39#include <asm/io.h> 42#include <asm/io.h>
40#include <linux/i2c.h> 43#include <linux/i2c.h>
41#include <linux/i2c-id.h> 44#include <linux/i2c-id.h>
45
46#ifdef CONFIG_IBM_OCP
42#include <asm/ocp.h> 47#include <asm/ocp.h>
43#include <asm/ibm4xx.h> 48#include <asm/ibm4xx.h>
49#else
50#include <linux/of_platform.h>
51#endif
44 52
45#include "i2c-ibm_iic.h" 53#include "i2c-ibm_iic.h"
46 54
47#define DRIVER_VERSION "2.1" 55#define DRIVER_VERSION "2.2"
48 56
49MODULE_DESCRIPTION("IBM IIC driver v" DRIVER_VERSION); 57MODULE_DESCRIPTION("IBM IIC driver v" DRIVER_VERSION);
50MODULE_LICENSE("GPL"); 58MODULE_LICENSE("GPL");
@@ -650,13 +658,14 @@ static inline u8 iic_clckdiv(unsigned int opb)
650 opb /= 1000000; 658 opb /= 1000000;
651 659
652 if (opb < 20 || opb > 150){ 660 if (opb < 20 || opb > 150){
653 printk(KERN_CRIT "ibm-iic: invalid OPB clock frequency %u MHz\n", 661 printk(KERN_WARNING "ibm-iic: invalid OPB clock frequency %u MHz\n",
654 opb); 662 opb);
655 opb = opb < 20 ? 20 : 150; 663 opb = opb < 20 ? 20 : 150;
656 } 664 }
657 return (u8)((opb + 9) / 10 - 1); 665 return (u8)((opb + 9) / 10 - 1);
658} 666}
659 667
668#ifdef CONFIG_IBM_OCP
660/* 669/*
661 * Register single IIC interface 670 * Register single IIC interface
662 */ 671 */
@@ -672,7 +681,7 @@ static int __devinit iic_probe(struct ocp_device *ocp){
672 ocp->def->index); 681 ocp->def->index);
673 682
674 if (!(dev = kzalloc(sizeof(*dev), GFP_KERNEL))) { 683 if (!(dev = kzalloc(sizeof(*dev), GFP_KERNEL))) {
675 printk(KERN_CRIT "ibm-iic%d: failed to allocate device data\n", 684 printk(KERN_ERR "ibm-iic%d: failed to allocate device data\n",
676 ocp->def->index); 685 ocp->def->index);
677 return -ENOMEM; 686 return -ENOMEM;
678 } 687 }
@@ -687,7 +696,7 @@ static int __devinit iic_probe(struct ocp_device *ocp){
687 } 696 }
688 697
689 if (!(dev->vaddr = ioremap(ocp->def->paddr, sizeof(struct iic_regs)))){ 698 if (!(dev->vaddr = ioremap(ocp->def->paddr, sizeof(struct iic_regs)))){
690 printk(KERN_CRIT "ibm-iic%d: failed to ioremap device registers\n", 699 printk(KERN_ERR "ibm-iic%d: failed to ioremap device registers\n",
691 dev->idx); 700 dev->idx);
692 ret = -ENXIO; 701 ret = -ENXIO;
693 goto fail2; 702 goto fail2;
@@ -745,7 +754,7 @@ static int __devinit iic_probe(struct ocp_device *ocp){
745 adap->nr = dev->idx >= 0 ? dev->idx : 0; 754 adap->nr = dev->idx >= 0 ? dev->idx : 0;
746 755
747 if ((ret = i2c_add_numbered_adapter(adap)) < 0) { 756 if ((ret = i2c_add_numbered_adapter(adap)) < 0) {
748 printk(KERN_CRIT "ibm-iic%d: failed to register i2c adapter\n", 757 printk(KERN_ERR "ibm-iic%d: failed to register i2c adapter\n",
749 dev->idx); 758 dev->idx);
750 goto fail; 759 goto fail;
751 } 760 }
@@ -778,7 +787,7 @@ static void __devexit iic_remove(struct ocp_device *ocp)
778 struct ibm_iic_private* dev = (struct ibm_iic_private*)ocp_get_drvdata(ocp); 787 struct ibm_iic_private* dev = (struct ibm_iic_private*)ocp_get_drvdata(ocp);
779 BUG_ON(dev == NULL); 788 BUG_ON(dev == NULL);
780 if (i2c_del_adapter(&dev->adap)){ 789 if (i2c_del_adapter(&dev->adap)){
781 printk(KERN_CRIT "ibm-iic%d: failed to delete i2c adapter :(\n", 790 printk(KERN_ERR "ibm-iic%d: failed to delete i2c adapter :(\n",
782 dev->idx); 791 dev->idx);
783 /* That's *very* bad, just shutdown IRQ ... */ 792 /* That's *very* bad, just shutdown IRQ ... */
784 if (dev->irq >= 0){ 793 if (dev->irq >= 0){
@@ -828,5 +837,181 @@ static void __exit iic_exit(void)
828 ocp_unregister_driver(&ibm_iic_driver); 837 ocp_unregister_driver(&ibm_iic_driver);
829} 838}
830 839
840#else /* !CONFIG_IBM_OCP */
841
842static int __devinit iic_request_irq(struct of_device *ofdev,
843 struct ibm_iic_private *dev)
844{
845 struct device_node *np = ofdev->node;
846 int irq;
847
848 if (iic_force_poll)
849 return NO_IRQ;
850
851 irq = irq_of_parse_and_map(np, 0);
852 if (irq == NO_IRQ) {
853 dev_err(&ofdev->dev, "irq_of_parse_and_map failed\n");
854 return NO_IRQ;
855 }
856
857 /* Disable interrupts until we finish initialization, assumes
858 * level-sensitive IRQ setup...
859 */
860 iic_interrupt_mode(dev, 0);
861 if (request_irq(irq, iic_handler, 0, "IBM IIC", dev)) {
862 dev_err(&ofdev->dev, "request_irq %d failed\n", irq);
863 /* Fallback to the polling mode */
864 return NO_IRQ;
865 }
866
867 return irq;
868}
869
870/*
871 * Register single IIC interface
872 */
873static int __devinit iic_probe(struct of_device *ofdev,
874 const struct of_device_id *match)
875{
876 struct device_node *np = ofdev->node;
877 struct ibm_iic_private *dev;
878 struct i2c_adapter *adap;
879 const u32 *indexp, *freq;
880 int ret;
881
882 dev = kzalloc(sizeof(*dev), GFP_KERNEL);
883 if (!dev) {
884 dev_err(&ofdev->dev, "failed to allocate device data\n");
885 return -ENOMEM;
886 }
887
888 dev_set_drvdata(&ofdev->dev, dev);
889
890 indexp = of_get_property(np, "index", NULL);
891 if (!indexp) {
892 dev_err(&ofdev->dev, "no index specified\n");
893 ret = -EINVAL;
894 goto error_cleanup;
895 }
896 dev->idx = *indexp;
897
898 dev->vaddr = of_iomap(np, 0);
899 if (dev->vaddr == NULL) {
900 dev_err(&ofdev->dev, "failed to iomap device\n");
901 ret = -ENXIO;
902 goto error_cleanup;
903 }
904
905 init_waitqueue_head(&dev->wq);
906
907 dev->irq = iic_request_irq(ofdev, dev);
908 if (dev->irq == NO_IRQ)
909 dev_warn(&ofdev->dev, "using polling mode\n");
910
911 /* Board specific settings */
912 if (iic_force_fast || of_get_property(np, "fast-mode", NULL))
913 dev->fast_mode = 1;
914
915 freq = of_get_property(np, "clock-frequency", NULL);
916 if (freq == NULL) {
917 freq = of_get_property(np->parent, "clock-frequency", NULL);
918 if (freq == NULL) {
919 dev_err(&ofdev->dev, "Unable to get bus frequency\n");
920 ret = -EINVAL;
921 goto error_cleanup;
922 }
923 }
924
925 dev->clckdiv = iic_clckdiv(*freq);
926 dev_dbg(&ofdev->dev, "clckdiv = %d\n", dev->clckdiv);
927
928 /* Initialize IIC interface */
929 iic_dev_init(dev);
930
931 /* Register it with i2c layer */
932 adap = &dev->adap;
933 adap->dev.parent = &ofdev->dev;
934 strlcpy(adap->name, "IBM IIC", sizeof(adap->name));
935 i2c_set_adapdata(adap, dev);
936 adap->id = I2C_HW_OCP;
937 adap->class = I2C_CLASS_HWMON;
938 adap->algo = &iic_algo;
939 adap->timeout = 1;
940 adap->nr = dev->idx;
941
942 ret = i2c_add_numbered_adapter(adap);
943 if (ret < 0) {
944 dev_err(&ofdev->dev, "failed to register i2c adapter\n");
945 goto error_cleanup;
946 }
947
948 dev_info(&ofdev->dev, "using %s mode\n",
949 dev->fast_mode ? "fast (400 kHz)" : "standard (100 kHz)");
950
951 return 0;
952
953error_cleanup:
954 if (dev->irq != NO_IRQ) {
955 iic_interrupt_mode(dev, 0);
956 free_irq(dev->irq, dev);
957 }
958
959 if (dev->vaddr)
960 iounmap(dev->vaddr);
961
962 dev_set_drvdata(&ofdev->dev, NULL);
963 kfree(dev);
964 return ret;
965}
966
967/*
968 * Cleanup initialized IIC interface
969 */
970static int __devexit iic_remove(struct of_device *ofdev)
971{
972 struct ibm_iic_private *dev = dev_get_drvdata(&ofdev->dev);
973
974 dev_set_drvdata(&ofdev->dev, NULL);
975
976 i2c_del_adapter(&dev->adap);
977
978 if (dev->irq != NO_IRQ) {
979 iic_interrupt_mode(dev, 0);
980 free_irq(dev->irq, dev);
981 }
982
983 iounmap(dev->vaddr);
984 kfree(dev);
985
986 return 0;
987}
988
989static const struct of_device_id ibm_iic_match[] = {
990 { .compatible = "ibm,iic-405ex", },
991 { .compatible = "ibm,iic-405gp", },
992 { .compatible = "ibm,iic-440gp", },
993 { .compatible = "ibm,iic-440gpx", },
994 { .compatible = "ibm,iic-440grx", },
995 {}
996};
997
998static struct of_platform_driver ibm_iic_driver = {
999 .name = "ibm-iic",
1000 .match_table = ibm_iic_match,
1001 .probe = iic_probe,
1002 .remove = __devexit_p(iic_remove),
1003};
1004
1005static int __init iic_init(void)
1006{
1007 return of_register_platform_driver(&ibm_iic_driver);
1008}
1009
1010static void __exit iic_exit(void)
1011{
1012 of_unregister_platform_driver(&ibm_iic_driver);
1013}
1014#endif /* CONFIG_IBM_OCP */
1015
831module_init(iic_init); 1016module_init(iic_init);
832module_exit(iic_exit); 1017module_exit(iic_exit);
diff --git a/drivers/i2c/busses/i2c-iop3xx.c b/drivers/i2c/busses/i2c-iop3xx.c
index ab41400c883e..39884e797594 100644
--- a/drivers/i2c/busses/i2c-iop3xx.c
+++ b/drivers/i2c/busses/i2c-iop3xx.c
@@ -550,3 +550,4 @@ module_exit (i2c_iop3xx_exit);
550MODULE_AUTHOR("D-TACQ Solutions Ltd <www.d-tacq.com>"); 550MODULE_AUTHOR("D-TACQ Solutions Ltd <www.d-tacq.com>");
551MODULE_DESCRIPTION("IOP3xx iic algorithm and driver"); 551MODULE_DESCRIPTION("IOP3xx iic algorithm and driver");
552MODULE_LICENSE("GPL"); 552MODULE_LICENSE("GPL");
553MODULE_ALIAS("platform:IOP3xx-I2C");
diff --git a/drivers/i2c/busses/i2c-ixp2000.c b/drivers/i2c/busses/i2c-ixp2000.c
index 6352121a2827..5af9e6521e6c 100644
--- a/drivers/i2c/busses/i2c-ixp2000.c
+++ b/drivers/i2c/busses/i2c-ixp2000.c
@@ -164,4 +164,5 @@ module_exit(ixp2000_i2c_exit);
164MODULE_AUTHOR ("Deepak Saxena <dsaxena@plexity.net>"); 164MODULE_AUTHOR ("Deepak Saxena <dsaxena@plexity.net>");
165MODULE_DESCRIPTION("IXP2000 GPIO-based I2C bus driver"); 165MODULE_DESCRIPTION("IXP2000 GPIO-based I2C bus driver");
166MODULE_LICENSE("GPL"); 166MODULE_LICENSE("GPL");
167MODULE_ALIAS("platform:IXP2000-I2C");
167 168
diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c
index bbe787b243b7..18beb0ad7bf3 100644
--- a/drivers/i2c/busses/i2c-mpc.c
+++ b/drivers/i2c/busses/i2c-mpc.c
@@ -392,6 +392,9 @@ static int fsl_i2c_remove(struct platform_device *pdev)
392 return 0; 392 return 0;
393}; 393};
394 394
395/* work with hotplug and coldplug */
396MODULE_ALIAS("platform:fsl-i2c");
397
395/* Structure for a device driver */ 398/* Structure for a device driver */
396static struct platform_driver fsl_i2c_driver = { 399static struct platform_driver fsl_i2c_driver = {
397 .probe = fsl_i2c_probe, 400 .probe = fsl_i2c_probe,
diff --git a/drivers/i2c/busses/i2c-ocores.c b/drivers/i2c/busses/i2c-ocores.c
index e417c2c3ca22..f145692cbb76 100644
--- a/drivers/i2c/busses/i2c-ocores.c
+++ b/drivers/i2c/busses/i2c-ocores.c
@@ -312,6 +312,9 @@ static int __devexit ocores_i2c_remove(struct platform_device* pdev)
312 return 0; 312 return 0;
313} 313}
314 314
315/* work with hotplug and coldplug */
316MODULE_ALIAS("platform:ocores-i2c");
317
315static struct platform_driver ocores_i2c_driver = { 318static struct platform_driver ocores_i2c_driver = {
316 .probe = ocores_i2c_probe, 319 .probe = ocores_i2c_probe,
317 .remove = __devexit_p(ocores_i2c_remove), 320 .remove = __devexit_p(ocores_i2c_remove),
diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 7ba31770d773..e7eb7bf9ddec 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -693,3 +693,4 @@ module_exit(omap_i2c_exit_driver);
693MODULE_AUTHOR("MontaVista Software, Inc. (and others)"); 693MODULE_AUTHOR("MontaVista Software, Inc. (and others)");
694MODULE_DESCRIPTION("TI OMAP I2C bus adapter"); 694MODULE_DESCRIPTION("TI OMAP I2C bus adapter");
695MODULE_LICENSE("GPL"); 695MODULE_LICENSE("GPL");
696MODULE_ALIAS("platform:i2c_omap");
diff --git a/drivers/i2c/busses/i2c-pca-isa.c b/drivers/i2c/busses/i2c-pca-isa.c
index 496ee875eb4f..a119784bae10 100644
--- a/drivers/i2c/busses/i2c-pca-isa.c
+++ b/drivers/i2c/busses/i2c-pca-isa.c
@@ -1,6 +1,7 @@
1/* 1/*
2 * i2c-pca-isa.c driver for PCA9564 on ISA boards 2 * i2c-pca-isa.c driver for PCA9564 on ISA boards
3 * Copyright (C) 2004 Arcom Control Systems 3 * Copyright (C) 2004 Arcom Control Systems
4 * Copyright (C) 2008 Pengutronix
4 * 5 *
5 * This program is free software; you can redistribute it and/or modify 6 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by 7 * it under the terms of the GNU General Public License as published by
@@ -22,11 +23,9 @@
22#include <linux/module.h> 23#include <linux/module.h>
23#include <linux/moduleparam.h> 24#include <linux/moduleparam.h>
24#include <linux/delay.h> 25#include <linux/delay.h>
25#include <linux/slab.h>
26#include <linux/init.h> 26#include <linux/init.h>
27#include <linux/interrupt.h> 27#include <linux/interrupt.h>
28#include <linux/wait.h> 28#include <linux/wait.h>
29
30#include <linux/isa.h> 29#include <linux/isa.h>
31#include <linux/i2c.h> 30#include <linux/i2c.h>
32#include <linux/i2c-algo-pca.h> 31#include <linux/i2c-algo-pca.h>
@@ -34,13 +33,9 @@
34#include <asm/io.h> 33#include <asm/io.h>
35#include <asm/irq.h> 34#include <asm/irq.h>
36 35
37#include "../algos/i2c-algo-pca.h" 36#define DRIVER "i2c-pca-isa"
38
39#define IO_SIZE 4 37#define IO_SIZE 4
40 38
41#undef DEBUG_IO
42//#define DEBUG_IO
43
44static unsigned long base = 0x330; 39static unsigned long base = 0x330;
45static int irq = 10; 40static int irq = 10;
46 41
@@ -48,22 +43,9 @@ static int irq = 10;
48 * in the actual clock rate */ 43 * in the actual clock rate */
49static int clock = I2C_PCA_CON_59kHz; 44static int clock = I2C_PCA_CON_59kHz;
50 45
51static int own = 0x55;
52
53static wait_queue_head_t pca_wait; 46static wait_queue_head_t pca_wait;
54 47
55static int pca_isa_getown(struct i2c_algo_pca_data *adap) 48static void pca_isa_writebyte(void *pd, int reg, int val)
56{
57 return (own);
58}
59
60static int pca_isa_getclock(struct i2c_algo_pca_data *adap)
61{
62 return (clock);
63}
64
65static void
66pca_isa_writebyte(struct i2c_algo_pca_data *adap, int reg, int val)
67{ 49{
68#ifdef DEBUG_IO 50#ifdef DEBUG_IO
69 static char *names[] = { "T/O", "DAT", "ADR", "CON" }; 51 static char *names[] = { "T/O", "DAT", "ADR", "CON" };
@@ -72,44 +54,49 @@ pca_isa_writebyte(struct i2c_algo_pca_data *adap, int reg, int val)
72 outb(val, base+reg); 54 outb(val, base+reg);
73} 55}
74 56
75static int 57static int pca_isa_readbyte(void *pd, int reg)
76pca_isa_readbyte(struct i2c_algo_pca_data *adap, int reg)
77{ 58{
78 int res = inb(base+reg); 59 int res = inb(base+reg);
79#ifdef DEBUG_IO 60#ifdef DEBUG_IO
80 { 61 {
81 static char *names[] = { "STA", "DAT", "ADR", "CON" }; 62 static char *names[] = { "STA", "DAT", "ADR", "CON" };
82 printk("*** read %s => %#04x\n", names[reg], res); 63 printk("*** read %s => %#04x\n", names[reg], res);
83 } 64 }
84#endif 65#endif
85 return res; 66 return res;
86} 67}
87 68
88static int pca_isa_waitforinterrupt(struct i2c_algo_pca_data *adap) 69static int pca_isa_waitforcompletion(void *pd)
89{ 70{
90 int ret = 0; 71 int ret = 0;
91 72
92 if (irq > -1) { 73 if (irq > -1) {
93 ret = wait_event_interruptible(pca_wait, 74 ret = wait_event_interruptible(pca_wait,
94 pca_isa_readbyte(adap, I2C_PCA_CON) & I2C_PCA_CON_SI); 75 pca_isa_readbyte(pd, I2C_PCA_CON) & I2C_PCA_CON_SI);
95 } else { 76 } else {
96 while ((pca_isa_readbyte(adap, I2C_PCA_CON) & I2C_PCA_CON_SI) == 0) 77 while ((pca_isa_readbyte(pd, I2C_PCA_CON) & I2C_PCA_CON_SI) == 0)
97 udelay(100); 78 udelay(100);
98 } 79 }
99 return ret; 80 return ret;
100} 81}
101 82
83static void pca_isa_resetchip(void *pd)
84{
85 /* apparently only an external reset will do it. not a lot can be done */
86 printk(KERN_WARNING DRIVER ": Haven't figured out how to do a reset yet\n");
87}
88
102static irqreturn_t pca_handler(int this_irq, void *dev_id) { 89static irqreturn_t pca_handler(int this_irq, void *dev_id) {
103 wake_up_interruptible(&pca_wait); 90 wake_up_interruptible(&pca_wait);
104 return IRQ_HANDLED; 91 return IRQ_HANDLED;
105} 92}
106 93
107static struct i2c_algo_pca_data pca_isa_data = { 94static struct i2c_algo_pca_data pca_isa_data = {
108 .get_own = pca_isa_getown, 95 /* .data intentionally left NULL, not needed with ISA */
109 .get_clock = pca_isa_getclock,
110 .write_byte = pca_isa_writebyte, 96 .write_byte = pca_isa_writebyte,
111 .read_byte = pca_isa_readbyte, 97 .read_byte = pca_isa_readbyte,
112 .wait_for_interrupt = pca_isa_waitforinterrupt, 98 .wait_for_completion = pca_isa_waitforcompletion,
99 .reset_chip = pca_isa_resetchip,
113}; 100};
114 101
115static struct i2c_adapter pca_isa_ops = { 102static struct i2c_adapter pca_isa_ops = {
@@ -117,6 +104,7 @@ static struct i2c_adapter pca_isa_ops = {
117 .id = I2C_HW_A_ISA, 104 .id = I2C_HW_A_ISA,
118 .algo_data = &pca_isa_data, 105 .algo_data = &pca_isa_data,
119 .name = "PCA9564 ISA Adapter", 106 .name = "PCA9564 ISA Adapter",
107 .timeout = 100,
120}; 108};
121 109
122static int __devinit pca_isa_probe(struct device *dev, unsigned int id) 110static int __devinit pca_isa_probe(struct device *dev, unsigned int id)
@@ -144,6 +132,7 @@ static int __devinit pca_isa_probe(struct device *dev, unsigned int id)
144 } 132 }
145 } 133 }
146 134
135 pca_isa_data.i2c_clock = clock;
147 if (i2c_pca_add_bus(&pca_isa_ops) < 0) { 136 if (i2c_pca_add_bus(&pca_isa_ops) < 0) {
148 dev_err(dev, "Failed to add i2c bus\n"); 137 dev_err(dev, "Failed to add i2c bus\n");
149 goto out_irq; 138 goto out_irq;
@@ -178,7 +167,7 @@ static struct isa_driver pca_isa_driver = {
178 .remove = __devexit_p(pca_isa_remove), 167 .remove = __devexit_p(pca_isa_remove),
179 .driver = { 168 .driver = {
180 .owner = THIS_MODULE, 169 .owner = THIS_MODULE,
181 .name = "i2c-pca-isa", 170 .name = DRIVER,
182 } 171 }
183}; 172};
184 173
@@ -204,7 +193,5 @@ MODULE_PARM_DESC(irq, "IRQ");
204module_param(clock, int, 0); 193module_param(clock, int, 0);
205MODULE_PARM_DESC(clock, "Clock rate as described in table 1 of PCA9564 datasheet"); 194MODULE_PARM_DESC(clock, "Clock rate as described in table 1 of PCA9564 datasheet");
206 195
207module_param(own, int, 0); /* the driver can't do slave mode, so there's no real point in this */
208
209module_init(pca_isa_init); 196module_init(pca_isa_init);
210module_exit(pca_isa_exit); 197module_exit(pca_isa_exit);
diff --git a/drivers/i2c/busses/i2c-pca-platform.c b/drivers/i2c/busses/i2c-pca-platform.c
new file mode 100644
index 000000000000..9d75f51e8f0e
--- /dev/null
+++ b/drivers/i2c/busses/i2c-pca-platform.c
@@ -0,0 +1,298 @@
1/*
2 * i2c_pca_platform.c
3 *
4 * Platform driver for the PCA9564 I2C controller.
5 *
6 * Copyright (C) 2008 Pengutronix
7 *
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
10 * published by the Free Software Foundation.
11
12 */
13#include <linux/kernel.h>
14#include <linux/module.h>
15#include <linux/init.h>
16#include <linux/slab.h>
17#include <linux/delay.h>
18#include <linux/errno.h>
19#include <linux/i2c.h>
20#include <linux/interrupt.h>
21#include <linux/platform_device.h>
22#include <linux/i2c-algo-pca.h>
23#include <linux/i2c-pca-platform.h>
24#include <linux/gpio.h>
25
26#include <asm/irq.h>
27#include <asm/io.h>
28
29#define res_len(r) ((r)->end - (r)->start + 1)
30
31struct i2c_pca_pf_data {
32 void __iomem *reg_base;
33 int irq; /* if 0, use polling */
34 int gpio;
35 wait_queue_head_t wait;
36 struct i2c_adapter adap;
37 struct i2c_algo_pca_data algo_data;
38 unsigned long io_base;
39 unsigned long io_size;
40};
41
42/* Read/Write functions for different register alignments */
43
44static int i2c_pca_pf_readbyte8(void *pd, int reg)
45{
46 struct i2c_pca_pf_data *i2c = pd;
47 return ioread8(i2c->reg_base + reg);
48}
49
50static int i2c_pca_pf_readbyte16(void *pd, int reg)
51{
52 struct i2c_pca_pf_data *i2c = pd;
53 return ioread8(i2c->reg_base + reg * 2);
54}
55
56static int i2c_pca_pf_readbyte32(void *pd, int reg)
57{
58 struct i2c_pca_pf_data *i2c = pd;
59 return ioread8(i2c->reg_base + reg * 4);
60}
61
62static void i2c_pca_pf_writebyte8(void *pd, int reg, int val)
63{
64 struct i2c_pca_pf_data *i2c = pd;
65 iowrite8(val, i2c->reg_base + reg);
66}
67
68static void i2c_pca_pf_writebyte16(void *pd, int reg, int val)
69{
70 struct i2c_pca_pf_data *i2c = pd;
71 iowrite8(val, i2c->reg_base + reg * 2);
72}
73
74static void i2c_pca_pf_writebyte32(void *pd, int reg, int val)
75{
76 struct i2c_pca_pf_data *i2c = pd;
77 iowrite8(val, i2c->reg_base + reg * 4);
78}
79
80
81static int i2c_pca_pf_waitforcompletion(void *pd)
82{
83 struct i2c_pca_pf_data *i2c = pd;
84 int ret = 0;
85
86 if (i2c->irq) {
87 ret = wait_event_interruptible(i2c->wait,
88 i2c->algo_data.read_byte(i2c, I2C_PCA_CON)
89 & I2C_PCA_CON_SI);
90 } else {
91 /*
92 * Do polling...
93 * XXX: Could get stuck in extreme cases!
94 * Maybe add timeout, but using irqs is preferred anyhow.
95 */
96 while ((i2c->algo_data.read_byte(i2c, I2C_PCA_CON)
97 & I2C_PCA_CON_SI) == 0)
98 udelay(100);
99 }
100
101 return ret;
102}
103
104static void i2c_pca_pf_dummyreset(void *pd)
105{
106 struct i2c_pca_pf_data *i2c = pd;
107 printk(KERN_WARNING "%s: No reset-pin found. Chip may get stuck!\n",
108 i2c->adap.name);
109}
110
111static void i2c_pca_pf_resetchip(void *pd)
112{
113 struct i2c_pca_pf_data *i2c = pd;
114
115 gpio_set_value(i2c->gpio, 0);
116 ndelay(100);
117 gpio_set_value(i2c->gpio, 1);
118}
119
120static irqreturn_t i2c_pca_pf_handler(int this_irq, void *dev_id)
121{
122 struct i2c_pca_pf_data *i2c = dev_id;
123
124 if ((i2c->algo_data.read_byte(i2c, I2C_PCA_CON) & I2C_PCA_CON_SI) == 0)
125 return IRQ_NONE;
126
127 wake_up_interruptible(&i2c->wait);
128
129 return IRQ_HANDLED;
130}
131
132
133static int __devinit i2c_pca_pf_probe(struct platform_device *pdev)
134{
135 struct i2c_pca_pf_data *i2c;
136 struct resource *res;
137 struct i2c_pca9564_pf_platform_data *platform_data =
138 pdev->dev.platform_data;
139 int ret = 0;
140 int irq;
141
142 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
143 irq = platform_get_irq(pdev, 0);
144 /* If irq is 0, we do polling. */
145
146 if (res == NULL) {
147 ret = -ENODEV;
148 goto e_print;
149 }
150
151 if (!request_mem_region(res->start, res_len(res), res->name)) {
152 ret = -ENOMEM;
153 goto e_print;
154 }
155
156 i2c = kzalloc(sizeof(struct i2c_pca_pf_data), GFP_KERNEL);
157 if (!i2c) {
158 ret = -ENOMEM;
159 goto e_alloc;
160 }
161
162 init_waitqueue_head(&i2c->wait);
163
164 i2c->reg_base = ioremap(res->start, res_len(res));
165 if (!i2c->reg_base) {
166 ret = -EIO;
167 goto e_remap;
168 }
169 i2c->io_base = res->start;
170 i2c->io_size = res_len(res);
171 i2c->irq = irq;
172
173 i2c->adap.nr = pdev->id >= 0 ? pdev->id : 0;
174 i2c->adap.owner = THIS_MODULE;
175 snprintf(i2c->adap.name, sizeof(i2c->adap.name), "PCA9564 at 0x%08lx",
176 (unsigned long) res->start);
177 i2c->adap.algo_data = &i2c->algo_data;
178 i2c->adap.dev.parent = &pdev->dev;
179 i2c->adap.timeout = platform_data->timeout;
180
181 i2c->algo_data.i2c_clock = platform_data->i2c_clock_speed;
182 i2c->algo_data.data = i2c;
183
184 switch (res->flags & IORESOURCE_MEM_TYPE_MASK) {
185 case IORESOURCE_MEM_32BIT:
186 i2c->algo_data.write_byte = i2c_pca_pf_writebyte32;
187 i2c->algo_data.read_byte = i2c_pca_pf_readbyte32;
188 break;
189 case IORESOURCE_MEM_16BIT:
190 i2c->algo_data.write_byte = i2c_pca_pf_writebyte16;
191 i2c->algo_data.read_byte = i2c_pca_pf_readbyte16;
192 break;
193 case IORESOURCE_MEM_8BIT:
194 default:
195 i2c->algo_data.write_byte = i2c_pca_pf_writebyte8;
196 i2c->algo_data.read_byte = i2c_pca_pf_readbyte8;
197 break;
198 }
199
200 i2c->algo_data.wait_for_completion = i2c_pca_pf_waitforcompletion;
201
202 i2c->gpio = platform_data->gpio;
203 i2c->algo_data.reset_chip = i2c_pca_pf_dummyreset;
204
205 /* Use gpio_is_valid() when in mainline */
206 if (i2c->gpio > -1) {
207 ret = gpio_request(i2c->gpio, i2c->adap.name);
208 if (ret == 0) {
209 gpio_direction_output(i2c->gpio, 1);
210 i2c->algo_data.reset_chip = i2c_pca_pf_resetchip;
211 } else {
212 printk(KERN_WARNING "%s: Registering gpio failed!\n",
213 i2c->adap.name);
214 i2c->gpio = ret;
215 }
216 }
217
218 if (irq) {
219 ret = request_irq(irq, i2c_pca_pf_handler,
220 IRQF_TRIGGER_FALLING, i2c->adap.name, i2c);
221 if (ret)
222 goto e_reqirq;
223 }
224
225 if (i2c_pca_add_numbered_bus(&i2c->adap) < 0) {
226 ret = -ENODEV;
227 goto e_adapt;
228 }
229
230 platform_set_drvdata(pdev, i2c);
231
232 printk(KERN_INFO "%s registered.\n", i2c->adap.name);
233
234 return 0;
235
236e_adapt:
237 if (irq)
238 free_irq(irq, i2c);
239e_reqirq:
240 if (i2c->gpio > -1)
241 gpio_free(i2c->gpio);
242
243 iounmap(i2c->reg_base);
244e_remap:
245 kfree(i2c);
246e_alloc:
247 release_mem_region(res->start, res_len(res));
248e_print:
249 printk(KERN_ERR "Registering PCA9564 FAILED! (%d)\n", ret);
250 return ret;
251}
252
253static int __devexit i2c_pca_pf_remove(struct platform_device *pdev)
254{
255 struct i2c_pca_pf_data *i2c = platform_get_drvdata(pdev);
256 platform_set_drvdata(pdev, NULL);
257
258 i2c_del_adapter(&i2c->adap);
259
260 if (i2c->irq)
261 free_irq(i2c->irq, i2c);
262
263 if (i2c->gpio > -1)
264 gpio_free(i2c->gpio);
265
266 iounmap(i2c->reg_base);
267 release_mem_region(i2c->io_base, i2c->io_size);
268 kfree(i2c);
269
270 return 0;
271}
272
273static struct platform_driver i2c_pca_pf_driver = {
274 .probe = i2c_pca_pf_probe,
275 .remove = __devexit_p(i2c_pca_pf_remove),
276 .driver = {
277 .name = "i2c-pca-platform",
278 .owner = THIS_MODULE,
279 },
280};
281
282static int __init i2c_pca_pf_init(void)
283{
284 return platform_driver_register(&i2c_pca_pf_driver);
285}
286
287static void __exit i2c_pca_pf_exit(void)
288{
289 platform_driver_unregister(&i2c_pca_pf_driver);
290}
291
292MODULE_AUTHOR("Wolfram Sang <w.sang@pengutronix.de>");
293MODULE_DESCRIPTION("I2C-PCA9564 platform driver");
294MODULE_LICENSE("GPL");
295
296module_init(i2c_pca_pf_init);
297module_exit(i2c_pca_pf_exit);
298
diff --git a/drivers/i2c/busses/i2c-pmcmsp.c b/drivers/i2c/busses/i2c-pmcmsp.c
index b03af5653c65..63b3e2c11cff 100644
--- a/drivers/i2c/busses/i2c-pmcmsp.c
+++ b/drivers/i2c/busses/i2c-pmcmsp.c
@@ -467,7 +467,7 @@ static enum pmcmsptwi_xfer_result pmcmsptwi_xfer_cmd(
467 (cmd->read_len == 0 || cmd->write_len == 0))) { 467 (cmd->read_len == 0 || cmd->write_len == 0))) {
468 dev_err(&pmcmsptwi_adapter.dev, 468 dev_err(&pmcmsptwi_adapter.dev,
469 "%s: Cannot transfer less than 1 byte\n", 469 "%s: Cannot transfer less than 1 byte\n",
470 __FUNCTION__); 470 __func__);
471 return -EINVAL; 471 return -EINVAL;
472 } 472 }
473 473
@@ -475,7 +475,7 @@ static enum pmcmsptwi_xfer_result pmcmsptwi_xfer_cmd(
475 cmd->write_len > MSP_MAX_BYTES_PER_RW) { 475 cmd->write_len > MSP_MAX_BYTES_PER_RW) {
476 dev_err(&pmcmsptwi_adapter.dev, 476 dev_err(&pmcmsptwi_adapter.dev,
477 "%s: Cannot transfer more than %d bytes\n", 477 "%s: Cannot transfer more than %d bytes\n",
478 __FUNCTION__, MSP_MAX_BYTES_PER_RW); 478 __func__, MSP_MAX_BYTES_PER_RW);
479 return -EINVAL; 479 return -EINVAL;
480 } 480 }
481 481
@@ -627,6 +627,9 @@ static struct i2c_adapter pmcmsptwi_adapter = {
627 .name = DRV_NAME, 627 .name = DRV_NAME,
628}; 628};
629 629
630/* work with hotplug and coldplug */
631MODULE_ALIAS("platform:" DRV_NAME);
632
630static struct platform_driver pmcmsptwi_driver = { 633static struct platform_driver pmcmsptwi_driver = {
631 .probe = pmcmsptwi_probe, 634 .probe = pmcmsptwi_probe,
632 .remove = __devexit_p(pmcmsptwi_remove), 635 .remove = __devexit_p(pmcmsptwi_remove),
diff --git a/drivers/i2c/busses/i2c-pnx.c b/drivers/i2c/busses/i2c-pnx.c
index f8d0dff0de7e..1ca21084ffcf 100644
--- a/drivers/i2c/busses/i2c-pnx.c
+++ b/drivers/i2c/busses/i2c-pnx.c
@@ -76,7 +76,7 @@ static int i2c_pnx_start(unsigned char slave_addr, struct i2c_adapter *adap)
76{ 76{
77 struct i2c_pnx_algo_data *alg_data = adap->algo_data; 77 struct i2c_pnx_algo_data *alg_data = adap->algo_data;
78 78
79 dev_dbg(&adap->dev, "%s(): addr 0x%x mode %d\n", __FUNCTION__, 79 dev_dbg(&adap->dev, "%s(): addr 0x%x mode %d\n", __func__,
80 slave_addr, alg_data->mif.mode); 80 slave_addr, alg_data->mif.mode);
81 81
82 /* Check for 7 bit slave addresses only */ 82 /* Check for 7 bit slave addresses only */
@@ -110,14 +110,14 @@ static int i2c_pnx_start(unsigned char slave_addr, struct i2c_adapter *adap)
110 iowrite32(ioread32(I2C_REG_STS(alg_data)) | mstatus_tdi | mstatus_afi, 110 iowrite32(ioread32(I2C_REG_STS(alg_data)) | mstatus_tdi | mstatus_afi,
111 I2C_REG_STS(alg_data)); 111 I2C_REG_STS(alg_data));
112 112
113 dev_dbg(&adap->dev, "%s(): sending %#x\n", __FUNCTION__, 113 dev_dbg(&adap->dev, "%s(): sending %#x\n", __func__,
114 (slave_addr << 1) | start_bit | alg_data->mif.mode); 114 (slave_addr << 1) | start_bit | alg_data->mif.mode);
115 115
116 /* Write the slave address, START bit and R/W bit */ 116 /* Write the slave address, START bit and R/W bit */
117 iowrite32((slave_addr << 1) | start_bit | alg_data->mif.mode, 117 iowrite32((slave_addr << 1) | start_bit | alg_data->mif.mode,
118 I2C_REG_TX(alg_data)); 118 I2C_REG_TX(alg_data));
119 119
120 dev_dbg(&adap->dev, "%s(): exit\n", __FUNCTION__); 120 dev_dbg(&adap->dev, "%s(): exit\n", __func__);
121 121
122 return 0; 122 return 0;
123} 123}
@@ -135,7 +135,7 @@ static void i2c_pnx_stop(struct i2c_adapter *adap)
135 long timeout = 1000; 135 long timeout = 1000;
136 136
137 dev_dbg(&adap->dev, "%s(): entering: stat = %04x.\n", 137 dev_dbg(&adap->dev, "%s(): entering: stat = %04x.\n",
138 __FUNCTION__, ioread32(I2C_REG_STS(alg_data))); 138 __func__, ioread32(I2C_REG_STS(alg_data)));
139 139
140 /* Write a STOP bit to TX FIFO */ 140 /* Write a STOP bit to TX FIFO */
141 iowrite32(0xff | stop_bit, I2C_REG_TX(alg_data)); 141 iowrite32(0xff | stop_bit, I2C_REG_TX(alg_data));
@@ -149,7 +149,7 @@ static void i2c_pnx_stop(struct i2c_adapter *adap)
149 } 149 }
150 150
151 dev_dbg(&adap->dev, "%s(): exiting: stat = %04x.\n", 151 dev_dbg(&adap->dev, "%s(): exiting: stat = %04x.\n",
152 __FUNCTION__, ioread32(I2C_REG_STS(alg_data))); 152 __func__, ioread32(I2C_REG_STS(alg_data)));
153} 153}
154 154
155/** 155/**
@@ -164,7 +164,7 @@ static int i2c_pnx_master_xmit(struct i2c_adapter *adap)
164 u32 val; 164 u32 val;
165 165
166 dev_dbg(&adap->dev, "%s(): entering: stat = %04x.\n", 166 dev_dbg(&adap->dev, "%s(): entering: stat = %04x.\n",
167 __FUNCTION__, ioread32(I2C_REG_STS(alg_data))); 167 __func__, ioread32(I2C_REG_STS(alg_data)));
168 168
169 if (alg_data->mif.len > 0) { 169 if (alg_data->mif.len > 0) {
170 /* We still have something to talk about... */ 170 /* We still have something to talk about... */
@@ -179,7 +179,7 @@ static int i2c_pnx_master_xmit(struct i2c_adapter *adap)
179 alg_data->mif.len--; 179 alg_data->mif.len--;
180 iowrite32(val, I2C_REG_TX(alg_data)); 180 iowrite32(val, I2C_REG_TX(alg_data));
181 181
182 dev_dbg(&adap->dev, "%s(): xmit %#x [%d]\n", __FUNCTION__, 182 dev_dbg(&adap->dev, "%s(): xmit %#x [%d]\n", __func__,
183 val, alg_data->mif.len + 1); 183 val, alg_data->mif.len + 1);
184 184
185 if (alg_data->mif.len == 0) { 185 if (alg_data->mif.len == 0) {
@@ -197,7 +197,7 @@ static int i2c_pnx_master_xmit(struct i2c_adapter *adap)
197 del_timer_sync(&alg_data->mif.timer); 197 del_timer_sync(&alg_data->mif.timer);
198 198
199 dev_dbg(&adap->dev, "%s(): Waking up xfer routine.\n", 199 dev_dbg(&adap->dev, "%s(): Waking up xfer routine.\n",
200 __FUNCTION__); 200 __func__);
201 201
202 complete(&alg_data->mif.complete); 202 complete(&alg_data->mif.complete);
203 } 203 }
@@ -213,13 +213,13 @@ static int i2c_pnx_master_xmit(struct i2c_adapter *adap)
213 /* Stop timer. */ 213 /* Stop timer. */
214 del_timer_sync(&alg_data->mif.timer); 214 del_timer_sync(&alg_data->mif.timer);
215 dev_dbg(&adap->dev, "%s(): Waking up xfer routine after " 215 dev_dbg(&adap->dev, "%s(): Waking up xfer routine after "
216 "zero-xfer.\n", __FUNCTION__); 216 "zero-xfer.\n", __func__);
217 217
218 complete(&alg_data->mif.complete); 218 complete(&alg_data->mif.complete);
219 } 219 }
220 220
221 dev_dbg(&adap->dev, "%s(): exiting: stat = %04x.\n", 221 dev_dbg(&adap->dev, "%s(): exiting: stat = %04x.\n",
222 __FUNCTION__, ioread32(I2C_REG_STS(alg_data))); 222 __func__, ioread32(I2C_REG_STS(alg_data)));
223 223
224 return 0; 224 return 0;
225} 225}
@@ -237,14 +237,14 @@ static int i2c_pnx_master_rcv(struct i2c_adapter *adap)
237 u32 ctl = 0; 237 u32 ctl = 0;
238 238
239 dev_dbg(&adap->dev, "%s(): entering: stat = %04x.\n", 239 dev_dbg(&adap->dev, "%s(): entering: stat = %04x.\n",
240 __FUNCTION__, ioread32(I2C_REG_STS(alg_data))); 240 __func__, ioread32(I2C_REG_STS(alg_data)));
241 241
242 /* Check, whether there is already data, 242 /* Check, whether there is already data,
243 * or we didn't 'ask' for it yet. 243 * or we didn't 'ask' for it yet.
244 */ 244 */
245 if (ioread32(I2C_REG_STS(alg_data)) & mstatus_rfe) { 245 if (ioread32(I2C_REG_STS(alg_data)) & mstatus_rfe) {
246 dev_dbg(&adap->dev, "%s(): Write dummy data to fill " 246 dev_dbg(&adap->dev, "%s(): Write dummy data to fill "
247 "Rx-fifo...\n", __FUNCTION__); 247 "Rx-fifo...\n", __func__);
248 248
249 if (alg_data->mif.len == 1) { 249 if (alg_data->mif.len == 1) {
250 /* Last byte, do not acknowledge next rcv. */ 250 /* Last byte, do not acknowledge next rcv. */
@@ -276,7 +276,7 @@ static int i2c_pnx_master_rcv(struct i2c_adapter *adap)
276 if (alg_data->mif.len > 0) { 276 if (alg_data->mif.len > 0) {
277 val = ioread32(I2C_REG_RX(alg_data)); 277 val = ioread32(I2C_REG_RX(alg_data));
278 *alg_data->mif.buf++ = (u8) (val & 0xff); 278 *alg_data->mif.buf++ = (u8) (val & 0xff);
279 dev_dbg(&adap->dev, "%s(): rcv 0x%x [%d]\n", __FUNCTION__, val, 279 dev_dbg(&adap->dev, "%s(): rcv 0x%x [%d]\n", __func__, val,
280 alg_data->mif.len); 280 alg_data->mif.len);
281 281
282 alg_data->mif.len--; 282 alg_data->mif.len--;
@@ -300,7 +300,7 @@ static int i2c_pnx_master_rcv(struct i2c_adapter *adap)
300 } 300 }
301 301
302 dev_dbg(&adap->dev, "%s(): exiting: stat = %04x.\n", 302 dev_dbg(&adap->dev, "%s(): exiting: stat = %04x.\n",
303 __FUNCTION__, ioread32(I2C_REG_STS(alg_data))); 303 __func__, ioread32(I2C_REG_STS(alg_data)));
304 304
305 return 0; 305 return 0;
306} 306}
@@ -312,7 +312,7 @@ static irqreturn_t i2c_pnx_interrupt(int irq, void *dev_id)
312 struct i2c_pnx_algo_data *alg_data = adap->algo_data; 312 struct i2c_pnx_algo_data *alg_data = adap->algo_data;
313 313
314 dev_dbg(&adap->dev, "%s(): mstat = %x mctrl = %x, mode = %d\n", 314 dev_dbg(&adap->dev, "%s(): mstat = %x mctrl = %x, mode = %d\n",
315 __FUNCTION__, 315 __func__,
316 ioread32(I2C_REG_STS(alg_data)), 316 ioread32(I2C_REG_STS(alg_data)),
317 ioread32(I2C_REG_CTL(alg_data)), 317 ioread32(I2C_REG_CTL(alg_data)),
318 alg_data->mif.mode); 318 alg_data->mif.mode);
@@ -336,7 +336,7 @@ static irqreturn_t i2c_pnx_interrupt(int irq, void *dev_id)
336 /* Slave did not acknowledge, generate a STOP */ 336 /* Slave did not acknowledge, generate a STOP */
337 dev_dbg(&adap->dev, "%s(): " 337 dev_dbg(&adap->dev, "%s(): "
338 "Slave did not acknowledge, generating a STOP.\n", 338 "Slave did not acknowledge, generating a STOP.\n",
339 __FUNCTION__); 339 __func__);
340 i2c_pnx_stop(adap); 340 i2c_pnx_stop(adap);
341 341
342 /* Disable master interrupts. */ 342 /* Disable master interrupts. */
@@ -375,7 +375,7 @@ static irqreturn_t i2c_pnx_interrupt(int irq, void *dev_id)
375 iowrite32(stat | mstatus_tdi | mstatus_afi, I2C_REG_STS(alg_data)); 375 iowrite32(stat | mstatus_tdi | mstatus_afi, I2C_REG_STS(alg_data));
376 376
377 dev_dbg(&adap->dev, "%s(): exiting, stat = %x ctrl = %x.\n", 377 dev_dbg(&adap->dev, "%s(): exiting, stat = %x ctrl = %x.\n",
378 __FUNCTION__, ioread32(I2C_REG_STS(alg_data)), 378 __func__, ioread32(I2C_REG_STS(alg_data)),
379 ioread32(I2C_REG_CTL(alg_data))); 379 ioread32(I2C_REG_CTL(alg_data)));
380 380
381 return IRQ_HANDLED; 381 return IRQ_HANDLED;
@@ -447,7 +447,7 @@ i2c_pnx_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
447 u32 stat = ioread32(I2C_REG_STS(alg_data)); 447 u32 stat = ioread32(I2C_REG_STS(alg_data));
448 448
449 dev_dbg(&adap->dev, "%s(): entering: %d messages, stat = %04x.\n", 449 dev_dbg(&adap->dev, "%s(): entering: %d messages, stat = %04x.\n",
450 __FUNCTION__, num, ioread32(I2C_REG_STS(alg_data))); 450 __func__, num, ioread32(I2C_REG_STS(alg_data)));
451 451
452 bus_reset_if_active(adap); 452 bus_reset_if_active(adap);
453 453
@@ -473,7 +473,7 @@ i2c_pnx_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
473 alg_data->mif.ret = 0; 473 alg_data->mif.ret = 0;
474 alg_data->last = (i == num - 1); 474 alg_data->last = (i == num - 1);
475 475
476 dev_dbg(&adap->dev, "%s(): mode %d, %d bytes\n", __FUNCTION__, 476 dev_dbg(&adap->dev, "%s(): mode %d, %d bytes\n", __func__,
477 alg_data->mif.mode, 477 alg_data->mif.mode,
478 alg_data->mif.len); 478 alg_data->mif.len);
479 479
@@ -498,7 +498,7 @@ i2c_pnx_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
498 if (!(rc = alg_data->mif.ret)) 498 if (!(rc = alg_data->mif.ret))
499 completed++; 499 completed++;
500 dev_dbg(&adap->dev, "%s(): Complete, return code = %d.\n", 500 dev_dbg(&adap->dev, "%s(): Complete, return code = %d.\n",
501 __FUNCTION__, rc); 501 __func__, rc);
502 502
503 /* Clear TDI and AFI bits in case they are set. */ 503 /* Clear TDI and AFI bits in case they are set. */
504 if ((stat = ioread32(I2C_REG_STS(alg_data))) & mstatus_tdi) { 504 if ((stat = ioread32(I2C_REG_STS(alg_data))) & mstatus_tdi) {
@@ -522,7 +522,7 @@ i2c_pnx_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
522 alg_data->mif.len = 0; 522 alg_data->mif.len = 0;
523 523
524 dev_dbg(&adap->dev, "%s(): exiting, stat = %x\n", 524 dev_dbg(&adap->dev, "%s(): exiting, stat = %x\n",
525 __FUNCTION__, ioread32(I2C_REG_STS(alg_data))); 525 __func__, ioread32(I2C_REG_STS(alg_data)));
526 526
527 if (completed != num) 527 if (completed != num)
528 return ((rc < 0) ? rc : -EREMOTEIO); 528 return ((rc < 0) ? rc : -EREMOTEIO);
@@ -563,7 +563,7 @@ static int __devinit i2c_pnx_probe(struct platform_device *pdev)
563 563
564 if (!i2c_pnx || !i2c_pnx->adapter) { 564 if (!i2c_pnx || !i2c_pnx->adapter) {
565 dev_err(&pdev->dev, "%s: no platform data supplied\n", 565 dev_err(&pdev->dev, "%s: no platform data supplied\n",
566 __FUNCTION__); 566 __func__);
567 ret = -EINVAL; 567 ret = -EINVAL;
568 goto out; 568 goto out;
569 } 569 }
@@ -697,6 +697,7 @@ static void __exit i2c_adap_pnx_exit(void)
697MODULE_AUTHOR("Vitaly Wool, Dennis Kovalev <source@mvista.com>"); 697MODULE_AUTHOR("Vitaly Wool, Dennis Kovalev <source@mvista.com>");
698MODULE_DESCRIPTION("I2C driver for Philips IP3204-based I2C busses"); 698MODULE_DESCRIPTION("I2C driver for Philips IP3204-based I2C busses");
699MODULE_LICENSE("GPL"); 699MODULE_LICENSE("GPL");
700MODULE_ALIAS("platform:pnx-i2c");
700 701
701/* We need to make sure I2C is initialized before USB */ 702/* We need to make sure I2C is initialized before USB */
702subsys_initcall(i2c_adap_pnx_init); 703subsys_initcall(i2c_adap_pnx_init);
diff --git a/drivers/i2c/busses/i2c-powermac.c b/drivers/i2c/busses/i2c-powermac.c
index 7813127649a1..22f6d5c00d80 100644
--- a/drivers/i2c/busses/i2c-powermac.c
+++ b/drivers/i2c/busses/i2c-powermac.c
@@ -263,6 +263,9 @@ static int __devexit i2c_powermac_probe(struct platform_device *dev)
263} 263}
264 264
265 265
266/* work with hotplug and coldplug */
267MODULE_ALIAS("platform:i2c-powermac");
268
266static struct platform_driver i2c_powermac_driver = { 269static struct platform_driver i2c_powermac_driver = {
267 .probe = i2c_powermac_probe, 270 .probe = i2c_powermac_probe,
268 .remove = __devexit_p(i2c_powermac_remove), 271 .remove = __devexit_p(i2c_powermac_remove),
diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c
index 6fd2d6a84eff..eb69fbadc9cb 100644
--- a/drivers/i2c/busses/i2c-pxa.c
+++ b/drivers/i2c/busses/i2c-pxa.c
@@ -155,7 +155,7 @@ static void i2c_pxa_show_state(struct pxa_i2c *i2c, int lno, const char *fname)
155 readl(_ISR(i2c)), readl(_ICR(i2c)), readl(_IBMR(i2c))); 155 readl(_ISR(i2c)), readl(_ICR(i2c)), readl(_IBMR(i2c)));
156} 156}
157 157
158#define show_state(i2c) i2c_pxa_show_state(i2c, __LINE__, __FUNCTION__) 158#define show_state(i2c) i2c_pxa_show_state(i2c, __LINE__, __func__)
159#else 159#else
160#define i2c_debug 0 160#define i2c_debug 0
161 161
@@ -1132,6 +1132,7 @@ static void __exit i2c_adap_pxa_exit(void)
1132} 1132}
1133 1133
1134MODULE_LICENSE("GPL"); 1134MODULE_LICENSE("GPL");
1135MODULE_ALIAS("platform:pxa2xx-i2c");
1135 1136
1136module_init(i2c_adap_pxa_init); 1137module_init(i2c_adap_pxa_init);
1137module_exit(i2c_adap_pxa_exit); 1138module_exit(i2c_adap_pxa_exit);
diff --git a/drivers/i2c/busses/i2c-s3c2410.c b/drivers/i2c/busses/i2c-s3c2410.c
index c44ada5f4292..1305ef190fc1 100644
--- a/drivers/i2c/busses/i2c-s3c2410.c
+++ b/drivers/i2c/busses/i2c-s3c2410.c
@@ -276,12 +276,12 @@ static int i2s_s3c_irq_nextbyte(struct s3c24xx_i2c *i2c, unsigned long iicstat)
276 switch (i2c->state) { 276 switch (i2c->state) {
277 277
278 case STATE_IDLE: 278 case STATE_IDLE:
279 dev_err(i2c->dev, "%s: called in STATE_IDLE\n", __FUNCTION__); 279 dev_err(i2c->dev, "%s: called in STATE_IDLE\n", __func__);
280 goto out; 280 goto out;
281 break; 281 break;
282 282
283 case STATE_STOP: 283 case STATE_STOP:
284 dev_err(i2c->dev, "%s: called in STATE_STOP\n", __FUNCTION__); 284 dev_err(i2c->dev, "%s: called in STATE_STOP\n", __func__);
285 s3c24xx_i2c_disable_irq(i2c); 285 s3c24xx_i2c_disable_irq(i2c);
286 goto out_ack; 286 goto out_ack;
287 287
@@ -948,3 +948,4 @@ module_exit(i2c_adap_s3c_exit);
948MODULE_DESCRIPTION("S3C24XX I2C Bus driver"); 948MODULE_DESCRIPTION("S3C24XX I2C Bus driver");
949MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>"); 949MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>");
950MODULE_LICENSE("GPL"); 950MODULE_LICENSE("GPL");
951MODULE_ALIAS("platform:s3c2410-i2c");
diff --git a/drivers/i2c/busses/i2c-sh7760.c b/drivers/i2c/busses/i2c-sh7760.c
new file mode 100644
index 000000000000..5e0e254976de
--- /dev/null
+++ b/drivers/i2c/busses/i2c-sh7760.c
@@ -0,0 +1,577 @@
1/*
2 * I2C bus driver for the SH7760 I2C Interfaces.
3 *
4 * (c) 2005-2008 MSC Vertriebsges.m.b.H, Manuel Lauss <mlau@msc-ge.com>
5 *
6 * licensed under the terms outlined in the file COPYING.
7 *
8 */
9
10#include <linux/completion.h>
11#include <linux/delay.h>
12#include <linux/err.h>
13#include <linux/i2c.h>
14#include <linux/init.h>
15#include <linux/interrupt.h>
16#include <linux/ioport.h>
17#include <linux/platform_device.h>
18#include <linux/slab.h>
19
20#include <asm/clock.h>
21#include <asm/i2c-sh7760.h>
22#include <asm/io.h>
23
24/* register offsets */
25#define I2CSCR 0x0 /* slave ctrl */
26#define I2CMCR 0x4 /* master ctrl */
27#define I2CSSR 0x8 /* slave status */
28#define I2CMSR 0xC /* master status */
29#define I2CSIER 0x10 /* slave irq enable */
30#define I2CMIER 0x14 /* master irq enable */
31#define I2CCCR 0x18 /* clock dividers */
32#define I2CSAR 0x1c /* slave address */
33#define I2CMAR 0x20 /* master address */
34#define I2CRXTX 0x24 /* data port */
35#define I2CFCR 0x28 /* fifo control */
36#define I2CFSR 0x2C /* fifo status */
37#define I2CFIER 0x30 /* fifo irq enable */
38#define I2CRFDR 0x34 /* rx fifo count */
39#define I2CTFDR 0x38 /* tx fifo count */
40
41#define REGSIZE 0x3C
42
43#define MCR_MDBS 0x80 /* non-fifo mode switch */
44#define MCR_FSCL 0x40 /* override SCL pin */
45#define MCR_FSDA 0x20 /* override SDA pin */
46#define MCR_OBPC 0x10 /* override pins */
47#define MCR_MIE 0x08 /* master if enable */
48#define MCR_TSBE 0x04
49#define MCR_FSB 0x02 /* force stop bit */
50#define MCR_ESG 0x01 /* en startbit gen. */
51
52#define MSR_MNR 0x40 /* nack received */
53#define MSR_MAL 0x20 /* arbitration lost */
54#define MSR_MST 0x10 /* sent a stop */
55#define MSR_MDE 0x08
56#define MSR_MDT 0x04
57#define MSR_MDR 0x02
58#define MSR_MAT 0x01 /* slave addr xfer done */
59
60#define MIE_MNRE 0x40 /* nack irq en */
61#define MIE_MALE 0x20 /* arblos irq en */
62#define MIE_MSTE 0x10 /* stop irq en */
63#define MIE_MDEE 0x08
64#define MIE_MDTE 0x04
65#define MIE_MDRE 0x02
66#define MIE_MATE 0x01 /* address sent irq en */
67
68#define FCR_RFRST 0x02 /* reset rx fifo */
69#define FCR_TFRST 0x01 /* reset tx fifo */
70
71#define FSR_TEND 0x04 /* last byte sent */
72#define FSR_RDF 0x02 /* rx fifo trigger */
73#define FSR_TDFE 0x01 /* tx fifo empty */
74
75#define FIER_TEIE 0x04 /* tx fifo empty irq en */
76#define FIER_RXIE 0x02 /* rx fifo trig irq en */
77#define FIER_TXIE 0x01 /* tx fifo trig irq en */
78
79#define FIFO_SIZE 16
80
81struct cami2c {
82 void __iomem *iobase;
83 struct i2c_adapter adap;
84
85 /* message processing */
86 struct i2c_msg *msg;
87#define IDF_SEND 1
88#define IDF_RECV 2
89#define IDF_STOP 4
90 int flags;
91
92#define IDS_DONE 1
93#define IDS_ARBLOST 2
94#define IDS_NACK 4
95 int status;
96 struct completion xfer_done;
97
98 int irq;
99 struct resource *ioarea;
100};
101
102static inline void OUT32(struct cami2c *cam, int reg, unsigned long val)
103{
104 ctrl_outl(val, (unsigned long)cam->iobase + reg);
105}
106
107static inline unsigned long IN32(struct cami2c *cam, int reg)
108{
109 return ctrl_inl((unsigned long)cam->iobase + reg);
110}
111
112static irqreturn_t sh7760_i2c_irq(int irq, void *ptr)
113{
114 struct cami2c *id = ptr;
115 struct i2c_msg *msg = id->msg;
116 char *data = msg->buf;
117 unsigned long msr, fsr, fier, len;
118
119 msr = IN32(id, I2CMSR);
120 fsr = IN32(id, I2CFSR);
121
122 /* arbitration lost */
123 if (msr & MSR_MAL) {
124 OUT32(id, I2CMCR, 0);
125 OUT32(id, I2CSCR, 0);
126 OUT32(id, I2CSAR, 0);
127 id->status |= IDS_DONE | IDS_ARBLOST;
128 goto out;
129 }
130
131 if (msr & MSR_MNR) {
132 /* NACK handling is very screwed up. After receiving a
133 * NAK IRQ one has to wait a bit before writing to any
134 * registers, or the ctl will lock up. After that delay
135 * do a normal i2c stop. Then wait at least 1 ms before
136 * attempting another transfer or ctl will stop working
137 */
138 udelay(100); /* wait or risk ctl hang */
139 OUT32(id, I2CFCR, FCR_RFRST | FCR_TFRST);
140 OUT32(id, I2CMCR, MCR_MIE | MCR_FSB);
141 OUT32(id, I2CFIER, 0);
142 OUT32(id, I2CMIER, MIE_MSTE);
143 OUT32(id, I2CSCR, 0);
144 OUT32(id, I2CSAR, 0);
145 id->status |= IDS_NACK;
146 msr &= ~MSR_MAT;
147 fsr = 0;
148 /* In some cases the MST bit is also set. */
149 }
150
151 /* i2c-stop was sent */
152 if (msr & MSR_MST) {
153 id->status |= IDS_DONE;
154 goto out;
155 }
156
157 /* i2c slave addr was sent; set to "normal" operation */
158 if (msr & MSR_MAT)
159 OUT32(id, I2CMCR, MCR_MIE);
160
161 fier = IN32(id, I2CFIER);
162
163 if (fsr & FSR_RDF) {
164 len = IN32(id, I2CRFDR);
165 if (msg->len <= len) {
166 if (id->flags & IDF_STOP) {
167 OUT32(id, I2CMCR, MCR_MIE | MCR_FSB);
168 OUT32(id, I2CFIER, 0);
169 /* manual says: wait >= 0.5 SCL times */
170 udelay(5);
171 /* next int should be MST */
172 } else {
173 id->status |= IDS_DONE;
174 /* keep the RDF bit: ctrl holds SCL low
175 * until the setup for the next i2c_msg
176 * clears this bit.
177 */
178 fsr &= ~FSR_RDF;
179 }
180 }
181 while (msg->len && len) {
182 *data++ = IN32(id, I2CRXTX);
183 msg->len--;
184 len--;
185 }
186
187 if (msg->len) {
188 len = (msg->len >= FIFO_SIZE) ? FIFO_SIZE - 1
189 : msg->len - 1;
190
191 OUT32(id, I2CFCR, FCR_TFRST | ((len & 0xf) << 4));
192 }
193
194 } else if (id->flags & IDF_SEND) {
195 if ((fsr & FSR_TEND) && (msg->len < 1)) {
196 if (id->flags & IDF_STOP) {
197 OUT32(id, I2CMCR, MCR_MIE | MCR_FSB);
198 } else {
199 id->status |= IDS_DONE;
200 /* keep the TEND bit: ctl holds SCL low
201 * until the setup for the next i2c_msg
202 * clears this bit.
203 */
204 fsr &= ~FSR_TEND;
205 }
206 }
207 if (fsr & FSR_TDFE) {
208 while (msg->len && (IN32(id, I2CTFDR) < FIFO_SIZE)) {
209 OUT32(id, I2CRXTX, *data++);
210 msg->len--;
211 }
212
213 if (msg->len < 1) {
214 fier &= ~FIER_TXIE;
215 OUT32(id, I2CFIER, fier);
216 } else {
217 len = (msg->len >= FIFO_SIZE) ? 2 : 0;
218 OUT32(id, I2CFCR,
219 FCR_RFRST | ((len & 3) << 2));
220 }
221 }
222 }
223out:
224 if (id->status & IDS_DONE) {
225 OUT32(id, I2CMIER, 0);
226 OUT32(id, I2CFIER, 0);
227 id->msg = NULL;
228 complete(&id->xfer_done);
229 }
230 /* clear status flags and ctrl resumes work */
231 OUT32(id, I2CMSR, ~msr);
232 OUT32(id, I2CFSR, ~fsr);
233 OUT32(id, I2CSSR, 0);
234
235 return IRQ_HANDLED;
236}
237
238
239/* prepare and start a master receive operation */
240static void sh7760_i2c_mrecv(struct cami2c *id)
241{
242 int len;
243
244 id->flags |= IDF_RECV;
245
246 /* set the slave addr reg; otherwise rcv wont work! */
247 OUT32(id, I2CSAR, 0xfe);
248 OUT32(id, I2CMAR, (id->msg->addr << 1) | 1);
249
250 /* adjust rx fifo trigger */
251 if (id->msg->len >= FIFO_SIZE)
252 len = FIFO_SIZE - 1; /* trigger at fifo full */
253 else
254 len = id->msg->len - 1; /* trigger before all received */
255
256 OUT32(id, I2CFCR, FCR_RFRST | FCR_TFRST);
257 OUT32(id, I2CFCR, FCR_TFRST | ((len & 0xF) << 4));
258
259 OUT32(id, I2CMSR, 0);
260 OUT32(id, I2CMCR, MCR_MIE | MCR_ESG);
261 OUT32(id, I2CMIER, MIE_MNRE | MIE_MALE | MIE_MSTE | MIE_MATE);
262 OUT32(id, I2CFIER, FIER_RXIE);
263}
264
265/* prepare and start a master send operation */
266static void sh7760_i2c_msend(struct cami2c *id)
267{
268 int len;
269
270 id->flags |= IDF_SEND;
271
272 /* set the slave addr reg; otherwise xmit wont work! */
273 OUT32(id, I2CSAR, 0xfe);
274 OUT32(id, I2CMAR, (id->msg->addr << 1) | 0);
275
276 /* adjust tx fifo trigger */
277 if (id->msg->len >= FIFO_SIZE)
278 len = 2; /* trig: 2 bytes left in TX fifo */
279 else
280 len = 0; /* trig: 8 bytes left in TX fifo */
281
282 OUT32(id, I2CFCR, FCR_RFRST | FCR_TFRST);
283 OUT32(id, I2CFCR, FCR_RFRST | ((len & 3) << 2));
284
285 while (id->msg->len && IN32(id, I2CTFDR) < FIFO_SIZE) {
286 OUT32(id, I2CRXTX, *(id->msg->buf));
287 (id->msg->len)--;
288 (id->msg->buf)++;
289 }
290
291 OUT32(id, I2CMSR, 0);
292 OUT32(id, I2CMCR, MCR_MIE | MCR_ESG);
293 OUT32(id, I2CFSR, 0);
294 OUT32(id, I2CMIER, MIE_MNRE | MIE_MALE | MIE_MSTE | MIE_MATE);
295 OUT32(id, I2CFIER, FIER_TEIE | (id->msg->len ? FIER_TXIE : 0));
296}
297
298static inline int sh7760_i2c_busy_check(struct cami2c *id)
299{
300 return (IN32(id, I2CMCR) & MCR_FSDA);
301}
302
303static int sh7760_i2c_master_xfer(struct i2c_adapter *adap,
304 struct i2c_msg *msgs,
305 int num)
306{
307 struct cami2c *id = adap->algo_data;
308 int i, retr;
309
310 if (sh7760_i2c_busy_check(id)) {
311 dev_err(&adap->dev, "sh7760-i2c%d: bus busy!\n", adap->nr);
312 return -EBUSY;
313 }
314
315 i = 0;
316 while (i < num) {
317 retr = adap->retries;
318retry:
319 id->flags = ((i == (num-1)) ? IDF_STOP : 0);
320 id->status = 0;
321 id->msg = msgs;
322 init_completion(&id->xfer_done);
323
324 if (msgs->flags & I2C_M_RD)
325 sh7760_i2c_mrecv(id);
326 else
327 sh7760_i2c_msend(id);
328
329 wait_for_completion(&id->xfer_done);
330
331 if (id->status == 0) {
332 num = -EIO;
333 break;
334 }
335
336 if (id->status & IDS_NACK) {
337 /* wait a bit or i2c module stops working */
338 mdelay(1);
339 num = -EREMOTEIO;
340 break;
341 }
342
343 if (id->status & IDS_ARBLOST) {
344 if (retr--) {
345 mdelay(2);
346 goto retry;
347 }
348 num = -EREMOTEIO;
349 break;
350 }
351
352 msgs++;
353 i++;
354 }
355
356 id->msg = NULL;
357 id->flags = 0;
358 id->status = 0;
359
360 OUT32(id, I2CMCR, 0);
361 OUT32(id, I2CMSR, 0);
362 OUT32(id, I2CMIER, 0);
363 OUT32(id, I2CFIER, 0);
364
365 /* reset slave module registers too: master mode enables slave
366 * module for receive ops (ack, data). Without this reset,
367 * eternal bus activity might be reported after NACK / ARBLOST.
368 */
369 OUT32(id, I2CSCR, 0);
370 OUT32(id, I2CSAR, 0);
371 OUT32(id, I2CSSR, 0);
372
373 return num;
374}
375
376static u32 sh7760_i2c_func(struct i2c_adapter *adap)
377{
378 return I2C_FUNC_I2C | (I2C_FUNC_SMBUS_EMUL & ~I2C_FUNC_SMBUS_QUICK);
379}
380
381static const struct i2c_algorithm sh7760_i2c_algo = {
382 .master_xfer = sh7760_i2c_master_xfer,
383 .functionality = sh7760_i2c_func,
384};
385
386/* calculate CCR register setting for a desired scl clock. SCL clock is
387 * derived from I2C module clock (iclk) which in turn is derived from
388 * peripheral module clock (mclk, usually around 33MHz):
389 * iclk = mclk/(CDF + 1). iclk must be < 20MHz.
390 * scl = iclk/(SCGD*8 + 20).
391 */
392static int __devinit calc_CCR(unsigned long scl_hz)
393{
394 struct clk *mclk;
395 unsigned long mck, m1, dff, odff, iclk;
396 signed char cdf, cdfm;
397 int scgd, scgdm, scgds;
398
399 mclk = clk_get(NULL, "module_clk");
400 if (IS_ERR(mclk)) {
401 return PTR_ERR(mclk);
402 } else {
403 mck = mclk->rate;
404 clk_put(mclk);
405 }
406
407 odff = scl_hz;
408 scgdm = cdfm = m1 = 0;
409 for (cdf = 3; cdf >= 0; cdf--) {
410 iclk = mck / (1 + cdf);
411 if (iclk >= 20000000)
412 continue;
413 scgds = ((iclk / scl_hz) - 20) >> 3;
414 for (scgd = scgds; (scgd < 63) && scgd <= scgds + 1; scgd++) {
415 m1 = iclk / (20 + (scgd << 3));
416 dff = abs(scl_hz - m1);
417 if (dff < odff) {
418 odff = dff;
419 cdfm = cdf;
420 scgdm = scgd;
421 }
422 }
423 }
424 /* fail if more than 25% off of requested SCL */
425 if (odff > (scl_hz >> 2))
426 return -EINVAL;
427
428 /* create a CCR register value */
429 return ((scgdm << 2) | cdfm);
430}
431
432static int __devinit sh7760_i2c_probe(struct platform_device *pdev)
433{
434 struct sh7760_i2c_platdata *pd;
435 struct resource *res;
436 struct cami2c *id;
437 int ret;
438
439 pd = pdev->dev.platform_data;
440 if (!pd) {
441 dev_err(&pdev->dev, "no platform_data!\n");
442 ret = -ENODEV;
443 goto out0;
444 }
445
446 id = kzalloc(sizeof(struct cami2c), GFP_KERNEL);
447 if (!id) {
448 dev_err(&pdev->dev, "no mem for private data\n");
449 ret = -ENOMEM;
450 goto out0;
451 }
452
453 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
454 if (!res) {
455 dev_err(&pdev->dev, "no mmio resources\n");
456 ret = -ENODEV;
457 goto out1;
458 }
459
460 id->ioarea = request_mem_region(res->start, REGSIZE, pdev->name);
461 if (!id->ioarea) {
462 dev_err(&pdev->dev, "mmio already reserved\n");
463 ret = -EBUSY;
464 goto out1;
465 }
466
467 id->iobase = ioremap(res->start, REGSIZE);
468 if (!id->iobase) {
469 dev_err(&pdev->dev, "cannot ioremap\n");
470 ret = -ENODEV;
471 goto out2;
472 }
473
474 id->irq = platform_get_irq(pdev, 0);
475
476 id->adap.nr = pdev->id;
477 id->adap.algo = &sh7760_i2c_algo;
478 id->adap.class = I2C_CLASS_ALL;
479 id->adap.retries = 3;
480 id->adap.algo_data = id;
481 id->adap.dev.parent = &pdev->dev;
482 snprintf(id->adap.name, sizeof(id->adap.name),
483 "SH7760 I2C at %08lx", (unsigned long)res->start);
484
485 OUT32(id, I2CMCR, 0);
486 OUT32(id, I2CMSR, 0);
487 OUT32(id, I2CMIER, 0);
488 OUT32(id, I2CMAR, 0);
489 OUT32(id, I2CSIER, 0);
490 OUT32(id, I2CSAR, 0);
491 OUT32(id, I2CSCR, 0);
492 OUT32(id, I2CSSR, 0);
493 OUT32(id, I2CFIER, 0);
494 OUT32(id, I2CFCR, FCR_RFRST | FCR_TFRST);
495 OUT32(id, I2CFSR, 0);
496
497 ret = calc_CCR(pd->speed_khz * 1000);
498 if (ret < 0) {
499 dev_err(&pdev->dev, "invalid SCL clock: %dkHz\n",
500 pd->speed_khz);
501 goto out3;
502 }
503 OUT32(id, I2CCCR, ret);
504
505 if (request_irq(id->irq, sh7760_i2c_irq, IRQF_DISABLED,
506 SH7760_I2C_DEVNAME, id)) {
507 dev_err(&pdev->dev, "cannot get irq %d\n", id->irq);
508 ret = -EBUSY;
509 goto out3;
510 }
511
512 ret = i2c_add_numbered_adapter(&id->adap);
513 if (ret < 0) {
514 dev_err(&pdev->dev, "reg adap failed: %d\n", ret);
515 goto out4;
516 }
517
518 platform_set_drvdata(pdev, id);
519
520 dev_info(&pdev->dev, "%d kHz mmio %08x irq %d\n",
521 pd->speed_khz, res->start, id->irq);
522
523 return 0;
524
525out4:
526 free_irq(id->irq, id);
527out3:
528 iounmap(id->iobase);
529out2:
530 release_resource(id->ioarea);
531 kfree(id->ioarea);
532out1:
533 kfree(id);
534out0:
535 return ret;
536}
537
538static int __devexit sh7760_i2c_remove(struct platform_device *pdev)
539{
540 struct cami2c *id = platform_get_drvdata(pdev);
541
542 i2c_del_adapter(&id->adap);
543 free_irq(id->irq, id);
544 iounmap(id->iobase);
545 release_resource(id->ioarea);
546 kfree(id->ioarea);
547 kfree(id);
548 platform_set_drvdata(pdev, NULL);
549
550 return 0;
551}
552
553static struct platform_driver sh7760_i2c_drv = {
554 .driver = {
555 .name = SH7760_I2C_DEVNAME,
556 .owner = THIS_MODULE,
557 },
558 .probe = sh7760_i2c_probe,
559 .remove = __devexit_p(sh7760_i2c_remove),
560};
561
562static int __init sh7760_i2c_init(void)
563{
564 return platform_driver_register(&sh7760_i2c_drv);
565}
566
567static void __exit sh7760_i2c_exit(void)
568{
569 platform_driver_unregister(&sh7760_i2c_drv);
570}
571
572module_init(sh7760_i2c_init);
573module_exit(sh7760_i2c_exit);
574
575MODULE_LICENSE("GPL");
576MODULE_DESCRIPTION("SH7760 I2C bus driver");
577MODULE_AUTHOR("Manuel Lauss <mano@roarinelk.homelinux.net>");
diff --git a/drivers/i2c/busses/i2c-sh_mobile.c b/drivers/i2c/busses/i2c-sh_mobile.c
new file mode 100644
index 000000000000..840e634fa31f
--- /dev/null
+++ b/drivers/i2c/busses/i2c-sh_mobile.c
@@ -0,0 +1,500 @@
1/*
2 * SuperH Mobile I2C Controller
3 *
4 * Copyright (C) 2008 Magnus Damm
5 *
6 * Portions of the code based on out-of-tree driver i2c-sh7343.c
7 * Copyright (c) 2006 Carlos Munoz <carlos@kenati.com>
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 as published by
11 * the Free Software Foundation; either version 2 of the License
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22
23#include <linux/kernel.h>
24#include <linux/module.h>
25#include <linux/init.h>
26#include <linux/delay.h>
27#include <linux/platform_device.h>
28#include <linux/interrupt.h>
29#include <linux/i2c.h>
30#include <linux/err.h>
31#include <linux/clk.h>
32#include <linux/io.h>
33
34enum sh_mobile_i2c_op {
35 OP_START = 0,
36 OP_TX_ONLY,
37 OP_TX_STOP,
38 OP_TX_TO_RX,
39 OP_RX_ONLY,
40 OP_RX_STOP,
41};
42
43struct sh_mobile_i2c_data {
44 struct device *dev;
45 void __iomem *reg;
46 struct i2c_adapter adap;
47
48 struct clk *clk;
49 u_int8_t iccl;
50 u_int8_t icch;
51
52 spinlock_t lock;
53 wait_queue_head_t wait;
54 struct i2c_msg *msg;
55 int pos;
56 int sr;
57};
58
59#define NORMAL_SPEED 100000 /* FAST_SPEED 400000 */
60
61/* Register offsets */
62#define ICDR(pd) (pd->reg + 0x00)
63#define ICCR(pd) (pd->reg + 0x04)
64#define ICSR(pd) (pd->reg + 0x08)
65#define ICIC(pd) (pd->reg + 0x0c)
66#define ICCL(pd) (pd->reg + 0x10)
67#define ICCH(pd) (pd->reg + 0x14)
68
69/* Register bits */
70#define ICCR_ICE 0x80
71#define ICCR_RACK 0x40
72#define ICCR_TRS 0x10
73#define ICCR_BBSY 0x04
74#define ICCR_SCP 0x01
75
76#define ICSR_SCLM 0x80
77#define ICSR_SDAM 0x40
78#define SW_DONE 0x20
79#define ICSR_BUSY 0x10
80#define ICSR_AL 0x08
81#define ICSR_TACK 0x04
82#define ICSR_WAIT 0x02
83#define ICSR_DTE 0x01
84
85#define ICIC_ALE 0x08
86#define ICIC_TACKE 0x04
87#define ICIC_WAITE 0x02
88#define ICIC_DTEE 0x01
89
90static void activate_ch(struct sh_mobile_i2c_data *pd)
91{
92 /* Make sure the clock is enabled */
93 clk_enable(pd->clk);
94
95 /* Enable channel and configure rx ack */
96 iowrite8(ioread8(ICCR(pd)) | ICCR_ICE, ICCR(pd));
97
98 /* Mask all interrupts */
99 iowrite8(0, ICIC(pd));
100
101 /* Set the clock */
102 iowrite8(pd->iccl, ICCL(pd));
103 iowrite8(pd->icch, ICCH(pd));
104}
105
106static void deactivate_ch(struct sh_mobile_i2c_data *pd)
107{
108 /* Clear/disable interrupts */
109 iowrite8(0, ICSR(pd));
110 iowrite8(0, ICIC(pd));
111
112 /* Disable channel */
113 iowrite8(ioread8(ICCR(pd)) & ~ICCR_ICE, ICCR(pd));
114
115 /* Disable clock */
116 clk_disable(pd->clk);
117}
118
119static unsigned char i2c_op(struct sh_mobile_i2c_data *pd,
120 enum sh_mobile_i2c_op op, unsigned char data)
121{
122 unsigned char ret = 0;
123 unsigned long flags;
124
125 dev_dbg(pd->dev, "op %d, data in 0x%02x\n", op, data);
126
127 spin_lock_irqsave(&pd->lock, flags);
128
129 switch (op) {
130 case OP_START:
131 iowrite8(0x94, ICCR(pd));
132 break;
133 case OP_TX_ONLY:
134 iowrite8(data, ICDR(pd));
135 break;
136 case OP_TX_STOP:
137 iowrite8(data, ICDR(pd));
138 iowrite8(0x90, ICCR(pd));
139 iowrite8(ICIC_ALE | ICIC_TACKE, ICIC(pd));
140 break;
141 case OP_TX_TO_RX:
142 iowrite8(data, ICDR(pd));
143 iowrite8(0x81, ICCR(pd));
144 break;
145 case OP_RX_ONLY:
146 ret = ioread8(ICDR(pd));
147 break;
148 case OP_RX_STOP:
149 ret = ioread8(ICDR(pd));
150 iowrite8(0xc0, ICCR(pd));
151 break;
152 }
153
154 spin_unlock_irqrestore(&pd->lock, flags);
155
156 dev_dbg(pd->dev, "op %d, data out 0x%02x\n", op, ret);
157 return ret;
158}
159
160static irqreturn_t sh_mobile_i2c_isr(int irq, void *dev_id)
161{
162 struct platform_device *dev = dev_id;
163 struct sh_mobile_i2c_data *pd = platform_get_drvdata(dev);
164 struct i2c_msg *msg = pd->msg;
165 unsigned char data, sr;
166 int wakeup = 0;
167
168 sr = ioread8(ICSR(pd));
169 pd->sr |= sr;
170
171 dev_dbg(pd->dev, "i2c_isr 0x%02x 0x%02x %s %d %d!\n", sr, pd->sr,
172 (msg->flags & I2C_M_RD) ? "read" : "write",
173 pd->pos, msg->len);
174
175 if (sr & (ICSR_AL | ICSR_TACK)) {
176 iowrite8(0, ICIC(pd)); /* disable interrupts */
177 wakeup = 1;
178 goto do_wakeup;
179 }
180
181 if (pd->pos == msg->len) {
182 i2c_op(pd, OP_RX_ONLY, 0);
183 wakeup = 1;
184 goto do_wakeup;
185 }
186
187 if (pd->pos == -1) {
188 data = (msg->addr & 0x7f) << 1;
189 data |= (msg->flags & I2C_M_RD) ? 1 : 0;
190 } else
191 data = msg->buf[pd->pos];
192
193 if ((pd->pos == -1) || !(msg->flags & I2C_M_RD)) {
194 if (msg->flags & I2C_M_RD)
195 i2c_op(pd, OP_TX_TO_RX, data);
196 else if (pd->pos == (msg->len - 1)) {
197 i2c_op(pd, OP_TX_STOP, data);
198 wakeup = 1;
199 } else
200 i2c_op(pd, OP_TX_ONLY, data);
201 } else {
202 if (pd->pos == (msg->len - 1))
203 data = i2c_op(pd, OP_RX_STOP, 0);
204 else
205 data = i2c_op(pd, OP_RX_ONLY, 0);
206
207 msg->buf[pd->pos] = data;
208 }
209 pd->pos++;
210
211 do_wakeup:
212 if (wakeup) {
213 pd->sr |= SW_DONE;
214 wake_up(&pd->wait);
215 }
216
217 return IRQ_HANDLED;
218}
219
220static int start_ch(struct sh_mobile_i2c_data *pd, struct i2c_msg *usr_msg)
221{
222 /* Initialize channel registers */
223 iowrite8(ioread8(ICCR(pd)) & ~ICCR_ICE, ICCR(pd));
224
225 /* Enable channel and configure rx ack */
226 iowrite8(ioread8(ICCR(pd)) | ICCR_ICE, ICCR(pd));
227
228 /* Set the clock */
229 iowrite8(pd->iccl, ICCL(pd));
230 iowrite8(pd->icch, ICCH(pd));
231
232 pd->msg = usr_msg;
233 pd->pos = -1;
234 pd->sr = 0;
235
236 /* Enable all interrupts except wait */
237 iowrite8(ioread8(ICIC(pd)) | ICIC_ALE | ICIC_TACKE | ICIC_DTEE,
238 ICIC(pd));
239 return 0;
240}
241
242static int sh_mobile_i2c_xfer(struct i2c_adapter *adapter,
243 struct i2c_msg *msgs,
244 int num)
245{
246 struct sh_mobile_i2c_data *pd = i2c_get_adapdata(adapter);
247 struct i2c_msg *msg;
248 int err = 0;
249 u_int8_t val;
250 int i, k, retry_count;
251
252 activate_ch(pd);
253
254 /* Process all messages */
255 for (i = 0; i < num; i++) {
256 msg = &msgs[i];
257
258 err = start_ch(pd, msg);
259 if (err)
260 break;
261
262 i2c_op(pd, OP_START, 0);
263
264 /* The interrupt handler takes care of the rest... */
265 k = wait_event_timeout(pd->wait,
266 pd->sr & (ICSR_TACK | SW_DONE),
267 5 * HZ);
268 if (!k)
269 dev_err(pd->dev, "Transfer request timed out\n");
270
271 retry_count = 10;
272again:
273 val = ioread8(ICSR(pd));
274
275 dev_dbg(pd->dev, "val 0x%02x pd->sr 0x%02x\n", val, pd->sr);
276
277 if ((val | pd->sr) & (ICSR_TACK | ICSR_AL)) {
278 err = -EIO;
279 break;
280 }
281
282 /* the interrupt handler may wake us up before the
283 * transfer is finished, so poll the hardware
284 * until we're done.
285 */
286
287 if (!(!(val & ICSR_BUSY) && (val & ICSR_SCLM) &&
288 (val & ICSR_SDAM))) {
289 msleep(1);
290 if (retry_count--)
291 goto again;
292
293 err = -EIO;
294 dev_err(pd->dev, "Polling timed out\n");
295 break;
296 }
297 }
298
299 deactivate_ch(pd);
300
301 if (!err)
302 err = num;
303 return err;
304}
305
306static u32 sh_mobile_i2c_func(struct i2c_adapter *adapter)
307{
308 return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
309}
310
311static struct i2c_algorithm sh_mobile_i2c_algorithm = {
312 .functionality = sh_mobile_i2c_func,
313 .master_xfer = sh_mobile_i2c_xfer,
314};
315
316static void sh_mobile_i2c_setup_channel(struct platform_device *dev)
317{
318 struct sh_mobile_i2c_data *pd = platform_get_drvdata(dev);
319 unsigned long peripheral_clk = clk_get_rate(pd->clk);
320 u_int32_t num;
321 u_int32_t denom;
322 u_int32_t tmp;
323
324 spin_lock_init(&pd->lock);
325 init_waitqueue_head(&pd->wait);
326
327 /* Calculate the value for iccl. From the data sheet:
328 * iccl = (p clock / transfer rate) * (L / (L + H))
329 * where L and H are the SCL low/high ratio (5/4 in this case).
330 * We also round off the result.
331 */
332 num = peripheral_clk * 5;
333 denom = NORMAL_SPEED * 9;
334 tmp = num * 10 / denom;
335 if (tmp % 10 >= 5)
336 pd->iccl = (u_int8_t)((num/denom) + 1);
337 else
338 pd->iccl = (u_int8_t)(num/denom);
339
340 /* Calculate the value for icch. From the data sheet:
341 icch = (p clock / transfer rate) * (H / (L + H)) */
342 num = peripheral_clk * 4;
343 tmp = num * 10 / denom;
344 if (tmp % 10 >= 5)
345 pd->icch = (u_int8_t)((num/denom) + 1);
346 else
347 pd->icch = (u_int8_t)(num/denom);
348}
349
350static int sh_mobile_i2c_hook_irqs(struct platform_device *dev, int hook)
351{
352 struct resource *res;
353 int ret = -ENXIO;
354 int q, m;
355 int k = 0;
356 int n = 0;
357
358 while ((res = platform_get_resource(dev, IORESOURCE_IRQ, k))) {
359 for (n = res->start; hook && n <= res->end; n++) {
360 if (request_irq(n, sh_mobile_i2c_isr, IRQF_DISABLED,
361 dev->dev.bus_id, dev))
362 goto rollback;
363 }
364 k++;
365 }
366
367 if (hook)
368 return k > 0 ? 0 : -ENOENT;
369
370 k--;
371 ret = 0;
372
373 rollback:
374 for (q = k; k >= 0; k--) {
375 for (m = n; m >= res->start; m--)
376 free_irq(m, dev);
377
378 res = platform_get_resource(dev, IORESOURCE_IRQ, k - 1);
379 m = res->end;
380 }
381
382 return ret;
383}
384
385static int sh_mobile_i2c_probe(struct platform_device *dev)
386{
387 struct sh_mobile_i2c_data *pd;
388 struct i2c_adapter *adap;
389 struct resource *res;
390 int size;
391 int ret;
392
393 pd = kzalloc(sizeof(struct sh_mobile_i2c_data), GFP_KERNEL);
394 if (pd == NULL) {
395 dev_err(&dev->dev, "cannot allocate private data\n");
396 return -ENOMEM;
397 }
398
399 pd->clk = clk_get(&dev->dev, "peripheral_clk");
400 if (IS_ERR(pd->clk)) {
401 dev_err(&dev->dev, "cannot get peripheral clock\n");
402 ret = PTR_ERR(pd->clk);
403 goto err;
404 }
405
406 ret = sh_mobile_i2c_hook_irqs(dev, 1);
407 if (ret) {
408 dev_err(&dev->dev, "cannot request IRQ\n");
409 goto err_clk;
410 }
411
412 pd->dev = &dev->dev;
413 platform_set_drvdata(dev, pd);
414
415 res = platform_get_resource(dev, IORESOURCE_MEM, 0);
416 if (res == NULL) {
417 dev_err(&dev->dev, "cannot find IO resource\n");
418 ret = -ENOENT;
419 goto err_irq;
420 }
421
422 size = (res->end - res->start) + 1;
423
424 pd->reg = ioremap(res->start, size);
425 if (pd->reg == NULL) {
426 dev_err(&dev->dev, "cannot map IO\n");
427 ret = -ENXIO;
428 goto err_irq;
429 }
430
431 /* setup the private data */
432 adap = &pd->adap;
433 i2c_set_adapdata(adap, pd);
434
435 adap->owner = THIS_MODULE;
436 adap->algo = &sh_mobile_i2c_algorithm;
437 adap->dev.parent = &dev->dev;
438 adap->retries = 5;
439 adap->nr = dev->id;
440
441 strlcpy(adap->name, dev->name, sizeof(adap->name));
442
443 sh_mobile_i2c_setup_channel(dev);
444
445 ret = i2c_add_numbered_adapter(adap);
446 if (ret < 0) {
447 dev_err(&dev->dev, "cannot add numbered adapter\n");
448 goto err_all;
449 }
450
451 return 0;
452
453 err_all:
454 iounmap(pd->reg);
455 err_irq:
456 sh_mobile_i2c_hook_irqs(dev, 0);
457 err_clk:
458 clk_put(pd->clk);
459 err:
460 kfree(pd);
461 return ret;
462}
463
464static int sh_mobile_i2c_remove(struct platform_device *dev)
465{
466 struct sh_mobile_i2c_data *pd = platform_get_drvdata(dev);
467
468 i2c_del_adapter(&pd->adap);
469 iounmap(pd->reg);
470 sh_mobile_i2c_hook_irqs(dev, 0);
471 clk_put(pd->clk);
472 kfree(pd);
473 return 0;
474}
475
476static struct platform_driver sh_mobile_i2c_driver = {
477 .driver = {
478 .name = "i2c-sh_mobile",
479 .owner = THIS_MODULE,
480 },
481 .probe = sh_mobile_i2c_probe,
482 .remove = sh_mobile_i2c_remove,
483};
484
485static int __init sh_mobile_i2c_adap_init(void)
486{
487 return platform_driver_register(&sh_mobile_i2c_driver);
488}
489
490static void __exit sh_mobile_i2c_adap_exit(void)
491{
492 platform_driver_unregister(&sh_mobile_i2c_driver);
493}
494
495module_init(sh_mobile_i2c_adap_init);
496module_exit(sh_mobile_i2c_adap_exit);
497
498MODULE_DESCRIPTION("SuperH Mobile I2C Bus Controller driver");
499MODULE_AUTHOR("Magnus Damm");
500MODULE_LICENSE("GPL v2");
diff --git a/drivers/i2c/busses/i2c-simtec.c b/drivers/i2c/busses/i2c-simtec.c
index 10af8d31e12a..042fda295f3a 100644
--- a/drivers/i2c/busses/i2c-simtec.c
+++ b/drivers/i2c/busses/i2c-simtec.c
@@ -159,6 +159,9 @@ static int simtec_i2c_remove(struct platform_device *dev)
159 159
160/* device driver */ 160/* device driver */
161 161
162/* work with hotplug and coldplug */
163MODULE_ALIAS("platform:simtec-i2c");
164
162static struct platform_driver simtec_i2c_driver = { 165static struct platform_driver simtec_i2c_driver = {
163 .driver = { 166 .driver = {
164 .name = "simtec-i2c", 167 .name = "simtec-i2c",
diff --git a/drivers/i2c/busses/i2c-versatile.c b/drivers/i2c/busses/i2c-versatile.c
index 081d9578ce10..4678babd3ce6 100644
--- a/drivers/i2c/busses/i2c-versatile.c
+++ b/drivers/i2c/busses/i2c-versatile.c
@@ -151,3 +151,4 @@ module_exit(i2c_versatile_exit);
151 151
152MODULE_DESCRIPTION("ARM Versatile I2C bus driver"); 152MODULE_DESCRIPTION("ARM Versatile I2C bus driver");
153MODULE_LICENSE("GPL"); 153MODULE_LICENSE("GPL");
154MODULE_ALIAS("platform:versatile-i2c");
diff --git a/drivers/i2c/busses/scx200_acb.c b/drivers/i2c/busses/scx200_acb.c
index f5e7a70da831..61abe0f33255 100644
--- a/drivers/i2c/busses/scx200_acb.c
+++ b/drivers/i2c/busses/scx200_acb.c
@@ -527,7 +527,7 @@ static int __init scx200_create_isa(const char *text, unsigned long base,
527 if (iface == NULL) 527 if (iface == NULL)
528 return -ENOMEM; 528 return -ENOMEM;
529 529
530 if (request_region(base, 8, iface->adapter.name) == 0) { 530 if (!request_region(base, 8, iface->adapter.name)) {
531 printk(KERN_ERR NAME ": can't allocate io 0x%lx-0x%lx\n", 531 printk(KERN_ERR NAME ": can't allocate io 0x%lx-0x%lx\n",
532 base, base + 8 - 1); 532 base, base + 8 - 1);
533 rc = -EBUSY; 533 rc = -EBUSY;
diff --git a/drivers/i2c/chips/isp1301_omap.c b/drivers/i2c/chips/isp1301_omap.c
index 2a3160153f54..b1b45dddb17e 100644
--- a/drivers/i2c/chips/isp1301_omap.c
+++ b/drivers/i2c/chips/isp1301_omap.c
@@ -658,7 +658,7 @@ pulldown:
658 OTG_CTRL_REG |= OTG_PULLUP; 658 OTG_CTRL_REG |= OTG_PULLUP;
659 } 659 }
660 660
661 check_state(isp, __FUNCTION__); 661 check_state(isp, __func__);
662 dump_regs(isp, "otg->isp1301"); 662 dump_regs(isp, "otg->isp1301");
663} 663}
664 664
@@ -782,7 +782,7 @@ static irqreturn_t omap_otg_irq(int irq, void *_isp)
782 if (otg_ctrl & OTG_DRIVER_SEL) { 782 if (otg_ctrl & OTG_DRIVER_SEL) {
783 switch (isp->otg.state) { 783 switch (isp->otg.state) {
784 case OTG_STATE_A_IDLE: 784 case OTG_STATE_A_IDLE:
785 b_idle(isp, __FUNCTION__); 785 b_idle(isp, __func__);
786 break; 786 break;
787 default: 787 default:
788 break; 788 break;
@@ -826,7 +826,7 @@ static irqreturn_t omap_otg_irq(int irq, void *_isp)
826 isp->otg.host->otg_port); 826 isp->otg.host->otg_port);
827 } 827 }
828 828
829 check_state(isp, __FUNCTION__); 829 check_state(isp, __func__);
830 return ret; 830 return ret;
831} 831}
832 832
@@ -837,7 +837,7 @@ static int otg_init(struct isp1301 *isp)
837 if (!otg_dev) 837 if (!otg_dev)
838 return -ENODEV; 838 return -ENODEV;
839 839
840 dump_regs(isp, __FUNCTION__); 840 dump_regs(isp, __func__);
841 /* some of these values are board-specific... */ 841 /* some of these values are board-specific... */
842 OTG_SYSCON_2_REG |= OTG_EN 842 OTG_SYSCON_2_REG |= OTG_EN
843 /* for B-device: */ 843 /* for B-device: */
@@ -853,9 +853,9 @@ static int otg_init(struct isp1301 *isp)
853 update_otg1(isp, isp1301_get_u8(isp, ISP1301_INTERRUPT_SOURCE)); 853 update_otg1(isp, isp1301_get_u8(isp, ISP1301_INTERRUPT_SOURCE));
854 update_otg2(isp, isp1301_get_u8(isp, ISP1301_OTG_STATUS)); 854 update_otg2(isp, isp1301_get_u8(isp, ISP1301_OTG_STATUS));
855 855
856 check_state(isp, __FUNCTION__); 856 check_state(isp, __func__);
857 pr_debug("otg: %s, %s %06x\n", 857 pr_debug("otg: %s, %s %06x\n",
858 state_name(isp), __FUNCTION__, OTG_CTRL_REG); 858 state_name(isp), __func__, OTG_CTRL_REG);
859 859
860 OTG_IRQ_EN_REG = DRIVER_SWITCH | OPRT_CHG 860 OTG_IRQ_EN_REG = DRIVER_SWITCH | OPRT_CHG
861 | B_SRP_TMROUT | B_HNP_FAIL 861 | B_SRP_TMROUT | B_HNP_FAIL
@@ -1041,11 +1041,11 @@ static void isp_update_otg(struct isp1301 *isp, u8 stat)
1041 OTG1_DP_PULLDOWN); 1041 OTG1_DP_PULLDOWN);
1042 isp1301_clear_bits(isp, ISP1301_OTG_CONTROL_1, 1042 isp1301_clear_bits(isp, ISP1301_OTG_CONTROL_1,
1043 OTG1_DP_PULLUP); 1043 OTG1_DP_PULLUP);
1044 dump_regs(isp, __FUNCTION__); 1044 dump_regs(isp, __func__);
1045#endif 1045#endif
1046 /* FALLTHROUGH */ 1046 /* FALLTHROUGH */
1047 case OTG_STATE_B_SRP_INIT: 1047 case OTG_STATE_B_SRP_INIT:
1048 b_idle(isp, __FUNCTION__); 1048 b_idle(isp, __func__);
1049 OTG_CTRL_REG &= OTG_CTRL_REG & OTG_XCEIV_OUTPUTS; 1049 OTG_CTRL_REG &= OTG_CTRL_REG & OTG_XCEIV_OUTPUTS;
1050 /* FALLTHROUGH */ 1050 /* FALLTHROUGH */
1051 case OTG_STATE_B_IDLE: 1051 case OTG_STATE_B_IDLE:
@@ -1077,7 +1077,7 @@ static void isp_update_otg(struct isp1301 *isp, u8 stat)
1077 */ 1077 */
1078 update_otg1(isp, isp_stat); 1078 update_otg1(isp, isp_stat);
1079 update_otg2(isp, isp_bstat); 1079 update_otg2(isp, isp_bstat);
1080 check_state(isp, __FUNCTION__); 1080 check_state(isp, __func__);
1081#endif 1081#endif
1082 1082
1083 dump_regs(isp, "isp1301->otg"); 1083 dump_regs(isp, "isp1301->otg");
@@ -1310,7 +1310,7 @@ isp1301_set_host(struct otg_transceiver *otg, struct usb_bus *host)
1310 */ 1310 */
1311 isp1301_set_bits(isp, ISP1301_OTG_CONTROL_1, OTG1_VBUS_DRV); 1311 isp1301_set_bits(isp, ISP1301_OTG_CONTROL_1, OTG1_VBUS_DRV);
1312 1312
1313 dump_regs(isp, __FUNCTION__); 1313 dump_regs(isp, __func__);
1314 1314
1315 return 0; 1315 return 0;
1316 1316
@@ -1365,7 +1365,7 @@ isp1301_set_peripheral(struct otg_transceiver *otg, struct usb_gadget *gadget)
1365 isp1301_set_bits(isp, ISP1301_INTERRUPT_FALLING, 1365 isp1301_set_bits(isp, ISP1301_INTERRUPT_FALLING,
1366 INTR_VBUS_VLD); 1366 INTR_VBUS_VLD);
1367 dev_info(&isp->client.dev, "B-Peripheral sessions ok\n"); 1367 dev_info(&isp->client.dev, "B-Peripheral sessions ok\n");
1368 dump_regs(isp, __FUNCTION__); 1368 dump_regs(isp, __func__);
1369 1369
1370 /* If this has a Mini-AB connector, this mode is highly 1370 /* If this has a Mini-AB connector, this mode is highly
1371 * nonstandard ... but can be handy for testing, so long 1371 * nonstandard ... but can be handy for testing, so long
@@ -1416,7 +1416,7 @@ isp1301_start_srp(struct otg_transceiver *dev)
1416 1416
1417 pr_debug("otg: SRP, %s ... %06x\n", state_name(isp), OTG_CTRL_REG); 1417 pr_debug("otg: SRP, %s ... %06x\n", state_name(isp), OTG_CTRL_REG);
1418#ifdef CONFIG_USB_OTG 1418#ifdef CONFIG_USB_OTG
1419 check_state(isp, __FUNCTION__); 1419 check_state(isp, __func__);
1420#endif 1420#endif
1421 return 0; 1421 return 0;
1422} 1422}
@@ -1463,7 +1463,7 @@ isp1301_start_hnp(struct otg_transceiver *dev)
1463 } 1463 }
1464 pr_debug("otg: HNP %s, %06x ...\n", 1464 pr_debug("otg: HNP %s, %06x ...\n",
1465 state_name(isp), OTG_CTRL_REG); 1465 state_name(isp), OTG_CTRL_REG);
1466 check_state(isp, __FUNCTION__); 1466 check_state(isp, __func__);
1467 return 0; 1467 return 0;
1468#else 1468#else
1469 /* srp-only */ 1469 /* srp-only */
@@ -1601,7 +1601,7 @@ fail2:
1601 update_otg2(isp, isp1301_get_u8(isp, ISP1301_OTG_STATUS)); 1601 update_otg2(isp, isp1301_get_u8(isp, ISP1301_OTG_STATUS));
1602#endif 1602#endif
1603 1603
1604 dump_regs(isp, __FUNCTION__); 1604 dump_regs(isp, __func__);
1605 1605
1606#ifdef VERBOSE 1606#ifdef VERBOSE
1607 mod_timer(&isp->timer, jiffies + TIMER_JIFFIES); 1607 mod_timer(&isp->timer, jiffies + TIMER_JIFFIES);
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
index e186df657119..6c7fa8d53c0e 100644
--- a/drivers/i2c/i2c-core.c
+++ b/drivers/i2c/i2c-core.c
@@ -1506,7 +1506,7 @@ static s32 i2c_smbus_xfer_emulated(struct i2c_adapter * adapter, u16 addr,
1506 read_write = I2C_SMBUS_READ; 1506 read_write = I2C_SMBUS_READ;
1507 if (data->block[0] > I2C_SMBUS_BLOCK_MAX) { 1507 if (data->block[0] > I2C_SMBUS_BLOCK_MAX) {
1508 dev_err(&adapter->dev, "%s called with invalid " 1508 dev_err(&adapter->dev, "%s called with invalid "
1509 "block proc call size (%d)\n", __FUNCTION__, 1509 "block proc call size (%d)\n", __func__,
1510 data->block[0]); 1510 data->block[0]);
1511 return -1; 1511 return -1;
1512 } 1512 }
diff --git a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c
index 393e679d9faa..d34c14c81c29 100644
--- a/drivers/i2c/i2c-dev.c
+++ b/drivers/i2c/i2c-dev.c
@@ -200,16 +200,176 @@ static int i2cdev_check_addr(struct i2c_adapter *adapter, unsigned int addr)
200 return device_for_each_child(&adapter->dev, &addr, i2cdev_check); 200 return device_for_each_child(&adapter->dev, &addr, i2cdev_check);
201} 201}
202 202
203static int i2cdev_ioctl(struct inode *inode, struct file *file, 203static noinline int i2cdev_ioctl_rdrw(struct i2c_client *client,
204 unsigned int cmd, unsigned long arg) 204 unsigned long arg)
205{ 205{
206 struct i2c_client *client = (struct i2c_client *)file->private_data;
207 struct i2c_rdwr_ioctl_data rdwr_arg; 206 struct i2c_rdwr_ioctl_data rdwr_arg;
208 struct i2c_smbus_ioctl_data data_arg;
209 union i2c_smbus_data temp;
210 struct i2c_msg *rdwr_pa; 207 struct i2c_msg *rdwr_pa;
211 u8 __user **data_ptrs; 208 u8 __user **data_ptrs;
212 int i,datasize,res; 209 int i, res;
210
211 if (copy_from_user(&rdwr_arg,
212 (struct i2c_rdwr_ioctl_data __user *)arg,
213 sizeof(rdwr_arg)))
214 return -EFAULT;
215
216 /* Put an arbitrary limit on the number of messages that can
217 * be sent at once */
218 if (rdwr_arg.nmsgs > I2C_RDRW_IOCTL_MAX_MSGS)
219 return -EINVAL;
220
221 rdwr_pa = (struct i2c_msg *)
222 kmalloc(rdwr_arg.nmsgs * sizeof(struct i2c_msg),
223 GFP_KERNEL);
224 if (!rdwr_pa)
225 return -ENOMEM;
226
227 if (copy_from_user(rdwr_pa, rdwr_arg.msgs,
228 rdwr_arg.nmsgs * sizeof(struct i2c_msg))) {
229 kfree(rdwr_pa);
230 return -EFAULT;
231 }
232
233 data_ptrs = kmalloc(rdwr_arg.nmsgs * sizeof(u8 __user *), GFP_KERNEL);
234 if (data_ptrs == NULL) {
235 kfree(rdwr_pa);
236 return -ENOMEM;
237 }
238
239 res = 0;
240 for (i = 0; i < rdwr_arg.nmsgs; i++) {
241 /* Limit the size of the message to a sane amount;
242 * and don't let length change either. */
243 if ((rdwr_pa[i].len > 8192) ||
244 (rdwr_pa[i].flags & I2C_M_RECV_LEN)) {
245 res = -EINVAL;
246 break;
247 }
248 data_ptrs[i] = (u8 __user *)rdwr_pa[i].buf;
249 rdwr_pa[i].buf = kmalloc(rdwr_pa[i].len, GFP_KERNEL);
250 if (rdwr_pa[i].buf == NULL) {
251 res = -ENOMEM;
252 break;
253 }
254 if (copy_from_user(rdwr_pa[i].buf, data_ptrs[i],
255 rdwr_pa[i].len)) {
256 ++i; /* Needs to be kfreed too */
257 res = -EFAULT;
258 break;
259 }
260 }
261 if (res < 0) {
262 int j;
263 for (j = 0; j < i; ++j)
264 kfree(rdwr_pa[j].buf);
265 kfree(data_ptrs);
266 kfree(rdwr_pa);
267 return res;
268 }
269
270 res = i2c_transfer(client->adapter, rdwr_pa, rdwr_arg.nmsgs);
271 while (i-- > 0) {
272 if (res >= 0 && (rdwr_pa[i].flags & I2C_M_RD)) {
273 if (copy_to_user(data_ptrs[i], rdwr_pa[i].buf,
274 rdwr_pa[i].len))
275 res = -EFAULT;
276 }
277 kfree(rdwr_pa[i].buf);
278 }
279 kfree(data_ptrs);
280 kfree(rdwr_pa);
281 return res;
282}
283
284static noinline int i2cdev_ioctl_smbus(struct i2c_client *client,
285 unsigned long arg)
286{
287 struct i2c_smbus_ioctl_data data_arg;
288 union i2c_smbus_data temp;
289 int datasize, res;
290
291 if (copy_from_user(&data_arg,
292 (struct i2c_smbus_ioctl_data __user *) arg,
293 sizeof(struct i2c_smbus_ioctl_data)))
294 return -EFAULT;
295 if ((data_arg.size != I2C_SMBUS_BYTE) &&
296 (data_arg.size != I2C_SMBUS_QUICK) &&
297 (data_arg.size != I2C_SMBUS_BYTE_DATA) &&
298 (data_arg.size != I2C_SMBUS_WORD_DATA) &&
299 (data_arg.size != I2C_SMBUS_PROC_CALL) &&
300 (data_arg.size != I2C_SMBUS_BLOCK_DATA) &&
301 (data_arg.size != I2C_SMBUS_I2C_BLOCK_BROKEN) &&
302 (data_arg.size != I2C_SMBUS_I2C_BLOCK_DATA) &&
303 (data_arg.size != I2C_SMBUS_BLOCK_PROC_CALL)) {
304 dev_dbg(&client->adapter->dev,
305 "size out of range (%x) in ioctl I2C_SMBUS.\n",
306 data_arg.size);
307 return -EINVAL;
308 }
309 /* Note that I2C_SMBUS_READ and I2C_SMBUS_WRITE are 0 and 1,
310 so the check is valid if size==I2C_SMBUS_QUICK too. */
311 if ((data_arg.read_write != I2C_SMBUS_READ) &&
312 (data_arg.read_write != I2C_SMBUS_WRITE)) {
313 dev_dbg(&client->adapter->dev,
314 "read_write out of range (%x) in ioctl I2C_SMBUS.\n",
315 data_arg.read_write);
316 return -EINVAL;
317 }
318
319 /* Note that command values are always valid! */
320
321 if ((data_arg.size == I2C_SMBUS_QUICK) ||
322 ((data_arg.size == I2C_SMBUS_BYTE) &&
323 (data_arg.read_write == I2C_SMBUS_WRITE)))
324 /* These are special: we do not use data */
325 return i2c_smbus_xfer(client->adapter, client->addr,
326 client->flags, data_arg.read_write,
327 data_arg.command, data_arg.size, NULL);
328
329 if (data_arg.data == NULL) {
330 dev_dbg(&client->adapter->dev,
331 "data is NULL pointer in ioctl I2C_SMBUS.\n");
332 return -EINVAL;
333 }
334
335 if ((data_arg.size == I2C_SMBUS_BYTE_DATA) ||
336 (data_arg.size == I2C_SMBUS_BYTE))
337 datasize = sizeof(data_arg.data->byte);
338 else if ((data_arg.size == I2C_SMBUS_WORD_DATA) ||
339 (data_arg.size == I2C_SMBUS_PROC_CALL))
340 datasize = sizeof(data_arg.data->word);
341 else /* size == smbus block, i2c block, or block proc. call */
342 datasize = sizeof(data_arg.data->block);
343
344 if ((data_arg.size == I2C_SMBUS_PROC_CALL) ||
345 (data_arg.size == I2C_SMBUS_BLOCK_PROC_CALL) ||
346 (data_arg.size == I2C_SMBUS_I2C_BLOCK_DATA) ||
347 (data_arg.read_write == I2C_SMBUS_WRITE)) {
348 if (copy_from_user(&temp, data_arg.data, datasize))
349 return -EFAULT;
350 }
351 if (data_arg.size == I2C_SMBUS_I2C_BLOCK_BROKEN) {
352 /* Convert old I2C block commands to the new
353 convention. This preserves binary compatibility. */
354 data_arg.size = I2C_SMBUS_I2C_BLOCK_DATA;
355 if (data_arg.read_write == I2C_SMBUS_READ)
356 temp.block[0] = I2C_SMBUS_BLOCK_MAX;
357 }
358 res = i2c_smbus_xfer(client->adapter, client->addr, client->flags,
359 data_arg.read_write, data_arg.command, data_arg.size, &temp);
360 if (!res && ((data_arg.size == I2C_SMBUS_PROC_CALL) ||
361 (data_arg.size == I2C_SMBUS_BLOCK_PROC_CALL) ||
362 (data_arg.read_write == I2C_SMBUS_READ))) {
363 if (copy_to_user(data_arg.data, &temp, datasize))
364 return -EFAULT;
365 }
366 return res;
367}
368
369static int i2cdev_ioctl(struct inode *inode, struct file *file,
370 unsigned int cmd, unsigned long arg)
371{
372 struct i2c_client *client = (struct i2c_client *)file->private_data;
213 unsigned long funcs; 373 unsigned long funcs;
214 374
215 dev_dbg(&client->adapter->dev, "ioctl, cmd=0x%02x, arg=0x%02lx\n", 375 dev_dbg(&client->adapter->dev, "ioctl, cmd=0x%02x, arg=0x%02lx\n",
@@ -253,164 +413,11 @@ static int i2cdev_ioctl(struct inode *inode, struct file *file,
253 return put_user(funcs, (unsigned long __user *)arg); 413 return put_user(funcs, (unsigned long __user *)arg);
254 414
255 case I2C_RDWR: 415 case I2C_RDWR:
256 if (copy_from_user(&rdwr_arg, 416 return i2cdev_ioctl_rdrw(client, arg);
257 (struct i2c_rdwr_ioctl_data __user *)arg,
258 sizeof(rdwr_arg)))
259 return -EFAULT;
260
261 /* Put an arbitrary limit on the number of messages that can
262 * be sent at once */
263 if (rdwr_arg.nmsgs > I2C_RDRW_IOCTL_MAX_MSGS)
264 return -EINVAL;
265
266 rdwr_pa = (struct i2c_msg *)
267 kmalloc(rdwr_arg.nmsgs * sizeof(struct i2c_msg),
268 GFP_KERNEL);
269
270 if (rdwr_pa == NULL) return -ENOMEM;
271
272 if (copy_from_user(rdwr_pa, rdwr_arg.msgs,
273 rdwr_arg.nmsgs * sizeof(struct i2c_msg))) {
274 kfree(rdwr_pa);
275 return -EFAULT;
276 }
277
278 data_ptrs = kmalloc(rdwr_arg.nmsgs * sizeof(u8 __user *), GFP_KERNEL);
279 if (data_ptrs == NULL) {
280 kfree(rdwr_pa);
281 return -ENOMEM;
282 }
283
284 res = 0;
285 for( i=0; i<rdwr_arg.nmsgs; i++ ) {
286 /* Limit the size of the message to a sane amount;
287 * and don't let length change either. */
288 if ((rdwr_pa[i].len > 8192) ||
289 (rdwr_pa[i].flags & I2C_M_RECV_LEN)) {
290 res = -EINVAL;
291 break;
292 }
293 data_ptrs[i] = (u8 __user *)rdwr_pa[i].buf;
294 rdwr_pa[i].buf = kmalloc(rdwr_pa[i].len, GFP_KERNEL);
295 if(rdwr_pa[i].buf == NULL) {
296 res = -ENOMEM;
297 break;
298 }
299 if(copy_from_user(rdwr_pa[i].buf,
300 data_ptrs[i],
301 rdwr_pa[i].len)) {
302 ++i; /* Needs to be kfreed too */
303 res = -EFAULT;
304 break;
305 }
306 }
307 if (res < 0) {
308 int j;
309 for (j = 0; j < i; ++j)
310 kfree(rdwr_pa[j].buf);
311 kfree(data_ptrs);
312 kfree(rdwr_pa);
313 return res;
314 }
315
316 res = i2c_transfer(client->adapter,
317 rdwr_pa,
318 rdwr_arg.nmsgs);
319 while(i-- > 0) {
320 if( res>=0 && (rdwr_pa[i].flags & I2C_M_RD)) {
321 if(copy_to_user(
322 data_ptrs[i],
323 rdwr_pa[i].buf,
324 rdwr_pa[i].len)) {
325 res = -EFAULT;
326 }
327 }
328 kfree(rdwr_pa[i].buf);
329 }
330 kfree(data_ptrs);
331 kfree(rdwr_pa);
332 return res;
333 417
334 case I2C_SMBUS: 418 case I2C_SMBUS:
335 if (copy_from_user(&data_arg, 419 return i2cdev_ioctl_smbus(client, arg);
336 (struct i2c_smbus_ioctl_data __user *) arg,
337 sizeof(struct i2c_smbus_ioctl_data)))
338 return -EFAULT;
339 if ((data_arg.size != I2C_SMBUS_BYTE) &&
340 (data_arg.size != I2C_SMBUS_QUICK) &&
341 (data_arg.size != I2C_SMBUS_BYTE_DATA) &&
342 (data_arg.size != I2C_SMBUS_WORD_DATA) &&
343 (data_arg.size != I2C_SMBUS_PROC_CALL) &&
344 (data_arg.size != I2C_SMBUS_BLOCK_DATA) &&
345 (data_arg.size != I2C_SMBUS_I2C_BLOCK_BROKEN) &&
346 (data_arg.size != I2C_SMBUS_I2C_BLOCK_DATA) &&
347 (data_arg.size != I2C_SMBUS_BLOCK_PROC_CALL)) {
348 dev_dbg(&client->adapter->dev,
349 "size out of range (%x) in ioctl I2C_SMBUS.\n",
350 data_arg.size);
351 return -EINVAL;
352 }
353 /* Note that I2C_SMBUS_READ and I2C_SMBUS_WRITE are 0 and 1,
354 so the check is valid if size==I2C_SMBUS_QUICK too. */
355 if ((data_arg.read_write != I2C_SMBUS_READ) &&
356 (data_arg.read_write != I2C_SMBUS_WRITE)) {
357 dev_dbg(&client->adapter->dev,
358 "read_write out of range (%x) in ioctl I2C_SMBUS.\n",
359 data_arg.read_write);
360 return -EINVAL;
361 }
362
363 /* Note that command values are always valid! */
364
365 if ((data_arg.size == I2C_SMBUS_QUICK) ||
366 ((data_arg.size == I2C_SMBUS_BYTE) &&
367 (data_arg.read_write == I2C_SMBUS_WRITE)))
368 /* These are special: we do not use data */
369 return i2c_smbus_xfer(client->adapter, client->addr,
370 client->flags,
371 data_arg.read_write,
372 data_arg.command,
373 data_arg.size, NULL);
374
375 if (data_arg.data == NULL) {
376 dev_dbg(&client->adapter->dev,
377 "data is NULL pointer in ioctl I2C_SMBUS.\n");
378 return -EINVAL;
379 }
380 420
381 if ((data_arg.size == I2C_SMBUS_BYTE_DATA) ||
382 (data_arg.size == I2C_SMBUS_BYTE))
383 datasize = sizeof(data_arg.data->byte);
384 else if ((data_arg.size == I2C_SMBUS_WORD_DATA) ||
385 (data_arg.size == I2C_SMBUS_PROC_CALL))
386 datasize = sizeof(data_arg.data->word);
387 else /* size == smbus block, i2c block, or block proc. call */
388 datasize = sizeof(data_arg.data->block);
389
390 if ((data_arg.size == I2C_SMBUS_PROC_CALL) ||
391 (data_arg.size == I2C_SMBUS_BLOCK_PROC_CALL) ||
392 (data_arg.size == I2C_SMBUS_I2C_BLOCK_DATA) ||
393 (data_arg.read_write == I2C_SMBUS_WRITE)) {
394 if (copy_from_user(&temp, data_arg.data, datasize))
395 return -EFAULT;
396 }
397 if (data_arg.size == I2C_SMBUS_I2C_BLOCK_BROKEN) {
398 /* Convert old I2C block commands to the new
399 convention. This preserves binary compatibility. */
400 data_arg.size = I2C_SMBUS_I2C_BLOCK_DATA;
401 if (data_arg.read_write == I2C_SMBUS_READ)
402 temp.block[0] = I2C_SMBUS_BLOCK_MAX;
403 }
404 res = i2c_smbus_xfer(client->adapter,client->addr,client->flags,
405 data_arg.read_write,
406 data_arg.command,data_arg.size,&temp);
407 if (! res && ((data_arg.size == I2C_SMBUS_PROC_CALL) ||
408 (data_arg.size == I2C_SMBUS_BLOCK_PROC_CALL) ||
409 (data_arg.read_write == I2C_SMBUS_READ))) {
410 if (copy_to_user(data_arg.data, &temp, datasize))
411 return -EFAULT;
412 }
413 return res;
414 case I2C_RETRIES: 421 case I2C_RETRIES:
415 client->adapter->retries = arg; 422 client->adapter->retries = arg;
416 break; 423 break;
diff --git a/drivers/infiniband/hw/ipath/Kconfig b/drivers/infiniband/hw/ipath/Kconfig
index 044da5828a78..3c7968f25ec2 100644
--- a/drivers/infiniband/hw/ipath/Kconfig
+++ b/drivers/infiniband/hw/ipath/Kconfig
@@ -1,6 +1,6 @@
1config INFINIBAND_IPATH 1config INFINIBAND_IPATH
2 tristate "QLogic InfiniPath Driver" 2 tristate "QLogic InfiniPath Driver"
3 depends on (PCI_MSI || HT_IRQ) && 64BIT && NET 3 depends on 64BIT && NET
4 ---help--- 4 ---help---
5 This is a driver for QLogic InfiniPath host channel adapters, 5 This is a driver for QLogic InfiniPath host channel adapters,
6 including InfiniBand verbs support. This driver allows these 6 including InfiniBand verbs support. This driver allows these
diff --git a/drivers/infiniband/hw/ipath/Makefile b/drivers/infiniband/hw/ipath/Makefile
index 75a6c91944c4..bf9450061986 100644
--- a/drivers/infiniband/hw/ipath/Makefile
+++ b/drivers/infiniband/hw/ipath/Makefile
@@ -29,11 +29,13 @@ ib_ipath-y := \
29 ipath_user_pages.o \ 29 ipath_user_pages.o \
30 ipath_user_sdma.o \ 30 ipath_user_sdma.o \
31 ipath_verbs_mcast.o \ 31 ipath_verbs_mcast.o \
32 ipath_verbs.o 32 ipath_verbs.o \
33 ipath_iba7220.o \
34 ipath_sd7220.o \
35 ipath_sd7220_img.o
33 36
34ib_ipath-$(CONFIG_HT_IRQ) += ipath_iba6110.o 37ib_ipath-$(CONFIG_HT_IRQ) += ipath_iba6110.o
35ib_ipath-$(CONFIG_PCI_MSI) += ipath_iba6120.o 38ib_ipath-$(CONFIG_PCI_MSI) += ipath_iba6120.o
36ib_ipath-$(CONFIG_PCI_MSI) += ipath_iba7220.o ipath_sd7220.o ipath_sd7220_img.o
37 39
38ib_ipath-$(CONFIG_X86_64) += ipath_wc_x86_64.o 40ib_ipath-$(CONFIG_X86_64) += ipath_wc_x86_64.o
39ib_ipath-$(CONFIG_PPC64) += ipath_wc_ppc64.o 41ib_ipath-$(CONFIG_PPC64) += ipath_wc_ppc64.o
diff --git a/drivers/infiniband/hw/ipath/ipath_driver.c b/drivers/infiniband/hw/ipath/ipath_driver.c
index e0a64f070b97..acf30c06a0c0 100644
--- a/drivers/infiniband/hw/ipath/ipath_driver.c
+++ b/drivers/infiniband/hw/ipath/ipath_driver.c
@@ -538,7 +538,7 @@ static int __devinit ipath_init_one(struct pci_dev *pdev,
538 case PCI_DEVICE_ID_INFINIPATH_7220: 538 case PCI_DEVICE_ID_INFINIPATH_7220:
539#ifndef CONFIG_PCI_MSI 539#ifndef CONFIG_PCI_MSI
540 ipath_dbg("CONFIG_PCI_MSI is not enabled, " 540 ipath_dbg("CONFIG_PCI_MSI is not enabled, "
541 "using IntX for unit %u\n", dd->ipath_unit); 541 "using INTx for unit %u\n", dd->ipath_unit);
542#endif 542#endif
543 ipath_init_iba7220_funcs(dd); 543 ipath_init_iba7220_funcs(dd);
544 break; 544 break;
diff --git a/drivers/infiniband/hw/ipath/ipath_iba7220.c b/drivers/infiniband/hw/ipath/ipath_iba7220.c
index 1b2de2cfb69b..e3ec0d1bdf50 100644
--- a/drivers/infiniband/hw/ipath/ipath_iba7220.c
+++ b/drivers/infiniband/hw/ipath/ipath_iba7220.c
@@ -1215,13 +1215,13 @@ static int ipath_msi_enabled(struct pci_dev *pdev)
1215 1215
1216/* 1216/*
1217 * disable msi interrupt if enabled, and clear the flag. 1217 * disable msi interrupt if enabled, and clear the flag.
1218 * flag is used primarily for the fallback to IntX, but 1218 * flag is used primarily for the fallback to INTx, but
1219 * is also used in reinit after reset as a flag. 1219 * is also used in reinit after reset as a flag.
1220 */ 1220 */
1221static void ipath_7220_nomsi(struct ipath_devdata *dd) 1221static void ipath_7220_nomsi(struct ipath_devdata *dd)
1222{ 1222{
1223 dd->ipath_msi_lo = 0; 1223 dd->ipath_msi_lo = 0;
1224#ifdef CONFIG_PCI_MSI 1224
1225 if (ipath_msi_enabled(dd->pcidev)) { 1225 if (ipath_msi_enabled(dd->pcidev)) {
1226 /* 1226 /*
1227 * free, but don't zero; later kernels require 1227 * free, but don't zero; later kernels require
@@ -1232,7 +1232,6 @@ static void ipath_7220_nomsi(struct ipath_devdata *dd)
1232 free_irq(dd->ipath_irq, dd); 1232 free_irq(dd->ipath_irq, dd);
1233 pci_disable_msi(dd->pcidev); 1233 pci_disable_msi(dd->pcidev);
1234 } 1234 }
1235#endif
1236} 1235}
1237 1236
1238/* 1237/*
@@ -1344,7 +1343,7 @@ static int ipath_setup_7220_config(struct ipath_devdata *dd,
1344 u32 boardrev; 1343 u32 boardrev;
1345 1344
1346 dd->ipath_msi_lo = 0; /* used as a flag during reset processing */ 1345 dd->ipath_msi_lo = 0; /* used as a flag during reset processing */
1347#ifdef CONFIG_PCI_MSI 1346
1348 pos = pci_find_capability(pdev, PCI_CAP_ID_MSI); 1347 pos = pci_find_capability(pdev, PCI_CAP_ID_MSI);
1349 if (!strcmp(int_type, "force_msi") || !strcmp(int_type, "auto")) 1348 if (!strcmp(int_type, "force_msi") || !strcmp(int_type, "auto"))
1350 ret = pci_enable_msi(pdev); 1349 ret = pci_enable_msi(pdev);
@@ -1377,10 +1376,6 @@ static int ipath_setup_7220_config(struct ipath_devdata *dd,
1377 } else 1376 } else
1378 ipath_dev_err(dd, "Can't find MSI capability, " 1377 ipath_dev_err(dd, "Can't find MSI capability, "
1379 "can't save MSI settings for reset\n"); 1378 "can't save MSI settings for reset\n");
1380#else
1381 ipath_dbg("PCI_MSI not configured, using IntX interrupts\n");
1382 ipath_enable_intx(pdev);
1383#endif
1384 1379
1385 dd->ipath_irq = pdev->irq; 1380 dd->ipath_irq = pdev->irq;
1386 1381
@@ -1583,7 +1578,7 @@ static void ipath_init_7220_variables(struct ipath_devdata *dd)
1583static int ipath_reinit_msi(struct ipath_devdata *dd) 1578static int ipath_reinit_msi(struct ipath_devdata *dd)
1584{ 1579{
1585 int ret = 0; 1580 int ret = 0;
1586#ifdef CONFIG_PCI_MSI 1581
1587 int pos; 1582 int pos;
1588 u16 control; 1583 u16 control;
1589 if (!dd->ipath_msi_lo) /* Using intX, or init problem */ 1584 if (!dd->ipath_msi_lo) /* Using intX, or init problem */
@@ -1617,10 +1612,10 @@ static int ipath_reinit_msi(struct ipath_devdata *dd)
1617 ((control & PCI_MSI_FLAGS_64BIT) ? 12 : 8), 1612 ((control & PCI_MSI_FLAGS_64BIT) ? 12 : 8),
1618 dd->ipath_msi_data); 1613 dd->ipath_msi_data);
1619 ret = 1; 1614 ret = 1;
1615
1620bail: 1616bail:
1621#endif
1622 if (!ret) { 1617 if (!ret) {
1623 ipath_dbg("Using IntX, MSI disabled or not configured\n"); 1618 ipath_dbg("Using INTx, MSI disabled or not configured\n");
1624 ipath_enable_intx(dd->pcidev); 1619 ipath_enable_intx(dd->pcidev);
1625 ret = 1; 1620 ret = 1;
1626 } 1621 }
@@ -2149,12 +2144,12 @@ static void ipath_7220_read_counters(struct ipath_devdata *dd,
2149 counters[i] = ipath_snap_cntr(dd, i); 2144 counters[i] = ipath_snap_cntr(dd, i);
2150} 2145}
2151 2146
2152/* if we are using MSI, try to fallback to IntX */ 2147/* if we are using MSI, try to fallback to INTx */
2153static int ipath_7220_intr_fallback(struct ipath_devdata *dd) 2148static int ipath_7220_intr_fallback(struct ipath_devdata *dd)
2154{ 2149{
2155 if (dd->ipath_msi_lo) { 2150 if (dd->ipath_msi_lo) {
2156 dev_info(&dd->pcidev->dev, "MSI interrupt not detected," 2151 dev_info(&dd->pcidev->dev, "MSI interrupt not detected,"
2157 " trying IntX interrupts\n"); 2152 " trying INTx interrupts\n");
2158 ipath_7220_nomsi(dd); 2153 ipath_7220_nomsi(dd);
2159 ipath_enable_intx(dd->pcidev); 2154 ipath_enable_intx(dd->pcidev);
2160 /* 2155 /*
@@ -2167,7 +2162,7 @@ static int ipath_7220_intr_fallback(struct ipath_devdata *dd)
2167 if (request_irq(dd->ipath_irq, ipath_intr, IRQF_SHARED, 2162 if (request_irq(dd->ipath_irq, ipath_intr, IRQF_SHARED,
2168 IPATH_DRV_NAME, dd)) 2163 IPATH_DRV_NAME, dd))
2169 ipath_dev_err(dd, 2164 ipath_dev_err(dd,
2170 "Could not re-request_irq for IntX\n"); 2165 "Could not re-request_irq for INTx\n");
2171 return 1; 2166 return 1;
2172 } 2167 }
2173 return 0; 2168 return 0;
diff --git a/drivers/infiniband/hw/ipath/ipath_verbs.c b/drivers/infiniband/hw/ipath/ipath_verbs.c
index c38f9aa8be8d..e63927cce5b5 100644
--- a/drivers/infiniband/hw/ipath/ipath_verbs.c
+++ b/drivers/infiniband/hw/ipath/ipath_verbs.c
@@ -109,7 +109,7 @@ MODULE_PARM_DESC(max_srq_wrs, "Maximum number of SRQ WRs support");
109 109
110static unsigned int ib_ipath_disable_sma; 110static unsigned int ib_ipath_disable_sma;
111module_param_named(disable_sma, ib_ipath_disable_sma, uint, S_IWUSR | S_IRUGO); 111module_param_named(disable_sma, ib_ipath_disable_sma, uint, S_IWUSR | S_IRUGO);
112MODULE_PARM_DESC(ib_ipath_disable_sma, "Disable the SMA"); 112MODULE_PARM_DESC(disable_sma, "Disable the SMA");
113 113
114const int ib_ipath_state_ops[IB_QPS_ERR + 1] = { 114const int ib_ipath_state_ops[IB_QPS_ERR + 1] = {
115 [IB_QPS_RESET] = 0, 115 [IB_QPS_RESET] = 0,
@@ -2067,7 +2067,6 @@ int ipath_register_ib_device(struct ipath_devdata *dd)
2067 dev->phys_port_cnt = 1; 2067 dev->phys_port_cnt = 1;
2068 dev->num_comp_vectors = 1; 2068 dev->num_comp_vectors = 1;
2069 dev->dma_device = &dd->pcidev->dev; 2069 dev->dma_device = &dd->pcidev->dev;
2070 dev->class_dev.dev = dev->dma_device;
2071 dev->query_device = ipath_query_device; 2070 dev->query_device = ipath_query_device;
2072 dev->modify_device = ipath_modify_device; 2071 dev->modify_device = ipath_modify_device;
2073 dev->query_port = ipath_query_port; 2072 dev->query_port = ipath_query_port;
diff --git a/drivers/infiniband/hw/nes/nes.c b/drivers/infiniband/hw/nes/nes.c
index b00b0e3a91dc..b046262ed638 100644
--- a/drivers/infiniband/hw/nes/nes.c
+++ b/drivers/infiniband/hw/nes/nes.c
@@ -96,12 +96,6 @@ static LIST_HEAD(nes_dev_list);
96 96
97atomic_t qps_destroyed; 97atomic_t qps_destroyed;
98 98
99static void nes_print_macaddr(struct net_device *netdev);
100static irqreturn_t nes_interrupt(int, void *);
101static int __devinit nes_probe(struct pci_dev *, const struct pci_device_id *);
102static void __devexit nes_remove(struct pci_dev *);
103static int __init nes_init_module(void);
104static void __exit nes_exit_module(void);
105static unsigned int ee_flsh_adapter; 99static unsigned int ee_flsh_adapter;
106static unsigned int sysfs_nonidx_addr; 100static unsigned int sysfs_nonidx_addr;
107static unsigned int sysfs_idx_addr; 101static unsigned int sysfs_idx_addr;
diff --git a/drivers/infiniband/hw/nes/nes_nic.c b/drivers/infiniband/hw/nes/nes_nic.c
index 34166641f207..01cd0effc492 100644
--- a/drivers/infiniband/hw/nes/nes_nic.c
+++ b/drivers/infiniband/hw/nes/nes_nic.c
@@ -92,15 +92,6 @@ static const u32 default_msg = NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_LINK
92 | NETIF_MSG_IFUP | NETIF_MSG_IFDOWN; 92 | NETIF_MSG_IFUP | NETIF_MSG_IFDOWN;
93static int debug = -1; 93static int debug = -1;
94 94
95
96static int nes_netdev_open(struct net_device *);
97static int nes_netdev_stop(struct net_device *);
98static int nes_netdev_start_xmit(struct sk_buff *, struct net_device *);
99static struct net_device_stats *nes_netdev_get_stats(struct net_device *);
100static void nes_netdev_tx_timeout(struct net_device *);
101static int nes_netdev_set_mac_address(struct net_device *, void *);
102static int nes_netdev_change_mtu(struct net_device *, int);
103
104/** 95/**
105 * nes_netdev_poll 96 * nes_netdev_poll
106 */ 97 */
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index b96667448eb5..01ced4c5a61d 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -35,10 +35,6 @@
35#include "sd_ops.h" 35#include "sd_ops.h"
36#include "sdio_ops.h" 36#include "sdio_ops.h"
37 37
38extern int mmc_attach_mmc(struct mmc_host *host, u32 ocr);
39extern int mmc_attach_sd(struct mmc_host *host, u32 ocr);
40extern int mmc_attach_sdio(struct mmc_host *host, u32 ocr);
41
42static struct workqueue_struct *workqueue; 38static struct workqueue_struct *workqueue;
43 39
44/* 40/*
@@ -516,7 +512,7 @@ static void mmc_power_off(struct mmc_host *host)
516/* 512/*
517 * Cleanup when the last reference to the bus operator is dropped. 513 * Cleanup when the last reference to the bus operator is dropped.
518 */ 514 */
519void __mmc_release_bus(struct mmc_host *host) 515static void __mmc_release_bus(struct mmc_host *host)
520{ 516{
521 BUG_ON(!host); 517 BUG_ON(!host);
522 BUG_ON(host->bus_refs); 518 BUG_ON(host->bus_refs);
diff --git a/drivers/mmc/core/core.h b/drivers/mmc/core/core.h
index cfa8e15b5923..cdb332b7dedc 100644
--- a/drivers/mmc/core/core.h
+++ b/drivers/mmc/core/core.h
@@ -46,6 +46,10 @@ void mmc_rescan(struct work_struct *work);
46void mmc_start_host(struct mmc_host *host); 46void mmc_start_host(struct mmc_host *host);
47void mmc_stop_host(struct mmc_host *host); 47void mmc_stop_host(struct mmc_host *host);
48 48
49int mmc_attach_mmc(struct mmc_host *host, u32 ocr);
50int mmc_attach_sd(struct mmc_host *host, u32 ocr);
51int mmc_attach_sdio(struct mmc_host *host, u32 ocr);
52
49extern int use_spi_crc; 53extern int use_spi_crc;
50 54
51#endif 55#endif
diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c
index c65d203a846d..1d795c5379b5 100644
--- a/drivers/mmc/core/host.c
+++ b/drivers/mmc/core/host.c
@@ -2,7 +2,7 @@
2 * linux/drivers/mmc/core/host.c 2 * linux/drivers/mmc/core/host.c
3 * 3 *
4 * Copyright (C) 2003 Russell King, All Rights Reserved. 4 * Copyright (C) 2003 Russell King, All Rights Reserved.
5 * Copyright (C) 2007 Pierre Ossman 5 * Copyright (C) 2007-2008 Pierre Ossman
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 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 8 * it under the terms of the GNU General Public License version 2 as
@@ -57,12 +57,25 @@ static DEFINE_SPINLOCK(mmc_host_lock);
57 */ 57 */
58struct mmc_host *mmc_alloc_host(int extra, struct device *dev) 58struct mmc_host *mmc_alloc_host(int extra, struct device *dev)
59{ 59{
60 int err;
60 struct mmc_host *host; 61 struct mmc_host *host;
61 62
63 if (!idr_pre_get(&mmc_host_idr, GFP_KERNEL))
64 return NULL;
65
62 host = kzalloc(sizeof(struct mmc_host) + extra, GFP_KERNEL); 66 host = kzalloc(sizeof(struct mmc_host) + extra, GFP_KERNEL);
63 if (!host) 67 if (!host)
64 return NULL; 68 return NULL;
65 69
70 spin_lock(&mmc_host_lock);
71 err = idr_get_new(&mmc_host_idr, host, &host->index);
72 spin_unlock(&mmc_host_lock);
73 if (err)
74 goto free;
75
76 snprintf(host->class_dev.bus_id, BUS_ID_SIZE,
77 "mmc%d", host->index);
78
66 host->parent = dev; 79 host->parent = dev;
67 host->class_dev.parent = dev; 80 host->class_dev.parent = dev;
68 host->class_dev.class = &mmc_host_class; 81 host->class_dev.class = &mmc_host_class;
@@ -85,6 +98,10 @@ struct mmc_host *mmc_alloc_host(int extra, struct device *dev)
85 host->max_blk_count = PAGE_CACHE_SIZE / 512; 98 host->max_blk_count = PAGE_CACHE_SIZE / 512;
86 99
87 return host; 100 return host;
101
102free:
103 kfree(host);
104 return NULL;
88} 105}
89 106
90EXPORT_SYMBOL(mmc_alloc_host); 107EXPORT_SYMBOL(mmc_alloc_host);
@@ -104,18 +121,6 @@ int mmc_add_host(struct mmc_host *host)
104 WARN_ON((host->caps & MMC_CAP_SDIO_IRQ) && 121 WARN_ON((host->caps & MMC_CAP_SDIO_IRQ) &&
105 !host->ops->enable_sdio_irq); 122 !host->ops->enable_sdio_irq);
106 123
107 if (!idr_pre_get(&mmc_host_idr, GFP_KERNEL))
108 return -ENOMEM;
109
110 spin_lock(&mmc_host_lock);
111 err = idr_get_new(&mmc_host_idr, host, &host->index);
112 spin_unlock(&mmc_host_lock);
113 if (err)
114 return err;
115
116 snprintf(host->class_dev.bus_id, BUS_ID_SIZE,
117 "mmc%d", host->index);
118
119 led_trigger_register_simple(host->class_dev.bus_id, &host->led); 124 led_trigger_register_simple(host->class_dev.bus_id, &host->led);
120 125
121 err = device_add(&host->class_dev); 126 err = device_add(&host->class_dev);
@@ -144,10 +149,6 @@ void mmc_remove_host(struct mmc_host *host)
144 device_del(&host->class_dev); 149 device_del(&host->class_dev);
145 150
146 led_trigger_unregister_simple(host->led); 151 led_trigger_unregister_simple(host->led);
147
148 spin_lock(&mmc_host_lock);
149 idr_remove(&mmc_host_idr, host->index);
150 spin_unlock(&mmc_host_lock);
151} 152}
152 153
153EXPORT_SYMBOL(mmc_remove_host); 154EXPORT_SYMBOL(mmc_remove_host);
@@ -160,6 +161,10 @@ EXPORT_SYMBOL(mmc_remove_host);
160 */ 161 */
161void mmc_free_host(struct mmc_host *host) 162void mmc_free_host(struct mmc_host *host)
162{ 163{
164 spin_lock(&mmc_host_lock);
165 idr_remove(&mmc_host_idr, host->index);
166 spin_unlock(&mmc_host_lock);
167
163 put_device(&host->class_dev); 168 put_device(&host->class_dev);
164} 169}
165 170
diff --git a/drivers/mmc/core/sdio_irq.c b/drivers/mmc/core/sdio_irq.c
index 3bd3021f5e80..c292e124107a 100644
--- a/drivers/mmc/core/sdio_irq.c
+++ b/drivers/mmc/core/sdio_irq.c
@@ -128,12 +128,12 @@ static int sdio_irq_thread(void *_host)
128 } 128 }
129 } 129 }
130 130
131 set_task_state(current, TASK_INTERRUPTIBLE); 131 set_current_state(TASK_INTERRUPTIBLE);
132 if (host->caps & MMC_CAP_SDIO_IRQ) 132 if (host->caps & MMC_CAP_SDIO_IRQ)
133 host->ops->enable_sdio_irq(host, 1); 133 host->ops->enable_sdio_irq(host, 1);
134 if (!kthread_should_stop()) 134 if (!kthread_should_stop())
135 schedule_timeout(period); 135 schedule_timeout(period);
136 set_task_state(current, TASK_RUNNING); 136 set_current_state(TASK_RUNNING);
137 } while (!kthread_should_stop()); 137 } while (!kthread_should_stop());
138 138
139 if (host->caps & MMC_CAP_SDIO_IRQ) 139 if (host->caps & MMC_CAP_SDIO_IRQ)
diff --git a/drivers/mmc/core/sdio_ops.c b/drivers/mmc/core/sdio_ops.c
index e1fca588e385..c8fa095a4488 100644
--- a/drivers/mmc/core/sdio_ops.c
+++ b/drivers/mmc/core/sdio_ops.c
@@ -17,6 +17,7 @@
17#include <linux/mmc/sdio.h> 17#include <linux/mmc/sdio.h>
18 18
19#include "core.h" 19#include "core.h"
20#include "sdio_ops.h"
20 21
21int mmc_send_io_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr) 22int mmc_send_io_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr)
22{ 23{
diff --git a/drivers/mmc/host/omap.c b/drivers/mmc/host/omap.c
index 90c358b57d1c..14759e9f42ad 100644
--- a/drivers/mmc/host/omap.c
+++ b/drivers/mmc/host/omap.c
@@ -32,6 +32,7 @@
32#include <asm/mach-types.h> 32#include <asm/mach-types.h>
33 33
34#include <asm/arch/board.h> 34#include <asm/arch/board.h>
35#include <asm/arch/mmc.h>
35#include <asm/arch/gpio.h> 36#include <asm/arch/gpio.h>
36#include <asm/arch/dma.h> 37#include <asm/arch/dma.h>
37#include <asm/arch/mux.h> 38#include <asm/arch/mux.h>
@@ -93,9 +94,27 @@
93 94
94/* Specifies how often in millisecs to poll for card status changes 95/* Specifies how often in millisecs to poll for card status changes
95 * when the cover switch is open */ 96 * when the cover switch is open */
96#define OMAP_MMC_SWITCH_POLL_DELAY 500 97#define OMAP_MMC_COVER_POLL_DELAY 500
97 98
98static int mmc_omap_enable_poll = 1; 99struct mmc_omap_host;
100
101struct mmc_omap_slot {
102 int id;
103 unsigned int vdd;
104 u16 saved_con;
105 u16 bus_mode;
106 unsigned int fclk_freq;
107 unsigned powered:1;
108
109 struct tasklet_struct cover_tasklet;
110 struct timer_list cover_timer;
111 unsigned cover_open;
112
113 struct mmc_request *mrq;
114 struct mmc_omap_host *host;
115 struct mmc_host *mmc;
116 struct omap_mmc_slot_data *pdata;
117};
99 118
100struct mmc_omap_host { 119struct mmc_omap_host {
101 int initialized; 120 int initialized;
@@ -115,6 +134,15 @@ struct mmc_omap_host {
115 unsigned char bus_mode; 134 unsigned char bus_mode;
116 unsigned char hw_bus_mode; 135 unsigned char hw_bus_mode;
117 136
137 struct work_struct cmd_abort_work;
138 unsigned abort:1;
139 struct timer_list cmd_abort_timer;
140
141 struct work_struct slot_release_work;
142 struct mmc_omap_slot *next_slot;
143 struct work_struct send_stop_work;
144 struct mmc_data *stop_data;
145
118 unsigned int sg_len; 146 unsigned int sg_len;
119 int sg_idx; 147 int sg_idx;
120 u16 * buffer; 148 u16 * buffer;
@@ -131,63 +159,178 @@ struct mmc_omap_host {
131 unsigned dma_len; 159 unsigned dma_len;
132 160
133 short power_pin; 161 short power_pin;
134 short wp_pin;
135 162
136 int switch_pin; 163 struct mmc_omap_slot *slots[OMAP_MMC_MAX_SLOTS];
137 struct work_struct switch_work; 164 struct mmc_omap_slot *current_slot;
138 struct timer_list switch_timer; 165 spinlock_t slot_lock;
139 int switch_last_state; 166 wait_queue_head_t slot_wq;
167 int nr_slots;
168
169 struct timer_list clk_timer;
170 spinlock_t clk_lock; /* for changing enabled state */
171 unsigned int fclk_enabled:1;
172
173 struct omap_mmc_platform_data *pdata;
140}; 174};
141 175
142static inline int 176void mmc_omap_fclk_offdelay(struct mmc_omap_slot *slot)
143mmc_omap_cover_is_open(struct mmc_omap_host *host)
144{ 177{
145 if (host->switch_pin < 0) 178 unsigned long tick_ns;
146 return 0; 179
147 return omap_get_gpio_datain(host->switch_pin); 180 if (slot != NULL && slot->host->fclk_enabled && slot->fclk_freq > 0) {
181 tick_ns = (1000000000 + slot->fclk_freq - 1) / slot->fclk_freq;
182 ndelay(8 * tick_ns);
183 }
148} 184}
149 185
150static ssize_t 186void mmc_omap_fclk_enable(struct mmc_omap_host *host, unsigned int enable)
151mmc_omap_show_cover_switch(struct device *dev,
152 struct device_attribute *attr, char *buf)
153{ 187{
154 struct mmc_omap_host *host = dev_get_drvdata(dev); 188 unsigned long flags;
155 189
156 return sprintf(buf, "%s\n", mmc_omap_cover_is_open(host) ? "open" : 190 spin_lock_irqsave(&host->clk_lock, flags);
157 "closed"); 191 if (host->fclk_enabled != enable) {
192 host->fclk_enabled = enable;
193 if (enable)
194 clk_enable(host->fclk);
195 else
196 clk_disable(host->fclk);
197 }
198 spin_unlock_irqrestore(&host->clk_lock, flags);
158} 199}
159 200
160static DEVICE_ATTR(cover_switch, S_IRUGO, mmc_omap_show_cover_switch, NULL); 201static void mmc_omap_select_slot(struct mmc_omap_slot *slot, int claimed)
202{
203 struct mmc_omap_host *host = slot->host;
204 unsigned long flags;
161 205
162static ssize_t 206 if (claimed)
163mmc_omap_show_enable_poll(struct device *dev, 207 goto no_claim;
164 struct device_attribute *attr, char *buf) 208 spin_lock_irqsave(&host->slot_lock, flags);
209 while (host->mmc != NULL) {
210 spin_unlock_irqrestore(&host->slot_lock, flags);
211 wait_event(host->slot_wq, host->mmc == NULL);
212 spin_lock_irqsave(&host->slot_lock, flags);
213 }
214 host->mmc = slot->mmc;
215 spin_unlock_irqrestore(&host->slot_lock, flags);
216no_claim:
217 del_timer(&host->clk_timer);
218 if (host->current_slot != slot || !claimed)
219 mmc_omap_fclk_offdelay(host->current_slot);
220
221 if (host->current_slot != slot) {
222 OMAP_MMC_WRITE(host, CON, slot->saved_con & 0xFC00);
223 if (host->pdata->switch_slot != NULL)
224 host->pdata->switch_slot(mmc_dev(slot->mmc), slot->id);
225 host->current_slot = slot;
226 }
227
228 if (claimed) {
229 mmc_omap_fclk_enable(host, 1);
230
231 /* Doing the dummy read here seems to work around some bug
232 * at least in OMAP24xx silicon where the command would not
233 * start after writing the CMD register. Sigh. */
234 OMAP_MMC_READ(host, CON);
235
236 OMAP_MMC_WRITE(host, CON, slot->saved_con);
237 } else
238 mmc_omap_fclk_enable(host, 0);
239}
240
241static void mmc_omap_start_request(struct mmc_omap_host *host,
242 struct mmc_request *req);
243
244static void mmc_omap_slot_release_work(struct work_struct *work)
165{ 245{
166 return snprintf(buf, PAGE_SIZE, "%d\n", mmc_omap_enable_poll); 246 struct mmc_omap_host *host = container_of(work, struct mmc_omap_host,
247 slot_release_work);
248 struct mmc_omap_slot *next_slot = host->next_slot;
249 struct mmc_request *rq;
250
251 host->next_slot = NULL;
252 mmc_omap_select_slot(next_slot, 1);
253
254 rq = next_slot->mrq;
255 next_slot->mrq = NULL;
256 mmc_omap_start_request(host, rq);
167} 257}
168 258
169static ssize_t 259static void mmc_omap_release_slot(struct mmc_omap_slot *slot, int clk_enabled)
170mmc_omap_store_enable_poll(struct device *dev,
171 struct device_attribute *attr, const char *buf,
172 size_t size)
173{ 260{
174 int enable_poll; 261 struct mmc_omap_host *host = slot->host;
262 unsigned long flags;
263 int i;
264
265 BUG_ON(slot == NULL || host->mmc == NULL);
266
267 if (clk_enabled)
268 /* Keeps clock running for at least 8 cycles on valid freq */
269 mod_timer(&host->clk_timer, jiffies + HZ/10);
270 else {
271 del_timer(&host->clk_timer);
272 mmc_omap_fclk_offdelay(slot);
273 mmc_omap_fclk_enable(host, 0);
274 }
175 275
176 if (sscanf(buf, "%10d", &enable_poll) != 1) 276 spin_lock_irqsave(&host->slot_lock, flags);
177 return -EINVAL; 277 /* Check for any pending requests */
278 for (i = 0; i < host->nr_slots; i++) {
279 struct mmc_omap_slot *new_slot;
178 280
179 if (enable_poll != mmc_omap_enable_poll) { 281 if (host->slots[i] == NULL || host->slots[i]->mrq == NULL)
180 struct mmc_omap_host *host = dev_get_drvdata(dev); 282 continue;
181 283
182 mmc_omap_enable_poll = enable_poll; 284 BUG_ON(host->next_slot != NULL);
183 if (enable_poll && host->switch_pin >= 0) 285 new_slot = host->slots[i];
184 schedule_work(&host->switch_work); 286 /* The current slot should not have a request in queue */
287 BUG_ON(new_slot == host->current_slot);
288
289 host->next_slot = new_slot;
290 host->mmc = new_slot->mmc;
291 spin_unlock_irqrestore(&host->slot_lock, flags);
292 schedule_work(&host->slot_release_work);
293 return;
185 } 294 }
186 return size; 295
296 host->mmc = NULL;
297 wake_up(&host->slot_wq);
298 spin_unlock_irqrestore(&host->slot_lock, flags);
299}
300
301static inline
302int mmc_omap_cover_is_open(struct mmc_omap_slot *slot)
303{
304 if (slot->pdata->get_cover_state)
305 return slot->pdata->get_cover_state(mmc_dev(slot->mmc),
306 slot->id);
307 return 0;
308}
309
310static ssize_t
311mmc_omap_show_cover_switch(struct device *dev, struct device_attribute *attr,
312 char *buf)
313{
314 struct mmc_host *mmc = container_of(dev, struct mmc_host, class_dev);
315 struct mmc_omap_slot *slot = mmc_priv(mmc);
316
317 return sprintf(buf, "%s\n", mmc_omap_cover_is_open(slot) ? "open" :
318 "closed");
187} 319}
188 320
189static DEVICE_ATTR(enable_poll, 0664, 321static DEVICE_ATTR(cover_switch, S_IRUGO, mmc_omap_show_cover_switch, NULL);
190 mmc_omap_show_enable_poll, mmc_omap_store_enable_poll); 322
323static ssize_t
324mmc_omap_show_slot_name(struct device *dev, struct device_attribute *attr,
325 char *buf)
326{
327 struct mmc_host *mmc = container_of(dev, struct mmc_host, class_dev);
328 struct mmc_omap_slot *slot = mmc_priv(mmc);
329
330 return sprintf(buf, "%s\n", slot->pdata->name);
331}
332
333static DEVICE_ATTR(slot_name, S_IRUGO, mmc_omap_show_slot_name, NULL);
191 334
192static void 335static void
193mmc_omap_start_command(struct mmc_omap_host *host, struct mmc_command *cmd) 336mmc_omap_start_command(struct mmc_omap_host *host, struct mmc_command *cmd)
@@ -233,7 +376,7 @@ mmc_omap_start_command(struct mmc_omap_host *host, struct mmc_command *cmd)
233 376
234 cmdreg = cmd->opcode | (resptype << 8) | (cmdtype << 12); 377 cmdreg = cmd->opcode | (resptype << 8) | (cmdtype << 12);
235 378
236 if (host->bus_mode == MMC_BUSMODE_OPENDRAIN) 379 if (host->current_slot->bus_mode == MMC_BUSMODE_OPENDRAIN)
237 cmdreg |= 1 << 6; 380 cmdreg |= 1 << 6;
238 381
239 if (cmd->flags & MMC_RSP_BUSY) 382 if (cmd->flags & MMC_RSP_BUSY)
@@ -242,7 +385,7 @@ mmc_omap_start_command(struct mmc_omap_host *host, struct mmc_command *cmd)
242 if (host->data && !(host->data->flags & MMC_DATA_WRITE)) 385 if (host->data && !(host->data->flags & MMC_DATA_WRITE))
243 cmdreg |= 1 << 15; 386 cmdreg |= 1 << 15;
244 387
245 clk_enable(host->fclk); 388 mod_timer(&host->cmd_abort_timer, jiffies + HZ/2);
246 389
247 OMAP_MMC_WRITE(host, CTO, 200); 390 OMAP_MMC_WRITE(host, CTO, 200);
248 OMAP_MMC_WRITE(host, ARGL, cmd->arg & 0xffff); 391 OMAP_MMC_WRITE(host, ARGL, cmd->arg & 0xffff);
@@ -257,26 +400,46 @@ mmc_omap_start_command(struct mmc_omap_host *host, struct mmc_command *cmd)
257} 400}
258 401
259static void 402static void
403mmc_omap_release_dma(struct mmc_omap_host *host, struct mmc_data *data,
404 int abort)
405{
406 enum dma_data_direction dma_data_dir;
407
408 BUG_ON(host->dma_ch < 0);
409 if (data->error)
410 omap_stop_dma(host->dma_ch);
411 /* Release DMA channel lazily */
412 mod_timer(&host->dma_timer, jiffies + HZ);
413 if (data->flags & MMC_DATA_WRITE)
414 dma_data_dir = DMA_TO_DEVICE;
415 else
416 dma_data_dir = DMA_FROM_DEVICE;
417 dma_unmap_sg(mmc_dev(host->mmc), data->sg, host->sg_len,
418 dma_data_dir);
419}
420
421static void mmc_omap_send_stop_work(struct work_struct *work)
422{
423 struct mmc_omap_host *host = container_of(work, struct mmc_omap_host,
424 send_stop_work);
425 struct mmc_omap_slot *slot = host->current_slot;
426 struct mmc_data *data = host->stop_data;
427 unsigned long tick_ns;
428
429 tick_ns = (1000000000 + slot->fclk_freq - 1)/slot->fclk_freq;
430 ndelay(8*tick_ns);
431
432 mmc_omap_start_command(host, data->stop);
433}
434
435static void
260mmc_omap_xfer_done(struct mmc_omap_host *host, struct mmc_data *data) 436mmc_omap_xfer_done(struct mmc_omap_host *host, struct mmc_data *data)
261{ 437{
262 if (host->dma_in_use) { 438 if (host->dma_in_use)
263 enum dma_data_direction dma_data_dir; 439 mmc_omap_release_dma(host, data, data->error);
264 440
265 BUG_ON(host->dma_ch < 0);
266 if (data->error)
267 omap_stop_dma(host->dma_ch);
268 /* Release DMA channel lazily */
269 mod_timer(&host->dma_timer, jiffies + HZ);
270 if (data->flags & MMC_DATA_WRITE)
271 dma_data_dir = DMA_TO_DEVICE;
272 else
273 dma_data_dir = DMA_FROM_DEVICE;
274 dma_unmap_sg(mmc_dev(host->mmc), data->sg, host->sg_len,
275 dma_data_dir);
276 }
277 host->data = NULL; 441 host->data = NULL;
278 host->sg_len = 0; 442 host->sg_len = 0;
279 clk_disable(host->fclk);
280 443
281 /* NOTE: MMC layer will sometimes poll-wait CMD13 next, issuing 444 /* NOTE: MMC layer will sometimes poll-wait CMD13 next, issuing
282 * dozens of requests until the card finishes writing data. 445 * dozens of requests until the card finishes writing data.
@@ -284,12 +447,58 @@ mmc_omap_xfer_done(struct mmc_omap_host *host, struct mmc_data *data)
284 */ 447 */
285 448
286 if (!data->stop) { 449 if (!data->stop) {
450 struct mmc_host *mmc;
451
287 host->mrq = NULL; 452 host->mrq = NULL;
288 mmc_request_done(host->mmc, data->mrq); 453 mmc = host->mmc;
454 mmc_omap_release_slot(host->current_slot, 1);
455 mmc_request_done(mmc, data->mrq);
289 return; 456 return;
290 } 457 }
291 458
292 mmc_omap_start_command(host, data->stop); 459 host->stop_data = data;
460 schedule_work(&host->send_stop_work);
461}
462
463static void
464mmc_omap_send_abort(struct mmc_omap_host *host, int maxloops)
465{
466 struct mmc_omap_slot *slot = host->current_slot;
467 unsigned int restarts, passes, timeout;
468 u16 stat = 0;
469
470 /* Sending abort takes 80 clocks. Have some extra and round up */
471 timeout = (120*1000000 + slot->fclk_freq - 1)/slot->fclk_freq;
472 restarts = 0;
473 while (restarts < maxloops) {
474 OMAP_MMC_WRITE(host, STAT, 0xFFFF);
475 OMAP_MMC_WRITE(host, CMD, (3 << 12) | (1 << 7));
476
477 passes = 0;
478 while (passes < timeout) {
479 stat = OMAP_MMC_READ(host, STAT);
480 if (stat & OMAP_MMC_STAT_END_OF_CMD)
481 goto out;
482 udelay(1);
483 passes++;
484 }
485
486 restarts++;
487 }
488out:
489 OMAP_MMC_WRITE(host, STAT, stat);
490}
491
492static void
493mmc_omap_abort_xfer(struct mmc_omap_host *host, struct mmc_data *data)
494{
495 if (host->dma_in_use)
496 mmc_omap_release_dma(host, data, 1);
497
498 host->data = NULL;
499 host->sg_len = 0;
500
501 mmc_omap_send_abort(host, 10000);
293} 502}
294 503
295static void 504static void
@@ -345,6 +554,8 @@ mmc_omap_cmd_done(struct mmc_omap_host *host, struct mmc_command *cmd)
345{ 554{
346 host->cmd = NULL; 555 host->cmd = NULL;
347 556
557 del_timer(&host->cmd_abort_timer);
558
348 if (cmd->flags & MMC_RSP_PRESENT) { 559 if (cmd->flags & MMC_RSP_PRESENT) {
349 if (cmd->flags & MMC_RSP_136) { 560 if (cmd->flags & MMC_RSP_136) {
350 /* response type 2 */ 561 /* response type 2 */
@@ -369,10 +580,66 @@ mmc_omap_cmd_done(struct mmc_omap_host *host, struct mmc_command *cmd)
369 } 580 }
370 581
371 if (host->data == NULL || cmd->error) { 582 if (host->data == NULL || cmd->error) {
583 struct mmc_host *mmc;
584
585 if (host->data != NULL)
586 mmc_omap_abort_xfer(host, host->data);
372 host->mrq = NULL; 587 host->mrq = NULL;
373 clk_disable(host->fclk); 588 mmc = host->mmc;
374 mmc_request_done(host->mmc, cmd->mrq); 589 mmc_omap_release_slot(host->current_slot, 1);
590 mmc_request_done(mmc, cmd->mrq);
591 }
592}
593
594/*
595 * Abort stuck command. Can occur when card is removed while it is being
596 * read.
597 */
598static void mmc_omap_abort_command(struct work_struct *work)
599{
600 struct mmc_omap_host *host = container_of(work, struct mmc_omap_host,
601 cmd_abort_work);
602 BUG_ON(!host->cmd);
603
604 dev_dbg(mmc_dev(host->mmc), "Aborting stuck command CMD%d\n",
605 host->cmd->opcode);
606
607 if (host->cmd->error == 0)
608 host->cmd->error = -ETIMEDOUT;
609
610 if (host->data == NULL) {
611 struct mmc_command *cmd;
612 struct mmc_host *mmc;
613
614 cmd = host->cmd;
615 host->cmd = NULL;
616 mmc_omap_send_abort(host, 10000);
617
618 host->mrq = NULL;
619 mmc = host->mmc;
620 mmc_omap_release_slot(host->current_slot, 1);
621 mmc_request_done(mmc, cmd->mrq);
622 } else
623 mmc_omap_cmd_done(host, host->cmd);
624
625 host->abort = 0;
626 enable_irq(host->irq);
627}
628
629static void
630mmc_omap_cmd_timer(unsigned long data)
631{
632 struct mmc_omap_host *host = (struct mmc_omap_host *) data;
633 unsigned long flags;
634
635 spin_lock_irqsave(&host->slot_lock, flags);
636 if (host->cmd != NULL && !host->abort) {
637 OMAP_MMC_WRITE(host, IE, 0);
638 disable_irq(host->irq);
639 host->abort = 1;
640 schedule_work(&host->cmd_abort_work);
375 } 641 }
642 spin_unlock_irqrestore(&host->slot_lock, flags);
376} 643}
377 644
378/* PIO only */ 645/* PIO only */
@@ -388,6 +655,14 @@ mmc_omap_sg_to_buf(struct mmc_omap_host *host)
388 host->buffer_bytes_left = host->total_bytes_left; 655 host->buffer_bytes_left = host->total_bytes_left;
389} 656}
390 657
658static void
659mmc_omap_clk_timer(unsigned long data)
660{
661 struct mmc_omap_host *host = (struct mmc_omap_host *) data;
662
663 mmc_omap_fclk_enable(host, 0);
664}
665
391/* PIO only */ 666/* PIO only */
392static void 667static void
393mmc_omap_xfer_data(struct mmc_omap_host *host, int write) 668mmc_omap_xfer_data(struct mmc_omap_host *host, int write)
@@ -436,11 +711,12 @@ static irqreturn_t mmc_omap_irq(int irq, void *dev_id)
436 u16 status; 711 u16 status;
437 int end_command; 712 int end_command;
438 int end_transfer; 713 int end_transfer;
439 int transfer_error; 714 int transfer_error, cmd_error;
440 715
441 if (host->cmd == NULL && host->data == NULL) { 716 if (host->cmd == NULL && host->data == NULL) {
442 status = OMAP_MMC_READ(host, STAT); 717 status = OMAP_MMC_READ(host, STAT);
443 dev_info(mmc_dev(host->mmc),"spurious irq 0x%04x\n", status); 718 dev_info(mmc_dev(host->slots[0]->mmc),
719 "Spurious IRQ 0x%04x\n", status);
444 if (status != 0) { 720 if (status != 0) {
445 OMAP_MMC_WRITE(host, STAT, status); 721 OMAP_MMC_WRITE(host, STAT, status);
446 OMAP_MMC_WRITE(host, IE, 0); 722 OMAP_MMC_WRITE(host, IE, 0);
@@ -451,12 +727,19 @@ static irqreturn_t mmc_omap_irq(int irq, void *dev_id)
451 end_command = 0; 727 end_command = 0;
452 end_transfer = 0; 728 end_transfer = 0;
453 transfer_error = 0; 729 transfer_error = 0;
730 cmd_error = 0;
454 731
455 while ((status = OMAP_MMC_READ(host, STAT)) != 0) { 732 while ((status = OMAP_MMC_READ(host, STAT)) != 0) {
733 int cmd;
734
456 OMAP_MMC_WRITE(host, STAT, status); 735 OMAP_MMC_WRITE(host, STAT, status);
736 if (host->cmd != NULL)
737 cmd = host->cmd->opcode;
738 else
739 cmd = -1;
457#ifdef CONFIG_MMC_DEBUG 740#ifdef CONFIG_MMC_DEBUG
458 dev_dbg(mmc_dev(host->mmc), "MMC IRQ %04x (CMD %d): ", 741 dev_dbg(mmc_dev(host->mmc), "MMC IRQ %04x (CMD %d): ",
459 status, host->cmd != NULL ? host->cmd->opcode : -1); 742 status, cmd);
460 mmc_omap_report_irq(status); 743 mmc_omap_report_irq(status);
461 printk("\n"); 744 printk("\n");
462#endif 745#endif
@@ -468,12 +751,12 @@ static irqreturn_t mmc_omap_irq(int irq, void *dev_id)
468 mmc_omap_xfer_data(host, 1); 751 mmc_omap_xfer_data(host, 1);
469 } 752 }
470 753
471 if (status & OMAP_MMC_STAT_END_OF_DATA) { 754 if (status & OMAP_MMC_STAT_END_OF_DATA)
472 end_transfer = 1; 755 end_transfer = 1;
473 }
474 756
475 if (status & OMAP_MMC_STAT_DATA_TOUT) { 757 if (status & OMAP_MMC_STAT_DATA_TOUT) {
476 dev_dbg(mmc_dev(host->mmc), "data timeout\n"); 758 dev_dbg(mmc_dev(host->mmc), "data timeout (CMD%d)\n",
759 cmd);
477 if (host->data) { 760 if (host->data) {
478 host->data->error = -ETIMEDOUT; 761 host->data->error = -ETIMEDOUT;
479 transfer_error = 1; 762 transfer_error = 1;
@@ -495,17 +778,16 @@ static irqreturn_t mmc_omap_irq(int irq, void *dev_id)
495 if (status & OMAP_MMC_STAT_CMD_TOUT) { 778 if (status & OMAP_MMC_STAT_CMD_TOUT) {
496 /* Timeouts are routine with some commands */ 779 /* Timeouts are routine with some commands */
497 if (host->cmd) { 780 if (host->cmd) {
498 if (host->cmd->opcode != MMC_ALL_SEND_CID && 781 struct mmc_omap_slot *slot =
499 host->cmd->opcode != 782 host->current_slot;
500 MMC_SEND_OP_COND && 783 if (slot == NULL ||
501 host->cmd->opcode != 784 !mmc_omap_cover_is_open(slot))
502 MMC_APP_CMD &&
503 !mmc_omap_cover_is_open(host))
504 dev_err(mmc_dev(host->mmc), 785 dev_err(mmc_dev(host->mmc),
505 "command timeout, CMD %d\n", 786 "command timeout (CMD%d)\n",
506 host->cmd->opcode); 787 cmd);
507 host->cmd->error = -ETIMEDOUT; 788 host->cmd->error = -ETIMEDOUT;
508 end_command = 1; 789 end_command = 1;
790 cmd_error = 1;
509 } 791 }
510 } 792 }
511 793
@@ -513,9 +795,10 @@ static irqreturn_t mmc_omap_irq(int irq, void *dev_id)
513 if (host->cmd) { 795 if (host->cmd) {
514 dev_err(mmc_dev(host->mmc), 796 dev_err(mmc_dev(host->mmc),
515 "command CRC error (CMD%d, arg 0x%08x)\n", 797 "command CRC error (CMD%d, arg 0x%08x)\n",
516 host->cmd->opcode, host->cmd->arg); 798 cmd, host->cmd->arg);
517 host->cmd->error = -EILSEQ; 799 host->cmd->error = -EILSEQ;
518 end_command = 1; 800 end_command = 1;
801 cmd_error = 1;
519 } else 802 } else
520 dev_err(mmc_dev(host->mmc), 803 dev_err(mmc_dev(host->mmc),
521 "command CRC error without cmd?\n"); 804 "command CRC error without cmd?\n");
@@ -524,13 +807,13 @@ static irqreturn_t mmc_omap_irq(int irq, void *dev_id)
524 if (status & OMAP_MMC_STAT_CARD_ERR) { 807 if (status & OMAP_MMC_STAT_CARD_ERR) {
525 dev_dbg(mmc_dev(host->mmc), 808 dev_dbg(mmc_dev(host->mmc),
526 "ignoring card status error (CMD%d)\n", 809 "ignoring card status error (CMD%d)\n",
527 host->cmd->opcode); 810 cmd);
528 end_command = 1; 811 end_command = 1;
529 } 812 }
530 813
531 /* 814 /*
532 * NOTE: On 1610 the END_OF_CMD may come too early when 815 * NOTE: On 1610 the END_OF_CMD may come too early when
533 * starting a write 816 * starting a write
534 */ 817 */
535 if ((status & OMAP_MMC_STAT_END_OF_CMD) && 818 if ((status & OMAP_MMC_STAT_END_OF_CMD) &&
536 (!(status & OMAP_MMC_STAT_A_EMPTY))) { 819 (!(status & OMAP_MMC_STAT_A_EMPTY))) {
@@ -538,63 +821,72 @@ static irqreturn_t mmc_omap_irq(int irq, void *dev_id)
538 } 821 }
539 } 822 }
540 823
541 if (end_command) { 824 if (cmd_error && host->data) {
825 del_timer(&host->cmd_abort_timer);
826 host->abort = 1;
827 OMAP_MMC_WRITE(host, IE, 0);
828 disable_irq(host->irq);
829 schedule_work(&host->cmd_abort_work);
830 return IRQ_HANDLED;
831 }
832
833 if (end_command)
542 mmc_omap_cmd_done(host, host->cmd); 834 mmc_omap_cmd_done(host, host->cmd);
835 if (host->data != NULL) {
836 if (transfer_error)
837 mmc_omap_xfer_done(host, host->data);
838 else if (end_transfer)
839 mmc_omap_end_of_data(host, host->data);
543 } 840 }
544 if (transfer_error)
545 mmc_omap_xfer_done(host, host->data);
546 else if (end_transfer)
547 mmc_omap_end_of_data(host, host->data);
548 841
549 return IRQ_HANDLED; 842 return IRQ_HANDLED;
550} 843}
551 844
552static irqreturn_t mmc_omap_switch_irq(int irq, void *dev_id) 845void omap_mmc_notify_cover_event(struct device *dev, int num, int is_closed)
553{ 846{
554 struct mmc_omap_host *host = (struct mmc_omap_host *) dev_id; 847 int cover_open;
848 struct mmc_omap_host *host = dev_get_drvdata(dev);
849 struct mmc_omap_slot *slot = host->slots[num];
555 850
556 schedule_work(&host->switch_work); 851 BUG_ON(num >= host->nr_slots);
557 852
558 return IRQ_HANDLED; 853 /* Other subsystems can call in here before we're initialised. */
854 if (host->nr_slots == 0 || !host->slots[num])
855 return;
856
857 cover_open = mmc_omap_cover_is_open(slot);
858 if (cover_open != slot->cover_open) {
859 slot->cover_open = cover_open;
860 sysfs_notify(&slot->mmc->class_dev.kobj, NULL, "cover_switch");
861 }
862
863 tasklet_hi_schedule(&slot->cover_tasklet);
559} 864}
560 865
561static void mmc_omap_switch_timer(unsigned long arg) 866static void mmc_omap_cover_timer(unsigned long arg)
562{ 867{
563 struct mmc_omap_host *host = (struct mmc_omap_host *) arg; 868 struct mmc_omap_slot *slot = (struct mmc_omap_slot *) arg;
564 869 tasklet_schedule(&slot->cover_tasklet);
565 schedule_work(&host->switch_work);
566} 870}
567 871
568static void mmc_omap_switch_handler(struct work_struct *work) 872static void mmc_omap_cover_handler(unsigned long param)
569{ 873{
570 struct mmc_omap_host *host = container_of(work, struct mmc_omap_host, switch_work); 874 struct mmc_omap_slot *slot = (struct mmc_omap_slot *)param;
571 struct mmc_card *card; 875 int cover_open = mmc_omap_cover_is_open(slot);
572 static int complained = 0;
573 int cards = 0, cover_open;
574 876
575 if (host->switch_pin == -1) 877 mmc_detect_change(slot->mmc, 0);
878 if (!cover_open)
576 return; 879 return;
577 cover_open = mmc_omap_cover_is_open(host); 880
578 if (cover_open != host->switch_last_state) { 881 /*
579 kobject_uevent(&host->dev->kobj, KOBJ_CHANGE); 882 * If no card is inserted, we postpone polling until
580 host->switch_last_state = cover_open; 883 * the cover has been closed.
581 } 884 */
582 mmc_detect_change(host->mmc, 0); 885 if (slot->mmc->card == NULL || !mmc_card_present(slot->mmc->card))
583 list_for_each_entry(card, &host->mmc->cards, node) { 886 return;
584 if (mmc_card_present(card)) 887
585 cards++; 888 mod_timer(&slot->cover_timer,
586 } 889 jiffies + msecs_to_jiffies(OMAP_MMC_COVER_POLL_DELAY));
587 if (mmc_omap_cover_is_open(host)) {
588 if (!complained) {
589 dev_info(mmc_dev(host->mmc), "cover is open\n");
590 complained = 1;
591 }
592 if (mmc_omap_enable_poll)
593 mod_timer(&host->switch_timer, jiffies +
594 msecs_to_jiffies(OMAP_MMC_SWITCH_POLL_DELAY));
595 } else {
596 complained = 0;
597 }
598} 890}
599 891
600/* Prepare to transfer the next segment of a scatterlist */ 892/* Prepare to transfer the next segment of a scatterlist */
@@ -765,13 +1057,12 @@ static inline void set_cmd_timeout(struct mmc_omap_host *host, struct mmc_reques
765 1057
766static inline void set_data_timeout(struct mmc_omap_host *host, struct mmc_request *req) 1058static inline void set_data_timeout(struct mmc_omap_host *host, struct mmc_request *req)
767{ 1059{
768 int timeout; 1060 unsigned int timeout, cycle_ns;
769 u16 reg; 1061 u16 reg;
770 1062
771 /* Convert ns to clock cycles by assuming 20MHz frequency 1063 cycle_ns = 1000000000 / host->current_slot->fclk_freq;
772 * 1 cycle at 20MHz = 500 ns 1064 timeout = req->data->timeout_ns / cycle_ns;
773 */ 1065 timeout += req->data->timeout_clks;
774 timeout = req->data->timeout_clks + req->data->timeout_ns / 500;
775 1066
776 /* Check if we need to use timeout multiplier register */ 1067 /* Check if we need to use timeout multiplier register */
777 reg = OMAP_MMC_READ(host, SDIO); 1068 reg = OMAP_MMC_READ(host, SDIO);
@@ -854,11 +1145,10 @@ mmc_omap_prepare_data(struct mmc_omap_host *host, struct mmc_request *req)
854 } 1145 }
855} 1146}
856 1147
857static void mmc_omap_request(struct mmc_host *mmc, struct mmc_request *req) 1148static void mmc_omap_start_request(struct mmc_omap_host *host,
1149 struct mmc_request *req)
858{ 1150{
859 struct mmc_omap_host *host = mmc_priv(mmc); 1151 BUG_ON(host->mrq != NULL);
860
861 WARN_ON(host->mrq != NULL);
862 1152
863 host->mrq = req; 1153 host->mrq = req;
864 1154
@@ -867,60 +1157,56 @@ static void mmc_omap_request(struct mmc_host *mmc, struct mmc_request *req)
867 mmc_omap_start_command(host, req->cmd); 1157 mmc_omap_start_command(host, req->cmd);
868 if (host->dma_in_use) 1158 if (host->dma_in_use)
869 omap_start_dma(host->dma_ch); 1159 omap_start_dma(host->dma_ch);
1160 BUG_ON(irqs_disabled());
870} 1161}
871 1162
872static void innovator_fpga_socket_power(int on) 1163static void mmc_omap_request(struct mmc_host *mmc, struct mmc_request *req)
873{ 1164{
874#if defined(CONFIG_MACH_OMAP_INNOVATOR) && defined(CONFIG_ARCH_OMAP15XX) 1165 struct mmc_omap_slot *slot = mmc_priv(mmc);
875 if (on) { 1166 struct mmc_omap_host *host = slot->host;
876 fpga_write(fpga_read(OMAP1510_FPGA_POWER) | (1 << 3), 1167 unsigned long flags;
877 OMAP1510_FPGA_POWER); 1168
878 } else { 1169 spin_lock_irqsave(&host->slot_lock, flags);
879 fpga_write(fpga_read(OMAP1510_FPGA_POWER) & ~(1 << 3), 1170 if (host->mmc != NULL) {
880 OMAP1510_FPGA_POWER); 1171 BUG_ON(slot->mrq != NULL);
881 } 1172 slot->mrq = req;
882#endif 1173 spin_unlock_irqrestore(&host->slot_lock, flags);
1174 return;
1175 } else
1176 host->mmc = mmc;
1177 spin_unlock_irqrestore(&host->slot_lock, flags);
1178 mmc_omap_select_slot(slot, 1);
1179 mmc_omap_start_request(host, req);
883} 1180}
884 1181
885/* 1182static void mmc_omap_set_power(struct mmc_omap_slot *slot, int power_on,
886 * Turn the socket power on/off. Innovator uses FPGA, most boards 1183 int vdd)
887 * probably use GPIO.
888 */
889static void mmc_omap_power(struct mmc_omap_host *host, int on)
890{ 1184{
891 if (on) { 1185 struct mmc_omap_host *host;
892 if (machine_is_omap_innovator()) 1186
893 innovator_fpga_socket_power(1); 1187 host = slot->host;
894 else if (machine_is_omap_h2()) 1188
895 tps65010_set_gpio_out_value(GPIO3, HIGH); 1189 if (slot->pdata->set_power != NULL)
896 else if (machine_is_omap_h3()) 1190 slot->pdata->set_power(mmc_dev(slot->mmc), slot->id, power_on,
897 /* GPIO 4 of TPS65010 sends SD_EN signal */ 1191 vdd);
898 tps65010_set_gpio_out_value(GPIO4, HIGH); 1192
899 else if (cpu_is_omap24xx()) { 1193 if (cpu_is_omap24xx()) {
900 u16 reg = OMAP_MMC_READ(host, CON); 1194 u16 w;
901 OMAP_MMC_WRITE(host, CON, reg | (1 << 11)); 1195
902 } else 1196 if (power_on) {
903 if (host->power_pin >= 0) 1197 w = OMAP_MMC_READ(host, CON);
904 omap_set_gpio_dataout(host->power_pin, 1); 1198 OMAP_MMC_WRITE(host, CON, w | (1 << 11));
905 } else { 1199 } else {
906 if (machine_is_omap_innovator()) 1200 w = OMAP_MMC_READ(host, CON);
907 innovator_fpga_socket_power(0); 1201 OMAP_MMC_WRITE(host, CON, w & ~(1 << 11));
908 else if (machine_is_omap_h2()) 1202 }
909 tps65010_set_gpio_out_value(GPIO3, LOW);
910 else if (machine_is_omap_h3())
911 tps65010_set_gpio_out_value(GPIO4, LOW);
912 else if (cpu_is_omap24xx()) {
913 u16 reg = OMAP_MMC_READ(host, CON);
914 OMAP_MMC_WRITE(host, CON, reg & ~(1 << 11));
915 } else
916 if (host->power_pin >= 0)
917 omap_set_gpio_dataout(host->power_pin, 0);
918 } 1203 }
919} 1204}
920 1205
921static int mmc_omap_calc_divisor(struct mmc_host *mmc, struct mmc_ios *ios) 1206static int mmc_omap_calc_divisor(struct mmc_host *mmc, struct mmc_ios *ios)
922{ 1207{
923 struct mmc_omap_host *host = mmc_priv(mmc); 1208 struct mmc_omap_slot *slot = mmc_priv(mmc);
1209 struct mmc_omap_host *host = slot->host;
924 int func_clk_rate = clk_get_rate(host->fclk); 1210 int func_clk_rate = clk_get_rate(host->fclk);
925 int dsor; 1211 int dsor;
926 1212
@@ -936,7 +1222,8 @@ static int mmc_omap_calc_divisor(struct mmc_host *mmc, struct mmc_ios *ios)
936 1222
937 if (dsor > 250) 1223 if (dsor > 250)
938 dsor = 250; 1224 dsor = 250;
939 dsor++; 1225
1226 slot->fclk_freq = func_clk_rate / dsor;
940 1227
941 if (ios->bus_width == MMC_BUS_WIDTH_4) 1228 if (ios->bus_width == MMC_BUS_WIDTH_4)
942 dsor |= 1 << 15; 1229 dsor |= 1 << 15;
@@ -946,28 +1233,40 @@ static int mmc_omap_calc_divisor(struct mmc_host *mmc, struct mmc_ios *ios)
946 1233
947static void mmc_omap_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) 1234static void mmc_omap_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
948{ 1235{
949 struct mmc_omap_host *host = mmc_priv(mmc); 1236 struct mmc_omap_slot *slot = mmc_priv(mmc);
950 int dsor; 1237 struct mmc_omap_host *host = slot->host;
951 int i; 1238 int i, dsor;
1239 int clk_enabled;
1240
1241 mmc_omap_select_slot(slot, 0);
952 1242
953 dsor = mmc_omap_calc_divisor(mmc, ios); 1243 dsor = mmc_omap_calc_divisor(mmc, ios);
954 host->bus_mode = ios->bus_mode;
955 host->hw_bus_mode = host->bus_mode;
956 1244
1245 if (ios->vdd != slot->vdd)
1246 slot->vdd = ios->vdd;
1247
1248 clk_enabled = 0;
957 switch (ios->power_mode) { 1249 switch (ios->power_mode) {
958 case MMC_POWER_OFF: 1250 case MMC_POWER_OFF:
959 mmc_omap_power(host, 0); 1251 mmc_omap_set_power(slot, 0, ios->vdd);
960 break; 1252 break;
961 case MMC_POWER_UP: 1253 case MMC_POWER_UP:
962 /* Cannot touch dsor yet, just power up MMC */ 1254 /* Cannot touch dsor yet, just power up MMC */
963 mmc_omap_power(host, 1); 1255 mmc_omap_set_power(slot, 1, ios->vdd);
964 return; 1256 goto exit;
965 case MMC_POWER_ON: 1257 case MMC_POWER_ON:
1258 mmc_omap_fclk_enable(host, 1);
1259 clk_enabled = 1;
966 dsor |= 1 << 11; 1260 dsor |= 1 << 11;
967 break; 1261 break;
968 } 1262 }
969 1263
970 clk_enable(host->fclk); 1264 if (slot->bus_mode != ios->bus_mode) {
1265 if (slot->pdata->set_bus_mode != NULL)
1266 slot->pdata->set_bus_mode(mmc_dev(mmc), slot->id,
1267 ios->bus_mode);
1268 slot->bus_mode = ios->bus_mode;
1269 }
971 1270
972 /* On insanely high arm_per frequencies something sometimes 1271 /* On insanely high arm_per frequencies something sometimes
973 * goes somehow out of sync, and the POW bit is not being set, 1272 * goes somehow out of sync, and the POW bit is not being set,
@@ -975,43 +1274,143 @@ static void mmc_omap_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
975 * Writing to the CON register twice seems to do the trick. */ 1274 * Writing to the CON register twice seems to do the trick. */
976 for (i = 0; i < 2; i++) 1275 for (i = 0; i < 2; i++)
977 OMAP_MMC_WRITE(host, CON, dsor); 1276 OMAP_MMC_WRITE(host, CON, dsor);
1277 slot->saved_con = dsor;
978 if (ios->power_mode == MMC_POWER_ON) { 1278 if (ios->power_mode == MMC_POWER_ON) {
1279 /* worst case at 400kHz, 80 cycles makes 200 microsecs */
1280 int usecs = 250;
1281
979 /* Send clock cycles, poll completion */ 1282 /* Send clock cycles, poll completion */
980 OMAP_MMC_WRITE(host, IE, 0); 1283 OMAP_MMC_WRITE(host, IE, 0);
981 OMAP_MMC_WRITE(host, STAT, 0xffff); 1284 OMAP_MMC_WRITE(host, STAT, 0xffff);
982 OMAP_MMC_WRITE(host, CMD, 1 << 7); 1285 OMAP_MMC_WRITE(host, CMD, 1 << 7);
983 while ((OMAP_MMC_READ(host, STAT) & 1) == 0); 1286 while (usecs > 0 && (OMAP_MMC_READ(host, STAT) & 1) == 0) {
1287 udelay(1);
1288 usecs--;
1289 }
984 OMAP_MMC_WRITE(host, STAT, 1); 1290 OMAP_MMC_WRITE(host, STAT, 1);
985 } 1291 }
986 clk_disable(host->fclk);
987}
988
989static int mmc_omap_get_ro(struct mmc_host *mmc)
990{
991 struct mmc_omap_host *host = mmc_priv(mmc);
992 1292
993 return host->wp_pin && omap_get_gpio_datain(host->wp_pin); 1293exit:
1294 mmc_omap_release_slot(slot, clk_enabled);
994} 1295}
995 1296
996static const struct mmc_host_ops mmc_omap_ops = { 1297static const struct mmc_host_ops mmc_omap_ops = {
997 .request = mmc_omap_request, 1298 .request = mmc_omap_request,
998 .set_ios = mmc_omap_set_ios, 1299 .set_ios = mmc_omap_set_ios,
999 .get_ro = mmc_omap_get_ro,
1000}; 1300};
1001 1301
1002static int __init mmc_omap_probe(struct platform_device *pdev) 1302static int __init mmc_omap_new_slot(struct mmc_omap_host *host, int id)
1003{ 1303{
1004 struct omap_mmc_conf *minfo = pdev->dev.platform_data; 1304 struct mmc_omap_slot *slot = NULL;
1005 struct mmc_host *mmc; 1305 struct mmc_host *mmc;
1306 int r;
1307
1308 mmc = mmc_alloc_host(sizeof(struct mmc_omap_slot), host->dev);
1309 if (mmc == NULL)
1310 return -ENOMEM;
1311
1312 slot = mmc_priv(mmc);
1313 slot->host = host;
1314 slot->mmc = mmc;
1315 slot->id = id;
1316 slot->pdata = &host->pdata->slots[id];
1317
1318 host->slots[id] = slot;
1319
1320 mmc->caps = MMC_CAP_MULTIWRITE;
1321 if (host->pdata->conf.wire4)
1322 mmc->caps |= MMC_CAP_4_BIT_DATA;
1323
1324 mmc->ops = &mmc_omap_ops;
1325 mmc->f_min = 400000;
1326
1327 if (cpu_class_is_omap2())
1328 mmc->f_max = 48000000;
1329 else
1330 mmc->f_max = 24000000;
1331 if (host->pdata->max_freq)
1332 mmc->f_max = min(host->pdata->max_freq, mmc->f_max);
1333 mmc->ocr_avail = slot->pdata->ocr_mask;
1334
1335 /* Use scatterlist DMA to reduce per-transfer costs.
1336 * NOTE max_seg_size assumption that small blocks aren't
1337 * normally used (except e.g. for reading SD registers).
1338 */
1339 mmc->max_phys_segs = 32;
1340 mmc->max_hw_segs = 32;
1341 mmc->max_blk_size = 2048; /* BLEN is 11 bits (+1) */
1342 mmc->max_blk_count = 2048; /* NBLK is 11 bits (+1) */
1343 mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count;
1344 mmc->max_seg_size = mmc->max_req_size;
1345
1346 r = mmc_add_host(mmc);
1347 if (r < 0)
1348 goto err_remove_host;
1349
1350 if (slot->pdata->name != NULL) {
1351 r = device_create_file(&mmc->class_dev,
1352 &dev_attr_slot_name);
1353 if (r < 0)
1354 goto err_remove_host;
1355 }
1356
1357 if (slot->pdata->get_cover_state != NULL) {
1358 r = device_create_file(&mmc->class_dev,
1359 &dev_attr_cover_switch);
1360 if (r < 0)
1361 goto err_remove_slot_name;
1362
1363 setup_timer(&slot->cover_timer, mmc_omap_cover_timer,
1364 (unsigned long)slot);
1365 tasklet_init(&slot->cover_tasklet, mmc_omap_cover_handler,
1366 (unsigned long)slot);
1367 tasklet_schedule(&slot->cover_tasklet);
1368 }
1369
1370 return 0;
1371
1372err_remove_slot_name:
1373 if (slot->pdata->name != NULL)
1374 device_remove_file(&mmc->class_dev, &dev_attr_slot_name);
1375err_remove_host:
1376 mmc_remove_host(mmc);
1377 mmc_free_host(mmc);
1378 return r;
1379}
1380
1381static void mmc_omap_remove_slot(struct mmc_omap_slot *slot)
1382{
1383 struct mmc_host *mmc = slot->mmc;
1384
1385 if (slot->pdata->name != NULL)
1386 device_remove_file(&mmc->class_dev, &dev_attr_slot_name);
1387 if (slot->pdata->get_cover_state != NULL)
1388 device_remove_file(&mmc->class_dev, &dev_attr_cover_switch);
1389
1390 tasklet_kill(&slot->cover_tasklet);
1391 del_timer_sync(&slot->cover_timer);
1392 flush_scheduled_work();
1393
1394 mmc_remove_host(mmc);
1395 mmc_free_host(mmc);
1396}
1397
1398static int __init mmc_omap_probe(struct platform_device *pdev)
1399{
1400 struct omap_mmc_platform_data *pdata = pdev->dev.platform_data;
1006 struct mmc_omap_host *host = NULL; 1401 struct mmc_omap_host *host = NULL;
1007 struct resource *res; 1402 struct resource *res;
1008 int ret = 0; 1403 int i, ret = 0;
1009 int irq; 1404 int irq;
1010 1405
1011 if (minfo == NULL) { 1406 if (pdata == NULL) {
1012 dev_err(&pdev->dev, "platform data missing\n"); 1407 dev_err(&pdev->dev, "platform data missing\n");
1013 return -ENXIO; 1408 return -ENXIO;
1014 } 1409 }
1410 if (pdata->nr_slots == 0) {
1411 dev_err(&pdev->dev, "no slots\n");
1412 return -ENXIO;
1413 }
1015 1414
1016 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1415 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1017 irq = platform_get_irq(pdev, 0); 1416 irq = platform_get_irq(pdev, 0);
@@ -1019,28 +1418,46 @@ static int __init mmc_omap_probe(struct platform_device *pdev)
1019 return -ENXIO; 1418 return -ENXIO;
1020 1419
1021 res = request_mem_region(res->start, res->end - res->start + 1, 1420 res = request_mem_region(res->start, res->end - res->start + 1,
1022 pdev->name); 1421 pdev->name);
1023 if (res == NULL) 1422 if (res == NULL)
1024 return -EBUSY; 1423 return -EBUSY;
1025 1424
1026 mmc = mmc_alloc_host(sizeof(struct mmc_omap_host), &pdev->dev); 1425 host = kzalloc(sizeof(struct mmc_omap_host), GFP_KERNEL);
1027 if (mmc == NULL) { 1426 if (host == NULL) {
1028 ret = -ENOMEM; 1427 ret = -ENOMEM;
1029 goto err_free_mem_region; 1428 goto err_free_mem_region;
1030 } 1429 }
1031 1430
1032 host = mmc_priv(mmc); 1431 INIT_WORK(&host->slot_release_work, mmc_omap_slot_release_work);
1033 host->mmc = mmc; 1432 INIT_WORK(&host->send_stop_work, mmc_omap_send_stop_work);
1433
1434 INIT_WORK(&host->cmd_abort_work, mmc_omap_abort_command);
1435 setup_timer(&host->cmd_abort_timer, mmc_omap_cmd_timer,
1436 (unsigned long) host);
1437
1438 spin_lock_init(&host->clk_lock);
1439 setup_timer(&host->clk_timer, mmc_omap_clk_timer, (unsigned long) host);
1034 1440
1035 spin_lock_init(&host->dma_lock); 1441 spin_lock_init(&host->dma_lock);
1036 init_timer(&host->dma_timer); 1442 setup_timer(&host->dma_timer, mmc_omap_dma_timer, (unsigned long) host);
1037 host->dma_timer.function = mmc_omap_dma_timer; 1443 spin_lock_init(&host->slot_lock);
1038 host->dma_timer.data = (unsigned long) host; 1444 init_waitqueue_head(&host->slot_wq);
1445
1446 host->pdata = pdata;
1447 host->dev = &pdev->dev;
1448 platform_set_drvdata(pdev, host);
1039 1449
1040 host->id = pdev->id; 1450 host->id = pdev->id;
1041 host->mem_res = res; 1451 host->mem_res = res;
1042 host->irq = irq; 1452 host->irq = irq;
1043 1453
1454 host->use_dma = 1;
1455 host->dma_ch = -1;
1456
1457 host->irq = irq;
1458 host->phys_base = host->mem_res->start;
1459 host->virt_base = (void __iomem *) IO_ADDRESS(host->phys_base);
1460
1044 if (cpu_is_omap24xx()) { 1461 if (cpu_is_omap24xx()) {
1045 host->iclk = clk_get(&pdev->dev, "mmc_ick"); 1462 host->iclk = clk_get(&pdev->dev, "mmc_ick");
1046 if (IS_ERR(host->iclk)) 1463 if (IS_ERR(host->iclk))
@@ -1058,109 +1475,34 @@ static int __init mmc_omap_probe(struct platform_device *pdev)
1058 goto err_free_iclk; 1475 goto err_free_iclk;
1059 } 1476 }
1060 1477
1061 /* REVISIT:
1062 * Also, use minfo->cover to decide how to manage
1063 * the card detect sensing.
1064 */
1065 host->power_pin = minfo->power_pin;
1066 host->switch_pin = minfo->switch_pin;
1067 host->wp_pin = minfo->wp_pin;
1068 host->use_dma = 1;
1069 host->dma_ch = -1;
1070
1071 host->irq = irq;
1072 host->phys_base = host->mem_res->start;
1073 host->virt_base = (void __iomem *) IO_ADDRESS(host->phys_base);
1074
1075 mmc->ops = &mmc_omap_ops;
1076 mmc->f_min = 400000;
1077 mmc->f_max = 24000000;
1078 mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
1079 mmc->caps = MMC_CAP_MULTIWRITE | MMC_CAP_BYTEBLOCK;
1080
1081 if (minfo->wire4)
1082 mmc->caps |= MMC_CAP_4_BIT_DATA;
1083
1084 /* Use scatterlist DMA to reduce per-transfer costs.
1085 * NOTE max_seg_size assumption that small blocks aren't
1086 * normally used (except e.g. for reading SD registers).
1087 */
1088 mmc->max_phys_segs = 32;
1089 mmc->max_hw_segs = 32;
1090 mmc->max_blk_size = 2048; /* BLEN is 11 bits (+1) */
1091 mmc->max_blk_count = 2048; /* NBLK is 11 bits (+1) */
1092 mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count;
1093 mmc->max_seg_size = mmc->max_req_size;
1094
1095 if (host->power_pin >= 0) {
1096 if ((ret = omap_request_gpio(host->power_pin)) != 0) {
1097 dev_err(mmc_dev(host->mmc),
1098 "Unable to get GPIO pin for MMC power\n");
1099 goto err_free_fclk;
1100 }
1101 omap_set_gpio_direction(host->power_pin, 0);
1102 }
1103
1104 ret = request_irq(host->irq, mmc_omap_irq, 0, DRIVER_NAME, host); 1478 ret = request_irq(host->irq, mmc_omap_irq, 0, DRIVER_NAME, host);
1105 if (ret) 1479 if (ret)
1106 goto err_free_power_gpio; 1480 goto err_free_fclk;
1107 1481
1108 host->dev = &pdev->dev; 1482 if (pdata->init != NULL) {
1109 platform_set_drvdata(pdev, host); 1483 ret = pdata->init(&pdev->dev);
1484 if (ret < 0)
1485 goto err_free_irq;
1486 }
1110 1487
1111 if (host->switch_pin >= 0) { 1488 host->nr_slots = pdata->nr_slots;
1112 INIT_WORK(&host->switch_work, mmc_omap_switch_handler); 1489 for (i = 0; i < pdata->nr_slots; i++) {
1113 init_timer(&host->switch_timer); 1490 ret = mmc_omap_new_slot(host, i);
1114 host->switch_timer.function = mmc_omap_switch_timer; 1491 if (ret < 0) {
1115 host->switch_timer.data = (unsigned long) host; 1492 while (--i >= 0)
1116 if (omap_request_gpio(host->switch_pin) != 0) { 1493 mmc_omap_remove_slot(host->slots[i]);
1117 dev_warn(mmc_dev(host->mmc), "Unable to get GPIO pin for MMC cover switch\n");
1118 host->switch_pin = -1;
1119 goto no_switch;
1120 }
1121 1494
1122 omap_set_gpio_direction(host->switch_pin, 1); 1495 goto err_plat_cleanup;
1123 ret = request_irq(OMAP_GPIO_IRQ(host->switch_pin),
1124 mmc_omap_switch_irq, IRQF_TRIGGER_RISING, DRIVER_NAME, host);
1125 if (ret) {
1126 dev_warn(mmc_dev(host->mmc), "Unable to get IRQ for MMC cover switch\n");
1127 omap_free_gpio(host->switch_pin);
1128 host->switch_pin = -1;
1129 goto no_switch;
1130 }
1131 ret = device_create_file(&pdev->dev, &dev_attr_cover_switch);
1132 if (ret == 0) {
1133 ret = device_create_file(&pdev->dev, &dev_attr_enable_poll);
1134 if (ret != 0)
1135 device_remove_file(&pdev->dev, &dev_attr_cover_switch);
1136 } 1496 }
1137 if (ret) {
1138 dev_warn(mmc_dev(host->mmc), "Unable to create sysfs attributes\n");
1139 free_irq(OMAP_GPIO_IRQ(host->switch_pin), host);
1140 omap_free_gpio(host->switch_pin);
1141 host->switch_pin = -1;
1142 goto no_switch;
1143 }
1144 if (mmc_omap_enable_poll && mmc_omap_cover_is_open(host))
1145 schedule_work(&host->switch_work);
1146 } 1497 }
1147 1498
1148 mmc_add_host(mmc);
1149
1150 return 0; 1499 return 0;
1151 1500
1152no_switch: 1501err_plat_cleanup:
1153 /* FIXME: Free other resources too. */ 1502 if (pdata->cleanup)
1154 if (host) { 1503 pdata->cleanup(&pdev->dev);
1155 if (host->iclk && !IS_ERR(host->iclk)) 1504err_free_irq:
1156 clk_put(host->iclk); 1505 free_irq(host->irq, host);
1157 if (host->fclk && !IS_ERR(host->fclk))
1158 clk_put(host->fclk);
1159 mmc_free_host(host->mmc);
1160 }
1161err_free_power_gpio:
1162 if (host->power_pin >= 0)
1163 omap_free_gpio(host->power_pin);
1164err_free_fclk: 1506err_free_fclk:
1165 clk_put(host->fclk); 1507 clk_put(host->fclk);
1166err_free_iclk: 1508err_free_iclk:
@@ -1169,7 +1511,7 @@ err_free_iclk:
1169 clk_put(host->iclk); 1511 clk_put(host->iclk);
1170 } 1512 }
1171err_free_mmc_host: 1513err_free_mmc_host:
1172 mmc_free_host(host->mmc); 1514 kfree(host);
1173err_free_mem_region: 1515err_free_mem_region:
1174 release_mem_region(res->start, res->end - res->start + 1); 1516 release_mem_region(res->start, res->end - res->start + 1);
1175 return ret; 1517 return ret;
@@ -1178,25 +1520,18 @@ err_free_mem_region:
1178static int mmc_omap_remove(struct platform_device *pdev) 1520static int mmc_omap_remove(struct platform_device *pdev)
1179{ 1521{
1180 struct mmc_omap_host *host = platform_get_drvdata(pdev); 1522 struct mmc_omap_host *host = platform_get_drvdata(pdev);
1523 int i;
1181 1524
1182 platform_set_drvdata(pdev, NULL); 1525 platform_set_drvdata(pdev, NULL);
1183 1526
1184 BUG_ON(host == NULL); 1527 BUG_ON(host == NULL);
1185 1528
1186 mmc_remove_host(host->mmc); 1529 for (i = 0; i < host->nr_slots; i++)
1187 free_irq(host->irq, host); 1530 mmc_omap_remove_slot(host->slots[i]);
1531
1532 if (host->pdata->cleanup)
1533 host->pdata->cleanup(&pdev->dev);
1188 1534
1189 if (host->power_pin >= 0)
1190 omap_free_gpio(host->power_pin);
1191 if (host->switch_pin >= 0) {
1192 device_remove_file(&pdev->dev, &dev_attr_enable_poll);
1193 device_remove_file(&pdev->dev, &dev_attr_cover_switch);
1194 free_irq(OMAP_GPIO_IRQ(host->switch_pin), host);
1195 omap_free_gpio(host->switch_pin);
1196 host->switch_pin = -1;
1197 del_timer_sync(&host->switch_timer);
1198 flush_scheduled_work();
1199 }
1200 if (host->iclk && !IS_ERR(host->iclk)) 1535 if (host->iclk && !IS_ERR(host->iclk))
1201 clk_put(host->iclk); 1536 clk_put(host->iclk);
1202 if (host->fclk && !IS_ERR(host->fclk)) 1537 if (host->fclk && !IS_ERR(host->fclk))
@@ -1205,7 +1540,7 @@ static int mmc_omap_remove(struct platform_device *pdev)
1205 release_mem_region(pdev->resource[0].start, 1540 release_mem_region(pdev->resource[0].start,
1206 pdev->resource[0].end - pdev->resource[0].start + 1); 1541 pdev->resource[0].end - pdev->resource[0].start + 1);
1207 1542
1208 mmc_free_host(host->mmc); 1543 kfree(host);
1209 1544
1210 return 0; 1545 return 0;
1211} 1546}
@@ -1213,35 +1548,47 @@ static int mmc_omap_remove(struct platform_device *pdev)
1213#ifdef CONFIG_PM 1548#ifdef CONFIG_PM
1214static int mmc_omap_suspend(struct platform_device *pdev, pm_message_t mesg) 1549static int mmc_omap_suspend(struct platform_device *pdev, pm_message_t mesg)
1215{ 1550{
1216 int ret = 0; 1551 int i, ret = 0;
1217 struct mmc_omap_host *host = platform_get_drvdata(pdev); 1552 struct mmc_omap_host *host = platform_get_drvdata(pdev);
1218 1553
1219 if (host && host->suspended) 1554 if (host == NULL || host->suspended)
1220 return 0; 1555 return 0;
1221 1556
1222 if (host) { 1557 for (i = 0; i < host->nr_slots; i++) {
1223 ret = mmc_suspend_host(host->mmc, mesg); 1558 struct mmc_omap_slot *slot;
1224 if (ret == 0) 1559
1225 host->suspended = 1; 1560 slot = host->slots[i];
1561 ret = mmc_suspend_host(slot->mmc, mesg);
1562 if (ret < 0) {
1563 while (--i >= 0) {
1564 slot = host->slots[i];
1565 mmc_resume_host(slot->mmc);
1566 }
1567 return ret;
1568 }
1226 } 1569 }
1227 return ret; 1570 host->suspended = 1;
1571 return 0;
1228} 1572}
1229 1573
1230static int mmc_omap_resume(struct platform_device *pdev) 1574static int mmc_omap_resume(struct platform_device *pdev)
1231{ 1575{
1232 int ret = 0; 1576 int i, ret = 0;
1233 struct mmc_omap_host *host = platform_get_drvdata(pdev); 1577 struct mmc_omap_host *host = platform_get_drvdata(pdev);
1234 1578
1235 if (host && !host->suspended) 1579 if (host == NULL || !host->suspended)
1236 return 0; 1580 return 0;
1237 1581
1238 if (host) { 1582 for (i = 0; i < host->nr_slots; i++) {
1239 ret = mmc_resume_host(host->mmc); 1583 struct mmc_omap_slot *slot;
1240 if (ret == 0) 1584 slot = host->slots[i];
1241 host->suspended = 0; 1585 ret = mmc_resume_host(slot->mmc);
1242 } 1586 if (ret < 0)
1587 return ret;
1243 1588
1244 return ret; 1589 host->suspended = 0;
1590 }
1591 return 0;
1245} 1592}
1246#else 1593#else
1247#define mmc_omap_suspend NULL 1594#define mmc_omap_suspend NULL
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 4b673aa2dc3c..07c2048b230b 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * linux/drivers/mmc/host/sdhci.c - Secure Digital Host Controller Interface driver 2 * linux/drivers/mmc/host/sdhci.c - Secure Digital Host Controller Interface driver
3 * 3 *
4 * Copyright (C) 2005-2007 Pierre Ossman, All Rights Reserved. 4 * Copyright (C) 2005-2008 Pierre Ossman, All Rights Reserved.
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify 6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by 7 * it under the terms of the GNU General Public License as published by
@@ -19,6 +19,8 @@
19#include <linux/dma-mapping.h> 19#include <linux/dma-mapping.h>
20#include <linux/scatterlist.h> 20#include <linux/scatterlist.h>
21 21
22#include <linux/leds.h>
23
22#include <linux/mmc/host.h> 24#include <linux/mmc/host.h>
23 25
24#include "sdhci.h" 26#include "sdhci.h"
@@ -30,10 +32,6 @@
30 32
31static unsigned int debug_quirks = 0; 33static unsigned int debug_quirks = 0;
32 34
33/* For multi controllers in one platform case */
34static u16 chip_index = 0;
35static spinlock_t index_lock;
36
37/* 35/*
38 * Different quirks to handle when the hardware deviates from a strict 36 * Different quirks to handle when the hardware deviates from a strict
39 * interpretation of the SDHCI specification. 37 * interpretation of the SDHCI specification.
@@ -43,7 +41,7 @@ static spinlock_t index_lock;
43#define SDHCI_QUIRK_CLOCK_BEFORE_RESET (1<<0) 41#define SDHCI_QUIRK_CLOCK_BEFORE_RESET (1<<0)
44/* Controller has bad caps bits, but really supports DMA */ 42/* Controller has bad caps bits, but really supports DMA */
45#define SDHCI_QUIRK_FORCE_DMA (1<<1) 43#define SDHCI_QUIRK_FORCE_DMA (1<<1)
46/* Controller doesn't like some resets when there is no card inserted. */ 44/* Controller doesn't like to be reset when there is no card inserted. */
47#define SDHCI_QUIRK_NO_CARD_NO_RESET (1<<2) 45#define SDHCI_QUIRK_NO_CARD_NO_RESET (1<<2)
48/* Controller doesn't like clearing the power reg before a change */ 46/* Controller doesn't like clearing the power reg before a change */
49#define SDHCI_QUIRK_SINGLE_POWER_WRITE (1<<3) 47#define SDHCI_QUIRK_SINGLE_POWER_WRITE (1<<3)
@@ -71,13 +69,21 @@ static const struct pci_device_id pci_ids[] __devinitdata = {
71 { 69 {
72 .vendor = PCI_VENDOR_ID_RICOH, 70 .vendor = PCI_VENDOR_ID_RICOH,
73 .device = PCI_DEVICE_ID_RICOH_R5C822, 71 .device = PCI_DEVICE_ID_RICOH_R5C822,
74 .subvendor = PCI_ANY_ID, 72 .subvendor = PCI_VENDOR_ID_SAMSUNG,
75 .subdevice = PCI_ANY_ID, 73 .subdevice = PCI_ANY_ID,
76 .driver_data = SDHCI_QUIRK_FORCE_DMA | 74 .driver_data = SDHCI_QUIRK_FORCE_DMA |
77 SDHCI_QUIRK_NO_CARD_NO_RESET, 75 SDHCI_QUIRK_NO_CARD_NO_RESET,
78 }, 76 },
79 77
80 { 78 {
79 .vendor = PCI_VENDOR_ID_RICOH,
80 .device = PCI_DEVICE_ID_RICOH_R5C822,
81 .subvendor = PCI_ANY_ID,
82 .subdevice = PCI_ANY_ID,
83 .driver_data = SDHCI_QUIRK_FORCE_DMA,
84 },
85
86 {
81 .vendor = PCI_VENDOR_ID_TI, 87 .vendor = PCI_VENDOR_ID_TI,
82 .device = PCI_DEVICE_ID_TI_XX21_XX11_SD, 88 .device = PCI_DEVICE_ID_TI_XX21_XX11_SD,
83 .subvendor = PCI_ANY_ID, 89 .subvendor = PCI_ANY_ID,
@@ -256,6 +262,24 @@ static void sdhci_deactivate_led(struct sdhci_host *host)
256 writeb(ctrl, host->ioaddr + SDHCI_HOST_CONTROL); 262 writeb(ctrl, host->ioaddr + SDHCI_HOST_CONTROL);
257} 263}
258 264
265#ifdef CONFIG_LEDS_CLASS
266static void sdhci_led_control(struct led_classdev *led,
267 enum led_brightness brightness)
268{
269 struct sdhci_host *host = container_of(led, struct sdhci_host, led);
270 unsigned long flags;
271
272 spin_lock_irqsave(&host->lock, flags);
273
274 if (brightness == LED_OFF)
275 sdhci_deactivate_led(host);
276 else
277 sdhci_activate_led(host);
278
279 spin_unlock_irqrestore(&host->lock, flags);
280}
281#endif
282
259/*****************************************************************************\ 283/*****************************************************************************\
260 * * 284 * *
261 * Core functions * 285 * Core functions *
@@ -773,7 +797,9 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq)
773 797
774 WARN_ON(host->mrq != NULL); 798 WARN_ON(host->mrq != NULL);
775 799
800#ifndef CONFIG_LEDS_CLASS
776 sdhci_activate_led(host); 801 sdhci_activate_led(host);
802#endif
777 803
778 host->mrq = mrq; 804 host->mrq = mrq;
779 805
@@ -965,7 +991,9 @@ static void sdhci_tasklet_finish(unsigned long param)
965 host->cmd = NULL; 991 host->cmd = NULL;
966 host->data = NULL; 992 host->data = NULL;
967 993
994#ifndef CONFIG_LEDS_CLASS
968 sdhci_deactivate_led(host); 995 sdhci_deactivate_led(host);
996#endif
969 997
970 mmiowb(); 998 mmiowb();
971 spin_unlock_irqrestore(&host->lock, flags); 999 spin_unlock_irqrestore(&host->lock, flags);
@@ -1105,7 +1133,8 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id)
1105 goto out; 1133 goto out;
1106 } 1134 }
1107 1135
1108 DBG("*** %s got interrupt: 0x%08x\n", host->slot_descr, intmask); 1136 DBG("*** %s got interrupt: 0x%08x\n",
1137 mmc_hostname(host->mmc), intmask);
1109 1138
1110 if (intmask & (SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE)) { 1139 if (intmask & (SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE)) {
1111 writel(intmask & (SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE), 1140 writel(intmask & (SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE),
@@ -1235,7 +1264,7 @@ static int sdhci_resume (struct pci_dev *pdev)
1235 if (chip->hosts[i]->flags & SDHCI_USE_DMA) 1264 if (chip->hosts[i]->flags & SDHCI_USE_DMA)
1236 pci_set_master(pdev); 1265 pci_set_master(pdev);
1237 ret = request_irq(chip->hosts[i]->irq, sdhci_irq, 1266 ret = request_irq(chip->hosts[i]->irq, sdhci_irq,
1238 IRQF_SHARED, chip->hosts[i]->slot_descr, 1267 IRQF_SHARED, mmc_hostname(chip->hosts[i]->mmc),
1239 chip->hosts[i]); 1268 chip->hosts[i]);
1240 if (ret) 1269 if (ret)
1241 return ret; 1270 return ret;
@@ -1324,9 +1353,7 @@ static int __devinit sdhci_probe_slot(struct pci_dev *pdev, int slot)
1324 1353
1325 DBG("slot %d at 0x%08lx, irq %d\n", slot, host->addr, host->irq); 1354 DBG("slot %d at 0x%08lx, irq %d\n", slot, host->addr, host->irq);
1326 1355
1327 snprintf(host->slot_descr, 20, "sdhc%d:slot%d", chip->index, slot); 1356 ret = pci_request_region(pdev, host->bar, mmc_hostname(mmc));
1328
1329 ret = pci_request_region(pdev, host->bar, host->slot_descr);
1330 if (ret) 1357 if (ret)
1331 goto free; 1358 goto free;
1332 1359
@@ -1343,7 +1370,7 @@ static int __devinit sdhci_probe_slot(struct pci_dev *pdev, int slot)
1343 version = (version & SDHCI_SPEC_VER_MASK) >> SDHCI_SPEC_VER_SHIFT; 1370 version = (version & SDHCI_SPEC_VER_MASK) >> SDHCI_SPEC_VER_SHIFT;
1344 if (version > 1) { 1371 if (version > 1) {
1345 printk(KERN_ERR "%s: Unknown controller version (%d). " 1372 printk(KERN_ERR "%s: Unknown controller version (%d). "
1346 "You may experience problems.\n", host->slot_descr, 1373 "You may experience problems.\n", mmc_hostname(mmc),
1347 version); 1374 version);
1348 } 1375 }
1349 1376
@@ -1366,13 +1393,13 @@ static int __devinit sdhci_probe_slot(struct pci_dev *pdev, int slot)
1366 (host->flags & SDHCI_USE_DMA)) { 1393 (host->flags & SDHCI_USE_DMA)) {
1367 printk(KERN_WARNING "%s: Will use DMA " 1394 printk(KERN_WARNING "%s: Will use DMA "
1368 "mode even though HW doesn't fully " 1395 "mode even though HW doesn't fully "
1369 "claim to support it.\n", host->slot_descr); 1396 "claim to support it.\n", mmc_hostname(mmc));
1370 } 1397 }
1371 1398
1372 if (host->flags & SDHCI_USE_DMA) { 1399 if (host->flags & SDHCI_USE_DMA) {
1373 if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) { 1400 if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
1374 printk(KERN_WARNING "%s: No suitable DMA available. " 1401 printk(KERN_WARNING "%s: No suitable DMA available. "
1375 "Falling back to PIO.\n", host->slot_descr); 1402 "Falling back to PIO.\n", mmc_hostname(mmc));
1376 host->flags &= ~SDHCI_USE_DMA; 1403 host->flags &= ~SDHCI_USE_DMA;
1377 } 1404 }
1378 } 1405 }
@@ -1386,7 +1413,7 @@ static int __devinit sdhci_probe_slot(struct pci_dev *pdev, int slot)
1386 (caps & SDHCI_CLOCK_BASE_MASK) >> SDHCI_CLOCK_BASE_SHIFT; 1413 (caps & SDHCI_CLOCK_BASE_MASK) >> SDHCI_CLOCK_BASE_SHIFT;
1387 if (host->max_clk == 0) { 1414 if (host->max_clk == 0) {
1388 printk(KERN_ERR "%s: Hardware doesn't specify base clock " 1415 printk(KERN_ERR "%s: Hardware doesn't specify base clock "
1389 "frequency.\n", host->slot_descr); 1416 "frequency.\n", mmc_hostname(mmc));
1390 ret = -ENODEV; 1417 ret = -ENODEV;
1391 goto unmap; 1418 goto unmap;
1392 } 1419 }
@@ -1396,7 +1423,7 @@ static int __devinit sdhci_probe_slot(struct pci_dev *pdev, int slot)
1396 (caps & SDHCI_TIMEOUT_CLK_MASK) >> SDHCI_TIMEOUT_CLK_SHIFT; 1423 (caps & SDHCI_TIMEOUT_CLK_MASK) >> SDHCI_TIMEOUT_CLK_SHIFT;
1397 if (host->timeout_clk == 0) { 1424 if (host->timeout_clk == 0) {
1398 printk(KERN_ERR "%s: Hardware doesn't specify timeout clock " 1425 printk(KERN_ERR "%s: Hardware doesn't specify timeout clock "
1399 "frequency.\n", host->slot_descr); 1426 "frequency.\n", mmc_hostname(mmc));
1400 ret = -ENODEV; 1427 ret = -ENODEV;
1401 goto unmap; 1428 goto unmap;
1402 } 1429 }
@@ -1424,7 +1451,7 @@ static int __devinit sdhci_probe_slot(struct pci_dev *pdev, int slot)
1424 1451
1425 if (mmc->ocr_avail == 0) { 1452 if (mmc->ocr_avail == 0) {
1426 printk(KERN_ERR "%s: Hardware doesn't report any " 1453 printk(KERN_ERR "%s: Hardware doesn't report any "
1427 "support voltages.\n", host->slot_descr); 1454 "support voltages.\n", mmc_hostname(mmc));
1428 ret = -ENODEV; 1455 ret = -ENODEV;
1429 goto unmap; 1456 goto unmap;
1430 } 1457 }
@@ -1458,8 +1485,8 @@ static int __devinit sdhci_probe_slot(struct pci_dev *pdev, int slot)
1458 */ 1485 */
1459 mmc->max_blk_size = (caps & SDHCI_MAX_BLOCK_MASK) >> SDHCI_MAX_BLOCK_SHIFT; 1486 mmc->max_blk_size = (caps & SDHCI_MAX_BLOCK_MASK) >> SDHCI_MAX_BLOCK_SHIFT;
1460 if (mmc->max_blk_size >= 3) { 1487 if (mmc->max_blk_size >= 3) {
1461 printk(KERN_WARNING "%s: Invalid maximum block size, assuming 512\n", 1488 printk(KERN_WARNING "%s: Invalid maximum block size, "
1462 host->slot_descr); 1489 "assuming 512 bytes\n", mmc_hostname(mmc));
1463 mmc->max_blk_size = 512; 1490 mmc->max_blk_size = 512;
1464 } else 1491 } else
1465 mmc->max_blk_size = 512 << mmc->max_blk_size; 1492 mmc->max_blk_size = 512 << mmc->max_blk_size;
@@ -1480,7 +1507,7 @@ static int __devinit sdhci_probe_slot(struct pci_dev *pdev, int slot)
1480 setup_timer(&host->timer, sdhci_timeout_timer, (unsigned long)host); 1507 setup_timer(&host->timer, sdhci_timeout_timer, (unsigned long)host);
1481 1508
1482 ret = request_irq(host->irq, sdhci_irq, IRQF_SHARED, 1509 ret = request_irq(host->irq, sdhci_irq, IRQF_SHARED,
1483 host->slot_descr, host); 1510 mmc_hostname(mmc), host);
1484 if (ret) 1511 if (ret)
1485 goto untasklet; 1512 goto untasklet;
1486 1513
@@ -1490,16 +1517,32 @@ static int __devinit sdhci_probe_slot(struct pci_dev *pdev, int slot)
1490 sdhci_dumpregs(host); 1517 sdhci_dumpregs(host);
1491#endif 1518#endif
1492 1519
1520#ifdef CONFIG_LEDS_CLASS
1521 host->led.name = mmc_hostname(mmc);
1522 host->led.brightness = LED_OFF;
1523 host->led.default_trigger = mmc_hostname(mmc);
1524 host->led.brightness_set = sdhci_led_control;
1525
1526 ret = led_classdev_register(&pdev->dev, &host->led);
1527 if (ret)
1528 goto reset;
1529#endif
1530
1493 mmiowb(); 1531 mmiowb();
1494 1532
1495 mmc_add_host(mmc); 1533 mmc_add_host(mmc);
1496 1534
1497 printk(KERN_INFO "%s: SDHCI at 0x%08lx irq %d %s\n", mmc_hostname(mmc), 1535 printk(KERN_INFO "%s: SDHCI at 0x%08lx irq %d %s\n",
1498 host->addr, host->irq, 1536 mmc_hostname(mmc), host->addr, host->irq,
1499 (host->flags & SDHCI_USE_DMA)?"DMA":"PIO"); 1537 (host->flags & SDHCI_USE_DMA)?"DMA":"PIO");
1500 1538
1501 return 0; 1539 return 0;
1502 1540
1541#ifdef CONFIG_LEDS_CLASS
1542reset:
1543 sdhci_reset(host, SDHCI_RESET_ALL);
1544 free_irq(host->irq, host);
1545#endif
1503untasklet: 1546untasklet:
1504 tasklet_kill(&host->card_tasklet); 1547 tasklet_kill(&host->card_tasklet);
1505 tasklet_kill(&host->finish_tasklet); 1548 tasklet_kill(&host->finish_tasklet);
@@ -1527,6 +1570,10 @@ static void sdhci_remove_slot(struct pci_dev *pdev, int slot)
1527 1570
1528 mmc_remove_host(mmc); 1571 mmc_remove_host(mmc);
1529 1572
1573#ifdef CONFIG_LEDS_CLASS
1574 led_classdev_unregister(&host->led);
1575#endif
1576
1530 sdhci_reset(host, SDHCI_RESET_ALL); 1577 sdhci_reset(host, SDHCI_RESET_ALL);
1531 1578
1532 free_irq(host->irq, host); 1579 free_irq(host->irq, host);
@@ -1589,11 +1636,6 @@ static int __devinit sdhci_probe(struct pci_dev *pdev,
1589 chip->num_slots = slots; 1636 chip->num_slots = slots;
1590 pci_set_drvdata(pdev, chip); 1637 pci_set_drvdata(pdev, chip);
1591 1638
1592 /* Add for multi controller case */
1593 spin_lock(&index_lock);
1594 chip->index = chip_index++;
1595 spin_unlock(&index_lock);
1596
1597 for (i = 0;i < slots;i++) { 1639 for (i = 0;i < slots;i++) {
1598 ret = sdhci_probe_slot(pdev, i); 1640 ret = sdhci_probe_slot(pdev, i);
1599 if (ret) { 1641 if (ret) {
@@ -1654,8 +1696,6 @@ static int __init sdhci_drv_init(void)
1654 ": Secure Digital Host Controller Interface driver\n"); 1696 ": Secure Digital Host Controller Interface driver\n");
1655 printk(KERN_INFO DRIVER_NAME ": Copyright(c) Pierre Ossman\n"); 1697 printk(KERN_INFO DRIVER_NAME ": Copyright(c) Pierre Ossman\n");
1656 1698
1657 spin_lock_init(&index_lock);
1658
1659 return pci_register_driver(&sdhci_driver); 1699 return pci_register_driver(&sdhci_driver);
1660} 1700}
1661 1701
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
index d5a38f1b755a..7fb02e177a3d 100644
--- a/drivers/mmc/host/sdhci.h
+++ b/drivers/mmc/host/sdhci.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * linux/drivers/mmc/host/sdhci.h - Secure Digital Host Controller Interface driver 2 * linux/drivers/mmc/host/sdhci.h - Secure Digital Host Controller Interface driver
3 * 3 *
4 * Copyright (C) 2005-2007 Pierre Ossman, All Rights Reserved. 4 * Copyright (C) 2005-2008 Pierre Ossman, All Rights Reserved.
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify 6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by 7 * it under the terms of the GNU General Public License as published by
@@ -168,6 +168,10 @@ struct sdhci_host {
168 struct sdhci_chip *chip; 168 struct sdhci_chip *chip;
169 struct mmc_host *mmc; /* MMC structure */ 169 struct mmc_host *mmc; /* MMC structure */
170 170
171#ifdef CONFIG_LEDS_CLASS
172 struct led_classdev led; /* LED control */
173#endif
174
171 spinlock_t lock; /* Mutex */ 175 spinlock_t lock; /* Mutex */
172 176
173 int flags; /* Host attributes */ 177 int flags; /* Host attributes */
@@ -190,8 +194,6 @@ struct sdhci_host {
190 int offset; /* Offset into current sg */ 194 int offset; /* Offset into current sg */
191 int remain; /* Bytes left in current */ 195 int remain; /* Bytes left in current */
192 196
193 char slot_descr[20]; /* Name for reservations */
194
195 int irq; /* Device IRQ */ 197 int irq; /* Device IRQ */
196 int bar; /* PCI BAR index */ 198 int bar; /* PCI BAR index */
197 unsigned long addr; /* Bus address */ 199 unsigned long addr; /* Bus address */
@@ -208,7 +210,6 @@ struct sdhci_chip {
208 210
209 unsigned long quirks; 211 unsigned long quirks;
210 212
211 int index; /* Index for chip0, chip1 ...*/
212 int num_slots; /* Slots on controller */ 213 int num_slots; /* Slots on controller */
213 struct sdhci_host *hosts[0]; /* Pointers to hosts */ 214 struct sdhci_host *hosts[0]; /* Pointers to hosts */
214}; 215};
diff --git a/fs/Kconfig b/fs/Kconfig
index 028ae38ecc52..8b18a8758677 100644
--- a/fs/Kconfig
+++ b/fs/Kconfig
@@ -689,6 +689,7 @@ config ZISOFS
689 689
690config UDF_FS 690config UDF_FS
691 tristate "UDF file system support" 691 tristate "UDF file system support"
692 select CRC_ITU_T
692 help 693 help
693 This is the new file system used on some CD-ROMs and DVDs. Say Y if 694 This is the new file system used on some CD-ROMs and DVDs. Say Y if
694 you intend to mount DVD discs or CDRW's written in packet mode, or 695 you intend to mount DVD discs or CDRW's written in packet mode, or
diff --git a/fs/Kconfig.binfmt b/fs/Kconfig.binfmt
index b5c3b6114add..853845abcca6 100644
--- a/fs/Kconfig.binfmt
+++ b/fs/Kconfig.binfmt
@@ -62,7 +62,7 @@ config BINFMT_SHARED_FLAT
62config BINFMT_AOUT 62config BINFMT_AOUT
63 tristate "Kernel support for a.out and ECOFF binaries" 63 tristate "Kernel support for a.out and ECOFF binaries"
64 depends on ARCH_SUPPORTS_AOUT && \ 64 depends on ARCH_SUPPORTS_AOUT && \
65 (X86_32 || ALPHA || ARM || M68K || SPARC32) 65 (X86_32 || ALPHA || ARM || M68K)
66 ---help--- 66 ---help---
67 A.out (Assembler.OUTput) is a set of formats for libraries and 67 A.out (Assembler.OUTput) is a set of formats for libraries and
68 executables used in the earliest versions of UNIX. Linux used 68 executables used in the earliest versions of UNIX. Linux used
diff --git a/fs/dlm/Makefile b/fs/dlm/Makefile
index d248e60951ba..ca1c9124c8ce 100644
--- a/fs/dlm/Makefile
+++ b/fs/dlm/Makefile
@@ -10,6 +10,7 @@ dlm-y := ast.o \
10 midcomms.o \ 10 midcomms.o \
11 netlink.o \ 11 netlink.o \
12 lowcomms.o \ 12 lowcomms.o \
13 plock.o \
13 rcom.o \ 14 rcom.o \
14 recover.o \ 15 recover.o \
15 recoverd.o \ 16 recoverd.o \
diff --git a/fs/dlm/config.c b/fs/dlm/config.c
index c3ad1dff3b25..eac23bd288b2 100644
--- a/fs/dlm/config.c
+++ b/fs/dlm/config.c
@@ -114,7 +114,7 @@ struct cluster_attribute {
114}; 114};
115 115
116static ssize_t cluster_set(struct cluster *cl, unsigned int *cl_field, 116static ssize_t cluster_set(struct cluster *cl, unsigned int *cl_field,
117 unsigned int *info_field, int check_zero, 117 int *info_field, int check_zero,
118 const char *buf, size_t len) 118 const char *buf, size_t len)
119{ 119{
120 unsigned int x; 120 unsigned int x;
@@ -284,6 +284,7 @@ struct node {
284 struct list_head list; /* space->members */ 284 struct list_head list; /* space->members */
285 int nodeid; 285 int nodeid;
286 int weight; 286 int weight;
287 int new;
287}; 288};
288 289
289static struct configfs_group_operations clusters_ops = { 290static struct configfs_group_operations clusters_ops = {
@@ -565,6 +566,7 @@ static struct config_item *make_node(struct config_group *g, const char *name)
565 config_item_init_type_name(&nd->item, name, &node_type); 566 config_item_init_type_name(&nd->item, name, &node_type);
566 nd->nodeid = -1; 567 nd->nodeid = -1;
567 nd->weight = 1; /* default weight of 1 if none is set */ 568 nd->weight = 1; /* default weight of 1 if none is set */
569 nd->new = 1; /* set to 0 once it's been read by dlm_nodeid_list() */
568 570
569 mutex_lock(&sp->members_lock); 571 mutex_lock(&sp->members_lock);
570 list_add(&nd->list, &sp->members); 572 list_add(&nd->list, &sp->members);
@@ -805,12 +807,13 @@ static void put_comm(struct comm *cm)
805} 807}
806 808
807/* caller must free mem */ 809/* caller must free mem */
808int dlm_nodeid_list(char *lsname, int **ids_out) 810int dlm_nodeid_list(char *lsname, int **ids_out, int *ids_count_out,
811 int **new_out, int *new_count_out)
809{ 812{
810 struct space *sp; 813 struct space *sp;
811 struct node *nd; 814 struct node *nd;
812 int i = 0, rv = 0; 815 int i = 0, rv = 0, ids_count = 0, new_count = 0;
813 int *ids; 816 int *ids, *new;
814 817
815 sp = get_space(lsname); 818 sp = get_space(lsname);
816 if (!sp) 819 if (!sp)
@@ -818,23 +821,50 @@ int dlm_nodeid_list(char *lsname, int **ids_out)
818 821
819 mutex_lock(&sp->members_lock); 822 mutex_lock(&sp->members_lock);
820 if (!sp->members_count) { 823 if (!sp->members_count) {
821 rv = 0; 824 rv = -EINVAL;
825 printk(KERN_ERR "dlm: zero members_count\n");
822 goto out; 826 goto out;
823 } 827 }
824 828
825 ids = kcalloc(sp->members_count, sizeof(int), GFP_KERNEL); 829 ids_count = sp->members_count;
830
831 ids = kcalloc(ids_count, sizeof(int), GFP_KERNEL);
826 if (!ids) { 832 if (!ids) {
827 rv = -ENOMEM; 833 rv = -ENOMEM;
828 goto out; 834 goto out;
829 } 835 }
830 836
831 rv = sp->members_count; 837 list_for_each_entry(nd, &sp->members, list) {
832 list_for_each_entry(nd, &sp->members, list)
833 ids[i++] = nd->nodeid; 838 ids[i++] = nd->nodeid;
839 if (nd->new)
840 new_count++;
841 }
842
843 if (ids_count != i)
844 printk(KERN_ERR "dlm: bad nodeid count %d %d\n", ids_count, i);
845
846 if (!new_count)
847 goto out_ids;
848
849 new = kcalloc(new_count, sizeof(int), GFP_KERNEL);
850 if (!new) {
851 kfree(ids);
852 rv = -ENOMEM;
853 goto out;
854 }
834 855
835 if (rv != i) 856 i = 0;
836 printk("bad nodeid count %d %d\n", rv, i); 857 list_for_each_entry(nd, &sp->members, list) {
858 if (nd->new) {
859 new[i++] = nd->nodeid;
860 nd->new = 0;
861 }
862 }
863 *new_count_out = new_count;
864 *new_out = new;
837 865
866 out_ids:
867 *ids_count_out = ids_count;
838 *ids_out = ids; 868 *ids_out = ids;
839 out: 869 out:
840 mutex_unlock(&sp->members_lock); 870 mutex_unlock(&sp->members_lock);
diff --git a/fs/dlm/config.h b/fs/dlm/config.h
index a3170fe22090..4f1d6fce58c5 100644
--- a/fs/dlm/config.h
+++ b/fs/dlm/config.h
@@ -35,7 +35,8 @@ extern struct dlm_config_info dlm_config;
35int dlm_config_init(void); 35int dlm_config_init(void);
36void dlm_config_exit(void); 36void dlm_config_exit(void);
37int dlm_node_weight(char *lsname, int nodeid); 37int dlm_node_weight(char *lsname, int nodeid);
38int dlm_nodeid_list(char *lsname, int **ids_out); 38int dlm_nodeid_list(char *lsname, int **ids_out, int *ids_count_out,
39 int **new_out, int *new_count_out);
39int dlm_nodeid_to_addr(int nodeid, struct sockaddr_storage *addr); 40int dlm_nodeid_to_addr(int nodeid, struct sockaddr_storage *addr);
40int dlm_addr_to_nodeid(struct sockaddr_storage *addr, int *nodeid); 41int dlm_addr_to_nodeid(struct sockaddr_storage *addr, int *nodeid);
41int dlm_our_nodeid(void); 42int dlm_our_nodeid(void);
diff --git a/fs/dlm/dlm_internal.h b/fs/dlm/dlm_internal.h
index 7a8824f475f2..5a7ac33b629c 100644
--- a/fs/dlm/dlm_internal.h
+++ b/fs/dlm/dlm_internal.h
@@ -42,8 +42,6 @@
42#include <linux/dlm.h> 42#include <linux/dlm.h>
43#include "config.h" 43#include "config.h"
44 44
45#define DLM_LOCKSPACE_LEN 64
46
47/* Size of the temp buffer midcomms allocates on the stack. 45/* Size of the temp buffer midcomms allocates on the stack.
48 We try to make this large enough so most messages fit. 46 We try to make this large enough so most messages fit.
49 FIXME: should sctp make this unnecessary? */ 47 FIXME: should sctp make this unnecessary? */
@@ -132,8 +130,10 @@ struct dlm_member {
132 130
133struct dlm_recover { 131struct dlm_recover {
134 struct list_head list; 132 struct list_head list;
135 int *nodeids; 133 int *nodeids; /* nodeids of all members */
136 int node_count; 134 int node_count;
135 int *new; /* nodeids of new members */
136 int new_count;
137 uint64_t seq; 137 uint64_t seq;
138}; 138};
139 139
@@ -579,6 +579,8 @@ static inline int dlm_no_directory(struct dlm_ls *ls)
579int dlm_netlink_init(void); 579int dlm_netlink_init(void);
580void dlm_netlink_exit(void); 580void dlm_netlink_exit(void);
581void dlm_timeout_warn(struct dlm_lkb *lkb); 581void dlm_timeout_warn(struct dlm_lkb *lkb);
582int dlm_plock_init(void);
583void dlm_plock_exit(void);
582 584
583#ifdef CONFIG_DLM_DEBUG 585#ifdef CONFIG_DLM_DEBUG
584int dlm_register_debugfs(void); 586int dlm_register_debugfs(void);
diff --git a/fs/dlm/lock.c b/fs/dlm/lock.c
index 8f250ac8b928..2d3d1027ce2b 100644
--- a/fs/dlm/lock.c
+++ b/fs/dlm/lock.c
@@ -165,7 +165,7 @@ void dlm_print_lkb(struct dlm_lkb *lkb)
165 lkb->lkb_grmode, lkb->lkb_wait_type, lkb->lkb_ast_type); 165 lkb->lkb_grmode, lkb->lkb_wait_type, lkb->lkb_ast_type);
166} 166}
167 167
168void dlm_print_rsb(struct dlm_rsb *r) 168static void dlm_print_rsb(struct dlm_rsb *r)
169{ 169{
170 printk(KERN_ERR "rsb: nodeid %d flags %lx first %x rlc %d name %s\n", 170 printk(KERN_ERR "rsb: nodeid %d flags %lx first %x rlc %d name %s\n",
171 r->res_nodeid, r->res_flags, r->res_first_lkid, 171 r->res_nodeid, r->res_flags, r->res_first_lkid,
@@ -1956,8 +1956,7 @@ static void confirm_master(struct dlm_rsb *r, int error)
1956 list_del_init(&lkb->lkb_rsb_lookup); 1956 list_del_init(&lkb->lkb_rsb_lookup);
1957 r->res_first_lkid = lkb->lkb_id; 1957 r->res_first_lkid = lkb->lkb_id;
1958 _request_lock(r, lkb); 1958 _request_lock(r, lkb);
1959 } else 1959 }
1960 r->res_nodeid = -1;
1961 break; 1960 break;
1962 1961
1963 default: 1962 default:
diff --git a/fs/dlm/lock.h b/fs/dlm/lock.h
index 05d9c82e646b..88e93c80cc22 100644
--- a/fs/dlm/lock.h
+++ b/fs/dlm/lock.h
@@ -13,7 +13,6 @@
13#ifndef __LOCK_DOT_H__ 13#ifndef __LOCK_DOT_H__
14#define __LOCK_DOT_H__ 14#define __LOCK_DOT_H__
15 15
16void dlm_print_rsb(struct dlm_rsb *r);
17void dlm_dump_rsb(struct dlm_rsb *r); 16void dlm_dump_rsb(struct dlm_rsb *r);
18void dlm_print_lkb(struct dlm_lkb *lkb); 17void dlm_print_lkb(struct dlm_lkb *lkb);
19void dlm_receive_message_saved(struct dlm_ls *ls, struct dlm_message *ms); 18void dlm_receive_message_saved(struct dlm_ls *ls, struct dlm_message *ms);
diff --git a/fs/dlm/main.c b/fs/dlm/main.c
index 58487fb95a4c..b80e0aa3cfa5 100644
--- a/fs/dlm/main.c
+++ b/fs/dlm/main.c
@@ -46,10 +46,16 @@ static int __init init_dlm(void)
46 if (error) 46 if (error)
47 goto out_user; 47 goto out_user;
48 48
49 error = dlm_plock_init();
50 if (error)
51 goto out_netlink;
52
49 printk("DLM (built %s %s) installed\n", __DATE__, __TIME__); 53 printk("DLM (built %s %s) installed\n", __DATE__, __TIME__);
50 54
51 return 0; 55 return 0;
52 56
57 out_netlink:
58 dlm_netlink_exit();
53 out_user: 59 out_user:
54 dlm_user_exit(); 60 dlm_user_exit();
55 out_debug: 61 out_debug:
@@ -66,6 +72,7 @@ static int __init init_dlm(void)
66 72
67static void __exit exit_dlm(void) 73static void __exit exit_dlm(void)
68{ 74{
75 dlm_plock_exit();
69 dlm_netlink_exit(); 76 dlm_netlink_exit();
70 dlm_user_exit(); 77 dlm_user_exit();
71 dlm_config_exit(); 78 dlm_config_exit();
diff --git a/fs/dlm/member.c b/fs/dlm/member.c
index fa17f5a27883..26133f05ae3a 100644
--- a/fs/dlm/member.c
+++ b/fs/dlm/member.c
@@ -210,6 +210,23 @@ int dlm_recover_members(struct dlm_ls *ls, struct dlm_recover *rv, int *neg_out)
210 } 210 }
211 } 211 }
212 212
213 /* Add an entry to ls_nodes_gone for members that were removed and
214 then added again, so that previous state for these nodes will be
215 cleared during recovery. */
216
217 for (i = 0; i < rv->new_count; i++) {
218 if (!dlm_is_member(ls, rv->new[i]))
219 continue;
220 log_debug(ls, "new nodeid %d is a re-added member", rv->new[i]);
221
222 memb = kzalloc(sizeof(struct dlm_member), GFP_KERNEL);
223 if (!memb)
224 return -ENOMEM;
225 memb->nodeid = rv->new[i];
226 list_add_tail(&memb->list, &ls->ls_nodes_gone);
227 neg++;
228 }
229
213 /* add new members to ls_nodes */ 230 /* add new members to ls_nodes */
214 231
215 for (i = 0; i < rv->node_count; i++) { 232 for (i = 0; i < rv->node_count; i++) {
@@ -314,15 +331,16 @@ int dlm_ls_stop(struct dlm_ls *ls)
314int dlm_ls_start(struct dlm_ls *ls) 331int dlm_ls_start(struct dlm_ls *ls)
315{ 332{
316 struct dlm_recover *rv = NULL, *rv_old; 333 struct dlm_recover *rv = NULL, *rv_old;
317 int *ids = NULL; 334 int *ids = NULL, *new = NULL;
318 int error, count; 335 int error, ids_count = 0, new_count = 0;
319 336
320 rv = kzalloc(sizeof(struct dlm_recover), GFP_KERNEL); 337 rv = kzalloc(sizeof(struct dlm_recover), GFP_KERNEL);
321 if (!rv) 338 if (!rv)
322 return -ENOMEM; 339 return -ENOMEM;
323 340
324 error = count = dlm_nodeid_list(ls->ls_name, &ids); 341 error = dlm_nodeid_list(ls->ls_name, &ids, &ids_count,
325 if (error <= 0) 342 &new, &new_count);
343 if (error < 0)
326 goto fail; 344 goto fail;
327 345
328 spin_lock(&ls->ls_recover_lock); 346 spin_lock(&ls->ls_recover_lock);
@@ -337,14 +355,19 @@ int dlm_ls_start(struct dlm_ls *ls)
337 } 355 }
338 356
339 rv->nodeids = ids; 357 rv->nodeids = ids;
340 rv->node_count = count; 358 rv->node_count = ids_count;
359 rv->new = new;
360 rv->new_count = new_count;
341 rv->seq = ++ls->ls_recover_seq; 361 rv->seq = ++ls->ls_recover_seq;
342 rv_old = ls->ls_recover_args; 362 rv_old = ls->ls_recover_args;
343 ls->ls_recover_args = rv; 363 ls->ls_recover_args = rv;
344 spin_unlock(&ls->ls_recover_lock); 364 spin_unlock(&ls->ls_recover_lock);
345 365
346 if (rv_old) { 366 if (rv_old) {
367 log_error(ls, "unused recovery %llx %d",
368 (unsigned long long)rv_old->seq, rv_old->node_count);
347 kfree(rv_old->nodeids); 369 kfree(rv_old->nodeids);
370 kfree(rv_old->new);
348 kfree(rv_old); 371 kfree(rv_old);
349 } 372 }
350 373
@@ -354,6 +377,7 @@ int dlm_ls_start(struct dlm_ls *ls)
354 fail: 377 fail:
355 kfree(rv); 378 kfree(rv);
356 kfree(ids); 379 kfree(ids);
380 kfree(new);
357 return error; 381 return error;
358} 382}
359 383
diff --git a/fs/gfs2/locking/dlm/plock.c b/fs/dlm/plock.c
index 2ebd374b3143..d6d6e370f89c 100644
--- a/fs/gfs2/locking/dlm/plock.c
+++ b/fs/dlm/plock.c
@@ -1,17 +1,19 @@
1/* 1/*
2 * Copyright (C) 2005 Red Hat, Inc. All rights reserved. 2 * Copyright (C) 2005-2008 Red Hat, Inc. All rights reserved.
3 * 3 *
4 * This copyrighted material is made available to anyone wishing to use, 4 * This copyrighted material is made available to anyone wishing to use,
5 * modify, copy, or redistribute it subject to the terms and conditions 5 * modify, copy, or redistribute it subject to the terms and conditions
6 * of the GNU General Public License version 2. 6 * of the GNU General Public License version 2.
7 */ 7 */
8 8
9#include <linux/fs.h>
9#include <linux/miscdevice.h> 10#include <linux/miscdevice.h>
10#include <linux/lock_dlm_plock.h>
11#include <linux/poll.h> 11#include <linux/poll.h>
12#include <linux/dlm.h>
13#include <linux/dlm_plock.h>
12 14
13#include "lock_dlm.h" 15#include "dlm_internal.h"
14 16#include "lockspace.h"
15 17
16static spinlock_t ops_lock; 18static spinlock_t ops_lock;
17static struct list_head send_list; 19static struct list_head send_list;
@@ -22,7 +24,7 @@ static wait_queue_head_t recv_wq;
22struct plock_op { 24struct plock_op {
23 struct list_head list; 25 struct list_head list;
24 int done; 26 int done;
25 struct gdlm_plock_info info; 27 struct dlm_plock_info info;
26}; 28};
27 29
28struct plock_xop { 30struct plock_xop {
@@ -34,22 +36,22 @@ struct plock_xop {
34}; 36};
35 37
36 38
37static inline void set_version(struct gdlm_plock_info *info) 39static inline void set_version(struct dlm_plock_info *info)
38{ 40{
39 info->version[0] = GDLM_PLOCK_VERSION_MAJOR; 41 info->version[0] = DLM_PLOCK_VERSION_MAJOR;
40 info->version[1] = GDLM_PLOCK_VERSION_MINOR; 42 info->version[1] = DLM_PLOCK_VERSION_MINOR;
41 info->version[2] = GDLM_PLOCK_VERSION_PATCH; 43 info->version[2] = DLM_PLOCK_VERSION_PATCH;
42} 44}
43 45
44static int check_version(struct gdlm_plock_info *info) 46static int check_version(struct dlm_plock_info *info)
45{ 47{
46 if ((GDLM_PLOCK_VERSION_MAJOR != info->version[0]) || 48 if ((DLM_PLOCK_VERSION_MAJOR != info->version[0]) ||
47 (GDLM_PLOCK_VERSION_MINOR < info->version[1])) { 49 (DLM_PLOCK_VERSION_MINOR < info->version[1])) {
48 log_error("plock device version mismatch: " 50 log_print("plock device version mismatch: "
49 "kernel (%u.%u.%u), user (%u.%u.%u)", 51 "kernel (%u.%u.%u), user (%u.%u.%u)",
50 GDLM_PLOCK_VERSION_MAJOR, 52 DLM_PLOCK_VERSION_MAJOR,
51 GDLM_PLOCK_VERSION_MINOR, 53 DLM_PLOCK_VERSION_MINOR,
52 GDLM_PLOCK_VERSION_PATCH, 54 DLM_PLOCK_VERSION_PATCH,
53 info->version[0], 55 info->version[0],
54 info->version[1], 56 info->version[1],
55 info->version[2]); 57 info->version[2]);
@@ -68,25 +70,31 @@ static void send_op(struct plock_op *op)
68 wake_up(&send_wq); 70 wake_up(&send_wq);
69} 71}
70 72
71int gdlm_plock(void *lockspace, struct lm_lockname *name, 73int dlm_posix_lock(dlm_lockspace_t *lockspace, u64 number, struct file *file,
72 struct file *file, int cmd, struct file_lock *fl) 74 int cmd, struct file_lock *fl)
73{ 75{
74 struct gdlm_ls *ls = lockspace; 76 struct dlm_ls *ls;
75 struct plock_op *op; 77 struct plock_op *op;
76 struct plock_xop *xop; 78 struct plock_xop *xop;
77 int rv; 79 int rv;
78 80
81 ls = dlm_find_lockspace_local(lockspace);
82 if (!ls)
83 return -EINVAL;
84
79 xop = kzalloc(sizeof(*xop), GFP_KERNEL); 85 xop = kzalloc(sizeof(*xop), GFP_KERNEL);
80 if (!xop) 86 if (!xop) {
81 return -ENOMEM; 87 rv = -ENOMEM;
88 goto out;
89 }
82 90
83 op = &xop->xop; 91 op = &xop->xop;
84 op->info.optype = GDLM_PLOCK_OP_LOCK; 92 op->info.optype = DLM_PLOCK_OP_LOCK;
85 op->info.pid = fl->fl_pid; 93 op->info.pid = fl->fl_pid;
86 op->info.ex = (fl->fl_type == F_WRLCK); 94 op->info.ex = (fl->fl_type == F_WRLCK);
87 op->info.wait = IS_SETLKW(cmd); 95 op->info.wait = IS_SETLKW(cmd);
88 op->info.fsid = ls->id; 96 op->info.fsid = ls->ls_global_id;
89 op->info.number = name->ln_number; 97 op->info.number = number;
90 op->info.start = fl->fl_start; 98 op->info.start = fl->fl_start;
91 op->info.end = fl->fl_end; 99 op->info.end = fl->fl_end;
92 if (fl->fl_lmops && fl->fl_lmops->fl_grant) { 100 if (fl->fl_lmops && fl->fl_lmops->fl_grant) {
@@ -107,12 +115,15 @@ int gdlm_plock(void *lockspace, struct lm_lockname *name,
107 115
108 if (xop->callback == NULL) 116 if (xop->callback == NULL)
109 wait_event(recv_wq, (op->done != 0)); 117 wait_event(recv_wq, (op->done != 0));
110 else 118 else {
111 return -EINPROGRESS; 119 rv = -EINPROGRESS;
120 goto out;
121 }
112 122
113 spin_lock(&ops_lock); 123 spin_lock(&ops_lock);
114 if (!list_empty(&op->list)) { 124 if (!list_empty(&op->list)) {
115 printk(KERN_INFO "plock op on list\n"); 125 log_error(ls, "dlm_posix_lock: op on list %llx",
126 (unsigned long long)number);
116 list_del(&op->list); 127 list_del(&op->list);
117 } 128 }
118 spin_unlock(&ops_lock); 129 spin_unlock(&ops_lock);
@@ -121,17 +132,19 @@ int gdlm_plock(void *lockspace, struct lm_lockname *name,
121 132
122 if (!rv) { 133 if (!rv) {
123 if (posix_lock_file_wait(file, fl) < 0) 134 if (posix_lock_file_wait(file, fl) < 0)
124 log_error("gdlm_plock: vfs lock error %x,%llx", 135 log_error(ls, "dlm_posix_lock: vfs lock error %llx",
125 name->ln_type, 136 (unsigned long long)number);
126 (unsigned long long)name->ln_number);
127 } 137 }
128 138
129 kfree(xop); 139 kfree(xop);
140out:
141 dlm_put_lockspace(ls);
130 return rv; 142 return rv;
131} 143}
144EXPORT_SYMBOL_GPL(dlm_posix_lock);
132 145
133/* Returns failure iff a succesful lock operation should be canceled */ 146/* Returns failure iff a succesful lock operation should be canceled */
134static int gdlm_plock_callback(struct plock_op *op) 147static int dlm_plock_callback(struct plock_op *op)
135{ 148{
136 struct file *file; 149 struct file *file;
137 struct file_lock *fl; 150 struct file_lock *fl;
@@ -142,7 +155,8 @@ static int gdlm_plock_callback(struct plock_op *op)
142 155
143 spin_lock(&ops_lock); 156 spin_lock(&ops_lock);
144 if (!list_empty(&op->list)) { 157 if (!list_empty(&op->list)) {
145 printk(KERN_INFO "plock op on list\n"); 158 log_print("dlm_plock_callback: op on list %llx",
159 (unsigned long long)op->info.number);
146 list_del(&op->list); 160 list_del(&op->list);
147 } 161 }
148 spin_unlock(&ops_lock); 162 spin_unlock(&ops_lock);
@@ -165,19 +179,19 @@ static int gdlm_plock_callback(struct plock_op *op)
165 * This can only happen in the case of kmalloc() failure. 179 * This can only happen in the case of kmalloc() failure.
166 * The filesystem's own lock is the authoritative lock, 180 * The filesystem's own lock is the authoritative lock,
167 * so a failure to get the lock locally is not a disaster. 181 * so a failure to get the lock locally is not a disaster.
168 * As long as GFS cannot reliably cancel locks (especially 182 * As long as the fs cannot reliably cancel locks (especially
169 * in a low-memory situation), we're better off ignoring 183 * in a low-memory situation), we're better off ignoring
170 * this failure than trying to recover. 184 * this failure than trying to recover.
171 */ 185 */
172 log_error("gdlm_plock: vfs lock error file %p fl %p", 186 log_print("dlm_plock_callback: vfs lock error %llx file %p fl %p",
173 file, fl); 187 (unsigned long long)op->info.number, file, fl);
174 } 188 }
175 189
176 rv = notify(flc, NULL, 0); 190 rv = notify(flc, NULL, 0);
177 if (rv) { 191 if (rv) {
178 /* XXX: We need to cancel the fs lock here: */ 192 /* XXX: We need to cancel the fs lock here: */
179 printk("gfs2 lock granted after lock request failed;" 193 log_print("dlm_plock_callback: lock granted after lock request "
180 " dangling lock!\n"); 194 "failed; dangling lock!\n");
181 goto out; 195 goto out;
182 } 196 }
183 197
@@ -186,25 +200,31 @@ out:
186 return rv; 200 return rv;
187} 201}
188 202
189int gdlm_punlock(void *lockspace, struct lm_lockname *name, 203int dlm_posix_unlock(dlm_lockspace_t *lockspace, u64 number, struct file *file,
190 struct file *file, struct file_lock *fl) 204 struct file_lock *fl)
191{ 205{
192 struct gdlm_ls *ls = lockspace; 206 struct dlm_ls *ls;
193 struct plock_op *op; 207 struct plock_op *op;
194 int rv; 208 int rv;
195 209
210 ls = dlm_find_lockspace_local(lockspace);
211 if (!ls)
212 return -EINVAL;
213
196 op = kzalloc(sizeof(*op), GFP_KERNEL); 214 op = kzalloc(sizeof(*op), GFP_KERNEL);
197 if (!op) 215 if (!op) {
198 return -ENOMEM; 216 rv = -ENOMEM;
217 goto out;
218 }
199 219
200 if (posix_lock_file_wait(file, fl) < 0) 220 if (posix_lock_file_wait(file, fl) < 0)
201 log_error("gdlm_punlock: vfs unlock error %x,%llx", 221 log_error(ls, "dlm_posix_unlock: vfs unlock error %llx",
202 name->ln_type, (unsigned long long)name->ln_number); 222 (unsigned long long)number);
203 223
204 op->info.optype = GDLM_PLOCK_OP_UNLOCK; 224 op->info.optype = DLM_PLOCK_OP_UNLOCK;
205 op->info.pid = fl->fl_pid; 225 op->info.pid = fl->fl_pid;
206 op->info.fsid = ls->id; 226 op->info.fsid = ls->ls_global_id;
207 op->info.number = name->ln_number; 227 op->info.number = number;
208 op->info.start = fl->fl_start; 228 op->info.start = fl->fl_start;
209 op->info.end = fl->fl_end; 229 op->info.end = fl->fl_end;
210 if (fl->fl_lmops && fl->fl_lmops->fl_grant) 230 if (fl->fl_lmops && fl->fl_lmops->fl_grant)
@@ -217,7 +237,8 @@ int gdlm_punlock(void *lockspace, struct lm_lockname *name,
217 237
218 spin_lock(&ops_lock); 238 spin_lock(&ops_lock);
219 if (!list_empty(&op->list)) { 239 if (!list_empty(&op->list)) {
220 printk(KERN_INFO "punlock op on list\n"); 240 log_error(ls, "dlm_posix_unlock: op on list %llx",
241 (unsigned long long)number);
221 list_del(&op->list); 242 list_del(&op->list);
222 } 243 }
223 spin_unlock(&ops_lock); 244 spin_unlock(&ops_lock);
@@ -228,25 +249,34 @@ int gdlm_punlock(void *lockspace, struct lm_lockname *name,
228 rv = 0; 249 rv = 0;
229 250
230 kfree(op); 251 kfree(op);
252out:
253 dlm_put_lockspace(ls);
231 return rv; 254 return rv;
232} 255}
256EXPORT_SYMBOL_GPL(dlm_posix_unlock);
233 257
234int gdlm_plock_get(void *lockspace, struct lm_lockname *name, 258int dlm_posix_get(dlm_lockspace_t *lockspace, u64 number, struct file *file,
235 struct file *file, struct file_lock *fl) 259 struct file_lock *fl)
236{ 260{
237 struct gdlm_ls *ls = lockspace; 261 struct dlm_ls *ls;
238 struct plock_op *op; 262 struct plock_op *op;
239 int rv; 263 int rv;
240 264
265 ls = dlm_find_lockspace_local(lockspace);
266 if (!ls)
267 return -EINVAL;
268
241 op = kzalloc(sizeof(*op), GFP_KERNEL); 269 op = kzalloc(sizeof(*op), GFP_KERNEL);
242 if (!op) 270 if (!op) {
243 return -ENOMEM; 271 rv = -ENOMEM;
272 goto out;
273 }
244 274
245 op->info.optype = GDLM_PLOCK_OP_GET; 275 op->info.optype = DLM_PLOCK_OP_GET;
246 op->info.pid = fl->fl_pid; 276 op->info.pid = fl->fl_pid;
247 op->info.ex = (fl->fl_type == F_WRLCK); 277 op->info.ex = (fl->fl_type == F_WRLCK);
248 op->info.fsid = ls->id; 278 op->info.fsid = ls->ls_global_id;
249 op->info.number = name->ln_number; 279 op->info.number = number;
250 op->info.start = fl->fl_start; 280 op->info.start = fl->fl_start;
251 op->info.end = fl->fl_end; 281 op->info.end = fl->fl_end;
252 if (fl->fl_lmops && fl->fl_lmops->fl_grant) 282 if (fl->fl_lmops && fl->fl_lmops->fl_grant)
@@ -259,7 +289,8 @@ int gdlm_plock_get(void *lockspace, struct lm_lockname *name,
259 289
260 spin_lock(&ops_lock); 290 spin_lock(&ops_lock);
261 if (!list_empty(&op->list)) { 291 if (!list_empty(&op->list)) {
262 printk(KERN_INFO "plock_get op on list\n"); 292 log_error(ls, "dlm_posix_get: op on list %llx",
293 (unsigned long long)number);
263 list_del(&op->list); 294 list_del(&op->list);
264 } 295 }
265 spin_unlock(&ops_lock); 296 spin_unlock(&ops_lock);
@@ -281,14 +312,17 @@ int gdlm_plock_get(void *lockspace, struct lm_lockname *name,
281 } 312 }
282 313
283 kfree(op); 314 kfree(op);
315out:
316 dlm_put_lockspace(ls);
284 return rv; 317 return rv;
285} 318}
319EXPORT_SYMBOL_GPL(dlm_posix_get);
286 320
287/* a read copies out one plock request from the send list */ 321/* a read copies out one plock request from the send list */
288static ssize_t dev_read(struct file *file, char __user *u, size_t count, 322static ssize_t dev_read(struct file *file, char __user *u, size_t count,
289 loff_t *ppos) 323 loff_t *ppos)
290{ 324{
291 struct gdlm_plock_info info; 325 struct dlm_plock_info info;
292 struct plock_op *op = NULL; 326 struct plock_op *op = NULL;
293 327
294 if (count < sizeof(info)) 328 if (count < sizeof(info))
@@ -315,7 +349,7 @@ static ssize_t dev_read(struct file *file, char __user *u, size_t count,
315static ssize_t dev_write(struct file *file, const char __user *u, size_t count, 349static ssize_t dev_write(struct file *file, const char __user *u, size_t count,
316 loff_t *ppos) 350 loff_t *ppos)
317{ 351{
318 struct gdlm_plock_info info; 352 struct dlm_plock_info info;
319 struct plock_op *op; 353 struct plock_op *op;
320 int found = 0; 354 int found = 0;
321 355
@@ -345,12 +379,12 @@ static ssize_t dev_write(struct file *file, const char __user *u, size_t count,
345 struct plock_xop *xop; 379 struct plock_xop *xop;
346 xop = (struct plock_xop *)op; 380 xop = (struct plock_xop *)op;
347 if (xop->callback) 381 if (xop->callback)
348 count = gdlm_plock_callback(op); 382 count = dlm_plock_callback(op);
349 else 383 else
350 wake_up(&recv_wq); 384 wake_up(&recv_wq);
351 } else 385 } else
352 printk(KERN_INFO "gdlm dev_write no op %x %llx\n", info.fsid, 386 log_print("dev_write no op %x %llx", info.fsid,
353 (unsigned long long)info.number); 387 (unsigned long long)info.number);
354 return count; 388 return count;
355} 389}
356 390
@@ -377,11 +411,11 @@ static const struct file_operations dev_fops = {
377 411
378static struct miscdevice plock_dev_misc = { 412static struct miscdevice plock_dev_misc = {
379 .minor = MISC_DYNAMIC_MINOR, 413 .minor = MISC_DYNAMIC_MINOR,
380 .name = GDLM_PLOCK_MISC_NAME, 414 .name = DLM_PLOCK_MISC_NAME,
381 .fops = &dev_fops 415 .fops = &dev_fops
382}; 416};
383 417
384int gdlm_plock_init(void) 418int dlm_plock_init(void)
385{ 419{
386 int rv; 420 int rv;
387 421
@@ -393,14 +427,13 @@ int gdlm_plock_init(void)
393 427
394 rv = misc_register(&plock_dev_misc); 428 rv = misc_register(&plock_dev_misc);
395 if (rv) 429 if (rv)
396 printk(KERN_INFO "gdlm_plock_init: misc_register failed %d", 430 log_print("dlm_plock_init: misc_register failed %d", rv);
397 rv);
398 return rv; 431 return rv;
399} 432}
400 433
401void gdlm_plock_exit(void) 434void dlm_plock_exit(void)
402{ 435{
403 if (misc_deregister(&plock_dev_misc) < 0) 436 if (misc_deregister(&plock_dev_misc) < 0)
404 printk(KERN_INFO "gdlm_plock_exit: misc_deregister failed"); 437 log_print("dlm_plock_exit: misc_deregister failed");
405} 438}
406 439
diff --git a/fs/dlm/recoverd.c b/fs/dlm/recoverd.c
index 997f9531d594..fd677c8c3d3b 100644
--- a/fs/dlm/recoverd.c
+++ b/fs/dlm/recoverd.c
@@ -257,6 +257,7 @@ static void do_ls_recovery(struct dlm_ls *ls)
257 if (rv) { 257 if (rv) {
258 ls_recover(ls, rv); 258 ls_recover(ls, rv);
259 kfree(rv->nodeids); 259 kfree(rv->nodeids);
260 kfree(rv->new);
260 kfree(rv); 261 kfree(rv);
261 } 262 }
262} 263}
diff --git a/fs/gfs2/locking/dlm/Makefile b/fs/gfs2/locking/dlm/Makefile
index 89b93b6b45cf..2609bb6cd013 100644
--- a/fs/gfs2/locking/dlm/Makefile
+++ b/fs/gfs2/locking/dlm/Makefile
@@ -1,3 +1,3 @@
1obj-$(CONFIG_GFS2_FS_LOCKING_DLM) += lock_dlm.o 1obj-$(CONFIG_GFS2_FS_LOCKING_DLM) += lock_dlm.o
2lock_dlm-y := lock.o main.o mount.o sysfs.o thread.o plock.o 2lock_dlm-y := lock.o main.o mount.o sysfs.o thread.o
3 3
diff --git a/fs/gfs2/locking/dlm/lock_dlm.h b/fs/gfs2/locking/dlm/lock_dlm.h
index 58fcf8c5bf39..a243cf69c54e 100644
--- a/fs/gfs2/locking/dlm/lock_dlm.h
+++ b/fs/gfs2/locking/dlm/lock_dlm.h
@@ -25,6 +25,7 @@
25#include <net/sock.h> 25#include <net/sock.h>
26 26
27#include <linux/dlm.h> 27#include <linux/dlm.h>
28#include <linux/dlm_plock.h>
28#include <linux/lm_interface.h> 29#include <linux/lm_interface.h>
29 30
30/* 31/*
@@ -173,17 +174,6 @@ void gdlm_cancel(void *);
173int gdlm_hold_lvb(void *, char **); 174int gdlm_hold_lvb(void *, char **);
174void gdlm_unhold_lvb(void *, char *); 175void gdlm_unhold_lvb(void *, char *);
175 176
176/* plock.c */
177
178int gdlm_plock_init(void);
179void gdlm_plock_exit(void);
180int gdlm_plock(void *, struct lm_lockname *, struct file *, int,
181 struct file_lock *);
182int gdlm_plock_get(void *, struct lm_lockname *, struct file *,
183 struct file_lock *);
184int gdlm_punlock(void *, struct lm_lockname *, struct file *,
185 struct file_lock *);
186
187/* mount.c */ 177/* mount.c */
188 178
189extern const struct lm_lockops gdlm_ops; 179extern const struct lm_lockops gdlm_ops;
diff --git a/fs/gfs2/locking/dlm/main.c b/fs/gfs2/locking/dlm/main.c
index 36a225850bd8..b9a03a7ff801 100644
--- a/fs/gfs2/locking/dlm/main.c
+++ b/fs/gfs2/locking/dlm/main.c
@@ -28,13 +28,6 @@ static int __init init_lock_dlm(void)
28 return error; 28 return error;
29 } 29 }
30 30
31 error = gdlm_plock_init();
32 if (error) {
33 gdlm_sysfs_exit();
34 gfs2_unregister_lockproto(&gdlm_ops);
35 return error;
36 }
37
38 printk(KERN_INFO 31 printk(KERN_INFO
39 "Lock_DLM (built %s %s) installed\n", __DATE__, __TIME__); 32 "Lock_DLM (built %s %s) installed\n", __DATE__, __TIME__);
40 return 0; 33 return 0;
@@ -42,7 +35,6 @@ static int __init init_lock_dlm(void)
42 35
43static void __exit exit_lock_dlm(void) 36static void __exit exit_lock_dlm(void)
44{ 37{
45 gdlm_plock_exit();
46 gdlm_sysfs_exit(); 38 gdlm_sysfs_exit();
47 gfs2_unregister_lockproto(&gdlm_ops); 39 gfs2_unregister_lockproto(&gdlm_ops);
48} 40}
diff --git a/fs/gfs2/locking/dlm/mount.c b/fs/gfs2/locking/dlm/mount.c
index f2efff424224..470bdf650b50 100644
--- a/fs/gfs2/locking/dlm/mount.c
+++ b/fs/gfs2/locking/dlm/mount.c
@@ -236,6 +236,27 @@ static void gdlm_withdraw(void *lockspace)
236 gdlm_kobject_release(ls); 236 gdlm_kobject_release(ls);
237} 237}
238 238
239static int gdlm_plock(void *lockspace, struct lm_lockname *name,
240 struct file *file, int cmd, struct file_lock *fl)
241{
242 struct gdlm_ls *ls = lockspace;
243 return dlm_posix_lock(ls->dlm_lockspace, name->ln_number, file, cmd, fl);
244}
245
246static int gdlm_punlock(void *lockspace, struct lm_lockname *name,
247 struct file *file, struct file_lock *fl)
248{
249 struct gdlm_ls *ls = lockspace;
250 return dlm_posix_unlock(ls->dlm_lockspace, name->ln_number, file, fl);
251}
252
253static int gdlm_plock_get(void *lockspace, struct lm_lockname *name,
254 struct file *file, struct file_lock *fl)
255{
256 struct gdlm_ls *ls = lockspace;
257 return dlm_posix_get(ls->dlm_lockspace, name->ln_number, file, fl);
258}
259
239const struct lm_lockops gdlm_ops = { 260const struct lm_lockops gdlm_ops = {
240 .lm_proto_name = "lock_dlm", 261 .lm_proto_name = "lock_dlm",
241 .lm_mount = gdlm_mount, 262 .lm_mount = gdlm_mount,
diff --git a/fs/udf/Makefile b/fs/udf/Makefile
index be845e7540ef..0d4503f7446d 100644
--- a/fs/udf/Makefile
+++ b/fs/udf/Makefile
@@ -6,4 +6,4 @@ obj-$(CONFIG_UDF_FS) += udf.o
6 6
7udf-objs := balloc.o dir.o file.o ialloc.o inode.o lowlevel.o namei.o \ 7udf-objs := balloc.o dir.o file.o ialloc.o inode.o lowlevel.o namei.o \
8 partition.o super.o truncate.o symlink.o fsync.o \ 8 partition.o super.o truncate.o symlink.o fsync.o \
9 crc.o directory.o misc.o udftime.o unicode.o 9 directory.o misc.o udftime.o unicode.o
diff --git a/fs/udf/balloc.c b/fs/udf/balloc.c
index f855dcbbdfb8..1b809bd494bd 100644
--- a/fs/udf/balloc.c
+++ b/fs/udf/balloc.c
@@ -149,8 +149,7 @@ static bool udf_add_free_space(struct udf_sb_info *sbi,
149 return false; 149 return false;
150 150
151 lvid = (struct logicalVolIntegrityDesc *)sbi->s_lvid_bh->b_data; 151 lvid = (struct logicalVolIntegrityDesc *)sbi->s_lvid_bh->b_data;
152 lvid->freeSpaceTable[partition] = cpu_to_le32(le32_to_cpu( 152 le32_add_cpu(&lvid->freeSpaceTable[partition], cnt);
153 lvid->freeSpaceTable[partition]) + cnt);
154 return true; 153 return true;
155} 154}
156 155
@@ -589,10 +588,8 @@ static void udf_table_free_blocks(struct super_block *sb,
589 sptr = oepos.bh->b_data + epos.offset; 588 sptr = oepos.bh->b_data + epos.offset;
590 aed = (struct allocExtDesc *) 589 aed = (struct allocExtDesc *)
591 oepos.bh->b_data; 590 oepos.bh->b_data;
592 aed->lengthAllocDescs = 591 le32_add_cpu(&aed->lengthAllocDescs,
593 cpu_to_le32(le32_to_cpu( 592 adsize);
594 aed->lengthAllocDescs) +
595 adsize);
596 } else { 593 } else {
597 sptr = iinfo->i_ext.i_data + 594 sptr = iinfo->i_ext.i_data +
598 epos.offset; 595 epos.offset;
@@ -645,9 +642,7 @@ static void udf_table_free_blocks(struct super_block *sb,
645 mark_inode_dirty(table); 642 mark_inode_dirty(table);
646 } else { 643 } else {
647 aed = (struct allocExtDesc *)epos.bh->b_data; 644 aed = (struct allocExtDesc *)epos.bh->b_data;
648 aed->lengthAllocDescs = 645 le32_add_cpu(&aed->lengthAllocDescs, adsize);
649 cpu_to_le32(le32_to_cpu(
650 aed->lengthAllocDescs) + adsize);
651 udf_update_tag(epos.bh->b_data, epos.offset); 646 udf_update_tag(epos.bh->b_data, epos.offset);
652 mark_buffer_dirty(epos.bh); 647 mark_buffer_dirty(epos.bh);
653 } 648 }
diff --git a/fs/udf/crc.c b/fs/udf/crc.c
deleted file mode 100644
index b1661296e786..000000000000
--- a/fs/udf/crc.c
+++ /dev/null
@@ -1,172 +0,0 @@
1/*
2 * crc.c
3 *
4 * PURPOSE
5 * Routines to generate, calculate, and test a 16-bit CRC.
6 *
7 * DESCRIPTION
8 * The CRC code was devised by Don P. Mitchell of AT&T Bell Laboratories
9 * and Ned W. Rhodes of Software Systems Group. It has been published in
10 * "Design and Validation of Computer Protocols", Prentice Hall,
11 * Englewood Cliffs, NJ, 1991, Chapter 3, ISBN 0-13-539925-4.
12 *
13 * Copyright is held by AT&T.
14 *
15 * AT&T gives permission for the free use of the CRC source code.
16 *
17 * COPYRIGHT
18 * This file is distributed under the terms of the GNU General Public
19 * License (GPL). Copies of the GPL can be obtained from:
20 * ftp://prep.ai.mit.edu/pub/gnu/GPL
21 * Each contributing author retains all rights to their own work.
22 */
23
24#include "udfdecl.h"
25
26static uint16_t crc_table[256] = {
27 0x0000U, 0x1021U, 0x2042U, 0x3063U, 0x4084U, 0x50a5U, 0x60c6U, 0x70e7U,
28 0x8108U, 0x9129U, 0xa14aU, 0xb16bU, 0xc18cU, 0xd1adU, 0xe1ceU, 0xf1efU,
29 0x1231U, 0x0210U, 0x3273U, 0x2252U, 0x52b5U, 0x4294U, 0x72f7U, 0x62d6U,
30 0x9339U, 0x8318U, 0xb37bU, 0xa35aU, 0xd3bdU, 0xc39cU, 0xf3ffU, 0xe3deU,
31 0x2462U, 0x3443U, 0x0420U, 0x1401U, 0x64e6U, 0x74c7U, 0x44a4U, 0x5485U,
32 0xa56aU, 0xb54bU, 0x8528U, 0x9509U, 0xe5eeU, 0xf5cfU, 0xc5acU, 0xd58dU,
33 0x3653U, 0x2672U, 0x1611U, 0x0630U, 0x76d7U, 0x66f6U, 0x5695U, 0x46b4U,
34 0xb75bU, 0xa77aU, 0x9719U, 0x8738U, 0xf7dfU, 0xe7feU, 0xd79dU, 0xc7bcU,
35 0x48c4U, 0x58e5U, 0x6886U, 0x78a7U, 0x0840U, 0x1861U, 0x2802U, 0x3823U,
36 0xc9ccU, 0xd9edU, 0xe98eU, 0xf9afU, 0x8948U, 0x9969U, 0xa90aU, 0xb92bU,
37 0x5af5U, 0x4ad4U, 0x7ab7U, 0x6a96U, 0x1a71U, 0x0a50U, 0x3a33U, 0x2a12U,
38 0xdbfdU, 0xcbdcU, 0xfbbfU, 0xeb9eU, 0x9b79U, 0x8b58U, 0xbb3bU, 0xab1aU,
39 0x6ca6U, 0x7c87U, 0x4ce4U, 0x5cc5U, 0x2c22U, 0x3c03U, 0x0c60U, 0x1c41U,
40 0xedaeU, 0xfd8fU, 0xcdecU, 0xddcdU, 0xad2aU, 0xbd0bU, 0x8d68U, 0x9d49U,
41 0x7e97U, 0x6eb6U, 0x5ed5U, 0x4ef4U, 0x3e13U, 0x2e32U, 0x1e51U, 0x0e70U,
42 0xff9fU, 0xefbeU, 0xdfddU, 0xcffcU, 0xbf1bU, 0xaf3aU, 0x9f59U, 0x8f78U,
43 0x9188U, 0x81a9U, 0xb1caU, 0xa1ebU, 0xd10cU, 0xc12dU, 0xf14eU, 0xe16fU,
44 0x1080U, 0x00a1U, 0x30c2U, 0x20e3U, 0x5004U, 0x4025U, 0x7046U, 0x6067U,
45 0x83b9U, 0x9398U, 0xa3fbU, 0xb3daU, 0xc33dU, 0xd31cU, 0xe37fU, 0xf35eU,
46 0x02b1U, 0x1290U, 0x22f3U, 0x32d2U, 0x4235U, 0x5214U, 0x6277U, 0x7256U,
47 0xb5eaU, 0xa5cbU, 0x95a8U, 0x8589U, 0xf56eU, 0xe54fU, 0xd52cU, 0xc50dU,
48 0x34e2U, 0x24c3U, 0x14a0U, 0x0481U, 0x7466U, 0x6447U, 0x5424U, 0x4405U,
49 0xa7dbU, 0xb7faU, 0x8799U, 0x97b8U, 0xe75fU, 0xf77eU, 0xc71dU, 0xd73cU,
50 0x26d3U, 0x36f2U, 0x0691U, 0x16b0U, 0x6657U, 0x7676U, 0x4615U, 0x5634U,
51 0xd94cU, 0xc96dU, 0xf90eU, 0xe92fU, 0x99c8U, 0x89e9U, 0xb98aU, 0xa9abU,
52 0x5844U, 0x4865U, 0x7806U, 0x6827U, 0x18c0U, 0x08e1U, 0x3882U, 0x28a3U,
53 0xcb7dU, 0xdb5cU, 0xeb3fU, 0xfb1eU, 0x8bf9U, 0x9bd8U, 0xabbbU, 0xbb9aU,
54 0x4a75U, 0x5a54U, 0x6a37U, 0x7a16U, 0x0af1U, 0x1ad0U, 0x2ab3U, 0x3a92U,
55 0xfd2eU, 0xed0fU, 0xdd6cU, 0xcd4dU, 0xbdaaU, 0xad8bU, 0x9de8U, 0x8dc9U,
56 0x7c26U, 0x6c07U, 0x5c64U, 0x4c45U, 0x3ca2U, 0x2c83U, 0x1ce0U, 0x0cc1U,
57 0xef1fU, 0xff3eU, 0xcf5dU, 0xdf7cU, 0xaf9bU, 0xbfbaU, 0x8fd9U, 0x9ff8U,
58 0x6e17U, 0x7e36U, 0x4e55U, 0x5e74U, 0x2e93U, 0x3eb2U, 0x0ed1U, 0x1ef0U
59};
60
61/*
62 * udf_crc
63 *
64 * PURPOSE
65 * Calculate a 16-bit CRC checksum using ITU-T V.41 polynomial.
66 *
67 * DESCRIPTION
68 * The OSTA-UDF(tm) 1.50 standard states that using CRCs is mandatory.
69 * The polynomial used is: x^16 + x^12 + x^15 + 1
70 *
71 * PRE-CONDITIONS
72 * data Pointer to the data block.
73 * size Size of the data block.
74 *
75 * POST-CONDITIONS
76 * <return> CRC of the data block.
77 *
78 * HISTORY
79 * July 21, 1997 - Andrew E. Mileski
80 * Adapted from OSTA-UDF(tm) 1.50 standard.
81 */
82uint16_t udf_crc(uint8_t *data, uint32_t size, uint16_t crc)
83{
84 while (size--)
85 crc = crc_table[(crc >> 8 ^ *(data++)) & 0xffU] ^ (crc << 8);
86
87 return crc;
88}
89
90/****************************************************************************/
91#if defined(TEST)
92
93/*
94 * PURPOSE
95 * Test udf_crc()
96 *
97 * HISTORY
98 * July 21, 1997 - Andrew E. Mileski
99 * Adapted from OSTA-UDF(tm) 1.50 standard.
100 */
101
102unsigned char bytes[] = { 0x70U, 0x6AU, 0x77U };
103
104int main(void)
105{
106 unsigned short x;
107
108 x = udf_crc(bytes, sizeof bytes);
109 printf("udf_crc: calculated = %4.4x, correct = %4.4x\n", x, 0x3299U);
110
111 return 0;
112}
113
114#endif /* defined(TEST) */
115
116/****************************************************************************/
117#if defined(GENERATE)
118
119/*
120 * PURPOSE
121 * Generate a table for fast 16-bit CRC calculations (any polynomial).
122 *
123 * DESCRIPTION
124 * The ITU-T V.41 polynomial is 010041.
125 *
126 * HISTORY
127 * July 21, 1997 - Andrew E. Mileski
128 * Adapted from OSTA-UDF(tm) 1.50 standard.
129 */
130
131#include <stdio.h>
132
133int main(int argc, char **argv)
134{
135 unsigned long crc, poly;
136 int n, i;
137
138 /* Get the polynomial */
139 sscanf(argv[1], "%lo", &poly);
140 if (poly & 0xffff0000U) {
141 fprintf(stderr, "polynomial is too large\en");
142 exit(1);
143 }
144
145 printf("/* CRC 0%o */\n", poly);
146
147 /* Create a table */
148 printf("static unsigned short crc_table[256] = {\n");
149 for (n = 0; n < 256; n++) {
150 if (n % 8 == 0)
151 printf("\t");
152 crc = n << 8;
153 for (i = 0; i < 8; i++) {
154 if (crc & 0x8000U)
155 crc = (crc << 1) ^ poly;
156 else
157 crc <<= 1;
158 crc &= 0xFFFFU;
159 }
160 if (n == 255)
161 printf("0x%04xU ", crc);
162 else
163 printf("0x%04xU, ", crc);
164 if (n % 8 == 7)
165 printf("\n");
166 }
167 printf("};\n");
168
169 return 0;
170}
171
172#endif /* defined(GENERATE) */
diff --git a/fs/udf/dir.c b/fs/udf/dir.c
index 8d8643ada199..62dc270c69d1 100644
--- a/fs/udf/dir.c
+++ b/fs/udf/dir.c
@@ -39,13 +39,13 @@
39static int do_udf_readdir(struct inode *dir, struct file *filp, 39static int do_udf_readdir(struct inode *dir, struct file *filp,
40 filldir_t filldir, void *dirent) 40 filldir_t filldir, void *dirent)
41{ 41{
42 struct udf_fileident_bh fibh; 42 struct udf_fileident_bh fibh = { .sbh = NULL, .ebh = NULL};
43 struct fileIdentDesc *fi = NULL; 43 struct fileIdentDesc *fi = NULL;
44 struct fileIdentDesc cfi; 44 struct fileIdentDesc cfi;
45 int block, iblock; 45 int block, iblock;
46 loff_t nf_pos = (filp->f_pos - 1) << 2; 46 loff_t nf_pos = (filp->f_pos - 1) << 2;
47 int flen; 47 int flen;
48 char fname[UDF_NAME_LEN]; 48 char *fname = NULL;
49 char *nameptr; 49 char *nameptr;
50 uint16_t liu; 50 uint16_t liu;
51 uint8_t lfi; 51 uint8_t lfi;
@@ -54,23 +54,32 @@ static int do_udf_readdir(struct inode *dir, struct file *filp,
54 kernel_lb_addr eloc; 54 kernel_lb_addr eloc;
55 uint32_t elen; 55 uint32_t elen;
56 sector_t offset; 56 sector_t offset;
57 int i, num; 57 int i, num, ret = 0;
58 unsigned int dt_type; 58 unsigned int dt_type;
59 struct extent_position epos = { NULL, 0, {0, 0} }; 59 struct extent_position epos = { NULL, 0, {0, 0} };
60 struct udf_inode_info *iinfo; 60 struct udf_inode_info *iinfo;
61 61
62 if (nf_pos >= size) 62 if (nf_pos >= size)
63 return 0; 63 goto out;
64
65 fname = kmalloc(UDF_NAME_LEN, GFP_NOFS);
66 if (!fname) {
67 ret = -ENOMEM;
68 goto out;
69 }
64 70
65 if (nf_pos == 0) 71 if (nf_pos == 0)
66 nf_pos = udf_ext0_offset(dir); 72 nf_pos = udf_ext0_offset(dir);
67 73
68 fibh.soffset = fibh.eoffset = nf_pos & (dir->i_sb->s_blocksize - 1); 74 fibh.soffset = fibh.eoffset = nf_pos & (dir->i_sb->s_blocksize - 1);
69 iinfo = UDF_I(dir); 75 iinfo = UDF_I(dir);
70 if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) { 76 if (iinfo->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB) {
71 fibh.sbh = fibh.ebh = NULL; 77 if (inode_bmap(dir, nf_pos >> dir->i_sb->s_blocksize_bits,
72 } else if (inode_bmap(dir, nf_pos >> dir->i_sb->s_blocksize_bits, 78 &epos, &eloc, &elen, &offset)
73 &epos, &eloc, &elen, &offset) == (EXT_RECORDED_ALLOCATED >> 30)) { 79 != (EXT_RECORDED_ALLOCATED >> 30)) {
80 ret = -ENOENT;
81 goto out;
82 }
74 block = udf_get_lb_pblock(dir->i_sb, eloc, offset); 83 block = udf_get_lb_pblock(dir->i_sb, eloc, offset);
75 if ((++offset << dir->i_sb->s_blocksize_bits) < elen) { 84 if ((++offset << dir->i_sb->s_blocksize_bits) < elen) {
76 if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT) 85 if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT)
@@ -83,8 +92,8 @@ static int do_udf_readdir(struct inode *dir, struct file *filp,
83 } 92 }
84 93
85 if (!(fibh.sbh = fibh.ebh = udf_tread(dir->i_sb, block))) { 94 if (!(fibh.sbh = fibh.ebh = udf_tread(dir->i_sb, block))) {
86 brelse(epos.bh); 95 ret = -EIO;
87 return -EIO; 96 goto out;
88 } 97 }
89 98
90 if (!(offset & ((16 >> (dir->i_sb->s_blocksize_bits - 9)) - 1))) { 99 if (!(offset & ((16 >> (dir->i_sb->s_blocksize_bits - 9)) - 1))) {
@@ -105,9 +114,6 @@ static int do_udf_readdir(struct inode *dir, struct file *filp,
105 brelse(bha[i]); 114 brelse(bha[i]);
106 } 115 }
107 } 116 }
108 } else {
109 brelse(epos.bh);
110 return -ENOENT;
111 } 117 }
112 118
113 while (nf_pos < size) { 119 while (nf_pos < size) {
@@ -115,13 +121,8 @@ static int do_udf_readdir(struct inode *dir, struct file *filp,
115 121
116 fi = udf_fileident_read(dir, &nf_pos, &fibh, &cfi, &epos, &eloc, 122 fi = udf_fileident_read(dir, &nf_pos, &fibh, &cfi, &epos, &eloc,
117 &elen, &offset); 123 &elen, &offset);
118 if (!fi) { 124 if (!fi)
119 if (fibh.sbh != fibh.ebh) 125 goto out;
120 brelse(fibh.ebh);
121 brelse(fibh.sbh);
122 brelse(epos.bh);
123 return 0;
124 }
125 126
126 liu = le16_to_cpu(cfi.lengthOfImpUse); 127 liu = le16_to_cpu(cfi.lengthOfImpUse);
127 lfi = cfi.lengthFileIdent; 128 lfi = cfi.lengthFileIdent;
@@ -167,53 +168,23 @@ static int do_udf_readdir(struct inode *dir, struct file *filp,
167 dt_type = DT_UNKNOWN; 168 dt_type = DT_UNKNOWN;
168 } 169 }
169 170
170 if (flen) { 171 if (flen && filldir(dirent, fname, flen, filp->f_pos,
171 if (filldir(dirent, fname, flen, filp->f_pos, iblock, dt_type) < 0) { 172 iblock, dt_type) < 0)
172 if (fibh.sbh != fibh.ebh) 173 goto out;
173 brelse(fibh.ebh);
174 brelse(fibh.sbh);
175 brelse(epos.bh);
176 return 0;
177 }
178 }
179 } /* end while */ 174 } /* end while */
180 175
181 filp->f_pos = (nf_pos >> 2) + 1; 176 filp->f_pos = (nf_pos >> 2) + 1;
182 177
178out:
183 if (fibh.sbh != fibh.ebh) 179 if (fibh.sbh != fibh.ebh)
184 brelse(fibh.ebh); 180 brelse(fibh.ebh);
185 brelse(fibh.sbh); 181 brelse(fibh.sbh);
186 brelse(epos.bh); 182 brelse(epos.bh);
183 kfree(fname);
187 184
188 return 0; 185 return ret;
189} 186}
190 187
191/*
192 * udf_readdir
193 *
194 * PURPOSE
195 * Read a directory entry.
196 *
197 * DESCRIPTION
198 * Optional - sys_getdents() will return -ENOTDIR if this routine is not
199 * available.
200 *
201 * Refer to sys_getdents() in fs/readdir.c
202 * sys_getdents() -> .
203 *
204 * PRE-CONDITIONS
205 * filp Pointer to directory file.
206 * buf Pointer to directory entry buffer.
207 * filldir Pointer to filldir function.
208 *
209 * POST-CONDITIONS
210 * <return> >=0 on success.
211 *
212 * HISTORY
213 * July 1, 1997 - Andrew E. Mileski
214 * Written, tested, and released.
215 */
216
217static int udf_readdir(struct file *filp, void *dirent, filldir_t filldir) 188static int udf_readdir(struct file *filp, void *dirent, filldir_t filldir)
218{ 189{
219 struct inode *dir = filp->f_path.dentry->d_inode; 190 struct inode *dir = filp->f_path.dentry->d_inode;
diff --git a/fs/udf/ecma_167.h b/fs/udf/ecma_167.h
index 56387711589b..a0974df82b31 100644
--- a/fs/udf/ecma_167.h
+++ b/fs/udf/ecma_167.h
@@ -70,19 +70,6 @@ typedef struct {
70 uint8_t microseconds; 70 uint8_t microseconds;
71} __attribute__ ((packed)) timestamp; 71} __attribute__ ((packed)) timestamp;
72 72
73typedef struct {
74 uint16_t typeAndTimezone;
75 int16_t year;
76 uint8_t month;
77 uint8_t day;
78 uint8_t hour;
79 uint8_t minute;
80 uint8_t second;
81 uint8_t centiseconds;
82 uint8_t hundredsOfMicroseconds;
83 uint8_t microseconds;
84} __attribute__ ((packed)) kernel_timestamp;
85
86/* Type and Time Zone (ECMA 167r3 1/7.3.1) */ 73/* Type and Time Zone (ECMA 167r3 1/7.3.1) */
87#define TIMESTAMP_TYPE_MASK 0xF000 74#define TIMESTAMP_TYPE_MASK 0xF000
88#define TIMESTAMP_TYPE_CUT 0x0000 75#define TIMESTAMP_TYPE_CUT 0x0000
diff --git a/fs/udf/file.c b/fs/udf/file.c
index 97c71ae7c689..0ed6e146a0d9 100644
--- a/fs/udf/file.c
+++ b/fs/udf/file.c
@@ -27,7 +27,6 @@
27 27
28#include "udfdecl.h" 28#include "udfdecl.h"
29#include <linux/fs.h> 29#include <linux/fs.h>
30#include <linux/udf_fs.h>
31#include <asm/uaccess.h> 30#include <asm/uaccess.h>
32#include <linux/kernel.h> 31#include <linux/kernel.h>
33#include <linux/string.h> /* memset */ 32#include <linux/string.h> /* memset */
@@ -144,40 +143,6 @@ static ssize_t udf_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
144 return retval; 143 return retval;
145} 144}
146 145
147/*
148 * udf_ioctl
149 *
150 * PURPOSE
151 * Issue an ioctl.
152 *
153 * DESCRIPTION
154 * Optional - sys_ioctl() will return -ENOTTY if this routine is not
155 * available, and the ioctl cannot be handled without filesystem help.
156 *
157 * sys_ioctl() handles these ioctls that apply only to regular files:
158 * FIBMAP [requires udf_block_map()], FIGETBSZ, FIONREAD
159 * These ioctls are also handled by sys_ioctl():
160 * FIOCLEX, FIONCLEX, FIONBIO, FIOASYNC
161 * All other ioctls are passed to the filesystem.
162 *
163 * Refer to sys_ioctl() in fs/ioctl.c
164 * sys_ioctl() -> .
165 *
166 * PRE-CONDITIONS
167 * inode Pointer to inode that ioctl was issued on.
168 * filp Pointer to file that ioctl was issued on.
169 * cmd The ioctl command.
170 * arg The ioctl argument [can be interpreted as a
171 * user-space pointer if desired].
172 *
173 * POST-CONDITIONS
174 * <return> Success (>=0) or an error code (<=0) that
175 * sys_ioctl() will return.
176 *
177 * HISTORY
178 * July 1, 1997 - Andrew E. Mileski
179 * Written, tested, and released.
180 */
181int udf_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, 146int udf_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
182 unsigned long arg) 147 unsigned long arg)
183{ 148{
@@ -225,18 +190,6 @@ int udf_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
225 return result; 190 return result;
226} 191}
227 192
228/*
229 * udf_release_file
230 *
231 * PURPOSE
232 * Called when all references to the file are closed
233 *
234 * DESCRIPTION
235 * Discard prealloced blocks
236 *
237 * HISTORY
238 *
239 */
240static int udf_release_file(struct inode *inode, struct file *filp) 193static int udf_release_file(struct inode *inode, struct file *filp)
241{ 194{
242 if (filp->f_mode & FMODE_WRITE) { 195 if (filp->f_mode & FMODE_WRITE) {
diff --git a/fs/udf/ialloc.c b/fs/udf/ialloc.c
index 84360315aca2..eb9cfa23dc3d 100644
--- a/fs/udf/ialloc.c
+++ b/fs/udf/ialloc.c
@@ -21,7 +21,6 @@
21#include "udfdecl.h" 21#include "udfdecl.h"
22#include <linux/fs.h> 22#include <linux/fs.h>
23#include <linux/quotaops.h> 23#include <linux/quotaops.h>
24#include <linux/udf_fs.h>
25#include <linux/sched.h> 24#include <linux/sched.h>
26#include <linux/slab.h> 25#include <linux/slab.h>
27 26
@@ -47,11 +46,9 @@ void udf_free_inode(struct inode *inode)
47 struct logicalVolIntegrityDescImpUse *lvidiu = 46 struct logicalVolIntegrityDescImpUse *lvidiu =
48 udf_sb_lvidiu(sbi); 47 udf_sb_lvidiu(sbi);
49 if (S_ISDIR(inode->i_mode)) 48 if (S_ISDIR(inode->i_mode))
50 lvidiu->numDirs = 49 le32_add_cpu(&lvidiu->numDirs, -1);
51 cpu_to_le32(le32_to_cpu(lvidiu->numDirs) - 1);
52 else 50 else
53 lvidiu->numFiles = 51 le32_add_cpu(&lvidiu->numFiles, -1);
54 cpu_to_le32(le32_to_cpu(lvidiu->numFiles) - 1);
55 52
56 mark_buffer_dirty(sbi->s_lvid_bh); 53 mark_buffer_dirty(sbi->s_lvid_bh);
57 } 54 }
@@ -105,11 +102,9 @@ struct inode *udf_new_inode(struct inode *dir, int mode, int *err)
105 lvhd = (struct logicalVolHeaderDesc *) 102 lvhd = (struct logicalVolHeaderDesc *)
106 (lvid->logicalVolContentsUse); 103 (lvid->logicalVolContentsUse);
107 if (S_ISDIR(mode)) 104 if (S_ISDIR(mode))
108 lvidiu->numDirs = 105 le32_add_cpu(&lvidiu->numDirs, 1);
109 cpu_to_le32(le32_to_cpu(lvidiu->numDirs) + 1);
110 else 106 else
111 lvidiu->numFiles = 107 le32_add_cpu(&lvidiu->numFiles, 1);
112 cpu_to_le32(le32_to_cpu(lvidiu->numFiles) + 1);
113 iinfo->i_unique = uniqueID = le64_to_cpu(lvhd->uniqueID); 108 iinfo->i_unique = uniqueID = le64_to_cpu(lvhd->uniqueID);
114 if (!(++uniqueID & 0x00000000FFFFFFFFUL)) 109 if (!(++uniqueID & 0x00000000FFFFFFFFUL))
115 uniqueID += 16; 110 uniqueID += 16;
diff --git a/fs/udf/inode.c b/fs/udf/inode.c
index 24cfa55d0fdc..6e74b117aaf0 100644
--- a/fs/udf/inode.c
+++ b/fs/udf/inode.c
@@ -37,6 +37,7 @@
37#include <linux/buffer_head.h> 37#include <linux/buffer_head.h>
38#include <linux/writeback.h> 38#include <linux/writeback.h>
39#include <linux/slab.h> 39#include <linux/slab.h>
40#include <linux/crc-itu-t.h>
40 41
41#include "udf_i.h" 42#include "udf_i.h"
42#include "udf_sb.h" 43#include "udf_sb.h"
@@ -66,22 +67,7 @@ static void udf_update_extents(struct inode *,
66 struct extent_position *); 67 struct extent_position *);
67static int udf_get_block(struct inode *, sector_t, struct buffer_head *, int); 68static int udf_get_block(struct inode *, sector_t, struct buffer_head *, int);
68 69
69/* 70
70 * udf_delete_inode
71 *
72 * PURPOSE
73 * Clean-up before the specified inode is destroyed.
74 *
75 * DESCRIPTION
76 * This routine is called when the kernel destroys an inode structure
77 * ie. when iput() finds i_count == 0.
78 *
79 * HISTORY
80 * July 1, 1997 - Andrew E. Mileski
81 * Written, tested, and released.
82 *
83 * Called at the last iput() if i_nlink is zero.
84 */
85void udf_delete_inode(struct inode *inode) 71void udf_delete_inode(struct inode *inode)
86{ 72{
87 truncate_inode_pages(&inode->i_data, 0); 73 truncate_inode_pages(&inode->i_data, 0);
@@ -323,9 +309,6 @@ static int udf_get_block(struct inode *inode, sector_t block,
323 309
324 lock_kernel(); 310 lock_kernel();
325 311
326 if (block < 0)
327 goto abort_negative;
328
329 iinfo = UDF_I(inode); 312 iinfo = UDF_I(inode);
330 if (block == iinfo->i_next_alloc_block + 1) { 313 if (block == iinfo->i_next_alloc_block + 1) {
331 iinfo->i_next_alloc_block++; 314 iinfo->i_next_alloc_block++;
@@ -347,10 +330,6 @@ static int udf_get_block(struct inode *inode, sector_t block,
347abort: 330abort:
348 unlock_kernel(); 331 unlock_kernel();
349 return err; 332 return err;
350
351abort_negative:
352 udf_warning(inode->i_sb, "udf_get_block", "block < 0");
353 goto abort;
354} 333}
355 334
356static struct buffer_head *udf_getblk(struct inode *inode, long block, 335static struct buffer_head *udf_getblk(struct inode *inode, long block,
@@ -1116,42 +1095,36 @@ static void __udf_read_inode(struct inode *inode)
1116 fe = (struct fileEntry *)bh->b_data; 1095 fe = (struct fileEntry *)bh->b_data;
1117 1096
1118 if (fe->icbTag.strategyType == cpu_to_le16(4096)) { 1097 if (fe->icbTag.strategyType == cpu_to_le16(4096)) {
1119 struct buffer_head *ibh = NULL, *nbh = NULL; 1098 struct buffer_head *ibh;
1120 struct indirectEntry *ie;
1121 1099
1122 ibh = udf_read_ptagged(inode->i_sb, iinfo->i_location, 1, 1100 ibh = udf_read_ptagged(inode->i_sb, iinfo->i_location, 1,
1123 &ident); 1101 &ident);
1124 if (ident == TAG_IDENT_IE) { 1102 if (ident == TAG_IDENT_IE && ibh) {
1125 if (ibh) { 1103 struct buffer_head *nbh = NULL;
1126 kernel_lb_addr loc; 1104 kernel_lb_addr loc;
1127 ie = (struct indirectEntry *)ibh->b_data; 1105 struct indirectEntry *ie;
1128 1106
1129 loc = lelb_to_cpu(ie->indirectICB.extLocation); 1107 ie = (struct indirectEntry *)ibh->b_data;
1130 1108 loc = lelb_to_cpu(ie->indirectICB.extLocation);
1131 if (ie->indirectICB.extLength && 1109
1132 (nbh = udf_read_ptagged(inode->i_sb, loc, 0, 1110 if (ie->indirectICB.extLength &&
1133 &ident))) { 1111 (nbh = udf_read_ptagged(inode->i_sb, loc, 0,
1134 if (ident == TAG_IDENT_FE || 1112 &ident))) {
1135 ident == TAG_IDENT_EFE) { 1113 if (ident == TAG_IDENT_FE ||
1136 memcpy(&iinfo->i_location, 1114 ident == TAG_IDENT_EFE) {
1137 &loc, 1115 memcpy(&iinfo->i_location,
1138 sizeof(kernel_lb_addr)); 1116 &loc,
1139 brelse(bh); 1117 sizeof(kernel_lb_addr));
1140 brelse(ibh); 1118 brelse(bh);
1141 brelse(nbh);
1142 __udf_read_inode(inode);
1143 return;
1144 } else {
1145 brelse(nbh);
1146 brelse(ibh);
1147 }
1148 } else {
1149 brelse(ibh); 1119 brelse(ibh);
1120 brelse(nbh);
1121 __udf_read_inode(inode);
1122 return;
1150 } 1123 }
1124 brelse(nbh);
1151 } 1125 }
1152 } else {
1153 brelse(ibh);
1154 } 1126 }
1127 brelse(ibh);
1155 } else if (fe->icbTag.strategyType != cpu_to_le16(4)) { 1128 } else if (fe->icbTag.strategyType != cpu_to_le16(4)) {
1156 printk(KERN_ERR "udf: unsupported strategy type: %d\n", 1129 printk(KERN_ERR "udf: unsupported strategy type: %d\n",
1157 le16_to_cpu(fe->icbTag.strategyType)); 1130 le16_to_cpu(fe->icbTag.strategyType));
@@ -1168,8 +1141,6 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh)
1168{ 1141{
1169 struct fileEntry *fe; 1142 struct fileEntry *fe;
1170 struct extendedFileEntry *efe; 1143 struct extendedFileEntry *efe;
1171 time_t convtime;
1172 long convtime_usec;
1173 int offset; 1144 int offset;
1174 struct udf_sb_info *sbi = UDF_SB(inode->i_sb); 1145 struct udf_sb_info *sbi = UDF_SB(inode->i_sb);
1175 struct udf_inode_info *iinfo = UDF_I(inode); 1146 struct udf_inode_info *iinfo = UDF_I(inode);
@@ -1257,29 +1228,15 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh)
1257 inode->i_blocks = le64_to_cpu(fe->logicalBlocksRecorded) << 1228 inode->i_blocks = le64_to_cpu(fe->logicalBlocksRecorded) <<
1258 (inode->i_sb->s_blocksize_bits - 9); 1229 (inode->i_sb->s_blocksize_bits - 9);
1259 1230
1260 if (udf_stamp_to_time(&convtime, &convtime_usec, 1231 if (!udf_disk_stamp_to_time(&inode->i_atime, fe->accessTime))
1261 lets_to_cpu(fe->accessTime))) {
1262 inode->i_atime.tv_sec = convtime;
1263 inode->i_atime.tv_nsec = convtime_usec * 1000;
1264 } else {
1265 inode->i_atime = sbi->s_record_time; 1232 inode->i_atime = sbi->s_record_time;
1266 }
1267 1233
1268 if (udf_stamp_to_time(&convtime, &convtime_usec, 1234 if (!udf_disk_stamp_to_time(&inode->i_mtime,
1269 lets_to_cpu(fe->modificationTime))) { 1235 fe->modificationTime))
1270 inode->i_mtime.tv_sec = convtime;
1271 inode->i_mtime.tv_nsec = convtime_usec * 1000;
1272 } else {
1273 inode->i_mtime = sbi->s_record_time; 1236 inode->i_mtime = sbi->s_record_time;
1274 }
1275 1237
1276 if (udf_stamp_to_time(&convtime, &convtime_usec, 1238 if (!udf_disk_stamp_to_time(&inode->i_ctime, fe->attrTime))
1277 lets_to_cpu(fe->attrTime))) {
1278 inode->i_ctime.tv_sec = convtime;
1279 inode->i_ctime.tv_nsec = convtime_usec * 1000;
1280 } else {
1281 inode->i_ctime = sbi->s_record_time; 1239 inode->i_ctime = sbi->s_record_time;
1282 }
1283 1240
1284 iinfo->i_unique = le64_to_cpu(fe->uniqueID); 1241 iinfo->i_unique = le64_to_cpu(fe->uniqueID);
1285 iinfo->i_lenEAttr = le32_to_cpu(fe->lengthExtendedAttr); 1242 iinfo->i_lenEAttr = le32_to_cpu(fe->lengthExtendedAttr);
@@ -1289,37 +1246,18 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh)
1289 inode->i_blocks = le64_to_cpu(efe->logicalBlocksRecorded) << 1246 inode->i_blocks = le64_to_cpu(efe->logicalBlocksRecorded) <<
1290 (inode->i_sb->s_blocksize_bits - 9); 1247 (inode->i_sb->s_blocksize_bits - 9);
1291 1248
1292 if (udf_stamp_to_time(&convtime, &convtime_usec, 1249 if (!udf_disk_stamp_to_time(&inode->i_atime, efe->accessTime))
1293 lets_to_cpu(efe->accessTime))) {
1294 inode->i_atime.tv_sec = convtime;
1295 inode->i_atime.tv_nsec = convtime_usec * 1000;
1296 } else {
1297 inode->i_atime = sbi->s_record_time; 1250 inode->i_atime = sbi->s_record_time;
1298 }
1299 1251
1300 if (udf_stamp_to_time(&convtime, &convtime_usec, 1252 if (!udf_disk_stamp_to_time(&inode->i_mtime,
1301 lets_to_cpu(efe->modificationTime))) { 1253 efe->modificationTime))
1302 inode->i_mtime.tv_sec = convtime;
1303 inode->i_mtime.tv_nsec = convtime_usec * 1000;
1304 } else {
1305 inode->i_mtime = sbi->s_record_time; 1254 inode->i_mtime = sbi->s_record_time;
1306 }
1307 1255
1308 if (udf_stamp_to_time(&convtime, &convtime_usec, 1256 if (!udf_disk_stamp_to_time(&iinfo->i_crtime, efe->createTime))
1309 lets_to_cpu(efe->createTime))) {
1310 iinfo->i_crtime.tv_sec = convtime;
1311 iinfo->i_crtime.tv_nsec = convtime_usec * 1000;
1312 } else {
1313 iinfo->i_crtime = sbi->s_record_time; 1257 iinfo->i_crtime = sbi->s_record_time;
1314 }
1315 1258
1316 if (udf_stamp_to_time(&convtime, &convtime_usec, 1259 if (!udf_disk_stamp_to_time(&inode->i_ctime, efe->attrTime))
1317 lets_to_cpu(efe->attrTime))) {
1318 inode->i_ctime.tv_sec = convtime;
1319 inode->i_ctime.tv_nsec = convtime_usec * 1000;
1320 } else {
1321 inode->i_ctime = sbi->s_record_time; 1260 inode->i_ctime = sbi->s_record_time;
1322 }
1323 1261
1324 iinfo->i_unique = le64_to_cpu(efe->uniqueID); 1262 iinfo->i_unique = le64_to_cpu(efe->uniqueID);
1325 iinfo->i_lenEAttr = le32_to_cpu(efe->lengthExtendedAttr); 1263 iinfo->i_lenEAttr = le32_to_cpu(efe->lengthExtendedAttr);
@@ -1338,6 +1276,7 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh)
1338 case ICBTAG_FILE_TYPE_REALTIME: 1276 case ICBTAG_FILE_TYPE_REALTIME:
1339 case ICBTAG_FILE_TYPE_REGULAR: 1277 case ICBTAG_FILE_TYPE_REGULAR:
1340 case ICBTAG_FILE_TYPE_UNDEF: 1278 case ICBTAG_FILE_TYPE_UNDEF:
1279 case ICBTAG_FILE_TYPE_VAT20:
1341 if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) 1280 if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB)
1342 inode->i_data.a_ops = &udf_adinicb_aops; 1281 inode->i_data.a_ops = &udf_adinicb_aops;
1343 else 1282 else
@@ -1363,6 +1302,15 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh)
1363 inode->i_op = &page_symlink_inode_operations; 1302 inode->i_op = &page_symlink_inode_operations;
1364 inode->i_mode = S_IFLNK | S_IRWXUGO; 1303 inode->i_mode = S_IFLNK | S_IRWXUGO;
1365 break; 1304 break;
1305 case ICBTAG_FILE_TYPE_MAIN:
1306 udf_debug("METADATA FILE-----\n");
1307 break;
1308 case ICBTAG_FILE_TYPE_MIRROR:
1309 udf_debug("METADATA MIRROR FILE-----\n");
1310 break;
1311 case ICBTAG_FILE_TYPE_BITMAP:
1312 udf_debug("METADATA BITMAP FILE-----\n");
1313 break;
1366 default: 1314 default:
1367 printk(KERN_ERR "udf: udf_fill_inode(ino %ld) failed unknown " 1315 printk(KERN_ERR "udf: udf_fill_inode(ino %ld) failed unknown "
1368 "file type=%d\n", inode->i_ino, 1316 "file type=%d\n", inode->i_ino,
@@ -1416,21 +1364,6 @@ static mode_t udf_convert_permissions(struct fileEntry *fe)
1416 return mode; 1364 return mode;
1417} 1365}
1418 1366
1419/*
1420 * udf_write_inode
1421 *
1422 * PURPOSE
1423 * Write out the specified inode.
1424 *
1425 * DESCRIPTION
1426 * This routine is called whenever an inode is synced.
1427 * Currently this routine is just a placeholder.
1428 *
1429 * HISTORY
1430 * July 1, 1997 - Andrew E. Mileski
1431 * Written, tested, and released.
1432 */
1433
1434int udf_write_inode(struct inode *inode, int sync) 1367int udf_write_inode(struct inode *inode, int sync)
1435{ 1368{
1436 int ret; 1369 int ret;
@@ -1455,7 +1388,6 @@ static int udf_update_inode(struct inode *inode, int do_sync)
1455 uint32_t udfperms; 1388 uint32_t udfperms;
1456 uint16_t icbflags; 1389 uint16_t icbflags;
1457 uint16_t crclen; 1390 uint16_t crclen;
1458 kernel_timestamp cpu_time;
1459 int err = 0; 1391 int err = 0;
1460 struct udf_sb_info *sbi = UDF_SB(inode->i_sb); 1392 struct udf_sb_info *sbi = UDF_SB(inode->i_sb);
1461 unsigned char blocksize_bits = inode->i_sb->s_blocksize_bits; 1393 unsigned char blocksize_bits = inode->i_sb->s_blocksize_bits;
@@ -1488,9 +1420,9 @@ static int udf_update_inode(struct inode *inode, int do_sync)
1488 iinfo->i_location. 1420 iinfo->i_location.
1489 logicalBlockNum); 1421 logicalBlockNum);
1490 use->descTag.descCRCLength = cpu_to_le16(crclen); 1422 use->descTag.descCRCLength = cpu_to_le16(crclen);
1491 use->descTag.descCRC = cpu_to_le16(udf_crc((char *)use + 1423 use->descTag.descCRC = cpu_to_le16(crc_itu_t(0, (char *)use +
1492 sizeof(tag), crclen, 1424 sizeof(tag),
1493 0)); 1425 crclen));
1494 use->descTag.tagChecksum = udf_tag_checksum(&use->descTag); 1426 use->descTag.tagChecksum = udf_tag_checksum(&use->descTag);
1495 1427
1496 mark_buffer_dirty(bh); 1428 mark_buffer_dirty(bh);
@@ -1558,12 +1490,9 @@ static int udf_update_inode(struct inode *inode, int do_sync)
1558 (inode->i_blocks + (1 << (blocksize_bits - 9)) - 1) >> 1490 (inode->i_blocks + (1 << (blocksize_bits - 9)) - 1) >>
1559 (blocksize_bits - 9)); 1491 (blocksize_bits - 9));
1560 1492
1561 if (udf_time_to_stamp(&cpu_time, inode->i_atime)) 1493 udf_time_to_disk_stamp(&fe->accessTime, inode->i_atime);
1562 fe->accessTime = cpu_to_lets(cpu_time); 1494 udf_time_to_disk_stamp(&fe->modificationTime, inode->i_mtime);
1563 if (udf_time_to_stamp(&cpu_time, inode->i_mtime)) 1495 udf_time_to_disk_stamp(&fe->attrTime, inode->i_ctime);
1564 fe->modificationTime = cpu_to_lets(cpu_time);
1565 if (udf_time_to_stamp(&cpu_time, inode->i_ctime))
1566 fe->attrTime = cpu_to_lets(cpu_time);
1567 memset(&(fe->impIdent), 0, sizeof(regid)); 1496 memset(&(fe->impIdent), 0, sizeof(regid));
1568 strcpy(fe->impIdent.ident, UDF_ID_DEVELOPER); 1497 strcpy(fe->impIdent.ident, UDF_ID_DEVELOPER);
1569 fe->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX; 1498 fe->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX;
@@ -1598,14 +1527,10 @@ static int udf_update_inode(struct inode *inode, int do_sync)
1598 iinfo->i_crtime.tv_nsec > inode->i_ctime.tv_nsec)) 1527 iinfo->i_crtime.tv_nsec > inode->i_ctime.tv_nsec))
1599 iinfo->i_crtime = inode->i_ctime; 1528 iinfo->i_crtime = inode->i_ctime;
1600 1529
1601 if (udf_time_to_stamp(&cpu_time, inode->i_atime)) 1530 udf_time_to_disk_stamp(&efe->accessTime, inode->i_atime);
1602 efe->accessTime = cpu_to_lets(cpu_time); 1531 udf_time_to_disk_stamp(&efe->modificationTime, inode->i_mtime);
1603 if (udf_time_to_stamp(&cpu_time, inode->i_mtime)) 1532 udf_time_to_disk_stamp(&efe->createTime, iinfo->i_crtime);
1604 efe->modificationTime = cpu_to_lets(cpu_time); 1533 udf_time_to_disk_stamp(&efe->attrTime, inode->i_ctime);
1605 if (udf_time_to_stamp(&cpu_time, iinfo->i_crtime))
1606 efe->createTime = cpu_to_lets(cpu_time);
1607 if (udf_time_to_stamp(&cpu_time, inode->i_ctime))
1608 efe->attrTime = cpu_to_lets(cpu_time);
1609 1534
1610 memset(&(efe->impIdent), 0, sizeof(regid)); 1535 memset(&(efe->impIdent), 0, sizeof(regid));
1611 strcpy(efe->impIdent.ident, UDF_ID_DEVELOPER); 1536 strcpy(efe->impIdent.ident, UDF_ID_DEVELOPER);
@@ -1660,8 +1585,8 @@ static int udf_update_inode(struct inode *inode, int do_sync)
1660 crclen += iinfo->i_lenEAttr + iinfo->i_lenAlloc - 1585 crclen += iinfo->i_lenEAttr + iinfo->i_lenAlloc -
1661 sizeof(tag); 1586 sizeof(tag);
1662 fe->descTag.descCRCLength = cpu_to_le16(crclen); 1587 fe->descTag.descCRCLength = cpu_to_le16(crclen);
1663 fe->descTag.descCRC = cpu_to_le16(udf_crc((char *)fe + sizeof(tag), 1588 fe->descTag.descCRC = cpu_to_le16(crc_itu_t(0, (char *)fe + sizeof(tag),
1664 crclen, 0)); 1589 crclen));
1665 fe->descTag.tagChecksum = udf_tag_checksum(&fe->descTag); 1590 fe->descTag.tagChecksum = udf_tag_checksum(&fe->descTag);
1666 1591
1667 /* write the data blocks */ 1592 /* write the data blocks */
@@ -1778,9 +1703,7 @@ int8_t udf_add_aext(struct inode *inode, struct extent_position *epos,
1778 1703
1779 if (epos->bh) { 1704 if (epos->bh) {
1780 aed = (struct allocExtDesc *)epos->bh->b_data; 1705 aed = (struct allocExtDesc *)epos->bh->b_data;
1781 aed->lengthAllocDescs = 1706 le32_add_cpu(&aed->lengthAllocDescs, adsize);
1782 cpu_to_le32(le32_to_cpu(
1783 aed->lengthAllocDescs) + adsize);
1784 } else { 1707 } else {
1785 iinfo->i_lenAlloc += adsize; 1708 iinfo->i_lenAlloc += adsize;
1786 mark_inode_dirty(inode); 1709 mark_inode_dirty(inode);
@@ -1830,9 +1753,7 @@ int8_t udf_add_aext(struct inode *inode, struct extent_position *epos,
1830 mark_inode_dirty(inode); 1753 mark_inode_dirty(inode);
1831 } else { 1754 } else {
1832 aed = (struct allocExtDesc *)epos->bh->b_data; 1755 aed = (struct allocExtDesc *)epos->bh->b_data;
1833 aed->lengthAllocDescs = 1756 le32_add_cpu(&aed->lengthAllocDescs, adsize);
1834 cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) +
1835 adsize);
1836 if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || 1757 if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) ||
1837 UDF_SB(inode->i_sb)->s_udfrev >= 0x0201) 1758 UDF_SB(inode->i_sb)->s_udfrev >= 0x0201)
1838 udf_update_tag(epos->bh->b_data, 1759 udf_update_tag(epos->bh->b_data,
@@ -2046,9 +1967,7 @@ int8_t udf_delete_aext(struct inode *inode, struct extent_position epos,
2046 mark_inode_dirty(inode); 1967 mark_inode_dirty(inode);
2047 } else { 1968 } else {
2048 aed = (struct allocExtDesc *)oepos.bh->b_data; 1969 aed = (struct allocExtDesc *)oepos.bh->b_data;
2049 aed->lengthAllocDescs = 1970 le32_add_cpu(&aed->lengthAllocDescs, -(2 * adsize));
2050 cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) -
2051 (2 * adsize));
2052 if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || 1971 if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) ||
2053 UDF_SB(inode->i_sb)->s_udfrev >= 0x0201) 1972 UDF_SB(inode->i_sb)->s_udfrev >= 0x0201)
2054 udf_update_tag(oepos.bh->b_data, 1973 udf_update_tag(oepos.bh->b_data,
@@ -2065,9 +1984,7 @@ int8_t udf_delete_aext(struct inode *inode, struct extent_position epos,
2065 mark_inode_dirty(inode); 1984 mark_inode_dirty(inode);
2066 } else { 1985 } else {
2067 aed = (struct allocExtDesc *)oepos.bh->b_data; 1986 aed = (struct allocExtDesc *)oepos.bh->b_data;
2068 aed->lengthAllocDescs = 1987 le32_add_cpu(&aed->lengthAllocDescs, -adsize);
2069 cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) -
2070 adsize);
2071 if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || 1988 if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) ||
2072 UDF_SB(inode->i_sb)->s_udfrev >= 0x0201) 1989 UDF_SB(inode->i_sb)->s_udfrev >= 0x0201)
2073 udf_update_tag(oepos.bh->b_data, 1990 udf_update_tag(oepos.bh->b_data,
@@ -2095,11 +2012,6 @@ int8_t inode_bmap(struct inode *inode, sector_t block,
2095 int8_t etype; 2012 int8_t etype;
2096 struct udf_inode_info *iinfo; 2013 struct udf_inode_info *iinfo;
2097 2014
2098 if (block < 0) {
2099 printk(KERN_ERR "udf: inode_bmap: block < 0\n");
2100 return -1;
2101 }
2102
2103 iinfo = UDF_I(inode); 2015 iinfo = UDF_I(inode);
2104 pos->offset = 0; 2016 pos->offset = 0;
2105 pos->block = iinfo->i_location; 2017 pos->block = iinfo->i_location;
diff --git a/fs/udf/lowlevel.c b/fs/udf/lowlevel.c
index 579bae71e67e..703843f30ffd 100644
--- a/fs/udf/lowlevel.c
+++ b/fs/udf/lowlevel.c
@@ -23,7 +23,6 @@
23#include <linux/cdrom.h> 23#include <linux/cdrom.h>
24#include <asm/uaccess.h> 24#include <asm/uaccess.h>
25 25
26#include <linux/udf_fs.h>
27#include "udf_sb.h" 26#include "udf_sb.h"
28 27
29unsigned int udf_get_last_session(struct super_block *sb) 28unsigned int udf_get_last_session(struct super_block *sb)
diff --git a/fs/udf/misc.c b/fs/udf/misc.c
index a1d6da0caf71..84bf0fd4a4f1 100644
--- a/fs/udf/misc.c
+++ b/fs/udf/misc.c
@@ -23,8 +23,8 @@
23 23
24#include <linux/fs.h> 24#include <linux/fs.h>
25#include <linux/string.h> 25#include <linux/string.h>
26#include <linux/udf_fs.h>
27#include <linux/buffer_head.h> 26#include <linux/buffer_head.h>
27#include <linux/crc-itu-t.h>
28 28
29#include "udf_i.h" 29#include "udf_i.h"
30#include "udf_sb.h" 30#include "udf_sb.h"
@@ -136,8 +136,8 @@ struct genericFormat *udf_add_extendedattr(struct inode *inode, uint32_t size,
136 /* rewrite CRC + checksum of eahd */ 136 /* rewrite CRC + checksum of eahd */
137 crclen = sizeof(struct extendedAttrHeaderDesc) - sizeof(tag); 137 crclen = sizeof(struct extendedAttrHeaderDesc) - sizeof(tag);
138 eahd->descTag.descCRCLength = cpu_to_le16(crclen); 138 eahd->descTag.descCRCLength = cpu_to_le16(crclen);
139 eahd->descTag.descCRC = cpu_to_le16(udf_crc((char *)eahd + 139 eahd->descTag.descCRC = cpu_to_le16(crc_itu_t(0, (char *)eahd +
140 sizeof(tag), crclen, 0)); 140 sizeof(tag), crclen));
141 eahd->descTag.tagChecksum = udf_tag_checksum(&eahd->descTag); 141 eahd->descTag.tagChecksum = udf_tag_checksum(&eahd->descTag);
142 iinfo->i_lenEAttr += size; 142 iinfo->i_lenEAttr += size;
143 return (struct genericFormat *)&ea[offset]; 143 return (struct genericFormat *)&ea[offset];
@@ -204,16 +204,15 @@ struct buffer_head *udf_read_tagged(struct super_block *sb, uint32_t block,
204{ 204{
205 tag *tag_p; 205 tag *tag_p;
206 struct buffer_head *bh = NULL; 206 struct buffer_head *bh = NULL;
207 struct udf_sb_info *sbi = UDF_SB(sb);
208 207
209 /* Read the block */ 208 /* Read the block */
210 if (block == 0xFFFFFFFF) 209 if (block == 0xFFFFFFFF)
211 return NULL; 210 return NULL;
212 211
213 bh = udf_tread(sb, block + sbi->s_session); 212 bh = udf_tread(sb, block);
214 if (!bh) { 213 if (!bh) {
215 udf_debug("block=%d, location=%d: read failed\n", 214 udf_debug("block=%d, location=%d: read failed\n",
216 block + sbi->s_session, location); 215 block, location);
217 return NULL; 216 return NULL;
218 } 217 }
219 218
@@ -223,8 +222,7 @@ struct buffer_head *udf_read_tagged(struct super_block *sb, uint32_t block,
223 222
224 if (location != le32_to_cpu(tag_p->tagLocation)) { 223 if (location != le32_to_cpu(tag_p->tagLocation)) {
225 udf_debug("location mismatch block %u, tag %u != %u\n", 224 udf_debug("location mismatch block %u, tag %u != %u\n",
226 block + sbi->s_session, 225 block, le32_to_cpu(tag_p->tagLocation), location);
227 le32_to_cpu(tag_p->tagLocation), location);
228 goto error_out; 226 goto error_out;
229 } 227 }
230 228
@@ -244,13 +242,13 @@ struct buffer_head *udf_read_tagged(struct super_block *sb, uint32_t block,
244 242
245 /* Verify the descriptor CRC */ 243 /* Verify the descriptor CRC */
246 if (le16_to_cpu(tag_p->descCRCLength) + sizeof(tag) > sb->s_blocksize || 244 if (le16_to_cpu(tag_p->descCRCLength) + sizeof(tag) > sb->s_blocksize ||
247 le16_to_cpu(tag_p->descCRC) == udf_crc(bh->b_data + sizeof(tag), 245 le16_to_cpu(tag_p->descCRC) == crc_itu_t(0,
248 le16_to_cpu(tag_p->descCRCLength), 0)) 246 bh->b_data + sizeof(tag),
247 le16_to_cpu(tag_p->descCRCLength)))
249 return bh; 248 return bh;
250 249
251 udf_debug("Crc failure block %d: crc = %d, crclen = %d\n", 250 udf_debug("Crc failure block %d: crc = %d, crclen = %d\n", block,
252 block + sbi->s_session, le16_to_cpu(tag_p->descCRC), 251 le16_to_cpu(tag_p->descCRC), le16_to_cpu(tag_p->descCRCLength));
253 le16_to_cpu(tag_p->descCRCLength));
254 252
255error_out: 253error_out:
256 brelse(bh); 254 brelse(bh);
@@ -270,7 +268,7 @@ void udf_update_tag(char *data, int length)
270 length -= sizeof(tag); 268 length -= sizeof(tag);
271 269
272 tptr->descCRCLength = cpu_to_le16(length); 270 tptr->descCRCLength = cpu_to_le16(length);
273 tptr->descCRC = cpu_to_le16(udf_crc(data + sizeof(tag), length, 0)); 271 tptr->descCRC = cpu_to_le16(crc_itu_t(0, data + sizeof(tag), length));
274 tptr->tagChecksum = udf_tag_checksum(tptr); 272 tptr->tagChecksum = udf_tag_checksum(tptr);
275} 273}
276 274
diff --git a/fs/udf/namei.c b/fs/udf/namei.c
index 112a5fb0b27b..ba5537d4bc15 100644
--- a/fs/udf/namei.c
+++ b/fs/udf/namei.c
@@ -31,6 +31,7 @@
31#include <linux/smp_lock.h> 31#include <linux/smp_lock.h>
32#include <linux/buffer_head.h> 32#include <linux/buffer_head.h>
33#include <linux/sched.h> 33#include <linux/sched.h>
34#include <linux/crc-itu-t.h>
34 35
35static inline int udf_match(int len1, const char *name1, int len2, 36static inline int udf_match(int len1, const char *name1, int len2,
36 const char *name2) 37 const char *name2)
@@ -97,25 +98,23 @@ int udf_write_fi(struct inode *inode, struct fileIdentDesc *cfi,
97 memset(fibh->ebh->b_data, 0x00, padlen + offset); 98 memset(fibh->ebh->b_data, 0x00, padlen + offset);
98 } 99 }
99 100
100 crc = udf_crc((uint8_t *)cfi + sizeof(tag), 101 crc = crc_itu_t(0, (uint8_t *)cfi + sizeof(tag),
101 sizeof(struct fileIdentDesc) - sizeof(tag), 0); 102 sizeof(struct fileIdentDesc) - sizeof(tag));
102 103
103 if (fibh->sbh == fibh->ebh) { 104 if (fibh->sbh == fibh->ebh) {
104 crc = udf_crc((uint8_t *)sfi->impUse, 105 crc = crc_itu_t(crc, (uint8_t *)sfi->impUse,
105 crclen + sizeof(tag) - 106 crclen + sizeof(tag) -
106 sizeof(struct fileIdentDesc), crc); 107 sizeof(struct fileIdentDesc));
107 } else if (sizeof(struct fileIdentDesc) >= -fibh->soffset) { 108 } else if (sizeof(struct fileIdentDesc) >= -fibh->soffset) {
108 crc = udf_crc(fibh->ebh->b_data + 109 crc = crc_itu_t(crc, fibh->ebh->b_data +
109 sizeof(struct fileIdentDesc) + 110 sizeof(struct fileIdentDesc) +
110 fibh->soffset, 111 fibh->soffset,
111 crclen + sizeof(tag) - 112 crclen + sizeof(tag) -
112 sizeof(struct fileIdentDesc), 113 sizeof(struct fileIdentDesc));
113 crc);
114 } else { 114 } else {
115 crc = udf_crc((uint8_t *)sfi->impUse, 115 crc = crc_itu_t(crc, (uint8_t *)sfi->impUse,
116 -fibh->soffset - sizeof(struct fileIdentDesc), 116 -fibh->soffset - sizeof(struct fileIdentDesc));
117 crc); 117 crc = crc_itu_t(crc, fibh->ebh->b_data, fibh->eoffset);
118 crc = udf_crc(fibh->ebh->b_data, fibh->eoffset, crc);
119 } 118 }
120 119
121 cfi->descTag.descCRC = cpu_to_le16(crc); 120 cfi->descTag.descCRC = cpu_to_le16(crc);
@@ -149,7 +148,7 @@ static struct fileIdentDesc *udf_find_entry(struct inode *dir,
149 struct fileIdentDesc *fi = NULL; 148 struct fileIdentDesc *fi = NULL;
150 loff_t f_pos; 149 loff_t f_pos;
151 int block, flen; 150 int block, flen;
152 char fname[UDF_NAME_LEN]; 151 char *fname = NULL;
153 char *nameptr; 152 char *nameptr;
154 uint8_t lfi; 153 uint8_t lfi;
155 uint16_t liu; 154 uint16_t liu;
@@ -163,12 +162,12 @@ static struct fileIdentDesc *udf_find_entry(struct inode *dir,
163 size = udf_ext0_offset(dir) + dir->i_size; 162 size = udf_ext0_offset(dir) + dir->i_size;
164 f_pos = udf_ext0_offset(dir); 163 f_pos = udf_ext0_offset(dir);
165 164
165 fibh->sbh = fibh->ebh = NULL;
166 fibh->soffset = fibh->eoffset = f_pos & (dir->i_sb->s_blocksize - 1); 166 fibh->soffset = fibh->eoffset = f_pos & (dir->i_sb->s_blocksize - 1);
167 if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) 167 if (dinfo->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB) {
168 fibh->sbh = fibh->ebh = NULL; 168 if (inode_bmap(dir, f_pos >> dir->i_sb->s_blocksize_bits, &epos,
169 else if (inode_bmap(dir, f_pos >> dir->i_sb->s_blocksize_bits, 169 &eloc, &elen, &offset) != (EXT_RECORDED_ALLOCATED >> 30))
170 &epos, &eloc, &elen, &offset) == 170 goto out_err;
171 (EXT_RECORDED_ALLOCATED >> 30)) {
172 block = udf_get_lb_pblock(dir->i_sb, eloc, offset); 171 block = udf_get_lb_pblock(dir->i_sb, eloc, offset);
173 if ((++offset << dir->i_sb->s_blocksize_bits) < elen) { 172 if ((++offset << dir->i_sb->s_blocksize_bits) < elen) {
174 if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT) 173 if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT)
@@ -179,25 +178,19 @@ static struct fileIdentDesc *udf_find_entry(struct inode *dir,
179 offset = 0; 178 offset = 0;
180 179
181 fibh->sbh = fibh->ebh = udf_tread(dir->i_sb, block); 180 fibh->sbh = fibh->ebh = udf_tread(dir->i_sb, block);
182 if (!fibh->sbh) { 181 if (!fibh->sbh)
183 brelse(epos.bh); 182 goto out_err;
184 return NULL;
185 }
186 } else {
187 brelse(epos.bh);
188 return NULL;
189 } 183 }
190 184
185 fname = kmalloc(UDF_NAME_LEN, GFP_NOFS);
186 if (!fname)
187 goto out_err;
188
191 while (f_pos < size) { 189 while (f_pos < size) {
192 fi = udf_fileident_read(dir, &f_pos, fibh, cfi, &epos, &eloc, 190 fi = udf_fileident_read(dir, &f_pos, fibh, cfi, &epos, &eloc,
193 &elen, &offset); 191 &elen, &offset);
194 if (!fi) { 192 if (!fi)
195 if (fibh->sbh != fibh->ebh) 193 goto out_err;
196 brelse(fibh->ebh);
197 brelse(fibh->sbh);
198 brelse(epos.bh);
199 return NULL;
200 }
201 194
202 liu = le16_to_cpu(cfi->lengthOfImpUse); 195 liu = le16_to_cpu(cfi->lengthOfImpUse);
203 lfi = cfi->lengthFileIdent; 196 lfi = cfi->lengthFileIdent;
@@ -237,53 +230,22 @@ static struct fileIdentDesc *udf_find_entry(struct inode *dir,
237 230
238 flen = udf_get_filename(dir->i_sb, nameptr, fname, lfi); 231 flen = udf_get_filename(dir->i_sb, nameptr, fname, lfi);
239 if (flen && udf_match(flen, fname, dentry->d_name.len, 232 if (flen && udf_match(flen, fname, dentry->d_name.len,
240 dentry->d_name.name)) { 233 dentry->d_name.name))
241 brelse(epos.bh); 234 goto out_ok;
242 return fi;
243 }
244 } 235 }
245 236
237out_err:
238 fi = NULL;
246 if (fibh->sbh != fibh->ebh) 239 if (fibh->sbh != fibh->ebh)
247 brelse(fibh->ebh); 240 brelse(fibh->ebh);
248 brelse(fibh->sbh); 241 brelse(fibh->sbh);
242out_ok:
249 brelse(epos.bh); 243 brelse(epos.bh);
244 kfree(fname);
250 245
251 return NULL; 246 return fi;
252} 247}
253 248
254/*
255 * udf_lookup
256 *
257 * PURPOSE
258 * Look-up the inode for a given name.
259 *
260 * DESCRIPTION
261 * Required - lookup_dentry() will return -ENOTDIR if this routine is not
262 * available for a directory. The filesystem is useless if this routine is
263 * not available for at least the filesystem's root directory.
264 *
265 * This routine is passed an incomplete dentry - it must be completed by
266 * calling d_add(dentry, inode). If the name does not exist, then the
267 * specified inode must be set to null. An error should only be returned
268 * when the lookup fails for a reason other than the name not existing.
269 * Note that the directory inode semaphore is held during the call.
270 *
271 * Refer to lookup_dentry() in fs/namei.c
272 * lookup_dentry() -> lookup() -> real_lookup() -> .
273 *
274 * PRE-CONDITIONS
275 * dir Pointer to inode of parent directory.
276 * dentry Pointer to dentry to complete.
277 * nd Pointer to lookup nameidata
278 *
279 * POST-CONDITIONS
280 * <return> Zero on success.
281 *
282 * HISTORY
283 * July 1, 1997 - Andrew E. Mileski
284 * Written, tested, and released.
285 */
286
287static struct dentry *udf_lookup(struct inode *dir, struct dentry *dentry, 249static struct dentry *udf_lookup(struct inode *dir, struct dentry *dentry,
288 struct nameidata *nd) 250 struct nameidata *nd)
289{ 251{
@@ -336,11 +298,9 @@ static struct fileIdentDesc *udf_add_entry(struct inode *dir,
336{ 298{
337 struct super_block *sb = dir->i_sb; 299 struct super_block *sb = dir->i_sb;
338 struct fileIdentDesc *fi = NULL; 300 struct fileIdentDesc *fi = NULL;
339 char name[UDF_NAME_LEN], fname[UDF_NAME_LEN]; 301 char *name = NULL;
340 int namelen; 302 int namelen;
341 loff_t f_pos; 303 loff_t f_pos;
342 int flen;
343 char *nameptr;
344 loff_t size = udf_ext0_offset(dir) + dir->i_size; 304 loff_t size = udf_ext0_offset(dir) + dir->i_size;
345 int nfidlen; 305 int nfidlen;
346 uint8_t lfi; 306 uint8_t lfi;
@@ -352,16 +312,23 @@ static struct fileIdentDesc *udf_add_entry(struct inode *dir,
352 struct extent_position epos = {}; 312 struct extent_position epos = {};
353 struct udf_inode_info *dinfo; 313 struct udf_inode_info *dinfo;
354 314
315 fibh->sbh = fibh->ebh = NULL;
316 name = kmalloc(UDF_NAME_LEN, GFP_NOFS);
317 if (!name) {
318 *err = -ENOMEM;
319 goto out_err;
320 }
321
355 if (dentry) { 322 if (dentry) {
356 if (!dentry->d_name.len) { 323 if (!dentry->d_name.len) {
357 *err = -EINVAL; 324 *err = -EINVAL;
358 return NULL; 325 goto out_err;
359 } 326 }
360 namelen = udf_put_filename(sb, dentry->d_name.name, name, 327 namelen = udf_put_filename(sb, dentry->d_name.name, name,
361 dentry->d_name.len); 328 dentry->d_name.len);
362 if (!namelen) { 329 if (!namelen) {
363 *err = -ENAMETOOLONG; 330 *err = -ENAMETOOLONG;
364 return NULL; 331 goto out_err;
365 } 332 }
366 } else { 333 } else {
367 namelen = 0; 334 namelen = 0;
@@ -373,11 +340,14 @@ static struct fileIdentDesc *udf_add_entry(struct inode *dir,
373 340
374 fibh->soffset = fibh->eoffset = f_pos & (dir->i_sb->s_blocksize - 1); 341 fibh->soffset = fibh->eoffset = f_pos & (dir->i_sb->s_blocksize - 1);
375 dinfo = UDF_I(dir); 342 dinfo = UDF_I(dir);
376 if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) 343 if (dinfo->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB) {
377 fibh->sbh = fibh->ebh = NULL; 344 if (inode_bmap(dir, f_pos >> dir->i_sb->s_blocksize_bits, &epos,
378 else if (inode_bmap(dir, f_pos >> dir->i_sb->s_blocksize_bits, 345 &eloc, &elen, &offset) != (EXT_RECORDED_ALLOCATED >> 30)) {
379 &epos, &eloc, &elen, &offset) == 346 block = udf_get_lb_pblock(dir->i_sb,
380 (EXT_RECORDED_ALLOCATED >> 30)) { 347 dinfo->i_location, 0);
348 fibh->soffset = fibh->eoffset = sb->s_blocksize;
349 goto add;
350 }
381 block = udf_get_lb_pblock(dir->i_sb, eloc, offset); 351 block = udf_get_lb_pblock(dir->i_sb, eloc, offset);
382 if ((++offset << dir->i_sb->s_blocksize_bits) < elen) { 352 if ((++offset << dir->i_sb->s_blocksize_bits) < elen) {
383 if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT) 353 if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT)
@@ -389,17 +359,11 @@ static struct fileIdentDesc *udf_add_entry(struct inode *dir,
389 359
390 fibh->sbh = fibh->ebh = udf_tread(dir->i_sb, block); 360 fibh->sbh = fibh->ebh = udf_tread(dir->i_sb, block);
391 if (!fibh->sbh) { 361 if (!fibh->sbh) {
392 brelse(epos.bh);
393 *err = -EIO; 362 *err = -EIO;
394 return NULL; 363 goto out_err;
395 } 364 }
396 365
397 block = dinfo->i_location.logicalBlockNum; 366 block = dinfo->i_location.logicalBlockNum;
398 } else {
399 block = udf_get_lb_pblock(dir->i_sb, dinfo->i_location, 0);
400 fibh->sbh = fibh->ebh = NULL;
401 fibh->soffset = fibh->eoffset = sb->s_blocksize;
402 goto add;
403 } 367 }
404 368
405 while (f_pos < size) { 369 while (f_pos < size) {
@@ -407,41 +371,16 @@ static struct fileIdentDesc *udf_add_entry(struct inode *dir,
407 &elen, &offset); 371 &elen, &offset);
408 372
409 if (!fi) { 373 if (!fi) {
410 if (fibh->sbh != fibh->ebh)
411 brelse(fibh->ebh);
412 brelse(fibh->sbh);
413 brelse(epos.bh);
414 *err = -EIO; 374 *err = -EIO;
415 return NULL; 375 goto out_err;
416 } 376 }
417 377
418 liu = le16_to_cpu(cfi->lengthOfImpUse); 378 liu = le16_to_cpu(cfi->lengthOfImpUse);
419 lfi = cfi->lengthFileIdent; 379 lfi = cfi->lengthFileIdent;
420 380
421 if (fibh->sbh == fibh->ebh)
422 nameptr = fi->fileIdent + liu;
423 else {
424 int poffset; /* Unpaded ending offset */
425
426 poffset = fibh->soffset + sizeof(struct fileIdentDesc) +
427 liu + lfi;
428
429 if (poffset >= lfi)
430 nameptr = (char *)(fibh->ebh->b_data +
431 poffset - lfi);
432 else {
433 nameptr = fname;
434 memcpy(nameptr, fi->fileIdent + liu,
435 lfi - poffset);
436 memcpy(nameptr + lfi - poffset,
437 fibh->ebh->b_data, poffset);
438 }
439 }
440
441 if ((cfi->fileCharacteristics & FID_FILE_CHAR_DELETED) != 0) { 381 if ((cfi->fileCharacteristics & FID_FILE_CHAR_DELETED) != 0) {
442 if (((sizeof(struct fileIdentDesc) + 382 if (((sizeof(struct fileIdentDesc) +
443 liu + lfi + 3) & ~3) == nfidlen) { 383 liu + lfi + 3) & ~3) == nfidlen) {
444 brelse(epos.bh);
445 cfi->descTag.tagSerialNum = cpu_to_le16(1); 384 cfi->descTag.tagSerialNum = cpu_to_le16(1);
446 cfi->fileVersionNum = cpu_to_le16(1); 385 cfi->fileVersionNum = cpu_to_le16(1);
447 cfi->fileCharacteristics = 0; 386 cfi->fileCharacteristics = 0;
@@ -449,27 +388,13 @@ static struct fileIdentDesc *udf_add_entry(struct inode *dir,
449 cfi->lengthOfImpUse = cpu_to_le16(0); 388 cfi->lengthOfImpUse = cpu_to_le16(0);
450 if (!udf_write_fi(dir, cfi, fi, fibh, NULL, 389 if (!udf_write_fi(dir, cfi, fi, fibh, NULL,
451 name)) 390 name))
452 return fi; 391 goto out_ok;
453 else { 392 else {
454 *err = -EIO; 393 *err = -EIO;
455 return NULL; 394 goto out_err;
456 } 395 }
457 } 396 }
458 } 397 }
459
460 if (!lfi || !dentry)
461 continue;
462
463 flen = udf_get_filename(dir->i_sb, nameptr, fname, lfi);
464 if (flen && udf_match(flen, fname, dentry->d_name.len,
465 dentry->d_name.name)) {
466 if (fibh->sbh != fibh->ebh)
467 brelse(fibh->ebh);
468 brelse(fibh->sbh);
469 brelse(epos.bh);
470 *err = -EEXIST;
471 return NULL;
472 }
473 } 398 }
474 399
475add: 400add:
@@ -496,7 +421,7 @@ add:
496 fibh->sbh = fibh->ebh = 421 fibh->sbh = fibh->ebh =
497 udf_expand_dir_adinicb(dir, &block, err); 422 udf_expand_dir_adinicb(dir, &block, err);
498 if (!fibh->sbh) 423 if (!fibh->sbh)
499 return NULL; 424 goto out_err;
500 epos.block = dinfo->i_location; 425 epos.block = dinfo->i_location;
501 epos.offset = udf_file_entry_alloc_offset(dir); 426 epos.offset = udf_file_entry_alloc_offset(dir);
502 /* Load extent udf_expand_dir_adinicb() has created */ 427 /* Load extent udf_expand_dir_adinicb() has created */
@@ -537,11 +462,8 @@ add:
537 dir->i_sb->s_blocksize_bits); 462 dir->i_sb->s_blocksize_bits);
538 fibh->ebh = udf_bread(dir, 463 fibh->ebh = udf_bread(dir,
539 f_pos >> dir->i_sb->s_blocksize_bits, 1, err); 464 f_pos >> dir->i_sb->s_blocksize_bits, 1, err);
540 if (!fibh->ebh) { 465 if (!fibh->ebh)
541 brelse(epos.bh); 466 goto out_err;
542 brelse(fibh->sbh);
543 return NULL;
544 }
545 467
546 if (!fibh->soffset) { 468 if (!fibh->soffset) {
547 if (udf_next_aext(dir, &epos, &eloc, &elen, 1) == 469 if (udf_next_aext(dir, &epos, &eloc, &elen, 1) ==
@@ -572,20 +494,25 @@ add:
572 cfi->lengthFileIdent = namelen; 494 cfi->lengthFileIdent = namelen;
573 cfi->lengthOfImpUse = cpu_to_le16(0); 495 cfi->lengthOfImpUse = cpu_to_le16(0);
574 if (!udf_write_fi(dir, cfi, fi, fibh, NULL, name)) { 496 if (!udf_write_fi(dir, cfi, fi, fibh, NULL, name)) {
575 brelse(epos.bh);
576 dir->i_size += nfidlen; 497 dir->i_size += nfidlen;
577 if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) 498 if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB)
578 dinfo->i_lenAlloc += nfidlen; 499 dinfo->i_lenAlloc += nfidlen;
579 mark_inode_dirty(dir); 500 mark_inode_dirty(dir);
580 return fi; 501 goto out_ok;
581 } else { 502 } else {
582 brelse(epos.bh);
583 if (fibh->sbh != fibh->ebh)
584 brelse(fibh->ebh);
585 brelse(fibh->sbh);
586 *err = -EIO; 503 *err = -EIO;
587 return NULL; 504 goto out_err;
588 } 505 }
506
507out_err:
508 fi = NULL;
509 if (fibh->sbh != fibh->ebh)
510 brelse(fibh->ebh);
511 brelse(fibh->sbh);
512out_ok:
513 brelse(epos.bh);
514 kfree(name);
515 return fi;
589} 516}
590 517
591static int udf_delete_entry(struct inode *inode, struct fileIdentDesc *fi, 518static int udf_delete_entry(struct inode *inode, struct fileIdentDesc *fi,
@@ -940,7 +867,7 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry,
940 char *ea; 867 char *ea;
941 int err; 868 int err;
942 int block; 869 int block;
943 char name[UDF_NAME_LEN]; 870 char *name = NULL;
944 int namelen; 871 int namelen;
945 struct buffer_head *bh; 872 struct buffer_head *bh;
946 struct udf_inode_info *iinfo; 873 struct udf_inode_info *iinfo;
@@ -950,6 +877,12 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry,
950 if (!inode) 877 if (!inode)
951 goto out; 878 goto out;
952 879
880 name = kmalloc(UDF_NAME_LEN, GFP_NOFS);
881 if (!name) {
882 err = -ENOMEM;
883 goto out_no_entry;
884 }
885
953 iinfo = UDF_I(inode); 886 iinfo = UDF_I(inode);
954 inode->i_mode = S_IFLNK | S_IRWXUGO; 887 inode->i_mode = S_IFLNK | S_IRWXUGO;
955 inode->i_data.a_ops = &udf_symlink_aops; 888 inode->i_data.a_ops = &udf_symlink_aops;
@@ -1089,6 +1022,7 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry,
1089 err = 0; 1022 err = 0;
1090 1023
1091out: 1024out:
1025 kfree(name);
1092 unlock_kernel(); 1026 unlock_kernel();
1093 return err; 1027 return err;
1094 1028
diff --git a/fs/udf/partition.c b/fs/udf/partition.c
index fc533345ab89..63610f026ae1 100644
--- a/fs/udf/partition.c
+++ b/fs/udf/partition.c
@@ -24,7 +24,6 @@
24 24
25#include <linux/fs.h> 25#include <linux/fs.h>
26#include <linux/string.h> 26#include <linux/string.h>
27#include <linux/udf_fs.h>
28#include <linux/slab.h> 27#include <linux/slab.h>
29#include <linux/buffer_head.h> 28#include <linux/buffer_head.h>
30 29
@@ -55,11 +54,10 @@ uint32_t udf_get_pblock_virt15(struct super_block *sb, uint32_t block,
55 struct udf_sb_info *sbi = UDF_SB(sb); 54 struct udf_sb_info *sbi = UDF_SB(sb);
56 struct udf_part_map *map; 55 struct udf_part_map *map;
57 struct udf_virtual_data *vdata; 56 struct udf_virtual_data *vdata;
58 struct udf_inode_info *iinfo; 57 struct udf_inode_info *iinfo = UDF_I(sbi->s_vat_inode);
59 58
60 map = &sbi->s_partmaps[partition]; 59 map = &sbi->s_partmaps[partition];
61 vdata = &map->s_type_specific.s_virtual; 60 vdata = &map->s_type_specific.s_virtual;
62 index = (sb->s_blocksize - vdata->s_start_offset) / sizeof(uint32_t);
63 61
64 if (block > vdata->s_num_entries) { 62 if (block > vdata->s_num_entries) {
65 udf_debug("Trying to access block beyond end of VAT " 63 udf_debug("Trying to access block beyond end of VAT "
@@ -67,6 +65,12 @@ uint32_t udf_get_pblock_virt15(struct super_block *sb, uint32_t block,
67 return 0xFFFFFFFF; 65 return 0xFFFFFFFF;
68 } 66 }
69 67
68 if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) {
69 loc = le32_to_cpu(((__le32 *)(iinfo->i_ext.i_data +
70 vdata->s_start_offset))[block]);
71 goto translate;
72 }
73 index = (sb->s_blocksize - vdata->s_start_offset) / sizeof(uint32_t);
70 if (block >= index) { 74 if (block >= index) {
71 block -= index; 75 block -= index;
72 newblock = 1 + (block / (sb->s_blocksize / sizeof(uint32_t))); 76 newblock = 1 + (block / (sb->s_blocksize / sizeof(uint32_t)));
@@ -89,7 +93,7 @@ uint32_t udf_get_pblock_virt15(struct super_block *sb, uint32_t block,
89 93
90 brelse(bh); 94 brelse(bh);
91 95
92 iinfo = UDF_I(sbi->s_vat_inode); 96translate:
93 if (iinfo->i_location.partitionReferenceNum == partition) { 97 if (iinfo->i_location.partitionReferenceNum == partition) {
94 udf_debug("recursive call to udf_get_pblock!\n"); 98 udf_debug("recursive call to udf_get_pblock!\n");
95 return 0xFFFFFFFF; 99 return 0xFFFFFFFF;
@@ -263,3 +267,58 @@ int udf_relocate_blocks(struct super_block *sb, long old_block, long *new_block)
263 267
264 return 0; 268 return 0;
265} 269}
270
271static uint32_t udf_try_read_meta(struct inode *inode, uint32_t block,
272 uint16_t partition, uint32_t offset)
273{
274 struct super_block *sb = inode->i_sb;
275 struct udf_part_map *map;
276 kernel_lb_addr eloc;
277 uint32_t elen;
278 sector_t ext_offset;
279 struct extent_position epos = {};
280 uint32_t phyblock;
281
282 if (inode_bmap(inode, block, &epos, &eloc, &elen, &ext_offset) !=
283 (EXT_RECORDED_ALLOCATED >> 30))
284 phyblock = 0xFFFFFFFF;
285 else {
286 map = &UDF_SB(sb)->s_partmaps[partition];
287 /* map to sparable/physical partition desc */
288 phyblock = udf_get_pblock(sb, eloc.logicalBlockNum,
289 map->s_partition_num, ext_offset + offset);
290 }
291
292 brelse(epos.bh);
293 return phyblock;
294}
295
296uint32_t udf_get_pblock_meta25(struct super_block *sb, uint32_t block,
297 uint16_t partition, uint32_t offset)
298{
299 struct udf_sb_info *sbi = UDF_SB(sb);
300 struct udf_part_map *map;
301 struct udf_meta_data *mdata;
302 uint32_t retblk;
303 struct inode *inode;
304
305 udf_debug("READING from METADATA\n");
306
307 map = &sbi->s_partmaps[partition];
308 mdata = &map->s_type_specific.s_metadata;
309 inode = mdata->s_metadata_fe ? : mdata->s_mirror_fe;
310
311 /* We shouldn't mount such media... */
312 BUG_ON(!inode);
313 retblk = udf_try_read_meta(inode, block, partition, offset);
314 if (retblk == 0xFFFFFFFF) {
315 udf_warning(sb, __func__, "error reading from METADATA, "
316 "trying to read from MIRROR");
317 inode = mdata->s_mirror_fe;
318 if (!inode)
319 return 0xFFFFFFFF;
320 retblk = udf_try_read_meta(inode, block, partition, offset);
321 }
322
323 return retblk;
324}
diff --git a/fs/udf/super.c b/fs/udf/super.c
index f3ac4abfc946..b564fc140fe4 100644
--- a/fs/udf/super.c
+++ b/fs/udf/super.c
@@ -55,9 +55,10 @@
55#include <linux/errno.h> 55#include <linux/errno.h>
56#include <linux/mount.h> 56#include <linux/mount.h>
57#include <linux/seq_file.h> 57#include <linux/seq_file.h>
58#include <linux/bitmap.h>
59#include <linux/crc-itu-t.h>
58#include <asm/byteorder.h> 60#include <asm/byteorder.h>
59 61
60#include <linux/udf_fs.h>
61#include "udf_sb.h" 62#include "udf_sb.h"
62#include "udf_i.h" 63#include "udf_i.h"
63 64
@@ -84,22 +85,19 @@ static void udf_write_super(struct super_block *);
84static int udf_remount_fs(struct super_block *, int *, char *); 85static int udf_remount_fs(struct super_block *, int *, char *);
85static int udf_check_valid(struct super_block *, int, int); 86static int udf_check_valid(struct super_block *, int, int);
86static int udf_vrs(struct super_block *sb, int silent); 87static int udf_vrs(struct super_block *sb, int silent);
87static int udf_load_partition(struct super_block *, kernel_lb_addr *);
88static int udf_load_logicalvol(struct super_block *, struct buffer_head *,
89 kernel_lb_addr *);
90static void udf_load_logicalvolint(struct super_block *, kernel_extent_ad); 88static void udf_load_logicalvolint(struct super_block *, kernel_extent_ad);
91static void udf_find_anchor(struct super_block *); 89static void udf_find_anchor(struct super_block *);
92static int udf_find_fileset(struct super_block *, kernel_lb_addr *, 90static int udf_find_fileset(struct super_block *, kernel_lb_addr *,
93 kernel_lb_addr *); 91 kernel_lb_addr *);
94static void udf_load_pvoldesc(struct super_block *, struct buffer_head *);
95static void udf_load_fileset(struct super_block *, struct buffer_head *, 92static void udf_load_fileset(struct super_block *, struct buffer_head *,
96 kernel_lb_addr *); 93 kernel_lb_addr *);
97static int udf_load_partdesc(struct super_block *, struct buffer_head *);
98static void udf_open_lvid(struct super_block *); 94static void udf_open_lvid(struct super_block *);
99static void udf_close_lvid(struct super_block *); 95static void udf_close_lvid(struct super_block *);
100static unsigned int udf_count_free(struct super_block *); 96static unsigned int udf_count_free(struct super_block *);
101static int udf_statfs(struct dentry *, struct kstatfs *); 97static int udf_statfs(struct dentry *, struct kstatfs *);
102static int udf_show_options(struct seq_file *, struct vfsmount *); 98static int udf_show_options(struct seq_file *, struct vfsmount *);
99static void udf_error(struct super_block *sb, const char *function,
100 const char *fmt, ...);
103 101
104struct logicalVolIntegrityDescImpUse *udf_sb_lvidiu(struct udf_sb_info *sbi) 102struct logicalVolIntegrityDescImpUse *udf_sb_lvidiu(struct udf_sb_info *sbi)
105{ 103{
@@ -587,48 +585,10 @@ static int udf_remount_fs(struct super_block *sb, int *flags, char *options)
587 return 0; 585 return 0;
588} 586}
589 587
590/*
591 * udf_set_blocksize
592 *
593 * PURPOSE
594 * Set the block size to be used in all transfers.
595 *
596 * DESCRIPTION
597 * To allow room for a DMA transfer, it is best to guess big when unsure.
598 * This routine picks 2048 bytes as the blocksize when guessing. This
599 * should be adequate until devices with larger block sizes become common.
600 *
601 * Note that the Linux kernel can currently only deal with blocksizes of
602 * 512, 1024, 2048, 4096, and 8192 bytes.
603 *
604 * PRE-CONDITIONS
605 * sb Pointer to _locked_ superblock.
606 *
607 * POST-CONDITIONS
608 * sb->s_blocksize Blocksize.
609 * sb->s_blocksize_bits log2 of blocksize.
610 * <return> 0 Blocksize is valid.
611 * <return> 1 Blocksize is invalid.
612 *
613 * HISTORY
614 * July 1, 1997 - Andrew E. Mileski
615 * Written, tested, and released.
616 */
617static int udf_set_blocksize(struct super_block *sb, int bsize)
618{
619 if (!sb_min_blocksize(sb, bsize)) {
620 udf_debug("Bad block size (%d)\n", bsize);
621 printk(KERN_ERR "udf: bad block size (%d)\n", bsize);
622 return 0;
623 }
624
625 return sb->s_blocksize;
626}
627
628static int udf_vrs(struct super_block *sb, int silent) 588static int udf_vrs(struct super_block *sb, int silent)
629{ 589{
630 struct volStructDesc *vsd = NULL; 590 struct volStructDesc *vsd = NULL;
631 int sector = 32768; 591 loff_t sector = 32768;
632 int sectorsize; 592 int sectorsize;
633 struct buffer_head *bh = NULL; 593 struct buffer_head *bh = NULL;
634 int iso9660 = 0; 594 int iso9660 = 0;
@@ -649,7 +609,8 @@ static int udf_vrs(struct super_block *sb, int silent)
649 sector += (sbi->s_session << sb->s_blocksize_bits); 609 sector += (sbi->s_session << sb->s_blocksize_bits);
650 610
651 udf_debug("Starting at sector %u (%ld byte sectors)\n", 611 udf_debug("Starting at sector %u (%ld byte sectors)\n",
652 (sector >> sb->s_blocksize_bits), sb->s_blocksize); 612 (unsigned int)(sector >> sb->s_blocksize_bits),
613 sb->s_blocksize);
653 /* Process the sequence (if applicable) */ 614 /* Process the sequence (if applicable) */
654 for (; !nsr02 && !nsr03; sector += sectorsize) { 615 for (; !nsr02 && !nsr03; sector += sectorsize) {
655 /* Read a block */ 616 /* Read a block */
@@ -719,162 +680,140 @@ static int udf_vrs(struct super_block *sb, int silent)
719} 680}
720 681
721/* 682/*
722 * udf_find_anchor 683 * Check whether there is an anchor block in the given block
723 *
724 * PURPOSE
725 * Find an anchor volume descriptor.
726 *
727 * PRE-CONDITIONS
728 * sb Pointer to _locked_ superblock.
729 * lastblock Last block on media.
730 *
731 * POST-CONDITIONS
732 * <return> 1 if not found, 0 if ok
733 *
734 * HISTORY
735 * July 1, 1997 - Andrew E. Mileski
736 * Written, tested, and released.
737 */ 684 */
738static void udf_find_anchor(struct super_block *sb) 685static int udf_check_anchor_block(struct super_block *sb, sector_t block,
686 bool varconv)
739{ 687{
740 int lastblock;
741 struct buffer_head *bh = NULL; 688 struct buffer_head *bh = NULL;
689 tag *t;
742 uint16_t ident; 690 uint16_t ident;
743 uint32_t location; 691 uint32_t location;
744 int i;
745 struct udf_sb_info *sbi;
746 692
747 sbi = UDF_SB(sb); 693 if (varconv) {
748 lastblock = sbi->s_last_block; 694 if (udf_fixed_to_variable(block) >=
695 sb->s_bdev->bd_inode->i_size >> sb->s_blocksize_bits)
696 return 0;
697 bh = sb_bread(sb, udf_fixed_to_variable(block));
698 }
699 else
700 bh = sb_bread(sb, block);
749 701
750 if (lastblock) { 702 if (!bh)
751 int varlastblock = udf_variable_to_fixed(lastblock); 703 return 0;
752 int last[] = { lastblock, lastblock - 2,
753 lastblock - 150, lastblock - 152,
754 varlastblock, varlastblock - 2,
755 varlastblock - 150, varlastblock - 152 };
756
757 lastblock = 0;
758
759 /* Search for an anchor volume descriptor pointer */
760
761 /* according to spec, anchor is in either:
762 * block 256
763 * lastblock-256
764 * lastblock
765 * however, if the disc isn't closed, it could be 512 */
766
767 for (i = 0; !lastblock && i < ARRAY_SIZE(last); i++) {
768 ident = location = 0;
769 if (last[i] >= 0) {
770 bh = sb_bread(sb, last[i]);
771 if (bh) {
772 tag *t = (tag *)bh->b_data;
773 ident = le16_to_cpu(t->tagIdent);
774 location = le32_to_cpu(t->tagLocation);
775 brelse(bh);
776 }
777 }
778 704
779 if (ident == TAG_IDENT_AVDP) { 705 t = (tag *)bh->b_data;
780 if (location == last[i] - sbi->s_session) { 706 ident = le16_to_cpu(t->tagIdent);
781 lastblock = last[i] - sbi->s_session; 707 location = le32_to_cpu(t->tagLocation);
782 sbi->s_anchor[0] = lastblock; 708 brelse(bh);
783 sbi->s_anchor[1] = lastblock - 256; 709 if (ident != TAG_IDENT_AVDP)
784 } else if (location == 710 return 0;
785 udf_variable_to_fixed(last[i]) - 711 return location == block;
786 sbi->s_session) { 712}
787 UDF_SET_FLAG(sb, UDF_FLAG_VARCONV);
788 lastblock =
789 udf_variable_to_fixed(last[i]) -
790 sbi->s_session;
791 sbi->s_anchor[0] = lastblock;
792 sbi->s_anchor[1] = lastblock - 256 -
793 sbi->s_session;
794 } else {
795 udf_debug("Anchor found at block %d, "
796 "location mismatch %d.\n",
797 last[i], location);
798 }
799 } else if (ident == TAG_IDENT_FE ||
800 ident == TAG_IDENT_EFE) {
801 lastblock = last[i];
802 sbi->s_anchor[3] = 512;
803 } else {
804 ident = location = 0;
805 if (last[i] >= 256) {
806 bh = sb_bread(sb, last[i] - 256);
807 if (bh) {
808 tag *t = (tag *)bh->b_data;
809 ident = le16_to_cpu(
810 t->tagIdent);
811 location = le32_to_cpu(
812 t->tagLocation);
813 brelse(bh);
814 }
815 }
816 713
817 if (ident == TAG_IDENT_AVDP && 714/* Search for an anchor volume descriptor pointer */
818 location == last[i] - 256 - 715static sector_t udf_scan_anchors(struct super_block *sb, bool varconv,
819 sbi->s_session) { 716 sector_t lastblock)
820 lastblock = last[i]; 717{
821 sbi->s_anchor[1] = last[i] - 256; 718 sector_t last[6];
822 } else { 719 int i;
823 ident = location = 0; 720 struct udf_sb_info *sbi = UDF_SB(sb);
824 if (last[i] >= 312 + sbi->s_session) {
825 bh = sb_bread(sb,
826 last[i] - 312 -
827 sbi->s_session);
828 if (bh) {
829 tag *t = (tag *)
830 bh->b_data;
831 ident = le16_to_cpu(
832 t->tagIdent);
833 location = le32_to_cpu(
834 t->tagLocation);
835 brelse(bh);
836 }
837 }
838 721
839 if (ident == TAG_IDENT_AVDP && 722 last[0] = lastblock;
840 location == udf_variable_to_fixed(last[i]) - 256) { 723 last[1] = last[0] - 1;
841 UDF_SET_FLAG(sb, 724 last[2] = last[0] + 1;
842 UDF_FLAG_VARCONV); 725 last[3] = last[0] - 2;
843 lastblock = udf_variable_to_fixed(last[i]); 726 last[4] = last[0] - 150;
844 sbi->s_anchor[1] = lastblock - 256; 727 last[5] = last[0] - 152;
845 } 728
846 } 729 /* according to spec, anchor is in either:
847 } 730 * block 256
731 * lastblock-256
732 * lastblock
733 * however, if the disc isn't closed, it could be 512 */
734
735 for (i = 0; i < ARRAY_SIZE(last); i++) {
736 if (last[i] < 0)
737 continue;
738 if (last[i] >= sb->s_bdev->bd_inode->i_size >>
739 sb->s_blocksize_bits)
740 continue;
741
742 if (udf_check_anchor_block(sb, last[i], varconv)) {
743 sbi->s_anchor[0] = last[i];
744 sbi->s_anchor[1] = last[i] - 256;
745 return last[i];
848 } 746 }
849 }
850 747
851 if (!lastblock) { 748 if (last[i] < 256)
852 /* We haven't found the lastblock. check 312 */ 749 continue;
853 bh = sb_bread(sb, 312 + sbi->s_session);
854 if (bh) {
855 tag *t = (tag *)bh->b_data;
856 ident = le16_to_cpu(t->tagIdent);
857 location = le32_to_cpu(t->tagLocation);
858 brelse(bh);
859 750
860 if (ident == TAG_IDENT_AVDP && location == 256) 751 if (udf_check_anchor_block(sb, last[i] - 256, varconv)) {
861 UDF_SET_FLAG(sb, UDF_FLAG_VARCONV); 752 sbi->s_anchor[1] = last[i] - 256;
753 return last[i];
862 } 754 }
863 } 755 }
864 756
757 if (udf_check_anchor_block(sb, sbi->s_session + 256, varconv)) {
758 sbi->s_anchor[0] = sbi->s_session + 256;
759 return last[0];
760 }
761 if (udf_check_anchor_block(sb, sbi->s_session + 512, varconv)) {
762 sbi->s_anchor[0] = sbi->s_session + 512;
763 return last[0];
764 }
765 return 0;
766}
767
768/*
769 * Find an anchor volume descriptor. The function expects sbi->s_lastblock to
770 * be the last block on the media.
771 *
772 * Return 1 if not found, 0 if ok
773 *
774 */
775static void udf_find_anchor(struct super_block *sb)
776{
777 sector_t lastblock;
778 struct buffer_head *bh = NULL;
779 uint16_t ident;
780 int i;
781 struct udf_sb_info *sbi = UDF_SB(sb);
782
783 lastblock = udf_scan_anchors(sb, 0, sbi->s_last_block);
784 if (lastblock)
785 goto check_anchor;
786
787 /* No anchor found? Try VARCONV conversion of block numbers */
788 /* Firstly, we try to not convert number of the last block */
789 lastblock = udf_scan_anchors(sb, 1,
790 udf_variable_to_fixed(sbi->s_last_block));
791 if (lastblock) {
792 UDF_SET_FLAG(sb, UDF_FLAG_VARCONV);
793 goto check_anchor;
794 }
795
796 /* Secondly, we try with converted number of the last block */
797 lastblock = udf_scan_anchors(sb, 1, sbi->s_last_block);
798 if (lastblock)
799 UDF_SET_FLAG(sb, UDF_FLAG_VARCONV);
800
801check_anchor:
802 /*
803 * Check located anchors and the anchor block supplied via
804 * mount options
805 */
865 for (i = 0; i < ARRAY_SIZE(sbi->s_anchor); i++) { 806 for (i = 0; i < ARRAY_SIZE(sbi->s_anchor); i++) {
866 if (sbi->s_anchor[i]) { 807 if (!sbi->s_anchor[i])
867 bh = udf_read_tagged(sb, sbi->s_anchor[i], 808 continue;
868 sbi->s_anchor[i], &ident); 809 bh = udf_read_tagged(sb, sbi->s_anchor[i],
869 if (!bh) 810 sbi->s_anchor[i], &ident);
811 if (!bh)
812 sbi->s_anchor[i] = 0;
813 else {
814 brelse(bh);
815 if (ident != TAG_IDENT_AVDP)
870 sbi->s_anchor[i] = 0; 816 sbi->s_anchor[i] = 0;
871 else {
872 brelse(bh);
873 if ((ident != TAG_IDENT_AVDP) &&
874 (i || (ident != TAG_IDENT_FE &&
875 ident != TAG_IDENT_EFE)))
876 sbi->s_anchor[i] = 0;
877 }
878 } 817 }
879 } 818 }
880 819
@@ -971,27 +910,30 @@ static int udf_find_fileset(struct super_block *sb,
971 return 1; 910 return 1;
972} 911}
973 912
974static void udf_load_pvoldesc(struct super_block *sb, struct buffer_head *bh) 913static int udf_load_pvoldesc(struct super_block *sb, sector_t block)
975{ 914{
976 struct primaryVolDesc *pvoldesc; 915 struct primaryVolDesc *pvoldesc;
977 time_t recording;
978 long recording_usec;
979 struct ustr instr; 916 struct ustr instr;
980 struct ustr outstr; 917 struct ustr outstr;
918 struct buffer_head *bh;
919 uint16_t ident;
920
921 bh = udf_read_tagged(sb, block, block, &ident);
922 if (!bh)
923 return 1;
924 BUG_ON(ident != TAG_IDENT_PVD);
981 925
982 pvoldesc = (struct primaryVolDesc *)bh->b_data; 926 pvoldesc = (struct primaryVolDesc *)bh->b_data;
983 927
984 if (udf_stamp_to_time(&recording, &recording_usec, 928 if (udf_disk_stamp_to_time(&UDF_SB(sb)->s_record_time,
985 lets_to_cpu(pvoldesc->recordingDateAndTime))) { 929 pvoldesc->recordingDateAndTime)) {
986 kernel_timestamp ts; 930#ifdef UDFFS_DEBUG
987 ts = lets_to_cpu(pvoldesc->recordingDateAndTime); 931 timestamp *ts = &pvoldesc->recordingDateAndTime;
988 udf_debug("recording time %ld/%ld, %04u/%02u/%02u" 932 udf_debug("recording time %04u/%02u/%02u"
989 " %02u:%02u (%x)\n", 933 " %02u:%02u (%x)\n",
990 recording, recording_usec, 934 le16_to_cpu(ts->year), ts->month, ts->day, ts->hour,
991 ts.year, ts.month, ts.day, ts.hour, 935 ts->minute, le16_to_cpu(ts->typeAndTimezone));
992 ts.minute, ts.typeAndTimezone); 936#endif
993 UDF_SB(sb)->s_record_time.tv_sec = recording;
994 UDF_SB(sb)->s_record_time.tv_nsec = recording_usec * 1000;
995 } 937 }
996 938
997 if (!udf_build_ustr(&instr, pvoldesc->volIdent, 32)) 939 if (!udf_build_ustr(&instr, pvoldesc->volIdent, 32))
@@ -1005,6 +947,104 @@ static void udf_load_pvoldesc(struct super_block *sb, struct buffer_head *bh)
1005 if (!udf_build_ustr(&instr, pvoldesc->volSetIdent, 128)) 947 if (!udf_build_ustr(&instr, pvoldesc->volSetIdent, 128))
1006 if (udf_CS0toUTF8(&outstr, &instr)) 948 if (udf_CS0toUTF8(&outstr, &instr))
1007 udf_debug("volSetIdent[] = '%s'\n", outstr.u_name); 949 udf_debug("volSetIdent[] = '%s'\n", outstr.u_name);
950
951 brelse(bh);
952 return 0;
953}
954
955static int udf_load_metadata_files(struct super_block *sb, int partition)
956{
957 struct udf_sb_info *sbi = UDF_SB(sb);
958 struct udf_part_map *map;
959 struct udf_meta_data *mdata;
960 kernel_lb_addr addr;
961 int fe_error = 0;
962
963 map = &sbi->s_partmaps[partition];
964 mdata = &map->s_type_specific.s_metadata;
965
966 /* metadata address */
967 addr.logicalBlockNum = mdata->s_meta_file_loc;
968 addr.partitionReferenceNum = map->s_partition_num;
969
970 udf_debug("Metadata file location: block = %d part = %d\n",
971 addr.logicalBlockNum, addr.partitionReferenceNum);
972
973 mdata->s_metadata_fe = udf_iget(sb, addr);
974
975 if (mdata->s_metadata_fe == NULL) {
976 udf_warning(sb, __func__, "metadata inode efe not found, "
977 "will try mirror inode.");
978 fe_error = 1;
979 } else if (UDF_I(mdata->s_metadata_fe)->i_alloc_type !=
980 ICBTAG_FLAG_AD_SHORT) {
981 udf_warning(sb, __func__, "metadata inode efe does not have "
982 "short allocation descriptors!");
983 fe_error = 1;
984 iput(mdata->s_metadata_fe);
985 mdata->s_metadata_fe = NULL;
986 }
987
988 /* mirror file entry */
989 addr.logicalBlockNum = mdata->s_mirror_file_loc;
990 addr.partitionReferenceNum = map->s_partition_num;
991
992 udf_debug("Mirror metadata file location: block = %d part = %d\n",
993 addr.logicalBlockNum, addr.partitionReferenceNum);
994
995 mdata->s_mirror_fe = udf_iget(sb, addr);
996
997 if (mdata->s_mirror_fe == NULL) {
998 if (fe_error) {
999 udf_error(sb, __func__, "mirror inode efe not found "
1000 "and metadata inode is missing too, exiting...");
1001 goto error_exit;
1002 } else
1003 udf_warning(sb, __func__, "mirror inode efe not found,"
1004 " but metadata inode is OK");
1005 } else if (UDF_I(mdata->s_mirror_fe)->i_alloc_type !=
1006 ICBTAG_FLAG_AD_SHORT) {
1007 udf_warning(sb, __func__, "mirror inode efe does not have "
1008 "short allocation descriptors!");
1009 iput(mdata->s_mirror_fe);
1010 mdata->s_mirror_fe = NULL;
1011 if (fe_error)
1012 goto error_exit;
1013 }
1014
1015 /*
1016 * bitmap file entry
1017 * Note:
1018 * Load only if bitmap file location differs from 0xFFFFFFFF (DCN-5102)
1019 */
1020 if (mdata->s_bitmap_file_loc != 0xFFFFFFFF) {
1021 addr.logicalBlockNum = mdata->s_bitmap_file_loc;
1022 addr.partitionReferenceNum = map->s_partition_num;
1023
1024 udf_debug("Bitmap file location: block = %d part = %d\n",
1025 addr.logicalBlockNum, addr.partitionReferenceNum);
1026
1027 mdata->s_bitmap_fe = udf_iget(sb, addr);
1028
1029 if (mdata->s_bitmap_fe == NULL) {
1030 if (sb->s_flags & MS_RDONLY)
1031 udf_warning(sb, __func__, "bitmap inode efe "
1032 "not found but it's ok since the disc"
1033 " is mounted read-only");
1034 else {
1035 udf_error(sb, __func__, "bitmap inode efe not "
1036 "found and attempted read-write mount");
1037 goto error_exit;
1038 }
1039 }
1040 }
1041
1042 udf_debug("udf_load_metadata_files Ok\n");
1043
1044 return 0;
1045
1046error_exit:
1047 return 1;
1008} 1048}
1009 1049
1010static void udf_load_fileset(struct super_block *sb, struct buffer_head *bh, 1050static void udf_load_fileset(struct super_block *sb, struct buffer_head *bh,
@@ -1025,10 +1065,9 @@ static void udf_load_fileset(struct super_block *sb, struct buffer_head *bh,
1025int udf_compute_nr_groups(struct super_block *sb, u32 partition) 1065int udf_compute_nr_groups(struct super_block *sb, u32 partition)
1026{ 1066{
1027 struct udf_part_map *map = &UDF_SB(sb)->s_partmaps[partition]; 1067 struct udf_part_map *map = &UDF_SB(sb)->s_partmaps[partition];
1028 return (map->s_partition_len + 1068 return DIV_ROUND_UP(map->s_partition_len +
1029 (sizeof(struct spaceBitmapDesc) << 3) + 1069 (sizeof(struct spaceBitmapDesc) << 3),
1030 (sb->s_blocksize * 8) - 1) / 1070 sb->s_blocksize * 8);
1031 (sb->s_blocksize * 8);
1032} 1071}
1033 1072
1034static struct udf_bitmap *udf_sb_alloc_bitmap(struct super_block *sb, u32 index) 1073static struct udf_bitmap *udf_sb_alloc_bitmap(struct super_block *sb, u32 index)
@@ -1059,134 +1098,241 @@ static struct udf_bitmap *udf_sb_alloc_bitmap(struct super_block *sb, u32 index)
1059 return bitmap; 1098 return bitmap;
1060} 1099}
1061 1100
1062static int udf_load_partdesc(struct super_block *sb, struct buffer_head *bh) 1101static int udf_fill_partdesc_info(struct super_block *sb,
1102 struct partitionDesc *p, int p_index)
1103{
1104 struct udf_part_map *map;
1105 struct udf_sb_info *sbi = UDF_SB(sb);
1106 struct partitionHeaderDesc *phd;
1107
1108 map = &sbi->s_partmaps[p_index];
1109
1110 map->s_partition_len = le32_to_cpu(p->partitionLength); /* blocks */
1111 map->s_partition_root = le32_to_cpu(p->partitionStartingLocation);
1112
1113 if (p->accessType == cpu_to_le32(PD_ACCESS_TYPE_READ_ONLY))
1114 map->s_partition_flags |= UDF_PART_FLAG_READ_ONLY;
1115 if (p->accessType == cpu_to_le32(PD_ACCESS_TYPE_WRITE_ONCE))
1116 map->s_partition_flags |= UDF_PART_FLAG_WRITE_ONCE;
1117 if (p->accessType == cpu_to_le32(PD_ACCESS_TYPE_REWRITABLE))
1118 map->s_partition_flags |= UDF_PART_FLAG_REWRITABLE;
1119 if (p->accessType == cpu_to_le32(PD_ACCESS_TYPE_OVERWRITABLE))
1120 map->s_partition_flags |= UDF_PART_FLAG_OVERWRITABLE;
1121
1122 udf_debug("Partition (%d type %x) starts at physical %d, "
1123 "block length %d\n", p_index,
1124 map->s_partition_type, map->s_partition_root,
1125 map->s_partition_len);
1126
1127 if (strcmp(p->partitionContents.ident, PD_PARTITION_CONTENTS_NSR02) &&
1128 strcmp(p->partitionContents.ident, PD_PARTITION_CONTENTS_NSR03))
1129 return 0;
1130
1131 phd = (struct partitionHeaderDesc *)p->partitionContentsUse;
1132 if (phd->unallocSpaceTable.extLength) {
1133 kernel_lb_addr loc = {
1134 .logicalBlockNum = le32_to_cpu(
1135 phd->unallocSpaceTable.extPosition),
1136 .partitionReferenceNum = p_index,
1137 };
1138
1139 map->s_uspace.s_table = udf_iget(sb, loc);
1140 if (!map->s_uspace.s_table) {
1141 udf_debug("cannot load unallocSpaceTable (part %d)\n",
1142 p_index);
1143 return 1;
1144 }
1145 map->s_partition_flags |= UDF_PART_FLAG_UNALLOC_TABLE;
1146 udf_debug("unallocSpaceTable (part %d) @ %ld\n",
1147 p_index, map->s_uspace.s_table->i_ino);
1148 }
1149
1150 if (phd->unallocSpaceBitmap.extLength) {
1151 struct udf_bitmap *bitmap = udf_sb_alloc_bitmap(sb, p_index);
1152 if (!bitmap)
1153 return 1;
1154 map->s_uspace.s_bitmap = bitmap;
1155 bitmap->s_extLength = le32_to_cpu(
1156 phd->unallocSpaceBitmap.extLength);
1157 bitmap->s_extPosition = le32_to_cpu(
1158 phd->unallocSpaceBitmap.extPosition);
1159 map->s_partition_flags |= UDF_PART_FLAG_UNALLOC_BITMAP;
1160 udf_debug("unallocSpaceBitmap (part %d) @ %d\n", p_index,
1161 bitmap->s_extPosition);
1162 }
1163
1164 if (phd->partitionIntegrityTable.extLength)
1165 udf_debug("partitionIntegrityTable (part %d)\n", p_index);
1166
1167 if (phd->freedSpaceTable.extLength) {
1168 kernel_lb_addr loc = {
1169 .logicalBlockNum = le32_to_cpu(
1170 phd->freedSpaceTable.extPosition),
1171 .partitionReferenceNum = p_index,
1172 };
1173
1174 map->s_fspace.s_table = udf_iget(sb, loc);
1175 if (!map->s_fspace.s_table) {
1176 udf_debug("cannot load freedSpaceTable (part %d)\n",
1177 p_index);
1178 return 1;
1179 }
1180
1181 map->s_partition_flags |= UDF_PART_FLAG_FREED_TABLE;
1182 udf_debug("freedSpaceTable (part %d) @ %ld\n",
1183 p_index, map->s_fspace.s_table->i_ino);
1184 }
1185
1186 if (phd->freedSpaceBitmap.extLength) {
1187 struct udf_bitmap *bitmap = udf_sb_alloc_bitmap(sb, p_index);
1188 if (!bitmap)
1189 return 1;
1190 map->s_fspace.s_bitmap = bitmap;
1191 bitmap->s_extLength = le32_to_cpu(
1192 phd->freedSpaceBitmap.extLength);
1193 bitmap->s_extPosition = le32_to_cpu(
1194 phd->freedSpaceBitmap.extPosition);
1195 map->s_partition_flags |= UDF_PART_FLAG_FREED_BITMAP;
1196 udf_debug("freedSpaceBitmap (part %d) @ %d\n", p_index,
1197 bitmap->s_extPosition);
1198 }
1199 return 0;
1200}
1201
1202static int udf_load_vat(struct super_block *sb, int p_index, int type1_index)
1203{
1204 struct udf_sb_info *sbi = UDF_SB(sb);
1205 struct udf_part_map *map = &sbi->s_partmaps[p_index];
1206 kernel_lb_addr ino;
1207 struct buffer_head *bh = NULL;
1208 struct udf_inode_info *vati;
1209 uint32_t pos;
1210 struct virtualAllocationTable20 *vat20;
1211
1212 /* VAT file entry is in the last recorded block */
1213 ino.partitionReferenceNum = type1_index;
1214 ino.logicalBlockNum = sbi->s_last_block - map->s_partition_root;
1215 sbi->s_vat_inode = udf_iget(sb, ino);
1216 if (!sbi->s_vat_inode)
1217 return 1;
1218
1219 if (map->s_partition_type == UDF_VIRTUAL_MAP15) {
1220 map->s_type_specific.s_virtual.s_start_offset = 0;
1221 map->s_type_specific.s_virtual.s_num_entries =
1222 (sbi->s_vat_inode->i_size - 36) >> 2;
1223 } else if (map->s_partition_type == UDF_VIRTUAL_MAP20) {
1224 vati = UDF_I(sbi->s_vat_inode);
1225 if (vati->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB) {
1226 pos = udf_block_map(sbi->s_vat_inode, 0);
1227 bh = sb_bread(sb, pos);
1228 if (!bh)
1229 return 1;
1230 vat20 = (struct virtualAllocationTable20 *)bh->b_data;
1231 } else {
1232 vat20 = (struct virtualAllocationTable20 *)
1233 vati->i_ext.i_data;
1234 }
1235
1236 map->s_type_specific.s_virtual.s_start_offset =
1237 le16_to_cpu(vat20->lengthHeader);
1238 map->s_type_specific.s_virtual.s_num_entries =
1239 (sbi->s_vat_inode->i_size -
1240 map->s_type_specific.s_virtual.
1241 s_start_offset) >> 2;
1242 brelse(bh);
1243 }
1244 return 0;
1245}
1246
1247static int udf_load_partdesc(struct super_block *sb, sector_t block)
1063{ 1248{
1249 struct buffer_head *bh;
1064 struct partitionDesc *p; 1250 struct partitionDesc *p;
1065 int i;
1066 struct udf_part_map *map; 1251 struct udf_part_map *map;
1067 struct udf_sb_info *sbi; 1252 struct udf_sb_info *sbi = UDF_SB(sb);
1253 int i, type1_idx;
1254 uint16_t partitionNumber;
1255 uint16_t ident;
1256 int ret = 0;
1257
1258 bh = udf_read_tagged(sb, block, block, &ident);
1259 if (!bh)
1260 return 1;
1261 if (ident != TAG_IDENT_PD)
1262 goto out_bh;
1068 1263
1069 p = (struct partitionDesc *)bh->b_data; 1264 p = (struct partitionDesc *)bh->b_data;
1070 sbi = UDF_SB(sb); 1265 partitionNumber = le16_to_cpu(p->partitionNumber);
1071 1266
1267 /* First scan for TYPE1, SPARABLE and METADATA partitions */
1072 for (i = 0; i < sbi->s_partitions; i++) { 1268 for (i = 0; i < sbi->s_partitions; i++) {
1073 map = &sbi->s_partmaps[i]; 1269 map = &sbi->s_partmaps[i];
1074 udf_debug("Searching map: (%d == %d)\n", 1270 udf_debug("Searching map: (%d == %d)\n",
1075 map->s_partition_num, 1271 map->s_partition_num, partitionNumber);
1076 le16_to_cpu(p->partitionNumber)); 1272 if (map->s_partition_num == partitionNumber &&
1077 if (map->s_partition_num == 1273 (map->s_partition_type == UDF_TYPE1_MAP15 ||
1078 le16_to_cpu(p->partitionNumber)) { 1274 map->s_partition_type == UDF_SPARABLE_MAP15))
1079 map->s_partition_len =
1080 le32_to_cpu(p->partitionLength); /* blocks */
1081 map->s_partition_root =
1082 le32_to_cpu(p->partitionStartingLocation);
1083 if (p->accessType ==
1084 cpu_to_le32(PD_ACCESS_TYPE_READ_ONLY))
1085 map->s_partition_flags |=
1086 UDF_PART_FLAG_READ_ONLY;
1087 if (p->accessType ==
1088 cpu_to_le32(PD_ACCESS_TYPE_WRITE_ONCE))
1089 map->s_partition_flags |=
1090 UDF_PART_FLAG_WRITE_ONCE;
1091 if (p->accessType ==
1092 cpu_to_le32(PD_ACCESS_TYPE_REWRITABLE))
1093 map->s_partition_flags |=
1094 UDF_PART_FLAG_REWRITABLE;
1095 if (p->accessType ==
1096 cpu_to_le32(PD_ACCESS_TYPE_OVERWRITABLE))
1097 map->s_partition_flags |=
1098 UDF_PART_FLAG_OVERWRITABLE;
1099
1100 if (!strcmp(p->partitionContents.ident,
1101 PD_PARTITION_CONTENTS_NSR02) ||
1102 !strcmp(p->partitionContents.ident,
1103 PD_PARTITION_CONTENTS_NSR03)) {
1104 struct partitionHeaderDesc *phd;
1105
1106 phd = (struct partitionHeaderDesc *)
1107 (p->partitionContentsUse);
1108 if (phd->unallocSpaceTable.extLength) {
1109 kernel_lb_addr loc = {
1110 .logicalBlockNum = le32_to_cpu(phd->unallocSpaceTable.extPosition),
1111 .partitionReferenceNum = i,
1112 };
1113
1114 map->s_uspace.s_table =
1115 udf_iget(sb, loc);
1116 if (!map->s_uspace.s_table) {
1117 udf_debug("cannot load unallocSpaceTable (part %d)\n", i);
1118 return 1;
1119 }
1120 map->s_partition_flags |=
1121 UDF_PART_FLAG_UNALLOC_TABLE;
1122 udf_debug("unallocSpaceTable (part %d) @ %ld\n",
1123 i, map->s_uspace.s_table->i_ino);
1124 }
1125 if (phd->unallocSpaceBitmap.extLength) {
1126 struct udf_bitmap *bitmap =
1127 udf_sb_alloc_bitmap(sb, i);
1128 map->s_uspace.s_bitmap = bitmap;
1129 if (bitmap != NULL) {
1130 bitmap->s_extLength =
1131 le32_to_cpu(phd->unallocSpaceBitmap.extLength);
1132 bitmap->s_extPosition =
1133 le32_to_cpu(phd->unallocSpaceBitmap.extPosition);
1134 map->s_partition_flags |= UDF_PART_FLAG_UNALLOC_BITMAP;
1135 udf_debug("unallocSpaceBitmap (part %d) @ %d\n",
1136 i, bitmap->s_extPosition);
1137 }
1138 }
1139 if (phd->partitionIntegrityTable.extLength)
1140 udf_debug("partitionIntegrityTable (part %d)\n", i);
1141 if (phd->freedSpaceTable.extLength) {
1142 kernel_lb_addr loc = {
1143 .logicalBlockNum = le32_to_cpu(phd->freedSpaceTable.extPosition),
1144 .partitionReferenceNum = i,
1145 };
1146
1147 map->s_fspace.s_table =
1148 udf_iget(sb, loc);
1149 if (!map->s_fspace.s_table) {
1150 udf_debug("cannot load freedSpaceTable (part %d)\n", i);
1151 return 1;
1152 }
1153 map->s_partition_flags |=
1154 UDF_PART_FLAG_FREED_TABLE;
1155 udf_debug("freedSpaceTable (part %d) @ %ld\n",
1156 i, map->s_fspace.s_table->i_ino);
1157 }
1158 if (phd->freedSpaceBitmap.extLength) {
1159 struct udf_bitmap *bitmap =
1160 udf_sb_alloc_bitmap(sb, i);
1161 map->s_fspace.s_bitmap = bitmap;
1162 if (bitmap != NULL) {
1163 bitmap->s_extLength =
1164 le32_to_cpu(phd->freedSpaceBitmap.extLength);
1165 bitmap->s_extPosition =
1166 le32_to_cpu(phd->freedSpaceBitmap.extPosition);
1167 map->s_partition_flags |= UDF_PART_FLAG_FREED_BITMAP;
1168 udf_debug("freedSpaceBitmap (part %d) @ %d\n",
1169 i, bitmap->s_extPosition);
1170 }
1171 }
1172 }
1173 break; 1275 break;
1174 }
1175 } 1276 }
1176 if (i == sbi->s_partitions) 1277
1278 if (i >= sbi->s_partitions) {
1177 udf_debug("Partition (%d) not found in partition map\n", 1279 udf_debug("Partition (%d) not found in partition map\n",
1178 le16_to_cpu(p->partitionNumber)); 1280 partitionNumber);
1179 else 1281 goto out_bh;
1180 udf_debug("Partition (%d:%d type %x) starts at physical %d, " 1282 }
1181 "block length %d\n", 1283
1182 le16_to_cpu(p->partitionNumber), i, 1284 ret = udf_fill_partdesc_info(sb, p, i);
1183 map->s_partition_type, 1285
1184 map->s_partition_root, 1286 /*
1185 map->s_partition_len); 1287 * Now rescan for VIRTUAL or METADATA partitions when SPARABLE and
1186 return 0; 1288 * PHYSICAL partitions are already set up
1289 */
1290 type1_idx = i;
1291 for (i = 0; i < sbi->s_partitions; i++) {
1292 map = &sbi->s_partmaps[i];
1293
1294 if (map->s_partition_num == partitionNumber &&
1295 (map->s_partition_type == UDF_VIRTUAL_MAP15 ||
1296 map->s_partition_type == UDF_VIRTUAL_MAP20 ||
1297 map->s_partition_type == UDF_METADATA_MAP25))
1298 break;
1299 }
1300
1301 if (i >= sbi->s_partitions)
1302 goto out_bh;
1303
1304 ret = udf_fill_partdesc_info(sb, p, i);
1305 if (ret)
1306 goto out_bh;
1307
1308 if (map->s_partition_type == UDF_METADATA_MAP25) {
1309 ret = udf_load_metadata_files(sb, i);
1310 if (ret) {
1311 printk(KERN_ERR "UDF-fs: error loading MetaData "
1312 "partition map %d\n", i);
1313 goto out_bh;
1314 }
1315 } else {
1316 ret = udf_load_vat(sb, i, type1_idx);
1317 if (ret)
1318 goto out_bh;
1319 /*
1320 * Mark filesystem read-only if we have a partition with
1321 * virtual map since we don't handle writing to it (we
1322 * overwrite blocks instead of relocating them).
1323 */
1324 sb->s_flags |= MS_RDONLY;
1325 printk(KERN_NOTICE "UDF-fs: Filesystem marked read-only "
1326 "because writing to pseudooverwrite partition is "
1327 "not implemented.\n");
1328 }
1329out_bh:
1330 /* In case loading failed, we handle cleanup in udf_fill_super */
1331 brelse(bh);
1332 return ret;
1187} 1333}
1188 1334
1189static int udf_load_logicalvol(struct super_block *sb, struct buffer_head *bh, 1335static int udf_load_logicalvol(struct super_block *sb, sector_t block,
1190 kernel_lb_addr *fileset) 1336 kernel_lb_addr *fileset)
1191{ 1337{
1192 struct logicalVolDesc *lvd; 1338 struct logicalVolDesc *lvd;
@@ -1194,12 +1340,21 @@ static int udf_load_logicalvol(struct super_block *sb, struct buffer_head *bh,
1194 uint8_t type; 1340 uint8_t type;
1195 struct udf_sb_info *sbi = UDF_SB(sb); 1341 struct udf_sb_info *sbi = UDF_SB(sb);
1196 struct genericPartitionMap *gpm; 1342 struct genericPartitionMap *gpm;
1343 uint16_t ident;
1344 struct buffer_head *bh;
1345 int ret = 0;
1197 1346
1347 bh = udf_read_tagged(sb, block, block, &ident);
1348 if (!bh)
1349 return 1;
1350 BUG_ON(ident != TAG_IDENT_LVD);
1198 lvd = (struct logicalVolDesc *)bh->b_data; 1351 lvd = (struct logicalVolDesc *)bh->b_data;
1199 1352
1200 i = udf_sb_alloc_partition_maps(sb, le32_to_cpu(lvd->numPartitionMaps)); 1353 i = udf_sb_alloc_partition_maps(sb, le32_to_cpu(lvd->numPartitionMaps));
1201 if (i != 0) 1354 if (i != 0) {
1202 return i; 1355 ret = i;
1356 goto out_bh;
1357 }
1203 1358
1204 for (i = 0, offset = 0; 1359 for (i = 0, offset = 0;
1205 i < sbi->s_partitions && offset < le32_to_cpu(lvd->mapTableLength); 1360 i < sbi->s_partitions && offset < le32_to_cpu(lvd->mapTableLength);
@@ -1223,12 +1378,12 @@ static int udf_load_logicalvol(struct super_block *sb, struct buffer_head *bh,
1223 u16 suf = 1378 u16 suf =
1224 le16_to_cpu(((__le16 *)upm2->partIdent. 1379 le16_to_cpu(((__le16 *)upm2->partIdent.
1225 identSuffix)[0]); 1380 identSuffix)[0]);
1226 if (suf == 0x0150) { 1381 if (suf < 0x0200) {
1227 map->s_partition_type = 1382 map->s_partition_type =
1228 UDF_VIRTUAL_MAP15; 1383 UDF_VIRTUAL_MAP15;
1229 map->s_partition_func = 1384 map->s_partition_func =
1230 udf_get_pblock_virt15; 1385 udf_get_pblock_virt15;
1231 } else if (suf == 0x0200) { 1386 } else {
1232 map->s_partition_type = 1387 map->s_partition_type =
1233 UDF_VIRTUAL_MAP20; 1388 UDF_VIRTUAL_MAP20;
1234 map->s_partition_func = 1389 map->s_partition_func =
@@ -1238,7 +1393,6 @@ static int udf_load_logicalvol(struct super_block *sb, struct buffer_head *bh,
1238 UDF_ID_SPARABLE, 1393 UDF_ID_SPARABLE,
1239 strlen(UDF_ID_SPARABLE))) { 1394 strlen(UDF_ID_SPARABLE))) {
1240 uint32_t loc; 1395 uint32_t loc;
1241 uint16_t ident;
1242 struct sparingTable *st; 1396 struct sparingTable *st;
1243 struct sparablePartitionMap *spm = 1397 struct sparablePartitionMap *spm =
1244 (struct sparablePartitionMap *)gpm; 1398 (struct sparablePartitionMap *)gpm;
@@ -1256,22 +1410,64 @@ static int udf_load_logicalvol(struct super_block *sb, struct buffer_head *bh,
1256 map->s_type_specific.s_sparing. 1410 map->s_type_specific.s_sparing.
1257 s_spar_map[j] = bh2; 1411 s_spar_map[j] = bh2;
1258 1412
1259 if (bh2 != NULL) { 1413 if (bh2 == NULL)
1260 st = (struct sparingTable *) 1414 continue;
1261 bh2->b_data; 1415
1262 if (ident != 0 || strncmp( 1416 st = (struct sparingTable *)bh2->b_data;
1263 st->sparingIdent.ident, 1417 if (ident != 0 || strncmp(
1264 UDF_ID_SPARING, 1418 st->sparingIdent.ident,
1265 strlen(UDF_ID_SPARING))) { 1419 UDF_ID_SPARING,
1266 brelse(bh2); 1420 strlen(UDF_ID_SPARING))) {
1267 map->s_type_specific. 1421 brelse(bh2);
1268 s_sparing. 1422 map->s_type_specific.s_sparing.
1269 s_spar_map[j] = 1423 s_spar_map[j] = NULL;
1270 NULL;
1271 }
1272 } 1424 }
1273 } 1425 }
1274 map->s_partition_func = udf_get_pblock_spar15; 1426 map->s_partition_func = udf_get_pblock_spar15;
1427 } else if (!strncmp(upm2->partIdent.ident,
1428 UDF_ID_METADATA,
1429 strlen(UDF_ID_METADATA))) {
1430 struct udf_meta_data *mdata =
1431 &map->s_type_specific.s_metadata;
1432 struct metadataPartitionMap *mdm =
1433 (struct metadataPartitionMap *)
1434 &(lvd->partitionMaps[offset]);
1435 udf_debug("Parsing Logical vol part %d "
1436 "type %d id=%s\n", i, type,
1437 UDF_ID_METADATA);
1438
1439 map->s_partition_type = UDF_METADATA_MAP25;
1440 map->s_partition_func = udf_get_pblock_meta25;
1441
1442 mdata->s_meta_file_loc =
1443 le32_to_cpu(mdm->metadataFileLoc);
1444 mdata->s_mirror_file_loc =
1445 le32_to_cpu(mdm->metadataMirrorFileLoc);
1446 mdata->s_bitmap_file_loc =
1447 le32_to_cpu(mdm->metadataBitmapFileLoc);
1448 mdata->s_alloc_unit_size =
1449 le32_to_cpu(mdm->allocUnitSize);
1450 mdata->s_align_unit_size =
1451 le16_to_cpu(mdm->alignUnitSize);
1452 mdata->s_dup_md_flag =
1453 mdm->flags & 0x01;
1454
1455 udf_debug("Metadata Ident suffix=0x%x\n",
1456 (le16_to_cpu(
1457 ((__le16 *)
1458 mdm->partIdent.identSuffix)[0])));
1459 udf_debug("Metadata part num=%d\n",
1460 le16_to_cpu(mdm->partitionNum));
1461 udf_debug("Metadata part alloc unit size=%d\n",
1462 le32_to_cpu(mdm->allocUnitSize));
1463 udf_debug("Metadata file loc=%d\n",
1464 le32_to_cpu(mdm->metadataFileLoc));
1465 udf_debug("Mirror file loc=%d\n",
1466 le32_to_cpu(mdm->metadataMirrorFileLoc));
1467 udf_debug("Bitmap file loc=%d\n",
1468 le32_to_cpu(mdm->metadataBitmapFileLoc));
1469 udf_debug("Duplicate Flag: %d %d\n",
1470 mdata->s_dup_md_flag, mdm->flags);
1275 } else { 1471 } else {
1276 udf_debug("Unknown ident: %s\n", 1472 udf_debug("Unknown ident: %s\n",
1277 upm2->partIdent.ident); 1473 upm2->partIdent.ident);
@@ -1296,7 +1492,9 @@ static int udf_load_logicalvol(struct super_block *sb, struct buffer_head *bh,
1296 if (lvd->integritySeqExt.extLength) 1492 if (lvd->integritySeqExt.extLength)
1297 udf_load_logicalvolint(sb, leea_to_cpu(lvd->integritySeqExt)); 1493 udf_load_logicalvolint(sb, leea_to_cpu(lvd->integritySeqExt));
1298 1494
1299 return 0; 1495out_bh:
1496 brelse(bh);
1497 return ret;
1300} 1498}
1301 1499
1302/* 1500/*
@@ -1345,7 +1543,7 @@ static void udf_load_logicalvolint(struct super_block *sb, kernel_extent_ad loc)
1345 * July 1, 1997 - Andrew E. Mileski 1543 * July 1, 1997 - Andrew E. Mileski
1346 * Written, tested, and released. 1544 * Written, tested, and released.
1347 */ 1545 */
1348static int udf_process_sequence(struct super_block *sb, long block, 1546static noinline int udf_process_sequence(struct super_block *sb, long block,
1349 long lastblock, kernel_lb_addr *fileset) 1547 long lastblock, kernel_lb_addr *fileset)
1350{ 1548{
1351 struct buffer_head *bh = NULL; 1549 struct buffer_head *bh = NULL;
@@ -1354,19 +1552,25 @@ static int udf_process_sequence(struct super_block *sb, long block,
1354 struct generic_desc *gd; 1552 struct generic_desc *gd;
1355 struct volDescPtr *vdp; 1553 struct volDescPtr *vdp;
1356 int done = 0; 1554 int done = 0;
1357 int i, j;
1358 uint32_t vdsn; 1555 uint32_t vdsn;
1359 uint16_t ident; 1556 uint16_t ident;
1360 long next_s = 0, next_e = 0; 1557 long next_s = 0, next_e = 0;
1361 1558
1362 memset(vds, 0, sizeof(struct udf_vds_record) * VDS_POS_LENGTH); 1559 memset(vds, 0, sizeof(struct udf_vds_record) * VDS_POS_LENGTH);
1363 1560
1364 /* Read the main descriptor sequence */ 1561 /*
1562 * Read the main descriptor sequence and find which descriptors
1563 * are in it.
1564 */
1365 for (; (!done && block <= lastblock); block++) { 1565 for (; (!done && block <= lastblock); block++) {
1366 1566
1367 bh = udf_read_tagged(sb, block, block, &ident); 1567 bh = udf_read_tagged(sb, block, block, &ident);
1368 if (!bh) 1568 if (!bh) {
1369 break; 1569 printk(KERN_ERR "udf: Block %Lu of volume descriptor "
1570 "sequence is corrupted or we could not read "
1571 "it.\n", (unsigned long long)block);
1572 return 1;
1573 }
1370 1574
1371 /* Process each descriptor (ISO 13346 3/8.3-8.4) */ 1575 /* Process each descriptor (ISO 13346 3/8.3-8.4) */
1372 gd = (struct generic_desc *)bh->b_data; 1576 gd = (struct generic_desc *)bh->b_data;
@@ -1432,41 +1636,31 @@ static int udf_process_sequence(struct super_block *sb, long block,
1432 } 1636 }
1433 brelse(bh); 1637 brelse(bh);
1434 } 1638 }
1435 for (i = 0; i < VDS_POS_LENGTH; i++) { 1639 /*
1436 if (vds[i].block) { 1640 * Now read interesting descriptors again and process them
1437 bh = udf_read_tagged(sb, vds[i].block, vds[i].block, 1641 * in a suitable order
1438 &ident); 1642 */
1439 1643 if (!vds[VDS_POS_PRIMARY_VOL_DESC].block) {
1440 if (i == VDS_POS_PRIMARY_VOL_DESC) { 1644 printk(KERN_ERR "udf: Primary Volume Descriptor not found!\n");
1441 udf_load_pvoldesc(sb, bh); 1645 return 1;
1442 } else if (i == VDS_POS_LOGICAL_VOL_DESC) { 1646 }
1443 if (udf_load_logicalvol(sb, bh, fileset)) { 1647 if (udf_load_pvoldesc(sb, vds[VDS_POS_PRIMARY_VOL_DESC].block))
1444 brelse(bh); 1648 return 1;
1445 return 1; 1649
1446 } 1650 if (vds[VDS_POS_LOGICAL_VOL_DESC].block && udf_load_logicalvol(sb,
1447 } else if (i == VDS_POS_PARTITION_DESC) { 1651 vds[VDS_POS_LOGICAL_VOL_DESC].block, fileset))
1448 struct buffer_head *bh2 = NULL; 1652 return 1;
1449 if (udf_load_partdesc(sb, bh)) { 1653
1450 brelse(bh); 1654 if (vds[VDS_POS_PARTITION_DESC].block) {
1451 return 1; 1655 /*
1452 } 1656 * We rescan the whole descriptor sequence to find
1453 for (j = vds[i].block + 1; 1657 * partition descriptor blocks and process them.
1454 j < vds[VDS_POS_TERMINATING_DESC].block; 1658 */
1455 j++) { 1659 for (block = vds[VDS_POS_PARTITION_DESC].block;
1456 bh2 = udf_read_tagged(sb, j, j, &ident); 1660 block < vds[VDS_POS_TERMINATING_DESC].block;
1457 gd = (struct generic_desc *)bh2->b_data; 1661 block++)
1458 if (ident == TAG_IDENT_PD) 1662 if (udf_load_partdesc(sb, block))
1459 if (udf_load_partdesc(sb, 1663 return 1;
1460 bh2)) {
1461 brelse(bh);
1462 brelse(bh2);
1463 return 1;
1464 }
1465 brelse(bh2);
1466 }
1467 }
1468 brelse(bh);
1469 }
1470 } 1664 }
1471 1665
1472 return 0; 1666 return 0;
@@ -1478,6 +1672,7 @@ static int udf_process_sequence(struct super_block *sb, long block,
1478static int udf_check_valid(struct super_block *sb, int novrs, int silent) 1672static int udf_check_valid(struct super_block *sb, int novrs, int silent)
1479{ 1673{
1480 long block; 1674 long block;
1675 struct udf_sb_info *sbi = UDF_SB(sb);
1481 1676
1482 if (novrs) { 1677 if (novrs) {
1483 udf_debug("Validity check skipped because of novrs option\n"); 1678 udf_debug("Validity check skipped because of novrs option\n");
@@ -1485,27 +1680,22 @@ static int udf_check_valid(struct super_block *sb, int novrs, int silent)
1485 } 1680 }
1486 /* Check that it is NSR02 compliant */ 1681 /* Check that it is NSR02 compliant */
1487 /* Process any "CD-ROM Volume Descriptor Set" (ECMA 167 2/8.3.1) */ 1682 /* Process any "CD-ROM Volume Descriptor Set" (ECMA 167 2/8.3.1) */
1488 else { 1683 block = udf_vrs(sb, silent);
1489 block = udf_vrs(sb, silent); 1684 if (block == -1)
1490 if (block == -1) { 1685 udf_debug("Failed to read byte 32768. Assuming open "
1491 struct udf_sb_info *sbi = UDF_SB(sb); 1686 "disc. Skipping validity check\n");
1492 udf_debug("Failed to read byte 32768. Assuming open " 1687 if (block && !sbi->s_last_block)
1493 "disc. Skipping validity check\n"); 1688 sbi->s_last_block = udf_get_last_block(sb);
1494 if (!sbi->s_last_block) 1689 return !block;
1495 sbi->s_last_block = udf_get_last_block(sb);
1496 return 0;
1497 } else
1498 return !block;
1499 }
1500} 1690}
1501 1691
1502static int udf_load_partition(struct super_block *sb, kernel_lb_addr *fileset) 1692static int udf_load_sequence(struct super_block *sb, kernel_lb_addr *fileset)
1503{ 1693{
1504 struct anchorVolDescPtr *anchor; 1694 struct anchorVolDescPtr *anchor;
1505 uint16_t ident; 1695 uint16_t ident;
1506 struct buffer_head *bh; 1696 struct buffer_head *bh;
1507 long main_s, main_e, reserve_s, reserve_e; 1697 long main_s, main_e, reserve_s, reserve_e;
1508 int i, j; 1698 int i;
1509 struct udf_sb_info *sbi; 1699 struct udf_sb_info *sbi;
1510 1700
1511 if (!sb) 1701 if (!sb)
@@ -1515,6 +1705,7 @@ static int udf_load_partition(struct super_block *sb, kernel_lb_addr *fileset)
1515 for (i = 0; i < ARRAY_SIZE(sbi->s_anchor); i++) { 1705 for (i = 0; i < ARRAY_SIZE(sbi->s_anchor); i++) {
1516 if (!sbi->s_anchor[i]) 1706 if (!sbi->s_anchor[i])
1517 continue; 1707 continue;
1708
1518 bh = udf_read_tagged(sb, sbi->s_anchor[i], sbi->s_anchor[i], 1709 bh = udf_read_tagged(sb, sbi->s_anchor[i], sbi->s_anchor[i],
1519 &ident); 1710 &ident);
1520 if (!bh) 1711 if (!bh)
@@ -1553,76 +1744,6 @@ static int udf_load_partition(struct super_block *sb, kernel_lb_addr *fileset)
1553 } 1744 }
1554 udf_debug("Using anchor in block %d\n", sbi->s_anchor[i]); 1745 udf_debug("Using anchor in block %d\n", sbi->s_anchor[i]);
1555 1746
1556 for (i = 0; i < sbi->s_partitions; i++) {
1557 kernel_lb_addr uninitialized_var(ino);
1558 struct udf_part_map *map = &sbi->s_partmaps[i];
1559 switch (map->s_partition_type) {
1560 case UDF_VIRTUAL_MAP15:
1561 case UDF_VIRTUAL_MAP20:
1562 if (!sbi->s_last_block) {
1563 sbi->s_last_block = udf_get_last_block(sb);
1564 udf_find_anchor(sb);
1565 }
1566
1567 if (!sbi->s_last_block) {
1568 udf_debug("Unable to determine Lastblock (For "
1569 "Virtual Partition)\n");
1570 return 1;
1571 }
1572
1573 for (j = 0; j < sbi->s_partitions; j++) {
1574 struct udf_part_map *map2 = &sbi->s_partmaps[j];
1575 if (j != i &&
1576 map->s_volumeseqnum ==
1577 map2->s_volumeseqnum &&
1578 map->s_partition_num ==
1579 map2->s_partition_num) {
1580 ino.partitionReferenceNum = j;
1581 ino.logicalBlockNum =
1582 sbi->s_last_block -
1583 map2->s_partition_root;
1584 break;
1585 }
1586 }
1587
1588 if (j == sbi->s_partitions)
1589 return 1;
1590
1591 sbi->s_vat_inode = udf_iget(sb, ino);
1592 if (!sbi->s_vat_inode)
1593 return 1;
1594
1595 if (map->s_partition_type == UDF_VIRTUAL_MAP15) {
1596 map->s_type_specific.s_virtual.s_start_offset =
1597 udf_ext0_offset(sbi->s_vat_inode);
1598 map->s_type_specific.s_virtual.s_num_entries =
1599 (sbi->s_vat_inode->i_size - 36) >> 2;
1600 } else if (map->s_partition_type == UDF_VIRTUAL_MAP20) {
1601 uint32_t pos;
1602 struct virtualAllocationTable20 *vat20;
1603
1604 pos = udf_block_map(sbi->s_vat_inode, 0);
1605 bh = sb_bread(sb, pos);
1606 if (!bh)
1607 return 1;
1608 vat20 = (struct virtualAllocationTable20 *)
1609 bh->b_data +
1610 udf_ext0_offset(sbi->s_vat_inode);
1611 map->s_type_specific.s_virtual.s_start_offset =
1612 le16_to_cpu(vat20->lengthHeader) +
1613 udf_ext0_offset(sbi->s_vat_inode);
1614 map->s_type_specific.s_virtual.s_num_entries =
1615 (sbi->s_vat_inode->i_size -
1616 map->s_type_specific.s_virtual.
1617 s_start_offset) >> 2;
1618 brelse(bh);
1619 }
1620 map->s_partition_root = udf_get_pblock(sb, 0, i, 0);
1621 map->s_partition_len =
1622 sbi->s_partmaps[ino.partitionReferenceNum].
1623 s_partition_len;
1624 }
1625 }
1626 return 0; 1747 return 0;
1627} 1748}
1628 1749
@@ -1630,65 +1751,61 @@ static void udf_open_lvid(struct super_block *sb)
1630{ 1751{
1631 struct udf_sb_info *sbi = UDF_SB(sb); 1752 struct udf_sb_info *sbi = UDF_SB(sb);
1632 struct buffer_head *bh = sbi->s_lvid_bh; 1753 struct buffer_head *bh = sbi->s_lvid_bh;
1633 if (bh) { 1754 struct logicalVolIntegrityDesc *lvid;
1634 kernel_timestamp cpu_time; 1755 struct logicalVolIntegrityDescImpUse *lvidiu;
1635 struct logicalVolIntegrityDesc *lvid = 1756 if (!bh)
1636 (struct logicalVolIntegrityDesc *)bh->b_data; 1757 return;
1637 struct logicalVolIntegrityDescImpUse *lvidiu =
1638 udf_sb_lvidiu(sbi);
1639 1758
1640 lvidiu->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX; 1759 lvid = (struct logicalVolIntegrityDesc *)bh->b_data;
1641 lvidiu->impIdent.identSuffix[1] = UDF_OS_ID_LINUX; 1760 lvidiu = udf_sb_lvidiu(sbi);
1642 if (udf_time_to_stamp(&cpu_time, CURRENT_TIME))
1643 lvid->recordingDateAndTime = cpu_to_lets(cpu_time);
1644 lvid->integrityType = LVID_INTEGRITY_TYPE_OPEN;
1645 1761
1646 lvid->descTag.descCRC = cpu_to_le16( 1762 lvidiu->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX;
1647 udf_crc((char *)lvid + sizeof(tag), 1763 lvidiu->impIdent.identSuffix[1] = UDF_OS_ID_LINUX;
1648 le16_to_cpu(lvid->descTag.descCRCLength), 1764 udf_time_to_disk_stamp(&lvid->recordingDateAndTime,
1649 0)); 1765 CURRENT_TIME);
1766 lvid->integrityType = LVID_INTEGRITY_TYPE_OPEN;
1650 1767
1651 lvid->descTag.tagChecksum = udf_tag_checksum(&lvid->descTag); 1768 lvid->descTag.descCRC = cpu_to_le16(
1652 mark_buffer_dirty(bh); 1769 crc_itu_t(0, (char *)lvid + sizeof(tag),
1653 } 1770 le16_to_cpu(lvid->descTag.descCRCLength)));
1771
1772 lvid->descTag.tagChecksum = udf_tag_checksum(&lvid->descTag);
1773 mark_buffer_dirty(bh);
1654} 1774}
1655 1775
1656static void udf_close_lvid(struct super_block *sb) 1776static void udf_close_lvid(struct super_block *sb)
1657{ 1777{
1658 kernel_timestamp cpu_time;
1659 struct udf_sb_info *sbi = UDF_SB(sb); 1778 struct udf_sb_info *sbi = UDF_SB(sb);
1660 struct buffer_head *bh = sbi->s_lvid_bh; 1779 struct buffer_head *bh = sbi->s_lvid_bh;
1661 struct logicalVolIntegrityDesc *lvid; 1780 struct logicalVolIntegrityDesc *lvid;
1781 struct logicalVolIntegrityDescImpUse *lvidiu;
1662 1782
1663 if (!bh) 1783 if (!bh)
1664 return; 1784 return;
1665 1785
1666 lvid = (struct logicalVolIntegrityDesc *)bh->b_data; 1786 lvid = (struct logicalVolIntegrityDesc *)bh->b_data;
1667 1787
1668 if (lvid->integrityType == LVID_INTEGRITY_TYPE_OPEN) { 1788 if (lvid->integrityType != LVID_INTEGRITY_TYPE_OPEN)
1669 struct logicalVolIntegrityDescImpUse *lvidiu = 1789 return;
1670 udf_sb_lvidiu(sbi); 1790
1671 lvidiu->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX; 1791 lvidiu = udf_sb_lvidiu(sbi);
1672 lvidiu->impIdent.identSuffix[1] = UDF_OS_ID_LINUX; 1792 lvidiu->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX;
1673 if (udf_time_to_stamp(&cpu_time, CURRENT_TIME)) 1793 lvidiu->impIdent.identSuffix[1] = UDF_OS_ID_LINUX;
1674 lvid->recordingDateAndTime = cpu_to_lets(cpu_time); 1794 udf_time_to_disk_stamp(&lvid->recordingDateAndTime, CURRENT_TIME);
1675 if (UDF_MAX_WRITE_VERSION > le16_to_cpu(lvidiu->maxUDFWriteRev)) 1795 if (UDF_MAX_WRITE_VERSION > le16_to_cpu(lvidiu->maxUDFWriteRev))
1676 lvidiu->maxUDFWriteRev = 1796 lvidiu->maxUDFWriteRev = cpu_to_le16(UDF_MAX_WRITE_VERSION);
1677 cpu_to_le16(UDF_MAX_WRITE_VERSION); 1797 if (sbi->s_udfrev > le16_to_cpu(lvidiu->minUDFReadRev))
1678 if (sbi->s_udfrev > le16_to_cpu(lvidiu->minUDFReadRev)) 1798 lvidiu->minUDFReadRev = cpu_to_le16(sbi->s_udfrev);
1679 lvidiu->minUDFReadRev = cpu_to_le16(sbi->s_udfrev); 1799 if (sbi->s_udfrev > le16_to_cpu(lvidiu->minUDFWriteRev))
1680 if (sbi->s_udfrev > le16_to_cpu(lvidiu->minUDFWriteRev)) 1800 lvidiu->minUDFWriteRev = cpu_to_le16(sbi->s_udfrev);
1681 lvidiu->minUDFWriteRev = cpu_to_le16(sbi->s_udfrev); 1801 lvid->integrityType = cpu_to_le32(LVID_INTEGRITY_TYPE_CLOSE);
1682 lvid->integrityType = cpu_to_le32(LVID_INTEGRITY_TYPE_CLOSE); 1802
1683 1803 lvid->descTag.descCRC = cpu_to_le16(
1684 lvid->descTag.descCRC = cpu_to_le16( 1804 crc_itu_t(0, (char *)lvid + sizeof(tag),
1685 udf_crc((char *)lvid + sizeof(tag), 1805 le16_to_cpu(lvid->descTag.descCRCLength)));
1686 le16_to_cpu(lvid->descTag.descCRCLength), 1806
1687 0)); 1807 lvid->descTag.tagChecksum = udf_tag_checksum(&lvid->descTag);
1688 1808 mark_buffer_dirty(bh);
1689 lvid->descTag.tagChecksum = udf_tag_checksum(&lvid->descTag);
1690 mark_buffer_dirty(bh);
1691 }
1692} 1809}
1693 1810
1694static void udf_sb_free_bitmap(struct udf_bitmap *bitmap) 1811static void udf_sb_free_bitmap(struct udf_bitmap *bitmap)
@@ -1708,22 +1825,35 @@ static void udf_sb_free_bitmap(struct udf_bitmap *bitmap)
1708 vfree(bitmap); 1825 vfree(bitmap);
1709} 1826}
1710 1827
1711/* 1828static void udf_free_partition(struct udf_part_map *map)
1712 * udf_read_super 1829{
1713 * 1830 int i;
1714 * PURPOSE 1831 struct udf_meta_data *mdata;
1715 * Complete the specified super block. 1832
1716 * 1833 if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_TABLE)
1717 * PRE-CONDITIONS 1834 iput(map->s_uspace.s_table);
1718 * sb Pointer to superblock to complete - never NULL. 1835 if (map->s_partition_flags & UDF_PART_FLAG_FREED_TABLE)
1719 * sb->s_dev Device to read suberblock from. 1836 iput(map->s_fspace.s_table);
1720 * options Pointer to mount options. 1837 if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_BITMAP)
1721 * silent Silent flag. 1838 udf_sb_free_bitmap(map->s_uspace.s_bitmap);
1722 * 1839 if (map->s_partition_flags & UDF_PART_FLAG_FREED_BITMAP)
1723 * HISTORY 1840 udf_sb_free_bitmap(map->s_fspace.s_bitmap);
1724 * July 1, 1997 - Andrew E. Mileski 1841 if (map->s_partition_type == UDF_SPARABLE_MAP15)
1725 * Written, tested, and released. 1842 for (i = 0; i < 4; i++)
1726 */ 1843 brelse(map->s_type_specific.s_sparing.s_spar_map[i]);
1844 else if (map->s_partition_type == UDF_METADATA_MAP25) {
1845 mdata = &map->s_type_specific.s_metadata;
1846 iput(mdata->s_metadata_fe);
1847 mdata->s_metadata_fe = NULL;
1848
1849 iput(mdata->s_mirror_fe);
1850 mdata->s_mirror_fe = NULL;
1851
1852 iput(mdata->s_bitmap_fe);
1853 mdata->s_bitmap_fe = NULL;
1854 }
1855}
1856
1727static int udf_fill_super(struct super_block *sb, void *options, int silent) 1857static int udf_fill_super(struct super_block *sb, void *options, int silent)
1728{ 1858{
1729 int i; 1859 int i;
@@ -1776,8 +1906,11 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent)
1776 sbi->s_nls_map = uopt.nls_map; 1906 sbi->s_nls_map = uopt.nls_map;
1777 1907
1778 /* Set the block size for all transfers */ 1908 /* Set the block size for all transfers */
1779 if (!udf_set_blocksize(sb, uopt.blocksize)) 1909 if (!sb_min_blocksize(sb, uopt.blocksize)) {
1910 udf_debug("Bad block size (%d)\n", uopt.blocksize);
1911 printk(KERN_ERR "udf: bad block size (%d)\n", uopt.blocksize);
1780 goto error_out; 1912 goto error_out;
1913 }
1781 1914
1782 if (uopt.session == 0xFFFFFFFF) 1915 if (uopt.session == 0xFFFFFFFF)
1783 sbi->s_session = udf_get_last_session(sb); 1916 sbi->s_session = udf_get_last_session(sb);
@@ -1789,7 +1922,6 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent)
1789 sbi->s_last_block = uopt.lastblock; 1922 sbi->s_last_block = uopt.lastblock;
1790 sbi->s_anchor[0] = sbi->s_anchor[1] = 0; 1923 sbi->s_anchor[0] = sbi->s_anchor[1] = 0;
1791 sbi->s_anchor[2] = uopt.anchor; 1924 sbi->s_anchor[2] = uopt.anchor;
1792 sbi->s_anchor[3] = 256;
1793 1925
1794 if (udf_check_valid(sb, uopt.novrs, silent)) { 1926 if (udf_check_valid(sb, uopt.novrs, silent)) {
1795 /* read volume recognition sequences */ 1927 /* read volume recognition sequences */
@@ -1806,7 +1938,7 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent)
1806 sb->s_magic = UDF_SUPER_MAGIC; 1938 sb->s_magic = UDF_SUPER_MAGIC;
1807 sb->s_time_gran = 1000; 1939 sb->s_time_gran = 1000;
1808 1940
1809 if (udf_load_partition(sb, &fileset)) { 1941 if (udf_load_sequence(sb, &fileset)) {
1810 printk(KERN_WARNING "UDF-fs: No partition found (1)\n"); 1942 printk(KERN_WARNING "UDF-fs: No partition found (1)\n");
1811 goto error_out; 1943 goto error_out;
1812 } 1944 }
@@ -1856,12 +1988,12 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent)
1856 } 1988 }
1857 1989
1858 if (!silent) { 1990 if (!silent) {
1859 kernel_timestamp ts; 1991 timestamp ts;
1860 udf_time_to_stamp(&ts, sbi->s_record_time); 1992 udf_time_to_disk_stamp(&ts, sbi->s_record_time);
1861 udf_info("UDF: Mounting volume '%s', " 1993 udf_info("UDF: Mounting volume '%s', "
1862 "timestamp %04u/%02u/%02u %02u:%02u (%x)\n", 1994 "timestamp %04u/%02u/%02u %02u:%02u (%x)\n",
1863 sbi->s_volume_ident, ts.year, ts.month, ts.day, 1995 sbi->s_volume_ident, le16_to_cpu(ts.year), ts.month, ts.day,
1864 ts.hour, ts.minute, ts.typeAndTimezone); 1996 ts.hour, ts.minute, le16_to_cpu(ts.typeAndTimezone));
1865 } 1997 }
1866 if (!(sb->s_flags & MS_RDONLY)) 1998 if (!(sb->s_flags & MS_RDONLY))
1867 udf_open_lvid(sb); 1999 udf_open_lvid(sb);
@@ -1890,21 +2022,9 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent)
1890error_out: 2022error_out:
1891 if (sbi->s_vat_inode) 2023 if (sbi->s_vat_inode)
1892 iput(sbi->s_vat_inode); 2024 iput(sbi->s_vat_inode);
1893 if (sbi->s_partitions) { 2025 if (sbi->s_partitions)
1894 struct udf_part_map *map = &sbi->s_partmaps[sbi->s_partition]; 2026 for (i = 0; i < sbi->s_partitions; i++)
1895 if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_TABLE) 2027 udf_free_partition(&sbi->s_partmaps[i]);
1896 iput(map->s_uspace.s_table);
1897 if (map->s_partition_flags & UDF_PART_FLAG_FREED_TABLE)
1898 iput(map->s_fspace.s_table);
1899 if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_BITMAP)
1900 udf_sb_free_bitmap(map->s_uspace.s_bitmap);
1901 if (map->s_partition_flags & UDF_PART_FLAG_FREED_BITMAP)
1902 udf_sb_free_bitmap(map->s_fspace.s_bitmap);
1903 if (map->s_partition_type == UDF_SPARABLE_MAP15)
1904 for (i = 0; i < 4; i++)
1905 brelse(map->s_type_specific.s_sparing.
1906 s_spar_map[i]);
1907 }
1908#ifdef CONFIG_UDF_NLS 2028#ifdef CONFIG_UDF_NLS
1909 if (UDF_QUERY_FLAG(sb, UDF_FLAG_NLS_MAP)) 2029 if (UDF_QUERY_FLAG(sb, UDF_FLAG_NLS_MAP))
1910 unload_nls(sbi->s_nls_map); 2030 unload_nls(sbi->s_nls_map);
@@ -1920,8 +2040,8 @@ error_out:
1920 return -EINVAL; 2040 return -EINVAL;
1921} 2041}
1922 2042
1923void udf_error(struct super_block *sb, const char *function, 2043static void udf_error(struct super_block *sb, const char *function,
1924 const char *fmt, ...) 2044 const char *fmt, ...)
1925{ 2045{
1926 va_list args; 2046 va_list args;
1927 2047
@@ -1948,19 +2068,6 @@ void udf_warning(struct super_block *sb, const char *function,
1948 sb->s_id, function, error_buf); 2068 sb->s_id, function, error_buf);
1949} 2069}
1950 2070
1951/*
1952 * udf_put_super
1953 *
1954 * PURPOSE
1955 * Prepare for destruction of the superblock.
1956 *
1957 * DESCRIPTION
1958 * Called before the filesystem is unmounted.
1959 *
1960 * HISTORY
1961 * July 1, 1997 - Andrew E. Mileski
1962 * Written, tested, and released.
1963 */
1964static void udf_put_super(struct super_block *sb) 2071static void udf_put_super(struct super_block *sb)
1965{ 2072{
1966 int i; 2073 int i;
@@ -1969,21 +2076,9 @@ static void udf_put_super(struct super_block *sb)
1969 sbi = UDF_SB(sb); 2076 sbi = UDF_SB(sb);
1970 if (sbi->s_vat_inode) 2077 if (sbi->s_vat_inode)
1971 iput(sbi->s_vat_inode); 2078 iput(sbi->s_vat_inode);
1972 if (sbi->s_partitions) { 2079 if (sbi->s_partitions)
1973 struct udf_part_map *map = &sbi->s_partmaps[sbi->s_partition]; 2080 for (i = 0; i < sbi->s_partitions; i++)
1974 if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_TABLE) 2081 udf_free_partition(&sbi->s_partmaps[i]);
1975 iput(map->s_uspace.s_table);
1976 if (map->s_partition_flags & UDF_PART_FLAG_FREED_TABLE)
1977 iput(map->s_fspace.s_table);
1978 if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_BITMAP)
1979 udf_sb_free_bitmap(map->s_uspace.s_bitmap);
1980 if (map->s_partition_flags & UDF_PART_FLAG_FREED_BITMAP)
1981 udf_sb_free_bitmap(map->s_fspace.s_bitmap);
1982 if (map->s_partition_type == UDF_SPARABLE_MAP15)
1983 for (i = 0; i < 4; i++)
1984 brelse(map->s_type_specific.s_sparing.
1985 s_spar_map[i]);
1986 }
1987#ifdef CONFIG_UDF_NLS 2082#ifdef CONFIG_UDF_NLS
1988 if (UDF_QUERY_FLAG(sb, UDF_FLAG_NLS_MAP)) 2083 if (UDF_QUERY_FLAG(sb, UDF_FLAG_NLS_MAP))
1989 unload_nls(sbi->s_nls_map); 2084 unload_nls(sbi->s_nls_map);
@@ -1996,19 +2091,6 @@ static void udf_put_super(struct super_block *sb)
1996 sb->s_fs_info = NULL; 2091 sb->s_fs_info = NULL;
1997} 2092}
1998 2093
1999/*
2000 * udf_stat_fs
2001 *
2002 * PURPOSE
2003 * Return info about the filesystem.
2004 *
2005 * DESCRIPTION
2006 * Called by sys_statfs()
2007 *
2008 * HISTORY
2009 * July 1, 1997 - Andrew E. Mileski
2010 * Written, tested, and released.
2011 */
2012static int udf_statfs(struct dentry *dentry, struct kstatfs *buf) 2094static int udf_statfs(struct dentry *dentry, struct kstatfs *buf)
2013{ 2095{
2014 struct super_block *sb = dentry->d_sb; 2096 struct super_block *sb = dentry->d_sb;
@@ -2035,10 +2117,6 @@ static int udf_statfs(struct dentry *dentry, struct kstatfs *buf)
2035 return 0; 2117 return 0;
2036} 2118}
2037 2119
2038static unsigned char udf_bitmap_lookup[16] = {
2039 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4
2040};
2041
2042static unsigned int udf_count_free_bitmap(struct super_block *sb, 2120static unsigned int udf_count_free_bitmap(struct super_block *sb,
2043 struct udf_bitmap *bitmap) 2121 struct udf_bitmap *bitmap)
2044{ 2122{
@@ -2048,7 +2126,6 @@ static unsigned int udf_count_free_bitmap(struct super_block *sb,
2048 int block = 0, newblock; 2126 int block = 0, newblock;
2049 kernel_lb_addr loc; 2127 kernel_lb_addr loc;
2050 uint32_t bytes; 2128 uint32_t bytes;
2051 uint8_t value;
2052 uint8_t *ptr; 2129 uint8_t *ptr;
2053 uint16_t ident; 2130 uint16_t ident;
2054 struct spaceBitmapDesc *bm; 2131 struct spaceBitmapDesc *bm;
@@ -2074,13 +2151,10 @@ static unsigned int udf_count_free_bitmap(struct super_block *sb,
2074 ptr = (uint8_t *)bh->b_data; 2151 ptr = (uint8_t *)bh->b_data;
2075 2152
2076 while (bytes > 0) { 2153 while (bytes > 0) {
2077 while ((bytes > 0) && (index < sb->s_blocksize)) { 2154 u32 cur_bytes = min_t(u32, bytes, sb->s_blocksize - index);
2078 value = ptr[index]; 2155 accum += bitmap_weight((const unsigned long *)(ptr + index),
2079 accum += udf_bitmap_lookup[value & 0x0f]; 2156 cur_bytes * 8);
2080 accum += udf_bitmap_lookup[value >> 4]; 2157 bytes -= cur_bytes;
2081 index++;
2082 bytes--;
2083 }
2084 if (bytes) { 2158 if (bytes) {
2085 brelse(bh); 2159 brelse(bh);
2086 newblock = udf_get_lb_pblock(sb, loc, ++block); 2160 newblock = udf_get_lb_pblock(sb, loc, ++block);
diff --git a/fs/udf/symlink.c b/fs/udf/symlink.c
index 6ec99221e50c..c3265e1385d4 100644
--- a/fs/udf/symlink.c
+++ b/fs/udf/symlink.c
@@ -23,7 +23,6 @@
23#include <asm/uaccess.h> 23#include <asm/uaccess.h>
24#include <linux/errno.h> 24#include <linux/errno.h>
25#include <linux/fs.h> 25#include <linux/fs.h>
26#include <linux/udf_fs.h>
27#include <linux/time.h> 26#include <linux/time.h>
28#include <linux/mm.h> 27#include <linux/mm.h>
29#include <linux/stat.h> 28#include <linux/stat.h>
diff --git a/fs/udf/truncate.c b/fs/udf/truncate.c
index fe61be17cdab..65e19b4f9424 100644
--- a/fs/udf/truncate.c
+++ b/fs/udf/truncate.c
@@ -22,7 +22,6 @@
22#include "udfdecl.h" 22#include "udfdecl.h"
23#include <linux/fs.h> 23#include <linux/fs.h>
24#include <linux/mm.h> 24#include <linux/mm.h>
25#include <linux/udf_fs.h>
26#include <linux/buffer_head.h> 25#include <linux/buffer_head.h>
27 26
28#include "udf_i.h" 27#include "udf_i.h"
@@ -180,6 +179,24 @@ void udf_discard_prealloc(struct inode *inode)
180 brelse(epos.bh); 179 brelse(epos.bh);
181} 180}
182 181
182static void udf_update_alloc_ext_desc(struct inode *inode,
183 struct extent_position *epos,
184 u32 lenalloc)
185{
186 struct super_block *sb = inode->i_sb;
187 struct udf_sb_info *sbi = UDF_SB(sb);
188
189 struct allocExtDesc *aed = (struct allocExtDesc *) (epos->bh->b_data);
190 int len = sizeof(struct allocExtDesc);
191
192 aed->lengthAllocDescs = cpu_to_le32(lenalloc);
193 if (!UDF_QUERY_FLAG(sb, UDF_FLAG_STRICT) || sbi->s_udfrev >= 0x0201)
194 len += lenalloc;
195
196 udf_update_tag(epos->bh->b_data, len);
197 mark_buffer_dirty_inode(epos->bh, inode);
198}
199
183void udf_truncate_extents(struct inode *inode) 200void udf_truncate_extents(struct inode *inode)
184{ 201{
185 struct extent_position epos; 202 struct extent_position epos;
@@ -187,7 +204,6 @@ void udf_truncate_extents(struct inode *inode)
187 uint32_t elen, nelen = 0, indirect_ext_len = 0, lenalloc; 204 uint32_t elen, nelen = 0, indirect_ext_len = 0, lenalloc;
188 int8_t etype; 205 int8_t etype;
189 struct super_block *sb = inode->i_sb; 206 struct super_block *sb = inode->i_sb;
190 struct udf_sb_info *sbi = UDF_SB(sb);
191 sector_t first_block = inode->i_size >> sb->s_blocksize_bits, offset; 207 sector_t first_block = inode->i_size >> sb->s_blocksize_bits, offset;
192 loff_t byte_offset; 208 loff_t byte_offset;
193 int adsize; 209 int adsize;
@@ -224,35 +240,15 @@ void udf_truncate_extents(struct inode *inode)
224 if (indirect_ext_len) { 240 if (indirect_ext_len) {
225 /* We managed to free all extents in the 241 /* We managed to free all extents in the
226 * indirect extent - free it too */ 242 * indirect extent - free it too */
227 if (!epos.bh) 243 BUG_ON(!epos.bh);
228 BUG();
229 udf_free_blocks(sb, inode, epos.block, 244 udf_free_blocks(sb, inode, epos.block,
230 0, indirect_ext_len); 245 0, indirect_ext_len);
231 } else { 246 } else if (!epos.bh) {
232 if (!epos.bh) { 247 iinfo->i_lenAlloc = lenalloc;
233 iinfo->i_lenAlloc = 248 mark_inode_dirty(inode);
234 lenalloc; 249 } else
235 mark_inode_dirty(inode); 250 udf_update_alloc_ext_desc(inode,
236 } else { 251 &epos, lenalloc);
237 struct allocExtDesc *aed =
238 (struct allocExtDesc *)
239 (epos.bh->b_data);
240 int len =
241 sizeof(struct allocExtDesc);
242
243 aed->lengthAllocDescs =
244 cpu_to_le32(lenalloc);
245 if (!UDF_QUERY_FLAG(sb,
246 UDF_FLAG_STRICT) ||
247 sbi->s_udfrev >= 0x0201)
248 len += lenalloc;
249
250 udf_update_tag(epos.bh->b_data,
251 len);
252 mark_buffer_dirty_inode(
253 epos.bh, inode);
254 }
255 }
256 brelse(epos.bh); 252 brelse(epos.bh);
257 epos.offset = sizeof(struct allocExtDesc); 253 epos.offset = sizeof(struct allocExtDesc);
258 epos.block = eloc; 254 epos.block = eloc;
@@ -272,29 +268,14 @@ void udf_truncate_extents(struct inode *inode)
272 } 268 }
273 269
274 if (indirect_ext_len) { 270 if (indirect_ext_len) {
275 if (!epos.bh) 271 BUG_ON(!epos.bh);
276 BUG();
277 udf_free_blocks(sb, inode, epos.block, 0, 272 udf_free_blocks(sb, inode, epos.block, 0,
278 indirect_ext_len); 273 indirect_ext_len);
279 } else { 274 } else if (!epos.bh) {
280 if (!epos.bh) { 275 iinfo->i_lenAlloc = lenalloc;
281 iinfo->i_lenAlloc = lenalloc; 276 mark_inode_dirty(inode);
282 mark_inode_dirty(inode); 277 } else
283 } else { 278 udf_update_alloc_ext_desc(inode, &epos, lenalloc);
284 struct allocExtDesc *aed =
285 (struct allocExtDesc *)(epos.bh->b_data);
286 aed->lengthAllocDescs = cpu_to_le32(lenalloc);
287 if (!UDF_QUERY_FLAG(sb, UDF_FLAG_STRICT) ||
288 sbi->s_udfrev >= 0x0201)
289 udf_update_tag(epos.bh->b_data,
290 lenalloc +
291 sizeof(struct allocExtDesc));
292 else
293 udf_update_tag(epos.bh->b_data,
294 sizeof(struct allocExtDesc));
295 mark_buffer_dirty_inode(epos.bh, inode);
296 }
297 }
298 } else if (inode->i_size) { 279 } else if (inode->i_size) {
299 if (byte_offset) { 280 if (byte_offset) {
300 kernel_long_ad extent; 281 kernel_long_ad extent;
diff --git a/fs/udf/udf_i.h b/fs/udf/udf_i.h
index ccc52f16bf7d..4f86b1d98a5d 100644
--- a/fs/udf/udf_i.h
+++ b/fs/udf/udf_i.h
@@ -1,10 +1,32 @@
1#ifndef __LINUX_UDF_I_H 1#ifndef _UDF_I_H
2#define __LINUX_UDF_I_H 2#define _UDF_I_H
3
4struct udf_inode_info {
5 struct timespec i_crtime;
6 /* Physical address of inode */
7 kernel_lb_addr i_location;
8 __u64 i_unique;
9 __u32 i_lenEAttr;
10 __u32 i_lenAlloc;
11 __u64 i_lenExtents;
12 __u32 i_next_alloc_block;
13 __u32 i_next_alloc_goal;
14 unsigned i_alloc_type : 3;
15 unsigned i_efe : 1; /* extendedFileEntry */
16 unsigned i_use : 1; /* unallocSpaceEntry */
17 unsigned i_strat4096 : 1;
18 unsigned reserved : 26;
19 union {
20 short_ad *i_sad;
21 long_ad *i_lad;
22 __u8 *i_data;
23 } i_ext;
24 struct inode vfs_inode;
25};
3 26
4#include <linux/udf_fs_i.h>
5static inline struct udf_inode_info *UDF_I(struct inode *inode) 27static inline struct udf_inode_info *UDF_I(struct inode *inode)
6{ 28{
7 return list_entry(inode, struct udf_inode_info, vfs_inode); 29 return list_entry(inode, struct udf_inode_info, vfs_inode);
8} 30}
9 31
10#endif /* !defined(_LINUX_UDF_I_H) */ 32#endif /* _UDF_I_H) */
diff --git a/fs/udf/udf_sb.h b/fs/udf/udf_sb.h
index 737d1c604eea..1c1c514a9725 100644
--- a/fs/udf/udf_sb.h
+++ b/fs/udf/udf_sb.h
@@ -1,10 +1,12 @@
1#ifndef __LINUX_UDF_SB_H 1#ifndef __LINUX_UDF_SB_H
2#define __LINUX_UDF_SB_H 2#define __LINUX_UDF_SB_H
3 3
4#include <linux/mutex.h>
5
4/* Since UDF 2.01 is ISO 13346 based... */ 6/* Since UDF 2.01 is ISO 13346 based... */
5#define UDF_SUPER_MAGIC 0x15013346 7#define UDF_SUPER_MAGIC 0x15013346
6 8
7#define UDF_MAX_READ_VERSION 0x0201 9#define UDF_MAX_READ_VERSION 0x0250
8#define UDF_MAX_WRITE_VERSION 0x0201 10#define UDF_MAX_WRITE_VERSION 0x0201
9 11
10#define UDF_FLAG_USE_EXTENDED_FE 0 12#define UDF_FLAG_USE_EXTENDED_FE 0
@@ -38,6 +40,111 @@
38#define UDF_PART_FLAG_REWRITABLE 0x0040 40#define UDF_PART_FLAG_REWRITABLE 0x0040
39#define UDF_PART_FLAG_OVERWRITABLE 0x0080 41#define UDF_PART_FLAG_OVERWRITABLE 0x0080
40 42
43#define UDF_MAX_BLOCK_LOADED 8
44
45#define UDF_TYPE1_MAP15 0x1511U
46#define UDF_VIRTUAL_MAP15 0x1512U
47#define UDF_VIRTUAL_MAP20 0x2012U
48#define UDF_SPARABLE_MAP15 0x1522U
49#define UDF_METADATA_MAP25 0x2511U
50
51#pragma pack(1) /* XXX(hch): Why? This file just defines in-core structures */
52
53struct udf_meta_data {
54 __u32 s_meta_file_loc;
55 __u32 s_mirror_file_loc;
56 __u32 s_bitmap_file_loc;
57 __u32 s_alloc_unit_size;
58 __u16 s_align_unit_size;
59 __u8 s_dup_md_flag;
60 struct inode *s_metadata_fe;
61 struct inode *s_mirror_fe;
62 struct inode *s_bitmap_fe;
63};
64
65struct udf_sparing_data {
66 __u16 s_packet_len;
67 struct buffer_head *s_spar_map[4];
68};
69
70struct udf_virtual_data {
71 __u32 s_num_entries;
72 __u16 s_start_offset;
73};
74
75struct udf_bitmap {
76 __u32 s_extLength;
77 __u32 s_extPosition;
78 __u16 s_nr_groups;
79 struct buffer_head **s_block_bitmap;
80};
81
82struct udf_part_map {
83 union {
84 struct udf_bitmap *s_bitmap;
85 struct inode *s_table;
86 } s_uspace;
87 union {
88 struct udf_bitmap *s_bitmap;
89 struct inode *s_table;
90 } s_fspace;
91 __u32 s_partition_root;
92 __u32 s_partition_len;
93 __u16 s_partition_type;
94 __u16 s_partition_num;
95 union {
96 struct udf_sparing_data s_sparing;
97 struct udf_virtual_data s_virtual;
98 struct udf_meta_data s_metadata;
99 } s_type_specific;
100 __u32 (*s_partition_func)(struct super_block *, __u32, __u16, __u32);
101 __u16 s_volumeseqnum;
102 __u16 s_partition_flags;
103};
104
105#pragma pack()
106
107struct udf_sb_info {
108 struct udf_part_map *s_partmaps;
109 __u8 s_volume_ident[32];
110
111 /* Overall info */
112 __u16 s_partitions;
113 __u16 s_partition;
114
115 /* Sector headers */
116 __s32 s_session;
117 __u32 s_anchor[3];
118 __u32 s_last_block;
119
120 struct buffer_head *s_lvid_bh;
121
122 /* Default permissions */
123 mode_t s_umask;
124 gid_t s_gid;
125 uid_t s_uid;
126
127 /* Root Info */
128 struct timespec s_record_time;
129
130 /* Fileset Info */
131 __u16 s_serial_number;
132
133 /* highest UDF revision we have recorded to this media */
134 __u16 s_udfrev;
135
136 /* Miscellaneous flags */
137 __u32 s_flags;
138
139 /* Encoding info */
140 struct nls_table *s_nls_map;
141
142 /* VAT inode */
143 struct inode *s_vat_inode;
144
145 struct mutex s_alloc_mutex;
146};
147
41static inline struct udf_sb_info *UDF_SB(struct super_block *sb) 148static inline struct udf_sb_info *UDF_SB(struct super_block *sb)
42{ 149{
43 return sb->s_fs_info; 150 return sb->s_fs_info;
diff --git a/fs/udf/udfdecl.h b/fs/udf/udfdecl.h
index 681dc2b66cdb..f3f45d029277 100644
--- a/fs/udf/udfdecl.h
+++ b/fs/udf/udfdecl.h
@@ -1,17 +1,37 @@
1#ifndef __UDF_DECL_H 1#ifndef __UDF_DECL_H
2#define __UDF_DECL_H 2#define __UDF_DECL_H
3 3
4#include <linux/udf_fs.h>
5#include "ecma_167.h" 4#include "ecma_167.h"
6#include "osta_udf.h" 5#include "osta_udf.h"
7 6
8#include <linux/fs.h> 7#include <linux/fs.h>
9#include <linux/types.h> 8#include <linux/types.h>
10#include <linux/udf_fs_i.h>
11#include <linux/udf_fs_sb.h>
12#include <linux/buffer_head.h> 9#include <linux/buffer_head.h>
10#include <linux/udf_fs_i.h>
13 11
12#include "udf_sb.h"
14#include "udfend.h" 13#include "udfend.h"
14#include "udf_i.h"
15
16#define UDF_PREALLOCATE
17#define UDF_DEFAULT_PREALLOC_BLOCKS 8
18
19#define UDFFS_DEBUG
20
21#ifdef UDFFS_DEBUG
22#define udf_debug(f, a...) \
23do { \
24 printk(KERN_DEBUG "UDF-fs DEBUG %s:%d:%s: ", \
25 __FILE__, __LINE__, __func__); \
26 printk(f, ##a); \
27} while (0)
28#else
29#define udf_debug(f, a...) /**/
30#endif
31
32#define udf_info(f, a...) \
33 printk(KERN_INFO "UDF-fs INFO " f, ##a);
34
15 35
16#define udf_fixed_to_variable(x) ( ( ( (x) >> 5 ) * 39 ) + ( (x) & 0x0000001F ) ) 36#define udf_fixed_to_variable(x) ( ( ( (x) >> 5 ) * 39 ) + ( (x) & 0x0000001F ) )
17#define udf_variable_to_fixed(x) ( ( ( (x) / 39 ) << 5 ) + ( (x) % 39 ) ) 37#define udf_variable_to_fixed(x) ( ( ( (x) / 39 ) << 5 ) + ( (x) % 39 ) )
@@ -23,16 +43,24 @@
23#define UDF_NAME_LEN 256 43#define UDF_NAME_LEN 256
24#define UDF_PATH_LEN 1023 44#define UDF_PATH_LEN 1023
25 45
26#define udf_file_entry_alloc_offset(inode)\ 46static inline size_t udf_file_entry_alloc_offset(struct inode *inode)
27 (UDF_I(inode)->i_use ?\ 47{
28 sizeof(struct unallocSpaceEntry) :\ 48 struct udf_inode_info *iinfo = UDF_I(inode);
29 ((UDF_I(inode)->i_efe ?\ 49 if (iinfo->i_use)
30 sizeof(struct extendedFileEntry) :\ 50 return sizeof(struct unallocSpaceEntry);
31 sizeof(struct fileEntry)) + UDF_I(inode)->i_lenEAttr)) 51 else if (iinfo->i_efe)
32 52 return sizeof(struct extendedFileEntry) + iinfo->i_lenEAttr;
33#define udf_ext0_offset(inode)\ 53 else
34 (UDF_I(inode)->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB ?\ 54 return sizeof(struct fileEntry) + iinfo->i_lenEAttr;
35 udf_file_entry_alloc_offset(inode) : 0) 55}
56
57static inline size_t udf_ext0_offset(struct inode *inode)
58{
59 if (UDF_I(inode)->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB)
60 return udf_file_entry_alloc_offset(inode);
61 else
62 return 0;
63}
36 64
37#define udf_get_lb_pblock(sb,loc,offset) udf_get_pblock((sb), (loc).logicalBlockNum, (loc).partitionReferenceNum, (offset)) 65#define udf_get_lb_pblock(sb,loc,offset) udf_get_pblock((sb), (loc).logicalBlockNum, (loc).partitionReferenceNum, (offset))
38 66
@@ -83,7 +111,6 @@ struct extent_position {
83}; 111};
84 112
85/* super.c */ 113/* super.c */
86extern void udf_error(struct super_block *, const char *, const char *, ...);
87extern void udf_warning(struct super_block *, const char *, const char *, ...); 114extern void udf_warning(struct super_block *, const char *, const char *, ...);
88 115
89/* namei.c */ 116/* namei.c */
@@ -150,6 +177,8 @@ extern uint32_t udf_get_pblock_virt20(struct super_block *, uint32_t, uint16_t,
150 uint32_t); 177 uint32_t);
151extern uint32_t udf_get_pblock_spar15(struct super_block *, uint32_t, uint16_t, 178extern uint32_t udf_get_pblock_spar15(struct super_block *, uint32_t, uint16_t,
152 uint32_t); 179 uint32_t);
180extern uint32_t udf_get_pblock_meta25(struct super_block *, uint32_t, uint16_t,
181 uint32_t);
153extern int udf_relocate_blocks(struct super_block *, long, long *); 182extern int udf_relocate_blocks(struct super_block *, long, long *);
154 183
155/* unicode.c */ 184/* unicode.c */
@@ -157,7 +186,7 @@ extern int udf_get_filename(struct super_block *, uint8_t *, uint8_t *, int);
157extern int udf_put_filename(struct super_block *, const uint8_t *, uint8_t *, 186extern int udf_put_filename(struct super_block *, const uint8_t *, uint8_t *,
158 int); 187 int);
159extern int udf_build_ustr(struct ustr *, dstring *, int); 188extern int udf_build_ustr(struct ustr *, dstring *, int);
160extern int udf_CS0toUTF8(struct ustr *, struct ustr *); 189extern int udf_CS0toUTF8(struct ustr *, const struct ustr *);
161 190
162/* ialloc.c */ 191/* ialloc.c */
163extern void udf_free_inode(struct inode *); 192extern void udf_free_inode(struct inode *);
@@ -191,11 +220,9 @@ extern struct fileIdentDesc *udf_get_fileident(void *buffer, int bufsize,
191extern long_ad *udf_get_filelongad(uint8_t *, int, uint32_t *, int); 220extern long_ad *udf_get_filelongad(uint8_t *, int, uint32_t *, int);
192extern short_ad *udf_get_fileshortad(uint8_t *, int, uint32_t *, int); 221extern short_ad *udf_get_fileshortad(uint8_t *, int, uint32_t *, int);
193 222
194/* crc.c */
195extern uint16_t udf_crc(uint8_t *, uint32_t, uint16_t);
196
197/* udftime.c */ 223/* udftime.c */
198extern time_t *udf_stamp_to_time(time_t *, long *, kernel_timestamp); 224extern struct timespec *udf_disk_stamp_to_time(struct timespec *dest,
199extern kernel_timestamp *udf_time_to_stamp(kernel_timestamp *, struct timespec); 225 timestamp src);
226extern timestamp *udf_time_to_disk_stamp(timestamp *dest, struct timespec src);
200 227
201#endif /* __UDF_DECL_H */ 228#endif /* __UDF_DECL_H */
diff --git a/fs/udf/udfend.h b/fs/udf/udfend.h
index c4bd1203f857..489f52fb428c 100644
--- a/fs/udf/udfend.h
+++ b/fs/udf/udfend.h
@@ -24,17 +24,6 @@ static inline lb_addr cpu_to_lelb(kernel_lb_addr in)
24 return out; 24 return out;
25} 25}
26 26
27static inline kernel_timestamp lets_to_cpu(timestamp in)
28{
29 kernel_timestamp out;
30
31 memcpy(&out, &in, sizeof(timestamp));
32 out.typeAndTimezone = le16_to_cpu(in.typeAndTimezone);
33 out.year = le16_to_cpu(in.year);
34
35 return out;
36}
37
38static inline short_ad lesa_to_cpu(short_ad in) 27static inline short_ad lesa_to_cpu(short_ad in)
39{ 28{
40 short_ad out; 29 short_ad out;
@@ -85,15 +74,4 @@ static inline kernel_extent_ad leea_to_cpu(extent_ad in)
85 return out; 74 return out;
86} 75}
87 76
88static inline timestamp cpu_to_lets(kernel_timestamp in)
89{
90 timestamp out;
91
92 memcpy(&out, &in, sizeof(timestamp));
93 out.typeAndTimezone = cpu_to_le16(in.typeAndTimezone);
94 out.year = cpu_to_le16(in.year);
95
96 return out;
97}
98
99#endif /* __UDF_ENDIAN_H */ 77#endif /* __UDF_ENDIAN_H */
diff --git a/fs/udf/udftime.c b/fs/udf/udftime.c
index ce595732ba6f..5f811655c9b5 100644
--- a/fs/udf/udftime.c
+++ b/fs/udf/udftime.c
@@ -85,39 +85,38 @@ extern struct timezone sys_tz;
85#define SECS_PER_HOUR (60 * 60) 85#define SECS_PER_HOUR (60 * 60)
86#define SECS_PER_DAY (SECS_PER_HOUR * 24) 86#define SECS_PER_DAY (SECS_PER_HOUR * 24)
87 87
88time_t *udf_stamp_to_time(time_t *dest, long *dest_usec, kernel_timestamp src) 88struct timespec *udf_disk_stamp_to_time(struct timespec *dest, timestamp src)
89{ 89{
90 int yday; 90 int yday;
91 uint8_t type = src.typeAndTimezone >> 12; 91 u16 typeAndTimezone = le16_to_cpu(src.typeAndTimezone);
92 u16 year = le16_to_cpu(src.year);
93 uint8_t type = typeAndTimezone >> 12;
92 int16_t offset; 94 int16_t offset;
93 95
94 if (type == 1) { 96 if (type == 1) {
95 offset = src.typeAndTimezone << 4; 97 offset = typeAndTimezone << 4;
96 /* sign extent offset */ 98 /* sign extent offset */
97 offset = (offset >> 4); 99 offset = (offset >> 4);
98 if (offset == -2047) /* unspecified offset */ 100 if (offset == -2047) /* unspecified offset */
99 offset = 0; 101 offset = 0;
100 } else { 102 } else
101 offset = 0; 103 offset = 0;
102 }
103 104
104 if ((src.year < EPOCH_YEAR) || 105 if ((year < EPOCH_YEAR) ||
105 (src.year >= EPOCH_YEAR + MAX_YEAR_SECONDS)) { 106 (year >= EPOCH_YEAR + MAX_YEAR_SECONDS)) {
106 *dest = -1;
107 *dest_usec = -1;
108 return NULL; 107 return NULL;
109 } 108 }
110 *dest = year_seconds[src.year - EPOCH_YEAR]; 109 dest->tv_sec = year_seconds[year - EPOCH_YEAR];
111 *dest -= offset * 60; 110 dest->tv_sec -= offset * 60;
112 111
113 yday = ((__mon_yday[__isleap(src.year)][src.month - 1]) + src.day - 1); 112 yday = ((__mon_yday[__isleap(year)][src.month - 1]) + src.day - 1);
114 *dest += (((yday * 24) + src.hour) * 60 + src.minute) * 60 + src.second; 113 dest->tv_sec += (((yday * 24) + src.hour) * 60 + src.minute) * 60 + src.second;
115 *dest_usec = src.centiseconds * 10000 + 114 dest->tv_nsec = 1000 * (src.centiseconds * 10000 +
116 src.hundredsOfMicroseconds * 100 + src.microseconds; 115 src.hundredsOfMicroseconds * 100 + src.microseconds);
117 return dest; 116 return dest;
118} 117}
119 118
120kernel_timestamp *udf_time_to_stamp(kernel_timestamp *dest, struct timespec ts) 119timestamp *udf_time_to_disk_stamp(timestamp *dest, struct timespec ts)
121{ 120{
122 long int days, rem, y; 121 long int days, rem, y;
123 const unsigned short int *ip; 122 const unsigned short int *ip;
@@ -128,7 +127,7 @@ kernel_timestamp *udf_time_to_stamp(kernel_timestamp *dest, struct timespec ts)
128 if (!dest) 127 if (!dest)
129 return NULL; 128 return NULL;
130 129
131 dest->typeAndTimezone = 0x1000 | (offset & 0x0FFF); 130 dest->typeAndTimezone = cpu_to_le16(0x1000 | (offset & 0x0FFF));
132 131
133 ts.tv_sec += offset * 60; 132 ts.tv_sec += offset * 60;
134 days = ts.tv_sec / SECS_PER_DAY; 133 days = ts.tv_sec / SECS_PER_DAY;
@@ -151,7 +150,7 @@ kernel_timestamp *udf_time_to_stamp(kernel_timestamp *dest, struct timespec ts)
151 - LEAPS_THRU_END_OF(y - 1)); 150 - LEAPS_THRU_END_OF(y - 1));
152 y = yg; 151 y = yg;
153 } 152 }
154 dest->year = y; 153 dest->year = cpu_to_le16(y);
155 ip = __mon_yday[__isleap(y)]; 154 ip = __mon_yday[__isleap(y)];
156 for (y = 11; days < (long int)ip[y]; --y) 155 for (y = 11; days < (long int)ip[y]; --y)
157 continue; 156 continue;
diff --git a/fs/udf/unicode.c b/fs/udf/unicode.c
index e533b11703bf..9fdf8c93c58e 100644
--- a/fs/udf/unicode.c
+++ b/fs/udf/unicode.c
@@ -23,7 +23,7 @@
23#include <linux/kernel.h> 23#include <linux/kernel.h>
24#include <linux/string.h> /* for memset */ 24#include <linux/string.h> /* for memset */
25#include <linux/nls.h> 25#include <linux/nls.h>
26#include <linux/udf_fs.h> 26#include <linux/crc-itu-t.h>
27 27
28#include "udf_sb.h" 28#include "udf_sb.h"
29 29
@@ -49,14 +49,16 @@ int udf_build_ustr(struct ustr *dest, dstring *ptr, int size)
49{ 49{
50 int usesize; 50 int usesize;
51 51
52 if ((!dest) || (!ptr) || (!size)) 52 if (!dest || !ptr || !size)
53 return -1; 53 return -1;
54 BUG_ON(size < 2);
54 55
55 memset(dest, 0, sizeof(struct ustr)); 56 usesize = min_t(size_t, ptr[size - 1], sizeof(dest->u_name));
56 usesize = (size > UDF_NAME_LEN) ? UDF_NAME_LEN : size; 57 usesize = min(usesize, size - 2);
57 dest->u_cmpID = ptr[0]; 58 dest->u_cmpID = ptr[0];
58 dest->u_len = ptr[size - 1]; 59 dest->u_len = usesize;
59 memcpy(dest->u_name, ptr + 1, usesize - 1); 60 memcpy(dest->u_name, ptr + 1, usesize);
61 memset(dest->u_name + usesize, 0, sizeof(dest->u_name) - usesize);
60 62
61 return 0; 63 return 0;
62} 64}
@@ -83,9 +85,6 @@ static int udf_build_ustr_exact(struct ustr *dest, dstring *ptr, int exactsize)
83 * PURPOSE 85 * PURPOSE
84 * Convert OSTA Compressed Unicode to the UTF-8 equivalent. 86 * Convert OSTA Compressed Unicode to the UTF-8 equivalent.
85 * 87 *
86 * DESCRIPTION
87 * This routine is only called by udf_filldir().
88 *
89 * PRE-CONDITIONS 88 * PRE-CONDITIONS
90 * utf Pointer to UTF-8 output buffer. 89 * utf Pointer to UTF-8 output buffer.
91 * ocu Pointer to OSTA Compressed Unicode input buffer 90 * ocu Pointer to OSTA Compressed Unicode input buffer
@@ -99,43 +98,39 @@ static int udf_build_ustr_exact(struct ustr *dest, dstring *ptr, int exactsize)
99 * November 12, 1997 - Andrew E. Mileski 98 * November 12, 1997 - Andrew E. Mileski
100 * Written, tested, and released. 99 * Written, tested, and released.
101 */ 100 */
102int udf_CS0toUTF8(struct ustr *utf_o, struct ustr *ocu_i) 101int udf_CS0toUTF8(struct ustr *utf_o, const struct ustr *ocu_i)
103{ 102{
104 uint8_t *ocu; 103 const uint8_t *ocu;
105 uint32_t c;
106 uint8_t cmp_id, ocu_len; 104 uint8_t cmp_id, ocu_len;
107 int i; 105 int i;
108 106
109 ocu = ocu_i->u_name;
110
111 ocu_len = ocu_i->u_len; 107 ocu_len = ocu_i->u_len;
112 cmp_id = ocu_i->u_cmpID;
113 utf_o->u_len = 0;
114
115 if (ocu_len == 0) { 108 if (ocu_len == 0) {
116 memset(utf_o, 0, sizeof(struct ustr)); 109 memset(utf_o, 0, sizeof(struct ustr));
117 utf_o->u_cmpID = 0;
118 utf_o->u_len = 0;
119 return 0; 110 return 0;
120 } 111 }
121 112
122 if ((cmp_id != 8) && (cmp_id != 16)) { 113 cmp_id = ocu_i->u_cmpID;
114 if (cmp_id != 8 && cmp_id != 16) {
115 memset(utf_o, 0, sizeof(struct ustr));
123 printk(KERN_ERR "udf: unknown compression code (%d) stri=%s\n", 116 printk(KERN_ERR "udf: unknown compression code (%d) stri=%s\n",
124 cmp_id, ocu_i->u_name); 117 cmp_id, ocu_i->u_name);
125 return 0; 118 return 0;
126 } 119 }
127 120
121 ocu = ocu_i->u_name;
122 utf_o->u_len = 0;
128 for (i = 0; (i < ocu_len) && (utf_o->u_len <= (UDF_NAME_LEN - 3));) { 123 for (i = 0; (i < ocu_len) && (utf_o->u_len <= (UDF_NAME_LEN - 3));) {
129 124
130 /* Expand OSTA compressed Unicode to Unicode */ 125 /* Expand OSTA compressed Unicode to Unicode */
131 c = ocu[i++]; 126 uint32_t c = ocu[i++];
132 if (cmp_id == 16) 127 if (cmp_id == 16)
133 c = (c << 8) | ocu[i++]; 128 c = (c << 8) | ocu[i++];
134 129
135 /* Compress Unicode to UTF-8 */ 130 /* Compress Unicode to UTF-8 */
136 if (c < 0x80U) { 131 if (c < 0x80U)
137 utf_o->u_name[utf_o->u_len++] = (uint8_t)c; 132 utf_o->u_name[utf_o->u_len++] = (uint8_t)c;
138 } else if (c < 0x800U) { 133 else if (c < 0x800U) {
139 utf_o->u_name[utf_o->u_len++] = 134 utf_o->u_name[utf_o->u_len++] =
140 (uint8_t)(0xc0 | (c >> 6)); 135 (uint8_t)(0xc0 | (c >> 6));
141 utf_o->u_name[utf_o->u_len++] = 136 utf_o->u_name[utf_o->u_len++] =
@@ -255,35 +250,32 @@ error_out:
255} 250}
256 251
257static int udf_CS0toNLS(struct nls_table *nls, struct ustr *utf_o, 252static int udf_CS0toNLS(struct nls_table *nls, struct ustr *utf_o,
258 struct ustr *ocu_i) 253 const struct ustr *ocu_i)
259{ 254{
260 uint8_t *ocu; 255 const uint8_t *ocu;
261 uint32_t c;
262 uint8_t cmp_id, ocu_len; 256 uint8_t cmp_id, ocu_len;
263 int i; 257 int i;
264 258
265 ocu = ocu_i->u_name;
266 259
267 ocu_len = ocu_i->u_len; 260 ocu_len = ocu_i->u_len;
268 cmp_id = ocu_i->u_cmpID;
269 utf_o->u_len = 0;
270
271 if (ocu_len == 0) { 261 if (ocu_len == 0) {
272 memset(utf_o, 0, sizeof(struct ustr)); 262 memset(utf_o, 0, sizeof(struct ustr));
273 utf_o->u_cmpID = 0;
274 utf_o->u_len = 0;
275 return 0; 263 return 0;
276 } 264 }
277 265
278 if ((cmp_id != 8) && (cmp_id != 16)) { 266 cmp_id = ocu_i->u_cmpID;
267 if (cmp_id != 8 && cmp_id != 16) {
268 memset(utf_o, 0, sizeof(struct ustr));
279 printk(KERN_ERR "udf: unknown compression code (%d) stri=%s\n", 269 printk(KERN_ERR "udf: unknown compression code (%d) stri=%s\n",
280 cmp_id, ocu_i->u_name); 270 cmp_id, ocu_i->u_name);
281 return 0; 271 return 0;
282 } 272 }
283 273
274 ocu = ocu_i->u_name;
275 utf_o->u_len = 0;
284 for (i = 0; (i < ocu_len) && (utf_o->u_len <= (UDF_NAME_LEN - 3));) { 276 for (i = 0; (i < ocu_len) && (utf_o->u_len <= (UDF_NAME_LEN - 3));) {
285 /* Expand OSTA compressed Unicode to Unicode */ 277 /* Expand OSTA compressed Unicode to Unicode */
286 c = ocu[i++]; 278 uint32_t c = ocu[i++];
287 if (cmp_id == 16) 279 if (cmp_id == 16)
288 c = (c << 8) | ocu[i++]; 280 c = (c << 8) | ocu[i++];
289 281
@@ -463,7 +455,7 @@ static int udf_translate_to_linux(uint8_t *newName, uint8_t *udfName,
463 } else if (newIndex > 250) 455 } else if (newIndex > 250)
464 newIndex = 250; 456 newIndex = 250;
465 newName[newIndex++] = CRC_MARK; 457 newName[newIndex++] = CRC_MARK;
466 valueCRC = udf_crc(fidName, fidNameLen, 0); 458 valueCRC = crc_itu_t(0, fidName, fidNameLen);
467 newName[newIndex++] = hexChar[(valueCRC & 0xf000) >> 12]; 459 newName[newIndex++] = hexChar[(valueCRC & 0xf000) >> 12];
468 newName[newIndex++] = hexChar[(valueCRC & 0x0f00) >> 8]; 460 newName[newIndex++] = hexChar[(valueCRC & 0x0f00) >> 8];
469 newName[newIndex++] = hexChar[(valueCRC & 0x00f0) >> 4]; 461 newName[newIndex++] = hexChar[(valueCRC & 0x00f0) >> 4];
diff --git a/include/asm-arm/arch-omap/mmc.h b/include/asm-arm/arch-omap/mmc.h
index b70e37b61242..c9588f49eb52 100644
--- a/include/asm-arm/arch-omap/mmc.h
+++ b/include/asm-arm/arch-omap/mmc.h
@@ -18,6 +18,8 @@
18#define OMAP_MMC_MAX_SLOTS 2 18#define OMAP_MMC_MAX_SLOTS 2
19 19
20struct omap_mmc_platform_data { 20struct omap_mmc_platform_data {
21 struct omap_mmc_conf conf;
22
21 unsigned enabled:1; 23 unsigned enabled:1;
22 /* number of slots on board */ 24 /* number of slots on board */
23 unsigned nr_slots:2; 25 unsigned nr_slots:2;
diff --git a/include/asm-sh/i2c-sh7760.h b/include/asm-sh/i2c-sh7760.h
new file mode 100644
index 000000000000..24182116711f
--- /dev/null
+++ b/include/asm-sh/i2c-sh7760.h
@@ -0,0 +1,22 @@
1/*
2 * MMIO/IRQ and platform data for SH7760 I2C channels
3 */
4
5#ifndef _I2C_SH7760_H_
6#define _I2C_SH7760_H_
7
8#define SH7760_I2C_DEVNAME "sh7760-i2c"
9
10#define SH7760_I2C0_MMIO 0xFE140000
11#define SH7760_I2C0_MMIOEND 0xFE14003B
12#define SH7760_I2C0_IRQ 62
13
14#define SH7760_I2C1_MMIO 0xFE150000
15#define SH7760_I2C1_MMIOEND 0xFE15003B
16#define SH7760_I2C1_IRQ 63
17
18struct sh7760_i2c_platdata {
19 unsigned int speed_khz;
20};
21
22#endif
diff --git a/include/asm-sparc/Kbuild b/include/asm-sparc/Kbuild
index c6a55cf0d337..671223718f0a 100644
--- a/include/asm-sparc/Kbuild
+++ b/include/asm-sparc/Kbuild
@@ -5,7 +5,6 @@ header-y += asi.h
5header-y += bpp.h 5header-y += bpp.h
6header-y += jsflash.h 6header-y += jsflash.h
7header-y += openpromio.h 7header-y += openpromio.h
8header-y += pconf.h
9header-y += reg.h 8header-y += reg.h
10header-y += traps.h 9header-y += traps.h
11header-y += vfc_ioctls.h 10header-y += vfc_ioctls.h
diff --git a/include/asm-sparc/a.out-core.h b/include/asm-sparc/a.out-core.h
deleted file mode 100644
index e8fd338ed0b2..000000000000
--- a/include/asm-sparc/a.out-core.h
+++ /dev/null
@@ -1,52 +0,0 @@
1/* a.out coredump register dumper
2 *
3 * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public Licence
8 * as published by the Free Software Foundation; either version
9 * 2 of the Licence, or (at your option) any later version.
10 */
11
12#ifndef _ASM_A_OUT_CORE_H
13#define _ASM_A_OUT_CORE_H
14
15#ifdef __KERNEL__
16
17#include <linux/user.h>
18
19/*
20 * fill in the user structure for an a.out core dump
21 */
22static inline void aout_dump_thread(struct pt_regs *regs, struct user *dump)
23{
24 unsigned long first_stack_page;
25
26 dump->magic = SUNOS_CORE_MAGIC;
27 dump->len = sizeof(struct user);
28 dump->regs.psr = regs->psr;
29 dump->regs.pc = regs->pc;
30 dump->regs.npc = regs->npc;
31 dump->regs.y = regs->y;
32 /* fuck me plenty */
33 memcpy(&dump->regs.regs[0], &regs->u_regs[1], (sizeof(unsigned long) * 15));
34 dump->uexec = current->thread.core_exec;
35 dump->u_tsize = (((unsigned long) current->mm->end_code) -
36 ((unsigned long) current->mm->start_code)) & ~(PAGE_SIZE - 1);
37 dump->u_dsize = ((unsigned long) (current->mm->brk + (PAGE_SIZE-1)));
38 dump->u_dsize -= dump->u_tsize;
39 dump->u_dsize &= ~(PAGE_SIZE - 1);
40 first_stack_page = (regs->u_regs[UREG_FP] & ~(PAGE_SIZE - 1));
41 dump->u_ssize = (TASK_SIZE - first_stack_page) & ~(PAGE_SIZE - 1);
42 memcpy(&dump->fpu.fpstatus.fregs.regs[0], &current->thread.float_regs[0], (sizeof(unsigned long) * 32));
43 dump->fpu.fpstatus.fsr = current->thread.fsr;
44 dump->fpu.fpstatus.flags = dump->fpu.fpstatus.extra = 0;
45 dump->fpu.fpstatus.fpq_count = current->thread.fpqdepth;
46 memcpy(&dump->fpu.fpstatus.fpq[0], &current->thread.fpqueue[0],
47 ((sizeof(unsigned long) * 2) * 16));
48 dump->sigcode = 0;
49}
50
51#endif /* __KERNEL__ */
52#endif /* _ASM_A_OUT_CORE_H */
diff --git a/include/asm-sparc/a.out.h b/include/asm-sparc/a.out.h
deleted file mode 100644
index 2f1c3748a068..000000000000
--- a/include/asm-sparc/a.out.h
+++ /dev/null
@@ -1,97 +0,0 @@
1#ifndef __SPARC_A_OUT_H__
2#define __SPARC_A_OUT_H__
3
4#define SPARC_PGSIZE 0x2000 /* Thanks to the sun4 architecture... */
5#define SEGMENT_SIZE SPARC_PGSIZE /* whee... */
6
7#ifndef __ASSEMBLY__
8
9struct exec {
10 unsigned char a_dynamic:1; /* A __DYNAMIC is in this image */
11 unsigned char a_toolversion:7;
12 unsigned char a_machtype;
13 unsigned short a_info;
14 unsigned int a_text; /* length of text, in bytes */
15 unsigned int a_data; /* length of data, in bytes */
16 unsigned int a_bss; /* length of bss, in bytes */
17 unsigned int a_syms; /* length of symbol table, in bytes */
18 unsigned int a_entry; /* where program begins */
19 unsigned int a_trsize;
20 unsigned int a_drsize;
21};
22
23#endif /* !__ASSEMBLY__ */
24
25/* Where in the file does the text information begin? */
26#define N_TXTOFF(x) (N_MAGIC(x) == ZMAGIC ? 0 : sizeof (struct exec))
27
28/* Where do the Symbols start? */
29#define N_SYMOFF(x) (N_TXTOFF(x) + (x).a_text + \
30 (x).a_data + (x).a_trsize + \
31 (x).a_drsize)
32
33/* Where does text segment go in memory after being loaded? */
34#define N_TXTADDR(x) (unsigned long)(((N_MAGIC(x) == ZMAGIC) && \
35 ((x).a_entry < SPARC_PGSIZE)) ? \
36 0 : SPARC_PGSIZE)
37
38/* And same for the data segment.. */
39#define N_DATADDR(x) (N_MAGIC(x)==OMAGIC ? \
40 (N_TXTADDR(x) + (x).a_text) \
41 : (unsigned long) (_N_SEGMENT_ROUND (_N_TXTENDADDR(x))))
42
43#define N_TRSIZE(a) ((a).a_trsize)
44#define N_DRSIZE(a) ((a).a_drsize)
45#define N_SYMSIZE(a) ((a).a_syms)
46
47#ifndef __ASSEMBLY__
48
49/*
50 * Sparc relocation types
51 */
52enum reloc_type
53{
54 RELOC_8,
55 RELOC_16,
56 RELOC_32, /* simplest relocs */
57 RELOC_DISP8,
58 RELOC_DISP16,
59 RELOC_DISP32, /* Disp's (pc-rel) */
60 RELOC_WDISP30,
61 RELOC_WDISP22, /* SR word disp's */
62 RELOC_HI22,
63 RELOC_22, /* SR 22-bit relocs */
64 RELOC_13,
65 RELOC_LO10, /* SR 13&10-bit relocs */
66 RELOC_SFA_BASE,
67 RELOC_SFA_OFF13, /* SR S.F.A. relocs */
68 RELOC_BASE10,
69 RELOC_BASE13,
70 RELOC_BASE22, /* base_relative pic */
71 RELOC_PC10,
72 RELOC_PC22, /* special pc-rel pic */
73 RELOC_JMP_TBL, /* jmp_tbl_rel in pic */
74 RELOC_SEGOFF16, /* ShLib offset-in-seg */
75 RELOC_GLOB_DAT,
76 RELOC_JMP_SLOT,
77 RELOC_RELATIVE /* rtld relocs */
78};
79
80/*
81 * Format of a relocation datum.
82 */
83struct relocation_info /* used when header.a_machtype == M_SPARC */
84{
85 unsigned int r_address; /* relocation addr */
86 unsigned int r_index:24; /* segment index or symbol index */
87 unsigned int r_extern:1; /* if F, r_index==SEG#; if T, SYM idx */
88 unsigned int r_pad:2; /* <unused> */
89 enum reloc_type r_type:5; /* type of relocation to perform */
90 int r_addend; /* addend for relocation value */
91};
92
93#define N_RELOCATION_INFO_DECLARED 1
94
95#endif /* !(__ASSEMBLY__) */
96
97#endif /* __SPARC_A_OUT_H__ */
diff --git a/include/asm-sparc/head.h b/include/asm-sparc/head.h
index 1a03c28da92d..fcdba5116339 100644
--- a/include/asm-sparc/head.h
+++ b/include/asm-sparc/head.h
@@ -46,45 +46,12 @@
46 b linux_sparc_syscall; \ 46 b linux_sparc_syscall; \
47 rd %psr, %l0; 47 rd %psr, %l0;
48 48
49/* Software trap for SunOS4.1.x system calls. */
50#define SUNOS_SYSCALL_TRAP \
51 rd %psr, %l0; \
52 sethi %hi(sunos_sys_table), %l7; \
53 b linux_sparc_syscall; \
54 or %l7, %lo(sunos_sys_table), %l7;
55
56#define SUNOS_NO_SYSCALL_TRAP \
57 b sunos_syscall; \
58 rd %psr, %l0; \
59 nop; \
60 nop;
61
62/* Software trap for Slowaris system calls. */
63#define SOLARIS_SYSCALL_TRAP \
64 b solaris_syscall; \
65 rd %psr, %l0; \
66 nop; \
67 nop;
68
69#define INDIRECT_SOLARIS_SYSCALL(x) \
70 mov x, %g1; \
71 b solaris_syscall; \
72 rd %psr, %l0; \
73 nop;
74
75#define BREAKPOINT_TRAP \ 49#define BREAKPOINT_TRAP \
76 b breakpoint_trap; \ 50 b breakpoint_trap; \
77 rd %psr,%l0; \ 51 rd %psr,%l0; \
78 nop; \ 52 nop; \
79 nop; 53 nop;
80 54
81/* Software trap for Sparc-netbsd system calls. */
82#define NETBSD_SYSCALL_TRAP \
83 sethi %hi(sys_call_table), %l7; \
84 or %l7, %lo(sys_call_table), %l7; \
85 b bsd_syscall; \
86 rd %psr, %l0;
87
88/* The Get Condition Codes software trap for userland. */ 55/* The Get Condition Codes software trap for userland. */
89#define GETCC_TRAP \ 56#define GETCC_TRAP \
90 b getcc_trap_handler; mov %psr, %l0; nop; nop; 57 b getcc_trap_handler; mov %psr, %l0; nop; nop;
diff --git a/include/asm-sparc/ioctls.h b/include/asm-sparc/ioctls.h
index 058c2064f706..3f4d0087b6a3 100644
--- a/include/asm-sparc/ioctls.h
+++ b/include/asm-sparc/ioctls.h
@@ -43,8 +43,6 @@
43#define __TIOCSETX _IOW('t', 34, int) /* SunOS Specific */ 43#define __TIOCSETX _IOW('t', 34, int) /* SunOS Specific */
44#define __TIOCGETX _IOR('t', 35, int) /* SunOS Specific */ 44#define __TIOCGETX _IOR('t', 35, int) /* SunOS Specific */
45#define TIOCCONS _IO('t', 36) 45#define TIOCCONS _IO('t', 36)
46#define __TIOCSSIZE _IOW('t', 37, struct sunos_ttysize) /* SunOS Specific */
47#define __TIOCGSIZE _IOR('t', 38, struct sunos_ttysize) /* SunOS Specific */
48#define TIOCGSOFTCAR _IOR('t', 100, int) 46#define TIOCGSOFTCAR _IOR('t', 100, int)
49#define TIOCSSOFTCAR _IOW('t', 101, int) 47#define TIOCSSOFTCAR _IOW('t', 101, int)
50#define __TIOCUCNTL _IOW('t', 102, int) /* SunOS Specific */ 48#define __TIOCUCNTL _IOW('t', 102, int) /* SunOS Specific */
diff --git a/include/asm-sparc/mman.h b/include/asm-sparc/mman.h
index b7dc40bc68f4..e18be984c01d 100644
--- a/include/asm-sparc/mman.h
+++ b/include/asm-sparc/mman.h
@@ -22,19 +22,6 @@
22#define MAP_POPULATE 0x8000 /* populate (prefault) pagetables */ 22#define MAP_POPULATE 0x8000 /* populate (prefault) pagetables */
23#define MAP_NONBLOCK 0x10000 /* do not block on IO */ 23#define MAP_NONBLOCK 0x10000 /* do not block on IO */
24 24
25/* XXX Need to add flags to SunOS's mctl, mlockall, and madvise system
26 * XXX calls.
27 */
28
29/* SunOS sys_mctl() stuff... */
30#define MC_SYNC 1 /* Sync pages in memory with storage (usu. a file) */
31#define MC_LOCK 2 /* Lock pages into core ram, do not allow swapping of them */
32#define MC_UNLOCK 3 /* Unlock pages locked via previous mctl() with MC_LOCK arg */
33#define MC_LOCKAS 5 /* Lock an entire address space of the calling process */
34#define MC_UNLOCKAS 6 /* Unlock entire address space of calling process */
35
36#define MADV_FREE 0x5 /* (Solaris) contents can be freed */
37
38#ifdef __KERNEL__ 25#ifdef __KERNEL__
39#ifndef __ASSEMBLY__ 26#ifndef __ASSEMBLY__
40#define arch_mmap_check sparc_mmap_check 27#define arch_mmap_check sparc_mmap_check
diff --git a/include/asm-sparc/namei.h b/include/asm-sparc/namei.h
index f2461e8a11ac..618344d89cc4 100644
--- a/include/asm-sparc/namei.h
+++ b/include/asm-sparc/namei.h
@@ -8,19 +8,6 @@
8#ifndef __SPARC_NAMEI_H 8#ifndef __SPARC_NAMEI_H
9#define __SPARC_NAMEI_H 9#define __SPARC_NAMEI_H
10 10
11#define SPARC_BSD_EMUL "/usr/gnemul/sunos/" 11#define __emul_prefix() NULL
12#define SPARC_SOL_EMUL "/usr/gnemul/solaris/"
13
14static inline char * __emul_prefix(void)
15{
16 switch (current->personality) {
17 case PER_SUNOS:
18 return SPARC_BSD_EMUL;
19 case PER_SVR4:
20 return SPARC_SOL_EMUL;
21 default:
22 return NULL;
23 }
24}
25 12
26#endif /* __SPARC_NAMEI_H */ 13#endif /* __SPARC_NAMEI_H */
diff --git a/include/asm-sparc/pconf.h b/include/asm-sparc/pconf.h
deleted file mode 100644
index d73c1f1c49dc..000000000000
--- a/include/asm-sparc/pconf.h
+++ /dev/null
@@ -1,25 +0,0 @@
1/* $Id: pconf.h,v 1.3 1996/04/25 06:13:25 davem Exp $
2 * pconf.h: pathconf() and fpathconf() defines for SunOS
3 * system call compatibility.
4 *
5 * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
6 */
7
8#ifndef _SPARC_PCONF_H
9#define _SPARC_PCONF_H
10
11#include <linux/fs.h>
12#include <linux/limits.h>
13
14#define _PCONF_LINK 1 /* Max number of links to an object */
15#define _PCONF_CANON 2 /* TTY input buffer line size */
16#define _PCONF_INPUT 3 /* Biggest packet a tty can imbibe at once */
17#define _PCONF_NAME 4 /* Filename length max */
18#define _PCONF_PATH 5 /* Max size of a pathname */
19#define _PCONF_PIPE 6 /* Buffer size for a pipe */
20#define _PCONF_CHRESTRICT 7 /* Can only root chown files? */
21#define _PCONF_NOTRUNC 8 /* Are pathnames truncated if too big? */
22#define _PCONF_VDISABLE 9 /* Magic char to disable special tty chars */
23#define _PCONF_MAXPCONF 9
24
25#endif /* !(_SPARC_PCONF_H) */
diff --git a/include/asm-sparc/processor.h b/include/asm-sparc/processor.h
index 40b1e41fdea7..e3006979709b 100644
--- a/include/asm-sparc/processor.h
+++ b/include/asm-sparc/processor.h
@@ -13,8 +13,6 @@
13 */ 13 */
14#define current_text_addr() ({ void *pc; __asm__("sethi %%hi(1f), %0; or %0, %%lo(1f), %0;\n1:" : "=r" (pc)); pc; }) 14#define current_text_addr() ({ void *pc; __asm__("sethi %%hi(1f), %0; or %0, %%lo(1f), %0;\n1:" : "=r" (pc)); pc; })
15 15
16#include <linux/a.out.h>
17
18#include <asm/psr.h> 16#include <asm/psr.h>
19#include <asm/ptrace.h> 17#include <asm/ptrace.h>
20#include <asm/head.h> 18#include <asm/head.h>
@@ -67,7 +65,6 @@ struct thread_struct {
67 struct fpq fpqueue[16]; 65 struct fpq fpqueue[16];
68 unsigned long flags; 66 unsigned long flags;
69 mm_segment_t current_ds; 67 mm_segment_t current_ds;
70 struct exec core_exec; /* just what it says. */
71 int new_signal; 68 int new_signal;
72}; 69};
73 70
diff --git a/include/asm-sparc/socket.h b/include/asm-sparc/socket.h
index 2e2bd0b7c8e3..a00e15df227c 100644
--- a/include/asm-sparc/socket.h
+++ b/include/asm-sparc/socket.h
@@ -24,9 +24,6 @@
24#define SO_SNDTIMEO 0x4000 24#define SO_SNDTIMEO 0x4000
25#define SO_ACCEPTCONN 0x8000 25#define SO_ACCEPTCONN 0x8000
26 26
27/* wha!??? */
28#define SO_DONTLINGER (~SO_LINGER) /* Older SunOS compat. hack */
29
30#define SO_SNDBUF 0x1001 27#define SO_SNDBUF 0x1001
31#define SO_RCVBUF 0x1002 28#define SO_RCVBUF 0x1002
32#define SO_SNDBUFFORCE 0x100a 29#define SO_SNDBUFFORCE 0x100a
diff --git a/include/asm-sparc/solerrno.h b/include/asm-sparc/solerrno.h
deleted file mode 100644
index 8abce7e4639f..000000000000
--- a/include/asm-sparc/solerrno.h
+++ /dev/null
@@ -1,132 +0,0 @@
1/* $Id: solerrno.h,v 1.5 1996/04/25 06:13:32 davem Exp $
2 * solerrno.h: Solaris error return codes for compatibility.
3 *
4 * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
5 */
6
7#ifndef _SPARC_SOLERRNO_H
8#define _SPARC_SOLERRNO_H
9
10#define SOL_EPERM 1 /* Required superuser access perms */
11#define SOL_ENOENT 2 /* File or directory does not exist */
12#define SOL_ESRCH 3 /* Process did not exist */
13#define SOL_EINTR 4 /* System call was interrupted */
14#define SOL_EIO 5 /* An i/o error occurred */
15#define SOL_ENXIO 6 /* Device or Address does not exist */
16#define SOL_E2BIG 7 /* Too many arguments were given */
17#define SOL_ENOEXEC 8 /* Header of executable was munged */
18#define SOL_EBADF 9 /* Bogus file number */
19#define SOL_ECHILD 10 /* No children of process exist */
20#define SOL_EAGAIN 11 /* beep beep, "try again later" */
21#define SOL_ENOMEM 12 /* No memory available */
22#define SOL_EACCES 13 /* Access not allowed */
23#define SOL_EFAULT 14 /* Address passed was invalid */
24#define SOL_ENOTBLK 15 /* blkdev op on non-block device */
25#define SOL_EBUSY 16 /* Mounted device was busy */
26#define SOL_EEXIST 17 /* File specified already exists */
27#define SOL_EXDEV 18 /* Link request across diff devices */
28#define SOL_ENODEV 19 /* Device does not exist on system */
29#define SOL_ENOTDIR 20 /* Dir operation on non-directory */
30#define SOL_EISDIR 21 /* File was of directory type */
31#define SOL_EINVAL 22 /* Argument passed was invalid */
32#define SOL_ENFILE 23 /* No more room in file table */
33#define SOL_EMFILE 24 /* Proc has too many files open */
34#define SOL_ENOTTY 25 /* Ioctl was invalid for req device */
35#define SOL_ETXTBSY 26 /* Text file in busy state */
36#define SOL_EFBIG 27 /* Too big of a file for operation */
37#define SOL_ENOSPC 28 /* Disk is full */
38#define SOL_ESPIPE 29 /* Seek attempted on non-seeking dev*/
39#define SOL_EROFS 30 /* Write attempted on read-only fs */
40#define SOL_EMLINK 31 /* Too many links in file search */
41#define SOL_EPIPE 32 /* Call a plumber */
42#define SOL_EDOM 33 /* Argument was out of fct domain */
43#define SOL_ERANGE 34 /* Could not represent math result */
44#define SOL_ENOMSG 35 /* Message of req type doesn't exist */
45#define SOL_EIDRM 36 /* Identifier has been removed */
46#define SOL_ECHRNG 37 /* Req channel number out of range */
47#define SOL_EL2NSYNC 38 /* Could not sync at run level 2 */
48#define SOL_EL3HLT 39 /* Halted at run level 3 */
49#define SOL_EL3RST 40 /* Reset at run level 3 */
50#define SOL_ELNRNG 41 /* Out of range link number */
51#define SOL_EUNATCH 42 /* Driver for protocol not attached */
52#define SOL_ENOCSI 43 /* CSI structure not around */
53#define SOL_EL2HLT 44 /* Halted at run level 2 */
54#define SOL_EDEADLK 45 /* Deadlock condition detected */
55#define SOL_ENOLCK 46 /* Record locks unavailable */
56#define SOL_ECANCELED 47 /* Cancellation of oper. happened */
57#define SOL_ENOTSUP 48 /* Attempt of unsupported operation */
58#define SOL_EDQUOT 49 /* Users disk quota exceeded */
59#define SOL_EBADE 50 /* Invalid exchange */
60#define SOL_EBADR 51 /* Request descriptor was invalid */
61#define SOL_EXFULL 52 /* Full exchange */
62#define SOL_ENOANO 53 /* ano does not exist */
63#define SOL_EBADRQC 54 /* Req code was invalid */
64#define SOL_EBADSLT 55 /* Bad slot number */
65#define SOL_EDEADLOCK 56 /* Deadlock in fs error */
66#define SOL_EBFONT 57 /* Font file format invalid */
67/* YOW, I LOVE SYSV STREAMS!!!! */
68#define SOL_ENOSTR 60 /* Stream-op on non-stream dev */
69#define SOL_ENODATA 61 /* No data avail at this time */
70#define SOL_ETIME 62 /* Expiration of time occurred */
71#define SOL_ENOSR 63 /* Streams resources exhausted */
72#define SOL_ENONET 64 /* No network connected */
73#define SOL_ENOPKG 65 /* Non-installed package */
74#define SOL_EREMOTE 66 /* Object was on remote machine */
75#define SOL_ENOLINK 67 /* Cut link */
76#define SOL_EADV 68 /* Error in advertise */
77#define SOL_ESRMNT 69 /* Some magic srmount problem */
78#define SOL_ECOMM 70 /* During send, comm error occurred */
79#define SOL_EPROTO 71 /* Protocol botch */
80#define SOL_EMULTIHOP 74 /* Multihop attempted */
81#define SOL_EBADMSG 77 /* Message was unreadable */
82#define SOL_ENAMETOOLONG 78 /* Too long of a path name */
83#define SOL_EOVERFLOW 79 /* Data type too small for datum */
84#define SOL_ENOTUNIQ 80 /* Logical name was not unique */
85#define SOL_EBADFD 81 /* Op cannot be performed on fd */
86#define SOL_EREMCHG 82 /* Remote address is now different */
87#define SOL_ELIBACC 83 /* Shared lib could not be accessed */
88#define SOL_ELIBBAD 84 /* ShLib is corrupted in some way */
89#define SOL_ELIBSCN 85 /* A.out ShLib problems */
90#define SOL_ELIBMAX 86 /* Exceeded ShLib linkage limit */
91#define SOL_ELIBEXEC 87 /* Execution of ShLib attempted */
92#define SOL_EILSEQ 88 /* Bad byte sequence found */
93#define SOL_ENOSYS 89 /* Invalid filesystem operation */
94#define SOL_ELOOP 90 /* Detected loop in symbolic links */
95#define SOL_ERESTART 91 /* System call is restartable */
96#define SOL_ESTRPIPE 92 /* Do not sleep in head of stream */
97#define SOL_ENOTEMPTY 93 /* Rmdir of non-empty directory */
98#define SOL_EUSERS 94 /* Over abundance of users for ufs */
99#define SOL_ENOTSOCK 95 /* Sock-op on non-sock */
100#define SOL_EDESTADDRREQ 96 /* No dest addr given, but needed */
101#define SOL_EMSGSIZE 97 /* Msg too big */
102#define SOL_EPROTOTYPE 98 /* Bad socket protocol */
103#define SOL_ENOPROTOOPT 99 /* Unavailable protocol */
104#define SOL_EPROTONOSUPPORT 120 /* Unsupported protocol */
105#define SOL_ESOCKTNOSUPPORT 121 /* Unsupported socket type */
106#define SOL_EOPNOTSUPP 122 /* Unsupported sock-op */
107#define SOL_EPFNOSUPPORT 123 /* Unsupported protocol family */
108#define SOL_EAFNOSUPPORT 124 /* Unsup addr family for protocol */
109#define SOL_EADDRINUSE 125 /* Req addr is already in use */
110#define SOL_EADDRNOTAVAIL 126 /* Req addr not available right now */
111#define SOL_ENETDOWN 127 /* Your subnet is on fire */
112#define SOL_ENETUNREACH 128 /* Someone playing with gateway and */
113 /* did not tell you he was going to */
114#define SOL_ENETRESET 129 /* Buy less-buggy ethernet cards */
115#define SOL_ECONNABORTED 130 /* Aborted connection due to sw */
116#define SOL_ECONNRESET 131 /* Your peers reset your connection */
117#define SOL_ENOBUFS 132 /* No buffer space available */
118#define SOL_EISCONN 133 /* Connect on already connected */
119 /* socket attempted */
120#define SOL_ENOTCONN 134 /* Comm on non-connected socket */
121#define SOL_ESHUTDOWN 143 /* Op attempted after sock-shutdown */
122#define SOL_ETOOMANYREFS 144 /* Reference limit exceeded */
123#define SOL_ETIMEDOUT 145 /* Timed out connection */
124#define SOL_ECONNREFUSED 146 /* Connection refused by remote host*/
125#define SOL_EHOSTDOWN 147 /* Remote host is up in flames */
126#define SOL_EHOSTUNREACH 148 /* Make a left at Easton Ave..... */
127#define SOL_EWOULDBLOCK EAGAIN /* Just an alias */
128#define SOL_EALREADY 149 /* Operation is already occurring */
129#define SOL_EINPROGRESS 150 /* Operation is happening now */
130#define SOL_ESTALE 151 /* Fungus growth on NFS file handle */
131
132#endif /* !(_SPARC_SOLERRNO_H) */
diff --git a/include/asm-sparc/svr4.h b/include/asm-sparc/svr4.h
deleted file mode 100644
index da1f1c980e2d..000000000000
--- a/include/asm-sparc/svr4.h
+++ /dev/null
@@ -1,119 +0,0 @@
1/* Solaris/SPARC constants and definitions --
2 * (C) 1996 Miguel de Icaza
3 *
4 * This file is not meant to be included by user level applications
5 * but the solaris syscall emulator
6 */
7
8#ifndef _SPARC_SVR4_H
9#define _SPARC_SVR4_H
10
11/* Signals as used by svr4 */
12typedef struct { /* signal set type */
13 ulong sigbits[4];
14} svr4_sigset_t;
15
16/* Values for siginfo.code */
17#define SVR4_SINOINFO 32767
18/* Siginfo, sucker expects bunch of information on those parameters */
19typedef union {
20 char total_size [128];
21 struct {
22 int signo;
23 int code;
24 int error;
25 union {
26 } data;
27 } siginfo;
28} svr4_siginfo_t;
29
30/* Context definition */
31
32/* Location of the user stored registers into a greg_t */
33enum {
34 SVR4_PSR, SVR4_PC, SVR4_NPC, SVR4_Y,
35 SVR4_G1, SVR4_G2, SVR4_G3, SVR4_G4,
36 SVR4_G5, SVR4_G6, SVR4_G7, SVR4_O0,
37 SVR4_O1, SVR4_O2, SVR4_O3, SVR4_O4,
38 SVR4_O5, SVR4_O6, SVR4_O7
39};
40
41/* sizeof (regs) / sizeof (greg_t), defined in the ABI */
42#define SVR4_NREGS 19
43#define SVR4_MAXWIN 31
44
45typedef struct {
46 uint rwin_lo[8];
47 uint rwin_in[8];
48} svr4_rwindow_t;
49
50typedef struct {
51 int count;
52 int __user *winptr [SVR4_MAXWIN]; /* pointer to the windows */
53 svr4_rwindow_t win[SVR4_MAXWIN]; /* the windows */
54} svr4_gwindows_t;
55
56typedef int svr4_gregset_t[SVR4_NREGS];
57
58typedef struct {
59 double fpu_regs[32];
60 void *fp_q;
61 unsigned fp_fsr;
62 u_char fp_nqel;
63 u_char fp_nqsize;
64 u_char inuse; /* if fpu is in use */
65} svr4_fregset_t;
66
67typedef struct {
68 uint id; /* if this holds "xrs" string => ptr is valid */
69 caddr_t ptr;
70} svr4_xrs_t;
71
72/* Machine dependent context */
73typedef struct {
74 svr4_gregset_t greg; /* registers 0..19 (see top) */
75 svr4_gwindows_t __user *gwin; /* may point to register windows */
76 svr4_fregset_t freg; /* floating point registers */
77 svr4_xrs_t xrs; /* mhm? */
78 long pad[19];
79} svr4_mcontext_t;
80
81/* flags for stack_t.flags */
82enum svr4_stack_flags {
83 SVR4_SS_ONSTACK,
84 SVR4_SS_DISABLE,
85};
86
87/* signal stack exection place, unsupported */
88typedef struct svr4_stack_t {
89 char __user *sp;
90 int size;
91 int flags;
92} svr4_stack_t;
93
94/* Context used by getcontext and setcontext */
95typedef struct svr4_ucontext_t {
96 u_long flags; /* context flags, indicate what is loaded */
97 struct svr4_ucontext *link;
98 svr4_sigset_t sigmask;
99 svr4_stack_t stack;
100 svr4_mcontext_t mcontext;
101 long pad[23];
102} svr4_ucontext_t;
103
104/* windows hold the windows as they were at signal time,
105 * ucontext->mcontext holds a pointer to them.
106 * addresses for uc and si are passed as parameters to svr4 signal
107 * handler
108 */
109
110/* This is the signal frame that is passed to the signal handler */
111typedef struct {
112 svr4_gwindows_t gw; /* windows */
113 svr4_ucontext_t uc; /* machine context */
114 svr4_siginfo_t si; /* siginfo */
115} svr4_signal_frame_t;
116
117#define SVR4_SF_ALIGNED (((sizeof (svr4_signal_frame_t) + 7) & (~7)))
118
119#endif /* include control */
diff --git a/include/asm-sparc/termios.h b/include/asm-sparc/termios.h
index 4333232abb9f..733d40504e1e 100644
--- a/include/asm-sparc/termios.h
+++ b/include/asm-sparc/termios.h
@@ -33,11 +33,6 @@ struct ltchars {
33}; 33};
34#endif /* __KERNEL__ */ 34#endif /* __KERNEL__ */
35 35
36struct sunos_ttysize {
37 int st_lines; /* Lines on the terminal */
38 int st_columns; /* Columns on the terminal */
39};
40
41struct winsize { 36struct winsize {
42 unsigned short ws_row; 37 unsigned short ws_row;
43 unsigned short ws_col; 38 unsigned short ws_col;
diff --git a/include/asm-sparc/user.h b/include/asm-sparc/user.h
index b5f1abf733d5..3400ea87f148 100644
--- a/include/asm-sparc/user.h
+++ b/include/asm-sparc/user.h
@@ -1,60 +1,6 @@
1/* $Id: user.h,v 1.5 1998/02/23 01:49:22 rth Exp $
2 * asm-sparc/user.h: Core file definitions for the Sparc.
3 *
4 * Keep in sync with reg.h. Actually, we could get rid of this
5 * one, since we won't a.out core dump that much anyways - miguel.
6 * Copyright (C) 1995 (davem@caip.rutgers.edu)
7 */
8#ifndef _SPARC_USER_H 1#ifndef _SPARC_USER_H
9#define _SPARC_USER_H 2#define _SPARC_USER_H
10 3
11#include <asm/a.out.h> 4/* Nothing to define. */
12struct sunos_regs {
13 unsigned long psr, pc, npc, y;
14 unsigned long regs[15];
15};
16
17struct sunos_fpqueue {
18 unsigned long *addr;
19 unsigned long inst;
20};
21
22struct sunos_fp {
23 union {
24 unsigned long regs[32];
25 double reg_dbls[16];
26 } fregs;
27 unsigned long fsr;
28 unsigned long flags;
29 unsigned long extra;
30 unsigned long fpq_count;
31 struct sunos_fpqueue fpq[16];
32};
33
34struct sunos_fpu {
35 struct sunos_fp fpstatus;
36};
37
38/* The SunOS core file header layout. */
39struct user {
40 unsigned long magic;
41 unsigned long len;
42 struct sunos_regs regs;
43 struct exec uexec;
44 int signal;
45 size_t u_tsize; /* all of these in bytes! */
46 size_t u_dsize;
47 size_t u_ssize;
48 char u_comm[17];
49 struct sunos_fpu fpu;
50 unsigned long sigcode; /* Special sigcontext subcode, if any */
51};
52
53#define NBPG 0x2000
54#define UPAGES 1
55#define HOST_TEXT_START_ADDR (u.start_code)
56#define HOST_DATA_START_ADDR (u.uexec.a_data)
57#define HOST_STACK_END_ADDR (- u.u_ssize * NBPG)
58#define SUNOS_CORE_MAGIC 0x080456
59 5
60#endif /* !(_SPARC_USER_H) */ 6#endif /* !(_SPARC_USER_H) */
diff --git a/include/asm-sparc64/Kbuild b/include/asm-sparc64/Kbuild
index a90dc82129d1..dce1cf9a9313 100644
--- a/include/asm-sparc64/Kbuild
+++ b/include/asm-sparc64/Kbuild
@@ -12,7 +12,6 @@ header-y += display7seg.h
12header-y += envctrl.h 12header-y += envctrl.h
13header-y += openprom.h 13header-y += openprom.h
14header-y += openpromio.h 14header-y += openpromio.h
15header-y += pconf.h
16header-y += psrcompat.h 15header-y += psrcompat.h
17header-y += pstate.h 16header-y += pstate.h
18header-y += reg.h 17header-y += reg.h
diff --git a/include/asm-sparc64/a.out-core.h b/include/asm-sparc64/a.out-core.h
deleted file mode 100644
index 3499b3c425ca..000000000000
--- a/include/asm-sparc64/a.out-core.h
+++ /dev/null
@@ -1,31 +0,0 @@
1/* a.out coredump register dumper
2 *
3 * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public Licence
8 * as published by the Free Software Foundation; either version
9 * 2 of the Licence, or (at your option) any later version.
10 */
11
12#ifndef _ASM_A_OUT_CORE_H
13#define _ASM_A_OUT_CORE_H
14
15#ifdef __KERNEL__
16
17#include <linux/user.h>
18
19/*
20 * fill in the user structure for an a.out core dump
21 */
22static inline void aout_dump_thread(struct pt_regs *regs, struct user *dump)
23{
24 /* Only should be used for SunOS and ancient a.out
25 * SparcLinux binaries... Not worth implementing.
26 */
27 memset(dump, 0, sizeof(struct user));
28}
29
30#endif /* __KERNEL__ */
31#endif /* _ASM_A_OUT_CORE_H */
diff --git a/include/asm-sparc64/a.out.h b/include/asm-sparc64/a.out.h
deleted file mode 100644
index 44208c2a188e..000000000000
--- a/include/asm-sparc64/a.out.h
+++ /dev/null
@@ -1 +0,0 @@
1#include <asm-sparc/a.out.h>
diff --git a/include/asm-sparc64/ioctls.h b/include/asm-sparc64/ioctls.h
index 083c9a0f37de..c1be40647c99 100644
--- a/include/asm-sparc64/ioctls.h
+++ b/include/asm-sparc64/ioctls.h
@@ -44,8 +44,6 @@
44#define __TIOCSETX _IOW('t', 34, int) /* SunOS Specific */ 44#define __TIOCSETX _IOW('t', 34, int) /* SunOS Specific */
45#define __TIOCGETX _IOR('t', 35, int) /* SunOS Specific */ 45#define __TIOCGETX _IOR('t', 35, int) /* SunOS Specific */
46#define TIOCCONS _IO('t', 36) 46#define TIOCCONS _IO('t', 36)
47#define __TIOCSSIZE _IOW('t', 37, struct sunos_ttysize) /* SunOS Specific */
48#define __TIOCGSIZE _IOR('t', 38, struct sunos_ttysize) /* SunOS Specific */
49#define TIOCGSOFTCAR _IOR('t', 100, int) 47#define TIOCGSOFTCAR _IOR('t', 100, int)
50#define TIOCSSOFTCAR _IOW('t', 101, int) 48#define TIOCSSOFTCAR _IOW('t', 101, int)
51#define __TIOCUCNTL _IOW('t', 102, int) /* SunOS Specific */ 49#define __TIOCUCNTL _IOW('t', 102, int) /* SunOS Specific */
diff --git a/include/asm-sparc64/mman.h b/include/asm-sparc64/mman.h
index 8cc1860be630..e584563b56eb 100644
--- a/include/asm-sparc64/mman.h
+++ b/include/asm-sparc64/mman.h
@@ -22,19 +22,6 @@
22#define MAP_POPULATE 0x8000 /* populate (prefault) pagetables */ 22#define MAP_POPULATE 0x8000 /* populate (prefault) pagetables */
23#define MAP_NONBLOCK 0x10000 /* do not block on IO */ 23#define MAP_NONBLOCK 0x10000 /* do not block on IO */
24 24
25/* XXX Need to add flags to SunOS's mctl, mlockall, and madvise system
26 * XXX calls.
27 */
28
29/* SunOS sys_mctl() stuff... */
30#define MC_SYNC 1 /* Sync pages in memory with storage (usu. a file) */
31#define MC_LOCK 2 /* Lock pages into core ram, do not allow swapping of them */
32#define MC_UNLOCK 3 /* Unlock pages locked via previous mctl() with MC_LOCK arg */
33#define MC_LOCKAS 5 /* Lock an entire address space of the calling process */
34#define MC_UNLOCKAS 6 /* Unlock entire address space of calling process */
35
36#define MADV_FREE 0x5 /* (Solaris) contents can be freed */
37
38#ifdef __KERNEL__ 25#ifdef __KERNEL__
39#ifndef __ASSEMBLY__ 26#ifndef __ASSEMBLY__
40#define arch_mmap_check sparc64_mmap_check 27#define arch_mmap_check sparc64_mmap_check
diff --git a/include/asm-sparc64/namei.h b/include/asm-sparc64/namei.h
index ccda19e28695..275161f21213 100644
--- a/include/asm-sparc64/namei.h
+++ b/include/asm-sparc64/namei.h
@@ -8,19 +8,6 @@
8#ifndef __SPARC64_NAMEI_H 8#ifndef __SPARC64_NAMEI_H
9#define __SPARC64_NAMEI_H 9#define __SPARC64_NAMEI_H
10 10
11#define SPARC_BSD_EMUL "/usr/gnemul/sunos/" 11#define __emul_prefix() NULL
12#define SPARC_SOL_EMUL "/usr/gnemul/solaris/"
13
14static inline char * __emul_prefix(void)
15{
16 switch (current->personality) {
17 case PER_SUNOS:
18 return SPARC_BSD_EMUL;
19 case PER_SVR4:
20 return SPARC_SOL_EMUL;
21 default:
22 return NULL;
23 }
24}
25 12
26#endif /* __SPARC64_NAMEI_H */ 13#endif /* __SPARC64_NAMEI_H */
diff --git a/include/asm-sparc64/pconf.h b/include/asm-sparc64/pconf.h
deleted file mode 100644
index aad106a70908..000000000000
--- a/include/asm-sparc64/pconf.h
+++ /dev/null
@@ -1,25 +0,0 @@
1/* $Id: pconf.h,v 1.1 1996/12/02 00:09:10 davem Exp $
2 * pconf.h: pathconf() and fpathconf() defines for SunOS
3 * system call compatibility.
4 *
5 * Copyright (C) 1995, 1996 David S. Miller (davem@caip.rutgers.edu)
6 */
7
8#ifndef _SPARC64_PCONF_H
9#define _SPARC64_PCONF_H
10
11#include <linux/fs.h>
12#include <linux/limits.h>
13
14#define _PCONF_LINK 1 /* Max number of links to an object */
15#define _PCONF_CANON 2 /* TTY input buffer line size */
16#define _PCONF_INPUT 3 /* Biggest packet a tty can imbibe at once */
17#define _PCONF_NAME 4 /* Filename length max */
18#define _PCONF_PATH 5 /* Max size of a pathname */
19#define _PCONF_PIPE 6 /* Buffer size for a pipe */
20#define _PCONF_CHRESTRICT 7 /* Can only root chown files? */
21#define _PCONF_NOTRUNC 8 /* Are pathnames truncated if too big? */
22#define _PCONF_VDISABLE 9 /* Magic char to disable special tty chars */
23#define _PCONF_MAXPCONF 9
24
25#endif /* !(_SPARC64_PCONF_H) */
diff --git a/include/asm-sparc64/socket.h b/include/asm-sparc64/socket.h
index 44a625af6e31..8cf071fae3eb 100644
--- a/include/asm-sparc64/socket.h
+++ b/include/asm-sparc64/socket.h
@@ -24,9 +24,6 @@
24#define SO_SNDTIMEO 0x4000 24#define SO_SNDTIMEO 0x4000
25#define SO_ACCEPTCONN 0x8000 25#define SO_ACCEPTCONN 0x8000
26 26
27/* wha!??? */
28#define SO_DONTLINGER (~SO_LINGER) /* Older SunOS compat. hack */
29
30#define SO_SNDBUF 0x1001 27#define SO_SNDBUF 0x1001
31#define SO_RCVBUF 0x1002 28#define SO_RCVBUF 0x1002
32#define SO_SNDBUFFORCE 0x100a 29#define SO_SNDBUFFORCE 0x100a
diff --git a/include/asm-sparc64/solerrno.h b/include/asm-sparc64/solerrno.h
deleted file mode 100644
index a2ea6fcf3446..000000000000
--- a/include/asm-sparc64/solerrno.h
+++ /dev/null
@@ -1,132 +0,0 @@
1/* $Id: solerrno.h,v 1.1 1996/12/26 14:22:40 davem Exp $
2 * solerrno.h: Solaris error return codes for compatibility.
3 *
4 * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
5 */
6
7#ifndef _SPARC64_SOLERRNO_H
8#define _SPARC64_SOLERRNO_H
9
10#define SOL_EPERM 1 /* Required superuser access perms */
11#define SOL_ENOENT 2 /* File or directory does not exist */
12#define SOL_ESRCH 3 /* Process did not exist */
13#define SOL_EINTR 4 /* System call was interrupted */
14#define SOL_EIO 5 /* An i/o error occurred */
15#define SOL_ENXIO 6 /* Device or Address does not exist */
16#define SOL_E2BIG 7 /* Too many arguments were given */
17#define SOL_ENOEXEC 8 /* Header of executable was munged */
18#define SOL_EBADF 9 /* Bogus file number */
19#define SOL_ECHILD 10 /* No children of process exist */
20#define SOL_EAGAIN 11 /* beep beep, "try again later" */
21#define SOL_ENOMEM 12 /* No memory available */
22#define SOL_EACCES 13 /* Access not allowed */
23#define SOL_EFAULT 14 /* Address passed was invalid */
24#define SOL_ENOTBLK 15 /* blkdev op on non-block device */
25#define SOL_EBUSY 16 /* Mounted device was busy */
26#define SOL_EEXIST 17 /* File specified already exists */
27#define SOL_EXDEV 18 /* Link request across diff devices */
28#define SOL_ENODEV 19 /* Device does not exist on system */
29#define SOL_ENOTDIR 20 /* Dir operation on non-directory */
30#define SOL_EISDIR 21 /* File was of directory type */
31#define SOL_EINVAL 22 /* Argument passed was invalid */
32#define SOL_ENFILE 23 /* No more room in file table */
33#define SOL_EMFILE 24 /* Proc has too many files open */
34#define SOL_ENOTTY 25 /* Ioctl was invalid for req device */
35#define SOL_ETXTBSY 26 /* Text file in busy state */
36#define SOL_EFBIG 27 /* Too big of a file for operation */
37#define SOL_ENOSPC 28 /* Disk is full */
38#define SOL_ESPIPE 29 /* Seek attempted on non-seeking dev*/
39#define SOL_EROFS 30 /* Write attempted on read-only fs */
40#define SOL_EMLINK 31 /* Too many links in file search */
41#define SOL_EPIPE 32 /* Call a plumber */
42#define SOL_EDOM 33 /* Argument was out of fct domain */
43#define SOL_ERANGE 34 /* Could not represent math result */
44#define SOL_ENOMSG 35 /* Message of req type doesn't exist */
45#define SOL_EIDRM 36 /* Identifier has been removed */
46#define SOL_ECHRNG 37 /* Req channel number out of range */
47#define SOL_EL2NSYNC 38 /* Could not sync at run level 2 */
48#define SOL_EL3HLT 39 /* Halted at run level 3 */
49#define SOL_EL3RST 40 /* Reset at run level 3 */
50#define SOL_ELNRNG 41 /* Out of range link number */
51#define SOL_EUNATCH 42 /* Driver for protocol not attached */
52#define SOL_ENOCSI 43 /* CSI structure not around */
53#define SOL_EL2HLT 44 /* Halted at run level 2 */
54#define SOL_EDEADLK 45 /* Deadlock condition detected */
55#define SOL_ENOLCK 46 /* Record locks unavailable */
56#define SOL_ECANCELED 47 /* Cancellation of oper. happened */
57#define SOL_ENOTSUP 48 /* Attempt of unsupported operation */
58#define SOL_EDQUOT 49 /* Users disk quota exceeded */
59#define SOL_EBADE 50 /* Invalid exchange */
60#define SOL_EBADR 51 /* Request descriptor was invalid */
61#define SOL_EXFULL 52 /* Full exchange */
62#define SOL_ENOANO 53 /* ano does not exist */
63#define SOL_EBADRQC 54 /* Req code was invalid */
64#define SOL_EBADSLT 55 /* Bad slot number */
65#define SOL_EDEADLOCK 56 /* Deadlock in fs error */
66#define SOL_EBFONT 57 /* Font file format invalid */
67/* YOW, I LOVE SYSV STREAMS!!!! */
68#define SOL_ENOSTR 60 /* Stream-op on non-stream dev */
69#define SOL_ENODATA 61 /* No data avail at this time */
70#define SOL_ETIME 62 /* Expiration of time occurred */
71#define SOL_ENOSR 63 /* Streams resources exhausted */
72#define SOL_ENONET 64 /* No network connected */
73#define SOL_ENOPKG 65 /* Non-installed package */
74#define SOL_EREMOTE 66 /* Object was on remote machine */
75#define SOL_ENOLINK 67 /* Cut link */
76#define SOL_EADV 68 /* Error in advertise */
77#define SOL_ESRMNT 69 /* Some magic srmount problem */
78#define SOL_ECOMM 70 /* During send, comm error occurred */
79#define SOL_EPROTO 71 /* Protocol botch */
80#define SOL_EMULTIHOP 74 /* Multihop attempted */
81#define SOL_EBADMSG 77 /* Message was unreadable */
82#define SOL_ENAMETOOLONG 78 /* Too long of a path name */
83#define SOL_EOVERFLOW 79 /* Data type too small for datum */
84#define SOL_ENOTUNIQ 80 /* Logical name was not unique */
85#define SOL_EBADFD 81 /* Op cannot be performed on fd */
86#define SOL_EREMCHG 82 /* Remote address is now different */
87#define SOL_ELIBACC 83 /* Shared lib could not be accessed */
88#define SOL_ELIBBAD 84 /* ShLib is corrupted in some way */
89#define SOL_ELIBSCN 85 /* A.out ShLib problems */
90#define SOL_ELIBMAX 86 /* Exceeded ShLib linkage limit */
91#define SOL_ELIBEXEC 87 /* Execution of ShLib attempted */
92#define SOL_EILSEQ 88 /* Bad byte sequence found */
93#define SOL_ENOSYS 89 /* Invalid filesystem operation */
94#define SOL_ELOOP 90 /* Detected loop in symbolic links */
95#define SOL_ERESTART 91 /* System call is restartable */
96#define SOL_ESTRPIPE 92 /* Do not sleep in head of stream */
97#define SOL_ENOTEMPTY 93 /* Rmdir of non-empty directory */
98#define SOL_EUSERS 94 /* Over abundance of users for ufs */
99#define SOL_ENOTSOCK 95 /* Sock-op on non-sock */
100#define SOL_EDESTADDRREQ 96 /* No dest addr given, but needed */
101#define SOL_EMSGSIZE 97 /* Msg too big */
102#define SOL_EPROTOTYPE 98 /* Bad socket protocol */
103#define SOL_ENOPROTOOPT 99 /* Unavailable protocol */
104#define SOL_EPROTONOSUPPORT 120 /* Unsupported protocol */
105#define SOL_ESOCKTNOSUPPORT 121 /* Unsupported socket type */
106#define SOL_EOPNOTSUPP 122 /* Unsupported sock-op */
107#define SOL_EPFNOSUPPORT 123 /* Unsupported protocol family */
108#define SOL_EAFNOSUPPORT 124 /* Unsup addr family for protocol */
109#define SOL_EADDRINUSE 125 /* Req addr is already in use */
110#define SOL_EADDRNOTAVAIL 126 /* Req addr not available right now */
111#define SOL_ENETDOWN 127 /* Your subnet is on fire */
112#define SOL_ENETUNREACH 128 /* Someone playing with gateway and */
113 /* did not tell you he was going to */
114#define SOL_ENETRESET 129 /* Buy less-buggy ethernet cards */
115#define SOL_ECONNABORTED 130 /* Aborted connection due to sw */
116#define SOL_ECONNRESET 131 /* Your peers reset your connection */
117#define SOL_ENOBUFS 132 /* No buffer space available */
118#define SOL_EISCONN 133 /* Connect on already connected */
119 /* socket attempted */
120#define SOL_ENOTCONN 134 /* Comm on non-connected socket */
121#define SOL_ESHUTDOWN 143 /* Op attempted after sock-shutdown */
122#define SOL_ETOOMANYREFS 144 /* Reference limit exceeded */
123#define SOL_ETIMEDOUT 145 /* Timed out connection */
124#define SOL_ECONNREFUSED 146 /* Connection refused by remote host*/
125#define SOL_EHOSTDOWN 147 /* Remote host is up in flames */
126#define SOL_EHOSTUNREACH 148 /* Make a left at Easton Ave..... */
127#define SOL_EWOULDBLOCK EAGAIN /* Just an alias */
128#define SOL_EALREADY 149 /* Operation is already occurring */
129#define SOL_EINPROGRESS 150 /* Operation is happening now */
130#define SOL_ESTALE 151 /* Fungus growth on NFS file handle */
131
132#endif /* !(_SPARC64_SOLERRNO_H) */
diff --git a/include/asm-sparc64/svr4.h b/include/asm-sparc64/svr4.h
deleted file mode 100644
index c96d5f116e1c..000000000000
--- a/include/asm-sparc64/svr4.h
+++ /dev/null
@@ -1,120 +0,0 @@
1/* Solaris/SPARC constants and definitions --
2 * (C) 1996 Miguel de Icaza
3 *
4 * This file is not meant to be included by user level applications
5 * but the solaris syscall emulator
6 */
7
8#ifndef _SPARC64_SVR4_H
9#define _SPARC64_SVR4_H
10
11/* Signals as used by svr4 */
12typedef struct { /* signal set type */
13 uint sigbits[4];
14} svr4_sigset_t;
15
16/* Values for siginfo.code */
17#define SVR4_SINOINFO 32767
18/* Siginfo, sucker expects bunch of information on those parameters */
19typedef union {
20 char total_size [128];
21 struct {
22 int signo;
23 int code;
24 int error;
25 union {
26 } data;
27 } siginfo;
28} svr4_siginfo_t;
29
30/* Context definition */
31
32/* Location of the user stored registers into a greg_t */
33enum {
34 SVR4_PSR, SVR4_PC, SVR4_NPC, SVR4_Y,
35 SVR4_G1, SVR4_G2, SVR4_G3, SVR4_G4,
36 SVR4_G5, SVR4_G6, SVR4_G7, SVR4_O0,
37 SVR4_O1, SVR4_O2, SVR4_O3, SVR4_O4,
38 SVR4_O5, SVR4_O6, SVR4_O7
39};
40
41/* sizeof (regs) / sizeof (greg_t), defined in the ABI */
42#define SVR4_NREGS 19
43#define SVR4_MAXWIN 31
44
45typedef struct {
46 u32 rwin_lo[8];
47 u32 rwin_in[8];
48} svr4_rwindow_t;
49
50typedef struct {
51 int count;
52 u32 winptr [SVR4_MAXWIN]; /* pointer to the windows */
53
54 svr4_rwindow_t win[SVR4_MAXWIN]; /* the windows */
55} svr4_gwindows_t;
56
57typedef int svr4_gregset_t[SVR4_NREGS];
58
59typedef struct {
60 u64 fpu_regs[32];
61 u32 fp_q;
62 u32 fp_fsr;
63 u_char fp_nqel;
64 u_char fp_nqsize;
65 u_char inuse; /* if fpu is in use */
66} svr4_fregset_t;
67
68typedef struct {
69 u32 id; /* if this holds "xrs" string => ptr is valid */
70 u32 ptr;
71} svr4_xrs_t;
72
73/* Machine dependent context */
74typedef struct {
75 svr4_gregset_t greg; /* registers 0..19 (see top) */
76 u32 gwin; /* may point to register windows */
77 svr4_fregset_t freg; /* floating point registers */
78 svr4_xrs_t xrs; /* mhm? */
79 int pad[19];
80} svr4_mcontext_t;
81
82/* flags for stack_t.flags */
83enum svr4_stack_flags {
84 SVR4_SS_ONSTACK,
85 SVR4_SS_DISABLE,
86};
87
88/* signal stack execution place, unsupported */
89typedef struct svr4_stack_t {
90 u32 sp;
91 int size;
92 int flags;
93} svr4_stack_t;
94
95/* Context used by getcontext and setcontext */
96typedef struct svr4_ucontext_t {
97 u32 flags; /* context flags, indicate what is loaded */
98 u32 link;
99 svr4_sigset_t sigmask;
100 svr4_stack_t stack;
101 svr4_mcontext_t mcontext;
102 int pad[23];
103} svr4_ucontext_t;
104
105/* windows hold the windows as they were at signal time,
106 * ucontext->mcontext holds a pointer to them.
107 * addresses for uc and si are passed as parameters to svr4 signal
108 * handler
109 */
110
111/* This is the signal frame that is passed to the signal handler */
112typedef struct {
113 svr4_gwindows_t gw; /* windows */
114 svr4_ucontext_t uc; /* machine context */
115 svr4_siginfo_t si; /* siginfo */
116} svr4_signal_frame_t;
117
118#define SVR4_SF_ALIGNED (((sizeof (svr4_signal_frame_t) + 7) & (~7)))
119
120#endif /* include control */
diff --git a/include/asm-sparc64/termios.h b/include/asm-sparc64/termios.h
index ef527211f8a8..cacbea171ad7 100644
--- a/include/asm-sparc64/termios.h
+++ b/include/asm-sparc64/termios.h
@@ -33,11 +33,6 @@ struct ltchars {
33}; 33};
34#endif /* __KERNEL__ */ 34#endif /* __KERNEL__ */
35 35
36struct sunos_ttysize {
37 int st_lines; /* Lines on the terminal */
38 int st_columns; /* Columns on the terminal */
39};
40
41struct winsize { 36struct winsize {
42 unsigned short ws_row; 37 unsigned short ws_row;
43 unsigned short ws_col; 38 unsigned short ws_col;
diff --git a/include/asm-sparc64/ttable.h b/include/asm-sparc64/ttable.h
index bbb9c8f13d61..7208a777750e 100644
--- a/include/asm-sparc64/ttable.h
+++ b/include/asm-sparc64/ttable.h
@@ -99,14 +99,6 @@
99 or %l7, %lo(systbl), %l7; \ 99 or %l7, %lo(systbl), %l7; \
100 nop; nop; 100 nop; nop;
101 101
102#define INDIRECT_SOLARIS_SYSCALL(num) \
103 sethi %hi(109f), %g7; \
104 ba,pt %xcc, etrap; \
105109: or %g7, %lo(109b), %g7; \
106 ba,pt %xcc, tl0_solaris + 0xc; \
107 mov num, %g1; \
108 nop;nop;nop;
109
110#define TRAP_UTRAP(handler,lvl) \ 102#define TRAP_UTRAP(handler,lvl) \
111 mov handler, %g3; \ 103 mov handler, %g3; \
112 ba,pt %xcc, utrap_trap; \ 104 ba,pt %xcc, utrap_trap; \
@@ -117,11 +109,6 @@
117 nop; \ 109 nop; \
118 nop; 110 nop;
119 111
120#ifdef CONFIG_SUNOS_EMUL
121#define SUNOS_SYSCALL_TRAP SYSCALL_TRAP(linux_sparc_syscall32, sunos_sys_table)
122#else
123#define SUNOS_SYSCALL_TRAP TRAP(sunos_syscall)
124#endif
125#ifdef CONFIG_COMPAT 112#ifdef CONFIG_COMPAT
126#define LINUX_32BIT_SYSCALL_TRAP SYSCALL_TRAP(linux_sparc_syscall32, sys_call_table32) 113#define LINUX_32BIT_SYSCALL_TRAP SYSCALL_TRAP(linux_sparc_syscall32, sys_call_table32)
127#else 114#else
@@ -130,11 +117,6 @@
130#define LINUX_64BIT_SYSCALL_TRAP SYSCALL_TRAP(linux_sparc_syscall, sys_call_table64) 117#define LINUX_64BIT_SYSCALL_TRAP SYSCALL_TRAP(linux_sparc_syscall, sys_call_table64)
131#define GETCC_TRAP TRAP(getcc) 118#define GETCC_TRAP TRAP(getcc)
132#define SETCC_TRAP TRAP(setcc) 119#define SETCC_TRAP TRAP(setcc)
133#ifdef CONFIG_SOLARIS_EMUL
134#define SOLARIS_SYSCALL_TRAP TRAP(solaris_sparc_syscall)
135#else
136#define SOLARIS_SYSCALL_TRAP TRAP(solaris_syscall)
137#endif
138#define BREAKPOINT_TRAP TRAP(breakpoint_trap) 120#define BREAKPOINT_TRAP TRAP(breakpoint_trap)
139 121
140#ifdef CONFIG_TRACE_IRQFLAGS 122#ifdef CONFIG_TRACE_IRQFLAGS
diff --git a/include/asm-sparc64/unistd.h b/include/asm-sparc64/unistd.h
index 77559da0ea3f..13be4453a1f0 100644
--- a/include/asm-sparc64/unistd.h
+++ b/include/asm-sparc64/unistd.h
@@ -338,16 +338,6 @@
338#define NR_SYSCALLS 317 338#define NR_SYSCALLS 317
339 339
340#ifdef __KERNEL__ 340#ifdef __KERNEL__
341/* sysconf options, for SunOS compatibility */
342#define _SC_ARG_MAX 1
343#define _SC_CHILD_MAX 2
344#define _SC_CLK_TCK 3
345#define _SC_NGROUPS_MAX 4
346#define _SC_OPEN_MAX 5
347#define _SC_JOB_CONTROL 6
348#define _SC_SAVED_IDS 7
349#define _SC_VERSION 8
350
351#define __ARCH_WANT_IPC_PARSE_VERSION 341#define __ARCH_WANT_IPC_PARSE_VERSION
352#define __ARCH_WANT_OLD_READDIR 342#define __ARCH_WANT_OLD_READDIR
353#define __ARCH_WANT_STAT64 343#define __ARCH_WANT_STAT64
diff --git a/include/asm-sparc64/user.h b/include/asm-sparc64/user.h
index 02b138943837..29fc6e906c29 100644
--- a/include/asm-sparc64/user.h
+++ b/include/asm-sparc64/user.h
@@ -1,60 +1 @@
1/* $Id: user.h,v 1.1 1996/12/26 14:22:44 davem Exp $ #include <asm-sparc/user.h>
2 * asm-sparc64/user.h: Core file definitions for the Sparc.
3 *
4 * Keep in sync with reg.h. Actually, we could get rid of this
5 * one, since we won't a.out core dump that much anyways - miguel.
6 * Copyright (C) 1995 (davem@caip.rutgers.edu)
7 */
8#ifndef _SPARC64_USER_H
9#define _SPARC64_USER_H
10
11#include <linux/a.out.h>
12struct sunos_regs {
13 unsigned int psr, pc, npc, y;
14 unsigned int regs[15];
15};
16
17struct sunos_fpqueue {
18 unsigned int *addr;
19 unsigned int inst;
20};
21
22struct sunos_fp {
23 union {
24 unsigned int regs[32];
25 double reg_dbls[16];
26 } fregs;
27 unsigned int fsr;
28 unsigned int flags;
29 unsigned int extra;
30 unsigned int fpq_count;
31 struct sunos_fpqueue fpq[16];
32};
33
34struct sunos_fpu {
35 struct sunos_fp fpstatus;
36};
37
38/* The SunOS core file header layout. */
39struct user {
40 unsigned int magic;
41 unsigned int len;
42 struct sunos_regs regs;
43 struct exec uexec;
44 int signal;
45 size_t u_tsize; /* all of these in bytes! */
46 size_t u_dsize;
47 size_t u_ssize;
48 char u_comm[17];
49 struct sunos_fpu fpu;
50 unsigned int sigcode; /* Special sigcontext subcode, if any */
51};
52
53#define NBPG PAGE_SIZE /* XXX 4096 maybe? */
54#define UPAGES 1
55#define HOST_TEXT_START_ADDR (u.start_code)
56#define HOST_DATA_START_ADDR (u.start_data)
57#define HOST_STACK_END_ADDR (u.start_stack + u.u_ssize * NBPG)
58#define SUNOS_CORE_MAGIC 0x080456
59
60#endif /* !(_SPARC64_USER_H) */
diff --git a/include/linux/Kbuild b/include/linux/Kbuild
index b3d9ccde0c27..cbb5ccb27de3 100644
--- a/include/linux/Kbuild
+++ b/include/linux/Kbuild
@@ -100,7 +100,7 @@ header-y += ixjuser.h
100header-y += jffs2.h 100header-y += jffs2.h
101header-y += keyctl.h 101header-y += keyctl.h
102header-y += limits.h 102header-y += limits.h
103header-y += lock_dlm_plock.h 103header-y += dlm_plock.h
104header-y += magic.h 104header-y += magic.h
105header-y += major.h 105header-y += major.h
106header-y += matroxfb.h 106header-y += matroxfb.h
@@ -150,6 +150,7 @@ header-y += tiocl.h
150header-y += tipc.h 150header-y += tipc.h
151header-y += tipc_config.h 151header-y += tipc_config.h
152header-y += toshiba.h 152header-y += toshiba.h
153header-y += udf_fs_i.h
153header-y += ultrasound.h 154header-y += ultrasound.h
154header-y += un.h 155header-y += un.h
155header-y += utime.h 156header-y += utime.h
@@ -210,7 +211,9 @@ unifdef-y += hdlcdrv.h
210unifdef-y += hdlc.h 211unifdef-y += hdlc.h
211unifdef-y += hdreg.h 212unifdef-y += hdreg.h
212unifdef-y += hdsmart.h 213unifdef-y += hdsmart.h
214unifdef-y += hid.h
213unifdef-y += hiddev.h 215unifdef-y += hiddev.h
216unifdef-y += hidraw.h
214unifdef-y += hpet.h 217unifdef-y += hpet.h
215unifdef-y += i2c.h 218unifdef-y += i2c.h
216unifdef-y += i2c-dev.h 219unifdef-y += i2c-dev.h
@@ -334,7 +337,6 @@ unifdef-y += time.h
334unifdef-y += timex.h 337unifdef-y += timex.h
335unifdef-y += tty.h 338unifdef-y += tty.h
336unifdef-y += types.h 339unifdef-y += types.h
337unifdef-y += udf_fs_i.h
338unifdef-y += udp.h 340unifdef-y += udp.h
339unifdef-y += uinput.h 341unifdef-y += uinput.h
340unifdef-y += uio.h 342unifdef-y += uio.h
diff --git a/include/linux/dlm.h b/include/linux/dlm.h
index c743fbc769db..203a025e30e5 100644
--- a/include/linux/dlm.h
+++ b/include/linux/dlm.h
@@ -21,10 +21,7 @@
21 21
22/* Lock levels and flags are here */ 22/* Lock levels and flags are here */
23#include <linux/dlmconstants.h> 23#include <linux/dlmconstants.h>
24 24#include <linux/types.h>
25
26#define DLM_RESNAME_MAXLEN 64
27
28 25
29typedef void dlm_lockspace_t; 26typedef void dlm_lockspace_t;
30 27
@@ -63,7 +60,7 @@ typedef void dlm_lockspace_t;
63 60
64struct dlm_lksb { 61struct dlm_lksb {
65 int sb_status; 62 int sb_status;
66 uint32_t sb_lkid; 63 __u32 sb_lkid;
67 char sb_flags; 64 char sb_flags;
68 char * sb_lvbptr; 65 char * sb_lvbptr;
69}; 66};
diff --git a/include/linux/dlm_device.h b/include/linux/dlm_device.h
index 9642277a152a..c6034508fed9 100644
--- a/include/linux/dlm_device.h
+++ b/include/linux/dlm_device.h
@@ -11,10 +11,16 @@
11******************************************************************************* 11*******************************************************************************
12******************************************************************************/ 12******************************************************************************/
13 13
14#ifndef _LINUX_DLM_DEVICE_H
15#define _LINUX_DLM_DEVICE_H
16
14/* This is the device interface for dlm, most users will use a library 17/* This is the device interface for dlm, most users will use a library
15 * interface. 18 * interface.
16 */ 19 */
17 20
21#include <linux/dlm.h>
22#include <linux/types.h>
23
18#define DLM_USER_LVB_LEN 32 24#define DLM_USER_LVB_LEN 32
19 25
20/* Version of the device interface */ 26/* Version of the device interface */
@@ -94,10 +100,9 @@ struct dlm_lock_result {
94#define DLM_USER_PURGE 6 100#define DLM_USER_PURGE 6
95#define DLM_USER_DEADLOCK 7 101#define DLM_USER_DEADLOCK 7
96 102
97/* Arbitrary length restriction */
98#define MAX_LS_NAME_LEN 64
99
100/* Lockspace flags */ 103/* Lockspace flags */
101#define DLM_USER_LSFLG_AUTOFREE 1 104#define DLM_USER_LSFLG_AUTOFREE 1
102#define DLM_USER_LSFLG_FORCEFREE 2 105#define DLM_USER_LSFLG_FORCEFREE 2
103 106
107#endif
108
diff --git a/include/linux/dlm_plock.h b/include/linux/dlm_plock.h
new file mode 100644
index 000000000000..18d5fdbceb74
--- /dev/null
+++ b/include/linux/dlm_plock.h
@@ -0,0 +1,50 @@
1/*
2 * Copyright (C) 2005-2008 Red Hat, Inc. All rights reserved.
3 *
4 * This copyrighted material is made available to anyone wishing to use,
5 * modify, copy, or redistribute it subject to the terms and conditions
6 * of the GNU General Public License v.2.
7 */
8
9#ifndef __DLM_PLOCK_DOT_H__
10#define __DLM_PLOCK_DOT_H__
11
12#define DLM_PLOCK_MISC_NAME "dlm_plock"
13
14#define DLM_PLOCK_VERSION_MAJOR 1
15#define DLM_PLOCK_VERSION_MINOR 1
16#define DLM_PLOCK_VERSION_PATCH 0
17
18enum {
19 DLM_PLOCK_OP_LOCK = 1,
20 DLM_PLOCK_OP_UNLOCK,
21 DLM_PLOCK_OP_GET,
22};
23
24struct dlm_plock_info {
25 __u32 version[3];
26 __u8 optype;
27 __u8 ex;
28 __u8 wait;
29 __u8 pad;
30 __u32 pid;
31 __s32 nodeid;
32 __s32 rv;
33 __u32 fsid;
34 __u64 number;
35 __u64 start;
36 __u64 end;
37 __u64 owner;
38};
39
40#ifdef __KERNEL__
41int dlm_posix_lock(dlm_lockspace_t *lockspace, u64 number, struct file *file,
42 int cmd, struct file_lock *fl);
43int dlm_posix_unlock(dlm_lockspace_t *lockspace, u64 number, struct file *file,
44 struct file_lock *fl);
45int dlm_posix_get(dlm_lockspace_t *lockspace, u64 number, struct file *file,
46 struct file_lock *fl);
47#endif /* __KERNEL__ */
48
49#endif
50
diff --git a/include/linux/dlmconstants.h b/include/linux/dlmconstants.h
index fddb3d3ff321..47bf08dc7566 100644
--- a/include/linux/dlmconstants.h
+++ b/include/linux/dlmconstants.h
@@ -18,6 +18,10 @@
18 * Constants used by DLM interface. 18 * Constants used by DLM interface.
19 */ 19 */
20 20
21#define DLM_LOCKSPACE_LEN 64
22#define DLM_RESNAME_MAXLEN 64
23
24
21/* 25/*
22 * Lock Modes 26 * Lock Modes
23 */ 27 */
diff --git a/include/linux/hid.h b/include/linux/hid.h
index 74ff57596eb1..d951ec411241 100644
--- a/include/linux/hid.h
+++ b/include/linux/hid.h
@@ -284,6 +284,7 @@ struct hid_item {
284#define HID_QUIRK_2WHEEL_MOUSE_HACK_B8 0x02000000 284#define HID_QUIRK_2WHEEL_MOUSE_HACK_B8 0x02000000
285#define HID_QUIRK_HWHEEL_WHEEL_INVERT 0x04000000 285#define HID_QUIRK_HWHEEL_WHEEL_INVERT 0x04000000
286#define HID_QUIRK_MICROSOFT_KEYS 0x08000000 286#define HID_QUIRK_MICROSOFT_KEYS 0x08000000
287#define HID_QUIRK_FULLSPEED_INTERVAL 0x10000000
287 288
288/* 289/*
289 * Separate quirks for runtime report descriptor fixup 290 * Separate quirks for runtime report descriptor fixup
@@ -296,6 +297,8 @@ struct hid_item {
296#define HID_QUIRK_RDESC_MACBOOK_JIS 0x00000010 297#define HID_QUIRK_RDESC_MACBOOK_JIS 0x00000010
297#define HID_QUIRK_RDESC_BUTTON_CONSUMER 0x00000020 298#define HID_QUIRK_RDESC_BUTTON_CONSUMER 0x00000020
298#define HID_QUIRK_RDESC_SAMSUNG_REMOTE 0x00000040 299#define HID_QUIRK_RDESC_SAMSUNG_REMOTE 0x00000040
300#define HID_QUIRK_RDESC_MICROSOFT_RECV_1028 0x00000080
301#define HID_QUIRK_RDESC_SUNPLUS_WDESKTOP 0x00000100
299 302
300/* 303/*
301 * This is the global environment of the parser. This information is 304 * This is the global environment of the parser. This information is
@@ -320,7 +323,7 @@ struct hid_global {
320 * This is the local environment. It is persistent up the next main-item. 323 * This is the local environment. It is persistent up the next main-item.
321 */ 324 */
322 325
323#define HID_MAX_USAGES 8192 326#define HID_MAX_USAGES 12288
324#define HID_DEFAULT_NUM_COLLECTIONS 16 327#define HID_DEFAULT_NUM_COLLECTIONS 16
325 328
326struct hid_local { 329struct hid_local {
@@ -421,6 +424,7 @@ struct hid_control_fifo {
421#define HID_RESET_PENDING 4 424#define HID_RESET_PENDING 4
422#define HID_SUSPENDED 5 425#define HID_SUSPENDED 5
423#define HID_CLEAR_HALT 6 426#define HID_CLEAR_HALT 6
427#define HID_DISCONNECTED 7
424 428
425struct hid_input { 429struct hid_input {
426 struct list_head list; 430 struct list_head list;
@@ -452,8 +456,6 @@ struct hid_device { /* device report descriptor */
452 void *hidraw; 456 void *hidraw;
453 int minor; /* Hiddev minor number */ 457 int minor; /* Hiddev minor number */
454 458
455 wait_queue_head_t wait; /* For sleeping */
456
457 int open; /* is the device open by anyone? */ 459 int open; /* is the device open by anyone? */
458 char name[128]; /* Device name */ 460 char name[128]; /* Device name */
459 char phys[64]; /* Device physical location */ 461 char phys[64]; /* Device physical location */
@@ -530,14 +532,12 @@ int hidinput_find_field(struct hid_device *hid, unsigned int type, unsigned int
530int hidinput_mapping_quirks(struct hid_usage *, struct input_dev *, unsigned long **, int *); 532int hidinput_mapping_quirks(struct hid_usage *, struct input_dev *, unsigned long **, int *);
531int hidinput_event_quirks(struct hid_device *, struct hid_field *, struct hid_usage *, __s32); 533int hidinput_event_quirks(struct hid_device *, struct hid_field *, struct hid_usage *, __s32);
532int hidinput_apple_event(struct hid_device *, struct input_dev *, struct hid_usage *, __s32); 534int hidinput_apple_event(struct hid_device *, struct input_dev *, struct hid_usage *, __s32);
533void hid_input_field(struct hid_device *hid, struct hid_field *field, __u8 *data, int interrupt);
534void hid_output_report(struct hid_report *report, __u8 *data); 535void hid_output_report(struct hid_report *report, __u8 *data);
535void hid_free_device(struct hid_device *device); 536void hid_free_device(struct hid_device *device);
536struct hid_device *hid_parse_report(__u8 *start, unsigned size); 537struct hid_device *hid_parse_report(__u8 *start, unsigned size);
537 538
538/* HID quirks API */ 539/* HID quirks API */
539u32 usbhid_lookup_quirk(const u16 idVendor, const u16 idProduct); 540u32 usbhid_lookup_quirk(const u16 idVendor, const u16 idProduct);
540int usbhid_modify_dquirk(const u16 idVendor, const u16 idProduct, const u32 quirks);
541int usbhid_quirks_init(char **quirks_param); 541int usbhid_quirks_init(char **quirks_param);
542void usbhid_quirks_exit(void); 542void usbhid_quirks_exit(void);
543void usbhid_fixup_report_descriptor(const u16, const u16, char *, unsigned, char **); 543void usbhid_fixup_report_descriptor(const u16, const u16, char *, unsigned, char **);
@@ -546,6 +546,7 @@ void usbhid_fixup_report_descriptor(const u16, const u16, char *, unsigned, char
546int hid_ff_init(struct hid_device *hid); 546int hid_ff_init(struct hid_device *hid);
547 547
548int hid_lgff_init(struct hid_device *hid); 548int hid_lgff_init(struct hid_device *hid);
549int hid_lg2ff_init(struct hid_device *hid);
549int hid_plff_init(struct hid_device *hid); 550int hid_plff_init(struct hid_device *hid);
550int hid_tmff_init(struct hid_device *hid); 551int hid_tmff_init(struct hid_device *hid);
551int hid_zpff_init(struct hid_device *hid); 552int hid_zpff_init(struct hid_device *hid);
@@ -566,7 +567,11 @@ static inline int hid_ff_init(struct hid_device *hid) { return -1; }
566#define dbg_hid_line(format, arg...) if (hid_debug) \ 567#define dbg_hid_line(format, arg...) if (hid_debug) \
567 printk(format, ## arg) 568 printk(format, ## arg)
568#else 569#else
569#define dbg_hid(format, arg...) do {} while (0) 570static inline int __attribute__((format(printf, 1, 2)))
571dbg_hid(const char *fmt, ...)
572{
573 return 0;
574}
570#define dbg_hid_line dbg_hid 575#define dbg_hid_line dbg_hid
571#endif 576#endif
572 577
diff --git a/include/linux/hidraw.h b/include/linux/hidraw.h
index 0536f299f7ff..dbb5c8c374f0 100644
--- a/include/linux/hidraw.h
+++ b/include/linux/hidraw.h
@@ -16,6 +16,7 @@
16 */ 16 */
17 17
18#include <linux/hid.h> 18#include <linux/hid.h>
19#include <linux/types.h>
19 20
20struct hidraw_report_descriptor { 21struct hidraw_report_descriptor {
21 __u32 size; 22 __u32 size;
diff --git a/include/linux/i2c-algo-pca.h b/include/linux/i2c-algo-pca.h
index fce47c051bb1..adcb3dc7ac26 100644
--- a/include/linux/i2c-algo-pca.h
+++ b/include/linux/i2c-algo-pca.h
@@ -1,14 +1,41 @@
1#ifndef _LINUX_I2C_ALGO_PCA_H 1#ifndef _LINUX_I2C_ALGO_PCA_H
2#define _LINUX_I2C_ALGO_PCA_H 2#define _LINUX_I2C_ALGO_PCA_H
3 3
4/* Clock speeds for the bus */
5#define I2C_PCA_CON_330kHz 0x00
6#define I2C_PCA_CON_288kHz 0x01
7#define I2C_PCA_CON_217kHz 0x02
8#define I2C_PCA_CON_146kHz 0x03
9#define I2C_PCA_CON_88kHz 0x04
10#define I2C_PCA_CON_59kHz 0x05
11#define I2C_PCA_CON_44kHz 0x06
12#define I2C_PCA_CON_36kHz 0x07
13
14/* PCA9564 registers */
15#define I2C_PCA_STA 0x00 /* STATUS Read Only */
16#define I2C_PCA_TO 0x00 /* TIMEOUT Write Only */
17#define I2C_PCA_DAT 0x01 /* DATA Read/Write */
18#define I2C_PCA_ADR 0x02 /* OWN ADR Read/Write */
19#define I2C_PCA_CON 0x03 /* CONTROL Read/Write */
20
21#define I2C_PCA_CON_AA 0x80 /* Assert Acknowledge */
22#define I2C_PCA_CON_ENSIO 0x40 /* Enable */
23#define I2C_PCA_CON_STA 0x20 /* Start */
24#define I2C_PCA_CON_STO 0x10 /* Stop */
25#define I2C_PCA_CON_SI 0x08 /* Serial Interrupt */
26#define I2C_PCA_CON_CR 0x07 /* Clock Rate (MASK) */
27
4struct i2c_algo_pca_data { 28struct i2c_algo_pca_data {
5 int (*get_own) (struct i2c_algo_pca_data *adap); /* Obtain own address */ 29 void *data; /* private low level data */
6 int (*get_clock) (struct i2c_algo_pca_data *adap); 30 void (*write_byte) (void *data, int reg, int val);
7 void (*write_byte) (struct i2c_algo_pca_data *adap, int reg, int val); 31 int (*read_byte) (void *data, int reg);
8 int (*read_byte) (struct i2c_algo_pca_data *adap, int reg); 32 int (*wait_for_completion) (void *data);
9 int (*wait_for_interrupt) (struct i2c_algo_pca_data *adap); 33 void (*reset_chip) (void *data);
34 /* i2c_clock values are defined in linux/i2c-algo-pca.h */
35 unsigned int i2c_clock;
10}; 36};
11 37
12int i2c_pca_add_bus(struct i2c_adapter *); 38int i2c_pca_add_bus(struct i2c_adapter *);
39int i2c_pca_add_numbered_bus(struct i2c_adapter *);
13 40
14#endif /* _LINUX_I2C_ALGO_PCA_H */ 41#endif /* _LINUX_I2C_ALGO_PCA_H */
diff --git a/include/linux/i2c-pca-platform.h b/include/linux/i2c-pca-platform.h
new file mode 100644
index 000000000000..3d191873f2d1
--- /dev/null
+++ b/include/linux/i2c-pca-platform.h
@@ -0,0 +1,12 @@
1#ifndef I2C_PCA9564_PLATFORM_H
2#define I2C_PCA9564_PLATFORM_H
3
4struct i2c_pca9564_pf_platform_data {
5 int gpio; /* pin to reset chip. driver will work when
6 * not supplied (negative value), but it
7 * cannot exit some error conditions then */
8 int i2c_clock_speed; /* values are defined in linux/i2c-algo-pca.h */
9 int timeout; /* timeout = this value * 10us */
10};
11
12#endif /* I2C_PCA9564_PLATFORM_H */
diff --git a/include/linux/lock_dlm_plock.h b/include/linux/lock_dlm_plock.h
deleted file mode 100644
index fc3415113973..000000000000
--- a/include/linux/lock_dlm_plock.h
+++ /dev/null
@@ -1,41 +0,0 @@
1/*
2 * Copyright (C) 2005 Red Hat, Inc. All rights reserved.
3 *
4 * This copyrighted material is made available to anyone wishing to use,
5 * modify, copy, or redistribute it subject to the terms and conditions
6 * of the GNU General Public License v.2.
7 */
8
9#ifndef __LOCK_DLM_PLOCK_DOT_H__
10#define __LOCK_DLM_PLOCK_DOT_H__
11
12#define GDLM_PLOCK_MISC_NAME "lock_dlm_plock"
13
14#define GDLM_PLOCK_VERSION_MAJOR 1
15#define GDLM_PLOCK_VERSION_MINOR 1
16#define GDLM_PLOCK_VERSION_PATCH 0
17
18enum {
19 GDLM_PLOCK_OP_LOCK = 1,
20 GDLM_PLOCK_OP_UNLOCK,
21 GDLM_PLOCK_OP_GET,
22};
23
24struct gdlm_plock_info {
25 __u32 version[3];
26 __u8 optype;
27 __u8 ex;
28 __u8 wait;
29 __u8 pad;
30 __u32 pid;
31 __s32 nodeid;
32 __s32 rv;
33 __u32 fsid;
34 __u64 number;
35 __u64 start;
36 __u64 end;
37 __u64 owner;
38};
39
40#endif
41
diff --git a/include/linux/udf_fs.h b/include/linux/udf_fs.h
deleted file mode 100644
index aa88654eb76b..000000000000
--- a/include/linux/udf_fs.h
+++ /dev/null
@@ -1,51 +0,0 @@
1/*
2 * udf_fs.h
3 *
4 * PURPOSE
5 * Included by fs/filesystems.c
6 *
7 * DESCRIPTION
8 * OSTA-UDF(tm) = Optical Storage Technology Association
9 * Universal Disk Format.
10 *
11 * This code is based on version 2.50 of the UDF specification,
12 * and revision 3 of the ECMA 167 standard [equivalent to ISO 13346].
13 * http://www.osta.org/ * http://www.ecma.ch/
14 * http://www.iso.org/
15 *
16 * COPYRIGHT
17 * This file is distributed under the terms of the GNU General Public
18 * License (GPL). Copies of the GPL can be obtained from:
19 * ftp://prep.ai.mit.edu/pub/gnu/GPL
20 * Each contributing author retains all rights to their own work.
21 *
22 * (C) 1999-2004 Ben Fennema
23 * (C) 1999-2000 Stelias Computing Inc
24 *
25 * HISTORY
26 *
27 */
28
29#ifndef _UDF_FS_H
30#define _UDF_FS_H 1
31
32#define UDF_PREALLOCATE
33#define UDF_DEFAULT_PREALLOC_BLOCKS 8
34
35#undef UDFFS_DEBUG
36
37#ifdef UDFFS_DEBUG
38#define udf_debug(f, a...) \
39 do { \
40 printk (KERN_DEBUG "UDF-fs DEBUG %s:%d:%s: ", \
41 __FILE__, __LINE__, __FUNCTION__); \
42 printk (f, ##a); \
43 } while (0)
44#else
45#define udf_debug(f, a...) /**/
46#endif
47
48#define udf_info(f, a...) \
49 printk (KERN_INFO "UDF-fs INFO " f, ##a);
50
51#endif /* _UDF_FS_H */
diff --git a/include/linux/udf_fs_i.h b/include/linux/udf_fs_i.h
index ffaf05679ffb..3536965913b0 100644
--- a/include/linux/udf_fs_i.h
+++ b/include/linux/udf_fs_i.h
@@ -9,41 +9,10 @@
9 * ftp://prep.ai.mit.edu/pub/gnu/GPL 9 * ftp://prep.ai.mit.edu/pub/gnu/GPL
10 * Each contributing author retains all rights to their own work. 10 * Each contributing author retains all rights to their own work.
11 */ 11 */
12
13#ifndef _UDF_FS_I_H 12#ifndef _UDF_FS_I_H
14#define _UDF_FS_I_H 1 13#define _UDF_FS_I_H 1
15 14
16#ifdef __KERNEL__
17
18struct udf_inode_info
19{
20 struct timespec i_crtime;
21 /* Physical address of inode */
22 kernel_lb_addr i_location;
23 __u64 i_unique;
24 __u32 i_lenEAttr;
25 __u32 i_lenAlloc;
26 __u64 i_lenExtents;
27 __u32 i_next_alloc_block;
28 __u32 i_next_alloc_goal;
29 unsigned i_alloc_type : 3;
30 unsigned i_efe : 1;
31 unsigned i_use : 1;
32 unsigned i_strat4096 : 1;
33 unsigned reserved : 26;
34 union
35 {
36 short_ad *i_sad;
37 long_ad *i_lad;
38 __u8 *i_data;
39 } i_ext;
40 struct inode vfs_inode;
41};
42
43#endif
44
45/* exported IOCTLs, we have 'l', 0x40-0x7f */ 15/* exported IOCTLs, we have 'l', 0x40-0x7f */
46
47#define UDF_GETEASIZE _IOR('l', 0x40, int) 16#define UDF_GETEASIZE _IOR('l', 0x40, int)
48#define UDF_GETEABLOCK _IOR('l', 0x41, void *) 17#define UDF_GETEABLOCK _IOR('l', 0x41, void *)
49#define UDF_GETVOLIDENT _IOR('l', 0x42, void *) 18#define UDF_GETVOLIDENT _IOR('l', 0x42, void *)
diff --git a/include/linux/udf_fs_sb.h b/include/linux/udf_fs_sb.h
deleted file mode 100644
index 9bc47352b6b4..000000000000
--- a/include/linux/udf_fs_sb.h
+++ /dev/null
@@ -1,117 +0,0 @@
1/*
2 * udf_fs_sb.h
3 *
4 * This include file is for the Linux kernel/module.
5 *
6 * COPYRIGHT
7 * This file is distributed under the terms of the GNU General Public
8 * License (GPL). Copies of the GPL can be obtained from:
9 * ftp://prep.ai.mit.edu/pub/gnu/GPL
10 * Each contributing author retains all rights to their own work.
11 */
12
13#ifndef _UDF_FS_SB_H
14#define _UDF_FS_SB_H 1
15
16#include <linux/mutex.h>
17
18#pragma pack(1)
19
20#define UDF_MAX_BLOCK_LOADED 8
21
22#define UDF_TYPE1_MAP15 0x1511U
23#define UDF_VIRTUAL_MAP15 0x1512U
24#define UDF_VIRTUAL_MAP20 0x2012U
25#define UDF_SPARABLE_MAP15 0x1522U
26
27struct udf_sparing_data
28{
29 __u16 s_packet_len;
30 struct buffer_head *s_spar_map[4];
31};
32
33struct udf_virtual_data
34{
35 __u32 s_num_entries;
36 __u16 s_start_offset;
37};
38
39struct udf_bitmap
40{
41 __u32 s_extLength;
42 __u32 s_extPosition;
43 __u16 s_nr_groups;
44 struct buffer_head **s_block_bitmap;
45};
46
47struct udf_part_map
48{
49 union
50 {
51 struct udf_bitmap *s_bitmap;
52 struct inode *s_table;
53 } s_uspace;
54 union
55 {
56 struct udf_bitmap *s_bitmap;
57 struct inode *s_table;
58 } s_fspace;
59 __u32 s_partition_root;
60 __u32 s_partition_len;
61 __u16 s_partition_type;
62 __u16 s_partition_num;
63 union
64 {
65 struct udf_sparing_data s_sparing;
66 struct udf_virtual_data s_virtual;
67 } s_type_specific;
68 __u32 (*s_partition_func)(struct super_block *, __u32, __u16, __u32);
69 __u16 s_volumeseqnum;
70 __u16 s_partition_flags;
71};
72
73#pragma pack()
74
75struct udf_sb_info
76{
77 struct udf_part_map *s_partmaps;
78 __u8 s_volume_ident[32];
79
80 /* Overall info */
81 __u16 s_partitions;
82 __u16 s_partition;
83
84 /* Sector headers */
85 __s32 s_session;
86 __u32 s_anchor[4];
87 __u32 s_last_block;
88
89 struct buffer_head *s_lvid_bh;
90
91 /* Default permissions */
92 mode_t s_umask;
93 gid_t s_gid;
94 uid_t s_uid;
95
96 /* Root Info */
97 struct timespec s_record_time;
98
99 /* Fileset Info */
100 __u16 s_serial_number;
101
102 /* highest UDF revision we have recorded to this media */
103 __u16 s_udfrev;
104
105 /* Miscellaneous flags */
106 __u32 s_flags;
107
108 /* Encoding info */
109 struct nls_table *s_nls_map;
110
111 /* VAT inode */
112 struct inode *s_vat_inode;
113
114 struct mutex s_alloc_mutex;
115};
116
117#endif /* _UDF_FS_SB_H */
diff --git a/kernel/sched.c b/kernel/sched.c
index 57ba7ea9b744..0014b03adaca 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -7035,6 +7035,7 @@ static int find_next_best_node(int node, nodemask_t *used_nodes)
7035/** 7035/**
7036 * sched_domain_node_span - get a cpumask for a node's sched_domain 7036 * sched_domain_node_span - get a cpumask for a node's sched_domain
7037 * @node: node whose cpumask we're constructing 7037 * @node: node whose cpumask we're constructing
7038 * @span: resulting cpumask
7038 * 7039 *
7039 * Given a node, construct a good cpumask for its sched_domain to span. It 7040 * Given a node, construct a good cpumask for its sched_domain to span. It
7040 * should be one that prevents unnecessary balancing, but also spreads tasks 7041 * should be one that prevents unnecessary balancing, but also spreads tasks
diff --git a/net/core/sock.c b/net/core/sock.c
index 5ac052693554..5dbb81bc9673 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -450,15 +450,6 @@ int sock_setsockopt(struct socket *sock, int level, int optname,
450 * Options without arguments 450 * Options without arguments
451 */ 451 */
452 452
453#ifdef SO_DONTLINGER /* Compatibility item... */
454 if (optname == SO_DONTLINGER) {
455 lock_sock(sk);
456 sock_reset_flag(sk, SOCK_LINGER);
457 release_sock(sk);
458 return 0;
459 }
460#endif
461
462 if (optname == SO_BINDTODEVICE) 453 if (optname == SO_BINDTODEVICE)
463 return sock_bindtodevice(sk, optval, optlen); 454 return sock_bindtodevice(sk, optval, optlen);
464 455