aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ide/ide-disk.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ide/ide-disk.c')
-rw-r--r--drivers/ide/ide-disk.c81
1 files changed, 68 insertions, 13 deletions
diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c
index e7bc4d35c40c..fb162cb3ebf5 100644
--- a/drivers/ide/ide-disk.c
+++ b/drivers/ide/ide-disk.c
@@ -737,6 +737,9 @@ static int set_multcount(ide_drive_t *drive, int arg)
737{ 737{
738 struct request rq; 738 struct request rq;
739 739
740 if (arg < 0 || arg > drive->id->max_multsect)
741 return -EINVAL;
742
740 if (drive->special.b.set_multmode) 743 if (drive->special.b.set_multmode)
741 return -EBUSY; 744 return -EBUSY;
742 ide_init_drive_cmd (&rq); 745 ide_init_drive_cmd (&rq);
@@ -749,6 +752,9 @@ static int set_multcount(ide_drive_t *drive, int arg)
749 752
750static int set_nowerr(ide_drive_t *drive, int arg) 753static int set_nowerr(ide_drive_t *drive, int arg)
751{ 754{
755 if (arg < 0 || arg > 1)
756 return -EINVAL;
757
752 if (ide_spin_wait_hwgroup(drive)) 758 if (ide_spin_wait_hwgroup(drive))
753 return -EBUSY; 759 return -EBUSY;
754 drive->nowerr = arg; 760 drive->nowerr = arg;
@@ -800,6 +806,9 @@ static int write_cache(ide_drive_t *drive, int arg)
800 ide_task_t args; 806 ide_task_t args;
801 int err = 1; 807 int err = 1;
802 808
809 if (arg < 0 || arg > 1)
810 return -EINVAL;
811
803 if (ide_id_has_flush_cache(drive->id)) { 812 if (ide_id_has_flush_cache(drive->id)) {
804 memset(&args, 0, sizeof(ide_task_t)); 813 memset(&args, 0, sizeof(ide_task_t));
805 args.tfRegister[IDE_FEATURE_OFFSET] = (arg) ? 814 args.tfRegister[IDE_FEATURE_OFFSET] = (arg) ?
@@ -835,6 +844,9 @@ static int set_acoustic (ide_drive_t *drive, int arg)
835{ 844{
836 ide_task_t args; 845 ide_task_t args;
837 846
847 if (arg < 0 || arg > 254)
848 return -EINVAL;
849
838 memset(&args, 0, sizeof(ide_task_t)); 850 memset(&args, 0, sizeof(ide_task_t));
839 args.tfRegister[IDE_FEATURE_OFFSET] = (arg) ? SETFEATURES_EN_AAM : 851 args.tfRegister[IDE_FEATURE_OFFSET] = (arg) ? SETFEATURES_EN_AAM :
840 SETFEATURES_DIS_AAM; 852 SETFEATURES_DIS_AAM;
@@ -855,6 +867,9 @@ static int set_acoustic (ide_drive_t *drive, int arg)
855 */ 867 */
856static int set_lba_addressing(ide_drive_t *drive, int arg) 868static int set_lba_addressing(ide_drive_t *drive, int arg)
857{ 869{
870 if (arg < 0 || arg > 2)
871 return -EINVAL;
872
858 drive->addressing = 0; 873 drive->addressing = 0;
859 874
860 if (HWIF(drive)->no_lba48) 875 if (HWIF(drive)->no_lba48)
@@ -870,18 +885,18 @@ static void idedisk_add_settings(ide_drive_t *drive)
870{ 885{
871 struct hd_driveid *id = drive->id; 886 struct hd_driveid *id = drive->id;
872 887
873 ide_add_setting(drive, "bios_cyl", SETTING_RW, -1, -1, TYPE_INT, 0, 65535, 1, 1, &drive->bios_cyl, NULL); 888 ide_add_setting(drive, "bios_cyl", SETTING_RW, TYPE_INT, 0, 65535, 1, 1, &drive->bios_cyl, NULL);
874 ide_add_setting(drive, "bios_head", SETTING_RW, -1, -1, TYPE_BYTE, 0, 255, 1, 1, &drive->bios_head, NULL); 889 ide_add_setting(drive, "bios_head", SETTING_RW, TYPE_BYTE, 0, 255, 1, 1, &drive->bios_head, NULL);
875 ide_add_setting(drive, "bios_sect", SETTING_RW, -1, -1, TYPE_BYTE, 0, 63, 1, 1, &drive->bios_sect, NULL); 890 ide_add_setting(drive, "bios_sect", SETTING_RW, TYPE_BYTE, 0, 63, 1, 1, &drive->bios_sect, NULL);
876 ide_add_setting(drive, "address", SETTING_RW, HDIO_GET_ADDRESS, HDIO_SET_ADDRESS, TYPE_INTA, 0, 2, 1, 1, &drive->addressing, set_lba_addressing); 891 ide_add_setting(drive, "address", SETTING_RW, TYPE_BYTE, 0, 2, 1, 1, &drive->addressing, set_lba_addressing);
877 ide_add_setting(drive, "bswap", SETTING_READ, -1, -1, TYPE_BYTE, 0, 1, 1, 1, &drive->bswap, NULL); 892 ide_add_setting(drive, "bswap", SETTING_READ, TYPE_BYTE, 0, 1, 1, 1, &drive->bswap, NULL);
878 ide_add_setting(drive, "multcount", id ? SETTING_RW : SETTING_READ, HDIO_GET_MULTCOUNT, HDIO_SET_MULTCOUNT, TYPE_BYTE, 0, id ? id->max_multsect : 0, 1, 1, &drive->mult_count, set_multcount); 893 ide_add_setting(drive, "multcount", SETTING_RW, TYPE_BYTE, 0, id->max_multsect, 1, 1, &drive->mult_count, set_multcount);
879 ide_add_setting(drive, "nowerr", SETTING_RW, HDIO_GET_NOWERR, HDIO_SET_NOWERR, TYPE_BYTE, 0, 1, 1, 1, &drive->nowerr, set_nowerr); 894 ide_add_setting(drive, "nowerr", SETTING_RW, TYPE_BYTE, 0, 1, 1, 1, &drive->nowerr, set_nowerr);
880 ide_add_setting(drive, "lun", SETTING_RW, -1, -1, TYPE_INT, 0, 7, 1, 1, &drive->lun, NULL); 895 ide_add_setting(drive, "lun", SETTING_RW, TYPE_INT, 0, 7, 1, 1, &drive->lun, NULL);
881 ide_add_setting(drive, "wcache", SETTING_RW, HDIO_GET_WCACHE, HDIO_SET_WCACHE, TYPE_BYTE, 0, 1, 1, 1, &drive->wcache, write_cache); 896 ide_add_setting(drive, "wcache", SETTING_RW, TYPE_BYTE, 0, 1, 1, 1, &drive->wcache, write_cache);
882 ide_add_setting(drive, "acoustic", SETTING_RW, HDIO_GET_ACOUSTIC, HDIO_SET_ACOUSTIC, TYPE_BYTE, 0, 254, 1, 1, &drive->acoustic, set_acoustic); 897 ide_add_setting(drive, "acoustic", SETTING_RW, TYPE_BYTE, 0, 254, 1, 1, &drive->acoustic, set_acoustic);
883 ide_add_setting(drive, "failures", SETTING_RW, -1, -1, TYPE_INT, 0, 65535, 1, 1, &drive->failures, NULL); 898 ide_add_setting(drive, "failures", SETTING_RW, TYPE_INT, 0, 65535, 1, 1, &drive->failures, NULL);
884 ide_add_setting(drive, "max_failures", SETTING_RW, -1, -1, TYPE_INT, 0, 65535, 1, 1, &drive->max_failures, NULL); 899 ide_add_setting(drive, "max_failures", SETTING_RW, TYPE_INT, 0, 65535, 1, 1, &drive->max_failures, NULL);
885} 900}
886 901
887static void idedisk_setup (ide_drive_t *drive) 902static void idedisk_setup (ide_drive_t *drive)
@@ -1140,9 +1155,49 @@ static int idedisk_getgeo(struct block_device *bdev, struct hd_geometry *geo)
1140static int idedisk_ioctl(struct inode *inode, struct file *file, 1155static int idedisk_ioctl(struct inode *inode, struct file *file,
1141 unsigned int cmd, unsigned long arg) 1156 unsigned int cmd, unsigned long arg)
1142{ 1157{
1158 unsigned long flags;
1143 struct block_device *bdev = inode->i_bdev; 1159 struct block_device *bdev = inode->i_bdev;
1144 struct ide_disk_obj *idkp = ide_disk_g(bdev->bd_disk); 1160 struct ide_disk_obj *idkp = ide_disk_g(bdev->bd_disk);
1145 return generic_ide_ioctl(idkp->drive, file, bdev, cmd, arg); 1161 ide_drive_t *drive = idkp->drive;
1162 int err, (*setfunc)(ide_drive_t *, int);
1163 u8 *val;
1164
1165 switch (cmd) {
1166 case HDIO_GET_ADDRESS: val = &drive->addressing; goto read_val;
1167 case HDIO_GET_MULTCOUNT: val = &drive->mult_count; goto read_val;
1168 case HDIO_GET_NOWERR: val = &drive->nowerr; goto read_val;
1169 case HDIO_GET_WCACHE: val = &drive->wcache; goto read_val;
1170 case HDIO_GET_ACOUSTIC: val = &drive->acoustic; goto read_val;
1171 case HDIO_SET_ADDRESS: setfunc = set_lba_addressing; goto set_val;
1172 case HDIO_SET_MULTCOUNT: setfunc = set_multcount; goto set_val;
1173 case HDIO_SET_NOWERR: setfunc = set_nowerr; goto set_val;
1174 case HDIO_SET_WCACHE: setfunc = write_cache; goto set_val;
1175 case HDIO_SET_ACOUSTIC: setfunc = set_acoustic; goto set_val;
1176 }
1177
1178 return generic_ide_ioctl(drive, file, bdev, cmd, arg);
1179
1180read_val:
1181 down(&ide_setting_sem);
1182 spin_lock_irqsave(&ide_lock, flags);
1183 err = *val;
1184 spin_unlock_irqrestore(&ide_lock, flags);
1185 up(&ide_setting_sem);
1186 return err >= 0 ? put_user(err, (long __user *)arg) : err;
1187
1188set_val:
1189 if (bdev != bdev->bd_contains)
1190 err = -EINVAL;
1191 else {
1192 if (!capable(CAP_SYS_ADMIN))
1193 err = -EACCES;
1194 else {
1195 down(&ide_setting_sem);
1196 err = setfunc(drive, arg);
1197 up(&ide_setting_sem);
1198 }
1199 }
1200 return err;
1146} 1201}
1147 1202
1148static int idedisk_media_changed(struct gendisk *disk) 1203static int idedisk_media_changed(struct gendisk *disk)