Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7abce6be authored by Pete Zaitcev's avatar Pete Zaitcev Committed by Greg Kroah-Hartman
Browse files

USB: usbmon: Implement compat_ioctl



Running a 32-bit usbmon(8) on 2.6.28-rc9 produces the following:
ioctl32(usbmon:28563): Unknown cmd fd(3) cmd(400c9206){t:ffffff92;sz:12} arg(ffd3f458) on /dev/usbmon0

It happens because the compatibility mode was implemented for 2.6.18
and not updated for the fsops.compat_ioctl API.

This patch relocates the pieces from under #ifdef CONFIG_COMPAT into
compat_ioctl with no other changes except one new whitespace.

Signed-off-by: default avatarPete Zaitcev <zaitcev@redhat.com>
Cc: stable <stable@kernel.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 11e76ae0
Loading
Loading
Loading
Loading
+66 −39
Original line number Diff line number Diff line
@@ -37,6 +37,7 @@
#define MON_IOCX_GET   _IOW(MON_IOC_MAGIC, 6, struct mon_bin_get)
#define MON_IOCX_MFETCH _IOWR(MON_IOC_MAGIC, 7, struct mon_bin_mfetch)
#define MON_IOCH_MFLUSH _IO(MON_IOC_MAGIC, 8)

#ifdef CONFIG_COMPAT
#define MON_IOCX_GET32 _IOW(MON_IOC_MAGIC, 6, struct mon_bin_get32)
#define MON_IOCX_MFETCH32 _IOWR(MON_IOC_MAGIC, 7, struct mon_bin_mfetch32)
@@ -921,21 +922,6 @@ static int mon_bin_ioctl(struct inode *inode, struct file *file,
		}
		break;

#ifdef CONFIG_COMPAT
	case MON_IOCX_GET32: {
		struct mon_bin_get32 getb;

		if (copy_from_user(&getb, (void __user *)arg,
					    sizeof(struct mon_bin_get32)))
			return -EFAULT;

		ret = mon_bin_get_event(file, rp,
		    compat_ptr(getb.hdr32), compat_ptr(getb.data32),
		    getb.alloc32);
		}
		break;
#endif

	case MON_IOCX_MFETCH:
		{
		struct mon_bin_mfetch mfetch;
@@ -962,7 +948,57 @@ static int mon_bin_ioctl(struct inode *inode, struct file *file,
		}
		break;

	case MON_IOCG_STATS: {
		struct mon_bin_stats __user *sp;
		unsigned int nevents;
		unsigned int ndropped;

		spin_lock_irqsave(&rp->b_lock, flags);
		ndropped = rp->cnt_lost;
		rp->cnt_lost = 0;
		spin_unlock_irqrestore(&rp->b_lock, flags);
		nevents = mon_bin_queued(rp);

		sp = (struct mon_bin_stats __user *)arg;
		if (put_user(rp->cnt_lost, &sp->dropped))
			return -EFAULT;
		if (put_user(nevents, &sp->queued))
			return -EFAULT;

		}
		break;

	default:
		return -ENOTTY;
	}

	return ret;
}

#ifdef CONFIG_COMPAT
static long mon_bin_compat_ioctl(struct file *file,
    unsigned int cmd, unsigned long arg)
{
	struct mon_reader_bin *rp = file->private_data;
	int ret;

	switch (cmd) {

	case MON_IOCX_GET32: {
		struct mon_bin_get32 getb;

		if (copy_from_user(&getb, (void __user *)arg,
					    sizeof(struct mon_bin_get32)))
			return -EFAULT;

		ret = mon_bin_get_event(file, rp,
		    compat_ptr(getb.hdr32), compat_ptr(getb.data32),
		    getb.alloc32);
		if (ret < 0)
			return ret;
		}
		return 0;

	case MON_IOCX_MFETCH32:
		{
		struct mon_bin_mfetch32 mfetch;
@@ -986,37 +1022,25 @@ static int mon_bin_ioctl(struct inode *inode, struct file *file,
			return ret;
		if (put_user(ret, &uptr->nfetch32))
			return -EFAULT;
		ret = 0;
		}
		break;
#endif

	case MON_IOCG_STATS: {
		struct mon_bin_stats __user *sp;
		unsigned int nevents;
		unsigned int ndropped;

		spin_lock_irqsave(&rp->b_lock, flags);
		ndropped = rp->cnt_lost;
		rp->cnt_lost = 0;
		spin_unlock_irqrestore(&rp->b_lock, flags);
		nevents = mon_bin_queued(rp);
		return 0;

		sp = (struct mon_bin_stats __user *)arg;
		if (put_user(rp->cnt_lost, &sp->dropped))
			return -EFAULT;
		if (put_user(nevents, &sp->queued))
			return -EFAULT;
	case MON_IOCG_STATS:
		return mon_bin_ioctl(NULL, file, cmd,
					    (unsigned long) compat_ptr(arg));

		}
		break;
	case MON_IOCQ_URB_LEN:
	case MON_IOCQ_RING_SIZE:
	case MON_IOCT_RING_SIZE:
	case MON_IOCH_MFLUSH:
		return mon_bin_ioctl(NULL, file, cmd, arg);

	default:
		return -ENOTTY;
		;
	}

	return ret;
	return -ENOTTY;
}
#endif /* CONFIG_COMPAT */

static unsigned int
mon_bin_poll(struct file *file, struct poll_table_struct *wait)
@@ -1094,6 +1118,9 @@ static const struct file_operations mon_fops_binary = {
	/* .write =	mon_text_write, */
	.poll =		mon_bin_poll,
	.ioctl =	mon_bin_ioctl,
#ifdef CONFIG_COMPAT
	.compat_ioctl =	mon_bin_compat_ioctl,
#endif
	.release =	mon_bin_release,
	.mmap =		mon_bin_mmap,
};