robin
-- ---- Robin Cutshaw internet: robin@interlabs.com robin@intercore.com Internet Labs, Inc. BellNet: 404-817-9787"Time is just one damn thing after another" -- PBS/Nova ----
--*** de4x5.c.ORIG Thu Dec 14 23:46:15 1995 --- de4x5.c Tue Feb 20 22:38:58 1996 *************** *** 458,463 **** --- 458,466 ---- static char name[DE4X5_NAME_LENGTH + 1]; static int num_de4x5s = 0, num_eth = 0; + #define MAX_DE4X5_DEVS 16 + static struct device *de4x5_devs[MAX_DE4X5_DEVS]; + /* ** Kludge to get around the fact that the CSR addresses have different ** offsets in the PCI and EISA boards. Also note that the ethernet address *************** *** 525,530 **** --- 528,540 ---- struct bus_type *lp = &bus; int tmpbus, tmpchs, i, j, status=0; char *tmp; + static int de4x5_devs_inited = 0; + + if (!de4x5_devs_inited) { + for (i=0; i<MAX_DE4X5_DEVS; i++) + de4x5_devs[i] = 0; + de4x5_devs_inited = 1; + } /* Ensure we're not sleeping */ if (lp->chipset == DC21041) { *************** *** 762,772 **** } if (request_irq(dev->irq, (void *)de4x5_interrupt, 0, lp->adapter_name)) { ! printk("de4x5_open(): Requested IRQ%d is busy\n",dev->irq); ! status = -EAGAIN; ! } else { ! irq2dev_map[dev->irq] = dev; /* ** Re-initialize the DE4X5... */ --- 772,806 ---- } if (request_irq(dev->irq, (void *)de4x5_interrupt, 0, lp->adapter_name)) { ! for (i=0; i<MAX_DE4X5_DEVS; i++) ! if ((de4x5_devs[i] != 0) && (de4x5_devs[i]->irq == dev->irq)) ! break; /* dup irq */ ! if (i == MAX_DE4X5_DEVS) { ! printk("de4x5_open(): Requested IRQ%d is busy\n",dev->irq); ! status = -EAGAIN; ! } ! } else irq2dev_map[dev->irq] = dev; + + if (!status) { + /* put the device in our private device array */ + for (i=0; i<MAX_DE4X5_DEVS; i++) + if (de4x5_devs[i] == dev) + break; /* already there */ + if (i == MAX_DE4X5_DEVS) { /* not found */ + for (i=0; i<MAX_DE4X5_DEVS; i++) + if (de4x5_devs[i] == 0) { + de4x5_devs[i] = dev; + break; + } + if (i == MAX_DE4X5_DEVS) { /* no more room */ + printk("de4x5_open(): Requested IRQ%d is busy\n",dev->irq); + status = -EAGAIN; + } + } + } + + if (!status) { /* ** Re-initialize the DE4X5... */ *************** *** 1067,1080 **** static void de4x5_interrupt(int irq, struct pt_regs *regs) { ! struct device *dev = (struct device *)(irq2dev_map[irq]); struct de4x5_private *lp; s32 imr, omr, sts; u_long iobase; ! if (dev == NULL) { ! printk ("de4x5_interrupt(): irq %d for unknown device.\n", irq); ! } else { lp = (struct de4x5_private *)dev->priv; iobase = dev->base_addr; --- 1101,1120 ---- static void de4x5_interrupt(int irq, struct pt_regs *regs) { ! struct device *dev; struct de4x5_private *lp; s32 imr, omr, sts; u_long iobase; + int i, devs_processed = 0; ! for (i=0; i<MAX_DE4X5_DEVS; i++) { ! if ((de4x5_devs[i] == 0) || (de4x5_devs[i]->irq != irq)) ! continue; ! ! /* found an irq that matched */ ! devs_processed++; ! ! dev = de4x5_devs[i]; lp = (struct de4x5_private *)dev->priv; iobase = dev->base_addr; *************** *** 1118,1123 **** --- 1158,1166 ---- ENABLE_IRQs; } + if (devs_processed == 0) + printk ("de4x5_interrupt(): irq %d for unknown device.\n", irq); + return; } *************** *** 1313,1318 **** --- 1356,1362 ---- struct de4x5_private *lp = (struct de4x5_private *)dev->priv; u_long iobase = dev->base_addr; s32 imr, omr; + int i; dev->start = 0; dev->tbusy = 1; *************** *** 1329,1339 **** STOP_DE4X5; ! /* ! ** Free the associated irq ! */ ! free_irq(dev->irq); ! irq2dev_map[dev->irq] = 0; MOD_DEC_USE_COUNT; --- 1373,1391 ---- STOP_DE4X5; ! for (i=0; i<MAX_DE4X5_DEVS; i++) ! if ((de4x5_devs[i] != 0) && ! (de4x5_devs[i] != dev) && ! (de4x5_devs[i]->irq == dev->irq)) ! break; /* dup irq, don't free it */ ! ! if (i == MAX_DE4X5_DEVS) { /* no dup irqs */ ! /* ! ** Free the associated irq ! */ ! free_irq(dev->irq); ! irq2dev_map[dev->irq] = 0; ! } MOD_DEC_USE_COUNT;