1 /*****************************************************************************/
2 /*
3  *      auerchar.c  --  Auerswald PBX/System Telephone character interface.
4  *
5  *      Copyright (C) 2002  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 #undef DEBUG			/* include debug macros until it's done */
27 #include <linux/usb.h>
28 #include "auerchar.h"
29 #include "auermain.h"
30 #include <linux/slab.h>
31 #include <asm/uaccess.h>	/* user area access functions */
32 
33 /*-------------------------------------------------------------------*/
34 
35 /* wake up waiting readers */
auerchar_disconnect(struct auerscon * scp)36 static void auerchar_disconnect(struct auerscon *scp)
37 {
38 	struct auerchar *ccp =((struct auerchar *) ((char *) (scp) - (unsigned long) (&((struct auerchar *) 0)->scontext)));
39 	dbg("auerchar_disconnect called");
40 	ccp->removed = 1;
41 	wake_up(&ccp->readwait);
42 }
43 
44 
45 /* dispatch a read paket to a waiting character device */
auerchar_ctrlread_dispatch(struct auerscon * scp,struct auerbuf * bp)46 static void auerchar_ctrlread_dispatch(struct auerscon *scp,
47 				       struct auerbuf *bp)
48 {
49 	unsigned long flags;
50 	struct auerchar *ccp;
51 	struct auerbuf *newbp = NULL;
52 	char *charp;
53 	dbg("auerchar_ctrlread_dispatch called");
54 	ccp =((struct auerchar *) ((char *) (scp) - (unsigned long)(&((struct auerchar *) 0)->scontext)));
55 
56 	/* get a read buffer from character device context */
57 	newbp = auerbuf_getbuf(&ccp->bufctl);
58 	if (!newbp) {
59 		dbg("No read buffer available, discard paket!");
60 		return;		/* no buffer, no dispatch */
61 	}
62 
63 	/* copy information to new buffer element
64 	   (all buffers have the same length) */
65 	charp = newbp->bufp;
66 	newbp->bufp = bp->bufp;
67 	bp->bufp = charp;
68 	newbp->len = bp->len;
69 
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");
75 
76 	/* wake up pending synchronous reads */
77 	wake_up(&ccp->readwait);
78 }
79 
80 
81 /* Delete an auerswald character context */
auerchar_delete(struct auerchar * ccp)82 void auerchar_delete(struct auerchar *ccp)
83 {
84 	dbg("auerchar_delete");
85 	if (ccp == NULL)
86 		return;
87 
88 	/* wake up pending synchronous reads */
89 	ccp->removed = 1;
90 	wake_up(&ccp->readwait);
91 
92 	/* remove the read buffer */
93 	if (ccp->readbuf) {
94 		auerbuf_releasebuf(ccp->readbuf);
95 		ccp->readbuf = NULL;
96 	}
97 
98 	/* remove the character buffers */
99 	auerbuf_free_buffers(&ccp->bufctl);
100 
101 	/* release the memory */
102 	kfree(ccp);
103 }
104 
105 
106 /* --------------------------------------------------------------------- */
107 /* Char device functions                                                 */
108 
109 /* Open a new character device */
auerchar_open(struct inode * inode,struct file * file)110 int auerchar_open(struct inode *inode, struct file *file)
111 {
112 	int dtindex = MINOR(inode->i_rdev) - AUER_MINOR_BASE;
113 	struct auerswald *cp = NULL;
114 	struct auerchar *ccp = NULL;
115 	int ret;
116 
117 	/* minor number in range? */
118 	if ((dtindex < 0) || (dtindex >= AUER_MAX_DEVICES)) {
119 		return -ENODEV;
120 	}
121 	/* usb device available? */
122 	if (down_interruptible(&auerdev_table_mutex)) {
123 		return -ERESTARTSYS;
124 	}
125 	cp = auerdev_table[dtindex];
126 	if (cp == NULL) {
127 		up(&auerdev_table_mutex);
128 		return -ENODEV;
129 	}
130 	if (down_interruptible(&cp->mutex)) {
131 		up(&auerdev_table_mutex);
132 		return -ERESTARTSYS;
133 	}
134 	up(&auerdev_table_mutex);
135 
136 	/* we have access to the device. Now lets allocate memory */
137 	ccp = (struct auerchar *) kmalloc(sizeof(struct auerchar), GFP_KERNEL);
138 	if (ccp == NULL) {
139 		err("out of memory");
140 		ret = -ENOMEM;
141 		goto ofail;
142 	}
143 
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);
153 
154 	ret =
155 	    auerbuf_setup(&ccp->bufctl, AU_RBUFFERS,
156 			  cp->maxControlLength + AUH_SIZE);
157 	if (ret) {
158 		goto ofail;
159 	}
160 
161 	cp->open_count++;
162 	ccp->auerdev = cp;
163 	dbg("open %s as /dev/usb/%s", cp->dev_desc, cp->name);
164 	up(&cp->mutex);
165 
166 	/* file IO stuff */
167 	file->f_pos = 0;
168 	file->private_data = ccp;
169 	return 0;
170 
171 	/* Error exit */
172       ofail:up(&cp->mutex);
173 	auerchar_delete(ccp);
174 	return ret;
175 }
176 
177 
178 /* IOCTL functions */
auerchar_ioctl(struct inode * inode,struct file * file,unsigned int cmd,unsigned long arg)179 int auerchar_ioctl(struct inode *inode, struct file *file,
180 		   unsigned int cmd, unsigned long arg)
181 {
182 	struct auerchar *ccp = (struct auerchar *) file->private_data;
183 	int ret = 0;
184 	struct audevinfo devinfo;
185 	struct auerswald *cp = NULL;
186 	unsigned int u;
187 	dbg("ioctl");
188 
189 	/* get the mutexes */
190 	if (down_interruptible(&ccp->mutex)) {
191 		return -ERESTARTSYS;
192 	}
193 	cp = ccp->auerdev;
194 	if (!cp) {
195 		up(&ccp->mutex);
196 		return -ENODEV;
197 	}
198 	if (down_interruptible(&cp->mutex)) {
199 		up(&ccp->mutex);
200 		return -ERESTARTSYS;
201 	}
202 
203 	/* Check for removal */
204 	if (!cp->usbdev) {
205 		up(&cp->mutex);
206 		up(&ccp->mutex);
207 		return -ENODEV;
208 	}
209 
210 	switch (cmd) {
211 
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);
218 		break;
219 
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);
225 		break;
226 
227 		/* return != 0 if Receive Data available */
228 	case IOCTL_AU_RXAVAIL:
229 		dbg("IOCTL_AU_RXAVAIL");
230 		if (ccp->scontext.id == AUH_UNASSIGNED) {
231 			ret = -EIO;
232 			break;
233 		}
234 		u = 0;		/* no data */
235 		if (ccp->readbuf) {
236 			int restlen = ccp->readbuf->len - ccp->readoffset;
237 			if (restlen > 0)
238 				u = 1;
239 		}
240 		if (!u) {
241 			if (!list_empty(&ccp->bufctl.rec_buff_list)) {
242 				u = 1;
243 			}
244 		}
245 		ret = put_user(u, (unsigned int *) arg);
246 		break;
247 
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);
253 		break;
254 
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);
262 		if (ret) {
263 			break;
264 		}
265 		if ((u < AUH_FIRSTUSERCH) || (u >= AUH_TYPESIZE)) {
266 			ret = -EIO;
267 			break;
268 		}
269 		dbg("auerchar service request parameters are ok");
270 		ccp->scontext.id = u;
271 
272 		/* request the service now */
273 		ret = auerswald_addservice(cp, &ccp->scontext);
274 		if (ret) {
275 			/* no: revert service entry */
276 			ccp->scontext.id = AUH_UNASSIGNED;
277 		}
278 		break;
279 
280 		/* get a string descriptor for the device */
281 	case IOCTL_AU_DEVINFO:
282 		dbg("IOCTL_AU_DEVINFO");
283 		if (copy_from_user
284 		    (&devinfo, (void *) arg, sizeof(struct audevinfo))) {
285 			ret = -EFAULT;
286 			break;
287 		}
288 		u = strlen(cp->dev_desc) + 1;
289 		if (u > devinfo.bsize) {
290 			u = devinfo.bsize;
291 		}
292 		ret = copy_to_user(devinfo.buf, cp->dev_desc, u);
293 		break;
294 
295 		/* get the max. string descriptor length */
296 	case IOCTL_AU_SLEN:
297 		dbg("IOCTL_AU_SLEN");
298 		u = AUSI_DLEN;
299 		ret = put_user(u, (unsigned int *) arg);
300 		break;
301 
302 	default:
303 		dbg("IOCTL_AU_UNKNOWN");
304 		ret = -ENOIOCTLCMD;
305 		break;
306 	}
307 	/* release the mutexes */
308 	up(&cp->mutex);
309 	up(&ccp->mutex);
310 	return ret;
311 }
312 
313 
314 /* Seek is not supported */
auerchar_llseek(struct file * file,loff_t offset,int origin)315 loff_t auerchar_llseek(struct file * file, loff_t offset, int origin)
316 {
317 	dbg("auerchar_seek");
318 	return -ESPIPE;
319 }
320 
321 
322 /* Read data from the device */
auerchar_read(struct file * file,char * buf,size_t count,loff_t * ppos)323 ssize_t auerchar_read(struct file * file, char *buf, size_t count,
324 		      loff_t * ppos)
325 {
326 	unsigned long flags;
327 	struct auerchar *ccp = (struct auerchar *) file->private_data;
328 	struct auerbuf *bp = NULL;
329 	wait_queue_t wait;
330 
331 	dbg("auerchar_read");
332 
333 	/* Error checking */
334 	if (!ccp)
335 		return -EIO;
336 	if (*ppos)
337 		return -ESPIPE;
338 	if (count == 0)
339 		return 0;
340 
341 	/* get the mutex */
342 	if (down_interruptible(&ccp->mutex))
343 		return -ERESTARTSYS;
344 
345 	/* Can we expect to read something? */
346 	if (ccp->scontext.id == AUH_UNASSIGNED) {
347 		up(&ccp->mutex);
348 		return -EIO;
349 	}
350 
351 	/* only one reader per device allowed */
352 	if (down_interruptible(&ccp->readmutex)) {
353 		up(&ccp->mutex);
354 		return -ERESTARTSYS;
355 	}
356 
357 	/* read data from readbuf, if available */
358       doreadbuf:
359 	bp = ccp->readbuf;
360 	if (bp) {
361 		/* read the maximum bytes */
362 		int restlen = bp->len - ccp->readoffset;
363 		if (restlen < 0)
364 			restlen = 0;
365 		if (count > restlen)
366 			count = restlen;
367 		if (count) {
368 			if (copy_to_user
369 			    (buf, bp->bufp + ccp->readoffset, count)) {
370 				dbg("auerswald_read: copy_to_user failed");
371 				up(&ccp->readmutex);
372 				up(&ccp->mutex);
373 				return -EFAULT;
374 			}
375 		}
376 		/* advance the read offset */
377 		ccp->readoffset += count;
378 		restlen -= count;
379 		// reuse the read buffer
380 		if (restlen <= 0) {
381 			auerbuf_releasebuf(bp);
382 			ccp->readbuf = NULL;
383 		}
384 		/* return with number of bytes read */
385 		if (count) {
386 			up(&ccp->readmutex);
387 			up(&ccp->mutex);
388 			return count;
389 		}
390 	}
391 
392 	/* a read buffer is not available. Try to get the next data block. */
393       doreadlist:
394 	/* Preparing for sleep */
395 	init_waitqueue_entry(&wait, current);
396 	set_current_state(TASK_INTERRUPTIBLE);
397 	add_wait_queue(&ccp->readwait, &wait);
398 
399 	bp = NULL;
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;
404 		list_del(tmp);
405 		bp = list_entry(tmp, struct auerbuf, buff_list);
406 	}
407 	spin_unlock_irqrestore(&ccp->bufctl.lock, flags);
408 
409 	/* have we got data? */
410 	if (bp) {
411 		ccp->readbuf = bp;
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! */
416 	}
417 
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);
423 		up(&ccp->readmutex);
424 		up(&ccp->mutex);
425 		return -EAGAIN;	/* nonblocking, no data available */
426 	}
427 
428 	/* yes, we should wait! */
429 	up(&ccp->mutex);	/* allow other operations while we wait */
430 	schedule();
431 	remove_wait_queue(&ccp->readwait, &wait);
432 	if (signal_pending(current)) {
433 		/* waked up by a signal */
434 		up(&ccp->readmutex);
435 		return -ERESTARTSYS;
436 	}
437 
438 	/* Anything left to read? */
439 	if ((ccp->scontext.id == AUH_UNASSIGNED) || ccp->removed) {
440 		up(&ccp->readmutex);
441 		return -EIO;
442 	}
443 
444 	if (down_interruptible(&ccp->mutex)) {
445 		up(&ccp->readmutex);
446 		return -ERESTARTSYS;
447 	}
448 
449 	/* try to read the incomming data again */
450 	goto doreadlist;
451 }
452 
453 
454 /* Write a data block into the right service channel of the device */
auerchar_write(struct file * file,const char * buf,size_t len,loff_t * ppos)455 ssize_t auerchar_write(struct file *file, const char *buf, size_t len,
456 		       loff_t * ppos)
457 {
458 	struct auerchar *ccp = (struct auerchar *) file->private_data;
459 	struct auerswald *cp = NULL;
460 	struct auerbuf *bp;
461 	int ret;
462 	wait_queue_t wait;
463 
464 	dbg("auerchar_write %d bytes", len);
465 
466 	/* Error checking */
467 	if (!ccp)
468 		return -EIO;
469 	if (*ppos)
470 		return -ESPIPE;
471 	if (len == 0)
472 		return 0;
473 
474       write_again:
475 	/* get the mutex */
476 	if (down_interruptible(&ccp->mutex))
477 		return -ERESTARTSYS;
478 
479 	/* Can we expect to write something? */
480 	if (ccp->scontext.id == AUH_UNASSIGNED) {
481 		up(&ccp->mutex);
482 		return -EIO;
483 	}
484 
485 	cp = ccp->auerdev;
486 	if (!cp) {
487 		up(&ccp->mutex);
488 		return -ERESTARTSYS;
489 	}
490 	if (down_interruptible(&cp->mutex)) {
491 		up(&ccp->mutex);
492 		return -ERESTARTSYS;
493 	}
494 	if (!cp->usbdev) {
495 		up(&cp->mutex);
496 		up(&ccp->mutex);
497 		return -EIO;
498 	}
499 	/* Prepare for sleep */
500 	init_waitqueue_entry(&wait, current);
501 	set_current_state(TASK_INTERRUPTIBLE);
502 	add_wait_queue(&cp->bufferwait, &wait);
503 
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? */
509 	if (!bp) {
510 		up(&cp->mutex);
511 		up(&ccp->mutex);
512 
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);
517 			return -EAGAIN;
518 		}
519 
520 		/* BLOCKING: wait */
521 		schedule();
522 		remove_wait_queue(&cp->bufferwait, &wait);
523 		if (signal_pending(current)) {
524 			/* waked up by a signal */
525 			return -ERESTARTSYS;
526 		}
527 		goto write_again;
528 	} else {
529 		set_current_state(TASK_RUNNING);
530 		remove_wait_queue(&cp->bufferwait, &wait);
531 	}
532 
533 	/* protect against too big write requests */
534 	if (len > cp->maxControlLength)
535 		len = cp->maxControlLength;
536 
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);
543 		up(&cp->mutex);
544 		up(&ccp->mutex);
545 		return -EIO;
546 	}
547 
548 	/* set the header byte */
549 	*(bp->bufp) = ccp->scontext.id | AUH_DIRECT | AUH_UNSPLIT;
550 
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);
556 	bp->dr->wIndex =
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);
563 	/* up we go */
564 	ret = auerchain_submit_urb(&cp->controlchain, bp->urbp);
565 	up(&cp->mutex);
566 	if (ret) {
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);
571 		up(&ccp->mutex);
572 		return -EIO;
573 	} else {
574 		dbg("auerchar_write: Write OK");
575 		up(&ccp->mutex);
576 		return len;
577 	}
578 }
579 
580 
581 /* Close a character device */
auerchar_release(struct inode * inode,struct file * file)582 int auerchar_release(struct inode *inode, struct file *file)
583 {
584 	struct auerchar *ccp = (struct auerchar *) file->private_data;
585 	struct auerswald *cp;
586 	dbg("release");
587 
588 	/* get the mutexes */
589 	if (down_interruptible(&ccp->mutex)) {
590 		return -ERESTARTSYS;
591 	}
592 	cp = ccp->auerdev;
593 	if (cp) {
594 		if (down_interruptible(&cp->mutex)) {
595 			up(&ccp->mutex);
596 			return -ERESTARTSYS;
597 		}
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 */
603 			up(&cp->mutex);
604 			auerswald_delete(cp);
605 		} else {
606 			up(&cp->mutex);
607 		}
608 		cp = NULL;
609 		ccp->auerdev = NULL;
610 	}
611 	up(&ccp->mutex);
612 	auerchar_delete(ccp);
613 
614 	return 0;
615 }
616