Add a sysfs input method for the non-static socket resource database. It works by writing "+ 0x%[l]x - 0x%[l]x" for adding resources, and by "- 0x%[l]x - 0x%[l]x" for removing resources to /sys/class/pcmcia_socket/pcmcia_socket%n/device_possible_resources_{io_mem} Signed-off-by: Dominik Brodowski drivers/pcmcia/rsrc_nostatic.c | 70 +++++++++++++++++++++++++++++++++++++---- 1 files changed, 64 insertions(+), 6 deletions(-) --- linux-original/drivers/pcmcia/rsrc_nostatic.c 2004-11-07 22:12:45.952991168 +0100 +++ linux/drivers/pcmcia/rsrc_nostatic.c 2004-11-07 22:27:52.997099504 +0100 @@ -821,13 +821,13 @@ static ssize_t show_io_db(struct class_device *class_dev, char *buf) { - struct pcmcia_socket *s = class_get_devdata(class_dev); + struct pcmcia_socket *s = class_get_devdata(class_dev); struct socket_data *data; struct resource_map_t *p; ssize_t ret = 0; - data = s->resource_data; down(&rsrc_sem); + data = s->resource_data; for (p = data->io_db.next; p != &data->io_db; p = p->next) { if (ret > (PAGE_SIZE - 10)) @@ -841,17 +841,47 @@ up(&rsrc_sem); return (ret); } -static CLASS_DEVICE_ATTR(device_possible_resources_io, 0400, show_io_db, NULL); + +static ssize_t store_io_db(struct class_device *class_dev, const char *buf, size_t count) +{ + struct pcmcia_socket *s = class_get_devdata(class_dev); + unsigned long start_addr, end_addr; + unsigned int add = 1; + adjust_t adj; + + ssize_t ret = 0; + + ret = sscanf (buf, "+ 0x%lx - 0x%lx\n", &start_addr, &end_addr); + if (ret != 2) { + ret = sscanf (buf, "- 0x%lx - 0x%lx\n", &start_addr, &end_addr); + add = 0; + if (ret != 2) + return -EINVAL; + } + if (end_addr <= start_addr) + return -EINVAL; + + adj.Action = add ? ADD_MANAGED_RESOURCE : REMOVE_MANAGED_RESOURCE; + adj.Resource = RES_IO_RANGE; + adj.resource.io.BasePort = start_addr; + adj.resource.io.NumPorts = end_addr - start_addr + 1; + + ret = adjust_io(s, &adj); + + return ret ? ret : count; +} +static CLASS_DEVICE_ATTR(device_possible_resources_io, 0400, show_io_db, store_io_db); + static ssize_t show_mem_db(struct class_device *class_dev, char *buf) { - struct pcmcia_socket *s = class_get_devdata(class_dev); + struct pcmcia_socket *s = class_get_devdata(class_dev); struct socket_data *data; struct resource_map_t *p; ssize_t ret = 0; - data = s->resource_data; down(&rsrc_sem); + data = s->resource_data; for (p = data->mem_db.next; p != &data->mem_db; p = p->next) { if (ret > (PAGE_SIZE - 10)) @@ -865,7 +895,35 @@ up(&rsrc_sem); return (ret); } -static CLASS_DEVICE_ATTR(device_possible_resources_mem, 0400, show_mem_db, NULL); + +static ssize_t store_mem_db(struct class_device *class_dev, const char *buf, size_t count) +{ + struct pcmcia_socket *s = class_get_devdata(class_dev); + unsigned long start_addr, end_addr; + unsigned int add = 1; + adjust_t adj; + ssize_t ret = 0; + + ret = sscanf (buf, "+ 0x%lx - 0x%lx\n", &start_addr, &end_addr); + if (ret != 2) { + ret = sscanf (buf, "- 0x%lx - 0x%lx\n", &start_addr, &end_addr); + add = 0; + if (ret != 2) + return -EINVAL; + } + if (end_addr <= start_addr) + return -EINVAL; + + adj.Action = add ? ADD_MANAGED_RESOURCE : REMOVE_MANAGED_RESOURCE; + adj.Resource = RES_MEMORY_RANGE; + adj.resource.memory.Base = start_addr; + adj.resource.memory.Size = end_addr - start_addr + 1; + + ret = adjust_memory(s, &adj); + + return ret ? ret : count; +} +static CLASS_DEVICE_ATTR(device_possible_resources_mem, 0400, show_mem_db, store_mem_db); static struct class_device_attribute *pccard_rsrc_attributes[] = { &class_device_attr_device_possible_resources_io,