mirror of
https://git.FreeBSD.org/src.git
synced 2025-01-20 15:43:16 +00:00
* Better kld support in pccbb/cardbus
- pccbb no longer needs to remember whether a card is inserted. - pccbb reissues insertion on load of cardbus/pccard modules. - got rid of unnecessary delays in power functions. - Cardbus children are no longer deleted if probe/attach fails. - non-attached child devices are reprobed at driver_added. * CARD interface to read CIS - added card_cis_read/card_cis_free interface to read arbitrary CIS data. This currently is only implemented in cardbus. * pccard begins to work - pccard can now use higher memory space (and uses it by default). - set_memory_offset interface changed. - fixed ccr access, which was broken at multiple locations. - implement an interrupt handler - pccard can now share interrupts. - resource alloc/release/activate/deactivate functions gutted: some resources are allocated by the bridge before the child device is probed or attached. Thus the resource "belongs" to the bridge, and the pccard_*_resource functions need to fudge the owner/rid. - changed some error conditions to panics to speed debugging. * Mutex fix - Giant is entered at the beginning of thread
This commit is contained in:
parent
41ed17bfec
commit
0c95c70577
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=70715
@ -190,8 +190,9 @@ cardbus_attach_card(device_t dev)
|
||||
static int curr_bus_number = 2; /* XXX EVILE BAD (see below) */
|
||||
int bus, slot, func;
|
||||
|
||||
POWER_ENABLE_SOCKET(bdev, dev);
|
||||
cardbus_detach_card(dev, DETACH_NOWARN); /* detach existing cards */
|
||||
|
||||
POWER_ENABLE_SOCKET(bdev, dev);
|
||||
bus = pcib_get_bus(dev);
|
||||
if (bus == 0) {
|
||||
/*
|
||||
@ -205,7 +206,6 @@ cardbus_attach_card(device_t dev)
|
||||
pci_write_config (bdev, PCIR_SUBBUS_2, curr_bus_number+2, 1);
|
||||
curr_bus_number += 3;
|
||||
}
|
||||
|
||||
for (slot = 0; slot <= CARDBUS_SLOTMAX; slot++) {
|
||||
int cardbusfunchigh = 0;
|
||||
for (func = 0; func <= cardbusfunchigh; func++) {
|
||||
@ -230,8 +230,6 @@ cardbus_attach_card(device_t dev)
|
||||
if (device_probe_and_attach(dinfo->cfg.dev) != 0) {
|
||||
cardbus_release_all_resources(dinfo->cfg.dev,
|
||||
&dinfo->resources);
|
||||
device_delete_child(dev, dinfo->cfg.dev);
|
||||
cardbus_freecfg(dinfo);
|
||||
} else
|
||||
cardattached++;
|
||||
}
|
||||
@ -253,20 +251,30 @@ cardbus_detach_card(device_t dev, int flags)
|
||||
device_get_children(dev, &devlist, &numdevs);
|
||||
|
||||
if (numdevs == 0) {
|
||||
DEVPRINTF((dev, "Detaching card: no cards to detach!\n"));
|
||||
POWER_DISABLE_SOCKET(device_get_parent(dev), dev);
|
||||
if (!(flags & DETACH_NOWARN)) {
|
||||
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 || flags & DETACH_FORCE){
|
||||
cardbus_release_all_resources(dinfo->cfg.dev,
|
||||
&dinfo->resources);
|
||||
int status = device_get_state(devlist[tmp]);
|
||||
|
||||
if (status == DS_ATTACHED || status == DS_BUSY) {
|
||||
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);
|
||||
} else {
|
||||
device_delete_child(dev, devlist[tmp]);
|
||||
} else
|
||||
err++;
|
||||
cardbus_freecfg(dinfo);
|
||||
}
|
||||
}
|
||||
if (err == 0)
|
||||
POWER_DISABLE_SOCKET(device_get_parent(dev), dev);
|
||||
@ -276,19 +284,39 @@ cardbus_detach_card(device_t dev, int flags)
|
||||
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");
|
||||
int numdevs;
|
||||
device_t *devlist;
|
||||
device_t bdev = device_get_parent(dev);
|
||||
int tmp, cardattached;
|
||||
|
||||
device_get_children(dev, &devlist, &numdevs);
|
||||
|
||||
cardattached = 0;
|
||||
for (tmp = 0; tmp < numdevs; tmp++) {
|
||||
if (device_get_state(devlist[tmp]) != DS_NOTPRESENT)
|
||||
cardattached++;
|
||||
}
|
||||
|
||||
if (cardattached == 0)
|
||||
POWER_ENABLE_SOCKET(bdev, dev);
|
||||
DEVICE_IDENTIFY(driver, dev);
|
||||
for (tmp = 0; tmp < numdevs; tmp++) {
|
||||
if (device_get_state(devlist[tmp]) == DS_NOTPRESENT){
|
||||
struct cardbus_devinfo *dinfo;
|
||||
dinfo = device_get_ivars(devlist[tmp]);
|
||||
resource_list_init(&dinfo->resources);
|
||||
cardbus_add_resources(dinfo->cfg.dev, &dinfo->cfg);
|
||||
cardbus_do_cis(dev, dinfo->cfg.dev);
|
||||
if (device_probe_and_attach(dinfo->cfg.dev) != 0) {
|
||||
cardbus_release_all_resources(dinfo->cfg.dev,
|
||||
&dinfo->resources);
|
||||
} else
|
||||
cardattached++;
|
||||
}
|
||||
}
|
||||
|
||||
if (cardattached == 0)
|
||||
POWER_DISABLE_SOCKET(bdev, dev);
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
@ -344,7 +372,7 @@ cardbus_read_device(device_t pcib, int b, int s, int f)
|
||||
cfg->intline = airq;
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
/*
|
||||
* PCI interrupts might be redirected to the
|
||||
* ISA bus according to some MP tables. Use the
|
||||
* same methods as used by the ISA devices
|
||||
@ -655,7 +683,7 @@ cardbus_alloc_resource(device_t self, device_t child, int type,
|
||||
rle = resource_list_find(rl, type, *rid);
|
||||
if (rle) {
|
||||
if (flags & RF_ACTIVE) {
|
||||
if (bus_activate_resource(child, type, *rid,
|
||||
if (bus_activate_resource(child, rle->type, *rid,
|
||||
rle->res)) {
|
||||
return NULL;
|
||||
}
|
||||
@ -930,6 +958,8 @@ static device_method_t cardbus_methods[] = {
|
||||
/* Card Interface */
|
||||
DEVMETHOD(card_attach_card, cardbus_attach_card),
|
||||
DEVMETHOD(card_detach_card, cardbus_detach_card),
|
||||
DEVMETHOD(card_cis_read, cardbus_cis_read),
|
||||
DEVMETHOD(card_cis_free, cardbus_cis_free),
|
||||
|
||||
/* Cardbus/PCI interface */
|
||||
DEVMETHOD(pci_read_config, cardbus_read_config_method),
|
||||
@ -947,4 +977,6 @@ static driver_t cardbus_driver = {
|
||||
static devclass_t cardbus_devclass;
|
||||
|
||||
DRIVER_MODULE(cardbus, pccbb, cardbus_driver, cardbus_devclass, 0, 0);
|
||||
/*
|
||||
MODULE_DEPEND(cardbus, pccbb, 1, 1, 1);
|
||||
*/
|
||||
|
@ -37,6 +37,7 @@
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/malloc.h>
|
||||
|
||||
#include <sys/bus.h>
|
||||
#include <machine/bus.h>
|
||||
@ -48,6 +49,8 @@
|
||||
#include <dev/cardbus/cardbusreg.h>
|
||||
#include <dev/cardbus/cardbus_cis.h>
|
||||
|
||||
#include "card_if.h"
|
||||
|
||||
#if defined CARDBUS_DEBUG
|
||||
#define STATIC
|
||||
#define DPRINTF(a) printf a
|
||||
@ -63,7 +66,7 @@ static const char rcsid[] =
|
||||
"$FreeBSD$";
|
||||
#endif
|
||||
|
||||
struct tupleinfo;
|
||||
struct tuple_callbacks;
|
||||
|
||||
static int cardbus_read_tuple_conf(device_t dev, device_t child,
|
||||
u_int32_t *start, u_int32_t *off,
|
||||
@ -78,13 +81,19 @@ static int cardbus_read_tuple(device_t dev, device_t child, u_int32_t *start,
|
||||
u_int32_t *off, int *tupleid, int *len,
|
||||
u_int8_t *tupledata);
|
||||
static int decode_tuple(device_t dev, device_t child, int tupleid, int len,
|
||||
u_int8_t *tupledata, u_int32_t *start, u_int32_t *off);
|
||||
u_int8_t *tupledata, u_int32_t *start, u_int32_t *off,
|
||||
struct tuple_callbacks *callbacks);
|
||||
static int cardbus_parse_cis(device_t dev, device_t child,
|
||||
struct tuple_callbacks *callbacks);
|
||||
|
||||
#define DECODE_PROTOTYPE(NAME) static int decode_tuple_ ## NAME \
|
||||
#define DECODE_PARAMS \
|
||||
(device_t dev, device_t child, int id, int len, \
|
||||
u_int8_t *tupledata, u_int32_t *start, u_int32_t *off, \
|
||||
struct tupleinfo *info)
|
||||
struct tuple_callbacks *info)
|
||||
#define DECODE_PROTOTYPE(NAME) static int decode_tuple_ ## NAME DECODE_PARAMS
|
||||
DECODE_PROTOTYPE(generic);
|
||||
DECODE_PROTOTYPE(nothing);
|
||||
DECODE_PROTOTYPE(copy);
|
||||
DECODE_PROTOTYPE(bar);
|
||||
DECODE_PROTOTYPE(linktarget);
|
||||
DECODE_PROTOTYPE(vers_1);
|
||||
@ -94,54 +103,12 @@ DECODE_PROTOTYPE(funce);
|
||||
DECODE_PROTOTYPE(end);
|
||||
DECODE_PROTOTYPE(unhandled);
|
||||
|
||||
static struct tupleinfo {
|
||||
u_int8_t id;
|
||||
struct tuple_callbacks {
|
||||
int id;
|
||||
char* name;
|
||||
int (*func)(device_t dev, device_t child, int id, int len,
|
||||
u_int8_t *tupledata, u_int32_t *start, u_int32_t *off,
|
||||
struct tupleinfo *info);
|
||||
} tupleinfo[] = {
|
||||
#define MAKETUPLE(NAME,FUNC) { CISTPL_ ## NAME, #NAME, decode_tuple_ ## FUNC }
|
||||
MAKETUPLE(NULL, generic),
|
||||
MAKETUPLE(DEVICE, generic),
|
||||
MAKETUPLE(LONG_LINK_CB, unhandled),
|
||||
MAKETUPLE(INDIRECT, unhandled),
|
||||
MAKETUPLE(CONFIG_CB, generic),
|
||||
MAKETUPLE(CFTABLE_ENTRY_CB, generic),
|
||||
MAKETUPLE(LONGLINK_MFC, unhandled),
|
||||
MAKETUPLE(BAR, bar),
|
||||
MAKETUPLE(PWR_MGMNT, generic),
|
||||
MAKETUPLE(EXTDEVICE, generic),
|
||||
MAKETUPLE(CHECKSUM, generic),
|
||||
MAKETUPLE(LONGLINK_A, unhandled),
|
||||
MAKETUPLE(LONGLINK_C, unhandled),
|
||||
MAKETUPLE(LINKTARGET, linktarget),
|
||||
MAKETUPLE(NO_LINK, generic),
|
||||
MAKETUPLE(VERS_1, vers_1),
|
||||
MAKETUPLE(ALTSTR, generic),
|
||||
MAKETUPLE(DEVICE_A, generic),
|
||||
MAKETUPLE(JEDEC_C, generic),
|
||||
MAKETUPLE(JEDEC_A, generic),
|
||||
MAKETUPLE(CONFIG, generic),
|
||||
MAKETUPLE(CFTABLE_ENTRY, generic),
|
||||
MAKETUPLE(DEVICE_OC, generic),
|
||||
MAKETUPLE(DEVICE_OA, generic),
|
||||
MAKETUPLE(DEVICE_GEO, generic),
|
||||
MAKETUPLE(DEVICE_GEO_A, generic),
|
||||
MAKETUPLE(MANFID, manfid),
|
||||
MAKETUPLE(FUNCID, funcid),
|
||||
MAKETUPLE(FUNCE, funce),
|
||||
MAKETUPLE(SWIL, generic),
|
||||
MAKETUPLE(VERS_2, generic),
|
||||
MAKETUPLE(FORMAT, generic),
|
||||
MAKETUPLE(GEOMETRY, generic),
|
||||
MAKETUPLE(BYTEORDER, generic),
|
||||
MAKETUPLE(DATE, generic),
|
||||
MAKETUPLE(BATTERY, generic),
|
||||
MAKETUPLE(ORG, generic),
|
||||
MAKETUPLE(END, end),
|
||||
#undef MAKETUPLE
|
||||
int (*func) DECODE_PARAMS;
|
||||
};
|
||||
#define MAKETUPLE(NAME,FUNC) { CISTPL_ ## NAME, #NAME, decode_tuple_ ## FUNC }
|
||||
|
||||
static char* funcnames[] = {
|
||||
"Multi-Functioned",
|
||||
@ -156,6 +123,9 @@ static char* funcnames[] = {
|
||||
"Security"
|
||||
};
|
||||
|
||||
static struct cis_tupleinfo* cisread_buf;
|
||||
static int ncisread_buf;
|
||||
|
||||
DECODE_PROTOTYPE(generic)
|
||||
{
|
||||
#ifdef CARDBUS_DEBUG
|
||||
@ -176,6 +146,32 @@ DECODE_PROTOTYPE(generic)
|
||||
return 0;
|
||||
}
|
||||
|
||||
DECODE_PROTOTYPE(nothing)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
DECODE_PROTOTYPE(copy)
|
||||
{
|
||||
struct cis_tupleinfo* tmpbuf;
|
||||
|
||||
tmpbuf = malloc(sizeof(struct cis_tupleinfo)*(ncisread_buf+1),
|
||||
M_DEVBUF, M_WAITOK);
|
||||
if (ncisread_buf > 0) {
|
||||
memcpy(tmpbuf, cisread_buf,
|
||||
sizeof(struct cis_tupleinfo)*ncisread_buf);
|
||||
free(cisread_buf, M_DEVBUF);
|
||||
}
|
||||
cisread_buf = tmpbuf;
|
||||
|
||||
cisread_buf[ncisread_buf].id = id;
|
||||
cisread_buf[ncisread_buf].len = len;
|
||||
cisread_buf[ncisread_buf].data = malloc(len, M_DEVBUF, M_WAITOK);
|
||||
memcpy (cisread_buf[ncisread_buf].data, tupledata, len);
|
||||
ncisread_buf++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
DECODE_PROTOTYPE(linktarget)
|
||||
{
|
||||
#ifdef CARDBUS_DEBUG
|
||||
@ -277,7 +273,7 @@ DECODE_PROTOTYPE(bar)
|
||||
if (bar < 0 || bar > 5 || (type == SYS_RES_IOPORT && bar == 5)) {
|
||||
device_printf(dev, "Invalid BAR number: %02x(%02x)\n",
|
||||
reg, bar);
|
||||
return EINVAL;
|
||||
return 0;
|
||||
}
|
||||
bar = CARDBUS_BASE0_REG + bar * 4;
|
||||
DEVPRINTF((dev, "Opening BAR: type=%s, bar=%02x, len=%04x\n",
|
||||
@ -299,6 +295,7 @@ DECODE_PROTOTYPE(unhandled)
|
||||
|
||||
DECODE_PROTOTYPE(end)
|
||||
{
|
||||
printf("CIS reading done\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -451,27 +448,29 @@ cardbus_read_tuple(device_t dev, device_t child, u_int32_t *start,
|
||||
|
||||
static int
|
||||
decode_tuple(device_t dev, device_t child, int tupleid, int len,
|
||||
u_int8_t *tupledata, u_int32_t *start, u_int32_t *off)
|
||||
u_int8_t *tupledata, u_int32_t *start, u_int32_t *off,
|
||||
struct tuple_callbacks *callbacks)
|
||||
{
|
||||
int i;
|
||||
int numtupleids = sizeof(tupleinfo)/sizeof(tupleinfo[0]);
|
||||
for (i = 0; i < numtupleids; i++) {
|
||||
if (tupleid == tupleinfo[i].id)
|
||||
return tupleinfo[i].func(dev, child, tupleid, len,
|
||||
for (i = 0; callbacks[i].id != CISTPL_GENERIC; i++) {
|
||||
if (tupleid == callbacks[i].id)
|
||||
return callbacks[i].func(dev, child, tupleid, len,
|
||||
tupledata, start, off,
|
||||
&tupleinfo[i]);
|
||||
&callbacks[i]);
|
||||
}
|
||||
|
||||
if (tupleid < CISTPL_CUSTOMSTART) {
|
||||
device_printf(dev, "Undefined tuple encountered, CIS parsing terminated\n");
|
||||
return EINVAL;
|
||||
}
|
||||
return decode_tuple_generic(dev, child, tupleid, len, tupledata,
|
||||
start, off, NULL);
|
||||
return callbacks[i].func(dev, child, tupleid, len,
|
||||
tupledata, start, off,
|
||||
NULL);
|
||||
}
|
||||
|
||||
int
|
||||
cardbus_do_cis(device_t dev, device_t child)
|
||||
static int
|
||||
cardbus_parse_cis(device_t dev, device_t child,
|
||||
struct tuple_callbacks *callbacks)
|
||||
{
|
||||
u_int8_t tupledata[MAXTUPLESIZE];
|
||||
int tupleid;
|
||||
@ -493,10 +492,128 @@ cardbus_do_cis(device_t dev, device_t child)
|
||||
return EINVAL;
|
||||
}
|
||||
expect_linktarget = decode_tuple(dev, child, tupleid, len,
|
||||
tupledata, &start, &off);
|
||||
tupledata, &start, &off,
|
||||
callbacks);
|
||||
if (expect_linktarget != 0)
|
||||
return expect_linktarget;
|
||||
} while (tupleid != CISTPL_END);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
cardbus_cis_read(device_t dev, device_t child, u_int8_t id,
|
||||
struct cis_tupleinfo** buff, int* nret)
|
||||
{
|
||||
struct tuple_callbacks cisread_callbacks[] = {
|
||||
MAKETUPLE(NULL, nothing),
|
||||
/* first entry will be overwritten */
|
||||
MAKETUPLE(NULL, nothing),
|
||||
MAKETUPLE(DEVICE, nothing),
|
||||
MAKETUPLE(LONG_LINK_CB, unhandled),
|
||||
MAKETUPLE(INDIRECT, unhandled),
|
||||
MAKETUPLE(CONFIG_CB, nothing),
|
||||
MAKETUPLE(CFTABLE_ENTRY_CB, nothing),
|
||||
MAKETUPLE(LONGLINK_MFC, unhandled),
|
||||
MAKETUPLE(BAR, nothing),
|
||||
MAKETUPLE(PWR_MGMNT, nothing),
|
||||
MAKETUPLE(EXTDEVICE, nothing),
|
||||
MAKETUPLE(CHECKSUM, nothing),
|
||||
MAKETUPLE(LONGLINK_A, unhandled),
|
||||
MAKETUPLE(LONGLINK_C, unhandled),
|
||||
MAKETUPLE(LINKTARGET, nothing),
|
||||
MAKETUPLE(NO_LINK, nothing),
|
||||
MAKETUPLE(VERS_1, nothing),
|
||||
MAKETUPLE(ALTSTR, nothing),
|
||||
MAKETUPLE(DEVICE_A, nothing),
|
||||
MAKETUPLE(JEDEC_C, nothing),
|
||||
MAKETUPLE(JEDEC_A, nothing),
|
||||
MAKETUPLE(CONFIG, nothing),
|
||||
MAKETUPLE(CFTABLE_ENTRY, nothing),
|
||||
MAKETUPLE(DEVICE_OC, nothing),
|
||||
MAKETUPLE(DEVICE_OA, nothing),
|
||||
MAKETUPLE(DEVICE_GEO, nothing),
|
||||
MAKETUPLE(DEVICE_GEO_A, nothing),
|
||||
MAKETUPLE(MANFID, nothing),
|
||||
MAKETUPLE(FUNCID, nothing),
|
||||
MAKETUPLE(FUNCE, nothing),
|
||||
MAKETUPLE(SWIL, nothing),
|
||||
MAKETUPLE(VERS_2, nothing),
|
||||
MAKETUPLE(FORMAT, nothing),
|
||||
MAKETUPLE(GEOMETRY, nothing),
|
||||
MAKETUPLE(BYTEORDER, nothing),
|
||||
MAKETUPLE(DATE, nothing),
|
||||
MAKETUPLE(BATTERY, nothing),
|
||||
MAKETUPLE(ORG, nothing),
|
||||
MAKETUPLE(END, end),
|
||||
MAKETUPLE(GENERIC, nothing),
|
||||
};
|
||||
int ret;
|
||||
|
||||
cisread_callbacks[0].id = id;
|
||||
cisread_callbacks[0].name = "COPY";
|
||||
cisread_callbacks[0].func = decode_tuple_copy;
|
||||
ncisread_buf = 0;
|
||||
cisread_buf = NULL;
|
||||
ret = cardbus_parse_cis(dev, child, cisread_callbacks);
|
||||
|
||||
*buff = cisread_buf;
|
||||
*nret = ncisread_buf;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
cardbus_cis_free(device_t dev, struct cis_tupleinfo *buff, int* nret)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < nret; i++)
|
||||
free(buff[i].data, M_DEVBUF);
|
||||
if (nret > 0)
|
||||
free(buff, M_DEVBUF);
|
||||
}
|
||||
|
||||
int
|
||||
cardbus_do_cis(device_t dev, device_t child)
|
||||
{
|
||||
struct tuple_callbacks init_callbacks[] = {
|
||||
MAKETUPLE(NULL, generic),
|
||||
MAKETUPLE(DEVICE, generic),
|
||||
MAKETUPLE(LONG_LINK_CB, unhandled),
|
||||
MAKETUPLE(INDIRECT, unhandled),
|
||||
MAKETUPLE(CONFIG_CB, generic),
|
||||
MAKETUPLE(CFTABLE_ENTRY_CB, generic),
|
||||
MAKETUPLE(LONGLINK_MFC, unhandled),
|
||||
MAKETUPLE(BAR, bar),
|
||||
MAKETUPLE(PWR_MGMNT, generic),
|
||||
MAKETUPLE(EXTDEVICE, generic),
|
||||
MAKETUPLE(CHECKSUM, generic),
|
||||
MAKETUPLE(LONGLINK_A, unhandled),
|
||||
MAKETUPLE(LONGLINK_C, unhandled),
|
||||
MAKETUPLE(LINKTARGET, linktarget),
|
||||
MAKETUPLE(NO_LINK, generic),
|
||||
MAKETUPLE(VERS_1, vers_1),
|
||||
MAKETUPLE(ALTSTR, generic),
|
||||
MAKETUPLE(DEVICE_A, generic),
|
||||
MAKETUPLE(JEDEC_C, generic),
|
||||
MAKETUPLE(JEDEC_A, generic),
|
||||
MAKETUPLE(CONFIG, generic),
|
||||
MAKETUPLE(CFTABLE_ENTRY, generic),
|
||||
MAKETUPLE(DEVICE_OC, generic),
|
||||
MAKETUPLE(DEVICE_OA, generic),
|
||||
MAKETUPLE(DEVICE_GEO, generic),
|
||||
MAKETUPLE(DEVICE_GEO_A, generic),
|
||||
MAKETUPLE(MANFID, manfid),
|
||||
MAKETUPLE(FUNCID, funcid),
|
||||
MAKETUPLE(FUNCE, funce),
|
||||
MAKETUPLE(SWIL, generic),
|
||||
MAKETUPLE(VERS_2, generic),
|
||||
MAKETUPLE(FORMAT, generic),
|
||||
MAKETUPLE(GEOMETRY, generic),
|
||||
MAKETUPLE(BYTEORDER, generic),
|
||||
MAKETUPLE(DATE, generic),
|
||||
MAKETUPLE(BATTERY, generic),
|
||||
MAKETUPLE(ORG, generic),
|
||||
MAKETUPLE(END, end),
|
||||
MAKETUPLE(GENERIC, generic),
|
||||
};
|
||||
return cardbus_parse_cis(dev, child, init_callbacks);
|
||||
}
|
||||
|
@ -32,7 +32,12 @@
|
||||
* Cardbus CIS definitions
|
||||
*/
|
||||
|
||||
struct cis_tupleinfo;
|
||||
|
||||
int cardbus_do_cis(device_t dev, device_t child);
|
||||
int cardbus_cis_read(device_t dev, device_t child, u_int8_t id,
|
||||
struct cis_tupleinfo** buff, int* nret);
|
||||
void cardbus_cis_free(device_t dev, struct cis_tupleinfo *buff, int* nret);
|
||||
|
||||
#define MAXTUPLESIZE 0x400
|
||||
|
||||
@ -78,6 +83,8 @@ int cardbus_do_cis(device_t dev, device_t child);
|
||||
#define CISTPL_CUSTOMSTART 0x80
|
||||
#define CISTPL_END 0xFF
|
||||
|
||||
#define CISTPL_GENERIC -1 /* catchall */
|
||||
|
||||
/* BAR */
|
||||
#define TPL_BAR_REG_ASI_MASK 0x07
|
||||
#define TPL_BAR_REG_AS 0x10
|
||||
|
@ -63,7 +63,8 @@ METHOD int set_memory_offset {
|
||||
device_t dev;
|
||||
device_t child;
|
||||
int rid;
|
||||
u_int32_t offset;
|
||||
u_int32_t cardaddr;
|
||||
u_int32_t *offsetp;
|
||||
}
|
||||
|
||||
METHOD int get_memory_offset {
|
||||
@ -90,6 +91,7 @@ METHOD int detach_card {
|
||||
|
||||
HEADER {
|
||||
#define DETACH_FORCE 0x01
|
||||
#define DETACH_NOWARN 0x02
|
||||
}
|
||||
|
||||
#
|
||||
@ -163,3 +165,53 @@ METHOD int compat_attach {
|
||||
METHOD int compat_match {
|
||||
device_t dev;
|
||||
}
|
||||
|
||||
#
|
||||
# Method for devices to ask its CIS-enabled parent bus for CIS info.
|
||||
# Device driver requests all tuples if type 'id', the routine places
|
||||
# 'nret' number of tuples in 'buff'. Returns 0 if all tuples processed,
|
||||
# or an error code if processing was aborted.
|
||||
# Users of this method will be responsible for freeing the memory allocated
|
||||
# by calling the cis_free method.
|
||||
#
|
||||
|
||||
HEADER {
|
||||
struct cis_tupleinfo {
|
||||
u_int8_t id;
|
||||
int len;
|
||||
char* data;
|
||||
};
|
||||
};
|
||||
|
||||
CODE {
|
||||
static int
|
||||
null_cis_read(device_t dev, device_t child, u_int8_t id,
|
||||
struct cis_tupleinfo **buff, int* nret)
|
||||
{
|
||||
*nret = 0;
|
||||
*buff = NULL;
|
||||
return ENXIO;
|
||||
}
|
||||
static void
|
||||
null_cis_free(device_t dev, struct cis_tupleinfo *buff, int* nret)
|
||||
{
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
METHOD int cis_read {
|
||||
device_t dev;
|
||||
device_t child;
|
||||
u_int8_t id;
|
||||
struct cis_tupleinfo **buff;
|
||||
int* nret;
|
||||
} DEFAULT null_cis_read;
|
||||
|
||||
METHOD int cis_free {
|
||||
device_t dev;
|
||||
struct cis_tupleinfo *buff;
|
||||
int nret;
|
||||
} DEFAULT null_cis_free;
|
||||
|
||||
|
||||
|
@ -103,6 +103,7 @@ pccard_attach_card(device_t dev)
|
||||
device_t child;
|
||||
int attached;
|
||||
|
||||
sc->intr_handler_count = 0;
|
||||
/*
|
||||
* this is here so that when socket_enable calls gettype, trt happens
|
||||
*/
|
||||
@ -122,10 +123,14 @@ pccard_attach_card(device_t dev)
|
||||
* the cis.
|
||||
*/
|
||||
|
||||
if (sc->card.error)
|
||||
if (sc->card.error) {
|
||||
device_printf (dev, "CARD ERROR!\n");
|
||||
return (1);
|
||||
if (STAILQ_EMPTY(&sc->card.pf_head))
|
||||
}
|
||||
if (STAILQ_EMPTY(&sc->card.pf_head)) {
|
||||
device_printf (dev, "Card has no functions!\n");
|
||||
return (1);
|
||||
}
|
||||
|
||||
if (1)
|
||||
pccard_print_cis(dev);
|
||||
@ -228,7 +233,7 @@ pccard_product_lookup(device_t dev, const struct pccard_product *tab,
|
||||
|
||||
#ifdef DIAGNOSTIC
|
||||
if (sizeof *ent > ent_size)
|
||||
panic("pccard_product_lookup: bogus ent_size %ld",
|
||||
panic("pccard_product_lookup: bogus ent_size %ld",
|
||||
(long) ent_size);
|
||||
#endif
|
||||
if (pccard_get_vendor(dev, &vendor))
|
||||
@ -241,7 +246,7 @@ pccard_product_lookup(device_t dev, const struct pccard_product *tab,
|
||||
return (NULL);
|
||||
if (pccard_get_product_str(dev, &prodstr))
|
||||
return (NULL);
|
||||
for (ent = tab; ent->pp_name != NULL;
|
||||
for (ent = tab; ent->pp_name != NULL;
|
||||
ent = (const struct pccard_product *)
|
||||
((const char *) ent + ent_size)) {
|
||||
matches = 1;
|
||||
@ -253,10 +258,10 @@ pccard_product_lookup(device_t dev, const struct pccard_product *tab,
|
||||
matches = 0;
|
||||
if (matches && fcn != ent->pp_expfunc)
|
||||
matches = 0;
|
||||
if (matches && ent->pp_vendor_str &&
|
||||
if (matches && ent->pp_vendor_str &&
|
||||
strcmp(ent->pp_vendor_str, vendorstr) != 0)
|
||||
matches = 0;
|
||||
if (matches && ent->pp_product_str &&
|
||||
if (matches && ent->pp_product_str &&
|
||||
strcmp(ent->pp_product_str, prodstr) != 0)
|
||||
matches = 0;
|
||||
if (matchfn != NULL)
|
||||
@ -267,7 +272,7 @@ pccard_product_lookup(device_t dev, const struct pccard_product *tab,
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static int
|
||||
static int
|
||||
pccard_card_gettype(device_t dev, int *type)
|
||||
{
|
||||
struct pccard_softc *sc = PCCARD_SOFTC(dev);
|
||||
@ -293,7 +298,7 @@ pccard_card_gettype(device_t dev, int *type)
|
||||
* disabled.
|
||||
*/
|
||||
void
|
||||
pccard_function_init(struct pccard_function *pf)
|
||||
pccard_function_init(struct pccard_function *pf)
|
||||
{
|
||||
struct pccard_config_entry *cfe;
|
||||
int i;
|
||||
@ -304,9 +309,10 @@ pccard_function_init(struct pccard_function *pf)
|
||||
int start;
|
||||
int end;
|
||||
|
||||
if (pf->pf_flags & PFF_ENABLED)
|
||||
panic("pccard_function_init: function is enabled");
|
||||
|
||||
if (pf->pf_flags & PFF_ENABLED) {
|
||||
printf("pccard_function_init: function is enabled");
|
||||
return;
|
||||
}
|
||||
bus = device_get_parent(pf->dev);
|
||||
/* Remember which configuration entry we are using. */
|
||||
for (cfe = STAILQ_FIRST(&pf->cfe_head); cfe != NULL;
|
||||
@ -323,13 +329,17 @@ pccard_function_init(struct pccard_function *pf)
|
||||
cfe->iorid[i] = i;
|
||||
r = cfe->iores[i] = bus_alloc_resource(bus,
|
||||
SYS_RES_IOPORT, &cfe->iorid[i], start, end,
|
||||
cfe->iospace[i].length,
|
||||
cfe->iospace[i].length,
|
||||
rman_make_alignment_flags(cfe->iospace[i].length));
|
||||
if (cfe->iores[i] == 0)
|
||||
goto not_this_one;
|
||||
resource_list_add(rl, SYS_RES_IOPORT, cfe->iorid[i],
|
||||
rman_get_start(r), rman_get_end(r),
|
||||
cfe->iospace[i].length);
|
||||
{
|
||||
struct resource_list_entry *rle = resource_list_find(rl, SYS_RES_IOPORT, cfe->iorid[i]);
|
||||
rle->res = r;
|
||||
}
|
||||
}
|
||||
if (cfe->num_memspace > 0) {
|
||||
goto not_this_one;
|
||||
@ -342,6 +352,10 @@ pccard_function_init(struct pccard_function *pf)
|
||||
goto not_this_one;
|
||||
resource_list_add(rl, SYS_RES_IRQ, cfe->irqrid,
|
||||
rman_get_start(r), rman_get_end(r), 1);
|
||||
{
|
||||
struct resource_list_entry *rle = resource_list_find(rl, SYS_RES_IRQ, cfe->irqrid);
|
||||
rle->res = r;
|
||||
}
|
||||
}
|
||||
/* XXX Don't know how to deal with maxtwins */
|
||||
/* If we get to here, we've allocated all we need */
|
||||
@ -357,7 +371,7 @@ pccard_function_init(struct pccard_function *pf)
|
||||
for (i = 0; i < cfe->num_iospace; i++) {
|
||||
resource_list_delete(rl, SYS_RES_IOPORT, i);
|
||||
if (cfe->iores[i])
|
||||
bus_release_resource(bus, SYS_RES_IOPORT,
|
||||
bus_release_resource(bus, SYS_RES_IOPORT,
|
||||
cfe->iorid[i], cfe->iores[i]);
|
||||
cfe->iores[i] = NULL;
|
||||
}
|
||||
@ -377,7 +391,6 @@ pccard_function_enable(struct pccard_function *pf)
|
||||
struct pccard_function *tmp;
|
||||
int reg;
|
||||
device_t dev = pf->sc->dev;
|
||||
|
||||
if (pf->cfe == NULL) {
|
||||
DEVPRVERBOSE((dev, "No config entry could be allocated.\n"));
|
||||
return ENOMEM;
|
||||
@ -416,29 +429,27 @@ pccard_function_enable(struct pccard_function *pf)
|
||||
* pf->pf_ccr_offset = (tmp->pf_ccr_offset -
|
||||
* tmp->ccr_base) + pf->ccr_base;
|
||||
*/
|
||||
pf->pf_ccr_offset =
|
||||
/* pf->pf_ccr_offset =
|
||||
(tmp->pf_ccr_offset + pf->ccr_base) -
|
||||
tmp->ccr_base;
|
||||
tmp->ccr_base; */
|
||||
pf->pf_ccr_window = tmp->pf_ccr_window;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (tmp == NULL) {
|
||||
pf->ccr_rid = 0;
|
||||
pf->ccr_res = bus_alloc_resource(dev, SYS_RES_MEMORY,
|
||||
&pf->ccr_rid, 0xa0000, 0xdffff, 1 << 10, RF_ACTIVE);
|
||||
if (!pf->ccr_res) {
|
||||
DEVPRINTF((dev, "ccr_res == 0\n"));
|
||||
&pf->ccr_rid, 0, ~0, 1 << 10, RF_ACTIVE);
|
||||
if (!pf->ccr_res)
|
||||
goto bad;
|
||||
}
|
||||
DEVPRINTF((dev, "ccr_res == %lx-%lx, base=%lx\n", rman_get_start(pf->ccr_res), rman_get_end(pf->ccr_res), pf->ccr_base));
|
||||
CARD_SET_RES_FLAGS(device_get_parent(dev), dev, SYS_RES_MEMORY,
|
||||
pf->ccr_rid, PCCARD_A_MEM_ATTR);
|
||||
CARD_SET_MEMORY_OFFSET(device_get_parent(dev), dev,
|
||||
pf->ccr_rid, (pf->ccr_rid >> 10) << 10);
|
||||
CARD_SET_MEMORY_OFFSET(device_get_parent(dev), dev,
|
||||
pf->ccr_rid, pf->ccr_base,
|
||||
&pf->pf_ccr_offset);
|
||||
pf->pf_ccrt = rman_get_bustag(pf->ccr_res);
|
||||
pf->pf_ccrh = rman_get_bushandle(pf->ccr_res);
|
||||
pf->pf_ccr_offset = rman_get_start(pf->ccr_res);
|
||||
pf->pf_ccr_realsize = 1;
|
||||
}
|
||||
|
||||
@ -447,12 +458,12 @@ pccard_function_enable(struct pccard_function *pf)
|
||||
if (pccard_mfc(pf->sc)) {
|
||||
reg |= (PCCARD_CCR_OPTION_FUNC_ENABLE |
|
||||
PCCARD_CCR_OPTION_ADDR_DECODE);
|
||||
/*
|
||||
/*
|
||||
* XXX Need to enable PCCARD_CCR_OPTION_IRQ_ENABLE if
|
||||
* XXX we have an interrupt handler, but we don't know that
|
||||
* XXX at this point.
|
||||
*/
|
||||
reg |= PCCARD_CCR_OPTION_IREQ_ENABLE;
|
||||
/* reg |= PCCARD_CCR_OPTION_IREQ_ENABLE;*/
|
||||
}
|
||||
pccard_ccr_write(pf, PCCARD_CCR_OPTION, reg);
|
||||
|
||||
@ -487,17 +498,17 @@ pccard_function_enable(struct pccard_function *pf)
|
||||
#ifdef PCCARDDEBUG
|
||||
if (pccard_debug) {
|
||||
STAILQ_FOREACH(tmp, &pf->sc->card.pf_head, pf_list) {
|
||||
device_printf(tmp->sc->dev,
|
||||
device_printf(tmp->sc->dev,
|
||||
"function %d CCR at %d offset %x: "
|
||||
"%x %x %x %x, %x %x %x %x, %x\n",
|
||||
tmp->number, tmp->pf_ccr_window,
|
||||
tmp->number, tmp->pf_ccr_window,
|
||||
tmp->pf_ccr_offset,
|
||||
pccard_ccr_read(tmp, 0x00),
|
||||
pccard_ccr_read(tmp, 0x02),
|
||||
pccard_ccr_read(tmp, 0x04),
|
||||
pccard_ccr_read(tmp, 0x06),
|
||||
pccard_ccr_read(tmp, 0x0A),
|
||||
pccard_ccr_read(tmp, 0x0C),
|
||||
pccard_ccr_read(tmp, 0x0C),
|
||||
pccard_ccr_read(tmp, 0x0E),
|
||||
pccard_ccr_read(tmp, 0x10),
|
||||
pccard_ccr_read(tmp, 0x12));
|
||||
@ -536,6 +547,27 @@ pccard_function_disable(struct pccard_function *pf)
|
||||
return;
|
||||
}
|
||||
|
||||
if (pf->intr_handler != NULL) {
|
||||
pf->intr_handler = NULL;
|
||||
pf->intr_handler_arg = NULL;
|
||||
pf->intr_handler_cookie = NULL;
|
||||
pccard_ccr_write(pf, PCCARD_CCR_OPTION,
|
||||
pccard_ccr_read(pf, PCCARD_CCR_OPTION) &
|
||||
~PCCARD_CCR_OPTION_IREQ_ENABLE);
|
||||
|
||||
if (pf->sc->intr_handler_count == 1) {
|
||||
struct pccard_ivar *ivar = PCCARD_IVAR(pf->dev);
|
||||
struct resource_list_entry *rle = NULL;
|
||||
|
||||
pf->sc->intr_handler_count--;
|
||||
rle = resource_list_find(&ivar->resources, SYS_RES_IRQ, 0);
|
||||
if (rle == NULL)
|
||||
panic("No IRQ for pccard?");
|
||||
|
||||
bus_teardown_intr(dev, rle->res, &pf->sc->intr_handler_count);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* it's possible for different functions' CCRs to be in the same
|
||||
* underlying page. Check for that. Note we mark us as disabled
|
||||
@ -553,7 +585,7 @@ pccard_function_disable(struct pccard_function *pf)
|
||||
|
||||
/* Not used by anyone else; unmap the CCR. */
|
||||
if (tmp == NULL) {
|
||||
bus_release_resource(dev, SYS_RES_MEMORY, pf->ccr_rid,
|
||||
bus_release_resource(dev, SYS_RES_MEMORY, pf->ccr_rid,
|
||||
pf->ccr_res);
|
||||
pf->ccr_res = NULL;
|
||||
}
|
||||
@ -605,7 +637,7 @@ pccard_io_map(struct pccard_function *pf, int width, bus_addr_t offset,
|
||||
;
|
||||
iosize--;
|
||||
|
||||
pccard_ccr_write(pf, PCCARD_CCR_IOBASE0,
|
||||
pccard_ccr_write(pf, PCCARD_CCR_IOBASE0,
|
||||
pf->pf_mfc_iobase & 0xff);
|
||||
pccard_ccr_write(pf, PCCARD_CCR_IOBASE1,
|
||||
(pf->pf_mfc_iobase >> 8) & 0xff);
|
||||
@ -728,7 +760,7 @@ pccard_print_child(device_t dev, device_t child)
|
||||
PCCARD_NMEM, "%#lx");
|
||||
pccard_print_resources(rl, "irq", SYS_RES_IRQ, PCCARD_NIRQ,
|
||||
"%ld");
|
||||
pccard_print_resources(rl, "drq", SYS_RES_DRQ, PCCARD_NDRQ,
|
||||
pccard_print_resources(rl, "drq", SYS_RES_DRQ, PCCARD_NDRQ,
|
||||
"%ld");
|
||||
retval += printf(" function %d config %d", devi->fcn->number,
|
||||
devi->fcn->cfe->number);
|
||||
@ -776,7 +808,7 @@ pccard_get_resource(device_t dev, device_t child, int type, int rid,
|
||||
rle = resource_list_find(rl, type, rid);
|
||||
if (!rle)
|
||||
return ENOENT;
|
||||
|
||||
|
||||
if (startp)
|
||||
*startp = rle->start;
|
||||
if (countp)
|
||||
@ -803,10 +835,11 @@ pccard_set_res_flags(device_t dev, device_t child, int type, int rid,
|
||||
|
||||
static int
|
||||
pccard_set_memory_offset(device_t dev, device_t child, int rid,
|
||||
u_int32_t offset)
|
||||
u_int32_t offset, u_int32_t *offsetp)
|
||||
|
||||
{
|
||||
return CARD_SET_MEMORY_OFFSET(device_get_parent(dev), child, rid,
|
||||
offset);
|
||||
offset, offsetp);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -866,33 +899,21 @@ static struct resource *
|
||||
pccard_alloc_resource(device_t dev, device_t child, int type, int *rid,
|
||||
u_long start, u_long end, u_long count, u_int flags)
|
||||
{
|
||||
struct pccard_ivar *ivar;
|
||||
struct pccard_function *pf;
|
||||
struct resource *r = 0;
|
||||
struct resource_list_entry *rle = NULL;
|
||||
|
||||
/* XXX: This is an ugly way to fudge the resources. */
|
||||
|
||||
if (device_get_parent(child) == dev) {
|
||||
ivar = PCCARD_IVAR(child);
|
||||
pf = ivar->fcn;
|
||||
switch (type) {
|
||||
case SYS_RES_IRQ:
|
||||
if (*rid > 0)
|
||||
return NULL;
|
||||
r = pf->cfe->irqres;
|
||||
break;
|
||||
case SYS_RES_IOPORT:
|
||||
if (*rid > 3) /* XXX */
|
||||
return NULL;
|
||||
r = pf->cfe->iores[*rid];
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
struct pccard_ivar *devi = PCCARD_IVAR(child);
|
||||
struct resource_list *rl = &devi->resources;
|
||||
|
||||
rle = resource_list_find(rl, type, *rid);
|
||||
}
|
||||
if (r != NULL) {
|
||||
if (flags & RF_ACTIVE)
|
||||
bus_generic_activate_resource(dev, child, type,
|
||||
*rid, r);
|
||||
return (r);
|
||||
|
||||
if (rle != NULL) {
|
||||
if (flags & RF_ACTIVE)
|
||||
bus_activate_resource(dev, type, rle->rid, rle->res);
|
||||
return (rle->res);
|
||||
}
|
||||
return (bus_generic_alloc_resource(dev, child, type, rid, start,
|
||||
end, count, flags));
|
||||
@ -902,6 +923,19 @@ static int
|
||||
pccard_release_resource(device_t dev, device_t child, int type, int rid,
|
||||
struct resource *r)
|
||||
{
|
||||
struct resource_list_entry *rle = NULL;
|
||||
|
||||
if (device_get_parent(child) == dev) {
|
||||
struct pccard_ivar *devi = PCCARD_IVAR(child);
|
||||
struct resource_list *rl = &devi->resources;
|
||||
|
||||
rle = resource_list_find(rl, type, rid);
|
||||
}
|
||||
|
||||
if (rle != NULL) {
|
||||
return bus_release_resource(dev, type, rle->rid, rle->res);
|
||||
}
|
||||
|
||||
return bus_generic_release_resource(dev, child, type, rid, r);
|
||||
}
|
||||
|
||||
@ -910,6 +944,19 @@ pccard_activate_resource(device_t dev, device_t child, int type, int rid,
|
||||
struct resource *r)
|
||||
{
|
||||
/* XXX need to write to the COR to activate this for mf cards */
|
||||
struct resource_list_entry *rle = NULL;
|
||||
|
||||
if (device_get_parent(child) == dev) {
|
||||
struct pccard_ivar *devi = PCCARD_IVAR(child);
|
||||
struct resource_list *rl = &devi->resources;
|
||||
|
||||
rle = resource_list_find(rl, type, rid);
|
||||
}
|
||||
|
||||
if (rle != NULL) {
|
||||
return (bus_activate_resource(dev, type, rle->rid, rle->res));
|
||||
}
|
||||
|
||||
return (bus_generic_activate_resource(dev, child, type, rid, r));
|
||||
}
|
||||
|
||||
@ -918,6 +965,19 @@ pccard_deactivate_resource(device_t dev, device_t child, int type, int rid,
|
||||
struct resource *r)
|
||||
{
|
||||
/* XXX need to write to the COR to deactivate this for mf cards */
|
||||
struct resource_list_entry *rle = NULL;
|
||||
|
||||
if (device_get_parent(child) == dev) {
|
||||
struct pccard_ivar *devi = PCCARD_IVAR(child);
|
||||
struct resource_list *rl = &devi->resources;
|
||||
|
||||
rle = resource_list_find(rl, type, rid);
|
||||
}
|
||||
|
||||
if (rle != NULL) {
|
||||
return (bus_deactivate_resource(dev, type, rle->rid, rle->res));
|
||||
}
|
||||
|
||||
return (bus_generic_deactivate_resource(dev, child, type, rid, r));
|
||||
}
|
||||
|
||||
@ -930,6 +990,85 @@ pccard_child_detached(device_t parent, device_t dev)
|
||||
free(ivar, M_DEVBUF);
|
||||
}
|
||||
|
||||
static void
|
||||
pccard_intr(void *arg) {
|
||||
struct pccard_function *pf;
|
||||
STAILQ_FOREACH(pf, &((struct pccard_softc*)arg)->card.pf_head, pf_list) {
|
||||
if (pf->intr_handler != NULL) {
|
||||
int reg = pccard_ccr_read(pf, PCCARD_CCR_STATUS);
|
||||
if (reg & PCCARD_CCR_STATUS_INTR) {
|
||||
pccard_ccr_write(pf, PCCARD_CCR_STATUS,
|
||||
reg & ~PCCARD_CCR_STATUS_INTR);
|
||||
pf->intr_handler(pf->intr_handler_arg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
pccard_setup_intr(device_t dev, device_t child,
|
||||
struct resource *irq, int flags,
|
||||
driver_intr_t *intr, void *arg, void **cookiep)
|
||||
{
|
||||
struct pccard_ivar *ivar = PCCARD_IVAR(child);
|
||||
struct pccard_function *func = ivar->fcn;
|
||||
struct resource_list_entry *rle = NULL;
|
||||
struct pccard_softc *sc = device_get_softc(dev);
|
||||
|
||||
if (func->intr_handler != NULL)
|
||||
panic("Only one interrupt handler per function allowed for pccard\n");
|
||||
|
||||
rle = resource_list_find(&ivar->resources, SYS_RES_IRQ, 0);
|
||||
if (rle == NULL || rle->res != irq)
|
||||
panic("irq in setup_intr does not match allocated irq\n");
|
||||
|
||||
func->intr_handler = intr;
|
||||
func->intr_handler_arg = arg;
|
||||
func->intr_handler_cookie = cookiep;
|
||||
pccard_ccr_write(func, PCCARD_CCR_OPTION,
|
||||
pccard_ccr_read(func, PCCARD_CCR_OPTION) |
|
||||
PCCARD_CCR_OPTION_IREQ_ENABLE);
|
||||
|
||||
if (sc->intr_handler_count++ == 0) {
|
||||
rle = resource_list_find(&ivar->resources, SYS_RES_IRQ, 0);
|
||||
if (rle == NULL)
|
||||
panic("No IRQ for pccard?");
|
||||
|
||||
bus_setup_intr(dev, rle->res, INTR_TYPE_TTY/* | INTR_FAST*/,
|
||||
pccard_intr, sc, (void*)&sc->intr_handler_count);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
pccard_teardown_intr(device_t dev, device_t child, struct resource *r, void *cookie)
|
||||
{
|
||||
struct pccard_ivar *ivar = PCCARD_IVAR(child);
|
||||
struct pccard_function *func = ivar->fcn;
|
||||
struct pccard_softc *sc = device_get_softc(dev);
|
||||
|
||||
if (func->intr_handler_cookie != cookie)
|
||||
panic("pccard teardown of unknown interrupt handler\n");
|
||||
|
||||
func->intr_handler = NULL;
|
||||
func->intr_handler_arg = NULL;
|
||||
func->intr_handler_cookie = NULL;
|
||||
pccard_ccr_write(func, PCCARD_CCR_OPTION,
|
||||
pccard_ccr_read(func, PCCARD_CCR_OPTION) &
|
||||
~PCCARD_CCR_OPTION_IREQ_ENABLE);
|
||||
|
||||
if (--sc->intr_handler_count == 0) {
|
||||
struct resource_list_entry *rle = NULL;
|
||||
|
||||
rle = resource_list_find(&ivar->resources, SYS_RES_IRQ, 0);
|
||||
if (rle == NULL)
|
||||
panic("No IRQ for pccard?");
|
||||
|
||||
bus_teardown_intr(dev, rle->res, &sc->intr_handler_count);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static device_method_t pccard_methods[] = {
|
||||
/* Device interface */
|
||||
DEVMETHOD(device_probe, pccard_probe),
|
||||
@ -947,8 +1086,8 @@ static device_method_t pccard_methods[] = {
|
||||
DEVMETHOD(bus_release_resource, pccard_release_resource),
|
||||
DEVMETHOD(bus_activate_resource, pccard_activate_resource),
|
||||
DEVMETHOD(bus_deactivate_resource, pccard_deactivate_resource),
|
||||
DEVMETHOD(bus_setup_intr, bus_generic_setup_intr),
|
||||
DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr),
|
||||
DEVMETHOD(bus_setup_intr, pccard_setup_intr),
|
||||
DEVMETHOD(bus_teardown_intr, pccard_teardown_intr),
|
||||
DEVMETHOD(bus_set_resource, pccard_set_resource),
|
||||
DEVMETHOD(bus_get_resource, pccard_get_resource),
|
||||
DEVMETHOD(bus_delete_resource, pccard_delete_resource),
|
||||
@ -977,4 +1116,4 @@ DRIVER_MODULE(pccard, pc98pcic, pccard_driver, pccard_devclass, 0, 0);
|
||||
DRIVER_MODULE(pccard, pccbb, pccard_driver, pccard_devclass, 0, 0);
|
||||
DRIVER_MODULE(pccard, tcic, pccard_driver, pccard_devclass, 0, 0);
|
||||
MODULE_VERSION(pccard, 1);
|
||||
MODULE_DEPEND(pccard, pcic, 1, 1, 1);
|
||||
/*MODULE_DEPEND(pccard, pcic, 1, 1, 1);*/
|
||||
|
@ -136,6 +136,9 @@ struct pccard_function {
|
||||
long pf_mfc_iobase;
|
||||
long pf_mfc_iomax;
|
||||
int pf_flags;
|
||||
driver_intr_t *intr_handler;
|
||||
void *intr_handler_arg;
|
||||
void *intr_handler_cookie;
|
||||
};
|
||||
|
||||
/* pf_flags */
|
||||
@ -181,6 +184,7 @@ struct pccard_softc {
|
||||
/* this stuff is for the card */
|
||||
struct pccard_card card;
|
||||
int sc_enabled_count; /* num functions enabled */
|
||||
int intr_handler_count;
|
||||
};
|
||||
|
||||
void
|
||||
|
@ -242,7 +242,7 @@ static int pccbb_pcic_release_resource(device_t self, device_t child, int type,
|
||||
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);
|
||||
u_int32_t offset, u_int32_t *offsetp);
|
||||
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,
|
||||
@ -378,7 +378,6 @@ static int
|
||||
pccbb_attach(device_t dev)
|
||||
{
|
||||
struct pccbb_softc *sc = (struct pccbb_softc *)device_get_softc(dev);
|
||||
int flags;
|
||||
int rid;
|
||||
u_int32_t tmp;
|
||||
|
||||
@ -387,9 +386,8 @@ pccbb_attach(device_t dev)
|
||||
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_chipset = cb_chipset(pci_get_devid(dev), NULL, &sc->sc_flags);
|
||||
sc->sc_dev = dev;
|
||||
sc->sc_flags = 0;
|
||||
sc->sc_cbdev = NULL;
|
||||
sc->sc_pccarddev = NULL;
|
||||
sc->sc_secbus = pci_read_config(dev, PCIR_SECBUS_2, 1);
|
||||
@ -562,7 +560,7 @@ pccbb_driver_added(device_t dev, driver_t *driver)
|
||||
device_t *devlist;
|
||||
int tmp;
|
||||
int numdevs;
|
||||
|
||||
|
||||
DEVICE_IDENTIFY(driver, dev);
|
||||
device_get_children(dev, &devlist, &numdevs);
|
||||
for (tmp = 0; tmp < numdevs; tmp++) {
|
||||
@ -570,12 +568,24 @@ pccbb_driver_added(device_t dev, driver_t *driver)
|
||||
device_probe_and_attach(devlist[tmp]) == 0) {
|
||||
if (devlist[tmp] == NULL)
|
||||
/* NOTHING */;
|
||||
else if (strcmp(driver->name, "cardbus") == 0)
|
||||
else if (strcmp(driver->name, "cardbus") == 0) {
|
||||
sc->sc_cbdev = devlist[tmp];
|
||||
else if (strcmp(driver->name, "pccard") == 0)
|
||||
if ((sc->sc_socketreg->socket_state
|
||||
& PCCBB_SOCKET_STAT_CD) == 0) {
|
||||
mtx_enter(&sc->sc_mtx, MTX_DEF);
|
||||
wakeup(sc);
|
||||
mtx_exit(&sc->sc_mtx, MTX_DEF);
|
||||
}
|
||||
} else if (strcmp(driver->name, "pccard") == 0) {
|
||||
sc->sc_pccarddev = devlist[tmp];
|
||||
else
|
||||
device_printf(dev,
|
||||
if ((sc->sc_socketreg->socket_state
|
||||
& PCCBB_SOCKET_STAT_CD) == 0) {
|
||||
mtx_enter(&sc->sc_mtx, MTX_DEF);
|
||||
wakeup(sc);
|
||||
mtx_exit(&sc->sc_mtx, MTX_DEF);
|
||||
}
|
||||
} else
|
||||
device_printf(dev,
|
||||
"Unsupported child bus: %s\n",
|
||||
driver->name);
|
||||
}
|
||||
@ -605,6 +615,7 @@ pccbb_event_thread (void *arg)
|
||||
struct pccbb_softc *sc = arg;
|
||||
u_int32_t status;
|
||||
|
||||
mtx_enter(&Giant, MTX_DEF);
|
||||
for(;;) {
|
||||
if (!(sc->sc_flags & PCCBB_KTHREAD_RUNNING))
|
||||
sc->sc_flags |= PCCBB_KTHREAD_RUNNING;
|
||||
@ -623,24 +634,15 @@ pccbb_event_thread (void *arg)
|
||||
|
||||
status = sc->sc_socketreg->socket_state;
|
||||
if ((status & PCCBB_SOCKET_STAT_CD) == 0) {
|
||||
if (!(sc->sc_flags & PCCBB_CARDATTACHED))
|
||||
pccbb_insert(sc);
|
||||
else
|
||||
device_printf(sc->sc_dev,
|
||||
"duplicate card insert\n");
|
||||
pccbb_insert(sc);
|
||||
} else {
|
||||
if (!(sc->sc_flags & PCCBB_CARDATTACHED))
|
||||
DEVPRINTF((sc->sc_dev,
|
||||
"removal of nonexistant card!\n"));
|
||||
else
|
||||
pccbb_removal(sc);
|
||||
pccbb_removal(sc);
|
||||
}
|
||||
mtx_exit(&sc->sc_mtx, MTX_DEF);
|
||||
}
|
||||
mtx_exit(&sc->sc_mtx, MTX_DEF);
|
||||
sc->sc_flags &= ~PCCBB_KTHREAD_RUNNING;
|
||||
wakeup(sc);
|
||||
mtx_enter(&Giant, MTX_DEF);
|
||||
kthread_exit(0);
|
||||
}
|
||||
|
||||
@ -689,18 +691,13 @@ pccbb_insert (struct pccbb_softc *sc)
|
||||
sockevent, sockstate));
|
||||
|
||||
if (sockstate & PCCBB_SOCKET_STAT_16BIT && sc->sc_pccarddev != NULL) {
|
||||
sc->sc_flags |= PCCBB_CARDATTACHED | PCCBB_16BIT_CARD;
|
||||
if (CARD_ATTACH_CARD(sc->sc_pccarddev) != 0) {
|
||||
sc->sc_flags |= PCCBB_16BIT_CARD;
|
||||
if (CARD_ATTACH_CARD(sc->sc_pccarddev) != 0)
|
||||
device_printf(sc->sc_dev, "card activation failed\n");
|
||||
sc->sc_flags &= ~PCCBB_CARDATTACHED;
|
||||
}
|
||||
} else if (sockstate & PCCBB_SOCKET_STAT_CB && sc->sc_cbdev != NULL) {
|
||||
sc->sc_flags |= PCCBB_CARDATTACHED;
|
||||
sc->sc_flags &= ~PCCBB_16BIT_CARD;
|
||||
if (CARD_ATTACH_CARD(sc->sc_cbdev) != 0) {
|
||||
if (CARD_ATTACH_CARD(sc->sc_cbdev) != 0)
|
||||
device_printf(sc->sc_dev, "card activation failed\n");
|
||||
sc->sc_flags &= ~PCCBB_CARDATTACHED;
|
||||
}
|
||||
} else {
|
||||
device_printf (sc->sc_dev, "Unsupported card type detected\n");
|
||||
}
|
||||
@ -714,10 +711,9 @@ pccbb_removal (struct pccbb_softc *sc)
|
||||
|
||||
sockstate = sc->sc_socketreg->socket_state;
|
||||
|
||||
sc->sc_flags &= ~PCCBB_CARDATTACHED;
|
||||
if (sockstate & PCCBB_16BIT_CARD)
|
||||
if (sockstate & PCCBB_16BIT_CARD && sc->sc_pccarddev != NULL)
|
||||
CARD_DETACH_CARD(sc->sc_pccarddev, DETACH_FORCE);
|
||||
else
|
||||
else if ((!(sockstate & PCCBB_16BIT_CARD)) && sc->sc_cbdev != NULL)
|
||||
CARD_DETACH_CARD(sc->sc_cbdev, DETACH_FORCE);
|
||||
|
||||
while (NULL != (rle = SLIST_FIRST(&sc->rl))) {
|
||||
@ -862,6 +858,9 @@ pccbb_power(device_t dev, int volts)
|
||||
break;
|
||||
}
|
||||
|
||||
if (sc->sc_socketreg->socket_control == sock_ctrl)
|
||||
return 1; /* no change necessary */
|
||||
|
||||
sc->sc_socketreg->socket_control = sock_ctrl;
|
||||
status = sc->sc_socketreg->socket_state;
|
||||
|
||||
@ -926,7 +925,7 @@ pccbb_cardbus_reset(device_t dev)
|
||||
DELAY(delay_us);
|
||||
|
||||
/* If a card exists, unreset it! */
|
||||
if (sc->sc_flags & PCCBB_CARDATTACHED) {
|
||||
if ((sc->sc_socketreg->socket_state & PCCBB_SOCKET_STAT_CD) == 0) {
|
||||
PCI_MASK_CONFIG(dev, PCCBBR_BRIDGECTRL,
|
||||
&~PCCBBM_BRIDGECTRL_RESET, 2);
|
||||
DELAY(delay_us);
|
||||
@ -936,8 +935,13 @@ pccbb_cardbus_reset(device_t dev)
|
||||
static int
|
||||
pccbb_cardbus_power_enable_socket(device_t self, device_t child)
|
||||
{
|
||||
struct pccbb_softc *sc = device_get_softc(self);
|
||||
int voltage;
|
||||
|
||||
|
||||
if ((sc->sc_socketreg->socket_state & PCCBB_SOCKET_STAT_CD)
|
||||
== PCCBB_SOCKET_STAT_CD)
|
||||
return ENODEV;
|
||||
|
||||
voltage = pccbb_detect_voltage(self);
|
||||
|
||||
pccbb_power(self, CARD_VCC_0V | CARD_VPP_0V);
|
||||
@ -1285,6 +1289,7 @@ pccbb_pcic_wait_ready(struct pccbb_softc *sc)
|
||||
PCIC_SYSMEM_ADDR ## NUM ## _START_MSB, \
|
||||
PCIC_SYSMEM_ADDR ## NUM ## _STOP_LSB, \
|
||||
PCIC_SYSMEM_ADDR ## NUM ## _STOP_MSB, \
|
||||
PCIC_SYSMEM_ADDR ## NUM ## _WIN, \
|
||||
PCIC_CARDMEM_ADDR ## NUM ## _LSB, \
|
||||
PCIC_CARDMEM_ADDR ## NUM ## _MSB, \
|
||||
PCIC_ADDRWIN_ENABLE_MEM ## NUM ## , \
|
||||
@ -1295,6 +1300,7 @@ static struct mem_map_index_st {
|
||||
int sysmem_start_msb;
|
||||
int sysmem_stop_lsb;
|
||||
int sysmem_stop_msb;
|
||||
int sysmem_win;
|
||||
int cardmem_lsb;
|
||||
int cardmem_msb;
|
||||
int memenable;
|
||||
@ -1314,7 +1320,7 @@ pccbb_pcic_do_mem_map(struct pccbb_softc *sc, int win)
|
||||
(sc->mem[win].addr >> PCIC_SYSMEM_ADDRX_SHIFT) & 0xff);
|
||||
PCIC_WRITE(sc, mem_map_index[win].sysmem_start_msb,
|
||||
((sc->mem[win].addr >> (PCIC_SYSMEM_ADDRX_SHIFT + 8)) &
|
||||
PCIC_SYSMEM_ADDRX_START_MSB_ADDR_MASK));
|
||||
PCIC_SYSMEM_ADDRX_START_MSB_ADDR_MASK) | 0x80);
|
||||
|
||||
PCIC_WRITE(sc, mem_map_index[win].sysmem_stop_lsb,
|
||||
((sc->mem[win].addr + sc->mem[win].realsize - 1) >>
|
||||
@ -1325,6 +1331,9 @@ pccbb_pcic_do_mem_map(struct pccbb_softc *sc, int win)
|
||||
PCIC_SYSMEM_ADDRX_STOP_MSB_ADDR_MASK) |
|
||||
PCIC_SYSMEM_ADDRX_STOP_MSB_WAIT2);
|
||||
|
||||
PCIC_WRITE(sc, mem_map_index[win].sysmem_win,
|
||||
(sc->mem[win].addr >> PCIC_MEMREG_WIN_SHIFT) & 0xff);
|
||||
|
||||
PCIC_WRITE(sc, mem_map_index[win].cardmem_lsb,
|
||||
(sc->mem[win].offset >> PCIC_CARDMEM_ADDRX_SHIFT) & 0xff);
|
||||
PCIC_WRITE(sc, mem_map_index[win].cardmem_msb,
|
||||
@ -1340,15 +1349,17 @@ pccbb_pcic_do_mem_map(struct pccbb_softc *sc, int win)
|
||||
|
||||
#ifdef CBB_DEBUG
|
||||
{
|
||||
int r1, r2, r3, r4, r5, r6;
|
||||
int r1, r2, r3, r4, r5, r6, r7;
|
||||
r1 = PCIC_READ(sc, mem_map_index[win].sysmem_start_msb);
|
||||
r2 = PCIC_READ(sc, mem_map_index[win].sysmem_start_lsb);
|
||||
r3 = PCIC_READ(sc, mem_map_index[win].sysmem_stop_msb);
|
||||
r4 = PCIC_READ(sc, mem_map_index[win].sysmem_stop_lsb);
|
||||
r5 = PCIC_READ(sc, mem_map_index[win].cardmem_msb);
|
||||
r6 = PCIC_READ(sc, mem_map_index[win].cardmem_lsb);
|
||||
r7 = PCIC_READ(sc, mem_map_index[win].sysmem_win);
|
||||
DPRINTF(("pccbb_pcic_do_mem_map window %d: %02x%02x %02x%02x "
|
||||
"%02x%02x\n", win, r1, r2, r3, r4, r5, r6));
|
||||
"%02x%02x %02x (%08x+%08x.%08x*%08lx)\n", win, r1, r2, r3, r4, r5, r6, r7,
|
||||
sc->mem[win].addr, sc->mem[win].size, sc->mem[win].realsize, sc->mem[win].offset));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@ -1371,7 +1382,6 @@ pccbb_pcic_mem_map(struct pccbb_softc *sc, int kind,
|
||||
return (1);
|
||||
|
||||
card_addr = card_addr - card_addr % PCIC_MEM_PAGESIZE;
|
||||
|
||||
sc->mem[*win].memt = rman_get_bustag(r);
|
||||
sc->mem[*win].memh = rman_get_bushandle(r);
|
||||
sc->mem[*win].addr = rman_get_start(r);
|
||||
@ -1399,7 +1409,6 @@ pccbb_pcic_mem_unmap(struct pccbb_softc *sc, int window)
|
||||
panic("pccbb_pcic_mem_unmap: window out of range");
|
||||
|
||||
PCIC_MASK(sc, PCIC_ADDRWIN_ENABLE, & ~mem_map_index[window].memenable);
|
||||
|
||||
sc->memalloc &= ~(1 << window);
|
||||
}
|
||||
|
||||
@ -1452,6 +1461,18 @@ static void pccbb_pcic_do_io_map(struct pccbb_softc *sc, int win)
|
||||
| io_map_index[win].ioctlbits[sc->io[win].width]);
|
||||
|
||||
PCIC_MASK(sc, PCIC_ADDRWIN_ENABLE, | io_map_index[win].ioenable);
|
||||
#ifdef CBB_DEBUG
|
||||
{
|
||||
int r1, r2, r3, r4;
|
||||
r1 = PCIC_READ(sc, io_map_index[win].start_msb);
|
||||
r2 = PCIC_READ(sc, io_map_index[win].start_lsb);
|
||||
r3 = PCIC_READ(sc, io_map_index[win].stop_msb);
|
||||
r4 = PCIC_READ(sc, io_map_index[win].stop_lsb);
|
||||
DPRINTF(("pccbb_pcic_do_io_map window %d: %02x%02x %02x%02x "
|
||||
"(%08x+%08x)\n", win, r1, r2, r3, r4,
|
||||
sc->io[win].addr, sc->io[win].size));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static int
|
||||
@ -1517,6 +1538,9 @@ pccbb_pcic_activate_resource(device_t self, device_t child, int type, int rid,
|
||||
struct pccbb_reslist *rle;
|
||||
struct pccbb_softc *sc = device_get_softc(self);
|
||||
|
||||
if (rman_get_flags(r) & RF_ACTIVE)
|
||||
return 0;
|
||||
|
||||
switch (type) {
|
||||
case SYS_RES_IOPORT:
|
||||
err = pccbb_pcic_io_map(sc, 0, r, 0, &win);
|
||||
@ -1549,7 +1573,6 @@ pccbb_pcic_deactivate_resource(device_t self, device_t child, int type,
|
||||
struct pccbb_softc *sc = device_get_softc(self);
|
||||
int win;
|
||||
struct pccbb_reslist *rle;
|
||||
|
||||
win = -1;
|
||||
SLIST_FOREACH(rle, &sc->rl, entries) {
|
||||
if (type == rle->type && rid == rle->rid &&
|
||||
@ -1558,8 +1581,10 @@ pccbb_pcic_deactivate_resource(device_t self, device_t child, int type,
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (win == -1)
|
||||
if (win == -1) {
|
||||
panic("pccbb_pcic: deactivating bogus resoure");
|
||||
return 1;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case SYS_RES_IOPORT:
|
||||
@ -1582,18 +1607,16 @@ 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;
|
||||
if ((sc->sc_flags & PCCBB_PCIC_MEM_32) == 0) {
|
||||
panic("PCCBB bridge cannot handle non MEM_32 bridges\n");
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case SYS_RES_MEMORY:
|
||||
/* Nearly default */
|
||||
if (start == 0 && end == ~0 && count != 1) {
|
||||
start = 0xd0000; /* XXX -- should be tweakable*/
|
||||
end = 0xdffff;
|
||||
start = CARDBUS_SYS_RES_MEMORY_START; /* XXX -- should be tweakable*/
|
||||
end = CARDBUS_SYS_RES_MEMORY_END;
|
||||
}
|
||||
flags = (flags & ~RF_ALIGNMENT_MASK)
|
||||
| rman_make_alignment_flags(PCCBB_MEMALIGN);
|
||||
@ -1639,15 +1662,27 @@ pccbb_pcic_release_resource(device_t self, device_t child, int type,
|
||||
{
|
||||
struct pccbb_softc *sc = device_get_softc(self);
|
||||
struct pccbb_reslist *rle;
|
||||
int count = 0;
|
||||
|
||||
if (rman_get_flags(res) & RF_ACTIVE) {
|
||||
int error;
|
||||
error = bus_deactivate_resource(child, type, rid, res);
|
||||
if (error != 0)
|
||||
return error;
|
||||
}
|
||||
|
||||
SLIST_FOREACH(rle, &sc->rl, entries) {
|
||||
if (type == rle->type && rid == rle->rid &&
|
||||
child == rle->odev) {
|
||||
SLIST_REMOVE(&sc->rl, rle, pccbb_reslist, entries);
|
||||
free(rle, M_DEVBUF);
|
||||
count++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (count == 0) {
|
||||
panic("pccbb_pcic: releasing bogus resource");
|
||||
}
|
||||
|
||||
return bus_generic_release_resource(self, child, type, rid, res);
|
||||
}
|
||||
@ -1671,13 +1706,14 @@ pccbb_pcic_set_res_flags(device_t self, device_t child, int type, int rid,
|
||||
|
||||
static int
|
||||
pccbb_pcic_set_memory_offset(device_t self, device_t child, int rid,
|
||||
u_int32_t offset)
|
||||
u_int32_t cardaddr, u_int32_t *offsetp)
|
||||
{
|
||||
struct pccbb_softc *sc = device_get_softc(self);
|
||||
int win;
|
||||
struct pccbb_reslist *rle;
|
||||
|
||||
win = -1;
|
||||
|
||||
SLIST_FOREACH(rle, &sc->rl, entries) {
|
||||
if (SYS_RES_MEMORY == rle->type && rid == rle->rid &&
|
||||
child == rle->odev) {
|
||||
@ -1685,13 +1721,17 @@ pccbb_pcic_set_memory_offset(device_t self, device_t child, int rid,
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (win == -1)
|
||||
if (win == -1) {
|
||||
panic("pccbb_pcic: setting memory offset of bogus resource");
|
||||
return 1;
|
||||
}
|
||||
|
||||
offset = offset - offset % PCIC_MEM_PAGESIZE;
|
||||
sc->mem[win].offset = ((long)offset) -
|
||||
((long)(sc->mem[win].addr));
|
||||
|
||||
*offsetp = cardaddr % PCIC_MEM_PAGESIZE;
|
||||
cardaddr -= *offsetp;
|
||||
sc->mem[win].realsize = sc->mem[win].size + *offsetp + PCIC_MEM_PAGESIZE - 1;
|
||||
sc->mem[win].realsize = sc->mem[win].realsize -
|
||||
(sc->mem[win].realsize % PCIC_MEM_PAGESIZE);
|
||||
sc->mem[win].offset = cardaddr - sc->mem[win].addr;
|
||||
pccbb_pcic_do_mem_map(sc, win);
|
||||
|
||||
return 0;
|
||||
@ -1785,7 +1825,7 @@ static int
|
||||
pccbb_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
|
||||
{
|
||||
struct pccbb_softc *sc = device_get_softc(dev);
|
||||
|
||||
|
||||
switch (which) {
|
||||
case PCIB_IVAR_BUS:
|
||||
*result = sc->sc_secbus;
|
||||
|
@ -71,7 +71,6 @@ struct pccbb_softc {
|
||||
u_int32_t sc_flags;
|
||||
#define PCCBB_PCIC_IO_RELOC 0x01
|
||||
#define PCCBB_PCIC_MEM_32 0x02
|
||||
#define PCCBB_CARDATTACHED 0x01000000
|
||||
#define PCCBB_16BIT_CARD 0x02000000
|
||||
#define PCCBB_KTHREAD_RUNNING 0x04000000
|
||||
#define PCCBB_KTHREAD_DONE 0x08000000
|
||||
@ -122,7 +121,7 @@ struct pccbb_softc {
|
||||
#define CARD_VPPMASK 0x00f0
|
||||
|
||||
/* XXX: rman is dumb */
|
||||
#define CARDBUS_SYS_RES_MEMORY_START 0x18020000
|
||||
#define CARDBUS_SYS_RES_MEMORY_START 0x44000000
|
||||
#define CARDBUS_SYS_RES_MEMORY_END 0xEFFFFFFF
|
||||
#define CARDBUS_SYS_RES_IOPORT_START 0x3000
|
||||
#define CARDBUS_SYS_RES_IOPORT_END 0xEFFF
|
||||
|
Loading…
Reference in New Issue
Block a user