diff options
Diffstat (limited to 'drivers/pnp/interface.c')
| -rw-r--r-- | drivers/pnp/interface.c | 155 |
1 files changed, 99 insertions, 56 deletions
diff --git a/drivers/pnp/interface.c b/drivers/pnp/interface.c index 68b0c04987e..e6c403be09a 100644 --- a/drivers/pnp/interface.c +++ b/drivers/pnp/interface.c @@ -203,8 +203,8 @@ static void pnp_print_option(pnp_info_buffer_t * buffer, char *space, } } -static ssize_t pnp_show_options(struct device *dmdev, - struct device_attribute *attr, char *buf) +static ssize_t options_show(struct device *dmdev, struct device_attribute *attr, + char *buf) { struct pnp_dev *dev = to_pnp_dev(dmdev); pnp_info_buffer_t *buffer; @@ -241,10 +241,10 @@ static ssize_t pnp_show_options(struct device *dmdev, kfree(buffer); return ret; } +static DEVICE_ATTR_RO(options); -static ssize_t pnp_show_current_resources(struct device *dmdev, - struct device_attribute *attr, - char *buf) +static ssize_t resources_show(struct device *dmdev, + struct device_attribute *attr, char *buf) { struct pnp_dev *dev = to_pnp_dev(dmdev); pnp_info_buffer_t *buffer; @@ -278,9 +278,12 @@ static ssize_t pnp_show_current_resources(struct device *dmdev, switch (pnp_resource_type(res)) { case IORESOURCE_IO: case IORESOURCE_MEM: - pnp_printf(buffer, " %#llx-%#llx\n", + case IORESOURCE_BUS: + pnp_printf(buffer, " %#llx-%#llx%s\n", (unsigned long long) res->start, - (unsigned long long) res->end); + (unsigned long long) res->end, + res->flags & IORESOURCE_WINDOW ? + " window" : ""); break; case IORESOURCE_IRQ: case IORESOURCE_DMA: @@ -295,14 +298,46 @@ static ssize_t pnp_show_current_resources(struct device *dmdev, return ret; } -static ssize_t pnp_set_current_resources(struct device *dmdev, - struct device_attribute *attr, - const char *ubuf, size_t count) +static char *pnp_get_resource_value(char *buf, + unsigned long type, + resource_size_t *start, + resource_size_t *end, + unsigned long *flags) +{ + if (start) + *start = 0; + if (end) + *end = 0; + if (flags) + *flags = 0; + + /* TBD: allow for disabled resources */ + + buf = skip_spaces(buf); + if (start) { + *start = simple_strtoull(buf, &buf, 0); + if (end) { + buf = skip_spaces(buf); + if (*buf == '-') { + buf = skip_spaces(buf + 1); + *end = simple_strtoull(buf, &buf, 0); + } else + *end = *start; + } + } + + /* TBD: allow for additional flags, e.g., IORESOURCE_WINDOW */ + + return buf; +} + +static ssize_t resources_store(struct device *dmdev, + struct device_attribute *attr, const char *ubuf, + size_t count) { struct pnp_dev *dev = to_pnp_dev(dmdev); char *buf = (void *)ubuf; int retval = 0; - resource_size_t start, end; if (dev->status & PNP_ATTACHED) { retval = -EBUSY; @@ -346,6 +381,10 @@ static ssize_t pnp_set_current_resources(struct device *dmdev, goto done; } if (!strnicmp(buf, "set", 3)) { + resource_size_t start; + resource_size_t end; + unsigned long flags; + if (dev->active) goto done; buf += 3; @@ -354,42 +393,37 @@ static ssize_t pnp_set_current_resources(struct device *dmdev, while (1) { buf = skip_spaces(buf); if (!strnicmp(buf, "io", 2)) { - buf = skip_spaces(buf + 2); - start = simple_strtoul(buf, &buf, 0); - buf = skip_spaces(buf); - if (*buf == '-') { - buf = skip_spaces(buf + 1); - end = simple_strtoul(buf, &buf, 0); - } else - end = start; - pnp_add_io_resource(dev, start, end, 0); - continue; - } - if (!strnicmp(buf, "mem", 3)) { - buf = skip_spaces(buf + 3); - start = simple_strtoul(buf, &buf, 0); - buf = skip_spaces(buf); - if (*buf == '-') { - buf = skip_spaces(buf + 1); - end = simple_strtoul(buf, &buf, 0); - } else - end = start; - pnp_add_mem_resource(dev, start, end, 0); - continue; - } - if (!strnicmp(buf, "irq", 3)) { - buf = skip_spaces(buf + 3); - start = simple_strtoul(buf, &buf, 0); - pnp_add_irq_resource(dev, start, 0); - continue; - } - if (!strnicmp(buf, "dma", 3)) { - buf = skip_spaces(buf + 3); - start = simple_strtoul(buf, &buf, 0); - pnp_add_dma_resource(dev, start, 0); - continue; - } - break; + buf = pnp_get_resource_value(buf + 2, + IORESOURCE_IO, + &start, &end, + &flags); + pnp_add_io_resource(dev, start, end, flags); + } else if (!strnicmp(buf, "mem", 3)) { + buf = pnp_get_resource_value(buf + 3, + IORESOURCE_MEM, + &start, &end, + &flags); + pnp_add_mem_resource(dev, start, end, flags); + } else if (!strnicmp(buf, "irq", 3)) { + buf = pnp_get_resource_value(buf + 3, + IORESOURCE_IRQ, + &start, NULL, + &flags); + pnp_add_irq_resource(dev, start, flags); + } else if (!strnicmp(buf, "dma", 3)) { + buf = pnp_get_resource_value(buf + 3, + IORESOURCE_DMA, + &start, NULL, + &flags); + pnp_add_dma_resource(dev, start, flags); + } else if (!strnicmp(buf, "bus", 3)) { + buf = pnp_get_resource_value(buf + 3, + IORESOURCE_BUS, + &start, &end, + NULL); + pnp_add_bus_resource(dev, start, end); + } else + break; } mutex_unlock(&pnp_res_mutex); goto done; @@ -400,9 +434,10 @@ done: return retval; return count; } +static DEVICE_ATTR_RW(resources); -static ssize_t pnp_show_current_ids(struct device *dmdev, - struct device_attribute *attr, char *buf) +static ssize_t id_show(struct device *dmdev, struct device_attribute *attr, + char *buf) { char *str = buf; struct pnp_dev *dev = to_pnp_dev(dmdev); @@ -414,12 +449,20 @@ static ssize_t pnp_show_current_ids(struct device *dmdev, } return (str - buf); } +static DEVICE_ATTR_RO(id); + +static struct attribute *pnp_dev_attrs[] = { + &dev_attr_resources.attr, + &dev_attr_options.attr, + &dev_attr_id.attr, + NULL, +}; + +static const struct attribute_group pnp_dev_group = { + .attrs = pnp_dev_attrs, +}; -struct device_attribute pnp_interface_attrs[] = { - __ATTR(resources, S_IRUGO | S_IWUSR, - pnp_show_current_resources, - pnp_set_current_resources), - __ATTR(options, S_IRUGO, pnp_show_options, NULL), - __ATTR(id, S_IRUGO, pnp_show_current_ids, NULL), - __ATTR_NULL, +const struct attribute_group *pnp_dev_groups[] = { + &pnp_dev_group, + NULL, }; |
