1 /*****************************************************************************/
3 * auerbuf.c -- Auerswald PBX/System Telephone urb list storage.
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>
26 #include <linux/slab.h>
28 /* free a single auerbuf */
29 void auerbuf_free(struct auerbuf *bp)
35 usb_free_urb(bp->urbp);
40 /* free the buffers from an auerbuf list */
41 void auerbuf_free_list(struct list_head *q)
43 struct list_head *tmp;
47 dbg("auerbuf_free_list");
48 for (p = q->next; p != q;) {
49 bp = list_entry(p, struct auerbuf, buff_list);
57 /* free all buffers from an auerbuf chain */
58 void auerbuf_free_buffers(struct auerbufctl *bcp)
61 dbg("auerbuf_free_buffers");
63 spin_lock_irqsave(&bcp->lock, flags);
65 auerbuf_free_list(&bcp->free_buff_list);
66 auerbuf_free_list(&bcp->rec_buff_list);
68 spin_unlock_irqrestore(&bcp->lock, flags);
71 /* init the members of a list control block */
72 void auerbuf_init(struct auerbufctl *bcp)
75 spin_lock_init(&bcp->lock);
76 INIT_LIST_HEAD(&bcp->free_buff_list);
77 INIT_LIST_HEAD(&bcp->rec_buff_list);
80 /* setup a list of buffers */
81 /* requirement: auerbuf_init() */
82 int auerbuf_setup(struct auerbufctl *bcp, unsigned int numElements,
85 struct auerbuf *bep = NULL;
87 dbg("auerbuf_setup called with %d elements of %d bytes",
88 numElements, bufsize);
90 /* fill the list of free elements */
91 for (; numElements; numElements--) {
93 (struct auerbuf *) kmalloc(sizeof(struct auerbuf),
97 memset(bep, 0, sizeof(struct auerbuf));
99 INIT_LIST_HEAD(&bep->buff_list);
100 bep->bufp = (char *) kmalloc(bufsize, GFP_KERNEL);
104 (struct usb_ctrlrequest *)
105 kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL);
108 bep->urbp = usb_alloc_urb(0);
111 list_add_tail(&bep->buff_list, &bcp->free_buff_list);
115 bl_fail: /* not enought memory. Free allocated elements */
116 dbg("auerbuf_setup: no more memory");
118 auerbuf_free_buffers(bcp);
122 /* alloc a free buffer from the list. Returns NULL if no buffer available */
123 struct auerbuf *auerbuf_getbuf(struct auerbufctl *bcp)
126 struct auerbuf *bp = NULL;
128 spin_lock_irqsave(&bcp->lock, flags);
129 if (!list_empty(&bcp->free_buff_list)) {
130 /* yes: get the entry */
131 struct list_head *tmp = bcp->free_buff_list.next;
133 bp = list_entry(tmp, struct auerbuf, buff_list);
135 spin_unlock_irqrestore(&bcp->lock, flags);
139 /* insert a used buffer into the free list */
140 void auerbuf_releasebuf(struct auerbuf *bp)
143 struct auerbufctl *bcp = bp->list;
146 dbg("auerbuf_releasebuf called");
147 spin_lock_irqsave(&bcp->lock, flags);
148 list_add_tail(&bp->buff_list, &bcp->free_buff_list);
149 spin_unlock_irqrestore(&bcp->lock, flags);