Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
L
linux-davinci-2.6.23
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
linux
linux-davinci-2.6.23
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