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
d2435050
Commit
d2435050
authored
Apr 27, 2004
by
Greg Kroah-Hartman
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
USB: make ehci driver use a kref instead of an atomic_t
parent
cb71655f
Changes
5
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
34 additions
and
26 deletions
+34
-26
drivers/usb/host/ehci-hcd.c
drivers/usb/host/ehci-hcd.c
+1
-1
drivers/usb/host/ehci-mem.c
drivers/usb/host/ehci-mem.c
+23
-16
drivers/usb/host/ehci-q.c
drivers/usb/host/ehci-q.c
+5
-5
drivers/usb/host/ehci-sched.c
drivers/usb/host/ehci-sched.c
+3
-3
drivers/usb/host/ehci.h
drivers/usb/host/ehci.h
+2
-1
No files found.
drivers/usb/host/ehci-hcd.c
View file @
d2435050
...
@@ -965,7 +965,7 @@ ehci_endpoint_disable (struct usb_hcd *hcd, struct hcd_dev *dev, int ep)
...
@@ -965,7 +965,7 @@ ehci_endpoint_disable (struct usb_hcd *hcd, struct hcd_dev *dev, int ep)
goto
rescan
;
goto
rescan
;
case
QH_STATE_IDLE
:
/* fully unlinked */
case
QH_STATE_IDLE
:
/* fully unlinked */
if
(
list_empty
(
&
qh
->
qtd_list
))
{
if
(
list_empty
(
&
qh
->
qtd_list
))
{
qh_put
(
ehci
,
qh
);
qh_put
(
qh
);
break
;
break
;
}
}
/* else FALL THROUGH */
/* else FALL THROUGH */
...
...
drivers/usb/host/ehci-mem.c
View file @
d2435050
...
@@ -87,6 +87,22 @@ static inline void ehci_qtd_free (struct ehci_hcd *ehci, struct ehci_qtd *qtd)
...
@@ -87,6 +87,22 @@ static inline void ehci_qtd_free (struct ehci_hcd *ehci, struct ehci_qtd *qtd)
}
}
static
void
qh_destroy
(
struct
kref
*
kref
)
{
struct
ehci_qh
*
qh
=
container_of
(
kref
,
struct
ehci_qh
,
kref
);
struct
ehci_hcd
*
ehci
=
qh
->
ehci
;
/* clean qtds first, and know this is not linked */
if
(
!
list_empty
(
&
qh
->
qtd_list
)
||
qh
->
qh_next
.
ptr
)
{
ehci_dbg
(
ehci
,
"unused qh not empty!
\n
"
);
BUG
();
}
if
(
qh
->
dummy
)
ehci_qtd_free
(
ehci
,
qh
->
dummy
);
usb_put_dev
(
qh
->
dev
);
dma_pool_free
(
ehci
->
qh_pool
,
qh
,
qh
->
qh_dma
);
}
static
struct
ehci_qh
*
ehci_qh_alloc
(
struct
ehci_hcd
*
ehci
,
int
flags
)
static
struct
ehci_qh
*
ehci_qh_alloc
(
struct
ehci_hcd
*
ehci
,
int
flags
)
{
{
struct
ehci_qh
*
qh
;
struct
ehci_qh
*
qh
;
...
@@ -98,7 +114,8 @@ static struct ehci_qh *ehci_qh_alloc (struct ehci_hcd *ehci, int flags)
...
@@ -98,7 +114,8 @@ static struct ehci_qh *ehci_qh_alloc (struct ehci_hcd *ehci, int flags)
return
qh
;
return
qh
;
memset
(
qh
,
0
,
sizeof
*
qh
);
memset
(
qh
,
0
,
sizeof
*
qh
);
atomic_set
(
&
qh
->
refcount
,
1
);
kref_init
(
&
qh
->
kref
,
qh_destroy
);
qh
->
ehci
=
ehci
;
qh
->
qh_dma
=
dma
;
qh
->
qh_dma
=
dma
;
// INIT_LIST_HEAD (&qh->qh_list);
// INIT_LIST_HEAD (&qh->qh_list);
INIT_LIST_HEAD
(
&
qh
->
qtd_list
);
INIT_LIST_HEAD
(
&
qh
->
qtd_list
);
...
@@ -114,25 +131,15 @@ static struct ehci_qh *ehci_qh_alloc (struct ehci_hcd *ehci, int flags)
...
@@ -114,25 +131,15 @@ static struct ehci_qh *ehci_qh_alloc (struct ehci_hcd *ehci, int flags)
}
}
/* to share a qh (cpu threads, or hc) */
/* to share a qh (cpu threads, or hc) */
static
inline
struct
ehci_qh
*
qh_get
(
/* ehci, */
struct
ehci_qh
*
qh
)
static
inline
struct
ehci_qh
*
qh_get
(
struct
ehci_qh
*
qh
)
{
{
atomic_inc
(
&
qh
->
refcount
);
kref_get
(
&
qh
->
kref
);
return
qh
;
return
qh
;
}
}
static
void
qh_put
(
struct
ehci_hcd
*
ehci
,
struct
ehci_qh
*
qh
)
static
inline
void
qh_put
(
struct
ehci_qh
*
qh
)
{
{
if
(
!
atomic_dec_and_test
(
&
qh
->
refcount
))
kref_put
(
&
qh
->
kref
);
return
;
/* clean qtds first, and know this is not linked */
if
(
!
list_empty
(
&
qh
->
qtd_list
)
||
qh
->
qh_next
.
ptr
)
{
ehci_dbg
(
ehci
,
"unused qh not empty!
\n
"
);
BUG
();
}
if
(
qh
->
dummy
)
ehci_qtd_free
(
ehci
,
qh
->
dummy
);
usb_put_dev
(
qh
->
dev
);
dma_pool_free
(
ehci
->
qh_pool
,
qh
,
qh
->
qh_dma
);
}
}
/*-------------------------------------------------------------------------*/
/*-------------------------------------------------------------------------*/
...
@@ -145,7 +152,7 @@ static void qh_put (struct ehci_hcd *ehci, struct ehci_qh *qh)
...
@@ -145,7 +152,7 @@ static void qh_put (struct ehci_hcd *ehci, struct ehci_qh *qh)
static
void
ehci_mem_cleanup
(
struct
ehci_hcd
*
ehci
)
static
void
ehci_mem_cleanup
(
struct
ehci_hcd
*
ehci
)
{
{
if
(
ehci
->
async
)
if
(
ehci
->
async
)
qh_put
(
ehci
,
ehci
->
async
);
qh_put
(
ehci
->
async
);
ehci
->
async
=
0
;
ehci
->
async
=
0
;
/* DMA consistent memory and pools */
/* DMA consistent memory and pools */
...
...
drivers/usb/host/ehci-q.c
View file @
d2435050
...
@@ -193,7 +193,7 @@ ehci_urb_done (struct ehci_hcd *ehci, struct urb *urb, struct pt_regs *regs)
...
@@ -193,7 +193,7 @@ ehci_urb_done (struct ehci_hcd *ehci, struct urb *urb, struct pt_regs *regs)
/* ... update hc-wide periodic stats (for usbfs) */
/* ... update hc-wide periodic stats (for usbfs) */
hcd_to_bus
(
&
ehci
->
hcd
)
->
bandwidth_int_reqs
--
;
hcd_to_bus
(
&
ehci
->
hcd
)
->
bandwidth_int_reqs
--
;
}
}
qh_put
(
ehci
,
qh
);
qh_put
(
qh
);
}
}
spin_lock
(
&
urb
->
lock
);
spin_lock
(
&
urb
->
lock
);
...
@@ -708,7 +708,7 @@ qh_make (
...
@@ -708,7 +708,7 @@ qh_make (
default:
default:
dbg
(
"bogus dev %p speed %d"
,
urb
->
dev
,
urb
->
dev
->
speed
);
dbg
(
"bogus dev %p speed %d"
,
urb
->
dev
,
urb
->
dev
->
speed
);
done:
done:
qh_put
(
ehci
,
qh
);
qh_put
(
qh
);
return
0
;
return
0
;
}
}
...
@@ -951,7 +951,7 @@ static void end_unlink_async (struct ehci_hcd *ehci, struct pt_regs *regs)
...
@@ -951,7 +951,7 @@ static void end_unlink_async (struct ehci_hcd *ehci, struct pt_regs *regs)
// qh->hw_next = cpu_to_le32 (qh->qh_dma);
// qh->hw_next = cpu_to_le32 (qh->qh_dma);
qh
->
qh_state
=
QH_STATE_IDLE
;
qh
->
qh_state
=
QH_STATE_IDLE
;
qh
->
qh_next
.
qh
=
0
;
qh
->
qh_next
.
qh
=
0
;
qh_put
(
ehci
,
qh
);
// refcount from reclaim
qh_put
(
qh
);
// refcount from reclaim
/* other unlink(s) may be pending (in QH_STATE_UNLINK_WAIT) */
/* other unlink(s) may be pending (in QH_STATE_UNLINK_WAIT) */
next
=
qh
->
reclaim
;
next
=
qh
->
reclaim
;
...
@@ -965,7 +965,7 @@ static void end_unlink_async (struct ehci_hcd *ehci, struct pt_regs *regs)
...
@@ -965,7 +965,7 @@ static void end_unlink_async (struct ehci_hcd *ehci, struct pt_regs *regs)
&&
HCD_IS_RUNNING
(
ehci
->
hcd
.
state
))
&&
HCD_IS_RUNNING
(
ehci
->
hcd
.
state
))
qh_link_async
(
ehci
,
qh
);
qh_link_async
(
ehci
,
qh
);
else
{
else
{
qh_put
(
ehci
,
qh
);
// refcount from async list
qh_put
(
qh
);
// refcount from async list
/* it's not free to turn the async schedule on/off; leave it
/* it's not free to turn the async schedule on/off; leave it
* active but idle for a while once it empties.
* active but idle for a while once it empties.
...
@@ -1067,7 +1067,7 @@ scan_async (struct ehci_hcd *ehci, struct pt_regs *regs)
...
@@ -1067,7 +1067,7 @@ scan_async (struct ehci_hcd *ehci, struct pt_regs *regs)
qh
=
qh_get
(
qh
);
qh
=
qh_get
(
qh
);
qh
->
stamp
=
ehci
->
stamp
;
qh
->
stamp
=
ehci
->
stamp
;
temp
=
qh_completions
(
ehci
,
qh
,
regs
);
temp
=
qh_completions
(
ehci
,
qh
,
regs
);
qh_put
(
ehci
,
qh
);
qh_put
(
qh
);
if
(
temp
!=
0
)
{
if
(
temp
!=
0
)
{
goto
rescan
;
goto
rescan
;
}
}
...
...
drivers/usb/host/ehci-sched.c
View file @
d2435050
...
@@ -312,7 +312,7 @@ static void intr_deschedule (
...
@@ -312,7 +312,7 @@ static void intr_deschedule (
do
{
do
{
periodic_unlink
(
ehci
,
frame
,
qh
);
periodic_unlink
(
ehci
,
frame
,
qh
);
qh_put
(
ehci
,
qh
);
qh_put
(
qh
);
frame
+=
qh
->
period
;
frame
+=
qh
->
period
;
}
while
(
frame
<
ehci
->
periodic_size
);
}
while
(
frame
<
ehci
->
periodic_size
);
...
@@ -355,7 +355,7 @@ static void intr_deschedule (
...
@@ -355,7 +355,7 @@ static void intr_deschedule (
dbg
(
"descheduled qh %p, period = %d frame = %d count = %d, urbs = %d"
,
dbg
(
"descheduled qh %p, period = %d frame = %d count = %d, urbs = %d"
,
qh
,
qh
->
period
,
frame
,
qh
,
qh
->
period
,
frame
,
atomic_read
(
&
qh
->
refcount
),
ehci
->
periodic_sched
);
atomic_read
(
&
qh
->
kref
.
refcount
),
ehci
->
periodic_sched
);
}
}
static
int
check_period
(
static
int
check_period
(
...
@@ -1846,7 +1846,7 @@ scan_periodic (struct ehci_hcd *ehci, struct pt_regs *regs)
...
@@ -1846,7 +1846,7 @@ scan_periodic (struct ehci_hcd *ehci, struct pt_regs *regs)
modified
=
qh_completions
(
ehci
,
temp
.
qh
,
regs
);
modified
=
qh_completions
(
ehci
,
temp
.
qh
,
regs
);
if
(
unlikely
(
list_empty
(
&
temp
.
qh
->
qtd_list
)))
if
(
unlikely
(
list_empty
(
&
temp
.
qh
->
qtd_list
)))
intr_deschedule
(
ehci
,
temp
.
qh
,
0
);
intr_deschedule
(
ehci
,
temp
.
qh
,
0
);
qh_put
(
ehci
,
temp
.
qh
);
qh_put
(
temp
.
qh
);
break
;
break
;
case
Q_TYPE_FSTN
:
case
Q_TYPE_FSTN
:
/* for "save place" FSTNs, look at QH entries
/* for "save place" FSTNs, look at QH entries
...
...
drivers/usb/host/ehci.h
View file @
d2435050
...
@@ -366,7 +366,8 @@ struct ehci_qh {
...
@@ -366,7 +366,8 @@ struct ehci_qh {
struct
ehci_qtd
*
dummy
;
struct
ehci_qtd
*
dummy
;
struct
ehci_qh
*
reclaim
;
/* next to reclaim */
struct
ehci_qh
*
reclaim
;
/* next to reclaim */
atomic_t
refcount
;
struct
ehci_hcd
*
ehci
;
struct
kref
kref
;
unsigned
stamp
;
unsigned
stamp
;
u8
qh_state
;
u8
qh_state
;
...
...
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