aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block/paride/pf.c
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/pf.c
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/pf.c')
-rw-r--r--drivers/block/paride/pf.c50
1 files changed, 26 insertions, 24 deletions
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