* [git patch] 2.6.x libata fix
@ 2005-07-29 6:31 Jeff Garzik
0 siblings, 0 replies; 6+ messages in thread
From: Jeff Garzik @ 2005-07-29 6:31 UTC (permalink / raw)
To: Linus Torvalds, Andrew Morton; +Cc: linux-ide@vger.kernel.org, Linux Kernel
[-- Attachment #1: Type: text/plain, Size: 183 bytes --]
Please pull from 'upstream' branch of
rsync://rsync.kernel.org/pub/scm/linux/kernel/git/jgarzik/libata-dev.git
to obtain the fix described in the attached diffstat/changelog/patch.
[-- Attachment #2: libata-dev.txt --]
[-- Type: text/plain, Size: 2359 bytes --]
drivers/scsi/ata_piix.c | 19 +++++++++++++------
1 files changed, 13 insertions(+), 6 deletions(-)
commit 7b6dbd6872ca1d0c03dc0e0a7108d79c8dafa793
Author: Greg Felix <gregfelixlkml@gmail.com>
Date: Thu Jul 28 15:54:15 2005 -0400
libata: Check PCI sub-class code before disabling AHCI
This patch adds functionality to check the PCI sub-class code of an
AHCI capable device before disabling AHCI. It fixes a bug where an
ICH7 sata controller is being setup by the BIOS as sub-class 1 (ide)
and the AHCI control registers weren't being initialized, thus causing
an IO error in piix_disable_ahci().
Signed-off-by: Gregory Felix <greg.felix@gmail.com>
diff --git a/drivers/scsi/ata_piix.c b/drivers/scsi/ata_piix.c
--- a/drivers/scsi/ata_piix.c
+++ b/drivers/scsi/ata_piix.c
@@ -38,6 +38,7 @@ enum {
PIIX_IOCFG = 0x54, /* IDE I/O configuration register */
ICH5_PMR = 0x90, /* port mapping register */
ICH5_PCS = 0x92, /* port control and status */
+ PIIX_SCC = 0x0A, /* sub-class code register */
PIIX_FLAG_AHCI = (1 << 28), /* AHCI possible */
PIIX_FLAG_CHECKINTR = (1 << 29), /* make sure PCI INTx enabled */
@@ -62,6 +63,8 @@ enum {
ich6_sata_rm = 4,
ich7_sata = 5,
esb2_sata = 6,
+
+ PIIX_AHCI_DEVICE = 6,
};
static int piix_init_one (struct pci_dev *pdev,
@@ -574,11 +577,11 @@ static int piix_disable_ahci(struct pci_
addr = pci_resource_start(pdev, AHCI_PCI_BAR);
if (!addr || !pci_resource_len(pdev, AHCI_PCI_BAR))
return 0;
-
+
mmio = ioremap(addr, 64);
if (!mmio)
return -ENOMEM;
-
+
tmp = readl(mmio + AHCI_GLOBAL_CTL);
if (tmp & AHCI_ENABLE) {
tmp &= ~AHCI_ENABLE;
@@ -588,7 +591,7 @@ static int piix_disable_ahci(struct pci_
if (tmp & AHCI_ENABLE)
rc = -EIO;
}
-
+
iounmap(mmio);
return rc;
}
@@ -626,9 +629,13 @@ static int piix_init_one (struct pci_dev
port_info[1] = NULL;
if (port_info[0]->host_flags & PIIX_FLAG_AHCI) {
- int rc = piix_disable_ahci(pdev);
- if (rc)
- return rc;
+ u8 tmp;
+ pci_read_config_byte(pdev, PIIX_SCC, &tmp);
+ if (tmp == PIIX_AHCI_DEVICE) {
+ int rc = piix_disable_ahci(pdev);
+ if (rc)
+ return rc;
+ }
}
if (port_info[0]->host_flags & PIIX_FLAG_COMBINED) {
^ permalink raw reply [flat|nested] 6+ messages in thread* [git patch] 2.6.x libata fix
@ 2006-01-09 17:11 Jeff Garzik
2006-01-11 10:18 ` Matt Darcy
0 siblings, 1 reply; 6+ messages in thread
From: Jeff Garzik @ 2006-01-09 17:11 UTC (permalink / raw)
To: Andrew Morton, Linus Torvalds; +Cc: linux-ide, linux-kernel
Please pull from 'upstream-linus' branch of
master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/libata-dev.git
to receive the following updates:
drivers/scsi/sata_nv.c | 30 ++++++++++++++++++++++++------
1 files changed, 24 insertions(+), 6 deletions(-)
Andrew Chew:
sata_nv, spurious interrupts at system startup with MAXTOR 6H500F0 drive
diff --git a/drivers/scsi/sata_nv.c b/drivers/scsi/sata_nv.c
index c0cf52c..bbbb55e 100644
--- a/drivers/scsi/sata_nv.c
+++ b/drivers/scsi/sata_nv.c
@@ -29,6 +29,12 @@
* NV-specific details such as register offsets, SATA phy location,
* hotplug info, etc.
*
+ * 0.10
+ * - Fixed spurious interrupts issue seen with the Maxtor 6H500F0 500GB
+ * drive. Also made the check_hotplug() callbacks return whether there
+ * was a hotplug interrupt or not. This was not the source of the
+ * spurious interrupts, but is the right thing to do anyway.
+ *
* 0.09
* - Fixed bug introduced by 0.08's MCP51 and MCP55 support.
*
@@ -124,10 +130,10 @@ static void nv_scr_write (struct ata_por
static void nv_host_stop (struct ata_host_set *host_set);
static void nv_enable_hotplug(struct ata_probe_ent *probe_ent);
static void nv_disable_hotplug(struct ata_host_set *host_set);
-static void nv_check_hotplug(struct ata_host_set *host_set);
+static int nv_check_hotplug(struct ata_host_set *host_set);
static void nv_enable_hotplug_ck804(struct ata_probe_ent *probe_ent);
static void nv_disable_hotplug_ck804(struct ata_host_set *host_set);
-static void nv_check_hotplug_ck804(struct ata_host_set *host_set);
+static int nv_check_hotplug_ck804(struct ata_host_set *host_set);
enum nv_host_type
{
@@ -176,7 +182,7 @@ struct nv_host_desc
enum nv_host_type host_type;
void (*enable_hotplug)(struct ata_probe_ent *probe_ent);
void (*disable_hotplug)(struct ata_host_set *host_set);
- void (*check_hotplug)(struct ata_host_set *host_set);
+ int (*check_hotplug)(struct ata_host_set *host_set);
};
static struct nv_host_desc nv_device_tbl[] = {
@@ -309,12 +315,16 @@ static irqreturn_t nv_interrupt (int irq
qc = ata_qc_from_tag(ap, ap->active_tag);
if (qc && (!(qc->tf.ctl & ATA_NIEN)))
handled += ata_host_intr(ap, qc);
+ else
+ // No request pending? Clear interrupt status
+ // anyway, in case there's one pending.
+ ap->ops->check_status(ap);
}
}
if (host->host_desc->check_hotplug)
- host->host_desc->check_hotplug(host_set);
+ handled += host->host_desc->check_hotplug(host_set);
spin_unlock_irqrestore(&host_set->lock, flags);
@@ -497,7 +507,7 @@ static void nv_disable_hotplug(struct at
outb(intr_mask, host_set->ports[0]->ioaddr.scr_addr + NV_INT_ENABLE);
}
-static void nv_check_hotplug(struct ata_host_set *host_set)
+static int nv_check_hotplug(struct ata_host_set *host_set)
{
u8 intr_status;
@@ -522,7 +532,11 @@ static void nv_check_hotplug(struct ata_
if (intr_status & NV_INT_STATUS_SDEV_REMOVED)
printk(KERN_WARNING "nv_sata: "
"Secondary device removed\n");
+
+ return 1;
}
+
+ return 0;
}
static void nv_enable_hotplug_ck804(struct ata_probe_ent *probe_ent)
@@ -560,7 +574,7 @@ static void nv_disable_hotplug_ck804(str
pci_write_config_byte(pdev, NV_MCP_SATA_CFG_20, regval);
}
-static void nv_check_hotplug_ck804(struct ata_host_set *host_set)
+static int nv_check_hotplug_ck804(struct ata_host_set *host_set)
{
u8 intr_status;
@@ -585,7 +599,11 @@ static void nv_check_hotplug_ck804(struc
if (intr_status & NV_INT_STATUS_SDEV_REMOVED)
printk(KERN_WARNING "nv_sata: "
"Secondary device removed\n");
+
+ return 1;
}
+
+ return 0;
}
static int __init nv_init(void)
^ permalink raw reply related [flat|nested] 6+ messages in thread* Re: [git patch] 2.6.x libata fix
2006-01-09 17:11 Jeff Garzik
@ 2006-01-11 10:18 ` Matt Darcy
0 siblings, 0 replies; 6+ messages in thread
From: Matt Darcy @ 2006-01-11 10:18 UTC (permalink / raw)
To: Jeff Garzik; +Cc: Andrew Morton, linux-ide, linux-kernel
Jeff Garzik wrote:
>Please pull from 'upstream-linus' branch of
>master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/libata-dev.git
>
>to receive the following updates:
>
> drivers/scsi/sata_nv.c | 30 ++++++++++++++++++++++++------
> 1 files changed, 24 insertions(+), 6 deletions(-)
>
>Andrew Chew:
> sata_nv, spurious interrupts at system startup with MAXTOR 6H500F0 drive
>
>diff --git a/drivers/scsi/sata_nv.c b/drivers/scsi/sata_nv.c
>index c0cf52c..bbbb55e 100644
>--- a/drivers/scsi/sata_nv.c
>+++ b/drivers/scsi/sata_nv.c
>
> <snip reset of patch>
>
>
Hi Jeff, et all
I pulled this down last night from
git.kernel.org/pub/scm/linux/kernel/git/jgarzik/libata-dev.git
as I don't have an account on master.kernel.org, I assume these are the
same physical tree.
This built fine and seemed aware of all the SATA disks on my controller
(as did previous git branches).
Again using my raid5 (7 disks 1.4tb) example, I am unable to build an
array without the machine hanging.
I am able to access the individual disks for a short period of time
before the box hangs totally which I assume is why the raid array will
not build as the access for the disks hangs, not the actual building of
the array.
I havn't got any output yet on the errors (if there are any) as I left
the array building overnight (300+ minutes) and when I woke up this
morning the box had hung, but power saver had come on the screen so I
couldn't see the messages.
I'll do another test this afternoon and try to get some output for you,
but I just thought I'd let you know this was coming.
Aslo FYI: I'm using maxtor SATA disks, so your patch was of particular
interesting to me.
Many thanks,
Matt
^ permalink raw reply [flat|nested] 6+ messages in thread
* [git patch] 2.6.x libata fix
@ 2005-12-04 1:57 Jeff Garzik
0 siblings, 0 replies; 6+ messages in thread
From: Jeff Garzik @ 2005-12-04 1:57 UTC (permalink / raw)
To: Andrew Morton, Linus Torvalds; +Cc: linux-kernel, linux-ide
Please pull from 'upstream-fixes' branch of
master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/libata-dev.git
to receive the following updates:
drivers/scsi/libata-scsi.c | 9 +++++++--
1 files changed, 7 insertions(+), 2 deletions(-)
Tejun Heo:
libata: fix ata_scsi_pass_thru error handling
diff --git a/drivers/scsi/libata-scsi.c b/drivers/scsi/libata-scsi.c
index 3b4ca55..379e870 100644
--- a/drivers/scsi/libata-scsi.c
+++ b/drivers/scsi/libata-scsi.c
@@ -2239,7 +2239,7 @@ ata_scsi_pass_thru(struct ata_queued_cmd
struct scsi_cmnd *cmd = qc->scsicmd;
if ((tf->protocol = ata_scsi_map_proto(scsicmd[1])) == ATA_PROT_UNKNOWN)
- return 1;
+ goto invalid_fld;
/*
* 12 and 16 byte CDBs use different offsets to
@@ -2301,7 +2301,7 @@ ata_scsi_pass_thru(struct ata_queued_cmd
*/
if ((tf->command == ATA_CMD_SET_FEATURES)
&& (tf->feature == SETFEATURES_XFER))
- return 1;
+ goto invalid_fld;
/*
* Set flags so that all registers will be written,
@@ -2322,6 +2322,11 @@ ata_scsi_pass_thru(struct ata_queued_cmd
qc->nsect = cmd->bufflen / ATA_SECT_SIZE;
return 0;
+
+ invalid_fld:
+ ata_scsi_set_sense(qc->scsicmd, ILLEGAL_REQUEST, 0x24, 0x00);
+ /* "Invalid field in cdb" */
+ return 1;
}
/**
^ permalink raw reply related [flat|nested] 6+ messages in thread* [git patch] 2.6.x libata fix
@ 2005-06-27 12:21 Jeff Garzik
0 siblings, 0 replies; 6+ messages in thread
From: Jeff Garzik @ 2005-06-27 12:21 UTC (permalink / raw)
To: Andrew Morton, Linus Torvalds; +Cc: linux-ide@vger.kernel.org, Linux Kernel
[-- Attachment #1: Type: text/plain, Size: 178 bytes --]
Please pull from the 'upstream' branch of
rsync://rsync.kernel.org/pub/scm/linux/kernel/git/jgarzik/libata-dev.git
to obtain the fix (and cleanup) described in the attachment.
[-- Attachment #2: libata-dev.txt --]
[-- Type: text/plain, Size: 1268 bytes --]
drivers/scsi/libata-scsi.c | 16 +++++++++++-----
1 files changed, 11 insertions(+), 5 deletions(-)
Philip Pokorny:
libata fix read capacity handling for more than 2TB
diff --git a/drivers/scsi/libata-scsi.c b/drivers/scsi/libata-scsi.c
--- a/drivers/scsi/libata-scsi.c
+++ b/drivers/scsi/libata-scsi.c
@@ -1176,8 +1176,12 @@ unsigned int ata_scsiop_read_cap(struct
n_sectors = ata_id_u32(args->id, 60);
n_sectors--; /* ATA TotalUserSectors - 1 */
- tmp = n_sectors; /* note: truncates, if lba48 */
if (args->cmd->cmnd[0] == READ_CAPACITY) {
+ if( n_sectors >= 0xffffffffULL )
+ tmp = 0xffffffff ; /* Return max count on overflow */
+ else
+ tmp = n_sectors ;
+
/* sector count, 32-bit */
rbuf[0] = tmp >> (8 * 3);
rbuf[1] = tmp >> (8 * 2);
@@ -1191,10 +1195,12 @@ unsigned int ata_scsiop_read_cap(struct
} else {
/* sector count, 64-bit */
- rbuf[2] = n_sectors >> (8 * 7);
- rbuf[3] = n_sectors >> (8 * 6);
- rbuf[4] = n_sectors >> (8 * 5);
- rbuf[5] = n_sectors >> (8 * 4);
+ tmp = n_sectors >> (8 * 4);
+ rbuf[2] = tmp >> (8 * 3);
+ rbuf[3] = tmp >> (8 * 2);
+ rbuf[4] = tmp >> (8 * 1);
+ rbuf[5] = tmp;
+ tmp = n_sectors;
rbuf[6] = tmp >> (8 * 3);
rbuf[7] = tmp >> (8 * 2);
rbuf[8] = tmp >> (8 * 1);
^ permalink raw reply [flat|nested] 6+ messages in thread* [git patch] 2.6.x libata fix
@ 2005-05-26 16:56 Jeff Garzik
0 siblings, 0 replies; 6+ messages in thread
From: Jeff Garzik @ 2005-05-26 16:56 UTC (permalink / raw)
To: Andrew Morton, Linus Torvalds; +Cc: linux-ide@vger.kernel.org, Linux Kernel
[-- Attachment #1: Type: text/plain, Size: 159 bytes --]
Please pull branch 'misc-fixes' of
rsync://rsync.kernel.org/pub/scm/linux/kernel/git/jgarzik/libata-dev.git
to obtain the fix described in the attachment.
[-- Attachment #2: libata-2.6.txt --]
[-- Type: text/plain, Size: 3129 bytes --]
drivers/scsi/libata-core.c | 13 +++++++------
1 files changed, 7 insertions(+), 6 deletions(-)
commit 32529e0128923e42126b5d14e444c18295a452ba
tree d50736f63bd9692076d68c3f8748f1b6bf540a80
parent bef9c558841604116704e10b3d9ff3dbf4939423
author Albert Lee <albertcc@tw.ibm.com> Thu, 26 May 2005 11:49:42 -0400
committer Jeff Garzik <jgarzik@pobox.com> Thu, 26 May 2005 11:49:42 -0400
[PATCH] libata: Fix zero sg_dma_len() on 64-bit platform
When testing ATAPI PIO data transfer on the ppc64 platform, __atapi_pio_bytes() got zero when
sg_dma_len() is used. I checked the <asm-ppc64/scatterlish.h>, the struct scatterlist is defined as:
struct scatterlist {
struct page *page;
unsigned int offset;
unsigned int length;
/* For TCE support */
u32 dma_address;
u32 dma_length;
};
#define sg_dma_address(sg) ((sg)->dma_address)
#define sg_dma_len(sg) ((sg)->dma_length)
So, if the scatterlist is not DMA mapped, sg_dma_len() will return zero on ppc64.
The same problem should occur on the x86-64 platform.
On the i386 platform, sg_dma_len() returns sg->length, that's why the problem does not occur on an i386.
Changes:
- Use sg->length if the scatterlist is not DMA mapped (yet).
Signed-off-by: Albert Lee <albertcc@tw.ibm.com>
--------------------------
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c
--- a/drivers/scsi/libata-core.c
+++ b/drivers/scsi/libata-core.c
@@ -2071,7 +2071,7 @@ void ata_sg_init_one(struct ata_queued_c
sg = qc->sg;
sg->page = virt_to_page(buf);
sg->offset = (unsigned long) buf & ~PAGE_MASK;
- sg_dma_len(sg) = buflen;
+ sg->length = buflen;
}
void ata_sg_init(struct ata_queued_cmd *qc, struct scatterlist *sg,
@@ -2101,11 +2101,12 @@ static int ata_sg_setup_one(struct ata_q
dma_addr_t dma_address;
dma_address = dma_map_single(ap->host_set->dev, qc->buf_virt,
- sg_dma_len(sg), dir);
+ sg->length, dir);
if (dma_mapping_error(dma_address))
return -1;
sg_dma_address(sg) = dma_address;
+ sg_dma_len(sg) = sg->length;
DPRINTK("mapped buffer of %d bytes for %s\n", sg_dma_len(sg),
qc->tf.flags & ATA_TFLAG_WRITE ? "write" : "read");
@@ -2310,7 +2311,7 @@ static void ata_pio_sector(struct ata_qu
qc->cursect++;
qc->cursg_ofs++;
- if ((qc->cursg_ofs * ATA_SECT_SIZE) == sg_dma_len(&sg[qc->cursg])) {
+ if ((qc->cursg_ofs * ATA_SECT_SIZE) == (&sg[qc->cursg])->length) {
qc->cursg++;
qc->cursg_ofs = 0;
}
@@ -2347,7 +2348,7 @@ next_page:
page = nth_page(page, (offset >> PAGE_SHIFT));
offset %= PAGE_SIZE;
- count = min(sg_dma_len(sg) - qc->cursg_ofs, bytes);
+ count = min(sg->length - qc->cursg_ofs, bytes);
/* don't cross page boundaries */
count = min(count, (unsigned int)PAGE_SIZE - offset);
@@ -2358,7 +2359,7 @@ next_page:
qc->curbytes += count;
qc->cursg_ofs += count;
- if (qc->cursg_ofs == sg_dma_len(sg)) {
+ if (qc->cursg_ofs == sg->length) {
qc->cursg++;
qc->cursg_ofs = 0;
}
@@ -2371,7 +2372,7 @@ next_page:
kunmap(page);
if (bytes) {
- if (qc->cursg_ofs < sg_dma_len(sg))
+ if (qc->cursg_ofs < sg->length)
goto next_page;
goto next_sg;
}
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2006-01-11 10:19 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-07-29 6:31 [git patch] 2.6.x libata fix Jeff Garzik
-- strict thread matches above, loose matches on Subject: below --
2006-01-09 17:11 Jeff Garzik
2006-01-11 10:18 ` Matt Darcy
2005-12-04 1:57 Jeff Garzik
2005-06-27 12:21 Jeff Garzik
2005-05-26 16:56 Jeff Garzik
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox