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
526975bd
Commit
526975bd
authored
Oct 21, 2003
by
Jeff Garzik
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[libata] convert Promise to packetized DMA
parent
8bf6845b
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
102 additions
and
44 deletions
+102
-44
drivers/scsi/sata_promise.c
drivers/scsi/sata_promise.c
+102
-44
No files found.
drivers/scsi/sata_promise.c
View file @
526975bd
...
@@ -34,12 +34,13 @@
...
@@ -34,12 +34,13 @@
#include <linux/libata.h>
#include <linux/libata.h>
#define DRV_NAME "sata_promise"
#define DRV_NAME "sata_promise"
#define DRV_VERSION "0.8
3
"
#define DRV_VERSION "0.8
4
"
enum
{
enum
{
PDC_PRD_TBL
=
0x44
,
/* Direct command DMA table addr */
PDC_PRD_TBL
=
0x44
,
/* Direct command DMA table addr */
PDC_PKT_SUBMIT
=
0x40
,
/* Command packet pointer addr */
PDC_INT_SEQMASK
=
0x40
,
/* Mask of asserted SEQ INTs */
PDC_INT_SEQMASK
=
0x40
,
/* Mask of asserted SEQ INTs */
PDC_TBG_MODE
=
0x41
,
/* TBG mode */
PDC_TBG_MODE
=
0x41
,
/* TBG mode */
PDC_FLASH_CTL
=
0x44
,
/* Flash control register */
PDC_FLASH_CTL
=
0x44
,
/* Flash control register */
...
@@ -59,6 +60,12 @@ enum {
...
@@ -59,6 +60,12 @@ enum {
};
};
struct
pdc_port_priv
{
u8
*
pkt
;
dma_addr_t
pkt_dma
;
};
static
u32
pdc_sata_scr_read
(
struct
ata_port
*
ap
,
unsigned
int
sc_reg
);
static
u32
pdc_sata_scr_read
(
struct
ata_port
*
ap
,
unsigned
int
sc_reg
);
static
void
pdc_sata_scr_write
(
struct
ata_port
*
ap
,
unsigned
int
sc_reg
,
u32
val
);
static
void
pdc_sata_scr_write
(
struct
ata_port
*
ap
,
unsigned
int
sc_reg
,
u32
val
);
static
void
pdc_sata_set_piomode
(
struct
ata_port
*
ap
,
struct
ata_device
*
adev
,
static
void
pdc_sata_set_piomode
(
struct
ata_port
*
ap
,
struct
ata_device
*
adev
,
...
@@ -70,6 +77,11 @@ static void pdc_dma_start(struct ata_queued_cmd *qc);
...
@@ -70,6 +77,11 @@ static void pdc_dma_start(struct ata_queued_cmd *qc);
static
irqreturn_t
pdc_interrupt
(
int
irq
,
void
*
dev_instance
,
struct
pt_regs
*
regs
);
static
irqreturn_t
pdc_interrupt
(
int
irq
,
void
*
dev_instance
,
struct
pt_regs
*
regs
);
static
void
pdc_eng_timeout
(
struct
ata_port
*
ap
);
static
void
pdc_eng_timeout
(
struct
ata_port
*
ap
);
static
void
pdc_20621_phy_reset
(
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
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
Scsi_Host_Template
pdc_sata_sht
=
{
static
Scsi_Host_Template
pdc_sata_sht
=
{
...
@@ -93,38 +105,38 @@ static struct ata_port_operations pdc_sata_ops = {
...
@@ -93,38 +105,38 @@ static struct ata_port_operations pdc_sata_ops = {
.
port_disable
=
ata_port_disable
,
.
port_disable
=
ata_port_disable
,
.
set_piomode
=
pdc_sata_set_piomode
,
.
set_piomode
=
pdc_sata_set_piomode
,
.
set_udmamode
=
pdc_sata_set_udmamode
,
.
set_udmamode
=
pdc_sata_set_udmamode
,
.
tf_load
=
ata
_tf_load_mmio
,
.
tf_load
=
pdc
_tf_load_mmio
,
.
tf_read
=
ata_tf_read_mmio
,
.
tf_read
=
ata_tf_read_mmio
,
.
check_status
=
ata_check_status_mmio
,
.
check_status
=
ata_check_status_mmio
,
.
exec_command
=
ata
_exec_command_mmio
,
.
exec_command
=
pdc
_exec_command_mmio
,
.
phy_reset
=
sata_phy_reset
,
.
phy_reset
=
sata_phy_reset
,
.
phy_config
=
pata_phy_config
,
/* not a typo */
.
phy_config
=
pata_phy_config
,
/* not a typo */
.
bmdma_start
=
pdc_dma_start
,
.
bmdma_start
=
pdc_dma_start
,
.
fill_sg
=
ata
_fill_sg
,
.
fill_sg
=
pdc
_fill_sg
,
.
eng_timeout
=
pdc_eng_timeout
,
.
eng_timeout
=
pdc_eng_timeout
,
.
irq_handler
=
pdc_interrupt
,
.
irq_handler
=
pdc_interrupt
,
.
scr_read
=
pdc_sata_scr_read
,
.
scr_read
=
pdc_sata_scr_read
,
.
scr_write
=
pdc_sata_scr_write
,
.
scr_write
=
pdc_sata_scr_write
,
.
port_start
=
ata
_port_start
,
.
port_start
=
pdc
_port_start
,
.
port_stop
=
ata
_port_stop
,
.
port_stop
=
pdc
_port_stop
,
};
};
static
struct
ata_port_operations
pdc_20621_ops
=
{
static
struct
ata_port_operations
pdc_20621_ops
=
{
.
port_disable
=
ata_port_disable
,
.
port_disable
=
ata_port_disable
,
.
set_piomode
=
pdc_sata_set_piomode
,
.
set_piomode
=
pdc_sata_set_piomode
,
.
set_udmamode
=
pdc_sata_set_udmamode
,
.
set_udmamode
=
pdc_sata_set_udmamode
,
.
tf_load
=
ata
_tf_load_mmio
,
.
tf_load
=
pdc
_tf_load_mmio
,
.
tf_read
=
ata_tf_read_mmio
,
.
tf_read
=
ata_tf_read_mmio
,
.
check_status
=
ata_check_status_mmio
,
.
check_status
=
ata_check_status_mmio
,
.
exec_command
=
ata
_exec_command_mmio
,
.
exec_command
=
pdc
_exec_command_mmio
,
.
phy_reset
=
pdc_20621_phy_reset
,
.
phy_reset
=
pdc_20621_phy_reset
,
.
phy_config
=
pata_phy_config
,
/* not a typo */
.
phy_config
=
pata_phy_config
,
/* not a typo */
.
bmdma_start
=
pdc_dma_start
,
.
bmdma_start
=
pdc_dma_start
,
.
fill_sg
=
ata
_fill_sg
,
.
fill_sg
=
pdc
_fill_sg
,
.
eng_timeout
=
pdc_eng_timeout
,
.
eng_timeout
=
pdc_eng_timeout
,
.
irq_handler
=
pdc_interrupt
,
.
irq_handler
=
pdc_interrupt
,
.
port_start
=
ata
_port_start
,
.
port_start
=
pdc
_port_start
,
.
port_stop
=
ata
_port_stop
,
.
port_stop
=
pdc
_port_stop
,
};
};
static
struct
ata_port_info
pdc_port_info
[]
=
{
static
struct
ata_port_info
pdc_port_info
[]
=
{
...
@@ -186,6 +198,52 @@ static struct pci_driver pdc_sata_pci_driver = {
...
@@ -186,6 +198,52 @@ static struct pci_driver pdc_sata_pci_driver = {
};
};
static
int
pdc_port_start
(
struct
ata_port
*
ap
)
{
struct
pci_dev
*
pdev
=
ap
->
host_set
->
pdev
;
struct
pdc_port_priv
*
pp
;
int
rc
;
rc
=
ata_port_start
(
ap
);
if
(
rc
)
return
rc
;
pp
=
kmalloc
(
sizeof
(
*
pp
),
GFP_KERNEL
);
if
(
!
pp
)
{
rc
=
-
ENOMEM
;
goto
err_out
;
}
pp
->
pkt
=
pci_alloc_consistent
(
pdev
,
128
,
&
pp
->
pkt_dma
);
if
(
!
pp
->
pkt
)
{
rc
=
-
ENOMEM
;
goto
err_out_kfree
;
}
ap
->
private_data
=
pp
;
return
0
;
err_out_kfree:
kfree
(
pp
);
err_out:
ata_port_stop
(
ap
);
return
rc
;
}
static
void
pdc_port_stop
(
struct
ata_port
*
ap
)
{
struct
pci_dev
*
pdev
=
ap
->
host_set
->
pdev
;
struct
pdc_port_priv
*
pp
=
ap
->
private_data
;
ap
->
private_data
=
NULL
;
pci_free_consistent
(
pdev
,
128
,
pp
->
pkt
,
pp
->
pkt_dma
);
kfree
(
pp
);
ata_port_stop
(
ap
);
}
static
void
pdc_20621_phy_reset
(
struct
ata_port
*
ap
)
static
void
pdc_20621_phy_reset
(
struct
ata_port
*
ap
)
{
{
VPRINTK
(
"ENTER
\n
"
);
VPRINTK
(
"ENTER
\n
"
);
...
@@ -357,6 +415,19 @@ static void pdc_prep_lba48(struct ata_taskfile *tf, dma_addr_t sg_table,
...
@@ -357,6 +415,19 @@ static void pdc_prep_lba48(struct ata_taskfile *tf, dma_addr_t sg_table,
pdc_pkt_footer
(
tf
,
buf
,
i
);
pdc_pkt_footer
(
tf
,
buf
,
i
);
}
}
static
void
pdc_fill_sg
(
struct
ata_queued_cmd
*
qc
)
{
struct
pdc_port_priv
*
pp
=
qc
->
ap
->
private_data
;
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
);
else
pdc_prep_lba28
(
&
qc
->
tf
,
qc
->
ap
->
prd_dma
,
qc
->
dev
->
devno
,
pp
->
pkt
);
}
static
inline
void
__pdc_dma_complete
(
struct
ata_port
*
ap
,
static
inline
void
__pdc_dma_complete
(
struct
ata_port
*
ap
,
struct
ata_queued_cmd
*
qc
)
struct
ata_queued_cmd
*
qc
)
{
{
...
@@ -524,56 +595,43 @@ static irqreturn_t pdc_interrupt (int irq, void *dev_instance, struct pt_regs *r
...
@@ -524,56 +595,43 @@ static irqreturn_t pdc_interrupt (int irq, void *dev_instance, struct pt_regs *r
static
void
pdc_dma_start
(
struct
ata_queued_cmd
*
qc
)
static
void
pdc_dma_start
(
struct
ata_queued_cmd
*
qc
)
{
{
struct
ata_port
*
ap
=
qc
->
ap
;
struct
ata_port
*
ap
=
qc
->
ap
;
struct
pdc_port_priv
*
pp
=
ap
->
private_data
;
struct
ata_host_set
*
host_set
=
ap
->
host_set
;
struct
ata_host_set
*
host_set
=
ap
->
host_set
;
unsigned
int
port_no
=
ap
->
port_no
;
unsigned
int
port_no
=
ap
->
port_no
;
void
*
mmio
=
host_set
->
mmio_base
;
void
*
mmio
=
host_set
->
mmio_base
;
void
*
dmactl
=
(
void
*
)
ap
->
ioaddr
.
cmd_addr
+
PDC_CTLSTAT
;
unsigned
int
rw
=
(
qc
->
flags
&
ATA_QCFLAG_WRITE
);
u32
val
;
u8
seq
=
(
u8
)
(
port_no
+
1
);
u8
seq
=
(
u8
)
(
port_no
+
1
);
wmb
();
/* flush writes made to PRD table in DMA memory */
if
(
ap
->
flags
&
PDC_FLAG_20621
)
if
(
ap
->
flags
&
PDC_FLAG_20621
)
mmio
+=
PDC_CHIP0_OFS
;
mmio
+=
PDC_CHIP0_OFS
;
VPRINTK
(
"ENTER, ap %p, mmio %p
\n
"
,
ap
,
mmio
);
VPRINTK
(
"ENTER, ap %p, mmio %p
\n
"
,
ap
,
mmio
);
/* indicate where our S/G table is to chip */
writel
(
ap
->
prd_dma
,
(
void
*
)
ap
->
ioaddr
.
cmd_addr
+
PDC_PRD_TBL
);
/* clear dma start bit (paranoia), clear intr seq id (paranoia),
* set DMA direction (bit 6 == from chip -> drive)
*/
val
=
readl
(
dmactl
);
VPRINTK
(
"val == %x
\n
"
,
val
);
val
&=
~
(
1
<<
7
);
/* clear dma start/stop bit */
if
(
rw
)
/* set/clear dma direction bit */
val
|=
(
1
<<
6
);
else
val
&=
~
(
1
<<
6
);
if
(
qc
->
tf
.
ctl
&
ATA_NIEN
)
/* set/clear irq-mask bit */
val
|=
(
1
<<
10
);
else
val
&=
~
(
1
<<
10
);
writel
(
val
,
dmactl
);
val
=
readl
(
dmactl
);
VPRINTK
(
"val == %x
\n
"
,
val
);
/* FIXME: clear any intr status bits here? */
ata_exec_command_mmio
(
ap
,
&
qc
->
tf
);
VPRINTK
(
"FIVE
\n
"
);
if
(
ap
->
flags
&
PDC_FLAG_20621
)
if
(
ap
->
flags
&
PDC_FLAG_20621
)
writel
(
0x00000001
,
mmio
+
PDC_20621_SEQCTL
+
(
seq
*
4
));
writel
(
0x00000001
,
mmio
+
PDC_20621_SEQCTL
+
(
seq
*
4
));
else
else
writel
(
0x00000001
,
mmio
+
(
seq
*
4
));
writel
(
0x00000001
,
mmio
+
(
seq
*
4
));
/* start host DMA transaction */
pp
->
pkt
[
2
]
=
seq
;
writel
(
val
|
seq
|
(
1
<<
7
),
dmactl
);
wmb
();
/* flush PRD, pkt writes */
writel
(
pp
->
pkt_dma
,
(
void
*
)
ap
->
ioaddr
.
cmd_addr
+
PDC_PKT_SUBMIT
);
}
}
static
void
pdc_tf_load_mmio
(
struct
ata_port
*
ap
,
struct
ata_taskfile
*
tf
)
{
if
((
tf
->
protocol
!=
ATA_PROT_DMA_READ
)
&&
(
tf
->
protocol
!=
ATA_PROT_DMA_WRITE
))
ata_tf_load_mmio
(
ap
,
tf
);
}
static
void
pdc_exec_command_mmio
(
struct
ata_port
*
ap
,
struct
ata_taskfile
*
tf
)
{
if
((
tf
->
protocol
!=
ATA_PROT_DMA_READ
)
&&
(
tf
->
protocol
!=
ATA_PROT_DMA_WRITE
))
ata_exec_command_mmio
(
ap
,
tf
);
}
static
void
pdc_sata_setup_port
(
struct
ata_ioports
*
port
,
unsigned
long
base
)
static
void
pdc_sata_setup_port
(
struct
ata_ioports
*
port
,
unsigned
long
base
)
{
{
port
->
cmd_addr
=
base
;
port
->
cmd_addr
=
base
;
...
...
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