Skip to content

Commit

Permalink
Merge branch 'upstream-linus' of master.kernel.org:/pub/scm/linux/ker…
Browse files Browse the repository at this point in the history
…nel/git/jgarzik/libata-dev

* 'upstream-linus' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/libata-dev:
  libata: Don't fail device revalidation for bad _GTF methods
  libata: port and host should be stopped before hardware resources are released
  libata: skip 0xff polling for PATA controllers
  libata: pata_platform: Support polling-mode configuration.
  libata: Support PIO polling-only hosts.
  libata sata_qstor conversion to new error handling (EH).
  libata sata_qstor workaround for spurious interrupts
  libata sata_qstor nuke idle state
  nv_hardreset: update dangling reference to bugzilla entry
  ata_piix: add SATELLITE PRO U200 to broken suspend list
  • Loading branch information
Linus Torvalds committed Nov 10, 2007
2 parents 1da63a2 + 037f6bb commit 487350e
Show file tree
Hide file tree
Showing 6 changed files with 172 additions and 74 deletions.
7 changes: 7 additions & 0 deletions drivers/ata/ata_piix.c
Original file line number Diff line number Diff line change
Expand Up @@ -959,6 +959,13 @@ static int piix_broken_suspend(void)
DMI_MATCH(DMI_PRODUCT_NAME, "Satellite U200"),
},
},
{
.ident = "Satellite Pro U200",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
DMI_MATCH(DMI_PRODUCT_NAME, "SATELLITE PRO U200"),
},
},
{
.ident = "Satellite U205",
.matches = {
Expand Down
10 changes: 2 additions & 8 deletions drivers/ata/libata-acpi.c
Original file line number Diff line number Diff line change
Expand Up @@ -312,7 +312,7 @@ EXPORT_SYMBOL_GPL(ata_acpi_stm);
*
* RETURNS:
* Number of taskfiles on success, 0 if _GTF doesn't exist or doesn't
* contain valid data. -errno on other errors.
* contain valid data.
*/
static int ata_dev_get_GTF(struct ata_device *dev, struct ata_acpi_gtf **gtf,
void **ptr_to_free)
Expand All @@ -339,7 +339,6 @@ static int ata_dev_get_GTF(struct ata_device *dev, struct ata_acpi_gtf **gtf,
ata_dev_printk(dev, KERN_WARNING,
"_GTF evaluation failed (AE 0x%x)\n",
status);
rc = -EIO;
}
goto out_free;
}
Expand All @@ -359,15 +358,13 @@ static int ata_dev_get_GTF(struct ata_device *dev, struct ata_acpi_gtf **gtf,
ata_dev_printk(dev, KERN_WARNING,
"_GTF unexpected object type 0x%x\n",
out_obj->type);
rc = -EINVAL;
goto out_free;
}

if (out_obj->buffer.length % REGS_PER_GTF) {
ata_dev_printk(dev, KERN_WARNING,
"unexpected _GTF length (%d)\n",
out_obj->buffer.length);
rc = -EINVAL;
goto out_free;
}

Expand Down Expand Up @@ -511,10 +508,7 @@ static int ata_acpi_exec_tfs(struct ata_device *dev)
int gtf_count, i, rc;

/* get taskfiles */
rc = ata_dev_get_GTF(dev, &gtf, &ptr_to_free);
if (rc < 0)
return rc;
gtf_count = rc;
gtf_count = ata_dev_get_GTF(dev, &gtf, &ptr_to_free);

/* execute them */
for (i = 0, rc = 0; i < gtf_count; i++) {
Expand Down
78 changes: 60 additions & 18 deletions drivers/ata/libata-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -3373,14 +3373,20 @@ void ata_wait_after_reset(struct ata_port *ap, unsigned long deadline)
* to clear 0xff after reset. For example, HHD424020F7SV00
* iVDR needs >= 800ms while. Quantum GoVault needs even more
* than that.
*
* Note that some PATA controllers (pata_ali) explode if
* status register is read more than once when there's no
* device attached.
*/
while (1) {
u8 status = ata_chk_status(ap);
if (ap->flags & ATA_FLAG_SATA) {
while (1) {
u8 status = ata_chk_status(ap);

if (status != 0xff || time_after(jiffies, deadline))
return;
if (status != 0xff || time_after(jiffies, deadline))
return;

msleep(50);
msleep(50);
}
}
}

Expand Down Expand Up @@ -6815,19 +6821,6 @@ static void ata_host_release(struct device *gendev, void *res)
struct ata_host *host = dev_get_drvdata(gendev);
int i;

for (i = 0; i < host->n_ports; i++) {
struct ata_port *ap = host->ports[i];

if (!ap)
continue;

if ((host->flags & ATA_HOST_STARTED) && ap->ops->port_stop)
ap->ops->port_stop(ap);
}

if ((host->flags & ATA_HOST_STARTED) && host->ops->host_stop)
host->ops->host_stop(host);

for (i = 0; i < host->n_ports; i++) {
struct ata_port *ap = host->ports[i];

Expand Down Expand Up @@ -6960,6 +6953,24 @@ struct ata_host *ata_host_alloc_pinfo(struct device *dev,
return host;
}

static void ata_host_stop(struct device *gendev, void *res)
{
struct ata_host *host = dev_get_drvdata(gendev);
int i;

WARN_ON(!(host->flags & ATA_HOST_STARTED));

for (i = 0; i < host->n_ports; i++) {
struct ata_port *ap = host->ports[i];

if (ap->ops->port_stop)
ap->ops->port_stop(ap);
}

if (host->ops->host_stop)
host->ops->host_stop(host);
}

/**
* ata_host_start - start and freeze ports of an ATA host
* @host: ATA host to start ports for
Expand All @@ -6978,6 +6989,8 @@ struct ata_host *ata_host_alloc_pinfo(struct device *dev,
*/
int ata_host_start(struct ata_host *host)
{
int have_stop = 0;
void *start_dr = NULL;
int i, rc;

if (host->flags & ATA_HOST_STARTED)
Expand All @@ -6989,6 +7002,22 @@ int ata_host_start(struct ata_host *host)
if (!host->ops && !ata_port_is_dummy(ap))
host->ops = ap->ops;

if (ap->ops->port_stop)
have_stop = 1;
}

if (host->ops->host_stop)
have_stop = 1;

if (have_stop) {
start_dr = devres_alloc(ata_host_stop, 0, GFP_KERNEL);
if (!start_dr)
return -ENOMEM;
}

for (i = 0; i < host->n_ports; i++) {
struct ata_port *ap = host->ports[i];

if (ap->ops->port_start) {
rc = ap->ops->port_start(ap);
if (rc) {
Expand All @@ -7001,6 +7030,8 @@ int ata_host_start(struct ata_host *host)
ata_eh_freeze_port(ap);
}

if (start_dr)
devres_add(host->dev, start_dr);
host->flags |= ATA_HOST_STARTED;
return 0;

Expand All @@ -7011,6 +7042,7 @@ int ata_host_start(struct ata_host *host)
if (ap->ops->port_stop)
ap->ops->port_stop(ap);
}
devres_free(start_dr);
return rc;
}

Expand Down Expand Up @@ -7178,6 +7210,10 @@ int ata_host_register(struct ata_host *host, struct scsi_host_template *sht)
* request IRQ and register it. This helper takes necessasry
* arguments and performs the three steps in one go.
*
* An invalid IRQ skips the IRQ registration and expects the host to
* have set polling mode on the port. In this case, @irq_handler
* should be NULL.
*
* LOCKING:
* Inherited from calling layer (may sleep).
*
Expand All @@ -7194,6 +7230,12 @@ int ata_host_activate(struct ata_host *host, int irq,
if (rc)
return rc;

/* Special case for polling mode */
if (!irq) {
WARN_ON(irq_handler);
return ata_host_register(host, sht);
}

rc = devm_request_irq(host->dev, irq, irq_handler, irq_flags,
dev_driver_string(host->dev), host);
if (rc)
Expand Down
35 changes: 28 additions & 7 deletions drivers/ata/pata_platform.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
* Generic platform device PATA driver
*
* Copyright (C) 2006 Paul Mundt
* Copyright (C) 2006 - 2007 Paul Mundt
*
* Based on pata_pcmcia:
*
Expand All @@ -22,7 +22,7 @@
#include <linux/pata_platform.h>

#define DRV_NAME "pata_platform"
#define DRV_VERSION "1.1"
#define DRV_VERSION "1.2"

static int pio_mask = 1;

Expand Down Expand Up @@ -120,15 +120,20 @@ static void pata_platform_setup_port(struct ata_ioports *ioaddr,
* Register a platform bus IDE interface. Such interfaces are PIO and we
* assume do not support IRQ sharing.
*
* Platform devices are expected to contain 3 resources per port:
* Platform devices are expected to contain at least 2 resources per port:
*
* - I/O Base (IORESOURCE_IO or IORESOURCE_MEM)
* - CTL Base (IORESOURCE_IO or IORESOURCE_MEM)
*
* and optionally:
*
* - IRQ (IORESOURCE_IRQ)
*
* If the base resources are both mem types, the ioremap() is handled
* here. For IORESOURCE_IO, it's assumed that there's no remapping
* necessary.
*
* If no IRQ resource is present, PIO polling mode is used instead.
*/
static int __devinit pata_platform_probe(struct platform_device *pdev)
{
Expand All @@ -137,11 +142,12 @@ static int __devinit pata_platform_probe(struct platform_device *pdev)
struct ata_port *ap;
struct pata_platform_info *pp_info;
unsigned int mmio;
int irq;

/*
* Simple resource validation ..
*/
if (unlikely(pdev->num_resources != 3)) {
if ((pdev->num_resources != 3) && (pdev->num_resources != 2)) {
dev_err(&pdev->dev, "invalid number of resources\n");
return -EINVAL;
}
Expand Down Expand Up @@ -172,6 +178,13 @@ static int __devinit pata_platform_probe(struct platform_device *pdev)
mmio = (( io_res->flags == IORESOURCE_MEM) &&
(ctl_res->flags == IORESOURCE_MEM));

/*
* And the IRQ
*/
irq = platform_get_irq(pdev, 0);
if (irq < 0)
irq = 0; /* no irq */

/*
* Now that that's out of the way, wire up the port..
*/
Expand All @@ -184,6 +197,14 @@ static int __devinit pata_platform_probe(struct platform_device *pdev)
ap->pio_mask = pio_mask;
ap->flags |= ATA_FLAG_SLAVE_POSS;

/*
* Use polling mode if there's no IRQ
*/
if (!irq) {
ap->flags |= ATA_FLAG_PIO_POLLING;
ata_port_desc(ap, "no IRQ, using PIO polling");
}

/*
* Handle the MMIO case
*/
Expand Down Expand Up @@ -213,9 +234,9 @@ static int __devinit pata_platform_probe(struct platform_device *pdev)
(unsigned long long)ctl_res->start);

/* activate */
return ata_host_activate(host, platform_get_irq(pdev, 0),
ata_interrupt, pp_info ? pp_info->irq_flags
: 0, &pata_platform_sht);
return ata_host_activate(host, irq, irq ? ata_interrupt : NULL,
pp_info ? pp_info->irq_flags : 0,
&pata_platform_sht);
}

/**
Expand Down
2 changes: 1 addition & 1 deletion drivers/ata/sata_nv.c
Original file line number Diff line number Diff line change
Expand Up @@ -1629,7 +1629,7 @@ static int nv_hardreset(struct ata_link *link, unsigned int *class,

/* SATA hardreset fails to retrieve proper device signature on
* some controllers. Don't classify on hardreset. For more
* info, see http://bugme.osdl.org/show_bug.cgi?id=3352
* info, see http://bugzilla.kernel.org/show_bug.cgi?id=3352
*/
return sata_std_hardreset(link, &dummy, deadline);
}
Expand Down
Loading

0 comments on commit 487350e

Please sign in to comment.