checkpoint latest pccard/pcic hacking:

o Eliminate cross calls between the devices.  Instead move to using the
  newbus messaging system.  Added three new card calls: attach_card,
  detach_card, get_type.
o Eliminate interrupt routine in pccard we never use.
o Move from deactivate to detach for removing cards.
o Start mapping CIS memory, but it is broken and causes panics.  At least
  it is closer to working than before.
o Eliminate struct device everywhere.  It was bogus.
o Initialize softc for pccard device so we have valid pointers to
  ourselves.
o Implement routine to find the pcic ivar for a child device of the pccard so
  we can use it to talk to the pcic hardware.
o Lots of minor tiding up.

This version now panics when we try to read the CIS.  The next batch
of work to make this work is what was outlined in my posting to mobile
about resource allocation and such.
This commit is contained in:
Warner Losh 2000-04-13 06:42:58 +00:00
parent 193faf8655
commit 3a6352bdee
7 changed files with 143 additions and 165 deletions

View File

@ -37,16 +37,41 @@ INTERFACE card;
# the driver activating the resources doesn't necessarily know or need to know
# these attributes.
#
METHOD int set_resource_attribute {
METHOD int set_res_flags {
device_t dev;
device_t child;
int restype;
int rid;
u_int flags;
u_long value;
};
METHOD int get_resource_attribute {
METHOD int get_res_flags {
device_t dev;
device_t child;
int restype;
int rid;
u_int *flags;
u_long *value;
};
METHOD int set_memory_offset {
device_t dev;
device_t child;
int rid;
u_int32_t offset;
}
# These might be better static
METHOD int attach_card {
device_t dev;
}
METHOD int detach_card {
device_t dev;
int flags;
}
METHOD int get_type {
device_t dev;
int *type;
}

View File

@ -48,6 +48,7 @@
#include <dev/pccard/pccardvar.h>
#include "power_if.h"
#include "card_if.h"
#define PCCARDDEBUG
@ -55,14 +56,9 @@
int pccard_debug = 1;
#define DPRINTF(arg) if (pccard_debug) printf arg
#define DEVPRINTF(arg) if (pccard_debug) device_printf arg
int pccardintr_debug = 0;
/* this is done this way to avoid doing lots of conditionals
at interrupt level. */
#define PCCARD_CARD_INTR (pccardintr_debug?pccard_card_intrdebug:pccard_card_intr)
#else
#define DPRINTF(arg)
#define DEVPRINTF(arg)
#define PCCARD_CARD_INTR (pccard_card_intr)
#endif
#ifdef PCCARDVERBOSE
@ -73,11 +69,6 @@ int pccard_verbose = 0;
int pccard_print(void *, const char *);
int pccard_card_intr(void *);
#ifdef PCCARDDEBUG
int pccard_card_intrdebug(void *);
#endif
int
pccard_ccr_read(pf, ccr)
struct pccard_function *pf;
@ -100,8 +91,8 @@ pccard_ccr_write(pf, ccr, val)
}
}
int
pccard_card_attach(device_t dev)
static int
pccard_attach_card(device_t dev)
{
struct pccard_softc *sc = (struct pccard_softc *)
device_get_softc(dev);
@ -146,16 +137,7 @@ pccard_card_attach(device_t dev)
if (STAILQ_EMPTY(&pf->cfe_head))
continue;
#ifdef DIAGNOSTIC
if (pf->child != NULL) {
device_printf(sc->dev,
"%s still attached to function %d!\n",
device_get_name(pf->child), pf->number);
panic("pccard_card_attach");
}
#endif
pf->sc = sc;
pf->child = NULL;
pf->cfe = NULL;
pf->ih_fct = NULL;
pf->ih_arg = NULL;
@ -184,8 +166,8 @@ pccard_card_attach(device_t dev)
return (attached ? 0 : 1);
}
void
pccard_card_detach(device_t dev, int flags)
static int
pccard_detach_card(device_t dev, int flags)
{
struct pccard_softc *sc = (struct pccard_softc *)
device_get_softc(dev);
@ -201,11 +183,9 @@ pccard_card_detach(device_t dev, int flags)
STAILQ_FOREACH(pf, &sc->card.pf_head, pf_list) {
if (STAILQ_FIRST(&pf->cfe_head) == NULL)
continue;
if (pf->child == NULL)
continue;
#if XXX
DEVPRINTF((sc->dev, "detaching %s (function %d)\n",
device_get_name(pf->child), pf->number));
#if XXX
if ((error = config_detach(pf->child, flags)) != 0) {
device_printf(sc->dev,
"error %d detaching %s (function %d)\n",
@ -214,35 +194,11 @@ pccard_card_detach(device_t dev, int flags)
pf->child = NULL;
#endif
}
return 0;
}
void
pccard_card_deactivate(device_t dev)
{
struct pccard_softc *sc = (struct pccard_softc *)
device_get_softc(dev);
struct pccard_function *pf;
/*
* We're in the chip's card removal interrupt handler.
* Deactivate the child driver. The PCCARD socket's
* event thread will run later to finish the detach.
*/
STAILQ_FOREACH(pf, &sc->card.pf_head, pf_list) {
if (STAILQ_FIRST(&pf->cfe_head) == NULL)
continue;
if (pf->child == NULL)
continue;
DEVPRINTF((sc->dev, "deactivating %s (function %d)\n",
device_get_name(pf->child), pf->number));
#if XXX
config_deactivate(pf->child);
#endif
}
}
int
pccard_card_gettype(device_t dev)
static int
pccard_card_gettype(device_t dev, int *type)
{
struct pccard_softc *sc = (struct pccard_softc *)
device_get_softc(dev);
@ -257,9 +213,10 @@ pccard_card_gettype(device_t dev)
if (pf == NULL ||
(STAILQ_NEXT(pf, pf_list) == NULL &&
(pf->cfe == NULL || pf->cfe->iftype == PCCARD_IFTYPE_MEMORY)))
return (PCCARD_IFTYPE_MEMORY);
*type = PCCARD_IFTYPE_MEMORY;
else
return (PCCARD_IFTYPE_IO);
*type = PCCARD_IFTYPE_IO;
return 0;
}
/*
@ -531,74 +488,6 @@ pccard_io_unmap(struct pccard_function *pf, int window)
}
#endif
/* I don't think FreeBSD needs the next two functions at all */
/* XXX */
int
pccard_card_intr(void *arg)
{
struct pccard_softc *sc = arg;
struct pccard_function *pf;
int reg, ret, ret2;
ret = 0;
STAILQ_FOREACH(pf, &sc->card.pf_head, pf_list) {
if (pf->ih_fct != NULL &&
(pf->ccr_mask & (1 << (PCCARD_CCR_STATUS / 2)))) {
reg = pccard_ccr_read(pf, PCCARD_CCR_STATUS);
if (reg & PCCARD_CCR_STATUS_INTR) {
ret2 = (*pf->ih_fct)(pf->ih_arg);
if (ret2 != 0 && ret == 0)
ret = ret2;
reg = pccard_ccr_read(pf, PCCARD_CCR_STATUS);
pccard_ccr_write(pf, PCCARD_CCR_STATUS,
reg & ~PCCARD_CCR_STATUS_INTR);
}
}
}
return (ret);
}
#ifdef PCCARDDEBUG
int
pccard_card_intrdebug(arg)
void *arg;
{
struct pccard_softc *sc = arg;
struct pccard_function *pf;
int reg, ret, ret2;
ret = 0;
STAILQ_FOREACH(pf, &sc->card.pf_head, pf_list) {
device_printf(sc->dev,
"intr flags=%x fct=%d cor=%02x csr=%02x pin=%02x",
pf->pf_flags, pf->number,
pccard_ccr_read(pf, PCCARD_CCR_OPTION),
pccard_ccr_read(pf, PCCARD_CCR_STATUS),
pccard_ccr_read(pf, PCCARD_CCR_PIN));
if (pf->ih_fct != NULL &&
(pf->ccr_mask & (1 << (PCCARD_CCR_STATUS / 2)))) {
reg = pccard_ccr_read(pf, PCCARD_CCR_STATUS);
if (reg & PCCARD_CCR_STATUS_INTR) {
ret2 = (*pf->ih_fct)(pf->ih_arg);
if (ret2 != 0 && ret == 0)
ret = ret2;
reg = pccard_ccr_read(pf, PCCARD_CCR_STATUS);
printf("; csr %02x->%02x",
reg, reg & ~PCCARD_CCR_STATUS_INTR);
pccard_ccr_write(pf, PCCARD_CCR_STATUS,
reg & ~PCCARD_CCR_STATUS_INTR);
}
}
printf("\n");
}
return (ret);
}
#endif
#define PCCARD_NPORT 2
#define PCCARD_NMEM 5
#define PCCARD_NIRQ 1
@ -607,6 +496,7 @@ pccard_card_intrdebug(arg)
static int
pccard_add_children(device_t dev, int busno)
{
/* Call parent to scan for any current children */
return 0;
}
@ -617,6 +507,17 @@ pccard_probe(device_t dev)
return pccard_add_children(dev, device_get_unit(dev));
}
static int
pccard_attach(device_t dev)
{
struct pccard_softc *sc;
sc = (struct pccard_softc *) device_get_softc(dev);
sc->dev = dev;
return bus_generic_attach(dev);
}
static void
pccard_print_resources(struct resource_list *rl, const char *name, int type,
int count, const char *format)
@ -727,10 +628,26 @@ pccard_delete_resource(device_t dev, device_t child, int type, int rid)
resource_list_delete(rl, type, rid);
}
static int
pccard_set_res_flags(device_t dev, device_t child, int type, int rid,
u_int32_t flags)
{
return CARD_SET_RES_FLAGS(device_get_parent(dev), child, type,
rid, flags);
}
static int
pccard_set_memory_offset(device_t dev, device_t child, int rid,
u_int32_t offset)
{
return CARD_SET_MEMORY_OFFSET(device_get_parent(dev), child, rid,
offset);
}
static device_method_t pccard_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, pccard_probe),
DEVMETHOD(device_attach, bus_generic_attach),
DEVMETHOD(device_attach, pccard_attach),
DEVMETHOD(device_shutdown, bus_generic_shutdown),
DEVMETHOD(device_suspend, bus_generic_suspend),
DEVMETHOD(device_resume, bus_generic_resume),
@ -748,6 +665,13 @@ static device_method_t pccard_methods[] = {
DEVMETHOD(bus_get_resource, pccard_get_resource),
DEVMETHOD(bus_delete_resource, pccard_delete_resource),
/* Card Interface */
DEVMETHOD(card_set_res_flags, pccard_set_res_flags),
DEVMETHOD(card_set_memory_offset, pccard_set_memory_offset),
DEVMETHOD(card_get_type, pccard_card_gettype),
DEVMETHOD(card_attach_card, pccard_attach_card),
DEVMETHOD(card_detach_card, pccard_detach_card),
{ 0, 0 }
};

View File

@ -47,8 +47,11 @@
#include <dev/pccard/pccardchip.h>
#include <dev/pccard/pccardvar.h>
#include "card_if.h"
#define PCCARDCISDEBUG
#ifdef PCCARDCISDEBUG
int pccardcis_debug = 0;
int pccardcis_debug = 1;
#define DPRINTF(arg) if (pccardcis_debug) printf arg
#define DEVPRINTF(arg) if (pccardcis_debug) device_printf arg
#else
@ -92,6 +95,8 @@ pccard_read_cis(struct pccard_softc *sc)
state.pf = NULL;
printf("Calling scan_cis\n");
if (pccard_scan_cis(sc->dev, pccard_parse_cis_tuple,
&state) == -1)
state.card->error++;
@ -121,13 +126,13 @@ pccard_scan_cis(device_t dev, int (*fct)(struct pccard_tuple *, void *),
rid = 0;
res = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid, 0, ~0,
PCCARD_CIS_SIZE, RF_ACTIVE /* | RF_PCCARD_ATTR */);
PCCARD_CIS_SIZE, RF_ACTIVE);
if (res == NULL) {
#ifdef DIAGNOSTIC
device_printf(dev, "can't alloc memory to read attributes\n");
#endif
return -1;
}
CARD_SET_RES_FLAGS(device_get_parent(dev), dev, SYS_RES_MEMORY,
rid, PCCARD_A_MEM_ATTR);
tuple.memt = rman_get_bustag(res);
tuple.memh = rman_get_bushandle(res);

View File

@ -122,7 +122,6 @@ struct pccard_function {
STAILQ_ENTRY(pccard_function) pf_list;
/* run-time state */
struct pccard_softc *sc;
struct device *child;
struct pccard_config_entry *cfe;
struct pccard_mem_handle pf_pcmh;
#define pf_ccrt pf_pcmh.memt
@ -202,8 +201,8 @@ struct pccard_tuple {
void pccard_read_cis(struct pccard_softc *);
void pccard_check_cis_quirks(device_t);
void pccard_print_cis(device_t);
int pccard_scan_cis(struct device * dev,
int (*) (struct pccard_tuple *, void *), void *);
int pccard_scan_cis(device_t,
int (*) (struct pccard_tuple *, void *), void *);
#define pccard_cis_read_1(tuple, idx0) \
(bus_space_read_1((tuple)->memt, (tuple)->memh, (tuple)->mult*(idx0)))
@ -284,12 +283,6 @@ pccard_get_ether(device_t dev, u_char *enaddr)
}
enum {
PCCARD_A_MEM_ATTR
PCCARD_A_MEM_ATTR = 0x1
};
/* Set the */
static __inline__ void
pccard_set_attribute(device_t dev, struct resource *r, int rid, int flags)
{
}

View File

@ -58,6 +58,8 @@
#include <dev/pcic/i82365reg.h>
#include <dev/pcic/i82365var.h>
#include "card_if.h"
#define PCICDEBUG
#ifdef PCICDEBUG
@ -92,9 +94,11 @@ static void pcic_deactivate(device_t dev);
static int pcic_activate(device_t dev);
static void pcic_intr(void *arg);
void pcic_attach_card(struct pcic_handle *);
void pcic_detach_card(struct pcic_handle *, int);
static void pcic_attach_card(struct pcic_handle *);
static void pcic_detach_card(struct pcic_handle *, int);
#if 0
void pcic_deactivate_card(struct pcic_handle *);
#endif
static void pcic_chip_do_mem_map(struct pcic_handle *, int);
static void pcic_chip_do_io_map(struct pcic_handle *, int);
@ -613,10 +617,11 @@ pcic_init_socket(struct pcic_handle *h)
pcic_write(h, PCIC_CIRRUS_MISC_CTL_2, reg);
}
}
/* if there's a card there, then attach it. */
reg = pcic_read(h, PCIC_IF_STATUS);
h->laststate = PCIC_LASTSTATE_EMPTY;
#if 0
/* XXX */
/* SHould do this later */
if ((reg & PCIC_IF_STATUS_CARDDETECT_MASK) ==
PCIC_IF_STATUS_CARDDETECT_PRESENT) {
pcic_attach_card(h);
@ -624,6 +629,7 @@ pcic_init_socket(struct pcic_handle *h)
} else {
h->laststate = PCIC_LASTSTATE_EMPTY;
}
#endif
}
static void
@ -670,8 +676,8 @@ pcic_intr_socket(struct pcic_handle *h)
} else {
if (h->laststate == PCIC_LASTSTATE_PRESENT) {
/* Deactivate the card now. */
DEVPRINTF((h->dev, "deactivating card\n"));
pcic_deactivate_card(h);
DEVPRINTF((h->dev, "detaching card\n"));
pcic_detach_card(h, DETACH_FORCE);
DEVPRINTF((h->dev,
"enqueing REMOVAL event\n"));
@ -710,13 +716,14 @@ pcic_queue_event(struct pcic_handle *h, int event)
wakeup(&h->events);
}
void
static void
pcic_attach_card(struct pcic_handle *h)
{
DPRINTF(("pcic_attach_card h %p h->dev %p\n", h, h->dev));
DPRINTF(("pcic_attach_card h %p h->dev %p %s %s\n", h, h->dev,
device_get_name(h->dev), device_get_name(device_get_parent(h->dev))));
if (!(h->flags & PCIC_FLAG_CARDP)) {
/* call the MI attach function */
pccard_card_attach(h->dev);
CARD_ATTACH_CARD(h->dev);
h->flags |= PCIC_FLAG_CARDP;
} else {
@ -724,7 +731,7 @@ pcic_attach_card(struct pcic_handle *h)
}
}
void
static void
pcic_detach_card(struct pcic_handle *h, int flags)
{
@ -732,12 +739,13 @@ pcic_detach_card(struct pcic_handle *h, int flags)
h->flags &= ~PCIC_FLAG_CARDP;
/* call the MI detach function */
pccard_card_detach(h->dev, flags);
CARD_DETACH_CARD(h->dev, flags);
} else {
DPRINTF(("pcic_detach_card: already detached"));
}
}
#if 0
void
pcic_deactivate_card(struct pcic_handle *h)
{
@ -751,6 +759,7 @@ pcic_deactivate_card(struct pcic_handle *h)
/* reset the socket */
pcic_write(h, PCIC_INTR, 0);
}
#endif
static int
pcic_chip_mem_alloc(struct pcic_handle *h, bus_size_t size,
@ -937,12 +946,11 @@ pcic_chip_mem_map(struct pcic_handle *h, int kind, bus_addr_t card_addr,
return (1);
*windowp = win;
#if 0
/* XXX this is pretty gross */
if (sc->memt != pcmhp->memt)
panic("pcic_chip_mem_map memt is bogus");
#endif
busaddr = pcmhp->addr;
/*
@ -1133,10 +1141,11 @@ pcic_chip_io_map(struct pcic_handle *h, int width, bus_addr_t offset,
*windowp = win;
#if 0
/* XXX this is pretty gross */
if (sc->iot != pcihp->iot)
panic("pcic_chip_io_map iot is bogus");
#endif
DPRINTF(("pcic_chip_io_map window %d %s port %lx+%lx\n",
win, width_names[width], (u_long) ioaddr, (u_long) size));
@ -1265,12 +1274,10 @@ pcic_enable_socket(device_t dev, device_t child)
pcic_wait_ready(h);
/* zero out the address windows */
pcic_write(h, PCIC_ADDRWIN_ENABLE, 0);
/* set the card type */
cardtype = pccard_card_gettype(h->dev);
CARD_GET_TYPE(h->dev, &cardtype);
reg = pcic_read(h, PCIC_INTR);
reg &= ~(PCIC_INTR_CARDTYPE_MASK | PCIC_INTR_IRQ_MASK | PCIC_INTR_ENABLE);
@ -1512,6 +1519,27 @@ pcic_resume(device_t dev)
return 0;
}
int
pcic_set_res_flags(device_t dev, device_t child, int type, int rid,
u_int32_t flags)
{
struct pcic_handle *h = pcic_get_handle(dev, child);
printf("%p %p %d %d %#x\n", dev, child, type, rid, flags);
if (type != SYS_RES_MEMORY)
return (EINVAL);
h->mem[rid].kind = PCCARD_MEM_ATTR;
pcic_chip_do_mem_map(h, rid);
return 0;
}
int
pcic_set_memory_offset(device_t dev, device_t child, int rid, u_int32_t offset)
{
return 0;
}
static void
pcic_start_threads(void *arg)
{

View File

@ -55,6 +55,7 @@
#include <dev/pcic/i82365var.h>
#include "power_if.h"
#include "card_if.h"
/*****************************************************************************
* Configurable parameters.
@ -357,11 +358,9 @@ static device_method_t pcic_isa_methods[] = {
DEVMETHOD(bus_setup_intr, pcic_setup_intr),
DEVMETHOD(bus_teardown_intr, pcic_teardown_intr),
#if 0
/* pccard/cardbus interface */
DEVMETHOD(card_set_resource_attribute, pcic_set_resource_attribute),
DEVMETHOD(card_get_resource_attribute, pcic_get_resource_attribute),
#endif
DEVMETHOD(card_set_res_flags, pcic_set_res_flags),
DEVMETHOD(card_set_memory_offset, pcic_set_memory_offset),
/* Power Interface */
DEVMETHOD(power_enable_socket, pcic_enable_socket),

View File

@ -191,3 +191,7 @@ int pcic_suspend(device_t dev);
int pcic_resume(device_t dev);
int pcic_enable_socket(device_t dev, device_t child);
int pcic_disable_socket(device_t dev, device_t child);
int pcic_set_res_flags(device_t dev, device_t child, int type, int rid,
u_int32_t flags);
int pcic_set_memory_offset(device_t dev, device_t child, int rid,
u_int32_t offset);