[PATCH] ide: fix HPT3xx hotswap support

Fix the broken hotswap code: on HPT37x it caused RESET- to glitch when
tristating the bus (the MISC control 3/6 and soft control 2 need to be written
to in the certain order), and for HPT36x the obsolete HDIO_TRISTATE_HWIF
ioctl() handler was called instead which treated the state argument wrong.
Also, get rid of the soft control reg. 1 wtite to enable IDE interrupt --
this is done in init_hpt37x() already...

Have been tested on HPT370 and 371N.

Signed-off-by: Sergei Shtylyov <sshtylyov@ru.mvista.com>
Cc: Bartlomiej Zolnierkiewicz <B.Zolnierkiewicz@elka.pw.edu.pl>
Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

authored by

Sergei Shtylyov and committed by
Linus Torvalds
33b18a60 471a0bda

+36 -79
+36 -79
drivers/ide/pci/hpt366.c
··· 70 * - fix/remove bad/unused timing tables and use one set of tables for the whole 71 * HPT37x chip family; save space by introducing the separate transfer mode 72 * table in which the mode lookup is done 73 * <source@mvista.com> 74 * 75 */ ··· 916 hpt3xxn_set_clock(hwif, wantclock); 917 } 918 919 - /* 920 - * Since SUN Cobalt is attempting to do this operation, I should disclose 921 - * this has been a long time ago Thu Jul 27 16:40:57 2000 was the patch date 922 - * HOTSWAP ATA Infrastructure. 923 - */ 924 - 925 - static void hpt3xx_reset (ide_drive_t *drive) 926 - { 927 - } 928 - 929 - static int hpt3xx_tristate (ide_drive_t * drive, int state) 930 - { 931 - ide_hwif_t *hwif = HWIF(drive); 932 - struct pci_dev *dev = hwif->pci_dev; 933 - u8 reg59h = 0, reset = (hwif->channel) ? 0x80 : 0x40; 934 - u8 regXXh = 0, state_reg= (hwif->channel) ? 0x57 : 0x53; 935 - 936 - pci_read_config_byte(dev, 0x59, &reg59h); 937 - pci_read_config_byte(dev, state_reg, &regXXh); 938 - 939 - if (state) { 940 - (void) ide_do_reset(drive); 941 - pci_write_config_byte(dev, state_reg, regXXh|0x80); 942 - pci_write_config_byte(dev, 0x59, reg59h|reset); 943 - } else { 944 - pci_write_config_byte(dev, 0x59, reg59h & ~(reset)); 945 - pci_write_config_byte(dev, state_reg, regXXh & ~(0x80)); 946 - (void) ide_do_reset(drive); 947 - } 948 - return 0; 949 - } 950 - 951 /* 952 - * set/get power state for a drive. 953 - * turning the power off does the following things: 954 - * 1) soft-reset the drive 955 - * 2) tri-states the ide bus 956 * 957 - * when we turn things back on, we need to re-initialize things. 958 */ 959 #define TRISTATE_BIT 0x8000 960 - static int hpt370_busproc(ide_drive_t * drive, int state) 961 { 962 ide_hwif_t *hwif = drive->hwif; 963 struct pci_dev *dev = hwif->pci_dev; 964 - u8 tristate = 0, resetmask = 0, bus_reg = 0; 965 - u16 tri_reg; 966 967 hwif->bus_state = state; 968 969 if (hwif->channel) { 970 /* secondary channel */ 971 - tristate = 0x56; 972 - resetmask = 0x80; 973 } else { 974 /* primary channel */ 975 - tristate = 0x52; 976 resetmask = 0x40; 977 } 978 979 - /* grab status */ 980 pci_read_config_word(dev, tristate, &tri_reg); 981 pci_read_config_byte(dev, 0x59, &bus_reg); 982 983 - /* set the state. we don't set it if we don't need to do so. 984 - * make sure that the drive knows that it has failed if it's off */ 985 switch (state) { 986 case BUSSTATE_ON: 987 - hwif->drives[0].failures = 0; 988 - hwif->drives[1].failures = 0; 989 - if ((bus_reg & resetmask) == 0) 990 return 0; 991 - tri_reg &= ~TRISTATE_BIT; 992 - bus_reg &= ~resetmask; 993 - break; 994 case BUSSTATE_OFF: 995 - hwif->drives[0].failures = hwif->drives[0].max_failures + 1; 996 - hwif->drives[1].failures = hwif->drives[1].max_failures + 1; 997 - if ((tri_reg & TRISTATE_BIT) == 0 && (bus_reg & resetmask)) 998 return 0; 999 tri_reg &= ~TRISTATE_BIT; 1000 - bus_reg |= resetmask; 1001 break; 1002 case BUSSTATE_TRISTATE: 1003 - hwif->drives[0].failures = hwif->drives[0].max_failures + 1; 1004 - hwif->drives[1].failures = hwif->drives[1].max_failures + 1; 1005 - if ((tri_reg & TRISTATE_BIT) && (bus_reg & resetmask)) 1006 return 0; 1007 tri_reg |= TRISTATE_BIT; 1008 - bus_reg |= resetmask; 1009 break; 1010 } 1011 - pci_write_config_byte(dev, 0x59, bus_reg); 1012 - pci_write_config_word(dev, tristate, tri_reg); 1013 1014 return 0; 1015 } 1016 ··· 1275 if (serialize && hwif->mate) 1276 hwif->serialized = hwif->mate->serialized = 1; 1277 1278 - if (info->revision >= 3) { 1279 - u8 reg5ah = 0; 1280 - pci_write_config_byte(dev, 0x5a, reg5ah & ~0x10); 1281 - /* 1282 - * set up ioctl for power status. 1283 - * note: power affects both 1284 - * drives on each channel 1285 - */ 1286 - hwif->resetproc = &hpt3xx_reset; 1287 - hwif->busproc = &hpt370_busproc; 1288 - } else if (info->revision >= 2) { 1289 - hwif->resetproc = &hpt3xx_reset; 1290 - hwif->busproc = &hpt3xx_tristate; 1291 - } else { 1292 - hwif->resetproc = &hpt3xx_reset; 1293 - hwif->busproc = &hpt3xx_tristate; 1294 - } 1295 1296 if (!hwif->dma_base) { 1297 hwif->drives[0].autotune = 1;
··· 70 * - fix/remove bad/unused timing tables and use one set of tables for the whole 71 * HPT37x chip family; save space by introducing the separate transfer mode 72 * table in which the mode lookup is done 73 + * - fix the hotswap code: it caused RESET- to glitch when tristating the bus, 74 + * and for HPT36x the obsolete HDIO_TRISTATE_HWIF handler was called instead 75 * <source@mvista.com> 76 * 77 */ ··· 914 hpt3xxn_set_clock(hwif, wantclock); 915 } 916 917 /* 918 + * Set/get power state for a drive. 919 * 920 + * When we turn the power back on, we need to re-initialize things. 921 */ 922 #define TRISTATE_BIT 0x8000 923 + 924 + static int hpt3xx_busproc(ide_drive_t *drive, int state) 925 { 926 ide_hwif_t *hwif = drive->hwif; 927 struct pci_dev *dev = hwif->pci_dev; 928 + u8 tristate, resetmask, bus_reg = 0; 929 + u16 tri_reg = 0; 930 931 hwif->bus_state = state; 932 933 if (hwif->channel) { 934 /* secondary channel */ 935 + tristate = 0x56; 936 + resetmask = 0x80; 937 } else { 938 /* primary channel */ 939 + tristate = 0x52; 940 resetmask = 0x40; 941 } 942 943 + /* Grab the status. */ 944 pci_read_config_word(dev, tristate, &tri_reg); 945 pci_read_config_byte(dev, 0x59, &bus_reg); 946 947 + /* 948 + * Set the state. We don't set it if we don't need to do so. 949 + * Make sure that the drive knows that it has failed if it's off. 950 + */ 951 switch (state) { 952 case BUSSTATE_ON: 953 + if (!(bus_reg & resetmask)) 954 return 0; 955 + hwif->drives[0].failures = hwif->drives[1].failures = 0; 956 + 957 + pci_write_config_byte(dev, 0x59, bus_reg & ~resetmask); 958 + pci_write_config_word(dev, tristate, tri_reg & ~TRISTATE_BIT); 959 + return 0; 960 case BUSSTATE_OFF: 961 + if ((bus_reg & resetmask) && !(tri_reg & TRISTATE_BIT)) 962 return 0; 963 tri_reg &= ~TRISTATE_BIT; 964 break; 965 case BUSSTATE_TRISTATE: 966 + if ((bus_reg & resetmask) && (tri_reg & TRISTATE_BIT)) 967 return 0; 968 tri_reg |= TRISTATE_BIT; 969 break; 970 + default: 971 + return -EINVAL; 972 } 973 974 + hwif->drives[0].failures = hwif->drives[0].max_failures + 1; 975 + hwif->drives[1].failures = hwif->drives[1].max_failures + 1; 976 + 977 + pci_write_config_word(dev, tristate, tri_reg); 978 + pci_write_config_byte(dev, 0x59, bus_reg | resetmask); 979 return 0; 980 } 981 ··· 1306 if (serialize && hwif->mate) 1307 hwif->serialized = hwif->mate->serialized = 1; 1308 1309 + /* 1310 + * Set up ioctl for power status. 1311 + * NOTE: power affects both drives on each channel. 1312 + */ 1313 + hwif->busproc = &hpt3xx_busproc; 1314 1315 if (!hwif->dma_base) { 1316 hwif->drives[0].autotune = 1;