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 #ifdef CONFIG_PARPORT_1284 263 struct ctl_table vars[10]; 264 #else 265 struct ctl_table vars[5]; 266 #endif /* IEEE 1284 support */ 267 struct ctl_table device_dir[1]; 268 }; 269 270 static const struct parport_sysctl_table parport_sysctl_template = { 271 .port_header = NULL, 272 .devices_header = NULL, 273 { 274 { 275 .procname = "spintime", 276 .data = NULL, 277 .maxlen = sizeof(int), 278 .mode = 0644, 279 .proc_handler = proc_dointvec_minmax, 280 .extra1 = (void*) &parport_min_spintime_value, 281 .extra2 = (void*) &parport_max_spintime_value 282 }, 283 { 284 .procname = "base-addr", 285 .data = NULL, 286 .maxlen = 0, 287 .mode = 0444, 288 .proc_handler = do_hardware_base_addr 289 }, 290 { 291 .procname = "irq", 292 .data = NULL, 293 .maxlen = 0, 294 .mode = 0444, 295 .proc_handler = do_hardware_irq 296 }, 297 { 298 .procname = "dma", 299 .data = NULL, 300 .maxlen = 0, 301 .mode = 0444, 302 .proc_handler = do_hardware_dma 303 }, 304 { 305 .procname = "modes", 306 .data = NULL, 307 .maxlen = 0, 308 .mode = 0444, 309 .proc_handler = do_hardware_modes 310 }, 311 #ifdef CONFIG_PARPORT_1284 312 { 313 .procname = "autoprobe", 314 .data = NULL, 315 .maxlen = 0, 316 .mode = 0444, 317 .proc_handler = do_autoprobe 318 }, 319 { 320 .procname = "autoprobe0", 321 .data = NULL, 322 .maxlen = 0, 323 .mode = 0444, 324 .proc_handler = do_autoprobe 325 }, 326 { 327 .procname = "autoprobe1", 328 .data = NULL, 329 .maxlen = 0, 330 .mode = 0444, 331 .proc_handler = do_autoprobe 332 }, 333 { 334 .procname = "autoprobe2", 335 .data = NULL, 336 .maxlen = 0, 337 .mode = 0444, 338 .proc_handler = do_autoprobe 339 }, 340 { 341 .procname = "autoprobe3", 342 .data = NULL, 343 .maxlen = 0, 344 .mode = 0444, 345 .proc_handler = do_autoprobe 346 }, 347 #endif /* IEEE 1284 support */ 348 }, 349 { 350 { 351 .procname = "active", 352 .data = NULL, 353 .maxlen = 0, 354 .mode = 0444, 355 .proc_handler = do_active_device 356 }, 357 }, 358 }; 359 360 struct parport_device_sysctl_table 361 { 362 struct ctl_table_header *sysctl_header; 363 struct ctl_table vars[1]; 364 struct ctl_table device_dir[1]; 365 }; 366 367 static const struct parport_device_sysctl_table 368 parport_device_sysctl_template = { 369 .sysctl_header = NULL, 370 { 371 { 372 .procname = "timeslice", 373 .data = NULL, 374 .maxlen = sizeof(unsigned long), 375 .mode = 0644, 376 .proc_handler = proc_doulongvec_ms_jiffies_minmax, 377 .extra1 = (void*) &parport_min_timeslice_value, 378 .extra2 = (void*) &parport_max_timeslice_value 379 }, 380 }, 381 { 382 { 383 .procname = NULL, 384 .data = NULL, 385 .maxlen = 0, 386 .mode = 0555, 387 }, 388 } 389 }; 390 391 struct parport_default_sysctl_table 392 { 393 struct ctl_table_header *sysctl_header; 394 struct ctl_table vars[2]; 395 }; 396 397 static struct parport_default_sysctl_table 398 parport_default_sysctl_table = { 399 .sysctl_header = NULL, 400 { 401 { 402 .procname = "timeslice", 403 .data = &parport_default_timeslice, 404 .maxlen = sizeof(parport_default_timeslice), 405 .mode = 0644, 406 .proc_handler = proc_doulongvec_ms_jiffies_minmax, 407 .extra1 = (void*) &parport_min_timeslice_value, 408 .extra2 = (void*) &parport_max_timeslice_value 409 }, 410 { 411 .procname = "spintime", 412 .data = &parport_default_spintime, 413 .maxlen = sizeof(parport_default_spintime), 414 .mode = 0644, 415 .proc_handler = proc_dointvec_minmax, 416 .extra1 = (void*) &parport_min_spintime_value, 417 .extra2 = (void*) &parport_max_spintime_value 418 }, 419 } 420 }; 421 422 int parport_proc_register(struct parport *port) 423 { 424 struct parport_sysctl_table *t; 425 char *tmp_dir_path; 426 size_t tmp_path_len, port_name_len; 427 int bytes_written, i, err = 0; 428 429 t = kmemdup(&parport_sysctl_template, sizeof(*t), GFP_KERNEL); 430 if (t == NULL) 431 return -ENOMEM; 432 433 t->device_dir[0].extra1 = port; 434 435 t->vars[0].data = &port->spintime; 436 for (i = 0; i < 5; i++) { 437 t->vars[i].extra1 = port; 438 #ifdef CONFIG_PARPORT_1284 439 t->vars[5 + i].extra2 = &port->probe_info[i]; 440 #endif /* IEEE 1284 support */ 441 } 442 443 port_name_len = strnlen(port->name, PARPORT_NAME_MAX_LEN); 444 /* 445 * Allocate a buffer for two paths: dev/parport/PORT and dev/parport/PORT/devices. 446 * We calculate for the second as that will give us enough for the first. 447 */ 448 tmp_path_len = PARPORT_BASE_DEVICES_PATH_SIZE + port_name_len; 449 tmp_dir_path = kzalloc(tmp_path_len, GFP_KERNEL); 450 if (!tmp_dir_path) { 451 err = -ENOMEM; 452 goto exit_free_t; 453 } 454 455 bytes_written = snprintf(tmp_dir_path, tmp_path_len, 456 "dev/parport/%s/devices", port->name); 457 if (tmp_path_len <= bytes_written) { 458 err = -ENOENT; 459 goto exit_free_tmp_dir_path; 460 } 461 t->devices_header = register_sysctl(tmp_dir_path, t->device_dir); 462 if (t->devices_header == NULL) { 463 err = -ENOENT; 464 goto exit_free_tmp_dir_path; 465 } 466 467 tmp_path_len = PARPORT_BASE_PATH_SIZE + port_name_len; 468 bytes_written = snprintf(tmp_dir_path, tmp_path_len, 469 "dev/parport/%s", port->name); 470 if (tmp_path_len <= bytes_written) { 471 err = -ENOENT; 472 goto unregister_devices_h; 473 } 474 475 t->port_header = register_sysctl(tmp_dir_path, t->vars); 476 if (t->port_header == NULL) { 477 err = -ENOENT; 478 goto unregister_devices_h; 479 } 480 481 port->sysctl_table = t; 482 483 kfree(tmp_dir_path); 484 return 0; 485 486 unregister_devices_h: 487 unregister_sysctl_table(t->devices_header); 488 489 exit_free_tmp_dir_path: 490 kfree(tmp_dir_path); 491 492 exit_free_t: 493 kfree(t); 494 return err; 495 } 496 497 int parport_proc_unregister(struct parport *port) 498 { 499 if (port->sysctl_table) { 500 struct parport_sysctl_table *t = port->sysctl_table; 501 port->sysctl_table = NULL; 502 unregister_sysctl_table(t->devices_header); 503 unregister_sysctl_table(t->port_header); 504 kfree(t); 505 } 506 return 0; 507 } 508 509 int parport_device_proc_register(struct pardevice *device) 510 { 511 int bytes_written, err = 0; 512 struct parport_device_sysctl_table *t; 513 struct parport * port = device->port; 514 size_t port_name_len, device_name_len, tmp_dir_path_len; 515 char *tmp_dir_path; 516 517 t = kmemdup(&parport_device_sysctl_template, sizeof(*t), GFP_KERNEL); 518 if (t == NULL) 519 return -ENOMEM; 520 521 port_name_len = strnlen(port->name, PARPORT_NAME_MAX_LEN); 522 device_name_len = strnlen(device->name, PATH_MAX); 523 524 /* Allocate a buffer for two paths: dev/parport/PORT/devices/DEVICE. */ 525 tmp_dir_path_len = PARPORT_BASE_DEVICES_PATH_SIZE + port_name_len + device_name_len; 526 tmp_dir_path = kzalloc(tmp_dir_path_len, GFP_KERNEL); 527 if (!tmp_dir_path) { 528 err = -ENOMEM; 529 goto exit_free_t; 530 } 531 532 bytes_written = snprintf(tmp_dir_path, tmp_dir_path_len, "dev/parport/%s/devices/%s", 533 port->name, device->name); 534 if (tmp_dir_path_len <= bytes_written) { 535 err = -ENOENT; 536 goto exit_free_path; 537 } 538 539 t->vars[0].data = &device->timeslice; 540 541 t->sysctl_header = register_sysctl(tmp_dir_path, t->vars); 542 if (t->sysctl_header == NULL) { 543 kfree(t); 544 t = NULL; 545 } 546 device->sysctl_table = t; 547 548 kfree(tmp_dir_path); 549 return 0; 550 551 exit_free_path: 552 kfree(tmp_dir_path); 553 554 exit_free_t: 555 kfree(t); 556 557 return err; 558 } 559 560 int parport_device_proc_unregister(struct pardevice *device) 561 { 562 if (device->sysctl_table) { 563 struct parport_device_sysctl_table *t = device->sysctl_table; 564 device->sysctl_table = NULL; 565 unregister_sysctl_table(t->sysctl_header); 566 kfree(t); 567 } 568 return 0; 569 } 570 571 static int __init parport_default_proc_register(void) 572 { 573 int ret; 574 575 parport_default_sysctl_table.sysctl_header = 576 register_sysctl("dev/parport/default", parport_default_sysctl_table.vars); 577 if (!parport_default_sysctl_table.sysctl_header) 578 return -ENOMEM; 579 ret = parport_bus_init(); 580 if (ret) { 581 unregister_sysctl_table(parport_default_sysctl_table. 582 sysctl_header); 583 return ret; 584 } 585 return 0; 586 } 587 588 static void __exit parport_default_proc_unregister(void) 589 { 590 if (parport_default_sysctl_table.sysctl_header) { 591 unregister_sysctl_table(parport_default_sysctl_table. 592 sysctl_header); 593 parport_default_sysctl_table.sysctl_header = NULL; 594 } 595 parport_bus_exit(); 596 } 597 598 #else /* no sysctl or no procfs*/ 599 600 int parport_proc_register(struct parport *pp) 601 { 602 return 0; 603 } 604 605 int parport_proc_unregister(struct parport *pp) 606 { 607 return 0; 608 } 609 610 int parport_device_proc_register(struct pardevice *device) 611 { 612 return 0; 613 } 614 615 int parport_device_proc_unregister(struct pardevice *device) 616 { 617 return 0; 618 } 619 620 static int __init parport_default_proc_register (void) 621 { 622 return parport_bus_init(); 623 } 624 625 static void __exit parport_default_proc_unregister (void) 626 { 627 parport_bus_exit(); 628 } 629 #endif 630 631 subsys_initcall(parport_default_proc_register) 632 module_exit(parport_default_proc_unregister) 633