[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 70 * - fix/remove bad/unused timing tables and use one set of tables for the whole 71 71 * HPT37x chip family; save space by introducing the separate transfer mode 72 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 73 75 * <source@mvista.com> 74 76 * 75 77 */ ··· 916 914 hpt3xxn_set_clock(hwif, wantclock); 917 915 } 918 916 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 917 /* 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 918 + * Set/get power state for a drive. 956 919 * 957 - * when we turn things back on, we need to re-initialize things. 920 + * When we turn the power back on, we need to re-initialize things. 958 921 */ 959 922 #define TRISTATE_BIT 0x8000 960 - static int hpt370_busproc(ide_drive_t * drive, int state) 923 + 924 + static int hpt3xx_busproc(ide_drive_t *drive, int state) 961 925 { 962 926 ide_hwif_t *hwif = drive->hwif; 963 927 struct pci_dev *dev = hwif->pci_dev; 964 - u8 tristate = 0, resetmask = 0, bus_reg = 0; 965 - u16 tri_reg; 928 + u8 tristate, resetmask, bus_reg = 0; 929 + u16 tri_reg = 0; 966 930 967 931 hwif->bus_state = state; 968 932 969 933 if (hwif->channel) { 970 934 /* secondary channel */ 971 - tristate = 0x56; 972 - resetmask = 0x80; 935 + tristate = 0x56; 936 + resetmask = 0x80; 973 937 } else { 974 938 /* primary channel */ 975 - tristate = 0x52; 939 + tristate = 0x52; 976 940 resetmask = 0x40; 977 941 } 978 942 979 - /* grab status */ 943 + /* Grab the status. */ 980 944 pci_read_config_word(dev, tristate, &tri_reg); 981 945 pci_read_config_byte(dev, 0x59, &bus_reg); 982 946 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 */ 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 + */ 985 951 switch (state) { 986 952 case BUSSTATE_ON: 987 - hwif->drives[0].failures = 0; 988 - hwif->drives[1].failures = 0; 989 - if ((bus_reg & resetmask) == 0) 953 + if (!(bus_reg & resetmask)) 990 954 return 0; 991 - tri_reg &= ~TRISTATE_BIT; 992 - bus_reg &= ~resetmask; 993 - break; 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; 994 960 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)) 961 + if ((bus_reg & resetmask) && !(tri_reg & TRISTATE_BIT)) 998 962 return 0; 999 963 tri_reg &= ~TRISTATE_BIT; 1000 - bus_reg |= resetmask; 1001 964 break; 1002 965 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)) 966 + if ((bus_reg & resetmask) && (tri_reg & TRISTATE_BIT)) 1006 967 return 0; 1007 968 tri_reg |= TRISTATE_BIT; 1008 - bus_reg |= resetmask; 1009 969 break; 970 + default: 971 + return -EINVAL; 1010 972 } 1011 - pci_write_config_byte(dev, 0x59, bus_reg); 1012 - pci_write_config_word(dev, tristate, tri_reg); 1013 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); 1014 979 return 0; 1015 980 } 1016 981 ··· 1275 1306 if (serialize && hwif->mate) 1276 1307 hwif->serialized = hwif->mate->serialized = 1; 1277 1308 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 - } 1309 + /* 1310 + * Set up ioctl for power status. 1311 + * NOTE: power affects both drives on each channel. 1312 + */ 1313 + hwif->busproc = &hpt3xx_busproc; 1295 1314 1296 1315 if (!hwif->dma_base) { 1297 1316 hwif->drives[0].autotune = 1;