summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorimp <imp@FreeBSD.org>2001-03-26 08:05:20 +0000
committerimp <imp@FreeBSD.org>2001-03-26 08:05:20 +0000
commitf828dc3f2f7d66be243c4e79988d6260b9544d9d (patch)
tree86ab5515ce3ff44d7daf3df5cf334ff8a557fc76
parent67e856d53e2fe31a60ac85723ca9aceb19995186 (diff)
downloadFreeBSD-src-f828dc3f2f7d66be243c4e79988d6260b9544d9d.zip
FreeBSD-src-f828dc3f2f7d66be243c4e79988d6260b9544d9d.tar.gz
First step towards plugging the "pccard is trying to map into a BIOS
region for CIS reading" problem: Use bus_alloc_resource to get the memory that we'll be using. Also has the benefit of doing usage checking as well. This gets rid of the ugly kludge that we had before for mapping pmem to vmem. Second, move PIOCSRESOURCE to its own routine and make it conform more to style(9) in the process.
-rw-r--r--sys/pccard/cardinfo.h1
-rw-r--r--sys/pccard/pccard.c138
2 files changed, 64 insertions, 75 deletions
diff --git a/sys/pccard/cardinfo.h b/sys/pccard/cardinfo.h
index ff5d7fc..4224d48 100644
--- a/sys/pccard/cardinfo.h
+++ b/sys/pccard/cardinfo.h
@@ -156,5 +156,6 @@ struct pccard_resource {
#define NUM_MEM_WINDOWS 10
#define NUM_IO_WINDOWS 6
#define CARD_DEVICE "/dev/card%d" /* String for snprintf */
+#define PCCARD_MEMSIZE (4*1024)
#endif /* !_PCCARD_CARDINFO_H_ */
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)
{
OpenPOWER on IntegriCloud