0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include <linux/pnp.h>
0012 #include <linux/string.h>
0013 #include <linux/errno.h>
0014 #include <linux/list.h>
0015 #include <linux/types.h>
0016 #include <linux/stat.h>
0017 #include <linux/ctype.h>
0018 #include <linux/slab.h>
0019 #include <linux/mutex.h>
0020
0021 #include <linux/uaccess.h>
0022
0023 #include "base.h"
0024
0025 struct pnp_info_buffer {
0026 char *buffer;
0027 char *curr;
0028 unsigned long size;
0029 unsigned long len;
0030 int stop;
0031 int error;
0032 };
0033
0034 typedef struct pnp_info_buffer pnp_info_buffer_t;
0035
0036 __printf(2, 3)
0037 static int pnp_printf(pnp_info_buffer_t * buffer, char *fmt, ...)
0038 {
0039 va_list args;
0040 int res;
0041
0042 if (buffer->stop || buffer->error)
0043 return 0;
0044 va_start(args, fmt);
0045 res = vsnprintf(buffer->curr, buffer->len - buffer->size, fmt, args);
0046 va_end(args);
0047 if (buffer->size + res >= buffer->len) {
0048 buffer->stop = 1;
0049 return 0;
0050 }
0051 buffer->curr += res;
0052 buffer->size += res;
0053 return res;
0054 }
0055
0056 static void pnp_print_port(pnp_info_buffer_t * buffer, char *space,
0057 struct pnp_port *port)
0058 {
0059 pnp_printf(buffer, "%sport %#llx-%#llx, align %#llx, size %#llx, "
0060 "%i-bit address decoding\n", space,
0061 (unsigned long long) port->min,
0062 (unsigned long long) port->max,
0063 port->align ? ((unsigned long long) port->align - 1) : 0,
0064 (unsigned long long) port->size,
0065 port->flags & IORESOURCE_IO_16BIT_ADDR ? 16 : 10);
0066 }
0067
0068 static void pnp_print_irq(pnp_info_buffer_t * buffer, char *space,
0069 struct pnp_irq *irq)
0070 {
0071 int first = 1, i;
0072
0073 pnp_printf(buffer, "%sirq ", space);
0074 for (i = 0; i < PNP_IRQ_NR; i++)
0075 if (test_bit(i, irq->map.bits)) {
0076 if (!first) {
0077 pnp_printf(buffer, ",");
0078 } else {
0079 first = 0;
0080 }
0081 if (i == 2 || i == 9)
0082 pnp_printf(buffer, "2/9");
0083 else
0084 pnp_printf(buffer, "%i", i);
0085 }
0086 if (bitmap_empty(irq->map.bits, PNP_IRQ_NR))
0087 pnp_printf(buffer, "<none>");
0088 if (irq->flags & IORESOURCE_IRQ_HIGHEDGE)
0089 pnp_printf(buffer, " High-Edge");
0090 if (irq->flags & IORESOURCE_IRQ_LOWEDGE)
0091 pnp_printf(buffer, " Low-Edge");
0092 if (irq->flags & IORESOURCE_IRQ_HIGHLEVEL)
0093 pnp_printf(buffer, " High-Level");
0094 if (irq->flags & IORESOURCE_IRQ_LOWLEVEL)
0095 pnp_printf(buffer, " Low-Level");
0096 if (irq->flags & IORESOURCE_IRQ_OPTIONAL)
0097 pnp_printf(buffer, " (optional)");
0098 pnp_printf(buffer, "\n");
0099 }
0100
0101 static void pnp_print_dma(pnp_info_buffer_t * buffer, char *space,
0102 struct pnp_dma *dma)
0103 {
0104 int first = 1, i;
0105 char *s;
0106
0107 pnp_printf(buffer, "%sdma ", space);
0108 for (i = 0; i < 8; i++)
0109 if (dma->map & (1 << i)) {
0110 if (!first) {
0111 pnp_printf(buffer, ",");
0112 } else {
0113 first = 0;
0114 }
0115 pnp_printf(buffer, "%i", i);
0116 }
0117 if (!dma->map)
0118 pnp_printf(buffer, "<none>");
0119 switch (dma->flags & IORESOURCE_DMA_TYPE_MASK) {
0120 case IORESOURCE_DMA_8BIT:
0121 s = "8-bit";
0122 break;
0123 case IORESOURCE_DMA_8AND16BIT:
0124 s = "8-bit&16-bit";
0125 break;
0126 default:
0127 s = "16-bit";
0128 }
0129 pnp_printf(buffer, " %s", s);
0130 if (dma->flags & IORESOURCE_DMA_MASTER)
0131 pnp_printf(buffer, " master");
0132 if (dma->flags & IORESOURCE_DMA_BYTE)
0133 pnp_printf(buffer, " byte-count");
0134 if (dma->flags & IORESOURCE_DMA_WORD)
0135 pnp_printf(buffer, " word-count");
0136 switch (dma->flags & IORESOURCE_DMA_SPEED_MASK) {
0137 case IORESOURCE_DMA_TYPEA:
0138 s = "type-A";
0139 break;
0140 case IORESOURCE_DMA_TYPEB:
0141 s = "type-B";
0142 break;
0143 case IORESOURCE_DMA_TYPEF:
0144 s = "type-F";
0145 break;
0146 default:
0147 s = "compatible";
0148 break;
0149 }
0150 pnp_printf(buffer, " %s\n", s);
0151 }
0152
0153 static void pnp_print_mem(pnp_info_buffer_t * buffer, char *space,
0154 struct pnp_mem *mem)
0155 {
0156 char *s;
0157
0158 pnp_printf(buffer, "%sMemory %#llx-%#llx, align %#llx, size %#llx",
0159 space, (unsigned long long) mem->min,
0160 (unsigned long long) mem->max,
0161 (unsigned long long) mem->align,
0162 (unsigned long long) mem->size);
0163 if (mem->flags & IORESOURCE_MEM_WRITEABLE)
0164 pnp_printf(buffer, ", writeable");
0165 if (mem->flags & IORESOURCE_MEM_CACHEABLE)
0166 pnp_printf(buffer, ", cacheable");
0167 if (mem->flags & IORESOURCE_MEM_RANGELENGTH)
0168 pnp_printf(buffer, ", range-length");
0169 if (mem->flags & IORESOURCE_MEM_SHADOWABLE)
0170 pnp_printf(buffer, ", shadowable");
0171 if (mem->flags & IORESOURCE_MEM_EXPANSIONROM)
0172 pnp_printf(buffer, ", expansion ROM");
0173 switch (mem->flags & IORESOURCE_MEM_TYPE_MASK) {
0174 case IORESOURCE_MEM_8BIT:
0175 s = "8-bit";
0176 break;
0177 case IORESOURCE_MEM_8AND16BIT:
0178 s = "8-bit&16-bit";
0179 break;
0180 case IORESOURCE_MEM_32BIT:
0181 s = "32-bit";
0182 break;
0183 default:
0184 s = "16-bit";
0185 }
0186 pnp_printf(buffer, ", %s\n", s);
0187 }
0188
0189 static void pnp_print_option(pnp_info_buffer_t * buffer, char *space,
0190 struct pnp_option *option)
0191 {
0192 switch (option->type) {
0193 case IORESOURCE_IO:
0194 pnp_print_port(buffer, space, &option->u.port);
0195 break;
0196 case IORESOURCE_MEM:
0197 pnp_print_mem(buffer, space, &option->u.mem);
0198 break;
0199 case IORESOURCE_IRQ:
0200 pnp_print_irq(buffer, space, &option->u.irq);
0201 break;
0202 case IORESOURCE_DMA:
0203 pnp_print_dma(buffer, space, &option->u.dma);
0204 break;
0205 }
0206 }
0207
0208 static ssize_t options_show(struct device *dmdev, struct device_attribute *attr,
0209 char *buf)
0210 {
0211 struct pnp_dev *dev = to_pnp_dev(dmdev);
0212 pnp_info_buffer_t *buffer;
0213 struct pnp_option *option;
0214 int ret, dep = 0, set = 0;
0215 char *indent;
0216
0217 buffer = kzalloc(sizeof(*buffer), GFP_KERNEL);
0218 if (!buffer)
0219 return -ENOMEM;
0220
0221 buffer->len = PAGE_SIZE;
0222 buffer->buffer = buf;
0223 buffer->curr = buffer->buffer;
0224
0225 list_for_each_entry(option, &dev->options, list) {
0226 if (pnp_option_is_dependent(option)) {
0227 indent = " ";
0228 if (!dep || pnp_option_set(option) != set) {
0229 set = pnp_option_set(option);
0230 dep = 1;
0231 pnp_printf(buffer, "Dependent: %02i - "
0232 "Priority %s\n", set,
0233 pnp_option_priority_name(option));
0234 }
0235 } else {
0236 dep = 0;
0237 indent = "";
0238 }
0239 pnp_print_option(buffer, indent, option);
0240 }
0241
0242 ret = (buffer->curr - buf);
0243 kfree(buffer);
0244 return ret;
0245 }
0246 static DEVICE_ATTR_RO(options);
0247
0248 static ssize_t resources_show(struct device *dmdev,
0249 struct device_attribute *attr, char *buf)
0250 {
0251 struct pnp_dev *dev = to_pnp_dev(dmdev);
0252 pnp_info_buffer_t *buffer;
0253 struct pnp_resource *pnp_res;
0254 struct resource *res;
0255 int ret;
0256
0257 if (!dev)
0258 return -EINVAL;
0259
0260 buffer = kzalloc(sizeof(*buffer), GFP_KERNEL);
0261 if (!buffer)
0262 return -ENOMEM;
0263
0264 buffer->len = PAGE_SIZE;
0265 buffer->buffer = buf;
0266 buffer->curr = buffer->buffer;
0267
0268 pnp_printf(buffer, "state = %s\n", dev->active ? "active" : "disabled");
0269
0270 list_for_each_entry(pnp_res, &dev->resources, list) {
0271 res = &pnp_res->res;
0272
0273 pnp_printf(buffer, pnp_resource_type_name(res));
0274
0275 if (res->flags & IORESOURCE_DISABLED) {
0276 pnp_printf(buffer, " disabled\n");
0277 continue;
0278 }
0279
0280 switch (pnp_resource_type(res)) {
0281 case IORESOURCE_IO:
0282 case IORESOURCE_MEM:
0283 case IORESOURCE_BUS:
0284 pnp_printf(buffer, " %#llx-%#llx%s\n",
0285 (unsigned long long) res->start,
0286 (unsigned long long) res->end,
0287 res->flags & IORESOURCE_WINDOW ?
0288 " window" : "");
0289 break;
0290 case IORESOURCE_IRQ:
0291 case IORESOURCE_DMA:
0292 pnp_printf(buffer, " %lld\n",
0293 (unsigned long long) res->start);
0294 break;
0295 }
0296 }
0297
0298 ret = (buffer->curr - buf);
0299 kfree(buffer);
0300 return ret;
0301 }
0302
0303 static char *pnp_get_resource_value(char *buf,
0304 unsigned long type,
0305 resource_size_t *start,
0306 resource_size_t *end,
0307 unsigned long *flags)
0308 {
0309 if (start)
0310 *start = 0;
0311 if (end)
0312 *end = 0;
0313 if (flags)
0314 *flags = 0;
0315
0316
0317
0318 buf = skip_spaces(buf);
0319 if (start) {
0320 *start = simple_strtoull(buf, &buf, 0);
0321 if (end) {
0322 buf = skip_spaces(buf);
0323 if (*buf == '-') {
0324 buf = skip_spaces(buf + 1);
0325 *end = simple_strtoull(buf, &buf, 0);
0326 } else
0327 *end = *start;
0328 }
0329 }
0330
0331
0332
0333 return buf;
0334 }
0335
0336 static ssize_t resources_store(struct device *dmdev,
0337 struct device_attribute *attr, const char *ubuf,
0338 size_t count)
0339 {
0340 struct pnp_dev *dev = to_pnp_dev(dmdev);
0341 char *buf = (void *)ubuf;
0342 int retval = 0;
0343
0344 if (dev->status & PNP_ATTACHED) {
0345 retval = -EBUSY;
0346 dev_info(&dev->dev, "in use; can't configure\n");
0347 goto done;
0348 }
0349
0350 buf = skip_spaces(buf);
0351 if (!strncasecmp(buf, "disable", 7)) {
0352 retval = pnp_disable_dev(dev);
0353 goto done;
0354 }
0355 if (!strncasecmp(buf, "activate", 8)) {
0356 retval = pnp_activate_dev(dev);
0357 goto done;
0358 }
0359 if (!strncasecmp(buf, "fill", 4)) {
0360 if (dev->active)
0361 goto done;
0362 retval = pnp_auto_config_dev(dev);
0363 goto done;
0364 }
0365 if (!strncasecmp(buf, "auto", 4)) {
0366 if (dev->active)
0367 goto done;
0368 pnp_init_resources(dev);
0369 retval = pnp_auto_config_dev(dev);
0370 goto done;
0371 }
0372 if (!strncasecmp(buf, "clear", 5)) {
0373 if (dev->active)
0374 goto done;
0375 pnp_init_resources(dev);
0376 goto done;
0377 }
0378 if (!strncasecmp(buf, "get", 3)) {
0379 mutex_lock(&pnp_res_mutex);
0380 if (pnp_can_read(dev))
0381 dev->protocol->get(dev);
0382 mutex_unlock(&pnp_res_mutex);
0383 goto done;
0384 }
0385 if (!strncasecmp(buf, "set", 3)) {
0386 resource_size_t start;
0387 resource_size_t end;
0388 unsigned long flags;
0389
0390 if (dev->active)
0391 goto done;
0392 buf += 3;
0393 pnp_init_resources(dev);
0394 mutex_lock(&pnp_res_mutex);
0395 while (1) {
0396 buf = skip_spaces(buf);
0397 if (!strncasecmp(buf, "io", 2)) {
0398 buf = pnp_get_resource_value(buf + 2,
0399 IORESOURCE_IO,
0400 &start, &end,
0401 &flags);
0402 pnp_add_io_resource(dev, start, end, flags);
0403 } else if (!strncasecmp(buf, "mem", 3)) {
0404 buf = pnp_get_resource_value(buf + 3,
0405 IORESOURCE_MEM,
0406 &start, &end,
0407 &flags);
0408 pnp_add_mem_resource(dev, start, end, flags);
0409 } else if (!strncasecmp(buf, "irq", 3)) {
0410 buf = pnp_get_resource_value(buf + 3,
0411 IORESOURCE_IRQ,
0412 &start, NULL,
0413 &flags);
0414 pnp_add_irq_resource(dev, start, flags);
0415 } else if (!strncasecmp(buf, "dma", 3)) {
0416 buf = pnp_get_resource_value(buf + 3,
0417 IORESOURCE_DMA,
0418 &start, NULL,
0419 &flags);
0420 pnp_add_dma_resource(dev, start, flags);
0421 } else if (!strncasecmp(buf, "bus", 3)) {
0422 buf = pnp_get_resource_value(buf + 3,
0423 IORESOURCE_BUS,
0424 &start, &end,
0425 NULL);
0426 pnp_add_bus_resource(dev, start, end);
0427 } else
0428 break;
0429 }
0430 mutex_unlock(&pnp_res_mutex);
0431 goto done;
0432 }
0433
0434 done:
0435 if (retval < 0)
0436 return retval;
0437 return count;
0438 }
0439 static DEVICE_ATTR_RW(resources);
0440
0441 static ssize_t id_show(struct device *dmdev, struct device_attribute *attr,
0442 char *buf)
0443 {
0444 char *str = buf;
0445 struct pnp_dev *dev = to_pnp_dev(dmdev);
0446 struct pnp_id *pos = dev->id;
0447
0448 while (pos) {
0449 str += sprintf(str, "%s\n", pos->id);
0450 pos = pos->next;
0451 }
0452 return (str - buf);
0453 }
0454 static DEVICE_ATTR_RO(id);
0455
0456 static struct attribute *pnp_dev_attrs[] = {
0457 &dev_attr_resources.attr,
0458 &dev_attr_options.attr,
0459 &dev_attr_id.attr,
0460 NULL,
0461 };
0462
0463 static const struct attribute_group pnp_dev_group = {
0464 .attrs = pnp_dev_attrs,
0465 };
0466
0467 const struct attribute_group *pnp_dev_groups[] = {
0468 &pnp_dev_group,
0469 NULL,
0470 };