*/
 EXPORT_SYMBOL_GPL(__blkdev_driver_ioctl);
 
+/*
+ * Is it an unrecognized ioctl? The correct returns are either
+ * ENOTTY (final) or ENOIOCTLCMD ("I don't know this one, try a
+ * fallback"). ENOIOCTLCMD gets turned into ENOTTY by the ioctl
+ * code before returning.
+ *
+ * Confused drivers sometimes return EINVAL, which is wrong. It
+ * means "I understood the ioctl command, but the parameters to
+ * it were wrong".
+ *
+ * We should aim to just fix the broken drivers, the EINVAL case
+ * should go away.
+ */
+static inline int is_unrecognized_ioctl(int ret)
+{
+       return  ret == -EINVAL ||
+               ret == -ENOTTY ||
+               ret == -ENOIOCTLCMD;
+}
+
 /*
  * always keep this in sync with compat_blkdev_ioctl()
  */
                        return -EACCES;
 
                ret = __blkdev_driver_ioctl(bdev, mode, cmd, arg);
-               /* -EINVAL to handle old uncorrected drivers */
-               if (ret != -EINVAL && ret != -ENOTTY)
+               if (!is_unrecognized_ioctl(ret))
                        return ret;
 
                fsync_bdev(bdev);
 
        case BLKROSET:
                ret = __blkdev_driver_ioctl(bdev, mode, cmd, arg);
-               /* -EINVAL to handle old uncorrected drivers */
-               if (ret != -EINVAL && ret != -ENOTTY)
+               if (!is_unrecognized_ioctl(ret))
                        return ret;
                if (!capable(CAP_SYS_ADMIN))
                        return -EACCES;
 
        return -ENOIOCTLCMD;
 }
 
-static void compat_ioctl_error(struct file *filp, unsigned int fd,
-               unsigned int cmd, unsigned long arg)
-{
-       char buf[10];
-       char *fn = "?";
-       char *path;
-
-       /* find the name of the device. */
-       path = (char *)__get_free_page(GFP_KERNEL);
-       if (path) {
-               fn = d_path(&filp->f_path, path, PAGE_SIZE);
-               if (IS_ERR(fn))
-                       fn = "?";
-       }
-
-        sprintf(buf,"'%c'", (cmd>>_IOC_TYPESHIFT) & _IOC_TYPEMASK);
-       if (!isprint(buf[1]))
-               sprintf(buf, "%02x", buf[1]);
-       compat_printk("ioctl32(%s:%d): Unknown cmd fd(%d) "
-                       "cmd(%08x){t:%s;sz:%u} arg(%08x) on %s\n",
-                       current->comm, current->pid,
-                       (int)fd, (unsigned int)cmd, buf,
-                       (cmd >> _IOC_SIZESHIFT) & _IOC_SIZEMASK,
-                       (unsigned int)arg, fn);
-
-       if (path)
-               free_page((unsigned long)path);
-}
-
 static int compat_ioctl_check_table(unsigned int xcmd)
 {
        int i;
                goto found_handler;
 
        error = do_ioctl_trans(fd, cmd, arg, filp);
-       if (error == -ENOIOCTLCMD) {
-               static int count;
-
-               if (++count <= 50)
-                       compat_ioctl_error(filp, fd, cmd, arg);
-               error = -EINVAL;
-       }
+       if (error == -ENOIOCTLCMD)
+               error = -ENOTTY;
 
        goto out_fput;
 
 
 
        error = filp->f_op->unlocked_ioctl(filp, cmd, arg);
        if (error == -ENOIOCTLCMD)
-               error = -EINVAL;
+               error = -ENOTTY;
  out:
        return error;
 }
 
 
                return dev_ioctl(net, cmd, uifr);
        default:
-               return -EINVAL;
+               return -ENOIOCTLCMD;
        }
 }
 
                return sock_do_ioctl(net, sock, cmd, arg);
        }
 
-       /* Prevent warning from compat_sys_ioctl, these always
-        * result in -EINVAL in the native case anyway. */
-       switch (cmd) {
-       case SIOCRTMSG:
-       case SIOCGIFCOUNT:
-       case SIOCSRARP:
-       case SIOCGRARP:
-       case SIOCDRARP:
-       case SIOCSIFLINK:
-       case SIOCGIFSLAVE:
-       case SIOCSIFSLAVE:
-               return -EINVAL;
-       }
-
        return -ENOIOCTLCMD;
 }