[PATCH] 3c507 ignores irq=# setting

From: Eric Chang (ericchang@my-Deja.com)
Date: Wed Aug 30 2000 - 11:15:29 EST


This patch has been explained by previous
messages. The computer will crash if any other
device takes the card default irq. Now, the
documented (previously non-functional) irq=#
boot string works:

--- /root/old.c Thu Aug 31 07:01:13 2000
+++ 3c507.c Thu Aug 31 07:02:05 2000
@@ -26,7 +26,6 @@
 static const char *version =
        "3c507.c:v1.10 9/23/94 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n";
 
-
 #include <linux/module.h>
 
 /*
@@ -282,6 +281,7 @@
 extern int el16_probe(struct device *dev); /* Called from Space.c */
 
 static int el16_probe1(struct device *dev, int ioaddr);
+static void el16_patternout(void);
 static int el16_open(struct device *dev);
 static int el16_send_packet(struct sk_buff *skb, struct device *dev);
 static void el16_interrupt(int irq, void *dev_id, struct pt_regs *regs);
@@ -329,18 +329,12 @@
 __initfunc(int el16_probe1(struct device *dev, int ioaddr))
 {
        static unsigned char init_ID_done = 0, version_printed = 0;
+ unsigned short inputbyt;
        int i, irq, irqval;
 
        if (init_ID_done == 0) {
- ushort lrs_state = 0xff;
- /* Send the ID sequence to the ID_PORT to enable the board(s). */
                outb(0x00, ID_PORT);
- for(i = 0; i < 255; i++) {
- outb(lrs_state, ID_PORT);
- lrs_state <<= 1;
- if (lrs_state & 0x100)
- lrs_state ^= 0xe7;
- }
+ el16_patternout();
                outb(0x00, ID_PORT);
                init_ID_done = 1;
        }
@@ -364,6 +358,38 @@
           the S.A. for the manufacturer's code. */
 
        irq = inb(ioaddr + IRQ_CONFIG) & 0x0f;
+ if (init_ID_done == 1 && dev->irq !=0 && irq != dev->irq)
+ { /* The user selected an irq that does not match with the card
+ irq. Attempt to reset it */
+ outb(0x00, ID_PORT);
+ el16_patternout();
+ el16_patternout();
+ outb(0xff, ID_PORT);
+ inputbyt = inb(ioaddr + IRQ_CONFIG);
+ /* get rid of the last 5 bits (4 is reset) */
+ inputbyt = inputbyt & 0xe0;
+ inputbyt = inputbyt | dev->irq;
+ printk("Attempting to set irq to %x\n", dev->irq);
+ outb(inputbyt, ioaddr + IRQ_CONFIG);
+
+ /* reset the port (but not restart) */
+ outb(0x00, ID_PORT);
+ el16_patternout();
+ outb(0x00, ID_PORT);
+
+ /* check to see if new irq is in */
+ inputbyt = inb(ioaddr + IRQ_CONFIG);
+ inputbyt = inputbyt & 0x0f;
+ if (inputbyt == dev->irq)
+ printk("succeeded to reset irq to %x\n", dev->irq);
+ else
+ {
+ printk("failed to reset irq to %x\n", dev->irq);
+ return EAGAIN;
+ }
+ irq = dev->irq;
+ init_ID_done = 2; /* no need to reset twice */
+ }
 
        irqval = request_irq(irq, &el16_interrupt, 0, "3c507", dev);
        if (irqval) {
@@ -432,6 +458,20 @@
        return 0;
 }
 
+__initfunc(void el16_patternout(void))
+{
+ ushort lrs_state = 0xff;
+ int i;
+
+ /* Send the ID sequence to the ID_PORT to enable the board(s). */
+ for(i = 0; i < 255; i++) {
+ outb(lrs_state, ID_PORT);
+ lrs_state <<= 1;
+ if (lrs_state & 0x100)
+ lrs_state ^= 0xe7;
+ }
+}
+
 static int el16_open(struct device *dev)
 {
        /* Initialize the 82586 memory and start it. */
@@ -885,6 +925,7 @@
 {
        if (io == 0)
                printk("3c507: You should not use auto-probing with insmod!\n");
+printk("3c507: setting io %x irq %d\n", io, irq); /* ericc */
        dev_3c507.base_addr = io;
        dev_3c507.irq = irq;
        if (register_netdev(&dev_3c507) != 0) {

--== Sent via Deja.com http://www.deja.com/ ==--
Before you buy.
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Thu Aug 31 2000 - 21:00:25 EST