summaryrefslogtreecommitdiff
path: root/sys/dev/pci/pccbb.c
diff options
context:
space:
mode:
authordyoung <dyoung@NetBSD.org>2009-05-21 17:32:32 +0000
committerdyoung <dyoung@NetBSD.org>2009-05-21 17:32:32 +0000
commita0d0f249f91f7fc7cff536e0f4852359814c00a2 (patch)
tree7b8c208858bf8c6db613e3fca6db8ee80769caad /sys/dev/pci/pccbb.c
parent272953ea5daa5e7ce2793489a9559efee99da9a0 (diff)
Let us detach pcmcia0 and cardbus0 at cardslot0, and cardslot0 at
cardbus0.
Diffstat (limited to 'sys/dev/pci/pccbb.c')
-rw-r--r--sys/dev/pci/pccbb.c43
1 files changed, 31 insertions, 12 deletions
diff --git a/sys/dev/pci/pccbb.c b/sys/dev/pci/pccbb.c
index 583918f336b..3e40fd98514 100644
--- a/sys/dev/pci/pccbb.c
+++ b/sys/dev/pci/pccbb.c
@@ -1,4 +1,4 @@
-/* $NetBSD: pccbb.c,v 1.187 2009/05/06 09:25:16 cegger Exp $ */
+/* $NetBSD: pccbb.c,v 1.188 2009/05/21 17:32:32 dyoung Exp $ */
/*
* Copyright (c) 1998, 1999 and 2000
@@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pccbb.c,v 1.187 2009/05/06 09:25:16 cegger Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pccbb.c,v 1.188 2009/05/21 17:32:32 dyoung Exp $");
/*
#define CBB_DEBUG
@@ -99,6 +99,7 @@ delay_ms(int millis, void *param)
int pcicbbmatch(device_t, cfdata_t, void *);
void pccbbattach(device_t, device_t, void *);
+void pccbbchilddet(device_t, device_t);
int pccbbdetach(device_t, int);
int pccbbintr(void *);
static void pci113x_insert(void *);
@@ -212,7 +213,7 @@ static void cb_show_regs(pci_chipset_tag_t pc, pcitag_t tag,
#endif
CFATTACH_DECL3_NEW(cbb_pci, sizeof(struct pccbb_softc),
- pcicbbmatch, pccbbattach, pccbbdetach, NULL, NULL, NULL,
+ pcicbbmatch, pccbbattach, pccbbdetach, NULL, NULL, pccbbchilddet,
DVF_DETACH_SHUTDOWN);
static const struct pcmcia_chip_functions pccbb_pcmcia_funcs = {
@@ -391,6 +392,20 @@ cb_chipset(u_int32_t pci_id, int *flagp)
}
void
+pccbbchilddet(device_t self, device_t child)
+{
+ struct pccbb_softc *sc = device_private(self);
+ int s;
+
+ KASSERT(sc->sc_csc == device_private(child));
+
+ s = splbio();
+ if (sc->sc_csc == device_private(child))
+ sc->sc_csc = NULL;
+ splx(s);
+}
+
+void
pccbbattach(device_t parent, device_t self, void *aux)
{
struct pccbb_softc *sc = device_private(self);
@@ -1030,6 +1045,7 @@ int
pccbbintr(void *arg)
{
struct pccbb_softc *sc = (struct pccbb_softc *)arg;
+ struct cardslot_softc *csc;
u_int32_t sockevent, sockstate;
bus_space_tag_t memt = sc->sc_base_memt;
bus_space_handle_t memh = sc->sc_base_memh;
@@ -1087,14 +1103,16 @@ pccbbintr(void *arg)
device_xname(sc->sc_dev), sockevent));
DPRINTF((" card removed, 0x%08x\n", sockstate));
sc->sc_flags &= ~CBB_CARDEXIST;
- if (sc->sc_csc->sc_status &
+ if ((csc = sc->sc_csc) == NULL)
+ ;
+ else if (csc->sc_status &
CARDSLOT_STATUS_CARD_16) {
- cardslot_event_throw(sc->sc_csc,
+ cardslot_event_throw(csc,
CARDSLOT_EVENT_REMOVAL_16);
- } else if (sc->sc_csc->sc_status &
+ } else if (csc->sc_status &
CARDSLOT_STATUS_CARD_CB) {
/* Cardbus intr removed */
- cardslot_event_throw(sc->sc_csc,
+ cardslot_event_throw(csc,
CARDSLOT_EVENT_REMOVAL_CB);
}
} else if (sc->sc_flags & CBB_INSERTING) {
@@ -1148,6 +1166,7 @@ static void
pci113x_insert(void *arg)
{
struct pccbb_softc *sc = arg;
+ struct cardslot_softc *csc;
u_int32_t sockevent, sockstate;
if (!(sc->sc_flags & CBB_INSERTING)) {
@@ -1166,14 +1185,14 @@ pci113x_insert(void *arg)
DPRINTF((" card inserted, 0x%08x\n", sockstate));
sc->sc_flags |= CBB_CARDEXIST;
/* call pccard interrupt handler here */
- if (sockstate & CB_SOCKET_STAT_16BIT) {
+ if ((csc = sc->sc_csc) == NULL)
+ ;
+ else if (sockstate & CB_SOCKET_STAT_16BIT) {
/* 16-bit card found */
- cardslot_event_throw(sc->sc_csc,
- CARDSLOT_EVENT_INSERTION_16);
+ cardslot_event_throw(csc, CARDSLOT_EVENT_INSERTION_16);
} else if (sockstate & CB_SOCKET_STAT_CB) {
/* cardbus card found */
- cardslot_event_throw(sc->sc_csc,
- CARDSLOT_EVENT_INSERTION_CB);
+ cardslot_event_throw(csc, CARDSLOT_EVENT_INSERTION_CB);
} else {
/* who are you? */
}