X-Git-Url: http://ftp.safe.ca/?a=blobdiff_plain;f=drivers%2Fpnp%2Finterface.c;h=c3f1c8e9d2545a4859d984ed7237455ec8e8ca36;hb=b31d0fde89c905673ceed0404d5ae24f2261d7c7;hp=ac9fcd499f3f0cb9912dee2e1400e6f1f519aad3;hpb=bfc7ee207078e8ca51264355805e6f56b485be4b;p=safe%2Fjmp%2Flinux-2.6 diff --git a/drivers/pnp/interface.c b/drivers/pnp/interface.c index ac9fcd4..c3f1c8e 100644 --- a/drivers/pnp/interface.c +++ b/drivers/pnp/interface.c @@ -1,9 +1,10 @@ /* * interface.c - contains everything related to the user interface * - * Some code, especially possible resource dumping is based on isapnp_proc.c (c) Jaroslav Kysela + * Some code, especially possible resource dumping is based on isapnp_proc.c (c) Jaroslav Kysela * Copyright 2002 Adam Belay - * + * Copyright (C) 2008 Hewlett-Packard Development Company, L.P. + * Bjorn Helgaas */ #include @@ -14,6 +15,8 @@ #include #include #include +#include + #include #include "base.h" @@ -29,7 +32,7 @@ struct pnp_info_buffer { typedef struct pnp_info_buffer pnp_info_buffer_t; -static int pnp_printf(pnp_info_buffer_t * buffer, char *fmt,...) +static int pnp_printf(pnp_info_buffer_t * buffer, char *fmt, ...) { va_list args; int res; @@ -48,20 +51,26 @@ static int pnp_printf(pnp_info_buffer_t * buffer, char *fmt,...) return res; } -static void pnp_print_port(pnp_info_buffer_t *buffer, char *space, struct pnp_port *port) +static void pnp_print_port(pnp_info_buffer_t * buffer, char *space, + struct pnp_port *port) { - pnp_printf(buffer, "%sport 0x%x-0x%x, align 0x%x, size 0x%x, %i-bit address decoding\n", - space, port->min, port->max, port->align ? (port->align-1) : 0, port->size, - port->flags & PNP_PORT_FLAG_16BITADDR ? 16 : 10); + pnp_printf(buffer, "%sport %#llx-%#llx, align %#llx, size %#llx, " + "%i-bit address decoding\n", space, + (unsigned long long) port->min, + (unsigned long long) port->max, + port->align ? ((unsigned long long) port->align - 1) : 0, + (unsigned long long) port->size, + port->flags & IORESOURCE_IO_16BIT_ADDR ? 16 : 10); } -static void pnp_print_irq(pnp_info_buffer_t *buffer, char *space, struct pnp_irq *irq) +static void pnp_print_irq(pnp_info_buffer_t * buffer, char *space, + struct pnp_irq *irq) { int first = 1, i; pnp_printf(buffer, "%sirq ", space); for (i = 0; i < PNP_IRQ_NR; i++) - if (test_bit(i, irq->map)) { + if (test_bit(i, irq->map.bits)) { if (!first) { pnp_printf(buffer, ","); } else { @@ -72,7 +81,7 @@ static void pnp_print_irq(pnp_info_buffer_t *buffer, char *space, struct pnp_irq else pnp_printf(buffer, "%i", i); } - if (bitmap_empty(irq->map, PNP_IRQ_NR)) + if (bitmap_empty(irq->map.bits, PNP_IRQ_NR)) pnp_printf(buffer, ""); if (irq->flags & IORESOURCE_IRQ_HIGHEDGE) pnp_printf(buffer, " High-Edge"); @@ -82,17 +91,20 @@ static void pnp_print_irq(pnp_info_buffer_t *buffer, char *space, struct pnp_irq pnp_printf(buffer, " High-Level"); if (irq->flags & IORESOURCE_IRQ_LOWLEVEL) pnp_printf(buffer, " Low-Level"); + if (irq->flags & IORESOURCE_IRQ_OPTIONAL) + pnp_printf(buffer, " (optional)"); pnp_printf(buffer, "\n"); } -static void pnp_print_dma(pnp_info_buffer_t *buffer, char *space, struct pnp_dma *dma) +static void pnp_print_dma(pnp_info_buffer_t * buffer, char *space, + struct pnp_dma *dma) { int first = 1, i; char *s; pnp_printf(buffer, "%sdma ", space); for (i = 0; i < 8; i++) - if (dma->map & (1<map & (1 << i)) { if (!first) { pnp_printf(buffer, ","); } else { @@ -136,12 +148,16 @@ static void pnp_print_dma(pnp_info_buffer_t *buffer, char *space, struct pnp_dma pnp_printf(buffer, " %s\n", s); } -static void pnp_print_mem(pnp_info_buffer_t *buffer, char *space, struct pnp_mem *mem) +static void pnp_print_mem(pnp_info_buffer_t * buffer, char *space, + struct pnp_mem *mem) { char *s; - pnp_printf(buffer, "%sMemory 0x%x-0x%x, align 0x%x, size 0x%x", - space, mem->min, mem->max, mem->align, mem->size); + pnp_printf(buffer, "%sMemory %#llx-%#llx, align %#llx, size %#llx", + space, (unsigned long long) mem->min, + (unsigned long long) mem->max, + (unsigned long long) mem->align, + (unsigned long long) mem->size); if (mem->flags & IORESOURCE_MEM_WRITEABLE) pnp_printf(buffer, ", writeable"); if (mem->flags & IORESOURCE_MEM_CACHEABLE) @@ -168,312 +184,258 @@ static void pnp_print_mem(pnp_info_buffer_t *buffer, char *space, struct pnp_mem pnp_printf(buffer, ", %s\n", s); } -static void pnp_print_option(pnp_info_buffer_t *buffer, char *space, - struct pnp_option *option, int dep) +static void pnp_print_option(pnp_info_buffer_t * buffer, char *space, + struct pnp_option *option) { - char *s; - struct pnp_port *port; - struct pnp_irq *irq; - struct pnp_dma *dma; - struct pnp_mem *mem; - - if (dep) { - switch (option->priority) { - case PNP_RES_PRIORITY_PREFERRED: - s = "preferred"; - break; - case PNP_RES_PRIORITY_ACCEPTABLE: - s = "acceptable"; - break; - case PNP_RES_PRIORITY_FUNCTIONAL: - s = "functional"; - break; - default: - s = "invalid"; - } - pnp_printf(buffer, "Dependent: %02i - Priority %s\n",dep, s); + switch (option->type) { + case IORESOURCE_IO: + pnp_print_port(buffer, space, &option->u.port); + break; + case IORESOURCE_MEM: + pnp_print_mem(buffer, space, &option->u.mem); + break; + case IORESOURCE_IRQ: + pnp_print_irq(buffer, space, &option->u.irq); + break; + case IORESOURCE_DMA: + pnp_print_dma(buffer, space, &option->u.dma); + break; } - - for (port = option->port; port; port = port->next) - pnp_print_port(buffer, space, port); - for (irq = option->irq; irq; irq = irq->next) - pnp_print_irq(buffer, space, irq); - for (dma = option->dma; dma; dma = dma->next) - pnp_print_dma(buffer, space, dma); - for (mem = option->mem; mem; mem = mem->next) - pnp_print_mem(buffer, space, mem); } - -static ssize_t pnp_show_options(struct device *dmdev, struct device_attribute *attr, char *buf) +static ssize_t pnp_show_options(struct device *dmdev, + struct device_attribute *attr, char *buf) { struct pnp_dev *dev = to_pnp_dev(dmdev); - struct pnp_option * independent = dev->independent; - struct pnp_option * dependent = dev->dependent; - int ret, dep = 1; + pnp_info_buffer_t *buffer; + struct pnp_option *option; + int ret, dep = 0, set = 0; + char *indent; - pnp_info_buffer_t *buffer = (pnp_info_buffer_t *) - pnp_alloc(sizeof(pnp_info_buffer_t)); + buffer = pnp_alloc(sizeof(pnp_info_buffer_t)); if (!buffer) return -ENOMEM; buffer->len = PAGE_SIZE; buffer->buffer = buf; buffer->curr = buffer->buffer; - if (independent) - pnp_print_option(buffer, "", independent, 0); - while (dependent){ - pnp_print_option(buffer, " ", dependent, dep); - dependent = dependent->next; - dep++; + list_for_each_entry(option, &dev->options, list) { + if (pnp_option_is_dependent(option)) { + indent = " "; + if (!dep || pnp_option_set(option) != set) { + set = pnp_option_set(option); + dep = 1; + pnp_printf(buffer, "Dependent: %02i - " + "Priority %s\n", set, + pnp_option_priority_name(option)); + } + } else { + dep = 0; + indent = ""; + } + pnp_print_option(buffer, indent, option); } + ret = (buffer->curr - buf); kfree(buffer); return ret; } -static DEVICE_ATTR(options,S_IRUGO,pnp_show_options,NULL); - - -static ssize_t pnp_show_current_resources(struct device *dmdev, struct device_attribute *attr, char *buf) +static ssize_t pnp_show_current_resources(struct device *dmdev, + struct device_attribute *attr, + char *buf) { struct pnp_dev *dev = to_pnp_dev(dmdev); - int i, ret; pnp_info_buffer_t *buffer; + struct pnp_resource *pnp_res; + struct resource *res; + int ret; if (!dev) return -EINVAL; - buffer = (pnp_info_buffer_t *) pnp_alloc(sizeof(pnp_info_buffer_t)); + buffer = pnp_alloc(sizeof(pnp_info_buffer_t)); if (!buffer) return -ENOMEM; + buffer->len = PAGE_SIZE; buffer->buffer = buf; buffer->curr = buffer->buffer; - pnp_printf(buffer,"state = "); - if (dev->active) - pnp_printf(buffer,"active\n"); - else - pnp_printf(buffer,"disabled\n"); - - for (i = 0; i < PNP_MAX_PORT; i++) { - if (pnp_port_valid(dev, i)) { - pnp_printf(buffer,"io"); - if (pnp_port_flags(dev, i) & IORESOURCE_DISABLED) - pnp_printf(buffer," disabled\n"); - else - pnp_printf(buffer," 0x%llx-0x%llx\n", - (unsigned long long)pnp_port_start(dev, i), - (unsigned long long)pnp_port_end(dev, i)); - } - } - for (i = 0; i < PNP_MAX_MEM; i++) { - if (pnp_mem_valid(dev, i)) { - pnp_printf(buffer,"mem"); - if (pnp_mem_flags(dev, i) & IORESOURCE_DISABLED) - pnp_printf(buffer," disabled\n"); - else - pnp_printf(buffer," 0x%llx-0x%llx\n", - (unsigned long long)pnp_mem_start(dev, i), - (unsigned long long)pnp_mem_end(dev, i)); - } - } - for (i = 0; i < PNP_MAX_IRQ; i++) { - if (pnp_irq_valid(dev, i)) { - pnp_printf(buffer,"irq"); - if (pnp_irq_flags(dev, i) & IORESOURCE_DISABLED) - pnp_printf(buffer," disabled\n"); - else - pnp_printf(buffer," %lld\n", - (unsigned long long)pnp_irq(dev, i)); + pnp_printf(buffer, "state = %s\n", dev->active ? "active" : "disabled"); + + list_for_each_entry(pnp_res, &dev->resources, list) { + res = &pnp_res->res; + + pnp_printf(buffer, pnp_resource_type_name(res)); + + if (res->flags & IORESOURCE_DISABLED) { + pnp_printf(buffer, " disabled\n"); + continue; } - } - for (i = 0; i < PNP_MAX_DMA; i++) { - if (pnp_dma_valid(dev, i)) { - pnp_printf(buffer,"dma"); - if (pnp_dma_flags(dev, i) & IORESOURCE_DISABLED) - pnp_printf(buffer," disabled\n"); - else - pnp_printf(buffer," %lld\n", - (unsigned long long)pnp_dma(dev, i)); + + switch (pnp_resource_type(res)) { + case IORESOURCE_IO: + case IORESOURCE_MEM: + pnp_printf(buffer, " %#llx-%#llx\n", + (unsigned long long) res->start, + (unsigned long long) res->end); + break; + case IORESOURCE_IRQ: + case IORESOURCE_DMA: + pnp_printf(buffer, " %lld\n", + (unsigned long long) res->start); + break; } } + ret = (buffer->curr - buf); kfree(buffer); return ret; } -extern struct semaphore pnp_res_mutex; - -static ssize_t -pnp_set_current_resources(struct device * dmdev, struct device_attribute *attr, const char * ubuf, size_t count) +static ssize_t pnp_set_current_resources(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; + char *buf = (void *)ubuf; + int retval = 0; + resource_size_t start, end; if (dev->status & PNP_ATTACHED) { retval = -EBUSY; - pnp_info("Device %s cannot be configured because it is in use.", dev->dev.bus_id); + dev_info(&dev->dev, "in use; can't configure\n"); goto done; } while (isspace(*buf)) ++buf; - if (!strnicmp(buf,"disable",7)) { + if (!strnicmp(buf, "disable", 7)) { retval = pnp_disable_dev(dev); goto done; } - if (!strnicmp(buf,"activate",8)) { + if (!strnicmp(buf, "activate", 8)) { retval = pnp_activate_dev(dev); goto done; } - if (!strnicmp(buf,"fill",4)) { + if (!strnicmp(buf, "fill", 4)) { if (dev->active) goto done; retval = pnp_auto_config_dev(dev); goto done; } - if (!strnicmp(buf,"auto",4)) { + if (!strnicmp(buf, "auto", 4)) { if (dev->active) goto done; - pnp_init_resource_table(&dev->res); + pnp_init_resources(dev); retval = pnp_auto_config_dev(dev); goto done; } - if (!strnicmp(buf,"clear",5)) { + if (!strnicmp(buf, "clear", 5)) { if (dev->active) goto done; - pnp_init_resource_table(&dev->res); + pnp_init_resources(dev); goto done; } - if (!strnicmp(buf,"get",3)) { - down(&pnp_res_mutex); + if (!strnicmp(buf, "get", 3)) { + mutex_lock(&pnp_res_mutex); if (pnp_can_read(dev)) - dev->protocol->get(dev, &dev->res); - up(&pnp_res_mutex); + dev->protocol->get(dev); + mutex_unlock(&pnp_res_mutex); goto done; } - if (!strnicmp(buf,"set",3)) { - int nport = 0, nmem = 0, nirq = 0, ndma = 0; + if (!strnicmp(buf, "set", 3)) { if (dev->active) goto done; buf += 3; - pnp_init_resource_table(&dev->res); - down(&pnp_res_mutex); + pnp_init_resources(dev); + mutex_lock(&pnp_res_mutex); while (1) { while (isspace(*buf)) ++buf; - if (!strnicmp(buf,"io",2)) { + if (!strnicmp(buf, "io", 2)) { buf += 2; while (isspace(*buf)) ++buf; - dev->res.port_resource[nport].start = simple_strtoul(buf,&buf,0); + start = simple_strtoul(buf, &buf, 0); while (isspace(*buf)) ++buf; - if(*buf == '-') { + if (*buf == '-') { buf += 1; while (isspace(*buf)) ++buf; - dev->res.port_resource[nport].end = simple_strtoul(buf,&buf,0); + end = simple_strtoul(buf, &buf, 0); } else - dev->res.port_resource[nport].end = dev->res.port_resource[nport].start; - dev->res.port_resource[nport].flags = IORESOURCE_IO; - nport++; - if (nport >= PNP_MAX_PORT) - break; + end = start; + pnp_add_io_resource(dev, start, end, 0); continue; } - if (!strnicmp(buf,"mem",3)) { + if (!strnicmp(buf, "mem", 3)) { buf += 3; while (isspace(*buf)) ++buf; - dev->res.mem_resource[nmem].start = simple_strtoul(buf,&buf,0); + start = simple_strtoul(buf, &buf, 0); while (isspace(*buf)) ++buf; - if(*buf == '-') { + if (*buf == '-') { buf += 1; while (isspace(*buf)) ++buf; - dev->res.mem_resource[nmem].end = simple_strtoul(buf,&buf,0); + end = simple_strtoul(buf, &buf, 0); } else - dev->res.mem_resource[nmem].end = dev->res.mem_resource[nmem].start; - dev->res.mem_resource[nmem].flags = IORESOURCE_MEM; - nmem++; - if (nmem >= PNP_MAX_MEM) - break; + end = start; + pnp_add_mem_resource(dev, start, end, 0); continue; } - if (!strnicmp(buf,"irq",3)) { + if (!strnicmp(buf, "irq", 3)) { buf += 3; while (isspace(*buf)) ++buf; - dev->res.irq_resource[nirq].start = - dev->res.irq_resource[nirq].end = simple_strtoul(buf,&buf,0); - dev->res.irq_resource[nirq].flags = IORESOURCE_IRQ; - nirq++; - if (nirq >= PNP_MAX_IRQ) - break; + start = simple_strtoul(buf, &buf, 0); + pnp_add_irq_resource(dev, start, 0); continue; } - if (!strnicmp(buf,"dma",3)) { + if (!strnicmp(buf, "dma", 3)) { buf += 3; while (isspace(*buf)) ++buf; - dev->res.dma_resource[ndma].start = - dev->res.dma_resource[ndma].end = simple_strtoul(buf,&buf,0); - dev->res.dma_resource[ndma].flags = IORESOURCE_DMA; - ndma++; - if (ndma >= PNP_MAX_DMA) - break; + start = simple_strtoul(buf, &buf, 0); + pnp_add_dma_resource(dev, start, 0); continue; } break; } - up(&pnp_res_mutex); + mutex_unlock(&pnp_res_mutex); goto done; } - done: + +done: if (retval < 0) return retval; return count; } -static DEVICE_ATTR(resources,S_IRUGO | S_IWUSR, - pnp_show_current_resources,pnp_set_current_resources); - -static ssize_t pnp_show_current_ids(struct device *dmdev, struct device_attribute *attr, char *buf) +static ssize_t pnp_show_current_ids(struct device *dmdev, + struct device_attribute *attr, char *buf) { char *str = buf; struct pnp_dev *dev = to_pnp_dev(dmdev); - struct pnp_id * pos = dev->id; + struct pnp_id *pos = dev->id; while (pos) { - str += sprintf(str,"%s\n", pos->id); + str += sprintf(str, "%s\n", pos->id); pos = pos->next; } return (str - buf); } -static DEVICE_ATTR(id,S_IRUGO,pnp_show_current_ids,NULL); - -int pnp_interface_attach_device(struct pnp_dev *dev) -{ - int rc = device_create_file(&dev->dev,&dev_attr_options); - if (rc) goto err; - rc = device_create_file(&dev->dev,&dev_attr_resources); - if (rc) goto err_opt; - rc = device_create_file(&dev->dev,&dev_attr_id); - if (rc) goto err_res; - - return 0; - -err_res: - device_remove_file(&dev->dev,&dev_attr_resources); -err_opt: - device_remove_file(&dev->dev,&dev_attr_options); -err: - return rc; -} +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, +};