From 1eedb4a90c958d8d59e0e4f19c297b445df21cf9 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sat, 29 Nov 2008 22:37:21 +0900 Subject: ata_piix: add borked Tecra M4 to broken suspend list Tecra M4 sometimes forget what it is and reports bogus data via DMI which makes the machine evade broken suspend matching and thus fail suspend/resume. This patch updates piix_broken_suspend() such that it can match such case. As the borked DMI data is a bit generic, matching many entries to make the match more specific is necessary. As the usual DMI matching is limited to four entries, this patch uses hard coded manual matching. This is reported by Alexandru Romanescu. Signed-off-by: Tejun Heo Cc: Alexandru Romanescu Signed-off-by: Jeff Garzik --- drivers/ata/ata_piix.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c index 8e37be19bbf..d6d97d8f3fa 100644 --- a/drivers/ata/ata_piix.c +++ b/drivers/ata/ata_piix.c @@ -1066,6 +1066,21 @@ static int piix_broken_suspend(void) if (dmi_find_device(DMI_DEV_TYPE_OEM_STRING, oemstrs[i], NULL)) return 1; + /* TECRA M4 sometimes forgets its identify and reports bogus + * DMI information. As the bogus information is a bit + * generic, match as many entries as possible. This manual + * matching is necessary because dmi_system_id.matches is + * limited to four entries. + */ + if (!strcmp(dmi_get_system_info(DMI_SYS_VENDOR), "TOSHIBA") && + !strcmp(dmi_get_system_info(DMI_PRODUCT_NAME), "000000") && + !strcmp(dmi_get_system_info(DMI_PRODUCT_VERSION), "000000") && + !strcmp(dmi_get_system_info(DMI_PRODUCT_SERIAL), "000000") && + !strcmp(dmi_get_system_info(DMI_BOARD_VENDOR), "TOSHIBA") && + !strcmp(dmi_get_system_info(DMI_BOARD_NAME), "Portable PC") && + !strcmp(dmi_get_system_info(DMI_BOARD_VERSION), "Version A0")) + return 1; + return 0; } -- cgit v1.2.3 From 9f14786e27908a176f0568cf2132558efef71b31 Mon Sep 17 00:00:00 2001 From: Phil Sutter Date: Fri, 28 Nov 2008 20:48:26 +0100 Subject: [libata] pata_rb532_cf: fix and rename register definitions The original standalone driver uses a custom address for the error register. Use it in pata_rb532_cf, too. Rename two register definitions: - The address offset 0x0800 in fact is the ATA base, not ATA command address. - The offset 0x0C00 is not a regular ATA data address, but a buffered one allowing 4-byte IO. Signed-off-by: Phil Sutter Signed-off-by: Jeff Garzik --- drivers/ata/pata_rb532_cf.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/ata/pata_rb532_cf.c b/drivers/ata/pata_rb532_cf.c index f8b3ffc8ae9..392116c1c16 100644 --- a/drivers/ata/pata_rb532_cf.c +++ b/drivers/ata/pata_rb532_cf.c @@ -39,9 +39,11 @@ #define RB500_CF_MAXPORTS 1 #define RB500_CF_IO_DELAY 400 -#define RB500_CF_REG_CMD 0x0800 +#define RB500_CF_REG_BASE 0x0800 +#define RB500_CF_REG_ERR 0x080D #define RB500_CF_REG_CTRL 0x080E -#define RB500_CF_REG_DATA 0x0C00 +/* 32bit buffered data register offset */ +#define RB500_CF_REG_DBUF32 0x0C00 struct rb532_cf_info { void __iomem *iobase; @@ -146,13 +148,14 @@ static void rb532_pata_setup_ports(struct ata_host *ah) ap->pio_mask = 0x1f; /* PIO4 */ ap->flags = ATA_FLAG_NO_LEGACY | ATA_FLAG_MMIO; - ap->ioaddr.cmd_addr = info->iobase + RB500_CF_REG_CMD; + ap->ioaddr.cmd_addr = info->iobase + RB500_CF_REG_BASE; ap->ioaddr.ctl_addr = info->iobase + RB500_CF_REG_CTRL; ap->ioaddr.altstatus_addr = info->iobase + RB500_CF_REG_CTRL; ata_sff_std_ports(&ap->ioaddr); - ap->ioaddr.data_addr = info->iobase + RB500_CF_REG_DATA; + ap->ioaddr.data_addr = info->iobase + RB500_CF_REG_DBUF32; + ap->ioaddr.error_addr = info->iobase + RB500_CF_REG_ERR; } static __devinit int rb532_pata_driver_probe(struct platform_device *pdev) -- cgit v1.2.3 From 03f60840fa462e92220b093f778b2426ceab23af Mon Sep 17 00:00:00 2001 From: Phil Sutter Date: Fri, 28 Nov 2008 20:48:35 +0100 Subject: [libata] pata_rb532_cf: fix signature of the xfer function Per definition, this function should return the number of bytes consumed. As the original parameter "buflen" is being decremented inside the read/write loop, save it in "retlen" at the beginning. Signed-off-by: Phil Sutter Acked-by: Sergei Shtyltov Acked-by: Bartlomiej Zolnierkiewicz Acked-by: Florian Fainelli Signed-off-by: Jeff Garzik --- drivers/ata/pata_rb532_cf.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/ata/pata_rb532_cf.c b/drivers/ata/pata_rb532_cf.c index 392116c1c16..c2e6fb9f2ef 100644 --- a/drivers/ata/pata_rb532_cf.c +++ b/drivers/ata/pata_rb532_cf.c @@ -74,11 +74,12 @@ static void rb532_pata_exec_command(struct ata_port *ap, rb532_pata_finish_io(ap); } -static void rb532_pata_data_xfer(struct ata_device *adev, unsigned char *buf, +static unsigned int rb532_pata_data_xfer(struct ata_device *adev, unsigned char *buf, unsigned int buflen, int write_data) { struct ata_port *ap = adev->link->ap; void __iomem *ioaddr = ap->ioaddr.data_addr; + int retlen = buflen; if (write_data) { for (; buflen > 0; buflen--, buf++) @@ -89,6 +90,7 @@ static void rb532_pata_data_xfer(struct ata_device *adev, unsigned char *buf, } rb532_pata_finish_io(adev->link->ap); + return retlen; } static void rb532_pata_freeze(struct ata_port *ap) -- cgit v1.2.3 From ac70a964b0e22a95af3628c344815857a01461b7 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Thu, 27 Nov 2008 13:36:48 +0900 Subject: libata: blacklist Seagate drives which time out FLUSH_CACHE when used with NCQ Some recent Seagate harddrives have firmware bug which causes FLUSH CACHE to timeout under certain circumstances if NCQ is being used. This can be worked around by disabling NCQ and fixed by updating the firmware. Implement ATA_HORKAGE_FIRMWARE_UPDATE and blacklist these devices. The wiki page has been updated to contain information on this issue. http://ata.wiki.kernel.org/index.php/Known_issues Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- drivers/ata/libata-core.c | 21 +++++++++++++++++++++ include/linux/libata.h | 1 + 2 files changed, 22 insertions(+) diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 4214bfb13bb..5e2eb740df4 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -2492,6 +2492,13 @@ int ata_dev_configure(struct ata_device *dev) } } + if ((dev->horkage & ATA_HORKAGE_FIRMWARE_WARN) && print_info) { + ata_dev_printk(dev, KERN_WARNING, "WARNING: device requires " + "firmware update to be fully functional.\n"); + ata_dev_printk(dev, KERN_WARNING, " contact the vendor " + "or visit http://ata.wiki.kernel.org.\n"); + } + return 0; err_out_nosup: @@ -4042,6 +4049,20 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = { { "ST380817AS", "3.42", ATA_HORKAGE_NONCQ }, { "ST3160023AS", "3.42", ATA_HORKAGE_NONCQ }, + /* Seagate NCQ + FLUSH CACHE firmware bug */ + { "ST31500341AS", "9JU138", ATA_HORKAGE_NONCQ | + ATA_HORKAGE_FIRMWARE_WARN }, + { "ST31000333AS", "9FZ136", ATA_HORKAGE_NONCQ | + ATA_HORKAGE_FIRMWARE_WARN }, + { "ST3640623AS", "9FZ164", ATA_HORKAGE_NONCQ | + ATA_HORKAGE_FIRMWARE_WARN }, + { "ST3640323AS", "9FZ134", ATA_HORKAGE_NONCQ | + ATA_HORKAGE_FIRMWARE_WARN }, + { "ST3320813AS", "9FZ182", ATA_HORKAGE_NONCQ | + ATA_HORKAGE_FIRMWARE_WARN }, + { "ST3320613AS", "9FZ162", ATA_HORKAGE_NONCQ | + ATA_HORKAGE_FIRMWARE_WARN }, + /* Blacklist entries taken from Silicon Image 3124/3132 Windows driver .inf file - also several Linux problem reports */ { "HTS541060G9SA00", "MB3OC60D", ATA_HORKAGE_NONCQ, }, diff --git a/include/linux/libata.h b/include/linux/libata.h index 59b0f1c807b..ed3f26eb5df 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -375,6 +375,7 @@ enum { ATA_HORKAGE_BRIDGE_OK = (1 << 10), /* no bridge limits */ ATA_HORKAGE_ATAPI_MOD16_DMA = (1 << 11), /* use ATAPI DMA for commands not multiple of 16 bytes */ + ATA_HORKAGE_FIRMWARE_WARN = (1 << 12), /* firwmare update warning */ /* DMA mask for user DMA control: User visible values; DO NOT renumber */ -- cgit v1.2.3