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;