Some interrelated interrupt changes.

Frist, for pci slots, make the setup intr save the requested interrupt
vector and arg and return rather than passing it up to our parent.  On
interrupts, we call this vector iff there's a card in the slot.  This
should eliminate some of the hangs or "weird" messages that people see
when ejecting cards and also help close the race window somewhat.
Reading the pci bus one more time for this information is judged to be
an acceptible tradeoff since it is very very fast.

Cleanup a little how we detect unsupported cards.  Only detect
unsupported cards (eg cardbus cards) on card insertion (or more
pedantically when a card is actually present).  This should allow us
to change the message in the future to "cardbus card not supported
with OLDCARD" :-).

Note:
	We may also consider this for the ISA bus case, but there the
	reads are much more expensive and the location of the CD pin
	status lines appears to be less standardized.  Also, the ISA
	management interrupt isn't shared with the card's interrupt.
	The mutliplex the CSC and function interrupts bit also appears
	to be non-standard (or at least not imlemented on all
	bridges).
This commit is contained in:
Warner Losh 2001-07-01 23:41:43 +00:00
parent c820d555c5
commit 554a9d4aa3
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=79060
2 changed files with 49 additions and 15 deletions

View File

@ -359,13 +359,14 @@ pcic_cd_event(void *arg)
stat = bus_space_read_4(sp->bst, sp->bsh, CB_SOCKET_STATE);
device_printf(sc->dev, "debounced state is 0x%x\n", stat);
if ((stat & CB_SS_16BIT) == 0) {
device_printf(sp->sc->dev, "Unsupported card type inserted\n");
} else {
if (stat & CB_SS_CD)
pccard_event(sp->slt, card_removed);
if ((stat & CB_SS_CD) == 0) {
if ((stat & CB_SS_16BIT) == 0)
device_printf(sp->sc->dev,
"Unsupported card type inserted\n");
else
pccard_event(sp->slt, card_inserted);
} else {
pccard_event(sp->slt, card_removed);
}
sc->cd_pending = 0;
}
@ -376,19 +377,23 @@ pcic_pci_intr(void *arg)
struct pcic_softc *sc = (struct pcic_softc *) arg;
struct pcic_slot *sp = &sc->slots[0];
u_int32_t event;
u_int32_t stat;
event = bus_space_read_4(sp->bst, sp->bsh, CB_SOCKET_EVENT);
if (event == 0)
return;
device_printf(sc->dev, "Event mask 0x%x\n", event);
if (event & CB_SE_CD) {
if (!sc->cd_pending) {
if (event != 0) {
device_printf(sc->dev, "Event mask 0x%x\n", event);
if ((event & CB_SE_CD) != 0 && !sc->cd_pending) {
sc->cd_pending = 1;
timeout(pcic_cd_event, arg, hz/2);
}
/* Ack the interrupt, all of them to be safe */
bus_space_write_4(sp->bst, sp->bsh, 0, 0xffffffff);
}
/* Ack the interrupt, all of them to be safe */
bus_space_write_4(sp->bst, sp->bsh, 0, 0xffffffff);
stat = bus_space_read_4(sp->bst, sp->bsh, CB_SOCKET_STATE);
/* Now call children interrupts if any */
if (sp->intr && (stat & CB_SS_CD) == 0)
sp->intr(sp->argp);
}
/*
@ -627,6 +632,33 @@ pcic_pci_get_memory(device_t dev)
return (0);
}
static int
pcic_pci_setup_intr(device_t dev, device_t child, struct resource *irq,
int flags, driver_intr_t *intr, void *arg, void **cookiep)
{
struct pcic_softc *sc = (struct pcic_softc *) device_get_softc(dev);
struct pcic_slot *sp = &sc->slots[0];
if (sp->intr)
panic("Interrupt already established");
sp->intr = intr;
sp->argp = arg;
*cookiep = sc;
return (0);
}
static int
pcic_pci_teardown_intr(device_t dev, device_t child, struct resource *irq,
void *cookie)
{
struct pcic_softc *sc = (struct pcic_softc *) device_get_softc(dev);
struct pcic_slot *sp = &sc->slots[0];
sp->intr = NULL;
sp->argp = NULL;
return (0);
}
static device_method_t pcic_pci_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, pcic_pci_probe),
@ -642,8 +674,8 @@ static device_method_t pcic_pci_methods[] = {
DEVMETHOD(bus_release_resource, bus_generic_release_resource),
DEVMETHOD(bus_activate_resource, pcic_activate_resource),
DEVMETHOD(bus_deactivate_resource, pcic_deactivate_resource),
DEVMETHOD(bus_setup_intr, pcic_setup_intr),
DEVMETHOD(bus_teardown_intr, pcic_teardown_intr),
DEVMETHOD(bus_setup_intr, pcic_pci_setup_intr),
DEVMETHOD(bus_teardown_intr, pcic_pci_teardown_intr),
/* Card interface */
DEVMETHOD(card_set_res_flags, pcic_set_res_flags),

View File

@ -37,6 +37,8 @@ struct pcic_slot {
void (*putb)(struct pcic_slot *, int, u_char);
bus_space_tag_t bst;
bus_space_handle_t bsh;
driver_intr_t *intr;
void *argp;
};
enum pcic_irq_type { isa_parallel, pci_parallel, isa_serial };
@ -50,7 +52,7 @@ struct pcic_softc
#define PCIC_PD_POWER 0x00000004 /* Uses CL-PD regs */
#define PCIC_VG_POWER 0x00000008 /* Uses VG power regs */
#define PCIC_KING_POWER 0x00000010 /* Uses IBM KING regs */
#define PCIC_RICOH_POWER 0x00000020 /* Uses the ricoh power regs */
#define PCIC_RICOH_POWER 0x0000020 /* Uses the ricoh power regs */
enum pcic_irq_type csc_route; /* How to route csc interrupts */
enum pcic_irq_type func_route; /* How to route function ints */
int iorid; /* Rid of I/O region */