diff --git a/drivers/ata/pata_via.c b/drivers/ata/pata_via.c
index ac8d7d9..6193cbd 100644
--- a/drivers/ata/pata_via.c
+++ b/drivers/ata/pata_via.c
@@ -93,6 +93,7 @@ static const struct via_isa_bridge {
 	u8 udma_mask;
 	u8 flags;
 } via_isa_bridges[] = {
+	{ "vx700/800",	PCI_DEVICE_ID_VIA_SATA_EIDE, 0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST | VIA_SATA_PATA },
 	{ "vx855",	PCI_DEVICE_ID_VIA_VX855,    0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST | VIA_SATA_PATA },
 	{ "vx800",	PCI_DEVICE_ID_VIA_VX800,    0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST | VIA_SATA_PATA },
 	{ "vt8261",	PCI_DEVICE_ID_VIA_8261,     0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST },
@@ -437,6 +438,83 @@ static int via_port_start(struct ata_port *ap)
 	return 0;
 }
 
+/* On VX800 SStatus, SError and SControl registers are located in PCI config
+ * space. SStatus and SControl registers are only 8 bits wide. VT8251 is the
+ * same. Copy & paste from sata_via.c */
+
+static int vx800_scr_read(struct ata_link *link, unsigned int scr, u32 *val)
+{
+	static const u8 ipm_tbl[] = { 1, 2, 6, 0 };
+	struct pci_dev *pdev = to_pci_dev(link->ap->host->dev);
+	int slot = 2 * link->ap->port_no + link->pmp;
+	u32 v = 0;
+	u8 raw;
+
+	switch (scr) {
+	case SCR_STATUS:
+		pci_read_config_byte(pdev, 0xA0 + slot, &raw);
+
+		/* read the DET field, bit0 and 1 of the config byte */
+		v |= raw & 0x03;
+
+		/* read the SPD field, bit4 of the configure byte */
+		if (raw & (1 << 4))
+			v |= 0x02 << 4;
+		else
+			v |= 0x01 << 4;
+
+		/* read the IPM field, bit2 and 3 of the config byte */
+		v |= ipm_tbl[(raw >> 2) & 0x3];
+		break;
+
+	case SCR_ERROR:
+		pci_read_config_dword(pdev, 0xA8 + slot * 4, &v);
+		break;
+
+	case SCR_CONTROL:
+		pci_read_config_byte(pdev, 0xA4 + slot, &raw);
+
+		/* read the DET field, bit0 and bit1 */
+		v |= ((raw & 0x02) << 1) | (raw & 0x01);
+
+		/* read the IPM field, bit2 and bit3 */
+		v |= ((raw >> 2) & 0x03) << 8;
+		break;
+
+	default:
+		return -EINVAL;
+	}
+
+	*val = v;
+	return 0;
+}
+
+static int vx800_scr_write(struct ata_link *link, unsigned int scr, u32 val)
+{
+	struct pci_dev *pdev = to_pci_dev(link->ap->host->dev);
+	int slot = 2 * link->ap->port_no + link->pmp;
+	u32 v = 0;
+
+	switch (scr) {
+	case SCR_ERROR:
+		pci_write_config_dword(pdev, 0xA8 + slot * 4, val);
+		return 0;
+
+	case SCR_CONTROL:
+		/* set the DET field */
+		v |= ((val & 0x4) >> 1) | (val & 0x1);
+
+		/* set the IPM field */
+		v |= ((val >> 8) & 0x3) << 2;
+
+		pci_write_config_byte(pdev, 0xA4 + slot, v);
+		return 0;
+
+	default:
+		return -EINVAL;
+	}
+}
+
 static struct scsi_host_template via_sht = {
 	ATA_BMDMA_SHT(DRV_NAME),
 };
@@ -457,6 +535,12 @@ static struct ata_port_operations via_port_ops_noirq = {
 	.sff_data_xfer	= ata_sff_data_xfer_noirq,
 };
 
+static struct ata_port_operations vx800_sata_ops = {
+	.inherits		= &via_port_ops,
+	.scr_read		= vx800_scr_read,
+	.scr_write		= vx800_scr_write,
+};
+
 /**
  *	via_config_fifo		-	set up the FIFO
  *	@pdev: PCI device
@@ -548,7 +632,22 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
 		.udma_mask = ATA_UDMA6,	/* FIXME: should check north bridge */
 		.port_ops = &via_port_ops
 	};
-	const struct ata_port_info *ppi[] = { NULL, NULL };
+	static const struct ata_port_info via_vx800_sata_info = {
+		.flags		= ATA_FLAG_SATA,
+		.pio_mask	= ATA_PIO4,
+		.mwdma_mask	= ATA_MWDMA2,
+		.udma_mask	= ATA_UDMA6,
+		.port_ops	= &vx800_sata_ops,
+	};
+	static const struct ata_port_info via_vx800_pata_info = {
+		.flags		= ATA_FLAG_SLAVE_POSS,
+		.pio_mask	= ATA_PIO4,
+		/* No MWDMA */
+		.udma_mask	= ATA_UDMA6,
+		.port_ops	= &via_port_ops,
+	};
+
+	const struct ata_port_info *ppi[] = { NULL, NULL, NULL };
 	struct pci_dev *isa;
 	const struct via_isa_bridge *config;
 	static int printed_version;
@@ -629,7 +728,41 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
 	}
 
 	/* We have established the device type, now fire it up */
-	return ata_pci_bmdma_init_one(pdev, ppi, &via_sht, (void *)config, 0);
+	if (config->id != PCI_DEVICE_ID_VIA_SATA_EIDE)
+		return ata_pci_bmdma_init_one(pdev, ppi, &via_sht,
+						(void *)config, 0);
+	/* VX800 has two SATA links on first port and two PATA links on 
+	 * second port. This is just to get SError in dmesg. */
+	else {
+		struct ata_host *host;
+		struct device *dev = &pdev->dev;
+		int rc;
+
+		ppi[0] = &via_vx800_sata_info;
+		ppi[1] = &via_vx800_pata_info;
+		dev_printk(KERN_INFO, &pdev->dev, "VIA VX800 SATA/PATA\n");
+
+		if (!devres_open_group(dev, NULL, GFP_KERNEL))
+			return -ENOMEM;
+
+		rc = ata_pci_bmdma_prepare_host(pdev, ppi, &host);
+		if (rc)
+			return rc;
+
+		host->private_data = (void *)config;
+		/* Do we need to set any? */
+		host->flags |= 0;
+		/* Only first port has separate cables for devices */
+		ata_slave_link_init(host->ports[0]);
+		pci_set_master(pdev);
+		rc = ata_pci_sff_activate_host(host, ata_bmdma_interrupt, 
+						&via_sht);
+		if (rc == 0)
+			devres_remove_group(&pdev->dev, NULL);
+		else
+			devres_release_group(&pdev->dev, NULL);
+		return rc;
+	}
 }
 
 #ifdef CONFIG_PM
