diff options
author | Greg Kroah-Hartman <gregkh@suse.de> | 2006-01-06 15:59:59 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2006-01-06 15:59:59 -0500 |
commit | ccf18968b1bbc2fb117190a1984ac2a826dac228 (patch) | |
tree | 7bc8fbf5722aecf1e84fa50c31c657864cba1daa /arch | |
parent | e91c021c487110386a07facd0396e6c3b7cf9c1f (diff) | |
parent | d99cf9d679a520d67f81d805b7cb91c68e1847f0 (diff) |
Merge ../torvalds-2.6/
Diffstat (limited to 'arch')
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 | ||
43 | config GENERIC_HARDIRQS | ||
44 | bool | ||
45 | default y | ||
46 | |||
47 | config GENERIC_IRQ_PROBE | ||
48 | bool | ||
49 | default y | ||
50 | |||
51 | config AUTO_IRQ_AFFINITY | ||
52 | bool | ||
53 | depends on SMP | ||
54 | default y | ||
55 | |||
43 | source "init/Kconfig" | 56 | source "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 |
178 | EXPORT_SYMBOL(synchronize_irq); | ||
179 | EXPORT_SYMBOL(flush_tlb_mm); | 178 | EXPORT_SYMBOL(flush_tlb_mm); |
180 | EXPORT_SYMBOL(flush_tlb_range); | 179 | EXPORT_SYMBOL(flush_tlb_range); |
181 | EXPORT_SYMBOL(flush_tlb_page); | 180 | EXPORT_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 | */ | ||
38 | irq_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 | |||
45 | static void register_irq_proc(unsigned int irq); | ||
46 | |||
47 | volatile unsigned long irq_err_count; | 35 | volatile unsigned long irq_err_count; |
48 | 36 | ||
49 | /* | 37 | void ack_bad_irq(unsigned int irq) |
50 | * Special irq handlers. | ||
51 | */ | ||
52 | |||
53 | irqreturn_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 | |||
62 | static void no_irq_enable_disable(unsigned int irq) { } | ||
63 | static unsigned int no_irq_startup(unsigned int irq) { return 0; } | ||
64 | |||
65 | static void | ||
66 | no_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 | ||
72 | struct 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 | |||
82 | int | ||
83 | handle_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 | */ | ||
113 | void inline | ||
114 | disable_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 | */ | ||
131 | void | ||
132 | disable_irq(unsigned int irq) | ||
133 | { | ||
134 | disable_irq_nosync(irq); | ||
135 | synchronize_irq(irq); | ||
136 | } | ||
137 | |||
138 | void | ||
139 | enable_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 | |||
166 | int | ||
167 | setup_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 | |||
227 | static struct proc_dir_entry * root_irq_dir; | ||
228 | static struct proc_dir_entry * irq_dir[NR_IRQS]; | ||
229 | |||
230 | #ifdef CONFIG_SMP | 43 | #ifdef CONFIG_SMP |
231 | static struct proc_dir_entry * smp_affinity_entry[NR_IRQS]; | ||
232 | static char irq_user_affinity[NR_IRQS]; | 44 | static char irq_user_affinity[NR_IRQS]; |
233 | static cpumask_t irq_affinity[NR_IRQS] = { [0 ... NR_IRQS-1] = CPU_MASK_ALL }; | ||
234 | 45 | ||
235 | static void | 46 | int |
236 | select_smp_affinity(int irq) | 47 | select_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 | |||
252 | static int | ||
253 | irq_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 | |||
263 | static int | ||
264 | irq_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 | |||
298 | static void | ||
299 | register_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 | |||
331 | void | ||
332 | init_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 | |||
354 | int | ||
355 | request_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 | |||
402 | EXPORT_SYMBOL(request_irq); | ||
403 | |||
404 | void | ||
405 | free_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 | |||
450 | EXPORT_SYMBOL(free_irq); | ||
451 | |||
452 | int | 65 | int |
453 | show_interrupts(struct seq_file *p, void *v) | 66 | show_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; | ||
600 | out: | ||
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 | */ | ||
619 | unsigned long | ||
620 | probe_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 | |||
689 | EXPORT_SYMBOL(probe_irq_on); | ||
690 | |||
691 | /* | ||
692 | * Return a mask of triggered interrupts (this | ||
693 | * can handle only legacy ISA interrupts). | ||
694 | */ | ||
695 | unsigned int | ||
696 | probe_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 | |||
731 | int | ||
732 | probe_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 | |||
762 | EXPORT_SYMBOL(probe_irq_off); | ||
763 | |||
764 | #ifdef CONFIG_SMP | ||
765 | void 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 | ||
572 | int | ||
573 | double_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 | |||
20 | obj-$(CONFIG_PM) += pm.o cmode.o | 20 | obj-$(CONFIG_PM) += pm.o cmode.o |
21 | obj-$(CONFIG_MB93093_PDK) += pm-mb93093.o | 21 | obj-$(CONFIG_MB93093_PDK) += pm-mb93093.o |
22 | obj-$(CONFIG_SYSCTL) += sysctl.o | 22 | obj-$(CONFIG_SYSCTL) += sysctl.o |
23 | obj-$(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 | */ | ||
21 | static 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 | |||
53 | static 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 | |||
86 | static 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 | |||
119 | static 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 | |||
152 | static 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 | */ | ||
189 | int 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 | ||
38 | asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset); | 38 | static 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 | */ |
278 | static inline void __user *get_sigframe(struct k_sigaction *ka, | 278 | static 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 | */ |
300 | static void setup_frame(int sig, struct k_sigaction *ka, sigset_t *set, struct pt_regs * regs) | 300 | static 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 | ||
372 | give_sigsegv: | 377 | give_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 | */ |
383 | static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | 387 | static 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 | ||
467 | give_sigsegv: | 476 | give_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 | */ |
478 | static void handle_signal(unsigned long sig, siginfo_t *info, | 486 | static 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(¤t->sighand->siglock); | ||
521 | sigorsets(¤t->blocked, ¤t->blocked, | ||
522 | &ka->sa.sa_mask); | ||
523 | if (!(ka->sa.sa_flags & SA_NODEFER)) | ||
524 | sigaddset(¤t->blocked, sig); | ||
525 | recalc_sigpending(); | ||
526 | spin_unlock_irq(¤t->sighand->siglock); | ||
527 | } | ||
528 | |||
529 | return ret; | ||
508 | 530 | ||
509 | spin_lock_irq(¤t->sighand->siglock); | ||
510 | sigorsets(¤t->blocked, ¤t->blocked, &ka->sa.sa_mask); | ||
511 | if (!(ka->sa.sa_flags & SA_NODEFER)) | ||
512 | sigaddset(¤t->blocked, sig); | ||
513 | recalc_sigpending(); | ||
514 | spin_unlock_irq(¤t->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 | */ |
523 | int do_signal(struct pt_regs *regs, sigset_t *oldset) | 539 | static 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 = ¤t->blocked; | 558 | oldset = ¤t->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: | 564 | no_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 |
470 | comment "NUMA (NUMA-Q) requires SMP, 64GB highmem support" | 469 | comment "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 | ||
495 | config ARCH_FLATMEM_ENABLE | ||
496 | def_bool y | ||
497 | depends on (ARCH_SELECT_MEMORY_MODEL && X86_PC) | ||
498 | |||
496 | config ARCH_DISCONTIGMEM_ENABLE | 499 | config 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 | ||
504 | config ARCH_SPARSEMEM_ENABLE | 507 | config 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 | ||
508 | config ARCH_SELECT_MEMORY_MODEL | 512 | config 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 | ||
175 | config MGEODE_LX | ||
176 | bool "Geode GX/LX" | ||
177 | help | ||
178 | Select this for AMD Geode GX and LX processors. | ||
179 | |||
174 | config MCYRIXIII | 180 | config MCYRIXIII |
175 | bool "CyrixIII/VIA-C3" | 181 | bool "CyrixIII/VIA-C3" |
176 | help | 182 | help |
@@ -220,8 +226,8 @@ config X86_XADD | |||
220 | config X86_L1_CACHE_SHIFT | 226 | config 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 | ||
227 | config RWSEM_GENERIC_SPINLOCK | 233 | config RWSEM_GENERIC_SPINLOCK |
@@ -290,12 +296,12 @@ config X86_INTEL_USERCOPY | |||
290 | 296 | ||
291 | config X86_USE_PPRO_CHECKSUM | 297 | config 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 | ||
296 | config X86_USE_3DNOW | 302 | config 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 | ||
301 | config X86_OOSTORE | 307 | config 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 | ||
45 | config 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 | |||
45 | config 4KSTACKS | 55 | config 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 | ||
1076 | static int apm_console_blank(int blank) | 1065 | static 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[] = { | |||
2233 | static int __init apm_init(void) | 2223 | static 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 | ||
21 | DEFINE_PER_CPU(struct desc_struct, cpu_gdt_table[GDT_ENTRIES]); | ||
22 | EXPORT_PER_CPU_SYMBOL(cpu_gdt_table); | ||
23 | |||
24 | DEFINE_PER_CPU(unsigned char, cpu_16bit_stack[CPU_16BIT_STACK_SIZE]); | 21 | DEFINE_PER_CPU(unsigned char, cpu_16bit_stack[CPU_16BIT_STACK_SIZE]); |
25 | EXPORT_PER_CPU_SYMBOL(cpu_16bit_stack); | 22 | EXPORT_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 | */ | ||
348 | static 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) | |||
422 | static struct cpu_dev nsc_cpu_dev __initdata = { | 447 | static 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 | ||
662 | syscall_table_size=(.-sys_call_table) | 663 | syscall_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 */ | 6 | EXPORT_SYMBOL_GPL(cpu_gdt_descr); |
7 | EXPORT_SYMBOL_GPL(cpu_gdt_table); | ||
8 | 7 | ||
9 | EXPORT_SYMBOL(__down_failed); | 8 | EXPORT_SYMBOL(__down_failed); |
10 | EXPORT_SYMBOL(__down_failed_interruptible); | 9 | EXPORT_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 @@ | |||
38 | int smp_found_config; | 38 | int smp_found_config; |
39 | unsigned int __initdata maxcpus = NR_CPUS; | 39 | unsigned 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, ®s->esp); | 313 | show_trace(NULL, ®s->esp); |
316 | } | 314 | } |
@@ -404,17 +402,7 @@ void flush_thread(void) | |||
404 | 402 | ||
405 | void release_thread(struct task_struct *dead_task) | 403 | void 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 | ||
957 | static int __init | ||
958 | efi_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 | ||
2 | ENTRY(sys_call_table) | 1 | ENTRY(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,÷_error); | 1078 | set_trap_gate(0,÷_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 | |||
740 | extern char __start_rodata, __end_rodata; | ||
741 | void 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 |
739 | void free_initrd_mem(unsigned long start, unsigned long end) | 763 | void 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 | ||
17 | static DEFINE_SPINLOCK(cpa_lock); | 18 | static DEFINE_SPINLOCK(cpa_lock); |
18 | static struct list_head df_list = LIST_HEAD_INIT(df_list); | 19 | static 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 | ||
39 | static struct page *split_large_page(unsigned long address, pgprot_t prot) | 40 | static 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 | */ |
99 | static inline void revert_page(struct page *kpte_page, unsigned long address) | 101 | static 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 | ||
108 | static int | 117 | static 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 | |||
81 | config PLAT_MAPPI3 | 81 | config PLAT_MAPPI3 |
82 | bool "Mappi-III(M3A-2170)" | 82 | bool "Mappi-III(M3A-2170)" |
83 | 83 | ||
84 | config 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 | |||
84 | endchoice | 90 | endchoice |
85 | 91 | ||
86 | choice | 92 | choice |
@@ -93,6 +99,10 @@ config CHIP_M32700 | |||
93 | config CHIP_M32102 | 99 | config CHIP_M32102 |
94 | bool "M32102" | 100 | bool "M32102" |
95 | 101 | ||
102 | config CHIP_M32104 | ||
103 | bool "M32104" | ||
104 | depends on PLAT_M32104UT | ||
105 | |||
96 | config CHIP_VDEC2 | 106 | config CHIP_VDEC2 |
97 | bool "VDEC2" | 107 | bool "VDEC2" |
98 | 108 | ||
@@ -115,7 +125,7 @@ config TLB_ENTRIES | |||
115 | 125 | ||
116 | config ISA_M32R | 126 | config 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 | ||
121 | config ISA_M32R2 | 131 | config 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 | ||
162 | config MEMORY_SIZE | 174 | config 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 | ||
171 | config NOHIGHMEM | 184 | config NOHIGHMEM |
@@ -174,21 +187,22 @@ config NOHIGHMEM | |||
174 | 187 | ||
175 | config ARCH_DISCONTIGMEM_ENABLE | 188 | config 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 | ||
180 | source "mm/Kconfig" | 193 | source "mm/Kconfig" |
181 | 194 | ||
182 | config IRAM_START | 195 | config 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 | ||
187 | config IRAM_SIZE | 201 | config 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 | |||
16 | obj-$(CONFIG_PLAT_OPSPUT) += setup_opsput.o io_opsput.o | 16 | obj-$(CONFIG_PLAT_OPSPUT) += setup_opsput.o io_opsput.o |
17 | obj-$(CONFIG_MODULES) += module.o | 17 | obj-$(CONFIG_MODULES) += module.o |
18 | obj-$(CONFIG_PLAT_OAKS32R) += setup_oaks32r.o io_oaks32r.o | 18 | obj-$(CONFIG_PLAT_OAKS32R) += setup_oaks32r.o io_oaks32r.o |
19 | obj-$(CONFIG_PLAT_M32104UT) += setup_m32104ut.o io_m32104ut.o | ||
19 | 20 | ||
20 | EXTRA_AFLAGS := -traditional | 21 | EXTRA_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 |
543 | check_end: | 543 | check_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 | ||
556 | check_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 | |||
25 | extern void pcc_ioread_byte(int, unsigned long, void *, size_t, size_t, int); | ||
26 | extern void pcc_ioread_word(int, unsigned long, void *, size_t, size_t, int); | ||
27 | extern void pcc_iowrite_byte(int, unsigned long, void *, size_t, size_t, int); | ||
28 | extern 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 | |||
33 | static inline void *_port2addr(unsigned long port) | ||
34 | { | ||
35 | return (void *)(port | NONCACHE_OFFSET); | ||
36 | } | ||
37 | |||
38 | #if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC) | ||
39 | static 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) | ||
65 | static inline void *_port2addr_ne(unsigned long port) | ||
66 | { | ||
67 | return (void *)(port + NONCACHE_OFFSET + 0x01000000); | ||
68 | } | ||
69 | |||
70 | static 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 | |||
81 | static inline unsigned char _ne_inb(void *portp) | ||
82 | { | ||
83 | return *(volatile unsigned char *)portp; | ||
84 | } | ||
85 | |||
86 | static inline unsigned short _ne_inw(void *portp) | ||
87 | { | ||
88 | return (unsigned short)le16_to_cpu(*(volatile unsigned short *)portp); | ||
89 | } | ||
90 | |||
91 | static 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 | |||
99 | static inline void _ne_outb(unsigned char b, void *portp) | ||
100 | { | ||
101 | *(volatile unsigned char *)portp = b; | ||
102 | } | ||
103 | |||
104 | static inline void _ne_outw(unsigned short w, void *portp) | ||
105 | { | ||
106 | *(volatile unsigned short *)portp = cpu_to_le16(w); | ||
107 | } | ||
108 | |||
109 | unsigned 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 | |||
117 | unsigned 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 | |||
125 | unsigned long _inl(unsigned long port) | ||
126 | { | ||
127 | return *(volatile unsigned long *)PORT2ADDR(port); | ||
128 | } | ||
129 | |||
130 | unsigned char _inb_p(unsigned long port) | ||
131 | { | ||
132 | unsigned char v = _inb(port); | ||
133 | delay(); | ||
134 | return (v); | ||
135 | } | ||
136 | |||
137 | unsigned short _inw_p(unsigned long port) | ||
138 | { | ||
139 | unsigned short v = _inw(port); | ||
140 | delay(); | ||
141 | return (v); | ||
142 | } | ||
143 | |||
144 | unsigned long _inl_p(unsigned long port) | ||
145 | { | ||
146 | unsigned long v = _inl(port); | ||
147 | delay(); | ||
148 | return (v); | ||
149 | } | ||
150 | |||
151 | void _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 | |||
159 | void _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 | |||
167 | void _outl(unsigned long l, unsigned long port) | ||
168 | { | ||
169 | *(volatile unsigned long *)PORT2ADDR(port) = l; | ||
170 | } | ||
171 | |||
172 | void _outb_p(unsigned char b, unsigned long port) | ||
173 | { | ||
174 | _outb(b, port); | ||
175 | delay(); | ||
176 | } | ||
177 | |||
178 | void _outw_p(unsigned short w, unsigned long port) | ||
179 | { | ||
180 | _outw(w, port); | ||
181 | delay(); | ||
182 | } | ||
183 | |||
184 | void _outl_p(unsigned long l, unsigned long port) | ||
185 | { | ||
186 | _outl(l, port); | ||
187 | delay(); | ||
188 | } | ||
189 | |||
190 | void _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 | |||
202 | void _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 | |||
233 | void _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 | |||
243 | void _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 | |||
259 | void _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 | |||
290 | void _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 | ||
37 | static inline void *_port2addr(unsigned long port) | 37 | static 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) |
69 | static inline void *_port2addr_ne(unsigned long port) | 69 | static 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 | ||
32 | static inline void *_port2addr(unsigned long port) | 32 | static inline void *_port2addr(unsigned long port) |
33 | { | 33 | { |
34 | return (void *)(port | (NONCACHE_OFFSET)); | 34 | return (void *)(port | NONCACHE_OFFSET); |
35 | } | 35 | } |
36 | 36 | ||
37 | static inline void *_port2addr_ne(unsigned long port) | 37 | static 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 | ||
34 | static inline void *_port2addr(unsigned long port) | 34 | static 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 |
62 | static inline void *_port2addr_ne(unsigned long port) | 62 | static 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 | ||
34 | static inline void *_port2addr(unsigned long port) | 34 | static 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) |
73 | static inline void *_port2addr_ne(unsigned long port) | 82 | static 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 | ||
17 | static inline void *_port2addr(unsigned long port) | 17 | static inline void *_port2addr(unsigned long port) |
18 | { | 18 | { |
19 | return (void *)(port | (NONCACHE_OFFSET)); | 19 | return (void *)(port | NONCACHE_OFFSET); |
20 | } | 20 | } |
21 | 21 | ||
22 | static inline void *_port2addr_ne(unsigned long port) | 22 | static 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 | ||
37 | static inline void *_port2addr(unsigned long port) | 37 | static 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) |
49 | static inline void *_port2addr_ne(unsigned long port) | 49 | static 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) |
393 | void __init cpu_init (void) | 398 | void __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 | |||
23 | icu_data_t icu_data[NR_IRQS]; | ||
24 | |||
25 | static 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 | |||
34 | static 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 | |||
43 | static void mask_and_ack_m32104ut(unsigned int irq) | ||
44 | { | ||
45 | disable_m32104ut_irq(irq); | ||
46 | } | ||
47 | |||
48 | static void end_m32104ut_irq(unsigned int irq) | ||
49 | { | ||
50 | enable_m32104ut_irq(irq); | ||
51 | } | ||
52 | |||
53 | static unsigned int startup_m32104ut_irq(unsigned int irq) | ||
54 | { | ||
55 | enable_m32104ut_irq(irq); | ||
56 | return (0); | ||
57 | } | ||
58 | |||
59 | static 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 | |||
67 | static 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 | |||
78 | void __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 | ||
128 | static 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 | |||
141 | static 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 | |||
149 | static int __init platform_init(void) | ||
150 | { | ||
151 | #if defined(CONFIG_SMC91X) | ||
152 | platform_device_register(&smc91x_device); | ||
153 | #endif | ||
154 | return 0; | ||
155 | } | ||
156 | arch_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 | ||
30 | typedef struct { | ||
31 | unsigned long icucr; /* ICU Control Register */ | ||
32 | } icu_data_t; | ||
33 | static icu_data_t icu_data[M32700UT_NUM_CPU_IRQ]; | ||
34 | #else | ||
35 | icu_data_t icu_data[M32700UT_NUM_CPU_IRQ]; | 29 | icu_data_t icu_data[M32700UT_NUM_CPU_IRQ]; |
36 | #endif /* CONFIG_SMP */ | ||
37 | |||
38 | 30 | ||
39 | static void disable_m32700ut_irq(unsigned int irq) | 31 | static 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 | ||
23 | typedef struct { | ||
24 | unsigned long icucr; /* ICU Control Register */ | ||
25 | } icu_data_t; | ||
26 | #endif /* CONFIG_SMP */ | ||
27 | |||
28 | icu_data_t icu_data[NR_IRQS]; | 22 | icu_data_t icu_data[NR_IRQS]; |
29 | 23 | ||
30 | static void disable_mappi_irq(unsigned int irq) | 24 | static 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 | ||
23 | typedef struct { | ||
24 | unsigned long icucr; /* ICU Control Register */ | ||
25 | } icu_data_t; | ||
26 | #endif /* CONFIG_SMP */ | ||
27 | |||
28 | icu_data_t icu_data[NR_IRQS]; | 22 | icu_data_t icu_data[NR_IRQS]; |
29 | 23 | ||
30 | static void disable_mappi2_irq(unsigned int irq) | 24 | static 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 | ||
23 | typedef struct { | ||
24 | unsigned long icucr; /* ICU Control Register */ | ||
25 | } icu_data_t; | ||
26 | #endif /* CONFIG_SMP */ | ||
27 | |||
28 | icu_data_t icu_data[NR_IRQS]; | 22 | icu_data_t icu_data[NR_IRQS]; |
29 | 23 | ||
30 | static void disable_mappi3_irq(unsigned int irq) | 24 | static 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 | ||
22 | typedef struct { | ||
23 | unsigned long icucr; /* ICU Control Register */ | ||
24 | } icu_data_t; | ||
25 | #endif /* CONFIG_SMP */ | ||
26 | |||
27 | icu_data_t icu_data[NR_IRQS]; | 21 | icu_data_t icu_data[NR_IRQS]; |
28 | 22 | ||
29 | static void disable_oaks32r_irq(unsigned int irq) | 23 | static 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 | ||
31 | typedef struct { | ||
32 | unsigned long icucr; /* ICU Control Register */ | ||
33 | } icu_data_t; | ||
34 | static icu_data_t icu_data[OPSPUT_NUM_CPU_IRQ]; | ||
35 | #else | ||
36 | icu_data_t icu_data[OPSPUT_NUM_CPU_IRQ]; | 30 | icu_data_t icu_data[OPSPUT_NUM_CPU_IRQ]; |
37 | #endif /* CONFIG_SMP */ | ||
38 | |||
39 | 31 | ||
40 | static void disable_opsput_irq(unsigned int irq) | 32 | static 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) | ||
22 | typedef struct { | ||
23 | unsigned long icucr; /* ICU Control Register */ | ||
24 | } icu_data_t; | ||
25 | #endif /* CONFIG_SMP */ | ||
26 | |||
27 | icu_data_t icu_data[M32700UT_NUM_CPU_IRQ]; | 21 | icu_data_t icu_data[M32700UT_NUM_CPU_IRQ]; |
28 | 22 | ||
29 | static void disable_mappi_irq(unsigned int irq) | 23 | static 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 | # | ||
6 | CONFIG_M32R=y | ||
7 | # CONFIG_UID16 is not set | ||
8 | CONFIG_GENERIC_ISA_DMA=y | ||
9 | CONFIG_GENERIC_HARDIRQS=y | ||
10 | CONFIG_GENERIC_IRQ_PROBE=y | ||
11 | |||
12 | # | ||
13 | # Code maturity level options | ||
14 | # | ||
15 | CONFIG_EXPERIMENTAL=y | ||
16 | CONFIG_CLEAN_COMPILE=y | ||
17 | CONFIG_BROKEN_ON_SMP=y | ||
18 | CONFIG_INIT_ENV_ARG_LIMIT=32 | ||
19 | |||
20 | # | ||
21 | # General setup | ||
22 | # | ||
23 | CONFIG_LOCALVERSION="" | ||
24 | CONFIG_LOCALVERSION_AUTO=y | ||
25 | # CONFIG_POSIX_MQUEUE is not set | ||
26 | # CONFIG_BSD_PROCESS_ACCT is not set | ||
27 | CONFIG_SYSCTL=y | ||
28 | # CONFIG_AUDIT is not set | ||
29 | CONFIG_HOTPLUG=y | ||
30 | # CONFIG_KOBJECT_UEVENT is not set | ||
31 | # CONFIG_IKCONFIG is not set | ||
32 | CONFIG_INITRAMFS_SOURCE="" | ||
33 | CONFIG_EMBEDDED=y | ||
34 | # CONFIG_KALLSYMS is not set | ||
35 | CONFIG_PRINTK=y | ||
36 | CONFIG_BUG=y | ||
37 | CONFIG_BASE_FULL=y | ||
38 | # CONFIG_FUTEX is not set | ||
39 | # CONFIG_EPOLL is not set | ||
40 | # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set | ||
41 | CONFIG_CC_ALIGN_FUNCTIONS=0 | ||
42 | CONFIG_CC_ALIGN_LABELS=0 | ||
43 | CONFIG_CC_ALIGN_LOOPS=0 | ||
44 | CONFIG_CC_ALIGN_JUMPS=0 | ||
45 | CONFIG_TINY_SHMEM=y | ||
46 | CONFIG_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 | ||
63 | CONFIG_PLAT_M32104UT=y | ||
64 | # CONFIG_CHIP_M32700 is not set | ||
65 | # CONFIG_CHIP_M32102 is not set | ||
66 | CONFIG_CHIP_M32104=y | ||
67 | # CONFIG_CHIP_VDEC2 is not set | ||
68 | # CONFIG_CHIP_OPSP is not set | ||
69 | CONFIG_ISA_M32R=y | ||
70 | CONFIG_BUS_CLOCK=54000000 | ||
71 | CONFIG_TIMER_DIVIDE=128 | ||
72 | # CONFIG_CPU_LITTLE_ENDIAN is not set | ||
73 | CONFIG_MEMORY_START=04000000 | ||
74 | CONFIG_MEMORY_SIZE=01000000 | ||
75 | CONFIG_NOHIGHMEM=y | ||
76 | # CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set | ||
77 | CONFIG_SELECT_MEMORY_MODEL=y | ||
78 | CONFIG_FLATMEM_MANUAL=y | ||
79 | # CONFIG_DISCONTIGMEM_MANUAL is not set | ||
80 | # CONFIG_SPARSEMEM_MANUAL is not set | ||
81 | CONFIG_FLATMEM=y | ||
82 | CONFIG_FLAT_NODE_MEM_MAP=y | ||
83 | # CONFIG_SPARSEMEM_STATIC is not set | ||
84 | CONFIG_RWSEM_GENERIC_SPINLOCK=y | ||
85 | # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set | ||
86 | CONFIG_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 | # | ||
98 | CONFIG_PCCARD=y | ||
99 | # CONFIG_PCMCIA_DEBUG is not set | ||
100 | CONFIG_PCMCIA=y | ||
101 | CONFIG_PCMCIA_LOAD_CIS=y | ||
102 | CONFIG_PCMCIA_IOCTL=y | ||
103 | |||
104 | # | ||
105 | # PC-card bridges | ||
106 | # | ||
107 | |||
108 | # | ||
109 | # PCI Hotplug Support | ||
110 | # | ||
111 | |||
112 | # | ||
113 | # Executable file formats | ||
114 | # | ||
115 | CONFIG_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 | # | ||
123 | CONFIG_NET=y | ||
124 | |||
125 | # | ||
126 | # Networking options | ||
127 | # | ||
128 | # CONFIG_PACKET is not set | ||
129 | CONFIG_UNIX=y | ||
130 | # CONFIG_NET_KEY is not set | ||
131 | CONFIG_INET=y | ||
132 | # CONFIG_IP_MULTICAST is not set | ||
133 | # CONFIG_IP_ADVANCED_ROUTER is not set | ||
134 | CONFIG_IP_FIB_HASH=y | ||
135 | CONFIG_IP_PNP=y | ||
136 | CONFIG_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 | ||
147 | CONFIG_INET_DIAG=y | ||
148 | CONFIG_INET_TCP_DIAG=y | ||
149 | # CONFIG_TCP_CONG_ADVANCED is not set | ||
150 | CONFIG_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 | # | ||
194 | CONFIG_STANDALONE=y | ||
195 | CONFIG_PREVENT_FIRMWARE_BUILD=y | ||
196 | CONFIG_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 | ||
222 | CONFIG_BLK_DEV_LOOP=y | ||
223 | # CONFIG_BLK_DEV_CRYPTOLOOP is not set | ||
224 | CONFIG_BLK_DEV_NBD=y | ||
225 | CONFIG_BLK_DEV_RAM=y | ||
226 | CONFIG_BLK_DEV_RAM_COUNT=16 | ||
227 | CONFIG_BLK_DEV_RAM_SIZE=4096 | ||
228 | CONFIG_BLK_DEV_INITRD=y | ||
229 | # CONFIG_CDROM_PKTCDVD is not set | ||
230 | |||
231 | # | ||
232 | # IO Schedulers | ||
233 | # | ||
234 | CONFIG_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 | # | ||
272 | CONFIG_NETDEVICES=y | ||
273 | CONFIG_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 | # | ||
286 | CONFIG_NET_ETHERNET=y | ||
287 | CONFIG_MII=y | ||
288 | CONFIG_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 | # | ||
359 | CONFIG_SERIAL_CORE=y | ||
360 | CONFIG_SERIAL_CORE_CONSOLE=y | ||
361 | CONFIG_SERIAL_M32R_SIO=y | ||
362 | CONFIG_SERIAL_M32R_SIO_CONSOLE=y | ||
363 | CONFIG_UNIX98_PTYS=y | ||
364 | CONFIG_LEGACY_PTYS=y | ||
365 | CONFIG_LEGACY_PTY_COUNT=256 | ||
366 | |||
367 | # | ||
368 | # IPMI | ||
369 | # | ||
370 | # CONFIG_IPMI_HANDLER is not set | ||
371 | |||
372 | # | ||
373 | # Watchdog Cards | ||
374 | # | ||
375 | CONFIG_WATCHDOG=y | ||
376 | # CONFIG_WATCHDOG_NOWAYOUT is not set | ||
377 | |||
378 | # | ||
379 | # Watchdog Device Drivers | ||
380 | # | ||
381 | CONFIG_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 | # | ||
471 | CONFIG_EXT2_FS=y | ||
472 | # CONFIG_EXT2_FS_XATTR is not set | ||
473 | # CONFIG_EXT2_FS_XIP is not set | ||
474 | CONFIG_EXT3_FS=y | ||
475 | CONFIG_EXT3_FS_XATTR=y | ||
476 | CONFIG_EXT3_FS_POSIX_ACL=y | ||
477 | # CONFIG_EXT3_FS_SECURITY is not set | ||
478 | CONFIG_JBD=y | ||
479 | # CONFIG_JBD_DEBUG is not set | ||
480 | CONFIG_FS_MBCACHE=y | ||
481 | # CONFIG_REISERFS_FS is not set | ||
482 | # CONFIG_JFS_FS is not set | ||
483 | CONFIG_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 | ||
489 | CONFIG_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 | # | ||
503 | CONFIG_FAT_FS=y | ||
504 | CONFIG_MSDOS_FS=y | ||
505 | CONFIG_VFAT_FS=y | ||
506 | CONFIG_FAT_DEFAULT_CODEPAGE=932 | ||
507 | CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" | ||
508 | # CONFIG_NTFS_FS is not set | ||
509 | |||
510 | # | ||
511 | # Pseudo filesystems | ||
512 | # | ||
513 | CONFIG_PROC_FS=y | ||
514 | CONFIG_SYSFS=y | ||
515 | CONFIG_TMPFS=y | ||
516 | # CONFIG_HUGETLB_PAGE is not set | ||
517 | CONFIG_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 | ||
530 | CONFIG_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 | # | ||
540 | CONFIG_NFS_FS=y | ||
541 | CONFIG_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 | ||
546 | CONFIG_ROOT_NFS=y | ||
547 | CONFIG_LOCKD=y | ||
548 | CONFIG_LOCKD_V4=y | ||
549 | CONFIG_NFS_COMMON=y | ||
550 | CONFIG_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 | ||
564 | CONFIG_MSDOS_PARTITION=y | ||
565 | |||
566 | # | ||
567 | # Native Language Support | ||
568 | # | ||
569 | CONFIG_NLS=y | ||
570 | CONFIG_NLS_DEFAULT="iso8859-1" | ||
571 | CONFIG_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 | ||
588 | CONFIG_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 | ||
608 | CONFIG_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 | ||
619 | CONFIG_DEBUG_KERNEL=y | ||
620 | CONFIG_MAGIC_SYSRQ=y | ||
621 | CONFIG_LOG_BUF_SHIFT=14 | ||
622 | CONFIG_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 | ||
629 | CONFIG_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 | ||
655 | CONFIG_CRC32=y | ||
656 | CONFIG_LIBCRC32C=y | ||
657 | CONFIG_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 @@ | |||
37 | void _flush_cache_all(void) | 48 | void _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 */ |
52 | void _flush_cache_copyback_all(void) | 70 | void _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 | ||
39 | EXPORT_SYMBOL(ip_fast_csum); | 39 | EXPORT_SYMBOL(ip_fast_csum); |
40 | 40 | ||
41 | EXPORT_SYMBOL(mach_enable_irq); | ||
42 | EXPORT_SYMBOL(mach_disable_irq); | ||
43 | EXPORT_SYMBOL(kernel_thread); | 41 | EXPORT_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 */ |
66 | void (*mach_init_IRQ) (void) = NULL; | 66 | void (*mach_init_IRQ) (void) = NULL; |
67 | irqreturn_t (*(*mach_default_handler)[]) (int, void *, struct pt_regs *) = NULL; | 67 | irqreturn_t (*(*mach_default_handler)[]) (int, void *, struct pt_regs *) = NULL; |
68 | void (*mach_enable_irq) (unsigned int) = NULL; | ||
69 | void (*mach_disable_irq) (unsigned int) = NULL; | ||
70 | int (*mach_get_irq_list) (struct seq_file *, void *) = NULL; | 68 | int (*mach_get_irq_list) (struct seq_file *, void *) = NULL; |
71 | void (*mach_process_int) (int irq, struct pt_regs *fp) = NULL; | 69 | void (*mach_process_int) (int irq, struct pt_regs *fp) = NULL; |
72 | void (*mach_trap_init) (void); | 70 | void (*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 | |||
190 | boot-$(CONFIG_REDWOOD_6) += embed_config.o | 190 | boot-$(CONFIG_REDWOOD_6) += embed_config.o |
191 | boot-$(CONFIG_8xx) += embed_config.o | 191 | boot-$(CONFIG_8xx) += embed_config.o |
192 | boot-$(CONFIG_8260) += embed_config.o | 192 | boot-$(CONFIG_8260) += embed_config.o |
193 | boot-$(CONFIG_EP405) += embed_config.o | ||
194 | boot-$(CONFIG_XILINX_ML300) += embed_config.o | ||
193 | boot-$(CONFIG_BSEIP) += iic.o | 195 | boot-$(CONFIG_BSEIP) += iic.o |
194 | boot-$(CONFIG_MBX) += iic.o pci.o qspan_pci.o | 196 | boot-$(CONFIG_MBX) += iic.o pci.o qspan_pci.o |
195 | boot-$(CONFIG_MV64X60) += misc-mv64x60.o | 197 | boot-$(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 @@ | |||
37 | void default_idle(void) | 37 | void 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 | ||
64 | static struct ocp_func_emac_data ibm440gx_emac3_def = { | 63 | static 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 | }; |
77 | OCP_SYSFS_EMAC_DATA() | 75 | OCP_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 | }; |
36 | OCP_SYSFS_EMAC_DATA() | 35 | OCP_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 | |||
20 | static 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 | */ | ||
31 | struct 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 | |||
27 | static int | 33 | static int |
28 | mpc52xx_pci_read_config(struct pci_bus *bus, unsigned int devfn, | 34 | mpc52xx_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 = { | |||
99 | static void __init | 154 | static void __init |
100 | mpc52xx_pci_setup(struct mpc52xx_pci __iomem *pci_regs) | 155 | mpc52xx_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 | ||
154 | static void __init | 211 | static void |
155 | mpc52xx_pci_fixup_resources(struct pci_dev *dev) | 212 | mpc52xx_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) | |||
84 | void __init | 84 | void __init |
85 | mpc52xx_map_io(void) | 85 | mpc52xx_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 | ||
24 | mainmenu "Linux Kernel Configuration" | 24 | mainmenu "Linux Kernel Configuration" |
25 | 25 | ||
26 | config ARCH_S390 | 26 | config S390 |
27 | bool | 27 | bool |
28 | default y | 28 | default y |
29 | 29 | ||
30 | config UID16 | 30 | config UID16 |
31 | bool | 31 | bool |
32 | default y | 32 | default y |
33 | depends on ARCH_S390X = 'n' | 33 | depends on !64BIT |
34 | 34 | ||
35 | source "init/Kconfig" | 35 | source "init/Kconfig" |
36 | 36 | ||
@@ -38,20 +38,12 @@ menu "Base setup" | |||
38 | 38 | ||
39 | comment "Processor type and features" | 39 | comment "Processor type and features" |
40 | 40 | ||
41 | config ARCH_S390X | 41 | config 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 | ||
47 | config 64BIT | ||
48 | def_bool ARCH_S390X | ||
49 | |||
50 | config ARCH_S390_31 | ||
51 | bool | ||
52 | depends on ARCH_S390X = 'n' | ||
53 | default y | ||
54 | |||
55 | config SMP | 47 | config 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 | ||
104 | config S390_SUPPORT | 96 | config 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 | ||
113 | config COMPAT | ||
114 | bool | ||
115 | depends on S390_SUPPORT | ||
116 | default y | ||
117 | |||
118 | config SYSVIPC_COMPAT | 105 | config 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 | ||
123 | config BINFMT_ELF32 | 110 | config 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 | ||
136 | config MARCH_G5 | 123 | config 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 | |||
240 | config QDIO | 227 | config 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 | ||
16 | ifdef CONFIG_ARCH_S390_31 | 16 | ifndef CONFIG_64BIT |
17 | LDFLAGS := -m elf_s390 | 17 | LDFLAGS := -m elf_s390 |
18 | CFLAGS += -m31 | 18 | CFLAGS += -m31 |
19 | AFLAGS += -m31 | 19 | AFLAGS += -m31 |
20 | UTS_MACHINE := s390 | 20 | UTS_MACHINE := s390 |
21 | STACK_SIZE := 8192 | 21 | STACK_SIZE := 8192 |
22 | CHECKFLAGS += -D__s390__ | 22 | CHECKFLAGS += -D__s390__ |
23 | endif | 23 | else |
24 | |||
25 | ifdef CONFIG_ARCH_S390X | ||
26 | LDFLAGS := -m elf64_s390 | 24 | LDFLAGS := -m elf64_s390 |
27 | MODFLAGS += -fpic -D__PIC__ | 25 | MODFLAGS += -fpic -D__PIC__ |
28 | CFLAGS += -m64 | 26 | CFLAGS += -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 |
64 | struct appldata_parameter_list { | 64 | struct 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 | ||
5 | obj-$(CONFIG_CRYPTO_SHA1_Z990) += sha1_z990.o | 5 | obj-$(CONFIG_CRYPTO_SHA1_S390) += sha1_s390.o |
6 | obj-$(CONFIG_CRYPTO_DES_Z990) += des_z990.o des_check_key.o | 6 | obj-$(CONFIG_CRYPTO_SHA256_S390) += sha256_s390.o |
7 | obj-$(CONFIG_CRYPTO_DES_S390) += des_s390.o des_check_key.o | ||
8 | obj-$(CONFIG_CRYPTO_AES_S390) += aes_s390.o | ||
7 | 9 | ||
8 | obj-$(CONFIG_CRYPTO_TEST) += crypt_z990_query.o | 10 | obj-$(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 | |||
30 | int has_aes_128 = 0; | ||
31 | int has_aes_192 = 0; | ||
32 | int has_aes_256 = 0; | ||
33 | |||
34 | struct s390_aes_ctx { | ||
35 | u8 iv[AES_BLOCK_SIZE]; | ||
36 | u8 key[AES_MAX_KEY_SIZE]; | ||
37 | int key_len; | ||
38 | }; | ||
39 | |||
40 | static 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; | ||
68 | fail: | ||
69 | *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN; | ||
70 | return -EINVAL; | ||
71 | } | ||
72 | |||
73 | static 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 | |||
93 | static 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 | |||
113 | static 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 | |||
132 | static 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 | |||
151 | static 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 | |||
173 | static 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 | |||
194 | static 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 | |||
216 | static 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 | |||
236 | static void __exit aes_fini(void) | ||
237 | { | ||
238 | crypto_unregister_alg(&aes_alg); | ||
239 | } | ||
240 | |||
241 | module_init(aes_init); | ||
242 | module_exit(aes_fini); | ||
243 | |||
244 | MODULE_ALIAS("aes"); | ||
245 | |||
246 | MODULE_DESCRIPTION("Rijndael (AES) Cipher Algorithm"); | ||
247 | MODULE_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*/ | 24 | enum crypt_s390_operations { |
25 | enum 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 |
34 | enum 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, | 35 | enum 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) |
45 | enum crypt_z990_kmc_func { | 52 | * instruction |
46 | KMC_QUERY = CRYPT_Z990_KMC | 0, | 53 | */ |
47 | KMC_DEA_ENCRYPT = CRYPT_Z990_KMC | 1, | 54 | enum 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) |
56 | enum crypt_z990_kimd_func { | 71 | * instruction |
57 | KIMD_QUERY = CRYPT_Z990_KIMD | 0, | 72 | */ |
58 | KIMD_SHA_1 = CRYPT_Z990_KIMD | 1, | 73 | enum 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) |
62 | enum crypt_z990_klmd_func { | 80 | * instruction |
63 | KLMD_QUERY = CRYPT_Z990_KLMD | 0, | 81 | */ |
64 | KLMD_SHA_1 = CRYPT_Z990_KLMD | 1, | 82 | enum 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) |
68 | enum crypt_z990_kmac_func { | 89 | * instruction |
69 | KMAC_QUERY = CRYPT_Z990_KMAC | 0, | 90 | */ |
70 | KMAC_DEA = CRYPT_Z990_KMAC | 1, | 91 | enum 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 */ |
76 | struct crypt_z990_query_status { | 99 | struct 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 | */ |
147 | static inline int | 171 | static inline int |
148 | crypt_z990_km(long func, void* param, u8* dest, const u8* src, long src_len) | 172 | crypt_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 | */ |
186 | static inline int | 210 | static inline int |
187 | crypt_z990_kmc(long func, void* param, u8* dest, const u8* src, long src_len) | 211 | crypt_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 | */ |
225 | static inline int | 249 | static inline int |
226 | crypt_z990_kimd(long func, void* param, const u8* src, long src_len) | 250 | crypt_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 | */ |
261 | static inline int | 285 | static inline int |
262 | crypt_z990_klmd(long func, void* param, const u8* src, long src_len) | 286 | crypt_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 | */ |
298 | static inline int | 322 | static inline int |
299 | crypt_z990_kmac(long func, void* param, const u8* src, long src_len) | 323 | crypt_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 | */ |
330 | static inline int | 354 | static inline int |
331 | crypt_z990_func_available(int func) | 355 | crypt_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 | |||
22 | static 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 | |||
85 | static 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 | |||
122 | static void __exit cleanup(void) | ||
123 | { | ||
124 | } | ||
125 | |||
126 | module_init(init); | ||
127 | module_exit(cleanup); | ||
128 | |||
129 | MODULE_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 | |||
22 | static void | ||
23 | query_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 | |||
65 | static int | ||
66 | init(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 | |||
103 | static void __exit | ||
104 | cleanup(void) | ||
105 | { | ||
106 | } | ||
107 | |||
108 | module_init(init); | ||
109 | module_exit(cleanup); | ||
110 | |||
111 | MODULE_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 | ||
34 | struct crypt_z990_des_ctx { | 34 | struct 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 | ||
39 | struct crypt_z990_des3_128_ctx { | 39 | struct 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 | ||
44 | struct crypt_z990_des3_192_ctx { | 44 | struct 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 { | |||
49 | static int | 49 | static int |
50 | des_setkey(void *ctx, const u8 *key, unsigned int keylen, u32 *flags) | 50 | des_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) | |||
65 | static void | 65 | static void |
66 | des_encrypt(void *ctx, u8 *dst, const u8 *src) | 66 | des_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 | ||
74 | static void | 74 | static void |
75 | des_decrypt(void *ctx, u8 *dst, const u8 *src) | 75 | des_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 | ||
83 | static struct crypto_alg des_alg = { | 83 | static 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 | |||
111 | des3_128_setkey(void *ctx, const u8 *key, unsigned int keylen, u32 *flags) | 111 | des3_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) | |||
132 | static void | 132 | static void |
133 | des3_128_encrypt(void *ctx, u8 *dst, const u8 *src) | 133 | des3_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 | ||
142 | static void | 142 | static void |
143 | des3_128_decrypt(void *ctx, u8 *dst, const u8 *src) | 143 | des3_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 | |||
181 | des3_192_setkey(void *ctx, const u8 *key, unsigned int keylen, u32 *flags) | 181 | des3_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) | |||
206 | static void | 206 | static void |
207 | des3_192_encrypt(void *ctx, u8 *dst, const u8 *src) | 207 | des3_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 | ||
216 | static void | 216 | static void |
217 | des3_192_decrypt(void *ctx, u8 *dst, const u8 *src) | 217 | des3_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 | ||
36 | struct crypt_z990_sha1_ctx { | 36 | struct 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 | ||
43 | static void | 43 | static void |
44 | sha1_init(void *ctx) | 44 | sha1_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) | |||
58 | static void | 58 | static void |
59 | sha1_update(void *ctx, const u8 *data, unsigned int len) | 59 | sha1_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 | ||
94 | static void | 94 | static void |
95 | pad_message(struct crypt_z990_sha1_ctx* sctx) | 95 | pad_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) | |||
113 | static void | 113 | static void |
114 | sha1_final(void* ctx, u8 *out) | 114 | sha1_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 | |||
28 | struct s390_sha256_ctx { | ||
29 | u64 count; | ||
30 | u32 state[8]; | ||
31 | u8 buf[2 * SHA256_BLOCK_SIZE]; | ||
32 | }; | ||
33 | |||
34 | static 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 | |||
50 | static 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 | |||
75 | static 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 */ | ||
96 | static 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 | |||
113 | static 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 | |||
127 | static 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 | |||
140 | static void __exit fini(void) | ||
141 | { | ||
142 | crypto_unregister_alg(&alg); | ||
143 | } | ||
144 | |||
145 | module_init(init); | ||
146 | module_exit(fini); | ||
147 | |||
148 | MODULE_ALIAS("sha256"); | ||
149 | |||
150 | MODULE_LICENSE("GPL"); | ||
151 | MODULE_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 | # |
6 | CONFIG_MMU=y | 6 | CONFIG_MMU=y |
7 | CONFIG_RWSEM_XCHGADD_ALGORITHM=y | 7 | CONFIG_RWSEM_XCHGADD_ALGORITHM=y |
8 | CONFIG_GENERIC_CALIBRATE_DELAY=y | 8 | CONFIG_GENERIC_CALIBRATE_DELAY=y |
9 | CONFIG_ARCH_S390=y | 9 | CONFIG_S390=y |
10 | CONFIG_UID16=y | 10 | CONFIG_UID16=y |
11 | 11 | ||
12 | # | 12 | # |
@@ -65,15 +65,31 @@ CONFIG_KMOD=y | |||
65 | CONFIG_STOP_MACHINE=y | 65 | CONFIG_STOP_MACHINE=y |
66 | 66 | ||
67 | # | 67 | # |
68 | # Block layer | ||
69 | # | ||
70 | # CONFIG_LBD is not set | ||
71 | |||
72 | # | ||
73 | # IO Schedulers | ||
74 | # | ||
75 | CONFIG_IOSCHED_NOOP=y | ||
76 | CONFIG_IOSCHED_AS=y | ||
77 | CONFIG_IOSCHED_DEADLINE=y | ||
78 | CONFIG_IOSCHED_CFQ=y | ||
79 | CONFIG_DEFAULT_AS=y | ||
80 | # CONFIG_DEFAULT_DEADLINE is not set | ||
81 | # CONFIG_DEFAULT_CFQ is not set | ||
82 | # CONFIG_DEFAULT_NOOP is not set | ||
83 | CONFIG_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 |
76 | CONFIG_ARCH_S390_31=y | ||
77 | CONFIG_SMP=y | 93 | CONFIG_SMP=y |
78 | CONFIG_NR_CPUS=32 | 94 | CONFIG_NR_CPUS=32 |
79 | CONFIG_HOTPLUG_CPU=y | 95 | CONFIG_HOTPLUG_CPU=y |
@@ -97,6 +113,7 @@ CONFIG_FLATMEM_MANUAL=y | |||
97 | CONFIG_FLATMEM=y | 113 | CONFIG_FLATMEM=y |
98 | CONFIG_FLAT_NODE_MEM_MAP=y | 114 | CONFIG_FLAT_NODE_MEM_MAP=y |
99 | # CONFIG_SPARSEMEM_STATIC is not set | 115 | # CONFIG_SPARSEMEM_STATIC is not set |
116 | CONFIG_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 | # | ||
191 | CONFIG_NET_SCHED=y | 212 | CONFIG_NET_SCHED=y |
192 | CONFIG_NET_SCH_CLK_JIFFIES=y | 213 | CONFIG_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 | # | ||
195 | CONFIG_NET_SCH_CBQ=m | 220 | CONFIG_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 | |||
204 | CONFIG_NET_SCH_DSMARK=m | 229 | CONFIG_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 |
207 | CONFIG_NET_QOS=y | 232 | |
208 | CONFIG_NET_ESTIMATOR=y | 233 | # |
234 | # Classification | ||
235 | # | ||
209 | CONFIG_NET_CLS=y | 236 | CONFIG_NET_CLS=y |
210 | # CONFIG_NET_CLS_BASIC is not set | 237 | # CONFIG_NET_CLS_BASIC is not set |
211 | CONFIG_NET_CLS_TCINDEX=m | 238 | CONFIG_NET_CLS_TCINDEX=m |
@@ -214,18 +241,18 @@ CONFIG_NET_CLS_ROUTE=y | |||
214 | CONFIG_NET_CLS_FW=m | 241 | CONFIG_NET_CLS_FW=m |
215 | CONFIG_NET_CLS_U32=m | 242 | CONFIG_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 | ||
218 | CONFIG_NET_CLS_RSVP=m | 244 | CONFIG_NET_CLS_RSVP=m |
219 | CONFIG_NET_CLS_RSVP6=m | 245 | CONFIG_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 |
222 | CONFIG_NET_CLS_POLICE=y | 248 | CONFIG_NET_CLS_POLICE=y |
249 | # CONFIG_NET_CLS_IND is not set | ||
250 | CONFIG_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 |
281 | CONFIG_ZFCP=y | 309 | CONFIG_ZFCP=y |
@@ -292,7 +320,6 @@ CONFIG_BLK_DEV_RAM=y | |||
292 | CONFIG_BLK_DEV_RAM_COUNT=16 | 320 | CONFIG_BLK_DEV_RAM_COUNT=16 |
293 | CONFIG_BLK_DEV_RAM_SIZE=4096 | 321 | CONFIG_BLK_DEV_RAM_SIZE=4096 |
294 | CONFIG_BLK_DEV_INITRD=y | 322 | CONFIG_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 | |||
305 | CONFIG_DASD_ECKD=y | 332 | CONFIG_DASD_ECKD=y |
306 | CONFIG_DASD_FBA=y | 333 | CONFIG_DASD_FBA=y |
307 | CONFIG_DASD_DIAG=y | 334 | CONFIG_DASD_DIAG=y |
335 | CONFIG_DASD_EER=m | ||
308 | # CONFIG_DASD_CMB is not set | 336 | # CONFIG_DASD_CMB is not set |
309 | |||
310 | # | ||
311 | # IO Schedulers | ||
312 | # | ||
313 | CONFIG_IOSCHED_NOOP=y | ||
314 | CONFIG_IOSCHED_AS=y | ||
315 | CONFIG_IOSCHED_DEADLINE=y | ||
316 | CONFIG_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 |
595 | CONFIG_DEBUG_FS=y | 614 | CONFIG_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 | ||
11 | obj-y += $(if $(CONFIG_64BIT),entry64.o,entry.o) | ||
12 | obj-y += $(if $(CONFIG_64BIT),reipl64.o,reipl.o) | ||
13 | |||
11 | extra-y += head.o init_task.o vmlinux.lds | 14 | extra-y += head.o init_task.o vmlinux.lds |
12 | 15 | ||
13 | obj-$(CONFIG_MODULES) += s390_ksyms.o module.o | 16 | obj-$(CONFIG_MODULES) += s390_ksyms.o module.o |
14 | obj-$(CONFIG_SMP) += smp.o | 17 | obj-$(CONFIG_SMP) += smp.o |
15 | 18 | ||
16 | obj-$(CONFIG_S390_SUPPORT) += compat_linux.o compat_signal.o \ | 19 | obj-$(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 |
19 | obj-$(CONFIG_BINFMT_ELF32) += binfmt_elf32.o | 22 | obj-$(CONFIG_BINFMT_ELF32) += binfmt_elf32.o |
20 | 23 | ||
21 | obj-$(CONFIG_ARCH_S390_31) += entry.o reipl.o | ||
22 | obj-$(CONFIG_ARCH_S390X) += entry64.o reipl64.o | ||
23 | |||
24 | obj-$(CONFIG_VIRT_TIMER) += vtime.o | 24 | obj-$(CONFIG_VIRT_TIMER) += vtime.o |
25 | 25 | ||
26 | # Kexec part | 26 | # Kexec part |
27 | S390_KEXEC_OBJS := machine_kexec.o crash.o | 27 | S390_KEXEC_OBJS := machine_kexec.o crash.o |
28 | ifeq ($(CONFIG_ARCH_S390X),y) | 28 | S390_KEXEC_OBJS += $(if $(CONFIG_64BIT),relocate_kernel64.o,relocate_kernel.o) |
29 | S390_KEXEC_OBJS += relocate_kernel64.o | ||
30 | else | ||
31 | S390_KEXEC_OBJS += relocate_kernel.o | ||
32 | endif | ||
33 | obj-$(CONFIG_KEXEC) += $(S390_KEXEC_OBJS) | 29 | obj-$(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 | ||
280 | static inline long get_tv32(struct timeval *o, struct compat_timeval *i) | 280 | static 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 | ||
106 | EXPORT_SYMBOL(__cpcmd); | 106 | EXPORT_SYMBOL(__cpcmd); |
107 | 107 | ||
108 | #ifdef CONFIG_ARCH_S390X | 108 | #ifdef CONFIG_64BIT |
109 | int cpcmd(const char *cmd, char *response, int rlen, int *response_code) | 109 | int 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 | ||
131 | EXPORT_SYMBOL(cpcmd); | 131 | EXPORT_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) |
214 | sysc_do_restart: | 214 | sysc_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 |
365 | sys32_clone_glue: | 365 | sys32_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 |
387 | sys32_execve_glue: | 387 | sys32_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 |
402 | sys32_sigreturn_glue: | 402 | sys32_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 |
412 | sys32_rt_sigreturn_glue: | 412 | sys32_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 |
433 | sys32_sigsuspend_glue: | 433 | sys32_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 |
453 | sys32_rt_sigsuspend_glue: | 453 | sys32_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 |
468 | sys32_sigaltstack_glue: | 468 | sys32_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 | ||
46 | void *module_alloc(unsigned long size) | 46 | void *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 | */ |
340 | int dump_fpu (struct pt_regs * regs, s390_fp_regs *fpregs) | 340 | int 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(¤t->thread.fp_regs); | 347 | save_fp_regs(¤t->thread.fp_regs); |
348 | memcpy(fpregs, ¤t->thread.fp_regs, sizeof(s390_fp_regs)); | 348 | memcpy(fpregs, ¤t->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 | ||
262 | badframe: | 262 | badframe: |
@@ -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 | } |
418 | EXPORT_SYMBOL(smp_ptlb_all); | 418 | EXPORT_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 |
125 | struct sel_arg_struct { | 123 | struct 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 |
215 | asmlinkage long s390x_newuname(struct new_utsname __user *name) | 213 | asmlinkage 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 | ||
245 | asmlinkage long | 243 | asmlinkage long |
246 | s390_fadvise64(int fd, u32 offset_high, u32 offset_low, size_t len, int advice) | 244 | s390_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" |
72 | static int kstack_depth_to_print = 12; | 72 | static 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" |
75 | static int kstack_depth_to_print = 20; | 75 | static 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 |
9 | OUTPUT_FORMAT("elf32-s390", "elf32-s390", "elf32-s390") | 9 | OUTPUT_FORMAT("elf32-s390", "elf32-s390", "elf32-s390") |
10 | OUTPUT_ARCH(s390) | 10 | OUTPUT_ARCH(s390) |
11 | ENTRY(_start) | 11 | ENTRY(_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 | ||
5 | EXTRA_AFLAGS := -traditional | 5 | EXTRA_AFLAGS := -traditional |
6 | 6 | ||
7 | lib-y += delay.o string.o | 7 | lib-y += delay.o string.o spinlock.o |
8 | lib-$(CONFIG_ARCH_S390_31) += uaccess.o spinlock.o | 8 | lib-y += $(if $(CONFIG_64BIT),uaccess64.o,uaccess.o) |
9 | lib-$(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); | |||
29 | static inline void | 29 | static 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 |
47 | extern int sysctl_userprocess_debug; | 47 | extern 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 |
110 | void __init paging_init(void) | 110 | void __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 */ |
179 | void __init paging_init(void) | 179 | void __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 | ||
261 | void __init mem_init(void) | 261 | void __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 | ||
51 | static inline int mmap_is_legacy(void) | 51 | static 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 | ||
9 | oprofile-y := $(DRIVER_OBJS) init.o | 9 | oprofile-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 | |||
13 | static 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 | |||
58 | void 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 | |||
16 | extern void s390_backtrace(struct pt_regs * const regs, unsigned int depth); | ||
17 | |||
15 | int __init oprofile_arch_init(struct oprofile_operations* ops) | 18 | int __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 | ||
64 | static int not_configged_open(int input, int output, int primary, void *data, | 64 | static 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 | ||
72 | static void not_configged_close(int fd, void *data) | 72 | static 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 | ||
85 | static int not_configged_write(int fd, const char *buf, int len, void *data) | 85 | static 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 | ||
92 | static int not_configged_console_write(int fd, const char *buf, int len) | 92 | static 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 | ||
99 | static int not_configged_window_size(int fd, void *data, unsigned short *rows, | 99 | static 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 | ||
107 | static void not_configged_free(void *data) | 107 | static 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 | ||
146 | int generic_write(int fd, const char *buf, int n, void *unused) | 146 | int 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 | ||
151 | int generic_window_size(int fd, void *unused, unsigned short *rows_out, | 151 | int 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 | ||
169 | void generic_free(void *data) | 169 | void 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 | ||
195 | static int open_one_chan(struct chan *chan, int input, int output, int primary) | 195 | static 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 | ||
210 | int open_chan(struct list_head *chans) | 214 | int 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 | ||
225 | void chan_enable_winch(struct list_head *chans, struct tty_struct *tty) | 229 | void 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 | ||
239 | void enable_chan(struct list_head *chans, struct tty_struct *tty) | 243 | void 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 | |||
261 | static LIST_HEAD(irqs_to_free); | ||
262 | |||
263 | void 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 | |||
279 | static 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 | ||
252 | void close_chan(struct list_head *chans) | 301 | void 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; | 315 | void 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 | |||
328 | void 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 | ||
270 | int write_chan(struct list_head *chans, const char *buf, int len, | 341 | int 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 | ||
291 | int console_write_chan(struct list_head *chans, const char *buf, int len) | 362 | int 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 | ||
307 | int console_open_chan(struct line *line, struct console *co, struct chan_opts *opts) | 378 | int 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 | ||
338 | void free_one_chan(struct chan *chan) | 409 | void 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 | ||
348 | void free_chan(struct list_head *chans) | 422 | void 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 | ||
382 | static int chan_pair_config_string(struct chan *in, struct chan *out, | 456 | static 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 | ||
405 | int chan_config_string(struct list_head *chans, char *str, int size, | 479 | int 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 | ||
424 | struct chan_type { | 498 | struct chan_type { |
@@ -462,7 +536,7 @@ struct chan_type chan_table[] = { | |||
462 | #endif | 536 | #endif |
463 | }; | 537 | }; |
464 | 538 | ||
465 | static struct chan *parse_chan(char *str, int pri, int device, | 539 | static 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 | ||
507 | int parse_chan_pair(char *str, struct list_head *chans, int pri, int device, | 587 | int 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 | ||
545 | int chan_out_fd(struct list_head *chans) | 631 | int 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 | ||
558 | void chan_interrupt(struct list_head *chans, struct work_struct *task, | 644 | void 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 | ||
24 | static irqreturn_t line_interrupt(int irq, void *data, struct pt_regs *unused) | 24 | static 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 | ||
34 | static void line_timer_cb(void *arg) | 35 | static 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 | ||
344 | void 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 | |||
352 | void 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 | |||
341 | static irqreturn_t line_write_interrupt(int irq, void *data, | 368 | static 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 | ||
379 | int line_setup_irq(int fd, int input, int output, struct tty_struct *tty) | 407 | int 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 | ||
399 | void line_disable(struct tty_struct *tty, int current_irq) | 426 | int 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 | |||
421 | int 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; | ||
458 | out: | 460 | out: |
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 | ||
506 | int line_setup(struct line *lines, unsigned int num, char *init, int all_allowed) | 505 | int 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 | ||
563 | int line_config(struct line *lines, unsigned int num, char *str) | 561 | int 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 | ||
574 | int line_get_config(char *name, struct line *lines, unsigned int num, char *str, | 587 | int 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 | ||
620 | int line_remove(struct line *lines, unsigned int num, int n) | 633 | int 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 | ||
628 | struct tty_driver *line_register_devfs(struct lines *set, | 645 | struct 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 | ||
666 | static spinlock_t winch_handler_lock; | 683 | static DEFINE_SPINLOCK(winch_handler_lock); |
667 | LIST_HEAD(winch_handlers); | 684 | static LIST_HEAD(winch_handlers); |
668 | 685 | ||
669 | void lines_init(struct line *lines, int nlines) | 686 | void 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 | ||
777 | static 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 | |||
757 | static void unregister_winch(struct tty_struct *tty) | 790 | static 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; | ||
783 | err: | ||
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? */ | ||
789 | static void winch_cleanup(void) | 807 | static 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 | ||
37 | static int do_unlink_socket(struct notifier_block *notifier, | 38 | static 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 | ||
54 | LIST_HEAD(mc_requests); | 55 | static LIST_HEAD(mc_requests); |
55 | 56 | ||
56 | static void mc_work_proc(void *unused) | 57 | static 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 | ||
72 | DECLARE_WORK(mconsole_work, mc_work_proc, NULL); | 73 | static DECLARE_WORK(mconsole_work, mc_work_proc, NULL); |
73 | 74 | ||
74 | static irqreturn_t mconsole_interrupt(int irq, void *dev_id, | 75 | static 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 | ||
351 | static void mconsole_get_config(int (*get_config)(char *, char *, int, | 352 | static 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 | ||
395 | void mconsole_config(struct mc_request *req) | 395 | void mconsole_config(struct mc_request *req) |
@@ -420,9 +420,9 @@ void mconsole_config(struct mc_request *req) | |||
420 | 420 | ||
421 | void mconsole_remove(struct mc_request *req) | 421 | void 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: | 462 | out: |
463 | mconsole_reply(req, err_msg, err, 0); | 463 | mconsole_reply(req, err_msg, err, 0); |
464 | } | 464 | } |
465 | 465 | ||
466 | static DEFINE_SPINLOCK(console_lock); | ||
467 | static LIST_HEAD(clients); | ||
468 | static char console_buf[MCONSOLE_MAX_DATA]; | ||
469 | static int console_index = 0; | ||
470 | |||
471 | static 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 | |||
501 | static struct console mc_console = { .name = "mc", | ||
502 | .write = console_write, | ||
503 | .flags = CON_PRINTBUFFER | CON_ENABLED, | ||
504 | .index = -1 }; | ||
505 | |||
506 | static int mc_add_console(void) | ||
507 | { | ||
508 | register_console(&mc_console); | ||
509 | return 0; | ||
510 | } | ||
511 | |||
512 | late_initcall(mc_add_console); | ||
513 | |||
514 | static 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 |
535 | static void sysrq_proc(void *arg) | ||
536 | { | ||
537 | char *op = arg; | ||
538 | |||
539 | handle_sysrq(*op, ¤t->thread.regs, NULL); | ||
540 | } | ||
541 | |||
467 | void mconsole_sysrq(struct mc_request *req) | 542 | void 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, ¤t->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 |
478 | void mconsole_sysrq(struct mc_request *req) | 558 | void 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 | ||
564 | static 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 | */ |
489 | void do_stack(struct mc_request *req) | 577 | void 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 | ||
524 | void mconsole_stack(struct mc_request *req) | 609 | void 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 | */ |
537 | static char *notify_socket = NULL; | 622 | static char *notify_socket = NULL; |
538 | 623 | ||
539 | int mconsole_init(void) | 624 | static 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 | ||
688 | EXPORT_SYMBOL(mconsole_notify_socket); | 773 | EXPORT_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 | ||
125 | int mconsole_reply(struct mc_request *req, char *str, int err, int more) | 125 | int 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 | ||
158 | int 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 | |||
158 | int mconsole_unlink_socket(void) | 164 | int 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 | ||
36 | static DEFINE_SPINLOCK(opened_lock); | 36 | static DEFINE_SPINLOCK(opened_lock); |
37 | LIST_HEAD(opened); | 37 | static LIST_HEAD(opened); |
38 | 38 | ||
39 | static int uml_net_rx(struct net_device *dev) | 39 | static 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 | ||
268 | static DEFINE_SPINLOCK(devices_lock); | 269 | static DEFINE_SPINLOCK(devices_lock); |
269 | static struct list_head devices = LIST_HEAD_INIT(devices); | 270 | static LIST_HEAD(devices); |
270 | 271 | ||
271 | static struct platform_driver uml_net_driver = { | 272 | static 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 | ||
85 | static int ssl_config(char *str) | 85 | static 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 | ||
91 | static int ssl_get_config(char *dev, char *str, int size, char **error_out) | 90 | static 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 | ||
98 | static int ssl_remove(int n) | 96 | static 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 | ||
104 | int ssl_open(struct tty_struct *tty, struct file *filp) | 101 | int 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 | ||
115 | static void ssl_throttle(struct tty_struct * tty) | ||
116 | { | ||
117 | printk(KERN_ERR "Someone should implement ssl_throttle\n"); | ||
118 | } | ||
119 | |||
120 | static void ssl_unthrottle(struct tty_struct * tty) | ||
121 | { | ||
122 | printk(KERN_ERR "Someone should implement ssl_unthrottle\n"); | ||
123 | } | ||
124 | |||
125 | static void ssl_stop(struct tty_struct *tty) | 112 | static 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 | ||
189 | static struct console ssl_cons = { | 176 | static 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 | } |
217 | late_initcall(ssl_init); | 205 | late_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 | ||
228 | static int ssl_chan_setup(char *str) | 215 | static 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 | */ |
88 | struct line vts[MAX_TTYS] = { LINE_INIT(CONFIG_CON_ZERO_CHAN, &driver), | 88 | struct 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 | ||
92 | static int con_config(char *str) | 92 | static 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 | ||
97 | static int con_get_config(char *dev, char *str, int size, char **error_out) | 97 | static 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 | ||
103 | static int con_remove(int n) | 102 | static 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 | ||
108 | static int con_open(struct tty_struct *tty, struct file *filp) | 107 | static 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 | ||
113 | static int con_init_done = 0; | 112 | static 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 | ||
128 | static void uml_console_write(struct console *console, const char *string, | 129 | static 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 | ||
152 | static struct console stdiocons = { | 153 | static 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 | ||
162 | int stdio_init(void) | 163 | int 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 | } |
183 | late_initcall(stdio_init); | 184 | late_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 | ||
193 | static int console_chan_setup(char *str) | 194 | static 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 | ||
15 | struct chan { | 15 | struct 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 | ||
28 | extern void chan_interrupt(struct list_head *chans, struct work_struct *task, | 30 | extern 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); |
30 | extern int parse_chan_pair(char *str, struct list_head *chans, int pri, | 32 | extern int parse_chan_pair(char *str, struct line *line, int device, |
31 | int device, struct chan_opts *opts); | 33 | struct chan_opts *opts); |
32 | extern int open_chan(struct list_head *chans); | 34 | extern int open_chan(struct list_head *chans); |
33 | extern int write_chan(struct list_head *chans, const char *buf, int len, | 35 | extern 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); |
37 | extern int console_open_chan(struct line *line, struct console *co, | 39 | extern int console_open_chan(struct line *line, struct console *co, |
38 | struct chan_opts *opts); | 40 | struct chan_opts *opts); |
39 | extern void close_chan(struct list_head *chans); | 41 | extern void deactivate_chan(struct list_head *chans, int irq); |
42 | extern void reactivate_chan(struct list_head *chans, int irq); | ||
40 | extern void chan_enable_winch(struct list_head *chans, struct tty_struct *tty); | 43 | extern void chan_enable_winch(struct list_head *chans, struct tty_struct *tty); |
41 | extern void enable_chan(struct list_head *chans, struct tty_struct *tty); | 44 | extern void enable_chan(struct line *line); |
45 | extern void close_chan(struct list_head *chans, int delay_free_irq); | ||
42 | extern int chan_window_size(struct list_head *chans, | 46 | extern 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); | |||
18 | extern void forward_interrupts(int pid); | 18 | extern void forward_interrupts(int pid); |
19 | extern void init_irq_signals(int on_sigstack); | 19 | extern void init_irq_signals(int on_sigstack); |
20 | extern void forward_ipi(int fd, int pid); | 20 | extern void forward_ipi(int fd, int pid); |
21 | extern void free_irq_later(int irq, void *dev_id); | ||
22 | extern int activate_ipi(int fd, int pid); | 21 | extern int activate_ipi(int fd, int pid); |
23 | extern unsigned long irq_lock(void); | 22 | extern unsigned long irq_lock(void); |
24 | extern void irq_unlock(unsigned long flags); | 23 | extern 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 | ||
18 | extern int clone(int (*proc)(void *), void *sp, int flags, void *data); | 18 | extern int clone(int (*proc)(void *), void *sp, int flags, void *data); |
19 | extern int sleep(int); | 19 | extern int sleep(int); |
20 | extern int printf(char *fmt, ...); | 20 | extern int printf(const char *fmt, ...); |
21 | extern char *strerror(int errnum); | 21 | extern char *strerror(int errnum); |
22 | extern char *ptsname(int __fd); | 22 | extern char *ptsname(int __fd); |
23 | extern int munmap(void *, int); | 23 | extern int munmap(void *, int); |
@@ -35,15 +35,6 @@ extern int read(unsigned int, char *, int); | |||
35 | extern int pipe(int *); | 35 | extern int pipe(int *); |
36 | extern int sched_yield(void); | 36 | extern int sched_yield(void); |
37 | extern int ptrace(int op, int pid, long addr, long data); | 37 | extern 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 | ||
34 | struct line { | 34 | struct 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 | ||
70 | struct lines { | 73 | struct 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 | ||
76 | extern void line_close(struct tty_struct *tty, struct file * filp); | 79 | extern void line_close(struct tty_struct *tty, struct file * filp); |
77 | extern int line_open(struct line *lines, struct tty_struct *tty, | 80 | extern int line_open(struct line *lines, struct tty_struct *tty); |
78 | struct chan_opts *opts); | 81 | extern int line_setup(struct line *lines, unsigned int sizeof_lines, |
79 | extern int line_setup(struct line *lines, unsigned int sizeof_lines, char *init, | 82 | char *init); |
80 | int all_allowed); | 83 | extern int line_write(struct tty_struct *tty, const unsigned char *buf, |
81 | extern int line_write(struct tty_struct *tty, const unsigned char *buf, int len); | 84 | int len); |
82 | extern void line_put_char(struct tty_struct *tty, unsigned char ch); | 85 | extern void line_put_char(struct tty_struct *tty, unsigned char ch); |
83 | extern void line_set_termios(struct tty_struct *tty, struct termios * old); | 86 | extern void line_set_termios(struct tty_struct *tty, struct termios * old); |
84 | extern int line_chars_in_buffer(struct tty_struct *tty); | 87 | extern int line_chars_in_buffer(struct tty_struct *tty); |
@@ -87,23 +90,27 @@ extern void line_flush_chars(struct tty_struct *tty); | |||
87 | extern int line_write_room(struct tty_struct *tty); | 90 | extern int line_write_room(struct tty_struct *tty); |
88 | extern int line_ioctl(struct tty_struct *tty, struct file * file, | 91 | extern int line_ioctl(struct tty_struct *tty, struct file * file, |
89 | unsigned int cmd, unsigned long arg); | 92 | unsigned int cmd, unsigned long arg); |
93 | extern void line_throttle(struct tty_struct *tty); | ||
94 | extern void line_unthrottle(struct tty_struct *tty); | ||
90 | 95 | ||
91 | extern char *add_xterm_umid(char *base); | 96 | extern char *add_xterm_umid(char *base); |
92 | extern int line_setup_irq(int fd, int input, int output, struct tty_struct *tty); | 97 | extern int line_setup_irq(int fd, int input, int output, struct line *line, |
98 | void *data); | ||
93 | extern void line_close_chan(struct line *line); | 99 | extern void line_close_chan(struct line *line); |
94 | extern void line_disable(struct tty_struct *tty, int current_irq); | 100 | extern struct tty_driver * line_register_devfs(struct lines *set, |
95 | extern 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); |
100 | extern void lines_init(struct line *lines, int nlines); | 105 | extern void lines_init(struct line *lines, int nlines, struct chan_opts *opts); |
101 | extern void close_lines(struct line *lines, int nlines); | 106 | extern void close_lines(struct line *lines, int nlines); |
102 | 107 | ||
103 | extern int line_config(struct line *lines, unsigned int sizeof_lines, char *str); | 108 | extern int line_config(struct line *lines, unsigned int sizeof_lines, |
109 | char *str, struct chan_opts *opts); | ||
104 | extern int line_id(char **str, int *start_out, int *end_out); | 110 | extern int line_id(char **str, int *start_out, int *end_out); |
105 | extern int line_remove(struct line *lines, unsigned int sizeof_lines, int n); | 111 | extern int line_remove(struct line *lines, unsigned int sizeof_lines, int n); |
106 | extern int line_get_config(char *dev, struct line *lines, unsigned int sizeof_lines, char *str, | 112 | extern 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 | ||
33 | struct mconsole_notify { | 33 | struct 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 | |||
66 | extern char mconsole_socket_name[]; | 66 | extern char mconsole_socket_name[]; |
67 | 67 | ||
68 | extern int mconsole_unlink_socket(void); | 68 | extern int mconsole_unlink_socket(void); |
69 | extern int mconsole_reply(struct mc_request *req, char *reply, int err, | 69 | extern int mconsole_reply_len(struct mc_request *req, const char *reply, |
70 | int len, int err, int more); | ||
71 | extern int mconsole_reply(struct mc_request *req, const char *str, int err, | ||
70 | int more); | 72 | int more); |
71 | 73 | ||
72 | extern void mconsole_version(struct mc_request *req); | 74 | extern void mconsole_version(struct mc_request *req); |
@@ -84,7 +86,7 @@ extern void mconsole_proc(struct mc_request *req); | |||
84 | extern void mconsole_stack(struct mc_request *req); | 86 | extern void mconsole_stack(struct mc_request *req); |
85 | 87 | ||
86 | extern int mconsole_get_request(int fd, struct mc_request *req); | 88 | extern int mconsole_get_request(int fd, struct mc_request *req); |
87 | extern int mconsole_notify(char *sock_name, int type, const void *data, | 89 | extern int mconsole_notify(char *sock_name, int type, const void *data, |
88 | int len); | 90 | int len); |
89 | extern char *mconsole_notify_socket(void); | 91 | extern char *mconsole_notify_socket(void); |
90 | extern void lock_notify(void); | 92 | extern 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); |
214 | extern int helper_wait(int pid); | 214 | extern int helper_wait(int pid); |
215 | 215 | ||
216 | #endif | 216 | /* umid.c */ |
217 | 217 | ||
218 | /* | 218 | extern int umid_file_name(char *name, char *buf, int len); |
219 | * Overrides for Emacs so that we follow Linus's tabbing style. | 219 | extern int set_umid(char *name); |
220 | * Emacs will notice this stuff at the end of the file and automatically | 220 | extern 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); | |||
64 | extern void setup_hostinfo(void); | 64 | extern void setup_hostinfo(void); |
65 | extern void do_exec(int old_pid, int new_pid); | 65 | extern void do_exec(int old_pid, int new_pid); |
66 | extern void tracer_panic(char *msg, ...); | 66 | extern void tracer_panic(char *msg, ...); |
67 | extern char *get_umid(int only_if_set); | ||
68 | extern void do_longjmp(void *p, int val); | 67 | extern void do_longjmp(void *p, int val); |
69 | extern int detach(int pid, int sig); | 68 | extern int detach(int pid, int sig); |
70 | extern int attach(int pid); | 69 | extern 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 | ||
16 | obj-$(CONFIG_BLK_DEV_INITRD) += initrd.o | 16 | obj-$(CONFIG_BLK_DEV_INITRD) += initrd.o |
17 | obj-$(CONFIG_GPROF) += gprof_syms.o | 17 | obj-$(CONFIG_GPROF) += gprof_syms.o |
@@ -24,7 +24,7 @@ obj-$(CONFIG_MODE_SKAS) += skas/ | |||
24 | 24 | ||
25 | user-objs-$(CONFIG_TTY_LOG) += tty_log.o | 25 | user-objs-$(CONFIG_TTY_LOG) += tty_log.o |
26 | 26 | ||
27 | USER_OBJS := $(user-objs-y) config.o time.o tty_log.o umid.o user_util.o | 27 | USER_OBJS := $(user-objs-y) config.o time.o tty_log.o user_util.o |
28 | 28 | ||
29 | include arch/um/scripts/Makefile.rules | 29 | include 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 | ||
35 | static struct irq_fd *active_fds = NULL; | 34 | static struct irq_fd *active_fds = NULL; |
@@ -41,9 +40,11 @@ static int pollfds_size = 0; | |||
41 | 40 | ||
42 | extern int io_count, intr_count; | 41 | extern int io_count, intr_count; |
43 | 42 | ||
43 | extern void free_irqs(void); | ||
44 | |||
44 | void sigio_handler(int sig, union uml_pt_regs *regs) | 45 | void 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 | ||
94 | int activate_ipi(int fd, int pid) | 81 | int 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 | ||
316 | void 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 | |||
336 | void reactivate_fd(int fd, int irqnum) | 302 | void 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 | ||
327 | extern void remove_umid_dir(void); | ||
328 | |||
329 | __uml_exitcall(remove_umid_dir); | ||
330 | |||
331 | extern exitcall_t __uml_exitcall_begin, __uml_exitcall_end; | 327 | extern exitcall_t __uml_exitcall_begin, __uml_exitcall_end; |
332 | 328 | ||
333 | void do_uml_exitcalls(void) | 329 | void 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 | ||
221 | static int need_poll(int n) | 223 | static 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 */ | ||
26 | static char umid[UMID_LEN] = { 0 }; | ||
27 | |||
28 | /* Changed by set_uml_dir and make_uml_dir, which are run early in boot */ | ||
29 | static char *uml_dir = UML_DIR; | ||
30 | |||
31 | /* Changed by set_umid */ | ||
32 | static int umid_is_random = 1; | ||
33 | static int umid_inited = 0; | 13 | static int umid_inited = 0; |
34 | /* Have we created the files? Should we remove them? */ | ||
35 | static int umid_owned = 0; | ||
36 | 14 | ||
37 | static int make_umid(int (*printer)(const char *fmt, ...)); | 15 | static int __init set_umid_arg(char *name, int *add) |
38 | |||
39 | static 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 | |||
57 | static 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 | ||
69 | int __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 | |||
85 | extern int tracing_pid; | ||
86 | |||
87 | static 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 | |||
111 | static 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 | |||
149 | void 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 | |||
159 | char *get_umid(int only_if_set) | ||
160 | { | ||
161 | if(only_if_set && umid_is_random) | ||
162 | return NULL; | ||
163 | return umid; | ||
164 | } | ||
165 | |||
166 | static 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 | |||
205 | static 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 | |||
224 | static 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 | |||
259 | static 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 | |||
311 | static 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 | ||
6 | obj-y = aio.o elf_aux.o file.o helper.o main.o mem.o process.o signal.o \ | 6 | obj-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 | ||
10 | USER_OBJS := aio.o elf_aux.o file.o helper.o main.o mem.o process.o signal.o \ | 10 | USER_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 | ||
13 | elf_aux.o: $(ARCH_DIR)/kernel-offsets.h | 13 | elf_aux.o: $(ARCH_DIR)/kernel-offsets.h |
14 | CFLAGS_elf_aux.o += -I$(objtree)/arch/um | 14 | CFLAGS_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 | ||
18 | struct aio_thread_req { | 18 | struct 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 | ||
27 | static int aio_req_fd_r = -1; | 27 | static int aio_req_fd_r = -1; |
@@ -38,18 +38,18 @@ static int aio_req_fd_w = -1; | |||
38 | 38 | ||
39 | static long io_setup(int n, aio_context_t *ctxp) | 39 | static 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 | ||
44 | static long io_submit(aio_context_t ctx, long nr, struct iocb **iocbpp) | 44 | static 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 | ||
49 | static long io_getevents(aio_context_t ctx_id, long min_nr, long nr, | 49 | static 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 | ||
68 | static int do_aio(aio_context_t ctx, enum aio_type type, int fd, char *buf, | 68 | static 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 | ||
114 | static aio_context_t ctx = 0; | 114 | static aio_context_t ctx = 0; |
115 | 115 | ||
116 | static int aio_thread(void *arg) | 116 | static 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 | ||
148 | static int do_not_aio(struct aio_thread_req *req) | 148 | static 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: | 181 | out: |
182 | return err; | 182 | return err; |
183 | } | 183 | } |
184 | 184 | ||
185 | static int not_aio_thread(void *arg) | 185 | static 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 | ||
215 | static int aio_pid = -1; | 217 | static int aio_pid = -1; |
216 | 218 | ||
217 | static int init_aio_24(void) | 219 | static 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: | 238 | out_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: | 243 | out: |
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 |
252 | static int init_aio_26(void) | 254 | static 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 | ||
275 | static int submit_aio_26(enum aio_type type, int io_fd, char *buf, int len, | 277 | static 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 |
297 | static int init_aio_26(void) | 299 | static int init_aio_26(void) |
298 | { | 300 | { |
299 | return -ENOSYS; | 301 | return -ENOSYS; |
300 | } | 302 | } |
301 | 303 | ||
302 | static int submit_aio_26(enum aio_type type, int io_fd, char *buf, int len, | 304 | static 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 | ||
311 | static int __init set_aio_24(char *name, int *add) | 313 | static 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 | ||
329 | static int init_aio(void) | 331 | static 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 | ||
363 | static void exit_aio(void) | 364 | static 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); | |||
371 | static int submit_aio_24(enum aio_type type, int io_fd, char *buf, int len, | 372 | static 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 | ||
390 | int submit_aio(enum aio_type type, int io_fd, char *buf, int len, | 391 | int 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 */ | ||
21 | char umid[UMID_LEN] = { 0 }; | ||
22 | |||
23 | /* Changed by set_uml_dir and make_uml_dir, which are run early in boot */ | ||
24 | static char *uml_dir = UML_DIR; | ||
25 | |||
26 | static 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 | |||
63 | err_free: | ||
64 | free(uml_dir); | ||
65 | err: | ||
66 | uml_dir = NULL; | ||
67 | return err; | ||
68 | } | ||
69 | |||
70 | static 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 | |||
108 | static 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 | |||
162 | static 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 | |||
186 | int __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 | |||
196 | static int umid_setup = 0; | ||
197 | |||
198 | int __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 | |||
262 | static int __init make_umid_init(void) | ||
263 | { | ||
264 | make_umid(); | ||
265 | |||
266 | return 0; | ||
267 | } | ||
268 | |||
269 | __initcall(make_umid_init); | ||
270 | |||
271 | int __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 | |||
288 | char *get_umid(void) | ||
289 | { | ||
290 | return umid; | ||
291 | } | ||
292 | |||
293 | static 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 | |||
324 | static 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 | ||
12 | config 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 | |||
12 | config IOMMU_DEBUG | 22 | config 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 |
347 | ia32_sys_call_table: | 347 | ia32_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); | |||
157 | DECLARE_PER_CPU(int, cpu_state); | 157 | DECLARE_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 */ |
161 | static inline void play_dead(void) | 161 | static 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 |
173 | static inline void play_dead(void) | 174 | static 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 | ||
20 | extern void sys_ni_syscall(void); | 20 | extern void sys_ni_syscall(void); |
21 | 21 | ||
22 | sys_call_ptr_t sys_call_table[__NR_syscall_max+1] __cacheline_aligned = { | 22 | const 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 | |||
503 | extern char __start_rodata, __end_rodata; | ||
504 | void 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 |
502 | void free_initrd_mem(unsigned long start, unsigned long end) | 525 | void 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); |