diff options
Diffstat (limited to 'drivers/ide/ide.c')
| -rw-r--r-- | drivers/ide/ide.c | 360 |
1 files changed, 198 insertions, 162 deletions
diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index bced02f9f2c3..999584c03d97 100644 --- a/drivers/ide/ide.c +++ b/drivers/ide/ide.c | |||
| @@ -94,12 +94,6 @@ DEFINE_MUTEX(ide_cfg_mtx); | |||
| 94 | 94 | ||
| 95 | int noautodma = 0; | 95 | int noautodma = 0; |
| 96 | 96 | ||
| 97 | #ifdef CONFIG_BLK_DEV_IDEACPI | ||
| 98 | int ide_noacpi = 0; | ||
| 99 | int ide_noacpitfs = 1; | ||
| 100 | int ide_noacpionboot = 1; | ||
| 101 | #endif | ||
| 102 | |||
| 103 | ide_hwif_t ide_hwifs[MAX_HWIFS]; /* master data repository */ | 97 | ide_hwif_t ide_hwifs[MAX_HWIFS]; /* master data repository */ |
| 104 | 98 | ||
| 105 | static void ide_port_init_devices_data(ide_hwif_t *); | 99 | static void ide_port_init_devices_data(ide_hwif_t *); |
| @@ -293,7 +287,7 @@ EXPORT_SYMBOL_GPL(ide_port_unregister_devices); | |||
| 293 | 287 | ||
| 294 | /** | 288 | /** |
| 295 | * ide_unregister - free an IDE interface | 289 | * ide_unregister - free an IDE interface |
| 296 | * @index: index of interface (will change soon to a pointer) | 290 | * @hwif: IDE interface |
| 297 | * | 291 | * |
| 298 | * Perform the final unregister of an IDE interface. At the moment | 292 | * Perform the final unregister of an IDE interface. At the moment |
| 299 | * we don't refcount interfaces so this will also get split up. | 293 | * we don't refcount interfaces so this will also get split up. |
| @@ -313,19 +307,16 @@ EXPORT_SYMBOL_GPL(ide_port_unregister_devices); | |||
| 313 | * This is raving bonkers. | 307 | * This is raving bonkers. |
| 314 | */ | 308 | */ |
| 315 | 309 | ||
| 316 | void ide_unregister(unsigned int index) | 310 | void ide_unregister(ide_hwif_t *hwif) |
| 317 | { | 311 | { |
| 318 | ide_hwif_t *hwif, *g; | 312 | ide_hwif_t *g; |
| 319 | ide_hwgroup_t *hwgroup; | 313 | ide_hwgroup_t *hwgroup; |
| 320 | int irq_count = 0; | 314 | int irq_count = 0; |
| 321 | 315 | ||
| 322 | BUG_ON(index >= MAX_HWIFS); | ||
| 323 | |||
| 324 | BUG_ON(in_interrupt()); | 316 | BUG_ON(in_interrupt()); |
| 325 | BUG_ON(irqs_disabled()); | 317 | BUG_ON(irqs_disabled()); |
| 326 | mutex_lock(&ide_cfg_mtx); | 318 | mutex_lock(&ide_cfg_mtx); |
| 327 | spin_lock_irq(&ide_lock); | 319 | spin_lock_irq(&ide_lock); |
| 328 | hwif = &ide_hwifs[index]; | ||
| 329 | if (!hwif->present) | 320 | if (!hwif->present) |
| 330 | goto abort; | 321 | goto abort; |
| 331 | __ide_port_unregister_devices(hwif); | 322 | __ide_port_unregister_devices(hwif); |
| @@ -366,7 +357,7 @@ void ide_unregister(unsigned int index) | |||
| 366 | ide_release_dma_engine(hwif); | 357 | ide_release_dma_engine(hwif); |
| 367 | 358 | ||
| 368 | /* restore hwif data to pristine status */ | 359 | /* restore hwif data to pristine status */ |
| 369 | ide_init_port_data(hwif, index); | 360 | ide_init_port_data(hwif, hwif->index); |
| 370 | 361 | ||
| 371 | abort: | 362 | abort: |
| 372 | spin_unlock_irq(&ide_lock); | 363 | spin_unlock_irq(&ide_lock); |
| @@ -377,7 +368,7 @@ EXPORT_SYMBOL(ide_unregister); | |||
| 377 | 368 | ||
| 378 | void ide_init_port_hw(ide_hwif_t *hwif, hw_regs_t *hw) | 369 | void ide_init_port_hw(ide_hwif_t *hwif, hw_regs_t *hw) |
| 379 | { | 370 | { |
| 380 | memcpy(hwif->io_ports, hw->io_ports, sizeof(hwif->io_ports)); | 371 | memcpy(&hwif->io_ports, &hw->io_ports, sizeof(hwif->io_ports)); |
| 381 | hwif->irq = hw->irq; | 372 | hwif->irq = hw->irq; |
| 382 | hwif->chipset = hw->chipset; | 373 | hwif->chipset = hw->chipset; |
| 383 | hwif->gendev.parent = hw->dev; | 374 | hwif->gendev.parent = hw->dev; |
| @@ -837,16 +828,6 @@ static int __init match_parm (char *s, const char *keywords[], int vals[], int m | |||
| 837 | return 0; /* zero = nothing matched */ | 828 | return 0; /* zero = nothing matched */ |
| 838 | } | 829 | } |
| 839 | 830 | ||
| 840 | extern int probe_ali14xx; | ||
| 841 | extern int probe_umc8672; | ||
| 842 | extern int probe_dtc2278; | ||
| 843 | extern int probe_ht6560b; | ||
| 844 | extern int probe_qd65xx; | ||
| 845 | extern int cmd640_vlb; | ||
| 846 | extern int probe_4drives; | ||
| 847 | |||
| 848 | static int __initdata is_chipset_set; | ||
| 849 | |||
| 850 | /* | 831 | /* |
| 851 | * ide_setup() gets called VERY EARLY during initialization, | 832 | * ide_setup() gets called VERY EARLY during initialization, |
| 852 | * to handle kernel "command line" strings beginning with "hdx=" or "ide". | 833 | * to handle kernel "command line" strings beginning with "hdx=" or "ide". |
| @@ -855,14 +836,12 @@ static int __initdata is_chipset_set; | |||
| 855 | */ | 836 | */ |
| 856 | static int __init ide_setup(char *s) | 837 | static int __init ide_setup(char *s) |
| 857 | { | 838 | { |
| 858 | int i, vals[3]; | ||
| 859 | ide_hwif_t *hwif; | 839 | ide_hwif_t *hwif; |
| 860 | ide_drive_t *drive; | 840 | ide_drive_t *drive; |
| 861 | unsigned int hw, unit; | 841 | unsigned int hw, unit; |
| 842 | int vals[3]; | ||
| 862 | const char max_drive = 'a' + ((MAX_HWIFS * MAX_DRIVES) - 1); | 843 | const char max_drive = 'a' + ((MAX_HWIFS * MAX_DRIVES) - 1); |
| 863 | const char max_hwif = '0' + (MAX_HWIFS - 1); | ||
| 864 | 844 | ||
| 865 | |||
| 866 | if (strncmp(s,"hd",2) == 0 && s[2] == '=') /* hd= is for hd.c */ | 845 | if (strncmp(s,"hd",2) == 0 && s[2] == '=') /* hd= is for hd.c */ |
| 867 | return 0; /* driver and not us */ | 846 | return 0; /* driver and not us */ |
| 868 | 847 | ||
| @@ -878,7 +857,7 @@ static int __init ide_setup(char *s) | |||
| 878 | 857 | ||
| 879 | printk(" : Enabled support for IDE doublers\n"); | 858 | printk(" : Enabled support for IDE doublers\n"); |
| 880 | ide_doubler = 1; | 859 | ide_doubler = 1; |
| 881 | return 1; | 860 | goto obsolete_option; |
| 882 | } | 861 | } |
| 883 | #endif /* CONFIG_BLK_DEV_IDEDOUBLER */ | 862 | #endif /* CONFIG_BLK_DEV_IDEDOUBLER */ |
| 884 | 863 | ||
| @@ -892,17 +871,17 @@ static int __init ide_setup(char *s) | |||
| 892 | if (!strcmp(s, "ide=noacpi")) { | 871 | if (!strcmp(s, "ide=noacpi")) { |
| 893 | //printk(" : Disable IDE ACPI support.\n"); | 872 | //printk(" : Disable IDE ACPI support.\n"); |
| 894 | ide_noacpi = 1; | 873 | ide_noacpi = 1; |
| 895 | return 1; | 874 | goto obsolete_option; |
| 896 | } | 875 | } |
| 897 | if (!strcmp(s, "ide=acpigtf")) { | 876 | if (!strcmp(s, "ide=acpigtf")) { |
| 898 | //printk(" : Enable IDE ACPI _GTF support.\n"); | 877 | //printk(" : Enable IDE ACPI _GTF support.\n"); |
| 899 | ide_noacpitfs = 0; | 878 | ide_acpigtf = 1; |
| 900 | return 1; | 879 | goto obsolete_option; |
| 901 | } | 880 | } |
| 902 | if (!strcmp(s, "ide=acpionboot")) { | 881 | if (!strcmp(s, "ide=acpionboot")) { |
| 903 | //printk(" : Call IDE ACPI methods on boot.\n"); | 882 | //printk(" : Call IDE ACPI methods on boot.\n"); |
| 904 | ide_noacpionboot = 0; | 883 | ide_acpionboot = 1; |
| 905 | return 1; | 884 | goto obsolete_option; |
| 906 | } | 885 | } |
| 907 | #endif /* CONFIG_BLK_DEV_IDEACPI */ | 886 | #endif /* CONFIG_BLK_DEV_IDEACPI */ |
| 908 | 887 | ||
| @@ -912,7 +891,7 @@ static int __init ide_setup(char *s) | |||
| 912 | if (s[0] == 'h' && s[1] == 'd' && s[2] >= 'a' && s[2] <= max_drive) { | 891 | if (s[0] == 'h' && s[1] == 'd' && s[2] >= 'a' && s[2] <= max_drive) { |
| 913 | const char *hd_words[] = { | 892 | const char *hd_words[] = { |
| 914 | "none", "noprobe", "nowerr", "cdrom", "nodma", | 893 | "none", "noprobe", "nowerr", "cdrom", "nodma", |
| 915 | "autotune", "noautotune", "-8", "-9", "-10", | 894 | "-6", "-7", "-8", "-9", "-10", |
| 916 | "noflush", "remap", "remap63", "scsi", NULL }; | 895 | "noflush", "remap", "remap63", "scsi", NULL }; |
| 917 | unit = s[2] - 'a'; | 896 | unit = s[2] - 'a'; |
| 918 | hw = unit / MAX_DRIVES; | 897 | hw = unit / MAX_DRIVES; |
| @@ -927,28 +906,22 @@ static int __init ide_setup(char *s) | |||
| 927 | case -1: /* "none" */ | 906 | case -1: /* "none" */ |
| 928 | case -2: /* "noprobe" */ | 907 | case -2: /* "noprobe" */ |
| 929 | drive->noprobe = 1; | 908 | drive->noprobe = 1; |
| 930 | goto done; | 909 | goto obsolete_option; |
| 931 | case -3: /* "nowerr" */ | 910 | case -3: /* "nowerr" */ |
| 932 | drive->bad_wstat = BAD_R_STAT; | 911 | drive->bad_wstat = BAD_R_STAT; |
| 933 | goto done; | 912 | goto obsolete_option; |
| 934 | case -4: /* "cdrom" */ | 913 | case -4: /* "cdrom" */ |
| 935 | drive->present = 1; | 914 | drive->present = 1; |
| 936 | drive->media = ide_cdrom; | 915 | drive->media = ide_cdrom; |
| 937 | /* an ATAPI device ignores DRDY */ | 916 | /* an ATAPI device ignores DRDY */ |
| 938 | drive->ready_stat = 0; | 917 | drive->ready_stat = 0; |
| 939 | goto done; | 918 | goto obsolete_option; |
| 940 | case -5: /* nodma */ | 919 | case -5: /* nodma */ |
| 941 | drive->nodma = 1; | 920 | drive->nodma = 1; |
| 942 | goto done; | ||
| 943 | case -6: /* "autotune" */ | ||
| 944 | drive->autotune = IDE_TUNE_AUTO; | ||
| 945 | goto obsolete_option; | ||
| 946 | case -7: /* "noautotune" */ | ||
| 947 | drive->autotune = IDE_TUNE_NOAUTO; | ||
| 948 | goto obsolete_option; | 921 | goto obsolete_option; |
| 949 | case -11: /* noflush */ | 922 | case -11: /* noflush */ |
| 950 | drive->noflush = 1; | 923 | drive->noflush = 1; |
| 951 | goto done; | 924 | goto obsolete_option; |
| 952 | case -12: /* "remap" */ | 925 | case -12: /* "remap" */ |
| 953 | drive->remap_0_to_1 = 1; | 926 | drive->remap_0_to_1 = 1; |
| 954 | goto obsolete_option; | 927 | goto obsolete_option; |
| @@ -966,7 +939,7 @@ static int __init ide_setup(char *s) | |||
| 966 | drive->sect = drive->bios_sect = vals[2]; | 939 | drive->sect = drive->bios_sect = vals[2]; |
| 967 | drive->present = 1; | 940 | drive->present = 1; |
| 968 | drive->forced_geom = 1; | 941 | drive->forced_geom = 1; |
| 969 | goto done; | 942 | goto obsolete_option; |
| 970 | default: | 943 | default: |
| 971 | goto bad_option; | 944 | goto bad_option; |
| 972 | } | 945 | } |
| @@ -984,126 +957,15 @@ static int __init ide_setup(char *s) | |||
| 984 | idebus_parameter = vals[0]; | 957 | idebus_parameter = vals[0]; |
| 985 | } else | 958 | } else |
| 986 | printk(" -- BAD BUS SPEED! Expected value from 20 to 66"); | 959 | printk(" -- BAD BUS SPEED! Expected value from 20 to 66"); |
| 987 | goto done; | 960 | goto obsolete_option; |
| 988 | } | 961 | } |
| 989 | /* | ||
| 990 | * Look for interface options: "idex=" | ||
| 991 | */ | ||
| 992 | if (s[3] >= '0' && s[3] <= max_hwif) { | ||
| 993 | /* | ||
| 994 | * Be VERY CAREFUL changing this: note hardcoded indexes below | ||
| 995 | * (-8, -9, -10) are reserved to ease the hardcoding. | ||
| 996 | */ | ||
| 997 | static const char *ide_words[] = { | ||
| 998 | "minus1", "serialize", "minus3", "minus4", | ||
| 999 | "reset", "minus6", "ata66", "minus8", "minus9", | ||
| 1000 | "minus10", "four", "qd65xx", "ht6560b", "cmd640_vlb", | ||
| 1001 | "dtc2278", "umc8672", "ali14xx", NULL }; | ||
| 1002 | |||
| 1003 | hw = s[3] - '0'; | ||
| 1004 | hwif = &ide_hwifs[hw]; | ||
| 1005 | i = match_parm(&s[4], ide_words, vals, 3); | ||
| 1006 | |||
| 1007 | /* | ||
| 1008 | * Cryptic check to ensure chipset not already set for hwif. | ||
| 1009 | * Note: we can't depend on hwif->chipset here. | ||
| 1010 | */ | ||
| 1011 | if (i >= -18 && i <= -11) { | ||
| 1012 | /* chipset already specified */ | ||
| 1013 | if (is_chipset_set) | ||
| 1014 | goto bad_option; | ||
| 1015 | /* these drivers are for "ide0=" only */ | ||
| 1016 | if (hw != 0) | ||
| 1017 | goto bad_hwif; | ||
| 1018 | is_chipset_set = 1; | ||
| 1019 | printk("\n"); | ||
| 1020 | } | ||
| 1021 | |||
| 1022 | switch (i) { | ||
| 1023 | #ifdef CONFIG_BLK_DEV_ALI14XX | ||
| 1024 | case -17: /* "ali14xx" */ | ||
| 1025 | probe_ali14xx = 1; | ||
| 1026 | goto obsolete_option; | ||
| 1027 | #endif | ||
| 1028 | #ifdef CONFIG_BLK_DEV_UMC8672 | ||
| 1029 | case -16: /* "umc8672" */ | ||
| 1030 | probe_umc8672 = 1; | ||
| 1031 | goto obsolete_option; | ||
| 1032 | #endif | ||
| 1033 | #ifdef CONFIG_BLK_DEV_DTC2278 | ||
| 1034 | case -15: /* "dtc2278" */ | ||
| 1035 | probe_dtc2278 = 1; | ||
| 1036 | goto obsolete_option; | ||
| 1037 | #endif | ||
| 1038 | #ifdef CONFIG_BLK_DEV_CMD640 | ||
| 1039 | case -14: /* "cmd640_vlb" */ | ||
| 1040 | cmd640_vlb = 1; | ||
| 1041 | goto obsolete_option; | ||
| 1042 | #endif | ||
| 1043 | #ifdef CONFIG_BLK_DEV_HT6560B | ||
| 1044 | case -13: /* "ht6560b" */ | ||
| 1045 | probe_ht6560b = 1; | ||
| 1046 | goto obsolete_option; | ||
| 1047 | #endif | ||
| 1048 | #ifdef CONFIG_BLK_DEV_QD65XX | ||
| 1049 | case -12: /* "qd65xx" */ | ||
| 1050 | probe_qd65xx = 1; | ||
| 1051 | goto obsolete_option; | ||
| 1052 | #endif | ||
| 1053 | #ifdef CONFIG_BLK_DEV_4DRIVES | ||
| 1054 | case -11: /* "four" drives on one set of ports */ | ||
| 1055 | probe_4drives = 1; | ||
| 1056 | goto obsolete_option; | ||
| 1057 | #endif | ||
| 1058 | case -10: /* minus10 */ | ||
| 1059 | case -9: /* minus9 */ | ||
| 1060 | case -8: /* minus8 */ | ||
| 1061 | case -6: | ||
| 1062 | case -4: | ||
| 1063 | case -3: | ||
| 1064 | goto bad_option; | ||
| 1065 | case -7: /* ata66 */ | ||
| 1066 | #ifdef CONFIG_BLK_DEV_IDEPCI | ||
| 1067 | /* | ||
| 1068 | * Use ATA_CBL_PATA40_SHORT so drive side | ||
| 1069 | * cable detection is also overriden. | ||
| 1070 | */ | ||
| 1071 | hwif->cbl = ATA_CBL_PATA40_SHORT; | ||
| 1072 | goto obsolete_option; | ||
| 1073 | #else | ||
| 1074 | goto bad_hwif; | ||
| 1075 | #endif | ||
| 1076 | case -5: /* "reset" */ | ||
| 1077 | hwif->reset = 1; | ||
| 1078 | goto obsolete_option; | ||
| 1079 | case -2: /* "serialize" */ | ||
| 1080 | hwif->mate = &ide_hwifs[hw^1]; | ||
| 1081 | hwif->mate->mate = hwif; | ||
| 1082 | hwif->serialized = hwif->mate->serialized = 1; | ||
| 1083 | goto obsolete_option; | ||
| 1084 | 962 | ||
| 1085 | case -1: | ||
| 1086 | case 0: | ||
| 1087 | case 1: | ||
| 1088 | case 2: | ||
| 1089 | case 3: | ||
| 1090 | goto bad_option; | ||
| 1091 | default: | ||
| 1092 | printk(" -- SUPPORT NOT CONFIGURED IN THIS KERNEL\n"); | ||
| 1093 | return 1; | ||
| 1094 | } | ||
| 1095 | } | ||
| 1096 | bad_option: | 963 | bad_option: |
| 1097 | printk(" -- BAD OPTION\n"); | 964 | printk(" -- BAD OPTION\n"); |
| 1098 | return 1; | 965 | return 1; |
| 1099 | obsolete_option: | 966 | obsolete_option: |
| 1100 | printk(" -- OBSOLETE OPTION, WILL BE REMOVED SOON!\n"); | 967 | printk(" -- OBSOLETE OPTION, WILL BE REMOVED SOON!\n"); |
| 1101 | return 1; | 968 | return 1; |
| 1102 | bad_hwif: | ||
| 1103 | printk("-- NOT SUPPORTED ON ide%d", hw); | ||
| 1104 | done: | ||
| 1105 | printk("\n"); | ||
| 1106 | return 1; | ||
| 1107 | } | 969 | } |
| 1108 | 970 | ||
| 1109 | EXPORT_SYMBOL(ide_lock); | 971 | EXPORT_SYMBOL(ide_lock); |
| @@ -1239,6 +1101,185 @@ static void ide_port_class_release(struct device *portdev) | |||
| 1239 | put_device(&hwif->gendev); | 1101 | put_device(&hwif->gendev); |
| 1240 | } | 1102 | } |
| 1241 | 1103 | ||
| 1104 | int ide_vlb_clk; | ||
| 1105 | EXPORT_SYMBOL_GPL(ide_vlb_clk); | ||
| 1106 | |||
| 1107 | module_param_named(vlb_clock, ide_vlb_clk, int, 0); | ||
| 1108 | MODULE_PARM_DESC(vlb_clock, "VLB clock frequency (in MHz)"); | ||
| 1109 | |||
| 1110 | int ide_pci_clk; | ||
| 1111 | EXPORT_SYMBOL_GPL(ide_pci_clk); | ||
| 1112 | |||
| 1113 | module_param_named(pci_clock, ide_pci_clk, int, 0); | ||
| 1114 | MODULE_PARM_DESC(pci_clock, "PCI bus clock frequency (in MHz)"); | ||
| 1115 | |||
| 1116 | static int ide_set_dev_param_mask(const char *s, struct kernel_param *kp) | ||
| 1117 | { | ||
| 1118 | int a, b, i, j = 1; | ||
| 1119 | unsigned int *dev_param_mask = (unsigned int *)kp->arg; | ||
| 1120 | |||
| 1121 | if (sscanf(s, "%d.%d:%d", &a, &b, &j) != 3 && | ||
| 1122 | sscanf(s, "%d.%d", &a, &b) != 2) | ||
| 1123 | return -EINVAL; | ||
| 1124 | |||
| 1125 | i = a * MAX_DRIVES + b; | ||
| 1126 | |||
| 1127 | if (i >= MAX_HWIFS * MAX_DRIVES || j < 0 || j > 1) | ||
| 1128 | return -EINVAL; | ||
| 1129 | |||
| 1130 | if (j) | ||
| 1131 | *dev_param_mask |= (1 << i); | ||
| 1132 | else | ||
| 1133 | *dev_param_mask &= (1 << i); | ||
| 1134 | |||
| 1135 | return 0; | ||
| 1136 | } | ||
| 1137 | |||
| 1138 | static unsigned int ide_nodma; | ||
| 1139 | |||
| 1140 | module_param_call(nodma, ide_set_dev_param_mask, NULL, &ide_nodma, 0); | ||
| 1141 | MODULE_PARM_DESC(nodma, "disallow DMA for a device"); | ||
| 1142 | |||
| 1143 | static unsigned int ide_noflush; | ||
| 1144 | |||
| 1145 | module_param_call(noflush, ide_set_dev_param_mask, NULL, &ide_noflush, 0); | ||
| 1146 | MODULE_PARM_DESC(noflush, "disable flush requests for a device"); | ||
| 1147 | |||
| 1148 | static unsigned int ide_noprobe; | ||
| 1149 | |||
| 1150 | module_param_call(noprobe, ide_set_dev_param_mask, NULL, &ide_noprobe, 0); | ||
| 1151 | MODULE_PARM_DESC(noprobe, "skip probing for a device"); | ||
| 1152 | |||
| 1153 | static unsigned int ide_nowerr; | ||
| 1154 | |||
| 1155 | module_param_call(nowerr, ide_set_dev_param_mask, NULL, &ide_nowerr, 0); | ||
| 1156 | MODULE_PARM_DESC(nowerr, "ignore the WRERR_STAT bit for a device"); | ||
| 1157 | |||
| 1158 | static unsigned int ide_cdroms; | ||
| 1159 | |||
| 1160 | module_param_call(cdrom, ide_set_dev_param_mask, NULL, &ide_cdroms, 0); | ||
| 1161 | MODULE_PARM_DESC(cdrom, "force device as a CD-ROM"); | ||
| 1162 | |||
| 1163 | struct chs_geom { | ||
| 1164 | unsigned int cyl; | ||
| 1165 | u8 head; | ||
| 1166 | u8 sect; | ||
| 1167 | }; | ||
| 1168 | |||
| 1169 | static unsigned int ide_disks; | ||
| 1170 | static struct chs_geom ide_disks_chs[MAX_HWIFS * MAX_DRIVES]; | ||
| 1171 | |||
| 1172 | static int ide_set_disk_chs(const char *str, struct kernel_param *kp) | ||
| 1173 | { | ||
| 1174 | int a, b, c = 0, h = 0, s = 0, i, j = 1; | ||
| 1175 | |||
| 1176 | if (sscanf(str, "%d.%d:%d,%d,%d", &a, &b, &c, &h, &s) != 5 && | ||
| 1177 | sscanf(str, "%d.%d:%d", &a, &b, &j) != 3) | ||
| 1178 | return -EINVAL; | ||
| 1179 | |||
| 1180 | i = a * MAX_DRIVES + b; | ||
| 1181 | |||
| 1182 | if (i >= MAX_HWIFS * MAX_DRIVES || j < 0 || j > 1) | ||
| 1183 | return -EINVAL; | ||
| 1184 | |||
| 1185 | if (c > INT_MAX || h > 255 || s > 255) | ||
| 1186 | return -EINVAL; | ||
| 1187 | |||
| 1188 | if (j) | ||
| 1189 | ide_disks |= (1 << i); | ||
| 1190 | else | ||
| 1191 | ide_disks &= (1 << i); | ||
| 1192 | |||
| 1193 | ide_disks_chs[i].cyl = c; | ||
| 1194 | ide_disks_chs[i].head = h; | ||
| 1195 | ide_disks_chs[i].sect = s; | ||
| 1196 | |||
| 1197 | return 0; | ||
| 1198 | } | ||
| 1199 | |||
| 1200 | module_param_call(chs, ide_set_disk_chs, NULL, NULL, 0); | ||
| 1201 | MODULE_PARM_DESC(chs, "force device as a disk (using CHS)"); | ||
| 1202 | |||
| 1203 | static void ide_dev_apply_params(ide_drive_t *drive) | ||
| 1204 | { | ||
| 1205 | int i = drive->hwif->index * MAX_DRIVES + drive->select.b.unit; | ||
| 1206 | |||
| 1207 | if (ide_nodma & (1 << i)) { | ||
| 1208 | printk(KERN_INFO "ide: disallowing DMA for %s\n", drive->name); | ||
| 1209 | drive->nodma = 1; | ||
| 1210 | } | ||
| 1211 | if (ide_noflush & (1 << i)) { | ||
| 1212 | printk(KERN_INFO "ide: disabling flush requests for %s\n", | ||
| 1213 | drive->name); | ||
| 1214 | drive->noflush = 1; | ||
| 1215 | } | ||
| 1216 | if (ide_noprobe & (1 << i)) { | ||
| 1217 | printk(KERN_INFO "ide: skipping probe for %s\n", drive->name); | ||
| 1218 | drive->noprobe = 1; | ||
| 1219 | } | ||
| 1220 | if (ide_nowerr & (1 << i)) { | ||
| 1221 | printk(KERN_INFO "ide: ignoring the WRERR_STAT bit for %s\n", | ||
| 1222 | drive->name); | ||
| 1223 | drive->bad_wstat = BAD_R_STAT; | ||
| 1224 | } | ||
| 1225 | if (ide_cdroms & (1 << i)) { | ||
| 1226 | printk(KERN_INFO "ide: forcing %s as a CD-ROM\n", drive->name); | ||
| 1227 | drive->present = 1; | ||
| 1228 | drive->media = ide_cdrom; | ||
| 1229 | /* an ATAPI device ignores DRDY */ | ||
| 1230 | drive->ready_stat = 0; | ||
| 1231 | } | ||
| 1232 | if (ide_disks & (1 << i)) { | ||
| 1233 | drive->cyl = drive->bios_cyl = ide_disks_chs[i].cyl; | ||
| 1234 | drive->head = drive->bios_head = ide_disks_chs[i].head; | ||
| 1235 | drive->sect = drive->bios_sect = ide_disks_chs[i].sect; | ||
| 1236 | drive->forced_geom = 1; | ||
| 1237 | printk(KERN_INFO "ide: forcing %s as a disk (%d/%d/%d)\n", | ||
| 1238 | drive->name, | ||
| 1239 | drive->cyl, drive->head, drive->sect); | ||
| 1240 | drive->present = 1; | ||
| 1241 | drive->media = ide_disk; | ||
| 1242 | drive->ready_stat = READY_STAT; | ||
| 1243 | } | ||
| 1244 | } | ||
| 1245 | |||
| 1246 | static unsigned int ide_ignore_cable; | ||
| 1247 | |||
| 1248 | static int ide_set_ignore_cable(const char *s, struct kernel_param *kp) | ||
| 1249 | { | ||
| 1250 | int i, j = 1; | ||
| 1251 | |||
| 1252 | if (sscanf(s, "%d:%d", &i, &j) != 2 && sscanf(s, "%d", &i) != 1) | ||
| 1253 | return -EINVAL; | ||
| 1254 | |||
| 1255 | if (i >= MAX_HWIFS || j < 0 || j > 1) | ||
| 1256 | return -EINVAL; | ||
| 1257 | |||
| 1258 | if (j) | ||
| 1259 | ide_ignore_cable |= (1 << i); | ||
| 1260 | else | ||
| 1261 | ide_ignore_cable &= (1 << i); | ||
| 1262 | |||
| 1263 | return 0; | ||
| 1264 | } | ||
| 1265 | |||
| 1266 | module_param_call(ignore_cable, ide_set_ignore_cable, NULL, NULL, 0); | ||
| 1267 | MODULE_PARM_DESC(ignore_cable, "ignore cable detection"); | ||
| 1268 | |||
| 1269 | void ide_port_apply_params(ide_hwif_t *hwif) | ||
| 1270 | { | ||
| 1271 | int i; | ||
| 1272 | |||
| 1273 | if (ide_ignore_cable & (1 << hwif->index)) { | ||
| 1274 | printk(KERN_INFO "ide: ignoring cable detection for %s\n", | ||
| 1275 | hwif->name); | ||
| 1276 | hwif->cbl = ATA_CBL_PATA40_SHORT; | ||
| 1277 | } | ||
| 1278 | |||
| 1279 | for (i = 0; i < MAX_DRIVES; i++) | ||
| 1280 | ide_dev_apply_params(&hwif->drives[i]); | ||
| 1281 | } | ||
| 1282 | |||
| 1242 | /* | 1283 | /* |
| 1243 | * This is gets invoked once during initialization, to set *everything* up | 1284 | * This is gets invoked once during initialization, to set *everything* up |
| 1244 | */ | 1285 | */ |
| @@ -1305,11 +1346,6 @@ int __init init_module (void) | |||
| 1305 | 1346 | ||
| 1306 | void __exit cleanup_module (void) | 1347 | void __exit cleanup_module (void) |
| 1307 | { | 1348 | { |
| 1308 | int index; | ||
| 1309 | |||
| 1310 | for (index = 0; index < MAX_HWIFS; ++index) | ||
| 1311 | ide_unregister(index); | ||
| 1312 | |||
| 1313 | proc_ide_destroy(); | 1349 | proc_ide_destroy(); |
| 1314 | 1350 | ||
| 1315 | class_destroy(ide_port_class); | 1351 | class_destroy(ide_port_class); |
