Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
L
linux-elphel
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Commits
Open sidebar
Elphel
linux-elphel
Commits
65b5b0e1
Commit
65b5b0e1
authored
Jan 03, 2017
by
Mikhail Karpenko
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Update locking for queue pointers
parent
0564ebaf
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
25 additions
and
10 deletions
+25
-10
ahci_elphel.c
src/drivers/ata/ahci_elphel.c
+23
-9
ahci_elphel.h
src/drivers/ata/ahci_elphel.h
+2
-1
No files found.
src/drivers/ata/ahci_elphel.c
View file @
65b5b0e1
...
@@ -1185,22 +1185,31 @@ static void finish_rec(struct elphel_ahci_priv *dpriv)
...
@@ -1185,22 +1185,31 @@ static void finish_rec(struct elphel_ahci_priv *dpriv)
/** Move a pointer to free command slot one step forward. This function holds spin lock #elphel_ahci_priv::flags_lock */
/** Move a pointer to free command slot one step forward. This function holds spin lock #elphel_ahci_priv::flags_lock */
static
int
move_tail
(
struct
elphel_ahci_priv
*
dpriv
)
static
int
move_tail
(
struct
elphel_ahci_priv
*
dpriv
)
{
{
int
ret
;
unsigned
long
irq_flags
;
size_t
slot
=
(
dpriv
->
tail_ptr
+
1
)
%
MAX_CMD_SLOTS
;
size_t
slot
=
(
dpriv
->
tail_ptr
+
1
)
%
MAX_CMD_SLOTS
;
spin_lock_irqsave
(
&
dpriv
->
flags_lock
,
irq_flags
);
if
(
slot
!=
dpriv
->
head_ptr
)
{
if
(
slot
!=
dpriv
->
head_ptr
)
{
set_flag
(
dpriv
,
LOCK_TAIL
)
;
dpriv
->
flags
|=
LOCK_TAIL
;
dpriv
->
tail_ptr
=
slot
;
dpriv
->
tail_ptr
=
slot
;
dev_dbg
(
dpriv
->
dev
,
"move tail pointer to slot: %u
\n
"
,
slot
);
ret
=
0
;
return
0
;
}
else
{
}
else
{
/* no more free command slots */
/* no more free command slots */
ret
urn
-
1
;
ret
=
-
1
;
}
}
spin_unlock_irqrestore
(
&
dpriv
->
flags_lock
,
irq_flags
);
if
(
ret
==
0
)
dev_dbg
(
dpriv
->
dev
,
"move tail pointer to slot: %u
\n
"
,
slot
);
return
ret
;
}
}
/** Move a pointer to next ready command. This function holds spin lock #elphel_ahci_priv::flags_lock*/
/** Move a pointer to next ready command. This function holds spin lock #elphel_ahci_priv::flags_lock*/
static
int
move_head
(
struct
elphel_ahci_priv
*
dpriv
)
static
int
move_head
(
struct
elphel_ahci_priv
*
dpriv
)
{
{
int
ret
;
size_t
use_tail
;
size_t
use_tail
;
unsigned
long
irq_flags
;
unsigned
long
irq_flags
;
size_t
slot
=
(
dpriv
->
head_ptr
+
1
)
%
MAX_CMD_SLOTS
;
size_t
slot
=
(
dpriv
->
head_ptr
+
1
)
%
MAX_CMD_SLOTS
;
...
@@ -1212,17 +1221,19 @@ static int move_head(struct elphel_ahci_priv *dpriv)
...
@@ -1212,17 +1221,19 @@ static int move_head(struct elphel_ahci_priv *dpriv)
}
else
{
}
else
{
use_tail
=
dpriv
->
tail_ptr
;
use_tail
=
dpriv
->
tail_ptr
;
}
}
spin_unlock_irqrestore
(
&
dpriv
->
flags_lock
,
irq_flags
);
if
(
dpriv
->
head_ptr
!=
use_tail
)
{
if
(
dpriv
->
head_ptr
!=
use_tail
)
{
dpriv
->
head_ptr
=
slot
;
dpriv
->
head_ptr
=
slot
;
dev_dbg
(
dpriv
->
dev
,
"move head pointer to slot: %u
\n
"
,
slot
);
ret
=
0
;
return
0
;
}
else
{
}
else
{
/* no more commands in queue */
/* no more commands in queue */
ret
urn
-
1
;
ret
=
-
1
;
}
}
spin_unlock_irqrestore
(
&
dpriv
->
flags_lock
,
irq_flags
);
if
(
ret
==
0
)
dev_dbg
(
dpriv
->
dev
,
"move head pointer to slot: %u
\n
"
,
slot
);
return
ret
;
}
}
/** Check if command queue is empty */
/** Check if command queue is empty */
...
@@ -1382,6 +1393,7 @@ static ssize_t rawdev_write(struct device *dev, ///< device structure associate
...
@@ -1382,6 +1393,7 @@ static ssize_t rawdev_write(struct device *dev, ///< device structure associate
}
else
{
}
else
{
dpriv
->
flags
|=
DELAYED_FINISH
;
dpriv
->
flags
|=
DELAYED_FINISH
;
}
}
dpriv
->
datascope
.
reg_stat
[
CMD_RCVD
]
=
dpriv
->
datascope
.
reg_stat
[
CMD_RCVD
]
+
1
;
return
buff_sz
;
return
buff_sz
;
}
}
...
@@ -1440,6 +1452,8 @@ static ssize_t rawdev_write(struct device *dev, ///< device structure associate
...
@@ -1440,6 +1452,8 @@ static ssize_t rawdev_write(struct device *dev, ///< device structure associate
/* new command slot is ready now and can be unlocked */
/* new command slot is ready now and can be unlocked */
reset_flag
(
dpriv
,
LOCK_TAIL
);
reset_flag
(
dpriv
,
LOCK_TAIL
);
dpriv
->
datascope
.
reg_stat
[
CMD_RCVD
]
=
dpriv
->
datascope
.
reg_stat
[
CMD_RCVD
]
+
1
;
if
(
!
proceed
)
{
if
(
!
proceed
)
{
/* disk may be free by the moment, try to grab it */
/* disk may be free by the moment, try to grab it */
spin_lock_irqsave
(
&
dpriv
->
flags_lock
,
irq_flags
);
spin_lock_irqsave
(
&
dpriv
->
flags_lock
,
irq_flags
);
...
...
src/drivers/ata/ahci_elphel.h
View file @
65b5b0e1
...
@@ -83,7 +83,8 @@ enum {
...
@@ -83,7 +83,8 @@ enum {
REG_PxSERR
,
///< value of PxSERR in data buffer
REG_PxSERR
,
///< value of PxSERR in data buffer
IRQ_COUNTER
,
///< interrupts counter for internal commands
IRQ_COUNTER
,
///< interrupts counter for internal commands
IRQ_COUNTER_SYS
,
///< interrupts counter for system commands
IRQ_COUNTER_SYS
,
///< interrupts counter for system commands
CMD_SENT
///< number of commands sent
CMD_SENT
,
///< number of commands sent
CMD_RCVD
///< number of commands received
};
};
struct
datascope
{
struct
datascope
{
void
__iomem
*
timestamp_reg
;
///< register in vendor specific address range (PxVS) where timestamp can be written
void
__iomem
*
timestamp_reg
;
///< register in vendor specific address range (PxVS) where timestamp can be written
...
...
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