From 62e0e10410c07cfb086acfffd093bbecd52cff35 Mon Sep 17 00:00:00 2001 From: sanpei Date: Sun, 17 Sep 2000 15:37:53 +0000 Subject: add PIOCSRESOURCE(IOC_GET_RESOURCE_RANGE) Now /usr/sbin/pccardd read free resource(io,irq) range with this ioctl. Original Idea from: PAO3 --- sys/pccard/cardinfo.h | 13 ++++++++++++ sys/pccard/pccard.c | 45 +++++++++++++++++++++++++++++++++++++++++ sys/pccard/pcic.h | 1 + usr.sbin/pccard/pccardd/cardd.c | 41 ++++++++++++++++++++++++++++++++----- 4 files changed, 95 insertions(+), 5 deletions(-) diff --git a/sys/pccard/cardinfo.h b/sys/pccard/cardinfo.h index f71cd6f..3f8ffce 100644 --- a/sys/pccard/cardinfo.h +++ b/sys/pccard/cardinfo.h @@ -49,6 +49,7 @@ #define PIOCSPOW _IOW('P', 9, struct power) /* Set power structure */ #define PIOCSVIR _IOW('P', 10, int) /* Virtual insert/remove */ #define PIOCSBEEP _IOW('P', 11, int) /* Select Beep */ +#define PIOCSRESOURCE _IOWR('P', 12, struct pccard_resource) /* get resource info */ /* * Debug codes. */ @@ -137,6 +138,18 @@ struct power { }; /* + * Th PC-Card resource IOC_GET_RESOURCE_RANGE + */ +struct pccard_resource { + int type; + u_long size; + u_long min; + u_long max; + u_long resource_addr; +}; + + +/* * Other system limits */ #define MAXSLOT 16 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); } diff --git a/sys/pccard/pcic.h b/sys/pccard/pcic.h index b8b6d23..c8a2457 100644 --- a/sys/pccard/pcic.h +++ b/sys/pccard/pcic.h @@ -41,3 +41,4 @@ #define PCIC_RF_MDF_WS1 (0x08 << 16) #define PCIC_RF_MDF_ATTR (0x10 << 16) #define PCIC_RF_MDF_WP (0x20 << 16) +extern devclass_t pcic_devclass; diff --git a/usr.sbin/pccard/pccardd/cardd.c b/usr.sbin/pccard/pccardd/cardd.c index e68182a..3a7153d 100644 --- a/usr.sbin/pccard/pccardd/cardd.c +++ b/usr.sbin/pccard/pccardd/cardd.c @@ -37,6 +37,7 @@ static const char rcsid[] = #include #include #include +#include #include #include "cardd.h" @@ -486,13 +487,29 @@ assign_driver(struct card *cp) } /* Allocate a free IRQ if none has been specified */ if (conf->irq == 0) { - int i; - for (i = 1; i < 16; i++) - if (pool_irq[i]) { + struct pccard_resource resource; + char name[128]; + int i, fd; + + sprintf(name, CARD_DEVICE, 0); /* XXX sanpei */ + fd = open(name, O_RDWR); + + resource.type = SYS_RES_IRQ; + resource.size = 1; + for (i = 1; i < 16; i++) { + resource.min = i; + resource.max = i; + if (ioctl(fd, PIOCSRESOURCE, &resource) < 0) { + perror("ioctl (PIOCSRESOURCE)"); + exit(1); + } + if (pool_irq[i] && resource.resource_addr == i) { conf->irq = i; pool_irq[i] = 0; break; } + } + close(fd); if (conf->irq == 0) { logmsg("Failed to allocate IRQ for %s\n", cp->manuf); return (NULL); @@ -513,19 +530,33 @@ assign_card_index(struct cis * cis) { struct cis_config *cp; struct cis_ioblk *cio; - int i; + struct pccard_resource resource; + char name[128]; + int i, fd; + + sprintf(name, CARD_DEVICE, 0); /* XXX sanpei */ + fd = open(name, O_RDWR); + resource.type = SYS_RES_IOPORT; for (cp = cis->conf; cp; cp = cp->next) { if (!cp->iospace || !cp->io) continue; for (cio = cp->io; cio; cio = cio->next) { + resource.size = cio->size; for (i = cio->addr; i < cio->addr + cio->size - 1; i++) - if (!bit_test(io_avail, i)) + resource.min = i; + resource.max = resource.min + cio->size - 1; + if (ioctl(fd, PIOCSRESOURCE, &resource) < 0) { + perror("ioctl (PIOCSRESOURCE)"); + exit(1); + } + if (!bit_test(io_avail, i) || resource.resource_addr != i) goto next; } return cp; /* found */ next: } + close(fd); return cis->def_config; } -- cgit v1.1