Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
f4c7bac1
Commit
f4c7bac1
authored
Oct 22, 2003
by
Jeff Garzik
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[libata] more pdc20621 work
parent
23700c6b
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
230 additions
and
78 deletions
+230
-78
drivers/scsi/sata_promise.c
drivers/scsi/sata_promise.c
+230
-78
No files found.
drivers/scsi/sata_promise.c
View file @
f4c7bac1
...
@@ -32,6 +32,9 @@
...
@@ -32,6 +32,9 @@
#include "scsi.h"
#include "scsi.h"
#include "hosts.h"
#include "hosts.h"
#include <linux/libata.h>
#include <linux/libata.h>
#include <asm/io.h>
#undef DIRECT_HDMA
#define DRV_NAME "sata_promise"
#define DRV_NAME "sata_promise"
#define DRV_VERSION "0.84"
#define DRV_VERSION "0.84"
...
@@ -50,12 +53,23 @@ enum {
...
@@ -50,12 +53,23 @@ enum {
PDC_SLEW_CTL
=
0x470
,
/* slew rate control reg */
PDC_SLEW_CTL
=
0x470
,
/* slew rate control reg */
PDC_20621_SEQCTL
=
0x400
,
PDC_20621_SEQCTL
=
0x400
,
PDC_20621_SEQMASK
=
0x480
,
PDC_20621_SEQMASK
=
0x480
,
PDC_20621_PAGE_SIZE
=
(
32
*
1024
),
/* chosen, not constant, values; we design our own DIMM mem map */
/* chosen, not constant, values; we design our own DIMM mem map */
PDC_20621_DIMM_WINDOW
=
0x0C
,
/* page# for 32K DIMM window */
PDC_20621_DIMM_WINDOW
=
0x0C
,
/* page# for 32K DIMM window */
PDC_20621_DIMM_BASE
=
0x00200000
,
PDC_20621_DIMM_BASE
=
0x00200000
,
PDC_20621_HOST_PRD
=
64
,
PDC_20621_DIMM_DATA
=
(
64
*
1024
),
PDC_20621_ATA_PRD
=
72
,
PDC_DIMM_DATA_STEP
=
(
256
*
1024
),
PDC_DIMM_WINDOW_STEP
=
(
8
*
1024
),
PDC_DIMM_HOST_PRD
=
(
6
*
1024
),
PDC_DIMM_HOST_PKT
=
(
128
*
0
),
PDC_DIMM_HPKT_PRD
=
(
128
*
1
),
PDC_DIMM_ATA_PKT
=
(
128
*
2
),
PDC_DIMM_APKT_PRD
=
(
128
*
3
),
PDC_DIMM_HEADER_SZ
=
PDC_DIMM_APKT_PRD
+
128
,
PDC_PAGE_DATA
=
0x40
+
(
PDC_20621_DIMM_DATA
/
PDC_20621_PAGE_SIZE
),
PDC_PAGE_SET
=
PDC_DIMM_DATA_STEP
/
PDC_20621_PAGE_SIZE
,
PDC_CHIP0_OFS
=
0xC0000
,
/* offset of chip #0 */
PDC_CHIP0_OFS
=
0xC0000
,
/* offset of chip #0 */
...
@@ -68,8 +82,7 @@ enum {
...
@@ -68,8 +82,7 @@ enum {
struct
pdc_port_priv
{
struct
pdc_port_priv
{
u8
prd_buf
[
ATA_PRD_SZ
*
ATA_MAX_PRD
];
u8
dimm_buf
[(
ATA_PRD_SZ
*
ATA_MAX_PRD
)
+
512
];
u8
pkt_buf
[
256
];
u8
*
pkt
;
u8
*
pkt
;
dma_addr_t
pkt_dma
;
dma_addr_t
pkt_dma
;
};
};
...
@@ -429,39 +442,64 @@ static inline unsigned int pdc_prep_lba48(struct ata_taskfile *tf, u8 *buf, unsi
...
@@ -429,39 +442,64 @@ static inline unsigned int pdc_prep_lba48(struct ata_taskfile *tf, u8 *buf, unsi
return
i
;
return
i
;
}
}
static
inline
unsigned
int
pdc20621_pkt_header
(
struct
ata_taskfile
*
tf
,
static
inline
void
pdc20621_ata_sg
(
struct
ata_taskfile
*
tf
,
u8
*
buf
,
unsigned
int
portno
,
unsigned
int
portno
,
unsigned
int
devno
,
unsigned
int
total_len
)
u8
*
buf
,
unsigned
int
total_len
)
{
{
u8
dev_reg
;
u32
addr
;
unsigned
int
dw
=
PDC_DIMM_APKT_PRD
>>
2
;
u32
*
buf32
=
(
u32
*
)
buf
;
u32
*
buf32
=
(
u32
*
)
buf
;
unsigned
int
ofs
,
i
=
0
;
/*
/* output ATA packet S/G table */
* Set up Host DMA packet
addr
=
PDC_20621_DIMM_BASE
+
PDC_20621_DIMM_DATA
+
*/
(
PDC_DIMM_DATA_STEP
*
portno
);
if
(
tf
->
protocol
==
ATA_PROT_DMA_READ
)
VPRINTK
(
"ATA sg addr 0x%x, %d
\n
"
,
addr
,
addr
);
buf
[
i
++
]
=
PDC20621_PKT_READ
;
buf32
[
dw
]
=
cpu_to_le32
(
addr
);
else
buf32
[
dw
+
1
]
=
cpu_to_le32
(
total_len
|
ATA_PRD_EOT
);
buf
[
i
++
]
=
0
;
buf
[
i
++
]
=
0
;
/* reserved */
VPRINTK
(
"ATA PSG @ %x == (0x%x, 0x%x)
\n
"
,
buf
[
i
++
]
=
portno
+
1
+
4
;
/* seq. id */
PDC_20621_DIMM_BASE
+
buf
[
i
++
]
=
0xff
;
/* delay seq. id */
(
PDC_DIMM_WINDOW_STEP
*
portno
)
+
buf32
[
i
/
4
]
=
cpu_to_le32
(
PDC_20621_DIMM_BASE
+
(
4
*
1024
)
+
PDC_DIMM_APKT_PRD
,
(
2
*
1024
*
portno
));
buf32
[
dw
],
buf32
[
dw
+
1
]);
i
+=
4
;
}
buf32
[
i
/
4
]
=
cpu_to_le32
(
PDC_20621_DIMM_BASE
+
(
portno
*
1024
)
+
PDC_20621_HOST_PRD
);
static
inline
void
pdc20621_host_sg
(
struct
ata_taskfile
*
tf
,
u8
*
buf
,
i
+=
4
;
unsigned
int
portno
,
buf32
[
i
/
4
]
=
0
;
unsigned
int
total_len
)
i
+=
4
;
{
u32
addr
;
ofs
=
PDC_20621_HOST_PRD
/
4
;
unsigned
int
dw
=
PDC_DIMM_HPKT_PRD
>>
2
;
buf32
[
ofs
]
=
cpu_to_le32
(
PDC_20621_DIMM_BASE
+
(
32
*
1024
)
+
u32
*
buf32
=
(
u32
*
)
buf
;
(
256
*
1024
*
portno
));
buf32
[
ofs
+
1
]
=
cpu_to_le32
(
total_len
|
ATA_PRD_EOT
);
/* output Host DMA packet S/G table */
addr
=
PDC_20621_DIMM_BASE
+
PDC_20621_DIMM_DATA
+
(
PDC_DIMM_DATA_STEP
*
portno
);
buf32
[
dw
]
=
cpu_to_le32
(
addr
);
buf32
[
dw
+
1
]
=
cpu_to_le32
(
total_len
|
ATA_PRD_EOT
);
VPRINTK
(
"HOST PSG @ %x == (0x%x, 0x%x)
\n
"
,
PDC_20621_DIMM_BASE
+
(
PDC_DIMM_WINDOW_STEP
*
portno
)
+
PDC_DIMM_HPKT_PRD
,
buf32
[
dw
],
buf32
[
dw
+
1
]);
}
static
inline
unsigned
int
pdc20621_ata_pkt
(
struct
ata_taskfile
*
tf
,
unsigned
int
devno
,
u8
*
buf
,
unsigned
int
portno
)
{
unsigned
int
i
,
dw
;
u32
*
buf32
=
(
u32
*
)
buf
;
u8
dev_reg
;
unsigned
int
dimm_sg
=
PDC_20621_DIMM_BASE
+
(
PDC_DIMM_WINDOW_STEP
*
portno
)
+
PDC_DIMM_APKT_PRD
;
VPRINTK
(
"ENTER, dimm_sg == 0x%x, %d
\n
"
,
dimm_sg
,
dimm_sg
);
i
=
PDC_DIMM_ATA_PKT
;
/*
/*
* Set up ATA packet
* Set up ATA packet
...
@@ -475,16 +513,12 @@ static inline unsigned int pdc20621_pkt_header(struct ata_taskfile *tf,
...
@@ -475,16 +513,12 @@ static inline unsigned int pdc20621_pkt_header(struct ata_taskfile *tf,
buf
[
i
++
]
=
0
;
/* reserved */
buf
[
i
++
]
=
0
;
/* reserved */
buf
[
i
++
]
=
portno
+
1
;
/* seq. id */
buf
[
i
++
]
=
portno
+
1
;
/* seq. id */
buf
[
i
++
]
=
0xff
;
/* delay seq. id */
buf
[
i
++
]
=
0xff
;
/* delay seq. id */
buf32
[
i
/
4
]
=
cpu_to_le32
(
PDC_20621_DIMM_BASE
+
(
portno
*
1024
)
+
PDC_20621_ATA_PRD
);
i
+=
4
;
buf32
[
i
/
4
]
=
0
;
/* no next-packet */
i
+=
4
;
ofs
=
PDC_20621_ATA_PRD
/
4
;
/* dimm dma S/G, and next-pkt */
buf32
[
ofs
]
=
cpu_to_le32
(
PDC_20621_DIMM_BASE
+
(
32
*
1024
)
+
dw
=
i
>>
2
;
(
256
*
1024
*
portno
));
buf32
[
dw
]
=
cpu_to_le32
(
dimm_sg
);
buf32
[
ofs
+
1
]
=
cpu_to_le32
(
total_len
|
ATA_PRD_EOT
);
buf32
[
dw
+
1
]
=
0
;
i
+=
8
;
if
(
devno
==
0
)
if
(
devno
==
0
)
dev_reg
=
ATA_DEVICE_OBS
;
dev_reg
=
ATA_DEVICE_OBS
;
...
@@ -499,7 +533,46 @@ static inline unsigned int pdc20621_pkt_header(struct ata_taskfile *tf,
...
@@ -499,7 +533,46 @@ static inline unsigned int pdc20621_pkt_header(struct ata_taskfile *tf,
buf
[
i
++
]
=
(
1
<<
5
)
|
PDC_REG_DEVCTL
;
buf
[
i
++
]
=
(
1
<<
5
)
|
PDC_REG_DEVCTL
;
buf
[
i
++
]
=
tf
->
ctl
;
buf
[
i
++
]
=
tf
->
ctl
;
return
i
;
/* offset of next byte */
return
i
;
}
static
inline
void
pdc20621_host_pkt
(
struct
ata_taskfile
*
tf
,
u8
*
buf
,
unsigned
int
portno
)
{
unsigned
int
dw
;
u32
tmp
,
*
buf32
=
(
u32
*
)
buf
;
unsigned
int
host_sg
=
PDC_20621_DIMM_BASE
+
(
PDC_DIMM_WINDOW_STEP
*
portno
)
+
PDC_DIMM_HOST_PRD
;
unsigned
int
dimm_sg
=
PDC_20621_DIMM_BASE
+
(
PDC_DIMM_WINDOW_STEP
*
portno
)
+
PDC_DIMM_HPKT_PRD
;
VPRINTK
(
"ENTER, dimm_sg == 0x%x, %d
\n
"
,
dimm_sg
,
dimm_sg
);
VPRINTK
(
"host_sg == 0x%x, %d
\n
"
,
host_sg
,
host_sg
);
dw
=
PDC_DIMM_HOST_PKT
>>
2
;
/*
* Set up Host DMA packet
*/
if
(
tf
->
protocol
==
ATA_PROT_DMA_READ
)
tmp
=
PDC20621_PKT_READ
;
else
tmp
=
0
;
tmp
|=
((
portno
+
1
+
4
)
<<
16
);
buf32
[
dw
+
0
]
=
cpu_to_le32
(
tmp
);
buf32
[
dw
+
1
]
=
cpu_to_le32
(
host_sg
);
buf32
[
dw
+
2
]
=
cpu_to_le32
(
dimm_sg
);
buf32
[
dw
+
3
]
=
0
;
VPRINTK
(
"HOST PKT @ %x == (0x%x 0x%x 0x%x 0x%x)
\n
"
,
PDC_20621_DIMM_BASE
+
(
PDC_DIMM_WINDOW_STEP
*
portno
)
+
PDC_DIMM_HOST_PKT
,
buf32
[
dw
+
0
],
buf32
[
dw
+
1
],
buf32
[
dw
+
2
],
buf32
[
dw
+
3
]);
}
}
static
void
pdc20621_fill_sg
(
struct
ata_queued_cmd
*
qc
)
static
void
pdc20621_fill_sg
(
struct
ata_queued_cmd
*
qc
)
...
@@ -509,9 +582,10 @@ static void pdc20621_fill_sg(struct ata_queued_cmd *qc)
...
@@ -509,9 +582,10 @@ static void pdc20621_fill_sg(struct ata_queued_cmd *qc)
struct
pdc_port_priv
*
pp
=
ap
->
private_data
;
struct
pdc_port_priv
*
pp
=
ap
->
private_data
;
void
*
dimm_mmio
=
ap
->
host_set
->
private_data
;
void
*
dimm_mmio
=
ap
->
host_set
->
private_data
;
unsigned
int
portno
=
ap
->
port_no
;
unsigned
int
portno
=
ap
->
port_no
;
unsigned
int
i
,
last
,
idx
,
total_len
=
0
;
unsigned
int
i
,
last
,
idx
,
total_len
=
0
,
sgt_len
;
u32
*
buf
=
(
u32
*
)
&
pp
->
prd_buf
;
u32
*
buf
=
(
u32
*
)
&
pp
->
dimm_buf
[
PDC_DIMM_HEADER_SZ
]
;
VPRINTK
(
"ata%u: ENTER
\n
"
,
ap
->
id
);
/*
/*
* Build S/G table
* Build S/G table
*/
*/
...
@@ -522,28 +596,66 @@ static void pdc20621_fill_sg(struct ata_queued_cmd *qc)
...
@@ -522,28 +596,66 @@ static void pdc20621_fill_sg(struct ata_queued_cmd *qc)
buf
[
idx
++
]
=
cpu_to_le32
(
sg
[
i
].
length
);
buf
[
idx
++
]
=
cpu_to_le32
(
sg
[
i
].
length
);
total_len
+=
sg
[
i
].
length
;
total_len
+=
sg
[
i
].
length
;
}
}
idx
--
;
buf
[
idx
-
1
]
|=
cpu_to_le32
(
ATA_PRD_EOT
)
;
buf
[
idx
]
|=
cpu_to_le32
(
ATA_PRD_EOT
)
;
sgt_len
=
idx
*
4
;
/*
/*
* Build ATA, host DMA packets
* Build ATA, host DMA packets
*/
*/
i
=
pdc20621_pkt_header
(
&
qc
->
tf
,
portno
,
qc
->
dev
->
devno
,
pdc20621_host_sg
(
&
qc
->
tf
,
&
pp
->
dimm_buf
[
0
],
portno
,
total_len
);
&
pp
->
pkt_buf
[
0
],
total_len
);
pdc20621_host_pkt
(
&
qc
->
tf
,
&
pp
->
dimm_buf
[
0
],
portno
);
pdc20621_ata_sg
(
&
qc
->
tf
,
&
pp
->
dimm_buf
[
0
],
portno
,
total_len
);
i
=
pdc20621_ata_pkt
(
&
qc
->
tf
,
qc
->
dev
->
devno
,
&
pp
->
dimm_buf
[
0
],
portno
);
if
(
qc
->
tf
.
flags
&
ATA_TFLAG_LBA48
)
if
(
qc
->
tf
.
flags
&
ATA_TFLAG_LBA48
)
i
=
pdc_prep_lba48
(
&
qc
->
tf
,
&
pp
->
pkt
_buf
[
0
],
i
);
i
=
pdc_prep_lba48
(
&
qc
->
tf
,
&
pp
->
dimm
_buf
[
0
],
i
);
else
else
i
=
pdc_prep_lba28
(
&
qc
->
tf
,
&
pp
->
pkt
_buf
[
0
],
i
);
i
=
pdc_prep_lba28
(
&
qc
->
tf
,
&
pp
->
dimm
_buf
[
0
],
i
);
i
=
pdc_pkt_footer
(
&
qc
->
tf
,
&
pp
->
pkt
_buf
[
0
],
i
);
pdc_pkt_footer
(
&
qc
->
tf
,
&
pp
->
dimm
_buf
[
0
],
i
);
/* copy t
wo packets and three S/G table
s to DIMM MMIO window */
/* copy t
hree S/G tables and two packet
s to DIMM MMIO window */
memcpy_toio
(
dimm_mmio
+
(
portno
*
1024
),
&
pp
->
pkt_buf
,
i
);
memcpy_toio
(
dimm_mmio
+
(
portno
*
PDC_DIMM_WINDOW_STEP
),
memcpy_toio
(
dimm_mmio
+
(
4
*
1024
)
+
(
2
*
1024
*
portno
),
&
pp
->
dimm_buf
,
PDC_DIMM_HEADER_SZ
+
sgt_len
);
buf
,
idx
*
4
);
VPRINTK
(
"ata pkt buf ofs %u, prd size %u, mmio copied
\n
"
,
i
,
sgt_len
);
}
}
#ifdef DIRECT_HDMA
static
void
pdc20621_push_hdma
(
struct
ata_queued_cmd
*
qc
)
{
struct
ata_port
*
ap
=
qc
->
ap
;
struct
ata_host_set
*
host_set
=
ap
->
host_set
;
unsigned
int
port_no
=
ap
->
port_no
;
void
*
mmio
=
host_set
->
mmio_base
;
unsigned
int
rw
=
(
qc
->
flags
&
ATA_QCFLAG_WRITE
);
u32
tmp
;
unsigned
int
host_sg
=
PDC_20621_DIMM_BASE
+
(
PDC_DIMM_WINDOW_STEP
*
port_no
)
+
PDC_DIMM_HOST_PRD
;
unsigned
int
dimm_sg
=
PDC_20621_DIMM_BASE
+
(
PDC_DIMM_WINDOW_STEP
*
port_no
)
+
PDC_DIMM_HPKT_PRD
;
/* hard-code chip #0 */
mmio
+=
PDC_CHIP0_OFS
;
tmp
=
port_no
+
1
+
4
;
if
(
!
rw
)
tmp
|=
(
1
<<
6
);
writel
(
tmp
,
mmio
+
0x12C
);
readl
(
mmio
+
0x12C
);
/* flush */
writel
(
host_sg
,
mmio
+
0x108
);
writel
(
dimm_sg
,
mmio
+
0x10C
);
writel
(
0
,
mmio
+
0x128
);
tmp
|=
(
1
<<
7
);
writel
(
tmp
,
mmio
+
0x12C
);
readl
(
mmio
+
0x12C
);
/* flush */
}
#endif
static
void
pdc20621_dma_start
(
struct
ata_queued_cmd
*
qc
)
static
void
pdc20621_dma_start
(
struct
ata_queued_cmd
*
qc
)
{
{
struct
ata_port
*
ap
=
qc
->
ap
;
struct
ata_port
*
ap
=
qc
->
ap
;
...
@@ -552,32 +664,44 @@ static void pdc20621_dma_start(struct ata_queued_cmd *qc)
...
@@ -552,32 +664,44 @@ static void pdc20621_dma_start(struct ata_queued_cmd *qc)
void
*
mmio
=
host_set
->
mmio_base
;
void
*
mmio
=
host_set
->
mmio_base
;
unsigned
int
rw
=
(
qc
->
flags
&
ATA_QCFLAG_WRITE
);
unsigned
int
rw
=
(
qc
->
flags
&
ATA_QCFLAG_WRITE
);
u8
seq
=
(
u8
)
(
port_no
+
1
);
u8
seq
=
(
u8
)
(
port_no
+
1
);
u32
pkt_addr
;
unsigned
int
doing_hdma
=
0
,
port_ofs
;
unsigned
int
doing_hdma
=
0
;
/* hard-code chip #0 */
/* hard-code chip #0 */
mmio
+=
PDC_CHIP0_OFS
;
mmio
+=
PDC_CHIP0_OFS
;
VPRINTK
(
"ENTER, ap %p, mmio %p
\n
"
,
ap
,
mmio
);
VPRINTK
(
"ata%u: ENTER
\n
"
,
ap
->
id
);
port_ofs
=
PDC_20621_DIMM_BASE
+
(
PDC_DIMM_WINDOW_STEP
*
port_no
);
/* if writing, we (1) DMA to DIMM, then (2) do ATA command */
/* if writing, we (1) DMA to DIMM, then (2) do ATA command */
if
(
rw
)
{
if
(
rw
)
{
doing_hdma
=
1
;
doing_hdma
=
1
;
seq
+=
4
;
seq
+=
4
;
pkt_addr
=
PDC_20621_DIMM_BASE
+
(
4
*
port_no
);
}
/* if reading, we (1) do ATA command, then (2) DMA from DIMM */
else
{
pkt_addr
=
PDC_20621_DIMM_BASE
+
(
4
*
port_no
)
+
16
;
}
}
wmb
();
/* flush PRD, pkt writes */
wmb
();
/* flush PRD, pkt writes */
writel
(
0x00000001
,
mmio
+
PDC_20621_SEQCTL
+
(
seq
*
4
));
writel
(
0x00000001
,
mmio
+
PDC_20621_SEQCTL
+
(
seq
*
4
));
if
(
doing_hdma
)
writel
(
pkt_addr
,
mmio
+
PDC_HDMA_PKT_SUBMIT
);
if
(
doing_hdma
)
{
else
#ifdef DIRECT_HDMA
writel
(
pkt_addr
,
(
void
*
)
ap
->
ioaddr
.
cmd_addr
+
PDC_PKT_SUBMIT
);
pdc20621_push_hdma
(
qc
);
#else
writel
(
port_ofs
+
PDC_DIMM_HOST_PKT
,
mmio
+
PDC_HDMA_PKT_SUBMIT
);
#endif
VPRINTK
(
"submitted ofs 0x%x (%u), seq %u
\n
"
,
port_ofs
+
PDC_DIMM_HOST_PKT
,
port_ofs
+
PDC_DIMM_HOST_PKT
,
seq
);
}
else
{
writel
(
port_ofs
+
PDC_DIMM_ATA_PKT
,
(
void
*
)
ap
->
ioaddr
.
cmd_addr
+
PDC_PKT_SUBMIT
);
VPRINTK
(
"submitted ofs 0x%x (%u), seq %u
\n
"
,
port_ofs
+
PDC_DIMM_ATA_PKT
,
port_ofs
+
PDC_DIMM_ATA_PKT
,
seq
);
}
}
}
static
inline
unsigned
int
pdc20621_host_intr
(
struct
ata_port
*
ap
,
static
inline
unsigned
int
pdc20621_host_intr
(
struct
ata_port
*
ap
,
...
@@ -586,23 +710,36 @@ static inline unsigned int pdc20621_host_intr( struct ata_port *ap,
...
@@ -586,23 +710,36 @@ static inline unsigned int pdc20621_host_intr( struct ata_port *ap,
void
*
mmio
)
void
*
mmio
)
{
{
unsigned
int
port_no
=
ap
->
port_no
;
unsigned
int
port_no
=
ap
->
port_no
;
unsigned
int
port_ofs
=
PDC_20621_DIMM_BASE
+
(
PDC_DIMM_WINDOW_STEP
*
port_no
);
u8
status
;
u8
status
;
unsigned
int
handled
=
0
;
unsigned
int
handled
=
0
;
VPRINTK
(
"ENTER
\n
"
);
switch
(
qc
->
tf
.
protocol
)
{
switch
(
qc
->
tf
.
protocol
)
{
case
ATA_PROT_DMA_READ
:
case
ATA_PROT_DMA_READ
:
/* step two - DMA from DIMM to host */
/* step two - DMA from DIMM to host */
if
(
doing_hdma
)
if
(
doing_hdma
)
{
VPRINTK
(
"ata%u: read hdma, 0x%x 0x%x
\n
"
,
ap
->
id
,
readl
(
mmio
+
0x104
),
readl
(
mmio
+
0x12c
));
pdc_dma_complete
(
ap
,
qc
);
pdc_dma_complete
(
ap
,
qc
);
}
/* step one - exec ATA command */
/* step one - exec ATA command */
else
{
else
{
u32
pkt_addr
=
PDC_20621_DIMM_BASE
+
(
4
*
port_no
);
VPRINTK
(
"ata%u: read ata, 0x%x 0x%x
\n
"
,
ap
->
id
,
readl
(
mmio
+
0x104
),
readl
(
mmio
+
0x12c
));
u8
seq
=
(
u8
)
(
port_no
+
1
+
4
);
u8
seq
=
(
u8
)
(
port_no
+
1
+
4
);
/* submit hdma pkt */
/* submit hdma pkt */
writel
(
0x00000001
,
mmio
+
PDC_20621_SEQCTL
+
(
seq
*
4
));
writel
(
0x00000001
,
mmio
+
PDC_20621_SEQCTL
+
(
seq
*
4
));
writel
(
pkt_addr
,
mmio
+
PDC_HDMA_PKT_SUBMIT
);
#ifdef DIRECT_HDMA
pdc20621_push_hdma
(
qc
);
#else
writel
(
port_ofs
+
PDC_DIMM_HOST_PKT
,
mmio
+
PDC_HDMA_PKT_SUBMIT
);
#endif
}
}
handled
=
1
;
handled
=
1
;
break
;
break
;
...
@@ -610,16 +747,22 @@ static inline unsigned int pdc20621_host_intr( struct ata_port *ap,
...
@@ -610,16 +747,22 @@ static inline unsigned int pdc20621_host_intr( struct ata_port *ap,
case
ATA_PROT_DMA_WRITE
:
case
ATA_PROT_DMA_WRITE
:
/* step one - DMA from host to DIMM */
/* step one - DMA from host to DIMM */
if
(
doing_hdma
)
{
if
(
doing_hdma
)
{
u32
pkt_addr
=
PDC_20621_DIMM_BASE
+
(
4
*
port_no
)
+
16
;
VPRINTK
(
"ata%u: write hdma, 0x%x 0x%x
\n
"
,
ap
->
id
,
readl
(
mmio
+
0x104
),
readl
(
mmio
+
0x12c
));
u8
seq
=
(
u8
)
(
port_no
+
1
);
u8
seq
=
(
u8
)
(
port_no
+
1
);
/* submit ata pkt */
/* submit ata pkt */
writel
(
0x00000001
,
mmio
+
PDC_20621_SEQCTL
+
(
seq
*
4
));
writel
(
0x00000001
,
mmio
+
PDC_20621_SEQCTL
+
(
seq
*
4
));
writel
(
pkt_addr
,
(
void
*
)
writel
(
port_ofs
+
PDC_DIMM_ATA_PKT
,
ap
->
ioaddr
.
cmd_addr
+
PDC_PKT_SUBMIT
);
(
void
*
)
ap
->
ioaddr
.
cmd_addr
+
PDC_PKT_SUBMIT
);
}
/* step two - execute ATA command */
/* step two - execute ATA command */
}
else
else
{
VPRINTK
(
"ata%u: write ata, 0x%x 0x%x
\n
"
,
ap
->
id
,
readl
(
mmio
+
0x104
),
readl
(
mmio
+
0x12c
));
pdc_dma_complete
(
ap
,
qc
);
pdc_dma_complete
(
ap
,
qc
);
}
handled
=
1
;
handled
=
1
;
break
;
break
;
...
@@ -659,6 +802,7 @@ static irqreturn_t pdc20621_interrupt (int irq, void *dev_instance, struct pt_re
...
@@ -659,6 +802,7 @@ static irqreturn_t pdc20621_interrupt (int irq, void *dev_instance, struct pt_re
/* reading should also clear interrupts */
/* reading should also clear interrupts */
mmio_base
+=
PDC_CHIP0_OFS
;
mmio_base
+=
PDC_CHIP0_OFS
;
mask
=
readl
(
mmio_base
+
PDC_20621_SEQMASK
);
mask
=
readl
(
mmio_base
+
PDC_20621_SEQMASK
);
VPRINTK
(
"mask == 0x%x
\n
"
,
mask
);
if
(
mask
==
0xffffffff
)
{
if
(
mask
==
0xffffffff
)
{
VPRINTK
(
"QUICK EXIT 2
\n
"
);
VPRINTK
(
"QUICK EXIT 2
\n
"
);
...
@@ -673,7 +817,6 @@ static irqreturn_t pdc20621_interrupt (int irq, void *dev_instance, struct pt_re
...
@@ -673,7 +817,6 @@ static irqreturn_t pdc20621_interrupt (int irq, void *dev_instance, struct pt_re
spin_lock_irq
(
&
host_set
->
lock
);
spin_lock_irq
(
&
host_set
->
lock
);
for
(
i
=
1
;
i
<
9
;
i
++
)
{
for
(
i
=
1
;
i
<
9
;
i
++
)
{
VPRINTK
(
"port %u
\n
"
,
port_no
);
port_no
=
i
-
1
;
port_no
=
i
-
1
;
if
(
port_no
>
3
)
if
(
port_no
>
3
)
port_no
-=
4
;
port_no
-=
4
;
...
@@ -682,6 +825,7 @@ static irqreturn_t pdc20621_interrupt (int irq, void *dev_instance, struct pt_re
...
@@ -682,6 +825,7 @@ static irqreturn_t pdc20621_interrupt (int irq, void *dev_instance, struct pt_re
else
else
ap
=
host_set
->
ports
[
port_no
];
ap
=
host_set
->
ports
[
port_no
];
tmp
=
mask
&
(
1
<<
i
);
tmp
=
mask
&
(
1
<<
i
);
VPRINTK
(
"seq %u, port_no %u, ap %p, tmp %x
\n
"
,
i
,
port_no
,
ap
,
tmp
);
if
(
tmp
&&
ap
&&
(
!
(
ap
->
flags
&
ATA_FLAG_PORT_DISABLED
)))
{
if
(
tmp
&&
ap
&&
(
!
(
ap
->
flags
&
ATA_FLAG_PORT_DISABLED
)))
{
struct
ata_queued_cmd
*
qc
;
struct
ata_queued_cmd
*
qc
;
...
@@ -694,6 +838,8 @@ static irqreturn_t pdc20621_interrupt (int irq, void *dev_instance, struct pt_re
...
@@ -694,6 +838,8 @@ static irqreturn_t pdc20621_interrupt (int irq, void *dev_instance, struct pt_re
spin_unlock_irq
(
&
host_set
->
lock
);
spin_unlock_irq
(
&
host_set
->
lock
);
VPRINTK
(
"mask == 0x%x
\n
"
,
mask
);
VPRINTK
(
"EXIT
\n
"
);
VPRINTK
(
"EXIT
\n
"
);
return
IRQ_RETVAL
(
handled
);
return
IRQ_RETVAL
(
handled
);
...
@@ -704,6 +850,8 @@ static void pdc_fill_sg(struct ata_queued_cmd *qc)
...
@@ -704,6 +850,8 @@ static void pdc_fill_sg(struct ata_queued_cmd *qc)
struct
pdc_port_priv
*
pp
=
qc
->
ap
->
private_data
;
struct
pdc_port_priv
*
pp
=
qc
->
ap
->
private_data
;
unsigned
int
i
;
unsigned
int
i
;
VPRINTK
(
"ENTER
\n
"
);
ata_fill_sg
(
qc
);
ata_fill_sg
(
qc
);
i
=
pdc_pkt_header
(
&
qc
->
tf
,
qc
->
ap
->
prd_dma
,
qc
->
dev
->
devno
,
pp
->
pkt
);
i
=
pdc_pkt_header
(
&
qc
->
tf
,
qc
->
ap
->
prd_dma
,
qc
->
dev
->
devno
,
pp
->
pkt
);
...
@@ -906,6 +1054,10 @@ static void pdc_20621_init(struct ata_probe_ent *pe)
...
@@ -906,6 +1054,10 @@ static void pdc_20621_init(struct ata_probe_ent *pe)
tmp
=
readl
(
mmio
+
PDC_20621_DIMM_WINDOW
)
&
0xffff0000
;
tmp
=
readl
(
mmio
+
PDC_20621_DIMM_WINDOW
)
&
0xffff0000
;
tmp
|=
0x40
;
/* page 40h; arbitrarily selected */
tmp
|=
0x40
;
/* page 40h; arbitrarily selected */
writel
(
tmp
,
mmio
+
PDC_20621_DIMM_WINDOW
);
writel
(
tmp
,
mmio
+
PDC_20621_DIMM_WINDOW
);
writel
(
(
1
<<
11
),
mmio
+
0x12C
);
udelay
(
10
);
writel
(
0
,
mmio
+
0x12C
);
}
}
static
void
pdc_host_init
(
unsigned
int
chip_id
,
struct
ata_probe_ent
*
pe
)
static
void
pdc_host_init
(
unsigned
int
chip_id
,
struct
ata_probe_ent
*
pe
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment