diff options
author | Tejun Heo <htejun@gmail.com> | 2007-01-25 06:46:59 -0500 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2007-01-25 17:22:47 -0500 |
commit | 17234246eb82898cf98e3c29e81d941c738e0587 (patch) | |
tree | 7461fcd868ff714f66f262b47ca6b6aa2973f237 | |
parent | b229a7b0aed808f2ef6a5e9dbf78b0f17cefb4d0 (diff) |
sata_via: don't diddle with ATA_NIEN in ->freeze
vt6420 completely loses its ability to raise IRQ for ATAPI devices if
ATA_NIEN is diddled with in ->freeze. Further investigation is
necessary to determine whether this problem is shared on other
controllers but it doesn't seem to be at this point.
Make vt6420's ->freeze only clear IRQ to fix this problem. This makes
vt6420 relatively more prone to IRQ storms but the controller is way
too braindamaged to worry about that anyway.
Signed-off-by: Tejun Heo <htejun@gmail.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
-rw-r--r-- | drivers/ata/sata_via.c | 12 |
1 files changed, 11 insertions, 1 deletions
diff --git a/drivers/ata/sata_via.c b/drivers/ata/sata_via.c index 88f0565c8883..55b01236a6f0 100644 --- a/drivers/ata/sata_via.c +++ b/drivers/ata/sata_via.c | |||
@@ -74,6 +74,7 @@ enum { | |||
74 | static int svia_init_one (struct pci_dev *pdev, const struct pci_device_id *ent); | 74 | static int svia_init_one (struct pci_dev *pdev, const struct pci_device_id *ent); |
75 | static u32 svia_scr_read (struct ata_port *ap, unsigned int sc_reg); | 75 | static u32 svia_scr_read (struct ata_port *ap, unsigned int sc_reg); |
76 | static void svia_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val); | 76 | static void svia_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val); |
77 | static void svia_noop_freeze(struct ata_port *ap); | ||
77 | static void vt6420_error_handler(struct ata_port *ap); | 78 | static void vt6420_error_handler(struct ata_port *ap); |
78 | 79 | ||
79 | static const struct pci_device_id svia_pci_tbl[] = { | 80 | static const struct pci_device_id svia_pci_tbl[] = { |
@@ -128,7 +129,7 @@ static const struct ata_port_operations vt6420_sata_ops = { | |||
128 | .qc_issue = ata_qc_issue_prot, | 129 | .qc_issue = ata_qc_issue_prot, |
129 | .data_xfer = ata_pio_data_xfer, | 130 | .data_xfer = ata_pio_data_xfer, |
130 | 131 | ||
131 | .freeze = ata_bmdma_freeze, | 132 | .freeze = svia_noop_freeze, |
132 | .thaw = ata_bmdma_thaw, | 133 | .thaw = ata_bmdma_thaw, |
133 | .error_handler = vt6420_error_handler, | 134 | .error_handler = vt6420_error_handler, |
134 | .post_internal_cmd = ata_bmdma_post_internal_cmd, | 135 | .post_internal_cmd = ata_bmdma_post_internal_cmd, |
@@ -204,6 +205,15 @@ static void svia_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val) | |||
204 | outl(val, ap->ioaddr.scr_addr + (4 * sc_reg)); | 205 | outl(val, ap->ioaddr.scr_addr + (4 * sc_reg)); |
205 | } | 206 | } |
206 | 207 | ||
208 | static void svia_noop_freeze(struct ata_port *ap) | ||
209 | { | ||
210 | /* Some VIA controllers choke if ATA_NIEN is manipulated in | ||
211 | * certain way. Leave it alone and just clear pending IRQ. | ||
212 | */ | ||
213 | ata_chk_status(ap); | ||
214 | ap->ops->irq_clear(ap); | ||
215 | } | ||
216 | |||
207 | /** | 217 | /** |
208 | * vt6420_prereset - prereset for vt6420 | 218 | * vt6420_prereset - prereset for vt6420 |
209 | * @ap: target ATA port | 219 | * @ap: target ATA port |