1 /*****************************************************************************/
3 * auerchain.c -- Auerswald PBX/System Telephone chained urb support.
5 * Copyright (C) 2002 Wolfgang Mües (wolfgang@iksw-muees.de)
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 /*****************************************************************************/
23 #undef DEBUG /* include debug macros until it's done */
24 #include <linux/usb.h>
25 #include "auerchain.h"
26 #include <linux/slab.h>
28 /* completion function for chained urbs */
29 static void auerchain_complete(struct urb *urb)
34 /* get pointer to element and to chain */
35 struct auerchainelement *acep =
36 (struct auerchainelement *) urb->context;
37 struct auerchain *acp = acep->chain;
39 /* restore original entries in urb */
40 urb->context = acep->context;
41 urb->complete = acep->complete;
43 dbg("auerchain_complete called");
45 /* call original completion function
46 NOTE: this function may lead to more urbs submitted into the chain.
47 (no chain lock at calling complete()!)
48 acp->active != NULL is protecting us against recursion. */
51 /* detach element from chain data structure */
52 spin_lock_irqsave(&acp->lock, flags);
53 if (acp->active != acep) /* paranoia debug check */
54 dbg("auerchain_complete: completion on non-active element called!");
58 /* add the used chain element to the list of free elements */
59 list_add_tail(&acep->list, &acp->free_list);
62 /* is there a new element waiting in the chain? */
63 if (!acp->active && !list_empty(&acp->waiting_list)) {
64 /* yes: get the entry */
65 struct list_head *tmp = acp->waiting_list.next;
67 acep = list_entry(tmp, struct auerchainelement, list);
70 spin_unlock_irqrestore(&acp->lock, flags);
72 /* submit the new urb */
75 dbg("auerchain_complete: submitting next urb from chain");
76 urb->status = 0; /* needed! */
77 result = usb_submit_urb(urb);
79 /* check for submit errors */
82 dbg("auerchain_complete: usb_submit_urb with error code %d", result);
83 /* and do error handling via *this* completion function (recursive) */
84 auerchain_complete(urb);
87 /* simple return without submitting a new urb.
88 The empty chain is detected with acp->active == NULL. */
92 /* submit function for chained urbs
93 this function may be called from completion context or from user space!
94 early = 1 -> submit in front of chain
96 int auerchain_submit_urb_list(struct auerchain *acp, struct urb *urb,
101 struct auerchainelement *acep = NULL;
103 dbg("auerchain_submit_urb called");
105 /* try to get a chain element */
106 spin_lock_irqsave(&acp->lock, flags);
107 if (!list_empty(&acp->free_list)) {
108 /* yes: get the entry */
109 struct list_head *tmp = acp->free_list.next;
111 acep = list_entry(tmp, struct auerchainelement, list);
113 spin_unlock_irqrestore(&acp->lock, flags);
115 /* if no chain element available: return with error */
120 /* fill in the new chain element values */
122 acep->context = urb->context;
123 acep->complete = urb->complete;
125 INIT_LIST_HEAD(&acep->list);
129 urb->complete = auerchain_complete;
130 urb->status = -EINPROGRESS; /* usb_submit_urb does this, too */
132 /* add element to chain - or start it immediately */
133 spin_lock_irqsave(&acp->lock, flags);
135 /* there is traffic in the chain, simple add element to chain */
137 dbg("adding new urb to head of chain");
138 list_add(&acep->list, &acp->waiting_list);
140 dbg("adding new urb to end of chain");
141 list_add_tail(&acep->list, &acp->waiting_list);
145 /* the chain is empty. Prepare restart */
148 /* Spin has to be removed before usb_submit_urb! */
149 spin_unlock_irqrestore(&acp->lock, flags);
151 /* Submit urb if immediate restart */
153 dbg("submitting urb immediate");
154 urb->status = 0; /* needed! */
155 result = usb_submit_urb(urb);
156 /* check for submit errors */
158 urb->status = result;
159 dbg("auerchain_submit_urb: usb_submit_urb with error code %d", result);
160 /* and do error handling via completion function */
161 auerchain_complete(urb);
168 /* submit function for chained urbs
169 this function may be called from completion context or from user space!
171 int auerchain_submit_urb(struct auerchain *acp, struct urb *urb)
173 return auerchain_submit_urb_list(acp, urb, 0);
176 /* cancel an urb which is submitted to the chain
177 the result is 0 if the urb is cancelled, or -EINPROGRESS if
178 USB_ASYNC_UNLINK is set and the function is successfully started.
180 int auerchain_unlink_urb(struct auerchain *acp, struct urb *urb)
184 struct auerchainelement *acep;
185 struct list_head *tmp;
187 dbg("auerchain_unlink_urb called");
189 /* search the chain of waiting elements */
190 spin_lock_irqsave(&acp->lock, flags);
191 list_for_each(tmp, &acp->waiting_list) {
192 acep = list_entry(tmp, struct auerchainelement, list);
193 if (acep->urbp == urb) {
195 urb->context = acep->context;
196 urb->complete = acep->complete;
197 list_add_tail(&acep->list, &acp->free_list);
198 spin_unlock_irqrestore(&acp->lock, flags);
199 dbg("unlink waiting urb");
200 urb->status = -ENOENT;
206 spin_unlock_irqrestore(&acp->lock, flags);
208 /* get the active urb */
213 /* check if we have to cancel the active urb */
215 /* note that there is a race condition between the check above
216 and the unlink() call because of no lock. This race is harmless,
217 because the usb module will detect the unlink() after completion.
218 We can't use the acp->lock here because the completion function
221 dbg("unlink active urb");
222 return usb_unlink_urb(urbp);
227 ... is some kind of success
229 dbg("urb to unlink not found in chain");
233 /* cancel all urbs which are in the chain.
234 this function must not be called from interrupt or completion handler.
236 void auerchain_unlink_all(struct auerchain *acp)
240 struct auerchainelement *acep;
242 dbg("auerchain_unlink_all called");
244 /* clear the chain of waiting elements */
245 spin_lock_irqsave(&acp->lock, flags);
246 while (!list_empty(&acp->waiting_list)) {
247 /* get the next entry */
248 struct list_head *tmp = acp->waiting_list.next;
250 acep = list_entry(tmp, struct auerchainelement, list);
252 urbp->context = acep->context;
253 urbp->complete = acep->complete;
254 list_add_tail(&acep->list, &acp->free_list);
255 spin_unlock_irqrestore(&acp->lock, flags);
256 dbg("unlink waiting urb");
257 urbp->status = -ENOENT;
258 urbp->complete(urbp);
259 spin_lock_irqsave(&acp->lock, flags);
261 spin_unlock_irqrestore(&acp->lock, flags);
263 /* clear the active urb */
267 urbp->transfer_flags &= ~USB_ASYNC_UNLINK;
268 dbg("unlink active urb");
269 usb_unlink_urb(urbp);
275 this function must not be called from interrupt or completion handler.
277 void auerchain_free(struct auerchain *acp)
280 struct auerchainelement *acep;
282 dbg("auerchain_free called");
284 /* first, cancel all pending urbs */
285 auerchain_unlink_all(acp);
287 /* free the elements */
288 spin_lock_irqsave(&acp->lock, flags);
289 while (!list_empty(&acp->free_list)) {
290 /* get the next entry */
291 struct list_head *tmp = acp->free_list.next;
293 spin_unlock_irqrestore(&acp->lock, flags);
294 acep = list_entry(tmp, struct auerchainelement, list);
296 spin_lock_irqsave(&acp->lock, flags);
298 spin_unlock_irqrestore(&acp->lock, flags);
302 /* Init the chain control structure */
303 void auerchain_init(struct auerchain *acp)
305 /* init the chain data structure */
307 spin_lock_init(&acp->lock);
308 INIT_LIST_HEAD(&acp->waiting_list);
309 INIT_LIST_HEAD(&acp->free_list);
313 It is assumed that there is no concurrency while setting up the chain
314 requirement: auerchain_init()
316 int auerchain_setup(struct auerchain *acp, unsigned int numElements)
318 struct auerchainelement *acep;
320 dbg("auerchain_setup called with %d elements", numElements);
322 /* fill the list of free elements */
323 for (; numElements; numElements--) {
325 (struct auerchainelement *)
326 kmalloc(sizeof(struct auerchainelement), GFP_KERNEL);
329 memset(acep, 0, sizeof(struct auerchainelement));
330 INIT_LIST_HEAD(&acep->list);
331 list_add_tail(&acep->list, &acp->free_list);
335 ac_fail: /* free the elements */
336 while (!list_empty(&acp->free_list)) {
337 /* get the next entry */
338 struct list_head *tmp = acp->free_list.next;
340 acep = list_entry(tmp, struct auerchainelement, list);
347 /* completion handler for synchronous chained URBs */
348 static void auerchain_blocking_completion(struct urb *urb)
350 struct auerchain_chs *pchs = (struct auerchain_chs *) urb->context;
357 /* Starts chained urb and waits for completion or timeout */
358 static int auerchain_start_wait_urb(struct auerchain *acp, struct urb *urb,
359 int timeout, int *actual_length)
361 DECLARE_WAITQUEUE(wait, current);
362 struct auerchain_chs chs;
365 dbg("auerchain_start_wait_urb called");
366 init_waitqueue_head(&chs.wqh);
369 set_current_state(TASK_UNINTERRUPTIBLE);
370 add_wait_queue(&chs.wqh, &wait);
372 status = auerchain_submit_urb(acp, urb);
374 /* something went wrong */
375 set_current_state(TASK_RUNNING);
376 remove_wait_queue(&chs.wqh, &wait);
380 while (timeout && !chs.done) {
381 timeout = schedule_timeout(timeout);
382 set_current_state(TASK_UNINTERRUPTIBLE);
386 set_current_state(TASK_RUNNING);
387 remove_wait_queue(&chs.wqh, &wait);
389 if (!timeout && !chs.done) {
390 if (urb->status != -EINPROGRESS) { /* No callback?!! */
391 dbg("auerchain_start_wait_urb: raced timeout");
392 status = urb->status;
394 dbg("auerchain_start_wait_urb: timeout");
395 auerchain_unlink_urb(acp, urb); /* remove urb safely */
399 status = urb->status;
402 *actual_length = urb->actual_length;
408 /* auerchain_control_msg - Builds a control urb, sends it off and waits for completion
409 acp: pointer to the auerchain
410 dev: pointer to the usb device to send the message to
411 pipe: endpoint "pipe" to send the message to
412 request: USB message request value
413 requesttype: USB message request type value
414 value: USB message value
415 index: USB message index value
416 data: pointer to the data to send
417 size: length in bytes of the data to send
418 timeout: time to wait for the message to complete before timing out (if 0 the wait is forever)
420 This function sends a simple control message to a specified endpoint
421 and waits for the message to complete, or timeout.
423 If successful, it returns the transfered length, othwise a negative error number.
425 Don't use this function from within an interrupt context, like a
426 bottom half handler. If you need a asyncronous message, or need to send
427 a message from within interrupt context, use auerchain_submit_urb()
429 int auerchain_control_msg(struct auerchain *acp, struct usb_device *dev,
430 unsigned int pipe, __u8 request,
431 __u8 requesttype, __u16 value, __u16 index,
432 void *data, __u16 size, int timeout)
435 struct usb_ctrlrequest *dr;
439 dbg("auerchain_control_msg");
440 dr = (struct usb_ctrlrequest *)
441 kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL);
444 urb = usb_alloc_urb(0);
450 dr->bRequestType = requesttype;
451 dr->bRequest = request;
452 dr->wValue = cpu_to_le16(value);
453 dr->wIndex = cpu_to_le16(index);
454 dr->wLength = cpu_to_le16(size);
456 FILL_CONTROL_URB(urb, dev, pipe, (unsigned char *) dr, data, size, /* build urb */
457 (usb_complete_t) auerchain_blocking_completion,
459 ret = auerchain_start_wait_urb(acp, urb, timeout, &length);