diff options
author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-11-10 17:26:04 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-11-10 17:26:04 -0500 |
commit | 487350e4434610e31b71eac5d6a9714b72fa32f6 (patch) | |
tree | bf09b2cd0e09091784eac9fc8041358c69ac3c7c /drivers | |
parent | 1da63a2131b0185f64a4c623a0e0b030479185fe (diff) | |
parent | 037f6bb79f753c014bc84bca0de9bf98bb5ab169 (diff) |
Merge branch 'upstream-linus' of master.kernel.org:/pub/scm/linux/kernel/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
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/ata/ata_piix.c | 7 | ||||
-rw-r--r-- | drivers/ata/libata-acpi.c | 10 | ||||
-rw-r--r-- | drivers/ata/libata-core.c | 78 | ||||
-rw-r--r-- | drivers/ata/pata_platform.c | 35 | ||||
-rw-r--r-- | drivers/ata/sata_nv.c | 2 | ||||
-rw-r--r-- | drivers/ata/sata_qstor.c | 114 |
6 files changed, 172 insertions, 74 deletions
diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c index f08cca21702c..328ce8a08426 100644 --- a/drivers/ata/ata_piix.c +++ b/drivers/ata/ata_piix.c | |||
@@ -960,6 +960,13 @@ static int piix_broken_suspend(void) | |||
960 | }, | 960 | }, |
961 | }, | 961 | }, |
962 | { | 962 | { |
963 | .ident = "Satellite Pro U200", | ||
964 | .matches = { | ||
965 | DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), | ||
966 | DMI_MATCH(DMI_PRODUCT_NAME, "SATELLITE PRO U200"), | ||
967 | }, | ||
968 | }, | ||
969 | { | ||
963 | .ident = "Satellite U205", | 970 | .ident = "Satellite U205", |
964 | .matches = { | 971 | .matches = { |
965 | DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), | 972 | DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), |
diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c index 08a52dd45fb6..545ea865ceb5 100644 --- a/drivers/ata/libata-acpi.c +++ b/drivers/ata/libata-acpi.c | |||
@@ -312,7 +312,7 @@ EXPORT_SYMBOL_GPL(ata_acpi_stm); | |||
312 | * | 312 | * |
313 | * RETURNS: | 313 | * RETURNS: |
314 | * Number of taskfiles on success, 0 if _GTF doesn't exist or doesn't | 314 | * Number of taskfiles on success, 0 if _GTF doesn't exist or doesn't |
315 | * contain valid data. -errno on other errors. | 315 | * contain valid data. |
316 | */ | 316 | */ |
317 | static int ata_dev_get_GTF(struct ata_device *dev, struct ata_acpi_gtf **gtf, | 317 | static int ata_dev_get_GTF(struct ata_device *dev, struct ata_acpi_gtf **gtf, |
318 | void **ptr_to_free) | 318 | void **ptr_to_free) |
@@ -339,7 +339,6 @@ static int ata_dev_get_GTF(struct ata_device *dev, struct ata_acpi_gtf **gtf, | |||
339 | ata_dev_printk(dev, KERN_WARNING, | 339 | ata_dev_printk(dev, KERN_WARNING, |
340 | "_GTF evaluation failed (AE 0x%x)\n", | 340 | "_GTF evaluation failed (AE 0x%x)\n", |
341 | status); | 341 | status); |
342 | rc = -EIO; | ||
343 | } | 342 | } |
344 | goto out_free; | 343 | goto out_free; |
345 | } | 344 | } |
@@ -359,7 +358,6 @@ static int ata_dev_get_GTF(struct ata_device *dev, struct ata_acpi_gtf **gtf, | |||
359 | ata_dev_printk(dev, KERN_WARNING, | 358 | ata_dev_printk(dev, KERN_WARNING, |
360 | "_GTF unexpected object type 0x%x\n", | 359 | "_GTF unexpected object type 0x%x\n", |
361 | out_obj->type); | 360 | out_obj->type); |
362 | rc = -EINVAL; | ||
363 | goto out_free; | 361 | goto out_free; |
364 | } | 362 | } |
365 | 363 | ||
@@ -367,7 +365,6 @@ static int ata_dev_get_GTF(struct ata_device *dev, struct ata_acpi_gtf **gtf, | |||
367 | ata_dev_printk(dev, KERN_WARNING, | 365 | ata_dev_printk(dev, KERN_WARNING, |
368 | "unexpected _GTF length (%d)\n", | 366 | "unexpected _GTF length (%d)\n", |
369 | out_obj->buffer.length); | 367 | out_obj->buffer.length); |
370 | rc = -EINVAL; | ||
371 | goto out_free; | 368 | goto out_free; |
372 | } | 369 | } |
373 | 370 | ||
@@ -511,10 +508,7 @@ static int ata_acpi_exec_tfs(struct ata_device *dev) | |||
511 | int gtf_count, i, rc; | 508 | int gtf_count, i, rc; |
512 | 509 | ||
513 | /* get taskfiles */ | 510 | /* get taskfiles */ |
514 | rc = ata_dev_get_GTF(dev, >f, &ptr_to_free); | 511 | gtf_count = ata_dev_get_GTF(dev, >f, &ptr_to_free); |
515 | if (rc < 0) | ||
516 | return rc; | ||
517 | gtf_count = rc; | ||
518 | 512 | ||
519 | /* execute them */ | 513 | /* execute them */ |
520 | for (i = 0, rc = 0; i < gtf_count; i++) { | 514 | for (i = 0, rc = 0; i < gtf_count; i++) { |
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index ec3ce120a517..81898036dbca 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c | |||
@@ -3373,14 +3373,20 @@ void ata_wait_after_reset(struct ata_port *ap, unsigned long deadline) | |||
3373 | * to clear 0xff after reset. For example, HHD424020F7SV00 | 3373 | * to clear 0xff after reset. For example, HHD424020F7SV00 |
3374 | * iVDR needs >= 800ms while. Quantum GoVault needs even more | 3374 | * iVDR needs >= 800ms while. Quantum GoVault needs even more |
3375 | * than that. | 3375 | * than that. |
3376 | * | ||
3377 | * Note that some PATA controllers (pata_ali) explode if | ||
3378 | * status register is read more than once when there's no | ||
3379 | * device attached. | ||
3376 | */ | 3380 | */ |
3377 | while (1) { | 3381 | if (ap->flags & ATA_FLAG_SATA) { |
3378 | u8 status = ata_chk_status(ap); | 3382 | while (1) { |
3383 | u8 status = ata_chk_status(ap); | ||
3379 | 3384 | ||
3380 | if (status != 0xff || time_after(jiffies, deadline)) | 3385 | if (status != 0xff || time_after(jiffies, deadline)) |
3381 | return; | 3386 | return; |
3382 | 3387 | ||
3383 | msleep(50); | 3388 | msleep(50); |
3389 | } | ||
3384 | } | 3390 | } |
3385 | } | 3391 | } |
3386 | 3392 | ||
@@ -6821,19 +6827,6 @@ static void ata_host_release(struct device *gendev, void *res) | |||
6821 | if (!ap) | 6827 | if (!ap) |
6822 | continue; | 6828 | continue; |
6823 | 6829 | ||
6824 | if ((host->flags & ATA_HOST_STARTED) && ap->ops->port_stop) | ||
6825 | ap->ops->port_stop(ap); | ||
6826 | } | ||
6827 | |||
6828 | if ((host->flags & ATA_HOST_STARTED) && host->ops->host_stop) | ||
6829 | host->ops->host_stop(host); | ||
6830 | |||
6831 | for (i = 0; i < host->n_ports; i++) { | ||
6832 | struct ata_port *ap = host->ports[i]; | ||
6833 | |||
6834 | if (!ap) | ||
6835 | continue; | ||
6836 | |||
6837 | if (ap->scsi_host) | 6830 | if (ap->scsi_host) |
6838 | scsi_host_put(ap->scsi_host); | 6831 | scsi_host_put(ap->scsi_host); |
6839 | 6832 | ||
@@ -6960,6 +6953,24 @@ struct ata_host *ata_host_alloc_pinfo(struct device *dev, | |||
6960 | return host; | 6953 | return host; |
6961 | } | 6954 | } |
6962 | 6955 | ||
6956 | static void ata_host_stop(struct device *gendev, void *res) | ||
6957 | { | ||
6958 | struct ata_host *host = dev_get_drvdata(gendev); | ||
6959 | int i; | ||
6960 | |||
6961 | WARN_ON(!(host->flags & ATA_HOST_STARTED)); | ||
6962 | |||
6963 | for (i = 0; i < host->n_ports; i++) { | ||
6964 | struct ata_port *ap = host->ports[i]; | ||
6965 | |||
6966 | if (ap->ops->port_stop) | ||
6967 | ap->ops->port_stop(ap); | ||
6968 | } | ||
6969 | |||
6970 | if (host->ops->host_stop) | ||
6971 | host->ops->host_stop(host); | ||
6972 | } | ||
6973 | |||
6963 | /** | 6974 | /** |
6964 | * ata_host_start - start and freeze ports of an ATA host | 6975 | * ata_host_start - start and freeze ports of an ATA host |
6965 | * @host: ATA host to start ports for | 6976 | * @host: ATA host to start ports for |
@@ -6978,6 +6989,8 @@ struct ata_host *ata_host_alloc_pinfo(struct device *dev, | |||
6978 | */ | 6989 | */ |
6979 | int ata_host_start(struct ata_host *host) | 6990 | int ata_host_start(struct ata_host *host) |
6980 | { | 6991 | { |
6992 | int have_stop = 0; | ||
6993 | void *start_dr = NULL; | ||
6981 | int i, rc; | 6994 | int i, rc; |
6982 | 6995 | ||
6983 | if (host->flags & ATA_HOST_STARTED) | 6996 | if (host->flags & ATA_HOST_STARTED) |
@@ -6989,6 +7002,22 @@ int ata_host_start(struct ata_host *host) | |||
6989 | if (!host->ops && !ata_port_is_dummy(ap)) | 7002 | if (!host->ops && !ata_port_is_dummy(ap)) |
6990 | host->ops = ap->ops; | 7003 | host->ops = ap->ops; |
6991 | 7004 | ||
7005 | if (ap->ops->port_stop) | ||
7006 | have_stop = 1; | ||
7007 | } | ||
7008 | |||
7009 | if (host->ops->host_stop) | ||
7010 | have_stop = 1; | ||
7011 | |||
7012 | if (have_stop) { | ||
7013 | start_dr = devres_alloc(ata_host_stop, 0, GFP_KERNEL); | ||
7014 | if (!start_dr) | ||
7015 | return -ENOMEM; | ||
7016 | } | ||
7017 | |||
7018 | for (i = 0; i < host->n_ports; i++) { | ||
7019 | struct ata_port *ap = host->ports[i]; | ||
7020 | |||
6992 | if (ap->ops->port_start) { | 7021 | if (ap->ops->port_start) { |
6993 | rc = ap->ops->port_start(ap); | 7022 | rc = ap->ops->port_start(ap); |
6994 | if (rc) { | 7023 | if (rc) { |
@@ -7001,6 +7030,8 @@ int ata_host_start(struct ata_host *host) | |||
7001 | ata_eh_freeze_port(ap); | 7030 | ata_eh_freeze_port(ap); |
7002 | } | 7031 | } |
7003 | 7032 | ||
7033 | if (start_dr) | ||
7034 | devres_add(host->dev, start_dr); | ||
7004 | host->flags |= ATA_HOST_STARTED; | 7035 | host->flags |= ATA_HOST_STARTED; |
7005 | return 0; | 7036 | return 0; |
7006 | 7037 | ||
@@ -7011,6 +7042,7 @@ int ata_host_start(struct ata_host *host) | |||
7011 | if (ap->ops->port_stop) | 7042 | if (ap->ops->port_stop) |
7012 | ap->ops->port_stop(ap); | 7043 | ap->ops->port_stop(ap); |
7013 | } | 7044 | } |
7045 | devres_free(start_dr); | ||
7014 | return rc; | 7046 | return rc; |
7015 | } | 7047 | } |
7016 | 7048 | ||
@@ -7178,6 +7210,10 @@ int ata_host_register(struct ata_host *host, struct scsi_host_template *sht) | |||
7178 | * request IRQ and register it. This helper takes necessasry | 7210 | * request IRQ and register it. This helper takes necessasry |
7179 | * arguments and performs the three steps in one go. | 7211 | * arguments and performs the three steps in one go. |
7180 | * | 7212 | * |
7213 | * An invalid IRQ skips the IRQ registration and expects the host to | ||
7214 | * have set polling mode on the port. In this case, @irq_handler | ||
7215 | * should be NULL. | ||
7216 | * | ||
7181 | * LOCKING: | 7217 | * LOCKING: |
7182 | * Inherited from calling layer (may sleep). | 7218 | * Inherited from calling layer (may sleep). |
7183 | * | 7219 | * |
@@ -7194,6 +7230,12 @@ int ata_host_activate(struct ata_host *host, int irq, | |||
7194 | if (rc) | 7230 | if (rc) |
7195 | return rc; | 7231 | return rc; |
7196 | 7232 | ||
7233 | /* Special case for polling mode */ | ||
7234 | if (!irq) { | ||
7235 | WARN_ON(irq_handler); | ||
7236 | return ata_host_register(host, sht); | ||
7237 | } | ||
7238 | |||
7197 | rc = devm_request_irq(host->dev, irq, irq_handler, irq_flags, | 7239 | rc = devm_request_irq(host->dev, irq, irq_handler, irq_flags, |
7198 | dev_driver_string(host->dev), host); | 7240 | dev_driver_string(host->dev), host); |
7199 | if (rc) | 7241 | if (rc) |
diff --git a/drivers/ata/pata_platform.c b/drivers/ata/pata_platform.c index fc72a965643d..ac03a90a6168 100644 --- a/drivers/ata/pata_platform.c +++ b/drivers/ata/pata_platform.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Generic platform device PATA driver | 2 | * Generic platform device PATA driver |
3 | * | 3 | * |
4 | * Copyright (C) 2006 Paul Mundt | 4 | * Copyright (C) 2006 - 2007 Paul Mundt |
5 | * | 5 | * |
6 | * Based on pata_pcmcia: | 6 | * Based on pata_pcmcia: |
7 | * | 7 | * |
@@ -22,7 +22,7 @@ | |||
22 | #include <linux/pata_platform.h> | 22 | #include <linux/pata_platform.h> |
23 | 23 | ||
24 | #define DRV_NAME "pata_platform" | 24 | #define DRV_NAME "pata_platform" |
25 | #define DRV_VERSION "1.1" | 25 | #define DRV_VERSION "1.2" |
26 | 26 | ||
27 | static int pio_mask = 1; | 27 | static int pio_mask = 1; |
28 | 28 | ||
@@ -120,15 +120,20 @@ static void pata_platform_setup_port(struct ata_ioports *ioaddr, | |||
120 | * Register a platform bus IDE interface. Such interfaces are PIO and we | 120 | * Register a platform bus IDE interface. Such interfaces are PIO and we |
121 | * assume do not support IRQ sharing. | 121 | * assume do not support IRQ sharing. |
122 | * | 122 | * |
123 | * Platform devices are expected to contain 3 resources per port: | 123 | * Platform devices are expected to contain at least 2 resources per port: |
124 | * | 124 | * |
125 | * - I/O Base (IORESOURCE_IO or IORESOURCE_MEM) | 125 | * - I/O Base (IORESOURCE_IO or IORESOURCE_MEM) |
126 | * - CTL Base (IORESOURCE_IO or IORESOURCE_MEM) | 126 | * - CTL Base (IORESOURCE_IO or IORESOURCE_MEM) |
127 | * | ||
128 | * and optionally: | ||
129 | * | ||
127 | * - IRQ (IORESOURCE_IRQ) | 130 | * - IRQ (IORESOURCE_IRQ) |
128 | * | 131 | * |
129 | * If the base resources are both mem types, the ioremap() is handled | 132 | * If the base resources are both mem types, the ioremap() is handled |
130 | * here. For IORESOURCE_IO, it's assumed that there's no remapping | 133 | * here. For IORESOURCE_IO, it's assumed that there's no remapping |
131 | * necessary. | 134 | * necessary. |
135 | * | ||
136 | * If no IRQ resource is present, PIO polling mode is used instead. | ||
132 | */ | 137 | */ |
133 | static int __devinit pata_platform_probe(struct platform_device *pdev) | 138 | static int __devinit pata_platform_probe(struct platform_device *pdev) |
134 | { | 139 | { |
@@ -137,11 +142,12 @@ static int __devinit pata_platform_probe(struct platform_device *pdev) | |||
137 | struct ata_port *ap; | 142 | struct ata_port *ap; |
138 | struct pata_platform_info *pp_info; | 143 | struct pata_platform_info *pp_info; |
139 | unsigned int mmio; | 144 | unsigned int mmio; |
145 | int irq; | ||
140 | 146 | ||
141 | /* | 147 | /* |
142 | * Simple resource validation .. | 148 | * Simple resource validation .. |
143 | */ | 149 | */ |
144 | if (unlikely(pdev->num_resources != 3)) { | 150 | if ((pdev->num_resources != 3) && (pdev->num_resources != 2)) { |
145 | dev_err(&pdev->dev, "invalid number of resources\n"); | 151 | dev_err(&pdev->dev, "invalid number of resources\n"); |
146 | return -EINVAL; | 152 | return -EINVAL; |
147 | } | 153 | } |
@@ -173,6 +179,13 @@ static int __devinit pata_platform_probe(struct platform_device *pdev) | |||
173 | (ctl_res->flags == IORESOURCE_MEM)); | 179 | (ctl_res->flags == IORESOURCE_MEM)); |
174 | 180 | ||
175 | /* | 181 | /* |
182 | * And the IRQ | ||
183 | */ | ||
184 | irq = platform_get_irq(pdev, 0); | ||
185 | if (irq < 0) | ||
186 | irq = 0; /* no irq */ | ||
187 | |||
188 | /* | ||
176 | * Now that that's out of the way, wire up the port.. | 189 | * Now that that's out of the way, wire up the port.. |
177 | */ | 190 | */ |
178 | host = ata_host_alloc(&pdev->dev, 1); | 191 | host = ata_host_alloc(&pdev->dev, 1); |
@@ -185,6 +198,14 @@ static int __devinit pata_platform_probe(struct platform_device *pdev) | |||
185 | ap->flags |= ATA_FLAG_SLAVE_POSS; | 198 | ap->flags |= ATA_FLAG_SLAVE_POSS; |
186 | 199 | ||
187 | /* | 200 | /* |
201 | * Use polling mode if there's no IRQ | ||
202 | */ | ||
203 | if (!irq) { | ||
204 | ap->flags |= ATA_FLAG_PIO_POLLING; | ||
205 | ata_port_desc(ap, "no IRQ, using PIO polling"); | ||
206 | } | ||
207 | |||
208 | /* | ||
188 | * Handle the MMIO case | 209 | * Handle the MMIO case |
189 | */ | 210 | */ |
190 | if (mmio) { | 211 | if (mmio) { |
@@ -213,9 +234,9 @@ static int __devinit pata_platform_probe(struct platform_device *pdev) | |||
213 | (unsigned long long)ctl_res->start); | 234 | (unsigned long long)ctl_res->start); |
214 | 235 | ||
215 | /* activate */ | 236 | /* activate */ |
216 | return ata_host_activate(host, platform_get_irq(pdev, 0), | 237 | return ata_host_activate(host, irq, irq ? ata_interrupt : NULL, |
217 | ata_interrupt, pp_info ? pp_info->irq_flags | 238 | pp_info ? pp_info->irq_flags : 0, |
218 | : 0, &pata_platform_sht); | 239 | &pata_platform_sht); |
219 | } | 240 | } |
220 | 241 | ||
221 | /** | 242 | /** |
diff --git a/drivers/ata/sata_nv.c b/drivers/ata/sata_nv.c index 35b2df297527..44f9e5d9e362 100644 --- a/drivers/ata/sata_nv.c +++ b/drivers/ata/sata_nv.c | |||
@@ -1629,7 +1629,7 @@ static int nv_hardreset(struct ata_link *link, unsigned int *class, | |||
1629 | 1629 | ||
1630 | /* SATA hardreset fails to retrieve proper device signature on | 1630 | /* SATA hardreset fails to retrieve proper device signature on |
1631 | * some controllers. Don't classify on hardreset. For more | 1631 | * some controllers. Don't classify on hardreset. For more |
1632 | * info, see http://bugme.osdl.org/show_bug.cgi?id=3352 | 1632 | * info, see http://bugzilla.kernel.org/show_bug.cgi?id=3352 |
1633 | */ | 1633 | */ |
1634 | return sata_std_hardreset(link, &dummy, deadline); | 1634 | return sata_std_hardreset(link, &dummy, deadline); |
1635 | } | 1635 | } |
diff --git a/drivers/ata/sata_qstor.c b/drivers/ata/sata_qstor.c index 6d43ba79e154..2f1de6ec044c 100644 --- a/drivers/ata/sata_qstor.c +++ b/drivers/ata/sata_qstor.c | |||
@@ -103,7 +103,7 @@ enum { | |||
103 | QS_DMA_BOUNDARY = ~0UL | 103 | QS_DMA_BOUNDARY = ~0UL |
104 | }; | 104 | }; |
105 | 105 | ||
106 | typedef enum { qs_state_idle, qs_state_pkt, qs_state_mmio } qs_state_t; | 106 | typedef enum { qs_state_mmio, qs_state_pkt } qs_state_t; |
107 | 107 | ||
108 | struct qs_port_priv { | 108 | struct qs_port_priv { |
109 | u8 *pkt; | 109 | u8 *pkt; |
@@ -116,14 +116,15 @@ static int qs_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val); | |||
116 | static int qs_ata_init_one(struct pci_dev *pdev, const struct pci_device_id *ent); | 116 | static int qs_ata_init_one(struct pci_dev *pdev, const struct pci_device_id *ent); |
117 | static int qs_port_start(struct ata_port *ap); | 117 | static int qs_port_start(struct ata_port *ap); |
118 | static void qs_host_stop(struct ata_host *host); | 118 | static void qs_host_stop(struct ata_host *host); |
119 | static void qs_phy_reset(struct ata_port *ap); | ||
120 | static void qs_qc_prep(struct ata_queued_cmd *qc); | 119 | static void qs_qc_prep(struct ata_queued_cmd *qc); |
121 | static unsigned int qs_qc_issue(struct ata_queued_cmd *qc); | 120 | static unsigned int qs_qc_issue(struct ata_queued_cmd *qc); |
122 | static int qs_check_atapi_dma(struct ata_queued_cmd *qc); | 121 | static int qs_check_atapi_dma(struct ata_queued_cmd *qc); |
123 | static void qs_bmdma_stop(struct ata_queued_cmd *qc); | 122 | static void qs_bmdma_stop(struct ata_queued_cmd *qc); |
124 | static u8 qs_bmdma_status(struct ata_port *ap); | 123 | static u8 qs_bmdma_status(struct ata_port *ap); |
125 | static void qs_irq_clear(struct ata_port *ap); | 124 | static void qs_irq_clear(struct ata_port *ap); |
126 | static void qs_eng_timeout(struct ata_port *ap); | 125 | static void qs_freeze(struct ata_port *ap); |
126 | static void qs_thaw(struct ata_port *ap); | ||
127 | static void qs_error_handler(struct ata_port *ap); | ||
127 | 128 | ||
128 | static struct scsi_host_template qs_ata_sht = { | 129 | static struct scsi_host_template qs_ata_sht = { |
129 | .module = THIS_MODULE, | 130 | .module = THIS_MODULE, |
@@ -150,11 +151,12 @@ static const struct ata_port_operations qs_ata_ops = { | |||
150 | .check_atapi_dma = qs_check_atapi_dma, | 151 | .check_atapi_dma = qs_check_atapi_dma, |
151 | .exec_command = ata_exec_command, | 152 | .exec_command = ata_exec_command, |
152 | .dev_select = ata_std_dev_select, | 153 | .dev_select = ata_std_dev_select, |
153 | .phy_reset = qs_phy_reset, | ||
154 | .qc_prep = qs_qc_prep, | 154 | .qc_prep = qs_qc_prep, |
155 | .qc_issue = qs_qc_issue, | 155 | .qc_issue = qs_qc_issue, |
156 | .data_xfer = ata_data_xfer, | 156 | .data_xfer = ata_data_xfer, |
157 | .eng_timeout = qs_eng_timeout, | 157 | .freeze = qs_freeze, |
158 | .thaw = qs_thaw, | ||
159 | .error_handler = qs_error_handler, | ||
158 | .irq_clear = qs_irq_clear, | 160 | .irq_clear = qs_irq_clear, |
159 | .irq_on = ata_irq_on, | 161 | .irq_on = ata_irq_on, |
160 | .scr_read = qs_scr_read, | 162 | .scr_read = qs_scr_read, |
@@ -169,8 +171,6 @@ static const struct ata_port_info qs_port_info[] = { | |||
169 | /* board_2068_idx */ | 171 | /* board_2068_idx */ |
170 | { | 172 | { |
171 | .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | | 173 | .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | |
172 | ATA_FLAG_SATA_RESET | | ||
173 | //FIXME ATA_FLAG_SRST | | ||
174 | ATA_FLAG_MMIO | ATA_FLAG_PIO_POLLING, | 174 | ATA_FLAG_MMIO | ATA_FLAG_PIO_POLLING, |
175 | .pio_mask = 0x10, /* pio4 */ | 175 | .pio_mask = 0x10, /* pio4 */ |
176 | .udma_mask = ATA_UDMA6, | 176 | .udma_mask = ATA_UDMA6, |
@@ -219,7 +219,9 @@ static void qs_irq_clear(struct ata_port *ap) | |||
219 | static inline void qs_enter_reg_mode(struct ata_port *ap) | 219 | static inline void qs_enter_reg_mode(struct ata_port *ap) |
220 | { | 220 | { |
221 | u8 __iomem *chan = qs_mmio_base(ap->host) + (ap->port_no * 0x4000); | 221 | u8 __iomem *chan = qs_mmio_base(ap->host) + (ap->port_no * 0x4000); |
222 | struct qs_port_priv *pp = ap->private_data; | ||
222 | 223 | ||
224 | pp->state = qs_state_mmio; | ||
223 | writeb(QS_CTR0_REG, chan + QS_CCT_CTR0); | 225 | writeb(QS_CTR0_REG, chan + QS_CCT_CTR0); |
224 | readb(chan + QS_CCT_CTR0); /* flush */ | 226 | readb(chan + QS_CCT_CTR0); /* flush */ |
225 | } | 227 | } |
@@ -233,23 +235,28 @@ static inline void qs_reset_channel_logic(struct ata_port *ap) | |||
233 | qs_enter_reg_mode(ap); | 235 | qs_enter_reg_mode(ap); |
234 | } | 236 | } |
235 | 237 | ||
236 | static void qs_phy_reset(struct ata_port *ap) | 238 | static void qs_freeze(struct ata_port *ap) |
237 | { | 239 | { |
238 | struct qs_port_priv *pp = ap->private_data; | 240 | u8 __iomem *mmio_base = qs_mmio_base(ap->host); |
239 | 241 | ||
240 | pp->state = qs_state_idle; | 242 | writeb(0, mmio_base + QS_HCT_CTRL); /* disable host interrupts */ |
241 | qs_reset_channel_logic(ap); | 243 | qs_enter_reg_mode(ap); |
242 | sata_phy_reset(ap); | ||
243 | } | 244 | } |
244 | 245 | ||
245 | static void qs_eng_timeout(struct ata_port *ap) | 246 | static void qs_thaw(struct ata_port *ap) |
246 | { | 247 | { |
247 | struct qs_port_priv *pp = ap->private_data; | 248 | u8 __iomem *mmio_base = qs_mmio_base(ap->host); |
249 | |||
250 | qs_enter_reg_mode(ap); | ||
251 | writeb(1, mmio_base + QS_HCT_CTRL); /* enable host interrupts */ | ||
252 | } | ||
253 | |||
254 | static int qs_prereset(struct ata_link *link, unsigned long deadline) | ||
255 | { | ||
256 | struct ata_port *ap = link->ap; | ||
248 | 257 | ||
249 | if (pp->state != qs_state_idle) /* healthy paranoia */ | ||
250 | pp->state = qs_state_mmio; | ||
251 | qs_reset_channel_logic(ap); | 258 | qs_reset_channel_logic(ap); |
252 | ata_eng_timeout(ap); | 259 | return ata_std_prereset(link, deadline); |
253 | } | 260 | } |
254 | 261 | ||
255 | static int qs_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val) | 262 | static int qs_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val) |
@@ -260,6 +267,13 @@ static int qs_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val) | |||
260 | return 0; | 267 | return 0; |
261 | } | 268 | } |
262 | 269 | ||
270 | static void qs_error_handler(struct ata_port *ap) | ||
271 | { | ||
272 | qs_enter_reg_mode(ap); | ||
273 | ata_do_eh(ap, qs_prereset, ata_std_softreset, NULL, | ||
274 | ata_std_postreset); | ||
275 | } | ||
276 | |||
263 | static int qs_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val) | 277 | static int qs_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val) |
264 | { | 278 | { |
265 | if (sc_reg > SCR_CONTROL) | 279 | if (sc_reg > SCR_CONTROL) |
@@ -358,7 +372,6 @@ static unsigned int qs_qc_issue(struct ata_queued_cmd *qc) | |||
358 | 372 | ||
359 | switch (qc->tf.protocol) { | 373 | switch (qc->tf.protocol) { |
360 | case ATA_PROT_DMA: | 374 | case ATA_PROT_DMA: |
361 | |||
362 | pp->state = qs_state_pkt; | 375 | pp->state = qs_state_pkt; |
363 | qs_packet_start(qc); | 376 | qs_packet_start(qc); |
364 | return 0; | 377 | return 0; |
@@ -375,6 +388,26 @@ static unsigned int qs_qc_issue(struct ata_queued_cmd *qc) | |||
375 | return ata_qc_issue_prot(qc); | 388 | return ata_qc_issue_prot(qc); |
376 | } | 389 | } |
377 | 390 | ||
391 | static void qs_do_or_die(struct ata_queued_cmd *qc, u8 status) | ||
392 | { | ||
393 | qc->err_mask |= ac_err_mask(status); | ||
394 | |||
395 | if (!qc->err_mask) { | ||
396 | ata_qc_complete(qc); | ||
397 | } else { | ||
398 | struct ata_port *ap = qc->ap; | ||
399 | struct ata_eh_info *ehi = &ap->link.eh_info; | ||
400 | |||
401 | ata_ehi_clear_desc(ehi); | ||
402 | ata_ehi_push_desc(ehi, "status 0x%02X", status); | ||
403 | |||
404 | if (qc->err_mask == AC_ERR_DEV) | ||
405 | ata_port_abort(ap); | ||
406 | else | ||
407 | ata_port_freeze(ap); | ||
408 | } | ||
409 | } | ||
410 | |||
378 | static inline unsigned int qs_intr_pkt(struct ata_host *host) | 411 | static inline unsigned int qs_intr_pkt(struct ata_host *host) |
379 | { | 412 | { |
380 | unsigned int handled = 0; | 413 | unsigned int handled = 0; |
@@ -406,10 +439,8 @@ static inline unsigned int qs_intr_pkt(struct ata_host *host) | |||
406 | switch (sHST) { | 439 | switch (sHST) { |
407 | case 0: /* successful CPB */ | 440 | case 0: /* successful CPB */ |
408 | case 3: /* device error */ | 441 | case 3: /* device error */ |
409 | pp->state = qs_state_idle; | ||
410 | qs_enter_reg_mode(qc->ap); | 442 | qs_enter_reg_mode(qc->ap); |
411 | qc->err_mask |= ac_err_mask(sDST); | 443 | qs_do_or_die(qc, sDST); |
412 | ata_qc_complete(qc); | ||
413 | break; | 444 | break; |
414 | default: | 445 | default: |
415 | break; | 446 | break; |
@@ -431,25 +462,27 @@ static inline unsigned int qs_intr_mmio(struct ata_host *host) | |||
431 | if (ap && | 462 | if (ap && |
432 | !(ap->flags & ATA_FLAG_DISABLED)) { | 463 | !(ap->flags & ATA_FLAG_DISABLED)) { |
433 | struct ata_queued_cmd *qc; | 464 | struct ata_queued_cmd *qc; |
434 | struct qs_port_priv *pp = ap->private_data; | 465 | struct qs_port_priv *pp; |
435 | if (!pp || pp->state != qs_state_mmio) | ||
436 | continue; | ||
437 | qc = ata_qc_from_tag(ap, ap->link.active_tag); | 466 | qc = ata_qc_from_tag(ap, ap->link.active_tag); |
438 | if (qc && (!(qc->tf.flags & ATA_TFLAG_POLLING))) { | 467 | if (!qc || !(qc->flags & ATA_QCFLAG_ACTIVE)) { |
439 | 468 | /* | |
440 | /* check main status, clearing INTRQ */ | 469 | * The qstor hardware generates spurious |
441 | u8 status = ata_check_status(ap); | 470 | * interrupts from time to time when switching |
442 | if ((status & ATA_BUSY)) | 471 | * in and out of packet mode. |
443 | continue; | 472 | * There's no obvious way to know if we're |
444 | DPRINTK("ata%u: protocol %d (dev_stat 0x%X)\n", | 473 | * here now due to that, so just ack the irq |
445 | ap->print_id, qc->tf.protocol, status); | 474 | * and pretend we knew it was ours.. (ugh). |
446 | 475 | * This does not affect packet mode. | |
447 | /* complete taskfile transaction */ | 476 | */ |
448 | pp->state = qs_state_idle; | 477 | ata_check_status(ap); |
449 | qc->err_mask |= ac_err_mask(status); | ||
450 | ata_qc_complete(qc); | ||
451 | handled = 1; | 478 | handled = 1; |
479 | continue; | ||
452 | } | 480 | } |
481 | pp = ap->private_data; | ||
482 | if (!pp || pp->state != qs_state_mmio) | ||
483 | continue; | ||
484 | if (!(qc->tf.flags & ATA_TFLAG_POLLING)) | ||
485 | handled |= ata_host_intr(ap, qc); | ||
453 | } | 486 | } |
454 | } | 487 | } |
455 | return handled; | 488 | return handled; |
@@ -459,12 +492,13 @@ static irqreturn_t qs_intr(int irq, void *dev_instance) | |||
459 | { | 492 | { |
460 | struct ata_host *host = dev_instance; | 493 | struct ata_host *host = dev_instance; |
461 | unsigned int handled = 0; | 494 | unsigned int handled = 0; |
495 | unsigned long flags; | ||
462 | 496 | ||
463 | VPRINTK("ENTER\n"); | 497 | VPRINTK("ENTER\n"); |
464 | 498 | ||
465 | spin_lock(&host->lock); | 499 | spin_lock_irqsave(&host->lock, flags); |
466 | handled = qs_intr_pkt(host) | qs_intr_mmio(host); | 500 | handled = qs_intr_pkt(host) | qs_intr_mmio(host); |
467 | spin_unlock(&host->lock); | 501 | spin_unlock_irqrestore(&host->lock, flags); |
468 | 502 | ||
469 | VPRINTK("EXIT\n"); | 503 | VPRINTK("EXIT\n"); |
470 | 504 | ||
@@ -501,7 +535,6 @@ static int qs_port_start(struct ata_port *ap) | |||
501 | rc = ata_port_start(ap); | 535 | rc = ata_port_start(ap); |
502 | if (rc) | 536 | if (rc) |
503 | return rc; | 537 | return rc; |
504 | qs_enter_reg_mode(ap); | ||
505 | pp = devm_kzalloc(dev, sizeof(*pp), GFP_KERNEL); | 538 | pp = devm_kzalloc(dev, sizeof(*pp), GFP_KERNEL); |
506 | if (!pp) | 539 | if (!pp) |
507 | return -ENOMEM; | 540 | return -ENOMEM; |
@@ -512,6 +545,7 @@ static int qs_port_start(struct ata_port *ap) | |||
512 | memset(pp->pkt, 0, QS_PKT_BYTES); | 545 | memset(pp->pkt, 0, QS_PKT_BYTES); |
513 | ap->private_data = pp; | 546 | ap->private_data = pp; |
514 | 547 | ||
548 | qs_enter_reg_mode(ap); | ||
515 | addr = (u64)pp->pkt_dma; | 549 | addr = (u64)pp->pkt_dma; |
516 | writel((u32) addr, chan + QS_CCF_CPBA); | 550 | writel((u32) addr, chan + QS_CCF_CPBA); |
517 | writel((u32)(addr >> 32), chan + QS_CCF_CPBA + 4); | 551 | writel((u32)(addr >> 32), chan + QS_CCF_CPBA + 4); |