dasd_cmb.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. /*
  2. * Linux on zSeries Channel Measurement Facility support
  3. * (dasd device driver interface)
  4. *
  5. * Copyright 2000,2003 IBM Corporation
  6. *
  7. * Author: Arnd Bergmann <arndb@de.ibm.com>
  8. *
  9. * This program is free software; you can redistribute it and/or modify
  10. * it under the terms of the GNU General Public License as published by
  11. * the Free Software Foundation; either version 2, or (at your option)
  12. * any later version.
  13. *
  14. * This program is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. * GNU General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU General Public License
  20. * along with this program; if not, write to the Free Software
  21. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  22. */
  23. #include <linux/init.h>
  24. #include <linux/module.h>
  25. #include <asm/ccwdev.h>
  26. #include <asm/cmb.h>
  27. #include "dasd_int.h"
  28. static int
  29. dasd_ioctl_cmf_enable(struct block_device *bdev, int no, long args)
  30. {
  31. struct dasd_device *device;
  32. device = bdev->bd_disk->private_data;
  33. if (!device)
  34. return -EINVAL;
  35. return enable_cmf(device->cdev);
  36. }
  37. static int
  38. dasd_ioctl_cmf_disable(struct block_device *bdev, int no, long args)
  39. {
  40. struct dasd_device *device;
  41. device = bdev->bd_disk->private_data;
  42. if (!device)
  43. return -EINVAL;
  44. return disable_cmf(device->cdev);
  45. }
  46. static int
  47. dasd_ioctl_readall_cmb(struct block_device *bdev, int no, long args)
  48. {
  49. struct dasd_device *device;
  50. struct cmbdata __user *udata;
  51. struct cmbdata data;
  52. size_t size;
  53. int ret;
  54. device = bdev->bd_disk->private_data;
  55. if (!device)
  56. return -EINVAL;
  57. udata = (void __user *) args;
  58. size = _IOC_SIZE(no);
  59. if (!access_ok(VERIFY_WRITE, udata, size))
  60. return -EFAULT;
  61. ret = cmf_readall(device->cdev, &data);
  62. if (ret)
  63. return ret;
  64. if (copy_to_user(udata, &data, min(size, sizeof(*udata))))
  65. return -EFAULT;
  66. return 0;
  67. }
  68. /* module initialization below here. dasd already provides a mechanism
  69. * to dynamically register ioctl functions, so we simply use this. */
  70. static inline int
  71. ioctl_reg(unsigned int no, dasd_ioctl_fn_t handler)
  72. {
  73. return dasd_ioctl_no_register(THIS_MODULE, no, handler);
  74. }
  75. static inline void
  76. ioctl_unreg(unsigned int no, dasd_ioctl_fn_t handler)
  77. {
  78. dasd_ioctl_no_unregister(THIS_MODULE, no, handler);
  79. }
  80. static void
  81. dasd_cmf_exit(void)
  82. {
  83. ioctl_unreg(BIODASDCMFENABLE, dasd_ioctl_cmf_enable);
  84. ioctl_unreg(BIODASDCMFDISABLE, dasd_ioctl_cmf_disable);
  85. ioctl_unreg(BIODASDREADALLCMB, dasd_ioctl_readall_cmb);
  86. }
  87. static int __init
  88. dasd_cmf_init(void)
  89. {
  90. int ret;
  91. ret = ioctl_reg (BIODASDCMFENABLE, dasd_ioctl_cmf_enable);
  92. if (ret)
  93. goto err;
  94. ret = ioctl_reg (BIODASDCMFDISABLE, dasd_ioctl_cmf_disable);
  95. if (ret)
  96. goto err;
  97. ret = ioctl_reg (BIODASDREADALLCMB, dasd_ioctl_readall_cmb);
  98. if (ret)
  99. goto err;
  100. return 0;
  101. err:
  102. dasd_cmf_exit();
  103. return ret;
  104. }
  105. module_init(dasd_cmf_init);
  106. module_exit(dasd_cmf_exit);
  107. MODULE_AUTHOR("Arnd Bergmann <arndb@de.ibm.com>");
  108. MODULE_LICENSE("GPL");
  109. MODULE_DESCRIPTION("channel measurement facility interface for dasd\n"
  110. "Copyright 2003 IBM Corporation\n");