1 // SPDX-License-Identifier: GPL-2.0 2 /* Sysctl interface for parport devices. 3 * 4 * Authors: David Campbell 5 * Tim Waugh <tim@cyberelk.demon.co.uk> 6 * Philip Blundell <philb@gnu.org> 7 * Andrea Arcangeli 8 * Riccardo Facchetti <fizban@tin.it> 9 * 10 * based on work by Grant Guenther <grant@torque.net> 11 * and Philip Blundell 12 * 13 * Cleaned up include files - Russell King <linux@arm.uk.linux.org> 14 */ 15 16 #include <linux/string.h> 17 #include <linux/init.h> 18 #include <linux/module.h> 19 #include <linux/errno.h> 20 #include <linux/kernel.h> 21 #include <linux/slab.h> 22 #include <linux/parport.h> 23 #include <linux/ctype.h> 24 #include <linux/sysctl.h> 25 #include <linux/device.h> 26 27 #include <linux/uaccess.h> 28 29 #if defined(CONFIG_SYSCTL) && defined(CONFIG_PROC_FS) 30 31 #define PARPORT_MIN_TIMESLICE_VALUE 1ul 32 #define PARPORT_MAX_TIMESLICE_VALUE ((unsigned long) HZ) 33 #define PARPORT_MIN_SPINTIME_VALUE 1 34 #define PARPORT_MAX_SPINTIME_VALUE 1000 35 /* 36 * PARPORT_BASE_* is the size of the known parts of the sysctl path 37 * in dev/partport/%s/devices/%s. "dev/parport/"(12), "/devices/"(9 38 * and null char(1). 39 */ 40 #define PARPORT_BASE_PATH_SIZE 13 41 #define PARPORT_BASE_DEVICES_PATH_SIZE 22 42 43 static int do_active_device(struct ctl_table *table, int write, 44 void *result, size_t *lenp, loff_t *ppos) 45 { 46 struct parport *port = (struct parport *)table->extra1; 47 char buffer[256]; 48 struct pardevice *dev; 49 int len = 0; 50 51 if (write) /* can't happen anyway */ 52 return -EACCES; 53 54 if (*ppos) { 55 *lenp = 0; 56 return 0; 57 } 58 59 for (dev = port->devices; dev ; dev = dev->next) { 60 if(dev == port->cad) { 61 len += sprintf(buffer, "%s\n", dev->name); 62 } 63 } 64 65 if(!len) { 66 len += sprintf(buffer, "%s\n", "none"); 67 } 68 69 if (len > *lenp) 70 len = *lenp; 71 else 72 *lenp = len; 73 74 *ppos += len; 75 memcpy(result, buffer, len); 76 return 0; 77 } 78 79 #ifdef CONFIG_PARPORT_1284 80 static int do_autoprobe(struct ctl_table *table, int write, 81 void *result, size_t *lenp, loff_t *ppos) 82 { 83 struct parport_device_info *info = table->extra2; 84 const char *str; 85 char buffer[256]; 86 int len = 0; 87 88 if (write) /* permissions stop this */ 89 return -EACCES; 90 91 if (*ppos) { 92 *lenp = 0; 93 return 0; 94 } 95 96 if ((str = info->class_name) != NULL) 97 len += sprintf (buffer + len, "CLASS:%s;\n", str); 98 99 if ((str = info->model) != NULL) 100 len += sprintf (buffer + len, "MODEL:%s;\n", str); 101 102 if ((str = info->mfr) != NULL) 103 len += sprintf (buffer + len, "MANUFACTURER:%s;\n", str); 104 105 if ((str = info->description) != NULL) 106 len += sprintf (buffer + len, "DESCRIPTION:%s;\n", str); 107 108 if ((str = info->cmdset) != NULL) 109 len += sprintf (buffer + len, "COMMAND SET:%s;\n", str); 110 111 if (len > *lenp) 112 len = *lenp; 113 else 114 *lenp = len; 115 116 *ppos += len; 117 118 memcpy(result, buffer, len); 119 return 0; 120 } 121 #endif /* IEEE1284.3 support. */ 122 123 static int do_hardware_base_addr(struct ctl_table *table, int write, 124 void *result, size_t *lenp, loff_t *ppos) 125 { 126 struct parport *port = (struct parport *)table->extra1; 127 char buffer[20]; 128 int len = 0; 129 130 if (*ppos) { 131 *lenp = 0; 132 return 0; 133 } 134 135 if (write) /* permissions prevent this anyway */ 136 return -EACCES; 137 138 len += sprintf (buffer, "%lu\t%lu\n", port->base, port->base_hi); 139 140 if (len > *lenp) 141 len = *lenp; 142 else 143 *lenp = len; 144 145 *ppos += len; 146 memcpy(result, buffer, len); 147 return 0; 148 } 149 150 static int do_hardware_irq(struct ctl_table *table, int write, 151 void *result, size_t *lenp, loff_t *ppos) 152 { 153 struct parport *port = (struct parport *)table->extra1; 154 char buffer[20]; 155 int len = 0; 156 157 if (*ppos) { 158 *lenp = 0; 159 return 0; 160 } 161 162 if (write) /* permissions prevent this anyway */ 163 return -EACCES; 164 165 len += sprintf (buffer, "%d\n", port->irq); 166 167 if (len > *lenp) 168 len = *lenp; 169 else 170 *lenp = len; 171 172 *ppos += len; 173 memcpy(result, buffer, len); 174 return 0; 175 } 176 177 static int do_hardware_dma(struct ctl_table *table, int write, 178 void *result, size_t *lenp, loff_t *ppos) 179 { 180 struct parport *port = (struct parport *)table->extra1; 181 char buffer[20]; 182 int len = 0; 183 184 if (*ppos) { 185 *lenp = 0; 186 return 0; 187 } 188 189 if (write) /* permissions prevent this anyway */ 190 return -EACCES; 191 192 len += sprintf (buffer, "%d\n", port->dma); 193 194 if (len > *lenp) 195 len = *lenp; 196 else 197 *lenp = len; 198 199 *ppos += len; 200 memcpy(result, buffer, len); 201 return 0; 202 } 203 204 static int do_hardware_modes(struct ctl_table *table, int write, 205 void *result, size_t *lenp, loff_t *ppos) 206 { 207 struct parport *port = (struct parport *)table->extra1; 208 char buffer[40]; 209 int len = 0; 210 211 if (*ppos) { 212 *lenp = 0; 213 return 0; 214 } 215 216 if (write) /* permissions prevent this anyway */ 217 return -EACCES; 218 219 { 220 #define printmode(x) \ 221 do { \ 222 if (port->modes & PARPORT_MODE_##x) \ 223 len += sprintf(buffer + len, "%s%s", f++ ? "," : "", #x); \ 224 } while (0) 225 int f = 0; 226 printmode(PCSPP); 227 printmode(TRISTATE); 228 printmode(COMPAT); 229 printmode(EPP); 230 printmode(ECP); 231 printmode(DMA); 232 #undef printmode 233 } 234 buffer[len++] = '\n'; 235 236 if (len > *lenp) 237 len = *lenp; 238 else 239 *lenp = len; 240 241 *ppos += len; 242 memcpy(result, buffer, len); 243 return 0; 244 } 245 246 static const unsigned long parport_min_timeslice_value = 247 PARPORT_MIN_TIMESLICE_VALUE; 248 249 static const unsigned long parport_max_timeslice_value = 250 PARPORT_MAX_TIMESLICE_VALUE; 251 252 static const int parport_min_spintime_value = 253 PARPORT_MIN_SPINTIME_VALUE; 254 255 static const int parport_max_spintime_value = 256 PARPORT_MAX_SPINTIME_VALUE; 257 258 259 struct parport_sysctl_table { 260 struct ctl_table_header *port_header; 261 struct ctl_table_header *devices_header; 262 struct ctl_table vars[12]; 263 struct ctl_table device_dir[2]; 264 }; 265 266 static const struct parport_sysctl_table parport_sysctl_template = { 267 .port_header = NULL, 268 .devices_header = NULL, 269 { 270 { 271 .procname = "spintime", 272 .data = NULL, 273 .maxlen = sizeof(int), 274 .mode = 0644, 275 .proc_handler = proc_dointvec_minmax, 276 .extra1 = (void*) &parport_min_spintime_value, 277 .extra2 = (void*) &parport_max_spintime_value 278 }, 279 { 280 .procname = "base-addr", 281 .data = NULL, 282 .maxlen = 0, 283 .mode = 0444, 284 .proc_handler = do_hardware_base_addr 285 }, 286 { 287 .procname = "irq", 288 .data = NULL, 289 .maxlen = 0, 290 .mode = 0444, 291 .proc_handler = do_hardware_irq 292 }, 293 { 294 .procname = "dma", 295 .data = NULL, 296 .maxlen = 0, 297 .mode = 0444, 298 .proc_handler = do_hardware_dma 299 }, 300 { 301 .procname = "modes", 302 .data = NULL, 303 .maxlen = 0, 304 .mode = 0444, 305 .proc_handler = do_hardware_modes 306 }, 307 #ifdef CONFIG_PARPORT_1284 308 { 309 .procname = "autoprobe", 310 .data = NULL, 311 .maxlen = 0, 312 .mode = 0444, 313 .proc_handler = do_autoprobe 314 }, 315 { 316 .procname = "autoprobe0", 317 .data = NULL, 318 .maxlen = 0, 319 .mode = 0444, 320 .proc_handler = do_autoprobe 321 }, 322 { 323 .procname = "autoprobe1", 324 .data = NULL, 325 .maxlen = 0, 326 .mode = 0444, 327 .proc_handler = do_autoprobe 328 }, 329 { 330 .procname = "autoprobe2", 331 .data = NULL, 332 .maxlen = 0, 333 .mode = 0444, 334 .proc_handler = do_autoprobe 335 }, 336 { 337 .procname = "autoprobe3", 338 .data = NULL, 339 .maxlen = 0, 340 .mode = 0444, 341 .proc_handler = do_autoprobe 342 }, 343 #endif /* IEEE 1284 support */ 344 {} 345 }, 346 { 347 { 348 .procname = "active", 349 .data = NULL, 350 .maxlen = 0, 351 .mode = 0444, 352 .proc_handler = do_active_device 353 }, 354 {} 355 }, 356 }; 357 358 struct parport_device_sysctl_table 359 { 360 struct ctl_table_header *sysctl_header; 361 struct ctl_table vars[2]; 362 struct ctl_table device_dir[2]; 363 struct ctl_table devices_root_dir[2]; 364 struct ctl_table port_dir[2]; 365 struct ctl_table parport_dir[2]; 366 struct ctl_table dev_dir[2]; 367 }; 368 369 static const struct parport_device_sysctl_table 370 parport_device_sysctl_template = { 371 .sysctl_header = NULL, 372 { 373 { 374 .procname = "timeslice", 375 .data = NULL, 376 .maxlen = sizeof(unsigned long), 377 .mode = 0644, 378 .proc_handler = proc_doulongvec_ms_jiffies_minmax, 379 .extra1 = (void*) &parport_min_timeslice_value, 380 .extra2 = (void*) &parport_max_timeslice_value 381 }, 382 {} 383 }, 384 { 385 { 386 .procname = NULL, 387 .data = NULL, 388 .maxlen = 0, 389 .mode = 0555, 390 }, 391 {} 392 } 393 }; 394 395 struct parport_default_sysctl_table 396 { 397 struct ctl_table_header *sysctl_header; 398 struct ctl_table vars[3]; 399 struct ctl_table default_dir[2]; 400 struct ctl_table parport_dir[2]; 401 struct ctl_table dev_dir[2]; 402 }; 403 404 static struct parport_default_sysctl_table 405 parport_default_sysctl_table = { 406 .sysctl_header = NULL, 407 { 408 { 409 .procname = "timeslice", 410 .data = &parport_default_timeslice, 411 .maxlen = sizeof(parport_default_timeslice), 412 .mode = 0644, 413 .proc_handler = proc_doulongvec_ms_jiffies_minmax, 414 .extra1 = (void*) &parport_min_timeslice_value, 415 .extra2 = (void*) &parport_max_timeslice_value 416 }, 417 { 418 .procname = "spintime", 419 .data = &parport_default_spintime, 420 .maxlen = sizeof(parport_default_spintime), 421 .mode = 0644, 422 .proc_handler = proc_dointvec_minmax, 423 .extra1 = (void*) &parport_min_spintime_value, 424 .extra2 = (void*) &parport_max_spintime_value 425 }, 426 {} 427 } 428 }; 429 430 int parport_proc_register(struct parport *port) 431 { 432 struct parport_sysctl_table *t; 433 char *tmp_dir_path; 434 size_t tmp_path_len, port_name_len; 435 int bytes_written, i, err = 0; 436 437 t = kmemdup(&parport_sysctl_template, sizeof(*t), GFP_KERNEL); 438 if (t == NULL) 439 return -ENOMEM; 440 441 t->device_dir[0].extra1 = port; 442 443 t->vars[0].data = &port->spintime; 444 for (i = 0; i < 5; i++) { 445 t->vars[i].extra1 = port; 446 t->vars[5 + i].extra2 = &port->probe_info[i]; 447 } 448 449 port_name_len = strnlen(port->name, PARPORT_NAME_MAX_LEN); 450 /* 451 * Allocate a buffer for two paths: dev/parport/PORT and dev/parport/PORT/devices. 452 * We calculate for the second as that will give us enough for the first. 453 */ 454 tmp_path_len = PARPORT_BASE_DEVICES_PATH_SIZE + port_name_len; 455 tmp_dir_path = kzalloc(tmp_path_len, GFP_KERNEL); 456 if (!tmp_dir_path) { 457 err = -ENOMEM; 458 goto exit_free_t; 459 } 460 461 bytes_written = snprintf(tmp_dir_path, tmp_path_len, 462 "dev/parport/%s/devices", port->name); 463 if (tmp_path_len <= bytes_written) { 464 err = -ENOENT; 465 goto exit_free_tmp_dir_path; 466 } 467 t->devices_header = register_sysctl(tmp_dir_path, t->device_dir); 468 if (t->devices_header == NULL) { 469 err = -ENOENT; 470 goto exit_free_tmp_dir_path; 471 } 472 473 tmp_path_len = PARPORT_BASE_PATH_SIZE + port_name_len; 474 bytes_written = snprintf(tmp_dir_path, tmp_path_len, 475 "dev/parport/%s", port->name); 476 if (tmp_path_len <= bytes_written) { 477 err = -ENOENT; 478 goto unregister_devices_h; 479 } 480 481 t->port_header = register_sysctl(tmp_dir_path, t->vars); 482 if (t->port_header == NULL) { 483 err = -ENOENT; 484 goto unregister_devices_h; 485 } 486 487 port->sysctl_table = t; 488 489 kfree(tmp_dir_path); 490 return 0; 491 492 unregister_devices_h: 493 unregister_sysctl_table(t->devices_header); 494 495 exit_free_tmp_dir_path: 496 kfree(tmp_dir_path); 497 498 exit_free_t: 499 kfree(t); 500 return err; 501 } 502 503 int parport_proc_unregister(struct parport *port) 504 { 505 if (port->sysctl_table) { 506 struct parport_sysctl_table *t = port->sysctl_table; 507 port->sysctl_table = NULL; 508 unregister_sysctl_table(t->devices_header); 509 unregister_sysctl_table(t->port_header); 510 kfree(t); 511 } 512 return 0; 513 } 514 515 int parport_device_proc_register(struct pardevice *device) 516 { 517 int bytes_written, err = 0; 518 struct parport_device_sysctl_table *t; 519 struct parport * port = device->port; 520 size_t port_name_len, device_name_len, tmp_dir_path_len; 521 char *tmp_dir_path; 522 523 t = kmemdup(&parport_device_sysctl_template, sizeof(*t), GFP_KERNEL); 524 if (t == NULL) 525 return -ENOMEM; 526 527 port_name_len = strnlen(port->name, PARPORT_NAME_MAX_LEN); 528 device_name_len = strnlen(device->name, PATH_MAX); 529 530 /* Allocate a buffer for two paths: dev/parport/PORT/devices/DEVICE. */ 531 tmp_dir_path_len = PARPORT_BASE_DEVICES_PATH_SIZE + port_name_len + device_name_len; 532 tmp_dir_path = kzalloc(tmp_dir_path_len, GFP_KERNEL); 533 if (!tmp_dir_path) { 534 err = -ENOMEM; 535 goto exit_free_t; 536 } 537 538 bytes_written = snprintf(tmp_dir_path, tmp_dir_path_len, "dev/parport/%s/devices/%s", 539 port->name, device->name); 540 if (tmp_dir_path_len <= bytes_written) { 541 err = -ENOENT; 542 goto exit_free_path; 543 } 544 545 t->vars[0].data = &device->timeslice; 546 547 t->sysctl_header = register_sysctl(tmp_dir_path, t->vars); 548 if (t->sysctl_header == NULL) { 549 kfree(t); 550 t = NULL; 551 } 552 device->sysctl_table = t; 553 554 kfree(tmp_dir_path); 555 return 0; 556 557 exit_free_path: 558 kfree(tmp_dir_path); 559 560 exit_free_t: 561 kfree(t); 562 563 return err; 564 } 565 566 int parport_device_proc_unregister(struct pardevice *device) 567 { 568 if (device->sysctl_table) { 569 struct parport_device_sysctl_table *t = device->sysctl_table; 570 device->sysctl_table = NULL; 571 unregister_sysctl_table(t->sysctl_header); 572 kfree(t); 573 } 574 return 0; 575 } 576 577 static int __init parport_default_proc_register(void) 578 { 579 int ret; 580 581 parport_default_sysctl_table.sysctl_header = 582 register_sysctl("dev/parport/default", parport_default_sysctl_table.vars); 583 if (!parport_default_sysctl_table.sysctl_header) 584 return -ENOMEM; 585 ret = parport_bus_init(); 586 if (ret) { 587 unregister_sysctl_table(parport_default_sysctl_table. 588 sysctl_header); 589 return ret; 590 } 591 return 0; 592 } 593 594 static void __exit parport_default_proc_unregister(void) 595 { 596 if (parport_default_sysctl_table.sysctl_header) { 597 unregister_sysctl_table(parport_default_sysctl_table. 598 sysctl_header); 599 parport_default_sysctl_table.sysctl_header = NULL; 600 } 601 parport_bus_exit(); 602 } 603 604 #else /* no sysctl or no procfs*/ 605 606 int parport_proc_register(struct parport *pp) 607 { 608 return 0; 609 } 610 611 int parport_proc_unregister(struct parport *pp) 612 { 613 return 0; 614 } 615 616 int parport_device_proc_register(struct pardevice *device) 617 { 618 return 0; 619 } 620 621 int parport_device_proc_unregister(struct pardevice *device) 622 { 623 return 0; 624 } 625 626 static int __init parport_default_proc_register (void) 627 { 628 return parport_bus_init(); 629 } 630 631 static void __exit parport_default_proc_unregister (void) 632 { 633 parport_bus_exit(); 634 } 635 #endif 636 637 subsys_initcall(parport_default_proc_register) 638 module_exit(parport_default_proc_unregister) 639