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
67651ee5
Commit
67651ee5
authored
Apr 08, 2009
by
Jeff Garzik
Committed by
Jeff Garzik
May 15, 2009
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[libata] sata_sx4: convert to new exception handling methods
Signed-off-by:
Jeff Garzik
<
jgarzik@redhat.com
>
parent
5d41343a
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
121 additions
and
45 deletions
+121
-45
drivers/ata/sata_sx4.c
drivers/ata/sata_sx4.c
+121
-45
No files found.
drivers/ata/sata_sx4.c
View file @
67651ee5
...
...
@@ -213,8 +213,9 @@ struct pdc_host_priv {
static
int
pdc_sata_init_one
(
struct
pci_dev
*
pdev
,
const
struct
pci_device_id
*
ent
);
static
void
pdc_eng_timeout
(
struct
ata_port
*
ap
);
static
void
pdc_20621_phy_reset
(
struct
ata_port
*
ap
);
static
void
pdc_error_handler
(
struct
ata_port
*
ap
);
static
void
pdc_freeze
(
struct
ata_port
*
ap
);
static
void
pdc_thaw
(
struct
ata_port
*
ap
);
static
int
pdc_port_start
(
struct
ata_port
*
ap
);
static
void
pdc20621_qc_prep
(
struct
ata_queued_cmd
*
qc
);
static
void
pdc_tf_load_mmio
(
struct
ata_port
*
ap
,
const
struct
ata_taskfile
*
tf
);
...
...
@@ -233,6 +234,10 @@ static void pdc20621_put_to_dimm(struct ata_host *host,
void
*
psource
,
u32
offset
,
u32
size
);
static
void
pdc20621_irq_clear
(
struct
ata_port
*
ap
);
static
unsigned
int
pdc20621_qc_issue
(
struct
ata_queued_cmd
*
qc
);
static
int
pdc_softreset
(
struct
ata_link
*
link
,
unsigned
int
*
class
,
unsigned
long
deadline
);
static
void
pdc_post_internal_cmd
(
struct
ata_queued_cmd
*
qc
);
static
int
pdc_check_atapi_dma
(
struct
ata_queued_cmd
*
qc
);
static
struct
scsi_host_template
pdc_sata_sht
=
{
...
...
@@ -243,20 +248,24 @@ static struct scsi_host_template pdc_sata_sht = {
/* TODO: inherit from base port_ops after converting to new EH */
static
struct
ata_port_operations
pdc_20621_ops
=
{
.
sff_tf_load
=
pdc_tf_load_mmio
,
.
sff_tf_read
=
ata_sff_tf_read
,
.
sff_check_status
=
ata_sff_check_status
,
.
sff_exec_command
=
pdc_exec_command_mmio
,
.
sff_dev_select
=
ata_sff_dev_select
,
.
phy_reset
=
pdc_20621_phy_reset
,
.
inherits
=
&
ata_sff_port_ops
,
.
check_atapi_dma
=
pdc_check_atapi_dma
,
.
qc_prep
=
pdc20621_qc_prep
,
.
qc_issue
=
pdc20621_qc_issue
,
.
qc_fill_rtf
=
ata_sff_qc_fill_rtf
,
.
sff_data_xfer
=
ata_sff_data_xfer
,
.
eng_timeout
=
pdc_eng_timeout
,
.
sff_irq_clear
=
pdc20621_irq_clear
,
.
sff_irq_on
=
ata_sff_irq_on
,
.
freeze
=
pdc_freeze
,
.
thaw
=
pdc_thaw
,
.
softreset
=
pdc_softreset
,
.
error_handler
=
pdc_error_handler
,
.
lost_interrupt
=
ATA_OP_NULL
,
.
post_internal_cmd
=
pdc_post_internal_cmd
,
.
port_start
=
pdc_port_start
,
.
sff_tf_load
=
pdc_tf_load_mmio
,
.
sff_exec_command
=
pdc_exec_command_mmio
,
.
sff_irq_clear
=
pdc20621_irq_clear
,
};
static
const
struct
ata_port_info
pdc_port_info
[]
=
{
...
...
@@ -310,14 +319,6 @@ static int pdc_port_start(struct ata_port *ap)
return
0
;
}
static
void
pdc_20621_phy_reset
(
struct
ata_port
*
ap
)
{
VPRINTK
(
"ENTER
\n
"
);
ap
->
cbl
=
ATA_CBL_SATA
;
ata_port_probe
(
ap
);
ata_bus_reset
(
ap
);
}
static
inline
void
pdc20621_ata_sg
(
struct
ata_taskfile
*
tf
,
u8
*
buf
,
unsigned
int
portno
,
unsigned
int
total_len
)
...
...
@@ -859,40 +860,115 @@ static irqreturn_t pdc20621_interrupt(int irq, void *dev_instance)
return
IRQ_RETVAL
(
handled
);
}
static
void
pdc_
eng_timeout
(
struct
ata_port
*
ap
)
static
void
pdc_
freeze
(
struct
ata_port
*
ap
)
{
u8
drv_stat
;
struct
ata_host
*
host
=
ap
->
host
;
struct
ata_queued_cmd
*
qc
;
unsigned
long
flags
;
void
__iomem
*
mmio
=
ap
->
ioaddr
.
cmd_addr
;
u32
tmp
;
DPRINTK
(
"ENTER
\n
"
);
/* FIXME: if all 4 ATA engines are stopped, also stop HDMA engine */
spin_lock_irqsave
(
&
host
->
lock
,
flags
);
tmp
=
readl
(
mmio
+
PDC_CTLSTAT
);
tmp
|=
PDC_MASK_INT
;
tmp
&=
~
PDC_DMA_ENABLE
;
writel
(
tmp
,
mmio
+
PDC_CTLSTAT
);
readl
(
mmio
+
PDC_CTLSTAT
);
/* flush */
}
qc
=
ata_qc_from_tag
(
ap
,
ap
->
link
.
active_tag
);
static
void
pdc_thaw
(
struct
ata_port
*
ap
)
{
void
__iomem
*
mmio
=
ap
->
ioaddr
.
cmd_addr
;
void
__iomem
*
mmio_base
;
u32
tmp
;
switch
(
qc
->
tf
.
protocol
)
{
case
ATA_PROT_DMA
:
case
ATA_PROT_NODATA
:
ata_port_printk
(
ap
,
KERN_ERR
,
"command timeout
\n
"
);
qc
->
err_mask
|=
__ac_err_mask
(
ata_wait_idle
(
ap
));
break
;
/* FIXME: start HDMA engine, if zero ATA engines running */
default:
drv_stat
=
ata_sff_busy_wait
(
ap
,
ATA_BUSY
|
ATA_DRQ
,
1000
);
/* reading SEQ mask register clears IRQ */
mmio_base
=
ap
->
host
->
iomap
[
PDC_MMIO_BAR
]
+
PDC_CHIP0_OFS
;
readl
(
mmio_base
+
PDC_20621_SEQMASK
);
ata_port_printk
(
ap
,
KERN_ERR
,
"unknown timeout, cmd 0x%x stat 0x%x
\n
"
,
qc
->
tf
.
command
,
drv_stat
);
/* turn IRQ back on */
tmp
=
readl
(
mmio
+
PDC_CTLSTAT
);
tmp
&=
~
PDC_MASK_INT
;
writel
(
tmp
,
mmio
+
PDC_CTLSTAT
);
readl
(
mmio
+
PDC_CTLSTAT
);
/* flush */
}
qc
->
err_mask
|=
ac_err_mask
(
drv_stat
);
break
;
static
void
pdc_reset_port
(
struct
ata_port
*
ap
)
{
void
__iomem
*
mmio
=
ap
->
ioaddr
.
cmd_addr
+
PDC_CTLSTAT
;
unsigned
int
i
;
u32
tmp
;
/* FIXME: handle HDMA copy engine */
for
(
i
=
11
;
i
>
0
;
i
--
)
{
tmp
=
readl
(
mmio
);
if
(
tmp
&
PDC_RESET
)
break
;
udelay
(
100
);
tmp
|=
PDC_RESET
;
writel
(
tmp
,
mmio
);
}
spin_unlock_irqrestore
(
&
host
->
lock
,
flags
);
ata_eh_qc_complete
(
qc
);
DPRINTK
(
"EXIT
\n
"
);
tmp
&=
~
PDC_RESET
;
writel
(
tmp
,
mmio
);
readl
(
mmio
);
/* flush */
}
static
int
pdc_softreset
(
struct
ata_link
*
link
,
unsigned
int
*
class
,
unsigned
long
deadline
)
{
pdc_reset_port
(
link
->
ap
);
return
ata_sff_softreset
(
link
,
class
,
deadline
);
}
static
void
pdc_error_handler
(
struct
ata_port
*
ap
)
{
if
(
!
(
ap
->
pflags
&
ATA_PFLAG_FROZEN
))
pdc_reset_port
(
ap
);
ata_std_error_handler
(
ap
);
}
static
void
pdc_post_internal_cmd
(
struct
ata_queued_cmd
*
qc
)
{
struct
ata_port
*
ap
=
qc
->
ap
;
/* make DMA engine forget about the failed command */
if
(
qc
->
flags
&
ATA_QCFLAG_FAILED
)
pdc_reset_port
(
ap
);
}
static
int
pdc_check_atapi_dma
(
struct
ata_queued_cmd
*
qc
)
{
u8
*
scsicmd
=
qc
->
scsicmd
->
cmnd
;
int
pio
=
1
;
/* atapi dma off by default */
/* Whitelist commands that may use DMA. */
switch
(
scsicmd
[
0
])
{
case
WRITE_12
:
case
WRITE_10
:
case
WRITE_6
:
case
READ_12
:
case
READ_10
:
case
READ_6
:
case
0xad
:
/* READ_DVD_STRUCTURE */
case
0xbe
:
/* READ_CD */
pio
=
0
;
}
/* -45150 (FFFF4FA2) to -1 (FFFFFFFF) shall use PIO mode */
if
(
scsicmd
[
0
]
==
WRITE_10
)
{
unsigned
int
lba
=
(
scsicmd
[
2
]
<<
24
)
|
(
scsicmd
[
3
]
<<
16
)
|
(
scsicmd
[
4
]
<<
8
)
|
scsicmd
[
5
];
if
(
lba
>=
0xFFFF4FA2
)
pio
=
1
;
}
return
pio
;
}
static
void
pdc_tf_load_mmio
(
struct
ata_port
*
ap
,
const
struct
ata_taskfile
*
tf
)
...
...
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