1 #define DEBUG_SUBSYSTEM S_CLASS
6 #include <mach/mach_types.h>
10 #include <miscfs/devfs/devfs.h>
12 #include <libcfs/libcfs.h>
13 #include <obd_support.h>
14 #include <obd_class.h>
15 #include <lprocfs_status.h>
17 #ifndef OBD_MAX_IOCTL_BUFFER
18 #define OBD_MAX_IOCTL_BUFFER 8192
21 /* buffer MUST be at least the size of obd_ioctl_hdr */
22 int obd_ioctl_getdata(char **buf, int *len, void *arg)
24 struct obd_ioctl_hdr *hdr;
25 struct obd_ioctl_data *data;
30 hdr = (struct obd_ioctl_hdr *)arg;
31 if (hdr->ioc_version != OBD_IOCTL_VERSION) {
32 CERROR("Version mismatch kernel vs application\n");
36 if (hdr->ioc_len > OBD_MAX_IOCTL_BUFFER) {
37 CERROR("User buffer len %d exceeds %d max buffer\n",
38 hdr->ioc_len, OBD_MAX_IOCTL_BUFFER);
42 if (hdr->ioc_len < sizeof(struct obd_ioctl_data)) {
43 CERROR("OBD: user buffer too small for ioctl (%d)\n", hdr->ioc_len);
47 /* XXX allocate this more intelligently, using kmalloc when
49 OBD_VMALLOC(*buf, hdr->ioc_len);
51 CERROR("Cannot allocate control buffer of len %d\n",
56 data = (struct obd_ioctl_data *)*buf;
58 bzero(data, hdr->ioc_len);
59 memcpy(data, (void *)arg, sizeof(struct obd_ioctl_data));
60 if (data->ioc_inlbuf1)
61 err = copy_from_user(&data->ioc_bulk[0], (void *)data->ioc_inlbuf1,
62 hdr->ioc_len - ((void *)&data->ioc_bulk[0] - (void *)data));
64 if (obd_ioctl_is_invalid(data)) {
65 CERROR("ioctl not correctly formatted\n");
69 if (data->ioc_inllen1) {
70 data->ioc_inlbuf1 = &data->ioc_bulk[0];
71 offset += size_round(data->ioc_inllen1);
74 if (data->ioc_inllen2) {
75 data->ioc_inlbuf2 = &data->ioc_bulk[0] + offset;
76 offset += size_round(data->ioc_inllen2);
79 if (data->ioc_inllen3) {
80 data->ioc_inlbuf3 = &data->ioc_bulk[0] + offset;
81 offset += size_round(data->ioc_inllen3);
84 if (data->ioc_inllen4) {
85 data->ioc_inlbuf4 = &data->ioc_bulk[0] + offset;
92 int obd_ioctl_popdata(void *arg, void *data, int len)
95 * Xnu ioctl copyout(uaddr, arg, sizeof(struct obd_ioctl_data)),
96 * we have to copyout data exceed sizeof(struct obd_ioctl_data)
99 if (len <= sizeof(struct obd_ioctl_data)) {
100 memcpy(arg, data, len);
104 struct obd_ioctl_data *u = (struct obd_ioctl_data *)arg;
105 struct obd_ioctl_data *k = (struct obd_ioctl_data *)data;
106 err = copy_to_user((void *)u->ioc_inlbuf1, &k->ioc_bulk[0],
107 len -((void *)&k->ioc_bulk[0] -(void *)k));
108 memcpy(arg, data, sizeof(struct obd_ioctl_data));
115 extern struct cfs_psdev_ops obd_psdev_ops;
118 obd_class_open(dev_t dev, int flags, int devtype, struct proc *p)
120 if (obd_psdev_ops.p_open != NULL)
121 return -obd_psdev_ops.p_open(0, NULL);
125 /* closing /dev/obd */
127 obd_class_release(dev_t dev, int flags, int mode, struct proc *p)
129 if (obd_psdev_ops.p_close != NULL)
130 return -obd_psdev_ops.p_close(0, NULL);
135 obd_class_ioctl(dev_t dev, u_long cmd, caddr_t arg, int flag, struct proc *p)
142 if (obd_psdev_ops.p_ioctl != NULL)
143 err = -obd_psdev_ops.p_ioctl(NULL, cmd, (void *)arg);
150 static struct cdevsw obd_psdevsw = {
166 cfs_psdev_t obd_psdev = {
173 int class_procfs_init(void)
178 int class_procfs_clean(void)