From 96bc103f4c4e470d82ba5e372191d02ad715da45 Mon Sep 17 00:00:00 2001 From: Luca Pedrielli Date: Tue, 16 Jan 2007 12:55:04 +0900 Subject: sata_via: add PCI ID 0x5337 Add PCI ID 0x5337 to supported PCI ID. This is VT8237 in IDE mode. Signed-off-by: Luca Pedrielli Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- drivers/ata/sata_via.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/ata') diff --git a/drivers/ata/sata_via.c b/drivers/ata/sata_via.c index 1c7f19aecc25..88f0565c8883 100644 --- a/drivers/ata/sata_via.c +++ b/drivers/ata/sata_via.c @@ -77,6 +77,7 @@ static void svia_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val); static void vt6420_error_handler(struct ata_port *ap); static const struct pci_device_id svia_pci_tbl[] = { + { PCI_VDEVICE(VIA, 0x5337), vt6420 }, { PCI_VDEVICE(VIA, 0x0591), vt6420 }, { PCI_VDEVICE(VIA, 0x3149), vt6420 }, { PCI_VDEVICE(VIA, 0x3249), vt6421 }, -- cgit v1.2.2 From 79a55b72a1996f77e9d23c7a5282e5839d45beb3 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Thu, 18 Jan 2007 17:22:18 +0900 Subject: libata: fix handling of port actions in per-dev action mask libata EH ignores port-wide actions in per-dev action mask. However, device resume requests EH_SOFTRESET using per-dev action mask. Under certain circumstances, this results in not resetting frozen port after resuming which causes failure of all commands. This patch allows port-wide actions to be requested in per-dev action mask. Before EH recovery starts, port-wide actions will be collected. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- drivers/ata/libata-eh.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers/ata') diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index 08ad44b3e48f..56cf59b60ec4 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c @@ -1979,6 +1979,10 @@ static int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset, ehc->tries[dev->devno] = ATA_EH_DEV_TRIES; + /* collect port action mask recorded in dev actions */ + ehc->i.action |= ehc->i.dev_action[i] & ~ATA_EH_PERDEV_MASK; + ehc->i.dev_action[i] &= ATA_EH_PERDEV_MASK; + /* process hotplug request */ if (dev->flags & ATA_DFLAG_DETACH) ata_eh_detach_dev(dev); -- cgit v1.2.2 From e93f09dc2d49d8e98818a93ad17f3ede91533738 Mon Sep 17 00:00:00 2001 From: Olof Johansson Date: Thu, 18 Jan 2007 18:39:59 -0600 Subject: sata_mv HighPoint 2310 support (88SX7042) With the following patch, my HighPoint 2310 with a Marvell 88SX7042 on it seems to work OK. The controller only has 4 ports, with MV_FLAG_DUAL_HC it seems to init 8 ports and fails miserably at probe time. There are no other devices mapped to that chip, maybe it was just incorrectly specified in the first place? Signed-off-by: Olof Johansson Signed-off-by: Jeff Garzik --- drivers/ata/sata_mv.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers/ata') diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index 1b8e0eb9e032..aae0b5201c1e 100644 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c @@ -523,8 +523,7 @@ static const struct ata_port_info mv_port_info[] = { }, { /* chip_7042 */ .sht = &mv_sht, - .flags = (MV_COMMON_FLAGS | MV_6XXX_FLAGS | - MV_FLAG_DUAL_HC), + .flags = (MV_COMMON_FLAGS | MV_6XXX_FLAGS), .pio_mask = 0x1f, /* pio0-4 */ .udma_mask = 0x7f, /* udma0-6 */ .port_ops = &mv_iie_ops, @@ -545,6 +544,8 @@ static const struct pci_device_id mv_pci_tbl[] = { { PCI_VDEVICE(ADAPTEC2, 0x0241), chip_604x }, + { PCI_VDEVICE(TTI, 0x2310), chip_7042 }, + { } /* terminate list */ }; -- cgit v1.2.2 From 82490c0937cb455e7e4150455ff52e89a9fc5ab8 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 23 Jan 2007 15:13:39 +0900 Subject: ahci: make ULi M5288 ignore interface fatal error bit As with JMicron controllers, ULi M5288 sets interface fatal error bit on device error including ATAPI CC. This makes libata hardreset the port on ATAPI CC thus making it impossible to use. Ignore interface fatal error bit on ULi M5288. This fixes bugzilla bug #7837. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- drivers/ata/ahci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/ata') diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index b517d2493551..bd241767caea 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -361,7 +361,7 @@ static const struct pci_device_id ahci_pci_tbl[] = { { PCI_VDEVICE(INTEL, 0x27c1), board_ahci }, /* ICH7 */ { PCI_VDEVICE(INTEL, 0x27c5), board_ahci }, /* ICH7M */ { PCI_VDEVICE(INTEL, 0x27c3), board_ahci }, /* ICH7R */ - { PCI_VDEVICE(AL, 0x5288), board_ahci }, /* ULi M5288 */ + { PCI_VDEVICE(AL, 0x5288), board_ahci_ign_iferr }, /* ULi M5288 */ { PCI_VDEVICE(INTEL, 0x2681), board_ahci }, /* ESB2 */ { PCI_VDEVICE(INTEL, 0x2682), board_ahci }, /* ESB2 */ { PCI_VDEVICE(INTEL, 0x2683), board_ahci }, /* ESB2 */ -- cgit v1.2.2 From f740d1689d91415cfc749d17138a11ed03b7d38b Mon Sep 17 00:00:00 2001 From: Robert Hancock Date: Tue, 23 Jan 2007 20:09:02 -0600 Subject: sata_nv: don't rely on NV_INT_DEV indication with ADMA Several people reported issues with certain drive commands timing out on sata_nv controllers running in ADMA mode. The commands in question were non-DMA-mapped commands, usually FLUSH CACHE or FLUSH CACHE EXT. From experimentation it appears that the NV_INT_DEV indication isn't always set when a legitimate command completion interrupt is received on a legacy-mode command, at least not on these controllers in ADMA mode. When a command is pending on the port, force the flag on always in the irq_stat value before calling nv_host_intr so that the drive busy state is always checked by ata_host_intr. This also fixes some questionable code in nv_host_intr which called ata_check_status when a command was pending and ata_host_intr returned "unhandled". If the device interrupted at just the wrong time this could cause interrupts to be lost. Signed-off-by: Robert Hancock Signed-off-by: Jeff Garzik --- drivers/ata/sata_nv.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) (limited to 'drivers/ata') diff --git a/drivers/ata/sata_nv.c b/drivers/ata/sata_nv.c index f6d498e1cf80..f7a963eb1f02 100644 --- a/drivers/ata/sata_nv.c +++ b/drivers/ata/sata_nv.c @@ -700,7 +700,6 @@ static void nv_adma_check_cpb(struct ata_port *ap, int cpb_num, int force_err) static int nv_host_intr(struct ata_port *ap, u8 irq_stat) { struct ata_queued_cmd *qc = ata_qc_from_tag(ap, ap->active_tag); - int handled; /* freeze if hotplugged */ if (unlikely(irq_stat & (NV_INT_ADDED | NV_INT_REMOVED))) { @@ -719,13 +718,7 @@ static int nv_host_intr(struct ata_port *ap, u8 irq_stat) } /* handle interrupt */ - handled = ata_host_intr(ap, qc); - if (unlikely(!handled)) { - /* spurious, clear it */ - ata_check_status(ap); - } - - return 1; + return ata_host_intr(ap, qc); } static irqreturn_t nv_adma_interrupt(int irq, void *dev_instance) @@ -752,6 +745,11 @@ static irqreturn_t nv_adma_interrupt(int irq, void *dev_instance) if (pp->flags & NV_ADMA_PORT_REGISTER_MODE) { u8 irq_stat = readb(host->mmio_base + NV_INT_STATUS_CK804) >> (NV_INT_PORT_SHIFT * i); + if(ata_tag_valid(ap->active_tag)) + /** NV_INT_DEV indication seems unreliable at times + at least in ADMA mode. Force it on always when a + command is active, to prevent losing interrupts. */ + irq_stat |= NV_INT_DEV; handled += nv_host_intr(ap, irq_stat); continue; } -- cgit v1.2.2 From 07c53dac4904206a50dd7c87adabbb1acff903fb Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sun, 21 Jan 2007 02:10:11 +0900 Subject: ahci: don't enter slumber on power down Some ATA/ATAPI devices act weirdly after the link is put into slumber mode. Some hang completely requiring physical power removal while others fail to wake up till the link is hardreset a couple of times. The addition of slumber on power down was never driven by real need. It just followed what ahci spec said literally. The spec itself seems faulty in that it doesn't consider devices (not controllers) which don't support link powersaving mode. Theory never matches reality when it comes to dark allys of cheap ATA/ATAPI world. It's just unrealistic to expect vendors to test rarely used link powersaving feature rigorously. This patch makes ahci more friendly to the coldness of reality. This shouldn't have any negative effect - when suspend operation succeeds, we power off the whole machine; otherwise, we wake up everything. I can't see any reason to be so elaborate with powering down the link in the first place. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- drivers/ata/ahci.c | 37 ++++++++++--------------------------- 1 file changed, 10 insertions(+), 27 deletions(-) (limited to 'drivers/ata') diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index bd241767caea..e3c7b312287a 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -586,35 +586,18 @@ static void ahci_power_down(void __iomem *port_mmio, u32 cap) { u32 cmd, scontrol; - cmd = readl(port_mmio + PORT_CMD) & ~PORT_CMD_ICC_MASK; - - if (cap & HOST_CAP_SSC) { - /* enable transitions to slumber mode */ - scontrol = readl(port_mmio + PORT_SCR_CTL); - if ((scontrol & 0x0f00) > 0x100) { - scontrol &= ~0xf00; - writel(scontrol, port_mmio + PORT_SCR_CTL); - } - - /* put device into slumber mode */ - writel(cmd | PORT_CMD_ICC_SLUMBER, port_mmio + PORT_CMD); - - /* wait for the transition to complete */ - ata_wait_register(port_mmio + PORT_CMD, PORT_CMD_ICC_SLUMBER, - PORT_CMD_ICC_SLUMBER, 1, 50); - } + if (!(cap & HOST_CAP_SSS)) + return; - /* put device into listen mode */ - if (cap & HOST_CAP_SSS) { - /* first set PxSCTL.DET to 0 */ - scontrol = readl(port_mmio + PORT_SCR_CTL); - scontrol &= ~0xf; - writel(scontrol, port_mmio + PORT_SCR_CTL); + /* put device into listen mode, first set PxSCTL.DET to 0 */ + scontrol = readl(port_mmio + PORT_SCR_CTL); + scontrol &= ~0xf; + writel(scontrol, port_mmio + PORT_SCR_CTL); - /* then set PxCMD.SUD to 0 */ - cmd &= ~PORT_CMD_SPIN_UP; - writel(cmd, port_mmio + PORT_CMD); - } + /* then set PxCMD.SUD to 0 */ + cmd = readl(port_mmio + PORT_CMD) & ~PORT_CMD_ICC_MASK; + cmd &= ~PORT_CMD_SPIN_UP; + writel(cmd, port_mmio + PORT_CMD); } static void ahci_init_port(void __iomem *port_mmio, u32 cap, -- cgit v1.2.2 From 7a801184fa480e11e6431f184a5bdf31f63326fb Mon Sep 17 00:00:00 2001 From: Brian King Date: Wed, 17 Jan 2007 12:32:12 -0600 Subject: libata: Fixup n_elem initialization Fixup the inialization of qc->n_elem. It currently gets initialized to 1 for commands that do not transfer any data. Fix this by initializing n_elem to 0 and only setting to 1 in ata_scsi_qc_new when there is data to transfer. This fixes some problems seen with SATA devices attached to ipr adapters. Signed-off-by: Brian King Signed-off-by: Jeff Garzik --- drivers/ata/libata-scsi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/ata') diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 836947da5b14..7cc5a4a910a4 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -372,7 +372,7 @@ struct ata_queued_cmd *ata_scsi_qc_new(struct ata_device *dev, if (cmd->use_sg) { qc->__sg = (struct scatterlist *) cmd->request_buffer; qc->n_elem = cmd->use_sg; - } else { + } else if (cmd->request_bufflen) { qc->__sg = &qc->sgent; qc->n_elem = 1; } -- cgit v1.2.2 From 6a40da02be1e1d74eee653c6d181934d35cbca7d Mon Sep 17 00:00:00 2001 From: Alan Date: Wed, 24 Jan 2007 11:49:03 +0000 Subject: libata cmd64x: whack into a shape that looks like the documentation Signed-off-by: Alan Cox Signed-off-by: Jeff Garzik --- drivers/ata/pata_cmd64x.c | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) (limited to 'drivers/ata') diff --git a/drivers/ata/pata_cmd64x.c b/drivers/ata/pata_cmd64x.c index 15841a563694..449162cbf93e 100644 --- a/drivers/ata/pata_cmd64x.c +++ b/drivers/ata/pata_cmd64x.c @@ -197,7 +197,7 @@ static void cmd64x_set_piomode(struct ata_port *ap, struct ata_device *adev) static void cmd64x_set_dmamode(struct ata_port *ap, struct ata_device *adev) { static const u8 udma_data[] = { - 0x31, 0x21, 0x11, 0x25, 0x15, 0x05 + 0x30, 0x20, 0x10, 0x20, 0x10, 0x00 }; static const u8 mwdma_data[] = { 0x30, 0x20, 0x10 @@ -213,12 +213,21 @@ static void cmd64x_set_dmamode(struct ata_port *ap, struct ata_device *adev) pci_read_config_byte(pdev, pciD, ®D); pci_read_config_byte(pdev, pciU, ®U); - regD &= ~(0x20 << shift); - regU &= ~(0x35 << shift); + /* DMA bits off */ + regD &= ~(0x20 << adev->devno); + /* DMA control bits */ + regU &= ~(0x30 << shift); + /* DMA timing bits */ + regU &= ~(0x05 << adev->devno); - if (adev->dma_mode >= XFER_UDMA_0) + if (adev->dma_mode >= XFER_UDMA_0) { + /* Merge thge timing value */ regU |= udma_data[adev->dma_mode - XFER_UDMA_0] << shift; - else + /* Merge the control bits */ + regU |= 1 << adev->devno; /* UDMA on */ + if (adev->dma_mode > 2) /* 15nS timing */ + regU |= 4 << adev->devno; + } else regD |= mwdma_data[adev->dma_mode - XFER_MW_DMA_0] << shift; regD |= 0x20 << adev->devno; @@ -239,8 +248,8 @@ static void cmd648_bmdma_stop(struct ata_queued_cmd *qc) struct ata_port *ap = qc->ap; struct pci_dev *pdev = to_pci_dev(ap->host->dev); u8 dma_intr; - int dma_reg = ap->port_no ? ARTTIM23_INTR_CH1 : CFR_INTR_CH0; - int dma_mask = ap->port_no ? ARTTIM2 : CFR; + int dma_mask = ap->port_no ? ARTTIM23_INTR_CH1 : CFR_INTR_CH0; + int dma_reg = ap->port_no ? ARTTIM2 : CFR; ata_bmdma_stop(qc); -- cgit v1.2.2 From a52865c239b1bc4f62e387509b1ad3415e476ee5 Mon Sep 17 00:00:00 2001 From: Alan Date: Wed, 24 Jan 2007 11:51:38 +0000 Subject: libata hpt3xn: Hopefully sort out the DPLL logic versus the vendor code Rather than ending up with two layers of negation jut rename the variable and lose one. Signed-off-by: Alan Cox Signed-off-by: Jeff Garzik --- drivers/ata/pata_hpt3x2n.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/ata') diff --git a/drivers/ata/pata_hpt3x2n.c b/drivers/ata/pata_hpt3x2n.c index f6817b4093a4..886fab9aa62c 100644 --- a/drivers/ata/pata_hpt3x2n.c +++ b/drivers/ata/pata_hpt3x2n.c @@ -25,7 +25,7 @@ #include #define DRV_NAME "pata_hpt3x2n" -#define DRV_VERSION "0.3" +#define DRV_VERSION "0.3.2" enum { HPT_PCI_FAST = (1 << 31), @@ -297,11 +297,11 @@ static int hpt3x2n_pair_idle(struct ata_port *ap) return 0; } -static int hpt3x2n_use_dpll(struct ata_port *ap, int reading) +static int hpt3x2n_use_dpll(struct ata_port *ap, int writing) { long flags = (long)ap->host->private_data; /* See if we should use the DPLL */ - if (reading == 0) + if (writing) return USE_DPLL; /* Needed for write */ if (flags & PCI66) return USE_DPLL; /* Needed at 66Mhz */ -- cgit v1.2.2 From b229a7b0aed808f2ef6a5e9dbf78b0f17cefb4d0 Mon Sep 17 00:00:00 2001 From: Alan Date: Wed, 24 Jan 2007 11:47:07 +0000 Subject: libata: set_mode, Fix the FIXME When set_mode() changed ->set_mode didn't adapt. This makes the needed changes and removes the relevant FIXME case. Signed-off-by: Alan Cox Signed-off-by: Jeff Garzik --- drivers/ata/ata_generic.c | 6 ++++-- drivers/ata/libata-core.c | 14 ++------------ drivers/ata/pata_it821x.c | 4 +++- drivers/ata/pata_ixp4xx_cf.c | 5 +++-- drivers/ata/pata_legacy.c | 4 +++- drivers/ata/pata_rz1000.c | 6 ++++-- 6 files changed, 19 insertions(+), 20 deletions(-) (limited to 'drivers/ata') diff --git a/drivers/ata/ata_generic.c b/drivers/ata/ata_generic.c index 908751d27e76..24af56081b5d 100644 --- a/drivers/ata/ata_generic.c +++ b/drivers/ata/ata_generic.c @@ -64,6 +64,7 @@ static void generic_error_handler(struct ata_port *ap) /** * generic_set_mode - mode setting * @ap: interface to set up + * @unused: returned device on error * * Use a non standard set_mode function. We don't want to be tuned. * The BIOS configured everything. Our job is not to fiddle. We @@ -71,7 +72,7 @@ static void generic_error_handler(struct ata_port *ap) * and respect them. */ -static void generic_set_mode(struct ata_port *ap) +static int generic_set_mode(struct ata_port *ap, struct ata_device **unused) { int dma_enabled = 0; int i; @@ -82,7 +83,7 @@ static void generic_set_mode(struct ata_port *ap) for (i = 0; i < ATA_MAX_DEVICES; i++) { struct ata_device *dev = &ap->device[i]; - if (ata_dev_enabled(dev)) { + if (ata_dev_ready(dev)) { /* We don't really care */ dev->pio_mode = XFER_PIO_0; dev->dma_mode = XFER_MW_DMA_0; @@ -99,6 +100,7 @@ static void generic_set_mode(struct ata_port *ap) } } } + return 0; } static struct scsi_host_template generic_sht = { diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 0d51d13b16bf..a388a8df0043 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -2431,18 +2431,8 @@ int ata_set_mode(struct ata_port *ap, struct ata_device **r_failed_dev) int i, rc = 0, used_dma = 0, found = 0; /* has private set_mode? */ - if (ap->ops->set_mode) { - /* FIXME: make ->set_mode handle no device case and - * return error code and failing device on failure. - */ - for (i = 0; i < ATA_MAX_DEVICES; i++) { - if (ata_dev_ready(&ap->device[i])) { - ap->ops->set_mode(ap); - break; - } - } - return 0; - } + if (ap->ops->set_mode) + return ap->ops->set_mode(ap, r_failed_dev); /* step 1: calculate xfer_mask */ for (i = 0; i < ATA_MAX_DEVICES; i++) { diff --git a/drivers/ata/pata_it821x.c b/drivers/ata/pata_it821x.c index 0b56ff3d1cfe..e8afd486434a 100644 --- a/drivers/ata/pata_it821x.c +++ b/drivers/ata/pata_it821x.c @@ -476,6 +476,7 @@ static unsigned int it821x_passthru_qc_issue_prot(struct ata_queued_cmd *qc) /** * it821x_smart_set_mode - mode setting * @ap: interface to set up + * @unused: device that failed (error only) * * Use a non standard set_mode function. We don't want to be tuned. * The BIOS configured everything. Our job is not to fiddle. We @@ -483,7 +484,7 @@ static unsigned int it821x_passthru_qc_issue_prot(struct ata_queued_cmd *qc) * and respect them. */ -static void it821x_smart_set_mode(struct ata_port *ap) +static int it821x_smart_set_mode(struct ata_port *ap, struct ata_device **unused) { int dma_enabled = 0; int i; @@ -512,6 +513,7 @@ static void it821x_smart_set_mode(struct ata_port *ap) } } } + return 0; } /** diff --git a/drivers/ata/pata_ixp4xx_cf.c b/drivers/ata/pata_ixp4xx_cf.c index cb8924109f59..23b8aab3ebd8 100644 --- a/drivers/ata/pata_ixp4xx_cf.c +++ b/drivers/ata/pata_ixp4xx_cf.c @@ -23,9 +23,9 @@ #include #define DRV_NAME "pata_ixp4xx_cf" -#define DRV_VERSION "0.1.1" +#define DRV_VERSION "0.1.1ac1" -static void ixp4xx_set_mode(struct ata_port *ap) +static int ixp4xx_set_mode(struct ata_port *ap, struct ata_device *adev) { int i; @@ -38,6 +38,7 @@ static void ixp4xx_set_mode(struct ata_port *ap) dev->flags |= ATA_DFLAG_PIO; } } + return 0; } static void ixp4xx_phy_reset(struct ata_port *ap) diff --git a/drivers/ata/pata_legacy.c b/drivers/ata/pata_legacy.c index e7bf9d89c8ee..581cb33c6f45 100644 --- a/drivers/ata/pata_legacy.c +++ b/drivers/ata/pata_legacy.c @@ -96,6 +96,7 @@ static int pio_mask = 0x1F; /* PIO range for autospeed devices */ /** * legacy_set_mode - mode setting * @ap: IDE interface + * @unused: Device that failed when error is returned * * Use a non standard set_mode function. We don't want to be tuned. * @@ -105,7 +106,7 @@ static int pio_mask = 0x1F; /* PIO range for autospeed devices */ * expand on this as per hdparm in the base kernel. */ -static void legacy_set_mode(struct ata_port *ap) +static int legacy_set_mode(struct ata_port *ap, struct ata_device **unused) { int i; @@ -118,6 +119,7 @@ static void legacy_set_mode(struct ata_port *ap) dev->flags |= ATA_DFLAG_PIO; } } + return 0; } static struct scsi_host_template legacy_sht = { diff --git a/drivers/ata/pata_rz1000.c b/drivers/ata/pata_rz1000.c index adf4cc134f25..cec0729225e1 100644 --- a/drivers/ata/pata_rz1000.c +++ b/drivers/ata/pata_rz1000.c @@ -52,19 +52,20 @@ static void rz1000_error_handler(struct ata_port *ap) /** * rz1000_set_mode - mode setting function * @ap: ATA interface + * @unused: returned device on set_mode failure * * Use a non standard set_mode function. We don't want to be tuned. We * would prefer to be BIOS generic but for the fact our hardware is * whacked out. */ -static void rz1000_set_mode(struct ata_port *ap) +static int rz1000_set_mode(struct ata_port *ap, struct ata_device **unused) { int i; for (i = 0; i < ATA_MAX_DEVICES; i++) { struct ata_device *dev = &ap->device[i]; - if (ata_dev_enabled(dev)) { + if (ata_dev_ready(dev)) { /* We don't really care */ dev->pio_mode = XFER_PIO_0; dev->xfer_mode = XFER_PIO_0; @@ -72,6 +73,7 @@ static void rz1000_set_mode(struct ata_port *ap) dev->flags |= ATA_DFLAG_PIO; } } + return 0; } -- cgit v1.2.2 From 17234246eb82898cf98e3c29e81d941c738e0587 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Thu, 25 Jan 2007 20:46:59 +0900 Subject: sata_via: don't diddle with ATA_NIEN in ->freeze vt6420 completely loses its ability to raise IRQ for ATAPI devices if ATA_NIEN is diddled with in ->freeze. Further investigation is necessary to determine whether this problem is shared on other controllers but it doesn't seem to be at this point. Make vt6420's ->freeze only clear IRQ to fix this problem. This makes vt6420 relatively more prone to IRQ storms but the controller is way too braindamaged to worry about that anyway. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- drivers/ata/sata_via.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'drivers/ata') diff --git a/drivers/ata/sata_via.c b/drivers/ata/sata_via.c index 88f0565c8883..55b01236a6f0 100644 --- a/drivers/ata/sata_via.c +++ b/drivers/ata/sata_via.c @@ -74,6 +74,7 @@ enum { static int svia_init_one (struct pci_dev *pdev, const struct pci_device_id *ent); static u32 svia_scr_read (struct ata_port *ap, unsigned int sc_reg); static void svia_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val); +static void svia_noop_freeze(struct ata_port *ap); static void vt6420_error_handler(struct ata_port *ap); static const struct pci_device_id svia_pci_tbl[] = { @@ -128,7 +129,7 @@ static const struct ata_port_operations vt6420_sata_ops = { .qc_issue = ata_qc_issue_prot, .data_xfer = ata_pio_data_xfer, - .freeze = ata_bmdma_freeze, + .freeze = svia_noop_freeze, .thaw = ata_bmdma_thaw, .error_handler = vt6420_error_handler, .post_internal_cmd = ata_bmdma_post_internal_cmd, @@ -204,6 +205,15 @@ static void svia_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val) outl(val, ap->ioaddr.scr_addr + (4 * sc_reg)); } +static void svia_noop_freeze(struct ata_port *ap) +{ + /* Some VIA controllers choke if ATA_NIEN is manipulated in + * certain way. Leave it alone and just clear pending IRQ. + */ + ata_chk_status(ap); + ap->ops->irq_clear(ap); +} + /** * vt6420_prereset - prereset for vt6420 * @ap: target ATA port -- cgit v1.2.2 From 0291f95fdb5fcd91cc077aafabea2c5b109fa8a8 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Thu, 25 Jan 2007 19:16:28 +0900 Subject: ahci: improve and limit spurious interrupt messages, take#3 We're still seeing a lot of issues with NCQ implementation in drive firmwares. Sprious FISes during NCQ command phase occur on many drives and some of them seem potentially dangerous (at least to me). Until we find the solution, spurious messages can give us more info. Improve and limit them such that more info can be reported while not disturbing users too much. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- drivers/ata/ahci.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 49 insertions(+), 8 deletions(-) (limited to 'drivers/ata') diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index e3c7b312287a..2fe5a58195de 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -75,6 +75,7 @@ enum { AHCI_CMD_CLR_BUSY = (1 << 10), RX_FIS_D2H_REG = 0x40, /* offset of D2H Register FIS data */ + RX_FIS_SDB = 0x58, /* offset of SDB FIS data */ RX_FIS_UNK = 0x60, /* offset of Unknown FIS data */ board_ahci = 0, @@ -202,6 +203,10 @@ struct ahci_port_priv { dma_addr_t cmd_tbl_dma; void *rx_fis; dma_addr_t rx_fis_dma; + /* for NCQ spurious interrupt analysis */ + int ncq_saw_spurious_sdb_cnt; + unsigned int ncq_saw_d2h:1; + unsigned int ncq_saw_dmas:1; }; static u32 ahci_scr_read (struct ata_port *ap, unsigned int sc_reg); @@ -1109,8 +1114,9 @@ static void ahci_host_intr(struct ata_port *ap) void __iomem *mmio = ap->host->mmio_base; void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); struct ata_eh_info *ehi = &ap->eh_info; + struct ahci_port_priv *pp = ap->private_data; u32 status, qc_active; - int rc; + int rc, known_irq = 0; status = readl(port_mmio + PORT_IRQ_STAT); writel(status, port_mmio + PORT_IRQ_STAT); @@ -1137,17 +1143,52 @@ static void ahci_host_intr(struct ata_port *ap) /* hmmm... a spurious interupt */ - /* some devices send D2H reg with I bit set during NCQ command phase */ - if (ap->sactive && (status & PORT_IRQ_D2H_REG_FIS)) + /* if !NCQ, ignore. No modern ATA device has broken HSM + * implementation for non-NCQ commands. + */ + if (!ap->sactive) return; - /* ignore interim PIO setup fis interrupts */ - if (ata_tag_valid(ap->active_tag) && (status & PORT_IRQ_PIOS_FIS)) - return; + if (status & PORT_IRQ_D2H_REG_FIS) { + if (!pp->ncq_saw_d2h) + ata_port_printk(ap, KERN_INFO, + "D2H reg with I during NCQ, " + "this message won't be printed again\n"); + pp->ncq_saw_d2h = 1; + known_irq = 1; + } + + if (status & PORT_IRQ_DMAS_FIS) { + if (!pp->ncq_saw_dmas) + ata_port_printk(ap, KERN_INFO, + "DMAS FIS during NCQ, " + "this message won't be printed again\n"); + pp->ncq_saw_dmas = 1; + known_irq = 1; + } + + if (status & PORT_IRQ_SDB_FIS && + pp->ncq_saw_spurious_sdb_cnt < 10) { + /* SDB FIS containing spurious completions might be + * dangerous, we need to know more about them. Print + * more of it. + */ + const u32 *f = pp->rx_fis + RX_FIS_SDB; + + ata_port_printk(ap, KERN_INFO, "Spurious SDB FIS during NCQ " + "issue=0x%x SAct=0x%x FIS=%08x:%08x%s\n", + readl(port_mmio + PORT_CMD_ISSUE), + readl(port_mmio + PORT_SCR_ACT), f[0], f[1], + pp->ncq_saw_spurious_sdb_cnt < 10 ? + "" : ", shutting up"); + + pp->ncq_saw_spurious_sdb_cnt++; + known_irq = 1; + } - if (ata_ratelimit()) + if (!known_irq) ata_port_printk(ap, KERN_INFO, "spurious interrupt " - "(irq_stat 0x%x active_tag %d sactive 0x%x)\n", + "(irq_stat 0x%x active_tag 0x%x sactive 0x%x)\n", status, ap->active_tag, ap->sactive); } -- cgit v1.2.2 From b2a8bbe67d73631c71492fd60b757fc50a87f182 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Thu, 25 Jan 2007 19:40:05 +0900 Subject: libata: implement ATA_FLAG_IGN_SIMPLEX and use it in sata_uli Some uli controllers have stuck SIMPLEX bit which can't be cleared with ata_pci_clear_simplex(), but the controller is capable of doing DMAs on both channels simultaneously. Implement ATA_FLAG_IGN_SIMPLEX which makes libata ignore the simplex bit and use it in sata_uli. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- drivers/ata/libata-sff.c | 12 ++++++++---- drivers/ata/sata_uli.c | 3 ++- 2 files changed, 10 insertions(+), 5 deletions(-) (limited to 'drivers/ata') diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c index 623cec914c9b..114fa81deb83 100644 --- a/drivers/ata/libata-sff.c +++ b/drivers/ata/libata-sff.c @@ -870,7 +870,8 @@ ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port, int pci_resource_start(pdev, 1) | ATA_PCI_CTL_OFS; bmdma = pci_resource_start(pdev, 4); if (bmdma) { - if (inb(bmdma + 2) & 0x80) + if ((!(port[p]->flags & ATA_FLAG_IGN_SIMPLEX)) && + (inb(bmdma + 2) & 0x80)) probe_ent->_host_flags |= ATA_HOST_SIMPLEX; probe_ent->port[p].bmdma_addr = bmdma; } @@ -886,7 +887,8 @@ ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port, int bmdma = pci_resource_start(pdev, 4); if (bmdma) { bmdma += 8; - if(inb(bmdma + 2) & 0x80) + if ((!(port[p]->flags & ATA_FLAG_IGN_SIMPLEX)) && + (inb(bmdma + 2) & 0x80)) probe_ent->_host_flags |= ATA_HOST_SIMPLEX; probe_ent->port[p].bmdma_addr = bmdma; } @@ -920,7 +922,8 @@ static struct ata_probe_ent *ata_pci_init_legacy_port(struct pci_dev *pdev, probe_ent->port[0].ctl_addr = ATA_PRIMARY_CTL; if (bmdma) { probe_ent->port[0].bmdma_addr = bmdma; - if (inb(bmdma + 2) & 0x80) + if ((!(port[0]->flags & ATA_FLAG_IGN_SIMPLEX)) && + (inb(bmdma + 2) & 0x80)) probe_ent->_host_flags |= ATA_HOST_SIMPLEX; } ata_std_ports(&probe_ent->port[0]); @@ -937,7 +940,8 @@ static struct ata_probe_ent *ata_pci_init_legacy_port(struct pci_dev *pdev, probe_ent->port[1].ctl_addr = ATA_SECONDARY_CTL; if (bmdma) { probe_ent->port[1].bmdma_addr = bmdma + 8; - if (inb(bmdma + 10) & 0x80) + if ((!(port[1]->flags & ATA_FLAG_IGN_SIMPLEX)) && + (inb(bmdma + 10) & 0x80)) probe_ent->_host_flags |= ATA_HOST_SIMPLEX; } ata_std_ports(&probe_ent->port[1]); diff --git a/drivers/ata/sata_uli.c b/drivers/ata/sata_uli.c index 5c603ca3a50a..a43aec62d505 100644 --- a/drivers/ata/sata_uli.c +++ b/drivers/ata/sata_uli.c @@ -128,7 +128,8 @@ static const struct ata_port_operations uli_ops = { static struct ata_port_info uli_port_info = { .sht = &uli_sht, - .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY, + .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | + ATA_FLAG_IGN_SIMPLEX, .pio_mask = 0x1f, /* pio0-4 */ .udma_mask = 0x7f, /* udma0-6 */ .port_ops = &uli_ops, -- cgit v1.2.2 From 61dd08c6c8d2b4ede530e43c01fa72f789ef65b1 Mon Sep 17 00:00:00 2001 From: Alan Date: Thu, 25 Jan 2007 15:09:05 +0000 Subject: libata-sff: Don't call bmdma_stop on non DMA capable controllers Fixes bogus accesses to ports 0-15 with a non DMA capable controller. This I think should go in for 2.6.20 Signed-off-by: Alan Cox Signed-off-by: Jeff Garzik --- drivers/ata/libata-sff.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/ata') diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c index 114fa81deb83..942aeba2940a 100644 --- a/drivers/ata/libata-sff.c +++ b/drivers/ata/libata-sff.c @@ -827,7 +827,8 @@ void ata_bmdma_error_handler(struct ata_port *ap) */ void ata_bmdma_post_internal_cmd(struct ata_queued_cmd *qc) { - ata_bmdma_stop(qc); + if (qc->ap->ioaddr.bmdma_addr) + ata_bmdma_stop(qc); } #ifdef CONFIG_PCI -- cgit v1.2.2 From 6096b63e2584796341baf7e7735f98d387f489f2 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Fri, 26 Jan 2007 14:47:38 +0900 Subject: ahci: fix endianness in spurious interrupt message Fix endianness in spurious interrupt message. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- drivers/ata/ahci.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/ata') diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 2fe5a58195de..d8f0ce970d54 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -1178,7 +1178,8 @@ static void ahci_host_intr(struct ata_port *ap) ata_port_printk(ap, KERN_INFO, "Spurious SDB FIS during NCQ " "issue=0x%x SAct=0x%x FIS=%08x:%08x%s\n", readl(port_mmio + PORT_CMD_ISSUE), - readl(port_mmio + PORT_SCR_ACT), f[0], f[1], + readl(port_mmio + PORT_SCR_ACT), + le32_to_cpu(f[0]), le32_to_cpu(f[1]), pp->ncq_saw_spurious_sdb_cnt < 10 ? "" : ", shutting up"); -- cgit v1.2.2 From d02598721706ab62a574823479b1f6c26c8980d2 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Fri, 26 Jan 2007 14:57:31 +0900 Subject: sata_via: style clean up, no indirect method call in LLD Call ata_bmdma_irq_clear() directly instead of through ap->ops->irq_clear() according to libata style guideline. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- drivers/ata/sata_via.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/ata') diff --git a/drivers/ata/sata_via.c b/drivers/ata/sata_via.c index 55b01236a6f0..d3d5c0d57032 100644 --- a/drivers/ata/sata_via.c +++ b/drivers/ata/sata_via.c @@ -211,7 +211,7 @@ static void svia_noop_freeze(struct ata_port *ap) * certain way. Leave it alone and just clear pending IRQ. */ ata_chk_status(ap); - ap->ops->irq_clear(ap); + ata_bmdma_irq_clear(ap); } /** -- cgit v1.2.2 From dfd7a3db3898e299bdc25f0c77081a8632b3a73c Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Fri, 26 Jan 2007 15:37:20 +0900 Subject: ahci: use 0x80 as wait stat value instead of 0xff Before hardreset, ahci initialized stat part of received FIS area to 0xff to wait for the first D2H Reg FIS which would change the value to device ready state. This used to work but now libata considers status value of 0xff as device not present making this wait prone to failure. This patch makes ahci use 0x80 for the wait stat value instead of 0xff to fix the above problem. Signed-off-by: Tejun Heo drivers/ata/ahci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) Signed-off-by: Jeff Garzik --- drivers/ata/ahci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/ata') diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index d8f0ce970d54..28a82e3403f1 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -903,7 +903,7 @@ static int ahci_hardreset(struct ata_port *ap, unsigned int *class) /* clear D2H reception area to properly wait for D2H FIS */ ata_tf_init(ap->device, &tf); - tf.command = 0xff; + tf.command = 0x80; ata_tf_to_fis(&tf, d2h_fis, 0); rc = sata_std_hardreset(ap, class); -- cgit v1.2.2 From 8cdf92a98fa0f91068615443f2a8597b7f2c34ca Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Mon, 1 Jan 2007 19:31:15 +0000 Subject: Fix Maple PATA IRQ assignment. On the Maple board, the AMD8111 IDE is in legacy mode... except that it appears on IRQ 20 instead of IRQ 15. For drivers/ide this was handled by the architecture's "pci_get_legacy_ide_irq()" function, but in libata we just hard-code the numbers 14 and 15. This patch provides asm-powerpc/libata-portmap.h which maps the IRQ as appropriate, having added a pci_dev argument to the ATA_{PRIM,SECOND}ARY_IRQ macros. There's probably a better way to do this -- especially if we observe that the _only_ case in which this seemingly-generic "pci_get_legacy_ide_irq()" function returns anything other than 14 and 15 for primary and secondary respectively is the case of the AMD8111 on the Maple board -- couldn't we handle that with a special case in the pata_amd driver, or perhaps with a PCI quirk for Maple to switch it into native mode during early boot and assign resources properly? Signed-off-by: David Woodhouse Signed-off-by: Jeff Garzik --- drivers/ata/Kconfig | 4 ++++ drivers/ata/libata-sff.c | 6 +++--- 2 files changed, 7 insertions(+), 3 deletions(-) (limited to 'drivers/ata') diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index da21552d2b1c..1c94b43d2c9b 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig @@ -19,6 +19,10 @@ config ATA if ATA +config ATA_NONSTANDARD + bool + default n + config SATA_AHCI tristate "AHCI SATA support" depends on PCI diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c index 942aeba2940a..12c88c588039 100644 --- a/drivers/ata/libata-sff.c +++ b/drivers/ata/libata-sff.c @@ -917,7 +917,7 @@ static struct ata_probe_ent *ata_pci_init_legacy_port(struct pci_dev *pdev, probe_ent->irq_flags = IRQF_SHARED; if (port_mask & ATA_PORT_PRIMARY) { - probe_ent->irq = ATA_PRIMARY_IRQ; + probe_ent->irq = ATA_PRIMARY_IRQ(pdev); probe_ent->port[0].cmd_addr = ATA_PRIMARY_CMD; probe_ent->port[0].altstatus_addr = probe_ent->port[0].ctl_addr = ATA_PRIMARY_CTL; @@ -933,9 +933,9 @@ static struct ata_probe_ent *ata_pci_init_legacy_port(struct pci_dev *pdev, if (port_mask & ATA_PORT_SECONDARY) { if (probe_ent->irq) - probe_ent->irq2 = ATA_SECONDARY_IRQ; + probe_ent->irq2 = ATA_SECONDARY_IRQ(pdev); else - probe_ent->irq = ATA_SECONDARY_IRQ; + probe_ent->irq = ATA_SECONDARY_IRQ(pdev); probe_ent->port[1].cmd_addr = ATA_SECONDARY_CMD; probe_ent->port[1].altstatus_addr = probe_ent->port[1].ctl_addr = ATA_SECONDARY_CTL; -- cgit v1.2.2 From a718728f9e40ec79c0879ec6509a54fee214f5b2 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sat, 27 Jan 2007 11:04:26 +0900 Subject: ahci: port_no should be used when clearing IRQ in ahci_thaw() ap->id is logcial port ID which is unique among all ATA ports and doesn't have anything to do with hardware port index. ap->port_no is the hardware port index and thus should be used when clearing IRQ mask in ahci_thaw(). This problem has been spotted by Jeff Garzik . Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- drivers/ata/ahci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/ata') diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 28a82e3403f1..48616c6fee9d 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -1282,7 +1282,7 @@ static void ahci_thaw(struct ata_port *ap) /* clear IRQ */ tmp = readl(port_mmio + PORT_IRQ_STAT); writel(tmp, port_mmio + PORT_IRQ_STAT); - writel(1 << ap->id, mmio + HOST_IRQ_STAT); + writel(1 << ap->port_no, mmio + HOST_IRQ_STAT); /* turn IRQ back on */ writel(DEF_PORT_IRQ, port_mmio + PORT_IRQ_MASK); -- cgit v1.2.2 From 03ee5b1cdd09ed1ee2e75d0bc647fc5db66b9d07 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Fri, 26 Jan 2007 20:10:25 +0900 Subject: libata: fix ata_eh_suspend() return value ata_eh_suspend() was returning 0 regardless of failure. This bug has potential to lose data on suspend. Fix it. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- drivers/ata/libata-eh.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/ata') diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index 56cf59b60ec4..748435807d68 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c @@ -1796,7 +1796,7 @@ static int ata_eh_suspend(struct ata_port *ap, struct ata_device **r_failed_dev) *r_failed_dev = dev; DPRINTK("EXIT\n"); - return 0; + return rc; } /** -- cgit v1.2.2 From e0b874df14052489e6408125903dba96b4dd7baa Mon Sep 17 00:00:00 2001 From: Josepch Chan Date: Sat, 27 Jan 2007 13:47:08 +0100 Subject: via82cxxx/pata_via: correct PCI_DEVICE_ID_VIA_SATA_EIDE ID and add support for CX700 and 8237S This patch: * Corrects the wrong device ID of PCI_DEVICE_ID_VIA_SATA_EIDE from 0x0581 to 0x5324. * Adds VIA CX700 and VT8237S support in drivers/ide/pci/via82cxxx.c * Adds VIA VT8237S support in drivers/ata/pata_via.c Signed-off-by: Josepch Chan Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ata/pata_via.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/ata') diff --git a/drivers/ata/pata_via.c b/drivers/ata/pata_via.c index f0d4f7e9ed31..0219419cae97 100644 --- a/drivers/ata/pata_via.c +++ b/drivers/ata/pata_via.c @@ -95,6 +95,7 @@ static const struct via_isa_bridge { u8 rev_max; u16 flags; } via_isa_bridges[] = { + { "vt8237s", PCI_DEVICE_ID_VIA_8237S, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST }, { "vt8251", PCI_DEVICE_ID_VIA_8251, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST }, { "cx700", PCI_DEVICE_ID_VIA_CX700, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST }, { "vt6410", PCI_DEVICE_ID_VIA_6410, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST | VIA_NO_ENABLES}, -- cgit v1.2.2 From 5dcade90db19205b9ebb8241a22664560973f81a Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Sun, 28 Jan 2007 21:33:44 +0300 Subject: pata_sil680: PIO1 taskfile transfers overclocking fix (repost) Fix PIO mode 1 overclocked taskfile transfers -- probably a typo carried over from drivers/ide/pci/siimage.c where I've found it by documentation check... Signed-off-by: Sergei Shtylyov Signed-off-by: Jeff Garzik --- drivers/ata/pata_sil680.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/ata') diff --git a/drivers/ata/pata_sil680.c b/drivers/ata/pata_sil680.c index 32cf0bfa8921..e8dfd8fc3ff7 100644 --- a/drivers/ata/pata_sil680.c +++ b/drivers/ata/pata_sil680.c @@ -135,7 +135,7 @@ static void sil680_error_handler(struct ata_port *ap) static void sil680_set_piomode(struct ata_port *ap, struct ata_device *adev) { static u16 speed_p[5] = { 0x328A, 0x2283, 0x1104, 0x10C3, 0x10C1 }; - static u16 speed_t[5] = { 0x328A, 0x1281, 0x1281, 0x10C3, 0x10C1 }; + static u16 speed_t[5] = { 0x328A, 0x2283, 0x1281, 0x10C3, 0x10C1 }; unsigned long tfaddr = sil680_selreg(ap, 0x02); unsigned long addr = sil680_seldev(ap, adev, 0x04); -- cgit v1.2.2 From 7a0f1c8a4b1052da7efc7715e2e557255b632712 Mon Sep 17 00:00:00 2001 From: Lennert Buytenhek Date: Mon, 29 Jan 2007 13:28:47 +0100 Subject: ata_if_xfermask() word 51 fix If word 53 bit 1 isn't set, the maximum PIO mode is indicated by the upper 8 bits of word 51, not the lower 8 bits. Fixes PIO mode detection on old Compact Flash cards. Signed-off-by: Lennert Buytenhek Signed-off-by: Jeff Garzik --- drivers/ata/libata-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/ata') diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index a388a8df0043..cf707029352e 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -1037,7 +1037,7 @@ static unsigned int ata_id_xfermask(const u16 *id) * the PIO timing number for the maximum. Turn it into * a mask. */ - u8 mode = id[ATA_ID_OLD_PIO_MODES] & 0xFF; + u8 mode = (id[ATA_ID_OLD_PIO_MODES] >> 8) & 0xFF; if (mode < 5) /* Valid PIO range */ pio_mask = (2 << mode) - 1; else -- cgit v1.2.2 From 2ca6611b1fc1f913f5370b3c50a0a35d817491b3 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Tue, 30 Jan 2007 00:59:14 -0800 Subject: pata_platform: set_mode fix drivers/ata/pata_platform.c:85: warning: initialization from incompatible pointer type Cc: Jeff Garzik Cc: Tejun Heo Acked-by: Alan Cox Signed-off-by: Andrew Morton Signed-off-by: Jeff Garzik --- drivers/ata/pata_platform.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers/ata') diff --git a/drivers/ata/pata_platform.c b/drivers/ata/pata_platform.c index 443b1d85c6c4..ca2999f9f048 100644 --- a/drivers/ata/pata_platform.c +++ b/drivers/ata/pata_platform.c @@ -30,7 +30,8 @@ static int pio_mask = 1; * Provide our own set_mode() as we don't want to change anything that has * already been configured.. */ -static void pata_platform_set_mode(struct ata_port *ap) +static int pata_platform_set_mode(struct ata_port *ap, + struct ata_device **r_failed_dev) { int i; @@ -44,6 +45,7 @@ static void pata_platform_set_mode(struct ata_port *ap) dev->flags |= ATA_DFLAG_PIO; } } + return 0; } static void pata_platform_host_stop(struct ata_host *host) -- cgit v1.2.2 From af068bd1debcc76c1bc265aa01401901bf0067ed Mon Sep 17 00:00:00 2001 From: David Milburn Date: Tue, 30 Jan 2007 00:59:15 -0800 Subject: libata-scsi: ata_task_ioctl should return ATA registers from sense data User applications using the HDIO_DRIVE_TASK ioctl through libata expect specific ATA registers to be returned to userspace. Verified that ata_task_ioctl correctly returns register values to the smartctl application. Signed-off-by: David Milburn Acked-by: Tejun Heo Cc: Jeff Garzik Signed-off-by: Andrew Morton Signed-off-by: Jeff Garzik --- drivers/ata/libata-scsi.c | 51 +++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 45 insertions(+), 6 deletions(-) (limited to 'drivers/ata') diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 7cc5a4a910a4..d151cf057ef2 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -273,8 +273,8 @@ int ata_task_ioctl(struct scsi_device *scsidev, void __user *arg) { int rc = 0; u8 scsi_cmd[MAX_COMMAND_SIZE]; - u8 args[7]; - struct scsi_sense_hdr sshdr; + u8 args[7], *sensebuf = NULL; + int cmd_result; if (arg == NULL) return -EINVAL; @@ -282,10 +282,14 @@ int ata_task_ioctl(struct scsi_device *scsidev, void __user *arg) if (copy_from_user(args, arg, sizeof(args))) return -EFAULT; + sensebuf = kzalloc(SCSI_SENSE_BUFFERSIZE, GFP_NOIO); + if (!sensebuf) + return -ENOMEM; + memset(scsi_cmd, 0, sizeof(scsi_cmd)); scsi_cmd[0] = ATA_16; scsi_cmd[1] = (3 << 1); /* Non-data */ - /* scsi_cmd[2] is already 0 -- no off.line, cc, or data xfer */ + scsi_cmd[2] = 0x20; /* cc but no off.line or data xfer */ scsi_cmd[4] = args[1]; scsi_cmd[6] = args[2]; scsi_cmd[8] = args[3]; @@ -295,11 +299,46 @@ int ata_task_ioctl(struct scsi_device *scsidev, void __user *arg) /* Good values for timeout and retries? Values below from scsi_ioctl_send_command() for default case... */ - if (scsi_execute_req(scsidev, scsi_cmd, DMA_NONE, NULL, 0, &sshdr, - (10*HZ), 5)) + cmd_result = scsi_execute(scsidev, scsi_cmd, DMA_NONE, NULL, 0, + sensebuf, (10*HZ), 5, 0); + + if (driver_byte(cmd_result) == DRIVER_SENSE) {/* sense data available */ + u8 *desc = sensebuf + 8; + cmd_result &= ~(0xFF<<24); /* DRIVER_SENSE is not an error */ + + /* If we set cc then ATA pass-through will cause a + * check condition even if no error. Filter that. */ + if (cmd_result & SAM_STAT_CHECK_CONDITION) { + struct scsi_sense_hdr sshdr; + scsi_normalize_sense(sensebuf, SCSI_SENSE_BUFFERSIZE, + &sshdr); + if (sshdr.sense_key==0 && + sshdr.asc==0 && sshdr.ascq==0) + cmd_result &= ~SAM_STAT_CHECK_CONDITION; + } + + /* Send userspace ATA registers */ + if (sensebuf[0] == 0x72 && /* format is "descriptor" */ + desc[0] == 0x09) {/* code is "ATA Descriptor" */ + args[0] = desc[13]; /* status */ + args[1] = desc[3]; /* error */ + args[2] = desc[5]; /* sector count (0:7) */ + args[3] = desc[7]; /* lbal */ + args[4] = desc[9]; /* lbam */ + args[5] = desc[11]; /* lbah */ + args[6] = desc[12]; /* select */ + if (copy_to_user(arg, args, sizeof(args))) + rc = -EFAULT; + } + } + + if (cmd_result) { rc = -EIO; + goto error; + } - /* Need code to retrieve data from check condition? */ + error: + kfree(sensebuf); return rc; } -- cgit v1.2.2 From 78981a7c6c34bddbb90da72cf6ce10953e84aad8 Mon Sep 17 00:00:00 2001 From: Robert Hancock Date: Tue, 30 Jan 2007 00:59:18 -0800 Subject: libata: fix translation for START STOP UNIT libata's SCSI translation for the SCSI START STOP UNIT command with the START bit clear (i.e. stopping the drive) appears to be incorrect. It sends an ATA STANDBY command with the time period set to 0, which the code comment says means "now", but the ATA standard says this means disable the standby timer, which effectively does nothing. Change this to issue a STANDBY IMMEDIATE command which will actually spin the drive down. The SAT (SCSI/ATA Translation) standard revision 9 concurs with this choice. Signed-off-by: Robert Hancock Signed-off-by: Andrew Morton Signed-off-by: Jeff Garzik --- drivers/ata/libata-scsi.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'drivers/ata') diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index d151cf057ef2..73902d335767 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -1022,11 +1022,10 @@ static unsigned int ata_scsi_start_stop_xlat(struct ata_queued_cmd *qc) } tf->command = ATA_CMD_VERIFY; /* READ VERIFY */ - } else { - tf->nsect = 0; /* time period value (0 implies now) */ - tf->command = ATA_CMD_STANDBY; - /* Consider: ATA STANDBY IMMEDIATE command */ - } + } else + /* Issue ATA STANDBY IMMEDIATE command */ + tf->command = ATA_CMD_STANDBYNOW1; + /* * Standby and Idle condition timers could be implemented but that * would require libata to implement the Power condition mode page -- cgit v1.2.2 From 161c888b0b4d28775dfe35274ee90c16a91b4365 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 30 Jan 2007 13:23:45 +0000 Subject: [PATCH] pata_platform: fallout from set_mode() change Signed-off-by: Al Viro Signed-off-by: Linus Torvalds --- drivers/ata/pata_platform.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/ata') diff --git a/drivers/ata/pata_platform.c b/drivers/ata/pata_platform.c index 443b1d85c6c4..40ae11cbfda4 100644 --- a/drivers/ata/pata_platform.c +++ b/drivers/ata/pata_platform.c @@ -30,7 +30,7 @@ static int pio_mask = 1; * Provide our own set_mode() as we don't want to change anything that has * already been configured.. */ -static void pata_platform_set_mode(struct ata_port *ap) +static int pata_platform_set_mode(struct ata_port *ap, struct ata_device **unused) { int i; @@ -44,6 +44,7 @@ static void pata_platform_set_mode(struct ata_port *ap) dev->flags |= ATA_DFLAG_PIO; } } + return 0; } static void pata_platform_host_stop(struct ata_host *host) -- cgit v1.2.2