base, base+num-1);
bad = fail = 0;
step = (num < 0x20000) ? 0x2000 : ((num>>4) & ~0x1fff);
+ /* don't allow too large steps */
+ if (step > 0x800000)
+ step = 0x800000;
/* cis_readable wants to map 2x map_size */
if (step < 2 * s->map_size)
step = 2 * s->map_size;
for (m = s_data->mem_db.next; m != &s_data->mem_db; m = mm.next) {
mm = *m;
- if (do_mem_probe(mm.base, mm.num, s))
- break;
+ do_mem_probe(mm.base, mm.num, s);
}
}
unsigned long size = end - start + 1;
int ret = 0;
- if (end <= start)
+ if (end < start)
return -EINVAL;
down(&rsrc_sem);
unsigned long size = end - start + 1;
int ret = 0;
- if (end <= start)
+ if (end < start)
return -EINVAL;
if (end > IO_SPACE_LIMIT)
return CS_UNSUPPORTED_FUNCTION;
}
+#ifdef CONFIG_PCI
+static int nonstatic_autoadd_resources(struct pcmcia_socket *s)
+{
+ struct resource *res;
+ int i, done = 0;
+
+ if (!s->cb_dev || !s->cb_dev->bus)
+ return -ENODEV;
+
+#if defined(CONFIG_X86)
+ /* If this is the root bus, the risk of hitting
+ * some strange system devices which aren't protected
+ * by either ACPI resource tables or properly requested
+ * resources is too big. Therefore, don't do auto-adding
+ * of resources at the moment.
+ */
+ if (s->cb_dev->bus->number == 0)
+ return -EINVAL;
+#endif
+
+ for (i=0; i < PCI_BUS_NUM_RESOURCES; i++) {
+ res = s->cb_dev->bus->resource[i];
+ if (!res)
+ continue;
+
+ if (res->flags & IORESOURCE_IO) {
+ if (res == &ioport_resource)
+ continue;
+ printk(KERN_INFO "pcmcia: parent PCI bridge I/O window: 0x%lx - 0x%lx\n",
+ res->start, res->end);
+ if (!adjust_io(s, ADD_MANAGED_RESOURCE, res->start, res->end))
+ done |= IORESOURCE_IO;
+
+ }
+
+ if (res->flags & IORESOURCE_MEM) {
+ if (res == &iomem_resource)
+ continue;
+ printk(KERN_INFO "pcmcia: parent PCI bridge Memory window: 0x%lx - 0x%lx\n",
+ res->start, res->end);
+ if (!adjust_memory(s, ADD_MANAGED_RESOURCE, res->start, res->end))
+ done |= IORESOURCE_MEM;
+ }
+ }
+
+ /* if we got at least one of IO, and one of MEM, we can be glad and
+ * activate the PCMCIA subsystem */
+ if (done == (IORESOURCE_MEM | IORESOURCE_IO))
+ s->resource_setup_done = 1;
+
+ return 0;
+}
+
+#else
+
+static inline int nonstatic_autoadd_resources(struct pcmcia_socket *s)
+{
+ return -ENODEV;
+}
+
+#endif
+
+
static int nonstatic_init(struct pcmcia_socket *s)
{
struct socket_data *data;
s->resource_data = (void *) data;
+ nonstatic_autoadd_resources(s);
+
return 0;
}
return -EINVAL;
}
}
- if (end_addr <= start_addr)
+ if (end_addr < start_addr)
return -EINVAL;
ret = adjust_io(s, add, start_addr, end_addr);
+ if (!ret)
+ s->resource_setup_new = 1;
return ret ? ret : count;
}
return -EINVAL;
}
}
- if (end_addr <= start_addr)
+ if (end_addr < start_addr)
return -EINVAL;
ret = adjust_memory(s, add, start_addr, end_addr);
+ if (!ret)
+ s->resource_setup_new = 1;
return ret ? ret : count;
}
NULL,
};
-static int __devinit pccard_sysfs_add_rsrc(struct class_device *class_dev)
+static int __devinit pccard_sysfs_add_rsrc(struct class_device *class_dev,
+ struct class_interface *class_intf)
{
struct pcmcia_socket *s = class_get_devdata(class_dev);
struct class_device_attribute **attr;
return ret;
}
-static void __devexit pccard_sysfs_remove_rsrc(struct class_device *class_dev)
+static void __devexit pccard_sysfs_remove_rsrc(struct class_device *class_dev,
+ struct class_interface *class_intf)
{
struct pcmcia_socket *s = class_get_devdata(class_dev);
struct class_device_attribute **attr;