All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] sata_via: add VT6421 PATA support
@ 2006-11-09 14:35 Tomasz Chmielewski
  0 siblings, 0 replies; 5+ messages in thread
From: Tomasz Chmielewski @ 2006-11-09 14:35 UTC (permalink / raw)
  To: linux-ide, Jeff Garzik

[-- Attachment #1: Type: text/plain, Size: 357 bytes --]

This patch adds VT6421 PATA support to sata_via.

If we don't want to enable PATA support, nothing is changed in sata_via 
driver:

<M> VIA SATA support
      [ ]   VT6421 PATA support (HIGHLY EXPERIMENTAL)


The patch is based on the patch from VIA.


It applies to 2.6.18.2, if someone wants, I can make it work with 
2.6.19-rc5.


-- 
Tomasz Chmielewski

[-- Attachment #2: patch.sata_via-vt6421_pata --]
[-- Type: text/plain, Size: 7612 bytes --]

diff -uprN linux-2.6.18.2/drivers/scsi/Kconfig linux-2.6.18.2.new/drivers/scsi/Kconfig
--- linux-2.6.18.2/drivers/scsi/Kconfig	2006-11-04 02:33:58.000000000 +0100
+++ linux-2.6.18.2.new/drivers/scsi/Kconfig	2006-11-09 11:56:12.000000000 +0100
@@ -606,6 +606,14 @@ config SCSI_SATA_VIA
 
 	  If unsure, say N.
 
+config SCSI_VT6421_PATA
+        bool "VT6421 PATA support (HIGHLY EXPERIMENTAL)"
+        depends on SCSI_SATA_VIA
+        help
+          This option enables support for PATA on VT6421 chips.
+
+          If unsure, say N.
+
 config SCSI_SATA_VITESSE
 	tristate "VITESSE VSC-7174 / INTEL 31244 SATA support"
 	depends on SCSI_SATA && PCI
diff -uprN linux-2.6.18.2/drivers/scsi/sata_via.c linux-2.6.18.2.new/drivers/scsi/sata_via.c
--- linux-2.6.18.2/drivers/scsi/sata_via.c	2006-11-04 02:33:58.000000000 +0100
+++ linux-2.6.18.2.new/drivers/scsi/sata_via.c	2006-11-09 12:43:59.000000000 +0100
@@ -3,7 +3,7 @@
  *
  *  Maintained by:  Jeff Garzik <jgarzik@pobox.com>
  * 		   Please ALWAYS copy linux-ide@vger.kernel.org
- 		   on emails.
+ *		   on emails.
  *
  *  Copyright 2003-2004 Red Hat, Inc.  All rights reserved.
  *  Copyright 2003-2004 Jeff Garzik
@@ -29,10 +29,6 @@
  *
  *  Hardware documentation available under NDA.
  *
- *
- *  To-do list:
- *  - VT6421 PATA support
- *
  */
 
 #include <linux/kernel.h>
@@ -63,7 +59,12 @@ enum {
 	PORT0			= (1 << 1),
 	PORT1			= (1 << 0),
 	ALL_PORTS		= PORT0 | PORT1,
+	
+#ifndef CONFIG_SCSI_VT6421_PATA
 	N_PORTS			= 2,
+#else
+	N_PORTS			= 3,
+#endif
 
 	NATIVE_MODE_ALL		= (1 << 7) | (1 << 6) | (1 << 5) | (1 << 4),
 
@@ -109,9 +110,18 @@ static struct scsi_host_template svia_sh
 	.bios_param		= ata_std_bios_param,
 };
 
+#ifdef CONFIG_SCSI_VT6421_PATA
+static void via_pata_phy_reset(struct ata_port *ap);
+static void via_pata_set_piomode(struct ata_port *ap, struct ata_device *adev);
+static void via_pata_set_dmamode(struct ata_port *ap, struct ata_device *adev);
+#endif
+
 static const struct ata_port_operations vt6420_sata_ops = {
 	.port_disable		= ata_port_disable,
-
+#ifdef CONFIG_SCSI_VT6421_PATA
+	.set_piomode            = via_pata_set_piomode,
+	.set_dmamode            = via_pata_set_dmamode,
+#endif
 	.tf_load		= ata_tf_load,
 	.tf_read		= ata_tf_read,
 	.check_status		= ata_check_status,
@@ -309,8 +319,10 @@ static void vt6421_init_addrs(struct ata
 	probe_ent->port[port].ctl_addr = (reg_addr + 8) | ATA_PCI_CTL_OFS;
 	probe_ent->port[port].bmdma_addr = bmdma_addr;
 
+#ifndef CONFIG_SCSI_VT6421_PATA
 	scr_addr = vt6421_scr_addr(pci_resource_start(pdev, 5), port);
 	probe_ent->port[port].scr_addr = scr_addr;
+#endif
 
 	ata_std_ports(&probe_ent->port[port]);
 }
@@ -346,7 +358,12 @@ static struct ata_probe_ent *vt6421_init
 	INIT_LIST_HEAD(&probe_ent->node);
 
 	probe_ent->sht		= &svia_sht;
+#ifndef CONFIG_SCSI_VT6421_PATA
 	probe_ent->host_flags	= ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY;
+#else
+	probe_ent->host_flags   = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST |
+				  ATA_FLAG_NO_LEGACY;
+#endif
 	probe_ent->port_ops	= &vt6421_sata_ops;
 	probe_ent->n_ports	= N_PORTS;
 	probe_ent->irq		= pdev->irq;
@@ -361,6 +378,166 @@ static struct ata_probe_ent *vt6421_init
 	return probe_ent;
 }
 
+/* add functions for pata */
+
+
+/**
+ *     via_pata_cbl_detect - Probe host controller cable detect info
+ *     @ap: Port for which cable detect info is desired
+ *
+ *     Read 80c cable indicator from ATA PCI device's PCI config
+ *     register.  This register is normally set by firmware (BIOS).
+ *
+ *     LOCKING:
+ *     None (inherited from caller).
+ */
+static void via_pata_cbl_detect(struct ata_port *ap)
+{
+       struct pci_dev *pdev = to_pci_dev(ap->host_set->dev);
+       int cfg_addr;
+       u8 tmp, mask;
+
+       if (ap->port_no == 2) { /* PATA channel in VT6421 */
+               ap->cbl = ATA_CBL_PATA80;
+               cfg_addr = 0xB3;
+               pci_read_config_byte(pdev, cfg_addr, &tmp);
+               if (tmp & 0x10) { /* 40pin cable */
+                       ap->cbl = ATA_CBL_PATA40;
+               } else { /* 80pin cable */
+                       ap->cbl = ATA_CBL_PATA80;
+               }
+       } else { /* channel 0 and 1 are SATA channels */
+               ap->cbl = ATA_CBL_SATA;
+       }
+
+       return;
+}
+
+/**
+ *     via_pata_phy_reset - Probe specified port on PATA host controller
+ *     @ap: Port to probe
+ *
+ *     Probe PATA phy.
+ *
+ *     LOCKING:
+ *     None (inherited from caller).
+ */
+
+static void via_pata_phy_reset(struct ata_port *ap)
+{
+       struct pci_dev *pdev = to_pci_dev(ap->host_set->dev);
+
+       via_pata_cbl_detect(ap);
+
+       ata_port_probe(ap);
+
+       ata_bus_reset(ap);
+}
+
+
+/**
+ *     via_pata_set_piomode - Initialize host controller PATA PIO timings
+ *     @ap: Port whose timings we are configuring
+ *     @adev: um
+ *     @pio: PIO mode, 0 - 4
+ *
+ *     Set PIO mode for device, in host controller PCI config space.
+ *
+ *     LOCKING:
+ *     None (inherited from caller).
+ */
+
+static void via_pata_set_piomode (struct ata_port *ap, struct ata_device *adev)
+{
+       struct pci_dev *dev     = to_pci_dev(ap->host_set->dev);
+
+       u8 cfg_byte;
+       int cfg_addr;
+
+       if (ap->port_no != 2) { /* SATA channel in VT6421 */
+               /* no need to set */
+               return;
+       }
+
+
+       cfg_addr = 0xAB;
+       switch (adev->pio_mode & 0x07) {
+               case 0:
+                       cfg_byte = 0xa8;
+                       break;
+               case 1:
+                       cfg_byte = 0x65;
+                       break;
+               case 2:
+                       cfg_byte = 0x65;
+                       break;
+               case 3:
+                       cfg_byte = 0x31;
+                       break;
+               case 4:
+                       cfg_byte = 0x20;
+                       break;
+               default:
+                       cfg_byte = 0x20;
+       }
+
+       pci_write_config_byte (dev, cfg_addr, cfg_byte);
+}
+
+/**
+ *     via_pata_set_dmamode - Initialize host controller PATA PIO timings
+ *     @ap: Port whose timings we are configuring
+ *     @adev: um
+ *     @udma: udma mode, 0 - 6
+ *
+ *     Set UDMA mode for device, in host controller PCI config space.
+ *
+ *     LOCKING:
+ *     None (inherited from caller).
+ */
+
+static void via_pata_set_dmamode (struct ata_port *ap, struct ata_device *adev)
+{
+       struct pci_dev *dev     = to_pci_dev(ap->host_set->dev);
+
+       u8 cfg_byte;
+       int cfg_addr;
+
+       if (ap->port_no != 2) { /* SATA channel in VT6421 */
+               /* no need to set */
+               return;
+       }
+
+       cfg_addr = 0xB3;
+       switch (adev->dma_mode & 0x07) {
+               case 0:
+                       cfg_byte = 0xee;
+                       break;
+               case 1:
+                       cfg_byte = 0xe8;
+                       break;
+               case 2:
+                       cfg_byte = 0xe6;
+                       break;
+               case 3:
+                       cfg_byte = 0xe4;
+                       break;
+               case 4:
+                       cfg_byte = 0xe2;
+                       break;
+               case 5:
+                       cfg_byte = 0xe1;
+                       break;
+               case 6:
+                       cfg_byte = 0xe0;
+                       break;
+               default:
+                       cfg_byte = 0xe0;
+       }
+
+       pci_write_config_byte (dev, cfg_addr, cfg_byte);
+}
+
 static void svia_configure(struct pci_dev *pdev)
 {
 	u8 tmp8;

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH] sata_via: add VT6421 PATA support
@ 2006-12-04 14:26 Tomasz Chmielewski
  2006-12-04 15:12 ` Alan
  2006-12-04 15:21 ` [PATCH]: via 6421 PATA support done in a rather cleaner fashion Alan
  0 siblings, 2 replies; 5+ messages in thread
From: Tomasz Chmielewski @ 2006-12-04 14:26 UTC (permalink / raw)
  To: Linux IDE, linux-kernel, Jeff Garzik

[-- Attachment #1: Type: text/plain, Size: 314 bytes --]

his patch adds VT6421 PATA support to sata_via.

If we don't want to enable PATA support, nothing is changed in sata_via 
driver:

<M> VIA SATA support
      [ ]   VT6421 PATA support (HIGHLY EXPERIMENTAL)


The patch is based on the patch from VIA, it applies to 2.6.19.


-- 
Tomasz Chmielewski
http://wpkg.org


[-- Attachment #2: sata_via-vt6421_pata.patch --]
[-- Type: text/x-patch, Size: 8294 bytes --]

diff -uprN a/drivers/ata/Kconfig b/drivers/ata/Kconfig
--- a/drivers/ata/Kconfig	2006-11-29 22:57:37.000000000 +0100
+++ b/drivers/ata/Kconfig	2006-12-04 14:37:09.000000000 +0100
@@ -135,6 +135,14 @@ config SATA_VIA
 
 	  If unsure, say N.
 
+config PATA_VT6421
+        bool "VIA VT6421 PATA support (HIGHLY EXPERIMENTAL)"
+        depends on SATA_VIA
+        help
+          This option enables support for PATA on VIA VT6421 chips.
+
+          If unsure, say N.
+
 config SATA_VITESSE
 	tristate "VITESSE VSC-7174 / INTEL 31244 SATA support"
 	depends on PCI
diff -uprN a/drivers/ata/sata_via.c b/drivers/ata/sata_via.c
--- a/drivers/ata/sata_via.c	2006-11-29 22:57:37.000000000 +0100
+++ b/drivers/ata/sata_via.c	2006-12-04 14:41:36.000000000 +0100
@@ -3,7 +3,7 @@
  *
  *  Maintained by:  Jeff Garzik <jgarzik@pobox.com>
  * 		   Please ALWAYS copy linux-ide@vger.kernel.org
- 		   on emails.
+ *		   on emails.
  *
  *  Copyright 2003-2004 Red Hat, Inc.  All rights reserved.
  *  Copyright 2003-2004 Jeff Garzik
@@ -29,10 +29,6 @@
  *
  *  Hardware documentation available under NDA.
  *
- *
- *  To-do list:
- *  - VT6421 PATA support
- *
  */
 
 #include <linux/kernel.h>
@@ -63,7 +59,12 @@ enum {
 	PORT0			= (1 << 1),
 	PORT1			= (1 << 0),
 	ALL_PORTS		= PORT0 | PORT1,
+
+#ifndef CONFIG_PATA_VT6421
 	N_PORTS			= 2,
+#else
+	N_PORTS                 = 3,
+#endif
 
 	NATIVE_MODE_ALL		= (1 << 7) | (1 << 6) | (1 << 5) | (1 << 4),
 
@@ -109,6 +110,12 @@ static struct scsi_host_template svia_sh
 	.bios_param		= ata_std_bios_param,
 };
 
+#ifdef CONFIG_PATA_VT6421
+static void via_pata_phy_reset(struct ata_port *ap);
+static void via_pata_set_piomode(struct ata_port *ap, struct ata_device *adev);
+static void via_pata_set_dmamode(struct ata_port *ap, struct ata_device *adev);
+#endif
+
 static const struct ata_port_operations vt6420_sata_ops = {
 	.port_disable		= ata_port_disable,
 
@@ -143,6 +150,11 @@ static const struct ata_port_operations 
 static const struct ata_port_operations vt6421_sata_ops = {
 	.port_disable		= ata_port_disable,
 
+#ifdef CONFIG_PATA_VT6421
+       .set_piomode            = via_pata_set_piomode,
+       .set_dmamode            = via_pata_set_dmamode,
+#endif
+
 	.tf_load		= ata_tf_load,
 	.tf_read		= ata_tf_read,
 	.check_status		= ata_check_status,
@@ -154,6 +166,10 @@ static const struct ata_port_operations 
 	.bmdma_stop		= ata_bmdma_stop,
 	.bmdma_status		= ata_bmdma_status,
 
+#ifdef CONFIG_PATA_VT6421
+	.phy_reset              = via_pata_phy_reset,
+#endif
+
 	.qc_prep		= ata_qc_prep,
 	.qc_issue		= ata_qc_issue_prot,
 	.data_xfer		= ata_pio_data_xfer,
@@ -166,8 +182,10 @@ static const struct ata_port_operations 
 	.irq_handler		= ata_interrupt,
 	.irq_clear		= ata_bmdma_irq_clear,
 
+#ifndef CONFIG_PATA_VT6421
 	.scr_read		= svia_scr_read,
 	.scr_write		= svia_scr_write,
+#endif
 
 	.port_start		= ata_port_start,
 	.port_stop		= ata_port_stop,
@@ -237,6 +255,7 @@ static int vt6420_prereset(struct ata_po
 	 * __sata_phy_reset().
 	 */
 	svia_scr_write(ap, SCR_CONTROL, 0x300);
+
 	svia_scr_read(ap, SCR_CONTROL); /* flush */
 
 	/* wait for phy to become ready, if necessary */
@@ -291,6 +310,7 @@ static unsigned long svia_scr_addr(unsig
 	return addr + (port * 128);
 }
 
+
 static unsigned long vt6421_scr_addr(unsigned long addr, unsigned int port)
 {
 	return addr + (port * 64);
@@ -347,7 +367,14 @@ static struct ata_probe_ent *vt6421_init
 	INIT_LIST_HEAD(&probe_ent->node);
 
 	probe_ent->sht		= &svia_sht;
+
+#ifndef CONFIG_PATA_VT6421
 	probe_ent->port_flags	= ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY;
+#else
+        probe_ent->port_flags   = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST |
+                                  ATA_FLAG_NO_LEGACY;
+#endif
+
 	probe_ent->port_ops	= &vt6421_sata_ops;
 	probe_ent->n_ports	= N_PORTS;
 	probe_ent->irq		= pdev->irq;
@@ -362,6 +389,165 @@ static struct ata_probe_ent *vt6421_init
 	return probe_ent;
 }
 
+#ifdef CONFIG_PATA_VT6421
+/* add functions for pata */
+
+/**
+ *     via_pata_cbl_detect - Probe host controller cable detect info
+ *     @ap: Port for which cable detect info is desired
+ *
+ *     Read 80c cable indicator from ATA PCI device's PCI config
+ *     register.  This register is normally set by firmware (BIOS).
+ *
+ *     LOCKING:
+ *     None (inherited from caller).
+ */
+static void via_pata_cbl_detect(struct ata_port *ap)
+{
+       struct pci_dev *pdev = to_pci_dev(ap->host->dev);
+       int cfg_addr;
+       u8 tmp;
+
+       if (ap->port_no == 2) { /* PATA channel in VT6421 */
+               ap->cbl = ATA_CBL_PATA80;
+               cfg_addr = 0xB3;
+               pci_read_config_byte(pdev, cfg_addr, &tmp);
+               if (tmp & 0x10) { /* 40pin cable */
+                       ap->cbl = ATA_CBL_PATA40;
+               } else { /* 80pin cable */
+                       ap->cbl = ATA_CBL_PATA80;
+               }
+       } else { /* channel 0 and 1 are SATA channels */
+               ap->cbl = ATA_CBL_SATA;
+       }
+
+       return;
+}
+
+/**
+ *     via_pata_phy_reset - Probe specified port on PATA host controller
+ *     @ap: Port to probe
+ *
+ *     Probe PATA phy.
+ *
+ *     LOCKING:
+ *     None (inherited from caller).
+ */
+
+static void via_pata_phy_reset(struct ata_port *ap)
+{
+       via_pata_cbl_detect(ap);
+
+       ata_port_probe(ap);
+
+       ata_bus_reset(ap);
+}
+
+
+/**
+ *     via_pata_set_piomode - Initialize host controller PATA PIO timings
+ *     @ap: Port whose timings we are configuring
+ *     @adev: um
+ *     @pio: PIO mode, 0 - 4
+ *
+ *     Set PIO mode for device, in host controller PCI config space.
+ *
+ *     LOCKING:
+ *     None (inherited from caller).
+ */
+
+static void via_pata_set_piomode (struct ata_port *ap, struct ata_device *adev)
+{
+       struct pci_dev *dev     = to_pci_dev(ap->host->dev);
+
+       u8 cfg_byte;
+       int cfg_addr;
+
+       if (ap->port_no != 2) { /* SATA channel in VT6421 */
+               /* no need to set */
+               return;
+       }
+
+
+       cfg_addr = 0xAB;
+       switch (adev->pio_mode & 0x07) {
+               case 0:
+                       cfg_byte = 0xa8;
+                       break;
+               case 1:
+                       cfg_byte = 0x65;
+                       break;
+               case 2:
+                       cfg_byte = 0x65;
+                       break;
+               case 3:
+                       cfg_byte = 0x31;
+                       break;
+               case 4:
+                       cfg_byte = 0x20;
+                       break;
+               default:
+                       cfg_byte = 0x20;
+       }
+
+       pci_write_config_byte (dev, cfg_addr, cfg_byte);
+}
+
+/**
+ *     via_pata_set_dmamode - Initialize host controller PATA PIO timings
+ *     @ap: Port whose timings we are configuring
+ *     @adev: um
+ *     @udma: udma mode, 0 - 6
+ *
+ *     Set UDMA mode for device, in host controller PCI config space.
+ *
+ *     LOCKING:
+ *     None (inherited from caller).
+ */
+
+static void via_pata_set_dmamode (struct ata_port *ap, struct ata_device *adev)
+{
+       struct pci_dev *dev     = to_pci_dev(ap->host->dev);
+
+       u8 cfg_byte;
+       int cfg_addr;
+
+       if (ap->port_no != 2) { /* SATA channel in VT6421 */
+               /* no need to set */
+               return;
+       }
+
+       cfg_addr = 0xB3;
+       switch (adev->dma_mode & 0x07) {
+               case 0:
+                       cfg_byte = 0xee;
+                       break;
+               case 1:
+                       cfg_byte = 0xe8;
+                       break;
+               case 2:
+                       cfg_byte = 0xe6;
+                       break;
+               case 3:
+                       cfg_byte = 0xe4;
+                       break;
+               case 4:
+                       cfg_byte = 0xe2;
+                       break;
+               case 5:
+                       cfg_byte = 0xe1;
+                       break;
+               case 6:
+                       cfg_byte = 0xe0;
+                       break;
+               default:
+                       cfg_byte = 0xe0;
+       }
+
+       pci_write_config_byte (dev, cfg_addr, cfg_byte);
+}
+#endif
+
 static void svia_configure(struct pci_dev *pdev)
 {
 	u8 tmp8;

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] sata_via: add VT6421 PATA support
  2006-12-04 14:26 [PATCH] sata_via: add VT6421 PATA support Tomasz Chmielewski
@ 2006-12-04 15:12 ` Alan
  2006-12-04 15:21 ` [PATCH]: via 6421 PATA support done in a rather cleaner fashion Alan
  1 sibling, 0 replies; 5+ messages in thread
From: Alan @ 2006-12-04 15:12 UTC (permalink / raw)
  To: Tomasz Chmielewski; +Cc: Linux IDE, linux-kernel, Jeff Garzik

On Mon, 04 Dec 2006 15:26:02 +0100
Tomasz Chmielewski <mangoo@wpkg.org> wrote:

> his patch adds VT6421 PATA support to sata_via.

NAK

This shouldn't be compile time
It doesn't handle MWDMA properly
It uses the old error/reset code


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH]: via 6421 PATA support done in a rather cleaner fashion
  2006-12-04 14:26 [PATCH] sata_via: add VT6421 PATA support Tomasz Chmielewski
  2006-12-04 15:12 ` Alan
@ 2006-12-04 15:21 ` Alan
  2006-12-04 16:27   ` Tomasz Chmielewski
  1 sibling, 1 reply; 5+ messages in thread
From: Alan @ 2006-12-04 15:21 UTC (permalink / raw)
  To: Tomasz Chmielewski; +Cc: Linux IDE, linux-kernel, Jeff Garzik

Wants testing... so test and report

Signed-off-by: Alan Cox <alan@redhat.com>

--- linux.vanilla-2.6.19-rc6-mm1/drivers/ata/sata_via.c	2006-11-24 13:58:05.000000000 +0000
+++ linux-2.6.19-rc6-mm1/drivers/ata/sata_via.c	2006-12-04 14:57:34.719099648 +0000
@@ -59,11 +59,14 @@
 	SATA_INT_GATE		= 0x41, /* SATA interrupt gating */
 	SATA_NATIVE_MODE	= 0x42, /* Native mode enable */
 	SATA_PATA_SHARING	= 0x49, /* PATA/SATA sharing func ctrl */
-
+	PATA_UDMA_TIMING	= 0xB3, /* PATA timing for DMA/ cable detect */
+	PATA_PIO_TIMING		= 0xAB, /* PATA timing register */
+	
 	PORT0			= (1 << 1),
 	PORT1			= (1 << 0),
 	ALL_PORTS		= PORT0 | PORT1,
-	N_PORTS			= 2,
+	PATA_PORT		= 2,	/* PATA is port 2 */
+	N_PORTS			= 3,
 
 	NATIVE_MODE_ALL		= (1 << 7) | (1 << 6) | (1 << 5) | (1 << 4),
 
@@ -75,6 +78,10 @@
 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 vt6420_error_handler(struct ata_port *ap);
+static void vt6421_error_handler(struct ata_port *ap);
+static void vt6421_set_pio_mode(struct ata_port *ap, struct ata_device *adev);
+static void vt6421_set_dma_mode(struct ata_port *ap, struct ata_device *adev);
+static unsigned long vt6421_mode_filter(const struct ata_port *ap, struct ata_device *adev, unsigned long modes);
 
 static const struct pci_device_id svia_pci_tbl[] = {
 	{ PCI_VDEVICE(VIA, 0x0591), vt6420 },
@@ -140,8 +147,12 @@
 	.host_stop		= ata_host_stop,
 };
 
-static const struct ata_port_operations vt6421_sata_ops = {
+static const struct ata_port_operations vt6421_ata_ops = {
 	.port_disable		= ata_port_disable,
+	
+	.set_piomode		= vt6421_set_pio_mode,
+	.set_dmamode		= vt6421_set_dma_mode,
+	.mode_filter		= vt6421_mode_filter,
 
 	.tf_load		= ata_tf_load,
 	.tf_read		= ata_tf_read,
@@ -160,7 +171,7 @@
 
 	.freeze			= ata_bmdma_freeze,
 	.thaw			= ata_bmdma_thaw,
-	.error_handler		= ata_bmdma_error_handler,
+	.error_handler		= vt6421_error_handler,
 	.post_internal_cmd	= ata_bmdma_post_internal_cmd,
 
 	.irq_handler		= ata_interrupt,
@@ -278,6 +289,55 @@
 				  NULL, ata_std_postreset);
 }
 
+static int vt6421_prereset(struct ata_port *ap)
+{
+	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
+	u8 tmp;
+	
+	if (ap->port_no != PATA_PORT) {
+		ap->cbl = ATA_CBL_SATA;
+		return 0;
+	}
+	pci_read_config_byte(pdev, PATA_UDMA_TIMING, &tmp);
+	
+	if (tmp & 0x10)
+		ap->cbl = ATA_CBL_PATA40;
+	else
+		ap->cbl = ATA_CBL_PATA80;
+	return 0;
+}
+
+static void vt6421_error_handler(struct ata_port *ap)
+{
+	return ata_bmdma_drive_eh(ap, vt6421_prereset, ata_std_softreset,
+				  NULL, ata_std_postreset);
+}
+
+static void vt6421_set_pio_mode(struct ata_port *ap, struct ata_device *adev)
+{
+	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
+	static const u8 pio_bits[] = { 0xA8, 0x65, 0x65, 0x31, 0x20 };
+	if (ap->port_no == PATA_PORT)
+		pci_write_config_byte(pdev, PATA_PIO_TIMING, pio_bits[adev->pio_mode - XFER_PIO_0]);
+}
+
+static void vt6421_set_dma_mode(struct ata_port *ap, struct ata_device *adev)
+{
+	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
+	static const u8 udma_bits[] = { 0xEE, 0xE8, 0xE6, 0xE4, 0xE2, 0xE1, 0xE0, 0xE0 };
+	if (ap->port_no == PATA_PORT)
+		pci_write_config_byte(pdev, PATA_UDMA_TIMING, udma_bits[adev->pio_mode - XFER_UDMA_0]);
+}
+
+static unsigned long vt6421_mode_filter(const struct ata_port *ap, struct ata_device *adev, unsigned long modes)
+{
+	if(ap->port_no == PATA_PORT) {
+		modes &= ~ATA_MASK_MWDMA;	/* No MWDMA support */
+		modes &= ~ (0x40 << ATA_SHIFT_UDMA);  /* UDMA 133 limited */
+	}
+	return modes;
+}
+
 static const unsigned int svia_bar_sizes[] = {
 	8, 4, 8, 4, 16, 256
 };
@@ -348,7 +408,7 @@
 
 	probe_ent->sht		= &svia_sht;
 	probe_ent->port_flags	= ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY;
-	probe_ent->port_ops	= &vt6421_sata_ops;
+	probe_ent->port_ops	= &vt6421_ata_ops;
 	probe_ent->n_ports	= N_PORTS;
 	probe_ent->irq		= pdev->irq;
 	probe_ent->irq_flags	= IRQF_SHARED;
@@ -500,4 +560,3 @@
 
 module_init(svia_init);
 module_exit(svia_exit);
-

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH]: via 6421 PATA support done in a rather cleaner fashion
  2006-12-04 15:21 ` [PATCH]: via 6421 PATA support done in a rather cleaner fashion Alan
@ 2006-12-04 16:27   ` Tomasz Chmielewski
  0 siblings, 0 replies; 5+ messages in thread
From: Tomasz Chmielewski @ 2006-12-04 16:27 UTC (permalink / raw)
  To: Alan; +Cc: Linux IDE, linux-kernel, Jeff Garzik

Alan wrote:
> Wants testing... so test and report
> 
> Signed-off-by: Alan Cox <alan@redhat.com>
> 
> --- linux.vanilla-2.6.19-rc6-mm1/drivers/ata/sata_via.c	2006-11-24 13:58:05.000000000 +0000
> +++ linux-2.6.19-rc6-mm1/drivers/ata/sata_via.c	2006-12-04 14:57:34.719099648 +0000

PATA works fine with this patch, great.


Being on sata_via subject - why did it start to appear in 2.6.19 kernel 
(even without any pata patch)?

# rmmod sata_via
ata6.00: disabled
Synchronizing SCSI cache for disk sdb:
FAILED
   status = 0, message = 00, host = 4, driver = 00


Other sata modules I tried unload fine.


-- 
Tomasz Chmielewski
http://wpkg.org

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2006-12-04 16:27 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-12-04 14:26 [PATCH] sata_via: add VT6421 PATA support Tomasz Chmielewski
2006-12-04 15:12 ` Alan
2006-12-04 15:21 ` [PATCH]: via 6421 PATA support done in a rather cleaner fashion Alan
2006-12-04 16:27   ` Tomasz Chmielewski
  -- strict thread matches above, loose matches on Subject: below --
2006-11-09 14:35 [PATCH] sata_via: add VT6421 PATA support Tomasz Chmielewski

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.