diff options
Diffstat (limited to 'debian/patches/bugfix/m68k/mac68k-macsonic-via-alt-mapping.diff')
-rw-r--r-- | debian/patches/bugfix/m68k/mac68k-macsonic-via-alt-mapping.diff | 194 |
1 files changed, 194 insertions, 0 deletions
diff --git a/debian/patches/bugfix/m68k/mac68k-macsonic-via-alt-mapping.diff b/debian/patches/bugfix/m68k/mac68k-macsonic-via-alt-mapping.diff new file mode 100644 index 000000000000..0998c9cab31a --- /dev/null +++ b/debian/patches/bugfix/m68k/mac68k-macsonic-via-alt-mapping.diff @@ -0,0 +1,194 @@ +Subject: [PATCH 13/13] SONIC interrupt handling +Cc: Thomas Bogendoerfer <tsbogend@alpha.franken.de>, + Jeff Garzik <jgarzik@pobox.com>, netdev@vger.kernel.org, + linux-mips@linux-mips.org + +From: Finn Thain <fthain@telegraphics.com.au> + +Install the built-in macsonic interrupt handler on both IRQs when using +via_alt_mapping. Otherwise the rare interrupt that still comes from the +nubus slot will wedge the nubus. + +$ cat /proc/interrupts +auto 2: 89176 via2 +auto 3: 744367 sonic +auto 4: 0 scc +auto 6: 318363 via1 +auto 7: 0 NMI +mac 9: 119413 framebuffer vbl +mac 10: 1971 ADB +mac 14: 198517 timer +mac 17: 89104 nubus +mac 19: 72 Mac ESP SCSI +mac 56: 629 sonic +mac 62: 1142593 ide0 + +Version 1 of this patch had a bug where a nubus sonic card would register +two interrupt handlers. Only a built-in sonic needs both. + +Versions 2 and 3 needed some cleanups, as Raylynn Knight and Christoph +Hellwig pointed out (thanks). + +Signed-off-by: Finn Thain <fthain@telegraphics.com.au> +--- + drivers/net/jazzsonic.c | 23 +++++++++++++++++++---- + drivers/net/macsonic.c | 46 ++++++++++++++++++++++++++++++++++++++++++---- + drivers/net/sonic.c | 25 ------------------------- + 3 files changed, 61 insertions(+), 33 deletions(-) + +--- linux-m68k-2.6.22-rc1.orig/drivers/net/jazzsonic.c ++++ linux-m68k-2.6.22-rc1/drivers/net/jazzsonic.c +@@ -88,6 +88,23 @@ static unsigned short known_revisions[] + 0xffff /* end of list */ + }; + ++static int jazzsonic_open(struct net_device* dev) ++{ ++ if (request_irq(dev->irq, &sonic_interrupt, IRQF_DISABLED, "sonic", dev)) { ++ printk(KERN_ERR "%s: unable to get IRQ %d.\n", dev->name, dev->irq); ++ return -EAGAIN; ++ } ++ return sonic_open(dev); ++} ++ ++static int jazzsonic_close(struct net_device* dev) ++{ ++ int err; ++ err = sonic_close(dev); ++ free_irq(dev->irq, dev); ++ return err; ++} ++ + static int __init sonic_probe1(struct net_device *dev) + { + static unsigned version_printed; +@@ -169,8 +186,8 @@ static int __init sonic_probe1(struct ne + lp->rra_laddr = lp->rda_laddr + (SIZEOF_SONIC_RD * SONIC_NUM_RDS + * SONIC_BUS_SCALE(lp->dma_bitmode)); + +- dev->open = sonic_open; +- dev->stop = sonic_close; ++ dev->open = jazzsonic_open; ++ dev->stop = jazzsonic_close; + dev->hard_start_xmit = sonic_send_packet; + dev->get_stats = sonic_get_stats; + dev->set_multicast_list = &sonic_multicast_list; +@@ -260,8 +277,6 @@ MODULE_DESCRIPTION("Jazz SONIC ethernet + module_param(sonic_debug, int, 0); + MODULE_PARM_DESC(sonic_debug, "jazzsonic debug level (1-4)"); + +-#define SONIC_IRQ_FLAG IRQF_DISABLED +- + #include "sonic.c" + + static int __devexit jazz_sonic_device_remove (struct platform_device *pdev) +--- linux-m68k-2.6.22-rc1.orig/drivers/net/macsonic.c ++++ linux-m68k-2.6.22-rc1/drivers/net/macsonic.c +@@ -130,6 +130,46 @@ static inline void bit_reverse_addr(unsi + addr[i] = bitrev8(addr[i]); + } + ++static irqreturn_t macsonic_interrupt(int irq, void *dev_id) ++{ ++ irqreturn_t result; ++ unsigned long flags; ++ ++ local_irq_save(flags); ++ result = sonic_interrupt(irq, dev_id); ++ local_irq_restore(flags); ++ return result; ++} ++ ++static int macsonic_open(struct net_device* dev) ++{ ++ if (request_irq(dev->irq, &sonic_interrupt, IRQ_FLG_FAST, "sonic", dev)) { ++ printk(KERN_ERR "%s: unable to get IRQ %d.\n", dev->name, dev->irq); ++ return -EAGAIN; ++ } ++ /* Under the A/UX interrupt scheme, the onboard SONIC interrupt comes ++ * in at priority level 3. However, we sometimes get the level 2 inter- ++ * rupt as well, which must prevent re-entrance of the sonic handler. ++ */ ++ if (dev->irq == IRQ_AUTO_3) ++ if (request_irq(IRQ_NUBUS_9, &macsonic_interrupt, IRQ_FLG_FAST, "sonic", dev)) { ++ printk(KERN_ERR "%s: unable to get IRQ %d.\n", dev->name, IRQ_NUBUS_9); ++ free_irq(dev->irq, dev); ++ return -EAGAIN; ++ } ++ return sonic_open(dev); ++} ++ ++static int macsonic_close(struct net_device* dev) ++{ ++ int err; ++ err = sonic_close(dev); ++ free_irq(dev->irq, dev); ++ if (dev->irq == IRQ_AUTO_3) ++ free_irq(IRQ_NUBUS_9, dev); ++ return err; ++} ++ + int __init macsonic_init(struct net_device* dev) + { + struct sonic_local* lp = netdev_priv(dev); +@@ -160,8 +200,8 @@ int __init macsonic_init(struct net_devi + lp->rra_laddr = lp->rda_laddr + (SIZEOF_SONIC_RD * SONIC_NUM_RDS + * SONIC_BUS_SCALE(lp->dma_bitmode)); + +- dev->open = sonic_open; +- dev->stop = sonic_close; ++ dev->open = macsonic_open; ++ dev->stop = macsonic_close; + dev->hard_start_xmit = sonic_send_packet; + dev->get_stats = sonic_get_stats; + dev->set_multicast_list = &sonic_multicast_list; +@@ -572,8 +612,6 @@ MODULE_DESCRIPTION("Macintosh SONIC ethe + module_param(sonic_debug, int, 0); + MODULE_PARM_DESC(sonic_debug, "macsonic debug level (1-4)"); + +-#define SONIC_IRQ_FLAG IRQ_FLG_FAST +- + #include "sonic.c" + + static int __devexit mac_sonic_device_remove (struct platform_device *pdev) +--- linux-m68k-2.6.22-rc1.orig/drivers/net/sonic.c ++++ linux-m68k-2.6.22-rc1/drivers/net/sonic.c +@@ -50,29 +50,6 @@ static int sonic_open(struct net_device + if (sonic_debug > 2) + printk("sonic_open: initializing sonic driver.\n"); + +- /* +- * We don't need to deal with auto-irq stuff since we +- * hardwire the sonic interrupt. +- */ +-/* +- * XXX Horrible work around: We install sonic_interrupt as fast interrupt. +- * This means that during execution of the handler interrupt are disabled +- * covering another bug otherwise corrupting data. This doesn't mean +- * this glue works ok under all situations. +- * +- * Note (dhd): this also appears to prevent lockups on the Macintrash +- * when more than one Ethernet card is installed (knock on wood) +- * +- * Note (fthain): whether the above is still true is anyones guess. Certainly +- * the buffer handling algorithms will not tolerate re-entrance without some +- * mutual exclusion added. Anyway, the memcpy has now been eliminated from the +- * rx code to make this a faster "fast interrupt". +- */ +- if (request_irq(dev->irq, &sonic_interrupt, SONIC_IRQ_FLAG, "sonic", dev)) { +- printk(KERN_ERR "\n%s: unable to get IRQ %d .\n", dev->name, dev->irq); +- return -EAGAIN; +- } +- + for (i = 0; i < SONIC_NUM_RRS; i++) { + struct sk_buff *skb = dev_alloc_skb(SONIC_RBSIZE + 2); + if (skb == NULL) { +@@ -169,8 +146,6 @@ static int sonic_close(struct net_device + } + } + +- free_irq(dev->irq, dev); /* release the IRQ */ +- + return 0; + } + |