summaryrefslogtreecommitdiffstats
path: root/sys/pccard/pccard.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/pccard/pccard.c')
-rw-r--r--sys/pccard/pccard.c45
1 files changed, 45 insertions, 0 deletions
diff --git a/sys/pccard/pccard.c b/sys/pccard/pccard.c
index 97c2294..a59133a 100644
--- a/sys/pccard/pccard.c
+++ b/sys/pccard/pccard.c
@@ -460,7 +460,12 @@ crdioctl(dev_t dev, u_long cmd, caddr_t data, int fflag, struct proc *p)
struct slot *slt = pccard_slots[minor(dev)];
struct mem_desc *mp;
struct io_desc *ip;
+ struct pccard_resource *pr;
+ struct resource *r;
+ device_t pcicdev;
int s, err;
+ int rid = 1;
+ int i;
int pwval;
if (slt == 0 && cmd != PIOCRWMEM)
@@ -613,6 +618,46 @@ crdioctl(dev_t dev, u_long cmd, caddr_t data, int fflag, struct proc *p)
return EINVAL;
}
break;
+ case PIOCSRESOURCE:
+ pr = (struct pccard_resource *)data;
+ pr->resource_addr = ~0ul;
+ /*
+ * pccard_devclass does not have soft_c
+ * so we use pcic_devclass
+ */
+ pcicdev = devclass_get_device(pcic_devclass, 0);
+ switch(pr->type) {
+ default:
+ return EINVAL;
+ case SYS_RES_IOPORT:
+ case SYS_RES_MEMORY:
+ for (i = pr->min; i + pr->size <= pr->max; i++) {
+ err = bus_set_resource(pcicdev, pr->type, rid, i, pr->size);
+ if (!err) {
+ r = bus_alloc_resource(pcicdev, pr->type, &rid, 0ul, ~0ul, pr->size, 0);
+ if (r) {
+ pr->resource_addr = (u_long)rman_get_start(r);
+ bus_release_resource(pcicdev, pr->type, rid, r);
+ break;
+ }
+ }
+ }
+ break;
+ case SYS_RES_IRQ:
+ for (i = pr->min; i <= pr->max; i++) {
+ err = bus_set_resource(pcicdev, SYS_RES_IRQ, rid, i, 1);
+ if (!err) {
+ r = bus_alloc_resource(pcicdev, SYS_RES_IRQ, &rid, 0ul, ~0ul, 1, 0);
+ if (r) {
+ pr->resource_addr = (u_long)rman_get_start(r);
+ bus_release_resource(pcicdev, SYS_RES_IRQ, rid, r);
+ break;
+ }
+ }
+ }
+ break;
+ }
+ break;
}
return(0);
}
OpenPOWER on IntegriCloud