Messages in this thread Patch in this message |  | | Date | Wed, 30 Aug 2000 09:15:29 -0700 | From | "Eric Chang" <> | Subject | [PATCH] 3c507 ignores irq=# setting |
| |
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/
|  |