From 9bd7496f5dd488e109e91d9d5743915fb4dfbfde Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Wed, 21 Oct 2009 08:55:28 +0000 Subject: ide: Serialize CMD643 and CMD646 to fix a hardware bug with SSD CMD646 corrupts data on concurrent transfers on both channels when IDE SSD is connected to one of the channels. Setup that demonstrates this hardware bug: Ultra 5, onboard CMD646, rev 3. /dev/hda is 8GB Seagate ST38410A in MWDMA2 /dev/hdd is 32GB SSD SiliconHardDisk in MWDMA2 - When reading /dev/hdd (for example with dd or fsck), reads from /dev/hda are corrupted, there are twiddled single bits 1->0 and some full 32-bit words corrupted, sometimes commands fail (which switches /dev/hda to PIO mode but the corruptions happen even in PIO). - Reads from /dev/hdd don't seem to be corrupted (i.e. fsck passes fine). - When I connected normal rotating harddisk to /dev/hdd, there was no corruption, so the corruption is something specific to SSD. - I tried the same setup on a PCI card with CMD649 and saw no corruption. This patch serializes the operation for CMD646 and 643 (I didn't test CMD643 but it may have the same hw bug too because it's earlier design). CMD649 is good. I don't know anything about CMD 648. Signed-off-by: Mikulas Patocka Tested-by: Frans Pop Signed-off-by: David S. Miller --- drivers/ide/cmd64x.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers/ide') diff --git a/drivers/ide/cmd64x.c b/drivers/ide/cmd64x.c index 680e5975217..ca0c46f6580 100644 --- a/drivers/ide/cmd64x.c +++ b/drivers/ide/cmd64x.c @@ -379,7 +379,8 @@ static const struct ide_port_info cmd64x_chipsets[] __devinitdata = { .enablebits = {{0x00,0x00,0x00}, {0x51,0x08,0x08}}, .port_ops = &cmd64x_port_ops, .host_flags = IDE_HFLAG_CLEAR_SIMPLEX | - IDE_HFLAG_ABUSE_PREFETCH, + IDE_HFLAG_ABUSE_PREFETCH | + IDE_HFLAG_SERIALIZE, .pio_mask = ATA_PIO5, .mwdma_mask = ATA_MWDMA2, .udma_mask = 0x00, /* no udma */ @@ -389,7 +390,8 @@ static const struct ide_port_info cmd64x_chipsets[] __devinitdata = { .init_chipset = init_chipset_cmd64x, .enablebits = {{0x51,0x04,0x04}, {0x51,0x08,0x08}}, .port_ops = &cmd648_port_ops, - .host_flags = IDE_HFLAG_ABUSE_PREFETCH, + .host_flags = IDE_HFLAG_ABUSE_PREFETCH | + IDE_HFLAG_SERIALIZE, .pio_mask = ATA_PIO5, .mwdma_mask = ATA_MWDMA2, .udma_mask = ATA_UDMA2, -- cgit v1.2.3 From 0fb18c4777ff424c1db694af98443a201fa4fc30 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Fri, 6 Nov 2009 04:52:50 -0800 Subject: Revert "ide: try to use PIO Mode 0 during probe if possible" This reverts commit 6029336426a2b43e4bc6f4a84be8789a047d139e. Ok, we really do need to revert this, even with Bart's sis5513.c fix in there. The problem is that several driver's ->set_pio_mode() method depends upon the drive->media type being set properly. Most of them use this to enable prefetching, which can only be done for disk media. But the commit being reverted here calls ->set_pio_mode() before it's setup. Actually it considers everything disk because that is the default media type set by ide_port_init_devices_data(). The set of drivers that depend upon the media type in their ->set_pio_method() are: drivers/ide/alim15x3.c drivers/ide/it8172.c drivers/ide/it8213.c drivers/ide/pdc202xx_old.c drivers/ide/piix.c drivers/ide/qd65xx.c drivers/ide/sis5513.c drivers/ide/slc90e66.c And it is possible that we could fix this by guarding the prefetching and other media dependent setting changes with a test on IDE_PFLAG_PROBING in hwif->port_flags, that's simply too risky for 2.6.32-rcX and -stable. Signed-off-by: David S. Miller --- drivers/ide/ide-probe.c | 9 --------- 1 file changed, 9 deletions(-) (limited to 'drivers/ide') diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index 63c53d65e87..4d76ba47309 100644 --- a/drivers/ide/ide-probe.c +++ b/drivers/ide/ide-probe.c @@ -1046,15 +1046,6 @@ static void ide_port_init_devices(ide_hwif_t *hwif) if (port_ops && port_ops->init_dev) port_ops->init_dev(drive); } - - ide_port_for_each_dev(i, drive, hwif) { - /* - * default to PIO Mode 0 before we figure out - * the most suited mode for the attached device - */ - if (port_ops && port_ops->set_pio_mode) - port_ops->set_pio_mode(drive, 0); - } } static void ide_init_port(ide_hwif_t *hwif, unsigned int port, -- cgit v1.2.3 From 28c1969ff887bc2a7df39272850dece01de03285 Mon Sep 17 00:00:00 2001 From: Hemant Pedanekar Date: Wed, 25 Nov 2009 15:04:54 -0800 Subject: ide: fix ioctl to pass requested transfer mode to ide_find_dma_mode instead of UDMA6 Currently, ide_cmd_ioctl when invoked for setting DMA transfer mode calls ide_find_dma_mode with requested mode as XFER_UDMA_6. This prevents setting DMA mode to any other value than the default (maximum) supported by the device (or UDMA6, if supported) irrespective of the actual requested transfer mode and returns error. For example, setting mode to UDMA2 using hdparm, where UDMA4 is the default transfer mode gives following error: # ./hdparm -d1 -Xudma2 /dev/hda /dev/hda:hda: UDMA/66 mode selected setting using_dma to 1 (on) hda: UDMA/66 mode selected setting xfermode to 66 (UltraDMA mode2) HDIO_DRIVE_CMD(setxfermode) failed: Invalid argument using_dma = 1 (on) This patch fixes the issue. Signed-off-by: Hemant Pedanekar Acked-by: Bartlomiej Zolnierkiewicz Acked-by: Sergei Shtylyov Signed-off-by: David S. Miller --- drivers/ide/ide-ioctls.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/ide') diff --git a/drivers/ide/ide-ioctls.c b/drivers/ide/ide-ioctls.c index d3440b5010a..6e7ae2b6cfc 100644 --- a/drivers/ide/ide-ioctls.c +++ b/drivers/ide/ide-ioctls.c @@ -162,7 +162,7 @@ static int ide_cmd_ioctl(ide_drive_t *drive, unsigned long arg) if (tf->command == ATA_CMD_SET_FEATURES && tf->feature == SETFEATURES_XFER && tf->nsect >= XFER_SW_DMA_0) { - xfer_rate = ide_find_dma_mode(drive, XFER_UDMA_6); + xfer_rate = ide_find_dma_mode(drive, tf->nsect); if (xfer_rate != tf->nsect) { err = -EINVAL; goto abort; -- cgit v1.2.3 From ee31527a02b0a8e1aa4a5e4084d2db5fa34737ed Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 30 Nov 2009 08:55:18 +0000 Subject: slc90e66: fix UDMA handling Fix checking of the currently programmed UDMA mode. Signed-off-by: Bartlomiej Zolnierkiewicz Acked-by: Sergei Shtylyov Signed-off-by: David S. Miller --- drivers/ide/slc90e66.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers/ide') diff --git a/drivers/ide/slc90e66.c b/drivers/ide/slc90e66.c index 9aec78d3bcf..1ccfb40e721 100644 --- a/drivers/ide/slc90e66.c +++ b/drivers/ide/slc90e66.c @@ -91,8 +91,7 @@ static void slc90e66_set_dma_mode(ide_drive_t *drive, const u8 speed) if (!(reg48 & u_flag)) pci_write_config_word(dev, 0x48, reg48|u_flag); - /* FIXME: (reg4a & a_speed) ? */ - if ((reg4a & u_speed) != u_speed) { + if ((reg4a & a_speed) != u_speed) { pci_write_config_word(dev, 0x4a, reg4a & ~a_speed); pci_read_config_word(dev, 0x4a, ®4a); pci_write_config_word(dev, 0x4a, reg4a|u_speed); -- cgit v1.2.3 From 10ca30285d5283ac88ba7ae94111f2e9fe59c232 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 2 Dec 2009 14:23:01 -0800 Subject: cs5535: add pci id for AMD based CS5535 controllers Based on commit 02cb009 for pata_cs5530. Signed-off-by: Bartlomiej Zolnierkiewicz Signed-off-by: David S. Miller --- drivers/ide/cs5535.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/ide') diff --git a/drivers/ide/cs5535.c b/drivers/ide/cs5535.c index 983d957a018..b883838adc2 100644 --- a/drivers/ide/cs5535.c +++ b/drivers/ide/cs5535.c @@ -187,6 +187,7 @@ static int __devinit cs5535_init_one(struct pci_dev *dev, static const struct pci_device_id cs5535_pci_tbl[] = { { PCI_VDEVICE(NS, PCI_DEVICE_ID_NS_CS5535_IDE), 0 }, + { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_CS5535_IDE), }, { 0, }, }; -- cgit v1.2.3