Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
cloud-kernel
提交
9be16a03
cloud-kernel
项目概览
openanolis
/
cloud-kernel
1 年多 前同步成功
通知
160
Star
36
Fork
7
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
10
列表
看板
标记
里程碑
合并请求
2
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
cloud-kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
10
Issue
10
列表
看板
标记
里程碑
合并请求
2
合并请求
2
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
9be16a03
编写于
10月 28, 2005
作者:
L
Linus Torvalds
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'sx8' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/misc-2.6
上级
5fadd053
cb650116
变更
1
显示空白变更内容
内联
并排
Showing
1 changed file
with
37 addition
and
14 deletion
+37
-14
drivers/block/sx8.c
drivers/block/sx8.c
+37
-14
未找到文件。
drivers/block/sx8.c
浏览文件 @
9be16a03
/*
/*
* sx8.c: Driver for Promise SATA SX8 looks-like-I2O hardware
* sx8.c: Driver for Promise SATA SX8 looks-like-I2O hardware
*
*
* Copyright 2004 Red Hat, Inc.
* Copyright 2004
-2005
Red Hat, Inc.
*
*
* Author/maintainer: Jeff Garzik <jgarzik@pobox.com>
* Author/maintainer: Jeff Garzik <jgarzik@pobox.com>
*
*
...
@@ -31,10 +31,6 @@
...
@@ -31,10 +31,6 @@
#include <asm/semaphore.h>
#include <asm/semaphore.h>
#include <asm/uaccess.h>
#include <asm/uaccess.h>
MODULE_AUTHOR
(
"Jeff Garzik"
);
MODULE_LICENSE
(
"GPL"
);
MODULE_DESCRIPTION
(
"Promise SATA SX8 block driver"
);
#if 0
#if 0
#define CARM_DEBUG
#define CARM_DEBUG
#define CARM_VERBOSE_DEBUG
#define CARM_VERBOSE_DEBUG
...
@@ -45,9 +41,35 @@ MODULE_DESCRIPTION("Promise SATA SX8 block driver");
...
@@ -45,9 +41,35 @@ MODULE_DESCRIPTION("Promise SATA SX8 block driver");
#undef CARM_NDEBUG
#undef CARM_NDEBUG
#define DRV_NAME "sx8"
#define DRV_NAME "sx8"
#define DRV_VERSION "
0.8
"
#define DRV_VERSION "
1.0
"
#define PFX DRV_NAME ": "
#define PFX DRV_NAME ": "
MODULE_AUTHOR
(
"Jeff Garzik"
);
MODULE_LICENSE
(
"GPL"
);
MODULE_DESCRIPTION
(
"Promise SATA SX8 block driver"
);
MODULE_VERSION
(
DRV_VERSION
);
/*
* SX8 hardware has a single message queue for all ATA ports.
* When this driver was written, the hardware (firmware?) would
* corrupt data eventually, if more than one request was outstanding.
* As one can imagine, having 8 ports bottlenecking on a single
* command hurts performance.
*
* Based on user reports, later versions of the hardware (firmware?)
* seem to be able to survive with more than one command queued.
*
* Therefore, we default to the safe option -- 1 command -- but
* allow the user to increase this.
*
* SX8 should be able to support up to ~60 queued commands (CARM_MAX_REQ),
* but problems seem to occur when you exceed ~30, even on newer hardware.
*/
static
int
max_queue
=
1
;
module_param
(
max_queue
,
int
,
0444
);
MODULE_PARM_DESC
(
max_queue
,
"Maximum number of queued commands. (min==1, max==30, safe==1)"
);
#define NEXT_RESP(idx) ((idx + 1) % RMSG_Q_LEN)
#define NEXT_RESP(idx) ((idx + 1) % RMSG_Q_LEN)
/* 0xf is just arbitrary, non-zero noise; this is sorta like poisoning */
/* 0xf is just arbitrary, non-zero noise; this is sorta like poisoning */
...
@@ -90,12 +112,10 @@ enum {
...
@@ -90,12 +112,10 @@ enum {
/* command message queue limits */
/* command message queue limits */
CARM_MAX_REQ
=
64
,
/* max command msgs per host */
CARM_MAX_REQ
=
64
,
/* max command msgs per host */
CARM_MAX_Q
=
1
,
/* one command at a time */
CARM_MSG_LOW_WATER
=
(
CARM_MAX_REQ
/
4
),
/* refill mark */
CARM_MSG_LOW_WATER
=
(
CARM_MAX_REQ
/
4
),
/* refill mark */
/* S/G limits, host-wide and per-request */
/* S/G limits, host-wide and per-request */
CARM_MAX_REQ_SG
=
32
,
/* max s/g entries per request */
CARM_MAX_REQ_SG
=
32
,
/* max s/g entries per request */
CARM_SG_BOUNDARY
=
0xffffUL
,
/* s/g segment boundary */
CARM_MAX_HOST_SG
=
600
,
/* max s/g entries per host */
CARM_MAX_HOST_SG
=
600
,
/* max s/g entries per host */
CARM_SG_LOW_WATER
=
(
CARM_MAX_HOST_SG
/
4
),
/* re-fill mark */
CARM_SG_LOW_WATER
=
(
CARM_MAX_HOST_SG
/
4
),
/* re-fill mark */
...
@@ -181,6 +201,10 @@ enum {
...
@@ -181,6 +201,10 @@ enum {
FL_DYN_MAJOR
=
(
1
<<
17
),
FL_DYN_MAJOR
=
(
1
<<
17
),
};
};
enum
{
CARM_SG_BOUNDARY
=
0xffffUL
,
/* s/g segment boundary */
};
enum
scatter_gather_types
{
enum
scatter_gather_types
{
SGT_32BIT
=
0
,
SGT_32BIT
=
0
,
SGT_64BIT
=
1
,
SGT_64BIT
=
1
,
...
@@ -218,7 +242,6 @@ static const char *state_name[] = {
...
@@ -218,7 +242,6 @@ static const char *state_name[] = {
struct
carm_port
{
struct
carm_port
{
unsigned
int
port_no
;
unsigned
int
port_no
;
unsigned
int
n_queued
;
struct
gendisk
*
disk
;
struct
gendisk
*
disk
;
struct
carm_host
*
host
;
struct
carm_host
*
host
;
...
@@ -509,7 +532,7 @@ static struct carm_request *carm_get_request(struct carm_host *host)
...
@@ -509,7 +532,7 @@ static struct carm_request *carm_get_request(struct carm_host *host)
if
(
host
->
hw_sg_used
>=
(
CARM_MAX_HOST_SG
-
CARM_MAX_REQ_SG
))
if
(
host
->
hw_sg_used
>=
(
CARM_MAX_HOST_SG
-
CARM_MAX_REQ_SG
))
return
NULL
;
return
NULL
;
for
(
i
=
0
;
i
<
CARM_MAX_Q
;
i
++
)
for
(
i
=
0
;
i
<
max_queue
;
i
++
)
if
((
host
->
msg_alloc
&
(
1ULL
<<
i
))
==
0
)
{
if
((
host
->
msg_alloc
&
(
1ULL
<<
i
))
==
0
)
{
struct
carm_request
*
crq
=
&
host
->
req
[
i
];
struct
carm_request
*
crq
=
&
host
->
req
[
i
];
crq
->
port
=
NULL
;
crq
->
port
=
NULL
;
...
@@ -528,7 +551,7 @@ static struct carm_request *carm_get_request(struct carm_host *host)
...
@@ -528,7 +551,7 @@ static struct carm_request *carm_get_request(struct carm_host *host)
static
int
carm_put_request
(
struct
carm_host
*
host
,
struct
carm_request
*
crq
)
static
int
carm_put_request
(
struct
carm_host
*
host
,
struct
carm_request
*
crq
)
{
{
assert
(
crq
->
tag
<
CARM_MAX_Q
);
assert
(
crq
->
tag
<
max_queue
);
if
(
unlikely
((
host
->
msg_alloc
&
(
1ULL
<<
crq
->
tag
))
==
0
))
if
(
unlikely
((
host
->
msg_alloc
&
(
1ULL
<<
crq
->
tag
))
==
0
))
return
-
EINVAL
;
/* tried to clear a tag that was not active */
return
-
EINVAL
;
/* tried to clear a tag that was not active */
...
@@ -791,7 +814,7 @@ static inline void carm_end_rq(struct carm_host *host, struct carm_request *crq,
...
@@ -791,7 +814,7 @@ static inline void carm_end_rq(struct carm_host *host, struct carm_request *crq,
int
is_ok
)
int
is_ok
)
{
{
carm_end_request_queued
(
host
,
crq
,
is_ok
);
carm_end_request_queued
(
host
,
crq
,
is_ok
);
if
(
CARM_MAX_Q
==
1
)
if
(
max_queue
==
1
)
carm_round_robin
(
host
);
carm_round_robin
(
host
);
else
if
((
host
->
n_msgs
<=
CARM_MSG_LOW_WATER
)
&&
else
if
((
host
->
n_msgs
<=
CARM_MSG_LOW_WATER
)
&&
(
host
->
hw_sg_used
<=
CARM_SG_LOW_WATER
))
{
(
host
->
hw_sg_used
<=
CARM_SG_LOW_WATER
))
{
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录