proc.c 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * ISA Plug & Play support
  4. * Copyright (c) by Jaroslav Kysela <[email protected]>
  5. */
  6. #include <linux/module.h>
  7. #include <linux/isapnp.h>
  8. #include <linux/proc_fs.h>
  9. #include <linux/init.h>
  10. #include <linux/uaccess.h>
  11. extern struct pnp_protocol isapnp_protocol;
  12. static struct proc_dir_entry *isapnp_proc_bus_dir = NULL;
  13. static loff_t isapnp_proc_bus_lseek(struct file *file, loff_t off, int whence)
  14. {
  15. return fixed_size_llseek(file, off, whence, 256);
  16. }
  17. static ssize_t isapnp_proc_bus_read(struct file *file, char __user * buf,
  18. size_t nbytes, loff_t * ppos)
  19. {
  20. struct pnp_dev *dev = pde_data(file_inode(file));
  21. int pos = *ppos;
  22. int cnt, size = 256;
  23. if (pos >= size)
  24. return 0;
  25. if (nbytes >= size)
  26. nbytes = size;
  27. if (pos + nbytes > size)
  28. nbytes = size - pos;
  29. cnt = nbytes;
  30. if (!access_ok(buf, cnt))
  31. return -EINVAL;
  32. isapnp_cfg_begin(dev->card->number, dev->number);
  33. for (; pos < 256 && cnt > 0; pos++, buf++, cnt--) {
  34. unsigned char val;
  35. val = isapnp_read_byte(pos);
  36. __put_user(val, buf);
  37. }
  38. isapnp_cfg_end();
  39. *ppos = pos;
  40. return nbytes;
  41. }
  42. static const struct proc_ops isapnp_proc_bus_proc_ops = {
  43. .proc_lseek = isapnp_proc_bus_lseek,
  44. .proc_read = isapnp_proc_bus_read,
  45. };
  46. static int isapnp_proc_attach_device(struct pnp_dev *dev)
  47. {
  48. struct pnp_card *bus = dev->card;
  49. char name[16];
  50. if (!bus->procdir) {
  51. sprintf(name, "%02x", bus->number);
  52. bus->procdir = proc_mkdir(name, isapnp_proc_bus_dir);
  53. if (!bus->procdir)
  54. return -ENOMEM;
  55. }
  56. sprintf(name, "%02x", dev->number);
  57. dev->procent = proc_create_data(name, S_IFREG | S_IRUGO, bus->procdir,
  58. &isapnp_proc_bus_proc_ops, dev);
  59. if (!dev->procent)
  60. return -ENOMEM;
  61. proc_set_size(dev->procent, 256);
  62. return 0;
  63. }
  64. int __init isapnp_proc_init(void)
  65. {
  66. struct pnp_dev *dev;
  67. isapnp_proc_bus_dir = proc_mkdir("bus/isapnp", NULL);
  68. protocol_for_each_dev(&isapnp_protocol, dev) {
  69. isapnp_proc_attach_device(dev);
  70. }
  71. return 0;
  72. }