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
60293731
Commit
60293731
authored
Apr 25, 2004
by
Jeff Garzik
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[libata] move PIO data xfer from katad thread to workqueue thread
parent
68c9a6a2
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
87 additions
and
69 deletions
+87
-69
drivers/scsi/libata-core.c
drivers/scsi/libata-core.c
+72
-62
include/linux/libata.h
include/linux/libata.h
+15
-7
No files found.
drivers/scsi/libata-core.c
View file @
60293731
...
...
@@ -73,12 +73,6 @@ static const char * thr_state_name[] = {
"THR_IDLE"
,
"THR_PROBE_SUCCESS"
,
"THR_PROBE_START"
,
"THR_PIO_POLL"
,
"THR_PIO_TMOUT"
,
"THR_PIO"
,
"THR_PIO_LAST"
,
"THR_PIO_LAST_POLL"
,
"THR_PIO_ERR"
,
};
/**
...
...
@@ -1997,20 +1991,20 @@ static int ata_sg_setup(struct ata_queued_cmd *qc)
static
unsigned
long
ata_pio_poll
(
struct
ata_port
*
ap
)
{
u8
status
;
unsigned
int
poll_state
=
THR
_UNKNOWN
;
unsigned
int
reg_state
=
THR
_UNKNOWN
;
const
unsigned
int
tmout_state
=
THR_PIO
_TMOUT
;
switch
(
ap
->
thr
_state
)
{
case
THR_PIO
:
case
THR_PIO
_POLL
:
poll_state
=
THR_PIO
_POLL
;
reg_state
=
THR_PIO
;
unsigned
int
poll_state
=
PIO_ST
_UNKNOWN
;
unsigned
int
reg_state
=
PIO_ST
_UNKNOWN
;
const
unsigned
int
tmout_state
=
PIO_ST
_TMOUT
;
switch
(
ap
->
pio_task
_state
)
{
case
PIO_ST
:
case
PIO_ST
_POLL
:
poll_state
=
PIO_ST
_POLL
;
reg_state
=
PIO_ST
;
break
;
case
THR_PIO
_LAST
:
case
THR_PIO
_LAST_POLL
:
poll_state
=
THR_PIO
_LAST_POLL
;
reg_state
=
THR_PIO
_LAST
;
case
PIO_ST
_LAST
:
case
PIO_ST
_LAST_POLL
:
poll_state
=
PIO_ST
_LAST_POLL
;
reg_state
=
PIO_ST
_LAST
;
break
;
default:
BUG
();
...
...
@@ -2019,15 +2013,15 @@ static unsigned long ata_pio_poll(struct ata_port *ap)
status
=
ata_chk_status
(
ap
);
if
(
status
&
ATA_BUSY
)
{
if
(
time_after
(
jiffies
,
ap
->
thr
_timeout
))
{
ap
->
thr
_state
=
tmout_state
;
if
(
time_after
(
jiffies
,
ap
->
pio_task
_timeout
))
{
ap
->
pio_task
_state
=
tmout_state
;
return
0
;
}
ap
->
thr
_state
=
poll_state
;
ap
->
pio_task
_state
=
poll_state
;
return
ATA_SHORT_PAUSE
;
}
ap
->
thr
_state
=
reg_state
;
ap
->
pio_task
_state
=
reg_state
;
return
0
;
}
...
...
@@ -2048,7 +2042,7 @@ static void ata_pio_start (struct ata_queued_cmd *qc)
qc
->
flags
|=
ATA_QCFLAG_POLL
;
qc
->
tf
.
ctl
|=
ATA_NIEN
;
/* disable interrupts */
ata_tf_to_host_nolock
(
ap
,
&
qc
->
tf
);
ata_thread_wake
(
ap
,
THR_PIO
);
queue_work
(
ata_wq
,
&
ap
->
pio_task
);
}
/**
...
...
@@ -2061,7 +2055,6 @@ static void ata_pio_start (struct ata_queued_cmd *qc)
static
void
ata_pio_complete
(
struct
ata_port
*
ap
)
{
struct
ata_queued_cmd
*
qc
;
unsigned
long
flags
;
u8
drv_stat
;
/*
...
...
@@ -2070,31 +2063,29 @@ static void ata_pio_complete (struct ata_port *ap)
* a chk-status or two. If not, the drive is probably seeking
* or something. Snooze for a couple msecs, then
* chk-status again. If still busy, fall back to
*
THR_PIO
_POLL state.
*
PIO_ST
_POLL state.
*/
drv_stat
=
ata_busy_wait
(
ap
,
ATA_BUSY
|
ATA_DRQ
,
10
);
if
(
drv_stat
&
(
ATA_BUSY
|
ATA_DRQ
))
{
msleep
(
2
);
drv_stat
=
ata_busy_wait
(
ap
,
ATA_BUSY
|
ATA_DRQ
,
10
);
if
(
drv_stat
&
(
ATA_BUSY
|
ATA_DRQ
))
{
ap
->
thr_state
=
THR_PIO
_LAST_POLL
;
ap
->
thr
_timeout
=
jiffies
+
ATA_TMOUT_PIO
;
ap
->
pio_task_state
=
PIO_ST
_LAST_POLL
;
ap
->
pio_task
_timeout
=
jiffies
+
ATA_TMOUT_PIO
;
return
;
}
}
drv_stat
=
ata_wait_idle
(
ap
);
if
(
drv_stat
&
(
ATA_BUSY
|
ATA_DRQ
))
{
ap
->
thr_state
=
THR_PIO
_ERR
;
ap
->
pio_task_state
=
PIO_ST
_ERR
;
return
;
}
qc
=
ata_qc_from_tag
(
ap
,
ap
->
active_tag
);
assert
(
qc
!=
NULL
);
spin_lock_irqsave
(
&
ap
->
host_set
->
lock
,
flags
);
ap
->
thr_state
=
THR_IDLE
;
spin_unlock_irqrestore
(
&
ap
->
host_set
->
lock
,
flags
);
ap
->
pio_task_state
=
PIO_ST_IDLE
;
ata_irq_on
(
ap
);
...
...
@@ -2122,22 +2113,22 @@ static void ata_pio_sector(struct ata_port *ap)
* a chk-status or two. If not, the drive is probably seeking
* or something. Snooze for a couple msecs, then
* chk-status again. If still busy, fall back to
*
THR_PIO
_POLL state.
*
PIO_ST
_POLL state.
*/
status
=
ata_busy_wait
(
ap
,
ATA_BUSY
,
5
);
if
(
status
&
ATA_BUSY
)
{
msleep
(
2
);
status
=
ata_busy_wait
(
ap
,
ATA_BUSY
,
10
);
if
(
status
&
ATA_BUSY
)
{
ap
->
thr_state
=
THR_PIO
_POLL
;
ap
->
thr
_timeout
=
jiffies
+
ATA_TMOUT_PIO
;
ap
->
pio_task_state
=
PIO_ST
_POLL
;
ap
->
pio_task
_timeout
=
jiffies
+
ATA_TMOUT_PIO
;
return
;
}
}
/* handle BSY=0, DRQ=0 as error */
if
((
status
&
ATA_DRQ
)
==
0
)
{
ap
->
thr_state
=
THR_PIO
_ERR
;
ap
->
pio_task_state
=
PIO_ST
_ERR
;
return
;
}
...
...
@@ -2148,7 +2139,7 @@ static void ata_pio_sector(struct ata_port *ap)
sg
=
qc
->
sg
;
if
(
qc
->
cursect
==
(
qc
->
nsect
-
1
))
ap
->
thr_state
=
THR_PIO
_LAST
;
ap
->
pio_task_state
=
PIO_ST
_LAST
;
buf
=
kmap
(
sg
[
qc
->
cursg
].
page
)
+
sg
[
qc
->
cursg
].
offset
+
(
qc
->
cursg_ofs
*
ATA_SECT_SIZE
);
...
...
@@ -2176,6 +2167,49 @@ static void ata_pio_sector(struct ata_port *ap)
kunmap
(
sg
[
qc
->
cursg
].
page
);
}
static
void
ata_pio_task
(
void
*
_data
)
{
struct
ata_port
*
ap
=
_data
;
unsigned
long
timeout
=
0
;
switch
(
ap
->
pio_task_state
)
{
case
PIO_ST
:
ata_pio_sector
(
ap
);
break
;
case
PIO_ST_LAST
:
ata_pio_complete
(
ap
);
break
;
case
PIO_ST_POLL
:
case
PIO_ST_LAST_POLL
:
timeout
=
ata_pio_poll
(
ap
);
break
;
case
PIO_ST_TMOUT
:
printk
(
KERN_ERR
"ata%d: FIXME: PIO_ST_TMOUT
\n
"
,
/* FIXME */
ap
->
id
);
timeout
=
11
*
HZ
;
break
;
case
PIO_ST_ERR
:
printk
(
KERN_ERR
"ata%d: FIXME: PIO_ST_ERR
\n
"
,
/* FIXME */
ap
->
id
);
timeout
=
11
*
HZ
;
break
;
}
if
(
timeout
)
{
set_current_state
(
TASK_UNINTERRUPTIBLE
);
schedule_timeout
(
timeout
);
}
if
((
ap
->
pio_task_state
!=
PIO_ST_IDLE
)
&&
(
ap
->
pio_task_state
!=
PIO_ST_TMOUT
)
&&
(
ap
->
pio_task_state
!=
PIO_ST_ERR
))
queue_work
(
ata_wq
,
&
ap
->
pio_task
);
}
/**
* ata_eng_timeout - Handle timeout of queued command
* @ap: Port on which timed-out command is active
...
...
@@ -2760,31 +2794,6 @@ static unsigned long ata_thread_iter(struct ata_port *ap)
timeout
=
30
*
HZ
;
break
;
case
THR_PIO
:
ata_pio_sector
(
ap
);
break
;
case
THR_PIO_LAST
:
ata_pio_complete
(
ap
);
break
;
case
THR_PIO_POLL
:
case
THR_PIO_LAST_POLL
:
timeout
=
ata_pio_poll
(
ap
);
break
;
case
THR_PIO_TMOUT
:
printk
(
KERN_ERR
"ata%d: FIXME: THR_PIO_TMOUT
\n
"
,
/* FIXME */
ap
->
id
);
timeout
=
11
*
HZ
;
break
;
case
THR_PIO_ERR
:
printk
(
KERN_ERR
"ata%d: FIXME: THR_PIO_ERR
\n
"
,
/* FIXME */
ap
->
id
);
timeout
=
11
*
HZ
;
break
;
default:
printk
(
KERN_DEBUG
"ata%u: unknown thr state %s
\n
"
,
ap
->
id
,
ata_thr_state_name
(
ap
->
thr_state
));
...
...
@@ -3029,6 +3038,7 @@ static void ata_host_init(struct ata_port *ap, struct Scsi_Host *host,
ap
->
eng
.
flags
=
0
;
INIT_LIST_HEAD
(
&
ap
->
eng
.
q
);
INIT_WORK
(
&
ap
->
packet_task
,
atapi_packet_task
,
ap
);
INIT_WORK
(
&
ap
->
pio_task
,
ata_pio_task
,
ap
);
for
(
i
=
0
;
i
<
ATA_MAX_DEVICES
;
i
++
)
ap
->
device
[
i
].
devno
=
i
;
...
...
include/linux/libata.h
View file @
60293731
...
...
@@ -145,12 +145,6 @@ enum {
THR_IDLE
=
(
THR_PROBE_FAILED
+
1
),
THR_PROBE_SUCCESS
=
(
THR_IDLE
+
1
),
THR_PROBE_START
=
(
THR_PROBE_SUCCESS
+
1
),
THR_PIO_POLL
=
(
THR_PROBE_START
+
1
),
THR_PIO_TMOUT
=
(
THR_PIO_POLL
+
1
),
THR_PIO
=
(
THR_PIO_TMOUT
+
1
),
THR_PIO_LAST
=
(
THR_PIO
+
1
),
THR_PIO_LAST_POLL
=
(
THR_PIO_LAST
+
1
),
THR_PIO_ERR
=
(
THR_PIO_LAST_POLL
+
1
),
/* SATA port states */
PORT_UNKNOWN
=
0
,
...
...
@@ -163,6 +157,17 @@ enum {
ATA_QCFLAG_TIMEOUT
=
(
1
<<
0
),
};
enum
pio_task_states
{
PIO_ST_UNKNOWN
,
PIO_ST_IDLE
,
PIO_ST_POLL
,
PIO_ST_TMOUT
,
PIO_ST
,
PIO_ST_LAST
,
PIO_ST_LAST_POLL
,
PIO_ST_ERR
,
};
/* forward declarations */
struct
scsi_device
;
struct
ata_port_operations
;
...
...
@@ -315,10 +320,13 @@ struct ata_port {
struct
completion
thr_exited
;
struct
semaphore
thr_sem
;
struct
timer_list
thr_timer
;
unsigned
long
thr_timeout
;
struct
work_struct
packet_task
;
struct
work_struct
pio_task
;
unsigned
int
pio_task_state
;
unsigned
long
pio_task_timeout
;
void
*
private_data
;
};
...
...
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