diff options
Diffstat (limited to 'sys/pccard/pccard.c')
-rw-r--r-- | sys/pccard/pccard.c | 138 |
1 files changed, 63 insertions, 75 deletions
diff --git a/sys/pccard/pccard.c b/sys/pccard/pccard.c index 98a820e..6abc141 100644 --- a/sys/pccard/pccard.c +++ b/sys/pccard/pccard.c @@ -34,6 +34,7 @@ #include "opt_pcic.h" #include <sys/param.h> +#include <sys/types.h> #include <sys/systm.h> #include <sys/kernel.h> #include <sys/malloc.h> @@ -52,16 +53,6 @@ #include <machine/md_var.h> -/* - * XXX We shouldn't be using processor-specific/bus-specific code in - * here, but we need the start of the ISA hole (IOM_BEGIN). - */ -#ifdef PC98 -#include <pc98/pc98/pc98.h> -#else -#include <i386/isa/isa.h> -#endif - SYSCTL_NODE(_machdep, OID_AUTO, pccard, CTLFLAG_RW, 0, "pccard"); static int pcic_resume_reset = 1; @@ -69,15 +60,12 @@ static int pcic_resume_reset = 1; SYSCTL_INT(_machdep_pccard, OID_AUTO, pcic_resume_reset, CTLFLAG_RW, &pcic_resume_reset, 0, ""); -#define PCCARD_MEMSIZE (4*1024) - #define MIN(a,b) ((a)<(b)?(a):(b)) static int allocate_driver(struct slot *, struct dev_desc *); static void inserted(void *); static void disable_slot(struct slot *); static void disable_slot_to(struct slot *); -static int invalid_io_memory(unsigned long, int); static void power_off_slot(void *); static struct slot *pccard_slots[MAXSLOT]; /* slot entries */ @@ -87,8 +75,11 @@ static struct slot *pccard_slots[MAXSLOT]; /* slot entries */ * of memory in the ISA I/O memory space allocated via * an ioctl setting. */ +/* XXX this should be in pcic */ static unsigned long pccard_mem; /* Physical memory */ static unsigned char *pccard_kmem; /* Kernel virtual address */ +static struct resource *pccard_mem_res; +static int pccard_mem_rid; static d_open_t crdopen; static d_close_t crdclose; @@ -449,6 +440,49 @@ crdwrite(dev_t dev, struct uio *uio, int ioflag) return(error); } +static int +crdioctl_sresource(dev_t dev, caddr_t data) +{ + struct pccard_resource *pr; + struct resource *r; + device_t pcicdev; + int i; + int rid = 1; + int err; + + 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_MEMORY: + case SYS_RES_IRQ: + case SYS_RES_IOPORT: + break; + } + for (i = pr->min; i + pr->size - 1 <= pr->max; i++) { + /* already allocated to pcic? */ + if (bus_get_resource_start(pcicdev, pr->type, 0) == i) + continue; + err = bus_set_resource(pcicdev, pr->type, rid, i, pr->size); + if (err != 0) + continue; + r = bus_alloc_resource(pcicdev, pr->type, &rid, 0ul, ~0ul, + pr->size, 0); + if (r == NULL) + continue; + pr->resource_addr = (u_long)rman_get_start(r); + bus_release_resource(pcicdev, pr->type, rid, r); + return (0); + } + return (0); +} + /* * ioctl calls - allows setting/getting of memory and I/O * descriptors, and assignment of drivers. @@ -459,13 +493,10 @@ 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; + u_int32_t addr; if (slt == 0 && cmd != PIOCRWMEM) return(ENXIO); @@ -548,15 +579,13 @@ crdioctl(dev_t dev, u_long cmd, caddr_t data, int fflag, struct proc *p) case PIOCRWFLAG: slt->rwmem = *(int *)data; break; -#ifndef __alpha__ /* * Set the memory window to be used for the read/write interface. * Not available on the alpha. */ case PIOCRWMEM: if (*(unsigned long *)data == 0) { - if (pccard_mem) - *(unsigned long *)data = pccard_mem; + *(unsigned long *)data = pccard_mem; break; } if (suser(p)) @@ -565,19 +594,22 @@ crdioctl(dev_t dev, u_long cmd, caddr_t data, int fflag, struct proc *p) * Validate the memory by checking it against the I/O * memory range. It must also start on an aligned block size. */ - if (invalid_io_memory(*(unsigned long *)data, PCCARD_MEMSIZE)) - return(EINVAL); if (*(unsigned long *)data & (PCCARD_MEMSIZE-1)) return(EINVAL); - /* - * Map it to kernel VM. - */ - pccard_mem = *(unsigned long *)data; - pccard_kmem = - (unsigned char *)(void *)(uintptr_t) - (pccard_mem + atdevbase - IOM_BEGIN); + pcicdev = devclass_get_device(pcic_devclass, 0); + pccard_mem_rid = 0; + addr = *(unsigned long *)data; + if (pccard_mem_res) + bus_release_resource(pcicdev, SYS_RES_MEMORY, + pccard_mem_rid, pccard_mem_res); + pccard_mem_res = bus_alloc_resource(pcicdev, SYS_RES_MEMORY, + &pccard_mem_rid, addr, addr, PCCARD_MEMSIZE, + RF_ACTIVE | rman_make_alignment_flags(PCCARD_MEMSIZE)); + if (pccard_mem_res == NULL) + return(EINVAL); + pccard_mem = rman_get_start(pccard_mem_res); + pccard_kmem = rman_get_virtual(pccard_mem_res); break; -#endif /* * Set power values. */ @@ -618,35 +650,7 @@ crdioctl(dev_t dev, u_long cmd, caddr_t data, int fflag, struct proc *p) } 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: - case SYS_RES_IRQ: - for (i = pr->min; i + pr->size - 1 <= pr->max; i++) { - /* already allocated to pcic? */ - if (bus_get_resource_start(pcicdev, pr->type, 0) == i) - continue; - 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; - } + return (crdioctl_sresource(dev, data)); break; } return(0); @@ -684,22 +688,6 @@ crdpoll(dev_t dev, int events, struct proc *p) return (revents); } -/* - * invalid_io_memory - verify that the ISA I/O memory block - * is a valid and unallocated address. - * A simple check of the range is done, and then a - * search of the current devices is done to check for - * overlapping regions. - */ -static int -invalid_io_memory(unsigned long adr, int size) -{ - /* XXX - What's magic about 0xC0000?? */ - if (adr < 0xC0000 || (adr+size) > IOM_END) - return(1); - return(0); -} - static struct slot * pccard_dev2slot(device_t dev) { |