1/*****************************************************************************/
2/*
3 *      auerchain.c  --  Auerswald PBX/System Telephone chained urb support.
4 *
5 *      Copyright (C) 2002  Wolfgang M�es (wolfgang@iksw-muees.de)
6 *
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.
11 *
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.
16 *
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.
20 */
21 /*****************************************************************************/
22
23#undef DEBUG			/* include debug macros until it's done */
24#include <linux/usb.h>
25#include "auerchain.h"
26#include <linux/slab.h>
27
28/* completion function for chained urbs */
29static void auerchain_complete(struct urb *urb)
30{
31	unsigned long flags;
32	int result;
33
34	/* get pointer to element and to chain */
35	struct auerchainelement *acep =
36	    (struct auerchainelement *) urb->context;
37	struct auerchain *acp = acep->chain;
38
39	/* restore original entries in urb */
40	urb->context = acep->context;
41	urb->complete = acep->complete;
42
43	dbg("auerchain_complete called");
44
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. */
49	urb->complete(urb);
50
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!");
55	else
56		acp->active = NULL;
57
58	/* add the used chain element to the list of free elements */
59	list_add_tail(&acep->list, &acp->free_list);
60	acep = NULL;
61
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;
66		list_del(tmp);
67		acep = list_entry(tmp, struct auerchainelement, list);
68		acp->active = acep;
69	}
70	spin_unlock_irqrestore(&acp->lock, flags);
71
72	/* submit the new urb */
73	if (acep) {
74		urb = acep->urbp;
75		dbg("auerchain_complete: submitting next urb from chain");
76		urb->status = 0;	/* needed! */
77		result = usb_submit_urb(urb);
78
79		/* check for submit errors */
80		if (result) {
81			urb->status = result;
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);
85		}
86	} else {
87		/* simple return without submitting a new urb.
88		   The empty chain is detected with acp->active == NULL. */
89	};
90}
91
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
95*/
96int auerchain_submit_urb_list(struct auerchain *acp, struct urb *urb,
97			      int early)
98{
99	int result;
100	unsigned long flags;
101	struct auerchainelement *acep = NULL;
102
103	dbg("auerchain_submit_urb called");
104
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;
110		list_del(tmp);
111		acep = list_entry(tmp, struct auerchainelement, list);
112	}
113	spin_unlock_irqrestore(&acp->lock, flags);
114
115	/* if no chain element available: return with error */
116	if (!acep) {
117		return -ENOMEM;
118	}
119
120	/* fill in the new chain element values */
121	acep->chain = acp;
122	acep->context = urb->context;
123	acep->complete = urb->complete;
124	acep->urbp = urb;
125	INIT_LIST_HEAD(&acep->list);
126
127	/* modify urb */
128	urb->context = acep;
129	urb->complete = auerchain_complete;
130	urb->status = -EINPROGRESS;	/* usb_submit_urb does this, too */
131
132	/* add element to chain - or start it immediately */
133	spin_lock_irqsave(&acp->lock, flags);
134	if (acp->active) {
135		/* there is traffic in the chain, simple add element to chain */
136		if (early) {
137			dbg("adding new urb to head of chain");
138			list_add(&acep->list, &acp->waiting_list);
139		} else {
140			dbg("adding new urb to end of chain");
141			list_add_tail(&acep->list, &acp->waiting_list);
142		}
143		acep = NULL;
144	} else {
145		/* the chain is empty. Prepare restart */
146		acp->active = acep;
147	}
148	/* Spin has to be removed before usb_submit_urb! */
149	spin_unlock_irqrestore(&acp->lock, flags);
150
151	/* Submit urb if immediate restart */
152	if (acep) {
153		dbg("submitting urb immediate");
154		urb->status = 0;	/* needed! */
155		result = usb_submit_urb(urb);
156		/* check for submit errors */
157		if (result) {
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);
162		}
163	}
164
165	return 0;
166}
167
168/* submit function for chained urbs
169   this function may be called from completion context or from user space!
170*/
171int auerchain_submit_urb(struct auerchain *acp, struct urb *urb)
172{
173	return auerchain_submit_urb_list(acp, urb, 0);
174}
175
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.
179*/
180int auerchain_unlink_urb(struct auerchain *acp, struct urb *urb)
181{
182	unsigned long flags;
183	struct urb *urbp;
184	struct auerchainelement *acep;
185	struct list_head *tmp;
186
187	dbg("auerchain_unlink_urb called");
188
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) {
194			list_del(tmp);
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;
201			urb->complete(urb);
202			return 0;
203		}
204	}
205	/* not found. */
206	spin_unlock_irqrestore(&acp->lock, flags);
207
208	/* get the active urb */
209	acep = acp->active;
210	if (acep) {
211		urbp = acep->urbp;
212
213		/* check if we have to cancel the active urb */
214		if (urbp == 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
219			   wants to grab it.
220			 */
221			dbg("unlink active urb");
222			return usb_unlink_urb(urbp);
223		}
224	}
225
226	/* not found anyway
227	   ... is some kind of success
228	 */
229	dbg("urb to unlink not found in chain");
230	return 0;
231}
232
233/* cancel all urbs which are in the chain.
234   this function must not be called from interrupt or completion handler.
235*/
236void auerchain_unlink_all(struct auerchain *acp)
237{
238	unsigned long flags;
239	struct urb *urbp;
240	struct auerchainelement *acep;
241
242	dbg("auerchain_unlink_all called");
243
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;
249		list_del(tmp);
250		acep = list_entry(tmp, struct auerchainelement, list);
251		urbp = acep->urbp;
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);
260	}
261	spin_unlock_irqrestore(&acp->lock, flags);
262
263	/* clear the active urb */
264	acep = acp->active;
265	if (acep) {
266		urbp = acep->urbp;
267		urbp->transfer_flags &= ~USB_ASYNC_UNLINK;
268		dbg("unlink active urb");
269		usb_unlink_urb(urbp);
270	}
271}
272
273
274/* free the chain.
275   this function must not be called from interrupt or completion handler.
276*/
277void auerchain_free(struct auerchain *acp)
278{
279	unsigned long flags;
280	struct auerchainelement *acep;
281
282	dbg("auerchain_free called");
283
284	/* first, cancel all pending urbs */
285	auerchain_unlink_all(acp);
286
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;
292		list_del(tmp);
293		spin_unlock_irqrestore(&acp->lock, flags);
294		acep = list_entry(tmp, struct auerchainelement, list);
295		kfree(acep);
296		spin_lock_irqsave(&acp->lock, flags);
297	}
298	spin_unlock_irqrestore(&acp->lock, flags);
299}
300
301
302/* Init the chain control structure */
303void auerchain_init(struct auerchain *acp)
304{
305	/* init the chain data structure */
306	acp->active = NULL;
307	spin_lock_init(&acp->lock);
308	INIT_LIST_HEAD(&acp->waiting_list);
309	INIT_LIST_HEAD(&acp->free_list);
310}
311
312/* setup a chain.
313   It is assumed that there is no concurrency while setting up the chain
314   requirement: auerchain_init()
315*/
316int auerchain_setup(struct auerchain *acp, unsigned int numElements)
317{
318	struct auerchainelement *acep;
319
320	dbg("auerchain_setup called with %d elements", numElements);
321
322	/* fill the list of free elements */
323	for (; numElements; numElements--) {
324		acep =
325		    (struct auerchainelement *)
326		    kmalloc(sizeof(struct auerchainelement), GFP_KERNEL);
327		if (!acep)
328			goto ac_fail;
329		memset(acep, 0, sizeof(struct auerchainelement));
330		INIT_LIST_HEAD(&acep->list);
331		list_add_tail(&acep->list, &acp->free_list);
332	}
333	return 0;
334
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;
339		list_del(tmp);
340		acep = list_entry(tmp, struct auerchainelement, list);
341		kfree(acep);
342	}
343	return -ENOMEM;
344}
345
346
347/* completion handler for synchronous chained URBs */
348static void auerchain_blocking_completion(struct urb *urb)
349{
350	struct auerchain_chs *pchs = (struct auerchain_chs *) urb->context;
351	pchs->done = 1;
352	wmb();
353	wake_up(&pchs->wqh);
354}
355
356
357/* Starts chained urb and waits for completion or timeout */
358static int auerchain_start_wait_urb(struct auerchain *acp, struct urb *urb,
359				    int timeout, int *actual_length)
360{
361	DECLARE_WAITQUEUE(wait, current);
362	struct auerchain_chs chs;
363	int status;
364
365	dbg("auerchain_start_wait_urb called");
366	init_waitqueue_head(&chs.wqh);
367	chs.done = 0;
368
369	set_current_state(TASK_UNINTERRUPTIBLE);
370	add_wait_queue(&chs.wqh, &wait);
371	urb->context = &chs;
372	status = auerchain_submit_urb(acp, urb);
373	if (status) {
374		/* something went wrong */
375		set_current_state(TASK_RUNNING);
376		remove_wait_queue(&chs.wqh, &wait);
377		return status;
378	}
379
380	while (timeout && !chs.done) {
381		timeout = schedule_timeout(timeout);
382		set_current_state(TASK_UNINTERRUPTIBLE);
383		rmb();
384	}
385
386	set_current_state(TASK_RUNNING);
387	remove_wait_queue(&chs.wqh, &wait);
388
389	if (!timeout && !chs.done) {
390		if (urb->status != -EINPROGRESS) {	/* No callback?!! */
391			dbg("auerchain_start_wait_urb: raced timeout");
392			status = urb->status;
393		} else {
394			dbg("auerchain_start_wait_urb: timeout");
395			auerchain_unlink_urb(acp, urb);	/* remove urb safely */
396			status = -ETIMEDOUT;
397		}
398	} else
399		status = urb->status;
400
401	if (actual_length)
402		*actual_length = urb->actual_length;
403
404	return status;
405}
406
407
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)
419
420   This function sends a simple control message to a specified endpoint
421   and waits for the message to complete, or timeout.
422
423   If successful, it returns the transfered length, othwise a negative error number.
424
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()
428*/
429int 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)
433{
434	int ret;
435	struct usb_ctrlrequest *dr;
436	struct urb *urb;
437	int length;
438
439	dbg("auerchain_control_msg");
440	dr = (struct usb_ctrlrequest *)
441	    kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL);
442	if (!dr)
443		return -ENOMEM;
444	urb = usb_alloc_urb(0);
445	if (!urb) {
446		kfree(dr);
447		return -ENOMEM;
448	}
449
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);
455
456	FILL_CONTROL_URB(urb, dev, pipe, (unsigned char *) dr, data, size,	/* build urb */
457			 (usb_complete_t) auerchain_blocking_completion,
458			 0);
459	ret = auerchain_start_wait_urb(acp, urb, timeout, &length);
460
461	usb_free_urb(urb);
462	kfree(dr);
463
464	if (ret < 0)
465		return ret;
466	else
467		return length;
468}
469