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
9be16a03
Commit
9be16a03
authored
Oct 28, 2005
by
Linus Torvalds
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'sx8' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/misc-2.6
parents
5fadd053
cb650116
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
37 additions
and
14 deletions
+37
-14
drivers/block/sx8.c
drivers/block/sx8.c
+37
-14
No files found.
drivers/block/sx8.c
View file @
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
))
{
...
...
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