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
nexedi
linux
Commits
23700c6b
Commit
23700c6b
authored
Oct 22, 2003
by
Jeff Garzik
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[libata] fill in a lot more Promise PDC20621 support
parent
402ba7d3
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
346 additions
and
80 deletions
+346
-80
drivers/scsi/sata_promise.c
drivers/scsi/sata_promise.c
+346
-80
No files found.
drivers/scsi/sata_promise.c
View file @
23700c6b
...
...
@@ -41,6 +41,7 @@ enum {
PDC_PRD_TBL
=
0x44
,
/* Direct command DMA table addr */
PDC_PKT_SUBMIT
=
0x40
,
/* Command packet pointer addr */
PDC_HDMA_PKT_SUBMIT
=
0x100
,
/* Host DMA packet pointer addr */
PDC_INT_SEQMASK
=
0x40
,
/* Mask of asserted SEQ INTs */
PDC_TBG_MODE
=
0x41
,
/* TBG mode */
PDC_FLASH_CTL
=
0x44
,
/* Flash control register */
...
...
@@ -50,6 +51,12 @@ enum {
PDC_20621_SEQCTL
=
0x400
,
PDC_20621_SEQMASK
=
0x480
,
/* chosen, not constant, values; we design our own DIMM mem map */
PDC_20621_DIMM_WINDOW
=
0x0C
,
/* page# for 32K DIMM window */
PDC_20621_DIMM_BASE
=
0x00200000
,
PDC_20621_HOST_PRD
=
64
,
PDC_20621_ATA_PRD
=
72
,
PDC_CHIP0_OFS
=
0xC0000
,
/* offset of chip #0 */
board_2037x
=
0
,
/* FastTrak S150 TX2plus */
...
...
@@ -61,6 +68,8 @@ enum {
struct
pdc_port_priv
{
u8
prd_buf
[
ATA_PRD_SZ
*
ATA_MAX_PRD
];
u8
pkt_buf
[
256
];
u8
*
pkt
;
dma_addr_t
pkt_dma
;
};
...
...
@@ -74,14 +83,20 @@ static void pdc_sata_set_udmamode (struct ata_port *ap, struct ata_device *adev,
unsigned
int
udma
);
static
int
pdc_sata_init_one
(
struct
pci_dev
*
pdev
,
const
struct
pci_device_id
*
ent
);
static
void
pdc_dma_start
(
struct
ata_queued_cmd
*
qc
);
static
void
pdc20621_dma_start
(
struct
ata_queued_cmd
*
qc
);
static
irqreturn_t
pdc_interrupt
(
int
irq
,
void
*
dev_instance
,
struct
pt_regs
*
regs
);
static
irqreturn_t
pdc20621_interrupt
(
int
irq
,
void
*
dev_instance
,
struct
pt_regs
*
regs
);
static
void
pdc_eng_timeout
(
struct
ata_port
*
ap
);
static
void
pdc_20621_phy_reset
(
struct
ata_port
*
ap
);
static
int
pdc_port_start
(
struct
ata_port
*
ap
);
static
void
pdc_port_stop
(
struct
ata_port
*
ap
);
static
void
pdc_fill_sg
(
struct
ata_queued_cmd
*
qc
);
static
void
pdc20621_fill_sg
(
struct
ata_queued_cmd
*
qc
);
static
void
pdc_tf_load_mmio
(
struct
ata_port
*
ap
,
struct
ata_taskfile
*
tf
);
static
void
pdc_exec_command_mmio
(
struct
ata_port
*
ap
,
struct
ata_taskfile
*
tf
);
static
void
pdc20621_host_stop
(
struct
ata_host_set
*
host_set
);
static
inline
void
pdc_dma_complete
(
struct
ata_port
*
ap
,
struct
ata_queued_cmd
*
qc
);
static
Scsi_Host_Template
pdc_sata_sht
=
{
...
...
@@ -131,12 +146,13 @@ static struct ata_port_operations pdc_20621_ops = {
.
exec_command
=
pdc_exec_command_mmio
,
.
phy_reset
=
pdc_20621_phy_reset
,
.
phy_config
=
pata_phy_config
,
/* not a typo */
.
bmdma_start
=
pdc_dma_start
,
.
fill_sg
=
pdc_fill_sg
,
.
bmdma_start
=
pdc
20621
_dma_start
,
.
fill_sg
=
pdc
20621
_fill_sg
,
.
eng_timeout
=
pdc_eng_timeout
,
.
irq_handler
=
pdc_interrupt
,
.
irq_handler
=
pdc
20621
_interrupt
,
.
port_start
=
pdc_port_start
,
.
port_stop
=
pdc_port_stop
,
.
host_stop
=
pdc20621_host_stop
,
};
static
struct
ata_port_info
pdc_port_info
[]
=
{
...
...
@@ -182,10 +198,8 @@ static struct pci_device_id pdc_sata_pci_tbl[] = {
board_20319
},
{
PCI_VENDOR_ID_PROMISE
,
0x3319
,
PCI_ANY_ID
,
PCI_ANY_ID
,
0
,
0
,
board_20319
},
#if 0 /* broken currently */
{
PCI_VENDOR_ID_PROMISE
,
0x6622
,
PCI_ANY_ID
,
PCI_ANY_ID
,
0
,
0
,
board_20621
},
#endif
{
}
/* terminate list */
};
...
...
@@ -198,6 +212,14 @@ static struct pci_driver pdc_sata_pci_driver = {
};
static
void
pdc20621_host_stop
(
struct
ata_host_set
*
host_set
)
{
void
*
mmio
=
host_set
->
private_data
;
assert
(
mmio
!=
NULL
);
iounmap
(
mmio
);
}
static
int
pdc_port_start
(
struct
ata_port
*
ap
)
{
struct
pci_dev
*
pdev
=
ap
->
host_set
->
pdev
;
...
...
@@ -284,6 +306,7 @@ static void pdc_sata_set_udmamode (struct ata_port *ap, struct ata_device *adev,
enum
pdc_packet_bits
{
PDC_PKT_READ
=
(
1
<<
2
),
PDC_PKT_NODATA
=
(
1
<<
3
),
PDC20621_PKT_READ
=
(
1
<<
4
),
PDC_PKT_SIZEMASK
=
(
1
<<
7
)
|
(
1
<<
6
)
|
(
1
<<
5
),
PDC_PKT_CLEAR_BSY
=
(
1
<<
4
),
...
...
@@ -293,8 +316,9 @@ enum pdc_packet_bits {
PDC_REG_DEVCTL
=
(
1
<<
3
)
|
(
1
<<
2
)
|
(
1
<<
1
),
};
static
inline
void
pdc_pkt_header
(
struct
ata_taskfile
*
tf
,
dma_addr_t
sg_table
,
unsigned
int
devno
,
u8
*
buf
)
static
inline
unsigned
int
pdc_pkt_header
(
struct
ata_taskfile
*
tf
,
dma_addr_t
sg_table
,
unsigned
int
devno
,
u8
*
buf
)
{
u8
dev_reg
;
u32
*
buf32
=
(
u32
*
)
buf
;
...
...
@@ -335,9 +359,11 @@ static inline void pdc_pkt_header(struct ata_taskfile *tf, dma_addr_t sg_table,
/* device control register */
buf
[
14
]
=
(
1
<<
5
)
|
PDC_REG_DEVCTL
;
buf
[
15
]
=
tf
->
ctl
;
return
16
;
/* offset of next byte */
}
static
inline
void
pdc_pkt_footer
(
struct
ata_taskfile
*
tf
,
u8
*
buf
,
static
inline
unsigned
int
pdc_pkt_footer
(
struct
ata_taskfile
*
tf
,
u8
*
buf
,
unsigned
int
i
)
{
if
(
tf
->
flags
&
ATA_TFLAG_DEVICE
)
{
...
...
@@ -348,19 +374,14 @@ static inline void pdc_pkt_footer(struct ata_taskfile *tf, u8 *buf,
/* and finally the command itself; also includes end-of-pkt marker */
buf
[
i
++
]
=
(
1
<<
5
)
|
PDC_LAST_REG
|
ATA_REG_CMD
;
buf
[
i
++
]
=
tf
->
command
;
return
i
;
}
static
void
pdc_prep_lba28
(
struct
ata_taskfile
*
tf
,
dma_addr_t
sg_table
,
unsigned
int
devno
,
u8
*
buf
)
static
inline
unsigned
int
pdc_prep_lba28
(
struct
ata_taskfile
*
tf
,
u8
*
buf
,
unsigned
int
i
)
{
unsigned
int
i
;
pdc_pkt_header
(
tf
,
sg_table
,
devno
,
buf
);
/* the "(1 << 5)" should be read "(count << 5)" */
i
=
16
;
/* ATA command block registers */
buf
[
i
++
]
=
(
1
<<
5
)
|
ATA_REG_FEATURE
;
buf
[
i
++
]
=
tf
->
feature
;
...
...
@@ -377,20 +398,13 @@ static void pdc_prep_lba28(struct ata_taskfile *tf, dma_addr_t sg_table,
buf
[
i
++
]
=
(
1
<<
5
)
|
ATA_REG_LBAH
;
buf
[
i
++
]
=
tf
->
lbah
;
pdc_pkt_footer
(
tf
,
buf
,
i
)
;
return
i
;
}
static
void
pdc_prep_lba48
(
struct
ata_taskfile
*
tf
,
dma_addr_t
sg_table
,
unsigned
int
devno
,
u8
*
buf
)
static
inline
unsigned
int
pdc_prep_lba48
(
struct
ata_taskfile
*
tf
,
u8
*
buf
,
unsigned
int
i
)
{
unsigned
int
i
;
pdc_pkt_header
(
tf
,
sg_table
,
devno
,
buf
);
/* the "(2 << 5)" should be read "(count << 5)" */
i
=
16
;
/* ATA command block registers */
buf
[
i
++
]
=
(
2
<<
5
)
|
ATA_REG_FEATURE
;
buf
[
i
++
]
=
tf
->
hob_feature
;
...
...
@@ -412,41 +426,299 @@ static void pdc_prep_lba48(struct ata_taskfile *tf, dma_addr_t sg_table,
buf
[
i
++
]
=
tf
->
hob_lbah
;
buf
[
i
++
]
=
tf
->
lbah
;
pdc_pkt_footer
(
tf
,
buf
,
i
)
;
return
i
;
}
static
void
pdc_fill_sg
(
struct
ata_queued_cmd
*
qc
)
static
inline
unsigned
int
pdc20621_pkt_header
(
struct
ata_taskfile
*
tf
,
unsigned
int
portno
,
unsigned
int
devno
,
u8
*
buf
,
unsigned
int
total_len
)
{
struct
pdc_port_priv
*
pp
=
qc
->
ap
->
private_data
;
u8
dev_reg
;
u32
*
buf32
=
(
u32
*
)
buf
;
unsigned
int
ofs
,
i
=
0
;
/*
* Set up Host DMA packet
*/
if
(
tf
->
protocol
==
ATA_PROT_DMA_READ
)
buf
[
i
++
]
=
PDC20621_PKT_READ
;
else
buf
[
i
++
]
=
0
;
buf
[
i
++
]
=
0
;
/* reserved */
buf
[
i
++
]
=
portno
+
1
+
4
;
/* seq. id */
buf
[
i
++
]
=
0xff
;
/* delay seq. id */
buf32
[
i
/
4
]
=
cpu_to_le32
(
PDC_20621_DIMM_BASE
+
(
4
*
1024
)
+
(
2
*
1024
*
portno
));
i
+=
4
;
buf32
[
i
/
4
]
=
cpu_to_le32
(
PDC_20621_DIMM_BASE
+
(
portno
*
1024
)
+
PDC_20621_HOST_PRD
);
i
+=
4
;
buf32
[
i
/
4
]
=
0
;
i
+=
4
;
ofs
=
PDC_20621_HOST_PRD
/
4
;
buf32
[
ofs
]
=
cpu_to_le32
(
PDC_20621_DIMM_BASE
+
(
32
*
1024
)
+
(
256
*
1024
*
portno
));
buf32
[
ofs
+
1
]
=
cpu_to_le32
(
total_len
|
ATA_PRD_EOT
);
/*
* Set up ATA packet
*/
if
(
tf
->
protocol
==
ATA_PROT_DMA_READ
)
buf
[
i
++
]
=
PDC_PKT_READ
;
else
if
(
tf
->
protocol
==
ATA_PROT_NODATA
)
buf
[
i
++
]
=
PDC_PKT_NODATA
;
else
buf
[
i
++
]
=
0
;
buf
[
i
++
]
=
0
;
/* reserved */
buf
[
i
++
]
=
portno
+
1
;
/* 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
;
buf32
[
ofs
]
=
cpu_to_le32
(
PDC_20621_DIMM_BASE
+
(
32
*
1024
)
+
(
256
*
1024
*
portno
));
buf32
[
ofs
+
1
]
=
cpu_to_le32
(
total_len
|
ATA_PRD_EOT
);
if
(
devno
==
0
)
dev_reg
=
ATA_DEVICE_OBS
;
else
dev_reg
=
ATA_DEVICE_OBS
|
ATA_DEV1
;
/* select device */
buf
[
i
++
]
=
(
1
<<
5
)
|
PDC_PKT_CLEAR_BSY
|
ATA_REG_DEVICE
;
buf
[
i
++
]
=
dev_reg
;
/* device control register */
buf
[
i
++
]
=
(
1
<<
5
)
|
PDC_REG_DEVCTL
;
buf
[
i
++
]
=
tf
->
ctl
;
return
i
;
/* offset of next byte */
}
static
void
pdc20621_fill_sg
(
struct
ata_queued_cmd
*
qc
)
{
struct
scatterlist
*
sg
=
qc
->
sg
;
struct
ata_port
*
ap
=
qc
->
ap
;
struct
pdc_port_priv
*
pp
=
ap
->
private_data
;
void
*
dimm_mmio
=
ap
->
host_set
->
private_data
;
unsigned
int
portno
=
ap
->
port_no
;
unsigned
int
i
,
last
,
idx
,
total_len
=
0
;
u32
*
buf
=
(
u32
*
)
&
pp
->
prd_buf
;
/*
* Build S/G table
*/
last
=
qc
->
n_elem
;
idx
=
0
;
for
(
i
=
0
;
i
<
last
;
i
++
)
{
buf
[
idx
++
]
=
cpu_to_le32
(
sg
[
i
].
dma_address
);
buf
[
idx
++
]
=
cpu_to_le32
(
sg
[
i
].
length
);
total_len
+=
sg
[
i
].
length
;
}
idx
--
;
buf
[
idx
]
|=
cpu_to_le32
(
ATA_PRD_EOT
);
/*
* Build ATA, host DMA packets
*/
i
=
pdc20621_pkt_header
(
&
qc
->
tf
,
portno
,
qc
->
dev
->
devno
,
&
pp
->
pkt_buf
[
0
],
total_len
);
ata_fill_sg
(
qc
);
if
(
qc
->
tf
.
flags
&
ATA_TFLAG_LBA48
)
pdc_prep_lba48
(
&
qc
->
tf
,
qc
->
ap
->
prd_dma
,
qc
->
dev
->
devno
,
pp
->
pkt
);
i
=
pdc_prep_lba48
(
&
qc
->
tf
,
&
pp
->
pkt_buf
[
0
],
i
);
else
pdc_prep_lba28
(
&
qc
->
tf
,
qc
->
ap
->
prd_dma
,
qc
->
dev
->
devno
,
pp
->
pkt
);
i
=
pdc_prep_lba28
(
&
qc
->
tf
,
&
pp
->
pkt_buf
[
0
],
i
);
i
=
pdc_pkt_footer
(
&
qc
->
tf
,
&
pp
->
pkt_buf
[
0
],
i
);
/* copy two packets and three S/G tables to DIMM MMIO window */
memcpy_toio
(
dimm_mmio
+
(
portno
*
1024
),
&
pp
->
pkt_buf
,
i
);
memcpy_toio
(
dimm_mmio
+
(
4
*
1024
)
+
(
2
*
1024
*
portno
),
buf
,
idx
*
4
);
}
static
void
pdc20621_dma_start
(
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
);
u8
seq
=
(
u8
)
(
port_no
+
1
);
u32
pkt_addr
;
unsigned
int
doing_hdma
=
0
;
/* hard-code chip #0 */
mmio
+=
PDC_CHIP0_OFS
;
VPRINTK
(
"ENTER, ap %p, mmio %p
\n
"
,
ap
,
mmio
);
/* if writing, we (1) DMA to DIMM, then (2) do ATA command */
if
(
rw
)
{
doing_hdma
=
1
;
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 */
writel
(
0x00000001
,
mmio
+
PDC_20621_SEQCTL
+
(
seq
*
4
));
if
(
doing_hdma
)
writel
(
pkt_addr
,
mmio
+
PDC_HDMA_PKT_SUBMIT
);
else
writel
(
pkt_addr
,
(
void
*
)
ap
->
ioaddr
.
cmd_addr
+
PDC_PKT_SUBMIT
);
}
static
inline
unsigned
int
pdc20621_host_intr
(
struct
ata_port
*
ap
,
struct
ata_queued_cmd
*
qc
,
unsigned
int
doing_hdma
,
void
*
mmio
)
{
unsigned
int
port_no
=
ap
->
port_no
;
u8
status
;
unsigned
int
handled
=
0
;
switch
(
qc
->
tf
.
protocol
)
{
case
ATA_PROT_DMA_READ
:
/* step two - DMA from DIMM to host */
if
(
doing_hdma
)
pdc_dma_complete
(
ap
,
qc
);
/* step one - exec ATA command */
else
{
u32
pkt_addr
=
PDC_20621_DIMM_BASE
+
(
4
*
port_no
);
u8
seq
=
(
u8
)
(
port_no
+
1
+
4
);
/* submit hdma pkt */
writel
(
0x00000001
,
mmio
+
PDC_20621_SEQCTL
+
(
seq
*
4
));
writel
(
pkt_addr
,
mmio
+
PDC_HDMA_PKT_SUBMIT
);
}
handled
=
1
;
break
;
case
ATA_PROT_DMA_WRITE
:
/* step one - DMA from host to DIMM */
if
(
doing_hdma
)
{
u32
pkt_addr
=
PDC_20621_DIMM_BASE
+
(
4
*
port_no
)
+
16
;
u8
seq
=
(
u8
)
(
port_no
+
1
);
/* submit ata pkt */
writel
(
0x00000001
,
mmio
+
PDC_20621_SEQCTL
+
(
seq
*
4
));
writel
(
pkt_addr
,
(
void
*
)
ap
->
ioaddr
.
cmd_addr
+
PDC_PKT_SUBMIT
);
/* step two - execute ATA command */
}
else
pdc_dma_complete
(
ap
,
qc
);
handled
=
1
;
break
;
case
ATA_PROT_NODATA
:
/* command completion, but no data xfer */
status
=
ata_busy_wait
(
ap
,
ATA_BUSY
|
ATA_DRQ
,
1000
);
DPRINTK
(
"BUS_NODATA (drv_stat 0x%X)
\n
"
,
status
);
ata_qc_complete
(
qc
,
status
,
0
);
handled
=
1
;
break
;
default:
ap
->
stats
.
idle_irq
++
;
break
;
}
return
handled
;
}
static
inline
void
__pdc_dma_complete
(
struct
ata_port
*
ap
,
struct
ata_queued_cmd
*
qc
)
static
irqreturn_t
pdc20621_interrupt
(
int
irq
,
void
*
dev_instance
,
struct
pt_regs
*
regs
)
{
void
*
dmactl
=
(
void
*
)
ap
->
ioaddr
.
cmd_addr
+
PDC_CTLSTAT
;
u32
val
;
struct
ata_host_set
*
host_set
=
dev_instance
;
struct
ata_port
*
ap
;
u32
mask
=
0
;
unsigned
int
i
,
tmp
,
port_no
;
unsigned
int
handled
=
0
;
void
*
mmio_base
;
VPRINTK
(
"ENTER
\n
"
);
if
(
!
host_set
||
!
host_set
->
mmio_base
)
{
VPRINTK
(
"QUICK EXIT
\n
"
);
return
IRQ_NONE
;
}
mmio_base
=
host_set
->
mmio_base
;
/* reading should also clear interrupts */
mmio_base
+=
PDC_CHIP0_OFS
;
mask
=
readl
(
mmio_base
+
PDC_20621_SEQMASK
);
if
(
mask
==
0xffffffff
)
{
VPRINTK
(
"QUICK EXIT 2
\n
"
);
return
IRQ_NONE
;
}
mask
&=
0xf
;
/* only 16 tags possible */
if
(
!
mask
)
{
VPRINTK
(
"QUICK EXIT 3
\n
"
);
return
IRQ_NONE
;
}
spin_lock_irq
(
&
host_set
->
lock
);
for
(
i
=
1
;
i
<
9
;
i
++
)
{
VPRINTK
(
"port %u
\n
"
,
port_no
);
port_no
=
i
-
1
;
if
(
port_no
>
3
)
port_no
-=
4
;
if
(
port_no
>=
host_set
->
n_ports
)
ap
=
NULL
;
else
ap
=
host_set
->
ports
[
port_no
];
tmp
=
mask
&
(
1
<<
i
);
if
(
tmp
&&
ap
&&
(
!
(
ap
->
flags
&
ATA_FLAG_PORT_DISABLED
)))
{
struct
ata_queued_cmd
*
qc
;
qc
=
ata_qc_from_tag
(
ap
,
ap
->
active_tag
);
if
(
qc
&&
((
qc
->
flags
&
ATA_QCFLAG_POLL
)
==
0
))
handled
+=
pdc20621_host_intr
(
ap
,
qc
,
(
i
>
4
),
mmio_base
);
}
}
/* clear DMA start/stop bit (bit 7) */
val
=
readl
(
dmactl
);
writel
(
val
&
~
(
1
<<
7
),
dmactl
);
spin_unlock_irq
(
&
host_set
->
lock
);
VPRINTK
(
"EXIT
\n
"
);
/* one-PIO-cycle guaranteed wait, per spec, for HDMA1:0 transition */
ata_altstatus
(
ap
);
/* dummy read */
return
IRQ_RETVAL
(
handled
);
}
static
void
pdc_fill_sg
(
struct
ata_queued_cmd
*
qc
)
{
struct
pdc_port_priv
*
pp
=
qc
->
ap
->
private_data
;
unsigned
int
i
;
ata_fill_sg
(
qc
);
i
=
pdc_pkt_header
(
&
qc
->
tf
,
qc
->
ap
->
prd_dma
,
qc
->
dev
->
devno
,
pp
->
pkt
);
if
(
qc
->
tf
.
flags
&
ATA_TFLAG_LBA48
)
i
=
pdc_prep_lba48
(
&
qc
->
tf
,
pp
->
pkt
,
i
);
else
i
=
pdc_prep_lba28
(
&
qc
->
tf
,
pp
->
pkt
,
i
);
pdc_pkt_footer
(
&
qc
->
tf
,
pp
->
pkt
,
i
);
}
static
inline
void
pdc_dma_complete
(
struct
ata_port
*
ap
,
struct
ata_queued_cmd
*
qc
)
{
__pdc_dma_complete
(
ap
,
qc
);
/* get drive status; clear intr; complete txn */
ata_qc_complete
(
ata_qc_from_tag
(
ap
,
ap
->
active_tag
),
ata_wait_idle
(
ap
),
0
);
...
...
@@ -470,7 +742,6 @@ static void pdc_eng_timeout(struct ata_port *ap)
case
ATA_PROT_DMA_READ
:
case
ATA_PROT_DMA_WRITE
:
printk
(
KERN_ERR
"ata%u: DMA timeout
\n
"
,
ap
->
id
);
__pdc_dma_complete
(
ap
,
qc
);
ata_qc_complete
(
ata_qc_from_tag
(
ap
,
ap
->
active_tag
),
ata_wait_idle
(
ap
)
|
ATA_ERR
,
0
);
break
;
...
...
@@ -532,7 +803,7 @@ static irqreturn_t pdc_interrupt (int irq, void *dev_instance, struct pt_regs *r
struct
ata_port
*
ap
;
u32
mask
=
0
;
unsigned
int
i
,
tmp
;
unsigned
int
handled
=
0
,
have_20621
=
0
;
unsigned
int
handled
=
0
;
void
*
mmio_base
;
VPRINTK
(
"ENTER
\n
"
);
...
...
@@ -544,21 +815,8 @@ static irqreturn_t pdc_interrupt (int irq, void *dev_instance, struct pt_regs *r
mmio_base
=
host_set
->
mmio_base
;
for
(
i
=
0
;
i
<
host_set
->
n_ports
;
i
++
)
{
ap
=
host_set
->
ports
[
i
];
if
(
ap
&&
(
ap
->
flags
&
PDC_FLAG_20621
))
{
have_20621
=
1
;
break
;
}
}
/* reading should also clear interrupts */
if
(
have_20621
)
{
mmio_base
+=
PDC_CHIP0_OFS
;
mask
=
readl
(
mmio_base
+
PDC_20621_SEQMASK
);
}
else
{
mask
=
readl
(
mmio_base
+
PDC_INT_SEQMASK
);
}
mask
=
readl
(
mmio_base
+
PDC_INT_SEQMASK
);
if
(
mask
==
0xffffffff
)
{
VPRINTK
(
"QUICK EXIT 2
\n
"
);
...
...
@@ -596,20 +854,12 @@ static void pdc_dma_start(struct ata_queued_cmd *qc)
{
struct
ata_port
*
ap
=
qc
->
ap
;
struct
pdc_port_priv
*
pp
=
ap
->
private_data
;
struct
ata_host_set
*
host_set
=
ap
->
host_set
;
unsigned
int
port_no
=
ap
->
port_no
;
void
*
mmio
=
host_set
->
mmio_base
;
u8
seq
=
(
u8
)
(
port_no
+
1
);
if
(
ap
->
flags
&
PDC_FLAG_20621
)
mmio
+=
PDC_CHIP0_OFS
;
VPRINTK
(
"ENTER, ap %p
\n
"
,
ap
);
VPRINTK
(
"ENTER, ap %p, mmio %p
\n
"
,
ap
,
mmio
);
if
(
ap
->
flags
&
PDC_FLAG_20621
)
writel
(
0x00000001
,
mmio
+
PDC_20621_SEQCTL
+
(
seq
*
4
));
else
writel
(
0x00000001
,
mmio
+
(
seq
*
4
));
writel
(
0x00000001
,
ap
->
host_set
->
mmio_base
+
(
seq
*
4
));
pp
->
pkt
[
2
]
=
seq
;
wmb
();
/* flush PRD, pkt writes */
...
...
@@ -648,6 +898,14 @@ static void pdc_sata_setup_port(struct ata_ioports *port, unsigned long base)
static
void
pdc_20621_init
(
struct
ata_probe_ent
*
pe
)
{
u32
tmp
;
void
*
mmio
=
pe
->
mmio_base
;
mmio
+=
PDC_CHIP0_OFS
;
tmp
=
readl
(
mmio
+
PDC_20621_DIMM_WINDOW
)
&
0xffff0000
;
tmp
|=
0x40
;
/* page 40h; arbitrarily selected */
writel
(
tmp
,
mmio
+
PDC_20621_DIMM_WINDOW
);
}
static
void
pdc_host_init
(
unsigned
int
chip_id
,
struct
ata_probe_ent
*
pe
)
...
...
@@ -691,8 +949,9 @@ static int pdc_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *
static
int
printed_version
;
struct
ata_probe_ent
*
probe_ent
=
NULL
;
unsigned
long
base
;
void
*
mmio_base
;
void
*
mmio_base
,
*
dimm_mmio
=
NULL
;
unsigned
int
board_idx
=
(
unsigned
int
)
ent
->
driver_data
;
unsigned
int
have_20621
=
(
board_idx
==
board_20621
);
int
rc
;
if
(
!
printed_version
++
)
...
...
@@ -732,6 +991,15 @@ static int pdc_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *
}
base
=
(
unsigned
long
)
mmio_base
;
if
(
have_20621
)
{
dimm_mmio
=
ioremap
(
pci_resource_start
(
pdev
,
4
),
pci_resource_len
(
pdev
,
4
));
if
(
!
dimm_mmio
)
{
rc
=
-
ENOMEM
;
goto
err_out_iounmap
;
}
}
probe_ent
->
sht
=
pdc_port_info
[
board_idx
].
sht
;
probe_ent
->
host_flags
=
pdc_port_info
[
board_idx
].
host_flags
;
probe_ent
->
pio_mask
=
pdc_port_info
[
board_idx
].
pio_mask
;
...
...
@@ -742,8 +1010,10 @@ static int pdc_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *
probe_ent
->
irq_flags
=
SA_SHIRQ
;
probe_ent
->
mmio_base
=
mmio_base
;
if
(
board_idx
==
board_20621
)
if
(
have_20621
)
{
probe_ent
->
private_data
=
dimm_mmio
;
base
+=
PDC_CHIP0_OFS
;
}
pdc_sata_setup_port
(
&
probe_ent
->
port
[
0
],
base
+
0x200
);
probe_ent
->
port
[
0
].
scr_addr
=
base
+
0x400
;
...
...
@@ -774,15 +1044,10 @@ static int pdc_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *
pci_set_master
(
pdev
);
/* initialize adapter */
switch
(
board_idx
)
{
case
board_20621
:
if
(
have_20621
)
pdc_20621_init
(
probe_ent
);
break
;
default:
else
pdc_host_init
(
board_idx
,
probe_ent
);
break
;
}
/* FIXME: check ata_device_add return value */
ata_device_add
(
probe_ent
);
...
...
@@ -790,6 +1055,8 @@ static int pdc_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *
return
0
;
err_out_iounmap:
iounmap
(
mmio_base
);
err_out_free_ent:
kfree
(
probe_ent
);
err_out_regions:
...
...
@@ -800,7 +1067,6 @@ static int pdc_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *
}
static
int
__init
pdc_sata_init
(
void
)
{
int
rc
;
...
...
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