* [git patch] libata critical fix
@ 2007-10-12 4:25 Jeff Garzik
2007-10-12 16:26 ` [stable] " Greg KH
0 siblings, 1 reply; 2+ messages in thread
From: Jeff Garzik @ 2007-10-12 4:25 UTC (permalink / raw)
To: Andrew Morton, Linus Torvalds; +Cc: linux-ide, LKML, stable
There is a lingering corruption in sata_mv that took me several days to
narrow down... the failure to mask off the lower 16 bits of the S/G
length was leading to corruption, because this stomped on other
important bits in that S/G entry.
This should fix it (stable aka 2.6.23.1 needs this too):
Please pull from 'upstream-fixes' branch of
master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/libata-dev.git upstream-fixes
to receive the following updates:
drivers/ata/sata_mv.c | 27 ++++++++++++++++++---------
1 files changed, 18 insertions(+), 9 deletions(-)
commit 6c08772e49622e90d39903e7ff0be1a0f463ac86
Author: Jeff Garzik <jeff@garzik.org>
Date: Fri Oct 12 00:16:23 2007 -0400
[libata] sata_mv: more S/G fixes
* corruption fix: we only want the lower 16 bits of length (0 == 64kb)
* ditto: the upper layer sets max-phys-segments to LIBATA_MAX_PRD,
so we must reset it to own hw-specific length.
* delete unused mv_fill_sg() return value
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c
index cb7dec9..d9832e2 100644
--- a/drivers/ata/sata_mv.c
+++ b/drivers/ata/sata_mv.c
@@ -69,10 +69,11 @@
#include <linux/device.h>
#include <scsi/scsi_host.h>
#include <scsi/scsi_cmnd.h>
+#include <scsi/scsi_device.h>
#include <linux/libata.h>
#define DRV_NAME "sata_mv"
-#define DRV_VERSION "1.0"
+#define DRV_VERSION "1.01"
enum {
/* BAR's are enumerated in terms of pci_resource_start() terms */
@@ -420,6 +421,7 @@ static void mv_error_handler(struct ata_port *ap);
static void mv_post_int_cmd(struct ata_queued_cmd *qc);
static void mv_eh_freeze(struct ata_port *ap);
static void mv_eh_thaw(struct ata_port *ap);
+static int mv_slave_config(struct scsi_device *sdev);
static int mv_init_one(struct pci_dev *pdev, const struct pci_device_id *ent);
static void mv5_phy_errata(struct mv_host_priv *hpriv, void __iomem *mmio,
@@ -457,7 +459,7 @@ static struct scsi_host_template mv5_sht = {
.use_clustering = 1,
.proc_name = DRV_NAME,
.dma_boundary = MV_DMA_BOUNDARY,
- .slave_configure = ata_scsi_slave_config,
+ .slave_configure = mv_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
};
@@ -475,7 +477,7 @@ static struct scsi_host_template mv6_sht = {
.use_clustering = 1,
.proc_name = DRV_NAME,
.dma_boundary = MV_DMA_BOUNDARY,
- .slave_configure = ata_scsi_slave_config,
+ .slave_configure = mv_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
};
@@ -763,6 +765,17 @@ static void mv_irq_clear(struct ata_port *ap)
{
}
+static int mv_slave_config(struct scsi_device *sdev)
+{
+ int rc = ata_scsi_slave_config(sdev);
+ if (rc)
+ return rc;
+
+ blk_queue_max_phys_segments(sdev->request_queue, MV_MAX_SG_CT / 2);
+
+ return 0; /* scsi layer doesn't check return value, sigh */
+}
+
static void mv_set_edma_ptrs(void __iomem *port_mmio,
struct mv_host_priv *hpriv,
struct mv_port_priv *pp)
@@ -1130,10 +1143,9 @@ static void mv_port_stop(struct ata_port *ap)
* LOCKING:
* Inherited from caller.
*/
-static unsigned int mv_fill_sg(struct ata_queued_cmd *qc)
+static void mv_fill_sg(struct ata_queued_cmd *qc)
{
struct mv_port_priv *pp = qc->ap->private_data;
- unsigned int n_sg = 0;
struct scatterlist *sg;
struct mv_sg *mv_sg;
@@ -1151,7 +1163,7 @@ static unsigned int mv_fill_sg(struct ata_queued_cmd *qc)
mv_sg->addr = cpu_to_le32(addr & 0xffffffff);
mv_sg->addr_hi = cpu_to_le32((addr >> 16) >> 16);
- mv_sg->flags_size = cpu_to_le32(len);
+ mv_sg->flags_size = cpu_to_le32(len & 0xffff);
sg_len -= len;
addr += len;
@@ -1160,12 +1172,9 @@ static unsigned int mv_fill_sg(struct ata_queued_cmd *qc)
mv_sg->flags_size |= cpu_to_le32(EPRD_FLAG_END_OF_TBL);
mv_sg++;
- n_sg++;
}
}
-
- return n_sg;
}
static inline void mv_crqb_pack_cmd(__le16 *cmdw, u8 data, u8 addr, unsigned last)
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [stable] [git patch] libata critical fix
2007-10-12 4:25 [git patch] libata critical fix Jeff Garzik
@ 2007-10-12 16:26 ` Greg KH
0 siblings, 0 replies; 2+ messages in thread
From: Greg KH @ 2007-10-12 16:26 UTC (permalink / raw)
To: Jeff Garzik; +Cc: Andrew Morton, Linus Torvalds, linux-ide, LKML, stable
On Fri, Oct 12, 2007 at 12:25:15AM -0400, Jeff Garzik wrote:
>
> There is a lingering corruption in sata_mv that took me several days to
> narrow down... the failure to mask off the lower 16 bits of the S/G
> length was leading to corruption, because this stomped on other
> important bits in that S/G entry.
>
> This should fix it (stable aka 2.6.23.1 needs this too):
I'm guessing that this is critical enough to do a 2.6.23.1 with this fix
in it right now. Any objections to that?
thanks,
greg k-h
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2007-10-12 16:33 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-10-12 4:25 [git patch] libata critical fix Jeff Garzik
2007-10-12 16:26 ` [stable] " Greg KH
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).