aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block
diff options
context:
space:
mode:
authorEd Cashin <ecashin@coraid.com>2012-12-17 19:03:42 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2012-12-17 20:15:24 -0500
commit667be1e757f5684576d01d7402907a2489b1402f (patch)
tree61acef58957c89392f1ee44a7df7e94fa985e157 /drivers/block
parentcd220bf51f94e6b3f7678183b6ea911cefbf7d03 (diff)
aoe: provide ATA identify device content to user on request
Make the aoe driver follow expected behavior when the user uses ioctl to get the ATA device identify information, allowing access to model, serial number, etc. Signed-off-by: Ed Cashin <ecashin@coraid.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/block')
-rw-r--r--drivers/block/aoe/aoe.h1
-rw-r--r--drivers/block/aoe/aoeblk.c30
-rw-r--r--drivers/block/aoe/aoecmd.c16
3 files changed, 47 insertions, 0 deletions
diff --git a/drivers/block/aoe/aoe.h b/drivers/block/aoe/aoe.h
index 536942b46ab6..f6e0c03fe7b2 100644
--- a/drivers/block/aoe/aoe.h
+++ b/drivers/block/aoe/aoe.h
@@ -169,6 +169,7 @@ struct aoedev {
169 struct aoetgt *htgt; /* target needing rexmit assistance */ 169 struct aoetgt *htgt; /* target needing rexmit assistance */
170 ulong ntargets; 170 ulong ntargets;
171 ulong kicked; 171 ulong kicked;
172 char ident[512];
172}; 173};
173 174
174/* kthread tracking */ 175/* kthread tracking */
diff --git a/drivers/block/aoe/aoeblk.c b/drivers/block/aoe/aoeblk.c
index 56736cd5f3fe..7ba0fcf7b06b 100644
--- a/drivers/block/aoe/aoeblk.c
+++ b/drivers/block/aoe/aoeblk.c
@@ -17,6 +17,7 @@
17#include <linux/mutex.h> 17#include <linux/mutex.h>
18#include <linux/export.h> 18#include <linux/export.h>
19#include <linux/moduleparam.h> 19#include <linux/moduleparam.h>
20#include <scsi/sg.h>
20#include "aoe.h" 21#include "aoe.h"
21 22
22static DEFINE_MUTEX(aoeblk_mutex); 23static DEFINE_MUTEX(aoeblk_mutex);
@@ -212,9 +213,38 @@ aoeblk_getgeo(struct block_device *bdev, struct hd_geometry *geo)
212 return 0; 213 return 0;
213} 214}
214 215
216static int
217aoeblk_ioctl(struct block_device *bdev, fmode_t mode, uint cmd, ulong arg)
218{
219 struct aoedev *d;
220
221 if (!arg)
222 return -EINVAL;
223
224 d = bdev->bd_disk->private_data;
225 if ((d->flags & DEVFL_UP) == 0) {
226 pr_err("aoe: disk not up\n");
227 return -ENODEV;
228 }
229
230 if (cmd == HDIO_GET_IDENTITY) {
231 if (!copy_to_user((void __user *) arg, &d->ident,
232 sizeof(d->ident)))
233 return 0;
234 return -EFAULT;
235 }
236
237 /* udev calls scsi_id, which uses SG_IO, resulting in noise */
238 if (cmd != SG_IO)
239 pr_info("aoe: unknown ioctl 0x%x\n", cmd);
240
241 return -ENOTTY;
242}
243
215static const struct block_device_operations aoe_bdops = { 244static const struct block_device_operations aoe_bdops = {
216 .open = aoeblk_open, 245 .open = aoeblk_open,
217 .release = aoeblk_release, 246 .release = aoeblk_release,
247 .ioctl = aoeblk_ioctl,
218 .getgeo = aoeblk_getgeo, 248 .getgeo = aoeblk_getgeo,
219 .owner = THIS_MODULE, 249 .owner = THIS_MODULE,
220}; 250};
diff --git a/drivers/block/aoe/aoecmd.c b/drivers/block/aoe/aoecmd.c
index 3ce01f6b3a5d..c4ff70b61e7e 100644
--- a/drivers/block/aoe/aoecmd.c
+++ b/drivers/block/aoe/aoecmd.c
@@ -799,6 +799,17 @@ aoecmd_sleepwork(struct work_struct *work)
799} 799}
800 800
801static void 801static void
802ata_ident_fixstring(u16 *id, int ns)
803{
804 u16 s;
805
806 while (ns-- > 0) {
807 s = *id;
808 *id++ = s >> 8 | s << 8;
809 }
810}
811
812static void
802ataid_complete(struct aoedev *d, struct aoetgt *t, unsigned char *id) 813ataid_complete(struct aoedev *d, struct aoetgt *t, unsigned char *id)
803{ 814{
804 u64 ssize; 815 u64 ssize;
@@ -833,6 +844,11 @@ ataid_complete(struct aoedev *d, struct aoetgt *t, unsigned char *id)
833 d->geo.sectors = get_unaligned_le16(&id[56 << 1]); 844 d->geo.sectors = get_unaligned_le16(&id[56 << 1]);
834 } 845 }
835 846
847 ata_ident_fixstring((u16 *) &id[10<<1], 10); /* serial */
848 ata_ident_fixstring((u16 *) &id[23<<1], 4); /* firmware */
849 ata_ident_fixstring((u16 *) &id[27<<1], 20); /* model */
850 memcpy(d->ident, id, sizeof(d->ident));
851
836 if (d->ssize != ssize) 852 if (d->ssize != ssize)
837 printk(KERN_INFO 853 printk(KERN_INFO
838 "aoe: %pm e%ld.%d v%04x has %llu sectors\n", 854 "aoe: %pm e%ld.%d v%04x has %llu sectors\n",