diff options
| author | Gwendal Grignou <gwendal@google.com> | 2008-01-10 01:47:56 -0500 |
|---|---|---|
| committer | Jeff Garzik <jeff@garzik.org> | 2008-01-10 16:54:01 -0500 |
| commit | 13cc546be3060324de9d92ebde3bc9dbd950df23 (patch) | |
| tree | 19c49aea192b14682bf094ea1a34fca17ddf102f | |
| parent | fcb71f6f034c6c4f6a3ab4a55404c95db6e32653 (diff) | |
sata_sil24: prevent hba lockup when pass-through ATA commands are used
Fix commands timeout with Sil3124/3132 based HBA when pass-through ATA
commands [where ATA_QCFLAG_RESULT_TF is set] are used while other
commands are active on other devices connected to the same port with a
Port Multiplier. Due to a hardware bug, these commands must be sent
alone, like ATAPI commands.
Signed-off-by: Gwendal Grignou <gwendal@google.com>
Acked-by: Tejun Heo <htejun@gmail.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
| -rw-r--r-- | drivers/ata/sata_sil24.c | 37 |
1 files changed, 26 insertions, 11 deletions
diff --git a/drivers/ata/sata_sil24.c b/drivers/ata/sata_sil24.c index 96fd5260446d..b4c674d83769 100644 --- a/drivers/ata/sata_sil24.c +++ b/drivers/ata/sata_sil24.c | |||
| @@ -832,16 +832,31 @@ static int sil24_qc_defer(struct ata_queued_cmd *qc) | |||
| 832 | struct ata_link *link = qc->dev->link; | 832 | struct ata_link *link = qc->dev->link; |
| 833 | struct ata_port *ap = link->ap; | 833 | struct ata_port *ap = link->ap; |
| 834 | u8 prot = qc->tf.protocol; | 834 | u8 prot = qc->tf.protocol; |
| 835 | int is_atapi = (prot == ATA_PROT_ATAPI || | 835 | |
| 836 | prot == ATA_PROT_ATAPI_NODATA || | 836 | /* |
| 837 | prot == ATA_PROT_ATAPI_DMA); | 837 | * There is a bug in the chip: |
| 838 | 838 | * Port LRAM Causes the PRB/SGT Data to be Corrupted | |
| 839 | /* ATAPI commands completing with CHECK_SENSE cause various | 839 | * If the host issues a read request for LRAM and SActive registers |
| 840 | * weird problems if other commands are active. PMP DMA CS | 840 | * while active commands are available in the port, PRB/SGT data in |
| 841 | * errata doesn't cover all and HSM violation occurs even with | 841 | * the LRAM can become corrupted. This issue applies only when |
| 842 | * only one other device active. Always run an ATAPI command | 842 | * reading from, but not writing to, the LRAM. |
| 843 | * by itself. | 843 | * |
| 844 | */ | 844 | * Therefore, reading LRAM when there is no particular error [and |
| 845 | * other commands may be outstanding] is prohibited. | ||
| 846 | * | ||
| 847 | * To avoid this bug there are two situations where a command must run | ||
| 848 | * exclusive of any other commands on the port: | ||
| 849 | * | ||
| 850 | * - ATAPI commands which check the sense data | ||
| 851 | * - Passthrough ATA commands which always have ATA_QCFLAG_RESULT_TF | ||
| 852 | * set. | ||
| 853 | * | ||
| 854 | */ | ||
| 855 | int is_excl = (prot == ATA_PROT_ATAPI || | ||
| 856 | prot == ATA_PROT_ATAPI_NODATA || | ||
| 857 | prot == ATA_PROT_ATAPI_DMA || | ||
| 858 | (qc->flags & ATA_QCFLAG_RESULT_TF)); | ||
| 859 | |||
| 845 | if (unlikely(ap->excl_link)) { | 860 | if (unlikely(ap->excl_link)) { |
| 846 | if (link == ap->excl_link) { | 861 | if (link == ap->excl_link) { |
| 847 | if (ap->nr_active_links) | 862 | if (ap->nr_active_links) |
| @@ -849,7 +864,7 @@ static int sil24_qc_defer(struct ata_queued_cmd *qc) | |||
| 849 | qc->flags |= ATA_QCFLAG_CLEAR_EXCL; | 864 | qc->flags |= ATA_QCFLAG_CLEAR_EXCL; |
| 850 | } else | 865 | } else |
| 851 | return ATA_DEFER_PORT; | 866 | return ATA_DEFER_PORT; |
| 852 | } else if (unlikely(is_atapi)) { | 867 | } else if (unlikely(is_excl)) { |
| 853 | ap->excl_link = link; | 868 | ap->excl_link = link; |
| 854 | if (ap->nr_active_links) | 869 | if (ap->nr_active_links) |
| 855 | return ATA_DEFER_PORT; | 870 | return ATA_DEFER_PORT; |
