summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/ata/sata_sx4.c51
-rw-r--r--drivers/ata/sata_via.c4
2 files changed, 52 insertions, 3 deletions
diff --git a/drivers/ata/sata_sx4.c b/drivers/ata/sata_sx4.c
index ff0a78dc8b8..3d83ee27338 100644
--- a/drivers/ata/sata_sx4.c
+++ b/drivers/ata/sata_sx4.c
@@ -30,6 +30,54 @@
*
*/
+/*
+ Theory of operation
+ -------------------
+
+ The SX4 (PDC20621) chip features a single Host DMA (HDMA) copy
+ engine, DIMM memory, and four ATA engines (one per SATA port).
+ Data is copied to/from DIMM memory by the HDMA engine, before
+ handing off to one (or more) of the ATA engines. The ATA
+ engines operate solely on DIMM memory.
+
+ The SX4 behaves like a PATA chip, with no SATA controls or
+ knowledge whatsoever, leading to the presumption that
+ PATA<->SATA bridges exist on SX4 boards, external to the
+ PDC20621 chip itself.
+
+ The chip is quite capable, supporting an XOR engine and linked
+ hardware commands (permits a string to transactions to be
+ submitted and waited-on as a single unit), and an optional
+ microprocessor.
+
+ The limiting factor is largely software. This Linux driver was
+ written to multiplex the single HDMA engine to copy disk
+ transactions into a fixed DIMM memory space, from where an ATA
+ engine takes over. As a result, each WRITE looks like this:
+
+ submit HDMA packet to hardware
+ hardware copies data from system memory to DIMM
+ hardware raises interrupt
+
+ submit ATA packet to hardware
+ hardware executes ATA WRITE command, w/ data in DIMM
+ hardware raises interrupt
+
+ and each READ looks like this:
+
+ submit ATA packet to hardware
+ hardware executes ATA READ command, w/ data in DIMM
+ hardware raises interrupt
+
+ submit HDMA packet to hardware
+ hardware copies data from DIMM to system memory
+ hardware raises interrupt
+
+ This is a very slow, lock-step way of doing things that can
+ certainly be improved by motivated kernel hackers.
+
+ */
+
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/pci.h>
@@ -58,6 +106,8 @@ enum {
PDC_INT_SEQMASK = 0x40, /* Mask of asserted SEQ INTs */
PDC_HDMA_CTLSTAT = 0x12C, /* Host DMA control / status */
+ PDC_CTLSTAT = 0x60, /* IDEn control / status */
+
PDC_20621_SEQCTL = 0x400,
PDC_20621_SEQMASK = 0x480,
PDC_20621_GENERAL_CTL = 0x484,
@@ -89,6 +139,7 @@ enum {
PDC_MASK_INT = (1 << 10), /* HDMA/ATA mask int */
PDC_RESET = (1 << 11), /* HDMA/ATA reset */
+ PDC_DMA_ENABLE = (1 << 7), /* DMA start/stop */
PDC_MAX_HDMA = 32,
PDC_HDMA_Q_MASK = (PDC_MAX_HDMA - 1),
diff --git a/drivers/ata/sata_via.c b/drivers/ata/sata_via.c
index e8b90e7b42d..e816965ef4f 100644
--- a/drivers/ata/sata_via.c
+++ b/drivers/ata/sata_via.c
@@ -303,9 +303,7 @@ static int vt6420_prereset(struct ata_port *ap, unsigned long deadline)
if (!(ap->pflags & ATA_PFLAG_LOADING))
goto skip_scr;
- /* Resume phy. This is the old resume sequence from
- * __sata_phy_reset().
- */
+ /* Resume phy. This is the old SATA resume sequence */
svia_scr_write(ap, SCR_CONTROL, 0x300);
svia_scr_read(ap, SCR_CONTROL); /* flush */