blob: 093938697426c3d2209b73754fa4341b519d672f [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*****************************************************************************/
2/*
3 * auerswald.c -- Auerswald PBX/System Telephone usb driver.
4 *
5 * Copyright (C) 2001 Wolfgang Mües (wolfgang@iksw-muees.de)
6 *
7 * Very much code of this driver is borrowed from dabusb.c (Deti Fliegl)
8 * and from the USB Skeleton driver (Greg Kroah-Hartman). Thank you.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 */
24 /*****************************************************************************/
25
26/* Standard Linux module include files */
27#include <asm/uaccess.h>
28#include <asm/byteorder.h>
29#include <linux/slab.h>
30#include <linux/module.h>
31#include <linux/init.h>
32#include <linux/wait.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070033#include <linux/usb.h>
matthias@kaehlcke.netb994d7f2008-02-18 20:45:34 +010034#include <linux/mutex.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070035
36/*-------------------------------------------------------------------*/
37/* Debug support */
38#ifdef DEBUG
39#define dump( adr, len) \
40do { \
41 unsigned int u; \
42 printk (KERN_DEBUG); \
43 for (u = 0; u < len; u++) \
44 printk (" %02X", adr[u] & 0xFF); \
45 printk ("\n"); \
46} while (0)
47#else
48#define dump( adr, len)
49#endif
50
51/*-------------------------------------------------------------------*/
52/* Version Information */
53#define DRIVER_VERSION "0.9.11"
54#define DRIVER_AUTHOR "Wolfgang Mües <wolfgang@iksw-muees.de>"
55#define DRIVER_DESC "Auerswald PBX/System Telephone usb driver"
56
57/*-------------------------------------------------------------------*/
58/* Private declarations for Auerswald USB driver */
59
60/* Auerswald Vendor ID */
61#define ID_AUERSWALD 0x09BF
62
63#define AUER_MINOR_BASE 112 /* auerswald driver minor number */
64
65/* we can have up to this number of device plugged in at once */
66#define AUER_MAX_DEVICES 16
67
68
69/* Number of read buffers for each device */
70#define AU_RBUFFERS 10
71
72/* Number of chain elements for each control chain */
73#define AUCH_ELEMENTS 20
74
75/* Number of retries in communication */
76#define AU_RETRIES 10
77
78/*-------------------------------------------------------------------*/
79/* vendor specific protocol */
80/* Header Byte */
81#define AUH_INDIRMASK 0x80 /* mask for direct/indirect bit */
82#define AUH_DIRECT 0x00 /* data is for USB device */
83#define AUH_INDIRECT 0x80 /* USB device is relay */
84
85#define AUH_SPLITMASK 0x40 /* mask for split bit */
86#define AUH_UNSPLIT 0x00 /* data block is full-size */
87#define AUH_SPLIT 0x40 /* data block is part of a larger one,
88 split-byte follows */
89
90#define AUH_TYPEMASK 0x3F /* mask for type of data transfer */
91#define AUH_TYPESIZE 0x40 /* different types */
92#define AUH_DCHANNEL 0x00 /* D channel data */
93#define AUH_B1CHANNEL 0x01 /* B1 channel transparent */
94#define AUH_B2CHANNEL 0x02 /* B2 channel transparent */
95/* 0x03..0x0F reserved for driver internal use */
96#define AUH_COMMAND 0x10 /* Command channel */
97#define AUH_BPROT 0x11 /* Configuration block protocol */
98#define AUH_DPROTANA 0x12 /* D channel protocol analyzer */
99#define AUH_TAPI 0x13 /* telephone api data (ATD) */
100/* 0x14..0x3F reserved for other protocols */
101#define AUH_UNASSIGNED 0xFF /* if char device has no assigned service */
102#define AUH_FIRSTUSERCH 0x11 /* first channel which is available for driver users */
103
104#define AUH_SIZE 1 /* Size of Header Byte */
105
106/* Split Byte. Only present if split bit in header byte set.*/
107#define AUS_STARTMASK 0x80 /* mask for first block of splitted frame */
108#define AUS_FIRST 0x80 /* first block */
109#define AUS_FOLLOW 0x00 /* following block */
110
111#define AUS_ENDMASK 0x40 /* mask for last block of splitted frame */
112#define AUS_END 0x40 /* last block */
113#define AUS_NOEND 0x00 /* not the last block */
114
115#define AUS_LENMASK 0x3F /* mask for block length information */
116
117/* Request types */
118#define AUT_RREQ (USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_OTHER) /* Read Request */
119#define AUT_WREQ (USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER) /* Write Request */
120
121/* Vendor Requests */
122#define AUV_GETINFO 0x00 /* GetDeviceInfo */
123#define AUV_WBLOCK 0x01 /* Write Block */
124#define AUV_RBLOCK 0x02 /* Read Block */
125#define AUV_CHANNELCTL 0x03 /* Channel Control */
126#define AUV_DUMMY 0x04 /* Dummy Out for retry */
127
128/* Device Info Types */
129#define AUDI_NUMBCH 0x0000 /* Number of supported B channels */
130#define AUDI_OUTFSIZE 0x0001 /* Size of OUT B channel fifos */
131#define AUDI_MBCTRANS 0x0002 /* max. Blocklength of control transfer */
132
133/* Interrupt endpoint definitions */
134#define AU_IRQENDP 1 /* Endpoint number */
135#define AU_IRQCMDID 16 /* Command-block ID */
136#define AU_BLOCKRDY 0 /* Command: Block data ready on ctl endpoint */
137#define AU_IRQMINSIZE 5 /* Nr. of bytes decoded in this driver */
138
139/* Device String Descriptors */
140#define AUSI_VENDOR 1 /* "Auerswald GmbH & Co. KG" */
141#define AUSI_DEVICE 2 /* Name of the Device */
142#define AUSI_SERIALNR 3 /* Serial Number */
143#define AUSI_MSN 4 /* "MSN ..." (first) Multiple Subscriber Number */
144
145#define AUSI_DLEN 100 /* Max. Length of Device Description */
146
147#define AUV_RETRY 0x101 /* First Firmware version which can do control retries */
148
149/*-------------------------------------------------------------------*/
150/* External data structures / Interface */
151typedef struct
152{
153 char __user *buf; /* return buffer for string contents */
154 unsigned int bsize; /* size of return buffer */
155} audevinfo_t,*paudevinfo_t;
156
157/* IO controls */
158#define IOCTL_AU_SLEN _IOR( 'U', 0xF0, int) /* return the max. string descriptor length */
159#define IOCTL_AU_DEVINFO _IOWR('U', 0xF1, audevinfo_t) /* get name of a specific device */
160#define IOCTL_AU_SERVREQ _IOW( 'U', 0xF2, int) /* request a service channel */
161#define IOCTL_AU_BUFLEN _IOR( 'U', 0xF3, int) /* return the max. buffer length for the device */
162#define IOCTL_AU_RXAVAIL _IOR( 'U', 0xF4, int) /* return != 0 if Receive Data available */
163#define IOCTL_AU_CONNECT _IOR( 'U', 0xF5, int) /* return != 0 if connected to a service channel */
164#define IOCTL_AU_TXREADY _IOR( 'U', 0xF6, int) /* return != 0 if Transmitt channel ready to send */
165/* 'U' 0xF7..0xFF reseved */
166
167/*-------------------------------------------------------------------*/
168/* Internal data structures */
169
170/* ..................................................................*/
171/* urb chain element */
172struct auerchain; /* forward for circular reference */
173typedef struct
174{
175 struct auerchain *chain; /* pointer to the chain to which this element belongs */
176 struct urb * urbp; /* pointer to attached urb */
177 void *context; /* saved URB context */
178 usb_complete_t complete; /* saved URB completion function */
179 struct list_head list; /* to include element into a list */
180} auerchainelement_t,*pauerchainelement_t;
181
182/* urb chain */
183typedef struct auerchain
184{
185 pauerchainelement_t active; /* element which is submitted to urb */
186 spinlock_t lock; /* protection agains interrupts */
187 struct list_head waiting_list; /* list of waiting elements */
188 struct list_head free_list; /* list of available elements */
189} auerchain_t,*pauerchain_t;
190
191/* urb blocking completion helper struct */
192typedef struct
193{
194 wait_queue_head_t wqh; /* wait for completion */
195 unsigned int done; /* completion flag */
196} auerchain_chs_t,*pauerchain_chs_t;
197
198/* ...................................................................*/
199/* buffer element */
200struct auerbufctl; /* forward */
201typedef struct
202{
203 char *bufp; /* reference to allocated data buffer */
204 unsigned int len; /* number of characters in data buffer */
205 unsigned int retries; /* for urb retries */
206 struct usb_ctrlrequest *dr; /* for setup data in control messages */
207 struct urb * urbp; /* USB urb */
208 struct auerbufctl *list; /* pointer to list */
209 struct list_head buff_list; /* reference to next buffer in list */
210} auerbuf_t,*pauerbuf_t;
211
212/* buffer list control block */
213typedef struct auerbufctl
214{
215 spinlock_t lock; /* protection in interrupt */
216 struct list_head free_buff_list;/* free buffers */
217 struct list_head rec_buff_list; /* buffers with receive data */
218} auerbufctl_t,*pauerbufctl_t;
219
220/* ...................................................................*/
221/* service context */
222struct auerscon; /* forward */
223typedef void (*auer_dispatch_t)(struct auerscon*, pauerbuf_t);
224typedef void (*auer_disconn_t) (struct auerscon*);
225typedef struct auerscon
226{
227 unsigned int id; /* protocol service id AUH_xxxx */
228 auer_dispatch_t dispatch; /* dispatch read buffer */
229 auer_disconn_t disconnect; /* disconnect from device, wake up all char readers */
230} auerscon_t,*pauerscon_t;
231
232/* ...................................................................*/
233/* USB device context */
234typedef struct
235{
matthias@kaehlcke.netb994d7f2008-02-18 20:45:34 +0100236 struct mutex mutex; /* protection in user context */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700237 char name[20]; /* name of the /dev/usb entry */
238 unsigned int dtindex; /* index in the device table */
239 struct usb_device * usbdev; /* USB device handle */
240 int open_count; /* count the number of open character channels */
241 char dev_desc[AUSI_DLEN];/* for storing a textual description */
242 unsigned int maxControlLength; /* max. Length of control paket (without header) */
243 struct urb * inturbp; /* interrupt urb */
244 char * intbufp; /* data buffer for interrupt urb */
245 unsigned int irqsize; /* size of interrupt endpoint 1 */
246 struct auerchain controlchain; /* for chaining of control messages */
247 auerbufctl_t bufctl; /* Buffer control for control transfers */
248 pauerscon_t services[AUH_TYPESIZE];/* context pointers for each service */
249 unsigned int version; /* Version of the device */
250 wait_queue_head_t bufferwait; /* wait for a control buffer */
251} auerswald_t,*pauerswald_t;
252
253/* ................................................................... */
254/* character device context */
255typedef struct
256{
matthias@kaehlcke.netfadec782008-02-18 20:45:36 +0100257 struct mutex mutex; /* protection in user context */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700258 pauerswald_t auerdev; /* context pointer of assigned device */
259 auerbufctl_t bufctl; /* controls the buffer chain */
260 auerscon_t scontext; /* service context */
261 wait_queue_head_t readwait; /* for synchronous reading */
matthias@kaehlcke.net8a0f46b2008-02-18 20:45:35 +0100262 struct mutex readmutex; /* protection against multiple reads */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700263 pauerbuf_t readbuf; /* buffer held for partial reading */
264 unsigned int readoffset; /* current offset in readbuf */
265 unsigned int removed; /* is != 0 if device is removed */
266} auerchar_t,*pauerchar_t;
267
268
269/*-------------------------------------------------------------------*/
270/* Forwards */
David Howells7d12e782006-10-05 14:55:46 +0100271static void auerswald_ctrlread_complete (struct urb * urb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700272static void auerswald_removeservice (pauerswald_t cp, pauerscon_t scp);
273static struct usb_driver auerswald_driver;
274
275
276/*-------------------------------------------------------------------*/
277/* USB chain helper functions */
278/* -------------------------- */
279
280/* completion function for chained urbs */
David Howells7d12e782006-10-05 14:55:46 +0100281static void auerchain_complete (struct urb * urb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700282{
283 unsigned long flags;
284 int result;
285
286 /* get pointer to element and to chain */
Ming Leicdc97792008-02-24 18:41:47 +0800287 pauerchainelement_t acep = urb->context;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700288 pauerchain_t acp = acep->chain;
289
290 /* restore original entries in urb */
291 urb->context = acep->context;
292 urb->complete = acep->complete;
293
294 dbg ("auerchain_complete called");
295
296 /* call original completion function
297 NOTE: this function may lead to more urbs submitted into the chain.
298 (no chain lock at calling complete()!)
299 acp->active != NULL is protecting us against recursion.*/
David Howells7d12e782006-10-05 14:55:46 +0100300 urb->complete (urb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700301
302 /* detach element from chain data structure */
303 spin_lock_irqsave (&acp->lock, flags);
304 if (acp->active != acep) /* paranoia debug check */
305 dbg ("auerchain_complete: completion on non-active element called!");
306 else
307 acp->active = NULL;
308
309 /* add the used chain element to the list of free elements */
310 list_add_tail (&acep->list, &acp->free_list);
311 acep = NULL;
312
313 /* is there a new element waiting in the chain? */
314 if (!acp->active && !list_empty (&acp->waiting_list)) {
315 /* yes: get the entry */
316 struct list_head *tmp = acp->waiting_list.next;
317 list_del (tmp);
318 acep = list_entry (tmp, auerchainelement_t, list);
319 acp->active = acep;
320 }
321 spin_unlock_irqrestore (&acp->lock, flags);
322
323 /* submit the new urb */
324 if (acep) {
325 urb = acep->urbp;
326 dbg ("auerchain_complete: submitting next urb from chain");
327 urb->status = 0; /* needed! */
328 result = usb_submit_urb(urb, GFP_ATOMIC);
329
330 /* check for submit errors */
331 if (result) {
332 urb->status = result;
333 dbg("auerchain_complete: usb_submit_urb with error code %d", result);
334 /* and do error handling via *this* completion function (recursive) */
David Howells7d12e782006-10-05 14:55:46 +0100335 auerchain_complete( urb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700336 }
337 } else {
338 /* simple return without submitting a new urb.
339 The empty chain is detected with acp->active == NULL. */
340 };
341}
342
343
344/* submit function for chained urbs
345 this function may be called from completion context or from user space!
346 early = 1 -> submit in front of chain
347*/
348static int auerchain_submit_urb_list (pauerchain_t acp, struct urb * urb, int early)
349{
350 int result;
351 unsigned long flags;
352 pauerchainelement_t acep = NULL;
353
354 dbg ("auerchain_submit_urb called");
355
356 /* try to get a chain element */
357 spin_lock_irqsave (&acp->lock, flags);
358 if (!list_empty (&acp->free_list)) {
359 /* yes: get the entry */
360 struct list_head *tmp = acp->free_list.next;
361 list_del (tmp);
362 acep = list_entry (tmp, auerchainelement_t, list);
363 }
364 spin_unlock_irqrestore (&acp->lock, flags);
365
366 /* if no chain element available: return with error */
367 if (!acep) {
368 return -ENOMEM;
369 }
370
371 /* fill in the new chain element values */
372 acep->chain = acp;
373 acep->context = urb->context;
374 acep->complete = urb->complete;
375 acep->urbp = urb;
376 INIT_LIST_HEAD (&acep->list);
377
378 /* modify urb */
379 urb->context = acep;
380 urb->complete = auerchain_complete;
381 urb->status = -EINPROGRESS; /* usb_submit_urb does this, too */
382
383 /* add element to chain - or start it immediately */
384 spin_lock_irqsave (&acp->lock, flags);
385 if (acp->active) {
386 /* there is traffic in the chain, simple add element to chain */
387 if (early) {
388 dbg ("adding new urb to head of chain");
389 list_add (&acep->list, &acp->waiting_list);
390 } else {
391 dbg ("adding new urb to end of chain");
392 list_add_tail (&acep->list, &acp->waiting_list);
393 }
394 acep = NULL;
395 } else {
396 /* the chain is empty. Prepare restart */
397 acp->active = acep;
398 }
399 /* Spin has to be removed before usb_submit_urb! */
400 spin_unlock_irqrestore (&acp->lock, flags);
401
402 /* Submit urb if immediate restart */
403 if (acep) {
404 dbg("submitting urb immediate");
405 urb->status = 0; /* needed! */
406 result = usb_submit_urb(urb, GFP_ATOMIC);
407 /* check for submit errors */
408 if (result) {
409 urb->status = result;
410 dbg("auerchain_submit_urb: usb_submit_urb with error code %d", result);
411 /* and do error handling via completion function */
David Howells7d12e782006-10-05 14:55:46 +0100412 auerchain_complete( urb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700413 }
414 }
415
416 return 0;
417}
418
419/* submit function for chained urbs
420 this function may be called from completion context or from user space!
421*/
422static int auerchain_submit_urb (pauerchain_t acp, struct urb * urb)
423{
424 return auerchain_submit_urb_list (acp, urb, 0);
425}
426
427/* cancel an urb which is submitted to the chain
428 the result is 0 if the urb is cancelled, or -EINPROGRESS if
Alan Sternb375a042005-07-29 16:11:07 -0400429 the function is successfully started.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700430*/
431static int auerchain_unlink_urb (pauerchain_t acp, struct urb * urb)
432{
433 unsigned long flags;
434 struct urb * urbp;
435 pauerchainelement_t acep;
436 struct list_head *tmp;
437
438 dbg ("auerchain_unlink_urb called");
439
440 /* search the chain of waiting elements */
441 spin_lock_irqsave (&acp->lock, flags);
442 list_for_each (tmp, &acp->waiting_list) {
443 acep = list_entry (tmp, auerchainelement_t, list);
444 if (acep->urbp == urb) {
445 list_del (tmp);
446 urb->context = acep->context;
447 urb->complete = acep->complete;
448 list_add_tail (&acep->list, &acp->free_list);
449 spin_unlock_irqrestore (&acp->lock, flags);
450 dbg ("unlink waiting urb");
451 urb->status = -ENOENT;
David Howells7d12e782006-10-05 14:55:46 +0100452 urb->complete (urb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700453 return 0;
454 }
455 }
456 /* not found. */
457 spin_unlock_irqrestore (&acp->lock, flags);
458
459 /* get the active urb */
460 acep = acp->active;
461 if (acep) {
462 urbp = acep->urbp;
463
464 /* check if we have to cancel the active urb */
465 if (urbp == urb) {
466 /* note that there is a race condition between the check above
467 and the unlink() call because of no lock. This race is harmless,
468 because the usb module will detect the unlink() after completion.
469 We can't use the acp->lock here because the completion function
470 wants to grab it.
471 */
472 dbg ("unlink active urb");
473 return usb_unlink_urb (urbp);
474 }
475 }
476
477 /* not found anyway
478 ... is some kind of success
479 */
480 dbg ("urb to unlink not found in chain");
481 return 0;
482}
483
484/* cancel all urbs which are in the chain.
485 this function must not be called from interrupt or completion handler.
486*/
487static void auerchain_unlink_all (pauerchain_t acp)
488{
489 unsigned long flags;
490 struct urb * urbp;
491 pauerchainelement_t acep;
492
493 dbg ("auerchain_unlink_all called");
494
495 /* clear the chain of waiting elements */
496 spin_lock_irqsave (&acp->lock, flags);
497 while (!list_empty (&acp->waiting_list)) {
498 /* get the next entry */
499 struct list_head *tmp = acp->waiting_list.next;
500 list_del (tmp);
501 acep = list_entry (tmp, auerchainelement_t, list);
502 urbp = acep->urbp;
503 urbp->context = acep->context;
504 urbp->complete = acep->complete;
505 list_add_tail (&acep->list, &acp->free_list);
506 spin_unlock_irqrestore (&acp->lock, flags);
507 dbg ("unlink waiting urb");
508 urbp->status = -ENOENT;
David Howells7d12e782006-10-05 14:55:46 +0100509 urbp->complete (urbp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700510 spin_lock_irqsave (&acp->lock, flags);
511 }
512 spin_unlock_irqrestore (&acp->lock, flags);
513
514 /* clear the active urb */
515 acep = acp->active;
516 if (acep) {
517 urbp = acep->urbp;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700518 dbg ("unlink active urb");
519 usb_kill_urb (urbp);
520 }
521}
522
523
524/* free the chain.
525 this function must not be called from interrupt or completion handler.
526*/
527static void auerchain_free (pauerchain_t acp)
528{
529 unsigned long flags;
530 pauerchainelement_t acep;
531
532 dbg ("auerchain_free called");
533
534 /* first, cancel all pending urbs */
535 auerchain_unlink_all (acp);
536
537 /* free the elements */
538 spin_lock_irqsave (&acp->lock, flags);
539 while (!list_empty (&acp->free_list)) {
540 /* get the next entry */
541 struct list_head *tmp = acp->free_list.next;
542 list_del (tmp);
543 spin_unlock_irqrestore (&acp->lock, flags);
544 acep = list_entry (tmp, auerchainelement_t, list);
545 kfree (acep);
546 spin_lock_irqsave (&acp->lock, flags);
547 }
548 spin_unlock_irqrestore (&acp->lock, flags);
549}
550
551
552/* Init the chain control structure */
553static void auerchain_init (pauerchain_t acp)
554{
555 /* init the chain data structure */
556 acp->active = NULL;
557 spin_lock_init (&acp->lock);
558 INIT_LIST_HEAD (&acp->waiting_list);
559 INIT_LIST_HEAD (&acp->free_list);
560}
561
562/* setup a chain.
563 It is assumed that there is no concurrency while setting up the chain
564 requirement: auerchain_init()
565*/
566static int auerchain_setup (pauerchain_t acp, unsigned int numElements)
567{
568 pauerchainelement_t acep;
569
570 dbg ("auerchain_setup called with %d elements", numElements);
571
572 /* fill the list of free elements */
573 for (;numElements; numElements--) {
Eric Sesterhenn80b6ca42006-02-27 21:29:43 +0100574 acep = kzalloc(sizeof(auerchainelement_t), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700575 if (!acep)
576 goto ac_fail;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700577 INIT_LIST_HEAD (&acep->list);
578 list_add_tail (&acep->list, &acp->free_list);
579 }
580 return 0;
581
582ac_fail:/* free the elements */
583 while (!list_empty (&acp->free_list)) {
584 /* get the next entry */
585 struct list_head *tmp = acp->free_list.next;
586 list_del (tmp);
587 acep = list_entry (tmp, auerchainelement_t, list);
588 kfree (acep);
589 }
590 return -ENOMEM;
591}
592
593
594/* completion handler for synchronous chained URBs */
David Howells7d12e782006-10-05 14:55:46 +0100595static void auerchain_blocking_completion (struct urb *urb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700596{
Ming Leicdc97792008-02-24 18:41:47 +0800597 pauerchain_chs_t pchs = urb->context;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700598 pchs->done = 1;
599 wmb();
600 wake_up (&pchs->wqh);
601}
602
603
604/* Starts chained urb and waits for completion or timeout */
605static int auerchain_start_wait_urb (pauerchain_t acp, struct urb *urb, int timeout, int* actual_length)
606{
607 auerchain_chs_t chs;
608 int status;
609
610 dbg ("auerchain_start_wait_urb called");
611 init_waitqueue_head (&chs.wqh);
612 chs.done = 0;
613
614 urb->context = &chs;
615 status = auerchain_submit_urb (acp, urb);
616 if (status)
617 /* something went wrong */
618 return status;
619
620 timeout = wait_event_timeout(chs.wqh, chs.done, timeout);
621
622 if (!timeout && !chs.done) {
623 if (urb->status != -EINPROGRESS) { /* No callback?!! */
624 dbg ("auerchain_start_wait_urb: raced timeout");
625 status = urb->status;
626 } else {
627 dbg ("auerchain_start_wait_urb: timeout");
628 auerchain_unlink_urb (acp, urb); /* remove urb safely */
629 status = -ETIMEDOUT;
630 }
631 } else
632 status = urb->status;
633
Jeff Garzikae97fec2007-07-17 01:08:29 -0400634 if (status >= 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700635 *actual_length = urb->actual_length;
636
637 return status;
638}
639
640
641/* auerchain_control_msg - Builds a control urb, sends it off and waits for completion
642 acp: pointer to the auerchain
643 dev: pointer to the usb device to send the message to
644 pipe: endpoint "pipe" to send the message to
645 request: USB message request value
646 requesttype: USB message request type value
647 value: USB message value
648 index: USB message index value
649 data: pointer to the data to send
650 size: length in bytes of the data to send
651 timeout: time to wait for the message to complete before timing out (if 0 the wait is forever)
652
653 This function sends a simple control message to a specified endpoint
654 and waits for the message to complete, or timeout.
655
656 If successful, it returns the transferred length, otherwise a negative error number.
657
658 Don't use this function from within an interrupt context, like a
659 bottom half handler. If you need an asynchronous message, or need to send
660 a message from within interrupt context, use auerchain_submit_urb()
661*/
662static int auerchain_control_msg (pauerchain_t acp, struct usb_device *dev, unsigned int pipe, __u8 request, __u8 requesttype,
663 __u16 value, __u16 index, void *data, __u16 size, int timeout)
664{
665 int ret;
666 struct usb_ctrlrequest *dr;
667 struct urb *urb;
Jeff Garzika6343af2007-07-17 05:39:58 -0400668 int uninitialized_var(length);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700669
670 dbg ("auerchain_control_msg");
671 dr = kmalloc (sizeof (struct usb_ctrlrequest), GFP_KERNEL);
672 if (!dr)
673 return -ENOMEM;
674 urb = usb_alloc_urb (0, GFP_KERNEL);
675 if (!urb) {
676 kfree (dr);
677 return -ENOMEM;
678 }
679
680 dr->bRequestType = requesttype;
681 dr->bRequest = request;
682 dr->wValue = cpu_to_le16 (value);
683 dr->wIndex = cpu_to_le16 (index);
684 dr->wLength = cpu_to_le16 (size);
685
686 usb_fill_control_urb (urb, dev, pipe, (unsigned char*)dr, data, size, /* build urb */
687 auerchain_blocking_completion, NULL);
688 ret = auerchain_start_wait_urb (acp, urb, timeout, &length);
689
690 usb_free_urb (urb);
691 kfree (dr);
692
693 if (ret < 0)
694 return ret;
695 else
696 return length;
697}
698
699
700/*-------------------------------------------------------------------*/
701/* Buffer List helper functions */
702
703/* free a single auerbuf */
704static void auerbuf_free (pauerbuf_t bp)
705{
Jesper Juhl1bc3c9e2005-04-18 17:39:34 -0700706 kfree(bp->bufp);
707 kfree(bp->dr);
Mariusz Kozlowski2891a512006-11-08 15:36:03 +0100708 usb_free_urb(bp->urbp);
Jesper Juhl1bc3c9e2005-04-18 17:39:34 -0700709 kfree(bp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700710}
711
712/* free the buffers from an auerbuf list */
713static void auerbuf_free_list (struct list_head *q)
714{
715 struct list_head *tmp;
716 struct list_head *p;
717 pauerbuf_t bp;
718
719 dbg ("auerbuf_free_list");
720 for (p = q->next; p != q;) {
721 bp = list_entry (p, auerbuf_t, buff_list);
722 tmp = p->next;
723 list_del (p);
724 p = tmp;
725 auerbuf_free (bp);
726 }
727}
728
729/* init the members of a list control block */
730static void auerbuf_init (pauerbufctl_t bcp)
731{
732 dbg ("auerbuf_init");
733 spin_lock_init (&bcp->lock);
734 INIT_LIST_HEAD (&bcp->free_buff_list);
735 INIT_LIST_HEAD (&bcp->rec_buff_list);
736}
737
738/* free all buffers from an auerbuf chain */
739static void auerbuf_free_buffers (pauerbufctl_t bcp)
740{
741 unsigned long flags;
742 dbg ("auerbuf_free_buffers");
743
744 spin_lock_irqsave (&bcp->lock, flags);
745
746 auerbuf_free_list (&bcp->free_buff_list);
747 auerbuf_free_list (&bcp->rec_buff_list);
748
749 spin_unlock_irqrestore (&bcp->lock, flags);
750}
751
752/* setup a list of buffers */
753/* requirement: auerbuf_init() */
754static int auerbuf_setup (pauerbufctl_t bcp, unsigned int numElements, unsigned int bufsize)
755{
756 pauerbuf_t bep = NULL;
757
758 dbg ("auerbuf_setup called with %d elements of %d bytes", numElements, bufsize);
759
760 /* fill the list of free elements */
761 for (;numElements; numElements--) {
Eric Sesterhenn80b6ca42006-02-27 21:29:43 +0100762 bep = kzalloc(sizeof(auerbuf_t), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700763 if (!bep)
764 goto bl_fail;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700765 bep->list = bcp;
766 INIT_LIST_HEAD (&bep->buff_list);
Jesper Juhl0e8eb0f2005-12-11 20:34:02 +0100767 bep->bufp = kmalloc (bufsize, GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700768 if (!bep->bufp)
769 goto bl_fail;
Robert P. J. Day5cbded52006-12-13 00:35:56 -0800770 bep->dr = kmalloc(sizeof (struct usb_ctrlrequest), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700771 if (!bep->dr)
772 goto bl_fail;
773 bep->urbp = usb_alloc_urb (0, GFP_KERNEL);
774 if (!bep->urbp)
775 goto bl_fail;
776 list_add_tail (&bep->buff_list, &bcp->free_buff_list);
777 }
778 return 0;
779
780bl_fail:/* not enough memory. Free allocated elements */
781 dbg ("auerbuf_setup: no more memory");
Mariusz Kozlowski5a3fcf52006-11-07 00:31:51 +0100782 auerbuf_free(bep);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700783 auerbuf_free_buffers (bcp);
784 return -ENOMEM;
785}
786
787/* insert a used buffer into the free list */
788static void auerbuf_releasebuf( pauerbuf_t bp)
789{
790 unsigned long flags;
791 pauerbufctl_t bcp = bp->list;
792 bp->retries = 0;
793
794 dbg ("auerbuf_releasebuf called");
795 spin_lock_irqsave (&bcp->lock, flags);
796 list_add_tail (&bp->buff_list, &bcp->free_buff_list);
797 spin_unlock_irqrestore (&bcp->lock, flags);
798}
799
800
801/*-------------------------------------------------------------------*/
802/* Completion handlers */
803
804/* Values of urb->status or results of usb_submit_urb():
8050 Initial, OK
806-EINPROGRESS during submission until end
807-ENOENT if urb is unlinked
Pete Zaitcev38e2bfc2006-09-18 22:49:02 -0700808-ETIME Device did not respond
Linus Torvalds1da177e2005-04-16 15:20:36 -0700809-ENOMEM Memory Overflow
810-ENODEV Specified USB-device or bus doesn't exist
811-ENXIO URB already queued
812-EINVAL a) Invalid transfer type specified (or not supported)
813 b) Invalid interrupt interval (0n256)
814-EAGAIN a) Specified ISO start frame too early
815 b) (using ISO-ASAP) Too much scheduled for the future wait some time and try again.
816-EFBIG Too much ISO frames requested (currently uhci900)
817-EPIPE Specified pipe-handle/Endpoint is already stalled
818-EMSGSIZE Endpoint message size is zero, do interface/alternate setting
819-EPROTO a) Bitstuff error
820 b) Unknown USB error
821-EILSEQ CRC mismatch
822-ENOSR Buffer error
823-EREMOTEIO Short packet detected
824-EXDEV ISO transfer only partially completed look at individual frame status for details
825-EINVAL ISO madness, if this happens: Log off and go home
826-EOVERFLOW babble
827*/
828
829/* check if a status code allows a retry */
830static int auerswald_status_retry (int status)
831{
832 switch (status) {
833 case 0:
Pete Zaitcev38e2bfc2006-09-18 22:49:02 -0700834 case -ETIME:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700835 case -EOVERFLOW:
836 case -EAGAIN:
837 case -EPIPE:
838 case -EPROTO:
839 case -EILSEQ:
840 case -ENOSR:
841 case -EREMOTEIO:
842 return 1; /* do a retry */
843 }
844 return 0; /* no retry possible */
845}
846
847/* Completion of asynchronous write block */
David Howells7d12e782006-10-05 14:55:46 +0100848static void auerchar_ctrlwrite_complete (struct urb * urb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700849{
Ming Leicdc97792008-02-24 18:41:47 +0800850 pauerbuf_t bp = urb->context;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700851 pauerswald_t cp = ((pauerswald_t)((char *)(bp->list)-(unsigned long)(&((pauerswald_t)0)->bufctl)));
852 dbg ("auerchar_ctrlwrite_complete called");
853
854 /* reuse the buffer */
855 auerbuf_releasebuf (bp);
856 /* Wake up all processes waiting for a buffer */
857 wake_up (&cp->bufferwait);
858}
859
860/* Completion handler for dummy retry packet */
David Howells7d12e782006-10-05 14:55:46 +0100861static void auerswald_ctrlread_wretcomplete (struct urb * urb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700862{
Ming Leicdc97792008-02-24 18:41:47 +0800863 pauerbuf_t bp = urb->context;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700864 pauerswald_t cp;
865 int ret;
Greg Kroah-Hartman22bea332007-07-18 10:58:02 -0700866 int status = urb->status;
867
Linus Torvalds1da177e2005-04-16 15:20:36 -0700868 dbg ("auerswald_ctrlread_wretcomplete called");
Greg Kroah-Hartman22bea332007-07-18 10:58:02 -0700869 dbg ("complete with status: %d", status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700870 cp = ((pauerswald_t)((char *)(bp->list)-(unsigned long)(&((pauerswald_t)0)->bufctl)));
871
872 /* check if it is possible to advance */
Greg Kroah-Hartman22bea332007-07-18 10:58:02 -0700873 if (!auerswald_status_retry(status) || !cp->usbdev) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700874 /* reuse the buffer */
Greg Kroah-Hartman22bea332007-07-18 10:58:02 -0700875 err ("control dummy: transmission error %d, can not retry", status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700876 auerbuf_releasebuf (bp);
877 /* Wake up all processes waiting for a buffer */
878 wake_up (&cp->bufferwait);
879 return;
880 }
881
882 /* fill the control message */
883 bp->dr->bRequestType = AUT_RREQ;
884 bp->dr->bRequest = AUV_RBLOCK;
885 bp->dr->wLength = bp->dr->wValue; /* temporary stored */
886 bp->dr->wValue = cpu_to_le16 (1); /* Retry Flag */
887 /* bp->dr->index = channel id; remains */
888 usb_fill_control_urb (bp->urbp, cp->usbdev, usb_rcvctrlpipe (cp->usbdev, 0),
889 (unsigned char*)bp->dr, bp->bufp, le16_to_cpu (bp->dr->wLength),
890 auerswald_ctrlread_complete,bp);
891
892 /* submit the control msg as next paket */
893 ret = auerchain_submit_urb_list (&cp->controlchain, bp->urbp, 1);
894 if (ret) {
895 dbg ("auerswald_ctrlread_complete: nonzero result of auerchain_submit_urb_list %d", ret);
896 bp->urbp->status = ret;
David Howells7d12e782006-10-05 14:55:46 +0100897 auerswald_ctrlread_complete (bp->urbp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700898 }
899}
900
901/* completion handler for receiving of control messages */
David Howells7d12e782006-10-05 14:55:46 +0100902static void auerswald_ctrlread_complete (struct urb * urb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700903{
904 unsigned int serviceid;
905 pauerswald_t cp;
906 pauerscon_t scp;
Ming Leicdc97792008-02-24 18:41:47 +0800907 pauerbuf_t bp = urb->context;
Greg Kroah-Hartman22bea332007-07-18 10:58:02 -0700908 int status = urb->status;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700909 int ret;
Greg Kroah-Hartman22bea332007-07-18 10:58:02 -0700910
Linus Torvalds1da177e2005-04-16 15:20:36 -0700911 dbg ("auerswald_ctrlread_complete called");
912
913 cp = ((pauerswald_t)((char *)(bp->list)-(unsigned long)(&((pauerswald_t)0)->bufctl)));
914
915 /* check if there is valid data in this urb */
Greg Kroah-Hartman22bea332007-07-18 10:58:02 -0700916 if (status) {
917 dbg ("complete with non-zero status: %d", status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700918 /* should we do a retry? */
Greg Kroah-Hartman22bea332007-07-18 10:58:02 -0700919 if (!auerswald_status_retry(status)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700920 || !cp->usbdev
921 || (cp->version < AUV_RETRY)
922 || (bp->retries >= AU_RETRIES)) {
923 /* reuse the buffer */
Greg Kroah-Hartman22bea332007-07-18 10:58:02 -0700924 err ("control read: transmission error %d, can not retry", status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700925 auerbuf_releasebuf (bp);
926 /* Wake up all processes waiting for a buffer */
927 wake_up (&cp->bufferwait);
928 return;
929 }
930 bp->retries++;
931 dbg ("Retry count = %d", bp->retries);
932 /* send a long dummy control-write-message to allow device firmware to react */
933 bp->dr->bRequestType = AUT_WREQ;
934 bp->dr->bRequest = AUV_DUMMY;
935 bp->dr->wValue = bp->dr->wLength; /* temporary storage */
936 // bp->dr->wIndex channel ID remains
937 bp->dr->wLength = cpu_to_le16 (32); /* >= 8 bytes */
938 usb_fill_control_urb (bp->urbp, cp->usbdev, usb_sndctrlpipe (cp->usbdev, 0),
939 (unsigned char*)bp->dr, bp->bufp, 32,
940 auerswald_ctrlread_wretcomplete,bp);
941
942 /* submit the control msg as next paket */
943 ret = auerchain_submit_urb_list (&cp->controlchain, bp->urbp, 1);
944 if (ret) {
945 dbg ("auerswald_ctrlread_complete: nonzero result of auerchain_submit_urb_list %d", ret);
946 bp->urbp->status = ret;
David Howells7d12e782006-10-05 14:55:46 +0100947 auerswald_ctrlread_wretcomplete (bp->urbp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700948 }
949 return;
950 }
951
952 /* get the actual bytecount (incl. headerbyte) */
953 bp->len = urb->actual_length;
954 serviceid = bp->bufp[0] & AUH_TYPEMASK;
955 dbg ("Paket with serviceid %d and %d bytes received", serviceid, bp->len);
956
957 /* dispatch the paket */
958 scp = cp->services[serviceid];
959 if (scp) {
960 /* look, Ma, a listener! */
961 scp->dispatch (scp, bp);
962 }
963
964 /* release the paket */
965 auerbuf_releasebuf (bp);
966 /* Wake up all processes waiting for a buffer */
967 wake_up (&cp->bufferwait);
968}
969
970/*-------------------------------------------------------------------*/
971/* Handling of Interrupt Endpoint */
972/* This interrupt Endpoint is used to inform the host about waiting
973 messages from the USB device.
974*/
975/* int completion handler. */
David Howells7d12e782006-10-05 14:55:46 +0100976static void auerswald_int_complete (struct urb * urb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700977{
978 unsigned long flags;
979 unsigned int channelid;
980 unsigned int bytecount;
981 int ret;
Greg Kroah-Hartman22bea332007-07-18 10:58:02 -0700982 int status = urb->status;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700983 pauerbuf_t bp = NULL;
Ming Leicdc97792008-02-24 18:41:47 +0800984 pauerswald_t cp = urb->context;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700985
Harvey Harrison441b62c2008-03-03 16:08:34 -0800986 dbg ("%s called", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700987
Greg Kroah-Hartman22bea332007-07-18 10:58:02 -0700988 switch (status) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700989 case 0:
990 /* success */
991 break;
992 case -ECONNRESET:
993 case -ENOENT:
994 case -ESHUTDOWN:
995 /* this urb is terminated, clean up */
Harvey Harrison441b62c2008-03-03 16:08:34 -0800996 dbg("%s - urb shutting down with status: %d", __func__, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700997 return;
998 default:
Harvey Harrison441b62c2008-03-03 16:08:34 -0800999 dbg("%s - nonzero urb status received: %d", __func__, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001000 goto exit;
1001 }
1002
1003 /* check if all needed data was received */
1004 if (urb->actual_length < AU_IRQMINSIZE) {
1005 dbg ("invalid data length received: %d bytes", urb->actual_length);
1006 goto exit;
1007 }
1008
1009 /* check the command code */
1010 if (cp->intbufp[0] != AU_IRQCMDID) {
1011 dbg ("invalid command received: %d", cp->intbufp[0]);
1012 goto exit;
1013 }
1014
1015 /* check the command type */
1016 if (cp->intbufp[1] != AU_BLOCKRDY) {
1017 dbg ("invalid command type received: %d", cp->intbufp[1]);
1018 goto exit;
1019 }
1020
1021 /* now extract the information */
1022 channelid = cp->intbufp[2];
1023 bytecount = (unsigned char)cp->intbufp[3];
1024 bytecount |= (unsigned char)cp->intbufp[4] << 8;
1025
1026 /* check the channel id */
1027 if (channelid >= AUH_TYPESIZE) {
1028 dbg ("invalid channel id received: %d", channelid);
1029 goto exit;
1030 }
1031
1032 /* check the byte count */
1033 if (bytecount > (cp->maxControlLength+AUH_SIZE)) {
1034 dbg ("invalid byte count received: %d", bytecount);
1035 goto exit;
1036 }
1037 dbg ("Service Channel = %d", channelid);
1038 dbg ("Byte Count = %d", bytecount);
1039
1040 /* get a buffer for the next data paket */
1041 spin_lock_irqsave (&cp->bufctl.lock, flags);
1042 if (!list_empty (&cp->bufctl.free_buff_list)) {
1043 /* yes: get the entry */
1044 struct list_head *tmp = cp->bufctl.free_buff_list.next;
1045 list_del (tmp);
1046 bp = list_entry (tmp, auerbuf_t, buff_list);
1047 }
1048 spin_unlock_irqrestore (&cp->bufctl.lock, flags);
1049
1050 /* if no buffer available: skip it */
1051 if (!bp) {
1052 dbg ("auerswald_int_complete: no data buffer available");
1053 /* can we do something more?
1054 This is a big problem: if this int packet is ignored, the
1055 device will wait forever and not signal any more data.
1056 The only real solution is: having enough buffers!
1057 Or perhaps temporary disabling the int endpoint?
1058 */
1059 goto exit;
1060 }
1061
1062 /* fill the control message */
1063 bp->dr->bRequestType = AUT_RREQ;
1064 bp->dr->bRequest = AUV_RBLOCK;
1065 bp->dr->wValue = cpu_to_le16 (0);
1066 bp->dr->wIndex = cpu_to_le16 (channelid | AUH_DIRECT | AUH_UNSPLIT);
1067 bp->dr->wLength = cpu_to_le16 (bytecount);
1068 usb_fill_control_urb (bp->urbp, cp->usbdev, usb_rcvctrlpipe (cp->usbdev, 0),
1069 (unsigned char*)bp->dr, bp->bufp, bytecount,
1070 auerswald_ctrlread_complete,bp);
1071
1072 /* submit the control msg */
1073 ret = auerchain_submit_urb (&cp->controlchain, bp->urbp);
1074 if (ret) {
1075 dbg ("auerswald_int_complete: nonzero result of auerchain_submit_urb %d", ret);
1076 bp->urbp->status = ret;
David Howells7d12e782006-10-05 14:55:46 +01001077 auerswald_ctrlread_complete( bp->urbp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001078 /* here applies the same problem as above: device locking! */
1079 }
1080exit:
1081 ret = usb_submit_urb (urb, GFP_ATOMIC);
1082 if (ret)
1083 err ("%s - usb_submit_urb failed with result %d",
Harvey Harrison441b62c2008-03-03 16:08:34 -08001084 __func__, ret);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001085}
1086
1087/* int memory deallocation
1088 NOTE: no mutex please!
1089*/
1090static void auerswald_int_free (pauerswald_t cp)
1091{
Jesper Juhl1bc3c9e2005-04-18 17:39:34 -07001092 if (cp->inturbp) {
1093 usb_free_urb(cp->inturbp);
1094 cp->inturbp = NULL;
1095 }
1096 kfree(cp->intbufp);
1097 cp->intbufp = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001098}
1099
1100/* This function is called to activate the interrupt
1101 endpoint. This function returns 0 if successful or an error code.
1102 NOTE: no mutex please!
1103*/
1104static int auerswald_int_open (pauerswald_t cp)
1105{
1106 int ret;
1107 struct usb_host_endpoint *ep;
1108 int irqsize;
1109 dbg ("auerswald_int_open");
1110
1111 ep = cp->usbdev->ep_in[AU_IRQENDP];
1112 if (!ep) {
1113 ret = -EFAULT;
1114 goto intoend;
1115 }
1116 irqsize = le16_to_cpu(ep->desc.wMaxPacketSize);
1117 cp->irqsize = irqsize;
1118
1119 /* allocate the urb and data buffer */
1120 if (!cp->inturbp) {
1121 cp->inturbp = usb_alloc_urb (0, GFP_KERNEL);
1122 if (!cp->inturbp) {
1123 ret = -ENOMEM;
1124 goto intoend;
1125 }
1126 }
1127 if (!cp->intbufp) {
Jesper Juhl0e8eb0f2005-12-11 20:34:02 +01001128 cp->intbufp = kmalloc (irqsize, GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001129 if (!cp->intbufp) {
1130 ret = -ENOMEM;
1131 goto intoend;
1132 }
1133 }
1134 /* setup urb */
1135 usb_fill_int_urb (cp->inturbp, cp->usbdev,
1136 usb_rcvintpipe (cp->usbdev,AU_IRQENDP), cp->intbufp,
1137 irqsize, auerswald_int_complete, cp, ep->desc.bInterval);
1138 /* start the urb */
1139 cp->inturbp->status = 0; /* needed! */
1140 ret = usb_submit_urb (cp->inturbp, GFP_KERNEL);
1141
1142intoend:
1143 if (ret < 0) {
1144 /* activation of interrupt endpoint has failed. Now clean up. */
1145 dbg ("auerswald_int_open: activation of int endpoint failed");
1146
1147 /* deallocate memory */
1148 auerswald_int_free (cp);
1149 }
1150 return ret;
1151}
1152
1153/* This function is called to deactivate the interrupt
1154 endpoint. This function returns 0 if successful or an error code.
1155 NOTE: no mutex please!
1156*/
1157static void auerswald_int_release (pauerswald_t cp)
1158{
1159 dbg ("auerswald_int_release");
1160
1161 /* stop the int endpoint */
Mariusz Kozlowski2891a512006-11-08 15:36:03 +01001162 usb_kill_urb (cp->inturbp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001163
1164 /* deallocate memory */
1165 auerswald_int_free (cp);
1166}
1167
1168/* --------------------------------------------------------------------- */
1169/* Helper functions */
1170
1171/* wake up waiting readers */
1172static void auerchar_disconnect (pauerscon_t scp)
1173{
1174 pauerchar_t ccp = ((pauerchar_t)((char *)(scp)-(unsigned long)(&((pauerchar_t)0)->scontext)));
1175 dbg ("auerchar_disconnect called");
1176 ccp->removed = 1;
1177 wake_up (&ccp->readwait);
1178}
1179
1180
1181/* dispatch a read paket to a waiting character device */
1182static void auerchar_ctrlread_dispatch (pauerscon_t scp, pauerbuf_t bp)
1183{
1184 unsigned long flags;
1185 pauerchar_t ccp;
1186 pauerbuf_t newbp = NULL;
1187 char * charp;
1188 dbg ("auerchar_ctrlread_dispatch called");
1189 ccp = ((pauerchar_t)((char *)(scp)-(unsigned long)(&((pauerchar_t)0)->scontext)));
1190
1191 /* get a read buffer from character device context */
1192 spin_lock_irqsave (&ccp->bufctl.lock, flags);
1193 if (!list_empty (&ccp->bufctl.free_buff_list)) {
1194 /* yes: get the entry */
1195 struct list_head *tmp = ccp->bufctl.free_buff_list.next;
1196 list_del (tmp);
1197 newbp = list_entry (tmp, auerbuf_t, buff_list);
1198 }
1199 spin_unlock_irqrestore (&ccp->bufctl.lock, flags);
1200
1201 if (!newbp) {
1202 dbg ("No read buffer available, discard paket!");
1203 return; /* no buffer, no dispatch */
1204 }
1205
1206 /* copy information to new buffer element
1207 (all buffers have the same length) */
1208 charp = newbp->bufp;
1209 newbp->bufp = bp->bufp;
1210 bp->bufp = charp;
1211 newbp->len = bp->len;
1212
1213 /* insert new buffer in read list */
1214 spin_lock_irqsave (&ccp->bufctl.lock, flags);
1215 list_add_tail (&newbp->buff_list, &ccp->bufctl.rec_buff_list);
1216 spin_unlock_irqrestore (&ccp->bufctl.lock, flags);
1217 dbg ("read buffer appended to rec_list");
1218
1219 /* wake up pending synchronous reads */
1220 wake_up (&ccp->readwait);
1221}
1222
1223
1224/* Delete an auerswald driver context */
1225static void auerswald_delete( pauerswald_t cp)
1226{
1227 dbg( "auerswald_delete");
1228 if (cp == NULL)
1229 return;
1230
1231 /* Wake up all processes waiting for a buffer */
1232 wake_up (&cp->bufferwait);
1233
1234 /* Cleaning up */
1235 auerswald_int_release (cp);
1236 auerchain_free (&cp->controlchain);
1237 auerbuf_free_buffers (&cp->bufctl);
1238
1239 /* release the memory */
1240 kfree( cp);
1241}
1242
1243
1244/* Delete an auerswald character context */
1245static void auerchar_delete( pauerchar_t ccp)
1246{
1247 dbg ("auerchar_delete");
1248 if (ccp == NULL)
1249 return;
1250
1251 /* wake up pending synchronous reads */
1252 ccp->removed = 1;
1253 wake_up (&ccp->readwait);
1254
1255 /* remove the read buffer */
1256 if (ccp->readbuf) {
1257 auerbuf_releasebuf (ccp->readbuf);
1258 ccp->readbuf = NULL;
1259 }
1260
1261 /* remove the character buffers */
1262 auerbuf_free_buffers (&ccp->bufctl);
1263
1264 /* release the memory */
1265 kfree( ccp);
1266}
1267
1268
1269/* add a new service to the device
1270 scp->id must be set!
1271 return: 0 if OK, else error code
1272*/
1273static int auerswald_addservice (pauerswald_t cp, pauerscon_t scp)
1274{
1275 int ret;
1276
1277 /* is the device available? */
1278 if (!cp->usbdev) {
1279 dbg ("usbdev == NULL");
1280 return -EIO; /*no: can not add a service, sorry*/
1281 }
1282
1283 /* is the service available? */
1284 if (cp->services[scp->id]) {
1285 dbg ("service is busy");
1286 return -EBUSY;
1287 }
1288
1289 /* device is available, service is free */
1290 cp->services[scp->id] = scp;
1291
1292 /* register service in device */
1293 ret = auerchain_control_msg(
1294 &cp->controlchain, /* pointer to control chain */
1295 cp->usbdev, /* pointer to device */
1296 usb_sndctrlpipe (cp->usbdev, 0), /* pipe to control endpoint */
1297 AUV_CHANNELCTL, /* USB message request value */
1298 AUT_WREQ, /* USB message request type value */
1299 0x01, /* open USB message value */
1300 scp->id, /* USB message index value */
1301 NULL, /* pointer to the data to send */
1302 0, /* length in bytes of the data to send */
1303 HZ * 2); /* time to wait for the message to complete before timing out */
1304 if (ret < 0) {
1305 dbg ("auerswald_addservice: auerchain_control_msg returned error code %d", ret);
1306 /* undo above actions */
1307 cp->services[scp->id] = NULL;
1308 return ret;
1309 }
1310
1311 dbg ("auerswald_addservice: channel open OK");
1312 return 0;
1313}
1314
1315
Michael Opdenacker59c51592007-05-09 08:57:56 +02001316/* remove a service from the device
Linus Torvalds1da177e2005-04-16 15:20:36 -07001317 scp->id must be set! */
1318static void auerswald_removeservice (pauerswald_t cp, pauerscon_t scp)
1319{
1320 dbg ("auerswald_removeservice called");
1321
1322 /* check if we have a service allocated */
1323 if (scp->id == AUH_UNASSIGNED)
1324 return;
1325
1326 /* If there is a device: close the channel */
1327 if (cp->usbdev) {
1328 /* Close the service channel inside the device */
1329 int ret = auerchain_control_msg(
1330 &cp->controlchain, /* pointer to control chain */
1331 cp->usbdev, /* pointer to device */
1332 usb_sndctrlpipe (cp->usbdev, 0), /* pipe to control endpoint */
1333 AUV_CHANNELCTL, /* USB message request value */
1334 AUT_WREQ, /* USB message request type value */
1335 0x00, // close /* USB message value */
1336 scp->id, /* USB message index value */
1337 NULL, /* pointer to the data to send */
1338 0, /* length in bytes of the data to send */
1339 HZ * 2); /* time to wait for the message to complete before timing out */
1340 if (ret < 0) {
1341 dbg ("auerswald_removeservice: auerchain_control_msg returned error code %d", ret);
1342 }
1343 else {
1344 dbg ("auerswald_removeservice: channel close OK");
1345 }
1346 }
1347
1348 /* remove the service from the device */
1349 cp->services[scp->id] = NULL;
1350 scp->id = AUH_UNASSIGNED;
1351}
1352
1353
1354/* --------------------------------------------------------------------- */
1355/* Char device functions */
1356
1357/* Open a new character device */
1358static int auerchar_open (struct inode *inode, struct file *file)
1359{
1360 int dtindex = iminor(inode);
1361 pauerswald_t cp = NULL;
1362 pauerchar_t ccp = NULL;
1363 struct usb_interface *intf;
1364 int ret;
1365
1366 /* minor number in range? */
1367 if (dtindex < 0) {
1368 return -ENODEV;
1369 }
1370 intf = usb_find_interface(&auerswald_driver, dtindex);
1371 if (!intf) {
1372 return -ENODEV;
1373 }
1374
1375 /* usb device available? */
1376 cp = usb_get_intfdata (intf);
1377 if (cp == NULL) {
1378 return -ENODEV;
1379 }
matthias@kaehlcke.netb994d7f2008-02-18 20:45:34 +01001380 if (mutex_lock_interruptible(&cp->mutex)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001381 return -ERESTARTSYS;
1382 }
1383
1384 /* we have access to the device. Now lets allocate memory */
Burman Yan66eb2e92006-12-04 15:22:40 -08001385 ccp = kzalloc(sizeof(auerchar_t), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001386 if (ccp == NULL) {
1387 err ("out of memory");
1388 ret = -ENOMEM;
1389 goto ofail;
1390 }
1391
1392 /* Initialize device descriptor */
matthias@kaehlcke.netfadec782008-02-18 20:45:36 +01001393 mutex_init(&ccp->mutex);
matthias@kaehlcke.net8a0f46b2008-02-18 20:45:35 +01001394 mutex_init(&ccp->readmutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001395 auerbuf_init (&ccp->bufctl);
1396 ccp->scontext.id = AUH_UNASSIGNED;
1397 ccp->scontext.dispatch = auerchar_ctrlread_dispatch;
1398 ccp->scontext.disconnect = auerchar_disconnect;
1399 init_waitqueue_head (&ccp->readwait);
1400
1401 ret = auerbuf_setup (&ccp->bufctl, AU_RBUFFERS, cp->maxControlLength+AUH_SIZE);
1402 if (ret) {
1403 goto ofail;
1404 }
1405
1406 cp->open_count++;
1407 ccp->auerdev = cp;
1408 dbg("open %s as /dev/%s", cp->dev_desc, cp->name);
matthias@kaehlcke.netb994d7f2008-02-18 20:45:34 +01001409 mutex_unlock(&cp->mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001410
1411 /* file IO stuff */
1412 file->f_pos = 0;
1413 file->private_data = ccp;
1414 return nonseekable_open(inode, file);
1415
1416 /* Error exit */
matthias@kaehlcke.netb994d7f2008-02-18 20:45:34 +01001417ofail: mutex_unlock(&cp->mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001418 auerchar_delete (ccp);
1419 return ret;
1420}
1421
1422
1423/* IOCTL functions */
1424static int auerchar_ioctl (struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
1425{
1426 pauerchar_t ccp = (pauerchar_t) file->private_data;
1427 int ret = 0;
1428 audevinfo_t devinfo;
1429 pauerswald_t cp = NULL;
1430 unsigned int u;
1431 unsigned int __user *user_arg = (unsigned int __user *)arg;
1432
1433 dbg ("ioctl");
1434
1435 /* get the mutexes */
matthias@kaehlcke.netfadec782008-02-18 20:45:36 +01001436 if (mutex_lock_interruptible(&ccp->mutex)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001437 return -ERESTARTSYS;
1438 }
1439 cp = ccp->auerdev;
1440 if (!cp) {
matthias@kaehlcke.netfadec782008-02-18 20:45:36 +01001441 mutex_unlock(&ccp->mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001442 return -ENODEV;
1443 }
matthias@kaehlcke.netb994d7f2008-02-18 20:45:34 +01001444 if (mutex_lock_interruptible(&cp->mutex)) {
matthias@kaehlcke.netfadec782008-02-18 20:45:36 +01001445 mutex_unlock(&ccp->mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001446 return -ERESTARTSYS;
1447 }
1448
1449 /* Check for removal */
1450 if (!cp->usbdev) {
matthias@kaehlcke.netb994d7f2008-02-18 20:45:34 +01001451 mutex_unlock(&cp->mutex);
matthias@kaehlcke.netfadec782008-02-18 20:45:36 +01001452 mutex_unlock(&ccp->mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001453 return -ENODEV;
1454 }
1455
1456 switch (cmd) {
1457
1458 /* return != 0 if Transmitt channel ready to send */
1459 case IOCTL_AU_TXREADY:
1460 dbg ("IOCTL_AU_TXREADY");
1461 u = ccp->auerdev
1462 && (ccp->scontext.id != AUH_UNASSIGNED)
1463 && !list_empty (&cp->bufctl.free_buff_list);
1464 ret = put_user (u, user_arg);
1465 break;
1466
1467 /* return != 0 if connected to a service channel */
1468 case IOCTL_AU_CONNECT:
1469 dbg ("IOCTL_AU_CONNECT");
1470 u = (ccp->scontext.id != AUH_UNASSIGNED);
1471 ret = put_user (u, user_arg);
1472 break;
1473
1474 /* return != 0 if Receive Data available */
1475 case IOCTL_AU_RXAVAIL:
1476 dbg ("IOCTL_AU_RXAVAIL");
1477 if (ccp->scontext.id == AUH_UNASSIGNED) {
1478 ret = -EIO;
1479 break;
1480 }
1481 u = 0; /* no data */
1482 if (ccp->readbuf) {
1483 int restlen = ccp->readbuf->len - ccp->readoffset;
1484 if (restlen > 0)
1485 u = 1;
1486 }
1487 if (!u) {
1488 if (!list_empty (&ccp->bufctl.rec_buff_list)) {
1489 u = 1;
1490 }
1491 }
1492 ret = put_user (u, user_arg);
1493 break;
1494
1495 /* return the max. buffer length for the device */
1496 case IOCTL_AU_BUFLEN:
1497 dbg ("IOCTL_AU_BUFLEN");
1498 u = cp->maxControlLength;
1499 ret = put_user (u, user_arg);
1500 break;
1501
1502 /* requesting a service channel */
1503 case IOCTL_AU_SERVREQ:
1504 dbg ("IOCTL_AU_SERVREQ");
1505 /* requesting a service means: release the previous one first */
1506 auerswald_removeservice (cp, &ccp->scontext);
1507 /* get the channel number */
1508 ret = get_user (u, user_arg);
1509 if (ret) {
1510 break;
1511 }
1512 if ((u < AUH_FIRSTUSERCH) || (u >= AUH_TYPESIZE)) {
1513 ret = -EIO;
1514 break;
1515 }
1516 dbg ("auerchar service request parameters are ok");
1517 ccp->scontext.id = u;
1518
1519 /* request the service now */
1520 ret = auerswald_addservice (cp, &ccp->scontext);
1521 if (ret) {
1522 /* no: revert service entry */
1523 ccp->scontext.id = AUH_UNASSIGNED;
1524 }
1525 break;
1526
1527 /* get a string descriptor for the device */
1528 case IOCTL_AU_DEVINFO:
1529 dbg ("IOCTL_AU_DEVINFO");
1530 if (copy_from_user (&devinfo, (void __user *) arg, sizeof (audevinfo_t))) {
1531 ret = -EFAULT;
1532 break;
1533 }
1534 u = strlen(cp->dev_desc)+1;
1535 if (u > devinfo.bsize) {
1536 u = devinfo.bsize;
1537 }
1538 ret = copy_to_user(devinfo.buf, cp->dev_desc, u) ? -EFAULT : 0;
1539 break;
1540
1541 /* get the max. string descriptor length */
1542 case IOCTL_AU_SLEN:
1543 dbg ("IOCTL_AU_SLEN");
1544 u = AUSI_DLEN;
1545 ret = put_user (u, user_arg);
1546 break;
1547
1548 default:
1549 dbg ("IOCTL_AU_UNKNOWN");
1550 ret = -ENOIOCTLCMD;
1551 break;
1552 }
1553 /* release the mutexes */
matthias@kaehlcke.netb994d7f2008-02-18 20:45:34 +01001554 mutex_unlock(&cp->mutex);
matthias@kaehlcke.netfadec782008-02-18 20:45:36 +01001555 mutex_unlock(&ccp->mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001556 return ret;
1557}
1558
1559/* Read data from the device */
1560static ssize_t auerchar_read (struct file *file, char __user *buf, size_t count, loff_t * ppos)
1561{
1562 unsigned long flags;
1563 pauerchar_t ccp = (pauerchar_t) file->private_data;
1564 pauerbuf_t bp = NULL;
1565 wait_queue_t wait;
1566
1567 dbg ("auerchar_read");
1568
1569 /* Error checking */
1570 if (!ccp)
1571 return -EIO;
1572 if (*ppos)
1573 return -ESPIPE;
1574 if (count == 0)
1575 return 0;
1576
1577 /* get the mutex */
matthias@kaehlcke.netfadec782008-02-18 20:45:36 +01001578 if (mutex_lock_interruptible(&ccp->mutex))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001579 return -ERESTARTSYS;
1580
1581 /* Can we expect to read something? */
1582 if (ccp->scontext.id == AUH_UNASSIGNED) {
matthias@kaehlcke.netfadec782008-02-18 20:45:36 +01001583 mutex_unlock(&ccp->mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001584 return -EIO;
1585 }
1586
1587 /* only one reader per device allowed */
matthias@kaehlcke.net8a0f46b2008-02-18 20:45:35 +01001588 if (mutex_lock_interruptible(&ccp->readmutex)) {
matthias@kaehlcke.netfadec782008-02-18 20:45:36 +01001589 mutex_unlock(&ccp->mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001590 return -ERESTARTSYS;
1591 }
1592
1593 /* read data from readbuf, if available */
1594doreadbuf:
1595 bp = ccp->readbuf;
1596 if (bp) {
1597 /* read the maximum bytes */
1598 int restlen = bp->len - ccp->readoffset;
1599 if (restlen < 0)
1600 restlen = 0;
1601 if (count > restlen)
1602 count = restlen;
1603 if (count) {
1604 if (copy_to_user (buf, bp->bufp+ccp->readoffset, count)) {
1605 dbg ("auerswald_read: copy_to_user failed");
matthias@kaehlcke.net8a0f46b2008-02-18 20:45:35 +01001606 mutex_unlock(&ccp->readmutex);
matthias@kaehlcke.netfadec782008-02-18 20:45:36 +01001607 mutex_unlock(&ccp->mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001608 return -EFAULT;
1609 }
1610 }
1611 /* advance the read offset */
1612 ccp->readoffset += count;
1613 restlen -= count;
1614 // reuse the read buffer
1615 if (restlen <= 0) {
1616 auerbuf_releasebuf (bp);
1617 ccp->readbuf = NULL;
1618 }
1619 /* return with number of bytes read */
1620 if (count) {
matthias@kaehlcke.net8a0f46b2008-02-18 20:45:35 +01001621 mutex_unlock(&ccp->readmutex);
matthias@kaehlcke.netfadec782008-02-18 20:45:36 +01001622 mutex_unlock(&ccp->mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001623 return count;
1624 }
1625 }
1626
1627 /* a read buffer is not available. Try to get the next data block. */
1628doreadlist:
1629 /* Preparing for sleep */
1630 init_waitqueue_entry (&wait, current);
1631 set_current_state (TASK_INTERRUPTIBLE);
1632 add_wait_queue (&ccp->readwait, &wait);
1633
1634 bp = NULL;
1635 spin_lock_irqsave (&ccp->bufctl.lock, flags);
1636 if (!list_empty (&ccp->bufctl.rec_buff_list)) {
1637 /* yes: get the entry */
1638 struct list_head *tmp = ccp->bufctl.rec_buff_list.next;
1639 list_del (tmp);
1640 bp = list_entry (tmp, auerbuf_t, buff_list);
1641 }
1642 spin_unlock_irqrestore (&ccp->bufctl.lock, flags);
1643
1644 /* have we got data? */
1645 if (bp) {
1646 ccp->readbuf = bp;
1647 ccp->readoffset = AUH_SIZE; /* for headerbyte */
1648 set_current_state (TASK_RUNNING);
1649 remove_wait_queue (&ccp->readwait, &wait);
1650 goto doreadbuf; /* now we can read! */
1651 }
1652
1653 /* no data available. Should we wait? */
1654 if (file->f_flags & O_NONBLOCK) {
1655 dbg ("No read buffer available, returning -EAGAIN");
1656 set_current_state (TASK_RUNNING);
1657 remove_wait_queue (&ccp->readwait, &wait);
matthias@kaehlcke.net8a0f46b2008-02-18 20:45:35 +01001658 mutex_unlock(&ccp->readmutex);
matthias@kaehlcke.netfadec782008-02-18 20:45:36 +01001659 mutex_unlock(&ccp->mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001660 return -EAGAIN; /* nonblocking, no data available */
1661 }
1662
1663 /* yes, we should wait! */
matthias@kaehlcke.netfadec782008-02-18 20:45:36 +01001664 mutex_unlock(&ccp->mutex); /* allow other operations while we wait */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001665 schedule();
1666 remove_wait_queue (&ccp->readwait, &wait);
1667 if (signal_pending (current)) {
1668 /* waked up by a signal */
matthias@kaehlcke.net8a0f46b2008-02-18 20:45:35 +01001669 mutex_unlock(&ccp->readmutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001670 return -ERESTARTSYS;
1671 }
1672
1673 /* Anything left to read? */
1674 if ((ccp->scontext.id == AUH_UNASSIGNED) || ccp->removed) {
matthias@kaehlcke.net8a0f46b2008-02-18 20:45:35 +01001675 mutex_unlock(&ccp->readmutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001676 return -EIO;
1677 }
1678
matthias@kaehlcke.netfadec782008-02-18 20:45:36 +01001679 if (mutex_lock_interruptible(&ccp->mutex)) {
matthias@kaehlcke.net8a0f46b2008-02-18 20:45:35 +01001680 mutex_unlock(&ccp->readmutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001681 return -ERESTARTSYS;
1682 }
1683
1684 /* try to read the incoming data again */
1685 goto doreadlist;
1686}
1687
1688
1689/* Write a data block into the right service channel of the device */
1690static ssize_t auerchar_write (struct file *file, const char __user *buf, size_t len, loff_t *ppos)
1691{
1692 pauerchar_t ccp = (pauerchar_t) file->private_data;
1693 pauerswald_t cp = NULL;
1694 pauerbuf_t bp;
1695 unsigned long flags;
1696 int ret;
1697 wait_queue_t wait;
1698
Al Viro53b3de12005-12-15 09:17:34 +00001699 dbg ("auerchar_write %zd bytes", len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001700
1701 /* Error checking */
1702 if (!ccp)
1703 return -EIO;
1704 if (*ppos)
1705 return -ESPIPE;
1706 if (len == 0)
1707 return 0;
1708
1709write_again:
1710 /* get the mutex */
matthias@kaehlcke.netfadec782008-02-18 20:45:36 +01001711 if (mutex_lock_interruptible(&ccp->mutex))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001712 return -ERESTARTSYS;
1713
1714 /* Can we expect to write something? */
1715 if (ccp->scontext.id == AUH_UNASSIGNED) {
matthias@kaehlcke.netfadec782008-02-18 20:45:36 +01001716 mutex_unlock(&ccp->mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001717 return -EIO;
1718 }
1719
1720 cp = ccp->auerdev;
1721 if (!cp) {
matthias@kaehlcke.netfadec782008-02-18 20:45:36 +01001722 mutex_unlock(&ccp->mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001723 return -ERESTARTSYS;
1724 }
matthias@kaehlcke.netb994d7f2008-02-18 20:45:34 +01001725 if (mutex_lock_interruptible(&cp->mutex)) {
matthias@kaehlcke.netfadec782008-02-18 20:45:36 +01001726 mutex_unlock(&ccp->mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001727 return -ERESTARTSYS;
1728 }
1729 if (!cp->usbdev) {
matthias@kaehlcke.netb994d7f2008-02-18 20:45:34 +01001730 mutex_unlock(&cp->mutex);
matthias@kaehlcke.netfadec782008-02-18 20:45:36 +01001731 mutex_unlock(&ccp->mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001732 return -EIO;
1733 }
1734 /* Prepare for sleep */
1735 init_waitqueue_entry (&wait, current);
1736 set_current_state (TASK_INTERRUPTIBLE);
1737 add_wait_queue (&cp->bufferwait, &wait);
1738
1739 /* Try to get a buffer from the device pool.
1740 We can't use a buffer from ccp->bufctl because the write
1741 command will last beond a release() */
1742 bp = NULL;
1743 spin_lock_irqsave (&cp->bufctl.lock, flags);
1744 if (!list_empty (&cp->bufctl.free_buff_list)) {
1745 /* yes: get the entry */
1746 struct list_head *tmp = cp->bufctl.free_buff_list.next;
1747 list_del (tmp);
1748 bp = list_entry (tmp, auerbuf_t, buff_list);
1749 }
1750 spin_unlock_irqrestore (&cp->bufctl.lock, flags);
1751
1752 /* are there any buffers left? */
1753 if (!bp) {
matthias@kaehlcke.netb994d7f2008-02-18 20:45:34 +01001754 mutex_unlock(&cp->mutex);
matthias@kaehlcke.netfadec782008-02-18 20:45:36 +01001755 mutex_unlock(&ccp->mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001756
1757 /* NONBLOCK: don't wait */
1758 if (file->f_flags & O_NONBLOCK) {
1759 set_current_state (TASK_RUNNING);
1760 remove_wait_queue (&cp->bufferwait, &wait);
1761 return -EAGAIN;
1762 }
1763
1764 /* BLOCKING: wait */
1765 schedule();
1766 remove_wait_queue (&cp->bufferwait, &wait);
1767 if (signal_pending (current)) {
1768 /* waked up by a signal */
1769 return -ERESTARTSYS;
1770 }
1771 goto write_again;
1772 } else {
1773 set_current_state (TASK_RUNNING);
1774 remove_wait_queue (&cp->bufferwait, &wait);
1775 }
1776
1777 /* protect against too big write requests */
1778 if (len > cp->maxControlLength)
1779 len = cp->maxControlLength;
1780
1781 /* Fill the buffer */
1782 if (copy_from_user ( bp->bufp+AUH_SIZE, buf, len)) {
1783 dbg ("copy_from_user failed");
1784 auerbuf_releasebuf (bp);
1785 /* Wake up all processes waiting for a buffer */
1786 wake_up (&cp->bufferwait);
matthias@kaehlcke.netb994d7f2008-02-18 20:45:34 +01001787 mutex_unlock(&cp->mutex);
matthias@kaehlcke.netfadec782008-02-18 20:45:36 +01001788 mutex_unlock(&ccp->mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001789 return -EFAULT;
1790 }
1791
1792 /* set the header byte */
1793 *(bp->bufp) = ccp->scontext.id | AUH_DIRECT | AUH_UNSPLIT;
1794
1795 /* Set the transfer Parameters */
1796 bp->len = len+AUH_SIZE;
1797 bp->dr->bRequestType = AUT_WREQ;
1798 bp->dr->bRequest = AUV_WBLOCK;
1799 bp->dr->wValue = cpu_to_le16 (0);
1800 bp->dr->wIndex = cpu_to_le16 (ccp->scontext.id | AUH_DIRECT | AUH_UNSPLIT);
1801 bp->dr->wLength = cpu_to_le16 (len+AUH_SIZE);
1802 usb_fill_control_urb (bp->urbp, cp->usbdev, usb_sndctrlpipe (cp->usbdev, 0),
1803 (unsigned char*)bp->dr, bp->bufp, len+AUH_SIZE,
1804 auerchar_ctrlwrite_complete, bp);
1805 /* up we go */
1806 ret = auerchain_submit_urb (&cp->controlchain, bp->urbp);
matthias@kaehlcke.netb994d7f2008-02-18 20:45:34 +01001807 mutex_unlock(&cp->mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001808 if (ret) {
1809 dbg ("auerchar_write: nonzero result of auerchain_submit_urb %d", ret);
1810 auerbuf_releasebuf (bp);
1811 /* Wake up all processes waiting for a buffer */
1812 wake_up (&cp->bufferwait);
matthias@kaehlcke.netfadec782008-02-18 20:45:36 +01001813 mutex_unlock(&ccp->mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001814 return -EIO;
1815 }
1816 else {
1817 dbg ("auerchar_write: Write OK");
matthias@kaehlcke.netfadec782008-02-18 20:45:36 +01001818 mutex_unlock(&ccp->mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001819 return len;
1820 }
1821}
1822
1823
1824/* Close a character device */
1825static int auerchar_release (struct inode *inode, struct file *file)
1826{
1827 pauerchar_t ccp = (pauerchar_t) file->private_data;
1828 pauerswald_t cp;
1829 dbg("release");
1830
matthias@kaehlcke.netfadec782008-02-18 20:45:36 +01001831 mutex_lock(&ccp->mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001832 cp = ccp->auerdev;
1833 if (cp) {
matthias@kaehlcke.netb994d7f2008-02-18 20:45:34 +01001834 mutex_lock(&cp->mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001835 /* remove an open service */
1836 auerswald_removeservice (cp, &ccp->scontext);
1837 /* detach from device */
1838 if ((--cp->open_count <= 0) && (cp->usbdev == NULL)) {
1839 /* usb device waits for removal */
matthias@kaehlcke.netb994d7f2008-02-18 20:45:34 +01001840 mutex_unlock(&cp->mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001841 auerswald_delete (cp);
1842 } else {
matthias@kaehlcke.netb994d7f2008-02-18 20:45:34 +01001843 mutex_unlock(&cp->mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001844 }
1845 cp = NULL;
1846 ccp->auerdev = NULL;
1847 }
matthias@kaehlcke.netfadec782008-02-18 20:45:36 +01001848 mutex_unlock(&ccp->mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001849 auerchar_delete (ccp);
1850
1851 return 0;
1852}
1853
1854
1855/*----------------------------------------------------------------------*/
1856/* File operation structure */
Luiz Fernando N. Capitulino066202d2006-08-05 20:37:11 -03001857static const struct file_operations auerswald_fops =
Linus Torvalds1da177e2005-04-16 15:20:36 -07001858{
1859 .owner = THIS_MODULE,
1860 .llseek = no_llseek,
1861 .read = auerchar_read,
1862 .write = auerchar_write,
1863 .ioctl = auerchar_ioctl,
1864 .open = auerchar_open,
1865 .release = auerchar_release,
1866};
1867
1868static struct usb_class_driver auerswald_class = {
Greg Kroah-Hartmand6e5bcf2005-06-20 21:15:16 -07001869 .name = "auer%d",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001870 .fops = &auerswald_fops,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001871 .minor_base = AUER_MINOR_BASE,
1872};
1873
1874
1875/* --------------------------------------------------------------------- */
1876/* Special USB driver functions */
1877
1878/* Probe if this driver wants to serve an USB device
1879
1880 This entry point is called whenever a new device is attached to the bus.
1881 Then the device driver has to create a new instance of its internal data
1882 structures for the new device.
1883
1884 The dev argument specifies the device context, which contains pointers
1885 to all USB descriptors. The interface argument specifies the interface
1886 number. If a USB driver wants to bind itself to a particular device and
1887 interface it has to return a pointer. This pointer normally references
1888 the device driver's context structure.
1889
1890 Probing normally is done by checking the vendor and product identifications
1891 or the class and subclass definitions. If they match the interface number
1892 is compared with the ones supported by the driver. When probing is done
1893 class based it might be necessary to parse some more USB descriptors because
1894 the device properties can differ in a wide range.
1895*/
1896static int auerswald_probe (struct usb_interface *intf,
1897 const struct usb_device_id *id)
1898{
1899 struct usb_device *usbdev = interface_to_usbdev(intf);
1900 pauerswald_t cp = NULL;
1901 unsigned int u = 0;
1902 __le16 *pbuf;
1903 int ret;
1904
1905 dbg ("probe: vendor id 0x%x, device id 0x%x",
1906 le16_to_cpu(usbdev->descriptor.idVendor),
1907 le16_to_cpu(usbdev->descriptor.idProduct));
1908
1909 /* we use only the first -and only- interface */
1910 if (intf->altsetting->desc.bInterfaceNumber != 0)
1911 return -ENODEV;
1912
1913 /* allocate memory for our device and initialize it */
Burman Yan66eb2e92006-12-04 15:22:40 -08001914 cp = kzalloc (sizeof(auerswald_t), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001915 if (cp == NULL) {
1916 err ("out of memory");
1917 goto pfail;
1918 }
1919
1920 /* Initialize device descriptor */
matthias@kaehlcke.netb994d7f2008-02-18 20:45:34 +01001921 mutex_init(&cp->mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001922 cp->usbdev = usbdev;
1923 auerchain_init (&cp->controlchain);
1924 auerbuf_init (&cp->bufctl);
1925 init_waitqueue_head (&cp->bufferwait);
1926
1927 ret = usb_register_dev(intf, &auerswald_class);
1928 if (ret) {
1929 err ("Not able to get a minor for this device.");
1930 goto pfail;
1931 }
1932
1933 /* Give the device a name */
1934 sprintf (cp->name, "usb/auer%d", intf->minor);
1935
1936 /* Store the index */
1937 cp->dtindex = intf->minor;
1938
1939 /* Get the usb version of the device */
1940 cp->version = le16_to_cpu(cp->usbdev->descriptor.bcdDevice);
1941 dbg ("Version is %X", cp->version);
1942
1943 /* allow some time to settle the device */
1944 msleep(334);
1945
1946 /* Try to get a suitable textual description of the device */
1947 /* Device name:*/
1948 ret = usb_string( cp->usbdev, AUSI_DEVICE, cp->dev_desc, AUSI_DLEN-1);
1949 if (ret >= 0) {
1950 u += ret;
1951 /* Append Serial Number */
1952 memcpy(&cp->dev_desc[u], ",Ser# ", 6);
1953 u += 6;
1954 ret = usb_string( cp->usbdev, AUSI_SERIALNR, &cp->dev_desc[u], AUSI_DLEN-u-1);
1955 if (ret >= 0) {
1956 u += ret;
1957 /* Append subscriber number */
1958 memcpy(&cp->dev_desc[u], ", ", 2);
1959 u += 2;
1960 ret = usb_string( cp->usbdev, AUSI_MSN, &cp->dev_desc[u], AUSI_DLEN-u-1);
1961 if (ret >= 0) {
1962 u += ret;
1963 }
1964 }
1965 }
1966 cp->dev_desc[u] = '\0';
1967 info("device is a %s", cp->dev_desc);
1968
1969 /* get the maximum allowed control transfer length */
Robert P. J. Day5cbded52006-12-13 00:35:56 -08001970 pbuf = kmalloc(2, GFP_KERNEL); /* use an allocated buffer because of urb target */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001971 if (!pbuf) {
1972 err( "out of memory");
1973 goto pfail;
1974 }
1975 ret = usb_control_msg(cp->usbdev, /* pointer to device */
1976 usb_rcvctrlpipe( cp->usbdev, 0 ), /* pipe to control endpoint */
1977 AUV_GETINFO, /* USB message request value */
1978 AUT_RREQ, /* USB message request type value */
1979 0, /* USB message value */
1980 AUDI_MBCTRANS, /* USB message index value */
1981 pbuf, /* pointer to the receive buffer */
1982 2, /* length of the buffer */
1983 2000); /* time to wait for the message to complete before timing out */
1984 if (ret == 2) {
1985 cp->maxControlLength = le16_to_cpup(pbuf);
1986 kfree(pbuf);
1987 dbg("setup: max. allowed control transfersize is %d bytes", cp->maxControlLength);
1988 } else {
1989 kfree(pbuf);
1990 err("setup: getting max. allowed control transfer length failed with error %d", ret);
1991 goto pfail;
1992 }
1993
1994 /* allocate a chain for the control messages */
1995 if (auerchain_setup (&cp->controlchain, AUCH_ELEMENTS)) {
1996 err ("out of memory");
1997 goto pfail;
1998 }
1999
2000 /* allocate buffers for control messages */
2001 if (auerbuf_setup (&cp->bufctl, AU_RBUFFERS, cp->maxControlLength+AUH_SIZE)) {
2002 err ("out of memory");
2003 goto pfail;
2004 }
2005
2006 /* start the interrupt endpoint */
2007 if (auerswald_int_open (cp)) {
2008 err ("int endpoint failed");
2009 goto pfail;
2010 }
2011
2012 /* all OK */
2013 usb_set_intfdata (intf, cp);
2014 return 0;
2015
2016 /* Error exit: clean up the memory */
2017pfail: auerswald_delete (cp);
2018 return -EIO;
2019}
2020
2021
2022/* Disconnect driver from a served device
2023
2024 This function is called whenever a device which was served by this driver
2025 is disconnected.
2026
2027 The argument dev specifies the device context and the driver_context
2028 returns a pointer to the previously registered driver_context of the
2029 probe function. After returning from the disconnect function the USB
2030 framework completely deallocates all data structures associated with
2031 this device. So especially the usb_device structure must not be used
2032 any longer by the usb driver.
2033*/
2034static void auerswald_disconnect (struct usb_interface *intf)
2035{
2036 pauerswald_t cp = usb_get_intfdata (intf);
2037 unsigned int u;
2038
2039 usb_set_intfdata (intf, NULL);
2040 if (!cp)
2041 return;
2042
Linus Torvalds1da177e2005-04-16 15:20:36 -07002043 /* give back our USB minor number */
2044 usb_deregister_dev(intf, &auerswald_class);
2045
matthias@kaehlcke.netb994d7f2008-02-18 20:45:34 +01002046 mutex_lock(&cp->mutex);
Alan Sternd4ead162007-05-22 11:46:41 -04002047 info ("device /dev/%s now disconnecting", cp->name);
2048
Linus Torvalds1da177e2005-04-16 15:20:36 -07002049 /* Stop the interrupt endpoint */
2050 auerswald_int_release (cp);
2051
2052 /* remove the control chain allocated in auerswald_probe
2053 This has the benefit of
2054 a) all pending (a)synchronous urbs are unlinked
2055 b) all buffers dealing with urbs are reclaimed
2056 */
2057 auerchain_free (&cp->controlchain);
2058
2059 if (cp->open_count == 0) {
2060 /* nobody is using this device. So we can clean up now */
matthias@kaehlcke.netb994d7f2008-02-18 20:45:34 +01002061 mutex_unlock(&cp->mutex);
2062 /* mutex_unlock() is possible here because no other task
2063 can open the device (see above). I don't want
2064 to kfree() a locked mutex. */
2065
Linus Torvalds1da177e2005-04-16 15:20:36 -07002066 auerswald_delete (cp);
2067 } else {
2068 /* device is used. Remove the pointer to the
2069 usb device (it's not valid any more). The last
2070 release() will do the clean up */
2071 cp->usbdev = NULL;
matthias@kaehlcke.netb994d7f2008-02-18 20:45:34 +01002072 mutex_unlock(&cp->mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002073 /* Terminate waiting writers */
2074 wake_up (&cp->bufferwait);
2075 /* Inform all waiting readers */
2076 for ( u = 0; u < AUH_TYPESIZE; u++) {
2077 pauerscon_t scp = cp->services[u];
2078 if (scp)
2079 scp->disconnect( scp);
2080 }
2081 }
2082}
2083
2084/* Descriptor for the devices which are served by this driver.
2085 NOTE: this struct is parsed by the usbmanager install scripts.
2086 Don't change without caution!
2087*/
2088static struct usb_device_id auerswald_ids [] = {
2089 { USB_DEVICE (ID_AUERSWALD, 0x00C0) }, /* COMpact 2104 USB */
2090 { USB_DEVICE (ID_AUERSWALD, 0x00DB) }, /* COMpact 4410/2206 USB */
Andrew Morton885e7742006-01-17 15:37:22 -08002091 { USB_DEVICE (ID_AUERSWALD, 0x00DC) }, /* COMpact 4406 DSL */
2092 { USB_DEVICE (ID_AUERSWALD, 0x00DD) }, /* COMpact 2204 USB */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002093 { USB_DEVICE (ID_AUERSWALD, 0x00F1) }, /* Comfort 2000 System Telephone */
2094 { USB_DEVICE (ID_AUERSWALD, 0x00F2) }, /* Comfort 1200 System Telephone */
2095 { } /* Terminating entry */
2096};
2097
2098/* Standard module device table */
2099MODULE_DEVICE_TABLE (usb, auerswald_ids);
2100
2101/* Standard usb driver struct */
2102static struct usb_driver auerswald_driver = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002103 .name = "auerswald",
2104 .probe = auerswald_probe,
2105 .disconnect = auerswald_disconnect,
2106 .id_table = auerswald_ids,
2107};
2108
2109
2110/* --------------------------------------------------------------------- */
2111/* Module loading/unloading */
2112
2113/* Driver initialisation. Called after module loading.
2114 NOTE: there is no concurrency at _init
2115*/
2116static int __init auerswald_init (void)
2117{
2118 int result;
2119 dbg ("init");
2120
2121 /* register driver at the USB subsystem */
2122 result = usb_register (&auerswald_driver);
2123 if (result < 0) {
2124 err ("driver could not be registered");
2125 return -1;
2126 }
2127 return 0;
2128}
2129
2130/* Driver deinit. Called before module removal.
2131 NOTE: there is no concurrency at _cleanup
2132*/
2133static void __exit auerswald_cleanup (void)
2134{
2135 dbg ("cleanup");
2136 usb_deregister (&auerswald_driver);
2137}
2138
2139/* --------------------------------------------------------------------- */
2140/* Linux device driver module description */
2141
2142MODULE_AUTHOR (DRIVER_AUTHOR);
2143MODULE_DESCRIPTION (DRIVER_DESC);
2144MODULE_LICENSE ("GPL");
2145
2146module_init (auerswald_init);
2147module_exit (auerswald_cleanup);
2148
2149/* --------------------------------------------------------------------- */
2150