1 /*****************************************************************************/
3 * auerchar.c -- Auerswald PBX/System Telephone character interface.
5 * Copyright (C) 2002 Wolfgang Mües (wolfgang@iksw-muees.de)
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.
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.
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.
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.
24 /*****************************************************************************/
26 #undef DEBUG /* include debug macros until it's done */
27 #include <linux/usb.h>
30 #include <linux/slab.h>
31 #include <asm/uaccess.h> /* user area access functions */
33 /*-------------------------------------------------------------------*/
35 /* wake up waiting readers */
36 static void auerchar_disconnect(struct auerscon *scp)
38 struct auerchar *ccp =((struct auerchar *) ((char *) (scp) - (unsigned long) (&((struct auerchar *) 0)->scontext)));
39 dbg("auerchar_disconnect called");
41 wake_up(&ccp->readwait);
45 /* dispatch a read paket to a waiting character device */
46 static void auerchar_ctrlread_dispatch(struct auerscon *scp,
51 struct auerbuf *newbp = NULL;
53 dbg("auerchar_ctrlread_dispatch called");
54 ccp =((struct auerchar *) ((char *) (scp) - (unsigned long)(&((struct auerchar *) 0)->scontext)));
56 /* get a read buffer from character device context */
57 newbp = auerbuf_getbuf(&ccp->bufctl);
59 dbg("No read buffer available, discard paket!");
60 return; /* no buffer, no dispatch */
63 /* copy information to new buffer element
64 (all buffers have the same length) */
66 newbp->bufp = bp->bufp;
70 /* insert new buffer in read list */
71 spin_lock_irqsave(&ccp->bufctl.lock, flags);
72 list_add_tail(&newbp->buff_list, &ccp->bufctl.rec_buff_list);
73 spin_unlock_irqrestore(&ccp->bufctl.lock, flags);
74 dbg("read buffer appended to rec_list");
76 /* wake up pending synchronous reads */
77 wake_up(&ccp->readwait);
81 /* Delete an auerswald character context */
82 void auerchar_delete(struct auerchar *ccp)
84 dbg("auerchar_delete");
88 /* wake up pending synchronous reads */
90 wake_up(&ccp->readwait);
92 /* remove the read buffer */
94 auerbuf_releasebuf(ccp->readbuf);
98 /* remove the character buffers */
99 auerbuf_free_buffers(&ccp->bufctl);
101 /* release the memory */
106 /* --------------------------------------------------------------------- */
107 /* Char device functions */
109 /* Open a new character device */
110 int auerchar_open(struct inode *inode, struct file *file)
112 int dtindex = MINOR(inode->i_rdev) - AUER_MINOR_BASE;
113 struct auerswald *cp = NULL;
114 struct auerchar *ccp = NULL;
117 /* minor number in range? */
118 if ((dtindex < 0) || (dtindex >= AUER_MAX_DEVICES)) {
121 /* usb device available? */
122 if (down_interruptible(&auerdev_table_mutex)) {
125 cp = auerdev_table[dtindex];
127 up(&auerdev_table_mutex);
130 if (down_interruptible(&cp->mutex)) {
131 up(&auerdev_table_mutex);
134 up(&auerdev_table_mutex);
136 /* we have access to the device. Now lets allocate memory */
137 ccp = (struct auerchar *) kmalloc(sizeof(struct auerchar), GFP_KERNEL);
139 err("out of memory");
144 /* Initialize device descriptor */
145 memset(ccp, 0, sizeof(struct auerchar));
146 init_MUTEX(&ccp->mutex);
147 init_MUTEX(&ccp->readmutex);
148 auerbuf_init(&ccp->bufctl);
149 ccp->scontext.id = AUH_UNASSIGNED;
150 ccp->scontext.dispatch = auerchar_ctrlread_dispatch;
151 ccp->scontext.disconnect = auerchar_disconnect;
152 init_waitqueue_head(&ccp->readwait);
155 auerbuf_setup(&ccp->bufctl, AU_RBUFFERS,
156 cp->maxControlLength + AUH_SIZE);
163 dbg("open %s as /dev/usb/%s", cp->dev_desc, cp->name);
168 file->private_data = ccp;
172 ofail:up(&cp->mutex);
173 auerchar_delete(ccp);
178 /* IOCTL functions */
179 int auerchar_ioctl(struct inode *inode, struct file *file,
180 unsigned int cmd, unsigned long arg)
182 struct auerchar *ccp = (struct auerchar *) file->private_data;
184 struct audevinfo devinfo;
185 struct auerswald *cp = NULL;
189 /* get the mutexes */
190 if (down_interruptible(&ccp->mutex)) {
198 if (down_interruptible(&cp->mutex)) {
203 /* Check for removal */
212 /* return != 0 if Transmitt channel ready to send */
213 case IOCTL_AU_TXREADY:
214 dbg("IOCTL_AU_TXREADY");
215 u = ccp->auerdev && (ccp->scontext.id != AUH_UNASSIGNED)
216 && !list_empty(&cp->bufctl.free_buff_list);
217 ret = put_user(u, (unsigned int *) arg);
220 /* return != 0 if connected to a service channel */
221 case IOCTL_AU_CONNECT:
222 dbg("IOCTL_AU_CONNECT");
223 u = (ccp->scontext.id != AUH_UNASSIGNED);
224 ret = put_user(u, (unsigned int *) arg);
227 /* return != 0 if Receive Data available */
228 case IOCTL_AU_RXAVAIL:
229 dbg("IOCTL_AU_RXAVAIL");
230 if (ccp->scontext.id == AUH_UNASSIGNED) {
236 int restlen = ccp->readbuf->len - ccp->readoffset;
241 if (!list_empty(&ccp->bufctl.rec_buff_list)) {
245 ret = put_user(u, (unsigned int *) arg);
248 /* return the max. buffer length for the device */
249 case IOCTL_AU_BUFLEN:
250 dbg("IOCTL_AU_BUFLEN");
251 u = cp->maxControlLength;
252 ret = put_user(u, (unsigned int *) arg);
255 /* requesting a service channel */
256 case IOCTL_AU_SERVREQ:
257 dbg("IOCTL_AU_SERVREQ");
258 /* requesting a service means: release the previous one first */
259 auerswald_removeservice(cp, &ccp->scontext);
260 /* get the channel number */
261 ret = get_user(u, (unsigned int *) arg);
265 if ((u < AUH_FIRSTUSERCH) || (u >= AUH_TYPESIZE)) {
269 dbg("auerchar service request parameters are ok");
270 ccp->scontext.id = u;
272 /* request the service now */
273 ret = auerswald_addservice(cp, &ccp->scontext);
275 /* no: revert service entry */
276 ccp->scontext.id = AUH_UNASSIGNED;
280 /* get a string descriptor for the device */
281 case IOCTL_AU_DEVINFO:
282 dbg("IOCTL_AU_DEVINFO");
284 (&devinfo, (void *) arg, sizeof(struct audevinfo))) {
288 u = strlen(cp->dev_desc) + 1;
289 if (u > devinfo.bsize) {
292 ret = copy_to_user(devinfo.buf, cp->dev_desc, u);
295 /* get the max. string descriptor length */
297 dbg("IOCTL_AU_SLEN");
299 ret = put_user(u, (unsigned int *) arg);
303 dbg("IOCTL_AU_UNKNOWN");
307 /* release the mutexes */
314 /* Seek is not supported */
315 loff_t auerchar_llseek(struct file * file, loff_t offset, int origin)
317 dbg("auerchar_seek");
322 /* Read data from the device */
323 ssize_t auerchar_read(struct file * file, char *buf, size_t count,
327 struct auerchar *ccp = (struct auerchar *) file->private_data;
328 struct auerbuf *bp = NULL;
331 dbg("auerchar_read");
342 if (down_interruptible(&ccp->mutex))
345 /* Can we expect to read something? */
346 if (ccp->scontext.id == AUH_UNASSIGNED) {
351 /* only one reader per device allowed */
352 if (down_interruptible(&ccp->readmutex)) {
357 /* read data from readbuf, if available */
361 /* read the maximum bytes */
362 int restlen = bp->len - ccp->readoffset;
369 (buf, bp->bufp + ccp->readoffset, count)) {
370 dbg("auerswald_read: copy_to_user failed");
376 /* advance the read offset */
377 ccp->readoffset += count;
379 // reuse the read buffer
381 auerbuf_releasebuf(bp);
384 /* return with number of bytes read */
392 /* a read buffer is not available. Try to get the next data block. */
394 /* Preparing for sleep */
395 init_waitqueue_entry(&wait, current);
396 set_current_state(TASK_INTERRUPTIBLE);
397 add_wait_queue(&ccp->readwait, &wait);
400 spin_lock_irqsave(&ccp->bufctl.lock, flags);
401 if (!list_empty(&ccp->bufctl.rec_buff_list)) {
402 /* yes: get the entry */
403 struct list_head *tmp = ccp->bufctl.rec_buff_list.next;
405 bp = list_entry(tmp, struct auerbuf, buff_list);
407 spin_unlock_irqrestore(&ccp->bufctl.lock, flags);
409 /* have we got data? */
412 ccp->readoffset = AUH_SIZE; /* for headerbyte */
413 set_current_state(TASK_RUNNING);
414 remove_wait_queue(&ccp->readwait, &wait);
415 goto doreadbuf; /* now we can read! */
418 /* no data available. Should we wait? */
419 if (file->f_flags & O_NONBLOCK) {
420 dbg("No read buffer available, returning -EAGAIN");
421 set_current_state(TASK_RUNNING);
422 remove_wait_queue(&ccp->readwait, &wait);
425 return -EAGAIN; /* nonblocking, no data available */
428 /* yes, we should wait! */
429 up(&ccp->mutex); /* allow other operations while we wait */
431 remove_wait_queue(&ccp->readwait, &wait);
432 if (signal_pending(current)) {
433 /* waked up by a signal */
438 /* Anything left to read? */
439 if ((ccp->scontext.id == AUH_UNASSIGNED) || ccp->removed) {
444 if (down_interruptible(&ccp->mutex)) {
449 /* try to read the incomming data again */
454 /* Write a data block into the right service channel of the device */
455 ssize_t auerchar_write(struct file *file, const char *buf, size_t len,
458 struct auerchar *ccp = (struct auerchar *) file->private_data;
459 struct auerswald *cp = NULL;
464 dbg("auerchar_write %d bytes", len);
476 if (down_interruptible(&ccp->mutex))
479 /* Can we expect to write something? */
480 if (ccp->scontext.id == AUH_UNASSIGNED) {
490 if (down_interruptible(&cp->mutex)) {
499 /* Prepare for sleep */
500 init_waitqueue_entry(&wait, current);
501 set_current_state(TASK_INTERRUPTIBLE);
502 add_wait_queue(&cp->bufferwait, &wait);
504 /* Try to get a buffer from the device pool.
505 We can't use a buffer from ccp->bufctl because the write
506 command will last beond a release() */
507 bp = auerbuf_getbuf(&cp->bufctl);
508 /* are there any buffers left? */
513 /* NONBLOCK: don't wait */
514 if (file->f_flags & O_NONBLOCK) {
515 set_current_state(TASK_RUNNING);
516 remove_wait_queue(&cp->bufferwait, &wait);
522 remove_wait_queue(&cp->bufferwait, &wait);
523 if (signal_pending(current)) {
524 /* waked up by a signal */
529 set_current_state(TASK_RUNNING);
530 remove_wait_queue(&cp->bufferwait, &wait);
533 /* protect against too big write requests */
534 if (len > cp->maxControlLength)
535 len = cp->maxControlLength;
537 /* Fill the buffer */
538 if (copy_from_user(bp->bufp + AUH_SIZE, buf, len)) {
539 dbg("copy_from_user failed");
540 auerbuf_releasebuf(bp);
541 /* Wake up all processes waiting for a buffer */
542 wake_up(&cp->bufferwait);
548 /* set the header byte */
549 *(bp->bufp) = ccp->scontext.id | AUH_DIRECT | AUH_UNSPLIT;
551 /* Set the transfer Parameters */
552 bp->len = len + AUH_SIZE;
553 bp->dr->bRequestType = AUT_WREQ;
554 bp->dr->bRequest = AUV_WBLOCK;
555 bp->dr->wValue = cpu_to_le16(0);
557 cpu_to_le16(ccp->scontext.id | AUH_DIRECT | AUH_UNSPLIT);
558 bp->dr->wLength = cpu_to_le16(len + AUH_SIZE);
559 FILL_CONTROL_URB(bp->urbp, cp->usbdev,
560 usb_sndctrlpipe(cp->usbdev, 0),
561 (unsigned char *) bp->dr, bp->bufp,
562 len + AUH_SIZE, auerchar_ctrlwrite_complete, bp);
564 ret = auerchain_submit_urb(&cp->controlchain, bp->urbp);
567 dbg("auerchar_write: nonzero result of auerchain_submit_urb %d", ret);
568 auerbuf_releasebuf(bp);
569 /* Wake up all processes waiting for a buffer */
570 wake_up(&cp->bufferwait);
574 dbg("auerchar_write: Write OK");
581 /* Close a character device */
582 int auerchar_release(struct inode *inode, struct file *file)
584 struct auerchar *ccp = (struct auerchar *) file->private_data;
585 struct auerswald *cp;
588 /* get the mutexes */
589 if (down_interruptible(&ccp->mutex)) {
594 if (down_interruptible(&cp->mutex)) {
598 /* remove an open service */
599 auerswald_removeservice(cp, &ccp->scontext);
600 /* detach from device */
601 if ((--cp->open_count <= 0) && (cp->usbdev == NULL)) {
602 /* usb device waits for removal */
604 auerswald_delete(cp);
612 auerchar_delete(ccp);