For some reason, via decided that combined SATA/PATA setup in sata_via
isn't good enough and added a SATA port without SCR access to CX700.
For yet another unknown reason, slave slot of the SATA port dislikes
SETXFER.

This patch implements two quirks for CX700 - VIA_SATA_PATA and
VIA_BAD_SLAVE_SETXFER.  SATA_PATA indicates that the first port is
SATA and BAD_SLAVE_SETXFER indicates slave port may fail SETXFER.

  http://bugzilla.kernel.org/show_bug.cgi?id=8563

Signed-off-by: Tejun Heo <[EMAIL PROTECTED]>
---
 drivers/ata/pata_via.c |   18 +++++++++++++++++-
 1 file changed, 17 insertions(+), 1 deletion(-)

Index: work/drivers/ata/pata_via.c
===================================================================
--- work.orig/drivers/ata/pata_via.c
+++ work/drivers/ata/pata_via.c
@@ -84,6 +84,8 @@ enum {
        VIA_BAD_ID      = 0x100, /* Has wrong vendor ID (0x1107) */
        VIA_BAD_AST     = 0x200, /* Don't touch Address Setup Timing */
        VIA_NO_ENABLES  = 0x400, /* Has no enablebits */
+       VIA_BAD_SLAVE_SETXFER = 0x0800, /* SETXFER on slave device may fail */
+       VIA_SATA_PATA   = 0x1000, /* SATA/PATA combined configuration */
 };
 
 /*
@@ -99,7 +101,7 @@ static const struct via_isa_bridge {
 } via_isa_bridges[] = {
        { "vt8237s",    PCI_DEVICE_ID_VIA_8237S,    0x00, 0x2f, VIA_UDMA_133 | 
VIA_BAD_AST },
        { "vt8251",     PCI_DEVICE_ID_VIA_8251,     0x00, 0x2f, VIA_UDMA_133 | 
VIA_BAD_AST },
-       { "cx700",      PCI_DEVICE_ID_VIA_CX700,    0x00, 0x2f, VIA_UDMA_133 | 
VIA_BAD_AST },
+       { "cx700",      PCI_DEVICE_ID_VIA_CX700,    0x00, 0x2f, VIA_UDMA_133 | 
VIA_BAD_AST | VIA_SATA_PATA | VIA_BAD_SLAVE_SETXFER },
        { "vt6410",     PCI_DEVICE_ID_VIA_6410,     0x00, 0x2f, VIA_UDMA_133 | 
VIA_BAD_AST | VIA_NO_ENABLES},
        { "vt8237a",    PCI_DEVICE_ID_VIA_8237A,    0x00, 0x2f, VIA_UDMA_133 | 
VIA_BAD_AST },
        { "vt8237",     PCI_DEVICE_ID_VIA_8237,     0x00, 0x2f, VIA_UDMA_133 | 
VIA_BAD_AST },
@@ -168,6 +170,9 @@ static int via_cable_detect(struct ata_p
        if (via_cable_override(pdev))
                return ATA_CBL_PATA40_SHORT;
 
+       if ((config->flags & VIA_SATA_PATA) && ap->port_no == 0)
+               return ATA_CBL_SATA;
+
        /* Early chips are 40 wire */
        if ((config->flags & VIA_UDMA) < VIA_UDMA_66)
                return ATA_CBL_PATA40;
@@ -292,6 +297,15 @@ static void via_do_set_mode(struct ata_p
                pci_write_config_byte(pdev, 0x50 + offset, ut);
 }
 
+static void via_dev_config(struct ata_device *dev)
+{
+       const struct via_isa_bridge *config = dev->ap->host->private_data;
+
+       /* some new VIA chips have problem with SETXFER on slave slot */
+       if (dev->devno && (config->flags & VIA_BAD_SLAVE_SETXFER))
+               dev->horkage |= ATA_HORKAGE_SETXFER;
+}
+
 static void via_set_piomode(struct ata_port *ap, struct ata_device *adev)
 {
        const struct via_isa_bridge *config = ap->host->private_data;
@@ -334,6 +348,7 @@ static struct scsi_host_template via_sht
 
 static struct ata_port_operations via_port_ops = {
        .port_disable   = ata_port_disable,
+       .dev_config     = via_dev_config,
        .set_piomode    = via_set_piomode,
        .set_dmamode    = via_set_dmamode,
        .mode_filter    = ata_pci_default_filter,
@@ -370,6 +385,7 @@ static struct ata_port_operations via_po
 
 static struct ata_port_operations via_port_ops_noirq = {
        .port_disable   = ata_port_disable,
+       .dev_config     = via_dev_config,
        .set_piomode    = via_set_piomode,
        .set_dmamode    = via_set_dmamode,
        .mode_filter    = ata_pci_default_filter,
-
To unsubscribe from this list: send the line "unsubscribe linux-ide" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to