summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authoronoe <onoe@NetBSD.org>2000-12-19 08:00:55 +0000
committeronoe <onoe@NetBSD.org>2000-12-19 08:00:55 +0000
commit684fe5613d3b9a8df29dd99ce3314e9fc39e6f46 (patch)
treea9dd846be296986ce9da1e5358e81eb27262944a /sys/dev
parent045091aa8f143ef9c6177eb42102d8bc35dd759c (diff)
cleanup attach procedure, use tsleep() instead of long delay (and ignore
timeouts). stop driver after suspend. XXX: should use command interrupt but no document... XXX: status update sometimes failed perhaps due to collision. (RID 0xff50 or 0xff68 access failed)
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/ic/an.c190
-rw-r--r--sys/dev/ic/anreg.h4
-rw-r--r--sys/dev/ic/anvar.h19
-rw-r--r--sys/dev/pcmcia/if_an_pcmcia.c202
4 files changed, 176 insertions, 239 deletions
diff --git a/sys/dev/ic/an.c b/sys/dev/ic/an.c
index 4da2910e0b9..742375fac38 100644
--- a/sys/dev/ic/an.c
+++ b/sys/dev/ic/an.c
@@ -1,4 +1,4 @@
-/* $NetBSD: an.c,v 1.8 2000/12/14 06:27:24 thorpej Exp $ */
+/* $NetBSD: an.c,v 1.9 2000/12/19 08:00:55 onoe Exp $ */
/*
* Copyright (c) 1997, 1998, 1999
* Bill Paul <wpaul@ctr.columbia.edu>. All rights reserved.
@@ -142,6 +142,7 @@ static const char rcsid[] =
/* These are global because we need them in sys/pci/if_an_p.c. */
static void an_reset __P((struct an_softc *));
+static void an_wait __P((struct an_softc *));
static int an_ioctl __P((struct ifnet *, u_long, caddr_t));
static int an_init __P((struct ifnet *));
static void an_stop __P((struct ifnet *, int));
@@ -172,57 +173,23 @@ static int an_media_change __P((struct ifnet *ifp));
static void an_media_status __P((struct ifnet *ifp, struct ifmediareq *imr));
#endif
-/*
- * We probe for an Aironet 4500/4800 card by attempting to
- * read the default SSID list. On reset, the first entry in
- * the SSID list will contain the name "tsunami." If we don't
- * find this, then there's no card present.
- */
-int an_probe(sc)
- struct an_softc *sc;
-{
- struct an_ltv_ssidlist ssid;
-
- bzero((char *)&ssid, sizeof(ssid));
-
- ssid.an_len = sizeof(ssid);
- ssid.an_type = AN_RID_SSIDLIST;
-
- /* Make sure interrupts are disabled. */
- CSR_WRITE_2(sc, AN_INT_EN, 0);
- CSR_WRITE_2(sc, AN_EVENT_ACK, 0xFFFF);
-
- an_reset(sc);
-
- if (an_cmd(sc, AN_CMD_READCFG, 0))
- return ENXIO;
-
- if (an_read_record(sc, (struct an_ltv_gen *)&ssid))
- return ENXIO;
-
- /* See if the ssid matches what we expect ... but doesn't have to */
- if (strcmp(ssid.an_ssid1, AN_DEF_SSID))
- return ENXIO;
-
- return 0;
-}
-
-int an_attach(sc)
- struct an_softc *sc;
+int
+an_attach(struct an_softc *sc)
{
struct ifnet *ifp = &sc->arpcom.ec_if;
+ int i, s;
#ifdef IFM_IEEE80211
- int i, mtype;
+ int mtype;
struct ifmediareq imr;
#endif
+ s = splnet();
sc->an_associated = 0;
-
- /* Reset the NIC. */
- an_reset(sc);
+ an_wait(sc);
/* Load factory config */
if (an_cmd(sc, AN_CMD_READCFG, 0)) {
+ splx(s);
printf("%s: failed to load config data\n", sc->an_dev.dv_xname);
return(EIO);
}
@@ -231,6 +198,7 @@ int an_attach(sc)
sc->an_config.an_type = AN_RID_GENCONFIG;
sc->an_config.an_len = sizeof(struct an_ltv_genconfig);
if (an_read_record(sc, (struct an_ltv_gen *)&sc->an_config)) {
+ splx(s);
printf("%s: read record failed\n", sc->an_dev.dv_xname);
return(EIO);
}
@@ -239,6 +207,7 @@ int an_attach(sc)
sc->an_caps.an_type = AN_RID_CAPABILITIES;
sc->an_caps.an_len = sizeof(struct an_ltv_caps);
if (an_read_record(sc, (struct an_ltv_gen *)&sc->an_caps)) {
+ splx(s);
printf("%s: read record failed\n", sc->an_dev.dv_xname);
return(EIO);
}
@@ -247,6 +216,7 @@ int an_attach(sc)
sc->an_ssidlist.an_type = AN_RID_SSIDLIST;
sc->an_ssidlist.an_len = sizeof(struct an_ltv_ssidlist);
if (an_read_record(sc, (struct an_ltv_gen *)&sc->an_ssidlist)) {
+ splx(s);
printf("%s: read record failed\n", sc->an_dev.dv_xname);
return(EIO);
}
@@ -255,6 +225,7 @@ int an_attach(sc)
sc->an_aplist.an_type = AN_RID_APLIST;
sc->an_aplist.an_len = sizeof(struct an_ltv_aplist);
if (an_read_record(sc, (struct an_ltv_gen *)&sc->an_aplist)) {
+ splx(s);
printf("%s: read record failed\n", sc->an_dev.dv_xname);
return(EIO);
}
@@ -326,13 +297,13 @@ int an_attach(sc)
ifmedia_set(&sc->sc_media, imr.ifm_active);
#endif
callout_init(&sc->an_stat_ch);
+ splx(s);
return(0);
}
int
-an_detach(sc)
- struct an_softc *sc;
+an_detach(struct an_softc *sc)
{
struct ifnet *ifp = &sc->arpcom.ec_if;
int s;
@@ -347,9 +318,7 @@ an_detach(sc)
}
int
-an_activate(self, act)
- struct device *self;
- enum devact act;
+an_activate(struct device *self, enum devact act)
{
struct an_softc *sc = (struct an_softc *)self;
int s, error = 0;
@@ -369,6 +338,41 @@ an_activate(self, act)
return error;
}
+void
+an_power(int why, void *arg)
+{
+ int s;
+ struct an_softc *sc = arg;
+ struct ifnet *ifp = &sc->arpcom.ec_if;
+
+ if (!sc->sc_enabled)
+ return;
+
+ s = splnet();
+ switch (why) {
+ case PWR_SUSPEND:
+ case PWR_STANDBY:
+ an_stop(ifp, 0);
+ break;
+ case PWR_RESUME:
+ break;
+ case PWR_SOFTSUSPEND:
+ case PWR_SOFTSTANDBY:
+ case PWR_SOFTRESUME:
+ break;
+ }
+ splx(s);
+}
+
+void
+an_shutdown(void *arg)
+{
+ struct an_softc *sc = arg;
+
+ an_stop(&sc->arpcom.ec_if, 1);
+ return;
+}
+
static void an_rxeof(sc)
struct an_softc *sc;
{
@@ -533,15 +537,12 @@ void an_stats_update(xsc)
return;
}
-int an_intr(xsc)
- void *xsc;
+int an_intr(void *arg)
{
- struct an_softc *sc;
+ struct an_softc *sc = arg;
struct ifnet *ifp;
u_int16_t status;
- sc = (struct an_softc*)xsc;
-
if (!sc->sc_enabled)
return 0;
@@ -589,6 +590,11 @@ int an_intr(xsc)
if (status & AN_EV_ALLOC)
CSR_WRITE_2(sc, AN_EVENT_ACK, AN_EV_ALLOC);
+ if (status & AN_EV_CMD) {
+ wakeup(sc);
+ CSR_WRITE_2(sc, AN_EVENT_ACK, AN_EV_CMD);
+ }
+
/* Re-enable interrupts. */
CSR_WRITE_2(sc, AN_INT_EN, AN_INTRS);
@@ -598,12 +604,10 @@ int an_intr(xsc)
return 1;
}
-static int an_cmd(sc, cmd, val)
- struct an_softc *sc;
- int cmd;
- int val;
+static int
+an_cmd(struct an_softc *sc, int cmd, int val)
{
- int i, s = 0;
+ int i;
CSR_WRITE_2(sc, AN_PARAM0, val);
CSR_WRITE_2(sc, AN_PARAM1, 0);
@@ -613,18 +617,14 @@ static int an_cmd(sc, cmd, val)
for (i = 0; i < AN_TIMEOUT; i++) {
if (CSR_READ_2(sc, AN_EVENT_STAT) & AN_EV_CMD)
break;
- else {
- if (CSR_READ_2(sc, AN_COMMAND) == cmd)
- CSR_WRITE_2(sc, AN_COMMAND, cmd);
- }
}
for (i = 0; i < AN_TIMEOUT; i++) {
CSR_READ_2(sc, AN_RESP0);
CSR_READ_2(sc, AN_RESP1);
CSR_READ_2(sc, AN_RESP2);
- s = CSR_READ_2(sc, AN_STATUS);
- if ((s & AN_STAT_CMD_CODE) == (cmd & AN_STAT_CMD_CODE))
+ if ((CSR_READ_2(sc, AN_STATUS) & AN_STAT_CMD_CODE) ==
+ (cmd & AN_STAT_CMD_CODE))
break;
}
@@ -645,12 +645,12 @@ static int an_cmd(sc, cmd, val)
* most reliable method I've found to really kick the NIC in the
* head and force it to reboot correctly.
*/
-static void an_reset(sc)
- struct an_softc *sc;
+static void
+an_reset(struct an_softc *sc)
{
if (!sc->sc_enabled)
return;
-
+
an_cmd(sc, AN_CMD_ENABLE, 0);
an_cmd(sc, AN_CMD_FW_RESTART, 0);
an_cmd(sc, AN_CMD_NOOP2, 0);
@@ -664,6 +664,26 @@ static void an_reset(sc)
}
/*
+ * Wait for firmware come up after power enabled.
+ */
+static void
+an_wait(struct an_softc *sc)
+{
+ int i;
+
+ if (!sc->sc_enabled)
+ return;
+
+ CSR_WRITE_2(sc, AN_COMMAND, AN_CMD_NOOP2);
+ for (i = 0; i < 3*hz; i++) {
+ if (CSR_READ_2(sc, AN_EVENT_STAT) & AN_EV_CMD)
+ break;
+ (void)tsleep(sc, PWAIT, "anatch", 1);
+ }
+ CSR_WRITE_2(sc, AN_EVENT_ACK, AN_EV_CMD);
+}
+
+/*
* Read an LTV record from the NIC.
*/
static int an_read_record(sc, ltv)
@@ -678,13 +698,15 @@ static int an_read_record(sc, ltv)
/* Tell the NIC to enter record read mode. */
if (an_cmd(sc, AN_CMD_ACCESS|AN_ACCESS_READ, ltv->an_type)) {
- printf("%s: RID access failed\n", sc->an_dev.dv_xname);
+ printf("%s: RID 0x%04x access failed\n", sc->an_dev.dv_xname,
+ ltv->an_type);
return(EIO);
}
/* Seek to the record. */
if (an_seek(sc, ltv->an_type, 0, AN_BAP1)) {
- printf("%s: seek to record failed\n", sc->an_dev.dv_xname);
+ printf("%s: RID 0x%04x seek to record failed\n",
+ sc->an_dev.dv_xname, ltv->an_type);
return(EIO);
}
@@ -695,8 +717,9 @@ static int an_read_record(sc, ltv)
*/
len = CSR_READ_2(sc, AN_DATA1);
if (len > ltv->an_len) {
- printf("%s: record length mismatch -- expected %d, "
- "got %d\n", sc->an_dev.dv_xname, ltv->an_len, len);
+ printf("%s: RID 0x%04x record length mismatch -- expected %d, "
+ "got %d\n", sc->an_dev.dv_xname,
+ ltv->an_type, ltv->an_len, len);
return(ENOSPC);
}
@@ -984,7 +1007,7 @@ static int an_ioctl(ifp, command, data)
u_long command;
caddr_t data;
{
- int i;
+ int i, s;
int error = 0;
struct an_softc *sc;
struct an_req areq;
@@ -996,6 +1019,7 @@ static int an_ioctl(ifp, command, data)
sc = ifp->if_softc;
ifr = (struct ifreq *)data;
+ s = splnet();
switch(command) {
case SIOCSIFFLAGS:
@@ -1146,6 +1170,7 @@ static int an_ioctl(ifp, command, data)
break;
}
out:
+ splx(s);
return(error);
}
@@ -1247,13 +1272,19 @@ static int an_init_tx_ring(sc)
return(0);
}
-static int an_init(ifp)
- struct ifnet *ifp;
+static int
+an_init(struct ifnet *ifp)
{
- struct an_softc *sc = (struct an_softc *)ifp->if_softc;
+ struct an_softc *sc = (struct an_softc *)ifp->if_softc;
if (ifp->if_flags & IFF_RUNNING)
an_stop(ifp, 0);
+ else if (sc->sc_enabled) {
+ /* re-enable to power on after resume ... */
+ if (sc->sc_disable)
+ (*sc->sc_disable)(sc);
+ sc->sc_enabled = 0;
+ }
sc->an_associated = 0;
@@ -1261,6 +1292,7 @@ static int an_init(ifp)
if (sc->sc_enable)
(*sc->sc_enable)(sc);
sc->sc_enabled = 1;
+ an_wait(sc);
}
/* Allocate the TX buffers */
@@ -1451,6 +1483,7 @@ void an_stop(ifp, disable)
an_cmd(sc, AN_CMD_DEALLOC_MEM, sc->an_rdata.an_tx_fids[i]);
ifp->if_flags &= ~(IFF_RUNNING|IFF_OACTIVE);
+ ifp->if_timer = 0;
if (disable) {
if (sc->sc_disable)
@@ -1479,15 +1512,6 @@ static void an_watchdog(ifp)
return;
}
-void an_shutdown(dev)
- struct device * dev;
-{
- struct an_softc *sc = (struct an_softc *)dev;
- an_stop(&sc->arpcom.ec_if, 1);
-
- return;
-}
-
#ifdef ANCACHE
/* Aironet signal strength cache code.
* store signal/noise/quality on per MAC src basis in
diff --git a/sys/dev/ic/anreg.h b/sys/dev/ic/anreg.h
index 2def231b021..1ae74549dc3 100644
--- a/sys/dev/ic/anreg.h
+++ b/sys/dev/ic/anreg.h
@@ -1,4 +1,4 @@
-/* $NetBSD: anreg.h,v 1.3 2000/12/12 05:11:15 onoe Exp $ */
+/* $NetBSD: anreg.h,v 1.4 2000/12/19 08:00:56 onoe Exp $ */
/*
* Copyright (c) 1997, 1998, 1999
* Bill Paul <wpaul@ctr.columbia.edu>. All rights reserved.
@@ -163,7 +163,7 @@
#define AN_EV_RX 0x0001 /* async rx completed */
#define AN_INTRS \
- (AN_EV_RX|AN_EV_TX|AN_EV_TX_EXC|AN_EV_ALLOC|AN_EV_LINKSTAT)
+ (AN_EV_RX|AN_EV_TX|AN_EV_TX_EXC|AN_EV_ALLOC|AN_EV_LINKSTAT|AN_EV_CMD)
/* Host software registers */
#define AN_SW0 0x28
diff --git a/sys/dev/ic/anvar.h b/sys/dev/ic/anvar.h
index 491cb3e76b5..49087c93109 100644
--- a/sys/dev/ic/anvar.h
+++ b/sys/dev/ic/anvar.h
@@ -1,4 +1,4 @@
-/* $NetBSD: anvar.h,v 1.3 2000/12/14 04:11:26 onoe Exp $ */
+/* $NetBSD: anvar.h,v 1.4 2000/12/19 08:00:56 onoe Exp $ */
/*
* Copyright (c) 1997, 1998, 1999
* Bill Paul <wpaul@ctr.columbia.edu>. All rights reserved.
@@ -98,10 +98,8 @@ struct an_req {
*/
#define AN_RID_IFACE_STATS 0x0100
#define AN_RID_MGMT_XMIT 0x0200
-#ifdef ANCACHE
#define AN_RID_ZERO_CACHE 0x0300
#define AN_RID_READ_CACHE 0x0400
-#endif
#define AN_RID_TX_SPEED 0x1234
/*
@@ -113,7 +111,6 @@ struct an_req {
*
* Each entry in the wi_sigcache has a unique macsrc.
*/
-#ifdef ANCACHE
#define MAXANCACHE 10
struct an_sigcache {
@@ -123,7 +120,6 @@ struct an_sigcache {
int noise; /* noise value */
int quality; /* quality of the packet */
};
-#endif
#define AN_TXGAP_80211 0
#define AN_TXGAP_8023 0
@@ -144,6 +140,7 @@ struct an_softc {
int (*sc_enable) __P((struct an_softc *));
void (*sc_disable) __P((struct an_softc *));
int sc_enabled;
+ int sc_invalid;
struct ifmedia sc_media;
bus_space_handle_t an_bhandle;
@@ -162,23 +159,17 @@ struct an_softc {
struct an_ltv_stats an_stats;
struct an_ltv_status an_status;
u_int8_t an_associated;
-#ifdef ANCACHE
int an_sigitems;
struct an_sigcache an_sigcache[MAXANCACHE];
int an_nextitem;
-#endif
struct callout an_stat_ch;
};
-void an_release_resources __P((struct device *));
-int an_alloc_port __P((struct device *, int, int));
-int an_alloc_memory __P((struct device *, int, int));
-int an_alloc_irq __P((struct device *, int, int));
-int an_probe __P((struct an_softc *));
-void an_shutdown __P((struct device *));
int an_attach __P((struct an_softc *));
int an_detach __P((struct an_softc *));
-int an_intr __P((void *));
int an_activate __P((struct device *, enum devact));
+void an_power __P((int, void *));
+void an_shutdown __P((void *));
+int an_intr __P((void *));
#endif /* _DEV_IC_ANVAR_H */
diff --git a/sys/dev/pcmcia/if_an_pcmcia.c b/sys/dev/pcmcia/if_an_pcmcia.c
index 1f9ef07ecc2..6788eae6ace 100644
--- a/sys/dev/pcmcia/if_an_pcmcia.c
+++ b/sys/dev/pcmcia/if_an_pcmcia.c
@@ -1,4 +1,4 @@
-/* $NetBSD: if_an_pcmcia.c,v 1.6 2000/12/19 01:59:21 onoe Exp $ */
+/* $NetBSD: if_an_pcmcia.c,v 1.7 2000/12/19 08:00:56 onoe Exp $ */
/*-
* Copyright (c) 2000 The NetBSD Foundation, Inc.
@@ -95,7 +95,6 @@ static void an_pcmcia_attach __P((struct device *, struct device *, void *));
static int an_pcmcia_detach __P((struct device *, int));
static int an_pcmcia_enable __P((struct an_softc *));
static void an_pcmcia_disable __P((struct an_softc *));
-static void an_pcmcia_powerhook __P((int, void *));
struct an_pcmcia_softc {
struct an_softc sc_an; /* real "an" softc */
@@ -108,9 +107,6 @@ struct an_pcmcia_softc {
void *sc_powerhook; /* power hook descriptor */
};
-static int an_pcmcia_find __P((struct an_pcmcia_softc *,
- struct pcmcia_attach_args *, struct pcmcia_config_entry *));
-
struct cfattach an_pcmcia_ca = {
sizeof(struct an_pcmcia_softc), an_pcmcia_match, an_pcmcia_attach,
an_pcmcia_detach, an_activate
@@ -130,36 +126,6 @@ static struct an_pcmcia_product {
{ NULL, NULL, NULL, NULL }, NULL }
};
-static struct an_pcmcia_product *
- an_pcmcia_lookup __P((struct pcmcia_attach_args *));
-
-static struct an_pcmcia_product *
-an_pcmcia_lookup(pa)
- struct pcmcia_attach_args *pa;
-{
- struct an_pcmcia_product *app;
-
- for (app = an_pcmcia_products; app->app_name != NULL; app++) {
- /* match by vendor/product id */
- if (pa->manufacturer != PCMCIA_VENDOR_INVALID &&
- pa->manufacturer == app->app_vendor &&
- pa->product != PCMCIA_PRODUCT_INVALID &&
- pa->product == app->app_product)
- return (app);
-
- /* match by CIS information */
- if (pa->card->cis1_info[0] != NULL &&
- app->app_cisinfo[0] != NULL &&
- strcmp(pa->card->cis1_info[0], app->app_cisinfo[0]) == 0 &&
- pa->card->cis1_info[1] != NULL &&
- app->app_cisinfo[1] != NULL &&
- strcmp(pa->card->cis1_info[1], app->app_cisinfo[1]) == 0)
- return (app);
- }
-
- return (NULL);
-}
-
static int
an_pcmcia_enable(sc)
struct an_softc *sc;
@@ -202,60 +168,26 @@ an_pcmcia_match(parent, match, aux)
void *aux;
{
struct pcmcia_attach_args *pa = aux;
+ struct an_pcmcia_product *app;
- if (an_pcmcia_lookup(pa) != NULL)
- return (1);
-
- return (0);
-}
-
-static int
-an_pcmcia_find(psc, pa, cfe)
- struct an_pcmcia_softc *psc;
- struct pcmcia_attach_args *pa;
- struct pcmcia_config_entry *cfe;
-{
- struct an_softc *sc = &psc->sc_an;
- int fail = 0;
-
- /*
- * see if we can read the firmware version sanely
- * through the i/o ports.
- * if not, try a different CIS string..
- */
- if (pcmcia_io_alloc(psc->sc_pf, cfe->iospace[0].start,
- cfe->iospace[0].length, AN_IOSIZ,
- &psc->sc_pcioh) != 0)
- goto fail;
-
- if (pcmcia_io_map(psc->sc_pf, PCMCIA_WIDTH_AUTO, 0, psc->sc_pcioh.size,
- &psc->sc_pcioh, &psc->sc_io_window))
- goto fail_io_free;
-
- /* Enable the card. */
- pcmcia_function_init(psc->sc_pf, cfe);
- if (pcmcia_function_enable(psc->sc_pf))
- goto fail_io_unmap;
-
- sc->an_btag = psc->sc_pcioh.iot;
- sc->an_bhandle = psc->sc_pcioh.ioh;
-
- if (an_probe(sc) == 0)
- return 0;
-
- fail++;
- pcmcia_function_disable(psc->sc_pf);
-
- fail_io_unmap:
- fail++;
- pcmcia_io_unmap(psc->sc_pf, psc->sc_io_window);
+ for (app = an_pcmcia_products; app->app_name != NULL; app++) {
+ /* match by vendor/product id */
+ if (pa->manufacturer != PCMCIA_VENDOR_INVALID &&
+ pa->manufacturer == app->app_vendor &&
+ pa->product != PCMCIA_PRODUCT_INVALID &&
+ pa->product == app->app_product)
+ return 1;
- fail_io_free:
- fail++;
- pcmcia_io_free(psc->sc_pf, &psc->sc_pcioh);
- fail:
- fail++;
- return (fail);
+ /* match by CIS information */
+ if (pa->card->cis1_info[0] != NULL &&
+ app->app_cisinfo[0] != NULL &&
+ strcmp(pa->card->cis1_info[0], app->app_cisinfo[0]) == 0 &&
+ pa->card->cis1_info[1] != NULL &&
+ app->app_cisinfo[1] != NULL &&
+ strcmp(pa->card->cis1_info[1], app->app_cisinfo[1]) == 0)
+ return 1;
+ }
+ return 0;
}
static void
@@ -265,71 +197,74 @@ an_pcmcia_attach(parent, self, aux)
{
struct an_pcmcia_softc *psc = (void *)self;
struct an_softc *sc = &psc->sc_an;
- struct an_pcmcia_product *app;
struct pcmcia_attach_args *pa = aux;
struct pcmcia_config_entry *cfe;
- app = an_pcmcia_lookup(pa);
- if (app == NULL)
- panic("an_pcmcia_attach: impossible");
-
psc->sc_pf = pa->pf;
+ if ((cfe = SIMPLEQ_FIRST(&pa->pf->cfe_head)) == NULL) {
+ printf(": no suitable CIS info found\n");
+ goto fail1;
+ }
- for (cfe = SIMPLEQ_FIRST(&pa->pf->cfe_head); cfe != NULL;
- cfe = SIMPLEQ_NEXT(cfe, cfe_list)) {
- if (cfe->iftype != PCMCIA_IFTYPE_IO)
- continue;
- if (cfe->num_iospace < 1)
- continue;
- if (cfe->iospace[0].length < AN_IOSIZ)
- continue;
-
- if (an_pcmcia_find(psc, pa, cfe) == 0)
- break;
+ if (pcmcia_io_alloc(psc->sc_pf, cfe->iospace[0].start,
+ cfe->iospace[0].length, AN_IOSIZ, &psc->sc_pcioh) != 0) {
+ printf(": failed to allocate io space\n");
+ goto fail1;
}
- if (cfe == NULL) {
- printf(": no suitable CIS info found\n");
- goto no_config_entry;
+
+ if (pcmcia_io_map(psc->sc_pf, PCMCIA_WIDTH_AUTO, 0, psc->sc_pcioh.size,
+ &psc->sc_pcioh, &psc->sc_io_window) != 0) {
+ printf(": failed to map io space\n");
+ goto fail2;
}
- sc->sc_enabled = 1;
- printf(": %s\n", app->app_name);
+ pcmcia_function_init(psc->sc_pf, cfe);
- sc->sc_enable = an_pcmcia_enable;
- sc->sc_disable = an_pcmcia_disable;
+ if (pcmcia_function_enable(psc->sc_pf)) {
+ printf(": failed to enable pcmcia\n");
+ goto fail3;
+ }
- /* establish the interrupt. */
- psc->sc_ih = pcmcia_intr_establish(psc->sc_pf, IPL_NET, an_intr, sc);
- if (psc->sc_ih == NULL) {
- printf("%s: couldn't establish interrupt\n",
- sc->an_dev.dv_xname);
- goto no_interrupt;
+ if ((psc->sc_ih = pcmcia_intr_establish(psc->sc_pf, IPL_NET, an_intr,
+ sc)) == NULL) {
+ printf(": unable to establish interrupt\n");
+ goto fail4;
+ }
+
+ if (pa->card->cis1_info[0] != NULL) {
+ printf(": %s", pa->card->cis1_info[0]);
+ if (pa->card->cis1_info[1] != NULL)
+ printf(" %s", pa->card->cis1_info[1]);
}
+ printf("\n");
+
+ sc->an_btag = psc->sc_pcioh.iot;
+ sc->an_bhandle = psc->sc_pcioh.ioh;
+ sc->sc_enabled = 1;
+ sc->sc_enable = an_pcmcia_enable;
+ sc->sc_disable = an_pcmcia_disable;
if (an_attach(sc) != 0) {
printf("%s: failed to attach controller\n",
sc->an_dev.dv_xname);
- goto attach_failed;
+ goto fail5;;
}
- psc->sc_powerhook = powerhook_establish(an_pcmcia_powerhook, psc);
+ psc->sc_powerhook = powerhook_establish(an_power, sc);
sc->sc_enabled = 0;
/* disable device and disestablish the interrupt */
an_pcmcia_disable(sc);
return;
- attach_failed:
+ fail5:
pcmcia_intr_disestablish(psc->sc_pf, psc->sc_ih);
-
- no_interrupt:
- /* Unmap our i/o window and space */
+ fail4:
+ pcmcia_function_disable(psc->sc_pf);
+ fail3:
pcmcia_io_unmap(psc->sc_pf, psc->sc_io_window);
+ fail2:
pcmcia_io_free(psc->sc_pf, &psc->sc_pcioh);
-
- /* Disable the function */
- pcmcia_function_disable(psc->sc_pf);
-
- no_config_entry:
+ fail1:
psc->sc_io_window = -1;
}
@@ -360,16 +295,3 @@ an_pcmcia_detach(self, flags)
pcmcia_io_free(psc->sc_pf, &psc->sc_pcioh);
return (0);
}
-
-static void
-an_pcmcia_powerhook(why, arg)
- int why;
- void *arg;
-{
-#if 0
- struct an_pcmcia_softc *psc = arg;
- struct an_softc *sc = &psc->sc_an;
-
- an_power(sc, why);
-#endif
-}