A bunch of newcard/cardbus changes that's been sitting in my tree for a while:
- Make pccbb/cardbus kld loadable and unloadable. - Make pccbb/cardbus use the power interface from pccard instead of inventing its own. - some other minor fixes
This commit is contained in:
parent
a8e5d9ac32
commit
af82f62d2f
@ -260,8 +260,6 @@ dev/buslogic/bt_mca.c optional bt mca
|
||||
dev/buslogic/bt_pci.c optional bt pci
|
||||
dev/cardbus/cardbus.c optional cardbus
|
||||
dev/cardbus/cardbus_cis.c optional cardbus
|
||||
dev/pccbb/pccbb_if.m optional cardbus
|
||||
dev/pccbb/pccbb_if.m optional pccbb
|
||||
dev/ccd/ccd.c count ccd
|
||||
dev/cs/if_cs.c optional cs
|
||||
#dev/dpt/dpt_control.c optional dpt
|
||||
|
@ -57,11 +57,10 @@
|
||||
#include <dev/cardbus/cardbusvar.h>
|
||||
#include <dev/cardbus/cardbus_cis.h>
|
||||
|
||||
#include "pccbb_if.h"
|
||||
#include "power_if.h"
|
||||
#include "card_if.h"
|
||||
#include "pcib_if.h"
|
||||
|
||||
|
||||
#if defined CARDBUS_DEBUG
|
||||
#define STATIC
|
||||
#define DPRINTF(a) printf a
|
||||
@ -74,10 +73,9 @@
|
||||
|
||||
#if !defined(lint)
|
||||
static const char rcsid[] =
|
||||
"$FreeBSD $";
|
||||
"$FreeBSD$";
|
||||
#endif
|
||||
|
||||
|
||||
struct cardbus_quirk {
|
||||
u_int32_t devid; /* Vendor/device of the card */
|
||||
int type;
|
||||
@ -155,6 +153,13 @@ cardbus_attach(device_t dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
cardbus_detach(device_t dev)
|
||||
{
|
||||
cardbus_detach_card(dev, DETACH_FORCE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
/* Attach/Detach card */
|
||||
/************************************************************************/
|
||||
@ -188,24 +193,11 @@ static int
|
||||
cardbus_attach_card(device_t dev)
|
||||
{
|
||||
device_t bdev = device_get_parent(dev);
|
||||
int cdstatus;
|
||||
int cardattached = 0;
|
||||
static int curr_bus_number = 2; /* XXX EVILE BAD (see below) */
|
||||
int bus, slot, func;
|
||||
|
||||
/* inspect initial voltage */
|
||||
if (0 == (cdstatus = PCCBB_DETECT_CARD(bdev))) {
|
||||
DEVPRINTF((dev, "cardbusattach: no CardBus card detected\n"));
|
||||
return ENXIO;
|
||||
}
|
||||
|
||||
if (cdstatus & CARD_3V_CARD) {
|
||||
PCCBB_POWER_SOCKET(bdev, CARD_VCC_3V);
|
||||
} else {
|
||||
device_printf(dev, "unsupported power: %d\n", cdstatus);
|
||||
return EINVAL;
|
||||
}
|
||||
PCCBB_RESET(bdev);
|
||||
POWER_ENABLE_SOCKET(bdev, dev);
|
||||
|
||||
bus = pci_get_secondarybus(bdev);
|
||||
if (bus == 0) {
|
||||
@ -253,6 +245,7 @@ cardbus_attach_card(device_t dev)
|
||||
}
|
||||
|
||||
if (cardattached > 0) return 0;
|
||||
POWER_DISABLE_SOCKET(bdev, dev);
|
||||
return ENOENT;
|
||||
}
|
||||
|
||||
@ -268,20 +261,43 @@ cardbus_detach_card(device_t dev, int flags)
|
||||
|
||||
if (numdevs == 0) {
|
||||
DEVPRINTF((dev, "Detaching card: no cards to detach!\n"));
|
||||
POWER_DISABLE_SOCKET(device_get_parent(dev), dev);
|
||||
return ENOENT;
|
||||
}
|
||||
|
||||
for (tmp = 0; tmp < numdevs; tmp++) {
|
||||
struct cardbus_devinfo *dinfo = device_get_ivars(devlist[tmp]);
|
||||
if (device_detach(dinfo->cfg.dev) != 0) err++;
|
||||
cardbus_release_all_resources(dinfo->cfg.dev,
|
||||
&dinfo->resources);
|
||||
device_delete_child(dev, devlist[tmp]);
|
||||
if (device_detach(dinfo->cfg.dev) == 0 || flags & DETACH_FORCE){
|
||||
cardbus_release_all_resources(dinfo->cfg.dev,
|
||||
&dinfo->resources);
|
||||
device_delete_child(dev, devlist[tmp]);
|
||||
} else
|
||||
err++;
|
||||
cardbus_freecfg(dinfo);
|
||||
}
|
||||
if (err == 0)
|
||||
POWER_DISABLE_SOCKET(device_get_parent(dev), dev);
|
||||
return err;
|
||||
}
|
||||
|
||||
static void
|
||||
cardbus_driver_added(device_t dev, driver_t *driver)
|
||||
{
|
||||
/*
|
||||
* For this to work, we should:
|
||||
* 1) power up the slot if it isn't powered.
|
||||
* (Is this necessary? Can we assume _probe() doesn't need power?)
|
||||
* 2) probe (we should probe even though we already have child?)
|
||||
* 3) power up if we haven't done so and probe succeeds
|
||||
* 4) attach if probe succeeds.
|
||||
* 5) power down if probe or attach failed, and the slot was powered
|
||||
* down to begin with.
|
||||
*/
|
||||
printf("I see you added a driver that could be a child of cardbus...\n");
|
||||
printf("If this is for a cardbus card, please remove and reinsert the card.\n");
|
||||
printf("(there is no current support for adding a driver like this)\n");
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
/* PCI-Like config reading (copied from pci.c */
|
||||
/************************************************************************/
|
||||
@ -649,6 +665,7 @@ cardbus_add_resources(device_t dev, pcicfgregs* cfg)
|
||||
struct cardbus_quirk *q;
|
||||
struct resource_list_entry *rle;
|
||||
struct resource *res;
|
||||
int rid;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < cfg->nummaps; i++) {
|
||||
@ -662,15 +679,16 @@ cardbus_add_resources(device_t dev, pcicfgregs* cfg)
|
||||
cardbus_add_map(cbdev, dev, cfg, q->arg1);
|
||||
}
|
||||
|
||||
rid = 0;
|
||||
res = bus_generic_alloc_resource(cbdev, dev, SYS_RES_IRQ,
|
||||
0, 0, ~0, 1, RF_SHAREABLE);
|
||||
&rid, 0, ~0, 1, RF_SHAREABLE);
|
||||
|
||||
if (res == NULL)
|
||||
panic("Cannot allocate IRQ for card\n");
|
||||
|
||||
resource_list_add(rl, SYS_RES_IRQ, 0,
|
||||
resource_list_add(rl, SYS_RES_IRQ, rid,
|
||||
rman_get_start(res), rman_get_start(res), 1);
|
||||
rle = resource_list_find(rl, SYS_RES_IRQ, 0);
|
||||
rle = resource_list_find(rl, SYS_RES_IRQ, rid);
|
||||
rle->res = res;
|
||||
}
|
||||
|
||||
@ -688,8 +706,8 @@ cardbus_release_all_resources(device_t dev, struct resource_list *rl)
|
||||
}
|
||||
}
|
||||
|
||||
static struct
|
||||
resource* cardbus_alloc_resource(device_t self, device_t child, int type,
|
||||
static struct resource*
|
||||
cardbus_alloc_resource(device_t self, device_t child, int type,
|
||||
int* rid, u_long start, u_long end,
|
||||
u_long count, u_int flags)
|
||||
{
|
||||
@ -941,7 +959,7 @@ static device_method_t cardbus_methods[] = {
|
||||
/* Device interface */
|
||||
DEVMETHOD(device_probe, cardbus_probe),
|
||||
DEVMETHOD(device_attach, cardbus_attach),
|
||||
DEVMETHOD(device_detach, bus_generic_detach),
|
||||
DEVMETHOD(device_detach, cardbus_detach),
|
||||
DEVMETHOD(device_shutdown, bus_generic_shutdown),
|
||||
DEVMETHOD(device_suspend, bus_generic_suspend),
|
||||
DEVMETHOD(device_resume, bus_generic_resume),
|
||||
@ -951,13 +969,14 @@ static device_method_t cardbus_methods[] = {
|
||||
DEVMETHOD(bus_probe_nomatch, cardbus_probe_nomatch),
|
||||
DEVMETHOD(bus_read_ivar, cardbus_read_ivar),
|
||||
DEVMETHOD(bus_write_ivar, cardbus_write_ivar),
|
||||
DEVMETHOD(bus_driver_added, bus_generic_driver_added),
|
||||
DEVMETHOD(bus_driver_added, cardbus_driver_added),
|
||||
DEVMETHOD(bus_alloc_resource, cardbus_alloc_resource),
|
||||
DEVMETHOD(bus_release_resource, cardbus_release_resource),
|
||||
DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
|
||||
DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
|
||||
DEVMETHOD(bus_setup_intr, bus_generic_setup_intr),
|
||||
DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr),
|
||||
DEVMETHOD(bus_driver_added, bus_generic_driver_added),
|
||||
|
||||
DEVMETHOD(bus_set_resource, cardbus_set_resource_method),
|
||||
DEVMETHOD(bus_get_resource, cardbus_get_resource_method),
|
||||
@ -980,6 +999,7 @@ static driver_t cardbus_driver = {
|
||||
0 /* no softc */
|
||||
};
|
||||
|
||||
static devclass_t cardbus_devclass = {};
|
||||
static devclass_t cardbus_devclass;
|
||||
|
||||
DRIVER_MODULE(cardbus, pccbb, cardbus_driver, cardbus_devclass, 0, 0);
|
||||
MODULE_DEPEND(cardbus, pccbb, 1, 1, 1);
|
||||
|
@ -53,6 +53,7 @@
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/kthread.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/mutex.h>
|
||||
|
||||
#include <sys/bus.h>
|
||||
#include <machine/bus.h>
|
||||
@ -72,7 +73,6 @@
|
||||
|
||||
#include "power_if.h"
|
||||
#include "card_if.h"
|
||||
#include "pccbb_if.h"
|
||||
#include "pcib_if.h"
|
||||
|
||||
#if defined CBB_DEBUG
|
||||
@ -98,7 +98,10 @@
|
||||
#define PCIC_MASK2(SC,REG,MASK,MASK2) \
|
||||
PCIC_WRITE(SC,REG,(PCIC_READ(SC,REG) MASK) MASK2)
|
||||
|
||||
#define DETACH_FORCE 0x1
|
||||
#if !defined(lint)
|
||||
static const char rcsid[] =
|
||||
"$FreeBSD$";
|
||||
#endif
|
||||
|
||||
struct pccbb_sclist {
|
||||
struct pccbb_softc *sc;
|
||||
@ -182,16 +185,20 @@ static int cb_chipset(u_int32_t pci_id, const char** namep, int* flagp);
|
||||
static int pccbb_probe(device_t dev);
|
||||
static void pccbb_chipinit(struct pccbb_softc* sc);
|
||||
static int pccbb_attach(device_t dev);
|
||||
static int pccbb_detach(device_t dev);
|
||||
static void pccbb_driver_added(device_t dev, driver_t *driver);
|
||||
static void pccbb_child_detached(device_t dev, device_t child);
|
||||
static void pccbb_event_thread (void *arg);
|
||||
static void pccbb_create_event_thread (struct pccbb_softc *sc);
|
||||
static void pccbb_start_threads(void *arg);
|
||||
static void pccbb_insert (struct pccbb_softc *sc);
|
||||
static void pccbb_removal (struct pccbb_softc *sc);
|
||||
static void pccbb_intr(void* arg);
|
||||
static int pccbb_detect_voltage(struct pccbb_softc *sc);
|
||||
static int pccbb_detect_voltage(device_t dev);
|
||||
static int pccbb_power(device_t dev, int volts);
|
||||
static int pccbb_cardbus_detect_card(device_t dev);
|
||||
static int pccbb_cardbus_reset(device_t dev);
|
||||
static void pccbb_cardbus_reset(device_t dev);
|
||||
static int pccbb_cardbus_power_enable_socket(device_t self, device_t child);
|
||||
static void pccbb_cardbus_power_disable_socket(device_t self, device_t child);
|
||||
static int pccbb_cardbus_io_open(device_t dev, int win,
|
||||
u_int32_t start, u_int32_t end);
|
||||
static int pccbb_cardbus_mem_open(device_t dev, int win,
|
||||
@ -210,6 +217,8 @@ static struct resource* pccbb_cardbus_alloc_resource(device_t self,
|
||||
static int pccbb_cardbus_release_resource(device_t self, device_t child,
|
||||
int type,int rid,
|
||||
struct resource *r);
|
||||
static int pccbb_pcic_power_enable_socket(device_t self, device_t child);
|
||||
static void pccbb_pcic_power_disable_socket(device_t self, device_t child);
|
||||
static void pccbb_pcic_wait_ready(struct pccbb_softc *sc);
|
||||
static void pccbb_pcic_do_mem_map(struct pccbb_softc *sc, int win);
|
||||
static int pccbb_pcic_mem_map(struct pccbb_softc *sc, int kind,
|
||||
@ -234,8 +243,8 @@ static int pccbb_pcic_set_res_flags(device_t self, device_t child, int type,
|
||||
int rid, u_int32_t flags);
|
||||
static int pccbb_pcic_set_memory_offset(device_t self, device_t child, int rid,
|
||||
u_int32_t offset);
|
||||
static int pccbb_pcic_enable_socket(device_t self, device_t child);
|
||||
static void pccbb_pcic_disable_socket(device_t self, device_t child);
|
||||
static int pccbb_power_enable_socket(device_t self, device_t child);
|
||||
static void pccbb_power_disable_socket(device_t self, device_t child);
|
||||
static int pccbb_activate_resource(device_t self, device_t child, int type,
|
||||
int rid, struct resource *r);
|
||||
static int pccbb_deactivate_resource(device_t self, device_t child, int type,
|
||||
@ -246,6 +255,11 @@ static struct resource* pccbb_alloc_resource(device_t self, device_t child,
|
||||
u_int flags);
|
||||
static int pccbb_release_resource(device_t self, device_t child,
|
||||
int type, int rid, struct resource *r);
|
||||
static int pccbb_maxslots(device_t dev);
|
||||
static u_int32_t pccbb_read_config(device_t dev, int b, int s, int f,
|
||||
int reg, int width);
|
||||
static void pccbb_write_config(device_t dev, int b, int s, int f, int reg,
|
||||
u_int32_t val, int width);
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
@ -372,6 +386,7 @@ pccbb_attach(device_t dev)
|
||||
softcs_init = 1;
|
||||
STAILQ_INIT(&softcs);
|
||||
}
|
||||
mtx_init(&sc->sc_mtx, device_get_nameunit(dev), MTX_DEF);
|
||||
sc->sc_chipset = cb_chipset(pci_get_devid(dev), NULL, &flags);
|
||||
sc->sc_dev = dev;
|
||||
sc->sc_flags = 0;
|
||||
@ -408,6 +423,7 @@ pccbb_attach(device_t dev)
|
||||
if (!sc->sc_base_res){
|
||||
device_printf(dev,
|
||||
"Could not grab register memory\n");
|
||||
mtx_destroy(&sc->sc_mtx);
|
||||
return ENOMEM;
|
||||
}
|
||||
pci_write_config(dev, PCCBBR_SOCKBASE,
|
||||
@ -416,6 +432,7 @@ pccbb_attach(device_t dev)
|
||||
rman_get_start(sc->sc_base_res)));
|
||||
} else {
|
||||
device_printf(dev, "Could not map register memory\n");
|
||||
mtx_destroy(&sc->sc_mtx);
|
||||
return ENOMEM;
|
||||
}
|
||||
}
|
||||
@ -437,6 +454,9 @@ pccbb_attach(device_t dev)
|
||||
RF_SHAREABLE | RF_ACTIVE);
|
||||
if (sc->sc_irq_res == NULL) {
|
||||
printf("pccbb: Unable to map IRQ...\n");
|
||||
bus_release_resource(dev, SYS_RES_MEMORY, PCCBBR_SOCKBASE,
|
||||
sc->sc_base_res);
|
||||
mtx_destroy(&sc->sc_mtx);
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
@ -446,34 +466,38 @@ pccbb_attach(device_t dev)
|
||||
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_irq_res);
|
||||
bus_release_resource(dev, SYS_RES_MEMORY, PCCBBR_SOCKBASE,
|
||||
sc->sc_base_res);
|
||||
mtx_destroy(&sc->sc_mtx);
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
/* attach children */
|
||||
sc->sc_cbdev = device_add_child(dev, "cardbus", -1);
|
||||
if (sc->sc_cbdev == NULL)
|
||||
DEVPRINTF((dev, "Cannot add cardbus bus!\n"));
|
||||
DEVPRINTF((dev, "WARNING: cannot add cardbus bus.\n"));
|
||||
else if (device_probe_and_attach(sc->sc_cbdev) != 0) {
|
||||
DEVPRINTF((dev, "Cannot attach cardbus bus!\n"));
|
||||
DEVPRINTF((dev, "WARNING: cannot attach cardbus bus!\n"));
|
||||
sc->sc_cbdev = NULL;
|
||||
}
|
||||
|
||||
sc->sc_pccarddev = device_add_child(dev, "pccard", -1);
|
||||
if (sc->sc_pccarddev == NULL)
|
||||
DEVPRINTF((dev, "Cannot add pccard bus!\n"));
|
||||
DEVPRINTF((dev, "WARNING: cannot add pccard bus.\n"));
|
||||
else if (device_probe_and_attach(sc->sc_pccarddev) != 0) {
|
||||
DEVPRINTF((dev, "Cannot attach pccard bus!\n"));
|
||||
DEVPRINTF((dev, "WARNING: cannot attach pccard bus.\n"));
|
||||
sc->sc_pccarddev = NULL;
|
||||
}
|
||||
|
||||
#ifndef KLD_MODULE
|
||||
if (sc->sc_cbdev == NULL && sc->sc_pccarddev == NULL) {
|
||||
device_printf(dev, "Failed to attach cardbus/pccard bus!\n");
|
||||
device_printf(dev, "ERROR: Failed to attach cardbus/pccard bus!\n");
|
||||
bus_teardown_intr(dev, sc->sc_irq_res, sc->sc_intrhand);
|
||||
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_irq_res);
|
||||
bus_release_resource(dev, SYS_RES_MEMORY, PCCBBR_SOCKBASE,
|
||||
sc->sc_base_res);
|
||||
mtx_destroy(&sc->sc_mtx);
|
||||
return ENOMEM;
|
||||
}
|
||||
#endif
|
||||
|
||||
{
|
||||
struct pccbb_sclist *sclist;
|
||||
@ -485,6 +509,90 @@ pccbb_attach(device_t dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
pccbb_detach(device_t dev)
|
||||
{
|
||||
struct pccbb_softc *sc = device_get_softc(dev);
|
||||
int numdevs;
|
||||
device_t *devlist;
|
||||
int tmp;
|
||||
int error;
|
||||
|
||||
device_get_children(dev, &devlist, &numdevs);
|
||||
|
||||
error = 0;
|
||||
for (tmp = 0; tmp < numdevs; tmp++) {
|
||||
if (device_detach(devlist[tmp]) == 0)
|
||||
device_delete_child(dev, devlist[tmp]);
|
||||
else
|
||||
error++;
|
||||
}
|
||||
if (error > 0)
|
||||
return ENXIO;
|
||||
|
||||
mtx_enter(&sc->sc_mtx, MTX_DEF);
|
||||
bus_teardown_intr(dev, sc->sc_irq_res, sc->sc_intrhand);
|
||||
|
||||
sc->sc_flags |= PCCBB_KTHREAD_DONE;
|
||||
if (sc->sc_flags & PCCBB_KTHREAD_RUNNING) {
|
||||
wakeup(sc);
|
||||
mtx_exit(&sc->sc_mtx, MTX_DEF);
|
||||
DEVPRINTF((dev, "waiting for kthread exit..."));
|
||||
error = tsleep(sc, PWAIT, "pccbb-detach-wait", 60 * hz);
|
||||
if (error)
|
||||
DPRINTF(("timeout\n"));
|
||||
else
|
||||
DPRINTF(("done\n"));
|
||||
} else
|
||||
mtx_exit(&sc->sc_mtx, MTX_DEF);
|
||||
|
||||
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_irq_res);
|
||||
bus_release_resource(dev, SYS_RES_MEMORY, PCCBBR_SOCKBASE,
|
||||
sc->sc_base_res);
|
||||
mtx_destroy(&sc->sc_mtx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
pccbb_driver_added(device_t dev, driver_t *driver)
|
||||
{
|
||||
struct pccbb_softc *sc = device_get_softc(dev);
|
||||
device_t *devlist;
|
||||
int tmp;
|
||||
int numdevs;
|
||||
|
||||
DEVICE_IDENTIFY(driver, dev);
|
||||
device_get_children(dev, &devlist, &numdevs);
|
||||
for (tmp = 0; tmp < numdevs; tmp++) {
|
||||
if (device_get_state(devlist[tmp]) == DS_NOTPRESENT &&
|
||||
device_probe_and_attach(devlist[tmp]) == 0) {
|
||||
if (devlist[tmp] == NULL)
|
||||
/* NOTHING */;
|
||||
else if (strcmp(driver->name, "cardbus") == 0)
|
||||
sc->sc_cbdev = devlist[tmp];
|
||||
else if (strcmp(driver->name, "pccard") == 0)
|
||||
sc->sc_pccarddev = devlist[tmp];
|
||||
else
|
||||
device_printf(dev,
|
||||
"Unsupported child bus: %s\n",
|
||||
driver->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
pccbb_child_detached(device_t dev, device_t child)
|
||||
{
|
||||
struct pccbb_softc *sc = device_get_softc(dev);
|
||||
if (child == sc->sc_cbdev)
|
||||
sc->sc_cbdev = NULL;
|
||||
else if (child == sc->sc_pccarddev)
|
||||
sc->sc_pccarddev = NULL;
|
||||
else
|
||||
device_printf(dev, "Unknown child detached: %s %p/%p\n",
|
||||
device_get_nameunit(child), sc->sc_cbdev, sc->sc_pccarddev);
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
/* Kthreads */
|
||||
/************************************************************************/
|
||||
@ -493,25 +601,24 @@ static void
|
||||
pccbb_event_thread (void *arg)
|
||||
{
|
||||
struct pccbb_softc *sc = arg;
|
||||
int s;
|
||||
u_int32_t status;
|
||||
|
||||
s = splhigh();
|
||||
for(;;) {
|
||||
if (sc->sc_flags & PCCBB_INITIALCARD)
|
||||
sc->sc_flags &= ~PCCBB_INITIALCARD;
|
||||
if (!(sc->sc_flags & PCCBB_KTHREAD_RUNNING))
|
||||
sc->sc_flags |= PCCBB_KTHREAD_RUNNING;
|
||||
else {
|
||||
splx (s);
|
||||
tsleep (sc, PWAIT, "pccbbev", 0);
|
||||
/*
|
||||
* Delay some time, make sure the user is done with
|
||||
* whatever he is doing.
|
||||
* Delay 1 second, make sure the user is done with
|
||||
* whatever he is doing. We tsleep on sc->sc_flags,
|
||||
* which should never be woken up.
|
||||
*/
|
||||
DELAY(1000*1000);
|
||||
s = splhigh();
|
||||
tsleep (&sc->sc_flags, PWAIT, "pccbbev", 1*hz);
|
||||
}
|
||||
mtx_enter(&sc->sc_mtx, MTX_DEF);
|
||||
if (sc->sc_flags & PCCBB_KTHREAD_DONE)
|
||||
break;
|
||||
|
||||
sc->sc_flags |= PCCBB_CARDSTATUS_BUSY;
|
||||
status = sc->sc_socketreg->socket_state;
|
||||
if ((status & PCCBB_SOCKET_STAT_CD) == 0) {
|
||||
if (!(sc->sc_flags & PCCBB_CARDATTACHED))
|
||||
@ -526,10 +633,12 @@ pccbb_event_thread (void *arg)
|
||||
else
|
||||
pccbb_removal(sc);
|
||||
}
|
||||
sc->sc_flags &= ~PCCBB_CARDSTATUS_BUSY;
|
||||
splx (s);
|
||||
mtx_exit(&sc->sc_mtx, MTX_DEF);
|
||||
}
|
||||
/* NOTREACHED */
|
||||
mtx_exit(&sc->sc_mtx, MTX_DEF);
|
||||
sc->sc_flags &= ~PCCBB_KTHREAD_RUNNING;
|
||||
wakeup(sc);
|
||||
mtx_enter(&Giant, MTX_DEF);
|
||||
kthread_exit(0);
|
||||
}
|
||||
|
||||
@ -550,10 +659,6 @@ pccbb_start_threads(void *arg)
|
||||
struct pccbb_sclist *sclist;
|
||||
|
||||
STAILQ_FOREACH(sclist, &softcs, entries) {
|
||||
if (0 == (sclist->sc->sc_socketreg->socket_state &
|
||||
PCCBB_SOCKET_STAT_CD)) {
|
||||
sclist->sc->sc_flags |= PCCBB_INITIALCARD;
|
||||
}
|
||||
pccbb_create_event_thread(sclist->sc);
|
||||
}
|
||||
}
|
||||
@ -630,7 +735,6 @@ pccbb_intr(void* arg)
|
||||
{
|
||||
struct pccbb_softc *sc = arg;
|
||||
u_int32_t sockevent;
|
||||
int tmp;
|
||||
|
||||
if (!(sockevent = sc->sc_socketreg->socket_event)) {
|
||||
/* not for me. */
|
||||
@ -641,19 +745,9 @@ pccbb_intr(void* arg)
|
||||
sc->sc_socketreg->socket_event = sockevent | 0x01;
|
||||
|
||||
if (sockevent & PCCBB_SOCKET_EVENT_CD) {
|
||||
for (tmp = 0; tmp <= 100 &&
|
||||
(sc->sc_flags & PCCBB_CARDSTATUS_BUSY); tmp++) {
|
||||
if (tmp == 0)
|
||||
DEVPRINTF((sc->sc_dev, "(pccbbintr): busy!"));
|
||||
else
|
||||
DPRINTF(("."));
|
||||
DELAY(1);
|
||||
}
|
||||
if (sc->sc_flags & PCCBB_CARDSTATUS_BUSY) {
|
||||
DPRINTF(("failed! Going ahead anyway..."));
|
||||
sc->sc_flags &= ~PCCBB_CARDSTATUS_BUSY;
|
||||
}
|
||||
mtx_enter(&sc->sc_mtx, MTX_DEF);
|
||||
wakeup(sc);
|
||||
mtx_exit(&sc->sc_mtx, MTX_DEF);
|
||||
} else {
|
||||
if (sockevent & PCCBB_SOCKET_EVENT_CSTS) {
|
||||
DPRINTF((" cstsevent occures, 0x%08x\n",
|
||||
@ -669,12 +763,13 @@ pccbb_intr(void* arg)
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
/* Power functions */
|
||||
/* Generic Power functions */
|
||||
/************************************************************************/
|
||||
|
||||
static int
|
||||
pccbb_detect_voltage(struct pccbb_softc *sc)
|
||||
pccbb_detect_voltage(device_t dev)
|
||||
{
|
||||
struct pccbb_softc *sc = device_get_softc(dev);
|
||||
u_int32_t psr;
|
||||
int vol = CARD_UKN_CARD;
|
||||
|
||||
@ -813,43 +908,56 @@ pccbb_power(device_t dev, int volts)
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
/* PCCBB methods */
|
||||
/* Cardbus power functions */
|
||||
/************************************************************************/
|
||||
|
||||
static int
|
||||
pccbb_cardbus_detect_card(device_t dev)
|
||||
{
|
||||
struct pccbb_softc *sc = device_get_softc(dev);
|
||||
u_int32_t sockstat = sc->sc_socketreg->socket_state;
|
||||
|
||||
if (sockstat & PCCBB_SOCKET_STAT_CB)
|
||||
return pccbb_detect_voltage(sc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
static void
|
||||
pccbb_cardbus_reset(device_t dev)
|
||||
{
|
||||
struct pccbb_softc *sc = device_get_softc(dev);
|
||||
u_int32_t bcr = pci_read_config(dev, PCCBBR_BRIDGECTRL, 2);
|
||||
int delay_us;
|
||||
|
||||
delay_us = sc->sc_chipset == CB_RF5C47X ? 400*1000 : 20*1000;
|
||||
|
||||
bcr |= PCCBBM_BRIDGECTRL_RESET;
|
||||
pci_write_config(dev, PCCBBR_BRIDGECTRL, bcr, 2);
|
||||
PCI_MASK_CONFIG(dev, PCCBBR_BRIDGECTRL, |PCCBBM_BRIDGECTRL_RESET, 2);
|
||||
|
||||
DELAY(delay_us);
|
||||
|
||||
/* If a card exists, unreset it! */
|
||||
if (sc->sc_flags & PCCBB_CARDATTACHED) {
|
||||
bcr &= ~PCCBBM_BRIDGECTRL_RESET;
|
||||
pci_write_config(dev, PCCBBR_BRIDGECTRL, bcr, 2);
|
||||
PCI_MASK_CONFIG(dev, PCCBBR_BRIDGECTRL,
|
||||
&~PCCBBM_BRIDGECTRL_RESET, 2);
|
||||
DELAY(delay_us);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
pccbb_cardbus_power_enable_socket(device_t self, device_t child)
|
||||
{
|
||||
int voltage;
|
||||
|
||||
voltage = pccbb_detect_voltage(self);
|
||||
|
||||
pccbb_power(self, CARD_VCC_0V | CARD_VPP_0V);
|
||||
if (voltage & CARD_5V_CARD)
|
||||
pccbb_power(self, CARD_VCC_5V | CARD_VPP_VCC);
|
||||
else if (voltage & CARD_3V_CARD)
|
||||
pccbb_power(self, CARD_VCC_3V | CARD_VPP_VCC);
|
||||
else {
|
||||
device_printf(self, "Unknown card voltage\n");
|
||||
return ENXIO;
|
||||
}
|
||||
|
||||
pccbb_cardbus_reset(self);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
pccbb_cardbus_power_disable_socket(device_t self, device_t child)
|
||||
{
|
||||
pccbb_power(self, CARD_VCC_0V | CARD_VPP_0V);
|
||||
pccbb_cardbus_reset(self);
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
/* Cardbus Resource */
|
||||
@ -953,11 +1061,8 @@ pccbb_cardbus_auto_open(struct pccbb_softc *sc, int type)
|
||||
ends[rle->win] = rle->end;
|
||||
else if (rle->end < starts[rle->win])
|
||||
starts[rle->win] = rle->start;
|
||||
else
|
||||
panic("pccbb_auto_open: Weird condition!\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (type == SYS_RES_MEMORY)
|
||||
align = PCCBB_MEMALIGN;
|
||||
else if (type == SYS_RES_IOPORT)
|
||||
@ -970,9 +1075,9 @@ pccbb_cardbus_auto_open(struct pccbb_softc *sc, int type)
|
||||
if (starts[1] != 0xffffffff)
|
||||
starts[1] -= starts[1] % align;
|
||||
if (ends[0] % align != 0)
|
||||
ends[0] += align - ends[0]%align;
|
||||
ends[0] += align - ends[0]%align - 1;
|
||||
if (ends[1] % align != 0)
|
||||
ends[1] += align - ends[1]%align;
|
||||
ends[1] += align - ends[1]%align - 1;
|
||||
|
||||
if (type == SYS_RES_MEMORY) {
|
||||
pccbb_cardbus_mem_open(sc->sc_dev, 0, starts[0], ends[0]);
|
||||
@ -1008,7 +1113,6 @@ pccbb_cardbus_activate_resource(device_t self, device_t child, int type,
|
||||
|
||||
pccbb_cardbus_auto_open(sc, type);
|
||||
}
|
||||
|
||||
return bus_generic_activate_resource(self, child, type, rid, r);
|
||||
}
|
||||
|
||||
@ -1066,7 +1170,96 @@ pccbb_cardbus_release_resource(device_t self, device_t child, int type,
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
/* PC Card Resources */
|
||||
/* PC Card Power Functions */
|
||||
/************************************************************************/
|
||||
|
||||
static int
|
||||
pccbb_pcic_power_enable_socket(device_t self, device_t child)
|
||||
{
|
||||
struct pccbb_softc *sc = device_get_softc(self);
|
||||
|
||||
DPRINTF(("pccbb_pcic_socket_enable:\n"));
|
||||
|
||||
/* power down/up the socket to reset */
|
||||
{
|
||||
int voltage = pccbb_detect_voltage(self);
|
||||
|
||||
pccbb_power(self, CARD_VCC_0V | CARD_VPP_0V);
|
||||
if (voltage & CARD_5V_CARD)
|
||||
pccbb_power(self, CARD_VCC_5V | CARD_VPP_VCC);
|
||||
else if (voltage & CARD_3V_CARD)
|
||||
pccbb_power(self, CARD_VCC_3V | CARD_VPP_VCC);
|
||||
else {
|
||||
device_printf(self, "Unknown card voltage\n");
|
||||
return ENXIO;
|
||||
}
|
||||
}
|
||||
|
||||
/* enable socket i/o */
|
||||
PCIC_MASK(sc, PCIC_PWRCTL, | PCIC_PWRCTL_OE);
|
||||
|
||||
PCIC_WRITE(sc, PCIC_INTR, PCIC_INTR_ENABLE);
|
||||
/* hold reset for 30ms */
|
||||
DELAY(30*1000);
|
||||
/* clear the reset flag */
|
||||
PCIC_MASK(sc, PCIC_INTR, | PCIC_INTR_RESET);
|
||||
/* wait 20ms as per pc card standard (r2.01) section 4.3.6 */
|
||||
DELAY(20*1000);
|
||||
|
||||
pccbb_pcic_wait_ready(sc);
|
||||
|
||||
/* disable all address windows */
|
||||
PCIC_WRITE(sc, PCIC_ADDRWIN_ENABLE, 0);
|
||||
|
||||
{
|
||||
int cardtype;
|
||||
CARD_GET_TYPE(child, &cardtype);
|
||||
PCIC_MASK(sc, PCIC_INTR, | ((cardtype == PCCARD_IFTYPE_IO) ?
|
||||
PCIC_INTR_CARDTYPE_IO :
|
||||
PCIC_INTR_CARDTYPE_MEM));
|
||||
DEVPRINTF((sc->sc_dev, "card type is %s\n",
|
||||
(cardtype == PCCARD_IFTYPE_IO) ? "io" : "mem"));
|
||||
}
|
||||
|
||||
/* reinstall all the memory and io mappings */
|
||||
{
|
||||
int win;
|
||||
|
||||
for (win = 0; win < PCIC_MEM_WINS; ++win) {
|
||||
if (sc->memalloc & (1 << win)) {
|
||||
pccbb_pcic_do_mem_map(sc, win);
|
||||
}
|
||||
}
|
||||
for (win = 0; win < PCIC_IO_WINS; ++win) {
|
||||
if (sc->ioalloc & (1 << win)) {
|
||||
pccbb_pcic_do_io_map(sc, win);
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
pccbb_pcic_power_disable_socket(device_t self, device_t child)
|
||||
{
|
||||
struct pccbb_softc *sc = device_get_softc(self);
|
||||
|
||||
DPRINTF(("pccbb_pcic_socket_disable\n"));
|
||||
|
||||
/* reset signal asserting... */
|
||||
PCIC_MASK(sc, PCIC_INTR, & ~PCIC_INTR_RESET);
|
||||
DELAY(2*1000);
|
||||
|
||||
/* power down the socket */
|
||||
PCIC_MASK(sc, PCIC_PWRCTL, &~PCIC_PWRCTL_OE);
|
||||
pccbb_power(self, CARD_VCC_0V | CARD_VPP_0V);
|
||||
|
||||
/* wait 300ms until power fails (Tpf). */
|
||||
DELAY(300 * 1000);
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
/* PC Card Resource Functions */
|
||||
/************************************************************************/
|
||||
|
||||
static void
|
||||
@ -1387,6 +1580,12 @@ pccbb_pcic_alloc_resource(device_t self, device_t child, int type, int* rid,
|
||||
struct pccbb_softc *sc = device_get_softc(self);
|
||||
struct pccbb_reslist *rle;
|
||||
|
||||
/* Nearly default */
|
||||
if (type == SYS_RES_MEMORY && start == 0 && end == ~0 && count != 1) {
|
||||
start = 0xd0000; /* XXX */
|
||||
end = 0xdffff;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case SYS_RES_MEMORY:
|
||||
/* Nearly default */
|
||||
@ -1463,7 +1662,7 @@ pccbb_pcic_set_res_flags(device_t self, device_t child, int type, int rid,
|
||||
|
||||
if (type != SYS_RES_MEMORY)
|
||||
return (EINVAL);
|
||||
sc->mem[rid].kind = PCCARD_MEM_ATTR;
|
||||
sc->mem[rid].kind = flags;
|
||||
pccbb_pcic_do_mem_map(sc, rid);
|
||||
return 0;
|
||||
}
|
||||
@ -1496,93 +1695,32 @@ pccbb_pcic_set_memory_offset(device_t self, device_t child, int rid,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
/* POWER methods */
|
||||
/************************************************************************/
|
||||
|
||||
static int
|
||||
pccbb_pcic_enable_socket(device_t self, device_t child)
|
||||
pccbb_power_enable_socket(device_t self, device_t child)
|
||||
{
|
||||
struct pccbb_softc *sc = device_get_softc(self);
|
||||
|
||||
DPRINTF(("pccbb_pcic_socket_enable:\n"));
|
||||
|
||||
/* power down/up the socket to reset */
|
||||
{
|
||||
int voltage = pccbb_detect_voltage(sc);
|
||||
|
||||
pccbb_power(self, CARD_VCC_0V | CARD_VPP_0V);
|
||||
if (voltage & CARD_5V_CARD)
|
||||
pccbb_power(self, CARD_VCC_5V | CARD_VPP_VCC);
|
||||
else if (voltage & CARD_3V_CARD)
|
||||
pccbb_power(self, CARD_VCC_3V | CARD_VPP_VCC);
|
||||
else {
|
||||
device_printf(self, "Unknown card voltage\n");
|
||||
return ENXIO;
|
||||
}
|
||||
}
|
||||
|
||||
/* enable socket i/o */
|
||||
PCIC_MASK(sc, PCIC_PWRCTL, | PCIC_PWRCTL_OE);
|
||||
|
||||
PCIC_WRITE(sc, PCIC_INTR, PCIC_INTR_ENABLE);
|
||||
/* hold reset for 30ms */
|
||||
DELAY(30*1000);
|
||||
/* clear the reset flag */
|
||||
PCIC_MASK(sc, PCIC_INTR, | PCIC_INTR_RESET);
|
||||
/* wait 20ms as per pc card standard (r2.01) section 4.3.6 */
|
||||
DELAY(20*1000);
|
||||
|
||||
pccbb_pcic_wait_ready(sc);
|
||||
|
||||
/* disable all address windows */
|
||||
PCIC_WRITE(sc, PCIC_ADDRWIN_ENABLE, 0);
|
||||
|
||||
{
|
||||
int cardtype;
|
||||
CARD_GET_TYPE(child, &cardtype);
|
||||
PCIC_MASK(sc, PCIC_INTR, | ((cardtype == PCCARD_IFTYPE_IO) ?
|
||||
PCIC_INTR_CARDTYPE_IO :
|
||||
PCIC_INTR_CARDTYPE_MEM));
|
||||
DEVPRINTF((sc->sc_dev, "card type is %s\n",
|
||||
(cardtype == PCCARD_IFTYPE_IO) ? "io" : "mem"));
|
||||
}
|
||||
|
||||
/* reinstall all the memory and io mappings */
|
||||
{
|
||||
int win;
|
||||
|
||||
for (win = 0; win < PCIC_MEM_WINS; ++win) {
|
||||
if (sc->memalloc & (1 << win)) {
|
||||
pccbb_pcic_do_mem_map(sc, win);
|
||||
}
|
||||
}
|
||||
for (win = 0; win < PCIC_IO_WINS; ++win) {
|
||||
if (sc->ioalloc & (1 << win)) {
|
||||
pccbb_pcic_do_io_map(sc, win);
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
if (sc->sc_flags & PCCBB_16BIT_CARD)
|
||||
return pccbb_pcic_power_enable_socket(self, child);
|
||||
else
|
||||
return pccbb_cardbus_power_enable_socket(self, child);
|
||||
}
|
||||
|
||||
static void
|
||||
pccbb_pcic_disable_socket(device_t self, device_t child)
|
||||
pccbb_power_disable_socket(device_t self, device_t child)
|
||||
{
|
||||
struct pccbb_softc *sc = device_get_softc(self);
|
||||
|
||||
DPRINTF(("pccbb_pcic_socket_disable\n"));
|
||||
|
||||
/* reset signal asserting... */
|
||||
PCIC_MASK(sc, PCIC_INTR, & ~PCIC_INTR_RESET);
|
||||
DELAY(2*1000);
|
||||
|
||||
/* power down the socket */
|
||||
PCIC_MASK(sc, PCIC_PWRCTL, &~PCIC_PWRCTL_OE);
|
||||
pccbb_power(self, CARD_VCC_0V | CARD_VPP_0V);
|
||||
|
||||
/* wait 300ms until power fails (Tpf). */
|
||||
DELAY(300 * 1000);
|
||||
if (sc->sc_flags & PCCBB_16BIT_CARD)
|
||||
pccbb_pcic_power_disable_socket(self, child);
|
||||
else
|
||||
pccbb_cardbus_power_disable_socket(self, child);
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
/* Methods */
|
||||
/* BUS Methods */
|
||||
/************************************************************************/
|
||||
|
||||
|
||||
@ -1641,6 +1779,10 @@ pccbb_release_resource(device_t self, device_t child, int type, int rid,
|
||||
rid, r);
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
/* PCI compat methods */
|
||||
/************************************************************************/
|
||||
|
||||
static int
|
||||
pccbb_maxslots(device_t dev)
|
||||
{
|
||||
@ -1648,8 +1790,7 @@ pccbb_maxslots(device_t dev)
|
||||
}
|
||||
|
||||
static u_int32_t
|
||||
pccbb_read_config(device_t dev, int b, int s, int f,
|
||||
int reg, int width)
|
||||
pccbb_read_config(device_t dev, int b, int s, int f, int reg, int width)
|
||||
{
|
||||
/*
|
||||
* Pass through to the next ppb up the chain (i.e. our grandparent).
|
||||
@ -1659,8 +1800,8 @@ pccbb_read_config(device_t dev, int b, int s, int f,
|
||||
}
|
||||
|
||||
static void
|
||||
pccbb_write_config(device_t dev, int b, int s, int f,
|
||||
int reg, u_int32_t val, int width)
|
||||
pccbb_write_config(device_t dev, int b, int s, int f, int reg, u_int32_t val,
|
||||
int width)
|
||||
{
|
||||
/*
|
||||
* Pass through to the next ppb up the chain (i.e. our grandparent).
|
||||
@ -1673,8 +1814,7 @@ static device_method_t pccbb_methods[] = {
|
||||
/* Device interface */
|
||||
DEVMETHOD(device_probe, pccbb_probe),
|
||||
DEVMETHOD(device_attach, pccbb_attach),
|
||||
DEVMETHOD(device_detach, bus_generic_detach),
|
||||
DEVMETHOD(device_shutdown, bus_generic_shutdown),
|
||||
DEVMETHOD(device_detach, pccbb_detach),
|
||||
DEVMETHOD(device_suspend, bus_generic_suspend),
|
||||
DEVMETHOD(device_resume, bus_generic_resume),
|
||||
|
||||
@ -1684,24 +1824,23 @@ static device_method_t pccbb_methods[] = {
|
||||
DEVMETHOD(bus_release_resource, pccbb_release_resource),
|
||||
DEVMETHOD(bus_activate_resource, pccbb_activate_resource),
|
||||
DEVMETHOD(bus_deactivate_resource, pccbb_deactivate_resource),
|
||||
DEVMETHOD(bus_driver_added, pccbb_driver_added),
|
||||
DEVMETHOD(bus_child_detached, pccbb_child_detached),
|
||||
DEVMETHOD(bus_setup_intr, bus_generic_setup_intr),
|
||||
DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr),
|
||||
|
||||
/* 16-bit card interface */
|
||||
DEVMETHOD(card_set_res_flags, pccbb_pcic_set_res_flags),
|
||||
DEVMETHOD(card_set_memory_offset, pccbb_pcic_set_memory_offset),
|
||||
|
||||
/* power interface */
|
||||
DEVMETHOD(power_enable_socket, pccbb_power_enable_socket),
|
||||
DEVMETHOD(power_disable_socket, pccbb_power_disable_socket),
|
||||
|
||||
/* pcib compatibility interface */
|
||||
DEVMETHOD(pcib_maxslots, pccbb_maxslots),
|
||||
DEVMETHOD(pcib_read_config, pccbb_read_config),
|
||||
DEVMETHOD(pcib_write_config, pccbb_write_config),
|
||||
|
||||
DEVMETHOD(pccbb_power_socket, pccbb_power),
|
||||
DEVMETHOD(pccbb_detect_card, pccbb_cardbus_detect_card),
|
||||
DEVMETHOD(pccbb_reset, pccbb_cardbus_reset),
|
||||
|
||||
DEVMETHOD(card_set_res_flags, pccbb_pcic_set_res_flags),
|
||||
DEVMETHOD(card_set_memory_offset, pccbb_pcic_set_memory_offset),
|
||||
|
||||
DEVMETHOD(power_enable_socket, pccbb_pcic_enable_socket),
|
||||
DEVMETHOD(power_disable_socket, pccbb_pcic_disable_socket),
|
||||
|
||||
{0,0}
|
||||
};
|
||||
|
||||
@ -1710,9 +1849,9 @@ static driver_t pccbb_driver = {
|
||||
pccbb_methods,
|
||||
sizeof(struct pccbb_softc)
|
||||
};
|
||||
static devclass_t pccbb_devclass = {
|
||||
};
|
||||
|
||||
static devclass_t pccbb_devclass;
|
||||
|
||||
DRIVER_MODULE(pccbb, pci, pccbb_driver, pccbb_devclass, 0, 0);
|
||||
|
||||
|
||||
SYSINIT(pccbb, SI_SUB_KTHREAD_IDLE, SI_ORDER_ANY, pccbb_start_threads, 0);
|
||||
|
@ -1,69 +0,0 @@
|
||||
#
|
||||
# Copyright (c) 2000,2001 Jonathan Chen.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
# 1. Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions, and the following disclaimer,
|
||||
# without modification, immediately at the beginning of the file.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in
|
||||
# the documentation and/or other materials provided with the
|
||||
# distribution.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
|
||||
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
# SUCH DAMAGE.
|
||||
#
|
||||
# $FreeBSD$
|
||||
#
|
||||
|
||||
#include <sys/bus.h>
|
||||
|
||||
INTERFACE pccbb;
|
||||
|
||||
METHOD int power_socket {
|
||||
device_t dev;
|
||||
int command;
|
||||
};
|
||||
|
||||
METHOD int detect_card {
|
||||
device_t dev;
|
||||
};
|
||||
|
||||
METHOD int reset {
|
||||
device_t dev;
|
||||
};
|
||||
|
||||
HEADER {
|
||||
/* result of detect_card */
|
||||
#define CARD_UKN_CARD 0x00
|
||||
#define CARD_5V_CARD 0x01
|
||||
#define CARD_3V_CARD 0x02
|
||||
#define CARD_XV_CARD 0x04
|
||||
#define CARD_YV_CARD 0x08
|
||||
|
||||
/* for power_socket */
|
||||
#define CARD_VCC_UC 0x0000
|
||||
#define CARD_VCC_3V 0x0001
|
||||
#define CARD_VCC_XV 0x0002
|
||||
#define CARD_VCC_YV 0x0003
|
||||
#define CARD_VCC_0V 0x0004
|
||||
#define CARD_VCC_5V 0x0005
|
||||
#define CARD_VCCMASK 0x000f
|
||||
#define CARD_VPP_UC 0x0000
|
||||
#define CARD_VPP_VCC 0x0010
|
||||
#define CARD_VPP_12V 0x0030
|
||||
#define CARD_VPP_0V 0x0040
|
||||
#define CARD_VPPMASK 0x00f0
|
||||
};
|
@ -66,12 +66,13 @@ struct pccbb_softc {
|
||||
void *sc_intrhand;
|
||||
struct pccbb_socketreg *sc_socketreg;
|
||||
u_int32_t sc_flags;
|
||||
struct mtx sc_mtx;
|
||||
#define PCCBB_PCIC_IO_RELOC 0x01
|
||||
#define PCCBB_PCIC_MEM_32 0x02
|
||||
#define PCCBB_CARDSTATUS_BUSY 0x01000000
|
||||
#define PCCBB_CARDATTACHED 0x02000000
|
||||
#define PCCBB_16BIT_CARD 0x04000000
|
||||
#define PCCBB_INITIALCARD 0x08000000
|
||||
#define PCCBB_CARDATTACHED 0x01000000
|
||||
#define PCCBB_16BIT_CARD 0x02000000
|
||||
#define PCCBB_KTHREAD_RUNNING 0x04000000
|
||||
#define PCCBB_KTHREAD_DONE 0x08000000
|
||||
int sc_chipset; /* chipset id */
|
||||
#define CB_UNKNOWN 0 /* NOT Cardbus-PCI bridge */
|
||||
#define CB_TI113X 1 /* TI PCI1130/1131 */
|
||||
@ -97,9 +98,30 @@ struct pccbb_softc {
|
||||
struct proc *event_thread;
|
||||
};
|
||||
|
||||
/* result of detect_card */
|
||||
#define CARD_UKN_CARD 0x00
|
||||
#define CARD_5V_CARD 0x01
|
||||
#define CARD_3V_CARD 0x02
|
||||
#define CARD_XV_CARD 0x04
|
||||
#define CARD_YV_CARD 0x08
|
||||
|
||||
/* for power_socket */
|
||||
#define CARD_VCC_UC 0x0000
|
||||
#define CARD_VCC_3V 0x0001
|
||||
#define CARD_VCC_XV 0x0002
|
||||
#define CARD_VCC_YV 0x0003
|
||||
#define CARD_VCC_0V 0x0004
|
||||
#define CARD_VCC_5V 0x0005
|
||||
#define CARD_VCCMASK 0x000f
|
||||
#define CARD_VPP_UC 0x0000
|
||||
#define CARD_VPP_VCC 0x0010
|
||||
#define CARD_VPP_12V 0x0030
|
||||
#define CARD_VPP_0V 0x0040
|
||||
#define CARD_VPPMASK 0x00f0
|
||||
|
||||
/* XXX: rman is dumb */
|
||||
#define CARDBUS_SYS_RES_MEMORY_START 0x18020000
|
||||
#define CARDBUS_SYS_RES_MEMORY_END 0xEFFFFFFF
|
||||
#define CARDBUS_SYS_RES_IOPORT_START 0x2000
|
||||
#define CARDBUS_SYS_RES_IOPORT_START 0x3000
|
||||
#define CARDBUS_SYS_RES_IOPORT_END 0xEFFF
|
||||
|
||||
|
@ -1,9 +1,9 @@
|
||||
# $FreeBSD$
|
||||
|
||||
.PATH: ${.CURDIR}/../../dev/cardbus
|
||||
KMOD= cardbus
|
||||
SRCS= cardbus.c \
|
||||
device_if.h bus_if.h
|
||||
.PATH: ${.CURDIR}/../../dev/cardbus
|
||||
KMOD= cardbus
|
||||
SRCS= cardbus.c cardbus_cis.c \
|
||||
device_if.h bus_if.h card_if.h power_if.h pci_if.h pcib_if.h
|
||||
NOMAN=
|
||||
|
||||
.include <bsd.kmod.mk>
|
||||
|
8
sys/modules/pccbb/Makefile
Normal file
8
sys/modules/pccbb/Makefile
Normal file
@ -0,0 +1,8 @@
|
||||
# $FreeBSD$
|
||||
|
||||
.PATH: ${.CURDIR}/../../dev/pccbb
|
||||
KMOD= pccbb
|
||||
SRCS= pccbb.c \
|
||||
device_if.h bus_if.h power_if.h card_if.h pci_if.h pcib_if.h
|
||||
|
||||
.include <bsd.kmod.mk>
|
Loading…
Reference in New Issue
Block a user