CINXE.COM
LKML: Christoph Hellwig: [PATCH] add ->getgeo block device method
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>LKML: Christoph Hellwig: [PATCH] add ->getgeo block device method</title><link href="/css/message.css" rel="stylesheet" type="text/css" /><link href="/css/wrap.css" rel="alternate stylesheet" type="text/css" title="wrap" /><link href="/css/nowrap.css" rel="stylesheet" type="text/css" title="nowrap" /><link href="/favicon.ico" rel="shortcut icon" /><script src="/js/simple-calendar.js" type="text/javascript"></script><script src="/js/styleswitcher.js" type="text/javascript"></script><link rel="alternate" type="application/rss+xml" title="lkml.org : last 100 messages" href="/rss.php" /><link rel="alternate" type="application/rss+xml" title="lkml.org : last messages by Christoph Hellwig" href="/groupie.php?aid=30078" /><!--Matomo--><script> var _paq = window._paq = window._paq || []; /* tracker methods like "setCustomDimension" should be called before "trackPageView" */ _paq.push(["setDoNotTrack", true]); _paq.push(["disableCookies"]); _paq.push(['trackPageView']); _paq.push(['enableLinkTracking']); (function() { var u="//m.lkml.org/"; _paq.push(['setTrackerUrl', u+'matomo.php']); _paq.push(['setSiteId', '1']); var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0]; g.async=true; g.src=u+'matomo.js'; s.parentNode.insertBefore(g,s); })(); </script><!--End Matomo Code--></head><body onload="es.jasper.simpleCalendar.init();" itemscope="itemscope" itemtype="http://schema.org/BlogPosting"><table border="0" cellpadding="0" cellspacing="0"><tr><td width="180" align="center"><a href="/"><img style="border:0;width:135px;height:32px" src="/images/toprowlk.gif" alt="lkml.org" /></a></td><td width="32">聽</td><td class="nb"><div><a class="nb" href="/lkml"> [lkml]</a> 聽 <a class="nb" href="/lkml/2005"> [2005]</a> 聽 <a class="nb" href="/lkml/2005/11"> [Nov]</a> 聽 <a class="nb" href="/lkml/2005/11/19"> [19]</a> 聽 <a class="nb" href="/lkml/last100"> [last100]</a> 聽 <a href="/rss.php"><img src="/images/rss-or.gif" border="0" alt="RSS Feed" /></a></div><div>Views: <a href="#" class="nowrap" onclick="setActiveStyleSheet('wrap');return false;">[wrap]</a><a href="#" class="wrap" onclick="setActiveStyleSheet('nowrap');return false;">[no wrap]</a> 聽 <a class="nb" href="/lkml/mheaders/2005/11/19/98" onclick="this.href='/lkml/headers'+'/2005/11/19/98';">[headers]</a>聽 <a href="/lkml/bounce/2005/11/19/98">[forward]</a>聽 </div></td><td width="32">聽</td></tr><tr><td valign="top"><div class="es-jasper-simpleCalendar" baseurl="/lkml/"></div><div class="threadlist">Messages in this thread</div><ul class="threadlist"><li class="root"><a href="/lkml/2005/11/19/98">First message in thread</a></li><li class="origin"><a href="">Christoph Hellwig</a></li></ul><div class="threadlist">Patch in this message</div><ul class="threadlist"><li><a href="/lkml/diff/2005/11/19/98/1">Get diff 1</a></li></ul></td><td width="32" rowspan="2" class="c" valign="top"><img src="/images/icornerl.gif" width="32" height="32" alt="/" /></td><td class="c" rowspan="2" valign="top" style="padding-top: 1em"><table><tr><td><table><tr><td class="lp">Date</td><td class="rp" itemprop="datePublished">Sat, 19 Nov 2005 21:47:54 +0100</td></tr><tr><td class="lp">From</td><td class="rp" itemprop="author">Christoph Hellwig <></td></tr><tr><td class="lp">Subject</td><td class="rp" itemprop="name">[PATCH] add ->getgeo block device method</td></tr></table></td><td></td></tr></table><pre itemprop="articleBody">HDIO_GETGEO is implemented in most block drivers, and all of them have<br />to duplicate the code to copy the structure to userspace, aswell as<br />getting the start sector. This patch moves that to common code [1]<br />and adds a ->getgeo method to fill out the raw kernel hd_geometry<br />structure. For many drivers this means ->ioctl can go away now.<br /><br />[1] the s390 block drivers are odd in this respect. xpram sets ->start<br /> to 4 always which seems more than odd, and the dasd driver shifts<br /> the start offset around, probably because of it's non-standard<br /> sector size.<br /><br /><br />Signed-off-by: Christoph Hellwig <hch@lst.de><br /><br />Index: linux-2.6/arch/um/drivers/ubd_kern.c<br />===================================================================<br />--- linux-2.6.orig/arch/um/drivers/ubd_kern.c 2005-11-19 19:51:41.000000000 +0100<br />+++ linux-2.6/arch/um/drivers/ubd_kern.c 2005-11-19 19:52:06.000000000 +0100<br />@@ -117,6 +117,7 @@<br /> static int ubd_release(struct inode * inode, struct file * file);<br /> static int ubd_ioctl(struct inode * inode, struct file * file,<br /> unsigned int cmd, unsigned long arg);<br />+static int ubd_getgeo(struct block_device *bdev, struct hd_geometry *geo);<br /> <br /> #define MAX_DEV (8)<br /> <br />@@ -125,6 +126,7 @@<br /> .open = ubd_open,<br /> .release = ubd_release,<br /> .ioctl = ubd_ioctl,<br />+ .getgeo = ubd_getgeo,<br /> };<br /> <br /> /* Protected by the queue_lock */<br />@@ -1058,6 +1060,16 @@<br /> }<br /> }<br /> <br />+static int ubd_getgeo(struct block_device *bdev, struct hd_geometry *geo)<br />+{<br />+ struct ubd *dev = bdev->bd_disk->private_data;<br />+<br />+ geo->heads = 128;<br />+ geo->sectors = 32;<br />+ geo->cylinders = dev->size / (128 * 32 * 512);<br />+ return 0;<br />+}<br />+<br /> static int ubd_ioctl(struct inode * inode, struct file * file,<br /> unsigned int cmd, unsigned long arg)<br /> {<br />@@ -1070,16 +1082,7 @@<br /> };<br /> <br /> switch (cmd) {<br />- struct hd_geometry g;<br /> struct cdrom_volctrl volume;<br />- case HDIO_GETGEO:<br />- if(!loc) return(-EINVAL);<br />- g.heads = 128;<br />- g.sectors = 32;<br />- g.cylinders = dev->size / (128 * 32 * 512);<br />- g.start = get_start_sect(inode->i_bdev);<br />- return(copy_to_user(loc, &g, sizeof(g)) ? -EFAULT : 0);<br />-<br /> case HDIO_GET_IDENTITY:<br /> ubd_id.cyls = dev->size / (128 * 32 * 512);<br /> if(copy_to_user((char __user *) arg, (char *) &ubd_id,<br />Index: linux-2.6/block/ioctl.c<br />===================================================================<br />--- linux-2.6.orig/block/ioctl.c 2005-11-19 19:51:58.000000000 +0100<br />+++ linux-2.6/block/ioctl.c 2005-11-19 19:52:25.000000000 +0100<br />@@ -1,6 +1,7 @@<br /> #include <linux/sched.h> /* for capable() */<br /> #include <linux/blkdev.h><br /> #include <linux/blkpg.h><br />+#include <linux/hdreg.h><br /> #include <linux/backing-dev.h><br /> #include <linux/buffer_head.h><br /> #include <linux/smp_lock.h><br />@@ -245,6 +246,27 @@<br /> set_device_ro(bdev, n);<br /> unlock_kernel();<br /> return 0;<br />+ case HDIO_GETGEO: {<br />+ struct hd_geometry geo;<br />+<br />+ if (!arg)<br />+ return -EINVAL;<br />+ if (!disk->fops->getgeo)<br />+ return -ENOTTY;<br />+<br />+ /*<br />+ * We need to set the startsect first, the driver may<br />+ * want to override it.<br />+ */<br />+ geo.start = get_start_sect(bdev);<br />+ ret = disk->fops->getgeo(bdev, &geo);<br />+ if (ret)<br />+ return ret;<br />+ if (copy_to_user((struct hd_geometry __user *)arg, &geo,<br />+ sizeof(geo)))<br />+ return -EFAULT;<br />+ return 0;<br />+ }<br /> }<br /> <br /> lock_kernel();<br />Index: linux-2.6/drivers/acorn/block/mfmhd.c<br />===================================================================<br />--- linux-2.6.orig/drivers/acorn/block/mfmhd.c 2005-11-19 19:51:41.000000000 +0100<br />+++ linux-2.6/drivers/acorn/block/mfmhd.c 2005-11-19 19:52:06.000000000 +0100<br />@@ -129,19 +129,6 @@<br /> #define MAJOR_NR MFM_ACORN_MAJOR<br /> #define QUEUE (mfm_queue)<br /> #define CURRENT elv_next_request(mfm_queue)<br />-/*<br />- * This sort of stuff should be in a header file shared with ide.c, hd.c, xd.c etc<br />- */<br />-#ifndef HDIO_GETGEO<br />-#define HDIO_GETGEO 0x301<br />-struct hd_geometry {<br />- unsigned char heads;<br />- unsigned char sectors;<br />- unsigned short cylinders;<br />- unsigned long start;<br />-};<br />-#endif<br />-<br /> <br /> /*<br /> * Configuration section<br />@@ -1153,22 +1140,13 @@<br /> * The 'front' end of the mfm driver follows...<br /> */<br /> <br />-static int mfm_ioctl(struct inode *inode, struct file *file, u_int cmd, u_long arg)<br />+static int mfm_getgeo(struct block_device *bdev, struct hd_geometry *geo)<br /> {<br />- struct mfm_info *p = inode->i_bdev->bd_disk->private_data;<br />- struct hd_geometry *geo = (struct hd_geometry *) arg;<br />- if (cmd != HDIO_GETGEO)<br />- return -EINVAL;<br />- if (!arg)<br />- return -EINVAL;<br />- if (put_user (p->heads, &geo->heads))<br />- return -EFAULT;<br />- if (put_user (p->sectors, &geo->sectors))<br />- return -EFAULT;<br />- if (put_user (p->cylinders, &geo->cylinders))<br />- return -EFAULT;<br />- if (put_user (get_start_sect(inode->i_bdev), &geo->start))<br />- return -EFAULT;<br />+ struct mfm_info *p = bdev->bd_disk->private_data;<br />+<br />+ geo->heads = p->heads;<br />+ geo->sectors = p->sectors;<br />+ geo->cylinders = p->cylinders;<br /> return 0;<br /> }<br /> <br />@@ -1219,7 +1197,7 @@<br /> static struct block_device_operations mfm_fops =<br /> {<br /> .owner = THIS_MODULE,<br />- .ioctl = mfm_ioctl,<br />+ .getgeo = mfm_getgeo,<br /> };<br /> <br /> /*<br />Index: linux-2.6/drivers/block/DAC960.c<br />===================================================================<br />--- linux-2.6.orig/drivers/block/DAC960.c 2005-11-19 19:51:41.000000000 +0100<br />+++ linux-2.6/drivers/block/DAC960.c 2005-11-19 19:52:06.000000000 +0100<br />@@ -92,34 +92,28 @@<br /> return 0;<br /> }<br /> <br />-static int DAC960_ioctl(struct inode *inode, struct file *file,<br />- unsigned int cmd, unsigned long arg)<br />+static int DAC960_getgeo(struct block_device *bdev, struct hd_geometry *geo)<br /> {<br />- struct gendisk *disk = inode->i_bdev->bd_disk;<br />+ struct gendisk *disk = bdev->bd_disk;<br /> DAC960_Controller_T *p = disk->queue->queuedata;<br /> int drive_nr = (long)disk->private_data;<br />- struct hd_geometry g;<br />- struct hd_geometry __user *loc = (struct hd_geometry __user *)arg;<br />-<br />- if (cmd != HDIO_GETGEO || !loc)<br />- return -EINVAL;<br /> <br /> if (p->FirmwareType == DAC960_V1_Controller) {<br />- g.heads = p->V1.GeometryTranslationHeads;<br />- g.sectors = p->V1.GeometryTranslationSectors;<br />- g.cylinders = p->V1.LogicalDriveInformation[drive_nr].<br />- LogicalDriveSize / (g.heads * g.sectors);<br />+ geo->heads = p->V1.GeometryTranslationHeads;<br />+ geo->sectors = p->V1.GeometryTranslationSectors;<br />+ geo->cylinders = p->V1.LogicalDriveInformation[drive_nr].<br />+ LogicalDriveSize / (geo->heads * geo->sectors);<br /> } else {<br /> DAC960_V2_LogicalDeviceInfo_T *i =<br /> p->V2.LogicalDeviceInformation[drive_nr];<br /> switch (i->DriveGeometry) {<br /> case DAC960_V2_Geometry_128_32:<br />- g.heads = 128;<br />- g.sectors = 32;<br />+ geo->heads = 128;<br />+ geo->sectors = 32;<br /> break;<br /> case DAC960_V2_Geometry_255_63:<br />- g.heads = 255;<br />- g.sectors = 63;<br />+ geo->heads = 255;<br />+ geo->sectors = 63;<br /> break;<br /> default:<br /> DAC960_Error("Illegal Logical Device Geometry %d\n",<br />@@ -127,12 +121,11 @@<br /> return -EINVAL;<br /> }<br /> <br />- g.cylinders = i->ConfigurableDeviceSize / (g.heads * g.sectors);<br />+ geo->cylinders = i->ConfigurableDeviceSize /<br />+ (geo->heads * geo->sectors);<br /> }<br /> <br />- g.start = get_start_sect(inode->i_bdev);<br />-<br />- return copy_to_user(loc, &g, sizeof g) ? -EFAULT : 0; <br />+ return 0;<br /> }<br /> <br /> static int DAC960_media_changed(struct gendisk *disk)<br />@@ -157,7 +150,7 @@<br /> static struct block_device_operations DAC960_BlockDeviceOperations = {<br /> .owner = THIS_MODULE,<br /> .open = DAC960_open,<br />- .ioctl = DAC960_ioctl,<br />+ .getgeo = DAC960_getgeo,<br /> .media_changed = DAC960_media_changed,<br /> .revalidate_disk = DAC960_revalidate_disk,<br /> };<br />Index: linux-2.6/drivers/block/acsi.c<br />===================================================================<br />--- linux-2.6.orig/drivers/block/acsi.c 2005-11-19 19:51:41.000000000 +0100<br />+++ linux-2.6/drivers/block/acsi.c 2005-11-19 19:52:06.000000000 +0100<br />@@ -1079,6 +1079,19 @@<br /> *<br /> ***********************************************************************/<br /> <br />+static int acsi_getgeo(struct block_device *bdev, struct hd_geometry *geo)<br />+{<br />+ struct acsi_info_struct *aip = bdev->bd_disk->private_data;<br />+<br />+ /*<br />+ * Just fake some geometry here, it's nonsense anyway<br />+ * To make it easy, use Adaptec's usual 64/32 mapping<br />+ */<br />+ geo->heads = 64;<br />+ geo->sectors = 32;<br />+ geo->cylinders = aip->size >> 11;<br />+ return 0;<br />+}<br /> <br /> static int acsi_ioctl( struct inode *inode, struct file *file,<br /> unsigned int cmd, unsigned long arg )<br />@@ -1086,18 +1099,6 @@<br /> struct gendisk *disk = inode->i_bdev->bd_disk;<br /> struct acsi_info_struct *aip = disk->private_data;<br /> switch (cmd) {<br />- case HDIO_GETGEO:<br />- /* HDIO_GETGEO is supported more for getting the partition's<br />- * start sector... */<br />- { struct hd_geometry *geo = (struct hd_geometry *)arg;<br />- /* just fake some geometry here, it's nonsense anyway; to make it<br />- * easy, use Adaptec's usual 64/32 mapping */<br />- put_user( 64, &geo->heads );<br />- put_user( 32, &geo->sectors );<br />- put_user( aip->size >> 11, &geo->cylinders );<br />- put_user(get_start_sect(inode->i_bdev), &geo->start);<br />- return 0;<br />- }<br /> case SCSI_IOCTL_GET_IDLUN:<br /> /* SCSI compatible GET_IDLUN call to get target's ID and LUN number */<br /> put_user( aip->target | (aip->lun << 8),<br />@@ -1592,6 +1593,7 @@<br /> .open = acsi_open,<br /> .release = acsi_release,<br /> .ioctl = acsi_ioctl,<br />+ .getgeo = acsi_getgeo,<br /> .media_changed = acsi_media_change,<br /> .revalidate_disk= acsi_revalidate,<br /> };<br />Index: linux-2.6/drivers/block/amiflop.c<br />===================================================================<br />--- linux-2.6.orig/drivers/block/amiflop.c 2005-11-19 19:51:41.000000000 +0100<br />+++ linux-2.6/drivers/block/amiflop.c 2005-11-19 19:52:06.000000000 +0100<br />@@ -1424,6 +1424,16 @@<br /> redo_fd_request();<br /> }<br /> <br />+static int fd_getgeo(struct block_device *bdev, struct hd_geometry *geo)<br />+{<br />+ int drive = minor(bdev->bd_dev) & 3;<br />+<br />+ geo->heads = unit[drive].type->heads;<br />+ geo->sectors = unit[drive].dtype->sects * unit[drive].type->sect_mult;<br />+ geo->cylinders = unit[drive].type->tracks;<br />+ return 0;<br />+}<br />+<br /> static int fd_ioctl(struct inode *inode, struct file *filp,<br /> unsigned int cmd, unsigned long param)<br /> {<br />@@ -1431,18 +1441,6 @@<br /> static struct floppy_struct getprm;<br /> <br /> switch(cmd){<br />- case HDIO_GETGEO:<br />- {<br />- struct hd_geometry loc;<br />- loc.heads = unit[drive].type->heads;<br />- loc.sectors = unit[drive].dtype->sects * unit[drive].type->sect_mult;<br />- loc.cylinders = unit[drive].type->tracks;<br />- loc.start = 0;<br />- if (copy_to_user((void *)param, (void *)&loc,<br />- sizeof(struct hd_geometry)))<br />- return -EFAULT;<br />- break;<br />- }<br /> case FDFMTBEG:<br /> get_fdc(drive);<br /> if (fd_ref[drive] > 1) {<br />@@ -1652,6 +1650,7 @@<br /> .open = floppy_open,<br /> .release = floppy_release,<br /> .ioctl = fd_ioctl,<br />+ .getgeo = fd_getgeo,<br /> .media_changed = amiga_floppy_change,<br /> };<br /> <br />Index: linux-2.6/drivers/block/aoe/aoeblk.c<br />===================================================================<br />--- linux-2.6.orig/drivers/block/aoe/aoeblk.c 2005-11-19 19:51:41.000000000 +0100<br />+++ linux-2.6/drivers/block/aoe/aoeblk.c 2005-11-19 19:52:06.000000000 +0100<br />@@ -169,38 +169,26 @@<br /> return 0;<br /> }<br /> <br />-/* This ioctl implementation expects userland to have the device node<br />- * permissions set so that only priviledged users can open an aoe<br />- * block device directly.<br />- */<br /> static int<br />-aoeblk_ioctl(struct inode *inode, struct file *filp, uint cmd, ulong arg)<br />+aoeblk_getgeo(struct block_device *bdev, struct hd_geometry *geo)<br /> {<br />- struct aoedev *d;<br />+ struct aoedev *d = bdev->bd_disk->private_data;<br /> <br />- if (!arg)<br />- return -EINVAL;<br />-<br />- d = inode->i_bdev->bd_disk->private_data;<br /> if ((d->flags & DEVFL_UP) == 0) {<br /> printk(KERN_ERR "aoe: aoeblk_ioctl: disk not up\n");<br /> return -ENODEV;<br /> }<br /> <br />- if (cmd == HDIO_GETGEO) {<br />- d->geo.start = get_start_sect(inode->i_bdev);<br />- if (!copy_to_user((void __user *) arg, &d->geo, sizeof d->geo))<br />- return 0;<br />- return -EFAULT;<br />- }<br />- printk(KERN_INFO "aoe: aoeblk_ioctl: unknown ioctl %d\n", cmd);<br />- return -EINVAL;<br />+ geo->cylinders = d->geo.cylinders;<br />+ geo->heads = d->geo.heads;<br />+ geo->sectors = d->geo.sectors;<br />+ return 0;<br /> }<br /> <br /> static struct block_device_operations aoe_bdops = {<br /> .open = aoeblk_open,<br /> .release = aoeblk_release,<br />- .ioctl = aoeblk_ioctl,<br />+ .getgeo = aoeblk_getgeo,<br /> .owner = THIS_MODULE,<br /> };<br /> <br />Index: linux-2.6/drivers/block/cciss.c<br />===================================================================<br />--- linux-2.6.orig/drivers/block/cciss.c 2005-11-19 19:51:41.000000000 +0100<br />+++ linux-2.6/drivers/block/cciss.c 2005-11-19 19:52:06.000000000 +0100<br />@@ -153,6 +153,7 @@<br /> static int cciss_release(struct inode *inode, struct file *filep);<br /> static int cciss_ioctl(struct inode *inode, struct file *filep, <br /> unsigned int cmd, unsigned long arg);<br />+static int cciss_getgeo(struct block_device *bdev, struct hd_geometry *geo);<br /> <br /> static int revalidate_allvol(ctlr_info_t *host);<br /> static int cciss_revalidate(struct gendisk *disk);<br />@@ -194,6 +195,7 @@<br /> .open = cciss_open, <br /> .release = cciss_release,<br /> .ioctl = cciss_ioctl,<br />+ .getgeo = cciss_getgeo,<br /> #ifdef CONFIG_COMPAT<br /> .compat_ioctl = cciss_compat_ioctl,<br /> #endif<br />@@ -633,6 +635,20 @@<br /> return err;<br /> }<br /> #endif<br />+<br />+static int cciss_getgeo(struct block_device *bdev, struct hd_geometry *geo)<br />+{<br />+ drive_info_struct *drv = get_drv(bdev->bd_disk);<br />+<br />+ if (!drv->cylinders)<br />+ return -ENXIO;<br />+<br />+ geo->heads = drv->heads;<br />+ geo->sectors = drv->sectors;<br />+ geo->cylinders = drv->cylinders;<br />+ return 0;<br />+}<br />+<br /> /*<br /> * ioctl <br /> */<br />@@ -651,21 +667,6 @@<br /> #endif /* CCISS_DEBUG */ <br /> <br /> switch(cmd) {<br />- case HDIO_GETGEO:<br />- {<br />- struct hd_geometry driver_geo;<br />- if (drv->cylinders) {<br />- driver_geo.heads = drv->heads;<br />- driver_geo.sectors = drv->sectors;<br />- driver_geo.cylinders = drv->cylinders;<br />- } else<br />- return -ENXIO;<br />- driver_geo.start= get_start_sect(inode->i_bdev);<br />- if (copy_to_user(argp, &driver_geo, sizeof(struct hd_geometry)))<br />- return -EFAULT;<br />- return(0);<br />- }<br />-<br /> case CCISS_GETPCIINFO:<br /> {<br /> cciss_pci_info_struct pciinfo;<br />Index: linux-2.6/drivers/block/cpqarray.c<br />===================================================================<br />--- linux-2.6.orig/drivers/block/cpqarray.c 2005-11-19 19:51:41.000000000 +0100<br />+++ linux-2.6/drivers/block/cpqarray.c 2005-11-19 20:30:43.000000000 +0100<br />@@ -160,6 +160,7 @@<br /> static int ida_open(struct inode *inode, struct file *filep);<br /> static int ida_release(struct inode *inode, struct file *filep);<br /> static int ida_ioctl(struct inode *inode, struct file *filep, unsigned int cmd, unsigned long arg);<br />+static int ida_getgeo(struct block_device *bdev, struct hd_geometry *geo);<br /> static int ida_ctlr_ioctl(ctlr_info_t *h, int dsk, ida_ioctl_t *io);<br /> <br /> static void do_ida_request(request_queue_t *q);<br />@@ -199,6 +200,7 @@<br /> .open = ida_open,<br /> .release = ida_release,<br /> .ioctl = ida_ioctl,<br />+ .getgeo = ida_getgeo,<br /> .revalidate_disk= ida_revalidate,<br /> };<br /> <br />@@ -1124,6 +1126,23 @@<br /> h->misc_tflags = 0;<br /> }<br /> <br />+static int ida_getgeo(struct block_device *bdev, struct hd_geometry *geo)<br />+{<br />+ drv_info_t *drv = get_drv(bdev->bd_disk);<br />+<br />+ if (drv->cylinders) {<br />+ geo->heads = drv->heads;<br />+ geo->sectors = drv->sectors;<br />+ geo->cylinders = drv->cylinders;<br />+ } else {<br />+ geo->heads = 0xff;<br />+ geo->sectors = 0x3f;<br />+ geo->cylinders = drv->nr_blks / (0xff*0x3f);<br />+ }<br />+<br />+ return 0;<br />+}<br />+<br /> /*<br /> * ida_ioctl does some miscellaneous stuff like reporting drive geometry,<br /> * setting readahead and submitting commands from userspace to the controller.<br />@@ -1133,27 +1152,10 @@<br /> drv_info_t *drv = get_drv(inode->i_bdev->bd_disk);<br /> ctlr_info_t *host = get_host(inode->i_bdev->bd_disk);<br /> int error;<br />- int diskinfo[4];<br />- struct hd_geometry __user *geo = (struct hd_geometry __user *)arg;<br /> ida_ioctl_t __user *io = (ida_ioctl_t __user *)arg;<br /> ida_ioctl_t *my_io;<br /> <br /> switch(cmd) {<br />- case HDIO_GETGEO:<br />- if (drv->cylinders) {<br />- diskinfo[0] = drv->heads;<br />- diskinfo[1] = drv->sectors;<br />- diskinfo[2] = drv->cylinders;<br />- } else {<br />- diskinfo[0] = 0xff;<br />- diskinfo[1] = 0x3f;<br />- diskinfo[2] = drv->nr_blks / (0xff*0x3f);<br />- }<br />- put_user(diskinfo[0], &geo->heads);<br />- put_user(diskinfo[1], &geo->sectors);<br />- put_user(diskinfo[2], &geo->cylinders);<br />- put_user(get_start_sect(inode->i_bdev), &geo->start);<br />- return 0;<br /> case IDAGETDRVINFO:<br /> if (copy_to_user(&io->c.drv, drv, sizeof(drv_info_t)))<br /> return -EFAULT;<br />Index: linux-2.6/drivers/block/floppy.c<br />===================================================================<br />--- linux-2.6.orig/drivers/block/floppy.c 2005-11-19 19:51:41.000000000 +0100<br />+++ linux-2.6/drivers/block/floppy.c 2005-11-19 19:52:07.000000000 +0100<br />@@ -3445,6 +3445,23 @@<br /> return 0;<br /> }<br /> <br />+static int fd_getgeo(struct block_device *bdev, struct hd_geometry *geo)<br />+{<br />+ int drive = (long)bdev->bd_disk->private_data;<br />+ int type = ITYPE(drive_state[drive].fd_device);<br />+ struct floppy_struct *g;<br />+ int ret;<br />+<br />+ ret = get_floppy_geometry(drive, type, &g);<br />+ if (ret)<br />+ return ret;<br />+<br />+ geo->heads = g->head;<br />+ geo->sectors = g->sect;<br />+ geo->cylinders = g->track;<br />+ return 0;<br />+}<br />+<br /> static int fd_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,<br /> unsigned long param)<br /> {<br />@@ -3474,23 +3491,6 @@<br /> cmd = FDEJECT;<br /> }<br /> <br />- /* generic block device ioctls */<br />- switch (cmd) {<br />- /* the following have been inspired by the corresponding<br />- * code for other block devices. */<br />- struct floppy_struct *g;<br />- case HDIO_GETGEO:<br />- {<br />- struct hd_geometry loc;<br />- ECALL(get_floppy_geometry(drive, type, &g));<br />- loc.heads = g->head;<br />- loc.sectors = g->sect;<br />- loc.cylinders = g->track;<br />- loc.start = 0;<br />- return _COPYOUT(loc);<br />- }<br />- }<br />-<br /> /* convert the old style command into a new style command */<br /> if ((cmd & 0xff00) == 0x0200) {<br /> ECALL(normalize_ioctl(&cmd, &size));<br />@@ -3944,6 +3944,7 @@<br /> .open = floppy_open,<br /> .release = floppy_release,<br /> .ioctl = fd_ioctl,<br />+ .getgeo = fd_getgeo,<br /> .media_changed = check_floppy_change,<br /> .revalidate_disk = floppy_revalidate,<br /> };<br />Index: linux-2.6/drivers/block/paride/pd.c<br />===================================================================<br />--- linux-2.6.orig/drivers/block/paride/pd.c 2005-11-19 19:51:41.000000000 +0100<br />+++ linux-2.6/drivers/block/paride/pd.c 2005-11-19 19:52:07.000000000 +0100<br />@@ -747,32 +747,33 @@<br /> return 0;<br /> }<br /> <br />+static int pd_getgeo(struct block_device *bdev, struct hd_geometry *geo)<br />+{<br />+ struct pd_unit *disk = bdev->bd_disk->private_data;<br />+<br />+ if (disk->alt_geom) {<br />+ geo->heads = PD_LOG_HEADS;<br />+ geo->sectors = PD_LOG_SECTS;<br />+ geo->cylinders = disk->capacity / (geo->heads * geo->sectors);<br />+ } else {<br />+ geo->heads = disk->heads;<br />+ geo->sectors = disk->sectors;<br />+ geo->cylinders = disk->cylinders;<br />+ }<br />+<br />+ return 0;<br />+}<br />+<br /> static int pd_ioctl(struct inode *inode, struct file *file,<br /> unsigned int cmd, unsigned long arg)<br /> {<br /> struct pd_unit *disk = inode->i_bdev->bd_disk->private_data;<br />- struct hd_geometry __user *geo = (struct hd_geometry __user *) arg;<br />- struct hd_geometry g;<br /> <br /> switch (cmd) {<br /> case CDROMEJECT:<br /> if (disk->access == 1)<br /> pd_special_command(disk, pd_eject);<br /> return 0;<br />- case HDIO_GETGEO:<br />- if (disk->alt_geom) {<br />- g.heads = PD_LOG_HEADS;<br />- g.sectors = PD_LOG_SECTS;<br />- g.cylinders = disk->capacity / (g.heads * g.sectors);<br />- } else {<br />- g.heads = disk->heads;<br />- g.sectors = disk->sectors;<br />- g.cylinders = disk->cylinders;<br />- }<br />- g.start = get_start_sect(inode->i_bdev);<br />- if (copy_to_user(geo, &g, sizeof(struct hd_geometry)))<br />- return -EFAULT;<br />- return 0;<br /> default:<br /> return -EINVAL;<br /> }<br />@@ -815,6 +816,7 @@<br /> .open = pd_open,<br /> .release = pd_release,<br /> .ioctl = pd_ioctl,<br />+ .getgeo = pd_getgeo,<br /> .media_changed = pd_check_media,<br /> .revalidate_disk= pd_revalidate<br /> };<br />Index: linux-2.6/drivers/block/paride/pf.c<br />===================================================================<br />--- linux-2.6.orig/drivers/block/paride/pf.c 2005-11-19 19:51:41.000000000 +0100<br />+++ linux-2.6/drivers/block/paride/pf.c 2005-11-19 19:52:07.000000000 +0100<br />@@ -205,6 +205,7 @@<br /> static void do_pf_request(request_queue_t * q);<br /> static int pf_ioctl(struct inode *inode, struct file *file,<br /> unsigned int cmd, unsigned long arg);<br />+static int pf_getgeo(struct block_device *bdev, struct hd_geometry *geo);<br /> <br /> static int pf_release(struct inode *inode, struct file *file);<br /> <br />@@ -266,6 +267,7 @@<br /> .open = pf_open,<br /> .release = pf_release,<br /> .ioctl = pf_ioctl,<br />+ .getgeo = pf_getgeo,<br /> .media_changed = pf_check_media,<br /> };<br /> <br />@@ -313,34 +315,34 @@<br /> return 0;<br /> }<br /> <br />-static int pf_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)<br />+static int pf_getgeo(struct block_device *bdev, struct hd_geometry *geo)<br /> {<br />- struct pf_unit *pf = inode->i_bdev->bd_disk->private_data;<br />- struct hd_geometry __user *geo = (struct hd_geometry __user *) arg;<br />- struct hd_geometry g;<br />- sector_t capacity;<br />-<br />- if (cmd == CDROMEJECT) {<br />- if (pf->access == 1) {<br />- pf_eject(pf);<br />- return 0;<br />- }<br />- return -EBUSY;<br />- }<br />- if (cmd != HDIO_GETGEO)<br />- return -EINVAL;<br />- capacity = get_capacity(pf->disk);<br />+ struct pf_unit *pf = bdev->bd_disk->private_data;<br />+ sector_t capacity = get_capacity(pf->disk);<br />+<br /> if (capacity < PF_FD_MAX) {<br />- g.cylinders = sector_div(capacity, PF_FD_HDS * PF_FD_SPT);<br />- g.heads = PF_FD_HDS;<br />- g.sectors = PF_FD_SPT;<br />+ geo->cylinders = sector_div(capacity, PF_FD_HDS * PF_FD_SPT);`<br />+ geo->heads = PF_FD_HDS;<br />+ geo->sectors = PF_FD_SPT;<br /> } else {<br />- g.cylinders = sector_div(capacity, PF_HD_HDS * PF_HD_SPT);<br />- g.heads = PF_HD_HDS;<br />- g.sectors = PF_HD_SPT;<br />+ geo->cylinders = sector_div(capacity, PF_HD_HDS * PF_HD_SPT);<br />+ geo->heads = PF_HD_HDS;<br />+ geo->sectors = PF_HD_SPT;<br /> }<br />- if (copy_to_user(geo, &g, sizeof(g)))<br />- return -EFAULT;<br />+<br />+ return 0;<br />+}<br />+<br />+static int pf_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)<br />+{<br />+ struct pf_unit *pf = inode->i_bdev->bd_disk->private_data;<br />+<br />+ if (cmd != CDROMEJECT)<br />+ return -EINVAL;<br />+<br />+ if (pf->access != 1)<br />+ return -EBUSY;<br />+ pf_eject(pf);<br /> return 0;<br /> }<br /> <br />Index: linux-2.6/drivers/block/ps2esdi.c<br />===================================================================<br />--- linux-2.6.orig/drivers/block/ps2esdi.c 2005-11-19 19:51:41.000000000 +0100<br />+++ linux-2.6/drivers/block/ps2esdi.c 2005-11-19 19:52:07.000000000 +0100<br />@@ -81,8 +81,7 @@<br /> static void ps2esdi_normal_interrupt_handler(u_int);<br /> static void ps2esdi_initial_reset_int_handler(u_int);<br /> static void ps2esdi_geometry_int_handler(u_int);<br />-static int ps2esdi_ioctl(struct inode *inode, struct file *file,<br />- u_int cmd, u_long arg);<br />+static int ps2esdi_getgeo(struct block_device *bdev, struct hd_geometry *geo);<br /> <br /> static int ps2esdi_read_status_words(int num_words, int max_words, u_short * buffer);<br /> <br />@@ -132,7 +131,7 @@<br /> static struct block_device_operations ps2esdi_fops =<br /> {<br /> .owner = THIS_MODULE,<br />- .ioctl = ps2esdi_ioctl,<br />+ .getgeo = ps2esdi_getgeo,<br /> };<br /> <br /> static struct gendisk *ps2esdi_gendisk[2];<br />@@ -1058,21 +1057,13 @@<br /> <br /> }<br /> <br />-static int ps2esdi_ioctl(struct inode *inode,<br />- struct file *file, u_int cmd, u_long arg)<br />+static int ps2esdi_getgeo(struct block_device *bdev, struct hd_geometry *geo)<br /> {<br />- struct ps2esdi_i_struct *p = inode->i_bdev->bd_disk->private_data;<br />- struct ps2esdi_geometry geom;<br />+ struct ps2esdi_i_struct *p = bdev->bd_disk->private_data;<br /> <br />- if (cmd != HDIO_GETGEO)<br />- return -EINVAL;<br />- memset(&geom, 0, sizeof(geom));<br />- geom.heads = p->head;<br />- geom.sectors = p->sect;<br />- geom.cylinders = p->cyl;<br />- geom.start = get_start_sect(inode->i_bdev);<br />- if (copy_to_user((void __user *)arg, &geom, sizeof(geom)))<br />- return -EFAULT;<br />+ geo->heads = p->head;<br />+ geo->sectors = p->sect;<br />+ geo->cylinders = p->cyl;<br /> return 0;<br /> }<br /> <br />Index: linux-2.6/drivers/block/sx8.c<br />===================================================================<br />--- linux-2.6.orig/drivers/block/sx8.c 2005-11-19 19:51:41.000000000 +0100<br />+++ linux-2.6/drivers/block/sx8.c 2005-11-19 20:31:11.000000000 +0100<br />@@ -407,8 +407,7 @@<br /> <br /> static int carm_init_one (struct pci_dev *pdev, const struct pci_device_id *ent);<br /> static void carm_remove_one (struct pci_dev *pdev);<br />-static int carm_bdev_ioctl(struct inode *ino, struct file *fil,<br />- unsigned int cmd, unsigned long arg);<br />+static int carm_bdev_getgeo(struct block_device *bdev, struct hd_geometry *geo);<br /> <br /> static struct pci_device_id carm_pci_tbl[] = {<br /> { PCI_VENDOR_ID_PROMISE, 0x8000, PCI_ANY_ID, PCI_ANY_ID, 0, 0, },<br />@@ -426,7 +425,7 @@<br /> <br /> static struct block_device_operations carm_bd_ops = {<br /> .owner = THIS_MODULE,<br />- .ioctl = carm_bdev_ioctl,<br />+ .getgeo = carm_bdev_getgeo,<br /> };<br /> <br /> static unsigned int carm_host_id;<br />@@ -434,32 +433,14 @@<br /> <br /> <br /> <br />-static int carm_bdev_ioctl(struct inode *ino, struct file *fil,<br />- unsigned int cmd, unsigned long arg)<br />+static int carm_bdev_getgeo(struct block_device *bdev, struct hd_geometry *geo)<br /> {<br />- void __user *usermem = (void __user *) arg;<br />- struct carm_port *port = ino->i_bdev->bd_disk->private_data;<br />- struct hd_geometry geom;<br />-<br />- switch (cmd) {<br />- case HDIO_GETGEO:<br />- if (!usermem)<br />- return -EINVAL;<br />-<br />- geom.heads = (u8) port->dev_geom_head;<br />- geom.sectors = (u8) port->dev_geom_sect;<br />- geom.cylinders = port->dev_geom_cyl;<br />- geom.start = get_start_sect(ino->i_bdev);<br />-<br />- if (copy_to_user(usermem, &geom, sizeof(geom)))<br />- return -EFAULT;<br />- return 0;<br />+ struct carm_port *port = bdev->bd_disk->private_data;<br /> <br />- default:<br />- break;<br />- }<br />-<br />- return -EOPNOTSUPP;<br />+ geo->heads = (u8) port->dev_geom_head;<br />+ geo->sectors = (u8) port->dev_geom_sect;<br />+ geo->cylinders = port->dev_geom_cyl;<br />+ return 0;<br /> }<br /> <br /> static const u32 msg_sizes[] = { 32, 64, 128, CARM_MSG_SIZE };<br />Index: linux-2.6/drivers/block/umem.c<br />===================================================================<br />--- linux-2.6.orig/drivers/block/umem.c 2005-11-19 19:51:41.000000000 +0100<br />+++ linux-2.6/drivers/block/umem.c 2005-11-19 19:52:07.000000000 +0100<br />@@ -809,34 +809,23 @@<br /> set_capacity(disk, card->mm_size << 1);<br /> return 0;<br /> }<br />-/*<br />------------------------------------------------------------------------------------<br />--- mm_ioctl<br />------------------------------------------------------------------------------------<br />-*/<br />-static int mm_ioctl(struct inode *i, struct file *f, unsigned int cmd, unsigned long arg)<br />+<br />+static int mm_getgeo(struct block_device *bdev, struct hd_geometry *geo)<br /> {<br />- if (cmd == HDIO_GETGEO) {<br />- struct cardinfo *card = i->i_bdev->bd_disk->private_data;<br />- int size = card->mm_size * (1024 / MM_HARDSECT);<br />- struct hd_geometry geo;<br />- /*<br />- * get geometry: we have to fake one... trim the size to a<br />- * multiple of 2048 (1M): tell we have 32 sectors, 64 heads,<br />- * whatever cylinders.<br />- */<br />- geo.heads = 64;<br />- geo.sectors = 32;<br />- geo.start = get_start_sect(i->i_bdev);<br />- geo.cylinders = size / (geo.heads * geo.sectors);<br />-<br />- if (copy_to_user((void __user *) arg, &geo, sizeof(geo)))<br />- return -EFAULT;<br />- return 0;<br />- }<br />+ struct cardinfo *card = bdev->bd_disk->private_data;<br />+ int size = card->mm_size * (1024 / MM_HARDSECT);<br /> <br />- return -EINVAL;<br />+ /*<br />+ * get geometry: we have to fake one... trim the size to a<br />+ * multiple of 2048 (1M): tell we have 32 sectors, 64 heads,<br />+ * whatever cylinders.<br />+ */<br />+ geo->heads = 64;<br />+ geo->sectors = 32;<br />+ geo->cylinders = size / (geo->heads * geo->sectors);<br />+ return 0;<br /> }<br />+<br /> /*<br /> -----------------------------------------------------------------------------------<br /> -- mm_check_change<br />@@ -855,7 +844,7 @@<br /> */<br /> static struct block_device_operations mm_fops = {<br /> .owner = THIS_MODULE,<br />- .ioctl = mm_ioctl,<br />+ .getgeo = mm_getgeo,<br /> .revalidate_disk= mm_revalidate,<br /> .media_changed = mm_check_change,<br /> };<br />Index: linux-2.6/drivers/block/viodasd.c<br />===================================================================<br />--- linux-2.6.orig/drivers/block/viodasd.c 2005-11-19 19:51:41.000000000 +0100<br />+++ linux-2.6/drivers/block/viodasd.c 2005-11-19 21:43:49.000000000 +0100<br />@@ -247,43 +247,17 @@<br /> <br /> /* External ioctl entry point.<br /> */<br />-static int viodasd_ioctl(struct inode *ino, struct file *fil,<br />- unsigned int cmd, unsigned long arg)<br />+static int viodasd_getgeo(struct block_device *bdev, struct hd_geometry *geo)<br /> {<br />- unsigned char sectors;<br />- unsigned char heads;<br />- unsigned short cylinders;<br />- struct hd_geometry *geo;<br />- struct gendisk *gendisk;<br />- struct viodasd_device *d;<br />+ struct gendisk *disk = bdev->bd_disk;<br />+ struct viodasd_device *d = disk->private_data;<br /> <br />- switch (cmd) {<br />- case HDIO_GETGEO:<br />- geo = (struct hd_geometry *)arg;<br />- if (geo == NULL)<br />- return -EINVAL;<br />- if (!access_ok(VERIFY_WRITE, geo, sizeof(*geo)))<br />- return -EFAULT;<br />- gendisk = ino->i_bdev->bd_disk;<br />- d = gendisk->private_data;<br />- sectors = d->sectors;<br />- if (sectors == 0)<br />- sectors = 32;<br />- heads = d->tracks;<br />- if (heads == 0)<br />- heads = 64;<br />- cylinders = d->cylinders;<br />- if (cylinders == 0)<br />- cylinders = get_capacity(gendisk) / (sectors * heads);<br />- if (__put_user(sectors, &geo->sectors) ||<br />- __put_user(heads, &geo->heads) ||<br />- __put_user(cylinders, &geo->cylinders) ||<br />- __put_user(get_start_sect(ino->i_bdev), &geo->start))<br />- return -EFAULT;<br />- return 0;<br />- }<br />+ geo->sectors = d->sectors ? d->sectors : 0;<br />+ geo->heads = d->tracks ? d->tracks : 64;<br />+ geo->cylinders = d->cylinders ? d->cylinders :<br />+ get_capacity(disk) / (geo->cylinders * geo->heads);<br /> <br />- return -EINVAL;<br />+ return 0;<br /> }<br /> <br /> /*<br />@@ -293,7 +267,7 @@<br /> .owner = THIS_MODULE,<br /> .open = viodasd_open,<br /> .release = viodasd_release,<br />- .ioctl = viodasd_ioctl,<br />+ .getgeo = viodasd_getgeo,<br /> };<br /> <br /> /*<br />Index: linux-2.6/drivers/block/xd.c<br />===================================================================<br />--- linux-2.6.orig/drivers/block/xd.c 2005-11-19 19:51:41.000000000 +0100<br />+++ linux-2.6/drivers/block/xd.c 2005-11-19 19:52:07.000000000 +0100<br />@@ -128,9 +128,12 @@<br /> <br /> static struct gendisk *xd_gendisk[2];<br /> <br />+static int xd_getgeo(struct block_device *bdev, struct hd_geometry *geo);<br />+<br /> static struct block_device_operations xd_fops = {<br /> .owner = THIS_MODULE,<br /> .ioctl = xd_ioctl,<br />+ .getgeo = xd_getgeo,<br /> };<br /> static DECLARE_WAIT_QUEUE_HEAD(xd_wait_int);<br /> static u_char xd_drives, xd_irq = 5, xd_dma = 3, xd_maxsectors;<br />@@ -330,22 +333,22 @@<br /> }<br /> }<br /> <br />+static int xd_getgeo(struct block_device *bdev, struct hd_geometry *geo)<br />+{<br />+ XD_INFO *p = bdev->bd_disk->private_data;<br />+<br />+ geo->heads = p->heads;<br />+ geo->sectors = p->sectors;<br />+ geo->cylinders = p->cylinders;<br />+ return 0;<br />+}<br />+<br /> /* xd_ioctl: handle device ioctl's */<br /> static int xd_ioctl (struct inode *inode,struct file *file,u_int cmd,u_long arg)<br /> {<br /> XD_INFO *p = inode->i_bdev->bd_disk->private_data;<br /> <br /> switch (cmd) {<br />- case HDIO_GETGEO:<br />- {<br />- struct hd_geometry g;<br />- struct hd_geometry __user *geom= (void __user *)arg;<br />- g.heads = p->heads;<br />- g.sectors = p->sectors;<br />- g.cylinders = p->cylinders;<br />- g.start = get_start_sect(inode->i_bdev);<br />- return copy_to_user(geom, &g, sizeof(g)) ? -EFAULT : 0;<br />- }<br /> case HDIO_SET_DMA:<br /> if (!capable(CAP_SYS_ADMIN)) return -EACCES;<br /> if (xdc_busy) return -EBUSY;<br />Index: linux-2.6/drivers/ide/ide-disk.c<br />===================================================================<br />--- linux-2.6.orig/drivers/ide/ide-disk.c 2005-11-19 19:51:41.000000000 +0100<br />+++ linux-2.6/drivers/ide/ide-disk.c 2005-11-19 19:52:07.000000000 +0100<br />@@ -1161,6 +1161,17 @@<br /> return 0;<br /> }<br /> <br />+static int idedisk_getgeo(struct block_device *bdev, struct hd_geometry *geo)<br />+{<br />+ struct ide_disk_obj *idkp = ide_disk_g(bdev->bd_disk);<br />+ ide_drive_t *drive = idkp->drive;<br />+<br />+ geo->heads = drive->bios_head;<br />+ geo->sectors = drive->bios_sect;<br />+ geo->cylinders = (u16)drive->bios_cyl; /* truncate */<br />+ return 0;<br />+}<br />+<br /> static int idedisk_ioctl(struct inode *inode, struct file *file,<br /> unsigned int cmd, unsigned long arg)<br /> {<br />@@ -1195,6 +1206,7 @@<br /> .open = idedisk_open,<br /> .release = idedisk_release,<br /> .ioctl = idedisk_ioctl,<br />+ .getgeo = idedisk_getgeo,<br /> .media_changed = idedisk_media_changed,<br /> .revalidate_disk= idedisk_revalidate_disk<br /> };<br />Index: linux-2.6/drivers/ide/ide-floppy.c<br />===================================================================<br />--- linux-2.6.orig/drivers/ide/ide-floppy.c 2005-11-19 19:51:41.000000000 +0100<br />+++ linux-2.6/drivers/ide/ide-floppy.c 2005-11-19 19:52:07.000000000 +0100<br />@@ -2031,6 +2031,17 @@<br /> return 0;<br /> }<br /> <br />+static int idefloppy_getgeo(struct block_device *bdev, struct hd_geometry *geo)<br />+{<br />+ struct ide_floppy_obj *floppy = ide_floppy_g(bdev->bd_disk);<br />+ ide_drive_t *drive = floppy->drive;<br />+<br />+ geo->heads = drive->bios_head;<br />+ geo->sectors = drive->bios_sect;<br />+ geo->cylinders = (u16)drive->bios_cyl; /* truncate */<br />+ return 0;<br />+}<br />+<br /> static int idefloppy_ioctl(struct inode *inode, struct file *file,<br /> unsigned int cmd, unsigned long arg)<br /> {<br />@@ -2120,6 +2131,7 @@<br /> .open = idefloppy_open,<br /> .release = idefloppy_release,<br /> .ioctl = idefloppy_ioctl,<br />+ .getgeo = idefloppy_getgeo,<br /> .media_changed = idefloppy_media_changed,<br /> .revalidate_disk= idefloppy_revalidate_disk<br /> };<br />Index: linux-2.6/drivers/ide/ide.c<br />===================================================================<br />--- linux-2.6.orig/drivers/ide/ide.c 2005-11-19 19:51:41.000000000 +0100<br />+++ linux-2.6/drivers/ide/ide.c 2005-11-19 19:52:07.000000000 +0100<br />@@ -1278,19 +1278,6 @@<br /> up(&ide_setting_sem);<br /> <br /> switch (cmd) {<br />- case HDIO_GETGEO:<br />- {<br />- struct hd_geometry geom;<br />- if (!p || (drive->media != ide_disk && drive->media != ide_floppy)) return -EINVAL;<br />- geom.heads = drive->bios_head;<br />- geom.sectors = drive->bios_sect;<br />- geom.cylinders = (u16)drive->bios_cyl; /* truncate */<br />- geom.start = get_start_sect(bdev);<br />- if (copy_to_user(p, &geom, sizeof(struct hd_geometry)))<br />- return -EFAULT;<br />- return 0;<br />- }<br />-<br /> case HDIO_OBSOLETE_IDENTITY:<br /> case HDIO_GET_IDENTITY:<br /> if (bdev != bdev->bd_contains)<br />Index: linux-2.6/drivers/ide/legacy/hd.c<br />===================================================================<br />--- linux-2.6.orig/drivers/ide/legacy/hd.c 2005-11-19 19:51:41.000000000 +0100<br />+++ linux-2.6/drivers/ide/legacy/hd.c 2005-11-19 19:52:07.000000000 +0100<br />@@ -658,22 +658,14 @@<br /> enable_irq(HD_IRQ);<br /> }<br /> <br />-static int hd_ioctl(struct inode * inode, struct file * file,<br />- unsigned int cmd, unsigned long arg)<br />+static int hd_getgeo(struct block_device *bdev, struct hd_geometry *geo)<br /> {<br />- struct hd_i_struct *disk = inode->i_bdev->bd_disk->private_data;<br />- struct hd_geometry __user *loc = (struct hd_geometry __user *) arg;<br />- struct hd_geometry g; <br />-<br />- if (cmd != HDIO_GETGEO)<br />- return -EINVAL;<br />- if (!loc)<br />- return -EINVAL;<br />- g.heads = disk->head;<br />- g.sectors = disk->sect;<br />- g.cylinders = disk->cyl;<br />- g.start = get_start_sect(inode->i_bdev);<br />- return copy_to_user(loc, &g, sizeof g) ? -EFAULT : 0; <br />+ struct hd_i_struct *disk = bdev->bd_disk->private_data;<br />+<br />+ geo->heads = disk->head;<br />+ geo->sectors = disk->sect;<br />+ geo->cylinders = disk->cyl;<br />+ return 0;<br /> }<br /> <br /> /*<br />@@ -695,7 +687,7 @@<br /> }<br /> <br /> static struct block_device_operations hd_fops = {<br />- .ioctl = hd_ioctl,<br />+ .getgeo = hd_getgeo,<br /> };<br /> <br /> /*<br />Index: linux-2.6/drivers/md/md.c<br />===================================================================<br />--- linux-2.6.orig/drivers/md/md.c 2005-11-19 19:51:41.000000000 +0100<br />+++ linux-2.6/drivers/md/md.c 2005-11-19 19:52:51.000000000 +0100<br />@@ -3101,12 +3101,21 @@<br /> return 0;<br /> }<br /> <br />+static int md_getgeo(struct block_device *bdev, struct hd_geometry *geo)<br />+{<br />+ mddev_t *mddev = bdev->bd_disk->private_data;<br />+<br />+ geo->heads = 2;<br />+ geo->sectors = 4;<br />+ geo->cylinders = get_capacity(mddev->gendisk) / 8;<br />+ return 0;<br />+}<br />+<br /> static int md_ioctl(struct inode *inode, struct file *file,<br /> unsigned int cmd, unsigned long arg)<br /> {<br /> int err = 0;<br /> void __user *argp = (void __user *)arg;<br />- struct hd_geometry __user *loc = argp;<br /> mddev_t *mddev = NULL;<br /> <br /> if (!capable(CAP_SYS_ADMIN))<br />@@ -3268,24 +3277,6 @@<br /> * 4 sectors (with a BIG number of cylinders...). This drives<br /> * dosfs just mad... ;-)<br /> */<br />- case HDIO_GETGEO:<br />- if (!loc) {<br />- err = -EINVAL;<br />- goto abort_unlock;<br />- }<br />- err = put_user (2, (char __user *) &loc->heads);<br />- if (err)<br />- goto abort_unlock;<br />- err = put_user (4, (char __user *) &loc->sectors);<br />- if (err)<br />- goto abort_unlock;<br />- err = put_user(get_capacity(mddev->gendisk)/8,<br />- (short __user *) &loc->cylinders);<br />- if (err)<br />- goto abort_unlock;<br />- err = put_user (get_start_sect(inode->i_bdev),<br />- (long __user *) &loc->start);<br />- goto done_unlock;<br /> }<br /> <br /> /*<br />@@ -3414,6 +3405,7 @@<br /> .open = md_open,<br /> .release = md_release,<br /> .ioctl = md_ioctl,<br />+ .getgeo = md_getgeo,<br /> .media_changed = md_media_changed,<br /> .revalidate_disk= md_revalidate,<br /> };<br />Index: linux-2.6/drivers/message/i2o/i2o_block.c<br />===================================================================<br />--- linux-2.6.orig/drivers/message/i2o/i2o_block.c 2005-11-19 19:51:41.000000000 +0100<br />+++ linux-2.6/drivers/message/i2o/i2o_block.c 2005-11-19 20:32:03.000000000 +0100<br />@@ -660,6 +660,13 @@<br /> return 0;<br /> }<br /> <br />+static int i2o_block_getgeo(struct block_device *bdev, struct hd_geometry *geo)<br />+{<br />+ i2o_block_biosparam(get_capacity(bdev->bd_disk),<br />+ &geo->cylinders, &geo->heads, &geo->sectors);<br />+ return 0;<br />+}<br />+<br /> /**<br /> * i2o_block_ioctl - Issue device specific ioctl calls.<br /> * @cmd: ioctl command<br />@@ -674,7 +681,6 @@<br /> {<br /> struct gendisk *disk = inode->i_bdev->bd_disk;<br /> struct i2o_block_device *dev = disk->private_data;<br />- void __user *argp = (void __user *)arg;<br /> <br /> /* Anyone capable of this syscall can do *real bad* things */<br /> <br />@@ -682,15 +688,6 @@<br /> return -EPERM;<br /> <br /> switch (cmd) {<br />- case HDIO_GETGEO:<br />- {<br />- struct hd_geometry g;<br />- i2o_block_biosparam(get_capacity(disk),<br />- &g.cylinders, &g.heads, &g.sectors);<br />- g.start = get_start_sect(inode->i_bdev);<br />- return copy_to_user(argp, &g, sizeof(g)) ? -EFAULT : 0;<br />- }<br />-<br /> case BLKI2OGRSTRAT:<br /> return put_user(dev->rcache, (int __user *)arg);<br /> case BLKI2OGWSTRAT:<br />@@ -959,6 +956,7 @@<br /> .open = i2o_block_open,<br /> .release = i2o_block_release,<br /> .ioctl = i2o_block_ioctl,<br />+ .getgeo = i2o_block_getgeo,<br /> .media_changed = i2o_block_media_changed<br /> };<br /> <br />Index: linux-2.6/drivers/mmc/mmc_block.c<br />===================================================================<br />--- linux-2.6.orig/drivers/mmc/mmc_block.c 2005-11-19 19:51:41.000000000 +0100<br />+++ linux-2.6/drivers/mmc/mmc_block.c 2005-11-19 19:52:07.000000000 +0100<br />@@ -119,31 +119,18 @@<br /> }<br /> <br /> static int<br />-mmc_blk_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)<br />+mmc_blk_getgeo(struct block_device *bdev, struct hd_geometry *geo)<br /> {<br />- struct block_device *bdev = inode->i_bdev;<br />-<br />- if (cmd == HDIO_GETGEO) {<br />- struct hd_geometry geo;<br />-<br />- memset(&geo, 0, sizeof(struct hd_geometry));<br />-<br />- geo.cylinders = get_capacity(bdev->bd_disk) / (4 * 16);<br />- geo.heads = 4;<br />- geo.sectors = 16;<br />- geo.start = get_start_sect(bdev);<br />-<br />- return copy_to_user((void __user *)arg, &geo, sizeof(geo))<br />- ? -EFAULT : 0;<br />- }<br />-<br />- return -ENOTTY;<br />+ geo->cylinders = get_capacity(bdev->bd_disk) / (4 * 16);<br />+ geo->heads = 4;<br />+ geo->sectors = 16;<br />+ return 0;<br /> }<br /> <br /> static struct block_device_operations mmc_bdops = {<br /> .open = mmc_blk_open,<br /> .release = mmc_blk_release,<br />- .ioctl = mmc_blk_ioctl,<br />+ .getgeo = mmc_blk_getgeo,<br /> .owner = THIS_MODULE,<br /> };<br /> <br />Index: linux-2.6/drivers/mtd/mtd_blkdevs.c<br />===================================================================<br />--- linux-2.6.orig/drivers/mtd/mtd_blkdevs.c 2005-11-19 19:51:41.000000000 +0100<br />+++ linux-2.6/drivers/mtd/mtd_blkdevs.c 2005-11-19 20:32:25.000000000 +0100<br />@@ -194,6 +194,14 @@<br /> return ret;<br /> }<br /> <br />+static int blktrans_getgeo(struct block_device *bdev, struct hd_geometry *geo)<br />+{<br />+ struct mtd_blktrans_dev *dev = bdev->bd_disk->private_data;<br />+<br />+ if (dev->tr->getgeo)<br />+ return dev->tr->getgeo(dev, geo);<br />+ return -ENOTTY;<br />+}<br /> <br /> static int blktrans_ioctl(struct inode *inode, struct file *file,<br /> unsigned int cmd, unsigned long arg)<br />@@ -207,22 +215,6 @@<br /> return tr->flush(dev);<br /> /* The core code did the work, we had nothing to do. */<br /> return 0;<br />-<br />- case HDIO_GETGEO:<br />- if (tr->getgeo) {<br />- struct hd_geometry g;<br />- int ret;<br />-<br />- memset(&g, 0, sizeof(g));<br />- ret = tr->getgeo(dev, &g);<br />- if (ret)<br />- return ret;<br />-<br />- g.start = get_start_sect(inode->i_bdev);<br />- if (copy_to_user((void __user *)arg, &g, sizeof(g)))<br />- return -EFAULT;<br />- return 0;<br />- } /* else */<br /> default:<br /> return -ENOTTY;<br /> }<br />@@ -233,6 +225,7 @@<br /> .open = blktrans_open,<br /> .release = blktrans_release,<br /> .ioctl = blktrans_ioctl,<br />+ .getgeo = blktrans_getgeo,<br /> };<br /> <br /> int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new)<br />Index: linux-2.6/drivers/s390/block/dasd.c<br />===================================================================<br />--- linux-2.6.orig/drivers/s390/block/dasd.c 2005-11-19 19:51:41.000000000 +0100<br />+++ linux-2.6/drivers/s390/block/dasd.c 2005-11-19 19:52:07.000000000 +0100<br />@@ -18,6 +18,7 @@<br /> #include <linux/major.h><br /> #include <linux/slab.h><br /> #include <linux/buffer_head.h><br />+#include <linux/hdreg.h><br /> <br /> #include <asm/ccwdev.h><br /> #include <asm/ebcdic.h><br />@@ -1717,12 +1718,34 @@<br /> return 0;<br /> }<br /> <br />+/*<br />+ * Return disk geometry.<br />+ */<br />+static int<br />+dasd_getgeo(struct block_device *bdev, struct hd_geometry *geo)<br />+{<br />+ struct dasd_device *device;<br />+<br />+ device = bdev->bd_disk->private_data;<br />+ if (!device)<br />+ return -ENODEV;<br />+<br />+ if (!device->discipline ||<br />+ !device->discipline->fill_geometry)<br />+ return -EINVAL;<br />+<br />+ device->discipline->fill_geometry(device, geo);<br />+ geo->start = get_start_sect(bdev) >> device->s2b_shift;<br />+ return 0;<br />+}<br />+<br /> struct block_device_operations<br /> dasd_device_operations = {<br /> .owner = THIS_MODULE,<br /> .open = dasd_open,<br /> .release = dasd_release,<br /> .ioctl = dasd_ioctl,<br />+ .getgeo = dasd_getgeo,<br /> };<br /> <br /> <br />Index: linux-2.6/drivers/s390/block/dasd_ioctl.c<br />===================================================================<br />--- linux-2.6.orig/drivers/s390/block/dasd_ioctl.c 2005-11-19 19:51:41.000000000 +0100<br />+++ linux-2.6/drivers/s390/block/dasd_ioctl.c 2005-11-19 19:52:07.000000000 +0100<br />@@ -483,33 +483,6 @@<br /> }<br /> <br /> /*<br />- * Return disk geometry.<br />- */<br />-static int<br />-dasd_ioctl_getgeo(struct block_device *bdev, int no, long args)<br />-{<br />- struct hd_geometry geo = { 0, };<br />- struct dasd_device *device;<br />-<br />- device = bdev->bd_disk->private_data;<br />- if (device == NULL)<br />- return -ENODEV;<br />-<br />- if (device == NULL || device->discipline == NULL ||<br />- device->discipline->fill_geometry == NULL)<br />- return -EINVAL;<br />-<br />- geo = (struct hd_geometry) {};<br />- device->discipline->fill_geometry(device, &geo);<br />- geo.start = get_start_sect(bdev) >> device->s2b_shift;<br />- if (copy_to_user((struct hd_geometry __user *) args, &geo,<br />- sizeof (struct hd_geometry)))<br />- return -EFAULT;<br />-<br />- return 0;<br />-}<br />-<br />-/*<br /> * List of static ioctls.<br /> */<br /> static struct { int no; dasd_ioctl_fn_t fn; } dasd_ioctls[] =<br />@@ -525,7 +498,6 @@<br /> { BIODASDPRRST, dasd_ioctl_reset_profile },<br /> { BLKROSET, dasd_ioctl_set_ro },<br /> { DASDAPIVER, dasd_ioctl_api_version },<br />- { HDIO_GETGEO, dasd_ioctl_getgeo },<br /> { -1, NULL }<br /> };<br /> <br />Index: linux-2.6/drivers/s390/block/xpram.c<br />===================================================================<br />--- linux-2.6.orig/drivers/s390/block/xpram.c 2005-11-19 19:51:41.000000000 +0100<br />+++ linux-2.6/drivers/s390/block/xpram.c 2005-11-19 19:52:07.000000000 +0100<br />@@ -328,31 +328,27 @@<br /> return 0;<br /> }<br /> <br />-static int xpram_ioctl (struct inode *inode, struct file *filp,<br />- unsigned int cmd, unsigned long arg)<br />+static int xpram_getgeo(struct block_device *bdev, struct hd_geometry *geo)<br /> {<br />- struct hd_geometry __user *geo;<br /> unsigned long size;<br />- if (cmd != HDIO_GETGEO)<br />- return -EINVAL;<br />+<br /> /*<br /> * get geometry: we have to fake one... trim the size to a<br /> * multiple of 64 (32k): tell we have 16 sectors, 4 heads,<br /> * whatever cylinders. Tell also that data starts at sector. 4.<br /> */<br />- geo = (struct hd_geometry __user *) arg;<br /> size = (xpram_pages * 8) & ~0x3f;<br />- put_user(size >> 6, &geo->cylinders);<br />- put_user(4, &geo->heads);<br />- put_user(16, &geo->sectors);<br />- put_user(4, &geo->start);<br />+ geo->cylinders = size >> 6;<br />+ geo->heads = 4;<br />+ geo->sectors = 16;<br />+ geo->start = 4;<br /> return 0;<br /> }<br /> <br /> static struct block_device_operations xpram_devops =<br /> {<br /> .owner = THIS_MODULE,<br />- .ioctl = xpram_ioctl,<br />+ .getgeo = xpram_getgeo,<br /> };<br /> <br /> /*<br />Index: linux-2.6/drivers/scsi/sd.c<br />===================================================================<br />--- linux-2.6.orig/drivers/scsi/sd.c 2005-11-19 19:51:41.000000000 +0100<br />+++ linux-2.6/drivers/scsi/sd.c 2005-11-19 19:52:07.000000000 +0100<br />@@ -530,7 +530,7 @@<br /> return 0;<br /> }<br /> <br />-static int sd_hdio_getgeo(struct block_device *bdev, struct hd_geometry __user *loc)<br />+static int sd_getgeo(struct block_device *bdev, struct hd_geometry *geo)<br /> {<br /> struct scsi_disk *sdkp = scsi_disk(bdev->bd_disk);<br /> struct scsi_device *sdp = sdkp->device;<br />@@ -548,15 +548,9 @@<br /> else<br /> scsicam_bios_param(bdev, sdkp->capacity, diskinfo);<br /> <br />- if (put_user(diskinfo[0], &loc->heads))<br />- return -EFAULT;<br />- if (put_user(diskinfo[1], &loc->sectors))<br />- return -EFAULT;<br />- if (put_user(diskinfo[2], &loc->cylinders))<br />- return -EFAULT;<br />- if (put_user((unsigned)get_start_sect(bdev),<br />- (unsigned long __user *)&loc->start))<br />- return -EFAULT;<br />+ geo->heads = diskinfo[0];<br />+ geo->sectors = diskinfo[1];<br />+ geo->cylinders = diskinfo[2];<br /> return 0;<br /> }<br /> <br />@@ -596,12 +590,6 @@<br /> if (!scsi_block_when_processing_errors(sdp) || !error)<br /> return error;<br /> <br />- if (cmd == HDIO_GETGEO) {<br />- if (!arg)<br />- return -EINVAL;<br />- return sd_hdio_getgeo(bdev, p);<br />- }<br />-<br /> /*<br /> * Send SCSI addressing ioctls directly to mid level, send other<br /> * ioctls to block level and then onto mid level if they can't be<br />@@ -832,6 +820,7 @@<br /> .open = sd_open,<br /> .release = sd_release,<br /> .ioctl = sd_ioctl,<br />+ .getgeo = sd_getgeo,<br /> #ifdef CONFIG_COMPAT<br /> .compat_ioctl = sd_compat_ioctl,<br /> #endif<br />Index: linux-2.6/include/linux/fs.h<br />===================================================================<br />--- linux-2.6.orig/include/linux/fs.h 2005-11-19 19:51:58.000000000 +0100<br />+++ linux-2.6/include/linux/fs.h 2005-11-19 19:52:07.000000000 +0100<br />@@ -225,6 +225,7 @@<br /> #include <asm/semaphore.h><br /> #include <asm/byteorder.h><br /> <br />+struct hd_geometry;<br /> struct iovec;<br /> struct nameidata;<br /> struct kiocb;<br />@@ -932,6 +933,7 @@<br /> int (*direct_access) (struct block_device *, sector_t, unsigned long *);<br /> int (*media_changed) (struct gendisk *);<br /> int (*revalidate_disk) (struct gendisk *);<br />+ int (*getgeo)(struct block_device *, struct hd_geometry *);<br /> struct module *owner;<br /> };<br /> <br />-<br />To unsubscribe from this list: send the line "unsubscribe linux-kernel" in<br />the body of a message to majordomo@vger.kernel.org<br />More majordomo info at <a href="http://vger.kernel.org/majordomo-info.html">http://vger.kernel.org/majordomo-info.html</a><br />Please read the FAQ at <a href="http://www.tux.org/lkml/">http://www.tux.org/lkml/</a><br /></pre></td><td width="32" rowspan="2" class="c" valign="top"><img src="/images/icornerr.gif" width="32" height="32" alt="\" /></td></tr><tr><td align="right" valign="bottom"> 聽 </td></tr><tr><td align="right" valign="bottom">聽</td><td class="c" valign="bottom" style="padding-bottom: 0px"><img src="/images/bcornerl.gif" width="32" height="32" alt="\" /></td><td class="c">聽</td><td class="c" valign="bottom" style="padding-bottom: 0px"><img src="/images/bcornerr.gif" width="32" height="32" alt="/" /></td></tr><tr><td align="right" valign="top" colspan="2"> 聽 </td><td class="lm">Last update: 2005-11-19 21:50 聽聽 [from the cache]<br />漏2003-2020 <a href="http://blog.jasper.es/"><span itemprop="editor">Jasper Spaans</span></a>|hosted at <a href="https://www.digitalocean.com/?refcode=9a8e99d24cf9">Digital Ocean</a> and my Meterkast|<a href="http://blog.jasper.es/categories.html#lkml-ref">Read the blog</a></td><td>聽</td></tr></table><script language="javascript" src="/js/styleswitcher.js" type="text/javascript"></script></body></html>