summaryrefslogtreecommitdiffstats
path: root/sys/dev/cardbus/cardbus_cis.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/cardbus/cardbus_cis.c')
-rw-r--r--sys/dev/cardbus/cardbus_cis.c318
1 files changed, 3 insertions, 315 deletions
diff --git a/sys/dev/cardbus/cardbus_cis.c b/sys/dev/cardbus/cardbus_cis.c
index 45cddf7..f7ee22e 100644
--- a/sys/dev/cardbus/cardbus_cis.c
+++ b/sys/dev/cardbus/cardbus_cis.c
@@ -116,11 +116,6 @@ static int decode_tuple(device_t cbdev, device_t child, int tupleid,
uint32_t *off, struct tuple_callbacks *callbacks);
static int cardbus_parse_cis(device_t cbdev, device_t child,
struct tuple_callbacks *callbacks);
-static int barsort(const void *a, const void *b);
-static int cardbus_alloc_resources(device_t cbdev, device_t child);
-static void cardbus_add_map(device_t cbdev, device_t child, int reg);
-static void cardbus_pickup_maps(device_t cbdev, device_t child);
-
#define MAKETUPLE(NAME,FUNC) { CISTPL_ ## NAME, #NAME, decode_tuple_ ## FUNC }
@@ -280,41 +275,9 @@ decode_tuple_funce(device_t cbdev, device_t child, int id,
return (0);
type = tupledata[0]; /* XXX <32 always? */
switch (dinfo->funcid) {
- case TPL_FUNC_SERIAL:
- if (type == TPL_FUNCE_SER_UART) { /* NB: len known > 1 */
- dinfo->funce.sio.type = tupledata[1] & 0x1f;
- }
- dinfo->fepresent |= 1<<type;
- break;
- case TPL_FUNC_LAN:
+ case PCCARD_FUNCTION_NETWORK:
switch (type) {
- case TPL_FUNCE_LAN_TECH:
- dinfo->funce.lan.tech = tupledata[1]; /* XXX mask? */
- break;
-#if 0
- case TPL_FUNCE_LAN_SPEED:
- for (i = 0; i < 3; i++) {
- if (dinfo->funce.lan.speed[i] == 0) {
- if (len > 4) {
- dinfo->funce.lan.speed[i] =
- ...;
- }
- break;
- }
- }
- break;
-#endif
- case TPL_FUNCE_LAN_MEDIA:
- for (i = 0; i < 4 && dinfo->funce.lan.media[i]; i++) {
- if (dinfo->funce.lan.media[i] == 0) {
- /* NB: len known > 1 */
- dinfo->funce.lan.media[i] =
- tupledata[1]; /*XXX? mask */
- break;
- }
- }
- break;
- case TPL_FUNCE_LAN_NID:
+ case PCCARD_TPLFE_TYPE_LAN_NID:
if (tupledata[1] > sizeof(dinfo->funce.lan.nid)) {
/* ignore, warning? */
return (0);
@@ -322,9 +285,6 @@ decode_tuple_funce(device_t cbdev, device_t child, int id,
bcopy(tupledata + 2, dinfo->funce.lan.nid,
tupledata[1]);
break;
- case TPL_FUNCE_LAN_CONN:
- dinfo->funce.lan.contype = tupledata[1];/*XXX mask? */
- break;
}
dinfo->fepresent |= 1<<type;
break;
@@ -731,277 +691,6 @@ cardbus_parse_cis(device_t cbdev, device_t child,
return (0);
}
-static void
-cardbus_do_res(struct resource_list_entry *rle, device_t child, uint32_t start)
-{
- rle->start = start;
- rle->end = start + rle->count - 1;
- pci_write_config(child, rle->rid, rle->start, 4);
-}
-
-static int
-barsort(const void *a, const void *b)
-{
- return ((*(const struct resource_list_entry * const *)b)->count -
- (*(const struct resource_list_entry * const *)a)->count);
-}
-
-static int
-cardbus_alloc_resources(device_t cbdev, device_t child)
-{
- struct cardbus_devinfo *dinfo = device_get_ivars(child);
- int count;
- struct resource_list_entry *rle;
- struct resource_list_entry **barlist;
- int tmp;
- uint32_t mem_psize = 0, mem_nsize = 0, io_size = 0;
- struct resource *res;
- uint32_t start,end;
- int rid, flags;
-
- count = 0;
- SLIST_FOREACH(rle, &dinfo->pci.resources, link) {
- count++;
- }
- if (count == 0)
- return (0);
- barlist = malloc(sizeof(struct resource_list_entry*) * count, M_DEVBUF,
- M_WAITOK);
- count = 0;
- SLIST_FOREACH(rle, &dinfo->pci.resources, link) {
- barlist[count] = rle;
- if (rle->type == SYS_RES_IOPORT) {
- io_size += rle->count;
- } else if (rle->type == SYS_RES_MEMORY) {
- if (dinfo->mprefetchable & BARBIT(rle->rid))
- mem_psize += rle->count;
- else
- mem_nsize += rle->count;
- }
- count++;
- }
-
- /*
- * We want to allocate the largest resource first, so that our
- * allocated memory is packed.
- */
- qsort(barlist, count, sizeof(struct resource_list_entry*), barsort);
-
- /* Allocate prefetchable memory */
- flags = 0;
- for (tmp = 0; tmp < count; tmp++) {
- rle = barlist[tmp];
- if (rle->res == NULL &&
- rle->type == SYS_RES_MEMORY &&
- dinfo->mprefetchable & BARBIT(rle->rid)) {
- flags = rman_make_alignment_flags(rle->count);
- break;
- }
- }
- if (flags > 0) { /* If any prefetchable memory is requested... */
- /*
- * First we allocate one big space for all resources of this
- * type. We do this because our parent, pccbb, needs to open
- * a window to forward all addresses within the window, and
- * it would be best if nobody else has resources allocated
- * within the window.
- * (XXX: Perhaps there might be a better way to do this?)
- */
- rid = 0;
- res = bus_alloc_resource(cbdev, SYS_RES_MEMORY, &rid, 0,
- (dinfo->mprefetchable & dinfo->mbelow1mb)?0xFFFFF:~0UL,
- mem_psize, flags);
- if (res == NULL) {
- device_printf(cbdev,
- "Can't get memory for prefetch mem\n");
- free(barlist, M_DEVBUF);
- return (EIO);
- }
- start = rman_get_start(res);
- end = rman_get_end(res);
- DEVPRINTF((cbdev, "Prefetchable memory at %x-%x\n", start, end));
- /*
- * Now that we know the region is free, release it and hand it
- * out piece by piece.
- */
- bus_release_resource(cbdev, SYS_RES_MEMORY, rid, res);
- for (tmp = 0; tmp < count; tmp++) {
- rle = barlist[tmp];
- if (rle->type == SYS_RES_MEMORY &&
- dinfo->mprefetchable & BARBIT(rle->rid)) {
- cardbus_do_res(rle, child, start);
- start += rle->count;
- }
- }
- }
-
- /* Allocate non-prefetchable memory */
- flags = 0;
- for (tmp = 0; tmp < count; tmp++) {
- rle = barlist[tmp];
- if (rle->type == SYS_RES_MEMORY &&
- (dinfo->mprefetchable & BARBIT(rle->rid)) == 0) {
- flags = rman_make_alignment_flags(rle->count);
- break;
- }
- }
- if (flags > 0) { /* If any non-prefetchable memory is requested... */
- /*
- * First we allocate one big space for all resources of this
- * type. We do this because our parent, pccbb, needs to open
- * a window to forward all addresses within the window, and
- * it would be best if nobody else has resources allocated
- * within the window.
- * (XXX: Perhaps there might be a better way to do this?)
- */
- rid = 0;
- res = bus_alloc_resource(cbdev, SYS_RES_MEMORY, &rid, 0,
- ((~dinfo->mprefetchable) & dinfo->mbelow1mb)?0xFFFFF:~0UL,
- mem_nsize, flags);
- if (res == NULL) {
- device_printf(cbdev,
- "Can't get memory for non-prefetch mem\n");
- free(barlist, M_DEVBUF);
- return (EIO);
- }
- start = rman_get_start(res);
- end = rman_get_end(res);
- DEVPRINTF((cbdev, "Non-prefetchable memory at %x-%x\n",
- start, end));
- /*
- * Now that we know the region is free, release it and hand it
- * out piece by piece.
- */
- bus_release_resource(cbdev, SYS_RES_MEMORY, rid, res);
- for (tmp = 0; tmp < count; tmp++) {
- rle = barlist[tmp];
- if (rle->type == SYS_RES_MEMORY &&
- (dinfo->mprefetchable & BARBIT(rle->rid)) == 0) {
- cardbus_do_res(rle, child, start);
- start += rle->count;
- }
- }
- }
-
- /* Allocate IO ports */
- flags = 0;
- for (tmp = 0; tmp < count; tmp++) {
- rle = barlist[tmp];
- if (rle->type == SYS_RES_IOPORT) {
- flags = rman_make_alignment_flags(rle->count);
- break;
- }
- }
- if (flags > 0) { /* If any IO port is requested... */
- /*
- * First we allocate one big space for all resources of this
- * type. We do this because our parent, pccbb, needs to open
- * a window to forward all addresses within the window, and
- * it would be best if nobody else has resources allocated
- * within the window.
- * (XXX: Perhaps there might be a better way to do this?)
- */
- rid = 0;
- res = bus_alloc_resource(cbdev, SYS_RES_IOPORT, &rid, 0,
- (dinfo->ibelow1mb)?0xFFFFF:~0UL, io_size, flags);
- if (res == NULL) {
- device_printf(cbdev,
- "Can't get memory for IO ports\n");
- free(barlist, M_DEVBUF);
- return (EIO);
- }
- start = rman_get_start(res);
- end = rman_get_end(res);
- DEVPRINTF((cbdev, "IO port at %x-%x\n", start, end));
- /*
- * Now that we know the region is free, release it and hand it
- * out piece by piece.
- */
- bus_release_resource(cbdev, SYS_RES_IOPORT, rid, res);
- for (tmp = 0; tmp < count; tmp++) {
- rle = barlist[tmp];
- if (rle->type == SYS_RES_IOPORT) {
- cardbus_do_res(rle, child, start);
- start += rle->count;
- }
- }
- }
-
- /* Allocate IRQ */
- rid = 0;
- res = bus_alloc_resource_any(cbdev, SYS_RES_IRQ, &rid, RF_SHAREABLE);
- if (res == NULL) {
- device_printf(cbdev, "Can't get memory for irq\n");
- free(barlist, M_DEVBUF);
- return (EIO);
- }
- start = rman_get_start(res);
- end = rman_get_end(res);
- bus_release_resource(cbdev, SYS_RES_IRQ, rid, res);
- resource_list_add(&dinfo->pci.resources, SYS_RES_IRQ, rid, start, end,
- 1);
- dinfo->pci.cfg.intline = rman_get_start(res);
- pci_write_config(child, PCIR_INTLINE, rman_get_start(res), 1);
-
- free(barlist, M_DEVBUF);
- return (0);
-}
-
-/*
- * Adding a memory/io resource (sans CIS)
- */
-
-static void
-cardbus_add_map(device_t cbdev, device_t child, int reg)
-{
- struct cardbus_devinfo *dinfo = device_get_ivars(child);
- struct resource_list_entry *rle;
- uint32_t size;
- uint32_t testval;
- int type;
-
- SLIST_FOREACH(rle, &dinfo->pci.resources, link) {
- if (rle->rid == reg)
- return;
- }
-
- if (reg == CARDBUS_ROM_REG)
- testval = CARDBUS_ROM_ADDRMASK;
- else
- testval = ~0;
-
- pci_write_config(child, reg, testval, 4);
- testval = pci_read_config(child, reg, 4);
-
- if (testval == ~0 || testval == 0)
- return;
-
- if ((testval & 1) == 0)
- type = SYS_RES_MEMORY;
- else
- type = SYS_RES_IOPORT;
-
- size = CARDBUS_MAPREG_MEM_SIZE(testval);
- device_printf(cbdev, "Resource not specified in CIS: id=%x, size=%x\n",
- reg, size);
- resource_list_add(&dinfo->pci.resources, type, reg, 0UL, ~0UL, size);
-}
-
-static void
-cardbus_pickup_maps(device_t cbdev, device_t child)
-{
- struct cardbus_devinfo *dinfo = device_get_ivars(child);
- int reg;
-
- /*
- * Try to pick up any resources that was not specified in CIS.
- * Maybe this isn't any longer necessary now that we have fixed
- * CIS parsing and we should filter things here? XXX
- */
- for (reg = 0; reg < dinfo->pci.cfg.nummaps; reg++)
- cardbus_add_map(cbdev, child, PCIR_BAR(reg));
-}
-
int
cardbus_do_cis(device_t cbdev, device_t child)
{
@@ -1025,6 +714,5 @@ cardbus_do_cis(device_t cbdev, device_t child)
ret = cardbus_parse_cis(cbdev, child, init_callbacks);
if (ret < 0)
return (ret);
- cardbus_pickup_maps(cbdev, child);
- return (cardbus_alloc_resources(cbdev, child));
+ return 0;
}
OpenPOWER on IntegriCloud