aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@suse.de>2006-01-06 15:59:59 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2006-01-06 15:59:59 -0500
commitccf18968b1bbc2fb117190a1984ac2a826dac228 (patch)
tree7bc8fbf5722aecf1e84fa50c31c657864cba1daa /arch
parente91c021c487110386a07facd0396e6c3b7cf9c1f (diff)
parentd99cf9d679a520d67f81d805b7cb91c68e1847f0 (diff)
Merge ../torvalds-2.6/
Diffstat (limited to 'arch')
-rw-r--r--arch/alpha/Kconfig13
-rw-r--r--arch/alpha/kernel/alpha_ksyms.c1
-rw-r--r--arch/alpha/kernel/irq.c630
-rw-r--r--arch/cris/arch-v10/kernel/kgdb.c6
-rw-r--r--arch/frv/kernel/Makefile1
-rw-r--r--arch/frv/kernel/entry.S2
-rw-r--r--arch/frv/kernel/futex.c242
-rw-r--r--arch/frv/kernel/signal.c155
-rw-r--r--arch/i386/Kconfig8
-rw-r--r--arch/i386/Kconfig.cpu14
-rw-r--r--arch/i386/Kconfig.debug10
-rw-r--r--arch/i386/kernel/apic.c2
-rw-r--r--arch/i386/kernel/apm.c97
-rw-r--r--arch/i386/kernel/cpu/amd.c7
-rw-r--r--arch/i386/kernel/cpu/common.c8
-rw-r--r--arch/i386/kernel/cpu/cyrix.c27
-rw-r--r--arch/i386/kernel/cpuid.c3
-rw-r--r--arch/i386/kernel/entry.S1
-rw-r--r--arch/i386/kernel/head.S27
-rw-r--r--arch/i386/kernel/i386_ksyms.c3
-rw-r--r--arch/i386/kernel/io_apic.c4
-rw-r--r--arch/i386/kernel/mpparse.c26
-rw-r--r--arch/i386/kernel/msr.c3
-rw-r--r--arch/i386/kernel/process.c16
-rw-r--r--arch/i386/kernel/ptrace.c9
-rw-r--r--arch/i386/kernel/reboot.c6
-rw-r--r--arch/i386/kernel/setup.c8
-rw-r--r--arch/i386/kernel/smpboot.c6
-rw-r--r--arch/i386/kernel/syscall_table.S1
-rw-r--r--arch/i386/kernel/timers/timer_tsc.c2
-rw-r--r--arch/i386/kernel/traps.c33
-rw-r--r--arch/i386/mm/init.c24
-rw-r--r--arch/i386/mm/pageattr.c27
-rw-r--r--arch/i386/pci/irq.c2
-rw-r--r--arch/m32r/Kconfig26
-rw-r--r--arch/m32r/boot/compressed/head.S5
-rw-r--r--arch/m32r/boot/setup.S24
-rw-r--r--arch/m32r/kernel/Makefile1
-rw-r--r--arch/m32r/kernel/entry.S19
-rw-r--r--arch/m32r/kernel/io_m32104ut.c298
-rw-r--r--arch/m32r/kernel/io_m32700ut.c24
-rw-r--r--arch/m32r/kernel/io_mappi.c2
-rw-r--r--arch/m32r/kernel/io_mappi2.c24
-rw-r--r--arch/m32r/kernel/io_mappi3.c51
-rw-r--r--arch/m32r/kernel/io_oaks32r.c2
-rw-r--r--arch/m32r/kernel/io_opsput.c6
-rw-r--r--arch/m32r/kernel/setup.c7
-rw-r--r--arch/m32r/kernel/setup_m32104ut.c156
-rw-r--r--arch/m32r/kernel/setup_m32700ut.c8
-rw-r--r--arch/m32r/kernel/setup_mappi.c6
-rw-r--r--arch/m32r/kernel/setup_mappi2.c6
-rw-r--r--arch/m32r/kernel/setup_mappi3.c6
-rw-r--r--arch/m32r/kernel/setup_oaks32r.c6
-rw-r--r--arch/m32r/kernel/setup_opsput.c8
-rw-r--r--arch/m32r/kernel/setup_usrv.c6
-rw-r--r--arch/m32r/kernel/time.c4
-rw-r--r--arch/m32r/m32104ut/defconfig.m32104ut657
-rw-r--r--arch/m32r/mm/cache.c36
-rw-r--r--arch/m68knommu/kernel/m68k_ksyms.c2
-rw-r--r--arch/m68knommu/kernel/setup.c2
-rw-r--r--arch/ppc/boot/simple/Makefile2
-rw-r--r--arch/ppc/kernel/idle.c4
-rw-r--r--arch/ppc/platforms/4xx/ibm440gx.c2
-rw-r--r--arch/ppc/platforms/4xx/ibm440sp.c1
-rw-r--r--arch/ppc/platforms/lite5200.c2
-rw-r--r--arch/ppc/platforms/mpc5200.c53
-rw-r--r--arch/ppc/syslib/mpc52xx_pci.c95
-rw-r--r--arch/ppc/syslib/mpc52xx_setup.c6
-rw-r--r--arch/s390/Kconfig34
-rw-r--r--arch/s390/Makefile6
-rw-r--r--arch/s390/appldata/appldata_base.c8
-rw-r--r--arch/s390/appldata/appldata_os.c14
-rw-r--r--arch/s390/crypto/Makefile8
-rw-r--r--arch/s390/crypto/aes_s390.c248
-rw-r--r--arch/s390/crypto/crypt_s390.h (renamed from arch/s390/crypto/crypt_z990.h)267
-rw-r--r--arch/s390/crypto/crypt_s390_query.c129
-rw-r--r--arch/s390/crypto/crypt_z990_query.c111
-rw-r--r--arch/s390/crypto/des_s390.c (renamed from arch/s390/crypto/des_z990.c)54
-rw-r--r--arch/s390/crypto/sha1_s390.c (renamed from arch/s390/crypto/sha1_z990.c)32
-rw-r--r--arch/s390/crypto/sha256_s390.c151
-rw-r--r--arch/s390/defconfig65
-rw-r--r--arch/s390/kernel/Makefile15
-rw-r--r--arch/s390/kernel/compat_linux.c2
-rw-r--r--arch/s390/kernel/compat_signal.c2
-rw-r--r--arch/s390/kernel/cpcmd.c16
-rw-r--r--arch/s390/kernel/entry64.S18
-rw-r--r--arch/s390/kernel/head.S4
-rw-r--r--arch/s390/kernel/machine_kexec.c2
-rw-r--r--arch/s390/kernel/module.c12
-rw-r--r--arch/s390/kernel/process.c12
-rw-r--r--arch/s390/kernel/ptrace.c24
-rw-r--r--arch/s390/kernel/reipl_diag.c2
-rw-r--r--arch/s390/kernel/setup.c14
-rw-r--r--arch/s390/kernel/signal.c8
-rw-r--r--arch/s390/kernel/smp.c14
-rw-r--r--arch/s390/kernel/sys_s390.c12
-rw-r--r--arch/s390/kernel/traps.c10
-rw-r--r--arch/s390/kernel/vmlinux.lds.S2
-rw-r--r--arch/s390/lib/Makefile5
-rw-r--r--arch/s390/lib/spinlock.c2
-rw-r--r--arch/s390/mm/extmem.c2
-rw-r--r--arch/s390/mm/fault.c18
-rw-r--r--arch/s390/mm/init.c8
-rw-r--r--arch/s390/mm/mmap.c2
-rw-r--r--arch/s390/oprofile/Makefile2
-rw-r--r--arch/s390/oprofile/backtrace.c79
-rw-r--r--arch/s390/oprofile/init.c4
-rw-r--r--arch/um/drivers/chan_kern.c273
-rw-r--r--arch/um/drivers/line.c298
-rw-r--r--arch/um/drivers/mconsole_kern.c232
-rw-r--r--arch/um/drivers/mconsole_user.c12
-rw-r--r--arch/um/drivers/net_kern.c8
-rw-r--r--arch/um/drivers/ssl.c47
-rw-r--r--arch/um/drivers/stdio_console.c33
-rw-r--r--arch/um/drivers/ubd_kern.c15
-rw-r--r--arch/um/include/chan_kern.h25
-rw-r--r--arch/um/include/choose-mode.h3
-rw-r--r--arch/um/include/irq_user.h13
-rw-r--r--arch/um/include/kern.h13
-rw-r--r--arch/um/include/line.h37
-rw-r--r--arch/um/include/mconsole.h8
-rw-r--r--arch/um/include/os.h17
-rw-r--r--arch/um/include/user_util.h1
-rw-r--r--arch/um/kernel/Makefile6
-rw-r--r--arch/um/kernel/irq_user.c48
-rw-r--r--arch/um/kernel/process_kern.c4
-rw-r--r--arch/um/kernel/sigio_user.c2
-rw-r--r--arch/um/kernel/um_arch.c4
-rw-r--r--arch/um/kernel/umid.c323
-rw-r--r--arch/um/os-Linux/Makefile4
-rw-r--r--arch/um/os-Linux/aio.c467
-rw-r--r--arch/um/os-Linux/umid.c335
-rw-r--r--arch/x86_64/Kconfig.debug10
-rw-r--r--arch/x86_64/ia32/ia32entry.S2
-rw-r--r--arch/x86_64/kernel/process.c5
-rw-r--r--arch/x86_64/kernel/syscall.c2
-rw-r--r--arch/x86_64/mm/init.c23
-rw-r--r--arch/x86_64/mm/pageattr.c9
138 files changed, 4139 insertions, 2539 deletions
diff --git a/arch/alpha/Kconfig b/arch/alpha/Kconfig
index 786491f9ceb2..153337ff1d7b 100644
--- a/arch/alpha/Kconfig
+++ b/arch/alpha/Kconfig
@@ -40,6 +40,19 @@ config GENERIC_IOMAP
40 bool 40 bool
41 default n 41 default n
42 42
43config GENERIC_HARDIRQS
44 bool
45 default y
46
47config GENERIC_IRQ_PROBE
48 bool
49 default y
50
51config AUTO_IRQ_AFFINITY
52 bool
53 depends on SMP
54 default y
55
43source "init/Kconfig" 56source "init/Kconfig"
44 57
45 58
diff --git a/arch/alpha/kernel/alpha_ksyms.c b/arch/alpha/kernel/alpha_ksyms.c
index 24ae9a366073..f3e98f837784 100644
--- a/arch/alpha/kernel/alpha_ksyms.c
+++ b/arch/alpha/kernel/alpha_ksyms.c
@@ -175,7 +175,6 @@ EXPORT_SYMBOL(up);
175 */ 175 */
176 176
177#ifdef CONFIG_SMP 177#ifdef CONFIG_SMP
178EXPORT_SYMBOL(synchronize_irq);
179EXPORT_SYMBOL(flush_tlb_mm); 178EXPORT_SYMBOL(flush_tlb_mm);
180EXPORT_SYMBOL(flush_tlb_range); 179EXPORT_SYMBOL(flush_tlb_range);
181EXPORT_SYMBOL(flush_tlb_page); 180EXPORT_SYMBOL(flush_tlb_page);
diff --git a/arch/alpha/kernel/irq.c b/arch/alpha/kernel/irq.c
index b6114f5c0d2b..76be5cf0de13 100644
--- a/arch/alpha/kernel/irq.c
+++ b/arch/alpha/kernel/irq.c
@@ -32,214 +32,25 @@
32#include <asm/io.h> 32#include <asm/io.h>
33#include <asm/uaccess.h> 33#include <asm/uaccess.h>
34 34
35/*
36 * Controller mappings for all interrupt sources:
37 */
38irq_desc_t irq_desc[NR_IRQS] __cacheline_aligned = {
39 [0 ... NR_IRQS-1] = {
40 .handler = &no_irq_type,
41 .lock = SPIN_LOCK_UNLOCKED
42 }
43};
44
45static void register_irq_proc(unsigned int irq);
46
47volatile unsigned long irq_err_count; 35volatile unsigned long irq_err_count;
48 36
49/* 37void ack_bad_irq(unsigned int irq)
50 * Special irq handlers.
51 */
52
53irqreturn_t no_action(int cpl, void *dev_id, struct pt_regs *regs)
54{
55 return IRQ_NONE;
56}
57
58/*
59 * Generic no controller code
60 */
61
62static void no_irq_enable_disable(unsigned int irq) { }
63static unsigned int no_irq_startup(unsigned int irq) { return 0; }
64
65static void
66no_irq_ack(unsigned int irq)
67{ 38{
68 irq_err_count++; 39 irq_err_count++;
69 printk(KERN_CRIT "Unexpected IRQ trap at vector %u\n", irq); 40 printk(KERN_CRIT "Unexpected IRQ trap at vector %u\n", irq);
70} 41}
71 42
72struct hw_interrupt_type no_irq_type = {
73 .typename = "none",
74 .startup = no_irq_startup,
75 .shutdown = no_irq_enable_disable,
76 .enable = no_irq_enable_disable,
77 .disable = no_irq_enable_disable,
78 .ack = no_irq_ack,
79 .end = no_irq_enable_disable,
80};
81
82int
83handle_IRQ_event(unsigned int irq, struct pt_regs *regs,
84 struct irqaction *action)
85{
86 int status = 1; /* Force the "do bottom halves" bit */
87 int ret;
88
89 do {
90 if (!(action->flags & SA_INTERRUPT))
91 local_irq_enable();
92 else
93 local_irq_disable();
94
95 ret = action->handler(irq, action->dev_id, regs);
96 if (ret == IRQ_HANDLED)
97 status |= action->flags;
98 action = action->next;
99 } while (action);
100 if (status & SA_SAMPLE_RANDOM)
101 add_interrupt_randomness(irq);
102 local_irq_disable();
103
104 return status;
105}
106
107/*
108 * Generic enable/disable code: this just calls
109 * down into the PIC-specific version for the actual
110 * hardware disable after having gotten the irq
111 * controller lock.
112 */
113void inline
114disable_irq_nosync(unsigned int irq)
115{
116 irq_desc_t *desc = irq_desc + irq;
117 unsigned long flags;
118
119 spin_lock_irqsave(&desc->lock, flags);
120 if (!desc->depth++) {
121 desc->status |= IRQ_DISABLED;
122 desc->handler->disable(irq);
123 }
124 spin_unlock_irqrestore(&desc->lock, flags);
125}
126
127/*
128 * Synchronous version of the above, making sure the IRQ is
129 * no longer running on any other IRQ..
130 */
131void
132disable_irq(unsigned int irq)
133{
134 disable_irq_nosync(irq);
135 synchronize_irq(irq);
136}
137
138void
139enable_irq(unsigned int irq)
140{
141 irq_desc_t *desc = irq_desc + irq;
142 unsigned long flags;
143
144 spin_lock_irqsave(&desc->lock, flags);
145 switch (desc->depth) {
146 case 1: {
147 unsigned int status = desc->status & ~IRQ_DISABLED;
148 desc->status = status;
149 if ((status & (IRQ_PENDING | IRQ_REPLAY)) == IRQ_PENDING) {
150 desc->status = status | IRQ_REPLAY;
151 hw_resend_irq(desc->handler,irq);
152 }
153 desc->handler->enable(irq);
154 /* fall-through */
155 }
156 default:
157 desc->depth--;
158 break;
159 case 0:
160 printk(KERN_ERR "enable_irq() unbalanced from %p\n",
161 __builtin_return_address(0));
162 }
163 spin_unlock_irqrestore(&desc->lock, flags);
164}
165
166int
167setup_irq(unsigned int irq, struct irqaction * new)
168{
169 int shared = 0;
170 struct irqaction *old, **p;
171 unsigned long flags;
172 irq_desc_t *desc = irq_desc + irq;
173
174 if (desc->handler == &no_irq_type)
175 return -ENOSYS;
176
177 /*
178 * Some drivers like serial.c use request_irq() heavily,
179 * so we have to be careful not to interfere with a
180 * running system.
181 */
182 if (new->flags & SA_SAMPLE_RANDOM) {
183 /*
184 * This function might sleep, we want to call it first,
185 * outside of the atomic block.
186 * Yes, this might clear the entropy pool if the wrong
187 * driver is attempted to be loaded, without actually
188 * installing a new handler, but is this really a problem,
189 * only the sysadmin is able to do this.
190 */
191 rand_initialize_irq(irq);
192 }
193
194 /*
195 * The following block of code has to be executed atomically
196 */
197 spin_lock_irqsave(&desc->lock,flags);
198 p = &desc->action;
199 if ((old = *p) != NULL) {
200 /* Can't share interrupts unless both agree to */
201 if (!(old->flags & new->flags & SA_SHIRQ)) {
202 spin_unlock_irqrestore(&desc->lock,flags);
203 return -EBUSY;
204 }
205
206 /* add new interrupt at end of irq queue */
207 do {
208 p = &old->next;
209 old = *p;
210 } while (old);
211 shared = 1;
212 }
213
214 *p = new;
215
216 if (!shared) {
217 desc->depth = 0;
218 desc->status &=
219 ~(IRQ_DISABLED|IRQ_AUTODETECT|IRQ_WAITING|IRQ_INPROGRESS);
220 desc->handler->startup(irq);
221 }
222 spin_unlock_irqrestore(&desc->lock,flags);
223
224 return 0;
225}
226
227static struct proc_dir_entry * root_irq_dir;
228static struct proc_dir_entry * irq_dir[NR_IRQS];
229
230#ifdef CONFIG_SMP 43#ifdef CONFIG_SMP
231static struct proc_dir_entry * smp_affinity_entry[NR_IRQS];
232static char irq_user_affinity[NR_IRQS]; 44static char irq_user_affinity[NR_IRQS];
233static cpumask_t irq_affinity[NR_IRQS] = { [0 ... NR_IRQS-1] = CPU_MASK_ALL };
234 45
235static void 46int
236select_smp_affinity(int irq) 47select_smp_affinity(unsigned int irq)
237{ 48{
238 static int last_cpu; 49 static int last_cpu;
239 int cpu = last_cpu + 1; 50 int cpu = last_cpu + 1;
240 51
241 if (! irq_desc[irq].handler->set_affinity || irq_user_affinity[irq]) 52 if (!irq_desc[irq].handler->set_affinity || irq_user_affinity[irq])
242 return; 53 return 1;
243 54
244 while (!cpu_possible(cpu)) 55 while (!cpu_possible(cpu))
245 cpu = (cpu < (NR_CPUS-1) ? cpu + 1 : 0); 56 cpu = (cpu < (NR_CPUS-1) ? cpu + 1 : 0);
@@ -247,208 +58,10 @@ select_smp_affinity(int irq)
247 58
248 irq_affinity[irq] = cpumask_of_cpu(cpu); 59 irq_affinity[irq] = cpumask_of_cpu(cpu);
249 irq_desc[irq].handler->set_affinity(irq, cpumask_of_cpu(cpu)); 60 irq_desc[irq].handler->set_affinity(irq, cpumask_of_cpu(cpu));
61 return 0;
250} 62}
251
252static int
253irq_affinity_read_proc (char *page, char **start, off_t off,
254 int count, int *eof, void *data)
255{
256 int len = cpumask_scnprintf(page, count, irq_affinity[(long)data]);
257 if (count - len < 2)
258 return -EINVAL;
259 len += sprintf(page + len, "\n");
260 return len;
261}
262
263static int
264irq_affinity_write_proc(struct file *file, const char __user *buffer,
265 unsigned long count, void *data)
266{
267 int irq = (long) data, full_count = count, err;
268 cpumask_t new_value;
269
270 if (!irq_desc[irq].handler->set_affinity)
271 return -EIO;
272
273 err = cpumask_parse(buffer, count, new_value);
274
275 /* The special value 0 means release control of the
276 affinity to kernel. */
277 cpus_and(new_value, new_value, cpu_online_map);
278 if (cpus_empty(new_value)) {
279 irq_user_affinity[irq] = 0;
280 select_smp_affinity(irq);
281 }
282 /* Do not allow disabling IRQs completely - it's a too easy
283 way to make the system unusable accidentally :-) At least
284 one online CPU still has to be targeted. */
285 else {
286 irq_affinity[irq] = new_value;
287 irq_user_affinity[irq] = 1;
288 irq_desc[irq].handler->set_affinity(irq, new_value);
289 }
290
291 return full_count;
292}
293
294#endif /* CONFIG_SMP */ 63#endif /* CONFIG_SMP */
295 64
296#define MAX_NAMELEN 10
297
298static void
299register_irq_proc (unsigned int irq)
300{
301 char name [MAX_NAMELEN];
302
303 if (!root_irq_dir || (irq_desc[irq].handler == &no_irq_type) ||
304 irq_dir[irq])
305 return;
306
307 memset(name, 0, MAX_NAMELEN);
308 sprintf(name, "%d", irq);
309
310 /* create /proc/irq/1234 */
311 irq_dir[irq] = proc_mkdir(name, root_irq_dir);
312
313#ifdef CONFIG_SMP
314 if (irq_desc[irq].handler->set_affinity) {
315 struct proc_dir_entry *entry;
316 /* create /proc/irq/1234/smp_affinity */
317 entry = create_proc_entry("smp_affinity", 0600, irq_dir[irq]);
318
319 if (entry) {
320 entry->nlink = 1;
321 entry->data = (void *)(long)irq;
322 entry->read_proc = irq_affinity_read_proc;
323 entry->write_proc = irq_affinity_write_proc;
324 }
325
326 smp_affinity_entry[irq] = entry;
327 }
328#endif
329}
330
331void
332init_irq_proc (void)
333{
334 int i;
335
336 /* create /proc/irq */
337 root_irq_dir = proc_mkdir("irq", NULL);
338
339#ifdef CONFIG_SMP
340 /* create /proc/irq/prof_cpu_mask */
341 create_prof_cpu_mask(root_irq_dir);
342#endif
343
344 /*
345 * Create entries for all existing IRQs.
346 */
347 for (i = 0; i < ACTUAL_NR_IRQS; i++) {
348 if (irq_desc[i].handler == &no_irq_type)
349 continue;
350 register_irq_proc(i);
351 }
352}
353
354int
355request_irq(unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_regs *),
356 unsigned long irqflags, const char * devname, void *dev_id)
357{
358 int retval;
359 struct irqaction * action;
360
361 if (irq >= ACTUAL_NR_IRQS)
362 return -EINVAL;
363 if (!handler)
364 return -EINVAL;
365
366#if 1
367 /*
368 * Sanity-check: shared interrupts should REALLY pass in
369 * a real dev-ID, otherwise we'll have trouble later trying
370 * to figure out which interrupt is which (messes up the
371 * interrupt freeing logic etc).
372 */
373 if ((irqflags & SA_SHIRQ) && !dev_id) {
374 printk(KERN_ERR
375 "Bad boy: %s (at %p) called us without a dev_id!\n",
376 devname, __builtin_return_address(0));
377 }
378#endif
379
380 action = (struct irqaction *)
381 kmalloc(sizeof(struct irqaction), GFP_KERNEL);
382 if (!action)
383 return -ENOMEM;
384
385 action->handler = handler;
386 action->flags = irqflags;
387 cpus_clear(action->mask);
388 action->name = devname;
389 action->next = NULL;
390 action->dev_id = dev_id;
391
392#ifdef CONFIG_SMP
393 select_smp_affinity(irq);
394#endif
395
396 retval = setup_irq(irq, action);
397 if (retval)
398 kfree(action);
399 return retval;
400}
401
402EXPORT_SYMBOL(request_irq);
403
404void
405free_irq(unsigned int irq, void *dev_id)
406{
407 irq_desc_t *desc;
408 struct irqaction **p;
409 unsigned long flags;
410
411 if (irq >= ACTUAL_NR_IRQS) {
412 printk(KERN_CRIT "Trying to free IRQ%d\n", irq);
413 return;
414 }
415
416 desc = irq_desc + irq;
417 spin_lock_irqsave(&desc->lock,flags);
418 p = &desc->action;
419 for (;;) {
420 struct irqaction * action = *p;
421 if (action) {
422 struct irqaction **pp = p;
423 p = &action->next;
424 if (action->dev_id != dev_id)
425 continue;
426
427 /* Found - now remove it from the list of entries. */
428 *pp = action->next;
429 if (!desc->action) {
430 desc->status |= IRQ_DISABLED;
431 desc->handler->shutdown(irq);
432 }
433 spin_unlock_irqrestore(&desc->lock,flags);
434
435#ifdef CONFIG_SMP
436 /* Wait to make sure it's not being used on
437 another CPU. */
438 while (desc->status & IRQ_INPROGRESS)
439 barrier();
440#endif
441 kfree(action);
442 return;
443 }
444 printk(KERN_ERR "Trying to free free IRQ%d\n",irq);
445 spin_unlock_irqrestore(&desc->lock,flags);
446 return;
447 }
448}
449
450EXPORT_SYMBOL(free_irq);
451
452int 65int
453show_interrupts(struct seq_file *p, void *v) 66show_interrupts(struct seq_file *p, void *v)
454{ 67{
@@ -531,10 +144,6 @@ handle_irq(int irq, struct pt_regs * regs)
531 * 0 return value means that this irq is already being 144 * 0 return value means that this irq is already being
532 * handled by some other CPU. (or is disabled) 145 * handled by some other CPU. (or is disabled)
533 */ 146 */
534 int cpu = smp_processor_id();
535 irq_desc_t *desc = irq_desc + irq;
536 struct irqaction * action;
537 unsigned int status;
538 static unsigned int illegal_count=0; 147 static unsigned int illegal_count=0;
539 148
540 if ((unsigned) irq > ACTUAL_NR_IRQS && illegal_count < MAX_ILLEGAL_IRQS ) { 149 if ((unsigned) irq > ACTUAL_NR_IRQS && illegal_count < MAX_ILLEGAL_IRQS ) {
@@ -546,229 +155,8 @@ handle_irq(int irq, struct pt_regs * regs)
546 } 155 }
547 156
548 irq_enter(); 157 irq_enter();
549 kstat_cpu(cpu).irqs[irq]++; 158 local_irq_disable();
550 spin_lock_irq(&desc->lock); /* mask also the higher prio events */ 159 __do_IRQ(irq, regs);
551 desc->handler->ack(irq); 160 local_irq_enable();
552 /*
553 * REPLAY is when Linux resends an IRQ that was dropped earlier.
554 * WAITING is used by probe to mark irqs that are being tested.
555 */
556 status = desc->status & ~(IRQ_REPLAY | IRQ_WAITING);
557 status |= IRQ_PENDING; /* we _want_ to handle it */
558
559 /*
560 * If the IRQ is disabled for whatever reason, we cannot
561 * use the action we have.
562 */
563 action = NULL;
564 if (!(status & (IRQ_DISABLED | IRQ_INPROGRESS))) {
565 action = desc->action;
566 status &= ~IRQ_PENDING; /* we commit to handling */
567 status |= IRQ_INPROGRESS; /* we are handling it */
568 }
569 desc->status = status;
570
571 /*
572 * If there is no IRQ handler or it was disabled, exit early.
573 * Since we set PENDING, if another processor is handling
574 * a different instance of this same irq, the other processor
575 * will take care of it.
576 */
577 if (!action)
578 goto out;
579
580 /*
581 * Edge triggered interrupts need to remember pending events.
582 * This applies to any hw interrupts that allow a second
583 * instance of the same irq to arrive while we are in handle_irq
584 * or in the handler. But the code here only handles the _second_
585 * instance of the irq, not the third or fourth. So it is mostly
586 * useful for irq hardware that does not mask cleanly in an
587 * SMP environment.
588 */
589 for (;;) {
590 spin_unlock(&desc->lock);
591 handle_IRQ_event(irq, regs, action);
592 spin_lock(&desc->lock);
593
594 if (!(desc->status & IRQ_PENDING)
595 || (desc->status & IRQ_LEVEL))
596 break;
597 desc->status &= ~IRQ_PENDING;
598 }
599 desc->status &= ~IRQ_INPROGRESS;
600out:
601 /*
602 * The ->end() handler has to deal with interrupts which got
603 * disabled while the handler was running.
604 */
605 desc->handler->end(irq);
606 spin_unlock(&desc->lock);
607
608 irq_exit(); 161 irq_exit();
609} 162}
610
611/*
612 * IRQ autodetection code..
613 *
614 * This depends on the fact that any interrupt that
615 * comes in on to an unassigned handler will get stuck
616 * with "IRQ_WAITING" cleared and the interrupt
617 * disabled.
618 */
619unsigned long
620probe_irq_on(void)
621{
622 int i;
623 irq_desc_t *desc;
624 unsigned long delay;
625 unsigned long val;
626
627 /* Something may have generated an irq long ago and we want to
628 flush such a longstanding irq before considering it as spurious. */
629 for (i = NR_IRQS-1; i >= 0; i--) {
630 desc = irq_desc + i;
631
632 spin_lock_irq(&desc->lock);
633 if (!irq_desc[i].action)
634 irq_desc[i].handler->startup(i);
635 spin_unlock_irq(&desc->lock);
636 }
637
638 /* Wait for longstanding interrupts to trigger. */
639 for (delay = jiffies + HZ/50; time_after(delay, jiffies); )
640 /* about 20ms delay */ barrier();
641
642 /* enable any unassigned irqs (we must startup again here because
643 if a longstanding irq happened in the previous stage, it may have
644 masked itself) first, enable any unassigned irqs. */
645 for (i = NR_IRQS-1; i >= 0; i--) {
646 desc = irq_desc + i;
647
648 spin_lock_irq(&desc->lock);
649 if (!desc->action) {
650 desc->status |= IRQ_AUTODETECT | IRQ_WAITING;
651 if (desc->handler->startup(i))
652 desc->status |= IRQ_PENDING;
653 }
654 spin_unlock_irq(&desc->lock);
655 }
656
657 /*
658 * Wait for spurious interrupts to trigger
659 */
660 for (delay = jiffies + HZ/10; time_after(delay, jiffies); )
661 /* about 100ms delay */ barrier();
662
663 /*
664 * Now filter out any obviously spurious interrupts
665 */
666 val = 0;
667 for (i=0; i<NR_IRQS; i++) {
668 irq_desc_t *desc = irq_desc + i;
669 unsigned int status;
670
671 spin_lock_irq(&desc->lock);
672 status = desc->status;
673
674 if (status & IRQ_AUTODETECT) {
675 /* It triggered already - consider it spurious. */
676 if (!(status & IRQ_WAITING)) {
677 desc->status = status & ~IRQ_AUTODETECT;
678 desc->handler->shutdown(i);
679 } else
680 if (i < 32)
681 val |= 1 << i;
682 }
683 spin_unlock_irq(&desc->lock);
684 }
685
686 return val;
687}
688
689EXPORT_SYMBOL(probe_irq_on);
690
691/*
692 * Return a mask of triggered interrupts (this
693 * can handle only legacy ISA interrupts).
694 */
695unsigned int
696probe_irq_mask(unsigned long val)
697{
698 int i;
699 unsigned int mask;
700
701 mask = 0;
702 for (i = 0; i < NR_IRQS; i++) {
703 irq_desc_t *desc = irq_desc + i;
704 unsigned int status;
705
706 spin_lock_irq(&desc->lock);
707 status = desc->status;
708
709 if (status & IRQ_AUTODETECT) {
710 /* We only react to ISA interrupts */
711 if (!(status & IRQ_WAITING)) {
712 if (i < 16)
713 mask |= 1 << i;
714 }
715
716 desc->status = status & ~IRQ_AUTODETECT;
717 desc->handler->shutdown(i);
718 }
719 spin_unlock_irq(&desc->lock);
720 }
721
722 return mask & val;
723}
724
725/*
726 * Get the result of the IRQ probe.. A negative result means that
727 * we have several candidates (but we return the lowest-numbered
728 * one).
729 */
730
731int
732probe_irq_off(unsigned long val)
733{
734 int i, irq_found, nr_irqs;
735
736 nr_irqs = 0;
737 irq_found = 0;
738 for (i=0; i<NR_IRQS; i++) {
739 irq_desc_t *desc = irq_desc + i;
740 unsigned int status;
741
742 spin_lock_irq(&desc->lock);
743 status = desc->status;
744
745 if (status & IRQ_AUTODETECT) {
746 if (!(status & IRQ_WAITING)) {
747 if (!nr_irqs)
748 irq_found = i;
749 nr_irqs++;
750 }
751 desc->status = status & ~IRQ_AUTODETECT;
752 desc->handler->shutdown(i);
753 }
754 spin_unlock_irq(&desc->lock);
755 }
756
757 if (nr_irqs > 1)
758 irq_found = -irq_found;
759 return irq_found;
760}
761
762EXPORT_SYMBOL(probe_irq_off);
763
764#ifdef CONFIG_SMP
765void synchronize_irq(unsigned int irq)
766{
767 /* is there anything to synchronize with? */
768 if (!irq_desc[irq].action)
769 return;
770
771 while (irq_desc[irq].status & IRQ_INPROGRESS)
772 barrier();
773}
774#endif
diff --git a/arch/cris/arch-v10/kernel/kgdb.c b/arch/cris/arch-v10/kernel/kgdb.c
index b72e6a91a639..34528da98817 100644
--- a/arch/cris/arch-v10/kernel/kgdb.c
+++ b/arch/cris/arch-v10/kernel/kgdb.c
@@ -569,12 +569,6 @@ gdb_cris_strtol (const char *s, char **endptr, int base)
569 return x; 569 return x;
570} 570}
571 571
572int
573double_this(int x)
574{
575 return 2 * x;
576}
577
578/********************************* Register image ****************************/ 572/********************************* Register image ****************************/
579/* Copy the content of a register image into another. The size n is 573/* Copy the content of a register image into another. The size n is
580 the size of the register image. Due to struct assignment generation of 574 the size of the register image. Due to struct assignment generation of
diff --git a/arch/frv/kernel/Makefile b/arch/frv/kernel/Makefile
index 981c2c7dec0d..422f30ede575 100644
--- a/arch/frv/kernel/Makefile
+++ b/arch/frv/kernel/Makefile
@@ -20,3 +20,4 @@ obj-$(CONFIG_FUJITSU_MB93493) += irq-mb93493.o
20obj-$(CONFIG_PM) += pm.o cmode.o 20obj-$(CONFIG_PM) += pm.o cmode.o
21obj-$(CONFIG_MB93093_PDK) += pm-mb93093.o 21obj-$(CONFIG_MB93093_PDK) += pm-mb93093.o
22obj-$(CONFIG_SYSCTL) += sysctl.o 22obj-$(CONFIG_SYSCTL) += sysctl.o
23obj-$(CONFIG_FUTEX) += futex.o
diff --git a/arch/frv/kernel/entry.S b/arch/frv/kernel/entry.S
index ad10ea595459..5f6548388b74 100644
--- a/arch/frv/kernel/entry.S
+++ b/arch/frv/kernel/entry.S
@@ -1076,7 +1076,7 @@ __entry_work_notifysig:
1076 LEDS 0x6410 1076 LEDS 0x6410
1077 ori.p gr4,#0,gr8 1077 ori.p gr4,#0,gr8
1078 call do_notify_resume 1078 call do_notify_resume
1079 bra __entry_return_direct 1079 bra __entry_resume_userspace
1080 1080
1081 # perform syscall entry tracing 1081 # perform syscall entry tracing
1082__syscall_trace_entry: 1082__syscall_trace_entry:
diff --git a/arch/frv/kernel/futex.c b/arch/frv/kernel/futex.c
new file mode 100644
index 000000000000..eae874a970c6
--- /dev/null
+++ b/arch/frv/kernel/futex.c
@@ -0,0 +1,242 @@
1/* futex.c: futex operations
2 *
3 * Copyright (C) 2005 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 */
11
12#include <linux/futex.h>
13#include <asm/futex.h>
14#include <asm/errno.h>
15#include <asm/uaccess.h>
16
17/*
18 * the various futex operations; MMU fault checking is ignored under no-MMU
19 * conditions
20 */
21static inline int atomic_futex_op_xchg_set(int oparg, int __user *uaddr, int *_oldval)
22{
23 int oldval, ret;
24
25 asm("0: \n"
26 " orcc gr0,gr0,gr0,icc3 \n" /* set ICC3.Z */
27 " ckeq icc3,cc7 \n"
28 "1: ld.p %M0,%1 \n" /* LD.P/ORCR must be atomic */
29 " orcr cc7,cc7,cc3 \n" /* set CC3 to true */
30 "2: cst.p %3,%M0 ,cc3,#1 \n"
31 " corcc gr29,gr29,gr0 ,cc3,#1 \n" /* clear ICC3.Z if store happens */
32 " beq icc3,#0,0b \n"
33 " setlos 0,%2 \n"
34 "3: \n"
35 ".subsection 2 \n"
36 "4: setlos %5,%2 \n"
37 " bra 3b \n"
38 ".previous \n"
39 ".section __ex_table,\"a\" \n"
40 " .balign 8 \n"
41 " .long 1b,4b \n"
42 " .long 2b,4b \n"
43 ".previous"
44 : "+U"(*uaddr), "=&r"(oldval), "=&r"(ret), "=r"(oparg)
45 : "3"(oparg), "i"(-EFAULT)
46 : "memory", "cc7", "cc3", "icc3"
47 );
48
49 *_oldval = oldval;
50 return ret;
51}
52
53static inline int atomic_futex_op_xchg_add(int oparg, int __user *uaddr, int *_oldval)
54{
55 int oldval, ret;
56
57 asm("0: \n"
58 " orcc gr0,gr0,gr0,icc3 \n" /* set ICC3.Z */
59 " ckeq icc3,cc7 \n"
60 "1: ld.p %M0,%1 \n" /* LD.P/ORCR must be atomic */
61 " orcr cc7,cc7,cc3 \n" /* set CC3 to true */
62 " add %1,%3,%3 \n"
63 "2: cst.p %3,%M0 ,cc3,#1 \n"
64 " corcc gr29,gr29,gr0 ,cc3,#1 \n" /* clear ICC3.Z if store happens */
65 " beq icc3,#0,0b \n"
66 " setlos 0,%2 \n"
67 "3: \n"
68 ".subsection 2 \n"
69 "4: setlos %5,%2 \n"
70 " bra 3b \n"
71 ".previous \n"
72 ".section __ex_table,\"a\" \n"
73 " .balign 8 \n"
74 " .long 1b,4b \n"
75 " .long 2b,4b \n"
76 ".previous"
77 : "+U"(*uaddr), "=&r"(oldval), "=&r"(ret), "=r"(oparg)
78 : "3"(oparg), "i"(-EFAULT)
79 : "memory", "cc7", "cc3", "icc3"
80 );
81
82 *_oldval = oldval;
83 return ret;
84}
85
86static inline int atomic_futex_op_xchg_or(int oparg, int __user *uaddr, int *_oldval)
87{
88 int oldval, ret;
89
90 asm("0: \n"
91 " orcc gr0,gr0,gr0,icc3 \n" /* set ICC3.Z */
92 " ckeq icc3,cc7 \n"
93 "1: ld.p %M0,%1 \n" /* LD.P/ORCR must be atomic */
94 " orcr cc7,cc7,cc3 \n" /* set CC3 to true */
95 " or %1,%3,%3 \n"
96 "2: cst.p %3,%M0 ,cc3,#1 \n"
97 " corcc gr29,gr29,gr0 ,cc3,#1 \n" /* clear ICC3.Z if store happens */
98 " beq icc3,#0,0b \n"
99 " setlos 0,%2 \n"
100 "3: \n"
101 ".subsection 2 \n"
102 "4: setlos %5,%2 \n"
103 " bra 3b \n"
104 ".previous \n"
105 ".section __ex_table,\"a\" \n"
106 " .balign 8 \n"
107 " .long 1b,4b \n"
108 " .long 2b,4b \n"
109 ".previous"
110 : "+U"(*uaddr), "=&r"(oldval), "=&r"(ret), "=r"(oparg)
111 : "3"(oparg), "i"(-EFAULT)
112 : "memory", "cc7", "cc3", "icc3"
113 );
114
115 *_oldval = oldval;
116 return ret;
117}
118
119static inline int atomic_futex_op_xchg_and(int oparg, int __user *uaddr, int *_oldval)
120{
121 int oldval, ret;
122
123 asm("0: \n"
124 " orcc gr0,gr0,gr0,icc3 \n" /* set ICC3.Z */
125 " ckeq icc3,cc7 \n"
126 "1: ld.p %M0,%1 \n" /* LD.P/ORCR must be atomic */
127 " orcr cc7,cc7,cc3 \n" /* set CC3 to true */
128 " and %1,%3,%3 \n"
129 "2: cst.p %3,%M0 ,cc3,#1 \n"
130 " corcc gr29,gr29,gr0 ,cc3,#1 \n" /* clear ICC3.Z if store happens */
131 " beq icc3,#0,0b \n"
132 " setlos 0,%2 \n"
133 "3: \n"
134 ".subsection 2 \n"
135 "4: setlos %5,%2 \n"
136 " bra 3b \n"
137 ".previous \n"
138 ".section __ex_table,\"a\" \n"
139 " .balign 8 \n"
140 " .long 1b,4b \n"
141 " .long 2b,4b \n"
142 ".previous"
143 : "+U"(*uaddr), "=&r"(oldval), "=&r"(ret), "=r"(oparg)
144 : "3"(oparg), "i"(-EFAULT)
145 : "memory", "cc7", "cc3", "icc3"
146 );
147
148 *_oldval = oldval;
149 return ret;
150}
151
152static inline int atomic_futex_op_xchg_xor(int oparg, int __user *uaddr, int *_oldval)
153{
154 int oldval, ret;
155
156 asm("0: \n"
157 " orcc gr0,gr0,gr0,icc3 \n" /* set ICC3.Z */
158 " ckeq icc3,cc7 \n"
159 "1: ld.p %M0,%1 \n" /* LD.P/ORCR must be atomic */
160 " orcr cc7,cc7,cc3 \n" /* set CC3 to true */
161 " xor %1,%3,%3 \n"
162 "2: cst.p %3,%M0 ,cc3,#1 \n"
163 " corcc gr29,gr29,gr0 ,cc3,#1 \n" /* clear ICC3.Z if store happens */
164 " beq icc3,#0,0b \n"
165 " setlos 0,%2 \n"
166 "3: \n"
167 ".subsection 2 \n"
168 "4: setlos %5,%2 \n"
169 " bra 3b \n"
170 ".previous \n"
171 ".section __ex_table,\"a\" \n"
172 " .balign 8 \n"
173 " .long 1b,4b \n"
174 " .long 2b,4b \n"
175 ".previous"
176 : "+U"(*uaddr), "=&r"(oldval), "=&r"(ret), "=r"(oparg)
177 : "3"(oparg), "i"(-EFAULT)
178 : "memory", "cc7", "cc3", "icc3"
179 );
180
181 *_oldval = oldval;
182 return ret;
183}
184
185/*****************************************************************************/
186/*
187 * do the futex operations
188 */
189int futex_atomic_op_inuser(int encoded_op, int __user *uaddr)
190{
191 int op = (encoded_op >> 28) & 7;
192 int cmp = (encoded_op >> 24) & 15;
193 int oparg = (encoded_op << 8) >> 20;
194 int cmparg = (encoded_op << 20) >> 20;
195 int oldval = 0, ret;
196
197 if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
198 oparg = 1 << oparg;
199
200 if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int)))
201 return -EFAULT;
202
203 inc_preempt_count();
204
205 switch (op) {
206 case FUTEX_OP_SET:
207 ret = atomic_futex_op_xchg_set(oparg, uaddr, &oldval);
208 break;
209 case FUTEX_OP_ADD:
210 ret = atomic_futex_op_xchg_add(oparg, uaddr, &oldval);
211 break;
212 case FUTEX_OP_OR:
213 ret = atomic_futex_op_xchg_or(oparg, uaddr, &oldval);
214 break;
215 case FUTEX_OP_ANDN:
216 ret = atomic_futex_op_xchg_and(~oparg, uaddr, &oldval);
217 break;
218 case FUTEX_OP_XOR:
219 ret = atomic_futex_op_xchg_xor(oparg, uaddr, &oldval);
220 break;
221 default:
222 ret = -ENOSYS;
223 break;
224 }
225
226 dec_preempt_count();
227
228 if (!ret) {
229 switch (cmp) {
230 case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break;
231 case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break;
232 case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break;
233 case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break;
234 case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break;
235 case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break;
236 default: ret = -ENOSYS; break;
237 }
238 }
239
240 return ret;
241
242} /* end futex_atomic_op_inuser() */
diff --git a/arch/frv/kernel/signal.c b/arch/frv/kernel/signal.c
index d4ccc0728dfe..5b7146f54fd5 100644
--- a/arch/frv/kernel/signal.c
+++ b/arch/frv/kernel/signal.c
@@ -35,7 +35,7 @@ struct fdpic_func_descriptor {
35 unsigned long GOT; 35 unsigned long GOT;
36}; 36};
37 37
38asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset); 38static int do_signal(sigset_t *oldset);
39 39
40/* 40/*
41 * Atomically swap in the new signal mask, and wait for a signal. 41 * Atomically swap in the new signal mask, and wait for a signal.
@@ -55,7 +55,7 @@ asmlinkage int sys_sigsuspend(int history0, int history1, old_sigset_t mask)
55 while (1) { 55 while (1) {
56 current->state = TASK_INTERRUPTIBLE; 56 current->state = TASK_INTERRUPTIBLE;
57 schedule(); 57 schedule();
58 if (do_signal(__frame, &saveset)) 58 if (do_signal(&saveset))
59 /* return the signal number as the return value of this function 59 /* return the signal number as the return value of this function
60 * - this is an utterly evil hack. syscalls should not invoke do_signal() 60 * - this is an utterly evil hack. syscalls should not invoke do_signal()
61 * as entry.S sets regs->gr8 to the return value of the system call 61 * as entry.S sets regs->gr8 to the return value of the system call
@@ -91,7 +91,7 @@ asmlinkage int sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize)
91 while (1) { 91 while (1) {
92 current->state = TASK_INTERRUPTIBLE; 92 current->state = TASK_INTERRUPTIBLE;
93 schedule(); 93 schedule();
94 if (do_signal(__frame, &saveset)) 94 if (do_signal(&saveset))
95 /* return the signal number as the return value of this function 95 /* return the signal number as the return value of this function
96 * - this is an utterly evil hack. syscalls should not invoke do_signal() 96 * - this is an utterly evil hack. syscalls should not invoke do_signal()
97 * as entry.S sets regs->gr8 to the return value of the system call 97 * as entry.S sets regs->gr8 to the return value of the system call
@@ -276,13 +276,12 @@ static int setup_sigcontext(struct sigcontext __user *sc, unsigned long mask)
276 * Determine which stack to use.. 276 * Determine which stack to use..
277 */ 277 */
278static inline void __user *get_sigframe(struct k_sigaction *ka, 278static inline void __user *get_sigframe(struct k_sigaction *ka,
279 struct pt_regs *regs,
280 size_t frame_size) 279 size_t frame_size)
281{ 280{
282 unsigned long sp; 281 unsigned long sp;
283 282
284 /* Default to using normal stack */ 283 /* Default to using normal stack */
285 sp = regs->sp; 284 sp = __frame->sp;
286 285
287 /* This is the X/Open sanctioned signal stack switching. */ 286 /* This is the X/Open sanctioned signal stack switching. */
288 if (ka->sa.sa_flags & SA_ONSTACK) { 287 if (ka->sa.sa_flags & SA_ONSTACK) {
@@ -291,18 +290,19 @@ static inline void __user *get_sigframe(struct k_sigaction *ka,
291 } 290 }
292 291
293 return (void __user *) ((sp - frame_size) & ~7UL); 292 return (void __user *) ((sp - frame_size) & ~7UL);
293
294} /* end get_sigframe() */ 294} /* end get_sigframe() */
295 295
296/*****************************************************************************/ 296/*****************************************************************************/
297/* 297/*
298 * 298 *
299 */ 299 */
300static void setup_frame(int sig, struct k_sigaction *ka, sigset_t *set, struct pt_regs * regs) 300static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set)
301{ 301{
302 struct sigframe __user *frame; 302 struct sigframe __user *frame;
303 int rsig; 303 int rsig;
304 304
305 frame = get_sigframe(ka, regs, sizeof(*frame)); 305 frame = get_sigframe(ka, sizeof(*frame));
306 306
307 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) 307 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
308 goto give_sigsegv; 308 goto give_sigsegv;
@@ -346,47 +346,51 @@ static void setup_frame(int sig, struct k_sigaction *ka, sigset_t *set, struct p
346 } 346 }
347 347
348 /* set up registers for signal handler */ 348 /* set up registers for signal handler */
349 regs->sp = (unsigned long) frame; 349 __frame->sp = (unsigned long) frame;
350 regs->lr = (unsigned long) &frame->retcode; 350 __frame->lr = (unsigned long) &frame->retcode;
351 regs->gr8 = sig; 351 __frame->gr8 = sig;
352 352
353 if (get_personality & FDPIC_FUNCPTRS) { 353 if (get_personality & FDPIC_FUNCPTRS) {
354 struct fdpic_func_descriptor __user *funcptr = 354 struct fdpic_func_descriptor __user *funcptr =
355 (struct fdpic_func_descriptor *) ka->sa.sa_handler; 355 (struct fdpic_func_descriptor *) ka->sa.sa_handler;
356 __get_user(regs->pc, &funcptr->text); 356 __get_user(__frame->pc, &funcptr->text);
357 __get_user(regs->gr15, &funcptr->GOT); 357 __get_user(__frame->gr15, &funcptr->GOT);
358 } else { 358 } else {
359 regs->pc = (unsigned long) ka->sa.sa_handler; 359 __frame->pc = (unsigned long) ka->sa.sa_handler;
360 regs->gr15 = 0; 360 __frame->gr15 = 0;
361 } 361 }
362 362
363 set_fs(USER_DS); 363 set_fs(USER_DS);
364 364
365 /* the tracer may want to single-step inside the handler */
366 if (test_thread_flag(TIF_SINGLESTEP))
367 ptrace_notify(SIGTRAP);
368
365#if DEBUG_SIG 369#if DEBUG_SIG
366 printk("SIG deliver %d (%s:%d): sp=%p pc=%lx ra=%p\n", 370 printk("SIG deliver %d (%s:%d): sp=%p pc=%lx ra=%p\n",
367 sig, current->comm, current->pid, frame, regs->pc, frame->pretcode); 371 sig, current->comm, current->pid, frame, __frame->pc,
372 frame->pretcode);
368#endif 373#endif
369 374
370 return; 375 return 1;
371 376
372give_sigsegv: 377give_sigsegv:
373 if (sig == SIGSEGV)
374 ka->sa.sa_handler = SIG_DFL;
375
376 force_sig(SIGSEGV, current); 378 force_sig(SIGSEGV, current);
379 return 0;
380
377} /* end setup_frame() */ 381} /* end setup_frame() */
378 382
379/*****************************************************************************/ 383/*****************************************************************************/
380/* 384/*
381 * 385 *
382 */ 386 */
383static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, 387static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
384 sigset_t *set, struct pt_regs * regs) 388 sigset_t *set)
385{ 389{
386 struct rt_sigframe __user *frame; 390 struct rt_sigframe __user *frame;
387 int rsig; 391 int rsig;
388 392
389 frame = get_sigframe(ka, regs, sizeof(*frame)); 393 frame = get_sigframe(ka, sizeof(*frame));
390 394
391 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) 395 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
392 goto give_sigsegv; 396 goto give_sigsegv;
@@ -409,7 +413,7 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
409 if (__put_user(0, &frame->uc.uc_flags) || 413 if (__put_user(0, &frame->uc.uc_flags) ||
410 __put_user(0, &frame->uc.uc_link) || 414 __put_user(0, &frame->uc.uc_link) ||
411 __put_user((void*)current->sas_ss_sp, &frame->uc.uc_stack.ss_sp) || 415 __put_user((void*)current->sas_ss_sp, &frame->uc.uc_stack.ss_sp) ||
412 __put_user(sas_ss_flags(regs->sp), &frame->uc.uc_stack.ss_flags) || 416 __put_user(sas_ss_flags(__frame->sp), &frame->uc.uc_stack.ss_flags) ||
413 __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size)) 417 __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size))
414 goto give_sigsegv; 418 goto give_sigsegv;
415 419
@@ -440,34 +444,38 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
440 } 444 }
441 445
442 /* Set up registers for signal handler */ 446 /* Set up registers for signal handler */
443 regs->sp = (unsigned long) frame; 447 __frame->sp = (unsigned long) frame;
444 regs->lr = (unsigned long) &frame->retcode; 448 __frame->lr = (unsigned long) &frame->retcode;
445 regs->gr8 = sig; 449 __frame->gr8 = sig;
446 regs->gr9 = (unsigned long) &frame->info; 450 __frame->gr9 = (unsigned long) &frame->info;
447 451
448 if (get_personality & FDPIC_FUNCPTRS) { 452 if (get_personality & FDPIC_FUNCPTRS) {
449 struct fdpic_func_descriptor *funcptr = 453 struct fdpic_func_descriptor *funcptr =
450 (struct fdpic_func_descriptor __user *) ka->sa.sa_handler; 454 (struct fdpic_func_descriptor __user *) ka->sa.sa_handler;
451 __get_user(regs->pc, &funcptr->text); 455 __get_user(__frame->pc, &funcptr->text);
452 __get_user(regs->gr15, &funcptr->GOT); 456 __get_user(__frame->gr15, &funcptr->GOT);
453 } else { 457 } else {
454 regs->pc = (unsigned long) ka->sa.sa_handler; 458 __frame->pc = (unsigned long) ka->sa.sa_handler;
455 regs->gr15 = 0; 459 __frame->gr15 = 0;
456 } 460 }
457 461
458 set_fs(USER_DS); 462 set_fs(USER_DS);
459 463
464 /* the tracer may want to single-step inside the handler */
465 if (test_thread_flag(TIF_SINGLESTEP))
466 ptrace_notify(SIGTRAP);
467
460#if DEBUG_SIG 468#if DEBUG_SIG
461 printk("SIG deliver %d (%s:%d): sp=%p pc=%lx ra=%p\n", 469 printk("SIG deliver %d (%s:%d): sp=%p pc=%lx ra=%p\n",
462 sig, current->comm, current->pid, frame, regs->pc, frame->pretcode); 470 sig, current->comm, current->pid, frame, __frame->pc,
471 frame->pretcode);
463#endif 472#endif
464 473
465 return; 474 return 1;
466 475
467give_sigsegv: 476give_sigsegv:
468 if (sig == SIGSEGV)
469 ka->sa.sa_handler = SIG_DFL;
470 force_sig(SIGSEGV, current); 477 force_sig(SIGSEGV, current);
478 return 0;
471 479
472} /* end setup_rt_frame() */ 480} /* end setup_rt_frame() */
473 481
@@ -475,43 +483,51 @@ give_sigsegv:
475/* 483/*
476 * OK, we're invoking a handler 484 * OK, we're invoking a handler
477 */ 485 */
478static void handle_signal(unsigned long sig, siginfo_t *info, 486static int handle_signal(unsigned long sig, siginfo_t *info,
479 struct k_sigaction *ka, sigset_t *oldset, 487 struct k_sigaction *ka, sigset_t *oldset)
480 struct pt_regs *regs)
481{ 488{
489 int ret;
490
482 /* Are we from a system call? */ 491 /* Are we from a system call? */
483 if (in_syscall(regs)) { 492 if (in_syscall(__frame)) {
484 /* If so, check system call restarting.. */ 493 /* If so, check system call restarting.. */
485 switch (regs->gr8) { 494 switch (__frame->gr8) {
486 case -ERESTART_RESTARTBLOCK: 495 case -ERESTART_RESTARTBLOCK:
487 case -ERESTARTNOHAND: 496 case -ERESTARTNOHAND:
488 regs->gr8 = -EINTR; 497 __frame->gr8 = -EINTR;
489 break; 498 break;
490 499
491 case -ERESTARTSYS: 500 case -ERESTARTSYS:
492 if (!(ka->sa.sa_flags & SA_RESTART)) { 501 if (!(ka->sa.sa_flags & SA_RESTART)) {
493 regs->gr8 = -EINTR; 502 __frame->gr8 = -EINTR;
494 break; 503 break;
495 } 504 }
505
496 /* fallthrough */ 506 /* fallthrough */
497 case -ERESTARTNOINTR: 507 case -ERESTARTNOINTR:
498 regs->gr8 = regs->orig_gr8; 508 __frame->gr8 = __frame->orig_gr8;
499 regs->pc -= 4; 509 __frame->pc -= 4;
500 } 510 }
501 } 511 }
502 512
503 /* Set up the stack frame */ 513 /* Set up the stack frame */
504 if (ka->sa.sa_flags & SA_SIGINFO) 514 if (ka->sa.sa_flags & SA_SIGINFO)
505 setup_rt_frame(sig, ka, info, oldset, regs); 515 ret = setup_rt_frame(sig, ka, info, oldset);
506 else 516 else
507 setup_frame(sig, ka, oldset, regs); 517 ret = setup_frame(sig, ka, oldset);
518
519 if (ret) {
520 spin_lock_irq(&current->sighand->siglock);
521 sigorsets(&current->blocked, &current->blocked,
522 &ka->sa.sa_mask);
523 if (!(ka->sa.sa_flags & SA_NODEFER))
524 sigaddset(&current->blocked, sig);
525 recalc_sigpending();
526 spin_unlock_irq(&current->sighand->siglock);
527 }
528
529 return ret;
508 530
509 spin_lock_irq(&current->sighand->siglock);
510 sigorsets(&current->blocked, &current->blocked, &ka->sa.sa_mask);
511 if (!(ka->sa.sa_flags & SA_NODEFER))
512 sigaddset(&current->blocked, sig);
513 recalc_sigpending();
514 spin_unlock_irq(&current->sighand->siglock);
515} /* end handle_signal() */ 531} /* end handle_signal() */
516 532
517/*****************************************************************************/ 533/*****************************************************************************/
@@ -520,7 +536,7 @@ static void handle_signal(unsigned long sig, siginfo_t *info,
520 * want to handle. Thus you cannot kill init even with a SIGKILL even by 536 * want to handle. Thus you cannot kill init even with a SIGKILL even by
521 * mistake. 537 * mistake.
522 */ 538 */
523int do_signal(struct pt_regs *regs, sigset_t *oldset) 539static int do_signal(sigset_t *oldset)
524{ 540{
525 struct k_sigaction ka; 541 struct k_sigaction ka;
526 siginfo_t info; 542 siginfo_t info;
@@ -532,7 +548,7 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset)
532 * kernel mode. Just return without doing anything 548 * kernel mode. Just return without doing anything
533 * if so. 549 * if so.
534 */ 550 */
535 if (!user_mode(regs)) 551 if (!user_mode(__frame))
536 return 1; 552 return 1;
537 553
538 if (try_to_freeze()) 554 if (try_to_freeze())
@@ -541,30 +557,29 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset)
541 if (!oldset) 557 if (!oldset)
542 oldset = &current->blocked; 558 oldset = &current->blocked;
543 559
544 signr = get_signal_to_deliver(&info, &ka, regs, NULL); 560 signr = get_signal_to_deliver(&info, &ka, __frame, NULL);
545 if (signr > 0) { 561 if (signr > 0)
546 handle_signal(signr, &info, &ka, oldset, regs); 562 return handle_signal(signr, &info, &ka, oldset);
547 return 1;
548 }
549 563
550 no_signal: 564no_signal:
551 /* Did we come from a system call? */ 565 /* Did we come from a system call? */
552 if (regs->syscallno >= 0) { 566 if (__frame->syscallno >= 0) {
553 /* Restart the system call - no handlers present */ 567 /* Restart the system call - no handlers present */
554 if (regs->gr8 == -ERESTARTNOHAND || 568 if (__frame->gr8 == -ERESTARTNOHAND ||
555 regs->gr8 == -ERESTARTSYS || 569 __frame->gr8 == -ERESTARTSYS ||
556 regs->gr8 == -ERESTARTNOINTR) { 570 __frame->gr8 == -ERESTARTNOINTR) {
557 regs->gr8 = regs->orig_gr8; 571 __frame->gr8 = __frame->orig_gr8;
558 regs->pc -= 4; 572 __frame->pc -= 4;
559 } 573 }
560 574
561 if (regs->gr8 == -ERESTART_RESTARTBLOCK){ 575 if (__frame->gr8 == -ERESTART_RESTARTBLOCK){
562 regs->gr8 = __NR_restart_syscall; 576 __frame->gr8 = __NR_restart_syscall;
563 regs->pc -= 4; 577 __frame->pc -= 4;
564 } 578 }
565 } 579 }
566 580
567 return 0; 581 return 0;
582
568} /* end do_signal() */ 583} /* end do_signal() */
569 584
570/*****************************************************************************/ 585/*****************************************************************************/
@@ -580,6 +595,6 @@ asmlinkage void do_notify_resume(__u32 thread_info_flags)
580 595
581 /* deal with pending signal delivery */ 596 /* deal with pending signal delivery */
582 if (thread_info_flags & _TIF_SIGPENDING) 597 if (thread_info_flags & _TIF_SIGPENDING)
583 do_signal(__frame, NULL); 598 do_signal(NULL);
584 599
585} /* end do_notify_resume() */ 600} /* end do_notify_resume() */
diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig
index 6004bb0795e0..968fabd8723f 100644
--- a/arch/i386/Kconfig
+++ b/arch/i386/Kconfig
@@ -464,7 +464,6 @@ config NUMA
464 depends on SMP && HIGHMEM64G && (X86_NUMAQ || X86_GENERICARCH || (X86_SUMMIT && ACPI)) 464 depends on SMP && HIGHMEM64G && (X86_NUMAQ || X86_GENERICARCH || (X86_SUMMIT && ACPI))
465 default n if X86_PC 465 default n if X86_PC
466 default y if (X86_NUMAQ || X86_SUMMIT) 466 default y if (X86_NUMAQ || X86_SUMMIT)
467 select SPARSEMEM_STATIC
468 467
469# Need comments to help the hapless user trying to turn on NUMA support 468# Need comments to help the hapless user trying to turn on NUMA support
470comment "NUMA (NUMA-Q) requires SMP, 64GB highmem support" 469comment "NUMA (NUMA-Q) requires SMP, 64GB highmem support"
@@ -493,6 +492,10 @@ config HAVE_ARCH_ALLOC_REMAP
493 depends on NUMA 492 depends on NUMA
494 default y 493 default y
495 494
495config ARCH_FLATMEM_ENABLE
496 def_bool y
497 depends on (ARCH_SELECT_MEMORY_MODEL && X86_PC)
498
496config ARCH_DISCONTIGMEM_ENABLE 499config ARCH_DISCONTIGMEM_ENABLE
497 def_bool y 500 def_bool y
498 depends on NUMA 501 depends on NUMA
@@ -503,7 +506,8 @@ config ARCH_DISCONTIGMEM_DEFAULT
503 506
504config ARCH_SPARSEMEM_ENABLE 507config ARCH_SPARSEMEM_ENABLE
505 def_bool y 508 def_bool y
506 depends on NUMA 509 depends on (NUMA || (X86_PC && EXPERIMENTAL))
510 select SPARSEMEM_STATIC
507 511
508config ARCH_SELECT_MEMORY_MODEL 512config ARCH_SELECT_MEMORY_MODEL
509 def_bool y 513 def_bool y
diff --git a/arch/i386/Kconfig.cpu b/arch/i386/Kconfig.cpu
index 53bbb3c008ee..79603b3471f9 100644
--- a/arch/i386/Kconfig.cpu
+++ b/arch/i386/Kconfig.cpu
@@ -39,6 +39,7 @@ config M386
39 - "Winchip-2" for IDT Winchip 2. 39 - "Winchip-2" for IDT Winchip 2.
40 - "Winchip-2A" for IDT Winchips with 3dNow! capabilities. 40 - "Winchip-2A" for IDT Winchips with 3dNow! capabilities.
41 - "GeodeGX1" for Geode GX1 (Cyrix MediaGX). 41 - "GeodeGX1" for Geode GX1 (Cyrix MediaGX).
42 - "Geode GX/LX" For AMD Geode GX and LX processors.
42 - "CyrixIII/VIA C3" for VIA Cyrix III or VIA C3. 43 - "CyrixIII/VIA C3" for VIA Cyrix III or VIA C3.
43 - "VIA C3-2 for VIA C3-2 "Nehemiah" (model 9 and above). 44 - "VIA C3-2 for VIA C3-2 "Nehemiah" (model 9 and above).
44 45
@@ -171,6 +172,11 @@ config MGEODEGX1
171 help 172 help
172 Select this for a Geode GX1 (Cyrix MediaGX) chip. 173 Select this for a Geode GX1 (Cyrix MediaGX) chip.
173 174
175config MGEODE_LX
176 bool "Geode GX/LX"
177 help
178 Select this for AMD Geode GX and LX processors.
179
174config MCYRIXIII 180config MCYRIXIII
175 bool "CyrixIII/VIA-C3" 181 bool "CyrixIII/VIA-C3"
176 help 182 help
@@ -220,8 +226,8 @@ config X86_XADD
220config X86_L1_CACHE_SHIFT 226config X86_L1_CACHE_SHIFT
221 int 227 int
222 default "7" if MPENTIUM4 || X86_GENERIC 228 default "7" if MPENTIUM4 || X86_GENERIC
223 default "4" if X86_ELAN || M486 || M386 229 default "4" if X86_ELAN || M486 || M386 || MGEODEGX1
224 default "5" if MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCRUSOE || MEFFICEON || MCYRIXIII || MK6 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || MVIAC3_2 || MGEODEGX1 230 default "5" if MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCRUSOE || MEFFICEON || MCYRIXIII || MK6 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || MVIAC3_2 || MGEODE_LX
225 default "6" if MK7 || MK8 || MPENTIUMM 231 default "6" if MK7 || MK8 || MPENTIUMM
226 232
227config RWSEM_GENERIC_SPINLOCK 233config RWSEM_GENERIC_SPINLOCK
@@ -290,12 +296,12 @@ config X86_INTEL_USERCOPY
290 296
291config X86_USE_PPRO_CHECKSUM 297config X86_USE_PPRO_CHECKSUM
292 bool 298 bool
293 depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MK8 || MVIAC3_2 || MEFFICEON 299 depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MK8 || MVIAC3_2 || MEFFICEON || MGEODE_LX
294 default y 300 default y
295 301
296config X86_USE_3DNOW 302config X86_USE_3DNOW
297 bool 303 bool
298 depends on MCYRIXIII || MK7 304 depends on MCYRIXIII || MK7 || MGEODE_LX
299 default y 305 default y
300 306
301config X86_OOSTORE 307config X86_OOSTORE
diff --git a/arch/i386/Kconfig.debug b/arch/i386/Kconfig.debug
index c48b424dd640..bf32ecc9ad04 100644
--- a/arch/i386/Kconfig.debug
+++ b/arch/i386/Kconfig.debug
@@ -42,6 +42,16 @@ config DEBUG_PAGEALLOC
42 This results in a large slowdown, but helps to find certain types 42 This results in a large slowdown, but helps to find certain types
43 of memory corruptions. 43 of memory corruptions.
44 44
45config DEBUG_RODATA
46 bool "Write protect kernel read-only data structures"
47 depends on DEBUG_KERNEL
48 help
49 Mark the kernel read-only data as write-protected in the pagetables,
50 in order to catch accidental (and incorrect) writes to such const
51 data. This option may have a slight performance impact because a
52 portion of the kernel code won't be covered by a 2MB TLB anymore.
53 If in doubt, say "N".
54
45config 4KSTACKS 55config 4KSTACKS
46 bool "Use 4Kb for kernel stacks instead of 8Kb" 56 bool "Use 4Kb for kernel stacks instead of 8Kb"
47 depends on DEBUG_KERNEL 57 depends on DEBUG_KERNEL
diff --git a/arch/i386/kernel/apic.c b/arch/i386/kernel/apic.c
index 496a2c9909fe..d8f94e78de8a 100644
--- a/arch/i386/kernel/apic.c
+++ b/arch/i386/kernel/apic.c
@@ -721,7 +721,7 @@ static int __init apic_set_verbosity(char *str)
721 apic_verbosity = APIC_VERBOSE; 721 apic_verbosity = APIC_VERBOSE;
722 else 722 else
723 printk(KERN_WARNING "APIC Verbosity level %s not recognised" 723 printk(KERN_WARNING "APIC Verbosity level %s not recognised"
724 " use apic=verbose or apic=debug", str); 724 " use apic=verbose or apic=debug\n", str);
725 725
726 return 0; 726 return 0;
727} 727}
diff --git a/arch/i386/kernel/apm.c b/arch/i386/kernel/apm.c
index 1e60acbed3c1..2d793d4aef1a 100644
--- a/arch/i386/kernel/apm.c
+++ b/arch/i386/kernel/apm.c
@@ -303,17 +303,6 @@ extern int (*console_blank_hook)(int);
303#include "apm.h" 303#include "apm.h"
304 304
305/* 305/*
306 * Define to make all _set_limit calls use 64k limits. The APM 1.1 BIOS is
307 * supposed to provide limit information that it recognizes. Many machines
308 * do this correctly, but many others do not restrict themselves to their
309 * claimed limit. When this happens, they will cause a segmentation
310 * violation in the kernel at boot time. Most BIOS's, however, will
311 * respect a 64k limit, so we use that. If you want to be pedantic and
312 * hold your BIOS to its claims, then undefine this.
313 */
314#define APM_RELAX_SEGMENTS
315
316/*
317 * Define to re-initialize the interrupt 0 timer to 100 Hz after a suspend. 306 * Define to re-initialize the interrupt 0 timer to 100 Hz after a suspend.
318 * This patched by Chad Miller <cmiller@surfsouth.com>, original code by 307 * This patched by Chad Miller <cmiller@surfsouth.com>, original code by
319 * David Chen <chen@ctpa04.mit.edu> 308 * David Chen <chen@ctpa04.mit.edu>
@@ -1075,22 +1064,23 @@ static int apm_engage_power_management(u_short device, int enable)
1075 1064
1076static int apm_console_blank(int blank) 1065static int apm_console_blank(int blank)
1077{ 1066{
1078 int error; 1067 int error, i;
1079 u_short state; 1068 u_short state;
1069 static const u_short dev[3] = { 0x100, 0x1FF, 0x101 };
1080 1070
1081 state = blank ? APM_STATE_STANDBY : APM_STATE_READY; 1071 state = blank ? APM_STATE_STANDBY : APM_STATE_READY;
1082 /* Blank the first display device */ 1072
1083 error = set_power_state(0x100, state); 1073 for (i = 0; i < ARRAY_SIZE(dev); i++) {
1084 if ((error != APM_SUCCESS) && (error != APM_NO_ERROR)) { 1074 error = set_power_state(dev[i], state);
1085 /* try to blank them all instead */ 1075
1086 error = set_power_state(0x1ff, state); 1076 if ((error == APM_SUCCESS) || (error == APM_NO_ERROR))
1087 if ((error != APM_SUCCESS) && (error != APM_NO_ERROR)) 1077 return 1;
1088 /* try to blank device one instead */ 1078
1089 error = set_power_state(0x101, state); 1079 if (error == APM_NOT_ENGAGED)
1080 break;
1090 } 1081 }
1091 if ((error == APM_SUCCESS) || (error == APM_NO_ERROR)) 1082
1092 return 1; 1083 if (error == APM_NOT_ENGAGED && state != APM_STATE_READY) {
1093 if (error == APM_NOT_ENGAGED) {
1094 static int tried; 1084 static int tried;
1095 int eng_error; 1085 int eng_error;
1096 if (tried++ == 0) { 1086 if (tried++ == 0) {
@@ -2233,8 +2223,8 @@ static struct dmi_system_id __initdata apm_dmi_table[] = {
2233static int __init apm_init(void) 2223static int __init apm_init(void)
2234{ 2224{
2235 struct proc_dir_entry *apm_proc; 2225 struct proc_dir_entry *apm_proc;
2226 struct desc_struct *gdt;
2236 int ret; 2227 int ret;
2237 int i;
2238 2228
2239 dmi_check_system(apm_dmi_table); 2229 dmi_check_system(apm_dmi_table);
2240 2230
@@ -2312,45 +2302,30 @@ static int __init apm_init(void)
2312 set_base(bad_bios_desc, __va((unsigned long)0x40 << 4)); 2302 set_base(bad_bios_desc, __va((unsigned long)0x40 << 4));
2313 _set_limit((char *)&bad_bios_desc, 4095 - (0x40 << 4)); 2303 _set_limit((char *)&bad_bios_desc, 4095 - (0x40 << 4));
2314 2304
2305 /*
2306 * Set up the long jump entry point to the APM BIOS, which is called
2307 * from inline assembly.
2308 */
2315 apm_bios_entry.offset = apm_info.bios.offset; 2309 apm_bios_entry.offset = apm_info.bios.offset;
2316 apm_bios_entry.segment = APM_CS; 2310 apm_bios_entry.segment = APM_CS;
2317 2311
2318 for (i = 0; i < NR_CPUS; i++) { 2312 /*
2319 struct desc_struct *gdt = get_cpu_gdt_table(i); 2313 * The APM 1.1 BIOS is supposed to provide limit information that it
2320 set_base(gdt[APM_CS >> 3], 2314 * recognizes. Many machines do this correctly, but many others do
2321 __va((unsigned long)apm_info.bios.cseg << 4)); 2315 * not restrict themselves to their claimed limit. When this happens,
2322 set_base(gdt[APM_CS_16 >> 3], 2316 * they will cause a segmentation violation in the kernel at boot time.
2323 __va((unsigned long)apm_info.bios.cseg_16 << 4)); 2317 * Most BIOS's, however, will respect a 64k limit, so we use that.
2324 set_base(gdt[APM_DS >> 3], 2318 *
2325 __va((unsigned long)apm_info.bios.dseg << 4)); 2319 * Note we only set APM segments on CPU zero, since we pin the APM
2326#ifndef APM_RELAX_SEGMENTS 2320 * code to that CPU.
2327 if (apm_info.bios.version == 0x100) { 2321 */
2328#endif 2322 gdt = get_cpu_gdt_table(0);
2329 /* For ASUS motherboard, Award BIOS rev 110 (and others?) */ 2323 set_base(gdt[APM_CS >> 3],
2330 _set_limit((char *)&gdt[APM_CS >> 3], 64 * 1024 - 1); 2324 __va((unsigned long)apm_info.bios.cseg << 4));
2331 /* For some unknown machine. */ 2325 set_base(gdt[APM_CS_16 >> 3],
2332 _set_limit((char *)&gdt[APM_CS_16 >> 3], 64 * 1024 - 1); 2326 __va((unsigned long)apm_info.bios.cseg_16 << 4));
2333 /* For the DEC Hinote Ultra CT475 (and others?) */ 2327 set_base(gdt[APM_DS >> 3],
2334 _set_limit((char *)&gdt[APM_DS >> 3], 64 * 1024 - 1); 2328 __va((unsigned long)apm_info.bios.dseg << 4));
2335#ifndef APM_RELAX_SEGMENTS
2336 } else {
2337 _set_limit((char *)&gdt[APM_CS >> 3],
2338 (apm_info.bios.cseg_len - 1) & 0xffff);
2339 _set_limit((char *)&gdt[APM_CS_16 >> 3],
2340 (apm_info.bios.cseg_16_len - 1) & 0xffff);
2341 _set_limit((char *)&gdt[APM_DS >> 3],
2342 (apm_info.bios.dseg_len - 1) & 0xffff);
2343 /* workaround for broken BIOSes */
2344 if (apm_info.bios.cseg_len <= apm_info.bios.offset)
2345 _set_limit((char *)&gdt[APM_CS >> 3], 64 * 1024 -1);
2346 if (apm_info.bios.dseg_len <= 0x40) { /* 0x40 * 4kB == 64kB */
2347 /* for the BIOS that assumes granularity = 1 */
2348 gdt[APM_DS >> 3].b |= 0x800000;
2349 printk(KERN_NOTICE "apm: we set the granularity of dseg.\n");
2350 }
2351 }
2352#endif
2353 }
2354 2329
2355 apm_proc = create_proc_info_entry("apm", 0, NULL, apm_get_info); 2330 apm_proc = create_proc_info_entry("apm", 0, NULL, apm_get_info);
2356 if (apm_proc) 2331 if (apm_proc)
diff --git a/arch/i386/kernel/cpu/amd.c b/arch/i386/kernel/cpu/amd.c
index e344ef88cfcd..e7697e077f6b 100644
--- a/arch/i386/kernel/cpu/amd.c
+++ b/arch/i386/kernel/cpu/amd.c
@@ -161,8 +161,13 @@ static void __init init_amd(struct cpuinfo_x86 *c)
161 set_bit(X86_FEATURE_K6_MTRR, c->x86_capability); 161 set_bit(X86_FEATURE_K6_MTRR, c->x86_capability);
162 break; 162 break;
163 } 163 }
164 break;
165 164
165 if (c->x86_model == 10) {
166 /* AMD Geode LX is model 10 */
167 /* placeholder for any needed mods */
168 break;
169 }
170 break;
166 case 6: /* An Athlon/Duron */ 171 case 6: /* An Athlon/Duron */
167 172
168 /* Bit 15 of Athlon specific MSR 15, needs to be 0 173 /* Bit 15 of Athlon specific MSR 15, needs to be 0
diff --git a/arch/i386/kernel/cpu/common.c b/arch/i386/kernel/cpu/common.c
index 31e344b26bae..cca655688ffc 100644
--- a/arch/i386/kernel/cpu/common.c
+++ b/arch/i386/kernel/cpu/common.c
@@ -18,9 +18,6 @@
18 18
19#include "cpu.h" 19#include "cpu.h"
20 20
21DEFINE_PER_CPU(struct desc_struct, cpu_gdt_table[GDT_ENTRIES]);
22EXPORT_PER_CPU_SYMBOL(cpu_gdt_table);
23
24DEFINE_PER_CPU(unsigned char, cpu_16bit_stack[CPU_16BIT_STACK_SIZE]); 21DEFINE_PER_CPU(unsigned char, cpu_16bit_stack[CPU_16BIT_STACK_SIZE]);
25EXPORT_PER_CPU_SYMBOL(cpu_16bit_stack); 22EXPORT_PER_CPU_SYMBOL(cpu_16bit_stack);
26 23
@@ -599,11 +596,6 @@ void __devinit cpu_init(void)
599 load_idt(&idt_descr); 596 load_idt(&idt_descr);
600 597
601 /* 598 /*
602 * Delete NT
603 */
604 __asm__("pushfl ; andl $0xffffbfff,(%esp) ; popfl");
605
606 /*
607 * Set up and load the per-CPU TSS and LDT 599 * Set up and load the per-CPU TSS and LDT
608 */ 600 */
609 atomic_inc(&init_mm.mm_count); 601 atomic_inc(&init_mm.mm_count);
diff --git a/arch/i386/kernel/cpu/cyrix.c b/arch/i386/kernel/cpu/cyrix.c
index ff87cc22b323..75015975d038 100644
--- a/arch/i386/kernel/cpu/cyrix.c
+++ b/arch/i386/kernel/cpu/cyrix.c
@@ -343,6 +343,31 @@ static void __init init_cyrix(struct cpuinfo_x86 *c)
343} 343}
344 344
345/* 345/*
346 * Handle National Semiconductor branded processors
347 */
348static void __devinit init_nsc(struct cpuinfo_x86 *c)
349{
350 /* There may be GX1 processors in the wild that are branded
351 * NSC and not Cyrix.
352 *
353 * This function only handles the GX processor, and kicks every
354 * thing else to the Cyrix init function above - that should
355 * cover any processors that might have been branded differently
356 * after NSC aquired Cyrix.
357 *
358 * If this breaks your GX1 horribly, please e-mail
359 * info-linux@ldcmail.amd.com to tell us.
360 */
361
362 /* Handle the GX (Formally known as the GX2) */
363
364 if (c->x86 == 5 && c->x86_model == 5)
365 display_cacheinfo(c);
366 else
367 init_cyrix(c);
368}
369
370/*
346 * Cyrix CPUs without cpuid or with cpuid not yet enabled can be detected 371 * Cyrix CPUs without cpuid or with cpuid not yet enabled can be detected
347 * by the fact that they preserve the flags across the division of 5/2. 372 * by the fact that they preserve the flags across the division of 5/2.
348 * PII and PPro exhibit this behavior too, but they have cpuid available. 373 * PII and PPro exhibit this behavior too, but they have cpuid available.
@@ -422,7 +447,7 @@ int __init cyrix_init_cpu(void)
422static struct cpu_dev nsc_cpu_dev __initdata = { 447static struct cpu_dev nsc_cpu_dev __initdata = {
423 .c_vendor = "NSC", 448 .c_vendor = "NSC",
424 .c_ident = { "Geode by NSC" }, 449 .c_ident = { "Geode by NSC" },
425 .c_init = init_cyrix, 450 .c_init = init_nsc,
426 .c_identify = generic_identify, 451 .c_identify = generic_identify,
427}; 452};
428 453
diff --git a/arch/i386/kernel/cpuid.c b/arch/i386/kernel/cpuid.c
index 13bae799e626..006141d1c12a 100644
--- a/arch/i386/kernel/cpuid.c
+++ b/arch/i386/kernel/cpuid.c
@@ -117,14 +117,13 @@ static ssize_t cpuid_read(struct file *file, char __user *buf,
117{ 117{
118 char __user *tmp = buf; 118 char __user *tmp = buf;
119 u32 data[4]; 119 u32 data[4];
120 size_t rv;
121 u32 reg = *ppos; 120 u32 reg = *ppos;
122 int cpu = iminor(file->f_dentry->d_inode); 121 int cpu = iminor(file->f_dentry->d_inode);
123 122
124 if (count % 16) 123 if (count % 16)
125 return -EINVAL; /* Invalid chunk size */ 124 return -EINVAL; /* Invalid chunk size */
126 125
127 for (rv = 0; count; count -= 16) { 126 for (; count; count -= 16) {
128 do_cpuid(cpu, reg, data); 127 do_cpuid(cpu, reg, data);
129 if (copy_to_user(tmp, &data, 16)) 128 if (copy_to_user(tmp, &data, 16))
130 return -EFAULT; 129 return -EFAULT;
diff --git a/arch/i386/kernel/entry.S b/arch/i386/kernel/entry.S
index e50b93155249..607c06007508 100644
--- a/arch/i386/kernel/entry.S
+++ b/arch/i386/kernel/entry.S
@@ -657,6 +657,7 @@ ENTRY(spurious_interrupt_bug)
657 pushl $do_spurious_interrupt_bug 657 pushl $do_spurious_interrupt_bug
658 jmp error_code 658 jmp error_code
659 659
660.section .rodata,"a"
660#include "syscall_table.S" 661#include "syscall_table.S"
661 662
662syscall_table_size=(.-sys_call_table) 663syscall_table_size=(.-sys_call_table)
diff --git a/arch/i386/kernel/head.S b/arch/i386/kernel/head.S
index e437fb367498..5884469f6bfe 100644
--- a/arch/i386/kernel/head.S
+++ b/arch/i386/kernel/head.S
@@ -504,19 +504,24 @@ ENTRY(cpu_gdt_table)
504 .quad 0x0000000000000000 /* 0x80 TSS descriptor */ 504 .quad 0x0000000000000000 /* 0x80 TSS descriptor */
505 .quad 0x0000000000000000 /* 0x88 LDT descriptor */ 505 .quad 0x0000000000000000 /* 0x88 LDT descriptor */
506 506
507 /* Segments used for calling PnP BIOS */ 507 /*
508 .quad 0x00c09a0000000000 /* 0x90 32-bit code */ 508 * Segments used for calling PnP BIOS have byte granularity.
509 .quad 0x00809a0000000000 /* 0x98 16-bit code */ 509 * They code segments and data segments have fixed 64k limits,
510 .quad 0x0080920000000000 /* 0xa0 16-bit data */ 510 * the transfer segment sizes are set at run time.
511 .quad 0x0080920000000000 /* 0xa8 16-bit data */ 511 */
512 .quad 0x0080920000000000 /* 0xb0 16-bit data */ 512 .quad 0x00409a000000ffff /* 0x90 32-bit code */
513 .quad 0x00009a000000ffff /* 0x98 16-bit code */
514 .quad 0x000092000000ffff /* 0xa0 16-bit data */
515 .quad 0x0000920000000000 /* 0xa8 16-bit data */
516 .quad 0x0000920000000000 /* 0xb0 16-bit data */
517
513 /* 518 /*
514 * The APM segments have byte granularity and their bases 519 * The APM segments have byte granularity and their bases
515 * and limits are set at run time. 520 * are set at run time. All have 64k limits.
516 */ 521 */
517 .quad 0x00409a0000000000 /* 0xb8 APM CS code */ 522 .quad 0x00409a000000ffff /* 0xb8 APM CS code */
518 .quad 0x00009a0000000000 /* 0xc0 APM CS 16 code (16 bit) */ 523 .quad 0x00009a000000ffff /* 0xc0 APM CS 16 code (16 bit) */
519 .quad 0x0040920000000000 /* 0xc8 APM DS data */ 524 .quad 0x004092000000ffff /* 0xc8 APM DS data */
520 525
521 .quad 0x0000920000000000 /* 0xd0 - ESPFIX 16-bit SS */ 526 .quad 0x0000920000000000 /* 0xd0 - ESPFIX 16-bit SS */
522 .quad 0x0000000000000000 /* 0xd8 - unused */ 527 .quad 0x0000000000000000 /* 0xd8 - unused */
@@ -525,3 +530,5 @@ ENTRY(cpu_gdt_table)
525 .quad 0x0000000000000000 /* 0xf0 - unused */ 530 .quad 0x0000000000000000 /* 0xf0 - unused */
526 .quad 0x0000000000000000 /* 0xf8 - GDT entry 31: double-fault TSS */ 531 .quad 0x0000000000000000 /* 0xf8 - GDT entry 31: double-fault TSS */
527 532
533 /* Be sure this is zeroed to avoid false validations in Xen */
534 .fill PAGE_SIZE_asm / 8 - GDT_ENTRIES,8,0
diff --git a/arch/i386/kernel/i386_ksyms.c b/arch/i386/kernel/i386_ksyms.c
index 180f070d03cb..3999bec50c33 100644
--- a/arch/i386/kernel/i386_ksyms.c
+++ b/arch/i386/kernel/i386_ksyms.c
@@ -3,8 +3,7 @@
3#include <asm/checksum.h> 3#include <asm/checksum.h>
4#include <asm/desc.h> 4#include <asm/desc.h>
5 5
6/* This is definitely a GPL-only symbol */ 6EXPORT_SYMBOL_GPL(cpu_gdt_descr);
7EXPORT_SYMBOL_GPL(cpu_gdt_table);
8 7
9EXPORT_SYMBOL(__down_failed); 8EXPORT_SYMBOL(__down_failed);
10EXPORT_SYMBOL(__down_failed_interruptible); 9EXPORT_SYMBOL(__down_failed_interruptible);
diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c
index 22c8675c79f4..7554f8fd874a 100644
--- a/arch/i386/kernel/io_apic.c
+++ b/arch/i386/kernel/io_apic.c
@@ -1722,8 +1722,8 @@ void disable_IO_APIC(void)
1722 entry.dest_mode = 0; /* Physical */ 1722 entry.dest_mode = 0; /* Physical */
1723 entry.delivery_mode = dest_ExtINT; /* ExtInt */ 1723 entry.delivery_mode = dest_ExtINT; /* ExtInt */
1724 entry.vector = 0; 1724 entry.vector = 0;
1725 entry.dest.physical.physical_dest = 0; 1725 entry.dest.physical.physical_dest =
1726 1726 GET_APIC_ID(apic_read(APIC_ID));
1727 1727
1728 /* 1728 /*
1729 * Add it to the IO-APIC irq-routing table: 1729 * Add it to the IO-APIC irq-routing table:
diff --git a/arch/i386/kernel/mpparse.c b/arch/i386/kernel/mpparse.c
index 1ca5269b1e86..91a64016956e 100644
--- a/arch/i386/kernel/mpparse.c
+++ b/arch/i386/kernel/mpparse.c
@@ -38,6 +38,12 @@
38int smp_found_config; 38int smp_found_config;
39unsigned int __initdata maxcpus = NR_CPUS; 39unsigned int __initdata maxcpus = NR_CPUS;
40 40
41#ifdef CONFIG_HOTPLUG_CPU
42#define CPU_HOTPLUG_ENABLED (1)
43#else
44#define CPU_HOTPLUG_ENABLED (0)
45#endif
46
41/* 47/*
42 * Various Linux-internal data structures created from the 48 * Various Linux-internal data structures created from the
43 * MP-table. 49 * MP-table.
@@ -219,14 +225,18 @@ static void __devinit MP_processor_info (struct mpc_config_processor *m)
219 cpu_set(num_processors, cpu_possible_map); 225 cpu_set(num_processors, cpu_possible_map);
220 num_processors++; 226 num_processors++;
221 227
222 if ((num_processors > 8) && 228 if (CPU_HOTPLUG_ENABLED || (num_processors > 8)) {
223 ((APIC_XAPIC(ver) && 229 switch (boot_cpu_data.x86_vendor) {
224 (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL)) || 230 case X86_VENDOR_INTEL:
225 (boot_cpu_data.x86_vendor == X86_VENDOR_AMD))) 231 if (!APIC_XAPIC(ver)) {
226 def_to_bigsmp = 1; 232 def_to_bigsmp = 0;
227 else 233 break;
228 def_to_bigsmp = 0; 234 }
229 235 /* If P4 and above fall through */
236 case X86_VENDOR_AMD:
237 def_to_bigsmp = 1;
238 }
239 }
230 bios_cpu_apicid[num_processors - 1] = m->mpc_apicid; 240 bios_cpu_apicid[num_processors - 1] = m->mpc_apicid;
231} 241}
232 242
diff --git a/arch/i386/kernel/msr.c b/arch/i386/kernel/msr.c
index 44470fea4309..1d0a55e68760 100644
--- a/arch/i386/kernel/msr.c
+++ b/arch/i386/kernel/msr.c
@@ -172,7 +172,6 @@ static ssize_t msr_read(struct file *file, char __user * buf,
172{ 172{
173 u32 __user *tmp = (u32 __user *) buf; 173 u32 __user *tmp = (u32 __user *) buf;
174 u32 data[2]; 174 u32 data[2];
175 size_t rv;
176 u32 reg = *ppos; 175 u32 reg = *ppos;
177 int cpu = iminor(file->f_dentry->d_inode); 176 int cpu = iminor(file->f_dentry->d_inode);
178 int err; 177 int err;
@@ -180,7 +179,7 @@ static ssize_t msr_read(struct file *file, char __user * buf,
180 if (count % 8) 179 if (count % 8)
181 return -EINVAL; /* Invalid chunk size */ 180 return -EINVAL; /* Invalid chunk size */
182 181
183 for (rv = 0; count; count -= 8) { 182 for (; count; count -= 8) {
184 err = do_rdmsr(cpu, reg, &data[0], &data[1]); 183 err = do_rdmsr(cpu, reg, &data[0], &data[1]);
185 if (err) 184 if (err)
186 return err; 185 return err;
diff --git a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c
index 2333aead0563..45e7f0ac4b04 100644
--- a/arch/i386/kernel/process.c
+++ b/arch/i386/kernel/process.c
@@ -308,9 +308,7 @@ void show_regs(struct pt_regs * regs)
308 cr0 = read_cr0(); 308 cr0 = read_cr0();
309 cr2 = read_cr2(); 309 cr2 = read_cr2();
310 cr3 = read_cr3(); 310 cr3 = read_cr3();
311 if (current_cpu_data.x86 > 4) { 311 cr4 = read_cr4_safe();
312 cr4 = read_cr4();
313 }
314 printk("CR0: %08lx CR2: %08lx CR3: %08lx CR4: %08lx\n", cr0, cr2, cr3, cr4); 312 printk("CR0: %08lx CR2: %08lx CR3: %08lx CR4: %08lx\n", cr0, cr2, cr3, cr4);
315 show_trace(NULL, &regs->esp); 313 show_trace(NULL, &regs->esp);
316} 314}
@@ -404,17 +402,7 @@ void flush_thread(void)
404 402
405void release_thread(struct task_struct *dead_task) 403void release_thread(struct task_struct *dead_task)
406{ 404{
407 if (dead_task->mm) { 405 BUG_ON(dead_task->mm);
408 // temporary debugging check
409 if (dead_task->mm->context.size) {
410 printk("WARNING: dead process %8s still has LDT? <%p/%d>\n",
411 dead_task->comm,
412 dead_task->mm->context.ldt,
413 dead_task->mm->context.size);
414 BUG();
415 }
416 }
417
418 release_vm86_irqs(dead_task); 406 release_vm86_irqs(dead_task);
419} 407}
420 408
diff --git a/arch/i386/kernel/ptrace.c b/arch/i386/kernel/ptrace.c
index 5ffbb4b7ad05..5c1fb6aada5b 100644
--- a/arch/i386/kernel/ptrace.c
+++ b/arch/i386/kernel/ptrace.c
@@ -32,9 +32,12 @@
32 * in exit.c or in signal.c. 32 * in exit.c or in signal.c.
33 */ 33 */
34 34
35/* determines which flags the user has access to. */ 35/*
36/* 1 = access 0 = no access */ 36 * Determines which flags the user has access to [1 = access, 0 = no access].
37#define FLAG_MASK 0x00044dd5 37 * Prohibits changing ID(21), VIP(20), VIF(19), VM(17), IOPL(12-13), IF(9).
38 * Also masks reserved bits (31-22, 15, 5, 3, 1).
39 */
40#define FLAG_MASK 0x00054dd5
38 41
39/* set's the trap flag. */ 42/* set's the trap flag. */
40#define TRAP_FLAG 0x100 43#define TRAP_FLAG 0x100
diff --git a/arch/i386/kernel/reboot.c b/arch/i386/kernel/reboot.c
index 2afe0f8d555a..2fa5803a759d 100644
--- a/arch/i386/kernel/reboot.c
+++ b/arch/i386/kernel/reboot.c
@@ -111,12 +111,12 @@ static struct dmi_system_id __initdata reboot_dmi_table[] = {
111 DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge 2400"), 111 DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge 2400"),
112 }, 112 },
113 }, 113 },
114 { /* Handle problems with rebooting on HP nc6120 */ 114 { /* Handle problems with rebooting on HP laptops */
115 .callback = set_bios_reboot, 115 .callback = set_bios_reboot,
116 .ident = "HP Compaq nc6120", 116 .ident = "HP Compaq Laptop",
117 .matches = { 117 .matches = {
118 DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), 118 DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
119 DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq nc6120"), 119 DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq"),
120 }, 120 },
121 }, 121 },
122 { } 122 { }
diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c
index fdfcb0cba9b4..27c956db0461 100644
--- a/arch/i386/kernel/setup.c
+++ b/arch/i386/kernel/setup.c
@@ -954,6 +954,12 @@ efi_find_max_pfn(unsigned long start, unsigned long end, void *arg)
954 return 0; 954 return 0;
955} 955}
956 956
957static int __init
958efi_memory_present_wrapper(unsigned long start, unsigned long end, void *arg)
959{
960 memory_present(0, start, end);
961 return 0;
962}
957 963
958/* 964/*
959 * Find the highest page frame number we have available 965 * Find the highest page frame number we have available
@@ -965,6 +971,7 @@ void __init find_max_pfn(void)
965 max_pfn = 0; 971 max_pfn = 0;
966 if (efi_enabled) { 972 if (efi_enabled) {
967 efi_memmap_walk(efi_find_max_pfn, &max_pfn); 973 efi_memmap_walk(efi_find_max_pfn, &max_pfn);
974 efi_memmap_walk(efi_memory_present_wrapper, NULL);
968 return; 975 return;
969 } 976 }
970 977
@@ -979,6 +986,7 @@ void __init find_max_pfn(void)
979 continue; 986 continue;
980 if (end > max_pfn) 987 if (end > max_pfn)
981 max_pfn = end; 988 max_pfn = end;
989 memory_present(0, start, end);
982 } 990 }
983} 991}
984 992
diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c
index 9ed449af8e9f..b3c2e2c26743 100644
--- a/arch/i386/kernel/smpboot.c
+++ b/arch/i386/kernel/smpboot.c
@@ -903,6 +903,12 @@ static int __devinit do_boot_cpu(int apicid, int cpu)
903 unsigned long start_eip; 903 unsigned long start_eip;
904 unsigned short nmi_high = 0, nmi_low = 0; 904 unsigned short nmi_high = 0, nmi_low = 0;
905 905
906 if (!cpu_gdt_descr[cpu].address &&
907 !(cpu_gdt_descr[cpu].address = get_zeroed_page(GFP_KERNEL))) {
908 printk("Failed to allocate GDT for CPU %d\n", cpu);
909 return 1;
910 }
911
906 ++cpucount; 912 ++cpucount;
907 913
908 /* 914 /*
diff --git a/arch/i386/kernel/syscall_table.S b/arch/i386/kernel/syscall_table.S
index 9b21a31d4f4e..f7ba4acc20ec 100644
--- a/arch/i386/kernel/syscall_table.S
+++ b/arch/i386/kernel/syscall_table.S
@@ -1,4 +1,3 @@
1.data
2ENTRY(sys_call_table) 1ENTRY(sys_call_table)
3 .long sys_restart_syscall /* 0 - old "setup()" system call, used for restarting */ 2 .long sys_restart_syscall /* 0 - old "setup()" system call, used for restarting */
4 .long sys_exit 3 .long sys_exit
diff --git a/arch/i386/kernel/timers/timer_tsc.c b/arch/i386/kernel/timers/timer_tsc.c
index d395e3b42485..47675bbbb316 100644
--- a/arch/i386/kernel/timers/timer_tsc.c
+++ b/arch/i386/kernel/timers/timer_tsc.c
@@ -330,7 +330,9 @@ int recalibrate_cpu_khz(void)
330 unsigned int cpu_khz_old = cpu_khz; 330 unsigned int cpu_khz_old = cpu_khz;
331 331
332 if (cpu_has_tsc) { 332 if (cpu_has_tsc) {
333 local_irq_disable();
333 init_cpu_khz(); 334 init_cpu_khz();
335 local_irq_enable();
334 cpu_data[0].loops_per_jiffy = 336 cpu_data[0].loops_per_jiffy =
335 cpufreq_scale(cpu_data[0].loops_per_jiffy, 337 cpufreq_scale(cpu_data[0].loops_per_jiffy,
336 cpu_khz_old, 338 cpu_khz_old,
diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c
index ab0e9430f775..53ad954e3ba4 100644
--- a/arch/i386/kernel/traps.c
+++ b/arch/i386/kernel/traps.c
@@ -306,14 +306,17 @@ void die(const char * str, struct pt_regs * regs, long err)
306 .lock_owner_depth = 0 306 .lock_owner_depth = 0
307 }; 307 };
308 static int die_counter; 308 static int die_counter;
309 unsigned long flags;
309 310
310 if (die.lock_owner != raw_smp_processor_id()) { 311 if (die.lock_owner != raw_smp_processor_id()) {
311 console_verbose(); 312 console_verbose();
312 spin_lock_irq(&die.lock); 313 spin_lock_irqsave(&die.lock, flags);
313 die.lock_owner = smp_processor_id(); 314 die.lock_owner = smp_processor_id();
314 die.lock_owner_depth = 0; 315 die.lock_owner_depth = 0;
315 bust_spinlocks(1); 316 bust_spinlocks(1);
316 } 317 }
318 else
319 local_save_flags(flags);
317 320
318 if (++die.lock_owner_depth < 3) { 321 if (++die.lock_owner_depth < 3) {
319 int nl = 0; 322 int nl = 0;
@@ -340,7 +343,7 @@ void die(const char * str, struct pt_regs * regs, long err)
340 343
341 bust_spinlocks(0); 344 bust_spinlocks(0);
342 die.lock_owner = -1; 345 die.lock_owner = -1;
343 spin_unlock_irq(&die.lock); 346 spin_unlock_irqrestore(&die.lock, flags);
344 347
345 if (kexec_should_crash(current)) 348 if (kexec_should_crash(current))
346 crash_kexec(regs); 349 crash_kexec(regs);
@@ -1075,9 +1078,9 @@ void __init trap_init(void)
1075 set_trap_gate(0,&divide_error); 1078 set_trap_gate(0,&divide_error);
1076 set_intr_gate(1,&debug); 1079 set_intr_gate(1,&debug);
1077 set_intr_gate(2,&nmi); 1080 set_intr_gate(2,&nmi);
1078 set_system_intr_gate(3, &int3); /* int3-5 can be called from all */ 1081 set_system_intr_gate(3, &int3); /* int3/4 can be called from all */
1079 set_system_gate(4,&overflow); 1082 set_system_gate(4,&overflow);
1080 set_system_gate(5,&bounds); 1083 set_trap_gate(5,&bounds);
1081 set_trap_gate(6,&invalid_op); 1084 set_trap_gate(6,&invalid_op);
1082 set_trap_gate(7,&device_not_available); 1085 set_trap_gate(7,&device_not_available);
1083 set_task_gate(8,GDT_ENTRY_DOUBLEFAULT_TSS); 1086 set_task_gate(8,GDT_ENTRY_DOUBLEFAULT_TSS);
@@ -1095,6 +1098,28 @@ void __init trap_init(void)
1095#endif 1098#endif
1096 set_trap_gate(19,&simd_coprocessor_error); 1099 set_trap_gate(19,&simd_coprocessor_error);
1097 1100
1101 if (cpu_has_fxsr) {
1102 /*
1103 * Verify that the FXSAVE/FXRSTOR data will be 16-byte aligned.
1104 * Generates a compile-time "error: zero width for bit-field" if
1105 * the alignment is wrong.
1106 */
1107 struct fxsrAlignAssert {
1108 int _:!(offsetof(struct task_struct,
1109 thread.i387.fxsave) & 15);
1110 };
1111
1112 printk(KERN_INFO "Enabling fast FPU save and restore... ");
1113 set_in_cr4(X86_CR4_OSFXSR);
1114 printk("done.\n");
1115 }
1116 if (cpu_has_xmm) {
1117 printk(KERN_INFO "Enabling unmasked SIMD FPU exception "
1118 "support... ");
1119 set_in_cr4(X86_CR4_OSXMMEXCPT);
1120 printk("done.\n");
1121 }
1122
1098 set_system_gate(SYSCALL_VECTOR,&system_call); 1123 set_system_gate(SYSCALL_VECTOR,&system_call);
1099 1124
1100 /* 1125 /*
diff --git a/arch/i386/mm/init.c b/arch/i386/mm/init.c
index 06e26f006238..7df494b51a5b 100644
--- a/arch/i386/mm/init.c
+++ b/arch/i386/mm/init.c
@@ -735,6 +735,30 @@ void free_initmem(void)
735 printk (KERN_INFO "Freeing unused kernel memory: %dk freed\n", (__init_end - __init_begin) >> 10); 735 printk (KERN_INFO "Freeing unused kernel memory: %dk freed\n", (__init_end - __init_begin) >> 10);
736} 736}
737 737
738#ifdef CONFIG_DEBUG_RODATA
739
740extern char __start_rodata, __end_rodata;
741void mark_rodata_ro(void)
742{
743 unsigned long addr = (unsigned long)&__start_rodata;
744
745 for (; addr < (unsigned long)&__end_rodata; addr += PAGE_SIZE)
746 change_page_attr(virt_to_page(addr), 1, PAGE_KERNEL_RO);
747
748 printk ("Write protecting the kernel read-only data: %luk\n",
749 (unsigned long)(&__end_rodata - &__start_rodata) >> 10);
750
751 /*
752 * change_page_attr() requires a global_flush_tlb() call after it.
753 * We do this after the printk so that if something went wrong in the
754 * change, the printk gets out at least to give a better debug hint
755 * of who is the culprit.
756 */
757 global_flush_tlb();
758}
759#endif
760
761
738#ifdef CONFIG_BLK_DEV_INITRD 762#ifdef CONFIG_BLK_DEV_INITRD
739void free_initrd_mem(unsigned long start, unsigned long end) 763void free_initrd_mem(unsigned long start, unsigned long end)
740{ 764{
diff --git a/arch/i386/mm/pageattr.c b/arch/i386/mm/pageattr.c
index f600fc244f02..c30a16df6440 100644
--- a/arch/i386/mm/pageattr.c
+++ b/arch/i386/mm/pageattr.c
@@ -13,6 +13,7 @@
13#include <asm/processor.h> 13#include <asm/processor.h>
14#include <asm/tlbflush.h> 14#include <asm/tlbflush.h>
15#include <asm/pgalloc.h> 15#include <asm/pgalloc.h>
16#include <asm/sections.h>
16 17
17static DEFINE_SPINLOCK(cpa_lock); 18static DEFINE_SPINLOCK(cpa_lock);
18static struct list_head df_list = LIST_HEAD_INIT(df_list); 19static struct list_head df_list = LIST_HEAD_INIT(df_list);
@@ -36,7 +37,8 @@ pte_t *lookup_address(unsigned long address)
36 return pte_offset_kernel(pmd, address); 37 return pte_offset_kernel(pmd, address);
37} 38}
38 39
39static struct page *split_large_page(unsigned long address, pgprot_t prot) 40static struct page *split_large_page(unsigned long address, pgprot_t prot,
41 pgprot_t ref_prot)
40{ 42{
41 int i; 43 int i;
42 unsigned long addr; 44 unsigned long addr;
@@ -54,7 +56,7 @@ static struct page *split_large_page(unsigned long address, pgprot_t prot)
54 pbase = (pte_t *)page_address(base); 56 pbase = (pte_t *)page_address(base);
55 for (i = 0; i < PTRS_PER_PTE; i++, addr += PAGE_SIZE) { 57 for (i = 0; i < PTRS_PER_PTE; i++, addr += PAGE_SIZE) {
56 set_pte(&pbase[i], pfn_pte(addr >> PAGE_SHIFT, 58 set_pte(&pbase[i], pfn_pte(addr >> PAGE_SHIFT,
57 addr == address ? prot : PAGE_KERNEL)); 59 addr == address ? prot : ref_prot));
58 } 60 }
59 return base; 61 return base;
60} 62}
@@ -98,11 +100,18 @@ static void set_pmd_pte(pte_t *kpte, unsigned long address, pte_t pte)
98 */ 100 */
99static inline void revert_page(struct page *kpte_page, unsigned long address) 101static inline void revert_page(struct page *kpte_page, unsigned long address)
100{ 102{
101 pte_t *linear = (pte_t *) 103 pgprot_t ref_prot;
104 pte_t *linear;
105
106 ref_prot =
107 ((address & LARGE_PAGE_MASK) < (unsigned long)&_etext)
108 ? PAGE_KERNEL_LARGE_EXEC : PAGE_KERNEL_LARGE;
109
110 linear = (pte_t *)
102 pmd_offset(pud_offset(pgd_offset_k(address), address), address); 111 pmd_offset(pud_offset(pgd_offset_k(address), address), address);
103 set_pmd_pte(linear, address, 112 set_pmd_pte(linear, address,
104 pfn_pte((__pa(address) & LARGE_PAGE_MASK) >> PAGE_SHIFT, 113 pfn_pte((__pa(address) & LARGE_PAGE_MASK) >> PAGE_SHIFT,
105 PAGE_KERNEL_LARGE)); 114 ref_prot));
106} 115}
107 116
108static int 117static int
@@ -123,10 +132,16 @@ __change_page_attr(struct page *page, pgprot_t prot)
123 if ((pte_val(*kpte) & _PAGE_PSE) == 0) { 132 if ((pte_val(*kpte) & _PAGE_PSE) == 0) {
124 set_pte_atomic(kpte, mk_pte(page, prot)); 133 set_pte_atomic(kpte, mk_pte(page, prot));
125 } else { 134 } else {
126 struct page *split = split_large_page(address, prot); 135 pgprot_t ref_prot;
136 struct page *split;
137
138 ref_prot =
139 ((address & LARGE_PAGE_MASK) < (unsigned long)&_etext)
140 ? PAGE_KERNEL_EXEC : PAGE_KERNEL;
141 split = split_large_page(address, prot, ref_prot);
127 if (!split) 142 if (!split)
128 return -ENOMEM; 143 return -ENOMEM;
129 set_pmd_pte(kpte,address,mk_pte(split, PAGE_KERNEL)); 144 set_pmd_pte(kpte,address,mk_pte(split, ref_prot));
130 kpte_page = split; 145 kpte_page = split;
131 } 146 }
132 get_page(kpte_page); 147 get_page(kpte_page);
diff --git a/arch/i386/pci/irq.c b/arch/i386/pci/irq.c
index 19e6f4871d1e..ee8e01697d96 100644
--- a/arch/i386/pci/irq.c
+++ b/arch/i386/pci/irq.c
@@ -846,7 +846,7 @@ static int pcibios_lookup_irq(struct pci_dev *dev, int assign)
846 * reported by the device if possible. 846 * reported by the device if possible.
847 */ 847 */
848 newirq = dev->irq; 848 newirq = dev->irq;
849 if (!((1 << newirq) & mask)) { 849 if (newirq && !((1 << newirq) & mask)) {
850 if ( pci_probe & PCI_USE_PIRQ_MASK) newirq = 0; 850 if ( pci_probe & PCI_USE_PIRQ_MASK) newirq = 0;
851 else printk(KERN_WARNING "PCI: IRQ %i for device %s doesn't match PIRQ mask - try pci=usepirqmask\n", newirq, pci_name(dev)); 851 else printk(KERN_WARNING "PCI: IRQ %i for device %s doesn't match PIRQ mask - try pci=usepirqmask\n", newirq, pci_name(dev));
852 } 852 }
diff --git a/arch/m32r/Kconfig b/arch/m32r/Kconfig
index 4d100f3886e1..fae67bbb52f6 100644
--- a/arch/m32r/Kconfig
+++ b/arch/m32r/Kconfig
@@ -81,6 +81,12 @@ config PLAT_MAPPI2
81config PLAT_MAPPI3 81config PLAT_MAPPI3
82 bool "Mappi-III(M3A-2170)" 82 bool "Mappi-III(M3A-2170)"
83 83
84config PLAT_M32104UT
85 bool "M32104UT"
86 help
87 The M3T-M32104UT is an reference board based on uT-Engine
88 specification. This board has a M32104 chip.
89
84endchoice 90endchoice
85 91
86choice 92choice
@@ -93,6 +99,10 @@ config CHIP_M32700
93config CHIP_M32102 99config CHIP_M32102
94 bool "M32102" 100 bool "M32102"
95 101
102config CHIP_M32104
103 bool "M32104"
104 depends on PLAT_M32104UT
105
96config CHIP_VDEC2 106config CHIP_VDEC2
97 bool "VDEC2" 107 bool "VDEC2"
98 108
@@ -115,7 +125,7 @@ config TLB_ENTRIES
115 125
116config ISA_M32R 126config ISA_M32R
117 bool 127 bool
118 depends on CHIP_M32102 128 depends on CHIP_M32102 || CHIP_M32104
119 default y 129 default y
120 130
121config ISA_M32R2 131config ISA_M32R2
@@ -140,6 +150,7 @@ config BUS_CLOCK
140 default "50000000" if PLAT_MAPPI3 150 default "50000000" if PLAT_MAPPI3
141 default "50000000" if PLAT_M32700UT 151 default "50000000" if PLAT_M32700UT
142 default "50000000" if PLAT_OPSPUT 152 default "50000000" if PLAT_OPSPUT
153 default "54000000" if PLAT_M32104UT
143 default "33333333" if PLAT_OAKS32R 154 default "33333333" if PLAT_OAKS32R
144 default "20000000" if PLAT_MAPPI2 155 default "20000000" if PLAT_MAPPI2
145 156
@@ -157,6 +168,7 @@ config MEMORY_START
157 default "08000000" if PLAT_USRV 168 default "08000000" if PLAT_USRV
158 default "08000000" if PLAT_M32700UT 169 default "08000000" if PLAT_M32700UT
159 default "08000000" if PLAT_OPSPUT 170 default "08000000" if PLAT_OPSPUT
171 default "04000000" if PLAT_M32104UT
160 default "01000000" if PLAT_OAKS32R 172 default "01000000" if PLAT_OAKS32R
161 173
162config MEMORY_SIZE 174config MEMORY_SIZE
@@ -166,6 +178,7 @@ config MEMORY_SIZE
166 default "02000000" if PLAT_USRV 178 default "02000000" if PLAT_USRV
167 default "01000000" if PLAT_M32700UT 179 default "01000000" if PLAT_M32700UT
168 default "01000000" if PLAT_OPSPUT 180 default "01000000" if PLAT_OPSPUT
181 default "01000000" if PLAT_M32104UT
169 default "00800000" if PLAT_OAKS32R 182 default "00800000" if PLAT_OAKS32R
170 183
171config NOHIGHMEM 184config NOHIGHMEM
@@ -174,21 +187,22 @@ config NOHIGHMEM
174 187
175config ARCH_DISCONTIGMEM_ENABLE 188config ARCH_DISCONTIGMEM_ENABLE
176 bool "Internal RAM Support" 189 bool "Internal RAM Support"
177 depends on CHIP_M32700 || CHIP_M32102 || CHIP_VDEC2 || CHIP_OPSP 190 depends on CHIP_M32700 || CHIP_M32102 || CHIP_VDEC2 || CHIP_OPSP || CHIP_M32104
178 default y 191 default y
179 192
180source "mm/Kconfig" 193source "mm/Kconfig"
181 194
182config IRAM_START 195config IRAM_START
183 hex "Internal memory start address (hex)" 196 hex "Internal memory start address (hex)"
184 default "00f00000" 197 default "00f00000" if !CHIP_M32104
185 depends on (CHIP_M32700 || CHIP_M32102 || CHIP_VDEC2 || CHIP_OPSP) && DISCONTIGMEM 198 default "00700000" if CHIP_M32104
199 depends on (CHIP_M32700 || CHIP_M32102 || CHIP_VDEC2 || CHIP_OPSP || CHIP_M32104) && DISCONTIGMEM
186 200
187config IRAM_SIZE 201config IRAM_SIZE
188 hex "Internal memory size (hex)" 202 hex "Internal memory size (hex)"
189 depends on (CHIP_M32700 || CHIP_M32102 || CHIP_VDEC2 || CHIP_OPSP) && DISCONTIGMEM 203 depends on (CHIP_M32700 || CHIP_M32102 || CHIP_VDEC2 || CHIP_OPSP || CHIP_M32104) && DISCONTIGMEM
190 default "00080000" if CHIP_M32700 204 default "00080000" if CHIP_M32700
191 default "00010000" if CHIP_M32102 || CHIP_OPSP 205 default "00010000" if CHIP_M32102 || CHIP_OPSP || CHIP_M32104
192 default "00008000" if CHIP_VDEC2 206 default "00008000" if CHIP_VDEC2
193 207
194# 208#
diff --git a/arch/m32r/boot/compressed/head.S b/arch/m32r/boot/compressed/head.S
index 07cfd6ad1ae4..234d8b1e0ac1 100644
--- a/arch/m32r/boot/compressed/head.S
+++ b/arch/m32r/boot/compressed/head.S
@@ -143,6 +143,11 @@ startup:
143 ldi r0, -2 143 ldi r0, -2
144 ldi r1, 0x0100 ; invalidate 144 ldi r1, 0x0100 ; invalidate
145 stb r1, @r0 145 stb r1, @r0
146#elif defined(CONFIG_CHIP_M32104)
147 /* Cache flush */
148 ldi r0, -2
149 ldi r1, 0x0700 ; invalidate i-cache, copy back d-cache
150 sth r1, @r0
146#else 151#else
147#error "put your cache flush function, please" 152#error "put your cache flush function, please"
148#endif 153#endif
diff --git a/arch/m32r/boot/setup.S b/arch/m32r/boot/setup.S
index 5d256434b4ad..398542507d84 100644
--- a/arch/m32r/boot/setup.S
+++ b/arch/m32r/boot/setup.S
@@ -1,11 +1,10 @@
1/* 1/*
2 * linux/arch/m32r/boot/setup.S -- A setup code. 2 * linux/arch/m32r/boot/setup.S -- A setup code.
3 * 3 *
4 * Copyright (C) 2001, 2002 Hiroyuki Kondo, Hirokazu Takata, 4 * Copyright (C) 2001-2005 Hiroyuki Kondo, Hirokazu Takata,
5 * and Hitoshi Yamamoto 5 * Hitoshi Yamamoto, Hayato Fujiwara
6 * 6 *
7 */ 7 */
8/* $Id$ */
9 8
10#include <linux/linkage.h> 9#include <linux/linkage.h>
11#include <asm/segment.h> 10#include <asm/segment.h>
@@ -80,6 +79,20 @@ ENTRY(boot)
80 ldi r1, #0x101 ; cache on (with invalidation) 79 ldi r1, #0x101 ; cache on (with invalidation)
81; ldi r1, #0x00 ; cache off 80; ldi r1, #0x00 ; cache off
82 st r1, @r0 81 st r1, @r0
82#elif defined(CONFIG_CHIP_M32104)
83 ldi r0, #-96 ; DNCR0
84 seth r1, #0x0060 ; from 0x00600000
85 or3 r1, r1, #0x0005 ; size 2MB
86 st r1, @r0
87 seth r1, #0x0100 ; from 0x01000000
88 or3 r1, r1, #0x0003 ; size 16MB
89 st r1, @+r0
90 seth r1, #0x0200 ; from 0x02000000
91 or3 r1, r1, #0x0002 ; size 32MB
92 st r1, @+r0
93 ldi r0, #-4 ;LDIMM (r0, M32R_MCCR)
94 ldi r1, #0x703 ; cache on (with invalidation)
95 st r1, @r0
83#else 96#else
84#error unknown chip configuration 97#error unknown chip configuration
85#endif 98#endif
@@ -115,10 +128,15 @@ mmu_on:
115 st r1, @(MATM_offset,r0) ; Set MATM (T bit ON) 128 st r1, @(MATM_offset,r0) ; Set MATM (T bit ON)
116 ld r0, @(MATM_offset,r0) ; Check 129 ld r0, @(MATM_offset,r0) ; Check
117#else 130#else
131#if defined(CONFIG_CHIP_M32700)
118 seth r0,#high(M32R_MCDCAR) 132 seth r0,#high(M32R_MCDCAR)
119 or3 r0,r0,#low(M32R_MCDCAR) 133 or3 r0,r0,#low(M32R_MCDCAR)
120 ld24 r1,#0x8080 134 ld24 r1,#0x8080
121 st r1,@r0 135 st r1,@r0
136#elif defined(CONFIG_CHIP_M32104)
137 LDIMM (r2, eit_vector) ; set EVB(cr5)
138 mvtc r2, cr5
139#endif
122#endif /* CONFIG_MMU */ 140#endif /* CONFIG_MMU */
123 jmp r13 141 jmp r13
124 nop 142 nop
diff --git a/arch/m32r/kernel/Makefile b/arch/m32r/kernel/Makefile
index 6c6b6c376638..5a2fa886906f 100644
--- a/arch/m32r/kernel/Makefile
+++ b/arch/m32r/kernel/Makefile
@@ -16,5 +16,6 @@ obj-$(CONFIG_PLAT_M32700UT) += setup_m32700ut.o io_m32700ut.o
16obj-$(CONFIG_PLAT_OPSPUT) += setup_opsput.o io_opsput.o 16obj-$(CONFIG_PLAT_OPSPUT) += setup_opsput.o io_opsput.o
17obj-$(CONFIG_MODULES) += module.o 17obj-$(CONFIG_MODULES) += module.o
18obj-$(CONFIG_PLAT_OAKS32R) += setup_oaks32r.o io_oaks32r.o 18obj-$(CONFIG_PLAT_OAKS32R) += setup_oaks32r.o io_oaks32r.o
19obj-$(CONFIG_PLAT_M32104UT) += setup_m32104ut.o io_m32104ut.o
19 20
20EXTRA_AFLAGS := -traditional 21EXTRA_AFLAGS := -traditional
diff --git a/arch/m32r/kernel/entry.S b/arch/m32r/kernel/entry.S
index 396c94218cc2..3871b65f0c82 100644
--- a/arch/m32r/kernel/entry.S
+++ b/arch/m32r/kernel/entry.S
@@ -315,7 +315,7 @@ ENTRY(ei_handler)
315 mv r1, sp ; arg1(regs) 315 mv r1, sp ; arg1(regs)
316#if defined(CONFIG_CHIP_VDEC2) || defined(CONFIG_CHIP_XNUX2) \ 316#if defined(CONFIG_CHIP_VDEC2) || defined(CONFIG_CHIP_XNUX2) \
317 || defined(CONFIG_CHIP_M32700) || defined(CONFIG_CHIP_M32102) \ 317 || defined(CONFIG_CHIP_M32700) || defined(CONFIG_CHIP_M32102) \
318 || defined(CONFIG_CHIP_OPSP) 318 || defined(CONFIG_CHIP_OPSP) || defined(CONFIG_CHIP_M32104)
319 319
320; GET_ICU_STATUS; 320; GET_ICU_STATUS;
321 seth r0, #shigh(M32R_ICU_ISTS_ADDR) 321 seth r0, #shigh(M32R_ICU_ISTS_ADDR)
@@ -541,7 +541,20 @@ check_int2:
541 bra check_end 541 bra check_end
542 .fillinsn 542 .fillinsn
543check_end: 543check_end:
544#endif /* CONFIG_PLAT_OPSPUT */ 544#elif defined(CONFIG_PLAT_M32104UT)
545 add3 r2, r0, #-(M32R_IRQ_INT1) ; INT1# interrupt
546 bnez r2, check_end
547 ; read ICU status register of PLD
548 seth r0, #high(PLD_ICUISTS)
549 or3 r0, r0, #low(PLD_ICUISTS)
550 lduh r0, @r0
551 slli r0, #21
552 srli r0, #27 ; ISN
553 addi r0, #(M32104UT_PLD_IRQ_BASE)
554 bra check_end
555 .fillinsn
556check_end:
557#endif /* CONFIG_PLAT_M32104UT */
545 bl do_IRQ 558 bl do_IRQ
546#endif /* CONFIG_SMP */ 559#endif /* CONFIG_SMP */
547 ld r14, @sp+ 560 ld r14, @sp+
@@ -651,8 +664,6 @@ ENTRY(rie_handler)
651/* void rie_handler(int error_code) */ 664/* void rie_handler(int error_code) */
652 SWITCH_TO_KERNEL_STACK 665 SWITCH_TO_KERNEL_STACK
653 SAVE_ALL 666 SAVE_ALL
654 mvfc r0, bpc
655 ld r1, @r0
656 ldi r1, #0x20 ; error_code 667 ldi r1, #0x20 ; error_code
657 mv r0, sp ; pt_regs 668 mv r0, sp ; pt_regs
658 bl do_rie_handler 669 bl do_rie_handler
diff --git a/arch/m32r/kernel/io_m32104ut.c b/arch/m32r/kernel/io_m32104ut.c
new file mode 100644
index 000000000000..d26adab9586c
--- /dev/null
+++ b/arch/m32r/kernel/io_m32104ut.c
@@ -0,0 +1,298 @@
1/*
2 * linux/arch/m32r/kernel/io_m32104ut.c
3 *
4 * Typical I/O routines for M32104UT board.
5 *
6 * Copyright (c) 2001-2005 Hiroyuki Kondo, Hirokazu Takata,
7 * Hitoshi Yamamoto, Mamoru Sakugawa,
8 * Naoto Sugai, Hayato Fujiwara
9 */
10
11#include <linux/config.h>
12#include <asm/m32r.h>
13#include <asm/page.h>
14#include <asm/io.h>
15#include <asm/byteorder.h>
16
17#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_CFC)
18#include <linux/types.h>
19
20#define M32R_PCC_IOMAP_SIZE 0x1000
21
22#define M32R_PCC_IOSTART0 0x1000
23#define M32R_PCC_IOEND0 (M32R_PCC_IOSTART0 + M32R_PCC_IOMAP_SIZE - 1)
24
25extern void pcc_ioread_byte(int, unsigned long, void *, size_t, size_t, int);
26extern void pcc_ioread_word(int, unsigned long, void *, size_t, size_t, int);
27extern void pcc_iowrite_byte(int, unsigned long, void *, size_t, size_t, int);
28extern void pcc_iowrite_word(int, unsigned long, void *, size_t, size_t, int);
29#endif /* CONFIG_PCMCIA && CONFIG_M32R_CFC */
30
31#define PORT2ADDR(port) _port2addr(port)
32
33static inline void *_port2addr(unsigned long port)
34{
35 return (void *)(port | NONCACHE_OFFSET);
36}
37
38#if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC)
39static inline void *__port2addr_ata(unsigned long port)
40{
41 static int dummy_reg;
42
43 switch (port) {
44 case 0x1f0: return (void *)(0x0c002000 | NONCACHE_OFFSET);
45 case 0x1f1: return (void *)(0x0c012800 | NONCACHE_OFFSET);
46 case 0x1f2: return (void *)(0x0c012002 | NONCACHE_OFFSET);
47 case 0x1f3: return (void *)(0x0c012802 | NONCACHE_OFFSET);
48 case 0x1f4: return (void *)(0x0c012004 | NONCACHE_OFFSET);
49 case 0x1f5: return (void *)(0x0c012804 | NONCACHE_OFFSET);
50 case 0x1f6: return (void *)(0x0c012006 | NONCACHE_OFFSET);
51 case 0x1f7: return (void *)(0x0c012806 | NONCACHE_OFFSET);
52 case 0x3f6: return (void *)(0x0c01200e | NONCACHE_OFFSET);
53 default: return (void *)&dummy_reg;
54 }
55}
56#endif
57
58/*
59 * M32104T-LAN is located in the extended bus space
60 * from 0x01000000 to 0x01ffffff on physical address.
61 * The base address of LAN controller(LAN91C111) is 0x300.
62 */
63#define LAN_IOSTART (0x300 | NONCACHE_OFFSET)
64#define LAN_IOEND (0x320 | NONCACHE_OFFSET)
65static inline void *_port2addr_ne(unsigned long port)
66{
67 return (void *)(port + NONCACHE_OFFSET + 0x01000000);
68}
69
70static inline void delay(void)
71{
72 __asm__ __volatile__ ("push r0; \n\t pop r0;" : : :"memory");
73}
74
75/*
76 * NIC I/O function
77 */
78
79#define PORT2ADDR_NE(port) _port2addr_ne(port)
80
81static inline unsigned char _ne_inb(void *portp)
82{
83 return *(volatile unsigned char *)portp;
84}
85
86static inline unsigned short _ne_inw(void *portp)
87{
88 return (unsigned short)le16_to_cpu(*(volatile unsigned short *)portp);
89}
90
91static inline void _ne_insb(void *portp, void *addr, unsigned long count)
92{
93 unsigned char *buf = (unsigned char *)addr;
94
95 while (count--)
96 *buf++ = _ne_inb(portp);
97}
98
99static inline void _ne_outb(unsigned char b, void *portp)
100{
101 *(volatile unsigned char *)portp = b;
102}
103
104static inline void _ne_outw(unsigned short w, void *portp)
105{
106 *(volatile unsigned short *)portp = cpu_to_le16(w);
107}
108
109unsigned char _inb(unsigned long port)
110{
111 if (port >= LAN_IOSTART && port < LAN_IOEND)
112 return _ne_inb(PORT2ADDR_NE(port));
113
114 return *(volatile unsigned char *)PORT2ADDR(port);
115}
116
117unsigned short _inw(unsigned long port)
118{
119 if (port >= LAN_IOSTART && port < LAN_IOEND)
120 return _ne_inw(PORT2ADDR_NE(port));
121
122 return *(volatile unsigned short *)PORT2ADDR(port);
123}
124
125unsigned long _inl(unsigned long port)
126{
127 return *(volatile unsigned long *)PORT2ADDR(port);
128}
129
130unsigned char _inb_p(unsigned long port)
131{
132 unsigned char v = _inb(port);
133 delay();
134 return (v);
135}
136
137unsigned short _inw_p(unsigned long port)
138{
139 unsigned short v = _inw(port);
140 delay();
141 return (v);
142}
143
144unsigned long _inl_p(unsigned long port)
145{
146 unsigned long v = _inl(port);
147 delay();
148 return (v);
149}
150
151void _outb(unsigned char b, unsigned long port)
152{
153 if (port >= LAN_IOSTART && port < LAN_IOEND)
154 _ne_outb(b, PORT2ADDR_NE(port));
155 else
156 *(volatile unsigned char *)PORT2ADDR(port) = b;
157}
158
159void _outw(unsigned short w, unsigned long port)
160{
161 if (port >= LAN_IOSTART && port < LAN_IOEND)
162 _ne_outw(w, PORT2ADDR_NE(port));
163 else
164 *(volatile unsigned short *)PORT2ADDR(port) = w;
165}
166
167void _outl(unsigned long l, unsigned long port)
168{
169 *(volatile unsigned long *)PORT2ADDR(port) = l;
170}
171
172void _outb_p(unsigned char b, unsigned long port)
173{
174 _outb(b, port);
175 delay();
176}
177
178void _outw_p(unsigned short w, unsigned long port)
179{
180 _outw(w, port);
181 delay();
182}
183
184void _outl_p(unsigned long l, unsigned long port)
185{
186 _outl(l, port);
187 delay();
188}
189
190void _insb(unsigned int port, void *addr, unsigned long count)
191{
192 if (port >= LAN_IOSTART && port < LAN_IOEND)
193 _ne_insb(PORT2ADDR_NE(port), addr, count);
194 else {
195 unsigned char *buf = addr;
196 unsigned char *portp = PORT2ADDR(port);
197 while (count--)
198 *buf++ = *(volatile unsigned char *)portp;
199 }
200}
201
202void _insw(unsigned int port, void *addr, unsigned long count)
203{
204 unsigned short *buf = addr;
205 unsigned short *portp;
206
207 if (port >= LAN_IOSTART && port < LAN_IOEND) {
208 /*
209 * This portion is only used by smc91111.c to read data
210 * from the DATA_REG. Do not swap the data.
211 */
212 portp = PORT2ADDR_NE(port);
213 while (count--)
214 *buf++ = *(volatile unsigned short *)portp;
215#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_CFC)
216 } else if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) {
217 pcc_ioread_word(9, port, (void *)addr, sizeof(unsigned short),
218 count, 1);
219#endif
220#if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC)
221 } else if ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) {
222 portp = __port2addr_ata(port);
223 while (count--)
224 *buf++ = *(volatile unsigned short *)portp;
225#endif
226 } else {
227 portp = PORT2ADDR(port);
228 while (count--)
229 *buf++ = *(volatile unsigned short *)portp;
230 }
231}
232
233void _insl(unsigned int port, void *addr, unsigned long count)
234{
235 unsigned long *buf = addr;
236 unsigned long *portp;
237
238 portp = PORT2ADDR(port);
239 while (count--)
240 *buf++ = *(volatile unsigned long *)portp;
241}
242
243void _outsb(unsigned int port, const void *addr, unsigned long count)
244{
245 const unsigned char *buf = addr;
246 unsigned char *portp;
247
248 if (port >= LAN_IOSTART && port < LAN_IOEND) {
249 portp = PORT2ADDR_NE(port);
250 while (count--)
251 _ne_outb(*buf++, portp);
252 } else {
253 portp = PORT2ADDR(port);
254 while (count--)
255 *(volatile unsigned char *)portp = *buf++;
256 }
257}
258
259void _outsw(unsigned int port, const void *addr, unsigned long count)
260{
261 const unsigned short *buf = addr;
262 unsigned short *portp;
263
264 if (port >= LAN_IOSTART && port < LAN_IOEND) {
265 /*
266 * This portion is only used by smc91111.c to write data
267 * into the DATA_REG. Do not swap the data.
268 */
269 portp = PORT2ADDR_NE(port);
270 while (count--)
271 *(volatile unsigned short *)portp = *buf++;
272#if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC)
273 } else if ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) {
274 portp = __port2addr_ata(port);
275 while (count--)
276 *(volatile unsigned short *)portp = *buf++;
277#endif
278#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_CFC)
279 } else if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) {
280 pcc_iowrite_word(9, port, (void *)addr, sizeof(unsigned short),
281 count, 1);
282#endif
283 } else {
284 portp = PORT2ADDR(port);
285 while (count--)
286 *(volatile unsigned short *)portp = *buf++;
287 }
288}
289
290void _outsl(unsigned int port, const void *addr, unsigned long count)
291{
292 const unsigned long *buf = addr;
293 unsigned char *portp;
294
295 portp = PORT2ADDR(port);
296 while (count--)
297 *(volatile unsigned long *)portp = *buf++;
298}
diff --git a/arch/m32r/kernel/io_m32700ut.c b/arch/m32r/kernel/io_m32700ut.c
index eda9f963c1eb..939932d6cc00 100644
--- a/arch/m32r/kernel/io_m32700ut.c
+++ b/arch/m32r/kernel/io_m32700ut.c
@@ -36,7 +36,7 @@ extern void pcc_iowrite_word(int, unsigned long, void *, size_t, size_t, int);
36 36
37static inline void *_port2addr(unsigned long port) 37static inline void *_port2addr(unsigned long port)
38{ 38{
39 return (void *)(port + NONCACHE_OFFSET); 39 return (void *)(port | NONCACHE_OFFSET);
40} 40}
41 41
42#if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC) 42#if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC)
@@ -45,15 +45,15 @@ static inline void *__port2addr_ata(unsigned long port)
45 static int dummy_reg; 45 static int dummy_reg;
46 46
47 switch (port) { 47 switch (port) {
48 case 0x1f0: return (void *)0xac002000; 48 case 0x1f0: return (void *)(0x0c002000 | NONCACHE_OFFSET);
49 case 0x1f1: return (void *)0xac012800; 49 case 0x1f1: return (void *)(0x0c012800 | NONCACHE_OFFSET);
50 case 0x1f2: return (void *)0xac012002; 50 case 0x1f2: return (void *)(0x0c012002 | NONCACHE_OFFSET);
51 case 0x1f3: return (void *)0xac012802; 51 case 0x1f3: return (void *)(0x0c012802 | NONCACHE_OFFSET);
52 case 0x1f4: return (void *)0xac012004; 52 case 0x1f4: return (void *)(0x0c012004 | NONCACHE_OFFSET);
53 case 0x1f5: return (void *)0xac012804; 53 case 0x1f5: return (void *)(0x0c012804 | NONCACHE_OFFSET);
54 case 0x1f6: return (void *)0xac012006; 54 case 0x1f6: return (void *)(0x0c012006 | NONCACHE_OFFSET);
55 case 0x1f7: return (void *)0xac012806; 55 case 0x1f7: return (void *)(0x0c012806 | NONCACHE_OFFSET);
56 case 0x3f6: return (void *)0xac01200e; 56 case 0x3f6: return (void *)(0x0c01200e | NONCACHE_OFFSET);
57 default: return (void *)&dummy_reg; 57 default: return (void *)&dummy_reg;
58 } 58 }
59} 59}
@@ -64,8 +64,8 @@ static inline void *__port2addr_ata(unsigned long port)
64 * from 0x10000000 to 0x13ffffff on physical address. 64 * from 0x10000000 to 0x13ffffff on physical address.
65 * The base address of LAN controller(LAN91C111) is 0x300. 65 * The base address of LAN controller(LAN91C111) is 0x300.
66 */ 66 */
67#define LAN_IOSTART 0xa0000300 67#define LAN_IOSTART (0x300 | NONCACHE_OFFSET)
68#define LAN_IOEND 0xa0000320 68#define LAN_IOEND (0x320 | NONCACHE_OFFSET)
69static inline void *_port2addr_ne(unsigned long port) 69static inline void *_port2addr_ne(unsigned long port)
70{ 70{
71 return (void *)(port + 0x10000000); 71 return (void *)(port + 0x10000000);
diff --git a/arch/m32r/kernel/io_mappi.c b/arch/m32r/kernel/io_mappi.c
index 3c3da042fbd1..a662b537c5ba 100644
--- a/arch/m32r/kernel/io_mappi.c
+++ b/arch/m32r/kernel/io_mappi.c
@@ -31,7 +31,7 @@ extern void pcc_iowrite(int, unsigned long, void *, size_t, size_t, int);
31 31
32static inline void *_port2addr(unsigned long port) 32static inline void *_port2addr(unsigned long port)
33{ 33{
34 return (void *)(port | (NONCACHE_OFFSET)); 34 return (void *)(port | NONCACHE_OFFSET);
35} 35}
36 36
37static inline void *_port2addr_ne(unsigned long port) 37static inline void *_port2addr_ne(unsigned long port)
diff --git a/arch/m32r/kernel/io_mappi2.c b/arch/m32r/kernel/io_mappi2.c
index df3c729cb3e0..e72d725606af 100644
--- a/arch/m32r/kernel/io_mappi2.c
+++ b/arch/m32r/kernel/io_mappi2.c
@@ -33,7 +33,7 @@ extern void pcc_iowrite_word(int, unsigned long, void *, size_t, size_t, int);
33 33
34static inline void *_port2addr(unsigned long port) 34static inline void *_port2addr(unsigned long port)
35{ 35{
36 return (void *)(port | (NONCACHE_OFFSET)); 36 return (void *)(port | NONCACHE_OFFSET);
37} 37}
38 38
39#if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC) 39#if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC)
@@ -42,22 +42,22 @@ static inline void *__port2addr_ata(unsigned long port)
42 static int dummy_reg; 42 static int dummy_reg;
43 43
44 switch (port) { 44 switch (port) {
45 case 0x1f0: return (void *)0xac002000; 45 case 0x1f0: return (void *)(0x0c002000 | NONCACHE_OFFSET);
46 case 0x1f1: return (void *)0xac012800; 46 case 0x1f1: return (void *)(0x0c012800 | NONCACHE_OFFSET);
47 case 0x1f2: return (void *)0xac012002; 47 case 0x1f2: return (void *)(0x0c012002 | NONCACHE_OFFSET);
48 case 0x1f3: return (void *)0xac012802; 48 case 0x1f3: return (void *)(0x0c012802 | NONCACHE_OFFSET);
49 case 0x1f4: return (void *)0xac012004; 49 case 0x1f4: return (void *)(0x0c012004 | NONCACHE_OFFSET);
50 case 0x1f5: return (void *)0xac012804; 50 case 0x1f5: return (void *)(0x0c012804 | NONCACHE_OFFSET);
51 case 0x1f6: return (void *)0xac012006; 51 case 0x1f6: return (void *)(0x0c012006 | NONCACHE_OFFSET);
52 case 0x1f7: return (void *)0xac012806; 52 case 0x1f7: return (void *)(0x0c012806 | NONCACHE_OFFSET);
53 case 0x3f6: return (void *)0xac01200e; 53 case 0x3f6: return (void *)(0x0c01200e | NONCACHE_OFFSET);
54 default: return (void *)&dummy_reg; 54 default: return (void *)&dummy_reg;
55 } 55 }
56} 56}
57#endif 57#endif
58 58
59#define LAN_IOSTART 0xa0000300 59#define LAN_IOSTART (0x300 | NONCACHE_OFFSET)
60#define LAN_IOEND 0xa0000320 60#define LAN_IOEND (0x320 | NONCACHE_OFFSET)
61#ifdef CONFIG_CHIP_OPSP 61#ifdef CONFIG_CHIP_OPSP
62static inline void *_port2addr_ne(unsigned long port) 62static inline void *_port2addr_ne(unsigned long port)
63{ 63{
diff --git a/arch/m32r/kernel/io_mappi3.c b/arch/m32r/kernel/io_mappi3.c
index f80321a58764..ed6da930bc64 100644
--- a/arch/m32r/kernel/io_mappi3.c
+++ b/arch/m32r/kernel/io_mappi3.c
@@ -33,7 +33,7 @@ extern void pcc_iowrite_word(int, unsigned long, void *, size_t, size_t, int);
33 33
34static inline void *_port2addr(unsigned long port) 34static inline void *_port2addr(unsigned long port)
35{ 35{
36 return (void *)(port + NONCACHE_OFFSET); 36 return (void *)(port | NONCACHE_OFFSET);
37} 37}
38 38
39#if defined(CONFIG_IDE) 39#if defined(CONFIG_IDE)
@@ -43,33 +43,42 @@ static inline void *__port2addr_ata(unsigned long port)
43 43
44 switch (port) { 44 switch (port) {
45 /* IDE0 CF */ 45 /* IDE0 CF */
46 case 0x1f0: return (void *)0xb4002000; 46 case 0x1f0: return (void *)(0x14002000 | NONCACHE_OFFSET);
47 case 0x1f1: return (void *)0xb4012800; 47 case 0x1f1: return (void *)(0x14012800 | NONCACHE_OFFSET);
48 case 0x1f2: return (void *)0xb4012002; 48 case 0x1f2: return (void *)(0x14012002 | NONCACHE_OFFSET);
49 case 0x1f3: return (void *)0xb4012802; 49 case 0x1f3: return (void *)(0x14012802 | NONCACHE_OFFSET);
50 case 0x1f4: return (void *)0xb4012004; 50 case 0x1f4: return (void *)(0x14012004 | NONCACHE_OFFSET);
51 case 0x1f5: return (void *)0xb4012804; 51 case 0x1f5: return (void *)(0x14012804 | NONCACHE_OFFSET);
52 case 0x1f6: return (void *)0xb4012006; 52 case 0x1f6: return (void *)(0x14012006 | NONCACHE_OFFSET);
53 case 0x1f7: return (void *)0xb4012806; 53 case 0x1f7: return (void *)(0x14012806 | NONCACHE_OFFSET);
54 case 0x3f6: return (void *)0xb401200e; 54 case 0x3f6: return (void *)(0x1401200e | NONCACHE_OFFSET);
55 /* IDE1 IDE */ 55 /* IDE1 IDE */
56 case 0x170: return (void *)0xb4810000; /* Data 16bit */ 56 case 0x170: /* Data 16bit */
57 case 0x171: return (void *)0xb4810002; /* Features / Error */ 57 return (void *)(0x14810000 | NONCACHE_OFFSET);
58 case 0x172: return (void *)0xb4810004; /* Sector count */ 58 case 0x171: /* Features / Error */
59 case 0x173: return (void *)0xb4810006; /* Sector number */ 59 return (void *)(0x14810002 | NONCACHE_OFFSET);
60 case 0x174: return (void *)0xb4810008; /* Cylinder low */ 60 case 0x172: /* Sector count */
61 case 0x175: return (void *)0xb481000a; /* Cylinder high */ 61 return (void *)(0x14810004 | NONCACHE_OFFSET);
62 case 0x176: return (void *)0xb481000c; /* Device head */ 62 case 0x173: /* Sector number */
63 case 0x177: return (void *)0xb481000e; /* Command */ 63 return (void *)(0x14810006 | NONCACHE_OFFSET);
64 case 0x376: return (void *)0xb480800c; /* Device control / Alt status */ 64 case 0x174: /* Cylinder low */
65 return (void *)(0x14810008 | NONCACHE_OFFSET);
66 case 0x175: /* Cylinder high */
67 return (void *)(0x1481000a | NONCACHE_OFFSET);
68 case 0x176: /* Device head */
69 return (void *)(0x1481000c | NONCACHE_OFFSET);
70 case 0x177: /* Command */
71 return (void *)(0x1481000e | NONCACHE_OFFSET);
72 case 0x376: /* Device control / Alt status */
73 return (void *)(0x1480800c | NONCACHE_OFFSET);
65 74
66 default: return (void *)&dummy_reg; 75 default: return (void *)&dummy_reg;
67 } 76 }
68} 77}
69#endif 78#endif
70 79
71#define LAN_IOSTART 0xa0000300 80#define LAN_IOSTART (0x300 | NONCACHE_OFFSET)
72#define LAN_IOEND 0xa0000320 81#define LAN_IOEND (0x320 | NONCACHE_OFFSET)
73static inline void *_port2addr_ne(unsigned long port) 82static inline void *_port2addr_ne(unsigned long port)
74{ 83{
75 return (void *)(port + 0x10000000); 84 return (void *)(port + 0x10000000);
diff --git a/arch/m32r/kernel/io_oaks32r.c b/arch/m32r/kernel/io_oaks32r.c
index 8be323931e4a..910dd131c227 100644
--- a/arch/m32r/kernel/io_oaks32r.c
+++ b/arch/m32r/kernel/io_oaks32r.c
@@ -16,7 +16,7 @@
16 16
17static inline void *_port2addr(unsigned long port) 17static inline void *_port2addr(unsigned long port)
18{ 18{
19 return (void *)(port | (NONCACHE_OFFSET)); 19 return (void *)(port | NONCACHE_OFFSET);
20} 20}
21 21
22static inline void *_port2addr_ne(unsigned long port) 22static inline void *_port2addr_ne(unsigned long port)
diff --git a/arch/m32r/kernel/io_opsput.c b/arch/m32r/kernel/io_opsput.c
index 4793bd18e115..bec69297db3c 100644
--- a/arch/m32r/kernel/io_opsput.c
+++ b/arch/m32r/kernel/io_opsput.c
@@ -36,7 +36,7 @@ extern void pcc_iowrite_word(int, unsigned long, void *, size_t, size_t, int);
36 36
37static inline void *_port2addr(unsigned long port) 37static inline void *_port2addr(unsigned long port)
38{ 38{
39 return (void *)(port | (NONCACHE_OFFSET)); 39 return (void *)(port | NONCACHE_OFFSET);
40} 40}
41 41
42/* 42/*
@@ -44,8 +44,8 @@ static inline void *_port2addr(unsigned long port)
44 * from 0x10000000 to 0x13ffffff on physical address. 44 * from 0x10000000 to 0x13ffffff on physical address.
45 * The base address of LAN controller(LAN91C111) is 0x300. 45 * The base address of LAN controller(LAN91C111) is 0x300.
46 */ 46 */
47#define LAN_IOSTART 0xa0000300 47#define LAN_IOSTART (0x300 | NONCACHE_OFFSET)
48#define LAN_IOEND 0xa0000320 48#define LAN_IOEND (0x320 | NONCACHE_OFFSET)
49static inline void *_port2addr_ne(unsigned long port) 49static inline void *_port2addr_ne(unsigned long port)
50{ 50{
51 return (void *)(port + 0x10000000); 51 return (void *)(port + 0x10000000);
diff --git a/arch/m32r/kernel/setup.c b/arch/m32r/kernel/setup.c
index f722ec8eb021..c2e4dccf0112 100644
--- a/arch/m32r/kernel/setup.c
+++ b/arch/m32r/kernel/setup.c
@@ -320,6 +320,9 @@ static int show_cpuinfo(struct seq_file *m, void *v)
320#elif defined(CONFIG_CHIP_MP) 320#elif defined(CONFIG_CHIP_MP)
321 seq_printf(m, "cpu family\t: M32R-MP\n" 321 seq_printf(m, "cpu family\t: M32R-MP\n"
322 "cache size\t: I-xxKB/D-xxKB\n"); 322 "cache size\t: I-xxKB/D-xxKB\n");
323#elif defined(CONFIG_CHIP_M32104)
324 seq_printf(m,"cpu family\t: M32104\n"
325 "cache size\t: I-8KB/D-8KB\n");
323#else 326#else
324 seq_printf(m, "cpu family\t: Unknown\n"); 327 seq_printf(m, "cpu family\t: Unknown\n");
325#endif 328#endif
@@ -340,6 +343,8 @@ static int show_cpuinfo(struct seq_file *m, void *v)
340 seq_printf(m, "Machine\t\t: uServer\n"); 343 seq_printf(m, "Machine\t\t: uServer\n");
341#elif defined(CONFIG_PLAT_OAKS32R) 344#elif defined(CONFIG_PLAT_OAKS32R)
342 seq_printf(m, "Machine\t\t: OAKS32R\n"); 345 seq_printf(m, "Machine\t\t: OAKS32R\n");
346#elif defined(CONFIG_PLAT_M32104UT)
347 seq_printf(m, "Machine\t\t: M3T-M32104UT uT Engine board\n");
343#else 348#else
344 seq_printf(m, "Machine\t\t: Unknown\n"); 349 seq_printf(m, "Machine\t\t: Unknown\n");
345#endif 350#endif
@@ -389,7 +394,7 @@ unsigned long cpu_initialized __initdata = 0;
389 */ 394 */
390#if defined(CONFIG_CHIP_VDEC2) || defined(CONFIG_CHIP_XNUX2) \ 395#if defined(CONFIG_CHIP_VDEC2) || defined(CONFIG_CHIP_XNUX2) \
391 || defined(CONFIG_CHIP_M32700) || defined(CONFIG_CHIP_M32102) \ 396 || defined(CONFIG_CHIP_M32700) || defined(CONFIG_CHIP_M32102) \
392 || defined(CONFIG_CHIP_OPSP) 397 || defined(CONFIG_CHIP_OPSP) || defined(CONFIG_CHIP_M32104)
393void __init cpu_init (void) 398void __init cpu_init (void)
394{ 399{
395 int cpu_id = smp_processor_id(); 400 int cpu_id = smp_processor_id();
diff --git a/arch/m32r/kernel/setup_m32104ut.c b/arch/m32r/kernel/setup_m32104ut.c
new file mode 100644
index 000000000000..6328e1357a80
--- /dev/null
+++ b/arch/m32r/kernel/setup_m32104ut.c
@@ -0,0 +1,156 @@
1/*
2 * linux/arch/m32r/kernel/setup_m32104ut.c
3 *
4 * Setup routines for M32104UT Board
5 *
6 * Copyright (c) 2002-2005 Hiroyuki Kondo, Hirokazu Takata,
7 * Hitoshi Yamamoto, Mamoru Sakugawa,
8 * Naoto Sugai, Hayato Fujiwara
9 */
10
11#include <linux/config.h>
12#include <linux/irq.h>
13#include <linux/kernel.h>
14#include <linux/init.h>
15#include <linux/device.h>
16
17#include <asm/system.h>
18#include <asm/m32r.h>
19#include <asm/io.h>
20
21#define irq2port(x) (M32R_ICU_CR1_PORTL + ((x - 1) * sizeof(unsigned long)))
22
23icu_data_t icu_data[NR_IRQS];
24
25static void disable_m32104ut_irq(unsigned int irq)
26{
27 unsigned long port, data;
28
29 port = irq2port(irq);
30 data = icu_data[irq].icucr|M32R_ICUCR_ILEVEL7;
31 outl(data, port);
32}
33
34static void enable_m32104ut_irq(unsigned int irq)
35{
36 unsigned long port, data;
37
38 port = irq2port(irq);
39 data = icu_data[irq].icucr|M32R_ICUCR_IEN|M32R_ICUCR_ILEVEL6;
40 outl(data, port);
41}
42
43static void mask_and_ack_m32104ut(unsigned int irq)
44{
45 disable_m32104ut_irq(irq);
46}
47
48static void end_m32104ut_irq(unsigned int irq)
49{
50 enable_m32104ut_irq(irq);
51}
52
53static unsigned int startup_m32104ut_irq(unsigned int irq)
54{
55 enable_m32104ut_irq(irq);
56 return (0);
57}
58
59static void shutdown_m32104ut_irq(unsigned int irq)
60{
61 unsigned long port;
62
63 port = irq2port(irq);
64 outl(M32R_ICUCR_ILEVEL7, port);
65}
66
67static struct hw_interrupt_type m32104ut_irq_type =
68{
69 .typename = "M32104UT-IRQ",
70 .startup = startup_m32104ut_irq,
71 .shutdown = shutdown_m32104ut_irq,
72 .enable = enable_m32104ut_irq,
73 .disable = disable_m32104ut_irq,
74 .ack = mask_and_ack_m32104ut,
75 .end = end_m32104ut_irq
76};
77
78void __init init_IRQ(void)
79{
80 static int once = 0;
81
82 if (once)
83 return;
84 else
85 once++;
86
87#if defined(CONFIG_SMC91X)
88 /* INT#0: LAN controller on M32104UT-LAN (SMC91C111)*/
89 irq_desc[M32R_IRQ_INT0].status = IRQ_DISABLED;
90 irq_desc[M32R_IRQ_INT0].handler = &m32104ut_irq_type;
91 irq_desc[M32R_IRQ_INT0].action = 0;
92 irq_desc[M32R_IRQ_INT0].depth = 1;
93 icu_data[M32R_IRQ_INT0].icucr = M32R_ICUCR_IEN | M32R_ICUCR_ISMOD11; /* "H" level sense */
94 disable_m32104ut_irq(M32R_IRQ_INT0);
95#endif /* CONFIG_SMC91X */
96
97 /* MFT2 : system timer */
98 irq_desc[M32R_IRQ_MFT2].status = IRQ_DISABLED;
99 irq_desc[M32R_IRQ_MFT2].handler = &m32104ut_irq_type;
100 irq_desc[M32R_IRQ_MFT2].action = 0;
101 irq_desc[M32R_IRQ_MFT2].depth = 1;
102 icu_data[M32R_IRQ_MFT2].icucr = M32R_ICUCR_IEN;
103 disable_m32104ut_irq(M32R_IRQ_MFT2);
104
105#ifdef CONFIG_SERIAL_M32R_SIO
106 /* SIO0_R : uart receive data */
107 irq_desc[M32R_IRQ_SIO0_R].status = IRQ_DISABLED;
108 irq_desc[M32R_IRQ_SIO0_R].handler = &m32104ut_irq_type;
109 irq_desc[M32R_IRQ_SIO0_R].action = 0;
110 irq_desc[M32R_IRQ_SIO0_R].depth = 1;
111 icu_data[M32R_IRQ_SIO0_R].icucr = M32R_ICUCR_IEN;
112 disable_m32104ut_irq(M32R_IRQ_SIO0_R);
113
114 /* SIO0_S : uart send data */
115 irq_desc[M32R_IRQ_SIO0_S].status = IRQ_DISABLED;
116 irq_desc[M32R_IRQ_SIO0_S].handler = &m32104ut_irq_type;
117 irq_desc[M32R_IRQ_SIO0_S].action = 0;
118 irq_desc[M32R_IRQ_SIO0_S].depth = 1;
119 icu_data[M32R_IRQ_SIO0_S].icucr = M32R_ICUCR_IEN;
120 disable_m32104ut_irq(M32R_IRQ_SIO0_S);
121#endif /* CONFIG_SERIAL_M32R_SIO */
122}
123
124#if defined(CONFIG_SMC91X)
125
126#define LAN_IOSTART 0x300
127#define LAN_IOEND 0x320
128static struct resource smc91x_resources[] = {
129 [0] = {
130 .start = (LAN_IOSTART),
131 .end = (LAN_IOEND),
132 .flags = IORESOURCE_MEM,
133 },
134 [1] = {
135 .start = M32R_IRQ_INT0,
136 .end = M32R_IRQ_INT0,
137 .flags = IORESOURCE_IRQ,
138 }
139};
140
141static struct platform_device smc91x_device = {
142 .name = "smc91x",
143 .id = 0,
144 .num_resources = ARRAY_SIZE(smc91x_resources),
145 .resource = smc91x_resources,
146};
147#endif
148
149static int __init platform_init(void)
150{
151#if defined(CONFIG_SMC91X)
152 platform_device_register(&smc91x_device);
153#endif
154 return 0;
155}
156arch_initcall(platform_init);
diff --git a/arch/m32r/kernel/setup_m32700ut.c b/arch/m32r/kernel/setup_m32700ut.c
index cb76916b014d..fad1fc99bb27 100644
--- a/arch/m32r/kernel/setup_m32700ut.c
+++ b/arch/m32r/kernel/setup_m32700ut.c
@@ -26,15 +26,7 @@
26 */ 26 */
27#define irq2port(x) (M32R_ICU_CR1_PORTL + ((x - 1) * sizeof(unsigned long))) 27#define irq2port(x) (M32R_ICU_CR1_PORTL + ((x - 1) * sizeof(unsigned long)))
28 28
29#ifndef CONFIG_SMP
30typedef struct {
31 unsigned long icucr; /* ICU Control Register */
32} icu_data_t;
33static icu_data_t icu_data[M32700UT_NUM_CPU_IRQ];
34#else
35icu_data_t icu_data[M32700UT_NUM_CPU_IRQ]; 29icu_data_t icu_data[M32700UT_NUM_CPU_IRQ];
36#endif /* CONFIG_SMP */
37
38 30
39static void disable_m32700ut_irq(unsigned int irq) 31static void disable_m32700ut_irq(unsigned int irq)
40{ 32{
diff --git a/arch/m32r/kernel/setup_mappi.c b/arch/m32r/kernel/setup_mappi.c
index 501d798cf050..00f253209cb3 100644
--- a/arch/m32r/kernel/setup_mappi.c
+++ b/arch/m32r/kernel/setup_mappi.c
@@ -19,12 +19,6 @@
19 19
20#define irq2port(x) (M32R_ICU_CR1_PORTL + ((x - 1) * sizeof(unsigned long))) 20#define irq2port(x) (M32R_ICU_CR1_PORTL + ((x - 1) * sizeof(unsigned long)))
21 21
22#ifndef CONFIG_SMP
23typedef struct {
24 unsigned long icucr; /* ICU Control Register */
25} icu_data_t;
26#endif /* CONFIG_SMP */
27
28icu_data_t icu_data[NR_IRQS]; 22icu_data_t icu_data[NR_IRQS];
29 23
30static void disable_mappi_irq(unsigned int irq) 24static void disable_mappi_irq(unsigned int irq)
diff --git a/arch/m32r/kernel/setup_mappi2.c b/arch/m32r/kernel/setup_mappi2.c
index 7f2db5bfd626..eebc9d8b4e72 100644
--- a/arch/m32r/kernel/setup_mappi2.c
+++ b/arch/m32r/kernel/setup_mappi2.c
@@ -19,12 +19,6 @@
19 19
20#define irq2port(x) (M32R_ICU_CR1_PORTL + ((x - 1) * sizeof(unsigned long))) 20#define irq2port(x) (M32R_ICU_CR1_PORTL + ((x - 1) * sizeof(unsigned long)))
21 21
22#ifndef CONFIG_SMP
23typedef struct {
24 unsigned long icucr; /* ICU Control Register */
25} icu_data_t;
26#endif /* CONFIG_SMP */
27
28icu_data_t icu_data[NR_IRQS]; 22icu_data_t icu_data[NR_IRQS];
29 23
30static void disable_mappi2_irq(unsigned int irq) 24static void disable_mappi2_irq(unsigned int irq)
diff --git a/arch/m32r/kernel/setup_mappi3.c b/arch/m32r/kernel/setup_mappi3.c
index f6ecdf7f555c..d2ff021e2d3d 100644
--- a/arch/m32r/kernel/setup_mappi3.c
+++ b/arch/m32r/kernel/setup_mappi3.c
@@ -19,12 +19,6 @@
19 19
20#define irq2port(x) (M32R_ICU_CR1_PORTL + ((x - 1) * sizeof(unsigned long))) 20#define irq2port(x) (M32R_ICU_CR1_PORTL + ((x - 1) * sizeof(unsigned long)))
21 21
22#ifndef CONFIG_SMP
23typedef struct {
24 unsigned long icucr; /* ICU Control Register */
25} icu_data_t;
26#endif /* CONFIG_SMP */
27
28icu_data_t icu_data[NR_IRQS]; 22icu_data_t icu_data[NR_IRQS];
29 23
30static void disable_mappi3_irq(unsigned int irq) 24static void disable_mappi3_irq(unsigned int irq)
diff --git a/arch/m32r/kernel/setup_oaks32r.c b/arch/m32r/kernel/setup_oaks32r.c
index 45add5b76f19..0e9e63538c0f 100644
--- a/arch/m32r/kernel/setup_oaks32r.c
+++ b/arch/m32r/kernel/setup_oaks32r.c
@@ -18,12 +18,6 @@
18 18
19#define irq2port(x) (M32R_ICU_CR1_PORTL + ((x - 1) * sizeof(unsigned long))) 19#define irq2port(x) (M32R_ICU_CR1_PORTL + ((x - 1) * sizeof(unsigned long)))
20 20
21#ifndef CONFIG_SMP
22typedef struct {
23 unsigned long icucr; /* ICU Control Register */
24} icu_data_t;
25#endif /* CONFIG_SMP */
26
27icu_data_t icu_data[NR_IRQS]; 21icu_data_t icu_data[NR_IRQS];
28 22
29static void disable_oaks32r_irq(unsigned int irq) 23static void disable_oaks32r_irq(unsigned int irq)
diff --git a/arch/m32r/kernel/setup_opsput.c b/arch/m32r/kernel/setup_opsput.c
index 1fbb140854e7..548e8fc7949b 100644
--- a/arch/m32r/kernel/setup_opsput.c
+++ b/arch/m32r/kernel/setup_opsput.c
@@ -27,15 +27,7 @@
27 */ 27 */
28#define irq2port(x) (M32R_ICU_CR1_PORTL + ((x - 1) * sizeof(unsigned long))) 28#define irq2port(x) (M32R_ICU_CR1_PORTL + ((x - 1) * sizeof(unsigned long)))
29 29
30#ifndef CONFIG_SMP
31typedef struct {
32 unsigned long icucr; /* ICU Control Register */
33} icu_data_t;
34static icu_data_t icu_data[OPSPUT_NUM_CPU_IRQ];
35#else
36icu_data_t icu_data[OPSPUT_NUM_CPU_IRQ]; 30icu_data_t icu_data[OPSPUT_NUM_CPU_IRQ];
37#endif /* CONFIG_SMP */
38
39 31
40static void disable_opsput_irq(unsigned int irq) 32static void disable_opsput_irq(unsigned int irq)
41{ 33{
diff --git a/arch/m32r/kernel/setup_usrv.c b/arch/m32r/kernel/setup_usrv.c
index 634741bf9d35..64be659a23e7 100644
--- a/arch/m32r/kernel/setup_usrv.c
+++ b/arch/m32r/kernel/setup_usrv.c
@@ -18,12 +18,6 @@
18 18
19#define irq2port(x) (M32R_ICU_CR1_PORTL + ((x - 1) * sizeof(unsigned long))) 19#define irq2port(x) (M32R_ICU_CR1_PORTL + ((x - 1) * sizeof(unsigned long)))
20 20
21#if !defined(CONFIG_SMP)
22typedef struct {
23 unsigned long icucr; /* ICU Control Register */
24} icu_data_t;
25#endif /* CONFIG_SMP */
26
27icu_data_t icu_data[M32700UT_NUM_CPU_IRQ]; 21icu_data_t icu_data[M32700UT_NUM_CPU_IRQ];
28 22
29static void disable_mappi_irq(unsigned int irq) 23static void disable_mappi_irq(unsigned int irq)
diff --git a/arch/m32r/kernel/time.c b/arch/m32r/kernel/time.c
index 2ebce2063fea..b8e68b542302 100644
--- a/arch/m32r/kernel/time.c
+++ b/arch/m32r/kernel/time.c
@@ -57,7 +57,7 @@ static unsigned long do_gettimeoffset(void)
57 57
58#if defined(CONFIG_CHIP_M32102) || defined(CONFIG_CHIP_XNUX2) \ 58#if defined(CONFIG_CHIP_M32102) || defined(CONFIG_CHIP_XNUX2) \
59 || defined(CONFIG_CHIP_VDEC2) || defined(CONFIG_CHIP_M32700) \ 59 || defined(CONFIG_CHIP_VDEC2) || defined(CONFIG_CHIP_M32700) \
60 || defined(CONFIG_CHIP_OPSP) 60 || defined(CONFIG_CHIP_OPSP) || defined(CONFIG_CHIP_M32104)
61#ifndef CONFIG_SMP 61#ifndef CONFIG_SMP
62 62
63 unsigned long count; 63 unsigned long count;
@@ -268,7 +268,7 @@ void __init time_init(void)
268 268
269#if defined(CONFIG_CHIP_M32102) || defined(CONFIG_CHIP_XNUX2) \ 269#if defined(CONFIG_CHIP_M32102) || defined(CONFIG_CHIP_XNUX2) \
270 || defined(CONFIG_CHIP_VDEC2) || defined(CONFIG_CHIP_M32700) \ 270 || defined(CONFIG_CHIP_VDEC2) || defined(CONFIG_CHIP_M32700) \
271 || defined(CONFIG_CHIP_OPSP) 271 || defined(CONFIG_CHIP_OPSP) || defined(CONFIG_CHIP_M32104)
272 272
273 /* M32102 MFT setup */ 273 /* M32102 MFT setup */
274 setup_irq(M32R_IRQ_MFT2, &irq0); 274 setup_irq(M32R_IRQ_MFT2, &irq0);
diff --git a/arch/m32r/m32104ut/defconfig.m32104ut b/arch/m32r/m32104ut/defconfig.m32104ut
new file mode 100644
index 000000000000..454de336803a
--- /dev/null
+++ b/arch/m32r/m32104ut/defconfig.m32104ut
@@ -0,0 +1,657 @@
1#
2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.14
4# Wed Nov 9 16:04:51 2005
5#
6CONFIG_M32R=y
7# CONFIG_UID16 is not set
8CONFIG_GENERIC_ISA_DMA=y
9CONFIG_GENERIC_HARDIRQS=y
10CONFIG_GENERIC_IRQ_PROBE=y
11
12#
13# Code maturity level options
14#
15CONFIG_EXPERIMENTAL=y
16CONFIG_CLEAN_COMPILE=y
17CONFIG_BROKEN_ON_SMP=y
18CONFIG_INIT_ENV_ARG_LIMIT=32
19
20#
21# General setup
22#
23CONFIG_LOCALVERSION=""
24CONFIG_LOCALVERSION_AUTO=y
25# CONFIG_POSIX_MQUEUE is not set
26# CONFIG_BSD_PROCESS_ACCT is not set
27CONFIG_SYSCTL=y
28# CONFIG_AUDIT is not set
29CONFIG_HOTPLUG=y
30# CONFIG_KOBJECT_UEVENT is not set
31# CONFIG_IKCONFIG is not set
32CONFIG_INITRAMFS_SOURCE=""
33CONFIG_EMBEDDED=y
34# CONFIG_KALLSYMS is not set
35CONFIG_PRINTK=y
36CONFIG_BUG=y
37CONFIG_BASE_FULL=y
38# CONFIG_FUTEX is not set
39# CONFIG_EPOLL is not set
40# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
41CONFIG_CC_ALIGN_FUNCTIONS=0
42CONFIG_CC_ALIGN_LABELS=0
43CONFIG_CC_ALIGN_LOOPS=0
44CONFIG_CC_ALIGN_JUMPS=0
45CONFIG_TINY_SHMEM=y
46CONFIG_BASE_SMALL=0
47
48#
49# Loadable module support
50#
51# CONFIG_MODULES is not set
52
53#
54# Processor type and features
55#
56# CONFIG_PLAT_MAPPI is not set
57# CONFIG_PLAT_USRV is not set
58# CONFIG_PLAT_M32700UT is not set
59# CONFIG_PLAT_OPSPUT is not set
60# CONFIG_PLAT_OAKS32R is not set
61# CONFIG_PLAT_MAPPI2 is not set
62# CONFIG_PLAT_MAPPI3 is not set
63CONFIG_PLAT_M32104UT=y
64# CONFIG_CHIP_M32700 is not set
65# CONFIG_CHIP_M32102 is not set
66CONFIG_CHIP_M32104=y
67# CONFIG_CHIP_VDEC2 is not set
68# CONFIG_CHIP_OPSP is not set
69CONFIG_ISA_M32R=y
70CONFIG_BUS_CLOCK=54000000
71CONFIG_TIMER_DIVIDE=128
72# CONFIG_CPU_LITTLE_ENDIAN is not set
73CONFIG_MEMORY_START=04000000
74CONFIG_MEMORY_SIZE=01000000
75CONFIG_NOHIGHMEM=y
76# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
77CONFIG_SELECT_MEMORY_MODEL=y
78CONFIG_FLATMEM_MANUAL=y
79# CONFIG_DISCONTIGMEM_MANUAL is not set
80# CONFIG_SPARSEMEM_MANUAL is not set
81CONFIG_FLATMEM=y
82CONFIG_FLAT_NODE_MEM_MAP=y
83# CONFIG_SPARSEMEM_STATIC is not set
84CONFIG_RWSEM_GENERIC_SPINLOCK=y
85# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
86CONFIG_GENERIC_CALIBRATE_DELAY=y
87# CONFIG_PREEMPT is not set
88# CONFIG_SMP is not set
89
90#
91# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
92#
93# CONFIG_ISA is not set
94
95#
96# PCCARD (PCMCIA/CardBus) support
97#
98CONFIG_PCCARD=y
99# CONFIG_PCMCIA_DEBUG is not set
100CONFIG_PCMCIA=y
101CONFIG_PCMCIA_LOAD_CIS=y
102CONFIG_PCMCIA_IOCTL=y
103
104#
105# PC-card bridges
106#
107
108#
109# PCI Hotplug Support
110#
111
112#
113# Executable file formats
114#
115CONFIG_BINFMT_FLAT=y
116# CONFIG_BINFMT_ZFLAT is not set
117# CONFIG_BINFMT_SHARED_FLAT is not set
118# CONFIG_BINFMT_MISC is not set
119
120#
121# Networking
122#
123CONFIG_NET=y
124
125#
126# Networking options
127#
128# CONFIG_PACKET is not set
129CONFIG_UNIX=y
130# CONFIG_NET_KEY is not set
131CONFIG_INET=y
132# CONFIG_IP_MULTICAST is not set
133# CONFIG_IP_ADVANCED_ROUTER is not set
134CONFIG_IP_FIB_HASH=y
135CONFIG_IP_PNP=y
136CONFIG_IP_PNP_DHCP=y
137# CONFIG_IP_PNP_BOOTP is not set
138# CONFIG_IP_PNP_RARP is not set
139# CONFIG_NET_IPIP is not set
140# CONFIG_NET_IPGRE is not set
141# CONFIG_ARPD is not set
142# CONFIG_SYN_COOKIES is not set
143# CONFIG_INET_AH is not set
144# CONFIG_INET_ESP is not set
145# CONFIG_INET_IPCOMP is not set
146# CONFIG_INET_TUNNEL is not set
147CONFIG_INET_DIAG=y
148CONFIG_INET_TCP_DIAG=y
149# CONFIG_TCP_CONG_ADVANCED is not set
150CONFIG_TCP_CONG_BIC=y
151# CONFIG_IPV6 is not set
152# CONFIG_NETFILTER is not set
153
154#
155# DCCP Configuration (EXPERIMENTAL)
156#
157# CONFIG_IP_DCCP is not set
158
159#
160# SCTP Configuration (EXPERIMENTAL)
161#
162# CONFIG_IP_SCTP is not set
163# CONFIG_ATM is not set
164# CONFIG_BRIDGE is not set
165# CONFIG_VLAN_8021Q is not set
166# CONFIG_DECNET is not set
167# CONFIG_LLC2 is not set
168# CONFIG_IPX is not set
169# CONFIG_ATALK is not set
170# CONFIG_X25 is not set
171# CONFIG_LAPB is not set
172# CONFIG_NET_DIVERT is not set
173# CONFIG_ECONET is not set
174# CONFIG_WAN_ROUTER is not set
175# CONFIG_NET_SCHED is not set
176# CONFIG_NET_CLS_ROUTE is not set
177
178#
179# Network testing
180#
181# CONFIG_NET_PKTGEN is not set
182# CONFIG_HAMRADIO is not set
183# CONFIG_IRDA is not set
184# CONFIG_BT is not set
185# CONFIG_IEEE80211 is not set
186
187#
188# Device Drivers
189#
190
191#
192# Generic Driver Options
193#
194CONFIG_STANDALONE=y
195CONFIG_PREVENT_FIRMWARE_BUILD=y
196CONFIG_FW_LOADER=y
197# CONFIG_DEBUG_DRIVER is not set
198
199#
200# Connector - unified userspace <-> kernelspace linker
201#
202# CONFIG_CONNECTOR is not set
203
204#
205# Memory Technology Devices (MTD)
206#
207# CONFIG_MTD is not set
208
209#
210# Parallel port support
211#
212# CONFIG_PARPORT is not set
213
214#
215# Plug and Play support
216#
217
218#
219# Block devices
220#
221# CONFIG_BLK_DEV_COW_COMMON is not set
222CONFIG_BLK_DEV_LOOP=y
223# CONFIG_BLK_DEV_CRYPTOLOOP is not set
224CONFIG_BLK_DEV_NBD=y
225CONFIG_BLK_DEV_RAM=y
226CONFIG_BLK_DEV_RAM_COUNT=16
227CONFIG_BLK_DEV_RAM_SIZE=4096
228CONFIG_BLK_DEV_INITRD=y
229# CONFIG_CDROM_PKTCDVD is not set
230
231#
232# IO Schedulers
233#
234CONFIG_IOSCHED_NOOP=y
235# CONFIG_IOSCHED_AS is not set
236# CONFIG_IOSCHED_DEADLINE is not set
237# CONFIG_IOSCHED_CFQ is not set
238# CONFIG_ATA_OVER_ETH is not set
239
240#
241# ATA/ATAPI/MFM/RLL support
242#
243# CONFIG_IDE is not set
244
245#
246# SCSI device support
247#
248# CONFIG_RAID_ATTRS is not set
249# CONFIG_SCSI is not set
250
251#
252# Multi-device support (RAID and LVM)
253#
254# CONFIG_MD is not set
255
256#
257# Fusion MPT device support
258#
259# CONFIG_FUSION is not set
260
261#
262# IEEE 1394 (FireWire) support
263#
264
265#
266# I2O device support
267#
268
269#
270# Network device support
271#
272CONFIG_NETDEVICES=y
273CONFIG_DUMMY=y
274# CONFIG_BONDING is not set
275# CONFIG_EQUALIZER is not set
276# CONFIG_TUN is not set
277
278#
279# PHY device support
280#
281# CONFIG_PHYLIB is not set
282
283#
284# Ethernet (10 or 100Mbit)
285#
286CONFIG_NET_ETHERNET=y
287CONFIG_MII=y
288CONFIG_SMC91X=y
289# CONFIG_NE2000 is not set
290
291#
292# Ethernet (1000 Mbit)
293#
294
295#
296# Ethernet (10000 Mbit)
297#
298
299#
300# Token Ring devices
301#
302
303#
304# Wireless LAN (non-hamradio)
305#
306# CONFIG_NET_RADIO is not set
307
308#
309# PCMCIA network device support
310#
311# CONFIG_NET_PCMCIA is not set
312
313#
314# Wan interfaces
315#
316# CONFIG_WAN is not set
317# CONFIG_PPP is not set
318# CONFIG_SLIP is not set
319# CONFIG_SHAPER is not set
320# CONFIG_NETCONSOLE is not set
321# CONFIG_NETPOLL is not set
322# CONFIG_NET_POLL_CONTROLLER is not set
323
324#
325# ISDN subsystem
326#
327# CONFIG_ISDN is not set
328
329#
330# Telephony Support
331#
332# CONFIG_PHONE is not set
333
334#
335# Input device support
336#
337# CONFIG_INPUT is not set
338
339#
340# Hardware I/O ports
341#
342# CONFIG_SERIO is not set
343# CONFIG_GAMEPORT is not set
344
345#
346# Character devices
347#
348# CONFIG_VT is not set
349# CONFIG_SERIAL_NONSTANDARD is not set
350
351#
352# Serial drivers
353#
354# CONFIG_SERIAL_8250 is not set
355
356#
357# Non-8250 serial port support
358#
359CONFIG_SERIAL_CORE=y
360CONFIG_SERIAL_CORE_CONSOLE=y
361CONFIG_SERIAL_M32R_SIO=y
362CONFIG_SERIAL_M32R_SIO_CONSOLE=y
363CONFIG_UNIX98_PTYS=y
364CONFIG_LEGACY_PTYS=y
365CONFIG_LEGACY_PTY_COUNT=256
366
367#
368# IPMI
369#
370# CONFIG_IPMI_HANDLER is not set
371
372#
373# Watchdog Cards
374#
375CONFIG_WATCHDOG=y
376# CONFIG_WATCHDOG_NOWAYOUT is not set
377
378#
379# Watchdog Device Drivers
380#
381CONFIG_SOFT_WATCHDOG=y
382# CONFIG_RTC is not set
383# CONFIG_DTLK is not set
384# CONFIG_R3964 is not set
385
386#
387# Ftape, the floppy tape device driver
388#
389
390#
391# PCMCIA character devices
392#
393# CONFIG_SYNCLINK_CS is not set
394# CONFIG_RAW_DRIVER is not set
395
396#
397# TPM devices
398#
399
400#
401# I2C support
402#
403# CONFIG_I2C is not set
404
405#
406# Dallas's 1-wire bus
407#
408# CONFIG_W1 is not set
409
410#
411# Hardware Monitoring support
412#
413# CONFIG_HWMON is not set
414# CONFIG_HWMON_VID is not set
415
416#
417# Misc devices
418#
419
420#
421# Multimedia Capabilities Port drivers
422#
423
424#
425# Multimedia devices
426#
427# CONFIG_VIDEO_DEV is not set
428
429#
430# Digital Video Broadcasting Devices
431#
432# CONFIG_DVB is not set
433
434#
435# Graphics support
436#
437# CONFIG_FB is not set
438
439#
440# Sound
441#
442# CONFIG_SOUND is not set
443
444#
445# USB support
446#
447# CONFIG_USB_ARCH_HAS_HCD is not set
448# CONFIG_USB_ARCH_HAS_OHCI is not set
449
450#
451# USB Gadget Support
452#
453# CONFIG_USB_GADGET is not set
454
455#
456# MMC/SD Card support
457#
458# CONFIG_MMC is not set
459
460#
461# InfiniBand support
462#
463
464#
465# SN Devices
466#
467
468#
469# File systems
470#
471CONFIG_EXT2_FS=y
472# CONFIG_EXT2_FS_XATTR is not set
473# CONFIG_EXT2_FS_XIP is not set
474CONFIG_EXT3_FS=y
475CONFIG_EXT3_FS_XATTR=y
476CONFIG_EXT3_FS_POSIX_ACL=y
477# CONFIG_EXT3_FS_SECURITY is not set
478CONFIG_JBD=y
479# CONFIG_JBD_DEBUG is not set
480CONFIG_FS_MBCACHE=y
481# CONFIG_REISERFS_FS is not set
482# CONFIG_JFS_FS is not set
483CONFIG_FS_POSIX_ACL=y
484# CONFIG_XFS_FS is not set
485# CONFIG_MINIX_FS is not set
486# CONFIG_ROMFS_FS is not set
487# CONFIG_INOTIFY is not set
488# CONFIG_QUOTA is not set
489CONFIG_DNOTIFY=y
490# CONFIG_AUTOFS_FS is not set
491# CONFIG_AUTOFS4_FS is not set
492# CONFIG_FUSE_FS is not set
493
494#
495# CD-ROM/DVD Filesystems
496#
497# CONFIG_ISO9660_FS is not set
498# CONFIG_UDF_FS is not set
499
500#
501# DOS/FAT/NT Filesystems
502#
503CONFIG_FAT_FS=y
504CONFIG_MSDOS_FS=y
505CONFIG_VFAT_FS=y
506CONFIG_FAT_DEFAULT_CODEPAGE=932
507CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
508# CONFIG_NTFS_FS is not set
509
510#
511# Pseudo filesystems
512#
513CONFIG_PROC_FS=y
514CONFIG_SYSFS=y
515CONFIG_TMPFS=y
516# CONFIG_HUGETLB_PAGE is not set
517CONFIG_RAMFS=y
518# CONFIG_RELAYFS_FS is not set
519
520#
521# Miscellaneous filesystems
522#
523# CONFIG_ADFS_FS is not set
524# CONFIG_AFFS_FS is not set
525# CONFIG_HFS_FS is not set
526# CONFIG_HFSPLUS_FS is not set
527# CONFIG_BEFS_FS is not set
528# CONFIG_BFS_FS is not set
529# CONFIG_EFS_FS is not set
530CONFIG_CRAMFS=y
531# CONFIG_VXFS_FS is not set
532# CONFIG_HPFS_FS is not set
533# CONFIG_QNX4FS_FS is not set
534# CONFIG_SYSV_FS is not set
535# CONFIG_UFS_FS is not set
536
537#
538# Network File Systems
539#
540CONFIG_NFS_FS=y
541CONFIG_NFS_V3=y
542# CONFIG_NFS_V3_ACL is not set
543# CONFIG_NFS_V4 is not set
544# CONFIG_NFS_DIRECTIO is not set
545# CONFIG_NFSD is not set
546CONFIG_ROOT_NFS=y
547CONFIG_LOCKD=y
548CONFIG_LOCKD_V4=y
549CONFIG_NFS_COMMON=y
550CONFIG_SUNRPC=y
551# CONFIG_RPCSEC_GSS_KRB5 is not set
552# CONFIG_RPCSEC_GSS_SPKM3 is not set
553# CONFIG_SMB_FS is not set
554# CONFIG_CIFS is not set
555# CONFIG_NCP_FS is not set
556# CONFIG_CODA_FS is not set
557# CONFIG_AFS_FS is not set
558# CONFIG_9P_FS is not set
559
560#
561# Partition Types
562#
563# CONFIG_PARTITION_ADVANCED is not set
564CONFIG_MSDOS_PARTITION=y
565
566#
567# Native Language Support
568#
569CONFIG_NLS=y
570CONFIG_NLS_DEFAULT="iso8859-1"
571CONFIG_NLS_CODEPAGE_437=y
572# CONFIG_NLS_CODEPAGE_737 is not set
573# CONFIG_NLS_CODEPAGE_775 is not set
574# CONFIG_NLS_CODEPAGE_850 is not set
575# CONFIG_NLS_CODEPAGE_852 is not set
576# CONFIG_NLS_CODEPAGE_855 is not set
577# CONFIG_NLS_CODEPAGE_857 is not set
578# CONFIG_NLS_CODEPAGE_860 is not set
579# CONFIG_NLS_CODEPAGE_861 is not set
580# CONFIG_NLS_CODEPAGE_862 is not set
581# CONFIG_NLS_CODEPAGE_863 is not set
582# CONFIG_NLS_CODEPAGE_864 is not set
583# CONFIG_NLS_CODEPAGE_865 is not set
584# CONFIG_NLS_CODEPAGE_866 is not set
585# CONFIG_NLS_CODEPAGE_869 is not set
586# CONFIG_NLS_CODEPAGE_936 is not set
587# CONFIG_NLS_CODEPAGE_950 is not set
588CONFIG_NLS_CODEPAGE_932=y
589# CONFIG_NLS_CODEPAGE_949 is not set
590# CONFIG_NLS_CODEPAGE_874 is not set
591# CONFIG_NLS_ISO8859_8 is not set
592# CONFIG_NLS_CODEPAGE_1250 is not set
593# CONFIG_NLS_CODEPAGE_1251 is not set
594# CONFIG_NLS_ASCII is not set
595# CONFIG_NLS_ISO8859_1 is not set
596# CONFIG_NLS_ISO8859_2 is not set
597# CONFIG_NLS_ISO8859_3 is not set
598# CONFIG_NLS_ISO8859_4 is not set
599# CONFIG_NLS_ISO8859_5 is not set
600# CONFIG_NLS_ISO8859_6 is not set
601# CONFIG_NLS_ISO8859_7 is not set
602# CONFIG_NLS_ISO8859_9 is not set
603# CONFIG_NLS_ISO8859_13 is not set
604# CONFIG_NLS_ISO8859_14 is not set
605# CONFIG_NLS_ISO8859_15 is not set
606# CONFIG_NLS_KOI8_R is not set
607# CONFIG_NLS_KOI8_U is not set
608CONFIG_NLS_UTF8=y
609
610#
611# Profiling support
612#
613# CONFIG_PROFILING is not set
614
615#
616# Kernel hacking
617#
618# CONFIG_PRINTK_TIME is not set
619CONFIG_DEBUG_KERNEL=y
620CONFIG_MAGIC_SYSRQ=y
621CONFIG_LOG_BUF_SHIFT=14
622CONFIG_DETECT_SOFTLOCKUP=y
623# CONFIG_SCHEDSTATS is not set
624# CONFIG_DEBUG_SLAB is not set
625# CONFIG_DEBUG_SPINLOCK is not set
626# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
627# CONFIG_DEBUG_KOBJECT is not set
628# CONFIG_DEBUG_BUGVERBOSE is not set
629CONFIG_DEBUG_INFO=y
630# CONFIG_DEBUG_FS is not set
631# CONFIG_FRAME_POINTER is not set
632# CONFIG_DEBUG_STACKOVERFLOW is not set
633# CONFIG_DEBUG_STACK_USAGE is not set
634
635#
636# Security options
637#
638# CONFIG_KEYS is not set
639# CONFIG_SECURITY is not set
640
641#
642# Cryptographic options
643#
644# CONFIG_CRYPTO is not set
645
646#
647# Hardware crypto devices
648#
649
650#
651# Library routines
652#
653# CONFIG_CRC_CCITT is not set
654# CONFIG_CRC16 is not set
655CONFIG_CRC32=y
656CONFIG_LIBCRC32C=y
657CONFIG_ZLIB_INFLATE=y
diff --git a/arch/m32r/mm/cache.c b/arch/m32r/mm/cache.c
index 31b0789c1992..9f54dd937013 100644
--- a/arch/m32r/mm/cache.c
+++ b/arch/m32r/mm/cache.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * linux/arch/m32r/mm/cache.c 2 * linux/arch/m32r/mm/cache.c
3 * 3 *
4 * Copyright (C) 2002 Hirokazu Takata 4 * Copyright (C) 2002-2005 Hirokazu Takata, Hayato Fujiwara
5 */ 5 */
6 6
7#include <linux/config.h> 7#include <linux/config.h>
@@ -9,7 +9,8 @@
9 9
10#undef MCCR 10#undef MCCR
11 11
12#if defined(CONFIG_CHIP_XNUX2) || defined(CONFIG_CHIP_M32700) || defined(CONFIG_CHIP_VDEC2) || defined(CONFIG_CHIP_OPSP) 12#if defined(CONFIG_CHIP_XNUX2) || defined(CONFIG_CHIP_M32700) \
13 || defined(CONFIG_CHIP_VDEC2) || defined(CONFIG_CHIP_OPSP)
13/* Cache Control Register */ 14/* Cache Control Register */
14#define MCCR ((volatile unsigned long*)0xfffffffc) 15#define MCCR ((volatile unsigned long*)0xfffffffc)
15#define MCCR_CC (1UL << 7) /* Cache mode modify bit */ 16#define MCCR_CC (1UL << 7) /* Cache mode modify bit */
@@ -26,7 +27,17 @@
26#define MCCR ((volatile unsigned char*)0xfffffffe) 27#define MCCR ((volatile unsigned char*)0xfffffffe)
27#define MCCR_IIV (1UL << 0) /* I-cache invalidate */ 28#define MCCR_IIV (1UL << 0) /* I-cache invalidate */
28#define MCCR_ICACHE_INV MCCR_IIV 29#define MCCR_ICACHE_INV MCCR_IIV
29#endif /* CONFIG_CHIP_XNUX2 || CONFIG_CHIP_M32700 */ 30#elif defined(CONFIG_CHIP_M32104)
31#define MCCR ((volatile unsigned short*)0xfffffffe)
32#define MCCR_IIV (1UL << 8) /* I-cache invalidate */
33#define MCCR_DIV (1UL << 9) /* D-cache invalidate */
34#define MCCR_DCB (1UL << 10) /* D-cache copy back */
35#define MCCR_ICM (1UL << 0) /* I-cache mode [0:off,1:on] */
36#define MCCR_DCM (1UL << 1) /* D-cache mode [0:off,1:on] */
37#define MCCR_ICACHE_INV MCCR_IIV
38#define MCCR_DCACHE_CB MCCR_DCB
39#define MCCR_DCACHE_CBINV (MCCR_DIV|MCCR_DCB)
40#endif
30 41
31#ifndef MCCR 42#ifndef MCCR
32#error Unknown cache type. 43#error Unknown cache type.
@@ -37,29 +48,42 @@
37void _flush_cache_all(void) 48void _flush_cache_all(void)
38{ 49{
39#if defined(CONFIG_CHIP_M32102) 50#if defined(CONFIG_CHIP_M32102)
51 unsigned char mccr;
40 *MCCR = MCCR_ICACHE_INV; 52 *MCCR = MCCR_ICACHE_INV;
53#elif defined(CONFIG_CHIP_M32104)
54 unsigned short mccr;
55
56 /* Copyback and invalidate D-cache */
57 /* Invalidate I-cache */
58 *MCCR |= (MCCR_ICACHE_INV | MCCR_DCACHE_CBINV);
41#else 59#else
42 unsigned long mccr; 60 unsigned long mccr;
43 61
44 /* Copyback and invalidate D-cache */ 62 /* Copyback and invalidate D-cache */
45 /* Invalidate I-cache */ 63 /* Invalidate I-cache */
46 *MCCR = MCCR_ICACHE_INV | MCCR_DCACHE_CBINV; 64 *MCCR = MCCR_ICACHE_INV | MCCR_DCACHE_CBINV;
47 while ((mccr = *MCCR) & MCCR_IIV); /* loop while invalidating... */
48#endif 65#endif
66 while ((mccr = *MCCR) & MCCR_IIV); /* loop while invalidating... */
49} 67}
50 68
51/* Copy back D-cache and invalidate I-cache all */ 69/* Copy back D-cache and invalidate I-cache all */
52void _flush_cache_copyback_all(void) 70void _flush_cache_copyback_all(void)
53{ 71{
54#if defined(CONFIG_CHIP_M32102) 72#if defined(CONFIG_CHIP_M32102)
73 unsigned char mccr;
55 *MCCR = MCCR_ICACHE_INV; 74 *MCCR = MCCR_ICACHE_INV;
75#elif defined(CONFIG_CHIP_M32104)
76 unsigned short mccr;
77
78 /* Copyback and invalidate D-cache */
79 /* Invalidate I-cache */
80 *MCCR |= (MCCR_ICACHE_INV | MCCR_DCACHE_CB);
56#else 81#else
57 unsigned long mccr; 82 unsigned long mccr;
58 83
59 /* Copyback D-cache */ 84 /* Copyback D-cache */
60 /* Invalidate I-cache */ 85 /* Invalidate I-cache */
61 *MCCR = MCCR_ICACHE_INV | MCCR_DCACHE_CB; 86 *MCCR = MCCR_ICACHE_INV | MCCR_DCACHE_CB;
62 while ((mccr = *MCCR) & MCCR_IIV); /* loop while invalidating... */
63
64#endif 87#endif
88 while ((mccr = *MCCR) & MCCR_IIV); /* loop while invalidating... */
65} 89}
diff --git a/arch/m68knommu/kernel/m68k_ksyms.c b/arch/m68knommu/kernel/m68k_ksyms.c
index e93a5ad56496..b2c62eeb3bab 100644
--- a/arch/m68knommu/kernel/m68k_ksyms.c
+++ b/arch/m68knommu/kernel/m68k_ksyms.c
@@ -38,8 +38,6 @@ EXPORT_SYMBOL(strncmp);
38 38
39EXPORT_SYMBOL(ip_fast_csum); 39EXPORT_SYMBOL(ip_fast_csum);
40 40
41EXPORT_SYMBOL(mach_enable_irq);
42EXPORT_SYMBOL(mach_disable_irq);
43EXPORT_SYMBOL(kernel_thread); 41EXPORT_SYMBOL(kernel_thread);
44 42
45/* Networking helper routines. */ 43/* Networking helper routines. */
diff --git a/arch/m68knommu/kernel/setup.c b/arch/m68knommu/kernel/setup.c
index abb80fa2b940..93120b9bfff1 100644
--- a/arch/m68knommu/kernel/setup.c
+++ b/arch/m68knommu/kernel/setup.c
@@ -65,8 +65,6 @@ void (*mach_kbd_leds) (unsigned int) = NULL;
65/* machine dependent irq functions */ 65/* machine dependent irq functions */
66void (*mach_init_IRQ) (void) = NULL; 66void (*mach_init_IRQ) (void) = NULL;
67irqreturn_t (*(*mach_default_handler)[]) (int, void *, struct pt_regs *) = NULL; 67irqreturn_t (*(*mach_default_handler)[]) (int, void *, struct pt_regs *) = NULL;
68void (*mach_enable_irq) (unsigned int) = NULL;
69void (*mach_disable_irq) (unsigned int) = NULL;
70int (*mach_get_irq_list) (struct seq_file *, void *) = NULL; 68int (*mach_get_irq_list) (struct seq_file *, void *) = NULL;
71void (*mach_process_int) (int irq, struct pt_regs *fp) = NULL; 69void (*mach_process_int) (int irq, struct pt_regs *fp) = NULL;
72void (*mach_trap_init) (void); 70void (*mach_trap_init) (void);
diff --git a/arch/ppc/boot/simple/Makefile b/arch/ppc/boot/simple/Makefile
index f3e9c534aa82..9533f8de238f 100644
--- a/arch/ppc/boot/simple/Makefile
+++ b/arch/ppc/boot/simple/Makefile
@@ -190,6 +190,8 @@ boot-$(CONFIG_REDWOOD_5) += embed_config.o
190boot-$(CONFIG_REDWOOD_6) += embed_config.o 190boot-$(CONFIG_REDWOOD_6) += embed_config.o
191boot-$(CONFIG_8xx) += embed_config.o 191boot-$(CONFIG_8xx) += embed_config.o
192boot-$(CONFIG_8260) += embed_config.o 192boot-$(CONFIG_8260) += embed_config.o
193boot-$(CONFIG_EP405) += embed_config.o
194boot-$(CONFIG_XILINX_ML300) += embed_config.o
193boot-$(CONFIG_BSEIP) += iic.o 195boot-$(CONFIG_BSEIP) += iic.o
194boot-$(CONFIG_MBX) += iic.o pci.o qspan_pci.o 196boot-$(CONFIG_MBX) += iic.o pci.o qspan_pci.o
195boot-$(CONFIG_MV64X60) += misc-mv64x60.o 197boot-$(CONFIG_MV64X60) += misc-mv64x60.o
diff --git a/arch/ppc/kernel/idle.c b/arch/ppc/kernel/idle.c
index 821a75e45602..1be3ca5bae40 100644
--- a/arch/ppc/kernel/idle.c
+++ b/arch/ppc/kernel/idle.c
@@ -37,7 +37,6 @@
37void default_idle(void) 37void default_idle(void)
38{ 38{
39 void (*powersave)(void); 39 void (*powersave)(void);
40 int cpu = smp_processor_id();
41 40
42 powersave = ppc_md.power_save; 41 powersave = ppc_md.power_save;
43 42
@@ -47,7 +46,8 @@ void default_idle(void)
47#ifdef CONFIG_SMP 46#ifdef CONFIG_SMP
48 else { 47 else {
49 set_thread_flag(TIF_POLLING_NRFLAG); 48 set_thread_flag(TIF_POLLING_NRFLAG);
50 while (!need_resched() && !cpu_is_offline(cpu)) 49 while (!need_resched() &&
50 !cpu_is_offline(smp_processor_id()))
51 barrier(); 51 barrier();
52 clear_thread_flag(TIF_POLLING_NRFLAG); 52 clear_thread_flag(TIF_POLLING_NRFLAG);
53 } 53 }
diff --git a/arch/ppc/platforms/4xx/ibm440gx.c b/arch/ppc/platforms/4xx/ibm440gx.c
index 956f45e4ef97..d24c09ee7b18 100644
--- a/arch/ppc/platforms/4xx/ibm440gx.c
+++ b/arch/ppc/platforms/4xx/ibm440gx.c
@@ -58,7 +58,6 @@ static struct ocp_func_emac_data ibm440gx_emac2_def = {
58 .wol_irq = 65, /* WOL interrupt number */ 58 .wol_irq = 65, /* WOL interrupt number */
59 .mdio_idx = -1, /* No shared MDIO */ 59 .mdio_idx = -1, /* No shared MDIO */
60 .tah_idx = 0, /* TAH device index */ 60 .tah_idx = 0, /* TAH device index */
61 .jumbo = 1, /* Jumbo frames supported */
62}; 61};
63 62
64static struct ocp_func_emac_data ibm440gx_emac3_def = { 63static struct ocp_func_emac_data ibm440gx_emac3_def = {
@@ -72,7 +71,6 @@ static struct ocp_func_emac_data ibm440gx_emac3_def = {
72 .wol_irq = 67, /* WOL interrupt number */ 71 .wol_irq = 67, /* WOL interrupt number */
73 .mdio_idx = -1, /* No shared MDIO */ 72 .mdio_idx = -1, /* No shared MDIO */
74 .tah_idx = 1, /* TAH device index */ 73 .tah_idx = 1, /* TAH device index */
75 .jumbo = 1, /* Jumbo frames supported */
76}; 74};
77OCP_SYSFS_EMAC_DATA() 75OCP_SYSFS_EMAC_DATA()
78 76
diff --git a/arch/ppc/platforms/4xx/ibm440sp.c b/arch/ppc/platforms/4xx/ibm440sp.c
index feb17e41ef69..71a0117d3597 100644
--- a/arch/ppc/platforms/4xx/ibm440sp.c
+++ b/arch/ppc/platforms/4xx/ibm440sp.c
@@ -31,7 +31,6 @@ static struct ocp_func_emac_data ibm440sp_emac0_def = {
31 .wol_irq = 61, /* WOL interrupt number */ 31 .wol_irq = 61, /* WOL interrupt number */
32 .mdio_idx = -1, /* No shared MDIO */ 32 .mdio_idx = -1, /* No shared MDIO */
33 .tah_idx = -1, /* No TAH */ 33 .tah_idx = -1, /* No TAH */
34 .jumbo = 1, /* Jumbo frames supported */
35}; 34};
36OCP_SYSFS_EMAC_DATA() 35OCP_SYSFS_EMAC_DATA()
37 36
diff --git a/arch/ppc/platforms/lite5200.c b/arch/ppc/platforms/lite5200.c
index d44cc991179f..7ed52dc340c9 100644
--- a/arch/ppc/platforms/lite5200.c
+++ b/arch/ppc/platforms/lite5200.c
@@ -196,8 +196,10 @@ platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
196 mpc52xx_set_bat(); 196 mpc52xx_set_bat();
197 197
198 /* No ISA bus by default */ 198 /* No ISA bus by default */
199#ifdef CONFIG_PCI
199 isa_io_base = 0; 200 isa_io_base = 0;
200 isa_mem_base = 0; 201 isa_mem_base = 0;
202#endif
201 203
202 /* Powersave */ 204 /* Powersave */
203 /* This is provided as an example on how to do it. But you 205 /* This is provided as an example on how to do it. But you
diff --git a/arch/ppc/platforms/mpc5200.c b/arch/ppc/platforms/mpc5200.c
deleted file mode 100644
index a58db438c162..000000000000
--- a/arch/ppc/platforms/mpc5200.c
+++ /dev/null
@@ -1,53 +0,0 @@
1/*
2 * arch/ppc/platforms/mpc5200.c
3 *
4 * OCP Definitions for the boards based on MPC5200 processor. Contains
5 * definitions for every common peripherals. (Mostly all but PSCs)
6 *
7 * Maintainer : Sylvain Munaut <tnt@246tNt.com>
8 *
9 * Copyright 2004 Sylvain Munaut <tnt@246tNt.com>
10 *
11 * This file is licensed under the terms of the GNU General Public License
12 * version 2. This program is licensed "as is" without any warranty of any
13 * kind, whether express or implied.
14 */
15
16#include <asm/ocp.h>
17#include <asm/mpc52xx.h>
18
19
20static struct ocp_fs_i2c_data mpc5200_i2c_def = {
21 .flags = FS_I2C_CLOCK_5200,
22};
23
24
25/* Here is the core_ocp struct.
26 * With all the devices common to all board. Even if port multiplexing is
27 * not setup for them (if the user don't want them, just don't select the
28 * config option). The potentially conflicting devices (like PSCs) goes in
29 * board specific file.
30 */
31struct ocp_def core_ocp[] = {
32 {
33 .vendor = OCP_VENDOR_FREESCALE,
34 .function = OCP_FUNC_IIC,
35 .index = 0,
36 .paddr = MPC52xx_I2C1,
37 .irq = OCP_IRQ_NA, /* MPC52xx_IRQ_I2C1 - Buggy */
38 .pm = OCP_CPM_NA,
39 .additions = &mpc5200_i2c_def,
40 },
41 {
42 .vendor = OCP_VENDOR_FREESCALE,
43 .function = OCP_FUNC_IIC,
44 .index = 1,
45 .paddr = MPC52xx_I2C2,
46 .irq = OCP_IRQ_NA, /* MPC52xx_IRQ_I2C2 - Buggy */
47 .pm = OCP_CPM_NA,
48 .additions = &mpc5200_i2c_def,
49 },
50 { /* Terminating entry */
51 .vendor = OCP_VENDOR_INVALID
52 }
53};
diff --git a/arch/ppc/syslib/mpc52xx_pci.c b/arch/ppc/syslib/mpc52xx_pci.c
index 4ac19080eb85..313c96ec7eb1 100644
--- a/arch/ppc/syslib/mpc52xx_pci.c
+++ b/arch/ppc/syslib/mpc52xx_pci.c
@@ -24,6 +24,12 @@
24#include <asm/machdep.h> 24#include <asm/machdep.h>
25 25
26 26
27/* This macro is defined to activate the workaround for the bug
28 435 of the MPC5200 (L25R). With it activated, we don't do any
29 32 bits configuration access during type-1 cycles */
30#define MPC5200_BUG_435_WORKAROUND
31
32
27static int 33static int
28mpc52xx_pci_read_config(struct pci_bus *bus, unsigned int devfn, 34mpc52xx_pci_read_config(struct pci_bus *bus, unsigned int devfn,
29 int offset, int len, u32 *val) 35 int offset, int len, u32 *val)
@@ -40,17 +46,39 @@ mpc52xx_pci_read_config(struct pci_bus *bus, unsigned int devfn,
40 ((bus->number - hose->bus_offset) << 16) | 46 ((bus->number - hose->bus_offset) << 16) |
41 (devfn << 8) | 47 (devfn << 8) |
42 (offset & 0xfc)); 48 (offset & 0xfc));
49 mb();
50
51#ifdef MPC5200_BUG_435_WORKAROUND
52 if (bus->number != hose->bus_offset) {
53 switch (len) {
54 case 1:
55 value = in_8(((u8 __iomem *)hose->cfg_data) + (offset & 3));
56 break;
57 case 2:
58 value = in_le16(((u16 __iomem *)hose->cfg_data) + ((offset>>1) & 1));
59 break;
60
61 default:
62 value = in_le16((u16 __iomem *)hose->cfg_data) |
63 (in_le16(((u16 __iomem *)hose->cfg_data) + 1) << 16);
64 break;
65 }
66 }
67 else
68#endif
69 {
70 value = in_le32(hose->cfg_data);
43 71
44 value = in_le32(hose->cfg_data); 72 if (len != 4) {
45 73 value >>= ((offset & 0x3) << 3);
46 if (len != 4) { 74 value &= 0xffffffff >> (32 - (len << 3));
47 value >>= ((offset & 0x3) << 3); 75 }
48 value &= 0xffffffff >> (32 - (len << 3));
49 } 76 }
50 77
51 *val = value; 78 *val = value;
52 79
53 out_be32(hose->cfg_addr, 0); 80 out_be32(hose->cfg_addr, 0);
81 mb();
54 82
55 return PCIBIOS_SUCCESSFUL; 83 return PCIBIOS_SUCCESSFUL;
56} 84}
@@ -71,21 +99,48 @@ mpc52xx_pci_write_config(struct pci_bus *bus, unsigned int devfn,
71 ((bus->number - hose->bus_offset) << 16) | 99 ((bus->number - hose->bus_offset) << 16) |
72 (devfn << 8) | 100 (devfn << 8) |
73 (offset & 0xfc)); 101 (offset & 0xfc));
102 mb();
103
104#ifdef MPC5200_BUG_435_WORKAROUND
105 if (bus->number != hose->bus_offset) {
106 switch (len) {
107 case 1:
108 out_8(((u8 __iomem *)hose->cfg_data) +
109 (offset & 3), val);
110 break;
111 case 2:
112 out_le16(((u16 __iomem *)hose->cfg_data) +
113 ((offset>>1) & 1), val);
114 break;
115
116 default:
117 out_le16((u16 __iomem *)hose->cfg_data,
118 (u16)val);
119 out_le16(((u16 __iomem *)hose->cfg_data) + 1,
120 (u16)(val>>16));
121 break;
122 }
123 }
124 else
125#endif
126 {
127 if (len != 4) {
128 value = in_le32(hose->cfg_data);
74 129
75 if (len != 4) { 130 offset = (offset & 0x3) << 3;
76 value = in_le32(hose->cfg_data); 131 mask = (0xffffffff >> (32 - (len << 3)));
132 mask <<= offset;
77 133
78 offset = (offset & 0x3) << 3; 134 value &= ~mask;
79 mask = (0xffffffff >> (32 - (len << 3))); 135 val = value | ((val << offset) & mask);
80 mask <<= offset; 136 }
81 137
82 value &= ~mask; 138 out_le32(hose->cfg_data, val);
83 val = value | ((val << offset) & mask);
84 } 139 }
85 140 mb();
86 out_le32(hose->cfg_data, val);
87 141
88 out_be32(hose->cfg_addr, 0); 142 out_be32(hose->cfg_addr, 0);
143 mb();
89 144
90 return PCIBIOS_SUCCESSFUL; 145 return PCIBIOS_SUCCESSFUL;
91} 146}
@@ -99,9 +154,12 @@ static struct pci_ops mpc52xx_pci_ops = {
99static void __init 154static void __init
100mpc52xx_pci_setup(struct mpc52xx_pci __iomem *pci_regs) 155mpc52xx_pci_setup(struct mpc52xx_pci __iomem *pci_regs)
101{ 156{
157 u32 tmp;
102 158
103 /* Setup control regs */ 159 /* Setup control regs */
104 /* Nothing to do afaik */ 160 tmp = in_be32(&pci_regs->scr);
161 tmp |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
162 out_be32(&pci_regs->scr, tmp);
105 163
106 /* Setup windows */ 164 /* Setup windows */
107 out_be32(&pci_regs->iw0btar, MPC52xx_PCI_IWBTAR_TRANSLATION( 165 out_be32(&pci_regs->iw0btar, MPC52xx_PCI_IWBTAR_TRANSLATION(
@@ -142,16 +200,15 @@ mpc52xx_pci_setup(struct mpc52xx_pci __iomem *pci_regs)
142 /* Not necessary and can be a bad thing if for example the bootloader 200 /* Not necessary and can be a bad thing if for example the bootloader
143 is displaying a splash screen or ... Just left here for 201 is displaying a splash screen or ... Just left here for
144 documentation purpose if anyone need it */ 202 documentation purpose if anyone need it */
145#if 0
146 u32 tmp;
147 tmp = in_be32(&pci_regs->gscr); 203 tmp = in_be32(&pci_regs->gscr);
204#if 0
148 out_be32(&pci_regs->gscr, tmp | MPC52xx_PCI_GSCR_PR); 205 out_be32(&pci_regs->gscr, tmp | MPC52xx_PCI_GSCR_PR);
149 udelay(50); 206 udelay(50);
150 out_be32(&pci_regs->gscr, tmp);
151#endif 207#endif
208 out_be32(&pci_regs->gscr, tmp & ~MPC52xx_PCI_GSCR_PR);
152} 209}
153 210
154static void __init 211static void
155mpc52xx_pci_fixup_resources(struct pci_dev *dev) 212mpc52xx_pci_fixup_resources(struct pci_dev *dev)
156{ 213{
157 int i; 214 int i;
diff --git a/arch/ppc/syslib/mpc52xx_setup.c b/arch/ppc/syslib/mpc52xx_setup.c
index bb2374585a7b..a4a4b02227df 100644
--- a/arch/ppc/syslib/mpc52xx_setup.c
+++ b/arch/ppc/syslib/mpc52xx_setup.c
@@ -84,9 +84,11 @@ mpc52xx_set_bat(void)
84void __init 84void __init
85mpc52xx_map_io(void) 85mpc52xx_map_io(void)
86{ 86{
87 /* Here we only map the MBAR */ 87 /* Here we map the MBAR and the whole upper zone. MBAR is only
88 64k but we can't map only 64k with BATs. Map the whole
89 0xf0000000 range is ok and helps eventual lpb devices placed there */
88 io_block_mapping( 90 io_block_mapping(
89 MPC52xx_MBAR_VIRT, MPC52xx_MBAR, MPC52xx_MBAR_SIZE, _PAGE_IO); 91 MPC52xx_MBAR_VIRT, MPC52xx_MBAR, 0x10000000, _PAGE_IO);
90} 92}
91 93
92 94
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
index 477ac2758bd5..6fe532d82417 100644
--- a/arch/s390/Kconfig
+++ b/arch/s390/Kconfig
@@ -23,14 +23,14 @@ config GENERIC_BUST_SPINLOCK
23 23
24mainmenu "Linux Kernel Configuration" 24mainmenu "Linux Kernel Configuration"
25 25
26config ARCH_S390 26config S390
27 bool 27 bool
28 default y 28 default y
29 29
30config UID16 30config UID16
31 bool 31 bool
32 default y 32 default y
33 depends on ARCH_S390X = 'n' 33 depends on !64BIT
34 34
35source "init/Kconfig" 35source "init/Kconfig"
36 36
@@ -38,20 +38,12 @@ menu "Base setup"
38 38
39comment "Processor type and features" 39comment "Processor type and features"
40 40
41config ARCH_S390X 41config 64BIT
42 bool "64 bit kernel" 42 bool "64 bit kernel"
43 help 43 help
44 Select this option if you have a 64 bit IBM zSeries machine 44 Select this option if you have a 64 bit IBM zSeries machine
45 and want to use the 64 bit addressing mode. 45 and want to use the 64 bit addressing mode.
46 46
47config 64BIT
48 def_bool ARCH_S390X
49
50config ARCH_S390_31
51 bool
52 depends on ARCH_S390X = 'n'
53 default y
54
55config SMP 47config SMP
56 bool "Symmetric multi-processing support" 48 bool "Symmetric multi-processing support"
57 ---help--- 49 ---help---
@@ -101,20 +93,15 @@ config MATHEMU
101 on older S/390 machines. Say Y unless you know your machine doesn't 93 on older S/390 machines. Say Y unless you know your machine doesn't
102 need this. 94 need this.
103 95
104config S390_SUPPORT 96config COMPAT
105 bool "Kernel support for 31 bit emulation" 97 bool "Kernel support for 31 bit emulation"
106 depends on ARCH_S390X 98 depends on 64BIT
107 help 99 help
108 Select this option if you want to enable your system kernel to 100 Select this option if you want to enable your system kernel to
109 handle system-calls from ELF binaries for 31 bit ESA. This option 101 handle system-calls from ELF binaries for 31 bit ESA. This option
110 (and some other stuff like libraries and such) is needed for 102 (and some other stuff like libraries and such) is needed for
111 executing 31 bit applications. It is safe to say "Y". 103 executing 31 bit applications. It is safe to say "Y".
112 104
113config COMPAT
114 bool
115 depends on S390_SUPPORT
116 default y
117
118config SYSVIPC_COMPAT 105config SYSVIPC_COMPAT
119 bool 106 bool
120 depends on COMPAT && SYSVIPC 107 depends on COMPAT && SYSVIPC
@@ -122,7 +109,7 @@ config SYSVIPC_COMPAT
122 109
123config BINFMT_ELF32 110config BINFMT_ELF32
124 tristate "Kernel support for 31 bit ELF binaries" 111 tristate "Kernel support for 31 bit ELF binaries"
125 depends on S390_SUPPORT 112 depends on COMPAT
126 help 113 help
127 This allows you to run 32-bit Linux/ELF binaries on your zSeries 114 This allows you to run 32-bit Linux/ELF binaries on your zSeries
128 in 64 bit mode. Everybody wants this; say Y. 115 in 64 bit mode. Everybody wants this; say Y.
@@ -135,7 +122,7 @@ choice
135 122
136config MARCH_G5 123config MARCH_G5
137 bool "S/390 model G5 and G6" 124 bool "S/390 model G5 and G6"
138 depends on ARCH_S390_31 125 depends on !64BIT
139 help 126 help
140 Select this to build a 31 bit kernel that works 127 Select this to build a 31 bit kernel that works
141 on all S/390 and zSeries machines. 128 on all S/390 and zSeries machines.
@@ -240,8 +227,8 @@ config MACHCHK_WARNING
240config QDIO 227config QDIO
241 tristate "QDIO support" 228 tristate "QDIO support"
242 ---help--- 229 ---help---
243 This driver provides the Queued Direct I/O base support for the 230 This driver provides the Queued Direct I/O base support for
244 IBM S/390 (G5 and G6) and eServer zSeries (z800, z890, z900 and z990). 231 IBM mainframes.
245 232
246 For details please refer to the documentation provided by IBM at 233 For details please refer to the documentation provided by IBM at
247 <http://www10.software.ibm.com/developerworks/opensource/linux390> 234 <http://www10.software.ibm.com/developerworks/opensource/linux390>
@@ -263,7 +250,8 @@ config QDIO_DEBUG
263 bool "Extended debugging information" 250 bool "Extended debugging information"
264 depends on QDIO 251 depends on QDIO
265 help 252 help
266 Say Y here to get extended debugging output in /proc/s390dbf/qdio... 253 Say Y here to get extended debugging output in
254 /sys/kernel/debug/s390dbf/qdio...
267 Warning: this option reduces the performance of the QDIO module. 255 Warning: this option reduces the performance of the QDIO module.
268 256
269 If unsure, say N. 257 If unsure, say N.
diff --git a/arch/s390/Makefile b/arch/s390/Makefile
index 73a09a6ee6c8..6c6b197898d0 100644
--- a/arch/s390/Makefile
+++ b/arch/s390/Makefile
@@ -13,16 +13,14 @@
13# Copyright (C) 1994 by Linus Torvalds 13# Copyright (C) 1994 by Linus Torvalds
14# 14#
15 15
16ifdef CONFIG_ARCH_S390_31 16ifndef CONFIG_64BIT
17LDFLAGS := -m elf_s390 17LDFLAGS := -m elf_s390
18CFLAGS += -m31 18CFLAGS += -m31
19AFLAGS += -m31 19AFLAGS += -m31
20UTS_MACHINE := s390 20UTS_MACHINE := s390
21STACK_SIZE := 8192 21STACK_SIZE := 8192
22CHECKFLAGS += -D__s390__ 22CHECKFLAGS += -D__s390__
23endif 23else
24
25ifdef CONFIG_ARCH_S390X
26LDFLAGS := -m elf64_s390 24LDFLAGS := -m elf64_s390
27MODFLAGS += -fpic -D__PIC__ 25MODFLAGS += -fpic -D__PIC__
28CFLAGS += -m64 26CFLAGS += -m64
diff --git a/arch/s390/appldata/appldata_base.c b/arch/s390/appldata/appldata_base.c
index dee6ab54984d..d06a8d71c71d 100644
--- a/arch/s390/appldata/appldata_base.c
+++ b/arch/s390/appldata/appldata_base.c
@@ -40,7 +40,7 @@
40 40
41#define TOD_MICRO 0x01000 /* nr. of TOD clock units 41#define TOD_MICRO 0x01000 /* nr. of TOD clock units
42 for 1 microsecond */ 42 for 1 microsecond */
43#ifndef CONFIG_ARCH_S390X 43#ifndef CONFIG_64BIT
44 44
45#define APPLDATA_START_INTERVAL_REC 0x00 /* Function codes for */ 45#define APPLDATA_START_INTERVAL_REC 0x00 /* Function codes for */
46#define APPLDATA_STOP_REC 0x01 /* DIAG 0xDC */ 46#define APPLDATA_STOP_REC 0x01 /* DIAG 0xDC */
@@ -54,13 +54,13 @@
54#define APPLDATA_GEN_EVENT_RECORD 0x82 54#define APPLDATA_GEN_EVENT_RECORD 0x82
55#define APPLDATA_START_CONFIG_REC 0x83 55#define APPLDATA_START_CONFIG_REC 0x83
56 56
57#endif /* CONFIG_ARCH_S390X */ 57#endif /* CONFIG_64BIT */
58 58
59 59
60/* 60/*
61 * Parameter list for DIAGNOSE X'DC' 61 * Parameter list for DIAGNOSE X'DC'
62 */ 62 */
63#ifndef CONFIG_ARCH_S390X 63#ifndef CONFIG_64BIT
64struct appldata_parameter_list { 64struct appldata_parameter_list {
65 u16 diag; /* The DIAGNOSE code X'00DC' */ 65 u16 diag; /* The DIAGNOSE code X'00DC' */
66 u8 function; /* The function code for the DIAGNOSE */ 66 u8 function; /* The function code for the DIAGNOSE */
@@ -82,7 +82,7 @@ struct appldata_parameter_list {
82 u64 product_id_addr; 82 u64 product_id_addr;
83 u64 buffer_addr; 83 u64 buffer_addr;
84}; 84};
85#endif /* CONFIG_ARCH_S390X */ 85#endif /* CONFIG_64BIT */
86 86
87/* 87/*
88 * /proc entries (sysctl) 88 * /proc entries (sysctl)
diff --git a/arch/s390/appldata/appldata_os.c b/arch/s390/appldata/appldata_os.c
index e0a476bf4fd6..99ddd3bf2fba 100644
--- a/arch/s390/appldata/appldata_os.c
+++ b/arch/s390/appldata/appldata_os.c
@@ -141,19 +141,19 @@ static void appldata_get_os_data(void *data)
141 j = 0; 141 j = 0;
142 for_each_online_cpu(i) { 142 for_each_online_cpu(i) {
143 os_data->os_cpu[j].per_cpu_user = 143 os_data->os_cpu[j].per_cpu_user =
144 kstat_cpu(i).cpustat.user; 144 cputime_to_jiffies(kstat_cpu(i).cpustat.user);
145 os_data->os_cpu[j].per_cpu_nice = 145 os_data->os_cpu[j].per_cpu_nice =
146 kstat_cpu(i).cpustat.nice; 146 cputime_to_jiffies(kstat_cpu(i).cpustat.nice);
147 os_data->os_cpu[j].per_cpu_system = 147 os_data->os_cpu[j].per_cpu_system =
148 kstat_cpu(i).cpustat.system; 148 cputime_to_jiffies(kstat_cpu(i).cpustat.system);
149 os_data->os_cpu[j].per_cpu_idle = 149 os_data->os_cpu[j].per_cpu_idle =
150 kstat_cpu(i).cpustat.idle; 150 cputime_to_jiffies(kstat_cpu(i).cpustat.idle);
151 os_data->os_cpu[j].per_cpu_irq = 151 os_data->os_cpu[j].per_cpu_irq =
152 kstat_cpu(i).cpustat.irq; 152 cputime_to_jiffies(kstat_cpu(i).cpustat.irq);
153 os_data->os_cpu[j].per_cpu_softirq = 153 os_data->os_cpu[j].per_cpu_softirq =
154 kstat_cpu(i).cpustat.softirq; 154 cputime_to_jiffies(kstat_cpu(i).cpustat.softirq);
155 os_data->os_cpu[j].per_cpu_iowait = 155 os_data->os_cpu[j].per_cpu_iowait =
156 kstat_cpu(i).cpustat.iowait; 156 cputime_to_jiffies(kstat_cpu(i).cpustat.iowait);
157 j++; 157 j++;
158 } 158 }
159 159
diff --git a/arch/s390/crypto/Makefile b/arch/s390/crypto/Makefile
index 96a05e6b51e0..bfe2541dc5cf 100644
--- a/arch/s390/crypto/Makefile
+++ b/arch/s390/crypto/Makefile
@@ -2,7 +2,9 @@
2# Cryptographic API 2# Cryptographic API
3# 3#
4 4
5obj-$(CONFIG_CRYPTO_SHA1_Z990) += sha1_z990.o 5obj-$(CONFIG_CRYPTO_SHA1_S390) += sha1_s390.o
6obj-$(CONFIG_CRYPTO_DES_Z990) += des_z990.o des_check_key.o 6obj-$(CONFIG_CRYPTO_SHA256_S390) += sha256_s390.o
7obj-$(CONFIG_CRYPTO_DES_S390) += des_s390.o des_check_key.o
8obj-$(CONFIG_CRYPTO_AES_S390) += aes_s390.o
7 9
8obj-$(CONFIG_CRYPTO_TEST) += crypt_z990_query.o 10obj-$(CONFIG_CRYPTO_TEST) += crypt_s390_query.o
diff --git a/arch/s390/crypto/aes_s390.c b/arch/s390/crypto/aes_s390.c
new file mode 100644
index 000000000000..7a1033d8e00f
--- /dev/null
+++ b/arch/s390/crypto/aes_s390.c
@@ -0,0 +1,248 @@
1/*
2 * Cryptographic API.
3 *
4 * s390 implementation of the AES Cipher Algorithm.
5 *
6 * s390 Version:
7 * Copyright (C) 2005 IBM Deutschland GmbH, IBM Corporation
8 * Author(s): Jan Glauber (jang@de.ibm.com)
9 *
10 * Derived from "crypto/aes.c"
11 *
12 * This program is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by the Free
14 * Software Foundation; either version 2 of the License, or (at your option)
15 * any later version.
16 *
17 */
18
19#include <linux/module.h>
20#include <linux/init.h>
21#include <linux/crypto.h>
22#include "crypt_s390.h"
23
24#define AES_MIN_KEY_SIZE 16
25#define AES_MAX_KEY_SIZE 32
26
27/* data block size for all key lengths */
28#define AES_BLOCK_SIZE 16
29
30int has_aes_128 = 0;
31int has_aes_192 = 0;
32int has_aes_256 = 0;
33
34struct s390_aes_ctx {
35 u8 iv[AES_BLOCK_SIZE];
36 u8 key[AES_MAX_KEY_SIZE];
37 int key_len;
38};
39
40static int aes_set_key(void *ctx, const u8 *in_key, unsigned int key_len,
41 u32 *flags)
42{
43 struct s390_aes_ctx *sctx = ctx;
44
45 switch (key_len) {
46 case 16:
47 if (!has_aes_128)
48 goto fail;
49 break;
50 case 24:
51 if (!has_aes_192)
52 goto fail;
53
54 break;
55 case 32:
56 if (!has_aes_256)
57 goto fail;
58 break;
59 default:
60 /* invalid key length */
61 goto fail;
62 break;
63 }
64
65 sctx->key_len = key_len;
66 memcpy(sctx->key, in_key, key_len);
67 return 0;
68fail:
69 *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
70 return -EINVAL;
71}
72
73static void aes_encrypt(void *ctx, u8 *out, const u8 *in)
74{
75 const struct s390_aes_ctx *sctx = ctx;
76
77 switch (sctx->key_len) {
78 case 16:
79 crypt_s390_km(KM_AES_128_ENCRYPT, &sctx->key, out, in,
80 AES_BLOCK_SIZE);
81 break;
82 case 24:
83 crypt_s390_km(KM_AES_192_ENCRYPT, &sctx->key, out, in,
84 AES_BLOCK_SIZE);
85 break;
86 case 32:
87 crypt_s390_km(KM_AES_256_ENCRYPT, &sctx->key, out, in,
88 AES_BLOCK_SIZE);
89 break;
90 }
91}
92
93static void aes_decrypt(void *ctx, u8 *out, const u8 *in)
94{
95 const struct s390_aes_ctx *sctx = ctx;
96
97 switch (sctx->key_len) {
98 case 16:
99 crypt_s390_km(KM_AES_128_DECRYPT, &sctx->key, out, in,
100 AES_BLOCK_SIZE);
101 break;
102 case 24:
103 crypt_s390_km(KM_AES_192_DECRYPT, &sctx->key, out, in,
104 AES_BLOCK_SIZE);
105 break;
106 case 32:
107 crypt_s390_km(KM_AES_256_DECRYPT, &sctx->key, out, in,
108 AES_BLOCK_SIZE);
109 break;
110 }
111}
112
113static unsigned int aes_encrypt_ecb(const struct cipher_desc *desc, u8 *out,
114 const u8 *in, unsigned int nbytes)
115{
116 struct s390_aes_ctx *sctx = crypto_tfm_ctx(desc->tfm);
117
118 switch (sctx->key_len) {
119 case 16:
120 crypt_s390_km(KM_AES_128_ENCRYPT, &sctx->key, out, in, nbytes);
121 break;
122 case 24:
123 crypt_s390_km(KM_AES_192_ENCRYPT, &sctx->key, out, in, nbytes);
124 break;
125 case 32:
126 crypt_s390_km(KM_AES_256_ENCRYPT, &sctx->key, out, in, nbytes);
127 break;
128 }
129 return nbytes & ~(AES_BLOCK_SIZE - 1);
130}
131
132static unsigned int aes_decrypt_ecb(const struct cipher_desc *desc, u8 *out,
133 const u8 *in, unsigned int nbytes)
134{
135 struct s390_aes_ctx *sctx = crypto_tfm_ctx(desc->tfm);
136
137 switch (sctx->key_len) {
138 case 16:
139 crypt_s390_km(KM_AES_128_DECRYPT, &sctx->key, out, in, nbytes);
140 break;
141 case 24:
142 crypt_s390_km(KM_AES_192_DECRYPT, &sctx->key, out, in, nbytes);
143 break;
144 case 32:
145 crypt_s390_km(KM_AES_256_DECRYPT, &sctx->key, out, in, nbytes);
146 break;
147 }
148 return nbytes & ~(AES_BLOCK_SIZE - 1);
149}
150
151static unsigned int aes_encrypt_cbc(const struct cipher_desc *desc, u8 *out,
152 const u8 *in, unsigned int nbytes)
153{
154 struct s390_aes_ctx *sctx = crypto_tfm_ctx(desc->tfm);
155
156 memcpy(&sctx->iv, desc->info, AES_BLOCK_SIZE);
157 switch (sctx->key_len) {
158 case 16:
159 crypt_s390_kmc(KMC_AES_128_ENCRYPT, &sctx->iv, out, in, nbytes);
160 break;
161 case 24:
162 crypt_s390_kmc(KMC_AES_192_ENCRYPT, &sctx->iv, out, in, nbytes);
163 break;
164 case 32:
165 crypt_s390_kmc(KMC_AES_256_ENCRYPT, &sctx->iv, out, in, nbytes);
166 break;
167 }
168 memcpy(desc->info, &sctx->iv, AES_BLOCK_SIZE);
169
170 return nbytes & ~(AES_BLOCK_SIZE - 1);
171}
172
173static unsigned int aes_decrypt_cbc(const struct cipher_desc *desc, u8 *out,
174 const u8 *in, unsigned int nbytes)
175{
176 struct s390_aes_ctx *sctx = crypto_tfm_ctx(desc->tfm);
177
178 memcpy(&sctx->iv, desc->info, AES_BLOCK_SIZE);
179 switch (sctx->key_len) {
180 case 16:
181 crypt_s390_kmc(KMC_AES_128_DECRYPT, &sctx->iv, out, in, nbytes);
182 break;
183 case 24:
184 crypt_s390_kmc(KMC_AES_192_DECRYPT, &sctx->iv, out, in, nbytes);
185 break;
186 case 32:
187 crypt_s390_kmc(KMC_AES_256_DECRYPT, &sctx->iv, out, in, nbytes);
188 break;
189 }
190 return nbytes & ~(AES_BLOCK_SIZE - 1);
191}
192
193
194static struct crypto_alg aes_alg = {
195 .cra_name = "aes",
196 .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
197 .cra_blocksize = AES_BLOCK_SIZE,
198 .cra_ctxsize = sizeof(struct s390_aes_ctx),
199 .cra_module = THIS_MODULE,
200 .cra_list = LIST_HEAD_INIT(aes_alg.cra_list),
201 .cra_u = {
202 .cipher = {
203 .cia_min_keysize = AES_MIN_KEY_SIZE,
204 .cia_max_keysize = AES_MAX_KEY_SIZE,
205 .cia_setkey = aes_set_key,
206 .cia_encrypt = aes_encrypt,
207 .cia_decrypt = aes_decrypt,
208 .cia_encrypt_ecb = aes_encrypt_ecb,
209 .cia_decrypt_ecb = aes_decrypt_ecb,
210 .cia_encrypt_cbc = aes_encrypt_cbc,
211 .cia_decrypt_cbc = aes_decrypt_cbc,
212 }
213 }
214};
215
216static int __init aes_init(void)
217{
218 int ret;
219
220 if (crypt_s390_func_available(KM_AES_128_ENCRYPT))
221 has_aes_128 = 1;
222 if (crypt_s390_func_available(KM_AES_192_ENCRYPT))
223 has_aes_192 = 1;
224 if (crypt_s390_func_available(KM_AES_256_ENCRYPT))
225 has_aes_256 = 1;
226
227 if (!has_aes_128 && !has_aes_192 && !has_aes_256)
228 return -ENOSYS;
229
230 ret = crypto_register_alg(&aes_alg);
231 if (ret != 0)
232 printk(KERN_INFO "crypt_s390: aes_s390 couldn't be loaded.\n");
233 return ret;
234}
235
236static void __exit aes_fini(void)
237{
238 crypto_unregister_alg(&aes_alg);
239}
240
241module_init(aes_init);
242module_exit(aes_fini);
243
244MODULE_ALIAS("aes");
245
246MODULE_DESCRIPTION("Rijndael (AES) Cipher Algorithm");
247MODULE_LICENSE("GPL");
248
diff --git a/arch/s390/crypto/crypt_z990.h b/arch/s390/crypto/crypt_s390.h
index 4df660b99e5a..d1c259a7fe33 100644
--- a/arch/s390/crypto/crypt_z990.h
+++ b/arch/s390/crypto/crypt_s390.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * Cryptographic API. 2 * Cryptographic API.
3 * 3 *
4 * Support for z990 cryptographic instructions. 4 * Support for s390 cryptographic instructions.
5 * 5 *
6 * Copyright (C) 2003 IBM Deutschland GmbH, IBM Corporation 6 * Copyright (C) 2003 IBM Deutschland GmbH, IBM Corporation
7 * Author(s): Thomas Spatzier (tspat@de.ibm.com) 7 * Author(s): Thomas Spatzier (tspat@de.ibm.com)
@@ -12,84 +12,108 @@
12 * any later version. 12 * any later version.
13 * 13 *
14 */ 14 */
15#ifndef _CRYPTO_ARCH_S390_CRYPT_Z990_H 15#ifndef _CRYPTO_ARCH_S390_CRYPT_S390_H
16#define _CRYPTO_ARCH_S390_CRYPT_Z990_H 16#define _CRYPTO_ARCH_S390_CRYPT_S390_H
17 17
18#include <asm/errno.h> 18#include <asm/errno.h>
19 19
20#define CRYPT_Z990_OP_MASK 0xFF00 20#define CRYPT_S390_OP_MASK 0xFF00
21#define CRYPT_Z990_FUNC_MASK 0x00FF 21#define CRYPT_S390_FUNC_MASK 0x00FF
22 22
23 23/* s930 cryptographic operations */
24/*z990 cryptographic operations*/ 24enum crypt_s390_operations {
25enum crypt_z990_operations { 25 CRYPT_S390_KM = 0x0100,
26 CRYPT_Z990_KM = 0x0100, 26 CRYPT_S390_KMC = 0x0200,
27 CRYPT_Z990_KMC = 0x0200, 27 CRYPT_S390_KIMD = 0x0300,
28 CRYPT_Z990_KIMD = 0x0300, 28 CRYPT_S390_KLMD = 0x0400,
29 CRYPT_Z990_KLMD = 0x0400, 29 CRYPT_S390_KMAC = 0x0500
30 CRYPT_Z990_KMAC = 0x0500
31}; 30};
32 31
33/*function codes for KM (CIPHER MESSAGE) instruction*/ 32/* function codes for KM (CIPHER MESSAGE) instruction
34enum crypt_z990_km_func { 33 * 0x80 is the decipher modifier bit
35 KM_QUERY = CRYPT_Z990_KM | 0, 34 */
36 KM_DEA_ENCRYPT = CRYPT_Z990_KM | 1, 35enum crypt_s390_km_func {
37 KM_DEA_DECRYPT = CRYPT_Z990_KM | 1 | 0x80, //modifier bit->decipher 36 KM_QUERY = CRYPT_S390_KM | 0x0,
38 KM_TDEA_128_ENCRYPT = CRYPT_Z990_KM | 2, 37 KM_DEA_ENCRYPT = CRYPT_S390_KM | 0x1,
39 KM_TDEA_128_DECRYPT = CRYPT_Z990_KM | 2 | 0x80, 38 KM_DEA_DECRYPT = CRYPT_S390_KM | 0x1 | 0x80,
40 KM_TDEA_192_ENCRYPT = CRYPT_Z990_KM | 3, 39 KM_TDEA_128_ENCRYPT = CRYPT_S390_KM | 0x2,
41 KM_TDEA_192_DECRYPT = CRYPT_Z990_KM | 3 | 0x80, 40 KM_TDEA_128_DECRYPT = CRYPT_S390_KM | 0x2 | 0x80,
41 KM_TDEA_192_ENCRYPT = CRYPT_S390_KM | 0x3,
42 KM_TDEA_192_DECRYPT = CRYPT_S390_KM | 0x3 | 0x80,
43 KM_AES_128_ENCRYPT = CRYPT_S390_KM | 0x12,
44 KM_AES_128_DECRYPT = CRYPT_S390_KM | 0x12 | 0x80,
45 KM_AES_192_ENCRYPT = CRYPT_S390_KM | 0x13,
46 KM_AES_192_DECRYPT = CRYPT_S390_KM | 0x13 | 0x80,
47 KM_AES_256_ENCRYPT = CRYPT_S390_KM | 0x14,
48 KM_AES_256_DECRYPT = CRYPT_S390_KM | 0x14 | 0x80,
42}; 49};
43 50
44/*function codes for KMC (CIPHER MESSAGE WITH CHAINING) instruction*/ 51/* function codes for KMC (CIPHER MESSAGE WITH CHAINING)
45enum crypt_z990_kmc_func { 52 * instruction
46 KMC_QUERY = CRYPT_Z990_KMC | 0, 53 */
47 KMC_DEA_ENCRYPT = CRYPT_Z990_KMC | 1, 54enum crypt_s390_kmc_func {
48 KMC_DEA_DECRYPT = CRYPT_Z990_KMC | 1 | 0x80, //modifier bit->decipher 55 KMC_QUERY = CRYPT_S390_KMC | 0x0,
49 KMC_TDEA_128_ENCRYPT = CRYPT_Z990_KMC | 2, 56 KMC_DEA_ENCRYPT = CRYPT_S390_KMC | 0x1,
50 KMC_TDEA_128_DECRYPT = CRYPT_Z990_KMC | 2 | 0x80, 57 KMC_DEA_DECRYPT = CRYPT_S390_KMC | 0x1 | 0x80,
51 KMC_TDEA_192_ENCRYPT = CRYPT_Z990_KMC | 3, 58 KMC_TDEA_128_ENCRYPT = CRYPT_S390_KMC | 0x2,
52 KMC_TDEA_192_DECRYPT = CRYPT_Z990_KMC | 3 | 0x80, 59 KMC_TDEA_128_DECRYPT = CRYPT_S390_KMC | 0x2 | 0x80,
60 KMC_TDEA_192_ENCRYPT = CRYPT_S390_KMC | 0x3,
61 KMC_TDEA_192_DECRYPT = CRYPT_S390_KMC | 0x3 | 0x80,
62 KMC_AES_128_ENCRYPT = CRYPT_S390_KMC | 0x12,
63 KMC_AES_128_DECRYPT = CRYPT_S390_KMC | 0x12 | 0x80,
64 KMC_AES_192_ENCRYPT = CRYPT_S390_KMC | 0x13,
65 KMC_AES_192_DECRYPT = CRYPT_S390_KMC | 0x13 | 0x80,
66 KMC_AES_256_ENCRYPT = CRYPT_S390_KMC | 0x14,
67 KMC_AES_256_DECRYPT = CRYPT_S390_KMC | 0x14 | 0x80,
53}; 68};
54 69
55/*function codes for KIMD (COMPUTE INTERMEDIATE MESSAGE DIGEST) instruction*/ 70/* function codes for KIMD (COMPUTE INTERMEDIATE MESSAGE DIGEST)
56enum crypt_z990_kimd_func { 71 * instruction
57 KIMD_QUERY = CRYPT_Z990_KIMD | 0, 72 */
58 KIMD_SHA_1 = CRYPT_Z990_KIMD | 1, 73enum crypt_s390_kimd_func {
74 KIMD_QUERY = CRYPT_S390_KIMD | 0,
75 KIMD_SHA_1 = CRYPT_S390_KIMD | 1,
76 KIMD_SHA_256 = CRYPT_S390_KIMD | 2,
59}; 77};
60 78
61/*function codes for KLMD (COMPUTE LAST MESSAGE DIGEST) instruction*/ 79/* function codes for KLMD (COMPUTE LAST MESSAGE DIGEST)
62enum crypt_z990_klmd_func { 80 * instruction
63 KLMD_QUERY = CRYPT_Z990_KLMD | 0, 81 */
64 KLMD_SHA_1 = CRYPT_Z990_KLMD | 1, 82enum crypt_s390_klmd_func {
83 KLMD_QUERY = CRYPT_S390_KLMD | 0,
84 KLMD_SHA_1 = CRYPT_S390_KLMD | 1,
85 KLMD_SHA_256 = CRYPT_S390_KLMD | 2,
65}; 86};
66 87
67/*function codes for KMAC (COMPUTE MESSAGE AUTHENTICATION CODE) instruction*/ 88/* function codes for KMAC (COMPUTE MESSAGE AUTHENTICATION CODE)
68enum crypt_z990_kmac_func { 89 * instruction
69 KMAC_QUERY = CRYPT_Z990_KMAC | 0, 90 */
70 KMAC_DEA = CRYPT_Z990_KMAC | 1, 91enum crypt_s390_kmac_func {
71 KMAC_TDEA_128 = CRYPT_Z990_KMAC | 2, 92 KMAC_QUERY = CRYPT_S390_KMAC | 0,
72 KMAC_TDEA_192 = CRYPT_Z990_KMAC | 3 93 KMAC_DEA = CRYPT_S390_KMAC | 1,
94 KMAC_TDEA_128 = CRYPT_S390_KMAC | 2,
95 KMAC_TDEA_192 = CRYPT_S390_KMAC | 3
73}; 96};
74 97
75/*status word for z990 crypto instructions' QUERY functions*/ 98/* status word for s390 crypto instructions' QUERY functions */
76struct crypt_z990_query_status { 99struct crypt_s390_query_status {
77 u64 high; 100 u64 high;
78 u64 low; 101 u64 low;
79}; 102};
80 103
81/* 104/*
82 * Standard fixup and ex_table sections for crypt_z990 inline functions. 105 * Standard fixup and ex_table sections for crypt_s390 inline functions.
83 * label 0: the z990 crypto operation 106 * label 0: the s390 crypto operation
84 * label 1: just after 1 to catch illegal operation exception on non-z990 107 * label 1: just after 1 to catch illegal operation exception
108 * (unsupported model)
85 * label 6: the return point after fixup 109 * label 6: the return point after fixup
86 * label 7: set error value if exception _in_ crypto operation 110 * label 7: set error value if exception _in_ crypto operation
87 * label 8: set error value if illegal operation exception 111 * label 8: set error value if illegal operation exception
88 * [ret] is the variable to receive the error code 112 * [ret] is the variable to receive the error code
89 * [ERR] is the error code value 113 * [ERR] is the error code value
90 */ 114 */
91#ifndef __s390x__ 115#ifndef CONFIG_64BIT
92#define __crypt_z990_fixup \ 116#define __crypt_s390_fixup \
93 ".section .fixup,\"ax\" \n" \ 117 ".section .fixup,\"ax\" \n" \
94 "7: lhi %0,%h[e1] \n" \ 118 "7: lhi %0,%h[e1] \n" \
95 " bras 1,9f \n" \ 119 " bras 1,9f \n" \
@@ -105,8 +129,8 @@ struct crypt_z990_query_status {
105 " .long 0b,7b \n" \ 129 " .long 0b,7b \n" \
106 " .long 1b,8b \n" \ 130 " .long 1b,8b \n" \
107 ".previous" 131 ".previous"
108#else /* __s390x__ */ 132#else /* CONFIG_64BIT */
109#define __crypt_z990_fixup \ 133#define __crypt_s390_fixup \
110 ".section .fixup,\"ax\" \n" \ 134 ".section .fixup,\"ax\" \n" \
111 "7: lhi %0,%h[e1] \n" \ 135 "7: lhi %0,%h[e1] \n" \
112 " jg 6b \n" \ 136 " jg 6b \n" \
@@ -118,25 +142,25 @@ struct crypt_z990_query_status {
118 " .quad 0b,7b \n" \ 142 " .quad 0b,7b \n" \
119 " .quad 1b,8b \n" \ 143 " .quad 1b,8b \n" \
120 ".previous" 144 ".previous"
121#endif /* __s390x__ */ 145#endif /* CONFIG_64BIT */
122 146
123/* 147/*
124 * Standard code for setting the result of z990 crypto instructions. 148 * Standard code for setting the result of s390 crypto instructions.
125 * %0: the register which will receive the result 149 * %0: the register which will receive the result
126 * [result]: the register containing the result (e.g. second operand length 150 * [result]: the register containing the result (e.g. second operand length
127 * to compute number of processed bytes]. 151 * to compute number of processed bytes].
128 */ 152 */
129#ifndef __s390x__ 153#ifndef CONFIG_64BIT
130#define __crypt_z990_set_result \ 154#define __crypt_s390_set_result \
131 " lr %0,%[result] \n" 155 " lr %0,%[result] \n"
132#else /* __s390x__ */ 156#else /* CONFIG_64BIT */
133#define __crypt_z990_set_result \ 157#define __crypt_s390_set_result \
134 " lgr %0,%[result] \n" 158 " lgr %0,%[result] \n"
135#endif 159#endif
136 160
137/* 161/*
138 * Executes the KM (CIPHER MESSAGE) operation of the z990 CPU. 162 * Executes the KM (CIPHER MESSAGE) operation of the CPU.
139 * @param func: the function code passed to KM; see crypt_z990_km_func 163 * @param func: the function code passed to KM; see crypt_s390_km_func
140 * @param param: address of parameter block; see POP for details on each func 164 * @param param: address of parameter block; see POP for details on each func
141 * @param dest: address of destination memory area 165 * @param dest: address of destination memory area
142 * @param src: address of source memory area 166 * @param src: address of source memory area
@@ -145,9 +169,9 @@ struct crypt_z990_query_status {
145 * for encryption/decryption funcs 169 * for encryption/decryption funcs
146 */ 170 */
147static inline int 171static inline int
148crypt_z990_km(long func, void* param, u8* dest, const u8* src, long src_len) 172crypt_s390_km(long func, void* param, u8* dest, const u8* src, long src_len)
149{ 173{
150 register long __func asm("0") = func & CRYPT_Z990_FUNC_MASK; 174 register long __func asm("0") = func & CRYPT_S390_FUNC_MASK;
151 register void* __param asm("1") = param; 175 register void* __param asm("1") = param;
152 register u8* __dest asm("4") = dest; 176 register u8* __dest asm("4") = dest;
153 register const u8* __src asm("2") = src; 177 register const u8* __src asm("2") = src;
@@ -156,26 +180,26 @@ crypt_z990_km(long func, void* param, u8* dest, const u8* src, long src_len)
156 180
157 ret = 0; 181 ret = 0;
158 __asm__ __volatile__ ( 182 __asm__ __volatile__ (
159 "0: .insn rre,0xB92E0000,%1,%2 \n" //KM opcode 183 "0: .insn rre,0xB92E0000,%1,%2 \n" /* KM opcode */
160 "1: brc 1,0b \n" //handle partial completion 184 "1: brc 1,0b \n" /* handle partial completion */
161 __crypt_z990_set_result 185 __crypt_s390_set_result
162 "6: \n" 186 "6: \n"
163 __crypt_z990_fixup 187 __crypt_s390_fixup
164 : "+d" (ret), "+a" (__dest), "+a" (__src), 188 : "+d" (ret), "+a" (__dest), "+a" (__src),
165 [result] "+d" (__src_len) 189 [result] "+d" (__src_len)
166 : [e1] "K" (-EFAULT), [e2] "K" (-ENOSYS), "d" (__func), 190 : [e1] "K" (-EFAULT), [e2] "K" (-ENOSYS), "d" (__func),
167 "a" (__param) 191 "a" (__param)
168 : "cc", "memory" 192 : "cc", "memory"
169 ); 193 );
170 if (ret >= 0 && func & CRYPT_Z990_FUNC_MASK){ 194 if (ret >= 0 && func & CRYPT_S390_FUNC_MASK){
171 ret = src_len - ret; 195 ret = src_len - ret;
172 } 196 }
173 return ret; 197 return ret;
174} 198}
175 199
176/* 200/*
177 * Executes the KMC (CIPHER MESSAGE WITH CHAINING) operation of the z990 CPU. 201 * Executes the KMC (CIPHER MESSAGE WITH CHAINING) operation of the CPU.
178 * @param func: the function code passed to KM; see crypt_z990_kmc_func 202 * @param func: the function code passed to KM; see crypt_s390_kmc_func
179 * @param param: address of parameter block; see POP for details on each func 203 * @param param: address of parameter block; see POP for details on each func
180 * @param dest: address of destination memory area 204 * @param dest: address of destination memory area
181 * @param src: address of source memory area 205 * @param src: address of source memory area
@@ -184,9 +208,9 @@ crypt_z990_km(long func, void* param, u8* dest, const u8* src, long src_len)
184 * for encryption/decryption funcs 208 * for encryption/decryption funcs
185 */ 209 */
186static inline int 210static inline int
187crypt_z990_kmc(long func, void* param, u8* dest, const u8* src, long src_len) 211crypt_s390_kmc(long func, void* param, u8* dest, const u8* src, long src_len)
188{ 212{
189 register long __func asm("0") = func & CRYPT_Z990_FUNC_MASK; 213 register long __func asm("0") = func & CRYPT_S390_FUNC_MASK;
190 register void* __param asm("1") = param; 214 register void* __param asm("1") = param;
191 register u8* __dest asm("4") = dest; 215 register u8* __dest asm("4") = dest;
192 register const u8* __src asm("2") = src; 216 register const u8* __src asm("2") = src;
@@ -195,18 +219,18 @@ crypt_z990_kmc(long func, void* param, u8* dest, const u8* src, long src_len)
195 219
196 ret = 0; 220 ret = 0;
197 __asm__ __volatile__ ( 221 __asm__ __volatile__ (
198 "0: .insn rre,0xB92F0000,%1,%2 \n" //KMC opcode 222 "0: .insn rre,0xB92F0000,%1,%2 \n" /* KMC opcode */
199 "1: brc 1,0b \n" //handle partial completion 223 "1: brc 1,0b \n" /* handle partial completion */
200 __crypt_z990_set_result 224 __crypt_s390_set_result
201 "6: \n" 225 "6: \n"
202 __crypt_z990_fixup 226 __crypt_s390_fixup
203 : "+d" (ret), "+a" (__dest), "+a" (__src), 227 : "+d" (ret), "+a" (__dest), "+a" (__src),
204 [result] "+d" (__src_len) 228 [result] "+d" (__src_len)
205 : [e1] "K" (-EFAULT), [e2] "K" (-ENOSYS), "d" (__func), 229 : [e1] "K" (-EFAULT), [e2] "K" (-ENOSYS), "d" (__func),
206 "a" (__param) 230 "a" (__param)
207 : "cc", "memory" 231 : "cc", "memory"
208 ); 232 );
209 if (ret >= 0 && func & CRYPT_Z990_FUNC_MASK){ 233 if (ret >= 0 && func & CRYPT_S390_FUNC_MASK){
210 ret = src_len - ret; 234 ret = src_len - ret;
211 } 235 }
212 return ret; 236 return ret;
@@ -214,8 +238,8 @@ crypt_z990_kmc(long func, void* param, u8* dest, const u8* src, long src_len)
214 238
215/* 239/*
216 * Executes the KIMD (COMPUTE INTERMEDIATE MESSAGE DIGEST) operation 240 * Executes the KIMD (COMPUTE INTERMEDIATE MESSAGE DIGEST) operation
217 * of the z990 CPU. 241 * of the CPU.
218 * @param func: the function code passed to KM; see crypt_z990_kimd_func 242 * @param func: the function code passed to KM; see crypt_s390_kimd_func
219 * @param param: address of parameter block; see POP for details on each func 243 * @param param: address of parameter block; see POP for details on each func
220 * @param src: address of source memory area 244 * @param src: address of source memory area
221 * @param src_len: length of src operand in bytes 245 * @param src_len: length of src operand in bytes
@@ -223,9 +247,9 @@ crypt_z990_kmc(long func, void* param, u8* dest, const u8* src, long src_len)
223 * for digest funcs 247 * for digest funcs
224 */ 248 */
225static inline int 249static inline int
226crypt_z990_kimd(long func, void* param, const u8* src, long src_len) 250crypt_s390_kimd(long func, void* param, const u8* src, long src_len)
227{ 251{
228 register long __func asm("0") = func & CRYPT_Z990_FUNC_MASK; 252 register long __func asm("0") = func & CRYPT_S390_FUNC_MASK;
229 register void* __param asm("1") = param; 253 register void* __param asm("1") = param;
230 register const u8* __src asm("2") = src; 254 register const u8* __src asm("2") = src;
231 register long __src_len asm("3") = src_len; 255 register long __src_len asm("3") = src_len;
@@ -233,25 +257,25 @@ crypt_z990_kimd(long func, void* param, const u8* src, long src_len)
233 257
234 ret = 0; 258 ret = 0;
235 __asm__ __volatile__ ( 259 __asm__ __volatile__ (
236 "0: .insn rre,0xB93E0000,%1,%1 \n" //KIMD opcode 260 "0: .insn rre,0xB93E0000,%1,%1 \n" /* KIMD opcode */
237 "1: brc 1,0b \n" /*handle partical completion of kimd*/ 261 "1: brc 1,0b \n" /* handle partical completion */
238 __crypt_z990_set_result 262 __crypt_s390_set_result
239 "6: \n" 263 "6: \n"
240 __crypt_z990_fixup 264 __crypt_s390_fixup
241 : "+d" (ret), "+a" (__src), [result] "+d" (__src_len) 265 : "+d" (ret), "+a" (__src), [result] "+d" (__src_len)
242 : [e1] "K" (-EFAULT), [e2] "K" (-ENOSYS), "d" (__func), 266 : [e1] "K" (-EFAULT), [e2] "K" (-ENOSYS), "d" (__func),
243 "a" (__param) 267 "a" (__param)
244 : "cc", "memory" 268 : "cc", "memory"
245 ); 269 );
246 if (ret >= 0 && (func & CRYPT_Z990_FUNC_MASK)){ 270 if (ret >= 0 && (func & CRYPT_S390_FUNC_MASK)){
247 ret = src_len - ret; 271 ret = src_len - ret;
248 } 272 }
249 return ret; 273 return ret;
250} 274}
251 275
252/* 276/*
253 * Executes the KLMD (COMPUTE LAST MESSAGE DIGEST) operation of the z990 CPU. 277 * Executes the KLMD (COMPUTE LAST MESSAGE DIGEST) operation of the CPU.
254 * @param func: the function code passed to KM; see crypt_z990_klmd_func 278 * @param func: the function code passed to KM; see crypt_s390_klmd_func
255 * @param param: address of parameter block; see POP for details on each func 279 * @param param: address of parameter block; see POP for details on each func
256 * @param src: address of source memory area 280 * @param src: address of source memory area
257 * @param src_len: length of src operand in bytes 281 * @param src_len: length of src operand in bytes
@@ -259,9 +283,9 @@ crypt_z990_kimd(long func, void* param, const u8* src, long src_len)
259 * for digest funcs 283 * for digest funcs
260 */ 284 */
261static inline int 285static inline int
262crypt_z990_klmd(long func, void* param, const u8* src, long src_len) 286crypt_s390_klmd(long func, void* param, const u8* src, long src_len)
263{ 287{
264 register long __func asm("0") = func & CRYPT_Z990_FUNC_MASK; 288 register long __func asm("0") = func & CRYPT_S390_FUNC_MASK;
265 register void* __param asm("1") = param; 289 register void* __param asm("1") = param;
266 register const u8* __src asm("2") = src; 290 register const u8* __src asm("2") = src;
267 register long __src_len asm("3") = src_len; 291 register long __src_len asm("3") = src_len;
@@ -269,17 +293,17 @@ crypt_z990_klmd(long func, void* param, const u8* src, long src_len)
269 293
270 ret = 0; 294 ret = 0;
271 __asm__ __volatile__ ( 295 __asm__ __volatile__ (
272 "0: .insn rre,0xB93F0000,%1,%1 \n" //KLMD opcode 296 "0: .insn rre,0xB93F0000,%1,%1 \n" /* KLMD opcode */
273 "1: brc 1,0b \n" /*handle partical completion of klmd*/ 297 "1: brc 1,0b \n" /* handle partical completion */
274 __crypt_z990_set_result 298 __crypt_s390_set_result
275 "6: \n" 299 "6: \n"
276 __crypt_z990_fixup 300 __crypt_s390_fixup
277 : "+d" (ret), "+a" (__src), [result] "+d" (__src_len) 301 : "+d" (ret), "+a" (__src), [result] "+d" (__src_len)
278 : [e1] "K" (-EFAULT), [e2] "K" (-ENOSYS), "d" (__func), 302 : [e1] "K" (-EFAULT), [e2] "K" (-ENOSYS), "d" (__func),
279 "a" (__param) 303 "a" (__param)
280 : "cc", "memory" 304 : "cc", "memory"
281 ); 305 );
282 if (ret >= 0 && func & CRYPT_Z990_FUNC_MASK){ 306 if (ret >= 0 && func & CRYPT_S390_FUNC_MASK){
283 ret = src_len - ret; 307 ret = src_len - ret;
284 } 308 }
285 return ret; 309 return ret;
@@ -287,8 +311,8 @@ crypt_z990_klmd(long func, void* param, const u8* src, long src_len)
287 311
288/* 312/*
289 * Executes the KMAC (COMPUTE MESSAGE AUTHENTICATION CODE) operation 313 * Executes the KMAC (COMPUTE MESSAGE AUTHENTICATION CODE) operation
290 * of the z990 CPU. 314 * of the CPU.
291 * @param func: the function code passed to KM; see crypt_z990_klmd_func 315 * @param func: the function code passed to KM; see crypt_s390_klmd_func
292 * @param param: address of parameter block; see POP for details on each func 316 * @param param: address of parameter block; see POP for details on each func
293 * @param src: address of source memory area 317 * @param src: address of source memory area
294 * @param src_len: length of src operand in bytes 318 * @param src_len: length of src operand in bytes
@@ -296,9 +320,9 @@ crypt_z990_klmd(long func, void* param, const u8* src, long src_len)
296 * for digest funcs 320 * for digest funcs
297 */ 321 */
298static inline int 322static inline int
299crypt_z990_kmac(long func, void* param, const u8* src, long src_len) 323crypt_s390_kmac(long func, void* param, const u8* src, long src_len)
300{ 324{
301 register long __func asm("0") = func & CRYPT_Z990_FUNC_MASK; 325 register long __func asm("0") = func & CRYPT_S390_FUNC_MASK;
302 register void* __param asm("1") = param; 326 register void* __param asm("1") = param;
303 register const u8* __src asm("2") = src; 327 register const u8* __src asm("2") = src;
304 register long __src_len asm("3") = src_len; 328 register long __src_len asm("3") = src_len;
@@ -306,58 +330,58 @@ crypt_z990_kmac(long func, void* param, const u8* src, long src_len)
306 330
307 ret = 0; 331 ret = 0;
308 __asm__ __volatile__ ( 332 __asm__ __volatile__ (
309 "0: .insn rre,0xB91E0000,%5,%5 \n" //KMAC opcode 333 "0: .insn rre,0xB91E0000,%5,%5 \n" /* KMAC opcode */
310 "1: brc 1,0b \n" /*handle partical completion of klmd*/ 334 "1: brc 1,0b \n" /* handle partical completion */
311 __crypt_z990_set_result 335 __crypt_s390_set_result
312 "6: \n" 336 "6: \n"
313 __crypt_z990_fixup 337 __crypt_s390_fixup
314 : "+d" (ret), "+a" (__src), [result] "+d" (__src_len) 338 : "+d" (ret), "+a" (__src), [result] "+d" (__src_len)
315 : [e1] "K" (-EFAULT), [e2] "K" (-ENOSYS), "d" (__func), 339 : [e1] "K" (-EFAULT), [e2] "K" (-ENOSYS), "d" (__func),
316 "a" (__param) 340 "a" (__param)
317 : "cc", "memory" 341 : "cc", "memory"
318 ); 342 );
319 if (ret >= 0 && func & CRYPT_Z990_FUNC_MASK){ 343 if (ret >= 0 && func & CRYPT_S390_FUNC_MASK){
320 ret = src_len - ret; 344 ret = src_len - ret;
321 } 345 }
322 return ret; 346 return ret;
323} 347}
324 348
325/** 349/**
326 * Tests if a specific z990 crypto function is implemented on the machine. 350 * Tests if a specific crypto function is implemented on the machine.
327 * @param func: the function code of the specific function; 0 if op in general 351 * @param func: the function code of the specific function; 0 if op in general
328 * @return 1 if func available; 0 if func or op in general not available 352 * @return 1 if func available; 0 if func or op in general not available
329 */ 353 */
330static inline int 354static inline int
331crypt_z990_func_available(int func) 355crypt_s390_func_available(int func)
332{ 356{
333 int ret; 357 int ret;
334 358
335 struct crypt_z990_query_status status = { 359 struct crypt_s390_query_status status = {
336 .high = 0, 360 .high = 0,
337 .low = 0 361 .low = 0
338 }; 362 };
339 switch (func & CRYPT_Z990_OP_MASK){ 363 switch (func & CRYPT_S390_OP_MASK){
340 case CRYPT_Z990_KM: 364 case CRYPT_S390_KM:
341 ret = crypt_z990_km(KM_QUERY, &status, NULL, NULL, 0); 365 ret = crypt_s390_km(KM_QUERY, &status, NULL, NULL, 0);
342 break; 366 break;
343 case CRYPT_Z990_KMC: 367 case CRYPT_S390_KMC:
344 ret = crypt_z990_kmc(KMC_QUERY, &status, NULL, NULL, 0); 368 ret = crypt_s390_kmc(KMC_QUERY, &status, NULL, NULL, 0);
345 break; 369 break;
346 case CRYPT_Z990_KIMD: 370 case CRYPT_S390_KIMD:
347 ret = crypt_z990_kimd(KIMD_QUERY, &status, NULL, 0); 371 ret = crypt_s390_kimd(KIMD_QUERY, &status, NULL, 0);
348 break; 372 break;
349 case CRYPT_Z990_KLMD: 373 case CRYPT_S390_KLMD:
350 ret = crypt_z990_klmd(KLMD_QUERY, &status, NULL, 0); 374 ret = crypt_s390_klmd(KLMD_QUERY, &status, NULL, 0);
351 break; 375 break;
352 case CRYPT_Z990_KMAC: 376 case CRYPT_S390_KMAC:
353 ret = crypt_z990_kmac(KMAC_QUERY, &status, NULL, 0); 377 ret = crypt_s390_kmac(KMAC_QUERY, &status, NULL, 0);
354 break; 378 break;
355 default: 379 default:
356 ret = 0; 380 ret = 0;
357 return ret; 381 return ret;
358 } 382 }
359 if (ret >= 0){ 383 if (ret >= 0){
360 func &= CRYPT_Z990_FUNC_MASK; 384 func &= CRYPT_S390_FUNC_MASK;
361 func &= 0x7f; //mask modifier bit 385 func &= 0x7f; //mask modifier bit
362 if (func < 64){ 386 if (func < 64){
363 ret = (status.high >> (64 - func - 1)) & 0x1; 387 ret = (status.high >> (64 - func - 1)) & 0x1;
@@ -370,5 +394,4 @@ crypt_z990_func_available(int func)
370 return ret; 394 return ret;
371} 395}
372 396
373 397#endif // _CRYPTO_ARCH_S390_CRYPT_S390_H
374#endif // _CRYPTO_ARCH_S390_CRYPT_Z990_H
diff --git a/arch/s390/crypto/crypt_s390_query.c b/arch/s390/crypto/crypt_s390_query.c
new file mode 100644
index 000000000000..def02bdc44a4
--- /dev/null
+++ b/arch/s390/crypto/crypt_s390_query.c
@@ -0,0 +1,129 @@
1/*
2 * Cryptographic API.
3 *
4 * Support for s390 cryptographic instructions.
5 * Testing module for querying processor crypto capabilities.
6 *
7 * Copyright (c) 2003 IBM Deutschland Entwicklung GmbH, IBM Corporation
8 * Author(s): Thomas Spatzier (tspat@de.ibm.com)
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the Free
12 * Software Foundation; either version 2 of the License, or (at your option)
13 * any later version.
14 *
15 */
16#include <linux/module.h>
17#include <linux/init.h>
18#include <linux/kernel.h>
19#include <asm/errno.h>
20#include "crypt_s390.h"
21
22static void query_available_functions(void)
23{
24 printk(KERN_INFO "#####################\n");
25
26 /* query available KM functions */
27 printk(KERN_INFO "KM_QUERY: %d\n",
28 crypt_s390_func_available(KM_QUERY));
29 printk(KERN_INFO "KM_DEA: %d\n",
30 crypt_s390_func_available(KM_DEA_ENCRYPT));
31 printk(KERN_INFO "KM_TDEA_128: %d\n",
32 crypt_s390_func_available(KM_TDEA_128_ENCRYPT));
33 printk(KERN_INFO "KM_TDEA_192: %d\n",
34 crypt_s390_func_available(KM_TDEA_192_ENCRYPT));
35 printk(KERN_INFO "KM_AES_128: %d\n",
36 crypt_s390_func_available(KM_AES_128_ENCRYPT));
37 printk(KERN_INFO "KM_AES_192: %d\n",
38 crypt_s390_func_available(KM_AES_192_ENCRYPT));
39 printk(KERN_INFO "KM_AES_256: %d\n",
40 crypt_s390_func_available(KM_AES_256_ENCRYPT));
41
42 /* query available KMC functions */
43 printk(KERN_INFO "KMC_QUERY: %d\n",
44 crypt_s390_func_available(KMC_QUERY));
45 printk(KERN_INFO "KMC_DEA: %d\n",
46 crypt_s390_func_available(KMC_DEA_ENCRYPT));
47 printk(KERN_INFO "KMC_TDEA_128: %d\n",
48 crypt_s390_func_available(KMC_TDEA_128_ENCRYPT));
49 printk(KERN_INFO "KMC_TDEA_192: %d\n",
50 crypt_s390_func_available(KMC_TDEA_192_ENCRYPT));
51 printk(KERN_INFO "KMC_AES_128: %d\n",
52 crypt_s390_func_available(KMC_AES_128_ENCRYPT));
53 printk(KERN_INFO "KMC_AES_192: %d\n",
54 crypt_s390_func_available(KMC_AES_192_ENCRYPT));
55 printk(KERN_INFO "KMC_AES_256: %d\n",
56 crypt_s390_func_available(KMC_AES_256_ENCRYPT));
57
58 /* query available KIMD fucntions */
59 printk(KERN_INFO "KIMD_QUERY: %d\n",
60 crypt_s390_func_available(KIMD_QUERY));
61 printk(KERN_INFO "KIMD_SHA_1: %d\n",
62 crypt_s390_func_available(KIMD_SHA_1));
63 printk(KERN_INFO "KIMD_SHA_256: %d\n",
64 crypt_s390_func_available(KIMD_SHA_256));
65
66 /* query available KLMD functions */
67 printk(KERN_INFO "KLMD_QUERY: %d\n",
68 crypt_s390_func_available(KLMD_QUERY));
69 printk(KERN_INFO "KLMD_SHA_1: %d\n",
70 crypt_s390_func_available(KLMD_SHA_1));
71 printk(KERN_INFO "KLMD_SHA_256: %d\n",
72 crypt_s390_func_available(KLMD_SHA_256));
73
74 /* query available KMAC functions */
75 printk(KERN_INFO "KMAC_QUERY: %d\n",
76 crypt_s390_func_available(KMAC_QUERY));
77 printk(KERN_INFO "KMAC_DEA: %d\n",
78 crypt_s390_func_available(KMAC_DEA));
79 printk(KERN_INFO "KMAC_TDEA_128: %d\n",
80 crypt_s390_func_available(KMAC_TDEA_128));
81 printk(KERN_INFO "KMAC_TDEA_192: %d\n",
82 crypt_s390_func_available(KMAC_TDEA_192));
83}
84
85static int init(void)
86{
87 struct crypt_s390_query_status status = {
88 .high = 0,
89 .low = 0
90 };
91
92 printk(KERN_INFO "crypt_s390: querying available crypto functions\n");
93 crypt_s390_km(KM_QUERY, &status, NULL, NULL, 0);
94 printk(KERN_INFO "KM:\t%016llx %016llx\n",
95 (unsigned long long) status.high,
96 (unsigned long long) status.low);
97 status.high = status.low = 0;
98 crypt_s390_kmc(KMC_QUERY, &status, NULL, NULL, 0);
99 printk(KERN_INFO "KMC:\t%016llx %016llx\n",
100 (unsigned long long) status.high,
101 (unsigned long long) status.low);
102 status.high = status.low = 0;
103 crypt_s390_kimd(KIMD_QUERY, &status, NULL, 0);
104 printk(KERN_INFO "KIMD:\t%016llx %016llx\n",
105 (unsigned long long) status.high,
106 (unsigned long long) status.low);
107 status.high = status.low = 0;
108 crypt_s390_klmd(KLMD_QUERY, &status, NULL, 0);
109 printk(KERN_INFO "KLMD:\t%016llx %016llx\n",
110 (unsigned long long) status.high,
111 (unsigned long long) status.low);
112 status.high = status.low = 0;
113 crypt_s390_kmac(KMAC_QUERY, &status, NULL, 0);
114 printk(KERN_INFO "KMAC:\t%016llx %016llx\n",
115 (unsigned long long) status.high,
116 (unsigned long long) status.low);
117
118 query_available_functions();
119 return -ECANCELED;
120}
121
122static void __exit cleanup(void)
123{
124}
125
126module_init(init);
127module_exit(cleanup);
128
129MODULE_LICENSE("GPL");
diff --git a/arch/s390/crypto/crypt_z990_query.c b/arch/s390/crypto/crypt_z990_query.c
deleted file mode 100644
index 7133983d1384..000000000000
--- a/arch/s390/crypto/crypt_z990_query.c
+++ /dev/null
@@ -1,111 +0,0 @@
1/*
2 * Cryptographic API.
3 *
4 * Support for z990 cryptographic instructions.
5 * Testing module for querying processor crypto capabilities.
6 *
7 * Copyright (c) 2003 IBM Deutschland Entwicklung GmbH, IBM Corporation
8 * Author(s): Thomas Spatzier (tspat@de.ibm.com)
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the Free
12 * Software Foundation; either version 2 of the License, or (at your option)
13 * any later version.
14 *
15 */
16#include <linux/module.h>
17#include <linux/init.h>
18#include <linux/kernel.h>
19#include <asm/errno.h>
20#include "crypt_z990.h"
21
22static void
23query_available_functions(void)
24{
25 printk(KERN_INFO "#####################\n");
26 //query available KM functions
27 printk(KERN_INFO "KM_QUERY: %d\n",
28 crypt_z990_func_available(KM_QUERY));
29 printk(KERN_INFO "KM_DEA: %d\n",
30 crypt_z990_func_available(KM_DEA_ENCRYPT));
31 printk(KERN_INFO "KM_TDEA_128: %d\n",
32 crypt_z990_func_available(KM_TDEA_128_ENCRYPT));
33 printk(KERN_INFO "KM_TDEA_192: %d\n",
34 crypt_z990_func_available(KM_TDEA_192_ENCRYPT));
35 //query available KMC functions
36 printk(KERN_INFO "KMC_QUERY: %d\n",
37 crypt_z990_func_available(KMC_QUERY));
38 printk(KERN_INFO "KMC_DEA: %d\n",
39 crypt_z990_func_available(KMC_DEA_ENCRYPT));
40 printk(KERN_INFO "KMC_TDEA_128: %d\n",
41 crypt_z990_func_available(KMC_TDEA_128_ENCRYPT));
42 printk(KERN_INFO "KMC_TDEA_192: %d\n",
43 crypt_z990_func_available(KMC_TDEA_192_ENCRYPT));
44 //query available KIMD fucntions
45 printk(KERN_INFO "KIMD_QUERY: %d\n",
46 crypt_z990_func_available(KIMD_QUERY));
47 printk(KERN_INFO "KIMD_SHA_1: %d\n",
48 crypt_z990_func_available(KIMD_SHA_1));
49 //query available KLMD functions
50 printk(KERN_INFO "KLMD_QUERY: %d\n",
51 crypt_z990_func_available(KLMD_QUERY));
52 printk(KERN_INFO "KLMD_SHA_1: %d\n",
53 crypt_z990_func_available(KLMD_SHA_1));
54 //query available KMAC functions
55 printk(KERN_INFO "KMAC_QUERY: %d\n",
56 crypt_z990_func_available(KMAC_QUERY));
57 printk(KERN_INFO "KMAC_DEA: %d\n",
58 crypt_z990_func_available(KMAC_DEA));
59 printk(KERN_INFO "KMAC_TDEA_128: %d\n",
60 crypt_z990_func_available(KMAC_TDEA_128));
61 printk(KERN_INFO "KMAC_TDEA_192: %d\n",
62 crypt_z990_func_available(KMAC_TDEA_192));
63}
64
65static int
66init(void)
67{
68 struct crypt_z990_query_status status = {
69 .high = 0,
70 .low = 0
71 };
72
73 printk(KERN_INFO "crypt_z990: querying available crypto functions\n");
74 crypt_z990_km(KM_QUERY, &status, NULL, NULL, 0);
75 printk(KERN_INFO "KM: %016llx %016llx\n",
76 (unsigned long long) status.high,
77 (unsigned long long) status.low);
78 status.high = status.low = 0;
79 crypt_z990_kmc(KMC_QUERY, &status, NULL, NULL, 0);
80 printk(KERN_INFO "KMC: %016llx %016llx\n",
81 (unsigned long long) status.high,
82 (unsigned long long) status.low);
83 status.high = status.low = 0;
84 crypt_z990_kimd(KIMD_QUERY, &status, NULL, 0);
85 printk(KERN_INFO "KIMD: %016llx %016llx\n",
86 (unsigned long long) status.high,
87 (unsigned long long) status.low);
88 status.high = status.low = 0;
89 crypt_z990_klmd(KLMD_QUERY, &status, NULL, 0);
90 printk(KERN_INFO "KLMD: %016llx %016llx\n",
91 (unsigned long long) status.high,
92 (unsigned long long) status.low);
93 status.high = status.low = 0;
94 crypt_z990_kmac(KMAC_QUERY, &status, NULL, 0);
95 printk(KERN_INFO "KMAC: %016llx %016llx\n",
96 (unsigned long long) status.high,
97 (unsigned long long) status.low);
98
99 query_available_functions();
100 return -1;
101}
102
103static void __exit
104cleanup(void)
105{
106}
107
108module_init(init);
109module_exit(cleanup);
110
111MODULE_LICENSE("GPL");
diff --git a/arch/s390/crypto/des_z990.c b/arch/s390/crypto/des_s390.c
index 813cf37b1177..a38bb2a3eef6 100644
--- a/arch/s390/crypto/des_z990.c
+++ b/arch/s390/crypto/des_s390.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Cryptographic API. 2 * Cryptographic API.
3 * 3 *
4 * z990 implementation of the DES Cipher Algorithm. 4 * s390 implementation of the DES Cipher Algorithm.
5 * 5 *
6 * Copyright (c) 2003 IBM Deutschland Entwicklung GmbH, IBM Corporation 6 * Copyright (c) 2003 IBM Deutschland Entwicklung GmbH, IBM Corporation
7 * Author(s): Thomas Spatzier (tspat@de.ibm.com) 7 * Author(s): Thomas Spatzier (tspat@de.ibm.com)
@@ -19,7 +19,7 @@
19#include <linux/errno.h> 19#include <linux/errno.h>
20#include <asm/scatterlist.h> 20#include <asm/scatterlist.h>
21#include <linux/crypto.h> 21#include <linux/crypto.h>
22#include "crypt_z990.h" 22#include "crypt_s390.h"
23#include "crypto_des.h" 23#include "crypto_des.h"
24 24
25#define DES_BLOCK_SIZE 8 25#define DES_BLOCK_SIZE 8
@@ -31,17 +31,17 @@
31#define DES3_192_KEY_SIZE (3 * DES_KEY_SIZE) 31#define DES3_192_KEY_SIZE (3 * DES_KEY_SIZE)
32#define DES3_192_BLOCK_SIZE DES_BLOCK_SIZE 32#define DES3_192_BLOCK_SIZE DES_BLOCK_SIZE
33 33
34struct crypt_z990_des_ctx { 34struct crypt_s390_des_ctx {
35 u8 iv[DES_BLOCK_SIZE]; 35 u8 iv[DES_BLOCK_SIZE];
36 u8 key[DES_KEY_SIZE]; 36 u8 key[DES_KEY_SIZE];
37}; 37};
38 38
39struct crypt_z990_des3_128_ctx { 39struct crypt_s390_des3_128_ctx {
40 u8 iv[DES_BLOCK_SIZE]; 40 u8 iv[DES_BLOCK_SIZE];
41 u8 key[DES3_128_KEY_SIZE]; 41 u8 key[DES3_128_KEY_SIZE];
42}; 42};
43 43
44struct crypt_z990_des3_192_ctx { 44struct crypt_s390_des3_192_ctx {
45 u8 iv[DES_BLOCK_SIZE]; 45 u8 iv[DES_BLOCK_SIZE];
46 u8 key[DES3_192_KEY_SIZE]; 46 u8 key[DES3_192_KEY_SIZE];
47}; 47};
@@ -49,7 +49,7 @@ struct crypt_z990_des3_192_ctx {
49static int 49static int
50des_setkey(void *ctx, const u8 *key, unsigned int keylen, u32 *flags) 50des_setkey(void *ctx, const u8 *key, unsigned int keylen, u32 *flags)
51{ 51{
52 struct crypt_z990_des_ctx *dctx; 52 struct crypt_s390_des_ctx *dctx;
53 int ret; 53 int ret;
54 54
55 dctx = ctx; 55 dctx = ctx;
@@ -65,26 +65,26 @@ des_setkey(void *ctx, const u8 *key, unsigned int keylen, u32 *flags)
65static void 65static void
66des_encrypt(void *ctx, u8 *dst, const u8 *src) 66des_encrypt(void *ctx, u8 *dst, const u8 *src)
67{ 67{
68 struct crypt_z990_des_ctx *dctx; 68 struct crypt_s390_des_ctx *dctx;
69 69
70 dctx = ctx; 70 dctx = ctx;
71 crypt_z990_km(KM_DEA_ENCRYPT, dctx->key, dst, src, DES_BLOCK_SIZE); 71 crypt_s390_km(KM_DEA_ENCRYPT, dctx->key, dst, src, DES_BLOCK_SIZE);
72} 72}
73 73
74static void 74static void
75des_decrypt(void *ctx, u8 *dst, const u8 *src) 75des_decrypt(void *ctx, u8 *dst, const u8 *src)
76{ 76{
77 struct crypt_z990_des_ctx *dctx; 77 struct crypt_s390_des_ctx *dctx;
78 78
79 dctx = ctx; 79 dctx = ctx;
80 crypt_z990_km(KM_DEA_DECRYPT, dctx->key, dst, src, DES_BLOCK_SIZE); 80 crypt_s390_km(KM_DEA_DECRYPT, dctx->key, dst, src, DES_BLOCK_SIZE);
81} 81}
82 82
83static struct crypto_alg des_alg = { 83static struct crypto_alg des_alg = {
84 .cra_name = "des", 84 .cra_name = "des",
85 .cra_flags = CRYPTO_ALG_TYPE_CIPHER, 85 .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
86 .cra_blocksize = DES_BLOCK_SIZE, 86 .cra_blocksize = DES_BLOCK_SIZE,
87 .cra_ctxsize = sizeof(struct crypt_z990_des_ctx), 87 .cra_ctxsize = sizeof(struct crypt_s390_des_ctx),
88 .cra_module = THIS_MODULE, 88 .cra_module = THIS_MODULE,
89 .cra_list = LIST_HEAD_INIT(des_alg.cra_list), 89 .cra_list = LIST_HEAD_INIT(des_alg.cra_list),
90 .cra_u = { .cipher = { 90 .cra_u = { .cipher = {
@@ -111,7 +111,7 @@ static int
111des3_128_setkey(void *ctx, const u8 *key, unsigned int keylen, u32 *flags) 111des3_128_setkey(void *ctx, const u8 *key, unsigned int keylen, u32 *flags)
112{ 112{
113 int i, ret; 113 int i, ret;
114 struct crypt_z990_des3_128_ctx *dctx; 114 struct crypt_s390_des3_128_ctx *dctx;
115 const u8* temp_key = key; 115 const u8* temp_key = key;
116 116
117 dctx = ctx; 117 dctx = ctx;
@@ -132,20 +132,20 @@ des3_128_setkey(void *ctx, const u8 *key, unsigned int keylen, u32 *flags)
132static void 132static void
133des3_128_encrypt(void *ctx, u8 *dst, const u8 *src) 133des3_128_encrypt(void *ctx, u8 *dst, const u8 *src)
134{ 134{
135 struct crypt_z990_des3_128_ctx *dctx; 135 struct crypt_s390_des3_128_ctx *dctx;
136 136
137 dctx = ctx; 137 dctx = ctx;
138 crypt_z990_km(KM_TDEA_128_ENCRYPT, dctx->key, dst, (void*)src, 138 crypt_s390_km(KM_TDEA_128_ENCRYPT, dctx->key, dst, (void*)src,
139 DES3_128_BLOCK_SIZE); 139 DES3_128_BLOCK_SIZE);
140} 140}
141 141
142static void 142static void
143des3_128_decrypt(void *ctx, u8 *dst, const u8 *src) 143des3_128_decrypt(void *ctx, u8 *dst, const u8 *src)
144{ 144{
145 struct crypt_z990_des3_128_ctx *dctx; 145 struct crypt_s390_des3_128_ctx *dctx;
146 146
147 dctx = ctx; 147 dctx = ctx;
148 crypt_z990_km(KM_TDEA_128_DECRYPT, dctx->key, dst, (void*)src, 148 crypt_s390_km(KM_TDEA_128_DECRYPT, dctx->key, dst, (void*)src,
149 DES3_128_BLOCK_SIZE); 149 DES3_128_BLOCK_SIZE);
150} 150}
151 151
@@ -153,7 +153,7 @@ static struct crypto_alg des3_128_alg = {
153 .cra_name = "des3_ede128", 153 .cra_name = "des3_ede128",
154 .cra_flags = CRYPTO_ALG_TYPE_CIPHER, 154 .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
155 .cra_blocksize = DES3_128_BLOCK_SIZE, 155 .cra_blocksize = DES3_128_BLOCK_SIZE,
156 .cra_ctxsize = sizeof(struct crypt_z990_des3_128_ctx), 156 .cra_ctxsize = sizeof(struct crypt_s390_des3_128_ctx),
157 .cra_module = THIS_MODULE, 157 .cra_module = THIS_MODULE,
158 .cra_list = LIST_HEAD_INIT(des3_128_alg.cra_list), 158 .cra_list = LIST_HEAD_INIT(des3_128_alg.cra_list),
159 .cra_u = { .cipher = { 159 .cra_u = { .cipher = {
@@ -181,7 +181,7 @@ static int
181des3_192_setkey(void *ctx, const u8 *key, unsigned int keylen, u32 *flags) 181des3_192_setkey(void *ctx, const u8 *key, unsigned int keylen, u32 *flags)
182{ 182{
183 int i, ret; 183 int i, ret;
184 struct crypt_z990_des3_192_ctx *dctx; 184 struct crypt_s390_des3_192_ctx *dctx;
185 const u8* temp_key; 185 const u8* temp_key;
186 186
187 dctx = ctx; 187 dctx = ctx;
@@ -206,20 +206,20 @@ des3_192_setkey(void *ctx, const u8 *key, unsigned int keylen, u32 *flags)
206static void 206static void
207des3_192_encrypt(void *ctx, u8 *dst, const u8 *src) 207des3_192_encrypt(void *ctx, u8 *dst, const u8 *src)
208{ 208{
209 struct crypt_z990_des3_192_ctx *dctx; 209 struct crypt_s390_des3_192_ctx *dctx;
210 210
211 dctx = ctx; 211 dctx = ctx;
212 crypt_z990_km(KM_TDEA_192_ENCRYPT, dctx->key, dst, (void*)src, 212 crypt_s390_km(KM_TDEA_192_ENCRYPT, dctx->key, dst, (void*)src,
213 DES3_192_BLOCK_SIZE); 213 DES3_192_BLOCK_SIZE);
214} 214}
215 215
216static void 216static void
217des3_192_decrypt(void *ctx, u8 *dst, const u8 *src) 217des3_192_decrypt(void *ctx, u8 *dst, const u8 *src)
218{ 218{
219 struct crypt_z990_des3_192_ctx *dctx; 219 struct crypt_s390_des3_192_ctx *dctx;
220 220
221 dctx = ctx; 221 dctx = ctx;
222 crypt_z990_km(KM_TDEA_192_DECRYPT, dctx->key, dst, (void*)src, 222 crypt_s390_km(KM_TDEA_192_DECRYPT, dctx->key, dst, (void*)src,
223 DES3_192_BLOCK_SIZE); 223 DES3_192_BLOCK_SIZE);
224} 224}
225 225
@@ -227,7 +227,7 @@ static struct crypto_alg des3_192_alg = {
227 .cra_name = "des3_ede", 227 .cra_name = "des3_ede",
228 .cra_flags = CRYPTO_ALG_TYPE_CIPHER, 228 .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
229 .cra_blocksize = DES3_192_BLOCK_SIZE, 229 .cra_blocksize = DES3_192_BLOCK_SIZE,
230 .cra_ctxsize = sizeof(struct crypt_z990_des3_192_ctx), 230 .cra_ctxsize = sizeof(struct crypt_s390_des3_192_ctx),
231 .cra_module = THIS_MODULE, 231 .cra_module = THIS_MODULE,
232 .cra_list = LIST_HEAD_INIT(des3_192_alg.cra_list), 232 .cra_list = LIST_HEAD_INIT(des3_192_alg.cra_list),
233 .cra_u = { .cipher = { 233 .cra_u = { .cipher = {
@@ -245,9 +245,9 @@ init(void)
245{ 245{
246 int ret; 246 int ret;
247 247
248 if (!crypt_z990_func_available(KM_DEA_ENCRYPT) || 248 if (!crypt_s390_func_available(KM_DEA_ENCRYPT) ||
249 !crypt_z990_func_available(KM_TDEA_128_ENCRYPT) || 249 !crypt_s390_func_available(KM_TDEA_128_ENCRYPT) ||
250 !crypt_z990_func_available(KM_TDEA_192_ENCRYPT)){ 250 !crypt_s390_func_available(KM_TDEA_192_ENCRYPT)){
251 return -ENOSYS; 251 return -ENOSYS;
252 } 252 }
253 253
@@ -262,7 +262,7 @@ init(void)
262 return -EEXIST; 262 return -EEXIST;
263 } 263 }
264 264
265 printk(KERN_INFO "crypt_z990: des_z990 loaded.\n"); 265 printk(KERN_INFO "crypt_s390: des_s390 loaded.\n");
266 return 0; 266 return 0;
267} 267}
268 268
diff --git a/arch/s390/crypto/sha1_z990.c b/arch/s390/crypto/sha1_s390.c
index 298174ddf5b1..98c896b86dcd 100644
--- a/arch/s390/crypto/sha1_z990.c
+++ b/arch/s390/crypto/sha1_s390.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Cryptographic API. 2 * Cryptographic API.
3 * 3 *
4 * z990 implementation of the SHA1 Secure Hash Algorithm. 4 * s390 implementation of the SHA1 Secure Hash Algorithm.
5 * 5 *
6 * Derived from cryptoapi implementation, adapted for in-place 6 * Derived from cryptoapi implementation, adapted for in-place
7 * scatterlist interface. Originally based on the public domain 7 * scatterlist interface. Originally based on the public domain
@@ -28,22 +28,22 @@
28#include <linux/crypto.h> 28#include <linux/crypto.h>
29#include <asm/scatterlist.h> 29#include <asm/scatterlist.h>
30#include <asm/byteorder.h> 30#include <asm/byteorder.h>
31#include "crypt_z990.h" 31#include "crypt_s390.h"
32 32
33#define SHA1_DIGEST_SIZE 20 33#define SHA1_DIGEST_SIZE 20
34#define SHA1_BLOCK_SIZE 64 34#define SHA1_BLOCK_SIZE 64
35 35
36struct crypt_z990_sha1_ctx { 36struct crypt_s390_sha1_ctx {
37 u64 count; 37 u64 count;
38 u32 state[5]; 38 u32 state[5];
39 u32 buf_len; 39 u32 buf_len;
40 u8 buffer[2 * SHA1_BLOCK_SIZE]; 40 u8 buffer[2 * SHA1_BLOCK_SIZE];
41}; 41};
42 42
43static void 43static void
44sha1_init(void *ctx) 44sha1_init(void *ctx)
45{ 45{
46 static const struct crypt_z990_sha1_ctx initstate = { 46 static const struct crypt_s390_sha1_ctx initstate = {
47 .state = { 47 .state = {
48 0x67452301, 48 0x67452301,
49 0xEFCDAB89, 49 0xEFCDAB89,
@@ -58,7 +58,7 @@ sha1_init(void *ctx)
58static void 58static void
59sha1_update(void *ctx, const u8 *data, unsigned int len) 59sha1_update(void *ctx, const u8 *data, unsigned int len)
60{ 60{
61 struct crypt_z990_sha1_ctx *sctx; 61 struct crypt_s390_sha1_ctx *sctx;
62 long imd_len; 62 long imd_len;
63 63
64 sctx = ctx; 64 sctx = ctx;
@@ -69,7 +69,7 @@ sha1_update(void *ctx, const u8 *data, unsigned int len)
69 //complete full block and hash 69 //complete full block and hash
70 memcpy(sctx->buffer + sctx->buf_len, data, 70 memcpy(sctx->buffer + sctx->buf_len, data,
71 SHA1_BLOCK_SIZE - sctx->buf_len); 71 SHA1_BLOCK_SIZE - sctx->buf_len);
72 crypt_z990_kimd(KIMD_SHA_1, sctx->state, sctx->buffer, 72 crypt_s390_kimd(KIMD_SHA_1, sctx->state, sctx->buffer,
73 SHA1_BLOCK_SIZE); 73 SHA1_BLOCK_SIZE);
74 data += SHA1_BLOCK_SIZE - sctx->buf_len; 74 data += SHA1_BLOCK_SIZE - sctx->buf_len;
75 len -= SHA1_BLOCK_SIZE - sctx->buf_len; 75 len -= SHA1_BLOCK_SIZE - sctx->buf_len;
@@ -79,7 +79,7 @@ sha1_update(void *ctx, const u8 *data, unsigned int len)
79 //rest of data contains full blocks? 79 //rest of data contains full blocks?
80 imd_len = len & ~0x3ful; 80 imd_len = len & ~0x3ful;
81 if (imd_len){ 81 if (imd_len){
82 crypt_z990_kimd(KIMD_SHA_1, sctx->state, data, imd_len); 82 crypt_s390_kimd(KIMD_SHA_1, sctx->state, data, imd_len);
83 data += imd_len; 83 data += imd_len;
84 len -= imd_len; 84 len -= imd_len;
85 } 85 }
@@ -92,7 +92,7 @@ sha1_update(void *ctx, const u8 *data, unsigned int len)
92 92
93 93
94static void 94static void
95pad_message(struct crypt_z990_sha1_ctx* sctx) 95pad_message(struct crypt_s390_sha1_ctx* sctx)
96{ 96{
97 int index; 97 int index;
98 98
@@ -113,11 +113,11 @@ pad_message(struct crypt_z990_sha1_ctx* sctx)
113static void 113static void
114sha1_final(void* ctx, u8 *out) 114sha1_final(void* ctx, u8 *out)
115{ 115{
116 struct crypt_z990_sha1_ctx *sctx = ctx; 116 struct crypt_s390_sha1_ctx *sctx = ctx;
117 117
118 //must perform manual padding 118 //must perform manual padding
119 pad_message(sctx); 119 pad_message(sctx);
120 crypt_z990_kimd(KIMD_SHA_1, sctx->state, sctx->buffer, sctx->buf_len); 120 crypt_s390_kimd(KIMD_SHA_1, sctx->state, sctx->buffer, sctx->buf_len);
121 //copy digest to out 121 //copy digest to out
122 memcpy(out, sctx->state, SHA1_DIGEST_SIZE); 122 memcpy(out, sctx->state, SHA1_DIGEST_SIZE);
123 /* Wipe context */ 123 /* Wipe context */
@@ -128,7 +128,7 @@ static struct crypto_alg alg = {
128 .cra_name = "sha1", 128 .cra_name = "sha1",
129 .cra_flags = CRYPTO_ALG_TYPE_DIGEST, 129 .cra_flags = CRYPTO_ALG_TYPE_DIGEST,
130 .cra_blocksize = SHA1_BLOCK_SIZE, 130 .cra_blocksize = SHA1_BLOCK_SIZE,
131 .cra_ctxsize = sizeof(struct crypt_z990_sha1_ctx), 131 .cra_ctxsize = sizeof(struct crypt_s390_sha1_ctx),
132 .cra_module = THIS_MODULE, 132 .cra_module = THIS_MODULE,
133 .cra_list = LIST_HEAD_INIT(alg.cra_list), 133 .cra_list = LIST_HEAD_INIT(alg.cra_list),
134 .cra_u = { .digest = { 134 .cra_u = { .digest = {
@@ -143,10 +143,10 @@ init(void)
143{ 143{
144 int ret = -ENOSYS; 144 int ret = -ENOSYS;
145 145
146 if (crypt_z990_func_available(KIMD_SHA_1)){ 146 if (crypt_s390_func_available(KIMD_SHA_1)){
147 ret = crypto_register_alg(&alg); 147 ret = crypto_register_alg(&alg);
148 if (ret == 0){ 148 if (ret == 0){
149 printk(KERN_INFO "crypt_z990: sha1_z990 loaded.\n"); 149 printk(KERN_INFO "crypt_s390: sha1_s390 loaded.\n");
150 } 150 }
151 } 151 }
152 return ret; 152 return ret;
diff --git a/arch/s390/crypto/sha256_s390.c b/arch/s390/crypto/sha256_s390.c
new file mode 100644
index 000000000000..b75bdbd476c7
--- /dev/null
+++ b/arch/s390/crypto/sha256_s390.c
@@ -0,0 +1,151 @@
1/*
2 * Cryptographic API.
3 *
4 * s390 implementation of the SHA256 Secure Hash Algorithm.
5 *
6 * s390 Version:
7 * Copyright (C) 2005 IBM Deutschland GmbH, IBM Corporation
8 * Author(s): Jan Glauber (jang@de.ibm.com)
9 *
10 * Derived from "crypto/sha256.c"
11 * and "arch/s390/crypto/sha1_s390.c"
12 *
13 * This program is free software; you can redistribute it and/or modify it
14 * under the terms of the GNU General Public License as published by the Free
15 * Software Foundation; either version 2 of the License, or (at your option)
16 * any later version.
17 *
18 */
19#include <linux/init.h>
20#include <linux/module.h>
21#include <linux/crypto.h>
22
23#include "crypt_s390.h"
24
25#define SHA256_DIGEST_SIZE 32
26#define SHA256_BLOCK_SIZE 64
27
28struct s390_sha256_ctx {
29 u64 count;
30 u32 state[8];
31 u8 buf[2 * SHA256_BLOCK_SIZE];
32};
33
34static void sha256_init(void *ctx)
35{
36 struct s390_sha256_ctx *sctx = ctx;
37
38 sctx->state[0] = 0x6a09e667;
39 sctx->state[1] = 0xbb67ae85;
40 sctx->state[2] = 0x3c6ef372;
41 sctx->state[3] = 0xa54ff53a;
42 sctx->state[4] = 0x510e527f;
43 sctx->state[5] = 0x9b05688c;
44 sctx->state[6] = 0x1f83d9ab;
45 sctx->state[7] = 0x5be0cd19;
46 sctx->count = 0;
47 memset(sctx->buf, 0, sizeof(sctx->buf));
48}
49
50static void sha256_update(void *ctx, const u8 *data, unsigned int len)
51{
52 struct s390_sha256_ctx *sctx = ctx;
53 unsigned int index;
54
55 /* how much is already in the buffer? */
56 index = sctx->count / 8 & 0x3f;
57
58 /* update message bit length */
59 sctx->count += len * 8;
60
61 /* process one block */
62 if ((index + len) >= SHA256_BLOCK_SIZE) {
63 memcpy(sctx->buf + index, data, SHA256_BLOCK_SIZE - index);
64 crypt_s390_kimd(KIMD_SHA_256, sctx->state, sctx->buf,
65 SHA256_BLOCK_SIZE);
66 data += SHA256_BLOCK_SIZE - index;
67 len -= SHA256_BLOCK_SIZE - index;
68 }
69
70 /* anything left? */
71 if (len)
72 memcpy(sctx->buf + index , data, len);
73}
74
75static void pad_message(struct s390_sha256_ctx* sctx)
76{
77 int index, end;
78
79 index = sctx->count / 8 & 0x3f;
80 end = index < 56 ? SHA256_BLOCK_SIZE : 2 * SHA256_BLOCK_SIZE;
81
82 /* start pad with 1 */
83 sctx->buf[index] = 0x80;
84
85 /* pad with zeros */
86 index++;
87 memset(sctx->buf + index, 0x00, end - index - 8);
88
89 /* append message length */
90 memcpy(sctx->buf + end - 8, &sctx->count, sizeof sctx->count);
91
92 sctx->count = end * 8;
93}
94
95/* Add padding and return the message digest */
96static void sha256_final(void* ctx, u8 *out)
97{
98 struct s390_sha256_ctx *sctx = ctx;
99
100 /* must perform manual padding */
101 pad_message(sctx);
102
103 crypt_s390_kimd(KIMD_SHA_256, sctx->state, sctx->buf,
104 sctx->count / 8);
105
106 /* copy digest to out */
107 memcpy(out, sctx->state, SHA256_DIGEST_SIZE);
108
109 /* wipe context */
110 memset(sctx, 0, sizeof *sctx);
111}
112
113static struct crypto_alg alg = {
114 .cra_name = "sha256",
115 .cra_flags = CRYPTO_ALG_TYPE_DIGEST,
116 .cra_blocksize = SHA256_BLOCK_SIZE,
117 .cra_ctxsize = sizeof(struct s390_sha256_ctx),
118 .cra_module = THIS_MODULE,
119 .cra_list = LIST_HEAD_INIT(alg.cra_list),
120 .cra_u = { .digest = {
121 .dia_digestsize = SHA256_DIGEST_SIZE,
122 .dia_init = sha256_init,
123 .dia_update = sha256_update,
124 .dia_final = sha256_final } }
125};
126
127static int init(void)
128{
129 int ret;
130
131 if (!crypt_s390_func_available(KIMD_SHA_256))
132 return -ENOSYS;
133
134 ret = crypto_register_alg(&alg);
135 if (ret != 0)
136 printk(KERN_INFO "crypt_s390: sha256_s390 couldn't be loaded.");
137 return ret;
138}
139
140static void __exit fini(void)
141{
142 crypto_unregister_alg(&alg);
143}
144
145module_init(init);
146module_exit(fini);
147
148MODULE_ALIAS("sha256");
149
150MODULE_LICENSE("GPL");
151MODULE_DESCRIPTION("SHA256 Secure Hash Algorithm");
diff --git a/arch/s390/defconfig b/arch/s390/defconfig
index 45d44c6bb39d..7d23edc6facb 100644
--- a/arch/s390/defconfig
+++ b/arch/s390/defconfig
@@ -1,12 +1,12 @@
1# 1#
2# Automatically generated make config: don't edit 2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.14-rc1 3# Linux kernel version: 2.6.15-rc2
4# Wed Sep 14 16:46:19 2005 4# Mon Nov 21 13:51:30 2005
5# 5#
6CONFIG_MMU=y 6CONFIG_MMU=y
7CONFIG_RWSEM_XCHGADD_ALGORITHM=y 7CONFIG_RWSEM_XCHGADD_ALGORITHM=y
8CONFIG_GENERIC_CALIBRATE_DELAY=y 8CONFIG_GENERIC_CALIBRATE_DELAY=y
9CONFIG_ARCH_S390=y 9CONFIG_S390=y
10CONFIG_UID16=y 10CONFIG_UID16=y
11 11
12# 12#
@@ -65,15 +65,31 @@ CONFIG_KMOD=y
65CONFIG_STOP_MACHINE=y 65CONFIG_STOP_MACHINE=y
66 66
67# 67#
68# Block layer
69#
70# CONFIG_LBD is not set
71
72#
73# IO Schedulers
74#
75CONFIG_IOSCHED_NOOP=y
76CONFIG_IOSCHED_AS=y
77CONFIG_IOSCHED_DEADLINE=y
78CONFIG_IOSCHED_CFQ=y
79CONFIG_DEFAULT_AS=y
80# CONFIG_DEFAULT_DEADLINE is not set
81# CONFIG_DEFAULT_CFQ is not set
82# CONFIG_DEFAULT_NOOP is not set
83CONFIG_DEFAULT_IOSCHED="anticipatory"
84
85#
68# Base setup 86# Base setup
69# 87#
70 88
71# 89#
72# Processor type and features 90# Processor type and features
73# 91#
74# CONFIG_ARCH_S390X is not set
75# CONFIG_64BIT is not set 92# CONFIG_64BIT is not set
76CONFIG_ARCH_S390_31=y
77CONFIG_SMP=y 93CONFIG_SMP=y
78CONFIG_NR_CPUS=32 94CONFIG_NR_CPUS=32
79CONFIG_HOTPLUG_CPU=y 95CONFIG_HOTPLUG_CPU=y
@@ -97,6 +113,7 @@ CONFIG_FLATMEM_MANUAL=y
97CONFIG_FLATMEM=y 113CONFIG_FLATMEM=y
98CONFIG_FLAT_NODE_MEM_MAP=y 114CONFIG_FLAT_NODE_MEM_MAP=y
99# CONFIG_SPARSEMEM_STATIC is not set 115# CONFIG_SPARSEMEM_STATIC is not set
116CONFIG_SPLIT_PTLOCK_CPUS=4
100 117
101# 118#
102# I/O subsystem configuration 119# I/O subsystem configuration
@@ -188,10 +205,18 @@ CONFIG_IPV6=y
188# CONFIG_NET_DIVERT is not set 205# CONFIG_NET_DIVERT is not set
189# CONFIG_ECONET is not set 206# CONFIG_ECONET is not set
190# CONFIG_WAN_ROUTER is not set 207# CONFIG_WAN_ROUTER is not set
208
209#
210# QoS and/or fair queueing
211#
191CONFIG_NET_SCHED=y 212CONFIG_NET_SCHED=y
192CONFIG_NET_SCH_CLK_JIFFIES=y 213CONFIG_NET_SCH_CLK_JIFFIES=y
193# CONFIG_NET_SCH_CLK_GETTIMEOFDAY is not set 214# CONFIG_NET_SCH_CLK_GETTIMEOFDAY is not set
194# CONFIG_NET_SCH_CLK_CPU is not set 215# CONFIG_NET_SCH_CLK_CPU is not set
216
217#
218# Queueing/Scheduling
219#
195CONFIG_NET_SCH_CBQ=m 220CONFIG_NET_SCH_CBQ=m
196# CONFIG_NET_SCH_HTB is not set 221# CONFIG_NET_SCH_HTB is not set
197# CONFIG_NET_SCH_HFSC is not set 222# CONFIG_NET_SCH_HFSC is not set
@@ -204,8 +229,10 @@ CONFIG_NET_SCH_GRED=m
204CONFIG_NET_SCH_DSMARK=m 229CONFIG_NET_SCH_DSMARK=m
205# CONFIG_NET_SCH_NETEM is not set 230# CONFIG_NET_SCH_NETEM is not set
206# CONFIG_NET_SCH_INGRESS is not set 231# CONFIG_NET_SCH_INGRESS is not set
207CONFIG_NET_QOS=y 232
208CONFIG_NET_ESTIMATOR=y 233#
234# Classification
235#
209CONFIG_NET_CLS=y 236CONFIG_NET_CLS=y
210# CONFIG_NET_CLS_BASIC is not set 237# CONFIG_NET_CLS_BASIC is not set
211CONFIG_NET_CLS_TCINDEX=m 238CONFIG_NET_CLS_TCINDEX=m
@@ -214,18 +241,18 @@ CONFIG_NET_CLS_ROUTE=y
214CONFIG_NET_CLS_FW=m 241CONFIG_NET_CLS_FW=m
215CONFIG_NET_CLS_U32=m 242CONFIG_NET_CLS_U32=m
216# CONFIG_CLS_U32_PERF is not set 243# CONFIG_CLS_U32_PERF is not set
217# CONFIG_NET_CLS_IND is not set
218CONFIG_NET_CLS_RSVP=m 244CONFIG_NET_CLS_RSVP=m
219CONFIG_NET_CLS_RSVP6=m 245CONFIG_NET_CLS_RSVP6=m
220# CONFIG_NET_EMATCH is not set 246# CONFIG_NET_EMATCH is not set
221# CONFIG_NET_CLS_ACT is not set 247# CONFIG_NET_CLS_ACT is not set
222CONFIG_NET_CLS_POLICE=y 248CONFIG_NET_CLS_POLICE=y
249# CONFIG_NET_CLS_IND is not set
250CONFIG_NET_ESTIMATOR=y
223 251
224# 252#
225# Network testing 253# Network testing
226# 254#
227# CONFIG_NET_PKTGEN is not set 255# CONFIG_NET_PKTGEN is not set
228# CONFIG_NETFILTER_NETLINK is not set
229# CONFIG_HAMRADIO is not set 256# CONFIG_HAMRADIO is not set
230# CONFIG_IRDA is not set 257# CONFIG_IRDA is not set
231# CONFIG_BT is not set 258# CONFIG_BT is not set
@@ -276,6 +303,7 @@ CONFIG_SCSI_FC_ATTRS=y
276# 303#
277# SCSI low-level drivers 304# SCSI low-level drivers
278# 305#
306# CONFIG_ISCSI_TCP is not set
279# CONFIG_SCSI_SATA is not set 307# CONFIG_SCSI_SATA is not set
280# CONFIG_SCSI_DEBUG is not set 308# CONFIG_SCSI_DEBUG is not set
281CONFIG_ZFCP=y 309CONFIG_ZFCP=y
@@ -292,7 +320,6 @@ CONFIG_BLK_DEV_RAM=y
292CONFIG_BLK_DEV_RAM_COUNT=16 320CONFIG_BLK_DEV_RAM_COUNT=16
293CONFIG_BLK_DEV_RAM_SIZE=4096 321CONFIG_BLK_DEV_RAM_SIZE=4096
294CONFIG_BLK_DEV_INITRD=y 322CONFIG_BLK_DEV_INITRD=y
295# CONFIG_LBD is not set
296# CONFIG_CDROM_PKTCDVD is not set 323# CONFIG_CDROM_PKTCDVD is not set
297 324
298# 325#
@@ -305,15 +332,8 @@ CONFIG_DASD_PROFILE=y
305CONFIG_DASD_ECKD=y 332CONFIG_DASD_ECKD=y
306CONFIG_DASD_FBA=y 333CONFIG_DASD_FBA=y
307CONFIG_DASD_DIAG=y 334CONFIG_DASD_DIAG=y
335CONFIG_DASD_EER=m
308# CONFIG_DASD_CMB is not set 336# CONFIG_DASD_CMB is not set
309
310#
311# IO Schedulers
312#
313CONFIG_IOSCHED_NOOP=y
314CONFIG_IOSCHED_AS=y
315CONFIG_IOSCHED_DEADLINE=y
316CONFIG_IOSCHED_CFQ=y
317# CONFIG_ATA_OVER_ETH is not set 337# CONFIG_ATA_OVER_ETH is not set
318 338
319# 339#
@@ -378,7 +398,6 @@ CONFIG_S390_TAPE_34XX=m
378# CONFIG_VMLOGRDR is not set 398# CONFIG_VMLOGRDR is not set
379# CONFIG_VMCP is not set 399# CONFIG_VMCP is not set
380# CONFIG_MONREADER is not set 400# CONFIG_MONREADER is not set
381# CONFIG_DCSS_SHM is not set
382 401
383# 402#
384# Cryptographic devices 403# Cryptographic devices
@@ -593,6 +612,8 @@ CONFIG_DEBUG_PREEMPT=y
593# CONFIG_DEBUG_KOBJECT is not set 612# CONFIG_DEBUG_KOBJECT is not set
594# CONFIG_DEBUG_INFO is not set 613# CONFIG_DEBUG_INFO is not set
595CONFIG_DEBUG_FS=y 614CONFIG_DEBUG_FS=y
615# CONFIG_DEBUG_VM is not set
616# CONFIG_RCU_TORTURE_TEST is not set
596 617
597# 618#
598# Security options 619# Security options
@@ -609,17 +630,19 @@ CONFIG_CRYPTO=y
609# CONFIG_CRYPTO_MD4 is not set 630# CONFIG_CRYPTO_MD4 is not set
610# CONFIG_CRYPTO_MD5 is not set 631# CONFIG_CRYPTO_MD5 is not set
611# CONFIG_CRYPTO_SHA1 is not set 632# CONFIG_CRYPTO_SHA1 is not set
612# CONFIG_CRYPTO_SHA1_Z990 is not set 633# CONFIG_CRYPTO_SHA1_S390 is not set
613# CONFIG_CRYPTO_SHA256 is not set 634# CONFIG_CRYPTO_SHA256 is not set
635# CONFIG_CRYPTO_SHA256_S390 is not set
614# CONFIG_CRYPTO_SHA512 is not set 636# CONFIG_CRYPTO_SHA512 is not set
615# CONFIG_CRYPTO_WP512 is not set 637# CONFIG_CRYPTO_WP512 is not set
616# CONFIG_CRYPTO_TGR192 is not set 638# CONFIG_CRYPTO_TGR192 is not set
617# CONFIG_CRYPTO_DES is not set 639# CONFIG_CRYPTO_DES is not set
618# CONFIG_CRYPTO_DES_Z990 is not set 640# CONFIG_CRYPTO_DES_S390 is not set
619# CONFIG_CRYPTO_BLOWFISH is not set 641# CONFIG_CRYPTO_BLOWFISH is not set
620# CONFIG_CRYPTO_TWOFISH is not set 642# CONFIG_CRYPTO_TWOFISH is not set
621# CONFIG_CRYPTO_SERPENT is not set 643# CONFIG_CRYPTO_SERPENT is not set
622# CONFIG_CRYPTO_AES is not set 644# CONFIG_CRYPTO_AES is not set
645# CONFIG_CRYPTO_AES_S390 is not set
623# CONFIG_CRYPTO_CAST5 is not set 646# CONFIG_CRYPTO_CAST5 is not set
624# CONFIG_CRYPTO_CAST6 is not set 647# CONFIG_CRYPTO_CAST6 is not set
625# CONFIG_CRYPTO_TEA is not set 648# CONFIG_CRYPTO_TEA is not set
diff --git a/arch/s390/kernel/Makefile b/arch/s390/kernel/Makefile
index 7434c32bc631..4865e4b49464 100644
--- a/arch/s390/kernel/Makefile
+++ b/arch/s390/kernel/Makefile
@@ -8,31 +8,26 @@ obj-y := bitmap.o traps.o time.o process.o \
8 setup.o sys_s390.o ptrace.o signal.o cpcmd.o ebcdic.o \ 8 setup.o sys_s390.o ptrace.o signal.o cpcmd.o ebcdic.o \
9 semaphore.o s390_ext.o debug.o profile.o irq.o reipl_diag.o 9 semaphore.o s390_ext.o debug.o profile.o irq.o reipl_diag.o
10 10
11obj-y += $(if $(CONFIG_64BIT),entry64.o,entry.o)
12obj-y += $(if $(CONFIG_64BIT),reipl64.o,reipl.o)
13
11extra-y += head.o init_task.o vmlinux.lds 14extra-y += head.o init_task.o vmlinux.lds
12 15
13obj-$(CONFIG_MODULES) += s390_ksyms.o module.o 16obj-$(CONFIG_MODULES) += s390_ksyms.o module.o
14obj-$(CONFIG_SMP) += smp.o 17obj-$(CONFIG_SMP) += smp.o
15 18
16obj-$(CONFIG_S390_SUPPORT) += compat_linux.o compat_signal.o \ 19obj-$(CONFIG_COMPAT) += compat_linux.o compat_signal.o \
17 compat_ioctl.o compat_wrapper.o \ 20 compat_ioctl.o compat_wrapper.o \
18 compat_exec_domain.o 21 compat_exec_domain.o
19obj-$(CONFIG_BINFMT_ELF32) += binfmt_elf32.o 22obj-$(CONFIG_BINFMT_ELF32) += binfmt_elf32.o
20 23
21obj-$(CONFIG_ARCH_S390_31) += entry.o reipl.o
22obj-$(CONFIG_ARCH_S390X) += entry64.o reipl64.o
23
24obj-$(CONFIG_VIRT_TIMER) += vtime.o 24obj-$(CONFIG_VIRT_TIMER) += vtime.o
25 25
26# Kexec part 26# Kexec part
27S390_KEXEC_OBJS := machine_kexec.o crash.o 27S390_KEXEC_OBJS := machine_kexec.o crash.o
28ifeq ($(CONFIG_ARCH_S390X),y) 28S390_KEXEC_OBJS += $(if $(CONFIG_64BIT),relocate_kernel64.o,relocate_kernel.o)
29S390_KEXEC_OBJS += relocate_kernel64.o
30else
31S390_KEXEC_OBJS += relocate_kernel.o
32endif
33obj-$(CONFIG_KEXEC) += $(S390_KEXEC_OBJS) 29obj-$(CONFIG_KEXEC) += $(S390_KEXEC_OBJS)
34 30
35
36# 31#
37# This is just to get the dependencies... 32# This is just to get the dependencies...
38# 33#
diff --git a/arch/s390/kernel/compat_linux.c b/arch/s390/kernel/compat_linux.c
index ed877d0f27e6..41b197a3f3a3 100644
--- a/arch/s390/kernel/compat_linux.c
+++ b/arch/s390/kernel/compat_linux.c
@@ -279,7 +279,7 @@ asmlinkage long sys32_getegid16(void)
279 279
280static inline long get_tv32(struct timeval *o, struct compat_timeval *i) 280static inline long get_tv32(struct timeval *o, struct compat_timeval *i)
281{ 281{
282 return (!access_ok(VERIFY_READ, tv32, sizeof(*tv32)) || 282 return (!access_ok(VERIFY_READ, o, sizeof(*o)) ||
283 (__get_user(o->tv_sec, &i->tv_sec) || 283 (__get_user(o->tv_sec, &i->tv_sec) ||
284 __get_user(o->tv_usec, &i->tv_usec))); 284 __get_user(o->tv_usec, &i->tv_usec)));
285} 285}
diff --git a/arch/s390/kernel/compat_signal.c b/arch/s390/kernel/compat_signal.c
index 4ff6808456ea..fa2b3bc22f20 100644
--- a/arch/s390/kernel/compat_signal.c
+++ b/arch/s390/kernel/compat_signal.c
@@ -467,8 +467,6 @@ asmlinkage long sys32_rt_sigreturn(struct pt_regs *regs)
467 if (err) 467 if (err)
468 goto badframe; 468 goto badframe;
469 469
470 /* It is more difficult to avoid calling this function than to
471 call it and ignore errors. */
472 set_fs (KERNEL_DS); 470 set_fs (KERNEL_DS);
473 do_sigaltstack((stack_t __user *)&st, NULL, regs->gprs[15]); 471 do_sigaltstack((stack_t __user *)&st, NULL, regs->gprs[15]);
474 set_fs (old_fs); 472 set_fs (old_fs);
diff --git a/arch/s390/kernel/cpcmd.c b/arch/s390/kernel/cpcmd.c
index d47fecb42cc5..4ef44e536b2c 100644
--- a/arch/s390/kernel/cpcmd.c
+++ b/arch/s390/kernel/cpcmd.c
@@ -39,7 +39,7 @@ int __cpcmd(const char *cmd, char *response, int rlen, int *response_code)
39 39
40 if (response != NULL && rlen > 0) { 40 if (response != NULL && rlen > 0) {
41 memset(response, 0, rlen); 41 memset(response, 0, rlen);
42#ifndef CONFIG_ARCH_S390X 42#ifndef CONFIG_64BIT
43 asm volatile ( "lra 2,0(%2)\n" 43 asm volatile ( "lra 2,0(%2)\n"
44 "lr 4,%3\n" 44 "lr 4,%3\n"
45 "o 4,%6\n" 45 "o 4,%6\n"
@@ -55,7 +55,7 @@ int __cpcmd(const char *cmd, char *response, int rlen, int *response_code)
55 : "a" (cpcmd_buf), "d" (cmdlen), 55 : "a" (cpcmd_buf), "d" (cmdlen),
56 "a" (response), "d" (rlen), "m" (mask) 56 "a" (response), "d" (rlen), "m" (mask)
57 : "cc", "2", "3", "4", "5" ); 57 : "cc", "2", "3", "4", "5" );
58#else /* CONFIG_ARCH_S390X */ 58#else /* CONFIG_64BIT */
59 asm volatile ( "lrag 2,0(%2)\n" 59 asm volatile ( "lrag 2,0(%2)\n"
60 "lgr 4,%3\n" 60 "lgr 4,%3\n"
61 "o 4,%6\n" 61 "o 4,%6\n"
@@ -73,11 +73,11 @@ int __cpcmd(const char *cmd, char *response, int rlen, int *response_code)
73 : "a" (cpcmd_buf), "d" (cmdlen), 73 : "a" (cpcmd_buf), "d" (cmdlen),
74 "a" (response), "d" (rlen), "m" (mask) 74 "a" (response), "d" (rlen), "m" (mask)
75 : "cc", "2", "3", "4", "5" ); 75 : "cc", "2", "3", "4", "5" );
76#endif /* CONFIG_ARCH_S390X */ 76#endif /* CONFIG_64BIT */
77 EBCASC(response, rlen); 77 EBCASC(response, rlen);
78 } else { 78 } else {
79 return_len = 0; 79 return_len = 0;
80#ifndef CONFIG_ARCH_S390X 80#ifndef CONFIG_64BIT
81 asm volatile ( "lra 2,0(%1)\n" 81 asm volatile ( "lra 2,0(%1)\n"
82 "lr 3,%2\n" 82 "lr 3,%2\n"
83 "diag 2,3,0x8\n" 83 "diag 2,3,0x8\n"
@@ -85,7 +85,7 @@ int __cpcmd(const char *cmd, char *response, int rlen, int *response_code)
85 : "=d" (return_code) 85 : "=d" (return_code)
86 : "a" (cpcmd_buf), "d" (cmdlen) 86 : "a" (cpcmd_buf), "d" (cmdlen)
87 : "2", "3" ); 87 : "2", "3" );
88#else /* CONFIG_ARCH_S390X */ 88#else /* CONFIG_64BIT */
89 asm volatile ( "lrag 2,0(%1)\n" 89 asm volatile ( "lrag 2,0(%1)\n"
90 "lgr 3,%2\n" 90 "lgr 3,%2\n"
91 "sam31\n" 91 "sam31\n"
@@ -95,7 +95,7 @@ int __cpcmd(const char *cmd, char *response, int rlen, int *response_code)
95 : "=d" (return_code) 95 : "=d" (return_code)
96 : "a" (cpcmd_buf), "d" (cmdlen) 96 : "a" (cpcmd_buf), "d" (cmdlen)
97 : "2", "3" ); 97 : "2", "3" );
98#endif /* CONFIG_ARCH_S390X */ 98#endif /* CONFIG_64BIT */
99 } 99 }
100 spin_unlock_irqrestore(&cpcmd_lock, flags); 100 spin_unlock_irqrestore(&cpcmd_lock, flags);
101 if (response_code != NULL) 101 if (response_code != NULL)
@@ -105,7 +105,7 @@ int __cpcmd(const char *cmd, char *response, int rlen, int *response_code)
105 105
106EXPORT_SYMBOL(__cpcmd); 106EXPORT_SYMBOL(__cpcmd);
107 107
108#ifdef CONFIG_ARCH_S390X 108#ifdef CONFIG_64BIT
109int cpcmd(const char *cmd, char *response, int rlen, int *response_code) 109int cpcmd(const char *cmd, char *response, int rlen, int *response_code)
110{ 110{
111 char *lowbuf; 111 char *lowbuf;
@@ -129,4 +129,4 @@ int cpcmd(const char *cmd, char *response, int rlen, int *response_code)
129} 129}
130 130
131EXPORT_SYMBOL(cpcmd); 131EXPORT_SYMBOL(cpcmd);
132#endif /* CONFIG_ARCH_S390X */ 132#endif /* CONFIG_64BIT */
diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S
index 4eb71ffcf484..369ab4413ec7 100644
--- a/arch/s390/kernel/entry64.S
+++ b/arch/s390/kernel/entry64.S
@@ -213,7 +213,7 @@ sysc_nr_ok:
213 mvc SP_ARGS(8,%r15),SP_R7(%r15) 213 mvc SP_ARGS(8,%r15),SP_R7(%r15)
214sysc_do_restart: 214sysc_do_restart:
215 larl %r10,sys_call_table 215 larl %r10,sys_call_table
216#ifdef CONFIG_S390_SUPPORT 216#ifdef CONFIG_COMPAT
217 tm __TI_flags+5(%r9),(_TIF_31BIT>>16) # running in 31 bit mode ? 217 tm __TI_flags+5(%r9),(_TIF_31BIT>>16) # running in 31 bit mode ?
218 jno sysc_noemu 218 jno sysc_noemu
219 larl %r10,sys_call_table_emu # use 31 bit emulation system calls 219 larl %r10,sys_call_table_emu # use 31 bit emulation system calls
@@ -361,7 +361,7 @@ sys_clone_glue:
361 la %r2,SP_PTREGS(%r15) # load pt_regs 361 la %r2,SP_PTREGS(%r15) # load pt_regs
362 jg sys_clone # branch to sys_clone 362 jg sys_clone # branch to sys_clone
363 363
364#ifdef CONFIG_S390_SUPPORT 364#ifdef CONFIG_COMPAT
365sys32_clone_glue: 365sys32_clone_glue:
366 la %r2,SP_PTREGS(%r15) # load pt_regs 366 la %r2,SP_PTREGS(%r15) # load pt_regs
367 jg sys32_clone # branch to sys32_clone 367 jg sys32_clone # branch to sys32_clone
@@ -383,7 +383,7 @@ sys_execve_glue:
383 bnz 0(%r12) # it did fail -> store result in gpr2 383 bnz 0(%r12) # it did fail -> store result in gpr2
384 b 6(%r12) # SKIP STG 2,SP_R2(15) in 384 b 6(%r12) # SKIP STG 2,SP_R2(15) in
385 # system_call/sysc_tracesys 385 # system_call/sysc_tracesys
386#ifdef CONFIG_S390_SUPPORT 386#ifdef CONFIG_COMPAT
387sys32_execve_glue: 387sys32_execve_glue:
388 la %r2,SP_PTREGS(%r15) # load pt_regs 388 la %r2,SP_PTREGS(%r15) # load pt_regs
389 lgr %r12,%r14 # save return address 389 lgr %r12,%r14 # save return address
@@ -398,7 +398,7 @@ sys_sigreturn_glue:
398 la %r2,SP_PTREGS(%r15) # load pt_regs as parameter 398 la %r2,SP_PTREGS(%r15) # load pt_regs as parameter
399 jg sys_sigreturn # branch to sys_sigreturn 399 jg sys_sigreturn # branch to sys_sigreturn
400 400
401#ifdef CONFIG_S390_SUPPORT 401#ifdef CONFIG_COMPAT
402sys32_sigreturn_glue: 402sys32_sigreturn_glue:
403 la %r2,SP_PTREGS(%r15) # load pt_regs as parameter 403 la %r2,SP_PTREGS(%r15) # load pt_regs as parameter
404 jg sys32_sigreturn # branch to sys32_sigreturn 404 jg sys32_sigreturn # branch to sys32_sigreturn
@@ -408,7 +408,7 @@ sys_rt_sigreturn_glue:
408 la %r2,SP_PTREGS(%r15) # load pt_regs as parameter 408 la %r2,SP_PTREGS(%r15) # load pt_regs as parameter
409 jg sys_rt_sigreturn # branch to sys_sigreturn 409 jg sys_rt_sigreturn # branch to sys_sigreturn
410 410
411#ifdef CONFIG_S390_SUPPORT 411#ifdef CONFIG_COMPAT
412sys32_rt_sigreturn_glue: 412sys32_rt_sigreturn_glue:
413 la %r2,SP_PTREGS(%r15) # load pt_regs as parameter 413 la %r2,SP_PTREGS(%r15) # load pt_regs as parameter
414 jg sys32_rt_sigreturn # branch to sys32_sigreturn 414 jg sys32_rt_sigreturn # branch to sys32_sigreturn
@@ -429,7 +429,7 @@ sys_sigsuspend_glue:
429 la %r14,6(%r14) # skip store of return value 429 la %r14,6(%r14) # skip store of return value
430 jg sys_sigsuspend # branch to sys_sigsuspend 430 jg sys_sigsuspend # branch to sys_sigsuspend
431 431
432#ifdef CONFIG_S390_SUPPORT 432#ifdef CONFIG_COMPAT
433sys32_sigsuspend_glue: 433sys32_sigsuspend_glue:
434 llgfr %r4,%r4 # unsigned long 434 llgfr %r4,%r4 # unsigned long
435 lgr %r5,%r4 # move mask back 435 lgr %r5,%r4 # move mask back
@@ -449,7 +449,7 @@ sys_rt_sigsuspend_glue:
449 la %r14,6(%r14) # skip store of return value 449 la %r14,6(%r14) # skip store of return value
450 jg sys_rt_sigsuspend # branch to sys_rt_sigsuspend 450 jg sys_rt_sigsuspend # branch to sys_rt_sigsuspend
451 451
452#ifdef CONFIG_S390_SUPPORT 452#ifdef CONFIG_COMPAT
453sys32_rt_sigsuspend_glue: 453sys32_rt_sigsuspend_glue:
454 llgfr %r3,%r3 # size_t 454 llgfr %r3,%r3 # size_t
455 lgr %r4,%r3 # move sigsetsize parameter 455 lgr %r4,%r3 # move sigsetsize parameter
@@ -464,7 +464,7 @@ sys_sigaltstack_glue:
464 la %r4,SP_PTREGS(%r15) # load pt_regs as parameter 464 la %r4,SP_PTREGS(%r15) # load pt_regs as parameter
465 jg sys_sigaltstack # branch to sys_sigreturn 465 jg sys_sigaltstack # branch to sys_sigreturn
466 466
467#ifdef CONFIG_S390_SUPPORT 467#ifdef CONFIG_COMPAT
468sys32_sigaltstack_glue: 468sys32_sigaltstack_glue:
469 la %r4,SP_PTREGS(%r15) # load pt_regs as parameter 469 la %r4,SP_PTREGS(%r15) # load pt_regs as parameter
470 jg sys32_sigaltstack_wrapper # branch to sys_sigreturn 470 jg sys32_sigaltstack_wrapper # branch to sys_sigreturn
@@ -1009,7 +1009,7 @@ sys_call_table:
1009#include "syscalls.S" 1009#include "syscalls.S"
1010#undef SYSCALL 1010#undef SYSCALL
1011 1011
1012#ifdef CONFIG_S390_SUPPORT 1012#ifdef CONFIG_COMPAT
1013 1013
1014#define SYSCALL(esa,esame,emu) .long emu 1014#define SYSCALL(esa,esame,emu) .long emu
1015 .globl sys_call_table_emu 1015 .globl sys_call_table_emu
diff --git a/arch/s390/kernel/head.S b/arch/s390/kernel/head.S
index d31a97c89f68..ea88d066bf04 100644
--- a/arch/s390/kernel/head.S
+++ b/arch/s390/kernel/head.S
@@ -30,7 +30,7 @@
30#include <asm/thread_info.h> 30#include <asm/thread_info.h>
31#include <asm/page.h> 31#include <asm/page.h>
32 32
33#ifdef CONFIG_ARCH_S390X 33#ifdef CONFIG_64BIT
34#define ARCH_OFFSET 4 34#define ARCH_OFFSET 4
35#else 35#else
36#define ARCH_OFFSET 0 36#define ARCH_OFFSET 0
@@ -539,7 +539,7 @@ ipl_devno:
539 .word 0 539 .word 0
540.endm 540.endm
541 541
542#ifdef CONFIG_ARCH_S390X 542#ifdef CONFIG_64BIT
543#include "head64.S" 543#include "head64.S"
544#else 544#else
545#include "head31.S" 545#include "head31.S"
diff --git a/arch/s390/kernel/machine_kexec.c b/arch/s390/kernel/machine_kexec.c
index 5aa71b05b8ae..f0ed5c642c74 100644
--- a/arch/s390/kernel/machine_kexec.c
+++ b/arch/s390/kernel/machine_kexec.c
@@ -85,7 +85,7 @@ kexec_halt_all_cpus(void *kernel_image)
85 pfault_fini(); 85 pfault_fini();
86#endif 86#endif
87 87
88 if (atomic_compare_and_swap(-1, smp_processor_id(), &cpuid)) 88 if (atomic_cmpxchg(&cpuid, -1, smp_processor_id()) != -1)
89 signal_processor(smp_processor_id(), sigp_stop); 89 signal_processor(smp_processor_id(), sigp_stop);
90 90
91 /* Wait for all other cpus to enter stopped state */ 91 /* Wait for all other cpus to enter stopped state */
diff --git a/arch/s390/kernel/module.c b/arch/s390/kernel/module.c
index 607d506689c8..c271cdab58e2 100644
--- a/arch/s390/kernel/module.c
+++ b/arch/s390/kernel/module.c
@@ -37,11 +37,11 @@
37#define DEBUGP(fmt , ...) 37#define DEBUGP(fmt , ...)
38#endif 38#endif
39 39
40#ifndef CONFIG_ARCH_S390X 40#ifndef CONFIG_64BIT
41#define PLT_ENTRY_SIZE 12 41#define PLT_ENTRY_SIZE 12
42#else /* CONFIG_ARCH_S390X */ 42#else /* CONFIG_64BIT */
43#define PLT_ENTRY_SIZE 20 43#define PLT_ENTRY_SIZE 20
44#endif /* CONFIG_ARCH_S390X */ 44#endif /* CONFIG_64BIT */
45 45
46void *module_alloc(unsigned long size) 46void *module_alloc(unsigned long size)
47{ 47{
@@ -294,17 +294,17 @@ apply_rela(Elf_Rela *rela, Elf_Addr base, Elf_Sym *symtab,
294 unsigned int *ip; 294 unsigned int *ip;
295 ip = me->module_core + me->arch.plt_offset + 295 ip = me->module_core + me->arch.plt_offset +
296 info->plt_offset; 296 info->plt_offset;
297#ifndef CONFIG_ARCH_S390X 297#ifndef CONFIG_64BIT
298 ip[0] = 0x0d105810; /* basr 1,0; l 1,6(1); br 1 */ 298 ip[0] = 0x0d105810; /* basr 1,0; l 1,6(1); br 1 */
299 ip[1] = 0x100607f1; 299 ip[1] = 0x100607f1;
300 ip[2] = val; 300 ip[2] = val;
301#else /* CONFIG_ARCH_S390X */ 301#else /* CONFIG_64BIT */
302 ip[0] = 0x0d10e310; /* basr 1,0; lg 1,10(1); br 1 */ 302 ip[0] = 0x0d10e310; /* basr 1,0; lg 1,10(1); br 1 */
303 ip[1] = 0x100a0004; 303 ip[1] = 0x100a0004;
304 ip[2] = 0x07f10000; 304 ip[2] = 0x07f10000;
305 ip[3] = (unsigned int) (val >> 32); 305 ip[3] = (unsigned int) (val >> 32);
306 ip[4] = (unsigned int) val; 306 ip[4] = (unsigned int) val;
307#endif /* CONFIG_ARCH_S390X */ 307#endif /* CONFIG_64BIT */
308 info->plt_initialized = 1; 308 info->plt_initialized = 1;
309 } 309 }
310 if (r_type == R_390_PLTOFF16 || 310 if (r_type == R_390_PLTOFF16 ||
diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c
index 78b64fe5e7c2..a942bf2d58e9 100644
--- a/arch/s390/kernel/process.c
+++ b/arch/s390/kernel/process.c
@@ -235,7 +235,7 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long new_stackp,
235 /* Save access registers to new thread structure. */ 235 /* Save access registers to new thread structure. */
236 save_access_regs(&p->thread.acrs[0]); 236 save_access_regs(&p->thread.acrs[0]);
237 237
238#ifndef CONFIG_ARCH_S390X 238#ifndef CONFIG_64BIT
239 /* 239 /*
240 * save fprs to current->thread.fp_regs to merge them with 240 * save fprs to current->thread.fp_regs to merge them with
241 * the emulated registers and then copy the result to the child. 241 * the emulated registers and then copy the result to the child.
@@ -247,7 +247,7 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long new_stackp,
247 /* Set a new TLS ? */ 247 /* Set a new TLS ? */
248 if (clone_flags & CLONE_SETTLS) 248 if (clone_flags & CLONE_SETTLS)
249 p->thread.acrs[0] = regs->gprs[6]; 249 p->thread.acrs[0] = regs->gprs[6];
250#else /* CONFIG_ARCH_S390X */ 250#else /* CONFIG_64BIT */
251 /* Save the fpu registers to new thread structure. */ 251 /* Save the fpu registers to new thread structure. */
252 save_fp_regs(&p->thread.fp_regs); 252 save_fp_regs(&p->thread.fp_regs);
253 p->thread.user_seg = __pa((unsigned long) p->mm->pgd) | _REGION_TABLE; 253 p->thread.user_seg = __pa((unsigned long) p->mm->pgd) | _REGION_TABLE;
@@ -260,7 +260,7 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long new_stackp,
260 p->thread.acrs[1] = (unsigned int) regs->gprs[6]; 260 p->thread.acrs[1] = (unsigned int) regs->gprs[6];
261 } 261 }
262 } 262 }
263#endif /* CONFIG_ARCH_S390X */ 263#endif /* CONFIG_64BIT */
264 /* start new process with ar4 pointing to the correct address space */ 264 /* start new process with ar4 pointing to the correct address space */
265 p->thread.mm_segment = get_fs(); 265 p->thread.mm_segment = get_fs();
266 /* Don't copy debug registers */ 266 /* Don't copy debug registers */
@@ -339,16 +339,16 @@ out:
339 */ 339 */
340int dump_fpu (struct pt_regs * regs, s390_fp_regs *fpregs) 340int dump_fpu (struct pt_regs * regs, s390_fp_regs *fpregs)
341{ 341{
342#ifndef CONFIG_ARCH_S390X 342#ifndef CONFIG_64BIT
343 /* 343 /*
344 * save fprs to current->thread.fp_regs to merge them with 344 * save fprs to current->thread.fp_regs to merge them with
345 * the emulated registers and then copy the result to the dump. 345 * the emulated registers and then copy the result to the dump.
346 */ 346 */
347 save_fp_regs(&current->thread.fp_regs); 347 save_fp_regs(&current->thread.fp_regs);
348 memcpy(fpregs, &current->thread.fp_regs, sizeof(s390_fp_regs)); 348 memcpy(fpregs, &current->thread.fp_regs, sizeof(s390_fp_regs));
349#else /* CONFIG_ARCH_S390X */ 349#else /* CONFIG_64BIT */
350 save_fp_regs(fpregs); 350 save_fp_regs(fpregs);
351#endif /* CONFIG_ARCH_S390X */ 351#endif /* CONFIG_64BIT */
352 return 1; 352 return 1;
353} 353}
354 354
diff --git a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c
index 06afa3103ace..8ecda6d66de4 100644
--- a/arch/s390/kernel/ptrace.c
+++ b/arch/s390/kernel/ptrace.c
@@ -42,7 +42,7 @@
42#include <asm/uaccess.h> 42#include <asm/uaccess.h>
43#include <asm/unistd.h> 43#include <asm/unistd.h>
44 44
45#ifdef CONFIG_S390_SUPPORT 45#ifdef CONFIG_COMPAT
46#include "compat_ptrace.h" 46#include "compat_ptrace.h"
47#endif 47#endif
48 48
@@ -59,7 +59,7 @@ FixPerRegisters(struct task_struct *task)
59 59
60 if (per_info->single_step) { 60 if (per_info->single_step) {
61 per_info->control_regs.bits.starting_addr = 0; 61 per_info->control_regs.bits.starting_addr = 0;
62#ifdef CONFIG_S390_SUPPORT 62#ifdef CONFIG_COMPAT
63 if (test_thread_flag(TIF_31BIT)) 63 if (test_thread_flag(TIF_31BIT))
64 per_info->control_regs.bits.ending_addr = 0x7fffffffUL; 64 per_info->control_regs.bits.ending_addr = 0x7fffffffUL;
65 else 65 else
@@ -112,7 +112,7 @@ ptrace_disable(struct task_struct *child)
112 clear_single_step(child); 112 clear_single_step(child);
113} 113}
114 114
115#ifndef CONFIG_ARCH_S390X 115#ifndef CONFIG_64BIT
116# define __ADDR_MASK 3 116# define __ADDR_MASK 3
117#else 117#else
118# define __ADDR_MASK 7 118# define __ADDR_MASK 7
@@ -138,7 +138,7 @@ peek_user(struct task_struct *child, addr_t addr, addr_t data)
138 * an alignment of 4. Programmers from hell... 138 * an alignment of 4. Programmers from hell...
139 */ 139 */
140 mask = __ADDR_MASK; 140 mask = __ADDR_MASK;
141#ifdef CONFIG_ARCH_S390X 141#ifdef CONFIG_64BIT
142 if (addr >= (addr_t) &dummy->regs.acrs && 142 if (addr >= (addr_t) &dummy->regs.acrs &&
143 addr < (addr_t) &dummy->regs.orig_gpr2) 143 addr < (addr_t) &dummy->regs.orig_gpr2)
144 mask = 3; 144 mask = 3;
@@ -160,7 +160,7 @@ peek_user(struct task_struct *child, addr_t addr, addr_t data)
160 * access registers are stored in the thread structure 160 * access registers are stored in the thread structure
161 */ 161 */
162 offset = addr - (addr_t) &dummy->regs.acrs; 162 offset = addr - (addr_t) &dummy->regs.acrs;
163#ifdef CONFIG_ARCH_S390X 163#ifdef CONFIG_64BIT
164 /* 164 /*
165 * Very special case: old & broken 64 bit gdb reading 165 * Very special case: old & broken 64 bit gdb reading
166 * from acrs[15]. Result is a 64 bit value. Read the 166 * from acrs[15]. Result is a 64 bit value. Read the
@@ -218,7 +218,7 @@ poke_user(struct task_struct *child, addr_t addr, addr_t data)
218 * an alignment of 4. Programmers from hell indeed... 218 * an alignment of 4. Programmers from hell indeed...
219 */ 219 */
220 mask = __ADDR_MASK; 220 mask = __ADDR_MASK;
221#ifdef CONFIG_ARCH_S390X 221#ifdef CONFIG_64BIT
222 if (addr >= (addr_t) &dummy->regs.acrs && 222 if (addr >= (addr_t) &dummy->regs.acrs &&
223 addr < (addr_t) &dummy->regs.orig_gpr2) 223 addr < (addr_t) &dummy->regs.orig_gpr2)
224 mask = 3; 224 mask = 3;
@@ -231,13 +231,13 @@ poke_user(struct task_struct *child, addr_t addr, addr_t data)
231 * psw and gprs are stored on the stack 231 * psw and gprs are stored on the stack
232 */ 232 */
233 if (addr == (addr_t) &dummy->regs.psw.mask && 233 if (addr == (addr_t) &dummy->regs.psw.mask &&
234#ifdef CONFIG_S390_SUPPORT 234#ifdef CONFIG_COMPAT
235 data != PSW_MASK_MERGE(PSW_USER32_BITS, data) && 235 data != PSW_MASK_MERGE(PSW_USER32_BITS, data) &&
236#endif 236#endif
237 data != PSW_MASK_MERGE(PSW_USER_BITS, data)) 237 data != PSW_MASK_MERGE(PSW_USER_BITS, data))
238 /* Invalid psw mask. */ 238 /* Invalid psw mask. */
239 return -EINVAL; 239 return -EINVAL;
240#ifndef CONFIG_ARCH_S390X 240#ifndef CONFIG_64BIT
241 if (addr == (addr_t) &dummy->regs.psw.addr) 241 if (addr == (addr_t) &dummy->regs.psw.addr)
242 /* I'd like to reject addresses without the 242 /* I'd like to reject addresses without the
243 high order bit but older gdb's rely on it */ 243 high order bit but older gdb's rely on it */
@@ -250,7 +250,7 @@ poke_user(struct task_struct *child, addr_t addr, addr_t data)
250 * access registers are stored in the thread structure 250 * access registers are stored in the thread structure
251 */ 251 */
252 offset = addr - (addr_t) &dummy->regs.acrs; 252 offset = addr - (addr_t) &dummy->regs.acrs;
253#ifdef CONFIG_ARCH_S390X 253#ifdef CONFIG_64BIT
254 /* 254 /*
255 * Very special case: old & broken 64 bit gdb writing 255 * Very special case: old & broken 64 bit gdb writing
256 * to acrs[15] with a 64 bit value. Ignore the lower 256 * to acrs[15] with a 64 bit value. Ignore the lower
@@ -357,7 +357,7 @@ do_ptrace_normal(struct task_struct *child, long request, long addr, long data)
357 return ptrace_request(child, request, addr, data); 357 return ptrace_request(child, request, addr, data);
358} 358}
359 359
360#ifdef CONFIG_S390_SUPPORT 360#ifdef CONFIG_COMPAT
361/* 361/*
362 * Now the fun part starts... a 31 bit program running in the 362 * Now the fun part starts... a 31 bit program running in the
363 * 31 bit emulation tracing another program. PTRACE_PEEKTEXT, 363 * 31 bit emulation tracing another program. PTRACE_PEEKTEXT,
@@ -629,7 +629,7 @@ do_ptrace(struct task_struct *child, long request, long addr, long data)
629 return peek_user(child, addr, data); 629 return peek_user(child, addr, data);
630 if (request == PTRACE_POKEUSR && addr == PT_IEEE_IP) 630 if (request == PTRACE_POKEUSR && addr == PT_IEEE_IP)
631 return poke_user(child, addr, data); 631 return poke_user(child, addr, data);
632#ifdef CONFIG_S390_SUPPORT 632#ifdef CONFIG_COMPAT
633 if (request == PTRACE_PEEKUSR && 633 if (request == PTRACE_PEEKUSR &&
634 addr == PT32_IEEE_IP && test_thread_flag(TIF_31BIT)) 634 addr == PT32_IEEE_IP && test_thread_flag(TIF_31BIT))
635 return peek_user_emu31(child, addr, data); 635 return peek_user_emu31(child, addr, data);
@@ -695,7 +695,7 @@ do_ptrace(struct task_struct *child, long request, long addr, long data)
695 695
696 /* Do requests that differ for 31/64 bit */ 696 /* Do requests that differ for 31/64 bit */
697 default: 697 default:
698#ifdef CONFIG_S390_SUPPORT 698#ifdef CONFIG_COMPAT
699 if (test_thread_flag(TIF_31BIT)) 699 if (test_thread_flag(TIF_31BIT))
700 return do_ptrace_emu31(child, request, addr, data); 700 return do_ptrace_emu31(child, request, addr, data);
701#endif 701#endif
diff --git a/arch/s390/kernel/reipl_diag.c b/arch/s390/kernel/reipl_diag.c
index 83cb42bc0b76..1f33951ba439 100644
--- a/arch/s390/kernel/reipl_diag.c
+++ b/arch/s390/kernel/reipl_diag.c
@@ -26,7 +26,7 @@ void reipl_diag(void)
26 " st %%r4,%0\n" 26 " st %%r4,%0\n"
27 " st %%r5,%1\n" 27 " st %%r5,%1\n"
28 ".section __ex_table,\"a\"\n" 28 ".section __ex_table,\"a\"\n"
29#ifdef __s390x__ 29#ifdef CONFIG_64BIT
30 " .align 8\n" 30 " .align 8\n"
31 " .quad 0b, 0b\n" 31 " .quad 0b, 0b\n"
32#else 32#else
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c
index 31e7b19348b7..b03847d100d9 100644
--- a/arch/s390/kernel/setup.c
+++ b/arch/s390/kernel/setup.c
@@ -427,7 +427,7 @@ setup_lowcore(void)
427 __alloc_bootmem(PAGE_SIZE, PAGE_SIZE, 0) + PAGE_SIZE; 427 __alloc_bootmem(PAGE_SIZE, PAGE_SIZE, 0) + PAGE_SIZE;
428 lc->current_task = (unsigned long) init_thread_union.thread_info.task; 428 lc->current_task = (unsigned long) init_thread_union.thread_info.task;
429 lc->thread_info = (unsigned long) &init_thread_union; 429 lc->thread_info = (unsigned long) &init_thread_union;
430#ifndef CONFIG_ARCH_S390X 430#ifndef CONFIG_64BIT
431 if (MACHINE_HAS_IEEE) { 431 if (MACHINE_HAS_IEEE) {
432 lc->extended_save_area_addr = (__u32) 432 lc->extended_save_area_addr = (__u32)
433 __alloc_bootmem(PAGE_SIZE, PAGE_SIZE, 0); 433 __alloc_bootmem(PAGE_SIZE, PAGE_SIZE, 0);
@@ -562,21 +562,21 @@ setup_arch(char **cmdline_p)
562 /* 562 /*
563 * print what head.S has found out about the machine 563 * print what head.S has found out about the machine
564 */ 564 */
565#ifndef CONFIG_ARCH_S390X 565#ifndef CONFIG_64BIT
566 printk((MACHINE_IS_VM) ? 566 printk((MACHINE_IS_VM) ?
567 "We are running under VM (31 bit mode)\n" : 567 "We are running under VM (31 bit mode)\n" :
568 "We are running native (31 bit mode)\n"); 568 "We are running native (31 bit mode)\n");
569 printk((MACHINE_HAS_IEEE) ? 569 printk((MACHINE_HAS_IEEE) ?
570 "This machine has an IEEE fpu\n" : 570 "This machine has an IEEE fpu\n" :
571 "This machine has no IEEE fpu\n"); 571 "This machine has no IEEE fpu\n");
572#else /* CONFIG_ARCH_S390X */ 572#else /* CONFIG_64BIT */
573 printk((MACHINE_IS_VM) ? 573 printk((MACHINE_IS_VM) ?
574 "We are running under VM (64 bit mode)\n" : 574 "We are running under VM (64 bit mode)\n" :
575 "We are running native (64 bit mode)\n"); 575 "We are running native (64 bit mode)\n");
576#endif /* CONFIG_ARCH_S390X */ 576#endif /* CONFIG_64BIT */
577 577
578 ROOT_DEV = Root_RAM0; 578 ROOT_DEV = Root_RAM0;
579#ifndef CONFIG_ARCH_S390X 579#ifndef CONFIG_64BIT
580 memory_end = memory_size & ~0x400000UL; /* align memory end to 4MB */ 580 memory_end = memory_size & ~0x400000UL; /* align memory end to 4MB */
581 /* 581 /*
582 * We need some free virtual space to be able to do vmalloc. 582 * We need some free virtual space to be able to do vmalloc.
@@ -585,9 +585,9 @@ setup_arch(char **cmdline_p)
585 */ 585 */
586 if (memory_end > 1920*1024*1024) 586 if (memory_end > 1920*1024*1024)
587 memory_end = 1920*1024*1024; 587 memory_end = 1920*1024*1024;
588#else /* CONFIG_ARCH_S390X */ 588#else /* CONFIG_64BIT */
589 memory_end = memory_size & ~0x200000UL; /* detected in head.s */ 589 memory_end = memory_size & ~0x200000UL; /* detected in head.s */
590#endif /* CONFIG_ARCH_S390X */ 590#endif /* CONFIG_64BIT */
591 591
592 init_mm.start_code = PAGE_OFFSET; 592 init_mm.start_code = PAGE_OFFSET;
593 init_mm.end_code = (unsigned long) &_etext; 593 init_mm.end_code = (unsigned long) &_etext;
diff --git a/arch/s390/kernel/signal.c b/arch/s390/kernel/signal.c
index 6e0110d71191..6ae4a77270b5 100644
--- a/arch/s390/kernel/signal.c
+++ b/arch/s390/kernel/signal.c
@@ -254,9 +254,9 @@ asmlinkage long sys_rt_sigreturn(struct pt_regs *regs)
254 if (restore_sigregs(regs, &frame->uc.uc_mcontext)) 254 if (restore_sigregs(regs, &frame->uc.uc_mcontext))
255 goto badframe; 255 goto badframe;
256 256
257 /* It is more difficult to avoid calling this function than to 257 if (do_sigaltstack(&frame->uc.uc_stack, NULL,
258 call it and ignore errors. */ 258 regs->gprs[15]) == -EFAULT)
259 do_sigaltstack(&frame->uc.uc_stack, NULL, regs->gprs[15]); 259 goto badframe;
260 return regs->gprs[2]; 260 return regs->gprs[2];
261 261
262badframe: 262badframe:
@@ -501,7 +501,7 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset)
501 501
502 if (signr > 0) { 502 if (signr > 0) {
503 /* Whee! Actually deliver the signal. */ 503 /* Whee! Actually deliver the signal. */
504#ifdef CONFIG_S390_SUPPORT 504#ifdef CONFIG_COMPAT
505 if (test_thread_flag(TIF_31BIT)) { 505 if (test_thread_flag(TIF_31BIT)) {
506 extern void handle_signal32(unsigned long sig, 506 extern void handle_signal32(unsigned long sig,
507 struct k_sigaction *ka, 507 struct k_sigaction *ka,
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c
index 5856b3fda6bf..e10f4ca00499 100644
--- a/arch/s390/kernel/smp.c
+++ b/arch/s390/kernel/smp.c
@@ -263,7 +263,7 @@ static void do_machine_restart(void * __unused)
263 int cpu; 263 int cpu;
264 static atomic_t cpuid = ATOMIC_INIT(-1); 264 static atomic_t cpuid = ATOMIC_INIT(-1);
265 265
266 if (atomic_compare_and_swap(-1, smp_processor_id(), &cpuid)) 266 if (atomic_cmpxchg(&cpuid, -1, smp_processor_id()) != -1)
267 signal_processor(smp_processor_id(), sigp_stop); 267 signal_processor(smp_processor_id(), sigp_stop);
268 268
269 /* Wait for all other cpus to enter stopped state */ 269 /* Wait for all other cpus to enter stopped state */
@@ -313,7 +313,7 @@ static void do_machine_halt(void * __unused)
313{ 313{
314 static atomic_t cpuid = ATOMIC_INIT(-1); 314 static atomic_t cpuid = ATOMIC_INIT(-1);
315 315
316 if (atomic_compare_and_swap(-1, smp_processor_id(), &cpuid) == 0) { 316 if (atomic_cmpxchg(&cpuid, -1, smp_processor_id()) == -1) {
317 smp_send_stop(); 317 smp_send_stop();
318 if (MACHINE_IS_VM && strlen(vmhalt_cmd) > 0) 318 if (MACHINE_IS_VM && strlen(vmhalt_cmd) > 0)
319 cpcmd(vmhalt_cmd, NULL, 0, NULL); 319 cpcmd(vmhalt_cmd, NULL, 0, NULL);
@@ -332,7 +332,7 @@ static void do_machine_power_off(void * __unused)
332{ 332{
333 static atomic_t cpuid = ATOMIC_INIT(-1); 333 static atomic_t cpuid = ATOMIC_INIT(-1);
334 334
335 if (atomic_compare_and_swap(-1, smp_processor_id(), &cpuid) == 0) { 335 if (atomic_cmpxchg(&cpuid, -1, smp_processor_id()) == -1) {
336 smp_send_stop(); 336 smp_send_stop();
337 if (MACHINE_IS_VM && strlen(vmpoff_cmd) > 0) 337 if (MACHINE_IS_VM && strlen(vmpoff_cmd) > 0)
338 cpcmd(vmpoff_cmd, NULL, 0, NULL); 338 cpcmd(vmpoff_cmd, NULL, 0, NULL);
@@ -402,7 +402,7 @@ static void smp_ext_bitcall_others(ec_bit_sig sig)
402 } 402 }
403} 403}
404 404
405#ifndef CONFIG_ARCH_S390X 405#ifndef CONFIG_64BIT
406/* 406/*
407 * this function sends a 'purge tlb' signal to another CPU. 407 * this function sends a 'purge tlb' signal to another CPU.
408 */ 408 */
@@ -416,7 +416,7 @@ void smp_ptlb_all(void)
416 on_each_cpu(smp_ptlb_callback, NULL, 0, 1); 416 on_each_cpu(smp_ptlb_callback, NULL, 0, 1);
417} 417}
418EXPORT_SYMBOL(smp_ptlb_all); 418EXPORT_SYMBOL(smp_ptlb_all);
419#endif /* ! CONFIG_ARCH_S390X */ 419#endif /* ! CONFIG_64BIT */
420 420
421/* 421/*
422 * this function sends a 'reschedule' IPI to another CPU. 422 * this function sends a 'reschedule' IPI to another CPU.
@@ -783,7 +783,7 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
783 if (stack == 0ULL) 783 if (stack == 0ULL)
784 panic("smp_boot_cpus failed to allocate memory\n"); 784 panic("smp_boot_cpus failed to allocate memory\n");
785 lowcore_ptr[i]->panic_stack = stack + (PAGE_SIZE); 785 lowcore_ptr[i]->panic_stack = stack + (PAGE_SIZE);
786#ifndef __s390x__ 786#ifndef CONFIG_64BIT
787 if (MACHINE_HAS_IEEE) { 787 if (MACHINE_HAS_IEEE) {
788 lowcore_ptr[i]->extended_save_area_addr = 788 lowcore_ptr[i]->extended_save_area_addr =
789 (__u32) __get_free_pages(GFP_KERNEL,0); 789 (__u32) __get_free_pages(GFP_KERNEL,0);
@@ -793,7 +793,7 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
793 } 793 }
794#endif 794#endif
795 } 795 }
796#ifndef __s390x__ 796#ifndef CONFIG_64BIT
797 if (MACHINE_HAS_IEEE) 797 if (MACHINE_HAS_IEEE)
798 ctl_set_bit(14, 29); /* enable extended save area */ 798 ctl_set_bit(14, 29); /* enable extended save area */
799#endif 799#endif
diff --git a/arch/s390/kernel/sys_s390.c b/arch/s390/kernel/sys_s390.c
index efe6b83b53f7..6a63553493c5 100644
--- a/arch/s390/kernel/sys_s390.c
+++ b/arch/s390/kernel/sys_s390.c
@@ -26,9 +26,7 @@
26#include <linux/mman.h> 26#include <linux/mman.h>
27#include <linux/file.h> 27#include <linux/file.h>
28#include <linux/utsname.h> 28#include <linux/utsname.h>
29#ifdef CONFIG_ARCH_S390X
30#include <linux/personality.h> 29#include <linux/personality.h>
31#endif /* CONFIG_ARCH_S390X */
32 30
33#include <asm/uaccess.h> 31#include <asm/uaccess.h>
34#include <asm/ipc.h> 32#include <asm/ipc.h>
@@ -121,7 +119,7 @@ out:
121 return error; 119 return error;
122} 120}
123 121
124#ifndef CONFIG_ARCH_S390X 122#ifndef CONFIG_64BIT
125struct sel_arg_struct { 123struct sel_arg_struct {
126 unsigned long n; 124 unsigned long n;
127 fd_set *inp, *outp, *exp; 125 fd_set *inp, *outp, *exp;
@@ -138,7 +136,7 @@ asmlinkage long old_select(struct sel_arg_struct __user *arg)
138 return sys_select(a.n, a.inp, a.outp, a.exp, a.tvp); 136 return sys_select(a.n, a.inp, a.outp, a.exp, a.tvp);
139 137
140} 138}
141#endif /* CONFIG_ARCH_S390X */ 139#endif /* CONFIG_64BIT */
142 140
143/* 141/*
144 * sys_ipc() is the de-multiplexer for the SysV IPC calls.. 142 * sys_ipc() is the de-multiplexer for the SysV IPC calls..
@@ -211,7 +209,7 @@ asmlinkage long sys_ipc(uint call, int first, unsigned long second,
211 return -EINVAL; 209 return -EINVAL;
212} 210}
213 211
214#ifdef CONFIG_ARCH_S390X 212#ifdef CONFIG_64BIT
215asmlinkage long s390x_newuname(struct new_utsname __user *name) 213asmlinkage long s390x_newuname(struct new_utsname __user *name)
216{ 214{
217 int ret = sys_newuname(name); 215 int ret = sys_newuname(name);
@@ -235,12 +233,12 @@ asmlinkage long s390x_personality(unsigned long personality)
235 233
236 return ret; 234 return ret;
237} 235}
238#endif /* CONFIG_ARCH_S390X */ 236#endif /* CONFIG_64BIT */
239 237
240/* 238/*
241 * Wrapper function for sys_fadvise64/fadvise64_64 239 * Wrapper function for sys_fadvise64/fadvise64_64
242 */ 240 */
243#ifndef CONFIG_ARCH_S390X 241#ifndef CONFIG_64BIT
244 242
245asmlinkage long 243asmlinkage long
246s390_fadvise64(int fd, u32 offset_high, u32 offset_low, size_t len, int advice) 244s390_fadvise64(int fd, u32 offset_high, u32 offset_low, size_t len, int advice)
diff --git a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c
index c5bd36fae56b..95d109968619 100644
--- a/arch/s390/kernel/traps.c
+++ b/arch/s390/kernel/traps.c
@@ -67,13 +67,13 @@ extern pgm_check_handler_t do_monitor_call;
67 67
68#define stack_pointer ({ void **sp; asm("la %0,0(15)" : "=&d" (sp)); sp; }) 68#define stack_pointer ({ void **sp; asm("la %0,0(15)" : "=&d" (sp)); sp; })
69 69
70#ifndef CONFIG_ARCH_S390X 70#ifndef CONFIG_64BIT
71#define FOURLONG "%08lx %08lx %08lx %08lx\n" 71#define FOURLONG "%08lx %08lx %08lx %08lx\n"
72static int kstack_depth_to_print = 12; 72static int kstack_depth_to_print = 12;
73#else /* CONFIG_ARCH_S390X */ 73#else /* CONFIG_64BIT */
74#define FOURLONG "%016lx %016lx %016lx %016lx\n" 74#define FOURLONG "%016lx %016lx %016lx %016lx\n"
75static int kstack_depth_to_print = 20; 75static int kstack_depth_to_print = 20;
76#endif /* CONFIG_ARCH_S390X */ 76#endif /* CONFIG_64BIT */
77 77
78/* 78/*
79 * For show_trace we have tree different stack to consider: 79 * For show_trace we have tree different stack to consider:
@@ -702,12 +702,12 @@ void __init trap_init(void)
702 pgm_check_table[0x11] = &do_dat_exception; 702 pgm_check_table[0x11] = &do_dat_exception;
703 pgm_check_table[0x12] = &translation_exception; 703 pgm_check_table[0x12] = &translation_exception;
704 pgm_check_table[0x13] = &special_op_exception; 704 pgm_check_table[0x13] = &special_op_exception;
705#ifdef CONFIG_ARCH_S390X 705#ifdef CONFIG_64BIT
706 pgm_check_table[0x38] = &do_dat_exception; 706 pgm_check_table[0x38] = &do_dat_exception;
707 pgm_check_table[0x39] = &do_dat_exception; 707 pgm_check_table[0x39] = &do_dat_exception;
708 pgm_check_table[0x3A] = &do_dat_exception; 708 pgm_check_table[0x3A] = &do_dat_exception;
709 pgm_check_table[0x3B] = &do_dat_exception; 709 pgm_check_table[0x3B] = &do_dat_exception;
710#endif /* CONFIG_ARCH_S390X */ 710#endif /* CONFIG_64BIT */
711 pgm_check_table[0x15] = &operand_exception; 711 pgm_check_table[0x15] = &operand_exception;
712 pgm_check_table[0x1C] = &space_switch_exception; 712 pgm_check_table[0x1C] = &space_switch_exception;
713 pgm_check_table[0x1D] = &hfp_sqrt_exception; 713 pgm_check_table[0x1D] = &hfp_sqrt_exception;
diff --git a/arch/s390/kernel/vmlinux.lds.S b/arch/s390/kernel/vmlinux.lds.S
index 89fdb3808bc0..9289face3027 100644
--- a/arch/s390/kernel/vmlinux.lds.S
+++ b/arch/s390/kernel/vmlinux.lds.S
@@ -5,7 +5,7 @@
5#include <asm-generic/vmlinux.lds.h> 5#include <asm-generic/vmlinux.lds.h>
6#include <linux/config.h> 6#include <linux/config.h>
7 7
8#ifndef CONFIG_ARCH_S390X 8#ifndef CONFIG_64BIT
9OUTPUT_FORMAT("elf32-s390", "elf32-s390", "elf32-s390") 9OUTPUT_FORMAT("elf32-s390", "elf32-s390", "elf32-s390")
10OUTPUT_ARCH(s390) 10OUTPUT_ARCH(s390)
11ENTRY(_start) 11ENTRY(_start)
diff --git a/arch/s390/lib/Makefile b/arch/s390/lib/Makefile
index b701efa1f00e..d9b97b3c597f 100644
--- a/arch/s390/lib/Makefile
+++ b/arch/s390/lib/Makefile
@@ -4,6 +4,5 @@
4 4
5EXTRA_AFLAGS := -traditional 5EXTRA_AFLAGS := -traditional
6 6
7lib-y += delay.o string.o 7lib-y += delay.o string.o spinlock.o
8lib-$(CONFIG_ARCH_S390_31) += uaccess.o spinlock.o 8lib-y += $(if $(CONFIG_64BIT),uaccess64.o,uaccess.o)
9lib-$(CONFIG_ARCH_S390X) += uaccess64.o spinlock.o
diff --git a/arch/s390/lib/spinlock.c b/arch/s390/lib/spinlock.c
index 2dc14e9c8327..68d79c502081 100644
--- a/arch/s390/lib/spinlock.c
+++ b/arch/s390/lib/spinlock.c
@@ -29,7 +29,7 @@ __setup("spin_retry=", spin_retry_setup);
29static inline void 29static inline void
30_diag44(void) 30_diag44(void)
31{ 31{
32#ifdef __s390x__ 32#ifdef CONFIG_64BIT
33 if (MACHINE_HAS_DIAG44) 33 if (MACHINE_HAS_DIAG44)
34#endif 34#endif
35 asm volatile("diag 0,0,0x44"); 35 asm volatile("diag 0,0,0x44");
diff --git a/arch/s390/mm/extmem.c b/arch/s390/mm/extmem.c
index 506a33b51e4f..a9566bcab682 100644
--- a/arch/s390/mm/extmem.c
+++ b/arch/s390/mm/extmem.c
@@ -143,7 +143,7 @@ dcss_diag (__u8 func, void *parameter,
143 rx = (unsigned long) parameter; 143 rx = (unsigned long) parameter;
144 ry = (unsigned long) func; 144 ry = (unsigned long) func;
145 __asm__ __volatile__( 145 __asm__ __volatile__(
146#ifdef CONFIG_ARCH_S390X 146#ifdef CONFIG_64BIT
147 " sam31\n" // switch to 31 bit 147 " sam31\n" // switch to 31 bit
148 " diag %0,%1,0x64\n" 148 " diag %0,%1,0x64\n"
149 " sam64\n" // switch back to 64 bit 149 " sam64\n" // switch back to 64 bit
diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c
index fb2607c369ed..81ade401b073 100644
--- a/arch/s390/mm/fault.c
+++ b/arch/s390/mm/fault.c
@@ -31,17 +31,17 @@
31#include <asm/uaccess.h> 31#include <asm/uaccess.h>
32#include <asm/pgtable.h> 32#include <asm/pgtable.h>
33 33
34#ifndef CONFIG_ARCH_S390X 34#ifndef CONFIG_64BIT
35#define __FAIL_ADDR_MASK 0x7ffff000 35#define __FAIL_ADDR_MASK 0x7ffff000
36#define __FIXUP_MASK 0x7fffffff 36#define __FIXUP_MASK 0x7fffffff
37#define __SUBCODE_MASK 0x0200 37#define __SUBCODE_MASK 0x0200
38#define __PF_RES_FIELD 0ULL 38#define __PF_RES_FIELD 0ULL
39#else /* CONFIG_ARCH_S390X */ 39#else /* CONFIG_64BIT */
40#define __FAIL_ADDR_MASK -4096L 40#define __FAIL_ADDR_MASK -4096L
41#define __FIXUP_MASK ~0L 41#define __FIXUP_MASK ~0L
42#define __SUBCODE_MASK 0x0600 42#define __SUBCODE_MASK 0x0600
43#define __PF_RES_FIELD 0x8000000000000000ULL 43#define __PF_RES_FIELD 0x8000000000000000ULL
44#endif /* CONFIG_ARCH_S390X */ 44#endif /* CONFIG_64BIT */
45 45
46#ifdef CONFIG_SYSCTL 46#ifdef CONFIG_SYSCTL
47extern int sysctl_userprocess_debug; 47extern int sysctl_userprocess_debug;
@@ -393,11 +393,11 @@ int pfault_init(void)
393 "2:\n" 393 "2:\n"
394 ".section __ex_table,\"a\"\n" 394 ".section __ex_table,\"a\"\n"
395 " .align 4\n" 395 " .align 4\n"
396#ifndef CONFIG_ARCH_S390X 396#ifndef CONFIG_64BIT
397 " .long 0b,1b\n" 397 " .long 0b,1b\n"
398#else /* CONFIG_ARCH_S390X */ 398#else /* CONFIG_64BIT */
399 " .quad 0b,1b\n" 399 " .quad 0b,1b\n"
400#endif /* CONFIG_ARCH_S390X */ 400#endif /* CONFIG_64BIT */
401 ".previous" 401 ".previous"
402 : "=d" (rc) : "a" (&refbk), "m" (refbk) : "cc" ); 402 : "=d" (rc) : "a" (&refbk), "m" (refbk) : "cc" );
403 __ctl_set_bit(0, 9); 403 __ctl_set_bit(0, 9);
@@ -417,11 +417,11 @@ void pfault_fini(void)
417 "0:\n" 417 "0:\n"
418 ".section __ex_table,\"a\"\n" 418 ".section __ex_table,\"a\"\n"
419 " .align 4\n" 419 " .align 4\n"
420#ifndef CONFIG_ARCH_S390X 420#ifndef CONFIG_64BIT
421 " .long 0b,0b\n" 421 " .long 0b,0b\n"
422#else /* CONFIG_ARCH_S390X */ 422#else /* CONFIG_64BIT */
423 " .quad 0b,0b\n" 423 " .quad 0b,0b\n"
424#endif /* CONFIG_ARCH_S390X */ 424#endif /* CONFIG_64BIT */
425 ".previous" 425 ".previous"
426 : : "a" (&refbk), "m" (refbk) : "cc" ); 426 : : "a" (&refbk), "m" (refbk) : "cc" );
427} 427}
diff --git a/arch/s390/mm/init.c b/arch/s390/mm/init.c
index 6ec5cd981e74..df953383724d 100644
--- a/arch/s390/mm/init.c
+++ b/arch/s390/mm/init.c
@@ -44,7 +44,7 @@ void diag10(unsigned long addr)
44{ 44{
45 if (addr >= 0x7ff00000) 45 if (addr >= 0x7ff00000)
46 return; 46 return;
47#ifdef __s390x__ 47#ifdef CONFIG_64BIT
48 asm volatile ( 48 asm volatile (
49 " sam31\n" 49 " sam31\n"
50 " diag %0,%0,0x10\n" 50 " diag %0,%0,0x10\n"
@@ -106,7 +106,7 @@ extern unsigned long __initdata zholes_size[];
106 * paging_init() sets up the page tables 106 * paging_init() sets up the page tables
107 */ 107 */
108 108
109#ifndef CONFIG_ARCH_S390X 109#ifndef CONFIG_64BIT
110void __init paging_init(void) 110void __init paging_init(void)
111{ 111{
112 pgd_t * pg_dir; 112 pgd_t * pg_dir;
@@ -175,7 +175,7 @@ void __init paging_init(void)
175 return; 175 return;
176} 176}
177 177
178#else /* CONFIG_ARCH_S390X */ 178#else /* CONFIG_64BIT */
179void __init paging_init(void) 179void __init paging_init(void)
180{ 180{
181 pgd_t * pg_dir; 181 pgd_t * pg_dir;
@@ -256,7 +256,7 @@ void __init paging_init(void)
256 256
257 return; 257 return;
258} 258}
259#endif /* CONFIG_ARCH_S390X */ 259#endif /* CONFIG_64BIT */
260 260
261void __init mem_init(void) 261void __init mem_init(void)
262{ 262{
diff --git a/arch/s390/mm/mmap.c b/arch/s390/mm/mmap.c
index fb187e5a54b4..356257c171de 100644
--- a/arch/s390/mm/mmap.c
+++ b/arch/s390/mm/mmap.c
@@ -50,7 +50,7 @@ static inline unsigned long mmap_base(void)
50 50
51static inline int mmap_is_legacy(void) 51static inline int mmap_is_legacy(void)
52{ 52{
53#ifdef CONFIG_ARCH_S390X 53#ifdef CONFIG_64BIT
54 /* 54 /*
55 * Force standard allocation for 64 bit programs. 55 * Force standard allocation for 64 bit programs.
56 */ 56 */
diff --git a/arch/s390/oprofile/Makefile b/arch/s390/oprofile/Makefile
index ec349276258a..537b2d840e69 100644
--- a/arch/s390/oprofile/Makefile
+++ b/arch/s390/oprofile/Makefile
@@ -6,4 +6,4 @@ DRIVER_OBJS = $(addprefix ../../../drivers/oprofile/, \
6 oprofilefs.o oprofile_stats.o \ 6 oprofilefs.o oprofile_stats.o \
7 timer_int.o ) 7 timer_int.o )
8 8
9oprofile-y := $(DRIVER_OBJS) init.o 9oprofile-y := $(DRIVER_OBJS) init.o backtrace.o
diff --git a/arch/s390/oprofile/backtrace.c b/arch/s390/oprofile/backtrace.c
new file mode 100644
index 000000000000..bc4b84a35cad
--- /dev/null
+++ b/arch/s390/oprofile/backtrace.c
@@ -0,0 +1,79 @@
1/**
2 * arch/s390/oprofile/backtrace.c
3 *
4 * S390 Version
5 * Copyright (C) 2005 IBM Corporation, IBM Deutschland Entwicklung GmbH.
6 * Author(s): Andreas Krebbel <Andreas.Krebbel@de.ibm.com>
7 */
8
9#include <linux/oprofile.h>
10
11#include <asm/processor.h> /* for struct stack_frame */
12
13static unsigned long
14__show_trace(unsigned int *depth, unsigned long sp,
15 unsigned long low, unsigned long high)
16{
17 struct stack_frame *sf;
18 struct pt_regs *regs;
19
20 while (*depth) {
21 sp = sp & PSW_ADDR_INSN;
22 if (sp < low || sp > high - sizeof(*sf))
23 return sp;
24 sf = (struct stack_frame *) sp;
25 (*depth)--;
26 oprofile_add_trace(sf->gprs[8] & PSW_ADDR_INSN);
27
28 /* Follow the backchain. */
29 while (*depth) {
30 low = sp;
31 sp = sf->back_chain & PSW_ADDR_INSN;
32 if (!sp)
33 break;
34 if (sp <= low || sp > high - sizeof(*sf))
35 return sp;
36 sf = (struct stack_frame *) sp;
37 (*depth)--;
38 oprofile_add_trace(sf->gprs[8] & PSW_ADDR_INSN);
39
40 }
41
42 if (*depth == 0)
43 break;
44
45 /* Zero backchain detected, check for interrupt frame. */
46 sp = (unsigned long) (sf + 1);
47 if (sp <= low || sp > high - sizeof(*regs))
48 return sp;
49 regs = (struct pt_regs *) sp;
50 (*depth)--;
51 oprofile_add_trace(sf->gprs[8] & PSW_ADDR_INSN);
52 low = sp;
53 sp = regs->gprs[15];
54 }
55 return sp;
56}
57
58void s390_backtrace(struct pt_regs * const regs, unsigned int depth)
59{
60 unsigned long head;
61 struct stack_frame* head_sf;
62
63 if (user_mode (regs))
64 return;
65
66 head = regs->gprs[15];
67 head_sf = (struct stack_frame*)head;
68
69 if (!head_sf->back_chain)
70 return;
71
72 head = head_sf->back_chain;
73
74 head = __show_trace(&depth, head, S390_lowcore.async_stack - ASYNC_SIZE,
75 S390_lowcore.async_stack);
76
77 __show_trace(&depth, head, S390_lowcore.thread_info,
78 S390_lowcore.thread_info + THREAD_SIZE);
79}
diff --git a/arch/s390/oprofile/init.c b/arch/s390/oprofile/init.c
index a65ead0e200a..7a995113b918 100644
--- a/arch/s390/oprofile/init.c
+++ b/arch/s390/oprofile/init.c
@@ -12,8 +12,12 @@
12#include <linux/init.h> 12#include <linux/init.h>
13#include <linux/errno.h> 13#include <linux/errno.h>
14 14
15
16extern void s390_backtrace(struct pt_regs * const regs, unsigned int depth);
17
15int __init oprofile_arch_init(struct oprofile_operations* ops) 18int __init oprofile_arch_init(struct oprofile_operations* ops)
16{ 19{
20 ops->backtrace = s390_backtrace;
17 return -ENODEV; 21 return -ENODEV;
18} 22}
19 23
diff --git a/arch/um/drivers/chan_kern.c b/arch/um/drivers/chan_kern.c
index 5b58fad45290..cd13b91b9ff6 100644
--- a/arch/um/drivers/chan_kern.c
+++ b/arch/um/drivers/chan_kern.c
@@ -1,4 +1,4 @@
1/* 1/*
2 * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
@@ -58,7 +58,7 @@ static void *not_configged_init(char *str, int device, struct chan_opts *opts)
58{ 58{
59 my_puts("Using a channel type which is configured out of " 59 my_puts("Using a channel type which is configured out of "
60 "UML\n"); 60 "UML\n");
61 return(NULL); 61 return NULL;
62} 62}
63 63
64static int not_configged_open(int input, int output, int primary, void *data, 64static int not_configged_open(int input, int output, int primary, void *data,
@@ -66,7 +66,7 @@ static int not_configged_open(int input, int output, int primary, void *data,
66{ 66{
67 my_puts("Using a channel type which is configured out of " 67 my_puts("Using a channel type which is configured out of "
68 "UML\n"); 68 "UML\n");
69 return(-ENODEV); 69 return -ENODEV;
70} 70}
71 71
72static void not_configged_close(int fd, void *data) 72static void not_configged_close(int fd, void *data)
@@ -79,21 +79,21 @@ static int not_configged_read(int fd, char *c_out, void *data)
79{ 79{
80 my_puts("Using a channel type which is configured out of " 80 my_puts("Using a channel type which is configured out of "
81 "UML\n"); 81 "UML\n");
82 return(-EIO); 82 return -EIO;
83} 83}
84 84
85static int not_configged_write(int fd, const char *buf, int len, void *data) 85static int not_configged_write(int fd, const char *buf, int len, void *data)
86{ 86{
87 my_puts("Using a channel type which is configured out of " 87 my_puts("Using a channel type which is configured out of "
88 "UML\n"); 88 "UML\n");
89 return(-EIO); 89 return -EIO;
90} 90}
91 91
92static int not_configged_console_write(int fd, const char *buf, int len) 92static int not_configged_console_write(int fd, const char *buf, int len)
93{ 93{
94 my_puts("Using a channel type which is configured out of " 94 my_puts("Using a channel type which is configured out of "
95 "UML\n"); 95 "UML\n");
96 return(-EIO); 96 return -EIO;
97} 97}
98 98
99static int not_configged_window_size(int fd, void *data, unsigned short *rows, 99static int not_configged_window_size(int fd, void *data, unsigned short *rows,
@@ -101,7 +101,7 @@ static int not_configged_window_size(int fd, void *data, unsigned short *rows,
101{ 101{
102 my_puts("Using a channel type which is configured out of " 102 my_puts("Using a channel type which is configured out of "
103 "UML\n"); 103 "UML\n");
104 return(-ENODEV); 104 return -ENODEV;
105} 105}
106 106
107static void not_configged_free(void *data) 107static void not_configged_free(void *data)
@@ -135,17 +135,17 @@ int generic_read(int fd, char *c_out, void *unused)
135 n = os_read_file(fd, c_out, sizeof(*c_out)); 135 n = os_read_file(fd, c_out, sizeof(*c_out));
136 136
137 if(n == -EAGAIN) 137 if(n == -EAGAIN)
138 return(0); 138 return 0;
139 else if(n == 0) 139 else if(n == 0)
140 return(-EIO); 140 return -EIO;
141 return(n); 141 return n;
142} 142}
143 143
144/* XXX Trivial wrapper around os_write_file */ 144/* XXX Trivial wrapper around os_write_file */
145 145
146int generic_write(int fd, const char *buf, int n, void *unused) 146int generic_write(int fd, const char *buf, int n, void *unused)
147{ 147{
148 return(os_write_file(fd, buf, n)); 148 return os_write_file(fd, buf, n);
149} 149}
150 150
151int generic_window_size(int fd, void *unused, unsigned short *rows_out, 151int generic_window_size(int fd, void *unused, unsigned short *rows_out,
@@ -156,14 +156,14 @@ int generic_window_size(int fd, void *unused, unsigned short *rows_out,
156 156
157 ret = os_window_size(fd, &rows, &cols); 157 ret = os_window_size(fd, &rows, &cols);
158 if(ret < 0) 158 if(ret < 0)
159 return(ret); 159 return ret;
160 160
161 ret = ((*rows_out != rows) || (*cols_out != cols)); 161 ret = ((*rows_out != rows) || (*cols_out != cols));
162 162
163 *rows_out = rows; 163 *rows_out = rows;
164 *cols_out = cols; 164 *cols_out = cols;
165 165
166 return(ret); 166 return ret;
167} 167}
168 168
169void generic_free(void *data) 169void generic_free(void *data)
@@ -186,25 +186,29 @@ static void tty_receive_char(struct tty_struct *tty, char ch)
186 } 186 }
187 } 187 }
188 188
189 if((tty->flip.flag_buf_ptr == NULL) || 189 if((tty->flip.flag_buf_ptr == NULL) ||
190 (tty->flip.char_buf_ptr == NULL)) 190 (tty->flip.char_buf_ptr == NULL))
191 return; 191 return;
192 tty_insert_flip_char(tty, ch, TTY_NORMAL); 192 tty_insert_flip_char(tty, ch, TTY_NORMAL);
193} 193}
194 194
195static int open_one_chan(struct chan *chan, int input, int output, int primary) 195static int open_one_chan(struct chan *chan)
196{ 196{
197 int fd; 197 int fd;
198 198
199 if(chan->opened) return(0); 199 if(chan->opened)
200 if(chan->ops->open == NULL) fd = 0; 200 return 0;
201 else fd = (*chan->ops->open)(input, output, primary, chan->data, 201
202 &chan->dev); 202 if(chan->ops->open == NULL)
203 if(fd < 0) return(fd); 203 fd = 0;
204 else fd = (*chan->ops->open)(chan->input, chan->output, chan->primary,
205 chan->data, &chan->dev);
206 if(fd < 0)
207 return fd;
204 chan->fd = fd; 208 chan->fd = fd;
205 209
206 chan->opened = 1; 210 chan->opened = 1;
207 return(0); 211 return 0;
208} 212}
209 213
210int open_chan(struct list_head *chans) 214int open_chan(struct list_head *chans)
@@ -215,11 +219,11 @@ int open_chan(struct list_head *chans)
215 219
216 list_for_each(ele, chans){ 220 list_for_each(ele, chans){
217 chan = list_entry(ele, struct chan, list); 221 chan = list_entry(ele, struct chan, list);
218 ret = open_one_chan(chan, chan->input, chan->output, 222 ret = open_one_chan(chan);
219 chan->primary); 223 if(chan->primary)
220 if(chan->primary) err = ret; 224 err = ret;
221 } 225 }
222 return(err); 226 return err;
223} 227}
224 228
225void chan_enable_winch(struct list_head *chans, struct tty_struct *tty) 229void chan_enable_winch(struct list_head *chans, struct tty_struct *tty)
@@ -236,20 +240,65 @@ void chan_enable_winch(struct list_head *chans, struct tty_struct *tty)
236 } 240 }
237} 241}
238 242
239void enable_chan(struct list_head *chans, struct tty_struct *tty) 243void enable_chan(struct line *line)
240{ 244{
241 struct list_head *ele; 245 struct list_head *ele;
242 struct chan *chan; 246 struct chan *chan;
243 247
244 list_for_each(ele, chans){ 248 list_for_each(ele, &line->chan_list){
245 chan = list_entry(ele, struct chan, list); 249 chan = list_entry(ele, struct chan, list);
246 if(!chan->opened) continue; 250 if(open_one_chan(chan))
251 continue;
252
253 if(chan->enabled)
254 continue;
255 line_setup_irq(chan->fd, chan->input, chan->output, line,
256 chan);
257 chan->enabled = 1;
258 }
259}
260
261static LIST_HEAD(irqs_to_free);
262
263void free_irqs(void)
264{
265 struct chan *chan;
266
267 while(!list_empty(&irqs_to_free)){
268 chan = list_entry(irqs_to_free.next, struct chan, free_list);
269 list_del(&chan->free_list);
247 270
248 line_setup_irq(chan->fd, chan->input, chan->output, tty); 271 if(chan->input)
272 free_irq(chan->line->driver->read_irq, chan);
273 if(chan->output)
274 free_irq(chan->line->driver->write_irq, chan);
275 chan->enabled = 0;
276 }
277}
278
279static void close_one_chan(struct chan *chan, int delay_free_irq)
280{
281 if(!chan->opened)
282 return;
283
284 if(delay_free_irq){
285 list_add(&chan->free_list, &irqs_to_free);
249 } 286 }
287 else {
288 if(chan->input)
289 free_irq(chan->line->driver->read_irq, chan);
290 if(chan->output)
291 free_irq(chan->line->driver->write_irq, chan);
292 chan->enabled = 0;
293 }
294 if(chan->ops->close != NULL)
295 (*chan->ops->close)(chan->fd, chan->data);
296
297 chan->opened = 0;
298 chan->fd = -1;
250} 299}
251 300
252void close_chan(struct list_head *chans) 301void close_chan(struct list_head *chans, int delay_free_irq)
253{ 302{
254 struct chan *chan; 303 struct chan *chan;
255 304
@@ -259,15 +308,37 @@ void close_chan(struct list_head *chans)
259 * so it must be the last closed. 308 * so it must be the last closed.
260 */ 309 */
261 list_for_each_entry_reverse(chan, chans, list) { 310 list_for_each_entry_reverse(chan, chans, list) {
262 if(!chan->opened) continue; 311 close_one_chan(chan, delay_free_irq);
263 if(chan->ops->close != NULL) 312 }
264 (*chan->ops->close)(chan->fd, chan->data); 313}
265 chan->opened = 0; 314
266 chan->fd = -1; 315void deactivate_chan(struct list_head *chans, int irq)
316{
317 struct list_head *ele;
318
319 struct chan *chan;
320 list_for_each(ele, chans) {
321 chan = list_entry(ele, struct chan, list);
322
323 if(chan->enabled && chan->input)
324 deactivate_fd(chan->fd, irq);
325 }
326}
327
328void reactivate_chan(struct list_head *chans, int irq)
329{
330 struct list_head *ele;
331 struct chan *chan;
332
333 list_for_each(ele, chans) {
334 chan = list_entry(ele, struct chan, list);
335
336 if(chan->enabled && chan->input)
337 reactivate_fd(chan->fd, irq);
267 } 338 }
268} 339}
269 340
270int write_chan(struct list_head *chans, const char *buf, int len, 341int write_chan(struct list_head *chans, const char *buf, int len,
271 int write_irq) 342 int write_irq)
272{ 343{
273 struct list_head *ele; 344 struct list_head *ele;
@@ -285,7 +356,7 @@ int write_chan(struct list_head *chans, const char *buf, int len,
285 reactivate_fd(chan->fd, write_irq); 356 reactivate_fd(chan->fd, write_irq);
286 } 357 }
287 } 358 }
288 return(ret); 359 return ret;
289} 360}
290 361
291int console_write_chan(struct list_head *chans, const char *buf, int len) 362int console_write_chan(struct list_head *chans, const char *buf, int len)
@@ -301,19 +372,18 @@ int console_write_chan(struct list_head *chans, const char *buf, int len)
301 n = chan->ops->console_write(chan->fd, buf, len); 372 n = chan->ops->console_write(chan->fd, buf, len);
302 if(chan->primary) ret = n; 373 if(chan->primary) ret = n;
303 } 374 }
304 return(ret); 375 return ret;
305} 376}
306 377
307int console_open_chan(struct line *line, struct console *co, struct chan_opts *opts) 378int console_open_chan(struct line *line, struct console *co,
379 struct chan_opts *opts)
308{ 380{
309 if (!list_empty(&line->chan_list)) 381 int err;
310 return 0; 382
383 err = open_chan(&line->chan_list);
384 if(err)
385 return err;
311 386
312 if (0 != parse_chan_pair(line->init_str, &line->chan_list,
313 line->init_pri, co->index, opts))
314 return -1;
315 if (0 != open_chan(&line->chan_list))
316 return -1;
317 printk("Console initialized on /dev/%s%d\n",co->name,co->index); 387 printk("Console initialized on /dev/%s%d\n",co->name,co->index);
318 return 0; 388 return 0;
319} 389}
@@ -327,32 +397,36 @@ int chan_window_size(struct list_head *chans, unsigned short *rows_out,
327 list_for_each(ele, chans){ 397 list_for_each(ele, chans){
328 chan = list_entry(ele, struct chan, list); 398 chan = list_entry(ele, struct chan, list);
329 if(chan->primary){ 399 if(chan->primary){
330 if(chan->ops->window_size == NULL) return(0); 400 if(chan->ops->window_size == NULL)
331 return(chan->ops->window_size(chan->fd, chan->data, 401 return 0;
332 rows_out, cols_out)); 402 return chan->ops->window_size(chan->fd, chan->data,
403 rows_out, cols_out);
333 } 404 }
334 } 405 }
335 return(0); 406 return 0;
336} 407}
337 408
338void free_one_chan(struct chan *chan) 409void free_one_chan(struct chan *chan, int delay_free_irq)
339{ 410{
340 list_del(&chan->list); 411 list_del(&chan->list);
412
413 close_one_chan(chan, delay_free_irq);
414
341 if(chan->ops->free != NULL) 415 if(chan->ops->free != NULL)
342 (*chan->ops->free)(chan->data); 416 (*chan->ops->free)(chan->data);
343 free_irq_by_fd(chan->fd); 417
344 if(chan->primary && chan->output) ignore_sigio_fd(chan->fd); 418 if(chan->primary && chan->output) ignore_sigio_fd(chan->fd);
345 kfree(chan); 419 kfree(chan);
346} 420}
347 421
348void free_chan(struct list_head *chans) 422void free_chan(struct list_head *chans, int delay_free_irq)
349{ 423{
350 struct list_head *ele, *next; 424 struct list_head *ele, *next;
351 struct chan *chan; 425 struct chan *chan;
352 426
353 list_for_each_safe(ele, next, chans){ 427 list_for_each_safe(ele, next, chans){
354 chan = list_entry(ele, struct chan, list); 428 chan = list_entry(ele, struct chan, list);
355 free_one_chan(chan); 429 free_one_chan(chan, delay_free_irq);
356 } 430 }
357} 431}
358 432
@@ -363,23 +437,23 @@ static int one_chan_config_string(struct chan *chan, char *str, int size,
363 437
364 if(chan == NULL){ 438 if(chan == NULL){
365 CONFIG_CHUNK(str, size, n, "none", 1); 439 CONFIG_CHUNK(str, size, n, "none", 1);
366 return(n); 440 return n;
367 } 441 }
368 442
369 CONFIG_CHUNK(str, size, n, chan->ops->type, 0); 443 CONFIG_CHUNK(str, size, n, chan->ops->type, 0);
370 444
371 if(chan->dev == NULL){ 445 if(chan->dev == NULL){
372 CONFIG_CHUNK(str, size, n, "", 1); 446 CONFIG_CHUNK(str, size, n, "", 1);
373 return(n); 447 return n;
374 } 448 }
375 449
376 CONFIG_CHUNK(str, size, n, ":", 0); 450 CONFIG_CHUNK(str, size, n, ":", 0);
377 CONFIG_CHUNK(str, size, n, chan->dev, 0); 451 CONFIG_CHUNK(str, size, n, chan->dev, 0);
378 452
379 return(n); 453 return n;
380} 454}
381 455
382static int chan_pair_config_string(struct chan *in, struct chan *out, 456static int chan_pair_config_string(struct chan *in, struct chan *out,
383 char *str, int size, char **error_out) 457 char *str, int size, char **error_out)
384{ 458{
385 int n; 459 int n;
@@ -390,7 +464,7 @@ static int chan_pair_config_string(struct chan *in, struct chan *out,
390 464
391 if(in == out){ 465 if(in == out){
392 CONFIG_CHUNK(str, size, n, "", 1); 466 CONFIG_CHUNK(str, size, n, "", 1);
393 return(n); 467 return n;
394 } 468 }
395 469
396 CONFIG_CHUNK(str, size, n, ",", 1); 470 CONFIG_CHUNK(str, size, n, ",", 1);
@@ -399,10 +473,10 @@ static int chan_pair_config_string(struct chan *in, struct chan *out,
399 size -= n; 473 size -= n;
400 CONFIG_CHUNK(str, size, n, "", 1); 474 CONFIG_CHUNK(str, size, n, "", 1);
401 475
402 return(n); 476 return n;
403} 477}
404 478
405int chan_config_string(struct list_head *chans, char *str, int size, 479int chan_config_string(struct list_head *chans, char *str, int size,
406 char **error_out) 480 char **error_out)
407{ 481{
408 struct list_head *ele; 482 struct list_head *ele;
@@ -418,7 +492,7 @@ int chan_config_string(struct list_head *chans, char *str, int size,
418 out = chan; 492 out = chan;
419 } 493 }
420 494
421 return(chan_pair_config_string(in, out, str, size, error_out)); 495 return chan_pair_config_string(in, out, str, size, error_out);
422} 496}
423 497
424struct chan_type { 498struct chan_type {
@@ -462,7 +536,7 @@ struct chan_type chan_table[] = {
462#endif 536#endif
463}; 537};
464 538
465static struct chan *parse_chan(char *str, int pri, int device, 539static struct chan *parse_chan(struct line *line, char *str, int device,
466 struct chan_opts *opts) 540 struct chan_opts *opts)
467{ 541{
468 struct chan_type *entry; 542 struct chan_type *entry;
@@ -484,36 +558,42 @@ static struct chan *parse_chan(char *str, int pri, int device,
484 if(ops == NULL){ 558 if(ops == NULL){
485 my_printf("parse_chan couldn't parse \"%s\"\n", 559 my_printf("parse_chan couldn't parse \"%s\"\n",
486 str); 560 str);
487 return(NULL); 561 return NULL;
488 } 562 }
489 if(ops->init == NULL) return(NULL); 563 if(ops->init == NULL)
564 return NULL;
490 data = (*ops->init)(str, device, opts); 565 data = (*ops->init)(str, device, opts);
491 if(data == NULL) return(NULL); 566 if(data == NULL)
567 return NULL;
492 568
493 chan = kmalloc(sizeof(*chan), GFP_ATOMIC); 569 chan = kmalloc(sizeof(*chan), GFP_ATOMIC);
494 if(chan == NULL) return(NULL); 570 if(chan == NULL)
571 return NULL;
495 *chan = ((struct chan) { .list = LIST_HEAD_INIT(chan->list), 572 *chan = ((struct chan) { .list = LIST_HEAD_INIT(chan->list),
573 .free_list =
574 LIST_HEAD_INIT(chan->free_list),
575 .line = line,
496 .primary = 1, 576 .primary = 1,
497 .input = 0, 577 .input = 0,
498 .output = 0, 578 .output = 0,
499 .opened = 0, 579 .opened = 0,
580 .enabled = 0,
500 .fd = -1, 581 .fd = -1,
501 .pri = pri,
502 .ops = ops, 582 .ops = ops,
503 .data = data }); 583 .data = data });
504 return(chan); 584 return chan;
505} 585}
506 586
507int parse_chan_pair(char *str, struct list_head *chans, int pri, int device, 587int parse_chan_pair(char *str, struct line *line, int device,
508 struct chan_opts *opts) 588 struct chan_opts *opts)
509{ 589{
590 struct list_head *chans = &line->chan_list;
510 struct chan *new, *chan; 591 struct chan *new, *chan;
511 char *in, *out; 592 char *in, *out;
512 593
513 if(!list_empty(chans)){ 594 if(!list_empty(chans)){
514 chan = list_entry(chans->next, struct chan, list); 595 chan = list_entry(chans->next, struct chan, list);
515 if(chan->pri >= pri) return(0); 596 free_chan(chans, 0);
516 free_chan(chans);
517 INIT_LIST_HEAD(chans); 597 INIT_LIST_HEAD(chans);
518 } 598 }
519 599
@@ -522,24 +602,30 @@ int parse_chan_pair(char *str, struct list_head *chans, int pri, int device,
522 in = str; 602 in = str;
523 *out = '\0'; 603 *out = '\0';
524 out++; 604 out++;
525 new = parse_chan(in, pri, device, opts); 605 new = parse_chan(line, in, device, opts);
526 if(new == NULL) return(-1); 606 if(new == NULL)
607 return -1;
608
527 new->input = 1; 609 new->input = 1;
528 list_add(&new->list, chans); 610 list_add(&new->list, chans);
529 611
530 new = parse_chan(out, pri, device, opts); 612 new = parse_chan(line, out, device, opts);
531 if(new == NULL) return(-1); 613 if(new == NULL)
614 return -1;
615
532 list_add(&new->list, chans); 616 list_add(&new->list, chans);
533 new->output = 1; 617 new->output = 1;
534 } 618 }
535 else { 619 else {
536 new = parse_chan(str, pri, device, opts); 620 new = parse_chan(line, str, device, opts);
537 if(new == NULL) return(-1); 621 if(new == NULL)
622 return -1;
623
538 list_add(&new->list, chans); 624 list_add(&new->list, chans);
539 new->input = 1; 625 new->input = 1;
540 new->output = 1; 626 new->output = 1;
541 } 627 }
542 return(0); 628 return 0;
543} 629}
544 630
545int chan_out_fd(struct list_head *chans) 631int chan_out_fd(struct list_head *chans)
@@ -550,9 +636,9 @@ int chan_out_fd(struct list_head *chans)
550 list_for_each(ele, chans){ 636 list_for_each(ele, chans){
551 chan = list_entry(ele, struct chan, list); 637 chan = list_entry(ele, struct chan, list);
552 if(chan->primary && chan->output) 638 if(chan->primary && chan->output)
553 return(chan->fd); 639 return chan->fd;
554 } 640 }
555 return(-1); 641 return -1;
556} 642}
557 643
558void chan_interrupt(struct list_head *chans, struct work_struct *task, 644void chan_interrupt(struct list_head *chans, struct work_struct *task,
@@ -567,9 +653,9 @@ void chan_interrupt(struct list_head *chans, struct work_struct *task,
567 chan = list_entry(ele, struct chan, list); 653 chan = list_entry(ele, struct chan, list);
568 if(!chan->input || (chan->ops->read == NULL)) continue; 654 if(!chan->input || (chan->ops->read == NULL)) continue;
569 do { 655 do {
570 if((tty != NULL) && 656 if((tty != NULL) &&
571 (tty->flip.count >= TTY_FLIPBUF_SIZE)){ 657 (tty->flip.count >= TTY_FLIPBUF_SIZE)){
572 schedule_work(task); 658 schedule_delayed_work(task, 1);
573 goto out; 659 goto out;
574 } 660 }
575 err = chan->ops->read(chan->fd, &c, chan->data); 661 err = chan->ops->read(chan->fd, &c, chan->data);
@@ -582,29 +668,12 @@ void chan_interrupt(struct list_head *chans, struct work_struct *task,
582 if(chan->primary){ 668 if(chan->primary){
583 if(tty != NULL) 669 if(tty != NULL)
584 tty_hangup(tty); 670 tty_hangup(tty);
585 line_disable(tty, irq); 671 close_chan(chans, 1);
586 close_chan(chans);
587 free_chan(chans);
588 return; 672 return;
589 } 673 }
590 else { 674 else close_one_chan(chan, 1);
591 if(chan->ops->close != NULL)
592 chan->ops->close(chan->fd, chan->data);
593 free_one_chan(chan);
594 }
595 } 675 }
596 } 676 }
597 out: 677 out:
598 if(tty) tty_flip_buffer_push(tty); 678 if(tty) tty_flip_buffer_push(tty);
599} 679}
600
601/*
602 * Overrides for Emacs so that we follow Linus's tabbing style.
603 * Emacs will notice this stuff at the end of the file and automatically
604 * adjust the settings for this buffer only. This must remain at the end
605 * of the file.
606 * ---------------------------------------------------------------------------
607 * Local variables:
608 * c-file-style: "linux"
609 * End:
610 */
diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c
index e0fdffa2d542..46ceb25a9959 100644
--- a/arch/um/drivers/line.c
+++ b/arch/um/drivers/line.c
@@ -1,4 +1,4 @@
1/* 1/*
2 * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
@@ -23,8 +23,9 @@
23 23
24static irqreturn_t line_interrupt(int irq, void *data, struct pt_regs *unused) 24static irqreturn_t line_interrupt(int irq, void *data, struct pt_regs *unused)
25{ 25{
26 struct tty_struct *tty = data; 26 struct chan *chan = data;
27 struct line *line = tty->driver_data; 27 struct line *line = chan->line;
28 struct tty_struct *tty = line->tty;
28 29
29 if (line) 30 if (line)
30 chan_interrupt(&line->chan_list, &line->task, tty, irq); 31 chan_interrupt(&line->chan_list, &line->task, tty, irq);
@@ -33,10 +34,11 @@ static irqreturn_t line_interrupt(int irq, void *data, struct pt_regs *unused)
33 34
34static void line_timer_cb(void *arg) 35static void line_timer_cb(void *arg)
35{ 36{
36 struct tty_struct *tty = arg; 37 struct line *line = arg;
37 struct line *line = tty->driver_data;
38 38
39 line_interrupt(line->driver->read_irq, arg, NULL); 39 if(!line->throttled)
40 chan_interrupt(&line->chan_list, &line->task, line->tty,
41 line->driver->read_irq);
40} 42}
41 43
42/* Returns the free space inside the ring buffer of this line. 44/* Returns the free space inside the ring buffer of this line.
@@ -124,7 +126,8 @@ static int buffer_data(struct line *line, const char *buf, int len)
124 if (len < end){ 126 if (len < end){
125 memcpy(line->tail, buf, len); 127 memcpy(line->tail, buf, len);
126 line->tail += len; 128 line->tail += len;
127 } else { 129 }
130 else {
128 /* The circular buffer is wrapping */ 131 /* The circular buffer is wrapping */
129 memcpy(line->tail, buf, end); 132 memcpy(line->tail, buf, end);
130 buf += end; 133 buf += end;
@@ -170,7 +173,7 @@ static int flush_buffer(struct line *line)
170 } 173 }
171 174
172 count = line->tail - line->head; 175 count = line->tail - line->head;
173 n = write_chan(&line->chan_list, line->head, count, 176 n = write_chan(&line->chan_list, line->head, count,
174 line->driver->write_irq); 177 line->driver->write_irq);
175 178
176 if(n < 0) 179 if(n < 0)
@@ -227,7 +230,7 @@ int line_write(struct tty_struct *tty, const unsigned char *buf, int len)
227 if (err <= 0 && (err != -EAGAIN || !ret)) 230 if (err <= 0 && (err != -EAGAIN || !ret))
228 ret = err; 231 ret = err;
229 } else { 232 } else {
230 n = write_chan(&line->chan_list, buf, len, 233 n = write_chan(&line->chan_list, buf, len,
231 line->driver->write_irq); 234 line->driver->write_irq);
232 if (n < 0) { 235 if (n < 0) {
233 ret = n; 236 ret = n;
@@ -338,11 +341,36 @@ int line_ioctl(struct tty_struct *tty, struct file * file,
338 return ret; 341 return ret;
339} 342}
340 343
344void line_throttle(struct tty_struct *tty)
345{
346 struct line *line = tty->driver_data;
347
348 deactivate_chan(&line->chan_list, line->driver->read_irq);
349 line->throttled = 1;
350}
351
352void line_unthrottle(struct tty_struct *tty)
353{
354 struct line *line = tty->driver_data;
355
356 line->throttled = 0;
357 chan_interrupt(&line->chan_list, &line->task, tty,
358 line->driver->read_irq);
359
360 /* Maybe there is enough stuff pending that calling the interrupt
361 * throttles us again. In this case, line->throttled will be 1
362 * again and we shouldn't turn the interrupt back on.
363 */
364 if(!line->throttled)
365 reactivate_chan(&line->chan_list, line->driver->read_irq);
366}
367
341static irqreturn_t line_write_interrupt(int irq, void *data, 368static irqreturn_t line_write_interrupt(int irq, void *data,
342 struct pt_regs *unused) 369 struct pt_regs *unused)
343{ 370{
344 struct tty_struct *tty = data; 371 struct chan *chan = data;
345 struct line *line = tty->driver_data; 372 struct line *line = chan->line;
373 struct tty_struct *tty = line->tty;
346 int err; 374 int err;
347 375
348 /* Interrupts are enabled here because we registered the interrupt with 376 /* Interrupts are enabled here because we registered the interrupt with
@@ -364,7 +392,7 @@ static irqreturn_t line_write_interrupt(int irq, void *data,
364 if (test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags) && 392 if (test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags) &&
365 (tty->ldisc.write_wakeup != NULL)) 393 (tty->ldisc.write_wakeup != NULL))
366 (tty->ldisc.write_wakeup)(tty); 394 (tty->ldisc.write_wakeup)(tty);
367 395
368 /* BLOCKING mode 396 /* BLOCKING mode
369 * In blocking mode, everything sleeps on tty->write_wait. 397 * In blocking mode, everything sleeps on tty->write_wait.
370 * Sleeping in the console driver would break non-blocking 398 * Sleeping in the console driver would break non-blocking
@@ -376,53 +404,29 @@ static irqreturn_t line_write_interrupt(int irq, void *data,
376 return IRQ_HANDLED; 404 return IRQ_HANDLED;
377} 405}
378 406
379int line_setup_irq(int fd, int input, int output, struct tty_struct *tty) 407int line_setup_irq(int fd, int input, int output, struct line *line, void *data)
380{ 408{
381 struct line *line = tty->driver_data;
382 struct line_driver *driver = line->driver; 409 struct line_driver *driver = line->driver;
383 int err = 0, flags = SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM; 410 int err = 0, flags = SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM;
384 411
385 if (input) 412 if (input)
386 err = um_request_irq(driver->read_irq, fd, IRQ_READ, 413 err = um_request_irq(driver->read_irq, fd, IRQ_READ,
387 line_interrupt, flags, 414 line_interrupt, flags,
388 driver->read_irq_name, tty); 415 driver->read_irq_name, data);
389 if (err) 416 if (err)
390 return err; 417 return err;
391 if (output) 418 if (output)
392 err = um_request_irq(driver->write_irq, fd, IRQ_WRITE, 419 err = um_request_irq(driver->write_irq, fd, IRQ_WRITE,
393 line_write_interrupt, flags, 420 line_write_interrupt, flags,
394 driver->write_irq_name, tty); 421 driver->write_irq_name, data);
395 line->have_irq = 1; 422 line->have_irq = 1;
396 return err; 423 return err;
397} 424}
398 425
399void line_disable(struct tty_struct *tty, int current_irq) 426int line_open(struct line *lines, struct tty_struct *tty)
400{
401 struct line *line = tty->driver_data;
402
403 if(!line->have_irq)
404 return;
405
406 if(line->driver->read_irq == current_irq)
407 free_irq_later(line->driver->read_irq, tty);
408 else {
409 free_irq(line->driver->read_irq, tty);
410 }
411
412 if(line->driver->write_irq == current_irq)
413 free_irq_later(line->driver->write_irq, tty);
414 else {
415 free_irq(line->driver->write_irq, tty);
416 }
417
418 line->have_irq = 0;
419}
420
421int line_open(struct line *lines, struct tty_struct *tty,
422 struct chan_opts *opts)
423{ 427{
424 struct line *line; 428 struct line *line;
425 int err = 0; 429 int err = -ENODEV;
426 430
427 line = &lines[tty->index]; 431 line = &lines[tty->index];
428 tty->driver_data = line; 432 tty->driver_data = line;
@@ -430,31 +434,29 @@ int line_open(struct line *lines, struct tty_struct *tty,
430 /* The IRQ which takes this lock is not yet enabled and won't be run 434 /* The IRQ which takes this lock is not yet enabled and won't be run
431 * before the end, so we don't need to use spin_lock_irq.*/ 435 * before the end, so we don't need to use spin_lock_irq.*/
432 spin_lock(&line->lock); 436 spin_lock(&line->lock);
433 if (tty->count == 1) { 437
434 if (!line->valid) { 438 tty->driver_data = line;
435 err = -ENODEV; 439 line->tty = tty;
436 goto out; 440 if(!line->valid)
437 } 441 goto out;
438 if (list_empty(&line->chan_list)) { 442
439 err = parse_chan_pair(line->init_str, &line->chan_list, 443 if(tty->count == 1){
440 line->init_pri, tty->index, opts); 444 /* Here the device is opened, if necessary, and interrupt
441 if(err) goto out; 445 * is registered.
442 err = open_chan(&line->chan_list); 446 */
443 if(err) goto out; 447 enable_chan(line);
448 INIT_WORK(&line->task, line_timer_cb, line);
449
450 if(!line->sigio){
451 chan_enable_winch(&line->chan_list, tty);
452 line->sigio = 1;
444 } 453 }
445 /* Here the interrupt is registered.*/
446 enable_chan(&line->chan_list, tty);
447 INIT_WORK(&line->task, line_timer_cb, tty);
448 }
449 454
450 if(!line->sigio){ 455 chan_window_size(&line->chan_list, &tty->winsize.ws_row,
451 chan_enable_winch(&line->chan_list, tty); 456 &tty->winsize.ws_col);
452 line->sigio = 1;
453 } 457 }
454 chan_window_size(&line->chan_list, &tty->winsize.ws_row,
455 &tty->winsize.ws_col);
456 line->count++;
457 458
459 err = 0;
458out: 460out:
459 spin_unlock(&line->lock); 461 spin_unlock(&line->lock);
460 return err; 462 return err;
@@ -474,15 +476,14 @@ void line_close(struct tty_struct *tty, struct file * filp)
474 /* We ignore the error anyway! */ 476 /* We ignore the error anyway! */
475 flush_buffer(line); 477 flush_buffer(line);
476 478
477 line->count--; 479 if(tty->count == 1){
478 if (tty->count == 1) { 480 line->tty = NULL;
479 line_disable(tty, -1);
480 tty->driver_data = NULL; 481 tty->driver_data = NULL;
481 }
482 482
483 if((line->count == 0) && line->sigio){ 483 if(line->sigio){
484 unregister_winch(tty); 484 unregister_winch(tty);
485 line->sigio = 0; 485 line->sigio = 0;
486 }
486 } 487 }
487 488
488 spin_unlock_irq(&line->lock); 489 spin_unlock_irq(&line->lock);
@@ -493,17 +494,15 @@ void close_lines(struct line *lines, int nlines)
493 int i; 494 int i;
494 495
495 for(i = 0; i < nlines; i++) 496 for(i = 0; i < nlines; i++)
496 close_chan(&lines[i].chan_list); 497 close_chan(&lines[i].chan_list, 0);
497} 498}
498 499
499/* Common setup code for both startup command line and mconsole initialization. 500/* Common setup code for both startup command line and mconsole initialization.
500 * @lines contains the the array (of size @num) to modify; 501 * @lines contains the the array (of size @num) to modify;
501 * @init is the setup string; 502 * @init is the setup string;
502 * @all_allowed is a boolean saying if we can setup the whole @lines 503 */
503 * at once. For instance, it will be usually true for startup init. (where we
504 * can use con=xterm) and false for mconsole.*/
505 504
506int line_setup(struct line *lines, unsigned int num, char *init, int all_allowed) 505int line_setup(struct line *lines, unsigned int num, char *init)
507{ 506{
508 int i, n; 507 int i, n;
509 char *end; 508 char *end;
@@ -512,10 +511,11 @@ int line_setup(struct line *lines, unsigned int num, char *init, int all_allowed
512 /* We said con=/ssl= instead of con#=, so we are configuring all 511 /* We said con=/ssl= instead of con#=, so we are configuring all
513 * consoles at once.*/ 512 * consoles at once.*/
514 n = -1; 513 n = -1;
515 } else { 514 }
515 else {
516 n = simple_strtoul(init, &end, 0); 516 n = simple_strtoul(init, &end, 0);
517 if(*end != '='){ 517 if(*end != '='){
518 printk(KERN_ERR "line_setup failed to parse \"%s\"\n", 518 printk(KERN_ERR "line_setup failed to parse \"%s\"\n",
519 init); 519 init);
520 return 0; 520 return 0;
521 } 521 }
@@ -527,8 +527,9 @@ int line_setup(struct line *lines, unsigned int num, char *init, int all_allowed
527 printk("line_setup - %d out of range ((0 ... %d) allowed)\n", 527 printk("line_setup - %d out of range ((0 ... %d) allowed)\n",
528 n, num - 1); 528 n, num - 1);
529 return 0; 529 return 0;
530 } else if (n >= 0){ 530 }
531 if (lines[n].count > 0) { 531 else if (n >= 0){
532 if (lines[n].tty != NULL) {
532 printk("line_setup - device %d is open\n", n); 533 printk("line_setup - device %d is open\n", n);
533 return 0; 534 return 0;
534 } 535 }
@@ -539,13 +540,10 @@ int line_setup(struct line *lines, unsigned int num, char *init, int all_allowed
539 else { 540 else {
540 lines[n].init_str = init; 541 lines[n].init_str = init;
541 lines[n].valid = 1; 542 lines[n].valid = 1;
542 } 543 }
543 } 544 }
544 } else if(!all_allowed){ 545 }
545 printk("line_setup - can't configure all devices from " 546 else {
546 "mconsole\n");
547 return 0;
548 } else {
549 for(i = 0; i < num; i++){ 547 for(i = 0; i < num; i++){
550 if(lines[i].init_pri <= INIT_ALL){ 548 if(lines[i].init_pri <= INIT_ALL){
551 lines[i].init_pri = INIT_ALL; 549 lines[i].init_pri = INIT_ALL;
@@ -557,18 +555,33 @@ int line_setup(struct line *lines, unsigned int num, char *init, int all_allowed
557 } 555 }
558 } 556 }
559 } 557 }
560 return 1; 558 return n == -1 ? num : n;
561} 559}
562 560
563int line_config(struct line *lines, unsigned int num, char *str) 561int line_config(struct line *lines, unsigned int num, char *str,
562 struct chan_opts *opts)
564{ 563{
565 char *new = uml_strdup(str); 564 struct line *line;
565 char *new;
566 int n;
566 567
568 if(*str == '='){
569 printk("line_config - can't configure all devices from "
570 "mconsole\n");
571 return 1;
572 }
573
574 new = kstrdup(str, GFP_KERNEL);
567 if(new == NULL){ 575 if(new == NULL){
568 printk("line_config - uml_strdup failed\n"); 576 printk("line_config - kstrdup failed\n");
569 return -ENOMEM; 577 return 1;
570 } 578 }
571 return !line_setup(lines, num, new, 0); 579 n = line_setup(lines, num, new);
580 if(n < 0)
581 return 1;
582
583 line = &lines[n];
584 return parse_chan_pair(line->init_str, line, n, opts);
572} 585}
573 586
574int line_get_config(char *name, struct line *lines, unsigned int num, char *str, 587int line_get_config(char *name, struct line *lines, unsigned int num, char *str,
@@ -594,7 +607,7 @@ int line_get_config(char *name, struct line *lines, unsigned int num, char *str,
594 spin_lock(&line->lock); 607 spin_lock(&line->lock);
595 if(!line->valid) 608 if(!line->valid)
596 CONFIG_CHUNK(str, size, n, "none", 1); 609 CONFIG_CHUNK(str, size, n, "none", 1);
597 else if(line->count == 0) 610 else if(line->tty == NULL)
598 CONFIG_CHUNK(str, size, n, line->init_str, 1); 611 CONFIG_CHUNK(str, size, n, line->init_str, 1);
599 else n = chan_config_string(&line->chan_list, str, size, error_out); 612 else n = chan_config_string(&line->chan_list, str, size, error_out);
600 spin_unlock(&line->lock); 613 spin_unlock(&line->lock);
@@ -619,14 +632,18 @@ int line_id(char **str, int *start_out, int *end_out)
619 632
620int line_remove(struct line *lines, unsigned int num, int n) 633int line_remove(struct line *lines, unsigned int num, int n)
621{ 634{
635 int err;
622 char config[sizeof("conxxxx=none\0")]; 636 char config[sizeof("conxxxx=none\0")];
623 637
624 sprintf(config, "%d=none", n); 638 sprintf(config, "%d=none", n);
625 return !line_setup(lines, num, config, 0); 639 err = line_setup(lines, num, config);
640 if(err >= 0)
641 err = 0;
642 return err;
626} 643}
627 644
628struct tty_driver *line_register_devfs(struct lines *set, 645struct tty_driver *line_register_devfs(struct lines *set,
629 struct line_driver *line_driver, 646 struct line_driver *line_driver,
630 struct tty_operations *ops, struct line *lines, 647 struct tty_operations *ops, struct line *lines,
631 int nlines) 648 int nlines)
632{ 649{
@@ -655,7 +672,7 @@ struct tty_driver *line_register_devfs(struct lines *set,
655 } 672 }
656 673
657 for(i = 0; i < nlines; i++){ 674 for(i = 0; i < nlines; i++){
658 if(!lines[i].valid) 675 if(!lines[i].valid)
659 tty_unregister_device(driver, i); 676 tty_unregister_device(driver, i);
660 } 677 }
661 678
@@ -663,24 +680,28 @@ struct tty_driver *line_register_devfs(struct lines *set,
663 return driver; 680 return driver;
664} 681}
665 682
666static spinlock_t winch_handler_lock; 683static DEFINE_SPINLOCK(winch_handler_lock);
667LIST_HEAD(winch_handlers); 684static LIST_HEAD(winch_handlers);
668 685
669void lines_init(struct line *lines, int nlines) 686void lines_init(struct line *lines, int nlines, struct chan_opts *opts)
670{ 687{
671 struct line *line; 688 struct line *line;
672 int i; 689 int i;
673 690
674 spin_lock_init(&winch_handler_lock);
675 for(i = 0; i < nlines; i++){ 691 for(i = 0; i < nlines; i++){
676 line = &lines[i]; 692 line = &lines[i];
677 INIT_LIST_HEAD(&line->chan_list); 693 INIT_LIST_HEAD(&line->chan_list);
678 spin_lock_init(&line->lock); 694
679 if(line->init_str != NULL){ 695 if(line->init_str == NULL)
680 line->init_str = uml_strdup(line->init_str); 696 continue;
681 if(line->init_str == NULL) 697
682 printk("lines_init - uml_strdup returned " 698 line->init_str = kstrdup(line->init_str, GFP_KERNEL);
683 "NULL\n"); 699 if(line->init_str == NULL)
700 printk("lines_init - kstrdup returned NULL\n");
701
702 if(parse_chan_pair(line->init_str, line, i, opts)){
703 printk("parse_chan_pair failed for device %d\n", i);
704 line->valid = 0;
684 } 705 }
685 } 706 }
686} 707}
@@ -717,8 +738,7 @@ irqreturn_t winch_interrupt(int irq, void *data, struct pt_regs *unused)
717 tty = winch->tty; 738 tty = winch->tty;
718 if (tty != NULL) { 739 if (tty != NULL) {
719 line = tty->driver_data; 740 line = tty->driver_data;
720 chan_window_size(&line->chan_list, 741 chan_window_size(&line->chan_list, &tty->winsize.ws_row,
721 &tty->winsize.ws_row,
722 &tty->winsize.ws_col); 742 &tty->winsize.ws_col);
723 kill_pg(tty->pgrp, SIGWINCH, 1); 743 kill_pg(tty->pgrp, SIGWINCH, 1);
724 } 744 }
@@ -749,60 +769,54 @@ void register_winch_irq(int fd, int tty_fd, int pid, struct tty_struct *tty)
749 spin_unlock(&winch_handler_lock); 769 spin_unlock(&winch_handler_lock);
750 770
751 if(um_request_irq(WINCH_IRQ, fd, IRQ_READ, winch_interrupt, 771 if(um_request_irq(WINCH_IRQ, fd, IRQ_READ, winch_interrupt,
752 SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM, 772 SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM,
753 "winch", winch) < 0) 773 "winch", winch) < 0)
754 printk("register_winch_irq - failed to register IRQ\n"); 774 printk("register_winch_irq - failed to register IRQ\n");
755} 775}
756 776
777static void free_winch(struct winch *winch)
778{
779 list_del(&winch->list);
780
781 if(winch->pid != -1)
782 os_kill_process(winch->pid, 1);
783 if(winch->fd != -1)
784 os_close_file(winch->fd);
785
786 free_irq(WINCH_IRQ, winch);
787 kfree(winch);
788}
789
757static void unregister_winch(struct tty_struct *tty) 790static void unregister_winch(struct tty_struct *tty)
758{ 791{
759 struct list_head *ele; 792 struct list_head *ele;
760 struct winch *winch, *found = NULL; 793 struct winch *winch;
761 794
762 spin_lock(&winch_handler_lock); 795 spin_lock(&winch_handler_lock);
796
763 list_for_each(ele, &winch_handlers){ 797 list_for_each(ele, &winch_handlers){
764 winch = list_entry(ele, struct winch, list); 798 winch = list_entry(ele, struct winch, list);
765 if(winch->tty == tty){ 799 if(winch->tty == tty){
766 found = winch; 800 free_winch(winch);
767 break; 801 break;
768 } 802 }
769 } 803 }
770 if(found == NULL)
771 goto err;
772
773 list_del(&winch->list);
774 spin_unlock(&winch_handler_lock);
775
776 if(winch->pid != -1)
777 os_kill_process(winch->pid, 1);
778
779 free_irq(WINCH_IRQ, winch);
780 kfree(winch);
781
782 return;
783err:
784 spin_unlock(&winch_handler_lock); 804 spin_unlock(&winch_handler_lock);
785} 805}
786 806
787/* XXX: No lock as it's an exitcall... is this valid? Depending on cleanup
788 * order... are we sure that nothing else is done on the list? */
789static void winch_cleanup(void) 807static void winch_cleanup(void)
790{ 808{
791 struct list_head *ele; 809 struct list_head *ele, *next;
792 struct winch *winch; 810 struct winch *winch;
793 811
794 list_for_each(ele, &winch_handlers){ 812 spin_lock(&winch_handler_lock);
813
814 list_for_each_safe(ele, next, &winch_handlers){
795 winch = list_entry(ele, struct winch, list); 815 winch = list_entry(ele, struct winch, list);
796 if(winch->fd != -1){ 816 free_winch(winch);
797 /* Why is this different from the above free_irq(),
798 * which deactivates SIGIO? This searches the FD
799 * somewhere else and removes it from the list... */
800 deactivate_fd(winch->fd, WINCH_IRQ);
801 os_close_file(winch->fd);
802 }
803 if(winch->pid != -1)
804 os_kill_process(winch->pid, 1);
805 } 817 }
818
819 spin_unlock(&winch_handler_lock);
806} 820}
807__uml_exitcall(winch_cleanup); 821__uml_exitcall(winch_cleanup);
808 822
@@ -811,10 +825,10 @@ char *add_xterm_umid(char *base)
811 char *umid, *title; 825 char *umid, *title;
812 int len; 826 int len;
813 827
814 umid = get_umid(1); 828 umid = get_umid();
815 if(umid == NULL) 829 if(*umid == '\0')
816 return base; 830 return base;
817 831
818 len = strlen(base) + strlen(" ()") + strlen(umid) + 1; 832 len = strlen(base) + strlen(" ()") + strlen(umid) + 1;
819 title = kmalloc(len, GFP_KERNEL); 833 title = kmalloc(len, GFP_KERNEL);
820 if(title == NULL){ 834 if(title == NULL){
diff --git a/arch/um/drivers/mconsole_kern.c b/arch/um/drivers/mconsole_kern.c
index 12c95368124a..be610125429f 100644
--- a/arch/um/drivers/mconsole_kern.c
+++ b/arch/um/drivers/mconsole_kern.c
@@ -20,6 +20,7 @@
20#include "linux/namei.h" 20#include "linux/namei.h"
21#include "linux/proc_fs.h" 21#include "linux/proc_fs.h"
22#include "linux/syscalls.h" 22#include "linux/syscalls.h"
23#include "linux/console.h"
23#include "asm/irq.h" 24#include "asm/irq.h"
24#include "asm/uaccess.h" 25#include "asm/uaccess.h"
25#include "user_util.h" 26#include "user_util.h"
@@ -34,7 +35,7 @@
34#include "irq_kern.h" 35#include "irq_kern.h"
35#include "choose-mode.h" 36#include "choose-mode.h"
36 37
37static int do_unlink_socket(struct notifier_block *notifier, 38static int do_unlink_socket(struct notifier_block *notifier,
38 unsigned long what, void *data) 39 unsigned long what, void *data)
39{ 40{
40 return(mconsole_unlink_socket()); 41 return(mconsole_unlink_socket());
@@ -46,12 +47,12 @@ static struct notifier_block reboot_notifier = {
46 .priority = 0, 47 .priority = 0,
47}; 48};
48 49
49/* Safe without explicit locking for now. Tasklets provide their own 50/* Safe without explicit locking for now. Tasklets provide their own
50 * locking, and the interrupt handler is safe because it can't interrupt 51 * locking, and the interrupt handler is safe because it can't interrupt
51 * itself and it can only happen on CPU 0. 52 * itself and it can only happen on CPU 0.
52 */ 53 */
53 54
54LIST_HEAD(mc_requests); 55static LIST_HEAD(mc_requests);
55 56
56static void mc_work_proc(void *unused) 57static void mc_work_proc(void *unused)
57{ 58{
@@ -60,7 +61,7 @@ static void mc_work_proc(void *unused)
60 61
61 while(!list_empty(&mc_requests)){ 62 while(!list_empty(&mc_requests)){
62 local_save_flags(flags); 63 local_save_flags(flags);
63 req = list_entry(mc_requests.next, struct mconsole_entry, 64 req = list_entry(mc_requests.next, struct mconsole_entry,
64 list); 65 list);
65 list_del(&req->list); 66 list_del(&req->list);
66 local_irq_restore(flags); 67 local_irq_restore(flags);
@@ -69,7 +70,7 @@ static void mc_work_proc(void *unused)
69 } 70 }
70} 71}
71 72
72DECLARE_WORK(mconsole_work, mc_work_proc, NULL); 73static DECLARE_WORK(mconsole_work, mc_work_proc, NULL);
73 74
74static irqreturn_t mconsole_interrupt(int irq, void *dev_id, 75static irqreturn_t mconsole_interrupt(int irq, void *dev_id,
75 struct pt_regs *regs) 76 struct pt_regs *regs)
@@ -103,8 +104,8 @@ void mconsole_version(struct mc_request *req)
103{ 104{
104 char version[256]; 105 char version[256];
105 106
106 sprintf(version, "%s %s %s %s %s", system_utsname.sysname, 107 sprintf(version, "%s %s %s %s %s", system_utsname.sysname,
107 system_utsname.nodename, system_utsname.release, 108 system_utsname.nodename, system_utsname.release,
108 system_utsname.version, system_utsname.machine); 109 system_utsname.version, system_utsname.machine);
109 mconsole_reply(req, version, 0, 0); 110 mconsole_reply(req, version, 0, 0);
110} 111}
@@ -348,7 +349,7 @@ static struct mc_device *mconsole_find_dev(char *name)
348 349
349#define CONFIG_BUF_SIZE 64 350#define CONFIG_BUF_SIZE 64
350 351
351static void mconsole_get_config(int (*get_config)(char *, char *, int, 352static void mconsole_get_config(int (*get_config)(char *, char *, int,
352 char **), 353 char **),
353 struct mc_request *req, char *name) 354 struct mc_request *req, char *name)
354{ 355{
@@ -389,7 +390,6 @@ static void mconsole_get_config(int (*get_config)(char *, char *, int,
389 out: 390 out:
390 if(buf != default_buf) 391 if(buf != default_buf)
391 kfree(buf); 392 kfree(buf);
392
393} 393}
394 394
395void mconsole_config(struct mc_request *req) 395void mconsole_config(struct mc_request *req)
@@ -420,9 +420,9 @@ void mconsole_config(struct mc_request *req)
420 420
421void mconsole_remove(struct mc_request *req) 421void mconsole_remove(struct mc_request *req)
422{ 422{
423 struct mc_device *dev; 423 struct mc_device *dev;
424 char *ptr = req->request.data, *err_msg = ""; 424 char *ptr = req->request.data, *err_msg = "";
425 char error[256]; 425 char error[256];
426 int err, start, end, n; 426 int err, start, end, n;
427 427
428 ptr += strlen("remove"); 428 ptr += strlen("remove");
@@ -433,37 +433,112 @@ void mconsole_remove(struct mc_request *req)
433 return; 433 return;
434 } 434 }
435 435
436 ptr = &ptr[strlen(dev->name)]; 436 ptr = &ptr[strlen(dev->name)];
437 437
438 err = 1; 438 err = 1;
439 n = (*dev->id)(&ptr, &start, &end); 439 n = (*dev->id)(&ptr, &start, &end);
440 if(n < 0){ 440 if(n < 0){
441 err_msg = "Couldn't parse device number"; 441 err_msg = "Couldn't parse device number";
442 goto out; 442 goto out;
443 } 443 }
444 else if((n < start) || (n > end)){ 444 else if((n < start) || (n > end)){
445 sprintf(error, "Invalid device number - must be between " 445 sprintf(error, "Invalid device number - must be between "
446 "%d and %d", start, end); 446 "%d and %d", start, end);
447 err_msg = error; 447 err_msg = error;
448 goto out; 448 goto out;
449 } 449 }
450 450
451 err = (*dev->remove)(n); 451 err = (*dev->remove)(n);
452 switch(err){ 452 switch(err){
453 case -ENODEV: 453 case -ENODEV:
454 err_msg = "Device doesn't exist"; 454 err_msg = "Device doesn't exist";
455 break; 455 break;
456 case -EBUSY: 456 case -EBUSY:
457 err_msg = "Device is currently open"; 457 err_msg = "Device is currently open";
458 break; 458 break;
459 default: 459 default:
460 break; 460 break;
461 } 461 }
462 out: 462out:
463 mconsole_reply(req, err_msg, err, 0); 463 mconsole_reply(req, err_msg, err, 0);
464} 464}
465 465
466static DEFINE_SPINLOCK(console_lock);
467static LIST_HEAD(clients);
468static char console_buf[MCONSOLE_MAX_DATA];
469static int console_index = 0;
470
471static void console_write(struct console *console, const char *string,
472 unsigned len)
473{
474 struct list_head *ele;
475 int n;
476
477 if(list_empty(&clients))
478 return;
479
480 while(1){
481 n = min(len, ARRAY_SIZE(console_buf) - console_index);
482 strncpy(&console_buf[console_index], string, n);
483 console_index += n;
484 string += n;
485 len -= n;
486 if(len == 0)
487 return;
488
489 list_for_each(ele, &clients){
490 struct mconsole_entry *entry;
491
492 entry = list_entry(ele, struct mconsole_entry, list);
493 mconsole_reply_len(&entry->request, console_buf,
494 console_index, 0, 1);
495 }
496
497 console_index = 0;
498 }
499}
500
501static struct console mc_console = { .name = "mc",
502 .write = console_write,
503 .flags = CON_PRINTBUFFER | CON_ENABLED,
504 .index = -1 };
505
506static int mc_add_console(void)
507{
508 register_console(&mc_console);
509 return 0;
510}
511
512late_initcall(mc_add_console);
513
514static void with_console(struct mc_request *req, void (*proc)(void *),
515 void *arg)
516{
517 struct mconsole_entry entry;
518 unsigned long flags;
519
520 INIT_LIST_HEAD(&entry.list);
521 entry.request = *req;
522 list_add(&entry.list, &clients);
523 spin_lock_irqsave(&console_lock, flags);
524
525 (*proc)(arg);
526
527 mconsole_reply_len(req, console_buf, console_index, 0, 0);
528 console_index = 0;
529
530 spin_unlock_irqrestore(&console_lock, flags);
531 list_del(&entry.list);
532}
533
466#ifdef CONFIG_MAGIC_SYSRQ 534#ifdef CONFIG_MAGIC_SYSRQ
535static void sysrq_proc(void *arg)
536{
537 char *op = arg;
538
539 handle_sysrq(*op, &current->thread.regs, NULL);
540}
541
467void mconsole_sysrq(struct mc_request *req) 542void mconsole_sysrq(struct mc_request *req)
468{ 543{
469 char *ptr = req->request.data; 544 char *ptr = req->request.data;
@@ -471,8 +546,13 @@ void mconsole_sysrq(struct mc_request *req)
471 ptr += strlen("sysrq"); 546 ptr += strlen("sysrq");
472 while(isspace(*ptr)) ptr++; 547 while(isspace(*ptr)) ptr++;
473 548
474 mconsole_reply(req, "", 0, 0); 549 /* With 'b', the system will shut down without a chance to reply,
475 handle_sysrq(*ptr, &current->thread.regs, NULL); 550 * so in this case, we reply first.
551 */
552 if(*ptr == 'b')
553 mconsole_reply(req, "", 0, 0);
554
555 with_console(req, sysrq_proc, ptr);
476} 556}
477#else 557#else
478void mconsole_sysrq(struct mc_request *req) 558void mconsole_sysrq(struct mc_request *req)
@@ -481,6 +561,14 @@ void mconsole_sysrq(struct mc_request *req)
481} 561}
482#endif 562#endif
483 563
564static void stack_proc(void *arg)
565{
566 struct task_struct *from = current, *to = arg;
567
568 to->thread.saved_task = from;
569 switch_to(from, to, from);
570}
571
484/* Mconsole stack trace 572/* Mconsole stack trace
485 * Added by Allan Graves, Jeff Dike 573 * Added by Allan Graves, Jeff Dike
486 * Dumps a stacks registers to the linux console. 574 * Dumps a stacks registers to the linux console.
@@ -488,37 +576,34 @@ void mconsole_sysrq(struct mc_request *req)
488 */ 576 */
489void do_stack(struct mc_request *req) 577void do_stack(struct mc_request *req)
490{ 578{
491 char *ptr = req->request.data; 579 char *ptr = req->request.data;
492 int pid_requested= -1; 580 int pid_requested= -1;
493 struct task_struct *from = NULL; 581 struct task_struct *from = NULL;
494 struct task_struct *to = NULL; 582 struct task_struct *to = NULL;
495 583
496 /* Would be nice: 584 /* Would be nice:
497 * 1) Send showregs output to mconsole. 585 * 1) Send showregs output to mconsole.
498 * 2) Add a way to stack dump all pids. 586 * 2) Add a way to stack dump all pids.
499 */ 587 */
500 588
501 ptr += strlen("stack"); 589 ptr += strlen("stack");
502 while(isspace(*ptr)) ptr++; 590 while(isspace(*ptr)) ptr++;
503
504 /* Should really check for multiple pids or reject bad args here */
505 /* What do the arguments in mconsole_reply mean? */
506 if(sscanf(ptr, "%d", &pid_requested) == 0){
507 mconsole_reply(req, "Please specify a pid", 1, 0);
508 return;
509 }
510 591
511 from = current; 592 /* Should really check for multiple pids or reject bad args here */
512 to = find_task_by_pid(pid_requested); 593 /* What do the arguments in mconsole_reply mean? */
594 if(sscanf(ptr, "%d", &pid_requested) == 0){
595 mconsole_reply(req, "Please specify a pid", 1, 0);
596 return;
597 }
513 598
514 if((to == NULL) || (pid_requested == 0)) { 599 from = current;
515 mconsole_reply(req, "Couldn't find that pid", 1, 0);
516 return;
517 }
518 to->thread.saved_task = current;
519 600
520 switch_to(from, to, from); 601 to = find_task_by_pid(pid_requested);
521 mconsole_reply(req, "Stack Dumped to console and message log", 0, 0); 602 if((to == NULL) || (pid_requested == 0)) {
603 mconsole_reply(req, "Couldn't find that pid", 1, 0);
604 return;
605 }
606 with_console(req, stack_proc, to);
522} 607}
523 608
524void mconsole_stack(struct mc_request *req) 609void mconsole_stack(struct mc_request *req)
@@ -534,9 +619,9 @@ void mconsole_stack(struct mc_request *req)
534/* Changed by mconsole_setup, which is __setup, and called before SMP is 619/* Changed by mconsole_setup, which is __setup, and called before SMP is
535 * active. 620 * active.
536 */ 621 */
537static char *notify_socket = NULL; 622static char *notify_socket = NULL;
538 623
539int mconsole_init(void) 624static int mconsole_init(void)
540{ 625{
541 /* long to avoid size mismatch warnings from gcc */ 626 /* long to avoid size mismatch warnings from gcc */
542 long sock; 627 long sock;
@@ -563,16 +648,16 @@ int mconsole_init(void)
563 } 648 }
564 649
565 if(notify_socket != NULL){ 650 if(notify_socket != NULL){
566 notify_socket = uml_strdup(notify_socket); 651 notify_socket = kstrdup(notify_socket, GFP_KERNEL);
567 if(notify_socket != NULL) 652 if(notify_socket != NULL)
568 mconsole_notify(notify_socket, MCONSOLE_SOCKET, 653 mconsole_notify(notify_socket, MCONSOLE_SOCKET,
569 mconsole_socket_name, 654 mconsole_socket_name,
570 strlen(mconsole_socket_name) + 1); 655 strlen(mconsole_socket_name) + 1);
571 else printk(KERN_ERR "mconsole_setup failed to strdup " 656 else printk(KERN_ERR "mconsole_setup failed to strdup "
572 "string\n"); 657 "string\n");
573 } 658 }
574 659
575 printk("mconsole (version %d) initialized on %s\n", 660 printk("mconsole (version %d) initialized on %s\n",
576 MCONSOLE_VERSION, mconsole_socket_name); 661 MCONSOLE_VERSION, mconsole_socket_name);
577 return(0); 662 return(0);
578} 663}
@@ -585,7 +670,7 @@ static int write_proc_mconsole(struct file *file, const char __user *buffer,
585 char *buf; 670 char *buf;
586 671
587 buf = kmalloc(count + 1, GFP_KERNEL); 672 buf = kmalloc(count + 1, GFP_KERNEL);
588 if(buf == NULL) 673 if(buf == NULL)
589 return(-ENOMEM); 674 return(-ENOMEM);
590 675
591 if(copy_from_user(buf, buffer, count)){ 676 if(copy_from_user(buf, buffer, count)){
@@ -661,7 +746,7 @@ static int notify_panic(struct notifier_block *self, unsigned long unused1,
661 746
662 if(notify_socket == NULL) return(0); 747 if(notify_socket == NULL) return(0);
663 748
664 mconsole_notify(notify_socket, MCONSOLE_PANIC, message, 749 mconsole_notify(notify_socket, MCONSOLE_PANIC, message,
665 strlen(message) + 1); 750 strlen(message) + 1);
666 return(0); 751 return(0);
667} 752}
@@ -686,14 +771,3 @@ char *mconsole_notify_socket(void)
686} 771}
687 772
688EXPORT_SYMBOL(mconsole_notify_socket); 773EXPORT_SYMBOL(mconsole_notify_socket);
689
690/*
691 * Overrides for Emacs so that we follow Linus's tabbing style.
692 * Emacs will notice this stuff at the end of the file and automatically
693 * adjust the settings for this buffer only. This must remain at the end
694 * of the file.
695 * ---------------------------------------------------------------------------
696 * Local variables:
697 * c-file-style: "linux"
698 * End:
699 */
diff --git a/arch/um/drivers/mconsole_user.c b/arch/um/drivers/mconsole_user.c
index 310c1f823f26..4b109fe7fff8 100644
--- a/arch/um/drivers/mconsole_user.c
+++ b/arch/um/drivers/mconsole_user.c
@@ -122,12 +122,12 @@ int mconsole_get_request(int fd, struct mc_request *req)
122 return(1); 122 return(1);
123} 123}
124 124
125int mconsole_reply(struct mc_request *req, char *str, int err, int more) 125int mconsole_reply_len(struct mc_request *req, const char *str, int total,
126 int err, int more)
126{ 127{
127 struct mconsole_reply reply; 128 struct mconsole_reply reply;
128 int total, len, n; 129 int len, n;
129 130
130 total = strlen(str);
131 do { 131 do {
132 reply.err = err; 132 reply.err = err;
133 133
@@ -155,6 +155,12 @@ int mconsole_reply(struct mc_request *req, char *str, int err, int more)
155 return(0); 155 return(0);
156} 156}
157 157
158int mconsole_reply(struct mc_request *req, const char *str, int err, int more)
159{
160 return mconsole_reply_len(req, str, strlen(str), err, more);
161}
162
163
158int mconsole_unlink_socket(void) 164int mconsole_unlink_socket(void)
159{ 165{
160 unlink(mconsole_socket_name); 166 unlink(mconsole_socket_name);
diff --git a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c
index 84c73a300acb..fb1f9fb9b871 100644
--- a/arch/um/drivers/net_kern.c
+++ b/arch/um/drivers/net_kern.c
@@ -34,7 +34,7 @@
34#define DRIVER_NAME "uml-netdev" 34#define DRIVER_NAME "uml-netdev"
35 35
36static DEFINE_SPINLOCK(opened_lock); 36static DEFINE_SPINLOCK(opened_lock);
37LIST_HEAD(opened); 37static LIST_HEAD(opened);
38 38
39static int uml_net_rx(struct net_device *dev) 39static int uml_net_rx(struct net_device *dev)
40{ 40{
@@ -150,6 +150,7 @@ static int uml_net_close(struct net_device *dev)
150 if(lp->close != NULL) 150 if(lp->close != NULL)
151 (*lp->close)(lp->fd, &lp->user); 151 (*lp->close)(lp->fd, &lp->user);
152 lp->fd = -1; 152 lp->fd = -1;
153 list_del(&lp->list);
153 154
154 spin_unlock(&lp->lock); 155 spin_unlock(&lp->lock);
155 return 0; 156 return 0;
@@ -266,7 +267,7 @@ void uml_net_user_timer_expire(unsigned long _conn)
266} 267}
267 268
268static DEFINE_SPINLOCK(devices_lock); 269static DEFINE_SPINLOCK(devices_lock);
269static struct list_head devices = LIST_HEAD_INIT(devices); 270static LIST_HEAD(devices);
270 271
271static struct platform_driver uml_net_driver = { 272static struct platform_driver uml_net_driver = {
272 .driver = { 273 .driver = {
@@ -586,7 +587,7 @@ static int net_config(char *str)
586 err = eth_parse(str, &n, &str); 587 err = eth_parse(str, &n, &str);
587 if(err) return(err); 588 if(err) return(err);
588 589
589 str = uml_strdup(str); 590 str = kstrdup(str, GFP_KERNEL);
590 if(str == NULL){ 591 if(str == NULL){
591 printk(KERN_ERR "net_config failed to strdup string\n"); 592 printk(KERN_ERR "net_config failed to strdup string\n");
592 return(-1); 593 return(-1);
@@ -715,6 +716,7 @@ static void close_devices(void)
715 716
716 list_for_each(ele, &opened){ 717 list_for_each(ele, &opened){
717 lp = list_entry(ele, struct uml_net_private, list); 718 lp = list_entry(ele, struct uml_net_private, list);
719 free_irq(lp->dev->irq, lp->dev);
718 if((lp->close != NULL) && (lp->fd >= 0)) 720 if((lp->close != NULL) && (lp->fd >= 0))
719 (*lp->close)(lp->fd, &lp->user); 721 (*lp->close)(lp->fd, &lp->user);
720 if(lp->remove != NULL) (*lp->remove)(&lp->user); 722 if(lp->remove != NULL) (*lp->remove)(&lp->user);
diff --git a/arch/um/drivers/ssl.c b/arch/um/drivers/ssl.c
index 62e04ecfada8..a32ef55cb244 100644
--- a/arch/um/drivers/ssl.c
+++ b/arch/um/drivers/ssl.c
@@ -69,7 +69,7 @@ static struct line_driver driver = {
69 .name = "ssl", 69 .name = "ssl",
70 .config = ssl_config, 70 .config = ssl_config,
71 .get_config = ssl_get_config, 71 .get_config = ssl_get_config,
72 .id = line_id, 72 .id = line_id,
73 .remove = ssl_remove, 73 .remove = ssl_remove,
74 }, 74 },
75}; 75};
@@ -84,26 +84,23 @@ static struct lines lines = LINES_INIT(NR_PORTS);
84 84
85static int ssl_config(char *str) 85static int ssl_config(char *str)
86{ 86{
87 return(line_config(serial_lines, 87 return line_config(serial_lines, ARRAY_SIZE(serial_lines), str, &opts);
88 sizeof(serial_lines)/sizeof(serial_lines[0]), str));
89} 88}
90 89
91static int ssl_get_config(char *dev, char *str, int size, char **error_out) 90static int ssl_get_config(char *dev, char *str, int size, char **error_out)
92{ 91{
93 return(line_get_config(dev, serial_lines, 92 return line_get_config(dev, serial_lines, ARRAY_SIZE(serial_lines), str,
94 sizeof(serial_lines)/sizeof(serial_lines[0]), 93 size, error_out);
95 str, size, error_out));
96} 94}
97 95
98static int ssl_remove(int n) 96static int ssl_remove(int n)
99{ 97{
100 return line_remove(serial_lines, 98 return line_remove(serial_lines, ARRAY_SIZE(serial_lines), n);
101 sizeof(serial_lines)/sizeof(serial_lines[0]), n);
102} 99}
103 100
104int ssl_open(struct tty_struct *tty, struct file *filp) 101int ssl_open(struct tty_struct *tty, struct file *filp)
105{ 102{
106 return line_open(serial_lines, tty, &opts); 103 return line_open(serial_lines, tty);
107} 104}
108 105
109#if 0 106#if 0
@@ -112,16 +109,6 @@ static void ssl_flush_buffer(struct tty_struct *tty)
112 return; 109 return;
113} 110}
114 111
115static void ssl_throttle(struct tty_struct * tty)
116{
117 printk(KERN_ERR "Someone should implement ssl_throttle\n");
118}
119
120static void ssl_unthrottle(struct tty_struct * tty)
121{
122 printk(KERN_ERR "Someone should implement ssl_unthrottle\n");
123}
124
125static void ssl_stop(struct tty_struct *tty) 112static void ssl_stop(struct tty_struct *tty)
126{ 113{
127 printk(KERN_ERR "Someone should implement ssl_stop\n"); 114 printk(KERN_ERR "Someone should implement ssl_stop\n");
@@ -148,9 +135,9 @@ static struct tty_operations ssl_ops = {
148 .flush_chars = line_flush_chars, 135 .flush_chars = line_flush_chars,
149 .set_termios = line_set_termios, 136 .set_termios = line_set_termios,
150 .ioctl = line_ioctl, 137 .ioctl = line_ioctl,
138 .throttle = line_throttle,
139 .unthrottle = line_unthrottle,
151#if 0 140#if 0
152 .throttle = ssl_throttle,
153 .unthrottle = ssl_unthrottle,
154 .stop = ssl_stop, 141 .stop = ssl_stop,
155 .start = ssl_start, 142 .start = ssl_start,
156 .hangup = ssl_hangup, 143 .hangup = ssl_hangup,
@@ -183,7 +170,7 @@ static int ssl_console_setup(struct console *co, char *options)
183{ 170{
184 struct line *line = &serial_lines[co->index]; 171 struct line *line = &serial_lines[co->index];
185 172
186 return console_open_chan(line,co,&opts); 173 return console_open_chan(line, co, &opts);
187} 174}
188 175
189static struct console ssl_cons = { 176static struct console ssl_cons = {
@@ -199,12 +186,13 @@ int ssl_init(void)
199{ 186{
200 char *new_title; 187 char *new_title;
201 188
202 printk(KERN_INFO "Initializing software serial port version %d\n", 189 printk(KERN_INFO "Initializing software serial port version %d\n",
203 ssl_version); 190 ssl_version);
204 ssl_driver = line_register_devfs(&lines, &driver, &ssl_ops, 191 ssl_driver = line_register_devfs(&lines, &driver, &ssl_ops,
205 serial_lines, ARRAY_SIZE(serial_lines)); 192 serial_lines,
193 ARRAY_SIZE(serial_lines));
206 194
207 lines_init(serial_lines, sizeof(serial_lines)/sizeof(serial_lines[0])); 195 lines_init(serial_lines, ARRAY_SIZE(serial_lines), &opts);
208 196
209 new_title = add_xterm_umid(opts.xterm_title); 197 new_title = add_xterm_umid(opts.xterm_title);
210 if (new_title != NULL) 198 if (new_title != NULL)
@@ -212,7 +200,7 @@ int ssl_init(void)
212 200
213 ssl_init_done = 1; 201 ssl_init_done = 1;
214 register_console(&ssl_cons); 202 register_console(&ssl_cons);
215 return(0); 203 return 0;
216} 204}
217late_initcall(ssl_init); 205late_initcall(ssl_init);
218 206
@@ -220,16 +208,13 @@ static void ssl_exit(void)
220{ 208{
221 if (!ssl_init_done) 209 if (!ssl_init_done)
222 return; 210 return;
223 close_lines(serial_lines, 211 close_lines(serial_lines, ARRAY_SIZE(serial_lines));
224 sizeof(serial_lines)/sizeof(serial_lines[0]));
225} 212}
226__uml_exitcall(ssl_exit); 213__uml_exitcall(ssl_exit);
227 214
228static int ssl_chan_setup(char *str) 215static int ssl_chan_setup(char *str)
229{ 216{
230 return(line_setup(serial_lines, 217 return line_setup(serial_lines, ARRAY_SIZE(serial_lines), str);
231 sizeof(serial_lines)/sizeof(serial_lines[0]),
232 str, 1));
233} 218}
234 219
235__setup("ssl", ssl_chan_setup); 220__setup("ssl", ssl_chan_setup);
diff --git a/arch/um/drivers/stdio_console.c b/arch/um/drivers/stdio_console.c
index 005aa6333b6e..61db8b2fc83f 100644
--- a/arch/um/drivers/stdio_console.c
+++ b/arch/um/drivers/stdio_console.c
@@ -75,7 +75,7 @@ static struct line_driver driver = {
75 .name = "con", 75 .name = "con",
76 .config = con_config, 76 .config = con_config,
77 .get_config = con_get_config, 77 .get_config = con_get_config,
78 .id = line_id, 78 .id = line_id,
79 .remove = con_remove, 79 .remove = con_remove,
80 }, 80 },
81}; 81};
@@ -86,28 +86,27 @@ static struct lines console_lines = LINES_INIT(MAX_TTYS);
86 * individual elements are protected by individual semaphores. 86 * individual elements are protected by individual semaphores.
87 */ 87 */
88struct line vts[MAX_TTYS] = { LINE_INIT(CONFIG_CON_ZERO_CHAN, &driver), 88struct line vts[MAX_TTYS] = { LINE_INIT(CONFIG_CON_ZERO_CHAN, &driver),
89 [ 1 ... MAX_TTYS - 1 ] = 89 [ 1 ... MAX_TTYS - 1 ] =
90 LINE_INIT(CONFIG_CON_CHAN, &driver) }; 90 LINE_INIT(CONFIG_CON_CHAN, &driver) };
91 91
92static int con_config(char *str) 92static int con_config(char *str)
93{ 93{
94 return(line_config(vts, sizeof(vts)/sizeof(vts[0]), str)); 94 return line_config(vts, ARRAY_SIZE(vts), str, &opts);
95} 95}
96 96
97static int con_get_config(char *dev, char *str, int size, char **error_out) 97static int con_get_config(char *dev, char *str, int size, char **error_out)
98{ 98{
99 return(line_get_config(dev, vts, sizeof(vts)/sizeof(vts[0]), str, 99 return line_get_config(dev, vts, ARRAY_SIZE(vts), str, size, error_out);
100 size, error_out));
101} 100}
102 101
103static int con_remove(int n) 102static int con_remove(int n)
104{ 103{
105 return line_remove(vts, sizeof(vts)/sizeof(vts[0]), n); 104 return line_remove(vts, ARRAY_SIZE(vts), n);
106} 105}
107 106
108static int con_open(struct tty_struct *tty, struct file *filp) 107static int con_open(struct tty_struct *tty, struct file *filp)
109{ 108{
110 return line_open(vts, tty, &opts); 109 return line_open(vts, tty);
111} 110}
112 111
113static int con_init_done = 0; 112static int con_init_done = 0;
@@ -117,16 +116,18 @@ static struct tty_operations console_ops = {
117 .close = line_close, 116 .close = line_close,
118 .write = line_write, 117 .write = line_write,
119 .put_char = line_put_char, 118 .put_char = line_put_char,
120 .write_room = line_write_room, 119 .write_room = line_write_room,
121 .chars_in_buffer = line_chars_in_buffer, 120 .chars_in_buffer = line_chars_in_buffer,
122 .flush_buffer = line_flush_buffer, 121 .flush_buffer = line_flush_buffer,
123 .flush_chars = line_flush_chars, 122 .flush_chars = line_flush_chars,
124 .set_termios = line_set_termios, 123 .set_termios = line_set_termios,
125 .ioctl = line_ioctl, 124 .ioctl = line_ioctl,
125 .throttle = line_throttle,
126 .unthrottle = line_unthrottle,
126}; 127};
127 128
128static void uml_console_write(struct console *console, const char *string, 129static void uml_console_write(struct console *console, const char *string,
129 unsigned len) 130 unsigned len)
130{ 131{
131 struct line *line = &vts[console->index]; 132 struct line *line = &vts[console->index];
132 unsigned long flags; 133 unsigned long flags;
@@ -146,7 +147,7 @@ static int uml_console_setup(struct console *co, char *options)
146{ 147{
147 struct line *line = &vts[co->index]; 148 struct line *line = &vts[co->index];
148 149
149 return console_open_chan(line,co,&opts); 150 return console_open_chan(line, co, &opts);
150} 151}
151 152
152static struct console stdiocons = { 153static struct console stdiocons = {
@@ -156,7 +157,7 @@ static struct console stdiocons = {
156 .setup = uml_console_setup, 157 .setup = uml_console_setup,
157 .flags = CON_PRINTBUFFER, 158 .flags = CON_PRINTBUFFER,
158 .index = -1, 159 .index = -1,
159 .data = &vts, 160 .data = &vts,
160}; 161};
161 162
162int stdio_init(void) 163int stdio_init(void)
@@ -166,11 +167,11 @@ int stdio_init(void)
166 console_driver = line_register_devfs(&console_lines, &driver, 167 console_driver = line_register_devfs(&console_lines, &driver,
167 &console_ops, vts, 168 &console_ops, vts,
168 ARRAY_SIZE(vts)); 169 ARRAY_SIZE(vts));
169 if (NULL == console_driver) 170 if (console_driver == NULL)
170 return -1; 171 return -1;
171 printk(KERN_INFO "Initialized stdio console driver\n"); 172 printk(KERN_INFO "Initialized stdio console driver\n");
172 173
173 lines_init(vts, sizeof(vts)/sizeof(vts[0])); 174 lines_init(vts, ARRAY_SIZE(vts), &opts);
174 175
175 new_title = add_xterm_umid(opts.xterm_title); 176 new_title = add_xterm_umid(opts.xterm_title);
176 if(new_title != NULL) 177 if(new_title != NULL)
@@ -178,7 +179,7 @@ int stdio_init(void)
178 179
179 con_init_done = 1; 180 con_init_done = 1;
180 register_console(&stdiocons); 181 register_console(&stdiocons);
181 return(0); 182 return 0;
182} 183}
183late_initcall(stdio_init); 184late_initcall(stdio_init);
184 185
@@ -186,13 +187,13 @@ static void console_exit(void)
186{ 187{
187 if (!con_init_done) 188 if (!con_init_done)
188 return; 189 return;
189 close_lines(vts, sizeof(vts)/sizeof(vts[0])); 190 close_lines(vts, ARRAY_SIZE(vts));
190} 191}
191__uml_exitcall(console_exit); 192__uml_exitcall(console_exit);
192 193
193static int console_chan_setup(char *str) 194static int console_chan_setup(char *str)
194{ 195{
195 return(line_setup(vts, sizeof(vts)/sizeof(vts[0]), str, 1)); 196 return line_setup(vts, ARRAY_SIZE(vts), str);
196} 197}
197__setup("con", console_chan_setup); 198__setup("con", console_chan_setup);
198__channel_help(console_chan_setup, "con"); 199__channel_help(console_chan_setup, "con");
diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c
index 93898917cbe5..73f9652b2ee9 100644
--- a/arch/um/drivers/ubd_kern.c
+++ b/arch/um/drivers/ubd_kern.c
@@ -706,7 +706,7 @@ static int ubd_config(char *str)
706{ 706{
707 int n, err; 707 int n, err;
708 708
709 str = uml_strdup(str); 709 str = kstrdup(str, GFP_KERNEL);
710 if(str == NULL){ 710 if(str == NULL){
711 printk(KERN_ERR "ubd_config failed to strdup string\n"); 711 printk(KERN_ERR "ubd_config failed to strdup string\n");
712 return(1); 712 return(1);
@@ -1387,15 +1387,6 @@ int io_thread(void *arg)
1387 printk("io_thread - write failed, fd = %d, err = %d\n", 1387 printk("io_thread - write failed, fd = %d, err = %d\n",
1388 kernel_fd, -n); 1388 kernel_fd, -n);
1389 } 1389 }
1390}
1391 1390
1392/* 1391 return 0;
1393 * Overrides for Emacs so that we follow Linus's tabbing style. 1392}
1394 * Emacs will notice this stuff at the end of the file and automatically
1395 * adjust the settings for this buffer only. This must remain at the end
1396 * of the file.
1397 * ---------------------------------------------------------------------------
1398 * Local variables:
1399 * c-file-style: "linux"
1400 * End:
1401 */
diff --git a/arch/um/include/chan_kern.h b/arch/um/include/chan_kern.h
index da9a6717e7a4..1bb5e9d94270 100644
--- a/arch/um/include/chan_kern.h
+++ b/arch/um/include/chan_kern.h
@@ -14,21 +14,23 @@
14 14
15struct chan { 15struct chan {
16 struct list_head list; 16 struct list_head list;
17 struct list_head free_list;
18 struct line *line;
17 char *dev; 19 char *dev;
18 unsigned int primary:1; 20 unsigned int primary:1;
19 unsigned int input:1; 21 unsigned int input:1;
20 unsigned int output:1; 22 unsigned int output:1;
21 unsigned int opened:1; 23 unsigned int opened:1;
24 unsigned int enabled:1;
22 int fd; 25 int fd;
23 enum chan_init_pri pri;
24 struct chan_ops *ops; 26 struct chan_ops *ops;
25 void *data; 27 void *data;
26}; 28};
27 29
28extern void chan_interrupt(struct list_head *chans, struct work_struct *task, 30extern void chan_interrupt(struct list_head *chans, struct work_struct *task,
29 struct tty_struct *tty, int irq); 31 struct tty_struct *tty, int irq);
30extern int parse_chan_pair(char *str, struct list_head *chans, int pri, 32extern int parse_chan_pair(char *str, struct line *line, int device,
31 int device, struct chan_opts *opts); 33 struct chan_opts *opts);
32extern int open_chan(struct list_head *chans); 34extern int open_chan(struct list_head *chans);
33extern int write_chan(struct list_head *chans, const char *buf, int len, 35extern int write_chan(struct list_head *chans, const char *buf, int len,
34 int write_irq); 36 int write_irq);
@@ -36,9 +38,11 @@ extern int console_write_chan(struct list_head *chans, const char *buf,
36 int len); 38 int len);
37extern int console_open_chan(struct line *line, struct console *co, 39extern int console_open_chan(struct line *line, struct console *co,
38 struct chan_opts *opts); 40 struct chan_opts *opts);
39extern void close_chan(struct list_head *chans); 41extern void deactivate_chan(struct list_head *chans, int irq);
42extern void reactivate_chan(struct list_head *chans, int irq);
40extern void chan_enable_winch(struct list_head *chans, struct tty_struct *tty); 43extern void chan_enable_winch(struct list_head *chans, struct tty_struct *tty);
41extern void enable_chan(struct list_head *chans, struct tty_struct *tty); 44extern void enable_chan(struct line *line);
45extern void close_chan(struct list_head *chans, int delay_free_irq);
42extern int chan_window_size(struct list_head *chans, 46extern int chan_window_size(struct list_head *chans,
43 unsigned short *rows_out, 47 unsigned short *rows_out,
44 unsigned short *cols_out); 48 unsigned short *cols_out);
@@ -47,14 +51,3 @@ extern int chan_config_string(struct list_head *chans, char *str, int size,
47 char **error_out); 51 char **error_out);
48 52
49#endif 53#endif
50
51/*
52 * Overrides for Emacs so that we follow Linus's tabbing style.
53 * Emacs will notice this stuff at the end of the file and automatically
54 * adjust the settings for this buffer only. This must remain at the end
55 * of the file.
56 * ---------------------------------------------------------------------------
57 * Local variables:
58 * c-file-style: "linux"
59 * End:
60 */
diff --git a/arch/um/include/choose-mode.h b/arch/um/include/choose-mode.h
index f25fa83a5da6..b87b36a87d91 100644
--- a/arch/um/include/choose-mode.h
+++ b/arch/um/include/choose-mode.h
@@ -23,6 +23,9 @@ static inline void *__choose_mode(void *tt, void *skas) {
23 23
24#elif defined(UML_CONFIG_MODE_TT) 24#elif defined(UML_CONFIG_MODE_TT)
25#define CHOOSE_MODE(tt, skas) (tt) 25#define CHOOSE_MODE(tt, skas) (tt)
26
27#else
28#error CONFIG_MODE_SKAS and CONFIG_MODE_TT are both disabled
26#endif 29#endif
27 30
28#define CHOOSE_MODE_PROC(tt, skas, args...) \ 31#define CHOOSE_MODE_PROC(tt, skas, args...) \
diff --git a/arch/um/include/irq_user.h b/arch/um/include/irq_user.h
index f724b717213f..b61deb8b362a 100644
--- a/arch/um/include/irq_user.h
+++ b/arch/um/include/irq_user.h
@@ -18,19 +18,8 @@ extern int deactivate_all_fds(void);
18extern void forward_interrupts(int pid); 18extern void forward_interrupts(int pid);
19extern void init_irq_signals(int on_sigstack); 19extern void init_irq_signals(int on_sigstack);
20extern void forward_ipi(int fd, int pid); 20extern void forward_ipi(int fd, int pid);
21extern void free_irq_later(int irq, void *dev_id);
22extern int activate_ipi(int fd, int pid); 21extern int activate_ipi(int fd, int pid);
23extern unsigned long irq_lock(void); 22extern unsigned long irq_lock(void);
24extern void irq_unlock(unsigned long flags); 23extern void irq_unlock(unsigned long flags);
25#endif
26 24
27/* 25#endif
28 * Overrides for Emacs so that we follow Linus's tabbing style.
29 * Emacs will notice this stuff at the end of the file and automatically
30 * adjust the settings for this buffer only. This must remain at the end
31 * of the file.
32 * ---------------------------------------------------------------------------
33 * Local variables:
34 * c-file-style: "linux"
35 * End:
36 */
diff --git a/arch/um/include/kern.h b/arch/um/include/kern.h
index 1e3170768b5c..7d223beccbc0 100644
--- a/arch/um/include/kern.h
+++ b/arch/um/include/kern.h
@@ -17,7 +17,7 @@ extern int errno;
17 17
18extern int clone(int (*proc)(void *), void *sp, int flags, void *data); 18extern int clone(int (*proc)(void *), void *sp, int flags, void *data);
19extern int sleep(int); 19extern int sleep(int);
20extern int printf(char *fmt, ...); 20extern int printf(const char *fmt, ...);
21extern char *strerror(int errnum); 21extern char *strerror(int errnum);
22extern char *ptsname(int __fd); 22extern char *ptsname(int __fd);
23extern int munmap(void *, int); 23extern int munmap(void *, int);
@@ -35,15 +35,6 @@ extern int read(unsigned int, char *, int);
35extern int pipe(int *); 35extern int pipe(int *);
36extern int sched_yield(void); 36extern int sched_yield(void);
37extern int ptrace(int op, int pid, long addr, long data); 37extern int ptrace(int op, int pid, long addr, long data);
38
38#endif 39#endif
39 40
40/*
41 * Overrides for Emacs so that we follow Linus's tabbing style.
42 * Emacs will notice this stuff at the end of the file and automatically
43 * adjust the settings for this buffer only. This must remain at the end
44 * of the file.
45 * ---------------------------------------------------------------------------
46 * Local variables:
47 * c-file-style: "linux"
48 * End:
49 */
diff --git a/arch/um/include/line.h b/arch/um/include/line.h
index 5323d22a6ca7..6f4d680dc1d4 100644
--- a/arch/um/include/line.h
+++ b/arch/um/include/line.h
@@ -32,11 +32,13 @@ struct line_driver {
32}; 32};
33 33
34struct line { 34struct line {
35 struct tty_struct *tty;
35 char *init_str; 36 char *init_str;
36 int init_pri; 37 int init_pri;
37 struct list_head chan_list; 38 struct list_head chan_list;
38 int valid; 39 int valid;
39 int count; 40 int count;
41 int throttled;
40 /*This lock is actually, mostly, local to*/ 42 /*This lock is actually, mostly, local to*/
41 spinlock_t lock; 43 spinlock_t lock;
42 44
@@ -58,14 +60,15 @@ struct line {
58#define LINE_INIT(str, d) \ 60#define LINE_INIT(str, d) \
59 { init_str : str, \ 61 { init_str : str, \
60 init_pri : INIT_STATIC, \ 62 init_pri : INIT_STATIC, \
61 chan_list : { }, \
62 valid : 1, \ 63 valid : 1, \
64 throttled : 0, \
65 lock : SPIN_LOCK_UNLOCKED, \
63 buffer : NULL, \ 66 buffer : NULL, \
64 head : NULL, \ 67 head : NULL, \
65 tail : NULL, \ 68 tail : NULL, \
66 sigio : 0, \ 69 sigio : 0, \
67 driver : d, \ 70 driver : d, \
68 have_irq : 0 } 71 have_irq : 0 }
69 72
70struct lines { 73struct lines {
71 int num; 74 int num;
@@ -74,11 +77,11 @@ struct lines {
74#define LINES_INIT(n) { num : n } 77#define LINES_INIT(n) { num : n }
75 78
76extern void line_close(struct tty_struct *tty, struct file * filp); 79extern void line_close(struct tty_struct *tty, struct file * filp);
77extern int line_open(struct line *lines, struct tty_struct *tty, 80extern int line_open(struct line *lines, struct tty_struct *tty);
78 struct chan_opts *opts); 81extern int line_setup(struct line *lines, unsigned int sizeof_lines,
79extern int line_setup(struct line *lines, unsigned int sizeof_lines, char *init, 82 char *init);
80 int all_allowed); 83extern int line_write(struct tty_struct *tty, const unsigned char *buf,
81extern int line_write(struct tty_struct *tty, const unsigned char *buf, int len); 84 int len);
82extern void line_put_char(struct tty_struct *tty, unsigned char ch); 85extern void line_put_char(struct tty_struct *tty, unsigned char ch);
83extern void line_set_termios(struct tty_struct *tty, struct termios * old); 86extern void line_set_termios(struct tty_struct *tty, struct termios * old);
84extern int line_chars_in_buffer(struct tty_struct *tty); 87extern int line_chars_in_buffer(struct tty_struct *tty);
@@ -87,23 +90,27 @@ extern void line_flush_chars(struct tty_struct *tty);
87extern int line_write_room(struct tty_struct *tty); 90extern int line_write_room(struct tty_struct *tty);
88extern int line_ioctl(struct tty_struct *tty, struct file * file, 91extern int line_ioctl(struct tty_struct *tty, struct file * file,
89 unsigned int cmd, unsigned long arg); 92 unsigned int cmd, unsigned long arg);
93extern void line_throttle(struct tty_struct *tty);
94extern void line_unthrottle(struct tty_struct *tty);
90 95
91extern char *add_xterm_umid(char *base); 96extern char *add_xterm_umid(char *base);
92extern int line_setup_irq(int fd, int input, int output, struct tty_struct *tty); 97extern int line_setup_irq(int fd, int input, int output, struct line *line,
98 void *data);
93extern void line_close_chan(struct line *line); 99extern void line_close_chan(struct line *line);
94extern void line_disable(struct tty_struct *tty, int current_irq); 100extern struct tty_driver * line_register_devfs(struct lines *set,
95extern struct tty_driver * line_register_devfs(struct lines *set, 101 struct line_driver *line_driver,
96 struct line_driver *line_driver,
97 struct tty_operations *driver, 102 struct tty_operations *driver,
98 struct line *lines, 103 struct line *lines,
99 int nlines); 104 int nlines);
100extern void lines_init(struct line *lines, int nlines); 105extern void lines_init(struct line *lines, int nlines, struct chan_opts *opts);
101extern void close_lines(struct line *lines, int nlines); 106extern void close_lines(struct line *lines, int nlines);
102 107
103extern int line_config(struct line *lines, unsigned int sizeof_lines, char *str); 108extern int line_config(struct line *lines, unsigned int sizeof_lines,
109 char *str, struct chan_opts *opts);
104extern int line_id(char **str, int *start_out, int *end_out); 110extern int line_id(char **str, int *start_out, int *end_out);
105extern int line_remove(struct line *lines, unsigned int sizeof_lines, int n); 111extern int line_remove(struct line *lines, unsigned int sizeof_lines, int n);
106extern int line_get_config(char *dev, struct line *lines, unsigned int sizeof_lines, char *str, 112extern int line_get_config(char *dev, struct line *lines,
113 unsigned int sizeof_lines, char *str,
107 int size, char **error_out); 114 int size, char **error_out);
108 115
109#endif 116#endif
diff --git a/arch/um/include/mconsole.h b/arch/um/include/mconsole.h
index b1b512f47035..58f67d391105 100644
--- a/arch/um/include/mconsole.h
+++ b/arch/um/include/mconsole.h
@@ -32,7 +32,7 @@ struct mconsole_reply {
32 32
33struct mconsole_notify { 33struct mconsole_notify {
34 u32 magic; 34 u32 magic;
35 u32 version; 35 u32 version;
36 enum { MCONSOLE_SOCKET, MCONSOLE_PANIC, MCONSOLE_HANG, 36 enum { MCONSOLE_SOCKET, MCONSOLE_PANIC, MCONSOLE_HANG,
37 MCONSOLE_USER_NOTIFY } type; 37 MCONSOLE_USER_NOTIFY } type;
38 u32 len; 38 u32 len;
@@ -66,7 +66,9 @@ struct mc_request
66extern char mconsole_socket_name[]; 66extern char mconsole_socket_name[];
67 67
68extern int mconsole_unlink_socket(void); 68extern int mconsole_unlink_socket(void);
69extern int mconsole_reply(struct mc_request *req, char *reply, int err, 69extern int mconsole_reply_len(struct mc_request *req, const char *reply,
70 int len, int err, int more);
71extern int mconsole_reply(struct mc_request *req, const char *str, int err,
70 int more); 72 int more);
71 73
72extern void mconsole_version(struct mc_request *req); 74extern void mconsole_version(struct mc_request *req);
@@ -84,7 +86,7 @@ extern void mconsole_proc(struct mc_request *req);
84extern void mconsole_stack(struct mc_request *req); 86extern void mconsole_stack(struct mc_request *req);
85 87
86extern int mconsole_get_request(int fd, struct mc_request *req); 88extern int mconsole_get_request(int fd, struct mc_request *req);
87extern int mconsole_notify(char *sock_name, int type, const void *data, 89extern int mconsole_notify(char *sock_name, int type, const void *data,
88 int len); 90 int len);
89extern char *mconsole_notify_socket(void); 91extern char *mconsole_notify_socket(void);
90extern void lock_notify(void); 92extern void lock_notify(void);
diff --git a/arch/um/include/os.h b/arch/um/include/os.h
index 2cccfa5b8ab5..c279ee6d89e4 100644
--- a/arch/um/include/os.h
+++ b/arch/um/include/os.h
@@ -213,15 +213,10 @@ extern int run_helper_thread(int (*proc)(void *), void *arg,
213 int stack_order); 213 int stack_order);
214extern int helper_wait(int pid); 214extern int helper_wait(int pid);
215 215
216#endif 216/* umid.c */
217 217
218/* 218extern int umid_file_name(char *name, char *buf, int len);
219 * Overrides for Emacs so that we follow Linus's tabbing style. 219extern int set_umid(char *name);
220 * Emacs will notice this stuff at the end of the file and automatically 220extern char *get_umid(void);
221 * adjust the settings for this buffer only. This must remain at the end 221
222 * of the file. 222#endif
223 * ---------------------------------------------------------------------------
224 * Local variables:
225 * c-file-style: "linux"
226 * End:
227 */
diff --git a/arch/um/include/user_util.h b/arch/um/include/user_util.h
index bb505e01d994..b9984003e603 100644
--- a/arch/um/include/user_util.h
+++ b/arch/um/include/user_util.h
@@ -64,7 +64,6 @@ extern void setup_machinename(char *machine_out);
64extern void setup_hostinfo(void); 64extern void setup_hostinfo(void);
65extern void do_exec(int old_pid, int new_pid); 65extern void do_exec(int old_pid, int new_pid);
66extern void tracer_panic(char *msg, ...); 66extern void tracer_panic(char *msg, ...);
67extern char *get_umid(int only_if_set);
68extern void do_longjmp(void *p, int val); 67extern void do_longjmp(void *p, int val);
69extern int detach(int pid, int sig); 68extern int detach(int pid, int sig);
70extern int attach(int pid); 69extern int attach(int pid);
diff --git a/arch/um/kernel/Makefile b/arch/um/kernel/Makefile
index 3de9d21e36bf..6f7700593a6f 100644
--- a/arch/um/kernel/Makefile
+++ b/arch/um/kernel/Makefile
@@ -10,8 +10,8 @@ obj-y = config.o exec_kern.o exitcode.o \
10 init_task.o irq.o irq_user.o ksyms.o mem.o physmem.o \ 10 init_task.o irq.o irq_user.o ksyms.o mem.o physmem.o \
11 process_kern.o ptrace.o reboot.o resource.o sigio_user.o sigio_kern.o \ 11 process_kern.o ptrace.o reboot.o resource.o sigio_user.o sigio_kern.o \
12 signal_kern.o signal_user.o smp.o syscall_kern.o sysrq.o time.o \ 12 signal_kern.o signal_user.o smp.o syscall_kern.o sysrq.o time.o \
13 time_kern.o tlb.o trap_kern.o trap_user.o uaccess.o um_arch.o \ 13 time_kern.o tlb.o trap_kern.o trap_user.o uaccess.o um_arch.o umid.o \
14 umid.o user_util.o 14 user_util.o
15 15
16obj-$(CONFIG_BLK_DEV_INITRD) += initrd.o 16obj-$(CONFIG_BLK_DEV_INITRD) += initrd.o
17obj-$(CONFIG_GPROF) += gprof_syms.o 17obj-$(CONFIG_GPROF) += gprof_syms.o
@@ -24,7 +24,7 @@ obj-$(CONFIG_MODE_SKAS) += skas/
24 24
25user-objs-$(CONFIG_TTY_LOG) += tty_log.o 25user-objs-$(CONFIG_TTY_LOG) += tty_log.o
26 26
27USER_OBJS := $(user-objs-y) config.o time.o tty_log.o umid.o user_util.o 27USER_OBJS := $(user-objs-y) config.o time.o tty_log.o user_util.o
28 28
29include arch/um/scripts/Makefile.rules 29include arch/um/scripts/Makefile.rules
30 30
diff --git a/arch/um/kernel/irq_user.c b/arch/um/kernel/irq_user.c
index c3ccaf24f3e0..50a2aa35cda9 100644
--- a/arch/um/kernel/irq_user.c
+++ b/arch/um/kernel/irq_user.c
@@ -29,7 +29,6 @@ struct irq_fd {
29 int pid; 29 int pid;
30 int events; 30 int events;
31 int current_events; 31 int current_events;
32 int freed;
33}; 32};
34 33
35static struct irq_fd *active_fds = NULL; 34static struct irq_fd *active_fds = NULL;
@@ -41,9 +40,11 @@ static int pollfds_size = 0;
41 40
42extern int io_count, intr_count; 41extern int io_count, intr_count;
43 42
43extern void free_irqs(void);
44
44void sigio_handler(int sig, union uml_pt_regs *regs) 45void sigio_handler(int sig, union uml_pt_regs *regs)
45{ 46{
46 struct irq_fd *irq_fd, *next; 47 struct irq_fd *irq_fd;
47 int i, n; 48 int i, n;
48 49
49 if(smp_sigio_handler()) return; 50 if(smp_sigio_handler()) return;
@@ -66,29 +67,15 @@ void sigio_handler(int sig, union uml_pt_regs *regs)
66 irq_fd = irq_fd->next; 67 irq_fd = irq_fd->next;
67 } 68 }
68 69
69 for(irq_fd = active_fds; irq_fd != NULL; irq_fd = next){ 70 for(irq_fd = active_fds; irq_fd != NULL; irq_fd = irq_fd->next){
70 next = irq_fd->next;
71 if(irq_fd->current_events != 0){ 71 if(irq_fd->current_events != 0){
72 irq_fd->current_events = 0; 72 irq_fd->current_events = 0;
73 do_IRQ(irq_fd->irq, regs); 73 do_IRQ(irq_fd->irq, regs);
74
75 /* This is here because the next irq may be
76 * freed in the handler. If a console goes
77 * away, both the read and write irqs will be
78 * freed. After do_IRQ, ->next will point to
79 * a good IRQ.
80 * Irqs can't be freed inside their handlers,
81 * so the next best thing is to have them
82 * marked as needing freeing, so that they
83 * can be freed here.
84 */
85 next = irq_fd->next;
86 if(irq_fd->freed){
87 free_irq(irq_fd->irq, irq_fd->id);
88 }
89 } 74 }
90 } 75 }
91 } 76 }
77
78 free_irqs();
92} 79}
93 80
94int activate_ipi(int fd, int pid) 81int activate_ipi(int fd, int pid)
@@ -136,8 +123,7 @@ int activate_fd(int irq, int fd, int type, void *dev_id)
136 .irq = irq, 123 .irq = irq,
137 .pid = pid, 124 .pid = pid,
138 .events = events, 125 .events = events,
139 .current_events = 0, 126 .current_events = 0 } );
140 .freed = 0 } );
141 127
142 /* Critical section - locked by a spinlock because this stuff can 128 /* Critical section - locked by a spinlock because this stuff can
143 * be changed from interrupt handlers. The stuff above is done 129 * be changed from interrupt handlers. The stuff above is done
@@ -313,26 +299,6 @@ static struct irq_fd *find_irq_by_fd(int fd, int irqnum, int *index_out)
313 return(irq); 299 return(irq);
314} 300}
315 301
316void free_irq_later(int irq, void *dev_id)
317{
318 struct irq_fd *irq_fd;
319 unsigned long flags;
320
321 flags = irq_lock();
322 for(irq_fd = active_fds; irq_fd != NULL; irq_fd = irq_fd->next){
323 if((irq_fd->irq == irq) && (irq_fd->id == dev_id))
324 break;
325 }
326 if(irq_fd == NULL){
327 printk("free_irq_later found no irq, irq = %d, "
328 "dev_id = 0x%p\n", irq, dev_id);
329 goto out;
330 }
331 irq_fd->freed = 1;
332 out:
333 irq_unlock(flags);
334}
335
336void reactivate_fd(int fd, int irqnum) 302void reactivate_fd(int fd, int irqnum)
337{ 303{
338 struct irq_fd *irq; 304 struct irq_fd *irq;
diff --git a/arch/um/kernel/process_kern.c b/arch/um/kernel/process_kern.c
index 34b54a3e2132..651abf255bc5 100644
--- a/arch/um/kernel/process_kern.c
+++ b/arch/um/kernel/process_kern.c
@@ -324,10 +324,6 @@ int user_context(unsigned long sp)
324 return(stack != (unsigned long) current_thread); 324 return(stack != (unsigned long) current_thread);
325} 325}
326 326
327extern void remove_umid_dir(void);
328
329__uml_exitcall(remove_umid_dir);
330
331extern exitcall_t __uml_exitcall_begin, __uml_exitcall_end; 327extern exitcall_t __uml_exitcall_begin, __uml_exitcall_end;
332 328
333void do_uml_exitcalls(void) 329void do_uml_exitcalls(void)
diff --git a/arch/um/kernel/sigio_user.c b/arch/um/kernel/sigio_user.c
index 48b1f644b9a6..62e5cfdf2188 100644
--- a/arch/um/kernel/sigio_user.c
+++ b/arch/um/kernel/sigio_user.c
@@ -216,6 +216,8 @@ static int write_sigio_thread(void *unused)
216 "err = %d\n", -n); 216 "err = %d\n", -n);
217 } 217 }
218 } 218 }
219
220 return 0;
219} 221}
220 222
221static int need_poll(int n) 223static int need_poll(int n)
diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c
index 142a9493912b..26626b2b9172 100644
--- a/arch/um/kernel/um_arch.c
+++ b/arch/um/kernel/um_arch.c
@@ -146,8 +146,8 @@ void set_cmdline(char *cmd)
146 146
147 if(CHOOSE_MODE(honeypot, 0)) return; 147 if(CHOOSE_MODE(honeypot, 0)) return;
148 148
149 umid = get_umid(1); 149 umid = get_umid();
150 if(umid != NULL){ 150 if(*umid != '\0'){
151 snprintf(argv1_begin, 151 snprintf(argv1_begin,
152 (argv1_end - argv1_begin) * sizeof(*ptr), 152 (argv1_end - argv1_begin) * sizeof(*ptr),
153 "(%s) ", umid); 153 "(%s) ", umid);
diff --git a/arch/um/kernel/umid.c b/arch/um/kernel/umid.c
index 0b21d59ba0cd..4eaee823bfd2 100644
--- a/arch/um/kernel/umid.c
+++ b/arch/um/kernel/umid.c
@@ -3,61 +3,30 @@
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#include <stdio.h> 6#include "asm/errno.h"
7#include <unistd.h>
8#include <errno.h>
9#include <string.h>
10#include <stdlib.h>
11#include <dirent.h>
12#include <signal.h>
13#include <sys/stat.h>
14#include <sys/param.h>
15#include "user.h"
16#include "umid.h"
17#include "init.h" 7#include "init.h"
18#include "os.h" 8#include "os.h"
19#include "user_util.h" 9#include "kern.h"
20#include "choose-mode.h" 10#include "linux/kernel.h"
21 11
22#define UMID_LEN 64 12/* Changed by set_umid_arg */
23#define UML_DIR "~/.uml/"
24
25/* Changed by set_umid and make_umid, which are run early in boot */
26static char umid[UMID_LEN] = { 0 };
27
28/* Changed by set_uml_dir and make_uml_dir, which are run early in boot */
29static char *uml_dir = UML_DIR;
30
31/* Changed by set_umid */
32static int umid_is_random = 1;
33static int umid_inited = 0; 13static int umid_inited = 0;
34/* Have we created the files? Should we remove them? */
35static int umid_owned = 0;
36 14
37static int make_umid(int (*printer)(const char *fmt, ...)); 15static int __init set_umid_arg(char *name, int *add)
38
39static int __init set_umid(char *name, int is_random,
40 int (*printer)(const char *fmt, ...))
41{ 16{
42 if(umid_inited){ 17 int err;
43 (*printer)("Unique machine name can't be set twice\n");
44 return(-1);
45 }
46 18
47 if(strlen(name) > UMID_LEN - 1) 19 if(umid_inited)
48 (*printer)("Unique machine name is being truncated to %d " 20 return 0;
49 "characters\n", UMID_LEN);
50 strlcpy(umid, name, sizeof(umid));
51 21
52 umid_is_random = is_random;
53 umid_inited = 1;
54 return 0;
55}
56
57static int __init set_umid_arg(char *name, int *add)
58{
59 *add = 0; 22 *add = 0;
60 return(set_umid(name, 0, printf)); 23 err = set_umid(name);
24 if(err == -EEXIST)
25 printf("umid '%s' already in use\n", name);
26 else if(!err)
27 umid_inited = 1;
28
29 return 0;
61} 30}
62 31
63__uml_setup("umid=", set_umid_arg, 32__uml_setup("umid=", set_umid_arg,
@@ -66,265 +35,3 @@ __uml_setup("umid=", set_umid_arg,
66" is used for naming the pid file and management console socket.\n\n" 35" is used for naming the pid file and management console socket.\n\n"
67); 36);
68 37
69int __init umid_file_name(char *name, char *buf, int len)
70{
71 int n;
72
73 if(!umid_inited && make_umid(printk)) return(-1);
74
75 n = strlen(uml_dir) + strlen(umid) + strlen(name) + 1;
76 if(n > len){
77 printk("umid_file_name : buffer too short\n");
78 return(-1);
79 }
80
81 sprintf(buf, "%s%s/%s", uml_dir, umid, name);
82 return(0);
83}
84
85extern int tracing_pid;
86
87static void __init create_pid_file(void)
88{
89 char file[strlen(uml_dir) + UMID_LEN + sizeof("/pid\0")];
90 char pid[sizeof("nnnnn\0")];
91 int fd, n;
92
93 if(umid_file_name("pid", file, sizeof(file)))
94 return;
95
96 fd = os_open_file(file, of_create(of_excl(of_rdwr(OPENFLAGS()))),
97 0644);
98 if(fd < 0){
99 printf("Open of machine pid file \"%s\" failed: %s\n",
100 file, strerror(-fd));
101 return;
102 }
103
104 sprintf(pid, "%d\n", os_getpid());
105 n = os_write_file(fd, pid, strlen(pid));
106 if(n != strlen(pid))
107 printf("Write of pid file failed - err = %d\n", -n);
108 os_close_file(fd);
109}
110
111static int actually_do_remove(char *dir)
112{
113 DIR *directory;
114 struct dirent *ent;
115 int len;
116 char file[256];
117
118 directory = opendir(dir);
119 if(directory == NULL){
120 printk("actually_do_remove : couldn't open directory '%s', "
121 "errno = %d\n", dir, errno);
122 return(1);
123 }
124 while((ent = readdir(directory)) != NULL){
125 if(!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, ".."))
126 continue;
127 len = strlen(dir) + sizeof("/") + strlen(ent->d_name) + 1;
128 if(len > sizeof(file)){
129 printk("Not deleting '%s' from '%s' - name too long\n",
130 ent->d_name, dir);
131 continue;
132 }
133 sprintf(file, "%s/%s", dir, ent->d_name);
134 if(unlink(file) < 0){
135 printk("actually_do_remove : couldn't remove '%s' "
136 "from '%s', errno = %d\n", ent->d_name, dir,
137 errno);
138 return(1);
139 }
140 }
141 if(rmdir(dir) < 0){
142 printk("actually_do_remove : couldn't rmdir '%s', "
143 "errno = %d\n", dir, errno);
144 return(1);
145 }
146 return(0);
147}
148
149void remove_umid_dir(void)
150{
151 char dir[strlen(uml_dir) + UMID_LEN + 1];
152 if (!umid_owned)
153 return;
154
155 sprintf(dir, "%s%s", uml_dir, umid);
156 actually_do_remove(dir);
157}
158
159char *get_umid(int only_if_set)
160{
161 if(only_if_set && umid_is_random)
162 return NULL;
163 return umid;
164}
165
166static int not_dead_yet(char *dir)
167{
168 char file[strlen(uml_dir) + UMID_LEN + sizeof("/pid\0")];
169 char pid[sizeof("nnnnn\0")], *end;
170 int dead, fd, p, n;
171
172 sprintf(file, "%s/pid", dir);
173 dead = 0;
174 fd = os_open_file(file, of_read(OPENFLAGS()), 0);
175 if(fd < 0){
176 if(fd != -ENOENT){
177 printk("not_dead_yet : couldn't open pid file '%s', "
178 "err = %d\n", file, -fd);
179 return(1);
180 }
181 dead = 1;
182 }
183 if(fd > 0){
184 n = os_read_file(fd, pid, sizeof(pid));
185 if(n < 0){
186 printk("not_dead_yet : couldn't read pid file '%s', "
187 "err = %d\n", file, -n);
188 return(1);
189 }
190 p = strtoul(pid, &end, 0);
191 if(end == pid){
192 printk("not_dead_yet : couldn't parse pid file '%s', "
193 "errno = %d\n", file, errno);
194 dead = 1;
195 }
196 if(((kill(p, 0) < 0) && (errno == ESRCH)) ||
197 (p == CHOOSE_MODE(tracing_pid, os_getpid())))
198 dead = 1;
199 }
200 if(!dead)
201 return(1);
202 return(actually_do_remove(dir));
203}
204
205static int __init set_uml_dir(char *name, int *add)
206{
207 if((strlen(name) > 0) && (name[strlen(name) - 1] != '/')){
208 uml_dir = malloc(strlen(name) + 2);
209 if(uml_dir == NULL){
210 printf("Failed to malloc uml_dir - error = %d\n",
211 errno);
212 uml_dir = name;
213 /* Return 0 here because do_initcalls doesn't look at
214 * the return value.
215 */
216 return(0);
217 }
218 sprintf(uml_dir, "%s/", name);
219 }
220 else uml_dir = name;
221 return(0);
222}
223
224static int __init make_uml_dir(void)
225{
226 char dir[MAXPATHLEN + 1] = { '\0' };
227 int len;
228
229 if(*uml_dir == '~'){
230 char *home = getenv("HOME");
231
232 if(home == NULL){
233 printf("make_uml_dir : no value in environment for "
234 "$HOME\n");
235 exit(1);
236 }
237 strlcpy(dir, home, sizeof(dir));
238 uml_dir++;
239 }
240 strlcat(dir, uml_dir, sizeof(dir));
241 len = strlen(dir);
242 if (len > 0 && dir[len - 1] != '/')
243 strlcat(dir, "/", sizeof(dir));
244
245 uml_dir = malloc(strlen(dir) + 1);
246 if (uml_dir == NULL) {
247 printf("make_uml_dir : malloc failed, errno = %d\n", errno);
248 exit(1);
249 }
250 strcpy(uml_dir, dir);
251
252 if((mkdir(uml_dir, 0777) < 0) && (errno != EEXIST)){
253 printf("Failed to mkdir %s: %s\n", uml_dir, strerror(errno));
254 return(-1);
255 }
256 return 0;
257}
258
259static int __init make_umid(int (*printer)(const char *fmt, ...))
260{
261 int fd, err;
262 char tmp[strlen(uml_dir) + UMID_LEN + 1];
263
264 strlcpy(tmp, uml_dir, sizeof(tmp));
265
266 if(!umid_inited){
267 strcat(tmp, "XXXXXX");
268 fd = mkstemp(tmp);
269 if(fd < 0){
270 (*printer)("make_umid - mkstemp(%s) failed: %s\n",
271 tmp,strerror(errno));
272 return(1);
273 }
274
275 os_close_file(fd);
276 /* There's a nice tiny little race between this unlink and
277 * the mkdir below. It'd be nice if there were a mkstemp
278 * for directories.
279 */
280 unlink(tmp);
281 set_umid(&tmp[strlen(uml_dir)], 1, printer);
282 }
283
284 sprintf(tmp, "%s%s", uml_dir, umid);
285
286 err = mkdir(tmp, 0777);
287 if(err < 0){
288 if(errno == EEXIST){
289 if(not_dead_yet(tmp)){
290 (*printer)("umid '%s' is in use\n", umid);
291 umid_owned = 0;
292 return(-1);
293 }
294 err = mkdir(tmp, 0777);
295 }
296 }
297 if(err < 0){
298 (*printer)("Failed to create %s - errno = %d\n", umid, errno);
299 return(-1);
300 }
301
302 umid_owned = 1;
303 return 0;
304}
305
306__uml_setup("uml_dir=", set_uml_dir,
307"uml_dir=<directory>\n"
308" The location to place the pid and umid files.\n\n"
309);
310
311static int __init make_umid_setup(void)
312{
313 /* one function with the ordering we need ... */
314 make_uml_dir();
315 make_umid(printf);
316 create_pid_file();
317 return 0;
318}
319__uml_postsetup(make_umid_setup);
320
321/*
322 * Overrides for Emacs so that we follow Linus's tabbing style.
323 * Emacs will notice this stuff at the end of the file and automatically
324 * adjust the settings for this buffer only. This must remain at the end
325 * of the file.
326 * ---------------------------------------------------------------------------
327 * Local variables:
328 * c-file-style: "linux"
329 * End:
330 */
diff --git a/arch/um/os-Linux/Makefile b/arch/um/os-Linux/Makefile
index b83ac8e21c35..11e30b13e318 100644
--- a/arch/um/os-Linux/Makefile
+++ b/arch/um/os-Linux/Makefile
@@ -4,11 +4,11 @@
4# 4#
5 5
6obj-y = aio.o elf_aux.o file.o helper.o main.o mem.o process.o signal.o \ 6obj-y = aio.o elf_aux.o file.o helper.o main.o mem.o process.o signal.o \
7 start_up.o time.o tt.o tty.o uaccess.o user_syms.o drivers/ \ 7 start_up.o time.o tt.o tty.o uaccess.o umid.o user_syms.o drivers/ \
8 sys-$(SUBARCH)/ 8 sys-$(SUBARCH)/
9 9
10USER_OBJS := aio.o elf_aux.o file.o helper.o main.o mem.o process.o signal.o \ 10USER_OBJS := aio.o elf_aux.o file.o helper.o main.o mem.o process.o signal.o \
11 start_up.o time.o tt.o tty.o uaccess.o 11 start_up.o time.o tt.o tty.o uaccess.o umid.o
12 12
13elf_aux.o: $(ARCH_DIR)/kernel-offsets.h 13elf_aux.o: $(ARCH_DIR)/kernel-offsets.h
14CFLAGS_elf_aux.o += -I$(objtree)/arch/um 14CFLAGS_elf_aux.o += -I$(objtree)/arch/um
diff --git a/arch/um/os-Linux/aio.c b/arch/um/os-Linux/aio.c
index ffa759addd3c..f897140cc4ae 100644
--- a/arch/um/os-Linux/aio.c
+++ b/arch/um/os-Linux/aio.c
@@ -16,12 +16,12 @@
16#include "mode.h" 16#include "mode.h"
17 17
18struct aio_thread_req { 18struct aio_thread_req {
19 enum aio_type type; 19 enum aio_type type;
20 int io_fd; 20 int io_fd;
21 unsigned long long offset; 21 unsigned long long offset;
22 char *buf; 22 char *buf;
23 int len; 23 int len;
24 struct aio_context *aio; 24 struct aio_context *aio;
25}; 25};
26 26
27static int aio_req_fd_r = -1; 27static int aio_req_fd_r = -1;
@@ -38,18 +38,18 @@ static int aio_req_fd_w = -1;
38 38
39static long io_setup(int n, aio_context_t *ctxp) 39static long io_setup(int n, aio_context_t *ctxp)
40{ 40{
41 return syscall(__NR_io_setup, n, ctxp); 41 return syscall(__NR_io_setup, n, ctxp);
42} 42}
43 43
44static long io_submit(aio_context_t ctx, long nr, struct iocb **iocbpp) 44static long io_submit(aio_context_t ctx, long nr, struct iocb **iocbpp)
45{ 45{
46 return syscall(__NR_io_submit, ctx, nr, iocbpp); 46 return syscall(__NR_io_submit, ctx, nr, iocbpp);
47} 47}
48 48
49static long io_getevents(aio_context_t ctx_id, long min_nr, long nr, 49static long io_getevents(aio_context_t ctx_id, long min_nr, long nr,
50 struct io_event *events, struct timespec *timeout) 50 struct io_event *events, struct timespec *timeout)
51{ 51{
52 return syscall(__NR_io_getevents, ctx_id, min_nr, nr, events, timeout); 52 return syscall(__NR_io_getevents, ctx_id, min_nr, nr, events, timeout);
53} 53}
54 54
55#endif 55#endif
@@ -66,243 +66,245 @@ static long io_getevents(aio_context_t ctx_id, long min_nr, long nr,
66 */ 66 */
67 67
68static int do_aio(aio_context_t ctx, enum aio_type type, int fd, char *buf, 68static int do_aio(aio_context_t ctx, enum aio_type type, int fd, char *buf,
69 int len, unsigned long long offset, struct aio_context *aio) 69 int len, unsigned long long offset, struct aio_context *aio)
70{ 70{
71 struct iocb iocb, *iocbp = &iocb; 71 struct iocb iocb, *iocbp = &iocb;
72 char c; 72 char c;
73 int err; 73 int err;
74 74
75 iocb = ((struct iocb) { .aio_data = (unsigned long) aio, 75 iocb = ((struct iocb) { .aio_data = (unsigned long) aio,
76 .aio_reqprio = 0, 76 .aio_reqprio = 0,
77 .aio_fildes = fd, 77 .aio_fildes = fd,
78 .aio_buf = (unsigned long) buf, 78 .aio_buf = (unsigned long) buf,
79 .aio_nbytes = len, 79 .aio_nbytes = len,
80 .aio_offset = offset, 80 .aio_offset = offset,
81 .aio_reserved1 = 0, 81 .aio_reserved1 = 0,
82 .aio_reserved2 = 0, 82 .aio_reserved2 = 0,
83 .aio_reserved3 = 0 }); 83 .aio_reserved3 = 0 });
84 84
85 switch(type){ 85 switch(type){
86 case AIO_READ: 86 case AIO_READ:
87 iocb.aio_lio_opcode = IOCB_CMD_PREAD; 87 iocb.aio_lio_opcode = IOCB_CMD_PREAD;
88 err = io_submit(ctx, 1, &iocbp); 88 err = io_submit(ctx, 1, &iocbp);
89 break; 89 break;
90 case AIO_WRITE: 90 case AIO_WRITE:
91 iocb.aio_lio_opcode = IOCB_CMD_PWRITE; 91 iocb.aio_lio_opcode = IOCB_CMD_PWRITE;
92 err = io_submit(ctx, 1, &iocbp); 92 err = io_submit(ctx, 1, &iocbp);
93 break; 93 break;
94 case AIO_MMAP: 94 case AIO_MMAP:
95 iocb.aio_lio_opcode = IOCB_CMD_PREAD; 95 iocb.aio_lio_opcode = IOCB_CMD_PREAD;
96 iocb.aio_buf = (unsigned long) &c; 96 iocb.aio_buf = (unsigned long) &c;
97 iocb.aio_nbytes = sizeof(c); 97 iocb.aio_nbytes = sizeof(c);
98 err = io_submit(ctx, 1, &iocbp); 98 err = io_submit(ctx, 1, &iocbp);
99 break; 99 break;
100 default: 100 default:
101 printk("Bogus op in do_aio - %d\n", type); 101 printk("Bogus op in do_aio - %d\n", type);
102 err = -EINVAL; 102 err = -EINVAL;
103 break; 103 break;
104 } 104 }
105 105
106 if(err > 0) 106 if(err > 0)
107 err = 0; 107 err = 0;
108 else 108 else
109 err = -errno; 109 err = -errno;
110 110
111 return err; 111 return err;
112} 112}
113 113
114static aio_context_t ctx = 0; 114static aio_context_t ctx = 0;
115 115
116static int aio_thread(void *arg) 116static int aio_thread(void *arg)
117{ 117{
118 struct aio_thread_reply reply; 118 struct aio_thread_reply reply;
119 struct io_event event; 119 struct io_event event;
120 int err, n, reply_fd; 120 int err, n, reply_fd;
121 121
122 signal(SIGWINCH, SIG_IGN); 122 signal(SIGWINCH, SIG_IGN);
123 123
124 while(1){ 124 while(1){
125 n = io_getevents(ctx, 1, 1, &event, NULL); 125 n = io_getevents(ctx, 1, 1, &event, NULL);
126 if(n < 0){ 126 if(n < 0){
127 if(errno == EINTR) 127 if(errno == EINTR)
128 continue; 128 continue;
129 printk("aio_thread - io_getevents failed, " 129 printk("aio_thread - io_getevents failed, "
130 "errno = %d\n", errno); 130 "errno = %d\n", errno);
131 } 131 }
132 else { 132 else {
133 reply = ((struct aio_thread_reply) 133 reply = ((struct aio_thread_reply)
134 { .data = (void *) (long) event.data, 134 { .data = (void *) (long) event.data,
135 .err = event.res }); 135 .err = event.res });
136 reply_fd = ((struct aio_context *) reply.data)->reply_fd; 136 reply_fd = ((struct aio_context *) reply.data)->reply_fd;
137 err = os_write_file(reply_fd, &reply, sizeof(reply)); 137 err = os_write_file(reply_fd, &reply, sizeof(reply));
138 if(err != sizeof(reply)) 138 if(err != sizeof(reply))
139 printk("aio_thread - write failed, fd = %d, " 139 printk("aio_thread - write failed, fd = %d, "
140 "err = %d\n", aio_req_fd_r, -err); 140 "err = %d\n", aio_req_fd_r, -err);
141 } 141 }
142 } 142 }
143 return 0; 143 return 0;
144} 144}
145 145
146#endif 146#endif
147 147
148static int do_not_aio(struct aio_thread_req *req) 148static int do_not_aio(struct aio_thread_req *req)
149{ 149{
150 char c; 150 char c;
151 int err; 151 int err;
152 152
153 switch(req->type){ 153 switch(req->type){
154 case AIO_READ: 154 case AIO_READ:
155 err = os_seek_file(req->io_fd, req->offset); 155 err = os_seek_file(req->io_fd, req->offset);
156 if(err) 156 if(err)
157 goto out; 157 goto out;
158 158
159 err = os_read_file(req->io_fd, req->buf, req->len); 159 err = os_read_file(req->io_fd, req->buf, req->len);
160 break; 160 break;
161 case AIO_WRITE: 161 case AIO_WRITE:
162 err = os_seek_file(req->io_fd, req->offset); 162 err = os_seek_file(req->io_fd, req->offset);
163 if(err) 163 if(err)
164 goto out; 164 goto out;
165 165
166 err = os_write_file(req->io_fd, req->buf, req->len); 166 err = os_write_file(req->io_fd, req->buf, req->len);
167 break; 167 break;
168 case AIO_MMAP: 168 case AIO_MMAP:
169 err = os_seek_file(req->io_fd, req->offset); 169 err = os_seek_file(req->io_fd, req->offset);
170 if(err) 170 if(err)
171 goto out; 171 goto out;
172 172
173 err = os_read_file(req->io_fd, &c, sizeof(c)); 173 err = os_read_file(req->io_fd, &c, sizeof(c));
174 break; 174 break;
175 default: 175 default:
176 printk("do_not_aio - bad request type : %d\n", req->type); 176 printk("do_not_aio - bad request type : %d\n", req->type);
177 err = -EINVAL; 177 err = -EINVAL;
178 break; 178 break;
179 } 179 }
180 180
181 out: 181out:
182 return err; 182 return err;
183} 183}
184 184
185static int not_aio_thread(void *arg) 185static int not_aio_thread(void *arg)
186{ 186{
187 struct aio_thread_req req; 187 struct aio_thread_req req;
188 struct aio_thread_reply reply; 188 struct aio_thread_reply reply;
189 int err; 189 int err;
190 190
191 signal(SIGWINCH, SIG_IGN); 191 signal(SIGWINCH, SIG_IGN);
192 while(1){ 192 while(1){
193 err = os_read_file(aio_req_fd_r, &req, sizeof(req)); 193 err = os_read_file(aio_req_fd_r, &req, sizeof(req));
194 if(err != sizeof(req)){ 194 if(err != sizeof(req)){
195 if(err < 0) 195 if(err < 0)
196 printk("not_aio_thread - read failed, " 196 printk("not_aio_thread - read failed, "
197 "fd = %d, err = %d\n", aio_req_fd_r, 197 "fd = %d, err = %d\n", aio_req_fd_r,
198 -err); 198 -err);
199 else { 199 else {
200 printk("not_aio_thread - short read, fd = %d, " 200 printk("not_aio_thread - short read, fd = %d, "
201 "length = %d\n", aio_req_fd_r, err); 201 "length = %d\n", aio_req_fd_r, err);
202 } 202 }
203 continue; 203 continue;
204 } 204 }
205 err = do_not_aio(&req); 205 err = do_not_aio(&req);
206 reply = ((struct aio_thread_reply) { .data = req.aio, 206 reply = ((struct aio_thread_reply) { .data = req.aio,
207 .err = err }); 207 .err = err });
208 err = os_write_file(req.aio->reply_fd, &reply, sizeof(reply)); 208 err = os_write_file(req.aio->reply_fd, &reply, sizeof(reply));
209 if(err != sizeof(reply)) 209 if(err != sizeof(reply))
210 printk("not_aio_thread - write failed, fd = %d, " 210 printk("not_aio_thread - write failed, fd = %d, "
211 "err = %d\n", aio_req_fd_r, -err); 211 "err = %d\n", aio_req_fd_r, -err);
212 } 212 }
213
214 return 0;
213} 215}
214 216
215static int aio_pid = -1; 217static int aio_pid = -1;
216 218
217static int init_aio_24(void) 219static int init_aio_24(void)
218{ 220{
219 unsigned long stack; 221 unsigned long stack;
220 int fds[2], err; 222 int fds[2], err;
221 223
222 err = os_pipe(fds, 1, 1); 224 err = os_pipe(fds, 1, 1);
223 if(err) 225 if(err)
224 goto out; 226 goto out;
225 227
226 aio_req_fd_w = fds[0]; 228 aio_req_fd_w = fds[0];
227 aio_req_fd_r = fds[1]; 229 aio_req_fd_r = fds[1];
228 err = run_helper_thread(not_aio_thread, NULL, 230 err = run_helper_thread(not_aio_thread, NULL,
229 CLONE_FILES | CLONE_VM | SIGCHLD, &stack, 0); 231 CLONE_FILES | CLONE_VM | SIGCHLD, &stack, 0);
230 if(err < 0) 232 if(err < 0)
231 goto out_close_pipe; 233 goto out_close_pipe;
232 234
233 aio_pid = err; 235 aio_pid = err;
234 goto out; 236 goto out;
235 237
236 out_close_pipe: 238out_close_pipe:
237 os_close_file(fds[0]); 239 os_close_file(fds[0]);
238 os_close_file(fds[1]); 240 os_close_file(fds[1]);
239 aio_req_fd_w = -1; 241 aio_req_fd_w = -1;
240 aio_req_fd_r = -1; 242 aio_req_fd_r = -1;
241 out: 243out:
242#ifndef HAVE_AIO_ABI 244#ifndef HAVE_AIO_ABI
243 printk("/usr/include/linux/aio_abi.h not present during build\n"); 245 printk("/usr/include/linux/aio_abi.h not present during build\n");
244#endif 246#endif
245 printk("2.6 host AIO support not used - falling back to I/O " 247 printk("2.6 host AIO support not used - falling back to I/O "
246 "thread\n"); 248 "thread\n");
247 return 0; 249 return 0;
248} 250}
249 251
250#ifdef HAVE_AIO_ABI 252#ifdef HAVE_AIO_ABI
251#define DEFAULT_24_AIO 0 253#define DEFAULT_24_AIO 0
252static int init_aio_26(void) 254static int init_aio_26(void)
253{ 255{
254 unsigned long stack; 256 unsigned long stack;
255 int err; 257 int err;
256 258
257 if(io_setup(256, &ctx)){ 259 if(io_setup(256, &ctx)){
258 err = -errno; 260 err = -errno;
259 printk("aio_thread failed to initialize context, err = %d\n", 261 printk("aio_thread failed to initialize context, err = %d\n",
260 errno); 262 errno);
261 return err; 263 return err;
262 } 264 }
263 265
264 err = run_helper_thread(aio_thread, NULL, 266 err = run_helper_thread(aio_thread, NULL,
265 CLONE_FILES | CLONE_VM | SIGCHLD, &stack, 0); 267 CLONE_FILES | CLONE_VM | SIGCHLD, &stack, 0);
266 if(err < 0) 268 if(err < 0)
267 return err; 269 return err;
268 270
269 aio_pid = err; 271 aio_pid = err;
270 272
271 printk("Using 2.6 host AIO\n"); 273 printk("Using 2.6 host AIO\n");
272 return 0; 274 return 0;
273} 275}
274 276
275static int submit_aio_26(enum aio_type type, int io_fd, char *buf, int len, 277static int submit_aio_26(enum aio_type type, int io_fd, char *buf, int len,
276 unsigned long long offset, struct aio_context *aio) 278 unsigned long long offset, struct aio_context *aio)
277{ 279{
278 struct aio_thread_reply reply; 280 struct aio_thread_reply reply;
279 int err; 281 int err;
280 282
281 err = do_aio(ctx, type, io_fd, buf, len, offset, aio); 283 err = do_aio(ctx, type, io_fd, buf, len, offset, aio);
282 if(err){ 284 if(err){
283 reply = ((struct aio_thread_reply) { .data = aio, 285 reply = ((struct aio_thread_reply) { .data = aio,
284 .err = err }); 286 .err = err });
285 err = os_write_file(aio->reply_fd, &reply, sizeof(reply)); 287 err = os_write_file(aio->reply_fd, &reply, sizeof(reply));
286 if(err != sizeof(reply)) 288 if(err != sizeof(reply))
287 printk("submit_aio_26 - write failed, " 289 printk("submit_aio_26 - write failed, "
288 "fd = %d, err = %d\n", aio->reply_fd, -err); 290 "fd = %d, err = %d\n", aio->reply_fd, -err);
289 else err = 0; 291 else err = 0;
290 } 292 }
291 293
292 return err; 294 return err;
293} 295}
294 296
295#else 297#else
296#define DEFAULT_24_AIO 1 298#define DEFAULT_24_AIO 1
297static int init_aio_26(void) 299static int init_aio_26(void)
298{ 300{
299 return -ENOSYS; 301 return -ENOSYS;
300} 302}
301 303
302static int submit_aio_26(enum aio_type type, int io_fd, char *buf, int len, 304static int submit_aio_26(enum aio_type type, int io_fd, char *buf, int len,
303 unsigned long long offset, struct aio_context *aio) 305 unsigned long long offset, struct aio_context *aio)
304{ 306{
305 return -ENOSYS; 307 return -ENOSYS;
306} 308}
307#endif 309#endif
308 310
@@ -310,8 +312,8 @@ static int aio_24 = DEFAULT_24_AIO;
310 312
311static int __init set_aio_24(char *name, int *add) 313static int __init set_aio_24(char *name, int *add)
312{ 314{
313 aio_24 = 1; 315 aio_24 = 1;
314 return 0; 316 return 0;
315} 317}
316 318
317__uml_setup("aio=2.4", set_aio_24, 319__uml_setup("aio=2.4", set_aio_24,
@@ -328,28 +330,27 @@ __uml_setup("aio=2.4", set_aio_24,
328 330
329static int init_aio(void) 331static int init_aio(void)
330{ 332{
331 int err; 333 int err;
332 334
333 CHOOSE_MODE(({ 335 CHOOSE_MODE(({ if(!aio_24){
334 if(!aio_24){ 336 printk("Disabling 2.6 AIO in tt mode\n");
335 printk("Disabling 2.6 AIO in tt mode\n"); 337 aio_24 = 1;
336 aio_24 = 1; 338 } }), (void) 0);
337 } }), (void) 0); 339
338 340 if(!aio_24){
339 if(!aio_24){ 341 err = init_aio_26();
340 err = init_aio_26(); 342 if(err && (errno == ENOSYS)){
341 if(err && (errno == ENOSYS)){ 343 printk("2.6 AIO not supported on the host - "
342 printk("2.6 AIO not supported on the host - " 344 "reverting to 2.4 AIO\n");
343 "reverting to 2.4 AIO\n"); 345 aio_24 = 1;
344 aio_24 = 1; 346 }
345 } 347 else return err;
346 else return err; 348 }
347 } 349
348 350 if(aio_24)
349 if(aio_24) 351 return init_aio_24();
350 return init_aio_24(); 352
351 353 return 0;
352 return 0;
353} 354}
354 355
355/* The reason for the __initcall/__uml_exitcall asymmetry is that init_aio 356/* The reason for the __initcall/__uml_exitcall asymmetry is that init_aio
@@ -362,8 +363,8 @@ __initcall(init_aio);
362 363
363static void exit_aio(void) 364static void exit_aio(void)
364{ 365{
365 if(aio_pid != -1) 366 if(aio_pid != -1)
366 os_kill_process(aio_pid, 1); 367 os_kill_process(aio_pid, 1);
367} 368}
368 369
369__uml_exitcall(exit_aio); 370__uml_exitcall(exit_aio);
@@ -371,30 +372,30 @@ __uml_exitcall(exit_aio);
371static int submit_aio_24(enum aio_type type, int io_fd, char *buf, int len, 372static int submit_aio_24(enum aio_type type, int io_fd, char *buf, int len,
372 unsigned long long offset, struct aio_context *aio) 373 unsigned long long offset, struct aio_context *aio)
373{ 374{
374 struct aio_thread_req req = { .type = type, 375 struct aio_thread_req req = { .type = type,
375 .io_fd = io_fd, 376 .io_fd = io_fd,
376 .offset = offset, 377 .offset = offset,
377 .buf = buf, 378 .buf = buf,
378 .len = len, 379 .len = len,
379 .aio = aio, 380 .aio = aio,
380 }; 381 };
381 int err; 382 int err;
382 383
383 err = os_write_file(aio_req_fd_w, &req, sizeof(req)); 384 err = os_write_file(aio_req_fd_w, &req, sizeof(req));
384 if(err == sizeof(req)) 385 if(err == sizeof(req))
385 err = 0; 386 err = 0;
386 387
387 return err; 388 return err;
388} 389}
389 390
390int submit_aio(enum aio_type type, int io_fd, char *buf, int len, 391int submit_aio(enum aio_type type, int io_fd, char *buf, int len,
391 unsigned long long offset, int reply_fd, 392 unsigned long long offset, int reply_fd,
392 struct aio_context *aio) 393 struct aio_context *aio)
393{ 394{
394 aio->reply_fd = reply_fd; 395 aio->reply_fd = reply_fd;
395 if(aio_24) 396 if(aio_24)
396 return submit_aio_24(type, io_fd, buf, len, offset, aio); 397 return submit_aio_24(type, io_fd, buf, len, offset, aio);
397 else { 398 else {
398 return submit_aio_26(type, io_fd, buf, len, offset, aio); 399 return submit_aio_26(type, io_fd, buf, len, offset, aio);
399 } 400 }
400} 401}
diff --git a/arch/um/os-Linux/umid.c b/arch/um/os-Linux/umid.c
new file mode 100644
index 000000000000..ecf107ae5ac8
--- /dev/null
+++ b/arch/um/os-Linux/umid.c
@@ -0,0 +1,335 @@
1#include <stdio.h>
2#include <unistd.h>
3#include <stdlib.h>
4#include <string.h>
5#include <errno.h>
6#include <signal.h>
7#include <dirent.h>
8#include <sys/fcntl.h>
9#include <sys/stat.h>
10#include <sys/param.h>
11#include "init.h"
12#include "os.h"
13#include "user.h"
14#include "mode.h"
15
16#define UML_DIR "~/.uml/"
17
18#define UMID_LEN 64
19
20/* Changed by set_umid, which is run early in boot */
21char umid[UMID_LEN] = { 0 };
22
23/* Changed by set_uml_dir and make_uml_dir, which are run early in boot */
24static char *uml_dir = UML_DIR;
25
26static int __init make_uml_dir(void)
27{
28 char dir[512] = { '\0' };
29 int len, err;
30
31 if(*uml_dir == '~'){
32 char *home = getenv("HOME");
33
34 err = -ENOENT;
35 if(home == NULL){
36 printk("make_uml_dir : no value in environment for "
37 "$HOME\n");
38 goto err;
39 }
40 strlcpy(dir, home, sizeof(dir));
41 uml_dir++;
42 }
43 strlcat(dir, uml_dir, sizeof(dir));
44 len = strlen(dir);
45 if (len > 0 && dir[len - 1] != '/')
46 strlcat(dir, "/", sizeof(dir));
47
48 err = -ENOMEM;
49 uml_dir = malloc(strlen(dir) + 1);
50 if (uml_dir == NULL) {
51 printf("make_uml_dir : malloc failed, errno = %d\n", errno);
52 goto err;
53 }
54 strcpy(uml_dir, dir);
55
56 if((mkdir(uml_dir, 0777) < 0) && (errno != EEXIST)){
57 printf("Failed to mkdir '%s': %s\n", uml_dir, strerror(errno));
58 err = -errno;
59 goto err_free;
60 }
61 return 0;
62
63err_free:
64 free(uml_dir);
65err:
66 uml_dir = NULL;
67 return err;
68}
69
70static int actually_do_remove(char *dir)
71{
72 DIR *directory;
73 struct dirent *ent;
74 int len;
75 char file[256];
76
77 directory = opendir(dir);
78 if(directory == NULL)
79 return -errno;
80
81 while((ent = readdir(directory)) != NULL){
82 if(!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, ".."))
83 continue;
84 len = strlen(dir) + sizeof("/") + strlen(ent->d_name) + 1;
85 if(len > sizeof(file))
86 return -E2BIG;
87
88 sprintf(file, "%s/%s", dir, ent->d_name);
89 if(unlink(file) < 0)
90 return -errno;
91 }
92 if(rmdir(dir) < 0)
93 return -errno;
94
95 return 0;
96}
97
98/* This says that there isn't already a user of the specified directory even if
99 * there are errors during the checking. This is because if these errors
100 * happen, the directory is unusable by the pre-existing UML, so we might as
101 * well take it over. This could happen either by
102 * the existing UML somehow corrupting its umid directory
103 * something other than UML sticking stuff in the directory
104 * this boot racing with a shutdown of the other UML
105 * In any of these cases, the directory isn't useful for anything else.
106 */
107
108static int not_dead_yet(char *dir)
109{
110 char file[strlen(uml_dir) + UMID_LEN + sizeof("/pid\0")];
111 char pid[sizeof("nnnnn\0")], *end;
112 int dead, fd, p, n, err;
113
114 n = snprintf(file, sizeof(file), "%s/pid", dir);
115 if(n >= sizeof(file)){
116 printk("not_dead_yet - pid filename too long\n");
117 err = -E2BIG;
118 goto out;
119 }
120
121 dead = 0;
122 fd = open(file, O_RDONLY);
123 if(fd < 0){
124 if(fd != -ENOENT){
125 printk("not_dead_yet : couldn't open pid file '%s', "
126 "err = %d\n", file, -fd);
127 }
128 goto out;
129 }
130
131 err = 0;
132 n = read(fd, pid, sizeof(pid));
133 if(n <= 0){
134 printk("not_dead_yet : couldn't read pid file '%s', "
135 "err = %d\n", file, -n);
136 goto out_close;
137 }
138
139 p = strtoul(pid, &end, 0);
140 if(end == pid){
141 printk("not_dead_yet : couldn't parse pid file '%s', "
142 "errno = %d\n", file, errno);
143 goto out_close;
144 }
145
146 if((kill(p, 0) == 0) || (errno != ESRCH))
147 return 1;
148
149 err = actually_do_remove(dir);
150 if(err)
151 printk("not_dead_yet - actually_do_remove failed with "
152 "err = %d\n", err);
153
154 return err;
155
156 out_close:
157 close(fd);
158 out:
159 return 0;
160}
161
162static void __init create_pid_file(void)
163{
164 char file[strlen(uml_dir) + UMID_LEN + sizeof("/pid\0")];
165 char pid[sizeof("nnnnn\0")];
166 int fd, n;
167
168 if(umid_file_name("pid", file, sizeof(file)))
169 return;
170
171 fd = open(file, O_RDWR | O_CREAT | O_EXCL, 0644);
172 if(fd < 0){
173 printk("Open of machine pid file \"%s\" failed: %s\n",
174 file, strerror(-fd));
175 return;
176 }
177
178 snprintf(pid, sizeof(pid), "%d\n", getpid());
179 n = write(fd, pid, strlen(pid));
180 if(n != strlen(pid))
181 printk("Write of pid file failed - err = %d\n", -n);
182
183 close(fd);
184}
185
186int __init set_umid(char *name)
187{
188 if(strlen(name) > UMID_LEN - 1)
189 return -E2BIG;
190
191 strlcpy(umid, name, sizeof(umid));
192
193 return 0;
194}
195
196static int umid_setup = 0;
197
198int __init make_umid(void)
199{
200 int fd, err;
201 char tmp[256];
202
203 if(umid_setup)
204 return 0;
205
206 make_uml_dir();
207
208 if(*umid == '\0'){
209 strlcpy(tmp, uml_dir, sizeof(tmp));
210 strlcat(tmp, "XXXXXX", sizeof(tmp));
211 fd = mkstemp(tmp);
212 if(fd < 0){
213 printk("make_umid - mkstemp(%s) failed: %s\n",
214 tmp, strerror(errno));
215 err = -errno;
216 goto err;
217 }
218
219 close(fd);
220
221 set_umid(&tmp[strlen(uml_dir)]);
222
223 /* There's a nice tiny little race between this unlink and
224 * the mkdir below. It'd be nice if there were a mkstemp
225 * for directories.
226 */
227 if(unlink(tmp)){
228 err = -errno;
229 goto err;
230 }
231 }
232
233 snprintf(tmp, sizeof(tmp), "%s%s", uml_dir, umid);
234 err = mkdir(tmp, 0777);
235 if(err < 0){
236 err = -errno;
237 if(errno != EEXIST)
238 goto err;
239
240 if(not_dead_yet(tmp) < 0)
241 goto err;
242
243 err = mkdir(tmp, 0777);
244 }
245 if(err < 0){
246 printk("Failed to create '%s' - err = %d\n", umid, err);
247 goto err_rmdir;
248 }
249
250 umid_setup = 1;
251
252 create_pid_file();
253
254 return 0;
255
256 err_rmdir:
257 rmdir(tmp);
258 err:
259 return err;
260}
261
262static int __init make_umid_init(void)
263{
264 make_umid();
265
266 return 0;
267}
268
269__initcall(make_umid_init);
270
271int __init umid_file_name(char *name, char *buf, int len)
272{
273 int n, err;
274
275 err = make_umid();
276 if(err)
277 return err;
278
279 n = snprintf(buf, len, "%s%s/%s", uml_dir, umid, name);
280 if(n >= len){
281 printk("umid_file_name : buffer too short\n");
282 return -E2BIG;
283 }
284
285 return 0;
286}
287
288char *get_umid(void)
289{
290 return umid;
291}
292
293static int __init set_uml_dir(char *name, int *add)
294{
295 if(*name == '\0'){
296 printf("uml_dir can't be an empty string\n");
297 return 0;
298 }
299
300 if(name[strlen(name) - 1] == '/'){
301 uml_dir = name;
302 return 0;
303 }
304
305 uml_dir = malloc(strlen(name) + 2);
306 if(uml_dir == NULL){
307 printf("Failed to malloc uml_dir - error = %d\n", errno);
308
309 /* Return 0 here because do_initcalls doesn't look at
310 * the return value.
311 */
312 return 0;
313 }
314 sprintf(uml_dir, "%s/", name);
315
316 return 0;
317}
318
319__uml_setup("uml_dir=", set_uml_dir,
320"uml_dir=<directory>\n"
321" The location to place the pid and umid files.\n\n"
322);
323
324static void remove_umid_dir(void)
325{
326 char dir[strlen(uml_dir) + UMID_LEN + 1], err;
327
328 sprintf(dir, "%s%s", uml_dir, umid);
329 err = actually_do_remove(dir);
330 if(err)
331 printf("remove_umid_dir - actually_do_remove failed with "
332 "err = %d\n", err);
333}
334
335__uml_exitcall(remove_umid_dir);
diff --git a/arch/x86_64/Kconfig.debug b/arch/x86_64/Kconfig.debug
index e2c6e64a85ec..fcb06a50fdd2 100644
--- a/arch/x86_64/Kconfig.debug
+++ b/arch/x86_64/Kconfig.debug
@@ -9,6 +9,16 @@ config INIT_DEBUG
9 Fill __init and __initdata at the end of boot. This helps debugging 9 Fill __init and __initdata at the end of boot. This helps debugging
10 illegal uses of __init and __initdata after initialization. 10 illegal uses of __init and __initdata after initialization.
11 11
12config DEBUG_RODATA
13 bool "Write protect kernel read-only data structures"
14 depends on DEBUG_KERNEL
15 help
16 Mark the kernel read-only data as write-protected in the pagetables,
17 in order to catch accidental (and incorrect) writes to such const data.
18 This option may have a slight performance impact because a portion
19 of the kernel code won't be covered by a 2MB TLB anymore.
20 If in doubt, say "N".
21
12config IOMMU_DEBUG 22config IOMMU_DEBUG
13 depends on GART_IOMMU && DEBUG_KERNEL 23 depends on GART_IOMMU && DEBUG_KERNEL
14 bool "Enable IOMMU debugging" 24 bool "Enable IOMMU debugging"
diff --git a/arch/x86_64/ia32/ia32entry.S b/arch/x86_64/ia32/ia32entry.S
index e0eb0c712fe9..df0773c9bdbe 100644
--- a/arch/x86_64/ia32/ia32entry.S
+++ b/arch/x86_64/ia32/ia32entry.S
@@ -341,7 +341,7 @@ ENTRY(ia32_ptregs_common)
341 jmp ia32_sysret /* misbalances the return cache */ 341 jmp ia32_sysret /* misbalances the return cache */
342 CFI_ENDPROC 342 CFI_ENDPROC
343 343
344 .data 344 .section .rodata,"a"
345 .align 8 345 .align 8
346 .globl ia32_sys_call_table 346 .globl ia32_sys_call_table
347ia32_sys_call_table: 347ia32_sys_call_table:
diff --git a/arch/x86_64/kernel/process.c b/arch/x86_64/kernel/process.c
index 7519fc520eb3..3060ed97b755 100644
--- a/arch/x86_64/kernel/process.c
+++ b/arch/x86_64/kernel/process.c
@@ -157,7 +157,7 @@ EXPORT_SYMBOL_GPL(cpu_idle_wait);
157DECLARE_PER_CPU(int, cpu_state); 157DECLARE_PER_CPU(int, cpu_state);
158 158
159#include <asm/nmi.h> 159#include <asm/nmi.h>
160/* We don't actually take CPU down, just spin without interrupts. */ 160/* We halt the CPU with physical CPU hotplug */
161static inline void play_dead(void) 161static inline void play_dead(void)
162{ 162{
163 idle_task_exit(); 163 idle_task_exit();
@@ -166,8 +166,9 @@ static inline void play_dead(void)
166 /* Ack it */ 166 /* Ack it */
167 __get_cpu_var(cpu_state) = CPU_DEAD; 167 __get_cpu_var(cpu_state) = CPU_DEAD;
168 168
169 local_irq_disable();
169 while (1) 170 while (1)
170 safe_halt(); 171 halt();
171} 172}
172#else 173#else
173static inline void play_dead(void) 174static inline void play_dead(void)
diff --git a/arch/x86_64/kernel/syscall.c b/arch/x86_64/kernel/syscall.c
index e263685f864c..7c176b3edde0 100644
--- a/arch/x86_64/kernel/syscall.c
+++ b/arch/x86_64/kernel/syscall.c
@@ -19,7 +19,7 @@ typedef void (*sys_call_ptr_t)(void);
19 19
20extern void sys_ni_syscall(void); 20extern void sys_ni_syscall(void);
21 21
22sys_call_ptr_t sys_call_table[__NR_syscall_max+1] __cacheline_aligned = { 22const sys_call_ptr_t sys_call_table[__NR_syscall_max+1] = {
23 /* Smells like a like a compiler bug -- it doesn't work when the & below is removed. */ 23 /* Smells like a like a compiler bug -- it doesn't work when the & below is removed. */
24 [0 ... __NR_syscall_max] = &sys_ni_syscall, 24 [0 ... __NR_syscall_max] = &sys_ni_syscall,
25#include <asm-x86_64/unistd.h> 25#include <asm-x86_64/unistd.h>
diff --git a/arch/x86_64/mm/init.c b/arch/x86_64/mm/init.c
index c016dfe84784..1faae5fc1c01 100644
--- a/arch/x86_64/mm/init.c
+++ b/arch/x86_64/mm/init.c
@@ -498,6 +498,29 @@ void free_initmem(void)
498 printk ("Freeing unused kernel memory: %luk freed\n", (__init_end - __init_begin) >> 10); 498 printk ("Freeing unused kernel memory: %luk freed\n", (__init_end - __init_begin) >> 10);
499} 499}
500 500
501#ifdef CONFIG_DEBUG_RODATA
502
503extern char __start_rodata, __end_rodata;
504void mark_rodata_ro(void)
505{
506 unsigned long addr = (unsigned long)&__start_rodata;
507
508 for (; addr < (unsigned long)&__end_rodata; addr += PAGE_SIZE)
509 change_page_attr_addr(addr, 1, PAGE_KERNEL_RO);
510
511 printk ("Write protecting the kernel read-only data: %luk\n",
512 (&__end_rodata - &__start_rodata) >> 10);
513
514 /*
515 * change_page_attr_addr() requires a global_flush_tlb() call after it.
516 * We do this after the printk so that if something went wrong in the
517 * change, the printk gets out at least to give a better debug hint
518 * of who is the culprit.
519 */
520 global_flush_tlb();
521}
522#endif
523
501#ifdef CONFIG_BLK_DEV_INITRD 524#ifdef CONFIG_BLK_DEV_INITRD
502void free_initrd_mem(unsigned long start, unsigned long end) 525void free_initrd_mem(unsigned long start, unsigned long end)
503{ 526{
diff --git a/arch/x86_64/mm/pageattr.c b/arch/x86_64/mm/pageattr.c
index b90e8fe9eeb0..35f1f1aab063 100644
--- a/arch/x86_64/mm/pageattr.c
+++ b/arch/x86_64/mm/pageattr.c
@@ -128,6 +128,7 @@ __change_page_attr(unsigned long address, unsigned long pfn, pgprot_t prot,
128 pte_t *kpte; 128 pte_t *kpte;
129 struct page *kpte_page; 129 struct page *kpte_page;
130 unsigned kpte_flags; 130 unsigned kpte_flags;
131 pgprot_t ref_prot2;
131 kpte = lookup_address(address); 132 kpte = lookup_address(address);
132 if (!kpte) return 0; 133 if (!kpte) return 0;
133 kpte_page = virt_to_page(((unsigned long)kpte) & PAGE_MASK); 134 kpte_page = virt_to_page(((unsigned long)kpte) & PAGE_MASK);
@@ -140,10 +141,14 @@ __change_page_attr(unsigned long address, unsigned long pfn, pgprot_t prot,
140 * split_large_page will take the reference for this change_page_attr 141 * split_large_page will take the reference for this change_page_attr
141 * on the split page. 142 * on the split page.
142 */ 143 */
143 struct page *split = split_large_page(address, prot, ref_prot); 144
145 struct page *split;
146 ref_prot2 = __pgprot(pgprot_val(pte_pgprot(*lookup_address(address))) & ~(1<<_PAGE_BIT_PSE));
147
148 split = split_large_page(address, prot, ref_prot2);
144 if (!split) 149 if (!split)
145 return -ENOMEM; 150 return -ENOMEM;
146 set_pte(kpte,mk_pte(split, ref_prot)); 151 set_pte(kpte,mk_pte(split, ref_prot2));
147 kpte_page = split; 152 kpte_page = split;
148 } 153 }
149 get_page(kpte_page); 154 get_page(kpte_page);