1
0
mirror of https://git.FreeBSD.org/src.git synced 2025-01-17 15:27:36 +00:00

Eliminate pccard_chip_* tonight.

o ifdef out pccardchip.h (almost all of it, there are dangling bits
o Add rid/res members to pccard_function
o remove pct/pch from pccard_softc
o map memory properly in scan_cis (almost, see XXX for more work)
o manage ccr.
o remove bogus comment I added about touching the ccr being a layering
  violation for pccard.  It is properly done at that level.
o More function prototyping
This commit is contained in:
Warner Losh 2000-01-10 06:58:17 +00:00
parent 62410b5785
commit 78ae73b5ea
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=55720
4 changed files with 68 additions and 328 deletions

View File

@ -78,8 +78,6 @@ int pccard_card_intr(void *);
int pccard_card_intrdebug(void *);
#endif
/* XXX Shouldn't be touching hardware, that's a layering violation */
/* XXX imp */
int
pccard_ccr_read(pf, ccr)
struct pccard_function *pf;
@ -269,9 +267,8 @@ pccard_card_gettype(device_t dev)
* disabled.
*/
void
pccard_function_init(pf, cfe)
struct pccard_function *pf;
struct pccard_config_entry *cfe;
pccard_function_init(struct pccard_function *pf,
struct pccard_config_entry *cfe)
{
if (pf->pf_flags & PFF_ENABLED)
panic("pccard_function_init: function is enabled");
@ -282,11 +279,11 @@ pccard_function_init(pf, cfe)
/* Enable a PCCARD function */
int
pccard_function_enable(pf)
struct pccard_function *pf;
pccard_function_enable(struct pccard_function *pf)
{
struct pccard_function *tmp;
int reg;
device_t dev = pf->sc->dev;
if (pf->cfe == NULL)
panic("pccard_function_enable: function not initialized");
@ -296,10 +293,8 @@ pccard_function_enable(pf)
* necessary.
*/
if (pf->sc->sc_enabled_count++ == 0)
POWER_ENABLE_SOCKET(device_get_parent(pf->sc->dev),
pf->sc->dev);
DEVPRINTF((pf->sc->dev, "++enabled_count = %d\n",
pf->sc->sc_enabled_count));
POWER_ENABLE_SOCKET(device_get_parent(dev), dev);
DEVPRINTF((dev, "++enabled_count = %d\n", pf->sc->sc_enabled_count));
if (pf->pf_flags & PFF_ENABLED) {
/*
@ -336,15 +331,16 @@ pccard_function_enable(pf)
}
if (tmp == NULL) {
if (pccard_mem_alloc(pf, PCCARD_CCR_SIZE, &pf->pf_pcmh))
pf->ccr_rid = 0;
pf->ccr_res = bus_alloc_resource(dev, SYS_RES_MEMORY,
&pf->ccr_rid, pf->ccr_base, pf->ccr_base + PCCARD_CCR_SIZE,
PCCARD_CCR_SIZE, RF_ACTIVE | RF_PCCARD_ATTR);
if (!pf->ccr_res)
goto bad;
if (pccard_mem_map(pf, PCCARD_MEM_ATTR, pf->ccr_base,
PCCARD_CCR_SIZE, &pf->pf_pcmh, &pf->pf_ccr_offset,
&pf->pf_ccr_window)) {
pccard_mem_free(pf, &pf->pf_pcmh);
goto bad;
}
pf->pf_ccrt = rman_get_bustag(pf->ccr_res);
pf->pf_ccrh = rman_get_bushandle(pf->ccr_res);
pf->pf_ccr_offset = rman_get_start(pf->ccr_res);
pf->pf_ccr_realsize = 1;
}
reg = (pf->cfe->number & PCCARD_CCR_OPTION_CFINDEX);
@ -407,7 +403,6 @@ pccard_function_enable(pf)
}
}
#endif
pf->pf_flags |= PFF_ENABLED;
return (0);
@ -417,20 +412,18 @@ pccard_function_enable(pf)
* necessary.
*/
if (--pf->sc->sc_enabled_count == 0)
POWER_DISABLE_SOCKET(device_get_parent(pf->sc->dev),
pf->sc->dev);
DEVPRINTF((pf->sc->dev, "--enabled_count = %d\n",
pf->sc->sc_enabled_count));
POWER_DISABLE_SOCKET(device_get_parent(dev), dev);
DEVPRINTF((dev, "--enabled_count = %d\n", pf->sc->sc_enabled_count));
return (1);
}
/* Disable PCCARD function. */
void
pccard_function_disable(pf)
struct pccard_function *pf;
pccard_function_disable(struct pccard_function *pf)
{
struct pccard_function *tmp;
device_t dev = pf->sc->dev;
if (pf->cfe == NULL)
panic("pccard_function_enable: function not initialized");
@ -459,8 +452,9 @@ pccard_function_disable(pf)
/* Not used by anyone else; unmap the CCR. */
if (tmp == NULL) {
pccard_mem_unmap(pf, pf->pf_ccr_window);
pccard_mem_free(pf, &pf->pf_pcmh);
bus_release_resource(dev, SYS_RES_MEMORY, pf->ccr_rid,
pf->ccr_res);
pf->ccr_res = NULL;
}
/*
@ -468,20 +462,15 @@ pccard_function_disable(pf)
* necessary.
*/
if (--pf->sc->sc_enabled_count == 0)
POWER_DISABLE_SOCKET(device_get_parent(pf->sc->dev),
pf->sc->dev);
DEVPRINTF((pf->sc->dev, "--enabled_count = %d\n",
pf->sc->sc_enabled_count));
POWER_DISABLE_SOCKET(device_get_parent(dev), dev);
DEVPRINTF((dev, "--enabled_count = %d\n", pf->sc->sc_enabled_count));
}
#if 0
/* XXX These functions are needed, but not like this XXX */
int
pccard_io_map(pf, width, offset, size, pcihp, windowp)
struct pccard_function *pf;
int width;
bus_addr_t offset;
bus_size_t size;
struct pccard_io_handle *pcihp;
int *windowp;
pccard_io_map(struct pccard_function *pf, int width, bus_addr_t offset,
bus_size_t size, struct pccard_io_handle *pcihp, int *windowp)
{
int reg;
@ -515,10 +504,10 @@ pccard_io_map(pf, width, offset, size, pcihp, windowp)
;
iosize--;
pccard_ccr_write(pf, PCCARD_CCR_IOBASE0,
pf->pf_mfc_iobase & 0xff);
pccard_ccr_write(pf, PCCARD_CCR_IOBASE0,
pf->pf_mfc_iobase & 0xff);
pccard_ccr_write(pf, PCCARD_CCR_IOBASE1,
(pf->pf_mfc_iobase >> 8) & 0xff);
(pf->pf_mfc_iobase >> 8) & 0xff);
pccard_ccr_write(pf, PCCARD_CCR_IOBASE2, 0);
pccard_ccr_write(pf, PCCARD_CCR_IOBASE3, 0);
@ -532,231 +521,19 @@ pccard_io_map(pf, width, offset, size, pcihp, windowp)
}
void
pccard_io_unmap(pf, window)
struct pccard_function *pf;
int window;
pccard_io_unmap(struct pccard_function *pf, int window)
{
pccard_chip_io_unmap(pf->sc->pct, pf->sc->pch, window);
/* XXX Anything for multi-function cards? */
}
void *
pccard_intr_establish(pf, ipl, ih_fct, ih_arg)
struct pccard_function *pf;
int ipl;
int (*ih_fct)(void *);
void *ih_arg;
{
void *ret;
/* behave differently if this is a multifunction card */
if (pccard_mfc(pf->sc)) {
int s, ihcnt, hiipl, reg;
struct pccard_function *pf2;
/*
* mask all the ipl's which are already used by this card,
* and find the highest ipl number (lowest priority)
*/
ihcnt = 0;
s = 0; /* this is only here to keep the compiler
happy */
hiipl = 0; /* this is only here to keep the compiler
happy */
STAILQ_FOREACH(pf2, &pf->sc->card.pf_head, pf_list) {
if (pf2->ih_fct) {
DEVPRINTF((pf2->sc->dev,
"function %d has ih_fct %p\n",
pf2->number, pf2->ih_fct));
if (ihcnt == 0) {
hiipl = pf2->ih_ipl;
} else {
if (pf2->ih_ipl > hiipl)
hiipl = pf2->ih_ipl;
}
ihcnt++;
}
}
/*
* establish the real interrupt, changing the ipl if
* necessary
*/
if (ihcnt == 0) {
#ifdef DIAGNOSTIC
if (pf->sc->ih != NULL)
panic("card has intr handler, but no function does");
#endif
s = splhigh();
/* set up the handler for the new function */
pf->ih_fct = ih_fct;
pf->ih_arg = ih_arg;
pf->ih_ipl = ipl;
pf->sc->ih = pccard_chip_intr_establish(pf->sc->pct,
pf->sc->pch, pf, ipl, PCCARD_CARD_INTR, pf->sc);
splx(s);
} else if (ipl > hiipl) {
#ifdef DIAGNOSTIC
if (pf->sc->ih == NULL)
panic("functions have ih, but the card does not");
#endif
/* XXX need #ifdef for splserial on x86 */
s = splhigh();
pccard_chip_intr_disestablish(pf->sc->pct, pf->sc->pch,
pf->sc->ih);
/* set up the handler for the new function */
pf->ih_fct = ih_fct;
pf->ih_arg = ih_arg;
pf->ih_ipl = ipl;
pf->sc->ih = pccard_chip_intr_establish(pf->sc->pct,
pf->sc->pch, pf, ipl, PCCARD_CARD_INTR, pf->sc);
splx(s);
} else {
s = splhigh();
/* set up the handler for the new function */
pf->ih_fct = ih_fct;
pf->ih_arg = ih_arg;
pf->ih_ipl = ipl;
splx(s);
}
ret = pf->sc->ih;
if (ret != NULL) {
reg = pccard_ccr_read(pf, PCCARD_CCR_OPTION);
reg |= PCCARD_CCR_OPTION_IREQ_ENABLE;
pccard_ccr_write(pf, PCCARD_CCR_OPTION, reg);
reg = pccard_ccr_read(pf, PCCARD_CCR_STATUS);
reg |= PCCARD_CCR_STATUS_INTRACK;
pccard_ccr_write(pf, PCCARD_CCR_STATUS, reg);
}
} else {
ret = pccard_chip_intr_establish(pf->sc->pct, pf->sc->pch,
pf, ipl, ih_fct, ih_arg);
}
return (ret);
}
void
pccard_intr_disestablish(pf, ih)
struct pccard_function *pf;
void *ih;
{
/* behave differently if this is a multifunction card */
if (pccard_mfc(pf->sc)) {
int s, ihcnt, hiipl;
struct pccard_function *pf2;
/*
* mask all the ipl's which are already used by this card,
* and find the highest ipl number (lowest priority). Skip
* the current function.
*/
ihcnt = 0;
s = 0; /* this is only here to keep the compipler
happy */
hiipl = 0; /* this is only here to keep the compipler
happy */
STAILQ_FOREACH(pf2, &pf->sc->card.pf_head, pf_list) {
if (pf2 == pf)
continue;
if (pf2->ih_fct) {
if (ihcnt == 0) {
hiipl = pf2->ih_ipl;
} else {
if (pf2->ih_ipl > hiipl)
hiipl = pf2->ih_ipl;
}
ihcnt++;
}
}
/*
* if the ih being removed is lower priority than the lowest
* priority remaining interrupt, up the priority.
*/
/* ihcnt is the number of interrupt handlers *not* including
the one about to be removed. */
if (ihcnt == 0) {
int reg;
#ifdef DIAGNOSTIC
if (pf->sc->ih == NULL)
panic("disestablishing last function, but card has no ih");
#endif
pccard_chip_intr_disestablish(pf->sc->pct, pf->sc->pch,
pf->sc->ih);
reg = pccard_ccr_read(pf, PCCARD_CCR_OPTION);
reg &= ~PCCARD_CCR_OPTION_IREQ_ENABLE;
pccard_ccr_write(pf, PCCARD_CCR_OPTION, reg);
pf->ih_fct = NULL;
pf->ih_arg = NULL;
pf->sc->ih = NULL;
} else if (pf->ih_ipl > hiipl) {
#ifdef DIAGNOSTIC
if (pf->sc->ih == NULL)
panic("changing ih ipl, but card has no ih");
#endif
/* XXX need #ifdef for splserial on x86 */
s = splhigh();
pccard_chip_intr_disestablish(pf->sc->pct, pf->sc->pch,
pf->sc->ih);
pf->sc->ih = pccard_chip_intr_establish(pf->sc->pct,
pf->sc->pch, pf, hiipl, PCCARD_CARD_INTR, pf->sc);
/* null out the handler for this function */
pf->ih_fct = NULL;
pf->ih_arg = NULL;
splx(s);
} else {
s = splhigh();
pf->ih_fct = NULL;
pf->ih_arg = NULL;
splx(s);
}
} else {
pccard_chip_intr_disestablish(pf->sc->pct, pf->sc->pch, ih);
}
}
/* I don't think FreeBSD needs the next two functions at all */
/* XXX */
int
pccard_card_intr(arg)
void *arg;
pccard_card_intr(void *arg)
{
struct pccard_softc *sc = arg;
struct pccard_function *pf;

View File

@ -50,8 +50,10 @@
#ifdef PCCARDCISDEBUG
int pccardcis_debug = 0;
#define DPRINTF(arg) if (pccardcis_debug) printf arg
#define DEVPRINTF(arg) if (pccardcis_debug) device_printf arg
#else
#define DPRINTF(arg)
#define DEVPRINTF(arg)
#endif
#define PCCARD_CIS_SIZE 1024
@ -68,8 +70,7 @@ struct cis_state {
int pccard_parse_cis_tuple(struct pccard_tuple *, void *);
void
pccard_read_cis(sc)
struct pccard_softc *sc;
pccard_read_cis(struct pccard_softc *sc)
{
struct cis_state state;
@ -97,16 +98,11 @@ pccard_read_cis(sc)
}
int
pccard_scan_cis(dev, fct, arg)
struct device *dev;
int (*fct)(struct pccard_tuple *, void *);
void *arg;
pccard_scan_cis(device_t dev, int (*fct)(struct pccard_tuple *, void *),
void *arg)
{
struct pccard_softc *sc = (struct pccard_softc *) dev;
pccard_chipset_tag_t pct;
pccard_chipset_handle_t pch;
int window;
struct pccard_mem_handle pcmh;
struct resource *res;
int rid;
struct pccard_tuple tuple;
int longlink_present;
int longlink_common;
@ -121,34 +117,22 @@ pccard_scan_cis(dev, fct, arg)
ret = 0;
pct = sc->pct;
pch = sc->pch;
/* allocate some memory */
if (pccard_chip_mem_alloc(pct, pch, PCCARD_CIS_SIZE, &pcmh)) {
rid = 0;
res = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid, 0, ~0,
PCCARD_CIS_SIZE, RF_ACTIVE | RF_PCCARD_ATTR);
if (res == NULL) {
#ifdef DIAGNOSTIC
printf("%s: can't alloc memory to read attributes\n",
sc->dev.dv_xname);
device_printf(dev, "can't alloc memory to read attributes\n");
#endif
return -1;
}
tuple.memt = pcmh.memt;
tuple.memh = pcmh.memh;
tuple.memt = rman_get_bustag(res);
tuple.memh = rman_get_bushandle(res);
/* initialize state for the primary tuple chain */
if (pccard_chip_mem_map(pct, pch, PCCARD_MEM_ATTR, 0,
PCCARD_CIS_SIZE, &pcmh, &tuple.ptr, &window)) {
pccard_chip_mem_free(pct, pch, &pcmh);
#ifdef DIAGNOSTIC
printf("%s: can't map memory to read attributes\n",
sc->dev.dv_xname);
#endif
return -1;
}
#ifndef __FreeBSD__
DPRINTF(("cis mem map %x\n", (unsigned int) tuple.memh));
#endif
tuple.mult = 2;
longlink_present = 1;
@ -158,7 +142,7 @@ pccard_scan_cis(dev, fct, arg)
mfc_count = 0;
mfc_index = 0;
DPRINTF(("%s: CIS tuple chain:\n", sc->dev.dv_xname));
DEVPRINTF((dev, "CIS tuple chain:\n"));
while (1) {
while (1) {
@ -177,8 +161,6 @@ pccard_scan_cis(dev, fct, arg)
/* Call the function for the END tuple, since
the CIS semantics depend on it */
if ((*fct) (&tuple, arg)) {
pccard_chip_mem_unmap(pct, pch,
window);
ret = 1;
goto done;
}
@ -253,11 +235,8 @@ pccard_scan_cis(dev, fct, arg)
if (cksum != (sum & 0xff)) {
DPRINTF((" failed sum=%x\n",
sum));
#if XXX
printf("%s: CIS checksum "
"failed\n",
sc->dev.dv_xname);
#endif
device_printf(dev,
"CIS checksum failed\n");
#if 0
/*
* XXX Some working cards have
@ -310,8 +289,6 @@ pccard_scan_cis(dev, fct, arg)
default:
{
if ((*fct) (&tuple, arg)) {
pccard_chip_mem_unmap(pct,
pch, window);
ret = 1;
goto done;
}
@ -340,6 +317,10 @@ pccard_scan_cis(dev, fct, arg)
tuple.ptr += 2 + tuple.length;
}
#ifdef XXX /* I'm not up to this tonight, need to implement new API */
/* to deal with moving windows and such. At least that's */
/* what it appears at this instant */
/*
* the chain is done. Clean up and move onto the next one,
* if any. The loop is here in the case that there is an MFC
@ -372,10 +353,8 @@ pccard_scan_cis(dev, fct, arg)
if (!longlink_common)
tuple.ptr /= 2;
#ifndef __FreeBSD__
DPRINTF(("cis mem map %x\n",
(unsigned int) tuple.memh));
#endif
tuple.mult = longlink_common ? 1 : 2;
longlink_present = 0;
longlink_common = 1;
@ -392,10 +371,8 @@ pccard_scan_cis(dev, fct, arg)
if (!mfc[mfc_index].common)
tuple.ptr /= 2;
#ifndef __FreeBSD__
DPRINTF(("cis mem map %x\n",
(unsigned int) tuple.memh));
#endif
/* set parse state, and point at the next one */
tuple.mult = mfc[mfc_index].common ? 1 : 2;
@ -432,13 +409,11 @@ pccard_scan_cis(dev, fct, arg)
break;
}
#endif /* XXX */
}
pccard_chip_mem_unmap(pct, pch, window);
done:
/* Last, free the allocated memory block */
pccard_chip_mem_free(pct, pch, &pcmh);
bus_release_resource(dev, SYS_RES_MEMORY, rid, res);
return (ret);
}
@ -610,9 +585,7 @@ pccard_print_cis(device_t dev)
}
int
pccard_parse_cis_tuple(tuple, arg)
struct pccard_tuple *tuple;
void *arg;
pccard_parse_cis_tuple(struct pccard_tuple *tuple, void *arg)
{
/* most of these are educated guesses */
static struct pccard_config_entry init_cfe = {

View File

@ -33,6 +33,7 @@
#ifndef _PCCARD_PCCARDCHIP_H_
#define _PCCARD_PCCARDCHIP_H_
#if 0
#include <machine/bus.h>
struct pccard_function;
@ -43,6 +44,7 @@ struct pccard_io_handle;
typedef struct pccard_chip_functions *pccard_chipset_tag_t;
typedef void *pccard_chipset_handle_t;
#endif
typedef int pccard_mem_handle_t;
#define PCCARD_MEM_ATTR 1
@ -52,6 +54,7 @@ typedef int pccard_mem_handle_t;
#define PCCARD_WIDTH_IO8 1
#define PCCARD_WIDTH_IO16 2
#if 0
struct pccard_chip_functions {
/* memory space allocation */
int (*mem_alloc)(pccard_chipset_handle_t, bus_size_t,
@ -126,13 +129,11 @@ struct pccard_chip_functions {
#define pccard_chip_intr_disestablish(tag, handle, ih) \
((*(tag)->intr_disestablish)((handle), (ih)))
#if 0
/* Socket functions. */
#define pccard_chip_socket_enable(tag, handle) \
((*(tag)->socket_enable)((handle)))
#define pccard_chip_socket_disable(tag, handle) \
((*(tag)->socket_disable)((handle)))
#endif /* 0 */
struct pccardbus_attach_args {
char *paa_busname; /* Bus name */
@ -142,4 +143,6 @@ struct pccardbus_attach_args {
bus_size_t iosize; /* size of the i/o space range */
};
#endif /* 0 */
#endif /* _PCCARD_PCCARDCHIP_H_ */

View File

@ -116,6 +116,8 @@ struct pccard_function {
int last_config_index;
u_long ccr_base;
u_long ccr_mask;
struct resource *ccr_res;
int ccr_rid;
STAILQ_HEAD(, pccard_config_entry) cfe_head;
STAILQ_ENTRY(pccard_function) pf_list;
/* run-time state */
@ -167,25 +169,14 @@ struct pccard_ivar {
};
struct pccard_softc {
/* this stuff is for the socket */
pccard_chipset_tag_t pct;
pccard_chipset_handle_t pch;
device_t dev;
/* this stuff is for the socket */
/* this stuff is for the card */
struct pccard_card card;
void *ih;
int sc_enabled_count; /* num functions enabled */
/*
* These are passed down from the PCCARD chip, and exist only
* so that cards with Very Special address allocation needs
* know what range they should be dealing with.
*/
bus_addr_t iobase; /* start i/o space allocation here */
bus_size_t iosize; /* size of the i/o space range */
};
void
@ -278,7 +269,3 @@ void pccard_io_unmap(struct pccard_function *, int);
#define pccard_mem_unmap(pf, window) \
(pccard_chip_mem_unmap((pf)->sc->pct, (pf)->sc->pch, (window)))
void *pccard_intr_establish(struct pccard_function *, int,
int (*) (void *), void *);
void pccard_intr_disestablish(struct pccard_function *, void *);