Fix about insertion/removal event problem.
This commit is contained in:
parent
74a54bbbc8
commit
88176e7d20
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: i82365.c,v 1.19 1999/01/01 14:05:18 christos Exp $ */
|
/* $NetBSD: i82365.c,v 1.20 1999/01/21 07:43:32 msaitoh Exp $ */
|
||||||
|
|
||||||
#define PCICDEBUG
|
#define PCICDEBUG
|
||||||
|
|
||||||
|
@ -36,6 +36,7 @@
|
||||||
#include <sys/systm.h>
|
#include <sys/systm.h>
|
||||||
#include <sys/device.h>
|
#include <sys/device.h>
|
||||||
#include <sys/extent.h>
|
#include <sys/extent.h>
|
||||||
|
#include <sys/kernel.h>
|
||||||
#include <sys/malloc.h>
|
#include <sys/malloc.h>
|
||||||
#include <sys/kthread.h>
|
#include <sys/kthread.h>
|
||||||
|
|
||||||
|
@ -190,6 +191,7 @@ pcic_attach(sc)
|
||||||
} else {
|
} else {
|
||||||
sc->handle[0].flags = 0;
|
sc->handle[0].flags = 0;
|
||||||
}
|
}
|
||||||
|
sc->handle[0].laststate = PCIC_LASTSTATE_EMPTY;
|
||||||
|
|
||||||
DPRINTF((" 0x%02x", reg));
|
DPRINTF((" 0x%02x", reg));
|
||||||
|
|
||||||
|
@ -201,6 +203,7 @@ pcic_attach(sc)
|
||||||
} else {
|
} else {
|
||||||
sc->handle[1].flags = 0;
|
sc->handle[1].flags = 0;
|
||||||
}
|
}
|
||||||
|
sc->handle[1].laststate = PCIC_LASTSTATE_EMPTY;
|
||||||
|
|
||||||
DPRINTF((" 0x%02x", reg));
|
DPRINTF((" 0x%02x", reg));
|
||||||
|
|
||||||
|
@ -220,6 +223,7 @@ pcic_attach(sc)
|
||||||
} else {
|
} else {
|
||||||
sc->handle[2].flags = 0;
|
sc->handle[2].flags = 0;
|
||||||
}
|
}
|
||||||
|
sc->handle[2].laststate = PCIC_LASTSTATE_EMPTY;
|
||||||
|
|
||||||
DPRINTF((" 0x%02x", reg));
|
DPRINTF((" 0x%02x", reg));
|
||||||
|
|
||||||
|
@ -232,6 +236,7 @@ pcic_attach(sc)
|
||||||
} else {
|
} else {
|
||||||
sc->handle[3].flags = 0;
|
sc->handle[3].flags = 0;
|
||||||
}
|
}
|
||||||
|
sc->handle[3].laststate = PCIC_LASTSTATE_EMPTY;
|
||||||
|
|
||||||
DPRINTF((" 0x%02x\n", reg));
|
DPRINTF((" 0x%02x\n", reg));
|
||||||
}
|
}
|
||||||
|
@ -386,17 +391,60 @@ pcic_event_thread(arg)
|
||||||
splx(s);
|
splx(s);
|
||||||
(void) tsleep(&h->events, PWAIT, "pcicev", 0);
|
(void) tsleep(&h->events, PWAIT, "pcicev", 0);
|
||||||
continue;
|
continue;
|
||||||
|
} else {
|
||||||
|
splx(s);
|
||||||
|
/* sleep .25s to be enqueued chatterling interrupts */
|
||||||
|
(void) tsleep((caddr_t)pcic_event_thread, PWAIT, "pcicss", hz/4);
|
||||||
}
|
}
|
||||||
|
s = splhigh();
|
||||||
SIMPLEQ_REMOVE_HEAD(&h->events, pe, pe_q);
|
SIMPLEQ_REMOVE_HEAD(&h->events, pe, pe_q);
|
||||||
splx(s);
|
splx(s);
|
||||||
|
|
||||||
switch (pe->pe_type) {
|
switch (pe->pe_type) {
|
||||||
case PCIC_EVENT_INSERTION:
|
case PCIC_EVENT_INSERTION:
|
||||||
|
s = splhigh();
|
||||||
|
while (1) {
|
||||||
|
struct pcic_event *pe1, *pe2;
|
||||||
|
|
||||||
|
if ((pe1 = SIMPLEQ_FIRST(&h->events)) == NULL)
|
||||||
|
break;
|
||||||
|
if (pe1->pe_type != PCIC_EVENT_REMOVAL)
|
||||||
|
break;
|
||||||
|
if ((pe2 = SIMPLEQ_NEXT(pe1, pe_q)) == NULL)
|
||||||
|
break;
|
||||||
|
if (pe2->pe_type == PCIC_EVENT_INSERTION) {
|
||||||
|
SIMPLEQ_REMOVE_HEAD(&h->events, pe1, pe_q);
|
||||||
|
free(pe1, M_TEMP);
|
||||||
|
SIMPLEQ_REMOVE_HEAD(&h->events, pe2, pe_q);
|
||||||
|
free(pe2, M_TEMP);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
splx(s);
|
||||||
|
|
||||||
DPRINTF(("%s: insertion event\n", h->sc->dev.dv_xname));
|
DPRINTF(("%s: insertion event\n", h->sc->dev.dv_xname));
|
||||||
pcic_attach_card(h);
|
pcic_attach_card(h);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PCIC_EVENT_REMOVAL:
|
case PCIC_EVENT_REMOVAL:
|
||||||
|
s = splhigh();
|
||||||
|
while (1) {
|
||||||
|
struct pcic_event *pe1, *pe2;
|
||||||
|
|
||||||
|
if ((pe1 = SIMPLEQ_FIRST(&h->events)) == NULL)
|
||||||
|
break;
|
||||||
|
if (pe1->pe_type != PCIC_EVENT_INSERTION)
|
||||||
|
break;
|
||||||
|
if ((pe2 = SIMPLEQ_NEXT(pe1, pe_q)) == NULL)
|
||||||
|
break;
|
||||||
|
if (pe2->pe_type == PCIC_EVENT_REMOVAL) {
|
||||||
|
SIMPLEQ_REMOVE_HEAD(&h->events, pe1, pe_q);
|
||||||
|
free(pe1, M_TEMP);
|
||||||
|
SIMPLEQ_REMOVE_HEAD(&h->events, pe2, pe_q);
|
||||||
|
free(pe2, M_TEMP);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
splx(s);
|
||||||
|
|
||||||
DPRINTF(("%s: removal event\n", h->sc->dev.dv_xname));
|
DPRINTF(("%s: removal event\n", h->sc->dev.dv_xname));
|
||||||
pcic_detach_card(h, DETACH_FORCE);
|
pcic_detach_card(h, DETACH_FORCE);
|
||||||
break;
|
break;
|
||||||
|
@ -455,8 +503,12 @@ pcic_init_socket(h)
|
||||||
reg = pcic_read(h, PCIC_IF_STATUS);
|
reg = pcic_read(h, PCIC_IF_STATUS);
|
||||||
|
|
||||||
if ((reg & PCIC_IF_STATUS_CARDDETECT_MASK) ==
|
if ((reg & PCIC_IF_STATUS_CARDDETECT_MASK) ==
|
||||||
PCIC_IF_STATUS_CARDDETECT_PRESENT)
|
PCIC_IF_STATUS_CARDDETECT_PRESENT) {
|
||||||
pcic_attach_card(h);
|
pcic_attach_card(h);
|
||||||
|
h->laststate = PCIC_LASTSTATE_PRESENT;
|
||||||
|
} else {
|
||||||
|
h->laststate = PCIC_LASTSTATE_EMPTY;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -596,22 +648,25 @@ pcic_intr_socket(h)
|
||||||
|
|
||||||
if ((statreg & PCIC_IF_STATUS_CARDDETECT_MASK) ==
|
if ((statreg & PCIC_IF_STATUS_CARDDETECT_MASK) ==
|
||||||
PCIC_IF_STATUS_CARDDETECT_PRESENT) {
|
PCIC_IF_STATUS_CARDDETECT_PRESENT) {
|
||||||
if (!(h->flags & PCIC_FLAG_CARDP)) {
|
if (h->laststate != PCIC_LASTSTATE_PRESENT) {
|
||||||
DPRINTF(("%s: enqueing INSERTION event\n",
|
DPRINTF(("%s: enqueing INSERTION event\n",
|
||||||
h->sc->dev.dv_xname));
|
h->sc->dev.dv_xname));
|
||||||
pcic_queue_event(h, PCIC_EVENT_INSERTION);
|
pcic_queue_event(h, PCIC_EVENT_INSERTION);
|
||||||
}
|
}
|
||||||
|
h->laststate = PCIC_LASTSTATE_PRESENT;
|
||||||
} else {
|
} else {
|
||||||
if (h->flags & PCIC_FLAG_CARDP) {
|
if (h->laststate == PCIC_LASTSTATE_PRESENT) {
|
||||||
/* Deactivate the card now. */
|
/* Deactivate the card now. */
|
||||||
DPRINTF(("%s: deactivating card\n",
|
DPRINTF(("%s: deactivating card\n",
|
||||||
h->sc->dev.dv_xname));
|
h->sc->dev.dv_xname));
|
||||||
pcic_deactivate_card(h);
|
pcic_deactivate_card(h);
|
||||||
|
|
||||||
DPRINTF(("%s: enqueing REMOVAL event\n",
|
DPRINTF(("%s: enqueing REMOVAL event\n",
|
||||||
h->sc->dev.dv_xname));
|
h->sc->dev.dv_xname));
|
||||||
pcic_queue_event(h, PCIC_EVENT_REMOVAL);
|
pcic_queue_event(h, PCIC_EVENT_REMOVAL);
|
||||||
}
|
}
|
||||||
|
h->laststate = ((statreg & PCIC_IF_STATUS_CARDDETECT_MASK) == 0)
|
||||||
|
? PCIC_LASTSTATE_EMPTY : PCIC_LASTSTATE_HALF;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (cscreg & PCIC_CSC_READY) {
|
if (cscreg & PCIC_CSC_READY) {
|
||||||
|
@ -651,13 +706,14 @@ pcic_attach_card(h)
|
||||||
struct pcic_handle *h;
|
struct pcic_handle *h;
|
||||||
{
|
{
|
||||||
|
|
||||||
if (h->flags & PCIC_FLAG_CARDP)
|
if (!(h->flags & PCIC_FLAG_CARDP)) {
|
||||||
panic("pcic_attach_card: already attached");
|
/* call the MI attach function */
|
||||||
|
pcmcia_card_attach(h->pcmcia);
|
||||||
|
|
||||||
/* call the MI attach function */
|
h->flags |= PCIC_FLAG_CARDP;
|
||||||
pcmcia_card_attach(h->pcmcia);
|
} else {
|
||||||
|
DPRINTF(("pcic_attach_card: already attached"));
|
||||||
h->flags |= PCIC_FLAG_CARDP;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -666,13 +722,14 @@ pcic_detach_card(h, flags)
|
||||||
int flags; /* DETACH_* */
|
int flags; /* DETACH_* */
|
||||||
{
|
{
|
||||||
|
|
||||||
if (!(h->flags & PCIC_FLAG_CARDP))
|
if (h->flags & PCIC_FLAG_CARDP) {
|
||||||
panic("pcic_detach_card: already detached");
|
h->flags &= ~PCIC_FLAG_CARDP;
|
||||||
|
|
||||||
h->flags &= ~PCIC_FLAG_CARDP;
|
/* call the MI detach function */
|
||||||
|
pcmcia_card_detach(h->pcmcia, flags);
|
||||||
/* call the MI detach function */
|
} else {
|
||||||
pcmcia_card_detach(h->pcmcia, flags);
|
DPRINTF(("pcic_detach_card: already detached"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -680,9 +737,6 @@ pcic_deactivate_card(h)
|
||||||
struct pcic_handle *h;
|
struct pcic_handle *h;
|
||||||
{
|
{
|
||||||
|
|
||||||
if (!(h->flags & PCIC_FLAG_CARDP))
|
|
||||||
panic("pcic_deactivate_card: already detached");
|
|
||||||
|
|
||||||
/* call the MI deactivate function */
|
/* call the MI deactivate function */
|
||||||
pcmcia_card_deactivate(h->pcmcia);
|
pcmcia_card_deactivate(h->pcmcia);
|
||||||
|
|
||||||
|
@ -1208,9 +1262,9 @@ pcic_chip_socket_enable(pch)
|
||||||
* stable (Tsu(Vcc)).
|
* stable (Tsu(Vcc)).
|
||||||
*
|
*
|
||||||
* some machines require some more time to be settled
|
* some machines require some more time to be settled
|
||||||
* (another 200ms is added here).
|
* (300ms is added here).
|
||||||
*/
|
*/
|
||||||
delay((100 + 20 + 200) * 1000);
|
delay((100 + 20 + 300) * 1000);
|
||||||
|
|
||||||
pcic_write(h, PCIC_PWRCTL, PCIC_PWRCTL_DISABLE_RESETDRV | PCIC_PWRCTL_OE
|
pcic_write(h, PCIC_PWRCTL, PCIC_PWRCTL_DISABLE_RESETDRV | PCIC_PWRCTL_OE
|
||||||
| PCIC_PWRCTL_PWR_ENABLE);
|
| PCIC_PWRCTL_PWR_ENABLE);
|
||||||
|
@ -1231,6 +1285,13 @@ pcic_chip_socket_enable(pch)
|
||||||
|
|
||||||
/* wait for the chip to finish initializing */
|
/* wait for the chip to finish initializing */
|
||||||
|
|
||||||
|
#ifdef DIAGNOSTIC
|
||||||
|
reg = pcic_read(h, PCIC_IF_STATUS);
|
||||||
|
if (!(reg & PCIC_IF_STATUS_POWERACTIVE)) {
|
||||||
|
printf("pcic_chip_socket_enable: status %x", reg);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
pcic_wait_ready(h);
|
pcic_wait_ready(h);
|
||||||
|
|
||||||
/* zero out the address windows */
|
/* zero out the address windows */
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: i82365var.h,v 1.6 1999/01/01 14:05:18 christos Exp $ */
|
/* $NetBSD: i82365var.h,v 1.7 1999/01/21 07:43:33 msaitoh Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1997 Marc Horowitz. All rights reserved.
|
* Copyright (c) 1997 Marc Horowitz. All rights reserved.
|
||||||
|
@ -52,6 +52,7 @@ struct pcic_handle {
|
||||||
int vendor;
|
int vendor;
|
||||||
int sock;
|
int sock;
|
||||||
int flags;
|
int flags;
|
||||||
|
int laststate;
|
||||||
int memalloc;
|
int memalloc;
|
||||||
struct {
|
struct {
|
||||||
bus_addr_t addr;
|
bus_addr_t addr;
|
||||||
|
@ -76,6 +77,10 @@ struct pcic_handle {
|
||||||
#define PCIC_FLAG_SOCKETP 0x0001
|
#define PCIC_FLAG_SOCKETP 0x0001
|
||||||
#define PCIC_FLAG_CARDP 0x0002
|
#define PCIC_FLAG_CARDP 0x0002
|
||||||
|
|
||||||
|
#define PCIC_LASTSTATE_PRESENT 0x0002
|
||||||
|
#define PCIC_LASTSTATE_HALF 0x0001
|
||||||
|
#define PCIC_LASTSTATE_EMPTY 0x0000
|
||||||
|
|
||||||
#define C0SA PCIC_CHIP0_BASE+PCIC_SOCKETA_INDEX
|
#define C0SA PCIC_CHIP0_BASE+PCIC_SOCKETA_INDEX
|
||||||
#define C0SB PCIC_CHIP0_BASE+PCIC_SOCKETB_INDEX
|
#define C0SB PCIC_CHIP0_BASE+PCIC_SOCKETB_INDEX
|
||||||
#define C1SA PCIC_CHIP1_BASE+PCIC_SOCKETA_INDEX
|
#define C1SA PCIC_CHIP1_BASE+PCIC_SOCKETA_INDEX
|
||||||
|
|
Loading…
Reference in New Issue