aboutsummaryrefslogtreecommitdiff
path: root/drivers/ide/hpt366.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ide/hpt366.c')
-rw-r--r--drivers/ide/hpt366.c172
1 files changed, 45 insertions, 127 deletions
diff --git a/drivers/ide/hpt366.c b/drivers/ide/hpt366.c
index a0eb87f5913..696b6c1ec94 100644
--- a/drivers/ide/hpt366.c
+++ b/drivers/ide/hpt366.c
@@ -3,7 +3,7 @@
* Portions Copyright (C) 2001 Sun Microsystems, Inc.
* Portions Copyright (C) 2003 Red Hat Inc
* Portions Copyright (C) 2007 Bartlomiej Zolnierkiewicz
- * Portions Copyright (C) 2005-2008 MontaVista Software, Inc.
+ * Portions Copyright (C) 2005-2009 MontaVista Software, Inc.
*
* Thanks to HighPoint Technologies for their assistance, and hardware.
* Special Thanks to Jon Burchmore in SanDiego for the deep pockets, his
@@ -12,7 +12,7 @@
*
*
* HighPoint has its own drivers (open source except for the RAID part)
- * available from http://www.highpoint-tech.com/BIOS%20+%20Driver/.
+ * available from http://www.highpoint-tech.com/USA_new/service_support.htm
* This may be useful to anyone wanting to work on this driver, however do not
* trust them too much since the code tends to become less and less meaningful
* as the time passes... :-/
@@ -114,6 +114,8 @@
* the register setting lists into the table indexed by the clock selected
* - set the correct hwif->ultra_mask for each individual chip
* - add Ultra and MW DMA mode filtering for the HPT37[24] based SATA cards
+ * - stop resetting HPT370's state machine before each DMA transfer as that has
+ * caused more harm than good
* Sergei Shtylyov, <sshtylyov@ru.mvista.com> or <source@mvista.com>
*/
@@ -126,6 +128,7 @@
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/ide.h>
+#include <linux/slab.h>
#include <asm/uaccess.h>
#include <asm/io.h>
@@ -133,17 +136,9 @@
#define DRV_NAME "hpt366"
/* various tuning parameters */
-#define HPT_RESET_STATE_ENGINE
+#undef HPT_RESET_STATE_ENGINE
#undef HPT_DELAY_INTERRUPT
-static const char *quirk_drives[] = {
- "QUANTUM FIREBALLlct08 08",
- "QUANTUM FIREBALLP KA6.4",
- "QUANTUM FIREBALLP LM20.4",
- "QUANTUM FIREBALLP LM20.5",
- NULL
-};
-
static const char *bad_ata100_5[] = {
"IBM-DTLA-307075",
"IBM-DTLA-307060",
@@ -303,68 +298,6 @@ static u32 twenty_five_base_hpt36x[] = {
/* XFER_PIO_0 */ 0xc0d08585
};
-#if 0
-/* These are the timing tables from the HighPoint open source drivers... */
-static u32 thirty_three_base_hpt37x[] = {
- /* XFER_UDMA_6 */ 0x12446231, /* 0x12646231 ?? */
- /* XFER_UDMA_5 */ 0x12446231,
- /* XFER_UDMA_4 */ 0x12446231,
- /* XFER_UDMA_3 */ 0x126c6231,
- /* XFER_UDMA_2 */ 0x12486231,
- /* XFER_UDMA_1 */ 0x124c6233,
- /* XFER_UDMA_0 */ 0x12506297,
-
- /* XFER_MW_DMA_2 */ 0x22406c31,
- /* XFER_MW_DMA_1 */ 0x22406c33,
- /* XFER_MW_DMA_0 */ 0x22406c97,
-
- /* XFER_PIO_4 */ 0x06414e31,
- /* XFER_PIO_3 */ 0x06414e42,
- /* XFER_PIO_2 */ 0x06414e53,
- /* XFER_PIO_1 */ 0x06814e93,
- /* XFER_PIO_0 */ 0x06814ea7
-};
-
-static u32 fifty_base_hpt37x[] = {
- /* XFER_UDMA_6 */ 0x12848242,
- /* XFER_UDMA_5 */ 0x12848242,
- /* XFER_UDMA_4 */ 0x12ac8242,
- /* XFER_UDMA_3 */ 0x128c8242,
- /* XFER_UDMA_2 */ 0x120c8242,
- /* XFER_UDMA_1 */ 0x12148254,
- /* XFER_UDMA_0 */ 0x121882ea,
-
- /* XFER_MW_DMA_2 */ 0x22808242,
- /* XFER_MW_DMA_1 */ 0x22808254,
- /* XFER_MW_DMA_0 */ 0x228082ea,
-
- /* XFER_PIO_4 */ 0x0a81f442,
- /* XFER_PIO_3 */ 0x0a81f443,
- /* XFER_PIO_2 */ 0x0a81f454,
- /* XFER_PIO_1 */ 0x0ac1f465,
- /* XFER_PIO_0 */ 0x0ac1f48a
-};
-
-static u32 sixty_six_base_hpt37x[] = {
- /* XFER_UDMA_6 */ 0x1c869c62,
- /* XFER_UDMA_5 */ 0x1cae9c62, /* 0x1c8a9c62 */
- /* XFER_UDMA_4 */ 0x1c8a9c62,
- /* XFER_UDMA_3 */ 0x1c8e9c62,
- /* XFER_UDMA_2 */ 0x1c929c62,
- /* XFER_UDMA_1 */ 0x1c9a9c62,
- /* XFER_UDMA_0 */ 0x1c829c62,
-
- /* XFER_MW_DMA_2 */ 0x2c829c62,
- /* XFER_MW_DMA_1 */ 0x2c829c66,
- /* XFER_MW_DMA_0 */ 0x2c829d2e,
-
- /* XFER_PIO_4 */ 0x0c829c62,
- /* XFER_PIO_3 */ 0x0c829c84,
- /* XFER_PIO_2 */ 0x0c829ca6,
- /* XFER_PIO_1 */ 0x0d029d26,
- /* XFER_PIO_0 */ 0x0d029d5e
-};
-#else
/*
* The following are the new timing tables with PIO mode data/taskfile transfer
* overclocking fixed...
@@ -430,16 +363,13 @@ static u32 sixty_six_base_hpt37x[] = {
/* XFER_PIO_1 */ 0x0d02ff26,
/* XFER_PIO_0 */ 0x0d42ff7f
};
-#endif
-#define HPT366_DEBUG_DRIVE_INFO 0
#define HPT371_ALLOW_ATA133_6 1
#define HPT302_ALLOW_ATA133_6 1
#define HPT372_ALLOW_ATA133_6 1
#define HPT370_ALLOW_ATA100_5 0
#define HPT366_ALLOW_ATA66_4 1
#define HPT366_ALLOW_ATA66_3 1
-#define HPT366_MAX_DEVS 8
/* Supported ATA clock frequencies */
enum ata_clock {
@@ -513,7 +443,7 @@ static struct hpt_timings hpt37x_timings = {
}
};
-static const struct hpt_info hpt36x __devinitdata = {
+static const struct hpt_info hpt36x = {
.chip_name = "HPT36x",
.chip_type = HPT36x,
.udma_mask = HPT366_ALLOW_ATA66_3 ? (HPT366_ALLOW_ATA66_4 ? ATA_UDMA4 : ATA_UDMA3) : ATA_UDMA2,
@@ -521,7 +451,7 @@ static const struct hpt_info hpt36x __devinitdata = {
.timings = &hpt36x_timings
};
-static const struct hpt_info hpt370 __devinitdata = {
+static const struct hpt_info hpt370 = {
.chip_name = "HPT370",
.chip_type = HPT370,
.udma_mask = HPT370_ALLOW_ATA100_5 ? ATA_UDMA5 : ATA_UDMA4,
@@ -529,7 +459,7 @@ static const struct hpt_info hpt370 __devinitdata = {
.timings = &hpt37x_timings
};
-static const struct hpt_info hpt370a __devinitdata = {
+static const struct hpt_info hpt370a = {
.chip_name = "HPT370A",
.chip_type = HPT370A,
.udma_mask = HPT370_ALLOW_ATA100_5 ? ATA_UDMA5 : ATA_UDMA4,
@@ -537,7 +467,7 @@ static const struct hpt_info hpt370a __devinitdata = {
.timings = &hpt37x_timings
};
-static const struct hpt_info hpt374 __devinitdata = {
+static const struct hpt_info hpt374 = {
.chip_name = "HPT374",
.chip_type = HPT374,
.udma_mask = ATA_UDMA5,
@@ -545,7 +475,7 @@ static const struct hpt_info hpt374 __devinitdata = {
.timings = &hpt37x_timings
};
-static const struct hpt_info hpt372 __devinitdata = {
+static const struct hpt_info hpt372 = {
.chip_name = "HPT372",
.chip_type = HPT372,
.udma_mask = HPT372_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5,
@@ -553,7 +483,7 @@ static const struct hpt_info hpt372 __devinitdata = {
.timings = &hpt37x_timings
};
-static const struct hpt_info hpt372a __devinitdata = {
+static const struct hpt_info hpt372a = {
.chip_name = "HPT372A",
.chip_type = HPT372A,
.udma_mask = HPT372_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5,
@@ -561,7 +491,7 @@ static const struct hpt_info hpt372a __devinitdata = {
.timings = &hpt37x_timings
};
-static const struct hpt_info hpt302 __devinitdata = {
+static const struct hpt_info hpt302 = {
.chip_name = "HPT302",
.chip_type = HPT302,
.udma_mask = HPT302_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5,
@@ -569,7 +499,7 @@ static const struct hpt_info hpt302 __devinitdata = {
.timings = &hpt37x_timings
};
-static const struct hpt_info hpt371 __devinitdata = {
+static const struct hpt_info hpt371 = {
.chip_name = "HPT371",
.chip_type = HPT371,
.udma_mask = HPT371_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5,
@@ -577,7 +507,7 @@ static const struct hpt_info hpt371 __devinitdata = {
.timings = &hpt37x_timings
};
-static const struct hpt_info hpt372n __devinitdata = {
+static const struct hpt_info hpt372n = {
.chip_name = "HPT372N",
.chip_type = HPT372N,
.udma_mask = HPT372_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5,
@@ -585,7 +515,7 @@ static const struct hpt_info hpt372n __devinitdata = {
.timings = &hpt37x_timings
};
-static const struct hpt_info hpt302n __devinitdata = {
+static const struct hpt_info hpt302n = {
.chip_name = "HPT302N",
.chip_type = HPT302N,
.udma_mask = HPT302_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5,
@@ -593,7 +523,7 @@ static const struct hpt_info hpt302n __devinitdata = {
.timings = &hpt37x_timings
};
-static const struct hpt_info hpt371n __devinitdata = {
+static const struct hpt_info hpt371n = {
.chip_name = "HPT371N",
.chip_type = HPT371N,
.udma_mask = HPT371_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5,
@@ -698,14 +628,14 @@ static u32 get_speed_setting(u8 speed, struct hpt_info *info)
return info->timings->clock_table[info->clock][i];
}
-static void hpt3xx_set_mode(ide_drive_t *drive, const u8 speed)
+static void hpt3xx_set_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
- ide_hwif_t *hwif = drive->hwif;
struct pci_dev *dev = to_pci_dev(hwif->dev);
struct hpt_info *info = hpt3xx_get_info(hwif->dev);
struct hpt_timings *t = info->timings;
u8 itr_addr = 0x40 + (drive->dn * 4);
u32 old_itr = 0;
+ const u8 speed = drive->dma_mode;
u32 new_itr = get_speed_setting(speed, info);
u32 itr_mask = speed < XFER_MW_DMA_0 ? t->pio_mask :
(speed < XFER_UDMA_0 ? t->dma_mask :
@@ -722,23 +652,10 @@ static void hpt3xx_set_mode(ide_drive_t *drive, const u8 speed)
pci_write_config_dword(dev, itr_addr, new_itr);
}
-static void hpt3xx_set_pio_mode(ide_drive_t *drive, const u8 pio)
-{
- hpt3xx_set_mode(drive, XFER_PIO_0 + pio);
-}
-
-static void hpt3xx_quirkproc(ide_drive_t *drive)
+static void hpt3xx_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
- char *m = (char *)&drive->id[ATA_ID_PROD];
- const char **list = quirk_drives;
-
- while (*list)
- if (strstr(m, *list++)) {
- drive->quirk_list = 1;
- return;
- }
-
- drive->quirk_list = 0;
+ drive->dma_mode = drive->pio_mode;
+ hpt3xx_set_mode(hwif, drive);
}
static void hpt3xx_maskproc(ide_drive_t *drive, int mask)
@@ -747,7 +664,7 @@ static void hpt3xx_maskproc(ide_drive_t *drive, int mask)
struct pci_dev *dev = to_pci_dev(hwif->dev);
struct hpt_info *info = hpt3xx_get_info(hwif->dev);
- if (drive->quirk_list == 0)
+ if ((drive->dev_flags & IDE_DFLAG_NIEN_QUIRK) == 0)
return;
if (info->chip_type >= HPT370) {
@@ -808,7 +725,7 @@ static void hpt370_irq_timeout(ide_drive_t *drive)
/* get DMA command mode */
dma_cmd = inb(hwif->dma_base + ATA_DMA_CMD);
/* stop DMA */
- outb(dma_cmd & ~0x1, hwif->dma_base + ATA_DMA_CMD);
+ outb(dma_cmd & ~ATA_DMA_START, hwif->dma_base + ATA_DMA_CMD);
hpt370_clear_engine(drive);
}
@@ -825,11 +742,11 @@ static int hpt370_dma_end(ide_drive_t *drive)
ide_hwif_t *hwif = drive->hwif;
u8 dma_stat = inb(hwif->dma_base + ATA_DMA_STATUS);
- if (dma_stat & 0x01) {
+ if (dma_stat & ATA_DMA_ACTIVE) {
/* wait a little */
udelay(20);
dma_stat = inb(hwif->dma_base + ATA_DMA_STATUS);
- if (dma_stat & 0x01)
+ if (dma_stat & ATA_DMA_ACTIVE)
hpt370_irq_timeout(drive);
}
return ide_dma_end(drive);
@@ -851,7 +768,7 @@ static int hpt374_dma_test_irq(ide_drive_t *drive)
dma_stat = inb(hwif->dma_base + ATA_DMA_STATUS);
/* return 1 if INTR asserted */
- if (dma_stat & 4)
+ if (dma_stat & ATA_DMA_INTR)
return 1;
return 0;
@@ -921,7 +838,7 @@ static void hpt3xxn_set_clock(ide_hwif_t *hwif, u8 mode)
static void hpt3xxn_rw_disk(ide_drive_t *drive, struct request *rq)
{
- hpt3xxn_set_clock(drive->hwif, rq_data_dir(rq) ? 0x23 : 0x21);
+ hpt3xxn_set_clock(drive->hwif, rq_data_dir(rq) ? 0x21 : 0x23);
}
/**
@@ -1256,8 +1173,9 @@ static u8 hpt3xx_cable_detect(ide_hwif_t *hwif)
u16 mcr;
pci_read_config_word(dev, mcr_addr, &mcr);
- pci_write_config_word(dev, mcr_addr, (mcr | 0x8000));
- /* now read cable id register */
+ pci_write_config_word(dev, mcr_addr, mcr | 0x8000);
+ /* Debounce, then read cable ID register */
+ udelay(10);
pci_read_config_byte(dev, 0x5a, &scr1);
pci_write_config_word(dev, mcr_addr, mcr);
} else if (chip_type >= HPT370) {
@@ -1268,17 +1186,18 @@ static u8 hpt3xx_cable_detect(ide_hwif_t *hwif)
u8 scr2 = 0;
pci_read_config_byte(dev, 0x5b, &scr2);
- pci_write_config_byte(dev, 0x5b, (scr2 & ~1));
- /* now read cable id register */
+ pci_write_config_byte(dev, 0x5b, scr2 & ~1);
+ /* Debounce, then read cable ID register */
+ udelay(10);
pci_read_config_byte(dev, 0x5a, &scr1);
- pci_write_config_byte(dev, 0x5b, scr2);
+ pci_write_config_byte(dev, 0x5b, scr2);
} else
pci_read_config_byte(dev, 0x5a, &scr1);
return (scr1 & ata66) ? ATA_CBL_PATA40 : ATA_CBL_PATA80;
}
-static void __devinit init_hwif_hpt366(ide_hwif_t *hwif)
+static void init_hwif_hpt366(ide_hwif_t *hwif)
{
struct hpt_info *info = hpt3xx_get_info(hwif->dev);
u8 chip_type = info->chip_type;
@@ -1302,7 +1221,7 @@ static void __devinit init_hwif_hpt366(ide_hwif_t *hwif)
}
}
-static int __devinit init_dma_hpt366(ide_hwif_t *hwif,
+static int init_dma_hpt366(ide_hwif_t *hwif,
const struct ide_port_info *d)
{
struct pci_dev *dev = to_pci_dev(hwif->dev);
@@ -1346,7 +1265,7 @@ static int __devinit init_dma_hpt366(ide_hwif_t *hwif,
return 0;
}
-static void __devinit hpt374_init(struct pci_dev *dev, struct pci_dev *dev2)
+static void hpt374_init(struct pci_dev *dev, struct pci_dev *dev2)
{
if (dev2->irq != dev->irq) {
/* FIXME: we need a core pci_set_interrupt() */
@@ -1356,7 +1275,7 @@ static void __devinit hpt374_init(struct pci_dev *dev, struct pci_dev *dev2)
}
}
-static void __devinit hpt371_init(struct pci_dev *dev)
+static void hpt371_init(struct pci_dev *dev)
{
u8 mcr1 = 0;
@@ -1371,7 +1290,7 @@ static void __devinit hpt371_init(struct pci_dev *dev)
pci_write_config_byte(dev, 0x50, mcr1 & ~0x04);
}
-static int __devinit hpt36x_init(struct pci_dev *dev, struct pci_dev *dev2)
+static int hpt36x_init(struct pci_dev *dev, struct pci_dev *dev2)
{
u8 mcr1 = 0, pin1 = 0, pin2 = 0;
@@ -1402,7 +1321,6 @@ static int __devinit hpt36x_init(struct pci_dev *dev, struct pci_dev *dev2)
static const struct ide_port_ops hpt3xx_port_ops = {
.set_pio_mode = hpt3xx_set_pio_mode,
.set_dma_mode = hpt3xx_set_mode,
- .quirkproc = hpt3xx_quirkproc,
.maskproc = hpt3xx_maskproc,
.mdma_filter = hpt3xx_mdma_filter,
.udma_filter = hpt3xx_udma_filter,
@@ -1443,7 +1361,7 @@ static const struct ide_dma_ops hpt36x_dma_ops = {
.dma_sff_read_status = ide_dma_sff_read_status,
};
-static const struct ide_port_info hpt366_chipsets[] __devinitdata = {
+static const struct ide_port_info hpt366_chipsets[] = {
{ /* 0: HPT36x */
.name = DRV_NAME,
.init_chipset = init_chipset_hpt366,
@@ -1484,7 +1402,7 @@ static const struct ide_port_info hpt366_chipsets[] __devinitdata = {
* Called when the PCI registration layer (or the IDE initialization)
* finds a device matching our IDE device tables.
*/
-static int __devinit hpt366_init_one(struct pci_dev *dev, const struct pci_device_id *id)
+static int hpt366_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
const struct hpt_info *info = NULL;
struct hpt_info *dyn_info;
@@ -1581,7 +1499,7 @@ static int __devinit hpt366_init_one(struct pci_dev *dev, const struct pci_devic
return ret;
}
-static void __devexit hpt366_remove(struct pci_dev *dev)
+static void hpt366_remove(struct pci_dev *dev)
{
struct ide_host *host = pci_get_drvdata(dev);
struct ide_info *info = host->host_priv;
@@ -1592,7 +1510,7 @@ static void __devexit hpt366_remove(struct pci_dev *dev)
kfree(info);
}
-static const struct pci_device_id hpt366_pci_tbl[] __devinitconst = {
+static const struct pci_device_id hpt366_pci_tbl[] = {
{ PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT366), 0 },
{ PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT372), 1 },
{ PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT302), 2 },
@@ -1607,7 +1525,7 @@ static struct pci_driver hpt366_pci_driver = {
.name = "HPT366_IDE",
.id_table = hpt366_pci_tbl,
.probe = hpt366_init_one,
- .remove = __devexit_p(hpt366_remove),
+ .remove = hpt366_remove,
.suspend = ide_pci_suspend,
.resume = ide_pci_resume,
};