diff options
Diffstat (limited to 'sys/pccard/pccard.c')
-rw-r--r-- | sys/pccard/pccard.c | 45 |
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); } |