From: Tejun Heo Date: Thu, 25 Jan 2007 11:46:59 +0000 (+0900) Subject: sata_via: don't diddle with ATA_NIEN in ->freeze X-Git-Tag: v2.6.20-rc7~57^2~7 X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=17234246eb82898cf98e3c29e81d941c738e0587;p=linux-2.6 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 Signed-off-by: Jeff Garzik --- diff --git a/drivers/ata/sata_via.c b/drivers/ata/sata_via.c index 88f0565c88..55b01236a6 100644 --- a/drivers/ata/sata_via.c +++ b/drivers/ata/sata_via.c @@ -74,6 +74,7 @@ enum { static int svia_init_one (struct pci_dev *pdev, const struct pci_device_id *ent); static u32 svia_scr_read (struct ata_port *ap, unsigned int sc_reg); static void svia_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val); +static void svia_noop_freeze(struct ata_port *ap); static void vt6420_error_handler(struct ata_port *ap); static const struct pci_device_id svia_pci_tbl[] = { @@ -128,7 +129,7 @@ static const struct ata_port_operations vt6420_sata_ops = { .qc_issue = ata_qc_issue_prot, .data_xfer = ata_pio_data_xfer, - .freeze = ata_bmdma_freeze, + .freeze = svia_noop_freeze, .thaw = ata_bmdma_thaw, .error_handler = vt6420_error_handler, .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) outl(val, ap->ioaddr.scr_addr + (4 * sc_reg)); } +static void svia_noop_freeze(struct ata_port *ap) +{ + /* Some VIA controllers choke if ATA_NIEN is manipulated in + * certain way. Leave it alone and just clear pending IRQ. + */ + ata_chk_status(ap); + ap->ops->irq_clear(ap); +} + /** * vt6420_prereset - prereset for vt6420 * @ap: target ATA port