aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block/paride
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2006-01-08 04:02:50 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2006-01-08 23:13:54 -0500
commita885c8c4316e1c1d2d2c8755da3f3d14f852528d (patch)
treee4f4e7a7657c0944d11c259f8f17ffcd6b2da0f5 /drivers/block/paride
parent5b0ed2c64d8fdafb5fcfb3baabdd288628b1ff9b (diff)
[PATCH] Add block_device_operations.getgeo block device method
HDIO_GETGEO is implemented in most block drivers, and all of them have to duplicate the code to copy the structure to userspace, as well as getting the start sector. This patch moves that to common code [1] and adds a ->getgeo method to fill out the raw kernel hd_geometry structure. For many drivers this means ->ioctl can go away now. [1] the s390 block drivers are odd in this respect. xpram sets ->start to 4 always which seems more than odd, and the dasd driver shifts the start offset around, probably because of it's non-standard sector size. Signed-off-by: Christoph Hellwig <hch@lst.de> Cc: Jens Axboe <axboe@suse.de> Cc: <mike.miller@hp.com> Cc: Jeff Dike <jdike@addtoit.com> Cc: Paolo Giarrusso <blaisorblade@yahoo.it> Cc: Bartlomiej Zolnierkiewicz <B.Zolnierkiewicz@elka.pw.edu.pl> Cc: Neil Brown <neilb@cse.unsw.edu.au> Cc: Markus Lidel <Markus.Lidel@shadowconnect.com> Cc: Russell King <rmk@arm.linux.org.uk> Cc: David Woodhouse <dwmw2@infradead.org> Cc: Martin Schwidefsky <schwidefsky@de.ibm.com> Cc: James Bottomley <James.Bottomley@steeleye.com> Signed-off-by: Adrian Bunk <bunk@stusta.de> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/block/paride')
-rw-r--r--drivers/block/paride/pd.c34
-rw-r--r--drivers/block/paride/pf.c50
2 files changed, 44 insertions, 40 deletions
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