Improve pci, cbb, cardslot, cardbus, and pcmcia to support detachment
of this entire device tree: pci0 at mainbus0 elansc0 at pci0 gpio0 at elansc0 cbb0 at pci0 cardslot0 at cbb0 cardbus0 at cardslot0 pcmcia0 at cardslot0 cbb1 at pci0 cardslot1 at cbb1 cardbus1 at cardslot1 rtw0 at cardbus1 pcmcia1 at cardslot1 sip0 at pci0 nsphyter0 at sip0 sip1 at pci0 nsphyter1 at sip1 Whew!
This commit is contained in:
parent
17c98b1431
commit
cf784f4497
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: cardbus.c,v 1.81 2007/12/09 20:27:55 jmcneill Exp $ */
|
||||
/* $NetBSD: cardbus.c,v 1.82 2007/12/16 21:28:30 dyoung Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1997, 1998, 1999 and 2000
|
||||
|
@ -33,7 +33,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: cardbus.c,v 1.81 2007/12/09 20:27:55 jmcneill Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: cardbus.c,v 1.82 2007/12/16 21:28:30 dyoung Exp $");
|
||||
|
||||
#include "opt_cardbus.h"
|
||||
|
||||
|
@ -70,6 +70,7 @@ __KERNEL_RCSID(0, "$NetBSD: cardbus.c,v 1.81 2007/12/09 20:27:55 jmcneill Exp $"
|
|||
|
||||
|
||||
STATIC void cardbusattach(struct device *, struct device *, void *);
|
||||
STATIC int cardbusdetach(device_t, int);
|
||||
STATIC int cardbusmatch(struct device *, struct cfdata *, void *);
|
||||
int cardbus_rescan(struct device *, const char *, const int *);
|
||||
void cardbus_childdetached(struct device *, struct device *);
|
||||
|
@ -91,7 +92,7 @@ static void disable_function(struct cardbus_softc *, int);
|
|||
static bool cardbus_child_register(device_t);
|
||||
|
||||
CFATTACH_DECL2(cardbus, sizeof(struct cardbus_softc),
|
||||
cardbusmatch, cardbusattach, NULL, NULL,
|
||||
cardbusmatch, cardbusattach, cardbusdetach, NULL,
|
||||
cardbus_rescan, cardbus_childdetached);
|
||||
|
||||
#ifndef __NetBSD_Version__
|
||||
|
@ -148,6 +149,18 @@ cardbusattach(struct device *parent, struct device *self, void *aux)
|
|||
aprint_error_dev(self, "couldn't establish power handler\n");
|
||||
}
|
||||
|
||||
STATIC int
|
||||
cardbusdetach(device_t self, int flags)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if ((rc = config_detach_children(self, flags)) != 0)
|
||||
return rc;
|
||||
|
||||
pmf_device_deregister(self);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
cardbus_read_tuples(struct cardbus_attach_args *ca, cardbusreg_t cis_ptr,
|
||||
u_int8_t *tuples, size_t len)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: cardslot.c,v 1.38 2007/12/09 20:27:55 jmcneill Exp $ */
|
||||
/* $NetBSD: cardslot.c,v 1.39 2007/12/16 21:28:31 dyoung Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1999 and 2000
|
||||
|
@ -33,7 +33,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: cardslot.c,v 1.38 2007/12/09 20:27:55 jmcneill Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: cardslot.c,v 1.39 2007/12/16 21:28:31 dyoung Exp $");
|
||||
|
||||
#include "opt_cardslot.h"
|
||||
|
||||
|
@ -66,6 +66,7 @@ __KERNEL_RCSID(0, "$NetBSD: cardslot.c,v 1.38 2007/12/09 20:27:55 jmcneill Exp $
|
|||
|
||||
|
||||
STATIC void cardslotattach(struct device *, struct device *, void *);
|
||||
STATIC int cardslotdetach(device_t, int);
|
||||
|
||||
STATIC int cardslotmatch(struct device *, struct cfdata *, void *);
|
||||
static void cardslot_event_thread(void *arg);
|
||||
|
@ -76,7 +77,7 @@ static int cardslot_16_submatch(struct device *, struct cfdata *,
|
|||
const int *, void *);
|
||||
|
||||
CFATTACH_DECL(cardslot, sizeof(struct cardslot_softc),
|
||||
cardslotmatch, cardslotattach, NULL, NULL);
|
||||
cardslotmatch, cardslotattach, cardslotdetach, NULL);
|
||||
|
||||
STATIC int
|
||||
cardslotmatch(struct device *parent, struct cfdata *cf,
|
||||
|
@ -171,7 +172,26 @@ cardslotattach(struct device *parent, struct device *self,
|
|||
aprint_error_dev(self, "couldn't establish power handler\n");
|
||||
}
|
||||
|
||||
STATIC int
|
||||
cardslotdetach(device_t self, int flags)
|
||||
{
|
||||
int rc;
|
||||
struct cardslot_softc *sc = device_private(self);
|
||||
|
||||
if ((rc = config_detach_children(self, flags)) != 0)
|
||||
return rc;
|
||||
|
||||
sc->sc_th_enable = 0;
|
||||
wakeup(&sc->sc_events);
|
||||
while (sc->sc_event_thread != NULL)
|
||||
(void)tsleep(sc, PWAIT, "cardslotthd", 0);
|
||||
|
||||
if (!SIMPLEQ_EMPTY(&sc->sc_events))
|
||||
aprint_error_dev(self, "events outstanding");
|
||||
|
||||
pmf_device_deregister(self);
|
||||
return 0;
|
||||
}
|
||||
|
||||
STATIC int
|
||||
cardslot_cb_print(void *aux, const char *pnp)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: pccbb.c,v 1.157 2007/12/11 11:11:22 martin Exp $ */
|
||||
/* $NetBSD: pccbb.c,v 1.158 2007/12/16 21:28:31 dyoung Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1998, 1999 and 2000
|
||||
|
@ -31,7 +31,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: pccbb.c,v 1.157 2007/12/11 11:11:22 martin Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: pccbb.c,v 1.158 2007/12/16 21:28:31 dyoung Exp $");
|
||||
|
||||
/*
|
||||
#define CBB_DEBUG
|
||||
|
@ -110,6 +110,7 @@ delay_ms(int millis, void *param)
|
|||
|
||||
int pcicbbmatch(struct device *, struct cfdata *, void *);
|
||||
void pccbbattach(struct device *, struct device *, void *);
|
||||
int pccbbdetach(device_t, int);
|
||||
int pccbbintr(void *);
|
||||
static void pci113x_insert(void *);
|
||||
static int pccbbintr_function(struct pccbb_softc *);
|
||||
|
@ -225,7 +226,7 @@ static void cb_show_regs(pci_chipset_tag_t pc, pcitag_t tag,
|
|||
#endif
|
||||
|
||||
CFATTACH_DECL(cbb_pci, sizeof(struct pccbb_softc),
|
||||
pcicbbmatch, pccbbattach, NULL, NULL);
|
||||
pcicbbmatch, pccbbattach, pccbbdetach, NULL);
|
||||
|
||||
static struct pcmcia_chip_functions pccbb_pcmcia_funcs = {
|
||||
pccbb_pcmcia_mem_alloc,
|
||||
|
@ -434,7 +435,7 @@ pccbbattach(struct device *parent, struct device *self, void *aux)
|
|||
PCI_MAPREG_MEM_ADDR(sock_base) != 0xfffffff0) {
|
||||
/* The address must be valid. */
|
||||
if (pci_mapreg_map(pa, PCI_SOCKBASE, PCI_MAPREG_TYPE_MEM, 0,
|
||||
&sc->sc_base_memt, &sc->sc_base_memh, &sockbase, NULL)) {
|
||||
&sc->sc_base_memt, &sc->sc_base_memh, &sockbase, &sc->sc_base_size)) {
|
||||
aprint_error("%s: can't map socket base address 0x%lx\n",
|
||||
sc->sc_dev.dv_xname, (unsigned long)sock_base);
|
||||
/*
|
||||
|
@ -443,7 +444,7 @@ pccbbattach(struct device *parent, struct device *self, void *aux)
|
|||
*/
|
||||
if (pci_mapreg_map(pa, PCI_SOCKBASE, PCI_MAPREG_TYPE_IO,
|
||||
0, &sc->sc_base_memt, &sc->sc_base_memh, &sockbase,
|
||||
NULL)) {
|
||||
&sc->sc_base_size)) {
|
||||
aprint_error("%s: can't map socket base address"
|
||||
" 0x%lx: io mode\n", sc->sc_dev.dv_xname,
|
||||
(unsigned long)sockbase);
|
||||
|
@ -515,8 +516,60 @@ pccbbattach(struct device *parent, struct device *self, void *aux)
|
|||
config_defer(self, pccbb_pci_callback);
|
||||
}
|
||||
|
||||
int
|
||||
pccbbdetach(device_t self, int flags)
|
||||
{
|
||||
struct pccbb_softc *sc = device_private(self);
|
||||
pci_chipset_tag_t pc = sc->sc_pa.pa_pc;
|
||||
bus_space_tag_t bmt = sc->sc_base_memt;
|
||||
bus_space_handle_t bmh = sc->sc_base_memh;
|
||||
uint32_t sockmask;
|
||||
int rc;
|
||||
|
||||
if ((rc = config_detach_children(self, flags)) != 0)
|
||||
return rc;
|
||||
|
||||
if (sc->sc_ih != NULL) {
|
||||
pci_intr_disestablish(pc, sc->sc_ih);
|
||||
sc->sc_ih = NULL;
|
||||
}
|
||||
|
||||
/* CSC Interrupt: turn off card detect and power cycle interrupts */
|
||||
sockmask = bus_space_read_4(bmt, bmh, CB_SOCKET_MASK);
|
||||
sockmask &= ~(CB_SOCKET_MASK_CD | CB_SOCKET_MASK_POWER);
|
||||
bus_space_write_4(bmt, bmh, CB_SOCKET_MASK, sockmask);
|
||||
/* reset interrupt */
|
||||
bus_space_write_4(bmt, bmh, CB_SOCKET_EVENT,
|
||||
bus_space_read_4(bmt, bmh, CB_SOCKET_EVENT));
|
||||
|
||||
switch (sc->sc_flags & (CBB_MEMHMAPPED|CBB_SPECMAPPED)) {
|
||||
case CBB_MEMHMAPPED:
|
||||
bus_space_unmap(bmt, bmh, sc->sc_base_size);
|
||||
break;
|
||||
case CBB_MEMHMAPPED|CBB_SPECMAPPED:
|
||||
#if rbus
|
||||
{
|
||||
pcireg_t sockbase;
|
||||
|
||||
sockbase = pci_conf_read(pc, sc->sc_tag, PCI_SOCKBASE);
|
||||
rbus_space_free(sc->sc_rbus_memt, bmh, 0x1000,
|
||||
NULL);
|
||||
}
|
||||
#else
|
||||
bus_space_free(bmt, bmh, 0x1000);
|
||||
#endif
|
||||
}
|
||||
sc->sc_flags &= ~(CBB_MEMHMAPPED|CBB_SPECMAPPED);
|
||||
|
||||
if (!TAILQ_EMPTY(&sc->sc_iowindow))
|
||||
aprint_error_dev(self, "i/o windows not empty");
|
||||
if (!TAILQ_EMPTY(&sc->sc_memwindow))
|
||||
aprint_error_dev(self, "memory windows not empty");
|
||||
|
||||
callout_stop(&sc->sc_insert_ch);
|
||||
callout_destroy(&sc->sc_insert_ch);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* static void pccbb_pci_callback(struct device *self)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: pccbbvar.h,v 1.30 2007/12/09 20:28:11 jmcneill Exp $ */
|
||||
/* $NetBSD: pccbbvar.h,v 1.31 2007/12/16 21:28:32 dyoung Exp $ */
|
||||
/*
|
||||
* Copyright (c) 1999 HAYAKAWA Koichi. All rights reserved.
|
||||
*
|
||||
|
@ -110,6 +110,7 @@ struct pccbb_softc {
|
|||
|
||||
bus_space_tag_t sc_base_memt;
|
||||
bus_space_handle_t sc_base_memh;
|
||||
bus_size_t sc_base_size;
|
||||
|
||||
struct callout sc_insert_ch;
|
||||
|
||||
|
@ -122,6 +123,7 @@ struct pccbb_softc {
|
|||
#define CBB_16BITCARD 0x04
|
||||
#define CBB_32BITCARD 0x08
|
||||
#define CBB_MEMHMAPPED 0x02000000
|
||||
#define CBB_SPECMAPPED 0x04000000 /* "special" mapping */
|
||||
|
||||
pci_chipset_tag_t sc_pc;
|
||||
pcitag_t sc_tag;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: pci.c,v 1.107 2007/12/09 20:28:11 jmcneill Exp $ */
|
||||
/* $NetBSD: pci.c,v 1.108 2007/12/16 21:28:32 dyoung Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1995, 1996, 1997, 1998
|
||||
|
@ -36,7 +36,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: pci.c,v 1.107 2007/12/09 20:28:11 jmcneill Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: pci.c,v 1.108 2007/12/16 21:28:32 dyoung Exp $");
|
||||
|
||||
#include "opt_pci.h"
|
||||
|
||||
|
@ -209,6 +209,10 @@ fail:
|
|||
static int
|
||||
pcidetach(struct device *self, int flags)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if ((rc = config_detach_children(self, flags)) != 0)
|
||||
return rc;
|
||||
pmf_device_deregister(self);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: pcmcia.c,v 1.84 2007/12/09 20:28:14 jmcneill Exp $ */
|
||||
/* $NetBSD: pcmcia.c,v 1.85 2007/12/16 21:28:30 dyoung Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2004 Charles M. Hannum. All rights reserved.
|
||||
|
@ -48,7 +48,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: pcmcia.c,v 1.84 2007/12/09 20:28:14 jmcneill Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: pcmcia.c,v 1.85 2007/12/16 21:28:30 dyoung Exp $");
|
||||
|
||||
#include "opt_pcmciaverbose.h"
|
||||
|
||||
|
@ -82,12 +82,13 @@ int pcmcia_verbose = 0;
|
|||
|
||||
int pcmcia_match(struct device *, struct cfdata *, void *);
|
||||
void pcmcia_attach(struct device *, struct device *, void *);
|
||||
int pcmcia_detach(device_t, int);
|
||||
int pcmcia_rescan(struct device *, const char *, const int *);
|
||||
void pcmcia_childdetached(struct device *, struct device *);
|
||||
int pcmcia_print(void *, const char *);
|
||||
|
||||
CFATTACH_DECL2(pcmcia, sizeof(struct pcmcia_softc),
|
||||
pcmcia_match, pcmcia_attach, NULL, NULL,
|
||||
pcmcia_match, pcmcia_attach, pcmcia_detach, NULL,
|
||||
pcmcia_rescan, pcmcia_childdetached);
|
||||
|
||||
int
|
||||
|
@ -145,6 +146,18 @@ pcmcia_attach(struct device *parent, struct device *self, void *aux)
|
|||
aprint_error_dev(self, "couldn't establish power handler\n");
|
||||
}
|
||||
|
||||
int
|
||||
pcmcia_detach(device_t self, int flags)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if ((rc = config_detach_children(self, flags)) != 0)
|
||||
return rc;
|
||||
|
||||
pmf_device_deregister(self);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
pcmcia_card_attach(dev)
|
||||
struct device *dev;
|
||||
|
|
Loading…
Reference in New Issue