Currently, only those mem resources are validated which are already
registered at the time the first PCMCIA card is inserted. As we can
only validate resources immediately after card insert, store
"registered" mem resources in mem_db, and only upon validation move
them to mem_db_valid. When allocationg mem resources, mem_db_valid is
then preferred to mem_db.
Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
struct socket_data {
struct resource_map mem_db;
struct socket_data {
struct resource_map mem_db;
+ struct resource_map mem_db_valid;
struct resource_map io_db;
struct resource_map io_db;
- unsigned int rsrc_mem_probe;
};
#define MEM_PROBE_LOW (1 << 0)
};
#define MEM_PROBE_LOW (1 << 0)
struct resource *res,
unsigned int *value))
{
struct resource *res,
unsigned int *value))
{
+ struct socket_data *s_data = s->resource_data;
struct resource *res1, *res2;
unsigned int info1 = 1, info2 = 1;
int ret = -EINVAL;
struct resource *res1, *res2;
unsigned int info1 = 1, info2 = 1;
int ret = -EINVAL;
if ((ret) || (info1 != info2) || (info1 == 0))
return -EINVAL;
if ((ret) || (info1 != info2) || (info1 == 0))
return -EINVAL;
+ if (validate && !s->fake_cis) {
+ /* move it to the validated data set */
+ add_interval(&s_data->mem_db_valid, base, size);
+ sub_interval(&s_data->mem_db, base, size);
+ }
+
if (probe_mask & MEM_PROBE_HIGH) {
if (inv_probe(s_data->mem_db.next, s) > 0)
return 0;
if (probe_mask & MEM_PROBE_HIGH) {
if (inv_probe(s_data->mem_db.next, s) > 0)
return 0;
+ if (s_data->mem_db_valid.next != &s_data->mem_db_valid)
+ return 0;
dev_printk(KERN_NOTICE, &s->dev,
"cs: warning: no high memory space available!\n");
return -ENODEV;
dev_printk(KERN_NOTICE, &s->dev,
"cs: warning: no high memory space available!\n");
return -ENODEV;
{
struct socket_data *s_data = s->resource_data;
unsigned int probe_mask = MEM_PROBE_LOW;
{
struct socket_data *s_data = s->resource_data;
unsigned int probe_mask = MEM_PROBE_LOW;
+ if (!probe_mem || !(s->state & SOCKET_PRESENT))
return 0;
if (s->features & SS_CAP_PAGE_REGS)
probe_mask = MEM_PROBE_HIGH;
return 0;
if (s->features & SS_CAP_PAGE_REGS)
probe_mask = MEM_PROBE_HIGH;
- if (probe_mask & ~s_data->rsrc_mem_probe) {
- if (s->state & SOCKET_PRESENT) {
- ret = validate_mem(s, probe_mask);
- if (!ret)
- s_data->rsrc_mem_probe |= probe_mask;
- }
- }
+ ret = validate_mem(s, probe_mask);
+
+ if (s_data->mem_db_valid.next != &s_data->mem_db_valid)
+ return 0;
struct socket_data *s_data = s->resource_data;
struct pcmcia_align_data data;
unsigned long min, max;
struct socket_data *s_data = s->resource_data;
struct pcmcia_align_data data;
unsigned long min, max;
low = low || !(s->features & SS_CAP_PAGE_REGS);
data.mask = align - 1;
data.offset = base & data.mask;
low = low || !(s->features & SS_CAP_PAGE_REGS);
data.mask = align - 1;
data.offset = base & data.mask;
- data.map = &s_data->mem_db;
for (i = 0; i < 2; i++) {
for (i = 0; i < 2; i++) {
+ data.map = &s_data->mem_db_valid;
if (low) {
max = 0x100000UL;
min = base < max ? base : 0;
if (low) {
max = 0x100000UL;
min = base < max ? base : 0;
min = 0x100000UL + base;
}
min = 0x100000UL + base;
}
+ for (j = 0; j < 2; j++) {
- if (s->cb_dev) {
- ret = pci_bus_alloc_resource(s->cb_dev->bus, res, num,
- 1, min, 0,
- pcmcia_align, &data);
- } else
+ if (s->cb_dev) {
+ ret = pci_bus_alloc_resource(s->cb_dev->bus,
+ res, num, 1, min, 0,
+ pcmcia_align, &data);
+ } else
- ret = allocate_resource(&iomem_resource, res, num, min,
- max, 1, pcmcia_align, &data);
+ {
+ ret = allocate_resource(&iomem_resource,
+ res, num, min, max, 1,
+ pcmcia_align, &data);
+ }
+ if (ret == 0)
+ break;
+ data.map = &s_data->mem_db;
+ }
if (ret == 0 || low)
break;
low = 1;
if (ret == 0 || low)
break;
low = 1;
return -ENOMEM;
data->mem_db.next = &data->mem_db;
return -ENOMEM;
data->mem_db.next = &data->mem_db;
+ data->mem_db_valid.next = &data->mem_db_valid;
data->io_db.next = &data->io_db;
s->resource_data = (void *) data;
data->io_db.next = &data->io_db;
s->resource_data = (void *) data;
struct socket_data *data = s->resource_data;
struct resource_map *p, *q;
struct socket_data *data = s->resource_data;
struct resource_map *p, *q;
+ for (p = data->mem_db_valid.next; p != &data->mem_db_valid; p = q) {
+ q = p->next;
+ kfree(p);
+ }
for (p = data->mem_db.next; p != &data->mem_db; p = q) {
q = p->next;
kfree(p);
for (p = data->mem_db.next; p != &data->mem_db; p = q) {
q = p->next;
kfree(p);
mutex_lock(&s->ops_mutex);
data = s->resource_data;
mutex_lock(&s->ops_mutex);
data = s->resource_data;
+ for (p = data->mem_db_valid.next; p != &data->mem_db_valid;
+ p = p->next) {
+ if (ret > (PAGE_SIZE - 10))
+ continue;
+ ret += snprintf(&buf[ret], (PAGE_SIZE - ret - 1),
+ "0x%08lx - 0x%08lx\n",
+ ((unsigned long) p->base),
+ ((unsigned long) p->base + p->num - 1));
+ }
+
for (p = data->mem_db.next; p != &data->mem_db; p = p->next) {
if (ret > (PAGE_SIZE - 10))
continue;
for (p = data->mem_db.next; p != &data->mem_db; p = p->next) {
if (ret > (PAGE_SIZE - 10))
continue;