diff options
Diffstat (limited to 'drivers/ide/ide.c')
-rw-r--r-- | drivers/ide/ide.c | 470 |
1 files changed, 90 insertions, 380 deletions
diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index ae5bf2be6f52..f2b547ff7722 100644 --- a/drivers/ide/ide.c +++ b/drivers/ide/ide.c | |||
@@ -168,12 +168,11 @@ static const u8 ide_hwif_to_major[] = { IDE0_MAJOR, IDE1_MAJOR, | |||
168 | 168 | ||
169 | static int idebus_parameter; /* holds the "idebus=" parameter */ | 169 | static int idebus_parameter; /* holds the "idebus=" parameter */ |
170 | static int system_bus_speed; /* holds what we think is VESA/PCI bus speed */ | 170 | static int system_bus_speed; /* holds what we think is VESA/PCI bus speed */ |
171 | static int initializing; /* set while initializing built-in drivers */ | ||
172 | 171 | ||
173 | DECLARE_MUTEX(ide_cfg_sem); | 172 | DECLARE_MUTEX(ide_cfg_sem); |
174 | __cacheline_aligned_in_smp DEFINE_SPINLOCK(ide_lock); | 173 | __cacheline_aligned_in_smp DEFINE_SPINLOCK(ide_lock); |
175 | 174 | ||
176 | #ifdef CONFIG_BLK_DEV_IDEPCI | 175 | #ifdef CONFIG_IDEPCI_PCIBUS_ORDER |
177 | static int ide_scan_direction; /* THIS was formerly 2.2.x pci=reverse */ | 176 | static int ide_scan_direction; /* THIS was formerly 2.2.x pci=reverse */ |
178 | #endif | 177 | #endif |
179 | 178 | ||
@@ -216,9 +215,6 @@ static void init_hwif_data(ide_hwif_t *hwif, unsigned int index) | |||
216 | hwif->bus_state = BUSSTATE_ON; | 215 | hwif->bus_state = BUSSTATE_ON; |
217 | 216 | ||
218 | hwif->atapi_dma = 0; /* disable all atapi dma */ | 217 | hwif->atapi_dma = 0; /* disable all atapi dma */ |
219 | hwif->ultra_mask = 0x80; /* disable all ultra */ | ||
220 | hwif->mwdma_mask = 0x80; /* disable all mwdma */ | ||
221 | hwif->swdma_mask = 0x80; /* disable all swdma */ | ||
222 | 218 | ||
223 | init_completion(&hwif->gendev_rel_comp); | 219 | init_completion(&hwif->gendev_rel_comp); |
224 | 220 | ||
@@ -305,9 +301,7 @@ static void __init init_ide_data (void) | |||
305 | #endif | 301 | #endif |
306 | } | 302 | } |
307 | #ifdef CONFIG_IDE_ARM | 303 | #ifdef CONFIG_IDE_ARM |
308 | initializing = 1; | ||
309 | ide_arm_init(); | 304 | ide_arm_init(); |
310 | initializing = 0; | ||
311 | #endif | 305 | #endif |
312 | } | 306 | } |
313 | 307 | ||
@@ -353,10 +347,6 @@ static int ide_system_bus_speed(void) | |||
353 | return system_bus_speed; | 347 | return system_bus_speed; |
354 | } | 348 | } |
355 | 349 | ||
356 | #ifdef CONFIG_PROC_FS | ||
357 | struct proc_dir_entry *proc_ide_root; | ||
358 | #endif | ||
359 | |||
360 | static struct resource* hwif_request_region(ide_hwif_t *hwif, | 350 | static struct resource* hwif_request_region(ide_hwif_t *hwif, |
361 | unsigned long addr, int num) | 351 | unsigned long addr, int num) |
362 | { | 352 | { |
@@ -480,6 +470,7 @@ static void ide_hwif_restore(ide_hwif_t *hwif, ide_hwif_t *tmp_hwif) | |||
480 | 470 | ||
481 | hwif->tuneproc = tmp_hwif->tuneproc; | 471 | hwif->tuneproc = tmp_hwif->tuneproc; |
482 | hwif->speedproc = tmp_hwif->speedproc; | 472 | hwif->speedproc = tmp_hwif->speedproc; |
473 | hwif->udma_filter = tmp_hwif->udma_filter; | ||
483 | hwif->selectproc = tmp_hwif->selectproc; | 474 | hwif->selectproc = tmp_hwif->selectproc; |
484 | hwif->reset_poll = tmp_hwif->reset_poll; | 475 | hwif->reset_poll = tmp_hwif->reset_poll; |
485 | hwif->pre_reset = tmp_hwif->pre_reset; | 476 | hwif->pre_reset = tmp_hwif->pre_reset; |
@@ -599,7 +590,7 @@ void ide_unregister(unsigned int index) | |||
599 | 590 | ||
600 | spin_unlock_irq(&ide_lock); | 591 | spin_unlock_irq(&ide_lock); |
601 | 592 | ||
602 | destroy_proc_ide_interface(hwif); | 593 | ide_proc_unregister_port(hwif); |
603 | 594 | ||
604 | hwgroup = hwif->hwgroup; | 595 | hwgroup = hwif->hwgroup; |
605 | /* | 596 | /* |
@@ -751,6 +742,7 @@ void ide_setup_ports ( hw_regs_t *hw, | |||
751 | /** | 742 | /** |
752 | * ide_register_hw_with_fixup - register IDE interface | 743 | * ide_register_hw_with_fixup - register IDE interface |
753 | * @hw: hardware registers | 744 | * @hw: hardware registers |
745 | * @initializing: set while initializing built-in drivers | ||
754 | * @hwifp: pointer to returned hwif | 746 | * @hwifp: pointer to returned hwif |
755 | * @fixup: fixup function | 747 | * @fixup: fixup function |
756 | * | 748 | * |
@@ -760,7 +752,9 @@ void ide_setup_ports ( hw_regs_t *hw, | |||
760 | * Returns -1 on error. | 752 | * Returns -1 on error. |
761 | */ | 753 | */ |
762 | 754 | ||
763 | int ide_register_hw_with_fixup(hw_regs_t *hw, ide_hwif_t **hwifp, void(*fixup)(ide_hwif_t *hwif)) | 755 | int ide_register_hw_with_fixup(hw_regs_t *hw, int initializing, |
756 | ide_hwif_t **hwifp, | ||
757 | void(*fixup)(ide_hwif_t *hwif)) | ||
764 | { | 758 | { |
765 | int index, retry = 1; | 759 | int index, retry = 1; |
766 | ide_hwif_t *hwif; | 760 | ide_hwif_t *hwif; |
@@ -801,7 +795,7 @@ found: | |||
801 | 795 | ||
802 | if (!initializing) { | 796 | if (!initializing) { |
803 | probe_hwif_init_with_fixup(hwif, fixup); | 797 | probe_hwif_init_with_fixup(hwif, fixup); |
804 | create_proc_ide_interfaces(); | 798 | ide_proc_register_port(hwif); |
805 | } | 799 | } |
806 | 800 | ||
807 | if (hwifp) | 801 | if (hwifp) |
@@ -812,9 +806,9 @@ found: | |||
812 | 806 | ||
813 | EXPORT_SYMBOL(ide_register_hw_with_fixup); | 807 | EXPORT_SYMBOL(ide_register_hw_with_fixup); |
814 | 808 | ||
815 | int ide_register_hw(hw_regs_t *hw, ide_hwif_t **hwifp) | 809 | int ide_register_hw(hw_regs_t *hw, int initializing, ide_hwif_t **hwifp) |
816 | { | 810 | { |
817 | return ide_register_hw_with_fixup(hw, hwifp, NULL); | 811 | return ide_register_hw_with_fixup(hw, initializing, hwifp, NULL); |
818 | } | 812 | } |
819 | 813 | ||
820 | EXPORT_SYMBOL(ide_register_hw); | 814 | EXPORT_SYMBOL(ide_register_hw); |
@@ -825,205 +819,7 @@ EXPORT_SYMBOL(ide_register_hw); | |||
825 | 819 | ||
826 | DECLARE_MUTEX(ide_setting_sem); | 820 | DECLARE_MUTEX(ide_setting_sem); |
827 | 821 | ||
828 | /** | 822 | EXPORT_SYMBOL_GPL(ide_setting_sem); |
829 | * __ide_add_setting - add an ide setting option | ||
830 | * @drive: drive to use | ||
831 | * @name: setting name | ||
832 | * @rw: true if the function is read write | ||
833 | * @read_ioctl: function to call on read | ||
834 | * @write_ioctl: function to call on write | ||
835 | * @data_type: type of data | ||
836 | * @min: range minimum | ||
837 | * @max: range maximum | ||
838 | * @mul_factor: multiplication scale | ||
839 | * @div_factor: divison scale | ||
840 | * @data: private data field | ||
841 | * @set: setting | ||
842 | * @auto_remove: setting auto removal flag | ||
843 | * | ||
844 | * Removes the setting named from the device if it is present. | ||
845 | * The function takes the settings_lock to protect against | ||
846 | * parallel changes. This function must not be called from IRQ | ||
847 | * context. Returns 0 on success or -1 on failure. | ||
848 | * | ||
849 | * BUGS: This code is seriously over-engineered. There is also | ||
850 | * magic about how the driver specific features are setup. If | ||
851 | * a driver is attached we assume the driver settings are auto | ||
852 | * remove. | ||
853 | */ | ||
854 | |||
855 | static int __ide_add_setting(ide_drive_t *drive, const char *name, int rw, int read_ioctl, int write_ioctl, int data_type, int min, int max, int mul_factor, int div_factor, void *data, ide_procset_t *set, int auto_remove) | ||
856 | { | ||
857 | ide_settings_t **p = (ide_settings_t **) &drive->settings, *setting = NULL; | ||
858 | |||
859 | down(&ide_setting_sem); | ||
860 | while ((*p) && strcmp((*p)->name, name) < 0) | ||
861 | p = &((*p)->next); | ||
862 | if ((setting = kzalloc(sizeof(*setting), GFP_KERNEL)) == NULL) | ||
863 | goto abort; | ||
864 | if ((setting->name = kmalloc(strlen(name) + 1, GFP_KERNEL)) == NULL) | ||
865 | goto abort; | ||
866 | strcpy(setting->name, name); | ||
867 | setting->rw = rw; | ||
868 | setting->read_ioctl = read_ioctl; | ||
869 | setting->write_ioctl = write_ioctl; | ||
870 | setting->data_type = data_type; | ||
871 | setting->min = min; | ||
872 | setting->max = max; | ||
873 | setting->mul_factor = mul_factor; | ||
874 | setting->div_factor = div_factor; | ||
875 | setting->data = data; | ||
876 | setting->set = set; | ||
877 | |||
878 | setting->next = *p; | ||
879 | if (auto_remove) | ||
880 | setting->auto_remove = 1; | ||
881 | *p = setting; | ||
882 | up(&ide_setting_sem); | ||
883 | return 0; | ||
884 | abort: | ||
885 | up(&ide_setting_sem); | ||
886 | kfree(setting); | ||
887 | return -1; | ||
888 | } | ||
889 | |||
890 | int ide_add_setting(ide_drive_t *drive, const char *name, int rw, int read_ioctl, int write_ioctl, int data_type, int min, int max, int mul_factor, int div_factor, void *data, ide_procset_t *set) | ||
891 | { | ||
892 | return __ide_add_setting(drive, name, rw, read_ioctl, write_ioctl, data_type, min, max, mul_factor, div_factor, data, set, 1); | ||
893 | } | ||
894 | |||
895 | EXPORT_SYMBOL(ide_add_setting); | ||
896 | |||
897 | /** | ||
898 | * __ide_remove_setting - remove an ide setting option | ||
899 | * @drive: drive to use | ||
900 | * @name: setting name | ||
901 | * | ||
902 | * Removes the setting named from the device if it is present. | ||
903 | * The caller must hold the setting semaphore. | ||
904 | */ | ||
905 | |||
906 | static void __ide_remove_setting (ide_drive_t *drive, char *name) | ||
907 | { | ||
908 | ide_settings_t **p, *setting; | ||
909 | |||
910 | p = (ide_settings_t **) &drive->settings; | ||
911 | |||
912 | while ((*p) && strcmp((*p)->name, name)) | ||
913 | p = &((*p)->next); | ||
914 | if ((setting = (*p)) == NULL) | ||
915 | return; | ||
916 | |||
917 | (*p) = setting->next; | ||
918 | |||
919 | kfree(setting->name); | ||
920 | kfree(setting); | ||
921 | } | ||
922 | |||
923 | /** | ||
924 | * ide_find_setting_by_ioctl - find a drive specific ioctl | ||
925 | * @drive: drive to scan | ||
926 | * @cmd: ioctl command to handle | ||
927 | * | ||
928 | * Scan's the device setting table for a matching entry and returns | ||
929 | * this or NULL if no entry is found. The caller must hold the | ||
930 | * setting semaphore | ||
931 | */ | ||
932 | |||
933 | static ide_settings_t *ide_find_setting_by_ioctl (ide_drive_t *drive, int cmd) | ||
934 | { | ||
935 | ide_settings_t *setting = drive->settings; | ||
936 | |||
937 | while (setting) { | ||
938 | if (setting->read_ioctl == cmd || setting->write_ioctl == cmd) | ||
939 | break; | ||
940 | setting = setting->next; | ||
941 | } | ||
942 | |||
943 | return setting; | ||
944 | } | ||
945 | |||
946 | /** | ||
947 | * ide_find_setting_by_name - find a drive specific setting | ||
948 | * @drive: drive to scan | ||
949 | * @name: setting name | ||
950 | * | ||
951 | * Scan's the device setting table for a matching entry and returns | ||
952 | * this or NULL if no entry is found. The caller must hold the | ||
953 | * setting semaphore | ||
954 | */ | ||
955 | |||
956 | ide_settings_t *ide_find_setting_by_name (ide_drive_t *drive, char *name) | ||
957 | { | ||
958 | ide_settings_t *setting = drive->settings; | ||
959 | |||
960 | while (setting) { | ||
961 | if (strcmp(setting->name, name) == 0) | ||
962 | break; | ||
963 | setting = setting->next; | ||
964 | } | ||
965 | return setting; | ||
966 | } | ||
967 | |||
968 | /** | ||
969 | * auto_remove_settings - remove driver specific settings | ||
970 | * @drive: drive | ||
971 | * | ||
972 | * Automatically remove all the driver specific settings for this | ||
973 | * drive. This function may not be called from IRQ context. The | ||
974 | * caller must hold ide_setting_sem. | ||
975 | */ | ||
976 | |||
977 | static void auto_remove_settings (ide_drive_t *drive) | ||
978 | { | ||
979 | ide_settings_t *setting; | ||
980 | repeat: | ||
981 | setting = drive->settings; | ||
982 | while (setting) { | ||
983 | if (setting->auto_remove) { | ||
984 | __ide_remove_setting(drive, setting->name); | ||
985 | goto repeat; | ||
986 | } | ||
987 | setting = setting->next; | ||
988 | } | ||
989 | } | ||
990 | |||
991 | /** | ||
992 | * ide_read_setting - read an IDE setting | ||
993 | * @drive: drive to read from | ||
994 | * @setting: drive setting | ||
995 | * | ||
996 | * Read a drive setting and return the value. The caller | ||
997 | * must hold the ide_setting_sem when making this call. | ||
998 | * | ||
999 | * BUGS: the data return and error are the same return value | ||
1000 | * so an error -EINVAL and true return of the same value cannot | ||
1001 | * be told apart | ||
1002 | */ | ||
1003 | |||
1004 | int ide_read_setting (ide_drive_t *drive, ide_settings_t *setting) | ||
1005 | { | ||
1006 | int val = -EINVAL; | ||
1007 | unsigned long flags; | ||
1008 | |||
1009 | if ((setting->rw & SETTING_READ)) { | ||
1010 | spin_lock_irqsave(&ide_lock, flags); | ||
1011 | switch(setting->data_type) { | ||
1012 | case TYPE_BYTE: | ||
1013 | val = *((u8 *) setting->data); | ||
1014 | break; | ||
1015 | case TYPE_SHORT: | ||
1016 | val = *((u16 *) setting->data); | ||
1017 | break; | ||
1018 | case TYPE_INT: | ||
1019 | case TYPE_INTA: | ||
1020 | val = *((u32 *) setting->data); | ||
1021 | break; | ||
1022 | } | ||
1023 | spin_unlock_irqrestore(&ide_lock, flags); | ||
1024 | } | ||
1025 | return val; | ||
1026 | } | ||
1027 | 823 | ||
1028 | /** | 824 | /** |
1029 | * ide_spin_wait_hwgroup - wait for group | 825 | * ide_spin_wait_hwgroup - wait for group |
@@ -1058,61 +854,14 @@ int ide_spin_wait_hwgroup (ide_drive_t *drive) | |||
1058 | 854 | ||
1059 | EXPORT_SYMBOL(ide_spin_wait_hwgroup); | 855 | EXPORT_SYMBOL(ide_spin_wait_hwgroup); |
1060 | 856 | ||
1061 | /** | 857 | int set_io_32bit(ide_drive_t *drive, int arg) |
1062 | * ide_write_setting - read an IDE setting | ||
1063 | * @drive: drive to read from | ||
1064 | * @setting: drive setting | ||
1065 | * @val: value | ||
1066 | * | ||
1067 | * Write a drive setting if it is possible. The caller | ||
1068 | * must hold the ide_setting_sem when making this call. | ||
1069 | * | ||
1070 | * BUGS: the data return and error are the same return value | ||
1071 | * so an error -EINVAL and true return of the same value cannot | ||
1072 | * be told apart | ||
1073 | * | ||
1074 | * FIXME: This should be changed to enqueue a special request | ||
1075 | * to the driver to change settings, and then wait on a sema for completion. | ||
1076 | * The current scheme of polling is kludgy, though safe enough. | ||
1077 | */ | ||
1078 | |||
1079 | int ide_write_setting (ide_drive_t *drive, ide_settings_t *setting, int val) | ||
1080 | { | 858 | { |
1081 | int i; | 859 | if (drive->no_io_32bit) |
1082 | u32 *p; | ||
1083 | |||
1084 | if (!capable(CAP_SYS_ADMIN)) | ||
1085 | return -EACCES; | ||
1086 | if (!(setting->rw & SETTING_WRITE)) | ||
1087 | return -EPERM; | 860 | return -EPERM; |
1088 | if (val < setting->min || val > setting->max) | 861 | |
862 | if (arg < 0 || arg > 1 + (SUPPORT_VLB_SYNC << 1)) | ||
1089 | return -EINVAL; | 863 | return -EINVAL; |
1090 | if (setting->set) | ||
1091 | return setting->set(drive, val); | ||
1092 | if (ide_spin_wait_hwgroup(drive)) | ||
1093 | return -EBUSY; | ||
1094 | switch (setting->data_type) { | ||
1095 | case TYPE_BYTE: | ||
1096 | *((u8 *) setting->data) = val; | ||
1097 | break; | ||
1098 | case TYPE_SHORT: | ||
1099 | *((u16 *) setting->data) = val; | ||
1100 | break; | ||
1101 | case TYPE_INT: | ||
1102 | *((u32 *) setting->data) = val; | ||
1103 | break; | ||
1104 | case TYPE_INTA: | ||
1105 | p = (u32 *) setting->data; | ||
1106 | for (i = 0; i < 1 << PARTN_BITS; i++, p++) | ||
1107 | *p = val; | ||
1108 | break; | ||
1109 | } | ||
1110 | spin_unlock_irq(&ide_lock); | ||
1111 | return 0; | ||
1112 | } | ||
1113 | 864 | ||
1114 | static int set_io_32bit(ide_drive_t *drive, int arg) | ||
1115 | { | ||
1116 | drive->io_32bit = arg; | 865 | drive->io_32bit = arg; |
1117 | #ifdef CONFIG_BLK_DEV_DTC2278 | 866 | #ifdef CONFIG_BLK_DEV_DTC2278 |
1118 | if (HWIF(drive)->chipset == ide_dtc2278) | 867 | if (HWIF(drive)->chipset == ide_dtc2278) |
@@ -1121,12 +870,28 @@ static int set_io_32bit(ide_drive_t *drive, int arg) | |||
1121 | return 0; | 870 | return 0; |
1122 | } | 871 | } |
1123 | 872 | ||
1124 | static int set_using_dma (ide_drive_t *drive, int arg) | 873 | static int set_ksettings(ide_drive_t *drive, int arg) |
874 | { | ||
875 | if (arg < 0 || arg > 1) | ||
876 | return -EINVAL; | ||
877 | |||
878 | if (ide_spin_wait_hwgroup(drive)) | ||
879 | return -EBUSY; | ||
880 | drive->keep_settings = arg; | ||
881 | spin_unlock_irq(&ide_lock); | ||
882 | |||
883 | return 0; | ||
884 | } | ||
885 | |||
886 | int set_using_dma(ide_drive_t *drive, int arg) | ||
1125 | { | 887 | { |
1126 | #ifdef CONFIG_BLK_DEV_IDEDMA | 888 | #ifdef CONFIG_BLK_DEV_IDEDMA |
1127 | ide_hwif_t *hwif = drive->hwif; | 889 | ide_hwif_t *hwif = drive->hwif; |
1128 | int err = -EPERM; | 890 | int err = -EPERM; |
1129 | 891 | ||
892 | if (arg < 0 || arg > 1) | ||
893 | return -EINVAL; | ||
894 | |||
1130 | if (!drive->id || !(drive->id->capability & 1)) | 895 | if (!drive->id || !(drive->id->capability & 1)) |
1131 | goto out; | 896 | goto out; |
1132 | 897 | ||
@@ -1159,14 +924,20 @@ static int set_using_dma (ide_drive_t *drive, int arg) | |||
1159 | out: | 924 | out: |
1160 | return err; | 925 | return err; |
1161 | #else | 926 | #else |
927 | if (arg < 0 || arg > 1) | ||
928 | return -EINVAL; | ||
929 | |||
1162 | return -EPERM; | 930 | return -EPERM; |
1163 | #endif | 931 | #endif |
1164 | } | 932 | } |
1165 | 933 | ||
1166 | static int set_pio_mode (ide_drive_t *drive, int arg) | 934 | int set_pio_mode(ide_drive_t *drive, int arg) |
1167 | { | 935 | { |
1168 | struct request rq; | 936 | struct request rq; |
1169 | 937 | ||
938 | if (arg < 0 || arg > 255) | ||
939 | return -EINVAL; | ||
940 | |||
1170 | if (!HWIF(drive)->tuneproc) | 941 | if (!HWIF(drive)->tuneproc) |
1171 | return -ENOSYS; | 942 | return -ENOSYS; |
1172 | if (drive->special.b.set_tune) | 943 | if (drive->special.b.set_tune) |
@@ -1178,42 +949,20 @@ static int set_pio_mode (ide_drive_t *drive, int arg) | |||
1178 | return 0; | 949 | return 0; |
1179 | } | 950 | } |
1180 | 951 | ||
1181 | static int set_xfer_rate (ide_drive_t *drive, int arg) | 952 | static int set_unmaskirq(ide_drive_t *drive, int arg) |
1182 | { | 953 | { |
1183 | int err = ide_wait_cmd(drive, | 954 | if (drive->no_unmask) |
1184 | WIN_SETFEATURES, (u8) arg, | 955 | return -EPERM; |
1185 | SETFEATURES_XFER, 0, NULL); | ||
1186 | 956 | ||
1187 | if (!err && arg) { | 957 | if (arg < 0 || arg > 1) |
1188 | ide_set_xfer_rate(drive, (u8) arg); | 958 | return -EINVAL; |
1189 | ide_driveid_update(drive); | ||
1190 | } | ||
1191 | return err; | ||
1192 | } | ||
1193 | 959 | ||
1194 | /** | 960 | if (ide_spin_wait_hwgroup(drive)) |
1195 | * ide_add_generic_settings - generic ide settings | 961 | return -EBUSY; |
1196 | * @drive: drive being configured | 962 | drive->unmask = arg; |
1197 | * | 963 | spin_unlock_irq(&ide_lock); |
1198 | * Add the generic parts of the system settings to the /proc files and | ||
1199 | * ioctls for this IDE device. The caller must not be holding the | ||
1200 | * ide_setting_sem. | ||
1201 | */ | ||
1202 | 964 | ||
1203 | void ide_add_generic_settings (ide_drive_t *drive) | 965 | return 0; |
1204 | { | ||
1205 | /* | ||
1206 | * drive setting name read/write access read ioctl write ioctl data type min max mul_factor div_factor data pointer set function | ||
1207 | */ | ||
1208 | __ide_add_setting(drive, "io_32bit", drive->no_io_32bit ? SETTING_READ : SETTING_RW, HDIO_GET_32BIT, HDIO_SET_32BIT, TYPE_BYTE, 0, 1 + (SUPPORT_VLB_SYNC << 1), 1, 1, &drive->io_32bit, set_io_32bit, 0); | ||
1209 | __ide_add_setting(drive, "keepsettings", SETTING_RW, HDIO_GET_KEEPSETTINGS, HDIO_SET_KEEPSETTINGS, TYPE_BYTE, 0, 1, 1, 1, &drive->keep_settings, NULL, 0); | ||
1210 | __ide_add_setting(drive, "nice1", SETTING_RW, -1, -1, TYPE_BYTE, 0, 1, 1, 1, &drive->nice1, NULL, 0); | ||
1211 | __ide_add_setting(drive, "pio_mode", SETTING_WRITE, -1, HDIO_SET_PIO_MODE, TYPE_BYTE, 0, 255, 1, 1, NULL, set_pio_mode, 0); | ||
1212 | __ide_add_setting(drive, "unmaskirq", drive->no_unmask ? SETTING_READ : SETTING_RW, HDIO_GET_UNMASKINTR, HDIO_SET_UNMASKINTR, TYPE_BYTE, 0, 1, 1, 1, &drive->unmask, NULL, 0); | ||
1213 | __ide_add_setting(drive, "using_dma", SETTING_RW, HDIO_GET_DMA, HDIO_SET_DMA, TYPE_BYTE, 0, 1, 1, 1, &drive->using_dma, set_using_dma, 0); | ||
1214 | __ide_add_setting(drive, "init_speed", SETTING_RW, -1, -1, TYPE_BYTE, 0, 70, 1, 1, &drive->init_speed, NULL, 0); | ||
1215 | __ide_add_setting(drive, "current_speed", SETTING_RW, -1, -1, TYPE_BYTE, 0, 70, 1, 1, &drive->current_speed, set_xfer_rate, 0); | ||
1216 | __ide_add_setting(drive, "number", SETTING_RW, -1, -1, TYPE_BYTE, 0, 3, 1, 1, &drive->dn, NULL, 0); | ||
1217 | } | 966 | } |
1218 | 967 | ||
1219 | /** | 968 | /** |
@@ -1285,27 +1034,23 @@ static int generic_ide_resume(struct device *dev) | |||
1285 | int generic_ide_ioctl(ide_drive_t *drive, struct file *file, struct block_device *bdev, | 1034 | int generic_ide_ioctl(ide_drive_t *drive, struct file *file, struct block_device *bdev, |
1286 | unsigned int cmd, unsigned long arg) | 1035 | unsigned int cmd, unsigned long arg) |
1287 | { | 1036 | { |
1288 | ide_settings_t *setting; | 1037 | unsigned long flags; |
1289 | ide_driver_t *drv; | 1038 | ide_driver_t *drv; |
1290 | int err = 0; | ||
1291 | void __user *p = (void __user *)arg; | 1039 | void __user *p = (void __user *)arg; |
1040 | int err = 0, (*setfunc)(ide_drive_t *, int); | ||
1041 | u8 *val; | ||
1292 | 1042 | ||
1293 | down(&ide_setting_sem); | 1043 | switch (cmd) { |
1294 | if ((setting = ide_find_setting_by_ioctl(drive, cmd)) != NULL) { | 1044 | case HDIO_GET_32BIT: val = &drive->io_32bit; goto read_val; |
1295 | if (cmd == setting->read_ioctl) { | 1045 | case HDIO_GET_KEEPSETTINGS: val = &drive->keep_settings; goto read_val; |
1296 | err = ide_read_setting(drive, setting); | 1046 | case HDIO_GET_UNMASKINTR: val = &drive->unmask; goto read_val; |
1297 | up(&ide_setting_sem); | 1047 | case HDIO_GET_DMA: val = &drive->using_dma; goto read_val; |
1298 | return err >= 0 ? put_user(err, (long __user *)arg) : err; | 1048 | case HDIO_SET_32BIT: setfunc = set_io_32bit; goto set_val; |
1299 | } else { | 1049 | case HDIO_SET_KEEPSETTINGS: setfunc = set_ksettings; goto set_val; |
1300 | if (bdev != bdev->bd_contains) | 1050 | case HDIO_SET_PIO_MODE: setfunc = set_pio_mode; goto set_val; |
1301 | err = -EINVAL; | 1051 | case HDIO_SET_UNMASKINTR: setfunc = set_unmaskirq; goto set_val; |
1302 | else | 1052 | case HDIO_SET_DMA: setfunc = set_using_dma; goto set_val; |
1303 | err = ide_write_setting(drive, setting, arg); | ||
1304 | up(&ide_setting_sem); | ||
1305 | return err; | ||
1306 | } | ||
1307 | } | 1053 | } |
1308 | up(&ide_setting_sem); | ||
1309 | 1054 | ||
1310 | switch (cmd) { | 1055 | switch (cmd) { |
1311 | case HDIO_OBSOLETE_IDENTITY: | 1056 | case HDIO_OBSOLETE_IDENTITY: |
@@ -1359,7 +1104,7 @@ int generic_ide_ioctl(ide_drive_t *drive, struct file *file, struct block_device | |||
1359 | ide_init_hwif_ports(&hw, (unsigned long) args[0], | 1104 | ide_init_hwif_ports(&hw, (unsigned long) args[0], |
1360 | (unsigned long) args[1], NULL); | 1105 | (unsigned long) args[1], NULL); |
1361 | hw.irq = args[2]; | 1106 | hw.irq = args[2]; |
1362 | if (ide_register_hw(&hw, NULL) == -1) | 1107 | if (ide_register_hw(&hw, 0, NULL) == -1) |
1363 | return -EIO; | 1108 | return -EIO; |
1364 | return 0; | 1109 | return 0; |
1365 | } | 1110 | } |
@@ -1434,6 +1179,28 @@ int generic_ide_ioctl(ide_drive_t *drive, struct file *file, struct block_device | |||
1434 | default: | 1179 | default: |
1435 | return -EINVAL; | 1180 | return -EINVAL; |
1436 | } | 1181 | } |
1182 | |||
1183 | read_val: | ||
1184 | down(&ide_setting_sem); | ||
1185 | spin_lock_irqsave(&ide_lock, flags); | ||
1186 | err = *val; | ||
1187 | spin_unlock_irqrestore(&ide_lock, flags); | ||
1188 | up(&ide_setting_sem); | ||
1189 | return err >= 0 ? put_user(err, (long __user *)arg) : err; | ||
1190 | |||
1191 | set_val: | ||
1192 | if (bdev != bdev->bd_contains) | ||
1193 | err = -EINVAL; | ||
1194 | else { | ||
1195 | if (!capable(CAP_SYS_ADMIN)) | ||
1196 | err = -EACCES; | ||
1197 | else { | ||
1198 | down(&ide_setting_sem); | ||
1199 | err = setfunc(drive, arg); | ||
1200 | up(&ide_setting_sem); | ||
1201 | } | ||
1202 | } | ||
1203 | return err; | ||
1437 | } | 1204 | } |
1438 | 1205 | ||
1439 | EXPORT_SYMBOL(generic_ide_ioctl); | 1206 | EXPORT_SYMBOL(generic_ide_ioctl); |
@@ -1566,13 +1333,13 @@ static int __init ide_setup(char *s) | |||
1566 | return 1; | 1333 | return 1; |
1567 | } | 1334 | } |
1568 | 1335 | ||
1569 | #ifdef CONFIG_BLK_DEV_IDEPCI | 1336 | #ifdef CONFIG_IDEPCI_PCIBUS_ORDER |
1570 | if (!strcmp(s, "ide=reverse")) { | 1337 | if (!strcmp(s, "ide=reverse")) { |
1571 | ide_scan_direction = 1; | 1338 | ide_scan_direction = 1; |
1572 | printk(" : Enabled support for IDE inverse scan order.\n"); | 1339 | printk(" : Enabled support for IDE inverse scan order.\n"); |
1573 | return 1; | 1340 | return 1; |
1574 | } | 1341 | } |
1575 | #endif /* CONFIG_BLK_DEV_IDEPCI */ | 1342 | #endif |
1576 | 1343 | ||
1577 | #ifdef CONFIG_BLK_DEV_IDEACPI | 1344 | #ifdef CONFIG_BLK_DEV_IDEACPI |
1578 | if (!strcmp(s, "ide=noacpi")) { | 1345 | if (!strcmp(s, "ide=noacpi")) { |
@@ -1832,9 +1599,9 @@ extern void __init h8300_ide_init(void); | |||
1832 | */ | 1599 | */ |
1833 | static void __init probe_for_hwifs (void) | 1600 | static void __init probe_for_hwifs (void) |
1834 | { | 1601 | { |
1835 | #ifdef CONFIG_BLK_DEV_IDEPCI | 1602 | #ifdef CONFIG_IDEPCI_PCIBUS_ORDER |
1836 | ide_scan_pcibus(ide_scan_direction); | 1603 | ide_scan_pcibus(ide_scan_direction); |
1837 | #endif /* CONFIG_BLK_DEV_IDEPCI */ | 1604 | #endif |
1838 | 1605 | ||
1839 | #ifdef CONFIG_ETRAX_IDE | 1606 | #ifdef CONFIG_ETRAX_IDE |
1840 | { | 1607 | { |
@@ -1892,54 +1659,6 @@ static void __init probe_for_hwifs (void) | |||
1892 | #endif | 1659 | #endif |
1893 | } | 1660 | } |
1894 | 1661 | ||
1895 | void ide_register_subdriver(ide_drive_t *drive, ide_driver_t *driver) | ||
1896 | { | ||
1897 | #ifdef CONFIG_PROC_FS | ||
1898 | ide_add_proc_entries(drive->proc, driver->proc, drive); | ||
1899 | #endif | ||
1900 | } | ||
1901 | |||
1902 | EXPORT_SYMBOL(ide_register_subdriver); | ||
1903 | |||
1904 | /** | ||
1905 | * ide_unregister_subdriver - disconnect drive from driver | ||
1906 | * @drive: drive to unplug | ||
1907 | * @driver: driver | ||
1908 | * | ||
1909 | * Disconnect a drive from the driver it was attached to and then | ||
1910 | * clean up the various proc files and other objects attached to it. | ||
1911 | * | ||
1912 | * Takes ide_setting_sem and ide_lock. | ||
1913 | * Caller must hold none of the locks. | ||
1914 | */ | ||
1915 | |||
1916 | void ide_unregister_subdriver(ide_drive_t *drive, ide_driver_t *driver) | ||
1917 | { | ||
1918 | unsigned long flags; | ||
1919 | |||
1920 | #ifdef CONFIG_PROC_FS | ||
1921 | ide_remove_proc_entries(drive->proc, driver->proc); | ||
1922 | #endif | ||
1923 | down(&ide_setting_sem); | ||
1924 | spin_lock_irqsave(&ide_lock, flags); | ||
1925 | /* | ||
1926 | * ide_setting_sem protects the settings list | ||
1927 | * ide_lock protects the use of settings | ||
1928 | * | ||
1929 | * so we need to hold both, ide_settings_sem because we want to | ||
1930 | * modify the settings list, and ide_lock because we cannot take | ||
1931 | * a setting out that is being used. | ||
1932 | * | ||
1933 | * OTOH both ide_{read,write}_setting are only ever used under | ||
1934 | * ide_setting_sem. | ||
1935 | */ | ||
1936 | auto_remove_settings(drive); | ||
1937 | spin_unlock_irqrestore(&ide_lock, flags); | ||
1938 | up(&ide_setting_sem); | ||
1939 | } | ||
1940 | |||
1941 | EXPORT_SYMBOL(ide_unregister_subdriver); | ||
1942 | |||
1943 | /* | 1662 | /* |
1944 | * Probe module | 1663 | * Probe module |
1945 | */ | 1664 | */ |
@@ -2071,9 +1790,7 @@ static int __init ide_init(void) | |||
2071 | 1790 | ||
2072 | init_ide_data(); | 1791 | init_ide_data(); |
2073 | 1792 | ||
2074 | #ifdef CONFIG_PROC_FS | 1793 | proc_ide_create(); |
2075 | proc_ide_root = proc_mkdir("ide", NULL); | ||
2076 | #endif | ||
2077 | 1794 | ||
2078 | #ifdef CONFIG_BLK_DEV_ALI14XX | 1795 | #ifdef CONFIG_BLK_DEV_ALI14XX |
2079 | if (probe_ali14xx) | 1796 | if (probe_ali14xx) |
@@ -2096,14 +1813,9 @@ static int __init ide_init(void) | |||
2096 | (void)qd65xx_init(); | 1813 | (void)qd65xx_init(); |
2097 | #endif | 1814 | #endif |
2098 | 1815 | ||
2099 | initializing = 1; | ||
2100 | /* Probe for special PCI and other "known" interface chipsets. */ | 1816 | /* Probe for special PCI and other "known" interface chipsets. */ |
2101 | probe_for_hwifs(); | 1817 | probe_for_hwifs(); |
2102 | initializing = 0; | ||
2103 | 1818 | ||
2104 | #ifdef CONFIG_PROC_FS | ||
2105 | proc_ide_create(); | ||
2106 | #endif | ||
2107 | return 0; | 1819 | return 0; |
2108 | } | 1820 | } |
2109 | 1821 | ||
@@ -2143,9 +1855,7 @@ void __exit cleanup_module (void) | |||
2143 | pnpide_exit(); | 1855 | pnpide_exit(); |
2144 | #endif | 1856 | #endif |
2145 | 1857 | ||
2146 | #ifdef CONFIG_PROC_FS | ||
2147 | proc_ide_destroy(); | 1858 | proc_ide_destroy(); |
2148 | #endif | ||
2149 | 1859 | ||
2150 | bus_unregister(&ide_bus_type); | 1860 | bus_unregister(&ide_bus_type); |
2151 | } | 1861 | } |