This patch makes the aoe driver follow expected behavior when
the user uses ioctl to get the ATA device identify information.

Signed-off-by: Ed Cashin <ecas...@coraid.com>
---
 drivers/block/aoe/aoe.h    |    1 +
 drivers/block/aoe/aoeblk.c |   30 ++++++++++++++++++++++++++++++
 drivers/block/aoe/aoecmd.c |   16 ++++++++++++++++
 3 files changed, 47 insertions(+), 0 deletions(-)

diff --git a/drivers/block/aoe/aoe.h b/drivers/block/aoe/aoe.h
index 536942b..f6e0c03 100644
--- a/drivers/block/aoe/aoe.h
+++ b/drivers/block/aoe/aoe.h
@@ -169,6 +169,7 @@ struct aoedev {
        struct aoetgt *htgt;    /* target needing rexmit assistance */
        ulong ntargets;
        ulong kicked;
+       char ident[512];
 };
 
 /* kthread tracking */
diff --git a/drivers/block/aoe/aoeblk.c b/drivers/block/aoe/aoeblk.c
index 56736cd..7ba0fcf 100644
--- a/drivers/block/aoe/aoeblk.c
+++ b/drivers/block/aoe/aoeblk.c
@@ -17,6 +17,7 @@
 #include <linux/mutex.h>
 #include <linux/export.h>
 #include <linux/moduleparam.h>
+#include <scsi/sg.h>
 #include "aoe.h"
 
 static DEFINE_MUTEX(aoeblk_mutex);
@@ -212,9 +213,38 @@ aoeblk_getgeo(struct block_device *bdev, struct 
hd_geometry *geo)
        return 0;
 }
 
+static int
+aoeblk_ioctl(struct block_device *bdev, fmode_t mode, uint cmd, ulong arg)
+{
+       struct aoedev *d;
+
+       if (!arg)
+               return -EINVAL;
+
+       d = bdev->bd_disk->private_data;
+       if ((d->flags & DEVFL_UP) == 0) {
+               pr_err("aoe: disk not up\n");
+               return -ENODEV;
+       }
+
+       if (cmd == HDIO_GET_IDENTITY) {
+               if (!copy_to_user((void __user *) arg, &d->ident,
+                       sizeof(d->ident)))
+                       return 0;
+               return -EFAULT;
+       }
+
+       /* udev calls scsi_id, which uses SG_IO, resulting in noise */
+       if (cmd != SG_IO)
+               pr_info("aoe: unknown ioctl 0x%x\n", cmd);
+
+       return -ENOTTY;
+}
+
 static const struct block_device_operations aoe_bdops = {
        .open = aoeblk_open,
        .release = aoeblk_release,
+       .ioctl = aoeblk_ioctl,
        .getgeo = aoeblk_getgeo,
        .owner = THIS_MODULE,
 };
diff --git a/drivers/block/aoe/aoecmd.c b/drivers/block/aoe/aoecmd.c
index 3ce01f6..c4ff70b 100644
--- a/drivers/block/aoe/aoecmd.c
+++ b/drivers/block/aoe/aoecmd.c
@@ -799,6 +799,17 @@ aoecmd_sleepwork(struct work_struct *work)
 }
 
 static void
+ata_ident_fixstring(u16 *id, int ns)
+{
+       u16 s;
+
+       while (ns-- > 0) {
+               s = *id;
+               *id++ = s >> 8 | s << 8;
+       }
+}
+
+static void
 ataid_complete(struct aoedev *d, struct aoetgt *t, unsigned char *id)
 {
        u64 ssize;
@@ -833,6 +844,11 @@ ataid_complete(struct aoedev *d, struct aoetgt *t, 
unsigned char *id)
                d->geo.sectors = get_unaligned_le16(&id[56 << 1]);
        }
 
+       ata_ident_fixstring((u16 *) &id[10<<1], 10);    /* serial */
+       ata_ident_fixstring((u16 *) &id[23<<1], 4);     /* firmware */
+       ata_ident_fixstring((u16 *) &id[27<<1], 20);    /* model */
+       memcpy(d->ident, id, sizeof(d->ident));
+
        if (d->ssize != ssize)
                printk(KERN_INFO
                        "aoe: %pm e%ld.%d v%04x has %llu sectors\n",
-- 
1.7.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to