aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ide/ide.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ide/ide.c')
-rw-r--r--drivers/ide/ide.c313
1 files changed, 3 insertions, 310 deletions
diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c
index 8793a960210c..614c5fd43cd2 100644
--- a/drivers/ide/ide.c
+++ b/drivers/ide/ide.c
@@ -826,178 +826,6 @@ DECLARE_MUTEX(ide_setting_sem);
826EXPORT_SYMBOL_GPL(ide_setting_sem); 826EXPORT_SYMBOL_GPL(ide_setting_sem);
827 827
828/** 828/**
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 * @data_type: type of data
834 * @min: range minimum
835 * @max: range maximum
836 * @mul_factor: multiplication scale
837 * @div_factor: divison scale
838 * @data: private data field
839 * @set: setting
840 * @auto_remove: setting auto removal flag
841 *
842 * Removes the setting named from the device if it is present.
843 * The function takes the settings_lock to protect against
844 * parallel changes. This function must not be called from IRQ
845 * context. Returns 0 on success or -1 on failure.
846 *
847 * BUGS: This code is seriously over-engineered. There is also
848 * magic about how the driver specific features are setup. If
849 * a driver is attached we assume the driver settings are auto
850 * remove.
851 */
852
853static int __ide_add_setting(ide_drive_t *drive, const char *name, int rw, int data_type, int min, int max, int mul_factor, int div_factor, void *data, ide_procset_t *set, int auto_remove)
854{
855 ide_settings_t **p = (ide_settings_t **) &drive->settings, *setting = NULL;
856
857 down(&ide_setting_sem);
858 while ((*p) && strcmp((*p)->name, name) < 0)
859 p = &((*p)->next);
860 if ((setting = kzalloc(sizeof(*setting), GFP_KERNEL)) == NULL)
861 goto abort;
862 if ((setting->name = kmalloc(strlen(name) + 1, GFP_KERNEL)) == NULL)
863 goto abort;
864 strcpy(setting->name, name);
865 setting->rw = rw;
866 setting->data_type = data_type;
867 setting->min = min;
868 setting->max = max;
869 setting->mul_factor = mul_factor;
870 setting->div_factor = div_factor;
871 setting->data = data;
872 setting->set = set;
873
874 setting->next = *p;
875 if (auto_remove)
876 setting->auto_remove = 1;
877 *p = setting;
878 up(&ide_setting_sem);
879 return 0;
880abort:
881 up(&ide_setting_sem);
882 kfree(setting);
883 return -1;
884}
885
886int ide_add_setting(ide_drive_t *drive, const char *name, int rw, int data_type, int min, int max, int mul_factor, int div_factor, void *data, ide_procset_t *set)
887{
888 return __ide_add_setting(drive, name, rw, data_type, min, max, mul_factor, div_factor, data, set, 1);
889}
890
891EXPORT_SYMBOL(ide_add_setting);
892
893/**
894 * __ide_remove_setting - remove an ide setting option
895 * @drive: drive to use
896 * @name: setting name
897 *
898 * Removes the setting named from the device if it is present.
899 * The caller must hold the setting semaphore.
900 */
901
902static void __ide_remove_setting (ide_drive_t *drive, char *name)
903{
904 ide_settings_t **p, *setting;
905
906 p = (ide_settings_t **) &drive->settings;
907
908 while ((*p) && strcmp((*p)->name, name))
909 p = &((*p)->next);
910 if ((setting = (*p)) == NULL)
911 return;
912
913 (*p) = setting->next;
914
915 kfree(setting->name);
916 kfree(setting);
917}
918
919/**
920 * ide_find_setting_by_name - find a drive specific setting
921 * @drive: drive to scan
922 * @name: setting name
923 *
924 * Scan's the device setting table for a matching entry and returns
925 * this or NULL if no entry is found. The caller must hold the
926 * setting semaphore
927 */
928
929ide_settings_t *ide_find_setting_by_name (ide_drive_t *drive, char *name)
930{
931 ide_settings_t *setting = drive->settings;
932
933 while (setting) {
934 if (strcmp(setting->name, name) == 0)
935 break;
936 setting = setting->next;
937 }
938 return setting;
939}
940
941/**
942 * auto_remove_settings - remove driver specific settings
943 * @drive: drive
944 *
945 * Automatically remove all the driver specific settings for this
946 * drive. This function may not be called from IRQ context. The
947 * caller must hold ide_setting_sem.
948 */
949
950static void auto_remove_settings (ide_drive_t *drive)
951{
952 ide_settings_t *setting;
953repeat:
954 setting = drive->settings;
955 while (setting) {
956 if (setting->auto_remove) {
957 __ide_remove_setting(drive, setting->name);
958 goto repeat;
959 }
960 setting = setting->next;
961 }
962}
963
964/**
965 * ide_read_setting - read an IDE setting
966 * @drive: drive to read from
967 * @setting: drive setting
968 *
969 * Read a drive setting and return the value. The caller
970 * must hold the ide_setting_sem when making this call.
971 *
972 * BUGS: the data return and error are the same return value
973 * so an error -EINVAL and true return of the same value cannot
974 * be told apart
975 */
976
977int ide_read_setting (ide_drive_t *drive, ide_settings_t *setting)
978{
979 int val = -EINVAL;
980 unsigned long flags;
981
982 if ((setting->rw & SETTING_READ)) {
983 spin_lock_irqsave(&ide_lock, flags);
984 switch(setting->data_type) {
985 case TYPE_BYTE:
986 val = *((u8 *) setting->data);
987 break;
988 case TYPE_SHORT:
989 val = *((u16 *) setting->data);
990 break;
991 case TYPE_INT:
992 val = *((u32 *) setting->data);
993 break;
994 }
995 spin_unlock_irqrestore(&ide_lock, flags);
996 }
997 return val;
998}
999
1000/**
1001 * ide_spin_wait_hwgroup - wait for group 829 * ide_spin_wait_hwgroup - wait for group
1002 * @drive: drive in the group 830 * @drive: drive in the group
1003 * 831 *
@@ -1030,52 +858,7 @@ int ide_spin_wait_hwgroup (ide_drive_t *drive)
1030 858
1031EXPORT_SYMBOL(ide_spin_wait_hwgroup); 859EXPORT_SYMBOL(ide_spin_wait_hwgroup);
1032 860
1033/** 861int set_io_32bit(ide_drive_t *drive, int arg)
1034 * ide_write_setting - read an IDE setting
1035 * @drive: drive to read from
1036 * @setting: drive setting
1037 * @val: value
1038 *
1039 * Write a drive setting if it is possible. The caller
1040 * must hold the ide_setting_sem when making this call.
1041 *
1042 * BUGS: the data return and error are the same return value
1043 * so an error -EINVAL and true return of the same value cannot
1044 * be told apart
1045 *
1046 * FIXME: This should be changed to enqueue a special request
1047 * to the driver to change settings, and then wait on a sema for completion.
1048 * The current scheme of polling is kludgy, though safe enough.
1049 */
1050
1051int ide_write_setting (ide_drive_t *drive, ide_settings_t *setting, int val)
1052{
1053 if (!capable(CAP_SYS_ADMIN))
1054 return -EACCES;
1055 if (setting->set)
1056 return setting->set(drive, val);
1057 if (!(setting->rw & SETTING_WRITE))
1058 return -EPERM;
1059 if (val < setting->min || val > setting->max)
1060 return -EINVAL;
1061 if (ide_spin_wait_hwgroup(drive))
1062 return -EBUSY;
1063 switch (setting->data_type) {
1064 case TYPE_BYTE:
1065 *((u8 *) setting->data) = val;
1066 break;
1067 case TYPE_SHORT:
1068 *((u16 *) setting->data) = val;
1069 break;
1070 case TYPE_INT:
1071 *((u32 *) setting->data) = val;
1072 break;
1073 }
1074 spin_unlock_irq(&ide_lock);
1075 return 0;
1076}
1077
1078static int set_io_32bit(ide_drive_t *drive, int arg)
1079{ 862{
1080 if (drive->no_io_32bit) 863 if (drive->no_io_32bit)
1081 return -EPERM; 864 return -EPERM;
@@ -1104,7 +887,7 @@ static int set_ksettings(ide_drive_t *drive, int arg)
1104 return 0; 887 return 0;
1105} 888}
1106 889
1107static int set_using_dma (ide_drive_t *drive, int arg) 890int set_using_dma(ide_drive_t *drive, int arg)
1108{ 891{
1109#ifdef CONFIG_BLK_DEV_IDEDMA 892#ifdef CONFIG_BLK_DEV_IDEDMA
1110 ide_hwif_t *hwif = drive->hwif; 893 ide_hwif_t *hwif = drive->hwif;
@@ -1152,7 +935,7 @@ out:
1152#endif 935#endif
1153} 936}
1154 937
1155static int set_pio_mode (ide_drive_t *drive, int arg) 938int set_pio_mode(ide_drive_t *drive, int arg)
1156{ 939{
1157 struct request rq; 940 struct request rq;
1158 941
@@ -1186,48 +969,6 @@ static int set_unmaskirq(ide_drive_t *drive, int arg)
1186 return 0; 969 return 0;
1187} 970}
1188 971
1189static int set_xfer_rate (ide_drive_t *drive, int arg)
1190{
1191 int err;
1192
1193 if (arg < 0 || arg > 70)
1194 return -EINVAL;
1195
1196 err = ide_wait_cmd(drive,
1197 WIN_SETFEATURES, (u8) arg,
1198 SETFEATURES_XFER, 0, NULL);
1199
1200 if (!err && arg) {
1201 ide_set_xfer_rate(drive, (u8) arg);
1202 ide_driveid_update(drive);
1203 }
1204 return err;
1205}
1206
1207/**
1208 * ide_add_generic_settings - generic ide settings
1209 * @drive: drive being configured
1210 *
1211 * Add the generic parts of the system settings to the /proc files.
1212 * The caller must not be holding the ide_setting_sem.
1213 */
1214
1215void ide_add_generic_settings (ide_drive_t *drive)
1216{
1217/*
1218 * drive setting name read/write access data type min max mul_factor div_factor data pointer set function
1219 */
1220 __ide_add_setting(drive, "io_32bit", drive->no_io_32bit ? SETTING_READ : SETTING_RW, TYPE_BYTE, 0, 1 + (SUPPORT_VLB_SYNC << 1), 1, 1, &drive->io_32bit, set_io_32bit, 0);
1221 __ide_add_setting(drive, "keepsettings", SETTING_RW, TYPE_BYTE, 0, 1, 1, 1, &drive->keep_settings, NULL, 0);
1222 __ide_add_setting(drive, "nice1", SETTING_RW, TYPE_BYTE, 0, 1, 1, 1, &drive->nice1, NULL, 0);
1223 __ide_add_setting(drive, "pio_mode", SETTING_WRITE, TYPE_BYTE, 0, 255, 1, 1, NULL, set_pio_mode, 0);
1224 __ide_add_setting(drive, "unmaskirq", drive->no_unmask ? SETTING_READ : SETTING_RW, TYPE_BYTE, 0, 1, 1, 1, &drive->unmask, NULL, 0);
1225 __ide_add_setting(drive, "using_dma", SETTING_RW, TYPE_BYTE, 0, 1, 1, 1, &drive->using_dma, set_using_dma, 0);
1226 __ide_add_setting(drive, "init_speed", SETTING_RW, TYPE_BYTE, 0, 70, 1, 1, &drive->init_speed, NULL, 0);
1227 __ide_add_setting(drive, "current_speed", SETTING_RW, TYPE_BYTE, 0, 70, 1, 1, &drive->current_speed, set_xfer_rate, 0);
1228 __ide_add_setting(drive, "number", SETTING_RW, TYPE_BYTE, 0, 3, 1, 1, &drive->dn, NULL, 0);
1229}
1230
1231/** 972/**
1232 * system_bus_clock - clock guess 973 * system_bus_clock - clock guess
1233 * 974 *
@@ -1922,54 +1663,6 @@ static void __init probe_for_hwifs (void)
1922#endif 1663#endif
1923} 1664}
1924 1665
1925void ide_register_subdriver(ide_drive_t *drive, ide_driver_t *driver)
1926{
1927#ifdef CONFIG_IDE_PROC_FS
1928 ide_add_proc_entries(drive->proc, driver->proc, drive);
1929#endif
1930}
1931
1932EXPORT_SYMBOL(ide_register_subdriver);
1933
1934/**
1935 * ide_unregister_subdriver - disconnect drive from driver
1936 * @drive: drive to unplug
1937 * @driver: driver
1938 *
1939 * Disconnect a drive from the driver it was attached to and then
1940 * clean up the various proc files and other objects attached to it.
1941 *
1942 * Takes ide_setting_sem and ide_lock.
1943 * Caller must hold none of the locks.
1944 */
1945
1946void ide_unregister_subdriver(ide_drive_t *drive, ide_driver_t *driver)
1947{
1948 unsigned long flags;
1949
1950#ifdef CONFIG_IDE_PROC_FS
1951 ide_remove_proc_entries(drive->proc, driver->proc);
1952#endif
1953 down(&ide_setting_sem);
1954 spin_lock_irqsave(&ide_lock, flags);
1955 /*
1956 * ide_setting_sem protects the settings list
1957 * ide_lock protects the use of settings
1958 *
1959 * so we need to hold both, ide_settings_sem because we want to
1960 * modify the settings list, and ide_lock because we cannot take
1961 * a setting out that is being used.
1962 *
1963 * OTOH both ide_{read,write}_setting are only ever used under
1964 * ide_setting_sem.
1965 */
1966 auto_remove_settings(drive);
1967 spin_unlock_irqrestore(&ide_lock, flags);
1968 up(&ide_setting_sem);
1969}
1970
1971EXPORT_SYMBOL(ide_unregister_subdriver);
1972
1973/* 1666/*
1974 * Probe module 1667 * Probe module
1975 */ 1668 */