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
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