11565 lines
331 KiB
Diff
11565 lines
331 KiB
Diff
diff -urN linux-i386/Makefile linux-m68k/Makefile
|
||
--- linux-i386/Makefile 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/Makefile 2006-06-22 09:48:16.000000000 +0200
|
||
@@ -172,7 +172,7 @@
|
||
# Default value for CROSS_COMPILE is not to prefix executables
|
||
# Note: Some architectures assign CROSS_COMPILE in their arch/*/Makefile
|
||
|
||
-ARCH ?= $(SUBARCH)
|
||
+ARCH ?= m68k
|
||
CROSS_COMPILE ?=
|
||
|
||
# Architecture as present in compile.h
|
||
diff -urN linux-i386/arch/m68k/Kconfig linux-m68k/arch/m68k/Kconfig
|
||
--- linux-i386/arch/m68k/Kconfig 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/arch/m68k/Kconfig 2006-06-18 19:06:43.000000000 +0200
|
||
@@ -600,7 +600,7 @@
|
||
|
||
config SERIAL167
|
||
bool "CD2401 support for MVME166/7 serial ports"
|
||
- depends on MVME16x && BROKEN
|
||
+ depends on MVME16x
|
||
help
|
||
This is the driver for the serial ports on the Motorola MVME166,
|
||
167, and 172 boards. Everyone using one of these boards should say
|
||
diff -urN linux-i386/arch/m68k/Makefile linux-m68k/arch/m68k/Makefile
|
||
--- linux-i386/arch/m68k/Makefile 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/arch/m68k/Makefile 2006-06-06 01:17:27.000000000 +0200
|
||
@@ -19,6 +19,7 @@
|
||
# override top level makefile
|
||
AS += -m68020
|
||
LDFLAGS := -m m68kelf
|
||
+LDFLAGS_MODULE += -T $(srctree)/arch/m68k/kernel/module.lds
|
||
ifneq ($(COMPILE_ARCH),$(ARCH))
|
||
# prefix for cross-compiling binaries
|
||
CROSS_COMPILE = m68k-linux-
|
||
diff -urN linux-i386/arch/m68k/amiga/amiga_ksyms.c linux-m68k/arch/m68k/amiga/amiga_ksyms.c
|
||
--- linux-i386/arch/m68k/amiga/amiga_ksyms.c 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/arch/m68k/amiga/amiga_ksyms.c 2006-01-28 22:32:48.000000000 +0100
|
||
@@ -23,8 +23,6 @@
|
||
EXPORT_SYMBOL(amiga_chip_size);
|
||
EXPORT_SYMBOL(amiga_audio_period);
|
||
EXPORT_SYMBOL(amiga_audio_min_period);
|
||
-EXPORT_SYMBOL(amiga_do_irq);
|
||
-EXPORT_SYMBOL(amiga_do_irq_list);
|
||
|
||
#ifdef CONFIG_AMIGA_PCMCIA
|
||
EXPORT_SYMBOL(pcmcia_reset);
|
||
diff -urN linux-i386/arch/m68k/amiga/amiints.c linux-m68k/arch/m68k/amiga/amiints.c
|
||
--- linux-i386/arch/m68k/amiga/amiints.c 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/arch/m68k/amiga/amiints.c 2006-04-10 00:21:43.000000000 +0200
|
||
@@ -35,60 +35,29 @@
|
||
* /Jes
|
||
*/
|
||
|
||
-#include <linux/types.h>
|
||
-#include <linux/kernel.h>
|
||
-#include <linux/sched.h>
|
||
-#include <linux/kernel_stat.h>
|
||
#include <linux/init.h>
|
||
+#include <linux/interrupt.h>
|
||
#include <linux/errno.h>
|
||
-#include <linux/seq_file.h>
|
||
|
||
-#include <asm/system.h>
|
||
#include <asm/irq.h>
|
||
#include <asm/traps.h>
|
||
#include <asm/amigahw.h>
|
||
#include <asm/amigaints.h>
|
||
#include <asm/amipcmcia.h>
|
||
|
||
-extern int cia_request_irq(struct ciabase *base,int irq,
|
||
- irqreturn_t (*handler)(int, void *, struct pt_regs *),
|
||
- unsigned long flags, const char *devname, void *dev_id);
|
||
-extern void cia_free_irq(struct ciabase *base, unsigned int irq, void *dev_id);
|
||
-extern void cia_init_IRQ(struct ciabase *base);
|
||
-extern int cia_get_irq_list(struct ciabase *base, struct seq_file *p);
|
||
-
|
||
-/* irq node variables for amiga interrupt sources */
|
||
-static irq_node_t *ami_irq_list[AMI_STD_IRQS];
|
||
-
|
||
-static unsigned short amiga_intena_vals[AMI_STD_IRQS] = {
|
||
- [IRQ_AMIGA_VERTB] = IF_VERTB,
|
||
- [IRQ_AMIGA_COPPER] = IF_COPER,
|
||
- [IRQ_AMIGA_AUD0] = IF_AUD0,
|
||
- [IRQ_AMIGA_AUD1] = IF_AUD1,
|
||
- [IRQ_AMIGA_AUD2] = IF_AUD2,
|
||
- [IRQ_AMIGA_AUD3] = IF_AUD3,
|
||
- [IRQ_AMIGA_BLIT] = IF_BLIT,
|
||
- [IRQ_AMIGA_DSKSYN] = IF_DSKSYN,
|
||
- [IRQ_AMIGA_DSKBLK] = IF_DSKBLK,
|
||
- [IRQ_AMIGA_RBF] = IF_RBF,
|
||
- [IRQ_AMIGA_TBE] = IF_TBE,
|
||
- [IRQ_AMIGA_SOFT] = IF_SOFT,
|
||
- [IRQ_AMIGA_PORTS] = IF_PORTS,
|
||
- [IRQ_AMIGA_EXTER] = IF_EXTER
|
||
+static void amiga_enable_irq(unsigned int irq);
|
||
+static void amiga_disable_irq(unsigned int irq);
|
||
+static irqreturn_t ami_int1(int irq, void *dev_id, struct pt_regs *fp);
|
||
+static irqreturn_t ami_int3(int irq, void *dev_id, struct pt_regs *fp);
|
||
+static irqreturn_t ami_int4(int irq, void *dev_id, struct pt_regs *fp);
|
||
+static irqreturn_t ami_int5(int irq, void *dev_id, struct pt_regs *fp);
|
||
+
|
||
+static struct irq_controller amiga_irq_controller = {
|
||
+ .name = "amiga",
|
||
+ .lock = SPIN_LOCK_UNLOCKED,
|
||
+ .enable = amiga_enable_irq,
|
||
+ .disable = amiga_disable_irq,
|
||
};
|
||
-static const unsigned char ami_servers[AMI_STD_IRQS] = {
|
||
- [IRQ_AMIGA_VERTB] = 1,
|
||
- [IRQ_AMIGA_PORTS] = 1,
|
||
- [IRQ_AMIGA_EXTER] = 1
|
||
-};
|
||
-
|
||
-static short ami_ablecount[AMI_IRQS];
|
||
-
|
||
-static irqreturn_t ami_badint(int irq, void *dev_id, struct pt_regs *fp)
|
||
-{
|
||
- num_spurious += 1;
|
||
- return IRQ_NONE;
|
||
-}
|
||
|
||
/*
|
||
* void amiga_init_IRQ(void)
|
||
@@ -103,23 +72,12 @@
|
||
|
||
void __init amiga_init_IRQ(void)
|
||
{
|
||
- int i;
|
||
+ request_irq(IRQ_AUTO_1, ami_int1, 0, "int1", NULL);
|
||
+ request_irq(IRQ_AUTO_3, ami_int3, 0, "int3", NULL);
|
||
+ request_irq(IRQ_AUTO_4, ami_int4, 0, "int4", NULL);
|
||
+ request_irq(IRQ_AUTO_5, ami_int5, 0, "int5", NULL);
|
||
|
||
- /* initialize handlers */
|
||
- for (i = 0; i < AMI_STD_IRQS; i++) {
|
||
- if (ami_servers[i]) {
|
||
- ami_irq_list[i] = NULL;
|
||
- } else {
|
||
- ami_irq_list[i] = new_irq_node();
|
||
- ami_irq_list[i]->handler = ami_badint;
|
||
- ami_irq_list[i]->flags = 0;
|
||
- ami_irq_list[i]->dev_id = NULL;
|
||
- ami_irq_list[i]->devname = NULL;
|
||
- ami_irq_list[i]->next = NULL;
|
||
- }
|
||
- }
|
||
- for (i = 0; i < AMI_IRQS; i++)
|
||
- ami_ablecount[i] = 0;
|
||
+ m68k_setup_irq_controller(&amiga_irq_controller, IRQ_USER, AMI_STD_IRQS);
|
||
|
||
/* turn off PCMCIA interrupts */
|
||
if (AMIGAHW_PRESENT(PCMCIA))
|
||
@@ -134,249 +92,21 @@
|
||
cia_init_IRQ(&ciab_base);
|
||
}
|
||
|
||
-static inline int amiga_insert_irq(irq_node_t **list, irq_node_t *node)
|
||
-{
|
||
- unsigned long flags;
|
||
- irq_node_t *cur;
|
||
-
|
||
- if (!node->dev_id)
|
||
- printk("%s: Warning: dev_id of %s is zero\n",
|
||
- __FUNCTION__, node->devname);
|
||
-
|
||
- local_irq_save(flags);
|
||
-
|
||
- cur = *list;
|
||
-
|
||
- if (node->flags & SA_INTERRUPT) {
|
||
- if (node->flags & SA_SHIRQ)
|
||
- return -EBUSY;
|
||
- /*
|
||
- * There should never be more than one
|
||
- */
|
||
- while (cur && cur->flags & SA_INTERRUPT) {
|
||
- list = &cur->next;
|
||
- cur = cur->next;
|
||
- }
|
||
- } else {
|
||
- while (cur) {
|
||
- list = &cur->next;
|
||
- cur = cur->next;
|
||
- }
|
||
- }
|
||
-
|
||
- node->next = cur;
|
||
- *list = node;
|
||
-
|
||
- local_irq_restore(flags);
|
||
- return 0;
|
||
-}
|
||
-
|
||
-static inline void amiga_delete_irq(irq_node_t **list, void *dev_id)
|
||
-{
|
||
- unsigned long flags;
|
||
- irq_node_t *node;
|
||
-
|
||
- local_irq_save(flags);
|
||
-
|
||
- for (node = *list; node; list = &node->next, node = *list) {
|
||
- if (node->dev_id == dev_id) {
|
||
- *list = node->next;
|
||
- /* Mark it as free. */
|
||
- node->handler = NULL;
|
||
- local_irq_restore(flags);
|
||
- return;
|
||
- }
|
||
- }
|
||
- local_irq_restore(flags);
|
||
- printk ("%s: tried to remove invalid irq\n", __FUNCTION__);
|
||
-}
|
||
-
|
||
-/*
|
||
- * amiga_request_irq : add an interrupt service routine for a particular
|
||
- * machine specific interrupt source.
|
||
- * If the addition was successful, it returns 0.
|
||
- */
|
||
-
|
||
-int amiga_request_irq(unsigned int irq,
|
||
- irqreturn_t (*handler)(int, void *, struct pt_regs *),
|
||
- unsigned long flags, const char *devname, void *dev_id)
|
||
-{
|
||
- irq_node_t *node;
|
||
- int error = 0;
|
||
-
|
||
- if (irq >= AMI_IRQS) {
|
||
- printk ("%s: Unknown IRQ %d from %s\n", __FUNCTION__,
|
||
- irq, devname);
|
||
- return -ENXIO;
|
||
- }
|
||
-
|
||
- if (irq >= IRQ_AMIGA_AUTO)
|
||
- return cpu_request_irq(irq - IRQ_AMIGA_AUTO, handler,
|
||
- flags, devname, dev_id);
|
||
-
|
||
- if (irq >= IRQ_AMIGA_CIAB)
|
||
- return cia_request_irq(&ciab_base, irq - IRQ_AMIGA_CIAB,
|
||
- handler, flags, devname, dev_id);
|
||
-
|
||
- if (irq >= IRQ_AMIGA_CIAA)
|
||
- return cia_request_irq(&ciaa_base, irq - IRQ_AMIGA_CIAA,
|
||
- handler, flags, devname, dev_id);
|
||
-
|
||
- /*
|
||
- * IRQ_AMIGA_PORTS & IRQ_AMIGA_EXTER defaults to shared,
|
||
- * we could add a check here for the SA_SHIRQ flag but all drivers
|
||
- * should be aware of sharing anyway.
|
||
- */
|
||
- if (ami_servers[irq]) {
|
||
- if (!(node = new_irq_node()))
|
||
- return -ENOMEM;
|
||
- node->handler = handler;
|
||
- node->flags = flags;
|
||
- node->dev_id = dev_id;
|
||
- node->devname = devname;
|
||
- node->next = NULL;
|
||
- error = amiga_insert_irq(&ami_irq_list[irq], node);
|
||
- } else {
|
||
- ami_irq_list[irq]->handler = handler;
|
||
- ami_irq_list[irq]->flags = flags;
|
||
- ami_irq_list[irq]->dev_id = dev_id;
|
||
- ami_irq_list[irq]->devname = devname;
|
||
- }
|
||
-
|
||
- /* enable the interrupt */
|
||
- if (irq < IRQ_AMIGA_PORTS && !ami_ablecount[irq])
|
||
- amiga_custom.intena = IF_SETCLR | amiga_intena_vals[irq];
|
||
-
|
||
- return error;
|
||
-}
|
||
-
|
||
-void amiga_free_irq(unsigned int irq, void *dev_id)
|
||
-{
|
||
- if (irq >= AMI_IRQS) {
|
||
- printk ("%s: Unknown IRQ %d\n", __FUNCTION__, irq);
|
||
- return;
|
||
- }
|
||
-
|
||
- if (irq >= IRQ_AMIGA_AUTO)
|
||
- cpu_free_irq(irq - IRQ_AMIGA_AUTO, dev_id);
|
||
-
|
||
- if (irq >= IRQ_AMIGA_CIAB) {
|
||
- cia_free_irq(&ciab_base, irq - IRQ_AMIGA_CIAB, dev_id);
|
||
- return;
|
||
- }
|
||
-
|
||
- if (irq >= IRQ_AMIGA_CIAA) {
|
||
- cia_free_irq(&ciaa_base, irq - IRQ_AMIGA_CIAA, dev_id);
|
||
- return;
|
||
- }
|
||
-
|
||
- if (ami_servers[irq]) {
|
||
- amiga_delete_irq(&ami_irq_list[irq], dev_id);
|
||
- /* if server list empty, disable the interrupt */
|
||
- if (!ami_irq_list[irq] && irq < IRQ_AMIGA_PORTS)
|
||
- amiga_custom.intena = amiga_intena_vals[irq];
|
||
- } else {
|
||
- if (ami_irq_list[irq]->dev_id != dev_id)
|
||
- printk("%s: removing probably wrong IRQ %d from %s\n",
|
||
- __FUNCTION__, irq, ami_irq_list[irq]->devname);
|
||
- ami_irq_list[irq]->handler = ami_badint;
|
||
- ami_irq_list[irq]->flags = 0;
|
||
- ami_irq_list[irq]->dev_id = NULL;
|
||
- ami_irq_list[irq]->devname = NULL;
|
||
- amiga_custom.intena = amiga_intena_vals[irq];
|
||
- }
|
||
-}
|
||
-
|
||
/*
|
||
* Enable/disable a particular machine specific interrupt source.
|
||
* Note that this may affect other interrupts in case of a shared interrupt.
|
||
* This function should only be called for a _very_ short time to change some
|
||
* internal data, that may not be changed by the interrupt at the same time.
|
||
- * ami_(enable|disable)_irq calls may also be nested.
|
||
*/
|
||
|
||
-void amiga_enable_irq(unsigned int irq)
|
||
-{
|
||
- if (irq >= AMI_IRQS) {
|
||
- printk("%s: Unknown IRQ %d\n", __FUNCTION__, irq);
|
||
- return;
|
||
- }
|
||
-
|
||
- if (--ami_ablecount[irq])
|
||
- return;
|
||
-
|
||
- /* No action for auto-vector interrupts */
|
||
- if (irq >= IRQ_AMIGA_AUTO){
|
||
- printk("%s: Trying to enable auto-vector IRQ %i\n",
|
||
- __FUNCTION__, irq - IRQ_AMIGA_AUTO);
|
||
- return;
|
||
- }
|
||
-
|
||
- if (irq >= IRQ_AMIGA_CIAB) {
|
||
- cia_set_irq(&ciab_base, (1 << (irq - IRQ_AMIGA_CIAB)));
|
||
- cia_able_irq(&ciab_base, CIA_ICR_SETCLR |
|
||
- (1 << (irq - IRQ_AMIGA_CIAB)));
|
||
- return;
|
||
- }
|
||
-
|
||
- if (irq >= IRQ_AMIGA_CIAA) {
|
||
- cia_set_irq(&ciaa_base, (1 << (irq - IRQ_AMIGA_CIAA)));
|
||
- cia_able_irq(&ciaa_base, CIA_ICR_SETCLR |
|
||
- (1 << (irq - IRQ_AMIGA_CIAA)));
|
||
- return;
|
||
- }
|
||
-
|
||
- /* enable the interrupt */
|
||
- amiga_custom.intena = IF_SETCLR | amiga_intena_vals[irq];
|
||
-}
|
||
-
|
||
-void amiga_disable_irq(unsigned int irq)
|
||
-{
|
||
- if (irq >= AMI_IRQS) {
|
||
- printk("%s: Unknown IRQ %d\n", __FUNCTION__, irq);
|
||
- return;
|
||
- }
|
||
-
|
||
- if (ami_ablecount[irq]++)
|
||
- return;
|
||
-
|
||
- /* No action for auto-vector interrupts */
|
||
- if (irq >= IRQ_AMIGA_AUTO) {
|
||
- printk("%s: Trying to disable auto-vector IRQ %i\n",
|
||
- __FUNCTION__, irq - IRQ_AMIGA_AUTO);
|
||
- return;
|
||
- }
|
||
-
|
||
- if (irq >= IRQ_AMIGA_CIAB) {
|
||
- cia_able_irq(&ciab_base, 1 << (irq - IRQ_AMIGA_CIAB));
|
||
- return;
|
||
- }
|
||
-
|
||
- if (irq >= IRQ_AMIGA_CIAA) {
|
||
- cia_able_irq(&ciaa_base, 1 << (irq - IRQ_AMIGA_CIAA));
|
||
- return;
|
||
- }
|
||
-
|
||
- /* disable the interrupt */
|
||
- amiga_custom.intena = amiga_intena_vals[irq];
|
||
-}
|
||
-
|
||
-inline void amiga_do_irq(int irq, struct pt_regs *fp)
|
||
+static void amiga_enable_irq(unsigned int irq)
|
||
{
|
||
- kstat_cpu(0).irqs[SYS_IRQS + irq]++;
|
||
- ami_irq_list[irq]->handler(irq, ami_irq_list[irq]->dev_id, fp);
|
||
+ amiga_custom.intena = IF_SETCLR | (1 << (irq - IRQ_USER));
|
||
}
|
||
|
||
-void amiga_do_irq_list(int irq, struct pt_regs *fp)
|
||
+static void amiga_disable_irq(unsigned int irq)
|
||
{
|
||
- irq_node_t *node;
|
||
-
|
||
- kstat_cpu(0).irqs[SYS_IRQS + irq]++;
|
||
-
|
||
- amiga_custom.intreq = amiga_intena_vals[irq];
|
||
-
|
||
- for (node = ami_irq_list[irq]; node; node = node->next)
|
||
- node->handler(irq, node->dev_id, fp);
|
||
+ amiga_custom.intena = 1 << (irq - IRQ_USER);
|
||
}
|
||
|
||
/*
|
||
@@ -390,19 +120,19 @@
|
||
/* if serial transmit buffer empty, interrupt */
|
||
if (ints & IF_TBE) {
|
||
amiga_custom.intreq = IF_TBE;
|
||
- amiga_do_irq(IRQ_AMIGA_TBE, fp);
|
||
+ m68k_handle_int(IRQ_AMIGA_TBE, fp);
|
||
}
|
||
|
||
/* if floppy disk transfer complete, interrupt */
|
||
if (ints & IF_DSKBLK) {
|
||
amiga_custom.intreq = IF_DSKBLK;
|
||
- amiga_do_irq(IRQ_AMIGA_DSKBLK, fp);
|
||
+ m68k_handle_int(IRQ_AMIGA_DSKBLK, fp);
|
||
}
|
||
|
||
/* if software interrupt set, interrupt */
|
||
if (ints & IF_SOFT) {
|
||
amiga_custom.intreq = IF_SOFT;
|
||
- amiga_do_irq(IRQ_AMIGA_SOFT, fp);
|
||
+ m68k_handle_int(IRQ_AMIGA_SOFT, fp);
|
||
}
|
||
return IRQ_HANDLED;
|
||
}
|
||
@@ -414,18 +144,20 @@
|
||
/* if a blitter interrupt */
|
||
if (ints & IF_BLIT) {
|
||
amiga_custom.intreq = IF_BLIT;
|
||
- amiga_do_irq(IRQ_AMIGA_BLIT, fp);
|
||
+ m68k_handle_int(IRQ_AMIGA_BLIT, fp);
|
||
}
|
||
|
||
/* if a copper interrupt */
|
||
if (ints & IF_COPER) {
|
||
amiga_custom.intreq = IF_COPER;
|
||
- amiga_do_irq(IRQ_AMIGA_COPPER, fp);
|
||
+ m68k_handle_int(IRQ_AMIGA_COPPER, fp);
|
||
}
|
||
|
||
/* if a vertical blank interrupt */
|
||
- if (ints & IF_VERTB)
|
||
- amiga_do_irq_list(IRQ_AMIGA_VERTB, fp);
|
||
+ if (ints & IF_VERTB) {
|
||
+ amiga_custom.intreq = IF_VERTB;
|
||
+ m68k_handle_int(IRQ_AMIGA_VERTB, fp);
|
||
+ }
|
||
return IRQ_HANDLED;
|
||
}
|
||
|
||
@@ -436,25 +168,25 @@
|
||
/* if audio 0 interrupt */
|
||
if (ints & IF_AUD0) {
|
||
amiga_custom.intreq = IF_AUD0;
|
||
- amiga_do_irq(IRQ_AMIGA_AUD0, fp);
|
||
+ m68k_handle_int(IRQ_AMIGA_AUD0, fp);
|
||
}
|
||
|
||
/* if audio 1 interrupt */
|
||
if (ints & IF_AUD1) {
|
||
amiga_custom.intreq = IF_AUD1;
|
||
- amiga_do_irq(IRQ_AMIGA_AUD1, fp);
|
||
+ m68k_handle_int(IRQ_AMIGA_AUD1, fp);
|
||
}
|
||
|
||
/* if audio 2 interrupt */
|
||
if (ints & IF_AUD2) {
|
||
amiga_custom.intreq = IF_AUD2;
|
||
- amiga_do_irq(IRQ_AMIGA_AUD2, fp);
|
||
+ m68k_handle_int(IRQ_AMIGA_AUD2, fp);
|
||
}
|
||
|
||
/* if audio 3 interrupt */
|
||
if (ints & IF_AUD3) {
|
||
amiga_custom.intreq = IF_AUD3;
|
||
- amiga_do_irq(IRQ_AMIGA_AUD3, fp);
|
||
+ m68k_handle_int(IRQ_AMIGA_AUD3, fp);
|
||
}
|
||
return IRQ_HANDLED;
|
||
}
|
||
@@ -466,55 +198,13 @@
|
||
/* if serial receive buffer full interrupt */
|
||
if (ints & IF_RBF) {
|
||
/* acknowledge of IF_RBF must be done by the serial interrupt */
|
||
- amiga_do_irq(IRQ_AMIGA_RBF, fp);
|
||
+ m68k_handle_int(IRQ_AMIGA_RBF, fp);
|
||
}
|
||
|
||
/* if a disk sync interrupt */
|
||
if (ints & IF_DSKSYN) {
|
||
amiga_custom.intreq = IF_DSKSYN;
|
||
- amiga_do_irq(IRQ_AMIGA_DSKSYN, fp);
|
||
+ m68k_handle_int(IRQ_AMIGA_DSKSYN, fp);
|
||
}
|
||
return IRQ_HANDLED;
|
||
}
|
||
-
|
||
-static irqreturn_t ami_int7(int irq, void *dev_id, struct pt_regs *fp)
|
||
-{
|
||
- panic ("level 7 interrupt received\n");
|
||
-}
|
||
-
|
||
-irqreturn_t (*amiga_default_handler[SYS_IRQS])(int, void *, struct pt_regs *) = {
|
||
- [0] = ami_badint,
|
||
- [1] = ami_int1,
|
||
- [2] = ami_badint,
|
||
- [3] = ami_int3,
|
||
- [4] = ami_int4,
|
||
- [5] = ami_int5,
|
||
- [6] = ami_badint,
|
||
- [7] = ami_int7
|
||
-};
|
||
-
|
||
-int show_amiga_interrupts(struct seq_file *p, void *v)
|
||
-{
|
||
- int i;
|
||
- irq_node_t *node;
|
||
-
|
||
- for (i = 0; i < AMI_STD_IRQS; i++) {
|
||
- if (!(node = ami_irq_list[i]))
|
||
- continue;
|
||
- seq_printf(p, "ami %2d: %10u ", i,
|
||
- kstat_cpu(0).irqs[SYS_IRQS + i]);
|
||
- do {
|
||
- if (node->flags & SA_INTERRUPT)
|
||
- seq_puts(p, "F ");
|
||
- else
|
||
- seq_puts(p, " ");
|
||
- seq_printf(p, "%s\n", node->devname);
|
||
- if ((node = node->next))
|
||
- seq_puts(p, " ");
|
||
- } while (node);
|
||
- }
|
||
-
|
||
- cia_get_irq_list(&ciaa_base, p);
|
||
- cia_get_irq_list(&ciab_base, p);
|
||
- return 0;
|
||
-}
|
||
diff -urN linux-i386/arch/m68k/amiga/cia.c linux-m68k/arch/m68k/amiga/cia.c
|
||
--- linux-i386/arch/m68k/amiga/cia.c 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/arch/m68k/amiga/cia.c 2006-04-10 00:21:43.000000000 +0200
|
||
@@ -29,21 +29,18 @@
|
||
unsigned short int_mask;
|
||
int handler_irq, cia_irq, server_irq;
|
||
char *name;
|
||
- irq_handler_t irq_list[CIA_IRQS];
|
||
} ciaa_base = {
|
||
.cia = &ciaa,
|
||
.int_mask = IF_PORTS,
|
||
- .handler_irq = IRQ_AMIGA_AUTO_2,
|
||
+ .handler_irq = IRQ_AMIGA_PORTS,
|
||
.cia_irq = IRQ_AMIGA_CIAA,
|
||
- .server_irq = IRQ_AMIGA_PORTS,
|
||
- .name = "CIAA handler"
|
||
+ .name = "CIAA"
|
||
}, ciab_base = {
|
||
.cia = &ciab,
|
||
.int_mask = IF_EXTER,
|
||
- .handler_irq = IRQ_AMIGA_AUTO_6,
|
||
+ .handler_irq = IRQ_AMIGA_EXTER,
|
||
.cia_irq = IRQ_AMIGA_CIAB,
|
||
- .server_irq = IRQ_AMIGA_EXTER,
|
||
- .name = "CIAB handler"
|
||
+ .name = "CIAB"
|
||
};
|
||
|
||
/*
|
||
@@ -66,13 +63,11 @@
|
||
|
||
/*
|
||
* Enable or disable CIA interrupts, return old interrupt mask,
|
||
- * interrupts will only be enabled if a handler exists
|
||
*/
|
||
|
||
unsigned char cia_able_irq(struct ciabase *base, unsigned char mask)
|
||
{
|
||
- unsigned char old, tmp;
|
||
- int i;
|
||
+ unsigned char old;
|
||
|
||
old = base->icr_mask;
|
||
base->icr_data |= base->cia->icr;
|
||
@@ -82,99 +77,104 @@
|
||
else
|
||
base->icr_mask &= ~mask;
|
||
base->icr_mask &= CIA_ICR_ALL;
|
||
- for (i = 0, tmp = 1; i < CIA_IRQS; i++, tmp <<= 1) {
|
||
- if ((tmp & base->icr_mask) && !base->irq_list[i].handler) {
|
||
- base->icr_mask &= ~tmp;
|
||
- base->cia->icr = tmp;
|
||
- }
|
||
- }
|
||
if (base->icr_data & base->icr_mask)
|
||
amiga_custom.intreq = IF_SETCLR | base->int_mask;
|
||
return old;
|
||
}
|
||
|
||
-int cia_request_irq(struct ciabase *base, unsigned int irq,
|
||
- irqreturn_t (*handler)(int, void *, struct pt_regs *),
|
||
- unsigned long flags, const char *devname, void *dev_id)
|
||
-{
|
||
- unsigned char mask;
|
||
-
|
||
- base->irq_list[irq].handler = handler;
|
||
- base->irq_list[irq].flags = flags;
|
||
- base->irq_list[irq].dev_id = dev_id;
|
||
- base->irq_list[irq].devname = devname;
|
||
-
|
||
- /* enable the interrupt */
|
||
- mask = 1 << irq;
|
||
- cia_set_irq(base, mask);
|
||
- cia_able_irq(base, CIA_ICR_SETCLR | mask);
|
||
- return 0;
|
||
-}
|
||
-
|
||
-void cia_free_irq(struct ciabase *base, unsigned int irq, void *dev_id)
|
||
-{
|
||
- if (base->irq_list[irq].dev_id != dev_id)
|
||
- printk("%s: removing probably wrong IRQ %i from %s\n",
|
||
- __FUNCTION__, base->cia_irq + irq,
|
||
- base->irq_list[irq].devname);
|
||
-
|
||
- base->irq_list[irq].handler = NULL;
|
||
- base->irq_list[irq].flags = 0;
|
||
-
|
||
- cia_able_irq(base, 1 << irq);
|
||
-}
|
||
-
|
||
static irqreturn_t cia_handler(int irq, void *dev_id, struct pt_regs *fp)
|
||
{
|
||
struct ciabase *base = (struct ciabase *)dev_id;
|
||
- int mach_irq, i;
|
||
+ int mach_irq;
|
||
unsigned char ints;
|
||
|
||
mach_irq = base->cia_irq;
|
||
- irq = SYS_IRQS + mach_irq;
|
||
ints = cia_set_irq(base, CIA_ICR_ALL);
|
||
amiga_custom.intreq = base->int_mask;
|
||
- for (i = 0; i < CIA_IRQS; i++, irq++, mach_irq++) {
|
||
- if (ints & 1) {
|
||
- kstat_cpu(0).irqs[irq]++;
|
||
- base->irq_list[i].handler(mach_irq, base->irq_list[i].dev_id, fp);
|
||
- }
|
||
- ints >>= 1;
|
||
+ for (; ints; mach_irq++, ints >>= 1) {
|
||
+ if (ints & 1)
|
||
+ m68k_handle_int(mach_irq, fp);
|
||
}
|
||
- amiga_do_irq_list(base->server_irq, fp);
|
||
return IRQ_HANDLED;
|
||
}
|
||
|
||
-void __init cia_init_IRQ(struct ciabase *base)
|
||
+static void cia_enable_irq(unsigned int irq)
|
||
{
|
||
- int i;
|
||
+ unsigned char mask;
|
||
|
||
- /* init isr handlers */
|
||
- for (i = 0; i < CIA_IRQS; i++) {
|
||
- base->irq_list[i].handler = NULL;
|
||
- base->irq_list[i].flags = 0;
|
||
+ if (irq >= IRQ_AMIGA_CIAB) {
|
||
+ mask = 1 << (irq - IRQ_AMIGA_CIAB);
|
||
+ cia_set_irq(&ciab_base, mask);
|
||
+ cia_able_irq(&ciab_base, CIA_ICR_SETCLR | mask);
|
||
+ } else {
|
||
+ mask = 1 << (irq - IRQ_AMIGA_CIAA);
|
||
+ cia_set_irq(&ciaa_base, mask);
|
||
+ cia_able_irq(&ciaa_base, CIA_ICR_SETCLR | mask);
|
||
}
|
||
+}
|
||
|
||
- /* clear any pending interrupt and turn off all interrupts */
|
||
- cia_set_irq(base, CIA_ICR_ALL);
|
||
- cia_able_irq(base, CIA_ICR_ALL);
|
||
+static void cia_disable_irq(unsigned int irq)
|
||
+{
|
||
+ if (irq >= IRQ_AMIGA_CIAB)
|
||
+ cia_able_irq(&ciab_base, 1 << (irq - IRQ_AMIGA_CIAB));
|
||
+ else
|
||
+ cia_able_irq(&ciaa_base, 1 << (irq - IRQ_AMIGA_CIAA));
|
||
+}
|
||
|
||
- /* install CIA handler */
|
||
- request_irq(base->handler_irq, cia_handler, 0, base->name, base);
|
||
+static struct irq_controller cia_irq_controller = {
|
||
+ .name = "cia",
|
||
+ .lock = SPIN_LOCK_UNLOCKED,
|
||
+ .enable = cia_enable_irq,
|
||
+ .disable = cia_disable_irq,
|
||
+};
|
||
|
||
- amiga_custom.intena = IF_SETCLR | base->int_mask;
|
||
-}
|
||
+/*
|
||
+ * Override auto irq 2 & 6 and use them as general chain
|
||
+ * for external interrupts, we link the CIA interrupt sources
|
||
+ * into this chain.
|
||
+ */
|
||
|
||
-int cia_get_irq_list(struct ciabase *base, struct seq_file *p)
|
||
+static void auto_enable_irq(unsigned int irq)
|
||
{
|
||
- int i, j;
|
||
+ switch (irq) {
|
||
+ case IRQ_AUTO_2:
|
||
+ amiga_custom.intena = IF_SETCLR | IF_PORTS;
|
||
+ break;
|
||
+ case IRQ_AUTO_6:
|
||
+ amiga_custom.intena = IF_SETCLR | IF_EXTER;
|
||
+ break;
|
||
+ }
|
||
+}
|
||
|
||
- j = base->cia_irq;
|
||
- for (i = 0; i < CIA_IRQS; i++) {
|
||
- seq_printf(p, "cia %2d: %10d ", j + i,
|
||
- kstat_cpu(0).irqs[SYS_IRQS + j + i]);
|
||
- seq_puts(p, " ");
|
||
- seq_printf(p, "%s\n", base->irq_list[i].devname);
|
||
+static void auto_disable_irq(unsigned int irq)
|
||
+{
|
||
+ switch (irq) {
|
||
+ case IRQ_AUTO_2:
|
||
+ amiga_custom.intena = IF_PORTS;
|
||
+ break;
|
||
+ case IRQ_AUTO_6:
|
||
+ amiga_custom.intena = IF_EXTER;
|
||
+ break;
|
||
}
|
||
- return 0;
|
||
+}
|
||
+
|
||
+static struct irq_controller auto_irq_controller = {
|
||
+ .name = "auto",
|
||
+ .lock = SPIN_LOCK_UNLOCKED,
|
||
+ .enable = auto_enable_irq,
|
||
+ .disable = auto_disable_irq,
|
||
+};
|
||
+
|
||
+void __init cia_init_IRQ(struct ciabase *base)
|
||
+{
|
||
+ m68k_setup_irq_controller(&cia_irq_controller, base->cia_irq, CIA_IRQS);
|
||
+
|
||
+ /* clear any pending interrupt and turn off all interrupts */
|
||
+ cia_set_irq(base, CIA_ICR_ALL);
|
||
+ cia_able_irq(base, CIA_ICR_ALL);
|
||
+
|
||
+ /* override auto int and install CIA handler */
|
||
+ m68k_setup_irq_controller(&auto_irq_controller, base->handler_irq, 1);
|
||
+ m68k_irq_startup(base->handler_irq);
|
||
+ request_irq(base->handler_irq, cia_handler, SA_SHIRQ, base->name, base);
|
||
}
|
||
diff -urN linux-i386/arch/m68k/amiga/config.c linux-m68k/arch/m68k/amiga/config.c
|
||
--- linux-i386/arch/m68k/amiga/config.c 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/arch/m68k/amiga/config.c 2006-04-10 00:21:43.000000000 +0200
|
||
@@ -87,17 +87,8 @@
|
||
static void amiga_sched_init(irqreturn_t (*handler)(int, void *, struct pt_regs *));
|
||
/* amiga specific irq functions */
|
||
extern void amiga_init_IRQ (void);
|
||
-extern irqreturn_t (*amiga_default_handler[]) (int, void *, struct pt_regs *);
|
||
-extern int amiga_request_irq (unsigned int irq,
|
||
- irqreturn_t (*handler)(int, void *, struct pt_regs *),
|
||
- unsigned long flags, const char *devname,
|
||
- void *dev_id);
|
||
-extern void amiga_free_irq (unsigned int irq, void *dev_id);
|
||
-extern void amiga_enable_irq (unsigned int);
|
||
-extern void amiga_disable_irq (unsigned int);
|
||
static void amiga_get_model(char *model);
|
||
static int amiga_get_hardware_list(char *buffer);
|
||
-extern int show_amiga_interrupts (struct seq_file *, void *);
|
||
/* amiga specific timer functions */
|
||
static unsigned long amiga_gettimeoffset (void);
|
||
static int a3000_hwclk (int, struct rtc_time *);
|
||
@@ -392,14 +383,8 @@
|
||
|
||
mach_sched_init = amiga_sched_init;
|
||
mach_init_IRQ = amiga_init_IRQ;
|
||
- mach_default_handler = &amiga_default_handler;
|
||
- mach_request_irq = amiga_request_irq;
|
||
- mach_free_irq = amiga_free_irq;
|
||
- enable_irq = amiga_enable_irq;
|
||
- disable_irq = amiga_disable_irq;
|
||
mach_get_model = amiga_get_model;
|
||
mach_get_hardware_list = amiga_get_hardware_list;
|
||
- mach_get_irq_list = show_amiga_interrupts;
|
||
mach_gettimeoffset = amiga_gettimeoffset;
|
||
if (AMIGAHW_PRESENT(A3000_CLK)){
|
||
mach_hwclk = a3000_hwclk;
|
||
diff -urN linux-i386/arch/m68k/apollo/Makefile linux-m68k/arch/m68k/apollo/Makefile
|
||
--- linux-i386/arch/m68k/apollo/Makefile 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/arch/m68k/apollo/Makefile 2006-06-06 01:18:31.000000000 +0200
|
||
@@ -2,4 +2,4 @@
|
||
# Makefile for Linux arch/m68k/amiga source directory
|
||
#
|
||
|
||
-obj-y := config.o dn_ints.o dma.o
|
||
+obj-y := config.o dn_ints.o
|
||
diff -urN linux-i386/arch/m68k/apollo/config.c linux-m68k/arch/m68k/apollo/config.c
|
||
--- linux-i386/arch/m68k/apollo/config.c 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/arch/m68k/apollo/config.c 2006-01-28 22:33:11.000000000 +0100
|
||
@@ -28,11 +28,6 @@
|
||
|
||
extern void dn_sched_init(irqreturn_t (*handler)(int,void *,struct pt_regs *));
|
||
extern void dn_init_IRQ(void);
|
||
-extern int dn_request_irq(unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_regs *), unsigned long flags, const char *devname, void *dev_id);
|
||
-extern void dn_free_irq(unsigned int irq, void *dev_id);
|
||
-extern void dn_enable_irq(unsigned int);
|
||
-extern void dn_disable_irq(unsigned int);
|
||
-extern int show_dn_interrupts(struct seq_file *, void *);
|
||
extern unsigned long dn_gettimeoffset(void);
|
||
extern int dn_dummy_hwclk(int, struct rtc_time *);
|
||
extern int dn_dummy_set_clock_mmss(unsigned long);
|
||
@@ -40,13 +35,11 @@
|
||
extern void dn_dummy_waitbut(void);
|
||
extern struct fb_info *dn_fb_init(long *);
|
||
extern void dn_dummy_debug_init(void);
|
||
-extern void dn_dummy_video_setup(char *,int *);
|
||
extern irqreturn_t dn_process_int(int irq, struct pt_regs *fp);
|
||
#ifdef CONFIG_HEARTBEAT
|
||
static void dn_heartbeat(int on);
|
||
#endif
|
||
static irqreturn_t dn_timer_int(int irq,void *, struct pt_regs *);
|
||
-static irqreturn_t (*sched_timer_handler)(int, void *, struct pt_regs *)=NULL;
|
||
static void dn_get_model(char *model);
|
||
static const char *apollo_models[] = {
|
||
[APOLLO_DN3000-APOLLO_DN3000] = "DN3000 (Otter)",
|
||
@@ -164,17 +157,10 @@
|
||
|
||
mach_sched_init=dn_sched_init; /* */
|
||
mach_init_IRQ=dn_init_IRQ;
|
||
- mach_default_handler=NULL;
|
||
- mach_request_irq = dn_request_irq;
|
||
- mach_free_irq = dn_free_irq;
|
||
- enable_irq = dn_enable_irq;
|
||
- disable_irq = dn_disable_irq;
|
||
- mach_get_irq_list = show_dn_interrupts;
|
||
mach_gettimeoffset = dn_gettimeoffset;
|
||
mach_max_dma_address = 0xffffffff;
|
||
mach_hwclk = dn_dummy_hwclk; /* */
|
||
mach_set_clock_mmss = dn_dummy_set_clock_mmss; /* */
|
||
- mach_process_int = dn_process_int;
|
||
mach_reset = dn_dummy_reset; /* */
|
||
#ifdef CONFIG_HEARTBEAT
|
||
mach_heartbeat = dn_heartbeat;
|
||
@@ -189,11 +175,13 @@
|
||
|
||
}
|
||
|
||
-irqreturn_t dn_timer_int(int irq, void *dev_id, struct pt_regs *fp) {
|
||
+irqreturn_t dn_timer_int(int irq, void *dev_id, struct pt_regs *fp)
|
||
+{
|
||
+ irqreturn_t (*timer_handler)(int, void *, struct pt_regs *) = dev_id;
|
||
|
||
volatile unsigned char x;
|
||
|
||
- sched_timer_handler(irq,dev_id,fp);
|
||
+ timer_handler(irq, dev_id, fp);
|
||
|
||
x=*(volatile unsigned char *)(timer+3);
|
||
x=*(volatile unsigned char *)(timer+5);
|
||
@@ -217,9 +205,7 @@
|
||
printk("*(0x10803) %02x\n",*(volatile unsigned char *)(timer+0x3));
|
||
#endif
|
||
|
||
- sched_timer_handler=timer_routine;
|
||
- request_irq(0,dn_timer_int,0,NULL,NULL);
|
||
-
|
||
+ request_irq(IRQ_APOLLO, dn_timer_int, 0, "time", timer_routine);
|
||
}
|
||
|
||
unsigned long dn_gettimeoffset(void) {
|
||
diff -urN linux-i386/arch/m68k/apollo/dn_ints.c linux-m68k/arch/m68k/apollo/dn_ints.c
|
||
--- linux-i386/arch/m68k/apollo/dn_ints.c 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/arch/m68k/apollo/dn_ints.c 2006-01-28 22:33:11.000000000 +0100
|
||
@@ -1,125 +1,44 @@
|
||
-#include <linux/types.h>
|
||
-#include <linux/kernel.h>
|
||
-#include <linux/jiffies.h>
|
||
-#include <linux/kernel_stat.h>
|
||
-#include <linux/timer.h>
|
||
+#include <linux/interrupt.h>
|
||
|
||
-#include <asm/system.h>
|
||
#include <asm/irq.h>
|
||
#include <asm/traps.h>
|
||
-#include <asm/page.h>
|
||
-#include <asm/machdep.h>
|
||
#include <asm/apollohw.h>
|
||
-#include <asm/errno.h>
|
||
|
||
-static irq_handler_t dn_irqs[16];
|
||
-
|
||
-irqreturn_t dn_process_int(int irq, struct pt_regs *fp)
|
||
+void dn_process_int(unsigned int irq, struct pt_regs *fp)
|
||
{
|
||
- irqreturn_t res = IRQ_NONE;
|
||
-
|
||
- if(dn_irqs[irq-160].handler) {
|
||
- res = dn_irqs[irq-160].handler(irq,dn_irqs[irq-160].dev_id,fp);
|
||
- } else {
|
||
- printk("spurious irq %d occurred\n",irq);
|
||
- }
|
||
-
|
||
- *(volatile unsigned char *)(pica)=0x20;
|
||
- *(volatile unsigned char *)(picb)=0x20;
|
||
-
|
||
- return res;
|
||
-}
|
||
-
|
||
-void dn_init_IRQ(void) {
|
||
-
|
||
- int i;
|
||
-
|
||
- for(i=0;i<16;i++) {
|
||
- dn_irqs[i].handler=NULL;
|
||
- dn_irqs[i].flags=IRQ_FLG_STD;
|
||
- dn_irqs[i].dev_id=NULL;
|
||
- dn_irqs[i].devname=NULL;
|
||
- }
|
||
-
|
||
-}
|
||
-
|
||
-int dn_request_irq(unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_regs *), unsigned long flags, const char *devname, void *dev_id) {
|
||
-
|
||
- if((irq<0) || (irq>15)) {
|
||
- printk("Trying to request invalid IRQ\n");
|
||
- return -ENXIO;
|
||
- }
|
||
-
|
||
- if(!dn_irqs[irq].handler) {
|
||
- dn_irqs[irq].handler=handler;
|
||
- dn_irqs[irq].flags=IRQ_FLG_STD;
|
||
- dn_irqs[irq].dev_id=dev_id;
|
||
- dn_irqs[irq].devname=devname;
|
||
- if(irq<8)
|
||
- *(volatile unsigned char *)(pica+1)&=~(1<<irq);
|
||
- else
|
||
- *(volatile unsigned char *)(picb+1)&=~(1<<(irq-8));
|
||
-
|
||
- return 0;
|
||
- }
|
||
- else {
|
||
- printk("Trying to request already assigned irq %d\n",irq);
|
||
- return -ENXIO;
|
||
- }
|
||
-
|
||
-}
|
||
-
|
||
-void dn_free_irq(unsigned int irq, void *dev_id) {
|
||
-
|
||
- if((irq<0) || (irq>15)) {
|
||
- printk("Trying to free invalid IRQ\n");
|
||
- return ;
|
||
- }
|
||
-
|
||
- if(irq<8)
|
||
- *(volatile unsigned char *)(pica+1)|=(1<<irq);
|
||
- else
|
||
- *(volatile unsigned char *)(picb+1)|=(1<<(irq-8));
|
||
-
|
||
- dn_irqs[irq].handler=NULL;
|
||
- dn_irqs[irq].flags=IRQ_FLG_STD;
|
||
- dn_irqs[irq].dev_id=NULL;
|
||
- dn_irqs[irq].devname=NULL;
|
||
-
|
||
- return ;
|
||
+ m68k_handle_int(irq, fp);
|
||
|
||
+ *(volatile unsigned char *)(pica)=0x20;
|
||
+ *(volatile unsigned char *)(picb)=0x20;
|
||
}
|
||
|
||
-void dn_enable_irq(unsigned int irq) {
|
||
-
|
||
- printk("dn enable irq\n");
|
||
-
|
||
-}
|
||
-
|
||
-void dn_disable_irq(unsigned int irq) {
|
||
-
|
||
- printk("dn disable irq\n");
|
||
-
|
||
-}
|
||
-
|
||
-int show_dn_interrupts(struct seq_file *p, void *v) {
|
||
-
|
||
- printk("dn get irq list\n");
|
||
-
|
||
- return 0;
|
||
-
|
||
+int apollo_irq_startup(unsigned int irq)
|
||
+{
|
||
+ if (irq < 8)
|
||
+ *(volatile unsigned char *)(pica+1) &= ~(1 << irq);
|
||
+ else
|
||
+ *(volatile unsigned char *)(picb+1) &= ~(1 << (irq - 8));
|
||
+ return 0;
|
||
}
|
||
|
||
-struct fb_info *dn_dummy_fb_init(long *mem_start) {
|
||
-
|
||
- printk("fb init\n");
|
||
-
|
||
- return NULL;
|
||
-
|
||
+void apollo_irq_shutdown(unsigned int irq)
|
||
+{
|
||
+ if (irq < 8)
|
||
+ *(volatile unsigned char *)(pica+1) |= (1 << irq);
|
||
+ else
|
||
+ *(volatile unsigned char *)(picb+1) |= (1 << (irq - 8));
|
||
}
|
||
|
||
-void dn_dummy_video_setup(char *options,int *ints) {
|
||
+static struct irq_controller apollo_irq_controller = {
|
||
+ .name = "apollo",
|
||
+ .lock = SPIN_LOCK_UNLOCKED,
|
||
+ .startup = apollo_irq_startup,
|
||
+ .shutdown = apollo_irq_shutdown,
|
||
+};
|
||
|
||
- printk("no video yet\n");
|
||
|
||
+void dn_init_IRQ(void)
|
||
+{
|
||
+ m68k_setup_user_interrupt(VEC_USER + 96, 16, dn_process_int);
|
||
+ m68k_setup_irq_controller(&apollo_irq_controller, IRQ_APOLLO, 16);
|
||
}
|
||
diff -urN linux-i386/arch/m68k/atari/ataints.c linux-m68k/arch/m68k/atari/ataints.c
|
||
--- linux-i386/arch/m68k/atari/ataints.c 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/arch/m68k/atari/ataints.c 2006-01-28 22:33:28.000000000 +0100
|
||
@@ -104,6 +104,7 @@
|
||
* the sr copy in the frame.
|
||
*/
|
||
|
||
+#if 0
|
||
|
||
#define NUM_INT_SOURCES (8 + NUM_ATARI_SOURCES)
|
||
|
||
@@ -133,13 +134,6 @@
|
||
*/
|
||
static struct irqparam irq_param[NUM_INT_SOURCES];
|
||
|
||
-/*
|
||
- * Bitmap for free interrupt vector numbers
|
||
- * (new vectors starting from 0x70 can be allocated by
|
||
- * atari_register_vme_int())
|
||
- */
|
||
-static int free_vme_vec_bitmap;
|
||
-
|
||
/* check for valid int number (complex, sigh...) */
|
||
#define IS_VALID_INTNO(n) \
|
||
((n) > 0 && \
|
||
@@ -301,6 +295,14 @@
|
||
);
|
||
for (;;);
|
||
}
|
||
+#endif
|
||
+
|
||
+/*
|
||
+ * Bitmap for free interrupt vector numbers
|
||
+ * (new vectors starting from 0x70 can be allocated by
|
||
+ * atari_register_vme_int())
|
||
+ */
|
||
+static int free_vme_vec_bitmap;
|
||
|
||
/* GK:
|
||
* HBL IRQ handler for Falcon. Nobody needs it :-)
|
||
@@ -313,13 +315,34 @@
|
||
"orw #0x200,%sp@\n\t" /* set saved ipl to 2 */
|
||
"rte");
|
||
|
||
-/* Defined in entry.S; only increments 'num_spurious' */
|
||
-asmlinkage void bad_interrupt(void);
|
||
-
|
||
-extern void atari_microwire_cmd( int cmd );
|
||
+extern void atari_microwire_cmd(int cmd);
|
||
|
||
extern int atari_SCC_reset_done;
|
||
|
||
+static int atari_startup_irq(unsigned int irq)
|
||
+{
|
||
+ m68k_irq_startup(irq);
|
||
+ atari_turnon_irq(irq);
|
||
+ atari_enable_irq(irq);
|
||
+ return 0;
|
||
+}
|
||
+
|
||
+static void atari_shutdown_irq(unsigned int irq)
|
||
+{
|
||
+ atari_disable_irq(irq);
|
||
+ atari_turnoff_irq(irq);
|
||
+ m68k_irq_shutdown(irq);
|
||
+}
|
||
+
|
||
+static struct irq_controller atari_irq_controller = {
|
||
+ .name = "atari",
|
||
+ .lock = SPIN_LOCK_UNLOCKED,
|
||
+ .startup = atari_startup_irq,
|
||
+ .shutdown = atari_shutdown_irq,
|
||
+ .enable = atari_enable_irq,
|
||
+ .disable = atari_disable_irq,
|
||
+};
|
||
+
|
||
/*
|
||
* void atari_init_IRQ (void)
|
||
*
|
||
@@ -333,12 +356,8 @@
|
||
|
||
void __init atari_init_IRQ(void)
|
||
{
|
||
- int i;
|
||
-
|
||
- /* initialize the vector table */
|
||
- for (i = 0; i < NUM_INT_SOURCES; ++i) {
|
||
- vectors[IRQ_SOURCE_TO_VECTOR(i)] = bad_interrupt;
|
||
- }
|
||
+ m68k_setup_user_interrupt(VEC_USER, 192, NULL);
|
||
+ m68k_setup_irq_controller(&atari_irq_controller, 1, NUM_ATARI_SOURCES - 1);
|
||
|
||
/* Initialize the MFP(s) */
|
||
|
||
@@ -378,8 +397,7 @@
|
||
* enabled in VME mask
|
||
*/
|
||
tt_scu.vme_mask = 0x60; /* enable MFP and SCC ints */
|
||
- }
|
||
- else {
|
||
+ } else {
|
||
/* If no SCU and no Hades, the HSYNC interrupt needs to be
|
||
* disabled this way. (Else _inthandler in kernel/sys_call.S
|
||
* gets overruns)
|
||
@@ -404,184 +422,6 @@
|
||
}
|
||
|
||
|
||
-static irqreturn_t atari_call_irq_list( int irq, void *dev_id, struct pt_regs *fp )
|
||
-{
|
||
- irq_node_t *node;
|
||
-
|
||
- for (node = (irq_node_t *)dev_id; node; node = node->next)
|
||
- node->handler(irq, node->dev_id, fp);
|
||
- return IRQ_HANDLED;
|
||
-}
|
||
-
|
||
-
|
||
-/*
|
||
- * atari_request_irq : add an interrupt service routine for a particular
|
||
- * machine specific interrupt source.
|
||
- * If the addition was successful, it returns 0.
|
||
- */
|
||
-
|
||
-int atari_request_irq(unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_regs *),
|
||
- unsigned long flags, const char *devname, void *dev_id)
|
||
-{
|
||
- int vector;
|
||
- unsigned long oflags = flags;
|
||
-
|
||
- /*
|
||
- * The following is a hack to make some PCI card drivers work,
|
||
- * which set the SA_SHIRQ flag.
|
||
- */
|
||
-
|
||
- flags &= ~SA_SHIRQ;
|
||
-
|
||
- if (flags == SA_INTERRUPT) {
|
||
- printk ("%s: SA_INTERRUPT changed to IRQ_TYPE_SLOW for %s\n",
|
||
- __FUNCTION__, devname);
|
||
- flags = IRQ_TYPE_SLOW;
|
||
- }
|
||
- if (flags < IRQ_TYPE_SLOW || flags > IRQ_TYPE_PRIO) {
|
||
- printk ("%s: Bad irq type 0x%lx <0x%lx> requested from %s\n",
|
||
- __FUNCTION__, flags, oflags, devname);
|
||
- return -EINVAL;
|
||
- }
|
||
- if (!IS_VALID_INTNO(irq)) {
|
||
- printk ("%s: Unknown irq %d requested from %s\n",
|
||
- __FUNCTION__, irq, devname);
|
||
- return -ENXIO;
|
||
- }
|
||
- vector = IRQ_SOURCE_TO_VECTOR(irq);
|
||
-
|
||
- /*
|
||
- * Check type/source combination: slow ints are (currently)
|
||
- * only possible for MFP-interrupts.
|
||
- */
|
||
- if (flags == IRQ_TYPE_SLOW &&
|
||
- (irq < STMFP_SOURCE_BASE || irq >= SCC_SOURCE_BASE)) {
|
||
- printk ("%s: Slow irq requested for non-MFP source %d from %s\n",
|
||
- __FUNCTION__, irq, devname);
|
||
- return -EINVAL;
|
||
- }
|
||
-
|
||
- if (vectors[vector] == bad_interrupt) {
|
||
- /* int has no handler yet */
|
||
- irq_handler[irq].handler = handler;
|
||
- irq_handler[irq].dev_id = dev_id;
|
||
- irq_param[irq].flags = flags;
|
||
- irq_param[irq].devname = devname;
|
||
- vectors[vector] =
|
||
- (flags == IRQ_TYPE_SLOW) ? slow_handlers[irq-STMFP_SOURCE_BASE] :
|
||
- (flags == IRQ_TYPE_FAST) ? atari_fast_irq_handler :
|
||
- atari_prio_irq_handler;
|
||
- /* If MFP int, also enable and umask it */
|
||
- atari_turnon_irq(irq);
|
||
- atari_enable_irq(irq);
|
||
-
|
||
- return 0;
|
||
- }
|
||
- else if (irq_param[irq].flags == flags) {
|
||
- /* old handler is of same type -> handlers can be chained */
|
||
- irq_node_t *node;
|
||
- unsigned long flags;
|
||
-
|
||
- local_irq_save(flags);
|
||
-
|
||
- if (irq_handler[irq].handler != atari_call_irq_list) {
|
||
- /* Only one handler yet, make a node for this first one */
|
||
- if (!(node = new_irq_node()))
|
||
- return -ENOMEM;
|
||
- node->handler = irq_handler[irq].handler;
|
||
- node->dev_id = irq_handler[irq].dev_id;
|
||
- node->devname = irq_param[irq].devname;
|
||
- node->next = NULL;
|
||
-
|
||
- irq_handler[irq].handler = atari_call_irq_list;
|
||
- irq_handler[irq].dev_id = node;
|
||
- irq_param[irq].devname = "chained";
|
||
- }
|
||
-
|
||
- if (!(node = new_irq_node()))
|
||
- return -ENOMEM;
|
||
- node->handler = handler;
|
||
- node->dev_id = dev_id;
|
||
- node->devname = devname;
|
||
- /* new handlers are put in front of the queue */
|
||
- node->next = irq_handler[irq].dev_id;
|
||
- irq_handler[irq].dev_id = node;
|
||
-
|
||
- local_irq_restore(flags);
|
||
- return 0;
|
||
- } else {
|
||
- printk ("%s: Irq %d allocated by other type int (call from %s)\n",
|
||
- __FUNCTION__, irq, devname);
|
||
- return -EBUSY;
|
||
- }
|
||
-}
|
||
-
|
||
-void atari_free_irq(unsigned int irq, void *dev_id)
|
||
-{
|
||
- unsigned long flags;
|
||
- int vector;
|
||
- irq_node_t **list, *node;
|
||
-
|
||
- if (!IS_VALID_INTNO(irq)) {
|
||
- printk("%s: Unknown irq %d\n", __FUNCTION__, irq);
|
||
- return;
|
||
- }
|
||
-
|
||
- vector = IRQ_SOURCE_TO_VECTOR(irq);
|
||
- if (vectors[vector] == bad_interrupt)
|
||
- goto not_found;
|
||
-
|
||
- local_irq_save(flags);
|
||
-
|
||
- if (irq_handler[irq].handler != atari_call_irq_list) {
|
||
- /* It's the only handler for the interrupt */
|
||
- if (irq_handler[irq].dev_id != dev_id) {
|
||
- local_irq_restore(flags);
|
||
- goto not_found;
|
||
- }
|
||
- irq_handler[irq].handler = NULL;
|
||
- irq_handler[irq].dev_id = NULL;
|
||
- irq_param[irq].devname = NULL;
|
||
- vectors[vector] = bad_interrupt;
|
||
- /* If MFP int, also disable it */
|
||
- atari_disable_irq(irq);
|
||
- atari_turnoff_irq(irq);
|
||
-
|
||
- local_irq_restore(flags);
|
||
- return;
|
||
- }
|
||
-
|
||
- /* The interrupt is chained, find the irq on the list */
|
||
- for(list = (irq_node_t **)&irq_handler[irq].dev_id; *list; list = &(*list)->next) {
|
||
- if ((*list)->dev_id == dev_id) break;
|
||
- }
|
||
- if (!*list) {
|
||
- local_irq_restore(flags);
|
||
- goto not_found;
|
||
- }
|
||
-
|
||
- (*list)->handler = NULL; /* Mark it as free for reallocation */
|
||
- *list = (*list)->next;
|
||
-
|
||
- /* If there's now only one handler, unchain the interrupt, i.e. plug in
|
||
- * the handler directly again and omit atari_call_irq_list */
|
||
- node = (irq_node_t *)irq_handler[irq].dev_id;
|
||
- if (node && !node->next) {
|
||
- irq_handler[irq].handler = node->handler;
|
||
- irq_handler[irq].dev_id = node->dev_id;
|
||
- irq_param[irq].devname = node->devname;
|
||
- node->handler = NULL; /* Mark it as free for reallocation */
|
||
- }
|
||
-
|
||
- local_irq_restore(flags);
|
||
- return;
|
||
-
|
||
-not_found:
|
||
- printk("%s: tried to remove invalid irq\n", __FUNCTION__);
|
||
- return;
|
||
-}
|
||
-
|
||
-
|
||
/*
|
||
* atari_register_vme_int() returns the number of a free interrupt vector for
|
||
* hardware with a programmable int vector (probably a VME board).
|
||
@@ -591,58 +431,24 @@
|
||
{
|
||
int i;
|
||
|
||
- for(i = 0; i < 32; i++)
|
||
- if((free_vme_vec_bitmap & (1 << i)) == 0)
|
||
+ for (i = 0; i < 32; i++)
|
||
+ if ((free_vme_vec_bitmap & (1 << i)) == 0)
|
||
break;
|
||
|
||
- if(i == 16)
|
||
+ if (i == 16)
|
||
return 0;
|
||
|
||
free_vme_vec_bitmap |= 1 << i;
|
||
- return (VME_SOURCE_BASE + i);
|
||
+ return VME_SOURCE_BASE + i;
|
||
}
|
||
|
||
|
||
void atari_unregister_vme_int(unsigned long irq)
|
||
{
|
||
- if(irq >= VME_SOURCE_BASE && irq < VME_SOURCE_BASE + VME_MAX_SOURCES) {
|
||
+ if (irq >= VME_SOURCE_BASE && irq < VME_SOURCE_BASE + VME_MAX_SOURCES) {
|
||
irq -= VME_SOURCE_BASE;
|
||
free_vme_vec_bitmap &= ~(1 << irq);
|
||
}
|
||
}
|
||
|
||
|
||
-int show_atari_interrupts(struct seq_file *p, void *v)
|
||
-{
|
||
- int i;
|
||
-
|
||
- for (i = 0; i < NUM_INT_SOURCES; ++i) {
|
||
- if (vectors[IRQ_SOURCE_TO_VECTOR(i)] == bad_interrupt)
|
||
- continue;
|
||
- if (i < STMFP_SOURCE_BASE)
|
||
- seq_printf(p, "auto %2d: %10u ",
|
||
- i, kstat_cpu(0).irqs[i]);
|
||
- else
|
||
- seq_printf(p, "vec $%02x: %10u ",
|
||
- IRQ_SOURCE_TO_VECTOR(i),
|
||
- kstat_cpu(0).irqs[i]);
|
||
-
|
||
- if (irq_handler[i].handler != atari_call_irq_list) {
|
||
- seq_printf(p, "%s\n", irq_param[i].devname);
|
||
- }
|
||
- else {
|
||
- irq_node_t *n;
|
||
- for( n = (irq_node_t *)irq_handler[i].dev_id; n; n = n->next ) {
|
||
- seq_printf(p, "%s\n", n->devname);
|
||
- if (n->next)
|
||
- seq_puts(p, " " );
|
||
- }
|
||
- }
|
||
- }
|
||
- if (num_spurious)
|
||
- seq_printf(p, "spurio.: %10u\n", num_spurious);
|
||
-
|
||
- return 0;
|
||
-}
|
||
-
|
||
-
|
||
diff -urN linux-i386/arch/m68k/atari/config.c linux-m68k/arch/m68k/atari/config.c
|
||
--- linux-i386/arch/m68k/atari/config.c 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/arch/m68k/atari/config.c 2006-04-10 00:21:44.000000000 +0200
|
||
@@ -57,12 +57,6 @@
|
||
|
||
/* atari specific irq functions */
|
||
extern void atari_init_IRQ (void);
|
||
-extern int atari_request_irq (unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_regs *),
|
||
- unsigned long flags, const char *devname, void *dev_id);
|
||
-extern void atari_free_irq (unsigned int irq, void *dev_id);
|
||
-extern void atari_enable_irq (unsigned int);
|
||
-extern void atari_disable_irq (unsigned int);
|
||
-extern int show_atari_interrupts (struct seq_file *, void *);
|
||
extern void atari_mksound( unsigned int count, unsigned int ticks );
|
||
#ifdef CONFIG_HEARTBEAT
|
||
static void atari_heartbeat( int on );
|
||
@@ -232,13 +226,8 @@
|
||
|
||
mach_sched_init = atari_sched_init;
|
||
mach_init_IRQ = atari_init_IRQ;
|
||
- mach_request_irq = atari_request_irq;
|
||
- mach_free_irq = atari_free_irq;
|
||
- enable_irq = atari_enable_irq;
|
||
- disable_irq = atari_disable_irq;
|
||
mach_get_model = atari_get_model;
|
||
mach_get_hardware_list = atari_get_hardware_list;
|
||
- mach_get_irq_list = show_atari_interrupts;
|
||
mach_gettimeoffset = atari_gettimeoffset;
|
||
mach_reset = atari_reset;
|
||
mach_max_dma_address = 0xffffff;
|
||
diff -urN linux-i386/arch/m68k/bvme6000/Makefile linux-m68k/arch/m68k/bvme6000/Makefile
|
||
--- linux-i386/arch/m68k/bvme6000/Makefile 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/arch/m68k/bvme6000/Makefile 2006-01-28 22:33:47.000000000 +0100
|
||
@@ -2,4 +2,4 @@
|
||
# Makefile for Linux arch/m68k/bvme6000 source directory
|
||
#
|
||
|
||
-obj-y := config.o bvmeints.o rtc.o
|
||
+obj-y := config.o rtc.o
|
||
diff -urN linux-i386/arch/m68k/bvme6000/config.c linux-m68k/arch/m68k/bvme6000/config.c
|
||
--- linux-i386/arch/m68k/bvme6000/config.c 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/arch/m68k/bvme6000/config.c 2006-06-18 19:06:43.000000000 +0200
|
||
@@ -36,15 +36,8 @@
|
||
#include <asm/machdep.h>
|
||
#include <asm/bvme6000hw.h>
|
||
|
||
-extern irqreturn_t bvme6000_process_int (int level, struct pt_regs *regs);
|
||
-extern void bvme6000_init_IRQ (void);
|
||
-extern void bvme6000_free_irq (unsigned int, void *);
|
||
-extern int show_bvme6000_interrupts(struct seq_file *, void *);
|
||
-extern void bvme6000_enable_irq (unsigned int);
|
||
-extern void bvme6000_disable_irq (unsigned int);
|
||
static void bvme6000_get_model(char *model);
|
||
static int bvme6000_get_hardware_list(char *buffer);
|
||
-extern int bvme6000_request_irq(unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_regs *), unsigned long flags, const char *devname, void *dev_id);
|
||
extern void bvme6000_sched_init(irqreturn_t (*handler)(int, void *, struct pt_regs *));
|
||
extern unsigned long bvme6000_gettimeoffset (void);
|
||
extern int bvme6000_hwclk (int, struct rtc_time *);
|
||
@@ -100,6 +93,14 @@
|
||
return 0;
|
||
}
|
||
|
||
+/*
|
||
+ * This function is called during kernel startup to initialize
|
||
+ * the bvme6000 IRQ handling routines.
|
||
+ */
|
||
+static void bvme6000_init_IRQ(void)
|
||
+{
|
||
+ m68k_setup_user_interrupt(VEC_USER, 192, NULL);
|
||
+}
|
||
|
||
void __init config_bvme6000(void)
|
||
{
|
||
@@ -127,12 +128,6 @@
|
||
mach_hwclk = bvme6000_hwclk;
|
||
mach_set_clock_mmss = bvme6000_set_clock_mmss;
|
||
mach_reset = bvme6000_reset;
|
||
- mach_free_irq = bvme6000_free_irq;
|
||
- mach_process_int = bvme6000_process_int;
|
||
- mach_get_irq_list = show_bvme6000_interrupts;
|
||
- mach_request_irq = bvme6000_request_irq;
|
||
- enable_irq = bvme6000_enable_irq;
|
||
- disable_irq = bvme6000_disable_irq;
|
||
mach_get_model = bvme6000_get_model;
|
||
mach_get_hardware_list = bvme6000_get_hardware_list;
|
||
|
||
diff -urN linux-i386/arch/m68k/hp300/Makefile linux-m68k/arch/m68k/hp300/Makefile
|
||
--- linux-i386/arch/m68k/hp300/Makefile 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/arch/m68k/hp300/Makefile 2006-01-28 22:35:53.000000000 +0100
|
||
@@ -2,4 +2,4 @@
|
||
# Makefile for Linux arch/m68k/hp300 source directory
|
||
#
|
||
|
||
-obj-y := ksyms.o config.o ints.o time.o reboot.o
|
||
+obj-y := ksyms.o config.o time.o reboot.o
|
||
diff -urN linux-i386/arch/m68k/hp300/config.c linux-m68k/arch/m68k/hp300/config.c
|
||
--- linux-i386/arch/m68k/hp300/config.c 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/arch/m68k/hp300/config.c 2006-01-28 22:35:53.000000000 +0100
|
||
@@ -21,7 +21,6 @@
|
||
#include <asm/hp300hw.h>
|
||
#include <asm/rtc.h>
|
||
|
||
-#include "ints.h"
|
||
#include "time.h"
|
||
|
||
unsigned long hp300_model;
|
||
@@ -64,8 +63,6 @@
|
||
static char hp300_model_name[13] = "HP9000/";
|
||
|
||
extern void hp300_reset(void);
|
||
-extern irqreturn_t (*hp300_default_handler[])(int, void *, struct pt_regs *);
|
||
-extern int show_hp300_interrupts(struct seq_file *, void *);
|
||
#ifdef CONFIG_SERIAL_8250_CONSOLE
|
||
extern int hp300_setup_serial_console(void) __init;
|
||
#endif
|
||
@@ -245,16 +242,16 @@
|
||
hp300_rtc_read(RTC_REG_SEC2);
|
||
}
|
||
|
||
+static void __init hp300_init_IRQ(void)
|
||
+{
|
||
+}
|
||
+
|
||
void __init config_hp300(void)
|
||
{
|
||
mach_sched_init = hp300_sched_init;
|
||
mach_init_IRQ = hp300_init_IRQ;
|
||
- mach_request_irq = hp300_request_irq;
|
||
- mach_free_irq = hp300_free_irq;
|
||
mach_get_model = hp300_get_model;
|
||
- mach_get_irq_list = show_hp300_interrupts;
|
||
mach_gettimeoffset = hp300_gettimeoffset;
|
||
- mach_default_handler = &hp300_default_handler;
|
||
mach_hwclk = hp300_hwclk;
|
||
mach_get_ss = hp300_get_ss;
|
||
mach_reset = hp300_reset;
|
||
diff -urN linux-i386/arch/m68k/hp300/time.c linux-m68k/arch/m68k/hp300/time.c
|
||
--- linux-i386/arch/m68k/hp300/time.c 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/arch/m68k/hp300/time.c 2006-01-28 22:35:53.000000000 +0100
|
||
@@ -18,7 +18,6 @@
|
||
#include <asm/system.h>
|
||
#include <asm/traps.h>
|
||
#include <asm/blinken.h>
|
||
-#include "ints.h"
|
||
|
||
/* Clock hardware definitions */
|
||
|
||
@@ -71,7 +70,7 @@
|
||
|
||
asm volatile(" movpw %0,%1@(5)" : : "d" (INTVAL), "a" (CLOCKBASE));
|
||
|
||
- cpu_request_irq(6, hp300_tick, IRQ_FLG_STD, "timer tick", vector);
|
||
+ request_irq(IRQ_AUTO_6, hp300_tick, IRQ_FLG_STD, "timer tick", vector);
|
||
|
||
out_8(CLOCKBASE + CLKCR2, 0x1); /* select CR1 */
|
||
out_8(CLOCKBASE + CLKCR1, 0x40); /* enable irq */
|
||
diff -urN linux-i386/arch/m68k/kernel/Makefile linux-m68k/arch/m68k/kernel/Makefile
|
||
--- linux-i386/arch/m68k/kernel/Makefile 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/arch/m68k/kernel/Makefile 2006-06-06 01:18:31.000000000 +0200
|
||
@@ -9,8 +9,8 @@
|
||
endif
|
||
extra-y += vmlinux.lds
|
||
|
||
-obj-y := entry.o process.o traps.o ints.o signal.o ptrace.o \
|
||
- sys_m68k.o time.o semaphore.o setup.o m68k_ksyms.o
|
||
+obj-y := entry.o process.o traps.o ints.o dma.o signal.o ptrace.o \
|
||
+ sys_m68k.o time.o semaphore.o setup.o m68k_ksyms.o
|
||
|
||
obj-$(CONFIG_PCI) += bios32.o
|
||
obj-$(CONFIG_MODULES) += module.o
|
||
diff -urN linux-i386/arch/m68k/kernel/bios32.c linux-m68k/arch/m68k/kernel/bios32.c
|
||
--- linux-i386/arch/m68k/kernel/bios32.c 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/arch/m68k/kernel/bios32.c 2004-10-20 01:06:39.000000000 +0200
|
||
@@ -285,7 +285,7 @@
|
||
|
||
DBG_DEVS(("layout_bus: starting bus %d\n", bus->number));
|
||
|
||
- if (!bus->devices && !bus->children)
|
||
+ if (list_empty(&bus->devices) && list_empty(&bus->children))
|
||
return;
|
||
|
||
/*
|
||
diff -urN linux-i386/arch/m68k/kernel/dma.c linux-m68k/arch/m68k/kernel/dma.c
|
||
--- linux-i386/arch/m68k/kernel/dma.c 1970-01-01 01:00:00.000000000 +0100
|
||
+++ linux-m68k/arch/m68k/kernel/dma.c 2006-06-24 16:32:07.000000000 +0200
|
||
@@ -0,0 +1,129 @@
|
||
+/*
|
||
+ * This file is subject to the terms and conditions of the GNU General Public
|
||
+ * License. See the file COPYING in the main directory of this archive
|
||
+ * for more details.
|
||
+ */
|
||
+
|
||
+#undef DEBUG
|
||
+
|
||
+#include <linux/dma-mapping.h>
|
||
+#include <linux/device.h>
|
||
+#include <linux/kernel.h>
|
||
+#include <linux/vmalloc.h>
|
||
+
|
||
+#include <asm/pgalloc.h>
|
||
+#include <asm/scatterlist.h>
|
||
+
|
||
+void *dma_alloc_coherent(struct device *dev, size_t size,
|
||
+ dma_addr_t *handle, int flag)
|
||
+{
|
||
+ struct page *page, **map;
|
||
+ pgprot_t pgprot;
|
||
+ void *addr;
|
||
+ int i, order;
|
||
+
|
||
+ pr_debug("dma_alloc_coherent: %d,%x\n", size, flag);
|
||
+
|
||
+ size = PAGE_ALIGN(size);
|
||
+ order = get_order(size);
|
||
+
|
||
+ page = alloc_pages(flag, order);
|
||
+ if (!page)
|
||
+ return NULL;
|
||
+
|
||
+ *handle = page_to_phys(page);
|
||
+ map = kmalloc(sizeof(struct page *) << order, flag & ~__GFP_DMA);
|
||
+ if (!map) {
|
||
+ __free_pages(page, order);
|
||
+ return NULL;
|
||
+ }
|
||
+ split_page(page, order);
|
||
+
|
||
+ order = 1 << order;
|
||
+ size >>= PAGE_SHIFT;
|
||
+ map[0] = page;
|
||
+ for (i = 1; i < size; i++)
|
||
+ map[i] = page + i;
|
||
+ for (; i < order; i++)
|
||
+ __free_page(page + i);
|
||
+ pgprot = __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_DIRTY);
|
||
+ if (CPU_IS_040_OR_060)
|
||
+ pgprot_val(pgprot) |= _PAGE_GLOBAL040 | _PAGE_NOCACHE_S;
|
||
+ else
|
||
+ pgprot_val(pgprot) |= _PAGE_NOCACHE030;
|
||
+ addr = vmap(map, size, flag, pgprot);
|
||
+ kfree(map);
|
||
+
|
||
+ return addr;
|
||
+}
|
||
+EXPORT_SYMBOL(dma_alloc_coherent);
|
||
+
|
||
+void dma_free_coherent(struct device *dev, size_t size,
|
||
+ void *addr, dma_addr_t handle)
|
||
+{
|
||
+ pr_debug("dma_free_coherent: %p, %x\n", addr, handle);
|
||
+ vfree(addr);
|
||
+}
|
||
+EXPORT_SYMBOL(dma_free_coherent);
|
||
+
|
||
+inline void dma_sync_single_for_device(struct device *dev, dma_addr_t handle, size_t size,
|
||
+ enum dma_data_direction dir)
|
||
+{
|
||
+ switch (dir) {
|
||
+ case DMA_TO_DEVICE:
|
||
+ cache_push(handle, size);
|
||
+ break;
|
||
+ case DMA_FROM_DEVICE:
|
||
+ cache_clear(handle, size);
|
||
+ break;
|
||
+ default:
|
||
+ if (printk_ratelimit())
|
||
+ printk("dma_sync_single_for_device: unsupported dir %u\n", dir);
|
||
+ break;
|
||
+ }
|
||
+}
|
||
+EXPORT_SYMBOL(dma_sync_single_for_device);
|
||
+
|
||
+void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nents,
|
||
+ enum dma_data_direction dir)
|
||
+{
|
||
+ int i;
|
||
+
|
||
+ for (i = 0; i < nents; sg++, i++)
|
||
+ dma_sync_single_for_device(dev, sg->dma_address, sg->length, dir);
|
||
+}
|
||
+EXPORT_SYMBOL(dma_sync_sg_for_device);
|
||
+
|
||
+dma_addr_t dma_map_single(struct device *dev, void *addr, size_t size,
|
||
+ enum dma_data_direction dir)
|
||
+{
|
||
+ dma_addr_t handle = virt_to_bus(addr);
|
||
+
|
||
+ dma_sync_single_for_device(dev, handle, size, dir);
|
||
+ return handle;
|
||
+}
|
||
+EXPORT_SYMBOL(dma_map_single);
|
||
+
|
||
+dma_addr_t dma_map_page(struct device *dev, struct page *page,
|
||
+ unsigned long offset, size_t size,
|
||
+ enum dma_data_direction dir)
|
||
+{
|
||
+ dma_addr_t handle = page_to_phys(page) + offset;
|
||
+
|
||
+ dma_sync_single_for_device(dev, handle, size, dir);
|
||
+ return handle;
|
||
+}
|
||
+EXPORT_SYMBOL(dma_map_page);
|
||
+
|
||
+int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
|
||
+ enum dma_data_direction dir)
|
||
+{
|
||
+ int i;
|
||
+
|
||
+ for (i = 0; i < nents; sg++, i++) {
|
||
+ sg->dma_address = page_to_phys(sg->page) + sg->offset;
|
||
+ dma_sync_single_for_device(dev, sg->dma_address, sg->length, dir);
|
||
+ }
|
||
+ return nents;
|
||
+}
|
||
+EXPORT_SYMBOL(dma_map_sg);
|
||
diff -urN linux-i386/arch/m68k/kernel/entry.S linux-m68k/arch/m68k/kernel/entry.S
|
||
--- linux-i386/arch/m68k/kernel/entry.S 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/arch/m68k/kernel/entry.S 2006-02-11 17:28:36.000000000 +0100
|
||
@@ -45,9 +45,11 @@
|
||
#include <asm/asm-offsets.h>
|
||
|
||
.globl system_call, buserr, trap, resume
|
||
-.globl inthandler, sys_call_table
|
||
+.globl sys_call_table
|
||
.globl sys_fork, sys_clone, sys_vfork
|
||
.globl ret_from_interrupt, bad_interrupt
|
||
+.globl auto_irqhandler_fixup
|
||
+.globl user_irqvec_fixup, user_irqhandler_fixup
|
||
|
||
.text
|
||
ENTRY(buserr)
|
||
@@ -191,65 +193,29 @@
|
||
jbra resume_userspace
|
||
|
||
|
||
-#if 0
|
||
-#ifdef CONFIG_AMIGA
|
||
-ami_inthandler:
|
||
- addql #1,irq_stat+CPUSTAT_LOCAL_IRQ_COUNT
|
||
- SAVE_ALL_INT
|
||
- GET_CURRENT(%d0)
|
||
+/* This is the main interrupt handler for autovector interrupts */
|
||
|
||
- bfextu %sp@(PT_VECTOR){#4,#12},%d0
|
||
- movel %d0,%a0
|
||
- addql #1,%a0@(kstat+STAT_IRQ-VECOFF(VEC_SPUR))
|
||
- movel %a0@(autoirq_list-VECOFF(VEC_SPUR)),%a0
|
||
-
|
||
-| amiga vector int handler get the req mask instead of irq vector
|
||
- lea CUSTOMBASE,%a1
|
||
- movew %a1@(C_INTREQR),%d0
|
||
- andw %a1@(C_INTENAR),%d0
|
||
-
|
||
-| prepare stack (push frame pointer, dev_id & req mask)
|
||
- pea %sp@
|
||
- movel %a0@(IRQ_DEVID),%sp@-
|
||
- movel %d0,%sp@-
|
||
- pea %pc@(ret_from_interrupt:w)
|
||
- jbra @(IRQ_HANDLER,%a0)@(0)
|
||
-
|
||
-ENTRY(nmi_handler)
|
||
- rte
|
||
-#endif
|
||
-#endif
|
||
-
|
||
-/*
|
||
-** This is the main interrupt handler, responsible for calling process_int()
|
||
-*/
|
||
-inthandler:
|
||
+ENTRY(auto_inthandler)
|
||
SAVE_ALL_INT
|
||
GET_CURRENT(%d0)
|
||
- addqb #1,%curptr@(TASK_INFO+TINFO_PREEMPT+2)
|
||
+ addqb #1,%curptr@(TASK_INFO+TINFO_PREEMPT+1)
|
||
| put exception # in d0
|
||
- bfextu %sp@(PT_VECTOR){#4,#10},%d0
|
||
+ bfextu %sp@(PT_VECTOR){#4,#10},%d0
|
||
+ subw #VEC_SPUR,%d0
|
||
|
||
movel %sp,%sp@-
|
||
movel %d0,%sp@- | put vector # on stack
|
||
-#if defined(MACH_Q40_ONLY) && defined(CONFIG_BLK_DEV_FD)
|
||
- btstb #4,0xff000000 | Q40 floppy needs very special treatment ...
|
||
- jbeq 1f
|
||
- btstb #3,0xff000004
|
||
- jbeq 1f
|
||
- jbsr floppy_hardint
|
||
- jbra 3f
|
||
-1:
|
||
-#endif
|
||
- jbsr process_int | process the IRQ
|
||
-3: addql #8,%sp | pop parameters off stack
|
||
+auto_irqhandler_fixup = . + 2
|
||
+ jsr m68k_handle_int | process the IRQ
|
||
+ addql #8,%sp | pop parameters off stack
|
||
|
||
ret_from_interrupt:
|
||
- subqb #1,%curptr@(TASK_INFO+TINFO_PREEMPT+2)
|
||
- jeq 1f
|
||
-2:
|
||
- RESTORE_ALL
|
||
-1:
|
||
+ subqb #1,%curptr@(TASK_INFO+TINFO_PREEMPT+1)
|
||
+ jeq ret_from_last_interrupt
|
||
+2: RESTORE_ALL
|
||
+
|
||
+ ALIGN
|
||
+ret_from_last_interrupt:
|
||
moveq #(~ALLOWINT>>8)&0xff,%d0
|
||
andb %sp@(PT_SR),%d0
|
||
jne 2b
|
||
@@ -260,12 +226,42 @@
|
||
pea ret_from_exception
|
||
jra do_softirq
|
||
|
||
+/* Handler for user defined interrupt vectors */
|
||
+
|
||
+ENTRY(user_inthandler)
|
||
+ SAVE_ALL_INT
|
||
+ GET_CURRENT(%d0)
|
||
+ addqb #1,%curptr@(TASK_INFO+TINFO_PREEMPT+1)
|
||
+ | put exception # in d0
|
||
+ bfextu %sp@(PT_VECTOR){#4,#10},%d0
|
||
+user_irqvec_fixup = . + 2
|
||
+ subw #VEC_USER,%d0
|
||
+
|
||
+ movel %sp,%sp@-
|
||
+ movel %d0,%sp@- | put vector # on stack
|
||
+user_irqhandler_fixup = . + 2
|
||
+ jsr m68k_handle_int | process the IRQ
|
||
+ addql #8,%sp | pop parameters off stack
|
||
+
|
||
+ subqb #1,%curptr@(TASK_INFO+TINFO_PREEMPT+1)
|
||
+ jeq ret_from_last_interrupt
|
||
+ RESTORE_ALL
|
||
|
||
/* Handler for uninitialized and spurious interrupts */
|
||
|
||
-bad_interrupt:
|
||
- addql #1,num_spurious
|
||
- rte
|
||
+ENTRY(bad_inthandler)
|
||
+ SAVE_ALL_INT
|
||
+ GET_CURRENT(%d0)
|
||
+ addqb #1,%curptr@(TASK_INFO+TINFO_PREEMPT+1)
|
||
+
|
||
+ movel %sp,%sp@-
|
||
+ jsr handle_badint
|
||
+ addql #4,%sp
|
||
+
|
||
+ subqb #1,%curptr@(TASK_INFO+TINFO_PREEMPT+1)
|
||
+ jeq ret_from_last_interrupt
|
||
+ RESTORE_ALL
|
||
+
|
||
|
||
ENTRY(sys_fork)
|
||
SAVE_SWITCH_STACK
|
||
@@ -711,4 +707,9 @@
|
||
.long sys_add_key
|
||
.long sys_request_key /* 280 */
|
||
.long sys_keyctl
|
||
+ .long sys_ioprio_set
|
||
+ .long sys_ioprio_get
|
||
+ .long sys_inotify_init
|
||
+ .long sys_inotify_add_watch /* 285 */
|
||
+ .long sys_inotify_rm_watch
|
||
|
||
diff -urN linux-i386/arch/m68k/kernel/ints.c linux-m68k/arch/m68k/kernel/ints.c
|
||
--- linux-i386/arch/m68k/kernel/ints.c 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/arch/m68k/kernel/ints.c 2006-01-31 01:57:35.000000000 +0100
|
||
@@ -39,47 +39,40 @@
|
||
#include <asm/traps.h>
|
||
#include <asm/page.h>
|
||
#include <asm/machdep.h>
|
||
+#include <asm/cacheflush.h>
|
||
|
||
#ifdef CONFIG_Q40
|
||
#include <asm/q40ints.h>
|
||
#endif
|
||
|
||
-/* table for system interrupt handlers */
|
||
-static irq_handler_t irq_list[SYS_IRQS];
|
||
+extern u32 auto_irqhandler_fixup[];
|
||
+extern u32 user_irqhandler_fixup[];
|
||
+extern u16 user_irqvec_fixup[];
|
||
|
||
-static const char *default_names[SYS_IRQS] = {
|
||
- [0] = "spurious int",
|
||
- [1] = "int1 handler",
|
||
- [2] = "int2 handler",
|
||
- [3] = "int3 handler",
|
||
- [4] = "int4 handler",
|
||
- [5] = "int5 handler",
|
||
- [6] = "int6 handler",
|
||
- [7] = "int7 handler"
|
||
+/* table for system interrupt handlers */
|
||
+static struct irq_node *irq_list[NR_IRQS];
|
||
+static struct irq_controller *irq_controller[NR_IRQS];
|
||
+static int irq_depth[NR_IRQS];
|
||
+
|
||
+static int m68k_first_user_vec;
|
||
+
|
||
+static struct irq_controller auto_irq_controller = {
|
||
+ .name = "auto",
|
||
+ .lock = SPIN_LOCK_UNLOCKED,
|
||
+ .startup = m68k_irq_startup,
|
||
+ .shutdown = m68k_irq_shutdown,
|
||
};
|
||
|
||
-/* The number of spurious interrupts */
|
||
-volatile unsigned int num_spurious;
|
||
+static struct irq_controller user_irq_controller = {
|
||
+ .name = "user",
|
||
+ .lock = SPIN_LOCK_UNLOCKED,
|
||
+ .startup = m68k_irq_startup,
|
||
+ .shutdown = m68k_irq_shutdown,
|
||
+};
|
||
|
||
#define NUM_IRQ_NODES 100
|
||
static irq_node_t nodes[NUM_IRQ_NODES];
|
||
|
||
-static void dummy_enable_irq(unsigned int irq);
|
||
-static void dummy_disable_irq(unsigned int irq);
|
||
-static int dummy_request_irq(unsigned int irq,
|
||
- irqreturn_t (*handler) (int, void *, struct pt_regs *),
|
||
- unsigned long flags, const char *devname, void *dev_id);
|
||
-static void dummy_free_irq(unsigned int irq, void *dev_id);
|
||
-
|
||
-void (*enable_irq) (unsigned int) = dummy_enable_irq;
|
||
-void (*disable_irq) (unsigned int) = dummy_disable_irq;
|
||
-
|
||
-int (*mach_request_irq) (unsigned int, irqreturn_t (*)(int, void *, struct pt_regs *),
|
||
- unsigned long, const char *, void *) = dummy_request_irq;
|
||
-void (*mach_free_irq) (unsigned int, void *) = dummy_free_irq;
|
||
-
|
||
-void init_irq_proc(void);
|
||
-
|
||
/*
|
||
* void init_IRQ(void)
|
||
*
|
||
@@ -95,18 +88,76 @@
|
||
{
|
||
int i;
|
||
|
||
- for (i = 0; i < SYS_IRQS; i++) {
|
||
- if (mach_default_handler)
|
||
- irq_list[i].handler = (*mach_default_handler)[i];
|
||
- irq_list[i].flags = 0;
|
||
- irq_list[i].dev_id = NULL;
|
||
- irq_list[i].devname = default_names[i];
|
||
+ /* assembly irq entry code relies on this... */
|
||
+ if (HARDIRQ_MASK != 0x00ff0000) {
|
||
+ extern void hardirq_mask_is_broken(void);
|
||
+ hardirq_mask_is_broken();
|
||
}
|
||
|
||
- for (i = 0; i < NUM_IRQ_NODES; i++)
|
||
- nodes[i].handler = NULL;
|
||
+ for (i = IRQ_AUTO_1; i < IRQ_USER; i++)
|
||
+ irq_controller[i] = &auto_irq_controller;
|
||
+
|
||
+ mach_init_IRQ();
|
||
+}
|
||
+
|
||
+/**
|
||
+ * m68k_setup_auto_interrupt
|
||
+ * @handler: called from auto vector interrupts
|
||
+ *
|
||
+ * setup the handler to be called from auto vector interrupts instead of the
|
||
+ * standard m68k_handle_int(), it will be called with irq numbers in the range
|
||
+ * from IRQ_AUTO_1 - IRQ_AUTO_7.
|
||
+ */
|
||
+void __init m68k_setup_auto_interrupt(void (*handler)(unsigned int, struct pt_regs *))
|
||
+{
|
||
+ if (handler)
|
||
+ *auto_irqhandler_fixup = (u32)handler;
|
||
+ flush_icache();
|
||
+}
|
||
+
|
||
+/**
|
||
+ * m68k_setup_user_interrupt
|
||
+ * @vec: first user vector interrupt to handle
|
||
+ * @cnt: number of active user vector interrupts
|
||
+ * @handler: called from user vector interrupts
|
||
+ *
|
||
+ * setup user vector interrupts, this includes activating the specified range
|
||
+ * of interrupts, only then these interrupts can be requested (note: this is
|
||
+ * different from auto vector interrupts). An optional handler can be installed
|
||
+ * to be called instead of the default m68k_handle_int(), it will be called
|
||
+ * with irq numbers starting from IRQ_USER.
|
||
+ */
|
||
+void __init m68k_setup_user_interrupt(unsigned int vec, unsigned int cnt,
|
||
+ void (*handler)(unsigned int, struct pt_regs *))
|
||
+{
|
||
+ int i;
|
||
+
|
||
+ m68k_first_user_vec = vec;
|
||
+ for (i = 0; i < cnt; i++)
|
||
+ irq_controller[IRQ_USER + i] = &user_irq_controller;
|
||
+ *user_irqvec_fixup = vec - IRQ_USER;
|
||
+ if (handler)
|
||
+ *user_irqhandler_fixup = (u32)handler;
|
||
+ flush_icache();
|
||
+}
|
||
+
|
||
+/**
|
||
+ * m68k_setup_irq_controller
|
||
+ * @contr: irq controller which controls specified irq
|
||
+ * @irq: first irq to be managed by the controller
|
||
+ *
|
||
+ * Change the controller for the specified range of irq, which will be used to
|
||
+ * manage these irq. auto/user irq already have a default controller, which can
|
||
+ * be changed as well, but the controller probably should use m68k_irq_startup/
|
||
+ * m68k_irq_shutdown.
|
||
+ */
|
||
+void m68k_setup_irq_controller(struct irq_controller *contr, unsigned int irq,
|
||
+ unsigned int cnt)
|
||
+{
|
||
+ int i;
|
||
|
||
- mach_init_IRQ ();
|
||
+ for (i = 0; i < cnt; i++)
|
||
+ irq_controller[irq + i] = contr;
|
||
}
|
||
|
||
irq_node_t *new_irq_node(void)
|
||
@@ -114,84 +165,183 @@
|
||
irq_node_t *node;
|
||
short i;
|
||
|
||
- for (node = nodes, i = NUM_IRQ_NODES-1; i >= 0; node++, i--)
|
||
- if (!node->handler)
|
||
+ for (node = nodes, i = NUM_IRQ_NODES-1; i >= 0; node++, i--) {
|
||
+ if (!node->handler) {
|
||
+ memset(node, 0, sizeof(*node));
|
||
return node;
|
||
+ }
|
||
+ }
|
||
|
||
printk ("new_irq_node: out of nodes\n");
|
||
return NULL;
|
||
}
|
||
|
||
-/*
|
||
- * We will keep these functions until I have convinced Linus to move
|
||
- * the declaration of them from include/linux/sched.h to
|
||
- * include/asm/irq.h.
|
||
- */
|
||
+int setup_irq(unsigned int irq, struct irq_node *node)
|
||
+{
|
||
+ struct irq_controller *contr;
|
||
+ struct irq_node **prev;
|
||
+ unsigned long flags;
|
||
+
|
||
+ if (irq >= NR_IRQS || !(contr = irq_controller[irq])) {
|
||
+ printk("%s: Incorrect IRQ %d from %s\n",
|
||
+ __FUNCTION__, irq, node->devname);
|
||
+ return -ENXIO;
|
||
+ }
|
||
+
|
||
+ spin_lock_irqsave(&contr->lock, flags);
|
||
+
|
||
+ prev = irq_list + irq;
|
||
+ if (*prev) {
|
||
+ /* Can't share interrupts unless both agree to */
|
||
+ if (!((*prev)->flags & node->flags & SA_SHIRQ)) {
|
||
+ spin_unlock_irqrestore(&contr->lock, flags);
|
||
+ return -EBUSY;
|
||
+ }
|
||
+ while (*prev)
|
||
+ prev = &(*prev)->next;
|
||
+ }
|
||
+
|
||
+ if (!irq_list[irq]) {
|
||
+ if (contr->startup)
|
||
+ contr->startup(irq);
|
||
+ else
|
||
+ contr->enable(irq);
|
||
+ }
|
||
+ node->next = NULL;
|
||
+ *prev = node;
|
||
+
|
||
+ spin_unlock_irqrestore(&contr->lock, flags);
|
||
+
|
||
+ return 0;
|
||
+}
|
||
+
|
||
int request_irq(unsigned int irq,
|
||
irqreturn_t (*handler) (int, void *, struct pt_regs *),
|
||
unsigned long flags, const char *devname, void *dev_id)
|
||
{
|
||
- return mach_request_irq(irq, handler, flags, devname, dev_id);
|
||
+ struct irq_node *node;
|
||
+ int res;
|
||
+
|
||
+ node = new_irq_node();
|
||
+ if (!node)
|
||
+ return -ENOMEM;
|
||
+
|
||
+ node->handler = handler;
|
||
+ node->flags = flags;
|
||
+ node->dev_id = dev_id;
|
||
+ node->devname = devname;
|
||
+
|
||
+ res = setup_irq(irq, node);
|
||
+ if (res)
|
||
+ node->handler = NULL;
|
||
+
|
||
+ return res;
|
||
}
|
||
|
||
EXPORT_SYMBOL(request_irq);
|
||
|
||
void free_irq(unsigned int irq, void *dev_id)
|
||
{
|
||
- mach_free_irq(irq, dev_id);
|
||
+ struct irq_controller *contr;
|
||
+ struct irq_node **p, *node;
|
||
+ unsigned long flags;
|
||
+
|
||
+ if (irq >= NR_IRQS || !(contr = irq_controller[irq])) {
|
||
+ printk("%s: Incorrect IRQ %d\n", __FUNCTION__, irq);
|
||
+ return;
|
||
+ }
|
||
+
|
||
+ spin_lock_irqsave(&contr->lock, flags);
|
||
+
|
||
+ p = irq_list + irq;
|
||
+ while ((node = *p)) {
|
||
+ if (node->dev_id == dev_id)
|
||
+ break;
|
||
+ p = &node->next;
|
||
+ }
|
||
+
|
||
+ if (node) {
|
||
+ *p = node->next;
|
||
+ node->handler = NULL;
|
||
+ } else
|
||
+ printk("%s: Removing probably wrong IRQ %d\n",
|
||
+ __FUNCTION__, irq);
|
||
+
|
||
+ if (!irq_list[irq]) {
|
||
+ if (contr->shutdown)
|
||
+ contr->shutdown(irq);
|
||
+ else
|
||
+ contr->disable(irq);
|
||
+ }
|
||
+
|
||
+ spin_unlock_irqrestore(&contr->lock, flags);
|
||
}
|
||
|
||
EXPORT_SYMBOL(free_irq);
|
||
|
||
-int cpu_request_irq(unsigned int irq,
|
||
- irqreturn_t (*handler)(int, void *, struct pt_regs *),
|
||
- unsigned long flags, const char *devname, void *dev_id)
|
||
+void enable_irq(unsigned int irq)
|
||
{
|
||
- if (irq < IRQ1 || irq > IRQ7) {
|
||
- printk("%s: Incorrect IRQ %d from %s\n",
|
||
- __FUNCTION__, irq, devname);
|
||
- return -ENXIO;
|
||
- }
|
||
+ struct irq_controller *contr;
|
||
+ unsigned long flags;
|
||
|
||
-#if 0
|
||
- if (!(irq_list[irq].flags & IRQ_FLG_STD)) {
|
||
- if (irq_list[irq].flags & IRQ_FLG_LOCK) {
|
||
- printk("%s: IRQ %d from %s is not replaceable\n",
|
||
- __FUNCTION__, irq, irq_list[irq].devname);
|
||
- return -EBUSY;
|
||
- }
|
||
- if (!(flags & IRQ_FLG_REPLACE)) {
|
||
- printk("%s: %s can't replace IRQ %d from %s\n",
|
||
- __FUNCTION__, devname, irq, irq_list[irq].devname);
|
||
- return -EBUSY;
|
||
- }
|
||
+ if (irq >= NR_IRQS || !(contr = irq_controller[irq])) {
|
||
+ printk("%s: Incorrect IRQ %d\n",
|
||
+ __FUNCTION__, irq);
|
||
+ return;
|
||
}
|
||
-#endif
|
||
|
||
- irq_list[irq].handler = handler;
|
||
- irq_list[irq].flags = flags;
|
||
- irq_list[irq].dev_id = dev_id;
|
||
- irq_list[irq].devname = devname;
|
||
- return 0;
|
||
+ spin_lock_irqsave(&contr->lock, flags);
|
||
+ if (irq_depth[irq]) {
|
||
+ if (!--irq_depth[irq]) {
|
||
+ if (contr->enable)
|
||
+ contr->enable(irq);
|
||
+ }
|
||
+ } else
|
||
+ WARN_ON(1);
|
||
+ spin_unlock_irqrestore(&contr->lock, flags);
|
||
}
|
||
|
||
-void cpu_free_irq(unsigned int irq, void *dev_id)
|
||
+EXPORT_SYMBOL(enable_irq);
|
||
+
|
||
+void disable_irq(unsigned int irq)
|
||
{
|
||
- if (irq < IRQ1 || irq > IRQ7) {
|
||
- printk("%s: Incorrect IRQ %d\n", __FUNCTION__, irq);
|
||
+ struct irq_controller *contr;
|
||
+ unsigned long flags;
|
||
+
|
||
+ if (irq >= NR_IRQS || !(contr = irq_controller[irq])) {
|
||
+ printk("%s: Incorrect IRQ %d\n",
|
||
+ __FUNCTION__, irq);
|
||
return;
|
||
}
|
||
|
||
- if (irq_list[irq].dev_id != dev_id)
|
||
- printk("%s: Removing probably wrong IRQ %d from %s\n",
|
||
- __FUNCTION__, irq, irq_list[irq].devname);
|
||
-
|
||
- irq_list[irq].handler = (*mach_default_handler)[irq];
|
||
- irq_list[irq].flags = 0;
|
||
- irq_list[irq].dev_id = NULL;
|
||
- irq_list[irq].devname = default_names[irq];
|
||
+ spin_lock_irqsave(&contr->lock, flags);
|
||
+ if (!irq_depth[irq]++) {
|
||
+ if (contr->disable)
|
||
+ contr->disable(irq);
|
||
+ }
|
||
+ spin_unlock_irqrestore(&contr->lock, flags);
|
||
+}
|
||
+
|
||
+EXPORT_SYMBOL(disable_irq);
|
||
+
|
||
+int m68k_irq_startup(unsigned int irq)
|
||
+{
|
||
+ if (irq < IRQ_USER)
|
||
+ vectors[VEC_SPUR + irq] = auto_inthandler;
|
||
+ else
|
||
+ vectors[m68k_first_user_vec + irq - IRQ_USER] = user_inthandler;
|
||
+ return 0;
|
||
}
|
||
|
||
+void m68k_irq_shutdown(unsigned int irq)
|
||
+{
|
||
+ if (irq < IRQ_USER)
|
||
+ vectors[VEC_SPUR + irq] = bad_inthandler;
|
||
+ else
|
||
+ vectors[m68k_first_user_vec + irq - IRQ_USER] = bad_inthandler;
|
||
+}
|
||
+
|
||
+
|
||
/*
|
||
* Do we need these probe functions on the m68k?
|
||
*
|
||
@@ -219,58 +369,50 @@
|
||
|
||
EXPORT_SYMBOL(probe_irq_off);
|
||
|
||
-static void dummy_enable_irq(unsigned int irq)
|
||
+unsigned int irq_canonicalize(unsigned int irq)
|
||
{
|
||
- printk("calling uninitialized enable_irq()\n");
|
||
+#ifdef CONFIG_Q40
|
||
+ if (MACH_IS_Q40 && irq == 11)
|
||
+ irq = 10;
|
||
+#endif
|
||
+ return irq;
|
||
}
|
||
|
||
-static void dummy_disable_irq(unsigned int irq)
|
||
-{
|
||
- printk("calling uninitialized disable_irq()\n");
|
||
-}
|
||
+EXPORT_SYMBOL(irq_canonicalize);
|
||
|
||
-static int dummy_request_irq(unsigned int irq,
|
||
- irqreturn_t (*handler) (int, void *, struct pt_regs *),
|
||
- unsigned long flags, const char *devname, void *dev_id)
|
||
+asmlinkage void m68k_handle_int(unsigned int irq, struct pt_regs *regs)
|
||
{
|
||
- printk("calling uninitialized request_irq()\n");
|
||
- return 0;
|
||
-}
|
||
+ struct irq_node *node;
|
||
|
||
-static void dummy_free_irq(unsigned int irq, void *dev_id)
|
||
-{
|
||
- printk("calling uninitialized disable_irq()\n");
|
||
+ kstat_cpu(0).irqs[irq]++;
|
||
+ node = irq_list[irq];
|
||
+ do {
|
||
+ node->handler(irq, node->dev_id, regs);
|
||
+ node = node->next;
|
||
+ } while (node);
|
||
}
|
||
|
||
-asmlinkage void process_int(unsigned long vec, struct pt_regs *fp)
|
||
+asmlinkage void handle_badint(struct pt_regs *regs)
|
||
{
|
||
- if (vec >= VEC_INT1 && vec <= VEC_INT7 && !MACH_IS_BVME6000) {
|
||
- vec -= VEC_SPUR;
|
||
- kstat_cpu(0).irqs[vec]++;
|
||
- irq_list[vec].handler(vec, irq_list[vec].dev_id, fp);
|
||
- } else {
|
||
- if (mach_process_int)
|
||
- mach_process_int(vec, fp);
|
||
- else
|
||
- panic("Can't process interrupt vector %ld\n", vec);
|
||
- return;
|
||
- }
|
||
+ kstat_cpu(0).irqs[0]++;
|
||
+ printk("unexpected interrupt from %u\n", regs->vector);
|
||
}
|
||
|
||
int show_interrupts(struct seq_file *p, void *v)
|
||
{
|
||
+ struct irq_controller *contr;
|
||
+ struct irq_node *node;
|
||
int i = *(loff_t *) v;
|
||
|
||
/* autovector interrupts */
|
||
- if (i < SYS_IRQS) {
|
||
- if (mach_default_handler) {
|
||
- seq_printf(p, "auto %2d: %10u ", i,
|
||
- i ? kstat_cpu(0).irqs[i] : num_spurious);
|
||
- seq_puts(p, " ");
|
||
- seq_printf(p, "%s\n", irq_list[i].devname);
|
||
- }
|
||
- } else if (i == SYS_IRQS)
|
||
- mach_get_irq_list(p, v);
|
||
+ if (irq_list[i]) {
|
||
+ contr = irq_controller[i];
|
||
+ node = irq_list[i];
|
||
+ seq_printf(p, "%-8s %3u: %10u %s", contr->name, i, kstat_cpu(0).irqs[i], node->devname);
|
||
+ while ((node = node->next))
|
||
+ seq_printf(p, ", %s", node->devname);
|
||
+ seq_puts(p, "\n");
|
||
+ }
|
||
return 0;
|
||
}
|
||
|
||
diff -urN linux-i386/arch/m68k/kernel/m68k_ksyms.c linux-m68k/arch/m68k/kernel/m68k_ksyms.c
|
||
--- linux-i386/arch/m68k/kernel/m68k_ksyms.c 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/arch/m68k/kernel/m68k_ksyms.c 2006-06-18 19:06:44.000000000 +0200
|
||
@@ -57,8 +57,6 @@
|
||
EXPORT_SYMBOL(strnlen);
|
||
EXPORT_SYMBOL(strrchr);
|
||
EXPORT_SYMBOL(strstr);
|
||
-EXPORT_SYMBOL(enable_irq);
|
||
-EXPORT_SYMBOL(disable_irq);
|
||
EXPORT_SYMBOL(kernel_thread);
|
||
#ifdef CONFIG_VME
|
||
EXPORT_SYMBOL(vme_brdtype);
|
||
diff -urN linux-i386/arch/m68k/kernel/module.c linux-m68k/arch/m68k/kernel/module.c
|
||
--- linux-i386/arch/m68k/kernel/module.c 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/arch/m68k/kernel/module.c 2006-06-06 01:17:28.000000000 +0200
|
||
@@ -1,3 +1,9 @@
|
||
+/*
|
||
+ * This file is subject to the terms and conditions of the GNU General Public
|
||
+ * License. See the file COPYING in the main directory of this archive
|
||
+ * for more details.
|
||
+ */
|
||
+
|
||
#include <linux/moduleloader.h>
|
||
#include <linux/elf.h>
|
||
#include <linux/vmalloc.h>
|
||
@@ -116,10 +122,26 @@
|
||
return 0;
|
||
}
|
||
|
||
+void module_fixup(struct module *mod, struct m68k_fixup_info *start,
|
||
+ struct m68k_fixup_info *end)
|
||
+{
|
||
+ struct m68k_fixup_info *fixup;
|
||
+
|
||
+ for (fixup = start; fixup < end; fixup++) {
|
||
+ switch (fixup->type) {
|
||
+ case m68k_fixup_memoffset:
|
||
+ *(u32 *)fixup->addr = m68k_memoffset;
|
||
+ break;
|
||
+ }
|
||
+ }
|
||
+}
|
||
+
|
||
int module_finalize(const Elf_Ehdr *hdr,
|
||
const Elf_Shdr *sechdrs,
|
||
- struct module *me)
|
||
+ struct module *mod)
|
||
{
|
||
+ module_fixup(mod, mod->arch.fixup_start, mod->arch.fixup_end);
|
||
+
|
||
return 0;
|
||
}
|
||
|
||
diff -urN linux-i386/arch/m68k/kernel/module.lds linux-m68k/arch/m68k/kernel/module.lds
|
||
--- linux-i386/arch/m68k/kernel/module.lds 1970-01-01 01:00:00.000000000 +0100
|
||
+++ linux-m68k/arch/m68k/kernel/module.lds 2006-06-06 01:17:28.000000000 +0200
|
||
@@ -0,0 +1,7 @@
|
||
+SECTIONS {
|
||
+ .m68k_fixup : {
|
||
+ __start_fixup = .;
|
||
+ *(.m68k_fixup)
|
||
+ __stop_fixup = .;
|
||
+ }
|
||
+}
|
||
diff -urN linux-i386/arch/m68k/kernel/setup.c linux-m68k/arch/m68k/kernel/setup.c
|
||
--- linux-i386/arch/m68k/kernel/setup.c 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/arch/m68k/kernel/setup.c 2006-04-10 00:21:45.000000000 +0200
|
||
@@ -68,11 +68,8 @@
|
||
void (*mach_sched_init) (irqreturn_t (*handler)(int, void *, struct pt_regs *)) __initdata = NULL;
|
||
/* machine dependent irq functions */
|
||
void (*mach_init_IRQ) (void) __initdata = NULL;
|
||
-irqreturn_t (*(*mach_default_handler)[]) (int, void *, struct pt_regs *);
|
||
void (*mach_get_model) (char *model);
|
||
int (*mach_get_hardware_list) (char *buffer);
|
||
-int (*mach_get_irq_list) (struct seq_file *, void *);
|
||
-irqreturn_t (*mach_process_int) (int, struct pt_regs *);
|
||
/* machine dependent timer functions */
|
||
unsigned long (*mach_gettimeoffset) (void);
|
||
int (*mach_hwclk) (int, struct rtc_time*);
|
||
diff -urN linux-i386/arch/m68k/kernel/sun3-head.S linux-m68k/arch/m68k/kernel/sun3-head.S
|
||
--- linux-i386/arch/m68k/kernel/sun3-head.S 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/arch/m68k/kernel/sun3-head.S 2006-05-11 13:14:10.000000000 +0200
|
||
@@ -66,17 +66,7 @@
|
||
/* Following code executes at high addresses (0xE000xxx). */
|
||
1: lea init_task,%curptr | get initial thread...
|
||
lea init_thread_union+THREAD_SIZE,%sp | ...and its stack.
|
||
-
|
||
-/* copy bootinfo records from the loader to _end */
|
||
- lea _end, %a1
|
||
- lea BI_START, %a0
|
||
- /* number of longs to copy */
|
||
- movel %a0@, %d0
|
||
-1: addl #4, %a0
|
||
- movel %a0@, %a1@
|
||
- addl #4, %a1
|
||
- dbf %d0, 1b
|
||
-
|
||
+
|
||
/* Point MSP at an invalid page to trap if it's used. --m */
|
||
movl #(PAGESIZE),%d0
|
||
movc %d0,%msp
|
||
diff -urN linux-i386/arch/m68k/kernel/traps.c linux-m68k/arch/m68k/kernel/traps.c
|
||
--- linux-i386/arch/m68k/kernel/traps.c 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/arch/m68k/kernel/traps.c 2006-06-01 02:34:48.000000000 +0200
|
||
@@ -45,7 +45,6 @@
|
||
asmlinkage void system_call(void);
|
||
asmlinkage void buserr(void);
|
||
asmlinkage void trap(void);
|
||
-asmlinkage void inthandler(void);
|
||
asmlinkage void nmihandler(void);
|
||
#ifdef CONFIG_M68KFPU_EMU
|
||
asmlinkage void fpu_emu(void);
|
||
@@ -53,51 +52,7 @@
|
||
|
||
e_vector vectors[256] = {
|
||
[VEC_BUSERR] = buserr,
|
||
- [VEC_ADDRERR] = trap,
|
||
- [VEC_ILLEGAL] = trap,
|
||
- [VEC_ZERODIV] = trap,
|
||
- [VEC_CHK] = trap,
|
||
- [VEC_TRAP] = trap,
|
||
- [VEC_PRIV] = trap,
|
||
- [VEC_TRACE] = trap,
|
||
- [VEC_LINE10] = trap,
|
||
- [VEC_LINE11] = trap,
|
||
- [VEC_RESV12] = trap,
|
||
- [VEC_COPROC] = trap,
|
||
- [VEC_FORMAT] = trap,
|
||
- [VEC_UNINT] = trap,
|
||
- [VEC_RESV16] = trap,
|
||
- [VEC_RESV17] = trap,
|
||
- [VEC_RESV18] = trap,
|
||
- [VEC_RESV19] = trap,
|
||
- [VEC_RESV20] = trap,
|
||
- [VEC_RESV21] = trap,
|
||
- [VEC_RESV22] = trap,
|
||
- [VEC_RESV23] = trap,
|
||
- [VEC_SPUR] = inthandler,
|
||
- [VEC_INT1] = inthandler,
|
||
- [VEC_INT2] = inthandler,
|
||
- [VEC_INT3] = inthandler,
|
||
- [VEC_INT4] = inthandler,
|
||
- [VEC_INT5] = inthandler,
|
||
- [VEC_INT6] = inthandler,
|
||
- [VEC_INT7] = inthandler,
|
||
[VEC_SYS] = system_call,
|
||
- [VEC_TRAP1] = trap,
|
||
- [VEC_TRAP2] = trap,
|
||
- [VEC_TRAP3] = trap,
|
||
- [VEC_TRAP4] = trap,
|
||
- [VEC_TRAP5] = trap,
|
||
- [VEC_TRAP6] = trap,
|
||
- [VEC_TRAP7] = trap,
|
||
- [VEC_TRAP8] = trap,
|
||
- [VEC_TRAP9] = trap,
|
||
- [VEC_TRAP10] = trap,
|
||
- [VEC_TRAP11] = trap,
|
||
- [VEC_TRAP12] = trap,
|
||
- [VEC_TRAP13] = trap,
|
||
- [VEC_TRAP14] = trap,
|
||
- [VEC_TRAP15] = trap,
|
||
};
|
||
|
||
/* nmi handler for the Amiga */
|
||
@@ -132,12 +87,15 @@
|
||
{
|
||
int i;
|
||
|
||
- for (i = 48; i < 64; i++)
|
||
+ for (i = VEC_SPUR; i <= VEC_INT7; i++)
|
||
+ vectors[i] = bad_inthandler;
|
||
+
|
||
+ for (i = 0; i < VEC_USER; i++)
|
||
if (!vectors[i])
|
||
vectors[i] = trap;
|
||
|
||
- for (i = 64; i < 256; i++)
|
||
- vectors[i] = inthandler;
|
||
+ for (i = VEC_USER; i < 256; i++)
|
||
+ vectors[i] = bad_inthandler;
|
||
|
||
#ifdef CONFIG_M68KFPU_EMU
|
||
if (FPU_IS_EMU)
|
||
@@ -927,71 +885,94 @@
|
||
void show_registers(struct pt_regs *regs)
|
||
{
|
||
struct frame *fp = (struct frame *)regs;
|
||
+ mm_segment_t old_fs = get_fs();
|
||
+ u16 c, *cp;
|
||
unsigned long addr;
|
||
int i;
|
||
|
||
+ print_modules();
|
||
+ printk("PC: [<%08lx>]",regs->pc);
|
||
+ print_symbol(" %s\n", regs->pc);
|
||
+ printk("SR: %04x SP: %p a2: %08lx\n",
|
||
+ regs->sr, regs, regs->a2);
|
||
+ printk("d0: %08lx d1: %08lx d2: %08lx d3: %08lx\n",
|
||
+ regs->d0, regs->d1, regs->d2, regs->d3);
|
||
+ printk("d4: %08lx d5: %08lx a0: %08lx a1: %08lx\n",
|
||
+ regs->d4, regs->d5, regs->a0, regs->a1);
|
||
+
|
||
+ printk("Process %s (pid: %d, task=%p)\n",
|
||
+ current->comm, current->pid, current);
|
||
addr = (unsigned long)&fp->un;
|
||
- printk("Frame format=%X ", fp->ptregs.format);
|
||
- switch (fp->ptregs.format) {
|
||
+ printk("Frame format=%X ", regs->format);
|
||
+ switch (regs->format) {
|
||
case 0x2:
|
||
- printk("instr addr=%08lx\n", fp->un.fmt2.iaddr);
|
||
- addr += sizeof(fp->un.fmt2);
|
||
- break;
|
||
+ printk("instr addr=%08lx\n", fp->un.fmt2.iaddr);
|
||
+ addr += sizeof(fp->un.fmt2);
|
||
+ break;
|
||
case 0x3:
|
||
- printk("eff addr=%08lx\n", fp->un.fmt3.effaddr);
|
||
- addr += sizeof(fp->un.fmt3);
|
||
- break;
|
||
+ printk("eff addr=%08lx\n", fp->un.fmt3.effaddr);
|
||
+ addr += sizeof(fp->un.fmt3);
|
||
+ break;
|
||
case 0x4:
|
||
- printk((CPU_IS_060 ? "fault addr=%08lx fslw=%08lx\n"
|
||
- : "eff addr=%08lx pc=%08lx\n"),
|
||
- fp->un.fmt4.effaddr, fp->un.fmt4.pc);
|
||
- addr += sizeof(fp->un.fmt4);
|
||
- break;
|
||
+ printk((CPU_IS_060 ? "fault addr=%08lx fslw=%08lx\n"
|
||
+ : "eff addr=%08lx pc=%08lx\n"),
|
||
+ fp->un.fmt4.effaddr, fp->un.fmt4.pc);
|
||
+ addr += sizeof(fp->un.fmt4);
|
||
+ break;
|
||
case 0x7:
|
||
- printk("eff addr=%08lx ssw=%04x faddr=%08lx\n",
|
||
- fp->un.fmt7.effaddr, fp->un.fmt7.ssw, fp->un.fmt7.faddr);
|
||
- printk("wb 1 stat/addr/data: %04x %08lx %08lx\n",
|
||
- fp->un.fmt7.wb1s, fp->un.fmt7.wb1a, fp->un.fmt7.wb1dpd0);
|
||
- printk("wb 2 stat/addr/data: %04x %08lx %08lx\n",
|
||
- fp->un.fmt7.wb2s, fp->un.fmt7.wb2a, fp->un.fmt7.wb2d);
|
||
- printk("wb 3 stat/addr/data: %04x %08lx %08lx\n",
|
||
- fp->un.fmt7.wb3s, fp->un.fmt7.wb3a, fp->un.fmt7.wb3d);
|
||
- printk("push data: %08lx %08lx %08lx %08lx\n",
|
||
- fp->un.fmt7.wb1dpd0, fp->un.fmt7.pd1, fp->un.fmt7.pd2,
|
||
- fp->un.fmt7.pd3);
|
||
- addr += sizeof(fp->un.fmt7);
|
||
- break;
|
||
+ printk("eff addr=%08lx ssw=%04x faddr=%08lx\n",
|
||
+ fp->un.fmt7.effaddr, fp->un.fmt7.ssw, fp->un.fmt7.faddr);
|
||
+ printk("wb 1 stat/addr/data: %04x %08lx %08lx\n",
|
||
+ fp->un.fmt7.wb1s, fp->un.fmt7.wb1a, fp->un.fmt7.wb1dpd0);
|
||
+ printk("wb 2 stat/addr/data: %04x %08lx %08lx\n",
|
||
+ fp->un.fmt7.wb2s, fp->un.fmt7.wb2a, fp->un.fmt7.wb2d);
|
||
+ printk("wb 3 stat/addr/data: %04x %08lx %08lx\n",
|
||
+ fp->un.fmt7.wb3s, fp->un.fmt7.wb3a, fp->un.fmt7.wb3d);
|
||
+ printk("push data: %08lx %08lx %08lx %08lx\n",
|
||
+ fp->un.fmt7.wb1dpd0, fp->un.fmt7.pd1, fp->un.fmt7.pd2,
|
||
+ fp->un.fmt7.pd3);
|
||
+ addr += sizeof(fp->un.fmt7);
|
||
+ break;
|
||
case 0x9:
|
||
- printk("instr addr=%08lx\n", fp->un.fmt9.iaddr);
|
||
- addr += sizeof(fp->un.fmt9);
|
||
- break;
|
||
+ printk("instr addr=%08lx\n", fp->un.fmt9.iaddr);
|
||
+ addr += sizeof(fp->un.fmt9);
|
||
+ break;
|
||
case 0xa:
|
||
- printk("ssw=%04x isc=%04x isb=%04x daddr=%08lx dobuf=%08lx\n",
|
||
- fp->un.fmta.ssw, fp->un.fmta.isc, fp->un.fmta.isb,
|
||
- fp->un.fmta.daddr, fp->un.fmta.dobuf);
|
||
- addr += sizeof(fp->un.fmta);
|
||
- break;
|
||
+ printk("ssw=%04x isc=%04x isb=%04x daddr=%08lx dobuf=%08lx\n",
|
||
+ fp->un.fmta.ssw, fp->un.fmta.isc, fp->un.fmta.isb,
|
||
+ fp->un.fmta.daddr, fp->un.fmta.dobuf);
|
||
+ addr += sizeof(fp->un.fmta);
|
||
+ break;
|
||
case 0xb:
|
||
- printk("ssw=%04x isc=%04x isb=%04x daddr=%08lx dobuf=%08lx\n",
|
||
- fp->un.fmtb.ssw, fp->un.fmtb.isc, fp->un.fmtb.isb,
|
||
- fp->un.fmtb.daddr, fp->un.fmtb.dobuf);
|
||
- printk("baddr=%08lx dibuf=%08lx ver=%x\n",
|
||
- fp->un.fmtb.baddr, fp->un.fmtb.dibuf, fp->un.fmtb.ver);
|
||
- addr += sizeof(fp->un.fmtb);
|
||
- break;
|
||
+ printk("ssw=%04x isc=%04x isb=%04x daddr=%08lx dobuf=%08lx\n",
|
||
+ fp->un.fmtb.ssw, fp->un.fmtb.isc, fp->un.fmtb.isb,
|
||
+ fp->un.fmtb.daddr, fp->un.fmtb.dobuf);
|
||
+ printk("baddr=%08lx dibuf=%08lx ver=%x\n",
|
||
+ fp->un.fmtb.baddr, fp->un.fmtb.dibuf, fp->un.fmtb.ver);
|
||
+ addr += sizeof(fp->un.fmtb);
|
||
+ break;
|
||
default:
|
||
- printk("\n");
|
||
+ printk("\n");
|
||
}
|
||
show_stack(NULL, (unsigned long *)addr);
|
||
|
||
- printk("Code: ");
|
||
- for (i = 0; i < 10; i++)
|
||
- printk("%04x ", 0xffff & ((short *) fp->ptregs.pc)[i]);
|
||
+ printk("Code:");
|
||
+ set_fs(KERNEL_DS);
|
||
+ cp = (u16 *)regs->pc;
|
||
+ for (i = -8; i < 16; i++) {
|
||
+ if (get_user(c, cp + i) && i >= 0) {
|
||
+ printk(" Bad PC value.");
|
||
+ break;
|
||
+ }
|
||
+ printk(i ? " %04x" : " <%04x>", c);
|
||
+ }
|
||
+ set_fs(old_fs);
|
||
printk ("\n");
|
||
}
|
||
|
||
void show_stack(struct task_struct *task, unsigned long *stack)
|
||
{
|
||
+ unsigned long *p;
|
||
unsigned long *endstack;
|
||
int i;
|
||
|
||
@@ -1004,12 +985,13 @@
|
||
endstack = (unsigned long *)(((unsigned long)stack + THREAD_SIZE - 1) & -THREAD_SIZE);
|
||
|
||
printk("Stack from %08lx:", (unsigned long)stack);
|
||
+ p = stack;
|
||
for (i = 0; i < kstack_depth_to_print; i++) {
|
||
- if (stack + 1 > endstack)
|
||
+ if (p + 1 > endstack)
|
||
break;
|
||
if (i % 8 == 0)
|
||
printk("\n ");
|
||
- printk(" %08lx", *stack++);
|
||
+ printk(" %08lx", *p++);
|
||
}
|
||
printk("\n");
|
||
show_trace(stack);
|
||
@@ -1188,19 +1170,7 @@
|
||
|
||
console_verbose();
|
||
printk("%s: %08x\n",str,nr);
|
||
- print_modules();
|
||
- printk("PC: [<%08lx>]",fp->pc);
|
||
- print_symbol(" %s\n", fp->pc);
|
||
- printk("\nSR: %04x SP: %p a2: %08lx\n",
|
||
- fp->sr, fp, fp->a2);
|
||
- printk("d0: %08lx d1: %08lx d2: %08lx d3: %08lx\n",
|
||
- fp->d0, fp->d1, fp->d2, fp->d3);
|
||
- printk("d4: %08lx d5: %08lx a0: %08lx a1: %08lx\n",
|
||
- fp->d4, fp->d5, fp->a0, fp->a1);
|
||
-
|
||
- printk("Process %s (pid: %d, stackpage=%08lx)\n",
|
||
- current->comm, current->pid, PAGE_SIZE+(unsigned long)current);
|
||
- show_stack(NULL, (unsigned long *)fp);
|
||
+ show_registers(fp);
|
||
do_exit(SIGSEGV);
|
||
}
|
||
|
||
diff -urN linux-i386/arch/m68k/kernel/vmlinux-std.lds linux-m68k/arch/m68k/kernel/vmlinux-std.lds
|
||
--- linux-i386/arch/m68k/kernel/vmlinux-std.lds 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/arch/m68k/kernel/vmlinux-std.lds 2006-06-06 01:17:28.000000000 +0200
|
||
@@ -66,6 +66,11 @@
|
||
__con_initcall_start = .;
|
||
.con_initcall.init : { *(.con_initcall.init) }
|
||
__con_initcall_end = .;
|
||
+ .m68k_fixup : {
|
||
+ __start_fixup = .;
|
||
+ *(.m68k_fixup)
|
||
+ __stop_fixup = .;
|
||
+ }
|
||
SECURITY_INIT
|
||
. = ALIGN(8192);
|
||
__initramfs_start = .;
|
||
diff -urN linux-i386/arch/m68k/kernel/vmlinux-sun3.lds linux-m68k/arch/m68k/kernel/vmlinux-sun3.lds
|
||
--- linux-i386/arch/m68k/kernel/vmlinux-sun3.lds 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/arch/m68k/kernel/vmlinux-sun3.lds 2006-06-06 01:17:28.000000000 +0200
|
||
@@ -8,7 +8,7 @@
|
||
jiffies = jiffies_64 + 4;
|
||
SECTIONS
|
||
{
|
||
- . = 0xE004000;
|
||
+ . = 0xE002000;
|
||
_text = .; /* Text and read-only data */
|
||
.text : {
|
||
*(.head)
|
||
@@ -60,6 +60,11 @@
|
||
__con_initcall_start = .;
|
||
.con_initcall.init : { *(.con_initcall.init) }
|
||
__con_initcall_end = .;
|
||
+ .m68k_fixup : {
|
||
+ __start_fixup = .;
|
||
+ *(.m68k_fixup)
|
||
+ __stop_fixup = .;
|
||
+ }
|
||
SECURITY_INIT
|
||
. = ALIGN(8192);
|
||
__initramfs_start = .;
|
||
diff -urN linux-i386/arch/m68k/lib/Makefile linux-m68k/arch/m68k/lib/Makefile
|
||
--- linux-i386/arch/m68k/lib/Makefile 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/arch/m68k/lib/Makefile 2006-06-06 00:59:09.000000000 +0200
|
||
@@ -4,5 +4,5 @@
|
||
|
||
EXTRA_AFLAGS := -traditional
|
||
|
||
-lib-y := ashldi3.o ashrdi3.o lshrdi3.o muldi3.o \
|
||
- checksum.o string.o semaphore.o
|
||
+lib-y := ashldi3.o ashrdi3.o lshrdi3.o muldi3.o \
|
||
+ checksum.o string.o semaphore.o uaccess.o
|
||
diff -urN linux-i386/arch/m68k/lib/uaccess.c linux-m68k/arch/m68k/lib/uaccess.c
|
||
--- linux-i386/arch/m68k/lib/uaccess.c 1970-01-01 01:00:00.000000000 +0100
|
||
+++ linux-m68k/arch/m68k/lib/uaccess.c 2006-06-06 00:59:09.000000000 +0200
|
||
@@ -0,0 +1,222 @@
|
||
+/*
|
||
+ * This file is subject to the terms and conditions of the GNU General Public
|
||
+ * License. See the file COPYING in the main directory of this archive
|
||
+ * for more details.
|
||
+ */
|
||
+
|
||
+#include <linux/module.h>
|
||
+#include <asm/uaccess.h>
|
||
+
|
||
+unsigned long __generic_copy_from_user(void *to, const void __user *from,
|
||
+ unsigned long n)
|
||
+{
|
||
+ unsigned long tmp, res;
|
||
+
|
||
+ asm volatile ("\n"
|
||
+ " tst.l %0\n"
|
||
+ " jeq 2f\n"
|
||
+ "1: moves.l (%1)+,%3\n"
|
||
+ " move.l %3,(%2)+\n"
|
||
+ " subq.l #1,%0\n"
|
||
+ " jne 1b\n"
|
||
+ "2: btst #1,%5\n"
|
||
+ " jeq 4f\n"
|
||
+ "3: moves.w (%1)+,%3\n"
|
||
+ " move.w %3,(%2)+\n"
|
||
+ "4: btst #0,%5\n"
|
||
+ " jeq 6f\n"
|
||
+ "5: moves.b (%1)+,%3\n"
|
||
+ " move.b %3,(%2)+\n"
|
||
+ "6:\n"
|
||
+ " .section .fixup,\"ax\"\n"
|
||
+ " .even\n"
|
||
+ "10: move.l %0,%3\n"
|
||
+ "7: clr.l (%2)+\n"
|
||
+ " subq.l #1,%3\n"
|
||
+ " jne 7b\n"
|
||
+ " lsl.l #2,%0\n"
|
||
+ " btst #1,%5\n"
|
||
+ " jeq 8f\n"
|
||
+ "30: clr.w (%2)+\n"
|
||
+ " addq.l #2,%0\n"
|
||
+ "8: btst #0,%5\n"
|
||
+ " jeq 6b\n"
|
||
+ "50: clr.b (%2)+\n"
|
||
+ " addq.l #1,%0\n"
|
||
+ " jra 6b\n"
|
||
+ " .previous\n"
|
||
+ "\n"
|
||
+ " .section __ex_table,\"a\"\n"
|
||
+ " .align 4\n"
|
||
+ " .long 1b,10b\n"
|
||
+ " .long 3b,30b\n"
|
||
+ " .long 5b,50b\n"
|
||
+ " .previous"
|
||
+ : "=d" (res), "+a" (from), "+a" (to), "=&r" (tmp)
|
||
+ : "0" (n / 4), "d" (n & 3));
|
||
+
|
||
+ return res;
|
||
+}
|
||
+EXPORT_SYMBOL(__generic_copy_from_user);
|
||
+
|
||
+unsigned long __generic_copy_to_user(void __user *to, const void *from,
|
||
+ unsigned long n)
|
||
+{
|
||
+ unsigned long tmp, res;
|
||
+
|
||
+ asm volatile ("\n"
|
||
+ " tst.l %0\n"
|
||
+ " jeq 4f\n"
|
||
+ "1: move.l (%1)+,%3\n"
|
||
+ "2: moves.l %3,(%2)+\n"
|
||
+ "3: subq.l #1,%0\n"
|
||
+ " jne 1b\n"
|
||
+ "4: btst #1,%5\n"
|
||
+ " jeq 6f\n"
|
||
+ " move.w (%1)+,%3\n"
|
||
+ "5: moves.w %3,(%2)+\n"
|
||
+ "6: btst #0,%5\n"
|
||
+ " jeq 8f\n"
|
||
+ " move.b (%1)+,%3\n"
|
||
+ "7: moves.b %3,(%2)+\n"
|
||
+ "8:\n"
|
||
+ " .section .fixup,\"ax\"\n"
|
||
+ " .even\n"
|
||
+ "20: lsl.l #2,%0\n"
|
||
+ "50: add.l %5,%0\n"
|
||
+ " jra 7b\n"
|
||
+ " .previous\n"
|
||
+ "\n"
|
||
+ " .section __ex_table,\"a\"\n"
|
||
+ " .align 4\n"
|
||
+ " .long 2b,20b\n"
|
||
+ " .long 3b,20b\n"
|
||
+ " .long 5b,50b\n"
|
||
+ " .long 6b,50b\n"
|
||
+ " .long 7b,50b\n"
|
||
+ " .long 8b,50b\n"
|
||
+ " .previous"
|
||
+ : "=d" (res), "+a" (from), "+a" (to), "=&r" (tmp)
|
||
+ : "0" (n / 4), "d" (n & 3));
|
||
+
|
||
+ return res;
|
||
+}
|
||
+EXPORT_SYMBOL(__generic_copy_to_user);
|
||
+
|
||
+/*
|
||
+ * Copy a null terminated string from userspace.
|
||
+ */
|
||
+long strncpy_from_user(char *dst, const char __user *src, long count)
|
||
+{
|
||
+ long res;
|
||
+ char c;
|
||
+
|
||
+ if (count <= 0)
|
||
+ return count;
|
||
+
|
||
+ asm volatile ("\n"
|
||
+ "1: moves.b (%2)+,%4\n"
|
||
+ " move.b %4,(%1)+\n"
|
||
+ " jeq 2f\n"
|
||
+ " subq.l #1,%3\n"
|
||
+ " jne 1b\n"
|
||
+ "2: sub.l %3,%0\n"
|
||
+ "3:\n"
|
||
+ " .section .fixup,\"ax\"\n"
|
||
+ " .even\n"
|
||
+ "10: move.l %5,%0\n"
|
||
+ " jra 3b\n"
|
||
+ " .previous\n"
|
||
+ "\n"
|
||
+ " .section __ex_table,\"a\"\n"
|
||
+ " .align 4\n"
|
||
+ " .long 1b,10b\n"
|
||
+ " .previous"
|
||
+ : "=d" (res), "+a" (dst), "+a" (src), "+r" (count), "=&d" (c)
|
||
+ : "i" (-EFAULT), "0" (count));
|
||
+
|
||
+ return res;
|
||
+}
|
||
+EXPORT_SYMBOL(strncpy_from_user);
|
||
+
|
||
+/*
|
||
+ * Return the size of a string (including the ending 0)
|
||
+ *
|
||
+ * Return 0 on exception, a value greater than N if too long
|
||
+ */
|
||
+long strnlen_user(const char __user *src, long n)
|
||
+{
|
||
+ char c;
|
||
+ long res;
|
||
+
|
||
+ asm volatile ("\n"
|
||
+ "1: subq.l #1,%1\n"
|
||
+ " jmi 3f\n"
|
||
+ "2: moves.b (%0)+,%2\n"
|
||
+ " tst.b %2\n"
|
||
+ " jne 1b\n"
|
||
+ " jra 4f\n"
|
||
+ "\n"
|
||
+ "3: addq.l #1,%0\n"
|
||
+ "4: sub.l %4,%0\n"
|
||
+ "5:\n"
|
||
+ " .section .fixup,\"ax\"\n"
|
||
+ " .even\n"
|
||
+ "20: sub.l %0,%0\n"
|
||
+ " jra 5b\n"
|
||
+ " .previous\n"
|
||
+ "\n"
|
||
+ " .section __ex_table,\"a\"\n"
|
||
+ " .align 4\n"
|
||
+ " .long 2b,20b\n"
|
||
+ " .previous\n"
|
||
+ : "=&a" (res), "+d" (n), "=&d" (c)
|
||
+ : "0" (src), "r" (src));
|
||
+
|
||
+ return res;
|
||
+}
|
||
+EXPORT_SYMBOL(strnlen_user);
|
||
+
|
||
+/*
|
||
+ * Zero Userspace
|
||
+ */
|
||
+
|
||
+unsigned long clear_user(void __user *to, unsigned long n)
|
||
+{
|
||
+ unsigned long res;
|
||
+
|
||
+ asm volatile ("\n"
|
||
+ " tst.l %0\n"
|
||
+ " jeq 3f\n"
|
||
+ "1: moves.l %2,(%1)+\n"
|
||
+ "2: subq.l #1,%0\n"
|
||
+ " jne 1b\n"
|
||
+ "3: btst #1,%4\n"
|
||
+ " jeq 5f\n"
|
||
+ "4: moves.w %2,(%1)+\n"
|
||
+ "5: btst #0,%4\n"
|
||
+ " jeq 7f\n"
|
||
+ "6: moves.b %2,(%1)\n"
|
||
+ "7:\n"
|
||
+ " .section .fixup,\"ax\"\n"
|
||
+ " .even\n"
|
||
+ "10: lsl.l #2,%0\n"
|
||
+ "40: add.l %4,%0\n"
|
||
+ " jra 7b\n"
|
||
+ " .previous\n"
|
||
+ "\n"
|
||
+ " .section __ex_table,\"a\"\n"
|
||
+ " .align 4\n"
|
||
+ " .long 1b,10b\n"
|
||
+ " .long 2b,10b\n"
|
||
+ " .long 4b,40b\n"
|
||
+ " .long 5b,40b\n"
|
||
+ " .long 6b,40b\n"
|
||
+ " .long 7b,40b\n"
|
||
+ " .previous"
|
||
+ : "=d" (res), "+a" (to)
|
||
+ : "r" (0), "0" (n / 4), "d" (n & 3));
|
||
+
|
||
+ return res;
|
||
+}
|
||
+EXPORT_SYMBOL(clear_user);
|
||
diff -urN linux-i386/arch/m68k/mac/baboon.c linux-m68k/arch/m68k/mac/baboon.c
|
||
--- linux-i386/arch/m68k/mac/baboon.c 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/arch/m68k/mac/baboon.c 2006-01-28 22:36:16.000000000 +0100
|
||
@@ -81,7 +81,7 @@
|
||
for (i = 0, irq_bit = 1 ; i < 3 ; i++, irq_bit <<= 1) {
|
||
if (events & irq_bit/* & baboon_active*/) {
|
||
baboon_active &= ~irq_bit;
|
||
- mac_do_irq_list(IRQ_BABOON_0 + i, regs);
|
||
+ m68k_handle_int(IRQ_BABOON_0 + i, regs);
|
||
baboon_active |= irq_bit;
|
||
baboon->mb_ifr &= ~irq_bit;
|
||
}
|
||
diff -urN linux-i386/arch/m68k/mac/config.c linux-m68k/arch/m68k/mac/config.c
|
||
--- linux-i386/arch/m68k/mac/config.c 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/arch/m68k/mac/config.c 2006-05-26 11:53:40.000000000 +0200
|
||
@@ -89,38 +89,11 @@
|
||
|
||
static void mac_get_model(char *str);
|
||
|
||
-void mac_bang(int irq, void *vector, struct pt_regs *p)
|
||
-{
|
||
- printk(KERN_INFO "Resetting ...\n");
|
||
- mac_reset();
|
||
-}
|
||
-
|
||
static void mac_sched_init(irqreturn_t (*vector)(int, void *, struct pt_regs *))
|
||
{
|
||
via_init_clock(vector);
|
||
}
|
||
|
||
-#if 0
|
||
-void mac_waitbut (void)
|
||
-{
|
||
- ;
|
||
-}
|
||
-#endif
|
||
-
|
||
-extern irqreturn_t mac_default_handler(int, void *, struct pt_regs *);
|
||
-
|
||
-irqreturn_t (*mac_handlers[8])(int, void *, struct pt_regs *)=
|
||
-{
|
||
- mac_default_handler,
|
||
- mac_default_handler,
|
||
- mac_default_handler,
|
||
- mac_default_handler,
|
||
- mac_default_handler,
|
||
- mac_default_handler,
|
||
- mac_default_handler,
|
||
- mac_default_handler
|
||
-};
|
||
-
|
||
/*
|
||
* Parse a Macintosh-specific record in the bootinfo
|
||
*/
|
||
@@ -196,13 +169,7 @@
|
||
|
||
mach_sched_init = mac_sched_init;
|
||
mach_init_IRQ = mac_init_IRQ;
|
||
- mach_request_irq = mac_request_irq;
|
||
- mach_free_irq = mac_free_irq;
|
||
- enable_irq = mac_enable_irq;
|
||
- disable_irq = mac_disable_irq;
|
||
mach_get_model = mac_get_model;
|
||
- mach_default_handler = &mac_handlers;
|
||
- mach_get_irq_list = show_mac_interrupts;
|
||
mach_gettimeoffset = mac_gettimeoffset;
|
||
#warning move to adb/via init
|
||
#if 0
|
||
diff -urN linux-i386/arch/m68k/mac/iop.c linux-m68k/arch/m68k/mac/iop.c
|
||
--- linux-i386/arch/m68k/mac/iop.c 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/arch/m68k/mac/iop.c 2006-04-10 00:21:46.000000000 +0200
|
||
@@ -317,7 +317,7 @@
|
||
{
|
||
if (iop_ism_present) {
|
||
if (oss_present) {
|
||
- cpu_request_irq(OSS_IRQLEV_IOPISM, iop_ism_irq,
|
||
+ request_irq(OSS_IRQLEV_IOPISM, iop_ism_irq,
|
||
IRQ_FLG_LOCK, "ISM IOP",
|
||
(void *) IOP_NUM_ISM);
|
||
oss_irq_enable(IRQ_MAC_ADB);
|
||
diff -urN linux-i386/arch/m68k/mac/macints.c linux-m68k/arch/m68k/mac/macints.c
|
||
--- linux-i386/arch/m68k/mac/macints.c 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/arch/m68k/mac/macints.c 2006-05-26 11:53:40.000000000 +0200
|
||
@@ -137,14 +137,6 @@
|
||
#define DEBUG_SPURIOUS
|
||
#define SHUTUP_SONIC
|
||
|
||
-/*
|
||
- * The mac_irq_list array is an array of linked lists of irq_node_t nodes.
|
||
- * Each node contains one handler to be called whenever the interrupt
|
||
- * occurs, with fast handlers listed before slow handlers.
|
||
- */
|
||
-
|
||
-irq_node_t *mac_irq_list[NUM_MAC_SOURCES];
|
||
-
|
||
/* SCC interrupt mask */
|
||
|
||
static int scc_mask;
|
||
@@ -209,34 +201,37 @@
|
||
* SCC interrupt routines
|
||
*/
|
||
|
||
-static void scc_irq_enable(int);
|
||
-static void scc_irq_disable(int);
|
||
+static void scc_irq_enable(unsigned int);
|
||
+static void scc_irq_disable(unsigned int);
|
||
|
||
/*
|
||
* console_loglevel determines NMI handler function
|
||
*/
|
||
|
||
-extern irqreturn_t mac_bang(int, void *, struct pt_regs *);
|
||
irqreturn_t mac_nmi_handler(int, void *, struct pt_regs *);
|
||
irqreturn_t mac_debug_handler(int, void *, struct pt_regs *);
|
||
|
||
/* #define DEBUG_MACINTS */
|
||
|
||
+static void mac_enable_irq(unsigned int irq);
|
||
+static void mac_disable_irq(unsigned int irq);
|
||
+
|
||
+static struct irq_controller mac_irq_controller = {
|
||
+ .name = "mac",
|
||
+ .lock = SPIN_LOCK_UNLOCKED,
|
||
+ .enable = mac_enable_irq,
|
||
+ .disable = mac_disable_irq,
|
||
+};
|
||
+
|
||
void mac_init_IRQ(void)
|
||
{
|
||
- int i;
|
||
-
|
||
#ifdef DEBUG_MACINTS
|
||
printk("mac_init_IRQ(): Setting things up...\n");
|
||
#endif
|
||
- /* Initialize the IRQ handler lists. Initially each list is empty, */
|
||
-
|
||
- for (i = 0; i < NUM_MAC_SOURCES; i++) {
|
||
- mac_irq_list[i] = NULL;
|
||
- }
|
||
-
|
||
scc_mask = 0;
|
||
|
||
+ m68k_setup_irq_controller(&mac_irq_controller, IRQ_USER,
|
||
+ NUM_MAC_SOURCES - IRQ_USER);
|
||
/* Make sure the SONIC interrupt is cleared or things get ugly */
|
||
#ifdef SHUTUP_SONIC
|
||
printk("Killing onboard sonic... ");
|
||
@@ -253,15 +248,16 @@
|
||
* at levels 1-7. Most of the work is done elsewhere.
|
||
*/
|
||
|
||
- if (oss_present) {
|
||
+ if (oss_present)
|
||
oss_register_interrupts();
|
||
- } else {
|
||
+ else
|
||
via_register_interrupts();
|
||
- }
|
||
- if (psc_present) psc_register_interrupts();
|
||
- if (baboon_present) baboon_register_interrupts();
|
||
+ if (psc_present)
|
||
+ psc_register_interrupts();
|
||
+ if (baboon_present)
|
||
+ baboon_register_interrupts();
|
||
iop_register_interrupts();
|
||
- cpu_request_irq(7, mac_nmi_handler, IRQ_FLG_LOCK, "NMI",
|
||
+ request_irq(IRQ_AUTO_7, mac_nmi_handler, 0, "NMI",
|
||
mac_nmi_handler);
|
||
#ifdef DEBUG_MACINTS
|
||
printk("mac_init_IRQ(): Done!\n");
|
||
@@ -269,104 +265,6 @@
|
||
}
|
||
|
||
/*
|
||
- * Routines to work with irq_node_t's on linked lists lifted from
|
||
- * the Amiga code written by Roman Zippel.
|
||
- */
|
||
-
|
||
-static inline void mac_insert_irq(irq_node_t **list, irq_node_t *node)
|
||
-{
|
||
- unsigned long flags;
|
||
- irq_node_t *cur;
|
||
-
|
||
- if (!node->dev_id)
|
||
- printk("%s: Warning: dev_id of %s is zero\n",
|
||
- __FUNCTION__, node->devname);
|
||
-
|
||
- local_irq_save(flags);
|
||
-
|
||
- cur = *list;
|
||
-
|
||
- if (node->flags & IRQ_FLG_FAST) {
|
||
- node->flags &= ~IRQ_FLG_SLOW;
|
||
- while (cur && cur->flags & IRQ_FLG_FAST) {
|
||
- list = &cur->next;
|
||
- cur = cur->next;
|
||
- }
|
||
- } else if (node->flags & IRQ_FLG_SLOW) {
|
||
- while (cur) {
|
||
- list = &cur->next;
|
||
- cur = cur->next;
|
||
- }
|
||
- } else {
|
||
- while (cur && !(cur->flags & IRQ_FLG_SLOW)) {
|
||
- list = &cur->next;
|
||
- cur = cur->next;
|
||
- }
|
||
- }
|
||
-
|
||
- node->next = cur;
|
||
- *list = node;
|
||
-
|
||
- local_irq_restore(flags);
|
||
-}
|
||
-
|
||
-static inline void mac_delete_irq(irq_node_t **list, void *dev_id)
|
||
-{
|
||
- unsigned long flags;
|
||
- irq_node_t *node;
|
||
-
|
||
- local_irq_save(flags);
|
||
-
|
||
- for (node = *list; node; list = &node->next, node = *list) {
|
||
- if (node->dev_id == dev_id) {
|
||
- *list = node->next;
|
||
- /* Mark it as free. */
|
||
- node->handler = NULL;
|
||
- local_irq_restore(flags);
|
||
- return;
|
||
- }
|
||
- }
|
||
- local_irq_restore(flags);
|
||
- printk ("%s: tried to remove invalid irq\n", __FUNCTION__);
|
||
-}
|
||
-
|
||
-/*
|
||
- * Call all the handlers for a given interrupt. Fast handlers are called
|
||
- * first followed by slow handlers.
|
||
- *
|
||
- * This code taken from the original Amiga code written by Roman Zippel.
|
||
- */
|
||
-
|
||
-void mac_do_irq_list(int irq, struct pt_regs *fp)
|
||
-{
|
||
- irq_node_t *node, *slow_nodes;
|
||
- unsigned long flags;
|
||
-
|
||
- kstat_cpu(0).irqs[irq]++;
|
||
-
|
||
-#ifdef DEBUG_SPURIOUS
|
||
- if (!mac_irq_list[irq] && (console_loglevel > 7)) {
|
||
- printk("mac_do_irq_list: spurious interrupt %d!\n", irq);
|
||
- return;
|
||
- }
|
||
-#endif
|
||
-
|
||
- /* serve first fast and normal handlers */
|
||
- for (node = mac_irq_list[irq];
|
||
- node && (!(node->flags & IRQ_FLG_SLOW));
|
||
- node = node->next)
|
||
- node->handler(irq, node->dev_id, fp);
|
||
- if (!node) return;
|
||
- local_save_flags(flags);
|
||
- local_irq_restore((flags & ~0x0700) | (fp->sr & 0x0700));
|
||
- /* if slow handlers exists, serve them now */
|
||
- slow_nodes = node;
|
||
- for (; node; node = node->next) {
|
||
- node->handler(irq, node->dev_id, fp);
|
||
- }
|
||
-}
|
||
-
|
||
-/*
|
||
* mac_enable_irq - enable an interrupt source
|
||
* mac_disable_irq - disable an interrupt source
|
||
* mac_clear_irq - clears a pending interrupt
|
||
@@ -375,276 +273,124 @@
|
||
* These routines are just dispatchers to the VIA/OSS/PSC routines.
|
||
*/
|
||
|
||
-void mac_enable_irq (unsigned int irq)
|
||
+static void mac_enable_irq(unsigned int irq)
|
||
{
|
||
- int irq_src = IRQ_SRC(irq);
|
||
+ int irq_src = IRQ_SRC(irq);
|
||
|
||
switch(irq_src) {
|
||
- case 1: via_irq_enable(irq);
|
||
- break;
|
||
- case 2:
|
||
- case 7: if (oss_present) {
|
||
- oss_irq_enable(irq);
|
||
- } else {
|
||
- via_irq_enable(irq);
|
||
- }
|
||
- break;
|
||
- case 3:
|
||
- case 4:
|
||
- case 5:
|
||
- case 6: if (psc_present) {
|
||
- psc_irq_enable(irq);
|
||
- } else if (oss_present) {
|
||
- oss_irq_enable(irq);
|
||
- } else if (irq_src == 4) {
|
||
- scc_irq_enable(irq);
|
||
- }
|
||
- break;
|
||
- case 8: if (baboon_present) {
|
||
- baboon_irq_enable(irq);
|
||
- }
|
||
- break;
|
||
+ case 1:
|
||
+ via_irq_enable(irq);
|
||
+ break;
|
||
+ case 2:
|
||
+ case 7:
|
||
+ if (oss_present)
|
||
+ oss_irq_enable(irq);
|
||
+ else
|
||
+ via_irq_enable(irq);
|
||
+ break;
|
||
+ case 3:
|
||
+ case 4:
|
||
+ case 5:
|
||
+ case 6:
|
||
+ if (psc_present)
|
||
+ psc_irq_enable(irq);
|
||
+ else if (oss_present)
|
||
+ oss_irq_enable(irq);
|
||
+ else if (irq_src == 4)
|
||
+ scc_irq_enable(irq);
|
||
+ break;
|
||
+ case 8:
|
||
+ if (baboon_present)
|
||
+ baboon_irq_enable(irq);
|
||
+ break;
|
||
}
|
||
}
|
||
|
||
-void mac_disable_irq (unsigned int irq)
|
||
+static void mac_disable_irq(unsigned int irq)
|
||
{
|
||
- int irq_src = IRQ_SRC(irq);
|
||
+ int irq_src = IRQ_SRC(irq);
|
||
|
||
switch(irq_src) {
|
||
- case 1: via_irq_disable(irq);
|
||
- break;
|
||
- case 2:
|
||
- case 7: if (oss_present) {
|
||
- oss_irq_disable(irq);
|
||
- } else {
|
||
- via_irq_disable(irq);
|
||
- }
|
||
- break;
|
||
- case 3:
|
||
- case 4:
|
||
- case 5:
|
||
- case 6: if (psc_present) {
|
||
- psc_irq_disable(irq);
|
||
- } else if (oss_present) {
|
||
- oss_irq_disable(irq);
|
||
- } else if (irq_src == 4) {
|
||
- scc_irq_disable(irq);
|
||
- }
|
||
- break;
|
||
- case 8: if (baboon_present) {
|
||
- baboon_irq_disable(irq);
|
||
- }
|
||
- break;
|
||
+ case 1:
|
||
+ via_irq_disable(irq);
|
||
+ break;
|
||
+ case 2:
|
||
+ case 7:
|
||
+ if (oss_present)
|
||
+ oss_irq_disable(irq);
|
||
+ else
|
||
+ via_irq_disable(irq);
|
||
+ break;
|
||
+ case 3:
|
||
+ case 4:
|
||
+ case 5:
|
||
+ case 6:
|
||
+ if (psc_present)
|
||
+ psc_irq_disable(irq);
|
||
+ else if (oss_present)
|
||
+ oss_irq_disable(irq);
|
||
+ else if (irq_src == 4)
|
||
+ scc_irq_disable(irq);
|
||
+ break;
|
||
+ case 8:
|
||
+ if (baboon_present)
|
||
+ baboon_irq_disable(irq);
|
||
+ break;
|
||
}
|
||
}
|
||
|
||
-void mac_clear_irq( unsigned int irq )
|
||
+void mac_clear_irq(unsigned int irq)
|
||
{
|
||
switch(IRQ_SRC(irq)) {
|
||
- case 1: via_irq_clear(irq);
|
||
- break;
|
||
- case 2:
|
||
- case 7: if (oss_present) {
|
||
- oss_irq_clear(irq);
|
||
- } else {
|
||
- via_irq_clear(irq);
|
||
- }
|
||
- break;
|
||
- case 3:
|
||
- case 4:
|
||
- case 5:
|
||
- case 6: if (psc_present) {
|
||
- psc_irq_clear(irq);
|
||
- } else if (oss_present) {
|
||
- oss_irq_clear(irq);
|
||
- }
|
||
- break;
|
||
- case 8: if (baboon_present) {
|
||
- baboon_irq_clear(irq);
|
||
- }
|
||
- break;
|
||
+ case 1:
|
||
+ via_irq_clear(irq);
|
||
+ break;
|
||
+ case 2:
|
||
+ case 7:
|
||
+ if (oss_present)
|
||
+ oss_irq_clear(irq);
|
||
+ else
|
||
+ via_irq_clear(irq);
|
||
+ break;
|
||
+ case 3:
|
||
+ case 4:
|
||
+ case 5:
|
||
+ case 6:
|
||
+ if (psc_present)
|
||
+ psc_irq_clear(irq);
|
||
+ else if (oss_present)
|
||
+ oss_irq_clear(irq);
|
||
+ break;
|
||
+ case 8:
|
||
+ if (baboon_present)
|
||
+ baboon_irq_clear(irq);
|
||
+ break;
|
||
}
|
||
}
|
||
|
||
-int mac_irq_pending( unsigned int irq )
|
||
+int mac_irq_pending(unsigned int irq)
|
||
{
|
||
switch(IRQ_SRC(irq)) {
|
||
- case 1: return via_irq_pending(irq);
|
||
- case 2:
|
||
- case 7: if (oss_present) {
|
||
- return oss_irq_pending(irq);
|
||
- } else {
|
||
- return via_irq_pending(irq);
|
||
- }
|
||
- case 3:
|
||
- case 4:
|
||
- case 5:
|
||
- case 6: if (psc_present) {
|
||
- return psc_irq_pending(irq);
|
||
- } else if (oss_present) {
|
||
- return oss_irq_pending(irq);
|
||
- }
|
||
- }
|
||
- return 0;
|
||
-}
|
||
-
|
||
-/*
|
||
- * Add an interrupt service routine to an interrupt source.
|
||
- * Returns 0 on success.
|
||
- *
|
||
- * FIXME: You can register interrupts on nonexistent source (ie PSC4 on a
|
||
- * non-PSC machine). We should return -EINVAL in those cases.
|
||
- */
|
||
-
|
||
-int mac_request_irq(unsigned int irq,
|
||
- irqreturn_t (*handler)(int, void *, struct pt_regs *),
|
||
- unsigned long flags, const char *devname, void *dev_id)
|
||
-{
|
||
- irq_node_t *node;
|
||
-
|
||
-#ifdef DEBUG_MACINTS
|
||
- printk ("%s: irq %d requested for %s\n", __FUNCTION__, irq, devname);
|
||
-#endif
|
||
-
|
||
- if (irq < VIA1_SOURCE_BASE) {
|
||
- return cpu_request_irq(irq, handler, flags, devname, dev_id);
|
||
+ case 1:
|
||
+ return via_irq_pending(irq);
|
||
+ case 2:
|
||
+ case 7:
|
||
+ if (oss_present)
|
||
+ return oss_irq_pending(irq);
|
||
+ else
|
||
+ return via_irq_pending(irq);
|
||
+ case 3:
|
||
+ case 4:
|
||
+ case 5:
|
||
+ case 6:
|
||
+ if (psc_present)
|
||
+ return psc_irq_pending(irq);
|
||
+ else if (oss_present)
|
||
+ return oss_irq_pending(irq);
|
||
}
|
||
-
|
||
- if (irq >= NUM_MAC_SOURCES) {
|
||
- printk ("%s: unknown irq %d requested by %s\n",
|
||
- __FUNCTION__, irq, devname);
|
||
- }
|
||
-
|
||
- /* Get a node and stick it onto the right list */
|
||
-
|
||
- if (!(node = new_irq_node())) return -ENOMEM;
|
||
-
|
||
- node->handler = handler;
|
||
- node->flags = flags;
|
||
- node->dev_id = dev_id;
|
||
- node->devname = devname;
|
||
- node->next = NULL;
|
||
- mac_insert_irq(&mac_irq_list[irq], node);
|
||
-
|
||
- /* Now enable the IRQ source */
|
||
-
|
||
- mac_enable_irq(irq);
|
||
-
|
||
return 0;
|
||
}
|
||
|
||
-/*
|
||
- * Removes an interrupt service routine from an interrupt source.
|
||
- */
|
||
-
|
||
-void mac_free_irq(unsigned int irq, void *dev_id)
|
||
-{
|
||
-#ifdef DEBUG_MACINTS
|
||
- printk ("%s: irq %d freed by %p\n", __FUNCTION__, irq, dev_id);
|
||
-#endif
|
||
-
|
||
- if (irq < VIA1_SOURCE_BASE) {
|
||
- cpu_free_irq(irq, dev_id);
|
||
- return;
|
||
- }
|
||
-
|
||
- if (irq >= NUM_MAC_SOURCES) {
|
||
- printk ("%s: unknown irq %d freed\n",
|
||
- __FUNCTION__, irq);
|
||
- return;
|
||
- }
|
||
-
|
||
- mac_delete_irq(&mac_irq_list[irq], dev_id);
|
||
-
|
||
- /* If the list for this interrupt is */
|
||
- /* empty then disable the source. */
|
||
-
|
||
- if (!mac_irq_list[irq]) {
|
||
- mac_disable_irq(irq);
|
||
- }
|
||
-}
|
||
-
|
||
-/*
|
||
- * Generate a pretty listing for /proc/interrupts
|
||
- *
|
||
- * By the time we're called the autovector interrupt list has already been
|
||
- * generated, so we just need to do the machspec interrupts.
|
||
- *
|
||
- * 990506 (jmt) - rewritten to handle chained machspec interrupt handlers.
|
||
- * Also removed display of num_spurious it is already
|
||
- * displayed for us as autovector irq 0.
|
||
- */
|
||
-
|
||
-int show_mac_interrupts(struct seq_file *p, void *v)
|
||
-{
|
||
- int i;
|
||
- irq_node_t *node;
|
||
- char *base;
|
||
-
|
||
- /* Don't do Nubus interrupts in this loop; we do them separately */
|
||
- /* below so that we can print slot numbers instead of IRQ numbers */
|
||
-
|
||
- for (i = VIA1_SOURCE_BASE ; i < NUM_MAC_SOURCES ; ++i) {
|
||
-
|
||
- /* Nonexistant interrupt or nothing registered; skip it. */
|
||
-
|
||
- if ((node = mac_irq_list[i]) == NULL) continue;
|
||
- if (node->flags & IRQ_FLG_STD) continue;
|
||
-
|
||
- base = "";
|
||
- switch(IRQ_SRC(i)) {
|
||
- case 1: base = "via1";
|
||
- break;
|
||
- case 2: if (oss_present) {
|
||
- base = "oss";
|
||
- } else {
|
||
- base = "via2";
|
||
- }
|
||
- break;
|
||
- case 3:
|
||
- case 4:
|
||
- case 5:
|
||
- case 6: if (psc_present) {
|
||
- base = "psc";
|
||
- } else if (oss_present) {
|
||
- base = "oss";
|
||
- } else {
|
||
- if (IRQ_SRC(i) == 4) base = "scc";
|
||
- }
|
||
- break;
|
||
- case 7: base = "nbus";
|
||
- break;
|
||
- case 8: base = "bbn";
|
||
- break;
|
||
- }
|
||
- seq_printf(p, "%4s %2d: %10u ", base, i, kstat_cpu(0).irqs[i]);
|
||
-
|
||
- do {
|
||
- if (node->flags & IRQ_FLG_FAST) {
|
||
- seq_puts(p, "F ");
|
||
- } else if (node->flags & IRQ_FLG_SLOW) {
|
||
- seq_puts(p, "S ");
|
||
- } else {
|
||
- seq_puts(p, " ");
|
||
- }
|
||
- seq_printf(p, "%s\n", node->devname);
|
||
- if ((node = node->next)) {
|
||
- seq_puts(p, " ");
|
||
- }
|
||
- } while(node);
|
||
-
|
||
- }
|
||
- return 0;
|
||
-}
|
||
-
|
||
-void mac_default_handler(int irq, void *dev_id, struct pt_regs *regs)
|
||
-{
|
||
-#ifdef DEBUG_SPURIOUS
|
||
- printk("Unexpected IRQ %d on device %p\n", irq, dev_id);
|
||
-#endif
|
||
-}
|
||
-
|
||
static int num_debug[8];
|
||
|
||
irqreturn_t mac_debug_handler(int irq, void *dev_id, struct pt_regs *regs)
|
||
@@ -684,7 +430,7 @@
|
||
while (nmi_hold == 1)
|
||
udelay(1000);
|
||
|
||
- if ( console_loglevel >= 8 ) {
|
||
+ if (console_loglevel >= 8) {
|
||
#if 0
|
||
show_state();
|
||
printk("PC: %08lx\nSR: %04x SP: %p\n", fp->pc, fp->sr, fp);
|
||
@@ -713,14 +459,16 @@
|
||
* done in hardware (only the PSC can do that.)
|
||
*/
|
||
|
||
-static void scc_irq_enable(int irq) {
|
||
- int irq_idx = IRQ_IDX(irq);
|
||
+static void scc_irq_enable(unsigned int irq)
|
||
+{
|
||
+ int irq_idx = IRQ_IDX(irq);
|
||
|
||
scc_mask |= (1 << irq_idx);
|
||
}
|
||
|
||
-static void scc_irq_disable(int irq) {
|
||
- int irq_idx = IRQ_IDX(irq);
|
||
+static void scc_irq_disable(unsigned int irq)
|
||
+{
|
||
+ int irq_idx = IRQ_IDX(irq);
|
||
|
||
scc_mask &= ~(1 << irq_idx);
|
||
}
|
||
@@ -755,6 +503,8 @@
|
||
/* and since they're autovector interrupts they */
|
||
/* pretty much kill the system. */
|
||
|
||
- if (reg & 0x38) mac_do_irq_list(IRQ_SCCA, regs);
|
||
- if (reg & 0x07) mac_do_irq_list(IRQ_SCCB, regs);
|
||
+ if (reg & 0x38)
|
||
+ m68k_handle_int(IRQ_SCCA, regs);
|
||
+ if (reg & 0x07)
|
||
+ m68k_handle_int(IRQ_SCCB, regs);
|
||
}
|
||
diff -urN linux-i386/arch/m68k/mac/oss.c linux-m68k/arch/m68k/mac/oss.c
|
||
--- linux-i386/arch/m68k/mac/oss.c 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/arch/m68k/mac/oss.c 2006-01-28 22:36:16.000000000 +0100
|
||
@@ -67,15 +67,15 @@
|
||
|
||
void __init oss_register_interrupts(void)
|
||
{
|
||
- cpu_request_irq(OSS_IRQLEV_SCSI, oss_irq, IRQ_FLG_LOCK,
|
||
+ request_irq(OSS_IRQLEV_SCSI, oss_irq, IRQ_FLG_LOCK,
|
||
"scsi", (void *) oss);
|
||
- cpu_request_irq(OSS_IRQLEV_IOPSCC, mac_scc_dispatch, IRQ_FLG_LOCK,
|
||
+ request_irq(OSS_IRQLEV_IOPSCC, mac_scc_dispatch, IRQ_FLG_LOCK,
|
||
"scc", mac_scc_dispatch);
|
||
- cpu_request_irq(OSS_IRQLEV_NUBUS, oss_nubus_irq, IRQ_FLG_LOCK,
|
||
+ request_irq(OSS_IRQLEV_NUBUS, oss_nubus_irq, IRQ_FLG_LOCK,
|
||
"nubus", (void *) oss);
|
||
- cpu_request_irq(OSS_IRQLEV_SOUND, oss_irq, IRQ_FLG_LOCK,
|
||
+ request_irq(OSS_IRQLEV_SOUND, oss_irq, IRQ_FLG_LOCK,
|
||
"sound", (void *) oss);
|
||
- cpu_request_irq(OSS_IRQLEV_VIA1, via1_irq, IRQ_FLG_LOCK,
|
||
+ request_irq(OSS_IRQLEV_VIA1, via1_irq, IRQ_FLG_LOCK,
|
||
"via1", (void *) via1);
|
||
}
|
||
|
||
@@ -113,7 +113,7 @@
|
||
oss->irq_pending &= ~OSS_IP_SOUND;
|
||
} else if (events & OSS_IP_SCSI) {
|
||
oss->irq_level[OSS_SCSI] = OSS_IRQLEV_DISABLED;
|
||
- mac_do_irq_list(IRQ_MAC_SCSI, regs);
|
||
+ m68k_handle_int(IRQ_MAC_SCSI, regs);
|
||
oss->irq_pending &= ~OSS_IP_SCSI;
|
||
oss->irq_level[OSS_SCSI] = OSS_IRQLEV_SCSI;
|
||
} else {
|
||
@@ -146,7 +146,7 @@
|
||
for (i = 0, irq_bit = 1 ; i < 6 ; i++, irq_bit <<= 1) {
|
||
if (events & irq_bit) {
|
||
oss->irq_level[i] = OSS_IRQLEV_DISABLED;
|
||
- mac_do_irq_list(NUBUS_SOURCE_BASE + i, regs);
|
||
+ m68k_handle_int(NUBUS_SOURCE_BASE + i, regs);
|
||
oss->irq_pending &= ~irq_bit;
|
||
oss->irq_level[i] = OSS_IRQLEV_NUBUS;
|
||
}
|
||
diff -urN linux-i386/arch/m68k/mac/psc.c linux-m68k/arch/m68k/mac/psc.c
|
||
--- linux-i386/arch/m68k/mac/psc.c 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/arch/m68k/mac/psc.c 2006-01-28 22:36:16.000000000 +0100
|
||
@@ -117,10 +117,10 @@
|
||
|
||
void __init psc_register_interrupts(void)
|
||
{
|
||
- cpu_request_irq(3, psc_irq, IRQ_FLG_LOCK, "psc3", (void *) 0x30);
|
||
- cpu_request_irq(4, psc_irq, IRQ_FLG_LOCK, "psc4", (void *) 0x40);
|
||
- cpu_request_irq(5, psc_irq, IRQ_FLG_LOCK, "psc5", (void *) 0x50);
|
||
- cpu_request_irq(6, psc_irq, IRQ_FLG_LOCK, "psc6", (void *) 0x60);
|
||
+ request_irq(IRQ_AUTO_3, psc_irq, 0, "psc3", (void *) 0x30);
|
||
+ request_irq(IRQ_AUTO_4, psc_irq, 0, "psc4", (void *) 0x40);
|
||
+ request_irq(IRQ_AUTO_5, psc_irq, 0, "psc5", (void *) 0x50);
|
||
+ request_irq(IRQ_AUTO_6, psc_irq, 0, "psc6", (void *) 0x60);
|
||
}
|
||
|
||
/*
|
||
@@ -149,7 +149,7 @@
|
||
for (i = 0, irq_bit = 1 ; i < 4 ; i++, irq_bit <<= 1) {
|
||
if (events & irq_bit) {
|
||
psc_write_byte(pIER, irq_bit);
|
||
- mac_do_irq_list(base_irq + i, regs);
|
||
+ m68k_handle_int(base_irq + i, regs);
|
||
psc_write_byte(pIFR, irq_bit);
|
||
psc_write_byte(pIER, irq_bit | 0x80);
|
||
}
|
||
diff -urN linux-i386/arch/m68k/mac/via.c linux-m68k/arch/m68k/mac/via.c
|
||
--- linux-i386/arch/m68k/mac/via.c 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/arch/m68k/mac/via.c 2006-05-26 11:53:40.000000000 +0200
|
||
@@ -25,7 +25,6 @@
|
||
#include <linux/init.h>
|
||
#include <linux/ide.h>
|
||
|
||
-#include <asm/traps.h>
|
||
#include <asm/bootinfo.h>
|
||
#include <asm/macintosh.h>
|
||
#include <asm/macints.h>
|
||
@@ -71,7 +70,6 @@
|
||
void via_irq_disable(int irq);
|
||
void via_irq_clear(int irq);
|
||
|
||
-extern irqreturn_t mac_bang(int, void *, struct pt_regs *);
|
||
extern irqreturn_t mac_scc_dispatch(int, void *, struct pt_regs *);
|
||
extern int oss_present;
|
||
|
||
@@ -212,11 +210,6 @@
|
||
break;
|
||
}
|
||
#else
|
||
- /* The alernate IRQ mapping seems to just not work. Anyone with a */
|
||
- /* supported machine is welcome to take a stab at fixing it. It */
|
||
- /* _should_ work on the following Quadras: 610,650,700,800,900,950 */
|
||
- /* - 1999-06-12 (jmt) */
|
||
-
|
||
via_alt_mapping = 0;
|
||
#endif
|
||
|
||
@@ -260,27 +253,21 @@
|
||
void __init via_register_interrupts(void)
|
||
{
|
||
if (via_alt_mapping) {
|
||
- cpu_request_irq(IRQ_AUTO_1, via1_irq,
|
||
+ request_irq(IRQ_AUTO_1, via1_irq,
|
||
IRQ_FLG_LOCK|IRQ_FLG_FAST, "software",
|
||
(void *) via1);
|
||
- cpu_request_irq(IRQ_AUTO_6, via1_irq,
|
||
+ request_irq(IRQ_AUTO_6, via1_irq,
|
||
IRQ_FLG_LOCK|IRQ_FLG_FAST, "via1",
|
||
(void *) via1);
|
||
} else {
|
||
- cpu_request_irq(IRQ_AUTO_1, via1_irq,
|
||
+ request_irq(IRQ_AUTO_1, via1_irq,
|
||
IRQ_FLG_LOCK|IRQ_FLG_FAST, "via1",
|
||
(void *) via1);
|
||
-#if 0 /* interferes with serial on some machines */
|
||
- if (!psc_present) {
|
||
- cpu_request_irq(IRQ_AUTO_6, mac_bang, IRQ_FLG_LOCK,
|
||
- "Off Switch", mac_bang);
|
||
- }
|
||
-#endif
|
||
}
|
||
- cpu_request_irq(IRQ_AUTO_2, via2_irq, IRQ_FLG_LOCK|IRQ_FLG_FAST,
|
||
+ request_irq(IRQ_AUTO_2, via2_irq, IRQ_FLG_LOCK|IRQ_FLG_FAST,
|
||
"via2", (void *) via2);
|
||
if (!psc_present) {
|
||
- cpu_request_irq(IRQ_AUTO_4, mac_scc_dispatch, IRQ_FLG_LOCK,
|
||
+ request_irq(IRQ_AUTO_4, mac_scc_dispatch, IRQ_FLG_LOCK,
|
||
"scc", mac_scc_dispatch);
|
||
}
|
||
request_irq(IRQ_MAC_NUBUS, via_nubus_irq, IRQ_FLG_LOCK|IRQ_FLG_FAST,
|
||
@@ -437,7 +424,7 @@
|
||
for (i = 0, irq_bit = 1 ; i < 7 ; i++, irq_bit <<= 1)
|
||
if (events & irq_bit) {
|
||
via1[vIER] = irq_bit;
|
||
- mac_do_irq_list(VIA1_SOURCE_BASE + i, regs);
|
||
+ m68k_handle_int(VIA1_SOURCE_BASE + i, regs);
|
||
via1[vIFR] = irq_bit;
|
||
via1[vIER] = irq_bit | 0x80;
|
||
}
|
||
@@ -452,7 +439,7 @@
|
||
/* No, it won't be set. that's why we're doing this. */
|
||
via_irq_disable(IRQ_MAC_NUBUS);
|
||
via_irq_clear(IRQ_MAC_NUBUS);
|
||
- mac_do_irq_list(IRQ_MAC_NUBUS, regs);
|
||
+ m68k_handle_int(IRQ_MAC_NUBUS, regs);
|
||
via_irq_enable(IRQ_MAC_NUBUS);
|
||
}
|
||
#endif
|
||
@@ -471,8 +458,8 @@
|
||
for (i = 0, irq_bit = 1 ; i < 7 ; i++, irq_bit <<= 1)
|
||
if (events & irq_bit) {
|
||
via2[gIER] = irq_bit;
|
||
- mac_do_irq_list(VIA2_SOURCE_BASE + i, regs);
|
||
via2[gIFR] = irq_bit | rbv_clear;
|
||
+ m68k_handle_int(VIA2_SOURCE_BASE + i, regs);
|
||
via2[gIER] = irq_bit | 0x80;
|
||
}
|
||
return IRQ_HANDLED;
|
||
@@ -494,7 +481,7 @@
|
||
for (i = 0, irq_bit = 1 ; i < 7 ; i++, irq_bit <<= 1) {
|
||
if (events & irq_bit) {
|
||
via_irq_disable(NUBUS_SOURCE_BASE + i);
|
||
- mac_do_irq_list(NUBUS_SOURCE_BASE + i, regs);
|
||
+ m68k_handle_int(NUBUS_SOURCE_BASE + i, regs);
|
||
via_irq_enable(NUBUS_SOURCE_BASE + i);
|
||
}
|
||
}
|
||
@@ -529,6 +516,7 @@
|
||
}
|
||
via2[gIER] = irq_bit | 0x80;
|
||
} else if (irq_src == 7) {
|
||
+ nubus_active |= irq_bit;
|
||
if (rbv_present) {
|
||
/* enable the slot interrupt. SIER works like IER. */
|
||
via2[rSIER] = IER_SET_BIT(irq_idx);
|
||
@@ -550,7 +538,6 @@
|
||
}
|
||
}
|
||
}
|
||
- nubus_active |= irq_bit;
|
||
}
|
||
}
|
||
|
||
diff -urN linux-i386/arch/m68k/mm/kmap.c linux-m68k/arch/m68k/mm/kmap.c
|
||
--- linux-i386/arch/m68k/mm/kmap.c 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/arch/m68k/mm/kmap.c 2006-06-06 00:59:41.000000000 +0200
|
||
@@ -259,13 +259,15 @@
|
||
|
||
if (CPU_IS_020_OR_030) {
|
||
int pmd_off = (virtaddr/PTRTREESIZE) & 15;
|
||
+ int pmd_type = pmd_dir->pmd[pmd_off] & _DESCTYPE_MASK;
|
||
|
||
- if ((pmd_dir->pmd[pmd_off] & _DESCTYPE_MASK) == _PAGE_PRESENT) {
|
||
+ if (pmd_type == _PAGE_PRESENT) {
|
||
pmd_dir->pmd[pmd_off] = 0;
|
||
virtaddr += PTRTREESIZE;
|
||
size -= PTRTREESIZE;
|
||
continue;
|
||
- }
|
||
+ } else if (pmd_type == 0)
|
||
+ continue;
|
||
}
|
||
|
||
if (pmd_bad(*pmd_dir)) {
|
||
diff -urN linux-i386/arch/m68k/mm/motorola.c linux-m68k/arch/m68k/mm/motorola.c
|
||
--- linux-i386/arch/m68k/mm/motorola.c 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/arch/m68k/mm/motorola.c 2006-06-18 19:06:45.000000000 +0200
|
||
@@ -203,7 +203,7 @@
|
||
{
|
||
int chunk;
|
||
unsigned long mem_avail = 0;
|
||
- unsigned long zones_size[3] = { 0, };
|
||
+ unsigned long zones_size[MAX_NR_ZONES] = { 0, };
|
||
|
||
#ifdef DEBUG
|
||
{
|
||
@@ -223,6 +223,9 @@
|
||
pgprot_val(protection_map[i]) |= _PAGE_CACHE040;
|
||
}
|
||
|
||
+ module_fixup(NULL, __start_fixup, __stop_fixup);
|
||
+ flush_icache();
|
||
+
|
||
/*
|
||
* Map the physical memory available into the kernel virtual
|
||
* address space. It may allocate some memory for page
|
||
@@ -257,12 +260,12 @@
|
||
#ifdef DEBUG
|
||
printk ("before free_area_init\n");
|
||
#endif
|
||
- zones_size[0] = (mach_max_dma_address < (unsigned long)high_memory ?
|
||
- (mach_max_dma_address+1) : (unsigned long)high_memory);
|
||
- zones_size[1] = (unsigned long)high_memory - zones_size[0];
|
||
+ zones_size[ZONE_DMA] = (mach_max_dma_address < (unsigned long)high_memory ?
|
||
+ (mach_max_dma_address+1) : (unsigned long)high_memory);
|
||
+ zones_size[ZONE_NORMAL] = (unsigned long)high_memory - zones_size[0];
|
||
|
||
- zones_size[0] = (zones_size[0] - PAGE_OFFSET) >> PAGE_SHIFT;
|
||
- zones_size[1] >>= PAGE_SHIFT;
|
||
+ zones_size[ZONE_DMA] = (zones_size[ZONE_DMA] - PAGE_OFFSET) >> PAGE_SHIFT;
|
||
+ zones_size[ZONE_NORMAL] >>= PAGE_SHIFT;
|
||
|
||
free_area_init(zones_size);
|
||
}
|
||
diff -urN linux-i386/arch/m68k/mm/sun3mmu.c linux-m68k/arch/m68k/mm/sun3mmu.c
|
||
--- linux-i386/arch/m68k/mm/sun3mmu.c 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/arch/m68k/mm/sun3mmu.c 2006-05-11 13:14:11.000000000 +0200
|
||
@@ -46,10 +46,9 @@
|
||
unsigned long address;
|
||
unsigned long next_pgtable;
|
||
unsigned long bootmem_end;
|
||
- unsigned long zones_size[3] = {0, 0, 0};
|
||
+ unsigned long zones_size[MAX_NR_ZONES] = { 0, };
|
||
unsigned long size;
|
||
|
||
-
|
||
#ifdef TEST_VERIFY_AREA
|
||
wp_works_ok = 0;
|
||
#endif
|
||
@@ -92,10 +91,13 @@
|
||
current->mm = NULL;
|
||
|
||
/* memory sizing is a hack stolen from motorola.c.. hope it works for us */
|
||
- zones_size[0] = ((unsigned long)high_memory - PAGE_OFFSET) >> PAGE_SHIFT;
|
||
- zones_size[1] = 0;
|
||
+ zones_size[ZONE_DMA] = ((unsigned long)high_memory - PAGE_OFFSET) >> PAGE_SHIFT;
|
||
+
|
||
+ /* I really wish I knew why the following change made things better... -- Sam */
|
||
+/* free_area_init(zones_size); */
|
||
+ free_area_init_node(0, NODE_DATA(0), zones_size,
|
||
+ (__pa(PAGE_OFFSET) >> PAGE_SHIFT) + 1, NULL);
|
||
|
||
- free_area_init(zones_size);
|
||
|
||
}
|
||
|
||
diff -urN linux-i386/arch/m68k/mvme147/Makefile linux-m68k/arch/m68k/mvme147/Makefile
|
||
--- linux-i386/arch/m68k/mvme147/Makefile 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/arch/m68k/mvme147/Makefile 2006-01-28 22:36:38.000000000 +0100
|
||
@@ -2,4 +2,4 @@
|
||
# Makefile for Linux arch/m68k/mvme147 source directory
|
||
#
|
||
|
||
-obj-y := config.o 147ints.o
|
||
+obj-y := config.o
|
||
diff -urN linux-i386/arch/m68k/mvme147/config.c linux-m68k/arch/m68k/mvme147/config.c
|
||
--- linux-i386/arch/m68k/mvme147/config.c 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/arch/m68k/mvme147/config.c 2006-01-28 22:36:38.000000000 +0100
|
||
@@ -36,15 +36,8 @@
|
||
#include <asm/mvme147hw.h>
|
||
|
||
|
||
-extern irqreturn_t mvme147_process_int (int level, struct pt_regs *regs);
|
||
-extern void mvme147_init_IRQ (void);
|
||
-extern void mvme147_free_irq (unsigned int, void *);
|
||
-extern int show_mvme147_interrupts (struct seq_file *, void *);
|
||
-extern void mvme147_enable_irq (unsigned int);
|
||
-extern void mvme147_disable_irq (unsigned int);
|
||
static void mvme147_get_model(char *model);
|
||
static int mvme147_get_hardware_list(char *buffer);
|
||
-extern int mvme147_request_irq (unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_regs *), unsigned long flags, const char *devname, void *dev_id);
|
||
extern void mvme147_sched_init(irqreturn_t (*handler)(int, void *, struct pt_regs *));
|
||
extern unsigned long mvme147_gettimeoffset (void);
|
||
extern int mvme147_hwclk (int, struct rtc_time *);
|
||
@@ -91,6 +84,15 @@
|
||
return 0;
|
||
}
|
||
|
||
+/*
|
||
+ * This function is called during kernel startup to initialize
|
||
+ * the mvme147 IRQ handling routines.
|
||
+ */
|
||
+
|
||
+void mvme147_init_IRQ(void)
|
||
+{
|
||
+ m68k_setup_user_interrupt(VEC_USER, 192, NULL);
|
||
+}
|
||
|
||
void __init config_mvme147(void)
|
||
{
|
||
@@ -101,12 +103,6 @@
|
||
mach_hwclk = mvme147_hwclk;
|
||
mach_set_clock_mmss = mvme147_set_clock_mmss;
|
||
mach_reset = mvme147_reset;
|
||
- mach_free_irq = mvme147_free_irq;
|
||
- mach_process_int = mvme147_process_int;
|
||
- mach_get_irq_list = show_mvme147_interrupts;
|
||
- mach_request_irq = mvme147_request_irq;
|
||
- enable_irq = mvme147_enable_irq;
|
||
- disable_irq = mvme147_disable_irq;
|
||
mach_get_model = mvme147_get_model;
|
||
mach_get_hardware_list = mvme147_get_hardware_list;
|
||
|
||
diff -urN linux-i386/arch/m68k/mvme16x/Makefile linux-m68k/arch/m68k/mvme16x/Makefile
|
||
--- linux-i386/arch/m68k/mvme16x/Makefile 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/arch/m68k/mvme16x/Makefile 2006-01-28 22:37:06.000000000 +0100
|
||
@@ -2,4 +2,4 @@
|
||
# Makefile for Linux arch/m68k/mvme16x source directory
|
||
#
|
||
|
||
-obj-y := config.o 16xints.o rtc.o mvme16x_ksyms.o
|
||
+obj-y := config.o rtc.o mvme16x_ksyms.o
|
||
diff -urN linux-i386/arch/m68k/mvme16x/config.c linux-m68k/arch/m68k/mvme16x/config.c
|
||
--- linux-i386/arch/m68k/mvme16x/config.c 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/arch/m68k/mvme16x/config.c 2006-01-28 22:37:06.000000000 +0100
|
||
@@ -40,15 +40,8 @@
|
||
|
||
static MK48T08ptr_t volatile rtc = (MK48T08ptr_t)MVME_RTC_BASE;
|
||
|
||
-extern irqreturn_t mvme16x_process_int (int level, struct pt_regs *regs);
|
||
-extern void mvme16x_init_IRQ (void);
|
||
-extern void mvme16x_free_irq (unsigned int, void *);
|
||
-extern int show_mvme16x_interrupts (struct seq_file *, void *);
|
||
-extern void mvme16x_enable_irq (unsigned int);
|
||
-extern void mvme16x_disable_irq (unsigned int);
|
||
static void mvme16x_get_model(char *model);
|
||
static int mvme16x_get_hardware_list(char *buffer);
|
||
-extern int mvme16x_request_irq(unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_regs *), unsigned long flags, const char *devname, void *dev_id);
|
||
extern void mvme16x_sched_init(irqreturn_t (*handler)(int, void *, struct pt_regs *));
|
||
extern unsigned long mvme16x_gettimeoffset (void);
|
||
extern int mvme16x_hwclk (int, struct rtc_time *);
|
||
@@ -120,6 +113,16 @@
|
||
return (len);
|
||
}
|
||
|
||
+/*
|
||
+ * This function is called during kernel startup to initialize
|
||
+ * the mvme16x IRQ handling routines. Should probably ensure
|
||
+ * that the base vectors for the VMEChip2 and PCCChip2 are valid.
|
||
+ */
|
||
+
|
||
+static void mvme16x_init_IRQ (void)
|
||
+{
|
||
+ m68k_setup_user_interrupt(VEC_USER, 192, NULL);
|
||
+}
|
||
|
||
#define pcc2chip ((volatile u_char *)0xfff42000)
|
||
#define PccSCCMICR 0x1d
|
||
@@ -138,12 +141,6 @@
|
||
mach_hwclk = mvme16x_hwclk;
|
||
mach_set_clock_mmss = mvme16x_set_clock_mmss;
|
||
mach_reset = mvme16x_reset;
|
||
- mach_free_irq = mvme16x_free_irq;
|
||
- mach_process_int = mvme16x_process_int;
|
||
- mach_get_irq_list = show_mvme16x_interrupts;
|
||
- mach_request_irq = mvme16x_request_irq;
|
||
- enable_irq = mvme16x_enable_irq;
|
||
- disable_irq = mvme16x_disable_irq;
|
||
mach_get_model = mvme16x_get_model;
|
||
mach_get_hardware_list = mvme16x_get_hardware_list;
|
||
|
||
diff -urN linux-i386/arch/m68k/q40/config.c linux-m68k/arch/m68k/q40/config.c
|
||
--- linux-i386/arch/m68k/q40/config.c 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/arch/m68k/q40/config.c 2006-04-10 00:21:47.000000000 +0200
|
||
@@ -37,15 +37,9 @@
|
||
#include <asm/q40_master.h>
|
||
|
||
extern irqreturn_t q40_process_int (int level, struct pt_regs *regs);
|
||
-extern irqreturn_t (*q40_default_handler[]) (int, void *, struct pt_regs *); /* added just for debugging */
|
||
extern void q40_init_IRQ (void);
|
||
-extern void q40_free_irq (unsigned int, void *);
|
||
-extern int show_q40_interrupts (struct seq_file *, void *);
|
||
-extern void q40_enable_irq (unsigned int);
|
||
-extern void q40_disable_irq (unsigned int);
|
||
static void q40_get_model(char *model);
|
||
static int q40_get_hardware_list(char *buffer);
|
||
-extern int q40_request_irq(unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_regs *), unsigned long flags, const char *devname, void *dev_id);
|
||
extern void q40_sched_init(irqreturn_t (*handler)(int, void *, struct pt_regs *));
|
||
|
||
extern unsigned long q40_gettimeoffset (void);
|
||
@@ -175,13 +169,6 @@
|
||
mach_set_clock_mmss = q40_set_clock_mmss;
|
||
|
||
mach_reset = q40_reset;
|
||
- mach_free_irq = q40_free_irq;
|
||
- mach_process_int = q40_process_int;
|
||
- mach_get_irq_list = show_q40_interrupts;
|
||
- mach_request_irq = q40_request_irq;
|
||
- enable_irq = q40_enable_irq;
|
||
- disable_irq = q40_disable_irq;
|
||
- mach_default_handler = &q40_default_handler;
|
||
mach_get_model = q40_get_model;
|
||
mach_get_hardware_list = q40_get_hardware_list;
|
||
|
||
diff -urN linux-i386/arch/m68k/q40/q40ints.c linux-m68k/arch/m68k/q40/q40ints.c
|
||
--- linux-i386/arch/m68k/q40/q40ints.c 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/arch/m68k/q40/q40ints.c 2006-01-28 22:37:37.000000000 +0100
|
||
@@ -14,13 +14,8 @@
|
||
#include <linux/types.h>
|
||
#include <linux/kernel.h>
|
||
#include <linux/errno.h>
|
||
-#include <linux/string.h>
|
||
-#include <linux/sched.h>
|
||
-#include <linux/seq_file.h>
|
||
#include <linux/interrupt.h>
|
||
-#include <linux/hardirq.h>
|
||
|
||
-#include <asm/rtc.h>
|
||
#include <asm/ptrace.h>
|
||
#include <asm/system.h>
|
||
#include <asm/irq.h>
|
||
@@ -39,29 +34,37 @@
|
||
*
|
||
*/
|
||
|
||
-extern int ints_inited;
|
||
+static void q40_irq_handler(unsigned int, struct pt_regs *fp);
|
||
+static void q40_enable_irq(unsigned int);
|
||
+static void q40_disable_irq(unsigned int);
|
||
|
||
+unsigned short q40_ablecount[35];
|
||
+unsigned short q40_state[35];
|
||
|
||
-irqreturn_t q40_irq2_handler (int, void *, struct pt_regs *fp);
|
||
-
|
||
-
|
||
-static irqreturn_t q40_defhand (int irq, void *dev_id, struct pt_regs *fp);
|
||
-static irqreturn_t default_handler(int lev, void *dev_id, struct pt_regs *regs);
|
||
-
|
||
-
|
||
-#define DEVNAME_SIZE 24
|
||
+static int q40_irq_startup(unsigned int irq)
|
||
+{
|
||
+ /* test for ISA ints not implemented by HW */
|
||
+ switch (irq) {
|
||
+ case 1: case 2: case 8: case 9:
|
||
+ case 11: case 12: case 13:
|
||
+ printk("%s: ISA IRQ %d not implemented by HW\n", __FUNCTION__, irq);
|
||
+ return -ENXIO;
|
||
+ }
|
||
+ return 0;
|
||
+}
|
||
|
||
-static struct q40_irq_node {
|
||
- irqreturn_t (*handler)(int, void *, struct pt_regs *);
|
||
- unsigned long flags;
|
||
- void *dev_id;
|
||
- /* struct q40_irq_node *next;*/
|
||
- char devname[DEVNAME_SIZE];
|
||
- unsigned count;
|
||
- unsigned short state;
|
||
-} irq_tab[Q40_IRQ_MAX+1];
|
||
+static void q40_irq_shutdown(unsigned int irq)
|
||
+{
|
||
+}
|
||
|
||
-short unsigned q40_ablecount[Q40_IRQ_MAX+1];
|
||
+static struct irq_controller q40_irq_controller = {
|
||
+ .name = "q40",
|
||
+ .lock = SPIN_LOCK_UNLOCKED,
|
||
+ .startup = q40_irq_startup,
|
||
+ .shutdown = q40_irq_shutdown,
|
||
+ .enable = q40_enable_irq,
|
||
+ .disable = q40_disable_irq,
|
||
+};
|
||
|
||
/*
|
||
* void q40_init_IRQ (void)
|
||
@@ -74,139 +77,29 @@
|
||
* the q40 IRQ handling routines.
|
||
*/
|
||
|
||
-static int disabled=0;
|
||
+static int disabled;
|
||
|
||
-void q40_init_IRQ (void)
|
||
+void q40_init_IRQ(void)
|
||
{
|
||
- int i;
|
||
-
|
||
- disabled=0;
|
||
- for (i = 0; i <= Q40_IRQ_MAX; i++) {
|
||
- irq_tab[i].handler = q40_defhand;
|
||
- irq_tab[i].flags = 0;
|
||
- irq_tab[i].dev_id = NULL;
|
||
- /* irq_tab[i].next = NULL;*/
|
||
- irq_tab[i].devname[0] = 0;
|
||
- irq_tab[i].count = 0;
|
||
- irq_tab[i].state =0;
|
||
- q40_ablecount[i]=0; /* all enabled */
|
||
- }
|
||
+ m68k_setup_irq_controller(&q40_irq_controller, 1, Q40_IRQ_MAX);
|
||
|
||
/* setup handler for ISA ints */
|
||
- cpu_request_irq(IRQ2, q40_irq2_handler, 0, "q40 ISA and master chip",
|
||
- NULL);
|
||
+ m68k_setup_auto_interrupt(q40_irq_handler);
|
||
+
|
||
+ m68k_irq_startup(IRQ_AUTO_2);
|
||
+ m68k_irq_startup(IRQ_AUTO_4);
|
||
|
||
/* now enable some ints.. */
|
||
- master_outb(1,EXT_ENABLE_REG); /* ISA IRQ 5-15 */
|
||
+ master_outb(1, EXT_ENABLE_REG); /* ISA IRQ 5-15 */
|
||
|
||
/* make sure keyboard IRQ is disabled */
|
||
- master_outb(0,KEY_IRQ_ENABLE_REG);
|
||
+ master_outb(0, KEY_IRQ_ENABLE_REG);
|
||
}
|
||
|
||
-int q40_request_irq(unsigned int irq,
|
||
- irqreturn_t (*handler)(int, void *, struct pt_regs *),
|
||
- unsigned long flags, const char *devname, void *dev_id)
|
||
-{
|
||
- /*printk("q40_request_irq %d, %s\n",irq,devname);*/
|
||
-
|
||
- if (irq > Q40_IRQ_MAX || (irq>15 && irq<32)) {
|
||
- printk("%s: Incorrect IRQ %d from %s\n", __FUNCTION__, irq, devname);
|
||
- return -ENXIO;
|
||
- }
|
||
-
|
||
- /* test for ISA ints not implemented by HW */
|
||
- switch (irq)
|
||
- {
|
||
- case 1: case 2: case 8: case 9:
|
||
- case 12: case 13:
|
||
- printk("%s: ISA IRQ %d from %s not implemented by HW\n", __FUNCTION__, irq, devname);
|
||
- return -ENXIO;
|
||
- case 11:
|
||
- printk("warning IRQ 10 and 11 not distinguishable\n");
|
||
- irq=10;
|
||
- default:
|
||
- ;
|
||
- }
|
||
-
|
||
- if (irq<Q40_IRQ_SAMPLE)
|
||
- {
|
||
- if (irq_tab[irq].dev_id != NULL)
|
||
- {
|
||
- printk("%s: IRQ %d from %s is not replaceable\n",
|
||
- __FUNCTION__, irq, irq_tab[irq].devname);
|
||
- return -EBUSY;
|
||
- }
|
||
- /*printk("IRQ %d set to handler %p\n",irq,handler);*/
|
||
- if (dev_id==NULL)
|
||
- {
|
||
- printk("WARNING: dev_id == NULL in request_irq\n");
|
||
- dev_id=(void*)1;
|
||
- }
|
||
- irq_tab[irq].handler = handler;
|
||
- irq_tab[irq].flags = flags;
|
||
- irq_tab[irq].dev_id = dev_id;
|
||
- strlcpy(irq_tab[irq].devname,devname,sizeof(irq_tab[irq].devname));
|
||
- irq_tab[irq].state = 0;
|
||
- return 0;
|
||
- }
|
||
- else {
|
||
- /* Q40_IRQ_SAMPLE :somewhat special actions required here ..*/
|
||
- cpu_request_irq(4, handler, flags, devname, dev_id);
|
||
- cpu_request_irq(6, handler, flags, devname, dev_id);
|
||
- return 0;
|
||
- }
|
||
-}
|
||
-
|
||
-void q40_free_irq(unsigned int irq, void *dev_id)
|
||
-{
|
||
- if (irq > Q40_IRQ_MAX || (irq>15 && irq<32)) {
|
||
- printk("%s: Incorrect IRQ %d, dev_id %x \n", __FUNCTION__, irq, (unsigned)dev_id);
|
||
- return;
|
||
- }
|
||
-
|
||
- /* test for ISA ints not implemented by HW */
|
||
- switch (irq)
|
||
- {
|
||
- case 1: case 2: case 8: case 9:
|
||
- case 12: case 13:
|
||
- printk("%s: ISA IRQ %d from %x invalid\n", __FUNCTION__, irq, (unsigned)dev_id);
|
||
- return;
|
||
- case 11: irq=10;
|
||
- default:
|
||
- ;
|
||
- }
|
||
-
|
||
- if (irq<Q40_IRQ_SAMPLE)
|
||
- {
|
||
- if (irq_tab[irq].dev_id != dev_id)
|
||
- printk("%s: Removing probably wrong IRQ %d from %s\n",
|
||
- __FUNCTION__, irq, irq_tab[irq].devname);
|
||
-
|
||
- irq_tab[irq].handler = q40_defhand;
|
||
- irq_tab[irq].flags = 0;
|
||
- irq_tab[irq].dev_id = NULL;
|
||
- /* irq_tab[irq].devname = NULL; */
|
||
- /* do not reset state !! */
|
||
- }
|
||
- else
|
||
- { /* == Q40_IRQ_SAMPLE */
|
||
- cpu_free_irq(4, dev_id);
|
||
- cpu_free_irq(6, dev_id);
|
||
- }
|
||
-}
|
||
-
|
||
-
|
||
-irqreturn_t q40_process_int (int level, struct pt_regs *fp)
|
||
-{
|
||
- printk("unexpected interrupt vec=%x, pc=%lx, d0=%lx, d0_orig=%lx, d1=%lx, d2=%lx\n",
|
||
- level, fp->pc, fp->d0, fp->orig_d0, fp->d1, fp->d2);
|
||
- printk("\tIIRQ_REG = %x, EIRQ_REG = %x\n",master_inb(IIRQ_REG),master_inb(EIRQ_REG));
|
||
- return IRQ_HANDLED;
|
||
-}
|
||
|
||
/*
|
||
* this stuff doesn't really belong here..
|
||
-*/
|
||
+ */
|
||
|
||
int ql_ticks; /* 200Hz ticks since last jiffie */
|
||
static int sound_ticks;
|
||
@@ -215,54 +108,53 @@
|
||
|
||
void q40_mksound(unsigned int hz, unsigned int ticks)
|
||
{
|
||
- /* for now ignore hz, except that hz==0 switches off sound */
|
||
- /* simply alternate the ampl (128-SVOL)-(128+SVOL)-..-.. at 200Hz */
|
||
- if (hz==0)
|
||
- {
|
||
- if (sound_ticks)
|
||
- sound_ticks=1;
|
||
-
|
||
- *DAC_LEFT=128;
|
||
- *DAC_RIGHT=128;
|
||
-
|
||
- return;
|
||
- }
|
||
- /* sound itself is done in q40_timer_int */
|
||
- if (sound_ticks == 0) sound_ticks=1000; /* pretty long beep */
|
||
- sound_ticks=ticks<<1;
|
||
+ /* for now ignore hz, except that hz==0 switches off sound */
|
||
+ /* simply alternate the ampl (128-SVOL)-(128+SVOL)-..-.. at 200Hz */
|
||
+ if (hz == 0) {
|
||
+ if (sound_ticks)
|
||
+ sound_ticks = 1;
|
||
+
|
||
+ *DAC_LEFT = 128;
|
||
+ *DAC_RIGHT = 128;
|
||
+
|
||
+ return;
|
||
+ }
|
||
+ /* sound itself is done in q40_timer_int */
|
||
+ if (sound_ticks == 0)
|
||
+ sound_ticks = 1000; /* pretty long beep */
|
||
+ sound_ticks = ticks << 1;
|
||
}
|
||
|
||
static irqreturn_t (*q40_timer_routine)(int, void *, struct pt_regs *);
|
||
|
||
static irqreturn_t q40_timer_int (int irq, void * dev, struct pt_regs * regs)
|
||
{
|
||
- ql_ticks = ql_ticks ? 0 : 1;
|
||
- if (sound_ticks)
|
||
- {
|
||
- unsigned char sval=(sound_ticks & 1) ? 128-SVOL : 128+SVOL;
|
||
- sound_ticks--;
|
||
- *DAC_LEFT=sval;
|
||
- *DAC_RIGHT=sval;
|
||
- }
|
||
-
|
||
- if (!ql_ticks)
|
||
- q40_timer_routine(irq, dev, regs);
|
||
- return IRQ_HANDLED;
|
||
+ ql_ticks = ql_ticks ? 0 : 1;
|
||
+ if (sound_ticks) {
|
||
+ unsigned char sval=(sound_ticks & 1) ? 128-SVOL : 128+SVOL;
|
||
+ sound_ticks--;
|
||
+ *DAC_LEFT=sval;
|
||
+ *DAC_RIGHT=sval;
|
||
+ }
|
||
+
|
||
+ if (!ql_ticks)
|
||
+ q40_timer_routine(irq, dev, regs);
|
||
+ return IRQ_HANDLED;
|
||
}
|
||
|
||
void q40_sched_init (irqreturn_t (*timer_routine)(int, void *, struct pt_regs *))
|
||
{
|
||
- int timer_irq;
|
||
+ int timer_irq;
|
||
|
||
- q40_timer_routine = timer_routine;
|
||
- timer_irq=Q40_IRQ_FRAME;
|
||
+ q40_timer_routine = timer_routine;
|
||
+ timer_irq = Q40_IRQ_FRAME;
|
||
|
||
- if (request_irq(timer_irq, q40_timer_int, 0,
|
||
+ if (request_irq(timer_irq, q40_timer_int, 0,
|
||
"timer", q40_timer_int))
|
||
- panic ("Couldn't register timer int");
|
||
+ panic("Couldn't register timer int");
|
||
|
||
- master_outb(-1,FRAME_CLEAR_REG);
|
||
- master_outb( 1,FRAME_RATE_REG);
|
||
+ master_outb(-1, FRAME_CLEAR_REG);
|
||
+ master_outb( 1, FRAME_RATE_REG);
|
||
}
|
||
|
||
|
||
@@ -308,169 +200,132 @@
|
||
static int aliased_irq=0; /* how many times inside handler ?*/
|
||
|
||
|
||
-/* got level 2 interrupt, dispatch to ISA or keyboard/timer IRQs */
|
||
-irqreturn_t q40_irq2_handler (int vec, void *devname, struct pt_regs *fp)
|
||
+/* got interrupt, dispatch to ISA or keyboard/timer IRQs */
|
||
+static void q40_irq_handler(unsigned int irq, struct pt_regs *fp)
|
||
{
|
||
- unsigned mir, mer;
|
||
- int irq,i;
|
||
+ unsigned mir, mer;
|
||
+ int i;
|
||
|
||
//repeat:
|
||
- mir=master_inb(IIRQ_REG);
|
||
- if (mir&Q40_IRQ_FRAME_MASK) {
|
||
- irq_tab[Q40_IRQ_FRAME].count++;
|
||
- irq_tab[Q40_IRQ_FRAME].handler(Q40_IRQ_FRAME,irq_tab[Q40_IRQ_FRAME].dev_id,fp);
|
||
- master_outb(-1,FRAME_CLEAR_REG);
|
||
- }
|
||
- if ((mir&Q40_IRQ_SER_MASK) || (mir&Q40_IRQ_EXT_MASK)) {
|
||
- mer=master_inb(EIRQ_REG);
|
||
- for (i=0; eirqs[i].mask; i++) {
|
||
- if (mer&(eirqs[i].mask)) {
|
||
- irq=eirqs[i].irq;
|
||
+ mir = master_inb(IIRQ_REG);
|
||
+#ifdef CONFIG_BLK_DEV_FD
|
||
+ if ((mir & Q40_IRQ_EXT_MASK) &&
|
||
+ (master_inb(EIRQ_REG) & Q40_IRQ6_MASK)) {
|
||
+ floppy_hardint();
|
||
+ return;
|
||
+ }
|
||
+#endif
|
||
+ switch (irq) {
|
||
+ case 4:
|
||
+ case 6:
|
||
+ m68k_handle_int(Q40_IRQ_SAMPLE, fp);
|
||
+ return;
|
||
+ }
|
||
+ if (mir & Q40_IRQ_FRAME_MASK) {
|
||
+ m68k_handle_int(Q40_IRQ_FRAME, fp);
|
||
+ master_outb(-1, FRAME_CLEAR_REG);
|
||
+ }
|
||
+ if ((mir & Q40_IRQ_SER_MASK) || (mir & Q40_IRQ_EXT_MASK)) {
|
||
+ mer = master_inb(EIRQ_REG);
|
||
+ for (i = 0; eirqs[i].mask; i++) {
|
||
+ if (mer & eirqs[i].mask) {
|
||
+ irq = eirqs[i].irq;
|
||
/*
|
||
* There is a little mess wrt which IRQ really caused this irq request. The
|
||
* main problem is that IIRQ_REG and EIRQ_REG reflect the state when they
|
||
* are read - which is long after the request came in. In theory IRQs should
|
||
* not just go away but they occassionally do
|
||
*/
|
||
- if (irq>4 && irq<=15 && mext_disabled) {
|
||
- /*aliased_irq++;*/
|
||
- goto iirq;
|
||
- }
|
||
- if (irq_tab[irq].handler == q40_defhand ) {
|
||
- printk("handler for IRQ %d not defined\n",irq);
|
||
- continue; /* ignore uninited INTs :-( */
|
||
- }
|
||
- if ( irq_tab[irq].state & IRQ_INPROGRESS ) {
|
||
- /* some handlers do local_irq_enable() for irq latency reasons, */
|
||
- /* however reentering an active irq handler is not permitted */
|
||
+ if (irq > 4 && irq <= 15 && mext_disabled) {
|
||
+ /*aliased_irq++;*/
|
||
+ goto iirq;
|
||
+ }
|
||
+ if (q40_state[irq] & IRQ_INPROGRESS) {
|
||
+ /* some handlers do local_irq_enable() for irq latency reasons, */
|
||
+ /* however reentering an active irq handler is not permitted */
|
||
#ifdef IP_USE_DISABLE
|
||
- /* in theory this is the better way to do it because it still */
|
||
- /* lets through eg the serial irqs, unfortunately it crashes */
|
||
- disable_irq(irq);
|
||
- disabled=1;
|
||
+ /* in theory this is the better way to do it because it still */
|
||
+ /* lets through eg the serial irqs, unfortunately it crashes */
|
||
+ disable_irq(irq);
|
||
+ disabled = 1;
|
||
#else
|
||
- /*printk("IRQ_INPROGRESS detected for irq %d, disabling - %s disabled\n",irq,disabled ? "already" : "not yet"); */
|
||
- fp->sr = (((fp->sr) & (~0x700))+0x200);
|
||
- disabled=1;
|
||
+ /*printk("IRQ_INPROGRESS detected for irq %d, disabling - %s disabled\n",
|
||
+ irq, disabled ? "already" : "not yet"); */
|
||
+ fp->sr = (((fp->sr) & (~0x700))+0x200);
|
||
+ disabled = 1;
|
||
#endif
|
||
- goto iirq;
|
||
- }
|
||
- irq_tab[irq].count++;
|
||
- irq_tab[irq].state |= IRQ_INPROGRESS;
|
||
- irq_tab[irq].handler(irq,irq_tab[irq].dev_id,fp);
|
||
- irq_tab[irq].state &= ~IRQ_INPROGRESS;
|
||
-
|
||
- /* naively enable everything, if that fails than */
|
||
- /* this function will be reentered immediately thus */
|
||
- /* getting another chance to disable the IRQ */
|
||
+ goto iirq;
|
||
+ }
|
||
+ q40_state[irq] |= IRQ_INPROGRESS;
|
||
+ m68k_handle_int(irq, fp);
|
||
+ q40_state[irq] &= ~IRQ_INPROGRESS;
|
||
+
|
||
+ /* naively enable everything, if that fails than */
|
||
+ /* this function will be reentered immediately thus */
|
||
+ /* getting another chance to disable the IRQ */
|
||
|
||
- if ( disabled ) {
|
||
+ if (disabled) {
|
||
#ifdef IP_USE_DISABLE
|
||
- if (irq>4){
|
||
- disabled=0;
|
||
- enable_irq(irq);}
|
||
+ if (irq > 4) {
|
||
+ disabled = 0;
|
||
+ enable_irq(irq);
|
||
+ }
|
||
#else
|
||
- disabled=0;
|
||
- /*printk("reenabling irq %d\n",irq); */
|
||
+ disabled = 0;
|
||
+ /*printk("reenabling irq %d\n", irq); */
|
||
#endif
|
||
- }
|
||
+ }
|
||
// used to do 'goto repeat;' here, this delayed bh processing too long
|
||
- return IRQ_HANDLED;
|
||
- }
|
||
- }
|
||
- if (mer && ccleirq>0 && !aliased_irq)
|
||
- printk("ISA interrupt from unknown source? EIRQ_REG = %x\n",mer),ccleirq--;
|
||
- }
|
||
+ return;
|
||
+ }
|
||
+ }
|
||
+ if (mer && ccleirq > 0 && !aliased_irq) {
|
||
+ printk("ISA interrupt from unknown source? EIRQ_REG = %x\n",mer);
|
||
+ ccleirq--;
|
||
+ }
|
||
+ }
|
||
iirq:
|
||
- mir=master_inb(IIRQ_REG);
|
||
- /* should test whether keyboard irq is really enabled, doing it in defhand */
|
||
- if (mir&Q40_IRQ_KEYB_MASK) {
|
||
- irq_tab[Q40_IRQ_KEYBOARD].count++;
|
||
- irq_tab[Q40_IRQ_KEYBOARD].handler(Q40_IRQ_KEYBOARD,irq_tab[Q40_IRQ_KEYBOARD].dev_id,fp);
|
||
- }
|
||
- return IRQ_HANDLED;
|
||
-}
|
||
-
|
||
-int show_q40_interrupts (struct seq_file *p, void *v)
|
||
-{
|
||
- int i;
|
||
-
|
||
- for (i = 0; i <= Q40_IRQ_MAX; i++) {
|
||
- if (irq_tab[i].count)
|
||
- seq_printf(p, "%sIRQ %02d: %8d %s%s\n",
|
||
- (i<=15) ? "ISA-" : " " ,
|
||
- i, irq_tab[i].count,
|
||
- irq_tab[i].devname[0] ? irq_tab[i].devname : "?",
|
||
- irq_tab[i].handler == q40_defhand ?
|
||
- " (now unassigned)" : "");
|
||
+ mir = master_inb(IIRQ_REG);
|
||
+ /* should test whether keyboard irq is really enabled, doing it in defhand */
|
||
+ if (mir & Q40_IRQ_KEYB_MASK)
|
||
+ m68k_handle_int(Q40_IRQ_KEYBOARD, fp);
|
||
+
|
||
+ return;
|
||
+}
|
||
+
|
||
+void q40_enable_irq(unsigned int irq)
|
||
+{
|
||
+ if (irq >= 5 && irq <= 15) {
|
||
+ mext_disabled--;
|
||
+ if (mext_disabled > 0)
|
||
+ printk("q40_enable_irq : nested disable/enable\n");
|
||
+ if (mext_disabled == 0)
|
||
+ master_outb(1, EXT_ENABLE_REG);
|
||
}
|
||
- return 0;
|
||
}
|
||
|
||
|
||
-static irqreturn_t q40_defhand (int irq, void *dev_id, struct pt_regs *fp)
|
||
-{
|
||
- if (irq!=Q40_IRQ_KEYBOARD)
|
||
- printk ("Unknown q40 interrupt %d\n", irq);
|
||
- else master_outb(-1,KEYBOARD_UNLOCK_REG);
|
||
- return IRQ_NONE;
|
||
-}
|
||
-static irqreturn_t default_handler(int lev, void *dev_id, struct pt_regs *regs)
|
||
-{
|
||
- printk ("Uninitialised interrupt level %d\n", lev);
|
||
- return IRQ_NONE;
|
||
-}
|
||
-
|
||
-irqreturn_t (*q40_default_handler[SYS_IRQS])(int, void *, struct pt_regs *) = {
|
||
- [0] = default_handler,
|
||
- [1] = default_handler,
|
||
- [2] = default_handler,
|
||
- [3] = default_handler,
|
||
- [4] = default_handler,
|
||
- [5] = default_handler,
|
||
- [6] = default_handler,
|
||
- [7] = default_handler
|
||
-};
|
||
-
|
||
-
|
||
-void q40_enable_irq (unsigned int irq)
|
||
+void q40_disable_irq(unsigned int irq)
|
||
{
|
||
- if ( irq>=5 && irq<=15 )
|
||
- {
|
||
- mext_disabled--;
|
||
- if (mext_disabled>0)
|
||
- printk("q40_enable_irq : nested disable/enable\n");
|
||
- if (mext_disabled==0)
|
||
- master_outb(1,EXT_ENABLE_REG);
|
||
- }
|
||
-}
|
||
-
|
||
-
|
||
-void q40_disable_irq (unsigned int irq)
|
||
-{
|
||
- /* disable ISA iqs : only do something if the driver has been
|
||
- * verified to be Q40 "compatible" - right now IDE, NE2K
|
||
- * Any driver should not attempt to sleep across disable_irq !!
|
||
- */
|
||
-
|
||
- if ( irq>=5 && irq<=15 ) {
|
||
- master_outb(0,EXT_ENABLE_REG);
|
||
- mext_disabled++;
|
||
- if (mext_disabled>1) printk("disable_irq nesting count %d\n",mext_disabled);
|
||
- }
|
||
+ /* disable ISA iqs : only do something if the driver has been
|
||
+ * verified to be Q40 "compatible" - right now IDE, NE2K
|
||
+ * Any driver should not attempt to sleep across disable_irq !!
|
||
+ */
|
||
+
|
||
+ if (irq >= 5 && irq <= 15) {
|
||
+ master_outb(0, EXT_ENABLE_REG);
|
||
+ mext_disabled++;
|
||
+ if (mext_disabled > 1)
|
||
+ printk("disable_irq nesting count %d\n",mext_disabled);
|
||
+ }
|
||
}
|
||
|
||
-unsigned long q40_probe_irq_on (void)
|
||
+unsigned long q40_probe_irq_on(void)
|
||
{
|
||
- printk("irq probing not working - reconfigure the driver to avoid this\n");
|
||
- return -1;
|
||
+ printk("irq probing not working - reconfigure the driver to avoid this\n");
|
||
+ return -1;
|
||
}
|
||
-int q40_probe_irq_off (unsigned long irqs)
|
||
+int q40_probe_irq_off(unsigned long irqs)
|
||
{
|
||
- return -1;
|
||
+ return -1;
|
||
}
|
||
-/*
|
||
- * Local variables:
|
||
- * compile-command: "m68k-linux-gcc -D__KERNEL__ -I/home/rz/lx/linux-2.2.6/include -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -pipe -fno-strength-reduce -ffixed-a2 -m68040 -c -o q40ints.o q40ints.c"
|
||
- * End:
|
||
- */
|
||
diff -urN linux-i386/arch/m68k/sun3/config.c linux-m68k/arch/m68k/sun3/config.c
|
||
--- linux-i386/arch/m68k/sun3/config.c 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/arch/m68k/sun3/config.c 2006-01-28 22:37:55.000000000 +0100
|
||
@@ -36,7 +36,6 @@
|
||
char sun3_reserved_pmeg[SUN3_PMEGS_NUM];
|
||
|
||
extern unsigned long sun3_gettimeoffset(void);
|
||
-extern int show_sun3_interrupts (struct seq_file *, void *);
|
||
extern void sun3_sched_init(irqreturn_t (*handler)(int, void *, struct pt_regs *));
|
||
extern void sun3_get_model (char* model);
|
||
extern void idprom_init (void);
|
||
@@ -147,13 +146,6 @@
|
||
|
||
mach_sched_init = sun3_sched_init;
|
||
mach_init_IRQ = sun3_init_IRQ;
|
||
- mach_default_handler = &sun3_default_handler;
|
||
- mach_request_irq = sun3_request_irq;
|
||
- mach_free_irq = sun3_free_irq;
|
||
- enable_irq = sun3_enable_irq;
|
||
- disable_irq = sun3_disable_irq;
|
||
- mach_process_int = sun3_process_int;
|
||
- mach_get_irq_list = show_sun3_interrupts;
|
||
mach_reset = sun3_reboot;
|
||
mach_gettimeoffset = sun3_gettimeoffset;
|
||
mach_get_model = sun3_get_model;
|
||
diff -urN linux-i386/arch/m68k/sun3/sun3ints.c linux-m68k/arch/m68k/sun3/sun3ints.c
|
||
--- linux-i386/arch/m68k/sun3/sun3ints.c 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/arch/m68k/sun3/sun3ints.c 2006-01-28 22:37:55.000000000 +0100
|
||
@@ -19,7 +19,6 @@
|
||
#include <linux/seq_file.h>
|
||
|
||
extern void sun3_leds (unsigned char);
|
||
-static irqreturn_t sun3_inthandle(int irq, void *dev_id, struct pt_regs *fp);
|
||
|
||
void sun3_disable_interrupts(void)
|
||
{
|
||
@@ -40,48 +39,30 @@
|
||
|
||
volatile unsigned char* sun3_intreg;
|
||
|
||
-void sun3_insert_irq(irq_node_t **list, irq_node_t *node)
|
||
-{
|
||
-}
|
||
-
|
||
-void sun3_delete_irq(irq_node_t **list, void *dev_id)
|
||
-{
|
||
-}
|
||
-
|
||
void sun3_enable_irq(unsigned int irq)
|
||
{
|
||
- *sun3_intreg |= (1<<irq);
|
||
+ *sun3_intreg |= (1 << irq);
|
||
}
|
||
|
||
void sun3_disable_irq(unsigned int irq)
|
||
{
|
||
- *sun3_intreg &= ~(1<<irq);
|
||
-}
|
||
-
|
||
-inline void sun3_do_irq(int irq, struct pt_regs *fp)
|
||
-{
|
||
- kstat_cpu(0).irqs[SYS_IRQS + irq]++;
|
||
- *sun3_intreg &= ~(1<<irq);
|
||
- *sun3_intreg |= (1<<irq);
|
||
+ *sun3_intreg &= ~(1 << irq);
|
||
}
|
||
|
||
static irqreturn_t sun3_int7(int irq, void *dev_id, struct pt_regs *fp)
|
||
{
|
||
- sun3_do_irq(irq,fp);
|
||
- if(!(kstat_cpu(0).irqs[SYS_IRQS + irq] % 2000))
|
||
- sun3_leds(led_pattern[(kstat_cpu(0).irqs[SYS_IRQS+irq]%16000)
|
||
- /2000]);
|
||
+ *sun3_intreg |= (1 << irq);
|
||
+ if (!(kstat_cpu(0).irqs[irq] % 2000))
|
||
+ sun3_leds(led_pattern[(kstat_cpu(0).irqs[irq] % 16000) / 2000]);
|
||
return IRQ_HANDLED;
|
||
}
|
||
|
||
static irqreturn_t sun3_int5(int irq, void *dev_id, struct pt_regs *fp)
|
||
{
|
||
- kstat_cpu(0).irqs[SYS_IRQS + irq]++;
|
||
#ifdef CONFIG_SUN3
|
||
intersil_clear();
|
||
#endif
|
||
- *sun3_intreg &= ~(1<<irq);
|
||
- *sun3_intreg |= (1<<irq);
|
||
+ *sun3_intreg |= (1 << irq);
|
||
#ifdef CONFIG_SUN3
|
||
intersil_clear();
|
||
#endif
|
||
@@ -89,65 +70,8 @@
|
||
#ifndef CONFIG_SMP
|
||
update_process_times(user_mode(fp));
|
||
#endif
|
||
- if(!(kstat_cpu(0).irqs[SYS_IRQS + irq] % 20))
|
||
- sun3_leds(led_pattern[(kstat_cpu(0).irqs[SYS_IRQS+irq]%160)
|
||
- /20]);
|
||
- return IRQ_HANDLED;
|
||
-}
|
||
-
|
||
-/* handle requested ints, excepting 5 and 7, which always do the same
|
||
- thing */
|
||
-irqreturn_t (*sun3_default_handler[SYS_IRQS])(int, void *, struct pt_regs *) = {
|
||
- [0] = sun3_inthandle,
|
||
- [1] = sun3_inthandle,
|
||
- [2] = sun3_inthandle,
|
||
- [3] = sun3_inthandle,
|
||
- [4] = sun3_inthandle,
|
||
- [5] = sun3_int5,
|
||
- [6] = sun3_inthandle,
|
||
- [7] = sun3_int7
|
||
-};
|
||
-
|
||
-static const char *dev_names[SYS_IRQS] = {
|
||
- [5] = "timer",
|
||
- [7] = "int7 handler"
|
||
-};
|
||
-static void *dev_ids[SYS_IRQS];
|
||
-static irqreturn_t (*sun3_inthandler[SYS_IRQS])(int, void *, struct pt_regs *) = {
|
||
- [5] = sun3_int5,
|
||
- [7] = sun3_int7
|
||
-};
|
||
-static irqreturn_t (*sun3_vechandler[SUN3_INT_VECS])(int, void *, struct pt_regs *);
|
||
-static void *vec_ids[SUN3_INT_VECS];
|
||
-static const char *vec_names[SUN3_INT_VECS];
|
||
-static int vec_ints[SUN3_INT_VECS];
|
||
-
|
||
-
|
||
-int show_sun3_interrupts(struct seq_file *p, void *v)
|
||
-{
|
||
- int i;
|
||
-
|
||
- for(i = 0; i < (SUN3_INT_VECS-1); i++) {
|
||
- if(sun3_vechandler[i] != NULL) {
|
||
- seq_printf(p, "vec %3d: %10u %s\n", i+64,
|
||
- vec_ints[i],
|
||
- (vec_names[i]) ? vec_names[i] :
|
||
- "sun3_vechandler");
|
||
- }
|
||
- }
|
||
-
|
||
- return 0;
|
||
-}
|
||
-
|
||
-static irqreturn_t sun3_inthandle(int irq, void *dev_id, struct pt_regs *fp)
|
||
-{
|
||
- if(sun3_inthandler[irq] == NULL)
|
||
- panic ("bad interrupt %d received (id %p)\n",irq, dev_id);
|
||
-
|
||
- kstat_cpu(0).irqs[SYS_IRQS + irq]++;
|
||
- *sun3_intreg &= ~(1<<irq);
|
||
-
|
||
- sun3_inthandler[irq](irq, dev_ids[irq], fp);
|
||
+ if (!(kstat_cpu(0).irqs[irq] % 20))
|
||
+ sun3_leds(led_pattern[(kstat_cpu(0).irqs[irq] % 160) / 20]);
|
||
return IRQ_HANDLED;
|
||
}
|
||
|
||
@@ -157,109 +81,31 @@
|
||
return IRQ_HANDLED;
|
||
}
|
||
|
||
-void sun3_init_IRQ(void)
|
||
-{
|
||
- int i;
|
||
-
|
||
- *sun3_intreg = 1;
|
||
-
|
||
- for(i = 0; i < SYS_IRQS; i++)
|
||
- {
|
||
- if(dev_names[i])
|
||
- cpu_request_irq(i, sun3_default_handler[i], 0,
|
||
- dev_names[i], NULL);
|
||
- }
|
||
-
|
||
- for(i = 0; i < 192; i++)
|
||
- sun3_vechandler[i] = NULL;
|
||
-
|
||
- sun3_vechandler[191] = sun3_vec255;
|
||
-}
|
||
-
|
||
-int sun3_request_irq(unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_regs *),
|
||
- unsigned long flags, const char *devname, void *dev_id)
|
||
+static void sun3_inthandle(unsigned int irq, struct pt_regs *fp)
|
||
{
|
||
+ *sun3_intreg &= ~(1 << irq);
|
||
|
||
- if(irq < SYS_IRQS) {
|
||
- if(sun3_inthandler[irq] != NULL) {
|
||
- printk("sun3_request_irq: request for irq %d -- already taken!\n", irq);
|
||
- return 1;
|
||
- }
|
||
-
|
||
- sun3_inthandler[irq] = handler;
|
||
- dev_ids[irq] = dev_id;
|
||
- dev_names[irq] = devname;
|
||
-
|
||
- /* setting devname would be nice */
|
||
- cpu_request_irq(irq, sun3_default_handler[irq], 0, devname,
|
||
- NULL);
|
||
-
|
||
- return 0;
|
||
- } else {
|
||
- if((irq >= 64) && (irq <= 255)) {
|
||
- int vec;
|
||
-
|
||
- vec = irq - 64;
|
||
- if(sun3_vechandler[vec] != NULL) {
|
||
- printk("sun3_request_irq: request for vec %d -- already taken!\n", irq);
|
||
- return 1;
|
||
- }
|
||
-
|
||
- sun3_vechandler[vec] = handler;
|
||
- vec_ids[vec] = dev_id;
|
||
- vec_names[vec] = devname;
|
||
- vec_ints[vec] = 0;
|
||
-
|
||
- return 0;
|
||
- }
|
||
- }
|
||
-
|
||
- printk("sun3_request_irq: invalid irq %d\n", irq);
|
||
- return 1;
|
||
-
|
||
+ m68k_handle_int(irq, fp);
|
||
}
|
||
|
||
-void sun3_free_irq(unsigned int irq, void *dev_id)
|
||
-{
|
||
-
|
||
- if(irq < SYS_IRQS) {
|
||
- if(sun3_inthandler[irq] == NULL)
|
||
- panic("sun3_free_int: attempt to free unused irq %d\n", irq);
|
||
- if(dev_ids[irq] != dev_id)
|
||
- panic("sun3_free_int: incorrect dev_id for irq %d\n", irq);
|
||
-
|
||
- sun3_inthandler[irq] = NULL;
|
||
- return;
|
||
- } else if((irq >= 64) && (irq <= 255)) {
|
||
- int vec;
|
||
-
|
||
- vec = irq - 64;
|
||
- if(sun3_vechandler[vec] == NULL)
|
||
- panic("sun3_free_int: attempt to free unused vector %d\n", irq);
|
||
- if(vec_ids[irq] != dev_id)
|
||
- panic("sun3_free_int: incorrect dev_id for vec %d\n", irq);
|
||
-
|
||
- sun3_vechandler[vec] = NULL;
|
||
- return;
|
||
- } else {
|
||
- panic("sun3_free_irq: invalid irq %d\n", irq);
|
||
- }
|
||
-}
|
||
+static struct irq_controller sun3_irq_controller = {
|
||
+ .name = "sun3",
|
||
+ .lock = SPIN_LOCK_UNLOCKED,
|
||
+ .startup = m68k_irq_startup,
|
||
+ .shutdown = m68k_irq_shutdown,
|
||
+ .enable = sun3_enable_irq,
|
||
+ .disable = sun3_disable_irq,
|
||
+};
|
||
|
||
-irqreturn_t sun3_process_int(int irq, struct pt_regs *regs)
|
||
+void sun3_init_IRQ(void)
|
||
{
|
||
+ *sun3_intreg = 1;
|
||
|
||
- if((irq >= 64) && (irq <= 255)) {
|
||
- int vec;
|
||
-
|
||
- vec = irq - 64;
|
||
- if(sun3_vechandler[vec] == NULL)
|
||
- panic ("bad interrupt vector %d received\n",irq);
|
||
-
|
||
- vec_ints[vec]++;
|
||
- return sun3_vechandler[vec](irq, vec_ids[vec], regs);
|
||
- } else {
|
||
- panic("sun3_process_int: unable to handle interrupt vector %d\n",
|
||
- irq);
|
||
- }
|
||
+ m68k_setup_auto_interrupt(sun3_inthandle);
|
||
+ m68k_setup_irq_controller(&sun3_irq_controller, IRQ_AUTO_1, 7);
|
||
+ m68k_setup_user_interrupt(VEC_USER, 192, NULL);
|
||
+
|
||
+ request_irq(IRQ_AUTO_5, sun3_int5, 0, "int5", NULL);
|
||
+ request_irq(IRQ_AUTO_7, sun3_int7, 0, "int7", NULL);
|
||
+ request_irq(IRQ_USER+127, sun3_vec255, 0, "vec255", NULL);
|
||
}
|
||
diff -urN linux-i386/arch/m68k/sun3x/config.c linux-m68k/arch/m68k/sun3x/config.c
|
||
--- linux-i386/arch/m68k/sun3x/config.c 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/arch/m68k/sun3x/config.c 2006-01-28 22:37:55.000000000 +0100
|
||
@@ -52,17 +52,10 @@
|
||
|
||
sun3x_prom_init();
|
||
|
||
- mach_get_irq_list = show_sun3_interrupts;
|
||
mach_max_dma_address = 0xffffffff; /* we can DMA anywhere, whee */
|
||
|
||
- mach_default_handler = &sun3_default_handler;
|
||
mach_sched_init = sun3x_sched_init;
|
||
mach_init_IRQ = sun3_init_IRQ;
|
||
- enable_irq = sun3_enable_irq;
|
||
- disable_irq = sun3_disable_irq;
|
||
- mach_request_irq = sun3_request_irq;
|
||
- mach_free_irq = sun3_free_irq;
|
||
- mach_process_int = sun3_process_int;
|
||
|
||
mach_gettimeoffset = sun3x_gettimeoffset;
|
||
mach_reset = sun3x_reboot;
|
||
diff -urN linux-i386/drivers/block/amiflop.c linux-m68k/drivers/block/amiflop.c
|
||
--- linux-i386/drivers/block/amiflop.c 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/drivers/block/amiflop.c 2006-06-18 19:08:07.000000000 +0200
|
||
@@ -64,6 +64,7 @@
|
||
#include <linux/buffer_head.h>
|
||
#include <linux/blkdev.h>
|
||
#include <linux/elevator.h>
|
||
+#include <linux/interrupt.h>
|
||
|
||
#include <asm/setup.h>
|
||
#include <asm/uaccess.h>
|
||
diff -urN linux-i386/drivers/char/16c552.h linux-m68k/drivers/char/16c552.h
|
||
--- linux-i386/drivers/char/16c552.h 1970-01-01 01:00:00.000000000 +0100
|
||
+++ linux-m68k/drivers/char/16c552.h 2001-10-22 11:34:32.000000000 +0200
|
||
@@ -0,0 +1,165 @@
|
||
+/*
|
||
+ * Definitions for the 16c552 DACE
|
||
+ * (dual-asynchronous-communications-element) used on the GVP
|
||
+ * IO-Extender.
|
||
+ *
|
||
+ * Basically this is two 16c550 uarts's and a parallel port, which is
|
||
+ * why the serial definitions should be valid for the 16c550 uart
|
||
+ * aswell.
|
||
+ *
|
||
+ * Data was taken from National Semiconductors duart 16c552
|
||
+ * data-sheets and the Texas Instruments DACE 16c552 data-sheets (the
|
||
+ * NS version of the chip is _non_ standard and their data-sheets did
|
||
+ * cost me several wasted hours of work).
|
||
+ *
|
||
+ * This file is (C) 1995 Jes Sorensen (jds@kom.auc.dk)
|
||
+ *
|
||
+ * Moved from drivers/char/ to include/linux/, because it's useful
|
||
+ * on more than just the one card. I'm using it on the hp300 DCA
|
||
+ * serial driver, for example.
|
||
+ * -- Peter Maydell <pmaydell@chiark.greenend.org.uk> 05/1998
|
||
+ */
|
||
+
|
||
+#ifndef _16C552_H_
|
||
+#define _16C552_H_
|
||
+
|
||
+/* Serial stuff */
|
||
+
|
||
+struct uart_16c550 {
|
||
+ volatile u_char skip0;
|
||
+ volatile u_char RBR;
|
||
+ volatile u_char skip1;
|
||
+ volatile u_char IER;
|
||
+ volatile u_char skip2;
|
||
+ volatile u_char IIR;
|
||
+ volatile u_char skip3;
|
||
+ volatile u_char LCR;
|
||
+ volatile u_char skip4;
|
||
+ volatile u_char MCR;
|
||
+ volatile u_char skip5;
|
||
+ volatile u_char LSR;
|
||
+ volatile u_char skip6;
|
||
+ volatile u_char MSR;
|
||
+ volatile u_char skip7;
|
||
+ volatile u_char SCR;
|
||
+};
|
||
+
|
||
+#define THR RBR
|
||
+#define FCR IIR
|
||
+#define DLL RBR
|
||
+#define DLM IER
|
||
+#define AFR IIR
|
||
+
|
||
+/*
|
||
+ * Bit-defines for the various registers.
|
||
+ */
|
||
+
|
||
+
|
||
+/* IER */
|
||
+
|
||
+#define ERDAI (1<<0)
|
||
+#define ETHREI (1<<1)
|
||
+#define ELSI (1<<2)
|
||
+#define EMSI (1<<3)
|
||
+
|
||
+/* IIR - Interrupt Ident. Register */
|
||
+
|
||
+#define IRQ_PEND (1<<0) /* NOTE: IRQ_PEND=0 implies irq pending */
|
||
+#define IRQ_ID1 (1<<1)
|
||
+#define IRQ_ID2 (1<<2)
|
||
+#define IRQ_ID3 (1<<3)
|
||
+#define FIFO_ENA0 (1<<6) /* Both these are set when FCR(1<<0)=1 */
|
||
+#define FIFO_ENA1 (1<<7)
|
||
+
|
||
+#define IRQ_RLS (IRQ_ID1 | IRQ_ID2)
|
||
+#define IRQ_RDA (IRQ_ID2)
|
||
+#define IRQ_CTI (IRQ_ID2 | IRQ_ID3)
|
||
+#define IRQ_THRE (IRQ_ID1)
|
||
+#define IRQ_MS 0
|
||
+
|
||
+/* FCR - FIFO Control Register */
|
||
+
|
||
+#define FIFO_ENA (1<<0)
|
||
+#define RCVR_FIFO_RES (1<<1)
|
||
+#define XMIT_FIFO_RES (1<<2)
|
||
+#define DMA_MODE_SEL (1<<3)
|
||
+#define RCVR_TRIG_LSB (1<<6)
|
||
+#define RCVR_TRIG_MSB (1<<7)
|
||
+
|
||
+#define FIFO_TRIG_1 0x00
|
||
+#define FIFO_TRIG_4 RCVR_TRIG_LSB
|
||
+#define FIFO_TRIG_8 RCVR_TRIG_MSB
|
||
+#define FIFO_TRIG_14 RCVR_TRIG_LSB|RCVR_TRIG_MSB
|
||
+
|
||
+/* LCR - Line Control Register */
|
||
+
|
||
+#define WLS0 (1<<0)
|
||
+#define WLS1 (1<<1)
|
||
+#define STB (1<<2)
|
||
+#define PEN (1<<3)
|
||
+#define EPS (1<<4)
|
||
+#define STICK_PARITY (1<<5)
|
||
+#define SET_BREAK (1<<6)
|
||
+#define DLAB (1<<7)
|
||
+
|
||
+#define data_5bit 0x00
|
||
+#define data_6bit 0x01
|
||
+#define data_7bit 0x02
|
||
+#define data_8bit 0x03
|
||
+
|
||
+
|
||
+/* MCR - Modem Control Register */
|
||
+
|
||
+#define DTR (1<<0)
|
||
+#define RTS (1<<1)
|
||
+#define OUT1 (1<<2)
|
||
+#define OUT2 (1<<3)
|
||
+#define LOOP (1<<4)
|
||
+
|
||
+/* LSR - Line Status Register */
|
||
+
|
||
+#define DR (1<<0)
|
||
+#define OE (1<<1)
|
||
+#define PE (1<<2)
|
||
+#define FE (1<<3)
|
||
+#define BI (1<<4)
|
||
+#define THRE (1<<5)
|
||
+#define TEMT (1<<6)
|
||
+#define RCVR_FIFO_ERR (1<<7)
|
||
+
|
||
+/* MSR - Modem Status Register */
|
||
+
|
||
+#define DCTS (1<<0)
|
||
+#define DDSR (1<<1)
|
||
+#define TERI (1<<2)
|
||
+#define DDCD (1<<3)
|
||
+#define CTS (1<<4)
|
||
+#define DSR (1<<5)
|
||
+#define RING_I (1<<6)
|
||
+#define DCD (1<<7)
|
||
+
|
||
+/* AFR - Alternate Function Register */
|
||
+
|
||
+#define CONCUR_WRITE (1<<0)
|
||
+#define BAUDOUT (1<<1)
|
||
+#define RXRDY (1<<2)
|
||
+
|
||
+/* Parallel stuff */
|
||
+
|
||
+/*
|
||
+ * Unfortunately National Semiconductors did not supply the
|
||
+ * specifications for the parallel port in the chip :-(
|
||
+ * TI succed though, so here they are :-)
|
||
+ *
|
||
+ * Defines for the bits can be found by including <linux/lp.h>
|
||
+ */
|
||
+struct IOEXT_par {
|
||
+ volatile u_char skip0;
|
||
+ volatile u_char DATA;
|
||
+ volatile u_char skip1;
|
||
+ volatile u_char STATUS;
|
||
+ volatile u_char skip2;
|
||
+ volatile u_char CTRL;
|
||
+};
|
||
+
|
||
+#endif
|
||
diff -urN linux-i386/drivers/char/ioext.h linux-m68k/drivers/char/ioext.h
|
||
--- linux-i386/drivers/char/ioext.h 1970-01-01 01:00:00.000000000 +0100
|
||
+++ linux-m68k/drivers/char/ioext.h 2001-10-22 11:34:32.000000000 +0200
|
||
@@ -0,0 +1,108 @@
|
||
+/*
|
||
+ * Shared data structure for GVP IO-Extender support.
|
||
+ *
|
||
+ * Merge of ioext.h and ser_ioext.h
|
||
+ */
|
||
+#ifndef _IOEXT_H_
|
||
+#define _IOEXT_H_
|
||
+
|
||
+#include <linux/config.h>
|
||
+#include <linux/netdevice.h>
|
||
+
|
||
+#include "16c552.h"
|
||
+
|
||
+#define MAX_IOEXT 5 /*
|
||
+ * The maximum number of io-extenders is 5, as you
|
||
+ * can't have more than 5 ZII boards in any Amiga.
|
||
+ */
|
||
+
|
||
+#define UART_CLK 7372800
|
||
+
|
||
+#define IOEXT_BAUD_BASE (UART_CLK / 16)
|
||
+
|
||
+#define IOEXT_MAX_LINES 2
|
||
+
|
||
+#define IOEXT_PAR_PLIP 0x0001
|
||
+#define IOEXT_PAR_LP 0x0002
|
||
+
|
||
+
|
||
+/*
|
||
+ * Macros for the serial driver.
|
||
+ */
|
||
+#define curruart(info) ((struct uart_16c550 *)(info->port))
|
||
+
|
||
+#define ser_DTRon(info) curruart(info)->MCR |= DTR
|
||
+#define ser_RTSon(info) curruart(info)->MCR |= RTS
|
||
+#define ser_DTRoff(info) curruart(info)->MCR &= ~DTR
|
||
+#define ser_RTSoff(info) curruart(info)->MCR &= ~RTS
|
||
+
|
||
+
|
||
+/*
|
||
+ * CNTR defines (copied from the GVP SCSI-driver file gvp11.h
|
||
+ */
|
||
+#define GVP_BUSY (1<<0)
|
||
+#define GVP_IRQ_PEND (1<<1)
|
||
+#define GVP_IRQ_ENA (1<<3)
|
||
+#define GVP_DIR_WRITE (1<<4)
|
||
+
|
||
+
|
||
+/*
|
||
+ * CTRL defines
|
||
+ */
|
||
+#define PORT0_MIDI (1<<0) /* CLR = DRIVERS SET = MIDI */
|
||
+#define PORT1_MIDI (1<<1) /* CLR = DRIVERS SET = MIDI */
|
||
+#define PORT0_DRIVER (1<<2) /* CLR = RS232, SET = MIDI */
|
||
+#define PORT1_DRIVER (1<<3) /* CLR = RS232, SET = MIDI */
|
||
+#define IRQ_SEL (1<<4) /* CLR = INT2, SET = INT6 */
|
||
+#define ROM_BANK_SEL (1<<5) /* CLR = LOW 32K, SET = HIGH 32K */
|
||
+#define PORT0_CTRL (1<<6) /* CLR = RTSx or RXRDYx, SET = RTSx ONLY */
|
||
+#define PORT1_CTRL (1<<7) /* CLR = RTSx or RXRDYx, SET = RTSx ONLY */
|
||
+
|
||
+
|
||
+/*
|
||
+ * This is the struct describing the registers on the IO-Extender.
|
||
+ * NOTE: The board uses a dual uart (16c552), which should be equal to
|
||
+ * two 16c550 uarts.
|
||
+ */
|
||
+typedef struct {
|
||
+ char gap0[0x41];
|
||
+ volatile unsigned char CNTR; /* GVP DMAC CNTR (status register) */
|
||
+ char gap1[0x11e];
|
||
+ struct uart_16c550 uart0; /* The first uart */
|
||
+ char gap2[0xf0];
|
||
+ struct uart_16c550 uart1; /* The second uart */
|
||
+ char gap3[0xf0];
|
||
+ struct IOEXT_par par; /* The parallel port */
|
||
+ char gap4[0xfb];
|
||
+ volatile unsigned char CTRL; /* The control-register on the board */
|
||
+} IOEXT_struct;
|
||
+
|
||
+
|
||
+typedef struct {
|
||
+ int num_uarts;
|
||
+ int line[IOEXT_MAX_LINES];
|
||
+ volatile struct uart_16c550 *uart[IOEXT_MAX_LINES];
|
||
+ IOEXT_struct *board;
|
||
+ int spurious_count;
|
||
+ unsigned char par_use; /* IOEXT_PAR_xxx */
|
||
+#if defined(CONFIG_GVPIOEXT_PLIP) || defined(CONFIG_GVPIOEXT_PLIP_MODULE)
|
||
+ struct nt_device *dev;
|
||
+#endif
|
||
+#if defined(CONFIG_GVPIOEXT_LP) || defined(CONFIG_GVPIOEXT_LP_MODULE)
|
||
+ struct lp_struct *lp_table;
|
||
+ int lp_dev;
|
||
+ int lp_interrupt;
|
||
+#endif
|
||
+} IOExtInfoType;
|
||
+
|
||
+/* Number of detected boards. */
|
||
+extern int ioext_num;
|
||
+extern IOExtInfoType ioext_info[MAX_IOEXT];
|
||
+
|
||
+void ioext_plip_interrupt(struct net_device *dev, int *spurious_count);
|
||
+void ioext_lp_interrupt(int dev, int *spurious_count);
|
||
+
|
||
+extern struct net_device ioext_dev_plip[3];
|
||
+extern struct lp_struct ioext_lp_table[1];
|
||
+
|
||
+#endif
|
||
diff -urN linux-i386/drivers/char/mc68681.h linux-m68k/drivers/char/mc68681.h
|
||
--- linux-i386/drivers/char/mc68681.h 1970-01-01 01:00:00.000000000 +0100
|
||
+++ linux-m68k/drivers/char/mc68681.h 2001-10-22 11:34:32.000000000 +0200
|
||
@@ -0,0 +1,131 @@
|
||
+#ifndef _MC68681_H_
|
||
+#define _MC68681_H_
|
||
+
|
||
+/*
|
||
+ * This describes an MC68681 DUART. It has almost only overlayed registers, which
|
||
+ * the structure very ugly.
|
||
+ * Note that the ri-register isn't really a register of the duart but a kludge of bsc
|
||
+ * to make the ring indicator available.
|
||
+ *
|
||
+ * The data came from the MFC-31-Developer Kit (from Ralph Seidel,
|
||
+ * zodiac@darkness.gun.de) and the data sheet of Phillip's clone device (SCN68681)
|
||
+ * (from Richard Hirst, srh@gpt.co.uk)
|
||
+ *
|
||
+ * 11.11.95 copyright Joerg Dorchain (dorchain@mpi-sb.mpg.de)
|
||
+ *
|
||
+ */
|
||
+
|
||
+struct duarthalf {
|
||
+union {
|
||
+volatile u_char mr1; /* rw */
|
||
+volatile u_char mr2; /* rw */
|
||
+} mr;
|
||
+volatile u_char ri; /* special, read */
|
||
+union {
|
||
+volatile u_char sr; /* read */
|
||
+volatile u_char csr; /* write */
|
||
+} sr_csr;
|
||
+u_char pad1;
|
||
+volatile u_char cr; /* write */
|
||
+u_char pad2;
|
||
+union {
|
||
+volatile u_char rhr; /* read */
|
||
+volatile u_char thr; /* write */
|
||
+} hr;
|
||
+u_char pad3;
|
||
+};
|
||
+
|
||
+struct duart {
|
||
+struct duarthalf pa;
|
||
+union {
|
||
+volatile u_char ipcr; /* read */
|
||
+volatile u_char acr; /* write */
|
||
+} ipcr_acr;
|
||
+u_char pad1;
|
||
+union {
|
||
+volatile u_char isr; /* read */
|
||
+volatile u_char imr; /* write */
|
||
+} ir;
|
||
+u_char pad2;
|
||
+volatile u_char ctu;
|
||
+u_char pad3;
|
||
+volatile u_char ctl;
|
||
+u_char pad4;
|
||
+struct duarthalf pb;
|
||
+volatile u_char ivr;
|
||
+u_char pad5;
|
||
+union {
|
||
+volatile u_char ipr; /* read */
|
||
+volatile u_char opcr; /* write */
|
||
+} ipr_opcr;
|
||
+u_char pad6;
|
||
+union {
|
||
+volatile u_char start; /* read */
|
||
+volatile u_char sopc; /* write */
|
||
+} start_sopc;
|
||
+u_char pad7;
|
||
+union {
|
||
+volatile u_char stop; /* read */
|
||
+volatile u_char ropc; /* write */
|
||
+} stop_ropc;
|
||
+u_char pad8;
|
||
+};
|
||
+
|
||
+#define MR1_BITS 3
|
||
+#define MR1_5BITS 0
|
||
+#define MR1_6BITS 1
|
||
+#define MR1_7BITS 2
|
||
+#define MR1_8BITS 3
|
||
+
|
||
+#define MR1_PARITY_ODD 4
|
||
+
|
||
+#define MR1_PARITY 24
|
||
+#define MR1_PARITY_WITH 0
|
||
+#define MR1_PARITY_FORCE 8
|
||
+#define MR1_PARITY_NO 16
|
||
+#define MR1_PARITY_MULTIDROP 24
|
||
+
|
||
+#define MR1_ERROR_BLOCK 32
|
||
+#define MR1_FFULL_IRQ 64
|
||
+#define MR1_RxRTS_ON 128
|
||
+
|
||
+#define MR2_STOPS 15
|
||
+#define MR2_1STOP 7
|
||
+#define MR2_2STOP 15
|
||
+
|
||
+#define MR2_CTS_ON 16
|
||
+#define MR2_TxRTS_ON 32
|
||
+
|
||
+#define MR2_MODE 192
|
||
+#define MR2_NORMAL 0
|
||
+#define MR2_ECHO 64
|
||
+#define MR2_LOCALLOOP 128
|
||
+#define MR2_REMOTELOOP 192
|
||
+
|
||
+#define CR_RXCOMMAND 3
|
||
+#define CR_NONE 0
|
||
+#define CR_RX_ON 1
|
||
+#define CR_RX_OFF 2
|
||
+#define CR_TXCOMMAND 12
|
||
+#define CR_TX_ON 4
|
||
+#define CR_TX_OFF 8
|
||
+#define CR_MISC 112
|
||
+#define CR_RESET_MR 16
|
||
+#define CR_RESET_RX 32
|
||
+#define CR_RESET_TX 48
|
||
+#define CR_RESET_ERR 64
|
||
+#define CR_RESET_BREAK 80
|
||
+#define CR_START_BREAK 96
|
||
+#define CR_STOP_BREAK 112
|
||
+
|
||
+#define SR_RXRDY 1
|
||
+#define SR_FFULL 2
|
||
+#define SR_TXRDY 4
|
||
+#define SR_TXEMPT 8
|
||
+#define SR_OVERRUN 16
|
||
+#define SR_PARITY 32
|
||
+#define SR_FRAMING 64
|
||
+#define SR_BREAK 128
|
||
+
|
||
+
|
||
+#endif
|
||
diff -urN linux-i386/drivers/char/plip_ioext.c linux-m68k/drivers/char/plip_ioext.c
|
||
--- linux-i386/drivers/char/plip_ioext.c 1970-01-01 01:00:00.000000000 +0100
|
||
+++ linux-m68k/drivers/char/plip_ioext.c 2004-10-24 22:59:56.000000000 +0200
|
||
@@ -0,0 +1,1058 @@
|
||
+/*
|
||
+ * plip_ioext: A parallel port "network" driver for GVP IO-Extender.
|
||
+ *
|
||
+ * Authors: See drivers/net/plip.c
|
||
+ * IO-Extender version by Steve Bennett, <msteveb@ozemail.com.au>
|
||
+ *
|
||
+ * This driver is for use with a 5-bit cable (LapLink (R) cable).
|
||
+ */
|
||
+
|
||
+static const char *version = "NET3 PLIP version 2.2/m68k";
|
||
+
|
||
+#define __NO_VERSION__
|
||
+
|
||
+#include <linux/module.h>
|
||
+#include <linux/types.h>
|
||
+#include <linux/sched.h>
|
||
+#include <linux/errno.h>
|
||
+#include <linux/interrupt.h>
|
||
+#include <linux/slab.h>
|
||
+#include <linux/termios.h>
|
||
+#include <linux/tty.h>
|
||
+#include <linux/serial.h>
|
||
+
|
||
+#include <asm/setup.h>
|
||
+#include <asm/irq.h>
|
||
+#include <asm/amigahw.h>
|
||
+#include <asm/amigaints.h>
|
||
+#include <linux/zorro.h>
|
||
+
|
||
+#include <linux/config.h>
|
||
+#include <linux/kernel.h>
|
||
+#include <linux/fcntl.h>
|
||
+#include <linux/string.h>
|
||
+#include <linux/ptrace.h>
|
||
+#include <linux/if_ether.h>
|
||
+
|
||
+#include <asm/system.h>
|
||
+
|
||
+#include <linux/in.h>
|
||
+#include <linux/delay.h>
|
||
+/*#include <linux/lp_m68k.h>*/
|
||
+
|
||
+#include <linux/netdevice.h>
|
||
+#include <linux/etherdevice.h>
|
||
+#include <linux/inetdevice.h>
|
||
+#include <linux/skbuff.h>
|
||
+#include <linux/if_plip.h>
|
||
+
|
||
+#include <linux/tqueue.h>
|
||
+#include <linux/ioport.h>
|
||
+#include <linux/bitops.h>
|
||
+#include <asm/byteorder.h>
|
||
+
|
||
+#include "ioext.h"
|
||
+
|
||
+#define DEBUG 0
|
||
+
|
||
+/* Map 'struct device *' to our control structure */
|
||
+#define PLIP_DEV(DEV) (&ioext_info[(DEV)->irq])
|
||
+
|
||
+/************************************************************************
|
||
+**
|
||
+** PLIP definitions
|
||
+**
|
||
+*************************************************************************
|
||
+*/
|
||
+
|
||
+/* Use 0 for production, 1 for verification, >2 for debug */
|
||
+#ifndef NET_DEBUG
|
||
+#define NET_DEBUG 2
|
||
+#endif
|
||
+static unsigned int net_debug = NET_DEBUG;
|
||
+
|
||
+/* In micro second */
|
||
+#define PLIP_DELAY_UNIT 1
|
||
+
|
||
+/* Connection time out = PLIP_TRIGGER_WAIT * PLIP_DELAY_UNIT usec */
|
||
+#define PLIP_TRIGGER_WAIT 500
|
||
+
|
||
+/* Nibble time out = PLIP_NIBBLE_WAIT * PLIP_DELAY_UNIT usec */
|
||
+#define PLIP_NIBBLE_WAIT 3000
|
||
+
|
||
+#define PAR_DATA(dev) ((dev)->base_addr+0)
|
||
+#define PAR_STATUS(dev) ((dev)->base_addr+2)
|
||
+#define PAR_CONTROL(dev) ((dev)->base_addr+4)
|
||
+
|
||
+static void enable_par_irq(struct device *dev, int on);
|
||
+static int plip_init(struct device *dev);
|
||
+
|
||
+/* Bottom halfs */
|
||
+static void plip_kick_bh(struct device *dev);
|
||
+static void plip_bh(struct device *dev);
|
||
+
|
||
+/* Functions for DEV methods */
|
||
+static int plip_rebuild_header(struct sk_buff *skb);
|
||
+static int plip_tx_packet(struct sk_buff *skb, struct device *dev);
|
||
+static int plip_open(struct device *dev);
|
||
+static int plip_close(struct device *dev);
|
||
+static struct enet_statistics *plip_get_stats(struct device *dev);
|
||
+static int plip_config(struct device *dev, struct ifmap *map);
|
||
+static int plip_ioctl(struct device *dev, struct ifreq *ifr, int cmd);
|
||
+
|
||
+enum plip_connection_state {
|
||
+ PLIP_CN_NONE=0,
|
||
+ PLIP_CN_RECEIVE,
|
||
+ PLIP_CN_SEND,
|
||
+ PLIP_CN_CLOSING,
|
||
+ PLIP_CN_ERROR
|
||
+};
|
||
+
|
||
+enum plip_packet_state {
|
||
+ PLIP_PK_DONE=0,
|
||
+ PLIP_PK_TRIGGER,
|
||
+ PLIP_PK_LENGTH_LSB,
|
||
+ PLIP_PK_LENGTH_MSB,
|
||
+ PLIP_PK_DATA,
|
||
+ PLIP_PK_CHECKSUM
|
||
+};
|
||
+
|
||
+enum plip_nibble_state {
|
||
+ PLIP_NB_BEGIN,
|
||
+ PLIP_NB_1,
|
||
+ PLIP_NB_2,
|
||
+};
|
||
+
|
||
+struct plip_local {
|
||
+ enum plip_packet_state state;
|
||
+ enum plip_nibble_state nibble;
|
||
+ union {
|
||
+ struct {
|
||
+#if defined(__LITTLE_ENDIAN)
|
||
+ unsigned char lsb;
|
||
+ unsigned char msb;
|
||
+#elif defined(__BIG_ENDIAN)
|
||
+ unsigned char msb;
|
||
+ unsigned char lsb;
|
||
+#else
|
||
+#error "Please fix the endianness defines in <asm/byteorder.h>"
|
||
+#endif
|
||
+ } b;
|
||
+ unsigned short h;
|
||
+ } length;
|
||
+ unsigned short byte;
|
||
+ unsigned char checksum;
|
||
+ unsigned char data;
|
||
+ struct sk_buff *skb;
|
||
+};
|
||
+
|
||
+struct net_local {
|
||
+ struct enet_statistics enet_stats;
|
||
+ struct tq_struct immediate;
|
||
+ struct tq_struct deferred;
|
||
+ struct plip_local snd_data;
|
||
+ struct plip_local rcv_data;
|
||
+ unsigned long trigger;
|
||
+ unsigned long nibble;
|
||
+ enum plip_connection_state connection;
|
||
+ unsigned short timeout_count;
|
||
+ char is_deferred;
|
||
+ int (*orig_rebuild_header)(struct sk_buff *skb);
|
||
+};
|
||
+
|
||
+struct device ioext_dev_plip[] = {
|
||
+ {
|
||
+ "plip0",
|
||
+ 0, 0, 0, 0, /* memory */
|
||
+ 0, 0, /* base, irq */
|
||
+ 0, 0, 0, NULL, plip_init
|
||
+ },
|
||
+ {
|
||
+ "plip1",
|
||
+ 0, 0, 0, 0, /* memory */
|
||
+ 0, 0, /* base, irq */
|
||
+ 0, 0, 0, NULL, plip_init
|
||
+ },
|
||
+ {
|
||
+ "plip2",
|
||
+ 0, 0, 0, 0, /* memory */
|
||
+ 0, 0, /* base, irq */
|
||
+ 0, 0, 0, NULL, plip_init
|
||
+ }
|
||
+};
|
||
+
|
||
+/*
|
||
+ * Check for and handle an interrupt for this PLIP device.
|
||
+ *
|
||
+ */
|
||
+void ioext_plip_interrupt(struct device *dev, int *spurious_count)
|
||
+{
|
||
+ struct net_local *nl;
|
||
+ struct plip_local *rcv;
|
||
+ unsigned char c0;
|
||
+ unsigned long flags;
|
||
+
|
||
+ nl = (struct net_local *)dev->priv;
|
||
+ rcv = &nl->rcv_data;
|
||
+
|
||
+ c0 = z_readb(PAR_STATUS(dev));
|
||
+
|
||
+ if (dev->interrupt) {
|
||
+ return;
|
||
+ }
|
||
+
|
||
+ if ((c0 & 0xf8) != 0xc0) {
|
||
+ /* Not for us */
|
||
+ ++*spurious_count;
|
||
+ return;
|
||
+ }
|
||
+
|
||
+ *spurious_count = 0;
|
||
+ dev->interrupt = 1;
|
||
+
|
||
+ local_irq_save(flags);
|
||
+
|
||
+ switch (nl->connection) {
|
||
+ case PLIP_CN_CLOSING:
|
||
+ dev->tbusy = 0;
|
||
+ case PLIP_CN_NONE:
|
||
+ case PLIP_CN_SEND:
|
||
+ dev->last_rx = jiffies;
|
||
+ rcv->state = PLIP_PK_TRIGGER;
|
||
+ nl->connection = PLIP_CN_RECEIVE;
|
||
+ nl->timeout_count = 0;
|
||
+ queue_task(&nl->immediate, &tq_immediate);
|
||
+ mark_bh(IMMEDIATE_BH);
|
||
+ local_irq_restore(flags);
|
||
+#if 0
|
||
+ printk("%s: receive irq in SEND/NONE/CLOSING (%d) ok\n",
|
||
+ dev->name, nl->connection);
|
||
+#endif
|
||
+ break;
|
||
+
|
||
+ case PLIP_CN_RECEIVE:
|
||
+ local_irq_restore(flags);
|
||
+ printk("%s: receive interrupt when receiving packet\n",
|
||
+ dev->name);
|
||
+ break;
|
||
+
|
||
+ case PLIP_CN_ERROR:
|
||
+ local_irq_restore(flags);
|
||
+ printk("%s: receive interrupt in error state\n", dev->name);
|
||
+ break;
|
||
+ }
|
||
+}
|
||
+
|
||
+
|
||
+/* Bottom half handler for the delayed request.
|
||
+ This routine is kicked by do_timer().
|
||
+ Request `plip_bh' to be invoked. */
|
||
+static void
|
||
+plip_kick_bh(struct device *dev)
|
||
+{
|
||
+ struct net_local *nl = (struct net_local *)dev->priv;
|
||
+
|
||
+ if (nl->is_deferred) {
|
||
+ queue_task(&nl->immediate, &tq_immediate);
|
||
+ mark_bh(IMMEDIATE_BH);
|
||
+ }
|
||
+}
|
||
+
|
||
+/* Forward declarations of internal routines */
|
||
+static int plip_none(struct device *, struct net_local *,
|
||
+ struct plip_local *, struct plip_local *);
|
||
+static int plip_receive_packet(struct device *, struct net_local *,
|
||
+ struct plip_local *, struct plip_local *);
|
||
+static int plip_send_packet(struct device *, struct net_local *,
|
||
+ struct plip_local *, struct plip_local *);
|
||
+static int plip_connection_close(struct device *, struct net_local *,
|
||
+ struct plip_local *, struct plip_local *);
|
||
+static int plip_error(struct device *, struct net_local *,
|
||
+ struct plip_local *, struct plip_local *);
|
||
+static int plip_bh_timeout_error(struct device *dev, struct net_local *nl,
|
||
+ struct plip_local *snd,
|
||
+ struct plip_local *rcv,
|
||
+ int error);
|
||
+
|
||
+#define OK 0
|
||
+#define TIMEOUT 1
|
||
+#define ERROR 2
|
||
+
|
||
+typedef int (*plip_func)(struct device *dev, struct net_local *nl,
|
||
+ struct plip_local *snd, struct plip_local *rcv);
|
||
+
|
||
+static plip_func connection_state_table[] =
|
||
+{
|
||
+ plip_none,
|
||
+ plip_receive_packet,
|
||
+ plip_send_packet,
|
||
+ plip_connection_close,
|
||
+ plip_error
|
||
+};
|
||
+
|
||
+/*
|
||
+** enable_par_irq()
|
||
+**
|
||
+** Enable or disable parallel irq for 'dev' according to 'on'.
|
||
+**
|
||
+** It is NOT possible to disable only the parallel irq.
|
||
+** So we disable the board interrupt instead. This means that
|
||
+** during reception of a PLIP packet, no serial interrupts can
|
||
+** happen. Sorry.
|
||
+*/
|
||
+static void enable_par_irq(struct device *dev, int on)
|
||
+{
|
||
+ if (on) {
|
||
+ PLIP_DEV(dev)->board->CNTR |= GVP_IRQ_ENA;
|
||
+ }
|
||
+ else {
|
||
+ PLIP_DEV(dev)->board->CNTR &= ~GVP_IRQ_ENA;
|
||
+ }
|
||
+}
|
||
+
|
||
+/* Bottom half handler of PLIP. */
|
||
+static void
|
||
+plip_bh(struct device *dev)
|
||
+{
|
||
+ struct net_local *nl = (struct net_local *)dev->priv;
|
||
+ struct plip_local *snd = &nl->snd_data;
|
||
+ struct plip_local *rcv = &nl->rcv_data;
|
||
+ plip_func f;
|
||
+ int r;
|
||
+
|
||
+ nl->is_deferred = 0;
|
||
+ f = connection_state_table[nl->connection];
|
||
+ if ((r = (*f)(dev, nl, snd, rcv)) != OK
|
||
+ && (r = plip_bh_timeout_error(dev, nl, snd, rcv, r)) != OK) {
|
||
+ nl->is_deferred = 1;
|
||
+ queue_task(&nl->deferred, &tq_timer);
|
||
+ }
|
||
+}
|
||
+
|
||
+static int
|
||
+plip_bh_timeout_error(struct device *dev, struct net_local *nl,
|
||
+ struct plip_local *snd, struct plip_local *rcv,
|
||
+ int error)
|
||
+{
|
||
+ unsigned char c0;
|
||
+ unsigned long flags;
|
||
+
|
||
+ local_irq_save(flags);
|
||
+ if (nl->connection == PLIP_CN_SEND) {
|
||
+
|
||
+ if (error != ERROR) { /* Timeout */
|
||
+ nl->timeout_count++;
|
||
+ if ((snd->state == PLIP_PK_TRIGGER
|
||
+ && nl->timeout_count <= 10)
|
||
+ || nl->timeout_count <= 3) {
|
||
+ local_irq_restore(flags);
|
||
+ /* Try again later */
|
||
+ return TIMEOUT;
|
||
+ }
|
||
+ c0 = z_readb(PAR_STATUS(dev));
|
||
+ printk(KERN_INFO "%s: transmit timeout(%d,%02x)\n",
|
||
+ dev->name, snd->state, c0);
|
||
+ }
|
||
+ nl->enet_stats.tx_errors++;
|
||
+ nl->enet_stats.tx_aborted_errors++;
|
||
+ } else if (nl->connection == PLIP_CN_RECEIVE) {
|
||
+ if (rcv->state == PLIP_PK_TRIGGER) {
|
||
+ /* Transmission was interrupted. */
|
||
+ local_irq_restore(flags);
|
||
+ return OK;
|
||
+ }
|
||
+ if (error != ERROR) { /* Timeout */
|
||
+ if (++nl->timeout_count <= 3) {
|
||
+ local_irq_restore(flags);
|
||
+ /* Try again later */
|
||
+ return TIMEOUT;
|
||
+ }
|
||
+ c0 = z_readb(PAR_STATUS(dev));
|
||
+ printk(KERN_INFO "%s: receive timeout(%d,%02x)\n",
|
||
+ dev->name, rcv->state, c0);
|
||
+ }
|
||
+ nl->enet_stats.rx_dropped++;
|
||
+ }
|
||
+ rcv->state = PLIP_PK_DONE;
|
||
+ if (rcv->skb) {
|
||
+ kfree_skb(rcv->skb);
|
||
+ rcv->skb = NULL;
|
||
+ }
|
||
+ snd->state = PLIP_PK_DONE;
|
||
+ if (snd->skb) {
|
||
+ dev_kfree_skb(snd->skb);
|
||
+ snd->skb = NULL;
|
||
+ }
|
||
+ enable_par_irq(dev, 0);
|
||
+ dev->tbusy = 1;
|
||
+ nl->connection = PLIP_CN_ERROR;
|
||
+ z_writeb(0x00, PAR_DATA(dev));
|
||
+ local_irq_restore(flags);
|
||
+
|
||
+ return TIMEOUT;
|
||
+}
|
||
+
|
||
+static int
|
||
+plip_none(struct device *dev, struct net_local *nl,
|
||
+ struct plip_local *snd, struct plip_local *rcv)
|
||
+{
|
||
+ return OK;
|
||
+}
|
||
+
|
||
+/* PLIP_RECEIVE --- receive a byte(two nibbles)
|
||
+ Returns OK on success, TIMEOUT on timeout */
|
||
+inline static int
|
||
+plip_receive(struct device *dev, unsigned short nibble_timeout,
|
||
+ enum plip_nibble_state *ns_p, unsigned char *data_p)
|
||
+{
|
||
+ unsigned char c0, c1;
|
||
+ unsigned int cx;
|
||
+
|
||
+ switch (*ns_p) {
|
||
+ case PLIP_NB_BEGIN:
|
||
+ cx = nibble_timeout;
|
||
+ while (1) {
|
||
+ c0 = z_readb(PAR_STATUS(dev));
|
||
+ udelay(PLIP_DELAY_UNIT);
|
||
+ if ((c0 & 0x80) == 0) {
|
||
+ c1 = z_readb(PAR_STATUS(dev));
|
||
+ if (c0 == c1)
|
||
+ break;
|
||
+ }
|
||
+ if (--cx == 0)
|
||
+ return TIMEOUT;
|
||
+ }
|
||
+#if 0
|
||
+ printk("received first nybble: %02X -> %02X\n",
|
||
+ c0, (c0 >> 3) & 0x0F);
|
||
+#endif
|
||
+ *data_p = (c0 >> 3) & 0x0f;
|
||
+ z_writeb(0x10, PAR_DATA(dev)); /* send ACK */
|
||
+ *ns_p = PLIP_NB_1;
|
||
+
|
||
+ case PLIP_NB_1:
|
||
+ cx = nibble_timeout;
|
||
+ while (1) {
|
||
+ c0 = z_readb(PAR_STATUS(dev));
|
||
+ udelay(PLIP_DELAY_UNIT);
|
||
+ if (c0 & 0x80) {
|
||
+ c1 = z_readb(PAR_STATUS(dev));
|
||
+ if (c0 == c1)
|
||
+ break;
|
||
+ }
|
||
+ if (--cx == 0)
|
||
+ return TIMEOUT;
|
||
+ }
|
||
+#if 0
|
||
+ printk("received second nybble: %02X -> %02X\n",
|
||
+ c0, (c0 << 1) & 0xF0);
|
||
+#endif
|
||
+ *data_p |= (c0 << 1) & 0xf0;
|
||
+ z_writeb(0x00, PAR_DATA(dev)); /* send ACK */
|
||
+ *ns_p = PLIP_NB_BEGIN;
|
||
+ case PLIP_NB_2:
|
||
+ break;
|
||
+ }
|
||
+ return OK;
|
||
+}
|
||
+
|
||
+/* PLIP_RECEIVE_PACKET --- receive a packet */
|
||
+static int
|
||
+plip_receive_packet(struct device *dev, struct net_local *nl,
|
||
+ struct plip_local *snd, struct plip_local *rcv)
|
||
+{
|
||
+ unsigned short nibble_timeout = nl->nibble;
|
||
+ unsigned char *lbuf;
|
||
+ unsigned long flags;
|
||
+
|
||
+ switch (rcv->state) {
|
||
+ case PLIP_PK_TRIGGER:
|
||
+ enable_par_irq(dev, 0);
|
||
+ dev->interrupt = 0;
|
||
+ z_writeb(0x01, PAR_DATA(dev)); /* send ACK */
|
||
+ if (net_debug > 2)
|
||
+ printk(KERN_DEBUG "%s: receive start\n", dev->name);
|
||
+ rcv->state = PLIP_PK_LENGTH_LSB;
|
||
+ rcv->nibble = PLIP_NB_BEGIN;
|
||
+
|
||
+ case PLIP_PK_LENGTH_LSB:
|
||
+ if (snd->state != PLIP_PK_DONE) {
|
||
+ if (plip_receive(dev, nl->trigger,
|
||
+ &rcv->nibble, &rcv->length.b.lsb)) {
|
||
+ /* collision, here dev->tbusy == 1 */
|
||
+ rcv->state = PLIP_PK_DONE;
|
||
+ nl->is_deferred = 1;
|
||
+ nl->connection = PLIP_CN_SEND;
|
||
+ queue_task(&nl->deferred, &tq_timer);
|
||
+ enable_par_irq(dev, 1);
|
||
+ return OK;
|
||
+ }
|
||
+ } else {
|
||
+ if (plip_receive(dev, nibble_timeout,
|
||
+ &rcv->nibble, &rcv->length.b.lsb))
|
||
+ return TIMEOUT;
|
||
+ }
|
||
+ rcv->state = PLIP_PK_LENGTH_MSB;
|
||
+
|
||
+ case PLIP_PK_LENGTH_MSB:
|
||
+ if (plip_receive(dev, nibble_timeout,
|
||
+ &rcv->nibble, &rcv->length.b.msb))
|
||
+ return TIMEOUT;
|
||
+ if (rcv->length.h > dev->mtu + dev->hard_header_len
|
||
+ || rcv->length.h < 8) {
|
||
+ printk(KERN_INFO "%s: bogus packet size %d.\n",
|
||
+ dev->name, rcv->length.h);
|
||
+ return ERROR;
|
||
+ }
|
||
+ /* Malloc up new buffer. */
|
||
+ rcv->skb = dev_alloc_skb(rcv->length.h);
|
||
+ if (rcv->skb == NULL) {
|
||
+ printk(KERN_INFO "%s: Memory squeeze.\n", dev->name);
|
||
+ return ERROR;
|
||
+ }
|
||
+ skb_put(rcv->skb,rcv->length.h);
|
||
+ rcv->skb->dev = dev;
|
||
+ rcv->state = PLIP_PK_DATA;
|
||
+ rcv->byte = 0;
|
||
+ rcv->checksum = 0;
|
||
+
|
||
+ case PLIP_PK_DATA:
|
||
+ lbuf = rcv->skb->data;
|
||
+ do
|
||
+ if (plip_receive(dev, nibble_timeout,
|
||
+ &rcv->nibble, &lbuf[rcv->byte]))
|
||
+ return TIMEOUT;
|
||
+ while (++rcv->byte < rcv->length.h);
|
||
+ do
|
||
+ rcv->checksum += lbuf[--rcv->byte];
|
||
+ while (rcv->byte);
|
||
+ rcv->state = PLIP_PK_CHECKSUM;
|
||
+
|
||
+ case PLIP_PK_CHECKSUM:
|
||
+ if (plip_receive(dev, nibble_timeout,
|
||
+ &rcv->nibble, &rcv->data))
|
||
+ return TIMEOUT;
|
||
+ if (rcv->data != rcv->checksum) {
|
||
+ nl->enet_stats.rx_crc_errors++;
|
||
+ if (net_debug)
|
||
+ printk(KERN_INFO "%s: checksum error\n",
|
||
+ dev->name);
|
||
+ return ERROR;
|
||
+ }
|
||
+ rcv->state = PLIP_PK_DONE;
|
||
+
|
||
+ case PLIP_PK_DONE:
|
||
+ /* Inform the upper layer for the arrival of a packet. */
|
||
+ rcv->skb->protocol=eth_type_trans(rcv->skb, dev);
|
||
+ netif_rx(rcv->skb);
|
||
+ nl->enet_stats.rx_packets++;
|
||
+ rcv->skb = NULL;
|
||
+ if (net_debug > 2)
|
||
+ printk(KERN_DEBUG "%s: receive end\n", dev->name);
|
||
+
|
||
+ /* Close the connection. */
|
||
+ z_writeb (0x00, PAR_DATA(dev));
|
||
+
|
||
+ local_irq_save(flags);
|
||
+ if (snd->state != PLIP_PK_DONE) {
|
||
+ nl->connection = PLIP_CN_SEND;
|
||
+ local_irq_restore(flags);
|
||
+ queue_task(&nl->immediate, &tq_immediate);
|
||
+ mark_bh(IMMEDIATE_BH);
|
||
+ enable_par_irq(dev, 1);
|
||
+ return OK;
|
||
+ } else {
|
||
+ nl->connection = PLIP_CN_NONE;
|
||
+ local_irq_restore(flags);
|
||
+ enable_par_irq(dev, 1);
|
||
+ return OK;
|
||
+ }
|
||
+ }
|
||
+ return OK;
|
||
+}
|
||
+
|
||
+/* PLIP_SEND --- send a byte (two nibbles)
|
||
+ Returns OK on success, TIMEOUT when timeout */
|
||
+inline static int
|
||
+plip_send(struct device *dev, unsigned short nibble_timeout,
|
||
+ enum plip_nibble_state *ns_p, unsigned char data)
|
||
+{
|
||
+ unsigned char c0;
|
||
+ unsigned int cx;
|
||
+
|
||
+ switch (*ns_p) {
|
||
+ case PLIP_NB_BEGIN:
|
||
+ z_writeb((data & 0x0f), PAR_DATA(dev));
|
||
+ *ns_p = PLIP_NB_1;
|
||
+
|
||
+ case PLIP_NB_1:
|
||
+ z_writeb(0x10 | (data & 0x0f), PAR_DATA(dev));
|
||
+ cx = nibble_timeout;
|
||
+ while (1) {
|
||
+ c0 = z_readb(PAR_STATUS(dev));
|
||
+ if ((c0 & 0x80) == 0)
|
||
+ break;
|
||
+ if (--cx == 0)
|
||
+ return TIMEOUT;
|
||
+ udelay(PLIP_DELAY_UNIT);
|
||
+ }
|
||
+ z_writeb(0x10 | (data >> 4), PAR_DATA(dev));
|
||
+ *ns_p = PLIP_NB_2;
|
||
+
|
||
+ case PLIP_NB_2:
|
||
+ z_writeb((data >> 4), PAR_DATA(dev));
|
||
+ cx = nibble_timeout;
|
||
+ while (1) {
|
||
+ c0 = z_readb(PAR_STATUS(dev));
|
||
+ if (c0 & 0x80)
|
||
+ break;
|
||
+ if (--cx == 0)
|
||
+ return TIMEOUT;
|
||
+ udelay(PLIP_DELAY_UNIT);
|
||
+ }
|
||
+ *ns_p = PLIP_NB_BEGIN;
|
||
+ return OK;
|
||
+ }
|
||
+ return OK;
|
||
+}
|
||
+
|
||
+/* PLIP_SEND_PACKET --- send a packet */
|
||
+static int
|
||
+plip_send_packet(struct device *dev, struct net_local *nl,
|
||
+ struct plip_local *snd, struct plip_local *rcv)
|
||
+{
|
||
+ unsigned short nibble_timeout = nl->nibble;
|
||
+ unsigned char *lbuf;
|
||
+ unsigned char c0;
|
||
+ unsigned int cx;
|
||
+ unsigned long flags;
|
||
+
|
||
+ if (snd->skb == NULL || (lbuf = snd->skb->data) == NULL) {
|
||
+ printk(KERN_INFO "%s: send skb lost\n", dev->name);
|
||
+ snd->state = PLIP_PK_DONE;
|
||
+ snd->skb = NULL;
|
||
+ return ERROR;
|
||
+ }
|
||
+
|
||
+ if (snd->length.h == 0) {
|
||
+ return OK;
|
||
+ }
|
||
+
|
||
+ switch (snd->state) {
|
||
+ case PLIP_PK_TRIGGER:
|
||
+ if ((z_readb(PAR_STATUS(dev)) & 0xf8) != 0x80)
|
||
+ return TIMEOUT;
|
||
+
|
||
+ /* Trigger remote rx interrupt. */
|
||
+ z_writeb(0x08, PAR_DATA(dev));
|
||
+ cx = nl->trigger;
|
||
+ while (1) {
|
||
+ udelay(PLIP_DELAY_UNIT);
|
||
+ local_irq_save(flags);
|
||
+ if (nl->connection == PLIP_CN_RECEIVE) {
|
||
+ local_irq_restore(flags);
|
||
+ /* interrupted */
|
||
+ nl->enet_stats.collisions++;
|
||
+ if (net_debug > 1)
|
||
+ printk(KERN_INFO "%s: collision.\n",
|
||
+ dev->name);
|
||
+ return OK;
|
||
+ }
|
||
+ c0 = z_readb(PAR_STATUS(dev));
|
||
+ if (c0 & 0x08) {
|
||
+ enable_par_irq(dev, 0);
|
||
+ if (net_debug > 2)
|
||
+ printk(KERN_DEBUG "%s: send start\n",
|
||
+ dev->name);
|
||
+ snd->state = PLIP_PK_LENGTH_LSB;
|
||
+ snd->nibble = PLIP_NB_BEGIN;
|
||
+ nl->timeout_count = 0;
|
||
+ local_irq_restore(flags);
|
||
+ break;
|
||
+ }
|
||
+ local_irq_restore(flags);
|
||
+ if (--cx == 0) {
|
||
+ z_writeb(0x00, PAR_DATA(dev));
|
||
+ return TIMEOUT;
|
||
+ }
|
||
+ }
|
||
+
|
||
+ case PLIP_PK_LENGTH_LSB:
|
||
+ if (plip_send(dev, nibble_timeout,
|
||
+ &snd->nibble, snd->length.b.lsb))
|
||
+ return TIMEOUT;
|
||
+ snd->state = PLIP_PK_LENGTH_MSB;
|
||
+
|
||
+ case PLIP_PK_LENGTH_MSB:
|
||
+ if (plip_send(dev, nibble_timeout,
|
||
+ &snd->nibble, snd->length.b.msb))
|
||
+ return TIMEOUT;
|
||
+ snd->state = PLIP_PK_DATA;
|
||
+ snd->byte = 0;
|
||
+ snd->checksum = 0;
|
||
+
|
||
+ case PLIP_PK_DATA:
|
||
+ do
|
||
+ if (plip_send(dev, nibble_timeout,
|
||
+ &snd->nibble, lbuf[snd->byte]))
|
||
+ return TIMEOUT;
|
||
+ while (++snd->byte < snd->length.h);
|
||
+ do
|
||
+ snd->checksum += lbuf[--snd->byte];
|
||
+ while (snd->byte);
|
||
+ snd->state = PLIP_PK_CHECKSUM;
|
||
+
|
||
+ case PLIP_PK_CHECKSUM:
|
||
+ if (plip_send(dev, nibble_timeout,
|
||
+ &snd->nibble, snd->checksum))
|
||
+ return TIMEOUT;
|
||
+
|
||
+ dev_kfree_skb(snd->skb);
|
||
+ nl->enet_stats.tx_packets++;
|
||
+ snd->state = PLIP_PK_DONE;
|
||
+
|
||
+ case PLIP_PK_DONE:
|
||
+ /* Close the connection */
|
||
+ z_writeb (0x00, PAR_DATA(dev));
|
||
+ snd->skb = NULL;
|
||
+ if (net_debug > 2)
|
||
+ printk(KERN_DEBUG "%s: send end\n", dev->name);
|
||
+ nl->connection = PLIP_CN_CLOSING;
|
||
+ nl->is_deferred = 1;
|
||
+ queue_task(&nl->deferred, &tq_timer);
|
||
+ enable_par_irq(dev, 1);
|
||
+ return OK;
|
||
+ }
|
||
+ return OK;
|
||
+}
|
||
+
|
||
+static int
|
||
+plip_connection_close(struct device *dev, struct net_local *nl,
|
||
+ struct plip_local *snd, struct plip_local *rcv)
|
||
+{
|
||
+ unsigned long flags;
|
||
+
|
||
+ local_irq_save(flags);
|
||
+ if (nl->connection == PLIP_CN_CLOSING) {
|
||
+ nl->connection = PLIP_CN_NONE;
|
||
+ dev->tbusy = 0;
|
||
+ mark_bh(NET_BH);
|
||
+ }
|
||
+ local_irq_restore(flags);
|
||
+ return OK;
|
||
+}
|
||
+
|
||
+/* PLIP_ERROR --- wait till other end settled */
|
||
+static int
|
||
+plip_error(struct device *dev, struct net_local *nl,
|
||
+ struct plip_local *snd, struct plip_local *rcv)
|
||
+{
|
||
+ unsigned char status;
|
||
+
|
||
+ status = z_readb(PAR_STATUS(dev));
|
||
+ if ((status & 0xf8) == 0x80) {
|
||
+ if (net_debug > 2)
|
||
+ printk(KERN_DEBUG "%s: reset interface.\n", dev->name);
|
||
+ nl->connection = PLIP_CN_NONE;
|
||
+ dev->tbusy = 0;
|
||
+ dev->interrupt = 0;
|
||
+ enable_par_irq(dev, 1);
|
||
+ mark_bh(NET_BH);
|
||
+ } else {
|
||
+ nl->is_deferred = 1;
|
||
+ queue_task(&nl->deferred, &tq_timer);
|
||
+ }
|
||
+
|
||
+ return OK;
|
||
+}
|
||
+
|
||
+/* We don't need to send arp, for plip is point-to-point. */
|
||
+static int
|
||
+plip_rebuild_header(struct sk_buff *skb)
|
||
+{
|
||
+ struct device *dev = skb->dev;
|
||
+ struct net_local *nl = (struct net_local *)dev->priv;
|
||
+ struct ethhdr *eth = (struct ethhdr *)skb->data;
|
||
+ int i;
|
||
+
|
||
+ if ((dev->flags & IFF_NOARP)==0)
|
||
+ return nl->orig_rebuild_header(skb);
|
||
+
|
||
+ if (eth->h_proto != __constant_htons(ETH_P_IP)
|
||
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
|
||
+ && eth->h_proto != __constant_htons(ETH_P_IPV6)
|
||
+#endif
|
||
+ ) {
|
||
+ printk(KERN_ERR "plip_rebuild_header: Don't know how to resolve type %d addresses?\n", (int)eth->h_proto);
|
||
+ memcpy(eth->h_source, dev->dev_addr, dev->addr_len);
|
||
+ return 0;
|
||
+ }
|
||
+
|
||
+ for (i=0; i < ETH_ALEN - sizeof(u32); i++)
|
||
+ eth->h_dest[i] = 0xfc;
|
||
+#if 0
|
||
+ *(u32 *)(eth->h_dest+i) = dst;
|
||
+#else
|
||
+ /* Do not want to include net/route.h here.
|
||
+ * In any case, it is TOP of silliness to emulate
|
||
+ * hardware addresses on PtP link. --ANK
|
||
+ */
|
||
+ *(u32 *)(eth->h_dest+i) = 0;
|
||
+#endif
|
||
+ return 0;
|
||
+}
|
||
+
|
||
+static int
|
||
+plip_tx_packet(struct sk_buff *skb, struct device *dev)
|
||
+{
|
||
+ struct net_local *nl = (struct net_local *)dev->priv;
|
||
+ struct plip_local *snd = &nl->snd_data;
|
||
+ unsigned long flags;
|
||
+
|
||
+ if (dev->tbusy)
|
||
+ return 1;
|
||
+
|
||
+ if (test_and_set_bit(0, (void*)&dev->tbusy) != 0) {
|
||
+ printk(KERN_ERR "%s: Transmitter access conflict.\n",
|
||
+ dev->name);
|
||
+ return 1;
|
||
+ }
|
||
+
|
||
+ if (skb->len > dev->mtu + dev->hard_header_len) {
|
||
+ printk(KERN_ERR "%s: packet too big, %d.\n",
|
||
+ dev->name, (int)skb->len);
|
||
+ dev->tbusy = 0;
|
||
+ return 0;
|
||
+ }
|
||
+
|
||
+ if (net_debug > 2)
|
||
+ printk(KERN_DEBUG "%s: send request\n", dev->name);
|
||
+
|
||
+ local_irq_save(flags);
|
||
+ dev->trans_start = jiffies;
|
||
+ snd->skb = skb;
|
||
+ snd->length.h = skb->len;
|
||
+ snd->state = PLIP_PK_TRIGGER;
|
||
+ if (nl->connection == PLIP_CN_NONE) {
|
||
+ nl->connection = PLIP_CN_SEND;
|
||
+ nl->timeout_count = 0;
|
||
+ }
|
||
+ queue_task(&nl->immediate, &tq_immediate);
|
||
+ mark_bh(IMMEDIATE_BH);
|
||
+ local_irq_restore(flags);
|
||
+
|
||
+ return 0;
|
||
+}
|
||
+
|
||
+/* Open/initialize the board. This is called (in the current kernel)
|
||
+ sometime after booting when the 'ifconfig' program is run.
|
||
+
|
||
+ */
|
||
+static int
|
||
+plip_open(struct device *dev)
|
||
+{
|
||
+ struct net_local *nl = (struct net_local *)dev->priv;
|
||
+ struct in_device *in_dev;
|
||
+
|
||
+#if defined(CONFIG_GVPIOEXT_LP) || defined(CONFIG_GVPIOEXT_LP_MODULE)
|
||
+ /* Yes, there is a race condition here. Fix it later */
|
||
+ if (PLIP_DEV(dev)->par_use & IOEXT_PAR_LP) {
|
||
+ /* Can't open if lp is in use */
|
||
+#if DEBUG
|
||
+ printk("par is in use by lp\n");
|
||
+#endif
|
||
+ return(-EBUSY);
|
||
+ }
|
||
+#endif
|
||
+ PLIP_DEV(dev)->par_use |= IOEXT_PAR_PLIP;
|
||
+
|
||
+#if DEBUG
|
||
+ printk("plip_open(): sending 00 to data port\n");
|
||
+#endif
|
||
+
|
||
+ /* Clear the data port. */
|
||
+ z_writeb (0x00, PAR_DATA(dev));
|
||
+
|
||
+#if DEBUG
|
||
+ printk("plip_open(): sent\n");
|
||
+#endif
|
||
+
|
||
+ /* Initialize the state machine. */
|
||
+ nl->rcv_data.state = nl->snd_data.state = PLIP_PK_DONE;
|
||
+ nl->rcv_data.skb = nl->snd_data.skb = NULL;
|
||
+ nl->connection = PLIP_CN_NONE;
|
||
+ nl->is_deferred = 0;
|
||
+
|
||
+ /* Fill in the MAC-level header.
|
||
+ (ab)Use "dev->broadcast" to store point-to-point MAC address.
|
||
+
|
||
+ PLIP doesn't have a real mac address, but we need to create one
|
||
+ to be DOS compatible. */
|
||
+ memset(dev->dev_addr, 0xfc, ETH_ALEN);
|
||
+ memset(dev->broadcast, 0xfc, ETH_ALEN);
|
||
+
|
||
+ if ((in_dev=dev->ip_ptr) != NULL) {
|
||
+ /*
|
||
+ * Any address will do - we take the first
|
||
+ */
|
||
+ struct in_ifaddr *ifa=in_dev->ifa_list;
|
||
+ if (ifa != NULL) {
|
||
+ memcpy(dev->dev_addr+2, &ifa->ifa_local, 4);
|
||
+ memcpy(dev->broadcast+2, &ifa->ifa_address, 4);
|
||
+ }
|
||
+ }
|
||
+
|
||
+ dev->interrupt = 0;
|
||
+ dev->start = 1;
|
||
+ dev->tbusy = 0;
|
||
+
|
||
+ MOD_INC_USE_COUNT;
|
||
+
|
||
+ /* Enable rx interrupt. */
|
||
+ enable_par_irq(dev, 1);
|
||
+
|
||
+ return 0;
|
||
+}
|
||
+
|
||
+/* The inverse routine to plip_open (). */
|
||
+static int
|
||
+plip_close(struct device *dev)
|
||
+{
|
||
+ struct net_local *nl = (struct net_local *)dev->priv;
|
||
+ struct plip_local *snd = &nl->snd_data;
|
||
+ struct plip_local *rcv = &nl->rcv_data;
|
||
+ unsigned long flags;
|
||
+
|
||
+ dev->tbusy = 1;
|
||
+ dev->start = 0;
|
||
+ local_irq_save(flags);
|
||
+ nl->is_deferred = 0;
|
||
+ nl->connection = PLIP_CN_NONE;
|
||
+ local_irq_restore(flags);
|
||
+ z_writeb(0x00, PAR_DATA(dev));
|
||
+
|
||
+ snd->state = PLIP_PK_DONE;
|
||
+ if (snd->skb) {
|
||
+ dev_kfree_skb(snd->skb);
|
||
+ snd->skb = NULL;
|
||
+ }
|
||
+ rcv->state = PLIP_PK_DONE;
|
||
+ if (rcv->skb) {
|
||
+ kfree_skb(rcv->skb);
|
||
+ rcv->skb = NULL;
|
||
+ }
|
||
+
|
||
+ PLIP_DEV(dev)->par_use &= ~IOEXT_PAR_PLIP;
|
||
+
|
||
+ MOD_DEC_USE_COUNT;
|
||
+ return 0;
|
||
+}
|
||
+
|
||
+static struct enet_statistics *
|
||
+plip_get_stats(struct device *dev)
|
||
+{
|
||
+ struct net_local *nl = (struct net_local *)dev->priv;
|
||
+ struct enet_statistics *r = &nl->enet_stats;
|
||
+
|
||
+ return r;
|
||
+}
|
||
+
|
||
+static int
|
||
+plip_config(struct device *dev, struct ifmap *map)
|
||
+{
|
||
+ if (dev->flags & IFF_UP)
|
||
+ return -EBUSY;
|
||
+
|
||
+ printk(KERN_INFO "%s: This interface is autodetected (ignored).\n",
|
||
+ dev->name);
|
||
+
|
||
+ return 0;
|
||
+}
|
||
+
|
||
+static int
|
||
+plip_ioctl(struct device *dev, struct ifreq *rq, int cmd)
|
||
+{
|
||
+ struct net_local *nl = (struct net_local *) dev->priv;
|
||
+ struct plipconf *pc = (struct plipconf *) &rq->ifr_data;
|
||
+
|
||
+ switch(pc->pcmd) {
|
||
+ case PLIP_GET_TIMEOUT:
|
||
+ pc->trigger = nl->trigger;
|
||
+ pc->nibble = nl->nibble;
|
||
+ break;
|
||
+ case PLIP_SET_TIMEOUT:
|
||
+ nl->trigger = pc->trigger;
|
||
+ nl->nibble = pc->nibble;
|
||
+ break;
|
||
+ default:
|
||
+ return -EOPNOTSUPP;
|
||
+ }
|
||
+ return 0;
|
||
+}
|
||
+
|
||
+/*
|
||
+ * Detect and initialize all IO-Extenders in this system.
|
||
+ *
|
||
+ * Both PLIP and serial devices are configured.
|
||
+ */
|
||
+int plip_init(struct device *dev)
|
||
+{
|
||
+ IOEXT_struct *board;
|
||
+ struct net_local *nl;
|
||
+
|
||
+ if (ioext_num == 0) {
|
||
+ printk(KERN_INFO "%s\n", version);
|
||
+ }
|
||
+
|
||
+ board = PLIP_DEV(dev)->board;
|
||
+ dev->base_addr = (unsigned long)&board->par.DATA;
|
||
+
|
||
+ /* Cheat and use irq to index into our table */
|
||
+ dev->irq = ioext_num;
|
||
+
|
||
+ printk(KERN_INFO "%s: IO-Extender parallel port at 0x%08lX\n", dev->name, dev->base_addr);
|
||
+
|
||
+ /* Fill in the generic fields of the device structure. */
|
||
+ ether_setup(dev);
|
||
+
|
||
+ /* Then, override parts of it */
|
||
+ dev->hard_start_xmit = plip_tx_packet;
|
||
+ dev->open = plip_open;
|
||
+ dev->stop = plip_close;
|
||
+ dev->get_stats = plip_get_stats;
|
||
+ dev->set_config = plip_config;
|
||
+ dev->do_ioctl = plip_ioctl;
|
||
+ dev->tx_queue_len = 10;
|
||
+ dev->flags = IFF_POINTOPOINT|IFF_NOARP;
|
||
+
|
||
+ /* Set the private structure */
|
||
+ dev->priv = kmalloc(sizeof (struct net_local), GFP_KERNEL);
|
||
+ if (dev->priv == NULL) {
|
||
+ printk(KERN_ERR "%s: out of memory\n", dev->name);
|
||
+ return -ENOMEM;
|
||
+ }
|
||
+ memset(dev->priv, 0, sizeof(struct net_local));
|
||
+ nl = (struct net_local *) dev->priv;
|
||
+
|
||
+ nl->orig_rebuild_header = dev->rebuild_header;
|
||
+ dev->rebuild_header = plip_rebuild_header;
|
||
+
|
||
+ /* Initialize constants */
|
||
+ nl->trigger = PLIP_TRIGGER_WAIT;
|
||
+ nl->nibble = PLIP_NIBBLE_WAIT;
|
||
+
|
||
+ /* Initialize task queue structures */
|
||
+ nl->immediate.next = NULL;
|
||
+ nl->immediate.sync = 0;
|
||
+ nl->immediate.routine = (void *)(void *)plip_bh;
|
||
+ nl->immediate.data = dev;
|
||
+
|
||
+ nl->deferred.next = NULL;
|
||
+ nl->deferred.sync = 0;
|
||
+ nl->deferred.routine = (void *)(void *)plip_kick_bh;
|
||
+ nl->deferred.data = dev;
|
||
+
|
||
+ /* Don't enable interrupts yet */
|
||
+
|
||
+ return 0;
|
||
+}
|
||
diff -urN linux-i386/drivers/char/serial167.c linux-m68k/drivers/char/serial167.c
|
||
--- linux-i386/drivers/char/serial167.c 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/drivers/char/serial167.c 2006-05-22 00:00:37.000000000 +0200
|
||
@@ -63,6 +63,7 @@
|
||
#include <linux/console.h>
|
||
#include <linux/module.h>
|
||
#include <linux/bitops.h>
|
||
+#include <linux/tty_flip.h>
|
||
|
||
#include <asm/system.h>
|
||
#include <asm/io.h>
|
||
@@ -439,8 +440,9 @@
|
||
overflowing, we still loose
|
||
the next incoming character.
|
||
*/
|
||
- tty_insert_flip_char(tty, data, TTY_NORMAL);
|
||
- }
|
||
+ if (tty_buffer_request_room(tty, 1) != 0){
|
||
+ tty_insert_flip_char(tty, data, TTY_FRAME);
|
||
+ }
|
||
/* These two conditions may imply */
|
||
/* a normal read should be done. */
|
||
/* else if(data & CyTIMEOUT) */
|
||
@@ -449,14 +451,14 @@
|
||
tty_insert_flip_char(tty, 0, TTY_NORMAL);
|
||
}
|
||
}else{
|
||
- tty_insert_flip_char(tty, data, TTY_NORMAL);
|
||
+ tty_insert_flip_char(tty, data, TTY_NORMAL);
|
||
}
|
||
}else{
|
||
/* there was a software buffer overrun
|
||
and nothing could be done about it!!! */
|
||
}
|
||
}
|
||
- schedule_delayed_work(&tty->flip.work, 1);
|
||
+ tty_schedule_flip(tty);
|
||
/* end of service */
|
||
base_addr[CyREOIR] = rfoc ? 0 : CyNOTRANS;
|
||
return IRQ_HANDLED;
|
||
@@ -647,6 +649,7 @@
|
||
char data;
|
||
int char_count;
|
||
int save_cnt;
|
||
+ int len;
|
||
|
||
/* determine the channel and change to that context */
|
||
channel = (u_short ) (base_addr[CyLICR] >> 2);
|
||
@@ -679,14 +682,15 @@
|
||
info->mon.char_max = char_count;
|
||
info->mon.char_last = char_count;
|
||
#endif
|
||
- while(char_count--){
|
||
+ len = tty_buffer_request_room(tty, char_count);
|
||
+ while(len--){
|
||
data = base_addr[CyRDR];
|
||
tty_insert_flip_char(tty, data, TTY_NORMAL);
|
||
#ifdef CYCLOM_16Y_HACK
|
||
udelay(10L);
|
||
#endif
|
||
}
|
||
- schedule_delayed_work(&tty->flip.work, 1);
|
||
+ tty_schedule_flip(tty);
|
||
}
|
||
/* end of service */
|
||
base_addr[CyREOIR] = save_cnt ? 0 : CyNOTRANS;
|
||
@@ -1434,7 +1438,6 @@
|
||
volatile unsigned char *base_addr = (u_char *)BASE_ADDR;
|
||
unsigned long flags;
|
||
unsigned char status;
|
||
- unsigned int result;
|
||
|
||
channel = info->line;
|
||
|
||
@@ -1458,7 +1461,6 @@
|
||
int channel;
|
||
volatile unsigned char *base_addr = (u_char *)BASE_ADDR;
|
||
unsigned long flags;
|
||
- unsigned int arg;
|
||
|
||
channel = info->line;
|
||
|
||
diff -urN linux-i386/drivers/ide/ide-iops.c linux-m68k/drivers/ide/ide-iops.c
|
||
--- linux-i386/drivers/ide/ide-iops.c 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/drivers/ide/ide-iops.c 2006-04-10 00:22:36.000000000 +0200
|
||
@@ -337,6 +337,23 @@
|
||
int i;
|
||
u16 *stringcast;
|
||
|
||
+#ifdef __mc68000__
|
||
+ if (!MACH_IS_AMIGA && !MACH_IS_MAC && !MACH_IS_Q40 && !MACH_IS_ATARI)
|
||
+ return;
|
||
+
|
||
+#ifdef M68K_IDE_SWAPW
|
||
+ if (M68K_IDE_SWAPW) { /* fix bus byteorder first */
|
||
+ u_char *p = (u_char *)id;
|
||
+ u_char t;
|
||
+ for (i = 0; i < 512; i += 2) {
|
||
+ t = p[i];
|
||
+ p[i] = p[i+1];
|
||
+ p[i+1] = t;
|
||
+ }
|
||
+ }
|
||
+#endif
|
||
+#endif /* __mc68000__ */
|
||
+
|
||
id->config = __le16_to_cpu(id->config);
|
||
id->cyls = __le16_to_cpu(id->cyls);
|
||
id->reserved2 = __le16_to_cpu(id->reserved2);
|
||
diff -urN linux-i386/drivers/ide/ide.c linux-m68k/drivers/ide/ide.c
|
||
--- linux-i386/drivers/ide/ide.c 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/drivers/ide/ide.c 2006-06-18 19:08:21.000000000 +0200
|
||
@@ -726,6 +726,7 @@
|
||
{
|
||
int i;
|
||
|
||
+ memset(hw, 0, sizeof(hw_regs_t));
|
||
for (i = 0; i < IDE_NR_PORTS; i++) {
|
||
if (offsets[i] == -1) {
|
||
switch(i) {
|
||
diff -urN linux-i386/drivers/ide/legacy/q40ide.c linux-m68k/drivers/ide/legacy/q40ide.c
|
||
--- linux-i386/drivers/ide/legacy/q40ide.c 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/drivers/ide/legacy/q40ide.c 2006-05-12 01:52:07.000000000 +0200
|
||
@@ -80,6 +80,7 @@
|
||
{
|
||
int i;
|
||
|
||
+ memset(hw, 0, sizeof(hw_regs_t));
|
||
for (i = 0; i < IDE_NR_PORTS; i++) {
|
||
/* BIG FAT WARNING:
|
||
assumption: only DATA port is ever used in 16 bit mode */
|
||
diff -urN linux-i386/drivers/input/keyboard/Kconfig linux-m68k/drivers/input/keyboard/Kconfig
|
||
--- linux-i386/drivers/input/keyboard/Kconfig 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/drivers/input/keyboard/Kconfig 2006-06-18 19:08:22.000000000 +0200
|
||
@@ -155,7 +155,7 @@
|
||
|
||
config KEYBOARD_HIL_OLD
|
||
tristate "HP HIL keyboard support (simple driver)"
|
||
- depends on GSC
|
||
+ depends on GSC || HP300
|
||
default y
|
||
help
|
||
The "Human Interface Loop" is a older, 8-channel USB-like
|
||
@@ -172,7 +172,7 @@
|
||
|
||
config KEYBOARD_HIL
|
||
tristate "HP HIL keyboard support"
|
||
- depends on GSC
|
||
+ depends on GSC || HP300
|
||
default y
|
||
select HP_SDC
|
||
select HIL_MLC
|
||
diff -urN linux-i386/drivers/input/keyboard/amikbd.c linux-m68k/drivers/input/keyboard/amikbd.c
|
||
--- linux-i386/drivers/input/keyboard/amikbd.c 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/drivers/input/keyboard/amikbd.c 2006-01-28 22:27:33.000000000 +0100
|
||
@@ -36,6 +36,7 @@
|
||
#include <linux/input.h>
|
||
#include <linux/delay.h>
|
||
#include <linux/interrupt.h>
|
||
+#include <linux/keyboard.h>
|
||
|
||
#include <asm/amigaints.h>
|
||
#include <asm/amigahw.h>
|
||
@@ -45,7 +46,7 @@
|
||
MODULE_DESCRIPTION("Amiga keyboard driver");
|
||
MODULE_LICENSE("GPL");
|
||
|
||
-static unsigned char amikbd_keycode[0x78] = {
|
||
+static unsigned char amikbd_keycode[0x78] __initdata = {
|
||
[0] = KEY_GRAVE,
|
||
[1] = KEY_1,
|
||
[2] = KEY_2,
|
||
@@ -170,12 +171,9 @@
|
||
scancode >>= 1;
|
||
|
||
if (scancode < 0x78) { /* scancodes < 0x78 are keys */
|
||
-
|
||
- scancode = amikbd_keycode[scancode];
|
||
-
|
||
input_regs(amikbd_dev, fp);
|
||
|
||
- if (scancode == KEY_CAPSLOCK) { /* CapsLock is a toggle switch key on Amiga */
|
||
+ if (scancode == 98) { /* CapsLock is a toggle switch key on Amiga */
|
||
input_report_key(amikbd_dev, scancode, 1);
|
||
input_report_key(amikbd_dev, scancode, 0);
|
||
} else {
|
||
@@ -191,7 +189,7 @@
|
||
|
||
static int __init amikbd_init(void)
|
||
{
|
||
- int i;
|
||
+ int i, j;
|
||
|
||
if (!AMIGAHW_PRESENT(AMI_KEYBOARD))
|
||
return -EIO;
|
||
@@ -214,14 +212,26 @@
|
||
amikbd_dev->id.version = 0x0100;
|
||
|
||
amikbd_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
|
||
- amikbd_dev->keycode = amikbd_keycode;
|
||
- amikbd_dev->keycodesize = sizeof(unsigned char);
|
||
- amikbd_dev->keycodemax = ARRAY_SIZE(amikbd_keycode);
|
||
|
||
for (i = 0; i < 0x78; i++)
|
||
- if (amikbd_keycode[i])
|
||
- set_bit(amikbd_keycode[i], amikbd_dev->keybit);
|
||
+ set_bit(i, amikbd_dev->keybit);
|
||
|
||
+ for (i = 0; i < MAX_NR_KEYMAPS; i++) {
|
||
+ static u_short temp_map[NR_KEYS] __initdata;
|
||
+ if (!key_maps[i])
|
||
+ continue;
|
||
+ memset(temp_map, 0, sizeof(temp_map));
|
||
+ for (j = 0; j < 0x78; j++) {
|
||
+ if (!amikbd_keycode[j])
|
||
+ continue;
|
||
+ temp_map[j] = key_maps[i][amikbd_keycode[j]];
|
||
+ }
|
||
+ for (j = 0; j < NR_KEYS; j++) {
|
||
+ if (!temp_map[j])
|
||
+ temp_map[j] = 0xf200;
|
||
+ }
|
||
+ memcpy(key_maps[i], temp_map, sizeof(temp_map));
|
||
+ }
|
||
ciaa.cra &= ~0x41; /* serial data in, turn off TA */
|
||
request_irq(IRQ_AMIGA_CIAA_SP, amikbd_interrupt, 0, "amikbd", amikbd_interrupt);
|
||
|
||
diff -urN linux-i386/drivers/input/misc/Kconfig linux-m68k/drivers/input/misc/Kconfig
|
||
--- linux-i386/drivers/input/misc/Kconfig 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/drivers/input/misc/Kconfig 2006-04-10 00:22:39.000000000 +0200
|
||
@@ -73,7 +73,7 @@
|
||
|
||
config HP_SDC_RTC
|
||
tristate "HP SDC Real Time Clock"
|
||
- depends on GSC
|
||
+ depends on GSC || HP300
|
||
select HP_SDC
|
||
help
|
||
Say Y here if you want to support the built-in real time clock
|
||
diff -urN linux-i386/drivers/input/mouse/Kconfig linux-m68k/drivers/input/mouse/Kconfig
|
||
--- linux-i386/drivers/input/mouse/Kconfig 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/drivers/input/mouse/Kconfig 2006-04-10 00:22:40.000000000 +0200
|
||
@@ -119,7 +119,7 @@
|
||
|
||
config MOUSE_HIL
|
||
tristate "HIL pointers (mice etc)."
|
||
- depends on GSC
|
||
+ depends on GSC || HP300
|
||
select HP_SDC
|
||
select HIL_MLC
|
||
help
|
||
diff -urN linux-i386/drivers/input/serio/Kconfig linux-m68k/drivers/input/serio/Kconfig
|
||
--- linux-i386/drivers/input/serio/Kconfig 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/drivers/input/serio/Kconfig 2005-08-29 21:17:45.000000000 +0200
|
||
@@ -112,7 +112,7 @@
|
||
|
||
config HP_SDC
|
||
tristate "HP System Device Controller i8042 Support"
|
||
- depends on GSC && SERIO
|
||
+ depends on (GSC || HP300) && SERIO
|
||
default y
|
||
---help---
|
||
This option enables supports for the the "System Device
|
||
diff -urN linux-i386/drivers/macintosh/adb.c linux-m68k/drivers/macintosh/adb.c
|
||
--- linux-i386/drivers/macintosh/adb.c 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/drivers/macintosh/adb.c 2006-06-18 19:08:24.000000000 +0200
|
||
@@ -480,13 +480,15 @@
|
||
use_sreq = 1;
|
||
} else
|
||
use_sreq = 0;
|
||
- req->nbytes = nbytes+1;
|
||
+ i = (flags & ADBREQ_RAW) ? 0 : 1;
|
||
+ req->nbytes = nbytes+i;
|
||
req->done = done;
|
||
req->reply_expected = flags & ADBREQ_REPLY;
|
||
req->data[0] = ADB_PACKET;
|
||
va_start(list, nbytes);
|
||
- for (i = 0; i < nbytes; ++i)
|
||
- req->data[i+1] = va_arg(list, int);
|
||
+ while (i < req->nbytes) {
|
||
+ req->data[i++] = va_arg(list, int);
|
||
+ }
|
||
va_end(list);
|
||
|
||
if (flags & ADBREQ_NOSEND)
|
||
diff -urN linux-i386/drivers/net/7990.c linux-m68k/drivers/net/7990.c
|
||
--- linux-i386/drivers/net/7990.c 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/drivers/net/7990.c 2006-06-18 19:08:38.000000000 +0200
|
||
@@ -500,7 +500,7 @@
|
||
int res;
|
||
|
||
/* Install the Interrupt handler. Or we could shunt this out to specific drivers? */
|
||
- if (request_irq(lp->irq, lance_interrupt, 0, lp->name, dev))
|
||
+ if (request_irq(lp->irq, lance_interrupt, SA_SHIRQ, lp->name, dev))
|
||
return -EAGAIN;
|
||
|
||
res = lance_reset(dev);
|
||
diff -urN linux-i386/drivers/net/Kconfig linux-m68k/drivers/net/Kconfig
|
||
--- linux-i386/drivers/net/Kconfig 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/drivers/net/Kconfig 2006-06-18 19:08:38.000000000 +0200
|
||
@@ -307,7 +307,7 @@
|
||
|
||
config MAC89x0
|
||
tristate "Macintosh CS89x0 based ethernet cards"
|
||
- depends on NET_ETHERNET && MAC && BROKEN
|
||
+ depends on NET_ETHERNET && MAC
|
||
---help---
|
||
Support for CS89x0 chipset based Ethernet cards. If you have a
|
||
Nubus or LC-PDS network (Ethernet) card of this type, say Y and
|
||
diff -urN linux-i386/drivers/net/hplance.c linux-m68k/drivers/net/hplance.c
|
||
--- linux-i386/drivers/net/hplance.c 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/drivers/net/hplance.c 2006-06-18 19:08:39.000000000 +0200
|
||
@@ -77,6 +77,7 @@
|
||
{
|
||
struct net_device *dev;
|
||
int err = -ENOMEM;
|
||
+ int i;
|
||
|
||
dev = alloc_etherdev(sizeof(struct hplance_private));
|
||
if (!dev)
|
||
@@ -93,6 +94,15 @@
|
||
goto out_release_mem_region;
|
||
|
||
dio_set_drvdata(d, dev);
|
||
+
|
||
+ printk(KERN_INFO "%s: %s; select code %d, addr %2.2x", dev->name, d->name, d->scode, dev->dev_addr[0]);
|
||
+
|
||
+ for (i=1; i<6; i++) {
|
||
+ printk(":%2.2x", dev->dev_addr[i]);
|
||
+ }
|
||
+
|
||
+ printk(", irq %d\n", d->ipl);
|
||
+
|
||
return 0;
|
||
|
||
out_release_mem_region:
|
||
@@ -118,9 +128,7 @@
|
||
unsigned long va = (d->resource.start + DIO_VIRADDRBASE);
|
||
struct hplance_private *lp;
|
||
int i;
|
||
-
|
||
- printk(KERN_INFO "%s: %s; select code %d, addr", dev->name, d->name, d->scode);
|
||
-
|
||
+
|
||
/* reset the board */
|
||
out_8(va+DIO_IDOFF, 0xff);
|
||
udelay(100); /* ariba! ariba! udelay! udelay! */
|
||
@@ -143,7 +151,6 @@
|
||
*/
|
||
dev->dev_addr[i] = ((in_8(va + HPLANCE_NVRAMOFF + i*4 + 1) & 0xF) << 4)
|
||
| (in_8(va + HPLANCE_NVRAMOFF + i*4 + 3) & 0xF);
|
||
- printk("%c%2.2x", i == 0 ? ' ' : ':', dev->dev_addr[i]);
|
||
}
|
||
|
||
lp = netdev_priv(dev);
|
||
@@ -160,7 +167,6 @@
|
||
lp->lance.lance_log_tx_bufs = LANCE_LOG_TX_BUFFERS;
|
||
lp->lance.rx_ring_mod_mask = RX_RING_MOD_MASK;
|
||
lp->lance.tx_ring_mod_mask = TX_RING_MOD_MASK;
|
||
- printk(", irq %d\n", lp->lance.irq);
|
||
}
|
||
|
||
/* This is disgusting. We have to check the DIO status register for ack every
|
||
diff -urN linux-i386/drivers/net/mac89x0.c linux-m68k/drivers/net/mac89x0.c
|
||
--- linux-i386/drivers/net/mac89x0.c 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/drivers/net/mac89x0.c 2006-06-18 19:08:40.000000000 +0200
|
||
@@ -128,7 +128,7 @@
|
||
extern void reset_chip(struct net_device *dev);
|
||
#endif
|
||
static int net_open(struct net_device *dev);
|
||
-static int net_send_packet(struct sk_buff *skb, struct net_device *dev);
|
||
+static int net_send_packet(struct sk_buff *skb, struct net_device *dev);
|
||
static irqreturn_t net_interrupt(int irq, void *dev_id, struct pt_regs *regs);
|
||
static void set_multicast_list(struct net_device *dev);
|
||
static void net_rx(struct net_device *dev);
|
||
@@ -374,56 +374,37 @@
|
||
static int
|
||
net_send_packet(struct sk_buff *skb, struct net_device *dev)
|
||
{
|
||
- if (dev->tbusy) {
|
||
- /* If we get here, some higher level has decided we are broken.
|
||
- There should really be a "kick me" function call instead. */
|
||
- int tickssofar = jiffies - dev->trans_start;
|
||
- if (tickssofar < 5)
|
||
- return 1;
|
||
- if (net_debug > 0) printk("%s: transmit timed out, %s?\n", dev->name,
|
||
- tx_done(dev) ? "IRQ conflict" : "network cable problem");
|
||
- /* Try to restart the adaptor. */
|
||
- dev->tbusy=0;
|
||
- dev->trans_start = jiffies;
|
||
- }
|
||
-
|
||
- /* Block a timer-based transmit from overlapping. This could better be
|
||
- done with atomic_swap(1, dev->tbusy), but set_bit() works as well. */
|
||
- if (test_and_set_bit(0, (void*)&dev->tbusy) != 0)
|
||
- printk("%s: Transmitter access conflict.\n", dev->name);
|
||
- else {
|
||
- struct net_local *lp = netdev_priv(dev);
|
||
- unsigned long flags;
|
||
-
|
||
- if (net_debug > 3)
|
||
- printk("%s: sent %d byte packet of type %x\n",
|
||
- dev->name, skb->len,
|
||
- (skb->data[ETH_ALEN+ETH_ALEN] << 8)
|
||
- | skb->data[ETH_ALEN+ETH_ALEN+1]);
|
||
-
|
||
- /* keep the upload from being interrupted, since we
|
||
- ask the chip to start transmitting before the
|
||
- whole packet has been completely uploaded. */
|
||
- local_irq_save(flags);
|
||
-
|
||
- /* initiate a transmit sequence */
|
||
- writereg(dev, PP_TxCMD, lp->send_cmd);
|
||
- writereg(dev, PP_TxLength, skb->len);
|
||
-
|
||
- /* Test to see if the chip has allocated memory for the packet */
|
||
- if ((readreg(dev, PP_BusST) & READY_FOR_TX_NOW) == 0) {
|
||
- /* Gasp! It hasn't. But that shouldn't happen since
|
||
- we're waiting for TxOk, so return 1 and requeue this packet. */
|
||
- local_irq_restore(flags);
|
||
- return 1;
|
||
- }
|
||
+ struct net_local *lp = netdev_priv(dev);
|
||
+ unsigned long flags;
|
||
|
||
- /* Write the contents of the packet */
|
||
- memcpy_toio(dev->mem_start + PP_TxFrame, skb->data, skb->len+1);
|
||
+ if (net_debug > 3)
|
||
+ printk("%s: sent %d byte packet of type %x\n",
|
||
+ dev->name, skb->len,
|
||
+ (skb->data[ETH_ALEN+ETH_ALEN] << 8)
|
||
+ | skb->data[ETH_ALEN+ETH_ALEN+1]);
|
||
+
|
||
+ /* keep the upload from being interrupted, since we
|
||
+ ask the chip to start transmitting before the
|
||
+ whole packet has been completely uploaded. */
|
||
+ local_irq_save(flags);
|
||
|
||
+ /* initiate a transmit sequence */
|
||
+ writereg(dev, PP_TxCMD, lp->send_cmd);
|
||
+ writereg(dev, PP_TxLength, skb->len);
|
||
+
|
||
+ /* Test to see if the chip has allocated memory for the packet */
|
||
+ if ((readreg(dev, PP_BusST) & READY_FOR_TX_NOW) == 0) {
|
||
+ /* Gasp! It hasn't. But that shouldn't happen since
|
||
+ we're waiting for TxOk, so return 1 and requeue this packet. */
|
||
local_irq_restore(flags);
|
||
- dev->trans_start = jiffies;
|
||
+ return 1;
|
||
}
|
||
+
|
||
+ /* Write the contents of the packet */
|
||
+ memcpy((void *)(dev->mem_start + PP_TxFrame), skb->data, skb->len+1);
|
||
+
|
||
+ local_irq_restore(flags);
|
||
+ dev->trans_start = jiffies;
|
||
dev_kfree_skb (skb);
|
||
|
||
return 0;
|
||
@@ -441,9 +422,6 @@
|
||
printk ("net_interrupt(): irq %d for unknown device.\n", irq);
|
||
return IRQ_NONE;
|
||
}
|
||
- if (dev->interrupt)
|
||
- printk("%s: Re-entering the interrupt handler.\n", dev->name);
|
||
- dev->interrupt = 1;
|
||
|
||
ioaddr = dev->base_addr;
|
||
lp = netdev_priv(dev);
|
||
@@ -464,8 +442,7 @@
|
||
break;
|
||
case ISQ_TRANSMITTER_EVENT:
|
||
lp->stats.tx_packets++;
|
||
- dev->tbusy = 0;
|
||
- mark_bh(NET_BH); /* Inform upper layers. */
|
||
+ netif_wake_queue(dev);
|
||
if ((status & TX_OK) == 0) lp->stats.tx_errors++;
|
||
if (status & TX_LOST_CRS) lp->stats.tx_carrier_errors++;
|
||
if (status & TX_SQE_ERROR) lp->stats.tx_heartbeat_errors++;
|
||
@@ -479,8 +456,7 @@
|
||
That shouldn't happen since we only ever
|
||
load one packet. Shrug. Do the right
|
||
thing anyway. */
|
||
- dev->tbusy = 0;
|
||
- mark_bh(NET_BH); /* Inform upper layers. */
|
||
+ netif_wake_queue(dev);
|
||
}
|
||
if (status & TX_UNDERRUN) {
|
||
if (net_debug > 0) printk("%s: transmit underrun\n", dev->name);
|
||
@@ -497,7 +473,6 @@
|
||
break;
|
||
}
|
||
}
|
||
- dev->interrupt = 0;
|
||
return IRQ_HANDLED;
|
||
}
|
||
|
||
@@ -532,7 +507,7 @@
|
||
skb_put(skb, length);
|
||
skb->dev = dev;
|
||
|
||
- memcpy_fromio(skb->data, dev->mem_start + PP_RxFrame, length);
|
||
+ memcpy(skb->data, (void *)(dev->mem_start + PP_RxFrame), length);
|
||
|
||
if (net_debug > 3)printk("%s: received %d byte packet of type %x\n",
|
||
dev->name, length,
|
||
@@ -611,8 +586,6 @@
|
||
static int set_mac_address(struct net_device *dev, void *addr)
|
||
{
|
||
int i;
|
||
- if (dev->start)
|
||
- return -EBUSY;
|
||
printk("%s: Setting MAC address to ", dev->name);
|
||
for (i = 0; i < 6; i++)
|
||
printk(" %2.2x", dev->dev_addr[i] = ((unsigned char *)addr)[i]);
|
||
diff -urN linux-i386/drivers/net/sun3lance.c linux-m68k/drivers/net/sun3lance.c
|
||
--- linux-i386/drivers/net/sun3lance.c 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/drivers/net/sun3lance.c 2006-06-18 19:08:41.000000000 +0200
|
||
@@ -55,7 +55,7 @@
|
||
/* sun3/60 addr/irq for the lance chip. If your sun is different,
|
||
change this. */
|
||
#define LANCE_OBIO 0x120000
|
||
-#define LANCE_IRQ IRQ3
|
||
+#define LANCE_IRQ IRQ_AUTO_3
|
||
|
||
/* Debug level:
|
||
* 0 = silent, print only serious errors
|
||
diff -urN linux-i386/drivers/scsi/53c7xx.c linux-m68k/drivers/scsi/53c7xx.c
|
||
--- linux-i386/drivers/scsi/53c7xx.c 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/drivers/scsi/53c7xx.c 2006-04-10 00:23:01.000000000 +0200
|
||
@@ -308,7 +308,7 @@
|
||
|
||
static int check_address (unsigned long addr, int size);
|
||
static void dump_events (struct Scsi_Host *host, int count);
|
||
-static Scsi_Cmnd * return_outstanding_commands (struct Scsi_Host *host,
|
||
+static struct scsi_cmnd * return_outstanding_commands (struct Scsi_Host *host,
|
||
int free, int issue);
|
||
static void hard_reset (struct Scsi_Host *host);
|
||
static void ncr_scsi_reset (struct Scsi_Host *host);
|
||
@@ -317,7 +317,7 @@
|
||
int scntl3, int now_connected);
|
||
static int datapath_residual (struct Scsi_Host *host);
|
||
static const char * sbcl_to_phase (int sbcl);
|
||
-static void print_progress (Scsi_Cmnd *cmd);
|
||
+static void print_progress (struct scsi_cmnd *cmd);
|
||
static void print_queues (struct Scsi_Host *host);
|
||
static void process_issue_queue (unsigned long flags);
|
||
static int shutdown (struct Scsi_Host *host);
|
||
@@ -342,9 +342,8 @@
|
||
static void NCR53c7x0_soft_reset (struct Scsi_Host *host);
|
||
|
||
/* Size of event list (per host adapter) */
|
||
-static int track_events = 0;
|
||
-static struct Scsi_Host *first_host = NULL; /* Head of list of NCR boards */
|
||
-static struct scsi_host_template *the_template = NULL;
|
||
+static int track_events;
|
||
+static struct scsi_host_template *the_template;
|
||
|
||
/* NCR53c710 script handling code */
|
||
|
||
@@ -667,8 +666,11 @@
|
||
|
||
static struct Scsi_Host *
|
||
find_host (int host) {
|
||
- struct Scsi_Host *h;
|
||
- for (h = first_host; h && h->host_no != host; h = h->next);
|
||
+ struct Scsi_Host *h, *s;
|
||
+ list_for_each_entry_safe(h, s, &the_template->legacy_hosts, sht_legacy_list) {
|
||
+ if (h->host_no == host)
|
||
+ break;
|
||
+ }
|
||
if (!h) {
|
||
printk (KERN_ALERT "scsi%d not found\n", host);
|
||
return NULL;
|
||
@@ -716,14 +718,14 @@
|
||
}
|
||
hostdata = (struct NCR53c7x0_hostdata *)h->hostdata[0];
|
||
|
||
- local_irq_save(flags);
|
||
+ spin_lock_irqsave(host->host_lock, flags);
|
||
if (hostdata->initiate_sdtr & (1 << target)) {
|
||
- local_irq_restore(flags);
|
||
+ spin_unlock_irqrestore(host->host_lock, flags);
|
||
printk (KERN_ALERT "target %d already doing SDTR\n", target);
|
||
return -1;
|
||
}
|
||
hostdata->initiate_sdtr |= (1 << target);
|
||
- local_irq_restore(flags);
|
||
+ spin_unlock_irqrestore(host->host_lock, flags);
|
||
return 0;
|
||
}
|
||
#endif
|
||
@@ -1034,9 +1036,6 @@
|
||
|
||
ccf = clock_to_ccf_710 (expected_clock);
|
||
|
||
- for (i = 0; i < 16; ++i)
|
||
- hostdata->cmd_allocated[i] = 0;
|
||
-
|
||
if (hostdata->init_save_regs)
|
||
hostdata->init_save_regs (host);
|
||
if (hostdata->init_fixup)
|
||
@@ -1044,7 +1043,6 @@
|
||
|
||
if (!the_template) {
|
||
the_template = host->hostt;
|
||
- first_host = host;
|
||
}
|
||
|
||
/*
|
||
@@ -1307,7 +1305,6 @@
|
||
hostdata->free->size = max_cmd_size;
|
||
hostdata->free->free = NULL;
|
||
hostdata->free->next = NULL;
|
||
- hostdata->extra_allocate = 0;
|
||
|
||
/* Allocate command start code space */
|
||
hostdata->schedule = (chip == 700 || chip == 70066) ?
|
||
@@ -1590,10 +1587,10 @@
|
||
|
||
/* The NCR chip _must_ be idle to run the test scripts */
|
||
|
||
- local_irq_save(flags);
|
||
+ spin_lock_irqsave(host->host_lock, flags);
|
||
if (!hostdata->idle) {
|
||
printk ("scsi%d : chip not idle, aborting tests\n", host->host_no);
|
||
- local_irq_restore(flags);
|
||
+ spin_unlock_irqrestore(host->host_lock, flags);
|
||
return -1;
|
||
}
|
||
|
||
@@ -1617,7 +1614,7 @@
|
||
NCR53c7x0_write8 (DCNTL_REG, hostdata->saved_dcntl | DCNTL_SSM |
|
||
DCNTL_STD);
|
||
printk (" started\n");
|
||
- local_irq_restore(flags);
|
||
+ spin_unlock_irqrestore(host->host_lock, flags);
|
||
|
||
/*
|
||
* This is currently a .5 second timeout, since (in theory) no slow
|
||
@@ -1656,7 +1653,7 @@
|
||
hostdata->script, start);
|
||
printk ("scsi%d : DSPS = 0x%x\n", host->host_no,
|
||
NCR53c7x0_read32(DSPS_REG));
|
||
- local_irq_restore(flags);
|
||
+ spin_unlock_irqrestore(host->host_lock, flags);
|
||
return -1;
|
||
}
|
||
hostdata->test_running = 0;
|
||
@@ -1694,7 +1691,7 @@
|
||
local_irq_disable();
|
||
if (!hostdata->idle) {
|
||
printk ("scsi%d : chip not idle, aborting tests\n", host->host_no);
|
||
- local_irq_restore(flags);
|
||
+ spin_unlock_irqrestore(host->host_lock, flags);
|
||
return -1;
|
||
}
|
||
|
||
@@ -1710,7 +1707,7 @@
|
||
if (hostdata->options & OPTION_DEBUG_TRACE)
|
||
NCR53c7x0_write8 (DCNTL_REG, hostdata->saved_dcntl |
|
||
DCNTL_SSM | DCNTL_STD);
|
||
- local_irq_restore(flags);
|
||
+ spin_unlock_irqrestore(host->host_lock, flags);
|
||
|
||
timeout = jiffies + 5 * HZ; /* arbitrary */
|
||
while ((hostdata->test_completed == -1) && time_before(jiffies, timeout))
|
||
@@ -1732,19 +1729,19 @@
|
||
host->host_no, i);
|
||
if (!hostdata->idle) {
|
||
printk("scsi%d : not idle\n", host->host_no);
|
||
- local_irq_restore(flags);
|
||
+ spin_unlock_irqrestore(host->host_lock, flags);
|
||
return -1;
|
||
}
|
||
} else if (hostdata->test_completed == -1) {
|
||
printk ("scsi%d : test 2 timed out\n", host->host_no);
|
||
- local_irq_restore(flags);
|
||
+ spin_unlock_irqrestore(host->host_lock, flags);
|
||
return -1;
|
||
}
|
||
hostdata->test_running = 0;
|
||
}
|
||
}
|
||
|
||
- local_irq_restore(flags);
|
||
+ spin_unlock_irqrestore(host->host_lock, flags);
|
||
return 0;
|
||
}
|
||
|
||
@@ -1760,7 +1757,7 @@
|
||
|
||
static void
|
||
NCR53c7xx_dsa_fixup (struct NCR53c7x0_cmd *cmd) {
|
||
- Scsi_Cmnd *c = cmd->cmd;
|
||
+ struct scsi_cmnd *c = cmd->cmd;
|
||
struct Scsi_Host *host = c->device->host;
|
||
struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
|
||
host->hostdata[0];
|
||
@@ -1846,7 +1843,7 @@
|
||
*
|
||
* Purpose : mark SCSI command as finished, OR'ing the host portion
|
||
* of the result word into the result field of the corresponding
|
||
- * Scsi_Cmnd structure, and removing it from the internal queues.
|
||
+ * scsi_cmnd structure, and removing it from the internal queues.
|
||
*
|
||
* Inputs : cmd - command, result - entire result field
|
||
*
|
||
@@ -1857,7 +1854,7 @@
|
||
|
||
static void
|
||
abnormal_finished (struct NCR53c7x0_cmd *cmd, int result) {
|
||
- Scsi_Cmnd *c = cmd->cmd;
|
||
+ struct scsi_cmnd *c = cmd->cmd;
|
||
struct Scsi_Host *host = c->device->host;
|
||
struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
|
||
host->hostdata[0];
|
||
@@ -1871,7 +1868,7 @@
|
||
printk ("scsi%d: abnormal finished\n", host->host_no);
|
||
#endif
|
||
|
||
- local_irq_save(flags);
|
||
+ spin_lock_irqsave(host->host_lock, flags);
|
||
found = 0;
|
||
/*
|
||
* Traverse the NCR issue array until we find a match or run out
|
||
@@ -1954,7 +1951,7 @@
|
||
c->result = result;
|
||
c->scsi_done(c);
|
||
|
||
- local_irq_restore(flags);
|
||
+ spin_unlock_irqrestore(host->host_lock, flags);
|
||
run_process_issue_queue();
|
||
}
|
||
|
||
@@ -1976,7 +1973,7 @@
|
||
NCR53c7x0_local_declare();
|
||
struct NCR53c7x0_break *bp;
|
||
#if 0
|
||
- Scsi_Cmnd *c = cmd ? cmd->cmd : NULL;
|
||
+ struct scsi_cmnd *c = cmd ? cmd->cmd : NULL;
|
||
#endif
|
||
u32 *dsp;
|
||
struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
|
||
@@ -1989,7 +1986,7 @@
|
||
* dump the appropriate debugging information to standard
|
||
* output.
|
||
*/
|
||
- local_irq_save(flags);
|
||
+ spin_lock_irqsave(host->host_lock, flags);
|
||
dsp = (u32 *) bus_to_virt(NCR53c7x0_read32(DSP_REG));
|
||
for (bp = hostdata->breakpoints; bp && bp->address != dsp;
|
||
bp = bp->next);
|
||
@@ -2011,7 +2008,7 @@
|
||
* instruction in bytes.
|
||
*/
|
||
|
||
- local_irq_restore(flags);
|
||
+ spin_unlock_irqrestore(host->host_lock, flags);
|
||
}
|
||
/*
|
||
* Function : static void print_synchronous (const char *prefix,
|
||
@@ -2253,7 +2250,7 @@
|
||
NCR53c7x0_cmd *cmd) {
|
||
NCR53c7x0_local_declare();
|
||
int print;
|
||
- Scsi_Cmnd *c = cmd ? cmd->cmd : NULL;
|
||
+ struct scsi_cmnd *c = cmd ? cmd->cmd : NULL;
|
||
struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
|
||
host->hostdata[0];
|
||
u32 dsps,*dsp; /* Argument of the INT instruction */
|
||
@@ -2917,7 +2914,7 @@
|
||
host->hostdata[0];
|
||
NCR53c7x0_local_setup(host);
|
||
|
||
- local_irq_save(flags);
|
||
+ spin_lock_irqsave(host->host_lock, flags);
|
||
|
||
/* Disable scsi chip and s/w level 7 ints */
|
||
|
||
@@ -3018,12 +3015,12 @@
|
||
}
|
||
#endif
|
||
/* Anything needed for your hardware? */
|
||
- local_irq_restore(flags);
|
||
+ spin_unlock_irqrestore(host->host_lock, flags);
|
||
}
|
||
|
||
|
||
/*
|
||
- * Function static struct NCR53c7x0_cmd *allocate_cmd (Scsi_Cmnd *cmd)
|
||
+ * Function static struct NCR53c7x0_cmd *allocate_cmd (struct scsi_cmnd *cmd)
|
||
*
|
||
* Purpose : Return the first free NCR53c7x0_cmd structure (which are
|
||
* reused in a LIFO manner to minimize cache thrashing).
|
||
@@ -3050,86 +3047,25 @@
|
||
}
|
||
|
||
static struct NCR53c7x0_cmd *
|
||
-allocate_cmd (Scsi_Cmnd *cmd) {
|
||
+allocate_cmd (struct scsi_cmnd *cmd) {
|
||
struct Scsi_Host *host = cmd->device->host;
|
||
struct NCR53c7x0_hostdata *hostdata =
|
||
(struct NCR53c7x0_hostdata *) host->hostdata[0];
|
||
- u32 real; /* Real address */
|
||
- int size; /* Size of *tmp */
|
||
struct NCR53c7x0_cmd *tmp;
|
||
unsigned long flags;
|
||
|
||
if (hostdata->options & OPTION_DEBUG_ALLOCATION)
|
||
printk ("scsi%d : num_cmds = %d, can_queue = %d\n"
|
||
- " target = %d, lun = %d, %s\n",
|
||
+ " target = %d, lun = %d\n",
|
||
host->host_no, hostdata->num_cmds, host->can_queue,
|
||
- cmd->device->id, cmd->device->lun, (hostdata->cmd_allocated[cmd->device->id] &
|
||
- (1 << cmd->device->lun)) ? "already allocated" : "not allocated");
|
||
-
|
||
-/*
|
||
- * If we have not yet reserved commands for this I_T_L nexus, and
|
||
- * the device exists (as indicated by permanent Scsi_Cmnd structures
|
||
- * being allocated under 1.3.x, or being outside of scan_scsis in
|
||
- * 1.2.x), do so now.
|
||
- */
|
||
- if (!(hostdata->cmd_allocated[cmd->device->id] & (1 << cmd->device->lun)) &&
|
||
- cmd->device && cmd->device->has_cmdblocks) {
|
||
- if ((hostdata->extra_allocate + hostdata->num_cmds) < host->can_queue)
|
||
- hostdata->extra_allocate += host->cmd_per_lun;
|
||
- hostdata->cmd_allocated[cmd->device->id] |= (1 << cmd->device->lun);
|
||
- }
|
||
-
|
||
- for (; hostdata->extra_allocate > 0 ; --hostdata->extra_allocate,
|
||
- ++hostdata->num_cmds) {
|
||
- /* historically, kmalloc has returned unaligned addresses; pad so we
|
||
- have enough room to ROUNDUP */
|
||
- size = hostdata->max_cmd_size + sizeof (void *);
|
||
-#ifdef FORCE_DSA_ALIGNMENT
|
||
- /*
|
||
- * 53c710 rev.0 doesn't have an add-with-carry instruction.
|
||
- * Ensure we allocate enough memory to force alignment.
|
||
- */
|
||
- size += 256;
|
||
-#endif
|
||
-/* FIXME: for ISA bus '7xx chips, we need to or GFP_DMA in here */
|
||
+ cmd->device->id, cmd->device->lun);
|
||
|
||
- if (size > 4096) {
|
||
- printk (KERN_ERR "53c7xx: allocate_cmd size > 4K\n");
|
||
- return NULL;
|
||
- }
|
||
- real = get_zeroed_page(GFP_ATOMIC);
|
||
- if (real == 0)
|
||
- return NULL;
|
||
- memset((void *)real, 0, 4096);
|
||
- cache_push(virt_to_phys((void *)real), 4096);
|
||
- cache_clear(virt_to_phys((void *)real), 4096);
|
||
- kernel_set_cachemode((void *)real, 4096, IOMAP_NOCACHE_SER);
|
||
- tmp = ROUNDUP(real, void *);
|
||
-#ifdef FORCE_DSA_ALIGNMENT
|
||
- {
|
||
- if (((u32)tmp & 0xff) > CmdPageStart)
|
||
- tmp = (struct NCR53c7x0_cmd *)((u32)tmp + 255);
|
||
- tmp = (struct NCR53c7x0_cmd *)(((u32)tmp & ~0xff) + CmdPageStart);
|
||
-#if 0
|
||
- printk ("scsi: size = %d, real = 0x%08x, tmp set to 0x%08x\n",
|
||
- size, real, (u32)tmp);
|
||
-#endif
|
||
- }
|
||
-#endif
|
||
- tmp->real = (void *)real;
|
||
- tmp->size = size;
|
||
- tmp->free = ((void (*)(void *, int)) my_free_page);
|
||
- local_irq_save(flags);
|
||
- tmp->next = hostdata->free;
|
||
- hostdata->free = tmp;
|
||
- local_irq_restore(flags);
|
||
- }
|
||
- local_irq_save(flags);
|
||
+ spin_lock_irqsave(host->host_lock, flags);
|
||
tmp = (struct NCR53c7x0_cmd *) hostdata->free;
|
||
if (tmp) {
|
||
hostdata->free = tmp->next;
|
||
}
|
||
- local_irq_restore(flags);
|
||
+ spin_unlock_irqrestore(host->host_lock, flags);
|
||
if (!tmp)
|
||
printk ("scsi%d : can't allocate command for target %d lun %d\n",
|
||
host->host_no, cmd->device->id, cmd->device->lun);
|
||
@@ -3137,11 +3073,11 @@
|
||
}
|
||
|
||
/*
|
||
- * Function static struct NCR53c7x0_cmd *create_cmd (Scsi_Cmnd *cmd)
|
||
+ * Function static struct NCR53c7x0_cmd *create_cmd (struct scsi_cmnd *cmd)
|
||
*
|
||
*
|
||
* Purpose : allocate a NCR53c7x0_cmd structure, initialize it based on the
|
||
- * Scsi_Cmnd structure passed in cmd, including dsa and Linux field
|
||
+ * scsi_cmnd structure passed in cmd, including dsa and Linux field
|
||
* initialization, and dsa code relocation.
|
||
*
|
||
* Inputs : cmd - SCSI command
|
||
@@ -3150,7 +3086,7 @@
|
||
* NULL on failure.
|
||
*/
|
||
static struct NCR53c7x0_cmd *
|
||
-create_cmd (Scsi_Cmnd *cmd) {
|
||
+create_cmd (struct scsi_cmnd *cmd) {
|
||
NCR53c7x0_local_declare();
|
||
struct Scsi_Host *host = cmd->device->host;
|
||
struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
|
||
@@ -3174,7 +3110,7 @@
|
||
return NULL;
|
||
|
||
/*
|
||
- * Copy CDB and initialised result fields from Scsi_Cmnd to NCR53c7x0_cmd.
|
||
+ * Copy CDB and initialised result fields from scsi_cmnd to NCR53c7x0_cmd.
|
||
* We do this because NCR53c7x0_cmd may have a special cache mode
|
||
* selected to cope with lack of bus snooping, etc.
|
||
*/
|
||
@@ -3317,7 +3253,7 @@
|
||
|
||
patch_dsa_32(tmp->dsa, dsa_next, 0, 0);
|
||
/*
|
||
- * XXX is this giving 53c710 access to the Scsi_Cmnd in some way?
|
||
+ * XXX is this giving 53c710 access to the scsi_cmnd in some way?
|
||
* Do we need to change it for caching reasons?
|
||
*/
|
||
patch_dsa_32(tmp->dsa, dsa_cmnd, 0, virt_to_bus(cmd));
|
||
@@ -3348,17 +3284,17 @@
|
||
memcpy ((void *) (tmp->select + 1), (void *) wdtr_message,
|
||
sizeof(wdtr_message));
|
||
patch_dsa_32(tmp->dsa, dsa_msgout, 0, 1 + sizeof(wdtr_message));
|
||
- local_irq_save(flags);
|
||
+ spin_lock_irqsave(host->host_lock, flags);
|
||
hostdata->initiate_wdtr &= ~(1 << cmd->device->id);
|
||
- local_irq_restore(flags);
|
||
+ spin_unlock_irqrestore(host->host_lock, flags);
|
||
} else if (hostdata->initiate_sdtr & (1 << cmd->device->id)) {
|
||
memcpy ((void *) (tmp->select + 1), (void *) sdtr_message,
|
||
sizeof(sdtr_message));
|
||
patch_dsa_32(tmp->dsa, dsa_msgout, 0, 1 + sizeof(sdtr_message));
|
||
tmp->flags |= CMD_FLAG_SDTR;
|
||
- local_irq_save(flags);
|
||
+ spin_lock_irqsave(host->host_lock, flags);
|
||
hostdata->initiate_sdtr &= ~(1 << cmd->device->id);
|
||
- local_irq_restore(flags);
|
||
+ spin_unlock_irqrestore(host->host_lock, flags);
|
||
|
||
}
|
||
#if 1
|
||
@@ -3571,8 +3507,8 @@
|
||
}
|
||
|
||
/*
|
||
- * Function : int NCR53c7xx_queue_command (Scsi_Cmnd *cmd,
|
||
- * void (*done)(Scsi_Cmnd *))
|
||
+ * Function : int NCR53c7xx_queue_command (struct scsi_cmnd *cmd,
|
||
+ * void (*done)(struct scsi_cmnd *))
|
||
*
|
||
* Purpose : enqueues a SCSI command
|
||
*
|
||
@@ -3586,18 +3522,18 @@
|
||
* twiddling done to the host specific fields of cmd. If the
|
||
* process_issue_queue coroutine isn't running, it is restarted.
|
||
*
|
||
- * NOTE : we use the host_scribble field of the Scsi_Cmnd structure to
|
||
+ * NOTE : we use the host_scribble field of the scsi_cmnd structure to
|
||
* hold our own data, and pervert the ptr field of the SCp field
|
||
* to create a linked list.
|
||
*/
|
||
|
||
int
|
||
-NCR53c7xx_queue_command (Scsi_Cmnd *cmd, void (* done)(Scsi_Cmnd *)) {
|
||
+NCR53c7xx_queue_command (struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *)) {
|
||
struct Scsi_Host *host = cmd->device->host;
|
||
struct NCR53c7x0_hostdata *hostdata =
|
||
(struct NCR53c7x0_hostdata *) host->hostdata[0];
|
||
unsigned long flags;
|
||
- Scsi_Cmnd *tmp;
|
||
+ struct scsi_cmnd *tmp;
|
||
|
||
cmd->scsi_done = done;
|
||
cmd->host_scribble = NULL;
|
||
@@ -3615,7 +3551,7 @@
|
||
}
|
||
#endif
|
||
|
||
- local_irq_save(flags);
|
||
+ spin_lock_irqsave(host->host_lock, flags);
|
||
if ((hostdata->options & (OPTION_DEBUG_INIT_ONLY|OPTION_DEBUG_PROBE_ONLY))
|
||
|| ((hostdata->options & OPTION_DEBUG_TARGET_LIMIT) &&
|
||
!(hostdata->debug_lun_limit[cmd->device->id] & (1 << cmd->device->lun)))
|
||
@@ -3630,7 +3566,7 @@
|
||
cmd->device->id, cmd->device->lun);
|
||
cmd->result = (DID_BAD_TARGET << 16);
|
||
done(cmd);
|
||
- local_irq_restore(flags);
|
||
+ spin_unlock_irqrestore(host->host_lock, flags);
|
||
return 0;
|
||
}
|
||
|
||
@@ -3639,7 +3575,7 @@
|
||
printk("scsi%d : maximum commands exceeded\n", host->host_no);
|
||
cmd->result = (DID_BAD_TARGET << 16);
|
||
done(cmd);
|
||
- local_irq_restore(flags);
|
||
+ spin_unlock_irqrestore(host->host_lock, flags);
|
||
return 0;
|
||
}
|
||
|
||
@@ -3651,7 +3587,7 @@
|
||
host->host_no);
|
||
cmd->result = (DID_BAD_TARGET << 16);
|
||
done(cmd);
|
||
- local_irq_restore(flags);
|
||
+ spin_unlock_irqrestore(host->host_lock, flags);
|
||
return 0;
|
||
}
|
||
}
|
||
@@ -3674,18 +3610,18 @@
|
||
cmd->SCp.ptr = (unsigned char *) hostdata->issue_queue;
|
||
hostdata->issue_queue = cmd;
|
||
} else {
|
||
- for (tmp = (Scsi_Cmnd *) hostdata->issue_queue; tmp->SCp.ptr;
|
||
- tmp = (Scsi_Cmnd *) tmp->SCp.ptr);
|
||
+ for (tmp = (struct scsi_cmnd *) hostdata->issue_queue; tmp->SCp.ptr;
|
||
+ tmp = (struct scsi_cmnd *) tmp->SCp.ptr);
|
||
tmp->SCp.ptr = (unsigned char *) cmd;
|
||
}
|
||
- local_irq_restore(flags);
|
||
+ spin_unlock_irqrestore(host->host_lock, flags);
|
||
run_process_issue_queue();
|
||
return 0;
|
||
}
|
||
|
||
/*
|
||
* Function : void to_schedule_list (struct Scsi_Host *host,
|
||
- * struct NCR53c7x0_hostdata * hostdata, Scsi_Cmnd *cmd)
|
||
+ * struct NCR53c7x0_hostdata * hostdata, struct scsi_cmnd *cmd)
|
||
*
|
||
* Purpose : takes a SCSI command which was just removed from the
|
||
* issue queue, and deals with it by inserting it in the first
|
||
@@ -3706,7 +3642,7 @@
|
||
to_schedule_list (struct Scsi_Host *host, struct NCR53c7x0_hostdata *hostdata,
|
||
struct NCR53c7x0_cmd *cmd) {
|
||
NCR53c7x0_local_declare();
|
||
- Scsi_Cmnd *tmp = cmd->cmd;
|
||
+ struct scsi_cmnd *tmp = cmd->cmd;
|
||
unsigned long flags;
|
||
/* dsa start is negative, so subtraction is used */
|
||
volatile u32 *ncrcurrent;
|
||
@@ -3718,7 +3654,7 @@
|
||
virt_to_bus(hostdata->dsa), hostdata->dsa);
|
||
#endif
|
||
|
||
- local_irq_save(flags);
|
||
+ spin_lock_irqsave(host->host_lock, flags);
|
||
|
||
/*
|
||
* Work around race condition : if an interrupt fired and we
|
||
@@ -3731,7 +3667,7 @@
|
||
cmd->next = (struct NCR53c7x0_cmd *) hostdata->free;
|
||
hostdata->free = cmd;
|
||
tmp->scsi_done(tmp);
|
||
- local_irq_restore(flags);
|
||
+ spin_unlock_irqrestore(host->host_lock, flags);
|
||
return;
|
||
}
|
||
|
||
@@ -3761,7 +3697,7 @@
|
||
cmd->next = (struct NCR53c7x0_cmd *) hostdata->free;
|
||
hostdata->free = cmd;
|
||
tmp->scsi_done(tmp);
|
||
- local_irq_restore(flags);
|
||
+ spin_unlock_irqrestore(host->host_lock, flags);
|
||
return;
|
||
}
|
||
|
||
@@ -3782,12 +3718,12 @@
|
||
NCR53c7x0_write8(hostdata->istat, ISTAT_10_SIGP);
|
||
}
|
||
|
||
- local_irq_restore(flags);
|
||
+ spin_unlock_irqrestore(host->host_lock, flags);
|
||
}
|
||
|
||
/*
|
||
* Function : busyp (struct Scsi_Host *host, struct NCR53c7x0_hostdata
|
||
- * *hostdata, Scsi_Cmnd *cmd)
|
||
+ * *hostdata, struct scsi_cmnd *cmd)
|
||
*
|
||
* Purpose : decide if we can pass the given SCSI command on to the
|
||
* device in question or not.
|
||
@@ -3797,7 +3733,7 @@
|
||
|
||
static __inline__ int
|
||
busyp (struct Scsi_Host *host, struct NCR53c7x0_hostdata *hostdata,
|
||
- Scsi_Cmnd *cmd) {
|
||
+ struct scsi_cmnd *cmd) {
|
||
/* FIXME : in the future, this needs to accommodate SCSI-II tagged
|
||
queuing, and we may be able to play with fairness here a bit.
|
||
*/
|
||
@@ -3823,8 +3759,8 @@
|
||
|
||
static void
|
||
process_issue_queue (unsigned long flags) {
|
||
- Scsi_Cmnd *tmp, *prev;
|
||
- struct Scsi_Host *host;
|
||
+ struct scsi_cmnd *tmp, *prev;
|
||
+ struct Scsi_Host *host, *s;
|
||
struct NCR53c7x0_hostdata *hostdata;
|
||
int done;
|
||
|
||
@@ -3842,14 +3778,13 @@
|
||
do {
|
||
local_irq_disable(); /* Freeze request queues */
|
||
done = 1;
|
||
- for (host = first_host; host && host->hostt == the_template;
|
||
- host = host->next) {
|
||
+ list_for_each_entry_safe(host, s, &the_template->legacy_hosts, sht_legacy_list) {
|
||
hostdata = (struct NCR53c7x0_hostdata *) host->hostdata[0];
|
||
- local_irq_disable();
|
||
+ spin_lock_irq(host->host_lock);
|
||
if (hostdata->issue_queue) {
|
||
if (hostdata->state == STATE_DISABLED) {
|
||
- tmp = (Scsi_Cmnd *) hostdata->issue_queue;
|
||
- hostdata->issue_queue = (Scsi_Cmnd *) tmp->SCp.ptr;
|
||
+ tmp = (struct scsi_cmnd *) hostdata->issue_queue;
|
||
+ hostdata->issue_queue = (struct scsi_cmnd *) tmp->SCp.ptr;
|
||
tmp->result = (DID_BAD_TARGET << 16);
|
||
if (tmp->host_scribble) {
|
||
((struct NCR53c7x0_cmd *)tmp->host_scribble)->next =
|
||
@@ -3861,15 +3796,15 @@
|
||
tmp->scsi_done (tmp);
|
||
done = 0;
|
||
} else
|
||
- for (tmp = (Scsi_Cmnd *) hostdata->issue_queue,
|
||
- prev = NULL; tmp; prev = tmp, tmp = (Scsi_Cmnd *)
|
||
+ for (tmp = (struct scsi_cmnd *) hostdata->issue_queue,
|
||
+ prev = NULL; tmp; prev = tmp, tmp = (struct scsi_cmnd *)
|
||
tmp->SCp.ptr)
|
||
if (!tmp->host_scribble ||
|
||
!busyp (host, hostdata, tmp)) {
|
||
if (prev)
|
||
prev->SCp.ptr = tmp->SCp.ptr;
|
||
else
|
||
- hostdata->issue_queue = (Scsi_Cmnd *)
|
||
+ hostdata->issue_queue = (struct scsi_cmnd *)
|
||
tmp->SCp.ptr;
|
||
tmp->SCp.ptr = NULL;
|
||
if (tmp->host_scribble) {
|
||
@@ -3894,6 +3829,7 @@
|
||
done = 0;
|
||
} /* if target/lun is not busy */
|
||
} /* if hostdata->issue_queue */
|
||
+ spin_unlock(host->host_lock);
|
||
if (!done)
|
||
local_irq_restore(flags);
|
||
} /* for host */
|
||
@@ -4104,7 +4040,7 @@
|
||
int cnt = 0;
|
||
int i = insn_log_index;
|
||
int size;
|
||
- struct Scsi_Host *host = first_host;
|
||
+ struct Scsi_Host *host = (struct Scsi_Host *)the_template->legacy_hosts->next;
|
||
|
||
while (cnt < 4096) {
|
||
printk ("%08x (+%6x): ", insn_log[i], (insn_log[i] - (u32)&(((struct NCR53c7x0_hostdata *)host->hostdata[0])->script))/4);
|
||
@@ -4162,14 +4098,14 @@
|
||
* completion.
|
||
*/
|
||
|
||
- local_irq_save(flags);
|
||
+ spin_lock_irqsave(host->host_lock, flags);
|
||
restart:
|
||
for (cmd_prev_ptr = (struct NCR53c7x0_cmd **)&(hostdata->running_list),
|
||
cmd = (struct NCR53c7x0_cmd *) hostdata->running_list; cmd ;
|
||
cmd_prev_ptr = (struct NCR53c7x0_cmd **) &(cmd->next),
|
||
cmd = (struct NCR53c7x0_cmd *) cmd->next)
|
||
{
|
||
- Scsi_Cmnd *tmp;
|
||
+ struct scsi_cmnd *tmp;
|
||
|
||
if (!cmd) {
|
||
printk("scsi%d : very weird.\n", host->host_no);
|
||
@@ -4177,7 +4113,7 @@
|
||
}
|
||
|
||
if (!(tmp = cmd->cmd)) {
|
||
- printk("scsi%d : weird. NCR53c7x0_cmd has no Scsi_Cmnd\n",
|
||
+ printk("scsi%d : weird. NCR53c7x0_cmd has no scsi_cmnd\n",
|
||
host->host_no);
|
||
continue;
|
||
}
|
||
@@ -4216,7 +4152,7 @@
|
||
tmp->scsi_done(tmp);
|
||
goto restart;
|
||
}
|
||
- local_irq_restore(flags);
|
||
+ spin_unlock_irqrestore(host->host_lock, flags);
|
||
|
||
if (!search_found) {
|
||
printk ("scsi%d : WARNING : INTFLY with no completed commands.\n",
|
||
@@ -4251,7 +4187,7 @@
|
||
struct NCR53c7x0_cmd *cmd; /* command which halted */
|
||
u32 *dsa; /* DSA */
|
||
int handled = 0;
|
||
-
|
||
+ unsigned long flags;
|
||
#ifdef NCR_DEBUG
|
||
char buf[80]; /* Debugging sprintf buffer */
|
||
size_t buflen; /* Length of same */
|
||
@@ -4260,6 +4196,7 @@
|
||
host = (struct Scsi_Host *)dev_id;
|
||
hostdata = (struct NCR53c7x0_hostdata *) host->hostdata[0];
|
||
NCR53c7x0_local_setup(host);
|
||
+ spin_lock_irqsave(host->host_lock, flags);
|
||
|
||
/*
|
||
* Only read istat once per loop, since reading it again will unstack
|
||
@@ -4352,7 +4289,8 @@
|
||
}
|
||
}
|
||
}
|
||
- return IRQ_HANDLED;
|
||
+ spin_unlock_irqrestore(host->host_lock, flags);
|
||
+ return IRQ_RETVAL(handled);
|
||
}
|
||
|
||
|
||
@@ -4361,7 +4299,7 @@
|
||
*
|
||
* Purpose : Assuming that the NCR SCSI processor is currently
|
||
* halted, break the currently established nexus. Clean
|
||
- * up of the NCR53c7x0_cmd and Scsi_Cmnd structures should
|
||
+ * up of the NCR53c7x0_cmd and scsi_cmnd structures should
|
||
* be done on receipt of the abort interrupt.
|
||
*
|
||
* Inputs : host - SCSI host
|
||
@@ -4900,12 +4838,12 @@
|
||
/* Don't print instr. until we write DSP at end of intr function */
|
||
} else if (hostdata->options & OPTION_DEBUG_SINGLE) {
|
||
print_insn (host, dsp, "s ", 0);
|
||
- local_irq_save(flags);
|
||
+ spin_lock_irqsave(host->host_lock, flags);
|
||
/* XXX - should we do this, or can we get away with writing dsp? */
|
||
|
||
NCR53c7x0_write8 (DCNTL_REG, (NCR53c7x0_read8(DCNTL_REG) &
|
||
~DCNTL_SSM) | DCNTL_STD);
|
||
- local_irq_restore(flags);
|
||
+ spin_unlock_irqrestore(host->host_lock, flags);
|
||
} else {
|
||
printk(KERN_ALERT "scsi%d : unexpected single step interrupt at\n"
|
||
" ", host->host_no);
|
||
@@ -5128,7 +5066,7 @@
|
||
}
|
||
|
||
/*
|
||
- * Function : int NCR53c7xx_abort (Scsi_Cmnd *cmd)
|
||
+ * Function : int NCR53c7xx_abort (struct scsi_cmnd *cmd)
|
||
*
|
||
* Purpose : Abort an errant SCSI command, doing all necessary
|
||
* cleanup of the issue_queue, running_list, shared Linux/NCR
|
||
@@ -5140,14 +5078,14 @@
|
||
*/
|
||
|
||
int
|
||
-NCR53c7xx_abort (Scsi_Cmnd *cmd) {
|
||
+NCR53c7xx_abort (struct scsi_cmnd *cmd) {
|
||
NCR53c7x0_local_declare();
|
||
struct Scsi_Host *host = cmd->device->host;
|
||
struct NCR53c7x0_hostdata *hostdata = host ? (struct NCR53c7x0_hostdata *)
|
||
host->hostdata[0] : NULL;
|
||
unsigned long flags;
|
||
struct NCR53c7x0_cmd *curr, **prev;
|
||
- Scsi_Cmnd *me, **last;
|
||
+ struct scsi_cmnd *me, **last;
|
||
#if 0
|
||
static long cache_pid = -1;
|
||
#endif
|
||
@@ -5156,10 +5094,10 @@
|
||
if (!host) {
|
||
printk ("Bogus SCSI command pid %ld; no host structure\n",
|
||
cmd->pid);
|
||
- return SCSI_ABORT_ERROR;
|
||
+ return FAILED;
|
||
} else if (!hostdata) {
|
||
printk ("Bogus SCSI host %d; no hostdata\n", host->host_no);
|
||
- return SCSI_ABORT_ERROR;
|
||
+ return FAILED;
|
||
}
|
||
NCR53c7x0_local_setup(host);
|
||
|
||
@@ -5180,10 +5118,10 @@
|
||
printk ("scsi%d : dropped interrupt for command %ld\n", host->host_no,
|
||
cmd->pid);
|
||
NCR53c7x0_intr (host->irq, NULL, NULL);
|
||
- return SCSI_ABORT_BUSY;
|
||
+ return FAILED;
|
||
}
|
||
|
||
- local_irq_save(flags);
|
||
+ spin_lock_irqsave(host->host_lock, flags);
|
||
#if 0
|
||
if (cache_pid == cmd->pid)
|
||
panic ("scsi%d : bloody fetus %d\n", host->host_no, cmd->pid);
|
||
@@ -5202,13 +5140,13 @@
|
||
* pull the command out of the old queue, and call it aborted.
|
||
*/
|
||
|
||
- for (me = (Scsi_Cmnd *) hostdata->issue_queue,
|
||
- last = (Scsi_Cmnd **) &(hostdata->issue_queue);
|
||
- me && me != cmd; last = (Scsi_Cmnd **)&(me->SCp.ptr),
|
||
- me = (Scsi_Cmnd *)me->SCp.ptr);
|
||
+ for (me = (struct scsi_cmnd *) hostdata->issue_queue,
|
||
+ last = (struct scsi_cmnd **) &(hostdata->issue_queue);
|
||
+ me && me != cmd; last = (struct scsi_cmnd **)&(me->SCp.ptr),
|
||
+ me = (struct scsi_cmnd *)me->SCp.ptr);
|
||
|
||
if (me) {
|
||
- *last = (Scsi_Cmnd *) me->SCp.ptr;
|
||
+ *last = (struct scsi_cmnd *) me->SCp.ptr;
|
||
if (me->host_scribble) {
|
||
((struct NCR53c7x0_cmd *)me->host_scribble)->next = hostdata->free;
|
||
hostdata->free = (struct NCR53c7x0_cmd *) me->host_scribble;
|
||
@@ -5218,9 +5156,9 @@
|
||
cmd->scsi_done(cmd);
|
||
printk ("scsi%d : found command %ld in Linux issue queue\n",
|
||
host->host_no, me->pid);
|
||
- local_irq_restore(flags);
|
||
+ spin_unlock_irqrestore(host->host_lock, flags);
|
||
run_process_issue_queue();
|
||
- return SCSI_ABORT_SUCCESS;
|
||
+ return SUCCESS;
|
||
}
|
||
|
||
/*
|
||
@@ -5244,13 +5182,13 @@
|
||
cmd->scsi_done(cmd);
|
||
printk ("scsi%d : found finished command %ld in running list\n",
|
||
host->host_no, cmd->pid);
|
||
- local_irq_restore(flags);
|
||
- return SCSI_ABORT_NOT_RUNNING;
|
||
+ spin_unlock_irqrestore(host->host_lock, flags);
|
||
+ return SUCCESS;
|
||
} else {
|
||
printk ("scsi%d : DANGER : command running, can not abort.\n",
|
||
cmd->device->host->host_no);
|
||
- local_irq_restore(flags);
|
||
- return SCSI_ABORT_BUSY;
|
||
+ spin_unlock_irqrestore(host->host_lock, flags);
|
||
+ return FAILED;
|
||
}
|
||
}
|
||
|
||
@@ -5281,21 +5219,20 @@
|
||
*/
|
||
--hostdata->busy[cmd->device->id][cmd->device->lun];
|
||
}
|
||
- local_irq_restore(flags);
|
||
+ spin_unlock_irqrestore(host->host_lock, flags);
|
||
cmd->scsi_done(cmd);
|
||
|
||
/*
|
||
* We need to run process_issue_queue since termination of this command
|
||
* may allow another queued command to execute first?
|
||
*/
|
||
- return SCSI_ABORT_NOT_RUNNING;
|
||
+ return SUCCESS;
|
||
}
|
||
|
||
/*
|
||
- * Function : int NCR53c7xx_reset (Scsi_Cmnd *cmd)
|
||
+ * Function : int NCR53c7xx_reset (struct scsi_cmnd *cmd)
|
||
*
|
||
- * Purpose : perform a hard reset of the SCSI bus and NCR
|
||
- * chip.
|
||
+ * Purpose : perform a hard reset of the SCSI bus.
|
||
*
|
||
* Inputs : cmd - command which caused the SCSI RESET
|
||
*
|
||
@@ -5303,12 +5240,12 @@
|
||
*/
|
||
|
||
int
|
||
-NCR53c7xx_reset (Scsi_Cmnd *cmd, unsigned int reset_flags) {
|
||
+NCR53c7xx_reset (struct scsi_cmnd *cmd) {
|
||
NCR53c7x0_local_declare();
|
||
unsigned long flags;
|
||
int found = 0;
|
||
struct NCR53c7x0_cmd * c;
|
||
- Scsi_Cmnd *tmp;
|
||
+ struct scsi_cmnd *tmp;
|
||
/*
|
||
* When we call scsi_done(), it's going to wake up anything sleeping on the
|
||
* resources which were in use by the aborted commands, and we'll start to
|
||
@@ -5323,19 +5260,19 @@
|
||
* pointer), do our reinitialization, and then call the done function for
|
||
* each command.
|
||
*/
|
||
- Scsi_Cmnd *nuke_list = NULL;
|
||
+ struct scsi_cmnd *nuke_list = NULL;
|
||
struct Scsi_Host *host = cmd->device->host;
|
||
struct NCR53c7x0_hostdata *hostdata =
|
||
(struct NCR53c7x0_hostdata *) host->hostdata[0];
|
||
|
||
NCR53c7x0_local_setup(host);
|
||
- local_irq_save(flags);
|
||
+ spin_lock_irqsave(host->host_lock, flags);
|
||
ncr_halt (host);
|
||
print_lots (host);
|
||
dump_events (host, 30);
|
||
ncr_scsi_reset (host);
|
||
for (tmp = nuke_list = return_outstanding_commands (host, 1 /* free */,
|
||
- 0 /* issue */ ); tmp; tmp = (Scsi_Cmnd *) tmp->SCp.buffer)
|
||
+ 0 /* issue */ ); tmp; tmp = (struct scsi_cmnd *) tmp->SCp.buffer)
|
||
if (tmp == cmd) {
|
||
found = 1;
|
||
break;
|
||
@@ -5358,19 +5295,21 @@
|
||
}
|
||
|
||
NCR53c7x0_driver_init (host);
|
||
+#if 0
|
||
hostdata->soft_reset (host);
|
||
+#endif
|
||
if (hostdata->resets == 0)
|
||
disable(host);
|
||
else if (hostdata->resets != -1)
|
||
--hostdata->resets;
|
||
- local_irq_restore(flags);
|
||
+ spin_unlock_irqrestore(host->host_lock, flags);
|
||
for (; nuke_list; nuke_list = tmp) {
|
||
- tmp = (Scsi_Cmnd *) nuke_list->SCp.buffer;
|
||
+ tmp = (struct scsi_cmnd *) nuke_list->SCp.buffer;
|
||
nuke_list->result = DID_RESET << 16;
|
||
nuke_list->scsi_done (nuke_list);
|
||
}
|
||
- local_irq_restore(flags);
|
||
- return SCSI_RESET_SUCCESS;
|
||
+ spin_unlock_irqrestore(host->host_lock, flags);
|
||
+ return SUCCESS;
|
||
}
|
||
|
||
/*
|
||
@@ -5379,7 +5318,7 @@
|
||
*/
|
||
|
||
/*
|
||
- * Function : int insn_to_offset (Scsi_Cmnd *cmd, u32 *insn)
|
||
+ * Function : int insn_to_offset (struct scsi_cmnd *cmd, u32 *insn)
|
||
*
|
||
* Purpose : convert instructions stored at NCR pointer into data
|
||
* pointer offset.
|
||
@@ -5392,7 +5331,7 @@
|
||
|
||
|
||
static int
|
||
-insn_to_offset (Scsi_Cmnd *cmd, u32 *insn) {
|
||
+insn_to_offset (struct scsi_cmnd *cmd, u32 *insn) {
|
||
struct NCR53c7x0_hostdata *hostdata =
|
||
(struct NCR53c7x0_hostdata *) cmd->device->host->hostdata[0];
|
||
struct NCR53c7x0_cmd *ncmd =
|
||
@@ -5446,7 +5385,7 @@
|
||
|
||
|
||
/*
|
||
- * Function : void print_progress (Scsi_Cmnd *cmd)
|
||
+ * Function : void print_progress (struct scsi_cmnd *cmd)
|
||
*
|
||
* Purpose : print the current location of the saved data pointer
|
||
*
|
||
@@ -5455,7 +5394,7 @@
|
||
*/
|
||
|
||
static void
|
||
-print_progress (Scsi_Cmnd *cmd) {
|
||
+print_progress (struct scsi_cmnd *cmd) {
|
||
NCR53c7x0_local_declare();
|
||
struct NCR53c7x0_cmd *ncmd =
|
||
(struct NCR53c7x0_cmd *) cmd->host_scribble;
|
||
@@ -5513,7 +5452,7 @@
|
||
host->hostdata[0];
|
||
int i, len;
|
||
char *ptr;
|
||
- Scsi_Cmnd *cmd;
|
||
+ struct scsi_cmnd *cmd;
|
||
|
||
if (check_address ((unsigned long) dsa, hostdata->dsa_end -
|
||
hostdata->dsa_start) == -1) {
|
||
@@ -5549,7 +5488,7 @@
|
||
|
||
printk(" + %d : select_indirect = 0x%x\n",
|
||
hostdata->dsa_select, dsa[hostdata->dsa_select / sizeof(u32)]);
|
||
- cmd = (Scsi_Cmnd *) bus_to_virt(dsa[hostdata->dsa_cmnd / sizeof(u32)]);
|
||
+ cmd = (struct scsi_cmnd *) bus_to_virt(dsa[hostdata->dsa_cmnd / sizeof(u32)]);
|
||
printk(" + %d : dsa_cmnd = 0x%x ", hostdata->dsa_cmnd,
|
||
(u32) virt_to_bus(cmd));
|
||
/* XXX Maybe we should access cmd->host_scribble->result here. RGH */
|
||
@@ -5589,16 +5528,16 @@
|
||
u32 *dsa, *next_dsa;
|
||
volatile u32 *ncrcurrent;
|
||
int left;
|
||
- Scsi_Cmnd *cmd, *next_cmd;
|
||
+ struct scsi_cmnd *cmd, *next_cmd;
|
||
unsigned long flags;
|
||
|
||
printk ("scsi%d : issue queue\n", host->host_no);
|
||
|
||
- for (left = host->can_queue, cmd = (Scsi_Cmnd *) hostdata->issue_queue;
|
||
+ for (left = host->can_queue, cmd = (struct scsi_cmnd *) hostdata->issue_queue;
|
||
left >= 0 && cmd;
|
||
cmd = next_cmd) {
|
||
- next_cmd = (Scsi_Cmnd *) cmd->SCp.ptr;
|
||
- local_irq_save(flags);
|
||
+ next_cmd = (struct scsi_cmnd *) cmd->SCp.ptr;
|
||
+ spin_lock_irqsave(host->host_lock, flags);
|
||
if (cmd->host_scribble) {
|
||
if (check_address ((unsigned long) (cmd->host_scribble),
|
||
sizeof (cmd->host_scribble)) == -1)
|
||
@@ -5611,7 +5550,7 @@
|
||
} else
|
||
printk ("scsi%d : scsi pid %ld for target %d lun %d has no NCR53c7x0_cmd\n",
|
||
host->host_no, cmd->pid, cmd->device->id, cmd->device->lun);
|
||
- local_irq_restore(flags);
|
||
+ spin_unlock_irqrestore(host->host_lock, flags);
|
||
}
|
||
|
||
if (left <= 0) {
|
||
@@ -5643,7 +5582,7 @@
|
||
dsa = bus_to_virt (hostdata->reconnect_dsa_head);
|
||
left >= 0 && dsa;
|
||
dsa = next_dsa) {
|
||
- local_irq_save(flags);
|
||
+ spin_lock_irqsave(host->host_lock, flags);
|
||
if (check_address ((unsigned long) dsa, sizeof(dsa)) == -1) {
|
||
printk ("scsi%d: bad DSA pointer 0x%p", host->host_no,
|
||
dsa);
|
||
@@ -5654,7 +5593,7 @@
|
||
next_dsa = bus_to_virt(dsa[hostdata->dsa_next / sizeof(u32)]);
|
||
print_dsa (host, dsa, "");
|
||
}
|
||
- local_irq_restore(flags);
|
||
+ spin_unlock_irqrestore(host->host_lock, flags);
|
||
}
|
||
printk ("scsi%d : end reconnect_dsa_head\n", host->host_no);
|
||
if (left < 0)
|
||
@@ -5744,14 +5683,14 @@
|
||
struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
|
||
host->hostdata[0];
|
||
NCR53c7x0_local_setup(host);
|
||
- local_irq_save(flags);
|
||
+ spin_lock_irqsave(host->host_lock, flags);
|
||
/* Get in a state where we can reset the SCSI bus */
|
||
ncr_halt (host);
|
||
ncr_scsi_reset (host);
|
||
hostdata->soft_reset(host);
|
||
|
||
disable (host);
|
||
- local_irq_restore(flags);
|
||
+ spin_unlock_irqrestore(host->host_lock, flags);
|
||
return 0;
|
||
}
|
||
|
||
@@ -5766,11 +5705,11 @@
|
||
NCR53c7x0_local_declare();
|
||
unsigned long flags;
|
||
NCR53c7x0_local_setup(host);
|
||
- local_irq_save(flags);
|
||
+ spin_lock_irqsave(host->host_lock, flags);
|
||
NCR53c7x0_write8(SCNTL1_REG, SCNTL1_RST);
|
||
udelay(25); /* Minimum amount of time to assert RST */
|
||
NCR53c7x0_write8(SCNTL1_REG, 0);
|
||
- local_irq_restore(flags);
|
||
+ spin_unlock_irqrestore(host->host_lock, flags);
|
||
}
|
||
|
||
/*
|
||
@@ -5783,26 +5722,26 @@
|
||
struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
|
||
host->hostdata[0];
|
||
unsigned long flags;
|
||
- local_irq_save(flags);
|
||
+ spin_lock_irqsave(host->host_lock, flags);
|
||
ncr_scsi_reset(host);
|
||
NCR53c7x0_driver_init (host);
|
||
if (hostdata->soft_reset)
|
||
hostdata->soft_reset (host);
|
||
- local_irq_restore(flags);
|
||
+ spin_unlock_irqrestore(host->host_lock, flags);
|
||
}
|
||
|
||
|
||
/*
|
||
- * Function : Scsi_Cmnd *return_outstanding_commands (struct Scsi_Host *host,
|
||
+ * Function : struct scsi_cmnd *return_outstanding_commands (struct Scsi_Host *host,
|
||
* int free, int issue)
|
||
*
|
||
* Purpose : return a linked list (using the SCp.buffer field as next,
|
||
* so we don't perturb hostdata. We don't use a field of the
|
||
* NCR53c7x0_cmd structure since we may not have allocated one
|
||
- * for the command causing the reset.) of Scsi_Cmnd structures that
|
||
+ * for the command causing the reset.) of scsi_cmnd structures that
|
||
* had propagated below the Linux issue queue level. If free is set,
|
||
* free the NCR53c7x0_cmd structures which are associated with
|
||
- * the Scsi_Cmnd structures, and clean up any internal
|
||
+ * the scsi_cmnd structures, and clean up any internal
|
||
* NCR lists that the commands were on. If issue is set,
|
||
* also return commands in the issue queue.
|
||
*
|
||
@@ -5812,14 +5751,14 @@
|
||
* if the free flag is set.
|
||
*/
|
||
|
||
-static Scsi_Cmnd *
|
||
+static struct scsi_cmnd *
|
||
return_outstanding_commands (struct Scsi_Host *host, int free, int issue) {
|
||
struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
|
||
host->hostdata[0];
|
||
struct NCR53c7x0_cmd *c;
|
||
int i;
|
||
u32 *ncrcurrent;
|
||
- Scsi_Cmnd *list = NULL, *tmp;
|
||
+ struct scsi_cmnd *list = NULL, *tmp, *next_cmd;
|
||
for (c = (struct NCR53c7x0_cmd *) hostdata->running_list; c;
|
||
c = (struct NCR53c7x0_cmd *) c->next) {
|
||
if (c->cmd->SCp.buffer) {
|
||
@@ -5848,7 +5787,9 @@
|
||
}
|
||
|
||
if (issue) {
|
||
- for (tmp = (Scsi_Cmnd *) hostdata->issue_queue; tmp; tmp = tmp->next) {
|
||
+ for (tmp = (struct scsi_cmnd *) hostdata->issue_queue; tmp; tmp = next_cmd) {
|
||
+ next_cmd = (struct scsi_cmnd *) tmp->SCp.ptr;
|
||
+
|
||
if (tmp->SCp.buffer) {
|
||
printk ("scsi%d : loop detected in issue queue!\n",
|
||
host->host_no);
|
||
@@ -5883,17 +5824,17 @@
|
||
struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
|
||
host->hostdata[0];
|
||
unsigned long flags;
|
||
- Scsi_Cmnd *nuke_list, *tmp;
|
||
- local_irq_save(flags);
|
||
+ struct scsi_cmnd *nuke_list, *tmp;
|
||
+ spin_lock_irqsave(host->host_lock, flags);
|
||
if (hostdata->state != STATE_HALTED)
|
||
ncr_halt (host);
|
||
nuke_list = return_outstanding_commands (host, 1 /* free */, 1 /* issue */);
|
||
hard_reset (host);
|
||
hostdata->state = STATE_DISABLED;
|
||
- local_irq_restore(flags);
|
||
+ spin_unlock_irqrestore(host->host_lock, flags);
|
||
printk ("scsi%d : nuking commands\n", host->host_no);
|
||
for (; nuke_list; nuke_list = tmp) {
|
||
- tmp = (Scsi_Cmnd *) nuke_list->SCp.buffer;
|
||
+ tmp = (struct scsi_cmnd *) nuke_list->SCp.buffer;
|
||
nuke_list->result = DID_ERROR << 16;
|
||
nuke_list->scsi_done(nuke_list);
|
||
}
|
||
@@ -5923,7 +5864,7 @@
|
||
int stage;
|
||
NCR53c7x0_local_setup(host);
|
||
|
||
- local_irq_save(flags);
|
||
+ spin_lock_irqsave(host->host_lock, flags);
|
||
/* Stage 0 : eat all interrupts
|
||
Stage 1 : set ABORT
|
||
Stage 2 : eat all but abort interrupts
|
||
@@ -5958,7 +5899,7 @@
|
||
}
|
||
}
|
||
hostdata->state = STATE_HALTED;
|
||
- local_irq_restore(flags);
|
||
+ spin_unlock_irqrestore(host->host_lock, flags);
|
||
#if 0
|
||
print_lots (host);
|
||
#endif
|
||
@@ -6012,7 +5953,7 @@
|
||
* still be guaranteed that they're happening on the same
|
||
* event structure.
|
||
*/
|
||
- local_irq_save(flags);
|
||
+ spin_lock_irqsave(host->host_lock, flags);
|
||
#if 0
|
||
event = hostdata->events[i];
|
||
#else
|
||
@@ -6020,7 +5961,7 @@
|
||
sizeof(event));
|
||
#endif
|
||
|
||
- local_irq_restore(flags);
|
||
+ spin_unlock_irqrestore(host->host_lock, flags);
|
||
printk ("scsi%d : %s event %d at %ld secs %ld usecs target %d lun %d\n",
|
||
host->host_no, event_name (event.event), count,
|
||
(long) event.time.tv_sec, (long) event.time.tv_usec,
|
||
@@ -6055,6 +5996,72 @@
|
||
return (virt_to_phys((void *)addr) < PAGE_SIZE || virt_to_phys((void *)(addr + size)) > virt_to_phys(high_memory) ? -1 : 0);
|
||
}
|
||
|
||
+int
|
||
+NCR53c7xx_slave_configure(struct scsi_device *sdev) {
|
||
+ struct Scsi_Host *host = sdev->host;
|
||
+ struct NCR53c7x0_hostdata *hostdata =
|
||
+ (struct NCR53c7x0_hostdata *) host->hostdata[0];
|
||
+ struct NCR53c7x0_cmd *tmp;
|
||
+ u32 real; /* Real address */
|
||
+ int size; /* Size of *tmp */
|
||
+ unsigned long flags;
|
||
+ int extra_allocate = 0;
|
||
+
|
||
+/*
|
||
+ * Reserve commands for this I_T_L nexus.
|
||
+ */
|
||
+ if (hostdata->num_cmds < host->can_queue)
|
||
+ extra_allocate = host->cmd_per_lun;
|
||
+
|
||
+ for (; extra_allocate > 0 ; --extra_allocate,
|
||
+ ++hostdata->num_cmds) {
|
||
+ /* historically, kmalloc has returned unaligned addresses; pad so we
|
||
+ have enough room to ROUNDUP */
|
||
+ size = hostdata->max_cmd_size + sizeof (void *);
|
||
+#ifdef FORCE_DSA_ALIGNMENT
|
||
+ /*
|
||
+ * 53c710 rev.0 doesn't have an add-with-carry instruction.
|
||
+ * Ensure we allocate enough memory to force alignment.
|
||
+ */
|
||
+ size += 256;
|
||
+#endif
|
||
+/* FIXME: for ISA bus '7xx chips, we need to or GFP_DMA in here */
|
||
+
|
||
+ if (size > 4096) {
|
||
+ printk (KERN_ERR "53c7xx: slave_configure size > 4K\n");
|
||
+ return -ENOMEM;
|
||
+ }
|
||
+ real = get_zeroed_page(GFP_ATOMIC);
|
||
+ if (real == 0)
|
||
+ return -ENOMEM;
|
||
+ memset((void *)real, 0, 4096);
|
||
+ cache_push(virt_to_phys((void *)real), 4096);
|
||
+ cache_clear(virt_to_phys((void *)real), 4096);
|
||
+ kernel_set_cachemode((void *)real, 4096, IOMAP_NOCACHE_SER);
|
||
+ tmp = ROUNDUP(real, void *);
|
||
+#ifdef FORCE_DSA_ALIGNMENT
|
||
+ {
|
||
+ if (((u32)tmp & 0xff) > CmdPageStart)
|
||
+ tmp = (struct NCR53c7x0_cmd *)((u32)tmp + 255);
|
||
+ tmp = (struct NCR53c7x0_cmd *)(((u32)tmp & ~0xff) + CmdPageStart);
|
||
+#if 0
|
||
+ printk ("scsi: size = %d, real = 0x%08x, tmp set to 0x%08x\n",
|
||
+ size, real, (u32)tmp);
|
||
+#endif
|
||
+ }
|
||
+#endif
|
||
+ tmp->real = (void *)real;
|
||
+ tmp->size = size;
|
||
+ tmp->free = ((void (*)(void *, int)) my_free_page);
|
||
+ spin_lock_irqsave(host->host_lock, flags);
|
||
+ tmp->next = hostdata->free;
|
||
+ hostdata->free = tmp;
|
||
+ spin_unlock_irqrestore(host->host_lock, flags);
|
||
+ }
|
||
+
|
||
+ return 0;
|
||
+}
|
||
+
|
||
#ifdef MODULE
|
||
int
|
||
NCR53c7x0_release(struct Scsi_Host *host) {
|
||
@@ -6064,19 +6071,22 @@
|
||
shutdown (host);
|
||
if (host->irq != SCSI_IRQ_NONE)
|
||
{
|
||
- int irq_count;
|
||
- struct Scsi_Host *tmp;
|
||
- for (irq_count = 0, tmp = first_host; tmp; tmp = tmp->next)
|
||
- if (tmp->hostt == the_template && tmp->irq == host->irq)
|
||
+ int irq_count = 0;
|
||
+ struct Scsi_Host *tmp, *s;
|
||
+ list_for_each_entry_safe(tmp, s, &the_template->legacy_hosts, sht_legacy_list) {
|
||
+ if (tmp->irq == host->irq)
|
||
++irq_count;
|
||
+ }
|
||
if (irq_count == 1)
|
||
free_irq(host->irq, NULL);
|
||
}
|
||
+#ifdef CONFIG_ISA
|
||
if (host->dma_channel != DMA_NONE)
|
||
free_dma(host->dma_channel);
|
||
+#endif
|
||
if (host->io_port)
|
||
release_region(host->io_port, host->n_io_port);
|
||
-
|
||
+
|
||
for (cmd = (struct NCR53c7x0_cmd *) hostdata->free; cmd; cmd = tmp,
|
||
--hostdata->num_cmds) {
|
||
tmp = (struct NCR53c7x0_cmd *) cmd->next;
|
||
diff -urN linux-i386/drivers/scsi/53c7xx.h linux-m68k/drivers/scsi/53c7xx.h
|
||
--- linux-i386/drivers/scsi/53c7xx.h 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/drivers/scsi/53c7xx.h 2004-10-30 14:41:36.000000000 +0200
|
||
@@ -997,7 +997,7 @@
|
||
u32 *dsa; /* What's in the DSA register now (virt) */
|
||
/*
|
||
* A few things from that SCSI pid so we know what happened after
|
||
- * the Scsi_Cmnd structure in question may have disappeared.
|
||
+ * the scsi_cmnd structure in question may have disappeared.
|
||
*/
|
||
unsigned long pid; /* The SCSI PID which caused this
|
||
event */
|
||
@@ -1029,8 +1029,8 @@
|
||
void (* free)(void *, int); /* Command to deallocate; NULL
|
||
for structures allocated with
|
||
scsi_register, etc. */
|
||
- Scsi_Cmnd *cmd; /* Associated Scsi_Cmnd
|
||
- structure, Scsi_Cmnd points
|
||
+ struct scsi_cmnd *cmd; /* Associated scsi_cmnd
|
||
+ structure, scsi_cmnd points
|
||
at NCR53c7x0_cmd using
|
||
host_scribble structure */
|
||
|
||
@@ -1039,8 +1039,8 @@
|
||
|
||
int flags; /* CMD_* flags */
|
||
|
||
- unsigned char cmnd[12]; /* CDB, copied from Scsi_Cmnd */
|
||
- int result; /* Copy to Scsi_Cmnd when done */
|
||
+ unsigned char cmnd[12]; /* CDB, copied from scsi_cmnd */
|
||
+ int result; /* Copy to scsi_cmnd when done */
|
||
|
||
struct { /* Private non-cached bounce buffer */
|
||
unsigned char buf[256];
|
||
@@ -1339,7 +1339,7 @@
|
||
volatile struct NCR53c7x0_synchronous sync[16]
|
||
__attribute__ ((aligned (4)));
|
||
|
||
- volatile Scsi_Cmnd *issue_queue
|
||
+ volatile struct scsi_cmnd *issue_queue
|
||
__attribute__ ((aligned (4)));
|
||
/* waiting to be issued by
|
||
Linux driver */
|
||
@@ -1363,10 +1363,6 @@
|
||
*/
|
||
volatile int num_cmds; /* Number of commands
|
||
allocated */
|
||
- volatile int extra_allocate;
|
||
- volatile unsigned char cmd_allocated[16]; /* Have we allocated commands
|
||
- for this target yet? If not,
|
||
- do so ASAP */
|
||
volatile unsigned char busy[16][8]; /* number of commands
|
||
executing on each target
|
||
*/
|
||
@@ -1589,11 +1585,11 @@
|
||
/* Patch field in dsa structure (assignment should be +=?) */
|
||
#define patch_dsa_32(dsa, symbol, word, value) \
|
||
{ \
|
||
- (dsa)[(hostdata->##symbol - hostdata->dsa_start) / sizeof(u32) \
|
||
+ (dsa)[(hostdata->symbol - hostdata->dsa_start) / sizeof(u32) \
|
||
+ (word)] = (value); \
|
||
if (hostdata->options & OPTION_DEBUG_DSA) \
|
||
printk("scsi : dsa %s symbol %s(%d) word %d now 0x%x\n", \
|
||
- #dsa, #symbol, hostdata->##symbol, \
|
||
+ #dsa, #symbol, hostdata->symbol, \
|
||
(word), (u32) (value)); \
|
||
}
|
||
|
||
@@ -1603,6 +1599,12 @@
|
||
extern int ncr53c7xx_init(struct scsi_host_template *tpnt, int board, int chip,
|
||
unsigned long base, int io_port, int irq, int dma,
|
||
long long options, int clock);
|
||
+extern const char *NCR53c7x0_info(void);
|
||
+extern int NCR53c7xx_queue_command(struct scsi_cmnd *, void (*done)(struct scsi_cmnd *));
|
||
+extern int NCR53c7xx_abort(struct scsi_cmnd *);
|
||
+extern int NCR53c7x0_release (struct Scsi_Host *);
|
||
+extern int NCR53c7xx_reset(struct scsi_cmnd *);
|
||
+extern int NCR53c7xx_slave_configure(struct scsi_device *);
|
||
|
||
#endif /* NCR53c710_C */
|
||
#endif /* NCR53c710_H */
|
||
diff -urN linux-i386/drivers/scsi/Kconfig linux-m68k/drivers/scsi/Kconfig
|
||
--- linux-i386/drivers/scsi/Kconfig 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/drivers/scsi/Kconfig 2006-06-18 19:08:56.000000000 +0200
|
||
@@ -1661,7 +1661,7 @@
|
||
|
||
config SCSI_AMIGA7XX
|
||
bool "Amiga NCR53c710 SCSI support (EXPERIMENTAL)"
|
||
- depends on AMIGA && SCSI && EXPERIMENTAL && BROKEN
|
||
+ depends on AMIGA && SCSI && EXPERIMENTAL
|
||
help
|
||
Support for various NCR53c710-based SCSI controllers on the Amiga.
|
||
This includes:
|
||
@@ -1761,7 +1761,7 @@
|
||
|
||
config MVME16x_SCSI
|
||
bool "NCR53C710 SCSI driver for MVME16x"
|
||
- depends on MVME16x && SCSI && BROKEN
|
||
+ depends on MVME16x && SCSI
|
||
select SCSI_SPI_ATTRS
|
||
help
|
||
The Motorola MVME162, 166, 167, 172 and 177 boards use the NCR53C710
|
||
@@ -1770,7 +1770,7 @@
|
||
|
||
config BVME6000_SCSI
|
||
bool "NCR53C710 SCSI driver for BVME6000"
|
||
- depends on BVME6000 && SCSI && BROKEN
|
||
+ depends on BVME6000 && SCSI
|
||
select SCSI_SPI_ATTRS
|
||
help
|
||
The BVME4000 and BVME6000 boards from BVM Ltd use the NCR53C710
|
||
@@ -1787,7 +1787,7 @@
|
||
|
||
config SUN3_SCSI
|
||
tristate "Sun3 NCR5380 SCSI"
|
||
- depends on SUN3 && SCSI && BROKEN
|
||
+ depends on SUN3 && SCSI
|
||
select SCSI_SPI_ATTRS
|
||
help
|
||
This option will enable support for the OBIO (onboard io) NCR5380
|
||
diff -urN linux-i386/drivers/scsi/NCR5380.c linux-m68k/drivers/scsi/NCR5380.c
|
||
--- linux-i386/drivers/scsi/NCR5380.c 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/drivers/scsi/NCR5380.c 2006-04-10 00:23:01.000000000 +0200
|
||
@@ -354,6 +354,7 @@
|
||
return -ETIMEDOUT;
|
||
}
|
||
|
||
+#if NDEBUG
|
||
static struct {
|
||
unsigned char value;
|
||
const char *name;
|
||
@@ -367,7 +368,6 @@
|
||
{PHASE_UNKNOWN, "UNKNOWN"}
|
||
};
|
||
|
||
-#if NDEBUG
|
||
static struct {
|
||
unsigned char mask;
|
||
const char *name;
|
||
diff -urN linux-i386/drivers/scsi/amiga7xx.c linux-m68k/drivers/scsi/amiga7xx.c
|
||
--- linux-i386/drivers/scsi/amiga7xx.c 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/drivers/scsi/amiga7xx.c 2006-01-15 02:01:20.000000000 +0100
|
||
@@ -26,8 +26,14 @@
|
||
#include "scsi.h"
|
||
#include <scsi/scsi_host.h>
|
||
#include "53c7xx.h"
|
||
-#include "amiga7xx.h"
|
||
|
||
+#ifndef CMD_PER_LUN
|
||
+#define CMD_PER_LUN 3
|
||
+#endif
|
||
+
|
||
+#ifndef CAN_QUEUE
|
||
+#define CAN_QUEUE 24
|
||
+#endif
|
||
|
||
static int amiga7xx_register_one(struct scsi_host_template *tpnt,
|
||
unsigned long address)
|
||
@@ -114,8 +120,10 @@
|
||
{
|
||
if (shost->irq)
|
||
free_irq(shost->irq, NULL);
|
||
+#ifdef CONFIG_ISA
|
||
if (shost->dma_channel != 0xff)
|
||
free_dma(shost->dma_channel);
|
||
+#endif
|
||
if (shost->io_port && shost->n_io_port)
|
||
release_region(shost->io_port, shost->n_io_port);
|
||
scsi_unregister(shost);
|
||
@@ -127,8 +135,9 @@
|
||
.detect = amiga7xx_detect,
|
||
.release = amiga7xx_release,
|
||
.queuecommand = NCR53c7xx_queue_command,
|
||
- .abort = NCR53c7xx_abort,
|
||
- .reset = NCR53c7xx_reset,
|
||
+ .eh_abort_handler = NCR53c7xx_abort,
|
||
+ .eh_bus_reset_handler = NCR53c7xx_reset,
|
||
+ .slave_configure = NCR53c7xx_slave_configure,
|
||
.can_queue = 24,
|
||
.this_id = 7,
|
||
.sg_tablesize = 63,
|
||
diff -urN linux-i386/drivers/scsi/amiga7xx.h linux-m68k/drivers/scsi/amiga7xx.h
|
||
--- linux-i386/drivers/scsi/amiga7xx.h 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/drivers/scsi/amiga7xx.h 1970-01-01 01:00:00.000000000 +0100
|
||
@@ -1,23 +0,0 @@
|
||
-#ifndef AMIGA7XX_H
|
||
-
|
||
-#include <linux/types.h>
|
||
-
|
||
-int amiga7xx_detect(struct scsi_host_template *);
|
||
-const char *NCR53c7x0_info(void);
|
||
-int NCR53c7xx_queue_command(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
|
||
-int NCR53c7xx_abort(Scsi_Cmnd *);
|
||
-int NCR53c7x0_release (struct Scsi_Host *);
|
||
-int NCR53c7xx_reset(Scsi_Cmnd *, unsigned int);
|
||
-void NCR53c7x0_intr(int irq, void *dev_id, struct pt_regs * regs);
|
||
-
|
||
-#ifndef CMD_PER_LUN
|
||
-#define CMD_PER_LUN 3
|
||
-#endif
|
||
-
|
||
-#ifndef CAN_QUEUE
|
||
-#define CAN_QUEUE 24
|
||
-#endif
|
||
-
|
||
-#include <scsi/scsicam.h>
|
||
-
|
||
-#endif /* AMIGA7XX_H */
|
||
diff -urN linux-i386/drivers/scsi/bvme6000.c linux-m68k/drivers/scsi/bvme6000.c
|
||
--- linux-i386/drivers/scsi/bvme6000.c 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/drivers/scsi/bvme6000.c 2006-01-15 02:01:21.000000000 +0100
|
||
@@ -18,10 +18,16 @@
|
||
#include "scsi.h"
|
||
#include <scsi/scsi_host.h>
|
||
#include "53c7xx.h"
|
||
-#include "bvme6000.h"
|
||
|
||
#include<linux/stat.h>
|
||
|
||
+#ifndef CMD_PER_LUN
|
||
+#define CMD_PER_LUN 3
|
||
+#endif
|
||
+
|
||
+#ifndef CAN_QUEUE
|
||
+#define CAN_QUEUE 24
|
||
+#endif
|
||
|
||
int bvme6000_scsi_detect(struct scsi_host_template *tpnt)
|
||
{
|
||
@@ -51,8 +57,10 @@
|
||
{
|
||
if (shost->irq)
|
||
free_irq(shost->irq, NULL);
|
||
+#ifdef CONFIG_ISA
|
||
if (shost->dma_channel != 0xff)
|
||
free_dma(shost->dma_channel);
|
||
+#endif
|
||
if (shost->io_port && shost->n_io_port)
|
||
release_region(shost->io_port, shost->n_io_port);
|
||
scsi_unregister(shost);
|
||
@@ -64,8 +72,9 @@
|
||
.detect = bvme6000_scsi_detect,
|
||
.release = bvme6000_scsi_release,
|
||
.queuecommand = NCR53c7xx_queue_command,
|
||
- .abort = NCR53c7xx_abort,
|
||
- .reset = NCR53c7xx_reset,
|
||
+ .eh_abort_handler = NCR53c7xx_abort,
|
||
+ .eh_bus_reset_handler = NCR53c7xx_reset,
|
||
+ .slave_configure = NCR53c7xx_slave_configure,
|
||
.can_queue = 24,
|
||
.this_id = 7,
|
||
.sg_tablesize = 63,
|
||
diff -urN linux-i386/drivers/scsi/bvme6000.h linux-m68k/drivers/scsi/bvme6000.h
|
||
--- linux-i386/drivers/scsi/bvme6000.h 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/drivers/scsi/bvme6000.h 1970-01-01 01:00:00.000000000 +0100
|
||
@@ -1,24 +0,0 @@
|
||
-#ifndef BVME6000_SCSI_H
|
||
-#define BVME6000_SCSI_H
|
||
-
|
||
-#include <linux/types.h>
|
||
-
|
||
-int bvme6000_scsi_detect(struct scsi_host_template *);
|
||
-const char *NCR53c7x0_info(void);
|
||
-int NCR53c7xx_queue_command(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
|
||
-int NCR53c7xx_abort(Scsi_Cmnd *);
|
||
-int NCR53c7x0_release (struct Scsi_Host *);
|
||
-int NCR53c7xx_reset(Scsi_Cmnd *, unsigned int);
|
||
-void NCR53c7x0_intr(int irq, void *dev_id, struct pt_regs * regs);
|
||
-
|
||
-#ifndef CMD_PER_LUN
|
||
-#define CMD_PER_LUN 3
|
||
-#endif
|
||
-
|
||
-#ifndef CAN_QUEUE
|
||
-#define CAN_QUEUE 24
|
||
-#endif
|
||
-
|
||
-#include <scsi/scsicam.h>
|
||
-
|
||
-#endif /* BVME6000_SCSI_H */
|
||
diff -urN linux-i386/drivers/scsi/mac_esp.c linux-m68k/drivers/scsi/mac_esp.c
|
||
--- linux-i386/drivers/scsi/mac_esp.c 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/drivers/scsi/mac_esp.c 2006-01-31 01:55:58.000000000 +0100
|
||
@@ -43,9 +43,6 @@
|
||
|
||
/* #define DEBUG_MAC_ESP */
|
||
|
||
-#define mac_turnon_irq(x) mac_enable_irq(x)
|
||
-#define mac_turnoff_irq(x) mac_disable_irq(x)
|
||
-
|
||
extern void esp_handle(struct NCR_ESP *esp);
|
||
extern void mac_esp_intr(int irq, void *dev_id, struct pt_regs *pregs);
|
||
|
||
@@ -639,13 +636,13 @@
|
||
|
||
static void dma_ints_off(struct NCR_ESP * esp)
|
||
{
|
||
- mac_turnoff_irq(esp->irq);
|
||
+ disable_irq(esp->irq);
|
||
}
|
||
|
||
|
||
static void dma_ints_on(struct NCR_ESP * esp)
|
||
{
|
||
- mac_turnon_irq(esp->irq);
|
||
+ enable_irq(esp->irq);
|
||
}
|
||
|
||
/*
|
||
diff -urN linux-i386/drivers/scsi/mac_scsi.c linux-m68k/drivers/scsi/mac_scsi.c
|
||
--- linux-i386/drivers/scsi/mac_scsi.c 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/drivers/scsi/mac_scsi.c 2006-01-31 01:55:58.000000000 +0100
|
||
@@ -65,9 +65,6 @@
|
||
#define RESET_BOOT
|
||
#define DRIVER_SETUP
|
||
|
||
-#define ENABLE_IRQ() mac_enable_irq( IRQ_MAC_SCSI );
|
||
-#define DISABLE_IRQ() mac_disable_irq( IRQ_MAC_SCSI );
|
||
-
|
||
extern void via_scsi_clear(void);
|
||
|
||
#ifdef RESET_BOOT
|
||
@@ -351,7 +348,7 @@
|
||
printk(KERN_INFO "Macintosh SCSI: resetting the SCSI bus..." );
|
||
|
||
/* switch off SCSI IRQ - catch an interrupt without IRQ bit set else */
|
||
- mac_disable_irq(IRQ_MAC_SCSI);
|
||
+ disable_irq(IRQ_MAC_SCSI);
|
||
|
||
/* get in phase */
|
||
NCR5380_write( TARGET_COMMAND_REG,
|
||
@@ -369,7 +366,7 @@
|
||
barrier();
|
||
|
||
/* switch on SCSI IRQ again */
|
||
- mac_enable_irq(IRQ_MAC_SCSI);
|
||
+ enable_irq(IRQ_MAC_SCSI);
|
||
|
||
printk(KERN_INFO " done\n" );
|
||
}
|
||
diff -urN linux-i386/drivers/scsi/mvme16x.c linux-m68k/drivers/scsi/mvme16x.c
|
||
--- linux-i386/drivers/scsi/mvme16x.c 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/drivers/scsi/mvme16x.c 2006-01-15 02:01:22.000000000 +0100
|
||
@@ -16,10 +16,16 @@
|
||
#include "scsi.h"
|
||
#include <scsi/scsi_host.h>
|
||
#include "53c7xx.h"
|
||
-#include "mvme16x.h"
|
||
|
||
#include<linux/stat.h>
|
||
|
||
+#ifndef CMD_PER_LUN
|
||
+#define CMD_PER_LUN 3
|
||
+#endif
|
||
+
|
||
+#ifndef CAN_QUEUE
|
||
+#define CAN_QUEUE 24
|
||
+#endif
|
||
|
||
int mvme16x_scsi_detect(struct scsi_host_template *tpnt)
|
||
{
|
||
@@ -53,8 +59,10 @@
|
||
{
|
||
if (shost->irq)
|
||
free_irq(shost->irq, NULL);
|
||
+#ifdef CONFIG_ISA
|
||
if (shost->dma_channel != 0xff)
|
||
free_dma(shost->dma_channel);
|
||
+#endif
|
||
if (shost->io_port && shost->n_io_port)
|
||
release_region(shost->io_port, shost->n_io_port);
|
||
scsi_unregister(shost);
|
||
@@ -66,8 +74,9 @@
|
||
.detect = mvme16x_scsi_detect,
|
||
.release = mvme16x_scsi_release,
|
||
.queuecommand = NCR53c7xx_queue_command,
|
||
- .abort = NCR53c7xx_abort,
|
||
- .reset = NCR53c7xx_reset,
|
||
+ .eh_abort_handler = NCR53c7xx_abort,
|
||
+ .eh_bus_reset_handler = NCR53c7xx_reset,
|
||
+ .slave_configure = NCR53c7xx_slave_configure,
|
||
.can_queue = 24,
|
||
.this_id = 7,
|
||
.sg_tablesize = 63,
|
||
diff -urN linux-i386/drivers/scsi/mvme16x.h linux-m68k/drivers/scsi/mvme16x.h
|
||
--- linux-i386/drivers/scsi/mvme16x.h 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/drivers/scsi/mvme16x.h 1970-01-01 01:00:00.000000000 +0100
|
||
@@ -1,24 +0,0 @@
|
||
-#ifndef MVME16x_SCSI_H
|
||
-#define MVME16x_SCSI_H
|
||
-
|
||
-#include <linux/types.h>
|
||
-
|
||
-int mvme16x_scsi_detect(struct scsi_host_template *);
|
||
-const char *NCR53c7x0_info(void);
|
||
-int NCR53c7xx_queue_command(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
|
||
-int NCR53c7xx_abort(Scsi_Cmnd *);
|
||
-int NCR53c7x0_release (struct Scsi_Host *);
|
||
-int NCR53c7xx_reset(Scsi_Cmnd *, unsigned int);
|
||
-void NCR53c7x0_intr(int irq, void *dev_id, struct pt_regs * regs);
|
||
-
|
||
-#ifndef CMD_PER_LUN
|
||
-#define CMD_PER_LUN 3
|
||
-#endif
|
||
-
|
||
-#ifndef CAN_QUEUE
|
||
-#define CAN_QUEUE 24
|
||
-#endif
|
||
-
|
||
-#include <scsi/scsicam.h>
|
||
-
|
||
-#endif /* MVME16x_SCSI_H */
|
||
diff -urN linux-i386/drivers/scsi/sun3_NCR5380.c linux-m68k/drivers/scsi/sun3_NCR5380.c
|
||
--- linux-i386/drivers/scsi/sun3_NCR5380.c 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/drivers/scsi/sun3_NCR5380.c 2006-05-11 13:16:27.000000000 +0200
|
||
@@ -1269,7 +1269,7 @@
|
||
NCR_PRINT(NDEBUG_INTR);
|
||
if ((NCR5380_read(STATUS_REG) & (SR_SEL|SR_IO)) == (SR_SEL|SR_IO)) {
|
||
done = 0;
|
||
- ENABLE_IRQ();
|
||
+// ENABLE_IRQ();
|
||
INT_PRINTK("scsi%d: SEL interrupt\n", HOSTNO);
|
||
NCR5380_reselect(instance);
|
||
(void) NCR5380_read(RESET_PARITY_INTERRUPT_REG);
|
||
@@ -1302,7 +1302,7 @@
|
||
INT_PRINTK("scsi%d: PHASE MISM or EOP interrupt\n", HOSTNO);
|
||
NCR5380_dma_complete( instance );
|
||
done = 0;
|
||
- ENABLE_IRQ();
|
||
+// ENABLE_IRQ();
|
||
} else
|
||
#endif /* REAL_DMA */
|
||
{
|
||
diff -urN linux-i386/drivers/scsi/sun3_scsi.c linux-m68k/drivers/scsi/sun3_scsi.c
|
||
--- linux-i386/drivers/scsi/sun3_scsi.c 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/drivers/scsi/sun3_scsi.c 2006-05-11 13:16:27.000000000 +0200
|
||
@@ -75,9 +75,9 @@
|
||
#define REAL_DMA
|
||
|
||
#include "scsi.h"
|
||
+#include "initio.h"
|
||
#include <scsi/scsi_host.h>
|
||
#include "sun3_scsi.h"
|
||
-#include "NCR5380.h"
|
||
|
||
static void NCR5380_print(struct Scsi_Host *instance);
|
||
|
||
diff -urN linux-i386/drivers/scsi/sun3_scsi.h linux-m68k/drivers/scsi/sun3_scsi.h
|
||
--- linux-i386/drivers/scsi/sun3_scsi.h 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/drivers/scsi/sun3_scsi.h 2006-05-11 13:16:27.000000000 +0200
|
||
@@ -220,7 +220,7 @@
|
||
*
|
||
*/
|
||
|
||
-
|
||
+#include "NCR5380.h"
|
||
|
||
#if NDEBUG & NDEBUG_ARBITRATION
|
||
#define ARB_PRINTK(format, args...) \
|
||
diff -urN linux-i386/drivers/scsi/sun3_scsi_vme.c linux-m68k/drivers/scsi/sun3_scsi_vme.c
|
||
--- linux-i386/drivers/scsi/sun3_scsi_vme.c 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/drivers/scsi/sun3_scsi_vme.c 2006-05-11 13:16:27.000000000 +0200
|
||
@@ -41,9 +41,9 @@
|
||
#define REAL_DMA
|
||
|
||
#include "scsi.h"
|
||
+#include "initio.h"
|
||
#include <scsi/scsi_host.h>
|
||
#include "sun3_scsi.h"
|
||
-#include "NCR5380.h"
|
||
|
||
extern int sun3_map_test(unsigned long, char *);
|
||
|
||
diff -urN linux-i386/drivers/scsi/sun3x_esp.c linux-m68k/drivers/scsi/sun3x_esp.c
|
||
--- linux-i386/drivers/scsi/sun3x_esp.c 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/drivers/scsi/sun3x_esp.c 2006-06-06 01:18:32.000000000 +0200
|
||
@@ -332,11 +332,11 @@
|
||
struct scatterlist *sg = sp->SCp.buffer;
|
||
|
||
while (sz >= 0) {
|
||
- sg[sz].dvma_address = dvma_map((unsigned long)page_address(sg[sz].page) +
|
||
+ sg[sz].dma_address = dvma_map((unsigned long)page_address(sg[sz].page) +
|
||
sg[sz].offset, sg[sz].length);
|
||
sz--;
|
||
}
|
||
- sp->SCp.ptr=(char *)((unsigned long)sp->SCp.buffer->dvma_address);
|
||
+ sp->SCp.ptr=(char *)((unsigned long)sp->SCp.buffer->dma_address);
|
||
}
|
||
|
||
static void dma_mmu_release_scsi_one (struct NCR_ESP *esp, Scsi_Cmnd *sp)
|
||
@@ -350,14 +350,14 @@
|
||
struct scatterlist *sg = (struct scatterlist *)sp->buffer;
|
||
|
||
while(sz >= 0) {
|
||
- dvma_unmap((char *)sg[sz].dvma_address);
|
||
+ dvma_unmap((char *)sg[sz].dma_address);
|
||
sz--;
|
||
}
|
||
}
|
||
|
||
static void dma_advance_sg (Scsi_Cmnd *sp)
|
||
{
|
||
- sp->SCp.ptr = (char *)((unsigned long)sp->SCp.buffer->dvma_address);
|
||
+ sp->SCp.ptr = (char *)((unsigned long)sp->SCp.buffer->dma_address);
|
||
}
|
||
|
||
static int sun3x_esp_release(struct Scsi_Host *instance)
|
||
diff -urN linux-i386/drivers/scsi/wd33c93.c linux-m68k/drivers/scsi/wd33c93.c
|
||
--- linux-i386/drivers/scsi/wd33c93.c 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/drivers/scsi/wd33c93.c 2006-06-18 19:09:00.000000000 +0200
|
||
@@ -939,6 +939,7 @@
|
||
DB(DB_INTR, printk("%02x", cmd->SCp.Status))
|
||
if (hostdata->level2 >= L2_BASIC) {
|
||
sr = read_wd33c93(regs, WD_SCSI_STATUS); /* clear interrupt */
|
||
+ udelay(7);
|
||
hostdata->state = S_RUNNING_LEVEL2;
|
||
write_wd33c93(regs, WD_COMMAND_PHASE, 0x50);
|
||
write_wd33c93_cmd(regs, WD_CMD_SEL_ATN_XFER);
|
||
@@ -955,6 +956,7 @@
|
||
|
||
msg = read_1_byte(regs);
|
||
sr = read_wd33c93(regs, WD_SCSI_STATUS); /* clear interrupt */
|
||
+ udelay(7);
|
||
|
||
hostdata->incoming_msg[hostdata->incoming_ptr] = msg;
|
||
if (hostdata->incoming_msg[0] == EXTENDED_MESSAGE)
|
||
@@ -1358,6 +1360,7 @@
|
||
} else {
|
||
/* Verify this is a change to MSG_IN and read the message */
|
||
sr = read_wd33c93(regs, WD_SCSI_STATUS);
|
||
+ udelay(7);
|
||
if (sr == (CSR_ABORT | PHS_MESS_IN) ||
|
||
sr == (CSR_UNEXP | PHS_MESS_IN) ||
|
||
sr == (CSR_SRV_REQ | PHS_MESS_IN)) {
|
||
@@ -1374,6 +1377,7 @@
|
||
asr);
|
||
}
|
||
sr = read_wd33c93(regs, WD_SCSI_STATUS);
|
||
+ udelay(7);
|
||
if (sr != CSR_MSGIN)
|
||
printk
|
||
("wd33c93: Not paused with ACK on RESEL (%02x)\n",
|
||
diff -urN linux-i386/drivers/video/aty/atyfb_base.c linux-m68k/drivers/video/aty/atyfb_base.c
|
||
--- linux-i386/drivers/video/aty/atyfb_base.c 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/drivers/video/aty/atyfb_base.c 2006-06-18 19:09:36.000000000 +0200
|
||
@@ -3722,7 +3722,9 @@
|
||
atyfb_setup(option);
|
||
#endif
|
||
|
||
+#ifdef CONFIG_PCI
|
||
pci_register_driver(&atyfb_driver);
|
||
+#endif
|
||
#ifdef CONFIG_ATARI
|
||
atyfb_atari_probe();
|
||
#endif
|
||
@@ -3731,7 +3733,9 @@
|
||
|
||
static void __exit atyfb_exit(void)
|
||
{
|
||
+#ifdef CONFIG_PCI
|
||
pci_unregister_driver(&atyfb_driver);
|
||
+#endif
|
||
}
|
||
|
||
module_init(atyfb_init);
|
||
diff -urN linux-i386/fs/fat/inode.c linux-m68k/fs/fat/inode.c
|
||
--- linux-i386/fs/fat/inode.c 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/fs/fat/inode.c 2006-06-18 19:09:42.000000000 +0200
|
||
@@ -11,12 +11,14 @@
|
||
*/
|
||
|
||
#include <linux/module.h>
|
||
+#include <linux/config.h>
|
||
#include <linux/init.h>
|
||
#include <linux/time.h>
|
||
#include <linux/slab.h>
|
||
#include <linux/smp_lock.h>
|
||
#include <linux/seq_file.h>
|
||
#include <linux/msdos_fs.h>
|
||
+#include <linux/major.h>
|
||
#include <linux/pagemap.h>
|
||
#include <linux/mpage.h>
|
||
#include <linux/buffer_head.h>
|
||
@@ -857,7 +859,7 @@
|
||
Opt_check_n, Opt_check_r, Opt_check_s, Opt_uid, Opt_gid,
|
||
Opt_umask, Opt_dmask, Opt_fmask, Opt_codepage, Opt_nocase,
|
||
Opt_quiet, Opt_showexec, Opt_debug, Opt_immutable,
|
||
- Opt_dots, Opt_nodots,
|
||
+ Opt_dots, Opt_nodots, Opt_atari_no, Opt_atari_yes,
|
||
Opt_charset, Opt_shortname_lower, Opt_shortname_win95,
|
||
Opt_shortname_winnt, Opt_shortname_mixed, Opt_utf8_no, Opt_utf8_yes,
|
||
Opt_uni_xl_no, Opt_uni_xl_yes, Opt_nonumtail_no, Opt_nonumtail_yes,
|
||
@@ -882,6 +884,9 @@
|
||
{Opt_showexec, "showexec"},
|
||
{Opt_debug, "debug"},
|
||
{Opt_immutable, "sys_immutable"},
|
||
+ {Opt_atari_yes, "atari=yes"},
|
||
+ {Opt_atari_yes, "atari"},
|
||
+ {Opt_atari_no, "atari=no"},
|
||
{Opt_obsolate, "conv=binary"},
|
||
{Opt_obsolate, "conv=text"},
|
||
{Opt_obsolate, "conv=auto"},
|
||
@@ -956,6 +961,13 @@
|
||
opts->utf8 = opts->unicode_xlate = 0;
|
||
opts->numtail = 1;
|
||
opts->nocase = 0;
|
||
+ opts->atari = 0;
|
||
+
|
||
+#ifdef CONFIG_ATARI
|
||
+ if(MACH_IS_ATARI)
|
||
+ /* make Atari GEMDOS format the default if machine is an Atari */
|
||
+ opts->atari = 1;
|
||
+#endif
|
||
*debug = 0;
|
||
|
||
if (!options)
|
||
@@ -1004,6 +1016,12 @@
|
||
case Opt_immutable:
|
||
opts->sys_immutable = 1;
|
||
break;
|
||
+ case Opt_atari_yes:
|
||
+ opts->atari = 1;
|
||
+ break;
|
||
+ case Opt_atari_no:
|
||
+ opts->atari = 0;
|
||
+ break;
|
||
case Opt_uid:
|
||
if (match_int(&args[0], &option))
|
||
return 0;
|
||
@@ -1339,8 +1357,31 @@
|
||
|
||
total_clusters = (total_sectors - sbi->data_start) / sbi->sec_per_clus;
|
||
|
||
- if (sbi->fat_bits != 32)
|
||
- sbi->fat_bits = (total_clusters > MAX_FAT12) ? 16 : 12;
|
||
+ if (!sbi->options.atari) {
|
||
+ if (sbi->fat_bits != 32)
|
||
+ sbi->fat_bits = (total_clusters > MAX_FAT12) ? 16 : 12;
|
||
+ } else {
|
||
+ int sectors;
|
||
+ /* Atari GEMDOS partitions always have 16-bit fat */
|
||
+ if (sbi->fat_bits != 32)
|
||
+ sbi->fat_bits = 16;
|
||
+ /* If more clusters than fat entries in 16-bit fat, we assume
|
||
+ * it's a real MSDOS partition with 12-bit fat.
|
||
+ */
|
||
+ if (sbi->fat_bits != 32 && total_clusters+2 > sbi->
|
||
+ fat_length*SECTOR_SIZE*8/sbi->fat_bits)
|
||
+ sbi->fat_bits = 12;
|
||
+ /* if it's a floppy disk --> 12bit fat */
|
||
+ if (sbi->fat_bits != 32 && MAJOR(sb->s_dev) == FLOPPY_MAJOR)
|
||
+ sbi->fat_bits = 12;
|
||
+ /* if it's a ramdisk or loopback device and has one of the usual
|
||
+ * floppy sizes -> 12bit FAT */
|
||
+ sectors = total_sectors + sbi->data_start;
|
||
+ if (sbi->fat_bits != 32 && (MAJOR(sb->s_dev) == RAMDISK_MAJOR ||
|
||
+ MAJOR(sb->s_dev) == LOOP_MAJOR) &&
|
||
+ (sectors == 720 || sectors == 1440 || sectors == 2880))
|
||
+ sbi->fat_bits = 12;
|
||
+ }
|
||
|
||
/* check that FAT table does not overflow */
|
||
fat_clusters = sbi->fat_length * sb->s_blocksize * 8 / sbi->fat_bits;
|
||
diff -urN linux-i386/include/asm-m68k/amigaints.h linux-m68k/include/asm-m68k/amigaints.h
|
||
--- linux-i386/include/asm-m68k/amigaints.h 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/include/asm-m68k/amigaints.h 2006-01-28 22:32:49.000000000 +0100
|
||
@@ -13,6 +13,8 @@
|
||
#ifndef _ASMm68k_AMIGAINTS_H_
|
||
#define _ASMm68k_AMIGAINTS_H_
|
||
|
||
+#include <asm/irq.h>
|
||
+
|
||
/*
|
||
** Amiga Interrupt sources.
|
||
**
|
||
@@ -23,72 +25,52 @@
|
||
#define CIA_IRQS (5)
|
||
#define AMI_IRQS (32) /* AUTO_IRQS+AMI_STD_IRQS+2*CIA_IRQS */
|
||
|
||
-/* vertical blanking interrupt */
|
||
-#define IRQ_AMIGA_VERTB 0
|
||
+/* builtin serial port interrupts */
|
||
+#define IRQ_AMIGA_TBE (IRQ_USER+0)
|
||
+#define IRQ_AMIGA_RBF (IRQ_USER+11)
|
||
|
||
-/* copper interrupt */
|
||
-#define IRQ_AMIGA_COPPER 1
|
||
+/* floppy disk interrupts */
|
||
+#define IRQ_AMIGA_DSKBLK (IRQ_USER+1)
|
||
+#define IRQ_AMIGA_DSKSYN (IRQ_USER+12)
|
||
|
||
-/* Audio interrupts */
|
||
-#define IRQ_AMIGA_AUD0 2
|
||
-#define IRQ_AMIGA_AUD1 3
|
||
-#define IRQ_AMIGA_AUD2 4
|
||
-#define IRQ_AMIGA_AUD3 5
|
||
+/* software interrupts */
|
||
+#define IRQ_AMIGA_SOFT (IRQ_USER+2)
|
||
|
||
-/* Blitter done interrupt */
|
||
-#define IRQ_AMIGA_BLIT 6
|
||
+/* interrupts from external hardware */
|
||
+#define IRQ_AMIGA_PORTS IRQ_AUTO_2
|
||
+#define IRQ_AMIGA_EXTER IRQ_AUTO_6
|
||
|
||
-/* floppy disk interrupts */
|
||
-#define IRQ_AMIGA_DSKSYN 7
|
||
-#define IRQ_AMIGA_DSKBLK 8
|
||
+/* copper interrupt */
|
||
+#define IRQ_AMIGA_COPPER (IRQ_USER+4)
|
||
|
||
-/* builtin serial port interrupts */
|
||
-#define IRQ_AMIGA_RBF 9
|
||
-#define IRQ_AMIGA_TBE 10
|
||
+/* vertical blanking interrupt */
|
||
+#define IRQ_AMIGA_VERTB (IRQ_USER+5)
|
||
|
||
-/* software interrupts */
|
||
-#define IRQ_AMIGA_SOFT 11
|
||
+/* Blitter done interrupt */
|
||
+#define IRQ_AMIGA_BLIT (IRQ_USER+6)
|
||
|
||
-/* interrupts from external hardware */
|
||
-#define IRQ_AMIGA_PORTS 12
|
||
-#define IRQ_AMIGA_EXTER 13
|
||
+/* Audio interrupts */
|
||
+#define IRQ_AMIGA_AUD0 (IRQ_USER+7)
|
||
+#define IRQ_AMIGA_AUD1 (IRQ_USER+8)
|
||
+#define IRQ_AMIGA_AUD2 (IRQ_USER+9)
|
||
+#define IRQ_AMIGA_AUD3 (IRQ_USER+10)
|
||
|
||
/* CIA interrupt sources */
|
||
-#define IRQ_AMIGA_CIAA 14
|
||
-#define IRQ_AMIGA_CIAA_TA 14
|
||
-#define IRQ_AMIGA_CIAA_TB 15
|
||
-#define IRQ_AMIGA_CIAA_ALRM 16
|
||
-#define IRQ_AMIGA_CIAA_SP 17
|
||
-#define IRQ_AMIGA_CIAA_FLG 18
|
||
-#define IRQ_AMIGA_CIAB 19
|
||
-#define IRQ_AMIGA_CIAB_TA 19
|
||
-#define IRQ_AMIGA_CIAB_TB 20
|
||
-#define IRQ_AMIGA_CIAB_ALRM 21
|
||
-#define IRQ_AMIGA_CIAB_SP 22
|
||
-#define IRQ_AMIGA_CIAB_FLG 23
|
||
-
|
||
-/* auto-vector interrupts */
|
||
-#define IRQ_AMIGA_AUTO 24
|
||
-#define IRQ_AMIGA_AUTO_0 24 /* This is just a dummy */
|
||
-#define IRQ_AMIGA_AUTO_1 25
|
||
-#define IRQ_AMIGA_AUTO_2 26
|
||
-#define IRQ_AMIGA_AUTO_3 27
|
||
-#define IRQ_AMIGA_AUTO_4 28
|
||
-#define IRQ_AMIGA_AUTO_5 29
|
||
-#define IRQ_AMIGA_AUTO_6 30
|
||
-#define IRQ_AMIGA_AUTO_7 31
|
||
+#define IRQ_AMIGA_CIAA (IRQ_USER+14)
|
||
+#define IRQ_AMIGA_CIAA_TA (IRQ_USER+14)
|
||
+#define IRQ_AMIGA_CIAA_TB (IRQ_USER+15)
|
||
+#define IRQ_AMIGA_CIAA_ALRM (IRQ_USER+16)
|
||
+#define IRQ_AMIGA_CIAA_SP (IRQ_USER+17)
|
||
+#define IRQ_AMIGA_CIAA_FLG (IRQ_USER+18)
|
||
+#define IRQ_AMIGA_CIAB (IRQ_USER+19)
|
||
+#define IRQ_AMIGA_CIAB_TA (IRQ_USER+19)
|
||
+#define IRQ_AMIGA_CIAB_TB (IRQ_USER+20)
|
||
+#define IRQ_AMIGA_CIAB_ALRM (IRQ_USER+21)
|
||
+#define IRQ_AMIGA_CIAB_SP (IRQ_USER+22)
|
||
+#define IRQ_AMIGA_CIAB_FLG (IRQ_USER+23)
|
||
|
||
-#define IRQ_FLOPPY IRQ_AMIGA_DSKBLK
|
||
|
||
/* INTREQR masks */
|
||
-#define IRQ1_MASK 0x0007 /* INTREQR mask for IRQ 1 */
|
||
-#define IRQ2_MASK 0x0008 /* INTREQR mask for IRQ 2 */
|
||
-#define IRQ3_MASK 0x0070 /* INTREQR mask for IRQ 3 */
|
||
-#define IRQ4_MASK 0x0780 /* INTREQR mask for IRQ 4 */
|
||
-#define IRQ5_MASK 0x1800 /* INTREQR mask for IRQ 5 */
|
||
-#define IRQ6_MASK 0x2000 /* INTREQR mask for IRQ 6 */
|
||
-#define IRQ7_MASK 0x4000 /* INTREQR mask for IRQ 7 */
|
||
-
|
||
#define IF_SETCLR 0x8000 /* set/clr bit */
|
||
#define IF_INTEN 0x4000 /* master interrupt bit in INT* registers */
|
||
#define IF_EXTER 0x2000 /* external level 6 and CIA B interrupt */
|
||
@@ -106,9 +88,6 @@
|
||
#define IF_DSKBLK 0x0002 /* diskblock DMA finished */
|
||
#define IF_TBE 0x0001 /* serial transmit buffer empty interrupt */
|
||
|
||
-extern void amiga_do_irq(int irq, struct pt_regs *fp);
|
||
-extern void amiga_do_irq_list(int irq, struct pt_regs *fp);
|
||
-
|
||
/* CIA interrupt control register bits */
|
||
|
||
#define CIA_ICR_TA 0x01
|
||
@@ -125,6 +104,7 @@
|
||
|
||
extern struct ciabase ciaa_base, ciab_base;
|
||
|
||
+extern void cia_init_IRQ(struct ciabase *base);
|
||
extern unsigned char cia_set_irq(struct ciabase *base, unsigned char mask);
|
||
extern unsigned char cia_able_irq(struct ciabase *base, unsigned char mask);
|
||
|
||
diff -urN linux-i386/include/asm-m68k/apollohw.h linux-m68k/include/asm-m68k/apollohw.h
|
||
--- linux-i386/include/asm-m68k/apollohw.h 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/include/asm-m68k/apollohw.h 2006-01-28 22:33:11.000000000 +0100
|
||
@@ -3,6 +3,8 @@
|
||
#ifndef _ASMm68k_APOLLOHW_H_
|
||
#define _ASMm68k_APOLLOHW_H_
|
||
|
||
+#include <linux/types.h>
|
||
+
|
||
/*
|
||
apollo models
|
||
*/
|
||
@@ -101,4 +103,6 @@
|
||
|
||
#define isaIO2mem(x) (((((x) & 0x3f8) << 7) | (((x) & 0xfc00) >> 6) | ((x) & 0x7)) + 0x40000 + IO_BASE)
|
||
|
||
+#define IRQ_APOLLO IRQ_USER
|
||
+
|
||
#endif
|
||
diff -urN linux-i386/include/asm-m68k/atari_stdma.h linux-m68k/include/asm-m68k/atari_stdma.h
|
||
--- linux-i386/include/asm-m68k/atari_stdma.h 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/include/asm-m68k/atari_stdma.h 2006-05-09 20:47:28.000000000 +0200
|
||
@@ -3,7 +3,7 @@
|
||
#define _atari_stdma_h
|
||
|
||
|
||
-#include <asm/irq.h>
|
||
+#include <linux/interrupt.h>
|
||
|
||
|
||
/***************************** Prototypes *****************************/
|
||
diff -urN linux-i386/include/asm-m68k/atariints.h linux-m68k/include/asm-m68k/atariints.h
|
||
--- linux-i386/include/asm-m68k/atariints.h 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/include/asm-m68k/atariints.h 2006-01-28 22:30:07.000000000 +0100
|
||
@@ -45,17 +45,6 @@
|
||
#define IRQ_TYPE_FAST 1
|
||
#define IRQ_TYPE_PRIO 2
|
||
|
||
-#define IRQ_SPURIOUS (0)
|
||
-
|
||
-/* auto-vector interrupts */
|
||
-#define IRQ_AUTO_1 (1)
|
||
-#define IRQ_AUTO_2 (2)
|
||
-#define IRQ_AUTO_3 (3)
|
||
-#define IRQ_AUTO_4 (4)
|
||
-#define IRQ_AUTO_5 (5)
|
||
-#define IRQ_AUTO_6 (6)
|
||
-#define IRQ_AUTO_7 (7)
|
||
-
|
||
/* ST-MFP interrupts */
|
||
#define IRQ_MFP_BUSY (8)
|
||
#define IRQ_MFP_DCD (9)
|
||
diff -urN linux-i386/include/asm-m68k/bvme6000hw.h linux-m68k/include/asm-m68k/bvme6000hw.h
|
||
--- linux-i386/include/asm-m68k/bvme6000hw.h 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/include/asm-m68k/bvme6000hw.h 2006-01-28 22:33:48.000000000 +0100
|
||
@@ -109,23 +109,23 @@
|
||
|
||
#define BVME_IRQ_TYPE_PRIO 0
|
||
|
||
-#define BVME_IRQ_PRN 0x54
|
||
-#define BVME_IRQ_I596 0x1a
|
||
-#define BVME_IRQ_SCSI 0x1b
|
||
-#define BVME_IRQ_TIMER 0x59
|
||
-#define BVME_IRQ_RTC 0x1e
|
||
-#define BVME_IRQ_ABORT 0x1f
|
||
+#define BVME_IRQ_PRN (IRQ_USER+20)
|
||
+#define BVME_IRQ_TIMER (IRQ_USER+25)
|
||
+#define BVME_IRQ_I596 IRQ_AUTO_2
|
||
+#define BVME_IRQ_SCSI IRQ_AUTO_3
|
||
+#define BVME_IRQ_RTC IRQ_AUTO_6
|
||
+#define BVME_IRQ_ABORT IRQ_AUTO_7
|
||
|
||
/* SCC interrupts */
|
||
-#define BVME_IRQ_SCC_BASE 0x40
|
||
-#define BVME_IRQ_SCCB_TX 0x40
|
||
-#define BVME_IRQ_SCCB_STAT 0x42
|
||
-#define BVME_IRQ_SCCB_RX 0x44
|
||
-#define BVME_IRQ_SCCB_SPCOND 0x46
|
||
-#define BVME_IRQ_SCCA_TX 0x48
|
||
-#define BVME_IRQ_SCCA_STAT 0x4a
|
||
-#define BVME_IRQ_SCCA_RX 0x4c
|
||
-#define BVME_IRQ_SCCA_SPCOND 0x4e
|
||
+#define BVME_IRQ_SCC_BASE IRQ_USER
|
||
+#define BVME_IRQ_SCCB_TX IRQ_USER
|
||
+#define BVME_IRQ_SCCB_STAT (IRQ_USER+2)
|
||
+#define BVME_IRQ_SCCB_RX (IRQ_USER+4)
|
||
+#define BVME_IRQ_SCCB_SPCOND (IRQ_USER+6)
|
||
+#define BVME_IRQ_SCCA_TX (IRQ_USER+8)
|
||
+#define BVME_IRQ_SCCA_STAT (IRQ_USER+10)
|
||
+#define BVME_IRQ_SCCA_RX (IRQ_USER+12)
|
||
+#define BVME_IRQ_SCCA_SPCOND (IRQ_USER+14)
|
||
|
||
/* Address control registers */
|
||
|
||
diff -urN linux-i386/include/asm-m68k/cacheflush.h linux-m68k/include/asm-m68k/cacheflush.h
|
||
--- linux-i386/include/asm-m68k/cacheflush.h 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/include/asm-m68k/cacheflush.h 2006-06-06 01:01:40.000000000 +0200
|
||
@@ -3,26 +3,30 @@
|
||
|
||
#include <linux/mm.h>
|
||
|
||
+/* cache code */
|
||
+#define FLUSH_I_AND_D (0x00000808)
|
||
+#define FLUSH_I (0x00000008)
|
||
+
|
||
/*
|
||
* Cache handling functions
|
||
*/
|
||
|
||
-#define flush_icache() \
|
||
-({ \
|
||
- if (CPU_IS_040_OR_060) \
|
||
- __asm__ __volatile__("nop\n\t" \
|
||
- ".chip 68040\n\t" \
|
||
- "cinva %%ic\n\t" \
|
||
- ".chip 68k" : ); \
|
||
- else { \
|
||
- unsigned long _tmp; \
|
||
- __asm__ __volatile__("movec %%cacr,%0\n\t" \
|
||
- "orw %1,%0\n\t" \
|
||
- "movec %0,%%cacr" \
|
||
- : "=&d" (_tmp) \
|
||
- : "id" (FLUSH_I)); \
|
||
- } \
|
||
-})
|
||
+static inline void flush_icache(void)
|
||
+{
|
||
+ if (CPU_IS_040_OR_060)
|
||
+ asm volatile ( "nop\n"
|
||
+ " .chip 68040\n"
|
||
+ " cpusha %bc\n"
|
||
+ " .chip 68k");
|
||
+ else {
|
||
+ unsigned long tmp;
|
||
+ asm volatile ( "movec %%cacr,%0\n"
|
||
+ " or.w %1,%0\n"
|
||
+ " movec %0,%%cacr"
|
||
+ : "=&d" (tmp)
|
||
+ : "id" (FLUSH_I));
|
||
+ }
|
||
+}
|
||
|
||
/*
|
||
* invalidate the cache for the specified memory range.
|
||
@@ -43,10 +47,6 @@
|
||
*/
|
||
extern void cache_push_v(unsigned long vaddr, int len);
|
||
|
||
-/* cache code */
|
||
-#define FLUSH_I_AND_D (0x00000808)
|
||
-#define FLUSH_I (0x00000008)
|
||
-
|
||
/* This is needed whenever the virtual mapping of the current
|
||
process changes. */
|
||
#define __flush_cache_all() \
|
||
diff -urN linux-i386/include/asm-m68k/dma-mapping.h linux-m68k/include/asm-m68k/dma-mapping.h
|
||
--- linux-i386/include/asm-m68k/dma-mapping.h 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/include/asm-m68k/dma-mapping.h 2006-06-08 22:20:50.000000000 +0200
|
||
@@ -1,12 +1,91 @@
|
||
#ifndef _M68K_DMA_MAPPING_H
|
||
#define _M68K_DMA_MAPPING_H
|
||
|
||
-#include <linux/config.h>
|
||
+#include <asm/cache.h>
|
||
|
||
-#ifdef CONFIG_PCI
|
||
-#include <asm-generic/dma-mapping.h>
|
||
-#else
|
||
-#include <asm-generic/dma-mapping-broken.h>
|
||
-#endif
|
||
+struct scatterlist;
|
||
+
|
||
+static inline int dma_supported(struct device *dev, u64 mask)
|
||
+{
|
||
+ return 1;
|
||
+}
|
||
+
|
||
+static inline int dma_set_mask(struct device *dev, u64 mask)
|
||
+{
|
||
+ return 0;
|
||
+}
|
||
+
|
||
+static inline int dma_get_cache_alignment(void)
|
||
+{
|
||
+ return 1 << L1_CACHE_SHIFT;
|
||
+}
|
||
+
|
||
+static inline int dma_is_consistent(dma_addr_t dma_addr)
|
||
+{
|
||
+ return 0;
|
||
+}
|
||
+
|
||
+extern void *dma_alloc_coherent(struct device *, size_t,
|
||
+ dma_addr_t *, int);
|
||
+extern void dma_free_coherent(struct device *, size_t,
|
||
+ void *, dma_addr_t);
|
||
+
|
||
+static inline void *dma_alloc_noncoherent(struct device *dev, size_t size,
|
||
+ dma_addr_t *handle, int flag)
|
||
+{
|
||
+ return dma_alloc_coherent(dev, size, handle, flag);
|
||
+}
|
||
+static inline void dma_free_noncoherent(struct device *dev, size_t size,
|
||
+ void *addr, dma_addr_t handle)
|
||
+{
|
||
+ dma_free_coherent(dev, size, addr, handle);
|
||
+}
|
||
+static inline void dma_cache_sync(void *vaddr, size_t size,
|
||
+ enum dma_data_direction dir)
|
||
+{
|
||
+ /* we use coherent allocation, so not much to do here. */
|
||
+}
|
||
+
|
||
+extern dma_addr_t dma_map_single(struct device *, void *, size_t,
|
||
+ enum dma_data_direction);
|
||
+static inline void dma_unmap_single(struct device *dev, dma_addr_t addr,
|
||
+ size_t size, enum dma_data_direction dir)
|
||
+{
|
||
+}
|
||
+
|
||
+extern dma_addr_t dma_map_page(struct device *, struct page *,
|
||
+ unsigned long, size_t size,
|
||
+ enum dma_data_direction);
|
||
+static inline void dma_unmap_page(struct device *dev, dma_addr_t address,
|
||
+ size_t size, enum dma_data_direction dir)
|
||
+{
|
||
+}
|
||
+
|
||
+extern int dma_map_sg(struct device *, struct scatterlist *, int,
|
||
+ enum dma_data_direction);
|
||
+static inline void dma_unmap_sg(struct device *dev, struct scatterlist *sg,
|
||
+ int nhwentries, enum dma_data_direction dir)
|
||
+{
|
||
+}
|
||
+
|
||
+extern void dma_sync_single_for_device(struct device *, dma_addr_t, size_t,
|
||
+ enum dma_data_direction);
|
||
+extern void dma_sync_sg_for_device(struct device *, struct scatterlist *, int,
|
||
+ enum dma_data_direction);
|
||
+
|
||
+static inline void dma_sync_single_for_cpu(struct device *dev, dma_addr_t handle,
|
||
+ size_t size, enum dma_data_direction dir)
|
||
+{
|
||
+}
|
||
+
|
||
+static inline void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg,
|
||
+ int nents, enum dma_data_direction dir)
|
||
+{
|
||
+}
|
||
+
|
||
+static inline int dma_mapping_error(dma_addr_t handle)
|
||
+{
|
||
+ return 0;
|
||
+}
|
||
|
||
#endif /* _M68K_DMA_MAPPING_H */
|
||
diff -urN linux-i386/include/asm-m68k/io.h linux-m68k/include/asm-m68k/io.h
|
||
--- linux-i386/include/asm-m68k/io.h 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/include/asm-m68k/io.h 2006-04-10 00:23:26.000000000 +0200
|
||
@@ -325,8 +325,6 @@
|
||
#define writel(val,addr) out_le32((addr),(val))
|
||
#endif
|
||
|
||
-#define mmiowb()
|
||
-
|
||
static inline void __iomem *ioremap(unsigned long physaddr, unsigned long size)
|
||
{
|
||
return __ioremap(physaddr, size, IOMAP_NOCACHE_SER);
|
||
diff -urN linux-i386/include/asm-m68k/irq.h linux-m68k/include/asm-m68k/irq.h
|
||
--- linux-i386/include/asm-m68k/irq.h 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/include/asm-m68k/irq.h 2006-04-10 00:23:26.000000000 +0200
|
||
@@ -2,13 +2,8 @@
|
||
#define _M68K_IRQ_H_
|
||
|
||
#include <linux/config.h>
|
||
-#include <linux/interrupt.h>
|
||
-
|
||
-/*
|
||
- * # of m68k interrupts
|
||
- */
|
||
-
|
||
-#define SYS_IRQS 8
|
||
+#include <linux/linkage.h>
|
||
+#include <linux/spinlock_types.h>
|
||
|
||
/*
|
||
* This should be the same as the max(NUM_X_SOURCES) for all the
|
||
@@ -16,10 +11,20 @@
|
||
* Currently the Atari has 72 and the Amiga 24, but if both are
|
||
* supported in the kernel it is better to make room for 72.
|
||
*/
|
||
-#if defined(CONFIG_ATARI) || defined(CONFIG_MAC)
|
||
-#define NR_IRQS (72+SYS_IRQS)
|
||
+#if defined(CONFIG_VME) || defined(CONFIG_SUN3) || defined(CONFIG_SUN3X)
|
||
+#define NR_IRQS 200
|
||
+#elif defined(CONFIG_ATARI) || defined(CONFIG_MAC)
|
||
+#define NR_IRQS 72
|
||
+#elif defined(CONFIG_Q40)
|
||
+#define NR_IRQS 43
|
||
+#elif defined(CONFIG_AMIGA)
|
||
+#define NR_IRQS 32
|
||
+#elif defined(CONFIG_APOLLO)
|
||
+#define NR_IRQS 24
|
||
+#elif defined(CONFIG_HP300)
|
||
+#define NR_IRQS 8
|
||
#else
|
||
-#define NR_IRQS (24+SYS_IRQS)
|
||
+#error unknown nr of irqs
|
||
#endif
|
||
|
||
/*
|
||
@@ -41,53 +46,26 @@
|
||
* that routine requires service.
|
||
*/
|
||
|
||
-#define IRQ1 (1) /* level 1 interrupt */
|
||
-#define IRQ2 (2) /* level 2 interrupt */
|
||
-#define IRQ3 (3) /* level 3 interrupt */
|
||
-#define IRQ4 (4) /* level 4 interrupt */
|
||
-#define IRQ5 (5) /* level 5 interrupt */
|
||
-#define IRQ6 (6) /* level 6 interrupt */
|
||
-#define IRQ7 (7) /* level 7 interrupt (non-maskable) */
|
||
-
|
||
-/*
|
||
- * "Generic" interrupt sources
|
||
- */
|
||
-
|
||
-#define IRQ_SCHED_TIMER (8) /* interrupt source for scheduling timer */
|
||
-
|
||
-static __inline__ int irq_canonicalize(int irq)
|
||
-{
|
||
- return irq;
|
||
-}
|
||
-
|
||
-/*
|
||
- * Machine specific interrupt sources.
|
||
- *
|
||
- * Adding an interrupt service routine for a source with this bit
|
||
- * set indicates a special machine specific interrupt source.
|
||
- * The machine specific files define these sources.
|
||
- *
|
||
- * The IRQ_MACHSPEC bit is now gone - the only thing it did was to
|
||
- * introduce unnecessary overhead.
|
||
- *
|
||
- * All interrupt handling is actually machine specific so it is better
|
||
- * to use function pointers, as used by the Sparc port, and select the
|
||
- * interrupt handling functions when initializing the kernel. This way
|
||
- * we save some unnecessary overhead at run-time.
|
||
- * 01/11/97 - Jes
|
||
- */
|
||
+#define IRQ_SPURIOUS 0
|
||
+
|
||
+#define IRQ_AUTO_1 1 /* level 1 interrupt */
|
||
+#define IRQ_AUTO_2 2 /* level 2 interrupt */
|
||
+#define IRQ_AUTO_3 3 /* level 3 interrupt */
|
||
+#define IRQ_AUTO_4 4 /* level 4 interrupt */
|
||
+#define IRQ_AUTO_5 5 /* level 5 interrupt */
|
||
+#define IRQ_AUTO_6 6 /* level 6 interrupt */
|
||
+#define IRQ_AUTO_7 7 /* level 7 interrupt (non-maskable) */
|
||
+
|
||
+#define IRQ_USER 8
|
||
+
|
||
+extern unsigned int irq_canonicalize(unsigned int irq);
|
||
+extern void enable_irq(unsigned int);
|
||
+extern void disable_irq(unsigned int);
|
||
|
||
-extern void (*enable_irq)(unsigned int);
|
||
-extern void (*disable_irq)(unsigned int);
|
||
#define disable_irq_nosync disable_irq
|
||
|
||
struct pt_regs;
|
||
|
||
-extern int cpu_request_irq(unsigned int,
|
||
- irqreturn_t (*)(int, void *, struct pt_regs *),
|
||
- unsigned long, const char *, void *);
|
||
-extern void cpu_free_irq(unsigned int, void *);
|
||
-
|
||
/*
|
||
* various flags for request_irq() - the Amiga now uses the standard
|
||
* mechanism like all other architectures - SA_INTERRUPT and SA_SHIRQ
|
||
@@ -106,33 +84,45 @@
|
||
* interrupt source (if it supports chaining).
|
||
*/
|
||
typedef struct irq_node {
|
||
- irqreturn_t (*handler)(int, void *, struct pt_regs *);
|
||
- unsigned long flags;
|
||
+ int (*handler)(int, void *, struct pt_regs *);
|
||
void *dev_id;
|
||
- const char *devname;
|
||
struct irq_node *next;
|
||
+ unsigned long flags;
|
||
+ const char *devname;
|
||
} irq_node_t;
|
||
|
||
/*
|
||
* This structure has only 4 elements for speed reasons
|
||
*/
|
||
typedef struct irq_handler {
|
||
- irqreturn_t (*handler)(int, void *, struct pt_regs *);
|
||
+ int (*handler)(int, void *, struct pt_regs *);
|
||
unsigned long flags;
|
||
void *dev_id;
|
||
const char *devname;
|
||
} irq_handler_t;
|
||
|
||
-/* count of spurious interrupts */
|
||
-extern volatile unsigned int num_spurious;
|
||
+struct irq_controller {
|
||
+ const char *name;
|
||
+ spinlock_t lock;
|
||
+ int (*startup)(unsigned int irq);
|
||
+ void (*shutdown)(unsigned int irq);
|
||
+ void (*enable)(unsigned int irq);
|
||
+ void (*disable)(unsigned int irq);
|
||
+};
|
||
+
|
||
+extern int m68k_irq_startup(unsigned int);
|
||
+extern void m68k_irq_shutdown(unsigned int);
|
||
|
||
/*
|
||
* This function returns a new irq_node_t
|
||
*/
|
||
extern irq_node_t *new_irq_node(void);
|
||
|
||
-struct irqaction;
|
||
-struct pt_regs;
|
||
-int handle_IRQ_event(unsigned int, struct pt_regs *, struct irqaction *);
|
||
+extern void m68k_setup_auto_interrupt(void (*handler)(unsigned int, struct pt_regs *));
|
||
+extern void m68k_setup_user_interrupt(unsigned int vec, unsigned int cnt,
|
||
+ void (*handler)(unsigned int, struct pt_regs *));
|
||
+extern void m68k_setup_irq_controller(struct irq_controller *, unsigned int, unsigned int);
|
||
+
|
||
+asmlinkage void m68k_handle_int(unsigned int, struct pt_regs *);
|
||
|
||
#endif /* _M68K_IRQ_H_ */
|
||
diff -urN linux-i386/include/asm-m68k/mac_oss.h linux-m68k/include/asm-m68k/mac_oss.h
|
||
--- linux-i386/include/asm-m68k/mac_oss.h 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/include/asm-m68k/mac_oss.h 2006-01-28 22:36:17.000000000 +0100
|
||
@@ -69,12 +69,12 @@
|
||
|
||
#define OSS_IRQLEV_DISABLED 0
|
||
#define OSS_IRQLEV_IOPISM 1 /* ADB? */
|
||
-#define OSS_IRQLEV_SCSI 2
|
||
-#define OSS_IRQLEV_NUBUS 3 /* keep this on its own level */
|
||
-#define OSS_IRQLEV_IOPSCC 4 /* matches VIA alternate mapping */
|
||
-#define OSS_IRQLEV_SOUND 5 /* matches VIA alternate mapping */
|
||
+#define OSS_IRQLEV_SCSI IRQ_AUTO_2
|
||
+#define OSS_IRQLEV_NUBUS IRQ_AUTO_3 /* keep this on its own level */
|
||
+#define OSS_IRQLEV_IOPSCC IRQ_AUTO_4 /* matches VIA alternate mapping */
|
||
+#define OSS_IRQLEV_SOUND IRQ_AUTO_5 /* matches VIA alternate mapping */
|
||
#define OSS_IRQLEV_60HZ 6 /* matches VIA alternate mapping */
|
||
-#define OSS_IRQLEV_VIA1 6 /* matches VIA alternate mapping */
|
||
+#define OSS_IRQLEV_VIA1 IRQ_AUTO_6 /* matches VIA alternate mapping */
|
||
#define OSS_IRQLEV_PARITY 7 /* matches VIA alternate mapping */
|
||
|
||
#ifndef __ASSEMBLY__
|
||
diff -urN linux-i386/include/asm-m68k/machdep.h linux-m68k/include/asm-m68k/machdep.h
|
||
--- linux-i386/include/asm-m68k/machdep.h 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/include/asm-m68k/machdep.h 2006-04-10 00:23:26.000000000 +0200
|
||
@@ -13,14 +13,8 @@
|
||
extern void (*mach_sched_init) (irqreturn_t (*handler)(int, void *, struct pt_regs *));
|
||
/* machine dependent irq functions */
|
||
extern void (*mach_init_IRQ) (void);
|
||
-extern irqreturn_t (*(*mach_default_handler)[]) (int, void *, struct pt_regs *);
|
||
-extern int (*mach_request_irq) (unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_regs *),
|
||
- unsigned long flags, const char *devname, void *dev_id);
|
||
-extern void (*mach_free_irq) (unsigned int irq, void *dev_id);
|
||
extern void (*mach_get_model) (char *model);
|
||
extern int (*mach_get_hardware_list) (char *buffer);
|
||
-extern int (*mach_get_irq_list) (struct seq_file *p, void *v);
|
||
-extern irqreturn_t (*mach_process_int) (int irq, struct pt_regs *fp);
|
||
/* machine dependent timer functions */
|
||
extern unsigned long (*mach_gettimeoffset)(void);
|
||
extern int (*mach_hwclk)(int, struct rtc_time*);
|
||
diff -urN linux-i386/include/asm-m68k/macintosh.h linux-m68k/include/asm-m68k/macintosh.h
|
||
--- linux-i386/include/asm-m68k/macintosh.h 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/include/asm-m68k/macintosh.h 2006-01-28 22:36:17.000000000 +0100
|
||
@@ -11,17 +11,7 @@
|
||
extern void mac_reset(void);
|
||
extern void mac_poweroff(void);
|
||
extern void mac_init_IRQ(void);
|
||
-extern int mac_request_irq (unsigned int, irqreturn_t (*)(int, void *,
|
||
- struct pt_regs *),
|
||
- unsigned long, const char *, void *);
|
||
-extern void mac_free_irq(unsigned int, void *);
|
||
-extern void mac_enable_irq(unsigned int);
|
||
-extern void mac_disable_irq(unsigned int);
|
||
extern int mac_irq_pending(unsigned int);
|
||
-extern int show_mac_interrupts(struct seq_file *, void *);
|
||
-#if 0
|
||
-extern void mac_default_handler(int irq);
|
||
-#endif
|
||
extern void mac_identify(void);
|
||
extern void mac_report_hardware(void);
|
||
extern void mac_debugging_penguin(int);
|
||
diff -urN linux-i386/include/asm-m68k/macints.h linux-m68k/include/asm-m68k/macints.h
|
||
--- linux-i386/include/asm-m68k/macints.h 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/include/asm-m68k/macints.h 2006-01-28 22:36:17.000000000 +0100
|
||
@@ -59,17 +59,6 @@
|
||
#define IRQ_SRC(irq) (irq >> 3)
|
||
#define IRQ_IDX(irq) (irq & 7)
|
||
|
||
-#define IRQ_SPURIOUS (0)
|
||
-
|
||
-/* auto-vector interrupts */
|
||
-#define IRQ_AUTO_1 (1)
|
||
-#define IRQ_AUTO_2 (2)
|
||
-#define IRQ_AUTO_3 (3)
|
||
-#define IRQ_AUTO_4 (4)
|
||
-#define IRQ_AUTO_5 (5)
|
||
-#define IRQ_AUTO_6 (6)
|
||
-#define IRQ_AUTO_7 (7)
|
||
-
|
||
/* VIA1 interrupts */
|
||
#define IRQ_VIA1_0 (8) /* one second int. */
|
||
#define IRQ_VIA1_1 (9) /* VBlank int. */
|
||
@@ -163,7 +152,4 @@
|
||
#define INT_CLK 24576 /* CLK while int_clk =2.456MHz and divide = 100 */
|
||
#define INT_TICKS 246 /* to make sched_time = 99.902... HZ */
|
||
|
||
-extern irq_node_t *mac_irq_list[NUM_MAC_SOURCES];
|
||
-extern void mac_do_irq_list(int irq, struct pt_regs *);
|
||
-
|
||
#endif /* asm/macints.h */
|
||
diff -urN linux-i386/include/asm-m68k/module.h linux-m68k/include/asm-m68k/module.h
|
||
--- linux-i386/include/asm-m68k/module.h 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/include/asm-m68k/module.h 2006-06-06 01:17:29.000000000 +0200
|
||
@@ -1,7 +1,38 @@
|
||
#ifndef _ASM_M68K_MODULE_H
|
||
#define _ASM_M68K_MODULE_H
|
||
-struct mod_arch_specific { };
|
||
+
|
||
+struct mod_arch_specific {
|
||
+ struct m68k_fixup_info *fixup_start, *fixup_end;
|
||
+};
|
||
+
|
||
+#define MODULE_ARCH_INIT { \
|
||
+ .fixup_start = __start_fixup, \
|
||
+ .fixup_end = __stop_fixup, \
|
||
+}
|
||
+
|
||
#define Elf_Shdr Elf32_Shdr
|
||
#define Elf_Sym Elf32_Sym
|
||
#define Elf_Ehdr Elf32_Ehdr
|
||
+
|
||
+
|
||
+enum m68k_fixup_type {
|
||
+ m68k_fixup_memoffset,
|
||
+};
|
||
+
|
||
+struct m68k_fixup_info {
|
||
+ enum m68k_fixup_type type;
|
||
+ void *addr;
|
||
+};
|
||
+
|
||
+#define m68k_fixup(type, addr) \
|
||
+ " .section \".m68k_fixup\",\"aw\"\n" \
|
||
+ " .long " #type "," #addr "\n" \
|
||
+ " .previous\n"
|
||
+
|
||
+extern struct m68k_fixup_info __start_fixup[], __stop_fixup[];
|
||
+
|
||
+struct module;
|
||
+extern void module_fixup(struct module *mod, struct m68k_fixup_info *start,
|
||
+ struct m68k_fixup_info *end);
|
||
+
|
||
#endif /* _ASM_M68K_MODULE_H */
|
||
diff -urN linux-i386/include/asm-m68k/mvme147hw.h linux-m68k/include/asm-m68k/mvme147hw.h
|
||
--- linux-i386/include/asm-m68k/mvme147hw.h 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/include/asm-m68k/mvme147hw.h 2006-01-28 22:36:38.000000000 +0100
|
||
@@ -1,6 +1,8 @@
|
||
#ifndef _MVME147HW_H_
|
||
#define _MVME147HW_H_
|
||
|
||
+#include <asm/irq.h>
|
||
+
|
||
typedef struct {
|
||
unsigned char
|
||
ctrl,
|
||
@@ -72,39 +74,39 @@
|
||
#define PCC_LEVEL_SCSI_PORT 0x04
|
||
#define PCC_LEVEL_SCSI_DMA 0x04
|
||
|
||
-#define PCC_IRQ_AC_FAIL 0x40
|
||
-#define PCC_IRQ_BERR 0x41
|
||
-#define PCC_IRQ_ABORT 0x42
|
||
-/* #define PCC_IRQ_SERIAL 0x43 */
|
||
-#define PCC_IRQ_PRINTER 0x47
|
||
-#define PCC_IRQ_TIMER1 0x48
|
||
-#define PCC_IRQ_TIMER2 0x49
|
||
-#define PCC_IRQ_SOFTWARE1 0x4a
|
||
-#define PCC_IRQ_SOFTWARE2 0x4b
|
||
+#define PCC_IRQ_AC_FAIL (IRQ_USER+0)
|
||
+#define PCC_IRQ_BERR (IRQ_USER+1)
|
||
+#define PCC_IRQ_ABORT (IRQ_USER+2)
|
||
+/* #define PCC_IRQ_SERIAL (IRQ_USER+3) */
|
||
+#define PCC_IRQ_PRINTER (IRQ_USER+7)
|
||
+#define PCC_IRQ_TIMER1 (IRQ_USER+8)
|
||
+#define PCC_IRQ_TIMER2 (IRQ_USER+9)
|
||
+#define PCC_IRQ_SOFTWARE1 (IRQ_USER+10)
|
||
+#define PCC_IRQ_SOFTWARE2 (IRQ_USER+11)
|
||
|
||
|
||
#define M147_SCC_A_ADDR 0xfffe3002
|
||
#define M147_SCC_B_ADDR 0xfffe3000
|
||
#define M147_SCC_PCLK 5000000
|
||
|
||
-#define MVME147_IRQ_SCSI_PORT 0x45
|
||
-#define MVME147_IRQ_SCSI_DMA 0x46
|
||
+#define MVME147_IRQ_SCSI_PORT (IRQ_USER+0x45)
|
||
+#define MVME147_IRQ_SCSI_DMA (IRQ_USER+0x46)
|
||
|
||
/* SCC interrupts, for MVME147 */
|
||
|
||
#define MVME147_IRQ_TYPE_PRIO 0
|
||
-#define MVME147_IRQ_SCC_BASE 0x60
|
||
-#define MVME147_IRQ_SCCB_TX 0x60
|
||
-#define MVME147_IRQ_SCCB_STAT 0x62
|
||
-#define MVME147_IRQ_SCCB_RX 0x64
|
||
-#define MVME147_IRQ_SCCB_SPCOND 0x66
|
||
-#define MVME147_IRQ_SCCA_TX 0x68
|
||
-#define MVME147_IRQ_SCCA_STAT 0x6a
|
||
-#define MVME147_IRQ_SCCA_RX 0x6c
|
||
-#define MVME147_IRQ_SCCA_SPCOND 0x6e
|
||
+#define MVME147_IRQ_SCC_BASE (IRQ_USER+32)
|
||
+#define MVME147_IRQ_SCCB_TX (IRQ_USER+32)
|
||
+#define MVME147_IRQ_SCCB_STAT (IRQ_USER+34)
|
||
+#define MVME147_IRQ_SCCB_RX (IRQ_USER+36)
|
||
+#define MVME147_IRQ_SCCB_SPCOND (IRQ_USER+38)
|
||
+#define MVME147_IRQ_SCCA_TX (IRQ_USER+40)
|
||
+#define MVME147_IRQ_SCCA_STAT (IRQ_USER+42)
|
||
+#define MVME147_IRQ_SCCA_RX (IRQ_USER+44)
|
||
+#define MVME147_IRQ_SCCA_SPCOND (IRQ_USER+46)
|
||
|
||
#define MVME147_LANCE_BASE 0xfffe1800
|
||
-#define MVME147_LANCE_IRQ 0x44
|
||
+#define MVME147_LANCE_IRQ (IRQ_USER+4)
|
||
|
||
#define ETHERNET_ADDRESS 0xfffe0778
|
||
|
||
diff -urN linux-i386/include/asm-m68k/mvme16xhw.h linux-m68k/include/asm-m68k/mvme16xhw.h
|
||
--- linux-i386/include/asm-m68k/mvme16xhw.h 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/include/asm-m68k/mvme16xhw.h 2006-01-28 22:37:06.000000000 +0100
|
||
@@ -66,28 +66,28 @@
|
||
|
||
#define MVME162_IRQ_TYPE_PRIO 0
|
||
|
||
-#define MVME167_IRQ_PRN 0x54
|
||
-#define MVME16x_IRQ_I596 0x57
|
||
-#define MVME16x_IRQ_SCSI 0x55
|
||
-#define MVME16x_IRQ_FLY 0x7f
|
||
-#define MVME167_IRQ_SER_ERR 0x5c
|
||
-#define MVME167_IRQ_SER_MODEM 0x5d
|
||
-#define MVME167_IRQ_SER_TX 0x5e
|
||
-#define MVME167_IRQ_SER_RX 0x5f
|
||
-#define MVME16x_IRQ_TIMER 0x59
|
||
-#define MVME167_IRQ_ABORT 0x6e
|
||
-#define MVME162_IRQ_ABORT 0x5e
|
||
+#define MVME167_IRQ_PRN (IRQ_USER+20)
|
||
+#define MVME16x_IRQ_I596 (IRQ_USER+23)
|
||
+#define MVME16x_IRQ_SCSI (IRQ_USER+21)
|
||
+#define MVME16x_IRQ_FLY (IRQ_USER+63)
|
||
+#define MVME167_IRQ_SER_ERR (IRQ_USER+28)
|
||
+#define MVME167_IRQ_SER_MODEM (IRQ_USER+29)
|
||
+#define MVME167_IRQ_SER_TX (IRQ_USER+30)
|
||
+#define MVME167_IRQ_SER_RX (IRQ_USER+31)
|
||
+#define MVME16x_IRQ_TIMER (IRQ_USER+25)
|
||
+#define MVME167_IRQ_ABORT (IRQ_USER+46)
|
||
+#define MVME162_IRQ_ABORT (IRQ_USER+30)
|
||
|
||
/* SCC interrupts, for MVME162 */
|
||
-#define MVME162_IRQ_SCC_BASE 0x40
|
||
-#define MVME162_IRQ_SCCB_TX 0x40
|
||
-#define MVME162_IRQ_SCCB_STAT 0x42
|
||
-#define MVME162_IRQ_SCCB_RX 0x44
|
||
-#define MVME162_IRQ_SCCB_SPCOND 0x46
|
||
-#define MVME162_IRQ_SCCA_TX 0x48
|
||
-#define MVME162_IRQ_SCCA_STAT 0x4a
|
||
-#define MVME162_IRQ_SCCA_RX 0x4c
|
||
-#define MVME162_IRQ_SCCA_SPCOND 0x4e
|
||
+#define MVME162_IRQ_SCC_BASE (IRQ_USER+0)
|
||
+#define MVME162_IRQ_SCCB_TX (IRQ_USER+0)
|
||
+#define MVME162_IRQ_SCCB_STAT (IRQ_USER+2)
|
||
+#define MVME162_IRQ_SCCB_RX (IRQ_USER+4)
|
||
+#define MVME162_IRQ_SCCB_SPCOND (IRQ_USER+6)
|
||
+#define MVME162_IRQ_SCCA_TX (IRQ_USER+8)
|
||
+#define MVME162_IRQ_SCCA_STAT (IRQ_USER+10)
|
||
+#define MVME162_IRQ_SCCA_RX (IRQ_USER+12)
|
||
+#define MVME162_IRQ_SCCA_SPCOND (IRQ_USER+14)
|
||
|
||
/* MVME162 version register */
|
||
|
||
diff -urN linux-i386/include/asm-m68k/page.h linux-m68k/include/asm-m68k/page.h
|
||
--- linux-i386/include/asm-m68k/page.h 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/include/asm-m68k/page.h 2006-06-06 01:17:29.000000000 +0200
|
||
@@ -28,6 +28,8 @@
|
||
|
||
#ifndef __ASSEMBLY__
|
||
|
||
+#include <asm/module.h>
|
||
+
|
||
#define get_user_page(vaddr) __get_free_page(GFP_KERNEL)
|
||
#define free_user_page(page, addr) free_page(addr)
|
||
|
||
@@ -115,14 +117,35 @@
|
||
|
||
#ifndef __ASSEMBLY__
|
||
|
||
+extern unsigned long m68k_memoffset;
|
||
+
|
||
#ifndef CONFIG_SUN3
|
||
|
||
#define WANT_PAGE_VIRTUAL
|
||
#ifdef CONFIG_SINGLE_MEMORY_CHUNK
|
||
-extern unsigned long m68k_memoffset;
|
||
|
||
-#define __pa(vaddr) ((unsigned long)(vaddr)+m68k_memoffset)
|
||
-#define __va(paddr) ((void *)((unsigned long)(paddr)-m68k_memoffset))
|
||
+static inline unsigned long ___pa(void *vaddr)
|
||
+{
|
||
+ unsigned long paddr;
|
||
+ asm (
|
||
+ "1: addl #0,%0\n"
|
||
+ m68k_fixup(%c2, 1b+2)
|
||
+ : "=r" (paddr)
|
||
+ : "0" (vaddr), "i" (m68k_fixup_memoffset));
|
||
+ return paddr;
|
||
+}
|
||
+#define __pa(vaddr) ___pa((void *)(vaddr))
|
||
+static inline void *__va(unsigned long paddr)
|
||
+{
|
||
+ void *vaddr;
|
||
+ asm (
|
||
+ "1: subl #0,%0\n"
|
||
+ m68k_fixup(%c2, 1b+2)
|
||
+ : "=r" (vaddr)
|
||
+ : "0" (paddr), "i" (m68k_fixup_memoffset));
|
||
+ return vaddr;
|
||
+}
|
||
+
|
||
#else
|
||
#define __pa(vaddr) virt_to_phys((void *)(vaddr))
|
||
#define __va(paddr) phys_to_virt((unsigned long)(paddr))
|
||
diff -urN linux-i386/include/asm-m68k/processor.h linux-m68k/include/asm-m68k/processor.h
|
||
--- linux-i386/include/asm-m68k/processor.h 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/include/asm-m68k/processor.h 2006-01-28 22:25:23.000000000 +0100
|
||
@@ -72,10 +72,10 @@
|
||
};
|
||
|
||
#define INIT_THREAD { \
|
||
- ksp: sizeof(init_stack) + (unsigned long) init_stack, \
|
||
- sr: PS_S, \
|
||
- fs: __KERNEL_DS, \
|
||
- info: INIT_THREAD_INFO(init_task) \
|
||
+ .ksp = sizeof(init_stack) + (unsigned long) init_stack, \
|
||
+ .sr = PS_S, \
|
||
+ .fs = __KERNEL_DS, \
|
||
+ .info = INIT_THREAD_INFO(init_task), \
|
||
}
|
||
|
||
/*
|
||
diff -urN linux-i386/include/asm-m68k/scatterlist.h linux-m68k/include/asm-m68k/scatterlist.h
|
||
--- linux-i386/include/asm-m68k/scatterlist.h 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/include/asm-m68k/scatterlist.h 2006-06-06 01:18:33.000000000 +0200
|
||
@@ -2,18 +2,17 @@
|
||
#define _M68K_SCATTERLIST_H
|
||
|
||
struct scatterlist {
|
||
- /* These two are only valid if ADDRESS member of this
|
||
- * struct is NULL.
|
||
- */
|
||
struct page *page;
|
||
unsigned int offset;
|
||
-
|
||
unsigned int length;
|
||
|
||
- __u32 dvma_address; /* A place to hang host-specific addresses at. */
|
||
+ __u32 dma_address; /* A place to hang host-specific addresses at. */
|
||
};
|
||
|
||
/* This is bogus and should go away. */
|
||
#define ISA_DMA_THRESHOLD (0x00ffffff)
|
||
|
||
+#define sg_dma_address(sg) ((sg)->dma_address)
|
||
+#define sg_dma_len(sg) ((sg)->length)
|
||
+
|
||
#endif /* !(_M68K_SCATTERLIST_H) */
|
||
diff -urN linux-i386/include/asm-m68k/serial.h linux-m68k/include/asm-m68k/serial.h
|
||
--- linux-i386/include/asm-m68k/serial.h 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/include/asm-m68k/serial.h 2005-08-29 17:37:10.000000000 +0200
|
||
@@ -26,9 +26,11 @@
|
||
#define STD_COM4_FLAGS ASYNC_BOOT_AUTOCONF
|
||
#endif
|
||
|
||
+#ifdef CONFIG_ISA
|
||
#define SERIAL_PORT_DFNS \
|
||
/* UART CLK PORT IRQ FLAGS */ \
|
||
{ 0, BASE_BAUD, 0x3F8, 4, STD_COM_FLAGS }, /* ttyS0 */ \
|
||
{ 0, BASE_BAUD, 0x2F8, 3, STD_COM_FLAGS }, /* ttyS1 */ \
|
||
{ 0, BASE_BAUD, 0x3E8, 4, STD_COM_FLAGS }, /* ttyS2 */ \
|
||
{ 0, BASE_BAUD, 0x2E8, 3, STD_COM4_FLAGS }, /* ttyS3 */
|
||
+#endif
|
||
diff -urN linux-i386/include/asm-m68k/signal.h linux-m68k/include/asm-m68k/signal.h
|
||
--- linux-i386/include/asm-m68k/signal.h 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/include/asm-m68k/signal.h 2006-06-06 00:57:58.000000000 +0200
|
||
@@ -156,13 +156,17 @@
|
||
|
||
static inline void sigaddset(sigset_t *set, int _sig)
|
||
{
|
||
- __asm__("bfset %0{%1,#1}" : "=m" (*set) : "id" ((_sig - 1) ^ 31)
|
||
+ asm ("bfset %0{%1,#1}"
|
||
+ : "+od" (*set)
|
||
+ : "id" ((_sig - 1) ^ 31)
|
||
: "cc");
|
||
}
|
||
|
||
static inline void sigdelset(sigset_t *set, int _sig)
|
||
{
|
||
- __asm__("bfclr %0{%1,#1}" : "=m"(*set) : "id"((_sig - 1) ^ 31)
|
||
+ asm ("bfclr %0{%1,#1}"
|
||
+ : "+od" (*set)
|
||
+ : "id" ((_sig - 1) ^ 31)
|
||
: "cc");
|
||
}
|
||
|
||
@@ -175,8 +179,10 @@
|
||
static inline int __gen_sigismember(sigset_t *set, int _sig)
|
||
{
|
||
int ret;
|
||
- __asm__("bfextu %1{%2,#1},%0"
|
||
- : "=d"(ret) : "m"(*set), "id"((_sig-1) ^ 31));
|
||
+ asm ("bfextu %1{%2,#1},%0"
|
||
+ : "=d" (ret)
|
||
+ : "od" (*set), "id" ((_sig-1) ^ 31)
|
||
+ : "cc");
|
||
return ret;
|
||
}
|
||
|
||
@@ -187,7 +193,10 @@
|
||
|
||
static inline int sigfindinword(unsigned long word)
|
||
{
|
||
- __asm__("bfffo %1{#0,#0},%0" : "=d"(word) : "d"(word & -word) : "cc");
|
||
+ asm ("bfffo %1{#0,#0},%0"
|
||
+ : "=d" (word)
|
||
+ : "d" (word & -word)
|
||
+ : "cc");
|
||
return word ^ 31;
|
||
}
|
||
|
||
diff -urN linux-i386/include/asm-m68k/sun3-head.h linux-m68k/include/asm-m68k/sun3-head.h
|
||
--- linux-i386/include/asm-m68k/sun3-head.h 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/include/asm-m68k/sun3-head.h 2006-05-11 13:14:11.000000000 +0200
|
||
@@ -4,7 +4,6 @@
|
||
|
||
#define KERNBASE 0xE000000 /* First address the kernel will eventually be */
|
||
#define LOAD_ADDR 0x4000 /* prom jumps to us here unless this is elf /boot */
|
||
-#define BI_START (KERNBASE + 0x3000) /* beginning of the bootinfo records */
|
||
#define FC_CONTROL 3
|
||
#define FC_SUPERD 5
|
||
#define FC_CPU 7
|
||
diff -urN linux-i386/include/asm-m68k/sun3ints.h linux-m68k/include/asm-m68k/sun3ints.h
|
||
--- linux-i386/include/asm-m68k/sun3ints.h 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/include/asm-m68k/sun3ints.h 2006-05-11 13:14:11.000000000 +0200
|
||
@@ -12,37 +12,26 @@
|
||
#define SUN3INTS_H
|
||
|
||
#include <linux/types.h>
|
||
-#include <linux/kernel.h>
|
||
-#include <linux/sched.h>
|
||
-#include <linux/kernel_stat.h>
|
||
#include <linux/interrupt.h>
|
||
-#include <linux/seq_file.h>
|
||
-#include <asm/segment.h>
|
||
#include <asm/intersil.h>
|
||
#include <asm/oplib.h>
|
||
+#include <asm/traps.h>
|
||
+#include <asm/irq.h>
|
||
|
||
#define SUN3_INT_VECS 192
|
||
|
||
void sun3_enable_irq(unsigned int irq);
|
||
void sun3_disable_irq(unsigned int irq);
|
||
-int sun3_request_irq(unsigned int irq,
|
||
- irqreturn_t (*handler)(int, void *, struct pt_regs *),
|
||
- unsigned long flags, const char *devname, void *dev_id
|
||
- );
|
||
extern void sun3_init_IRQ (void);
|
||
-extern irqreturn_t (*sun3_default_handler[]) (int, void *, struct pt_regs *);
|
||
-extern void sun3_free_irq (unsigned int irq, void *dev_id);
|
||
extern void sun3_enable_interrupts (void);
|
||
extern void sun3_disable_interrupts (void);
|
||
-extern int show_sun3_interrupts(struct seq_file *, void *);
|
||
-extern irqreturn_t sun3_process_int(int, struct pt_regs *);
|
||
extern volatile unsigned char* sun3_intreg;
|
||
|
||
/* master list of VME vectors -- don't fuck with this */
|
||
-#define SUN3_VEC_FLOPPY 0x40
|
||
-#define SUN3_VEC_VMESCSI0 0x40
|
||
-#define SUN3_VEC_VMESCSI1 0x41
|
||
-#define SUN3_VEC_CG 0xA8
|
||
+#define SUN3_VEC_FLOPPY (IRQ_USER+0)
|
||
+#define SUN3_VEC_VMESCSI0 (IRQ_USER+0)
|
||
+#define SUN3_VEC_VMESCSI1 (IRQ_USER+1)
|
||
+#define SUN3_VEC_CG (IRQ_USER+104)
|
||
|
||
|
||
#endif /* SUN3INTS_H */
|
||
diff -urN linux-i386/include/asm-m68k/thread_info.h linux-m68k/include/asm-m68k/thread_info.h
|
||
--- linux-i386/include/asm-m68k/thread_info.h 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/include/asm-m68k/thread_info.h 2006-04-11 01:58:28.000000000 +0200
|
||
@@ -26,24 +26,24 @@
|
||
|
||
/* THREAD_SIZE should be 8k, so handle differently for 4k and 8k machines */
|
||
#if PAGE_SHIFT == 13 /* 8k machines */
|
||
-#define alloc_thread_info(tsk) ((struct thread_info *)__get_free_pages(GFP_KERNEL,0))
|
||
-#define free_thread_info(ti) free_pages((unsigned long)(ti),0)
|
||
+#define alloc_thread_stack(tsk) ((void *)__get_free_pages(GFP_KERNEL,0))
|
||
+#define free_thread_stack(ti) free_pages((unsigned long)(ti),0)
|
||
#else /* otherwise assume 4k pages */
|
||
-#define alloc_thread_info(tsk) ((struct thread_info *)__get_free_pages(GFP_KERNEL,1))
|
||
-#define free_thread_info(ti) free_pages((unsigned long)(ti),1)
|
||
+#define alloc_thread_stack(tsk) ((void *)__get_free_pages(GFP_KERNEL,1))
|
||
+#define free_thread_stack(ti) free_pages((unsigned long)(ti),1)
|
||
#endif /* PAGE_SHIFT == 13 */
|
||
|
||
#define init_thread_info (init_task.thread.info)
|
||
#define init_stack (init_thread_union.stack)
|
||
|
||
#define task_thread_info(tsk) (&(tsk)->thread.info)
|
||
-#define task_stack_page(tsk) ((void *)(tsk)->thread_info)
|
||
+#define task_stack_page(tsk) ((void *)(tsk)->stack)
|
||
#define current_thread_info() task_thread_info(current)
|
||
|
||
#define __HAVE_THREAD_FUNCTIONS
|
||
|
||
#define setup_thread_stack(p, org) ({ \
|
||
- *(struct task_struct **)(p)->thread_info = (p); \
|
||
+ *(struct task_struct **)(p)->stack = (p); \
|
||
task_thread_info(p)->task = (p); \
|
||
})
|
||
|
||
diff -urN linux-i386/include/asm-m68k/traps.h linux-m68k/include/asm-m68k/traps.h
|
||
--- linux-i386/include/asm-m68k/traps.h 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/include/asm-m68k/traps.h 2006-01-28 22:32:08.000000000 +0100
|
||
@@ -15,6 +15,10 @@
|
||
|
||
typedef void (*e_vector)(void);
|
||
|
||
+asmlinkage void auto_inthandler(void);
|
||
+asmlinkage void user_inthandler(void);
|
||
+asmlinkage void bad_inthandler(void);
|
||
+
|
||
extern e_vector vectors[];
|
||
|
||
#endif
|
||
diff -urN linux-i386/include/asm-m68k/uaccess.h linux-m68k/include/asm-m68k/uaccess.h
|
||
--- linux-i386/include/asm-m68k/uaccess.h 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/include/asm-m68k/uaccess.h 2006-06-23 16:34:41.000000000 +0200
|
||
@@ -4,8 +4,9 @@
|
||
/*
|
||
* User space memory access functions
|
||
*/
|
||
+#include <linux/compiler.h>
|
||
#include <linux/errno.h>
|
||
-#include <linux/sched.h>
|
||
+#include <linux/types.h>
|
||
#include <asm/segment.h>
|
||
|
||
#define VERIFY_READ 0
|
||
@@ -32,858 +33,335 @@
|
||
unsigned long insn, fixup;
|
||
};
|
||
|
||
+extern int __put_user_bad(void);
|
||
+extern int __get_user_bad(void);
|
||
+
|
||
+#define __put_user_asm(res, x, ptr, bwl, reg, err) \
|
||
+asm volatile ("\n" \
|
||
+ "1: moves."#bwl" %2,%1\n" \
|
||
+ "2:\n" \
|
||
+ " .section .fixup,\"ax\"\n" \
|
||
+ " .even\n" \
|
||
+ "10: moveq.l %3,%0\n" \
|
||
+ " jra 2b\n" \
|
||
+ " .previous\n" \
|
||
+ "\n" \
|
||
+ " .section __ex_table,\"a\"\n" \
|
||
+ " .align 4\n" \
|
||
+ " .long 1b,10b\n" \
|
||
+ " .long 2b,10b\n" \
|
||
+ " .previous" \
|
||
+ : "+d" (res), "=m" (*(ptr)) \
|
||
+ : #reg (x), "i" (err))
|
||
|
||
/*
|
||
* These are the main single-value transfer routines. They automatically
|
||
* use the right size if we just have the right pointer type.
|
||
*/
|
||
|
||
-#define put_user(x, ptr) \
|
||
-({ \
|
||
- int __pu_err; \
|
||
- typeof(*(ptr)) __pu_val = (x); \
|
||
- __chk_user_ptr(ptr); \
|
||
- switch (sizeof (*(ptr))) { \
|
||
- case 1: \
|
||
- __put_user_asm(__pu_err, __pu_val, ptr, b); \
|
||
- break; \
|
||
- case 2: \
|
||
- __put_user_asm(__pu_err, __pu_val, ptr, w); \
|
||
- break; \
|
||
- case 4: \
|
||
- __put_user_asm(__pu_err, __pu_val, ptr, l); \
|
||
- break; \
|
||
- case 8: \
|
||
- __pu_err = __constant_copy_to_user(ptr, &__pu_val, 8); \
|
||
- break; \
|
||
- default: \
|
||
- __pu_err = __put_user_bad(); \
|
||
- break; \
|
||
- } \
|
||
- __pu_err; \
|
||
+#define __put_user(x, ptr) \
|
||
+({ \
|
||
+ typeof(*(ptr)) __pu_val = (x); \
|
||
+ int __pu_err = 0; \
|
||
+ __chk_user_ptr(ptr); \
|
||
+ switch (sizeof (*(ptr))) { \
|
||
+ case 1: \
|
||
+ __put_user_asm(__pu_err, __pu_val, ptr, b, d, -EFAULT); \
|
||
+ break; \
|
||
+ case 2: \
|
||
+ __put_user_asm(__pu_err, __pu_val, ptr, w, d, -EFAULT); \
|
||
+ break; \
|
||
+ case 4: \
|
||
+ __put_user_asm(__pu_err, __pu_val, ptr, l, r, -EFAULT); \
|
||
+ break; \
|
||
+ case 8: \
|
||
+ { \
|
||
+ const void *__pu_ptr = (ptr); \
|
||
+ asm volatile ("\n" \
|
||
+ "1: moves.l %2,(%1)+\n" \
|
||
+ "2: moves.l %R2,(%1)\n" \
|
||
+ "3:\n" \
|
||
+ " .section .fixup,\"ax\"\n" \
|
||
+ " .even\n" \
|
||
+ "10: movel %3,%0\n" \
|
||
+ " jra 3b\n" \
|
||
+ " .previous\n" \
|
||
+ "\n" \
|
||
+ " .section __ex_table,\"a\"\n" \
|
||
+ " .align 4\n" \
|
||
+ " .long 1b,10b\n" \
|
||
+ " .long 2b,10b\n" \
|
||
+ " .long 3b,10b\n" \
|
||
+ " .previous" \
|
||
+ : "+d" (__pu_err), "+a" (__pu_ptr) \
|
||
+ : "r" (__pu_val), "i" (-EFAULT) \
|
||
+ : "memory"); \
|
||
+ break; \
|
||
+ } \
|
||
+ default: \
|
||
+ __pu_err = __put_user_bad(); \
|
||
+ break; \
|
||
+ } \
|
||
+ __pu_err; \
|
||
})
|
||
-#define __put_user(x, ptr) put_user(x, ptr)
|
||
+#define put_user(x, ptr) __put_user(x, ptr)
|
||
|
||
-extern int __put_user_bad(void);
|
||
|
||
-/*
|
||
- * Tell gcc we read from memory instead of writing: this is because
|
||
- * we do not write to any memory gcc knows about, so there are no
|
||
- * aliasing issues.
|
||
- */
|
||
-#define __put_user_asm(err,x,ptr,bwl) \
|
||
-__asm__ __volatile__ \
|
||
- ("21:moves" #bwl " %2,%1\n" \
|
||
- "1:\n" \
|
||
- ".section .fixup,\"ax\"\n" \
|
||
- " .even\n" \
|
||
- "2: movel %3,%0\n" \
|
||
- " jra 1b\n" \
|
||
- ".previous\n" \
|
||
- ".section __ex_table,\"a\"\n" \
|
||
- " .align 4\n" \
|
||
- " .long 21b,2b\n" \
|
||
- " .long 1b,2b\n" \
|
||
- ".previous" \
|
||
- : "=d"(err) \
|
||
- : "m"(*(ptr)), "r"(x), "i"(-EFAULT), "0"(0))
|
||
-
|
||
-#define get_user(x, ptr) \
|
||
-({ \
|
||
- int __gu_err; \
|
||
- typeof(*(ptr)) __gu_val; \
|
||
- __chk_user_ptr(ptr); \
|
||
- switch (sizeof(*(ptr))) { \
|
||
- case 1: \
|
||
- __get_user_asm(__gu_err, __gu_val, ptr, b, "=d"); \
|
||
- break; \
|
||
- case 2: \
|
||
- __get_user_asm(__gu_err, __gu_val, ptr, w, "=r"); \
|
||
- break; \
|
||
- case 4: \
|
||
- __get_user_asm(__gu_err, __gu_val, ptr, l, "=r"); \
|
||
- break; \
|
||
- case 8: \
|
||
- __gu_err = __constant_copy_from_user(&__gu_val, ptr, 8); \
|
||
- break; \
|
||
- default: \
|
||
- __gu_val = (typeof(*(ptr)))0; \
|
||
- __gu_err = __get_user_bad(); \
|
||
- break; \
|
||
- } \
|
||
- (x) = __gu_val; \
|
||
- __gu_err; \
|
||
+#define __get_user_asm(res, x, ptr, type, bwl, reg, err) ({ \
|
||
+ type __gu_val; \
|
||
+ asm volatile ("\n" \
|
||
+ "1: moves."#bwl" %2,%1\n" \
|
||
+ "2:\n" \
|
||
+ " .section .fixup,\"ax\"\n" \
|
||
+ " .even\n" \
|
||
+ "10: move.l %3,%0\n" \
|
||
+ " sub."#bwl" %1,%1\n" \
|
||
+ " jra 2b\n" \
|
||
+ " .previous\n" \
|
||
+ "\n" \
|
||
+ " .section __ex_table,\"a\"\n" \
|
||
+ " .align 4\n" \
|
||
+ " .long 1b,10b\n" \
|
||
+ " .previous" \
|
||
+ : "+d" (res), "=&" #reg (__gu_val) \
|
||
+ : "m" (*(ptr)), "i" (err)); \
|
||
+ (x) = (typeof(*(ptr)))(long)__gu_val; \
|
||
})
|
||
-#define __get_user(x, ptr) get_user(x, ptr)
|
||
-
|
||
-extern int __get_user_bad(void);
|
||
|
||
-#define __get_user_asm(err,x,ptr,bwl,reg) \
|
||
-__asm__ __volatile__ \
|
||
- ("1: moves" #bwl " %2,%1\n" \
|
||
- "2:\n" \
|
||
- ".section .fixup,\"ax\"\n" \
|
||
- " .even\n" \
|
||
- "3: movel %3,%0\n" \
|
||
- " sub" #bwl " %1,%1\n" \
|
||
- " jra 2b\n" \
|
||
- ".previous\n" \
|
||
- ".section __ex_table,\"a\"\n" \
|
||
- " .align 4\n" \
|
||
- " .long 1b,3b\n" \
|
||
- ".previous" \
|
||
- : "=d"(err), reg(x) \
|
||
- : "m"(*(ptr)), "i" (-EFAULT), "0"(0))
|
||
-
|
||
-static inline unsigned long
|
||
-__generic_copy_from_user(void *to, const void __user *from, unsigned long n)
|
||
-{
|
||
- unsigned long tmp;
|
||
- __asm__ __volatile__
|
||
- (" tstl %2\n"
|
||
- " jeq 2f\n"
|
||
- "1: movesl (%1)+,%3\n"
|
||
- " movel %3,(%0)+\n"
|
||
- " subql #1,%2\n"
|
||
- " jne 1b\n"
|
||
- "2: movel %4,%2\n"
|
||
- " bclr #1,%2\n"
|
||
- " jeq 4f\n"
|
||
- "3: movesw (%1)+,%3\n"
|
||
- " movew %3,(%0)+\n"
|
||
- "4: bclr #0,%2\n"
|
||
- " jeq 6f\n"
|
||
- "5: movesb (%1)+,%3\n"
|
||
- " moveb %3,(%0)+\n"
|
||
- "6:\n"
|
||
- ".section .fixup,\"ax\"\n"
|
||
- " .even\n"
|
||
- "7: movel %2,%%d0\n"
|
||
- "71:clrl (%0)+\n"
|
||
- " subql #1,%%d0\n"
|
||
- " jne 71b\n"
|
||
- " lsll #2,%2\n"
|
||
- " addl %4,%2\n"
|
||
- " btst #1,%4\n"
|
||
- " jne 81f\n"
|
||
- " btst #0,%4\n"
|
||
- " jne 91f\n"
|
||
- " jra 6b\n"
|
||
- "8: addql #2,%2\n"
|
||
- "81:clrw (%0)+\n"
|
||
- " btst #0,%4\n"
|
||
- " jne 91f\n"
|
||
- " jra 6b\n"
|
||
- "9: addql #1,%2\n"
|
||
- "91:clrb (%0)+\n"
|
||
- " jra 6b\n"
|
||
- ".previous\n"
|
||
- ".section __ex_table,\"a\"\n"
|
||
- " .align 4\n"
|
||
- " .long 1b,7b\n"
|
||
- " .long 3b,8b\n"
|
||
- " .long 5b,9b\n"
|
||
- ".previous"
|
||
- : "=a"(to), "=a"(from), "=d"(n), "=&d"(tmp)
|
||
- : "d"(n & 3), "0"(to), "1"(from), "2"(n/4)
|
||
- : "d0", "memory");
|
||
- return n;
|
||
-}
|
||
+#define __get_user(x, ptr) \
|
||
+({ \
|
||
+ int __gu_err = 0; \
|
||
+ __chk_user_ptr(ptr); \
|
||
+ switch (sizeof(*(ptr))) { \
|
||
+ case 1: \
|
||
+ __get_user_asm(__gu_err, x, ptr, u8, b, d, -EFAULT); \
|
||
+ break; \
|
||
+ case 2: \
|
||
+ __get_user_asm(__gu_err, x, ptr, u16, w, d, -EFAULT); \
|
||
+ break; \
|
||
+ case 4: \
|
||
+ __get_user_asm(__gu_err, x, ptr, u32, l, r, -EFAULT); \
|
||
+ break; \
|
||
+/* case 8: disabled because gcc-4.1 has a broken typeof \
|
||
+ { \
|
||
+ const void *__gu_ptr = (ptr); \
|
||
+ u64 __gu_val; \
|
||
+ asm volatile ("\n" \
|
||
+ "1: moves.l (%2)+,%1\n" \
|
||
+ "2: moves.l (%2),%R1\n" \
|
||
+ "3:\n" \
|
||
+ " .section .fixup,\"ax\"\n" \
|
||
+ " .even\n" \
|
||
+ "10: move.l %3,%0\n" \
|
||
+ " sub.l %1,%1\n" \
|
||
+ " sub.l %R1,%R1\n" \
|
||
+ " jra 3b\n" \
|
||
+ " .previous\n" \
|
||
+ "\n" \
|
||
+ " .section __ex_table,\"a\"\n" \
|
||
+ " .align 4\n" \
|
||
+ " .long 1b,10b\n" \
|
||
+ " .long 2b,10b\n" \
|
||
+ " .previous" \
|
||
+ : "+d" (__gu_err), "=&r" (__gu_val), \
|
||
+ "+a" (__gu_ptr) \
|
||
+ : "i" (-EFAULT) \
|
||
+ : "memory"); \
|
||
+ (x) = (typeof(*(ptr)))__gu_val; \
|
||
+ break; \
|
||
+ } */ \
|
||
+ default: \
|
||
+ __gu_err = __get_user_bad(); \
|
||
+ break; \
|
||
+ } \
|
||
+ __gu_err; \
|
||
+})
|
||
+#define get_user(x, ptr) __get_user(x, ptr)
|
||
|
||
-static inline unsigned long
|
||
-__generic_copy_to_user(void __user *to, const void *from, unsigned long n)
|
||
-{
|
||
- unsigned long tmp;
|
||
- __asm__ __volatile__
|
||
- (" tstl %2\n"
|
||
- " jeq 3f\n"
|
||
- "1: movel (%1)+,%3\n"
|
||
- "22:movesl %3,(%0)+\n"
|
||
- "2: subql #1,%2\n"
|
||
- " jne 1b\n"
|
||
- "3: movel %4,%2\n"
|
||
- " bclr #1,%2\n"
|
||
- " jeq 4f\n"
|
||
- " movew (%1)+,%3\n"
|
||
- "24:movesw %3,(%0)+\n"
|
||
- "4: bclr #0,%2\n"
|
||
- " jeq 5f\n"
|
||
- " moveb (%1)+,%3\n"
|
||
- "25:movesb %3,(%0)+\n"
|
||
- "5:\n"
|
||
- ".section .fixup,\"ax\"\n"
|
||
- " .even\n"
|
||
- "60:addql #1,%2\n"
|
||
- "6: lsll #2,%2\n"
|
||
- " addl %4,%2\n"
|
||
- " jra 5b\n"
|
||
- "7: addql #2,%2\n"
|
||
- " jra 5b\n"
|
||
- "8: addql #1,%2\n"
|
||
- " jra 5b\n"
|
||
- ".previous\n"
|
||
- ".section __ex_table,\"a\"\n"
|
||
- " .align 4\n"
|
||
- " .long 1b,60b\n"
|
||
- " .long 22b,6b\n"
|
||
- " .long 2b,6b\n"
|
||
- " .long 24b,7b\n"
|
||
- " .long 3b,60b\n"
|
||
- " .long 4b,7b\n"
|
||
- " .long 25b,8b\n"
|
||
- " .long 5b,8b\n"
|
||
- ".previous"
|
||
- : "=a"(to), "=a"(from), "=d"(n), "=&d"(tmp)
|
||
- : "r"(n & 3), "0"(to), "1"(from), "2"(n / 4)
|
||
- : "memory");
|
||
- return n;
|
||
-}
|
||
+unsigned long __generic_copy_from_user(void *to, const void __user *from, unsigned long n);
|
||
+unsigned long __generic_copy_to_user(void __user *to, const void *from, unsigned long n);
|
||
|
||
-#define __copy_from_user_big(to, from, n, fixup, copy) \
|
||
- __asm__ __volatile__ \
|
||
- ("10: movesl (%1)+,%%d0\n" \
|
||
- " movel %%d0,(%0)+\n" \
|
||
- " subql #1,%2\n" \
|
||
- " jne 10b\n" \
|
||
- ".section .fixup,\"ax\"\n" \
|
||
- " .even\n" \
|
||
- "11: movel %2,%%d0\n" \
|
||
- "13: clrl (%0)+\n" \
|
||
- " subql #1,%%d0\n" \
|
||
- " jne 13b\n" \
|
||
- " lsll #2,%2\n" \
|
||
- fixup "\n" \
|
||
- " jra 12f\n" \
|
||
- ".previous\n" \
|
||
- ".section __ex_table,\"a\"\n" \
|
||
- " .align 4\n" \
|
||
- " .long 10b,11b\n" \
|
||
- ".previous\n" \
|
||
- copy "\n" \
|
||
- "12:" \
|
||
- : "=a"(to), "=a"(from), "=d"(n) \
|
||
- : "0"(to), "1"(from), "2"(n/4) \
|
||
- : "d0", "memory")
|
||
+#define __constant_copy_from_user_asm(res, to, from, tmp, n, s1, s2, s3)\
|
||
+ asm volatile ("\n" \
|
||
+ "1: moves."#s1" (%2)+,%3\n" \
|
||
+ " move."#s1" %3,(%1)+\n" \
|
||
+ "2: moves."#s2" (%2)+,%3\n" \
|
||
+ " move."#s2" %3,(%1)+\n" \
|
||
+ " .ifnc \""#s3"\",\"\"\n" \
|
||
+ "3: moves."#s3" (%2)+,%3\n" \
|
||
+ " move."#s3" %3,(%1)+\n" \
|
||
+ " .endif\n" \
|
||
+ "4:\n" \
|
||
+ " .section __ex_table,\"a\"\n" \
|
||
+ " .align 4\n" \
|
||
+ " .long 1b,10f\n" \
|
||
+ " .long 2b,20f\n" \
|
||
+ " .ifnc \""#s3"\",\"\"\n" \
|
||
+ " .long 3b,30f\n" \
|
||
+ " .endif\n" \
|
||
+ " .previous\n" \
|
||
+ "\n" \
|
||
+ " .section .fixup,\"ax\"\n" \
|
||
+ " .even\n" \
|
||
+ "10: clr."#s1" (%1)+\n" \
|
||
+ "20: clr."#s2" (%1)+\n" \
|
||
+ " .ifnc \""#s3"\",\"\"\n" \
|
||
+ "30: clr."#s3" (%1)+\n" \
|
||
+ " .endif\n" \
|
||
+ " moveq.l #"#n",%0\n" \
|
||
+ " jra 4b\n" \
|
||
+ " .previous\n" \
|
||
+ : "+d" (res), "+&a" (to), "+a" (from), "=&d" (tmp) \
|
||
+ : : "memory")
|
||
|
||
-static inline unsigned long
|
||
+static __always_inline unsigned long
|
||
__constant_copy_from_user(void *to, const void __user *from, unsigned long n)
|
||
{
|
||
- switch (n) {
|
||
- case 0:
|
||
- break;
|
||
- case 1:
|
||
- __asm__ __volatile__
|
||
- ("1: movesb (%1)+,%%d0\n"
|
||
- " moveb %%d0,(%0)+\n"
|
||
- "2:\n"
|
||
- ".section .fixup,\"ax\"\n"
|
||
- " .even\n"
|
||
- "3: addql #1,%2\n"
|
||
- " clrb (%0)+\n"
|
||
- " jra 2b\n"
|
||
- ".previous\n"
|
||
- ".section __ex_table,\"a\"\n"
|
||
- " .align 4\n"
|
||
- " .long 1b,3b\n"
|
||
- ".previous"
|
||
- : "=a"(to), "=a"(from), "=d"(n)
|
||
- : "0"(to), "1"(from), "2"(0)
|
||
- : "d0", "memory");
|
||
- break;
|
||
- case 2:
|
||
- __asm__ __volatile__
|
||
- ("1: movesw (%1)+,%%d0\n"
|
||
- " movew %%d0,(%0)+\n"
|
||
- "2:\n"
|
||
- ".section .fixup,\"ax\"\n"
|
||
- " .even\n"
|
||
- "3: addql #2,%2\n"
|
||
- " clrw (%0)+\n"
|
||
- " jra 2b\n"
|
||
- ".previous\n"
|
||
- ".section __ex_table,\"a\"\n"
|
||
- " .align 4\n"
|
||
- " .long 1b,3b\n"
|
||
- ".previous"
|
||
- : "=a"(to), "=a"(from), "=d"(n)
|
||
- : "0"(to), "1"(from), "2"(0)
|
||
- : "d0", "memory");
|
||
- break;
|
||
- case 3:
|
||
- __asm__ __volatile__
|
||
- ("1: movesw (%1)+,%%d0\n"
|
||
- " movew %%d0,(%0)+\n"
|
||
- "2: movesb (%1)+,%%d0\n"
|
||
- " moveb %%d0,(%0)+\n"
|
||
- "3:"
|
||
- ".section .fixup,\"ax\"\n"
|
||
- " .even\n"
|
||
- "4: addql #2,%2\n"
|
||
- " clrw (%0)+\n"
|
||
- "5: addql #1,%2\n"
|
||
- " clrb (%0)+\n"
|
||
- " jra 3b\n"
|
||
- ".previous\n"
|
||
- ".section __ex_table,\"a\"\n"
|
||
- " .align 4\n"
|
||
- " .long 1b,4b\n"
|
||
- " .long 2b,5b\n"
|
||
- ".previous"
|
||
- : "=a"(to), "=a"(from), "=d"(n)
|
||
- : "0"(to), "1"(from), "2"(0)
|
||
- : "d0", "memory");
|
||
- break;
|
||
- case 4:
|
||
- __asm__ __volatile__
|
||
- ("1: movesl (%1)+,%%d0\n"
|
||
- " movel %%d0,(%0)+\n"
|
||
- "2:"
|
||
- ".section .fixup,\"ax\"\n"
|
||
- " .even\n"
|
||
- "3: addql #4,%2\n"
|
||
- " clrl (%0)+\n"
|
||
- " jra 2b\n"
|
||
- ".previous\n"
|
||
- ".section __ex_table,\"a\"\n"
|
||
- " .align 4\n"
|
||
- " .long 1b,3b\n"
|
||
- ".previous"
|
||
- : "=a"(to), "=a"(from), "=d"(n)
|
||
- : "0"(to), "1"(from), "2"(0)
|
||
- : "d0", "memory");
|
||
- break;
|
||
- case 8:
|
||
- __asm__ __volatile__
|
||
- ("1: movesl (%1)+,%%d0\n"
|
||
- " movel %%d0,(%0)+\n"
|
||
- "2: movesl (%1)+,%%d0\n"
|
||
- " movel %%d0,(%0)+\n"
|
||
- "3:"
|
||
- ".section .fixup,\"ax\"\n"
|
||
- " .even\n"
|
||
- "4: addql #4,%2\n"
|
||
- " clrl (%0)+\n"
|
||
- "5: addql #4,%2\n"
|
||
- " clrl (%0)+\n"
|
||
- " jra 3b\n"
|
||
- ".previous\n"
|
||
- ".section __ex_table,\"a\"\n"
|
||
- " .align 4\n"
|
||
- " .long 1b,4b\n"
|
||
- " .long 2b,5b\n"
|
||
- ".previous"
|
||
- : "=a"(to), "=a"(from), "=d"(n)
|
||
- : "0"(to), "1"(from), "2"(0)
|
||
- : "d0", "memory");
|
||
- break;
|
||
- case 12:
|
||
- __asm__ __volatile__
|
||
- ("1: movesl (%1)+,%%d0\n"
|
||
- " movel %%d0,(%0)+\n"
|
||
- "2: movesl (%1)+,%%d0\n"
|
||
- " movel %%d0,(%0)+\n"
|
||
- "3: movesl (%1)+,%%d0\n"
|
||
- " movel %%d0,(%0)+\n"
|
||
- "4:"
|
||
- ".section .fixup,\"ax\"\n"
|
||
- " .even\n"
|
||
- "5: addql #4,%2\n"
|
||
- " clrl (%0)+\n"
|
||
- "6: addql #4,%2\n"
|
||
- " clrl (%0)+\n"
|
||
- "7: addql #4,%2\n"
|
||
- " clrl (%0)+\n"
|
||
- " jra 4b\n"
|
||
- ".previous\n"
|
||
- ".section __ex_table,\"a\"\n"
|
||
- " .align 4\n"
|
||
- " .long 1b,5b\n"
|
||
- " .long 2b,6b\n"
|
||
- " .long 3b,7b\n"
|
||
- ".previous"
|
||
- : "=a"(to), "=a"(from), "=d"(n)
|
||
- : "0"(to), "1"(from), "2"(0)
|
||
- : "d0", "memory");
|
||
- break;
|
||
- case 16:
|
||
- __asm__ __volatile__
|
||
- ("1: movesl (%1)+,%%d0\n"
|
||
- " movel %%d0,(%0)+\n"
|
||
- "2: movesl (%1)+,%%d0\n"
|
||
- " movel %%d0,(%0)+\n"
|
||
- "3: movesl (%1)+,%%d0\n"
|
||
- " movel %%d0,(%0)+\n"
|
||
- "4: movesl (%1)+,%%d0\n"
|
||
- " movel %%d0,(%0)+\n"
|
||
- "5:"
|
||
- ".section .fixup,\"ax\"\n"
|
||
- " .even\n"
|
||
- "6: addql #4,%2\n"
|
||
- " clrl (%0)+\n"
|
||
- "7: addql #4,%2\n"
|
||
- " clrl (%0)+\n"
|
||
- "8: addql #4,%2\n"
|
||
- " clrl (%0)+\n"
|
||
- "9: addql #4,%2\n"
|
||
- " clrl (%0)+\n"
|
||
- " jra 5b\n"
|
||
- ".previous\n"
|
||
- ".section __ex_table,\"a\"\n"
|
||
- " .align 4\n"
|
||
- " .long 1b,6b\n"
|
||
- " .long 2b,7b\n"
|
||
- " .long 3b,8b\n"
|
||
- " .long 4b,9b\n"
|
||
- ".previous"
|
||
- : "=a"(to), "=a"(from), "=d"(n)
|
||
- : "0"(to), "1"(from), "2"(0)
|
||
- : "d0", "memory");
|
||
- break;
|
||
- default:
|
||
- switch (n & 3) {
|
||
- case 0:
|
||
- __copy_from_user_big(to, from, n, "", "");
|
||
- break;
|
||
+ unsigned long res = 0, tmp;
|
||
+
|
||
+ switch (n) {
|
||
case 1:
|
||
- __copy_from_user_big(to, from, n,
|
||
- /* fixup */
|
||
- "1: addql #1,%2\n"
|
||
- " clrb (%0)+",
|
||
- /* copy */
|
||
- "2: movesb (%1)+,%%d0\n"
|
||
- " moveb %%d0,(%0)+\n"
|
||
- ".section __ex_table,\"a\"\n"
|
||
- " .long 2b,1b\n"
|
||
- ".previous");
|
||
- break;
|
||
+ __get_user_asm(res, *(u8 *)to, (u8 *)from, u8, b, d, 1);
|
||
+ break;
|
||
case 2:
|
||
- __copy_from_user_big(to, from, n,
|
||
- /* fixup */
|
||
- "1: addql #2,%2\n"
|
||
- " clrw (%0)+",
|
||
- /* copy */
|
||
- "2: movesw (%1)+,%%d0\n"
|
||
- " movew %%d0,(%0)+\n"
|
||
- ".section __ex_table,\"a\"\n"
|
||
- " .long 2b,1b\n"
|
||
- ".previous");
|
||
- break;
|
||
+ __get_user_asm(res, *(u16 *)to, (u16 *)from, u16, w, d, 2);
|
||
+ break;
|
||
case 3:
|
||
- __copy_from_user_big(to, from, n,
|
||
- /* fixup */
|
||
- "1: addql #2,%2\n"
|
||
- " clrw (%0)+\n"
|
||
- "2: addql #1,%2\n"
|
||
- " clrb (%0)+",
|
||
- /* copy */
|
||
- "3: movesw (%1)+,%%d0\n"
|
||
- " movew %%d0,(%0)+\n"
|
||
- "4: movesb (%1)+,%%d0\n"
|
||
- " moveb %%d0,(%0)+\n"
|
||
- ".section __ex_table,\"a\"\n"
|
||
- " .long 3b,1b\n"
|
||
- " .long 4b,2b\n"
|
||
- ".previous");
|
||
- break;
|
||
+ __constant_copy_from_user_asm(res, to, from, tmp, 3, w, b,);
|
||
+ break;
|
||
+ case 4:
|
||
+ __get_user_asm(res, *(u32 *)to, (u32 *)from, u32, l, r, 4);
|
||
+ break;
|
||
+ case 5:
|
||
+ __constant_copy_from_user_asm(res, to, from, tmp, 5, l, b,);
|
||
+ break;
|
||
+ case 6:
|
||
+ __constant_copy_from_user_asm(res, to, from, tmp, 6, l, w,);
|
||
+ break;
|
||
+ case 7:
|
||
+ __constant_copy_from_user_asm(res, to, from, tmp, 7, l, w, b);
|
||
+ break;
|
||
+ case 8:
|
||
+ __constant_copy_from_user_asm(res, to, from, tmp, 8, l, l,);
|
||
+ break;
|
||
+ case 9:
|
||
+ __constant_copy_from_user_asm(res, to, from, tmp, 9, l, l, b);
|
||
+ break;
|
||
+ case 10:
|
||
+ __constant_copy_from_user_asm(res, to, from, tmp, 10, l, l, w);
|
||
+ break;
|
||
+ case 12:
|
||
+ __constant_copy_from_user_asm(res, to, from, tmp, 12, l, l, l);
|
||
+ break;
|
||
+ default:
|
||
+ /* we limit the inlined version to 3 moves */
|
||
+ return __generic_copy_from_user(to, from, n);
|
||
}
|
||
- break;
|
||
- }
|
||
- return n;
|
||
-}
|
||
|
||
-#define __copy_to_user_big(to, from, n, fixup, copy) \
|
||
- __asm__ __volatile__ \
|
||
- ("10: movel (%1)+,%%d0\n" \
|
||
- "31: movesl %%d0,(%0)+\n" \
|
||
- "11: subql #1,%2\n" \
|
||
- " jne 10b\n" \
|
||
- "41:\n" \
|
||
- ".section .fixup,\"ax\"\n" \
|
||
- " .even\n" \
|
||
- "22: addql #1,%2\n" \
|
||
- "12: lsll #2,%2\n" \
|
||
- fixup "\n" \
|
||
- " jra 13f\n" \
|
||
- ".previous\n" \
|
||
- ".section __ex_table,\"a\"\n" \
|
||
- " .align 4\n" \
|
||
- " .long 10b,22b\n" \
|
||
- " .long 31b,12b\n" \
|
||
- " .long 11b,12b\n" \
|
||
- " .long 41b,22b\n" \
|
||
- ".previous\n" \
|
||
- copy "\n" \
|
||
- "13:" \
|
||
- : "=a"(to), "=a"(from), "=d"(n) \
|
||
- : "0"(to), "1"(from), "2"(n/4) \
|
||
- : "d0", "memory")
|
||
+ return res;
|
||
+}
|
||
|
||
-#define __copy_to_user_inatomic __copy_to_user
|
||
-#define __copy_from_user_inatomic __copy_from_user
|
||
+#define __constant_copy_to_user_asm(res, to, from, tmp, n, s1, s2, s3) \
|
||
+ asm volatile ("\n" \
|
||
+ " move."#s1" (%2)+,%3\n" \
|
||
+ "11: moves."#s1" %3,(%1)+\n" \
|
||
+ "12: move."#s2" (%2)+,%3\n" \
|
||
+ "21: moves."#s2" %3,(%1)+\n" \
|
||
+ "22:\n" \
|
||
+ " .ifnc \""#s3"\",\"\"\n" \
|
||
+ " move."#s3" (%2)+,%3\n" \
|
||
+ "31: moves."#s3" %3,(%1)+\n" \
|
||
+ "32:\n" \
|
||
+ " .endif\n" \
|
||
+ "4:\n" \
|
||
+ "\n" \
|
||
+ " .section __ex_table,\"a\"\n" \
|
||
+ " .align 4\n" \
|
||
+ " .long 11b,5f\n" \
|
||
+ " .long 12b,5f\n" \
|
||
+ " .long 21b,5f\n" \
|
||
+ " .long 22b,5f\n" \
|
||
+ " .ifnc \""#s3"\",\"\"\n" \
|
||
+ " .long 31b,5f\n" \
|
||
+ " .long 32b,5f\n" \
|
||
+ " .endif\n" \
|
||
+ " .previous\n" \
|
||
+ "\n" \
|
||
+ " .section .fixup,\"ax\"\n" \
|
||
+ " .even\n" \
|
||
+ "5: moveq.l #"#n",%0\n" \
|
||
+ " jra 4b\n" \
|
||
+ " .previous\n" \
|
||
+ : "+d" (res), "+a" (to), "+a" (from), "=&d" (tmp) \
|
||
+ : : "memory")
|
||
|
||
-static inline unsigned long
|
||
+static __always_inline unsigned long
|
||
__constant_copy_to_user(void __user *to, const void *from, unsigned long n)
|
||
{
|
||
- switch (n) {
|
||
- case 0:
|
||
- break;
|
||
- case 1:
|
||
- __asm__ __volatile__
|
||
- (" moveb (%1)+,%%d0\n"
|
||
- "21:movesb %%d0,(%0)+\n"
|
||
- "1:\n"
|
||
- ".section .fixup,\"ax\"\n"
|
||
- " .even\n"
|
||
- "2: addql #1,%2\n"
|
||
- " jra 1b\n"
|
||
- ".previous\n"
|
||
- ".section __ex_table,\"a\"\n"
|
||
- " .align 4\n "
|
||
- " .long 21b,2b\n"
|
||
- " .long 1b,2b\n"
|
||
- ".previous"
|
||
- : "=a"(to), "=a"(from), "=d"(n)
|
||
- : "0"(to), "1"(from), "2"(0)
|
||
- : "d0", "memory");
|
||
- break;
|
||
- case 2:
|
||
- __asm__ __volatile__
|
||
- (" movew (%1)+,%%d0\n"
|
||
- "21:movesw %%d0,(%0)+\n"
|
||
- "1:\n"
|
||
- ".section .fixup,\"ax\"\n"
|
||
- " .even\n"
|
||
- "2: addql #2,%2\n"
|
||
- " jra 1b\n"
|
||
- ".previous\n"
|
||
- ".section __ex_table,\"a\"\n"
|
||
- " .align 4\n"
|
||
- " .long 21b,2b\n"
|
||
- " .long 1b,2b\n"
|
||
- ".previous"
|
||
- : "=a"(to), "=a"(from), "=d"(n)
|
||
- : "0"(to), "1"(from), "2"(0)
|
||
- : "d0", "memory");
|
||
- break;
|
||
- case 3:
|
||
- __asm__ __volatile__
|
||
- (" movew (%1)+,%%d0\n"
|
||
- "21:movesw %%d0,(%0)+\n"
|
||
- "1: moveb (%1)+,%%d0\n"
|
||
- "22:movesb %%d0,(%0)+\n"
|
||
- "2:\n"
|
||
- ".section .fixup,\"ax\"\n"
|
||
- " .even\n"
|
||
- "3: addql #2,%2\n"
|
||
- "4: addql #1,%2\n"
|
||
- " jra 2b\n"
|
||
- ".previous\n"
|
||
- ".section __ex_table,\"a\"\n"
|
||
- " .align 4\n"
|
||
- " .long 21b,3b\n"
|
||
- " .long 1b,3b\n"
|
||
- " .long 22b,4b\n"
|
||
- " .long 2b,4b\n"
|
||
- ".previous"
|
||
- : "=a"(to), "=a"(from), "=d"(n)
|
||
- : "0"(to), "1"(from), "2"(0)
|
||
- : "d0", "memory");
|
||
- break;
|
||
- case 4:
|
||
- __asm__ __volatile__
|
||
- (" movel (%1)+,%%d0\n"
|
||
- "21:movesl %%d0,(%0)+\n"
|
||
- "1:\n"
|
||
- ".section .fixup,\"ax\"\n"
|
||
- " .even\n"
|
||
- "2: addql #4,%2\n"
|
||
- " jra 1b\n"
|
||
- ".previous\n"
|
||
- ".section __ex_table,\"a\"\n"
|
||
- " .align 4\n"
|
||
- " .long 21b,2b\n"
|
||
- " .long 1b,2b\n"
|
||
- ".previous"
|
||
- : "=a"(to), "=a"(from), "=d"(n)
|
||
- : "0"(to), "1"(from), "2"(0)
|
||
- : "d0", "memory");
|
||
- break;
|
||
- case 8:
|
||
- __asm__ __volatile__
|
||
- (" movel (%1)+,%%d0\n"
|
||
- "21:movesl %%d0,(%0)+\n"
|
||
- "1: movel (%1)+,%%d0\n"
|
||
- "22:movesl %%d0,(%0)+\n"
|
||
- "2:\n"
|
||
- ".section .fixup,\"ax\"\n"
|
||
- " .even\n"
|
||
- "3: addql #4,%2\n"
|
||
- "4: addql #4,%2\n"
|
||
- " jra 2b\n"
|
||
- ".previous\n"
|
||
- ".section __ex_table,\"a\"\n"
|
||
- " .align 4\n"
|
||
- " .long 21b,3b\n"
|
||
- " .long 1b,3b\n"
|
||
- " .long 22b,4b\n"
|
||
- " .long 2b,4b\n"
|
||
- ".previous"
|
||
- : "=a"(to), "=a"(from), "=d"(n)
|
||
- : "0"(to), "1"(from), "2"(0)
|
||
- : "d0", "memory");
|
||
- break;
|
||
- case 12:
|
||
- __asm__ __volatile__
|
||
- (" movel (%1)+,%%d0\n"
|
||
- "21:movesl %%d0,(%0)+\n"
|
||
- "1: movel (%1)+,%%d0\n"
|
||
- "22:movesl %%d0,(%0)+\n"
|
||
- "2: movel (%1)+,%%d0\n"
|
||
- "23:movesl %%d0,(%0)+\n"
|
||
- "3:\n"
|
||
- ".section .fixup,\"ax\"\n"
|
||
- " .even\n"
|
||
- "4: addql #4,%2\n"
|
||
- "5: addql #4,%2\n"
|
||
- "6: addql #4,%2\n"
|
||
- " jra 3b\n"
|
||
- ".previous\n"
|
||
- ".section __ex_table,\"a\"\n"
|
||
- " .align 4\n"
|
||
- " .long 21b,4b\n"
|
||
- " .long 1b,4b\n"
|
||
- " .long 22b,5b\n"
|
||
- " .long 2b,5b\n"
|
||
- " .long 23b,6b\n"
|
||
- " .long 3b,6b\n"
|
||
- ".previous"
|
||
- : "=a"(to), "=a"(from), "=d"(n)
|
||
- : "0"(to), "1"(from), "2"(0)
|
||
- : "d0", "memory");
|
||
- break;
|
||
- case 16:
|
||
- __asm__ __volatile__
|
||
- (" movel (%1)+,%%d0\n"
|
||
- "21:movesl %%d0,(%0)+\n"
|
||
- "1: movel (%1)+,%%d0\n"
|
||
- "22:movesl %%d0,(%0)+\n"
|
||
- "2: movel (%1)+,%%d0\n"
|
||
- "23:movesl %%d0,(%0)+\n"
|
||
- "3: movel (%1)+,%%d0\n"
|
||
- "24:movesl %%d0,(%0)+\n"
|
||
- "4:"
|
||
- ".section .fixup,\"ax\"\n"
|
||
- " .even\n"
|
||
- "5: addql #4,%2\n"
|
||
- "6: addql #4,%2\n"
|
||
- "7: addql #4,%2\n"
|
||
- "8: addql #4,%2\n"
|
||
- " jra 4b\n"
|
||
- ".previous\n"
|
||
- ".section __ex_table,\"a\"\n"
|
||
- " .align 4\n"
|
||
- " .long 21b,5b\n"
|
||
- " .long 1b,5b\n"
|
||
- " .long 22b,6b\n"
|
||
- " .long 2b,6b\n"
|
||
- " .long 23b,7b\n"
|
||
- " .long 3b,7b\n"
|
||
- " .long 24b,8b\n"
|
||
- " .long 4b,8b\n"
|
||
- ".previous"
|
||
- : "=a"(to), "=a"(from), "=d"(n)
|
||
- : "0"(to), "1"(from), "2"(0)
|
||
- : "d0", "memory");
|
||
- break;
|
||
- default:
|
||
- switch (n & 3) {
|
||
- case 0:
|
||
- __copy_to_user_big(to, from, n, "", "");
|
||
- break;
|
||
+ unsigned long res = 0, tmp;
|
||
+
|
||
+ switch (n) {
|
||
case 1:
|
||
- __copy_to_user_big(to, from, n,
|
||
- /* fixup */
|
||
- "1: addql #1,%2",
|
||
- /* copy */
|
||
- " moveb (%1)+,%%d0\n"
|
||
- "22:movesb %%d0,(%0)+\n"
|
||
- "2:"
|
||
- ".section __ex_table,\"a\"\n"
|
||
- " .long 22b,1b\n"
|
||
- " .long 2b,1b\n"
|
||
- ".previous");
|
||
- break;
|
||
+ __put_user_asm(res, *(u8 *)from, (u8 *)to, b, d, 1);
|
||
+ break;
|
||
case 2:
|
||
- __copy_to_user_big(to, from, n,
|
||
- /* fixup */
|
||
- "1: addql #2,%2",
|
||
- /* copy */
|
||
- " movew (%1)+,%%d0\n"
|
||
- "22:movesw %%d0,(%0)+\n"
|
||
- "2:"
|
||
- ".section __ex_table,\"a\"\n"
|
||
- " .long 22b,1b\n"
|
||
- " .long 2b,1b\n"
|
||
- ".previous");
|
||
- break;
|
||
+ __put_user_asm(res, *(u16 *)from, (u16 *)to, w, d, 2);
|
||
+ break;
|
||
case 3:
|
||
- __copy_to_user_big(to, from, n,
|
||
- /* fixup */
|
||
- "1: addql #2,%2\n"
|
||
- "2: addql #1,%2",
|
||
- /* copy */
|
||
- " movew (%1)+,%%d0\n"
|
||
- "23:movesw %%d0,(%0)+\n"
|
||
- "3: moveb (%1)+,%%d0\n"
|
||
- "24:movesb %%d0,(%0)+\n"
|
||
- "4:"
|
||
- ".section __ex_table,\"a\"\n"
|
||
- " .long 23b,1b\n"
|
||
- " .long 3b,1b\n"
|
||
- " .long 24b,2b\n"
|
||
- " .long 4b,2b\n"
|
||
- ".previous");
|
||
- break;
|
||
+ __constant_copy_to_user_asm(res, to, from, tmp, 3, w, b,);
|
||
+ break;
|
||
+ case 4:
|
||
+ __put_user_asm(res, *(u32 *)from, (u32 *)to, l, r, 4);
|
||
+ break;
|
||
+ case 5:
|
||
+ __constant_copy_to_user_asm(res, to, from, tmp, 5, l, b,);
|
||
+ break;
|
||
+ case 6:
|
||
+ __constant_copy_to_user_asm(res, to, from, tmp, 6, l, w,);
|
||
+ break;
|
||
+ case 7:
|
||
+ __constant_copy_to_user_asm(res, to, from, tmp, 7, l, w, b);
|
||
+ break;
|
||
+ case 8:
|
||
+ __constant_copy_to_user_asm(res, to, from, tmp, 8, l, l,);
|
||
+ break;
|
||
+ case 9:
|
||
+ __constant_copy_to_user_asm(res, to, from, tmp, 9, l, l, b);
|
||
+ break;
|
||
+ case 10:
|
||
+ __constant_copy_to_user_asm(res, to, from, tmp, 10, l, l, w);
|
||
+ break;
|
||
+ case 12:
|
||
+ __constant_copy_to_user_asm(res, to, from, tmp, 12, l, l, l);
|
||
+ break;
|
||
+ default:
|
||
+ /* limit the inlined version to 3 moves */
|
||
+ return __generic_copy_to_user(to, from, n);
|
||
}
|
||
- break;
|
||
- }
|
||
- return n;
|
||
+
|
||
+ return res;
|
||
}
|
||
|
||
-#define copy_from_user(to, from, n) \
|
||
+#define __copy_from_user(to, from, n) \
|
||
(__builtin_constant_p(n) ? \
|
||
__constant_copy_from_user(to, from, n) : \
|
||
__generic_copy_from_user(to, from, n))
|
||
|
||
-#define copy_to_user(to, from, n) \
|
||
+#define __copy_to_user(to, from, n) \
|
||
(__builtin_constant_p(n) ? \
|
||
__constant_copy_to_user(to, from, n) : \
|
||
__generic_copy_to_user(to, from, n))
|
||
|
||
-#define __copy_from_user(to, from, n) copy_from_user(to, from, n)
|
||
-#define __copy_to_user(to, from, n) copy_to_user(to, from, n)
|
||
+#define __copy_to_user_inatomic __copy_to_user
|
||
+#define __copy_from_user_inatomic __copy_from_user
|
||
|
||
-/*
|
||
- * Copy a null terminated string from userspace.
|
||
- */
|
||
-
|
||
-static inline long
|
||
-strncpy_from_user(char *dst, const char __user *src, long count)
|
||
-{
|
||
- long res;
|
||
- if (count == 0) return count;
|
||
- __asm__ __volatile__
|
||
- ("1: movesb (%2)+,%%d0\n"
|
||
- "12:moveb %%d0,(%1)+\n"
|
||
- " jeq 2f\n"
|
||
- " subql #1,%3\n"
|
||
- " jne 1b\n"
|
||
- "2: subl %3,%0\n"
|
||
- "3:\n"
|
||
- ".section .fixup,\"ax\"\n"
|
||
- " .even\n"
|
||
- "4: movel %4,%0\n"
|
||
- " jra 3b\n"
|
||
- ".previous\n"
|
||
- ".section __ex_table,\"a\"\n"
|
||
- " .align 4\n"
|
||
- " .long 1b,4b\n"
|
||
- " .long 12b,4b\n"
|
||
- ".previous"
|
||
- : "=d"(res), "=a"(dst), "=a"(src), "=d"(count)
|
||
- : "i"(-EFAULT), "0"(count), "1"(dst), "2"(src), "3"(count)
|
||
- : "d0", "memory");
|
||
- return res;
|
||
-}
|
||
+#define copy_from_user(to, from, n) __copy_from_user(to, from, n)
|
||
+#define copy_to_user(to, from, n) __copy_to_user(to, from, n)
|
||
|
||
-/*
|
||
- * Return the size of a string (including the ending 0)
|
||
- *
|
||
- * Return 0 on exception, a value greater than N if too long
|
||
- */
|
||
-static inline long strnlen_user(const char __user *src, long n)
|
||
-{
|
||
- long res;
|
||
-
|
||
- res = -(unsigned long)src;
|
||
- __asm__ __volatile__
|
||
- ("1:\n"
|
||
- " tstl %2\n"
|
||
- " jeq 3f\n"
|
||
- "2: movesb (%1)+,%%d0\n"
|
||
- "22:\n"
|
||
- " subql #1,%2\n"
|
||
- " tstb %%d0\n"
|
||
- " jne 1b\n"
|
||
- " jra 4f\n"
|
||
- "3:\n"
|
||
- " addql #1,%0\n"
|
||
- "4:\n"
|
||
- " addl %1,%0\n"
|
||
- "5:\n"
|
||
- ".section .fixup,\"ax\"\n"
|
||
- " .even\n"
|
||
- "6: moveq %3,%0\n"
|
||
- " jra 5b\n"
|
||
- ".previous\n"
|
||
- ".section __ex_table,\"a\"\n"
|
||
- " .align 4\n"
|
||
- " .long 2b,6b\n"
|
||
- " .long 22b,6b\n"
|
||
- ".previous"
|
||
- : "=d"(res), "=a"(src), "=d"(n)
|
||
- : "i"(0), "0"(res), "1"(src), "2"(n)
|
||
- : "d0");
|
||
- return res;
|
||
-}
|
||
+long strncpy_from_user(char *dst, const char __user *src, long count);
|
||
+long strnlen_user(const char __user *src, long n);
|
||
+unsigned long clear_user(void __user *to, unsigned long n);
|
||
|
||
#define strlen_user(str) strnlen_user(str, 32767)
|
||
|
||
-/*
|
||
- * Zero Userspace
|
||
- */
|
||
-
|
||
-static inline unsigned long
|
||
-clear_user(void __user *to, unsigned long n)
|
||
-{
|
||
- __asm__ __volatile__
|
||
- (" tstl %1\n"
|
||
- " jeq 3f\n"
|
||
- "1: movesl %3,(%0)+\n"
|
||
- "2: subql #1,%1\n"
|
||
- " jne 1b\n"
|
||
- "3: movel %2,%1\n"
|
||
- " bclr #1,%1\n"
|
||
- " jeq 4f\n"
|
||
- "24:movesw %3,(%0)+\n"
|
||
- "4: bclr #0,%1\n"
|
||
- " jeq 5f\n"
|
||
- "25:movesb %3,(%0)+\n"
|
||
- "5:\n"
|
||
- ".section .fixup,\"ax\"\n"
|
||
- " .even\n"
|
||
- "61:addql #1,%1\n"
|
||
- "6: lsll #2,%1\n"
|
||
- " addl %2,%1\n"
|
||
- " jra 5b\n"
|
||
- "7: addql #2,%1\n"
|
||
- " jra 5b\n"
|
||
- "8: addql #1,%1\n"
|
||
- " jra 5b\n"
|
||
- ".previous\n"
|
||
- ".section __ex_table,\"a\"\n"
|
||
- " .align 4\n"
|
||
- " .long 1b,61b\n"
|
||
- " .long 2b,6b\n"
|
||
- " .long 3b,61b\n"
|
||
- " .long 24b,7b\n"
|
||
- " .long 4b,7b\n"
|
||
- " .long 25b,8b\n"
|
||
- " .long 5b,8b\n"
|
||
- ".previous"
|
||
- : "=a"(to), "=d"(n)
|
||
- : "r"(n & 3), "r"(0), "0"(to), "1"(n/4));
|
||
- return n;
|
||
-}
|
||
-
|
||
#endif /* _M68K_UACCESS_H */
|
||
diff -urN linux-i386/include/asm-m68k/unistd.h linux-m68k/include/asm-m68k/unistd.h
|
||
--- linux-i386/include/asm-m68k/unistd.h 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/include/asm-m68k/unistd.h 2006-02-11 17:28:36.000000000 +0100
|
||
@@ -284,8 +284,13 @@
|
||
#define __NR_add_key 279
|
||
#define __NR_request_key 280
|
||
#define __NR_keyctl 281
|
||
+#define __NR_ioprio_set 282
|
||
+#define __NR_ioprio_get 283
|
||
+#define __NR_inotify_init 284
|
||
+#define __NR_inotify_add_watch 285
|
||
+#define __NR_inotify_rm_watch 286
|
||
|
||
-#define NR_syscalls 282
|
||
+#define NR_syscalls 287
|
||
|
||
/* user-visible error numbers are in the range -1 - -124: see
|
||
<asm-m68k/errno.h> */
|
||
diff -urN linux-i386/include/linux/adb.h linux-m68k/include/linux/adb.h
|
||
--- linux-i386/include/linux/adb.h 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/include/linux/adb.h 2006-06-18 19:10:20.000000000 +0200
|
||
@@ -76,6 +76,7 @@
|
||
#define ADBREQ_REPLY 1 /* expect reply */
|
||
#define ADBREQ_SYNC 2 /* poll until done */
|
||
#define ADBREQ_NOSEND 4 /* build the request, but don't send it */
|
||
+#define ADBREQ_RAW 8 /* send raw packet (don't prepend ADB_PACKET) */
|
||
|
||
/* Messages sent thru the client_list notifier. You should NOT stop
|
||
the operation, at least not with this version */
|
||
diff -urN linux-i386/include/linux/bootmem.h linux-m68k/include/linux/bootmem.h
|
||
--- linux-i386/include/linux/bootmem.h 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/include/linux/bootmem.h 2006-06-18 19:10:21.000000000 +0200
|
||
@@ -61,11 +61,11 @@
|
||
#define alloc_bootmem(x) \
|
||
__alloc_bootmem((x), SMP_CACHE_BYTES, __pa(MAX_DMA_ADDRESS))
|
||
#define alloc_bootmem_low(x) \
|
||
- __alloc_bootmem_low((x), SMP_CACHE_BYTES, 0)
|
||
+ __alloc_bootmem_low((x), SMP_CACHE_BYTES, __pa(PAGE_OFFSET))
|
||
#define alloc_bootmem_pages(x) \
|
||
__alloc_bootmem((x), PAGE_SIZE, __pa(MAX_DMA_ADDRESS))
|
||
#define alloc_bootmem_low_pages(x) \
|
||
- __alloc_bootmem_low((x), PAGE_SIZE, 0)
|
||
+ __alloc_bootmem_low((x), PAGE_SIZE, __pa(PAGE_OFFSET))
|
||
#endif /* !CONFIG_HAVE_ARCH_BOOTMEM_NODE */
|
||
extern unsigned long __init free_all_bootmem (void);
|
||
extern void * __init __alloc_bootmem_node (pg_data_t *pgdat, unsigned long size, unsigned long align, unsigned long goal);
|
||
diff -urN linux-i386/include/linux/file.h linux-m68k/include/linux/file.h
|
||
--- linux-i386/include/linux/file.h 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/include/linux/file.h 2006-06-18 19:10:21.000000000 +0200
|
||
@@ -5,7 +5,6 @@
|
||
#ifndef __LINUX_FILE_H
|
||
#define __LINUX_FILE_H
|
||
|
||
-#include <asm/atomic.h>
|
||
#include <linux/posix_types.h>
|
||
#include <linux/compiler.h>
|
||
#include <linux/spinlock.h>
|
||
diff -urN linux-i386/include/linux/ide.h linux-m68k/include/linux/ide.h
|
||
--- linux-i386/include/linux/ide.h 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/include/linux/ide.h 2006-06-18 19:10:21.000000000 +0200
|
||
@@ -510,7 +510,7 @@
|
||
* sense_key : Sense key of the last failed packet command
|
||
*/
|
||
typedef union {
|
||
- unsigned all :8;
|
||
+ u8 all;
|
||
struct {
|
||
#if defined(__LITTLE_ENDIAN_BITFIELD)
|
||
unsigned ili :1;
|
||
diff -urN linux-i386/include/linux/init_task.h linux-m68k/include/linux/init_task.h
|
||
--- linux-i386/include/linux/init_task.h 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/include/linux/init_task.h 2006-06-18 19:10:21.000000000 +0200
|
||
@@ -81,7 +81,7 @@
|
||
#define INIT_TASK(tsk) \
|
||
{ \
|
||
.state = 0, \
|
||
- .thread_info = &init_thread_info, \
|
||
+ .stack = &init_stack, \
|
||
.usage = ATOMIC_INIT(2), \
|
||
.flags = 0, \
|
||
.lock_depth = -1, \
|
||
diff -urN linux-i386/include/linux/kernel_stat.h linux-m68k/include/linux/kernel_stat.h
|
||
--- linux-i386/include/linux/kernel_stat.h 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/include/linux/kernel_stat.h 2006-06-18 19:10:21.000000000 +0200
|
||
@@ -2,12 +2,12 @@
|
||
#define _LINUX_KERNEL_STAT_H
|
||
|
||
#include <linux/config.h>
|
||
-#include <asm/irq.h>
|
||
#include <linux/smp.h>
|
||
#include <linux/threads.h>
|
||
#include <linux/percpu.h>
|
||
#include <linux/cpumask.h>
|
||
#include <asm/cputime.h>
|
||
+#include <asm/irq.h>
|
||
|
||
/*
|
||
* 'kernel_stat.h' contains the definitions needed for doing
|
||
diff -urN linux-i386/include/linux/module.h linux-m68k/include/linux/module.h
|
||
--- linux-i386/include/linux/module.h 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/include/linux/module.h 2006-06-18 19:10:21.000000000 +0200
|
||
@@ -324,6 +324,9 @@
|
||
keeping pointers to this stuff */
|
||
char *args;
|
||
};
|
||
+#ifndef MODULE_ARCH_INIT
|
||
+#define MODULE_ARCH_INIT {}
|
||
+#endif
|
||
|
||
/* FIXME: It'd be nice to isolate modules during init, too, so they
|
||
aren't used before they (may) fail. But presently too much code
|
||
diff -urN linux-i386/include/linux/sched.h linux-m68k/include/linux/sched.h
|
||
--- linux-i386/include/linux/sched.h 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/include/linux/sched.h 2006-06-18 19:10:22.000000000 +0200
|
||
@@ -695,7 +695,8 @@
|
||
|
||
struct task_struct {
|
||
volatile long state; /* -1 unrunnable, 0 runnable, >0 stopped */
|
||
- struct thread_info *thread_info;
|
||
+ //struct thread_info *thread_info;
|
||
+ void *stack;
|
||
atomic_t usage;
|
||
unsigned long flags; /* per process flags, defined below */
|
||
unsigned long ptrace;
|
||
@@ -1273,6 +1274,7 @@
|
||
/* set thread flags in other task's structures
|
||
* - see asm/thread_info.h for TIF_xxxx flags available
|
||
*/
|
||
+
|
||
static inline void set_tsk_thread_flag(struct task_struct *tsk, int flag)
|
||
{
|
||
set_ti_thread_flag(task_thread_info(tsk), flag);
|
||
diff -urN linux-i386/include/linux/thread_info.h linux-m68k/include/linux/thread_info.h
|
||
--- linux-i386/include/linux/thread_info.h 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/include/linux/thread_info.h 2005-05-30 02:26:01.000000000 +0200
|
||
@@ -66,6 +66,6 @@
|
||
#define set_need_resched() set_thread_flag(TIF_NEED_RESCHED)
|
||
#define clear_need_resched() clear_thread_flag(TIF_NEED_RESCHED)
|
||
|
||
-#endif
|
||
+#endif /* __KERNEL__ */
|
||
|
||
#endif /* _LINUX_THREAD_INFO_H */
|
||
diff -urN linux-i386/include/linux/zorro.h linux-m68k/include/linux/zorro.h
|
||
--- linux-i386/include/linux/zorro.h 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/include/linux/zorro.h 2006-06-18 19:10:25.000000000 +0200
|
||
@@ -11,8 +11,6 @@
|
||
#ifndef _LINUX_ZORRO_H
|
||
#define _LINUX_ZORRO_H
|
||
|
||
-#ifndef __ASSEMBLY__
|
||
-
|
||
#include <linux/device.h>
|
||
|
||
|
||
@@ -112,45 +110,6 @@
|
||
__u32 cd_Unused[4]; /* for whatever the driver wants */
|
||
} __attribute__ ((packed));
|
||
|
||
-#else /* __ASSEMBLY__ */
|
||
-
|
||
-LN_Succ = 0
|
||
-LN_Pred = LN_Succ+4
|
||
-LN_Type = LN_Pred+4
|
||
-LN_Pri = LN_Type+1
|
||
-LN_Name = LN_Pri+1
|
||
-LN_sizeof = LN_Name+4
|
||
-
|
||
-ER_Type = 0
|
||
-ER_Product = ER_Type+1
|
||
-ER_Flags = ER_Product+1
|
||
-ER_Reserved03 = ER_Flags+1
|
||
-ER_Manufacturer = ER_Reserved03+1
|
||
-ER_SerialNumber = ER_Manufacturer+2
|
||
-ER_InitDiagVec = ER_SerialNumber+4
|
||
-ER_Reserved0c = ER_InitDiagVec+2
|
||
-ER_Reserved0d = ER_Reserved0c+1
|
||
-ER_Reserved0e = ER_Reserved0d+1
|
||
-ER_Reserved0f = ER_Reserved0e+1
|
||
-ER_sizeof = ER_Reserved0f+1
|
||
-
|
||
-CD_Node = 0
|
||
-CD_Flags = CD_Node+LN_sizeof
|
||
-CD_Pad = CD_Flags+1
|
||
-CD_Rom = CD_Pad+1
|
||
-CD_BoardAddr = CD_Rom+ER_sizeof
|
||
-CD_BoardSize = CD_BoardAddr+4
|
||
-CD_SlotAddr = CD_BoardSize+4
|
||
-CD_SlotSize = CD_SlotAddr+2
|
||
-CD_Driver = CD_SlotSize+2
|
||
-CD_NextCD = CD_Driver+4
|
||
-CD_Unused = CD_NextCD+4
|
||
-CD_sizeof = CD_Unused+(4*4)
|
||
-
|
||
-#endif /* __ASSEMBLY__ */
|
||
-
|
||
-#ifndef __ASSEMBLY__
|
||
-
|
||
#define ZORRO_NUM_AUTO 16
|
||
|
||
#ifdef __KERNEL__
|
||
@@ -290,7 +249,6 @@
|
||
#define Z2RAM_CHUNKSHIFT (16)
|
||
|
||
|
||
-#endif /* !__ASSEMBLY__ */
|
||
#endif /* __KERNEL__ */
|
||
|
||
#endif /* _LINUX_ZORRO_H */
|
||
diff -urN linux-i386/kernel/fork.c linux-m68k/kernel/fork.c
|
||
--- linux-i386/kernel/fork.c 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/kernel/fork.c 2006-06-18 19:10:30.000000000 +0200
|
||
@@ -103,7 +103,7 @@
|
||
|
||
void free_task(struct task_struct *tsk)
|
||
{
|
||
- free_thread_info(tsk->thread_info);
|
||
+ free_thread_stack(tsk->stack);
|
||
free_task_struct(tsk);
|
||
}
|
||
EXPORT_SYMBOL(free_task);
|
||
@@ -156,7 +156,7 @@
|
||
static struct task_struct *dup_task_struct(struct task_struct *orig)
|
||
{
|
||
struct task_struct *tsk;
|
||
- struct thread_info *ti;
|
||
+ void *stack;
|
||
|
||
prepare_to_copy(orig);
|
||
|
||
@@ -164,14 +164,14 @@
|
||
if (!tsk)
|
||
return NULL;
|
||
|
||
- ti = alloc_thread_info(tsk);
|
||
- if (!ti) {
|
||
+ stack = alloc_thread_stack(tsk);
|
||
+ if (!stack) {
|
||
free_task_struct(tsk);
|
||
return NULL;
|
||
}
|
||
|
||
*tsk = *orig;
|
||
- tsk->thread_info = ti;
|
||
+ tsk->stack = stack;
|
||
setup_thread_stack(tsk, orig);
|
||
|
||
/* One for us, one for whoever does the "release_task()" (usually parent) */
|
||
diff -urN linux-i386/kernel/mutex-debug.c linux-m68k/kernel/mutex-debug.c
|
||
--- linux-i386/kernel/mutex-debug.c 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/kernel/mutex-debug.c 2006-05-09 20:50:42.000000000 +0200
|
||
@@ -149,7 +149,7 @@
|
||
continue;
|
||
lock = list_entry(curr, struct mutex, held_list);
|
||
t = lock->owner;
|
||
- if (filter && (t != filter->thread_info))
|
||
+ if (filter && (t != task_thread_info(filter)))
|
||
continue;
|
||
count++;
|
||
cursor = curr->next;
|
||
@@ -312,7 +312,7 @@
|
||
list_for_each_safe(curr, next, &debug_mutex_held_locks) {
|
||
lock = list_entry(curr, struct mutex, held_list);
|
||
t = lock->owner;
|
||
- if (t != task->thread_info)
|
||
+ if (t != task_thread_info(task))
|
||
continue;
|
||
list_del_init(curr);
|
||
DEBUG_OFF();
|
||
@@ -321,7 +321,7 @@
|
||
printk("BUG: %s/%d, lock held at task exit time!\n",
|
||
task->comm, task->pid);
|
||
printk_lock(lock, 1);
|
||
- if (lock->owner != task->thread_info)
|
||
+ if (lock->owner != task_thread_info(task))
|
||
printk("exiting task is not even the owner??\n");
|
||
return;
|
||
}
|
||
diff -urN linux-i386/kernel/mutex.c linux-m68k/kernel/mutex.c
|
||
--- linux-i386/kernel/mutex.c 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/kernel/mutex.c 2006-05-09 20:50:42.000000000 +0200
|
||
@@ -130,7 +130,7 @@
|
||
|
||
spin_lock_mutex(&lock->wait_lock);
|
||
|
||
- debug_mutex_add_waiter(lock, &waiter, task->thread_info, ip);
|
||
+ debug_mutex_add_waiter(lock, &waiter, task_thread_info(task), ip);
|
||
|
||
/* add waiting tasks to the end of the waitqueue (FIFO): */
|
||
list_add_tail(&waiter.list, &lock->wait_list);
|
||
@@ -156,7 +156,7 @@
|
||
*/
|
||
if (unlikely(state == TASK_INTERRUPTIBLE &&
|
||
signal_pending(task))) {
|
||
- mutex_remove_waiter(lock, &waiter, task->thread_info);
|
||
+ mutex_remove_waiter(lock, &waiter, task_thread_info(task));
|
||
spin_unlock_mutex(&lock->wait_lock);
|
||
|
||
debug_mutex_free_waiter(&waiter);
|
||
@@ -171,8 +171,8 @@
|
||
}
|
||
|
||
/* got the lock - rejoice! */
|
||
- mutex_remove_waiter(lock, &waiter, task->thread_info);
|
||
- debug_mutex_set_owner(lock, task->thread_info __IP__);
|
||
+ mutex_remove_waiter(lock, &waiter, task_thread_info(task));
|
||
+ debug_mutex_set_owner(lock, task_thread_info(task) __IP__);
|
||
|
||
/* set it to 0 if there are no waiters left: */
|
||
if (likely(list_empty(&lock->wait_list)))
|
||
@@ -183,7 +183,7 @@
|
||
debug_mutex_free_waiter(&waiter);
|
||
|
||
DEBUG_WARN_ON(list_empty(&lock->held_list));
|
||
- DEBUG_WARN_ON(lock->owner != task->thread_info);
|
||
+ DEBUG_WARN_ON(lock->owner != task_thread_info(task));
|
||
|
||
return 0;
|
||
}
|
||
diff -urN linux-i386/lib/kref.c linux-m68k/lib/kref.c
|
||
--- linux-i386/lib/kref.c 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/lib/kref.c 2006-06-18 19:10:31.000000000 +0200
|
||
@@ -11,8 +11,8 @@
|
||
*
|
||
*/
|
||
|
||
-#include <linux/kref.h>
|
||
#include <linux/module.h>
|
||
+#include <linux/kref.h>
|
||
|
||
/**
|
||
* kref_init - initialize object.
|
||
diff -urN linux-i386/mm/bootmem.c linux-m68k/mm/bootmem.c
|
||
--- linux-i386/mm/bootmem.c 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/mm/bootmem.c 2006-06-18 19:10:31.000000000 +0200
|
||
@@ -305,7 +305,6 @@
|
||
|
||
count = 0;
|
||
/* first extant page of the node */
|
||
- pfn = bdata->node_boot_start >> PAGE_SHIFT;
|
||
idx = bdata->node_low_pfn - (bdata->node_boot_start >> PAGE_SHIFT);
|
||
map = bdata->node_bootmem_map;
|
||
/* Check physaddr is O(LOG2(BITS_PER_LONG)) page aligned */
|
||
@@ -318,26 +317,24 @@
|
||
if (gofast && v == ~0UL) {
|
||
int order;
|
||
|
||
- page = pfn_to_page(pfn);
|
||
+ page = virt_to_page(phys_to_virt((i << PAGE_SHIFT) +
|
||
+ bdata->node_boot_start));
|
||
count += BITS_PER_LONG;
|
||
order = ffs(BITS_PER_LONG) - 1;
|
||
__free_pages_bootmem(page, order);
|
||
i += BITS_PER_LONG;
|
||
- page += BITS_PER_LONG;
|
||
} else if (v) {
|
||
unsigned long m;
|
||
-
|
||
- page = pfn_to_page(pfn);
|
||
- for (m = 1; m && i < idx; m<<=1, page++, i++) {
|
||
+ for (m = 1; m && i < idx; m<<=1, i++) {
|
||
if (v & m) {
|
||
+ page = virt_to_page(phys_to_virt((i << PAGE_SHIFT) +
|
||
+ bdata->node_boot_start));
|
||
count++;
|
||
__free_pages_bootmem(page, 0);
|
||
}
|
||
}
|
||
- } else {
|
||
+ } else
|
||
i+=BITS_PER_LONG;
|
||
- }
|
||
- pfn += BITS_PER_LONG;
|
||
}
|
||
total += count;
|
||
|
||
diff -urN linux-i386/scripts/mod/modpost.c linux-m68k/scripts/mod/modpost.c
|
||
--- linux-i386/scripts/mod/modpost.c 2006-06-18 03:49:35.000000000 +0200
|
||
+++ linux-m68k/scripts/mod/modpost.c 2006-06-18 19:10:38.000000000 +0200
|
||
@@ -1012,6 +1012,7 @@
|
||
buf_printf(b, "#ifdef CONFIG_MODULE_UNLOAD\n"
|
||
" .exit = cleanup_module,\n"
|
||
"#endif\n");
|
||
+ buf_printf(b, " .arch = MODULE_ARCH_INIT,\n");
|
||
buf_printf(b, "};\n");
|
||
}
|
||
|