diff options
author | Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> | 2008-10-10 16:39:33 -0400 |
---|---|---|
committer | Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> | 2008-10-10 16:39:33 -0400 |
commit | aa7687738af3332470e02ac1060f6c046d83c9a3 (patch) | |
tree | 2eb2cd89de0b8dcad12534e28a9178d0325ae491 | |
parent | 9232c14bff36d65de254f34386c00b732c5b6099 (diff) |
ide: add ide_setting_ioctl() helper
* Add struct ide_ioctl_devset representing ioctl device setting.
* Add ide_setting_ioctl() helper for matching given ioctl
and its parameters against table of ioctl device settings.
* Convert ide_setting_ioctl() and idedisk_ioctl() to use
ide_setting_ioctl().
* Un-export ide_setting_mtx.
While at it:
* {get,set}_lba_addressing() -> {get,set}_addressing()
There should be no functional changes caused by this patch.
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
-rw-r--r-- | drivers/ide/ide-disk.c | 59 | ||||
-rw-r--r-- | drivers/ide/ide.c | 53 | ||||
-rw-r--r-- | include/linux/ide.h | 14 |
3 files changed, 65 insertions, 61 deletions
diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c index 43025c9d8355..119063470820 100644 --- a/drivers/ide/ide-disk.c +++ b/drivers/ide/ide-disk.c | |||
@@ -676,7 +676,7 @@ static int set_acoustic(ide_drive_t *drive, int arg) | |||
676 | return 0; | 676 | return 0; |
677 | } | 677 | } |
678 | 678 | ||
679 | ide_devset_get(lba_addressing, addressing); | 679 | ide_devset_get(addressing, addressing); |
680 | 680 | ||
681 | /* | 681 | /* |
682 | * drive->addressing: | 682 | * drive->addressing: |
@@ -684,7 +684,7 @@ ide_devset_get(lba_addressing, addressing); | |||
684 | * 1: 48-bit | 684 | * 1: 48-bit |
685 | * 2: 48-bit capable doing 28-bit | 685 | * 2: 48-bit capable doing 28-bit |
686 | */ | 686 | */ |
687 | static int set_lba_addressing(ide_drive_t *drive, int arg) | 687 | static int set_addressing(ide_drive_t *drive, int arg) |
688 | { | 688 | { |
689 | if (arg < 0 || arg > 2) | 689 | if (arg < 0 || arg > 2) |
690 | return -EINVAL; | 690 | return -EINVAL; |
@@ -704,7 +704,7 @@ static int set_lba_addressing(ide_drive_t *drive, int arg) | |||
704 | 704 | ||
705 | #ifdef CONFIG_IDE_PROC_FS | 705 | #ifdef CONFIG_IDE_PROC_FS |
706 | ide_devset_rw_nolock(acoustic, 0, 254, acoustic); | 706 | ide_devset_rw_nolock(acoustic, 0, 254, acoustic); |
707 | ide_devset_rw_nolock(address, 0, 2, lba_addressing); | 707 | ide_devset_rw_nolock(address, 0, 2, addressing); |
708 | ide_devset_rw_nolock(multcount, 0, 16, multcount); | 708 | ide_devset_rw_nolock(multcount, 0, 16, multcount); |
709 | ide_devset_rw_nolock(nowerr, 0, 1, nowerr); | 709 | ide_devset_rw_nolock(nowerr, 0, 1, nowerr); |
710 | ide_devset_rw_nolock(wcache, 0, 1, wcache); | 710 | ide_devset_rw_nolock(wcache, 0, 1, wcache); |
@@ -753,7 +753,7 @@ static void idedisk_setup(ide_drive_t *drive) | |||
753 | drive->doorlocking = 1; | 753 | drive->doorlocking = 1; |
754 | } | 754 | } |
755 | 755 | ||
756 | (void)set_lba_addressing(drive, 1); | 756 | (void)set_addressing(drive, 1); |
757 | 757 | ||
758 | if (drive->addressing == 1) { | 758 | if (drive->addressing == 1) { |
759 | int max_s = 2048; | 759 | int max_s = 2048; |
@@ -1000,51 +1000,28 @@ static int idedisk_getgeo(struct block_device *bdev, struct hd_geometry *geo) | |||
1000 | return 0; | 1000 | return 0; |
1001 | } | 1001 | } |
1002 | 1002 | ||
1003 | static const struct ide_ioctl_devset ide_disk_ioctl_settings[] = { | ||
1004 | { HDIO_GET_ADDRESS, HDIO_SET_ADDRESS, get_addressing, set_addressing }, | ||
1005 | { HDIO_GET_MULTCOUNT, HDIO_SET_MULTCOUNT, get_multcount, set_multcount }, | ||
1006 | { HDIO_GET_NOWERR, HDIO_SET_NOWERR, get_nowerr, set_nowerr }, | ||
1007 | { HDIO_GET_WCACHE, HDIO_SET_WCACHE, get_wcache, set_wcache }, | ||
1008 | { HDIO_GET_ACOUSTIC, HDIO_SET_ACOUSTIC, get_acoustic, set_acoustic }, | ||
1009 | { 0 } | ||
1010 | }; | ||
1011 | |||
1003 | static int idedisk_ioctl(struct inode *inode, struct file *file, | 1012 | static int idedisk_ioctl(struct inode *inode, struct file *file, |
1004 | unsigned int cmd, unsigned long arg) | 1013 | unsigned int cmd, unsigned long arg) |
1005 | { | 1014 | { |
1006 | unsigned long flags; | ||
1007 | struct block_device *bdev = inode->i_bdev; | 1015 | struct block_device *bdev = inode->i_bdev; |
1008 | struct ide_disk_obj *idkp = ide_disk_g(bdev->bd_disk); | 1016 | struct ide_disk_obj *idkp = ide_disk_g(bdev->bd_disk); |
1009 | ide_drive_t *drive = idkp->drive; | 1017 | ide_drive_t *drive = idkp->drive; |
1010 | int err, (*getfunc)(ide_drive_t *), (*setfunc)(ide_drive_t *, int); | 1018 | int err; |
1011 | |||
1012 | switch (cmd) { | ||
1013 | case HDIO_GET_ADDRESS: getfunc = get_lba_addressing; goto read_val; | ||
1014 | case HDIO_GET_MULTCOUNT: getfunc = get_multcount; goto read_val; | ||
1015 | case HDIO_GET_NOWERR: getfunc = get_nowerr; goto read_val; | ||
1016 | case HDIO_GET_WCACHE: getfunc = get_wcache; goto read_val; | ||
1017 | case HDIO_GET_ACOUSTIC: getfunc = get_acoustic; goto read_val; | ||
1018 | case HDIO_SET_ADDRESS: setfunc = set_lba_addressing; goto set_val; | ||
1019 | case HDIO_SET_MULTCOUNT: setfunc = set_multcount; goto set_val; | ||
1020 | case HDIO_SET_NOWERR: setfunc = set_nowerr; goto set_val; | ||
1021 | case HDIO_SET_WCACHE: setfunc = set_wcache; goto set_val; | ||
1022 | case HDIO_SET_ACOUSTIC: setfunc = set_acoustic; goto set_val; | ||
1023 | } | ||
1024 | 1019 | ||
1025 | return generic_ide_ioctl(drive, file, bdev, cmd, arg); | 1020 | err = ide_setting_ioctl(drive, bdev, cmd, arg, ide_disk_ioctl_settings); |
1021 | if (err != -EOPNOTSUPP) | ||
1022 | return err; | ||
1026 | 1023 | ||
1027 | read_val: | 1024 | return generic_ide_ioctl(drive, file, bdev, cmd, arg); |
1028 | mutex_lock(&ide_setting_mtx); | ||
1029 | spin_lock_irqsave(&ide_lock, flags); | ||
1030 | err = getfunc(drive); | ||
1031 | spin_unlock_irqrestore(&ide_lock, flags); | ||
1032 | mutex_unlock(&ide_setting_mtx); | ||
1033 | return err >= 0 ? put_user(err, (long __user *)arg) : err; | ||
1034 | |||
1035 | set_val: | ||
1036 | if (bdev != bdev->bd_contains) | ||
1037 | err = -EINVAL; | ||
1038 | else { | ||
1039 | if (!capable(CAP_SYS_ADMIN)) | ||
1040 | err = -EACCES; | ||
1041 | else { | ||
1042 | mutex_lock(&ide_setting_mtx); | ||
1043 | err = setfunc(drive, arg); | ||
1044 | mutex_unlock(&ide_setting_mtx); | ||
1045 | } | ||
1046 | } | ||
1047 | return err; | ||
1048 | } | 1025 | } |
1049 | 1026 | ||
1050 | static int idedisk_media_changed(struct gendisk *disk) | 1027 | static int idedisk_media_changed(struct gendisk *disk) |
diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index f78e789ea5f7..4910924abeb7 100644 --- a/drivers/ide/ide.c +++ b/drivers/ide/ide.c | |||
@@ -250,8 +250,6 @@ void ide_init_port_hw(ide_hwif_t *hwif, hw_regs_t *hw) | |||
250 | 250 | ||
251 | DEFINE_MUTEX(ide_setting_mtx); | 251 | DEFINE_MUTEX(ide_setting_mtx); |
252 | 252 | ||
253 | EXPORT_SYMBOL_GPL(ide_setting_mtx); | ||
254 | |||
255 | /** | 253 | /** |
256 | * ide_spin_wait_hwgroup - wait for group | 254 | * ide_spin_wait_hwgroup - wait for group |
257 | * @drive: drive in the group | 255 | * @drive: drive in the group |
@@ -558,23 +556,23 @@ static int ide_set_nice_ioctl(ide_drive_t *drive, unsigned long arg) | |||
558 | return 0; | 556 | return 0; |
559 | } | 557 | } |
560 | 558 | ||
559 | static const struct ide_ioctl_devset ide_ioctl_settings[] = { | ||
560 | { HDIO_GET_32BIT, HDIO_SET_32BIT, get_io_32bit, set_io_32bit }, | ||
561 | { HDIO_GET_KEEPSETTINGS, HDIO_SET_KEEPSETTINGS, get_ksettings, set_ksettings }, | ||
562 | { HDIO_GET_UNMASKINTR, HDIO_SET_UNMASKINTR, get_unmaskirq, set_unmaskirq }, | ||
563 | { HDIO_GET_DMA, HDIO_SET_DMA, get_using_dma, set_using_dma }, | ||
564 | { -1, HDIO_SET_PIO_MODE, NULL, set_pio_mode }, | ||
565 | { 0 } | ||
566 | }; | ||
567 | |||
561 | int generic_ide_ioctl(ide_drive_t *drive, struct file *file, struct block_device *bdev, | 568 | int generic_ide_ioctl(ide_drive_t *drive, struct file *file, struct block_device *bdev, |
562 | unsigned int cmd, unsigned long arg) | 569 | unsigned int cmd, unsigned long arg) |
563 | { | 570 | { |
564 | unsigned long flags; | 571 | int err; |
565 | int err = 0, (*getfunc)(ide_drive_t *), (*setfunc)(ide_drive_t *, int); | ||
566 | 572 | ||
567 | switch (cmd) { | 573 | err = ide_setting_ioctl(drive, bdev, cmd, arg, ide_ioctl_settings); |
568 | case HDIO_GET_32BIT: getfunc = get_io_32bit; goto read_val; | 574 | if (err != -EOPNOTSUPP) |
569 | case HDIO_GET_KEEPSETTINGS: getfunc = get_ksettings; goto read_val; | 575 | return err; |
570 | case HDIO_GET_UNMASKINTR: getfunc = get_unmaskirq; goto read_val; | ||
571 | case HDIO_GET_DMA: getfunc = get_using_dma; goto read_val; | ||
572 | case HDIO_SET_32BIT: setfunc = set_io_32bit; goto set_val; | ||
573 | case HDIO_SET_KEEPSETTINGS: setfunc = set_ksettings; goto set_val; | ||
574 | case HDIO_SET_PIO_MODE: setfunc = set_pio_mode; goto set_val; | ||
575 | case HDIO_SET_UNMASKINTR: setfunc = set_unmaskirq; goto set_val; | ||
576 | case HDIO_SET_DMA: setfunc = set_using_dma; goto set_val; | ||
577 | } | ||
578 | 576 | ||
579 | switch (cmd) { | 577 | switch (cmd) { |
580 | case HDIO_OBSOLETE_IDENTITY: | 578 | case HDIO_OBSOLETE_IDENTITY: |
@@ -629,11 +627,29 @@ int generic_ide_ioctl(ide_drive_t *drive, struct file *file, struct block_device | |||
629 | default: | 627 | default: |
630 | return -EINVAL; | 628 | return -EINVAL; |
631 | } | 629 | } |
630 | } | ||
631 | EXPORT_SYMBOL(generic_ide_ioctl); | ||
632 | |||
633 | int ide_setting_ioctl(ide_drive_t *drive, struct block_device *bdev, | ||
634 | unsigned int cmd, unsigned long arg, | ||
635 | const struct ide_ioctl_devset *s) | ||
636 | { | ||
637 | unsigned long flags; | ||
638 | int err = -EOPNOTSUPP; | ||
639 | |||
640 | for (; s->get_ioctl; s++) { | ||
641 | if (s->get && s->get_ioctl == cmd) | ||
642 | goto read_val; | ||
643 | else if (s->set && s->set_ioctl == cmd) | ||
644 | goto set_val; | ||
645 | } | ||
646 | |||
647 | return err; | ||
632 | 648 | ||
633 | read_val: | 649 | read_val: |
634 | mutex_lock(&ide_setting_mtx); | 650 | mutex_lock(&ide_setting_mtx); |
635 | spin_lock_irqsave(&ide_lock, flags); | 651 | spin_lock_irqsave(&ide_lock, flags); |
636 | err = getfunc(drive); | 652 | err = s->get(drive); |
637 | spin_unlock_irqrestore(&ide_lock, flags); | 653 | spin_unlock_irqrestore(&ide_lock, flags); |
638 | mutex_unlock(&ide_setting_mtx); | 654 | mutex_unlock(&ide_setting_mtx); |
639 | return err >= 0 ? put_user(err, (long __user *)arg) : err; | 655 | return err >= 0 ? put_user(err, (long __user *)arg) : err; |
@@ -646,14 +662,13 @@ set_val: | |||
646 | err = -EACCES; | 662 | err = -EACCES; |
647 | else { | 663 | else { |
648 | mutex_lock(&ide_setting_mtx); | 664 | mutex_lock(&ide_setting_mtx); |
649 | err = setfunc(drive, arg); | 665 | err = s->set(drive, arg); |
650 | mutex_unlock(&ide_setting_mtx); | 666 | mutex_unlock(&ide_setting_mtx); |
651 | } | 667 | } |
652 | } | 668 | } |
653 | return err; | 669 | return err; |
654 | } | 670 | } |
655 | 671 | EXPORT_SYMBOL_GPL(ide_setting_ioctl); | |
656 | EXPORT_SYMBOL(generic_ide_ioctl); | ||
657 | 672 | ||
658 | /** | 673 | /** |
659 | * ide_device_get - get an additional reference to a ide_drive_t | 674 | * ide_device_get - get an additional reference to a ide_drive_t |
diff --git a/include/linux/ide.h b/include/linux/ide.h index 42f39781af87..64624b9b645c 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h | |||
@@ -932,7 +932,19 @@ struct ide_driver_s { | |||
932 | int ide_device_get(ide_drive_t *); | 932 | int ide_device_get(ide_drive_t *); |
933 | void ide_device_put(ide_drive_t *); | 933 | void ide_device_put(ide_drive_t *); |
934 | 934 | ||
935 | int generic_ide_ioctl(ide_drive_t *, struct file *, struct block_device *, unsigned, unsigned long); | 935 | struct ide_ioctl_devset { |
936 | unsigned int get_ioctl; | ||
937 | unsigned int set_ioctl; | ||
938 | |||
939 | int (*get)(ide_drive_t *); | ||
940 | int (*set)(ide_drive_t *, int); | ||
941 | }; | ||
942 | |||
943 | int ide_setting_ioctl(ide_drive_t *, struct block_device *, unsigned int, | ||
944 | unsigned long, const struct ide_ioctl_devset *); | ||
945 | |||
946 | int generic_ide_ioctl(ide_drive_t *, struct file *, struct block_device *, | ||
947 | unsigned, unsigned long); | ||
936 | 948 | ||
937 | extern int ide_vlb_clk; | 949 | extern int ide_vlb_clk; |
938 | extern int ide_pci_clk; | 950 | extern int ide_pci_clk; |