aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/um/drivers/ubd_kern.c21
-rw-r--r--block/ioctl.c22
-rw-r--r--drivers/acorn/block/mfmhd.c36
-rw-r--r--drivers/block/DAC960.c35
-rw-r--r--drivers/block/acsi.c26
-rw-r--r--drivers/block/amiflop.c23
-rw-r--r--drivers/block/aoe/aoeblk.c26
-rw-r--r--drivers/block/cciss.c31
-rw-r--r--drivers/block/cpqarray.c36
-rw-r--r--drivers/block/floppy.c35
-rw-r--r--drivers/block/paride/pd.c34
-rw-r--r--drivers/block/paride/pf.c50
-rw-r--r--drivers/block/ps2esdi.c25
-rw-r--r--drivers/block/sx8.c35
-rw-r--r--drivers/block/umem.c41
-rw-r--r--drivers/block/viodasd.c44
-rw-r--r--drivers/block/xd.c25
-rw-r--r--drivers/ide/ide-disk.c12
-rw-r--r--drivers/ide/ide-floppy.c12
-rw-r--r--drivers/ide/ide.c13
-rw-r--r--drivers/ide/legacy/hd.c24
-rw-r--r--drivers/md/md.c30
-rw-r--r--drivers/message/i2o/i2o_block.c18
-rw-r--r--drivers/mmc/mmc_block.c25
-rw-r--r--drivers/mtd/mtd_blkdevs.c25
-rw-r--r--drivers/s390/block/dasd.c23
-rw-r--r--drivers/s390/block/dasd_ioctl.c28
-rw-r--r--drivers/s390/block/xpram.c18
-rw-r--r--drivers/scsi/sd.c21
-rw-r--r--include/linux/fs.h2
30 files changed, 340 insertions, 456 deletions
diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c
index 73f9652b2ee9..3a93c6f772fa 100644
--- a/arch/um/drivers/ubd_kern.c
+++ b/arch/um/drivers/ubd_kern.c
@@ -117,6 +117,7 @@ static int ubd_open(struct inode * inode, struct file * filp);
117static int ubd_release(struct inode * inode, struct file * file); 117static int ubd_release(struct inode * inode, struct file * file);
118static int ubd_ioctl(struct inode * inode, struct file * file, 118static int ubd_ioctl(struct inode * inode, struct file * file,
119 unsigned int cmd, unsigned long arg); 119 unsigned int cmd, unsigned long arg);
120static int ubd_getgeo(struct block_device *bdev, struct hd_geometry *geo);
120 121
121#define MAX_DEV (8) 122#define MAX_DEV (8)
122 123
@@ -125,6 +126,7 @@ static struct block_device_operations ubd_blops = {
125 .open = ubd_open, 126 .open = ubd_open,
126 .release = ubd_release, 127 .release = ubd_release,
127 .ioctl = ubd_ioctl, 128 .ioctl = ubd_ioctl,
129 .getgeo = ubd_getgeo,
128}; 130};
129 131
130/* Protected by the queue_lock */ 132/* Protected by the queue_lock */
@@ -1058,6 +1060,16 @@ static void do_ubd_request(request_queue_t *q)
1058 } 1060 }
1059} 1061}
1060 1062
1063static int ubd_getgeo(struct block_device *bdev, struct hd_geometry *geo)
1064{
1065 struct ubd *dev = bdev->bd_disk->private_data;
1066
1067 geo->heads = 128;
1068 geo->sectors = 32;
1069 geo->cylinders = dev->size / (128 * 32 * 512);
1070 return 0;
1071}
1072
1061static int ubd_ioctl(struct inode * inode, struct file * file, 1073static int ubd_ioctl(struct inode * inode, struct file * file,
1062 unsigned int cmd, unsigned long arg) 1074 unsigned int cmd, unsigned long arg)
1063{ 1075{
@@ -1070,16 +1082,7 @@ static int ubd_ioctl(struct inode * inode, struct file * file,
1070 }; 1082 };
1071 1083
1072 switch (cmd) { 1084 switch (cmd) {
1073 struct hd_geometry g;
1074 struct cdrom_volctrl volume; 1085 struct cdrom_volctrl volume;
1075 case HDIO_GETGEO:
1076 if(!loc) return(-EINVAL);
1077 g.heads = 128;
1078 g.sectors = 32;
1079 g.cylinders = dev->size / (128 * 32 * 512);
1080 g.start = get_start_sect(inode->i_bdev);
1081 return(copy_to_user(loc, &g, sizeof(g)) ? -EFAULT : 0);
1082
1083 case HDIO_GET_IDENTITY: 1086 case HDIO_GET_IDENTITY:
1084 ubd_id.cyls = dev->size / (128 * 32 * 512); 1087 ubd_id.cyls = dev->size / (128 * 32 * 512);
1085 if(copy_to_user((char __user *) arg, (char *) &ubd_id, 1088 if(copy_to_user((char __user *) arg, (char *) &ubd_id,
diff --git a/block/ioctl.c b/block/ioctl.c
index 6e278474f9a8..82030e1dfd63 100644
--- a/block/ioctl.c
+++ b/block/ioctl.c
@@ -1,6 +1,7 @@
1#include <linux/sched.h> /* for capable() */ 1#include <linux/sched.h> /* for capable() */
2#include <linux/blkdev.h> 2#include <linux/blkdev.h>
3#include <linux/blkpg.h> 3#include <linux/blkpg.h>
4#include <linux/hdreg.h>
4#include <linux/backing-dev.h> 5#include <linux/backing-dev.h>
5#include <linux/buffer_head.h> 6#include <linux/buffer_head.h>
6#include <linux/smp_lock.h> 7#include <linux/smp_lock.h>
@@ -245,6 +246,27 @@ int blkdev_ioctl(struct inode *inode, struct file *file, unsigned cmd,
245 set_device_ro(bdev, n); 246 set_device_ro(bdev, n);
246 unlock_kernel(); 247 unlock_kernel();
247 return 0; 248 return 0;
249 case HDIO_GETGEO: {
250 struct hd_geometry geo;
251
252 if (!arg)
253 return -EINVAL;
254 if (!disk->fops->getgeo)
255 return -ENOTTY;
256
257 /*
258 * We need to set the startsect first, the driver may
259 * want to override it.
260 */
261 geo.start = get_start_sect(bdev);
262 ret = disk->fops->getgeo(bdev, &geo);
263 if (ret)
264 return ret;
265 if (copy_to_user((struct hd_geometry __user *)arg, &geo,
266 sizeof(geo)))
267 return -EFAULT;
268 return 0;
269 }
248 } 270 }
249 271
250 lock_kernel(); 272 lock_kernel();
diff --git a/drivers/acorn/block/mfmhd.c b/drivers/acorn/block/mfmhd.c
index 4b65f74d66b1..ce074f6f3369 100644
--- a/drivers/acorn/block/mfmhd.c
+++ b/drivers/acorn/block/mfmhd.c
@@ -129,19 +129,6 @@ static DEFINE_SPINLOCK(mfm_lock);
129#define MAJOR_NR MFM_ACORN_MAJOR 129#define MAJOR_NR MFM_ACORN_MAJOR
130#define QUEUE (mfm_queue) 130#define QUEUE (mfm_queue)
131#define CURRENT elv_next_request(mfm_queue) 131#define CURRENT elv_next_request(mfm_queue)
132/*
133 * This sort of stuff should be in a header file shared with ide.c, hd.c, xd.c etc
134 */
135#ifndef HDIO_GETGEO
136#define HDIO_GETGEO 0x301
137struct hd_geometry {
138 unsigned char heads;
139 unsigned char sectors;
140 unsigned short cylinders;
141 unsigned long start;
142};
143#endif
144
145 132
146/* 133/*
147 * Configuration section 134 * Configuration section
@@ -1153,22 +1140,13 @@ static int mfm_initdrives(void)
1153 * The 'front' end of the mfm driver follows... 1140 * The 'front' end of the mfm driver follows...
1154 */ 1141 */
1155 1142
1156static int mfm_ioctl(struct inode *inode, struct file *file, u_int cmd, u_long arg) 1143static int mfm_getgeo(struct block_device *bdev, struct hd_geometry *geo)
1157{ 1144{
1158 struct mfm_info *p = inode->i_bdev->bd_disk->private_data; 1145 struct mfm_info *p = bdev->bd_disk->private_data;
1159 struct hd_geometry *geo = (struct hd_geometry *) arg; 1146
1160 if (cmd != HDIO_GETGEO) 1147 geo->heads = p->heads;
1161 return -EINVAL; 1148 geo->sectors = p->sectors;
1162 if (!arg) 1149 geo->cylinders = p->cylinders;
1163 return -EINVAL;
1164 if (put_user (p->heads, &geo->heads))
1165 return -EFAULT;
1166 if (put_user (p->sectors, &geo->sectors))
1167 return -EFAULT;
1168 if (put_user (p->cylinders, &geo->cylinders))
1169 return -EFAULT;
1170 if (put_user (get_start_sect(inode->i_bdev), &geo->start))
1171 return -EFAULT;
1172 return 0; 1150 return 0;
1173} 1151}
1174 1152
@@ -1219,7 +1197,7 @@ void xd_set_geometry(struct block_device *bdev, unsigned char secsptrack,
1219static struct block_device_operations mfm_fops = 1197static struct block_device_operations mfm_fops =
1220{ 1198{
1221 .owner = THIS_MODULE, 1199 .owner = THIS_MODULE,
1222 .ioctl = mfm_ioctl, 1200 .getgeo = mfm_getgeo,
1223}; 1201};
1224 1202
1225/* 1203/*
diff --git a/drivers/block/DAC960.c b/drivers/block/DAC960.c
index 21097a39a057..179c68a3cef3 100644
--- a/drivers/block/DAC960.c
+++ b/drivers/block/DAC960.c
@@ -92,34 +92,28 @@ static int DAC960_open(struct inode *inode, struct file *file)
92 return 0; 92 return 0;
93} 93}
94 94
95static int DAC960_ioctl(struct inode *inode, struct file *file, 95static int DAC960_getgeo(struct block_device *bdev, struct hd_geometry *geo)
96 unsigned int cmd, unsigned long arg)
97{ 96{
98 struct gendisk *disk = inode->i_bdev->bd_disk; 97 struct gendisk *disk = bdev->bd_disk;
99 DAC960_Controller_T *p = disk->queue->queuedata; 98 DAC960_Controller_T *p = disk->queue->queuedata;
100 int drive_nr = (long)disk->private_data; 99 int drive_nr = (long)disk->private_data;
101 struct hd_geometry g;
102 struct hd_geometry __user *loc = (struct hd_geometry __user *)arg;
103
104 if (cmd != HDIO_GETGEO || !loc)
105 return -EINVAL;
106 100
107 if (p->FirmwareType == DAC960_V1_Controller) { 101 if (p->FirmwareType == DAC960_V1_Controller) {
108 g.heads = p->V1.GeometryTranslationHeads; 102 geo->heads = p->V1.GeometryTranslationHeads;
109 g.sectors = p->V1.GeometryTranslationSectors; 103 geo->sectors = p->V1.GeometryTranslationSectors;
110 g.cylinders = p->V1.LogicalDriveInformation[drive_nr]. 104 geo->cylinders = p->V1.LogicalDriveInformation[drive_nr].
111 LogicalDriveSize / (g.heads * g.sectors); 105 LogicalDriveSize / (geo->heads * geo->sectors);
112 } else { 106 } else {
113 DAC960_V2_LogicalDeviceInfo_T *i = 107 DAC960_V2_LogicalDeviceInfo_T *i =
114 p->V2.LogicalDeviceInformation[drive_nr]; 108 p->V2.LogicalDeviceInformation[drive_nr];
115 switch (i->DriveGeometry) { 109 switch (i->DriveGeometry) {
116 case DAC960_V2_Geometry_128_32: 110 case DAC960_V2_Geometry_128_32:
117 g.heads = 128; 111 geo->heads = 128;
118 g.sectors = 32; 112 geo->sectors = 32;
119 break; 113 break;
120 case DAC960_V2_Geometry_255_63: 114 case DAC960_V2_Geometry_255_63:
121 g.heads = 255; 115 geo->heads = 255;
122 g.sectors = 63; 116 geo->sectors = 63;
123 break; 117 break;
124 default: 118 default:
125 DAC960_Error("Illegal Logical Device Geometry %d\n", 119 DAC960_Error("Illegal Logical Device Geometry %d\n",
@@ -127,12 +121,11 @@ static int DAC960_ioctl(struct inode *inode, struct file *file,
127 return -EINVAL; 121 return -EINVAL;
128 } 122 }
129 123
130 g.cylinders = i->ConfigurableDeviceSize / (g.heads * g.sectors); 124 geo->cylinders = i->ConfigurableDeviceSize /
125 (geo->heads * geo->sectors);
131 } 126 }
132 127
133 g.start = get_start_sect(inode->i_bdev); 128 return 0;
134
135 return copy_to_user(loc, &g, sizeof g) ? -EFAULT : 0;
136} 129}
137 130
138static int DAC960_media_changed(struct gendisk *disk) 131static int DAC960_media_changed(struct gendisk *disk)
@@ -157,7 +150,7 @@ static int DAC960_revalidate_disk(struct gendisk *disk)
157static struct block_device_operations DAC960_BlockDeviceOperations = { 150static struct block_device_operations DAC960_BlockDeviceOperations = {
158 .owner = THIS_MODULE, 151 .owner = THIS_MODULE,
159 .open = DAC960_open, 152 .open = DAC960_open,
160 .ioctl = DAC960_ioctl, 153 .getgeo = DAC960_getgeo,
161 .media_changed = DAC960_media_changed, 154 .media_changed = DAC960_media_changed,
162 .revalidate_disk = DAC960_revalidate_disk, 155 .revalidate_disk = DAC960_revalidate_disk,
163}; 156};
diff --git a/drivers/block/acsi.c b/drivers/block/acsi.c
index 5d2d649f7e8d..196c0ec9cd54 100644
--- a/drivers/block/acsi.c
+++ b/drivers/block/acsi.c
@@ -1079,6 +1079,19 @@ static void redo_acsi_request( void )
1079 * 1079 *
1080 ***********************************************************************/ 1080 ***********************************************************************/
1081 1081
1082static int acsi_getgeo(struct block_device *bdev, struct hd_geometry *geo)
1083{
1084 struct acsi_info_struct *aip = bdev->bd_disk->private_data;
1085
1086 /*
1087 * Just fake some geometry here, it's nonsense anyway
1088 * To make it easy, use Adaptec's usual 64/32 mapping
1089 */
1090 geo->heads = 64;
1091 geo->sectors = 32;
1092 geo->cylinders = aip->size >> 11;
1093 return 0;
1094}
1082 1095
1083static int acsi_ioctl( struct inode *inode, struct file *file, 1096static int acsi_ioctl( struct inode *inode, struct file *file,
1084 unsigned int cmd, unsigned long arg ) 1097 unsigned int cmd, unsigned long arg )
@@ -1086,18 +1099,6 @@ static int acsi_ioctl( struct inode *inode, struct file *file,
1086 struct gendisk *disk = inode->i_bdev->bd_disk; 1099 struct gendisk *disk = inode->i_bdev->bd_disk;
1087 struct acsi_info_struct *aip = disk->private_data; 1100 struct acsi_info_struct *aip = disk->private_data;
1088 switch (cmd) { 1101 switch (cmd) {
1089 case HDIO_GETGEO:
1090 /* HDIO_GETGEO is supported more for getting the partition's
1091 * start sector... */
1092 { struct hd_geometry *geo = (struct hd_geometry *)arg;
1093 /* just fake some geometry here, it's nonsense anyway; to make it
1094 * easy, use Adaptec's usual 64/32 mapping */
1095 put_user( 64, &geo->heads );
1096 put_user( 32, &geo->sectors );
1097 put_user( aip->size >> 11, &geo->cylinders );
1098 put_user(get_start_sect(inode->i_bdev), &geo->start);
1099 return 0;
1100 }
1101 case SCSI_IOCTL_GET_IDLUN: 1102 case SCSI_IOCTL_GET_IDLUN:
1102 /* SCSI compatible GET_IDLUN call to get target's ID and LUN number */ 1103 /* SCSI compatible GET_IDLUN call to get target's ID and LUN number */
1103 put_user( aip->target | (aip->lun << 8), 1104 put_user( aip->target | (aip->lun << 8),
@@ -1592,6 +1593,7 @@ static struct block_device_operations acsi_fops = {
1592 .open = acsi_open, 1593 .open = acsi_open,
1593 .release = acsi_release, 1594 .release = acsi_release,
1594 .ioctl = acsi_ioctl, 1595 .ioctl = acsi_ioctl,
1596 .getgeo = acsi_getgeo,
1595 .media_changed = acsi_media_change, 1597 .media_changed = acsi_media_change,
1596 .revalidate_disk= acsi_revalidate, 1598 .revalidate_disk= acsi_revalidate,
1597}; 1599};
diff --git a/drivers/block/amiflop.c b/drivers/block/amiflop.c
index 0acbfff8ad28..cb2a545e57dc 100644
--- a/drivers/block/amiflop.c
+++ b/drivers/block/amiflop.c
@@ -1424,6 +1424,16 @@ static void do_fd_request(request_queue_t * q)
1424 redo_fd_request(); 1424 redo_fd_request();
1425} 1425}
1426 1426
1427static int fd_getgeo(struct block_device *bdev, struct hd_geometry *geo)
1428{
1429 int drive = MINOR(bdev->bd_dev) & 3;
1430
1431 geo->heads = unit[drive].type->heads;
1432 geo->sectors = unit[drive].dtype->sects * unit[drive].type->sect_mult;
1433 geo->cylinders = unit[drive].type->tracks;
1434 return 0;
1435}
1436
1427static int fd_ioctl(struct inode *inode, struct file *filp, 1437static int fd_ioctl(struct inode *inode, struct file *filp,
1428 unsigned int cmd, unsigned long param) 1438 unsigned int cmd, unsigned long param)
1429{ 1439{
@@ -1431,18 +1441,6 @@ static int fd_ioctl(struct inode *inode, struct file *filp,
1431 static struct floppy_struct getprm; 1441 static struct floppy_struct getprm;
1432 1442
1433 switch(cmd){ 1443 switch(cmd){
1434 case HDIO_GETGEO:
1435 {
1436 struct hd_geometry loc;
1437 loc.heads = unit[drive].type->heads;
1438 loc.sectors = unit[drive].dtype->sects * unit[drive].type->sect_mult;
1439 loc.cylinders = unit[drive].type->tracks;
1440 loc.start = 0;
1441 if (copy_to_user((void *)param, (void *)&loc,
1442 sizeof(struct hd_geometry)))
1443 return -EFAULT;
1444 break;
1445 }
1446 case FDFMTBEG: 1444 case FDFMTBEG:
1447 get_fdc(drive); 1445 get_fdc(drive);
1448 if (fd_ref[drive] > 1) { 1446 if (fd_ref[drive] > 1) {
@@ -1652,6 +1650,7 @@ static struct block_device_operations floppy_fops = {
1652 .open = floppy_open, 1650 .open = floppy_open,
1653 .release = floppy_release, 1651 .release = floppy_release,
1654 .ioctl = fd_ioctl, 1652 .ioctl = fd_ioctl,
1653 .getgeo = fd_getgeo,
1655 .media_changed = amiga_floppy_change, 1654 .media_changed = amiga_floppy_change,
1656}; 1655};
1657 1656
diff --git a/drivers/block/aoe/aoeblk.c b/drivers/block/aoe/aoeblk.c
index 0e97fcb9f3a1..c05ee8bffd97 100644
--- a/drivers/block/aoe/aoeblk.c
+++ b/drivers/block/aoe/aoeblk.c
@@ -169,38 +169,26 @@ aoeblk_make_request(request_queue_t *q, struct bio *bio)
169 return 0; 169 return 0;
170} 170}
171 171
172/* This ioctl implementation expects userland to have the device node
173 * permissions set so that only priviledged users can open an aoe
174 * block device directly.
175 */
176static int 172static int
177aoeblk_ioctl(struct inode *inode, struct file *filp, uint cmd, ulong arg) 173aoeblk_getgeo(struct block_device *bdev, struct hd_geometry *geo)
178{ 174{
179 struct aoedev *d; 175 struct aoedev *d = bdev->bd_disk->private_data;
180
181 if (!arg)
182 return -EINVAL;
183 176
184 d = inode->i_bdev->bd_disk->private_data;
185 if ((d->flags & DEVFL_UP) == 0) { 177 if ((d->flags & DEVFL_UP) == 0) {
186 printk(KERN_ERR "aoe: aoeblk_ioctl: disk not up\n"); 178 printk(KERN_ERR "aoe: aoeblk_ioctl: disk not up\n");
187 return -ENODEV; 179 return -ENODEV;
188 } 180 }
189 181
190 if (cmd == HDIO_GETGEO) { 182 geo->cylinders = d->geo.cylinders;
191 d->geo.start = get_start_sect(inode->i_bdev); 183 geo->heads = d->geo.heads;
192 if (!copy_to_user((void __user *) arg, &d->geo, sizeof d->geo)) 184 geo->sectors = d->geo.sectors;
193 return 0; 185 return 0;
194 return -EFAULT;
195 }
196 printk(KERN_INFO "aoe: aoeblk_ioctl: unknown ioctl %d\n", cmd);
197 return -EINVAL;
198} 186}
199 187
200static struct block_device_operations aoe_bdops = { 188static struct block_device_operations aoe_bdops = {
201 .open = aoeblk_open, 189 .open = aoeblk_open,
202 .release = aoeblk_release, 190 .release = aoeblk_release,
203 .ioctl = aoeblk_ioctl, 191 .getgeo = aoeblk_getgeo,
204 .owner = THIS_MODULE, 192 .owner = THIS_MODULE,
205}; 193};
206 194
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c
index d2815b7a9150..bdb9c2717d40 100644
--- a/drivers/block/cciss.c
+++ b/drivers/block/cciss.c
@@ -153,6 +153,7 @@ static int cciss_open(struct inode *inode, struct file *filep);
153static int cciss_release(struct inode *inode, struct file *filep); 153static int cciss_release(struct inode *inode, struct file *filep);
154static int cciss_ioctl(struct inode *inode, struct file *filep, 154static int cciss_ioctl(struct inode *inode, struct file *filep,
155 unsigned int cmd, unsigned long arg); 155 unsigned int cmd, unsigned long arg);
156static int cciss_getgeo(struct block_device *bdev, struct hd_geometry *geo);
156 157
157static int revalidate_allvol(ctlr_info_t *host); 158static int revalidate_allvol(ctlr_info_t *host);
158static int cciss_revalidate(struct gendisk *disk); 159static int cciss_revalidate(struct gendisk *disk);
@@ -194,6 +195,7 @@ static struct block_device_operations cciss_fops = {
194 .open = cciss_open, 195 .open = cciss_open,
195 .release = cciss_release, 196 .release = cciss_release,
196 .ioctl = cciss_ioctl, 197 .ioctl = cciss_ioctl,
198 .getgeo = cciss_getgeo,
197#ifdef CONFIG_COMPAT 199#ifdef CONFIG_COMPAT
198 .compat_ioctl = cciss_compat_ioctl, 200 .compat_ioctl = cciss_compat_ioctl,
199#endif 201#endif
@@ -633,6 +635,20 @@ static int cciss_ioctl32_big_passthru(struct file *file, unsigned cmd, unsigned
633 return err; 635 return err;
634} 636}
635#endif 637#endif
638
639static int cciss_getgeo(struct block_device *bdev, struct hd_geometry *geo)
640{
641 drive_info_struct *drv = get_drv(bdev->bd_disk);
642
643 if (!drv->cylinders)
644 return -ENXIO;
645
646 geo->heads = drv->heads;
647 geo->sectors = drv->sectors;
648 geo->cylinders = drv->cylinders;
649 return 0;
650}
651
636/* 652/*
637 * ioctl 653 * ioctl
638 */ 654 */
@@ -651,21 +667,6 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
651#endif /* CCISS_DEBUG */ 667#endif /* CCISS_DEBUG */
652 668
653 switch(cmd) { 669 switch(cmd) {
654 case HDIO_GETGEO:
655 {
656 struct hd_geometry driver_geo;
657 if (drv->cylinders) {
658 driver_geo.heads = drv->heads;
659 driver_geo.sectors = drv->sectors;
660 driver_geo.cylinders = drv->cylinders;
661 } else
662 return -ENXIO;
663 driver_geo.start= get_start_sect(inode->i_bdev);
664 if (copy_to_user(argp, &driver_geo, sizeof(struct hd_geometry)))
665 return -EFAULT;
666 return(0);
667 }
668
669 case CCISS_GETPCIINFO: 670 case CCISS_GETPCIINFO:
670 { 671 {
671 cciss_pci_info_struct pciinfo; 672 cciss_pci_info_struct pciinfo;
diff --git a/drivers/block/cpqarray.c b/drivers/block/cpqarray.c
index 9bddb6874873..9f0664dd3800 100644
--- a/drivers/block/cpqarray.c
+++ b/drivers/block/cpqarray.c
@@ -160,6 +160,7 @@ static int sendcmd(
160static int ida_open(struct inode *inode, struct file *filep); 160static int ida_open(struct inode *inode, struct file *filep);
161static int ida_release(struct inode *inode, struct file *filep); 161static int ida_release(struct inode *inode, struct file *filep);
162static int ida_ioctl(struct inode *inode, struct file *filep, unsigned int cmd, unsigned long arg); 162static int ida_ioctl(struct inode *inode, struct file *filep, unsigned int cmd, unsigned long arg);
163static int ida_getgeo(struct block_device *bdev, struct hd_geometry *geo);
163static int ida_ctlr_ioctl(ctlr_info_t *h, int dsk, ida_ioctl_t *io); 164static int ida_ctlr_ioctl(ctlr_info_t *h, int dsk, ida_ioctl_t *io);
164 165
165static void do_ida_request(request_queue_t *q); 166static void do_ida_request(request_queue_t *q);
@@ -199,6 +200,7 @@ static struct block_device_operations ida_fops = {
199 .open = ida_open, 200 .open = ida_open,
200 .release = ida_release, 201 .release = ida_release,
201 .ioctl = ida_ioctl, 202 .ioctl = ida_ioctl,
203 .getgeo = ida_getgeo,
202 .revalidate_disk= ida_revalidate, 204 .revalidate_disk= ida_revalidate,
203}; 205};
204 206
@@ -1124,6 +1126,23 @@ static void ida_timer(unsigned long tdata)
1124 h->misc_tflags = 0; 1126 h->misc_tflags = 0;
1125} 1127}
1126 1128
1129static int ida_getgeo(struct block_device *bdev, struct hd_geometry *geo)
1130{
1131 drv_info_t *drv = get_drv(bdev->bd_disk);
1132
1133 if (drv->cylinders) {
1134 geo->heads = drv->heads;
1135 geo->sectors = drv->sectors;
1136 geo->cylinders = drv->cylinders;
1137 } else {
1138 geo->heads = 0xff;
1139 geo->sectors = 0x3f;
1140 geo->cylinders = drv->nr_blks / (0xff*0x3f);
1141 }
1142
1143 return 0;
1144}
1145
1127/* 1146/*
1128 * ida_ioctl does some miscellaneous stuff like reporting drive geometry, 1147 * ida_ioctl does some miscellaneous stuff like reporting drive geometry,
1129 * setting readahead and submitting commands from userspace to the controller. 1148 * setting readahead and submitting commands from userspace to the controller.
@@ -1133,27 +1152,10 @@ static int ida_ioctl(struct inode *inode, struct file *filep, unsigned int cmd,
1133 drv_info_t *drv = get_drv(inode->i_bdev->bd_disk); 1152 drv_info_t *drv = get_drv(inode->i_bdev->bd_disk);
1134 ctlr_info_t *host = get_host(inode->i_bdev->bd_disk); 1153 ctlr_info_t *host = get_host(inode->i_bdev->bd_disk);
1135 int error; 1154 int error;
1136 int diskinfo[4];
1137 struct hd_geometry __user *geo = (struct hd_geometry __user *)arg;
1138 ida_ioctl_t __user *io = (ida_ioctl_t __user *)arg; 1155 ida_ioctl_t __user *io = (ida_ioctl_t __user *)arg;
1139 ida_ioctl_t *my_io; 1156 ida_ioctl_t *my_io;
1140 1157
1141 switch(cmd) { 1158 switch(cmd) {
1142 case HDIO_GETGEO:
1143 if (drv->cylinders) {
1144 diskinfo[0] = drv->heads;
1145 diskinfo[1] = drv->sectors;
1146 diskinfo[2] = drv->cylinders;
1147 } else {
1148 diskinfo[0] = 0xff;
1149 diskinfo[1] = 0x3f;
1150 diskinfo[2] = drv->nr_blks / (0xff*0x3f);
1151 }
1152 put_user(diskinfo[0], &geo->heads);
1153 put_user(diskinfo[1], &geo->sectors);
1154 put_user(diskinfo[2], &geo->cylinders);
1155 put_user(get_start_sect(inode->i_bdev), &geo->start);
1156 return 0;
1157 case IDAGETDRVINFO: 1159 case IDAGETDRVINFO:
1158 if (copy_to_user(&io->c.drv, drv, sizeof(drv_info_t))) 1160 if (copy_to_user(&io->c.drv, drv, sizeof(drv_info_t)))
1159 return -EFAULT; 1161 return -EFAULT;
diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c
index a5b857c5c4b8..b86613b21cf1 100644
--- a/drivers/block/floppy.c
+++ b/drivers/block/floppy.c
@@ -3445,6 +3445,23 @@ static int get_floppy_geometry(int drive, int type, struct floppy_struct **g)
3445 return 0; 3445 return 0;
3446} 3446}
3447 3447
3448static int fd_getgeo(struct block_device *bdev, struct hd_geometry *geo)
3449{
3450 int drive = (long)bdev->bd_disk->private_data;
3451 int type = ITYPE(drive_state[drive].fd_device);
3452 struct floppy_struct *g;
3453 int ret;
3454
3455 ret = get_floppy_geometry(drive, type, &g);
3456 if (ret)
3457 return ret;
3458
3459 geo->heads = g->head;
3460 geo->sectors = g->sect;
3461 geo->cylinders = g->track;
3462 return 0;
3463}
3464
3448static int fd_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, 3465static int fd_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
3449 unsigned long param) 3466 unsigned long param)
3450{ 3467{
@@ -3474,23 +3491,6 @@ static int fd_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
3474 cmd = FDEJECT; 3491 cmd = FDEJECT;
3475 } 3492 }
3476 3493
3477 /* generic block device ioctls */
3478 switch (cmd) {
3479 /* the following have been inspired by the corresponding
3480 * code for other block devices. */
3481 struct floppy_struct *g;
3482 case HDIO_GETGEO:
3483 {
3484 struct hd_geometry loc;
3485 ECALL(get_floppy_geometry(drive, type, &g));
3486 loc.heads = g->head;
3487 loc.sectors = g->sect;
3488 loc.cylinders = g->track;
3489 loc.start = 0;
3490 return _COPYOUT(loc);
3491 }
3492 }
3493
3494 /* convert the old style command into a new style command */ 3494 /* convert the old style command into a new style command */
3495 if ((cmd & 0xff00) == 0x0200) { 3495 if ((cmd & 0xff00) == 0x0200) {
3496 ECALL(normalize_ioctl(&cmd, &size)); 3496 ECALL(normalize_ioctl(&cmd, &size));
@@ -3938,6 +3938,7 @@ static struct block_device_operations floppy_fops = {
3938 .open = floppy_open, 3938 .open = floppy_open,
3939 .release = floppy_release, 3939 .release = floppy_release,
3940 .ioctl = fd_ioctl, 3940 .ioctl = fd_ioctl,
3941 .getgeo = fd_getgeo,
3941 .media_changed = check_floppy_change, 3942 .media_changed = check_floppy_change,
3942 .revalidate_disk = floppy_revalidate, 3943 .revalidate_disk = floppy_revalidate,
3943}; 3944};
diff --git a/drivers/block/paride/pd.c b/drivers/block/paride/pd.c
index fa49d62626ba..62d2464c12f2 100644
--- a/drivers/block/paride/pd.c
+++ b/drivers/block/paride/pd.c
@@ -747,32 +747,33 @@ static int pd_open(struct inode *inode, struct file *file)
747 return 0; 747 return 0;
748} 748}
749 749
750static int pd_getgeo(struct block_device *bdev, struct hd_geometry *geo)
751{
752 struct pd_unit *disk = bdev->bd_disk->private_data;
753
754 if (disk->alt_geom) {
755 geo->heads = PD_LOG_HEADS;
756 geo->sectors = PD_LOG_SECTS;
757 geo->cylinders = disk->capacity / (geo->heads * geo->sectors);
758 } else {
759 geo->heads = disk->heads;
760 geo->sectors = disk->sectors;
761 geo->cylinders = disk->cylinders;
762 }
763
764 return 0;
765}
766
750static int pd_ioctl(struct inode *inode, struct file *file, 767static int pd_ioctl(struct inode *inode, struct file *file,
751 unsigned int cmd, unsigned long arg) 768 unsigned int cmd, unsigned long arg)
752{ 769{
753 struct pd_unit *disk = inode->i_bdev->bd_disk->private_data; 770 struct pd_unit *disk = inode->i_bdev->bd_disk->private_data;
754 struct hd_geometry __user *geo = (struct hd_geometry __user *) arg;
755 struct hd_geometry g;
756 771
757 switch (cmd) { 772 switch (cmd) {
758 case CDROMEJECT: 773 case CDROMEJECT:
759 if (disk->access == 1) 774 if (disk->access == 1)
760 pd_special_command(disk, pd_eject); 775 pd_special_command(disk, pd_eject);
761 return 0; 776 return 0;
762 case HDIO_GETGEO:
763 if (disk->alt_geom) {
764 g.heads = PD_LOG_HEADS;
765 g.sectors = PD_LOG_SECTS;
766 g.cylinders = disk->capacity / (g.heads * g.sectors);
767 } else {
768 g.heads = disk->heads;
769 g.sectors = disk->sectors;
770 g.cylinders = disk->cylinders;
771 }
772 g.start = get_start_sect(inode->i_bdev);
773 if (copy_to_user(geo, &g, sizeof(struct hd_geometry)))
774 return -EFAULT;
775 return 0;
776 default: 777 default:
777 return -EINVAL; 778 return -EINVAL;
778 } 779 }
@@ -815,6 +816,7 @@ static struct block_device_operations pd_fops = {
815 .open = pd_open, 816 .open = pd_open,
816 .release = pd_release, 817 .release = pd_release,
817 .ioctl = pd_ioctl, 818 .ioctl = pd_ioctl,
819 .getgeo = pd_getgeo,
818 .media_changed = pd_check_media, 820 .media_changed = pd_check_media,
819 .revalidate_disk= pd_revalidate 821 .revalidate_disk= pd_revalidate
820}; 822};
diff --git a/drivers/block/paride/pf.c b/drivers/block/paride/pf.c
index e9746af29b9f..852b564e903a 100644
--- a/drivers/block/paride/pf.c
+++ b/drivers/block/paride/pf.c
@@ -205,6 +205,7 @@ static int pf_open(struct inode *inode, struct file *file);
205static void do_pf_request(request_queue_t * q); 205static void do_pf_request(request_queue_t * q);
206static int pf_ioctl(struct inode *inode, struct file *file, 206static int pf_ioctl(struct inode *inode, struct file *file,
207 unsigned int cmd, unsigned long arg); 207 unsigned int cmd, unsigned long arg);
208static int pf_getgeo(struct block_device *bdev, struct hd_geometry *geo);
208 209
209static int pf_release(struct inode *inode, struct file *file); 210static int pf_release(struct inode *inode, struct file *file);
210 211
@@ -266,6 +267,7 @@ static struct block_device_operations pf_fops = {
266 .open = pf_open, 267 .open = pf_open,
267 .release = pf_release, 268 .release = pf_release,
268 .ioctl = pf_ioctl, 269 .ioctl = pf_ioctl,
270 .getgeo = pf_getgeo,
269 .media_changed = pf_check_media, 271 .media_changed = pf_check_media,
270}; 272};
271 273
@@ -313,34 +315,34 @@ static int pf_open(struct inode *inode, struct file *file)
313 return 0; 315 return 0;
314} 316}
315 317
316static int pf_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) 318static int pf_getgeo(struct block_device *bdev, struct hd_geometry *geo)
317{ 319{
318 struct pf_unit *pf = inode->i_bdev->bd_disk->private_data; 320 struct pf_unit *pf = bdev->bd_disk->private_data;
319 struct hd_geometry __user *geo = (struct hd_geometry __user *) arg; 321 sector_t capacity = get_capacity(pf->disk);
320 struct hd_geometry g; 322
321 sector_t capacity;
322
323 if (cmd == CDROMEJECT) {
324 if (pf->access == 1) {
325 pf_eject(pf);
326 return 0;
327 }
328 return -EBUSY;
329 }
330 if (cmd != HDIO_GETGEO)
331 return -EINVAL;
332 capacity = get_capacity(pf->disk);
333 if (capacity < PF_FD_MAX) { 323 if (capacity < PF_FD_MAX) {
334 g.cylinders = sector_div(capacity, PF_FD_HDS * PF_FD_SPT); 324 geo->cylinders = sector_div(capacity, PF_FD_HDS * PF_FD_SPT);
335 g.heads = PF_FD_HDS; 325 geo->heads = PF_FD_HDS;
336 g.sectors = PF_FD_SPT; 326 geo->sectors = PF_FD_SPT;
337 } else { 327 } else {
338 g.cylinders = sector_div(capacity, PF_HD_HDS * PF_HD_SPT); 328 geo->cylinders = sector_div(capacity, PF_HD_HDS * PF_HD_SPT);
339 g.heads = PF_HD_HDS; 329 geo->heads = PF_HD_HDS;
340 g.sectors = PF_HD_SPT; 330 geo->sectors = PF_HD_SPT;
341 } 331 }
342 if (copy_to_user(geo, &g, sizeof(g))) 332
343 return -EFAULT; 333 return 0;
334}
335
336static int pf_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
337{
338 struct pf_unit *pf = inode->i_bdev->bd_disk->private_data;
339
340 if (cmd != CDROMEJECT)
341 return -EINVAL;
342
343 if (pf->access != 1)
344 return -EBUSY;
345 pf_eject(pf);
344 return 0; 346 return 0;
345} 347}
346 348
diff --git a/drivers/block/ps2esdi.c b/drivers/block/ps2esdi.c
index 29d1518be72a..43415f69839f 100644
--- a/drivers/block/ps2esdi.c
+++ b/drivers/block/ps2esdi.c
@@ -81,8 +81,7 @@ static void (*current_int_handler) (u_int) = NULL;
81static void ps2esdi_normal_interrupt_handler(u_int); 81static void ps2esdi_normal_interrupt_handler(u_int);
82static void ps2esdi_initial_reset_int_handler(u_int); 82static void ps2esdi_initial_reset_int_handler(u_int);
83static void ps2esdi_geometry_int_handler(u_int); 83static void ps2esdi_geometry_int_handler(u_int);
84static int ps2esdi_ioctl(struct inode *inode, struct file *file, 84static int ps2esdi_getgeo(struct block_device *bdev, struct hd_geometry *geo);
85 u_int cmd, u_long arg);
86 85
87static int ps2esdi_read_status_words(int num_words, int max_words, u_short * buffer); 86static int ps2esdi_read_status_words(int num_words, int max_words, u_short * buffer);
88 87
@@ -132,7 +131,7 @@ static struct ps2esdi_i_struct ps2esdi_info[MAX_HD] =
132static struct block_device_operations ps2esdi_fops = 131static struct block_device_operations ps2esdi_fops =
133{ 132{
134 .owner = THIS_MODULE, 133 .owner = THIS_MODULE,
135 .ioctl = ps2esdi_ioctl, 134 .getgeo = ps2esdi_getgeo,
136}; 135};
137 136
138static struct gendisk *ps2esdi_gendisk[2]; 137static struct gendisk *ps2esdi_gendisk[2];
@@ -1058,21 +1057,13 @@ static void dump_cmd_complete_status(u_int int_ret_code)
1058 1057
1059} 1058}
1060 1059
1061static int ps2esdi_ioctl(struct inode *inode, 1060static int ps2esdi_getgeo(struct block_device *bdev, struct hd_geometry *geo)
1062 struct file *file, u_int cmd, u_long arg)
1063{ 1061{
1064 struct ps2esdi_i_struct *p = inode->i_bdev->bd_disk->private_data; 1062 struct ps2esdi_i_struct *p = bdev->bd_disk->private_data;
1065 struct ps2esdi_geometry geom; 1063
1066 1064 geo->heads = p->head;
1067 if (cmd != HDIO_GETGEO) 1065 geo->sectors = p->sect;
1068 return -EINVAL; 1066 geo->cylinders = p->cyl;
1069 memset(&geom, 0, sizeof(geom));
1070 geom.heads = p->head;
1071 geom.sectors = p->sect;
1072 geom.cylinders = p->cyl;
1073 geom.start = get_start_sect(inode->i_bdev);
1074 if (copy_to_user((void __user *)arg, &geom, sizeof(geom)))
1075 return -EFAULT;
1076 return 0; 1067 return 0;
1077} 1068}
1078 1069
diff --git a/drivers/block/sx8.c b/drivers/block/sx8.c
index 9251f4131b53..c0cdc182a8b0 100644
--- a/drivers/block/sx8.c
+++ b/drivers/block/sx8.c
@@ -407,8 +407,7 @@ struct carm_array_info {
407 407
408static int carm_init_one (struct pci_dev *pdev, const struct pci_device_id *ent); 408static int carm_init_one (struct pci_dev *pdev, const struct pci_device_id *ent);
409static void carm_remove_one (struct pci_dev *pdev); 409static void carm_remove_one (struct pci_dev *pdev);
410static int carm_bdev_ioctl(struct inode *ino, struct file *fil, 410static int carm_bdev_getgeo(struct block_device *bdev, struct hd_geometry *geo);
411 unsigned int cmd, unsigned long arg);
412 411
413static struct pci_device_id carm_pci_tbl[] = { 412static struct pci_device_id carm_pci_tbl[] = {
414 { PCI_VENDOR_ID_PROMISE, 0x8000, PCI_ANY_ID, PCI_ANY_ID, 0, 0, }, 413 { PCI_VENDOR_ID_PROMISE, 0x8000, PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
@@ -426,7 +425,7 @@ static struct pci_driver carm_driver = {
426 425
427static struct block_device_operations carm_bd_ops = { 426static struct block_device_operations carm_bd_ops = {
428 .owner = THIS_MODULE, 427 .owner = THIS_MODULE,
429 .ioctl = carm_bdev_ioctl, 428 .getgeo = carm_bdev_getgeo,
430}; 429};
431 430
432static unsigned int carm_host_id; 431static unsigned int carm_host_id;
@@ -434,32 +433,14 @@ static unsigned long carm_major_alloc;
434 433
435 434
436 435
437static int carm_bdev_ioctl(struct inode *ino, struct file *fil, 436static int carm_bdev_getgeo(struct block_device *bdev, struct hd_geometry *geo)
438 unsigned int cmd, unsigned long arg)
439{ 437{
440 void __user *usermem = (void __user *) arg; 438 struct carm_port *port = bdev->bd_disk->private_data;
441 struct carm_port *port = ino->i_bdev->bd_disk->private_data;
442 struct hd_geometry geom;
443 439
444 switch (cmd) { 440 geo->heads = (u8) port->dev_geom_head;
445 case HDIO_GETGEO: 441 geo->sectors = (u8) port->dev_geom_sect;
446 if (!usermem) 442 geo->cylinders = port->dev_geom_cyl;
447 return -EINVAL; 443 return 0;
448
449 geom.heads = (u8) port->dev_geom_head;
450 geom.sectors = (u8) port->dev_geom_sect;
451 geom.cylinders = port->dev_geom_cyl;
452 geom.start = get_start_sect(ino->i_bdev);
453
454 if (copy_to_user(usermem, &geom, sizeof(geom)))
455 return -EFAULT;
456 return 0;
457
458 default:
459 break;
460 }
461
462 return -EOPNOTSUPP;
463} 444}
464 445
465static const u32 msg_sizes[] = { 32, 64, 128, CARM_MSG_SIZE }; 446static const u32 msg_sizes[] = { 32, 64, 128, CARM_MSG_SIZE };
diff --git a/drivers/block/umem.c b/drivers/block/umem.c
index 0f48301342da..15299e7a1ade 100644
--- a/drivers/block/umem.c
+++ b/drivers/block/umem.c
@@ -809,34 +809,23 @@ static int mm_revalidate(struct gendisk *disk)
809 set_capacity(disk, card->mm_size << 1); 809 set_capacity(disk, card->mm_size << 1);
810 return 0; 810 return 0;
811} 811}
812/* 812
813----------------------------------------------------------------------------------- 813static int mm_getgeo(struct block_device *bdev, struct hd_geometry *geo)
814-- mm_ioctl
815-----------------------------------------------------------------------------------
816*/
817static int mm_ioctl(struct inode *i, struct file *f, unsigned int cmd, unsigned long arg)
818{ 814{
819 if (cmd == HDIO_GETGEO) { 815 struct cardinfo *card = bdev->bd_disk->private_data;
820 struct cardinfo *card = i->i_bdev->bd_disk->private_data; 816 int size = card->mm_size * (1024 / MM_HARDSECT);
821 int size = card->mm_size * (1024 / MM_HARDSECT);
822 struct hd_geometry geo;
823 /*
824 * get geometry: we have to fake one... trim the size to a
825 * multiple of 2048 (1M): tell we have 32 sectors, 64 heads,
826 * whatever cylinders.
827 */
828 geo.heads = 64;
829 geo.sectors = 32;
830 geo.start = get_start_sect(i->i_bdev);
831 geo.cylinders = size / (geo.heads * geo.sectors);
832
833 if (copy_to_user((void __user *) arg, &geo, sizeof(geo)))
834 return -EFAULT;
835 return 0;
836 }
837 817
838 return -EINVAL; 818 /*
819 * get geometry: we have to fake one... trim the size to a
820 * multiple of 2048 (1M): tell we have 32 sectors, 64 heads,
821 * whatever cylinders.
822 */
823 geo->heads = 64;
824 geo->sectors = 32;
825 geo->cylinders = size / (geo->heads * geo->sectors);
826 return 0;
839} 827}
828
840/* 829/*
841----------------------------------------------------------------------------------- 830-----------------------------------------------------------------------------------
842-- mm_check_change 831-- mm_check_change
@@ -855,7 +844,7 @@ static int mm_check_change(struct gendisk *disk)
855*/ 844*/
856static struct block_device_operations mm_fops = { 845static struct block_device_operations mm_fops = {
857 .owner = THIS_MODULE, 846 .owner = THIS_MODULE,
858 .ioctl = mm_ioctl, 847 .getgeo = mm_getgeo,
859 .revalidate_disk= mm_revalidate, 848 .revalidate_disk= mm_revalidate,
860 .media_changed = mm_check_change, 849 .media_changed = mm_check_change,
861}; 850};
diff --git a/drivers/block/viodasd.c b/drivers/block/viodasd.c
index 063f0304a163..d1aaf31bd97e 100644
--- a/drivers/block/viodasd.c
+++ b/drivers/block/viodasd.c
@@ -247,43 +247,17 @@ static int viodasd_release(struct inode *ino, struct file *fil)
247 247
248/* External ioctl entry point. 248/* External ioctl entry point.
249 */ 249 */
250static int viodasd_ioctl(struct inode *ino, struct file *fil, 250static int viodasd_getgeo(struct block_device *bdev, struct hd_geometry *geo)
251 unsigned int cmd, unsigned long arg)
252{ 251{
253 unsigned char sectors; 252 struct gendisk *disk = bdev->bd_disk;
254 unsigned char heads; 253 struct viodasd_device *d = disk->private_data;
255 unsigned short cylinders;
256 struct hd_geometry *geo;
257 struct gendisk *gendisk;
258 struct viodasd_device *d;
259 254
260 switch (cmd) { 255 geo->sectors = d->sectors ? d->sectors : 0;
261 case HDIO_GETGEO: 256 geo->heads = d->tracks ? d->tracks : 64;
262 geo = (struct hd_geometry *)arg; 257 geo->cylinders = d->cylinders ? d->cylinders :
263 if (geo == NULL) 258 get_capacity(disk) / (geo->cylinders * geo->heads);
264 return -EINVAL;
265 if (!access_ok(VERIFY_WRITE, geo, sizeof(*geo)))
266 return -EFAULT;
267 gendisk = ino->i_bdev->bd_disk;
268 d = gendisk->private_data;
269 sectors = d->sectors;
270 if (sectors == 0)
271 sectors = 32;
272 heads = d->tracks;
273 if (heads == 0)
274 heads = 64;
275 cylinders = d->cylinders;
276 if (cylinders == 0)
277 cylinders = get_capacity(gendisk) / (sectors * heads);
278 if (__put_user(sectors, &geo->sectors) ||
279 __put_user(heads, &geo->heads) ||
280 __put_user(cylinders, &geo->cylinders) ||
281 __put_user(get_start_sect(ino->i_bdev), &geo->start))
282 return -EFAULT;
283 return 0;
284 }
285 259
286 return -EINVAL; 260 return 0;
287} 261}
288 262
289/* 263/*
@@ -293,7 +267,7 @@ static struct block_device_operations viodasd_fops = {
293 .owner = THIS_MODULE, 267 .owner = THIS_MODULE,
294 .open = viodasd_open, 268 .open = viodasd_open,
295 .release = viodasd_release, 269 .release = viodasd_release,
296 .ioctl = viodasd_ioctl, 270 .getgeo = viodasd_getgeo,
297}; 271};
298 272
299/* 273/*
diff --git a/drivers/block/xd.c b/drivers/block/xd.c
index 68b6d7b154cf..97f5dab24b5a 100644
--- a/drivers/block/xd.c
+++ b/drivers/block/xd.c
@@ -128,9 +128,12 @@ static DEFINE_SPINLOCK(xd_lock);
128 128
129static struct gendisk *xd_gendisk[2]; 129static struct gendisk *xd_gendisk[2];
130 130
131static int xd_getgeo(struct block_device *bdev, struct hd_geometry *geo);
132
131static struct block_device_operations xd_fops = { 133static struct block_device_operations xd_fops = {
132 .owner = THIS_MODULE, 134 .owner = THIS_MODULE,
133 .ioctl = xd_ioctl, 135 .ioctl = xd_ioctl,
136 .getgeo = xd_getgeo,
134}; 137};
135static DECLARE_WAIT_QUEUE_HEAD(xd_wait_int); 138static DECLARE_WAIT_QUEUE_HEAD(xd_wait_int);
136static u_char xd_drives, xd_irq = 5, xd_dma = 3, xd_maxsectors; 139static u_char xd_drives, xd_irq = 5, xd_dma = 3, xd_maxsectors;
@@ -330,22 +333,20 @@ static void do_xd_request (request_queue_t * q)
330 } 333 }
331} 334}
332 335
336static int xd_getgeo(struct block_device *bdev, struct hd_geometry *geo)
337{
338 XD_INFO *p = bdev->bd_disk->private_data;
339
340 geo->heads = p->heads;
341 geo->sectors = p->sectors;
342 geo->cylinders = p->cylinders;
343 return 0;
344}
345
333/* xd_ioctl: handle device ioctl's */ 346/* xd_ioctl: handle device ioctl's */
334static int xd_ioctl (struct inode *inode,struct file *file,u_int cmd,u_long arg) 347static int xd_ioctl (struct inode *inode,struct file *file,u_int cmd,u_long arg)
335{ 348{
336 XD_INFO *p = inode->i_bdev->bd_disk->private_data;
337
338 switch (cmd) { 349 switch (cmd) {
339 case HDIO_GETGEO:
340 {
341 struct hd_geometry g;
342 struct hd_geometry __user *geom= (void __user *)arg;
343 g.heads = p->heads;
344 g.sectors = p->sectors;
345 g.cylinders = p->cylinders;
346 g.start = get_start_sect(inode->i_bdev);
347 return copy_to_user(geom, &g, sizeof(g)) ? -EFAULT : 0;
348 }
349 case HDIO_SET_DMA: 350 case HDIO_SET_DMA:
350 if (!capable(CAP_SYS_ADMIN)) return -EACCES; 351 if (!capable(CAP_SYS_ADMIN)) return -EACCES;
351 if (xdc_busy) return -EBUSY; 352 if (xdc_busy) return -EBUSY;
diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c
index 4b441720b6ba..cab362ea0336 100644
--- a/drivers/ide/ide-disk.c
+++ b/drivers/ide/ide-disk.c
@@ -1130,6 +1130,17 @@ static int idedisk_release(struct inode *inode, struct file *filp)
1130 return 0; 1130 return 0;
1131} 1131}
1132 1132
1133static int idedisk_getgeo(struct block_device *bdev, struct hd_geometry *geo)
1134{
1135 struct ide_disk_obj *idkp = ide_disk_g(bdev->bd_disk);
1136 ide_drive_t *drive = idkp->drive;
1137
1138 geo->heads = drive->bios_head;
1139 geo->sectors = drive->bios_sect;
1140 geo->cylinders = (u16)drive->bios_cyl; /* truncate */
1141 return 0;
1142}
1143
1133static int idedisk_ioctl(struct inode *inode, struct file *file, 1144static int idedisk_ioctl(struct inode *inode, struct file *file,
1134 unsigned int cmd, unsigned long arg) 1145 unsigned int cmd, unsigned long arg)
1135{ 1146{
@@ -1164,6 +1175,7 @@ static struct block_device_operations idedisk_ops = {
1164 .open = idedisk_open, 1175 .open = idedisk_open,
1165 .release = idedisk_release, 1176 .release = idedisk_release,
1166 .ioctl = idedisk_ioctl, 1177 .ioctl = idedisk_ioctl,
1178 .getgeo = idedisk_getgeo,
1167 .media_changed = idedisk_media_changed, 1179 .media_changed = idedisk_media_changed,
1168 .revalidate_disk= idedisk_revalidate_disk 1180 .revalidate_disk= idedisk_revalidate_disk
1169}; 1181};
diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c
index fba3fffc2d66..5945f551aaaa 100644
--- a/drivers/ide/ide-floppy.c
+++ b/drivers/ide/ide-floppy.c
@@ -2031,6 +2031,17 @@ static int idefloppy_release(struct inode *inode, struct file *filp)
2031 return 0; 2031 return 0;
2032} 2032}
2033 2033
2034static int idefloppy_getgeo(struct block_device *bdev, struct hd_geometry *geo)
2035{
2036 struct ide_floppy_obj *floppy = ide_floppy_g(bdev->bd_disk);
2037 ide_drive_t *drive = floppy->drive;
2038
2039 geo->heads = drive->bios_head;
2040 geo->sectors = drive->bios_sect;
2041 geo->cylinders = (u16)drive->bios_cyl; /* truncate */
2042 return 0;
2043}
2044
2034static int idefloppy_ioctl(struct inode *inode, struct file *file, 2045static int idefloppy_ioctl(struct inode *inode, struct file *file,
2035 unsigned int cmd, unsigned long arg) 2046 unsigned int cmd, unsigned long arg)
2036{ 2047{
@@ -2120,6 +2131,7 @@ static struct block_device_operations idefloppy_ops = {
2120 .open = idefloppy_open, 2131 .open = idefloppy_open,
2121 .release = idefloppy_release, 2132 .release = idefloppy_release,
2122 .ioctl = idefloppy_ioctl, 2133 .ioctl = idefloppy_ioctl,
2134 .getgeo = idefloppy_getgeo,
2123 .media_changed = idefloppy_media_changed, 2135 .media_changed = idefloppy_media_changed,
2124 .revalidate_disk= idefloppy_revalidate_disk 2136 .revalidate_disk= idefloppy_revalidate_disk
2125}; 2137};
diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c
index 4b524f6b3ecd..b069b13b75a7 100644
--- a/drivers/ide/ide.c
+++ b/drivers/ide/ide.c
@@ -1278,19 +1278,6 @@ int generic_ide_ioctl(ide_drive_t *drive, struct file *file, struct block_device
1278 up(&ide_setting_sem); 1278 up(&ide_setting_sem);
1279 1279
1280 switch (cmd) { 1280 switch (cmd) {
1281 case HDIO_GETGEO:
1282 {
1283 struct hd_geometry geom;
1284 if (!p || (drive->media != ide_disk && drive->media != ide_floppy)) return -EINVAL;
1285 geom.heads = drive->bios_head;
1286 geom.sectors = drive->bios_sect;
1287 geom.cylinders = (u16)drive->bios_cyl; /* truncate */
1288 geom.start = get_start_sect(bdev);
1289 if (copy_to_user(p, &geom, sizeof(struct hd_geometry)))
1290 return -EFAULT;
1291 return 0;
1292 }
1293
1294 case HDIO_OBSOLETE_IDENTITY: 1281 case HDIO_OBSOLETE_IDENTITY:
1295 case HDIO_GET_IDENTITY: 1282 case HDIO_GET_IDENTITY:
1296 if (bdev != bdev->bd_contains) 1283 if (bdev != bdev->bd_contains)
diff --git a/drivers/ide/legacy/hd.c b/drivers/ide/legacy/hd.c
index 242029c9c0ca..6439dec66881 100644
--- a/drivers/ide/legacy/hd.c
+++ b/drivers/ide/legacy/hd.c
@@ -658,22 +658,14 @@ static void do_hd_request (request_queue_t * q)
658 enable_irq(HD_IRQ); 658 enable_irq(HD_IRQ);
659} 659}
660 660
661static int hd_ioctl(struct inode * inode, struct file * file, 661static int hd_getgeo(struct block_device *bdev, struct hd_geometry *geo)
662 unsigned int cmd, unsigned long arg)
663{ 662{
664 struct hd_i_struct *disk = inode->i_bdev->bd_disk->private_data; 663 struct hd_i_struct *disk = bdev->bd_disk->private_data;
665 struct hd_geometry __user *loc = (struct hd_geometry __user *) arg; 664
666 struct hd_geometry g; 665 geo->heads = disk->head;
667 666 geo->sectors = disk->sect;
668 if (cmd != HDIO_GETGEO) 667 geo->cylinders = disk->cyl;
669 return -EINVAL; 668 return 0;
670 if (!loc)
671 return -EINVAL;
672 g.heads = disk->head;
673 g.sectors = disk->sect;
674 g.cylinders = disk->cyl;
675 g.start = get_start_sect(inode->i_bdev);
676 return copy_to_user(loc, &g, sizeof g) ? -EFAULT : 0;
677} 669}
678 670
679/* 671/*
@@ -695,7 +687,7 @@ static irqreturn_t hd_interrupt(int irq, void *dev_id, struct pt_regs *regs)
695} 687}
696 688
697static struct block_device_operations hd_fops = { 689static struct block_device_operations hd_fops = {
698 .ioctl = hd_ioctl, 690 .getgeo = hd_getgeo,
699}; 691};
700 692
701/* 693/*
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 1b76fb29fb70..e423a16ba3c9 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -3598,12 +3598,21 @@ static int set_disk_faulty(mddev_t *mddev, dev_t dev)
3598 return 0; 3598 return 0;
3599} 3599}
3600 3600
3601static int md_getgeo(struct block_device *bdev, struct hd_geometry *geo)
3602{
3603 mddev_t *mddev = bdev->bd_disk->private_data;
3604
3605 geo->heads = 2;
3606 geo->sectors = 4;
3607 geo->cylinders = get_capacity(mddev->gendisk) / 8;
3608 return 0;
3609}
3610
3601static int md_ioctl(struct inode *inode, struct file *file, 3611static int md_ioctl(struct inode *inode, struct file *file,
3602 unsigned int cmd, unsigned long arg) 3612 unsigned int cmd, unsigned long arg)
3603{ 3613{
3604 int err = 0; 3614 int err = 0;
3605 void __user *argp = (void __user *)arg; 3615 void __user *argp = (void __user *)arg;
3606 struct hd_geometry __user *loc = argp;
3607 mddev_t *mddev = NULL; 3616 mddev_t *mddev = NULL;
3608 3617
3609 if (!capable(CAP_SYS_ADMIN)) 3618 if (!capable(CAP_SYS_ADMIN))
@@ -3765,24 +3774,6 @@ static int md_ioctl(struct inode *inode, struct file *file,
3765 * 4 sectors (with a BIG number of cylinders...). This drives 3774 * 4 sectors (with a BIG number of cylinders...). This drives
3766 * dosfs just mad... ;-) 3775 * dosfs just mad... ;-)
3767 */ 3776 */
3768 case HDIO_GETGEO:
3769 if (!loc) {
3770 err = -EINVAL;
3771 goto abort_unlock;
3772 }
3773 err = put_user (2, (char __user *) &loc->heads);
3774 if (err)
3775 goto abort_unlock;
3776 err = put_user (4, (char __user *) &loc->sectors);
3777 if (err)
3778 goto abort_unlock;
3779 err = put_user(get_capacity(mddev->gendisk)/8,
3780 (short __user *) &loc->cylinders);
3781 if (err)
3782 goto abort_unlock;
3783 err = put_user (get_start_sect(inode->i_bdev),
3784 (long __user *) &loc->start);
3785 goto done_unlock;
3786 } 3777 }
3787 3778
3788 /* 3779 /*
@@ -3911,6 +3902,7 @@ static struct block_device_operations md_fops =
3911 .open = md_open, 3902 .open = md_open,
3912 .release = md_release, 3903 .release = md_release,
3913 .ioctl = md_ioctl, 3904 .ioctl = md_ioctl,
3905 .getgeo = md_getgeo,
3914 .media_changed = md_media_changed, 3906 .media_changed = md_media_changed,
3915 .revalidate_disk= md_revalidate, 3907 .revalidate_disk= md_revalidate,
3916}; 3908};
diff --git a/drivers/message/i2o/i2o_block.c b/drivers/message/i2o/i2o_block.c
index 5b1febed3133..b09fb6307153 100644
--- a/drivers/message/i2o/i2o_block.c
+++ b/drivers/message/i2o/i2o_block.c
@@ -662,6 +662,13 @@ static int i2o_block_release(struct inode *inode, struct file *file)
662 return 0; 662 return 0;
663} 663}
664 664
665static int i2o_block_getgeo(struct block_device *bdev, struct hd_geometry *geo)
666{
667 i2o_block_biosparam(get_capacity(bdev->bd_disk),
668 &geo->cylinders, &geo->heads, &geo->sectors);
669 return 0;
670}
671
665/** 672/**
666 * i2o_block_ioctl - Issue device specific ioctl calls. 673 * i2o_block_ioctl - Issue device specific ioctl calls.
667 * @cmd: ioctl command 674 * @cmd: ioctl command
@@ -676,7 +683,6 @@ static int i2o_block_ioctl(struct inode *inode, struct file *file,
676{ 683{
677 struct gendisk *disk = inode->i_bdev->bd_disk; 684 struct gendisk *disk = inode->i_bdev->bd_disk;
678 struct i2o_block_device *dev = disk->private_data; 685 struct i2o_block_device *dev = disk->private_data;
679 void __user *argp = (void __user *)arg;
680 686
681 /* Anyone capable of this syscall can do *real bad* things */ 687 /* Anyone capable of this syscall can do *real bad* things */
682 688
@@ -684,15 +690,6 @@ static int i2o_block_ioctl(struct inode *inode, struct file *file,
684 return -EPERM; 690 return -EPERM;
685 691
686 switch (cmd) { 692 switch (cmd) {
687 case HDIO_GETGEO:
688 {
689 struct hd_geometry g;
690 i2o_block_biosparam(get_capacity(disk),
691 &g.cylinders, &g.heads, &g.sectors);
692 g.start = get_start_sect(inode->i_bdev);
693 return copy_to_user(argp, &g, sizeof(g)) ? -EFAULT : 0;
694 }
695
696 case BLKI2OGRSTRAT: 693 case BLKI2OGRSTRAT:
697 return put_user(dev->rcache, (int __user *)arg); 694 return put_user(dev->rcache, (int __user *)arg);
698 case BLKI2OGWSTRAT: 695 case BLKI2OGWSTRAT:
@@ -962,6 +959,7 @@ static struct block_device_operations i2o_block_fops = {
962 .open = i2o_block_open, 959 .open = i2o_block_open,
963 .release = i2o_block_release, 960 .release = i2o_block_release,
964 .ioctl = i2o_block_ioctl, 961 .ioctl = i2o_block_ioctl,
962 .getgeo = i2o_block_getgeo,
965 .media_changed = i2o_block_media_changed 963 .media_changed = i2o_block_media_changed
966}; 964};
967 965
diff --git a/drivers/mmc/mmc_block.c b/drivers/mmc/mmc_block.c
index 198561d21710..d5f28981596b 100644
--- a/drivers/mmc/mmc_block.c
+++ b/drivers/mmc/mmc_block.c
@@ -113,31 +113,18 @@ static int mmc_blk_release(struct inode *inode, struct file *filp)
113} 113}
114 114
115static int 115static int
116mmc_blk_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) 116mmc_blk_getgeo(struct block_device *bdev, struct hd_geometry *geo)
117{ 117{
118 struct block_device *bdev = inode->i_bdev; 118 geo->cylinders = get_capacity(bdev->bd_disk) / (4 * 16);
119 119 geo->heads = 4;
120 if (cmd == HDIO_GETGEO) { 120 geo->sectors = 16;
121 struct hd_geometry geo; 121 return 0;
122
123 memset(&geo, 0, sizeof(struct hd_geometry));
124
125 geo.cylinders = get_capacity(bdev->bd_disk) / (4 * 16);
126 geo.heads = 4;
127 geo.sectors = 16;
128 geo.start = get_start_sect(bdev);
129
130 return copy_to_user((void __user *)arg, &geo, sizeof(geo))
131 ? -EFAULT : 0;
132 }
133
134 return -ENOTTY;
135} 122}
136 123
137static struct block_device_operations mmc_bdops = { 124static struct block_device_operations mmc_bdops = {
138 .open = mmc_blk_open, 125 .open = mmc_blk_open,
139 .release = mmc_blk_release, 126 .release = mmc_blk_release,
140 .ioctl = mmc_blk_ioctl, 127 .getgeo = mmc_blk_getgeo,
141 .owner = THIS_MODULE, 128 .owner = THIS_MODULE,
142}; 129};
143 130
diff --git a/drivers/mtd/mtd_blkdevs.c b/drivers/mtd/mtd_blkdevs.c
index 339cb1218eaa..7f3ff500b68e 100644
--- a/drivers/mtd/mtd_blkdevs.c
+++ b/drivers/mtd/mtd_blkdevs.c
@@ -194,6 +194,14 @@ static int blktrans_release(struct inode *i, struct file *f)
194 return ret; 194 return ret;
195} 195}
196 196
197static int blktrans_getgeo(struct block_device *bdev, struct hd_geometry *geo)
198{
199 struct mtd_blktrans_dev *dev = bdev->bd_disk->private_data;
200
201 if (dev->tr->getgeo)
202 return dev->tr->getgeo(dev, geo);
203 return -ENOTTY;
204}
197 205
198static int blktrans_ioctl(struct inode *inode, struct file *file, 206static int blktrans_ioctl(struct inode *inode, struct file *file,
199 unsigned int cmd, unsigned long arg) 207 unsigned int cmd, unsigned long arg)
@@ -207,22 +215,6 @@ static int blktrans_ioctl(struct inode *inode, struct file *file,
207 return tr->flush(dev); 215 return tr->flush(dev);
208 /* The core code did the work, we had nothing to do. */ 216 /* The core code did the work, we had nothing to do. */
209 return 0; 217 return 0;
210
211 case HDIO_GETGEO:
212 if (tr->getgeo) {
213 struct hd_geometry g;
214 int ret;
215
216 memset(&g, 0, sizeof(g));
217 ret = tr->getgeo(dev, &g);
218 if (ret)
219 return ret;
220
221 g.start = get_start_sect(inode->i_bdev);
222 if (copy_to_user((void __user *)arg, &g, sizeof(g)))
223 return -EFAULT;
224 return 0;
225 } /* else */
226 default: 218 default:
227 return -ENOTTY; 219 return -ENOTTY;
228 } 220 }
@@ -233,6 +225,7 @@ struct block_device_operations mtd_blktrans_ops = {
233 .open = blktrans_open, 225 .open = blktrans_open,
234 .release = blktrans_release, 226 .release = blktrans_release,
235 .ioctl = blktrans_ioctl, 227 .ioctl = blktrans_ioctl,
228 .getgeo = blktrans_getgeo,
236}; 229};
237 230
238int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new) 231int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new)
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c
index f779f674dfa0..2472fa1a1be1 100644
--- a/drivers/s390/block/dasd.c
+++ b/drivers/s390/block/dasd.c
@@ -18,6 +18,7 @@
18#include <linux/major.h> 18#include <linux/major.h>
19#include <linux/slab.h> 19#include <linux/slab.h>
20#include <linux/buffer_head.h> 20#include <linux/buffer_head.h>
21#include <linux/hdreg.h>
21 22
22#include <asm/ccwdev.h> 23#include <asm/ccwdev.h>
23#include <asm/ebcdic.h> 24#include <asm/ebcdic.h>
@@ -1723,12 +1724,34 @@ dasd_release(struct inode *inp, struct file *filp)
1723 return 0; 1724 return 0;
1724} 1725}
1725 1726
1727/*
1728 * Return disk geometry.
1729 */
1730static int
1731dasd_getgeo(struct block_device *bdev, struct hd_geometry *geo)
1732{
1733 struct dasd_device *device;
1734
1735 device = bdev->bd_disk->private_data;
1736 if (!device)
1737 return -ENODEV;
1738
1739 if (!device->discipline ||
1740 !device->discipline->fill_geometry)
1741 return -EINVAL;
1742
1743 device->discipline->fill_geometry(device, geo);
1744 geo->start = get_start_sect(bdev) >> device->s2b_shift;
1745 return 0;
1746}
1747
1726struct block_device_operations 1748struct block_device_operations
1727dasd_device_operations = { 1749dasd_device_operations = {
1728 .owner = THIS_MODULE, 1750 .owner = THIS_MODULE,
1729 .open = dasd_open, 1751 .open = dasd_open,
1730 .release = dasd_release, 1752 .release = dasd_release,
1731 .ioctl = dasd_ioctl, 1753 .ioctl = dasd_ioctl,
1754 .getgeo = dasd_getgeo,
1732}; 1755};
1733 1756
1734 1757
diff --git a/drivers/s390/block/dasd_ioctl.c b/drivers/s390/block/dasd_ioctl.c
index 044b75371990..8e4dcd58599e 100644
--- a/drivers/s390/block/dasd_ioctl.c
+++ b/drivers/s390/block/dasd_ioctl.c
@@ -486,33 +486,6 @@ dasd_ioctl_set_ro(struct block_device *bdev, int no, long args)
486} 486}
487 487
488/* 488/*
489 * Return disk geometry.
490 */
491static int
492dasd_ioctl_getgeo(struct block_device *bdev, int no, long args)
493{
494 struct hd_geometry geo = { 0, };
495 struct dasd_device *device;
496
497 device = bdev->bd_disk->private_data;
498 if (device == NULL)
499 return -ENODEV;
500
501 if (device == NULL || device->discipline == NULL ||
502 device->discipline->fill_geometry == NULL)
503 return -EINVAL;
504
505 geo = (struct hd_geometry) {};
506 device->discipline->fill_geometry(device, &geo);
507 geo.start = get_start_sect(bdev) >> device->s2b_shift;
508 if (copy_to_user((struct hd_geometry __user *) args, &geo,
509 sizeof (struct hd_geometry)))
510 return -EFAULT;
511
512 return 0;
513}
514
515/*
516 * List of static ioctls. 489 * List of static ioctls.
517 */ 490 */
518static struct { int no; dasd_ioctl_fn_t fn; } dasd_ioctls[] = 491static struct { int no; dasd_ioctl_fn_t fn; } dasd_ioctls[] =
@@ -528,7 +501,6 @@ static struct { int no; dasd_ioctl_fn_t fn; } dasd_ioctls[] =
528 { BIODASDPRRST, dasd_ioctl_reset_profile }, 501 { BIODASDPRRST, dasd_ioctl_reset_profile },
529 { BLKROSET, dasd_ioctl_set_ro }, 502 { BLKROSET, dasd_ioctl_set_ro },
530 { DASDAPIVER, dasd_ioctl_api_version }, 503 { DASDAPIVER, dasd_ioctl_api_version },
531 { HDIO_GETGEO, dasd_ioctl_getgeo },
532 { -1, NULL } 504 { -1, NULL }
533}; 505};
534 506
diff --git a/drivers/s390/block/xpram.c b/drivers/s390/block/xpram.c
index bf3a67c3cc5e..54ecd548c318 100644
--- a/drivers/s390/block/xpram.c
+++ b/drivers/s390/block/xpram.c
@@ -328,31 +328,27 @@ fail:
328 return 0; 328 return 0;
329} 329}
330 330
331static int xpram_ioctl (struct inode *inode, struct file *filp, 331static int xpram_getgeo(struct block_device *bdev, struct hd_geometry *geo)
332 unsigned int cmd, unsigned long arg)
333{ 332{
334 struct hd_geometry __user *geo;
335 unsigned long size; 333 unsigned long size;
336 if (cmd != HDIO_GETGEO) 334
337 return -EINVAL;
338 /* 335 /*
339 * get geometry: we have to fake one... trim the size to a 336 * get geometry: we have to fake one... trim the size to a
340 * multiple of 64 (32k): tell we have 16 sectors, 4 heads, 337 * multiple of 64 (32k): tell we have 16 sectors, 4 heads,
341 * whatever cylinders. Tell also that data starts at sector. 4. 338 * whatever cylinders. Tell also that data starts at sector. 4.
342 */ 339 */
343 geo = (struct hd_geometry __user *) arg;
344 size = (xpram_pages * 8) & ~0x3f; 340 size = (xpram_pages * 8) & ~0x3f;
345 put_user(size >> 6, &geo->cylinders); 341 geo->cylinders = size >> 6;
346 put_user(4, &geo->heads); 342 geo->heads = 4;
347 put_user(16, &geo->sectors); 343 geo->sectors = 16;
348 put_user(4, &geo->start); 344 geo->start = 4;
349 return 0; 345 return 0;
350} 346}
351 347
352static struct block_device_operations xpram_devops = 348static struct block_device_operations xpram_devops =
353{ 349{
354 .owner = THIS_MODULE, 350 .owner = THIS_MODULE,
355 .ioctl = xpram_ioctl, 351 .getgeo = xpram_getgeo,
356}; 352};
357 353
358/* 354/*
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 32d4d8d7b9f3..4c5127ed379c 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -527,7 +527,7 @@ static int sd_release(struct inode *inode, struct file *filp)
527 return 0; 527 return 0;
528} 528}
529 529
530static int sd_hdio_getgeo(struct block_device *bdev, struct hd_geometry __user *loc) 530static int sd_getgeo(struct block_device *bdev, struct hd_geometry *geo)
531{ 531{
532 struct scsi_disk *sdkp = scsi_disk(bdev->bd_disk); 532 struct scsi_disk *sdkp = scsi_disk(bdev->bd_disk);
533 struct scsi_device *sdp = sdkp->device; 533 struct scsi_device *sdp = sdkp->device;
@@ -545,15 +545,9 @@ static int sd_hdio_getgeo(struct block_device *bdev, struct hd_geometry __user *
545 else 545 else
546 scsicam_bios_param(bdev, sdkp->capacity, diskinfo); 546 scsicam_bios_param(bdev, sdkp->capacity, diskinfo);
547 547
548 if (put_user(diskinfo[0], &loc->heads)) 548 geo->heads = diskinfo[0];
549 return -EFAULT; 549 geo->sectors = diskinfo[1];
550 if (put_user(diskinfo[1], &loc->sectors)) 550 geo->cylinders = diskinfo[2];
551 return -EFAULT;
552 if (put_user(diskinfo[2], &loc->cylinders))
553 return -EFAULT;
554 if (put_user((unsigned)get_start_sect(bdev),
555 (unsigned long __user *)&loc->start))
556 return -EFAULT;
557 return 0; 551 return 0;
558} 552}
559 553
@@ -593,12 +587,6 @@ static int sd_ioctl(struct inode * inode, struct file * filp,
593 if (!scsi_block_when_processing_errors(sdp) || !error) 587 if (!scsi_block_when_processing_errors(sdp) || !error)
594 return error; 588 return error;
595 589
596 if (cmd == HDIO_GETGEO) {
597 if (!arg)
598 return -EINVAL;
599 return sd_hdio_getgeo(bdev, p);
600 }
601
602 /* 590 /*
603 * Send SCSI addressing ioctls directly to mid level, send other 591 * Send SCSI addressing ioctls directly to mid level, send other
604 * ioctls to block level and then onto mid level if they can't be 592 * ioctls to block level and then onto mid level if they can't be
@@ -800,6 +788,7 @@ static struct block_device_operations sd_fops = {
800 .open = sd_open, 788 .open = sd_open,
801 .release = sd_release, 789 .release = sd_release,
802 .ioctl = sd_ioctl, 790 .ioctl = sd_ioctl,
791 .getgeo = sd_getgeo,
803#ifdef CONFIG_COMPAT 792#ifdef CONFIG_COMPAT
804 .compat_ioctl = sd_compat_ioctl, 793 .compat_ioctl = sd_compat_ioctl,
805#endif 794#endif
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 74c01aabd4ab..7f140480c6a8 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -224,6 +224,7 @@ extern int dir_notify_enable;
224#include <asm/semaphore.h> 224#include <asm/semaphore.h>
225#include <asm/byteorder.h> 225#include <asm/byteorder.h>
226 226
227struct hd_geometry;
227struct iovec; 228struct iovec;
228struct nameidata; 229struct nameidata;
229struct kiocb; 230struct kiocb;
@@ -962,6 +963,7 @@ struct block_device_operations {
962 int (*direct_access) (struct block_device *, sector_t, unsigned long *); 963 int (*direct_access) (struct block_device *, sector_t, unsigned long *);
963 int (*media_changed) (struct gendisk *); 964 int (*media_changed) (struct gendisk *);
964 int (*revalidate_disk) (struct gendisk *); 965 int (*revalidate_disk) (struct gendisk *);
966 int (*getgeo)(struct block_device *, struct hd_geometry *);
965 struct module *owner; 967 struct module *owner;
966}; 968};
967 969