summaryrefslogtreecommitdiff
path: root/sys/pci/if_en_pci.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/pci/if_en_pci.c')
-rw-r--r--sys/pci/if_en_pci.c170
1 files changed, 39 insertions, 131 deletions
diff --git a/sys/pci/if_en_pci.c b/sys/pci/if_en_pci.c
index 3414edc489be..d1853b5748aa 100644
--- a/sys/pci/if_en_pci.c
+++ b/sys/pci/if_en_pci.c
@@ -50,6 +50,17 @@
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/systm.h>
+#ifndef SHUTDOWN_PRE_SYNC
+/*
+ * device shutdown mechanism has been changed since 2.2-ALPHA.
+ * if SHUTDOWN_PRE_SYNC is defined in "sys/systm.h", use new one.
+ * otherwise, use old one.
+ * new: 2.2-ALPHA, 2.2-BETA, 2.2-GAMME, 2.2-RELEASE, 3.0
+ * old: 2.1.5, 2.1.6, 2.2-SNAP
+ * -- kjc
+ */
+#include <sys/devconf.h>
+#endif
#include <sys/malloc.h>
#include <sys/socket.h>
@@ -69,8 +80,12 @@
*/
static void en_pci_attach __P((pcici_t, int));
-static const char *en_pci_probe __P((pcici_t, pcidi_t));
+static char *en_pci_probe __P((pcici_t, pcidi_t));
+#ifdef SHUTDOWN_PRE_SYNC
static void en_pci_shutdown __P((int, void *));
+#else
+static int en_pci_shutdown __P((struct kern_devconf *, int));
+#endif
/*
* local structures
@@ -83,15 +98,8 @@ struct en_pci_softc {
/* PCI bus glue */
void *sc_ih; /* interrupt handle */
pci_chipset_tag_t en_pc; /* for PCI calls */
- pcici_t en_confid; /* config id */
-};
-#if !defined(MIDWAY_ENIONLY)
-static void eni_get_macaddr __P((struct en_pci_softc *));
-#endif
-#if !defined(MIDWAY_ADPONLY)
-static void adp_get_macaddr __P((struct en_pci_softc *));
-#endif
+};
/*
* pointers to softcs (we alloc)
@@ -111,7 +119,11 @@ static struct pci_device endevice = {
en_pci_probe,
en_pci_attach,
&en_pci_count,
+#ifdef SHUTDOWN_PRE_SYNC
NULL,
+#else
+ en_pci_shutdown,
+#endif
};
DATA_SET (pcidevice_set, endevice);
@@ -191,7 +203,7 @@ void *v;
* autoconfig stuff
*/
-static const char *en_pci_probe(config_id, device_id)
+static char *en_pci_probe(config_id, device_id)
pcici_t config_id;
pcidi_t device_id;
@@ -247,10 +259,9 @@ int unit;
enpcis[unit] = scp; /* lock it in */
en_cd.cd_devs[unit] = sc; /* fake a cfdriver structure */
en_cd.cd_ndevs = NEN;
- snprintf(sc->sc_dev.dv_xname, sizeof(sc->sc_dev.dv_xname), "en%d", unit);
+ sprintf(sc->sc_dev.dv_xname, "en%d", unit);
sc->enif.if_unit = unit;
sc->enif.if_name = "en";
- scp->en_confid = config_id;
/*
* figure out if we are an adaptec card or not.
@@ -261,12 +272,14 @@ int unit;
device_id = pci_conf_read(config_id, PCI_ID_REG);
sc->is_adaptec = (PCI_VENDOR(device_id) == PCI_VENDOR_ADP) ? 1 : 0;
+#ifdef SHUTDOWN_PRE_SYNC
/*
* Add shutdown hook so that DMA is disabled prior to reboot. Not
* doing so could allow DMA to corrupt kernel memory during the
* reboot before the driver initializes.
*/
at_shutdown(en_pci_shutdown, scp, SHUTDOWN_POST_SYNC);
+#endif
if (!pci_map_int(config_id, en_intr, (void *) sc, &net_imask)) {
printf("%s: couldn't establish interrupt\n", sc->sc_dev.dv_xname);
@@ -280,7 +293,6 @@ int unit;
#if !defined(MIDWAY_ENIONLY)
if (sc->is_adaptec) {
- adp_get_macaddr(scp);
sc->en_busreset = adp_busreset;
adp_busreset(sc);
}
@@ -288,7 +300,6 @@ int unit;
#if !defined(MIDWAY_ADPONLY)
if (!sc->is_adaptec) {
- eni_get_macaddr(scp);
sc->en_busreset = NULL;
pci_conf_write(config_id, EN_TONGA, (TONGA_SWAP_DMA|TONGA_SWAP_WORD));
}
@@ -302,6 +313,7 @@ int unit;
}
+#ifdef SHUTDOWN_PRE_SYNC
static void
en_pci_shutdown(
int howto,
@@ -312,126 +324,22 @@ en_pci_shutdown(
en_reset(&psc->esc);
DELAY(10);
}
+#else /* !SHUTDOWN_PRE_SYNC */
+static int
+en_pci_shutdown(kdc, force)
-#if !defined(MIDWAY_ENIONLY)
-
-#if defined(sparc) || defined(__FreeBSD__)
-#define bus_space_read_1(t, h, o) \
- ((void)t, (*(volatile u_int8_t *)((h) + (o))))
-#endif
-
-static void
-adp_get_macaddr(scp)
- struct en_pci_softc *scp;
-{
- struct en_softc * sc = (struct en_softc *)scp;
- int lcv;
-
- for (lcv = 0; lcv < sizeof(sc->macaddr); lcv++)
- sc->macaddr[lcv] = bus_space_read_1(sc->en_memt, sc->en_base,
- MID_ADPMACOFF + lcv);
-}
-
-#endif /* MIDWAY_ENIONLY */
-
-#if !defined(MIDWAY_ADPONLY)
+struct kern_devconf *kdc;
+int force;
-/*
- * Read station (MAC) address from serial EEPROM.
- * derived from linux drivers/atm/eni.c by Werner Almesberger, EPFL LRC.
- */
-#define EN_PROM_MAGIC 0x0c
-#define EN_PROM_DATA 0x02
-#define EN_PROM_CLK 0x01
-#define EN_ESI 64
-
-static void
-eni_get_macaddr(scp)
- struct en_pci_softc *scp;
{
- struct en_softc * sc = (struct en_softc *)scp;
- pcici_t id = scp->en_confid;
- int i, j, address, status;
- u_int32_t data, t_data;
- u_int8_t tmp;
-
- t_data = pci_conf_read(id, EN_TONGA) & 0xffffff00;
-
- data = EN_PROM_MAGIC | EN_PROM_DATA | EN_PROM_CLK;
- pci_conf_write(id, EN_TONGA, data);
-
- for (i = 0; i < sizeof(sc->macaddr); i ++){
- /* start operation */
- data |= EN_PROM_DATA ;
- pci_conf_write(id, EN_TONGA, data);
- data |= EN_PROM_CLK ;
- pci_conf_write(id, EN_TONGA, data);
- data &= ~EN_PROM_DATA ;
- pci_conf_write(id, EN_TONGA, data);
- data &= ~EN_PROM_CLK ;
- pci_conf_write(id, EN_TONGA, data);
- /* send address with serial line */
- address = ((i + EN_ESI) << 1) + 1;
- for ( j = 7 ; j >= 0 ; j --){
- data = (address >> j) & 1 ? data | EN_PROM_DATA :
- data & ~EN_PROM_DATA;
- pci_conf_write(id, EN_TONGA, data);
- data |= EN_PROM_CLK ;
- pci_conf_write(id, EN_TONGA, data);
- data &= ~EN_PROM_CLK ;
- pci_conf_write(id, EN_TONGA, data);
- }
- /* get ack */
- data |= EN_PROM_DATA ;
- pci_conf_write(id, EN_TONGA, data);
- data |= EN_PROM_CLK ;
- pci_conf_write(id, EN_TONGA, data);
- data = pci_conf_read(id, EN_TONGA);
- status = data & EN_PROM_DATA;
- data &= ~EN_PROM_CLK ;
- pci_conf_write(id, EN_TONGA, data);
- data |= EN_PROM_DATA ;
- pci_conf_write(id, EN_TONGA, data);
-
- tmp = 0;
-
- for ( j = 7 ; j >= 0 ; j --){
- tmp <<= 1;
- data |= EN_PROM_DATA ;
- pci_conf_write(id, EN_TONGA, data);
- data |= EN_PROM_CLK ;
- pci_conf_write(id, EN_TONGA, data);
- data = pci_conf_read(id, EN_TONGA);
- if(data & EN_PROM_DATA) tmp |= 1;
- data &= ~EN_PROM_CLK ;
- pci_conf_write(id, EN_TONGA, data);
- data |= EN_PROM_DATA ;
- pci_conf_write(id, EN_TONGA, data);
- }
- /* get ack */
- data |= EN_PROM_DATA ;
- pci_conf_write(id, EN_TONGA, data);
- data |= EN_PROM_CLK ;
- pci_conf_write(id, EN_TONGA, data);
- data = pci_conf_read(id, EN_TONGA);
- status = data & EN_PROM_DATA;
- data &= ~EN_PROM_CLK ;
- pci_conf_write(id, EN_TONGA, data);
- data |= EN_PROM_DATA ;
- pci_conf_write(id, EN_TONGA, data);
-
- sc->macaddr[i] = tmp;
+ if (kdc->kdc_unit < NEN) {
+ struct en_pci_softc *psc = enpcis[kdc->kdc_unit];
+ if (psc) /* can it be null? */
+ en_reset(&psc->esc);
+ DELAY(10);
}
- /* stop operation */
- data &= ~EN_PROM_DATA;
- pci_conf_write(id, EN_TONGA, data);
- data |= EN_PROM_CLK;
- pci_conf_write(id, EN_TONGA, data);
- data |= EN_PROM_DATA;
- pci_conf_write(id, EN_TONGA, data);
- pci_conf_write(id, EN_TONGA, t_data);
+ dev_detach(kdc);
+ return(0);
}
-
-#endif /* !MIDWAY_ADPONLY */
-
+#endif /* !SHUTDOWN_PRE_SYNC */
#endif /* NEN > 0 && NPCI > 0 */