drivers/rtc/rtc-r9701.c: check that r9701_set_datetime() succeeded
[platform/adaptation/renesas_rcar/renesas_kernel.git] / block / ioctl.c
index ca939fc..ba15b2d 100644 (file)
@@ -5,7 +5,7 @@
 #include <linux/blkpg.h>
 #include <linux/hdreg.h>
 #include <linux/backing-dev.h>
-#include <linux/buffer_head.h>
+#include <linux/fs.h>
 #include <linux/blktrace_api.h>
 #include <asm/uaccess.h>
 
@@ -180,6 +180,26 @@ int __blkdev_driver_ioctl(struct block_device *bdev, fmode_t mode,
 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()
  */
 int blkdev_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd,
@@ -196,8 +216,7 @@ int blkdev_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd,
                        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);
@@ -206,8 +225,7 @@ int blkdev_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd,
 
        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;
@@ -278,6 +296,8 @@ int blkdev_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd,
                return put_uint(arg, bdev_discard_zeroes_data(bdev));
        case BLKSECTGET:
                return put_ushort(arg, queue_max_sectors(bdev_get_queue(bdev)));
+       case BLKROTATIONAL:
+               return put_ushort(arg, !blk_queue_nonrot(bdev_get_queue(bdev)));
        case BLKRASET:
        case BLKFRASET:
                if(!capable(CAP_SYS_ADMIN))