aboutsummaryrefslogtreecommitdiffstats
path: root/Documentation/usb
diff options
context:
space:
mode:
Diffstat (limited to 'Documentation/usb')
-rw-r--r--Documentation/usb/URB.txt22
1 files changed, 22 insertions, 0 deletions
diff --git a/Documentation/usb/URB.txt b/Documentation/usb/URB.txt
index 8ffce746d496..00d2c644068e 100644
--- a/Documentation/usb/URB.txt
+++ b/Documentation/usb/URB.txt
@@ -168,6 +168,28 @@ that if the completion handler or anyone else tries to resubmit it
168they will get a -EPERM error. Thus you can be sure that when 168they will get a -EPERM error. Thus you can be sure that when
169usb_kill_urb() returns, the URB is totally idle. 169usb_kill_urb() returns, the URB is totally idle.
170 170
171There is a lifetime issue to consider. An URB may complete at any
172time, and the completion handler may free the URB. If this happens
173while usb_unlink_urb or usb_kill_urb is running, it will cause a
174memory-access violation. The driver is responsible for avoiding this,
175which often means some sort of lock will be needed to prevent the URB
176from being deallocated while it is still in use.
177
178On the other hand, since usb_unlink_urb may end up calling the
179completion handler, the handler must not take any lock that is held
180when usb_unlink_urb is invoked. The general solution to this problem
181is to increment the URB's reference count while holding the lock, then
182drop the lock and call usb_unlink_urb or usb_kill_urb, and then
183decrement the URB's reference count. You increment the reference
184count by calling
185
186 struct urb *usb_get_urb(struct urb *urb)
187
188(ignore the return value; it is the same as the argument) and
189decrement the reference count by calling usb_free_urb. Of course,
190none of this is necessary if there's no danger of the URB being freed
191by the completion handler.
192
171 193
1721.7. What about the completion handler? 1941.7. What about the completion handler?
173 195