Fixed brokeness in the support of the 83C790/Elite Ultra (now that I
authorDavid Greenman <davidg@Root.COM>
Sun, 10 Apr 1994 20:06:28 +0000 (20:06 +0000)
committerDavid Greenman <davidg@Root.COM>
Sun, 10 Apr 1994 20:06:28 +0000 (20:06 +0000)
finally have the f**king documentation!):

1) Changed all the numeric register offsets to symbolic ones (it should
have been this way originally).
2) If 16 bit, disable the shared memory when not using it. Apparantly
switching between 8/16bit mode makes the Ultra unhappy unless
this is done (i.e. it trashes the bus).

sys/i386/isa/if_ed.c
sys/i386/isa/if_edreg.h

index 72409f8..d9a7232 100644 (file)
@@ -16,7 +16,7 @@
  */
 
 /*
  */
 
 /*
- * $Id: if_ed.c,v 1.34 1994/03/01 12:23:33 davidg Exp $
+ * $Id: if_ed.c,v 1.35 1994/03/02 05:50:01 davidg Exp $
  */
 
 #include "ed.h"
  */
 
 #include "ed.h"
@@ -414,14 +414,15 @@ ed_probe_WD80x3(isa_dev)
                 * Assemble together the encoded interrupt number.
                 */
                iptr = (inb(isa_dev->id_iobase + ED_WD_ICR) & ED_WD_ICR_IR2) |
                 * Assemble together the encoded interrupt number.
                 */
                iptr = (inb(isa_dev->id_iobase + ED_WD_ICR) & ED_WD_ICR_IR2) |
-                       ((inb(isa_dev->id_iobase + ED_WD_IRR) &
-                       (ED_WD_IRR_IR0 | ED_WD_IRR_IR1)) >> 5);
+                           ((inb(isa_dev->id_iobase + ED_WD_IRR) &
+                           (ED_WD_IRR_IR0 | ED_WD_IRR_IR1)) >> 5);
                /*
                 * Translate it using translation table, and check for correctness.
                 */
                if (ed_intr_mask[iptr] != isa_dev->id_irq) {
                        printf("ed%d: kernel configured irq %d doesn't match board configured irq %d\n",
                /*
                 * Translate it using translation table, and check for correctness.
                 */
                if (ed_intr_mask[iptr] != isa_dev->id_irq) {
                        printf("ed%d: kernel configured irq %d doesn't match board configured irq %d\n",
-                               isa_dev->id_unit, ffs(isa_dev->id_irq) - 1, ffs(ed_intr_mask[iptr]) - 1);
+                           isa_dev->id_unit, ffs(isa_dev->id_irq) - 1,
+                           ffs(ed_intr_mask[iptr]) - 1);
                        return(0);
                }
                /*
                        return(0);
                }
                /*
@@ -431,17 +432,25 @@ ed_probe_WD80x3(isa_dev)
                        inb(isa_dev->id_iobase + ED_WD_IRR) | ED_WD_IRR_IEN);
        }
        if (sc->is790) {
                        inb(isa_dev->id_iobase + ED_WD_IRR) | ED_WD_IRR_IEN);
        }
        if (sc->is790) {
-               outb(isa_dev->id_iobase + 0x04, inb(isa_dev->id_iobase + 0x04) | 0x80);
-               iptr = ((inb(isa_dev->id_iobase + 0x0d) & 0x0c ) >> 2) | 
-                       ((inb(isa_dev->id_iobase + 0x0d) & 0x40) >> 4);
-               outb(isa_dev->id_iobase + 0x04, inb(isa_dev->id_iobase + 0x04) & ~0x80);
+               outb(isa_dev->id_iobase + ED_WD790_HWR,
+                   inb(isa_dev->id_iobase + ED_WD790_HWR) | ED_WD790_HWR_SWH);
+               iptr = (((inb(isa_dev->id_iobase + ED_WD790_GCR) & ED_WD790_GCR_IR2) >> 4) |
+                           (inb(isa_dev->id_iobase + ED_WD790_GCR) &
+                           (ED_WD790_GCR_IR1|ED_WD790_GCR_IR0)) >> 2);
+               outb(isa_dev->id_iobase + ED_WD790_HWR,
+                   inb(isa_dev->id_iobase + ED_WD790_HWR) & ~ED_WD790_HWR_SWH);
 
                if (ed_790_intr_mask[iptr] != isa_dev->id_irq) {
                        printf("ed%d: kernel configured irq %d doesn't match board configured irq %d %d\n",
 
                if (ed_790_intr_mask[iptr] != isa_dev->id_irq) {
                        printf("ed%d: kernel configured irq %d doesn't match board configured irq %d %d\n",
-                               isa_dev->id_unit, ffs(isa_dev->id_irq) - 1, ffs(ed_790_intr_mask[iptr]) -1, iptr);
+                           isa_dev->id_unit, ffs(isa_dev->id_irq) - 1,
+                           ffs(ed_790_intr_mask[iptr]) - 1, iptr);
                        return 0;
                }
                        return 0;
                }
-               outb(isa_dev->id_iobase + 0x06, inb(isa_dev->id_iobase + 0x06) | 0x01);
+               /*
+                * Enable interrupts.
+                */
+               outb(isa_dev->id_iobase + ED_WD790_ICR,
+                   inb(isa_dev->id_iobase + ED_WD790_ICR) | ED_WD790_ICR_EIL);
        }
 
        sc->isa16bit = isa16bit;
        }
 
        sc->isa16bit = isa16bit;
@@ -1444,9 +1453,13 @@ outloop:
                         *      may cause a call-back to ed_start)
                         * XXX - the call-back to 'start' is a bug, IMHO.
                         */
                         *      may cause a call-back to ed_start)
                         * XXX - the call-back to 'start' is a bug, IMHO.
                         */
-                       case ED_VENDOR_WD_SMC:
+                       case ED_VENDOR_WD_SMC: {
                                outb(sc->asic_addr + ED_WD_LAAR,
                                    (sc->wd_laar_proto | ED_WD_LAAR_M16EN));
                                outb(sc->asic_addr + ED_WD_LAAR,
                                    (sc->wd_laar_proto | ED_WD_LAAR_M16EN));
+                               if (sc->is790)
+                                   outb(sc->asic_addr + ED_WD_MSR, ED_WD_MSR_MENB);
+                               break;
+                           }
                        }
                }
 
                        }
                }
 
@@ -1465,9 +1478,12 @@ outloop:
                                outb(sc->asic_addr + ED_3COM_GACFR,
                                    ED_3COM_GACFR_RSEL | ED_3COM_GACFR_MBS0);
                                break;
                                outb(sc->asic_addr + ED_3COM_GACFR,
                                    ED_3COM_GACFR_RSEL | ED_3COM_GACFR_MBS0);
                                break;
-                       case ED_VENDOR_WD_SMC:
+                       case ED_VENDOR_WD_SMC: {
                                outb(sc->asic_addr + ED_WD_LAAR, sc->wd_laar_proto);
                                outb(sc->asic_addr + ED_WD_LAAR, sc->wd_laar_proto);
+                               if (sc->is790)
+                                   outb(sc->asic_addr + ED_WD_MSR, 0x00);
                                break;
                                break;
+                           }
                        }
                }
        } else {
                        }
                }
        } else {
@@ -1823,6 +1839,9 @@ edintr(unit)
                                        outb(sc->asic_addr + ED_WD_LAAR,
                                             (sc->wd_laar_proto |=
                                             ED_WD_LAAR_M16EN));
                                        outb(sc->asic_addr + ED_WD_LAAR,
                                             (sc->wd_laar_proto |=
                                             ED_WD_LAAR_M16EN));
+                                       if (sc->is790)
+                                           outb(sc->asic_addr + ED_WD_MSR,
+                                               ED_WD_MSR_MENB);
                                }
 
                                ed_rint (unit);
                                }
 
                                ed_rint (unit);
@@ -1834,6 +1853,8 @@ edintr(unit)
                                        outb(sc->asic_addr + ED_WD_LAAR,
                                             (sc->wd_laar_proto &=
                                             ~ED_WD_LAAR_M16EN));
                                        outb(sc->asic_addr + ED_WD_LAAR,
                                             (sc->wd_laar_proto &=
                                             ~ED_WD_LAAR_M16EN));
+                                       if (sc->is790)
+                                           outb(sc->asic_addr + ED_WD_MSR, 0x00);
                                }
                        }
                }
                                }
                        }
                }
index cd3f1d0..f75e261 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * National Semiconductor DS8390 NIC register definitions 
  *
 /*
  * National Semiconductor DS8390 NIC register definitions 
  *
- * $Id: if_edreg.h,v 1.12 1994/02/02 02:24:42 davidg Exp $
+ * $Id: if_edreg.h,v 1.13 1994/02/02 14:05:58 davidg Exp $
  *
  * Modification history
  *
  *
  * Modification history
  *
@@ -602,16 +602,14 @@ struct ed_ring    {
  */
 #define ED_WD_MSR      0
 
  */
 #define ED_WD_MSR      0
 
-#define ED_WD_MSR_ADDR 0x3f    /* Memory decode bits 18-13 */
-#define ED_WD_MSR_MENB 0x40    /* Memory enable */
-#define ED_WD_MSR_RST  0x80    /* Reset board */
-#ifdef TOSH_ETHER
+/* next three definitions for Toshiba */
 #define ED_WD_MSR_POW  0x02    /* 0 = power save, 1 = normal (R/W) */
 #define ED_WD_MSR_BSY  0x04    /* gate array busy (R) */
 #define ED_WD_MSR_LEN  0x20    /* data bus width, 0 = 16 bits,
                                   1 = 8 bits (R/W) */
 #define ED_WD_MSR_POW  0x02    /* 0 = power save, 1 = normal (R/W) */
 #define ED_WD_MSR_BSY  0x04    /* gate array busy (R) */
 #define ED_WD_MSR_LEN  0x20    /* data bus width, 0 = 16 bits,
                                   1 = 8 bits (R/W) */
-#endif
-
+#define ED_WD_MSR_ADDR 0x3f    /* Memory decode bits 18-13 */
+#define ED_WD_MSR_MENB 0x40    /* Memory enable */
+#define ED_WD_MSR_RST  0x80    /* Reset board */
 
 /*
  * Interface Configuration Register (ICR)
 
 /*
  * Interface Configuration Register (ICR)
@@ -657,7 +655,7 @@ struct ed_ring      {
 #define ED_WD_IRR_FLASH        0x10    /* Flash RAM is in the ROM socket */
 
 /*
 #define ED_WD_IRR_FLASH        0x10    /* Flash RAM is in the ROM socket */
 
 /*
- * The three bit of the encoded IRQ are decoded as follows:
+ * The three bits of the encoded IRQ are decoded as follows:
  *
  *     IR2 IR1 IR0     IRQ
  *      0   0   0       2/9
  *
  *     IR2 IR1 IR0     IRQ
  *      0   0   0       2/9
@@ -686,6 +684,49 @@ struct ed_ring     {
 /* i/o base offset to station address/card-ID PROM */
 #define ED_WD_PROM     8
 
 /* i/o base offset to station address/card-ID PROM */
 #define ED_WD_PROM     8
 
+/*
+ *     83C790 specific registers
+ */
+/*
+ * Hardware Support Register (HWR) ('790)
+ */
+#define ED_WD790_HWR   4
+
+#define WD_WD790_HWR_NUKE      0x10    /* hardware reset */
+#define ED_WD790_HWR_LPRM      0x40    /* LAN PROM select */
+#define ED_WD790_HWR_SWH       0x80    /* switch register set */
+
+/*
+ * ICR790 Interrupt Control Register for the 83C790
+ */
+#define ED_WD790_ICR   6
+
+#define ED_WD790_ICR_EIL       0x01    /* enable interrupts */
+
+/*
+ * General Control Register (GCR)
+ *     Enabled with SWH bit=1 in HWR register
+ */
+#define ED_WD790_GCR   0x0d
+
+#define ED_WD790_GCR_IR0       0x04    /* bit 0 of encoded IRQ */
+#define ED_WD790_GCR_IR1       0x08    /* bit 1 of encoded IRQ */
+#define ED_WD790_GCR_ZWSEN     0x20    /* zero wait state enable */
+#define ED_WD790_GCR_IR2       0x40    /* bit 2 of encoded IRQ */
+/*
+ * The three bits of the encoded IRQ are decoded as follows:
+ *
+ *     IR2 IR1 IR0     IRQ
+ *      0   0   0       none
+ *      0   0   1       9
+ *      0   1   0       3
+ *      0   1   1       5
+ *      1   0   0       7
+ *      1   0   1       10
+ *      1   1   0       11
+ *      1   1   1       15
+ */
+
 /* i/o base offset to CARD ID */
 #define ED_WD_CARD_ID  ED_WD_PROM+6
 
 /* i/o base offset to CARD ID */
 #define ED_WD_CARD_ID  ED_WD_PROM+6