aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/mach-imx/mach-cpuimx27.c4
-rw-r--r--arch/arm/mach-imx/mach-pca100.c4
-rw-r--r--arch/arm/mach-mx25/mach-cpuimx25.c2
-rw-r--r--arch/arm/mach-mx3/mach-cpuimx35.c2
-rw-r--r--arch/powerpc/Makefile2
-rw-r--r--arch/powerpc/boot/dts/canyonlands.dts8
-rw-r--r--arch/powerpc/include/asm/mmu-hash64.h2
-rw-r--r--arch/powerpc/include/asm/reg.h9
-rw-r--r--arch/powerpc/include/asm/rwsem.h64
-rw-r--r--arch/powerpc/include/asm/systbl.h3
-rw-r--r--arch/powerpc/include/asm/unistd.h5
-rw-r--r--arch/powerpc/kernel/cputable.c1
-rw-r--r--arch/powerpc/kernel/crash.c24
-rw-r--r--arch/powerpc/kernel/head_44x.S4
-rw-r--r--arch/powerpc/kernel/head_64.S6
-rw-r--r--arch/powerpc/kernel/idle.c2
-rw-r--r--arch/powerpc/kernel/irq.c16
-rw-r--r--arch/powerpc/kernel/pci_of_scan.c2
-rw-r--r--arch/powerpc/kernel/process.c20
-rw-r--r--arch/powerpc/kernel/setup_32.c9
-rw-r--r--arch/powerpc/kernel/setup_64.c63
-rw-r--r--arch/powerpc/kernel/smp.c4
-rw-r--r--arch/powerpc/kernel/sys_ppc32.c8
-rw-r--r--arch/powerpc/kernel/vio.c3
-rw-r--r--arch/powerpc/mm/init_64.c2
-rw-r--r--arch/powerpc/mm/tlb_nohash_low.S1
-rw-r--r--arch/powerpc/platforms/Kconfig3
-rw-r--r--arch/powerpc/platforms/cell/iommu.c2
-rw-r--r--arch/powerpc/platforms/iseries/iommu.c2
-rw-r--r--arch/powerpc/platforms/powermac/feature.c3
-rw-r--r--arch/powerpc/platforms/powermac/pci.c2
-rw-r--r--arch/powerpc/platforms/pseries/iommu.c8
-rw-r--r--arch/powerpc/platforms/pseries/smp.c11
-rw-r--r--arch/powerpc/platforms/pseries/xics.c6
-rw-r--r--arch/sparc/include/asm/atomic_64.h8
-rw-r--r--arch/sparc/include/asm/backoff.h11
-rw-r--r--arch/sparc/include/asm/oplib_64.h27
-rw-r--r--arch/sparc/include/asm/rwsem-const.h12
-rw-r--r--arch/sparc/include/asm/rwsem.h120
-rw-r--r--arch/sparc/include/asm/system_64.h1
-rw-r--r--arch/sparc/lib/Makefile2
-rw-r--r--arch/sparc/lib/atomic_64.S36
-rw-r--r--arch/sparc/lib/bitops.S12
-rw-r--r--arch/sparc/lib/rwsem_64.S163
-rw-r--r--arch/sparc/prom/cif.S16
-rw-r--r--arch/sparc/prom/console_64.c48
-rw-r--r--arch/sparc/prom/devops_64.c36
-rw-r--r--arch/sparc/prom/misc_64.c314
-rw-r--r--arch/sparc/prom/p1275.c102
-rw-r--r--arch/sparc/prom/tree_64.c210
-rw-r--r--drivers/base/firmware_class.c2
-rw-r--r--drivers/char/ip2/ip2main.c4
-rw-r--r--drivers/char/rocket.c1
-rw-r--r--drivers/char/synclink_gt.c4
-rw-r--r--drivers/macintosh/via-pmu.c42
-rw-r--r--drivers/media/dvb/mantis/Kconfig2
-rw-r--r--drivers/platform/x86/intel_rar_register.c2
-rw-r--r--drivers/platform/x86/intel_scu_ipc.c2
-rw-r--r--drivers/serial/68328serial.c29
-rw-r--r--drivers/serial/8250_early.c4
-rw-r--r--drivers/staging/Kconfig2
-rw-r--r--drivers/staging/Makefile1
-rw-r--r--drivers/staging/batman-adv/bat_sysfs.c4
-rw-r--r--drivers/staging/batman-adv/hard-interface.c29
-rw-r--r--drivers/staging/batman-adv/icmp_socket.c12
-rw-r--r--drivers/staging/batman-adv/main.c7
-rw-r--r--drivers/staging/batman-adv/originator.c14
-rw-r--r--drivers/staging/batman-adv/routing.c16
-rw-r--r--drivers/staging/batman-adv/types.h1
-rw-r--r--drivers/staging/sep/Kconfig10
-rw-r--r--drivers/staging/sep/Makefile2
-rw-r--r--drivers/staging/sep/TODO8
-rw-r--r--drivers/staging/sep/sep_dev.h110
-rw-r--r--drivers/staging/sep/sep_driver.c2742
-rw-r--r--drivers/staging/sep/sep_driver_api.h425
-rw-r--r--drivers/staging/sep/sep_driver_config.h225
-rw-r--r--drivers/staging/sep/sep_driver_hw_defs.h232
-rw-r--r--drivers/staging/spectra/ffsport.c29
-rw-r--r--drivers/staging/spectra/flash.c420
-rw-r--r--drivers/usb/gadget/composite.c4
-rw-r--r--drivers/usb/gadget/m66592-udc.c1
-rw-r--r--drivers/usb/gadget/r8a66597-udc.c1
-rw-r--r--drivers/usb/gadget/uvc_v4l2.c2
-rw-r--r--drivers/usb/host/isp1760-hcd.c2
-rw-r--r--drivers/usb/host/xhci-ring.c6
-rw-r--r--drivers/usb/misc/adutux.c2
-rw-r--r--drivers/usb/misc/iowarrior.c4
-rw-r--r--drivers/usb/otg/twl4030-usb.c6
-rw-r--r--drivers/usb/serial/cp210x.c4
-rw-r--r--drivers/usb/serial/ftdi_sio.c5
-rw-r--r--drivers/usb/serial/ftdi_sio_ids.h9
-rw-r--r--drivers/usb/serial/generic.c1
-rw-r--r--drivers/usb/serial/io_ti.c4
-rw-r--r--drivers/usb/serial/navman.c1
-rw-r--r--drivers/usb/serial/option.c7
-rw-r--r--drivers/usb/serial/pl2303.c1
-rw-r--r--drivers/usb/serial/pl2303.h4
-rw-r--r--drivers/usb/serial/ssu100.c254
-rw-r--r--drivers/usb/serial/usb-serial.c23
-rw-r--r--include/linux/kobject.h35
-rw-r--r--include/linux/kobject_ns.h56
-rw-r--r--include/linux/sysfs.h1
-rw-r--r--include/linux/usb/composite.h1
-rw-r--r--lib/kobject_uevent.c4
104 files changed, 1196 insertions, 5048 deletions
diff --git a/arch/arm/mach-imx/mach-cpuimx27.c b/arch/arm/mach-imx/mach-cpuimx27.c
index 575ff1ae85a7..339150ab0ea5 100644
--- a/arch/arm/mach-imx/mach-cpuimx27.c
+++ b/arch/arm/mach-imx/mach-cpuimx27.c
@@ -279,13 +279,13 @@ static void __init eukrea_cpuimx27_init(void)
279#if defined(CONFIG_USB_ULPI) 279#if defined(CONFIG_USB_ULPI)
280 if (otg_mode_host) { 280 if (otg_mode_host) {
281 otg_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops, 281 otg_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops,
282 USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT); 282 ULPI_OTG_DRVVBUS | ULPI_OTG_DRVVBUS_EXT);
283 283
284 mxc_register_device(&mxc_otg_host, &otg_pdata); 284 mxc_register_device(&mxc_otg_host, &otg_pdata);
285 } 285 }
286 286
287 usbh2_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops, 287 usbh2_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops,
288 USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT); 288 ULPI_OTG_DRVVBUS | ULPI_OTG_DRVVBUS_EXT);
289 289
290 mxc_register_device(&mxc_usbh2, &usbh2_pdata); 290 mxc_register_device(&mxc_usbh2, &usbh2_pdata);
291#endif 291#endif
diff --git a/arch/arm/mach-imx/mach-pca100.c b/arch/arm/mach-imx/mach-pca100.c
index a389d1148f18..23c9e1f37b9c 100644
--- a/arch/arm/mach-imx/mach-pca100.c
+++ b/arch/arm/mach-imx/mach-pca100.c
@@ -419,13 +419,13 @@ static void __init pca100_init(void)
419#if defined(CONFIG_USB_ULPI) 419#if defined(CONFIG_USB_ULPI)
420 if (otg_mode_host) { 420 if (otg_mode_host) {
421 otg_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops, 421 otg_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops,
422 USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT); 422 ULPI_OTG_DRVVBUS | ULPI_OTG_DRVVBUS_EXT);
423 423
424 mxc_register_device(&mxc_otg_host, &otg_pdata); 424 mxc_register_device(&mxc_otg_host, &otg_pdata);
425 } 425 }
426 426
427 usbh2_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops, 427 usbh2_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops,
428 USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT); 428 ULPI_OTG_DRVVBUS | ULPI_OTG_DRVVBUS_EXT);
429 429
430 mxc_register_device(&mxc_usbh2, &usbh2_pdata); 430 mxc_register_device(&mxc_usbh2, &usbh2_pdata);
431#endif 431#endif
diff --git a/arch/arm/mach-mx25/mach-cpuimx25.c b/arch/arm/mach-mx25/mach-cpuimx25.c
index 56b2e26d23b4..a5f0174290b4 100644
--- a/arch/arm/mach-mx25/mach-cpuimx25.c
+++ b/arch/arm/mach-mx25/mach-cpuimx25.c
@@ -138,7 +138,7 @@ static void __init eukrea_cpuimx25_init(void)
138#if defined(CONFIG_USB_ULPI) 138#if defined(CONFIG_USB_ULPI)
139 if (otg_mode_host) { 139 if (otg_mode_host) {
140 otg_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops, 140 otg_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops,
141 USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT); 141 ULPI_OTG_DRVVBUS | ULPI_OTG_DRVVBUS_EXT);
142 142
143 mxc_register_device(&mxc_otg, &otg_pdata); 143 mxc_register_device(&mxc_otg, &otg_pdata);
144 } 144 }
diff --git a/arch/arm/mach-mx3/mach-cpuimx35.c b/arch/arm/mach-mx3/mach-cpuimx35.c
index 63f970f340a2..9770a6a973be 100644
--- a/arch/arm/mach-mx3/mach-cpuimx35.c
+++ b/arch/arm/mach-mx3/mach-cpuimx35.c
@@ -192,7 +192,7 @@ static void __init mxc_board_init(void)
192#if defined(CONFIG_USB_ULPI) 192#if defined(CONFIG_USB_ULPI)
193 if (otg_mode_host) { 193 if (otg_mode_host) {
194 otg_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops, 194 otg_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops,
195 USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT); 195 ULPI_OTG_DRVVBUS | ULPI_OTG_DRVVBUS_EXT);
196 196
197 mxc_register_device(&mxc_otg_host, &otg_pdata); 197 mxc_register_device(&mxc_otg_host, &otg_pdata);
198 } 198 }
diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile
index e3ea151c9597..b7212b619c52 100644
--- a/arch/powerpc/Makefile
+++ b/arch/powerpc/Makefile
@@ -164,7 +164,7 @@ drivers-$(CONFIG_OPROFILE) += arch/powerpc/oprofile/
164all: zImage 164all: zImage
165 165
166# With make 3.82 we cannot mix normal and wildcard targets 166# With make 3.82 we cannot mix normal and wildcard targets
167BOOT_TARGETS1 := zImage zImage.initrd uImaged 167BOOT_TARGETS1 := zImage zImage.initrd uImage
168BOOT_TARGETS2 := zImage% dtbImage% treeImage.% cuImage.% simpleImage.% 168BOOT_TARGETS2 := zImage% dtbImage% treeImage.% cuImage.% simpleImage.%
169 169
170PHONY += $(BOOT_TARGETS1) $(BOOT_TARGETS2) 170PHONY += $(BOOT_TARGETS1) $(BOOT_TARGETS2)
diff --git a/arch/powerpc/boot/dts/canyonlands.dts b/arch/powerpc/boot/dts/canyonlands.dts
index 5806ef0b860b..a30370396250 100644
--- a/arch/powerpc/boot/dts/canyonlands.dts
+++ b/arch/powerpc/boot/dts/canyonlands.dts
@@ -163,6 +163,14 @@
163 interrupts = <0x1e 4>; 163 interrupts = <0x1e 4>;
164 }; 164 };
165 165
166 SATA0: sata@bffd1000 {
167 compatible = "amcc,sata-460ex";
168 reg = <4 0xbffd1000 0x800 4 0xbffd0800 0x400>;
169 interrupt-parent = <&UIC3>;
170 interrupts = <0x0 0x4 /* SATA */
171 0x5 0x4>; /* AHBDMA */
172 };
173
166 POB0: opb { 174 POB0: opb {
167 compatible = "ibm,opb-460ex", "ibm,opb"; 175 compatible = "ibm,opb-460ex", "ibm,opb";
168 #address-cells = <1>; 176 #address-cells = <1>;
diff --git a/arch/powerpc/include/asm/mmu-hash64.h b/arch/powerpc/include/asm/mmu-hash64.h
index 0e398cfee2c8..acac35d5b382 100644
--- a/arch/powerpc/include/asm/mmu-hash64.h
+++ b/arch/powerpc/include/asm/mmu-hash64.h
@@ -433,7 +433,7 @@ typedef struct {
433 * with. However gcc is not clever enough to compute the 433 * with. However gcc is not clever enough to compute the
434 * modulus (2^n-1) without a second multiply. 434 * modulus (2^n-1) without a second multiply.
435 */ 435 */
436#define vsid_scrample(protovsid, size) \ 436#define vsid_scramble(protovsid, size) \
437 ((((protovsid) * VSID_MULTIPLIER_##size) % VSID_MODULUS_##size)) 437 ((((protovsid) * VSID_MULTIPLIER_##size) % VSID_MODULUS_##size))
438 438
439#else /* 1 */ 439#else /* 1 */
diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h
index d8be016d2ede..ff0005eec7dd 100644
--- a/arch/powerpc/include/asm/reg.h
+++ b/arch/powerpc/include/asm/reg.h
@@ -951,7 +951,14 @@
951#ifdef CONFIG_PPC64 951#ifdef CONFIG_PPC64
952 952
953extern void ppc64_runlatch_on(void); 953extern void ppc64_runlatch_on(void);
954extern void ppc64_runlatch_off(void); 954extern void __ppc64_runlatch_off(void);
955
956#define ppc64_runlatch_off() \
957 do { \
958 if (cpu_has_feature(CPU_FTR_CTRL) && \
959 test_thread_flag(TIF_RUNLATCH)) \
960 __ppc64_runlatch_off(); \
961 } while (0)
955 962
956extern unsigned long scom970_read(unsigned int address); 963extern unsigned long scom970_read(unsigned int address);
957extern void scom970_write(unsigned int address, unsigned long value); 964extern void scom970_write(unsigned int address, unsigned long value);
diff --git a/arch/powerpc/include/asm/rwsem.h b/arch/powerpc/include/asm/rwsem.h
index 24cd9281ec37..8447d89fbe72 100644
--- a/arch/powerpc/include/asm/rwsem.h
+++ b/arch/powerpc/include/asm/rwsem.h
@@ -21,15 +21,20 @@
21/* 21/*
22 * the semaphore definition 22 * the semaphore definition
23 */ 23 */
24struct rw_semaphore { 24#ifdef CONFIG_PPC64
25 /* XXX this should be able to be an atomic_t -- paulus */ 25# define RWSEM_ACTIVE_MASK 0xffffffffL
26 signed int count; 26#else
27#define RWSEM_UNLOCKED_VALUE 0x00000000 27# define RWSEM_ACTIVE_MASK 0x0000ffffL
28#define RWSEM_ACTIVE_BIAS 0x00000001 28#endif
29#define RWSEM_ACTIVE_MASK 0x0000ffff 29
30#define RWSEM_WAITING_BIAS (-0x00010000) 30#define RWSEM_UNLOCKED_VALUE 0x00000000L
31#define RWSEM_ACTIVE_BIAS 0x00000001L
32#define RWSEM_WAITING_BIAS (-RWSEM_ACTIVE_MASK-1)
31#define RWSEM_ACTIVE_READ_BIAS RWSEM_ACTIVE_BIAS 33#define RWSEM_ACTIVE_READ_BIAS RWSEM_ACTIVE_BIAS
32#define RWSEM_ACTIVE_WRITE_BIAS (RWSEM_WAITING_BIAS + RWSEM_ACTIVE_BIAS) 34#define RWSEM_ACTIVE_WRITE_BIAS (RWSEM_WAITING_BIAS + RWSEM_ACTIVE_BIAS)
35
36struct rw_semaphore {
37 long count;
33 spinlock_t wait_lock; 38 spinlock_t wait_lock;
34 struct list_head wait_list; 39 struct list_head wait_list;
35#ifdef CONFIG_DEBUG_LOCK_ALLOC 40#ifdef CONFIG_DEBUG_LOCK_ALLOC
@@ -43,9 +48,13 @@ struct rw_semaphore {
43# define __RWSEM_DEP_MAP_INIT(lockname) 48# define __RWSEM_DEP_MAP_INIT(lockname)
44#endif 49#endif
45 50
46#define __RWSEM_INITIALIZER(name) \ 51#define __RWSEM_INITIALIZER(name) \
47 { RWSEM_UNLOCKED_VALUE, __SPIN_LOCK_UNLOCKED((name).wait_lock), \ 52{ \
48 LIST_HEAD_INIT((name).wait_list) __RWSEM_DEP_MAP_INIT(name) } 53 RWSEM_UNLOCKED_VALUE, \
54 __SPIN_LOCK_UNLOCKED((name).wait_lock), \
55 LIST_HEAD_INIT((name).wait_list) \
56 __RWSEM_DEP_MAP_INIT(name) \
57}
49 58
50#define DECLARE_RWSEM(name) \ 59#define DECLARE_RWSEM(name) \
51 struct rw_semaphore name = __RWSEM_INITIALIZER(name) 60 struct rw_semaphore name = __RWSEM_INITIALIZER(name)
@@ -70,13 +79,13 @@ extern void __init_rwsem(struct rw_semaphore *sem, const char *name,
70 */ 79 */
71static inline void __down_read(struct rw_semaphore *sem) 80static inline void __down_read(struct rw_semaphore *sem)
72{ 81{
73 if (unlikely(atomic_inc_return((atomic_t *)(&sem->count)) <= 0)) 82 if (unlikely(atomic_long_inc_return((atomic_long_t *)&sem->count) <= 0))
74 rwsem_down_read_failed(sem); 83 rwsem_down_read_failed(sem);
75} 84}
76 85
77static inline int __down_read_trylock(struct rw_semaphore *sem) 86static inline int __down_read_trylock(struct rw_semaphore *sem)
78{ 87{
79 int tmp; 88 long tmp;
80 89
81 while ((tmp = sem->count) >= 0) { 90 while ((tmp = sem->count) >= 0) {
82 if (tmp == cmpxchg(&sem->count, tmp, 91 if (tmp == cmpxchg(&sem->count, tmp,
@@ -92,10 +101,10 @@ static inline int __down_read_trylock(struct rw_semaphore *sem)
92 */ 101 */
93static inline void __down_write_nested(struct rw_semaphore *sem, int subclass) 102static inline void __down_write_nested(struct rw_semaphore *sem, int subclass)
94{ 103{
95 int tmp; 104 long tmp;
96 105
97 tmp = atomic_add_return(RWSEM_ACTIVE_WRITE_BIAS, 106 tmp = atomic_long_add_return(RWSEM_ACTIVE_WRITE_BIAS,
98 (atomic_t *)(&sem->count)); 107 (atomic_long_t *)&sem->count);
99 if (unlikely(tmp != RWSEM_ACTIVE_WRITE_BIAS)) 108 if (unlikely(tmp != RWSEM_ACTIVE_WRITE_BIAS))
100 rwsem_down_write_failed(sem); 109 rwsem_down_write_failed(sem);
101} 110}
@@ -107,7 +116,7 @@ static inline void __down_write(struct rw_semaphore *sem)
107 116
108static inline int __down_write_trylock(struct rw_semaphore *sem) 117static inline int __down_write_trylock(struct rw_semaphore *sem)
109{ 118{
110 int tmp; 119 long tmp;
111 120
112 tmp = cmpxchg(&sem->count, RWSEM_UNLOCKED_VALUE, 121 tmp = cmpxchg(&sem->count, RWSEM_UNLOCKED_VALUE,
113 RWSEM_ACTIVE_WRITE_BIAS); 122 RWSEM_ACTIVE_WRITE_BIAS);
@@ -119,9 +128,9 @@ static inline int __down_write_trylock(struct rw_semaphore *sem)
119 */ 128 */
120static inline void __up_read(struct rw_semaphore *sem) 129static inline void __up_read(struct rw_semaphore *sem)
121{ 130{
122 int tmp; 131 long tmp;
123 132
124 tmp = atomic_dec_return((atomic_t *)(&sem->count)); 133 tmp = atomic_long_dec_return((atomic_long_t *)&sem->count);
125 if (unlikely(tmp < -1 && (tmp & RWSEM_ACTIVE_MASK) == 0)) 134 if (unlikely(tmp < -1 && (tmp & RWSEM_ACTIVE_MASK) == 0))
126 rwsem_wake(sem); 135 rwsem_wake(sem);
127} 136}
@@ -131,17 +140,17 @@ static inline void __up_read(struct rw_semaphore *sem)
131 */ 140 */
132static inline void __up_write(struct rw_semaphore *sem) 141static inline void __up_write(struct rw_semaphore *sem)
133{ 142{
134 if (unlikely(atomic_sub_return(RWSEM_ACTIVE_WRITE_BIAS, 143 if (unlikely(atomic_long_sub_return(RWSEM_ACTIVE_WRITE_BIAS,
135 (atomic_t *)(&sem->count)) < 0)) 144 (atomic_long_t *)&sem->count) < 0))
136 rwsem_wake(sem); 145 rwsem_wake(sem);
137} 146}
138 147
139/* 148/*
140 * implement atomic add functionality 149 * implement atomic add functionality
141 */ 150 */
142static inline void rwsem_atomic_add(int delta, struct rw_semaphore *sem) 151static inline void rwsem_atomic_add(long delta, struct rw_semaphore *sem)
143{ 152{
144 atomic_add(delta, (atomic_t *)(&sem->count)); 153 atomic_long_add(delta, (atomic_long_t *)&sem->count);
145} 154}
146 155
147/* 156/*
@@ -149,9 +158,10 @@ static inline void rwsem_atomic_add(int delta, struct rw_semaphore *sem)
149 */ 158 */
150static inline void __downgrade_write(struct rw_semaphore *sem) 159static inline void __downgrade_write(struct rw_semaphore *sem)
151{ 160{
152 int tmp; 161 long tmp;
153 162
154 tmp = atomic_add_return(-RWSEM_WAITING_BIAS, (atomic_t *)(&sem->count)); 163 tmp = atomic_long_add_return(-RWSEM_WAITING_BIAS,
164 (atomic_long_t *)&sem->count);
155 if (tmp < 0) 165 if (tmp < 0)
156 rwsem_downgrade_wake(sem); 166 rwsem_downgrade_wake(sem);
157} 167}
@@ -159,14 +169,14 @@ static inline void __downgrade_write(struct rw_semaphore *sem)
159/* 169/*
160 * implement exchange and add functionality 170 * implement exchange and add functionality
161 */ 171 */
162static inline int rwsem_atomic_update(int delta, struct rw_semaphore *sem) 172static inline long rwsem_atomic_update(long delta, struct rw_semaphore *sem)
163{ 173{
164 return atomic_add_return(delta, (atomic_t *)(&sem->count)); 174 return atomic_long_add_return(delta, (atomic_long_t *)&sem->count);
165} 175}
166 176
167static inline int rwsem_is_locked(struct rw_semaphore *sem) 177static inline int rwsem_is_locked(struct rw_semaphore *sem)
168{ 178{
169 return (sem->count != 0); 179 return sem->count != 0;
170} 180}
171 181
172#endif /* __KERNEL__ */ 182#endif /* __KERNEL__ */
diff --git a/arch/powerpc/include/asm/systbl.h b/arch/powerpc/include/asm/systbl.h
index a5ee345b6a5c..3d212669a130 100644
--- a/arch/powerpc/include/asm/systbl.h
+++ b/arch/powerpc/include/asm/systbl.h
@@ -326,3 +326,6 @@ SYSCALL_SPU(perf_event_open)
326COMPAT_SYS_SPU(preadv) 326COMPAT_SYS_SPU(preadv)
327COMPAT_SYS_SPU(pwritev) 327COMPAT_SYS_SPU(pwritev)
328COMPAT_SYS(rt_tgsigqueueinfo) 328COMPAT_SYS(rt_tgsigqueueinfo)
329SYSCALL(fanotify_init)
330COMPAT_SYS(fanotify_mark)
331SYSCALL_SPU(prlimit64)
diff --git a/arch/powerpc/include/asm/unistd.h b/arch/powerpc/include/asm/unistd.h
index f0a10266e7f7..597e6f9d094a 100644
--- a/arch/powerpc/include/asm/unistd.h
+++ b/arch/powerpc/include/asm/unistd.h
@@ -345,10 +345,13 @@
345#define __NR_preadv 320 345#define __NR_preadv 320
346#define __NR_pwritev 321 346#define __NR_pwritev 321
347#define __NR_rt_tgsigqueueinfo 322 347#define __NR_rt_tgsigqueueinfo 322
348#define __NR_fanotify_init 323
349#define __NR_fanotify_mark 324
350#define __NR_prlimit64 325
348 351
349#ifdef __KERNEL__ 352#ifdef __KERNEL__
350 353
351#define __NR_syscalls 323 354#define __NR_syscalls 326
352 355
353#define __NR__exit __NR_exit 356#define __NR__exit __NR_exit
354#define NR_syscalls __NR_syscalls 357#define NR_syscalls __NR_syscalls
diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c
index 65e2b4e10f97..1f9123f412ec 100644
--- a/arch/powerpc/kernel/cputable.c
+++ b/arch/powerpc/kernel/cputable.c
@@ -1826,7 +1826,6 @@ static struct cpu_spec __initdata cpu_specs[] = {
1826 .cpu_features = CPU_FTRS_47X, 1826 .cpu_features = CPU_FTRS_47X,
1827 .cpu_user_features = COMMON_USER_BOOKE | 1827 .cpu_user_features = COMMON_USER_BOOKE |
1828 PPC_FEATURE_HAS_FPU, 1828 PPC_FEATURE_HAS_FPU,
1829 .cpu_user_features = COMMON_USER_BOOKE,
1830 .mmu_features = MMU_FTR_TYPE_47x | 1829 .mmu_features = MMU_FTR_TYPE_47x |
1831 MMU_FTR_USE_TLBIVAX_BCAST | MMU_FTR_LOCK_BCAST_INVAL, 1830 MMU_FTR_USE_TLBIVAX_BCAST | MMU_FTR_LOCK_BCAST_INVAL,
1832 .icache_bsize = 32, 1831 .icache_bsize = 32,
diff --git a/arch/powerpc/kernel/crash.c b/arch/powerpc/kernel/crash.c
index 417f7b05a9ce..4457382f8667 100644
--- a/arch/powerpc/kernel/crash.c
+++ b/arch/powerpc/kernel/crash.c
@@ -402,6 +402,18 @@ void default_machine_crash_shutdown(struct pt_regs *regs)
402 */ 402 */
403 hard_irq_disable(); 403 hard_irq_disable();
404 404
405 /*
406 * Make a note of crashing cpu. Will be used in machine_kexec
407 * such that another IPI will not be sent.
408 */
409 crashing_cpu = smp_processor_id();
410 crash_save_cpu(regs, crashing_cpu);
411 crash_kexec_prepare_cpus(crashing_cpu);
412 cpu_set(crashing_cpu, cpus_in_crash);
413#if defined(CONFIG_PPC_STD_MMU_64) && defined(CONFIG_SMP)
414 crash_kexec_wait_realmode(crashing_cpu);
415#endif
416
405 for_each_irq(i) { 417 for_each_irq(i) {
406 struct irq_desc *desc = irq_to_desc(i); 418 struct irq_desc *desc = irq_to_desc(i);
407 419
@@ -438,18 +450,8 @@ void default_machine_crash_shutdown(struct pt_regs *regs)
438 crash_shutdown_cpu = -1; 450 crash_shutdown_cpu = -1;
439 __debugger_fault_handler = old_handler; 451 __debugger_fault_handler = old_handler;
440 452
441 /*
442 * Make a note of crashing cpu. Will be used in machine_kexec
443 * such that another IPI will not be sent.
444 */
445 crashing_cpu = smp_processor_id();
446 crash_save_cpu(regs, crashing_cpu);
447 crash_kexec_prepare_cpus(crashing_cpu);
448 cpu_set(crashing_cpu, cpus_in_crash);
449 crash_kexec_stop_spus(); 453 crash_kexec_stop_spus();
450#if defined(CONFIG_PPC_STD_MMU_64) && defined(CONFIG_SMP) 454
451 crash_kexec_wait_realmode(crashing_cpu);
452#endif
453 if (ppc_md.kexec_cpu_down) 455 if (ppc_md.kexec_cpu_down)
454 ppc_md.kexec_cpu_down(1, 0); 456 ppc_md.kexec_cpu_down(1, 0);
455} 457}
diff --git a/arch/powerpc/kernel/head_44x.S b/arch/powerpc/kernel/head_44x.S
index 5ab484ef06a7..562305b40a8e 100644
--- a/arch/powerpc/kernel/head_44x.S
+++ b/arch/powerpc/kernel/head_44x.S
@@ -113,6 +113,10 @@ _ENTRY(_start);
113 stw r5, 0(r4) /* Save abatron_pteptrs at a fixed location */ 113 stw r5, 0(r4) /* Save abatron_pteptrs at a fixed location */
114 stw r6, 0(r5) 114 stw r6, 0(r5)
115 115
116 /* Clear the Machine Check Syndrome Register */
117 li r0,0
118 mtspr SPRN_MCSR,r0
119
116 /* Let's move on */ 120 /* Let's move on */
117 lis r4,start_kernel@h 121 lis r4,start_kernel@h
118 ori r4,r4,start_kernel@l 122 ori r4,r4,start_kernel@l
diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S
index 844a44b64472..4d6681dce816 100644
--- a/arch/powerpc/kernel/head_64.S
+++ b/arch/powerpc/kernel/head_64.S
@@ -572,9 +572,6 @@ __secondary_start:
572 /* Set thread priority to MEDIUM */ 572 /* Set thread priority to MEDIUM */
573 HMT_MEDIUM 573 HMT_MEDIUM
574 574
575 /* Do early setup for that CPU (stab, slb, hash table pointer) */
576 bl .early_setup_secondary
577
578 /* Initialize the kernel stack. Just a repeat for iSeries. */ 575 /* Initialize the kernel stack. Just a repeat for iSeries. */
579 LOAD_REG_ADDR(r3, current_set) 576 LOAD_REG_ADDR(r3, current_set)
580 sldi r28,r24,3 /* get current_set[cpu#] */ 577 sldi r28,r24,3 /* get current_set[cpu#] */
@@ -582,6 +579,9 @@ __secondary_start:
582 addi r1,r1,THREAD_SIZE-STACK_FRAME_OVERHEAD 579 addi r1,r1,THREAD_SIZE-STACK_FRAME_OVERHEAD
583 std r1,PACAKSAVE(r13) 580 std r1,PACAKSAVE(r13)
584 581
582 /* Do early setup for that CPU (stab, slb, hash table pointer) */
583 bl .early_setup_secondary
584
585 /* Clear backchain so we get nice backtraces */ 585 /* Clear backchain so we get nice backtraces */
586 li r7,0 586 li r7,0
587 mtlr r7 587 mtlr r7
diff --git a/arch/powerpc/kernel/idle.c b/arch/powerpc/kernel/idle.c
index 049dda60e475..39a2baa6ad58 100644
--- a/arch/powerpc/kernel/idle.c
+++ b/arch/powerpc/kernel/idle.c
@@ -94,9 +94,9 @@ void cpu_idle(void)
94 HMT_medium(); 94 HMT_medium();
95 ppc64_runlatch_on(); 95 ppc64_runlatch_on();
96 tick_nohz_restart_sched_tick(); 96 tick_nohz_restart_sched_tick();
97 preempt_enable_no_resched();
97 if (cpu_should_die()) 98 if (cpu_should_die())
98 cpu_die(); 99 cpu_die();
99 preempt_enable_no_resched();
100 schedule(); 100 schedule();
101 preempt_disable(); 101 preempt_disable();
102 } 102 }
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index d3ce67cf03be..4a65386995d7 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -67,6 +67,7 @@
67#include <asm/machdep.h> 67#include <asm/machdep.h>
68#include <asm/udbg.h> 68#include <asm/udbg.h>
69#include <asm/dbell.h> 69#include <asm/dbell.h>
70#include <asm/smp.h>
70 71
71#ifdef CONFIG_PPC64 72#ifdef CONFIG_PPC64
72#include <asm/paca.h> 73#include <asm/paca.h>
@@ -446,22 +447,23 @@ struct thread_info *mcheckirq_ctx[NR_CPUS] __read_mostly;
446void exc_lvl_ctx_init(void) 447void exc_lvl_ctx_init(void)
447{ 448{
448 struct thread_info *tp; 449 struct thread_info *tp;
449 int i; 450 int i, hw_cpu;
450 451
451 for_each_possible_cpu(i) { 452 for_each_possible_cpu(i) {
452 memset((void *)critirq_ctx[i], 0, THREAD_SIZE); 453 hw_cpu = get_hard_smp_processor_id(i);
453 tp = critirq_ctx[i]; 454 memset((void *)critirq_ctx[hw_cpu], 0, THREAD_SIZE);
455 tp = critirq_ctx[hw_cpu];
454 tp->cpu = i; 456 tp->cpu = i;
455 tp->preempt_count = 0; 457 tp->preempt_count = 0;
456 458
457#ifdef CONFIG_BOOKE 459#ifdef CONFIG_BOOKE
458 memset((void *)dbgirq_ctx[i], 0, THREAD_SIZE); 460 memset((void *)dbgirq_ctx[hw_cpu], 0, THREAD_SIZE);
459 tp = dbgirq_ctx[i]; 461 tp = dbgirq_ctx[hw_cpu];
460 tp->cpu = i; 462 tp->cpu = i;
461 tp->preempt_count = 0; 463 tp->preempt_count = 0;
462 464
463 memset((void *)mcheckirq_ctx[i], 0, THREAD_SIZE); 465 memset((void *)mcheckirq_ctx[hw_cpu], 0, THREAD_SIZE);
464 tp = mcheckirq_ctx[i]; 466 tp = mcheckirq_ctx[hw_cpu];
465 tp->cpu = i; 467 tp->cpu = i;
466 tp->preempt_count = HARDIRQ_OFFSET; 468 tp->preempt_count = HARDIRQ_OFFSET;
467#endif 469#endif
diff --git a/arch/powerpc/kernel/pci_of_scan.c b/arch/powerpc/kernel/pci_of_scan.c
index 6ddb795f83e8..e751506323b4 100644
--- a/arch/powerpc/kernel/pci_of_scan.c
+++ b/arch/powerpc/kernel/pci_of_scan.c
@@ -336,7 +336,7 @@ static void __devinit __of_scan_bus(struct device_node *node,
336 if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE || 336 if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE ||
337 dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) { 337 dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) {
338 struct device_node *child = pci_device_to_OF_node(dev); 338 struct device_node *child = pci_device_to_OF_node(dev);
339 if (dev) 339 if (child)
340 of_scan_pci_bridge(child, dev); 340 of_scan_pci_bridge(child, dev);
341 } 341 }
342 } 342 }
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index 91356ffda2ca..b1c648a36b03 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -728,7 +728,7 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
728 p->thread.regs = childregs; 728 p->thread.regs = childregs;
729 if (clone_flags & CLONE_SETTLS) { 729 if (clone_flags & CLONE_SETTLS) {
730#ifdef CONFIG_PPC64 730#ifdef CONFIG_PPC64
731 if (!test_thread_flag(TIF_32BIT)) 731 if (!is_32bit_task())
732 childregs->gpr[13] = childregs->gpr[6]; 732 childregs->gpr[13] = childregs->gpr[6];
733 else 733 else
734#endif 734#endif
@@ -823,7 +823,7 @@ void start_thread(struct pt_regs *regs, unsigned long start, unsigned long sp)
823 regs->nip = start; 823 regs->nip = start;
824 regs->msr = MSR_USER; 824 regs->msr = MSR_USER;
825#else 825#else
826 if (!test_thread_flag(TIF_32BIT)) { 826 if (!is_32bit_task()) {
827 unsigned long entry, toc; 827 unsigned long entry, toc;
828 828
829 /* start is a relocated pointer to the function descriptor for 829 /* start is a relocated pointer to the function descriptor for
@@ -995,7 +995,7 @@ int sys_clone(unsigned long clone_flags, unsigned long usp,
995 if (usp == 0) 995 if (usp == 0)
996 usp = regs->gpr[1]; /* stack pointer for child */ 996 usp = regs->gpr[1]; /* stack pointer for child */
997#ifdef CONFIG_PPC64 997#ifdef CONFIG_PPC64
998 if (test_thread_flag(TIF_32BIT)) { 998 if (is_32bit_task()) {
999 parent_tidp = TRUNC_PTR(parent_tidp); 999 parent_tidp = TRUNC_PTR(parent_tidp);
1000 child_tidp = TRUNC_PTR(child_tidp); 1000 child_tidp = TRUNC_PTR(child_tidp);
1001 } 1001 }
@@ -1199,19 +1199,17 @@ void ppc64_runlatch_on(void)
1199 } 1199 }
1200} 1200}
1201 1201
1202void ppc64_runlatch_off(void) 1202void __ppc64_runlatch_off(void)
1203{ 1203{
1204 unsigned long ctrl; 1204 unsigned long ctrl;
1205 1205
1206 if (cpu_has_feature(CPU_FTR_CTRL) && test_thread_flag(TIF_RUNLATCH)) { 1206 HMT_medium();
1207 HMT_medium();
1208 1207
1209 clear_thread_flag(TIF_RUNLATCH); 1208 clear_thread_flag(TIF_RUNLATCH);
1210 1209
1211 ctrl = mfspr(SPRN_CTRLF); 1210 ctrl = mfspr(SPRN_CTRLF);
1212 ctrl &= ~CTRL_RUNLATCH; 1211 ctrl &= ~CTRL_RUNLATCH;
1213 mtspr(SPRN_CTRLT, ctrl); 1212 mtspr(SPRN_CTRLT, ctrl);
1214 }
1215} 1213}
1216#endif 1214#endif
1217 1215
diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c
index a10ffc85ada7..93666f9cabf1 100644
--- a/arch/powerpc/kernel/setup_32.c
+++ b/arch/powerpc/kernel/setup_32.c
@@ -258,17 +258,18 @@ static void __init irqstack_early_init(void)
258#if defined(CONFIG_BOOKE) || defined(CONFIG_40x) 258#if defined(CONFIG_BOOKE) || defined(CONFIG_40x)
259static void __init exc_lvl_early_init(void) 259static void __init exc_lvl_early_init(void)
260{ 260{
261 unsigned int i; 261 unsigned int i, hw_cpu;
262 262
263 /* interrupt stacks must be in lowmem, we get that for free on ppc32 263 /* interrupt stacks must be in lowmem, we get that for free on ppc32
264 * as the memblock is limited to lowmem by MEMBLOCK_REAL_LIMIT */ 264 * as the memblock is limited to lowmem by MEMBLOCK_REAL_LIMIT */
265 for_each_possible_cpu(i) { 265 for_each_possible_cpu(i) {
266 critirq_ctx[i] = (struct thread_info *) 266 hw_cpu = get_hard_smp_processor_id(i);
267 critirq_ctx[hw_cpu] = (struct thread_info *)
267 __va(memblock_alloc(THREAD_SIZE, THREAD_SIZE)); 268 __va(memblock_alloc(THREAD_SIZE, THREAD_SIZE));
268#ifdef CONFIG_BOOKE 269#ifdef CONFIG_BOOKE
269 dbgirq_ctx[i] = (struct thread_info *) 270 dbgirq_ctx[hw_cpu] = (struct thread_info *)
270 __va(memblock_alloc(THREAD_SIZE, THREAD_SIZE)); 271 __va(memblock_alloc(THREAD_SIZE, THREAD_SIZE));
271 mcheckirq_ctx[i] = (struct thread_info *) 272 mcheckirq_ctx[hw_cpu] = (struct thread_info *)
272 __va(memblock_alloc(THREAD_SIZE, THREAD_SIZE)); 273 __va(memblock_alloc(THREAD_SIZE, THREAD_SIZE));
273#endif 274#endif
274 } 275 }
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
index 1bee4b68fa45..e72690ec9b87 100644
--- a/arch/powerpc/kernel/setup_64.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -95,7 +95,7 @@ int ucache_bsize;
95 95
96#ifdef CONFIG_SMP 96#ifdef CONFIG_SMP
97 97
98static int smt_enabled_cmdline; 98static char *smt_enabled_cmdline;
99 99
100/* Look for ibm,smt-enabled OF option */ 100/* Look for ibm,smt-enabled OF option */
101static void check_smt_enabled(void) 101static void check_smt_enabled(void)
@@ -103,37 +103,46 @@ static void check_smt_enabled(void)
103 struct device_node *dn; 103 struct device_node *dn;
104 const char *smt_option; 104 const char *smt_option;
105 105
106 /* Allow the command line to overrule the OF option */ 106 /* Default to enabling all threads */
107 if (smt_enabled_cmdline) 107 smt_enabled_at_boot = threads_per_core;
108 return;
109
110 dn = of_find_node_by_path("/options");
111
112 if (dn) {
113 smt_option = of_get_property(dn, "ibm,smt-enabled", NULL);
114 108
115 if (smt_option) { 109 /* Allow the command line to overrule the OF option */
116 if (!strcmp(smt_option, "on")) 110 if (smt_enabled_cmdline) {
117 smt_enabled_at_boot = 1; 111 if (!strcmp(smt_enabled_cmdline, "on"))
118 else if (!strcmp(smt_option, "off")) 112 smt_enabled_at_boot = threads_per_core;
119 smt_enabled_at_boot = 0; 113 else if (!strcmp(smt_enabled_cmdline, "off"))
120 } 114 smt_enabled_at_boot = 0;
121 } 115 else {
116 long smt;
117 int rc;
118
119 rc = strict_strtol(smt_enabled_cmdline, 10, &smt);
120 if (!rc)
121 smt_enabled_at_boot =
122 min(threads_per_core, (int)smt);
123 }
124 } else {
125 dn = of_find_node_by_path("/options");
126 if (dn) {
127 smt_option = of_get_property(dn, "ibm,smt-enabled",
128 NULL);
129
130 if (smt_option) {
131 if (!strcmp(smt_option, "on"))
132 smt_enabled_at_boot = threads_per_core;
133 else if (!strcmp(smt_option, "off"))
134 smt_enabled_at_boot = 0;
135 }
136
137 of_node_put(dn);
138 }
139 }
122} 140}
123 141
124/* Look for smt-enabled= cmdline option */ 142/* Look for smt-enabled= cmdline option */
125static int __init early_smt_enabled(char *p) 143static int __init early_smt_enabled(char *p)
126{ 144{
127 smt_enabled_cmdline = 1; 145 smt_enabled_cmdline = p;
128
129 if (!p)
130 return 0;
131
132 if (!strcmp(p, "on") || !strcmp(p, "1"))
133 smt_enabled_at_boot = 1;
134 else if (!strcmp(p, "off") || !strcmp(p, "0"))
135 smt_enabled_at_boot = 0;
136
137 return 0; 146 return 0;
138} 147}
139early_param("smt-enabled", early_smt_enabled); 148early_param("smt-enabled", early_smt_enabled);
@@ -380,8 +389,8 @@ void __init setup_system(void)
380 */ 389 */
381 xmon_setup(); 390 xmon_setup();
382 391
383 check_smt_enabled();
384 smp_setup_cpu_maps(); 392 smp_setup_cpu_maps();
393 check_smt_enabled();
385 394
386#ifdef CONFIG_SMP 395#ifdef CONFIG_SMP
387 /* Release secondary cpus out of their spinloops at 0x60 now that 396 /* Release secondary cpus out of their spinloops at 0x60 now that
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c
index a61b3ddd7bb3..0008bc58e826 100644
--- a/arch/powerpc/kernel/smp.c
+++ b/arch/powerpc/kernel/smp.c
@@ -427,11 +427,11 @@ int __cpuinit __cpu_up(unsigned int cpu)
427#endif 427#endif
428 428
429 if (!cpu_callin_map[cpu]) { 429 if (!cpu_callin_map[cpu]) {
430 printk("Processor %u is stuck.\n", cpu); 430 printk(KERN_ERR "Processor %u is stuck.\n", cpu);
431 return -ENOENT; 431 return -ENOENT;
432 } 432 }
433 433
434 printk("Processor %u found.\n", cpu); 434 DBG("Processor %u found.\n", cpu);
435 435
436 if (smp_ops->give_timebase) 436 if (smp_ops->give_timebase)
437 smp_ops->give_timebase(); 437 smp_ops->give_timebase();
diff --git a/arch/powerpc/kernel/sys_ppc32.c b/arch/powerpc/kernel/sys_ppc32.c
index 20fd701a686a..b1b6043a56c4 100644
--- a/arch/powerpc/kernel/sys_ppc32.c
+++ b/arch/powerpc/kernel/sys_ppc32.c
@@ -616,3 +616,11 @@ asmlinkage long compat_sys_sync_file_range2(int fd, unsigned int flags,
616 616
617 return sys_sync_file_range(fd, offset, nbytes, flags); 617 return sys_sync_file_range(fd, offset, nbytes, flags);
618} 618}
619
620asmlinkage long compat_sys_fanotify_mark(int fanotify_fd, unsigned int flags,
621 unsigned mask_hi, unsigned mask_lo,
622 int dfd, const char __user *pathname)
623{
624 u64 mask = ((u64)mask_hi << 32) | mask_lo;
625 return sys_fanotify_mark(fanotify_fd, flags, mask, dfd, pathname);
626}
diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c
index 00b9436f7652..fa3469ddaef8 100644
--- a/arch/powerpc/kernel/vio.c
+++ b/arch/powerpc/kernel/vio.c
@@ -1059,7 +1059,7 @@ static struct iommu_table *vio_build_iommu_table(struct vio_dev *dev)
1059 if (!dma_window) 1059 if (!dma_window)
1060 return NULL; 1060 return NULL;
1061 1061
1062 tbl = kmalloc(sizeof(*tbl), GFP_KERNEL); 1062 tbl = kzalloc(sizeof(*tbl), GFP_KERNEL);
1063 if (tbl == NULL) 1063 if (tbl == NULL)
1064 return NULL; 1064 return NULL;
1065 1065
@@ -1072,6 +1072,7 @@ static struct iommu_table *vio_build_iommu_table(struct vio_dev *dev)
1072 tbl->it_offset = offset >> IOMMU_PAGE_SHIFT; 1072 tbl->it_offset = offset >> IOMMU_PAGE_SHIFT;
1073 tbl->it_busno = 0; 1073 tbl->it_busno = 0;
1074 tbl->it_type = TCE_VB; 1074 tbl->it_type = TCE_VB;
1075 tbl->it_blocksize = 16;
1075 1076
1076 return iommu_init_table(tbl, -1); 1077 return iommu_init_table(tbl, -1);
1077} 1078}
diff --git a/arch/powerpc/mm/init_64.c b/arch/powerpc/mm/init_64.c
index 71f1415e2472..ace85fa74b29 100644
--- a/arch/powerpc/mm/init_64.c
+++ b/arch/powerpc/mm/init_64.c
@@ -79,7 +79,9 @@
79#endif /* CONFIG_PPC_STD_MMU_64 */ 79#endif /* CONFIG_PPC_STD_MMU_64 */
80 80
81phys_addr_t memstart_addr = ~0; 81phys_addr_t memstart_addr = ~0;
82EXPORT_SYMBOL_GPL(memstart_addr);
82phys_addr_t kernstart_addr; 83phys_addr_t kernstart_addr;
84EXPORT_SYMBOL_GPL(kernstart_addr);
83 85
84void free_initmem(void) 86void free_initmem(void)
85{ 87{
diff --git a/arch/powerpc/mm/tlb_nohash_low.S b/arch/powerpc/mm/tlb_nohash_low.S
index cfa768203d08..b9d9fed8f36e 100644
--- a/arch/powerpc/mm/tlb_nohash_low.S
+++ b/arch/powerpc/mm/tlb_nohash_low.S
@@ -200,6 +200,7 @@ _GLOBAL(_tlbivax_bcast)
200 rlwimi r5,r4,0,16,31 200 rlwimi r5,r4,0,16,31
201 wrteei 0 201 wrteei 0
202 mtspr SPRN_MMUCR,r5 202 mtspr SPRN_MMUCR,r5
203 isync
203/* tlbivax 0,r3 - use .long to avoid binutils deps */ 204/* tlbivax 0,r3 - use .long to avoid binutils deps */
204 .long 0x7c000624 | (r3 << 11) 205 .long 0x7c000624 | (r3 << 11)
205 isync 206 isync
diff --git a/arch/powerpc/platforms/Kconfig b/arch/powerpc/platforms/Kconfig
index d1663db7810f..81c9208025fa 100644
--- a/arch/powerpc/platforms/Kconfig
+++ b/arch/powerpc/platforms/Kconfig
@@ -106,8 +106,7 @@ config MMIO_NVRAM
106 106
107config MPIC_U3_HT_IRQS 107config MPIC_U3_HT_IRQS
108 bool 108 bool
109 depends on PPC_MAPLE 109 default n
110 default y
111 110
112config MPIC_BROKEN_REGREAD 111config MPIC_BROKEN_REGREAD
113 bool 112 bool
diff --git a/arch/powerpc/platforms/cell/iommu.c b/arch/powerpc/platforms/cell/iommu.c
index 58b13ce3847e..26a067122a54 100644
--- a/arch/powerpc/platforms/cell/iommu.c
+++ b/arch/powerpc/platforms/cell/iommu.c
@@ -477,7 +477,7 @@ cell_iommu_setup_window(struct cbe_iommu *iommu, struct device_node *np,
477 477
478 ioid = cell_iommu_get_ioid(np); 478 ioid = cell_iommu_get_ioid(np);
479 479
480 window = kmalloc_node(sizeof(*window), GFP_KERNEL, iommu->nid); 480 window = kzalloc_node(sizeof(*window), GFP_KERNEL, iommu->nid);
481 BUG_ON(window == NULL); 481 BUG_ON(window == NULL);
482 482
483 window->offset = offset; 483 window->offset = offset;
diff --git a/arch/powerpc/platforms/iseries/iommu.c b/arch/powerpc/platforms/iseries/iommu.c
index ce61cea0afb5..d8b76335bd13 100644
--- a/arch/powerpc/platforms/iseries/iommu.c
+++ b/arch/powerpc/platforms/iseries/iommu.c
@@ -184,7 +184,7 @@ static void pci_dma_dev_setup_iseries(struct pci_dev *pdev)
184 184
185 BUG_ON(lsn == NULL); 185 BUG_ON(lsn == NULL);
186 186
187 tbl = kmalloc(sizeof(struct iommu_table), GFP_KERNEL); 187 tbl = kzalloc(sizeof(struct iommu_table), GFP_KERNEL);
188 188
189 iommu_table_getparms_iSeries(pdn->busno, *lsn, 0, tbl); 189 iommu_table_getparms_iSeries(pdn->busno, *lsn, 0, tbl);
190 190
diff --git a/arch/powerpc/platforms/powermac/feature.c b/arch/powerpc/platforms/powermac/feature.c
index 39df6ab1735a..df423993f175 100644
--- a/arch/powerpc/platforms/powermac/feature.c
+++ b/arch/powerpc/platforms/powermac/feature.c
@@ -2873,12 +2873,11 @@ set_initial_features(void)
2873 2873
2874 /* Switch airport off */ 2874 /* Switch airport off */
2875 for_each_node_by_name(np, "radio") { 2875 for_each_node_by_name(np, "radio") {
2876 if (np && np->parent == macio_chips[0].of_node) { 2876 if (np->parent == macio_chips[0].of_node) {
2877 macio_chips[0].flags |= MACIO_FLAG_AIRPORT_ON; 2877 macio_chips[0].flags |= MACIO_FLAG_AIRPORT_ON;
2878 core99_airport_enable(np, 0, 0); 2878 core99_airport_enable(np, 0, 0);
2879 } 2879 }
2880 } 2880 }
2881 of_node_put(np);
2882 } 2881 }
2883 2882
2884 /* On all machines that support sound PM, switch sound off */ 2883 /* On all machines that support sound PM, switch sound off */
diff --git a/arch/powerpc/platforms/powermac/pci.c b/arch/powerpc/platforms/powermac/pci.c
index ab2027cdf893..3bc075c788ef 100644
--- a/arch/powerpc/platforms/powermac/pci.c
+++ b/arch/powerpc/platforms/powermac/pci.c
@@ -1155,13 +1155,11 @@ void __init pmac_pcibios_after_init(void)
1155 pmac_call_feature(PMAC_FTR_1394_CABLE_POWER, nd, 0, 0); 1155 pmac_call_feature(PMAC_FTR_1394_CABLE_POWER, nd, 0, 0);
1156 } 1156 }
1157 } 1157 }
1158 of_node_put(nd);
1159 for_each_node_by_name(nd, "ethernet") { 1158 for_each_node_by_name(nd, "ethernet") {
1160 if (nd->parent && of_device_is_compatible(nd, "gmac") 1159 if (nd->parent && of_device_is_compatible(nd, "gmac")
1161 && of_device_is_compatible(nd->parent, "uni-north")) 1160 && of_device_is_compatible(nd->parent, "uni-north"))
1162 pmac_call_feature(PMAC_FTR_GMAC_ENABLE, nd, 0, 0); 1161 pmac_call_feature(PMAC_FTR_GMAC_ENABLE, nd, 0, 0);
1163 } 1162 }
1164 of_node_put(nd);
1165} 1163}
1166 1164
1167void pmac_pci_fixup_cardbus(struct pci_dev* dev) 1165void pmac_pci_fixup_cardbus(struct pci_dev* dev)
diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c
index 395848e30c52..a77bcaed80af 100644
--- a/arch/powerpc/platforms/pseries/iommu.c
+++ b/arch/powerpc/platforms/pseries/iommu.c
@@ -403,7 +403,7 @@ static void pci_dma_bus_setup_pSeries(struct pci_bus *bus)
403 pci->phb->dma_window_size = 0x8000000ul; 403 pci->phb->dma_window_size = 0x8000000ul;
404 pci->phb->dma_window_base_cur = 0x8000000ul; 404 pci->phb->dma_window_base_cur = 0x8000000ul;
405 405
406 tbl = kmalloc_node(sizeof(struct iommu_table), GFP_KERNEL, 406 tbl = kzalloc_node(sizeof(struct iommu_table), GFP_KERNEL,
407 pci->phb->node); 407 pci->phb->node);
408 408
409 iommu_table_setparms(pci->phb, dn, tbl); 409 iommu_table_setparms(pci->phb, dn, tbl);
@@ -448,7 +448,7 @@ static void pci_dma_bus_setup_pSeriesLP(struct pci_bus *bus)
448 pdn->full_name, ppci->iommu_table); 448 pdn->full_name, ppci->iommu_table);
449 449
450 if (!ppci->iommu_table) { 450 if (!ppci->iommu_table) {
451 tbl = kmalloc_node(sizeof(struct iommu_table), GFP_KERNEL, 451 tbl = kzalloc_node(sizeof(struct iommu_table), GFP_KERNEL,
452 ppci->phb->node); 452 ppci->phb->node);
453 iommu_table_setparms_lpar(ppci->phb, pdn, tbl, dma_window, 453 iommu_table_setparms_lpar(ppci->phb, pdn, tbl, dma_window,
454 bus->number); 454 bus->number);
@@ -478,7 +478,7 @@ static void pci_dma_dev_setup_pSeries(struct pci_dev *dev)
478 struct pci_controller *phb = PCI_DN(dn)->phb; 478 struct pci_controller *phb = PCI_DN(dn)->phb;
479 479
480 pr_debug(" --> first child, no bridge. Allocating iommu table.\n"); 480 pr_debug(" --> first child, no bridge. Allocating iommu table.\n");
481 tbl = kmalloc_node(sizeof(struct iommu_table), GFP_KERNEL, 481 tbl = kzalloc_node(sizeof(struct iommu_table), GFP_KERNEL,
482 phb->node); 482 phb->node);
483 iommu_table_setparms(phb, dn, tbl); 483 iommu_table_setparms(phb, dn, tbl);
484 PCI_DN(dn)->iommu_table = iommu_init_table(tbl, phb->node); 484 PCI_DN(dn)->iommu_table = iommu_init_table(tbl, phb->node);
@@ -544,7 +544,7 @@ static void pci_dma_dev_setup_pSeriesLP(struct pci_dev *dev)
544 544
545 pci = PCI_DN(pdn); 545 pci = PCI_DN(pdn);
546 if (!pci->iommu_table) { 546 if (!pci->iommu_table) {
547 tbl = kmalloc_node(sizeof(struct iommu_table), GFP_KERNEL, 547 tbl = kzalloc_node(sizeof(struct iommu_table), GFP_KERNEL,
548 pci->phb->node); 548 pci->phb->node);
549 iommu_table_setparms_lpar(pci->phb, pdn, tbl, dma_window, 549 iommu_table_setparms_lpar(pci->phb, pdn, tbl, dma_window,
550 pci->phb->bus->number); 550 pci->phb->bus->number);
diff --git a/arch/powerpc/platforms/pseries/smp.c b/arch/powerpc/platforms/pseries/smp.c
index 3b1bf61c45be..0317cce877c6 100644
--- a/arch/powerpc/platforms/pseries/smp.c
+++ b/arch/powerpc/platforms/pseries/smp.c
@@ -182,10 +182,13 @@ static int smp_pSeries_cpu_bootable(unsigned int nr)
182 /* Special case - we inhibit secondary thread startup 182 /* Special case - we inhibit secondary thread startup
183 * during boot if the user requests it. 183 * during boot if the user requests it.
184 */ 184 */
185 if (system_state < SYSTEM_RUNNING && 185 if (system_state < SYSTEM_RUNNING && cpu_has_feature(CPU_FTR_SMT)) {
186 cpu_has_feature(CPU_FTR_SMT) && 186 if (!smt_enabled_at_boot && cpu_thread_in_core(nr) != 0)
187 !smt_enabled_at_boot && cpu_thread_in_core(nr) != 0) 187 return 0;
188 return 0; 188 if (smt_enabled_at_boot
189 && cpu_thread_in_core(nr) >= smt_enabled_at_boot)
190 return 0;
191 }
189 192
190 return 1; 193 return 1;
191} 194}
diff --git a/arch/powerpc/platforms/pseries/xics.c b/arch/powerpc/platforms/pseries/xics.c
index 5b22b07c8f67..93834b0d8272 100644
--- a/arch/powerpc/platforms/pseries/xics.c
+++ b/arch/powerpc/platforms/pseries/xics.c
@@ -928,8 +928,10 @@ void xics_migrate_irqs_away(void)
928 if (xics_status[0] != hw_cpu) 928 if (xics_status[0] != hw_cpu)
929 goto unlock; 929 goto unlock;
930 930
931 printk(KERN_WARNING "IRQ %u affinity broken off cpu %u\n", 931 /* This is expected during cpu offline. */
932 virq, cpu); 932 if (cpu_online(cpu))
933 printk(KERN_WARNING "IRQ %u affinity broken off cpu %u\n",
934 virq, cpu);
933 935
934 /* Reset affinity to all cpus */ 936 /* Reset affinity to all cpus */
935 cpumask_setall(irq_to_desc(virq)->affinity); 937 cpumask_setall(irq_to_desc(virq)->affinity);
diff --git a/arch/sparc/include/asm/atomic_64.h b/arch/sparc/include/asm/atomic_64.h
index f0c74227c737..bdb2ff880bdd 100644
--- a/arch/sparc/include/asm/atomic_64.h
+++ b/arch/sparc/include/asm/atomic_64.h
@@ -20,14 +20,14 @@
20#define atomic64_set(v, i) (((v)->counter) = i) 20#define atomic64_set(v, i) (((v)->counter) = i)
21 21
22extern void atomic_add(int, atomic_t *); 22extern void atomic_add(int, atomic_t *);
23extern void atomic64_add(int, atomic64_t *); 23extern void atomic64_add(long, atomic64_t *);
24extern void atomic_sub(int, atomic_t *); 24extern void atomic_sub(int, atomic_t *);
25extern void atomic64_sub(int, atomic64_t *); 25extern void atomic64_sub(long, atomic64_t *);
26 26
27extern int atomic_add_ret(int, atomic_t *); 27extern int atomic_add_ret(int, atomic_t *);
28extern long atomic64_add_ret(int, atomic64_t *); 28extern long atomic64_add_ret(long, atomic64_t *);
29extern int atomic_sub_ret(int, atomic_t *); 29extern int atomic_sub_ret(int, atomic_t *);
30extern long atomic64_sub_ret(int, atomic64_t *); 30extern long atomic64_sub_ret(long, atomic64_t *);
31 31
32#define atomic_dec_return(v) atomic_sub_ret(1, v) 32#define atomic_dec_return(v) atomic_sub_ret(1, v)
33#define atomic64_dec_return(v) atomic64_sub_ret(1, v) 33#define atomic64_dec_return(v) atomic64_sub_ret(1, v)
diff --git a/arch/sparc/include/asm/backoff.h b/arch/sparc/include/asm/backoff.h
index fa1fdf67e350..db3af0d30fb1 100644
--- a/arch/sparc/include/asm/backoff.h
+++ b/arch/sparc/include/asm/backoff.h
@@ -8,6 +8,9 @@
8#define BACKOFF_SETUP(reg) \ 8#define BACKOFF_SETUP(reg) \
9 mov 1, reg 9 mov 1, reg
10 10
11#define BACKOFF_LABEL(spin_label, continue_label) \
12 spin_label
13
11#define BACKOFF_SPIN(reg, tmp, label) \ 14#define BACKOFF_SPIN(reg, tmp, label) \
12 mov reg, tmp; \ 15 mov reg, tmp; \
1388: brnz,pt tmp, 88b; \ 1688: brnz,pt tmp, 88b; \
@@ -22,9 +25,11 @@
22#else 25#else
23 26
24#define BACKOFF_SETUP(reg) 27#define BACKOFF_SETUP(reg)
25#define BACKOFF_SPIN(reg, tmp, label) \ 28
26 ba,pt %xcc, label; \ 29#define BACKOFF_LABEL(spin_label, continue_label) \
27 nop; 30 continue_label
31
32#define BACKOFF_SPIN(reg, tmp, label)
28 33
29#endif 34#endif
30 35
diff --git a/arch/sparc/include/asm/oplib_64.h b/arch/sparc/include/asm/oplib_64.h
index a5db0317b5fb..3e0b2d62303d 100644
--- a/arch/sparc/include/asm/oplib_64.h
+++ b/arch/sparc/include/asm/oplib_64.h
@@ -185,9 +185,8 @@ extern int prom_getunumber(int syndrome_code,
185 char *buf, int buflen); 185 char *buf, int buflen);
186 186
187/* Retain physical memory to the caller across soft resets. */ 187/* Retain physical memory to the caller across soft resets. */
188extern unsigned long prom_retain(const char *name, 188extern int prom_retain(const char *name, unsigned long size,
189 unsigned long pa_low, unsigned long pa_high, 189 unsigned long align, unsigned long *paddr);
190 long size, long align);
191 190
192/* Load explicit I/D TLB entries into the calling processor. */ 191/* Load explicit I/D TLB entries into the calling processor. */
193extern long prom_itlb_load(unsigned long index, 192extern long prom_itlb_load(unsigned long index,
@@ -287,26 +286,6 @@ extern void prom_sun4v_guest_soft_state(void);
287extern int prom_ihandle2path(int handle, char *buffer, int bufsize); 286extern int prom_ihandle2path(int handle, char *buffer, int bufsize);
288 287
289/* Client interface level routines. */ 288/* Client interface level routines. */
290extern long p1275_cmd(const char *, long, ...); 289extern void p1275_cmd_direct(unsigned long *);
291
292#if 0
293#define P1275_SIZE(x) ((((long)((x) / 32)) << 32) | (x))
294#else
295#define P1275_SIZE(x) x
296#endif
297
298/* We support at most 16 input and 1 output argument */
299#define P1275_ARG_NUMBER 0
300#define P1275_ARG_IN_STRING 1
301#define P1275_ARG_OUT_BUF 2
302#define P1275_ARG_OUT_32B 3
303#define P1275_ARG_IN_FUNCTION 4
304#define P1275_ARG_IN_BUF 5
305#define P1275_ARG_IN_64B 6
306
307#define P1275_IN(x) ((x) & 0xf)
308#define P1275_OUT(x) (((x) << 4) & 0xf0)
309#define P1275_INOUT(i,o) (P1275_IN(i)|P1275_OUT(o))
310#define P1275_ARG(n,x) ((x) << ((n)*3 + 8))
311 290
312#endif /* !(__SPARC64_OPLIB_H) */ 291#endif /* !(__SPARC64_OPLIB_H) */
diff --git a/arch/sparc/include/asm/rwsem-const.h b/arch/sparc/include/asm/rwsem-const.h
deleted file mode 100644
index e4c61a18bb28..000000000000
--- a/arch/sparc/include/asm/rwsem-const.h
+++ /dev/null
@@ -1,12 +0,0 @@
1/* rwsem-const.h: RW semaphore counter constants. */
2#ifndef _SPARC64_RWSEM_CONST_H
3#define _SPARC64_RWSEM_CONST_H
4
5#define RWSEM_UNLOCKED_VALUE 0x00000000
6#define RWSEM_ACTIVE_BIAS 0x00000001
7#define RWSEM_ACTIVE_MASK 0x0000ffff
8#define RWSEM_WAITING_BIAS (-0x00010000)
9#define RWSEM_ACTIVE_READ_BIAS RWSEM_ACTIVE_BIAS
10#define RWSEM_ACTIVE_WRITE_BIAS (RWSEM_WAITING_BIAS + RWSEM_ACTIVE_BIAS)
11
12#endif /* _SPARC64_RWSEM_CONST_H */
diff --git a/arch/sparc/include/asm/rwsem.h b/arch/sparc/include/asm/rwsem.h
index 6e5621006f85..a2b4302869bc 100644
--- a/arch/sparc/include/asm/rwsem.h
+++ b/arch/sparc/include/asm/rwsem.h
@@ -15,16 +15,21 @@
15 15
16#include <linux/list.h> 16#include <linux/list.h>
17#include <linux/spinlock.h> 17#include <linux/spinlock.h>
18#include <asm/rwsem-const.h>
19 18
20struct rwsem_waiter; 19struct rwsem_waiter;
21 20
22struct rw_semaphore { 21struct rw_semaphore {
23 signed int count; 22 signed long count;
24 spinlock_t wait_lock; 23#define RWSEM_UNLOCKED_VALUE 0x00000000L
25 struct list_head wait_list; 24#define RWSEM_ACTIVE_BIAS 0x00000001L
25#define RWSEM_ACTIVE_MASK 0xffffffffL
26#define RWSEM_WAITING_BIAS (-RWSEM_ACTIVE_MASK-1)
27#define RWSEM_ACTIVE_READ_BIAS RWSEM_ACTIVE_BIAS
28#define RWSEM_ACTIVE_WRITE_BIAS (RWSEM_WAITING_BIAS + RWSEM_ACTIVE_BIAS)
29 spinlock_t wait_lock;
30 struct list_head wait_list;
26#ifdef CONFIG_DEBUG_LOCK_ALLOC 31#ifdef CONFIG_DEBUG_LOCK_ALLOC
27 struct lockdep_map dep_map; 32 struct lockdep_map dep_map;
28#endif 33#endif
29}; 34};
30 35
@@ -41,6 +46,11 @@ struct rw_semaphore {
41#define DECLARE_RWSEM(name) \ 46#define DECLARE_RWSEM(name) \
42 struct rw_semaphore name = __RWSEM_INITIALIZER(name) 47 struct rw_semaphore name = __RWSEM_INITIALIZER(name)
43 48
49extern struct rw_semaphore *rwsem_down_read_failed(struct rw_semaphore *sem);
50extern struct rw_semaphore *rwsem_down_write_failed(struct rw_semaphore *sem);
51extern struct rw_semaphore *rwsem_wake(struct rw_semaphore *sem);
52extern struct rw_semaphore *rwsem_downgrade_wake(struct rw_semaphore *sem);
53
44extern void __init_rwsem(struct rw_semaphore *sem, const char *name, 54extern void __init_rwsem(struct rw_semaphore *sem, const char *name,
45 struct lock_class_key *key); 55 struct lock_class_key *key);
46 56
@@ -51,27 +61,103 @@ do { \
51 __init_rwsem((sem), #sem, &__key); \ 61 __init_rwsem((sem), #sem, &__key); \
52} while (0) 62} while (0)
53 63
54extern void __down_read(struct rw_semaphore *sem); 64/*
55extern int __down_read_trylock(struct rw_semaphore *sem); 65 * lock for reading
56extern void __down_write(struct rw_semaphore *sem); 66 */
57extern int __down_write_trylock(struct rw_semaphore *sem); 67static inline void __down_read(struct rw_semaphore *sem)
58extern void __up_read(struct rw_semaphore *sem); 68{
59extern void __up_write(struct rw_semaphore *sem); 69 if (unlikely(atomic64_inc_return((atomic64_t *)(&sem->count)) <= 0L))
60extern void __downgrade_write(struct rw_semaphore *sem); 70 rwsem_down_read_failed(sem);
71}
72
73static inline int __down_read_trylock(struct rw_semaphore *sem)
74{
75 long tmp;
76
77 while ((tmp = sem->count) >= 0L) {
78 if (tmp == cmpxchg(&sem->count, tmp,
79 tmp + RWSEM_ACTIVE_READ_BIAS)) {
80 return 1;
81 }
82 }
83 return 0;
84}
61 85
86/*
87 * lock for writing
88 */
62static inline void __down_write_nested(struct rw_semaphore *sem, int subclass) 89static inline void __down_write_nested(struct rw_semaphore *sem, int subclass)
63{ 90{
64 __down_write(sem); 91 long tmp;
92
93 tmp = atomic64_add_return(RWSEM_ACTIVE_WRITE_BIAS,
94 (atomic64_t *)(&sem->count));
95 if (unlikely(tmp != RWSEM_ACTIVE_WRITE_BIAS))
96 rwsem_down_write_failed(sem);
65} 97}
66 98
67static inline int rwsem_atomic_update(int delta, struct rw_semaphore *sem) 99static inline void __down_write(struct rw_semaphore *sem)
68{ 100{
69 return atomic_add_return(delta, (atomic_t *)(&sem->count)); 101 __down_write_nested(sem, 0);
102}
103
104static inline int __down_write_trylock(struct rw_semaphore *sem)
105{
106 long tmp;
107
108 tmp = cmpxchg(&sem->count, RWSEM_UNLOCKED_VALUE,
109 RWSEM_ACTIVE_WRITE_BIAS);
110 return tmp == RWSEM_UNLOCKED_VALUE;
70} 111}
71 112
72static inline void rwsem_atomic_add(int delta, struct rw_semaphore *sem) 113/*
114 * unlock after reading
115 */
116static inline void __up_read(struct rw_semaphore *sem)
117{
118 long tmp;
119
120 tmp = atomic64_dec_return((atomic64_t *)(&sem->count));
121 if (unlikely(tmp < -1L && (tmp & RWSEM_ACTIVE_MASK) == 0L))
122 rwsem_wake(sem);
123}
124
125/*
126 * unlock after writing
127 */
128static inline void __up_write(struct rw_semaphore *sem)
129{
130 if (unlikely(atomic64_sub_return(RWSEM_ACTIVE_WRITE_BIAS,
131 (atomic64_t *)(&sem->count)) < 0L))
132 rwsem_wake(sem);
133}
134
135/*
136 * implement atomic add functionality
137 */
138static inline void rwsem_atomic_add(long delta, struct rw_semaphore *sem)
139{
140 atomic64_add(delta, (atomic64_t *)(&sem->count));
141}
142
143/*
144 * downgrade write lock to read lock
145 */
146static inline void __downgrade_write(struct rw_semaphore *sem)
147{
148 long tmp;
149
150 tmp = atomic64_add_return(-RWSEM_WAITING_BIAS, (atomic64_t *)(&sem->count));
151 if (tmp < 0L)
152 rwsem_downgrade_wake(sem);
153}
154
155/*
156 * implement exchange and add functionality
157 */
158static inline long rwsem_atomic_update(long delta, struct rw_semaphore *sem)
73{ 159{
74 atomic_add(delta, (atomic_t *)(&sem->count)); 160 return atomic64_add_return(delta, (atomic64_t *)(&sem->count));
75} 161}
76 162
77static inline int rwsem_is_locked(struct rw_semaphore *sem) 163static inline int rwsem_is_locked(struct rw_semaphore *sem)
diff --git a/arch/sparc/include/asm/system_64.h b/arch/sparc/include/asm/system_64.h
index d24cfe16afc1..e3b65d8cf41b 100644
--- a/arch/sparc/include/asm/system_64.h
+++ b/arch/sparc/include/asm/system_64.h
@@ -106,6 +106,7 @@ do { __asm__ __volatile__("ba,pt %%xcc, 1f\n\t" \
106 */ 106 */
107#define write_pic(__p) \ 107#define write_pic(__p) \
108 __asm__ __volatile__("ba,pt %%xcc, 99f\n\t" \ 108 __asm__ __volatile__("ba,pt %%xcc, 99f\n\t" \
109 " nop\n\t" \
109 ".align 64\n" \ 110 ".align 64\n" \
110 "99:wr %0, 0x0, %%pic\n\t" \ 111 "99:wr %0, 0x0, %%pic\n\t" \
111 "rd %%pic, %%g0" : : "r" (__p)) 112 "rd %%pic, %%g0" : : "r" (__p))
diff --git a/arch/sparc/lib/Makefile b/arch/sparc/lib/Makefile
index c4b5e03af115..846d1c4374ea 100644
--- a/arch/sparc/lib/Makefile
+++ b/arch/sparc/lib/Makefile
@@ -15,7 +15,7 @@ lib-$(CONFIG_SPARC32) += divdi3.o udivdi3.o
15lib-$(CONFIG_SPARC32) += copy_user.o locks.o 15lib-$(CONFIG_SPARC32) += copy_user.o locks.o
16lib-y += atomic_$(BITS).o 16lib-y += atomic_$(BITS).o
17lib-$(CONFIG_SPARC32) += lshrdi3.o ashldi3.o 17lib-$(CONFIG_SPARC32) += lshrdi3.o ashldi3.o
18lib-y += rwsem_$(BITS).o 18lib-$(CONFIG_SPARC32) += rwsem_32.o
19lib-$(CONFIG_SPARC32) += muldi3.o bitext.o cmpdi2.o 19lib-$(CONFIG_SPARC32) += muldi3.o bitext.o cmpdi2.o
20 20
21lib-$(CONFIG_SPARC64) += copy_page.o clear_page.o bzero.o 21lib-$(CONFIG_SPARC64) += copy_page.o clear_page.o bzero.o
diff --git a/arch/sparc/lib/atomic_64.S b/arch/sparc/lib/atomic_64.S
index 0268210ca168..59186e0fcf39 100644
--- a/arch/sparc/lib/atomic_64.S
+++ b/arch/sparc/lib/atomic_64.S
@@ -21,7 +21,7 @@ atomic_add: /* %o0 = increment, %o1 = atomic_ptr */
21 add %g1, %o0, %g7 21 add %g1, %o0, %g7
22 cas [%o1], %g1, %g7 22 cas [%o1], %g1, %g7
23 cmp %g1, %g7 23 cmp %g1, %g7
24 bne,pn %icc, 2f 24 bne,pn %icc, BACKOFF_LABEL(2f, 1b)
25 nop 25 nop
26 retl 26 retl
27 nop 27 nop
@@ -36,7 +36,7 @@ atomic_sub: /* %o0 = decrement, %o1 = atomic_ptr */
36 sub %g1, %o0, %g7 36 sub %g1, %o0, %g7
37 cas [%o1], %g1, %g7 37 cas [%o1], %g1, %g7
38 cmp %g1, %g7 38 cmp %g1, %g7
39 bne,pn %icc, 2f 39 bne,pn %icc, BACKOFF_LABEL(2f, 1b)
40 nop 40 nop
41 retl 41 retl
42 nop 42 nop
@@ -51,11 +51,10 @@ atomic_add_ret: /* %o0 = increment, %o1 = atomic_ptr */
51 add %g1, %o0, %g7 51 add %g1, %o0, %g7
52 cas [%o1], %g1, %g7 52 cas [%o1], %g1, %g7
53 cmp %g1, %g7 53 cmp %g1, %g7
54 bne,pn %icc, 2f 54 bne,pn %icc, BACKOFF_LABEL(2f, 1b)
55 add %g7, %o0, %g7 55 add %g1, %o0, %g1
56 sra %g7, 0, %o0
57 retl 56 retl
58 nop 57 sra %g1, 0, %o0
592: BACKOFF_SPIN(%o2, %o3, 1b) 582: BACKOFF_SPIN(%o2, %o3, 1b)
60 .size atomic_add_ret, .-atomic_add_ret 59 .size atomic_add_ret, .-atomic_add_ret
61 60
@@ -67,11 +66,10 @@ atomic_sub_ret: /* %o0 = decrement, %o1 = atomic_ptr */
67 sub %g1, %o0, %g7 66 sub %g1, %o0, %g7
68 cas [%o1], %g1, %g7 67 cas [%o1], %g1, %g7
69 cmp %g1, %g7 68 cmp %g1, %g7
70 bne,pn %icc, 2f 69 bne,pn %icc, BACKOFF_LABEL(2f, 1b)
71 sub %g7, %o0, %g7 70 sub %g1, %o0, %g1
72 sra %g7, 0, %o0
73 retl 71 retl
74 nop 72 sra %g1, 0, %o0
752: BACKOFF_SPIN(%o2, %o3, 1b) 732: BACKOFF_SPIN(%o2, %o3, 1b)
76 .size atomic_sub_ret, .-atomic_sub_ret 74 .size atomic_sub_ret, .-atomic_sub_ret
77 75
@@ -83,7 +81,7 @@ atomic64_add: /* %o0 = increment, %o1 = atomic_ptr */
83 add %g1, %o0, %g7 81 add %g1, %o0, %g7
84 casx [%o1], %g1, %g7 82 casx [%o1], %g1, %g7
85 cmp %g1, %g7 83 cmp %g1, %g7
86 bne,pn %xcc, 2f 84 bne,pn %xcc, BACKOFF_LABEL(2f, 1b)
87 nop 85 nop
88 retl 86 retl
89 nop 87 nop
@@ -98,7 +96,7 @@ atomic64_sub: /* %o0 = decrement, %o1 = atomic_ptr */
98 sub %g1, %o0, %g7 96 sub %g1, %o0, %g7
99 casx [%o1], %g1, %g7 97 casx [%o1], %g1, %g7
100 cmp %g1, %g7 98 cmp %g1, %g7
101 bne,pn %xcc, 2f 99 bne,pn %xcc, BACKOFF_LABEL(2f, 1b)
102 nop 100 nop
103 retl 101 retl
104 nop 102 nop
@@ -113,11 +111,10 @@ atomic64_add_ret: /* %o0 = increment, %o1 = atomic_ptr */
113 add %g1, %o0, %g7 111 add %g1, %o0, %g7
114 casx [%o1], %g1, %g7 112 casx [%o1], %g1, %g7
115 cmp %g1, %g7 113 cmp %g1, %g7
116 bne,pn %xcc, 2f 114 bne,pn %xcc, BACKOFF_LABEL(2f, 1b)
117 add %g7, %o0, %g7
118 mov %g7, %o0
119 retl
120 nop 115 nop
116 retl
117 add %g1, %o0, %o0
1212: BACKOFF_SPIN(%o2, %o3, 1b) 1182: BACKOFF_SPIN(%o2, %o3, 1b)
122 .size atomic64_add_ret, .-atomic64_add_ret 119 .size atomic64_add_ret, .-atomic64_add_ret
123 120
@@ -129,10 +126,9 @@ atomic64_sub_ret: /* %o0 = decrement, %o1 = atomic_ptr */
129 sub %g1, %o0, %g7 126 sub %g1, %o0, %g7
130 casx [%o1], %g1, %g7 127 casx [%o1], %g1, %g7
131 cmp %g1, %g7 128 cmp %g1, %g7
132 bne,pn %xcc, 2f 129 bne,pn %xcc, BACKOFF_LABEL(2f, 1b)
133 sub %g7, %o0, %g7
134 mov %g7, %o0
135 retl
136 nop 130 nop
131 retl
132 sub %g1, %o0, %o0
1372: BACKOFF_SPIN(%o2, %o3, 1b) 1332: BACKOFF_SPIN(%o2, %o3, 1b)
138 .size atomic64_sub_ret, .-atomic64_sub_ret 134 .size atomic64_sub_ret, .-atomic64_sub_ret
diff --git a/arch/sparc/lib/bitops.S b/arch/sparc/lib/bitops.S
index 2b7228cb8c22..3dc61d5537c0 100644
--- a/arch/sparc/lib/bitops.S
+++ b/arch/sparc/lib/bitops.S
@@ -22,7 +22,7 @@ test_and_set_bit: /* %o0=nr, %o1=addr */
22 or %g7, %o2, %g1 22 or %g7, %o2, %g1
23 casx [%o1], %g7, %g1 23 casx [%o1], %g7, %g1
24 cmp %g7, %g1 24 cmp %g7, %g1
25 bne,pn %xcc, 2f 25 bne,pn %xcc, BACKOFF_LABEL(2f, 1b)
26 and %g7, %o2, %g2 26 and %g7, %o2, %g2
27 clr %o0 27 clr %o0
28 movrne %g2, 1, %o0 28 movrne %g2, 1, %o0
@@ -45,7 +45,7 @@ test_and_clear_bit: /* %o0=nr, %o1=addr */
45 andn %g7, %o2, %g1 45 andn %g7, %o2, %g1
46 casx [%o1], %g7, %g1 46 casx [%o1], %g7, %g1
47 cmp %g7, %g1 47 cmp %g7, %g1
48 bne,pn %xcc, 2f 48 bne,pn %xcc, BACKOFF_LABEL(2f, 1b)
49 and %g7, %o2, %g2 49 and %g7, %o2, %g2
50 clr %o0 50 clr %o0
51 movrne %g2, 1, %o0 51 movrne %g2, 1, %o0
@@ -68,7 +68,7 @@ test_and_change_bit: /* %o0=nr, %o1=addr */
68 xor %g7, %o2, %g1 68 xor %g7, %o2, %g1
69 casx [%o1], %g7, %g1 69 casx [%o1], %g7, %g1
70 cmp %g7, %g1 70 cmp %g7, %g1
71 bne,pn %xcc, 2f 71 bne,pn %xcc, BACKOFF_LABEL(2f, 1b)
72 and %g7, %o2, %g2 72 and %g7, %o2, %g2
73 clr %o0 73 clr %o0
74 movrne %g2, 1, %o0 74 movrne %g2, 1, %o0
@@ -91,7 +91,7 @@ set_bit: /* %o0=nr, %o1=addr */
91 or %g7, %o2, %g1 91 or %g7, %o2, %g1
92 casx [%o1], %g7, %g1 92 casx [%o1], %g7, %g1
93 cmp %g7, %g1 93 cmp %g7, %g1
94 bne,pn %xcc, 2f 94 bne,pn %xcc, BACKOFF_LABEL(2f, 1b)
95 nop 95 nop
96 retl 96 retl
97 nop 97 nop
@@ -112,7 +112,7 @@ clear_bit: /* %o0=nr, %o1=addr */
112 andn %g7, %o2, %g1 112 andn %g7, %o2, %g1
113 casx [%o1], %g7, %g1 113 casx [%o1], %g7, %g1
114 cmp %g7, %g1 114 cmp %g7, %g1
115 bne,pn %xcc, 2f 115 bne,pn %xcc, BACKOFF_LABEL(2f, 1b)
116 nop 116 nop
117 retl 117 retl
118 nop 118 nop
@@ -133,7 +133,7 @@ change_bit: /* %o0=nr, %o1=addr */
133 xor %g7, %o2, %g1 133 xor %g7, %o2, %g1
134 casx [%o1], %g7, %g1 134 casx [%o1], %g7, %g1
135 cmp %g7, %g1 135 cmp %g7, %g1
136 bne,pn %xcc, 2f 136 bne,pn %xcc, BACKOFF_LABEL(2f, 1b)
137 nop 137 nop
138 retl 138 retl
139 nop 139 nop
diff --git a/arch/sparc/lib/rwsem_64.S b/arch/sparc/lib/rwsem_64.S
deleted file mode 100644
index 91a7d29a79d5..000000000000
--- a/arch/sparc/lib/rwsem_64.S
+++ /dev/null
@@ -1,163 +0,0 @@
1/* rwsem.S: RW semaphore assembler.
2 *
3 * Written by David S. Miller (davem@redhat.com), 2001.
4 * Derived from asm-i386/rwsem.h
5 */
6
7#include <asm/rwsem-const.h>
8
9 .section .sched.text, "ax"
10
11 .globl __down_read
12__down_read:
131: lduw [%o0], %g1
14 add %g1, 1, %g7
15 cas [%o0], %g1, %g7
16 cmp %g1, %g7
17 bne,pn %icc, 1b
18 add %g7, 1, %g7
19 cmp %g7, 0
20 bl,pn %icc, 3f
21 nop
222:
23 retl
24 nop
253:
26 save %sp, -192, %sp
27 call rwsem_down_read_failed
28 mov %i0, %o0
29 ret
30 restore
31 .size __down_read, .-__down_read
32
33 .globl __down_read_trylock
34__down_read_trylock:
351: lduw [%o0], %g1
36 add %g1, 1, %g7
37 cmp %g7, 0
38 bl,pn %icc, 2f
39 mov 0, %o1
40 cas [%o0], %g1, %g7
41 cmp %g1, %g7
42 bne,pn %icc, 1b
43 mov 1, %o1
442: retl
45 mov %o1, %o0
46 .size __down_read_trylock, .-__down_read_trylock
47
48 .globl __down_write
49__down_write:
50 sethi %hi(RWSEM_ACTIVE_WRITE_BIAS), %g1
51 or %g1, %lo(RWSEM_ACTIVE_WRITE_BIAS), %g1
521:
53 lduw [%o0], %g3
54 add %g3, %g1, %g7
55 cas [%o0], %g3, %g7
56 cmp %g3, %g7
57 bne,pn %icc, 1b
58 cmp %g7, 0
59 bne,pn %icc, 3f
60 nop
612: retl
62 nop
633:
64 save %sp, -192, %sp
65 call rwsem_down_write_failed
66 mov %i0, %o0
67 ret
68 restore
69 .size __down_write, .-__down_write
70
71 .globl __down_write_trylock
72__down_write_trylock:
73 sethi %hi(RWSEM_ACTIVE_WRITE_BIAS), %g1
74 or %g1, %lo(RWSEM_ACTIVE_WRITE_BIAS), %g1
751:
76 lduw [%o0], %g3
77 cmp %g3, 0
78 bne,pn %icc, 2f
79 mov 0, %o1
80 add %g3, %g1, %g7
81 cas [%o0], %g3, %g7
82 cmp %g3, %g7
83 bne,pn %icc, 1b
84 mov 1, %o1
852: retl
86 mov %o1, %o0
87 .size __down_write_trylock, .-__down_write_trylock
88
89 .globl __up_read
90__up_read:
911:
92 lduw [%o0], %g1
93 sub %g1, 1, %g7
94 cas [%o0], %g1, %g7
95 cmp %g1, %g7
96 bne,pn %icc, 1b
97 cmp %g7, 0
98 bl,pn %icc, 3f
99 nop
1002: retl
101 nop
1023: sethi %hi(RWSEM_ACTIVE_MASK), %g1
103 sub %g7, 1, %g7
104 or %g1, %lo(RWSEM_ACTIVE_MASK), %g1
105 andcc %g7, %g1, %g0
106 bne,pn %icc, 2b
107 nop
108 save %sp, -192, %sp
109 call rwsem_wake
110 mov %i0, %o0
111 ret
112 restore
113 .size __up_read, .-__up_read
114
115 .globl __up_write
116__up_write:
117 sethi %hi(RWSEM_ACTIVE_WRITE_BIAS), %g1
118 or %g1, %lo(RWSEM_ACTIVE_WRITE_BIAS), %g1
1191:
120 lduw [%o0], %g3
121 sub %g3, %g1, %g7
122 cas [%o0], %g3, %g7
123 cmp %g3, %g7
124 bne,pn %icc, 1b
125 sub %g7, %g1, %g7
126 cmp %g7, 0
127 bl,pn %icc, 3f
128 nop
1292:
130 retl
131 nop
1323:
133 save %sp, -192, %sp
134 call rwsem_wake
135 mov %i0, %o0
136 ret
137 restore
138 .size __up_write, .-__up_write
139
140 .globl __downgrade_write
141__downgrade_write:
142 sethi %hi(RWSEM_WAITING_BIAS), %g1
143 or %g1, %lo(RWSEM_WAITING_BIAS), %g1
1441:
145 lduw [%o0], %g3
146 sub %g3, %g1, %g7
147 cas [%o0], %g3, %g7
148 cmp %g3, %g7
149 bne,pn %icc, 1b
150 sub %g7, %g1, %g7
151 cmp %g7, 0
152 bl,pn %icc, 3f
153 nop
1542:
155 retl
156 nop
1573:
158 save %sp, -192, %sp
159 call rwsem_downgrade_wake
160 mov %i0, %o0
161 ret
162 restore
163 .size __downgrade_write, .-__downgrade_write
diff --git a/arch/sparc/prom/cif.S b/arch/sparc/prom/cif.S
index 5f27ad779c0c..9c86b4b7d429 100644
--- a/arch/sparc/prom/cif.S
+++ b/arch/sparc/prom/cif.S
@@ -9,18 +9,18 @@
9#include <asm/thread_info.h> 9#include <asm/thread_info.h>
10 10
11 .text 11 .text
12 .globl prom_cif_interface 12 .globl prom_cif_direct
13prom_cif_interface: 13prom_cif_direct:
14 sethi %hi(p1275buf), %o0 14 sethi %hi(p1275buf), %o1
15 or %o0, %lo(p1275buf), %o0 15 or %o1, %lo(p1275buf), %o1
16 ldx [%o0 + 0x010], %o1 ! prom_cif_stack 16 ldx [%o1 + 0x0010], %o2 ! prom_cif_stack
17 save %o1, -192, %sp 17 save %o2, -192, %sp
18 ldx [%i0 + 0x008], %l2 ! prom_cif_handler 18 ldx [%i1 + 0x0008], %l2 ! prom_cif_handler
19 mov %g4, %l0 19 mov %g4, %l0
20 mov %g5, %l1 20 mov %g5, %l1
21 mov %g6, %l3 21 mov %g6, %l3
22 call %l2 22 call %l2
23 add %i0, 0x018, %o0 ! prom_args 23 mov %i0, %o0 ! prom_args
24 mov %l0, %g4 24 mov %l0, %g4
25 mov %l1, %g5 25 mov %l1, %g5
26 mov %l3, %g6 26 mov %l3, %g6
diff --git a/arch/sparc/prom/console_64.c b/arch/sparc/prom/console_64.c
index f55d58a8a156..10322dc2f557 100644
--- a/arch/sparc/prom/console_64.c
+++ b/arch/sparc/prom/console_64.c
@@ -21,14 +21,22 @@ extern int prom_stdin, prom_stdout;
21inline int 21inline int
22prom_nbgetchar(void) 22prom_nbgetchar(void)
23{ 23{
24 unsigned long args[7];
24 char inc; 25 char inc;
25 26
26 if (p1275_cmd("read", P1275_ARG(1,P1275_ARG_OUT_BUF)| 27 args[0] = (unsigned long) "read";
27 P1275_INOUT(3,1), 28 args[1] = 3;
28 prom_stdin, &inc, P1275_SIZE(1)) == 1) 29 args[2] = 1;
30 args[3] = (unsigned int) prom_stdin;
31 args[4] = (unsigned long) &inc;
32 args[5] = 1;
33 args[6] = (unsigned long) -1;
34
35 p1275_cmd_direct(args);
36
37 if (args[6] == 1)
29 return inc; 38 return inc;
30 else 39 return -1;
31 return -1;
32} 40}
33 41
34/* Non blocking put character to console device, returns -1 if 42/* Non blocking put character to console device, returns -1 if
@@ -37,12 +45,22 @@ prom_nbgetchar(void)
37inline int 45inline int
38prom_nbputchar(char c) 46prom_nbputchar(char c)
39{ 47{
48 unsigned long args[7];
40 char outc; 49 char outc;
41 50
42 outc = c; 51 outc = c;
43 if (p1275_cmd("write", P1275_ARG(1,P1275_ARG_IN_BUF)| 52
44 P1275_INOUT(3,1), 53 args[0] = (unsigned long) "write";
45 prom_stdout, &outc, P1275_SIZE(1)) == 1) 54 args[1] = 3;
55 args[2] = 1;
56 args[3] = (unsigned int) prom_stdout;
57 args[4] = (unsigned long) &outc;
58 args[5] = 1;
59 args[6] = (unsigned long) -1;
60
61 p1275_cmd_direct(args);
62
63 if (args[6] == 1)
46 return 0; 64 return 0;
47 else 65 else
48 return -1; 66 return -1;
@@ -67,7 +85,15 @@ prom_putchar(char c)
67void 85void
68prom_puts(const char *s, int len) 86prom_puts(const char *s, int len)
69{ 87{
70 p1275_cmd("write", P1275_ARG(1,P1275_ARG_IN_BUF)| 88 unsigned long args[7];
71 P1275_INOUT(3,1), 89
72 prom_stdout, s, P1275_SIZE(len)); 90 args[0] = (unsigned long) "write";
91 args[1] = 3;
92 args[2] = 1;
93 args[3] = (unsigned int) prom_stdout;
94 args[4] = (unsigned long) s;
95 args[5] = len;
96 args[6] = (unsigned long) -1;
97
98 p1275_cmd_direct(args);
73} 99}
diff --git a/arch/sparc/prom/devops_64.c b/arch/sparc/prom/devops_64.c
index 9dbd803e46e1..a017119e7ef1 100644
--- a/arch/sparc/prom/devops_64.c
+++ b/arch/sparc/prom/devops_64.c
@@ -18,16 +18,32 @@
18int 18int
19prom_devopen(const char *dstr) 19prom_devopen(const char *dstr)
20{ 20{
21 return p1275_cmd ("open", P1275_ARG(0,P1275_ARG_IN_STRING)| 21 unsigned long args[5];
22 P1275_INOUT(1,1), 22
23 dstr); 23 args[0] = (unsigned long) "open";
24 args[1] = 1;
25 args[2] = 1;
26 args[3] = (unsigned long) dstr;
27 args[4] = (unsigned long) -1;
28
29 p1275_cmd_direct(args);
30
31 return (int) args[4];
24} 32}
25 33
26/* Close the device described by device handle 'dhandle'. */ 34/* Close the device described by device handle 'dhandle'. */
27int 35int
28prom_devclose(int dhandle) 36prom_devclose(int dhandle)
29{ 37{
30 p1275_cmd ("close", P1275_INOUT(1,0), dhandle); 38 unsigned long args[4];
39
40 args[0] = (unsigned long) "close";
41 args[1] = 1;
42 args[2] = 0;
43 args[3] = (unsigned int) dhandle;
44
45 p1275_cmd_direct(args);
46
31 return 0; 47 return 0;
32} 48}
33 49
@@ -37,5 +53,15 @@ prom_devclose(int dhandle)
37void 53void
38prom_seek(int dhandle, unsigned int seekhi, unsigned int seeklo) 54prom_seek(int dhandle, unsigned int seekhi, unsigned int seeklo)
39{ 55{
40 p1275_cmd ("seek", P1275_INOUT(3,1), dhandle, seekhi, seeklo); 56 unsigned long args[7];
57
58 args[0] = (unsigned long) "seek";
59 args[1] = 3;
60 args[2] = 1;
61 args[3] = (unsigned int) dhandle;
62 args[4] = seekhi;
63 args[5] = seeklo;
64 args[6] = (unsigned long) -1;
65
66 p1275_cmd_direct(args);
41} 67}
diff --git a/arch/sparc/prom/misc_64.c b/arch/sparc/prom/misc_64.c
index 39fc6af21b7c..6cb1581d6aef 100644
--- a/arch/sparc/prom/misc_64.c
+++ b/arch/sparc/prom/misc_64.c
@@ -20,10 +20,17 @@
20 20
21int prom_service_exists(const char *service_name) 21int prom_service_exists(const char *service_name)
22{ 22{
23 int err = p1275_cmd("test", P1275_ARG(0, P1275_ARG_IN_STRING) | 23 unsigned long args[5];
24 P1275_INOUT(1, 1), service_name);
25 24
26 if (err) 25 args[0] = (unsigned long) "test";
26 args[1] = 1;
27 args[2] = 1;
28 args[3] = (unsigned long) service_name;
29 args[4] = (unsigned long) -1;
30
31 p1275_cmd_direct(args);
32
33 if (args[4])
27 return 0; 34 return 0;
28 return 1; 35 return 1;
29} 36}
@@ -31,30 +38,47 @@ int prom_service_exists(const char *service_name)
31void prom_sun4v_guest_soft_state(void) 38void prom_sun4v_guest_soft_state(void)
32{ 39{
33 const char *svc = "SUNW,soft-state-supported"; 40 const char *svc = "SUNW,soft-state-supported";
41 unsigned long args[3];
34 42
35 if (!prom_service_exists(svc)) 43 if (!prom_service_exists(svc))
36 return; 44 return;
37 p1275_cmd(svc, P1275_INOUT(0, 0)); 45 args[0] = (unsigned long) svc;
46 args[1] = 0;
47 args[2] = 0;
48 p1275_cmd_direct(args);
38} 49}
39 50
40/* Reset and reboot the machine with the command 'bcommand'. */ 51/* Reset and reboot the machine with the command 'bcommand'. */
41void prom_reboot(const char *bcommand) 52void prom_reboot(const char *bcommand)
42{ 53{
54 unsigned long args[4];
55
43#ifdef CONFIG_SUN_LDOMS 56#ifdef CONFIG_SUN_LDOMS
44 if (ldom_domaining_enabled) 57 if (ldom_domaining_enabled)
45 ldom_reboot(bcommand); 58 ldom_reboot(bcommand);
46#endif 59#endif
47 p1275_cmd("boot", P1275_ARG(0, P1275_ARG_IN_STRING) | 60 args[0] = (unsigned long) "boot";
48 P1275_INOUT(1, 0), bcommand); 61 args[1] = 1;
62 args[2] = 0;
63 args[3] = (unsigned long) bcommand;
64
65 p1275_cmd_direct(args);
49} 66}
50 67
51/* Forth evaluate the expression contained in 'fstring'. */ 68/* Forth evaluate the expression contained in 'fstring'. */
52void prom_feval(const char *fstring) 69void prom_feval(const char *fstring)
53{ 70{
71 unsigned long args[5];
72
54 if (!fstring || fstring[0] == 0) 73 if (!fstring || fstring[0] == 0)
55 return; 74 return;
56 p1275_cmd("interpret", P1275_ARG(0, P1275_ARG_IN_STRING) | 75 args[0] = (unsigned long) "interpret";
57 P1275_INOUT(1, 1), fstring); 76 args[1] = 1;
77 args[2] = 1;
78 args[3] = (unsigned long) fstring;
79 args[4] = (unsigned long) -1;
80
81 p1275_cmd_direct(args);
58} 82}
59EXPORT_SYMBOL(prom_feval); 83EXPORT_SYMBOL(prom_feval);
60 84
@@ -68,6 +92,7 @@ extern void smp_release(void);
68 */ 92 */
69void prom_cmdline(void) 93void prom_cmdline(void)
70{ 94{
95 unsigned long args[3];
71 unsigned long flags; 96 unsigned long flags;
72 97
73 local_irq_save(flags); 98 local_irq_save(flags);
@@ -76,7 +101,11 @@ void prom_cmdline(void)
76 smp_capture(); 101 smp_capture();
77#endif 102#endif
78 103
79 p1275_cmd("enter", P1275_INOUT(0, 0)); 104 args[0] = (unsigned long) "enter";
105 args[1] = 0;
106 args[2] = 0;
107
108 p1275_cmd_direct(args);
80 109
81#ifdef CONFIG_SMP 110#ifdef CONFIG_SMP
82 smp_release(); 111 smp_release();
@@ -90,22 +119,32 @@ void prom_cmdline(void)
90 */ 119 */
91void notrace prom_halt(void) 120void notrace prom_halt(void)
92{ 121{
122 unsigned long args[3];
123
93#ifdef CONFIG_SUN_LDOMS 124#ifdef CONFIG_SUN_LDOMS
94 if (ldom_domaining_enabled) 125 if (ldom_domaining_enabled)
95 ldom_power_off(); 126 ldom_power_off();
96#endif 127#endif
97again: 128again:
98 p1275_cmd("exit", P1275_INOUT(0, 0)); 129 args[0] = (unsigned long) "exit";
130 args[1] = 0;
131 args[2] = 0;
132 p1275_cmd_direct(args);
99 goto again; /* PROM is out to get me -DaveM */ 133 goto again; /* PROM is out to get me -DaveM */
100} 134}
101 135
102void prom_halt_power_off(void) 136void prom_halt_power_off(void)
103{ 137{
138 unsigned long args[3];
139
104#ifdef CONFIG_SUN_LDOMS 140#ifdef CONFIG_SUN_LDOMS
105 if (ldom_domaining_enabled) 141 if (ldom_domaining_enabled)
106 ldom_power_off(); 142 ldom_power_off();
107#endif 143#endif
108 p1275_cmd("SUNW,power-off", P1275_INOUT(0, 0)); 144 args[0] = (unsigned long) "SUNW,power-off";
145 args[1] = 0;
146 args[2] = 0;
147 p1275_cmd_direct(args);
109 148
110 /* if nothing else helps, we just halt */ 149 /* if nothing else helps, we just halt */
111 prom_halt(); 150 prom_halt();
@@ -114,10 +153,15 @@ void prom_halt_power_off(void)
114/* Set prom sync handler to call function 'funcp'. */ 153/* Set prom sync handler to call function 'funcp'. */
115void prom_setcallback(callback_func_t funcp) 154void prom_setcallback(callback_func_t funcp)
116{ 155{
156 unsigned long args[5];
117 if (!funcp) 157 if (!funcp)
118 return; 158 return;
119 p1275_cmd("set-callback", P1275_ARG(0, P1275_ARG_IN_FUNCTION) | 159 args[0] = (unsigned long) "set-callback";
120 P1275_INOUT(1, 1), funcp); 160 args[1] = 1;
161 args[2] = 1;
162 args[3] = (unsigned long) funcp;
163 args[4] = (unsigned long) -1;
164 p1275_cmd_direct(args);
121} 165}
122 166
123/* Get the idprom and stuff it into buffer 'idbuf'. Returns the 167/* Get the idprom and stuff it into buffer 'idbuf'. Returns the
@@ -173,57 +217,61 @@ static int prom_get_memory_ihandle(void)
173} 217}
174 218
175/* Load explicit I/D TLB entries. */ 219/* Load explicit I/D TLB entries. */
220static long tlb_load(const char *type, unsigned long index,
221 unsigned long tte_data, unsigned long vaddr)
222{
223 unsigned long args[9];
224
225 args[0] = (unsigned long) prom_callmethod_name;
226 args[1] = 5;
227 args[2] = 1;
228 args[3] = (unsigned long) type;
229 args[4] = (unsigned int) prom_get_mmu_ihandle();
230 args[5] = vaddr;
231 args[6] = tte_data;
232 args[7] = index;
233 args[8] = (unsigned long) -1;
234
235 p1275_cmd_direct(args);
236
237 return (long) args[8];
238}
239
176long prom_itlb_load(unsigned long index, 240long prom_itlb_load(unsigned long index,
177 unsigned long tte_data, 241 unsigned long tte_data,
178 unsigned long vaddr) 242 unsigned long vaddr)
179{ 243{
180 return p1275_cmd(prom_callmethod_name, 244 return tlb_load("SUNW,itlb-load", index, tte_data, vaddr);
181 (P1275_ARG(0, P1275_ARG_IN_STRING) |
182 P1275_ARG(2, P1275_ARG_IN_64B) |
183 P1275_ARG(3, P1275_ARG_IN_64B) |
184 P1275_INOUT(5, 1)),
185 "SUNW,itlb-load",
186 prom_get_mmu_ihandle(),
187 /* And then our actual args are pushed backwards. */
188 vaddr,
189 tte_data,
190 index);
191} 245}
192 246
193long prom_dtlb_load(unsigned long index, 247long prom_dtlb_load(unsigned long index,
194 unsigned long tte_data, 248 unsigned long tte_data,
195 unsigned long vaddr) 249 unsigned long vaddr)
196{ 250{
197 return p1275_cmd(prom_callmethod_name, 251 return tlb_load("SUNW,dtlb-load", index, tte_data, vaddr);
198 (P1275_ARG(0, P1275_ARG_IN_STRING) |
199 P1275_ARG(2, P1275_ARG_IN_64B) |
200 P1275_ARG(3, P1275_ARG_IN_64B) |
201 P1275_INOUT(5, 1)),
202 "SUNW,dtlb-load",
203 prom_get_mmu_ihandle(),
204 /* And then our actual args are pushed backwards. */
205 vaddr,
206 tte_data,
207 index);
208} 252}
209 253
210int prom_map(int mode, unsigned long size, 254int prom_map(int mode, unsigned long size,
211 unsigned long vaddr, unsigned long paddr) 255 unsigned long vaddr, unsigned long paddr)
212{ 256{
213 int ret = p1275_cmd(prom_callmethod_name, 257 unsigned long args[11];
214 (P1275_ARG(0, P1275_ARG_IN_STRING) | 258 int ret;
215 P1275_ARG(3, P1275_ARG_IN_64B) | 259
216 P1275_ARG(4, P1275_ARG_IN_64B) | 260 args[0] = (unsigned long) prom_callmethod_name;
217 P1275_ARG(6, P1275_ARG_IN_64B) | 261 args[1] = 7;
218 P1275_INOUT(7, 1)), 262 args[2] = 1;
219 prom_map_name, 263 args[3] = (unsigned long) prom_map_name;
220 prom_get_mmu_ihandle(), 264 args[4] = (unsigned int) prom_get_mmu_ihandle();
221 mode, 265 args[5] = (unsigned int) mode;
222 size, 266 args[6] = size;
223 vaddr, 267 args[7] = vaddr;
224 0, 268 args[8] = 0;
225 paddr); 269 args[9] = paddr;
226 270 args[10] = (unsigned long) -1;
271
272 p1275_cmd_direct(args);
273
274 ret = (int) args[10];
227 if (ret == 0) 275 if (ret == 0)
228 ret = -1; 276 ret = -1;
229 return ret; 277 return ret;
@@ -231,40 +279,51 @@ int prom_map(int mode, unsigned long size,
231 279
232void prom_unmap(unsigned long size, unsigned long vaddr) 280void prom_unmap(unsigned long size, unsigned long vaddr)
233{ 281{
234 p1275_cmd(prom_callmethod_name, 282 unsigned long args[7];
235 (P1275_ARG(0, P1275_ARG_IN_STRING) | 283
236 P1275_ARG(2, P1275_ARG_IN_64B) | 284 args[0] = (unsigned long) prom_callmethod_name;
237 P1275_ARG(3, P1275_ARG_IN_64B) | 285 args[1] = 4;
238 P1275_INOUT(4, 0)), 286 args[2] = 0;
239 prom_unmap_name, 287 args[3] = (unsigned long) prom_unmap_name;
240 prom_get_mmu_ihandle(), 288 args[4] = (unsigned int) prom_get_mmu_ihandle();
241 size, 289 args[5] = size;
242 vaddr); 290 args[6] = vaddr;
291
292 p1275_cmd_direct(args);
243} 293}
244 294
245/* Set aside physical memory which is not touched or modified 295/* Set aside physical memory which is not touched or modified
246 * across soft resets. 296 * across soft resets.
247 */ 297 */
248unsigned long prom_retain(const char *name, 298int prom_retain(const char *name, unsigned long size,
249 unsigned long pa_low, unsigned long pa_high, 299 unsigned long align, unsigned long *paddr)
250 long size, long align)
251{ 300{
252 /* XXX I don't think we return multiple values correctly. 301 unsigned long args[11];
253 * XXX OBP supposedly returns pa_low/pa_high here, how does 302
254 * XXX it work? 303 args[0] = (unsigned long) prom_callmethod_name;
304 args[1] = 5;
305 args[2] = 3;
306 args[3] = (unsigned long) "SUNW,retain";
307 args[4] = (unsigned int) prom_get_memory_ihandle();
308 args[5] = align;
309 args[6] = size;
310 args[7] = (unsigned long) name;
311 args[8] = (unsigned long) -1;
312 args[9] = (unsigned long) -1;
313 args[10] = (unsigned long) -1;
314
315 p1275_cmd_direct(args);
316
317 if (args[8])
318 return (int) args[8];
319
320 /* Next we get "phys_high" then "phys_low". On 64-bit
321 * the phys_high cell is don't care since the phys_low
322 * cell has the full value.
255 */ 323 */
324 *paddr = args[10];
256 325
257 /* If align is zero, the pa_low/pa_high args are passed, 326 return 0;
258 * else they are not.
259 */
260 if (align == 0)
261 return p1275_cmd("SUNW,retain",
262 (P1275_ARG(0, P1275_ARG_IN_BUF) | P1275_INOUT(5, 2)),
263 name, pa_low, pa_high, size, align);
264 else
265 return p1275_cmd("SUNW,retain",
266 (P1275_ARG(0, P1275_ARG_IN_BUF) | P1275_INOUT(3, 2)),
267 name, size, align);
268} 327}
269 328
270/* Get "Unumber" string for the SIMM at the given 329/* Get "Unumber" string for the SIMM at the given
@@ -277,62 +336,129 @@ int prom_getunumber(int syndrome_code,
277 unsigned long phys_addr, 336 unsigned long phys_addr,
278 char *buf, int buflen) 337 char *buf, int buflen)
279{ 338{
280 return p1275_cmd(prom_callmethod_name, 339 unsigned long args[12];
281 (P1275_ARG(0, P1275_ARG_IN_STRING) | 340
282 P1275_ARG(3, P1275_ARG_OUT_BUF) | 341 args[0] = (unsigned long) prom_callmethod_name;
283 P1275_ARG(6, P1275_ARG_IN_64B) | 342 args[1] = 7;
284 P1275_INOUT(8, 2)), 343 args[2] = 2;
285 "SUNW,get-unumber", prom_get_memory_ihandle(), 344 args[3] = (unsigned long) "SUNW,get-unumber";
286 buflen, buf, P1275_SIZE(buflen), 345 args[4] = (unsigned int) prom_get_memory_ihandle();
287 0, phys_addr, syndrome_code); 346 args[5] = buflen;
347 args[6] = (unsigned long) buf;
348 args[7] = 0;
349 args[8] = phys_addr;
350 args[9] = (unsigned int) syndrome_code;
351 args[10] = (unsigned long) -1;
352 args[11] = (unsigned long) -1;
353
354 p1275_cmd_direct(args);
355
356 return (int) args[10];
288} 357}
289 358
290/* Power management extensions. */ 359/* Power management extensions. */
291void prom_sleepself(void) 360void prom_sleepself(void)
292{ 361{
293 p1275_cmd("SUNW,sleep-self", P1275_INOUT(0, 0)); 362 unsigned long args[3];
363
364 args[0] = (unsigned long) "SUNW,sleep-self";
365 args[1] = 0;
366 args[2] = 0;
367 p1275_cmd_direct(args);
294} 368}
295 369
296int prom_sleepsystem(void) 370int prom_sleepsystem(void)
297{ 371{
298 return p1275_cmd("SUNW,sleep-system", P1275_INOUT(0, 1)); 372 unsigned long args[4];
373
374 args[0] = (unsigned long) "SUNW,sleep-system";
375 args[1] = 0;
376 args[2] = 1;
377 args[3] = (unsigned long) -1;
378 p1275_cmd_direct(args);
379
380 return (int) args[3];
299} 381}
300 382
301int prom_wakeupsystem(void) 383int prom_wakeupsystem(void)
302{ 384{
303 return p1275_cmd("SUNW,wakeup-system", P1275_INOUT(0, 1)); 385 unsigned long args[4];
386
387 args[0] = (unsigned long) "SUNW,wakeup-system";
388 args[1] = 0;
389 args[2] = 1;
390 args[3] = (unsigned long) -1;
391 p1275_cmd_direct(args);
392
393 return (int) args[3];
304} 394}
305 395
306#ifdef CONFIG_SMP 396#ifdef CONFIG_SMP
307void prom_startcpu(int cpunode, unsigned long pc, unsigned long arg) 397void prom_startcpu(int cpunode, unsigned long pc, unsigned long arg)
308{ 398{
309 p1275_cmd("SUNW,start-cpu", P1275_INOUT(3, 0), cpunode, pc, arg); 399 unsigned long args[6];
400
401 args[0] = (unsigned long) "SUNW,start-cpu";
402 args[1] = 3;
403 args[2] = 0;
404 args[3] = (unsigned int) cpunode;
405 args[4] = pc;
406 args[5] = arg;
407 p1275_cmd_direct(args);
310} 408}
311 409
312void prom_startcpu_cpuid(int cpuid, unsigned long pc, unsigned long arg) 410void prom_startcpu_cpuid(int cpuid, unsigned long pc, unsigned long arg)
313{ 411{
314 p1275_cmd("SUNW,start-cpu-by-cpuid", P1275_INOUT(3, 0), 412 unsigned long args[6];
315 cpuid, pc, arg); 413
414 args[0] = (unsigned long) "SUNW,start-cpu-by-cpuid";
415 args[1] = 3;
416 args[2] = 0;
417 args[3] = (unsigned int) cpuid;
418 args[4] = pc;
419 args[5] = arg;
420 p1275_cmd_direct(args);
316} 421}
317 422
318void prom_stopcpu_cpuid(int cpuid) 423void prom_stopcpu_cpuid(int cpuid)
319{ 424{
320 p1275_cmd("SUNW,stop-cpu-by-cpuid", P1275_INOUT(1, 0), 425 unsigned long args[4];
321 cpuid); 426
427 args[0] = (unsigned long) "SUNW,stop-cpu-by-cpuid";
428 args[1] = 1;
429 args[2] = 0;
430 args[3] = (unsigned int) cpuid;
431 p1275_cmd_direct(args);
322} 432}
323 433
324void prom_stopself(void) 434void prom_stopself(void)
325{ 435{
326 p1275_cmd("SUNW,stop-self", P1275_INOUT(0, 0)); 436 unsigned long args[3];
437
438 args[0] = (unsigned long) "SUNW,stop-self";
439 args[1] = 0;
440 args[2] = 0;
441 p1275_cmd_direct(args);
327} 442}
328 443
329void prom_idleself(void) 444void prom_idleself(void)
330{ 445{
331 p1275_cmd("SUNW,idle-self", P1275_INOUT(0, 0)); 446 unsigned long args[3];
447
448 args[0] = (unsigned long) "SUNW,idle-self";
449 args[1] = 0;
450 args[2] = 0;
451 p1275_cmd_direct(args);
332} 452}
333 453
334void prom_resumecpu(int cpunode) 454void prom_resumecpu(int cpunode)
335{ 455{
336 p1275_cmd("SUNW,resume-cpu", P1275_INOUT(1, 0), cpunode); 456 unsigned long args[4];
457
458 args[0] = (unsigned long) "SUNW,resume-cpu";
459 args[1] = 1;
460 args[2] = 0;
461 args[3] = (unsigned int) cpunode;
462 p1275_cmd_direct(args);
337} 463}
338#endif 464#endif
diff --git a/arch/sparc/prom/p1275.c b/arch/sparc/prom/p1275.c
index 2d8b70d397f1..fa6e4e219b9c 100644
--- a/arch/sparc/prom/p1275.c
+++ b/arch/sparc/prom/p1275.c
@@ -22,13 +22,11 @@ struct {
22 long prom_callback; /* 0x00 */ 22 long prom_callback; /* 0x00 */
23 void (*prom_cif_handler)(long *); /* 0x08 */ 23 void (*prom_cif_handler)(long *); /* 0x08 */
24 unsigned long prom_cif_stack; /* 0x10 */ 24 unsigned long prom_cif_stack; /* 0x10 */
25 unsigned long prom_args [23]; /* 0x18 */
26 char prom_buffer [3000];
27} p1275buf; 25} p1275buf;
28 26
29extern void prom_world(int); 27extern void prom_world(int);
30 28
31extern void prom_cif_interface(void); 29extern void prom_cif_direct(unsigned long *args);
32extern void prom_cif_callback(void); 30extern void prom_cif_callback(void);
33 31
34/* 32/*
@@ -36,114 +34,20 @@ extern void prom_cif_callback(void);
36 */ 34 */
37DEFINE_RAW_SPINLOCK(prom_entry_lock); 35DEFINE_RAW_SPINLOCK(prom_entry_lock);
38 36
39long p1275_cmd(const char *service, long fmt, ...) 37void p1275_cmd_direct(unsigned long *args)
40{ 38{
41 char *p, *q;
42 unsigned long flags; 39 unsigned long flags;
43 int nargs, nrets, i;
44 va_list list;
45 long attrs, x;
46
47 p = p1275buf.prom_buffer;
48 40
49 raw_local_save_flags(flags); 41 raw_local_save_flags(flags);
50 raw_local_irq_restore(PIL_NMI); 42 raw_local_irq_restore(PIL_NMI);
51 raw_spin_lock(&prom_entry_lock); 43 raw_spin_lock(&prom_entry_lock);
52 44
53 p1275buf.prom_args[0] = (unsigned long)p; /* service */
54 strcpy (p, service);
55 p = (char *)(((long)(strchr (p, 0) + 8)) & ~7);
56 p1275buf.prom_args[1] = nargs = (fmt & 0x0f); /* nargs */
57 p1275buf.prom_args[2] = nrets = ((fmt & 0xf0) >> 4); /* nrets */
58 attrs = fmt >> 8;
59 va_start(list, fmt);
60 for (i = 0; i < nargs; i++, attrs >>= 3) {
61 switch (attrs & 0x7) {
62 case P1275_ARG_NUMBER:
63 p1275buf.prom_args[i + 3] =
64 (unsigned)va_arg(list, long);
65 break;
66 case P1275_ARG_IN_64B:
67 p1275buf.prom_args[i + 3] =
68 va_arg(list, unsigned long);
69 break;
70 case P1275_ARG_IN_STRING:
71 strcpy (p, va_arg(list, char *));
72 p1275buf.prom_args[i + 3] = (unsigned long)p;
73 p = (char *)(((long)(strchr (p, 0) + 8)) & ~7);
74 break;
75 case P1275_ARG_OUT_BUF:
76 (void) va_arg(list, char *);
77 p1275buf.prom_args[i + 3] = (unsigned long)p;
78 x = va_arg(list, long);
79 i++; attrs >>= 3;
80 p = (char *)(((long)(p + (int)x + 7)) & ~7);
81 p1275buf.prom_args[i + 3] = x;
82 break;
83 case P1275_ARG_IN_BUF:
84 q = va_arg(list, char *);
85 p1275buf.prom_args[i + 3] = (unsigned long)p;
86 x = va_arg(list, long);
87 i++; attrs >>= 3;
88 memcpy (p, q, (int)x);
89 p = (char *)(((long)(p + (int)x + 7)) & ~7);
90 p1275buf.prom_args[i + 3] = x;
91 break;
92 case P1275_ARG_OUT_32B:
93 (void) va_arg(list, char *);
94 p1275buf.prom_args[i + 3] = (unsigned long)p;
95 p += 32;
96 break;
97 case P1275_ARG_IN_FUNCTION:
98 p1275buf.prom_args[i + 3] =
99 (unsigned long)prom_cif_callback;
100 p1275buf.prom_callback = va_arg(list, long);
101 break;
102 }
103 }
104 va_end(list);
105
106 prom_world(1); 45 prom_world(1);
107 prom_cif_interface(); 46 prom_cif_direct(args);
108 prom_world(0); 47 prom_world(0);
109 48
110 attrs = fmt >> 8;
111 va_start(list, fmt);
112 for (i = 0; i < nargs; i++, attrs >>= 3) {
113 switch (attrs & 0x7) {
114 case P1275_ARG_NUMBER:
115 (void) va_arg(list, long);
116 break;
117 case P1275_ARG_IN_STRING:
118 (void) va_arg(list, char *);
119 break;
120 case P1275_ARG_IN_FUNCTION:
121 (void) va_arg(list, long);
122 break;
123 case P1275_ARG_IN_BUF:
124 (void) va_arg(list, char *);
125 (void) va_arg(list, long);
126 i++; attrs >>= 3;
127 break;
128 case P1275_ARG_OUT_BUF:
129 p = va_arg(list, char *);
130 x = va_arg(list, long);
131 memcpy (p, (char *)(p1275buf.prom_args[i + 3]), (int)x);
132 i++; attrs >>= 3;
133 break;
134 case P1275_ARG_OUT_32B:
135 p = va_arg(list, char *);
136 memcpy (p, (char *)(p1275buf.prom_args[i + 3]), 32);
137 break;
138 }
139 }
140 va_end(list);
141 x = p1275buf.prom_args [nargs + 3];
142
143 raw_spin_unlock(&prom_entry_lock); 49 raw_spin_unlock(&prom_entry_lock);
144 raw_local_irq_restore(flags); 50 raw_local_irq_restore(flags);
145
146 return x;
147} 51}
148 52
149void prom_cif_init(void *cif_handler, void *cif_stack) 53void prom_cif_init(void *cif_handler, void *cif_stack)
diff --git a/arch/sparc/prom/tree_64.c b/arch/sparc/prom/tree_64.c
index 3c0d2dd9f693..9d3f9137a43a 100644
--- a/arch/sparc/prom/tree_64.c
+++ b/arch/sparc/prom/tree_64.c
@@ -16,22 +16,39 @@
16#include <asm/oplib.h> 16#include <asm/oplib.h>
17#include <asm/ldc.h> 17#include <asm/ldc.h>
18 18
19static int prom_node_to_node(const char *type, int node)
20{
21 unsigned long args[5];
22
23 args[0] = (unsigned long) type;
24 args[1] = 1;
25 args[2] = 1;
26 args[3] = (unsigned int) node;
27 args[4] = (unsigned long) -1;
28
29 p1275_cmd_direct(args);
30
31 return (int) args[4];
32}
33
19/* Return the child of node 'node' or zero if no this node has no 34/* Return the child of node 'node' or zero if no this node has no
20 * direct descendent. 35 * direct descendent.
21 */ 36 */
22inline int __prom_getchild(int node) 37inline int __prom_getchild(int node)
23{ 38{
24 return p1275_cmd ("child", P1275_INOUT(1, 1), node); 39 return prom_node_to_node("child", node);
25} 40}
26 41
27inline int prom_getchild(int node) 42inline int prom_getchild(int node)
28{ 43{
29 int cnode; 44 int cnode;
30 45
31 if(node == -1) return 0; 46 if (node == -1)
47 return 0;
32 cnode = __prom_getchild(node); 48 cnode = __prom_getchild(node);
33 if(cnode == -1) return 0; 49 if (cnode == -1)
34 return (int)cnode; 50 return 0;
51 return cnode;
35} 52}
36EXPORT_SYMBOL(prom_getchild); 53EXPORT_SYMBOL(prom_getchild);
37 54
@@ -39,10 +56,12 @@ inline int prom_getparent(int node)
39{ 56{
40 int cnode; 57 int cnode;
41 58
42 if(node == -1) return 0; 59 if (node == -1)
43 cnode = p1275_cmd ("parent", P1275_INOUT(1, 1), node); 60 return 0;
44 if(cnode == -1) return 0; 61 cnode = prom_node_to_node("parent", node);
45 return (int)cnode; 62 if (cnode == -1)
63 return 0;
64 return cnode;
46} 65}
47 66
48/* Return the next sibling of node 'node' or zero if no more siblings 67/* Return the next sibling of node 'node' or zero if no more siblings
@@ -50,7 +69,7 @@ inline int prom_getparent(int node)
50 */ 69 */
51inline int __prom_getsibling(int node) 70inline int __prom_getsibling(int node)
52{ 71{
53 return p1275_cmd(prom_peer_name, P1275_INOUT(1, 1), node); 72 return prom_node_to_node(prom_peer_name, node);
54} 73}
55 74
56inline int prom_getsibling(int node) 75inline int prom_getsibling(int node)
@@ -72,11 +91,21 @@ EXPORT_SYMBOL(prom_getsibling);
72 */ 91 */
73inline int prom_getproplen(int node, const char *prop) 92inline int prom_getproplen(int node, const char *prop)
74{ 93{
75 if((!node) || (!prop)) return -1; 94 unsigned long args[6];
76 return p1275_cmd ("getproplen", 95
77 P1275_ARG(1,P1275_ARG_IN_STRING)| 96 if (!node || !prop)
78 P1275_INOUT(2, 1), 97 return -1;
79 node, prop); 98
99 args[0] = (unsigned long) "getproplen";
100 args[1] = 2;
101 args[2] = 1;
102 args[3] = (unsigned int) node;
103 args[4] = (unsigned long) prop;
104 args[5] = (unsigned long) -1;
105
106 p1275_cmd_direct(args);
107
108 return (int) args[5];
80} 109}
81EXPORT_SYMBOL(prom_getproplen); 110EXPORT_SYMBOL(prom_getproplen);
82 111
@@ -87,19 +116,25 @@ EXPORT_SYMBOL(prom_getproplen);
87inline int prom_getproperty(int node, const char *prop, 116inline int prom_getproperty(int node, const char *prop,
88 char *buffer, int bufsize) 117 char *buffer, int bufsize)
89{ 118{
119 unsigned long args[8];
90 int plen; 120 int plen;
91 121
92 plen = prom_getproplen(node, prop); 122 plen = prom_getproplen(node, prop);
93 if ((plen > bufsize) || (plen == 0) || (plen == -1)) { 123 if ((plen > bufsize) || (plen == 0) || (plen == -1))
94 return -1; 124 return -1;
95 } else { 125
96 /* Ok, things seem all right. */ 126 args[0] = (unsigned long) prom_getprop_name;
97 return p1275_cmd(prom_getprop_name, 127 args[1] = 4;
98 P1275_ARG(1,P1275_ARG_IN_STRING)| 128 args[2] = 1;
99 P1275_ARG(2,P1275_ARG_OUT_BUF)| 129 args[3] = (unsigned int) node;
100 P1275_INOUT(4, 1), 130 args[4] = (unsigned long) prop;
101 node, prop, buffer, P1275_SIZE(plen)); 131 args[5] = (unsigned long) buffer;
102 } 132 args[6] = bufsize;
133 args[7] = (unsigned long) -1;
134
135 p1275_cmd_direct(args);
136
137 return (int) args[7];
103} 138}
104EXPORT_SYMBOL(prom_getproperty); 139EXPORT_SYMBOL(prom_getproperty);
105 140
@@ -110,7 +145,7 @@ inline int prom_getint(int node, const char *prop)
110{ 145{
111 int intprop; 146 int intprop;
112 147
113 if(prom_getproperty(node, prop, (char *) &intprop, sizeof(int)) != -1) 148 if (prom_getproperty(node, prop, (char *) &intprop, sizeof(int)) != -1)
114 return intprop; 149 return intprop;
115 150
116 return -1; 151 return -1;
@@ -126,7 +161,8 @@ int prom_getintdefault(int node, const char *property, int deflt)
126 int retval; 161 int retval;
127 162
128 retval = prom_getint(node, property); 163 retval = prom_getint(node, property);
129 if(retval == -1) return deflt; 164 if (retval == -1)
165 return deflt;
130 166
131 return retval; 167 return retval;
132} 168}
@@ -138,7 +174,8 @@ int prom_getbool(int node, const char *prop)
138 int retval; 174 int retval;
139 175
140 retval = prom_getproplen(node, prop); 176 retval = prom_getproplen(node, prop);
141 if(retval == -1) return 0; 177 if (retval == -1)
178 return 0;
142 return 1; 179 return 1;
143} 180}
144EXPORT_SYMBOL(prom_getbool); 181EXPORT_SYMBOL(prom_getbool);
@@ -152,7 +189,8 @@ void prom_getstring(int node, const char *prop, char *user_buf, int ubuf_size)
152 int len; 189 int len;
153 190
154 len = prom_getproperty(node, prop, user_buf, ubuf_size); 191 len = prom_getproperty(node, prop, user_buf, ubuf_size);
155 if(len != -1) return; 192 if (len != -1)
193 return;
156 user_buf[0] = 0; 194 user_buf[0] = 0;
157} 195}
158EXPORT_SYMBOL(prom_getstring); 196EXPORT_SYMBOL(prom_getstring);
@@ -164,7 +202,8 @@ int prom_nodematch(int node, const char *name)
164{ 202{
165 char namebuf[128]; 203 char namebuf[128];
166 prom_getproperty(node, "name", namebuf, sizeof(namebuf)); 204 prom_getproperty(node, "name", namebuf, sizeof(namebuf));
167 if(strcmp(namebuf, name) == 0) return 1; 205 if (strcmp(namebuf, name) == 0)
206 return 1;
168 return 0; 207 return 0;
169} 208}
170 209
@@ -190,16 +229,29 @@ int prom_searchsiblings(int node_start, const char *nodename)
190} 229}
191EXPORT_SYMBOL(prom_searchsiblings); 230EXPORT_SYMBOL(prom_searchsiblings);
192 231
232static const char *prom_nextprop_name = "nextprop";
233
193/* Return the first property type for node 'node'. 234/* Return the first property type for node 'node'.
194 * buffer should be at least 32B in length 235 * buffer should be at least 32B in length
195 */ 236 */
196inline char *prom_firstprop(int node, char *buffer) 237inline char *prom_firstprop(int node, char *buffer)
197{ 238{
239 unsigned long args[7];
240
198 *buffer = 0; 241 *buffer = 0;
199 if(node == -1) return buffer; 242 if (node == -1)
200 p1275_cmd ("nextprop", P1275_ARG(2,P1275_ARG_OUT_32B)| 243 return buffer;
201 P1275_INOUT(3, 0), 244
202 node, (char *) 0x0, buffer); 245 args[0] = (unsigned long) prom_nextprop_name;
246 args[1] = 3;
247 args[2] = 1;
248 args[3] = (unsigned int) node;
249 args[4] = 0;
250 args[5] = (unsigned long) buffer;
251 args[6] = (unsigned long) -1;
252
253 p1275_cmd_direct(args);
254
203 return buffer; 255 return buffer;
204} 256}
205EXPORT_SYMBOL(prom_firstprop); 257EXPORT_SYMBOL(prom_firstprop);
@@ -210,9 +262,10 @@ EXPORT_SYMBOL(prom_firstprop);
210 */ 262 */
211inline char *prom_nextprop(int node, const char *oprop, char *buffer) 263inline char *prom_nextprop(int node, const char *oprop, char *buffer)
212{ 264{
265 unsigned long args[7];
213 char buf[32]; 266 char buf[32];
214 267
215 if(node == -1) { 268 if (node == -1) {
216 *buffer = 0; 269 *buffer = 0;
217 return buffer; 270 return buffer;
218 } 271 }
@@ -220,10 +273,17 @@ inline char *prom_nextprop(int node, const char *oprop, char *buffer)
220 strcpy (buf, oprop); 273 strcpy (buf, oprop);
221 oprop = buf; 274 oprop = buf;
222 } 275 }
223 p1275_cmd ("nextprop", P1275_ARG(1,P1275_ARG_IN_STRING)| 276
224 P1275_ARG(2,P1275_ARG_OUT_32B)| 277 args[0] = (unsigned long) prom_nextprop_name;
225 P1275_INOUT(3, 0), 278 args[1] = 3;
226 node, oprop, buffer); 279 args[2] = 1;
280 args[3] = (unsigned int) node;
281 args[4] = (unsigned long) oprop;
282 args[5] = (unsigned long) buffer;
283 args[6] = (unsigned long) -1;
284
285 p1275_cmd_direct(args);
286
227 return buffer; 287 return buffer;
228} 288}
229EXPORT_SYMBOL(prom_nextprop); 289EXPORT_SYMBOL(prom_nextprop);
@@ -231,12 +291,19 @@ EXPORT_SYMBOL(prom_nextprop);
231int 291int
232prom_finddevice(const char *name) 292prom_finddevice(const char *name)
233{ 293{
294 unsigned long args[5];
295
234 if (!name) 296 if (!name)
235 return 0; 297 return 0;
236 return p1275_cmd(prom_finddev_name, 298 args[0] = (unsigned long) "finddevice";
237 P1275_ARG(0,P1275_ARG_IN_STRING)| 299 args[1] = 1;
238 P1275_INOUT(1, 1), 300 args[2] = 1;
239 name); 301 args[3] = (unsigned long) name;
302 args[4] = (unsigned long) -1;
303
304 p1275_cmd_direct(args);
305
306 return (int) args[4];
240} 307}
241EXPORT_SYMBOL(prom_finddevice); 308EXPORT_SYMBOL(prom_finddevice);
242 309
@@ -247,7 +314,7 @@ int prom_node_has_property(int node, const char *prop)
247 *buf = 0; 314 *buf = 0;
248 do { 315 do {
249 prom_nextprop(node, buf, buf); 316 prom_nextprop(node, buf, buf);
250 if(!strcmp(buf, prop)) 317 if (!strcmp(buf, prop))
251 return 1; 318 return 1;
252 } while (*buf); 319 } while (*buf);
253 return 0; 320 return 0;
@@ -260,6 +327,8 @@ EXPORT_SYMBOL(prom_node_has_property);
260int 327int
261prom_setprop(int node, const char *pname, char *value, int size) 328prom_setprop(int node, const char *pname, char *value, int size)
262{ 329{
330 unsigned long args[8];
331
263 if (size == 0) 332 if (size == 0)
264 return 0; 333 return 0;
265 if ((pname == 0) || (value == 0)) 334 if ((pname == 0) || (value == 0))
@@ -271,19 +340,37 @@ prom_setprop(int node, const char *pname, char *value, int size)
271 return 0; 340 return 0;
272 } 341 }
273#endif 342#endif
274 return p1275_cmd ("setprop", P1275_ARG(1,P1275_ARG_IN_STRING)| 343 args[0] = (unsigned long) "setprop";
275 P1275_ARG(2,P1275_ARG_IN_BUF)| 344 args[1] = 4;
276 P1275_INOUT(4, 1), 345 args[2] = 1;
277 node, pname, value, P1275_SIZE(size)); 346 args[3] = (unsigned int) node;
347 args[4] = (unsigned long) pname;
348 args[5] = (unsigned long) value;
349 args[6] = size;
350 args[7] = (unsigned long) -1;
351
352 p1275_cmd_direct(args);
353
354 return (int) args[7];
278} 355}
279EXPORT_SYMBOL(prom_setprop); 356EXPORT_SYMBOL(prom_setprop);
280 357
281inline int prom_inst2pkg(int inst) 358inline int prom_inst2pkg(int inst)
282{ 359{
360 unsigned long args[5];
283 int node; 361 int node;
284 362
285 node = p1275_cmd ("instance-to-package", P1275_INOUT(1, 1), inst); 363 args[0] = (unsigned long) "instance-to-package";
286 if (node == -1) return 0; 364 args[1] = 1;
365 args[2] = 1;
366 args[3] = (unsigned int) inst;
367 args[4] = (unsigned long) -1;
368
369 p1275_cmd_direct(args);
370
371 node = (int) args[4];
372 if (node == -1)
373 return 0;
287 return node; 374 return node;
288} 375}
289 376
@@ -296,17 +383,28 @@ prom_pathtoinode(const char *path)
296 int node, inst; 383 int node, inst;
297 384
298 inst = prom_devopen (path); 385 inst = prom_devopen (path);
299 if (inst == 0) return 0; 386 if (inst == 0)
300 node = prom_inst2pkg (inst); 387 return 0;
301 prom_devclose (inst); 388 node = prom_inst2pkg(inst);
302 if (node == -1) return 0; 389 prom_devclose(inst);
390 if (node == -1)
391 return 0;
303 return node; 392 return node;
304} 393}
305 394
306int prom_ihandle2path(int handle, char *buffer, int bufsize) 395int prom_ihandle2path(int handle, char *buffer, int bufsize)
307{ 396{
308 return p1275_cmd("instance-to-path", 397 unsigned long args[7];
309 P1275_ARG(1,P1275_ARG_OUT_BUF)| 398
310 P1275_INOUT(3, 1), 399 args[0] = (unsigned long) "instance-to-path";
311 handle, buffer, P1275_SIZE(bufsize)); 400 args[1] = 3;
401 args[2] = 1;
402 args[3] = (unsigned int) handle;
403 args[4] = (unsigned long) buffer;
404 args[5] = bufsize;
405 args[6] = (unsigned long) -1;
406
407 p1275_cmd_direct(args);
408
409 return (int) args[6];
312} 410}
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c
index c8a44f5e0584..40af43ebd92d 100644
--- a/drivers/base/firmware_class.c
+++ b/drivers/base/firmware_class.c
@@ -568,7 +568,7 @@ static int _request_firmware(const struct firmware **firmware_p,
568out: 568out:
569 if (retval) { 569 if (retval) {
570 release_firmware(firmware); 570 release_firmware(firmware);
571 firmware_p = NULL; 571 *firmware_p = NULL;
572 } 572 }
573 573
574 return retval; 574 return retval;
diff --git a/drivers/char/ip2/ip2main.c b/drivers/char/ip2/ip2main.c
index 07f3ea38b582..d4b71e8d0d23 100644
--- a/drivers/char/ip2/ip2main.c
+++ b/drivers/char/ip2/ip2main.c
@@ -1650,7 +1650,7 @@ ip2_close( PTTY tty, struct file *pFile )
1650 /* disable DSS reporting */ 1650 /* disable DSS reporting */
1651 i2QueueCommands(PTYPE_INLINE, pCh, 100, 4, 1651 i2QueueCommands(PTYPE_INLINE, pCh, 100, 4,
1652 CMD_DCD_NREP, CMD_CTS_NREP, CMD_DSR_NREP, CMD_RI_NREP); 1652 CMD_DCD_NREP, CMD_CTS_NREP, CMD_DSR_NREP, CMD_RI_NREP);
1653 if ( !tty || (tty->termios->c_cflag & HUPCL) ) { 1653 if (tty->termios->c_cflag & HUPCL) {
1654 i2QueueCommands(PTYPE_INLINE, pCh, 100, 2, CMD_RTSDN, CMD_DTRDN); 1654 i2QueueCommands(PTYPE_INLINE, pCh, 100, 2, CMD_RTSDN, CMD_DTRDN);
1655 pCh->dataSetOut &= ~(I2_DTR | I2_RTS); 1655 pCh->dataSetOut &= ~(I2_DTR | I2_RTS);
1656 i2QueueCommands( PTYPE_INLINE, pCh, 100, 1, CMD_PAUSE(25)); 1656 i2QueueCommands( PTYPE_INLINE, pCh, 100, 1, CMD_PAUSE(25));
@@ -2930,6 +2930,8 @@ ip2_ipl_ioctl (struct file *pFile, UINT cmd, ULONG arg )
2930 if ( pCh ) 2930 if ( pCh )
2931 { 2931 {
2932 rc = copy_to_user(argp, pCh, sizeof(i2ChanStr)); 2932 rc = copy_to_user(argp, pCh, sizeof(i2ChanStr));
2933 if (rc)
2934 rc = -EFAULT;
2933 } else { 2935 } else {
2934 rc = -ENODEV; 2936 rc = -ENODEV;
2935 } 2937 }
diff --git a/drivers/char/rocket.c b/drivers/char/rocket.c
index 79c3bc69165a..7c79d243acc9 100644
--- a/drivers/char/rocket.c
+++ b/drivers/char/rocket.c
@@ -1244,6 +1244,7 @@ static int set_config(struct tty_struct *tty, struct r_port *info,
1244 } 1244 }
1245 info->flags = ((info->flags & ~ROCKET_USR_MASK) | (new_serial.flags & ROCKET_USR_MASK)); 1245 info->flags = ((info->flags & ~ROCKET_USR_MASK) | (new_serial.flags & ROCKET_USR_MASK));
1246 configure_r_port(tty, info, NULL); 1246 configure_r_port(tty, info, NULL);
1247 mutex_unlock(&info->port.mutex);
1247 return 0; 1248 return 0;
1248 } 1249 }
1249 1250
diff --git a/drivers/char/synclink_gt.c b/drivers/char/synclink_gt.c
index fef80cfcab5c..e63b830c86cc 100644
--- a/drivers/char/synclink_gt.c
+++ b/drivers/char/synclink_gt.c
@@ -691,8 +691,10 @@ static int open(struct tty_struct *tty, struct file *filp)
691 if (info->port.count == 1) { 691 if (info->port.count == 1) {
692 /* 1st open on this device, init hardware */ 692 /* 1st open on this device, init hardware */
693 retval = startup(info); 693 retval = startup(info);
694 if (retval < 0) 694 if (retval < 0) {
695 mutex_unlock(&info->port.mutex);
695 goto cleanup; 696 goto cleanup;
697 }
696 } 698 }
697 mutex_unlock(&info->port.mutex); 699 mutex_unlock(&info->port.mutex);
698 retval = block_til_ready(tty, filp, info); 700 retval = block_til_ready(tty, filp, info);
diff --git a/drivers/macintosh/via-pmu.c b/drivers/macintosh/via-pmu.c
index 35bc2737412f..2d17e76066bd 100644
--- a/drivers/macintosh/via-pmu.c
+++ b/drivers/macintosh/via-pmu.c
@@ -45,6 +45,7 @@
45#include <linux/syscalls.h> 45#include <linux/syscalls.h>
46#include <linux/suspend.h> 46#include <linux/suspend.h>
47#include <linux/cpu.h> 47#include <linux/cpu.h>
48#include <linux/compat.h>
48#include <asm/prom.h> 49#include <asm/prom.h>
49#include <asm/machdep.h> 50#include <asm/machdep.h>
50#include <asm/io.h> 51#include <asm/io.h>
@@ -2349,11 +2350,52 @@ static long pmu_unlocked_ioctl(struct file *filp,
2349 return ret; 2350 return ret;
2350} 2351}
2351 2352
2353#ifdef CONFIG_COMPAT
2354#define PMU_IOC_GET_BACKLIGHT32 _IOR('B', 1, compat_size_t)
2355#define PMU_IOC_SET_BACKLIGHT32 _IOW('B', 2, compat_size_t)
2356#define PMU_IOC_GET_MODEL32 _IOR('B', 3, compat_size_t)
2357#define PMU_IOC_HAS_ADB32 _IOR('B', 4, compat_size_t)
2358#define PMU_IOC_CAN_SLEEP32 _IOR('B', 5, compat_size_t)
2359#define PMU_IOC_GRAB_BACKLIGHT32 _IOR('B', 6, compat_size_t)
2360
2361static long compat_pmu_ioctl (struct file *filp, u_int cmd, u_long arg)
2362{
2363 switch (cmd) {
2364 case PMU_IOC_SLEEP:
2365 break;
2366 case PMU_IOC_GET_BACKLIGHT32:
2367 cmd = PMU_IOC_GET_BACKLIGHT;
2368 break;
2369 case PMU_IOC_SET_BACKLIGHT32:
2370 cmd = PMU_IOC_SET_BACKLIGHT;
2371 break;
2372 case PMU_IOC_GET_MODEL32:
2373 cmd = PMU_IOC_GET_MODEL;
2374 break;
2375 case PMU_IOC_HAS_ADB32:
2376 cmd = PMU_IOC_HAS_ADB;
2377 break;
2378 case PMU_IOC_CAN_SLEEP32:
2379 cmd = PMU_IOC_CAN_SLEEP;
2380 break;
2381 case PMU_IOC_GRAB_BACKLIGHT32:
2382 cmd = PMU_IOC_GRAB_BACKLIGHT;
2383 break;
2384 default:
2385 return -ENOIOCTLCMD;
2386 }
2387 return pmu_unlocked_ioctl(filp, cmd, (unsigned long)compat_ptr(arg));
2388}
2389#endif
2390
2352static const struct file_operations pmu_device_fops = { 2391static const struct file_operations pmu_device_fops = {
2353 .read = pmu_read, 2392 .read = pmu_read,
2354 .write = pmu_write, 2393 .write = pmu_write,
2355 .poll = pmu_fpoll, 2394 .poll = pmu_fpoll,
2356 .unlocked_ioctl = pmu_unlocked_ioctl, 2395 .unlocked_ioctl = pmu_unlocked_ioctl,
2396#ifdef CONFIG_COMPAT
2397 .compat_ioctl = compat_pmu_ioctl,
2398#endif
2357 .open = pmu_open, 2399 .open = pmu_open,
2358 .release = pmu_release, 2400 .release = pmu_release,
2359}; 2401};
diff --git a/drivers/media/dvb/mantis/Kconfig b/drivers/media/dvb/mantis/Kconfig
index decdeda840d0..fd0830ed10d8 100644
--- a/drivers/media/dvb/mantis/Kconfig
+++ b/drivers/media/dvb/mantis/Kconfig
@@ -1,6 +1,6 @@
1config MANTIS_CORE 1config MANTIS_CORE
2 tristate "Mantis/Hopper PCI bridge based devices" 2 tristate "Mantis/Hopper PCI bridge based devices"
3 depends on PCI && I2C && INPUT 3 depends on PCI && I2C && INPUT && IR_CORE
4 4
5 help 5 help
6 Support for PCI cards based on the Mantis and Hopper PCi bridge. 6 Support for PCI cards based on the Mantis and Hopper PCi bridge.
diff --git a/drivers/platform/x86/intel_rar_register.c b/drivers/platform/x86/intel_rar_register.c
index 73f8e6d72669..2b11a33325e6 100644
--- a/drivers/platform/x86/intel_rar_register.c
+++ b/drivers/platform/x86/intel_rar_register.c
@@ -145,7 +145,7 @@ static void free_rar_device(struct rar_device *rar)
145 */ 145 */
146static struct rar_device *_rar_to_device(int rar, int *off) 146static struct rar_device *_rar_to_device(int rar, int *off)
147{ 147{
148 if (rar >= 0 && rar <= 3) { 148 if (rar >= 0 && rar < MRST_NUM_RAR) {
149 *off = rar; 149 *off = rar;
150 return &my_rar_device; 150 return &my_rar_device;
151 } 151 }
diff --git a/drivers/platform/x86/intel_scu_ipc.c b/drivers/platform/x86/intel_scu_ipc.c
index 943f9084dcb1..6abe18e638e9 100644
--- a/drivers/platform/x86/intel_scu_ipc.c
+++ b/drivers/platform/x86/intel_scu_ipc.c
@@ -487,7 +487,7 @@ int intel_scu_ipc_i2c_cntrl(u32 addr, u32 *data)
487 mdelay(1); 487 mdelay(1);
488 *data = readl(ipcdev.i2c_base + I2C_DATA_ADDR); 488 *data = readl(ipcdev.i2c_base + I2C_DATA_ADDR);
489 } else if (cmd == IPC_I2C_WRITE) { 489 } else if (cmd == IPC_I2C_WRITE) {
490 writel(addr, ipcdev.i2c_base + I2C_DATA_ADDR); 490 writel(*data, ipcdev.i2c_base + I2C_DATA_ADDR);
491 mdelay(1); 491 mdelay(1);
492 writel(addr, ipcdev.i2c_base + IPC_I2C_CNTRL_ADDR); 492 writel(addr, ipcdev.i2c_base + IPC_I2C_CNTRL_ADDR);
493 } else { 493 } else {
diff --git a/drivers/serial/68328serial.c b/drivers/serial/68328serial.c
index 7356a56ac458..be0ebce36e54 100644
--- a/drivers/serial/68328serial.c
+++ b/drivers/serial/68328serial.c
@@ -869,7 +869,9 @@ static int get_serial_info(struct m68k_serial * info,
869 tmp.close_delay = info->close_delay; 869 tmp.close_delay = info->close_delay;
870 tmp.closing_wait = info->closing_wait; 870 tmp.closing_wait = info->closing_wait;
871 tmp.custom_divisor = info->custom_divisor; 871 tmp.custom_divisor = info->custom_divisor;
872 copy_to_user(retinfo,&tmp,sizeof(*retinfo)); 872 if (copy_to_user(retinfo, &tmp, sizeof(*retinfo)))
873 return -EFAULT;
874
873 return 0; 875 return 0;
874} 876}
875 877
@@ -882,7 +884,8 @@ static int set_serial_info(struct m68k_serial * info,
882 884
883 if (!new_info) 885 if (!new_info)
884 return -EFAULT; 886 return -EFAULT;
885 copy_from_user(&new_serial,new_info,sizeof(new_serial)); 887 if (copy_from_user(&new_serial, new_info, sizeof(new_serial)))
888 return -EFAULT;
886 old_info = *info; 889 old_info = *info;
887 890
888 if (!capable(CAP_SYS_ADMIN)) { 891 if (!capable(CAP_SYS_ADMIN)) {
@@ -943,8 +946,7 @@ static int get_lsr_info(struct m68k_serial * info, unsigned int *value)
943 status = 0; 946 status = 0;
944#endif 947#endif
945 local_irq_restore(flags); 948 local_irq_restore(flags);
946 put_user(status,value); 949 return put_user(status, value);
947 return 0;
948} 950}
949 951
950/* 952/*
@@ -999,27 +1001,18 @@ static int rs_ioctl(struct tty_struct *tty, struct file * file,
999 send_break(info, arg ? arg*(100) : 250); 1001 send_break(info, arg ? arg*(100) : 250);
1000 return 0; 1002 return 0;
1001 case TIOCGSERIAL: 1003 case TIOCGSERIAL:
1002 if (access_ok(VERIFY_WRITE, (void *) arg, 1004 return get_serial_info(info,
1003 sizeof(struct serial_struct))) 1005 (struct serial_struct *) arg);
1004 return get_serial_info(info,
1005 (struct serial_struct *) arg);
1006 return -EFAULT;
1007 case TIOCSSERIAL: 1006 case TIOCSSERIAL:
1008 return set_serial_info(info, 1007 return set_serial_info(info,
1009 (struct serial_struct *) arg); 1008 (struct serial_struct *) arg);
1010 case TIOCSERGETLSR: /* Get line status register */ 1009 case TIOCSERGETLSR: /* Get line status register */
1011 if (access_ok(VERIFY_WRITE, (void *) arg, 1010 return get_lsr_info(info, (unsigned int *) arg);
1012 sizeof(unsigned int)))
1013 return get_lsr_info(info, (unsigned int *) arg);
1014 return -EFAULT;
1015 case TIOCSERGSTRUCT: 1011 case TIOCSERGSTRUCT:
1016 if (!access_ok(VERIFY_WRITE, (void *) arg, 1012 if (copy_to_user((struct m68k_serial *) arg,
1017 sizeof(struct m68k_serial))) 1013 info, sizeof(struct m68k_serial)))
1018 return -EFAULT; 1014 return -EFAULT;
1019 copy_to_user((struct m68k_serial *) arg,
1020 info, sizeof(struct m68k_serial));
1021 return 0; 1015 return 0;
1022
1023 default: 1016 default:
1024 return -ENOIOCTLCMD; 1017 return -ENOIOCTLCMD;
1025 } 1018 }
diff --git a/drivers/serial/8250_early.c b/drivers/serial/8250_early.c
index b745792ec25a..eaafb98debed 100644
--- a/drivers/serial/8250_early.c
+++ b/drivers/serial/8250_early.c
@@ -203,13 +203,13 @@ static int __init parse_options(struct early_serial8250_device *device,
203 203
204 if (mmio || mmio32) 204 if (mmio || mmio32)
205 printk(KERN_INFO 205 printk(KERN_INFO
206 "Early serial console at MMIO%s 0x%llu (options '%s')\n", 206 "Early serial console at MMIO%s 0x%llx (options '%s')\n",
207 mmio32 ? "32" : "", 207 mmio32 ? "32" : "",
208 (unsigned long long)port->mapbase, 208 (unsigned long long)port->mapbase,
209 device->options); 209 device->options);
210 else 210 else
211 printk(KERN_INFO 211 printk(KERN_INFO
212 "Early serial console at I/O port 0x%lu (options '%s')\n", 212 "Early serial console at I/O port 0x%lx (options '%s')\n",
213 port->iobase, 213 port->iobase,
214 device->options); 214 device->options);
215 215
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig
index 4a7a7a7f11b6..335311a98fdc 100644
--- a/drivers/staging/Kconfig
+++ b/drivers/staging/Kconfig
@@ -113,8 +113,6 @@ source "drivers/staging/vme/Kconfig"
113 113
114source "drivers/staging/memrar/Kconfig" 114source "drivers/staging/memrar/Kconfig"
115 115
116source "drivers/staging/sep/Kconfig"
117
118source "drivers/staging/iio/Kconfig" 116source "drivers/staging/iio/Kconfig"
119 117
120source "drivers/staging/zram/Kconfig" 118source "drivers/staging/zram/Kconfig"
diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile
index ca5c03eb3ce3..e3f1e1b6095e 100644
--- a/drivers/staging/Makefile
+++ b/drivers/staging/Makefile
@@ -38,7 +38,6 @@ obj-$(CONFIG_FB_UDL) += udlfb/
38obj-$(CONFIG_HYPERV) += hv/ 38obj-$(CONFIG_HYPERV) += hv/
39obj-$(CONFIG_VME_BUS) += vme/ 39obj-$(CONFIG_VME_BUS) += vme/
40obj-$(CONFIG_MRST_RAR_HANDLER) += memrar/ 40obj-$(CONFIG_MRST_RAR_HANDLER) += memrar/
41obj-$(CONFIG_DX_SEP) += sep/
42obj-$(CONFIG_IIO) += iio/ 41obj-$(CONFIG_IIO) += iio/
43obj-$(CONFIG_ZRAM) += zram/ 42obj-$(CONFIG_ZRAM) += zram/
44obj-$(CONFIG_WLAGS49_H2) += wlags49_h2/ 43obj-$(CONFIG_WLAGS49_H2) += wlags49_h2/
diff --git a/drivers/staging/batman-adv/bat_sysfs.c b/drivers/staging/batman-adv/bat_sysfs.c
index b4a8d5eb64fa..05ca15a6c9f8 100644
--- a/drivers/staging/batman-adv/bat_sysfs.c
+++ b/drivers/staging/batman-adv/bat_sysfs.c
@@ -267,6 +267,10 @@ static ssize_t store_log_level(struct kobject *kobj, struct attribute *attr,
267 if (atomic_read(&bat_priv->log_level) == log_level_tmp) 267 if (atomic_read(&bat_priv->log_level) == log_level_tmp)
268 return count; 268 return count;
269 269
270 bat_info(net_dev, "Changing log level from: %i to: %li\n",
271 atomic_read(&bat_priv->log_level),
272 log_level_tmp);
273
270 atomic_set(&bat_priv->log_level, (unsigned)log_level_tmp); 274 atomic_set(&bat_priv->log_level, (unsigned)log_level_tmp);
271 return count; 275 return count;
272} 276}
diff --git a/drivers/staging/batman-adv/hard-interface.c b/drivers/staging/batman-adv/hard-interface.c
index 92c216a56885..baa8b05b9e8d 100644
--- a/drivers/staging/batman-adv/hard-interface.c
+++ b/drivers/staging/batman-adv/hard-interface.c
@@ -129,6 +129,9 @@ static bool hardif_is_iface_up(struct batman_if *batman_if)
129 129
130static void update_mac_addresses(struct batman_if *batman_if) 130static void update_mac_addresses(struct batman_if *batman_if)
131{ 131{
132 if (!batman_if || !batman_if->packet_buff)
133 return;
134
132 addr_to_string(batman_if->addr_str, batman_if->net_dev->dev_addr); 135 addr_to_string(batman_if->addr_str, batman_if->net_dev->dev_addr);
133 136
134 memcpy(((struct batman_packet *)(batman_if->packet_buff))->orig, 137 memcpy(((struct batman_packet *)(batman_if->packet_buff))->orig,
@@ -194,8 +197,6 @@ static void hardif_activate_interface(struct net_device *net_dev,
194 if (batman_if->if_status != IF_INACTIVE) 197 if (batman_if->if_status != IF_INACTIVE)
195 return; 198 return;
196 199
197 dev_hold(batman_if->net_dev);
198
199 update_mac_addresses(batman_if); 200 update_mac_addresses(batman_if);
200 batman_if->if_status = IF_TO_BE_ACTIVATED; 201 batman_if->if_status = IF_TO_BE_ACTIVATED;
201 202
@@ -222,8 +223,6 @@ static void hardif_deactivate_interface(struct net_device *net_dev,
222 (batman_if->if_status != IF_TO_BE_ACTIVATED)) 223 (batman_if->if_status != IF_TO_BE_ACTIVATED))
223 return; 224 return;
224 225
225 dev_put(batman_if->net_dev);
226
227 batman_if->if_status = IF_INACTIVE; 226 batman_if->if_status = IF_INACTIVE;
228 227
229 bat_info(net_dev, "Interface deactivated: %s\n", batman_if->dev); 228 bat_info(net_dev, "Interface deactivated: %s\n", batman_if->dev);
@@ -318,11 +317,13 @@ static struct batman_if *hardif_add_interface(struct net_device *net_dev)
318 if (ret != 1) 317 if (ret != 1)
319 goto out; 318 goto out;
320 319
320 dev_hold(net_dev);
321
321 batman_if = kmalloc(sizeof(struct batman_if), GFP_ATOMIC); 322 batman_if = kmalloc(sizeof(struct batman_if), GFP_ATOMIC);
322 if (!batman_if) { 323 if (!batman_if) {
323 pr_err("Can't add interface (%s): out of memory\n", 324 pr_err("Can't add interface (%s): out of memory\n",
324 net_dev->name); 325 net_dev->name);
325 goto out; 326 goto release_dev;
326 } 327 }
327 328
328 batman_if->dev = kstrdup(net_dev->name, GFP_ATOMIC); 329 batman_if->dev = kstrdup(net_dev->name, GFP_ATOMIC);
@@ -336,6 +337,7 @@ static struct batman_if *hardif_add_interface(struct net_device *net_dev)
336 batman_if->if_num = -1; 337 batman_if->if_num = -1;
337 batman_if->net_dev = net_dev; 338 batman_if->net_dev = net_dev;
338 batman_if->if_status = IF_NOT_IN_USE; 339 batman_if->if_status = IF_NOT_IN_USE;
340 batman_if->packet_buff = NULL;
339 INIT_LIST_HEAD(&batman_if->list); 341 INIT_LIST_HEAD(&batman_if->list);
340 342
341 check_known_mac_addr(batman_if->net_dev->dev_addr); 343 check_known_mac_addr(batman_if->net_dev->dev_addr);
@@ -346,6 +348,8 @@ free_dev:
346 kfree(batman_if->dev); 348 kfree(batman_if->dev);
347free_if: 349free_if:
348 kfree(batman_if); 350 kfree(batman_if);
351release_dev:
352 dev_put(net_dev);
349out: 353out:
350 return NULL; 354 return NULL;
351} 355}
@@ -374,6 +378,7 @@ static void hardif_remove_interface(struct batman_if *batman_if)
374 batman_if->if_status = IF_TO_BE_REMOVED; 378 batman_if->if_status = IF_TO_BE_REMOVED;
375 list_del_rcu(&batman_if->list); 379 list_del_rcu(&batman_if->list);
376 sysfs_del_hardif(&batman_if->hardif_obj); 380 sysfs_del_hardif(&batman_if->hardif_obj);
381 dev_put(batman_if->net_dev);
377 call_rcu(&batman_if->rcu, hardif_free_interface); 382 call_rcu(&batman_if->rcu, hardif_free_interface);
378} 383}
379 384
@@ -393,15 +398,13 @@ static int hard_if_event(struct notifier_block *this,
393 /* FIXME: each batman_if will be attached to a softif */ 398 /* FIXME: each batman_if will be attached to a softif */
394 struct bat_priv *bat_priv = netdev_priv(soft_device); 399 struct bat_priv *bat_priv = netdev_priv(soft_device);
395 400
396 if (!batman_if) 401 if (!batman_if && event == NETDEV_REGISTER)
397 batman_if = hardif_add_interface(net_dev); 402 batman_if = hardif_add_interface(net_dev);
398 403
399 if (!batman_if) 404 if (!batman_if)
400 goto out; 405 goto out;
401 406
402 switch (event) { 407 switch (event) {
403 case NETDEV_REGISTER:
404 break;
405 case NETDEV_UP: 408 case NETDEV_UP:
406 hardif_activate_interface(soft_device, bat_priv, batman_if); 409 hardif_activate_interface(soft_device, bat_priv, batman_if);
407 break; 410 break;
@@ -442,8 +445,6 @@ int batman_skb_recv(struct sk_buff *skb, struct net_device *dev,
442 struct bat_priv *bat_priv = netdev_priv(soft_device); 445 struct bat_priv *bat_priv = netdev_priv(soft_device);
443 struct batman_packet *batman_packet; 446 struct batman_packet *batman_packet;
444 struct batman_if *batman_if; 447 struct batman_if *batman_if;
445 struct net_device_stats *stats;
446 struct rtnl_link_stats64 temp;
447 int ret; 448 int ret;
448 449
449 skb = skb_share_check(skb, GFP_ATOMIC); 450 skb = skb_share_check(skb, GFP_ATOMIC);
@@ -479,12 +480,6 @@ int batman_skb_recv(struct sk_buff *skb, struct net_device *dev,
479 if (batman_if->if_status != IF_ACTIVE) 480 if (batman_if->if_status != IF_ACTIVE)
480 goto err_free; 481 goto err_free;
481 482
482 stats = (struct net_device_stats *)dev_get_stats(skb->dev, &temp);
483 if (stats) {
484 stats->rx_packets++;
485 stats->rx_bytes += skb->len;
486 }
487
488 batman_packet = (struct batman_packet *)skb->data; 483 batman_packet = (struct batman_packet *)skb->data;
489 484
490 if (batman_packet->version != COMPAT_VERSION) { 485 if (batman_packet->version != COMPAT_VERSION) {
diff --git a/drivers/staging/batman-adv/icmp_socket.c b/drivers/staging/batman-adv/icmp_socket.c
index fc3d32c12729..3ae7dd2d2d4d 100644
--- a/drivers/staging/batman-adv/icmp_socket.c
+++ b/drivers/staging/batman-adv/icmp_socket.c
@@ -67,6 +67,7 @@ static int bat_socket_open(struct inode *inode, struct file *file)
67 INIT_LIST_HEAD(&socket_client->queue_list); 67 INIT_LIST_HEAD(&socket_client->queue_list);
68 socket_client->queue_len = 0; 68 socket_client->queue_len = 0;
69 socket_client->index = i; 69 socket_client->index = i;
70 socket_client->bat_priv = inode->i_private;
70 spin_lock_init(&socket_client->lock); 71 spin_lock_init(&socket_client->lock);
71 init_waitqueue_head(&socket_client->queue_wait); 72 init_waitqueue_head(&socket_client->queue_wait);
72 73
@@ -151,9 +152,8 @@ static ssize_t bat_socket_read(struct file *file, char __user *buf,
151static ssize_t bat_socket_write(struct file *file, const char __user *buff, 152static ssize_t bat_socket_write(struct file *file, const char __user *buff,
152 size_t len, loff_t *off) 153 size_t len, loff_t *off)
153{ 154{
154 /* FIXME: each orig_node->batman_if will be attached to a softif */
155 struct bat_priv *bat_priv = netdev_priv(soft_device);
156 struct socket_client *socket_client = file->private_data; 155 struct socket_client *socket_client = file->private_data;
156 struct bat_priv *bat_priv = socket_client->bat_priv;
157 struct icmp_packet_rr icmp_packet; 157 struct icmp_packet_rr icmp_packet;
158 struct orig_node *orig_node; 158 struct orig_node *orig_node;
159 struct batman_if *batman_if; 159 struct batman_if *batman_if;
@@ -168,6 +168,9 @@ static ssize_t bat_socket_write(struct file *file, const char __user *buff,
168 return -EINVAL; 168 return -EINVAL;
169 } 169 }
170 170
171 if (!bat_priv->primary_if)
172 return -EFAULT;
173
171 if (len >= sizeof(struct icmp_packet_rr)) 174 if (len >= sizeof(struct icmp_packet_rr))
172 packet_len = sizeof(struct icmp_packet_rr); 175 packet_len = sizeof(struct icmp_packet_rr);
173 176
@@ -223,7 +226,8 @@ static ssize_t bat_socket_write(struct file *file, const char __user *buff,
223 if (batman_if->if_status != IF_ACTIVE) 226 if (batman_if->if_status != IF_ACTIVE)
224 goto dst_unreach; 227 goto dst_unreach;
225 228
226 memcpy(icmp_packet.orig, batman_if->net_dev->dev_addr, ETH_ALEN); 229 memcpy(icmp_packet.orig,
230 bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN);
227 231
228 if (packet_len == sizeof(struct icmp_packet_rr)) 232 if (packet_len == sizeof(struct icmp_packet_rr))
229 memcpy(icmp_packet.rr, batman_if->net_dev->dev_addr, ETH_ALEN); 233 memcpy(icmp_packet.rr, batman_if->net_dev->dev_addr, ETH_ALEN);
@@ -271,7 +275,7 @@ int bat_socket_setup(struct bat_priv *bat_priv)
271 goto err; 275 goto err;
272 276
273 d = debugfs_create_file(ICMP_SOCKET, S_IFREG | S_IWUSR | S_IRUSR, 277 d = debugfs_create_file(ICMP_SOCKET, S_IFREG | S_IWUSR | S_IRUSR,
274 bat_priv->debug_dir, NULL, &fops); 278 bat_priv->debug_dir, bat_priv, &fops);
275 if (d) 279 if (d)
276 goto err; 280 goto err;
277 281
diff --git a/drivers/staging/batman-adv/main.c b/drivers/staging/batman-adv/main.c
index 2686019fe4e1..ef7c20ae7979 100644
--- a/drivers/staging/batman-adv/main.c
+++ b/drivers/staging/batman-adv/main.c
@@ -250,10 +250,13 @@ int choose_orig(void *data, int32_t size)
250int is_my_mac(uint8_t *addr) 250int is_my_mac(uint8_t *addr)
251{ 251{
252 struct batman_if *batman_if; 252 struct batman_if *batman_if;
253
253 rcu_read_lock(); 254 rcu_read_lock();
254 list_for_each_entry_rcu(batman_if, &if_list, list) { 255 list_for_each_entry_rcu(batman_if, &if_list, list) {
255 if ((batman_if->net_dev) && 256 if (batman_if->if_status != IF_ACTIVE)
256 (compare_orig(batman_if->net_dev->dev_addr, addr))) { 257 continue;
258
259 if (compare_orig(batman_if->net_dev->dev_addr, addr)) {
257 rcu_read_unlock(); 260 rcu_read_unlock();
258 return 1; 261 return 1;
259 } 262 }
diff --git a/drivers/staging/batman-adv/originator.c b/drivers/staging/batman-adv/originator.c
index 28bb627ffa13..de5a8c1a8104 100644
--- a/drivers/staging/batman-adv/originator.c
+++ b/drivers/staging/batman-adv/originator.c
@@ -391,11 +391,12 @@ static int orig_node_add_if(struct orig_node *orig_node, int max_if_num)
391int orig_hash_add_if(struct batman_if *batman_if, int max_if_num) 391int orig_hash_add_if(struct batman_if *batman_if, int max_if_num)
392{ 392{
393 struct orig_node *orig_node; 393 struct orig_node *orig_node;
394 unsigned long flags;
394 HASHIT(hashit); 395 HASHIT(hashit);
395 396
396 /* resize all orig nodes because orig_node->bcast_own(_sum) depend on 397 /* resize all orig nodes because orig_node->bcast_own(_sum) depend on
397 * if_num */ 398 * if_num */
398 spin_lock(&orig_hash_lock); 399 spin_lock_irqsave(&orig_hash_lock, flags);
399 400
400 while (hash_iterate(orig_hash, &hashit)) { 401 while (hash_iterate(orig_hash, &hashit)) {
401 orig_node = hashit.bucket->data; 402 orig_node = hashit.bucket->data;
@@ -404,11 +405,11 @@ int orig_hash_add_if(struct batman_if *batman_if, int max_if_num)
404 goto err; 405 goto err;
405 } 406 }
406 407
407 spin_unlock(&orig_hash_lock); 408 spin_unlock_irqrestore(&orig_hash_lock, flags);
408 return 0; 409 return 0;
409 410
410err: 411err:
411 spin_unlock(&orig_hash_lock); 412 spin_unlock_irqrestore(&orig_hash_lock, flags);
412 return -ENOMEM; 413 return -ENOMEM;
413} 414}
414 415
@@ -468,12 +469,13 @@ int orig_hash_del_if(struct batman_if *batman_if, int max_if_num)
468{ 469{
469 struct batman_if *batman_if_tmp; 470 struct batman_if *batman_if_tmp;
470 struct orig_node *orig_node; 471 struct orig_node *orig_node;
472 unsigned long flags;
471 HASHIT(hashit); 473 HASHIT(hashit);
472 int ret; 474 int ret;
473 475
474 /* resize all orig nodes because orig_node->bcast_own(_sum) depend on 476 /* resize all orig nodes because orig_node->bcast_own(_sum) depend on
475 * if_num */ 477 * if_num */
476 spin_lock(&orig_hash_lock); 478 spin_lock_irqsave(&orig_hash_lock, flags);
477 479
478 while (hash_iterate(orig_hash, &hashit)) { 480 while (hash_iterate(orig_hash, &hashit)) {
479 orig_node = hashit.bucket->data; 481 orig_node = hashit.bucket->data;
@@ -500,10 +502,10 @@ int orig_hash_del_if(struct batman_if *batman_if, int max_if_num)
500 rcu_read_unlock(); 502 rcu_read_unlock();
501 503
502 batman_if->if_num = -1; 504 batman_if->if_num = -1;
503 spin_unlock(&orig_hash_lock); 505 spin_unlock_irqrestore(&orig_hash_lock, flags);
504 return 0; 506 return 0;
505 507
506err: 508err:
507 spin_unlock(&orig_hash_lock); 509 spin_unlock_irqrestore(&orig_hash_lock, flags);
508 return -ENOMEM; 510 return -ENOMEM;
509} 511}
diff --git a/drivers/staging/batman-adv/routing.c b/drivers/staging/batman-adv/routing.c
index 066cc9149bf1..032195e6de94 100644
--- a/drivers/staging/batman-adv/routing.c
+++ b/drivers/staging/batman-adv/routing.c
@@ -783,6 +783,8 @@ int recv_bat_packet(struct sk_buff *skb,
783 783
784static int recv_my_icmp_packet(struct sk_buff *skb, size_t icmp_len) 784static int recv_my_icmp_packet(struct sk_buff *skb, size_t icmp_len)
785{ 785{
786 /* FIXME: each batman_if will be attached to a softif */
787 struct bat_priv *bat_priv = netdev_priv(soft_device);
786 struct orig_node *orig_node; 788 struct orig_node *orig_node;
787 struct icmp_packet_rr *icmp_packet; 789 struct icmp_packet_rr *icmp_packet;
788 struct ethhdr *ethhdr; 790 struct ethhdr *ethhdr;
@@ -801,6 +803,9 @@ static int recv_my_icmp_packet(struct sk_buff *skb, size_t icmp_len)
801 return NET_RX_DROP; 803 return NET_RX_DROP;
802 } 804 }
803 805
806 if (!bat_priv->primary_if)
807 return NET_RX_DROP;
808
804 /* answer echo request (ping) */ 809 /* answer echo request (ping) */
805 /* get routing information */ 810 /* get routing information */
806 spin_lock_irqsave(&orig_hash_lock, flags); 811 spin_lock_irqsave(&orig_hash_lock, flags);
@@ -830,7 +835,8 @@ static int recv_my_icmp_packet(struct sk_buff *skb, size_t icmp_len)
830 } 835 }
831 836
832 memcpy(icmp_packet->dst, icmp_packet->orig, ETH_ALEN); 837 memcpy(icmp_packet->dst, icmp_packet->orig, ETH_ALEN);
833 memcpy(icmp_packet->orig, ethhdr->h_dest, ETH_ALEN); 838 memcpy(icmp_packet->orig,
839 bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN);
834 icmp_packet->msg_type = ECHO_REPLY; 840 icmp_packet->msg_type = ECHO_REPLY;
835 icmp_packet->ttl = TTL; 841 icmp_packet->ttl = TTL;
836 842
@@ -845,6 +851,8 @@ static int recv_my_icmp_packet(struct sk_buff *skb, size_t icmp_len)
845 851
846static int recv_icmp_ttl_exceeded(struct sk_buff *skb, size_t icmp_len) 852static int recv_icmp_ttl_exceeded(struct sk_buff *skb, size_t icmp_len)
847{ 853{
854 /* FIXME: each batman_if will be attached to a softif */
855 struct bat_priv *bat_priv = netdev_priv(soft_device);
848 struct orig_node *orig_node; 856 struct orig_node *orig_node;
849 struct icmp_packet *icmp_packet; 857 struct icmp_packet *icmp_packet;
850 struct ethhdr *ethhdr; 858 struct ethhdr *ethhdr;
@@ -865,6 +873,9 @@ static int recv_icmp_ttl_exceeded(struct sk_buff *skb, size_t icmp_len)
865 return NET_RX_DROP; 873 return NET_RX_DROP;
866 } 874 }
867 875
876 if (!bat_priv->primary_if)
877 return NET_RX_DROP;
878
868 /* get routing information */ 879 /* get routing information */
869 spin_lock_irqsave(&orig_hash_lock, flags); 880 spin_lock_irqsave(&orig_hash_lock, flags);
870 orig_node = ((struct orig_node *) 881 orig_node = ((struct orig_node *)
@@ -892,7 +903,8 @@ static int recv_icmp_ttl_exceeded(struct sk_buff *skb, size_t icmp_len)
892 } 903 }
893 904
894 memcpy(icmp_packet->dst, icmp_packet->orig, ETH_ALEN); 905 memcpy(icmp_packet->dst, icmp_packet->orig, ETH_ALEN);
895 memcpy(icmp_packet->orig, ethhdr->h_dest, ETH_ALEN); 906 memcpy(icmp_packet->orig,
907 bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN);
896 icmp_packet->msg_type = TTL_EXCEEDED; 908 icmp_packet->msg_type = TTL_EXCEEDED;
897 icmp_packet->ttl = TTL; 909 icmp_packet->ttl = TTL;
898 910
diff --git a/drivers/staging/batman-adv/types.h b/drivers/staging/batman-adv/types.h
index 21d0717afb09..9aa9d369c752 100644
--- a/drivers/staging/batman-adv/types.h
+++ b/drivers/staging/batman-adv/types.h
@@ -126,6 +126,7 @@ struct socket_client {
126 unsigned char index; 126 unsigned char index;
127 spinlock_t lock; 127 spinlock_t lock;
128 wait_queue_head_t queue_wait; 128 wait_queue_head_t queue_wait;
129 struct bat_priv *bat_priv;
129}; 130};
130 131
131struct socket_packet { 132struct socket_packet {
diff --git a/drivers/staging/sep/Kconfig b/drivers/staging/sep/Kconfig
deleted file mode 100644
index 0a9c39c7f2bd..000000000000
--- a/drivers/staging/sep/Kconfig
+++ /dev/null
@@ -1,10 +0,0 @@
1config DX_SEP
2 tristate "Discretix SEP driver"
3# depends on MRST
4 depends on RAR_REGISTER && PCI
5 default y
6 help
7 Discretix SEP driver
8
9 If unsure say M. The compiled module will be
10 called sep_driver.ko
diff --git a/drivers/staging/sep/Makefile b/drivers/staging/sep/Makefile
deleted file mode 100644
index 628d5f919414..000000000000
--- a/drivers/staging/sep/Makefile
+++ /dev/null
@@ -1,2 +0,0 @@
1obj-$(CONFIG_DX_SEP) := sep_driver.o
2
diff --git a/drivers/staging/sep/TODO b/drivers/staging/sep/TODO
deleted file mode 100644
index ff0e931dab64..000000000000
--- a/drivers/staging/sep/TODO
+++ /dev/null
@@ -1,8 +0,0 @@
1Todo's so far (from Alan Cox)
2- Fix firmware loading
3- Get firmware into firmware git tree
4- Review and tidy each algorithm function
5- Check whether it can be plugged into any of the kernel crypto API
6 interfaces
7- Do something about the magic shared memory interface and replace it
8 with something saner (in Linux terms)
diff --git a/drivers/staging/sep/sep_dev.h b/drivers/staging/sep/sep_dev.h
deleted file mode 100644
index 9200524bb64d..000000000000
--- a/drivers/staging/sep/sep_dev.h
+++ /dev/null
@@ -1,110 +0,0 @@
1#ifndef __SEP_DEV_H__
2#define __SEP_DEV_H__
3
4/*
5 *
6 * sep_dev.h - Security Processor Device Structures
7 *
8 * Copyright(c) 2009 Intel Corporation. All rights reserved.
9 * Copyright(c) 2009 Discretix. All rights reserved.
10 *
11 * This program is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License as published by the Free
13 * Software Foundation; either version 2 of the License, or (at your option)
14 * any later version.
15 *
16 * This program is distributed in the hope that it will be useful, but WITHOUT
17 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
19 * more details.
20 *
21 * You should have received a copy of the GNU General Public License along with
22 * this program; if not, write to the Free Software Foundation, Inc., 59
23 * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24 *
25 * CONTACTS:
26 *
27 * Alan Cox alan@linux.intel.com
28 *
29 */
30
31struct sep_device {
32 /* pointer to pci dev */
33 struct pci_dev *pdev;
34
35 unsigned long in_use;
36
37 /* address of the shared memory allocated during init for SEP driver
38 (coherent alloc) */
39 void *shared_addr;
40 /* the physical address of the shared area */
41 dma_addr_t shared_bus;
42
43 /* restricted access region (coherent alloc) */
44 dma_addr_t rar_bus;
45 void *rar_addr;
46 /* firmware regions: cache is at rar_addr */
47 unsigned long cache_size;
48
49 /* follows the cache */
50 dma_addr_t resident_bus;
51 unsigned long resident_size;
52 void *resident_addr;
53
54 /* start address of the access to the SEP registers from driver */
55 void __iomem *reg_addr;
56 /* transaction counter that coordinates the transactions between SEP and HOST */
57 unsigned long send_ct;
58 /* counter for the messages from sep */
59 unsigned long reply_ct;
60 /* counter for the number of bytes allocated in the pool for the current
61 transaction */
62 unsigned long data_pool_bytes_allocated;
63
64 /* array of pointers to the pages that represent input data for the synchronic
65 DMA action */
66 struct page **in_page_array;
67
68 /* array of pointers to the pages that represent out data for the synchronic
69 DMA action */
70 struct page **out_page_array;
71
72 /* number of pages in the sep_in_page_array */
73 unsigned long in_num_pages;
74
75 /* number of pages in the sep_out_page_array */
76 unsigned long out_num_pages;
77
78 /* global data for every flow */
79 struct sep_flow_context_t flows[SEP_DRIVER_NUM_FLOWS];
80
81 /* pointer to the workqueue that handles the flow done interrupts */
82 struct workqueue_struct *flow_wq;
83
84};
85
86static struct sep_device *sep_dev;
87
88static inline void sep_write_reg(struct sep_device *dev, int reg, u32 value)
89{
90 void __iomem *addr = dev->reg_addr + reg;
91 writel(value, addr);
92}
93
94static inline u32 sep_read_reg(struct sep_device *dev, int reg)
95{
96 void __iomem *addr = dev->reg_addr + reg;
97 return readl(addr);
98}
99
100/* wait for SRAM write complete(indirect write */
101static inline void sep_wait_sram_write(struct sep_device *dev)
102{
103 u32 reg_val;
104 do
105 reg_val = sep_read_reg(dev, HW_SRAM_DATA_READY_REG_ADDR);
106 while (!(reg_val & 1));
107}
108
109
110#endif
diff --git a/drivers/staging/sep/sep_driver.c b/drivers/staging/sep/sep_driver.c
deleted file mode 100644
index ecbde3467b1b..000000000000
--- a/drivers/staging/sep/sep_driver.c
+++ /dev/null
@@ -1,2742 +0,0 @@
1/*
2 *
3 * sep_driver.c - Security Processor Driver main group of functions
4 *
5 * Copyright(c) 2009 Intel Corporation. All rights reserved.
6 * Copyright(c) 2009 Discretix. All rights reserved.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the Free
10 * Software Foundation; either version 2 of the License, or (at your option)
11 * any later version.
12 *
13 * This program is distributed in the hope that it will be useful, but WITHOUT
14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 * more details.
17 *
18 * You should have received a copy of the GNU General Public License along with
19 * this program; if not, write to the Free Software Foundation, Inc., 59
20 * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 *
22 * CONTACTS:
23 *
24 * Mark Allyn mark.a.allyn@intel.com
25 *
26 * CHANGES:
27 *
28 * 2009.06.26 Initial publish
29 *
30 */
31
32#include <linux/init.h>
33#include <linux/module.h>
34#include <linux/fs.h>
35#include <linux/cdev.h>
36#include <linux/kdev_t.h>
37#include <linux/mutex.h>
38#include <linux/sched.h>
39#include <linux/mm.h>
40#include <linux/poll.h>
41#include <linux/wait.h>
42#include <linux/pci.h>
43#include <linux/firmware.h>
44#include <linux/slab.h>
45#include <asm/ioctl.h>
46#include <linux/ioport.h>
47#include <asm/io.h>
48#include <linux/interrupt.h>
49#include <linux/pagemap.h>
50#include <asm/cacheflush.h>
51#include "sep_driver_hw_defs.h"
52#include "sep_driver_config.h"
53#include "sep_driver_api.h"
54#include "sep_dev.h"
55
56#if SEP_DRIVER_ARM_DEBUG_MODE
57
58#define CRYS_SEP_ROM_length 0x4000
59#define CRYS_SEP_ROM_start_address 0x8000C000UL
60#define CRYS_SEP_ROM_start_address_offset 0xC000UL
61#define SEP_ROM_BANK_register 0x80008420UL
62#define SEP_ROM_BANK_register_offset 0x8420UL
63#define SEP_RAR_IO_MEM_REGION_START_ADDRESS 0x82000000
64
65/*
66 * THESE 2 definitions are specific to the board - must be
67 * defined during integration
68 */
69#define SEP_RAR_IO_MEM_REGION_START_ADDRESS 0xFF0D0000
70
71/* 2M size */
72
73static void sep_load_rom_code(struct sep_device *sep)
74{
75 /* Index variables */
76 unsigned long i, k, j;
77 u32 reg;
78 u32 error;
79 u32 warning;
80
81 /* Loading ROM from SEP_ROM_image.h file */
82 k = sizeof(CRYS_SEP_ROM);
83
84 edbg("SEP Driver: DX_CC_TST_SepRomLoader start\n");
85
86 edbg("SEP Driver: k is %lu\n", k);
87 edbg("SEP Driver: sep->reg_addr is %p\n", sep->reg_addr);
88 edbg("SEP Driver: CRYS_SEP_ROM_start_address_offset is %p\n", CRYS_SEP_ROM_start_address_offset);
89
90 for (i = 0; i < 4; i++) {
91 /* write bank */
92 sep_write_reg(sep, SEP_ROM_BANK_register_offset, i);
93
94 for (j = 0; j < CRYS_SEP_ROM_length / 4; j++) {
95 sep_write_reg(sep, CRYS_SEP_ROM_start_address_offset + 4 * j, CRYS_SEP_ROM[i * 0x1000 + j]);
96
97 k = k - 4;
98
99 if (k == 0) {
100 j = CRYS_SEP_ROM_length;
101 i = 4;
102 }
103 }
104 }
105
106 /* reset the SEP */
107 sep_write_reg(sep, HW_HOST_SEP_SW_RST_REG_ADDR, 0x1);
108
109 /* poll for SEP ROM boot finish */
110 do
111 reg = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR3_REG_ADDR);
112 while (!reg);
113
114 edbg("SEP Driver: ROM polling ended\n");
115
116 switch (reg) {
117 case 0x1:
118 /* fatal error - read erro status from GPRO */
119 error = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR0_REG_ADDR);
120 edbg("SEP Driver: ROM polling case 1\n");
121 break;
122 case 0x4:
123 /* Cold boot ended successfully */
124 case 0x8:
125 /* Warmboot ended successfully */
126 case 0x10:
127 /* ColdWarm boot ended successfully */
128 error = 0;
129 case 0x2:
130 /* Boot First Phase ended */
131 warning = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR0_REG_ADDR);
132 case 0x20:
133 edbg("SEP Driver: ROM polling case %d\n", reg);
134 break;
135 }
136
137}
138
139#else
140static void sep_load_rom_code(struct sep_device *sep) { }
141#endif /* SEP_DRIVER_ARM_DEBUG_MODE */
142
143
144
145/*----------------------------------------
146 DEFINES
147-----------------------------------------*/
148
149#define BASE_ADDRESS_FOR_SYSTEM 0xfffc0000
150#define SEP_RAR_IO_MEM_REGION_SIZE 0x40000
151
152/*--------------------------------------------
153 GLOBAL variables
154--------------------------------------------*/
155
156/* debug messages level */
157static int debug;
158module_param(debug, int , 0);
159MODULE_PARM_DESC(debug, "Flag to enable SEP debug messages");
160
161/* Keep this a single static object for now to keep the conversion easy */
162
163static struct sep_device sep_instance;
164static struct sep_device *sep_dev = &sep_instance;
165
166/*
167 mutex for the access to the internals of the sep driver
168*/
169static DEFINE_MUTEX(sep_mutex);
170
171
172/* wait queue head (event) of the driver */
173static DECLARE_WAIT_QUEUE_HEAD(sep_event);
174
175/**
176 * sep_load_firmware - copy firmware cache/resident
177 * @sep: device we are loading
178 *
179 * This functions copies the cache and resident from their source
180 * location into destination shared memory.
181 */
182
183static int sep_load_firmware(struct sep_device *sep)
184{
185 const struct firmware *fw;
186 char *cache_name = "sep/cache.image.bin";
187 char *res_name = "sep/resident.image.bin";
188 int error;
189
190 edbg("SEP Driver:rar_virtual is %p\n", sep->rar_addr);
191 edbg("SEP Driver:rar_bus is %08llx\n", (unsigned long long)sep->rar_bus);
192
193 /* load cache */
194 error = request_firmware(&fw, cache_name, &sep->pdev->dev);
195 if (error) {
196 edbg("SEP Driver:cant request cache fw\n");
197 return error;
198 }
199 edbg("SEP Driver:cache %08Zx@%p\n", fw->size, (void *) fw->data);
200
201 memcpy(sep->rar_addr, (void *)fw->data, fw->size);
202 sep->cache_size = fw->size;
203 release_firmware(fw);
204
205 sep->resident_bus = sep->rar_bus + sep->cache_size;
206 sep->resident_addr = sep->rar_addr + sep->cache_size;
207
208 /* load resident */
209 error = request_firmware(&fw, res_name, &sep->pdev->dev);
210 if (error) {
211 edbg("SEP Driver:cant request res fw\n");
212 return error;
213 }
214 edbg("sep: res %08Zx@%p\n", fw->size, (void *)fw->data);
215
216 memcpy(sep->resident_addr, (void *) fw->data, fw->size);
217 sep->resident_size = fw->size;
218 release_firmware(fw);
219
220 edbg("sep: resident v %p b %08llx cache v %p b %08llx\n",
221 sep->resident_addr, (unsigned long long)sep->resident_bus,
222 sep->rar_addr, (unsigned long long)sep->rar_bus);
223 return 0;
224}
225
226MODULE_FIRMWARE("sep/cache.image.bin");
227MODULE_FIRMWARE("sep/resident.image.bin");
228
229/**
230 * sep_map_and_alloc_shared_area - allocate shared block
231 * @sep: security processor
232 * @size: size of shared area
233 *
234 * Allocate a shared buffer in host memory that can be used by both the
235 * kernel and also the hardware interface via DMA.
236 */
237
238static int sep_map_and_alloc_shared_area(struct sep_device *sep,
239 unsigned long size)
240{
241 /* shared_addr = ioremap_nocache(0xda00000,shared_area_size); */
242 sep->shared_addr = dma_alloc_coherent(&sep->pdev->dev, size,
243 &sep->shared_bus, GFP_KERNEL);
244
245 if (!sep->shared_addr) {
246 edbg("sep_driver :shared memory dma_alloc_coherent failed\n");
247 return -ENOMEM;
248 }
249 /* set the bus address of the shared area */
250 edbg("sep: shared_addr %ld bytes @%p (bus %08llx)\n",
251 size, sep->shared_addr, (unsigned long long)sep->shared_bus);
252 return 0;
253}
254
255/**
256 * sep_unmap_and_free_shared_area - free shared block
257 * @sep: security processor
258 *
259 * Free the shared area allocated to the security processor. The
260 * processor must have finished with this and any final posted
261 * writes cleared before we do so.
262 */
263static void sep_unmap_and_free_shared_area(struct sep_device *sep, int size)
264{
265 dma_free_coherent(&sep->pdev->dev, size,
266 sep->shared_addr, sep->shared_bus);
267}
268
269/**
270 * sep_shared_virt_to_bus - convert bus/virt addresses
271 *
272 * Returns the bus address inside the shared area according
273 * to the virtual address.
274 */
275
276static dma_addr_t sep_shared_virt_to_bus(struct sep_device *sep,
277 void *virt_address)
278{
279 dma_addr_t pa = sep->shared_bus + (virt_address - sep->shared_addr);
280 edbg("sep: virt to bus b %08llx v %p\n", (unsigned long long) pa,
281 virt_address);
282 return pa;
283}
284
285/**
286 * sep_shared_bus_to_virt - convert bus/virt addresses
287 *
288 * Returns virtual address inside the shared area according
289 * to the bus address.
290 */
291
292static void *sep_shared_bus_to_virt(struct sep_device *sep,
293 dma_addr_t bus_address)
294{
295 return sep->shared_addr + (bus_address - sep->shared_bus);
296}
297
298
299/**
300 * sep_try_open - attempt to open a SEP device
301 * @sep: device to attempt to open
302 *
303 * Atomically attempt to get ownership of a SEP device.
304 * Returns 1 if the device was opened, 0 on failure.
305 */
306
307static int sep_try_open(struct sep_device *sep)
308{
309 if (!test_and_set_bit(0, &sep->in_use))
310 return 1;
311 return 0;
312}
313
314/**
315 * sep_open - device open method
316 * @inode: inode of sep device
317 * @filp: file handle to sep device
318 *
319 * Open method for the SEP device. Called when userspace opens
320 * the SEP device node. Must also release the memory data pool
321 * allocations.
322 *
323 * Returns zero on success otherwise an error code.
324 */
325
326static int sep_open(struct inode *inode, struct file *filp)
327{
328 if (sep_dev == NULL)
329 return -ENODEV;
330
331 /* check the blocking mode */
332 if (filp->f_flags & O_NDELAY) {
333 if (sep_try_open(sep_dev) == 0)
334 return -EAGAIN;
335 } else
336 if (wait_event_interruptible(sep_event, sep_try_open(sep_dev)) < 0)
337 return -EINTR;
338
339 /* Bind to the device, we only have one which makes it easy */
340 filp->private_data = sep_dev;
341 /* release data pool allocations */
342 sep_dev->data_pool_bytes_allocated = 0;
343 return 0;
344}
345
346
347/**
348 * sep_release - close a SEP device
349 * @inode: inode of SEP device
350 * @filp: file handle being closed
351 *
352 * Called on the final close of a SEP device. As the open protects against
353 * multiple simultaenous opens that means this method is called when the
354 * final reference to the open handle is dropped.
355 */
356
357static int sep_release(struct inode *inode, struct file *filp)
358{
359 struct sep_device *sep = filp->private_data;
360#if 0 /*!SEP_DRIVER_POLLING_MODE */
361 /* close IMR */
362 sep_write_reg(sep, HW_HOST_IMR_REG_ADDR, 0x7FFF);
363 /* release IRQ line */
364 free_irq(SEP_DIRVER_IRQ_NUM, sep);
365
366#endif
367 /* Ensure any blocked open progresses */
368 clear_bit(0, &sep->in_use);
369 wake_up(&sep_event);
370 return 0;
371}
372
373/*---------------------------------------------------------------
374 map function - this functions maps the message shared area
375-----------------------------------------------------------------*/
376static int sep_mmap(struct file *filp, struct vm_area_struct *vma)
377{
378 dma_addr_t bus_addr;
379 struct sep_device *sep = filp->private_data;
380
381 dbg("-------->SEP Driver: mmap start\n");
382
383 /* check that the size of the mapped range is as the size of the message
384 shared area */
385 if ((vma->vm_end - vma->vm_start) > SEP_DRIVER_MMMAP_AREA_SIZE) {
386 edbg("SEP Driver mmap requested size is more than allowed\n");
387 printk(KERN_WARNING "SEP Driver mmap requested size is more than allowed\n");
388 printk(KERN_WARNING "SEP Driver vma->vm_end is %08lx\n", vma->vm_end);
389 printk(KERN_WARNING "SEP Driver vma->vm_end is %08lx\n", vma->vm_start);
390 return -EAGAIN;
391 }
392
393 edbg("SEP Driver:sep->shared_addr is %p\n", sep->shared_addr);
394
395 /* get bus address */
396 bus_addr = sep->shared_bus;
397
398 edbg("SEP Driver: phys_addr is %08llx\n", (unsigned long long)bus_addr);
399
400 if (remap_pfn_range(vma, vma->vm_start, bus_addr >> PAGE_SHIFT, vma->vm_end - vma->vm_start, vma->vm_page_prot)) {
401 edbg("SEP Driver remap_page_range failed\n");
402 printk(KERN_WARNING "SEP Driver remap_page_range failed\n");
403 return -EAGAIN;
404 }
405
406 dbg("SEP Driver:<-------- mmap end\n");
407
408 return 0;
409}
410
411
412/*-----------------------------------------------
413 poll function
414*----------------------------------------------*/
415static unsigned int sep_poll(struct file *filp, poll_table * wait)
416{
417 unsigned long count;
418 unsigned int mask = 0;
419 unsigned long retval = 0; /* flow id */
420 struct sep_device *sep = filp->private_data;
421
422 dbg("---------->SEP Driver poll: start\n");
423
424
425#if SEP_DRIVER_POLLING_MODE
426
427 while (sep->send_ct != (retval & 0x7FFFFFFF)) {
428 retval = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR2_REG_ADDR);
429
430 for (count = 0; count < 10 * 4; count += 4)
431 edbg("Poll Debug Word %lu of the message is %lu\n", count, *((unsigned long *) (sep->shared_addr + SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES + count)));
432 }
433
434 sep->reply_ct++;
435#else
436 /* add the event to the polling wait table */
437 poll_wait(filp, &sep_event, wait);
438
439#endif
440
441 edbg("sep->send_ct is %lu\n", sep->send_ct);
442 edbg("sep->reply_ct is %lu\n", sep->reply_ct);
443
444 /* check if the data is ready */
445 if (sep->send_ct == sep->reply_ct) {
446 for (count = 0; count < 12 * 4; count += 4)
447 edbg("Sep Mesg Word %lu of the message is %lu\n", count, *((unsigned long *) (sep->shared_addr + count)));
448
449 for (count = 0; count < 10 * 4; count += 4)
450 edbg("Debug Data Word %lu of the message is %lu\n", count, *((unsigned long *) (sep->shared_addr + 0x1800 + count)));
451
452 retval = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR2_REG_ADDR);
453 edbg("retval is %lu\n", retval);
454 /* check if the this is sep reply or request */
455 if (retval >> 31) {
456 edbg("SEP Driver: sep request in\n");
457 /* request */
458 mask |= POLLOUT | POLLWRNORM;
459 } else {
460 edbg("SEP Driver: sep reply in\n");
461 mask |= POLLIN | POLLRDNORM;
462 }
463 }
464 dbg("SEP Driver:<-------- poll exit\n");
465 return mask;
466}
467
468/**
469 * sep_time_address - address in SEP memory of time
470 * @sep: SEP device we want the address from
471 *
472 * Return the address of the two dwords in memory used for time
473 * setting.
474 */
475
476static u32 *sep_time_address(struct sep_device *sep)
477{
478 return sep->shared_addr + SEP_DRIVER_SYSTEM_TIME_MEMORY_OFFSET_IN_BYTES;
479}
480
481/**
482 * sep_set_time - set the SEP time
483 * @sep: the SEP we are setting the time for
484 *
485 * Calculates time and sets it at the predefined address.
486 * Called with the sep mutex held.
487 */
488static unsigned long sep_set_time(struct sep_device *sep)
489{
490 struct timeval time;
491 u32 *time_addr; /* address of time as seen by the kernel */
492
493
494 dbg("sep:sep_set_time start\n");
495
496 do_gettimeofday(&time);
497
498 /* set value in the SYSTEM MEMORY offset */
499 time_addr = sep_time_address(sep);
500
501 time_addr[0] = SEP_TIME_VAL_TOKEN;
502 time_addr[1] = time.tv_sec;
503
504 edbg("SEP Driver:time.tv_sec is %lu\n", time.tv_sec);
505 edbg("SEP Driver:time_addr is %p\n", time_addr);
506 edbg("SEP Driver:sep->shared_addr is %p\n", sep->shared_addr);
507
508 return time.tv_sec;
509}
510
511/**
512 * sep_dump_message - dump the message that is pending
513 * @sep: sep device
514 *
515 * Dump out the message pending in the shared message area
516 */
517
518static void sep_dump_message(struct sep_device *sep)
519{
520 int count;
521 for (count = 0; count < 12 * 4; count += 4)
522 edbg("Word %d of the message is %u\n", count, *((u32 *) (sep->shared_addr + count)));
523}
524
525/**
526 * sep_send_command_handler - kick off a command
527 * @sep: sep being signalled
528 *
529 * This function raises interrupt to SEP that signals that is has a new
530 * command from the host
531 */
532
533static void sep_send_command_handler(struct sep_device *sep)
534{
535 dbg("sep:sep_send_command_handler start\n");
536
537 mutex_lock(&sep_mutex);
538 sep_set_time(sep);
539
540 /* FIXME: flush cache */
541 flush_cache_all();
542
543 sep_dump_message(sep);
544 /* update counter */
545 sep->send_ct++;
546 /* send interrupt to SEP */
547 sep_write_reg(sep, HW_HOST_HOST_SEP_GPR0_REG_ADDR, 0x2);
548 dbg("SEP Driver:<-------- sep_send_command_handler end\n");
549 mutex_unlock(&sep_mutex);
550 return;
551}
552
553/**
554 * sep_send_reply_command_handler - kick off a command reply
555 * @sep: sep being signalled
556 *
557 * This function raises interrupt to SEP that signals that is has a new
558 * command from the host
559 */
560
561static void sep_send_reply_command_handler(struct sep_device *sep)
562{
563 dbg("sep:sep_send_reply_command_handler start\n");
564
565 /* flash cache */
566 flush_cache_all();
567
568 sep_dump_message(sep);
569
570 mutex_lock(&sep_mutex);
571 sep->send_ct++; /* update counter */
572 /* send the interrupt to SEP */
573 sep_write_reg(sep, HW_HOST_HOST_SEP_GPR2_REG_ADDR, sep->send_ct);
574 /* update both counters */
575 sep->send_ct++;
576 sep->reply_ct++;
577 mutex_unlock(&sep_mutex);
578 dbg("sep: sep_send_reply_command_handler end\n");
579}
580
581/*
582 This function handles the allocate data pool memory request
583 This function returns calculates the bus address of the
584 allocated memory, and the offset of this area from the mapped address.
585 Therefore, the FVOs in user space can calculate the exact virtual
586 address of this allocated memory
587*/
588static int sep_allocate_data_pool_memory_handler(struct sep_device *sep,
589 unsigned long arg)
590{
591 int error;
592 struct sep_driver_alloc_t command_args;
593
594 dbg("SEP Driver:--------> sep_allocate_data_pool_memory_handler start\n");
595
596 error = copy_from_user(&command_args, (void *) arg, sizeof(struct sep_driver_alloc_t));
597 if (error) {
598 error = -EFAULT;
599 goto end_function;
600 }
601
602 /* allocate memory */
603 if ((sep->data_pool_bytes_allocated + command_args.num_bytes) > SEP_DRIVER_DATA_POOL_SHARED_AREA_SIZE_IN_BYTES) {
604 error = -ENOMEM;
605 goto end_function;
606 }
607
608 /* set the virtual and bus address */
609 command_args.offset = SEP_DRIVER_DATA_POOL_AREA_OFFSET_IN_BYTES + sep->data_pool_bytes_allocated;
610 command_args.phys_address = sep->shared_bus + SEP_DRIVER_DATA_POOL_AREA_OFFSET_IN_BYTES + sep->data_pool_bytes_allocated;
611
612 /* write the memory back to the user space */
613 error = copy_to_user((void *) arg, (void *) &command_args, sizeof(struct sep_driver_alloc_t));
614 if (error) {
615 error = -EFAULT;
616 goto end_function;
617 }
618
619 /* set the allocation */
620 sep->data_pool_bytes_allocated += command_args.num_bytes;
621
622end_function:
623 dbg("SEP Driver:<-------- sep_allocate_data_pool_memory_handler end\n");
624 return error;
625}
626
627/*
628 This function handles write into allocated data pool command
629*/
630static int sep_write_into_data_pool_handler(struct sep_device *sep, unsigned long arg)
631{
632 int error;
633 void *virt_address;
634 unsigned long va;
635 unsigned long app_in_address;
636 unsigned long num_bytes;
637 void *data_pool_area_addr;
638
639 dbg("SEP Driver:--------> sep_write_into_data_pool_handler start\n");
640
641 /* get the application address */
642 error = get_user(app_in_address, &(((struct sep_driver_write_t *) arg)->app_address));
643 if (error)
644 goto end_function;
645
646 /* get the virtual kernel address address */
647 error = get_user(va, &(((struct sep_driver_write_t *) arg)->datapool_address));
648 if (error)
649 goto end_function;
650 virt_address = (void *)va;
651
652 /* get the number of bytes */
653 error = get_user(num_bytes, &(((struct sep_driver_write_t *) arg)->num_bytes));
654 if (error)
655 goto end_function;
656
657 /* calculate the start of the data pool */
658 data_pool_area_addr = sep->shared_addr + SEP_DRIVER_DATA_POOL_AREA_OFFSET_IN_BYTES;
659
660
661 /* check that the range of the virtual kernel address is correct */
662 if (virt_address < data_pool_area_addr || virt_address > (data_pool_area_addr + SEP_DRIVER_DATA_POOL_SHARED_AREA_SIZE_IN_BYTES)) {
663 error = -EINVAL;
664 goto end_function;
665 }
666 /* copy the application data */
667 error = copy_from_user(virt_address, (void *) app_in_address, num_bytes);
668 if (error)
669 error = -EFAULT;
670end_function:
671 dbg("SEP Driver:<-------- sep_write_into_data_pool_handler end\n");
672 return error;
673}
674
675/*
676 this function handles the read from data pool command
677*/
678static int sep_read_from_data_pool_handler(struct sep_device *sep, unsigned long arg)
679{
680 int error;
681 /* virtual address of dest application buffer */
682 unsigned long app_out_address;
683 /* virtual address of the data pool */
684 unsigned long va;
685 void *virt_address;
686 unsigned long num_bytes;
687 void *data_pool_area_addr;
688
689 dbg("SEP Driver:--------> sep_read_from_data_pool_handler start\n");
690
691 /* get the application address */
692 error = get_user(app_out_address, &(((struct sep_driver_write_t *) arg)->app_address));
693 if (error)
694 goto end_function;
695
696 /* get the virtual kernel address address */
697 error = get_user(va, &(((struct sep_driver_write_t *) arg)->datapool_address));
698 if (error)
699 goto end_function;
700 virt_address = (void *)va;
701
702 /* get the number of bytes */
703 error = get_user(num_bytes, &(((struct sep_driver_write_t *) arg)->num_bytes));
704 if (error)
705 goto end_function;
706
707 /* calculate the start of the data pool */
708 data_pool_area_addr = sep->shared_addr + SEP_DRIVER_DATA_POOL_AREA_OFFSET_IN_BYTES;
709
710 /* FIXME: These are incomplete all over the driver: what about + len
711 and when doing that also overflows */
712 /* check that the range of the virtual kernel address is correct */
713 if (virt_address < data_pool_area_addr || virt_address > data_pool_area_addr + SEP_DRIVER_DATA_POOL_SHARED_AREA_SIZE_IN_BYTES) {
714 error = -EINVAL;
715 goto end_function;
716 }
717
718 /* copy the application data */
719 error = copy_to_user((void *) app_out_address, virt_address, num_bytes);
720 if (error)
721 error = -EFAULT;
722end_function:
723 dbg("SEP Driver:<-------- sep_read_from_data_pool_handler end\n");
724 return error;
725}
726
727/*
728 This function releases all the application virtual buffer physical pages,
729 that were previously locked
730*/
731static int sep_free_dma_pages(struct page **page_array_ptr, unsigned long num_pages, unsigned long dirtyFlag)
732{
733 unsigned long count;
734
735 if (dirtyFlag) {
736 for (count = 0; count < num_pages; count++) {
737 /* the out array was written, therefore the data was changed */
738 if (!PageReserved(page_array_ptr[count]))
739 SetPageDirty(page_array_ptr[count]);
740 page_cache_release(page_array_ptr[count]);
741 }
742 } else {
743 /* free in pages - the data was only read, therefore no update was done
744 on those pages */
745 for (count = 0; count < num_pages; count++)
746 page_cache_release(page_array_ptr[count]);
747 }
748
749 if (page_array_ptr)
750 /* free the array */
751 kfree(page_array_ptr);
752
753 return 0;
754}
755
756/*
757 This function locks all the physical pages of the kernel virtual buffer
758 and construct a basic lli array, where each entry holds the physical
759 page address and the size that application data holds in this physical pages
760*/
761static int sep_lock_kernel_pages(struct sep_device *sep,
762 unsigned long kernel_virt_addr,
763 unsigned long data_size,
764 unsigned long *num_pages_ptr,
765 struct sep_lli_entry_t **lli_array_ptr,
766 struct page ***page_array_ptr)
767{
768 int error = 0;
769 /* the the page of the end address of the user space buffer */
770 unsigned long end_page;
771 /* the page of the start address of the user space buffer */
772 unsigned long start_page;
773 /* the range in pages */
774 unsigned long num_pages;
775 struct sep_lli_entry_t *lli_array;
776 /* next kernel address to map */
777 unsigned long next_kernel_address;
778 unsigned long count;
779
780 dbg("SEP Driver:--------> sep_lock_kernel_pages start\n");
781
782 /* set start and end pages and num pages */
783 end_page = (kernel_virt_addr + data_size - 1) >> PAGE_SHIFT;
784 start_page = kernel_virt_addr >> PAGE_SHIFT;
785 num_pages = end_page - start_page + 1;
786
787 edbg("SEP Driver: kernel_virt_addr is %08lx\n", kernel_virt_addr);
788 edbg("SEP Driver: data_size is %lu\n", data_size);
789 edbg("SEP Driver: start_page is %lx\n", start_page);
790 edbg("SEP Driver: end_page is %lx\n", end_page);
791 edbg("SEP Driver: num_pages is %lu\n", num_pages);
792
793 lli_array = kmalloc(sizeof(struct sep_lli_entry_t) * num_pages, GFP_ATOMIC);
794 if (!lli_array) {
795 edbg("SEP Driver: kmalloc for lli_array failed\n");
796 error = -ENOMEM;
797 goto end_function;
798 }
799
800 /* set the start address of the first page - app data may start not at
801 the beginning of the page */
802 lli_array[0].physical_address = (unsigned long) virt_to_phys((unsigned long *) kernel_virt_addr);
803
804 /* check that not all the data is in the first page only */
805 if ((PAGE_SIZE - (kernel_virt_addr & (~PAGE_MASK))) >= data_size)
806 lli_array[0].block_size = data_size;
807 else
808 lli_array[0].block_size = PAGE_SIZE - (kernel_virt_addr & (~PAGE_MASK));
809
810 /* debug print */
811 dbg("lli_array[0].physical_address is %08lx, lli_array[0].block_size is %lu\n", lli_array[0].physical_address, lli_array[0].block_size);
812
813 /* advance the address to the start of the next page */
814 next_kernel_address = (kernel_virt_addr & PAGE_MASK) + PAGE_SIZE;
815
816 /* go from the second page to the prev before last */
817 for (count = 1; count < (num_pages - 1); count++) {
818 lli_array[count].physical_address = (unsigned long) virt_to_phys((unsigned long *) next_kernel_address);
819 lli_array[count].block_size = PAGE_SIZE;
820
821 edbg("lli_array[%lu].physical_address is %08lx, lli_array[%lu].block_size is %lu\n", count, lli_array[count].physical_address, count, lli_array[count].block_size);
822 next_kernel_address += PAGE_SIZE;
823 }
824
825 /* if more then 1 pages locked - then update for the last page size needed */
826 if (num_pages > 1) {
827 /* update the address of the last page */
828 lli_array[count].physical_address = (unsigned long) virt_to_phys((unsigned long *) next_kernel_address);
829
830 /* set the size of the last page */
831 lli_array[count].block_size = (kernel_virt_addr + data_size) & (~PAGE_MASK);
832
833 if (lli_array[count].block_size == 0) {
834 dbg("app_virt_addr is %08lx\n", kernel_virt_addr);
835 dbg("data_size is %lu\n", data_size);
836 while (1);
837 }
838
839 edbg("lli_array[%lu].physical_address is %08lx, lli_array[%lu].block_size is %lu\n", count, lli_array[count].physical_address, count, lli_array[count].block_size);
840 }
841 /* set output params */
842 *lli_array_ptr = lli_array;
843 *num_pages_ptr = num_pages;
844 *page_array_ptr = 0;
845end_function:
846 dbg("SEP Driver:<-------- sep_lock_kernel_pages end\n");
847 return 0;
848}
849
850/*
851 This function locks all the physical pages of the application virtual buffer
852 and construct a basic lli array, where each entry holds the physical page
853 address and the size that application data holds in this physical pages
854*/
855static int sep_lock_user_pages(struct sep_device *sep,
856 unsigned long app_virt_addr,
857 unsigned long data_size,
858 unsigned long *num_pages_ptr,
859 struct sep_lli_entry_t **lli_array_ptr,
860 struct page ***page_array_ptr)
861{
862 int error = 0;
863 /* the the page of the end address of the user space buffer */
864 unsigned long end_page;
865 /* the page of the start address of the user space buffer */
866 unsigned long start_page;
867 /* the range in pages */
868 unsigned long num_pages;
869 struct page **page_array;
870 struct sep_lli_entry_t *lli_array;
871 unsigned long count;
872 int result;
873
874 dbg("SEP Driver:--------> sep_lock_user_pages start\n");
875
876 /* set start and end pages and num pages */
877 end_page = (app_virt_addr + data_size - 1) >> PAGE_SHIFT;
878 start_page = app_virt_addr >> PAGE_SHIFT;
879 num_pages = end_page - start_page + 1;
880
881 edbg("SEP Driver: app_virt_addr is %08lx\n", app_virt_addr);
882 edbg("SEP Driver: data_size is %lu\n", data_size);
883 edbg("SEP Driver: start_page is %lu\n", start_page);
884 edbg("SEP Driver: end_page is %lu\n", end_page);
885 edbg("SEP Driver: num_pages is %lu\n", num_pages);
886
887 /* allocate array of pages structure pointers */
888 page_array = kmalloc(sizeof(struct page *) * num_pages, GFP_ATOMIC);
889 if (!page_array) {
890 edbg("SEP Driver: kmalloc for page_array failed\n");
891
892 error = -ENOMEM;
893 goto end_function;
894 }
895
896 lli_array = kmalloc(sizeof(struct sep_lli_entry_t) * num_pages, GFP_ATOMIC);
897 if (!lli_array) {
898 edbg("SEP Driver: kmalloc for lli_array failed\n");
899
900 error = -ENOMEM;
901 goto end_function_with_error1;
902 }
903
904 /* convert the application virtual address into a set of physical */
905 down_read(&current->mm->mmap_sem);
906 result = get_user_pages(current, current->mm, app_virt_addr, num_pages, 1, 0, page_array, 0);
907 up_read(&current->mm->mmap_sem);
908
909 /* check the number of pages locked - if not all then exit with error */
910 if (result != num_pages) {
911 dbg("SEP Driver: not all pages locked by get_user_pages\n");
912
913 error = -ENOMEM;
914 goto end_function_with_error2;
915 }
916
917 /* flush the cache */
918 for (count = 0; count < num_pages; count++)
919 flush_dcache_page(page_array[count]);
920
921 /* set the start address of the first page - app data may start not at
922 the beginning of the page */
923 lli_array[0].physical_address = ((unsigned long) page_to_phys(page_array[0])) + (app_virt_addr & (~PAGE_MASK));
924
925 /* check that not all the data is in the first page only */
926 if ((PAGE_SIZE - (app_virt_addr & (~PAGE_MASK))) >= data_size)
927 lli_array[0].block_size = data_size;
928 else
929 lli_array[0].block_size = PAGE_SIZE - (app_virt_addr & (~PAGE_MASK));
930
931 /* debug print */
932 dbg("lli_array[0].physical_address is %08lx, lli_array[0].block_size is %lu\n", lli_array[0].physical_address, lli_array[0].block_size);
933
934 /* go from the second page to the prev before last */
935 for (count = 1; count < (num_pages - 1); count++) {
936 lli_array[count].physical_address = (unsigned long) page_to_phys(page_array[count]);
937 lli_array[count].block_size = PAGE_SIZE;
938
939 edbg("lli_array[%lu].physical_address is %08lx, lli_array[%lu].block_size is %lu\n", count, lli_array[count].physical_address, count, lli_array[count].block_size);
940 }
941
942 /* if more then 1 pages locked - then update for the last page size needed */
943 if (num_pages > 1) {
944 /* update the address of the last page */
945 lli_array[count].physical_address = (unsigned long) page_to_phys(page_array[count]);
946
947 /* set the size of the last page */
948 lli_array[count].block_size = (app_virt_addr + data_size) & (~PAGE_MASK);
949
950 if (lli_array[count].block_size == 0) {
951 dbg("app_virt_addr is %08lx\n", app_virt_addr);
952 dbg("data_size is %lu\n", data_size);
953 while (1);
954 }
955 edbg("lli_array[%lu].physical_address is %08lx, lli_array[%lu].block_size is %lu\n",
956 count, lli_array[count].physical_address,
957 count, lli_array[count].block_size);
958 }
959
960 /* set output params */
961 *lli_array_ptr = lli_array;
962 *num_pages_ptr = num_pages;
963 *page_array_ptr = page_array;
964 goto end_function;
965
966end_function_with_error2:
967 /* release the cache */
968 for (count = 0; count < num_pages; count++)
969 page_cache_release(page_array[count]);
970 kfree(lli_array);
971end_function_with_error1:
972 kfree(page_array);
973end_function:
974 dbg("SEP Driver:<-------- sep_lock_user_pages end\n");
975 return 0;
976}
977
978
979/*
980 this function calculates the size of data that can be inserted into the lli
981 table from this array the condition is that either the table is full
982 (all etnries are entered), or there are no more entries in the lli array
983*/
984static unsigned long sep_calculate_lli_table_max_size(struct sep_lli_entry_t *lli_in_array_ptr, unsigned long num_array_entries)
985{
986 unsigned long table_data_size = 0;
987 unsigned long counter;
988
989 /* calculate the data in the out lli table if till we fill the whole
990 table or till the data has ended */
991 for (counter = 0; (counter < (SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP - 1)) && (counter < num_array_entries); counter++)
992 table_data_size += lli_in_array_ptr[counter].block_size;
993 return table_data_size;
994}
995
996/*
997 this functions builds ont lli table from the lli_array according to
998 the given size of data
999*/
1000static void sep_build_lli_table(struct sep_lli_entry_t *lli_array_ptr, struct sep_lli_entry_t *lli_table_ptr, unsigned long *num_processed_entries_ptr, unsigned long *num_table_entries_ptr, unsigned long table_data_size)
1001{
1002 unsigned long curr_table_data_size;
1003 /* counter of lli array entry */
1004 unsigned long array_counter;
1005
1006 dbg("SEP Driver:--------> sep_build_lli_table start\n");
1007
1008 /* init currrent table data size and lli array entry counter */
1009 curr_table_data_size = 0;
1010 array_counter = 0;
1011 *num_table_entries_ptr = 1;
1012
1013 edbg("SEP Driver:table_data_size is %lu\n", table_data_size);
1014
1015 /* fill the table till table size reaches the needed amount */
1016 while (curr_table_data_size < table_data_size) {
1017 /* update the number of entries in table */
1018 (*num_table_entries_ptr)++;
1019
1020 lli_table_ptr->physical_address = lli_array_ptr[array_counter].physical_address;
1021 lli_table_ptr->block_size = lli_array_ptr[array_counter].block_size;
1022 curr_table_data_size += lli_table_ptr->block_size;
1023
1024 edbg("SEP Driver:lli_table_ptr is %08lx\n", (unsigned long) lli_table_ptr);
1025 edbg("SEP Driver:lli_table_ptr->physical_address is %08lx\n", lli_table_ptr->physical_address);
1026 edbg("SEP Driver:lli_table_ptr->block_size is %lu\n", lli_table_ptr->block_size);
1027
1028 /* check for overflow of the table data */
1029 if (curr_table_data_size > table_data_size) {
1030 edbg("SEP Driver:curr_table_data_size > table_data_size\n");
1031
1032 /* update the size of block in the table */
1033 lli_table_ptr->block_size -= (curr_table_data_size - table_data_size);
1034
1035 /* update the physical address in the lli array */
1036 lli_array_ptr[array_counter].physical_address += lli_table_ptr->block_size;
1037
1038 /* update the block size left in the lli array */
1039 lli_array_ptr[array_counter].block_size = (curr_table_data_size - table_data_size);
1040 } else
1041 /* advance to the next entry in the lli_array */
1042 array_counter++;
1043
1044 edbg("SEP Driver:lli_table_ptr->physical_address is %08lx\n", lli_table_ptr->physical_address);
1045 edbg("SEP Driver:lli_table_ptr->block_size is %lu\n", lli_table_ptr->block_size);
1046
1047 /* move to the next entry in table */
1048 lli_table_ptr++;
1049 }
1050
1051 /* set the info entry to default */
1052 lli_table_ptr->physical_address = 0xffffffff;
1053 lli_table_ptr->block_size = 0;
1054
1055 edbg("SEP Driver:lli_table_ptr is %08lx\n", (unsigned long) lli_table_ptr);
1056 edbg("SEP Driver:lli_table_ptr->physical_address is %08lx\n", lli_table_ptr->physical_address);
1057 edbg("SEP Driver:lli_table_ptr->block_size is %lu\n", lli_table_ptr->block_size);
1058
1059 /* set the output parameter */
1060 *num_processed_entries_ptr += array_counter;
1061
1062 edbg("SEP Driver:*num_processed_entries_ptr is %lu\n", *num_processed_entries_ptr);
1063 dbg("SEP Driver:<-------- sep_build_lli_table end\n");
1064 return;
1065}
1066
1067/*
1068 this function goes over the list of the print created tables and
1069 prints all the data
1070*/
1071static void sep_debug_print_lli_tables(struct sep_device *sep, struct sep_lli_entry_t *lli_table_ptr, unsigned long num_table_entries, unsigned long table_data_size)
1072{
1073 unsigned long table_count;
1074 unsigned long entries_count;
1075
1076 dbg("SEP Driver:--------> sep_debug_print_lli_tables start\n");
1077
1078 table_count = 1;
1079 while ((unsigned long) lli_table_ptr != 0xffffffff) {
1080 edbg("SEP Driver: lli table %08lx, table_data_size is %lu\n", table_count, table_data_size);
1081 edbg("SEP Driver: num_table_entries is %lu\n", num_table_entries);
1082
1083 /* print entries of the table (without info entry) */
1084 for (entries_count = 0; entries_count < num_table_entries; entries_count++, lli_table_ptr++) {
1085 edbg("SEP Driver:lli_table_ptr address is %08lx\n", (unsigned long) lli_table_ptr);
1086 edbg("SEP Driver:phys address is %08lx block size is %lu\n", lli_table_ptr->physical_address, lli_table_ptr->block_size);
1087 }
1088
1089 /* point to the info entry */
1090 lli_table_ptr--;
1091
1092 edbg("SEP Driver:phys lli_table_ptr->block_size is %lu\n", lli_table_ptr->block_size);
1093 edbg("SEP Driver:phys lli_table_ptr->physical_address is %08lx\n", lli_table_ptr->physical_address);
1094
1095
1096 table_data_size = lli_table_ptr->block_size & 0xffffff;
1097 num_table_entries = (lli_table_ptr->block_size >> 24) & 0xff;
1098 lli_table_ptr = (struct sep_lli_entry_t *)
1099 (lli_table_ptr->physical_address);
1100
1101 edbg("SEP Driver:phys table_data_size is %lu num_table_entries is %lu lli_table_ptr is%lu\n", table_data_size, num_table_entries, (unsigned long) lli_table_ptr);
1102
1103 if ((unsigned long) lli_table_ptr != 0xffffffff)
1104 lli_table_ptr = (struct sep_lli_entry_t *) sep_shared_bus_to_virt(sep, (unsigned long) lli_table_ptr);
1105
1106 table_count++;
1107 }
1108 dbg("SEP Driver:<-------- sep_debug_print_lli_tables end\n");
1109}
1110
1111
1112/*
1113 This function prepares only input DMA table for synhronic symmetric
1114 operations (HASH)
1115*/
1116static int sep_prepare_input_dma_table(struct sep_device *sep,
1117 unsigned long app_virt_addr,
1118 unsigned long data_size,
1119 unsigned long block_size,
1120 unsigned long *lli_table_ptr,
1121 unsigned long *num_entries_ptr,
1122 unsigned long *table_data_size_ptr,
1123 bool isKernelVirtualAddress)
1124{
1125 /* pointer to the info entry of the table - the last entry */
1126 struct sep_lli_entry_t *info_entry_ptr;
1127 /* array of pointers ot page */
1128 struct sep_lli_entry_t *lli_array_ptr;
1129 /* points to the first entry to be processed in the lli_in_array */
1130 unsigned long current_entry;
1131 /* num entries in the virtual buffer */
1132 unsigned long sep_lli_entries;
1133 /* lli table pointer */
1134 struct sep_lli_entry_t *in_lli_table_ptr;
1135 /* the total data in one table */
1136 unsigned long table_data_size;
1137 /* number of entries in lli table */
1138 unsigned long num_entries_in_table;
1139 /* next table address */
1140 void *lli_table_alloc_addr;
1141 unsigned long result;
1142
1143 dbg("SEP Driver:--------> sep_prepare_input_dma_table start\n");
1144
1145 edbg("SEP Driver:data_size is %lu\n", data_size);
1146 edbg("SEP Driver:block_size is %lu\n", block_size);
1147
1148 /* initialize the pages pointers */
1149 sep->in_page_array = 0;
1150 sep->in_num_pages = 0;
1151
1152 if (data_size == 0) {
1153 /* special case - created 2 entries table with zero data */
1154 in_lli_table_ptr = (struct sep_lli_entry_t *) (sep->shared_addr + SEP_DRIVER_SYNCHRONIC_DMA_TABLES_AREA_OFFSET_IN_BYTES);
1155 /* FIXME: Should the entry below not be for _bus */
1156 in_lli_table_ptr->physical_address = (unsigned long)sep->shared_addr + SEP_DRIVER_SYNCHRONIC_DMA_TABLES_AREA_OFFSET_IN_BYTES;
1157 in_lli_table_ptr->block_size = 0;
1158
1159 in_lli_table_ptr++;
1160 in_lli_table_ptr->physical_address = 0xFFFFFFFF;
1161 in_lli_table_ptr->block_size = 0;
1162
1163 *lli_table_ptr = sep->shared_bus + SEP_DRIVER_SYNCHRONIC_DMA_TABLES_AREA_OFFSET_IN_BYTES;
1164 *num_entries_ptr = 2;
1165 *table_data_size_ptr = 0;
1166
1167 goto end_function;
1168 }
1169
1170 /* check if the pages are in Kernel Virtual Address layout */
1171 if (isKernelVirtualAddress == true)
1172 /* lock the pages of the kernel buffer and translate them to pages */
1173 result = sep_lock_kernel_pages(sep, app_virt_addr, data_size, &sep->in_num_pages, &lli_array_ptr, &sep->in_page_array);
1174 else
1175 /* lock the pages of the user buffer and translate them to pages */
1176 result = sep_lock_user_pages(sep, app_virt_addr, data_size, &sep->in_num_pages, &lli_array_ptr, &sep->in_page_array);
1177
1178 if (result)
1179 return result;
1180
1181 edbg("SEP Driver:output sep->in_num_pages is %lu\n", sep->in_num_pages);
1182
1183 current_entry = 0;
1184 info_entry_ptr = 0;
1185 sep_lli_entries = sep->in_num_pages;
1186
1187 /* initiate to point after the message area */
1188 lli_table_alloc_addr = sep->shared_addr + SEP_DRIVER_SYNCHRONIC_DMA_TABLES_AREA_OFFSET_IN_BYTES;
1189
1190 /* loop till all the entries in in array are not processed */
1191 while (current_entry < sep_lli_entries) {
1192 /* set the new input and output tables */
1193 in_lli_table_ptr = (struct sep_lli_entry_t *) lli_table_alloc_addr;
1194
1195 lli_table_alloc_addr += sizeof(struct sep_lli_entry_t) * SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP;
1196
1197 /* calculate the maximum size of data for input table */
1198 table_data_size = sep_calculate_lli_table_max_size(&lli_array_ptr[current_entry], (sep_lli_entries - current_entry));
1199
1200 /* now calculate the table size so that it will be module block size */
1201 table_data_size = (table_data_size / block_size) * block_size;
1202
1203 edbg("SEP Driver:output table_data_size is %lu\n", table_data_size);
1204
1205 /* construct input lli table */
1206 sep_build_lli_table(&lli_array_ptr[current_entry], in_lli_table_ptr, &current_entry, &num_entries_in_table, table_data_size);
1207
1208 if (info_entry_ptr == 0) {
1209 /* set the output parameters to physical addresses */
1210 *lli_table_ptr = sep_shared_virt_to_bus(sep, in_lli_table_ptr);
1211 *num_entries_ptr = num_entries_in_table;
1212 *table_data_size_ptr = table_data_size;
1213
1214 edbg("SEP Driver:output lli_table_in_ptr is %08lx\n", *lli_table_ptr);
1215 } else {
1216 /* update the info entry of the previous in table */
1217 info_entry_ptr->physical_address = sep_shared_virt_to_bus(sep, in_lli_table_ptr);
1218 info_entry_ptr->block_size = ((num_entries_in_table) << 24) | (table_data_size);
1219 }
1220
1221 /* save the pointer to the info entry of the current tables */
1222 info_entry_ptr = in_lli_table_ptr + num_entries_in_table - 1;
1223 }
1224
1225 /* print input tables */
1226 sep_debug_print_lli_tables(sep, (struct sep_lli_entry_t *)
1227 sep_shared_bus_to_virt(sep, *lli_table_ptr), *num_entries_ptr, *table_data_size_ptr);
1228
1229 /* the array of the pages */
1230 kfree(lli_array_ptr);
1231end_function:
1232 dbg("SEP Driver:<-------- sep_prepare_input_dma_table end\n");
1233 return 0;
1234
1235}
1236
1237/*
1238 This function creates the input and output dma tables for
1239 symmetric operations (AES/DES) according to the block size from LLI arays
1240*/
1241static int sep_construct_dma_tables_from_lli(struct sep_device *sep,
1242 struct sep_lli_entry_t *lli_in_array,
1243 unsigned long sep_in_lli_entries,
1244 struct sep_lli_entry_t *lli_out_array,
1245 unsigned long sep_out_lli_entries,
1246 unsigned long block_size, unsigned long *lli_table_in_ptr, unsigned long *lli_table_out_ptr, unsigned long *in_num_entries_ptr, unsigned long *out_num_entries_ptr, unsigned long *table_data_size_ptr)
1247{
1248 /* points to the area where next lli table can be allocated: keep void *
1249 as there is pointer scaling to fix otherwise */
1250 void *lli_table_alloc_addr;
1251 /* input lli table */
1252 struct sep_lli_entry_t *in_lli_table_ptr;
1253 /* output lli table */
1254 struct sep_lli_entry_t *out_lli_table_ptr;
1255 /* pointer to the info entry of the table - the last entry */
1256 struct sep_lli_entry_t *info_in_entry_ptr;
1257 /* pointer to the info entry of the table - the last entry */
1258 struct sep_lli_entry_t *info_out_entry_ptr;
1259 /* points to the first entry to be processed in the lli_in_array */
1260 unsigned long current_in_entry;
1261 /* points to the first entry to be processed in the lli_out_array */
1262 unsigned long current_out_entry;
1263 /* max size of the input table */
1264 unsigned long in_table_data_size;
1265 /* max size of the output table */
1266 unsigned long out_table_data_size;
1267 /* flag te signifies if this is the first tables build from the arrays */
1268 unsigned long first_table_flag;
1269 /* the data size that should be in table */
1270 unsigned long table_data_size;
1271 /* number of etnries in the input table */
1272 unsigned long num_entries_in_table;
1273 /* number of etnries in the output table */
1274 unsigned long num_entries_out_table;
1275
1276 dbg("SEP Driver:--------> sep_construct_dma_tables_from_lli start\n");
1277
1278 /* initiate to pint after the message area */
1279 lli_table_alloc_addr = sep->shared_addr + SEP_DRIVER_SYNCHRONIC_DMA_TABLES_AREA_OFFSET_IN_BYTES;
1280
1281 current_in_entry = 0;
1282 current_out_entry = 0;
1283 first_table_flag = 1;
1284 info_in_entry_ptr = 0;
1285 info_out_entry_ptr = 0;
1286
1287 /* loop till all the entries in in array are not processed */
1288 while (current_in_entry < sep_in_lli_entries) {
1289 /* set the new input and output tables */
1290 in_lli_table_ptr = (struct sep_lli_entry_t *) lli_table_alloc_addr;
1291
1292 lli_table_alloc_addr += sizeof(struct sep_lli_entry_t) * SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP;
1293
1294 /* set the first output tables */
1295 out_lli_table_ptr = (struct sep_lli_entry_t *) lli_table_alloc_addr;
1296
1297 lli_table_alloc_addr += sizeof(struct sep_lli_entry_t) * SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP;
1298
1299 /* calculate the maximum size of data for input table */
1300 in_table_data_size = sep_calculate_lli_table_max_size(&lli_in_array[current_in_entry], (sep_in_lli_entries - current_in_entry));
1301
1302 /* calculate the maximum size of data for output table */
1303 out_table_data_size = sep_calculate_lli_table_max_size(&lli_out_array[current_out_entry], (sep_out_lli_entries - current_out_entry));
1304
1305 edbg("SEP Driver:in_table_data_size is %lu\n", in_table_data_size);
1306 edbg("SEP Driver:out_table_data_size is %lu\n", out_table_data_size);
1307
1308 /* check where the data is smallest */
1309 table_data_size = in_table_data_size;
1310 if (table_data_size > out_table_data_size)
1311 table_data_size = out_table_data_size;
1312
1313 /* now calculate the table size so that it will be module block size */
1314 table_data_size = (table_data_size / block_size) * block_size;
1315
1316 dbg("SEP Driver:table_data_size is %lu\n", table_data_size);
1317
1318 /* construct input lli table */
1319 sep_build_lli_table(&lli_in_array[current_in_entry], in_lli_table_ptr, &current_in_entry, &num_entries_in_table, table_data_size);
1320
1321 /* construct output lli table */
1322 sep_build_lli_table(&lli_out_array[current_out_entry], out_lli_table_ptr, &current_out_entry, &num_entries_out_table, table_data_size);
1323
1324 /* if info entry is null - this is the first table built */
1325 if (info_in_entry_ptr == 0) {
1326 /* set the output parameters to physical addresses */
1327 *lli_table_in_ptr = sep_shared_virt_to_bus(sep, in_lli_table_ptr);
1328 *in_num_entries_ptr = num_entries_in_table;
1329 *lli_table_out_ptr = sep_shared_virt_to_bus(sep, out_lli_table_ptr);
1330 *out_num_entries_ptr = num_entries_out_table;
1331 *table_data_size_ptr = table_data_size;
1332
1333 edbg("SEP Driver:output lli_table_in_ptr is %08lx\n", *lli_table_in_ptr);
1334 edbg("SEP Driver:output lli_table_out_ptr is %08lx\n", *lli_table_out_ptr);
1335 } else {
1336 /* update the info entry of the previous in table */
1337 info_in_entry_ptr->physical_address = sep_shared_virt_to_bus(sep, in_lli_table_ptr);
1338 info_in_entry_ptr->block_size = ((num_entries_in_table) << 24) | (table_data_size);
1339
1340 /* update the info entry of the previous in table */
1341 info_out_entry_ptr->physical_address = sep_shared_virt_to_bus(sep, out_lli_table_ptr);
1342 info_out_entry_ptr->block_size = ((num_entries_out_table) << 24) | (table_data_size);
1343 }
1344
1345 /* save the pointer to the info entry of the current tables */
1346 info_in_entry_ptr = in_lli_table_ptr + num_entries_in_table - 1;
1347 info_out_entry_ptr = out_lli_table_ptr + num_entries_out_table - 1;
1348
1349 edbg("SEP Driver:output num_entries_out_table is %lu\n", (unsigned long) num_entries_out_table);
1350 edbg("SEP Driver:output info_in_entry_ptr is %lu\n", (unsigned long) info_in_entry_ptr);
1351 edbg("SEP Driver:output info_out_entry_ptr is %lu\n", (unsigned long) info_out_entry_ptr);
1352 }
1353
1354 /* print input tables */
1355 sep_debug_print_lli_tables(sep, (struct sep_lli_entry_t *)
1356 sep_shared_bus_to_virt(sep, *lli_table_in_ptr), *in_num_entries_ptr, *table_data_size_ptr);
1357 /* print output tables */
1358 sep_debug_print_lli_tables(sep, (struct sep_lli_entry_t *)
1359 sep_shared_bus_to_virt(sep, *lli_table_out_ptr), *out_num_entries_ptr, *table_data_size_ptr);
1360 dbg("SEP Driver:<-------- sep_construct_dma_tables_from_lli end\n");
1361 return 0;
1362}
1363
1364
1365/*
1366 This function builds input and output DMA tables for synhronic
1367 symmetric operations (AES, DES). It also checks that each table
1368 is of the modular block size
1369*/
1370static int sep_prepare_input_output_dma_table(struct sep_device *sep,
1371 unsigned long app_virt_in_addr,
1372 unsigned long app_virt_out_addr,
1373 unsigned long data_size,
1374 unsigned long block_size,
1375 unsigned long *lli_table_in_ptr, unsigned long *lli_table_out_ptr, unsigned long *in_num_entries_ptr, unsigned long *out_num_entries_ptr, unsigned long *table_data_size_ptr, bool isKernelVirtualAddress)
1376{
1377 /* array of pointers of page */
1378 struct sep_lli_entry_t *lli_in_array;
1379 /* array of pointers of page */
1380 struct sep_lli_entry_t *lli_out_array;
1381 int result = 0;
1382
1383 dbg("SEP Driver:--------> sep_prepare_input_output_dma_table start\n");
1384
1385 /* initialize the pages pointers */
1386 sep->in_page_array = 0;
1387 sep->out_page_array = 0;
1388
1389 /* check if the pages are in Kernel Virtual Address layout */
1390 if (isKernelVirtualAddress == true) {
1391 /* lock the pages of the kernel buffer and translate them to pages */
1392 result = sep_lock_kernel_pages(sep, app_virt_in_addr, data_size, &sep->in_num_pages, &lli_in_array, &sep->in_page_array);
1393 if (result) {
1394 edbg("SEP Driver: sep_lock_kernel_pages for input virtual buffer failed\n");
1395 goto end_function;
1396 }
1397 } else {
1398 /* lock the pages of the user buffer and translate them to pages */
1399 result = sep_lock_user_pages(sep, app_virt_in_addr, data_size, &sep->in_num_pages, &lli_in_array, &sep->in_page_array);
1400 if (result) {
1401 edbg("SEP Driver: sep_lock_user_pages for input virtual buffer failed\n");
1402 goto end_function;
1403 }
1404 }
1405
1406 if (isKernelVirtualAddress == true) {
1407 result = sep_lock_kernel_pages(sep, app_virt_out_addr, data_size, &sep->out_num_pages, &lli_out_array, &sep->out_page_array);
1408 if (result) {
1409 edbg("SEP Driver: sep_lock_kernel_pages for output virtual buffer failed\n");
1410 goto end_function_with_error1;
1411 }
1412 } else {
1413 result = sep_lock_user_pages(sep, app_virt_out_addr, data_size, &sep->out_num_pages, &lli_out_array, &sep->out_page_array);
1414 if (result) {
1415 edbg("SEP Driver: sep_lock_user_pages for output virtual buffer failed\n");
1416 goto end_function_with_error1;
1417 }
1418 }
1419 edbg("sep->in_num_pages is %lu\n", sep->in_num_pages);
1420 edbg("sep->out_num_pages is %lu\n", sep->out_num_pages);
1421 edbg("SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP is %x\n", SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP);
1422
1423
1424 /* call the fucntion that creates table from the lli arrays */
1425 result = sep_construct_dma_tables_from_lli(sep, lli_in_array, sep->in_num_pages, lli_out_array, sep->out_num_pages, block_size, lli_table_in_ptr, lli_table_out_ptr, in_num_entries_ptr, out_num_entries_ptr, table_data_size_ptr);
1426 if (result) {
1427 edbg("SEP Driver: sep_construct_dma_tables_from_lli failed\n");
1428 goto end_function_with_error2;
1429 }
1430
1431 /* fall through - free the lli entry arrays */
1432 dbg("in_num_entries_ptr is %08lx\n", *in_num_entries_ptr);
1433 dbg("out_num_entries_ptr is %08lx\n", *out_num_entries_ptr);
1434 dbg("table_data_size_ptr is %08lx\n", *table_data_size_ptr);
1435end_function_with_error2:
1436 kfree(lli_out_array);
1437end_function_with_error1:
1438 kfree(lli_in_array);
1439end_function:
1440 dbg("SEP Driver:<-------- sep_prepare_input_output_dma_table end result = %d\n", (int) result);
1441 return result;
1442
1443}
1444
1445/*
1446 this function handles tha request for creation of the DMA table
1447 for the synchronic symmetric operations (AES,DES)
1448*/
1449static int sep_create_sync_dma_tables_handler(struct sep_device *sep,
1450 unsigned long arg)
1451{
1452 int error;
1453 /* command arguments */
1454 struct sep_driver_build_sync_table_t command_args;
1455
1456 dbg("SEP Driver:--------> sep_create_sync_dma_tables_handler start\n");
1457
1458 error = copy_from_user(&command_args, (void *) arg, sizeof(struct sep_driver_build_sync_table_t));
1459 if (error) {
1460 error = -EFAULT;
1461 goto end_function;
1462 }
1463
1464 edbg("app_in_address is %08lx\n", command_args.app_in_address);
1465 edbg("app_out_address is %08lx\n", command_args.app_out_address);
1466 edbg("data_size is %lu\n", command_args.data_in_size);
1467 edbg("block_size is %lu\n", command_args.block_size);
1468
1469 /* check if we need to build only input table or input/output */
1470 if (command_args.app_out_address)
1471 /* prepare input and output tables */
1472 error = sep_prepare_input_output_dma_table(sep,
1473 command_args.app_in_address,
1474 command_args.app_out_address,
1475 command_args.data_in_size,
1476 command_args.block_size,
1477 &command_args.in_table_address,
1478 &command_args.out_table_address, &command_args.in_table_num_entries, &command_args.out_table_num_entries, &command_args.table_data_size, command_args.isKernelVirtualAddress);
1479 else
1480 /* prepare input tables */
1481 error = sep_prepare_input_dma_table(sep,
1482 command_args.app_in_address,
1483 command_args.data_in_size, command_args.block_size, &command_args.in_table_address, &command_args.in_table_num_entries, &command_args.table_data_size, command_args.isKernelVirtualAddress);
1484
1485 if (error)
1486 goto end_function;
1487 /* copy to user */
1488 if (copy_to_user((void *) arg, (void *) &command_args, sizeof(struct sep_driver_build_sync_table_t)))
1489 error = -EFAULT;
1490end_function:
1491 dbg("SEP Driver:<-------- sep_create_sync_dma_tables_handler end\n");
1492 return error;
1493}
1494
1495/*
1496 this function handles the request for freeing dma table for synhronic actions
1497*/
1498static int sep_free_dma_table_data_handler(struct sep_device *sep)
1499{
1500 dbg("SEP Driver:--------> sep_free_dma_table_data_handler start\n");
1501
1502 /* free input pages array */
1503 sep_free_dma_pages(sep->in_page_array, sep->in_num_pages, 0);
1504
1505 /* free output pages array if needed */
1506 if (sep->out_page_array)
1507 sep_free_dma_pages(sep->out_page_array, sep->out_num_pages, 1);
1508
1509 /* reset all the values */
1510 sep->in_page_array = 0;
1511 sep->out_page_array = 0;
1512 sep->in_num_pages = 0;
1513 sep->out_num_pages = 0;
1514 dbg("SEP Driver:<-------- sep_free_dma_table_data_handler end\n");
1515 return 0;
1516}
1517
1518/*
1519 this function find a space for the new flow dma table
1520*/
1521static int sep_find_free_flow_dma_table_space(struct sep_device *sep,
1522 unsigned long **table_address_ptr)
1523{
1524 int error = 0;
1525 /* pointer to the id field of the flow dma table */
1526 unsigned long *start_table_ptr;
1527 /* Do not make start_addr unsigned long * unless fixing the offset
1528 computations ! */
1529 void *flow_dma_area_start_addr;
1530 unsigned long *flow_dma_area_end_addr;
1531 /* maximum table size in words */
1532 unsigned long table_size_in_words;
1533
1534 /* find the start address of the flow DMA table area */
1535 flow_dma_area_start_addr = sep->shared_addr + SEP_DRIVER_FLOW_DMA_TABLES_AREA_OFFSET_IN_BYTES;
1536
1537 /* set end address of the flow table area */
1538 flow_dma_area_end_addr = flow_dma_area_start_addr + SEP_DRIVER_FLOW_DMA_TABLES_AREA_SIZE_IN_BYTES;
1539
1540 /* set table size in words */
1541 table_size_in_words = SEP_DRIVER_MAX_FLOW_NUM_ENTRIES_IN_TABLE * (sizeof(struct sep_lli_entry_t) / sizeof(long)) + 2;
1542
1543 /* set the pointer to the start address of DMA area */
1544 start_table_ptr = flow_dma_area_start_addr;
1545
1546 /* find the space for the next table */
1547 while (((*start_table_ptr & 0x7FFFFFFF) != 0) && start_table_ptr < flow_dma_area_end_addr)
1548 start_table_ptr += table_size_in_words;
1549
1550 /* check if we reached the end of floa tables area */
1551 if (start_table_ptr >= flow_dma_area_end_addr)
1552 error = -1;
1553 else
1554 *table_address_ptr = start_table_ptr;
1555
1556 return error;
1557}
1558
1559/*
1560 This function creates one DMA table for flow and returns its data,
1561 and pointer to its info entry
1562*/
1563static int sep_prepare_one_flow_dma_table(struct sep_device *sep,
1564 unsigned long virt_buff_addr,
1565 unsigned long virt_buff_size,
1566 struct sep_lli_entry_t *table_data,
1567 struct sep_lli_entry_t **info_entry_ptr,
1568 struct sep_flow_context_t *flow_data_ptr,
1569 bool isKernelVirtualAddress)
1570{
1571 int error;
1572 /* the range in pages */
1573 unsigned long lli_array_size;
1574 struct sep_lli_entry_t *lli_array;
1575 struct sep_lli_entry_t *flow_dma_table_entry_ptr;
1576 unsigned long *start_dma_table_ptr;
1577 /* total table data counter */
1578 unsigned long dma_table_data_count;
1579 /* pointer that will keep the pointer to the pages of the virtual buffer */
1580 struct page **page_array_ptr;
1581 unsigned long entry_count;
1582
1583 /* find the space for the new table */
1584 error = sep_find_free_flow_dma_table_space(sep, &start_dma_table_ptr);
1585 if (error)
1586 goto end_function;
1587
1588 /* check if the pages are in Kernel Virtual Address layout */
1589 if (isKernelVirtualAddress == true)
1590 /* lock kernel buffer in the memory */
1591 error = sep_lock_kernel_pages(sep, virt_buff_addr, virt_buff_size, &lli_array_size, &lli_array, &page_array_ptr);
1592 else
1593 /* lock user buffer in the memory */
1594 error = sep_lock_user_pages(sep, virt_buff_addr, virt_buff_size, &lli_array_size, &lli_array, &page_array_ptr);
1595
1596 if (error)
1597 goto end_function;
1598
1599 /* set the pointer to page array at the beginning of table - this table is
1600 now considered taken */
1601 *start_dma_table_ptr = lli_array_size;
1602
1603 /* point to the place of the pages pointers of the table */
1604 start_dma_table_ptr++;
1605
1606 /* set the pages pointer */
1607 *start_dma_table_ptr = (unsigned long) page_array_ptr;
1608
1609 /* set the pointer to the first entry */
1610 flow_dma_table_entry_ptr = (struct sep_lli_entry_t *) (++start_dma_table_ptr);
1611
1612 /* now create the entries for table */
1613 for (dma_table_data_count = entry_count = 0; entry_count < lli_array_size; entry_count++) {
1614 flow_dma_table_entry_ptr->physical_address = lli_array[entry_count].physical_address;
1615
1616 flow_dma_table_entry_ptr->block_size = lli_array[entry_count].block_size;
1617
1618 /* set the total data of a table */
1619 dma_table_data_count += lli_array[entry_count].block_size;
1620
1621 flow_dma_table_entry_ptr++;
1622 }
1623
1624 /* set the physical address */
1625 table_data->physical_address = virt_to_phys(start_dma_table_ptr);
1626
1627 /* set the num_entries and total data size */
1628 table_data->block_size = ((lli_array_size + 1) << SEP_NUM_ENTRIES_OFFSET_IN_BITS) | (dma_table_data_count);
1629
1630 /* set the info entry */
1631 flow_dma_table_entry_ptr->physical_address = 0xffffffff;
1632 flow_dma_table_entry_ptr->block_size = 0;
1633
1634 /* set the pointer to info entry */
1635 *info_entry_ptr = flow_dma_table_entry_ptr;
1636
1637 /* the array of the lli entries */
1638 kfree(lli_array);
1639end_function:
1640 return error;
1641}
1642
1643
1644
1645/*
1646 This function creates a list of tables for flow and returns the data for
1647 the first and last tables of the list
1648*/
1649static int sep_prepare_flow_dma_tables(struct sep_device *sep,
1650 unsigned long num_virtual_buffers,
1651 unsigned long first_buff_addr, struct sep_flow_context_t *flow_data_ptr, struct sep_lli_entry_t *first_table_data_ptr, struct sep_lli_entry_t *last_table_data_ptr, bool isKernelVirtualAddress)
1652{
1653 int error;
1654 unsigned long virt_buff_addr;
1655 unsigned long virt_buff_size;
1656 struct sep_lli_entry_t table_data;
1657 struct sep_lli_entry_t *info_entry_ptr;
1658 struct sep_lli_entry_t *prev_info_entry_ptr;
1659 unsigned long i;
1660
1661 /* init vars */
1662 error = 0;
1663 prev_info_entry_ptr = 0;
1664
1665 /* init the first table to default */
1666 table_data.physical_address = 0xffffffff;
1667 first_table_data_ptr->physical_address = 0xffffffff;
1668 table_data.block_size = 0;
1669
1670 for (i = 0; i < num_virtual_buffers; i++) {
1671 /* get the virtual buffer address */
1672 error = get_user(virt_buff_addr, &first_buff_addr);
1673 if (error)
1674 goto end_function;
1675
1676 /* get the virtual buffer size */
1677 first_buff_addr++;
1678 error = get_user(virt_buff_size, &first_buff_addr);
1679 if (error)
1680 goto end_function;
1681
1682 /* advance the address to point to the next pair of address|size */
1683 first_buff_addr++;
1684
1685 /* now prepare the one flow LLI table from the data */
1686 error = sep_prepare_one_flow_dma_table(sep, virt_buff_addr, virt_buff_size, &table_data, &info_entry_ptr, flow_data_ptr, isKernelVirtualAddress);
1687 if (error)
1688 goto end_function;
1689
1690 if (i == 0) {
1691 /* if this is the first table - save it to return to the user
1692 application */
1693 *first_table_data_ptr = table_data;
1694
1695 /* set the pointer to info entry */
1696 prev_info_entry_ptr = info_entry_ptr;
1697 } else {
1698 /* not first table - the previous table info entry should
1699 be updated */
1700 prev_info_entry_ptr->block_size = (0x1 << SEP_INT_FLAG_OFFSET_IN_BITS) | (table_data.block_size);
1701
1702 /* set the pointer to info entry */
1703 prev_info_entry_ptr = info_entry_ptr;
1704 }
1705 }
1706
1707 /* set the last table data */
1708 *last_table_data_ptr = table_data;
1709end_function:
1710 return error;
1711}
1712
1713/*
1714 this function goes over all the flow tables connected to the given
1715 table and deallocate them
1716*/
1717static void sep_deallocated_flow_tables(struct sep_lli_entry_t *first_table_ptr)
1718{
1719 /* id pointer */
1720 unsigned long *table_ptr;
1721 /* end address of the flow dma area */
1722 unsigned long num_entries;
1723 unsigned long num_pages;
1724 struct page **pages_ptr;
1725 /* maximum table size in words */
1726 struct sep_lli_entry_t *info_entry_ptr;
1727
1728 /* set the pointer to the first table */
1729 table_ptr = (unsigned long *) first_table_ptr->physical_address;
1730
1731 /* set the num of entries */
1732 num_entries = (first_table_ptr->block_size >> SEP_NUM_ENTRIES_OFFSET_IN_BITS)
1733 & SEP_NUM_ENTRIES_MASK;
1734
1735 /* go over all the connected tables */
1736 while (*table_ptr != 0xffffffff) {
1737 /* get number of pages */
1738 num_pages = *(table_ptr - 2);
1739
1740 /* get the pointer to the pages */
1741 pages_ptr = (struct page **) (*(table_ptr - 1));
1742
1743 /* free the pages */
1744 sep_free_dma_pages(pages_ptr, num_pages, 1);
1745
1746 /* goto to the info entry */
1747 info_entry_ptr = ((struct sep_lli_entry_t *) table_ptr) + (num_entries - 1);
1748
1749 table_ptr = (unsigned long *) info_entry_ptr->physical_address;
1750 num_entries = (info_entry_ptr->block_size >> SEP_NUM_ENTRIES_OFFSET_IN_BITS) & SEP_NUM_ENTRIES_MASK;
1751 }
1752
1753 return;
1754}
1755
1756/**
1757 * sep_find_flow_context - find a flow
1758 * @sep: the SEP we are working with
1759 * @flow_id: flow identifier
1760 *
1761 * Returns a pointer the matching flow, or NULL if the flow does not
1762 * exist.
1763 */
1764
1765static struct sep_flow_context_t *sep_find_flow_context(struct sep_device *sep,
1766 unsigned long flow_id)
1767{
1768 int count;
1769 /*
1770 * always search for flow with id default first - in case we
1771 * already started working on the flow there can be no situation
1772 * when 2 flows are with default flag
1773 */
1774 for (count = 0; count < SEP_DRIVER_NUM_FLOWS; count++) {
1775 if (sep->flows[count].flow_id == flow_id)
1776 return &sep->flows[count];
1777 }
1778 return NULL;
1779}
1780
1781
1782/*
1783 this function handles the request to create the DMA tables for flow
1784*/
1785static int sep_create_flow_dma_tables_handler(struct sep_device *sep,
1786 unsigned long arg)
1787{
1788 int error = -ENOENT;
1789 struct sep_driver_build_flow_table_t command_args;
1790 /* first table - output */
1791 struct sep_lli_entry_t first_table_data;
1792 /* dma table data */
1793 struct sep_lli_entry_t last_table_data;
1794 /* pointer to the info entry of the previuos DMA table */
1795 struct sep_lli_entry_t *prev_info_entry_ptr;
1796 /* pointer to the flow data strucutre */
1797 struct sep_flow_context_t *flow_context_ptr;
1798
1799 dbg("SEP Driver:--------> sep_create_flow_dma_tables_handler start\n");
1800
1801 /* init variables */
1802 prev_info_entry_ptr = 0;
1803 first_table_data.physical_address = 0xffffffff;
1804
1805 /* find the free structure for flow data */
1806 error = -EINVAL;
1807 flow_context_ptr = sep_find_flow_context(sep, SEP_FREE_FLOW_ID);
1808 if (flow_context_ptr == NULL)
1809 goto end_function;
1810
1811 error = copy_from_user(&command_args, (void *) arg, sizeof(struct sep_driver_build_flow_table_t));
1812 if (error) {
1813 error = -EFAULT;
1814 goto end_function;
1815 }
1816
1817 /* create flow tables */
1818 error = sep_prepare_flow_dma_tables(sep, command_args.num_virtual_buffers, command_args.virt_buff_data_addr, flow_context_ptr, &first_table_data, &last_table_data, command_args.isKernelVirtualAddress);
1819 if (error)
1820 goto end_function_with_error;
1821
1822 /* check if flow is static */
1823 if (!command_args.flow_type)
1824 /* point the info entry of the last to the info entry of the first */
1825 last_table_data = first_table_data;
1826
1827 /* set output params */
1828 command_args.first_table_addr = first_table_data.physical_address;
1829 command_args.first_table_num_entries = ((first_table_data.block_size >> SEP_NUM_ENTRIES_OFFSET_IN_BITS) & SEP_NUM_ENTRIES_MASK);
1830 command_args.first_table_data_size = (first_table_data.block_size & SEP_TABLE_DATA_SIZE_MASK);
1831
1832 /* send the parameters to user application */
1833 error = copy_to_user((void *) arg, &command_args, sizeof(struct sep_driver_build_flow_table_t));
1834 if (error) {
1835 error = -EFAULT;
1836 goto end_function_with_error;
1837 }
1838
1839 /* all the flow created - update the flow entry with temp id */
1840 flow_context_ptr->flow_id = SEP_TEMP_FLOW_ID;
1841
1842 /* set the processing tables data in the context */
1843 if (command_args.input_output_flag == SEP_DRIVER_IN_FLAG)
1844 flow_context_ptr->input_tables_in_process = first_table_data;
1845 else
1846 flow_context_ptr->output_tables_in_process = first_table_data;
1847
1848 goto end_function;
1849
1850end_function_with_error:
1851 /* free the allocated tables */
1852 sep_deallocated_flow_tables(&first_table_data);
1853end_function:
1854 dbg("SEP Driver:<-------- sep_create_flow_dma_tables_handler end\n");
1855 return error;
1856}
1857
1858/*
1859 this function handles add tables to flow
1860*/
1861static int sep_add_flow_tables_handler(struct sep_device *sep, unsigned long arg)
1862{
1863 int error;
1864 unsigned long num_entries;
1865 struct sep_driver_add_flow_table_t command_args;
1866 struct sep_flow_context_t *flow_context_ptr;
1867 /* first dma table data */
1868 struct sep_lli_entry_t first_table_data;
1869 /* last dma table data */
1870 struct sep_lli_entry_t last_table_data;
1871 /* pointer to the info entry of the current DMA table */
1872 struct sep_lli_entry_t *info_entry_ptr;
1873
1874 dbg("SEP Driver:--------> sep_add_flow_tables_handler start\n");
1875
1876 /* get input parameters */
1877 error = copy_from_user(&command_args, (void *) arg, sizeof(struct sep_driver_add_flow_table_t));
1878 if (error) {
1879 error = -EFAULT;
1880 goto end_function;
1881 }
1882
1883 /* find the flow structure for the flow id */
1884 flow_context_ptr = sep_find_flow_context(sep, command_args.flow_id);
1885 if (flow_context_ptr == NULL)
1886 goto end_function;
1887
1888 /* prepare the flow dma tables */
1889 error = sep_prepare_flow_dma_tables(sep, command_args.num_virtual_buffers, command_args.virt_buff_data_addr, flow_context_ptr, &first_table_data, &last_table_data, command_args.isKernelVirtualAddress);
1890 if (error)
1891 goto end_function_with_error;
1892
1893 /* now check if there is already an existing add table for this flow */
1894 if (command_args.inputOutputFlag == SEP_DRIVER_IN_FLAG) {
1895 /* this buffer was for input buffers */
1896 if (flow_context_ptr->input_tables_flag) {
1897 /* add table already exists - add the new tables to the end
1898 of the previous */
1899 num_entries = (flow_context_ptr->last_input_table.block_size >> SEP_NUM_ENTRIES_OFFSET_IN_BITS) & SEP_NUM_ENTRIES_MASK;
1900
1901 info_entry_ptr = (struct sep_lli_entry_t *)
1902 (flow_context_ptr->last_input_table.physical_address + (sizeof(struct sep_lli_entry_t) * (num_entries - 1)));
1903
1904 /* connect to list of tables */
1905 *info_entry_ptr = first_table_data;
1906
1907 /* set the first table data */
1908 first_table_data = flow_context_ptr->first_input_table;
1909 } else {
1910 /* set the input flag */
1911 flow_context_ptr->input_tables_flag = 1;
1912
1913 /* set the first table data */
1914 flow_context_ptr->first_input_table = first_table_data;
1915 }
1916 /* set the last table data */
1917 flow_context_ptr->last_input_table = last_table_data;
1918 } else { /* this is output tables */
1919
1920 /* this buffer was for input buffers */
1921 if (flow_context_ptr->output_tables_flag) {
1922 /* add table already exists - add the new tables to
1923 the end of the previous */
1924 num_entries = (flow_context_ptr->last_output_table.block_size >> SEP_NUM_ENTRIES_OFFSET_IN_BITS) & SEP_NUM_ENTRIES_MASK;
1925
1926 info_entry_ptr = (struct sep_lli_entry_t *)
1927 (flow_context_ptr->last_output_table.physical_address + (sizeof(struct sep_lli_entry_t) * (num_entries - 1)));
1928
1929 /* connect to list of tables */
1930 *info_entry_ptr = first_table_data;
1931
1932 /* set the first table data */
1933 first_table_data = flow_context_ptr->first_output_table;
1934 } else {
1935 /* set the input flag */
1936 flow_context_ptr->output_tables_flag = 1;
1937
1938 /* set the first table data */
1939 flow_context_ptr->first_output_table = first_table_data;
1940 }
1941 /* set the last table data */
1942 flow_context_ptr->last_output_table = last_table_data;
1943 }
1944
1945 /* set output params */
1946 command_args.first_table_addr = first_table_data.physical_address;
1947 command_args.first_table_num_entries = ((first_table_data.block_size >> SEP_NUM_ENTRIES_OFFSET_IN_BITS) & SEP_NUM_ENTRIES_MASK);
1948 command_args.first_table_data_size = (first_table_data.block_size & SEP_TABLE_DATA_SIZE_MASK);
1949
1950 /* send the parameters to user application */
1951 error = copy_to_user((void *) arg, &command_args, sizeof(struct sep_driver_add_flow_table_t));
1952 if (error)
1953 error = -EFAULT;
1954end_function_with_error:
1955 /* free the allocated tables */
1956 sep_deallocated_flow_tables(&first_table_data);
1957end_function:
1958 dbg("SEP Driver:<-------- sep_add_flow_tables_handler end\n");
1959 return error;
1960}
1961
1962/*
1963 this function add the flow add message to the specific flow
1964*/
1965static int sep_add_flow_tables_message_handler(struct sep_device *sep, unsigned long arg)
1966{
1967 int error;
1968 struct sep_driver_add_message_t command_args;
1969 struct sep_flow_context_t *flow_context_ptr;
1970
1971 dbg("SEP Driver:--------> sep_add_flow_tables_message_handler start\n");
1972
1973 error = copy_from_user(&command_args, (void *) arg, sizeof(struct sep_driver_add_message_t));
1974 if (error) {
1975 error = -EFAULT;
1976 goto end_function;
1977 }
1978
1979 /* check input */
1980 if (command_args.message_size_in_bytes > SEP_MAX_ADD_MESSAGE_LENGTH_IN_BYTES) {
1981 error = -ENOMEM;
1982 goto end_function;
1983 }
1984
1985 /* find the flow context */
1986 flow_context_ptr = sep_find_flow_context(sep, command_args.flow_id);
1987 if (flow_context_ptr == NULL)
1988 goto end_function;
1989
1990 /* copy the message into context */
1991 flow_context_ptr->message_size_in_bytes = command_args.message_size_in_bytes;
1992 error = copy_from_user(flow_context_ptr->message, (void *) command_args.message_address, command_args.message_size_in_bytes);
1993 if (error)
1994 error = -EFAULT;
1995end_function:
1996 dbg("SEP Driver:<-------- sep_add_flow_tables_message_handler end\n");
1997 return error;
1998}
1999
2000
2001/*
2002 this function returns the bus and virtual addresses of the static pool
2003*/
2004static int sep_get_static_pool_addr_handler(struct sep_device *sep, unsigned long arg)
2005{
2006 int error;
2007 struct sep_driver_static_pool_addr_t command_args;
2008
2009 dbg("SEP Driver:--------> sep_get_static_pool_addr_handler start\n");
2010
2011 /*prepare the output parameters in the struct */
2012 command_args.physical_static_address = sep->shared_bus + SEP_DRIVER_STATIC_AREA_OFFSET_IN_BYTES;
2013 command_args.virtual_static_address = (unsigned long)sep->shared_addr + SEP_DRIVER_STATIC_AREA_OFFSET_IN_BYTES;
2014
2015 edbg("SEP Driver:bus_static_address is %08lx, virtual_static_address %08lx\n", command_args.physical_static_address, command_args.virtual_static_address);
2016
2017 /* send the parameters to user application */
2018 error = copy_to_user((void *) arg, &command_args, sizeof(struct sep_driver_static_pool_addr_t));
2019 if (error)
2020 error = -EFAULT;
2021 dbg("SEP Driver:<-------- sep_get_static_pool_addr_handler end\n");
2022 return error;
2023}
2024
2025/*
2026 this address gets the offset of the physical address from the start
2027 of the mapped area
2028*/
2029static int sep_get_physical_mapped_offset_handler(struct sep_device *sep, unsigned long arg)
2030{
2031 int error;
2032 struct sep_driver_get_mapped_offset_t command_args;
2033
2034 dbg("SEP Driver:--------> sep_get_physical_mapped_offset_handler start\n");
2035
2036 error = copy_from_user(&command_args, (void *) arg, sizeof(struct sep_driver_get_mapped_offset_t));
2037 if (error) {
2038 error = -EFAULT;
2039 goto end_function;
2040 }
2041
2042 if (command_args.physical_address < sep->shared_bus) {
2043 error = -EINVAL;
2044 goto end_function;
2045 }
2046
2047 /*prepare the output parameters in the struct */
2048 command_args.offset = command_args.physical_address - sep->shared_bus;
2049
2050 edbg("SEP Driver:bus_address is %08lx, offset is %lu\n", command_args.physical_address, command_args.offset);
2051
2052 /* send the parameters to user application */
2053 error = copy_to_user((void *) arg, &command_args, sizeof(struct sep_driver_get_mapped_offset_t));
2054 if (error)
2055 error = -EFAULT;
2056end_function:
2057 dbg("SEP Driver:<-------- sep_get_physical_mapped_offset_handler end\n");
2058 return error;
2059}
2060
2061
2062/*
2063 ?
2064*/
2065static int sep_start_handler(struct sep_device *sep)
2066{
2067 unsigned long reg_val;
2068 unsigned long error = 0;
2069
2070 dbg("SEP Driver:--------> sep_start_handler start\n");
2071
2072 /* wait in polling for message from SEP */
2073 do
2074 reg_val = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR3_REG_ADDR);
2075 while (!reg_val);
2076
2077 /* check the value */
2078 if (reg_val == 0x1)
2079 /* fatal error - read error status from GPRO */
2080 error = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR0_REG_ADDR);
2081 dbg("SEP Driver:<-------- sep_start_handler end\n");
2082 return error;
2083}
2084
2085/*
2086 this function handles the request for SEP initialization
2087*/
2088static int sep_init_handler(struct sep_device *sep, unsigned long arg)
2089{
2090 unsigned long message_word;
2091 unsigned long *message_ptr;
2092 struct sep_driver_init_t command_args;
2093 unsigned long counter;
2094 unsigned long error;
2095 unsigned long reg_val;
2096
2097 dbg("SEP Driver:--------> sep_init_handler start\n");
2098 error = 0;
2099
2100 error = copy_from_user(&command_args, (void *) arg, sizeof(struct sep_driver_init_t));
2101 if (error) {
2102 error = -EFAULT;
2103 goto end_function;
2104 }
2105 dbg("SEP Driver:--------> sep_init_handler - finished copy_from_user\n");
2106
2107 /* PATCH - configure the DMA to single -burst instead of multi-burst */
2108 /*sep_configure_dma_burst(); */
2109
2110 dbg("SEP Driver:--------> sep_init_handler - finished sep_configure_dma_burst \n");
2111
2112 message_ptr = (unsigned long *) command_args.message_addr;
2113
2114 /* set the base address of the SRAM */
2115 sep_write_reg(sep, HW_SRAM_ADDR_REG_ADDR, HW_CC_SRAM_BASE_ADDRESS);
2116
2117 for (counter = 0; counter < command_args.message_size_in_words; counter++, message_ptr++) {
2118 get_user(message_word, message_ptr);
2119 /* write data to SRAM */
2120 sep_write_reg(sep, HW_SRAM_DATA_REG_ADDR, message_word);
2121 edbg("SEP Driver:message_word is %lu\n", message_word);
2122 /* wait for write complete */
2123 sep_wait_sram_write(sep);
2124 }
2125 dbg("SEP Driver:--------> sep_init_handler - finished getting messages from user space\n");
2126 /* signal SEP */
2127 sep_write_reg(sep, HW_HOST_HOST_SEP_GPR0_REG_ADDR, 0x1);
2128
2129 do
2130 reg_val = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR3_REG_ADDR);
2131 while (!(reg_val & 0xFFFFFFFD));
2132
2133 dbg("SEP Driver:--------> sep_init_handler - finished waiting for reg_val & 0xFFFFFFFD \n");
2134
2135 /* check the value */
2136 if (reg_val == 0x1) {
2137 edbg("SEP Driver:init failed\n");
2138
2139 error = sep_read_reg(sep, 0x8060);
2140 edbg("SEP Driver:sw monitor is %lu\n", error);
2141
2142 /* fatal error - read erro status from GPRO */
2143 error = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR0_REG_ADDR);
2144 edbg("SEP Driver:error is %lu\n", error);
2145 }
2146end_function:
2147 dbg("SEP Driver:<-------- sep_init_handler end\n");
2148 return error;
2149
2150}
2151
2152/*
2153 this function handles the request cache and resident reallocation
2154*/
2155static int sep_realloc_cache_resident_handler(struct sep_device *sep,
2156 unsigned long arg)
2157{
2158 struct sep_driver_realloc_cache_resident_t command_args;
2159 int error;
2160
2161 /* copy cache and resident to the their intended locations */
2162 error = sep_load_firmware(sep);
2163 if (error)
2164 return error;
2165
2166 command_args.new_base_addr = sep->shared_bus;
2167
2168 /* find the new base address according to the lowest address between
2169 cache, resident and shared area */
2170 if (sep->resident_bus < command_args.new_base_addr)
2171 command_args.new_base_addr = sep->resident_bus;
2172 if (sep->rar_bus < command_args.new_base_addr)
2173 command_args.new_base_addr = sep->rar_bus;
2174
2175 /* set the return parameters */
2176 command_args.new_cache_addr = sep->rar_bus;
2177 command_args.new_resident_addr = sep->resident_bus;
2178
2179 /* set the new shared area */
2180 command_args.new_shared_area_addr = sep->shared_bus;
2181
2182 edbg("SEP Driver:command_args.new_shared_addr is %08llx\n", command_args.new_shared_area_addr);
2183 edbg("SEP Driver:command_args.new_base_addr is %08llx\n", command_args.new_base_addr);
2184 edbg("SEP Driver:command_args.new_resident_addr is %08llx\n", command_args.new_resident_addr);
2185 edbg("SEP Driver:command_args.new_rar_addr is %08llx\n", command_args.new_cache_addr);
2186
2187 /* return to user */
2188 if (copy_to_user((void *) arg, &command_args, sizeof(struct sep_driver_realloc_cache_resident_t)))
2189 return -EFAULT;
2190 return 0;
2191}
2192
2193/**
2194 * sep_get_time_handler - time request from user space
2195 * @sep: sep we are to set the time for
2196 * @arg: pointer to user space arg buffer
2197 *
2198 * This function reports back the time and the address in the SEP
2199 * shared buffer at which it has been placed. (Do we really need this!!!)
2200 */
2201
2202static int sep_get_time_handler(struct sep_device *sep, unsigned long arg)
2203{
2204 struct sep_driver_get_time_t command_args;
2205
2206 mutex_lock(&sep_mutex);
2207 command_args.time_value = sep_set_time(sep);
2208 command_args.time_physical_address = (unsigned long)sep_time_address(sep);
2209 mutex_unlock(&sep_mutex);
2210 if (copy_to_user((void __user *)arg,
2211 &command_args, sizeof(struct sep_driver_get_time_t)))
2212 return -EFAULT;
2213 return 0;
2214
2215}
2216
2217/*
2218 This API handles the end transaction request
2219*/
2220static int sep_end_transaction_handler(struct sep_device *sep, unsigned long arg)
2221{
2222 dbg("SEP Driver:--------> sep_end_transaction_handler start\n");
2223
2224#if 0 /*!SEP_DRIVER_POLLING_MODE */
2225 /* close IMR */
2226 sep_write_reg(sep, HW_HOST_IMR_REG_ADDR, 0x7FFF);
2227
2228 /* release IRQ line */
2229 free_irq(SEP_DIRVER_IRQ_NUM, sep);
2230
2231 /* lock the sep mutex */
2232 mutex_unlock(&sep_mutex);
2233#endif
2234
2235 dbg("SEP Driver:<-------- sep_end_transaction_handler end\n");
2236
2237 return 0;
2238}
2239
2240
2241/**
2242 * sep_set_flow_id_handler - handle flow setting
2243 * @sep: the SEP we are configuring
2244 * @flow_id: the flow we are setting
2245 *
2246 * This function handler the set flow id command
2247 */
2248static int sep_set_flow_id_handler(struct sep_device *sep,
2249 unsigned long flow_id)
2250{
2251 int error = 0;
2252 struct sep_flow_context_t *flow_data_ptr;
2253
2254 /* find the flow data structure that was just used for creating new flow
2255 - its id should be default */
2256
2257 mutex_lock(&sep_mutex);
2258 flow_data_ptr = sep_find_flow_context(sep, SEP_TEMP_FLOW_ID);
2259 if (flow_data_ptr)
2260 flow_data_ptr->flow_id = flow_id; /* set flow id */
2261 else
2262 error = -EINVAL;
2263 mutex_unlock(&sep_mutex);
2264 return error;
2265}
2266
2267static long sep_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
2268{
2269 int error = 0;
2270 struct sep_device *sep = filp->private_data;
2271
2272 dbg("------------>SEP Driver: ioctl start\n");
2273
2274 edbg("SEP Driver: cmd is %x\n", cmd);
2275
2276 switch (cmd) {
2277 case SEP_IOCSENDSEPCOMMAND:
2278 /* send command to SEP */
2279 sep_send_command_handler(sep);
2280 edbg("SEP Driver: after sep_send_command_handler\n");
2281 break;
2282 case SEP_IOCSENDSEPRPLYCOMMAND:
2283 /* send reply command to SEP */
2284 sep_send_reply_command_handler(sep);
2285 break;
2286 case SEP_IOCALLOCDATAPOLL:
2287 /* allocate data pool */
2288 error = sep_allocate_data_pool_memory_handler(sep, arg);
2289 break;
2290 case SEP_IOCWRITEDATAPOLL:
2291 /* write data into memory pool */
2292 error = sep_write_into_data_pool_handler(sep, arg);
2293 break;
2294 case SEP_IOCREADDATAPOLL:
2295 /* read data from data pool into application memory */
2296 error = sep_read_from_data_pool_handler(sep, arg);
2297 break;
2298 case SEP_IOCCREATESYMDMATABLE:
2299 /* create dma table for synhronic operation */
2300 error = sep_create_sync_dma_tables_handler(sep, arg);
2301 break;
2302 case SEP_IOCCREATEFLOWDMATABLE:
2303 /* create flow dma tables */
2304 error = sep_create_flow_dma_tables_handler(sep, arg);
2305 break;
2306 case SEP_IOCFREEDMATABLEDATA:
2307 /* free the pages */
2308 error = sep_free_dma_table_data_handler(sep);
2309 break;
2310 case SEP_IOCSETFLOWID:
2311 /* set flow id */
2312 error = sep_set_flow_id_handler(sep, (unsigned long)arg);
2313 break;
2314 case SEP_IOCADDFLOWTABLE:
2315 /* add tables to the dynamic flow */
2316 error = sep_add_flow_tables_handler(sep, arg);
2317 break;
2318 case SEP_IOCADDFLOWMESSAGE:
2319 /* add message of add tables to flow */
2320 error = sep_add_flow_tables_message_handler(sep, arg);
2321 break;
2322 case SEP_IOCSEPSTART:
2323 /* start command to sep */
2324 error = sep_start_handler(sep);
2325 break;
2326 case SEP_IOCSEPINIT:
2327 /* init command to sep */
2328 error = sep_init_handler(sep, arg);
2329 break;
2330 case SEP_IOCGETSTATICPOOLADDR:
2331 /* get the physical and virtual addresses of the static pool */
2332 error = sep_get_static_pool_addr_handler(sep, arg);
2333 break;
2334 case SEP_IOCENDTRANSACTION:
2335 error = sep_end_transaction_handler(sep, arg);
2336 break;
2337 case SEP_IOCREALLOCCACHERES:
2338 error = sep_realloc_cache_resident_handler(sep, arg);
2339 break;
2340 case SEP_IOCGETMAPPEDADDROFFSET:
2341 error = sep_get_physical_mapped_offset_handler(sep, arg);
2342 break;
2343 case SEP_IOCGETIME:
2344 error = sep_get_time_handler(sep, arg);
2345 break;
2346 default:
2347 error = -ENOTTY;
2348 break;
2349 }
2350 dbg("SEP Driver:<-------- ioctl end\n");
2351 return error;
2352}
2353
2354
2355
2356#if !SEP_DRIVER_POLLING_MODE
2357
2358/* handler for flow done interrupt */
2359
2360static void sep_flow_done_handler(struct work_struct *work)
2361{
2362 struct sep_flow_context_t *flow_data_ptr;
2363
2364 /* obtain the mutex */
2365 mutex_lock(&sep_mutex);
2366
2367 /* get the pointer to context */
2368 flow_data_ptr = (struct sep_flow_context_t *) work;
2369
2370 /* free all the current input tables in sep */
2371 sep_deallocated_flow_tables(&flow_data_ptr->input_tables_in_process);
2372
2373 /* free all the current tables output tables in SEP (if needed) */
2374 if (flow_data_ptr->output_tables_in_process.physical_address != 0xffffffff)
2375 sep_deallocated_flow_tables(&flow_data_ptr->output_tables_in_process);
2376
2377 /* check if we have additional tables to be sent to SEP only input
2378 flag may be checked */
2379 if (flow_data_ptr->input_tables_flag) {
2380 /* copy the message to the shared RAM and signal SEP */
2381 memcpy((void *) flow_data_ptr->message, (void *) sep->shared_addr, flow_data_ptr->message_size_in_bytes);
2382
2383 sep_write_reg(sep, HW_HOST_HOST_SEP_GPR2_REG_ADDR, 0x2);
2384 }
2385 mutex_unlock(&sep_mutex);
2386}
2387/*
2388 interrupt handler function
2389*/
2390static irqreturn_t sep_inthandler(int irq, void *dev_id)
2391{
2392 irqreturn_t int_error;
2393 unsigned long reg_val;
2394 unsigned long flow_id;
2395 struct sep_flow_context_t *flow_context_ptr;
2396 struct sep_device *sep = dev_id;
2397
2398 int_error = IRQ_HANDLED;
2399
2400 /* read the IRR register to check if this is SEP interrupt */
2401 reg_val = sep_read_reg(sep, HW_HOST_IRR_REG_ADDR);
2402 edbg("SEP Interrupt - reg is %08lx\n", reg_val);
2403
2404 /* check if this is the flow interrupt */
2405 if (0 /*reg_val & (0x1 << 11) */ ) {
2406 /* read GPRO to find out the which flow is done */
2407 flow_id = sep_read_reg(sep, HW_HOST_IRR_REG_ADDR);
2408
2409 /* find the contex of the flow */
2410 flow_context_ptr = sep_find_flow_context(sep, flow_id >> 28);
2411 if (flow_context_ptr == NULL)
2412 goto end_function_with_error;
2413
2414 /* queue the work */
2415 INIT_WORK(&flow_context_ptr->flow_wq, sep_flow_done_handler);
2416 queue_work(sep->flow_wq, &flow_context_ptr->flow_wq);
2417
2418 } else {
2419 /* check if this is reply interrupt from SEP */
2420 if (reg_val & (0x1 << 13)) {
2421 /* update the counter of reply messages */
2422 sep->reply_ct++;
2423 /* wake up the waiting process */
2424 wake_up(&sep_event);
2425 } else {
2426 int_error = IRQ_NONE;
2427 goto end_function;
2428 }
2429 }
2430end_function_with_error:
2431 /* clear the interrupt */
2432 sep_write_reg(sep, HW_HOST_ICR_REG_ADDR, reg_val);
2433end_function:
2434 return int_error;
2435}
2436
2437#endif
2438
2439
2440
2441#if 0
2442
2443static void sep_wait_busy(struct sep_device *sep)
2444{
2445 u32 reg;
2446
2447 do {
2448 reg = sep_read_reg(sep, HW_HOST_SEP_BUSY_REG_ADDR);
2449 } while (reg);
2450}
2451
2452/*
2453 PATCH for configuring the DMA to single burst instead of multi-burst
2454*/
2455static void sep_configure_dma_burst(struct sep_device *sep)
2456{
2457#define HW_AHB_RD_WR_BURSTS_REG_ADDR 0x0E10UL
2458
2459 dbg("SEP Driver:<-------- sep_configure_dma_burst start \n");
2460
2461 /* request access to registers from SEP */
2462 sep_write_reg(sep, HW_HOST_HOST_SEP_GPR0_REG_ADDR, 0x2);
2463
2464 dbg("SEP Driver:<-------- sep_configure_dma_burst finished request access to registers from SEP (write reg) \n");
2465
2466 sep_wait_busy(sep);
2467
2468 dbg("SEP Driver:<-------- sep_configure_dma_burst finished request access to registers from SEP (while(revVal) wait loop) \n");
2469
2470 /* set the DMA burst register to single burst */
2471 sep_write_reg(sep, HW_AHB_RD_WR_BURSTS_REG_ADDR, 0x0UL);
2472
2473 /* release the sep busy */
2474 sep_write_reg(sep, HW_HOST_HOST_SEP_GPR0_REG_ADDR, 0x0UL);
2475 sep_wait_busy(sep);
2476
2477 dbg("SEP Driver:<-------- sep_configure_dma_burst done \n");
2478
2479}
2480
2481#endif
2482
2483/*
2484 Function that is activated on the successful probe of the SEP device
2485*/
2486static int __devinit sep_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
2487{
2488 int error = 0;
2489 struct sep_device *sep;
2490 int counter;
2491 int size; /* size of memory for allocation */
2492
2493 edbg("Sep pci probe starting\n");
2494 if (sep_dev != NULL) {
2495 dev_warn(&pdev->dev, "only one SEP supported.\n");
2496 return -EBUSY;
2497 }
2498
2499 /* enable the device */
2500 error = pci_enable_device(pdev);
2501 if (error) {
2502 edbg("error enabling pci device\n");
2503 goto end_function;
2504 }
2505
2506 /* set the pci dev pointer */
2507 sep_dev = &sep_instance;
2508 sep = &sep_instance;
2509
2510 edbg("sep->shared_addr = %p\n", sep->shared_addr);
2511 /* transaction counter that coordinates the transactions between SEP
2512 and HOST */
2513 sep->send_ct = 0;
2514 /* counter for the messages from sep */
2515 sep->reply_ct = 0;
2516 /* counter for the number of bytes allocated in the pool
2517 for the current transaction */
2518 sep->data_pool_bytes_allocated = 0;
2519
2520 /* calculate the total size for allocation */
2521 size = SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES +
2522 SEP_DRIVER_SYNCHRONIC_DMA_TABLES_AREA_SIZE_IN_BYTES + SEP_DRIVER_DATA_POOL_SHARED_AREA_SIZE_IN_BYTES + SEP_DRIVER_FLOW_DMA_TABLES_AREA_SIZE_IN_BYTES + SEP_DRIVER_STATIC_AREA_SIZE_IN_BYTES + SEP_DRIVER_SYSTEM_DATA_MEMORY_SIZE_IN_BYTES;
2523
2524 /* allocate the shared area */
2525 if (sep_map_and_alloc_shared_area(sep, size)) {
2526 error = -ENOMEM;
2527 /* allocation failed */
2528 goto end_function_error;
2529 }
2530 /* now set the memory regions */
2531#if (SEP_DRIVER_RECONFIG_MESSAGE_AREA == 1)
2532 /* Note: this test section will need moving before it could ever
2533 work as the registers are not yet mapped ! */
2534 /* send the new SHARED MESSAGE AREA to the SEP */
2535 sep_write_reg(sep, HW_HOST_HOST_SEP_GPR1_REG_ADDR, sep->shared_bus);
2536
2537 /* poll for SEP response */
2538 retval = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR1_REG_ADDR);
2539 while (retval != 0xffffffff && retval != sep->shared_bus)
2540 retval = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR1_REG_ADDR);
2541
2542 /* check the return value (register) */
2543 if (retval != sep->shared_bus) {
2544 error = -ENOMEM;
2545 goto end_function_deallocate_sep_shared_area;
2546 }
2547#endif
2548 /* init the flow contextes */
2549 for (counter = 0; counter < SEP_DRIVER_NUM_FLOWS; counter++)
2550 sep->flows[counter].flow_id = SEP_FREE_FLOW_ID;
2551
2552 sep->flow_wq = create_singlethread_workqueue("sepflowwq");
2553 if (sep->flow_wq == NULL) {
2554 error = -ENOMEM;
2555 edbg("sep_driver:flow queue creation failed\n");
2556 goto end_function_deallocate_sep_shared_area;
2557 }
2558 edbg("SEP Driver: create flow workqueue \n");
2559 sep->pdev = pci_dev_get(pdev);
2560
2561 sep->reg_addr = pci_ioremap_bar(pdev, 0);
2562 if (!sep->reg_addr) {
2563 edbg("sep: ioremap of registers failed.\n");
2564 goto end_function_deallocate_sep_shared_area;
2565 }
2566 edbg("SEP Driver:reg_addr is %p\n", sep->reg_addr);
2567
2568 /* load the rom code */
2569 sep_load_rom_code(sep);
2570
2571 /* set up system base address and shared memory location */
2572 sep->rar_addr = dma_alloc_coherent(&sep->pdev->dev,
2573 2 * SEP_RAR_IO_MEM_REGION_SIZE,
2574 &sep->rar_bus, GFP_KERNEL);
2575
2576 if (!sep->rar_addr) {
2577 edbg("SEP Driver:can't allocate rar\n");
2578 goto end_function_uniomap;
2579 }
2580
2581
2582 edbg("SEP Driver:rar_bus is %08llx\n", (unsigned long long)sep->rar_bus);
2583 edbg("SEP Driver:rar_virtual is %p\n", sep->rar_addr);
2584
2585#if !SEP_DRIVER_POLLING_MODE
2586
2587 edbg("SEP Driver: about to write IMR and ICR REG_ADDR\n");
2588
2589 /* clear ICR register */
2590 sep_write_reg(sep, HW_HOST_ICR_REG_ADDR, 0xFFFFFFFF);
2591
2592 /* set the IMR register - open only GPR 2 */
2593 sep_write_reg(sep, HW_HOST_IMR_REG_ADDR, (~(0x1 << 13)));
2594
2595 edbg("SEP Driver: about to call request_irq\n");
2596 /* get the interrupt line */
2597 error = request_irq(pdev->irq, sep_inthandler, IRQF_SHARED, "sep_driver", sep);
2598 if (error)
2599 goto end_function_free_res;
2600 return 0;
2601 edbg("SEP Driver: about to write IMR REG_ADDR");
2602
2603 /* set the IMR register - open only GPR 2 */
2604 sep_write_reg(sep, HW_HOST_IMR_REG_ADDR, (~(0x1 << 13)));
2605
2606end_function_free_res:
2607 dma_free_coherent(&sep->pdev->dev, 2 * SEP_RAR_IO_MEM_REGION_SIZE,
2608 sep->rar_addr, sep->rar_bus);
2609#endif /* SEP_DRIVER_POLLING_MODE */
2610end_function_uniomap:
2611 iounmap(sep->reg_addr);
2612end_function_deallocate_sep_shared_area:
2613 /* de-allocate shared area */
2614 sep_unmap_and_free_shared_area(sep, size);
2615end_function_error:
2616 sep_dev = NULL;
2617end_function:
2618 return error;
2619}
2620
2621static const struct pci_device_id sep_pci_id_tbl[] = {
2622 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x080c)},
2623 {0}
2624};
2625
2626MODULE_DEVICE_TABLE(pci, sep_pci_id_tbl);
2627
2628/* field for registering driver to PCI device */
2629static struct pci_driver sep_pci_driver = {
2630 .name = "sep_sec_driver",
2631 .id_table = sep_pci_id_tbl,
2632 .probe = sep_probe
2633 /* FIXME: remove handler */
2634};
2635
2636/* major and minor device numbers */
2637static dev_t sep_devno;
2638
2639/* the files operations structure of the driver */
2640static struct file_operations sep_file_operations = {
2641 .owner = THIS_MODULE,
2642 .unlocked_ioctl = sep_ioctl,
2643 .poll = sep_poll,
2644 .open = sep_open,
2645 .release = sep_release,
2646 .mmap = sep_mmap,
2647};
2648
2649
2650/* cdev struct of the driver */
2651static struct cdev sep_cdev;
2652
2653/*
2654 this function registers the driver to the file system
2655*/
2656static int sep_register_driver_to_fs(void)
2657{
2658 int ret_val = alloc_chrdev_region(&sep_devno, 0, 1, "sep_sec_driver");
2659 if (ret_val) {
2660 edbg("sep: major number allocation failed, retval is %d\n",
2661 ret_val);
2662 return ret_val;
2663 }
2664 /* init cdev */
2665 cdev_init(&sep_cdev, &sep_file_operations);
2666 sep_cdev.owner = THIS_MODULE;
2667
2668 /* register the driver with the kernel */
2669 ret_val = cdev_add(&sep_cdev, sep_devno, 1);
2670 if (ret_val) {
2671 edbg("sep_driver:cdev_add failed, retval is %d\n", ret_val);
2672 /* unregister dev numbers */
2673 unregister_chrdev_region(sep_devno, 1);
2674 }
2675 return ret_val;
2676}
2677
2678
2679/*--------------------------------------------------------------
2680 init function
2681----------------------------------------------------------------*/
2682static int __init sep_init(void)
2683{
2684 int ret_val = 0;
2685 dbg("SEP Driver:-------->Init start\n");
2686 /* FIXME: Probe can occur before we are ready to survive a probe */
2687 ret_val = pci_register_driver(&sep_pci_driver);
2688 if (ret_val) {
2689 edbg("sep_driver:sep_driver_to_device failed, ret_val is %d\n", ret_val);
2690 goto end_function_unregister_from_fs;
2691 }
2692 /* register driver to fs */
2693 ret_val = sep_register_driver_to_fs();
2694 if (ret_val)
2695 goto end_function_unregister_pci;
2696 goto end_function;
2697end_function_unregister_pci:
2698 pci_unregister_driver(&sep_pci_driver);
2699end_function_unregister_from_fs:
2700 /* unregister from fs */
2701 cdev_del(&sep_cdev);
2702 /* unregister dev numbers */
2703 unregister_chrdev_region(sep_devno, 1);
2704end_function:
2705 dbg("SEP Driver:<-------- Init end\n");
2706 return ret_val;
2707}
2708
2709
2710/*-------------------------------------------------------------
2711 exit function
2712--------------------------------------------------------------*/
2713static void __exit sep_exit(void)
2714{
2715 int size;
2716
2717 dbg("SEP Driver:--------> Exit start\n");
2718
2719 /* unregister from fs */
2720 cdev_del(&sep_cdev);
2721 /* unregister dev numbers */
2722 unregister_chrdev_region(sep_devno, 1);
2723 /* calculate the total size for de-allocation */
2724 size = SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES +
2725 SEP_DRIVER_SYNCHRONIC_DMA_TABLES_AREA_SIZE_IN_BYTES + SEP_DRIVER_DATA_POOL_SHARED_AREA_SIZE_IN_BYTES + SEP_DRIVER_FLOW_DMA_TABLES_AREA_SIZE_IN_BYTES + SEP_DRIVER_STATIC_AREA_SIZE_IN_BYTES + SEP_DRIVER_SYSTEM_DATA_MEMORY_SIZE_IN_BYTES;
2726 /* FIXME: We need to do this in the unload for the device */
2727 /* free shared area */
2728 if (sep_dev) {
2729 sep_unmap_and_free_shared_area(sep_dev, size);
2730 edbg("SEP Driver: free pages SEP SHARED AREA \n");
2731 iounmap((void *) sep_dev->reg_addr);
2732 edbg("SEP Driver: iounmap \n");
2733 }
2734 edbg("SEP Driver: release_mem_region \n");
2735 dbg("SEP Driver:<-------- Exit end\n");
2736}
2737
2738
2739module_init(sep_init);
2740module_exit(sep_exit);
2741
2742MODULE_LICENSE("GPL");
diff --git a/drivers/staging/sep/sep_driver_api.h b/drivers/staging/sep/sep_driver_api.h
deleted file mode 100644
index 7ef16da7c4ef..000000000000
--- a/drivers/staging/sep/sep_driver_api.h
+++ /dev/null
@@ -1,425 +0,0 @@
1/*
2 *
3 * sep_driver_api.h - Security Processor Driver api definitions
4 *
5 * Copyright(c) 2009 Intel Corporation. All rights reserved.
6 * Copyright(c) 2009 Discretix. All rights reserved.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the Free
10 * Software Foundation; either version 2 of the License, or (at your option)
11 * any later version.
12 *
13 * This program is distributed in the hope that it will be useful, but WITHOUT
14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 * more details.
17 *
18 * You should have received a copy of the GNU General Public License along with
19 * this program; if not, write to the Free Software Foundation, Inc., 59
20 * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 *
22 * CONTACTS:
23 *
24 * Mark Allyn mark.a.allyn@intel.com
25 *
26 * CHANGES:
27 *
28 * 2009.06.26 Initial publish
29 *
30 */
31
32#ifndef __SEP_DRIVER_API_H__
33#define __SEP_DRIVER_API_H__
34
35
36
37/*----------------------------------------------------------------
38 IOCTL command defines
39 -----------------------------------------------------------------*/
40
41/* magic number 1 of the sep IOCTL command */
42#define SEP_IOC_MAGIC_NUMBER 's'
43
44/* sends interrupt to sep that message is ready */
45#define SEP_IOCSENDSEPCOMMAND _IO(SEP_IOC_MAGIC_NUMBER , 0)
46
47/* sends interrupt to sep that message is ready */
48#define SEP_IOCSENDSEPRPLYCOMMAND _IO(SEP_IOC_MAGIC_NUMBER , 1)
49
50/* allocate memory in data pool */
51#define SEP_IOCALLOCDATAPOLL _IO(SEP_IOC_MAGIC_NUMBER , 2)
52
53/* write to pre-allocated memory in data pool */
54#define SEP_IOCWRITEDATAPOLL _IO(SEP_IOC_MAGIC_NUMBER , 3)
55
56/* read from pre-allocated memory in data pool */
57#define SEP_IOCREADDATAPOLL _IO(SEP_IOC_MAGIC_NUMBER , 4)
58
59/* create sym dma lli tables */
60#define SEP_IOCCREATESYMDMATABLE _IO(SEP_IOC_MAGIC_NUMBER , 5)
61
62/* create flow dma lli tables */
63#define SEP_IOCCREATEFLOWDMATABLE _IO(SEP_IOC_MAGIC_NUMBER , 6)
64
65/* free dynamic data aalocated during table creation */
66#define SEP_IOCFREEDMATABLEDATA _IO(SEP_IOC_MAGIC_NUMBER , 7)
67
68/* get the static pool area addresses (physical and virtual) */
69#define SEP_IOCGETSTATICPOOLADDR _IO(SEP_IOC_MAGIC_NUMBER , 8)
70
71/* set flow id command */
72#define SEP_IOCSETFLOWID _IO(SEP_IOC_MAGIC_NUMBER , 9)
73
74/* add tables to the dynamic flow */
75#define SEP_IOCADDFLOWTABLE _IO(SEP_IOC_MAGIC_NUMBER , 10)
76
77/* add flow add tables message */
78#define SEP_IOCADDFLOWMESSAGE _IO(SEP_IOC_MAGIC_NUMBER , 11)
79
80/* start sep command */
81#define SEP_IOCSEPSTART _IO(SEP_IOC_MAGIC_NUMBER , 12)
82
83/* init sep command */
84#define SEP_IOCSEPINIT _IO(SEP_IOC_MAGIC_NUMBER , 13)
85
86/* end transaction command */
87#define SEP_IOCENDTRANSACTION _IO(SEP_IOC_MAGIC_NUMBER , 15)
88
89/* reallocate cache and resident */
90#define SEP_IOCREALLOCCACHERES _IO(SEP_IOC_MAGIC_NUMBER , 16)
91
92/* get the offset of the address starting from the beginnnig of the map area */
93#define SEP_IOCGETMAPPEDADDROFFSET _IO(SEP_IOC_MAGIC_NUMBER , 17)
94
95/* get time address and value */
96#define SEP_IOCGETIME _IO(SEP_IOC_MAGIC_NUMBER , 19)
97
98/*-------------------------------------------
99 TYPEDEFS
100----------------------------------------------*/
101
102/*
103 init command struct
104*/
105struct sep_driver_init_t {
106 /* start of the 1G of the host memory address that SEP can access */
107 unsigned long message_addr;
108
109 /* start address of resident */
110 unsigned long message_size_in_words;
111
112};
113
114
115/*
116 realloc cache resident command
117*/
118struct sep_driver_realloc_cache_resident_t {
119 /* new cache address */
120 u64 new_cache_addr;
121 /* new resident address */
122 u64 new_resident_addr;
123 /* new resident address */
124 u64 new_shared_area_addr;
125 /* new base address */
126 u64 new_base_addr;
127};
128
129struct sep_driver_alloc_t {
130 /* virtual address of allocated space */
131 unsigned long offset;
132
133 /* physical address of allocated space */
134 unsigned long phys_address;
135
136 /* number of bytes to allocate */
137 unsigned long num_bytes;
138};
139
140/*
141 */
142struct sep_driver_write_t {
143 /* application space address */
144 unsigned long app_address;
145
146 /* address of the data pool */
147 unsigned long datapool_address;
148
149 /* number of bytes to write */
150 unsigned long num_bytes;
151};
152
153/*
154 */
155struct sep_driver_read_t {
156 /* application space address */
157 unsigned long app_address;
158
159 /* address of the data pool */
160 unsigned long datapool_address;
161
162 /* number of bytes to read */
163 unsigned long num_bytes;
164};
165
166/*
167*/
168struct sep_driver_build_sync_table_t {
169 /* address value of the data in */
170 unsigned long app_in_address;
171
172 /* size of data in */
173 unsigned long data_in_size;
174
175 /* address of the data out */
176 unsigned long app_out_address;
177
178 /* the size of the block of the operation - if needed,
179 every table will be modulo this parameter */
180 unsigned long block_size;
181
182 /* the physical address of the first input DMA table */
183 unsigned long in_table_address;
184
185 /* number of entries in the first input DMA table */
186 unsigned long in_table_num_entries;
187
188 /* the physical address of the first output DMA table */
189 unsigned long out_table_address;
190
191 /* number of entries in the first output DMA table */
192 unsigned long out_table_num_entries;
193
194 /* data in the first input table */
195 unsigned long table_data_size;
196
197 /* distinct user/kernel layout */
198 bool isKernelVirtualAddress;
199
200};
201
202/*
203*/
204struct sep_driver_build_flow_table_t {
205 /* flow type */
206 unsigned long flow_type;
207
208 /* flag for input output */
209 unsigned long input_output_flag;
210
211 /* address value of the data in */
212 unsigned long virt_buff_data_addr;
213
214 /* size of data in */
215 unsigned long num_virtual_buffers;
216
217 /* the physical address of the first input DMA table */
218 unsigned long first_table_addr;
219
220 /* number of entries in the first input DMA table */
221 unsigned long first_table_num_entries;
222
223 /* data in the first input table */
224 unsigned long first_table_data_size;
225
226 /* distinct user/kernel layout */
227 bool isKernelVirtualAddress;
228};
229
230
231struct sep_driver_add_flow_table_t {
232 /* flow id */
233 unsigned long flow_id;
234
235 /* flag for input output */
236 unsigned long inputOutputFlag;
237
238 /* address value of the data in */
239 unsigned long virt_buff_data_addr;
240
241 /* size of data in */
242 unsigned long num_virtual_buffers;
243
244 /* address of the first table */
245 unsigned long first_table_addr;
246
247 /* number of entries in the first table */
248 unsigned long first_table_num_entries;
249
250 /* data size of the first table */
251 unsigned long first_table_data_size;
252
253 /* distinct user/kernel layout */
254 bool isKernelVirtualAddress;
255
256};
257
258/*
259 command struct for set flow id
260*/
261struct sep_driver_set_flow_id_t {
262 /* flow id to set */
263 unsigned long flow_id;
264};
265
266
267/* command struct for add tables message */
268struct sep_driver_add_message_t {
269 /* flow id to set */
270 unsigned long flow_id;
271
272 /* message size in bytes */
273 unsigned long message_size_in_bytes;
274
275 /* address of the message */
276 unsigned long message_address;
277};
278
279/* command struct for static pool addresses */
280struct sep_driver_static_pool_addr_t {
281 /* physical address of the static pool */
282 unsigned long physical_static_address;
283
284 /* virtual address of the static pool */
285 unsigned long virtual_static_address;
286};
287
288/* command struct for getiing offset of the physical address from
289 the start of the mapped area */
290struct sep_driver_get_mapped_offset_t {
291 /* physical address of the static pool */
292 unsigned long physical_address;
293
294 /* virtual address of the static pool */
295 unsigned long offset;
296};
297
298/* command struct for getting time value and address */
299struct sep_driver_get_time_t {
300 /* physical address of stored time */
301 unsigned long time_physical_address;
302
303 /* value of the stored time */
304 unsigned long time_value;
305};
306
307
308/*
309 structure that represent one entry in the DMA LLI table
310*/
311struct sep_lli_entry_t {
312 /* physical address */
313 unsigned long physical_address;
314
315 /* block size */
316 unsigned long block_size;
317};
318
319/*
320 structure that reperesents data needed for lli table construction
321*/
322struct sep_lli_prepare_table_data_t {
323 /* pointer to the memory where the first lli entry to be built */
324 struct sep_lli_entry_t *lli_entry_ptr;
325
326 /* pointer to the array of lli entries from which the table is to be built */
327 struct sep_lli_entry_t *lli_array_ptr;
328
329 /* number of elements in lli array */
330 int lli_array_size;
331
332 /* number of entries in the created table */
333 int num_table_entries;
334
335 /* number of array entries processed during table creation */
336 int num_array_entries_processed;
337
338 /* the totatl data size in the created table */
339 int lli_table_total_data_size;
340};
341
342/*
343 structure that represent tone table - it is not used in code, jkust
344 to show what table looks like
345*/
346struct sep_lli_table_t {
347 /* number of pages mapped in this tables. If 0 - means that the table
348 is not defined (used as a valid flag) */
349 unsigned long num_pages;
350 /*
351 pointer to array of page pointers that represent the mapping of the
352 virtual buffer defined by the table to the physical memory. If this
353 pointer is NULL, it means that the table is not defined
354 (used as a valid flag)
355 */
356 struct page **table_page_array_ptr;
357
358 /* maximum flow entries in table */
359 struct sep_lli_entry_t lli_entries[SEP_DRIVER_MAX_FLOW_NUM_ENTRIES_IN_TABLE];
360};
361
362
363/*
364 structure for keeping the mapping of the virtual buffer into physical pages
365*/
366struct sep_flow_buffer_data {
367 /* pointer to the array of page structs pointers to the pages of the
368 virtual buffer */
369 struct page **page_array_ptr;
370
371 /* number of pages taken by the virtual buffer */
372 unsigned long num_pages;
373
374 /* this flag signals if this page_array is the last one among many that were
375 sent in one setting to SEP */
376 unsigned long last_page_array_flag;
377};
378
379/*
380 struct that keeps all the data for one flow
381*/
382struct sep_flow_context_t {
383 /*
384 work struct for handling the flow done interrupt in the workqueue
385 this structure must be in the first place, since it will be used
386 forcasting to the containing flow context
387 */
388 struct work_struct flow_wq;
389
390 /* flow id */
391 unsigned long flow_id;
392
393 /* additional input tables exists */
394 unsigned long input_tables_flag;
395
396 /* additional output tables exists */
397 unsigned long output_tables_flag;
398
399 /* data of the first input file */
400 struct sep_lli_entry_t first_input_table;
401
402 /* data of the first output table */
403 struct sep_lli_entry_t first_output_table;
404
405 /* last input table data */
406 struct sep_lli_entry_t last_input_table;
407
408 /* last output table data */
409 struct sep_lli_entry_t last_output_table;
410
411 /* first list of table */
412 struct sep_lli_entry_t input_tables_in_process;
413
414 /* output table in process (in sep) */
415 struct sep_lli_entry_t output_tables_in_process;
416
417 /* size of messages in bytes */
418 unsigned long message_size_in_bytes;
419
420 /* message */
421 unsigned char message[SEP_MAX_ADD_MESSAGE_LENGTH_IN_BYTES];
422};
423
424
425#endif
diff --git a/drivers/staging/sep/sep_driver_config.h b/drivers/staging/sep/sep_driver_config.h
deleted file mode 100644
index 6008fe5eca09..000000000000
--- a/drivers/staging/sep/sep_driver_config.h
+++ /dev/null
@@ -1,225 +0,0 @@
1/*
2 *
3 * sep_driver_config.h - Security Processor Driver configuration
4 *
5 * Copyright(c) 2009 Intel Corporation. All rights reserved.
6 * Copyright(c) 2009 Discretix. All rights reserved.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the Free
10 * Software Foundation; either version 2 of the License, or (at your option)
11 * any later version.
12 *
13 * This program is distributed in the hope that it will be useful, but WITHOUT
14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 * more details.
17 *
18 * You should have received a copy of the GNU General Public License along with
19 * this program; if not, write to the Free Software Foundation, Inc., 59
20 * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 *
22 * CONTACTS:
23 *
24 * Mark Allyn mark.a.allyn@intel.com
25 *
26 * CHANGES:
27 *
28 * 2009.06.26 Initial publish
29 *
30 */
31
32#ifndef __SEP_DRIVER_CONFIG_H__
33#define __SEP_DRIVER_CONFIG_H__
34
35
36/*--------------------------------------
37 DRIVER CONFIGURATION FLAGS
38 -------------------------------------*/
39
40/* if flag is on , then the driver is running in polling and
41 not interrupt mode */
42#define SEP_DRIVER_POLLING_MODE 1
43
44/* flag which defines if the shared area address should be
45 reconfiged (send to SEP anew) during init of the driver */
46#define SEP_DRIVER_RECONFIG_MESSAGE_AREA 0
47
48/* the mode for running on the ARM1172 Evaluation platform (flag is 1) */
49#define SEP_DRIVER_ARM_DEBUG_MODE 0
50
51/*-------------------------------------------
52 INTERNAL DATA CONFIGURATION
53 -------------------------------------------*/
54
55/* flag for the input array */
56#define SEP_DRIVER_IN_FLAG 0
57
58/* flag for output array */
59#define SEP_DRIVER_OUT_FLAG 1
60
61/* maximum number of entries in one LLI tables */
62#define SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP 8
63
64
65/*--------------------------------------------------------
66 SHARED AREA memory total size is 36K
67 it is divided is following:
68
69 SHARED_MESSAGE_AREA 8K }
70 }
71 STATIC_POOL_AREA 4K } MAPPED AREA ( 24 K)
72 }
73 DATA_POOL_AREA 12K }
74
75 SYNCHRONIC_DMA_TABLES_AREA 5K
76
77 FLOW_DMA_TABLES_AREA 4K
78
79 SYSTEM_MEMORY_AREA 3k
80
81 SYSTEM_MEMORY total size is 3k
82 it is divided as following:
83
84 TIME_MEMORY_AREA 8B
85-----------------------------------------------------------*/
86
87
88
89/*
90 the maximum length of the message - the rest of the message shared
91 area will be dedicated to the dma lli tables
92*/
93#define SEP_DRIVER_MAX_MESSAGE_SIZE_IN_BYTES (8 * 1024)
94
95/* the size of the message shared area in pages */
96#define SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES (8 * 1024)
97
98/* the size of the data pool static area in pages */
99#define SEP_DRIVER_STATIC_AREA_SIZE_IN_BYTES (4 * 1024)
100
101/* the size of the data pool shared area size in pages */
102#define SEP_DRIVER_DATA_POOL_SHARED_AREA_SIZE_IN_BYTES (12 * 1024)
103
104/* the size of the message shared area in pages */
105#define SEP_DRIVER_SYNCHRONIC_DMA_TABLES_AREA_SIZE_IN_BYTES (1024 * 5)
106
107
108/* the size of the data pool shared area size in pages */
109#define SEP_DRIVER_FLOW_DMA_TABLES_AREA_SIZE_IN_BYTES (1024 * 4)
110
111/* system data (time, caller id etc') pool */
112#define SEP_DRIVER_SYSTEM_DATA_MEMORY_SIZE_IN_BYTES 100
113
114
115/* area size that is mapped - we map the MESSAGE AREA, STATIC POOL and
116 DATA POOL areas. area must be module 4k */
117#define SEP_DRIVER_MMMAP_AREA_SIZE (1024 * 24)
118
119
120/*-----------------------------------------------
121 offsets of the areas starting from the shared area start address
122*/
123
124/* message area offset */
125#define SEP_DRIVER_MESSAGE_AREA_OFFSET_IN_BYTES 0
126
127/* static pool area offset */
128#define SEP_DRIVER_STATIC_AREA_OFFSET_IN_BYTES \
129 (SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES)
130
131/* data pool area offset */
132#define SEP_DRIVER_DATA_POOL_AREA_OFFSET_IN_BYTES \
133 (SEP_DRIVER_STATIC_AREA_OFFSET_IN_BYTES + \
134 SEP_DRIVER_STATIC_AREA_SIZE_IN_BYTES)
135
136/* synhronic dma tables area offset */
137#define SEP_DRIVER_SYNCHRONIC_DMA_TABLES_AREA_OFFSET_IN_BYTES \
138 (SEP_DRIVER_DATA_POOL_AREA_OFFSET_IN_BYTES + \
139 SEP_DRIVER_DATA_POOL_SHARED_AREA_SIZE_IN_BYTES)
140
141/* sep driver flow dma tables area offset */
142#define SEP_DRIVER_FLOW_DMA_TABLES_AREA_OFFSET_IN_BYTES \
143 (SEP_DRIVER_SYNCHRONIC_DMA_TABLES_AREA_OFFSET_IN_BYTES + \
144 SEP_DRIVER_SYNCHRONIC_DMA_TABLES_AREA_SIZE_IN_BYTES)
145
146/* system memory offset in bytes */
147#define SEP_DRIVER_SYSTEM_DATA_MEMORY_OFFSET_IN_BYTES \
148 (SEP_DRIVER_FLOW_DMA_TABLES_AREA_OFFSET_IN_BYTES + \
149 SEP_DRIVER_FLOW_DMA_TABLES_AREA_SIZE_IN_BYTES)
150
151/* offset of the time area */
152#define SEP_DRIVER_SYSTEM_TIME_MEMORY_OFFSET_IN_BYTES \
153 (SEP_DRIVER_SYSTEM_DATA_MEMORY_OFFSET_IN_BYTES)
154
155
156
157/* start physical address of the SEP registers memory in HOST */
158#define SEP_IO_MEM_REGION_START_ADDRESS 0x80000000
159
160/* size of the SEP registers memory region in HOST (for now 100 registers) */
161#define SEP_IO_MEM_REGION_SIZE (2 * 0x100000)
162
163/* define the number of IRQ for SEP interrupts */
164#define SEP_DIRVER_IRQ_NUM 1
165
166/* maximum number of add buffers */
167#define SEP_MAX_NUM_ADD_BUFFERS 100
168
169/* number of flows */
170#define SEP_DRIVER_NUM_FLOWS 4
171
172/* maximum number of entries in flow table */
173#define SEP_DRIVER_MAX_FLOW_NUM_ENTRIES_IN_TABLE 25
174
175/* offset of the num entries in the block length entry of the LLI */
176#define SEP_NUM_ENTRIES_OFFSET_IN_BITS 24
177
178/* offset of the interrupt flag in the block length entry of the LLI */
179#define SEP_INT_FLAG_OFFSET_IN_BITS 31
180
181/* mask for extracting data size from LLI */
182#define SEP_TABLE_DATA_SIZE_MASK 0xFFFFFF
183
184/* mask for entries after being shifted left */
185#define SEP_NUM_ENTRIES_MASK 0x7F
186
187/* default flow id */
188#define SEP_FREE_FLOW_ID 0xFFFFFFFF
189
190/* temp flow id used during cretiong of new flow until receiving
191 real flow id from sep */
192#define SEP_TEMP_FLOW_ID (SEP_DRIVER_NUM_FLOWS + 1)
193
194/* maximum add buffers message length in bytes */
195#define SEP_MAX_ADD_MESSAGE_LENGTH_IN_BYTES (7 * 4)
196
197/* maximum number of concurrent virtual buffers */
198#define SEP_MAX_VIRT_BUFFERS_CONCURRENT 100
199
200/* the token that defines the start of time address */
201#define SEP_TIME_VAL_TOKEN 0x12345678
202
203/* DEBUG LEVEL MASKS */
204#define SEP_DEBUG_LEVEL_BASIC 0x1
205
206#define SEP_DEBUG_LEVEL_EXTENDED 0x4
207
208
209/* Debug helpers */
210
211#define dbg(fmt, args...) \
212do {\
213 if (debug & SEP_DEBUG_LEVEL_BASIC) \
214 printk(KERN_DEBUG fmt, ##args); \
215} while(0);
216
217#define edbg(fmt, args...) \
218do { \
219 if (debug & SEP_DEBUG_LEVEL_EXTENDED) \
220 printk(KERN_DEBUG fmt, ##args); \
221} while(0);
222
223
224
225#endif
diff --git a/drivers/staging/sep/sep_driver_hw_defs.h b/drivers/staging/sep/sep_driver_hw_defs.h
deleted file mode 100644
index ea6abd8a14b4..000000000000
--- a/drivers/staging/sep/sep_driver_hw_defs.h
+++ /dev/null
@@ -1,232 +0,0 @@
1/*
2 *
3 * sep_driver_hw_defs.h - Security Processor Driver hardware definitions
4 *
5 * Copyright(c) 2009 Intel Corporation. All rights reserved.
6 * Copyright(c) 2009 Discretix. All rights reserved.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the Free
10 * Software Foundation; either version 2 of the License, or (at your option)
11 * any later version.
12 *
13 * This program is distributed in the hope that it will be useful, but WITHOUT
14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 * more details.
17 *
18 * You should have received a copy of the GNU General Public License along with
19 * this program; if not, write to the Free Software Foundation, Inc., 59
20 * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 *
22 * CONTACTS:
23 *
24 * Mark Allyn mark.a.allyn@intel.com
25 *
26 * CHANGES:
27 *
28 * 2009.06.26 Initial publish
29 *
30 */
31
32#ifndef SEP_DRIVER_HW_DEFS__H
33#define SEP_DRIVER_HW_DEFS__H
34
35/*--------------------------------------------------------------------------*/
36/* Abstract: HW Registers Defines. */
37/* */
38/* Note: This file was automatically created !!! */
39/* DO NOT EDIT THIS FILE !!! */
40/*--------------------------------------------------------------------------*/
41
42
43/* cf registers */
44#define HW_R0B_ADDR_0_REG_ADDR 0x0000UL
45#define HW_R0B_ADDR_1_REG_ADDR 0x0004UL
46#define HW_R0B_ADDR_2_REG_ADDR 0x0008UL
47#define HW_R0B_ADDR_3_REG_ADDR 0x000cUL
48#define HW_R0B_ADDR_4_REG_ADDR 0x0010UL
49#define HW_R0B_ADDR_5_REG_ADDR 0x0014UL
50#define HW_R0B_ADDR_6_REG_ADDR 0x0018UL
51#define HW_R0B_ADDR_7_REG_ADDR 0x001cUL
52#define HW_R0B_ADDR_8_REG_ADDR 0x0020UL
53#define HW_R2B_ADDR_0_REG_ADDR 0x0080UL
54#define HW_R2B_ADDR_1_REG_ADDR 0x0084UL
55#define HW_R2B_ADDR_2_REG_ADDR 0x0088UL
56#define HW_R2B_ADDR_3_REG_ADDR 0x008cUL
57#define HW_R2B_ADDR_4_REG_ADDR 0x0090UL
58#define HW_R2B_ADDR_5_REG_ADDR 0x0094UL
59#define HW_R2B_ADDR_6_REG_ADDR 0x0098UL
60#define HW_R2B_ADDR_7_REG_ADDR 0x009cUL
61#define HW_R2B_ADDR_8_REG_ADDR 0x00a0UL
62#define HW_R3B_REG_ADDR 0x00C0UL
63#define HW_R4B_REG_ADDR 0x0100UL
64#define HW_CSA_ADDR_0_REG_ADDR 0x0140UL
65#define HW_CSA_ADDR_1_REG_ADDR 0x0144UL
66#define HW_CSA_ADDR_2_REG_ADDR 0x0148UL
67#define HW_CSA_ADDR_3_REG_ADDR 0x014cUL
68#define HW_CSA_ADDR_4_REG_ADDR 0x0150UL
69#define HW_CSA_ADDR_5_REG_ADDR 0x0154UL
70#define HW_CSA_ADDR_6_REG_ADDR 0x0158UL
71#define HW_CSA_ADDR_7_REG_ADDR 0x015cUL
72#define HW_CSA_ADDR_8_REG_ADDR 0x0160UL
73#define HW_CSA_REG_ADDR 0x0140UL
74#define HW_SINB_REG_ADDR 0x0180UL
75#define HW_SOUTB_REG_ADDR 0x0184UL
76#define HW_PKI_CONTROL_REG_ADDR 0x01C0UL
77#define HW_PKI_STATUS_REG_ADDR 0x01C4UL
78#define HW_PKI_BUSY_REG_ADDR 0x01C8UL
79#define HW_PKI_A_1025_REG_ADDR 0x01CCUL
80#define HW_PKI_SDMA_CTL_REG_ADDR 0x01D0UL
81#define HW_PKI_SDMA_OFFSET_REG_ADDR 0x01D4UL
82#define HW_PKI_SDMA_POINTERS_REG_ADDR 0x01D8UL
83#define HW_PKI_SDMA_DLENG_REG_ADDR 0x01DCUL
84#define HW_PKI_SDMA_EXP_POINTERS_REG_ADDR 0x01E0UL
85#define HW_PKI_SDMA_RES_POINTERS_REG_ADDR 0x01E4UL
86#define HW_PKI_CLR_REG_ADDR 0x01E8UL
87#define HW_PKI_SDMA_BUSY_REG_ADDR 0x01E8UL
88#define HW_PKI_SDMA_FIRST_EXP_N_REG_ADDR 0x01ECUL
89#define HW_PKI_SDMA_MUL_BY1_REG_ADDR 0x01F0UL
90#define HW_PKI_SDMA_RMUL_SEL_REG_ADDR 0x01F4UL
91#define HW_DES_KEY_0_REG_ADDR 0x0208UL
92#define HW_DES_KEY_1_REG_ADDR 0x020CUL
93#define HW_DES_KEY_2_REG_ADDR 0x0210UL
94#define HW_DES_KEY_3_REG_ADDR 0x0214UL
95#define HW_DES_KEY_4_REG_ADDR 0x0218UL
96#define HW_DES_KEY_5_REG_ADDR 0x021CUL
97#define HW_DES_CONTROL_0_REG_ADDR 0x0220UL
98#define HW_DES_CONTROL_1_REG_ADDR 0x0224UL
99#define HW_DES_IV_0_REG_ADDR 0x0228UL
100#define HW_DES_IV_1_REG_ADDR 0x022CUL
101#define HW_AES_KEY_0_ADDR_0_REG_ADDR 0x0400UL
102#define HW_AES_KEY_0_ADDR_1_REG_ADDR 0x0404UL
103#define HW_AES_KEY_0_ADDR_2_REG_ADDR 0x0408UL
104#define HW_AES_KEY_0_ADDR_3_REG_ADDR 0x040cUL
105#define HW_AES_KEY_0_ADDR_4_REG_ADDR 0x0410UL
106#define HW_AES_KEY_0_ADDR_5_REG_ADDR 0x0414UL
107#define HW_AES_KEY_0_ADDR_6_REG_ADDR 0x0418UL
108#define HW_AES_KEY_0_ADDR_7_REG_ADDR 0x041cUL
109#define HW_AES_KEY_0_REG_ADDR 0x0400UL
110#define HW_AES_IV_0_ADDR_0_REG_ADDR 0x0440UL
111#define HW_AES_IV_0_ADDR_1_REG_ADDR 0x0444UL
112#define HW_AES_IV_0_ADDR_2_REG_ADDR 0x0448UL
113#define HW_AES_IV_0_ADDR_3_REG_ADDR 0x044cUL
114#define HW_AES_IV_0_REG_ADDR 0x0440UL
115#define HW_AES_CTR1_ADDR_0_REG_ADDR 0x0460UL
116#define HW_AES_CTR1_ADDR_1_REG_ADDR 0x0464UL
117#define HW_AES_CTR1_ADDR_2_REG_ADDR 0x0468UL
118#define HW_AES_CTR1_ADDR_3_REG_ADDR 0x046cUL
119#define HW_AES_CTR1_REG_ADDR 0x0460UL
120#define HW_AES_SK_REG_ADDR 0x0478UL
121#define HW_AES_MAC_OK_REG_ADDR 0x0480UL
122#define HW_AES_PREV_IV_0_ADDR_0_REG_ADDR 0x0490UL
123#define HW_AES_PREV_IV_0_ADDR_1_REG_ADDR 0x0494UL
124#define HW_AES_PREV_IV_0_ADDR_2_REG_ADDR 0x0498UL
125#define HW_AES_PREV_IV_0_ADDR_3_REG_ADDR 0x049cUL
126#define HW_AES_PREV_IV_0_REG_ADDR 0x0490UL
127#define HW_AES_CONTROL_REG_ADDR 0x04C0UL
128#define HW_HASH_H0_REG_ADDR 0x0640UL
129#define HW_HASH_H1_REG_ADDR 0x0644UL
130#define HW_HASH_H2_REG_ADDR 0x0648UL
131#define HW_HASH_H3_REG_ADDR 0x064CUL
132#define HW_HASH_H4_REG_ADDR 0x0650UL
133#define HW_HASH_H5_REG_ADDR 0x0654UL
134#define HW_HASH_H6_REG_ADDR 0x0658UL
135#define HW_HASH_H7_REG_ADDR 0x065CUL
136#define HW_HASH_H8_REG_ADDR 0x0660UL
137#define HW_HASH_H9_REG_ADDR 0x0664UL
138#define HW_HASH_H10_REG_ADDR 0x0668UL
139#define HW_HASH_H11_REG_ADDR 0x066CUL
140#define HW_HASH_H12_REG_ADDR 0x0670UL
141#define HW_HASH_H13_REG_ADDR 0x0674UL
142#define HW_HASH_H14_REG_ADDR 0x0678UL
143#define HW_HASH_H15_REG_ADDR 0x067CUL
144#define HW_HASH_CONTROL_REG_ADDR 0x07C0UL
145#define HW_HASH_PAD_EN_REG_ADDR 0x07C4UL
146#define HW_HASH_PAD_CFG_REG_ADDR 0x07C8UL
147#define HW_HASH_CUR_LEN_0_REG_ADDR 0x07CCUL
148#define HW_HASH_CUR_LEN_1_REG_ADDR 0x07D0UL
149#define HW_HASH_CUR_LEN_2_REG_ADDR 0x07D4UL
150#define HW_HASH_CUR_LEN_3_REG_ADDR 0x07D8UL
151#define HW_HASH_PARAM_REG_ADDR 0x07DCUL
152#define HW_HASH_INT_BUSY_REG_ADDR 0x07E0UL
153#define HW_HASH_SW_RESET_REG_ADDR 0x07E4UL
154#define HW_HASH_ENDIANESS_REG_ADDR 0x07E8UL
155#define HW_HASH_DATA_REG_ADDR 0x07ECUL
156#define HW_DRNG_CONTROL_REG_ADDR 0x0800UL
157#define HW_DRNG_VALID_REG_ADDR 0x0804UL
158#define HW_DRNG_DATA_REG_ADDR 0x0808UL
159#define HW_RND_SRC_EN_REG_ADDR 0x080CUL
160#define HW_AES_CLK_ENABLE_REG_ADDR 0x0810UL
161#define HW_DES_CLK_ENABLE_REG_ADDR 0x0814UL
162#define HW_HASH_CLK_ENABLE_REG_ADDR 0x0818UL
163#define HW_PKI_CLK_ENABLE_REG_ADDR 0x081CUL
164#define HW_CLK_STATUS_REG_ADDR 0x0824UL
165#define HW_CLK_ENABLE_REG_ADDR 0x0828UL
166#define HW_DRNG_SAMPLE_REG_ADDR 0x0850UL
167#define HW_RND_SRC_CTL_REG_ADDR 0x0858UL
168#define HW_CRYPTO_CTL_REG_ADDR 0x0900UL
169#define HW_CRYPTO_STATUS_REG_ADDR 0x090CUL
170#define HW_CRYPTO_BUSY_REG_ADDR 0x0910UL
171#define HW_AES_BUSY_REG_ADDR 0x0914UL
172#define HW_DES_BUSY_REG_ADDR 0x0918UL
173#define HW_HASH_BUSY_REG_ADDR 0x091CUL
174#define HW_CONTENT_REG_ADDR 0x0924UL
175#define HW_VERSION_REG_ADDR 0x0928UL
176#define HW_CONTEXT_ID_REG_ADDR 0x0930UL
177#define HW_DIN_BUFFER_REG_ADDR 0x0C00UL
178#define HW_DIN_MEM_DMA_BUSY_REG_ADDR 0x0c20UL
179#define HW_SRC_LLI_MEM_ADDR_REG_ADDR 0x0c24UL
180#define HW_SRC_LLI_WORD0_REG_ADDR 0x0C28UL
181#define HW_SRC_LLI_WORD1_REG_ADDR 0x0C2CUL
182#define HW_SRAM_SRC_ADDR_REG_ADDR 0x0c30UL
183#define HW_DIN_SRAM_BYTES_LEN_REG_ADDR 0x0c34UL
184#define HW_DIN_SRAM_DMA_BUSY_REG_ADDR 0x0C38UL
185#define HW_WRITE_ALIGN_REG_ADDR 0x0C3CUL
186#define HW_OLD_DATA_REG_ADDR 0x0C48UL
187#define HW_WRITE_ALIGN_LAST_REG_ADDR 0x0C4CUL
188#define HW_DOUT_BUFFER_REG_ADDR 0x0C00UL
189#define HW_DST_LLI_WORD0_REG_ADDR 0x0D28UL
190#define HW_DST_LLI_WORD1_REG_ADDR 0x0D2CUL
191#define HW_DST_LLI_MEM_ADDR_REG_ADDR 0x0D24UL
192#define HW_DOUT_MEM_DMA_BUSY_REG_ADDR 0x0D20UL
193#define HW_SRAM_DEST_ADDR_REG_ADDR 0x0D30UL
194#define HW_DOUT_SRAM_BYTES_LEN_REG_ADDR 0x0D34UL
195#define HW_DOUT_SRAM_DMA_BUSY_REG_ADDR 0x0D38UL
196#define HW_READ_ALIGN_REG_ADDR 0x0D3CUL
197#define HW_READ_LAST_DATA_REG_ADDR 0x0D44UL
198#define HW_RC4_THRU_CPU_REG_ADDR 0x0D4CUL
199#define HW_AHB_SINGLE_REG_ADDR 0x0E00UL
200#define HW_SRAM_DATA_REG_ADDR 0x0F00UL
201#define HW_SRAM_ADDR_REG_ADDR 0x0F04UL
202#define HW_SRAM_DATA_READY_REG_ADDR 0x0F08UL
203#define HW_HOST_IRR_REG_ADDR 0x0A00UL
204#define HW_HOST_IMR_REG_ADDR 0x0A04UL
205#define HW_HOST_ICR_REG_ADDR 0x0A08UL
206#define HW_HOST_SEP_SRAM_THRESHOLD_REG_ADDR 0x0A10UL
207#define HW_HOST_SEP_BUSY_REG_ADDR 0x0A14UL
208#define HW_HOST_SEP_LCS_REG_ADDR 0x0A18UL
209#define HW_HOST_CC_SW_RST_REG_ADDR 0x0A40UL
210#define HW_HOST_SEP_SW_RST_REG_ADDR 0x0A44UL
211#define HW_HOST_FLOW_DMA_SW_INT0_REG_ADDR 0x0A80UL
212#define HW_HOST_FLOW_DMA_SW_INT1_REG_ADDR 0x0A84UL
213#define HW_HOST_FLOW_DMA_SW_INT2_REG_ADDR 0x0A88UL
214#define HW_HOST_FLOW_DMA_SW_INT3_REG_ADDR 0x0A8cUL
215#define HW_HOST_FLOW_DMA_SW_INT4_REG_ADDR 0x0A90UL
216#define HW_HOST_FLOW_DMA_SW_INT5_REG_ADDR 0x0A94UL
217#define HW_HOST_FLOW_DMA_SW_INT6_REG_ADDR 0x0A98UL
218#define HW_HOST_FLOW_DMA_SW_INT7_REG_ADDR 0x0A9cUL
219#define HW_HOST_SEP_HOST_GPR0_REG_ADDR 0x0B00UL
220#define HW_HOST_SEP_HOST_GPR1_REG_ADDR 0x0B04UL
221#define HW_HOST_SEP_HOST_GPR2_REG_ADDR 0x0B08UL
222#define HW_HOST_SEP_HOST_GPR3_REG_ADDR 0x0B0CUL
223#define HW_HOST_HOST_SEP_GPR0_REG_ADDR 0x0B80UL
224#define HW_HOST_HOST_SEP_GPR1_REG_ADDR 0x0B84UL
225#define HW_HOST_HOST_SEP_GPR2_REG_ADDR 0x0B88UL
226#define HW_HOST_HOST_SEP_GPR3_REG_ADDR 0x0B8CUL
227#define HW_HOST_HOST_ENDIAN_REG_ADDR 0x0B90UL
228#define HW_HOST_HOST_COMM_CLK_EN_REG_ADDR 0x0B94UL
229#define HW_CLR_SRAM_BUSY_REG_REG_ADDR 0x0F0CUL
230#define HW_CC_SRAM_BASE_ADDRESS 0x5800UL
231
232#endif /* ifndef HW_DEFS */
diff --git a/drivers/staging/spectra/ffsport.c b/drivers/staging/spectra/ffsport.c
index d0c5c97eda3e..44a7fbe7eccd 100644
--- a/drivers/staging/spectra/ffsport.c
+++ b/drivers/staging/spectra/ffsport.c
@@ -27,6 +27,7 @@
27#include <linux/kthread.h> 27#include <linux/kthread.h>
28#include <linux/log2.h> 28#include <linux/log2.h>
29#include <linux/init.h> 29#include <linux/init.h>
30#include <linux/smp_lock.h>
30 31
31/**** Helper functions used for Div, Remainder operation on u64 ****/ 32/**** Helper functions used for Div, Remainder operation on u64 ****/
32 33
@@ -113,7 +114,6 @@ u64 GLOB_u64_Remainder(u64 addr, u32 divisor_type)
113 114
114#define GLOB_SBD_NAME "nd" 115#define GLOB_SBD_NAME "nd"
115#define GLOB_SBD_IRQ_NUM (29) 116#define GLOB_SBD_IRQ_NUM (29)
116#define GLOB_VERSION "driver version 20091110"
117 117
118#define GLOB_SBD_IOCTL_GC (0x7701) 118#define GLOB_SBD_IOCTL_GC (0x7701)
119#define GLOB_SBD_IOCTL_WL (0x7702) 119#define GLOB_SBD_IOCTL_WL (0x7702)
@@ -272,13 +272,6 @@ static int get_res_blk_num_os(void)
272 return res_blks; 272 return res_blks;
273} 273}
274 274
275static void SBD_prepare_flush(struct request_queue *q, struct request *rq)
276{
277 rq->cmd_type = REQ_TYPE_LINUX_BLOCK;
278 /* rq->timeout = 5 * HZ; */
279 rq->cmd[0] = REQ_LB_OP_FLUSH;
280}
281
282/* Transfer a full request. */ 275/* Transfer a full request. */
283static int do_transfer(struct spectra_nand_dev *tr, struct request *req) 276static int do_transfer(struct spectra_nand_dev *tr, struct request *req)
284{ 277{
@@ -296,8 +289,7 @@ static int do_transfer(struct spectra_nand_dev *tr, struct request *req)
296 IdentifyDeviceData.PagesPerBlock * 289 IdentifyDeviceData.PagesPerBlock *
297 res_blks_os; 290 res_blks_os;
298 291
299 if (req->cmd_type == REQ_TYPE_LINUX_BLOCK && 292 if (req->cmd_type & REQ_FLUSH) {
300 req->cmd[0] == REQ_LB_OP_FLUSH) {
301 if (force_flush_cache()) /* Fail to flush cache */ 293 if (force_flush_cache()) /* Fail to flush cache */
302 return -EIO; 294 return -EIO;
303 else 295 else
@@ -597,11 +589,23 @@ int GLOB_SBD_ioctl(struct block_device *bdev, fmode_t mode,
597 return -ENOTTY; 589 return -ENOTTY;
598} 590}
599 591
592int GLOB_SBD_unlocked_ioctl(struct block_device *bdev, fmode_t mode,
593 unsigned int cmd, unsigned long arg)
594{
595 int ret;
596
597 lock_kernel();
598 ret = GLOB_SBD_ioctl(bdev, mode, cmd, arg);
599 unlock_kernel();
600
601 return ret;
602}
603
600static struct block_device_operations GLOB_SBD_ops = { 604static struct block_device_operations GLOB_SBD_ops = {
601 .owner = THIS_MODULE, 605 .owner = THIS_MODULE,
602 .open = GLOB_SBD_open, 606 .open = GLOB_SBD_open,
603 .release = GLOB_SBD_release, 607 .release = GLOB_SBD_release,
604 .locked_ioctl = GLOB_SBD_ioctl, 608 .ioctl = GLOB_SBD_unlocked_ioctl,
605 .getgeo = GLOB_SBD_getgeo, 609 .getgeo = GLOB_SBD_getgeo,
606}; 610};
607 611
@@ -650,8 +654,7 @@ static int SBD_setup_device(struct spectra_nand_dev *dev, int which)
650 /* Here we force report 512 byte hardware sector size to Kernel */ 654 /* Here we force report 512 byte hardware sector size to Kernel */
651 blk_queue_logical_block_size(dev->queue, 512); 655 blk_queue_logical_block_size(dev->queue, 512);
652 656
653 blk_queue_ordered(dev->queue, QUEUE_ORDERED_DRAIN_FLUSH, 657 blk_queue_ordered(dev->queue, QUEUE_ORDERED_DRAIN_FLUSH);
654 SBD_prepare_flush);
655 658
656 dev->thread = kthread_run(spectra_trans_thread, dev, "nand_thd"); 659 dev->thread = kthread_run(spectra_trans_thread, dev, "nand_thd");
657 if (IS_ERR(dev->thread)) { 660 if (IS_ERR(dev->thread)) {
diff --git a/drivers/staging/spectra/flash.c b/drivers/staging/spectra/flash.c
index 134aa5166a8d..9b5218b6ada8 100644
--- a/drivers/staging/spectra/flash.c
+++ b/drivers/staging/spectra/flash.c
@@ -61,7 +61,6 @@ static void FTL_Cache_Read_Page(u8 *pData, u64 dwPageAddr,
61static void FTL_Cache_Write_Page(u8 *pData, u64 dwPageAddr, 61static void FTL_Cache_Write_Page(u8 *pData, u64 dwPageAddr,
62 u8 cache_blk, u16 flag); 62 u8 cache_blk, u16 flag);
63static int FTL_Cache_Write(void); 63static int FTL_Cache_Write(void);
64static int FTL_Cache_Write_Back(u8 *pData, u64 blk_addr);
65static void FTL_Calculate_LRU(void); 64static void FTL_Calculate_LRU(void);
66static u32 FTL_Get_Block_Index(u32 wBlockNum); 65static u32 FTL_Get_Block_Index(u32 wBlockNum);
67 66
@@ -86,8 +85,6 @@ static u32 FTL_Replace_MWBlock(void);
86static int FTL_Replace_Block(u64 blk_addr); 85static int FTL_Replace_Block(u64 blk_addr);
87static int FTL_Adjust_Relative_Erase_Count(u32 Index_of_MAX); 86static int FTL_Adjust_Relative_Erase_Count(u32 Index_of_MAX);
88 87
89static int FTL_Flash_Error_Handle(u8 *pData, u64 old_page_addr, u64 blk_addr);
90
91struct device_info_tag DeviceInfo; 88struct device_info_tag DeviceInfo;
92struct flash_cache_tag Cache; 89struct flash_cache_tag Cache;
93static struct spectra_l2_cache_info cache_l2; 90static struct spectra_l2_cache_info cache_l2;
@@ -775,7 +772,7 @@ static void dump_cache_l2_table(void)
775{ 772{
776 struct list_head *p; 773 struct list_head *p;
777 struct spectra_l2_cache_list *pnd; 774 struct spectra_l2_cache_list *pnd;
778 int n, i; 775 int n;
779 776
780 n = 0; 777 n = 0;
781 list_for_each(p, &cache_l2.table.list) { 778 list_for_each(p, &cache_l2.table.list) {
@@ -1538,79 +1535,6 @@ static int FTL_Cache_Write_All(u8 *pData, u64 blk_addr)
1538} 1535}
1539 1536
1540/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& 1537/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
1541* Function: FTL_Cache_Update_Block
1542* Inputs: pointer to buffer,page address,block address
1543* Outputs: PASS=0 / FAIL=1
1544* Description: It updates the cache
1545*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
1546static int FTL_Cache_Update_Block(u8 *pData,
1547 u64 old_page_addr, u64 blk_addr)
1548{
1549 int i, j;
1550 u8 *buf = pData;
1551 int wResult = PASS;
1552 int wFoundInCache;
1553 u64 page_addr;
1554 u64 addr;
1555 u64 old_blk_addr;
1556 u16 page_offset;
1557
1558 nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
1559 __FILE__, __LINE__, __func__);
1560
1561 old_blk_addr = (u64)(old_page_addr >>
1562 DeviceInfo.nBitsInBlockDataSize) * DeviceInfo.wBlockDataSize;
1563 page_offset = (u16)(GLOB_u64_Remainder(old_page_addr, 2) >>
1564 DeviceInfo.nBitsInPageDataSize);
1565
1566 for (i = 0; i < DeviceInfo.wPagesPerBlock; i += Cache.pages_per_item) {
1567 page_addr = old_blk_addr + i * DeviceInfo.wPageDataSize;
1568 if (i != page_offset) {
1569 wFoundInCache = FAIL;
1570 for (j = 0; j < CACHE_ITEM_NUM; j++) {
1571 addr = Cache.array[j].address;
1572 addr = FTL_Get_Physical_Block_Addr(addr) +
1573 GLOB_u64_Remainder(addr, 2);
1574 if ((addr >= page_addr) && addr <
1575 (page_addr + Cache.cache_item_size)) {
1576 wFoundInCache = PASS;
1577 buf = Cache.array[j].buf;
1578 Cache.array[j].changed = SET;
1579#if CMD_DMA
1580#if RESTORE_CACHE_ON_CDMA_CHAIN_FAILURE
1581 int_cache[ftl_cmd_cnt].item = j;
1582 int_cache[ftl_cmd_cnt].cache.address =
1583 Cache.array[j].address;
1584 int_cache[ftl_cmd_cnt].cache.changed =
1585 Cache.array[j].changed;
1586#endif
1587#endif
1588 break;
1589 }
1590 }
1591 if (FAIL == wFoundInCache) {
1592 if (ERR == FTL_Cache_Read_All(g_pTempBuf,
1593 page_addr)) {
1594 wResult = FAIL;
1595 break;
1596 }
1597 buf = g_pTempBuf;
1598 }
1599 } else {
1600 buf = pData;
1601 }
1602
1603 if (FAIL == FTL_Cache_Write_All(buf,
1604 blk_addr + (page_addr - old_blk_addr))) {
1605 wResult = FAIL;
1606 break;
1607 }
1608 }
1609
1610 return wResult;
1611}
1612
1613/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
1614* Function: FTL_Copy_Block 1538* Function: FTL_Copy_Block
1615* Inputs: source block address 1539* Inputs: source block address
1616* Destination block address 1540* Destination block address
@@ -1698,7 +1622,7 @@ static int get_l2_cache_blks(void)
1698static int erase_l2_cache_blocks(void) 1622static int erase_l2_cache_blocks(void)
1699{ 1623{
1700 int i, ret = PASS; 1624 int i, ret = PASS;
1701 u32 pblk, lblk; 1625 u32 pblk, lblk = BAD_BLOCK;
1702 u64 addr; 1626 u64 addr;
1703 u32 *pbt = (u32 *)g_pBlockTable; 1627 u32 *pbt = (u32 *)g_pBlockTable;
1704 1628
@@ -2004,87 +1928,6 @@ static int search_l2_cache(u8 *buf, u64 logical_addr)
2004 return ret; 1928 return ret;
2005} 1929}
2006 1930
2007/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
2008* Function: FTL_Cache_Write_Back
2009* Inputs: pointer to data cached in sys memory
2010* address of free block in flash
2011* Outputs: PASS=0 / FAIL=1
2012* Description: writes all the pages of Cache Block to flash
2013*
2014*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
2015static int FTL_Cache_Write_Back(u8 *pData, u64 blk_addr)
2016{
2017 int i, j, iErase;
2018 u64 old_page_addr, addr, phy_addr;
2019 u32 *pbt = (u32 *)g_pBlockTable;
2020 u32 lba;
2021
2022 nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
2023 __FILE__, __LINE__, __func__);
2024
2025 old_page_addr = FTL_Get_Physical_Block_Addr(blk_addr) +
2026 GLOB_u64_Remainder(blk_addr, 2);
2027
2028 iErase = (FAIL == FTL_Replace_Block(blk_addr)) ? PASS : FAIL;
2029
2030 pbt[BLK_FROM_ADDR(blk_addr)] &= (~SPARE_BLOCK);
2031
2032#if CMD_DMA
2033 p_BTableChangesDelta = (struct BTableChangesDelta *)g_pBTDelta_Free;
2034 g_pBTDelta_Free += sizeof(struct BTableChangesDelta);
2035
2036 p_BTableChangesDelta->ftl_cmd_cnt = ftl_cmd_cnt;
2037 p_BTableChangesDelta->BT_Index = (u32)(blk_addr >>
2038 DeviceInfo.nBitsInBlockDataSize);
2039 p_BTableChangesDelta->BT_Entry_Value =
2040 pbt[(u32)(blk_addr >> DeviceInfo.nBitsInBlockDataSize)];
2041 p_BTableChangesDelta->ValidFields = 0x0C;
2042#endif
2043
2044 if (IN_PROGRESS_BLOCK_TABLE != g_cBlockTableStatus) {
2045 g_cBlockTableStatus = IN_PROGRESS_BLOCK_TABLE;
2046 FTL_Write_IN_Progress_Block_Table_Page();
2047 }
2048
2049 for (i = 0; i < RETRY_TIMES; i++) {
2050 if (PASS == iErase) {
2051 phy_addr = FTL_Get_Physical_Block_Addr(blk_addr);
2052 if (FAIL == GLOB_FTL_Block_Erase(phy_addr)) {
2053 lba = BLK_FROM_ADDR(blk_addr);
2054 MARK_BLOCK_AS_BAD(pbt[lba]);
2055 i = RETRY_TIMES;
2056 break;
2057 }
2058 }
2059
2060 for (j = 0; j < CACHE_ITEM_NUM; j++) {
2061 addr = Cache.array[j].address;
2062 if ((addr <= blk_addr) &&
2063 ((addr + Cache.cache_item_size) > blk_addr))
2064 cache_block_to_write = j;
2065 }
2066
2067 phy_addr = FTL_Get_Physical_Block_Addr(blk_addr);
2068 if (PASS == FTL_Cache_Update_Block(pData,
2069 old_page_addr, phy_addr)) {
2070 cache_block_to_write = UNHIT_CACHE_ITEM;
2071 break;
2072 } else {
2073 iErase = PASS;
2074 }
2075 }
2076
2077 if (i >= RETRY_TIMES) {
2078 if (ERR == FTL_Flash_Error_Handle(pData,
2079 old_page_addr, blk_addr))
2080 return ERR;
2081 else
2082 return FAIL;
2083 }
2084
2085 return PASS;
2086}
2087
2088/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& 1931/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
2089* Function: FTL_Cache_Write_Page 1932* Function: FTL_Cache_Write_Page
2090* Inputs: Pointer to buffer, page address, cache block number 1933* Inputs: Pointer to buffer, page address, cache block number
@@ -2370,159 +2213,6 @@ static int FTL_Write_Block_Table(int wForce)
2370 return 1; 2213 return 1;
2371} 2214}
2372 2215
2373/******************************************************************
2374* Function: GLOB_FTL_Flash_Format
2375* Inputs: none
2376* Outputs: PASS
2377* Description: The block table stores bad block info, including MDF+
2378* blocks gone bad over the ages. Therefore, if we have a
2379* block table in place, then use it to scan for bad blocks
2380* If not, then scan for MDF.
2381* Now, a block table will only be found if spectra was already
2382* being used. For a fresh flash, we'll go thru scanning for
2383* MDF. If spectra was being used, then there is a chance that
2384* the MDF has been corrupted. Spectra avoids writing to the
2385* first 2 bytes of the spare area to all pages in a block. This
2386* covers all known flash devices. However, since flash
2387* manufacturers have no standard of where the MDF is stored,
2388* this cannot guarantee that the MDF is protected for future
2389* devices too. The initial scanning for the block table assures
2390* this. It is ok even if the block table is outdated, as all
2391* we're looking for are bad block markers.
2392* Use this when mounting a file system or starting a
2393* new flash.
2394*
2395*********************************************************************/
2396static int FTL_Format_Flash(u8 valid_block_table)
2397{
2398 u32 i, j;
2399 u32 *pbt = (u32 *)g_pBlockTable;
2400 u32 tempNode;
2401 int ret;
2402
2403#if CMD_DMA
2404 u32 *pbtStartingCopy = (u32 *)g_pBTStartingCopy;
2405 if (ftl_cmd_cnt)
2406 return FAIL;
2407#endif
2408
2409 if (FAIL == FTL_Check_Block_Table(FAIL))
2410 valid_block_table = 0;
2411
2412 if (valid_block_table) {
2413 u8 switched = 1;
2414 u32 block, k;
2415
2416 k = DeviceInfo.wSpectraStartBlock;
2417 while (switched && (k < DeviceInfo.wSpectraEndBlock)) {
2418 switched = 0;
2419 k++;
2420 for (j = DeviceInfo.wSpectraStartBlock, i = 0;
2421 j <= DeviceInfo.wSpectraEndBlock;
2422 j++, i++) {
2423 block = (pbt[i] & ~BAD_BLOCK) -
2424 DeviceInfo.wSpectraStartBlock;
2425 if (block != i) {
2426 switched = 1;
2427 tempNode = pbt[i];
2428 pbt[i] = pbt[block];
2429 pbt[block] = tempNode;
2430 }
2431 }
2432 }
2433 if ((k == DeviceInfo.wSpectraEndBlock) && switched)
2434 valid_block_table = 0;
2435 }
2436
2437 if (!valid_block_table) {
2438 memset(g_pBlockTable, 0,
2439 DeviceInfo.wDataBlockNum * sizeof(u32));
2440 memset(g_pWearCounter, 0,
2441 DeviceInfo.wDataBlockNum * sizeof(u8));
2442 if (DeviceInfo.MLCDevice)
2443 memset(g_pReadCounter, 0,
2444 DeviceInfo.wDataBlockNum * sizeof(u16));
2445#if CMD_DMA
2446 memset(g_pBTStartingCopy, 0,
2447 DeviceInfo.wDataBlockNum * sizeof(u32));
2448 memset(g_pWearCounterCopy, 0,
2449 DeviceInfo.wDataBlockNum * sizeof(u8));
2450 if (DeviceInfo.MLCDevice)
2451 memset(g_pReadCounterCopy, 0,
2452 DeviceInfo.wDataBlockNum * sizeof(u16));
2453#endif
2454 for (j = DeviceInfo.wSpectraStartBlock, i = 0;
2455 j <= DeviceInfo.wSpectraEndBlock;
2456 j++, i++) {
2457 if (GLOB_LLD_Get_Bad_Block((u32)j))
2458 pbt[i] = (u32)(BAD_BLOCK | j);
2459 }
2460 }
2461
2462 nand_dbg_print(NAND_DBG_WARN, "Erasing all blocks in the NAND\n");
2463
2464 for (j = DeviceInfo.wSpectraStartBlock, i = 0;
2465 j <= DeviceInfo.wSpectraEndBlock;
2466 j++, i++) {
2467 if ((pbt[i] & BAD_BLOCK) != BAD_BLOCK) {
2468 ret = GLOB_LLD_Erase_Block(j);
2469 if (FAIL == ret) {
2470 pbt[i] = (u32)(j);
2471 MARK_BLOCK_AS_BAD(pbt[i]);
2472 nand_dbg_print(NAND_DBG_WARN,
2473 "NAND Program fail in %s, Line %d, "
2474 "Function: %s, new Bad Block %d generated!\n",
2475 __FILE__, __LINE__, __func__, (int)j);
2476 } else {
2477 pbt[i] = (u32)(SPARE_BLOCK | j);
2478 }
2479 }
2480#if CMD_DMA
2481 pbtStartingCopy[i] = pbt[i];
2482#endif
2483 }
2484
2485 g_wBlockTableOffset = 0;
2486 for (i = 0; (i <= (DeviceInfo.wSpectraEndBlock -
2487 DeviceInfo.wSpectraStartBlock))
2488 && ((pbt[i] & BAD_BLOCK) == BAD_BLOCK); i++)
2489 ;
2490 if (i > (DeviceInfo.wSpectraEndBlock - DeviceInfo.wSpectraStartBlock)) {
2491 printk(KERN_ERR "All blocks bad!\n");
2492 return FAIL;
2493 } else {
2494 g_wBlockTableIndex = pbt[i] & ~BAD_BLOCK;
2495 if (i != BLOCK_TABLE_INDEX) {
2496 tempNode = pbt[i];
2497 pbt[i] = pbt[BLOCK_TABLE_INDEX];
2498 pbt[BLOCK_TABLE_INDEX] = tempNode;
2499 }
2500 }
2501 pbt[BLOCK_TABLE_INDEX] &= (~SPARE_BLOCK);
2502
2503#if CMD_DMA
2504 pbtStartingCopy[BLOCK_TABLE_INDEX] &= (~SPARE_BLOCK);
2505#endif
2506
2507 g_cBlockTableStatus = IN_PROGRESS_BLOCK_TABLE;
2508 memset(g_pBTBlocks, 0xFF,
2509 (1 + LAST_BT_ID - FIRST_BT_ID) * sizeof(u32));
2510 g_pBTBlocks[FIRST_BT_ID-FIRST_BT_ID] = g_wBlockTableIndex;
2511 FTL_Write_Block_Table(FAIL);
2512
2513 for (i = 0; i < CACHE_ITEM_NUM; i++) {
2514 Cache.array[i].address = NAND_CACHE_INIT_ADDR;
2515 Cache.array[i].use_cnt = 0;
2516 Cache.array[i].changed = CLEAR;
2517 }
2518
2519#if (RESTORE_CACHE_ON_CDMA_CHAIN_FAILURE && CMD_DMA)
2520 memcpy((void *)&cache_start_copy, (void *)&Cache,
2521 sizeof(struct flash_cache_tag));
2522#endif
2523 return PASS;
2524}
2525
2526static int force_format_nand(void) 2216static int force_format_nand(void)
2527{ 2217{
2528 u32 i; 2218 u32 i;
@@ -3031,112 +2721,6 @@ static int FTL_Read_Block_Table(void)
3031 return wResult; 2721 return wResult;
3032} 2722}
3033 2723
3034
3035/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
3036* Function: FTL_Flash_Error_Handle
3037* Inputs: Pointer to data
3038* Page address
3039* Block address
3040* Outputs: PASS=0 / FAIL=1
3041* Description: It handles any error occured during Spectra operation
3042*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
3043static int FTL_Flash_Error_Handle(u8 *pData, u64 old_page_addr,
3044 u64 blk_addr)
3045{
3046 u32 i;
3047 int j;
3048 u32 tmp_node, blk_node = BLK_FROM_ADDR(blk_addr);
3049 u64 phy_addr;
3050 int wErase = FAIL;
3051 int wResult = FAIL;
3052 u32 *pbt = (u32 *)g_pBlockTable;
3053
3054 nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
3055 __FILE__, __LINE__, __func__);
3056
3057 if (ERR == GLOB_FTL_Garbage_Collection())
3058 return ERR;
3059
3060 do {
3061 for (i = DeviceInfo.wSpectraEndBlock -
3062 DeviceInfo.wSpectraStartBlock;
3063 i > 0; i--) {
3064 if (IS_SPARE_BLOCK(i)) {
3065 tmp_node = (u32)(BAD_BLOCK |
3066 pbt[blk_node]);
3067 pbt[blk_node] = (u32)(pbt[i] &
3068 (~SPARE_BLOCK));
3069 pbt[i] = tmp_node;
3070#if CMD_DMA
3071 p_BTableChangesDelta =
3072 (struct BTableChangesDelta *)
3073 g_pBTDelta_Free;
3074 g_pBTDelta_Free +=
3075 sizeof(struct BTableChangesDelta);
3076
3077 p_BTableChangesDelta->ftl_cmd_cnt =
3078 ftl_cmd_cnt;
3079 p_BTableChangesDelta->BT_Index =
3080 blk_node;
3081 p_BTableChangesDelta->BT_Entry_Value =
3082 pbt[blk_node];
3083 p_BTableChangesDelta->ValidFields = 0x0C;
3084
3085 p_BTableChangesDelta =
3086 (struct BTableChangesDelta *)
3087 g_pBTDelta_Free;
3088 g_pBTDelta_Free +=
3089 sizeof(struct BTableChangesDelta);
3090
3091 p_BTableChangesDelta->ftl_cmd_cnt =
3092 ftl_cmd_cnt;
3093 p_BTableChangesDelta->BT_Index = i;
3094 p_BTableChangesDelta->BT_Entry_Value = pbt[i];
3095 p_BTableChangesDelta->ValidFields = 0x0C;
3096#endif
3097 wResult = PASS;
3098 break;
3099 }
3100 }
3101
3102 if (FAIL == wResult) {
3103 if (FAIL == GLOB_FTL_Garbage_Collection())
3104 break;
3105 else
3106 continue;
3107 }
3108
3109 if (IN_PROGRESS_BLOCK_TABLE != g_cBlockTableStatus) {
3110 g_cBlockTableStatus = IN_PROGRESS_BLOCK_TABLE;
3111 FTL_Write_IN_Progress_Block_Table_Page();
3112 }
3113
3114 phy_addr = FTL_Get_Physical_Block_Addr(blk_addr);
3115
3116 for (j = 0; j < RETRY_TIMES; j++) {
3117 if (PASS == wErase) {
3118 if (FAIL == GLOB_FTL_Block_Erase(phy_addr)) {
3119 MARK_BLOCK_AS_BAD(pbt[blk_node]);
3120 break;
3121 }
3122 }
3123 if (PASS == FTL_Cache_Update_Block(pData,
3124 old_page_addr,
3125 phy_addr)) {
3126 wResult = PASS;
3127 break;
3128 } else {
3129 wResult = FAIL;
3130 wErase = PASS;
3131 }
3132 }
3133 } while (FAIL == wResult);
3134
3135 FTL_Write_Block_Table(FAIL);
3136
3137 return wResult;
3138}
3139
3140/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& 2724/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
3141* Function: FTL_Get_Page_Num 2725* Function: FTL_Get_Page_Num
3142* Inputs: Size in bytes 2726* Inputs: Size in bytes
diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
index e483f80822d2..1160c55de7f2 100644
--- a/drivers/usb/gadget/composite.c
+++ b/drivers/usb/gadget/composite.c
@@ -723,12 +723,12 @@ int usb_string_ids_tab(struct usb_composite_dev *cdev, struct usb_string *str)
723 723
724/** 724/**
725 * usb_string_ids_n() - allocate unused string IDs in batch 725 * usb_string_ids_n() - allocate unused string IDs in batch
726 * @cdev: the device whose string descriptor IDs are being allocated 726 * @c: the device whose string descriptor IDs are being allocated
727 * @n: number of string IDs to allocate 727 * @n: number of string IDs to allocate
728 * Context: single threaded during gadget setup 728 * Context: single threaded during gadget setup
729 * 729 *
730 * Returns the first requested ID. This ID and next @n-1 IDs are now 730 * Returns the first requested ID. This ID and next @n-1 IDs are now
731 * valid IDs. At least providind that @n is non zore because if it 731 * valid IDs. At least provided that @n is non-zero because if it
732 * is, returns last requested ID which is now very useful information. 732 * is, returns last requested ID which is now very useful information.
733 * 733 *
734 * @usb_string_ids_n() is called from bind() callbacks to allocate 734 * @usb_string_ids_n() is called from bind() callbacks to allocate
diff --git a/drivers/usb/gadget/m66592-udc.c b/drivers/usb/gadget/m66592-udc.c
index 166bf71fd348..e03058fe23cb 100644
--- a/drivers/usb/gadget/m66592-udc.c
+++ b/drivers/usb/gadget/m66592-udc.c
@@ -1609,6 +1609,7 @@ static int __init m66592_probe(struct platform_device *pdev)
1609 /* initialize ucd */ 1609 /* initialize ucd */
1610 m66592 = kzalloc(sizeof(struct m66592), GFP_KERNEL); 1610 m66592 = kzalloc(sizeof(struct m66592), GFP_KERNEL);
1611 if (m66592 == NULL) { 1611 if (m66592 == NULL) {
1612 ret = -ENOMEM;
1612 pr_err("kzalloc error\n"); 1613 pr_err("kzalloc error\n");
1613 goto clean_up; 1614 goto clean_up;
1614 } 1615 }
diff --git a/drivers/usb/gadget/r8a66597-udc.c b/drivers/usb/gadget/r8a66597-udc.c
index 70a817842755..2456ccd9965e 100644
--- a/drivers/usb/gadget/r8a66597-udc.c
+++ b/drivers/usb/gadget/r8a66597-udc.c
@@ -1557,6 +1557,7 @@ static int __init r8a66597_probe(struct platform_device *pdev)
1557 /* initialize ucd */ 1557 /* initialize ucd */
1558 r8a66597 = kzalloc(sizeof(struct r8a66597), GFP_KERNEL); 1558 r8a66597 = kzalloc(sizeof(struct r8a66597), GFP_KERNEL);
1559 if (r8a66597 == NULL) { 1559 if (r8a66597 == NULL) {
1560 ret = -ENOMEM;
1560 printk(KERN_ERR "kzalloc error\n"); 1561 printk(KERN_ERR "kzalloc error\n");
1561 goto clean_up; 1562 goto clean_up;
1562 } 1563 }
diff --git a/drivers/usb/gadget/uvc_v4l2.c b/drivers/usb/gadget/uvc_v4l2.c
index 2dcffdac86d2..5e807f083bc8 100644
--- a/drivers/usb/gadget/uvc_v4l2.c
+++ b/drivers/usb/gadget/uvc_v4l2.c
@@ -94,7 +94,7 @@ uvc_v4l2_set_format(struct uvc_video *video, struct v4l2_format *fmt)
94 break; 94 break;
95 } 95 }
96 96
97 if (format == NULL || format->fcc != fmt->fmt.pix.pixelformat) { 97 if (i == ARRAY_SIZE(uvc_formats)) {
98 printk(KERN_INFO "Unsupported format 0x%08x.\n", 98 printk(KERN_INFO "Unsupported format 0x%08x.\n",
99 fmt->fmt.pix.pixelformat); 99 fmt->fmt.pix.pixelformat);
100 return -EINVAL; 100 return -EINVAL;
diff --git a/drivers/usb/host/isp1760-hcd.c b/drivers/usb/host/isp1760-hcd.c
index d1a3dfc9a408..bdba8c5d844a 100644
--- a/drivers/usb/host/isp1760-hcd.c
+++ b/drivers/usb/host/isp1760-hcd.c
@@ -829,6 +829,7 @@ static void enqueue_an_ATL_packet(struct usb_hcd *hcd, struct isp1760_qh *qh,
829 * almost immediately. With ISP1761, this register requires a delay of 829 * almost immediately. With ISP1761, this register requires a delay of
830 * 195ns between a write and subsequent read (see section 15.1.1.3). 830 * 195ns between a write and subsequent read (see section 15.1.1.3).
831 */ 831 */
832 mmiowb();
832 ndelay(195); 833 ndelay(195);
833 skip_map = isp1760_readl(hcd->regs + HC_ATL_PTD_SKIPMAP_REG); 834 skip_map = isp1760_readl(hcd->regs + HC_ATL_PTD_SKIPMAP_REG);
834 835
@@ -870,6 +871,7 @@ static void enqueue_an_INT_packet(struct usb_hcd *hcd, struct isp1760_qh *qh,
870 * almost immediately. With ISP1761, this register requires a delay of 871 * almost immediately. With ISP1761, this register requires a delay of
871 * 195ns between a write and subsequent read (see section 15.1.1.3). 872 * 195ns between a write and subsequent read (see section 15.1.1.3).
872 */ 873 */
874 mmiowb();
873 ndelay(195); 875 ndelay(195);
874 skip_map = isp1760_readl(hcd->regs + HC_INT_PTD_SKIPMAP_REG); 876 skip_map = isp1760_readl(hcd->regs + HC_INT_PTD_SKIPMAP_REG);
875 877
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index bc3f4f427065..48e60d166ff0 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -131,7 +131,7 @@ static void next_trb(struct xhci_hcd *xhci,
131 *seg = (*seg)->next; 131 *seg = (*seg)->next;
132 *trb = ((*seg)->trbs); 132 *trb = ((*seg)->trbs);
133 } else { 133 } else {
134 *trb = (*trb)++; 134 (*trb)++;
135 } 135 }
136} 136}
137 137
@@ -1551,6 +1551,10 @@ static int process_isoc_td(struct xhci_hcd *xhci, struct xhci_td *td,
1551 /* calc actual length */ 1551 /* calc actual length */
1552 if (ep->skip) { 1552 if (ep->skip) {
1553 td->urb->iso_frame_desc[idx].actual_length = 0; 1553 td->urb->iso_frame_desc[idx].actual_length = 0;
1554 /* Update ring dequeue pointer */
1555 while (ep_ring->dequeue != td->last_trb)
1556 inc_deq(xhci, ep_ring, false);
1557 inc_deq(xhci, ep_ring, false);
1554 return finish_td(xhci, td, event_trb, event, ep, status, true); 1558 return finish_td(xhci, td, event_trb, event, ep, status, true);
1555 } 1559 }
1556 1560
diff --git a/drivers/usb/misc/adutux.c b/drivers/usb/misc/adutux.c
index d240de097c62..801324af9470 100644
--- a/drivers/usb/misc/adutux.c
+++ b/drivers/usb/misc/adutux.c
@@ -439,7 +439,7 @@ static ssize_t adu_read(struct file *file, __user char *buffer, size_t count,
439 /* drain secondary buffer */ 439 /* drain secondary buffer */
440 int amount = bytes_to_read < data_in_secondary ? bytes_to_read : data_in_secondary; 440 int amount = bytes_to_read < data_in_secondary ? bytes_to_read : data_in_secondary;
441 i = copy_to_user(buffer, dev->read_buffer_secondary+dev->secondary_head, amount); 441 i = copy_to_user(buffer, dev->read_buffer_secondary+dev->secondary_head, amount);
442 if (i < 0) { 442 if (i) {
443 retval = -EFAULT; 443 retval = -EFAULT;
444 goto exit; 444 goto exit;
445 } 445 }
diff --git a/drivers/usb/misc/iowarrior.c b/drivers/usb/misc/iowarrior.c
index 2de49c8887c5..bc88c79875a1 100644
--- a/drivers/usb/misc/iowarrior.c
+++ b/drivers/usb/misc/iowarrior.c
@@ -542,7 +542,7 @@ static long iowarrior_ioctl(struct file *file, unsigned int cmd,
542 retval = io_res; 542 retval = io_res;
543 else { 543 else {
544 io_res = copy_to_user(user_buffer, buffer, dev->report_size); 544 io_res = copy_to_user(user_buffer, buffer, dev->report_size);
545 if (io_res < 0) 545 if (io_res)
546 retval = -EFAULT; 546 retval = -EFAULT;
547 } 547 }
548 break; 548 break;
@@ -574,7 +574,7 @@ static long iowarrior_ioctl(struct file *file, unsigned int cmd,
574 } 574 }
575 io_res = copy_to_user((struct iowarrior_info __user *)arg, &info, 575 io_res = copy_to_user((struct iowarrior_info __user *)arg, &info,
576 sizeof(struct iowarrior_info)); 576 sizeof(struct iowarrior_info));
577 if (io_res < 0) 577 if (io_res)
578 retval = -EFAULT; 578 retval = -EFAULT;
579 break; 579 break;
580 } 580 }
diff --git a/drivers/usb/otg/twl4030-usb.c b/drivers/usb/otg/twl4030-usb.c
index 0e8888588d4e..05aaac1c3861 100644
--- a/drivers/usb/otg/twl4030-usb.c
+++ b/drivers/usb/otg/twl4030-usb.c
@@ -550,6 +550,7 @@ static int __devinit twl4030_usb_probe(struct platform_device *pdev)
550 struct twl4030_usb_data *pdata = pdev->dev.platform_data; 550 struct twl4030_usb_data *pdata = pdev->dev.platform_data;
551 struct twl4030_usb *twl; 551 struct twl4030_usb *twl;
552 int status, err; 552 int status, err;
553 u8 pwr;
553 554
554 if (!pdata) { 555 if (!pdata) {
555 dev_dbg(&pdev->dev, "platform_data not available\n"); 556 dev_dbg(&pdev->dev, "platform_data not available\n");
@@ -568,7 +569,10 @@ static int __devinit twl4030_usb_probe(struct platform_device *pdev)
568 twl->otg.set_peripheral = twl4030_set_peripheral; 569 twl->otg.set_peripheral = twl4030_set_peripheral;
569 twl->otg.set_suspend = twl4030_set_suspend; 570 twl->otg.set_suspend = twl4030_set_suspend;
570 twl->usb_mode = pdata->usb_mode; 571 twl->usb_mode = pdata->usb_mode;
571 twl->asleep = 1; 572
573 pwr = twl4030_usb_read(twl, PHY_PWR_CTRL);
574
575 twl->asleep = (pwr & PHY_PWR_PHYPWD);
572 576
573 /* init spinlock for workqueue */ 577 /* init spinlock for workqueue */
574 spin_lock_init(&twl->lock); 578 spin_lock_init(&twl->lock);
diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c
index 2bef4415c19c..80bf8333bb03 100644
--- a/drivers/usb/serial/cp210x.c
+++ b/drivers/usb/serial/cp210x.c
@@ -222,8 +222,8 @@ static struct usb_serial_driver cp210x_device = {
222#define BITS_STOP_2 0x0002 222#define BITS_STOP_2 0x0002
223 223
224/* CP210X_SET_BREAK */ 224/* CP210X_SET_BREAK */
225#define BREAK_ON 0x0000 225#define BREAK_ON 0x0001
226#define BREAK_OFF 0x0001 226#define BREAK_OFF 0x0000
227 227
228/* CP210X_(SET_MHS|GET_MDMSTS) */ 228/* CP210X_(SET_MHS|GET_MDMSTS) */
229#define CONTROL_DTR 0x0001 229#define CONTROL_DTR 0x0001
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
index eb12d9b096b4..63ddb2f65cee 100644
--- a/drivers/usb/serial/ftdi_sio.c
+++ b/drivers/usb/serial/ftdi_sio.c
@@ -180,6 +180,7 @@ static struct usb_device_id id_table_combined [] = {
180 { USB_DEVICE(INTERBIOMETRICS_VID, INTERBIOMETRICS_IOBOARD_PID) }, 180 { USB_DEVICE(INTERBIOMETRICS_VID, INTERBIOMETRICS_IOBOARD_PID) },
181 { USB_DEVICE(INTERBIOMETRICS_VID, INTERBIOMETRICS_MINI_IOBOARD_PID) }, 181 { USB_DEVICE(INTERBIOMETRICS_VID, INTERBIOMETRICS_MINI_IOBOARD_PID) },
182 { USB_DEVICE(FTDI_VID, FTDI_SPROG_II) }, 182 { USB_DEVICE(FTDI_VID, FTDI_SPROG_II) },
183 { USB_DEVICE(FTDI_VID, FTDI_LENZ_LIUSB_PID) },
183 { USB_DEVICE(FTDI_VID, FTDI_XF_632_PID) }, 184 { USB_DEVICE(FTDI_VID, FTDI_XF_632_PID) },
184 { USB_DEVICE(FTDI_VID, FTDI_XF_634_PID) }, 185 { USB_DEVICE(FTDI_VID, FTDI_XF_634_PID) },
185 { USB_DEVICE(FTDI_VID, FTDI_XF_547_PID) }, 186 { USB_DEVICE(FTDI_VID, FTDI_XF_547_PID) },
@@ -750,6 +751,8 @@ static struct usb_device_id id_table_combined [] = {
750 { USB_DEVICE(FTDI_VID, XVERVE_SIGNALYZER_SH4_PID), 751 { USB_DEVICE(FTDI_VID, XVERVE_SIGNALYZER_SH4_PID),
751 .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, 752 .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
752 { USB_DEVICE(FTDI_VID, SEGWAY_RMP200_PID) }, 753 { USB_DEVICE(FTDI_VID, SEGWAY_RMP200_PID) },
754 { USB_DEVICE(IONICS_VID, IONICS_PLUGCOMPUTER_PID),
755 .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
753 { }, /* Optional parameter entry */ 756 { }, /* Optional parameter entry */
754 { } /* Terminating entry */ 757 { } /* Terminating entry */
755}; 758};
@@ -1376,7 +1379,7 @@ static void ftdi_set_max_packet_size(struct usb_serial_port *port)
1376 } 1379 }
1377 1380
1378 /* set max packet size based on descriptor */ 1381 /* set max packet size based on descriptor */
1379 priv->max_packet_size = ep_desc->wMaxPacketSize; 1382 priv->max_packet_size = le16_to_cpu(ep_desc->wMaxPacketSize);
1380 1383
1381 dev_info(&udev->dev, "Setting MaxPacketSize %d\n", priv->max_packet_size); 1384 dev_info(&udev->dev, "Setting MaxPacketSize %d\n", priv->max_packet_size);
1382} 1385}
diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h
index 6e612c52e763..2e95857c9633 100644
--- a/drivers/usb/serial/ftdi_sio_ids.h
+++ b/drivers/usb/serial/ftdi_sio_ids.h
@@ -110,6 +110,9 @@
110/* Propox devices */ 110/* Propox devices */
111#define FTDI_PROPOX_JTAGCABLEII_PID 0xD738 111#define FTDI_PROPOX_JTAGCABLEII_PID 0xD738
112 112
113/* Lenz LI-USB Computer Interface. */
114#define FTDI_LENZ_LIUSB_PID 0xD780
115
113/* 116/*
114 * Xsens Technologies BV products (http://www.xsens.com). 117 * Xsens Technologies BV products (http://www.xsens.com).
115 */ 118 */
@@ -989,6 +992,12 @@
989#define ALTI2_N3_PID 0x6001 /* Neptune 3 */ 992#define ALTI2_N3_PID 0x6001 /* Neptune 3 */
990 993
991/* 994/*
995 * Ionics PlugComputer
996 */
997#define IONICS_VID 0x1c0c
998#define IONICS_PLUGCOMPUTER_PID 0x0102
999
1000/*
992 * Dresden Elektronik Sensor Terminal Board 1001 * Dresden Elektronik Sensor Terminal Board
993 */ 1002 */
994#define DE_VID 0x1cf1 /* Vendor ID */ 1003#define DE_VID 0x1cf1 /* Vendor ID */
diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c
index ca92f67747cc..0b1a13384c6d 100644
--- a/drivers/usb/serial/generic.c
+++ b/drivers/usb/serial/generic.c
@@ -518,6 +518,7 @@ void usb_serial_generic_disconnect(struct usb_serial *serial)
518 for (i = 0; i < serial->num_ports; ++i) 518 for (i = 0; i < serial->num_ports; ++i)
519 generic_cleanup(serial->port[i]); 519 generic_cleanup(serial->port[i]);
520} 520}
521EXPORT_SYMBOL_GPL(usb_serial_generic_disconnect);
521 522
522void usb_serial_generic_release(struct usb_serial *serial) 523void usb_serial_generic_release(struct usb_serial *serial)
523{ 524{
diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c
index dc47f986df57..a7cfc5952937 100644
--- a/drivers/usb/serial/io_ti.c
+++ b/drivers/usb/serial/io_ti.c
@@ -1151,7 +1151,7 @@ static int download_fw(struct edgeport_serial *serial)
1151 1151
1152 /* Check if we have an old version in the I2C and 1152 /* Check if we have an old version in the I2C and
1153 update if necessary */ 1153 update if necessary */
1154 if (download_cur_ver != download_new_ver) { 1154 if (download_cur_ver < download_new_ver) {
1155 dbg("%s - Update I2C dld from %d.%d to %d.%d", 1155 dbg("%s - Update I2C dld from %d.%d to %d.%d",
1156 __func__, 1156 __func__,
1157 firmware_version->Ver_Major, 1157 firmware_version->Ver_Major,
@@ -1284,7 +1284,7 @@ static int download_fw(struct edgeport_serial *serial)
1284 kfree(header); 1284 kfree(header);
1285 kfree(rom_desc); 1285 kfree(rom_desc);
1286 kfree(ti_manuf_desc); 1286 kfree(ti_manuf_desc);
1287 return status; 1287 return -EINVAL;
1288 } 1288 }
1289 1289
1290 /* Update I2C with type 0xf2 record with correct 1290 /* Update I2C with type 0xf2 record with correct
diff --git a/drivers/usb/serial/navman.c b/drivers/usb/serial/navman.c
index a6b207c84917..1f00f243c26c 100644
--- a/drivers/usb/serial/navman.c
+++ b/drivers/usb/serial/navman.c
@@ -25,6 +25,7 @@ static int debug;
25 25
26static const struct usb_device_id id_table[] = { 26static const struct usb_device_id id_table[] = {
27 { USB_DEVICE(0x0a99, 0x0001) }, /* Talon Technology device */ 27 { USB_DEVICE(0x0a99, 0x0001) }, /* Talon Technology device */
28 { USB_DEVICE(0x0df7, 0x0900) }, /* Mobile Action i-gotU */
28 { }, 29 { },
29}; 30};
30MODULE_DEVICE_TABLE(usb, id_table); 31MODULE_DEVICE_TABLE(usb, id_table);
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
index 9fc6ea2c681f..adcbdb994de3 100644
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -365,6 +365,10 @@ static void option_instat_callback(struct urb *urb);
365#define OLIVETTI_VENDOR_ID 0x0b3c 365#define OLIVETTI_VENDOR_ID 0x0b3c
366#define OLIVETTI_PRODUCT_OLICARD100 0xc000 366#define OLIVETTI_PRODUCT_OLICARD100 0xc000
367 367
368/* Celot products */
369#define CELOT_VENDOR_ID 0x211f
370#define CELOT_PRODUCT_CT680M 0x6801
371
368/* some devices interfaces need special handling due to a number of reasons */ 372/* some devices interfaces need special handling due to a number of reasons */
369enum option_blacklist_reason { 373enum option_blacklist_reason {
370 OPTION_BLACKLIST_NONE = 0, 374 OPTION_BLACKLIST_NONE = 0,
@@ -887,10 +891,9 @@ static const struct usb_device_id option_ids[] = {
887 { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_100F) }, 891 { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_100F) },
888 { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1011)}, 892 { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1011)},
889 { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1012)}, 893 { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1012)},
890
891 { USB_DEVICE(CINTERION_VENDOR_ID, 0x0047) }, 894 { USB_DEVICE(CINTERION_VENDOR_ID, 0x0047) },
892
893 { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD100) }, 895 { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD100) },
896 { USB_DEVICE(CELOT_VENDOR_ID, CELOT_PRODUCT_CT680M) }, /* CT-650 CDMA 450 1xEVDO modem */
894 { } /* Terminating entry */ 897 { } /* Terminating entry */
895}; 898};
896MODULE_DEVICE_TABLE(usb, option_ids); 899MODULE_DEVICE_TABLE(usb, option_ids);
diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c
index 6b6001822279..c98f0fb675ba 100644
--- a/drivers/usb/serial/pl2303.c
+++ b/drivers/usb/serial/pl2303.c
@@ -86,6 +86,7 @@ static const struct usb_device_id id_table[] = {
86 { USB_DEVICE(SUPERIAL_VENDOR_ID, SUPERIAL_PRODUCT_ID) }, 86 { USB_DEVICE(SUPERIAL_VENDOR_ID, SUPERIAL_PRODUCT_ID) },
87 { USB_DEVICE(HP_VENDOR_ID, HP_LD220_PRODUCT_ID) }, 87 { USB_DEVICE(HP_VENDOR_ID, HP_LD220_PRODUCT_ID) },
88 { USB_DEVICE(CRESSI_VENDOR_ID, CRESSI_EDY_PRODUCT_ID) }, 88 { USB_DEVICE(CRESSI_VENDOR_ID, CRESSI_EDY_PRODUCT_ID) },
89 { USB_DEVICE(ZEAGLE_VENDOR_ID, ZEAGLE_N2ITION3_PRODUCT_ID) },
89 { USB_DEVICE(SONY_VENDOR_ID, SONY_QN3USB_PRODUCT_ID) }, 90 { USB_DEVICE(SONY_VENDOR_ID, SONY_QN3USB_PRODUCT_ID) },
90 { USB_DEVICE(SANWA_VENDOR_ID, SANWA_PRODUCT_ID) }, 91 { USB_DEVICE(SANWA_VENDOR_ID, SANWA_PRODUCT_ID) },
91 { USB_DEVICE(ADLINK_VENDOR_ID, ADLINK_ND6530_PRODUCT_ID) }, 92 { USB_DEVICE(ADLINK_VENDOR_ID, ADLINK_ND6530_PRODUCT_ID) },
diff --git a/drivers/usb/serial/pl2303.h b/drivers/usb/serial/pl2303.h
index a871645389dd..43eb9bdad422 100644
--- a/drivers/usb/serial/pl2303.h
+++ b/drivers/usb/serial/pl2303.h
@@ -128,6 +128,10 @@
128#define CRESSI_VENDOR_ID 0x04b8 128#define CRESSI_VENDOR_ID 0x04b8
129#define CRESSI_EDY_PRODUCT_ID 0x0521 129#define CRESSI_EDY_PRODUCT_ID 0x0521
130 130
131/* Zeagle dive computer interface */
132#define ZEAGLE_VENDOR_ID 0x04b8
133#define ZEAGLE_N2ITION3_PRODUCT_ID 0x0522
134
131/* Sony, USB data cable for CMD-Jxx mobile phones */ 135/* Sony, USB data cable for CMD-Jxx mobile phones */
132#define SONY_VENDOR_ID 0x054c 136#define SONY_VENDOR_ID 0x054c
133#define SONY_QN3USB_PRODUCT_ID 0x0437 137#define SONY_QN3USB_PRODUCT_ID 0x0437
diff --git a/drivers/usb/serial/ssu100.c b/drivers/usb/serial/ssu100.c
index 6e82d4f54bc8..660c31f14999 100644
--- a/drivers/usb/serial/ssu100.c
+++ b/drivers/usb/serial/ssu100.c
@@ -15,6 +15,7 @@
15#include <linux/serial.h> 15#include <linux/serial.h>
16#include <linux/usb.h> 16#include <linux/usb.h>
17#include <linux/usb/serial.h> 17#include <linux/usb/serial.h>
18#include <linux/serial_reg.h>
18#include <linux/uaccess.h> 19#include <linux/uaccess.h>
19 20
20#define QT_OPEN_CLOSE_CHANNEL 0xca 21#define QT_OPEN_CLOSE_CHANNEL 0xca
@@ -27,36 +28,11 @@
27#define QT_HW_FLOW_CONTROL_MASK 0xc5 28#define QT_HW_FLOW_CONTROL_MASK 0xc5
28#define QT_SW_FLOW_CONTROL_MASK 0xc6 29#define QT_SW_FLOW_CONTROL_MASK 0xc6
29 30
30#define MODEM_CTL_REGISTER 0x04
31#define MODEM_STATUS_REGISTER 0x06
32
33
34#define SERIAL_LSR_OE 0x02
35#define SERIAL_LSR_PE 0x04
36#define SERIAL_LSR_FE 0x08
37#define SERIAL_LSR_BI 0x10
38
39#define SERIAL_LSR_TEMT 0x40
40
41#define SERIAL_MCR_DTR 0x01
42#define SERIAL_MCR_RTS 0x02
43#define SERIAL_MCR_LOOP 0x10
44
45#define SERIAL_MSR_CTS 0x10
46#define SERIAL_MSR_CD 0x80
47#define SERIAL_MSR_RI 0x40
48#define SERIAL_MSR_DSR 0x20
49#define SERIAL_MSR_MASK 0xf0 31#define SERIAL_MSR_MASK 0xf0
50 32
51#define SERIAL_CRTSCTS ((SERIAL_MCR_RTS << 8) | SERIAL_MSR_CTS) 33#define SERIAL_CRTSCTS ((UART_MCR_RTS << 8) | UART_MSR_CTS)
52 34
53#define SERIAL_8_DATA 0x03 35#define SERIAL_EVEN_PARITY (UART_LCR_PARITY | UART_LCR_EPAR)
54#define SERIAL_7_DATA 0x02
55#define SERIAL_6_DATA 0x01
56#define SERIAL_5_DATA 0x00
57
58#define SERIAL_ODD_PARITY 0X08
59#define SERIAL_EVEN_PARITY 0X18
60 36
61#define MAX_BAUD_RATE 460800 37#define MAX_BAUD_RATE 460800
62 38
@@ -99,10 +75,12 @@ static struct usb_driver ssu100_driver = {
99}; 75};
100 76
101struct ssu100_port_private { 77struct ssu100_port_private {
78 spinlock_t status_lock;
102 u8 shadowLSR; 79 u8 shadowLSR;
103 u8 shadowMSR; 80 u8 shadowMSR;
104 wait_queue_head_t delta_msr_wait; /* Used for TIOCMIWAIT */ 81 wait_queue_head_t delta_msr_wait; /* Used for TIOCMIWAIT */
105 unsigned short max_packet_size; 82 unsigned short max_packet_size;
83 struct async_icount icount;
106}; 84};
107 85
108static void ssu100_release(struct usb_serial *serial) 86static void ssu100_release(struct usb_serial *serial)
@@ -150,9 +128,10 @@ static inline int ssu100_getregister(struct usb_device *dev,
150 128
151static inline int ssu100_setregister(struct usb_device *dev, 129static inline int ssu100_setregister(struct usb_device *dev,
152 unsigned short uart, 130 unsigned short uart,
131 unsigned short reg,
153 u16 data) 132 u16 data)
154{ 133{
155 u16 value = (data << 8) | MODEM_CTL_REGISTER; 134 u16 value = (data << 8) | reg;
156 135
157 return usb_control_msg(dev, usb_sndctrlpipe(dev, 0), 136 return usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
158 QT_SET_GET_REGISTER, 0x40, value, uart, 137 QT_SET_GET_REGISTER, 0x40, value, uart,
@@ -178,11 +157,11 @@ static inline int update_mctrl(struct usb_device *dev, unsigned int set,
178 clear &= ~set; /* 'set' takes precedence over 'clear' */ 157 clear &= ~set; /* 'set' takes precedence over 'clear' */
179 urb_value = 0; 158 urb_value = 0;
180 if (set & TIOCM_DTR) 159 if (set & TIOCM_DTR)
181 urb_value |= SERIAL_MCR_DTR; 160 urb_value |= UART_MCR_DTR;
182 if (set & TIOCM_RTS) 161 if (set & TIOCM_RTS)
183 urb_value |= SERIAL_MCR_RTS; 162 urb_value |= UART_MCR_RTS;
184 163
185 result = ssu100_setregister(dev, 0, urb_value); 164 result = ssu100_setregister(dev, 0, UART_MCR, urb_value);
186 if (result < 0) 165 if (result < 0)
187 dbg("%s Error from MODEM_CTRL urb", __func__); 166 dbg("%s Error from MODEM_CTRL urb", __func__);
188 167
@@ -264,24 +243,24 @@ static void ssu100_set_termios(struct tty_struct *tty,
264 243
265 if (cflag & PARENB) { 244 if (cflag & PARENB) {
266 if (cflag & PARODD) 245 if (cflag & PARODD)
267 urb_value |= SERIAL_ODD_PARITY; 246 urb_value |= UART_LCR_PARITY;
268 else 247 else
269 urb_value |= SERIAL_EVEN_PARITY; 248 urb_value |= SERIAL_EVEN_PARITY;
270 } 249 }
271 250
272 switch (cflag & CSIZE) { 251 switch (cflag & CSIZE) {
273 case CS5: 252 case CS5:
274 urb_value |= SERIAL_5_DATA; 253 urb_value |= UART_LCR_WLEN5;
275 break; 254 break;
276 case CS6: 255 case CS6:
277 urb_value |= SERIAL_6_DATA; 256 urb_value |= UART_LCR_WLEN6;
278 break; 257 break;
279 case CS7: 258 case CS7:
280 urb_value |= SERIAL_7_DATA; 259 urb_value |= UART_LCR_WLEN7;
281 break; 260 break;
282 default: 261 default:
283 case CS8: 262 case CS8:
284 urb_value |= SERIAL_8_DATA; 263 urb_value |= UART_LCR_WLEN8;
285 break; 264 break;
286 } 265 }
287 266
@@ -333,6 +312,7 @@ static int ssu100_open(struct tty_struct *tty, struct usb_serial_port *port)
333 struct ssu100_port_private *priv = usb_get_serial_port_data(port); 312 struct ssu100_port_private *priv = usb_get_serial_port_data(port);
334 u8 *data; 313 u8 *data;
335 int result; 314 int result;
315 unsigned long flags;
336 316
337 dbg("%s - port %d", __func__, port->number); 317 dbg("%s - port %d", __func__, port->number);
338 318
@@ -350,11 +330,10 @@ static int ssu100_open(struct tty_struct *tty, struct usb_serial_port *port)
350 return result; 330 return result;
351 } 331 }
352 332
353 priv->shadowLSR = data[0] & (SERIAL_LSR_OE | SERIAL_LSR_PE | 333 spin_lock_irqsave(&priv->status_lock, flags);
354 SERIAL_LSR_FE | SERIAL_LSR_BI); 334 priv->shadowLSR = data[0];
355 335 priv->shadowMSR = data[1];
356 priv->shadowMSR = data[1] & (SERIAL_MSR_CTS | SERIAL_MSR_DSR | 336 spin_unlock_irqrestore(&priv->status_lock, flags);
357 SERIAL_MSR_RI | SERIAL_MSR_CD);
358 337
359 kfree(data); 338 kfree(data);
360 339
@@ -398,11 +377,51 @@ static int get_serial_info(struct usb_serial_port *port,
398 return 0; 377 return 0;
399} 378}
400 379
380static int wait_modem_info(struct usb_serial_port *port, unsigned int arg)
381{
382 struct ssu100_port_private *priv = usb_get_serial_port_data(port);
383 struct async_icount prev, cur;
384 unsigned long flags;
385
386 spin_lock_irqsave(&priv->status_lock, flags);
387 prev = priv->icount;
388 spin_unlock_irqrestore(&priv->status_lock, flags);
389
390 while (1) {
391 wait_event_interruptible(priv->delta_msr_wait,
392 ((priv->icount.rng != prev.rng) ||
393 (priv->icount.dsr != prev.dsr) ||
394 (priv->icount.dcd != prev.dcd) ||
395 (priv->icount.cts != prev.cts)));
396
397 if (signal_pending(current))
398 return -ERESTARTSYS;
399
400 spin_lock_irqsave(&priv->status_lock, flags);
401 cur = priv->icount;
402 spin_unlock_irqrestore(&priv->status_lock, flags);
403
404 if ((prev.rng == cur.rng) &&
405 (prev.dsr == cur.dsr) &&
406 (prev.dcd == cur.dcd) &&
407 (prev.cts == cur.cts))
408 return -EIO;
409
410 if ((arg & TIOCM_RNG && (prev.rng != cur.rng)) ||
411 (arg & TIOCM_DSR && (prev.dsr != cur.dsr)) ||
412 (arg & TIOCM_CD && (prev.dcd != cur.dcd)) ||
413 (arg & TIOCM_CTS && (prev.cts != cur.cts)))
414 return 0;
415 }
416 return 0;
417}
418
401static int ssu100_ioctl(struct tty_struct *tty, struct file *file, 419static int ssu100_ioctl(struct tty_struct *tty, struct file *file,
402 unsigned int cmd, unsigned long arg) 420 unsigned int cmd, unsigned long arg)
403{ 421{
404 struct usb_serial_port *port = tty->driver_data; 422 struct usb_serial_port *port = tty->driver_data;
405 struct ssu100_port_private *priv = usb_get_serial_port_data(port); 423 struct ssu100_port_private *priv = usb_get_serial_port_data(port);
424 void __user *user_arg = (void __user *)arg;
406 425
407 dbg("%s cmd 0x%04x", __func__, cmd); 426 dbg("%s cmd 0x%04x", __func__, cmd);
408 427
@@ -412,28 +431,28 @@ static int ssu100_ioctl(struct tty_struct *tty, struct file *file,
412 (struct serial_struct __user *) arg); 431 (struct serial_struct __user *) arg);
413 432
414 case TIOCMIWAIT: 433 case TIOCMIWAIT:
415 while (priv != NULL) { 434 return wait_modem_info(port, arg);
416 u8 prevMSR = priv->shadowMSR & SERIAL_MSR_MASK; 435
417 interruptible_sleep_on(&priv->delta_msr_wait); 436 case TIOCGICOUNT:
418 /* see if a signal did it */ 437 {
419 if (signal_pending(current)) 438 struct serial_icounter_struct icount;
420 return -ERESTARTSYS; 439 struct async_icount cnow = priv->icount;
421 else { 440 memset(&icount, 0, sizeof(icount));
422 u8 diff = (priv->shadowMSR & SERIAL_MSR_MASK) ^ prevMSR; 441 icount.cts = cnow.cts;
423 if (!diff) 442 icount.dsr = cnow.dsr;
424 return -EIO; /* no change => error */ 443 icount.rng = cnow.rng;
425 444 icount.dcd = cnow.dcd;
426 /* Return 0 if caller wanted to know about 445 icount.rx = cnow.rx;
427 these bits */ 446 icount.tx = cnow.tx;
428 447 icount.frame = cnow.frame;
429 if (((arg & TIOCM_RNG) && (diff & SERIAL_MSR_RI)) || 448 icount.overrun = cnow.overrun;
430 ((arg & TIOCM_DSR) && (diff & SERIAL_MSR_DSR)) || 449 icount.parity = cnow.parity;
431 ((arg & TIOCM_CD) && (diff & SERIAL_MSR_CD)) || 450 icount.brk = cnow.brk;
432 ((arg & TIOCM_CTS) && (diff & SERIAL_MSR_CTS))) 451 icount.buf_overrun = cnow.buf_overrun;
433 return 0; 452 if (copy_to_user(user_arg, &icount, sizeof(icount)))
434 } 453 return -EFAULT;
435 }
436 return 0; 454 return 0;
455 }
437 456
438 default: 457 default:
439 break; 458 break;
@@ -455,6 +474,7 @@ static void ssu100_set_max_packet_size(struct usb_serial_port *port)
455 474
456 unsigned num_endpoints; 475 unsigned num_endpoints;
457 int i; 476 int i;
477 unsigned long flags;
458 478
459 num_endpoints = interface->cur_altsetting->desc.bNumEndpoints; 479 num_endpoints = interface->cur_altsetting->desc.bNumEndpoints;
460 dev_info(&udev->dev, "Number of endpoints %d\n", num_endpoints); 480 dev_info(&udev->dev, "Number of endpoints %d\n", num_endpoints);
@@ -466,7 +486,9 @@ static void ssu100_set_max_packet_size(struct usb_serial_port *port)
466 } 486 }
467 487
468 /* set max packet size based on descriptor */ 488 /* set max packet size based on descriptor */
489 spin_lock_irqsave(&priv->status_lock, flags);
469 priv->max_packet_size = ep_desc->wMaxPacketSize; 490 priv->max_packet_size = ep_desc->wMaxPacketSize;
491 spin_unlock_irqrestore(&priv->status_lock, flags);
470 492
471 dev_info(&udev->dev, "Setting MaxPacketSize %d\n", priv->max_packet_size); 493 dev_info(&udev->dev, "Setting MaxPacketSize %d\n", priv->max_packet_size);
472} 494}
@@ -485,9 +507,9 @@ static int ssu100_attach(struct usb_serial *serial)
485 return -ENOMEM; 507 return -ENOMEM;
486 } 508 }
487 509
510 spin_lock_init(&priv->status_lock);
488 init_waitqueue_head(&priv->delta_msr_wait); 511 init_waitqueue_head(&priv->delta_msr_wait);
489 usb_set_serial_port_data(port, priv); 512 usb_set_serial_port_data(port, priv);
490
491 ssu100_set_max_packet_size(port); 513 ssu100_set_max_packet_size(port);
492 514
493 return ssu100_initdevice(serial->dev); 515 return ssu100_initdevice(serial->dev);
@@ -506,20 +528,20 @@ static int ssu100_tiocmget(struct tty_struct *tty, struct file *file)
506 if (!d) 528 if (!d)
507 return -ENOMEM; 529 return -ENOMEM;
508 530
509 r = ssu100_getregister(dev, 0, MODEM_CTL_REGISTER, d); 531 r = ssu100_getregister(dev, 0, UART_MCR, d);
510 if (r < 0) 532 if (r < 0)
511 goto mget_out; 533 goto mget_out;
512 534
513 r = ssu100_getregister(dev, 0, MODEM_STATUS_REGISTER, d+1); 535 r = ssu100_getregister(dev, 0, UART_MSR, d+1);
514 if (r < 0) 536 if (r < 0)
515 goto mget_out; 537 goto mget_out;
516 538
517 r = (d[0] & SERIAL_MCR_DTR ? TIOCM_DTR : 0) | 539 r = (d[0] & UART_MCR_DTR ? TIOCM_DTR : 0) |
518 (d[0] & SERIAL_MCR_RTS ? TIOCM_RTS : 0) | 540 (d[0] & UART_MCR_RTS ? TIOCM_RTS : 0) |
519 (d[1] & SERIAL_MSR_CTS ? TIOCM_CTS : 0) | 541 (d[1] & UART_MSR_CTS ? TIOCM_CTS : 0) |
520 (d[1] & SERIAL_MSR_CD ? TIOCM_CAR : 0) | 542 (d[1] & UART_MSR_DCD ? TIOCM_CAR : 0) |
521 (d[1] & SERIAL_MSR_RI ? TIOCM_RI : 0) | 543 (d[1] & UART_MSR_RI ? TIOCM_RI : 0) |
522 (d[1] & SERIAL_MSR_DSR ? TIOCM_DSR : 0); 544 (d[1] & UART_MSR_DSR ? TIOCM_DSR : 0);
523 545
524mget_out: 546mget_out:
525 kfree(d); 547 kfree(d);
@@ -546,7 +568,7 @@ static void ssu100_dtr_rts(struct usb_serial_port *port, int on)
546 if (!port->serial->disconnected) { 568 if (!port->serial->disconnected) {
547 /* Disable flow control */ 569 /* Disable flow control */
548 if (!on && 570 if (!on &&
549 ssu100_setregister(dev, 0, 0) < 0) 571 ssu100_setregister(dev, 0, UART_MCR, 0) < 0)
550 dev_err(&port->dev, "error from flowcontrol urb\n"); 572 dev_err(&port->dev, "error from flowcontrol urb\n");
551 /* drop RTS and DTR */ 573 /* drop RTS and DTR */
552 if (on) 574 if (on)
@@ -557,34 +579,88 @@ static void ssu100_dtr_rts(struct usb_serial_port *port, int on)
557 mutex_unlock(&port->serial->disc_mutex); 579 mutex_unlock(&port->serial->disc_mutex);
558} 580}
559 581
582static void ssu100_update_msr(struct usb_serial_port *port, u8 msr)
583{
584 struct ssu100_port_private *priv = usb_get_serial_port_data(port);
585 unsigned long flags;
586
587 spin_lock_irqsave(&priv->status_lock, flags);
588 priv->shadowMSR = msr;
589 spin_unlock_irqrestore(&priv->status_lock, flags);
590
591 if (msr & UART_MSR_ANY_DELTA) {
592 /* update input line counters */
593 if (msr & UART_MSR_DCTS)
594 priv->icount.cts++;
595 if (msr & UART_MSR_DDSR)
596 priv->icount.dsr++;
597 if (msr & UART_MSR_DDCD)
598 priv->icount.dcd++;
599 if (msr & UART_MSR_TERI)
600 priv->icount.rng++;
601 wake_up_interruptible(&priv->delta_msr_wait);
602 }
603}
604
605static void ssu100_update_lsr(struct usb_serial_port *port, u8 lsr,
606 char *tty_flag)
607{
608 struct ssu100_port_private *priv = usb_get_serial_port_data(port);
609 unsigned long flags;
610
611 spin_lock_irqsave(&priv->status_lock, flags);
612 priv->shadowLSR = lsr;
613 spin_unlock_irqrestore(&priv->status_lock, flags);
614
615 *tty_flag = TTY_NORMAL;
616 if (lsr & UART_LSR_BRK_ERROR_BITS) {
617 /* we always want to update icount, but we only want to
618 * update tty_flag for one case */
619 if (lsr & UART_LSR_BI) {
620 priv->icount.brk++;
621 *tty_flag = TTY_BREAK;
622 usb_serial_handle_break(port);
623 }
624 if (lsr & UART_LSR_PE) {
625 priv->icount.parity++;
626 if (*tty_flag == TTY_NORMAL)
627 *tty_flag = TTY_PARITY;
628 }
629 if (lsr & UART_LSR_FE) {
630 priv->icount.frame++;
631 if (*tty_flag == TTY_NORMAL)
632 *tty_flag = TTY_FRAME;
633 }
634 if (lsr & UART_LSR_OE){
635 priv->icount.overrun++;
636 if (*tty_flag == TTY_NORMAL)
637 *tty_flag = TTY_OVERRUN;
638 }
639 }
640
641}
642
560static int ssu100_process_packet(struct tty_struct *tty, 643static int ssu100_process_packet(struct tty_struct *tty,
561 struct usb_serial_port *port, 644 struct usb_serial_port *port,
562 struct ssu100_port_private *priv, 645 struct ssu100_port_private *priv,
563 char *packet, int len) 646 char *packet, int len)
564{ 647{
565 int i; 648 int i;
566 char flag; 649 char flag = TTY_NORMAL;
567 char *ch; 650 char *ch;
568 651
569 dbg("%s - port %d", __func__, port->number); 652 dbg("%s - port %d", __func__, port->number);
570 653
571 if (len < 4) { 654 if ((len >= 4) &&
572 dbg("%s - malformed packet", __func__); 655 (packet[0] == 0x1b) && (packet[1] == 0x1b) &&
573 return 0;
574 }
575
576 if ((packet[0] == 0x1b) && (packet[1] == 0x1b) &&
577 ((packet[2] == 0x00) || (packet[2] == 0x01))) { 656 ((packet[2] == 0x00) || (packet[2] == 0x01))) {
578 if (packet[2] == 0x00) 657 if (packet[2] == 0x00) {
579 priv->shadowLSR = packet[3] & (SERIAL_LSR_OE | 658 ssu100_update_lsr(port, packet[3], &flag);
580 SERIAL_LSR_PE | 659 if (flag == TTY_OVERRUN)
581 SERIAL_LSR_FE | 660 tty_insert_flip_char(tty, 0, TTY_OVERRUN);
582 SERIAL_LSR_BI);
583
584 if (packet[2] == 0x01) {
585 priv->shadowMSR = packet[3];
586 wake_up_interruptible(&priv->delta_msr_wait);
587 } 661 }
662 if (packet[2] == 0x01)
663 ssu100_update_msr(port, packet[3]);
588 664
589 len -= 4; 665 len -= 4;
590 ch = packet + 4; 666 ch = packet + 4;
@@ -631,7 +707,6 @@ static void ssu100_process_read_urb(struct urb *urb)
631 tty_kref_put(tty); 707 tty_kref_put(tty);
632} 708}
633 709
634
635static struct usb_serial_driver ssu100_device = { 710static struct usb_serial_driver ssu100_device = {
636 .driver = { 711 .driver = {
637 .owner = THIS_MODULE, 712 .owner = THIS_MODULE,
@@ -653,6 +728,7 @@ static struct usb_serial_driver ssu100_device = {
653 .tiocmset = ssu100_tiocmset, 728 .tiocmset = ssu100_tiocmset,
654 .ioctl = ssu100_ioctl, 729 .ioctl = ssu100_ioctl,
655 .set_termios = ssu100_set_termios, 730 .set_termios = ssu100_set_termios,
731 .disconnect = usb_serial_generic_disconnect,
656}; 732};
657 733
658static int __init ssu100_init(void) 734static int __init ssu100_init(void)
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
index 2a982e62963b..7a2177c79bde 100644
--- a/drivers/usb/serial/usb-serial.c
+++ b/drivers/usb/serial/usb-serial.c
@@ -736,6 +736,7 @@ int usb_serial_probe(struct usb_interface *interface,
736 736
737 serial = create_serial(dev, interface, type); 737 serial = create_serial(dev, interface, type);
738 if (!serial) { 738 if (!serial) {
739 module_put(type->driver.owner);
739 dev_err(&interface->dev, "%s - out of memory\n", __func__); 740 dev_err(&interface->dev, "%s - out of memory\n", __func__);
740 return -ENOMEM; 741 return -ENOMEM;
741 } 742 }
@@ -746,11 +747,11 @@ int usb_serial_probe(struct usb_interface *interface,
746 747
747 id = get_iface_id(type, interface); 748 id = get_iface_id(type, interface);
748 retval = type->probe(serial, id); 749 retval = type->probe(serial, id);
749 module_put(type->driver.owner);
750 750
751 if (retval) { 751 if (retval) {
752 dbg("sub driver rejected device"); 752 dbg("sub driver rejected device");
753 kfree(serial); 753 kfree(serial);
754 module_put(type->driver.owner);
754 return retval; 755 return retval;
755 } 756 }
756 } 757 }
@@ -822,6 +823,7 @@ int usb_serial_probe(struct usb_interface *interface,
822 if (num_bulk_in == 0 || num_bulk_out == 0) { 823 if (num_bulk_in == 0 || num_bulk_out == 0) {
823 dev_info(&interface->dev, "PL-2303 hack: descriptors matched but endpoints did not\n"); 824 dev_info(&interface->dev, "PL-2303 hack: descriptors matched but endpoints did not\n");
824 kfree(serial); 825 kfree(serial);
826 module_put(type->driver.owner);
825 return -ENODEV; 827 return -ENODEV;
826 } 828 }
827 } 829 }
@@ -835,22 +837,15 @@ int usb_serial_probe(struct usb_interface *interface,
835 dev_err(&interface->dev, 837 dev_err(&interface->dev,
836 "Generic device with no bulk out, not allowed.\n"); 838 "Generic device with no bulk out, not allowed.\n");
837 kfree(serial); 839 kfree(serial);
840 module_put(type->driver.owner);
838 return -EIO; 841 return -EIO;
839 } 842 }
840 } 843 }
841#endif 844#endif
842 if (!num_ports) { 845 if (!num_ports) {
843 /* if this device type has a calc_num_ports function, call it */ 846 /* if this device type has a calc_num_ports function, call it */
844 if (type->calc_num_ports) { 847 if (type->calc_num_ports)
845 if (!try_module_get(type->driver.owner)) {
846 dev_err(&interface->dev,
847 "module get failed, exiting\n");
848 kfree(serial);
849 return -EIO;
850 }
851 num_ports = type->calc_num_ports(serial); 848 num_ports = type->calc_num_ports(serial);
852 module_put(type->driver.owner);
853 }
854 if (!num_ports) 849 if (!num_ports)
855 num_ports = type->num_ports; 850 num_ports = type->num_ports;
856 } 851 }
@@ -1039,13 +1034,7 @@ int usb_serial_probe(struct usb_interface *interface,
1039 1034
1040 /* if this device type has an attach function, call it */ 1035 /* if this device type has an attach function, call it */
1041 if (type->attach) { 1036 if (type->attach) {
1042 if (!try_module_get(type->driver.owner)) {
1043 dev_err(&interface->dev,
1044 "module get failed, exiting\n");
1045 goto probe_error;
1046 }
1047 retval = type->attach(serial); 1037 retval = type->attach(serial);
1048 module_put(type->driver.owner);
1049 if (retval < 0) 1038 if (retval < 0)
1050 goto probe_error; 1039 goto probe_error;
1051 serial->attached = 1; 1040 serial->attached = 1;
@@ -1088,10 +1077,12 @@ int usb_serial_probe(struct usb_interface *interface,
1088exit: 1077exit:
1089 /* success */ 1078 /* success */
1090 usb_set_intfdata(interface, serial); 1079 usb_set_intfdata(interface, serial);
1080 module_put(type->driver.owner);
1091 return 0; 1081 return 0;
1092 1082
1093probe_error: 1083probe_error:
1094 usb_serial_put(serial); 1084 usb_serial_put(serial);
1085 module_put(type->driver.owner);
1095 return -EIO; 1086 return -EIO;
1096} 1087}
1097EXPORT_SYMBOL_GPL(usb_serial_probe); 1088EXPORT_SYMBOL_GPL(usb_serial_probe);
diff --git a/include/linux/kobject.h b/include/linux/kobject.h
index cf343a852534..7950a37a7146 100644
--- a/include/linux/kobject.h
+++ b/include/linux/kobject.h
@@ -22,6 +22,7 @@
22#include <linux/compiler.h> 22#include <linux/compiler.h>
23#include <linux/spinlock.h> 23#include <linux/spinlock.h>
24#include <linux/kref.h> 24#include <linux/kref.h>
25#include <linux/kobject_ns.h>
25#include <linux/kernel.h> 26#include <linux/kernel.h>
26#include <linux/wait.h> 27#include <linux/wait.h>
27#include <asm/atomic.h> 28#include <asm/atomic.h>
@@ -136,42 +137,8 @@ struct kobj_attribute {
136 137
137extern const struct sysfs_ops kobj_sysfs_ops; 138extern const struct sysfs_ops kobj_sysfs_ops;
138 139
139/*
140 * Namespace types which are used to tag kobjects and sysfs entries.
141 * Network namespace will likely be the first.
142 */
143enum kobj_ns_type {
144 KOBJ_NS_TYPE_NONE = 0,
145 KOBJ_NS_TYPE_NET,
146 KOBJ_NS_TYPES
147};
148
149struct sock; 140struct sock;
150 141
151/*
152 * Callbacks so sysfs can determine namespaces
153 * @current_ns: return calling task's namespace
154 * @netlink_ns: return namespace to which a sock belongs (right?)
155 * @initial_ns: return the initial namespace (i.e. init_net_ns)
156 */
157struct kobj_ns_type_operations {
158 enum kobj_ns_type type;
159 const void *(*current_ns)(void);
160 const void *(*netlink_ns)(struct sock *sk);
161 const void *(*initial_ns)(void);
162};
163
164int kobj_ns_type_register(const struct kobj_ns_type_operations *ops);
165int kobj_ns_type_registered(enum kobj_ns_type type);
166const struct kobj_ns_type_operations *kobj_child_ns_ops(struct kobject *parent);
167const struct kobj_ns_type_operations *kobj_ns_ops(struct kobject *kobj);
168
169const void *kobj_ns_current(enum kobj_ns_type type);
170const void *kobj_ns_netlink(enum kobj_ns_type type, struct sock *sk);
171const void *kobj_ns_initial(enum kobj_ns_type type);
172void kobj_ns_exit(enum kobj_ns_type type, const void *ns);
173
174
175/** 142/**
176 * struct kset - a set of kobjects of a specific type, belonging to a specific subsystem. 143 * struct kset - a set of kobjects of a specific type, belonging to a specific subsystem.
177 * 144 *
diff --git a/include/linux/kobject_ns.h b/include/linux/kobject_ns.h
new file mode 100644
index 000000000000..82cb5bf461fb
--- /dev/null
+++ b/include/linux/kobject_ns.h
@@ -0,0 +1,56 @@
1/* Kernel object name space definitions
2 *
3 * Copyright (c) 2002-2003 Patrick Mochel
4 * Copyright (c) 2002-2003 Open Source Development Labs
5 * Copyright (c) 2006-2008 Greg Kroah-Hartman <greg@kroah.com>
6 * Copyright (c) 2006-2008 Novell Inc.
7 *
8 * Split from kobject.h by David Howells (dhowells@redhat.com)
9 *
10 * This file is released under the GPLv2.
11 *
12 * Please read Documentation/kobject.txt before using the kobject
13 * interface, ESPECIALLY the parts about reference counts and object
14 * destructors.
15 */
16
17#ifndef _LINUX_KOBJECT_NS_H
18#define _LINUX_KOBJECT_NS_H
19
20struct sock;
21struct kobject;
22
23/*
24 * Namespace types which are used to tag kobjects and sysfs entries.
25 * Network namespace will likely be the first.
26 */
27enum kobj_ns_type {
28 KOBJ_NS_TYPE_NONE = 0,
29 KOBJ_NS_TYPE_NET,
30 KOBJ_NS_TYPES
31};
32
33/*
34 * Callbacks so sysfs can determine namespaces
35 * @current_ns: return calling task's namespace
36 * @netlink_ns: return namespace to which a sock belongs (right?)
37 * @initial_ns: return the initial namespace (i.e. init_net_ns)
38 */
39struct kobj_ns_type_operations {
40 enum kobj_ns_type type;
41 const void *(*current_ns)(void);
42 const void *(*netlink_ns)(struct sock *sk);
43 const void *(*initial_ns)(void);
44};
45
46int kobj_ns_type_register(const struct kobj_ns_type_operations *ops);
47int kobj_ns_type_registered(enum kobj_ns_type type);
48const struct kobj_ns_type_operations *kobj_child_ns_ops(struct kobject *parent);
49const struct kobj_ns_type_operations *kobj_ns_ops(struct kobject *kobj);
50
51const void *kobj_ns_current(enum kobj_ns_type type);
52const void *kobj_ns_netlink(enum kobj_ns_type type, struct sock *sk);
53const void *kobj_ns_initial(enum kobj_ns_type type);
54void kobj_ns_exit(enum kobj_ns_type type, const void *ns);
55
56#endif /* _LINUX_KOBJECT_NS_H */
diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h
index 3c92121ba9af..96eb576d82fd 100644
--- a/include/linux/sysfs.h
+++ b/include/linux/sysfs.h
@@ -16,6 +16,7 @@
16#include <linux/errno.h> 16#include <linux/errno.h>
17#include <linux/list.h> 17#include <linux/list.h>
18#include <linux/lockdep.h> 18#include <linux/lockdep.h>
19#include <linux/kobject_ns.h>
19#include <asm/atomic.h> 20#include <asm/atomic.h>
20 21
21struct kobject; 22struct kobject;
diff --git a/include/linux/usb/composite.h b/include/linux/usb/composite.h
index 890bc1472190..617068134ae8 100644
--- a/include/linux/usb/composite.h
+++ b/include/linux/usb/composite.h
@@ -247,6 +247,7 @@ int usb_add_config(struct usb_composite_dev *,
247 * value; it should return zero on successful initialization. 247 * value; it should return zero on successful initialization.
248 * @unbind: Reverses @bind(); called as a side effect of unregistering 248 * @unbind: Reverses @bind(); called as a side effect of unregistering
249 * this driver. 249 * this driver.
250 * @disconnect: optional driver disconnect method
250 * @suspend: Notifies when the host stops sending USB traffic, 251 * @suspend: Notifies when the host stops sending USB traffic,
251 * after function notifications 252 * after function notifications
252 * @resume: Notifies configuration when the host restarts USB traffic, 253 * @resume: Notifies configuration when the host restarts USB traffic,
diff --git a/lib/kobject_uevent.c b/lib/kobject_uevent.c
index b93579504dfa..70af0a7f97c0 100644
--- a/lib/kobject_uevent.c
+++ b/lib/kobject_uevent.c
@@ -123,7 +123,7 @@ static int kobj_usermode_filter(struct kobject *kobj)
123 * @kobj: struct kobject that the action is happening to 123 * @kobj: struct kobject that the action is happening to
124 * @envp_ext: pointer to environmental data 124 * @envp_ext: pointer to environmental data
125 * 125 *
126 * Returns 0 if kobject_uevent() is completed with success or the 126 * Returns 0 if kobject_uevent_env() is completed with success or the
127 * corresponding error when it fails. 127 * corresponding error when it fails.
128 */ 128 */
129int kobject_uevent_env(struct kobject *kobj, enum kobject_action action, 129int kobject_uevent_env(struct kobject *kobj, enum kobject_action action,
@@ -317,7 +317,7 @@ exit:
317EXPORT_SYMBOL_GPL(kobject_uevent_env); 317EXPORT_SYMBOL_GPL(kobject_uevent_env);
318 318
319/** 319/**
320 * kobject_uevent - notify userspace by ending an uevent 320 * kobject_uevent - notify userspace by sending an uevent
321 * 321 *
322 * @action: action that is happening 322 * @action: action that is happening
323 * @kobj: struct kobject that the action is happening to 323 * @kobj: struct kobject that the action is happening to