From 397710d3125993da667b3653dff6534d6a89a541 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 22 Oct 2008 00:45:57 +0900 Subject: [PATCH] --- yaml --- r: 116833 b: refs/heads/master c: b78152e9dbab6d6175e2adcbd8c62959e8f0f922 h: refs/heads/master i: 116831: 5cf17eeb53332b589cf12713deee6e73f47848c9 v: v3 --- [refs] | 2 +- trunk/drivers/ata/sata_via.c | 35 ++++++++++++++++++++++++++++++++--- 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/[refs] b/[refs] index c31131a94c5b..50a4e12c2e70 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 816ab89782ac139a8b65147cca990822bb7e8675 +refs/heads/master: b78152e9dbab6d6175e2adcbd8c62959e8f0f922 diff --git a/trunk/drivers/ata/sata_via.c b/trunk/drivers/ata/sata_via.c index 1cfa74535d91..5b72e734300a 100644 --- a/trunk/drivers/ata/sata_via.c +++ b/trunk/drivers/ata/sata_via.c @@ -70,6 +70,7 @@ enum { static int svia_init_one(struct pci_dev *pdev, const struct pci_device_id *ent); static int svia_scr_read(struct ata_link *link, unsigned int sc_reg, u32 *val); static int svia_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val); +static void svia_tf_load(struct ata_port *ap, const struct ata_taskfile *tf); static void svia_noop_freeze(struct ata_port *ap); static int vt6420_prereset(struct ata_link *link, unsigned long deadline); static int vt6421_pata_cable_detect(struct ata_port *ap); @@ -103,21 +104,26 @@ static struct scsi_host_template svia_sht = { ATA_BMDMA_SHT(DRV_NAME), }; -static struct ata_port_operations vt6420_sata_ops = { +static struct ata_port_operations svia_base_ops = { .inherits = &ata_bmdma_port_ops, + .sff_tf_load = svia_tf_load, +}; + +static struct ata_port_operations vt6420_sata_ops = { + .inherits = &svia_base_ops, .freeze = svia_noop_freeze, .prereset = vt6420_prereset, }; static struct ata_port_operations vt6421_pata_ops = { - .inherits = &ata_bmdma_port_ops, + .inherits = &svia_base_ops, .cable_detect = vt6421_pata_cable_detect, .set_piomode = vt6421_set_pio_mode, .set_dmamode = vt6421_set_dma_mode, }; static struct ata_port_operations vt6421_sata_ops = { - .inherits = &ata_bmdma_port_ops, + .inherits = &svia_base_ops, .scr_read = svia_scr_read, .scr_write = svia_scr_write, }; @@ -168,6 +174,29 @@ static int svia_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val) return 0; } +/** + * svia_tf_load - send taskfile registers to host controller + * @ap: Port to which output is sent + * @tf: ATA taskfile register set + * + * Outputs ATA taskfile to standard ATA host controller. + * + * This is to fix the internal bug of via chipsets, which will + * reset the device register after changing the IEN bit on ctl + * register. + */ +static void svia_tf_load(struct ata_port *ap, const struct ata_taskfile *tf) +{ + struct ata_taskfile ttf; + + if (tf->ctl != ap->last_ctl) { + ttf = *tf; + ttf.flags |= ATA_TFLAG_DEVICE; + tf = &ttf; + } + ata_sff_tf_load(ap, tf); +} + static void svia_noop_freeze(struct ata_port *ap) { /* Some VIA controllers choke if ATA_NIEN is manipulated in