Use pcmcia_function_{configure,unconfigure}().
This commit is contained in:
parent
2137977a97
commit
7f6dd84dc4
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: com_pcmcia.c,v 1.43 2004/08/09 18:30:51 mycroft Exp $ */
|
||||
/* $NetBSD: com_pcmcia.c,v 1.44 2004/08/10 02:55:30 mycroft Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1998 The NetBSD Foundation, Inc.
|
||||
|
@ -68,7 +68,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: com_pcmcia.c,v 1.43 2004/08/09 18:30:51 mycroft Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: com_pcmcia.c,v 1.44 2004/08/10 02:55:30 mycroft Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
|
@ -110,6 +110,7 @@ static int com_devs_size = sizeof(com_devs) / sizeof(com_devs[0]);
|
|||
static struct com_dev *com_dev_match __P((struct pcmcia_card *));
|
||||
|
||||
int com_pcmcia_match __P((struct device *, struct cfdata *, void *));
|
||||
int com_pcmcia_validate_config __P((struct pcmcia_config_entry *));
|
||||
void com_pcmcia_attach __P((struct device *, struct device *, void *));
|
||||
int com_pcmcia_detach __P((struct device *, int));
|
||||
void com_pcmcia_cleanup __P((void *));
|
||||
|
@ -121,10 +122,9 @@ struct com_pcmcia_softc {
|
|||
struct com_softc sc_com; /* real "com" softc */
|
||||
|
||||
/* PCMCIA-specific goo */
|
||||
struct pcmcia_io_handle sc_pcioh; /* PCMCIA i/o space info */
|
||||
int sc_io_window; /* our i/o window */
|
||||
struct pcmcia_function *sc_pf; /* our PCMCIA function */
|
||||
void *sc_ih; /* interrupt handler */
|
||||
int sc_attached;
|
||||
};
|
||||
|
||||
CFATTACH_DECL(com_pcmcia, sizeof(struct com_pcmcia_softc),
|
||||
|
@ -194,6 +194,20 @@ com_pcmcia_match(parent, match, aux)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
com_pcmcia_validate_config(cfe)
|
||||
struct pcmcia_config_entry *cfe;
|
||||
{
|
||||
if (cfe->iftype != PCMCIA_IFTYPE_IO ||
|
||||
cfe->num_iospace != 1)
|
||||
return (EINVAL);
|
||||
/* Some cards have a memory space, but we don't use it. */
|
||||
cfe->num_memspace = 0;
|
||||
/* Some cards don't have IO8 in their CIS. */
|
||||
cfe->flags |= PCMCIA_CFE_IO8;
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
com_pcmcia_attach(parent, self, aux)
|
||||
struct device *parent, *self;
|
||||
|
@ -203,86 +217,31 @@ com_pcmcia_attach(parent, self, aux)
|
|||
struct com_softc *sc = &psc->sc_com;
|
||||
struct pcmcia_attach_args *pa = aux;
|
||||
struct pcmcia_config_entry *cfe;
|
||||
int autoalloc = 0;
|
||||
int error;
|
||||
|
||||
aprint_normal("\n");
|
||||
|
||||
psc->sc_pf = pa->pf;
|
||||
|
||||
psc->sc_io_window = -1;
|
||||
|
||||
retry:
|
||||
/* find a cfe we can use */
|
||||
|
||||
SIMPLEQ_FOREACH(cfe, &pa->pf->cfe_head, cfe_list) {
|
||||
#if 0
|
||||
/*
|
||||
* Some modem cards (e.g. Xircom CM33) also have
|
||||
* mem space. Don't bother with this check.
|
||||
*/
|
||||
if (cfe->num_memspace != 0)
|
||||
continue;
|
||||
#endif
|
||||
|
||||
if (cfe->num_iospace != 1)
|
||||
continue;
|
||||
|
||||
if (autoalloc == 0) {
|
||||
/*
|
||||
* cfe->iomask == 3 is our test for the "generic"
|
||||
* config table entry, which we want to avoid on the
|
||||
* first pass and use exclusively on the second pass.
|
||||
*/
|
||||
if ((cfe->iomask != 3) &&
|
||||
(cfe->iospace[0].start != 0)) {
|
||||
if (!pcmcia_io_alloc(pa->pf,
|
||||
cfe->iospace[0].start,
|
||||
cfe->iospace[0].length,
|
||||
cfe->iospace[0].length, &psc->sc_pcioh)) {
|
||||
goto found;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (cfe->iomask == 3) {
|
||||
if (!pcmcia_io_alloc(pa->pf, 0,
|
||||
cfe->iospace[0].length,
|
||||
cfe->iospace[0].length, &psc->sc_pcioh)) {
|
||||
goto found;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (autoalloc == 0) {
|
||||
autoalloc = 1;
|
||||
goto retry;
|
||||
} else if (!cfe) {
|
||||
aprint_error("%s: can't allocate i/o space\n", self->dv_xname);
|
||||
return;
|
||||
}
|
||||
found:
|
||||
/* Enable the card. */
|
||||
pcmcia_function_init(pa->pf, cfe);
|
||||
|
||||
if (pcmcia_io_map(pa->pf, ((cfe->flags & PCMCIA_CFE_IO16) ?
|
||||
PCMCIA_WIDTH_AUTO : PCMCIA_WIDTH_IO8), &psc->sc_pcioh,
|
||||
&psc->sc_io_window)) {
|
||||
aprint_error("%s: can't map i/o space\n", self->dv_xname);
|
||||
error = pcmcia_function_configure(pa->pf, com_pcmcia_validate_config);
|
||||
if (error) {
|
||||
aprint_error("%s: configure failed, error=%d\n", self->dv_xname,
|
||||
error);
|
||||
return;
|
||||
}
|
||||
|
||||
if (com_pcmcia_enable(sc)) {
|
||||
aprint_error("%s: function enable failed\n", self->dv_xname);
|
||||
pcmcia_io_unmap(psc->sc_pf, psc->sc_io_window);
|
||||
return;
|
||||
cfe = pa->pf->cfe;
|
||||
sc->sc_iot = cfe->iospace[0].handle.iot;
|
||||
sc->sc_ioh = cfe->iospace[0].handle.ioh;
|
||||
|
||||
error = com_pcmcia_enable(sc);
|
||||
if (error) {
|
||||
aprint_error("%s: enable failed, error=%d\n", self->dv_xname,
|
||||
error);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
sc->enabled = 1;
|
||||
|
||||
/* map in the io space */
|
||||
|
||||
sc->sc_iot = psc->sc_pcioh.iot;
|
||||
sc->sc_ioh = psc->sc_pcioh.ioh;
|
||||
|
||||
sc->sc_iobase = -1;
|
||||
sc->sc_frequency = COM_FREQ;
|
||||
|
||||
|
@ -295,7 +254,12 @@ found:
|
|||
|
||||
sc->enabled = 0;
|
||||
|
||||
psc->sc_attached = 1;
|
||||
com_pcmcia_disable(sc);
|
||||
return;
|
||||
|
||||
fail:
|
||||
pcmcia_function_unconfigure(pa->pf);
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -306,23 +270,14 @@ com_pcmcia_detach(self, flags)
|
|||
struct com_pcmcia_softc *psc = (struct com_pcmcia_softc *) self;
|
||||
int error;
|
||||
|
||||
/* Unmap our i/o window. */
|
||||
if (psc->sc_io_window == -1) {
|
||||
printf("%s: I/O window not allocated.\n",
|
||||
psc->sc_com.sc_dev.dv_xname);
|
||||
return 0;
|
||||
}
|
||||
if (!psc->sc_attached)
|
||||
return (0);
|
||||
|
||||
if ((error = com_detach(self, flags)) != 0)
|
||||
return error;
|
||||
|
||||
/* Unmap our i/o window. */
|
||||
pcmcia_io_unmap(psc->sc_pf, psc->sc_io_window);
|
||||
|
||||
/* Free our i/o space. */
|
||||
pcmcia_io_free(psc->sc_pf, &psc->sc_pcioh);
|
||||
|
||||
return 0;
|
||||
pcmcia_function_unconfigure(psc->sc_pf);
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -343,6 +298,7 @@ com_pcmcia_enable(sc)
|
|||
|
||||
if ((error = pcmcia_function_enable(pf)) != 0) {
|
||||
pcmcia_intr_disestablish(pf, psc->sc_ih);
|
||||
psc->sc_ih = 0;
|
||||
return (error);
|
||||
}
|
||||
|
||||
|
@ -370,4 +326,5 @@ com_pcmcia_disable(sc)
|
|||
|
||||
pcmcia_function_disable(psc->sc_pf);
|
||||
pcmcia_intr_disestablish(psc->sc_pf, psc->sc_ih);
|
||||
psc->sc_ih = 0;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
/* $NetBSD: if_ray.c,v 1.48 2004/08/09 21:30:18 mycroft Exp $ */
|
||||
/* $NetBSD: if_ray.c,v 1.49 2004/08/10 02:54:19 mycroft Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2000 Christian E. Hopps
|
||||
* All rights reserved.
|
||||
|
@ -56,7 +57,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: if_ray.c,v 1.48 2004/08/09 21:30:18 mycroft Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: if_ray.c,v 1.49 2004/08/10 02:54:19 mycroft Exp $");
|
||||
|
||||
#include "opt_inet.h"
|
||||
#include "bpfilter.h"
|
||||
|
@ -156,11 +157,11 @@ struct ray_softc {
|
|||
struct ifmedia sc_media;
|
||||
|
||||
struct pcmcia_function *sc_pf;
|
||||
struct pcmcia_mem_handle sc_mem;
|
||||
int sc_window;
|
||||
void *sc_ih;
|
||||
void *sc_sdhook;
|
||||
void *sc_pwrhook;
|
||||
int sc_attached;
|
||||
|
||||
int sc_flags; /*. misc flags */
|
||||
#define RAY_FLAGS_RESUMEINIT 0x0001
|
||||
int sc_resetloop;
|
||||
|
@ -214,12 +215,13 @@ struct ray_softc {
|
|||
struct ray_param_req *sc_repreq;
|
||||
struct ray_param_req *sc_updreq;
|
||||
|
||||
bus_space_tag_t sc_memt;
|
||||
bus_space_handle_t sc_memh;
|
||||
|
||||
#ifdef RAY_DO_SIGLEV
|
||||
struct ray_siglev sc_siglevs[RAY_NSIGLEVRECS];
|
||||
#endif
|
||||
};
|
||||
#define sc_memt sc_mem.memt
|
||||
#define sc_memh sc_mem.memh
|
||||
#define sc_ccrt sc_pf->pf_ccrt
|
||||
#define sc_ccrh sc_pf->pf_ccrh
|
||||
#define sc_ccroff sc_pf->pf_ccr_offset
|
||||
|
@ -280,6 +282,7 @@ typedef void (*ray_cmd_func_t)(struct ray_softc *);
|
|||
static int ray_alloc_ccs __P((struct ray_softc *, bus_size_t *, u_int, u_int));
|
||||
static bus_size_t ray_fill_in_tx_ccs __P((struct ray_softc *, size_t,
|
||||
u_int, u_int));
|
||||
static int ray_validate_config __P((struct pcmcia_config_entry *));
|
||||
static void ray_attach __P((struct device *, struct device *, void *));
|
||||
static ray_cmd_func_t ray_ccs_done __P((struct ray_softc *, bus_size_t));
|
||||
static void ray_check_ccs __P((void *));
|
||||
|
@ -491,6 +494,17 @@ ray_match(parent, match, aux)
|
|||
&& pa->product == PCMCIA_PRODUCT_RAYTHEON_WLAN);
|
||||
}
|
||||
|
||||
static int
|
||||
ray_validate_config(cfe)
|
||||
struct pcmcia_config_entry *cfe;
|
||||
{
|
||||
if (cfe->iftype != PCMCIA_IFTYPE_IO ||
|
||||
cfe->num_memspace != 1 ||
|
||||
cfe->num_iospace != 0 ||
|
||||
cfe->memspace[0].length != RAY_SRAM_MEM_SIZE)
|
||||
return (EINVAL);
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
ray_attach(parent, self, aux)
|
||||
|
@ -502,45 +516,32 @@ ray_attach(parent, self, aux)
|
|||
struct ifnet *ifp = &sc->sc_if;
|
||||
struct pcmcia_config_entry *cfe;
|
||||
struct ray_ecf_startup *ep;
|
||||
bus_size_t memoff;
|
||||
|
||||
sc->sc_window = -1;
|
||||
int error;
|
||||
|
||||
aprint_normal("\n");
|
||||
sc->sc_pf = pa->pf;
|
||||
|
||||
SIMPLEQ_FOREACH(cfe, &pa->pf->cfe_head, cfe_list) {
|
||||
if (cfe->num_memspace != 1)
|
||||
continue;
|
||||
if (cfe->num_iospace != 0)
|
||||
continue;
|
||||
|
||||
if (pcmcia_mem_alloc(pa->pf, cfe->memspace[0].length,
|
||||
&sc->sc_mem) == 0)
|
||||
break;
|
||||
}
|
||||
if (!cfe) {
|
||||
aprint_error("%s: can't alloc shared memory\n", self->dv_xname);
|
||||
goto fail1;
|
||||
/*XXXmem8|common*/
|
||||
error = pcmcia_function_configure(pa->pf, ray_validate_config);
|
||||
if (error) {
|
||||
aprint_error("%s: configure failed, error=%d\n", self->dv_xname,
|
||||
error);
|
||||
return;
|
||||
}
|
||||
|
||||
/* enable the card */
|
||||
pcmcia_function_init(sc->sc_pf, cfe);
|
||||
|
||||
if (pcmcia_mem_map(sc->sc_pf, PCMCIA_WIDTH_MEM8|PCMCIA_MEM_COMMON,
|
||||
RAY_SRAM_MEM_BASE, RAY_SRAM_MEM_SIZE, &sc->sc_mem, &memoff,
|
||||
&sc->sc_window)) {
|
||||
aprint_error("%s: can't map shared memory\n", self->dv_xname);
|
||||
goto fail2;
|
||||
}
|
||||
cfe = pa->pf->cfe;
|
||||
sc->sc_memt = cfe->memspace[0].handle.memt;
|
||||
sc->sc_memh = cfe->memspace[0].handle.memh;
|
||||
|
||||
callout_init(&sc->sc_reset_resetloop_ch);
|
||||
callout_init(&sc->sc_disable_ch);
|
||||
callout_init(&sc->sc_start_join_timo_ch);
|
||||
|
||||
if (ray_enable(sc)) {
|
||||
aprint_error("%s: failed to enable the card\n", self->dv_xname);
|
||||
goto fail3;
|
||||
error = ray_enable(sc);
|
||||
if (error) {
|
||||
aprint_error("%s: enable failed, error=%d\n", self->dv_xname,
|
||||
error);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* get startup results */
|
||||
|
@ -552,14 +553,14 @@ ray_attach(parent, self, aux)
|
|||
if (ep->e_status != RAY_ECFS_CARD_OK) {
|
||||
aprint_error("%s: card failed self test: status %d\n",
|
||||
self->dv_xname, sc->sc_ecf_startup.e_status);
|
||||
goto fail4;
|
||||
goto fail2;
|
||||
}
|
||||
|
||||
/* check firmware version */
|
||||
if (sc->sc_version != SC_BUILD_4 && sc->sc_version != SC_BUILD_5) {
|
||||
aprint_error("%s: unsupported firmware version %d\n",
|
||||
self->dv_xname, ep->e_fw_build_string);
|
||||
goto fail4;
|
||||
goto fail2;
|
||||
}
|
||||
|
||||
/* clear any interrupt if present */
|
||||
|
@ -620,17 +621,14 @@ ray_attach(parent, self, aux)
|
|||
sc->sc_pwrhook = powerhook_establish(ray_power, sc);
|
||||
|
||||
/* The attach is successful. */
|
||||
sc->sc_attached = 1;
|
||||
ray_disable(sc);
|
||||
return;
|
||||
|
||||
fail4:
|
||||
ray_disable(sc);
|
||||
fail3:
|
||||
pcmcia_mem_unmap(sc->sc_pf, sc->sc_window);
|
||||
fail2:
|
||||
pcmcia_mem_free(sc->sc_pf, &sc->sc_mem);
|
||||
fail1:
|
||||
sc->sc_window = -1;
|
||||
ray_disable(sc);
|
||||
fail:
|
||||
pcmcia_function_unconfigure(pa->pf);
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -671,8 +669,7 @@ ray_detach(self, flags)
|
|||
ifp = &sc->sc_if;
|
||||
RAY_DPRINTF(("%s: detach\n", sc->sc_xname));
|
||||
|
||||
if (sc->sc_window == -1)
|
||||
/* Nothing to detach. */
|
||||
if (!sc->sc_attached)
|
||||
return (0);
|
||||
|
||||
if (sc->sc_pwrhook)
|
||||
|
@ -686,8 +683,7 @@ ray_detach(self, flags)
|
|||
ether_ifdetach(ifp);
|
||||
if_detach(ifp);
|
||||
|
||||
pcmcia_mem_unmap(sc->sc_pf, sc->sc_window);
|
||||
pcmcia_mem_free(sc->sc_pf, &sc->sc_mem);
|
||||
pcmcia_function_unconfigure(sc->sc_pf);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
@ -709,8 +705,10 @@ ray_enable(sc)
|
|||
return (EIO);
|
||||
|
||||
error = ray_init(sc);
|
||||
if (error)
|
||||
if (error) {
|
||||
pcmcia_intr_disestablish(sc->sc_pf, sc->sc_ih);
|
||||
sc->sc_ih = 0;
|
||||
}
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
@ -732,9 +730,10 @@ ray_disable(sc)
|
|||
sc->sc_rxhcksum = 0;
|
||||
sc->sc_rxnoise = 0;
|
||||
|
||||
if (sc->sc_ih)
|
||||
if (sc->sc_ih) {
|
||||
pcmcia_intr_disestablish(sc->sc_pf, sc->sc_ih);
|
||||
sc->sc_ih = 0;
|
||||
sc->sc_ih = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in New Issue