Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
gsplhtlxg
clone-Linux
提交
67651ee5
C
clone-Linux
项目概览
gsplhtlxg
/
clone-Linux
通知
2
Star
0
Fork
1
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
C
clone-Linux
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
67651ee5
编写于
4月 08, 2009
作者:
J
Jeff Garzik
提交者:
Jeff Garzik
5月 15, 2009
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
[libata] sata_sx4: convert to new exception handling methods
Signed-off-by:
N
Jeff Garzik
<
jgarzik@redhat.com
>
上级
5d41343a
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
121 addition
and
45 deletion
+121
-45
drivers/ata/sata_sx4.c
drivers/ata/sata_sx4.c
+121
-45
未找到文件。
drivers/ata/sata_sx4.c
浏览文件 @
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
)
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录