summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/dev/cardbus/cardbus.c330
-rw-r--r--sys/dev/cardbus/cardbus_cis.c129
2 files changed, 49 insertions, 410 deletions
diff --git a/sys/dev/cardbus/cardbus.c b/sys/dev/cardbus/cardbus.c
index eddfe61..1559712 100644
--- a/sys/dev/cardbus/cardbus.c
+++ b/sys/dev/cardbus/cardbus.c
@@ -71,40 +71,18 @@ SYSCTL_INT(_hw_cardbus, OID_AUTO, cis_debug, CTLFLAG_RW,
#define DEVPRINTF(x) if (cardbus_debug) device_printf x
-static struct resource *cardbus_alloc_resource(device_t cbdev, device_t child,
- int type, int *rid, u_long start, u_long end, u_long count,
- u_int flags);
static int cardbus_attach(device_t cbdev);
static int cardbus_attach_card(device_t cbdev);
-static void cardbus_delete_resource(device_t cbdev, device_t child,
- int type, int rid);
-static void cardbus_delete_resource_method(device_t cbdev, device_t child,
- int type, int rid);
static int cardbus_detach(device_t cbdev);
static int cardbus_detach_card(device_t cbdev);
static void cardbus_device_setup_regs(device_t brdev, int b, int s, int f,
pcicfgregs *cfg);
static void cardbus_driver_added(device_t cbdev, driver_t *driver);
-static int cardbus_get_resource(device_t cbdev, device_t child, int type,
- int rid, u_long *startp, u_long *countp);
-static int cardbus_get_resource_method(device_t cbdev, device_t child,
- int type, int rid, u_long *startp, u_long *countp);
static int cardbus_probe(device_t cbdev);
static int cardbus_read_ivar(device_t cbdev, device_t child, int which,
uintptr_t *result);
static void cardbus_release_all_resources(device_t cbdev,
struct cardbus_devinfo *dinfo);
-static int cardbus_release_resource(device_t cbdev, device_t child,
- int type, int rid, struct resource *r);
-static int cardbus_set_resource(device_t cbdev, device_t child, int type,
- int rid, u_long start, u_long count, struct resource *res);
-static int cardbus_set_resource_method(device_t cbdev, device_t child,
- int type, int rid, u_long start, u_long count);
-static int cardbus_setup_intr(device_t cbdev, device_t child,
- struct resource *irq, int flags, driver_intr_t *intr,
- void *arg, void **cookiep);
-static int cardbus_teardown_intr(device_t cbdev, device_t child,
- struct resource *irq, void *cookie);
static int cardbus_write_ivar(device_t cbdev, device_t child, int which,
uintptr_t value);
@@ -300,143 +278,6 @@ cardbus_driver_added(device_t cbdev, driver_t *driver)
free(devlist, M_TEMP);
}
-/************************************************************************/
-/* Resources */
-/************************************************************************/
-
-static int
-cardbus_set_resource(device_t cbdev, device_t child, int type, int rid,
- u_long start, u_long count, struct resource *res)
-{
- struct cardbus_devinfo *dinfo;
- struct resource_list *rl;
- struct resource_list_entry *rle;
-
- if (device_get_parent(child) != cbdev)
- return ENOENT;
-
- dinfo = device_get_ivars(child);
- rl = &dinfo->pci.resources;
- rle = resource_list_find(rl, type, rid);
- if (rle == NULL) {
- resource_list_add(rl, type, rid, start, start + count - 1,
- count);
- if (res != NULL) {
- rle = resource_list_find(rl, type, rid);
- rle->res = res;
- }
- } else {
- if (rle->res == NULL) {
- } else if (rman_get_device(rle->res) == cbdev &&
- (!(rman_get_flags(rle->res) & RF_ACTIVE))) {
- int f;
- f = rman_get_flags(rle->res);
- bus_release_resource(cbdev, type, rid, res);
- rle->res = bus_alloc_resource(cbdev, type, &rid,
- start, start + count - 1,
- count, f);
- } else {
- device_printf(cbdev, "set_resource: resource busy\n");
- return EBUSY;
- }
- rle->start = start;
- rle->end = start + count - 1;
- rle->count = count;
- if (res != NULL)
- rle->res = res;
- }
- if (device_get_parent(child) == cbdev)
- pci_write_config(child, rid, start, 4);
- return 0;
-}
-
-static int
-cardbus_get_resource(device_t cbdev, device_t child, int type, int rid,
- u_long *startp, u_long *countp)
-{
- struct cardbus_devinfo *dinfo;
- struct resource_list *rl;
- struct resource_list_entry *rle;
-
- if (device_get_parent(child) != cbdev)
- return ENOENT;
-
- dinfo = device_get_ivars(child);
- rl = &dinfo->pci.resources;
- rle = resource_list_find(rl, type, rid);
- if (!rle)
- return ENOENT;
- if (startp)
- *startp = rle->start;
- if (countp)
- *countp = rle->count;
- return 0;
-}
-
-static void
-cardbus_delete_resource(device_t cbdev, device_t child, int type, int rid)
-{
- struct cardbus_devinfo *dinfo;
- struct resource_list *rl;
- struct resource_list_entry *rle;
-
- if (device_get_parent(child) != cbdev)
- return;
-
- dinfo = device_get_ivars(child);
- rl = &dinfo->pci.resources;
- rle = resource_list_find(rl, type, rid);
- if (rle) {
- if (rle->res) {
- if (rman_get_device(rle->res) != cbdev ||
- rman_get_flags(rle->res) & RF_ACTIVE) {
- device_printf(cbdev, "delete_resource: "
- "Resource still owned by child, oops. "
- "(type=%d, rid=%d, addr=%lx)\n",
- rle->type, rle->rid,
- rman_get_start(rle->res));
- return;
- }
- bus_release_resource(cbdev, type, rid, rle->res);
- }
- resource_list_delete(rl, type, rid);
- }
- if (device_get_parent(child) == cbdev)
- pci_write_config(child, rid, 0, 4);
-}
-
-static int
-cardbus_set_resource_method(device_t cbdev, device_t child, int type, int rid,
- u_long start, u_long count)
-{
- int ret;
- ret = cardbus_set_resource(cbdev, child, type, rid, start, count, NULL);
- if (ret != 0)
- return ret;
- return BUS_SET_RESOURCE(device_get_parent(cbdev), child, type, rid,
- start, count);
-}
-
-static int
-cardbus_get_resource_method(device_t cbdev, device_t child, int type, int rid,
- u_long *startp, u_long *countp)
-{
- int ret;
- ret = cardbus_get_resource(cbdev, child, type, rid, startp, countp);
- if (ret != 0)
- return ret;
- return BUS_GET_RESOURCE(device_get_parent(cbdev), child, type, rid,
- startp, countp);
-}
-
-static void
-cardbus_delete_resource_method(device_t cbdev, device_t child,
- int type, int rid)
-{
- cardbus_delete_resource(cbdev, child, type, rid);
- BUS_DELETE_RESOURCE(device_get_parent(cbdev), child, type, rid);
-}
-
static void
cardbus_release_all_resources(device_t cbdev, struct cardbus_devinfo *dinfo)
{
@@ -464,155 +305,6 @@ cardbus_release_all_resources(device_t cbdev, struct cardbus_devinfo *dinfo)
resource_list_free(&dinfo->pci.resources);
}
-static struct resource *
-cardbus_alloc_resource(device_t cbdev, device_t child, int type,
- int *rid, u_long start, u_long end, u_long count, u_int flags)
-{
- struct cardbus_devinfo *dinfo;
- struct resource_list_entry *rle = 0;
- int passthrough = (device_get_parent(child) != cbdev);
-
- if (passthrough) {
- return (BUS_ALLOC_RESOURCE(device_get_parent(cbdev), child,
- type, rid, start, end, count, flags));
- }
-
- dinfo = device_get_ivars(child);
- rle = resource_list_find(&dinfo->pci.resources, type, *rid);
-
- if (!rle)
- return NULL; /* no resource of that type/rid */
-
- if (!rle->res) {
- device_printf(cbdev, "WARNING: Resource not reserved by bus\n");
- return NULL;
- } else {
- /* Release the cardbus hold on the resource */
- if (rman_get_device(rle->res) != cbdev)
- return NULL;
- bus_release_resource(cbdev, type, *rid, rle->res);
- rle->res = NULL;
- switch (type) {
- case SYS_RES_IOPORT:
- case SYS_RES_MEMORY:
- if (!(flags & RF_ALIGNMENT_MASK))
- flags |= rman_make_alignment_flags(rle->count);
- break;
- case SYS_RES_IRQ:
- flags |= RF_SHAREABLE;
- break;
- }
- /* Allocate the resource to the child */
- return resource_list_alloc(&dinfo->pci.resources, cbdev, child,
- type, rid, rle->start, rle->end, rle->count, flags);
- }
-}
-
-static int
-cardbus_release_resource(device_t cbdev, device_t child, int type, int rid,
- struct resource *r)
-{
- struct cardbus_devinfo *dinfo;
- int passthrough = (device_get_parent(child) != cbdev);
- struct resource_list_entry *rle = 0;
- int flags;
- int ret;
-
- if (passthrough) {
- return BUS_RELEASE_RESOURCE(device_get_parent(cbdev), child,
- type, rid, r);
- }
-
- dinfo = device_get_ivars(child);
- /*
- * According to the PCI 2.2 spec, devices may share an address
- * decoder between memory mapped ROM access and memory
- * mapped register access. To be safe, disable ROM access
- * whenever it is released.
- */
- if (rid == CARDBUS_ROM_REG) {
- uint32_t rom_reg;
-
- rom_reg = pci_read_config(child, rid, 4);
- rom_reg &= ~CARDBUS_ROM_ENABLE;
- pci_write_config(child, rid, rom_reg, 4);
- }
-
- rle = resource_list_find(&dinfo->pci.resources, type, rid);
-
- if (!rle) {
- device_printf(cbdev, "Allocated resource not found\n");
- return ENOENT;
- }
- if (!rle->res) {
- device_printf(cbdev, "Allocated resource not recorded\n");
- return ENOENT;
- }
-
- ret = BUS_RELEASE_RESOURCE(device_get_parent(cbdev), child,
- type, rid, r);
- switch (type) {
- case SYS_RES_IOPORT:
- case SYS_RES_MEMORY:
- flags = rman_make_alignment_flags(rle->count);
- break;
- case SYS_RES_IRQ:
- flags = RF_SHAREABLE;
- break;
- default:
- flags = 0;
- }
- /* Restore cardbus hold on the resource */
- rle->res = bus_alloc_resource(cbdev, type, &rid,
- rle->start, rle->end, rle->count, flags);
- if (rle->res == NULL)
- device_printf(cbdev, "release_resource: "
- "unable to reacquire resource\n");
- return ret;
-}
-
-static int
-cardbus_setup_intr(device_t cbdev, device_t child, struct resource *irq,
- int flags, driver_intr_t *intr, void *arg, void **cookiep)
-{
- int ret;
- device_t cdev;
- struct cardbus_devinfo *dinfo;
-
- ret = bus_generic_setup_intr(cbdev, child, irq, flags, intr, arg,
- cookiep);
- if (ret != 0)
- return ret;
-
- for (cdev = child; cbdev != device_get_parent(cdev);
- cdev = device_get_parent(cdev))
- /* NOTHING */;
- dinfo = device_get_ivars(cdev);
-
- return 0;
-}
-
-static int
-cardbus_teardown_intr(device_t cbdev, device_t child, struct resource *irq,
- void *cookie)
-{
- int ret;
- device_t cdev;
- struct cardbus_devinfo *dinfo;
-
- ret = bus_generic_teardown_intr(cbdev, child, irq, cookie);
- if (ret != 0)
- return ret;
-
- for (cdev = child; cbdev != device_get_parent(cdev);
- cdev = device_get_parent(cdev))
- /* NOTHING */;
- dinfo = device_get_ivars(cdev);
-
- return (0);
-}
-
-
/************************************************************************/
/* Other Bus Methods */
/************************************************************************/
@@ -665,16 +357,18 @@ static device_method_t cardbus_methods[] = {
DEVMETHOD(bus_read_ivar, cardbus_read_ivar),
DEVMETHOD(bus_write_ivar, cardbus_write_ivar),
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, cardbus_setup_intr),
- DEVMETHOD(bus_teardown_intr, cardbus_teardown_intr),
-
- DEVMETHOD(bus_set_resource, cardbus_set_resource_method),
- DEVMETHOD(bus_get_resource, cardbus_get_resource_method),
- DEVMETHOD(bus_delete_resource, cardbus_delete_resource_method),
+ DEVMETHOD(bus_get_resource_list,pci_get_resource_list),
+ DEVMETHOD(bus_set_resource, bus_generic_rl_set_resource),
+ DEVMETHOD(bus_get_resource, bus_generic_rl_get_resource),
+ DEVMETHOD(bus_delete_resource, pci_delete_resource),
+ DEVMETHOD(bus_alloc_resource, pci_alloc_resource),
+ DEVMETHOD(bus_release_resource, bus_generic_rl_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_child_pnpinfo_str, pci_child_pnpinfo_str_method),
DEVMETHOD(bus_child_location_str, pci_child_location_str_method),
@@ -707,7 +401,3 @@ static devclass_t cardbus_devclass;
DRIVER_MODULE(cardbus, cbb, cardbus_driver, cardbus_devclass, 0, 0);
MODULE_VERSION(cardbus, 1);
-MODULE_DEPEND(cardbus, exca, 1, 1, 1);
-/*
-MODULE_DEPEND(cardbus, pccbb, 1, 1, 1);
-*/
diff --git a/sys/dev/cardbus/cardbus_cis.c b/sys/dev/cardbus/cardbus_cis.c
index 2b8e2b2..250ac65 100644
--- a/sys/dev/cardbus/cardbus_cis.c
+++ b/sys/dev/cardbus/cardbus_cis.c
@@ -456,7 +456,6 @@ decode_tuple_bar(device_t cbdev, device_t child, int id,
* device drivers will know which type of BARs can be used.
*/
pci_enable_io(child, type);
-
return (0);
}
@@ -770,6 +769,14 @@ 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)
{
@@ -821,10 +828,11 @@ cardbus_alloc_resources(device_t cbdev, device_t child)
/* Allocate prefetchable memory */
flags = 0;
for (tmp = 0; tmp < count; tmp++) {
- if (barlist[tmp]->res == NULL &&
- barlist[tmp]->type == SYS_RES_MEMORY &&
- dinfo->mprefetchable & BARBIT(barlist[tmp]->rid)) {
- flags = rman_make_alignment_flags(barlist[tmp]->count);
+ 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;
}
}
@@ -850,36 +858,11 @@ cardbus_alloc_resources(device_t cbdev, device_t child)
*/
bus_release_resource(cbdev, SYS_RES_MEMORY, rid, res);
for (tmp = 0; tmp < count; tmp++) {
- if (barlist[tmp]->res == NULL &&
- barlist[tmp]->type == SYS_RES_MEMORY &&
- dinfo->mprefetchable & BARBIT(barlist[tmp]->rid)) {
- barlist[tmp]->res = bus_alloc_resource(cbdev,
- barlist[tmp]->type,
- &barlist[tmp]->rid, start, end,
- barlist[tmp]->count,
- rman_make_alignment_flags(
- barlist[tmp]->count));
- if (barlist[tmp]->res == NULL) {
- mem_nsize += barlist[tmp]->count;
- dinfo->mprefetchable &=
- ~BARBIT(barlist[tmp]->rid);
- DEVPRINTF((cbdev, "Cannot pre-allocate "
- "prefetchable memory, will try as "
- "non-prefetchable.\n"));
- } else {
- barlist[tmp]->start =
- rman_get_start(barlist[tmp]->res);
- barlist[tmp]->end =
- rman_get_end(barlist[tmp]->res);
- pci_write_config(child,
- barlist[tmp]->rid,
- barlist[tmp]->start, 4);
- DEVPRINTF((cbdev, "Prefetchable memory "
- "rid=%x at %lx-%lx\n",
- barlist[tmp]->rid,
- barlist[tmp]->start,
- barlist[tmp]->end));
- }
+ rle = barlist[tmp];
+ if (rle->type == SYS_RES_MEMORY &&
+ dinfo->mprefetchable & BARBIT(rle->rid)) {
+ cardbus_do_res(rle, child, start);
+ start += rle->count;
}
}
}
@@ -887,9 +870,10 @@ cardbus_alloc_resources(device_t cbdev, device_t child)
/* Allocate non-prefetchable memory */
flags = 0;
for (tmp = 0; tmp < count; tmp++) {
- if (barlist[tmp]->res == NULL &&
- barlist[tmp]->type == SYS_RES_MEMORY) {
- flags = rman_make_alignment_flags(barlist[tmp]->count);
+ rle = barlist[tmp];
+ if (rle->type == SYS_RES_MEMORY &&
+ (dinfo->mprefetchable & BARBIT(rle->rid)) == 0) {
+ flags = rman_make_alignment_flags(rle->count);
break;
}
}
@@ -916,29 +900,11 @@ cardbus_alloc_resources(device_t cbdev, device_t child)
*/
bus_release_resource(cbdev, SYS_RES_MEMORY, rid, res);
for (tmp = 0; tmp < count; tmp++) {
- if (barlist[tmp]->res == NULL &&
- barlist[tmp]->type == SYS_RES_MEMORY) {
- barlist[tmp]->res = bus_alloc_resource(cbdev,
- barlist[tmp]->type, &barlist[tmp]->rid,
- start, end, barlist[tmp]->count,
- rman_make_alignment_flags(
- barlist[tmp]->count));
- if (barlist[tmp]->res == NULL) {
- DEVPRINTF((cbdev, "Cannot pre-allocate "
- "memory for cardbus device\n"));
- free(barlist, M_DEVBUF);
- return (ENOMEM);
- }
- barlist[tmp]->start =
- rman_get_start(barlist[tmp]->res);
- barlist[tmp]->end = rman_get_end(
- barlist[tmp]->res);
- pci_write_config(child, barlist[tmp]->rid,
- barlist[tmp]->start, 4);
- DEVPRINTF((cbdev, "Non-prefetchable memory "
- "rid=%x at %lx-%lx (%lx)\n",
- barlist[tmp]->rid, barlist[tmp]->start,
- barlist[tmp]->end, barlist[tmp]->count));
+ rle = barlist[tmp];
+ if (rle->type == SYS_RES_MEMORY &&
+ (dinfo->mprefetchable & BARBIT(rle->rid)) == 0) {
+ cardbus_do_res(rle, child, start);
+ start += rle->count;
}
}
}
@@ -946,9 +912,9 @@ cardbus_alloc_resources(device_t cbdev, device_t child)
/* Allocate IO ports */
flags = 0;
for (tmp = 0; tmp < count; tmp++) {
- if (barlist[tmp]->res == NULL &&
- barlist[tmp]->type == SYS_RES_IOPORT) {
- flags = rman_make_alignment_flags(barlist[tmp]->count);
+ rle = barlist[tmp];
+ if (rle->type == SYS_RES_IOPORT) {
+ flags = rman_make_alignment_flags(rle->count);
break;
}
}
@@ -973,28 +939,10 @@ cardbus_alloc_resources(device_t cbdev, device_t child)
*/
bus_release_resource(cbdev, SYS_RES_IOPORT, rid, res);
for (tmp = 0; tmp < count; tmp++) {
- if (barlist[tmp]->res == NULL &&
- barlist[tmp]->type == SYS_RES_IOPORT) {
- barlist[tmp]->res = bus_alloc_resource(cbdev,
- barlist[tmp]->type, &barlist[tmp]->rid,
- start, end, barlist[tmp]->count,
- rman_make_alignment_flags(
- barlist[tmp]->count));
- if (barlist[tmp]->res == NULL) {
- DEVPRINTF((cbdev, "Cannot pre-allocate "
- "IO port for cardbus device\n"));
- free(barlist, M_DEVBUF);
- return (ENOMEM);
- }
- barlist[tmp]->start =
- rman_get_start(barlist[tmp]->res);
- barlist[tmp]->end =
- rman_get_end(barlist[tmp]->res);
- pci_write_config(child, barlist[tmp]->rid,
- barlist[tmp]->start, 4);
- DEVPRINTF((cbdev, "IO port rid=%x at %lx-%lx\n",
- barlist[tmp]->rid, barlist[tmp]->start,
- barlist[tmp]->end));
+ rle = barlist[tmp];
+ if (rle->type == SYS_RES_IOPORT) {
+ cardbus_do_res(rle, child, start);
+ start += rle->count;
}
}
}
@@ -1003,10 +951,11 @@ cardbus_alloc_resources(device_t cbdev, device_t child)
rid = 0;
res = bus_alloc_resource(cbdev, SYS_RES_IRQ, &rid, 0, ~0UL, 1,
RF_SHAREABLE);
- resource_list_add(&dinfo->pci.resources, SYS_RES_IRQ, rid,
- rman_get_start(res), rman_get_end(res), 1);
- rle = resource_list_find(&dinfo->pci.resources, SYS_RES_IRQ, rid);
- rle->res = res;
+ 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);
OpenPOWER on IntegriCloud