diff options
Diffstat (limited to 'drivers/pnp/interface.c')
| -rw-r--r-- | drivers/pnp/interface.c | 105 |
1 files changed, 68 insertions, 37 deletions
diff --git a/drivers/pnp/interface.c b/drivers/pnp/interface.c index cfaf5b73540b..0c201317284b 100644 --- a/drivers/pnp/interface.c +++ b/drivers/pnp/interface.c | |||
| @@ -298,6 +298,39 @@ static ssize_t pnp_show_current_resources(struct device *dmdev, | |||
| 298 | return ret; | 298 | return ret; |
| 299 | } | 299 | } |
| 300 | 300 | ||
| 301 | static char *pnp_get_resource_value(char *buf, | ||
| 302 | unsigned long type, | ||
| 303 | resource_size_t *start, | ||
| 304 | resource_size_t *end, | ||
| 305 | unsigned long *flags) | ||
| 306 | { | ||
| 307 | if (start) | ||
| 308 | *start = 0; | ||
| 309 | if (end) | ||
| 310 | *end = 0; | ||
| 311 | if (flags) | ||
| 312 | *flags = 0; | ||
| 313 | |||
| 314 | /* TBD: allow for disabled resources */ | ||
| 315 | |||
| 316 | buf = skip_spaces(buf); | ||
| 317 | if (start) { | ||
| 318 | *start = simple_strtoull(buf, &buf, 0); | ||
| 319 | if (end) { | ||
| 320 | buf = skip_spaces(buf); | ||
| 321 | if (*buf == '-') { | ||
| 322 | buf = skip_spaces(buf + 1); | ||
| 323 | *end = simple_strtoull(buf, &buf, 0); | ||
| 324 | } else | ||
| 325 | *end = *start; | ||
| 326 | } | ||
| 327 | } | ||
| 328 | |||
| 329 | /* TBD: allow for additional flags, e.g., IORESOURCE_WINDOW */ | ||
| 330 | |||
| 331 | return buf; | ||
| 332 | } | ||
| 333 | |||
| 301 | static ssize_t pnp_set_current_resources(struct device *dmdev, | 334 | static ssize_t pnp_set_current_resources(struct device *dmdev, |
| 302 | struct device_attribute *attr, | 335 | struct device_attribute *attr, |
| 303 | const char *ubuf, size_t count) | 336 | const char *ubuf, size_t count) |
| @@ -305,7 +338,6 @@ static ssize_t pnp_set_current_resources(struct device *dmdev, | |||
| 305 | struct pnp_dev *dev = to_pnp_dev(dmdev); | 338 | struct pnp_dev *dev = to_pnp_dev(dmdev); |
| 306 | char *buf = (void *)ubuf; | 339 | char *buf = (void *)ubuf; |
| 307 | int retval = 0; | 340 | int retval = 0; |
| 308 | resource_size_t start, end; | ||
| 309 | 341 | ||
| 310 | if (dev->status & PNP_ATTACHED) { | 342 | if (dev->status & PNP_ATTACHED) { |
| 311 | retval = -EBUSY; | 343 | retval = -EBUSY; |
| @@ -349,6 +381,10 @@ static ssize_t pnp_set_current_resources(struct device *dmdev, | |||
| 349 | goto done; | 381 | goto done; |
| 350 | } | 382 | } |
| 351 | if (!strnicmp(buf, "set", 3)) { | 383 | if (!strnicmp(buf, "set", 3)) { |
| 384 | resource_size_t start; | ||
| 385 | resource_size_t end; | ||
| 386 | unsigned long flags; | ||
| 387 | |||
| 352 | if (dev->active) | 388 | if (dev->active) |
| 353 | goto done; | 389 | goto done; |
| 354 | buf += 3; | 390 | buf += 3; |
| @@ -357,42 +393,37 @@ static ssize_t pnp_set_current_resources(struct device *dmdev, | |||
| 357 | while (1) { | 393 | while (1) { |
| 358 | buf = skip_spaces(buf); | 394 | buf = skip_spaces(buf); |
| 359 | if (!strnicmp(buf, "io", 2)) { | 395 | if (!strnicmp(buf, "io", 2)) { |
| 360 | buf = skip_spaces(buf + 2); | 396 | buf = pnp_get_resource_value(buf + 2, |
| 361 | start = simple_strtoul(buf, &buf, 0); | 397 | IORESOURCE_IO, |
| 362 | buf = skip_spaces(buf); | 398 | &start, &end, |
| 363 | if (*buf == '-') { | 399 | &flags); |
| 364 | buf = skip_spaces(buf + 1); | 400 | pnp_add_io_resource(dev, start, end, flags); |
| 365 | end = simple_strtoul(buf, &buf, 0); | 401 | } else if (!strnicmp(buf, "mem", 3)) { |
| 366 | } else | 402 | buf = pnp_get_resource_value(buf + 3, |
| 367 | end = start; | 403 | IORESOURCE_MEM, |
| 368 | pnp_add_io_resource(dev, start, end, 0); | 404 | &start, &end, |
| 369 | continue; | 405 | &flags); |
| 370 | } | 406 | pnp_add_mem_resource(dev, start, end, flags); |
| 371 | if (!strnicmp(buf, "mem", 3)) { | 407 | } else if (!strnicmp(buf, "irq", 3)) { |
| 372 | buf = skip_spaces(buf + 3); | 408 | buf = pnp_get_resource_value(buf + 3, |
| 373 | start = simple_strtoul(buf, &buf, 0); | 409 | IORESOURCE_IRQ, |
| 374 | buf = skip_spaces(buf); | 410 | &start, NULL, |
| 375 | if (*buf == '-') { | 411 | &flags); |
| 376 | buf = skip_spaces(buf + 1); | 412 | pnp_add_irq_resource(dev, start, flags); |
| 377 | end = simple_strtoul(buf, &buf, 0); | 413 | } else if (!strnicmp(buf, "dma", 3)) { |
| 378 | } else | 414 | buf = pnp_get_resource_value(buf + 3, |
| 379 | end = start; | 415 | IORESOURCE_DMA, |
| 380 | pnp_add_mem_resource(dev, start, end, 0); | 416 | &start, NULL, |
| 381 | continue; | 417 | &flags); |
| 382 | } | 418 | pnp_add_dma_resource(dev, start, flags); |
| 383 | if (!strnicmp(buf, "irq", 3)) { | 419 | } else if (!strnicmp(buf, "bus", 3)) { |
| 384 | buf = skip_spaces(buf + 3); | 420 | buf = pnp_get_resource_value(buf + 3, |
| 385 | start = simple_strtoul(buf, &buf, 0); | 421 | IORESOURCE_BUS, |
| 386 | pnp_add_irq_resource(dev, start, 0); | 422 | &start, &end, |
| 387 | continue; | 423 | NULL); |
| 388 | } | 424 | pnp_add_bus_resource(dev, start, end); |
| 389 | if (!strnicmp(buf, "dma", 3)) { | 425 | } else |
| 390 | buf = skip_spaces(buf + 3); | 426 | break; |
| 391 | start = simple_strtoul(buf, &buf, 0); | ||
| 392 | pnp_add_dma_resource(dev, start, 0); | ||
| 393 | continue; | ||
| 394 | } | ||
| 395 | break; | ||
| 396 | } | 427 | } |
| 397 | mutex_unlock(&pnp_res_mutex); | 428 | mutex_unlock(&pnp_res_mutex); |
| 398 | goto done; | 429 | goto done; |
