mirror of
https://git.hardenedbsd.org/hardenedbsd/HardenedBSD.git
synced 2024-11-15 23:05:49 +01:00
add PIOCSRESOURCE(IOC_GET_RESOURCE_RANGE)
Now /usr/sbin/pccardd read free resource(io,irq) range with this ioctl. Original Idea from: PAO3
This commit is contained in:
parent
df6bd679e7
commit
5935ef4c44
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=65991
@ -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.
|
||||
*/
|
||||
@ -136,6 +137,18 @@ struct power {
|
||||
int vpp;
|
||||
};
|
||||
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -37,6 +37,7 @@ static const char rcsid[] =
|
||||
#include <fcntl.h>
|
||||
#include <ctype.h>
|
||||
#include <regex.h>
|
||||
#include <machine/resource.h>
|
||||
#include <sys/ioctl.h>
|
||||
#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;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user