summaryrefslogtreecommitdiff
path: root/drivers/ata/pata_hpt37x.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ata/pata_hpt37x.c')
-rw-r--r--drivers/ata/pata_hpt37x.c258
1 files changed, 154 insertions, 104 deletions
diff --git a/drivers/ata/pata_hpt37x.c b/drivers/ata/pata_hpt37x.c
index 9ae4c0830577..4c5b5183225e 100644
--- a/drivers/ata/pata_hpt37x.c
+++ b/drivers/ata/pata_hpt37x.c
@@ -8,7 +8,7 @@
* Copyright (C) 1999-2003 Andre Hedrick <andre@linux-ide.org>
* Portions Copyright (C) 2001 Sun Microsystems, Inc.
* Portions Copyright (C) 2003 Red Hat Inc
- * Portions Copyright (C) 2005-2009 MontaVista Software, Inc.
+ * Portions Copyright (C) 2005-2010 MontaVista Software, Inc.
*
* TODO
* Look into engine reset on timeout errors. Should not be required.
@@ -24,7 +24,7 @@
#include <linux/libata.h>
#define DRV_NAME "pata_hpt37x"
-#define DRV_VERSION "0.6.15"
+#define DRV_VERSION "0.6.22"
struct hpt_clock {
u8 xfer_speed;
@@ -210,7 +210,7 @@ static u32 hpt37x_find_mode(struct ata_port *ap, int speed)
{
struct hpt_clock *clocks = ap->host->private_data;
- while(clocks->xfer_speed) {
+ while (clocks->xfer_speed) {
if (clocks->xfer_speed == speed)
return clocks->timing;
clocks++;
@@ -219,7 +219,8 @@ static u32 hpt37x_find_mode(struct ata_port *ap, int speed)
return 0xffffffffU; /* silence compiler warning */
}
-static int hpt_dma_blacklisted(const struct ata_device *dev, char *modestr, const char *list[])
+static int hpt_dma_blacklisted(const struct ata_device *dev, char *modestr,
+ const char * const list[])
{
unsigned char model_num[ATA_ID_PROD_LEN + 1];
int i = 0;
@@ -228,8 +229,8 @@ static int hpt_dma_blacklisted(const struct ata_device *dev, char *modestr, cons
while (list[i] != NULL) {
if (!strcmp(list[i], model_num)) {
- printk(KERN_WARNING DRV_NAME ": %s is not supported for %s.\n",
- modestr, list[i]);
+ pr_warning(DRV_NAME ": %s is not supported for %s.\n",
+ modestr, list[i]);
return 1;
}
i++;
@@ -237,18 +238,23 @@ static int hpt_dma_blacklisted(const struct ata_device *dev, char *modestr, cons
return 0;
}
-static const char *bad_ata33[] = {
- "Maxtor 92720U8", "Maxtor 92040U6", "Maxtor 91360U4", "Maxtor 91020U3", "Maxtor 90845U3", "Maxtor 90650U2",
- "Maxtor 91360D8", "Maxtor 91190D7", "Maxtor 91020D6", "Maxtor 90845D5", "Maxtor 90680D4", "Maxtor 90510D3", "Maxtor 90340D2",
- "Maxtor 91152D8", "Maxtor 91008D7", "Maxtor 90845D6", "Maxtor 90840D6", "Maxtor 90720D5", "Maxtor 90648D5", "Maxtor 90576D4",
+static const char * const bad_ata33[] = {
+ "Maxtor 92720U8", "Maxtor 92040U6", "Maxtor 91360U4", "Maxtor 91020U3",
+ "Maxtor 90845U3", "Maxtor 90650U2",
+ "Maxtor 91360D8", "Maxtor 91190D7", "Maxtor 91020D6", "Maxtor 90845D5",
+ "Maxtor 90680D4", "Maxtor 90510D3", "Maxtor 90340D2",
+ "Maxtor 91152D8", "Maxtor 91008D7", "Maxtor 90845D6", "Maxtor 90840D6",
+ "Maxtor 90720D5", "Maxtor 90648D5", "Maxtor 90576D4",
"Maxtor 90510D4",
"Maxtor 90432D3", "Maxtor 90288D2", "Maxtor 90256D2",
- "Maxtor 91000D8", "Maxtor 90910D8", "Maxtor 90875D7", "Maxtor 90840D7", "Maxtor 90750D6", "Maxtor 90625D5", "Maxtor 90500D4",
- "Maxtor 91728D8", "Maxtor 91512D7", "Maxtor 91303D6", "Maxtor 91080D5", "Maxtor 90845D4", "Maxtor 90680D4", "Maxtor 90648D3", "Maxtor 90432D2",
+ "Maxtor 91000D8", "Maxtor 90910D8", "Maxtor 90875D7", "Maxtor 90840D7",
+ "Maxtor 90750D6", "Maxtor 90625D5", "Maxtor 90500D4",
+ "Maxtor 91728D8", "Maxtor 91512D7", "Maxtor 91303D6", "Maxtor 91080D5",
+ "Maxtor 90845D4", "Maxtor 90680D4", "Maxtor 90648D3", "Maxtor 90432D2",
NULL
};
-static const char *bad_ata100_5[] = {
+static const char * const bad_ata100_5[] = {
"IBM-DTLA-307075",
"IBM-DTLA-307060",
"IBM-DTLA-307045",
@@ -302,6 +308,22 @@ static unsigned long hpt370a_filter(struct ata_device *adev, unsigned long mask)
}
/**
+ * hpt372_filter - mode selection filter
+ * @adev: ATA device
+ * @mask: mode mask
+ *
+ * The Marvell bridge chips used on the HighPoint SATA cards do not seem
+ * to support the UltraDMA modes 1, 2, and 3 as well as any MWDMA modes...
+ */
+static unsigned long hpt372_filter(struct ata_device *adev, unsigned long mask)
+{
+ if (ata_id_is_sata(adev->id))
+ mask &= ~((0xE << ATA_SHIFT_UDMA) | ATA_MASK_MWDMA);
+
+ return mask;
+}
+
+/**
* hpt37x_cable_detect - Detect the cable type
* @ap: ATA port to detect on
*
@@ -373,6 +395,7 @@ static int hpt37x_pre_reset(struct ata_link *link, unsigned long deadline)
{ 0x50, 1, 0x04, 0x04 },
{ 0x54, 1, 0x04, 0x04 }
};
+
if (!pci_test_config_bits(pdev, &hpt37x_enable_bits[ap->port_no]))
return -ENOENT;
@@ -586,11 +609,11 @@ static struct ata_port_operations hpt370a_port_ops = {
};
/*
- * Configuration for HPT372, HPT371, HPT302. Slightly different PIO
- * and DMA mode setting functionality.
+ * Configuration for HPT371 and HPT302. Slightly different PIO and DMA
+ * mode setting functionality.
*/
-static struct ata_port_operations hpt372_port_ops = {
+static struct ata_port_operations hpt302_port_ops = {
.inherits = &ata_bmdma_port_ops,
.bmdma_stop = hpt37x_bmdma_stop,
@@ -602,14 +625,23 @@ static struct ata_port_operations hpt372_port_ops = {
};
/*
- * Configuration for HPT374. Mode setting works like 372 and friends
+ * Configuration for HPT372. Mode setting works like 371 and 302
+ * but we have a mode filter.
+ */
+
+static struct ata_port_operations hpt372_port_ops = {
+ .inherits = &hpt302_port_ops,
+ .mode_filter = hpt372_filter,
+};
+
+/*
+ * Configuration for HPT374. Mode setting and filtering works like 372
* but we have a different cable detection procedure for function 1.
*/
static struct ata_port_operations hpt374_fn1_port_ops = {
.inherits = &hpt372_port_ops,
.cable_detect = hpt374_fn1_cable_detect,
- .prereset = hpt37x_pre_reset,
};
/**
@@ -647,12 +679,12 @@ static int hpt37x_calibrate_dpll(struct pci_dev *dev)
u32 reg5c;
int tries;
- for(tries = 0; tries < 0x5000; tries++) {
+ for (tries = 0; tries < 0x5000; tries++) {
udelay(50);
pci_read_config_byte(dev, 0x5b, &reg5b);
if (reg5b & 0x80) {
/* See if it stays set */
- for(tries = 0; tries < 0x1000; tries ++) {
+ for (tries = 0; tries < 0x1000; tries++) {
pci_read_config_byte(dev, 0x5b, &reg5b);
/* Failed ? */
if ((reg5b & 0x80) == 0)
@@ -660,7 +692,7 @@ static int hpt37x_calibrate_dpll(struct pci_dev *dev)
}
/* Turn off tuning, we have the DPLL set */
pci_read_config_dword(dev, 0x5c, &reg5c);
- pci_write_config_dword(dev, 0x5c, reg5c & ~ 0x100);
+ pci_write_config_dword(dev, 0x5c, reg5c & ~0x100);
return 1;
}
}
@@ -672,6 +704,7 @@ static u32 hpt374_read_freq(struct pci_dev *pdev)
{
u32 freq;
unsigned long io_base = pci_resource_start(pdev, 4);
+
if (PCI_FUNC(pdev->devfn) & 1) {
struct pci_dev *pdev_0;
@@ -737,23 +770,23 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
.udma_mask = ATA_UDMA5,
.port_ops = &hpt370a_port_ops
};
- /* HPT370 - UDMA100 */
+ /* HPT370 - UDMA66 */
static const struct ata_port_info info_hpt370_33 = {
.flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = ATA_PIO4,
.mwdma_mask = ATA_MWDMA2,
- .udma_mask = ATA_UDMA5,
+ .udma_mask = ATA_UDMA4,
.port_ops = &hpt370_port_ops
};
- /* HPT370A - UDMA100 */
+ /* HPT370A - UDMA66 */
static const struct ata_port_info info_hpt370a_33 = {
.flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = ATA_PIO4,
.mwdma_mask = ATA_MWDMA2,
- .udma_mask = ATA_UDMA5,
+ .udma_mask = ATA_UDMA4,
.port_ops = &hpt370a_port_ops
};
- /* HPT371, 372 and friends - UDMA133 */
+ /* HPT372 - UDMA133 */
static const struct ata_port_info info_hpt372 = {
.flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = ATA_PIO4,
@@ -761,7 +794,15 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
.udma_mask = ATA_UDMA6,
.port_ops = &hpt372_port_ops
};
- /* HPT374 - UDMA100, function 1 uses different prereset method */
+ /* HPT371, 302 - UDMA133 */
+ static const struct ata_port_info info_hpt302 = {
+ .flags = ATA_FLAG_SLAVE_POSS,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
+ .udma_mask = ATA_UDMA6,
+ .port_ops = &hpt302_port_ops
+ };
+ /* HPT374 - UDMA100, function 1 uses different cable_detect method */
static const struct ata_port_info info_hpt374_fn0 = {
.flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = ATA_PIO4,
@@ -796,7 +837,8 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
if (rc)
return rc;
- if (dev->device == PCI_DEVICE_ID_TTI_HPT366) {
+ switch (dev->device) {
+ case PCI_DEVICE_ID_TTI_HPT366:
/* May be a later chip in disguise. Check */
/* Older chips are in the HPT366 driver. Ignore them */
if (rev < 3)
@@ -805,66 +847,66 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
if (rev == 6)
return -ENODEV;
- switch(rev) {
- case 3:
- ppi[0] = &info_hpt370;
- chip_table = &hpt370;
- prefer_dpll = 0;
- break;
- case 4:
- ppi[0] = &info_hpt370a;
- chip_table = &hpt370a;
- prefer_dpll = 0;
- break;
- case 5:
- ppi[0] = &info_hpt372;
- chip_table = &hpt372;
- break;
- default:
- printk(KERN_ERR "pata_hpt37x: Unknown HPT366 "
- "subtype, please report (%d).\n", rev);
- return -ENODEV;
- }
- } else {
- switch(dev->device) {
- case PCI_DEVICE_ID_TTI_HPT372:
- /* 372N if rev >= 2*/
- if (rev >= 2)
- return -ENODEV;
- ppi[0] = &info_hpt372;
- chip_table = &hpt372a;
- break;
- case PCI_DEVICE_ID_TTI_HPT302:
- /* 302N if rev > 1 */
- if (rev > 1)
- return -ENODEV;
- ppi[0] = &info_hpt372;
- /* Check this */
- chip_table = &hpt302;
- break;
- case PCI_DEVICE_ID_TTI_HPT371:
- if (rev > 1)
- return -ENODEV;
- ppi[0] = &info_hpt372;
- chip_table = &hpt371;
- /* Single channel device, master is not present
- but the BIOS (or us for non x86) must mark it
- absent */
- pci_read_config_byte(dev, 0x50, &mcr1);
- mcr1 &= ~0x04;
- pci_write_config_byte(dev, 0x50, mcr1);
- break;
- case PCI_DEVICE_ID_TTI_HPT374:
- chip_table = &hpt374;
- if (!(PCI_FUNC(dev->devfn) & 1))
- *ppi = &info_hpt374_fn0;
- else
- *ppi = &info_hpt374_fn1;
- break;
- default:
- printk(KERN_ERR "pata_hpt37x: PCI table is bogus please report (%d).\n", dev->device);
- return -ENODEV;
+ switch (rev) {
+ case 3:
+ ppi[0] = &info_hpt370;
+ chip_table = &hpt370;
+ prefer_dpll = 0;
+ break;
+ case 4:
+ ppi[0] = &info_hpt370a;
+ chip_table = &hpt370a;
+ prefer_dpll = 0;
+ break;
+ case 5:
+ ppi[0] = &info_hpt372;
+ chip_table = &hpt372;
+ break;
+ default:
+ pr_err(DRV_NAME ": Unknown HPT366 subtype, "
+ "please report (%d).\n", rev);
+ return -ENODEV;
}
+ break;
+ case PCI_DEVICE_ID_TTI_HPT372:
+ /* 372N if rev >= 2 */
+ if (rev >= 2)
+ return -ENODEV;
+ ppi[0] = &info_hpt372;
+ chip_table = &hpt372a;
+ break;
+ case PCI_DEVICE_ID_TTI_HPT302:
+ /* 302N if rev > 1 */
+ if (rev > 1)
+ return -ENODEV;
+ ppi[0] = &info_hpt302;
+ /* Check this */
+ chip_table = &hpt302;
+ break;
+ case PCI_DEVICE_ID_TTI_HPT371:
+ if (rev > 1)
+ return -ENODEV;
+ ppi[0] = &info_hpt302;
+ chip_table = &hpt371;
+ /*
+ * Single channel device, master is not present but the BIOS
+ * (or us for non x86) must mark it absent
+ */
+ pci_read_config_byte(dev, 0x50, &mcr1);
+ mcr1 &= ~0x04;
+ pci_write_config_byte(dev, 0x50, mcr1);
+ break;
+ case PCI_DEVICE_ID_TTI_HPT374:
+ chip_table = &hpt374;
+ if (!(PCI_FUNC(dev->devfn) & 1))
+ *ppi = &info_hpt374_fn0;
+ else
+ *ppi = &info_hpt374_fn1;
+ break;
+ default:
+ pr_err(DRV_NAME ": PCI table is bogus, please report (%d).\n",
+ dev->device);
+ return -ENODEV;
}
/* Ok so this is a chip we support */
@@ -893,9 +935,11 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
if (chip_table == &hpt372a)
outb(0x0e, iobase + 0x9c);
- /* Some devices do not let this value be accessed via PCI space
- according to the old driver. In addition we must use the value
- from FN 0 on the HPT374 */
+ /*
+ * Some devices do not let this value be accessed via PCI space
+ * according to the old driver. In addition we must use the value
+ * from FN 0 on the HPT374.
+ */
if (chip_table == &hpt374) {
freq = hpt374_read_freq(dev);
@@ -909,10 +953,10 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
u8 sr;
u32 total = 0;
- printk(KERN_WARNING "pata_hpt37x: BIOS has not set timing clocks.\n");
+ pr_warning(DRV_NAME ": BIOS has not set timing clocks.\n");
/* This is the process the HPT371 BIOS is reported to use */
- for(i = 0; i < 128; i++) {
+ for (i = 0; i < 128; i++) {
pci_read_config_byte(dev, 0x78, &sr);
total += sr & 0x1FF;
udelay(15);
@@ -947,20 +991,25 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
/* Select the DPLL clock. */
pci_write_config_byte(dev, 0x5b, 0x21);
- pci_write_config_dword(dev, 0x5C, (f_high << 16) | f_low | 0x100);
+ pci_write_config_dword(dev, 0x5C,
+ (f_high << 16) | f_low | 0x100);
- for(adjust = 0; adjust < 8; adjust++) {
+ for (adjust = 0; adjust < 8; adjust++) {
if (hpt37x_calibrate_dpll(dev))
break;
- /* See if it'll settle at a fractionally different clock */
+ /*
+ * See if it'll settle at a fractionally
+ * different clock
+ */
if (adjust & 1)
f_low -= adjust >> 1;
else
f_high += adjust >> 1;
- pci_write_config_dword(dev, 0x5C, (f_high << 16) | f_low | 0x100);
+ pci_write_config_dword(dev, 0x5C,
+ (f_high << 16) | f_low | 0x100);
}
if (adjust == 8) {
- printk(KERN_ERR "pata_hpt37x: DPLL did not stabilize!\n");
+ pr_err(DRV_NAME ": DPLL did not stabilize!\n");
return -ENODEV;
}
if (dpll == 3)
@@ -968,22 +1017,23 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
else
private_data = (void *)hpt37x_timings_50;
- printk(KERN_INFO "pata_hpt37x: bus clock %dMHz, using %dMHz DPLL.\n",
- MHz[clock_slot], MHz[dpll]);
+ pr_info(DRV_NAME ": bus clock %dMHz, using %dMHz DPLL.\n",
+ MHz[clock_slot], MHz[dpll]);
} else {
private_data = (void *)chip_table->clocks[clock_slot];
/*
* Perform a final fixup. Note that we will have used the
* DPLL on the HPT372 which means we don't have to worry
* about lack of UDMA133 support on lower clocks
- */
+ */
if (clock_slot < 2 && ppi[0] == &info_hpt370)
ppi[0] = &info_hpt370_33;
if (clock_slot < 2 && ppi[0] == &info_hpt370a)
ppi[0] = &info_hpt370a_33;
- printk(KERN_INFO "pata_hpt37x: %s using %dMHz bus clock.\n",
- chip_table->name, MHz[clock_slot]);
+
+ pr_info(DRV_NAME ": %s using %dMHz bus clock.\n",
+ chip_table->name, MHz[clock_slot]);
}
/* Now kick off ATA set up */
@@ -1001,9 +1051,9 @@ static const struct pci_device_id hpt37x[] = {
};
static struct pci_driver hpt37x_pci_driver = {
- .name = DRV_NAME,
+ .name = DRV_NAME,
.id_table = hpt37x,
- .probe = hpt37x_init_one,
+ .probe = hpt37x_init_one,
.remove = ata_pci_remove_one
};