Merge tag 'for-linus-4.17-ofs' of git://git.kernel.org/pub/scm/linux/kernel/git/hubca...
[sfrench/cifs-2.6.git] / drivers / parport / procfs.c
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 static int do_active_device(struct ctl_table *table, int write,
37                       void __user *result, size_t *lenp, loff_t *ppos)
38 {
39         struct parport *port = (struct parport *)table->extra1;
40         char buffer[256];
41         struct pardevice *dev;
42         int len = 0;
43
44         if (write)              /* can't happen anyway */
45                 return -EACCES;
46
47         if (*ppos) {
48                 *lenp = 0;
49                 return 0;
50         }
51         
52         for (dev = port->devices; dev ; dev = dev->next) {
53                 if(dev == port->cad) {
54                         len += sprintf(buffer, "%s\n", dev->name);
55                 }
56         }
57
58         if(!len) {
59                 len += sprintf(buffer, "%s\n", "none");
60         }
61
62         if (len > *lenp)
63                 len = *lenp;
64         else
65                 *lenp = len;
66
67         *ppos += len;
68
69         return copy_to_user(result, buffer, len) ? -EFAULT : 0;
70 }
71
72 #ifdef CONFIG_PARPORT_1284
73 static int do_autoprobe(struct ctl_table *table, int write,
74                         void __user *result, size_t *lenp, loff_t *ppos)
75 {
76         struct parport_device_info *info = table->extra2;
77         const char *str;
78         char buffer[256];
79         int len = 0;
80
81         if (write) /* permissions stop this */
82                 return -EACCES;
83
84         if (*ppos) {
85                 *lenp = 0;
86                 return 0;
87         }
88         
89         if ((str = info->class_name) != NULL)
90                 len += sprintf (buffer + len, "CLASS:%s;\n", str);
91
92         if ((str = info->model) != NULL)
93                 len += sprintf (buffer + len, "MODEL:%s;\n", str);
94
95         if ((str = info->mfr) != NULL)
96                 len += sprintf (buffer + len, "MANUFACTURER:%s;\n", str);
97
98         if ((str = info->description) != NULL)
99                 len += sprintf (buffer + len, "DESCRIPTION:%s;\n", str);
100
101         if ((str = info->cmdset) != NULL)
102                 len += sprintf (buffer + len, "COMMAND SET:%s;\n", str);
103
104         if (len > *lenp)
105                 len = *lenp;
106         else
107                 *lenp = len;
108
109         *ppos += len;
110
111         return copy_to_user (result, buffer, len) ? -EFAULT : 0;
112 }
113 #endif /* IEEE1284.3 support. */
114
115 static int do_hardware_base_addr(struct ctl_table *table, int write,
116                                  void __user *result,
117                                  size_t *lenp, loff_t *ppos)
118 {
119         struct parport *port = (struct parport *)table->extra1;
120         char buffer[20];
121         int len = 0;
122
123         if (*ppos) {
124                 *lenp = 0;
125                 return 0;
126         }
127
128         if (write) /* permissions prevent this anyway */
129                 return -EACCES;
130
131         len += sprintf (buffer, "%lu\t%lu\n", port->base, port->base_hi);
132
133         if (len > *lenp)
134                 len = *lenp;
135         else
136                 *lenp = len;
137
138         *ppos += len;
139
140         return copy_to_user(result, buffer, len) ? -EFAULT : 0;
141 }
142
143 static int do_hardware_irq(struct ctl_table *table, int write,
144                            void __user *result,
145                            size_t *lenp, loff_t *ppos)
146 {
147         struct parport *port = (struct parport *)table->extra1;
148         char buffer[20];
149         int len = 0;
150
151         if (*ppos) {
152                 *lenp = 0;
153                 return 0;
154         }
155
156         if (write) /* permissions prevent this anyway */
157                 return -EACCES;
158
159         len += sprintf (buffer, "%d\n", port->irq);
160
161         if (len > *lenp)
162                 len = *lenp;
163         else
164                 *lenp = len;
165
166         *ppos += len;
167
168         return copy_to_user(result, buffer, len) ? -EFAULT : 0;
169 }
170
171 static int do_hardware_dma(struct ctl_table *table, int write,
172                            void __user *result,
173                            size_t *lenp, loff_t *ppos)
174 {
175         struct parport *port = (struct parport *)table->extra1;
176         char buffer[20];
177         int len = 0;
178
179         if (*ppos) {
180                 *lenp = 0;
181                 return 0;
182         }
183
184         if (write) /* permissions prevent this anyway */
185                 return -EACCES;
186
187         len += sprintf (buffer, "%d\n", port->dma);
188
189         if (len > *lenp)
190                 len = *lenp;
191         else
192                 *lenp = len;
193
194         *ppos += len;
195
196         return copy_to_user(result, buffer, len) ? -EFAULT : 0;
197 }
198
199 static int do_hardware_modes(struct ctl_table *table, int write,
200                              void __user *result,
201                              size_t *lenp, loff_t *ppos)
202 {
203         struct parport *port = (struct parport *)table->extra1;
204         char buffer[40];
205         int len = 0;
206
207         if (*ppos) {
208                 *lenp = 0;
209                 return 0;
210         }
211
212         if (write) /* permissions prevent this anyway */
213                 return -EACCES;
214
215         {
216 #define printmode(x) {if(port->modes&PARPORT_MODE_##x){len+=sprintf(buffer+len,"%s%s",f?",":"",#x);f++;}}
217                 int f = 0;
218                 printmode(PCSPP);
219                 printmode(TRISTATE);
220                 printmode(COMPAT);
221                 printmode(EPP);
222                 printmode(ECP);
223                 printmode(DMA);
224 #undef printmode
225         }
226         buffer[len++] = '\n';
227
228         if (len > *lenp)
229                 len = *lenp;
230         else
231                 *lenp = len;
232
233         *ppos += len;
234
235         return copy_to_user(result, buffer, len) ? -EFAULT : 0;
236 }
237
238 #define PARPORT_PORT_DIR(CHILD) { .procname = NULL, .mode = 0555, .child = CHILD }
239 #define PARPORT_PARPORT_DIR(CHILD) { .procname = "parport", \
240                                      .mode = 0555, .child = CHILD }
241 #define PARPORT_DEV_DIR(CHILD) { .procname = "dev", .mode = 0555, .child = CHILD }
242 #define PARPORT_DEVICES_ROOT_DIR  {  .procname = "devices", \
243                                     .mode = 0555, .child = NULL }
244
245 static const unsigned long parport_min_timeslice_value =
246 PARPORT_MIN_TIMESLICE_VALUE;
247
248 static const unsigned long parport_max_timeslice_value =
249 PARPORT_MAX_TIMESLICE_VALUE;
250
251 static const  int parport_min_spintime_value =
252 PARPORT_MIN_SPINTIME_VALUE;
253
254 static const int parport_max_spintime_value =
255 PARPORT_MAX_SPINTIME_VALUE;
256
257
258 struct parport_sysctl_table {
259         struct ctl_table_header *sysctl_header;
260         struct ctl_table vars[12];
261         struct ctl_table device_dir[2];
262         struct ctl_table port_dir[2];
263         struct ctl_table parport_dir[2];
264         struct ctl_table dev_dir[2];
265 };
266
267 static const struct parport_sysctl_table parport_sysctl_template = {
268         .sysctl_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                 PARPORT_DEVICES_ROOT_DIR,
308 #ifdef CONFIG_PARPORT_1284
309                 {
310                         .procname       = "autoprobe",
311                         .data           = NULL,
312                         .maxlen         = 0,
313                         .mode           = 0444,
314                         .proc_handler   = do_autoprobe
315                 },
316                 {
317                         .procname       = "autoprobe0",
318                         .data           = NULL,
319                         .maxlen         = 0,
320                         .mode           = 0444,
321                         .proc_handler   = do_autoprobe
322                 },
323                 {
324                         .procname       = "autoprobe1",
325                         .data           = NULL,
326                         .maxlen         = 0,
327                         .mode           = 0444,
328                         .proc_handler   = do_autoprobe
329                 },
330                 {
331                         .procname       = "autoprobe2",
332                         .data           = NULL,
333                         .maxlen         = 0,
334                         .mode           = 0444,
335                         .proc_handler   = do_autoprobe
336                 },
337                 {
338                         .procname       = "autoprobe3",
339                         .data           = NULL,
340                         .maxlen         = 0,
341                         .mode           = 0444,
342                         .proc_handler   = do_autoprobe
343                 },
344 #endif /* IEEE 1284 support */
345                 {}
346         },
347         {
348                 {
349                         .procname       = "active",
350                         .data           = NULL,
351                         .maxlen         = 0,
352                         .mode           = 0444,
353                         .proc_handler   = do_active_device
354                 },
355                 {}
356         },
357         {
358                 PARPORT_PORT_DIR(NULL),
359                 {}
360         },
361         {
362                 PARPORT_PARPORT_DIR(NULL),
363                 {}
364         },
365         {
366                 PARPORT_DEV_DIR(NULL),
367                 {}
368         }
369 };
370
371 struct parport_device_sysctl_table
372 {
373         struct ctl_table_header *sysctl_header;
374         struct ctl_table vars[2];
375         struct ctl_table device_dir[2];
376         struct ctl_table devices_root_dir[2];
377         struct ctl_table port_dir[2];
378         struct ctl_table parport_dir[2];
379         struct ctl_table dev_dir[2];
380 };
381
382 static const struct parport_device_sysctl_table
383 parport_device_sysctl_template = {
384         .sysctl_header = NULL,
385         {
386                 {
387                         .procname       = "timeslice",
388                         .data           = NULL,
389                         .maxlen         = sizeof(unsigned long),
390                         .mode           = 0644,
391                         .proc_handler   = proc_doulongvec_ms_jiffies_minmax,
392                         .extra1         = (void*) &parport_min_timeslice_value,
393                         .extra2         = (void*) &parport_max_timeslice_value
394                 },
395         },
396         {
397                 {
398                         .procname       = NULL,
399                         .data           = NULL,
400                         .maxlen         = 0,
401                         .mode           = 0555,
402                         .child          = NULL
403                 },
404                 {}
405         },
406         {
407                 PARPORT_DEVICES_ROOT_DIR,
408                 {}
409         },
410         {
411                 PARPORT_PORT_DIR(NULL),
412                 {}
413         },
414         {
415                 PARPORT_PARPORT_DIR(NULL),
416                 {}
417         },
418         {
419                 PARPORT_DEV_DIR(NULL),
420                 {}
421         }
422 };
423
424 struct parport_default_sysctl_table
425 {
426         struct ctl_table_header *sysctl_header;
427         struct ctl_table vars[3];
428         struct ctl_table default_dir[2];
429         struct ctl_table parport_dir[2];
430         struct ctl_table dev_dir[2];
431 };
432
433 static struct parport_default_sysctl_table
434 parport_default_sysctl_table = {
435         .sysctl_header  = NULL,
436         {
437                 {
438                         .procname       = "timeslice",
439                         .data           = &parport_default_timeslice,
440                         .maxlen         = sizeof(parport_default_timeslice),
441                         .mode           = 0644,
442                         .proc_handler   = proc_doulongvec_ms_jiffies_minmax,
443                         .extra1         = (void*) &parport_min_timeslice_value,
444                         .extra2         = (void*) &parport_max_timeslice_value
445                 },
446                 {
447                         .procname       = "spintime",
448                         .data           = &parport_default_spintime,
449                         .maxlen         = sizeof(parport_default_spintime),
450                         .mode           = 0644,
451                         .proc_handler   = proc_dointvec_minmax,
452                         .extra1         = (void*) &parport_min_spintime_value,
453                         .extra2         = (void*) &parport_max_spintime_value
454                 },
455                 {}
456         },
457         {
458                 {
459                         .procname       = "default",
460                         .mode           = 0555,
461                         .child          = parport_default_sysctl_table.vars
462                 },
463                 {}
464         },
465         {
466                 PARPORT_PARPORT_DIR(parport_default_sysctl_table.default_dir),
467                 {}
468         },
469         {
470                 PARPORT_DEV_DIR(parport_default_sysctl_table.parport_dir),
471                 {}
472         }
473 };
474
475
476 int parport_proc_register(struct parport *port)
477 {
478         struct parport_sysctl_table *t;
479         int i;
480
481         t = kmemdup(&parport_sysctl_template, sizeof(*t), GFP_KERNEL);
482         if (t == NULL)
483                 return -ENOMEM;
484
485         t->device_dir[0].extra1 = port;
486
487         for (i = 0; i < 5; i++)
488                 t->vars[i].extra1 = port;
489
490         t->vars[0].data = &port->spintime;
491         t->vars[5].child = t->device_dir;
492         
493         for (i = 0; i < 5; i++)
494                 t->vars[6 + i].extra2 = &port->probe_info[i];
495
496         t->port_dir[0].procname = port->name;
497
498         t->port_dir[0].child = t->vars;
499         t->parport_dir[0].child = t->port_dir;
500         t->dev_dir[0].child = t->parport_dir;
501
502         t->sysctl_header = register_sysctl_table(t->dev_dir);
503         if (t->sysctl_header == NULL) {
504                 kfree(t);
505                 t = NULL;
506         }
507         port->sysctl_table = t;
508         return 0;
509 }
510
511 int parport_proc_unregister(struct parport *port)
512 {
513         if (port->sysctl_table) {
514                 struct parport_sysctl_table *t = port->sysctl_table;
515                 port->sysctl_table = NULL;
516                 unregister_sysctl_table(t->sysctl_header);
517                 kfree(t);
518         }
519         return 0;
520 }
521
522 int parport_device_proc_register(struct pardevice *device)
523 {
524         struct parport_device_sysctl_table *t;
525         struct parport * port = device->port;
526         
527         t = kmemdup(&parport_device_sysctl_template, sizeof(*t), GFP_KERNEL);
528         if (t == NULL)
529                 return -ENOMEM;
530
531         t->dev_dir[0].child = t->parport_dir;
532         t->parport_dir[0].child = t->port_dir;
533         t->port_dir[0].procname = port->name;
534         t->port_dir[0].child = t->devices_root_dir;
535         t->devices_root_dir[0].child = t->device_dir;
536
537         t->device_dir[0].procname = device->name;
538         t->device_dir[0].child = t->vars;
539         t->vars[0].data = &device->timeslice;
540
541         t->sysctl_header = register_sysctl_table(t->dev_dir);
542         if (t->sysctl_header == NULL) {
543                 kfree(t);
544                 t = NULL;
545         }
546         device->sysctl_table = t;
547         return 0;
548 }
549
550 int parport_device_proc_unregister(struct pardevice *device)
551 {
552         if (device->sysctl_table) {
553                 struct parport_device_sysctl_table *t = device->sysctl_table;
554                 device->sysctl_table = NULL;
555                 unregister_sysctl_table(t->sysctl_header);
556                 kfree(t);
557         }
558         return 0;
559 }
560
561 static int __init parport_default_proc_register(void)
562 {
563         int ret;
564
565         parport_default_sysctl_table.sysctl_header =
566                 register_sysctl_table(parport_default_sysctl_table.dev_dir);
567         if (!parport_default_sysctl_table.sysctl_header)
568                 return -ENOMEM;
569         ret = parport_bus_init();
570         if (ret) {
571                 unregister_sysctl_table(parport_default_sysctl_table.
572                                         sysctl_header);
573                 return ret;
574         }
575         return 0;
576 }
577
578 static void __exit parport_default_proc_unregister(void)
579 {
580         if (parport_default_sysctl_table.sysctl_header) {
581                 unregister_sysctl_table(parport_default_sysctl_table.
582                                         sysctl_header);
583                 parport_default_sysctl_table.sysctl_header = NULL;
584         }
585         parport_bus_exit();
586 }
587
588 #else /* no sysctl or no procfs*/
589
590 int parport_proc_register(struct parport *pp)
591 {
592         return 0;
593 }
594
595 int parport_proc_unregister(struct parport *pp)
596 {
597         return 0;
598 }
599
600 int parport_device_proc_register(struct pardevice *device)
601 {
602         return 0;
603 }
604
605 int parport_device_proc_unregister(struct pardevice *device)
606 {
607         return 0;
608 }
609
610 static int __init parport_default_proc_register (void)
611 {
612         return parport_bus_init();
613 }
614
615 static void __exit parport_default_proc_unregister (void)
616 {
617         parport_bus_exit();
618 }
619 #endif
620
621 subsys_initcall(parport_default_proc_register)
622 module_exit(parport_default_proc_unregister)