aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata/sata_sx4.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ata/sata_sx4.c')
-rw-r--r--drivers/ata/sata_sx4.c51
1 files changed, 51 insertions, 0 deletions
diff --git a/drivers/ata/sata_sx4.c b/drivers/ata/sata_sx4.c
index ff0a78dc8b86..3d83ee273388 100644
--- a/drivers/ata/sata_sx4.c
+++ b/drivers/ata/sata_sx4.c
@@ -30,6 +30,54 @@
30 * 30 *
31 */ 31 */
32 32
33/*
34 Theory of operation
35 -------------------
36
37 The SX4 (PDC20621) chip features a single Host DMA (HDMA) copy
38 engine, DIMM memory, and four ATA engines (one per SATA port).
39 Data is copied to/from DIMM memory by the HDMA engine, before
40 handing off to one (or more) of the ATA engines. The ATA
41 engines operate solely on DIMM memory.
42
43 The SX4 behaves like a PATA chip, with no SATA controls or
44 knowledge whatsoever, leading to the presumption that
45 PATA<->SATA bridges exist on SX4 boards, external to the
46 PDC20621 chip itself.
47
48 The chip is quite capable, supporting an XOR engine and linked
49 hardware commands (permits a string to transactions to be
50 submitted and waited-on as a single unit), and an optional
51 microprocessor.
52
53 The limiting factor is largely software. This Linux driver was
54 written to multiplex the single HDMA engine to copy disk
55 transactions into a fixed DIMM memory space, from where an ATA
56 engine takes over. As a result, each WRITE looks like this:
57
58 submit HDMA packet to hardware
59 hardware copies data from system memory to DIMM
60 hardware raises interrupt
61
62 submit ATA packet to hardware
63 hardware executes ATA WRITE command, w/ data in DIMM
64 hardware raises interrupt
65
66 and each READ looks like this:
67
68 submit ATA packet to hardware
69 hardware executes ATA READ command, w/ data in DIMM
70 hardware raises interrupt
71
72 submit HDMA packet to hardware
73 hardware copies data from DIMM to system memory
74 hardware raises interrupt
75
76 This is a very slow, lock-step way of doing things that can
77 certainly be improved by motivated kernel hackers.
78
79 */
80
33#include <linux/kernel.h> 81#include <linux/kernel.h>
34#include <linux/module.h> 82#include <linux/module.h>
35#include <linux/pci.h> 83#include <linux/pci.h>
@@ -58,6 +106,8 @@ enum {
58 PDC_INT_SEQMASK = 0x40, /* Mask of asserted SEQ INTs */ 106 PDC_INT_SEQMASK = 0x40, /* Mask of asserted SEQ INTs */
59 PDC_HDMA_CTLSTAT = 0x12C, /* Host DMA control / status */ 107 PDC_HDMA_CTLSTAT = 0x12C, /* Host DMA control / status */
60 108
109 PDC_CTLSTAT = 0x60, /* IDEn control / status */
110
61 PDC_20621_SEQCTL = 0x400, 111 PDC_20621_SEQCTL = 0x400,
62 PDC_20621_SEQMASK = 0x480, 112 PDC_20621_SEQMASK = 0x480,
63 PDC_20621_GENERAL_CTL = 0x484, 113 PDC_20621_GENERAL_CTL = 0x484,
@@ -89,6 +139,7 @@ enum {
89 139
90 PDC_MASK_INT = (1 << 10), /* HDMA/ATA mask int */ 140 PDC_MASK_INT = (1 << 10), /* HDMA/ATA mask int */
91 PDC_RESET = (1 << 11), /* HDMA/ATA reset */ 141 PDC_RESET = (1 << 11), /* HDMA/ATA reset */
142 PDC_DMA_ENABLE = (1 << 7), /* DMA start/stop */
92 143
93 PDC_MAX_HDMA = 32, 144 PDC_MAX_HDMA = 32,
94 PDC_HDMA_Q_MASK = (PDC_MAX_HDMA - 1), 145 PDC_HDMA_Q_MASK = (PDC_MAX_HDMA - 1),