BK users:
bk pull bk://gkernel.bkbits.net/libata-2.4
This will update the following files:
Documentation/DocBook/Makefile | 2
Documentation/DocBook/libata.tmpl | 5 ++
drivers/pci/quirks.c | 85 ++++++++++++++++++++++++++++++++++++++
drivers/scsi/ahci.c | 15 +++++-
drivers/scsi/ata_piix.c | 3 -
drivers/scsi/libata-core.c | 24 ++++++++--
include/linux/ioport.h | 1
kernel/ksyms.c | 1
kernel/resource.c | 10 ++++
9 files changed, 138 insertions(+), 8 deletions(-)
through these ChangeSets:
Arjan van de Ven:
o [libata ata_piix] Use standard headers from include/scsi, not drivers/scsi
Brett Russ:
o AHCI: fix fatal error int handling
Jason Gaston:
o [PCI] update SATA PCI quirk for Intel ICH7
Jeff Garzik:
o [libata ahci] support ->tf_read hook
o [PCI, libata] Fix "combined mode" PCI quirk for ICH6
o [libata ata_piix] re-enable combined mode support
o [libata ata_piix] ->qc_prep hook
o [libata ata_piix] fix DocBook docs
o [libata ata_piix] add ->bmdma_setup hook
o [libata] re-merge the rest of the 2.4 junk
diff -Nru a/Documentation/DocBook/Makefile b/Documentation/DocBook/Makefile
--- a/Documentation/DocBook/Makefile 2005-03-10 13:51:32 -05:00
+++ b/Documentation/DocBook/Makefile 2005-03-10 13:51:32 -05:00
@@ -82,10 +82,12 @@
libata.sgml: libata.tmpl $(TOPDIR)/drivers/scsi/libata-core.c \
$(TOPDIR)/drivers/scsi/libata-scsi.c \
$(TOPDIR)/drivers/scsi/sata_sil.c \
+ $(TOPDIR)/drivers/scsi/ata_piix.c \
$(TOPDIR)/drivers/scsi/sata_via.c
$(TOPDIR)/scripts/docgen $(TOPDIR)/drivers/scsi/libata-core.c \
$(TOPDIR)/drivers/scsi/libata-scsi.c \
$(TOPDIR)/drivers/scsi/sata_sil.c \
+ $(TOPDIR)/drivers/scsi/ata_piix.c \
$(TOPDIR)/drivers/scsi/sata_via.c \
< libata.tmpl > libata.sgml
diff -Nru a/Documentation/DocBook/libata.tmpl b/Documentation/DocBook/libata.tmpl
--- a/Documentation/DocBook/libata.tmpl 2005-03-10 13:51:32 -05:00
+++ b/Documentation/DocBook/libata.tmpl 2005-03-10 13:51:32 -05:00
@@ -267,6 +267,11 @@
!Idrivers/scsi/libata-scsi.c
+
+ ata_piix Internals
+!Idrivers/scsi/ata_piix.c
+
+
sata_sil Internals
!Idrivers/scsi/sata_sil.c
diff -Nru a/drivers/pci/quirks.c b/drivers/pci/quirks.c
--- a/drivers/pci/quirks.c 2005-03-10 13:51:32 -05:00
+++ b/drivers/pci/quirks.c 2005-03-10 13:51:32 -05:00
@@ -702,6 +702,83 @@
}
}
+#ifdef CONFIG_SCSI_SATA
+static void __init quirk_intel_ide_combined(struct pci_dev *pdev)
+{
+ u8 prog, comb, tmp;
+ int ich = 0;
+
+ /*
+ * Narrow down to Intel SATA PCI devices.
+ */
+ switch (pdev->device) {
+ /* PCI ids taken from drivers/scsi/ata_piix.c */
+ case 0x24d1:
+ case 0x24df:
+ case 0x25a3:
+ case 0x25b0:
+ ich = 5;
+ break;
+ case 0x2651:
+ case 0x2652:
+ case 0x2653:
+ ich = 6;
+ break;
+ case 0x27c0:
+ case 0x27c4:
+ ich = 7;
+ break;
+ default:
+ /* we do not handle this PCI device */
+ return;
+ }
+
+ /*
+ * Read combined mode register.
+ */
+ pci_read_config_byte(pdev, 0x90, &tmp); /* combined mode reg */
+
+ if (ich == 5) {
+ tmp &= 0x6; /* interesting bits 2:1, PATA primary/secondary */
+ if (tmp == 0x4) /* bits 10x */
+ comb = (1 << 0); /* SATA port 0, PATA port 1 */
+ else if (tmp == 0x6) /* bits 11x */
+ comb = (1 << 2); /* PATA port 0, SATA port 1 */
+ else
+ return; /* not in combined mode */
+ } else {
+ WARN_ON((ich != 6) && (ich != 7));
+ tmp &= 0x3; /* interesting bits 1:0 */
+ if (tmp & (1 << 0))
+ comb = (1 << 2); /* PATA port 0, SATA port 1 */
+ else if (tmp & (1 << 1))
+ comb = (1 << 0); /* SATA port 0, PATA port 1 */
+ else
+ return; /* not in combined mode */
+ }
+
+ /*
+ * Read programming interface register.
+ * (Tells us if it's legacy or native mode)
+ */
+ pci_read_config_byte(pdev, PCI_CLASS_PROG, &prog);
+
+ /* if SATA port is in native mode, we're ok. */
+ if (prog & comb)
+ return;
+
+ /* SATA port is in legacy mode. Reserve port so that
+ * IDE driver does not attempt to use it. If request_region
+ * fails, it will be obvious at boot time, so we don't bother
+ * checking return values.
+ */
+ if (comb == (1 << 0))
+ request_region(0x1f0, 8, "libata"); /* port 0 */
+ else
+ request_region(0x170, 8, "libata"); /* port 1 */
+}
+#endif /* CONFIG_SCSI_SATA */
+
/*
* The main table of quirks.
*/
@@ -787,6 +864,14 @@
{ PCI_FIXUP_HEADER, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_7205_0, asus_hides_smbus_hostbridge },
{ PCI_FIXUP_HEADER, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0, asus_hides_smbus_lpc },
{ PCI_FIXUP_HEADER, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0, asus_hides_smbus_lpc },
+
+#ifdef CONFIG_SCSI_SATA
+ /* Fixup BIOSes that configure Parallel ATA (PATA / IDE) and
+ * Serial ATA (SATA) into the same PCI ID.
+ */
+ { PCI_FIXUP_FINAL, PCI_VENDOR_ID_INTEL, PCI_ANY_ID,
+ quirk_intel_ide_combined },
+#endif /* CONFIG_SCSI_SATA */
{ 0 }
};
diff -Nru a/drivers/scsi/ahci.c b/drivers/scsi/ahci.c
--- a/drivers/scsi/ahci.c 2005-03-10 13:51:32 -05:00
+++ b/drivers/scsi/ahci.c 2005-03-10 13:51:32 -05:00
@@ -176,6 +176,7 @@
static int ahci_port_start(struct ata_port *ap);
static void ahci_port_stop(struct ata_port *ap);
static void ahci_host_stop(struct ata_host_set *host_set);
+static void ahci_tf_read(struct ata_port *ap, struct ata_taskfile *tf);
static void ahci_qc_prep(struct ata_queued_cmd *qc);
static u8 ahci_check_status(struct ata_port *ap);
static u8 ahci_check_err(struct ata_port *ap);
@@ -209,6 +210,8 @@
.check_err = ahci_check_err,
.dev_select = ata_noop_dev_select,
+ .tf_read = ahci_tf_read,
+
.phy_reset = ahci_phy_reset,
.qc_prep = ahci_qc_prep,
@@ -462,6 +465,14 @@
return (readl(mmio + PORT_TFDATA) >> 8) & 0xFF;
}
+static void ahci_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
+{
+ struct ahci_port_priv *pp = ap->private_data;
+ u8 *d2h_fis = pp->rx_fis + RX_FIS_D2H_REG;
+
+ ata_tf_from_fis(d2h_fis, tf);
+}
+
static void ahci_fill_sg(struct ata_queued_cmd *qc)
{
struct ahci_port_priv *pp = qc->ap->private_data;
@@ -538,7 +549,7 @@
/* stop DMA */
tmp = readl(port_mmio + PORT_CMD);
- tmp &= PORT_CMD_START | PORT_CMD_FIS_RX;
+ tmp &= ~PORT_CMD_START;
writel(tmp, port_mmio + PORT_CMD);
/* wait for engine to stop. TODO: this could be
@@ -570,7 +581,7 @@
/* re-start DMA */
tmp = readl(port_mmio + PORT_CMD);
- tmp |= PORT_CMD_START | PORT_CMD_FIS_RX;
+ tmp |= PORT_CMD_START;
writel(tmp, port_mmio + PORT_CMD);
readl(port_mmio + PORT_CMD); /* flush */
diff -Nru a/drivers/scsi/ata_piix.c b/drivers/scsi/ata_piix.c
--- a/drivers/scsi/ata_piix.c 2005-03-10 13:51:32 -05:00
+++ b/drivers/scsi/ata_piix.c 2005-03-10 13:51:32 -05:00
@@ -643,8 +643,7 @@
port_info[pata_chan] = &piix_port_info[ich5_pata];
n_ports++;
- printk(KERN_ERR DRV_NAME ": combined mode not supported\n");
- return -ENODEV;
+ printk(KERN_ERR DRV_NAME ": combined mode detected\n");
}
return ata_pci_init_one(pdev, port_info, n_ports);
diff -Nru a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c
--- a/drivers/scsi/libata-core.c 2005-03-10 13:51:32 -05:00
+++ b/drivers/scsi/libata-core.c 2005-03-10 13:51:32 -05:00
@@ -3787,14 +3787,30 @@
if (legacy_mode) {
if (!request_region(0x1f0, 8, "libata")) {
- disable_dev_on_err = 0;
- printk(KERN_WARNING "ata: 0x1f0 IDE port busy\n");
+ struct resource *conflict, res;
+ res.start = 0x1f0;
+ res.end = 0x1f0 + 8 - 1;
+ conflict = ____request_resource(&ioport_resource, &res);
+ if (!strcmp(conflict->name, "libata"))
+ legacy_mode |= (1 << 0);
+ else {
+ disable_dev_on_err = 0;
+ printk(KERN_WARNING "ata: 0x1f0 IDE port busy\n");
+ }
} else
legacy_mode |= (1 << 0);
if (!request_region(0x170, 8, "libata")) {
- disable_dev_on_err = 0;
- printk(KERN_WARNING "ata: 0x170 IDE port busy\n");
+ struct resource *conflict, res;
+ res.start = 0x170;
+ res.end = 0x170 + 8 - 1;
+ conflict = ____request_resource(&ioport_resource, &res);
+ if (!strcmp(conflict->name, "libata"))
+ legacy_mode |= (1 << 1);
+ else {
+ disable_dev_on_err = 0;
+ printk(KERN_WARNING "ata: 0x170 IDE port busy\n");
+ }
} else
legacy_mode |= (1 << 1);
}
diff -Nru a/include/linux/ioport.h b/include/linux/ioport.h
--- a/include/linux/ioport.h 2005-03-10 13:51:32 -05:00
+++ b/include/linux/ioport.h 2005-03-10 13:51:32 -05:00
@@ -85,6 +85,7 @@
extern int check_resource(struct resource *root, unsigned long, unsigned long);
extern int request_resource(struct resource *root, struct resource *new);
+extern struct resource * ____request_resource(struct resource *root, struct resource *new);
extern int release_resource(struct resource *new);
extern int allocate_resource(struct resource *root, struct resource *new,
unsigned long size,
diff -Nru a/kernel/ksyms.c b/kernel/ksyms.c
--- a/kernel/ksyms.c 2005-03-10 13:51:32 -05:00
+++ b/kernel/ksyms.c 2005-03-10 13:51:32 -05:00
@@ -448,6 +448,7 @@
#endif
/* resource handling */
+EXPORT_SYMBOL_GPL(____request_resource); /* may disappear in a few months */
EXPORT_SYMBOL(request_resource);
EXPORT_SYMBOL(release_resource);
EXPORT_SYMBOL(allocate_resource);
diff -Nru a/kernel/resource.c b/kernel/resource.c
--- a/kernel/resource.c 2005-03-10 13:51:32 -05:00
+++ b/kernel/resource.c 2005-03-10 13:51:32 -05:00
@@ -166,6 +166,16 @@
return conflict ? -EBUSY : 0;
}
+struct resource *____request_resource(struct resource *root, struct resource *new)
+{
+ struct resource *conflict;
+
+ write_lock(&resource_lock);
+ conflict = __request_resource(root, new);
+ write_unlock(&resource_lock);
+ return conflict;
+}
+
int release_resource(struct resource *old)
{
int retval;